aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-06-05 10:51:55 -0400
committerTakashi Iwai <tiwai@suse.de>2018-06-05 10:51:55 -0400
commitd4d5a1cd298e67cb68cca8dc7dd1ea3942cce3ff (patch)
tree282417771a28cb3d88fdd3246d9b778f1e3e8fd3
parent7a6fc28b162bc0e48d8cef72be8226e11300317b (diff)
parentaac521e880f221e6d4e67b7061022dbecace0df0 (diff)
Merge tag 'asoc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.18 This is a very big update, mainly due to a huge set of new drivers some of which are individually very large. We also have a lot of fixes for the topology stuff, several of the users have stepped up and fixed some the serious issues there, and continued progress on the transition away from CODEC specific drivers to generic component drivers. - Many fixes for the topology code, including fixes for the half done v4 ABI compatibility from Guenter Roeck and other ABI fixes from Kirill Marinushkin. - Lots of cleanup for Intel platforms based on Realtek CODECs from Hans de Goode. - More followups on removing legacy CODEC things and transitioning to components from Morimoto-san. - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver. - A series of fixes and updates to the rather elderly Cirrus Logic SoC drivers from Alexander Sverdlin. - Qualcomm DSP support from Srinivas Kandagatla. - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306 and RT5668 and TI TSCS454
-rw-r--r--.mailmap3
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt84
-rw-r--r--Documentation/devicetree/bindings/sound/adi,ssm2305.txt14
-rw-r--r--Documentation/devicetree/bindings/sound/atmel-i2s.txt47
-rw-r--r--Documentation/devicetree/bindings/sound/cs42xx8.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,asrc.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,esai.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,spdif.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl-sai.txt8
-rw-r--r--Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/mt6351.txt16
-rw-r--r--Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt42
-rw-r--r--Documentation/devicetree/bindings/sound/mt6797-mt6351.txt14
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,apq8096.txt109
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,q6adm.txt33
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,q6afe.txt172
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,q6asm.txt33
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,q6core.txt21
-rw-r--r--Documentation/devicetree/bindings/sound/rt274.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5514.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5616.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5640.txt35
-rw-r--r--Documentation/devicetree/bindings/sound/rt5645.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5651.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5663.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5668.txt50
-rw-r--r--Documentation/devicetree/bindings/sound/sgtl5000.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.txt5
-rw-r--r--Documentation/devicetree/bindings/sound/ti,tas6424.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/tscs42xx.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/tscs454.txt23
-rw-r--r--Documentation/devicetree/bindings/sound/wm8510.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8523.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8524.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8580.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8711.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8728.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8731.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8737.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8741.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8750.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8753.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8770.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8776.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8804.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8903.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8960.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8962.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/wm8994.txt2
-rw-r--r--Documentation/sound/soc/codec.rst8
-rw-r--r--Documentation/sound/soc/platform.rst30
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/mach-ep93xx/core.c1
-rw-r--r--drivers/media/i2c/tda1997x.c25
-rw-r--r--drivers/soc/qcom/Kconfig9
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/apr.c378
-rw-r--r--include/dt-bindings/soc/qcom,apr.h28
-rw-r--r--include/dt-bindings/sound/fsl-imx-audmux.h7
-rw-r--r--include/dt-bindings/sound/qcom,q6afe.h111
-rw-r--r--include/dt-bindings/sound/qcom,q6asm.h22
-rw-r--r--include/dt-bindings/sound/rt5640.h25
-rw-r--r--include/linux/mfd/wm8350/audio.h3
-rw-r--r--include/linux/mod_devicetable.h11
-rw-r--r--include/linux/soc/qcom/apr.h128
-rw-r--r--include/sound/omap-pcm.h30
-rw-r--r--include/sound/rt5640.h27
-rw-r--r--include/sound/rt5668.h40
-rw-r--r--include/sound/soc-dai.h5
-rw-r--r--include/sound/soc.h397
-rw-r--r--include/trace/events/asoc.h1
-rw-r--r--include/uapi/sound/asoc.h86
-rw-r--r--include/uapi/sound/skl-tplg-interface.h (renamed from sound/soc/intel/skylake/skl-tplg-interface.h)85
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/amd/acp-da7219-max98357a.c90
-rw-r--r--sound/soc/amd/acp-pcm-dma.c623
-rw-r--r--sound/soc/amd/acp.h97
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-i2s.c765
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c8
-rw-r--r--sound/soc/bcm/Kconfig3
-rw-r--r--sound/soc/cirrus/Kconfig17
-rw-r--r--sound/soc/cirrus/edb93xx.c2
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c106
-rw-r--r--sound/soc/cirrus/snappercl15.c2
-rw-r--r--sound/soc/codecs/Kconfig33
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/adau17x1.c9
-rw-r--r--sound/soc/codecs/cs35l35.c1
-rw-r--r--sound/soc/codecs/max98088.c13
-rw-r--r--sound/soc/codecs/max98095.c13
-rw-r--r--sound/soc/codecs/max9860.c44
-rw-r--r--sound/soc/codecs/max9860.h10
-rw-r--r--sound/soc/codecs/mt6351.c1505
-rw-r--r--sound/soc/codecs/mt6351.h105
-rw-r--r--sound/soc/codecs/nau8810.c19
-rw-r--r--sound/soc/codecs/nau8824.c13
-rw-r--r--sound/soc/codecs/pcm1789.c2
-rw-r--r--sound/soc/codecs/pcm512x-i2c.c17
-rw-r--r--sound/soc/codecs/rt1305.c1191
-rw-r--r--sound/soc/codecs/rt1305.h276
-rw-r--r--sound/soc/codecs/rt5640.c553
-rw-r--r--sound/soc/codecs/rt5640.h46
-rw-r--r--sound/soc/codecs/rt5645.c23
-rw-r--r--sound/soc/codecs/rt5663.c55
-rw-r--r--sound/soc/codecs/rt5663.h2
-rw-r--r--sound/soc/codecs/rt5668.c2639
-rw-r--r--sound/soc/codecs/rt5668.h1318
-rw-r--r--sound/soc/codecs/rt5670.c2
-rw-r--r--sound/soc/codecs/rt5677.c13
-rw-r--r--sound/soc/codecs/sgtl5000.c18
-rw-r--r--sound/soc/codecs/sgtl5000.h5
-rw-r--r--sound/soc/codecs/ssm2305.c104
-rw-r--r--sound/soc/codecs/tas6424.c72
-rw-r--r--sound/soc/codecs/tas6424.h4
-rw-r--r--sound/soc/codecs/tfa9879.c48
-rw-r--r--sound/soc/codecs/tfa9879.h7
-rw-r--r--sound/soc/codecs/tscs42xx.c203
-rw-r--r--sound/soc/codecs/tscs42xx.h2
-rw-r--r--sound/soc/codecs/tscs454.c3497
-rw-r--r--sound/soc/codecs/tscs454.h2323
-rw-r--r--sound/soc/codecs/wm2200.c4
-rw-r--r--sound/soc/codecs/wm5100.c8
-rw-r--r--sound/soc/codecs/wm8782.c9
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm_adsp.c8
-rw-r--r--sound/soc/davinci/Kconfig2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c10
-rw-r--r--sound/soc/fsl/fsl_esai.c20
-rw-r--r--sound/soc/fsl/fsl_esai.h5
-rw-r--r--sound/soc/fsl/fsl_sai.c16
-rw-r--r--sound/soc/fsl/fsl_sai.h5
-rw-r--r--sound/soc/fsl/fsl_spdif.c24
-rw-r--r--sound/soc/fsl/fsl_spdif.h5
-rw-r--r--sound/soc/fsl/fsl_ssi.c60
-rw-r--r--sound/soc/fsl/fsl_ssi.h6
-rw-r--r--sound/soc/fsl/fsl_ssi_dbg.c18
-rw-r--r--sound/soc/generic/simple-card.c21
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.c2
-rw-r--r--sound/soc/intel/Kconfig2
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c2
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c2
-rw-r--r--sound/soc/intel/boards/byt-max98090.c2
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c2
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c568
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c18
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_nau8824.c4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c2
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c30
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98357a.c19
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c5
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c4
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c2
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c2
-rw-r--r--sound/soc/intel/boards/skl_rt286.c2
-rw-r--r--sound/soc/intel/skylake/skl-debug.c6
-rw-r--r--sound/soc/intel/skylake/skl-messages.c4
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c36
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h3
-rw-r--r--sound/soc/intel/skylake/skl-sst.c34
-rw-r--r--sound/soc/intel/skylake/skl-topology.c171
-rw-r--r--sound/soc/intel/skylake/skl-topology.h2
-rw-r--r--sound/soc/intel/skylake/skl.c7
-rw-r--r--sound/soc/kirkwood/Kconfig1
-rw-r--r--sound/soc/mediatek/Kconfig20
-rw-r--r--sound/soc/mediatek/Makefile2
-rw-r--r--sound/soc/mediatek/common/Makefile14
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.c30
-rw-r--r--sound/soc/mediatek/common/mtk-afe-fe-dai.h10
-rw-r--r--sound/soc/mediatek/common/mtk-afe-platform-driver.c103
-rw-r--r--sound/soc/mediatek/common/mtk-afe-platform-driver.h22
-rw-r--r--sound/soc/mediatek/common/mtk-base-afe.h30
-rw-r--r--sound/soc/mediatek/mt2701/Makefile14
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c66
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h23
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-common.h38
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c349
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-cs42448.c13
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-reg.h11
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-wm8960.c10
-rw-r--r--sound/soc/mediatek/mt6797/Makefile14
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-clk.c123
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-clk.h17
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-common.h58
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-pcm.c914
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-dai-adda.c396
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-dai-hostless.c112
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-dai-pcm.c312
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-interconnection.h33
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-mt6351.c223
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-reg.h1015
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-common.h10
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-pcm.c38
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-max98090.c10
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c10
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c10
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c10
-rw-r--r--sound/soc/omap/Kconfig28
-rw-r--r--sound/soc/omap/Makefile4
-rw-r--r--sound/soc/omap/n810.c21
-rw-r--r--sound/soc/omap/omap-dmic.c4
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c5
-rw-r--r--sound/soc/omap/omap-mcbsp.c4
-rw-r--r--sound/soc/omap/omap-mcpdm.c4
-rw-r--r--sound/soc/omap/omap-pcm.c262
-rw-r--r--sound/soc/omap/sdma-pcm.c74
-rw-r--r--sound/soc/omap/sdma-pcm.h21
-rw-r--r--sound/soc/pxa/Kconfig1
-rw-r--r--sound/soc/pxa/pxa-ssp.c88
-rw-r--r--sound/soc/qcom/Kconfig57
-rw-r--r--sound/soc/qcom/Makefile5
-rw-r--r--sound/soc/qcom/apq8096.c255
-rw-r--r--sound/soc/qcom/qdsp6/Makefile8
-rw-r--r--sound/soc/qcom/qdsp6/q6adm.c646
-rw-r--r--sound/soc/qcom/qdsp6/q6adm.h27
-rw-r--r--sound/soc/qcom/qdsp6/q6afe-dai.c1303
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.c1495
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.h211
-rw-r--r--sound/soc/qcom/qdsp6/q6asm-dai.c624
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.c1399
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.h69
-rw-r--r--sound/soc/qcom/qdsp6/q6core.c380
-rw-r--r--sound/soc/qcom/qdsp6/q6core.h15
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-common.c66
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-common.h24
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-errno.h51
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.c1006
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.h9
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c46
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/rcar/cmd.c15
-rw-r--r--sound/soc/sh/rcar/core.c49
-rw-r--r--sound/soc/sh/rcar/dma.c11
-rw-r--r--sound/soc/sh/rcar/gen.c3
-rw-r--r--sound/soc/sh/rcar/rsnd.h4
-rw-r--r--sound/soc/sh/rcar/ssi.c13
-rw-r--r--sound/soc/soc-cache.c53
-rw-r--r--sound/soc/soc-compress.c385
-rw-r--r--sound/soc/soc-core.c794
-rw-r--r--sound/soc/soc-dapm.c20
-rw-r--r--sound/soc/soc-devres.c35
-rw-r--r--sound/soc/soc-io.c83
-rw-r--r--sound/soc/soc-jack.c22
-rw-r--r--sound/soc/soc-pcm.c147
-rw-r--r--sound/soc/soc-topology.c93
-rw-r--r--sound/soc/uniphier/aio-compress.c13
-rw-r--r--sound/soc/uniphier/aio-core.c71
-rw-r--r--sound/soc/uniphier/aio-cpu.c153
-rw-r--r--sound/soc/uniphier/aio-dma.c13
-rw-r--r--sound/soc/uniphier/aio-ld11.c13
-rw-r--r--sound/soc/uniphier/aio-reg.h46
-rw-r--r--sound/soc/uniphier/aio.h20
-rw-r--r--sound/soc/uniphier/evea.c55
-rw-r--r--sound/soc/zte/zx-i2s.c5
256 files changed, 29764 insertions, 3964 deletions
diff --git a/.mailmap b/.mailmap
index 7fa9d41fbdaf..29ddeb1bf015 100644
--- a/.mailmap
+++ b/.mailmap
@@ -186,6 +186,9 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
186Uwe Kleine-König <ukl@pengutronix.de> 186Uwe Kleine-König <ukl@pengutronix.de>
187Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com> 187Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
188Valdis Kletnieks <Valdis.Kletnieks@vt.edu> 188Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
189Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
190Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
191Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
189Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com> 192Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
190Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com> 193Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
191Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com> 194Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
new file mode 100644
index 000000000000..bcc612cc7423
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
@@ -0,0 +1,84 @@
1Qualcomm APR (Asynchronous Packet Router) binding
2
3This binding describes the Qualcomm APR. APR is a IPC protocol for
4communication between Application processor and QDSP. APR is mainly
5used for audio/voice services on the QDSP.
6
7- compatible:
8 Usage: required
9 Value type: <stringlist>
10 Definition: must be "qcom,apr-v<VERSION-NUMBER>", example "qcom,apr-v2"
11
12- reg
13 Usage: required
14 Value type: <u32>
15 Definition: Destination processor ID.
16 Possible values are :
17 1 - APR simulator
18 2 - PC
19 3 - MODEM
20 4 - ADSP
21 5 - APPS
22 6 - MODEM2
23 7 - APPS2
24
25= APR SERVICES
26Each subnode of the APR node represents service tied to this apr. The name
27of the nodes are not important. The properties of these nodes are defined
28by the individual bindings for the specific service
29- All APR services MUST contain the following property:
30
31- reg
32 Usage: required
33 Value type: <u32>
34 Definition: APR Service ID
35 Possible values are :
36 3 - DSP Core Service
37 4 - Audio Front End Service.
38 5 - Voice Stream Manager Service.
39 6 - Voice processing manager.
40 7 - Audio Stream Manager Service.
41 8 - Audio Device Manager Service.
42 9 - Multimode voice manager.
43 10 - Core voice stream.
44 11 - Core voice processor.
45 12 - Ultrasound stream manager.
46 13 - Listen stream manager.
47
48= EXAMPLE
49The following example represents a QDSP based sound card on a MSM8996 device
50which uses apr as communication between Apps and QDSP.
51
52 apr@4 {
53 compatible = "qcom,apr-v2";
54 reg = <APR_DOMAIN_ADSP>;
55
56 q6core@3 {
57 compatible = "qcom,q6core";
58 reg = <APR_SVC_ADSP_CORE>;
59 };
60
61 q6afe@4 {
62 compatible = "qcom,q6afe";
63 reg = <APR_SVC_AFE>;
64
65 dais {
66 #sound-dai-cells = <1>;
67 hdmi@1 {
68 reg = <1>;
69 };
70 };
71 };
72
73 q6asm@7 {
74 compatible = "qcom,q6asm";
75 reg = <APR_SVC_ASM>;
76 ...
77 };
78
79 q6adm@8 {
80 compatible = "qcom,q6adm";
81 reg = <APR_SVC_ADM>;
82 ...
83 };
84 };
diff --git a/Documentation/devicetree/bindings/sound/adi,ssm2305.txt b/Documentation/devicetree/bindings/sound/adi,ssm2305.txt
new file mode 100644
index 000000000000..a9c9d83c8a30
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/adi,ssm2305.txt
@@ -0,0 +1,14 @@
1Analog Devices SSM2305 Speaker Amplifier
2========================================
3
4Required properties:
5 - compatible : "adi,ssm2305"
6 - shutdown-gpios : The gpio connected to the shutdown pin.
7 The gpio signal is ACTIVE_LOW.
8
9Example:
10
11ssm2305: analog-amplifier {
12 compatible = "adi,ssm2305";
13 shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
14};
diff --git a/Documentation/devicetree/bindings/sound/atmel-i2s.txt b/Documentation/devicetree/bindings/sound/atmel-i2s.txt
new file mode 100644
index 000000000000..735368b8a73f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-i2s.txt
@@ -0,0 +1,47 @@
1* Atmel I2S controller
2
3Required properties:
4- compatible: Should be "atmel,sama5d2-i2s".
5- reg: Should be the physical base address of the controller and the
6 length of memory mapped region.
7- interrupts: Should contain the interrupt for the controller.
8- dmas: Should be one per channel name listed in the dma-names property,
9 as described in atmel-dma.txt and dma.txt files.
10- dma-names: Two dmas have to be defined, "tx" and "rx".
11 This IP also supports one shared channel for both rx and tx;
12 if this mode is used, one "rx-tx" name must be used.
13- clocks: Must contain an entry for each entry in clock-names.
14 Please refer to clock-bindings.txt.
15- clock-names: Should be one of each entry matching the clocks phandles list:
16 - "pclk" (peripheral clock) Required.
17 - "gclk" (generated clock) Optional (1).
18 - "aclk" (Audio PLL clock) Optional (1).
19 - "muxclk" (I2S mux clock) Optional (1).
20
21Optional properties:
22- pinctrl-0: Should specify pin control groups used for this controller.
23- princtrl-names: Should contain only one value - "default".
24
25
26(1) : Only the peripheral clock is required. The generated clock, the Audio
27 PLL clock adn the I2S mux clock are optional and should only be set
28 together, when Master Mode is required.
29
30Example:
31
32 i2s@f8050000 {
33 compatible = "atmel,sama5d2-i2s";
34 reg = <0xf8050000 0x300>;
35 interrupts = <54 IRQ_TYPE_LEVEL_HIGH 7>;
36 dmas = <&dma0
37 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
38 AT91_XDMAC_DT_PERID(31))>,
39 <&dma0
40 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
41 AT91_XDMAC_DT_PERID(32))>;
42 dma-names = "tx", "rx";
43 clocks = <&i2s0_clk>, <&i2s0_gclk>, <&audio_pll_pmc>, <&i2s0muxck>;
44 clock-names = "pclk", "gclk", "aclk", "muxclk";
45 pinctrl-names = "default";
46 pinctrl-0 = <&pinctrl_i2s0_default>;
47 };
diff --git a/Documentation/devicetree/bindings/sound/cs42xx8.txt b/Documentation/devicetree/bindings/sound/cs42xx8.txt
index f631fbca6284..8619a156d038 100644
--- a/Documentation/devicetree/bindings/sound/cs42xx8.txt
+++ b/Documentation/devicetree/bindings/sound/cs42xx8.txt
@@ -16,7 +16,7 @@ Required properties:
16 16
17Example: 17Example:
18 18
19codec: cs42888@48 { 19cs42888: codec@48 {
20 compatible = "cirrus,cs42888"; 20 compatible = "cirrus,cs42888";
21 reg = <0x48>; 21 reg = <0x48>;
22 clocks = <&codec_mclk 0>; 22 clocks = <&codec_mclk 0>;
diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index f5a14115b459..1d4d9f938689 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -31,14 +31,16 @@ Required properties:
31 it. This property is optional depending on the SoC 31 it. This property is optional depending on the SoC
32 design. 32 design.
33 33
34 - big-endian : If this property is absent, the little endian mode
35 will be in use as default. Otherwise, the big endian
36 mode will be in use for all the device registers.
37
38 - fsl,asrc-rate : Defines a mutual sample rate used by DPCM Back Ends. 34 - fsl,asrc-rate : Defines a mutual sample rate used by DPCM Back Ends.
39 35
40 - fsl,asrc-width : Defines a mutual sample width used by DPCM Back Ends. 36 - fsl,asrc-width : Defines a mutual sample width used by DPCM Back Ends.
41 37
38Optional properties:
39
40 - big-endian : If this property is absent, the little endian mode
41 will be in use as default. Otherwise, the big endian
42 mode will be in use for all the device registers.
43
42Example: 44Example:
43 45
44asrc: asrc@2034000 { 46asrc: asrc@2034000 {
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index cacd18bb9ba6..5b9914367610 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -42,6 +42,8 @@ Required properties:
42 means all the settings for Receiving would be 42 means all the settings for Receiving would be
43 duplicated from Transmition related registers. 43 duplicated from Transmition related registers.
44 44
45Optional properties:
46
45 - big-endian : If this property is absent, the native endian mode 47 - big-endian : If this property is absent, the native endian mode
46 will be in use as default, or the big endian mode 48 will be in use as default, or the big endian mode
47 will be in use for all the device registers. 49 will be in use for all the device registers.
diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 38cfa7573441..8b324f82a782 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -33,6 +33,8 @@ Required properties:
33 it. This property is optional depending on the SoC 33 it. This property is optional depending on the SoC
34 design. 34 design.
35 35
36Optional properties:
37
36 - big-endian : If this property is absent, the native endian mode 38 - big-endian : If this property is absent, the native endian mode
37 will be in use as default, or the big endian mode 39 will be in use as default, or the big endian mode
38 will be in use for all the device registers. 40 will be in use for all the device registers.
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 740b467adf7d..dd9e59738e08 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -28,9 +28,6 @@ Required properties:
28 pinctrl-names. See ../pinctrl/pinctrl-bindings.txt 28 pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
29 for details of the property values. 29 for details of the property values.
30 30
31 - big-endian : Boolean property, required if all the FTM_PWM
32 registers are big-endian rather than little-endian.
33
34 - lsb-first : Configures whether the LSB or the MSB is transmitted 31 - lsb-first : Configures whether the LSB or the MSB is transmitted
35 first for the fifo data. If this property is absent, 32 first for the fifo data. If this property is absent,
36 the MSB is transmitted first as default, or the LSB 33 the MSB is transmitted first as default, or the LSB
@@ -48,6 +45,11 @@ Required properties:
48 receive data by following their own bit clocks and 45 receive data by following their own bit clocks and
49 frame sync clocks separately. 46 frame sync clocks separately.
50 47
48Optional properties:
49
50 - big-endian : Boolean property, required if all the SAI
51 registers are big-endian rather than little-endian.
52
51Optional properties (for mx6ul): 53Optional properties (for mx6ul):
52 54
53 - fsl,sai-mclk-direction-output: This is a boolean property. If present, 55 - fsl,sai-mclk-direction-output: This is a boolean property. If present,
diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
index e2f7f4951215..560762e0a168 100644
--- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
+++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
@@ -1,7 +1,9 @@
1Mediatek AFE PCM controller for mt2701 1Mediatek AFE PCM controller for mt2701
2 2
3Required properties: 3Required properties:
4- compatible = "mediatek,mt2701-audio"; 4- compatible: should be one of the followings.
5 - "mediatek,mt2701-audio"
6 - "mediatek,mt7622-audio"
5- interrupts: should contain AFE and ASYS interrupts 7- interrupts: should contain AFE and ASYS interrupts
6- interrupt-names: should be "afe" and "asys" 8- interrupt-names: should be "afe" and "asys"
7- power-domains: should define the power domain 9- power-domains: should define the power domain
diff --git a/Documentation/devicetree/bindings/sound/mt6351.txt b/Documentation/devicetree/bindings/sound/mt6351.txt
new file mode 100644
index 000000000000..7fb2cb99245e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt6351.txt
@@ -0,0 +1,16 @@
1Mediatek MT6351 Audio Codec
2
3The communication between MT6351 and SoC is through Mediatek PMIC wrapper.
4For more detail, please visit Mediatek PMIC wrapper documentation.
5
6Must be a child node of PMIC wrapper.
7
8Required properties:
9
10- compatible : "mediatek,mt6351-sound".
11
12Example:
13
14mt6351_snd {
15 compatible = "mediatek,mt6351-sound";
16};
diff --git a/Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt
new file mode 100644
index 000000000000..0ae29de15bfd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt
@@ -0,0 +1,42 @@
1Mediatek AFE PCM controller for mt6797
2
3Required properties:
4- compatible = "mediatek,mt6797-audio";
5- reg: register location and size
6- interrupts: should contain AFE interrupt
7- power-domains: should define the power domain
8- clocks: Must contain an entry for each entry in clock-names
9- clock-names: should have these clock names:
10 "infra_sys_audio_clk",
11 "infra_sys_audio_26m",
12 "mtkaif_26m_clk",
13 "top_mux_audio",
14 "top_mux_aud_intbus",
15 "top_sys_pll3_d4",
16 "top_sys_pll1_d4",
17 "top_clk26m_clk";
18
19Example:
20
21 afe: mt6797-afe-pcm@11220000 {
22 compatible = "mediatek,mt6797-audio";
23 reg = <0 0x11220000 0 0x1000>;
24 interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_LOW>;
25 power-domains = <&scpsys MT6797_POWER_DOMAIN_AUDIO>;
26 clocks = <&infrasys CLK_INFRA_AUDIO>,
27 <&infrasys CLK_INFRA_AUDIO_26M>,
28 <&infrasys CLK_INFRA_AUDIO_26M_PAD_TOP>,
29 <&topckgen CLK_TOP_MUX_AUDIO>,
30 <&topckgen CLK_TOP_MUX_AUD_INTBUS>,
31 <&topckgen CLK_TOP_SYSPLL3_D4>,
32 <&topckgen CLK_TOP_SYSPLL1_D4>,
33 <&clk26m>;
34 clock-names = "infra_sys_audio_clk",
35 "infra_sys_audio_26m",
36 "mtkaif_26m_clk",
37 "top_mux_audio",
38 "top_mux_aud_intbus",
39 "top_sys_pll3_d4",
40 "top_sys_pll1_d4",
41 "top_clk26m_clk";
42 };
diff --git a/Documentation/devicetree/bindings/sound/mt6797-mt6351.txt b/Documentation/devicetree/bindings/sound/mt6797-mt6351.txt
new file mode 100644
index 000000000000..1d95a8840f19
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt6797-mt6351.txt
@@ -0,0 +1,14 @@
1MT6797 with MT6351 CODEC
2
3Required properties:
4- compatible: "mediatek,mt6797-mt6351-sound"
5- mediatek,platform: the phandle of MT6797 ASoC platform
6- mediatek,audio-codec: the phandles of MT6351 codec
7
8Example:
9
10 sound {
11 compatible = "mediatek,mt6797-mt6351-sound";
12 mediatek,audio-codec = <&mt6351_snd>;
13 mediatek,platform = <&afe>;
14 };
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
new file mode 100644
index 000000000000..aa54e49fc8a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
@@ -0,0 +1,109 @@
1* Qualcomm Technologies APQ8096 ASoC sound card driver
2
3This binding describes the APQ8096 sound card, which uses qdsp for audio.
4
5- compatible:
6 Usage: required
7 Value type: <stringlist>
8 Definition: must be "qcom,apq8096-sndcard"
9
10- qcom,audio-routing:
11 Usage: Optional
12 Value type: <stringlist>
13 Definition: A list of the connections between audio components.
14 Each entry is a pair of strings, the first being the
15 connection's sink, the second being the connection's
16 source. Valid names could be power supplies, MicBias
17 of codec and the jacks on the board:
18 Valid names include:
19
20 Board Connectors:
21 "Headphone Left"
22 "Headphone Right"
23 "Earphone"
24 "Line Out1"
25 "Line Out2"
26 "Line Out3"
27 "Line Out4"
28 "Analog Mic1"
29 "Analog Mic2"
30 "Analog Mic3"
31 "Analog Mic4"
32 "Analog Mic5"
33 "Analog Mic6"
34 "Digital Mic2"
35 "Digital Mic3"
36
37 Audio pins and MicBias on WCD9335 Codec:
38 "MIC_BIAS1
39 "MIC_BIAS2"
40 "MIC_BIAS3"
41 "MIC_BIAS4"
42 "AMIC1"
43 "AMIC2"
44 "AMIC3"
45 "AMIC4"
46 "AMIC5"
47 "AMIC6"
48 "AMIC6"
49 "DMIC1"
50 "DMIC2"
51 "DMIC3"
52= dailinks
53Each subnode of sndcard represents either a dailink, and subnodes of each
54dailinks would be cpu/codec/platform dais.
55
56- link-name:
57 Usage: required
58 Value type: <string>
59 Definition: User friendly name for dai link
60
61= CPU, PLATFORM, CODEC dais subnodes
62- cpu:
63 Usage: required
64 Value type: <subnode>
65 Definition: cpu dai sub-node
66
67- codec:
68 Usage: Optional
69 Value type: <subnode>
70 Definition: codec dai sub-node
71
72- platform:
73 Usage: Optional
74 Value type: <subnode>
75 Definition: platform dai sub-node
76
77- sound-dai:
78 Usage: required
79 Value type: <phandle with arguments>
80 Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node.
81
82Example:
83
84audio {
85 compatible = "qcom,apq8096-sndcard";
86 qcom,model = "DB820c";
87
88 mm1-dai-link {
89 link-name = "MultiMedia1";
90 cpu {
91 sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
92 };
93 };
94
95 hdmi-dai-link {
96 link-name = "HDMI Playback";
97 cpu {
98 sound-dai = <&q6afe HDMI_RX>;
99 };
100
101 platform {
102 sound-dai = <&q6adm>;
103 };
104
105 codec {
106 sound-dai = <&hdmi 0>;
107 };
108 };
109};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6adm.txt b/Documentation/devicetree/bindings/sound/qcom,q6adm.txt
new file mode 100644
index 000000000000..cb709e5dbc44
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,q6adm.txt
@@ -0,0 +1,33 @@
1Qualcomm Audio Device Manager (Q6ADM) binding
2
3Q6ADM is one of the APR audio service on Q6DSP.
4Please refer to qcom,apr.txt for details of the coommon apr service bindings
5used by the apr service device.
6
7- but must contain the following property:
8
9- compatible:
10 Usage: required
11 Value type: <stringlist>
12 Definition: must be "qcom,q6adm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
13 Or "qcom,q6adm" where the version number can be queried
14 from DSP.
15 example "qcom,q6adm-v2.0"
16
17
18= ADM routing
19"routing" subnode of the ADM node represents adm routing specific configuration
20
21- #sound-dai-cells
22 Usage: required
23 Value type: <u32>
24 Definition: Must be 0
25
26= EXAMPLE
27q6adm@8 {
28 compatible = "qcom,q6adm";
29 reg = <APR_SVC_ADM>;
30 q6routing: routing {
31 #sound-dai-cells = <0>;
32 };
33};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6afe.txt b/Documentation/devicetree/bindings/sound/qcom,q6afe.txt
new file mode 100644
index 000000000000..bdbf87df8c0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,q6afe.txt
@@ -0,0 +1,172 @@
1Qualcomm Audio Front End (Q6AFE) binding
2
3AFE is one of the APR audio service on Q6DSP
4Please refer to qcom,apr.txt for details of the common apr service bindings
5used by all apr services. Must contain the following properties.
6
7- compatible:
8 Usage: required
9 Value type: <stringlist>
10 Definition: must be "qcom,q6afe-v<MAJOR-NUMBER>.<MINOR-NUMBER>"
11 Or "qcom,q6afe" where the version number can be queried
12 from DSP.
13 example "qcom,q6afe"
14
15= AFE DAIs (Digial Audio Interface)
16"dais" subnode of the AFE node. It represents afe dais, each afe dai is a
17subnode of "dais" representing board specific dai setup.
18"dais" node should have following properties followed by dai children.
19
20- #sound-dai-cells
21 Usage: required
22 Value type: <u32>
23 Definition: Must be 1
24
25- #address-cells
26 Usage: required
27 Value type: <u32>
28 Definition: Must be 1
29
30- #size-cells
31 Usage: required
32 Value type: <u32>
33 Definition: Must be 0
34
35== AFE DAI is subnode of "dais" and represent a dai, it includes board specific
36configuration of each dai. Must contain the following properties.
37
38- reg
39 Usage: required
40 Value type: <u32>
41 Definition: Must be dai id
42
43- qcom,sd-lines
44 Usage: required for mi2s interface
45 Value type: <prop-encoded-array>
46 Definition: Must be list of serial data lines used by this dai.
47 should be one or more of the 1-4 sd lines.
48
49 - qcom,tdm-sync-mode:
50 Usage: required for tdm interface
51 Value type: <prop-encoded-array>
52 Definition: Synchronization mode.
53 0 - Short sync bit mode
54 1 - Long sync mode
55 2 - Short sync slot mode
56
57 - qcom,tdm-sync-src:
58 Usage: required for tdm interface
59 Value type: <prop-encoded-array>
60 Definition: Synchronization source.
61 0 - External source
62 1 - Internal source
63
64 - qcom,tdm-data-out:
65 Usage: required for tdm interface
66 Value type: <prop-encoded-array>
67 Definition: Data out signal to drive with other masters.
68 0 - Disable
69 1 - Enable
70
71 - qcom,tdm-invert-sync:
72 Usage: required for tdm interface
73 Value type: <prop-encoded-array>
74 Definition: Invert the sync.
75 0 - Normal
76 1 - Invert
77
78 - qcom,tdm-data-delay:
79 Usage: required for tdm interface
80 Value type: <prop-encoded-array>
81 Definition: Number of bit clock to delay data
82 with respect to sync edge.
83 0 - 0 bit clock cycle
84 1 - 1 bit clock cycle
85 2 - 2 bit clock cycle
86
87 - qcom,tdm-data-align:
88 Usage: required for tdm interface
89 Value type: <prop-encoded-array>
90 Definition: Indicate how data is packed
91 within the slot. For example, 32 slot width in case of
92 sample bit width is 24.
93 0 - MSB
94 1 - LSB
95
96= EXAMPLE
97
98q6afe@4 {
99 compatible = "qcom,q6afe";
100 reg = <APR_SVC_AFE>;
101
102 dais {
103 #sound-dai-cells = <1>;
104 #address-cells = <1>;
105 #size-cells = <0>;
106
107 hdmi@1 {
108 reg = <1>;
109 };
110
111 tdm@24 {
112 reg = <24>;
113 qcom,tdm-sync-mode = <1>:
114 qcom,tdm-sync-src = <1>;
115 qcom,tdm-data-out = <0>;
116 qcom,tdm-invert-sync = <1>;
117 qcom,tdm-data-delay = <1>;
118 qcom,tdm-data-align = <0>;
119
120 };
121
122 tdm@25 {
123 reg = <25>;
124 qcom,tdm-sync-mode = <1>:
125 qcom,tdm-sync-src = <1>;
126 qcom,tdm-data-out = <0>;
127 qcom,tdm-invert-sync = <1>;
128 qcom,tdm-data-delay <1>:
129 qcom,tdm-data-align = <0>;
130 };
131
132 prim-mi2s-rx@16 {
133 reg = <16>;
134 qcom,sd-lines = <1 3>;
135 };
136
137 prim-mi2s-tx@17 {
138 reg = <17>;
139 qcom,sd-lines = <2>;
140 };
141
142 sec-mi2s-rx@18 {
143 reg = <18>;
144 qcom,sd-lines = <1 4>;
145 };
146
147 sec-mi2s-tx@19 {
148 reg = <19>;
149 qcom,sd-lines = <2>;
150 };
151
152 tert-mi2s-rx@20 {
153 reg = <20>;
154 qcom,sd-lines = <2 4>;
155 };
156
157 tert-mi2s-tx@21 {
158 reg = <21>;
159 qcom,sd-lines = <1>;
160 };
161
162 quat-mi2s-rx@22 {
163 reg = <22>;
164 qcom,sd-lines = <1>;
165 };
166
167 quat-mi2s-tx@23 {
168 reg = <23>;
169 qcom,sd-lines = <2>;
170 };
171 };
172};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm.txt b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt
new file mode 100644
index 000000000000..2178eb91146f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt
@@ -0,0 +1,33 @@
1Qualcomm Audio Stream Manager (Q6ASM) binding
2
3Q6ASM is one of the APR audio service on Q6DSP.
4Please refer to qcom,apr.txt for details of the common apr service bindings
5used by the apr service device.
6
7- but must contain the following property:
8
9- compatible:
10 Usage: required
11 Value type: <stringlist>
12 Definition: must be "qcom,q6asm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
13 Or "qcom,q6asm" where the version number can be queried
14 from DSP.
15 example "qcom,q6asm-v2.0"
16
17= ASM DAIs (Digial Audio Interface)
18"dais" subnode of the ASM node represents dai specific configuration
19
20- #sound-dai-cells
21 Usage: required
22 Value type: <u32>
23 Definition: Must be 1
24
25= EXAMPLE
26
27q6asm@7 {
28 compatible = "qcom,q6asm";
29 reg = <APR_SVC_ASM>;
30 q6asmdai: dais {
31 #sound-dai-cells = <1>;
32 };
33};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6core.txt b/Documentation/devicetree/bindings/sound/qcom,q6core.txt
new file mode 100644
index 000000000000..7f36ff8bec18
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,q6core.txt
@@ -0,0 +1,21 @@
1Qualcomm ADSP Core service binding
2
3Q6CORE is one of the APR audio service on Q6DSP.
4Please refer to qcom,apr.txt for details of the common apr service bindings
5used by the apr service device.
6
7- but must contain the following property:
8
9- compatible:
10 Usage: required
11 Value type: <stringlist>
12 Definition: must be "qcom,q6core-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
13 Or "qcom,q6core" where the version number can be queried
14 from DSP.
15 example "qcom,q6core-v2.0"
16
17= EXAMPLE
18q6core@3 {
19 compatible = "qcom,q6core";
20 reg = <APR_SVC_ADSP_CORE>;
21};
diff --git a/Documentation/devicetree/bindings/sound/rt274.txt b/Documentation/devicetree/bindings/sound/rt274.txt
index e9a6178c78cf..791a1bd767b9 100644
--- a/Documentation/devicetree/bindings/sound/rt274.txt
+++ b/Documentation/devicetree/bindings/sound/rt274.txt
@@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT274:
26 26
27Example: 27Example:
28 28
29codec: rt274@1c { 29rt274: codec@1c {
30 compatible = "realtek,rt274"; 30 compatible = "realtek,rt274";
31 reg = <0x1c>; 31 reg = <0x1c>;
32 interrupts = <7 IRQ_TYPE_EDGE_FALLING>; 32 interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
diff --git a/Documentation/devicetree/bindings/sound/rt5514.txt b/Documentation/devicetree/bindings/sound/rt5514.txt
index 4f33b0d96afe..b25ed08c7a5a 100644
--- a/Documentation/devicetree/bindings/sound/rt5514.txt
+++ b/Documentation/devicetree/bindings/sound/rt5514.txt
@@ -32,7 +32,7 @@ Pins on the device (for linking into audio routes) for I2C:
32 32
33Example: 33Example:
34 34
35codec: rt5514@57 { 35rt5514: codec@57 {
36 compatible = "realtek,rt5514"; 36 compatible = "realtek,rt5514";
37 reg = <0x57>; 37 reg = <0x57>;
38}; 38};
diff --git a/Documentation/devicetree/bindings/sound/rt5616.txt b/Documentation/devicetree/bindings/sound/rt5616.txt
index e41085818559..540a4bf252e4 100644
--- a/Documentation/devicetree/bindings/sound/rt5616.txt
+++ b/Documentation/devicetree/bindings/sound/rt5616.txt
@@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT5616:
26 26
27Example: 27Example:
28 28
29codec: rt5616@1b { 29rt5616: codec@1b {
30 compatible = "realtek,rt5616"; 30 compatible = "realtek,rt5616";
31 reg = <0x1b>; 31 reg = <0x1b>;
32}; 32};
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
index 57fe64643050..e40e4893eed8 100644
--- a/Documentation/devicetree/bindings/sound/rt5640.txt
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -22,6 +22,41 @@ Optional properties:
22 22
23- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. 23- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
24 24
25- realtek,dmic1-data-pin
26 0: dmic1 is not used
27 1: using IN1P pin as dmic1 data pin
28 2: using GPIO3 pin as dmic1 data pin
29
30- realtek,dmic2-data-pin
31 0: dmic2 is not used
32 1: using IN1N pin as dmic2 data pin
33 2: using GPIO4 pin as dmic2 data pin
34
35- realtek,jack-detect-source
36 u32. Valid values:
37 0: jack-detect is not used
38 1: Use GPIO1 for jack-detect
39 2: Use JD1_IN4P for jack-detect
40 3: Use JD2_IN4N for jack-detect
41 4: Use GPIO2 for jack-detect
42 5: Use GPIO3 for jack-detect
43 6: Use GPIO4 for jack-detect
44
45- realtek,jack-detect-not-inverted
46 bool. Normal jack-detect switches give an inverted signal, set this bool
47 in the rare case you've a jack-detect switch which is not inverted.
48
49- realtek,over-current-threshold-microamp
50 u32, micbias over-current detection threshold in µA, valid values are
51 600, 1500 and 2000µA.
52
53- realtek,over-current-scale-factor
54 u32, micbias over-current detection scale-factor, valid values are:
55 0: Scale current by 0.5
56 1: Scale current by 0.75
57 2: Scale current by 1.0
58 3: Scale current by 1.5
59
25Pins on the device (for linking into audio routes) for RT5639/RT5640: 60Pins on the device (for linking into audio routes) for RT5639/RT5640:
26 61
27 * DMIC1 62 * DMIC1
diff --git a/Documentation/devicetree/bindings/sound/rt5645.txt b/Documentation/devicetree/bindings/sound/rt5645.txt
index 7cee1f518f59..a03f9a872a71 100644
--- a/Documentation/devicetree/bindings/sound/rt5645.txt
+++ b/Documentation/devicetree/bindings/sound/rt5645.txt
@@ -69,4 +69,4 @@ codec: rt5650@1a {
69 realtek,dmic-en = "true"; 69 realtek,dmic-en = "true";
70 realtek,en-jd-func = "true"; 70 realtek,en-jd-func = "true";
71 realtek,jd-mode = <3>; 71 realtek,jd-mode = <3>;
72}; \ No newline at end of file 72};
diff --git a/Documentation/devicetree/bindings/sound/rt5651.txt b/Documentation/devicetree/bindings/sound/rt5651.txt
index b85221864cec..a41199a5cd79 100644
--- a/Documentation/devicetree/bindings/sound/rt5651.txt
+++ b/Documentation/devicetree/bindings/sound/rt5651.txt
@@ -50,7 +50,7 @@ Pins on the device (for linking into audio routes) for RT5651:
50 50
51Example: 51Example:
52 52
53codec: rt5651@1a { 53rt5651: codec@1a {
54 compatible = "realtek,rt5651"; 54 compatible = "realtek,rt5651";
55 reg = <0x1a>; 55 reg = <0x1a>;
56 realtek,dmic-en = "true"; 56 realtek,dmic-en = "true";
diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt
index 497bcfc58b71..23386446c63d 100644
--- a/Documentation/devicetree/bindings/sound/rt5663.txt
+++ b/Documentation/devicetree/bindings/sound/rt5663.txt
@@ -47,7 +47,7 @@ Pins on the device (for linking into audio routes) for RT5663:
47 47
48Example: 48Example:
49 49
50codec: rt5663@12 { 50rt5663: codec@12 {
51 compatible = "realtek,rt5663"; 51 compatible = "realtek,rt5663";
52 reg = <0x12>; 52 reg = <0x12>;
53 interrupts = <7 IRQ_TYPE_EDGE_FALLING>; 53 interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
diff --git a/Documentation/devicetree/bindings/sound/rt5668.txt b/Documentation/devicetree/bindings/sound/rt5668.txt
new file mode 100644
index 000000000000..c88b96e7764b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5668.txt
@@ -0,0 +1,50 @@
1RT5668B audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5668b"
8
9- reg : The I2C address of the device.
10
11Optional properties:
12
13- interrupts : The CODEC's interrupt output.
14
15- realtek,dmic1-data-pin
16 0: dmic1 is not used
17 1: using GPIO2 pin as dmic1 data pin
18 2: using GPIO5 pin as dmic1 data pin
19
20- realtek,dmic1-clk-pin
21 0: using GPIO1 pin as dmic1 clock pin
22 1: using GPIO3 pin as dmic1 clock pin
23
24- realtek,jd-src
25 0: No JD is used
26 1: using JD1 as JD source
27
28- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
29
30Pins on the device (for linking into audio routes) for RT5668B:
31
32 * DMIC L1
33 * DMIC R1
34 * IN1P
35 * HPOL
36 * HPOR
37
38Example:
39
40rt5668 {
41 compatible = "realtek,rt5668b";
42 reg = <0x1a>;
43 interrupt-parent = <&gpio>;
44 interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
45 realtek,ldo1-en-gpios =
46 <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
47 realtek,dmic1-data-pin = <1>;
48 realtek,dmic1-clk-pin = <1>;
49 realtek,jd-src = <1>;
50};
diff --git a/Documentation/devicetree/bindings/sound/sgtl5000.txt b/Documentation/devicetree/bindings/sound/sgtl5000.txt
index 9a36c7e2a143..0f214457476f 100644
--- a/Documentation/devicetree/bindings/sound/sgtl5000.txt
+++ b/Documentation/devicetree/bindings/sound/sgtl5000.txt
@@ -39,7 +39,7 @@ VDDIO 1.8V 2.5V 3.3V
39 39
40Example: 40Example:
41 41
42codec: sgtl5000@a { 42sgtl5000: codec@a {
43 compatible = "fsl,sgtl5000"; 43 compatible = "fsl,sgtl5000";
44 reg = <0x0a>; 44 reg = <0x0a>;
45 #sound-dai-cells = <0>; 45 #sound-dai-cells = <0>;
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index 17c13e74667d..a4c72d09cd45 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -86,6 +86,11 @@ Optional CPU/CODEC subnodes properties:
86 in dai startup() and disabled with 86 in dai startup() and disabled with
87 clk_disable_unprepare() in dai 87 clk_disable_unprepare() in dai
88 shutdown(). 88 shutdown().
89 If a clock is specified and a
90 multiplication factor is given with
91 mclk-fs, the clock will be set to the
92 calculated mclk frequency when the
93 stream starts.
89- system-clock-direction-out : specifies clock direction as 'out' on 94- system-clock-direction-out : specifies clock direction as 'out' on
90 initialization. It is useful for some aCPUs with 95 initialization. It is useful for some aCPUs with
91 fixed clocks. 96 fixed clocks.
diff --git a/Documentation/devicetree/bindings/sound/ti,tas6424.txt b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
index 1c4ada0eef4e..eacb54f34188 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas6424.txt
+++ b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
@@ -6,6 +6,8 @@ Required properties:
6 - compatible: "ti,tas6424" - TAS6424 6 - compatible: "ti,tas6424" - TAS6424
7 - reg: I2C slave address 7 - reg: I2C slave address
8 - sound-dai-cells: must be equal to 0 8 - sound-dai-cells: must be equal to 0
9 - standby-gpios: GPIO used to shut the TAS6424 down.
10 - mute-gpios: GPIO used to mute all the outputs
9 11
10Example: 12Example:
11 13
diff --git a/Documentation/devicetree/bindings/sound/tscs42xx.txt b/Documentation/devicetree/bindings/sound/tscs42xx.txt
index 2ac2f0996697..7eea32e9d078 100644
--- a/Documentation/devicetree/bindings/sound/tscs42xx.txt
+++ b/Documentation/devicetree/bindings/sound/tscs42xx.txt
@@ -8,9 +8,15 @@ Required Properties:
8 - reg : <0x71> for analog mic 8 - reg : <0x71> for analog mic
9 <0x69> for digital mic 9 <0x69> for digital mic
10 10
11 - clock-names: Must one of the following "mclk1", "xtal", "mclk2"
12
13 - clocks: phandle of the clock that provides the codec sysclk
14
11Example: 15Example:
12 16
13wookie: codec@69 { 17wookie: codec@69 {
14 compatible = "tempo,tscs42A2"; 18 compatible = "tempo,tscs42A2";
15 reg = <0x69>; 19 reg = <0x69>;
20 clock-names = "xtal";
21 clocks = <&audio_xtal>;
16}; 22};
diff --git a/Documentation/devicetree/bindings/sound/tscs454.txt b/Documentation/devicetree/bindings/sound/tscs454.txt
new file mode 100644
index 000000000000..3ba3e2d2c206
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tscs454.txt
@@ -0,0 +1,23 @@
1TSCS454 Audio CODEC
2
3Required Properties:
4
5 - compatible : "tempo,tscs454"
6
7 - reg : <0x69>
8
9 - clock-names: Must one of the following "xtal", "mclk1", "mclk2"
10
11 - clocks: phandle of the clock that provides the codec sysclk
12
13 Note: If clock is not provided then bit clock is assumed
14
15Example:
16
17redwood: codec@69 {
18 #sound-dai-cells = <1>;
19 compatible = "tempo,tscs454";
20 reg = <0x69>;
21 clock-names = "mclk1";
22 clocks = <&audio_mclk>;
23};
diff --git a/Documentation/devicetree/bindings/sound/wm8510.txt b/Documentation/devicetree/bindings/sound/wm8510.txt
index fa1a32b85577..e6b6cc041f89 100644
--- a/Documentation/devicetree/bindings/sound/wm8510.txt
+++ b/Documentation/devicetree/bindings/sound/wm8510.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8510@1a { 15wm8510: codec@1a {
16 compatible = "wlf,wm8510"; 16 compatible = "wlf,wm8510";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8523.txt b/Documentation/devicetree/bindings/sound/wm8523.txt
index 04746186b283..f3a6485f4b8a 100644
--- a/Documentation/devicetree/bindings/sound/wm8523.txt
+++ b/Documentation/devicetree/bindings/sound/wm8523.txt
@@ -10,7 +10,7 @@ Required properties:
10 10
11Example: 11Example:
12 12
13codec: wm8523@1a { 13wm8523: codec@1a {
14 compatible = "wlf,wm8523"; 14 compatible = "wlf,wm8523";
15 reg = <0x1a>; 15 reg = <0x1a>;
16}; 16};
diff --git a/Documentation/devicetree/bindings/sound/wm8524.txt b/Documentation/devicetree/bindings/sound/wm8524.txt
index 0f0553563fc1..f6c0c263b135 100644
--- a/Documentation/devicetree/bindings/sound/wm8524.txt
+++ b/Documentation/devicetree/bindings/sound/wm8524.txt
@@ -10,7 +10,7 @@ Required properties:
10 10
11Example: 11Example:
12 12
13codec: wm8524 { 13wm8524: codec {
14 compatible = "wlf,wm8524"; 14 compatible = "wlf,wm8524";
15 wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; 15 wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
16}; 16};
diff --git a/Documentation/devicetree/bindings/sound/wm8580.txt b/Documentation/devicetree/bindings/sound/wm8580.txt
index 78fce9b14954..ff3f9f5f2111 100644
--- a/Documentation/devicetree/bindings/sound/wm8580.txt
+++ b/Documentation/devicetree/bindings/sound/wm8580.txt
@@ -10,7 +10,7 @@ Required properties:
10 10
11Example: 11Example:
12 12
13codec: wm8580@1a { 13wm8580: codec@1a {
14 compatible = "wlf,wm8580"; 14 compatible = "wlf,wm8580";
15 reg = <0x1a>; 15 reg = <0x1a>;
16}; 16};
diff --git a/Documentation/devicetree/bindings/sound/wm8711.txt b/Documentation/devicetree/bindings/sound/wm8711.txt
index 8ed9998cd23c..c30a1387c4bf 100644
--- a/Documentation/devicetree/bindings/sound/wm8711.txt
+++ b/Documentation/devicetree/bindings/sound/wm8711.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8711@1a { 15wm8711: codec@1a {
16 compatible = "wlf,wm8711"; 16 compatible = "wlf,wm8711";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8728.txt b/Documentation/devicetree/bindings/sound/wm8728.txt
index a8b5c3668e60..a3608b4c78b9 100644
--- a/Documentation/devicetree/bindings/sound/wm8728.txt
+++ b/Documentation/devicetree/bindings/sound/wm8728.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8728@1a { 15wm8728: codec@1a {
16 compatible = "wlf,wm8728"; 16 compatible = "wlf,wm8728";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8731.txt b/Documentation/devicetree/bindings/sound/wm8731.txt
index 236690e99b87..f660d9bb0e69 100644
--- a/Documentation/devicetree/bindings/sound/wm8731.txt
+++ b/Documentation/devicetree/bindings/sound/wm8731.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8731@1a { 15wm8731: codec@1a {
16 compatible = "wlf,wm8731"; 16 compatible = "wlf,wm8731";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8737.txt b/Documentation/devicetree/bindings/sound/wm8737.txt
index 4bc2cea3b140..eda1ec6a7563 100644
--- a/Documentation/devicetree/bindings/sound/wm8737.txt
+++ b/Documentation/devicetree/bindings/sound/wm8737.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8737@1a { 15wm8737: codec@1a {
16 compatible = "wlf,wm8737"; 16 compatible = "wlf,wm8737";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8741.txt b/Documentation/devicetree/bindings/sound/wm8741.txt
index a13315408719..b69e196c741c 100644
--- a/Documentation/devicetree/bindings/sound/wm8741.txt
+++ b/Documentation/devicetree/bindings/sound/wm8741.txt
@@ -21,7 +21,7 @@ Optional properties:
21 21
22Example: 22Example:
23 23
24codec: wm8741@1a { 24wm8741: codec@1a {
25 compatible = "wlf,wm8741"; 25 compatible = "wlf,wm8741";
26 reg = <0x1a>; 26 reg = <0x1a>;
27 27
diff --git a/Documentation/devicetree/bindings/sound/wm8750.txt b/Documentation/devicetree/bindings/sound/wm8750.txt
index 8db239fd5ecd..682f221f6f38 100644
--- a/Documentation/devicetree/bindings/sound/wm8750.txt
+++ b/Documentation/devicetree/bindings/sound/wm8750.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8750@1a { 15wm8750: codec@1a {
16 compatible = "wlf,wm8750"; 16 compatible = "wlf,wm8750";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8753.txt b/Documentation/devicetree/bindings/sound/wm8753.txt
index 8eee61282105..eca9e5a825a9 100644
--- a/Documentation/devicetree/bindings/sound/wm8753.txt
+++ b/Documentation/devicetree/bindings/sound/wm8753.txt
@@ -34,7 +34,7 @@ Pins on the device (for linking into audio routes):
34 34
35Example: 35Example:
36 36
37codec: wm8753@1a { 37wm8753: codec@1a {
38 compatible = "wlf,wm8753"; 38 compatible = "wlf,wm8753";
39 reg = <0x1a>; 39 reg = <0x1a>;
40}; 40};
diff --git a/Documentation/devicetree/bindings/sound/wm8770.txt b/Documentation/devicetree/bindings/sound/wm8770.txt
index 866e00ca150b..cac762a1105d 100644
--- a/Documentation/devicetree/bindings/sound/wm8770.txt
+++ b/Documentation/devicetree/bindings/sound/wm8770.txt
@@ -10,7 +10,7 @@ Required properties:
10 10
11Example: 11Example:
12 12
13codec: wm8770@1 { 13wm8770: codec@1 {
14 compatible = "wlf,wm8770"; 14 compatible = "wlf,wm8770";
15 reg = <1>; 15 reg = <1>;
16}; 16};
diff --git a/Documentation/devicetree/bindings/sound/wm8776.txt b/Documentation/devicetree/bindings/sound/wm8776.txt
index 3b9ca49abc2b..01173369c3ed 100644
--- a/Documentation/devicetree/bindings/sound/wm8776.txt
+++ b/Documentation/devicetree/bindings/sound/wm8776.txt
@@ -12,7 +12,7 @@ Required properties:
12 12
13Example: 13Example:
14 14
15codec: wm8776@1a { 15wm8776: codec@1a {
16 compatible = "wlf,wm8776"; 16 compatible = "wlf,wm8776";
17 reg = <0x1a>; 17 reg = <0x1a>;
18}; 18};
diff --git a/Documentation/devicetree/bindings/sound/wm8804.txt b/Documentation/devicetree/bindings/sound/wm8804.txt
index 6fd124b16496..2c1641c17a91 100644
--- a/Documentation/devicetree/bindings/sound/wm8804.txt
+++ b/Documentation/devicetree/bindings/sound/wm8804.txt
@@ -19,7 +19,7 @@ Optional properties:
19 19
20Example: 20Example:
21 21
22codec: wm8804@1a { 22wm8804: codec@1a {
23 compatible = "wlf,wm8804"; 23 compatible = "wlf,wm8804";
24 reg = <0x1a>; 24 reg = <0x1a>;
25}; 25};
diff --git a/Documentation/devicetree/bindings/sound/wm8903.txt b/Documentation/devicetree/bindings/sound/wm8903.txt
index afc51caf1137..6371c2434afe 100644
--- a/Documentation/devicetree/bindings/sound/wm8903.txt
+++ b/Documentation/devicetree/bindings/sound/wm8903.txt
@@ -57,7 +57,7 @@ Pins on the device (for linking into audio routes):
57 57
58Example: 58Example:
59 59
60codec: wm8903@1a { 60wm8903: codec@1a {
61 compatible = "wlf,wm8903"; 61 compatible = "wlf,wm8903";
62 reg = <0x1a>; 62 reg = <0x1a>;
63 interrupts = < 347 >; 63 interrupts = < 347 >;
diff --git a/Documentation/devicetree/bindings/sound/wm8960.txt b/Documentation/devicetree/bindings/sound/wm8960.txt
index 2deb8a3da9c5..6d29ac3750ee 100644
--- a/Documentation/devicetree/bindings/sound/wm8960.txt
+++ b/Documentation/devicetree/bindings/sound/wm8960.txt
@@ -23,7 +23,7 @@ Optional properties:
23 23
24Example: 24Example:
25 25
26codec: wm8960@1a { 26wm8960: codec@1a {
27 compatible = "wlf,wm8960"; 27 compatible = "wlf,wm8960";
28 reg = <0x1a>; 28 reg = <0x1a>;
29 29
diff --git a/Documentation/devicetree/bindings/sound/wm8962.txt b/Documentation/devicetree/bindings/sound/wm8962.txt
index 7f82b59ec8f9..dcfa9a3369fd 100644
--- a/Documentation/devicetree/bindings/sound/wm8962.txt
+++ b/Documentation/devicetree/bindings/sound/wm8962.txt
@@ -24,7 +24,7 @@ Optional properties:
24 24
25Example: 25Example:
26 26
27codec: wm8962@1a { 27wm8962: codec@1a {
28 compatible = "wlf,wm8962"; 28 compatible = "wlf,wm8962";
29 reg = <0x1a>; 29 reg = <0x1a>;
30 30
diff --git a/Documentation/devicetree/bindings/sound/wm8994.txt b/Documentation/devicetree/bindings/sound/wm8994.txt
index 68c4e8d96bed..4a9dead1b7d3 100644
--- a/Documentation/devicetree/bindings/sound/wm8994.txt
+++ b/Documentation/devicetree/bindings/sound/wm8994.txt
@@ -59,7 +59,7 @@ Optional properties:
59 59
60Example: 60Example:
61 61
62codec: wm8994@1a { 62wm8994: codec@1a {
63 compatible = "wlf,wm8994"; 63 compatible = "wlf,wm8994";
64 reg = <0x1a>; 64 reg = <0x1a>;
65 65
diff --git a/Documentation/sound/soc/codec.rst b/Documentation/sound/soc/codec.rst
index f87612b94812..58f625fe3d39 100644
--- a/Documentation/sound/soc/codec.rst
+++ b/Documentation/sound/soc/codec.rst
@@ -179,12 +179,12 @@ i.e.
179 179
180 static int wm8974_mute(struct snd_soc_dai *dai, int mute) 180 static int wm8974_mute(struct snd_soc_dai *dai, int mute)
181 { 181 {
182 struct snd_soc_codec *codec = dai->codec; 182 struct snd_soc_component *component = dai->component;
183 u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf; 183 u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
184 184
185 if (mute) 185 if (mute)
186 snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40); 186 snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
187 else 187 else
188 snd_soc_write(codec, WM8974_DAC, mute_reg); 188 snd_soc_component_write(component, WM8974_DAC, mute_reg);
189 return 0; 189 return 0;
190 } 190 }
diff --git a/Documentation/sound/soc/platform.rst b/Documentation/sound/soc/platform.rst
index d5574904d981..cc817078daa6 100644
--- a/Documentation/sound/soc/platform.rst
+++ b/Documentation/sound/soc/platform.rst
@@ -23,30 +23,26 @@ The platform DMA driver optionally supports the following ALSA operations:-
23 }; 23 };
24 24
25The platform driver exports its DMA functionality via struct 25The platform driver exports its DMA functionality via struct
26snd_soc_platform_driver:- 26snd_soc_component_driver:-
27:: 27::
28 28
29 struct snd_soc_platform_driver { 29 struct snd_soc_component_driver {
30 char *name; 30 const char *name;
31 31
32 int (*probe)(struct platform_device *pdev); 32 ...
33 int (*remove)(struct platform_device *pdev); 33 int (*probe)(struct snd_soc_component *);
34 int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); 34 void (*remove)(struct snd_soc_component *);
35 int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai); 35 int (*suspend)(struct snd_soc_component *);
36 int (*resume)(struct snd_soc_component *);
36 37
37 /* pcm creation and destruction */ 38 /* pcm creation and destruction */
38 int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *); 39 int (*pcm_new)(struct snd_soc_pcm_runtime *);
39 void (*pcm_free)(struct snd_pcm *); 40 void (*pcm_free)(struct snd_pcm *);
40 41
41 /* 42 ...
42 * For platform caused delay reporting. 43 const struct snd_pcm_ops *ops;
43 * Optional. 44 const struct snd_compr_ops *compr_ops;
44 */ 45 ...
45 snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
46 struct snd_soc_dai *);
47
48 /* platform stream ops */
49 struct snd_pcm_ops *pcm_ops;
50 }; 46 };
51 47
52Please refer to the ALSA driver documentation for details of audio DMA. 48Please refer to the ALSA driver documentation for details of audio DMA.
diff --git a/MAINTAINERS b/MAINTAINERS
index bd214e061359..488b88071c13 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7038,14 +7038,13 @@ L: linux-fbdev@vger.kernel.org
7038S: Maintained 7038S: Maintained
7039F: drivers/video/fbdev/i810/ 7039F: drivers/video/fbdev/i810/
7040 7040
7041INTEL ASoC BDW/HSW DRIVERS 7041INTEL ASoC DRIVERS
7042M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
7043M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
7042M: Jie Yang <yang.jie@linux.intel.com> 7044M: Jie Yang <yang.jie@linux.intel.com>
7043L: alsa-devel@alsa-project.org (moderated for non-subscribers) 7045L: alsa-devel@alsa-project.org (moderated for non-subscribers)
7044S: Supported 7046S: Supported
7045F: sound/soc/intel/common/sst-dsp* 7047F: sound/soc/intel/
7046F: sound/soc/intel/common/sst-firmware.c
7047F: sound/soc/intel/boards/broadwell.c
7048F: sound/soc/intel/haswell/
7049 7048
7050INTEL C600 SERIES SAS CONTROLLER DRIVER 7049INTEL C600 SERIES SAS CONTROLLER DRIVER
7051M: Intel SCU Linux support <intel-linux-scu@intel.com> 7050M: Intel SCU Linux support <intel-linux-scu@intel.com>
@@ -13124,7 +13123,7 @@ F: include/uapi/sound/
13124F: sound/ 13123F: sound/
13125 13124
13126SOUND - COMPRESSED AUDIO 13125SOUND - COMPRESSED AUDIO
13127M: Vinod Koul <vinod.koul@intel.com> 13126M: Vinod Koul <vkoul@kernel.org>
13128L: alsa-devel@alsa-project.org (moderated for non-subscribers) 13127L: alsa-devel@alsa-project.org (moderated for non-subscribers)
13129T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git 13128T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
13130S: Supported 13129S: Supported
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index e70feec6fad5..48d6a9e01dc8 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -635,6 +635,7 @@ EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
635 *************************************************************************/ 635 *************************************************************************/
636static struct resource ep93xx_i2s_resource[] = { 636static struct resource ep93xx_i2s_resource[] = {
637 DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100), 637 DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
638 DEFINE_RES_IRQ(IRQ_EP93XX_SAI),
638}; 639};
639 640
640static struct platform_device ep93xx_i2s_device = { 641static struct platform_device ep93xx_i2s_device = {
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index 3021913c28fa..33d7fcf541fc 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2444,7 +2444,7 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
2444 struct snd_soc_dai *dai) 2444 struct snd_soc_dai *dai)
2445{ 2445{
2446 struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai); 2446 struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai);
2447 struct snd_soc_codec *codec = dai->codec; 2447 struct snd_soc_component *component = dai->component;
2448 struct snd_pcm_runtime *rtd = substream->runtime; 2448 struct snd_pcm_runtime *rtd = substream->runtime;
2449 int rate, err; 2449 int rate, err;
2450 2450
@@ -2452,11 +2452,11 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
2452 err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE, 2452 err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE,
2453 rate, rate); 2453 rate, rate);
2454 if (err < 0) { 2454 if (err < 0) {
2455 dev_err(codec->dev, "failed to constrain samplerate to %dHz\n", 2455 dev_err(component->dev, "failed to constrain samplerate to %dHz\n",
2456 rate); 2456 rate);
2457 return err; 2457 return err;
2458 } 2458 }
2459 dev_info(codec->dev, "set samplerate constraint to %dHz\n", rate); 2459 dev_info(component->dev, "set samplerate constraint to %dHz\n", rate);
2460 2460
2461 return 0; 2461 return 0;
2462} 2462}
@@ -2479,20 +2479,22 @@ static struct snd_soc_dai_driver tda1997x_audio_dai = {
2479 .ops = &tda1997x_dai_ops, 2479 .ops = &tda1997x_dai_ops,
2480}; 2480};
2481 2481
2482static int tda1997x_codec_probe(struct snd_soc_codec *codec) 2482static int tda1997x_codec_probe(struct snd_soc_component *component)
2483{ 2483{
2484 return 0; 2484 return 0;
2485} 2485}
2486 2486
2487static int tda1997x_codec_remove(struct snd_soc_codec *codec) 2487static void tda1997x_codec_remove(struct snd_soc_component *component)
2488{ 2488{
2489 return 0;
2490} 2489}
2491 2490
2492static struct snd_soc_codec_driver tda1997x_codec_driver = { 2491static struct snd_soc_component_driver tda1997x_codec_driver = {
2493 .probe = tda1997x_codec_probe, 2492 .probe = tda1997x_codec_probe,
2494 .remove = tda1997x_codec_remove, 2493 .remove = tda1997x_codec_remove,
2495 .reg_word_size = sizeof(u16), 2494 .idle_bias_on = 1,
2495 .use_pmdown_time = 1,
2496 .endianness = 1,
2497 .non_legacy_dai_naming = 1,
2496}; 2498};
2497 2499
2498static int tda1997x_probe(struct i2c_client *client, 2500static int tda1997x_probe(struct i2c_client *client,
@@ -2737,7 +2739,7 @@ static int tda1997x_probe(struct i2c_client *client,
2737 else 2739 else
2738 formats = SNDRV_PCM_FMTBIT_S16_LE; 2740 formats = SNDRV_PCM_FMTBIT_S16_LE;
2739 tda1997x_audio_dai.capture.formats = formats; 2741 tda1997x_audio_dai.capture.formats = formats;
2740 ret = snd_soc_register_codec(&state->client->dev, 2742 ret = devm_snd_soc_register_component(&state->client->dev,
2741 &tda1997x_codec_driver, 2743 &tda1997x_codec_driver,
2742 &tda1997x_audio_dai, 1); 2744 &tda1997x_audio_dai, 1);
2743 if (ret) { 2745 if (ret) {
@@ -2782,7 +2784,6 @@ static int tda1997x_remove(struct i2c_client *client)
2782 struct tda1997x_platform_data *pdata = &state->pdata; 2784 struct tda1997x_platform_data *pdata = &state->pdata;
2783 2785
2784 if (pdata->audout_format) { 2786 if (pdata->audout_format) {
2785 snd_soc_unregister_codec(&client->dev);
2786 mutex_destroy(&state->audio_lock); 2787 mutex_destroy(&state->audio_lock);
2787 } 2788 }
2788 2789
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5c4535b545cc..d053f2634c67 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -108,4 +108,13 @@ config QCOM_WCNSS_CTRL
108 Client driver for the WCNSS_CTRL SMD channel, used to download nv 108 Client driver for the WCNSS_CTRL SMD channel, used to download nv
109 firmware to a newly booted WCNSS chip. 109 firmware to a newly booted WCNSS chip.
110 110
111config QCOM_APR
112 tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
113 depends on ARCH_QCOM
114 depends on RPMSG
115 help
116 Enable APR IPC protocol support between
117 application processor and QDSP6. APR is
118 used by audio driver to configure QDSP6
119 ASM, ADM and AFE modules.
111endmenu 120endmenu
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index dcebf2814e6d..39de5dee55d9 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
12obj-$(CONFIG_QCOM_SMP2P) += smp2p.o 12obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
13obj-$(CONFIG_QCOM_SMSM) += smsm.o 13obj-$(CONFIG_QCOM_SMSM) += smsm.o
14obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o 14obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
15obj-$(CONFIG_QCOM_APR) += apr.o
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
new file mode 100644
index 000000000000..57af8a537332
--- /dev/null
+++ b/drivers/soc/qcom/apr.c
@@ -0,0 +1,378 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/device.h>
8#include <linux/spinlock.h>
9#include <linux/idr.h>
10#include <linux/slab.h>
11#include <linux/of_device.h>
12#include <linux/soc/qcom/apr.h>
13#include <linux/rpmsg.h>
14#include <linux/of.h>
15
16struct apr {
17 struct rpmsg_endpoint *ch;
18 struct device *dev;
19 spinlock_t svcs_lock;
20 struct idr svcs_idr;
21 int dest_domain_id;
22};
23
24/**
25 * apr_send_pkt() - Send a apr message from apr device
26 *
27 * @adev: Pointer to previously registered apr device.
28 * @pkt: Pointer to apr packet to send
29 *
30 * Return: Will be an negative on packet size on success.
31 */
32int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
33{
34 struct apr *apr = dev_get_drvdata(adev->dev.parent);
35 struct apr_hdr *hdr;
36 unsigned long flags;
37 int ret;
38
39 spin_lock_irqsave(&adev->lock, flags);
40
41 hdr = &pkt->hdr;
42 hdr->src_domain = APR_DOMAIN_APPS;
43 hdr->src_svc = adev->svc_id;
44 hdr->dest_domain = adev->domain_id;
45 hdr->dest_svc = adev->svc_id;
46
47 ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
48 spin_unlock_irqrestore(&adev->lock, flags);
49
50 return ret ? ret : hdr->pkt_size;
51}
52EXPORT_SYMBOL_GPL(apr_send_pkt);
53
54static void apr_dev_release(struct device *dev)
55{
56 struct apr_device *adev = to_apr_device(dev);
57
58 kfree(adev);
59}
60
61static int apr_callback(struct rpmsg_device *rpdev, void *buf,
62 int len, void *priv, u32 addr)
63{
64 struct apr *apr = dev_get_drvdata(&rpdev->dev);
65 uint16_t hdr_size, msg_type, ver, svc_id;
66 struct apr_device *svc = NULL;
67 struct apr_driver *adrv = NULL;
68 struct apr_resp_pkt resp;
69 struct apr_hdr *hdr;
70 unsigned long flags;
71
72 if (len <= APR_HDR_SIZE) {
73 dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n",
74 buf, len);
75 return -EINVAL;
76 }
77
78 hdr = buf;
79 ver = APR_HDR_FIELD_VER(hdr->hdr_field);
80 if (ver > APR_PKT_VER + 1)
81 return -EINVAL;
82
83 hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field);
84 if (hdr_size < APR_HDR_SIZE) {
85 dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size);
86 return -EINVAL;
87 }
88
89 if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) {
90 dev_err(apr->dev, "APR: Wrong paket size\n");
91 return -EINVAL;
92 }
93
94 msg_type = APR_HDR_FIELD_MT(hdr->hdr_field);
95 if (msg_type >= APR_MSG_TYPE_MAX) {
96 dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type);
97 return -EINVAL;
98 }
99
100 if (hdr->src_domain >= APR_DOMAIN_MAX ||
101 hdr->dest_domain >= APR_DOMAIN_MAX ||
102 hdr->src_svc >= APR_SVC_MAX ||
103 hdr->dest_svc >= APR_SVC_MAX) {
104 dev_err(apr->dev, "APR: Wrong APR header\n");
105 return -EINVAL;
106 }
107
108 svc_id = hdr->dest_svc;
109 spin_lock_irqsave(&apr->svcs_lock, flags);
110 svc = idr_find(&apr->svcs_idr, svc_id);
111 if (svc && svc->dev.driver)
112 adrv = to_apr_driver(svc->dev.driver);
113 spin_unlock_irqrestore(&apr->svcs_lock, flags);
114
115 if (!adrv) {
116 dev_err(apr->dev, "APR: service is not registered\n");
117 return -EINVAL;
118 }
119
120 resp.hdr = *hdr;
121 resp.payload_size = hdr->pkt_size - hdr_size;
122
123 /*
124 * NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include
125 * optional headers in to apr_hdr which should be ignored
126 */
127 if (resp.payload_size > 0)
128 resp.payload = buf + hdr_size;
129
130 adrv->callback(svc, &resp);
131
132 return 0;
133}
134
135static int apr_device_match(struct device *dev, struct device_driver *drv)
136{
137 struct apr_device *adev = to_apr_device(dev);
138 struct apr_driver *adrv = to_apr_driver(drv);
139 const struct apr_device_id *id = adrv->id_table;
140
141 /* Attempt an OF style match first */
142 if (of_driver_match_device(dev, drv))
143 return 1;
144
145 if (!id)
146 return 0;
147
148 while (id->domain_id != 0 || id->svc_id != 0) {
149 if (id->domain_id == adev->domain_id &&
150 id->svc_id == adev->svc_id)
151 return 1;
152 id++;
153 }
154
155 return 0;
156}
157
158static int apr_device_probe(struct device *dev)
159{
160 struct apr_device *adev = to_apr_device(dev);
161 struct apr_driver *adrv = to_apr_driver(dev->driver);
162
163 return adrv->probe(adev);
164}
165
166static int apr_device_remove(struct device *dev)
167{
168 struct apr_device *adev = to_apr_device(dev);
169 struct apr_driver *adrv;
170 struct apr *apr = dev_get_drvdata(adev->dev.parent);
171
172 if (dev->driver) {
173 adrv = to_apr_driver(dev->driver);
174 if (adrv->remove)
175 adrv->remove(adev);
176 spin_lock(&apr->svcs_lock);
177 idr_remove(&apr->svcs_idr, adev->svc_id);
178 spin_unlock(&apr->svcs_lock);
179 }
180
181 return 0;
182}
183
184static int apr_uevent(struct device *dev, struct kobj_uevent_env *env)
185{
186 struct apr_device *adev = to_apr_device(dev);
187 int ret;
188
189 ret = of_device_uevent_modalias(dev, env);
190 if (ret != -ENODEV)
191 return ret;
192
193 return add_uevent_var(env, "MODALIAS=apr:%s", adev->name);
194}
195
196struct bus_type aprbus = {
197 .name = "aprbus",
198 .match = apr_device_match,
199 .probe = apr_device_probe,
200 .uevent = apr_uevent,
201 .remove = apr_device_remove,
202};
203EXPORT_SYMBOL_GPL(aprbus);
204
205static int apr_add_device(struct device *dev, struct device_node *np,
206 const struct apr_device_id *id)
207{
208 struct apr *apr = dev_get_drvdata(dev);
209 struct apr_device *adev = NULL;
210 int ret;
211
212 adev = kzalloc(sizeof(*adev), GFP_KERNEL);
213 if (!adev)
214 return -ENOMEM;
215
216 spin_lock_init(&adev->lock);
217
218 adev->svc_id = id->svc_id;
219 adev->domain_id = id->domain_id;
220 adev->version = id->svc_version;
221 if (np)
222 strncpy(adev->name, np->name, APR_NAME_SIZE);
223 else
224 strncpy(adev->name, id->name, APR_NAME_SIZE);
225
226 dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
227 id->domain_id, id->svc_id);
228
229 adev->dev.bus = &aprbus;
230 adev->dev.parent = dev;
231 adev->dev.of_node = np;
232 adev->dev.release = apr_dev_release;
233 adev->dev.driver = NULL;
234
235 spin_lock(&apr->svcs_lock);
236 idr_alloc(&apr->svcs_idr, adev, id->svc_id,
237 id->svc_id + 1, GFP_ATOMIC);
238 spin_unlock(&apr->svcs_lock);
239
240 dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
241
242 ret = device_register(&adev->dev);
243 if (ret) {
244 dev_err(dev, "device_register failed: %d\n", ret);
245 put_device(&adev->dev);
246 }
247
248 return ret;
249}
250
251static void of_register_apr_devices(struct device *dev)
252{
253 struct apr *apr = dev_get_drvdata(dev);
254 struct device_node *node;
255
256 for_each_child_of_node(dev->of_node, node) {
257 struct apr_device_id id = { {0} };
258
259 if (of_property_read_u32(node, "reg", &id.svc_id))
260 continue;
261
262 id.domain_id = apr->dest_domain_id;
263
264 if (apr_add_device(dev, node, &id))
265 dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
266 }
267}
268
269static int apr_probe(struct rpmsg_device *rpdev)
270{
271 struct device *dev = &rpdev->dev;
272 struct apr *apr;
273 int ret;
274
275 apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
276 if (!apr)
277 return -ENOMEM;
278
279 ret = of_property_read_u32(dev->of_node, "reg", &apr->dest_domain_id);
280 if (ret) {
281 dev_err(dev, "APR Domain ID not specified in DT\n");
282 return ret;
283 }
284
285 dev_set_drvdata(dev, apr);
286 apr->ch = rpdev->ept;
287 apr->dev = dev;
288 spin_lock_init(&apr->svcs_lock);
289 idr_init(&apr->svcs_idr);
290 of_register_apr_devices(dev);
291
292 return 0;
293}
294
295static int apr_remove_device(struct device *dev, void *null)
296{
297 struct apr_device *adev = to_apr_device(dev);
298
299 device_unregister(&adev->dev);
300
301 return 0;
302}
303
304static void apr_remove(struct rpmsg_device *rpdev)
305{
306 device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
307}
308
309/*
310 * __apr_driver_register() - Client driver registration with aprbus
311 *
312 * @drv:Client driver to be associated with client-device.
313 * @owner: owning module/driver
314 *
315 * This API will register the client driver with the aprbus
316 * It is called from the driver's module-init function.
317 */
318int __apr_driver_register(struct apr_driver *drv, struct module *owner)
319{
320 drv->driver.bus = &aprbus;
321 drv->driver.owner = owner;
322
323 return driver_register(&drv->driver);
324}
325EXPORT_SYMBOL_GPL(__apr_driver_register);
326
327/*
328 * apr_driver_unregister() - Undo effect of apr_driver_register
329 *
330 * @drv: Client driver to be unregistered
331 */
332void apr_driver_unregister(struct apr_driver *drv)
333{
334 driver_unregister(&drv->driver);
335}
336EXPORT_SYMBOL_GPL(apr_driver_unregister);
337
338static const struct of_device_id apr_of_match[] = {
339 { .compatible = "qcom,apr"},
340 { .compatible = "qcom,apr-v2"},
341 {}
342};
343MODULE_DEVICE_TABLE(of, apr_of_match);
344
345static struct rpmsg_driver apr_driver = {
346 .probe = apr_probe,
347 .remove = apr_remove,
348 .callback = apr_callback,
349 .drv = {
350 .name = "qcom,apr",
351 .of_match_table = apr_of_match,
352 },
353};
354
355static int __init apr_init(void)
356{
357 int ret;
358
359 ret = bus_register(&aprbus);
360 if (!ret)
361 ret = register_rpmsg_driver(&apr_driver);
362 else
363 bus_unregister(&aprbus);
364
365 return ret;
366}
367
368static void __exit apr_exit(void)
369{
370 bus_unregister(&aprbus);
371 unregister_rpmsg_driver(&apr_driver);
372}
373
374subsys_initcall(apr_init);
375module_exit(apr_exit);
376
377MODULE_LICENSE("GPL v2");
378MODULE_DESCRIPTION("Qualcomm APR Bus");
diff --git a/include/dt-bindings/soc/qcom,apr.h b/include/dt-bindings/soc/qcom,apr.h
new file mode 100644
index 000000000000..006362400c0f
--- /dev/null
+++ b/include/dt-bindings/soc/qcom,apr.h
@@ -0,0 +1,28 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_QCOM_APR_H
3#define __DT_BINDINGS_QCOM_APR_H
4
5/* Domain IDs */
6#define APR_DOMAIN_SIM 0x1
7#define APR_DOMAIN_PC 0x2
8#define APR_DOMAIN_MODEM 0x3
9#define APR_DOMAIN_ADSP 0x4
10#define APR_DOMAIN_APPS 0x5
11#define APR_DOMAIN_MAX 0x6
12
13/* ADSP service IDs */
14#define APR_SVC_ADSP_CORE 0x3
15#define APR_SVC_AFE 0x4
16#define APR_SVC_VSM 0x5
17#define APR_SVC_VPM 0x6
18#define APR_SVC_ASM 0x7
19#define APR_SVC_ADM 0x8
20#define APR_SVC_ADSP_MVM 0x09
21#define APR_SVC_ADSP_CVS 0x0A
22#define APR_SVC_ADSP_CVP 0x0B
23#define APR_SVC_USM 0x0C
24#define APR_SVC_LSM 0x0D
25#define APR_SVC_VIDC 0x16
26#define APR_SVC_MAX 0x17
27
28#endif /* __DT_BINDINGS_QCOM_APR_H */
diff --git a/include/dt-bindings/sound/fsl-imx-audmux.h b/include/dt-bindings/sound/fsl-imx-audmux.h
index 751fe1416f95..15f138bebe16 100644
--- a/include/dt-bindings/sound/fsl-imx-audmux.h
+++ b/include/dt-bindings/sound/fsl-imx-audmux.h
@@ -25,6 +25,13 @@
25#define MX51_AUDMUX_PORT6 5 25#define MX51_AUDMUX_PORT6 5
26#define MX51_AUDMUX_PORT7 6 26#define MX51_AUDMUX_PORT7 6
27 27
28/*
29 * TFCSEL/RFCSEL (i.MX27) or TFSEL/TCSEL/RFSEL/RCSEL (i.MX31/51/53/6Q)
30 * can be sourced from Rx/Tx.
31 */
32#define IMX_AUDMUX_RXFS 0x8
33#define IMX_AUDMUX_RXCLK 0x8
34
28/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */ 35/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
29#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff) 36#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
30#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8) 37#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
diff --git a/include/dt-bindings/sound/qcom,q6afe.h b/include/dt-bindings/sound/qcom,q6afe.h
new file mode 100644
index 000000000000..e2d3892240b8
--- /dev/null
+++ b/include/dt-bindings/sound/qcom,q6afe.h
@@ -0,0 +1,111 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_Q6_AFE_H__
3#define __DT_BINDINGS_Q6_AFE_H__
4
5/* Audio Front End (AFE) virtual ports IDs */
6#define HDMI_RX 1
7#define SLIMBUS_0_RX 2
8#define SLIMBUS_0_TX 3
9#define SLIMBUS_1_RX 4
10#define SLIMBUS_1_TX 5
11#define SLIMBUS_2_RX 6
12#define SLIMBUS_2_TX 7
13#define SLIMBUS_3_RX 8
14#define SLIMBUS_3_TX 9
15#define SLIMBUS_4_RX 10
16#define SLIMBUS_4_TX 11
17#define SLIMBUS_5_RX 12
18#define SLIMBUS_5_TX 13
19#define SLIMBUS_6_RX 14
20#define SLIMBUS_6_TX 15
21#define PRIMARY_MI2S_RX 16
22#define PRIMARY_MI2S_TX 17
23#define SECONDARY_MI2S_RX 18
24#define SECONDARY_MI2S_TX 19
25#define TERTIARY_MI2S_RX 20
26#define TERTIARY_MI2S_TX 21
27#define QUATERNARY_MI2S_RX 22
28#define QUATERNARY_MI2S_TX 23
29#define PRIMARY_TDM_RX_0 24
30#define PRIMARY_TDM_TX_0 25
31#define PRIMARY_TDM_RX_1 26
32#define PRIMARY_TDM_TX_1 27
33#define PRIMARY_TDM_RX_2 28
34#define PRIMARY_TDM_TX_2 29
35#define PRIMARY_TDM_RX_3 30
36#define PRIMARY_TDM_TX_3 31
37#define PRIMARY_TDM_RX_4 32
38#define PRIMARY_TDM_TX_4 33
39#define PRIMARY_TDM_RX_5 34
40#define PRIMARY_TDM_TX_5 35
41#define PRIMARY_TDM_RX_6 36
42#define PRIMARY_TDM_TX_6 37
43#define PRIMARY_TDM_RX_7 38
44#define PRIMARY_TDM_TX_7 39
45#define SECONDARY_TDM_RX_0 40
46#define SECONDARY_TDM_TX_0 41
47#define SECONDARY_TDM_RX_1 42
48#define SECONDARY_TDM_TX_1 43
49#define SECONDARY_TDM_RX_2 44
50#define SECONDARY_TDM_TX_2 45
51#define SECONDARY_TDM_RX_3 46
52#define SECONDARY_TDM_TX_3 47
53#define SECONDARY_TDM_RX_4 48
54#define SECONDARY_TDM_TX_4 49
55#define SECONDARY_TDM_RX_5 50
56#define SECONDARY_TDM_TX_5 51
57#define SECONDARY_TDM_RX_6 52
58#define SECONDARY_TDM_TX_6 53
59#define SECONDARY_TDM_RX_7 54
60#define SECONDARY_TDM_TX_7 55
61#define TERTIARY_TDM_RX_0 56
62#define TERTIARY_TDM_TX_0 57
63#define TERTIARY_TDM_RX_1 58
64#define TERTIARY_TDM_TX_1 59
65#define TERTIARY_TDM_RX_2 60
66#define TERTIARY_TDM_TX_2 61
67#define TERTIARY_TDM_RX_3 62
68#define TERTIARY_TDM_TX_3 63
69#define TERTIARY_TDM_RX_4 64
70#define TERTIARY_TDM_TX_4 65
71#define TERTIARY_TDM_RX_5 66
72#define TERTIARY_TDM_TX_5 67
73#define TERTIARY_TDM_RX_6 68
74#define TERTIARY_TDM_TX_6 69
75#define TERTIARY_TDM_RX_7 70
76#define TERTIARY_TDM_TX_7 71
77#define QUATERNARY_TDM_RX_0 72
78#define QUATERNARY_TDM_TX_0 73
79#define QUATERNARY_TDM_RX_1 74
80#define QUATERNARY_TDM_TX_1 75
81#define QUATERNARY_TDM_RX_2 76
82#define QUATERNARY_TDM_TX_2 77
83#define QUATERNARY_TDM_RX_3 78
84#define QUATERNARY_TDM_TX_3 79
85#define QUATERNARY_TDM_RX_4 80
86#define QUATERNARY_TDM_TX_4 81
87#define QUATERNARY_TDM_RX_5 82
88#define QUATERNARY_TDM_TX_5 83
89#define QUATERNARY_TDM_RX_6 84
90#define QUATERNARY_TDM_TX_6 85
91#define QUATERNARY_TDM_RX_7 86
92#define QUATERNARY_TDM_TX_7 87
93#define QUINARY_TDM_RX_0 88
94#define QUINARY_TDM_TX_0 89
95#define QUINARY_TDM_RX_1 90
96#define QUINARY_TDM_TX_1 91
97#define QUINARY_TDM_RX_2 92
98#define QUINARY_TDM_TX_2 93
99#define QUINARY_TDM_RX_3 94
100#define QUINARY_TDM_TX_3 95
101#define QUINARY_TDM_RX_4 96
102#define QUINARY_TDM_TX_4 97
103#define QUINARY_TDM_RX_5 98
104#define QUINARY_TDM_TX_5 99
105#define QUINARY_TDM_RX_6 100
106#define QUINARY_TDM_TX_6 101
107#define QUINARY_TDM_RX_7 102
108#define QUINARY_TDM_TX_7 103
109
110#endif /* __DT_BINDINGS_Q6_AFE_H__ */
111
diff --git a/include/dt-bindings/sound/qcom,q6asm.h b/include/dt-bindings/sound/qcom,q6asm.h
new file mode 100644
index 000000000000..1eb77d87c2e8
--- /dev/null
+++ b/include/dt-bindings/sound/qcom,q6asm.h
@@ -0,0 +1,22 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_BINDINGS_Q6_ASM_H__
3#define __DT_BINDINGS_Q6_ASM_H__
4
5#define MSM_FRONTEND_DAI_MULTIMEDIA1 0
6#define MSM_FRONTEND_DAI_MULTIMEDIA2 1
7#define MSM_FRONTEND_DAI_MULTIMEDIA3 2
8#define MSM_FRONTEND_DAI_MULTIMEDIA4 3
9#define MSM_FRONTEND_DAI_MULTIMEDIA5 4
10#define MSM_FRONTEND_DAI_MULTIMEDIA6 5
11#define MSM_FRONTEND_DAI_MULTIMEDIA7 6
12#define MSM_FRONTEND_DAI_MULTIMEDIA8 7
13#define MSM_FRONTEND_DAI_MULTIMEDIA9 8
14#define MSM_FRONTEND_DAI_MULTIMEDIA10 9
15#define MSM_FRONTEND_DAI_MULTIMEDIA11 10
16#define MSM_FRONTEND_DAI_MULTIMEDIA12 11
17#define MSM_FRONTEND_DAI_MULTIMEDIA13 12
18#define MSM_FRONTEND_DAI_MULTIMEDIA14 13
19#define MSM_FRONTEND_DAI_MULTIMEDIA15 14
20#define MSM_FRONTEND_DAI_MULTIMEDIA16 15
21
22#endif /* __DT_BINDINGS_Q6_ASM_H__ */
diff --git a/include/dt-bindings/sound/rt5640.h b/include/dt-bindings/sound/rt5640.h
new file mode 100644
index 000000000000..154c9b4414f2
--- /dev/null
+++ b/include/dt-bindings/sound/rt5640.h
@@ -0,0 +1,25 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __DT_RT5640_H
3#define __DT_RT5640_H
4
5#define RT5640_DMIC1_DATA_PIN_NONE 0
6#define RT5640_DMIC1_DATA_PIN_IN1P 1
7#define RT5640_DMIC1_DATA_PIN_GPIO3 2
8
9#define RT5640_DMIC2_DATA_PIN_NONE 0
10#define RT5640_DMIC2_DATA_PIN_IN1N 1
11#define RT5640_DMIC2_DATA_PIN_GPIO4 2
12
13#define RT5640_JD_SRC_GPIO1 1
14#define RT5640_JD_SRC_JD1_IN4P 2
15#define RT5640_JD_SRC_JD2_IN4N 3
16#define RT5640_JD_SRC_GPIO2 4
17#define RT5640_JD_SRC_GPIO3 5
18#define RT5640_JD_SRC_GPIO4 6
19
20#define RT5640_OVCD_SF_0P5 0
21#define RT5640_OVCD_SF_0P75 1
22#define RT5640_OVCD_SF_1P0 2
23#define RT5640_OVCD_SF_1P5 3
24
25#endif /* __DT_RT5640_H */
diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h
index bd581c6fa085..0bc41c4c0429 100644
--- a/include/linux/mfd/wm8350/audio.h
+++ b/include/linux/mfd/wm8350/audio.h
@@ -617,11 +617,8 @@ struct wm8350_audio_platform_data {
617 u32 codec_current_charge:2; /* codec current @ vmid charge */ 617 u32 codec_current_charge:2; /* codec current @ vmid charge */
618}; 618};
619 619
620struct snd_soc_codec;
621
622struct wm8350_codec { 620struct wm8350_codec {
623 struct platform_device *pdev; 621 struct platform_device *pdev;
624 struct snd_soc_codec *codec;
625 struct wm8350_audio_platform_data *platform_data; 622 struct wm8350_audio_platform_data *platform_data;
626}; 623};
627 624
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 7d361be2e24f..2014bd19f28e 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -471,6 +471,17 @@ struct slim_device_id {
471 kernel_ulong_t driver_data; 471 kernel_ulong_t driver_data;
472}; 472};
473 473
474#define APR_NAME_SIZE 32
475#define APR_MODULE_PREFIX "apr:"
476
477struct apr_device_id {
478 char name[APR_NAME_SIZE];
479 __u32 domain_id;
480 __u32 svc_id;
481 __u32 svc_version;
482 kernel_ulong_t driver_data; /* Data private to the driver */
483};
484
474#define SPMI_NAME_SIZE 32 485#define SPMI_NAME_SIZE 32
475#define SPMI_MODULE_PREFIX "spmi:" 486#define SPMI_MODULE_PREFIX "spmi:"
476 487
diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h
new file mode 100644
index 000000000000..c5d52e2cb275
--- /dev/null
+++ b/include/linux/soc/qcom/apr.h
@@ -0,0 +1,128 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __QCOM_APR_H_
4#define __QCOM_APR_H_
5
6#include <linux/spinlock.h>
7#include <linux/device.h>
8#include <linux/mod_devicetable.h>
9#include <dt-bindings/soc/qcom,apr.h>
10
11extern struct bus_type aprbus;
12
13#define APR_HDR_LEN(hdr_len) ((hdr_len)/4)
14
15/*
16 * HEADER field
17 * version:0:3
18 * header_size : 4:7
19 * message_type : 8:9
20 * reserved: 10:15
21 */
22#define APR_HDR_FIELD(msg_type, hdr_len, ver)\
23 (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF))
24
25#define APR_HDR_SIZE sizeof(struct apr_hdr)
26#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
27 APR_HDR_LEN(APR_HDR_SIZE), \
28 APR_PKT_VER)
29/* Version */
30#define APR_PKT_VER 0x0
31
32/* Command and Response Types */
33#define APR_MSG_TYPE_EVENT 0x0
34#define APR_MSG_TYPE_CMD_RSP 0x1
35#define APR_MSG_TYPE_SEQ_CMD 0x2
36#define APR_MSG_TYPE_NSEQ_CMD 0x3
37#define APR_MSG_TYPE_MAX 0x04
38
39/* APR Basic Response Message */
40#define APR_BASIC_RSP_RESULT 0x000110E8
41#define APR_RSP_ACCEPTED 0x000100BE
42
43struct aprv2_ibasic_rsp_result_t {
44 uint32_t opcode;
45 uint32_t status;
46};
47
48/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */
49#define APR_HDR_FIELD_VER(h) (h & 0x000F)
50#define APR_HDR_FIELD_SIZE(h) ((h & 0x00F0) >> 4)
51#define APR_HDR_FIELD_SIZE_BYTES(h) (((h & 0x00F0) >> 4) * 4)
52#define APR_HDR_FIELD_MT(h) ((h & 0x0300) >> 8)
53
54struct apr_hdr {
55 uint16_t hdr_field;
56 uint16_t pkt_size;
57 uint8_t src_svc;
58 uint8_t src_domain;
59 uint16_t src_port;
60 uint8_t dest_svc;
61 uint8_t dest_domain;
62 uint16_t dest_port;
63 uint32_t token;
64 uint32_t opcode;
65} __packed;
66
67struct apr_pkt {
68 struct apr_hdr hdr;
69 uint8_t payload[];
70};
71
72struct apr_resp_pkt {
73 struct apr_hdr hdr;
74 void *payload;
75 int payload_size;
76};
77
78/* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */
79#define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF)
80#define APR_SVC_MINOR_VERSION(v) (v & 0xFF)
81
82struct apr_device {
83 struct device dev;
84 uint16_t svc_id;
85 uint16_t domain_id;
86 uint32_t version;
87 char name[APR_NAME_SIZE];
88 spinlock_t lock;
89 struct list_head node;
90};
91
92#define to_apr_device(d) container_of(d, struct apr_device, dev)
93
94struct apr_driver {
95 int (*probe)(struct apr_device *sl);
96 int (*remove)(struct apr_device *sl);
97 int (*callback)(struct apr_device *a,
98 struct apr_resp_pkt *d);
99 struct device_driver driver;
100 const struct apr_device_id *id_table;
101};
102
103#define to_apr_driver(d) container_of(d, struct apr_driver, driver)
104
105/*
106 * use a macro to avoid include chaining to get THIS_MODULE
107 */
108#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE)
109
110int __apr_driver_register(struct apr_driver *drv, struct module *owner);
111void apr_driver_unregister(struct apr_driver *drv);
112
113/**
114 * module_apr_driver() - Helper macro for registering a aprbus driver
115 * @__aprbus_driver: aprbus_driver struct
116 *
117 * Helper macro for aprbus drivers which do not do anything special in
118 * module init/exit. This eliminates a lot of boilerplate. Each module
119 * may only use this macro once, and calling it replaces module_init()
120 * and module_exit()
121 */
122#define module_apr_driver(__apr_driver) \
123 module_driver(__apr_driver, apr_driver_register, \
124 apr_driver_unregister)
125
126int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt);
127
128#endif /* __QCOM_APR_H_ */
diff --git a/include/sound/omap-pcm.h b/include/sound/omap-pcm.h
deleted file mode 100644
index c1d2f31d71e9..000000000000
--- a/include/sound/omap-pcm.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * omap-pcm.h - OMAP PCM driver
3 *
4 * Copyright (C) 2014 Texas Instruments, Inc.
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __OMAP_PCM_H__
19#define __OMAP_PCM_H__
20
21#if IS_ENABLED(CONFIG_SND_OMAP_SOC)
22int omap_pcm_platform_register(struct device *dev);
23#else
24static inline int omap_pcm_platform_register(struct device *dev)
25{
26 return 0;
27}
28#endif /* CONFIG_SND_OMAP_SOC */
29
30#endif /* __OMAP_PCM_H__ */
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
deleted file mode 100644
index e3c84b92ff70..000000000000
--- a/include/sound/rt5640.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * linux/sound/rt5640.h -- Platform data for RT5640
3 *
4 * Copyright 2011 Realtek Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_RT5640_H
12#define __LINUX_SND_RT5640_H
13
14struct rt5640_platform_data {
15 /* IN1 & IN2 & IN3 can optionally be differential */
16 bool in1_diff;
17 bool in2_diff;
18 bool in3_diff;
19
20 bool dmic_en;
21 bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
22 bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
23
24 int ldo1_en; /* GPIO for LDO1_EN */
25};
26
27#endif
diff --git a/include/sound/rt5668.h b/include/sound/rt5668.h
new file mode 100644
index 000000000000..f907b78696cf
--- /dev/null
+++ b/include/sound/rt5668.h
@@ -0,0 +1,40 @@
1/*
2 * linux/sound/rt5668.h -- Platform data for RT5668
3 *
4 * Copyright 2018 Realtek Microelectronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_RT5668_H
12#define __LINUX_SND_RT5668_H
13
14enum rt5668_dmic1_data_pin {
15 RT5668_DMIC1_NULL,
16 RT5668_DMIC1_DATA_GPIO2,
17 RT5668_DMIC1_DATA_GPIO5,
18};
19
20enum rt5668_dmic1_clk_pin {
21 RT5668_DMIC1_CLK_GPIO1,
22 RT5668_DMIC1_CLK_GPIO3,
23};
24
25enum rt5668_jd_src {
26 RT5668_JD_NULL,
27 RT5668_JD1,
28};
29
30struct rt5668_platform_data {
31
32 int ldo1_en; /* GPIO for LDO1_EN */
33
34 enum rt5668_dmic1_data_pin dmic1_data_pin;
35 enum rt5668_dmic1_clk_pin dmic1_clk_pin;
36 enum rt5668_jd_src jd_src;
37};
38
39#endif
40
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 8ad11669e4d8..568f6a72c974 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -294,8 +294,8 @@ struct snd_soc_dai {
294 struct snd_soc_dai_driver *driver; 294 struct snd_soc_dai_driver *driver;
295 295
296 /* DAI runtime info */ 296 /* DAI runtime info */
297 unsigned int capture_active:1; /* stream is in use */ 297 unsigned int capture_active; /* stream usage count */
298 unsigned int playback_active:1; /* stream is in use */ 298 unsigned int playback_active; /* stream usage count */
299 unsigned int probed:1; 299 unsigned int probed:1;
300 300
301 unsigned int active; 301 unsigned int active;
@@ -313,7 +313,6 @@ struct snd_soc_dai {
313 unsigned int sample_bits; 313 unsigned int sample_bits;
314 314
315 /* parent platform/codec */ 315 /* parent platform/codec */
316 struct snd_soc_codec *codec;
317 struct snd_soc_component *component; 316 struct snd_soc_component *component;
318 317
319 /* CODEC TDM slot masks and params (for fixup) */ 318 /* CODEC TDM slot masks and params (for fixup) */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index ad266d7e9553..1378dcd2128a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -401,11 +401,7 @@ struct snd_soc_ops;
401struct snd_soc_pcm_runtime; 401struct snd_soc_pcm_runtime;
402struct snd_soc_dai; 402struct snd_soc_dai;
403struct snd_soc_dai_driver; 403struct snd_soc_dai_driver;
404struct snd_soc_platform;
405struct snd_soc_dai_link; 404struct snd_soc_dai_link;
406struct snd_soc_platform_driver;
407struct snd_soc_codec;
408struct snd_soc_codec_driver;
409struct snd_soc_component; 405struct snd_soc_component;
410struct snd_soc_component_driver; 406struct snd_soc_component_driver;
411struct soc_enum; 407struct soc_enum;
@@ -430,13 +426,6 @@ enum snd_soc_card_subclass {
430 SND_SOC_CARD_CLASS_RUNTIME = 1, 426 SND_SOC_CARD_CLASS_RUNTIME = 1,
431}; 427};
432 428
433int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
434 int source, unsigned int freq, int dir);
435int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
436 unsigned int freq_in, unsigned int freq_out);
437int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
438 struct snd_soc_jack *jack, void *data);
439
440int snd_soc_register_card(struct snd_soc_card *card); 429int snd_soc_register_card(struct snd_soc_card *card);
441int snd_soc_unregister_card(struct snd_soc_card *card); 430int snd_soc_unregister_card(struct snd_soc_card *card);
442int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card); 431int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
@@ -455,19 +444,6 @@ static inline int snd_soc_resume(struct device *dev)
455} 444}
456#endif 445#endif
457int snd_soc_poweroff(struct device *dev); 446int snd_soc_poweroff(struct device *dev);
458int snd_soc_register_platform(struct device *dev,
459 const struct snd_soc_platform_driver *platform_drv);
460int devm_snd_soc_register_platform(struct device *dev,
461 const struct snd_soc_platform_driver *platform_drv);
462void snd_soc_unregister_platform(struct device *dev);
463int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
464 const struct snd_soc_platform_driver *platform_drv);
465void snd_soc_remove_platform(struct snd_soc_platform *platform);
466struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev);
467int snd_soc_register_codec(struct device *dev,
468 const struct snd_soc_codec_driver *codec_drv,
469 struct snd_soc_dai_driver *dai_drv, int num_dai);
470void snd_soc_unregister_codec(struct device *dev);
471int snd_soc_add_component(struct device *dev, 447int snd_soc_add_component(struct device *dev,
472 struct snd_soc_component *component, 448 struct snd_soc_component *component,
473 const struct snd_soc_component_driver *component_driver, 449 const struct snd_soc_component_driver *component_driver,
@@ -482,16 +458,15 @@ int devm_snd_soc_register_component(struct device *dev,
482void snd_soc_unregister_component(struct device *dev); 458void snd_soc_unregister_component(struct device *dev);
483struct snd_soc_component *snd_soc_lookup_component(struct device *dev, 459struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
484 const char *driver_name); 460 const char *driver_name);
485int snd_soc_cache_init(struct snd_soc_codec *codec);
486int snd_soc_cache_exit(struct snd_soc_codec *codec);
487 461
488int snd_soc_platform_read(struct snd_soc_platform *platform,
489 unsigned int reg);
490int snd_soc_platform_write(struct snd_soc_platform *platform,
491 unsigned int reg, unsigned int val);
492int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); 462int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
493#ifdef CONFIG_SND_SOC_COMPRESS 463#ifdef CONFIG_SND_SOC_COMPRESS
494int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); 464int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
465#else
466static inline int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
467{
468 return 0;
469}
495#endif 470#endif
496 471
497void snd_soc_disconnect_sync(struct device *dev); 472void snd_soc_disconnect_sync(struct device *dev);
@@ -576,23 +551,7 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
576} 551}
577#endif 552#endif
578 553
579/* codec register bit access */
580int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
581 unsigned int mask, unsigned int value);
582int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
583 unsigned int reg, unsigned int mask,
584 unsigned int value);
585int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
586 unsigned int mask, unsigned int value);
587
588#ifdef CONFIG_SND_SOC_AC97_BUS 554#ifdef CONFIG_SND_SOC_AC97_BUS
589#define snd_soc_alloc_ac97_codec(codec) \
590 snd_soc_alloc_ac97_component(&codec->component)
591#define snd_soc_new_ac97_codec(codec, id, id_mask) \
592 snd_soc_new_ac97_component(&codec->component, id, id_mask)
593#define snd_soc_free_ac97_codec(ac97) \
594 snd_soc_free_ac97_component(ac97)
595
596struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component); 555struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
597struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component, 556struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
598 unsigned int id, unsigned int id_mask); 557 unsigned int id, unsigned int id_mask);
@@ -626,10 +585,6 @@ struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
626 const char *name); 585 const char *name);
627int snd_soc_add_component_controls(struct snd_soc_component *component, 586int snd_soc_add_component_controls(struct snd_soc_component *component,
628 const struct snd_kcontrol_new *controls, unsigned int num_controls); 587 const struct snd_kcontrol_new *controls, unsigned int num_controls);
629int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
630 const struct snd_kcontrol_new *controls, unsigned int num_controls);
631int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
632 const struct snd_kcontrol_new *controls, unsigned int num_controls);
633int snd_soc_add_card_controls(struct snd_soc_card *soc_card, 588int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
634 const struct snd_kcontrol_new *controls, int num_controls); 589 const struct snd_kcontrol_new *controls, int num_controls);
635int snd_soc_add_dai_controls(struct snd_soc_dai *dai, 590int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
@@ -862,8 +817,6 @@ struct snd_soc_component {
862 817
863 unsigned int active; 818 unsigned int active;
864 819
865 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
866 unsigned int registered_as_component:1;
867 unsigned int suspended:1; /* is in suspend PM state */ 820 unsigned int suspended:1; /* is in suspend PM state */
868 821
869 struct list_head list; 822 struct list_head list;
@@ -875,9 +828,6 @@ struct snd_soc_component {
875 struct list_head dai_list; 828 struct list_head dai_list;
876 int num_dai; 829 int num_dai;
877 830
878 int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
879 int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
880
881 struct regmap *regmap; 831 struct regmap *regmap;
882 int val_bytes; 832 int val_bytes;
883 833
@@ -886,10 +836,6 @@ struct snd_soc_component {
886 /* attached dynamic objects */ 836 /* attached dynamic objects */
887 struct list_head dobj_list; 837 struct list_head dobj_list;
888 838
889#ifdef CONFIG_DEBUG_FS
890 struct dentry *debugfs_root;
891#endif
892
893 /* 839 /*
894 * DO NOT use any of the fields below in drivers, they are temporary and 840 * DO NOT use any of the fields below in drivers, they are temporary and
895 * are going to be removed again soon. If you use them in driver code the 841 * are going to be removed again soon. If you use them in driver code the
@@ -899,29 +845,11 @@ struct snd_soc_component {
899 /* Don't use these, use snd_soc_component_get_dapm() */ 845 /* Don't use these, use snd_soc_component_get_dapm() */
900 struct snd_soc_dapm_context dapm; 846 struct snd_soc_dapm_context dapm;
901 847
902 struct snd_soc_codec *codec;
903
904 int (*probe)(struct snd_soc_component *);
905 void (*remove)(struct snd_soc_component *);
906 int (*suspend)(struct snd_soc_component *);
907 int (*resume)(struct snd_soc_component *);
908 int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
909 void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
910
911 int (*set_sysclk)(struct snd_soc_component *component,
912 int clk_id, int source, unsigned int freq, int dir);
913 int (*set_pll)(struct snd_soc_component *component, int pll_id,
914 int source, unsigned int freq_in, unsigned int freq_out);
915 int (*set_jack)(struct snd_soc_component *component,
916 struct snd_soc_jack *jack, void *data);
917 int (*set_bias_level)(struct snd_soc_component *component,
918 enum snd_soc_bias_level level);
919
920 /* machine specific init */ 848 /* machine specific init */
921 int (*init)(struct snd_soc_component *component); 849 int (*init)(struct snd_soc_component *component);
922 850
923#ifdef CONFIG_DEBUG_FS 851#ifdef CONFIG_DEBUG_FS
924 void (*init_debugfs)(struct snd_soc_component *component); 852 struct dentry *debugfs_root;
925 const char *debugfs_prefix; 853 const char *debugfs_prefix;
926#endif 854#endif
927}; 855};
@@ -938,97 +866,12 @@ snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
938#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \ 866#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
939 list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list) 867 list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
940 868
941/* SoC Audio Codec device */
942struct snd_soc_codec {
943 struct device *dev;
944 const struct snd_soc_codec_driver *driver;
945
946 struct list_head list;
947
948 /* runtime */
949 unsigned int cache_init:1; /* codec cache has been initialized */
950
951 /* codec IO */
952 void *control_data; /* codec control (i2c/3wire) data */
953 hw_write_t hw_write;
954 void *reg_cache;
955
956 /* component */
957 struct snd_soc_component component;
958};
959
960/* codec driver */
961struct snd_soc_codec_driver {
962
963 /* driver ops */
964 int (*probe)(struct snd_soc_codec *);
965 int (*remove)(struct snd_soc_codec *);
966 int (*suspend)(struct snd_soc_codec *);
967 int (*resume)(struct snd_soc_codec *);
968 struct snd_soc_component_driver component_driver;
969
970 /* codec wide operations */
971 int (*set_sysclk)(struct snd_soc_codec *codec,
972 int clk_id, int source, unsigned int freq, int dir);
973 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
974 unsigned int freq_in, unsigned int freq_out);
975 int (*set_jack)(struct snd_soc_codec *codec,
976 struct snd_soc_jack *jack, void *data);
977
978 /* codec IO */
979 struct regmap *(*get_regmap)(struct device *);
980 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
981 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
982 unsigned int reg_cache_size;
983 short reg_cache_step;
984 short reg_word_size;
985 const void *reg_cache_default;
986
987 /* codec bias level */
988 int (*set_bias_level)(struct snd_soc_codec *,
989 enum snd_soc_bias_level level);
990 bool idle_bias_off;
991 bool suspend_bias_off;
992
993 void (*seq_notifier)(struct snd_soc_dapm_context *,
994 enum snd_soc_dapm_type, int);
995
996 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
997};
998
999/* SoC platform interface */
1000struct snd_soc_platform_driver {
1001
1002 int (*probe)(struct snd_soc_platform *);
1003 int (*remove)(struct snd_soc_platform *);
1004 struct snd_soc_component_driver component_driver;
1005
1006 /* pcm creation and destruction */
1007 int (*pcm_new)(struct snd_soc_pcm_runtime *);
1008 void (*pcm_free)(struct snd_pcm *);
1009
1010 /* platform stream pcm ops */
1011 const struct snd_pcm_ops *ops;
1012
1013 /* platform stream compress ops */
1014 const struct snd_compr_ops *compr_ops;
1015};
1016
1017struct snd_soc_dai_link_component { 869struct snd_soc_dai_link_component {
1018 const char *name; 870 const char *name;
1019 struct device_node *of_node; 871 struct device_node *of_node;
1020 const char *dai_name; 872 const char *dai_name;
1021}; 873};
1022 874
1023struct snd_soc_platform {
1024 struct device *dev;
1025 const struct snd_soc_platform_driver *driver;
1026
1027 struct list_head list;
1028
1029 struct snd_soc_component component;
1030};
1031
1032struct snd_soc_dai_link { 875struct snd_soc_dai_link {
1033 /* config - must be set by machine driver */ 876 /* config - must be set by machine driver */
1034 const char *name; /* Codec name */ 877 const char *name; /* Codec name */
@@ -1276,8 +1119,6 @@ struct snd_soc_pcm_runtime {
1276 /* runtime devices */ 1119 /* runtime devices */
1277 struct snd_pcm *pcm; 1120 struct snd_pcm *pcm;
1278 struct snd_compr *compr; 1121 struct snd_compr *compr;
1279 struct snd_soc_codec *codec;
1280 struct snd_soc_platform *platform; /* will be removed */
1281 struct snd_soc_dai *codec_dai; 1122 struct snd_soc_dai *codec_dai;
1282 struct snd_soc_dai *cpu_dai; 1123 struct snd_soc_dai *cpu_dai;
1283 1124
@@ -1346,32 +1187,6 @@ struct soc_enum {
1346}; 1187};
1347 1188
1348/** 1189/**
1349 * snd_soc_component_to_codec() - Casts a component to the CODEC it is embedded in
1350 * @component: The component to cast to a CODEC
1351 *
1352 * This function must only be used on components that are known to be CODECs.
1353 * Otherwise the behavior is undefined.
1354 */
1355static inline struct snd_soc_codec *snd_soc_component_to_codec(
1356 struct snd_soc_component *component)
1357{
1358 return container_of(component, struct snd_soc_codec, component);
1359}
1360
1361/**
1362 * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in
1363 * @component: The component to cast to a platform
1364 *
1365 * This function must only be used on components that are known to be platforms.
1366 * Otherwise the behavior is undefined.
1367 */
1368static inline struct snd_soc_platform *snd_soc_component_to_platform(
1369 struct snd_soc_component *component)
1370{
1371 return container_of(component, struct snd_soc_platform, component);
1372}
1373
1374/**
1375 * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is 1190 * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
1376 * embedded in 1191 * embedded in
1377 * @dapm: The DAPM context to cast to the component 1192 * @dapm: The DAPM context to cast to the component
@@ -1387,33 +1202,6 @@ static inline struct snd_soc_component *snd_soc_dapm_to_component(
1387} 1202}
1388 1203
1389/** 1204/**
1390 * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
1391 * @dapm: The DAPM context to cast to the CODEC
1392 *
1393 * This function must only be used on DAPM contexts that are known to be part of
1394 * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
1395 */
1396static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
1397 struct snd_soc_dapm_context *dapm)
1398{
1399 return snd_soc_component_to_codec(snd_soc_dapm_to_component(dapm));
1400}
1401
1402/**
1403 * snd_soc_dapm_to_platform() - Casts a DAPM context to the platform it is
1404 * embedded in
1405 * @dapm: The DAPM context to cast to the platform.
1406 *
1407 * This function must only be used on DAPM contexts that are known to be part of
1408 * a platform (e.g. in a platform driver). Otherwise the behavior is undefined.
1409 */
1410static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
1411 struct snd_soc_dapm_context *dapm)
1412{
1413 return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
1414}
1415
1416/**
1417 * snd_soc_component_get_dapm() - Returns the DAPM context associated with a 1205 * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
1418 * component 1206 * component
1419 * @component: The component for which to get the DAPM context 1207 * @component: The component for which to get the DAPM context
@@ -1425,31 +1213,6 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
1425} 1213}
1426 1214
1427/** 1215/**
1428 * snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
1429 * @codec: The CODEC for which to get the DAPM context
1430 *
1431 * Note: Use this function instead of directly accessing the CODEC's dapm field
1432 */
1433static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
1434 struct snd_soc_codec *codec)
1435{
1436 return snd_soc_component_get_dapm(&codec->component);
1437}
1438
1439/**
1440 * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
1441 * @codec: The CODEC for which to initialize the DAPM bias level
1442 * @level: The DAPM level to initialize to
1443 *
1444 * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
1445 */
1446static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
1447 enum snd_soc_bias_level level)
1448{
1449 snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
1450}
1451
1452/**
1453 * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level 1216 * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
1454 * @component: The COMPONENT for which to initialize the DAPM bias level 1217 * @component: The COMPONENT for which to initialize the DAPM bias level
1455 * @level: The DAPM level to initialize to 1218 * @level: The DAPM level to initialize to
@@ -1465,18 +1228,6 @@ snd_soc_component_init_bias_level(struct snd_soc_component *component,
1465} 1228}
1466 1229
1467/** 1230/**
1468 * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
1469 * @codec: The CODEC for which to get the DAPM bias level
1470 *
1471 * Returns: The current DAPM bias level of the CODEC.
1472 */
1473static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
1474 struct snd_soc_codec *codec)
1475{
1476 return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
1477}
1478
1479/**
1480 * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level 1231 * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
1481 * @component: The COMPONENT for which to get the DAPM bias level 1232 * @component: The COMPONENT for which to get the DAPM bias level
1482 * 1233 *
@@ -1490,21 +1241,6 @@ snd_soc_component_get_bias_level(struct snd_soc_component *component)
1490} 1241}
1491 1242
1492/** 1243/**
1493 * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
1494 * @codec: The CODEC for which to set the level
1495 * @level: The level to set to
1496 *
1497 * Forces the CODEC bias level to a specific state. See
1498 * snd_soc_dapm_force_bias_level().
1499 */
1500static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
1501 enum snd_soc_bias_level level)
1502{
1503 return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
1504 level);
1505}
1506
1507/**
1508 * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level 1244 * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
1509 * @component: The COMPONENT for which to set the level 1245 * @component: The COMPONENT for which to set the level
1510 * @level: The level to set to 1246 * @level: The level to set to
@@ -1522,19 +1258,6 @@ snd_soc_component_force_bias_level(struct snd_soc_component *component,
1522} 1258}
1523 1259
1524/** 1260/**
1525 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
1526 * @kcontrol: The kcontrol
1527 *
1528 * This function must only be used on DAPM contexts that are known to be part of
1529 * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
1530 */
1531static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
1532 struct snd_kcontrol *kcontrol)
1533{
1534 return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
1535}
1536
1537/**
1538 * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol 1261 * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
1539 * @kcontrol: The kcontrol 1262 * @kcontrol: The kcontrol
1540 * 1263 *
@@ -1547,22 +1270,6 @@ static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
1547 return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol)); 1270 return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
1548} 1271}
1549 1272
1550/* codec IO */
1551unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
1552int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
1553 unsigned int val);
1554
1555/**
1556 * snd_soc_cache_sync() - Sync the register cache with the hardware
1557 * @codec: CODEC to sync
1558 *
1559 * Note: This function will call regcache_sync()
1560 */
1561static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
1562{
1563 return regcache_sync(codec->component.regmap);
1564}
1565
1566/** 1273/**
1567 * snd_soc_component_cache_sync() - Sync the register cache with the hardware 1274 * snd_soc_component_cache_sync() - Sync the register cache with the hardware
1568 * @component: COMPONENT to sync 1275 * @component: COMPONENT to sync
@@ -1605,37 +1312,6 @@ void snd_soc_component_init_regmap(struct snd_soc_component *component,
1605 struct regmap *regmap); 1312 struct regmap *regmap);
1606void snd_soc_component_exit_regmap(struct snd_soc_component *component); 1313void snd_soc_component_exit_regmap(struct snd_soc_component *component);
1607 1314
1608/**
1609 * snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
1610 * @codec: The CODEC for which to initialize the regmap instance
1611 * @regmap: The regmap instance that should be used by the CODEC
1612 *
1613 * This function allows deferred assignment of the regmap instance that is
1614 * associated with the CODEC. Only use this if the regmap instance is not yet
1615 * ready when the CODEC is registered. The function must also be called before
1616 * the first IO attempt of the CODEC.
1617 */
1618static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
1619 struct regmap *regmap)
1620{
1621 snd_soc_component_init_regmap(&codec->component, regmap);
1622}
1623
1624/**
1625 * snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
1626 * @codec: The CODEC for which to de-initialize the regmap instance
1627 *
1628 * Calls regmap_exit() on the regmap instance associated to the CODEC and
1629 * removes the regmap instance from the CODEC.
1630 *
1631 * This function should only be used if snd_soc_codec_init_regmap() was used to
1632 * initialize the regmap instance.
1633 */
1634static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
1635{
1636 snd_soc_component_exit_regmap(&codec->component);
1637}
1638
1639#endif 1315#endif
1640 1316
1641/* device driver data */ 1317/* device driver data */
@@ -1662,28 +1338,6 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
1662 return dev_get_drvdata(c->dev); 1338 return dev_get_drvdata(c->dev);
1663} 1339}
1664 1340
1665static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
1666 void *data)
1667{
1668 snd_soc_component_set_drvdata(&codec->component, data);
1669}
1670
1671static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
1672{
1673 return snd_soc_component_get_drvdata(&codec->component);
1674}
1675
1676static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
1677 void *data)
1678{
1679 snd_soc_component_set_drvdata(&platform->component, data);
1680}
1681
1682static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
1683{
1684 return snd_soc_component_get_drvdata(&platform->component);
1685}
1686
1687static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) 1341static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
1688{ 1342{
1689 INIT_LIST_HEAD(&card->widgets); 1343 INIT_LIST_HEAD(&card->widgets);
@@ -1735,20 +1389,15 @@ static inline bool snd_soc_component_is_active(
1735 return component->active != 0; 1389 return component->active != 0;
1736} 1390}
1737 1391
1738static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
1739{
1740 return snd_soc_component_is_active(&codec->component);
1741}
1742
1743/** 1392/**
1744 * snd_soc_kcontrol_component() - Returns the component that registered the 1393 * snd_soc_kcontrol_component() - Returns the component that registered the
1745 * control 1394 * control
1746 * @kcontrol: The control for which to get the component 1395 * @kcontrol: The control for which to get the component
1747 * 1396 *
1748 * Note: This function will work correctly if the control has been registered 1397 * Note: This function will work correctly if the control has been registered
1749 * for a component. Either with snd_soc_add_codec_controls() or 1398 * for a component. With snd_soc_add_codec_controls() or via table based
1750 * snd_soc_add_platform_controls() or via table based setup for either a 1399 * setup for either a CODEC or component driver. Otherwise the behavior is
1751 * CODEC, a platform or component driver. Otherwise the behavior is undefined. 1400 * undefined.
1752 */ 1401 */
1753static inline struct snd_soc_component *snd_soc_kcontrol_component( 1402static inline struct snd_soc_component *snd_soc_kcontrol_component(
1754 struct snd_kcontrol *kcontrol) 1403 struct snd_kcontrol *kcontrol)
@@ -1756,34 +1405,6 @@ static inline struct snd_soc_component *snd_soc_kcontrol_component(
1756 return snd_kcontrol_chip(kcontrol); 1405 return snd_kcontrol_chip(kcontrol);
1757} 1406}
1758 1407
1759/**
1760 * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
1761 * @kcontrol: The control for which to get the CODEC
1762 *
1763 * Note: This function will only work correctly if the control has been
1764 * registered with snd_soc_add_codec_controls() or via table based setup of
1765 * snd_soc_codec_driver. Otherwise the behavior is undefined.
1766 */
1767static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
1768 struct snd_kcontrol *kcontrol)
1769{
1770 return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
1771}
1772
1773/**
1774 * snd_soc_kcontrol_platform() - Returns the platform that registered the control
1775 * @kcontrol: The control for which to get the platform
1776 *
1777 * Note: This function will only work correctly if the control has been
1778 * registered with snd_soc_add_platform_controls() or via table based setup of
1779 * a snd_soc_platform_driver. Otherwise the behavior is undefined.
1780 */
1781static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
1782 struct snd_kcontrol *kcontrol)
1783{
1784 return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
1785}
1786
1787int snd_soc_util_init(void); 1408int snd_soc_util_init(void);
1788void snd_soc_util_exit(void); 1409void snd_soc_util_exit(void);
1789 1410
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index ccd1a3bdff46..40c300fe704d 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -12,7 +12,6 @@
12#define DAPM_ARROW(dir) (((dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-") 12#define DAPM_ARROW(dir) (((dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-")
13 13
14struct snd_soc_jack; 14struct snd_soc_jack;
15struct snd_soc_codec;
16struct snd_soc_card; 15struct snd_soc_card;
17struct snd_soc_dapm_widget; 16struct snd_soc_dapm_widget;
18struct snd_soc_dapm_path; 17struct snd_soc_dapm_path;
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h
index 69c37ecbff7e..a74ca232f1fc 100644
--- a/include/uapi/sound/asoc.h
+++ b/include/uapi/sound/asoc.h
@@ -139,6 +139,15 @@
139#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) 139#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1)
140#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) 140#define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
141 141
142/* DAI clock gating */
143#define SND_SOC_TPLG_DAI_CLK_GATE_UNDEFINED 0
144#define SND_SOC_TPLG_DAI_CLK_GATE_GATED 1
145#define SND_SOC_TPLG_DAI_CLK_GATE_CONT 2
146
147/* DAI mclk_direction */
148#define SND_SOC_TPLG_MCLK_CO 0 /* for codec, mclk is output */
149#define SND_SOC_TPLG_MCLK_CI 1 /* for codec, mclk is input */
150
142/* DAI physical PCM data formats. 151/* DAI physical PCM data formats.
143 * Add new formats to the end of the list. 152 * Add new formats to the end of the list.
144 */ 153 */
@@ -160,6 +169,18 @@
160#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) 169#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2)
161#define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3) 170#define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3)
162 171
172/* DAI topology BCLK parameter
173 * For the backwards capability, by default codec is bclk master
174 */
175#define SND_SOC_TPLG_BCLK_CM 0 /* codec is bclk master */
176#define SND_SOC_TPLG_BCLK_CS 1 /* codec is bclk slave */
177
178/* DAI topology FSYNC parameter
179 * For the backwards capability, by default codec is fsync master
180 */
181#define SND_SOC_TPLG_FSYNC_CM 0 /* codec is fsync master */
182#define SND_SOC_TPLG_FSYNC_CS 1 /* codec is fsync slave */
183
163/* 184/*
164 * Block Header. 185 * Block Header.
165 * This header precedes all object and object arrays below. 186 * This header precedes all object and object arrays below.
@@ -312,12 +333,12 @@ struct snd_soc_tplg_hw_config {
312 __le32 size; /* in bytes of this structure */ 333 __le32 size; /* in bytes of this structure */
313 __le32 id; /* unique ID - - used to match */ 334 __le32 id; /* unique ID - - used to match */
314 __le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */ 335 __le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */
315 __u8 clock_gated; /* 1 if clock can be gated to save power */ 336 __u8 clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */
316 __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */ 337 __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */
317 __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ 338 __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */
318 __u8 bclk_master; /* 1 for master of BCLK, 0 for slave */ 339 __u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */
319 __u8 fsync_master; /* 1 for master of FSYNC, 0 for slave */ 340 __u8 fsync_master; /* SND_SOC_TPLG_FSYNC_ value */
320 __u8 mclk_direction; /* 0 for input, 1 for output */ 341 __u8 mclk_direction; /* SND_SOC_TPLG_MCLK_ value */
321 __le16 reserved; /* for 32bit alignment */ 342 __le16 reserved; /* for 32bit alignment */
322 __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */ 343 __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */
323 __le32 bclk_rate; /* BCLK freqency in Hz */ 344 __le32 bclk_rate; /* BCLK freqency in Hz */
@@ -552,4 +573,61 @@ struct snd_soc_tplg_dai {
552 __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */ 573 __le32 flags; /* SND_SOC_TPLG_DAI_FLGBIT_* */
553 struct snd_soc_tplg_private priv; 574 struct snd_soc_tplg_private priv;
554} __attribute__((packed)); 575} __attribute__((packed));
576
577/*
578 * Old version of ABI structs, supported for backward compatibility.
579 */
580
581/* Manifest v4 */
582struct snd_soc_tplg_manifest_v4 {
583 __le32 size; /* in bytes of this structure */
584 __le32 control_elems; /* number of control elements */
585 __le32 widget_elems; /* number of widget elements */
586 __le32 graph_elems; /* number of graph elements */
587 __le32 pcm_elems; /* number of PCM elements */
588 __le32 dai_link_elems; /* number of DAI link elements */
589 struct snd_soc_tplg_private priv;
590} __packed;
591
592/* Stream Capabilities v4 */
593struct snd_soc_tplg_stream_caps_v4 {
594 __le32 size; /* in bytes of this structure */
595 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
596 __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
597 __le32 rates; /* supported rates SNDRV_PCM_RATE_* */
598 __le32 rate_min; /* min rate */
599 __le32 rate_max; /* max rate */
600 __le32 channels_min; /* min channels */
601 __le32 channels_max; /* max channels */
602 __le32 periods_min; /* min number of periods */
603 __le32 periods_max; /* max number of periods */
604 __le32 period_size_min; /* min period size bytes */
605 __le32 period_size_max; /* max period size bytes */
606 __le32 buffer_size_min; /* min buffer size bytes */
607 __le32 buffer_size_max; /* max buffer size bytes */
608} __packed;
609
610/* PCM v4 */
611struct snd_soc_tplg_pcm_v4 {
612 __le32 size; /* in bytes of this structure */
613 char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
614 char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
615 __le32 pcm_id; /* unique ID - used to match with DAI link */
616 __le32 dai_id; /* unique ID - used to match */
617 __le32 playback; /* supports playback mode */
618 __le32 capture; /* supports capture mode */
619 __le32 compress; /* 1 = compressed; 0 = PCM */
620 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
621 __le32 num_streams; /* number of streams */
622 struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */
623} __packed;
624
625/* Physical link config v4 */
626struct snd_soc_tplg_link_config_v4 {
627 __le32 size; /* in bytes of this structure */
628 __le32 id; /* unique ID - used to match */
629 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
630 __le32 num_streams; /* number of streams */
631} __packed;
632
555#endif 633#endif
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/include/uapi/sound/skl-tplg-interface.h
index f8d1749a2e0c..f58cafa42f18 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/include/uapi/sound/skl-tplg-interface.h
@@ -1,19 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * skl-tplg-interface.h - Intel DSP FW private data interface 3 * skl-tplg-interface.h - Intel DSP FW private data interface
3 * 4 *
4 * Copyright (C) 2015 Intel Corp 5 * Copyright (C) 2015 Intel Corp
5 * Author: Jeeja KP <jeeja.kp@intel.com> 6 * Author: Jeeja KP <jeeja.kp@intel.com>
6 * Nilofer, Samreen <samreen.nilofer@intel.com> 7 * Nilofer, Samreen <samreen.nilofer@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */ 8 */
18 9
19#ifndef __HDA_TPLG_INTERFACE_H__ 10#ifndef __HDA_TPLG_INTERFACE_H__
@@ -169,4 +160,78 @@ enum skl_tuple_type {
169 SKL_TYPE_DATA 160 SKL_TYPE_DATA
170}; 161};
171 162
163/* v4 configuration data */
164
165struct skl_dfw_v4_module_pin {
166 u16 module_id;
167 u16 instance_id;
168} __packed;
169
170struct skl_dfw_v4_module_fmt {
171 u32 channels;
172 u32 freq;
173 u32 bit_depth;
174 u32 valid_bit_depth;
175 u32 ch_cfg;
176 u32 interleaving_style;
177 u32 sample_type;
178 u32 ch_map;
179} __packed;
180
181struct skl_dfw_v4_module_caps {
182 u32 set_params:2;
183 u32 rsvd:30;
184 u32 param_id;
185 u32 caps_size;
186 u32 caps[HDA_SST_CFG_MAX];
187} __packed;
188
189struct skl_dfw_v4_pipe {
190 u8 pipe_id;
191 u8 pipe_priority;
192 u16 conn_type:4;
193 u16 rsvd:4;
194 u16 memory_pages:8;
195} __packed;
196
197struct skl_dfw_v4_module {
198 char uuid[SKL_UUID_STR_SZ];
199
200 u16 module_id;
201 u16 instance_id;
202 u32 max_mcps;
203 u32 mem_pages;
204 u32 obs;
205 u32 ibs;
206 u32 vbus_id;
207
208 u32 max_in_queue:8;
209 u32 max_out_queue:8;
210 u32 time_slot:8;
211 u32 core_id:4;
212 u32 rsvd1:4;
213
214 u32 module_type:8;
215 u32 conn_type:4;
216 u32 dev_type:4;
217 u32 hw_conn_type:4;
218 u32 rsvd2:12;
219
220 u32 params_fixup:8;
221 u32 converter:8;
222 u32 input_pin_type:1;
223 u32 output_pin_type:1;
224 u32 is_dynamic_in_pin:1;
225 u32 is_dynamic_out_pin:1;
226 u32 is_loadable:1;
227 u32 rsvd3:11;
228
229 struct skl_dfw_v4_pipe pipe;
230 struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
231 struct skl_dfw_v4_module_fmt out_fmt[MAX_OUT_QUEUE];
232 struct skl_dfw_v4_module_pin in_pin[MAX_IN_QUEUE];
233 struct skl_dfw_v4_module_pin out_pin[MAX_OUT_QUEUE];
234 struct skl_dfw_v4_module_caps caps;
235} __packed;
236
172#endif 237#endif
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 8d92492183d2..06389a5385d7 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-cache.o soc-utils.o 2snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.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
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
index f41560ecbcd1..ccddc6650b9c 100644
--- a/sound/soc/amd/acp-da7219-max98357a.c
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -33,17 +33,19 @@
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/i2c.h> 35#include <linux/i2c.h>
36#include <linux/input.h>
36#include <linux/acpi.h> 37#include <linux/acpi.h>
37 38
39#include "acp.h"
38#include "../codecs/da7219.h" 40#include "../codecs/da7219.h"
39#include "../codecs/da7219-aad.h" 41#include "../codecs/da7219-aad.h"
40 42
41#define CZ_PLAT_CLK 24000000 43#define CZ_PLAT_CLK 25000000
42#define MCLK_RATE 24576000
43#define DUAL_CHANNEL 2 44#define DUAL_CHANNEL 2
44 45
45static struct snd_soc_jack cz_jack; 46static struct snd_soc_jack cz_jack;
46static struct clk *da7219_dai_clk; 47static struct clk *da7219_dai_clk;
48extern int bt_uart_enable;
47 49
48static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) 50static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
49{ 51{
@@ -62,7 +64,7 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
62 } 64 }
63 65
64 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL, 66 ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL,
65 CZ_PLAT_CLK, MCLK_RATE); 67 CZ_PLAT_CLK, DA7219_PLL_FREQ_OUT_98304);
66 if (ret < 0) { 68 if (ret < 0) {
67 dev_err(rtd->dev, "can't set codec pll: %d\n", ret); 69 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
68 return ret; 70 return ret;
@@ -80,13 +82,17 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
80 return ret; 82 return ret;
81 } 83 }
82 84
85 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
86 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
87 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
88 snd_jack_set_key(cz_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
89
83 da7219_aad_jack_det(component, &cz_jack); 90 da7219_aad_jack_det(component, &cz_jack);
84 91
85 return 0; 92 return 0;
86} 93}
87 94
88static int cz_da7219_hw_params(struct snd_pcm_substream *substream, 95static int da7219_clk_enable(struct snd_pcm_substream *substream)
89 struct snd_pcm_hw_params *params)
90{ 96{
91 int ret = 0; 97 int ret = 0;
92 struct snd_soc_pcm_runtime *rtd = substream->private_data; 98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -100,11 +106,9 @@ static int cz_da7219_hw_params(struct snd_pcm_substream *substream,
100 return ret; 106 return ret;
101} 107}
102 108
103static int cz_da7219_hw_free(struct snd_pcm_substream *substream) 109static void da7219_clk_disable(void)
104{ 110{
105 clk_disable_unprepare(da7219_dai_clk); 111 clk_disable_unprepare(da7219_dai_clk);
106
107 return 0;
108} 112}
109 113
110static const unsigned int channels[] = { 114static const unsigned int channels[] = {
@@ -127,9 +131,12 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
127 .mask = 0, 131 .mask = 0,
128}; 132};
129 133
130static int cz_fe_startup(struct snd_pcm_substream *substream) 134static int cz_da7219_startup(struct snd_pcm_substream *substream)
131{ 135{
132 struct snd_pcm_runtime *runtime = substream->runtime; 136 struct snd_pcm_runtime *runtime = substream->runtime;
137 struct snd_soc_pcm_runtime *rtd = substream->private_data;
138 struct snd_soc_card *card = rtd->card;
139 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
133 140
134 /* 141 /*
135 * On this platform for PCM device we support stereo 142 * On this platform for PCM device we support stereo
@@ -141,23 +148,58 @@ static int cz_fe_startup(struct snd_pcm_substream *substream)
141 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 148 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
142 &constraints_rates); 149 &constraints_rates);
143 150
144 return 0; 151 machine->i2s_instance = I2S_BT_INSTANCE;
152 return da7219_clk_enable(substream);
153}
154
155static void cz_da7219_shutdown(struct snd_pcm_substream *substream)
156{
157 da7219_clk_disable();
158}
159
160static int cz_max_startup(struct snd_pcm_substream *substream)
161{
162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
163 struct snd_soc_card *card = rtd->card;
164 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
165
166 machine->i2s_instance = I2S_SP_INSTANCE;
167 return da7219_clk_enable(substream);
168}
169
170static void cz_max_shutdown(struct snd_pcm_substream *substream)
171{
172 da7219_clk_disable();
173}
174
175static int cz_dmic_startup(struct snd_pcm_substream *substream)
176{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct snd_soc_card *card = rtd->card;
179 struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
180
181 machine->i2s_instance = I2S_SP_INSTANCE;
182 return da7219_clk_enable(substream);
183}
184
185static void cz_dmic_shutdown(struct snd_pcm_substream *substream)
186{
187 da7219_clk_disable();
145} 188}
146 189
147static struct snd_soc_ops cz_da7219_cap_ops = { 190static const struct snd_soc_ops cz_da7219_cap_ops = {
148 .hw_params = cz_da7219_hw_params, 191 .startup = cz_da7219_startup,
149 .hw_free = cz_da7219_hw_free, 192 .shutdown = cz_da7219_shutdown,
150 .startup = cz_fe_startup,
151}; 193};
152 194
153static struct snd_soc_ops cz_max_play_ops = { 195static const struct snd_soc_ops cz_max_play_ops = {
154 .hw_params = cz_da7219_hw_params, 196 .startup = cz_max_startup,
155 .hw_free = cz_da7219_hw_free, 197 .shutdown = cz_max_shutdown,
156}; 198};
157 199
158static struct snd_soc_ops cz_dmic_cap_ops = { 200static const struct snd_soc_ops cz_dmic_cap_ops = {
159 .hw_params = cz_da7219_hw_params, 201 .startup = cz_dmic_startup,
160 .hw_free = cz_da7219_hw_free, 202 .shutdown = cz_dmic_shutdown,
161}; 203};
162 204
163static struct snd_soc_dai_link cz_dai_7219_98357[] = { 205static struct snd_soc_dai_link cz_dai_7219_98357[] = {
@@ -240,10 +282,16 @@ static int cz_probe(struct platform_device *pdev)
240{ 282{
241 int ret; 283 int ret;
242 struct snd_soc_card *card; 284 struct snd_soc_card *card;
285 struct acp_platform_info *machine;
243 286
287 machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info),
288 GFP_KERNEL);
289 if (!machine)
290 return -ENOMEM;
244 card = &cz_card; 291 card = &cz_card;
245 cz_card.dev = &pdev->dev; 292 cz_card.dev = &pdev->dev;
246 platform_set_drvdata(pdev, card); 293 platform_set_drvdata(pdev, card);
294 snd_soc_card_set_drvdata(card, machine);
247 ret = devm_snd_soc_register_card(&pdev->dev, &cz_card); 295 ret = devm_snd_soc_register_card(&pdev->dev, &cz_card);
248 if (ret) { 296 if (ret) {
249 dev_err(&pdev->dev, 297 dev_err(&pdev->dev,
@@ -251,6 +299,8 @@ static int cz_probe(struct platform_device *pdev)
251 cz_card.name, ret); 299 cz_card.name, ret);
252 return ret; 300 return ret;
253 } 301 }
302 bt_uart_enable = !device_property_read_bool(&pdev->dev,
303 "bt-pad-enable");
254 return 0; 304 return 0;
255} 305}
256 306
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index 540088d317f2..77203841c535 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -37,12 +37,14 @@
37#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) 37#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
38#define MIN_BUFFER MAX_BUFFER 38#define MIN_BUFFER MAX_BUFFER
39 39
40#define ST_PLAYBACK_MAX_PERIOD_SIZE 8192 40#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096
41#define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE 41#define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE
42#define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) 42#define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
43#define ST_MIN_BUFFER ST_MAX_BUFFER 43#define ST_MIN_BUFFER ST_MAX_BUFFER
44 44
45#define DRV_NAME "acp_audio_dma" 45#define DRV_NAME "acp_audio_dma"
46bool bt_uart_enable = true;
47EXPORT_SYMBOL(bt_uart_enable);
46 48
47static const struct snd_pcm_hardware acp_pcm_hardware_playback = { 49static const struct snd_pcm_hardware acp_pcm_hardware_playback = {
48 .info = SNDRV_PCM_INFO_INTERLEAVED | 50 .info = SNDRV_PCM_INFO_INTERLEAVED |
@@ -130,7 +132,8 @@ static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg)
130 writel(val, acp_mmio + (reg * 4)); 132 writel(val, acp_mmio + (reg * 4));
131} 133}
132 134
133/* Configure a given dma channel parameters - enable/disable, 135/*
136 * Configure a given dma channel parameters - enable/disable,
134 * number of descriptors, priority 137 * number of descriptors, priority
135 */ 138 */
136static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, 139static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num,
@@ -149,11 +152,12 @@ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num,
149 & dscr_strt_idx), 152 & dscr_strt_idx),
150 acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num); 153 acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num);
151 154
152 /* program a DMA channel with the number of descriptors to be 155 /*
156 * program a DMA channel with the number of descriptors to be
153 * processed in the transfer 157 * processed in the transfer
154 */ 158 */
155 acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs, 159 acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs,
156 acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num); 160 acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num);
157 161
158 /* set DMA channel priority */ 162 /* set DMA channel priority */
159 acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num); 163 acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num);
@@ -180,13 +184,15 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio,
180 acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data); 184 acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
181} 185}
182 186
183/* Initialize the DMA descriptor information for transfer between 187/*
188 * Initialize the DMA descriptor information for transfer between
184 * system memory <-> ACP SRAM 189 * system memory <-> ACP SRAM
185 */ 190 */
186static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, 191static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
187 u32 size, int direction, u32 pte_offset, 192 u32 size, int direction,
188 u16 ch, u32 sram_bank, 193 u32 pte_offset, u16 ch,
189 u16 dma_dscr_idx, u32 asic_type) 194 u32 sram_bank, u16 dma_dscr_idx,
195 u32 asic_type)
190{ 196{
191 u16 i; 197 u16 i;
192 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL]; 198 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
@@ -195,58 +201,58 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio,
195 dmadscr[i].xfer_val = 0; 201 dmadscr[i].xfer_val = 0;
196 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 202 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
197 dma_dscr_idx = dma_dscr_idx + i; 203 dma_dscr_idx = dma_dscr_idx + i;
198 dmadscr[i].dest = sram_bank + (i * (size/2)); 204 dmadscr[i].dest = sram_bank + (i * (size / 2));
199 dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS 205 dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS
200 + (pte_offset * SZ_4K) + (i * (size/2)); 206 + (pte_offset * SZ_4K) + (i * (size / 2));
201 switch (asic_type) { 207 switch (asic_type) {
202 case CHIP_STONEY: 208 case CHIP_STONEY:
203 dmadscr[i].xfer_val |= 209 dmadscr[i].xfer_val |=
204 (ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM << 16) | 210 (ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM << 16) |
205 (size / 2); 211 (size / 2);
206 break; 212 break;
207 default: 213 default:
208 dmadscr[i].xfer_val |= 214 dmadscr[i].xfer_val |=
209 (ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM << 16) | 215 (ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM << 16) |
210 (size / 2); 216 (size / 2);
211 } 217 }
212 } else { 218 } else {
213 dma_dscr_idx = dma_dscr_idx + i; 219 dma_dscr_idx = dma_dscr_idx + i;
214 dmadscr[i].src = sram_bank + (i * (size/2)); 220 dmadscr[i].src = sram_bank + (i * (size / 2));
215 dmadscr[i].dest = 221 dmadscr[i].dest =
216 ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS + 222 ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS +
217 (pte_offset * SZ_4K) + (i * (size/2)); 223 (pte_offset * SZ_4K) + (i * (size / 2));
218 switch (asic_type) { 224 switch (asic_type) {
219 case CHIP_STONEY: 225 case CHIP_STONEY:
220 dmadscr[i].xfer_val |= 226 dmadscr[i].xfer_val |=
221 BIT(22) | 227 BIT(22) |
222 (ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) | 228 (ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC << 16) |
223 (size / 2); 229 (size / 2);
224 break; 230 break;
225 default: 231 default:
226 dmadscr[i].xfer_val |= 232 dmadscr[i].xfer_val |=
227 BIT(22) | 233 BIT(22) |
228 (ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) | 234 (ACP_DMA_ATTR_SHAREDMEM_TO_DAGB_ONION << 16) |
229 (size / 2); 235 (size / 2);
230 } 236 }
231 } 237 }
232 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx, 238 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
233 &dmadscr[i]); 239 &dmadscr[i]);
234 } 240 }
235 config_acp_dma_channel(acp_mmio, ch, 241 config_acp_dma_channel(acp_mmio, ch,
236 dma_dscr_idx - 1, 242 dma_dscr_idx - 1,
237 NUM_DSCRS_PER_CHANNEL, 243 NUM_DSCRS_PER_CHANNEL,
238 ACP_DMA_PRIORITY_LEVEL_NORMAL); 244 ACP_DMA_PRIORITY_LEVEL_NORMAL);
239} 245}
240 246
241/* Initialize the DMA descriptor information for transfer between 247/*
248 * Initialize the DMA descriptor information for transfer between
242 * ACP SRAM <-> I2S 249 * ACP SRAM <-> I2S
243 */ 250 */
244static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size, 251static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
245 int direction, u32 sram_bank, 252 int direction, u32 sram_bank,
246 u16 destination, u16 ch, 253 u16 destination, u16 ch,
247 u16 dma_dscr_idx, u32 asic_type) 254 u16 dma_dscr_idx, u32 asic_type)
248{ 255{
249
250 u16 i; 256 u16 i;
251 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL]; 257 acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL];
252 258
@@ -254,7 +260,7 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
254 dmadscr[i].xfer_val = 0; 260 dmadscr[i].xfer_val = 0;
255 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 261 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
256 dma_dscr_idx = dma_dscr_idx + i; 262 dma_dscr_idx = dma_dscr_idx + i;
257 dmadscr[i].src = sram_bank + (i * (size/2)); 263 dmadscr[i].src = sram_bank + (i * (size / 2));
258 /* dmadscr[i].dest is unused by hardware. */ 264 /* dmadscr[i].dest is unused by hardware. */
259 dmadscr[i].dest = 0; 265 dmadscr[i].dest = 0;
260 dmadscr[i].xfer_val |= BIT(22) | (destination << 16) | 266 dmadscr[i].xfer_val |= BIT(22) | (destination << 16) |
@@ -269,12 +275,12 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
269 (destination << 16) | (size / 2); 275 (destination << 16) | (size / 2);
270 } 276 }
271 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx, 277 config_dma_descriptor_in_sram(acp_mmio, dma_dscr_idx,
272 &dmadscr[i]); 278 &dmadscr[i]);
273 } 279 }
274 /* Configure the DMA channel with the above descriptore */ 280 /* Configure the DMA channel with the above descriptore */
275 config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1, 281 config_acp_dma_channel(acp_mmio, ch, dma_dscr_idx - 1,
276 NUM_DSCRS_PER_CHANNEL, 282 NUM_DSCRS_PER_CHANNEL,
277 ACP_DMA_PRIORITY_LEVEL_NORMAL); 283 ACP_DMA_PRIORITY_LEVEL_NORMAL);
278} 284}
279 285
280/* Create page table entries in ACP SRAM for the allocated memory */ 286/* Create page table entries in ACP SRAM for the allocated memory */
@@ -291,7 +297,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
291 for (page_idx = 0; page_idx < (num_of_pages); page_idx++) { 297 for (page_idx = 0; page_idx < (num_of_pages); page_idx++) {
292 /* Load the low address of page int ACP SRAM through SRBM */ 298 /* Load the low address of page int ACP SRAM through SRBM */
293 acp_reg_write((offset + (page_idx * 8)), 299 acp_reg_write((offset + (page_idx * 8)),
294 acp_mmio, mmACP_SRBM_Targ_Idx_Addr); 300 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
295 addr = page_to_phys(pg); 301 addr = page_to_phys(pg);
296 302
297 low = lower_32_bits(addr); 303 low = lower_32_bits(addr);
@@ -301,7 +307,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
301 307
302 /* Load the High address of page int ACP SRAM through SRBM */ 308 /* Load the High address of page int ACP SRAM through SRBM */
303 acp_reg_write((offset + (page_idx * 8) + 4), 309 acp_reg_write((offset + (page_idx * 8) + 4),
304 acp_mmio, mmACP_SRBM_Targ_Idx_Addr); 310 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
305 311
306 /* page enable in ACP */ 312 /* page enable in ACP */
307 high |= BIT(31); 313 high |= BIT(31);
@@ -313,59 +319,25 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
313} 319}
314 320
315static void config_acp_dma(void __iomem *acp_mmio, 321static void config_acp_dma(void __iomem *acp_mmio,
316 struct audio_substream_data *audio_config, 322 struct audio_substream_data *rtd,
317 u32 asic_type) 323 u32 asic_type)
318{ 324{
319 u32 pte_offset, sram_bank; 325 acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages,
320 u16 ch1, ch2, destination, dma_dscr_idx; 326 rtd->pte_offset);
321
322 if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) {
323 pte_offset = ACP_PLAYBACK_PTE_OFFSET;
324 ch1 = SYSRAM_TO_ACP_CH_NUM;
325 ch2 = ACP_TO_I2S_DMA_CH_NUM;
326 sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS;
327 destination = TO_ACP_I2S_1;
328
329 } else {
330 pte_offset = ACP_CAPTURE_PTE_OFFSET;
331 ch1 = SYSRAM_TO_ACP_CH_NUM;
332 ch2 = ACP_TO_I2S_DMA_CH_NUM;
333 switch (asic_type) {
334 case CHIP_STONEY:
335 sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS;
336 break;
337 default:
338 sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS;
339 }
340 destination = FROM_ACP_I2S_1;
341 }
342
343 acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages,
344 pte_offset);
345 if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
346 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
347 else
348 dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14;
349
350 /* Configure System memory <-> ACP SRAM DMA descriptors */ 327 /* Configure System memory <-> ACP SRAM DMA descriptors */
351 set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size, 328 set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size,
352 audio_config->direction, pte_offset, 329 rtd->direction, rtd->pte_offset,
353 ch1, sram_bank, dma_dscr_idx, asic_type); 330 rtd->ch1, rtd->sram_bank,
354 331 rtd->dma_dscr_idx_1, asic_type);
355 if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK)
356 dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13;
357 else
358 dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15;
359 /* Configure ACP SRAM <-> I2S DMA descriptors */ 332 /* Configure ACP SRAM <-> I2S DMA descriptors */
360 set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size, 333 set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size,
361 audio_config->direction, sram_bank, 334 rtd->direction, rtd->sram_bank,
362 destination, ch2, dma_dscr_idx, 335 rtd->destination, rtd->ch2,
363 asic_type); 336 rtd->dma_dscr_idx_2, asic_type);
364} 337}
365 338
366/* Start a given DMA channel transfer */ 339/* Start a given DMA channel transfer */
367static void acp_dma_start(void __iomem *acp_mmio, 340static void acp_dma_start(void __iomem *acp_mmio, u16 ch_num)
368 u16 ch_num, bool is_circular)
369{ 341{
370 u32 dma_ctrl; 342 u32 dma_ctrl;
371 343
@@ -375,7 +347,8 @@ static void acp_dma_start(void __iomem *acp_mmio,
375 /* Invalidating the DAGB cache */ 347 /* Invalidating the DAGB cache */
376 acp_reg_write(1, acp_mmio, mmACP_DAGB_ATU_CTRL); 348 acp_reg_write(1, acp_mmio, mmACP_DAGB_ATU_CTRL);
377 349
378 /* configure the DMA channel and start the DMA transfer 350 /*
351 * configure the DMA channel and start the DMA transfer
379 * set dmachrun bit to start the transfer and enable the 352 * set dmachrun bit to start the transfer and enable the
380 * interrupt on completion of the dma transfer 353 * interrupt on completion of the dma transfer
381 */ 354 */
@@ -385,6 +358,9 @@ static void acp_dma_start(void __iomem *acp_mmio,
385 case ACP_TO_I2S_DMA_CH_NUM: 358 case ACP_TO_I2S_DMA_CH_NUM:
386 case ACP_TO_SYSRAM_CH_NUM: 359 case ACP_TO_SYSRAM_CH_NUM:
387 case I2S_TO_ACP_DMA_CH_NUM: 360 case I2S_TO_ACP_DMA_CH_NUM:
361 case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM:
362 case ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM:
363 case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM:
388 dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK; 364 dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
389 break; 365 break;
390 default: 366 default:
@@ -392,11 +368,8 @@ static void acp_dma_start(void __iomem *acp_mmio,
392 break; 368 break;
393 } 369 }
394 370
395 /* enable for ACP SRAM to/from I2S DMA channel */ 371 /* circular for both DMA channel */
396 if (is_circular == true) 372 dma_ctrl |= ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
397 dma_ctrl |= ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
398 else
399 dma_ctrl &= ~ACP_DMA_CNTL_0__Circular_DMA_En_MASK;
400 373
401 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num); 374 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
402} 375}
@@ -410,9 +383,10 @@ static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
410 383
411 dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num); 384 dma_ctrl = acp_reg_read(acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
412 385
413 /* clear the dma control register fields before writing zero 386 /*
387 * clear the dma control register fields before writing zero
414 * in reset bit 388 * in reset bit
415 */ 389 */
416 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK; 390 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRun_MASK;
417 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK; 391 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChIOCEn_MASK;
418 392
@@ -420,9 +394,10 @@ static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
420 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS); 394 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
421 395
422 if (dma_ch_sts & BIT(ch_num)) { 396 if (dma_ch_sts & BIT(ch_num)) {
423 /* set the reset bit for this channel to stop the dma 397 /*
424 * transfer 398 * set the reset bit for this channel to stop the dma
425 */ 399 * transfer
400 */
426 dma_ctrl |= ACP_DMA_CNTL_0__DMAChRst_MASK; 401 dma_ctrl |= ACP_DMA_CNTL_0__DMAChRst_MASK;
427 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num); 402 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 + ch_num);
428 } 403 }
@@ -431,13 +406,14 @@ static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
431 while (true) { 406 while (true) {
432 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS); 407 dma_ch_sts = acp_reg_read(acp_mmio, mmACP_DMA_CH_STS);
433 if (!(dma_ch_sts & BIT(ch_num))) { 408 if (!(dma_ch_sts & BIT(ch_num))) {
434 /* clear the reset flag after successfully stopping 409 /*
435 * the dma transfer and break from the loop 410 * clear the reset flag after successfully stopping
436 */ 411 * the dma transfer and break from the loop
412 */
437 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK; 413 dma_ctrl &= ~ACP_DMA_CNTL_0__DMAChRst_MASK;
438 414
439 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0 415 acp_reg_write(dma_ctrl, acp_mmio, mmACP_DMA_CNTL_0
440 + ch_num); 416 + ch_num);
441 break; 417 break;
442 } 418 }
443 if (--count == 0) { 419 if (--count == 0) {
@@ -450,7 +426,7 @@ static int acp_dma_stop(void __iomem *acp_mmio, u8 ch_num)
450} 426}
451 427
452static void acp_set_sram_bank_state(void __iomem *acp_mmio, u16 bank, 428static void acp_set_sram_bank_state(void __iomem *acp_mmio, u16 bank,
453 bool power_on) 429 bool power_on)
454{ 430{
455 u32 val, req_reg, sts_reg, sts_reg_mask; 431 u32 val, req_reg, sts_reg, sts_reg_mask;
456 u32 loops = 1000; 432 u32 loops = 1000;
@@ -530,7 +506,7 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
530 506
531 while (true) { 507 while (true) {
532 val = acp_reg_read(acp_mmio, mmACP_STATUS); 508 val = acp_reg_read(acp_mmio, mmACP_STATUS);
533 if (val & (u32) 0x1) 509 if (val & (u32)0x1)
534 break; 510 break;
535 if (--count == 0) { 511 if (--count == 0) {
536 pr_err("Failed to reset ACP\n"); 512 pr_err("Failed to reset ACP\n");
@@ -544,13 +520,20 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
544 val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; 520 val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
545 acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET); 521 acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET);
546 522
523 /* For BT instance change pins from UART to BT */
524 if (!bt_uart_enable) {
525 val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL);
526 val |= ACP_BT_UART_PAD_SELECT_MASK;
527 acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL);
528 }
529
547 /* initiailize Onion control DAGB register */ 530 /* initiailize Onion control DAGB register */
548 acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio, 531 acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio,
549 mmACP_AXI2DAGB_ONION_CNTL); 532 mmACP_AXI2DAGB_ONION_CNTL);
550 533
551 /* initiailize Garlic control DAGB registers */ 534 /* initiailize Garlic control DAGB registers */
552 acp_reg_write(ACP_GARLIC_CNTL_DEFAULT, acp_mmio, 535 acp_reg_write(ACP_GARLIC_CNTL_DEFAULT, acp_mmio,
553 mmACP_AXI2DAGB_GARLIC_CNTL); 536 mmACP_AXI2DAGB_GARLIC_CNTL);
554 537
555 sram_pte_offset = ACP_DAGB_GRP_SRAM_BASE_ADDRESS | 538 sram_pte_offset = ACP_DAGB_GRP_SRAM_BASE_ADDRESS |
556 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK | 539 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBSnoopSel_MASK |
@@ -558,17 +541,18 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type)
558 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK; 541 ACP_DAGB_BASE_ADDR_GRP_1__AXI2DAGBGrpEnable_MASK;
559 acp_reg_write(sram_pte_offset, acp_mmio, mmACP_DAGB_BASE_ADDR_GRP_1); 542 acp_reg_write(sram_pte_offset, acp_mmio, mmACP_DAGB_BASE_ADDR_GRP_1);
560 acp_reg_write(ACP_PAGE_SIZE_4K_ENABLE, acp_mmio, 543 acp_reg_write(ACP_PAGE_SIZE_4K_ENABLE, acp_mmio,
561 mmACP_DAGB_PAGE_SIZE_GRP_1); 544 mmACP_DAGB_PAGE_SIZE_GRP_1);
562 545
563 acp_reg_write(ACP_SRAM_BASE_ADDRESS, acp_mmio, 546 acp_reg_write(ACP_SRAM_BASE_ADDRESS, acp_mmio,
564 mmACP_DMA_DESC_BASE_ADDR); 547 mmACP_DMA_DESC_BASE_ADDR);
565 548
566 /* Num of descriptiors in SRAM 0x4, means 256 descriptors;(64 * 4) */ 549 /* Num of descriptiors in SRAM 0x4, means 256 descriptors;(64 * 4) */
567 acp_reg_write(0x4, acp_mmio, mmACP_DMA_DESC_MAX_NUM_DSCR); 550 acp_reg_write(0x4, acp_mmio, mmACP_DMA_DESC_MAX_NUM_DSCR);
568 acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK, 551 acp_reg_write(ACP_EXTERNAL_INTR_CNTL__DMAIOCMask_MASK,
569 acp_mmio, mmACP_EXTERNAL_INTR_CNTL); 552 acp_mmio, mmACP_EXTERNAL_INTR_CNTL);
570 553
571 /* When ACP_TILE_P1 is turned on, all SRAM banks get turned on. 554 /*
555 * When ACP_TILE_P1 is turned on, all SRAM banks get turned on.
572 * Now, turn off all of them. This can't be done in 'poweron' of 556 * Now, turn off all of them. This can't be done in 'poweron' of
573 * ACP pm domain, as this requires ACP to be initialized. 557 * ACP pm domain, as this requires ACP to be initialized.
574 * For Stoney, Memory gating is disabled,i.e SRAM Banks 558 * For Stoney, Memory gating is disabled,i.e SRAM Banks
@@ -606,7 +590,7 @@ static int acp_deinit(void __iomem *acp_mmio)
606 } 590 }
607 udelay(100); 591 udelay(100);
608 } 592 }
609 /** Disable ACP clock */ 593 /* Disable ACP clock */
610 val = acp_reg_read(acp_mmio, mmACP_CONTROL); 594 val = acp_reg_read(acp_mmio, mmACP_CONTROL);
611 val &= ~ACP_CONTROL__ClkEn_MASK; 595 val &= ~ACP_CONTROL__ClkEn_MASK;
612 acp_reg_write(val, acp_mmio, mmACP_CONTROL); 596 acp_reg_write(val, acp_mmio, mmACP_CONTROL);
@@ -615,7 +599,7 @@ static int acp_deinit(void __iomem *acp_mmio)
615 599
616 while (true) { 600 while (true) {
617 val = acp_reg_read(acp_mmio, mmACP_STATUS); 601 val = acp_reg_read(acp_mmio, mmACP_STATUS);
618 if (!(val & (u32) 0x1)) 602 if (!(val & (u32)0x1))
619 break; 603 break;
620 if (--count == 0) { 604 if (--count == 0) {
621 pr_err("Failed to reset ACP\n"); 605 pr_err("Failed to reset ACP\n");
@@ -629,7 +613,6 @@ static int acp_deinit(void __iomem *acp_mmio)
629/* ACP DMA irq handler routine for playback, capture usecases */ 613/* ACP DMA irq handler routine for playback, capture usecases */
630static irqreturn_t dma_irq_handler(int irq, void *arg) 614static irqreturn_t dma_irq_handler(int irq, void *arg)
631{ 615{
632 u16 dscr_idx;
633 u32 intr_flag, ext_intr_status; 616 u32 intr_flag, ext_intr_status;
634 struct audio_drv_data *irq_data; 617 struct audio_drv_data *irq_data;
635 void __iomem *acp_mmio; 618 void __iomem *acp_mmio;
@@ -646,41 +629,45 @@ static irqreturn_t dma_irq_handler(int irq, void *arg)
646 629
647 if ((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) != 0) { 630 if ((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) != 0) {
648 valid_irq = true; 631 valid_irq = true;
649 if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_13) ==
650 PLAYBACK_START_DMA_DESCR_CH13)
651 dscr_idx = PLAYBACK_END_DMA_DESCR_CH12;
652 else
653 dscr_idx = PLAYBACK_START_DMA_DESCR_CH12;
654 config_acp_dma_channel(acp_mmio, SYSRAM_TO_ACP_CH_NUM, dscr_idx,
655 1, 0);
656 acp_dma_start(acp_mmio, SYSRAM_TO_ACP_CH_NUM, false);
657
658 snd_pcm_period_elapsed(irq_data->play_i2ssp_stream); 632 snd_pcm_period_elapsed(irq_data->play_i2ssp_stream);
659
660 acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16, 633 acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_CH_NUM)) << 16,
661 acp_mmio, mmACP_EXTERNAL_INTR_STAT); 634 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
662 } 635 }
663 636
664 if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) { 637 if ((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) != 0) {
665 valid_irq = true; 638 valid_irq = true;
666 if (acp_reg_read(acp_mmio, mmACP_DMA_CUR_DSCR_15) == 639 snd_pcm_period_elapsed(irq_data->play_i2sbt_stream);
667 CAPTURE_START_DMA_DESCR_CH15) 640 acp_reg_write((intr_flag &
668 dscr_idx = CAPTURE_END_DMA_DESCR_CH14; 641 BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) << 16,
669 else 642 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
670 dscr_idx = CAPTURE_START_DMA_DESCR_CH14; 643 }
671 config_acp_dma_channel(acp_mmio, ACP_TO_SYSRAM_CH_NUM, dscr_idx,
672 1, 0);
673 acp_dma_start(acp_mmio, ACP_TO_SYSRAM_CH_NUM, false);
674 644
645 if ((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) != 0) {
646 valid_irq = true;
647 snd_pcm_period_elapsed(irq_data->capture_i2ssp_stream);
675 acp_reg_write((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) << 16, 648 acp_reg_write((intr_flag & BIT(I2S_TO_ACP_DMA_CH_NUM)) << 16,
676 acp_mmio, mmACP_EXTERNAL_INTR_STAT); 649 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
677 } 650 }
678 651
679 if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) { 652 if ((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) != 0) {
680 valid_irq = true; 653 valid_irq = true;
681 snd_pcm_period_elapsed(irq_data->capture_i2ssp_stream);
682 acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16, 654 acp_reg_write((intr_flag & BIT(ACP_TO_SYSRAM_CH_NUM)) << 16,
683 acp_mmio, mmACP_EXTERNAL_INTR_STAT); 655 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
656 }
657
658 if ((intr_flag & BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) != 0) {
659 valid_irq = true;
660 snd_pcm_period_elapsed(irq_data->capture_i2sbt_stream);
661 acp_reg_write((intr_flag &
662 BIT(I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM)) << 16,
663 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
664 }
665
666 if ((intr_flag & BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) != 0) {
667 valid_irq = true;
668 acp_reg_write((intr_flag &
669 BIT(ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM)) << 16,
670 acp_mmio, mmACP_EXTERNAL_INTR_STAT);
684 } 671 }
685 672
686 if (valid_irq) 673 if (valid_irq)
@@ -695,11 +682,12 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
695 int ret = 0; 682 int ret = 0;
696 struct snd_pcm_runtime *runtime = substream->runtime; 683 struct snd_pcm_runtime *runtime = substream->runtime;
697 struct snd_soc_pcm_runtime *prtd = substream->private_data; 684 struct snd_soc_pcm_runtime *prtd = substream->private_data;
698 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); 685 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd,
686 DRV_NAME);
699 struct audio_drv_data *intr_data = dev_get_drvdata(component->dev); 687 struct audio_drv_data *intr_data = dev_get_drvdata(component->dev);
700 struct audio_substream_data *adata = 688 struct audio_substream_data *adata =
701 kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL); 689 kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL);
702 if (adata == NULL) 690 if (!adata)
703 return -ENOMEM; 691 return -ENOMEM;
704 692
705 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 693 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -731,17 +719,19 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
731 adata->acp_mmio = intr_data->acp_mmio; 719 adata->acp_mmio = intr_data->acp_mmio;
732 runtime->private_data = adata; 720 runtime->private_data = adata;
733 721
734 /* Enable ACP irq, when neither playback or capture streams are 722 /*
723 * Enable ACP irq, when neither playback or capture streams are
735 * active by the time when a new stream is being opened. 724 * active by the time when a new stream is being opened.
736 * This enablement is not required for another stream, if current 725 * This enablement is not required for another stream, if current
737 * stream is not closed 726 * stream is not closed
738 */ 727 */
739 if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream) 728 if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream &&
729 !intr_data->play_i2sbt_stream && !intr_data->capture_i2sbt_stream)
740 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 730 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
741 731
742 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 732 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
743 intr_data->play_i2ssp_stream = substream; 733 /*
744 /* For Stoney, Memory gating is disabled,i.e SRAM Banks 734 * For Stoney, Memory gating is disabled,i.e SRAM Banks
745 * won't be turned off. The default state for SRAM banks is ON. 735 * won't be turned off. The default state for SRAM banks is ON.
746 * Setting SRAM bank state code skipped for STONEY platform. 736 * Setting SRAM bank state code skipped for STONEY platform.
747 */ 737 */
@@ -751,7 +741,6 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
751 bank, true); 741 bank, true);
752 } 742 }
753 } else { 743 } else {
754 intr_data->capture_i2ssp_stream = substream;
755 if (intr_data->asic_type != CHIP_STONEY) { 744 if (intr_data->asic_type != CHIP_STONEY) {
756 for (bank = 5; bank <= 8; bank++) 745 for (bank = 5; bank <= 8; bank++)
757 acp_set_sram_bank_state(intr_data->acp_mmio, 746 acp_set_sram_bank_state(intr_data->acp_mmio,
@@ -772,8 +761,11 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
772 struct snd_pcm_runtime *runtime; 761 struct snd_pcm_runtime *runtime;
773 struct audio_substream_data *rtd; 762 struct audio_substream_data *rtd;
774 struct snd_soc_pcm_runtime *prtd = substream->private_data; 763 struct snd_soc_pcm_runtime *prtd = substream->private_data;
775 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); 764 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd,
765 DRV_NAME);
776 struct audio_drv_data *adata = dev_get_drvdata(component->dev); 766 struct audio_drv_data *adata = dev_get_drvdata(component->dev);
767 struct snd_soc_card *card = prtd->card;
768 struct acp_platform_info *pinfo = snd_soc_card_get_drvdata(card);
777 769
778 runtime = substream->runtime; 770 runtime = substream->runtime;
779 rtd = runtime->private_data; 771 rtd = runtime->private_data;
@@ -781,14 +773,111 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
781 if (WARN_ON(!rtd)) 773 if (WARN_ON(!rtd))
782 return -EINVAL; 774 return -EINVAL;
783 775
776 rtd->i2s_instance = pinfo->i2s_instance;
784 if (adata->asic_type == CHIP_STONEY) { 777 if (adata->asic_type == CHIP_STONEY) {
785 val = acp_reg_read(adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); 778 val = acp_reg_read(adata->acp_mmio,
786 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 779 mmACP_I2S_16BIT_RESOLUTION_EN);
787 val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; 780 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
788 else 781 switch (rtd->i2s_instance) {
789 val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; 782 case I2S_BT_INSTANCE:
790 acp_reg_write(val, adata->acp_mmio, mmACP_I2S_16BIT_RESOLUTION_EN); 783 val |= ACP_I2S_BT_16BIT_RESOLUTION_EN;
784 break;
785 case I2S_SP_INSTANCE:
786 default:
787 val |= ACP_I2S_SP_16BIT_RESOLUTION_EN;
788 }
789 } else {
790 switch (rtd->i2s_instance) {
791 case I2S_BT_INSTANCE:
792 val |= ACP_I2S_BT_16BIT_RESOLUTION_EN;
793 break;
794 case I2S_SP_INSTANCE:
795 default:
796 val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN;
797 }
798 }
799 acp_reg_write(val, adata->acp_mmio,
800 mmACP_I2S_16BIT_RESOLUTION_EN);
801 }
802
803 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
804 switch (rtd->i2s_instance) {
805 case I2S_BT_INSTANCE:
806 rtd->pte_offset = ACP_ST_BT_PLAYBACK_PTE_OFFSET;
807 rtd->ch1 = SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM;
808 rtd->ch2 = ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM;
809 rtd->sram_bank = ACP_SRAM_BANK_3_ADDRESS;
810 rtd->destination = TO_BLUETOOTH;
811 rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH8;
812 rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH9;
813 rtd->byte_cnt_high_reg_offset =
814 mmACP_I2S_BT_TRANSMIT_BYTE_CNT_HIGH;
815 rtd->byte_cnt_low_reg_offset =
816 mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW;
817 adata->play_i2sbt_stream = substream;
818 break;
819 case I2S_SP_INSTANCE:
820 default:
821 switch (adata->asic_type) {
822 case CHIP_STONEY:
823 rtd->pte_offset = ACP_ST_PLAYBACK_PTE_OFFSET;
824 break;
825 default:
826 rtd->pte_offset = ACP_PLAYBACK_PTE_OFFSET;
827 }
828 rtd->ch1 = SYSRAM_TO_ACP_CH_NUM;
829 rtd->ch2 = ACP_TO_I2S_DMA_CH_NUM;
830 rtd->sram_bank = ACP_SRAM_BANK_1_ADDRESS;
831 rtd->destination = TO_ACP_I2S_1;
832 rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH12;
833 rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH13;
834 rtd->byte_cnt_high_reg_offset =
835 mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH;
836 rtd->byte_cnt_low_reg_offset =
837 mmACP_I2S_TRANSMIT_BYTE_CNT_LOW;
838 adata->play_i2ssp_stream = substream;
839 }
840 } else {
841 switch (rtd->i2s_instance) {
842 case I2S_BT_INSTANCE:
843 rtd->pte_offset = ACP_ST_BT_CAPTURE_PTE_OFFSET;
844 rtd->ch1 = ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM;
845 rtd->ch2 = I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM;
846 rtd->sram_bank = ACP_SRAM_BANK_4_ADDRESS;
847 rtd->destination = FROM_BLUETOOTH;
848 rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH10;
849 rtd->dma_dscr_idx_2 = CAPTURE_START_DMA_DESCR_CH11;
850 rtd->byte_cnt_high_reg_offset =
851 mmACP_I2S_BT_RECEIVE_BYTE_CNT_HIGH;
852 rtd->byte_cnt_low_reg_offset =
853 mmACP_I2S_BT_RECEIVE_BYTE_CNT_LOW;
854 adata->capture_i2sbt_stream = substream;
855 break;
856 case I2S_SP_INSTANCE:
857 default:
858 rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET;
859 rtd->ch1 = ACP_TO_SYSRAM_CH_NUM;
860 rtd->ch2 = I2S_TO_ACP_DMA_CH_NUM;
861 switch (adata->asic_type) {
862 case CHIP_STONEY:
863 rtd->pte_offset = ACP_ST_CAPTURE_PTE_OFFSET;
864 rtd->sram_bank = ACP_SRAM_BANK_2_ADDRESS;
865 break;
866 default:
867 rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET;
868 rtd->sram_bank = ACP_SRAM_BANK_5_ADDRESS;
869 }
870 rtd->destination = FROM_ACP_I2S_1;
871 rtd->dma_dscr_idx_1 = CAPTURE_START_DMA_DESCR_CH14;
872 rtd->dma_dscr_idx_2 = CAPTURE_START_DMA_DESCR_CH15;
873 rtd->byte_cnt_high_reg_offset =
874 mmACP_I2S_RECEIVED_BYTE_CNT_HIGH;
875 rtd->byte_cnt_low_reg_offset =
876 mmACP_I2S_RECEIVED_BYTE_CNT_LOW;
877 adata->capture_i2ssp_stream = substream;
878 }
791 } 879 }
880
792 size = params_buffer_bytes(params); 881 size = params_buffer_bytes(params);
793 status = snd_pcm_lib_malloc_pages(substream, size); 882 status = snd_pcm_lib_malloc_pages(substream, size);
794 if (status < 0) 883 if (status < 0)
@@ -797,7 +886,7 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
797 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); 886 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
798 pg = virt_to_page(substream->dma_buffer.area); 887 pg = virt_to_page(substream->dma_buffer.area);
799 888
800 if (pg != NULL) { 889 if (pg) {
801 acp_set_sram_bank_state(rtd->acp_mmio, 0, true); 890 acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
802 /* Save for runtime private data */ 891 /* Save for runtime private data */
803 rtd->pg = pg; 892 rtd->pg = pg;
@@ -822,26 +911,15 @@ static int acp_dma_hw_free(struct snd_pcm_substream *substream)
822 return snd_pcm_lib_free_pages(substream); 911 return snd_pcm_lib_free_pages(substream);
823} 912}
824 913
825static u64 acp_get_byte_count(void __iomem *acp_mmio, int stream) 914static u64 acp_get_byte_count(struct audio_substream_data *rtd)
826{ 915{
827 union acp_dma_count playback_dma_count; 916 union acp_dma_count byte_count;
828 union acp_dma_count capture_dma_count;
829 u64 bytescount = 0;
830 917
831 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 918 byte_count.bcount.high = acp_reg_read(rtd->acp_mmio,
832 playback_dma_count.bcount.high = acp_reg_read(acp_mmio, 919 rtd->byte_cnt_high_reg_offset);
833 mmACP_I2S_TRANSMIT_BYTE_CNT_HIGH); 920 byte_count.bcount.low = acp_reg_read(rtd->acp_mmio,
834 playback_dma_count.bcount.low = acp_reg_read(acp_mmio, 921 rtd->byte_cnt_low_reg_offset);
835 mmACP_I2S_TRANSMIT_BYTE_CNT_LOW); 922 return byte_count.bytescount;
836 bytescount = playback_dma_count.bytescount;
837 } else {
838 capture_dma_count.bcount.high = acp_reg_read(acp_mmio,
839 mmACP_I2S_RECEIVED_BYTE_CNT_HIGH);
840 capture_dma_count.bcount.low = acp_reg_read(acp_mmio,
841 mmACP_I2S_RECEIVED_BYTE_CNT_LOW);
842 bytescount = capture_dma_count.bytescount;
843 }
844 return bytescount;
845} 923}
846 924
847static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream) 925static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
@@ -857,15 +935,10 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream)
857 return -EINVAL; 935 return -EINVAL;
858 936
859 buffersize = frames_to_bytes(runtime, runtime->buffer_size); 937 buffersize = frames_to_bytes(runtime, runtime->buffer_size);
860 bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream); 938 bytescount = acp_get_byte_count(rtd);
861 939
862 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 940 if (bytescount > rtd->bytescount)
863 if (bytescount > rtd->i2ssp_renderbytescount) 941 bytescount -= rtd->bytescount;
864 bytescount = bytescount - rtd->i2ssp_renderbytescount;
865 } else {
866 if (bytescount > rtd->i2ssp_capturebytescount)
867 bytescount = bytescount - rtd->i2ssp_capturebytescount;
868 }
869 pos = do_div(bytescount, buffersize); 942 pos = do_div(bytescount, buffersize);
870 return bytes_to_frames(runtime, pos); 943 return bytes_to_frames(runtime, pos);
871} 944}
@@ -883,34 +956,25 @@ static int acp_dma_prepare(struct snd_pcm_substream *substream)
883 956
884 if (!rtd) 957 if (!rtd)
885 return -EINVAL; 958 return -EINVAL;
886 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 959
887 config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, 960 config_acp_dma_channel(rtd->acp_mmio,
888 PLAYBACK_START_DMA_DESCR_CH12, 961 rtd->ch1,
889 NUM_DSCRS_PER_CHANNEL, 0); 962 rtd->dma_dscr_idx_1,
890 config_acp_dma_channel(rtd->acp_mmio, ACP_TO_I2S_DMA_CH_NUM, 963 NUM_DSCRS_PER_CHANNEL, 0);
891 PLAYBACK_START_DMA_DESCR_CH13, 964 config_acp_dma_channel(rtd->acp_mmio,
892 NUM_DSCRS_PER_CHANNEL, 0); 965 rtd->ch2,
893 } else { 966 rtd->dma_dscr_idx_2,
894 config_acp_dma_channel(rtd->acp_mmio, ACP_TO_SYSRAM_CH_NUM, 967 NUM_DSCRS_PER_CHANNEL, 0);
895 CAPTURE_START_DMA_DESCR_CH14,
896 NUM_DSCRS_PER_CHANNEL, 0);
897 config_acp_dma_channel(rtd->acp_mmio, I2S_TO_ACP_DMA_CH_NUM,
898 CAPTURE_START_DMA_DESCR_CH15,
899 NUM_DSCRS_PER_CHANNEL, 0);
900 }
901 return 0; 968 return 0;
902} 969}
903 970
904static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd) 971static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
905{ 972{
906 int ret; 973 int ret;
907 u32 loops = 4000;
908 u64 bytescount = 0; 974 u64 bytescount = 0;
909 975
910 struct snd_pcm_runtime *runtime = substream->runtime; 976 struct snd_pcm_runtime *runtime = substream->runtime;
911 struct snd_soc_pcm_runtime *prtd = substream->private_data;
912 struct audio_substream_data *rtd = runtime->private_data; 977 struct audio_substream_data *rtd = runtime->private_data;
913 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
914 978
915 if (!rtd) 979 if (!rtd)
916 return -EINVAL; 980 return -EINVAL;
@@ -918,59 +982,40 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
918 case SNDRV_PCM_TRIGGER_START: 982 case SNDRV_PCM_TRIGGER_START:
919 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 983 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
920 case SNDRV_PCM_TRIGGER_RESUME: 984 case SNDRV_PCM_TRIGGER_RESUME:
921 bytescount = acp_get_byte_count(rtd->acp_mmio, 985 bytescount = acp_get_byte_count(rtd);
922 substream->stream); 986 if (rtd->bytescount == 0)
987 rtd->bytescount = bytescount;
923 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 988 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
924 if (rtd->i2ssp_renderbytescount == 0) 989 acp_dma_start(rtd->acp_mmio, rtd->ch1);
925 rtd->i2ssp_renderbytescount = bytescount; 990 acp_dma_start(rtd->acp_mmio, rtd->ch2);
926 acp_dma_start(rtd->acp_mmio,
927 SYSRAM_TO_ACP_CH_NUM, false);
928 while (acp_reg_read(rtd->acp_mmio, mmACP_DMA_CH_STS) &
929 BIT(SYSRAM_TO_ACP_CH_NUM)) {
930 if (!loops--) {
931 dev_err(component->dev,
932 "acp dma start timeout\n");
933 return -ETIMEDOUT;
934 }
935 cpu_relax();
936 }
937
938 acp_dma_start(rtd->acp_mmio,
939 ACP_TO_I2S_DMA_CH_NUM, true);
940
941 } else { 991 } else {
942 if (rtd->i2ssp_capturebytescount == 0) 992 acp_dma_start(rtd->acp_mmio, rtd->ch2);
943 rtd->i2ssp_capturebytescount = bytescount; 993 acp_dma_start(rtd->acp_mmio, rtd->ch1);
944 acp_dma_start(rtd->acp_mmio,
945 I2S_TO_ACP_DMA_CH_NUM, true);
946 } 994 }
947 ret = 0; 995 ret = 0;
948 break; 996 break;
949 case SNDRV_PCM_TRIGGER_STOP: 997 case SNDRV_PCM_TRIGGER_STOP:
950 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 998 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
951 case SNDRV_PCM_TRIGGER_SUSPEND: 999 case SNDRV_PCM_TRIGGER_SUSPEND:
952 /* Need to stop only circular DMA channels : 1000 /* For playback, non circular dma should be stopped first
953 * ACP_TO_I2S_DMA_CH_NUM / I2S_TO_ACP_DMA_CH_NUM. Non-circular 1001 * i.e Sysram to acp dma transfer channel(rtd->ch1) should be
954 * channels will stopped automatically after its transfer 1002 * stopped before stopping cirular dma which is acp sram to i2s
955 * completes : SYSRAM_TO_ACP_CH_NUM / ACP_TO_SYSRAM_CH_NUM 1003 * fifo dma transfer channel(rtd->ch2). Where as in Capture
1004 * scenario, i2s fifo to acp sram dma channel(rtd->ch2) stopped
1005 * first before stopping acp sram to sysram which is circular
1006 * dma(rtd->ch1).
956 */ 1007 */
957 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1008 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
958 ret = acp_dma_stop(rtd->acp_mmio, 1009 acp_dma_stop(rtd->acp_mmio, rtd->ch1);
959 SYSRAM_TO_ACP_CH_NUM); 1010 ret = acp_dma_stop(rtd->acp_mmio, rtd->ch2);
960 ret = acp_dma_stop(rtd->acp_mmio,
961 ACP_TO_I2S_DMA_CH_NUM);
962 rtd->i2ssp_renderbytescount = 0;
963 } else { 1011 } else {
964 ret = acp_dma_stop(rtd->acp_mmio, 1012 acp_dma_stop(rtd->acp_mmio, rtd->ch2);
965 I2S_TO_ACP_DMA_CH_NUM); 1013 ret = acp_dma_stop(rtd->acp_mmio, rtd->ch1);
966 ret = acp_dma_stop(rtd->acp_mmio,
967 ACP_TO_SYSRAM_CH_NUM);
968 rtd->i2ssp_capturebytescount = 0;
969 } 1014 }
1015 rtd->bytescount = 0;
970 break; 1016 break;
971 default: 1017 default:
972 ret = -EINVAL; 1018 ret = -EINVAL;
973
974 } 1019 }
975 return ret; 1020 return ret;
976} 1021}
@@ -978,26 +1023,27 @@ static int acp_dma_trigger(struct snd_pcm_substream *substream, int cmd)
978static int acp_dma_new(struct snd_soc_pcm_runtime *rtd) 1023static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
979{ 1024{
980 int ret; 1025 int ret;
981 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); 1026 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd,
1027 DRV_NAME);
982 struct audio_drv_data *adata = dev_get_drvdata(component->dev); 1028 struct audio_drv_data *adata = dev_get_drvdata(component->dev);
983 1029
984 switch (adata->asic_type) { 1030 switch (adata->asic_type) {
985 case CHIP_STONEY: 1031 case CHIP_STONEY:
986 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, 1032 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
987 SNDRV_DMA_TYPE_DEV, 1033 SNDRV_DMA_TYPE_DEV,
988 NULL, ST_MIN_BUFFER, 1034 NULL, ST_MIN_BUFFER,
989 ST_MAX_BUFFER); 1035 ST_MAX_BUFFER);
990 break; 1036 break;
991 default: 1037 default:
992 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, 1038 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
993 SNDRV_DMA_TYPE_DEV, 1039 SNDRV_DMA_TYPE_DEV,
994 NULL, MIN_BUFFER, 1040 NULL, MIN_BUFFER,
995 MAX_BUFFER); 1041 MAX_BUFFER);
996 break; 1042 break;
997 } 1043 }
998 if (ret < 0) 1044 if (ret < 0)
999 dev_err(component->dev, 1045 dev_err(component->dev,
1000 "buffer preallocation failer error:%d\n", ret); 1046 "buffer preallocation failure error:%d\n", ret);
1001 return ret; 1047 return ret;
1002} 1048}
1003 1049
@@ -1007,38 +1053,55 @@ static int acp_dma_close(struct snd_pcm_substream *substream)
1007 struct snd_pcm_runtime *runtime = substream->runtime; 1053 struct snd_pcm_runtime *runtime = substream->runtime;
1008 struct audio_substream_data *rtd = runtime->private_data; 1054 struct audio_substream_data *rtd = runtime->private_data;
1009 struct snd_soc_pcm_runtime *prtd = substream->private_data; 1055 struct snd_soc_pcm_runtime *prtd = substream->private_data;
1010 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); 1056 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd,
1057 DRV_NAME);
1011 struct audio_drv_data *adata = dev_get_drvdata(component->dev); 1058 struct audio_drv_data *adata = dev_get_drvdata(component->dev);
1012 1059
1013 kfree(rtd);
1014
1015 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1060 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1016 adata->play_i2ssp_stream = NULL; 1061 switch (rtd->i2s_instance) {
1017 /* For Stoney, Memory gating is disabled,i.e SRAM Banks 1062 case I2S_BT_INSTANCE:
1018 * won't be turned off. The default state for SRAM banks is ON. 1063 adata->play_i2sbt_stream = NULL;
1019 * Setting SRAM bank state code skipped for STONEY platform. 1064 break;
1020 * added condition checks for Carrizo platform only 1065 case I2S_SP_INSTANCE:
1021 */ 1066 default:
1022 if (adata->asic_type != CHIP_STONEY) { 1067 adata->play_i2ssp_stream = NULL;
1023 for (bank = 1; bank <= 4; bank++) 1068 /*
1024 acp_set_sram_bank_state(adata->acp_mmio, bank, 1069 * For Stoney, Memory gating is disabled,i.e SRAM Banks
1025 false); 1070 * won't be turned off. The default state for SRAM banks
1071 * is ON.Setting SRAM bank state code skipped for STONEY
1072 * platform. Added condition checks for Carrizo platform
1073 * only.
1074 */
1075 if (adata->asic_type != CHIP_STONEY) {
1076 for (bank = 1; bank <= 4; bank++)
1077 acp_set_sram_bank_state(adata->acp_mmio,
1078 bank, false);
1079 }
1026 } 1080 }
1027 } else { 1081 } else {
1028 adata->capture_i2ssp_stream = NULL; 1082 switch (rtd->i2s_instance) {
1029 if (adata->asic_type != CHIP_STONEY) { 1083 case I2S_BT_INSTANCE:
1030 for (bank = 5; bank <= 8; bank++) 1084 adata->capture_i2sbt_stream = NULL;
1031 acp_set_sram_bank_state(adata->acp_mmio, bank, 1085 break;
1032 false); 1086 case I2S_SP_INSTANCE:
1087 default:
1088 adata->capture_i2ssp_stream = NULL;
1089 if (adata->asic_type != CHIP_STONEY) {
1090 for (bank = 5; bank <= 8; bank++)
1091 acp_set_sram_bank_state(adata->acp_mmio,
1092 bank, false);
1093 }
1033 } 1094 }
1034 } 1095 }
1035 1096
1036 /* Disable ACP irq, when the current stream is being closed and 1097 /*
1098 * Disable ACP irq, when the current stream is being closed and
1037 * another stream is also not active. 1099 * another stream is also not active.
1038 */ 1100 */
1039 if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream) 1101 if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream &&
1102 !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream)
1040 acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 1103 acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
1041 1104 kfree(rtd);
1042 return 0; 1105 return 0;
1043} 1106}
1044 1107
@@ -1054,7 +1117,7 @@ static const struct snd_pcm_ops acp_dma_ops = {
1054 .prepare = acp_dma_prepare, 1117 .prepare = acp_dma_prepare,
1055}; 1118};
1056 1119
1057static struct snd_soc_component_driver acp_asoc_platform = { 1120static const struct snd_soc_component_driver acp_asoc_platform = {
1058 .name = DRV_NAME, 1121 .name = DRV_NAME,
1059 .ops = &acp_dma_ops, 1122 .ops = &acp_dma_ops,
1060 .pcm_new = acp_dma_new, 1123 .pcm_new = acp_dma_new,
@@ -1073,8 +1136,8 @@ static int acp_audio_probe(struct platform_device *pdev)
1073 } 1136 }
1074 1137
1075 audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data), 1138 audio_drv_data = devm_kzalloc(&pdev->dev, sizeof(struct audio_drv_data),
1076 GFP_KERNEL); 1139 GFP_KERNEL);
1077 if (audio_drv_data == NULL) 1140 if (!audio_drv_data)
1078 return -ENOMEM; 1141 return -ENOMEM;
1079 1142
1080 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1143 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1082,13 +1145,16 @@ static int acp_audio_probe(struct platform_device *pdev)
1082 if (IS_ERR(audio_drv_data->acp_mmio)) 1145 if (IS_ERR(audio_drv_data->acp_mmio))
1083 return PTR_ERR(audio_drv_data->acp_mmio); 1146 return PTR_ERR(audio_drv_data->acp_mmio);
1084 1147
1085 /* The following members gets populated in device 'open' 1148 /*
1149 * The following members gets populated in device 'open'
1086 * function. Till then interrupts are disabled in 'acp_init' 1150 * function. Till then interrupts are disabled in 'acp_init'
1087 * and device doesn't generate any interrupts. 1151 * and device doesn't generate any interrupts.
1088 */ 1152 */
1089 1153
1090 audio_drv_data->play_i2ssp_stream = NULL; 1154 audio_drv_data->play_i2ssp_stream = NULL;
1091 audio_drv_data->capture_i2ssp_stream = NULL; 1155 audio_drv_data->capture_i2ssp_stream = NULL;
1156 audio_drv_data->play_i2sbt_stream = NULL;
1157 audio_drv_data->capture_i2sbt_stream = NULL;
1092 1158
1093 audio_drv_data->asic_type = *pdata; 1159 audio_drv_data->asic_type = *pdata;
1094 1160
@@ -1099,7 +1165,7 @@ static int acp_audio_probe(struct platform_device *pdev)
1099 } 1165 }
1100 1166
1101 status = devm_request_irq(&pdev->dev, res->start, dma_irq_handler, 1167 status = devm_request_irq(&pdev->dev, res->start, dma_irq_handler,
1102 0, "ACP_IRQ", &pdev->dev); 1168 0, "ACP_IRQ", &pdev->dev);
1103 if (status) { 1169 if (status) {
1104 dev_err(&pdev->dev, "ACP IRQ request failed\n"); 1170 dev_err(&pdev->dev, "ACP IRQ request failed\n");
1105 return status; 1171 return status;
@@ -1115,7 +1181,7 @@ static int acp_audio_probe(struct platform_device *pdev)
1115 } 1181 }
1116 1182
1117 status = devm_snd_soc_register_component(&pdev->dev, 1183 status = devm_snd_soc_register_component(&pdev->dev,
1118 &acp_asoc_platform, NULL, 0); 1184 &acp_asoc_platform, NULL, 0);
1119 if (status != 0) { 1185 if (status != 0) {
1120 dev_err(&pdev->dev, "Fail to register ALSA platform device\n"); 1186 dev_err(&pdev->dev, "Fail to register ALSA platform device\n");
1121 return status; 1187 return status;
@@ -1145,6 +1211,7 @@ static int acp_pcm_resume(struct device *dev)
1145{ 1211{
1146 u16 bank; 1212 u16 bank;
1147 int status; 1213 int status;
1214 struct audio_substream_data *rtd;
1148 struct audio_drv_data *adata = dev_get_drvdata(dev); 1215 struct audio_drv_data *adata = dev_get_drvdata(dev);
1149 1216
1150 status = acp_init(adata->acp_mmio, adata->asic_type); 1217 status = acp_init(adata->acp_mmio, adata->asic_type);
@@ -1154,28 +1221,40 @@ static int acp_pcm_resume(struct device *dev)
1154 } 1221 }
1155 1222
1156 if (adata->play_i2ssp_stream && adata->play_i2ssp_stream->runtime) { 1223 if (adata->play_i2ssp_stream && adata->play_i2ssp_stream->runtime) {
1157 /* For Stoney, Memory gating is disabled,i.e SRAM Banks 1224 /*
1225 * For Stoney, Memory gating is disabled,i.e SRAM Banks
1158 * won't be turned off. The default state for SRAM banks is ON. 1226 * won't be turned off. The default state for SRAM banks is ON.
1159 * Setting SRAM bank state code skipped for STONEY platform. 1227 * Setting SRAM bank state code skipped for STONEY platform.
1160 */ 1228 */
1161 if (adata->asic_type != CHIP_STONEY) { 1229 if (adata->asic_type != CHIP_STONEY) {
1162 for (bank = 1; bank <= 4; bank++) 1230 for (bank = 1; bank <= 4; bank++)
1163 acp_set_sram_bank_state(adata->acp_mmio, bank, 1231 acp_set_sram_bank_state(adata->acp_mmio, bank,
1164 true); 1232 true);
1165 } 1233 }
1166 config_acp_dma(adata->acp_mmio, 1234 rtd = adata->play_i2ssp_stream->runtime->private_data;
1167 adata->play_i2ssp_stream->runtime->private_data, 1235 config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
1168 adata->asic_type);
1169 } 1236 }
1170 if (adata->capture_i2ssp_stream && adata->capture_i2ssp_stream->runtime) { 1237 if (adata->capture_i2ssp_stream &&
1238 adata->capture_i2ssp_stream->runtime) {
1171 if (adata->asic_type != CHIP_STONEY) { 1239 if (adata->asic_type != CHIP_STONEY) {
1172 for (bank = 5; bank <= 8; bank++) 1240 for (bank = 5; bank <= 8; bank++)
1173 acp_set_sram_bank_state(adata->acp_mmio, bank, 1241 acp_set_sram_bank_state(adata->acp_mmio, bank,
1174 true); 1242 true);
1243 }
1244 rtd = adata->capture_i2ssp_stream->runtime->private_data;
1245 config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
1246 }
1247 if (adata->asic_type != CHIP_CARRIZO) {
1248 if (adata->play_i2sbt_stream &&
1249 adata->play_i2sbt_stream->runtime) {
1250 rtd = adata->play_i2sbt_stream->runtime->private_data;
1251 config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
1252 }
1253 if (adata->capture_i2sbt_stream &&
1254 adata->capture_i2sbt_stream->runtime) {
1255 rtd = adata->capture_i2sbt_stream->runtime->private_data;
1256 config_acp_dma(adata->acp_mmio, rtd, adata->asic_type);
1175 } 1257 }
1176 config_acp_dma(adata->acp_mmio,
1177 adata->capture_i2ssp_stream->runtime->private_data,
1178 adata->asic_type);
1179 } 1258 }
1180 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 1259 acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB);
1181 return 0; 1260 return 0;
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index ba01510eb818..9cd3e96c84d4 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -10,17 +10,30 @@
10#define ACP_PLAYBACK_PTE_OFFSET 10 10#define ACP_PLAYBACK_PTE_OFFSET 10
11#define ACP_CAPTURE_PTE_OFFSET 0 11#define ACP_CAPTURE_PTE_OFFSET 0
12 12
13/* Playback and Capture Offset for Stoney */
14#define ACP_ST_PLAYBACK_PTE_OFFSET 0x04
15#define ACP_ST_CAPTURE_PTE_OFFSET 0x00
16#define ACP_ST_BT_PLAYBACK_PTE_OFFSET 0x08
17#define ACP_ST_BT_CAPTURE_PTE_OFFSET 0x0c
18
13#define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4 19#define ACP_GARLIC_CNTL_DEFAULT 0x00000FB4
14#define ACP_ONION_CNTL_DEFAULT 0x00000FB4 20#define ACP_ONION_CNTL_DEFAULT 0x00000FB4
15 21
16#define ACP_PHYSICAL_BASE 0x14000 22#define ACP_PHYSICAL_BASE 0x14000
17 23
18/* Playback SRAM address (as a destination in dma descriptor) */ 24/*
19#define ACP_SHARED_RAM_BANK_1_ADDRESS 0x4002000 25 * In case of I2S SP controller instance, Stoney uses SRAM bank 1 for
20 26 * playback and SRAM Bank 2 for capture where as in case of BT I2S
21/* Capture SRAM address (as a source in dma descriptor) */ 27 * Instance, Stoney uses SRAM Bank 3 for playback & SRAM Bank 4 will
22#define ACP_SHARED_RAM_BANK_5_ADDRESS 0x400A000 28 * be used for capture. Carrizo uses I2S SP controller instance. SRAM Banks
23#define ACP_SHARED_RAM_BANK_3_ADDRESS 0x4006000 29 * 1, 2, 3, 4 will be used for playback & SRAM Banks 5, 6, 7, 8 will be used
30 * for capture scenario.
31 */
32#define ACP_SRAM_BANK_1_ADDRESS 0x4002000
33#define ACP_SRAM_BANK_2_ADDRESS 0x4004000
34#define ACP_SRAM_BANK_3_ADDRESS 0x4006000
35#define ACP_SRAM_BANK_4_ADDRESS 0x4008000
36#define ACP_SRAM_BANK_5_ADDRESS 0x400A000
24 37
25#define ACP_DMA_RESET_TIME 10000 38#define ACP_DMA_RESET_TIME 10000
26#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF 39#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF
@@ -35,8 +48,13 @@
35 48
36#define TO_ACP_I2S_1 0x2 49#define TO_ACP_I2S_1 0x2
37#define TO_ACP_I2S_2 0x4 50#define TO_ACP_I2S_2 0x4
51#define TO_BLUETOOTH 0x3
38#define FROM_ACP_I2S_1 0xa 52#define FROM_ACP_I2S_1 0xa
39#define FROM_ACP_I2S_2 0xb 53#define FROM_ACP_I2S_2 0xb
54#define FROM_BLUETOOTH 0xb
55
56#define I2S_SP_INSTANCE 0x01
57#define I2S_BT_INSTANCE 0x02
40 58
41#define ACP_TILE_ON_MASK 0x03 59#define ACP_TILE_ON_MASK 0x03
42#define ACP_TILE_OFF_MASK 0x02 60#define ACP_TILE_OFF_MASK 0x02
@@ -57,6 +75,14 @@
57#define ACP_TO_SYSRAM_CH_NUM 14 75#define ACP_TO_SYSRAM_CH_NUM 14
58#define I2S_TO_ACP_DMA_CH_NUM 15 76#define I2S_TO_ACP_DMA_CH_NUM 15
59 77
78/* Playback DMA Channels for I2S BT instance */
79#define SYSRAM_TO_ACP_BT_INSTANCE_CH_NUM 8
80#define ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM 9
81
82/* Capture DMA Channels for I2S BT Instance */
83#define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 10
84#define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 11
85
60#define NUM_DSCRS_PER_CHANNEL 2 86#define NUM_DSCRS_PER_CHANNEL 2
61 87
62#define PLAYBACK_START_DMA_DESCR_CH12 0 88#define PLAYBACK_START_DMA_DESCR_CH12 0
@@ -69,9 +95,23 @@
69#define CAPTURE_START_DMA_DESCR_CH15 6 95#define CAPTURE_START_DMA_DESCR_CH15 6
70#define CAPTURE_END_DMA_DESCR_CH15 7 96#define CAPTURE_END_DMA_DESCR_CH15 7
71 97
98/* I2S BT Instance DMA Descriptors */
99#define PLAYBACK_START_DMA_DESCR_CH8 8
100#define PLAYBACK_END_DMA_DESCR_CH8 9
101#define PLAYBACK_START_DMA_DESCR_CH9 10
102#define PLAYBACK_END_DMA_DESCR_CH9 11
103
104#define CAPTURE_START_DMA_DESCR_CH10 12
105#define CAPTURE_END_DMA_DESCR_CH10 13
106#define CAPTURE_START_DMA_DESCR_CH11 14
107#define CAPTURE_END_DMA_DESCR_CH11 15
108
72#define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 109#define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209
73#define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 110#define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01
74#define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 111#define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02
112#define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04
113#define ACP_BT_UART_PAD_SELECT_MASK 0x1
114
75enum acp_dma_priority_level { 115enum acp_dma_priority_level {
76 /* 0x0 Specifies the DMA channel is given normal priority */ 116 /* 0x0 Specifies the DMA channel is given normal priority */
77 ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0, 117 ACP_DMA_PRIORITY_LEVEL_NORMAL = 0x0,
@@ -84,20 +124,39 @@ struct audio_substream_data {
84 struct page *pg; 124 struct page *pg;
85 unsigned int order; 125 unsigned int order;
86 u16 num_of_pages; 126 u16 num_of_pages;
127 u16 i2s_instance;
87 u16 direction; 128 u16 direction;
129 u16 ch1;
130 u16 ch2;
131 u16 destination;
132 u16 dma_dscr_idx_1;
133 u16 dma_dscr_idx_2;
134 u32 pte_offset;
135 u32 sram_bank;
136 u32 byte_cnt_high_reg_offset;
137 u32 byte_cnt_low_reg_offset;
88 uint64_t size; 138 uint64_t size;
89 u64 i2ssp_renderbytescount; 139 u64 bytescount;
90 u64 i2ssp_capturebytescount;
91 void __iomem *acp_mmio; 140 void __iomem *acp_mmio;
92}; 141};
93 142
94struct audio_drv_data { 143struct audio_drv_data {
95 struct snd_pcm_substream *play_i2ssp_stream; 144 struct snd_pcm_substream *play_i2ssp_stream;
96 struct snd_pcm_substream *capture_i2ssp_stream; 145 struct snd_pcm_substream *capture_i2ssp_stream;
146 struct snd_pcm_substream *play_i2sbt_stream;
147 struct snd_pcm_substream *capture_i2sbt_stream;
97 void __iomem *acp_mmio; 148 void __iomem *acp_mmio;
98 u32 asic_type; 149 u32 asic_type;
99}; 150};
100 151
152/*
153 * this structure used for platform data transfer between machine driver
154 * and dma driver
155 */
156struct acp_platform_info {
157 u16 i2s_instance;
158};
159
101union acp_dma_count { 160union acp_dma_count {
102 struct { 161 struct {
103 u32 low; 162 u32 low;
@@ -115,23 +174,25 @@ enum {
115}; 174};
116 175
117enum { 176enum {
118 ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION = 0x0, 177 ACP_DMA_ATTR_SHAREDMEM_TO_DAGB_ONION = 0x0,
119 ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC = 0x1, 178 ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC = 0x1,
120 ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM = 0x8, 179 ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM = 0x8,
121 ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM = 0x9, 180 ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM = 0x9,
122 ACP_DMA_ATTRIBUTES_FORCE_SIZE = 0xF 181 ACP_DMA_ATTR_FORCE_SIZE = 0xF
123}; 182};
124 183
125typedef struct acp_dma_dscr_transfer { 184typedef struct acp_dma_dscr_transfer {
126 /* Specifies the source memory location for the DMA data transfer. */ 185 /* Specifies the source memory location for the DMA data transfer. */
127 u32 src; 186 u32 src;
128 /* Specifies the destination memory location to where the data will 187 /*
188 * Specifies the destination memory location to where the data will
129 * be transferred. 189 * be transferred.
130 */ 190 */
131 u32 dest; 191 u32 dest;
132 /* Specifies the number of bytes need to be transferred 192 /*
133 * from source to destination memory.Transfer direction & IOC enable 193 * Specifies the number of bytes need to be transferred
134 */ 194 * from source to destination memory.Transfer direction & IOC enable
195 */
135 u32 xfer_val; 196 u32 xfer_val;
136 /* Reserved for future use */ 197 /* Reserved for future use */
137 u32 reserved; 198 u32 reserved;
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index dcee145dd179..64b784e96f84 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -88,4 +88,13 @@ config SND_ATMEL_SOC_TSE850_PCM5142
88 help 88 help
89 Say Y if you want to add support for the ASoC driver for the 89 Say Y if you want to add support for the ASoC driver for the
90 Axentia TSE-850 with a PCM5142 codec. 90 Axentia TSE-850 with a PCM5142 codec.
91
92config SND_ATMEL_SOC_I2S
93 tristate "Atmel ASoC driver for boards using I2S"
94 depends on OF && (ARCH_AT91 || COMPILE_TEST)
95 select SND_SOC_GENERIC_DMAENGINE_PCM
96 select REGMAP_MMIO
97 help
98 Say Y or M if you want to add support for Atmel ASoc driver for boards
99 using I2S.
91endif 100endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 4440646416e8..cd87cb4bcff5 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -3,10 +3,12 @@
3snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o 3snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
4snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o 4snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
5snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o 5snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
6snd-soc-atmel-i2s-objs := atmel-i2s.o
6 7
7obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o 8obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
8obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o 9obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
9obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o 10obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
11obj-$(CONFIG_SND_ATMEL_SOC_I2S) += snd-soc-atmel-i2s.o
10 12
11# AT91 Machine Support 13# AT91 Machine Support
12snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o 14snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
new file mode 100644
index 000000000000..5d3b5af9fd92
--- /dev/null
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -0,0 +1,765 @@
1/*
2 * Driver for Atmel I2S controller
3 *
4 * Copyright (C) 2015 Atmel Corporation
5 *
6 * Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/device.h>
24#include <linux/slab.h>
25#include <linux/delay.h>
26#include <linux/io.h>
27#include <linux/clk.h>
28#include <linux/mfd/syscon.h>
29
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/initval.h>
34#include <sound/soc.h>
35#include <sound/dmaengine_pcm.h>
36
37#define ATMEL_I2SC_MAX_TDM_CHANNELS 8
38
39/*
40 * ---- I2S Controller Register map ----
41 */
42#define ATMEL_I2SC_CR 0x0000 /* Control Register */
43#define ATMEL_I2SC_MR 0x0004 /* Mode Register */
44#define ATMEL_I2SC_SR 0x0008 /* Status Register */
45#define ATMEL_I2SC_SCR 0x000c /* Status Clear Register */
46#define ATMEL_I2SC_SSR 0x0010 /* Status Set Register */
47#define ATMEL_I2SC_IER 0x0014 /* Interrupt Enable Register */
48#define ATMEL_I2SC_IDR 0x0018 /* Interrupt Disable Register */
49#define ATMEL_I2SC_IMR 0x001c /* Interrupt Mask Register */
50#define ATMEL_I2SC_RHR 0x0020 /* Receiver Holding Register */
51#define ATMEL_I2SC_THR 0x0024 /* Transmitter Holding Register */
52#define ATMEL_I2SC_VERSION 0x0028 /* Version Register */
53
54/*
55 * ---- Control Register (Write-only) ----
56 */
57#define ATMEL_I2SC_CR_RXEN BIT(0) /* Receiver Enable */
58#define ATMEL_I2SC_CR_RXDIS BIT(1) /* Receiver Disable */
59#define ATMEL_I2SC_CR_CKEN BIT(2) /* Clock Enable */
60#define ATMEL_I2SC_CR_CKDIS BIT(3) /* Clock Disable */
61#define ATMEL_I2SC_CR_TXEN BIT(4) /* Transmitter Enable */
62#define ATMEL_I2SC_CR_TXDIS BIT(5) /* Transmitter Disable */
63#define ATMEL_I2SC_CR_SWRST BIT(7) /* Software Reset */
64
65/*
66 * ---- Mode Register (Read/Write) ----
67 */
68#define ATMEL_I2SC_MR_MODE_MASK GENMASK(0, 0)
69#define ATMEL_I2SC_MR_MODE_SLAVE (0 << 0)
70#define ATMEL_I2SC_MR_MODE_MASTER (1 << 0)
71
72#define ATMEL_I2SC_MR_DATALENGTH_MASK GENMASK(4, 2)
73#define ATMEL_I2SC_MR_DATALENGTH_32_BITS (0 << 2)
74#define ATMEL_I2SC_MR_DATALENGTH_24_BITS (1 << 2)
75#define ATMEL_I2SC_MR_DATALENGTH_20_BITS (2 << 2)
76#define ATMEL_I2SC_MR_DATALENGTH_18_BITS (3 << 2)
77#define ATMEL_I2SC_MR_DATALENGTH_16_BITS (4 << 2)
78#define ATMEL_I2SC_MR_DATALENGTH_16_BITS_COMPACT (5 << 2)
79#define ATMEL_I2SC_MR_DATALENGTH_8_BITS (6 << 2)
80#define ATMEL_I2SC_MR_DATALENGTH_8_BITS_COMPACT (7 << 2)
81
82#define ATMEL_I2SC_MR_FORMAT_MASK GENMASK(7, 6)
83#define ATMEL_I2SC_MR_FORMAT_I2S (0 << 6)
84#define ATMEL_I2SC_MR_FORMAT_LJ (1 << 6) /* Left Justified */
85#define ATMEL_I2SC_MR_FORMAT_TDM (2 << 6)
86#define ATMEL_I2SC_MR_FORMAT_TDMLJ (3 << 6)
87
88/* Left audio samples duplicated to right audio channel */
89#define ATMEL_I2SC_MR_RXMONO BIT(8)
90
91/* Receiver uses one DMA channel ... */
92#define ATMEL_I2SC_MR_RXDMA_MASK GENMASK(9, 9)
93#define ATMEL_I2SC_MR_RXDMA_SINGLE (0 << 9) /* for all audio channels */
94#define ATMEL_I2SC_MR_RXDMA_MULTIPLE (1 << 9) /* per audio channel */
95
96/* I2SDO output of I2SC is internally connected to I2SDI input */
97#define ATMEL_I2SC_MR_RXLOOP BIT(10)
98
99/* Left audio samples duplicated to right audio channel */
100#define ATMEL_I2SC_MR_TXMONO BIT(12)
101
102/* Transmitter uses one DMA channel ... */
103#define ATMEL_I2SC_MR_TXDMA_MASK GENMASK(13, 13)
104#define ATMEL_I2SC_MR_TXDMA_SINGLE (0 << 13) /* for all audio channels */
105#define ATMEL_I2SC_MR_TXDME_MULTIPLE (1 << 13) /* per audio channel */
106
107/* x sample transmitted when underrun */
108#define ATMEL_I2SC_MR_TXSAME_MASK GENMASK(14, 14)
109#define ATMEL_I2SC_MR_TXSAME_ZERO (0 << 14) /* Zero sample */
110#define ATMEL_I2SC_MR_TXSAME_PREVIOUS (1 << 14) /* Previous sample */
111
112/* Audio Clock to I2SC Master Clock ratio */
113#define ATMEL_I2SC_MR_IMCKDIV_MASK GENMASK(21, 16)
114#define ATMEL_I2SC_MR_IMCKDIV(div) \
115 (((div) << 16) & ATMEL_I2SC_MR_IMCKDIV_MASK)
116
117/* Master Clock to fs ratio */
118#define ATMEL_I2SC_MR_IMCKFS_MASK GENMASK(29, 24)
119#define ATMEL_I2SC_MR_IMCKFS(fs) \
120 (((fs) << 24) & ATMEL_I2SC_MR_IMCKFS_MASK)
121
122/* Master Clock mode */
123#define ATMEL_I2SC_MR_IMCKMODE_MASK GENMASK(30, 30)
124/* 0: No master clock generated (selected clock drives I2SCK pin) */
125#define ATMEL_I2SC_MR_IMCKMODE_I2SCK (0 << 30)
126/* 1: master clock generated (internally generated clock drives I2SMCK pin) */
127#define ATMEL_I2SC_MR_IMCKMODE_I2SMCK (1 << 30)
128
129/* Slot Width */
130/* 0: slot is 32 bits wide for DATALENGTH = 18/20/24 bits. */
131/* 1: slot is 24 bits wide for DATALENGTH = 18/20/24 bits. */
132#define ATMEL_I2SC_MR_IWS BIT(31)
133
134/*
135 * ---- Status Registers ----
136 */
137#define ATMEL_I2SC_SR_RXEN BIT(0) /* Receiver Enabled */
138#define ATMEL_I2SC_SR_RXRDY BIT(1) /* Receive Ready */
139#define ATMEL_I2SC_SR_RXOR BIT(2) /* Receive Overrun */
140
141#define ATMEL_I2SC_SR_TXEN BIT(4) /* Transmitter Enabled */
142#define ATMEL_I2SC_SR_TXRDY BIT(5) /* Transmit Ready */
143#define ATMEL_I2SC_SR_TXUR BIT(6) /* Transmit Underrun */
144
145/* Receive Overrun Channel */
146#define ATMEL_I2SC_SR_RXORCH_MASK GENMASK(15, 8)
147#define ATMEL_I2SC_SR_RXORCH(ch) (1 << (((ch) & 0x7) + 8))
148
149/* Transmit Underrun Channel */
150#define ATMEL_I2SC_SR_TXURCH_MASK GENMASK(27, 20)
151#define ATMEL_I2SC_SR_TXURCH(ch) (1 << (((ch) & 0x7) + 20))
152
153/*
154 * ---- Interrupt Enable/Disable/Mask Registers ----
155 */
156#define ATMEL_I2SC_INT_RXRDY ATMEL_I2SC_SR_RXRDY
157#define ATMEL_I2SC_INT_RXOR ATMEL_I2SC_SR_RXOR
158#define ATMEL_I2SC_INT_TXRDY ATMEL_I2SC_SR_TXRDY
159#define ATMEL_I2SC_INT_TXUR ATMEL_I2SC_SR_TXUR
160
161static const struct regmap_config atmel_i2s_regmap_config = {
162 .reg_bits = 32,
163 .reg_stride = 4,
164 .val_bits = 32,
165 .max_register = ATMEL_I2SC_VERSION,
166};
167
168struct atmel_i2s_gck_param {
169 int fs;
170 unsigned long mck;
171 int imckdiv;
172 int imckfs;
173};
174
175#define I2S_MCK_12M288 12288000UL
176#define I2S_MCK_11M2896 11289600UL
177
178/* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */
179static const struct atmel_i2s_gck_param gck_params[] = {
180 /* mck = 12.288MHz */
181 { 8000, I2S_MCK_12M288, 0, 47}, /* mck = 1536 fs */
182 { 16000, I2S_MCK_12M288, 1, 47}, /* mck = 768 fs */
183 { 24000, I2S_MCK_12M288, 3, 63}, /* mck = 512 fs */
184 { 32000, I2S_MCK_12M288, 3, 47}, /* mck = 384 fs */
185 { 48000, I2S_MCK_12M288, 7, 63}, /* mck = 256 fs */
186 { 64000, I2S_MCK_12M288, 7, 47}, /* mck = 192 fs */
187 { 96000, I2S_MCK_12M288, 7, 31}, /* mck = 128 fs */
188 {192000, I2S_MCK_12M288, 7, 15}, /* mck = 64 fs */
189
190 /* mck = 11.2896MHz */
191 { 11025, I2S_MCK_11M2896, 1, 63}, /* mck = 1024 fs */
192 { 22050, I2S_MCK_11M2896, 3, 63}, /* mck = 512 fs */
193 { 44100, I2S_MCK_11M2896, 7, 63}, /* mck = 256 fs */
194 { 88200, I2S_MCK_11M2896, 7, 31}, /* mck = 128 fs */
195 {176400, I2S_MCK_11M2896, 7, 15}, /* mck = 64 fs */
196};
197
198struct atmel_i2s_dev;
199
200struct atmel_i2s_caps {
201 int (*mck_init)(struct atmel_i2s_dev *, struct device_node *np);
202};
203
204struct atmel_i2s_dev {
205 struct device *dev;
206 struct regmap *regmap;
207 struct clk *pclk;
208 struct clk *gclk;
209 struct clk *aclk;
210 struct snd_dmaengine_dai_dma_data playback;
211 struct snd_dmaengine_dai_dma_data capture;
212 unsigned int fmt;
213 const struct atmel_i2s_gck_param *gck_param;
214 const struct atmel_i2s_caps *caps;
215};
216
217static irqreturn_t atmel_i2s_interrupt(int irq, void *dev_id)
218{
219 struct atmel_i2s_dev *dev = dev_id;
220 unsigned int sr, imr, pending, ch, mask;
221 irqreturn_t ret = IRQ_NONE;
222
223 regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
224 regmap_read(dev->regmap, ATMEL_I2SC_IMR, &imr);
225 pending = sr & imr;
226
227 if (!pending)
228 return IRQ_NONE;
229
230 if (pending & ATMEL_I2SC_INT_RXOR) {
231 mask = ATMEL_I2SC_SR_RXOR;
232
233 for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
234 if (sr & ATMEL_I2SC_SR_RXORCH(ch)) {
235 mask |= ATMEL_I2SC_SR_RXORCH(ch);
236 dev_err(dev->dev,
237 "RX overrun on channel %d\n", ch);
238 }
239 }
240 regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
241 ret = IRQ_HANDLED;
242 }
243
244 if (pending & ATMEL_I2SC_INT_TXUR) {
245 mask = ATMEL_I2SC_SR_TXUR;
246
247 for (ch = 0; ch < ATMEL_I2SC_MAX_TDM_CHANNELS; ++ch) {
248 if (sr & ATMEL_I2SC_SR_TXURCH(ch)) {
249 mask |= ATMEL_I2SC_SR_TXURCH(ch);
250 dev_err(dev->dev,
251 "TX underrun on channel %d\n", ch);
252 }
253 }
254 regmap_write(dev->regmap, ATMEL_I2SC_SCR, mask);
255 ret = IRQ_HANDLED;
256 }
257
258 return ret;
259}
260
261#define ATMEL_I2S_RATES SNDRV_PCM_RATE_8000_192000
262
263#define ATMEL_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
264 SNDRV_PCM_FMTBIT_S16_LE | \
265 SNDRV_PCM_FMTBIT_S18_3LE | \
266 SNDRV_PCM_FMTBIT_S20_3LE | \
267 SNDRV_PCM_FMTBIT_S24_3LE | \
268 SNDRV_PCM_FMTBIT_S24_LE | \
269 SNDRV_PCM_FMTBIT_S32_LE)
270
271static int atmel_i2s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
272{
273 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
274
275 dev->fmt = fmt;
276 return 0;
277}
278
279static int atmel_i2s_prepare(struct snd_pcm_substream *substream,
280 struct snd_soc_dai *dai)
281{
282 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
283 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
284 unsigned int rhr, sr = 0;
285
286 if (is_playback) {
287 regmap_read(dev->regmap, ATMEL_I2SC_SR, &sr);
288 if (sr & ATMEL_I2SC_SR_RXRDY) {
289 /*
290 * The RX Ready flag should not be set. However if here,
291 * we flush (read) the Receive Holding Register to start
292 * from a clean state.
293 */
294 dev_dbg(dev->dev, "RXRDY is set\n");
295 regmap_read(dev->regmap, ATMEL_I2SC_RHR, &rhr);
296 }
297 }
298
299 return 0;
300}
301
302static int atmel_i2s_get_gck_param(struct atmel_i2s_dev *dev, int fs)
303{
304 int i, best;
305
306 if (!dev->gclk || !dev->aclk) {
307 dev_err(dev->dev, "cannot generate the I2S Master Clock\n");
308 return -EINVAL;
309 }
310
311 /*
312 * Find the best possible settings to generate the I2S Master Clock
313 * from the PLL Audio.
314 */
315 dev->gck_param = NULL;
316 best = INT_MAX;
317 for (i = 0; i < ARRAY_SIZE(gck_params); ++i) {
318 const struct atmel_i2s_gck_param *gck_param = &gck_params[i];
319 int val = abs(fs - gck_param->fs);
320
321 if (val < best) {
322 best = val;
323 dev->gck_param = gck_param;
324 }
325 }
326
327 return 0;
328}
329
330static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
331 struct snd_pcm_hw_params *params,
332 struct snd_soc_dai *dai)
333{
334 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
335 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
336 unsigned int mr = 0;
337 int ret;
338
339 switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
340 case SND_SOC_DAIFMT_I2S:
341 mr |= ATMEL_I2SC_MR_FORMAT_I2S;
342 break;
343
344 default:
345 dev_err(dev->dev, "unsupported bus format\n");
346 return -EINVAL;
347 }
348
349 switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
350 case SND_SOC_DAIFMT_CBS_CFS:
351 /* codec is slave, so cpu is master */
352 mr |= ATMEL_I2SC_MR_MODE_MASTER;
353 ret = atmel_i2s_get_gck_param(dev, params_rate(params));
354 if (ret)
355 return ret;
356 break;
357
358 case SND_SOC_DAIFMT_CBM_CFM:
359 /* codec is master, so cpu is slave */
360 mr |= ATMEL_I2SC_MR_MODE_SLAVE;
361 dev->gck_param = NULL;
362 break;
363
364 default:
365 dev_err(dev->dev, "unsupported master/slave mode\n");
366 return -EINVAL;
367 }
368
369 switch (params_channels(params)) {
370 case 1:
371 if (is_playback)
372 mr |= ATMEL_I2SC_MR_TXMONO;
373 else
374 mr |= ATMEL_I2SC_MR_RXMONO;
375 break;
376 case 2:
377 break;
378 default:
379 dev_err(dev->dev, "unsupported number of audio channels\n");
380 return -EINVAL;
381 }
382
383 switch (params_format(params)) {
384 case SNDRV_PCM_FORMAT_S8:
385 mr |= ATMEL_I2SC_MR_DATALENGTH_8_BITS;
386 break;
387
388 case SNDRV_PCM_FORMAT_S16_LE:
389 mr |= ATMEL_I2SC_MR_DATALENGTH_16_BITS;
390 break;
391
392 case SNDRV_PCM_FORMAT_S18_3LE:
393 mr |= ATMEL_I2SC_MR_DATALENGTH_18_BITS | ATMEL_I2SC_MR_IWS;
394 break;
395
396 case SNDRV_PCM_FORMAT_S20_3LE:
397 mr |= ATMEL_I2SC_MR_DATALENGTH_20_BITS | ATMEL_I2SC_MR_IWS;
398 break;
399
400 case SNDRV_PCM_FORMAT_S24_3LE:
401 mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS | ATMEL_I2SC_MR_IWS;
402 break;
403
404 case SNDRV_PCM_FORMAT_S24_LE:
405 mr |= ATMEL_I2SC_MR_DATALENGTH_24_BITS;
406 break;
407
408 case SNDRV_PCM_FORMAT_S32_LE:
409 mr |= ATMEL_I2SC_MR_DATALENGTH_32_BITS;
410 break;
411
412 default:
413 dev_err(dev->dev, "unsupported size/endianness for audio samples\n");
414 return -EINVAL;
415 }
416
417 return regmap_write(dev->regmap, ATMEL_I2SC_MR, mr);
418}
419
420static int atmel_i2s_switch_mck_generator(struct atmel_i2s_dev *dev,
421 bool enabled)
422{
423 unsigned int mr, mr_mask;
424 unsigned long aclk_rate;
425 int ret;
426
427 mr = 0;
428 mr_mask = (ATMEL_I2SC_MR_IMCKDIV_MASK |
429 ATMEL_I2SC_MR_IMCKFS_MASK |
430 ATMEL_I2SC_MR_IMCKMODE_MASK);
431
432 if (!enabled) {
433 /* Disable the I2S Master Clock generator. */
434 ret = regmap_write(dev->regmap, ATMEL_I2SC_CR,
435 ATMEL_I2SC_CR_CKDIS);
436 if (ret)
437 return ret;
438
439 /* Reset the I2S Master Clock generator settings. */
440 ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR,
441 mr_mask, mr);
442 if (ret)
443 return ret;
444
445 /* Disable/unprepare the PMC generated clock. */
446 clk_disable_unprepare(dev->gclk);
447
448 /* Disable/unprepare the PLL audio clock. */
449 clk_disable_unprepare(dev->aclk);
450 return 0;
451 }
452
453 if (!dev->gck_param)
454 return -EINVAL;
455
456 aclk_rate = dev->gck_param->mck * (dev->gck_param->imckdiv + 1);
457
458 /* Fist change the PLL audio clock frequency ... */
459 ret = clk_set_rate(dev->aclk, aclk_rate);
460 if (ret)
461 return ret;
462
463 /*
464 * ... then set the PMC generated clock rate to the very same frequency
465 * to set the gclk parent to aclk.
466 */
467 ret = clk_set_rate(dev->gclk, aclk_rate);
468 if (ret)
469 return ret;
470
471 /* Prepare and enable the PLL audio clock first ... */
472 ret = clk_prepare_enable(dev->aclk);
473 if (ret)
474 return ret;
475
476 /* ... then prepare and enable the PMC generated clock. */
477 ret = clk_prepare_enable(dev->gclk);
478 if (ret)
479 return ret;
480
481 /* Update the Mode Register to generate the I2S Master Clock. */
482 mr |= ATMEL_I2SC_MR_IMCKDIV(dev->gck_param->imckdiv);
483 mr |= ATMEL_I2SC_MR_IMCKFS(dev->gck_param->imckfs);
484 mr |= ATMEL_I2SC_MR_IMCKMODE_I2SMCK;
485 ret = regmap_update_bits(dev->regmap, ATMEL_I2SC_MR, mr_mask, mr);
486 if (ret)
487 return ret;
488
489 /* Finally enable the I2S Master Clock generator. */
490 return regmap_write(dev->regmap, ATMEL_I2SC_CR,
491 ATMEL_I2SC_CR_CKEN);
492}
493
494static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
495 struct snd_soc_dai *dai)
496{
497 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
498 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
499 bool is_master, mck_enabled;
500 unsigned int cr, mr;
501 int err;
502
503 switch (cmd) {
504 case SNDRV_PCM_TRIGGER_START:
505 case SNDRV_PCM_TRIGGER_RESUME:
506 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
507 cr = is_playback ? ATMEL_I2SC_CR_TXEN : ATMEL_I2SC_CR_RXEN;
508 mck_enabled = true;
509 break;
510 case SNDRV_PCM_TRIGGER_STOP:
511 case SNDRV_PCM_TRIGGER_SUSPEND:
512 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
513 cr = is_playback ? ATMEL_I2SC_CR_TXDIS : ATMEL_I2SC_CR_RXDIS;
514 mck_enabled = false;
515 break;
516 default:
517 return -EINVAL;
518 }
519
520 /* Read the Mode Register to retrieve the master/slave state. */
521 err = regmap_read(dev->regmap, ATMEL_I2SC_MR, &mr);
522 if (err)
523 return err;
524 is_master = (mr & ATMEL_I2SC_MR_MODE_MASK) == ATMEL_I2SC_MR_MODE_MASTER;
525
526 /* If master starts, enable the audio clock. */
527 if (is_master && mck_enabled)
528 err = atmel_i2s_switch_mck_generator(dev, true);
529 if (err)
530 return err;
531
532 err = regmap_write(dev->regmap, ATMEL_I2SC_CR, cr);
533 if (err)
534 return err;
535
536 /* If master stops, disable the audio clock. */
537 if (is_master && !mck_enabled)
538 err = atmel_i2s_switch_mck_generator(dev, false);
539
540 return err;
541}
542
543static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
544 .prepare = atmel_i2s_prepare,
545 .trigger = atmel_i2s_trigger,
546 .hw_params = atmel_i2s_hw_params,
547 .set_fmt = atmel_i2s_set_dai_fmt,
548};
549
550static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)
551{
552 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
553
554 snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture);
555 return 0;
556}
557
558static struct snd_soc_dai_driver atmel_i2s_dai = {
559 .probe = atmel_i2s_dai_probe,
560 .playback = {
561 .channels_min = 1,
562 .channels_max = 2,
563 .rates = ATMEL_I2S_RATES,
564 .formats = ATMEL_I2S_FORMATS,
565 },
566 .capture = {
567 .channels_min = 1,
568 .channels_max = 2,
569 .rates = ATMEL_I2S_RATES,
570 .formats = ATMEL_I2S_FORMATS,
571 },
572 .ops = &atmel_i2s_dai_ops,
573 .symmetric_rates = 1,
574};
575
576static const struct snd_soc_component_driver atmel_i2s_component = {
577 .name = "atmel-i2s",
578};
579
580static int atmel_i2s_sama5d2_mck_init(struct atmel_i2s_dev *dev,
581 struct device_node *np)
582{
583 struct clk *muxclk;
584 int err;
585
586 if (!dev->gclk)
587 return 0;
588
589 /* muxclk is optional, so we return error for probe defer only */
590 muxclk = devm_clk_get(dev->dev, "muxclk");
591 if (IS_ERR(muxclk)) {
592 err = PTR_ERR(muxclk);
593 if (err == -EPROBE_DEFER)
594 return -EPROBE_DEFER;
595 dev_warn(dev->dev,
596 "failed to get the I2S clock control: %d\n", err);
597 return 0;
598 }
599
600 return clk_set_parent(muxclk, dev->gclk);
601}
602
603static const struct atmel_i2s_caps atmel_i2s_sama5d2_caps = {
604 .mck_init = atmel_i2s_sama5d2_mck_init,
605};
606
607static const struct of_device_id atmel_i2s_dt_ids[] = {
608 {
609 .compatible = "atmel,sama5d2-i2s",
610 .data = (void *)&atmel_i2s_sama5d2_caps,
611 },
612
613 { /* sentinel */ }
614};
615
616MODULE_DEVICE_TABLE(of, atmel_i2s_dt_ids);
617
618static int atmel_i2s_probe(struct platform_device *pdev)
619{
620 struct device_node *np = pdev->dev.of_node;
621 const struct of_device_id *match;
622 struct atmel_i2s_dev *dev;
623 struct resource *mem;
624 struct regmap *regmap;
625 void __iomem *base;
626 int irq;
627 int err = -ENXIO;
628 unsigned int pcm_flags = 0;
629 unsigned int version;
630
631 /* Get memory for driver data. */
632 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
633 if (!dev)
634 return -ENOMEM;
635
636 /* Get hardware capabilities. */
637 match = of_match_node(atmel_i2s_dt_ids, np);
638 if (match)
639 dev->caps = match->data;
640
641 /* Map I/O registers. */
642 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
643 base = devm_ioremap_resource(&pdev->dev, mem);
644 if (IS_ERR(base))
645 return PTR_ERR(base);
646
647 regmap = devm_regmap_init_mmio(&pdev->dev, base,
648 &atmel_i2s_regmap_config);
649 if (IS_ERR(regmap))
650 return PTR_ERR(regmap);
651
652 /* Request IRQ. */
653 irq = platform_get_irq(pdev, 0);
654 if (irq < 0)
655 return irq;
656
657 err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0,
658 dev_name(&pdev->dev), dev);
659 if (err)
660 return err;
661
662 /* Get the peripheral clock. */
663 dev->pclk = devm_clk_get(&pdev->dev, "pclk");
664 if (IS_ERR(dev->pclk)) {
665 err = PTR_ERR(dev->pclk);
666 dev_err(&pdev->dev,
667 "failed to get the peripheral clock: %d\n", err);
668 return err;
669 }
670
671 /* Get audio clocks to generate the I2S Master Clock (I2S_MCK) */
672 dev->aclk = devm_clk_get(&pdev->dev, "aclk");
673 dev->gclk = devm_clk_get(&pdev->dev, "gclk");
674 if (IS_ERR(dev->aclk) && IS_ERR(dev->gclk)) {
675 if (PTR_ERR(dev->aclk) == -EPROBE_DEFER ||
676 PTR_ERR(dev->gclk) == -EPROBE_DEFER)
677 return -EPROBE_DEFER;
678 /* Master Mode not supported */
679 dev->aclk = NULL;
680 dev->gclk = NULL;
681 } else if (IS_ERR(dev->gclk)) {
682 err = PTR_ERR(dev->gclk);
683 dev_err(&pdev->dev,
684 "failed to get the PMC generated clock: %d\n", err);
685 return err;
686 } else if (IS_ERR(dev->aclk)) {
687 err = PTR_ERR(dev->aclk);
688 dev_err(&pdev->dev,
689 "failed to get the PLL audio clock: %d\n", err);
690 return err;
691 }
692
693 dev->dev = &pdev->dev;
694 dev->regmap = regmap;
695 platform_set_drvdata(pdev, dev);
696
697 /* Do hardware specific settings to initialize I2S_MCK generator */
698 if (dev->caps && dev->caps->mck_init) {
699 err = dev->caps->mck_init(dev, np);
700 if (err)
701 return err;
702 }
703
704 /* Enable the peripheral clock. */
705 err = clk_prepare_enable(dev->pclk);
706 if (err)
707 return err;
708
709 /* Get IP version. */
710 regmap_read(dev->regmap, ATMEL_I2SC_VERSION, &version);
711 dev_info(&pdev->dev, "hw version: %#x\n", version);
712
713 /* Enable error interrupts. */
714 regmap_write(dev->regmap, ATMEL_I2SC_IER,
715 ATMEL_I2SC_INT_RXOR | ATMEL_I2SC_INT_TXUR);
716
717 err = devm_snd_soc_register_component(&pdev->dev,
718 &atmel_i2s_component,
719 &atmel_i2s_dai, 1);
720 if (err) {
721 dev_err(&pdev->dev, "failed to register DAI: %d\n", err);
722 clk_disable_unprepare(dev->pclk);
723 return err;
724 }
725
726 /* Prepare DMA config. */
727 dev->playback.addr = (dma_addr_t)mem->start + ATMEL_I2SC_THR;
728 dev->playback.maxburst = 1;
729 dev->capture.addr = (dma_addr_t)mem->start + ATMEL_I2SC_RHR;
730 dev->capture.maxburst = 1;
731
732 if (of_property_match_string(np, "dma-names", "rx-tx") == 0)
733 pcm_flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX;
734 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, pcm_flags);
735 if (err) {
736 dev_err(&pdev->dev, "failed to register PCM: %d\n", err);
737 clk_disable_unprepare(dev->pclk);
738 return err;
739 }
740
741 return 0;
742}
743
744static int atmel_i2s_remove(struct platform_device *pdev)
745{
746 struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
747
748 clk_disable_unprepare(dev->pclk);
749
750 return 0;
751}
752
753static struct platform_driver atmel_i2s_driver = {
754 .driver = {
755 .name = "atmel_i2s",
756 .of_match_table = of_match_ptr(atmel_i2s_dt_ids),
757 },
758 .probe = atmel_i2s_probe,
759 .remove = atmel_i2s_remove,
760};
761module_platform_driver(atmel_i2s_driver);
762
763MODULE_DESCRIPTION("Atmel I2S Controller driver");
764MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@atmel.com>");
765MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index a1e2c5682dcd..d3b69682d9c2 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -820,7 +820,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
820 if (ret < 0) { 820 if (ret < 0) {
821 printk(KERN_WARNING 821 printk(KERN_WARNING
822 "atmel_ssc_dai: request_irq failure\n"); 822 "atmel_ssc_dai: request_irq failure\n");
823 pr_debug("Atmel_ssc_dai: Stoping clock\n"); 823 pr_debug("Atmel_ssc_dai: Stopping clock\n");
824 clk_disable(ssc_p->ssc->clk); 824 clk_disable(ssc_p->ssc->clk);
825 return ret; 825 return ret;
826 } 826 }
@@ -1002,8 +1002,7 @@ static const struct snd_soc_component_driver atmel_ssc_component = {
1002 1002
1003static int asoc_ssc_init(struct device *dev) 1003static int asoc_ssc_init(struct device *dev)
1004{ 1004{
1005 struct platform_device *pdev = to_platform_device(dev); 1005 struct ssc_device *ssc = dev_get_drvdata(dev);
1006 struct ssc_device *ssc = platform_get_drvdata(pdev);
1007 int ret; 1006 int ret;
1008 1007
1009 ret = snd_soc_register_component(dev, &atmel_ssc_component, 1008 ret = snd_soc_register_component(dev, &atmel_ssc_component,
@@ -1033,8 +1032,7 @@ err:
1033 1032
1034static void asoc_ssc_exit(struct device *dev) 1033static void asoc_ssc_exit(struct device *dev)
1035{ 1034{
1036 struct platform_device *pdev = to_platform_device(dev); 1035 struct ssc_device *ssc = dev_get_drvdata(dev);
1037 struct ssc_device *ssc = platform_get_drvdata(pdev);
1038 1036
1039 if (ssc->pdata->use_dma) 1037 if (ssc->pdata->use_dma)
1040 atmel_pcm_dma_platform_unregister(dev); 1038 atmel_pcm_dma_platform_unregister(dev);
diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig
index edf367100ebd..02f50b7a966f 100644
--- a/sound/soc/bcm/Kconfig
+++ b/sound/soc/bcm/Kconfig
@@ -11,9 +11,8 @@ config SND_BCM2835_SOC_I2S
11config SND_SOC_CYGNUS 11config SND_SOC_CYGNUS
12 tristate "SoC platform audio for Broadcom Cygnus chips" 12 tristate "SoC platform audio for Broadcom Cygnus chips"
13 depends on ARCH_BCM_CYGNUS || COMPILE_TEST 13 depends on ARCH_BCM_CYGNUS || COMPILE_TEST
14 depends on HAS_DMA
15 help 14 help
16 Say Y if you want to add support for ASoC audio on Broadcom 15 Say Y if you want to add support for ASoC audio on Broadcom
17 Cygnus chips (bcm958300, bcm958305, bcm911360) 16 Cygnus chips (bcm958300, bcm958305, bcm911360)
18 17
19 If you don't know what to do here, say N. \ No newline at end of file 18 If you don't know what to do here, say N.
diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig
index c7cd60f009e9..e09199124c36 100644
--- a/sound/soc/cirrus/Kconfig
+++ b/sound/soc/cirrus/Kconfig
@@ -9,6 +9,23 @@ config SND_EP93XX_SOC
9config SND_EP93XX_SOC_I2S 9config SND_EP93XX_SOC_I2S
10 tristate 10 tristate
11 11
12if SND_EP93XX_SOC_I2S
13
14config SND_EP93XX_SOC_I2S_WATCHDOG
15 bool "IRQ based underflow watchdog workaround"
16 default y
17 help
18 I2S controller on EP93xx seems to have undocumented HW issue.
19 Underflow of internal I2S controller FIFO could confuse the
20 state machine and the whole stream can be shifted by one byte
21 until I2S is disabled. This option enables IRQ based watchdog
22 which disables and re-enables I2S in case of underflow and
23 fills FIFO with zeroes.
24
25 If you are unsure how to answer this question, answer Y.
26
27endif # if SND_EP93XX_SOC_I2S
28
12config SND_EP93XX_SOC_AC97 29config SND_EP93XX_SOC_AC97
13 tristate 30 tristate
14 select AC97_BUS 31 select AC97_BUS
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index c53bd6f2c2d7..3d011abaa266 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -67,7 +67,7 @@ static struct snd_soc_dai_link edb93xx_dai = {
67 .cpu_dai_name = "ep93xx-i2s", 67 .cpu_dai_name = "ep93xx-i2s",
68 .codec_name = "spi0.0", 68 .codec_name = "spi0.0",
69 .codec_dai_name = "cs4271-hifi", 69 .codec_dai_name = "cs4271-hifi",
70 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | 70 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
71 SND_SOC_DAIFMT_CBS_CFS, 71 SND_SOC_DAIFMT_CBS_CFS,
72 .ops = &edb93xx_ops, 72 .ops = &edb93xx_ops,
73}; 73};
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 934f8aefdd90..0918c5da575a 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -35,8 +35,12 @@
35 35
36#define EP93XX_I2S_TXCLKCFG 0x00 36#define EP93XX_I2S_TXCLKCFG 0x00
37#define EP93XX_I2S_RXCLKCFG 0x04 37#define EP93XX_I2S_RXCLKCFG 0x04
38#define EP93XX_I2S_GLSTS 0x08
38#define EP93XX_I2S_GLCTRL 0x0C 39#define EP93XX_I2S_GLCTRL 0x0C
39 40
41#define EP93XX_I2S_I2STX0LFT 0x10
42#define EP93XX_I2S_I2STX0RT 0x14
43
40#define EP93XX_I2S_TXLINCTRLDATA 0x28 44#define EP93XX_I2S_TXLINCTRLDATA 0x28
41#define EP93XX_I2S_TXCTRL 0x2C 45#define EP93XX_I2S_TXCTRL 0x2C
42#define EP93XX_I2S_TXWRDLEN 0x30 46#define EP93XX_I2S_TXWRDLEN 0x30
@@ -51,7 +55,17 @@
51#define EP93XX_I2S_WRDLEN_24 (1 << 0) 55#define EP93XX_I2S_WRDLEN_24 (1 << 0)
52#define EP93XX_I2S_WRDLEN_32 (2 << 0) 56#define EP93XX_I2S_WRDLEN_32 (2 << 0)
53 57
54#define EP93XX_I2S_LINCTRLDATA_R_JUST (1 << 2) /* Right justify */ 58#define EP93XX_I2S_RXLINCTRLDATA_R_JUST BIT(1) /* Right justify */
59
60#define EP93XX_I2S_TXLINCTRLDATA_R_JUST BIT(2) /* Right justify */
61
62/*
63 * Transmit empty interrupt level select:
64 * 0 - Generate interrupt when FIFO is half empty
65 * 1 - Generate interrupt when FIFO is empty
66 */
67#define EP93XX_I2S_TXCTRL_TXEMPTY_LVL BIT(0)
68#define EP93XX_I2S_TXCTRL_TXUFIE BIT(1) /* Transmit interrupt enable */
55 69
56#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */ 70#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */
57#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */ 71#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */
@@ -59,6 +73,8 @@
59#define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */ 73#define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */
60#define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */ 74#define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */
61 75
76#define EP93XX_I2S_GLSTS_TX0_FIFO_FULL BIT(12)
77
62struct ep93xx_i2s_info { 78struct ep93xx_i2s_info {
63 struct clk *mclk; 79 struct clk *mclk;
64 struct clk *sclk; 80 struct clk *sclk;
@@ -96,7 +112,6 @@ static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info,
96static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream) 112static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
97{ 113{
98 unsigned base_reg; 114 unsigned base_reg;
99 int i;
100 115
101 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 && 116 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
102 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) { 117 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
@@ -109,27 +124,36 @@ static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
109 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1); 124 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
110 } 125 }
111 126
112 /* Enable fifos */ 127 /* Enable fifo */
113 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 128 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
114 base_reg = EP93XX_I2S_TX0EN; 129 base_reg = EP93XX_I2S_TX0EN;
115 else 130 else
116 base_reg = EP93XX_I2S_RX0EN; 131 base_reg = EP93XX_I2S_RX0EN;
117 for (i = 0; i < 3; i++) 132 ep93xx_i2s_write_reg(info, base_reg, 1);
118 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 1); 133
134 /* Enable TX IRQs (FIFO empty or underflow) */
135 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG) &&
136 stream == SNDRV_PCM_STREAM_PLAYBACK)
137 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCTRL,
138 EP93XX_I2S_TXCTRL_TXEMPTY_LVL |
139 EP93XX_I2S_TXCTRL_TXUFIE);
119} 140}
120 141
121static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) 142static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
122{ 143{
123 unsigned base_reg; 144 unsigned base_reg;
124 int i;
125 145
126 /* Disable fifos */ 146 /* Disable IRQs */
147 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG) &&
148 stream == SNDRV_PCM_STREAM_PLAYBACK)
149 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCTRL, 0);
150
151 /* Disable fifo */
127 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 152 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
128 base_reg = EP93XX_I2S_TX0EN; 153 base_reg = EP93XX_I2S_TX0EN;
129 else 154 else
130 base_reg = EP93XX_I2S_RX0EN; 155 base_reg = EP93XX_I2S_RX0EN;
131 for (i = 0; i < 3; i++) 156 ep93xx_i2s_write_reg(info, base_reg, 0);
132 ep93xx_i2s_write_reg(info, base_reg + (i * 4), 0);
133 157
134 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 && 158 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
135 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) { 159 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
@@ -143,6 +167,37 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
143 } 167 }
144} 168}
145 169
170/*
171 * According to documentation I2S controller can handle underflow conditions
172 * just fine, but in reality the state machine is sometimes confused so that
173 * the whole stream is shifted by one byte. The watchdog below disables the TX
174 * FIFO, fills the buffer with zeroes and re-enables the FIFO. State machine
175 * is being reset and by filling the buffer we get some time before next
176 * underflow happens.
177 */
178static irqreturn_t ep93xx_i2s_interrupt(int irq, void *dev_id)
179{
180 struct ep93xx_i2s_info *info = dev_id;
181
182 /* Disable FIFO */
183 ep93xx_i2s_write_reg(info, EP93XX_I2S_TX0EN, 0);
184 /*
185 * Fill TX FIFO with zeroes, this way we can defer next IRQs as much as
186 * possible and get more time for DMA to catch up. Actually there are
187 * only 8 samples in this FIFO, so even on 8kHz maximum deferral here is
188 * 1ms.
189 */
190 while (!(ep93xx_i2s_read_reg(info, EP93XX_I2S_GLSTS) &
191 EP93XX_I2S_GLSTS_TX0_FIFO_FULL)) {
192 ep93xx_i2s_write_reg(info, EP93XX_I2S_I2STX0LFT, 0);
193 ep93xx_i2s_write_reg(info, EP93XX_I2S_I2STX0RT, 0);
194 }
195 /* Re-enable FIFO */
196 ep93xx_i2s_write_reg(info, EP93XX_I2S_TX0EN, 1);
197
198 return IRQ_HANDLED;
199}
200
146static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) 201static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)
147{ 202{
148 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); 203 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
@@ -170,25 +225,25 @@ static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
170 unsigned int fmt) 225 unsigned int fmt)
171{ 226{
172 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai); 227 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
173 unsigned int clk_cfg, lin_ctrl; 228 unsigned int clk_cfg;
229 unsigned int txlin_ctrl = 0;
230 unsigned int rxlin_ctrl = 0;
174 231
175 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG); 232 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
176 lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA);
177 233
178 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 234 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
179 case SND_SOC_DAIFMT_I2S: 235 case SND_SOC_DAIFMT_I2S:
180 clk_cfg |= EP93XX_I2S_CLKCFG_REL; 236 clk_cfg |= EP93XX_I2S_CLKCFG_REL;
181 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
182 break; 237 break;
183 238
184 case SND_SOC_DAIFMT_LEFT_J: 239 case SND_SOC_DAIFMT_LEFT_J:
185 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 240 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
186 lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
187 break; 241 break;
188 242
189 case SND_SOC_DAIFMT_RIGHT_J: 243 case SND_SOC_DAIFMT_RIGHT_J:
190 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 244 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
191 lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST; 245 rxlin_ctrl |= EP93XX_I2S_RXLINCTRLDATA_R_JUST;
246 txlin_ctrl |= EP93XX_I2S_TXLINCTRLDATA_R_JUST;
192 break; 247 break;
193 248
194 default: 249 default:
@@ -213,32 +268,32 @@ static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
213 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 268 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
214 case SND_SOC_DAIFMT_NB_NF: 269 case SND_SOC_DAIFMT_NB_NF:
215 /* Negative bit clock, lrclk low on left word */ 270 /* Negative bit clock, lrclk low on left word */
216 clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL); 271 clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS);
217 break; 272 break;
218 273
219 case SND_SOC_DAIFMT_NB_IF: 274 case SND_SOC_DAIFMT_NB_IF:
220 /* Negative bit clock, lrclk low on right word */ 275 /* Negative bit clock, lrclk low on right word */
221 clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP; 276 clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;
222 clk_cfg |= EP93XX_I2S_CLKCFG_REL; 277 clk_cfg |= EP93XX_I2S_CLKCFG_LRS;
223 break; 278 break;
224 279
225 case SND_SOC_DAIFMT_IB_NF: 280 case SND_SOC_DAIFMT_IB_NF:
226 /* Positive bit clock, lrclk low on left word */ 281 /* Positive bit clock, lrclk low on left word */
227 clk_cfg |= EP93XX_I2S_CLKCFG_CKP; 282 clk_cfg |= EP93XX_I2S_CLKCFG_CKP;
228 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL; 283 clk_cfg &= ~EP93XX_I2S_CLKCFG_LRS;
229 break; 284 break;
230 285
231 case SND_SOC_DAIFMT_IB_IF: 286 case SND_SOC_DAIFMT_IB_IF:
232 /* Positive bit clock, lrclk low on right word */ 287 /* Positive bit clock, lrclk low on right word */
233 clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL; 288 clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS;
234 break; 289 break;
235 } 290 }
236 291
237 /* Write new register values */ 292 /* Write new register values */
238 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg); 293 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);
239 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg); 294 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);
240 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl); 295 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, rxlin_ctrl);
241 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl); 296 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, txlin_ctrl);
242 return 0; 297 return 0;
243} 298}
244 299
@@ -392,6 +447,17 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
392 if (IS_ERR(info->regs)) 447 if (IS_ERR(info->regs))
393 return PTR_ERR(info->regs); 448 return PTR_ERR(info->regs);
394 449
450 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG)) {
451 int irq = platform_get_irq(pdev, 0);
452 if (irq <= 0)
453 return irq < 0 ? irq : -ENODEV;
454
455 err = devm_request_irq(&pdev->dev, irq, ep93xx_i2s_interrupt, 0,
456 pdev->name, info);
457 if (err)
458 return err;
459 }
460
395 info->mclk = clk_get(&pdev->dev, "mclk"); 461 info->mclk = clk_get(&pdev->dev, "mclk");
396 if (IS_ERR(info->mclk)) { 462 if (IS_ERR(info->mclk)) {
397 err = PTR_ERR(info->mclk); 463 err = PTR_ERR(info->mclk);
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 2334ec19e7eb..11ff7b2672b2 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -72,7 +72,7 @@ static struct snd_soc_dai_link snappercl15_dai = {
72 .codec_dai_name = "tlv320aic23-hifi", 72 .codec_dai_name = "tlv320aic23-hifi",
73 .codec_name = "tlv320aic23-codec.0-001a", 73 .codec_name = "tlv320aic23-codec.0-001a",
74 .platform_name = "ep93xx-i2s", 74 .platform_name = "ep93xx-i2s",
75 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | 75 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
76 SND_SOC_DAIFMT_CBS_CFS, 76 SND_SOC_DAIFMT_CBS_CFS,
77 .ops = &snappercl15_ops, 77 .ops = &snappercl15_ops,
78}; 78};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9548f63ca531..63cf62e9c9aa 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -106,6 +106,7 @@ config SND_SOC_ALL_CODECS
106 select SND_SOC_MAX9877 if I2C 106 select SND_SOC_MAX9877 if I2C
107 select SND_SOC_MC13783 if MFD_MC13XXX 107 select SND_SOC_MC13783 if MFD_MC13XXX
108 select SND_SOC_ML26124 if I2C 108 select SND_SOC_ML26124 if I2C
109 select SND_SOC_MT6351 if MTK_PMIC_WRAP
109 select SND_SOC_NAU8540 if I2C 110 select SND_SOC_NAU8540 if I2C
110 select SND_SOC_NAU8810 if I2C 111 select SND_SOC_NAU8810 if I2C
111 select SND_SOC_NAU8824 if I2C 112 select SND_SOC_NAU8824 if I2C
@@ -126,6 +127,7 @@ config SND_SOC_ALL_CODECS
126 select SND_SOC_RT274 if I2C 127 select SND_SOC_RT274 if I2C
127 select SND_SOC_RT286 if I2C 128 select SND_SOC_RT286 if I2C
128 select SND_SOC_RT298 if I2C 129 select SND_SOC_RT298 if I2C
130 select SND_SOC_RT1305 if I2C
129 select SND_SOC_RT5514 if I2C 131 select SND_SOC_RT5514 if I2C
130 select SND_SOC_RT5616 if I2C 132 select SND_SOC_RT5616 if I2C
131 select SND_SOC_RT5631 if I2C 133 select SND_SOC_RT5631 if I2C
@@ -136,12 +138,14 @@ config SND_SOC_ALL_CODECS
136 select SND_SOC_RT5660 if I2C 138 select SND_SOC_RT5660 if I2C
137 select SND_SOC_RT5663 if I2C 139 select SND_SOC_RT5663 if I2C
138 select SND_SOC_RT5665 if I2C 140 select SND_SOC_RT5665 if I2C
141 select SND_SOC_RT5668 if I2C
139 select SND_SOC_RT5670 if I2C 142 select SND_SOC_RT5670 if I2C
140 select SND_SOC_RT5677 if I2C && SPI_MASTER 143 select SND_SOC_RT5677 if I2C && SPI_MASTER
141 select SND_SOC_SGTL5000 if I2C 144 select SND_SOC_SGTL5000 if I2C
142 select SND_SOC_SI476X if MFD_SI476X_CORE 145 select SND_SOC_SI476X if MFD_SI476X_CORE
143 select SND_SOC_SIRF_AUDIO_CODEC 146 select SND_SOC_SIRF_AUDIO_CODEC
144 select SND_SOC_SPDIF 147 select SND_SOC_SPDIF
148 select SND_SOC_SSM2305
145 select SND_SOC_SSM2518 if I2C 149 select SND_SOC_SSM2518 if I2C
146 select SND_SOC_SSM2602_SPI if SPI_MASTER 150 select SND_SOC_SSM2602_SPI if SPI_MASTER
147 select SND_SOC_SSM2602_I2C if I2C 151 select SND_SOC_SSM2602_I2C if I2C
@@ -168,6 +172,7 @@ config SND_SOC_ALL_CODECS
168 select SND_SOC_TPA6130A2 if I2C 172 select SND_SOC_TPA6130A2 if I2C
169 select SND_SOC_TLV320DAC33 if I2C 173 select SND_SOC_TLV320DAC33 if I2C
170 select SND_SOC_TSCS42XX if I2C 174 select SND_SOC_TSCS42XX if I2C
175 select SND_SOC_TSCS454 if I2C
171 select SND_SOC_TS3A227E if I2C 176 select SND_SOC_TS3A227E if I2C
172 select SND_SOC_TWL4030 if TWL4030_CORE 177 select SND_SOC_TWL4030 if TWL4030_CORE
173 select SND_SOC_TWL6040 if TWL6040_CORE 178 select SND_SOC_TWL6040 if TWL6040_CORE
@@ -770,8 +775,10 @@ config SND_SOC_RL6231
770 default y if SND_SOC_RT5660=y 775 default y if SND_SOC_RT5660=y
771 default y if SND_SOC_RT5663=y 776 default y if SND_SOC_RT5663=y
772 default y if SND_SOC_RT5665=y 777 default y if SND_SOC_RT5665=y
778 default y if SND_SOC_RT5668=y
773 default y if SND_SOC_RT5670=y 779 default y if SND_SOC_RT5670=y
774 default y if SND_SOC_RT5677=y 780 default y if SND_SOC_RT5677=y
781 default y if SND_SOC_RT1305=y
775 default m if SND_SOC_RT5514=m 782 default m if SND_SOC_RT5514=m
776 default m if SND_SOC_RT5616=m 783 default m if SND_SOC_RT5616=m
777 default m if SND_SOC_RT5640=m 784 default m if SND_SOC_RT5640=m
@@ -781,8 +788,10 @@ config SND_SOC_RL6231
781 default m if SND_SOC_RT5660=m 788 default m if SND_SOC_RT5660=m
782 default m if SND_SOC_RT5663=m 789 default m if SND_SOC_RT5663=m
783 default m if SND_SOC_RT5665=m 790 default m if SND_SOC_RT5665=m
791 default m if SND_SOC_RT5668=m
784 default m if SND_SOC_RT5670=m 792 default m if SND_SOC_RT5670=m
785 default m if SND_SOC_RT5677=m 793 default m if SND_SOC_RT5677=m
794 default m if SND_SOC_RT1305=m
786 795
787config SND_SOC_RL6347A 796config SND_SOC_RL6347A
788 tristate 797 tristate
@@ -805,6 +814,9 @@ config SND_SOC_RT298
805 tristate 814 tristate
806 depends on I2C 815 depends on I2C
807 816
817config SND_SOC_RT1305
818 tristate
819
808config SND_SOC_RT5514 820config SND_SOC_RT5514
809 tristate 821 tristate
810 822
@@ -844,6 +856,9 @@ config SND_SOC_RT5663
844config SND_SOC_RT5665 856config SND_SOC_RT5665
845 tristate 857 tristate
846 858
859config SND_SOC_RT5668
860 tristate
861
847config SND_SOC_RT5670 862config SND_SOC_RT5670
848 tristate 863 tristate
849 864
@@ -883,6 +898,12 @@ config SND_SOC_SIRF_AUDIO_CODEC
883config SND_SOC_SPDIF 898config SND_SOC_SPDIF
884 tristate "S/PDIF CODEC" 899 tristate "S/PDIF CODEC"
885 900
901config SND_SOC_SSM2305
902 tristate "Analog Devices SSM2305 Class-D Amplifier"
903 help
904 Enable support for Analog Devices SSM2305 filterless
905 high-efficiency mono Class-D audio power amplifiers.
906
886config SND_SOC_SSM2518 907config SND_SOC_SSM2518
887 tristate 908 tristate
888 909
@@ -1011,6 +1032,13 @@ config SND_SOC_TSCS42XX
1011 help 1032 help
1012 Add support for Tempo Semiconductor's TSCS42xx audio CODEC. 1033 Add support for Tempo Semiconductor's TSCS42xx audio CODEC.
1013 1034
1035config SND_SOC_TSCS454
1036 tristate "Tempo Semiconductor TSCS454 CODEC"
1037 depends on I2C
1038 select REGMAP_I2C
1039 help
1040 Add support for Tempo Semiconductor's TSCS454 audio CODEC.
1041
1014config SND_SOC_TWL4030 1042config SND_SOC_TWL4030
1015 select MFD_TWL4030_AUDIO 1043 select MFD_TWL4030_AUDIO
1016 tristate 1044 tristate
@@ -1111,7 +1139,7 @@ config SND_SOC_WM8776
1111 depends on SND_SOC_I2C_AND_SPI 1139 depends on SND_SOC_I2C_AND_SPI
1112 1140
1113config SND_SOC_WM8782 1141config SND_SOC_WM8782
1114 tristate 1142 tristate "Wolfson Microelectronics WM8782 ADC"
1115 1143
1116config SND_SOC_WM8804 1144config SND_SOC_WM8804
1117 tristate 1145 tristate
@@ -1247,6 +1275,9 @@ config SND_SOC_MC13783
1247config SND_SOC_ML26124 1275config SND_SOC_ML26124
1248 tristate 1276 tristate
1249 1277
1278config SND_SOC_MT6351
1279 tristate "MediaTek MT6351 Codec"
1280
1250config SND_SOC_NAU8540 1281config SND_SOC_NAU8540
1251 tristate "Nuvoton Technology Corporation NAU85L40 CODEC" 1282 tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
1252 depends on I2C 1283 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index e849d1495308..e023fdf85221 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -102,6 +102,7 @@ snd-soc-mc13783-objs := mc13783.o
102snd-soc-ml26124-objs := ml26124.o 102snd-soc-ml26124-objs := ml26124.o
103snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o 103snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
104snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o 104snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
105snd-soc-mt6351-objs := mt6351.o
105snd-soc-nau8540-objs := nau8540.o 106snd-soc-nau8540-objs := nau8540.o
106snd-soc-nau8810-objs := nau8810.o 107snd-soc-nau8810-objs := nau8810.o
107snd-soc-nau8824-objs := nau8824.o 108snd-soc-nau8824-objs := nau8824.o
@@ -126,6 +127,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
126snd-soc-pcm512x-spi-objs := pcm512x-spi.o 127snd-soc-pcm512x-spi-objs := pcm512x-spi.o
127snd-soc-rl6231-objs := rl6231.o 128snd-soc-rl6231-objs := rl6231.o
128snd-soc-rl6347a-objs := rl6347a.o 129snd-soc-rl6347a-objs := rl6347a.o
130snd-soc-rt1305-objs := rt1305.o
129snd-soc-rt274-objs := rt274.o 131snd-soc-rt274-objs := rt274.o
130snd-soc-rt286-objs := rt286.o 132snd-soc-rt286-objs := rt286.o
131snd-soc-rt298-objs := rt298.o 133snd-soc-rt298-objs := rt298.o
@@ -140,6 +142,7 @@ snd-soc-rt5659-objs := rt5659.o
140snd-soc-rt5660-objs := rt5660.o 142snd-soc-rt5660-objs := rt5660.o
141snd-soc-rt5663-objs := rt5663.o 143snd-soc-rt5663-objs := rt5663.o
142snd-soc-rt5665-objs := rt5665.o 144snd-soc-rt5665-objs := rt5665.o
145snd-soc-rt5668-objs := rt5668.o
143snd-soc-rt5670-objs := rt5670.o 146snd-soc-rt5670-objs := rt5670.o
144snd-soc-rt5677-objs := rt5677.o 147snd-soc-rt5677-objs := rt5677.o
145snd-soc-rt5677-spi-objs := rt5677-spi.o 148snd-soc-rt5677-spi-objs := rt5677-spi.o
@@ -153,6 +156,7 @@ snd-soc-si476x-objs := si476x.o
153snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o 156snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
154snd-soc-spdif-tx-objs := spdif_transmitter.o 157snd-soc-spdif-tx-objs := spdif_transmitter.o
155snd-soc-spdif-rx-objs := spdif_receiver.o 158snd-soc-spdif-rx-objs := spdif_receiver.o
159snd-soc-ssm2305-objs := ssm2305.o
156snd-soc-ssm2518-objs := ssm2518.o 160snd-soc-ssm2518-objs := ssm2518.o
157snd-soc-ssm2602-objs := ssm2602.o 161snd-soc-ssm2602-objs := ssm2602.o
158snd-soc-ssm2602-spi-objs := ssm2602-spi.o 162snd-soc-ssm2602-spi-objs := ssm2602-spi.o
@@ -180,6 +184,7 @@ snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o
180snd-soc-tlv320aic3x-objs := tlv320aic3x.o 184snd-soc-tlv320aic3x-objs := tlv320aic3x.o
181snd-soc-tlv320dac33-objs := tlv320dac33.o 185snd-soc-tlv320dac33-objs := tlv320dac33.o
182snd-soc-tscs42xx-objs := tscs42xx.o 186snd-soc-tscs42xx-objs := tscs42xx.o
187snd-soc-tscs454-objs := tscs454.o
183snd-soc-ts3a227e-objs := ts3a227e.o 188snd-soc-ts3a227e-objs := ts3a227e.o
184snd-soc-twl4030-objs := twl4030.o 189snd-soc-twl4030-objs := twl4030.o
185snd-soc-twl6040-objs := twl6040.o 190snd-soc-twl6040-objs := twl6040.o
@@ -355,6 +360,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
355obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 360obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
356obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o 361obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
357obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o 362obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
363obj-$(CONFIG_SND_SOC_MT6351) += snd-soc-mt6351.o
358obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o 364obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
359obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o 365obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
360obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o 366obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o
@@ -379,6 +385,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
379obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 385obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
380obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o 386obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
381obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o 387obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
388obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o
382obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o 389obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o
383obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 390obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
384obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 391obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
@@ -394,6 +401,7 @@ obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
394obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o 401obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
395obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o 402obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
396obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o 403obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
404obj-$(CONFIG_SND_SOC_RT5668) += snd-soc-rt5668.o
397obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o 405obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
398obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o 406obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
399obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o 407obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
@@ -404,6 +412,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
404obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o 412obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
405obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o 413obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
406obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o 414obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
415obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o
407obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o 416obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
408obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 417obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
409obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o 418obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o
@@ -432,6 +441,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC32X4_SPI) += snd-soc-tlv320aic32x4-spi.o
432obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 441obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
433obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 442obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
434obj-$(CONFIG_SND_SOC_TSCS42XX) += snd-soc-tscs42xx.o 443obj-$(CONFIG_SND_SOC_TSCS42XX) += snd-soc-tscs42xx.o
444obj-$(CONFIG_SND_SOC_TSCS454) += snd-soc-tscs454.o
435obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o 445obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o
436obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 446obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
437obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 447obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 12bf24c26818..ae41edd1c406 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -843,6 +843,15 @@ int adau17x1_setup_firmware(struct snd_soc_component *component,
843 struct adau *adau = snd_soc_component_get_drvdata(component); 843 struct adau *adau = snd_soc_component_get_drvdata(component);
844 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 844 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
845 845
846 /* Check if sample rate is the same as before. If it is there is no
847 * point in performing the below steps as the call to
848 * sigmadsp_setup(...) will return directly when it finds the sample
849 * rate to be the same as before. By checking this we can prevent an
850 * audiable popping noise which occours when toggling DSP_RUN.
851 */
852 if (adau->sigmadsp->current_samplerate == rate)
853 return 0;
854
846 snd_soc_dapm_mutex_lock(dapm); 855 snd_soc_dapm_mutex_lock(dapm);
847 856
848 ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr); 857 ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
index a4a2cb171bdf..bd6226bde45f 100644
--- a/sound/soc/codecs/cs35l35.c
+++ b/sound/soc/codecs/cs35l35.c
@@ -1105,6 +1105,7 @@ static struct regmap_config cs35l35_regmap = {
1105 .readable_reg = cs35l35_readable_register, 1105 .readable_reg = cs35l35_readable_register,
1106 .precious_reg = cs35l35_precious_register, 1106 .precious_reg = cs35l35_precious_register,
1107 .cache_type = REGCACHE_RBTREE, 1107 .cache_type = REGCACHE_RBTREE,
1108 .use_single_rw = true,
1108}; 1109};
1109 1110
1110static irqreturn_t cs35l35_irq(int irq, void *data) 1111static irqreturn_t cs35l35_irq(int irq, void *data)
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 865f64c40b79..fb515aaa54fc 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1382,15 +1382,12 @@ static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};
1382 1382
1383static int max98088_get_channel(struct snd_soc_component *component, const char *name) 1383static int max98088_get_channel(struct snd_soc_component *component, const char *name)
1384{ 1384{
1385 int i; 1385 int ret;
1386 1386
1387 for (i = 0; i < ARRAY_SIZE(eq_mode_name); i++) 1387 ret = match_string(eq_mode_name, ARRAY_SIZE(eq_mode_name), name);
1388 if (strcmp(name, eq_mode_name[i]) == 0) 1388 if (ret < 0)
1389 return i; 1389 dev_err(component->dev, "Bad EQ channel name '%s'\n", name);
1390 1390 return ret;
1391 /* Shouldn't happen */
1392 dev_err(component->dev, "Bad EQ channel name '%s'\n", name);
1393 return -EINVAL;
1394} 1391}
1395 1392
1396static void max98088_setup_eq1(struct snd_soc_component *component) 1393static void max98088_setup_eq1(struct snd_soc_component *component)
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 6bf2d0ba864f..3b3a10da7f40 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1634,15 +1634,12 @@ static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"};
1634static int max98095_get_bq_channel(struct snd_soc_component *component, 1634static int max98095_get_bq_channel(struct snd_soc_component *component,
1635 const char *name) 1635 const char *name)
1636{ 1636{
1637 int i; 1637 int ret;
1638
1639 for (i = 0; i < ARRAY_SIZE(bq_mode_name); i++)
1640 if (strcmp(name, bq_mode_name[i]) == 0)
1641 return i;
1642 1638
1643 /* Shouldn't happen */ 1639 ret = match_string(bq_mode_name, ARRAY_SIZE(bq_mode_name), name);
1644 dev_err(component->dev, "Bad biquad channel name '%s'\n", name); 1640 if (ret < 0)
1645 return -EINVAL; 1641 dev_err(component->dev, "Bad biquad channel name '%s'\n", name);
1642 return ret;
1646} 1643}
1647 1644
1648static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, 1645static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c
index 5bbf889ad98e..de3d44e9199b 100644
--- a/sound/soc/codecs/max9860.c
+++ b/sound/soc/codecs/max9860.c
@@ -1,23 +1,14 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Driver for the MAX9860 Mono Audio Voice Codec 2//
3 * 3// Driver for the MAX9860 Mono Audio Voice Codec
4 * https://datasheets.maximintegrated.com/en/ds/MAX9860.pdf 4//
5 * 5// https://datasheets.maximintegrated.com/en/ds/MAX9860.pdf
6 * The driver does not support sidetone since the DVST register field is 6//
7 * backwards with the mute near the maximum level instead of the minimum. 7// The driver does not support sidetone since the DVST register field is
8 * 8// backwards with the mute near the maximum level instead of the minimum.
9 * Author: Peter Rosin <peda@axentia.s> 9//
10 * Copyright 2016 Axentia Technologies 10// Author: Peter Rosin <peda@axentia.s>
11 * 11// Copyright 2016 Axentia Technologies
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 */
21 12
22#include <linux/init.h> 13#include <linux/init.h>
23#include <linux/module.h> 14#include <linux/module.h>
@@ -443,7 +434,8 @@ static int max9860_hw_params(struct snd_pcm_substream *substream,
443 ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH, 434 ret = regmap_update_bits(max9860->regmap, MAX9860_AUDIOCLKHIGH,
444 MAX9860_PLL, MAX9860_PLL); 435 MAX9860_PLL, MAX9860_PLL);
445 if (ret) { 436 if (ret) {
446 dev_err(component->dev, "Failed to enable PLL: %d\n", ret); 437 dev_err(component->dev, "Failed to enable PLL: %d\n",
438 ret);
447 return ret; 439 return ret;
448 } 440 }
449 } 441 }
@@ -515,7 +507,8 @@ static int max9860_set_bias_level(struct snd_soc_component *component,
515 ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN, 507 ret = regmap_update_bits(max9860->regmap, MAX9860_PWRMAN,
516 MAX9860_SHDN, MAX9860_SHDN); 508 MAX9860_SHDN, MAX9860_SHDN);
517 if (ret) { 509 if (ret) {
518 dev_err(component->dev, "Failed to remove SHDN: %d\n", ret); 510 dev_err(component->dev, "Failed to remove SHDN: %d\n",
511 ret);
519 return ret; 512 return ret;
520 } 513 }
521 break; 514 break;
@@ -598,8 +591,7 @@ static const struct dev_pm_ops max9860_pm_ops = {
598 SET_RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL) 591 SET_RUNTIME_PM_OPS(max9860_suspend, max9860_resume, NULL)
599}; 592};
600 593
601static int max9860_probe(struct i2c_client *i2c, 594static int max9860_probe(struct i2c_client *i2c)
602 const struct i2c_device_id *id)
603{ 595{
604 struct device *dev = &i2c->dev; 596 struct device *dev = &i2c->dev;
605 struct max9860_priv *max9860; 597 struct max9860_priv *max9860;
@@ -698,7 +690,7 @@ static int max9860_probe(struct i2c_client *i2c,
698 pm_runtime_idle(dev); 690 pm_runtime_idle(dev);
699 691
700 ret = devm_snd_soc_register_component(dev, &max9860_component_driver, 692 ret = devm_snd_soc_register_component(dev, &max9860_component_driver,
701 &max9860_dai, 1); 693 &max9860_dai, 1);
702 if (ret) { 694 if (ret) {
703 dev_err(dev, "Failed to register CODEC: %d\n", ret); 695 dev_err(dev, "Failed to register CODEC: %d\n", ret);
704 goto err_pm; 696 goto err_pm;
@@ -736,7 +728,7 @@ static const struct of_device_id max9860_of_match[] = {
736MODULE_DEVICE_TABLE(of, max9860_of_match); 728MODULE_DEVICE_TABLE(of, max9860_of_match);
737 729
738static struct i2c_driver max9860_i2c_driver = { 730static struct i2c_driver max9860_i2c_driver = {
739 .probe = max9860_probe, 731 .probe_new = max9860_probe,
740 .remove = max9860_remove, 732 .remove = max9860_remove,
741 .id_table = max9860_i2c_id, 733 .id_table = max9860_i2c_id,
742 .driver = { 734 .driver = {
diff --git a/sound/soc/codecs/max9860.h b/sound/soc/codecs/max9860.h
index 22041bd67a7d..e07b905eaf50 100644
--- a/sound/soc/codecs/max9860.h
+++ b/sound/soc/codecs/max9860.h
@@ -1,17 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Driver for the MAX9860 Mono Audio Voice Codec 3 * Driver for the MAX9860 Mono Audio Voice Codec
3 * 4 *
4 * Author: Peter Rosin <peda@axentia.s> 5 * Author: Peter Rosin <peda@axentia.s>
5 * Copyright 2016 Axentia Technologies 6 * Copyright 2016 Axentia Technologies
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */ 7 */
16 8
17#ifndef _SND_SOC_MAX9860 9#ifndef _SND_SOC_MAX9860
diff --git a/sound/soc/codecs/mt6351.c b/sound/soc/codecs/mt6351.c
new file mode 100644
index 000000000000..f73dcd753584
--- /dev/null
+++ b/sound/soc/codecs/mt6351.c
@@ -0,0 +1,1505 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// mt6351.c -- mt6351 ALSA SoC audio codec driver
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/dma-mapping.h>
9#include <linux/platform_device.h>
10#include <linux/slab.h>
11#include <linux/module.h>
12#include <linux/of_device.h>
13#include <linux/delay.h>
14
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/soc.h>
18#include <sound/tlv.h>
19
20#include "mt6351.h"
21
22/* MT6351_TOP_CLKSQ */
23#define RG_CLKSQ_EN_AUD_BIT (0)
24
25/* MT6351_TOP_CKPDN_CON0 */
26#define RG_AUDNCP_CK_PDN_BIT (12)
27#define RG_AUDIF_CK_PDN_BIT (13)
28#define RG_AUD_CK_PDN_BIT (14)
29#define RG_ZCD13M_CK_PDN_BIT (15)
30
31/* MT6351_AUDDEC_ANA_CON0 */
32#define RG_AUDDACLPWRUP_VAUDP32_BIT (0)
33#define RG_AUDDACRPWRUP_VAUDP32_BIT (1)
34#define RG_AUD_DAC_PWR_UP_VA32_BIT (2)
35#define RG_AUD_DAC_PWL_UP_VA32_BIT (3)
36
37#define RG_AUDHSPWRUP_VAUDP32_BIT (4)
38
39#define RG_AUDHPLPWRUP_VAUDP32_BIT (5)
40#define RG_AUDHPRPWRUP_VAUDP32_BIT (6)
41
42#define RG_AUDHSMUXINPUTSEL_VAUDP32_SFT (7)
43#define RG_AUDHSMUXINPUTSEL_VAUDP32_MASK (0x3)
44
45#define RG_AUDHPLMUXINPUTSEL_VAUDP32_SFT (9)
46#define RG_AUDHPLMUXINPUTSEL_VAUDP32_MASK (0x3)
47
48#define RG_AUDHPRMUXINPUTSEL_VAUDP32_SFT (11)
49#define RG_AUDHPRMUXINPUTSEL_VAUDP32_MASK (0x3)
50
51#define RG_AUDHSSCDISABLE_VAUDP32 (13)
52#define RG_AUDHPLSCDISABLE_VAUDP32_BIT (14)
53#define RG_AUDHPRSCDISABLE_VAUDP32_BIT (15)
54
55/* MT6351_AUDDEC_ANA_CON1 */
56#define RG_HSOUTPUTSTBENH_VAUDP32_BIT (8)
57
58/* MT6351_AUDDEC_ANA_CON3 */
59#define RG_AUDLOLPWRUP_VAUDP32_BIT (2)
60
61#define RG_AUDLOLMUXINPUTSEL_VAUDP32_SFT (3)
62#define RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK (0x3)
63
64#define RG_AUDLOLSCDISABLE_VAUDP32_BIT (5)
65#define RG_LOOUTPUTSTBENH_VAUDP32_BIT (9)
66
67/* MT6351_AUDDEC_ANA_CON6 */
68#define RG_ABIDEC_RSVD0_VAUDP32_HPL_BIT (8)
69#define RG_ABIDEC_RSVD0_VAUDP32_HPR_BIT (9)
70#define RG_ABIDEC_RSVD0_VAUDP32_HS_BIT (10)
71#define RG_ABIDEC_RSVD0_VAUDP32_LOL_BIT (11)
72
73/* MT6351_AUDDEC_ANA_CON9 */
74#define RG_AUDIBIASPWRDN_VAUDP32_BIT (8)
75#define RG_RSTB_DECODER_VA32_BIT (9)
76#define RG_AUDGLB_PWRDN_VA32_BIT (12)
77
78#define RG_LCLDO_DEC_EN_VA32_BIT (13)
79#define RG_LCLDO_DEC_REMOTE_SENSE_VA18_BIT (15)
80/* MT6351_AUDDEC_ANA_CON10 */
81#define RG_NVREG_EN_VAUDP32_BIT (8)
82
83#define RG_AUDGLB_LP2_VOW_EN_VA32 10
84
85/* MT6351_AFE_UL_DL_CON0 */
86#define RG_AFE_ON_BIT (0)
87
88/* MT6351_AFE_DL_SRC2_CON0_L */
89#define RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT (0)
90
91/* MT6351_AFE_UL_SRC_CON0_L */
92#define UL_SRC_ON_TMP_CTL (0)
93
94/* MT6351_AFE_TOP_CON0 */
95#define RG_DL_SINE_ON_SFT (0)
96#define RG_DL_SINE_ON_MASK (0x1)
97
98#define RG_UL_SINE_ON_SFT (1)
99#define RG_UL_SINE_ON_MASK (0x1)
100
101/* MT6351_AUDIO_TOP_CON0 */
102#define AUD_TOP_PDN_RESERVED_BIT 0
103#define AUD_TOP_PWR_CLK_DIS_CTL_BIT 2
104#define AUD_TOP_PDN_ADC_CTL_BIT 5
105#define AUD_TOP_PDN_DAC_CTL_BIT 6
106#define AUD_TOP_PDN_AFE_CTL_BIT 7
107
108/* MT6351_AFE_SGEN_CFG0 */
109#define SGEN_C_MUTE_SW_CTL_BIT 6
110#define SGEN_C_DAC_EN_CTL_BIT 7
111
112/* MT6351_AFE_NCP_CFG0 */
113#define RG_NCP_ON_BIT 0
114
115/* MT6351_LDO_VUSB33_CON0 */
116#define RG_VUSB33_EN 1
117#define RG_VUSB33_ON_CTRL 3
118
119/* MT6351_LDO_VA18_CON0 */
120#define RG_VA18_EN 1
121#define RG_VA18_ON_CTRL 3
122
123/* MT6351_AUDENC_ANA_CON0 */
124#define RG_AUDPREAMPLON 0
125#define RG_AUDPREAMPLDCCEN 1
126#define RG_AUDPREAMPLDCPRECHARGE 2
127
128#define RG_AUDPREAMPLINPUTSEL_SFT (4)
129#define RG_AUDPREAMPLINPUTSEL_MASK (0x3)
130
131#define RG_AUDADCLPWRUP 12
132
133#define RG_AUDADCLINPUTSEL_SFT (13)
134#define RG_AUDADCLINPUTSEL_MASK (0x3)
135
136/* MT6351_AUDENC_ANA_CON1 */
137#define RG_AUDPREAMPRON 0
138#define RG_AUDPREAMPRDCCEN 1
139#define RG_AUDPREAMPRDCPRECHARGE 2
140
141#define RG_AUDPREAMPRINPUTSEL_SFT (4)
142#define RG_AUDPREAMPRINPUTSEL_MASK (0x3)
143
144#define RG_AUDADCRPWRUP 12
145
146#define RG_AUDADCRINPUTSEL_SFT (13)
147#define RG_AUDADCRINPUTSEL_MASK (0x3)
148
149/* MT6351_AUDENC_ANA_CON3 */
150#define RG_AUDADCCLKRSTB 6
151
152/* MT6351_AUDENC_ANA_CON9 */
153#define RG_AUDPWDBMICBIAS0 0
154#define RG_AUDMICBIAS0VREF 4
155#define RG_AUDMICBIAS0LOWPEN 7
156
157#define RG_AUDPWDBMICBIAS2 8
158#define RG_AUDMICBIAS2VREF 12
159#define RG_AUDMICBIAS2LOWPEN 15
160
161/* MT6351_AUDENC_ANA_CON10 */
162#define RG_AUDPWDBMICBIAS1 0
163#define RG_AUDMICBIAS1DCSW1NEN 2
164#define RG_AUDMICBIAS1VREF 4
165#define RG_AUDMICBIAS1LOWPEN 7
166
167enum {
168 AUDIO_ANALOG_VOLUME_HSOUTL,
169 AUDIO_ANALOG_VOLUME_HSOUTR,
170 AUDIO_ANALOG_VOLUME_HPOUTL,
171 AUDIO_ANALOG_VOLUME_HPOUTR,
172 AUDIO_ANALOG_VOLUME_LINEOUTL,
173 AUDIO_ANALOG_VOLUME_LINEOUTR,
174 AUDIO_ANALOG_VOLUME_MICAMP1,
175 AUDIO_ANALOG_VOLUME_MICAMP2,
176 AUDIO_ANALOG_VOLUME_TYPE_MAX
177};
178
179/* Supply subseq */
180enum {
181 SUPPLY_SUBSEQ_SETTING,
182 SUPPLY_SUBSEQ_ENABLE,
183 SUPPLY_SUBSEQ_MICBIAS,
184};
185
186#define REG_STRIDE 2
187
188struct mt6351_priv {
189 struct device *dev;
190 struct regmap *regmap;
191
192 unsigned int dl_rate;
193 unsigned int ul_rate;
194
195 int ana_gain[AUDIO_ANALOG_VOLUME_TYPE_MAX];
196
197 int hp_en_counter;
198};
199
200static void set_hp_gain_zero(struct snd_soc_component *cmpnt)
201{
202 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON2,
203 0x1f << 7, 0x8 << 7);
204 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON2,
205 0x1f << 0, 0x8 << 0);
206}
207
208static unsigned int get_cap_reg_val(struct snd_soc_component *cmpnt,
209 unsigned int rate)
210{
211 switch (rate) {
212 case 8000:
213 return 0;
214 case 16000:
215 return 1;
216 case 32000:
217 return 2;
218 case 48000:
219 return 3;
220 case 96000:
221 return 4;
222 case 192000:
223 return 5;
224 default:
225 dev_warn(cmpnt->dev, "%s(), error rate %d, return 3",
226 __func__, rate);
227 return 3;
228 }
229}
230
231static unsigned int get_play_reg_val(struct snd_soc_component *cmpnt,
232 unsigned int rate)
233{
234 switch (rate) {
235 case 8000:
236 return 0;
237 case 11025:
238 return 1;
239 case 12000:
240 return 2;
241 case 16000:
242 return 3;
243 case 22050:
244 return 4;
245 case 24000:
246 return 5;
247 case 32000:
248 return 6;
249 case 44100:
250 return 7;
251 case 48000:
252 case 96000:
253 case 192000:
254 return 8;
255 default:
256 dev_warn(cmpnt->dev, "%s(), error rate %d, return 8",
257 __func__, rate);
258 return 8;
259 }
260}
261
262static int mt6351_codec_dai_hw_params(struct snd_pcm_substream *substream,
263 struct snd_pcm_hw_params *params,
264 struct snd_soc_dai *dai)
265{
266 struct snd_soc_component *cmpnt = dai->component;
267 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
268 unsigned int rate = params_rate(params);
269
270 dev_dbg(priv->dev, "%s(), substream->stream %d, rate %d\n",
271 __func__, substream->stream, rate);
272
273 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
274 priv->dl_rate = rate;
275 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
276 priv->ul_rate = rate;
277
278 return 0;
279}
280
281static const struct snd_soc_dai_ops mt6351_codec_dai_ops = {
282 .hw_params = mt6351_codec_dai_hw_params,
283};
284
285#define MT6351_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
286 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |\
287 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
288 SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |\
289 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\
290 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE)
291
292static struct snd_soc_dai_driver mt6351_dai_driver[] = {
293 {
294 .name = "mt6351-snd-codec-aif1",
295 .playback = {
296 .stream_name = "AIF1 Playback",
297 .channels_min = 1,
298 .channels_max = 2,
299 .rates = SNDRV_PCM_RATE_8000_48000 |
300 SNDRV_PCM_RATE_96000 |
301 SNDRV_PCM_RATE_192000,
302 .formats = MT6351_FORMATS,
303 },
304 .capture = {
305 .stream_name = "AIF1 Capture",
306 .channels_min = 1,
307 .channels_max = 2,
308 .rates = SNDRV_PCM_RATE_8000 |
309 SNDRV_PCM_RATE_16000 |
310 SNDRV_PCM_RATE_32000 |
311 SNDRV_PCM_RATE_48000 |
312 SNDRV_PCM_RATE_96000 |
313 SNDRV_PCM_RATE_192000,
314 .formats = MT6351_FORMATS,
315 },
316 .ops = &mt6351_codec_dai_ops,
317 },
318};
319
320enum {
321 HP_GAIN_SET_ZERO,
322 HP_GAIN_RESTORE,
323};
324
325static void hp_gain_ramp_set(struct snd_soc_component *cmpnt, int hp_gain_ctl)
326{
327 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
328 int idx, old_idx, offset, reg_idx;
329
330 if (hp_gain_ctl == HP_GAIN_SET_ZERO) {
331 idx = 8; /* 0dB */
332 old_idx = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];
333 } else {
334 idx = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];
335 old_idx = 8; /* 0dB */
336 }
337 dev_dbg(priv->dev, "%s(), idx %d, old_idx %d\n",
338 __func__, idx, old_idx);
339
340 if (idx > old_idx)
341 offset = idx - old_idx;
342 else
343 offset = old_idx - idx;
344
345 reg_idx = old_idx;
346
347 while (offset > 0) {
348 reg_idx = idx > old_idx ? reg_idx + 1 : reg_idx - 1;
349
350 /* check valid range, and set value */
351 if ((reg_idx >= 0 && reg_idx <= 0x12) || reg_idx == 0x1f) {
352 regmap_update_bits(cmpnt->regmap,
353 MT6351_ZCD_CON2,
354 0xf9f,
355 (reg_idx << 7) | reg_idx);
356 usleep_range(100, 120);
357 }
358 offset--;
359 }
360}
361
362static void hp_zcd_enable(struct snd_soc_component *cmpnt)
363{
364 /* Enable ZCD, for minimize pop noise */
365 /* when adjust gain during HP buffer on */
366 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x7 << 8, 0x1 << 8);
367 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x1 << 7, 0x0 << 7);
368
369 /* timeout, 1=5ms, 0=30ms */
370 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x1 << 6, 0x1 << 6);
371
372 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x3 << 4, 0x0 << 4);
373 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x7 << 1, 0x5 << 1);
374 regmap_update_bits(cmpnt->regmap, MT6351_ZCD_CON0, 0x1 << 0, 0x1 << 0);
375}
376
377static void hp_zcd_disable(struct snd_soc_component *cmpnt)
378{
379 regmap_write(cmpnt->regmap, MT6351_ZCD_CON0, 0x0000);
380}
381
382static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
383static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0);
384
385static const struct snd_kcontrol_new mt6351_snd_controls[] = {
386 /* dl pga gain */
387 SOC_DOUBLE_TLV("Headphone Volume",
388 MT6351_ZCD_CON2, 0, 7, 0x12, 1,
389 playback_tlv),
390 SOC_DOUBLE_TLV("Lineout Volume",
391 MT6351_ZCD_CON1, 0, 7, 0x12, 1,
392 playback_tlv),
393 SOC_SINGLE_TLV("Handset Volume",
394 MT6351_ZCD_CON3, 0, 0x12, 1,
395 playback_tlv),
396 /* ul pga gain */
397 SOC_DOUBLE_R_TLV("PGA Volume",
398 MT6351_AUDENC_ANA_CON0, MT6351_AUDENC_ANA_CON1,
399 8, 4, 0,
400 pga_tlv),
401};
402
403/* MUX */
404
405/* LOL MUX */
406static const char *const lo_in_mux_map[] = {
407 "Open", "Mute", "Playback", "Test Mode",
408};
409
410static int lo_in_mux_map_value[] = {
411 0x0, 0x1, 0x2, 0x3,
412};
413
414static SOC_VALUE_ENUM_SINGLE_DECL(lo_in_mux_map_enum,
415 MT6351_AUDDEC_ANA_CON3,
416 RG_AUDLOLMUXINPUTSEL_VAUDP32_SFT,
417 RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK,
418 lo_in_mux_map,
419 lo_in_mux_map_value);
420
421static const struct snd_kcontrol_new lo_in_mux_control =
422 SOC_DAPM_ENUM("In Select", lo_in_mux_map_enum);
423
424/*HP MUX */
425static const char *const hp_in_mux_map[] = {
426 "Open", "LoudSPK Playback", "Audio Playback", "Test Mode",
427};
428
429static int hp_in_mux_map_value[] = {
430 0x0, 0x1, 0x2, 0x3,
431};
432
433static SOC_VALUE_ENUM_SINGLE_DECL(hpl_in_mux_map_enum,
434 MT6351_AUDDEC_ANA_CON0,
435 RG_AUDHPLMUXINPUTSEL_VAUDP32_SFT,
436 RG_AUDHPLMUXINPUTSEL_VAUDP32_MASK,
437 hp_in_mux_map,
438 hp_in_mux_map_value);
439
440static const struct snd_kcontrol_new hpl_in_mux_control =
441 SOC_DAPM_ENUM("HPL Select", hpl_in_mux_map_enum);
442
443static SOC_VALUE_ENUM_SINGLE_DECL(hpr_in_mux_map_enum,
444 MT6351_AUDDEC_ANA_CON0,
445 RG_AUDHPRMUXINPUTSEL_VAUDP32_SFT,
446 RG_AUDHPRMUXINPUTSEL_VAUDP32_MASK,
447 hp_in_mux_map,
448 hp_in_mux_map_value);
449
450static const struct snd_kcontrol_new hpr_in_mux_control =
451 SOC_DAPM_ENUM("HPR Select", hpr_in_mux_map_enum);
452
453/* RCV MUX */
454static const char *const rcv_in_mux_map[] = {
455 "Open", "Mute", "Voice Playback", "Test Mode",
456};
457
458static int rcv_in_mux_map_value[] = {
459 0x0, 0x1, 0x2, 0x3,
460};
461
462static SOC_VALUE_ENUM_SINGLE_DECL(rcv_in_mux_map_enum,
463 MT6351_AUDDEC_ANA_CON0,
464 RG_AUDHSMUXINPUTSEL_VAUDP32_SFT,
465 RG_AUDHSMUXINPUTSEL_VAUDP32_MASK,
466 rcv_in_mux_map,
467 rcv_in_mux_map_value);
468
469static const struct snd_kcontrol_new rcv_in_mux_control =
470 SOC_DAPM_ENUM("RCV Select", rcv_in_mux_map_enum);
471
472/* DAC In MUX */
473static const char *const dac_in_mux_map[] = {
474 "Normal Path", "Sgen",
475};
476
477static int dac_in_mux_map_value[] = {
478 0x0, 0x1,
479};
480
481static SOC_VALUE_ENUM_SINGLE_DECL(dac_in_mux_map_enum,
482 MT6351_AFE_TOP_CON0,
483 RG_DL_SINE_ON_SFT,
484 RG_DL_SINE_ON_MASK,
485 dac_in_mux_map,
486 dac_in_mux_map_value);
487
488static const struct snd_kcontrol_new dac_in_mux_control =
489 SOC_DAPM_ENUM("DAC Select", dac_in_mux_map_enum);
490
491/* AIF Out MUX */
492static SOC_VALUE_ENUM_SINGLE_DECL(aif_out_mux_map_enum,
493 MT6351_AFE_TOP_CON0,
494 RG_UL_SINE_ON_SFT,
495 RG_UL_SINE_ON_MASK,
496 dac_in_mux_map,
497 dac_in_mux_map_value);
498
499static const struct snd_kcontrol_new aif_out_mux_control =
500 SOC_DAPM_ENUM("AIF Out Select", aif_out_mux_map_enum);
501
502/* ADC L MUX */
503static const char *const adc_left_mux_map[] = {
504 "Idle", "AIN0", "Left Preamplifier", "Idle_1",
505};
506
507static int adc_left_mux_map_value[] = {
508 0x0, 0x1, 0x2, 0x3,
509};
510
511static SOC_VALUE_ENUM_SINGLE_DECL(adc_left_mux_map_enum,
512 MT6351_AUDENC_ANA_CON0,
513 RG_AUDADCLINPUTSEL_SFT,
514 RG_AUDADCLINPUTSEL_MASK,
515 adc_left_mux_map,
516 adc_left_mux_map_value);
517
518static const struct snd_kcontrol_new adc_left_mux_control =
519 SOC_DAPM_ENUM("ADC L Select", adc_left_mux_map_enum);
520
521/* ADC R MUX */
522static const char *const adc_right_mux_map[] = {
523 "Idle", "AIN0", "Right Preamplifier", "Idle_1",
524};
525
526static int adc_right_mux_map_value[] = {
527 0x0, 0x1, 0x2, 0x3,
528};
529
530static SOC_VALUE_ENUM_SINGLE_DECL(adc_right_mux_map_enum,
531 MT6351_AUDENC_ANA_CON1,
532 RG_AUDADCRINPUTSEL_SFT,
533 RG_AUDADCRINPUTSEL_MASK,
534 adc_right_mux_map,
535 adc_right_mux_map_value);
536
537static const struct snd_kcontrol_new adc_right_mux_control =
538 SOC_DAPM_ENUM("ADC R Select", adc_right_mux_map_enum);
539
540/* PGA L MUX */
541static const char *const pga_left_mux_map[] = {
542 "None", "AIN0", "AIN1", "AIN2",
543};
544
545static int pga_left_mux_map_value[] = {
546 0x0, 0x1, 0x2, 0x3,
547};
548
549static SOC_VALUE_ENUM_SINGLE_DECL(pga_left_mux_map_enum,
550 MT6351_AUDENC_ANA_CON0,
551 RG_AUDPREAMPLINPUTSEL_SFT,
552 RG_AUDPREAMPLINPUTSEL_MASK,
553 pga_left_mux_map,
554 pga_left_mux_map_value);
555
556static const struct snd_kcontrol_new pga_left_mux_control =
557 SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum);
558
559/* PGA R MUX */
560static const char *const pga_right_mux_map[] = {
561 "None", "AIN0", "AIN3", "AIN2",
562};
563
564static int pga_right_mux_map_value[] = {
565 0x0, 0x1, 0x2, 0x3,
566};
567
568static SOC_VALUE_ENUM_SINGLE_DECL(pga_right_mux_map_enum,
569 MT6351_AUDENC_ANA_CON1,
570 RG_AUDPREAMPRINPUTSEL_SFT,
571 RG_AUDPREAMPRINPUTSEL_MASK,
572 pga_right_mux_map,
573 pga_right_mux_map_value);
574
575static const struct snd_kcontrol_new pga_right_mux_control =
576 SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum);
577
578static int mt_reg_set_clr_event(struct snd_soc_dapm_widget *w,
579 struct snd_kcontrol *kcontrol,
580 int event)
581{
582 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
583
584 switch (event) {
585 case SND_SOC_DAPM_POST_PMU:
586 if (w->on_val) {
587 /* SET REG */
588 regmap_update_bits(cmpnt->regmap,
589 w->reg + REG_STRIDE,
590 0x1 << w->shift,
591 0x1 << w->shift);
592 } else {
593 /* CLR REG */
594 regmap_update_bits(cmpnt->regmap,
595 w->reg + REG_STRIDE * 2,
596 0x1 << w->shift,
597 0x1 << w->shift);
598 }
599 break;
600 case SND_SOC_DAPM_PRE_PMD:
601 if (w->off_val) {
602 /* SET REG */
603 regmap_update_bits(cmpnt->regmap,
604 w->reg + REG_STRIDE,
605 0x1 << w->shift,
606 0x1 << w->shift);
607 } else {
608 /* CLR REG */
609 regmap_update_bits(cmpnt->regmap,
610 w->reg + REG_STRIDE * 2,
611 0x1 << w->shift,
612 0x1 << w->shift);
613 }
614 break;
615 default:
616 break;
617 }
618
619 return 0;
620}
621
622static int mt_ncp_event(struct snd_soc_dapm_widget *w,
623 struct snd_kcontrol *kcontrol,
624 int event)
625{
626 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
627
628 switch (event) {
629 case SND_SOC_DAPM_PRE_PMU:
630 regmap_update_bits(cmpnt->regmap, MT6351_AFE_NCP_CFG1,
631 0xffff, 0x1515);
632 /* NCP: ck1 and ck2 clock frequecy adjust configure */
633 regmap_update_bits(cmpnt->regmap, MT6351_AFE_NCP_CFG0,
634 0xfffe, 0x8C00);
635 break;
636 case SND_SOC_DAPM_POST_PMU:
637 usleep_range(250, 270);
638 break;
639 default:
640 break;
641 }
642
643 return 0;
644}
645
646static int mt_sgen_event(struct snd_soc_dapm_widget *w,
647 struct snd_kcontrol *kcontrol,
648 int event)
649{
650 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
651
652 switch (event) {
653 case SND_SOC_DAPM_PRE_PMU:
654 regmap_update_bits(cmpnt->regmap, MT6351_AFE_SGEN_CFG0,
655 0xffef, 0x0008);
656 regmap_update_bits(cmpnt->regmap, MT6351_AFE_SGEN_CFG1,
657 0xffff, 0x0101);
658 break;
659 default:
660 break;
661 }
662
663 return 0;
664}
665
666static int mt_aif_in_event(struct snd_soc_dapm_widget *w,
667 struct snd_kcontrol *kcontrol,
668 int event)
669{
670 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
671 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
672
673 dev_dbg(priv->dev, "%s(), event 0x%x, rate %d\n",
674 __func__, event, priv->dl_rate);
675
676 switch (event) {
677 case SND_SOC_DAPM_PRE_PMU:
678 /* sdm audio fifo clock power on */
679 regmap_update_bits(cmpnt->regmap, MT6351_AFUNC_AUD_CON2,
680 0xffff, 0x0006);
681 /* scrambler clock on enable */
682 regmap_update_bits(cmpnt->regmap, MT6351_AFUNC_AUD_CON0,
683 0xffff, 0xC3A1);
684 /* sdm power on */
685 regmap_update_bits(cmpnt->regmap, MT6351_AFUNC_AUD_CON2,
686 0xffff, 0x0003);
687 /* sdm fifo enable */
688 regmap_update_bits(cmpnt->regmap, MT6351_AFUNC_AUD_CON2,
689 0xffff, 0x000B);
690 /* set attenuation gain */
691 regmap_update_bits(cmpnt->regmap, MT6351_AFE_DL_SDM_CON1,
692 0xffff, 0x001E);
693
694 regmap_write(cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG0,
695 (get_play_reg_val(cmpnt, priv->dl_rate) << 12) |
696 0x330);
697 regmap_write(cmpnt->regmap, MT6351_AFE_DL_SRC2_CON0_H,
698 (get_play_reg_val(cmpnt, priv->dl_rate) << 12) |
699 0x300);
700
701 regmap_update_bits(cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG2,
702 0x8000, 0x8000);
703 break;
704 default:
705 break;
706 }
707
708 return 0;
709}
710
711static int mt_hp_event(struct snd_soc_dapm_widget *w,
712 struct snd_kcontrol *kcontrol,
713 int event)
714{
715 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
716 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
717 int reg;
718
719 dev_dbg(priv->dev, "%s(), event 0x%x, hp_en_counter %d\n",
720 __func__, event, priv->hp_en_counter);
721
722 switch (event) {
723 case SND_SOC_DAPM_PRE_PMU:
724 priv->hp_en_counter++;
725 if (priv->hp_en_counter > 1)
726 break; /* already enabled, do nothing */
727 else if (priv->hp_en_counter <= 0)
728 dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n",
729 __func__,
730 priv->hp_en_counter);
731
732 hp_zcd_disable(cmpnt);
733
734 /* from yoyo HQA script */
735 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON6,
736 0x0700, 0x0700);
737
738 /* save target gain to restore after hardware open complete */
739 regmap_read(cmpnt->regmap, MT6351_ZCD_CON2, &reg);
740 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] = reg & 0x1f;
741 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] = (reg >> 7) & 0x1f;
742
743 /* Set HPR/HPL gain as minimum (~ -40dB) */
744 regmap_update_bits(cmpnt->regmap,
745 MT6351_ZCD_CON2, 0xffff, 0x0F9F);
746 /* Set HS gain as minimum (~ -40dB) */
747 regmap_update_bits(cmpnt->regmap,
748 MT6351_ZCD_CON3, 0xffff, 0x001F);
749 /* De_OSC of HP */
750 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON2,
751 0x0001, 0x0001);
752 /* enable output STBENH */
753 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON1,
754 0xffff, 0x2000);
755 /* De_OSC of voice, enable output STBENH */
756 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON1,
757 0xffff, 0x2100);
758 /* Enable voice driver */
759 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON0,
760 0x0010, 0xE090);
761 /* Enable pre-charge buffer */
762 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON1,
763 0xffff, 0x2140);
764
765 usleep_range(50, 60);
766
767 /* Apply digital DC compensation value to DAC */
768 set_hp_gain_zero(cmpnt);
769
770 /* Enable HPR/HPL */
771 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON1,
772 0xffff, 0x2100);
773 /* Disable pre-charge buffer */
774 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON1,
775 0xffff, 0x2000);
776 /* Disable De_OSC of voice */
777 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON0,
778 0x0010, 0xF4EF);
779 /* Disable voice buffer */
780
781 /* from yoyo HQ */
782 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON6,
783 0x0700, 0x0300);
784
785 /* Enable ZCD, for minimize pop noise */
786 /* when adjust gain during HP buffer on */
787 hp_zcd_enable(cmpnt);
788
789 /* apply volume setting */
790 hp_gain_ramp_set(cmpnt, HP_GAIN_RESTORE);
791
792 break;
793 case SND_SOC_DAPM_PRE_PMD:
794 priv->hp_en_counter--;
795 if (priv->hp_en_counter > 0)
796 break; /* still being used, don't close */
797 else if (priv->hp_en_counter < 0)
798 dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n",
799 __func__,
800 priv->hp_en_counter);
801
802 /* Disable AUD_ZCD */
803 hp_zcd_disable(cmpnt);
804
805 /* Set HPR/HPL gain as -1dB, step by step */
806 hp_gain_ramp_set(cmpnt, HP_GAIN_SET_ZERO);
807
808 set_hp_gain_zero(cmpnt);
809 break;
810 case SND_SOC_DAPM_POST_PMD:
811 if (priv->hp_en_counter > 0)
812 break; /* still being used, don't close */
813 else if (priv->hp_en_counter < 0)
814 dev_err(priv->dev, "%s(), hp_en_counter %d <= 0\n",
815 __func__,
816 priv->hp_en_counter);
817
818 /* reset*/
819 regmap_update_bits(cmpnt->regmap,
820 MT6351_AUDDEC_ANA_CON6,
821 0x0700,
822 0x0000);
823 /* De_OSC of HP */
824 regmap_update_bits(cmpnt->regmap,
825 MT6351_AUDDEC_ANA_CON2,
826 0x0001,
827 0x0000);
828
829 /* apply volume setting */
830 hp_gain_ramp_set(cmpnt, HP_GAIN_RESTORE);
831 break;
832 default:
833 break;
834 }
835
836 return 0;
837}
838
839static int mt_aif_out_event(struct snd_soc_dapm_widget *w,
840 struct snd_kcontrol *kcontrol,
841 int event)
842{
843 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
844 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
845
846 dev_dbg(priv->dev, "%s(), event 0x%x, rate %d\n",
847 __func__, event, priv->ul_rate);
848
849 switch (event) {
850 case SND_SOC_DAPM_PRE_PMU:
851 /* dcclk_div=11'b00100000011, dcclk_ref_ck_sel=2'b00 */
852 regmap_update_bits(cmpnt->regmap, MT6351_AFE_DCCLK_CFG0,
853 0xffff, 0x2062);
854 /* dcclk_pdn=1'b0 */
855 regmap_update_bits(cmpnt->regmap, MT6351_AFE_DCCLK_CFG0,
856 0xffff, 0x2060);
857 /* dcclk_gen_on=1'b1 */
858 regmap_update_bits(cmpnt->regmap, MT6351_AFE_DCCLK_CFG0,
859 0xffff, 0x2061);
860
861 /* UL sample rate and mode configure */
862 regmap_update_bits(cmpnt->regmap, MT6351_AFE_UL_SRC_CON0_H,
863 0x000E,
864 get_cap_reg_val(cmpnt, priv->ul_rate) << 1);
865
866 /* fixed 260k path for 8/16/32/48 */
867 if (priv->ul_rate <= 48000) {
868 /* anc ul path src on */
869 regmap_update_bits(cmpnt->regmap,
870 MT6351_AFE_HPANC_CFG0,
871 0x1 << 1,
872 0x1 << 1);
873 /* ANC clk pdn release */
874 regmap_update_bits(cmpnt->regmap,
875 MT6351_AFE_HPANC_CFG0,
876 0x1 << 0,
877 0x0 << 0);
878 }
879 break;
880 case SND_SOC_DAPM_PRE_PMD:
881 /* fixed 260k path for 8/16/32/48 */
882 if (priv->ul_rate <= 48000) {
883 /* anc ul path src on */
884 regmap_update_bits(cmpnt->regmap,
885 MT6351_AFE_HPANC_CFG0,
886 0x1 << 1,
887 0x0 << 1);
888 /* ANC clk pdn release */
889 regmap_update_bits(cmpnt->regmap,
890 MT6351_AFE_HPANC_CFG0,
891 0x1 << 0,
892 0x1 << 0);
893 }
894 break;
895 default:
896 break;
897 }
898
899 return 0;
900}
901
902static int mt_adc_clkgen_event(struct snd_soc_dapm_widget *w,
903 struct snd_kcontrol *kcontrol,
904 int event)
905{
906 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
907
908 switch (event) {
909 case SND_SOC_DAPM_PRE_PMU:
910 /* Audio ADC clock gen. mode: 00_divided by 2 (Normal) */
911 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON3,
912 0x3 << 4, 0x0);
913 break;
914 case SND_SOC_DAPM_POST_PMU:
915 /* ADC CLK from: 00_13MHz from CLKSQ (Default) */
916 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON3,
917 0x3 << 2, 0x0);
918 break;
919 default:
920 break;
921 }
922 return 0;
923}
924
925static int mt_pga_left_event(struct snd_soc_dapm_widget *w,
926 struct snd_kcontrol *kcontrol,
927 int event)
928{
929 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
930
931 switch (event) {
932 case SND_SOC_DAPM_PRE_PMU:
933 /* Audio L PGA precharge on */
934 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON0,
935 0x3 << RG_AUDPREAMPLDCPRECHARGE,
936 0x1 << RG_AUDPREAMPLDCPRECHARGE);
937 /* Audio L PGA mode: 1_DCC */
938 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON0,
939 0x3 << RG_AUDPREAMPLDCCEN,
940 0x1 << RG_AUDPREAMPLDCCEN);
941 break;
942 case SND_SOC_DAPM_POST_PMU:
943 usleep_range(100, 120);
944 /* Audio L PGA precharge off */
945 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON0,
946 0x3 << RG_AUDPREAMPLDCPRECHARGE,
947 0x0 << RG_AUDPREAMPLDCPRECHARGE);
948 break;
949 default:
950 break;
951 }
952 return 0;
953}
954
955static int mt_pga_right_event(struct snd_soc_dapm_widget *w,
956 struct snd_kcontrol *kcontrol,
957 int event)
958{
959 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
960
961 switch (event) {
962 case SND_SOC_DAPM_PRE_PMU:
963 /* Audio R PGA precharge on */
964 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON1,
965 0x3 << RG_AUDPREAMPRDCPRECHARGE,
966 0x1 << RG_AUDPREAMPRDCPRECHARGE);
967 /* Audio R PGA mode: 1_DCC */
968 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON1,
969 0x3 << RG_AUDPREAMPRDCCEN,
970 0x1 << RG_AUDPREAMPRDCCEN);
971 break;
972 case SND_SOC_DAPM_POST_PMU:
973 usleep_range(100, 120);
974 /* Audio R PGA precharge off */
975 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON1,
976 0x3 << RG_AUDPREAMPRDCPRECHARGE,
977 0x0 << RG_AUDPREAMPRDCPRECHARGE);
978 break;
979 default:
980 break;
981 }
982 return 0;
983}
984
985static int mt_mic_bias_0_event(struct snd_soc_dapm_widget *w,
986 struct snd_kcontrol *kcontrol,
987 int event)
988{
989 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
990
991 switch (event) {
992 case SND_SOC_DAPM_PRE_PMU:
993 /* MIC Bias 0 LowPower: 0_Normal */
994 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
995 0x3 << RG_AUDMICBIAS0LOWPEN, 0x0);
996 /* MISBIAS0 = 1P9V */
997 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
998 0x7 << RG_AUDMICBIAS0VREF,
999 0x2 << RG_AUDMICBIAS0VREF);
1000 break;
1001 case SND_SOC_DAPM_POST_PMD:
1002 /* MISBIAS0 = 1P97 */
1003 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
1004 0x7 << RG_AUDMICBIAS0VREF,
1005 0x0 << RG_AUDMICBIAS0VREF);
1006 break;
1007 default:
1008 break;
1009 }
1010 return 0;
1011}
1012
1013static int mt_mic_bias_1_event(struct snd_soc_dapm_widget *w,
1014 struct snd_kcontrol *kcontrol,
1015 int event)
1016{
1017 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
1018
1019 switch (event) {
1020 case SND_SOC_DAPM_PRE_PMU:
1021 /* MIC Bias 1 LowPower: 0_Normal */
1022 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON10,
1023 0x3 << RG_AUDMICBIAS1LOWPEN, 0x0);
1024 /* MISBIAS1 = 2P7V */
1025 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON10,
1026 0x7 << RG_AUDMICBIAS1VREF,
1027 0x7 << RG_AUDMICBIAS1VREF);
1028 break;
1029 case SND_SOC_DAPM_POST_PMD:
1030 /* MISBIAS1 = 1P7V */
1031 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON10,
1032 0x7 << RG_AUDMICBIAS1VREF,
1033 0x0 << RG_AUDMICBIAS1VREF);
1034 break;
1035 default:
1036 break;
1037 }
1038 return 0;
1039}
1040
1041static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w,
1042 struct snd_kcontrol *kcontrol,
1043 int event)
1044{
1045 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
1046
1047 switch (event) {
1048 case SND_SOC_DAPM_PRE_PMU:
1049 /* MIC Bias 2 LowPower: 0_Normal */
1050 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
1051 0x3 << RG_AUDMICBIAS2LOWPEN, 0x0);
1052 /* MISBIAS2 = 1P9V */
1053 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
1054 0x7 << RG_AUDMICBIAS2VREF,
1055 0x2 << RG_AUDMICBIAS2VREF);
1056 break;
1057 case SND_SOC_DAPM_POST_PMD:
1058 /* MISBIAS2 = 1P97 */
1059 regmap_update_bits(cmpnt->regmap, MT6351_AUDENC_ANA_CON9,
1060 0x7 << RG_AUDMICBIAS2VREF,
1061 0x0 << RG_AUDMICBIAS2VREF);
1062 break;
1063 default:
1064 break;
1065 }
1066 return 0;
1067}
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 */
1075static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = {
1076 /* Digital Clock */
1077 SND_SOC_DAPM_SUPPLY("AUDIO_TOP_AFE_CTL", MT6351_AUDIO_TOP_CON0,
1078 AUD_TOP_PDN_AFE_CTL_BIT, 1, NULL, 0),
1079 SND_SOC_DAPM_SUPPLY("AUDIO_TOP_DAC_CTL", MT6351_AUDIO_TOP_CON0,
1080 AUD_TOP_PDN_DAC_CTL_BIT, 1, NULL, 0),
1081 SND_SOC_DAPM_SUPPLY("AUDIO_TOP_ADC_CTL", MT6351_AUDIO_TOP_CON0,
1082 AUD_TOP_PDN_ADC_CTL_BIT, 1, NULL, 0),
1083 SND_SOC_DAPM_SUPPLY("AUDIO_TOP_PWR_CLK", MT6351_AUDIO_TOP_CON0,
1084 AUD_TOP_PWR_CLK_DIS_CTL_BIT, 1, NULL, 0),
1085 SND_SOC_DAPM_SUPPLY("AUDIO_TOP_PDN_RESERVED", MT6351_AUDIO_TOP_CON0,
1086 AUD_TOP_PDN_RESERVED_BIT, 1, NULL, 0),
1087
1088 SND_SOC_DAPM_SUPPLY("NCP", MT6351_AFE_NCP_CFG0,
1089 RG_NCP_ON_BIT, 0,
1090 mt_ncp_event,
1091 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1092
1093 SND_SOC_DAPM_SUPPLY("DL Digital Clock", SND_SOC_NOPM,
1094 0, 0, NULL, 0),
1095
1096 /* Global Supply*/
1097 SND_SOC_DAPM_SUPPLY("AUDGLB", MT6351_AUDDEC_ANA_CON9,
1098 RG_AUDGLB_PWRDN_VA32_BIT, 1, NULL, 0),
1099 SND_SOC_DAPM_SUPPLY("CLKSQ Audio", MT6351_TOP_CLKSQ,
1100 RG_CLKSQ_EN_AUD_BIT, 0,
1101 mt_reg_set_clr_event,
1102 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1103 SND_SOC_DAPM_SUPPLY("ZCD13M_CK", MT6351_TOP_CKPDN_CON0,
1104 RG_ZCD13M_CK_PDN_BIT, 1,
1105 mt_reg_set_clr_event,
1106 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1107 SND_SOC_DAPM_SUPPLY("AUD_CK", MT6351_TOP_CKPDN_CON0,
1108 RG_AUD_CK_PDN_BIT, 1,
1109 mt_reg_set_clr_event,
1110 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1111 SND_SOC_DAPM_SUPPLY("AUDIF_CK", MT6351_TOP_CKPDN_CON0,
1112 RG_AUDIF_CK_PDN_BIT, 1,
1113 mt_reg_set_clr_event,
1114 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1115 SND_SOC_DAPM_SUPPLY("AUDNCP_CK", MT6351_TOP_CKPDN_CON0,
1116 RG_AUDNCP_CK_PDN_BIT, 1,
1117 mt_reg_set_clr_event,
1118 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1119
1120 SND_SOC_DAPM_SUPPLY("AFE_ON", MT6351_AFE_UL_DL_CON0, RG_AFE_ON_BIT, 0,
1121 NULL, 0),
1122
1123 /* AIF Rx*/
1124 SND_SOC_DAPM_AIF_IN_E("AIF_RX", "AIF1 Playback", 0,
1125 MT6351_AFE_DL_SRC2_CON0_L,
1126 RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT, 0,
1127 mt_aif_in_event, SND_SOC_DAPM_PRE_PMU),
1128
1129 /* DL Supply */
1130 SND_SOC_DAPM_SUPPLY("DL Power Supply", SND_SOC_NOPM,
1131 0, 0, NULL, 0),
1132 SND_SOC_DAPM_SUPPLY("NV Regulator", MT6351_AUDDEC_ANA_CON10,
1133 RG_NVREG_EN_VAUDP32_BIT, 0, NULL, 0),
1134 SND_SOC_DAPM_SUPPLY("AUD_CLK", MT6351_AUDDEC_ANA_CON9,
1135 RG_RSTB_DECODER_VA32_BIT, 0, NULL, 0),
1136 SND_SOC_DAPM_SUPPLY("IBIST", MT6351_AUDDEC_ANA_CON9,
1137 RG_AUDIBIASPWRDN_VAUDP32_BIT, 1, NULL, 0),
1138 SND_SOC_DAPM_SUPPLY("LDO", MT6351_AUDDEC_ANA_CON9,
1139 RG_LCLDO_DEC_EN_VA32_BIT, 0, NULL, 0),
1140 SND_SOC_DAPM_SUPPLY("LDO_REMOTE_SENSE", MT6351_AUDDEC_ANA_CON9,
1141 RG_LCLDO_DEC_REMOTE_SENSE_VA18_BIT, 0, NULL, 0),
1142
1143 /* DAC */
1144 SND_SOC_DAPM_MUX("DAC In Mux", SND_SOC_NOPM, 0, 0, &dac_in_mux_control),
1145
1146 SND_SOC_DAPM_DAC("DACL", NULL, MT6351_AUDDEC_ANA_CON0,
1147 RG_AUDDACLPWRUP_VAUDP32_BIT, 0),
1148 SND_SOC_DAPM_SUPPLY("DACL_BIASGEN", MT6351_AUDDEC_ANA_CON0,
1149 RG_AUD_DAC_PWL_UP_VA32_BIT, 0, NULL, 0),
1150
1151 SND_SOC_DAPM_DAC("DACR", NULL, MT6351_AUDDEC_ANA_CON0,
1152 RG_AUDDACRPWRUP_VAUDP32_BIT, 0),
1153 SND_SOC_DAPM_SUPPLY("DACR_BIASGEN", MT6351_AUDDEC_ANA_CON0,
1154 RG_AUD_DAC_PWR_UP_VA32_BIT, 0, NULL, 0),
1155 /* LOL */
1156 SND_SOC_DAPM_MUX("LOL Mux", SND_SOC_NOPM, 0, 0, &lo_in_mux_control),
1157
1158 SND_SOC_DAPM_SUPPLY("LO Stability Enh", MT6351_AUDDEC_ANA_CON3,
1159 RG_LOOUTPUTSTBENH_VAUDP32_BIT, 0, NULL, 0),
1160 SND_SOC_DAPM_SUPPLY("LOL Bias Gen", MT6351_AUDDEC_ANA_CON6,
1161 RG_ABIDEC_RSVD0_VAUDP32_LOL_BIT, 0, NULL, 0),
1162
1163 SND_SOC_DAPM_OUT_DRV("LOL Buffer", MT6351_AUDDEC_ANA_CON3,
1164 RG_AUDLOLPWRUP_VAUDP32_BIT, 0, NULL, 0),
1165
1166 /* Headphone */
1167 SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_in_mux_control),
1168 SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_in_mux_control),
1169
1170 SND_SOC_DAPM_OUT_DRV_E("HPL Power", MT6351_AUDDEC_ANA_CON0,
1171 RG_AUDHPLPWRUP_VAUDP32_BIT, 0, NULL, 0,
1172 mt_hp_event,
1173 SND_SOC_DAPM_PRE_PMU |
1174 SND_SOC_DAPM_PRE_PMD |
1175 SND_SOC_DAPM_POST_PMD),
1176 SND_SOC_DAPM_OUT_DRV_E("HPR Power", MT6351_AUDDEC_ANA_CON0,
1177 RG_AUDHPRPWRUP_VAUDP32_BIT, 0, NULL, 0,
1178 mt_hp_event,
1179 SND_SOC_DAPM_PRE_PMU |
1180 SND_SOC_DAPM_PRE_PMD |
1181 SND_SOC_DAPM_POST_PMD),
1182
1183 /* Receiver */
1184 SND_SOC_DAPM_MUX("RCV Mux", SND_SOC_NOPM, 0, 0, &rcv_in_mux_control),
1185
1186 SND_SOC_DAPM_SUPPLY("RCV Stability Enh", MT6351_AUDDEC_ANA_CON1,
1187 RG_HSOUTPUTSTBENH_VAUDP32_BIT, 0, NULL, 0),
1188 SND_SOC_DAPM_SUPPLY("RCV Bias Gen", MT6351_AUDDEC_ANA_CON6,
1189 RG_ABIDEC_RSVD0_VAUDP32_HS_BIT, 0, NULL, 0),
1190
1191 SND_SOC_DAPM_OUT_DRV("RCV Buffer", MT6351_AUDDEC_ANA_CON0,
1192 RG_AUDHSPWRUP_VAUDP32_BIT, 0, NULL, 0),
1193
1194 /* Outputs */
1195 SND_SOC_DAPM_OUTPUT("Receiver"),
1196 SND_SOC_DAPM_OUTPUT("Headphone L"),
1197 SND_SOC_DAPM_OUTPUT("Headphone R"),
1198 SND_SOC_DAPM_OUTPUT("LINEOUT L"),
1199
1200 /* SGEN */
1201 SND_SOC_DAPM_SUPPLY("SGEN DL Enable", MT6351_AFE_SGEN_CFG0,
1202 SGEN_C_DAC_EN_CTL_BIT, 0, NULL, 0),
1203 SND_SOC_DAPM_SUPPLY("SGEN MUTE", MT6351_AFE_SGEN_CFG0,
1204 SGEN_C_MUTE_SW_CTL_BIT, 1,
1205 mt_sgen_event, SND_SOC_DAPM_PRE_PMU),
1206 SND_SOC_DAPM_SUPPLY("SGEN DL SRC", MT6351_AFE_DL_SRC2_CON0_L,
1207 RG_DL_2_SRC_ON_TMP_CTL_PRE_BIT, 0, NULL, 0),
1208
1209 SND_SOC_DAPM_INPUT("SGEN DL"),
1210
1211 /* Uplinks */
1212 SND_SOC_DAPM_AIF_OUT_E("AIF1TX", "AIF1 Capture", 0,
1213 MT6351_AFE_UL_SRC_CON0_L,
1214 UL_SRC_ON_TMP_CTL, 0,
1215 mt_aif_out_event,
1216 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1217
1218 SND_SOC_DAPM_SUPPLY_S("VUSB33_LDO", SUPPLY_SUBSEQ_ENABLE,
1219 MT6351_LDO_VUSB33_CON0, RG_VUSB33_EN, 0,
1220 NULL, 0),
1221 SND_SOC_DAPM_SUPPLY_S("VUSB33_LDO_CTRL", SUPPLY_SUBSEQ_SETTING,
1222 MT6351_LDO_VUSB33_CON0, RG_VUSB33_ON_CTRL, 1,
1223 NULL, 0),
1224
1225 SND_SOC_DAPM_SUPPLY_S("VA18_LDO", SUPPLY_SUBSEQ_ENABLE,
1226 MT6351_LDO_VA18_CON0, RG_VA18_EN, 0, NULL, 0),
1227 SND_SOC_DAPM_SUPPLY_S("VA18_LDO_CTRL", SUPPLY_SUBSEQ_SETTING,
1228 MT6351_LDO_VA18_CON0, RG_VA18_ON_CTRL, 1,
1229 NULL, 0),
1230
1231 SND_SOC_DAPM_SUPPLY_S("ADC CLKGEN", SUPPLY_SUBSEQ_ENABLE,
1232 MT6351_AUDENC_ANA_CON3, RG_AUDADCCLKRSTB, 0,
1233 mt_adc_clkgen_event,
1234 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1235
1236 /* Uplinks MUX */
1237 SND_SOC_DAPM_MUX("AIF Out Mux", SND_SOC_NOPM, 0, 0,
1238 &aif_out_mux_control),
1239
1240 SND_SOC_DAPM_MUX("ADC L Mux", SND_SOC_NOPM, 0, 0,
1241 &adc_left_mux_control),
1242 SND_SOC_DAPM_MUX("ADC R Mux", SND_SOC_NOPM, 0, 0,
1243 &adc_right_mux_control),
1244
1245 SND_SOC_DAPM_ADC("ADC L", NULL,
1246 MT6351_AUDENC_ANA_CON0, RG_AUDADCLPWRUP, 0),
1247 SND_SOC_DAPM_ADC("ADC R", NULL,
1248 MT6351_AUDENC_ANA_CON1, RG_AUDADCRPWRUP, 0),
1249
1250 SND_SOC_DAPM_MUX("PGA L Mux", SND_SOC_NOPM, 0, 0,
1251 &pga_left_mux_control),
1252 SND_SOC_DAPM_MUX("PGA R Mux", SND_SOC_NOPM, 0, 0,
1253 &pga_right_mux_control),
1254
1255 SND_SOC_DAPM_PGA_E("PGA L", MT6351_AUDENC_ANA_CON0, RG_AUDPREAMPLON, 0,
1256 NULL, 0,
1257 mt_pga_left_event,
1258 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1259 SND_SOC_DAPM_PGA_E("PGA R", MT6351_AUDENC_ANA_CON1, RG_AUDPREAMPRON, 0,
1260 NULL, 0,
1261 mt_pga_right_event,
1262 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1263
1264 /* main mic mic bias */
1265 SND_SOC_DAPM_SUPPLY_S("Mic Bias 0", SUPPLY_SUBSEQ_MICBIAS,
1266 MT6351_AUDENC_ANA_CON9, RG_AUDPWDBMICBIAS0, 0,
1267 mt_mic_bias_0_event,
1268 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1269 /* ref mic mic bias */
1270 SND_SOC_DAPM_SUPPLY_S("Mic Bias 2", SUPPLY_SUBSEQ_MICBIAS,
1271 MT6351_AUDENC_ANA_CON9, RG_AUDPWDBMICBIAS2, 0,
1272 mt_mic_bias_2_event,
1273 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1274 /* headset mic1/2 mic bias */
1275 SND_SOC_DAPM_SUPPLY_S("Mic Bias 1", SUPPLY_SUBSEQ_MICBIAS,
1276 MT6351_AUDENC_ANA_CON10, RG_AUDPWDBMICBIAS1, 0,
1277 mt_mic_bias_1_event,
1278 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1279 SND_SOC_DAPM_SUPPLY_S("Mic Bias 1 DCC pull high", SUPPLY_SUBSEQ_MICBIAS,
1280 MT6351_AUDENC_ANA_CON10,
1281 RG_AUDMICBIAS1DCSW1NEN, 0,
1282 NULL, 0),
1283
1284 /* UL input */
1285 SND_SOC_DAPM_INPUT("AIN0"),
1286 SND_SOC_DAPM_INPUT("AIN1"),
1287 SND_SOC_DAPM_INPUT("AIN2"),
1288 SND_SOC_DAPM_INPUT("AIN3"),
1289};
1290
1291static const struct snd_soc_dapm_route mt6351_dapm_routes[] = {
1292 /* Capture */
1293 {"AIF1TX", NULL, "AIF Out Mux"},
1294 {"AIF1TX", NULL, "VUSB33_LDO"},
1295 {"VUSB33_LDO", NULL, "VUSB33_LDO_CTRL"},
1296 {"AIF1TX", NULL, "VA18_LDO"},
1297 {"VA18_LDO", NULL, "VA18_LDO_CTRL"},
1298
1299 {"AIF1TX", NULL, "AUDGLB"},
1300 {"AIF1TX", NULL, "CLKSQ Audio"},
1301
1302 {"AIF1TX", NULL, "AFE_ON"},
1303
1304 {"AIF1TX", NULL, "AUDIO_TOP_AFE_CTL"},
1305 {"AIF1TX", NULL, "AUDIO_TOP_ADC_CTL"},
1306 {"AIF1TX", NULL, "AUDIO_TOP_PWR_CLK"},
1307 {"AIF1TX", NULL, "AUDIO_TOP_PDN_RESERVED"},
1308
1309 {"AIF Out Mux", "Normal Path", "ADC L"},
1310 {"AIF Out Mux", "Normal Path", "ADC R"},
1311
1312 {"ADC L", NULL, "ADC L Mux"},
1313 {"ADC L", NULL, "AUD_CK"},
1314 {"ADC L", NULL, "AUDIF_CK"},
1315 {"ADC L", NULL, "ADC CLKGEN"},
1316 {"ADC R", NULL, "ADC R Mux"},
1317 {"ADC R", NULL, "AUD_CK"},
1318 {"ADC R", NULL, "AUDIF_CK"},
1319 {"ADC R", NULL, "ADC CLKGEN"},
1320
1321 {"ADC L Mux", "AIN0", "AIN0"},
1322 {"ADC L Mux", "Left Preamplifier", "PGA L"},
1323
1324 {"ADC R Mux", "AIN0", "AIN0"},
1325 {"ADC R Mux", "Right Preamplifier", "PGA R"},
1326
1327 {"PGA L", NULL, "PGA L Mux"},
1328 {"PGA R", NULL, "PGA R Mux"},
1329
1330 {"PGA L Mux", "AIN0", "AIN0"},
1331 {"PGA L Mux", "AIN1", "AIN1"},
1332 {"PGA L Mux", "AIN2", "AIN2"},
1333
1334 {"PGA R Mux", "AIN0", "AIN0"},
1335 {"PGA R Mux", "AIN3", "AIN3"},
1336 {"PGA R Mux", "AIN2", "AIN2"},
1337
1338 {"AIN0", NULL, "Mic Bias 0"},
1339 {"AIN2", NULL, "Mic Bias 2"},
1340
1341 {"AIN1", NULL, "Mic Bias 1"},
1342 {"AIN1", NULL, "Mic Bias 1 DCC pull high"},
1343
1344 /* DL Supply */
1345 {"DL Power Supply", NULL, "AUDGLB"},
1346 {"DL Power Supply", NULL, "CLKSQ Audio"},
1347 {"DL Power Supply", NULL, "ZCD13M_CK"},
1348 {"DL Power Supply", NULL, "AUD_CK"},
1349 {"DL Power Supply", NULL, "AUDIF_CK"},
1350 {"DL Power Supply", NULL, "AUDNCP_CK"},
1351
1352 {"DL Power Supply", NULL, "NV Regulator"},
1353 {"DL Power Supply", NULL, "AUD_CLK"},
1354 {"DL Power Supply", NULL, "IBIST"},
1355 {"DL Power Supply", NULL, "LDO"},
1356 {"LDO", NULL, "LDO_REMOTE_SENSE"},
1357
1358 /* DL Digital Supply */
1359 {"DL Digital Clock", NULL, "AUDIO_TOP_AFE_CTL"},
1360 {"DL Digital Clock", NULL, "AUDIO_TOP_DAC_CTL"},
1361 {"DL Digital Clock", NULL, "AUDIO_TOP_PWR_CLK"},
1362 {"DL Digital Clock", NULL, "AUDIO_TOP_PDN_RESERVED"},
1363 {"DL Digital Clock", NULL, "NCP"},
1364 {"DL Digital Clock", NULL, "AFE_ON"},
1365
1366 {"AIF_RX", NULL, "DL Digital Clock"},
1367
1368 /* DL Path */
1369 {"DAC In Mux", "Normal Path", "AIF_RX"},
1370
1371 {"DAC In Mux", "Sgen", "SGEN DL"},
1372 {"SGEN DL", NULL, "SGEN DL SRC"},
1373 {"SGEN DL", NULL, "SGEN MUTE"},
1374 {"SGEN DL", NULL, "SGEN DL Enable"},
1375 {"SGEN DL", NULL, "DL Digital Clock"},
1376
1377 {"DACL", NULL, "DAC In Mux"},
1378 {"DACL", NULL, "DL Power Supply"},
1379 {"DACL", NULL, "DACL_BIASGEN"},
1380
1381 {"DACR", NULL, "DAC In Mux"},
1382 {"DACR", NULL, "DL Power Supply"},
1383 {"DACR", NULL, "DACR_BIASGEN"},
1384
1385 {"LOL Mux", "Playback", "DACL"},
1386
1387 {"LOL Buffer", NULL, "LOL Mux"},
1388 {"LOL Buffer", NULL, "LO Stability Enh"},
1389 {"LOL Buffer", NULL, "LOL Bias Gen"},
1390
1391 {"LINEOUT L", NULL, "LOL Buffer"},
1392
1393 /* Headphone Path */
1394 {"HPL Mux", "Audio Playback", "DACL"},
1395 {"HPR Mux", "Audio Playback", "DACR"},
1396
1397 {"HPL Mux", "LoudSPK Playback", "DACL"},
1398 {"HPR Mux", "LoudSPK Playback", "DACR"},
1399
1400 {"HPL Power", NULL, "HPL Mux"},
1401 {"HPR Power", NULL, "HPR Mux"},
1402
1403 {"Headphone L", NULL, "HPL Power"},
1404 {"Headphone R", NULL, "HPR Power"},
1405
1406 /* Receiver Path */
1407 {"RCV Mux", "Voice Playback", "DACL"},
1408
1409 {"RCV Buffer", NULL, "RCV Mux"},
1410 {"RCV Buffer", NULL, "RCV Stability Enh"},
1411 {"RCV Buffer", NULL, "RCV Bias Gen"},
1412
1413 {"Receiver", NULL, "RCV Buffer"},
1414};
1415
1416static int mt6351_codec_init_reg(struct snd_soc_component *cmpnt)
1417{
1418 int ret = 0;
1419
1420 /* Disable CLKSQ 26MHz */
1421 regmap_update_bits(cmpnt->regmap, MT6351_TOP_CLKSQ, 0x0001, 0x0);
1422 /* disable AUDGLB */
1423 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON9,
1424 0x1000, 0x1000);
1425 /* Turn off AUDNCP_CLKDIV engine clock,Turn off AUD 26M */
1426 regmap_update_bits(cmpnt->regmap, MT6351_TOP_CKPDN_CON0_SET,
1427 0x3800, 0x3800);
1428 /* Disable HeadphoneL/HeadphoneR/voice short circuit protection */
1429 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON0,
1430 0xe000, 0xe000);
1431 /* [5] = 1, disable LO buffer left short circuit protection */
1432 regmap_update_bits(cmpnt->regmap, MT6351_AUDDEC_ANA_CON3,
1433 0x20, 0x20);
1434 /* Reverse the PMIC clock*/
1435 regmap_update_bits(cmpnt->regmap, MT6351_AFE_PMIC_NEWIF_CFG2,
1436 0x8000, 0x8000);
1437 return ret;
1438}
1439
1440static int mt6351_codec_probe(struct snd_soc_component *cmpnt)
1441{
1442 struct mt6351_priv *priv = snd_soc_component_get_drvdata(cmpnt);
1443
1444 snd_soc_component_init_regmap(cmpnt, priv->regmap);
1445
1446 mt6351_codec_init_reg(cmpnt);
1447 return 0;
1448}
1449
1450static const struct snd_soc_component_driver mt6351_soc_component_driver = {
1451 .probe = mt6351_codec_probe,
1452 .controls = mt6351_snd_controls,
1453 .num_controls = ARRAY_SIZE(mt6351_snd_controls),
1454 .dapm_widgets = mt6351_dapm_widgets,
1455 .num_dapm_widgets = ARRAY_SIZE(mt6351_dapm_widgets),
1456 .dapm_routes = mt6351_dapm_routes,
1457 .num_dapm_routes = ARRAY_SIZE(mt6351_dapm_routes),
1458};
1459
1460static int mt6351_codec_driver_probe(struct platform_device *pdev)
1461{
1462 struct mt6351_priv *priv;
1463
1464 priv = devm_kzalloc(&pdev->dev,
1465 sizeof(struct mt6351_priv),
1466 GFP_KERNEL);
1467 if (!priv)
1468 return -ENOMEM;
1469
1470 dev_set_drvdata(&pdev->dev, priv);
1471
1472 priv->dev = &pdev->dev;
1473
1474 priv->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1475 if (!priv->regmap)
1476 return -ENODEV;
1477
1478 dev_dbg(priv->dev, "%s(), dev name %s\n",
1479 __func__, dev_name(&pdev->dev));
1480
1481 return devm_snd_soc_register_component(&pdev->dev,
1482 &mt6351_soc_component_driver,
1483 mt6351_dai_driver,
1484 ARRAY_SIZE(mt6351_dai_driver));
1485}
1486
1487static const struct of_device_id mt6351_of_match[] = {
1488 {.compatible = "mediatek,mt6351-sound",},
1489 {}
1490};
1491
1492static struct platform_driver mt6351_codec_driver = {
1493 .driver = {
1494 .name = "mt6351-sound",
1495 .of_match_table = mt6351_of_match,
1496 },
1497 .probe = mt6351_codec_driver_probe,
1498};
1499
1500module_platform_driver(mt6351_codec_driver)
1501
1502/* Module information */
1503MODULE_DESCRIPTION("MT6351 ALSA SoC codec driver");
1504MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>");
1505MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/mt6351.h b/sound/soc/codecs/mt6351.h
new file mode 100644
index 000000000000..04b2ab694ec7
--- /dev/null
+++ b/sound/soc/codecs/mt6351.h
@@ -0,0 +1,105 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * mt6351.h -- mt6351 ALSA SoC audio codec driver
4 *
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7 */
8
9#ifndef __MT6351_H__
10#define __MT6351_H__
11
12#define MT6351_AFE_UL_DL_CON0 (0x2000 + 0x0000)
13#define MT6351_AFE_DL_SRC2_CON0_H (0x2000 + 0x0002)
14#define MT6351_AFE_DL_SRC2_CON0_L (0x2000 + 0x0004)
15#define MT6351_AFE_DL_SDM_CON0 (0x2000 + 0x0006)
16#define MT6351_AFE_DL_SDM_CON1 (0x2000 + 0x0008)
17#define MT6351_AFE_UL_SRC_CON0_H (0x2000 + 0x000a)
18#define MT6351_AFE_UL_SRC_CON0_L (0x2000 + 0x000c)
19#define MT6351_AFE_UL_SRC_CON1_H (0x2000 + 0x000e)
20#define MT6351_AFE_UL_SRC_CON1_L (0x2000 + 0x0010)
21#define MT6351_AFE_TOP_CON0 (0x2000 + 0x0012)
22#define MT6351_AUDIO_TOP_CON0 (0x2000 + 0x0014)
23#define MT6351_AFE_DL_SRC_MON0 (0x2000 + 0x0016)
24#define MT6351_AFE_DL_SDM_TEST0 (0x2000 + 0x0018)
25#define MT6351_AFE_MON_DEBUG0 (0x2000 + 0x001a)
26#define MT6351_AFUNC_AUD_CON0 (0x2000 + 0x001c)
27#define MT6351_AFUNC_AUD_CON1 (0x2000 + 0x001e)
28#define MT6351_AFUNC_AUD_CON2 (0x2000 + 0x0020)
29#define MT6351_AFUNC_AUD_CON3 (0x2000 + 0x0022)
30#define MT6351_AFUNC_AUD_CON4 (0x2000 + 0x0024)
31#define MT6351_AFUNC_AUD_MON0 (0x2000 + 0x0026)
32#define MT6351_AFUNC_AUD_MON1 (0x2000 + 0x0028)
33#define MT6351_AFE_UP8X_FIFO_CFG0 (0x2000 + 0x002c)
34#define MT6351_AFE_UP8X_FIFO_LOG_MON0 (0x2000 + 0x002e)
35#define MT6351_AFE_UP8X_FIFO_LOG_MON1 (0x2000 + 0x0030)
36#define MT6351_AFE_DL_DC_COMP_CFG0 (0x2000 + 0x0032)
37#define MT6351_AFE_DL_DC_COMP_CFG1 (0x2000 + 0x0034)
38#define MT6351_AFE_DL_DC_COMP_CFG2 (0x2000 + 0x0036)
39#define MT6351_AFE_PMIC_NEWIF_CFG0 (0x2000 + 0x0038)
40#define MT6351_AFE_PMIC_NEWIF_CFG1 (0x2000 + 0x003a)
41#define MT6351_AFE_PMIC_NEWIF_CFG2 (0x2000 + 0x003c)
42#define MT6351_AFE_PMIC_NEWIF_CFG3 (0x2000 + 0x003e)
43#define MT6351_AFE_SGEN_CFG0 (0x2000 + 0x0040)
44#define MT6351_AFE_SGEN_CFG1 (0x2000 + 0x0042)
45#define MT6351_AFE_ADDA2_UP8X_FIFO_LOG_MON0 (0x2000 + 0x004c)
46#define MT6351_AFE_ADDA2_UP8X_FIFO_LOG_MON1 (0x2000 + 0x004e)
47#define MT6351_AFE_ADDA2_PMIC_NEWIF_CFG0 (0x2000 + 0x0050)
48#define MT6351_AFE_ADDA2_PMIC_NEWIF_CFG1 (0x2000 + 0x0052)
49#define MT6351_AFE_ADDA2_PMIC_NEWIF_CFG2 (0x2000 + 0x0054)
50#define MT6351_AFE_DCCLK_CFG0 (0x2000 + 0x0090)
51#define MT6351_AFE_DCCLK_CFG1 (0x2000 + 0x0092)
52#define MT6351_AFE_HPANC_CFG0 (0x2000 + 0x0094)
53#define MT6351_AFE_NCP_CFG0 (0x2000 + 0x0096)
54#define MT6351_AFE_NCP_CFG1 (0x2000 + 0x0098)
55
56#define MT6351_TOP_CKPDN_CON0 0x023A
57#define MT6351_TOP_CKPDN_CON0_SET 0x023C
58#define MT6351_TOP_CKPDN_CON0_CLR 0x023E
59
60#define MT6351_TOP_CLKSQ 0x029A
61#define MT6351_TOP_CLKSQ_SET 0x029C
62#define MT6351_TOP_CLKSQ_CLR 0x029E
63
64#define MT6351_ZCD_CON0 0x0800
65#define MT6351_ZCD_CON1 0x0802
66#define MT6351_ZCD_CON2 0x0804
67#define MT6351_ZCD_CON3 0x0806
68#define MT6351_ZCD_CON4 0x0808
69#define MT6351_ZCD_CON5 0x080A
70
71#define MT6351_LDO_VA18_CON0 0x0A00
72#define MT6351_LDO_VA18_CON1 0x0A02
73#define MT6351_LDO_VUSB33_CON0 0x0A16
74#define MT6351_LDO_VUSB33_CON1 0x0A18
75
76#define MT6351_AUDDEC_ANA_CON0 0x0CF2
77#define MT6351_AUDDEC_ANA_CON1 0x0CF4
78#define MT6351_AUDDEC_ANA_CON2 0x0CF6
79#define MT6351_AUDDEC_ANA_CON3 0x0CF8
80#define MT6351_AUDDEC_ANA_CON4 0x0CFA
81#define MT6351_AUDDEC_ANA_CON5 0x0CFC
82#define MT6351_AUDDEC_ANA_CON6 0x0CFE
83#define MT6351_AUDDEC_ANA_CON7 0x0D00
84#define MT6351_AUDDEC_ANA_CON8 0x0D02
85#define MT6351_AUDDEC_ANA_CON9 0x0D04
86#define MT6351_AUDDEC_ANA_CON10 0x0D06
87
88#define MT6351_AUDENC_ANA_CON0 0x0D08
89#define MT6351_AUDENC_ANA_CON1 0x0D0A
90#define MT6351_AUDENC_ANA_CON2 0x0D0C
91#define MT6351_AUDENC_ANA_CON3 0x0D0E
92#define MT6351_AUDENC_ANA_CON4 0x0D10
93#define MT6351_AUDENC_ANA_CON5 0x0D12
94#define MT6351_AUDENC_ANA_CON6 0x0D14
95#define MT6351_AUDENC_ANA_CON7 0x0D16
96#define MT6351_AUDENC_ANA_CON8 0x0D18
97#define MT6351_AUDENC_ANA_CON9 0x0D1A
98#define MT6351_AUDENC_ANA_CON10 0x0D1C
99#define MT6351_AUDENC_ANA_CON11 0x0D1E
100#define MT6351_AUDENC_ANA_CON12 0x0D20
101#define MT6351_AUDENC_ANA_CON13 0x0D22
102#define MT6351_AUDENC_ANA_CON14 0x0D24
103#define MT6351_AUDENC_ANA_CON15 0x0D26
104#define MT6351_AUDENC_ANA_CON16 0x0D28
105#endif
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c
index ca2ba1c7bb9a..bfd74b86c9d2 100644
--- a/sound/soc/codecs/nau8810.c
+++ b/sound/soc/codecs/nau8810.c
@@ -373,9 +373,11 @@ static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
373}; 373};
374 374
375/* PGA Mute */ 375/* PGA Mute */
376static const struct snd_kcontrol_new nau8810_inpga_mute[] = { 376static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
377 SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN, 377 SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
378 NAU8810_PGAMT_SFT, 1, 0), 378 NAU8810_PGAMT_SFT, 1, 1),
379 SOC_DAPM_SINGLE("PMIC PGA Switch", NAU8810_REG_ADCBOOST,
380 NAU8810_PMICBSTGAIN_SFT, 0x7, 0),
379}; 381};
380 382
381/* Input PGA */ 383/* Input PGA */
@@ -386,11 +388,6 @@ static const struct snd_kcontrol_new nau8810_inpga[] = {
386 NAU8810_PMICPGA_SFT, 1, 0), 388 NAU8810_PMICPGA_SFT, 1, 0),
387}; 389};
388 390
389/* Mic Input boost vol */
390static const struct snd_kcontrol_new nau8810_mic_boost_controls =
391 SOC_DAPM_SINGLE("Mic Volume", NAU8810_REG_ADCBOOST,
392 NAU8810_PMICBSTGAIN_SFT, 0x7, 0);
393
394/* Loopback Switch */ 391/* Loopback Switch */
395static const struct snd_kcontrol_new nau8810_loopback = 392static const struct snd_kcontrol_new nau8810_loopback =
396 SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP, 393 SOC_DAPM_SINGLE("Switch", NAU8810_REG_COMP,
@@ -429,8 +426,8 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
429 NAU8810_PGA_EN_SFT, 0, nau8810_inpga, 426 NAU8810_PGA_EN_SFT, 0, nau8810_inpga,
430 ARRAY_SIZE(nau8810_inpga)), 427 ARRAY_SIZE(nau8810_inpga)),
431 SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2, 428 SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
432 NAU8810_BST_EN_SFT, 0, nau8810_inpga_mute, 429 NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls,
433 ARRAY_SIZE(nau8810_inpga_mute)), 430 ARRAY_SIZE(nau8810_pgaboost_mixer_controls)),
434 431
435 SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1, 432 SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
436 NAU8810_MICBIAS_EN_SFT, 0, NULL, 0), 433 NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
@@ -469,8 +466,8 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
469 /* Input Boost Stage */ 466 /* Input Boost Stage */
470 {"ADC", NULL, "Input Boost Stage"}, 467 {"ADC", NULL, "Input Boost Stage"},
471 {"ADC", NULL, "PLL", check_mclk_select_pll}, 468 {"ADC", NULL, "PLL", check_mclk_select_pll},
472 {"Input Boost Stage", NULL, "Input PGA"}, 469 {"Input Boost Stage", "PGA Mute Switch", "Input PGA"},
473 {"Input Boost Stage", NULL, "MICP"}, 470 {"Input Boost Stage", "PMIC PGA Switch", "MICP"},
474 471
475 /* Input PGA */ 472 /* Input PGA */
476 {"Input PGA", NULL, "Mic Bias"}, 473 {"Input PGA", NULL, "Mic Bias"},
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c
index 637e9527805f..6bd14453f06e 100644
--- a/sound/soc/codecs/nau8824.c
+++ b/sound/soc/codecs/nau8824.c
@@ -205,11 +205,11 @@ static int nau8824_sema_acquire(struct nau8824 *nau8824, long timeout)
205 if (timeout) { 205 if (timeout) {
206 ret = down_timeout(&nau8824->jd_sem, timeout); 206 ret = down_timeout(&nau8824->jd_sem, timeout);
207 if (ret < 0) 207 if (ret < 0)
208 dev_warn(nau8824->dev, "Acquire semaphone timeout\n"); 208 dev_warn(nau8824->dev, "Acquire semaphore timeout\n");
209 } else { 209 } else {
210 ret = down_interruptible(&nau8824->jd_sem); 210 ret = down_interruptible(&nau8824->jd_sem);
211 if (ret < 0) 211 if (ret < 0)
212 dev_warn(nau8824->dev, "Acquire semaphone fail\n"); 212 dev_warn(nau8824->dev, "Acquire semaphore fail\n");
213 } 213 }
214 214
215 return ret; 215 return ret;
@@ -409,6 +409,15 @@ static const struct snd_kcontrol_new nau8824_snd_controls[] = {
409 409
410 SOC_SINGLE("DACL LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 0, 1, 0), 410 SOC_SINGLE("DACL LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 0, 1, 0),
411 SOC_SINGLE("DACR LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 1, 1, 0), 411 SOC_SINGLE("DACR LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 1, 1, 0),
412
413 SOC_SINGLE("THD for key media",
414 NAU8824_REG_VDET_THRESHOLD_1, 8, 0xff, 0),
415 SOC_SINGLE("THD for key voice command",
416 NAU8824_REG_VDET_THRESHOLD_1, 0, 0xff, 0),
417 SOC_SINGLE("THD for key volume up",
418 NAU8824_REG_VDET_THRESHOLD_2, 8, 0xff, 0),
419 SOC_SINGLE("THD for key volume down",
420 NAU8824_REG_VDET_THRESHOLD_2, 0, 0xff, 0),
412}; 421};
413 422
414static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w, 423static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c
index 507ac9412d6c..21f15219b3ad 100644
--- a/sound/soc/codecs/pcm1789.c
+++ b/sound/soc/codecs/pcm1789.c
@@ -3,7 +3,7 @@
3// Copyright (C) 2018 Bootlin 3// Copyright (C) 2018 Bootlin
4// Mylène Josserand <mylene.josserand@bootlin.com> 4// Mylène Josserand <mylene.josserand@bootlin.com>
5 5
6#include <linux/gpio.h> 6#include <linux/gpio/consumer.h>
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/workqueue.h> 8#include <linux/workqueue.h>
9 9
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c
index 5f9c069569d5..0fe5ced841a3 100644
--- a/sound/soc/codecs/pcm512x-i2c.c
+++ b/sound/soc/codecs/pcm512x-i2c.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/acpi.h>
20 21
21#include "pcm512x.h" 22#include "pcm512x.h"
22 23
@@ -52,6 +53,7 @@ static const struct i2c_device_id pcm512x_i2c_id[] = {
52}; 53};
53MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id); 54MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
54 55
56#if defined(CONFIG_OF)
55static const struct of_device_id pcm512x_of_match[] = { 57static const struct of_device_id pcm512x_of_match[] = {
56 { .compatible = "ti,pcm5121", }, 58 { .compatible = "ti,pcm5121", },
57 { .compatible = "ti,pcm5122", }, 59 { .compatible = "ti,pcm5122", },
@@ -60,6 +62,18 @@ static const struct of_device_id pcm512x_of_match[] = {
60 { } 62 { }
61}; 63};
62MODULE_DEVICE_TABLE(of, pcm512x_of_match); 64MODULE_DEVICE_TABLE(of, pcm512x_of_match);
65#endif
66
67#ifdef CONFIG_ACPI
68static const struct acpi_device_id pcm512x_acpi_match[] = {
69 { "104C5121", 0 },
70 { "104C5122", 0 },
71 { "104C5141", 0 },
72 { "104C5142", 0 },
73 { },
74};
75MODULE_DEVICE_TABLE(acpi, pcm512x_acpi_match);
76#endif
63 77
64static struct i2c_driver pcm512x_i2c_driver = { 78static struct i2c_driver pcm512x_i2c_driver = {
65 .probe = pcm512x_i2c_probe, 79 .probe = pcm512x_i2c_probe,
@@ -67,7 +81,8 @@ static struct i2c_driver pcm512x_i2c_driver = {
67 .id_table = pcm512x_i2c_id, 81 .id_table = pcm512x_i2c_id,
68 .driver = { 82 .driver = {
69 .name = "pcm512x", 83 .name = "pcm512x",
70 .of_match_table = pcm512x_of_match, 84 .of_match_table = of_match_ptr(pcm512x_of_match),
85 .acpi_match_table = ACPI_PTR(pcm512x_acpi_match),
71 .pm = &pcm512x_pm_ops, 86 .pm = &pcm512x_pm_ops,
72 }, 87 },
73}; 88};
diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c
new file mode 100644
index 000000000000..f4c8c45f4010
--- /dev/null
+++ b/sound/soc/codecs/rt1305.c
@@ -0,0 +1,1191 @@
1/*
2 * rt1305.c -- RT1305 ALSA SoC amplifier component driver
3 *
4 * Copyright 2018 Realtek Semiconductor Corp.
5 * Author: Shuming Fan <shumingf@realtek.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
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/acpi.h>
18#include <linux/gpio.h>
19#include <linux/i2c.h>
20#include <linux/regmap.h>
21#include <linux/of_gpio.h>
22#include <linux/platform_device.h>
23#include <linux/firmware.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31
32#include "rl6231.h"
33#include "rt1305.h"
34
35
36#define RT1305_PR_RANGE_BASE (0xff + 1)
37#define RT1305_PR_SPACING 0x100
38
39#define RT1305_PR_BASE (RT1305_PR_RANGE_BASE + (0 * RT1305_PR_SPACING))
40
41
42static const struct regmap_range_cfg rt1305_ranges[] = {
43 {
44 .name = "PR",
45 .range_min = RT1305_PR_BASE,
46 .range_max = RT1305_PR_BASE + 0xff,
47 .selector_reg = RT1305_PRIV_INDEX,
48 .selector_mask = 0xff,
49 .selector_shift = 0x0,
50 .window_start = RT1305_PRIV_DATA,
51 .window_len = 0x1,
52 },
53};
54
55
56static const struct reg_sequence init_list[] = {
57
58 { RT1305_PR_BASE + 0xcf, 0x5548 },
59 { RT1305_PR_BASE + 0x5d, 0x0442 },
60 { RT1305_PR_BASE + 0xc1, 0x0320 },
61
62 { RT1305_POWER_STATUS, 0x0000 },
63
64 { RT1305_SPK_TEMP_PROTECTION_1, 0xd6de },
65 { RT1305_SPK_TEMP_PROTECTION_2, 0x0707 },
66 { RT1305_SPK_TEMP_PROTECTION_3, 0x4090 },
67
68 { RT1305_DAC_SET_1, 0xdfdf }, /* 4 ohm 2W */
69 { RT1305_ADC_SET_3, 0x0219 },
70 { RT1305_ADC_SET_1, 0x170f }, /* 0.2 ohm RSense*/
71
72};
73#define RT1305_INIT_REG_LEN ARRAY_SIZE(init_list)
74
75struct rt1305_priv {
76 struct snd_soc_component *component;
77 struct regmap *regmap;
78
79 int sysclk;
80 int sysclk_src;
81 int lrck;
82 int bclk;
83 int master;
84
85 int pll_src;
86 int pll_in;
87 int pll_out;
88};
89
90static const struct reg_default rt1305_reg[] = {
91
92 { 0x04, 0x0400 },
93 { 0x05, 0x0880 },
94 { 0x06, 0x0000 },
95 { 0x07, 0x3100 },
96 { 0x08, 0x8000 },
97 { 0x09, 0x0000 },
98 { 0x0a, 0x087e },
99 { 0x0b, 0x0020 },
100 { 0x0c, 0x0802 },
101 { 0x0d, 0x0020 },
102 { 0x10, 0x1d1d },
103 { 0x11, 0x1d1d },
104 { 0x12, 0xffff },
105 { 0x14, 0x000c },
106 { 0x16, 0x1717 },
107 { 0x17, 0x4000 },
108 { 0x18, 0x0019 },
109 { 0x20, 0x0000 },
110 { 0x22, 0x0000 },
111 { 0x24, 0x0000 },
112 { 0x26, 0x0000 },
113 { 0x28, 0x0000 },
114 { 0x2a, 0x4000 },
115 { 0x2b, 0x3000 },
116 { 0x2d, 0x6000 },
117 { 0x2e, 0x0000 },
118 { 0x2f, 0x8000 },
119 { 0x32, 0x0000 },
120 { 0x39, 0x0001 },
121 { 0x3a, 0x0000 },
122 { 0x3b, 0x1020 },
123 { 0x3c, 0x0000 },
124 { 0x3d, 0x0000 },
125 { 0x3e, 0x4c00 },
126 { 0x3f, 0x3000 },
127 { 0x40, 0x000c },
128 { 0x42, 0x0400 },
129 { 0x46, 0xc22c },
130 { 0x47, 0x0000 },
131 { 0x4b, 0x0000 },
132 { 0x4c, 0x0300 },
133 { 0x4f, 0xf000 },
134 { 0x50, 0xc200 },
135 { 0x51, 0x1f1f },
136 { 0x52, 0x01f0 },
137 { 0x53, 0x407f },
138 { 0x54, 0xffff },
139 { 0x58, 0x4005 },
140 { 0x5e, 0x0000 },
141 { 0x5f, 0x0000 },
142 { 0x60, 0xee13 },
143 { 0x62, 0x0000 },
144 { 0x63, 0x5f5f },
145 { 0x64, 0x0040 },
146 { 0x65, 0x4000 },
147 { 0x66, 0x4004 },
148 { 0x67, 0x0306 },
149 { 0x68, 0x8c04 },
150 { 0x69, 0xe021 },
151 { 0x6a, 0x0000 },
152 { 0x6c, 0xaaaa },
153 { 0x70, 0x0333 },
154 { 0x71, 0x3330 },
155 { 0x72, 0x3333 },
156 { 0x73, 0x3300 },
157 { 0x74, 0x0000 },
158 { 0x75, 0x0000 },
159 { 0x76, 0x0000 },
160 { 0x7a, 0x0003 },
161 { 0x7c, 0x10ec },
162 { 0x7e, 0x6251 },
163 { 0x80, 0x0800 },
164 { 0x81, 0x4000 },
165 { 0x82, 0x0000 },
166 { 0x90, 0x7a01 },
167 { 0x91, 0x8431 },
168 { 0x92, 0x0180 },
169 { 0x93, 0x0000 },
170 { 0x94, 0x0000 },
171 { 0x95, 0x0000 },
172 { 0x96, 0x0000 },
173 { 0x97, 0x0000 },
174 { 0x98, 0x0000 },
175 { 0x99, 0x0000 },
176 { 0x9a, 0x0000 },
177 { 0x9b, 0x0000 },
178 { 0x9c, 0x0000 },
179 { 0x9d, 0x0000 },
180 { 0x9e, 0x0000 },
181 { 0x9f, 0x0000 },
182 { 0xa0, 0x0000 },
183 { 0xb0, 0x8200 },
184 { 0xb1, 0x00ff },
185 { 0xb2, 0x0008 },
186 { 0xc0, 0x0200 },
187 { 0xc1, 0x0000 },
188 { 0xc2, 0x0000 },
189 { 0xc3, 0x0000 },
190 { 0xc4, 0x0000 },
191 { 0xc5, 0x0000 },
192 { 0xc6, 0x0000 },
193 { 0xc7, 0x0000 },
194 { 0xc8, 0x0000 },
195 { 0xc9, 0x0000 },
196 { 0xca, 0x0200 },
197 { 0xcb, 0x0000 },
198 { 0xcc, 0x0000 },
199 { 0xcd, 0x0000 },
200 { 0xce, 0x0000 },
201 { 0xcf, 0x0000 },
202 { 0xd0, 0x0000 },
203 { 0xd1, 0x0000 },
204 { 0xd2, 0x0000 },
205 { 0xd3, 0x0000 },
206 { 0xd4, 0x0200 },
207 { 0xd5, 0x0000 },
208 { 0xd6, 0x0000 },
209 { 0xd7, 0x0000 },
210 { 0xd8, 0x0000 },
211 { 0xd9, 0x0000 },
212 { 0xda, 0x0000 },
213 { 0xdb, 0x0000 },
214 { 0xdc, 0x0000 },
215 { 0xdd, 0x0000 },
216 { 0xde, 0x0200 },
217 { 0xdf, 0x0000 },
218 { 0xe0, 0x0000 },
219 { 0xe1, 0x0000 },
220 { 0xe2, 0x0000 },
221 { 0xe3, 0x0000 },
222 { 0xe4, 0x0000 },
223 { 0xe5, 0x0000 },
224 { 0xe6, 0x0000 },
225 { 0xe7, 0x0000 },
226 { 0xe8, 0x0200 },
227 { 0xe9, 0x0000 },
228 { 0xea, 0x0000 },
229 { 0xeb, 0x0000 },
230 { 0xec, 0x0000 },
231 { 0xed, 0x0000 },
232 { 0xee, 0x0000 },
233 { 0xef, 0x0000 },
234 { 0xf0, 0x0000 },
235 { 0xf1, 0x0000 },
236 { 0xf2, 0x0200 },
237 { 0xf3, 0x0000 },
238 { 0xf4, 0x0000 },
239 { 0xf5, 0x0000 },
240 { 0xf6, 0x0000 },
241 { 0xf7, 0x0000 },
242 { 0xf8, 0x0000 },
243 { 0xf9, 0x0000 },
244 { 0xfa, 0x0000 },
245 { 0xfb, 0x0000 },
246};
247
248static int rt1305_reg_init(struct snd_soc_component *component)
249{
250 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
251
252 regmap_multi_reg_write(rt1305->regmap, init_list, RT1305_INIT_REG_LEN);
253 return 0;
254}
255
256static bool rt1305_volatile_register(struct device *dev, unsigned int reg)
257{
258 int i;
259
260 for (i = 0; i < ARRAY_SIZE(rt1305_ranges); i++) {
261 if (reg >= rt1305_ranges[i].range_min &&
262 reg <= rt1305_ranges[i].range_max) {
263 return true;
264 }
265 }
266
267 switch (reg) {
268 case RT1305_RESET:
269 case RT1305_SPDIF_IN_SET_1:
270 case RT1305_SPDIF_IN_SET_2:
271 case RT1305_SPDIF_IN_SET_3:
272 case RT1305_POWER_CTRL_2:
273 case RT1305_CLOCK_DETECT:
274 case RT1305_BIQUAD_SET_1:
275 case RT1305_BIQUAD_SET_2:
276 case RT1305_EQ_SET_2:
277 case RT1305_SPK_TEMP_PROTECTION_0:
278 case RT1305_SPK_TEMP_PROTECTION_2:
279 case RT1305_SPK_DC_DETECT_1:
280 case RT1305_SILENCE_DETECT:
281 case RT1305_VERSION_ID:
282 case RT1305_VENDOR_ID:
283 case RT1305_DEVICE_ID:
284 case RT1305_EFUSE_1:
285 case RT1305_EFUSE_3:
286 case RT1305_DC_CALIB_1:
287 case RT1305_DC_CALIB_3:
288 case RT1305_DAC_OFFSET_1:
289 case RT1305_DAC_OFFSET_2:
290 case RT1305_DAC_OFFSET_3:
291 case RT1305_DAC_OFFSET_4:
292 case RT1305_DAC_OFFSET_5:
293 case RT1305_DAC_OFFSET_6:
294 case RT1305_DAC_OFFSET_7:
295 case RT1305_DAC_OFFSET_8:
296 case RT1305_DAC_OFFSET_9:
297 case RT1305_DAC_OFFSET_10:
298 case RT1305_DAC_OFFSET_11:
299 case RT1305_TRIM_1:
300 case RT1305_TRIM_2:
301 return true;
302
303 default:
304 return false;
305 }
306}
307
308static bool rt1305_readable_register(struct device *dev, unsigned int reg)
309{
310 int i;
311
312 for (i = 0; i < ARRAY_SIZE(rt1305_ranges); i++) {
313 if (reg >= rt1305_ranges[i].range_min &&
314 reg <= rt1305_ranges[i].range_max) {
315 return true;
316 }
317 }
318
319 switch (reg) {
320 case RT1305_RESET:
321 case RT1305_CLK_1 ... RT1305_CAL_EFUSE_CLOCK:
322 case RT1305_PLL0_1 ... RT1305_PLL1_2:
323 case RT1305_MIXER_CTRL_1:
324 case RT1305_MIXER_CTRL_2:
325 case RT1305_DAC_SET_1:
326 case RT1305_DAC_SET_2:
327 case RT1305_ADC_SET_1:
328 case RT1305_ADC_SET_2:
329 case RT1305_ADC_SET_3:
330 case RT1305_PATH_SET:
331 case RT1305_SPDIF_IN_SET_1:
332 case RT1305_SPDIF_IN_SET_2:
333 case RT1305_SPDIF_IN_SET_3:
334 case RT1305_SPDIF_OUT_SET_1:
335 case RT1305_SPDIF_OUT_SET_2:
336 case RT1305_SPDIF_OUT_SET_3:
337 case RT1305_I2S_SET_1:
338 case RT1305_I2S_SET_2:
339 case RT1305_PBTL_MONO_MODE_SRC:
340 case RT1305_MANUALLY_I2C_DEVICE:
341 case RT1305_POWER_STATUS:
342 case RT1305_POWER_CTRL_1:
343 case RT1305_POWER_CTRL_2:
344 case RT1305_POWER_CTRL_3:
345 case RT1305_POWER_CTRL_4:
346 case RT1305_POWER_CTRL_5:
347 case RT1305_CLOCK_DETECT:
348 case RT1305_BIQUAD_SET_1:
349 case RT1305_BIQUAD_SET_2:
350 case RT1305_ADJUSTED_HPF_1:
351 case RT1305_ADJUSTED_HPF_2:
352 case RT1305_EQ_SET_1:
353 case RT1305_EQ_SET_2:
354 case RT1305_SPK_TEMP_PROTECTION_0:
355 case RT1305_SPK_TEMP_PROTECTION_1:
356 case RT1305_SPK_TEMP_PROTECTION_2:
357 case RT1305_SPK_TEMP_PROTECTION_3:
358 case RT1305_SPK_DC_DETECT_1:
359 case RT1305_SPK_DC_DETECT_2:
360 case RT1305_LOUDNESS:
361 case RT1305_THERMAL_FOLD_BACK_1:
362 case RT1305_THERMAL_FOLD_BACK_2:
363 case RT1305_SILENCE_DETECT ... RT1305_SPK_EXCURSION_LIMITER_7:
364 case RT1305_VERSION_ID:
365 case RT1305_VENDOR_ID:
366 case RT1305_DEVICE_ID:
367 case RT1305_EFUSE_1:
368 case RT1305_EFUSE_2:
369 case RT1305_EFUSE_3:
370 case RT1305_DC_CALIB_1:
371 case RT1305_DC_CALIB_2:
372 case RT1305_DC_CALIB_3:
373 case RT1305_DAC_OFFSET_1 ... RT1305_DAC_OFFSET_14:
374 case RT1305_TRIM_1:
375 case RT1305_TRIM_2:
376 case RT1305_TUNE_INTERNAL_OSC:
377 case RT1305_BIQUAD1_H0_L_28_16 ... RT1305_BIQUAD3_A2_R_15_0:
378 return true;
379 default:
380 return false;
381 }
382}
383
384static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9435, 37, 0);
385
386static const char * const rt1305_rx_data_ch_select[] = {
387 "LR",
388 "RL",
389 "Copy L",
390 "Copy R",
391};
392
393static SOC_ENUM_SINGLE_DECL(rt1305_rx_data_ch_enum, RT1305_I2S_SET_2, 2,
394 rt1305_rx_data_ch_select);
395
396static void rt1305_reset(struct regmap *regmap)
397{
398 regmap_write(regmap, RT1305_RESET, 0);
399}
400
401static const struct snd_kcontrol_new rt1305_snd_controls[] = {
402 SOC_DOUBLE_TLV("DAC Playback Volume", RT1305_DAC_SET_1,
403 8, 0, 0xff, 0, dac_vol_tlv),
404
405 /* I2S Data Channel Selection */
406 SOC_ENUM("RX Channel Select", rt1305_rx_data_ch_enum),
407};
408
409static int rt1305_is_rc_clk_from_pll(struct snd_soc_dapm_widget *source,
410 struct snd_soc_dapm_widget *sink)
411{
412 struct snd_soc_component *component =
413 snd_soc_dapm_to_component(source->dapm);
414 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
415 unsigned int val;
416
417 snd_soc_component_read(component, RT1305_CLK_1, &val);
418
419 if (rt1305->sysclk_src == RT1305_FS_SYS_PRE_S_PLL1 &&
420 (val & RT1305_SEL_PLL_SRC_2_RCCLK))
421 return 1;
422 else
423 return 0;
424}
425
426static int rt1305_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
427 struct snd_soc_dapm_widget *sink)
428{
429 struct snd_soc_component *component =
430 snd_soc_dapm_to_component(source->dapm);
431 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
432
433 if (rt1305->sysclk_src == RT1305_FS_SYS_PRE_S_PLL1)
434 return 1;
435 else
436 return 0;
437}
438
439static int rt1305_classd_event(struct snd_soc_dapm_widget *w,
440 struct snd_kcontrol *kcontrol, int event)
441{
442 struct snd_soc_component *component =
443 snd_soc_dapm_to_component(w->dapm);
444
445 switch (event) {
446 case SND_SOC_DAPM_POST_PMU:
447 snd_soc_component_update_bits(component, RT1305_POWER_CTRL_1,
448 RT1305_POW_PDB_JD_MASK, RT1305_POW_PDB_JD);
449 break;
450 case SND_SOC_DAPM_PRE_PMD:
451 snd_soc_component_update_bits(component, RT1305_POWER_CTRL_1,
452 RT1305_POW_PDB_JD_MASK, 0);
453 usleep_range(150000, 200000);
454 break;
455
456 default:
457 return 0;
458 }
459
460 return 0;
461}
462
463static const struct snd_kcontrol_new rt1305_sto_dac_l =
464 SOC_DAPM_SINGLE("Switch", RT1305_DAC_SET_2,
465 RT1305_DVOL_MUTE_L_EN_SFT, 1, 1);
466
467static const struct snd_kcontrol_new rt1305_sto_dac_r =
468 SOC_DAPM_SINGLE("Switch", RT1305_DAC_SET_2,
469 RT1305_DVOL_MUTE_R_EN_SFT, 1, 1);
470
471static const struct snd_soc_dapm_widget rt1305_dapm_widgets[] = {
472 SND_SOC_DAPM_SUPPLY("PLL0", RT1305_POWER_CTRL_1,
473 RT1305_POW_PLL0_EN_BIT, 0, NULL, 0),
474 SND_SOC_DAPM_SUPPLY("PLL1", RT1305_POWER_CTRL_1,
475 RT1305_POW_PLL1_EN_BIT, 0, NULL, 0),
476 SND_SOC_DAPM_SUPPLY("MBIAS", RT1305_POWER_CTRL_1,
477 RT1305_POW_MBIAS_LV_BIT, 0, NULL, 0),
478 SND_SOC_DAPM_SUPPLY("BG MBIAS", RT1305_POWER_CTRL_1,
479 RT1305_POW_BG_MBIAS_LV_BIT, 0, NULL, 0),
480 SND_SOC_DAPM_SUPPLY("LDO2", RT1305_POWER_CTRL_1,
481 RT1305_POW_LDO2_BIT, 0, NULL, 0),
482 SND_SOC_DAPM_SUPPLY("BG2", RT1305_POWER_CTRL_1,
483 RT1305_POW_BG2_BIT, 0, NULL, 0),
484 SND_SOC_DAPM_SUPPLY("LDO2 IB2", RT1305_POWER_CTRL_1,
485 RT1305_POW_LDO2_IB2_BIT, 0, NULL, 0),
486 SND_SOC_DAPM_SUPPLY("VREF", RT1305_POWER_CTRL_1,
487 RT1305_POW_VREF_BIT, 0, NULL, 0),
488 SND_SOC_DAPM_SUPPLY("VREF1", RT1305_POWER_CTRL_1,
489 RT1305_POW_VREF1_BIT, 0, NULL, 0),
490 SND_SOC_DAPM_SUPPLY("VREF2", RT1305_POWER_CTRL_1,
491 RT1305_POW_VREF2_BIT, 0, NULL, 0),
492
493
494 SND_SOC_DAPM_SUPPLY("DISC VREF", RT1305_POWER_CTRL_2,
495 RT1305_POW_DISC_VREF_BIT, 0, NULL, 0),
496 SND_SOC_DAPM_SUPPLY("FASTB VREF", RT1305_POWER_CTRL_2,
497 RT1305_POW_FASTB_VREF_BIT, 0, NULL, 0),
498 SND_SOC_DAPM_SUPPLY("ULTRA FAST VREF", RT1305_POWER_CTRL_2,
499 RT1305_POW_ULTRA_FAST_VREF_BIT, 0, NULL, 0),
500 SND_SOC_DAPM_SUPPLY("CHOP DAC", RT1305_POWER_CTRL_2,
501 RT1305_POW_CKXEN_DAC_BIT, 0, NULL, 0),
502 SND_SOC_DAPM_SUPPLY("CKGEN DAC", RT1305_POWER_CTRL_2,
503 RT1305_POW_EN_CKGEN_DAC_BIT, 0, NULL, 0),
504 SND_SOC_DAPM_SUPPLY("CLAMP", RT1305_POWER_CTRL_2,
505 RT1305_POW_CLAMP_BIT, 0, NULL, 0),
506 SND_SOC_DAPM_SUPPLY("BUFL", RT1305_POWER_CTRL_2,
507 RT1305_POW_BUFL_BIT, 0, NULL, 0),
508 SND_SOC_DAPM_SUPPLY("BUFR", RT1305_POWER_CTRL_2,
509 RT1305_POW_BUFR_BIT, 0, NULL, 0),
510 SND_SOC_DAPM_SUPPLY("CKGEN ADC", RT1305_POWER_CTRL_2,
511 RT1305_POW_EN_CKGEN_ADC_BIT, 0, NULL, 0),
512 SND_SOC_DAPM_SUPPLY("ADC3 L", RT1305_POWER_CTRL_2,
513 RT1305_POW_ADC3_L_BIT, 0, NULL, 0),
514 SND_SOC_DAPM_SUPPLY("ADC3 R", RT1305_POWER_CTRL_2,
515 RT1305_POW_ADC3_R_BIT, 0, NULL, 0),
516 SND_SOC_DAPM_SUPPLY("TRIOSC", RT1305_POWER_CTRL_2,
517 RT1305_POW_TRIOSC_BIT, 0, NULL, 0),
518 SND_SOC_DAPM_SUPPLY("AVDD1", RT1305_POWER_CTRL_2,
519 RT1305_POR_AVDD1_BIT, 0, NULL, 0),
520 SND_SOC_DAPM_SUPPLY("AVDD2", RT1305_POWER_CTRL_2,
521 RT1305_POR_AVDD2_BIT, 0, NULL, 0),
522
523
524 SND_SOC_DAPM_SUPPLY("VSENSE R", RT1305_POWER_CTRL_3,
525 RT1305_POW_VSENSE_RCH_BIT, 0, NULL, 0),
526 SND_SOC_DAPM_SUPPLY("VSENSE L", RT1305_POWER_CTRL_3,
527 RT1305_POW_VSENSE_LCH_BIT, 0, NULL, 0),
528 SND_SOC_DAPM_SUPPLY("ISENSE R", RT1305_POWER_CTRL_3,
529 RT1305_POW_ISENSE_RCH_BIT, 0, NULL, 0),
530 SND_SOC_DAPM_SUPPLY("ISENSE L", RT1305_POWER_CTRL_3,
531 RT1305_POW_ISENSE_LCH_BIT, 0, NULL, 0),
532 SND_SOC_DAPM_SUPPLY("POR AVDD1", RT1305_POWER_CTRL_3,
533 RT1305_POW_POR_AVDD1_BIT, 0, NULL, 0),
534 SND_SOC_DAPM_SUPPLY("POR AVDD2", RT1305_POWER_CTRL_3,
535 RT1305_POW_POR_AVDD2_BIT, 0, NULL, 0),
536 SND_SOC_DAPM_SUPPLY("VCM 6172", RT1305_POWER_CTRL_3,
537 RT1305_EN_VCM_6172_BIT, 0, NULL, 0),
538
539
540 /* Audio Interface */
541 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
542
543 /* Digital Interface */
544 SND_SOC_DAPM_SUPPLY("DAC L Power", RT1305_POWER_CTRL_2,
545 RT1305_POW_DAC1_L_BIT, 0, NULL, 0),
546 SND_SOC_DAPM_SUPPLY("DAC R Power", RT1305_POWER_CTRL_2,
547 RT1305_POW_DAC1_R_BIT, 0, NULL, 0),
548 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
549 SND_SOC_DAPM_SWITCH("DAC L", SND_SOC_NOPM, 0, 0, &rt1305_sto_dac_l),
550 SND_SOC_DAPM_SWITCH("DAC R", SND_SOC_NOPM, 0, 0, &rt1305_sto_dac_r),
551
552 /* Output Lines */
553 SND_SOC_DAPM_PGA_E("CLASS D", SND_SOC_NOPM, 0, 0, NULL, 0,
554 rt1305_classd_event,
555 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
556 SND_SOC_DAPM_OUTPUT("SPOL"),
557 SND_SOC_DAPM_OUTPUT("SPOR"),
558};
559
560static const struct snd_soc_dapm_route rt1305_dapm_routes[] = {
561
562 { "DAC", NULL, "AIF1RX" },
563
564 { "DAC", NULL, "PLL0", rt1305_is_rc_clk_from_pll },
565 { "DAC", NULL, "PLL1", rt1305_is_sys_clk_from_pll },
566
567 { "DAC", NULL, "MBIAS" },
568 { "DAC", NULL, "BG MBIAS" },
569 { "DAC", NULL, "LDO2" },
570 { "DAC", NULL, "BG2" },
571 { "DAC", NULL, "LDO2 IB2" },
572 { "DAC", NULL, "VREF" },
573 { "DAC", NULL, "VREF1" },
574 { "DAC", NULL, "VREF2" },
575
576 { "DAC", NULL, "DISC VREF" },
577 { "DAC", NULL, "FASTB VREF" },
578 { "DAC", NULL, "ULTRA FAST VREF" },
579 { "DAC", NULL, "CHOP DAC" },
580 { "DAC", NULL, "CKGEN DAC" },
581 { "DAC", NULL, "CLAMP" },
582 { "DAC", NULL, "CKGEN ADC" },
583 { "DAC", NULL, "TRIOSC" },
584 { "DAC", NULL, "AVDD1" },
585 { "DAC", NULL, "AVDD2" },
586
587 { "DAC", NULL, "POR AVDD1" },
588 { "DAC", NULL, "POR AVDD2" },
589 { "DAC", NULL, "VCM 6172" },
590
591 { "DAC L", "Switch", "DAC" },
592 { "DAC R", "Switch", "DAC" },
593
594 { "DAC R", NULL, "VSENSE R" },
595 { "DAC L", NULL, "VSENSE L" },
596 { "DAC R", NULL, "ISENSE R" },
597 { "DAC L", NULL, "ISENSE L" },
598 { "DAC L", NULL, "ADC3 L" },
599 { "DAC R", NULL, "ADC3 R" },
600 { "DAC L", NULL, "BUFL" },
601 { "DAC R", NULL, "BUFR" },
602 { "DAC L", NULL, "DAC L Power" },
603 { "DAC R", NULL, "DAC R Power" },
604
605 { "CLASS D", NULL, "DAC L" },
606 { "CLASS D", NULL, "DAC R" },
607
608 { "SPOL", NULL, "CLASS D" },
609 { "SPOR", NULL, "CLASS D" },
610};
611
612static int rt1305_get_clk_info(int sclk, int rate)
613{
614 int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
615
616 if (sclk <= 0 || rate <= 0)
617 return -EINVAL;
618
619 rate = rate << 8;
620 for (i = 0; i < ARRAY_SIZE(pd); i++)
621 if (sclk == rate * pd[i])
622 return i;
623
624 return -EINVAL;
625}
626
627static int rt1305_hw_params(struct snd_pcm_substream *substream,
628 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
629{
630 struct snd_soc_component *component = dai->component;
631 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
632 unsigned int val_len = 0, val_clk, mask_clk;
633 int pre_div, bclk_ms, frame_size;
634
635 rt1305->lrck = params_rate(params);
636 pre_div = rt1305_get_clk_info(rt1305->sysclk, rt1305->lrck);
637 if (pre_div < 0) {
638 dev_warn(component->dev, "Force using PLL ");
639 snd_soc_dai_set_pll(dai, 0, RT1305_PLL1_S_BCLK,
640 rt1305->lrck * 64, rt1305->lrck * 256);
641 snd_soc_dai_set_sysclk(dai, RT1305_FS_SYS_PRE_S_PLL1,
642 rt1305->lrck * 256, SND_SOC_CLOCK_IN);
643 pre_div = 0;
644 }
645 frame_size = snd_soc_params_to_frame_size(params);
646 if (frame_size < 0) {
647 dev_err(component->dev, "Unsupported frame size: %d\n",
648 frame_size);
649 return -EINVAL;
650 }
651
652 bclk_ms = frame_size > 32;
653 rt1305->bclk = rt1305->lrck * (32 << bclk_ms);
654
655 dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
656 bclk_ms, pre_div, dai->id);
657
658 dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
659 rt1305->lrck, pre_div, dai->id);
660
661 switch (params_width(params)) {
662 case 16:
663 val_len |= RT1305_I2S_DL_SEL_16B;
664 break;
665 case 20:
666 val_len |= RT1305_I2S_DL_SEL_20B;
667 break;
668 case 24:
669 val_len |= RT1305_I2S_DL_SEL_24B;
670 break;
671 case 8:
672 val_len |= RT1305_I2S_DL_SEL_8B;
673 break;
674 default:
675 return -EINVAL;
676 }
677
678 switch (dai->id) {
679 case RT1305_AIF1:
680 mask_clk = RT1305_DIV_FS_SYS_MASK;
681 val_clk = pre_div << RT1305_DIV_FS_SYS_SFT;
682 snd_soc_component_update_bits(component, RT1305_I2S_SET_2,
683 RT1305_I2S_DL_SEL_MASK,
684 val_len);
685 break;
686 default:
687 dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
688 return -EINVAL;
689 }
690
691 snd_soc_component_update_bits(component, RT1305_CLK_2,
692 mask_clk, val_clk);
693
694 return 0;
695}
696
697static int rt1305_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
698{
699 struct snd_soc_component *component = dai->component;
700 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
701 unsigned int reg_val = 0, reg1_val = 0;
702
703 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
704 case SND_SOC_DAIFMT_CBM_CFM:
705 reg_val |= RT1305_SEL_I2S_OUT_MODE_M;
706 rt1305->master = 1;
707 break;
708 case SND_SOC_DAIFMT_CBS_CFS:
709 reg_val |= RT1305_SEL_I2S_OUT_MODE_S;
710 rt1305->master = 0;
711 break;
712 default:
713 return -EINVAL;
714 }
715
716 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
717 case SND_SOC_DAIFMT_NB_NF:
718 break;
719 case SND_SOC_DAIFMT_IB_NF:
720 reg1_val |= RT1305_I2S_BCLK_INV;
721 break;
722 default:
723 return -EINVAL;
724 }
725
726 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
727 case SND_SOC_DAIFMT_I2S:
728 break;
729 case SND_SOC_DAIFMT_LEFT_J:
730 reg1_val |= RT1305_I2S_DF_SEL_LEFT;
731 break;
732 case SND_SOC_DAIFMT_DSP_A:
733 reg1_val |= RT1305_I2S_DF_SEL_PCM_A;
734 break;
735 case SND_SOC_DAIFMT_DSP_B:
736 reg1_val |= RT1305_I2S_DF_SEL_PCM_B;
737 break;
738 default:
739 return -EINVAL;
740 }
741
742 switch (dai->id) {
743 case RT1305_AIF1:
744 snd_soc_component_update_bits(component, RT1305_I2S_SET_1,
745 RT1305_SEL_I2S_OUT_MODE_MASK, reg_val);
746 snd_soc_component_update_bits(component, RT1305_I2S_SET_2,
747 RT1305_I2S_DF_SEL_MASK | RT1305_I2S_BCLK_MASK,
748 reg1_val);
749 break;
750 default:
751 dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
752 return -EINVAL;
753 }
754 return 0;
755}
756
757static int rt1305_set_component_sysclk(struct snd_soc_component *component,
758 int clk_id, int source, unsigned int freq, int dir)
759{
760 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
761 unsigned int reg_val = 0;
762
763 if (freq == rt1305->sysclk && clk_id == rt1305->sysclk_src)
764 return 0;
765
766 switch (clk_id) {
767 case RT1305_FS_SYS_PRE_S_MCLK:
768 reg_val |= RT1305_SEL_FS_SYS_PRE_MCLK;
769 snd_soc_component_update_bits(component,
770 RT1305_CLOCK_DETECT, RT1305_SEL_CLK_DET_SRC_MASK,
771 RT1305_SEL_CLK_DET_SRC_MCLK);
772 break;
773 case RT1305_FS_SYS_PRE_S_PLL1:
774 reg_val |= RT1305_SEL_FS_SYS_PRE_PLL;
775 break;
776 case RT1305_FS_SYS_PRE_S_RCCLK:
777 reg_val |= RT1305_SEL_FS_SYS_PRE_RCCLK;
778 break;
779 default:
780 dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
781 return -EINVAL;
782 }
783 snd_soc_component_update_bits(component, RT1305_CLK_1,
784 RT1305_SEL_FS_SYS_PRE_MASK, reg_val);
785 rt1305->sysclk = freq;
786 rt1305->sysclk_src = clk_id;
787
788 dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
789 freq, clk_id);
790
791 return 0;
792}
793
794static int rt1305_set_component_pll(struct snd_soc_component *component,
795 int pll_id, int source, unsigned int freq_in,
796 unsigned int freq_out)
797{
798 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
799 struct rl6231_pll_code pll_code;
800 int ret;
801
802 if (source == rt1305->pll_src && freq_in == rt1305->pll_in &&
803 freq_out == rt1305->pll_out)
804 return 0;
805
806 if (!freq_in || !freq_out) {
807 dev_dbg(component->dev, "PLL disabled\n");
808
809 rt1305->pll_in = 0;
810 rt1305->pll_out = 0;
811 snd_soc_component_update_bits(component, RT1305_CLK_1,
812 RT1305_SEL_FS_SYS_PRE_MASK | RT1305_SEL_PLL_SRC_1_MASK,
813 RT1305_SEL_FS_SYS_PRE_PLL | RT1305_SEL_PLL_SRC_1_BCLK);
814 return 0;
815 }
816
817 switch (source) {
818 case RT1305_PLL2_S_MCLK:
819 snd_soc_component_update_bits(component, RT1305_CLK_1,
820 RT1305_SEL_PLL_SRC_2_MASK | RT1305_SEL_PLL_SRC_1_MASK |
821 RT1305_DIV_PLL_SRC_2_MASK,
822 RT1305_SEL_PLL_SRC_2_MCLK | RT1305_SEL_PLL_SRC_1_PLL2);
823 snd_soc_component_update_bits(component,
824 RT1305_CLOCK_DETECT, RT1305_SEL_CLK_DET_SRC_MASK,
825 RT1305_SEL_CLK_DET_SRC_MCLK);
826 break;
827 case RT1305_PLL1_S_BCLK:
828 snd_soc_component_update_bits(component,
829 RT1305_CLK_1, RT1305_SEL_PLL_SRC_1_MASK,
830 RT1305_SEL_PLL_SRC_1_BCLK);
831 break;
832 case RT1305_PLL2_S_RCCLK:
833 snd_soc_component_update_bits(component, RT1305_CLK_1,
834 RT1305_SEL_PLL_SRC_2_MASK | RT1305_SEL_PLL_SRC_1_MASK |
835 RT1305_DIV_PLL_SRC_2_MASK,
836 RT1305_SEL_PLL_SRC_2_RCCLK | RT1305_SEL_PLL_SRC_1_PLL2);
837 freq_in = 98304000;
838 break;
839 default:
840 dev_err(component->dev, "Unknown PLL Source %d\n", source);
841 return -EINVAL;
842 }
843
844 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
845 if (ret < 0) {
846 dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
847 return ret;
848 }
849
850 dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
851 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
852 pll_code.n_code, pll_code.k_code);
853
854 snd_soc_component_write(component, RT1305_PLL1_1,
855 (pll_code.m_bp ? 0 : pll_code.m_code) << RT1305_PLL_1_M_SFT |
856 pll_code.m_bp << RT1305_PLL_1_M_BYPASS_SFT |
857 pll_code.n_code);
858 snd_soc_component_write(component, RT1305_PLL1_2,
859 pll_code.k_code);
860
861 rt1305->pll_in = freq_in;
862 rt1305->pll_out = freq_out;
863 rt1305->pll_src = source;
864
865 return 0;
866}
867
868static int rt1305_probe(struct snd_soc_component *component)
869{
870 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
871
872 rt1305->component = component;
873
874 /* initial settings */
875 rt1305_reg_init(component);
876
877 return 0;
878}
879
880static void rt1305_remove(struct snd_soc_component *component)
881{
882 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
883
884 rt1305_reset(rt1305->regmap);
885}
886
887#ifdef CONFIG_PM
888static int rt1305_suspend(struct snd_soc_component *component)
889{
890 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
891
892 regcache_cache_only(rt1305->regmap, true);
893 regcache_mark_dirty(rt1305->regmap);
894
895 return 0;
896}
897
898static int rt1305_resume(struct snd_soc_component *component)
899{
900 struct rt1305_priv *rt1305 = snd_soc_component_get_drvdata(component);
901
902 regcache_cache_only(rt1305->regmap, false);
903 regcache_sync(rt1305->regmap);
904
905 return 0;
906}
907#else
908#define rt1305_suspend NULL
909#define rt1305_resume NULL
910#endif
911
912#define RT1305_STEREO_RATES SNDRV_PCM_RATE_8000_192000
913#define RT1305_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
914 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE | \
915 SNDRV_PCM_FMTBIT_S24_LE)
916
917static const struct snd_soc_dai_ops rt1305_aif_dai_ops = {
918 .hw_params = rt1305_hw_params,
919 .set_fmt = rt1305_set_dai_fmt,
920};
921
922static struct snd_soc_dai_driver rt1305_dai[] = {
923 {
924 .name = "rt1305-aif",
925 .playback = {
926 .stream_name = "AIF1 Playback",
927 .channels_min = 1,
928 .channels_max = 2,
929 .rates = RT1305_STEREO_RATES,
930 .formats = RT1305_FORMATS,
931 },
932 .ops = &rt1305_aif_dai_ops,
933 },
934};
935
936static const struct snd_soc_component_driver soc_component_dev_rt1305 = {
937 .probe = rt1305_probe,
938 .remove = rt1305_remove,
939 .suspend = rt1305_suspend,
940 .resume = rt1305_resume,
941 .controls = rt1305_snd_controls,
942 .num_controls = ARRAY_SIZE(rt1305_snd_controls),
943 .dapm_widgets = rt1305_dapm_widgets,
944 .num_dapm_widgets = ARRAY_SIZE(rt1305_dapm_widgets),
945 .dapm_routes = rt1305_dapm_routes,
946 .num_dapm_routes = ARRAY_SIZE(rt1305_dapm_routes),
947 .set_sysclk = rt1305_set_component_sysclk,
948 .set_pll = rt1305_set_component_pll,
949 .use_pmdown_time = 1,
950 .endianness = 1,
951 .non_legacy_dai_naming = 1,
952};
953
954static const struct regmap_config rt1305_regmap = {
955 .reg_bits = 8,
956 .val_bits = 16,
957 .max_register = RT1305_MAX_REG + 1 + (ARRAY_SIZE(rt1305_ranges) *
958 RT1305_PR_SPACING),
959 .volatile_reg = rt1305_volatile_register,
960 .readable_reg = rt1305_readable_register,
961 .cache_type = REGCACHE_RBTREE,
962 .reg_defaults = rt1305_reg,
963 .num_reg_defaults = ARRAY_SIZE(rt1305_reg),
964 .ranges = rt1305_ranges,
965 .num_ranges = ARRAY_SIZE(rt1305_ranges),
966 .use_single_rw = true,
967};
968
969#if defined(CONFIG_OF)
970static const struct of_device_id rt1305_of_match[] = {
971 { .compatible = "realtek,rt1305", },
972 { .compatible = "realtek,rt1306", },
973 {},
974};
975MODULE_DEVICE_TABLE(of, rt1305_of_match);
976#endif
977
978#ifdef CONFIG_ACPI
979static struct acpi_device_id rt1305_acpi_match[] = {
980 {"10EC1305", 0,},
981 {"10EC1306", 0,},
982 {},
983};
984MODULE_DEVICE_TABLE(acpi, rt1305_acpi_match);
985#endif
986
987static const struct i2c_device_id rt1305_i2c_id[] = {
988 { "rt1305", 0 },
989 { "rt1306", 0 },
990 { }
991};
992MODULE_DEVICE_TABLE(i2c, rt1305_i2c_id);
993
994static void rt1305_calibrate(struct rt1305_priv *rt1305)
995{
996 unsigned int valmsb, vallsb, offsetl, offsetr;
997 unsigned int rh, rl, rhl, r0ohm;
998 u64 r0l, r0r;
999
1000 regcache_cache_bypass(rt1305->regmap, true);
1001
1002 rt1305_reset(rt1305->regmap);
1003 regmap_write(rt1305->regmap, RT1305_ADC_SET_3, 0x0219);
1004 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xcf, 0x5548);
1005 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xc1, 0x0320);
1006 regmap_write(rt1305->regmap, RT1305_CLOCK_DETECT, 0x1000);
1007 regmap_write(rt1305->regmap, RT1305_CLK_1, 0x0600);
1008 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xffd0);
1009 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0080);
1010 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0880);
1011 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_1, 0x0dfe);
1012
1013 /* Sin Gen */
1014 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x5d, 0x0442);
1015
1016 regmap_write(rt1305->regmap, RT1305_CAL_EFUSE_CLOCK, 0xb000);
1017 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xc3, 0xd4a0);
1018 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xcc, 0x00cc);
1019 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xc1, 0x0320);
1020 regmap_write(rt1305->regmap, RT1305_POWER_STATUS, 0x0000);
1021 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_2, 0xffff);
1022 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfc20);
1023 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x06, 0x00c0);
1024 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfca0);
1025 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfce0);
1026 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfcf0);
1027
1028 /* EFUSE read */
1029 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0080);
1030 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0880);
1031 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0880);
1032 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfce0);
1033 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfca0);
1034 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfc20);
1035 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x06, 0x0000);
1036 regmap_write(rt1305->regmap, RT1305_EFUSE_1, 0x0000);
1037
1038 regmap_read(rt1305->regmap, RT1305_DAC_OFFSET_5, &valmsb);
1039 regmap_read(rt1305->regmap, RT1305_DAC_OFFSET_6, &vallsb);
1040 offsetl = valmsb << 16 | vallsb;
1041 regmap_read(rt1305->regmap, RT1305_DAC_OFFSET_7, &valmsb);
1042 regmap_read(rt1305->regmap, RT1305_DAC_OFFSET_8, &vallsb);
1043 offsetr = valmsb << 16 | vallsb;
1044 pr_info("DC offsetl=0x%x, offsetr=0x%x\n", offsetl, offsetr);
1045
1046 /* R0 calibration */
1047 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x5d, 0x9542);
1048 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0xfcf0);
1049 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_2, 0xffff);
1050 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_1, 0x1dfe);
1051 regmap_write(rt1305->regmap, RT1305_SILENCE_DETECT, 0x0e13);
1052 regmap_write(rt1305->regmap, RT1305_CLK_1, 0x0650);
1053
1054 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x50, 0x0064);
1055 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x51, 0x0770);
1056 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x52, 0xc30c);
1057 regmap_write(rt1305->regmap, RT1305_SPK_TEMP_PROTECTION_1, 0x8200);
1058 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xd4, 0xfb00);
1059 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xd4, 0xff80);
1060 msleep(2000);
1061 regmap_read(rt1305->regmap, RT1305_PR_BASE + 0x55, &rh);
1062 regmap_read(rt1305->regmap, RT1305_PR_BASE + 0x56, &rl);
1063 rhl = (rh << 16) | rl;
1064 r0ohm = (rhl*10) / 33554432;
1065
1066 pr_debug("Left_rhl = 0x%x rh=0x%x rl=0x%x\n", rhl, rh, rl);
1067 pr_info("Left channel %d.%dohm\n", (r0ohm/10), (r0ohm%10));
1068
1069 r0l = 562949953421312;
1070 if (rhl != 0)
1071 do_div(r0l, rhl);
1072 pr_debug("Left_r0 = 0x%llx\n", r0l);
1073
1074 regmap_write(rt1305->regmap, RT1305_SPK_TEMP_PROTECTION_1, 0x9200);
1075 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xd4, 0xfb00);
1076 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xd4, 0xff80);
1077 msleep(2000);
1078 regmap_read(rt1305->regmap, RT1305_PR_BASE + 0x55, &rh);
1079 regmap_read(rt1305->regmap, RT1305_PR_BASE + 0x56, &rl);
1080 rhl = (rh << 16) | rl;
1081 r0ohm = (rhl*10) / 33554432;
1082
1083 pr_debug("Right_rhl = 0x%x rh=0x%x rl=0x%x\n", rhl, rh, rl);
1084 pr_info("Right channel %d.%dohm\n", (r0ohm/10), (r0ohm%10));
1085
1086 r0r = 562949953421312;
1087 if (rhl != 0)
1088 do_div(r0r, rhl);
1089 pr_debug("Right_r0 = 0x%llx\n", r0r);
1090
1091 regmap_write(rt1305->regmap, RT1305_SPK_TEMP_PROTECTION_1, 0xc2ec);
1092
1093 if ((r0l > R0_UPPER) && (r0l < R0_LOWER) &&
1094 (r0r > R0_UPPER) && (r0r < R0_LOWER)) {
1095 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x4e,
1096 (r0l >> 16) & 0xffff);
1097 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x4f,
1098 r0l & 0xffff);
1099 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xfe,
1100 ((r0r >> 16) & 0xffff) | 0xf800);
1101 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0xfd,
1102 r0r & 0xffff);
1103 } else {
1104 pr_err("R0 calibration failed\n");
1105 }
1106
1107 /* restore some registers */
1108 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_1, 0x0dfe);
1109 usleep_range(200000, 400000);
1110 regmap_write(rt1305->regmap, RT1305_PR_BASE + 0x5d, 0x0442);
1111 regmap_write(rt1305->regmap, RT1305_CLOCK_DETECT, 0x3000);
1112 regmap_write(rt1305->regmap, RT1305_CLK_1, 0x0400);
1113 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_1, 0x0000);
1114 regmap_write(rt1305->regmap, RT1305_CAL_EFUSE_CLOCK, 0x8000);
1115 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_2, 0x1020);
1116 regmap_write(rt1305->regmap, RT1305_POWER_CTRL_3, 0x0000);
1117
1118 regcache_cache_bypass(rt1305->regmap, false);
1119}
1120
1121static int rt1305_i2c_probe(struct i2c_client *i2c,
1122 const struct i2c_device_id *id)
1123{
1124 struct rt1305_priv *rt1305;
1125 int ret;
1126 unsigned int val;
1127
1128 rt1305 = devm_kzalloc(&i2c->dev, sizeof(struct rt1305_priv),
1129 GFP_KERNEL);
1130 if (rt1305 == NULL)
1131 return -ENOMEM;
1132
1133 i2c_set_clientdata(i2c, rt1305);
1134
1135 rt1305->regmap = devm_regmap_init_i2c(i2c, &rt1305_regmap);
1136 if (IS_ERR(rt1305->regmap)) {
1137 ret = PTR_ERR(rt1305->regmap);
1138 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1139 ret);
1140 return ret;
1141 }
1142
1143 regmap_read(rt1305->regmap, RT1305_DEVICE_ID, &val);
1144 if (val != RT1305_DEVICE_ID_NUM) {
1145 dev_err(&i2c->dev,
1146 "Device with ID register %x is not rt1305\n", val);
1147 return -ENODEV;
1148 }
1149
1150 rt1305_reset(rt1305->regmap);
1151 rt1305_calibrate(rt1305);
1152
1153 return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt1305,
1154 rt1305_dai, ARRAY_SIZE(rt1305_dai));
1155}
1156
1157static int rt1305_i2c_remove(struct i2c_client *i2c)
1158{
1159 snd_soc_unregister_component(&i2c->dev);
1160
1161 return 0;
1162}
1163
1164static void rt1305_i2c_shutdown(struct i2c_client *client)
1165{
1166 struct rt1305_priv *rt1305 = i2c_get_clientdata(client);
1167
1168 rt1305_reset(rt1305->regmap);
1169}
1170
1171
1172static struct i2c_driver rt1305_i2c_driver = {
1173 .driver = {
1174 .name = "rt1305",
1175#if defined(CONFIG_OF)
1176 .of_match_table = rt1305_of_match,
1177#endif
1178#if defined(CONFIG_ACPI)
1179 .acpi_match_table = ACPI_PTR(rt1305_acpi_match)
1180#endif
1181 },
1182 .probe = rt1305_i2c_probe,
1183 .remove = rt1305_i2c_remove,
1184 .shutdown = rt1305_i2c_shutdown,
1185 .id_table = rt1305_i2c_id,
1186};
1187module_i2c_driver(rt1305_i2c_driver);
1188
1189MODULE_DESCRIPTION("ASoC RT1305 amplifier driver");
1190MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
1191MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt1305.h b/sound/soc/codecs/rt1305.h
new file mode 100644
index 000000000000..bde86f97729a
--- /dev/null
+++ b/sound/soc/codecs/rt1305.h
@@ -0,0 +1,276 @@
1/*
2 * RT1305.h -- RT1305 ALSA SoC amplifier component driver
3 *
4 * Copyright 2018 Realtek Semiconductor Corp.
5 * Author: Shuming Fan <shumingf@realtek.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
12#ifndef _RT1305_H_
13#define _RT1305_H_
14
15#define RT1305_DEVICE_ID_NUM 0x6251
16
17#define RT1305_RESET 0x00
18#define RT1305_CLK_1 0x04
19#define RT1305_CLK_2 0x05
20#define RT1305_CLK_3 0x06
21#define RT1305_DFLL_REG 0x07
22#define RT1305_CAL_EFUSE_CLOCK 0x08
23#define RT1305_PLL0_1 0x0a
24#define RT1305_PLL0_2 0x0b
25#define RT1305_PLL1_1 0x0c
26#define RT1305_PLL1_2 0x0d
27#define RT1305_MIXER_CTRL_1 0x10
28#define RT1305_MIXER_CTRL_2 0x11
29#define RT1305_DAC_SET_1 0x12
30#define RT1305_DAC_SET_2 0x14
31#define RT1305_ADC_SET_1 0x16
32#define RT1305_ADC_SET_2 0x17
33#define RT1305_ADC_SET_3 0x18
34#define RT1305_PATH_SET 0x20
35#define RT1305_SPDIF_IN_SET_1 0x22
36#define RT1305_SPDIF_IN_SET_2 0x24
37#define RT1305_SPDIF_IN_SET_3 0x26
38#define RT1305_SPDIF_OUT_SET_1 0x28
39#define RT1305_SPDIF_OUT_SET_2 0x2a
40#define RT1305_SPDIF_OUT_SET_3 0x2b
41#define RT1305_I2S_SET_1 0x2d
42#define RT1305_I2S_SET_2 0x2e
43#define RT1305_PBTL_MONO_MODE_SRC 0x2f
44#define RT1305_MANUALLY_I2C_DEVICE 0x32
45#define RT1305_POWER_STATUS 0x39
46#define RT1305_POWER_CTRL_1 0x3a
47#define RT1305_POWER_CTRL_2 0x3b
48#define RT1305_POWER_CTRL_3 0x3c
49#define RT1305_POWER_CTRL_4 0x3d
50#define RT1305_POWER_CTRL_5 0x3e
51#define RT1305_CLOCK_DETECT 0x3f
52#define RT1305_BIQUAD_SET_1 0x40
53#define RT1305_BIQUAD_SET_2 0x42
54#define RT1305_ADJUSTED_HPF_1 0x46
55#define RT1305_ADJUSTED_HPF_2 0x47
56#define RT1305_EQ_SET_1 0x4b
57#define RT1305_EQ_SET_2 0x4c
58#define RT1305_SPK_TEMP_PROTECTION_0 0x4f
59#define RT1305_SPK_TEMP_PROTECTION_1 0x50
60#define RT1305_SPK_TEMP_PROTECTION_2 0x51
61#define RT1305_SPK_TEMP_PROTECTION_3 0x52
62#define RT1305_SPK_DC_DETECT_1 0x53
63#define RT1305_SPK_DC_DETECT_2 0x54
64#define RT1305_LOUDNESS 0x58
65#define RT1305_THERMAL_FOLD_BACK_1 0x5e
66#define RT1305_THERMAL_FOLD_BACK_2 0x5f
67#define RT1305_SILENCE_DETECT 0x60
68#define RT1305_ALC_DRC_1 0x62
69#define RT1305_ALC_DRC_2 0x63
70#define RT1305_ALC_DRC_3 0x64
71#define RT1305_ALC_DRC_4 0x65
72#define RT1305_PRIV_INDEX 0x6a
73#define RT1305_PRIV_DATA 0x6c
74#define RT1305_SPK_EXCURSION_LIMITER_7 0x76
75#define RT1305_VERSION_ID 0x7a
76#define RT1305_VENDOR_ID 0x7c
77#define RT1305_DEVICE_ID 0x7e
78#define RT1305_EFUSE_1 0x80
79#define RT1305_EFUSE_2 0x81
80#define RT1305_EFUSE_3 0x82
81#define RT1305_DC_CALIB_1 0x90
82#define RT1305_DC_CALIB_2 0x91
83#define RT1305_DC_CALIB_3 0x92
84#define RT1305_DAC_OFFSET_1 0x93
85#define RT1305_DAC_OFFSET_2 0x94
86#define RT1305_DAC_OFFSET_3 0x95
87#define RT1305_DAC_OFFSET_4 0x96
88#define RT1305_DAC_OFFSET_5 0x97
89#define RT1305_DAC_OFFSET_6 0x98
90#define RT1305_DAC_OFFSET_7 0x99
91#define RT1305_DAC_OFFSET_8 0x9a
92#define RT1305_DAC_OFFSET_9 0x9b
93#define RT1305_DAC_OFFSET_10 0x9c
94#define RT1305_DAC_OFFSET_11 0x9d
95#define RT1305_DAC_OFFSET_12 0x9e
96#define RT1305_DAC_OFFSET_13 0x9f
97#define RT1305_DAC_OFFSET_14 0xa0
98#define RT1305_TRIM_1 0xb0
99#define RT1305_TRIM_2 0xb1
100#define RT1305_TUNE_INTERNAL_OSC 0xb2
101#define RT1305_BIQUAD1_H0_L_28_16 0xc0
102#define RT1305_BIQUAD3_A2_R_15_0 0xfb
103#define RT1305_MAX_REG 0xff
104
105/* CLOCK-1 (0x04) */
106#define RT1305_SEL_PLL_SRC_2_MASK (0x1 << 15)
107#define RT1305_SEL_PLL_SRC_2_SFT 15
108#define RT1305_SEL_PLL_SRC_2_MCLK (0x0 << 15)
109#define RT1305_SEL_PLL_SRC_2_RCCLK (0x1 << 15)
110#define RT1305_DIV_PLL_SRC_2_MASK (0x3 << 13)
111#define RT1305_DIV_PLL_SRC_2_SFT 13
112#define RT1305_SEL_PLL_SRC_1_MASK (0x3 << 10)
113#define RT1305_SEL_PLL_SRC_1_SFT 10
114#define RT1305_SEL_PLL_SRC_1_PLL2 (0x0 << 10)
115#define RT1305_SEL_PLL_SRC_1_BCLK (0x1 << 10)
116#define RT1305_SEL_PLL_SRC_1_DFLL (0x2 << 10)
117#define RT1305_SEL_FS_SYS_PRE_MASK (0x3 << 8)
118#define RT1305_SEL_FS_SYS_PRE_SFT 8
119#define RT1305_SEL_FS_SYS_PRE_MCLK (0x0 << 8)
120#define RT1305_SEL_FS_SYS_PRE_PLL (0x1 << 8)
121#define RT1305_SEL_FS_SYS_PRE_RCCLK (0x2 << 8)
122#define RT1305_DIV_FS_SYS_MASK (0x7 << 4)
123#define RT1305_DIV_FS_SYS_SFT 4
124
125/* PLL1M/N/K Code-1 (0x0c) */
126#define RT1305_PLL_1_M_SFT 12
127#define RT1305_PLL_1_M_BYPASS_MASK (0x1 << 11)
128#define RT1305_PLL_1_M_BYPASS_SFT 11
129#define RT1305_PLL_1_M_BYPASS (0x1 << 11)
130#define RT1305_PLL_1_N_MASK (0x1ff << 0)
131
132/* DAC Setting (0x14) */
133#define RT1305_DVOL_MUTE_L_EN_SFT 15
134#define RT1305_DVOL_MUTE_R_EN_SFT 14
135
136/* I2S Setting-1 (0x2d) */
137#define RT1305_SEL_I2S_OUT_MODE_MASK (0x1 << 15)
138#define RT1305_SEL_I2S_OUT_MODE_SFT 15
139#define RT1305_SEL_I2S_OUT_MODE_S (0x0 << 15)
140#define RT1305_SEL_I2S_OUT_MODE_M (0x1 << 15)
141
142/* I2S Setting-2 (0x2e) */
143#define RT1305_I2S_DF_SEL_MASK (0x3 << 12)
144#define RT1305_I2S_DF_SEL_SFT 12
145#define RT1305_I2S_DF_SEL_I2S (0x0 << 12)
146#define RT1305_I2S_DF_SEL_LEFT (0x1 << 12)
147#define RT1305_I2S_DF_SEL_PCM_A (0x2 << 12)
148#define RT1305_I2S_DF_SEL_PCM_B (0x3 << 12)
149#define RT1305_I2S_DL_SEL_MASK (0x3 << 10)
150#define RT1305_I2S_DL_SEL_SFT 10
151#define RT1305_I2S_DL_SEL_16B (0x0 << 10)
152#define RT1305_I2S_DL_SEL_20B (0x1 << 10)
153#define RT1305_I2S_DL_SEL_24B (0x2 << 10)
154#define RT1305_I2S_DL_SEL_8B (0x3 << 10)
155#define RT1305_I2S_BCLK_MASK (0x1 << 9)
156#define RT1305_I2S_BCLK_SFT 9
157#define RT1305_I2S_BCLK_NORMAL (0x0 << 9)
158#define RT1305_I2S_BCLK_INV (0x1 << 9)
159
160/* Power Control-1 (0x3a) */
161#define RT1305_POW_PDB_JD_MASK (0x1 << 12)
162#define RT1305_POW_PDB_JD (0x1 << 12)
163#define RT1305_POW_PDB_JD_BIT 12
164#define RT1305_POW_PLL0_EN (0x1 << 11)
165#define RT1305_POW_PLL0_EN_BIT 11
166#define RT1305_POW_PLL1_EN (0x1 << 10)
167#define RT1305_POW_PLL1_EN_BIT 10
168#define RT1305_POW_PDB_JD_POLARITY (0x1 << 9)
169#define RT1305_POW_PDB_JD_POLARITY_BIT 9
170#define RT1305_POW_MBIAS_LV (0x1 << 8)
171#define RT1305_POW_MBIAS_LV_BIT 8
172#define RT1305_POW_BG_MBIAS_LV (0x1 << 7)
173#define RT1305_POW_BG_MBIAS_LV_BIT 7
174#define RT1305_POW_LDO2 (0x1 << 6)
175#define RT1305_POW_LDO2_BIT 6
176#define RT1305_POW_BG2 (0x1 << 5)
177#define RT1305_POW_BG2_BIT 5
178#define RT1305_POW_LDO2_IB2 (0x1 << 4)
179#define RT1305_POW_LDO2_IB2_BIT 4
180#define RT1305_POW_VREF (0x1 << 3)
181#define RT1305_POW_VREF_BIT 3
182#define RT1305_POW_VREF1 (0x1 << 2)
183#define RT1305_POW_VREF1_BIT 2
184#define RT1305_POW_VREF2 (0x1 << 1)
185#define RT1305_POW_VREF2_BIT 1
186
187/* Power Control-2 (0x3b) */
188#define RT1305_POW_DISC_VREF (1 << 15)
189#define RT1305_POW_DISC_VREF_BIT 15
190#define RT1305_POW_FASTB_VREF (1 << 14)
191#define RT1305_POW_FASTB_VREF_BIT 14
192#define RT1305_POW_ULTRA_FAST_VREF (1 << 13)
193#define RT1305_POW_ULTRA_FAST_VREF_BIT 13
194#define RT1305_POW_CKXEN_DAC (1 << 12)
195#define RT1305_POW_CKXEN_DAC_BIT 12
196#define RT1305_POW_EN_CKGEN_DAC (1 << 11)
197#define RT1305_POW_EN_CKGEN_DAC_BIT 11
198#define RT1305_POW_DAC1_L (1 << 10)
199#define RT1305_POW_DAC1_L_BIT 10
200#define RT1305_POW_DAC1_R (1 << 9)
201#define RT1305_POW_DAC1_R_BIT 9
202#define RT1305_POW_CLAMP (1 << 8)
203#define RT1305_POW_CLAMP_BIT 8
204#define RT1305_POW_BUFL (1 << 7)
205#define RT1305_POW_BUFL_BIT 7
206#define RT1305_POW_BUFR (1 << 6)
207#define RT1305_POW_BUFR_BIT 6
208#define RT1305_POW_EN_CKGEN_ADC (1 << 5)
209#define RT1305_POW_EN_CKGEN_ADC_BIT 5
210#define RT1305_POW_ADC3_L (1 << 4)
211#define RT1305_POW_ADC3_L_BIT 4
212#define RT1305_POW_ADC3_R (1 << 3)
213#define RT1305_POW_ADC3_R_BIT 3
214#define RT1305_POW_TRIOSC (1 << 2)
215#define RT1305_POW_TRIOSC_BIT 2
216#define RT1305_POR_AVDD1 (1 << 1)
217#define RT1305_POR_AVDD1_BIT 1
218#define RT1305_POR_AVDD2 (1 << 0)
219#define RT1305_POR_AVDD2_BIT 0
220
221/* Power Control-3 (0x3c) */
222#define RT1305_POW_VSENSE_RCH (1 << 15)
223#define RT1305_POW_VSENSE_RCH_BIT 15
224#define RT1305_POW_VSENSE_LCH (1 << 14)
225#define RT1305_POW_VSENSE_LCH_BIT 14
226#define RT1305_POW_ISENSE_RCH (1 << 13)
227#define RT1305_POW_ISENSE_RCH_BIT 13
228#define RT1305_POW_ISENSE_LCH (1 << 12)
229#define RT1305_POW_ISENSE_LCH_BIT 12
230#define RT1305_POW_POR_AVDD1 (1 << 11)
231#define RT1305_POW_POR_AVDD1_BIT 11
232#define RT1305_POW_POR_AVDD2 (1 << 10)
233#define RT1305_POW_POR_AVDD2_BIT 10
234#define RT1305_EN_K_HV (1 << 9)
235#define RT1305_EN_K_HV_BIT 9
236#define RT1305_EN_PRE_K_HV (1 << 8)
237#define RT1305_EN_PRE_K_HV_BIT 8
238#define RT1305_EN_EFUSE_1P8V (1 << 7)
239#define RT1305_EN_EFUSE_1P8V_BIT 7
240#define RT1305_EN_EFUSE_5V (1 << 6)
241#define RT1305_EN_EFUSE_5V_BIT 6
242#define RT1305_EN_VCM_6172 (1 << 5)
243#define RT1305_EN_VCM_6172_BIT 5
244#define RT1305_POR_EFUSE (1 << 4)
245#define RT1305_POR_EFUSE_BIT 4
246
247/* Clock Detect (0x3f) */
248#define RT1305_SEL_CLK_DET_SRC_MASK (0x1 << 12)
249#define RT1305_SEL_CLK_DET_SRC_SFT 12
250#define RT1305_SEL_CLK_DET_SRC_MCLK (0x0 << 12)
251#define RT1305_SEL_CLK_DET_SRC_BCLK (0x1 << 12)
252
253
254/* System Clock Source */
255enum {
256 RT1305_FS_SYS_PRE_S_MCLK,
257 RT1305_FS_SYS_PRE_S_PLL1,
258 RT1305_FS_SYS_PRE_S_RCCLK, /* 98.304M Hz */
259};
260
261/* PLL Source 1/2 */
262enum {
263 RT1305_PLL1_S_BCLK,
264 RT1305_PLL2_S_MCLK,
265 RT1305_PLL2_S_RCCLK, /* 98.304M Hz */
266};
267
268enum {
269 RT1305_AIF1,
270 RT1305_AIFS
271};
272
273#define R0_UPPER 0x2E8BA2 //5.5 ohm
274#define R0_LOWER 0x666666 //2.5 ohm
275
276#endif /* end of _RT1305_H_ */
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 05567426f211..8bf8d360c25f 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -24,6 +24,7 @@
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/jack.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
28#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
@@ -476,20 +477,6 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
476 return idx; 477 return idx;
477} 478}
478 479
479static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
480 struct snd_soc_dapm_widget *sink)
481{
482 struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
483 unsigned int val;
484
485 val = snd_soc_component_read32(component, RT5640_GLB_CLK);
486 val &= RT5640_SCLK_SRC_MASK;
487 if (val == RT5640_SCLK_SRC_PLL1)
488 return 1;
489 else
490 return 0;
491}
492
493static int is_using_asrc(struct snd_soc_dapm_widget *source, 480static int is_using_asrc(struct snd_soc_dapm_widget *source,
494 struct snd_soc_dapm_widget *sink) 481 struct snd_soc_dapm_widget *sink)
495{ 482{
@@ -1071,9 +1058,6 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
1071} 1058}
1072 1059
1073static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 1060static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1074 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
1075 RT5640_PWR_PLL_BIT, 0, NULL, 0),
1076
1077 /* ASRC */ 1061 /* ASRC */
1078 SND_SOC_DAPM_SUPPLY_S("Stereo Filter ASRC", 1, RT5640_ASRC_1, 1062 SND_SOC_DAPM_SUPPLY_S("Stereo Filter ASRC", 1, RT5640_ASRC_1,
1079 15, 0, NULL, 0), 1063 15, 0, NULL, 0),
@@ -1427,22 +1411,18 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1427 {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, 1411 {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"},
1428 {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, 1412 {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"},
1429 {"Stereo ADC MIXL", NULL, "Stereo Filter"}, 1413 {"Stereo ADC MIXL", NULL, "Stereo Filter"},
1430 {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
1431 1414
1432 {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, 1415 {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"},
1433 {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, 1416 {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"},
1434 {"Stereo ADC MIXR", NULL, "Stereo Filter"}, 1417 {"Stereo ADC MIXR", NULL, "Stereo Filter"},
1435 {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
1436 1418
1437 {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, 1419 {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"},
1438 {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, 1420 {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"},
1439 {"Mono ADC MIXL", NULL, "Mono Left Filter"}, 1421 {"Mono ADC MIXL", NULL, "Mono Left Filter"},
1440 {"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll},
1441 1422
1442 {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, 1423 {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"},
1443 {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, 1424 {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"},
1444 {"Mono ADC MIXR", NULL, "Mono Right Filter"}, 1425 {"Mono ADC MIXR", NULL, "Mono Right Filter"},
1445 {"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll},
1446 1426
1447 {"IF2 ADC L", NULL, "Mono ADC MIXL"}, 1427 {"IF2 ADC L", NULL, "Mono ADC MIXL"},
1448 {"IF2 ADC R", NULL, "Mono ADC MIXR"}, 1428 {"IF2 ADC R", NULL, "Mono ADC MIXR"},
@@ -1512,10 +1492,8 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1512 {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, 1492 {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"},
1513 1493
1514 {"DAC L1", NULL, "Stereo DAC MIXL"}, 1494 {"DAC L1", NULL, "Stereo DAC MIXL"},
1515 {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
1516 {"DAC L1", NULL, "DAC L1 Power"}, 1495 {"DAC L1", NULL, "DAC L1 Power"},
1517 {"DAC R1", NULL, "Stereo DAC MIXR"}, 1496 {"DAC R1", NULL, "Stereo DAC MIXR"},
1518 {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
1519 {"DAC R1", NULL, "DAC R1 Power"}, 1497 {"DAC R1", NULL, "DAC R1 Power"},
1520 1498
1521 {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, 1499 {"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
@@ -1622,10 +1600,8 @@ static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = {
1622 {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, 1600 {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
1623 1601
1624 {"DAC L2", NULL, "Mono DAC MIXL"}, 1602 {"DAC L2", NULL, "Mono DAC MIXL"},
1625 {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll},
1626 {"DAC L2", NULL, "DAC L2 Power"}, 1603 {"DAC L2", NULL, "DAC L2 Power"},
1627 {"DAC R2", NULL, "Mono DAC MIXR"}, 1604 {"DAC R2", NULL, "Mono DAC MIXR"},
1628 {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll},
1629 {"DAC R2", NULL, "DAC R2 Power"}, 1605 {"DAC R2", NULL, "DAC R2 Power"},
1630 1606
1631 {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, 1607 {"SPK MIXL", "DAC L2 Switch", "DAC L2"},
@@ -1861,6 +1837,7 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1861 struct snd_soc_component *component = dai->component; 1837 struct snd_soc_component *component = dai->component;
1862 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); 1838 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
1863 unsigned int reg_val = 0; 1839 unsigned int reg_val = 0;
1840 unsigned int pll_bit = 0;
1864 1841
1865 if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src) 1842 if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
1866 return 0; 1843 return 0;
@@ -1871,6 +1848,7 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1871 break; 1848 break;
1872 case RT5640_SCLK_S_PLL1: 1849 case RT5640_SCLK_S_PLL1:
1873 reg_val |= RT5640_SCLK_SRC_PLL1; 1850 reg_val |= RT5640_SCLK_SRC_PLL1;
1851 pll_bit |= RT5640_PWR_PLL;
1874 break; 1852 break;
1875 case RT5640_SCLK_S_RCCLK: 1853 case RT5640_SCLK_S_RCCLK:
1876 reg_val |= RT5640_SCLK_SRC_RCCLK; 1854 reg_val |= RT5640_SCLK_SRC_RCCLK;
@@ -1879,6 +1857,8 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
1879 dev_err(component->dev, "Invalid clock id (%d)\n", clk_id); 1857 dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
1880 return -EINVAL; 1858 return -EINVAL;
1881 } 1859 }
1860 snd_soc_component_update_bits(component, RT5640_PWR_ANLG2,
1861 RT5640_PWR_PLL, pll_bit);
1882 snd_soc_component_update_bits(component, RT5640_GLB_CLK, 1862 snd_soc_component_update_bits(component, RT5640_GLB_CLK,
1883 RT5640_SCLK_SRC_MASK, reg_val); 1863 RT5640_SCLK_SRC_MASK, reg_val);
1884 rt5640->sysclk = freq; 1864 rt5640->sysclk = freq;
@@ -2114,10 +2094,376 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
2114} 2094}
2115EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src); 2095EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
2116 2096
2097static void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
2098{
2099 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
2100
2101 snd_soc_dapm_mutex_lock(dapm);
2102 snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");
2103 snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS1");
2104 /* OVCD is unreliable when used with RCCLK as sysclk-source */
2105 snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
2106 snd_soc_dapm_sync_unlocked(dapm);
2107 snd_soc_dapm_mutex_unlock(dapm);
2108}
2109
2110static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component)
2111{
2112 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
2113
2114 snd_soc_dapm_mutex_lock(dapm);
2115 snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
2116 snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS1");
2117 snd_soc_dapm_disable_pin_unlocked(dapm, "LDO2");
2118 snd_soc_dapm_sync_unlocked(dapm);
2119 snd_soc_dapm_mutex_unlock(dapm);
2120}
2121
2122static void rt5640_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
2123{
2124 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2125
2126 snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
2127 RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_NOR);
2128 rt5640->ovcd_irq_enabled = true;
2129}
2130
2131static void rt5640_disable_micbias1_ovcd_irq(struct snd_soc_component *component)
2132{
2133 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2134
2135 snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
2136 RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_BP);
2137 rt5640->ovcd_irq_enabled = false;
2138}
2139
2140static void rt5640_clear_micbias1_ovcd(struct snd_soc_component *component)
2141{
2142 snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
2143 RT5640_MB1_OC_STATUS, 0);
2144}
2145
2146static bool rt5640_micbias1_ovcd(struct snd_soc_component *component)
2147{
2148 int val;
2149
2150 val = snd_soc_component_read32(component, RT5640_IRQ_CTRL2);
2151 dev_dbg(component->dev, "irq ctrl2 %#04x\n", val);
2152
2153 return (val & RT5640_MB1_OC_STATUS);
2154}
2155
2156static bool rt5640_jack_inserted(struct snd_soc_component *component)
2157{
2158 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2159 int val;
2160
2161 val = snd_soc_component_read32(component, RT5640_INT_IRQ_ST);
2162 dev_dbg(component->dev, "irq status %#04x\n", val);
2163
2164 if (rt5640->jd_inverted)
2165 return !(val & RT5640_JD_STATUS);
2166 else
2167 return (val & RT5640_JD_STATUS);
2168}
2169
2170/* Jack detect and button-press timings */
2171#define JACK_SETTLE_TIME 100 /* milli seconds */
2172#define JACK_DETECT_COUNT 5
2173#define JACK_DETECT_MAXCOUNT 20 /* Aprox. 2 seconds worth of tries */
2174#define JACK_UNPLUG_TIME 80 /* milli seconds */
2175#define BP_POLL_TIME 10 /* milli seconds */
2176#define BP_POLL_MAXCOUNT 200 /* assume something is wrong after this */
2177#define BP_THRESHOLD 3
2178
2179static void rt5640_start_button_press_work(struct snd_soc_component *component)
2180{
2181 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2182
2183 rt5640->poll_count = 0;
2184 rt5640->press_count = 0;
2185 rt5640->release_count = 0;
2186 rt5640->pressed = false;
2187 rt5640->press_reported = false;
2188 rt5640_clear_micbias1_ovcd(component);
2189 schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
2190}
2191
2192static void rt5640_button_press_work(struct work_struct *work)
2193{
2194 struct rt5640_priv *rt5640 =
2195 container_of(work, struct rt5640_priv, bp_work.work);
2196 struct snd_soc_component *component = rt5640->component;
2197
2198 /* Check the jack was not removed underneath us */
2199 if (!rt5640_jack_inserted(component))
2200 return;
2201
2202 if (rt5640_micbias1_ovcd(component)) {
2203 rt5640->release_count = 0;
2204 rt5640->press_count++;
2205 /* Remember till after JACK_UNPLUG_TIME wait */
2206 if (rt5640->press_count >= BP_THRESHOLD)
2207 rt5640->pressed = true;
2208 rt5640_clear_micbias1_ovcd(component);
2209 } else {
2210 rt5640->press_count = 0;
2211 rt5640->release_count++;
2212 }
2213
2214 /*
2215 * The pins get temporarily shorted on jack unplug, so we poll for
2216 * at least JACK_UNPLUG_TIME milli-seconds before reporting a press.
2217 */
2218 rt5640->poll_count++;
2219 if (rt5640->poll_count < (JACK_UNPLUG_TIME / BP_POLL_TIME)) {
2220 schedule_delayed_work(&rt5640->bp_work,
2221 msecs_to_jiffies(BP_POLL_TIME));
2222 return;
2223 }
2224
2225 if (rt5640->pressed && !rt5640->press_reported) {
2226 dev_dbg(component->dev, "headset button press\n");
2227 snd_soc_jack_report(rt5640->jack, SND_JACK_BTN_0,
2228 SND_JACK_BTN_0);
2229 rt5640->press_reported = true;
2230 }
2231
2232 if (rt5640->release_count >= BP_THRESHOLD) {
2233 if (rt5640->press_reported) {
2234 dev_dbg(component->dev, "headset button release\n");
2235 snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
2236 }
2237 /* Re-enable OVCD IRQ to detect next press */
2238 rt5640_enable_micbias1_ovcd_irq(component);
2239 return; /* Stop polling */
2240 }
2241
2242 schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
2243}
2244
2245static int rt5640_detect_headset(struct snd_soc_component *component)
2246{
2247 int i, headset_count = 0, headphone_count = 0;
2248
2249 /*
2250 * We get the insertion event before the jack is fully inserted at which
2251 * point the second ring on a TRRS connector may short the 2nd ring and
2252 * sleeve contacts, also the overcurrent detection is not entirely
2253 * reliable. So we try several times with a wait in between until we
2254 * detect the same type JACK_DETECT_COUNT times in a row.
2255 */
2256 for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) {
2257 /* Clear any previous over-current status flag */
2258 rt5640_clear_micbias1_ovcd(component);
2259
2260 msleep(JACK_SETTLE_TIME);
2261
2262 /* Check the jack is still connected before checking ovcd */
2263 if (!rt5640_jack_inserted(component))
2264 return 0;
2265
2266 if (rt5640_micbias1_ovcd(component)) {
2267 /*
2268 * Over current detected, there is a short between the
2269 * 2nd ring contact and the ground, so a TRS connector
2270 * without a mic contact and thus plain headphones.
2271 */
2272 dev_dbg(component->dev, "jack mic-gnd shorted\n");
2273 headset_count = 0;
2274 headphone_count++;
2275 if (headphone_count == JACK_DETECT_COUNT)
2276 return SND_JACK_HEADPHONE;
2277 } else {
2278 dev_dbg(component->dev, "jack mic-gnd open\n");
2279 headphone_count = 0;
2280 headset_count++;
2281 if (headset_count == JACK_DETECT_COUNT)
2282 return SND_JACK_HEADSET;
2283 }
2284 }
2285
2286 dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
2287 return SND_JACK_HEADPHONE;
2288}
2289
2290static void rt5640_jack_work(struct work_struct *work)
2291{
2292 struct rt5640_priv *rt5640 =
2293 container_of(work, struct rt5640_priv, jack_work);
2294 struct snd_soc_component *component = rt5640->component;
2295 int status;
2296
2297 if (!rt5640_jack_inserted(component)) {
2298 /* Jack removed, or spurious IRQ? */
2299 if (rt5640->jack->status & SND_JACK_HEADPHONE) {
2300 if (rt5640->jack->status & SND_JACK_MICROPHONE) {
2301 cancel_delayed_work_sync(&rt5640->bp_work);
2302 rt5640_disable_micbias1_ovcd_irq(component);
2303 rt5640_disable_micbias1_for_ovcd(component);
2304 }
2305 snd_soc_jack_report(rt5640->jack, 0,
2306 SND_JACK_HEADSET | SND_JACK_BTN_0);
2307 dev_dbg(component->dev, "jack unplugged\n");
2308 }
2309 } else if (!(rt5640->jack->status & SND_JACK_HEADPHONE)) {
2310 /* Jack inserted */
2311 WARN_ON(rt5640->ovcd_irq_enabled);
2312 rt5640_enable_micbias1_for_ovcd(component);
2313 status = rt5640_detect_headset(component);
2314 if (status == SND_JACK_HEADSET) {
2315 /* Enable ovcd IRQ for button press detect. */
2316 rt5640_enable_micbias1_ovcd_irq(component);
2317 } else {
2318 /* No more need for overcurrent detect. */
2319 rt5640_disable_micbias1_for_ovcd(component);
2320 }
2321 dev_dbg(component->dev, "detect status %#02x\n", status);
2322 snd_soc_jack_report(rt5640->jack, status, SND_JACK_HEADSET);
2323 } else if (rt5640->ovcd_irq_enabled && rt5640_micbias1_ovcd(component)) {
2324 dev_dbg(component->dev, "OVCD IRQ\n");
2325
2326 /*
2327 * The ovcd IRQ keeps firing while the button is pressed, so
2328 * we disable it and start polling the button until released.
2329 *
2330 * The disable will make the IRQ pin 0 again and since we get
2331 * IRQs on both edges (so as to detect both jack plugin and
2332 * unplug) this means we will immediately get another IRQ.
2333 * The ovcd_irq_enabled check above makes the 2ND IRQ a NOP.
2334 */
2335 rt5640_disable_micbias1_ovcd_irq(component);
2336 rt5640_start_button_press_work(component);
2337
2338 /*
2339 * If the jack-detect IRQ flag goes high (unplug) after our
2340 * above rt5640_jack_inserted() check and before we have
2341 * disabled the OVCD IRQ, the IRQ pin will stay high and as
2342 * we react to edges, we miss the unplug event -> recheck.
2343 */
2344 queue_work(system_long_wq, &rt5640->jack_work);
2345 }
2346}
2347
2348static irqreturn_t rt5640_irq(int irq, void *data)
2349{
2350 struct rt5640_priv *rt5640 = data;
2351
2352 if (rt5640->jack)
2353 queue_work(system_long_wq, &rt5640->jack_work);
2354
2355 return IRQ_HANDLED;
2356}
2357
2358static void rt5640_cancel_work(void *data)
2359{
2360 struct rt5640_priv *rt5640 = data;
2361
2362 cancel_work_sync(&rt5640->jack_work);
2363 cancel_delayed_work_sync(&rt5640->bp_work);
2364}
2365
2366static void rt5640_enable_jack_detect(struct snd_soc_component *component,
2367 struct snd_soc_jack *jack)
2368{
2369 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2370
2371 /* Select JD-source */
2372 snd_soc_component_update_bits(component, RT5640_JD_CTRL,
2373 RT5640_JD_MASK, rt5640->jd_src);
2374
2375 /* Selecting GPIO01 as an interrupt */
2376 snd_soc_component_update_bits(component, RT5640_GPIO_CTRL1,
2377 RT5640_GP1_PIN_MASK, RT5640_GP1_PIN_IRQ);
2378
2379 /* Set GPIO1 output */
2380 snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3,
2381 RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT);
2382
2383 /* Enabling jd2 in general control 1 */
2384 snd_soc_component_write(component, RT5640_DUMMY1, 0x3f41);
2385
2386 /* Enabling jd2 in general control 2 */
2387 snd_soc_component_write(component, RT5640_DUMMY2, 0x4001);
2388
2389 snd_soc_component_write(component, RT5640_PR_BASE + RT5640_BIAS_CUR4,
2390 0xa800 | rt5640->ovcd_sf);
2391
2392 snd_soc_component_update_bits(component, RT5640_MICBIAS,
2393 RT5640_MIC1_OVTH_MASK | RT5640_MIC1_OVCD_MASK,
2394 rt5640->ovcd_th | RT5640_MIC1_OVCD_EN);
2395
2396 /*
2397 * The over-current-detect is only reliable in detecting the absence
2398 * of over-current, when the mic-contact in the jack is short-circuited,
2399 * the hardware periodically retries if it can apply the bias-current
2400 * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
2401 * 10% of the time, as we poll the ovcd status bit we might hit that
2402 * 10%, so we enable sticky mode and when checking OVCD we clear the
2403 * status, msleep() a bit and then check to get a reliable reading.
2404 */
2405 snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
2406 RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
2407
2408 /*
2409 * All IRQs get or-ed together, so we need the jack IRQ to report 0
2410 * when a jack is inserted so that the OVCD IRQ then toggles the IRQ
2411 * pin 0/1 instead of it being stuck to 1. So we invert the JD polarity
2412 * on systems where the hardware does not already do this.
2413 */
2414 if (rt5640->jd_inverted)
2415 snd_soc_component_write(component, RT5640_IRQ_CTRL1,
2416 RT5640_IRQ_JD_NOR);
2417 else
2418 snd_soc_component_write(component, RT5640_IRQ_CTRL1,
2419 RT5640_IRQ_JD_NOR | RT5640_JD_P_INV);
2420
2421 rt5640->jack = jack;
2422 if (rt5640->jack->status & SND_JACK_MICROPHONE) {
2423 rt5640_enable_micbias1_for_ovcd(component);
2424 rt5640_enable_micbias1_ovcd_irq(component);
2425 }
2426
2427 enable_irq(rt5640->irq);
2428 /* sync initial jack state */
2429 queue_work(system_long_wq, &rt5640->jack_work);
2430}
2431
2432static void rt5640_disable_jack_detect(struct snd_soc_component *component)
2433{
2434 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2435
2436 disable_irq(rt5640->irq);
2437 rt5640_cancel_work(rt5640);
2438
2439 if (rt5640->jack->status & SND_JACK_MICROPHONE) {
2440 rt5640_disable_micbias1_ovcd_irq(component);
2441 rt5640_disable_micbias1_for_ovcd(component);
2442 snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
2443 }
2444
2445 rt5640->jack = NULL;
2446}
2447
2448static int rt5640_set_jack(struct snd_soc_component *component,
2449 struct snd_soc_jack *jack, void *data)
2450{
2451 if (jack)
2452 rt5640_enable_jack_detect(component, jack);
2453 else
2454 rt5640_disable_jack_detect(component);
2455
2456 return 0;
2457}
2458
2117static int rt5640_probe(struct snd_soc_component *component) 2459static int rt5640_probe(struct snd_soc_component *component)
2118{ 2460{
2119 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 2461 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
2120 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); 2462 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2463 u32 dmic1_data_pin = 0;
2464 u32 dmic2_data_pin = 0;
2465 bool dmic_en = false;
2466 u32 val;
2121 2467
2122 /* Check if MCLK provided */ 2468 /* Check if MCLK provided */
2123 rt5640->mclk = devm_clk_get(component->dev, "mclk"); 2469 rt5640->mclk = devm_clk_get(component->dev, "mclk");
@@ -2159,9 +2505,86 @@ static int rt5640_probe(struct snd_soc_component *component)
2159 return -ENODEV; 2505 return -ENODEV;
2160 } 2506 }
2161 2507
2162 if (rt5640->pdata.dmic_en) 2508 /*
2163 rt5640_dmic_enable(component, rt5640->pdata.dmic1_data_pin, 2509 * Note on some platforms the platform code may need to add device-props
2164 rt5640->pdata.dmic2_data_pin); 2510 * rather then relying only on properties set by the firmware.
2511 * Therefor the property parsing MUST be done here, rather then from
2512 * rt5640_i2c_probe(), so that the platform-code can attach extra
2513 * properties before calling snd_soc_register_card().
2514 */
2515 if (device_property_read_bool(component->dev, "realtek,in1-differential"))
2516 snd_soc_component_update_bits(component, RT5640_IN1_IN2,
2517 RT5640_IN_DF1, RT5640_IN_DF1);
2518
2519 if (device_property_read_bool(component->dev, "realtek,in2-differential"))
2520 snd_soc_component_update_bits(component, RT5640_IN3_IN4,
2521 RT5640_IN_DF2, RT5640_IN_DF2);
2522
2523 if (device_property_read_bool(component->dev, "realtek,in3-differential"))
2524 snd_soc_component_update_bits(component, RT5640_IN1_IN2,
2525 RT5640_IN_DF2, RT5640_IN_DF2);
2526
2527 if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin",
2528 &val) == 0 && val) {
2529 dmic1_data_pin = val - 1;
2530 dmic_en = true;
2531 }
2532
2533 if (device_property_read_u32(component->dev, "realtek,dmic2-data-pin",
2534 &val) == 0 && val) {
2535 dmic2_data_pin = val - 1;
2536 dmic_en = true;
2537 }
2538
2539 if (dmic_en)
2540 rt5640_dmic_enable(component, dmic1_data_pin, dmic2_data_pin);
2541
2542 if (device_property_read_u32(component->dev,
2543 "realtek,jack-detect-source", &val) == 0) {
2544 if (val <= RT5640_JD_SRC_GPIO4)
2545 rt5640->jd_src = val << RT5640_JD_SFT;
2546 else
2547 dev_warn(component->dev, "Warning: Invalid jack-detect-source value: %d, leaving jack-detect disabled\n",
2548 val);
2549 }
2550
2551 if (!device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted"))
2552 rt5640->jd_inverted = true;
2553
2554 /*
2555 * Testing on various boards has shown that good defaults for the OVCD
2556 * threshold and scale-factor are 2000µA and 0.75. For an effective
2557 * limit of 1500µA, this seems to be more reliable then 1500µA and 1.0.
2558 */
2559 rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
2560 rt5640->ovcd_sf = RT5640_MIC_OVCD_SF_0P75;
2561
2562 if (device_property_read_u32(component->dev,
2563 "realtek,over-current-threshold-microamp", &val) == 0) {
2564 switch (val) {
2565 case 600:
2566 rt5640->ovcd_th = RT5640_MIC1_OVTH_600UA;
2567 break;
2568 case 1500:
2569 rt5640->ovcd_th = RT5640_MIC1_OVTH_1500UA;
2570 break;
2571 case 2000:
2572 rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
2573 break;
2574 default:
2575 dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n",
2576 val);
2577 }
2578 }
2579
2580 if (device_property_read_u32(component->dev,
2581 "realtek,over-current-scale-factor", &val) == 0) {
2582 if (val <= RT5640_OVCD_SF_1P5)
2583 rt5640->ovcd_sf = val << RT5640_MIC_OVCD_SF_SFT;
2584 else
2585 dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n",
2586 val);
2587 }
2165 2588
2166 return 0; 2589 return 0;
2167} 2590}
@@ -2180,8 +2603,8 @@ static int rt5640_suspend(struct snd_soc_component *component)
2180 rt5640_reset(component); 2603 rt5640_reset(component);
2181 regcache_cache_only(rt5640->regmap, true); 2604 regcache_cache_only(rt5640->regmap, true);
2182 regcache_mark_dirty(rt5640->regmap); 2605 regcache_mark_dirty(rt5640->regmap);
2183 if (gpio_is_valid(rt5640->pdata.ldo1_en)) 2606 if (gpio_is_valid(rt5640->ldo1_en))
2184 gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 0); 2607 gpio_set_value_cansleep(rt5640->ldo1_en, 0);
2185 2608
2186 return 0; 2609 return 0;
2187} 2610}
@@ -2190,8 +2613,8 @@ static int rt5640_resume(struct snd_soc_component *component)
2190{ 2613{
2191 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); 2614 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
2192 2615
2193 if (gpio_is_valid(rt5640->pdata.ldo1_en)) { 2616 if (gpio_is_valid(rt5640->ldo1_en)) {
2194 gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 1); 2617 gpio_set_value_cansleep(rt5640->ldo1_en, 1);
2195 msleep(400); 2618 msleep(400);
2196 } 2619 }
2197 2620
@@ -2263,6 +2686,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt5640 = {
2263 .suspend = rt5640_suspend, 2686 .suspend = rt5640_suspend,
2264 .resume = rt5640_resume, 2687 .resume = rt5640_resume,
2265 .set_bias_level = rt5640_set_bias_level, 2688 .set_bias_level = rt5640_set_bias_level,
2689 .set_jack = rt5640_set_jack,
2266 .controls = rt5640_snd_controls, 2690 .controls = rt5640_snd_controls,
2267 .num_controls = ARRAY_SIZE(rt5640_snd_controls), 2691 .num_controls = ARRAY_SIZE(rt5640_snd_controls),
2268 .dapm_widgets = rt5640_dapm_widgets, 2692 .dapm_widgets = rt5640_dapm_widgets,
@@ -2323,22 +2747,16 @@ MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
2323 2747
2324static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np) 2748static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
2325{ 2749{
2326 rt5640->pdata.in1_diff = of_property_read_bool(np, 2750 rt5640->ldo1_en = of_get_named_gpio(np, "realtek,ldo1-en-gpios", 0);
2327 "realtek,in1-differential");
2328 rt5640->pdata.in2_diff = of_property_read_bool(np,
2329 "realtek,in2-differential");
2330
2331 rt5640->pdata.ldo1_en = of_get_named_gpio(np,
2332 "realtek,ldo1-en-gpios", 0);
2333 /* 2751 /*
2334 * LDO1_EN is optional (it may be statically tied on the board). 2752 * LDO1_EN is optional (it may be statically tied on the board).
2335 * -ENOENT means that the property doesn't exist, i.e. there is no 2753 * -ENOENT means that the property doesn't exist, i.e. there is no
2336 * GPIO, so is not an error. Any other error code means the property 2754 * GPIO, so is not an error. Any other error code means the property
2337 * exists, but could not be parsed. 2755 * exists, but could not be parsed.
2338 */ 2756 */
2339 if (!gpio_is_valid(rt5640->pdata.ldo1_en) && 2757 if (!gpio_is_valid(rt5640->ldo1_en) &&
2340 (rt5640->pdata.ldo1_en != -ENOENT)) 2758 (rt5640->ldo1_en != -ENOENT))
2341 return rt5640->pdata.ldo1_en; 2759 return rt5640->ldo1_en;
2342 2760
2343 return 0; 2761 return 0;
2344} 2762}
@@ -2346,7 +2764,6 @@ static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
2346static int rt5640_i2c_probe(struct i2c_client *i2c, 2764static int rt5640_i2c_probe(struct i2c_client *i2c,
2347 const struct i2c_device_id *id) 2765 const struct i2c_device_id *id)
2348{ 2766{
2349 struct rt5640_platform_data *pdata = dev_get_platdata(&i2c->dev);
2350 struct rt5640_priv *rt5640; 2767 struct rt5640_priv *rt5640;
2351 int ret; 2768 int ret;
2352 unsigned int val; 2769 unsigned int val;
@@ -2358,22 +2775,12 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2358 return -ENOMEM; 2775 return -ENOMEM;
2359 i2c_set_clientdata(i2c, rt5640); 2776 i2c_set_clientdata(i2c, rt5640);
2360 2777
2361 if (pdata) { 2778 if (i2c->dev.of_node) {
2362 rt5640->pdata = *pdata;
2363 /*
2364 * Translate zero'd out (default) pdata value to an invalid
2365 * GPIO ID. This makes the pdata and DT paths consistent in
2366 * terms of the value left in this field when no GPIO is
2367 * specified, but means we can't actually use GPIO 0.
2368 */
2369 if (!rt5640->pdata.ldo1_en)
2370 rt5640->pdata.ldo1_en = -EINVAL;
2371 } else if (i2c->dev.of_node) {
2372 ret = rt5640_parse_dt(rt5640, i2c->dev.of_node); 2779 ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
2373 if (ret) 2780 if (ret)
2374 return ret; 2781 return ret;
2375 } else 2782 } else
2376 rt5640->pdata.ldo1_en = -EINVAL; 2783 rt5640->ldo1_en = -EINVAL;
2377 2784
2378 rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap); 2785 rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
2379 if (IS_ERR(rt5640->regmap)) { 2786 if (IS_ERR(rt5640->regmap)) {
@@ -2383,13 +2790,13 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2383 return ret; 2790 return ret;
2384 } 2791 }
2385 2792
2386 if (gpio_is_valid(rt5640->pdata.ldo1_en)) { 2793 if (gpio_is_valid(rt5640->ldo1_en)) {
2387 ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en, 2794 ret = devm_gpio_request_one(&i2c->dev, rt5640->ldo1_en,
2388 GPIOF_OUT_INIT_HIGH, 2795 GPIOF_OUT_INIT_HIGH,
2389 "RT5640 LDO1_EN"); 2796 "RT5640 LDO1_EN");
2390 if (ret < 0) { 2797 if (ret < 0) {
2391 dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n", 2798 dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n",
2392 rt5640->pdata.ldo1_en, ret); 2799 rt5640->ldo1_en, ret);
2393 return ret; 2800 return ret;
2394 } 2801 }
2395 msleep(400); 2802 msleep(400);
@@ -2412,19 +2819,27 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2412 regmap_update_bits(rt5640->regmap, RT5640_DUMMY1, 2819 regmap_update_bits(rt5640->regmap, RT5640_DUMMY1,
2413 RT5640_MCLK_DET, RT5640_MCLK_DET); 2820 RT5640_MCLK_DET, RT5640_MCLK_DET);
2414 2821
2415 if (rt5640->pdata.in1_diff) 2822 rt5640->hp_mute = 1;
2416 regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2, 2823 rt5640->irq = i2c->irq;
2417 RT5640_IN_DF1, RT5640_IN_DF1); 2824 INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work);
2418 2825 INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
2419 if (rt5640->pdata.in2_diff)
2420 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2421 RT5640_IN_DF2, RT5640_IN_DF2);
2422 2826
2423 if (rt5640->pdata.in3_diff) 2827 /* Make sure work is stopped on probe-error / remove */
2424 regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2, 2828 ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
2425 RT5640_IN_DF2, RT5640_IN_DF2); 2829 if (ret)
2830 return ret;
2426 2831
2427 rt5640->hp_mute = 1; 2832 ret = devm_request_irq(&i2c->dev, rt5640->irq, rt5640_irq,
2833 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
2834 | IRQF_ONESHOT, "rt5640", rt5640);
2835 if (ret == 0) {
2836 /* Gets re-enabled by rt5640_set_jack() */
2837 disable_irq(rt5640->irq);
2838 } else {
2839 dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n",
2840 rt5640->irq, ret);
2841 rt5640->irq = -ENXIO;
2842 }
2428 2843
2429 return devm_snd_soc_register_component(&i2c->dev, 2844 return devm_snd_soc_register_component(&i2c->dev,
2430 &soc_component_dev_rt5640, 2845 &soc_component_dev_rt5640,
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c473e8ae2eda..e29e3e7d61b0 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -13,7 +13,8 @@
13#define _RT5640_H 13#define _RT5640_H
14 14
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <sound/rt5640.h> 16#include <linux/workqueue.h>
17#include <dt-bindings/sound/rt5640.h>
17 18
18/* Info */ 19/* Info */
19#define RT5640_RESET 0x00 20#define RT5640_RESET 0x00
@@ -146,6 +147,7 @@
146 147
147 148
148/* Index of Codec Private Register definition */ 149/* Index of Codec Private Register definition */
150#define RT5640_BIAS_CUR4 0x15
149#define RT5640_CHPUMP_INT_REG1 0x24 151#define RT5640_CHPUMP_INT_REG1 0x24
150#define RT5640_MAMP_INT_REG2 0x37 152#define RT5640_MAMP_INT_REG2 0x37
151#define RT5640_3D_SPK 0x63 153#define RT5640_3D_SPK 0x63
@@ -1607,10 +1609,17 @@
1607#define RT5640_MB2_OC_P_SFT 6 1609#define RT5640_MB2_OC_P_SFT 6
1608#define RT5640_MB2_OC_P_NOR (0x0 << 6) 1610#define RT5640_MB2_OC_P_NOR (0x0 << 6)
1609#define RT5640_MB2_OC_P_INV (0x1 << 6) 1611#define RT5640_MB2_OC_P_INV (0x1 << 6)
1610#define RT5640_MB1_OC_CLR (0x1 << 3) 1612#define RT5640_MB1_OC_STATUS (0x1 << 3)
1611#define RT5640_MB1_OC_CLR_SFT 3 1613#define RT5640_MB1_OC_STATUS_SFT 3
1612#define RT5640_MB2_OC_CLR (0x1 << 2) 1614#define RT5640_MB2_OC_STATUS (0x1 << 2)
1613#define RT5640_MB2_OC_CLR_SFT 2 1615#define RT5640_MB2_OC_STATUS_SFT 2
1616
1617/* GPIO and Internal Status (0xbf) */
1618#define RT5640_GPIO1_STATUS (0x1 << 8)
1619#define RT5640_GPIO2_STATUS (0x1 << 7)
1620#define RT5640_JD_STATUS (0x1 << 4)
1621#define RT5640_OVT_STATUS (0x1 << 3)
1622#define RT5640_CLS_D_OVCD_STATUS (0x1 << 0)
1614 1623
1615/* GPIO Control 1 (0xc0) */ 1624/* GPIO Control 1 (0xc0) */
1616#define RT5640_GP1_PIN_MASK (0x1 << 15) 1625#define RT5640_GP1_PIN_MASK (0x1 << 15)
@@ -1978,6 +1987,15 @@
1978#define RT5640_MCLK_DET (0x1 << 11) 1987#define RT5640_MCLK_DET (0x1 << 11)
1979 1988
1980/* Codec Private Register definition */ 1989/* Codec Private Register definition */
1990
1991/* MIC Over current threshold scale factor (0x15) */
1992#define RT5640_MIC_OVCD_SF_MASK (0x3 << 8)
1993#define RT5640_MIC_OVCD_SF_SFT 8
1994#define RT5640_MIC_OVCD_SF_0P5 (0x0 << 8)
1995#define RT5640_MIC_OVCD_SF_0P75 (0x1 << 8)
1996#define RT5640_MIC_OVCD_SF_1P0 (0x2 << 8)
1997#define RT5640_MIC_OVCD_SF_1P5 (0x3 << 8)
1998
1981/* 3D Speaker Control (0x63) */ 1999/* 3D Speaker Control (0x63) */
1982#define RT5640_3D_SPK_MASK (0x1 << 15) 2000#define RT5640_3D_SPK_MASK (0x1 << 15)
1983#define RT5640_3D_SPK_SFT 15 2001#define RT5640_3D_SPK_SFT 15
@@ -2103,10 +2121,11 @@ enum {
2103 2121
2104struct rt5640_priv { 2122struct rt5640_priv {
2105 struct snd_soc_component *component; 2123 struct snd_soc_component *component;
2106 struct rt5640_platform_data pdata;
2107 struct regmap *regmap; 2124 struct regmap *regmap;
2108 struct clk *mclk; 2125 struct clk *mclk;
2109 2126
2127 int ldo1_en; /* GPIO for LDO1_EN */
2128 int irq;
2110 int sysclk; 2129 int sysclk;
2111 int sysclk_src; 2130 int sysclk_src;
2112 int lrck[RT5640_AIFS]; 2131 int lrck[RT5640_AIFS];
@@ -2119,6 +2138,21 @@ struct rt5640_priv {
2119 2138
2120 bool hp_mute; 2139 bool hp_mute;
2121 bool asrc_en; 2140 bool asrc_en;
2141
2142 /* Jack and button detect data */
2143 bool ovcd_irq_enabled;
2144 bool pressed;
2145 bool press_reported;
2146 int press_count;
2147 int release_count;
2148 int poll_count;
2149 struct delayed_work bp_work;
2150 struct work_struct jack_work;
2151 struct snd_soc_jack *jack;
2152 unsigned int jd_src;
2153 bool jd_inverted;
2154 unsigned int ovcd_th;
2155 unsigned int ovcd_sf;
2122}; 2156};
2123 2157
2124int rt5640_dmic_enable(struct snd_soc_component *component, 2158int rt5640_dmic_enable(struct snd_soc_component *component,
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index bc8d829ce45b..712384581ebf 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3652,6 +3652,11 @@ static const struct rt5645_platform_data asus_t100ha_platform_data = {
3652 .inv_jd1_1 = true, 3652 .inv_jd1_1 = true,
3653}; 3653};
3654 3654
3655static const struct rt5645_platform_data lenovo_ideapad_miix_310_pdata = {
3656 .jd_mode = 3,
3657 .in2_diff = true,
3658};
3659
3655static const struct rt5645_platform_data jd_mode3_platform_data = { 3660static const struct rt5645_platform_data jd_mode3_platform_data = {
3656 .jd_mode = 3, 3661 .jd_mode = 3,
3657}; 3662};
@@ -3735,6 +3740,24 @@ static const struct dmi_system_id dmi_platform_data[] = {
3735 }, 3740 },
3736 .driver_data = (void *)&jd_mode3_platform_data, 3741 .driver_data = (void *)&jd_mode3_platform_data,
3737 }, 3742 },
3743 {
3744 .ident = "Lenovo Ideapad Miix 310",
3745 .matches = {
3746 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
3747 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80SG"),
3748 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
3749 },
3750 .driver_data = (void *)&lenovo_ideapad_miix_310_pdata,
3751 },
3752 {
3753 .ident = "Lenovo Ideapad Miix 320",
3754 .matches = {
3755 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
3756 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
3757 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
3758 },
3759 .driver_data = (void *)&intel_braswell_platform_data,
3760 },
3738 { } 3761 { }
3739}; 3762};
3740 3763
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index 20c0aeea6ca3..9bd24ad42240 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -72,6 +72,8 @@ struct rt5663_priv {
72static const struct reg_sequence rt5663_patch_list[] = { 72static const struct reg_sequence rt5663_patch_list[] = {
73 { 0x002a, 0x8020 }, 73 { 0x002a, 0x8020 },
74 { 0x0086, 0x0028 }, 74 { 0x0086, 0x0028 },
75 { 0x0117, 0x0f28 },
76 { 0x02fb, 0x8089 },
75}; 77};
76 78
77static const struct reg_default rt5663_v2_reg[] = { 79static const struct reg_default rt5663_v2_reg[] = {
@@ -593,7 +595,7 @@ static const struct reg_default rt5663_reg[] = {
593 { 0x0113, 0x2000 }, 595 { 0x0113, 0x2000 },
594 { 0x0114, 0x0000 }, 596 { 0x0114, 0x0000 },
595 { 0x0116, 0x0000 }, 597 { 0x0116, 0x0000 },
596 { 0x0117, 0x0f00 }, 598 { 0x0117, 0x0f28 },
597 { 0x0118, 0x0006 }, 599 { 0x0118, 0x0006 },
598 { 0x0125, 0x2424 }, 600 { 0x0125, 0x2424 },
599 { 0x0126, 0x5550 }, 601 { 0x0126, 0x5550 },
@@ -693,7 +695,7 @@ static const struct reg_default rt5663_reg[] = {
693 { 0x0251, 0x0000 }, 695 { 0x0251, 0x0000 },
694 { 0x0252, 0x028a }, 696 { 0x0252, 0x028a },
695 { 0x02fa, 0x0000 }, 697 { 0x02fa, 0x0000 },
696 { 0x02fb, 0x00a4 }, 698 { 0x02fb, 0x8089 },
697 { 0x02fc, 0x0300 }, 699 { 0x02fc, 0x0300 },
698 { 0x0300, 0x0000 }, 700 { 0x0300, 0x0000 },
699 { 0x03d0, 0x0000 }, 701 { 0x03d0, 0x0000 },
@@ -1556,6 +1558,14 @@ static int rt5663_jack_detect(struct snd_soc_component *component, int jack_inse
1556 RT5663_PWR_MB_MASK | RT5663_LDO1_DVO_MASK | 1558 RT5663_PWR_MB_MASK | RT5663_LDO1_DVO_MASK |
1557 RT5663_AMP_HP_MASK, RT5663_PWR_MB | 1559 RT5663_AMP_HP_MASK, RT5663_PWR_MB |
1558 RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X); 1560 RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X);
1561 snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
1562 RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
1563 RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
1564 RT5663_PWR_VREF1 | RT5663_PWR_VREF2);
1565 msleep(20);
1566 snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
1567 RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
1568 RT5663_PWR_FV1 | RT5663_PWR_FV2);
1559 snd_soc_component_update_bits(component, RT5663_AUTO_1MRC_CLK, 1569 snd_soc_component_update_bits(component, RT5663_AUTO_1MRC_CLK,
1560 RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); 1570 RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN);
1561 snd_soc_component_update_bits(component, RT5663_IRQ_1, 1571 snd_soc_component_update_bits(component, RT5663_IRQ_1,
@@ -1613,7 +1623,10 @@ static int rt5663_jack_detect(struct snd_soc_component *component, int jack_inse
1613 break; 1623 break;
1614 default: 1624 default:
1615 rt5663->jack_type = SND_JACK_HEADPHONE; 1625 rt5663->jack_type = SND_JACK_HEADPHONE;
1616 1626 snd_soc_component_update_bits(component,
1627 RT5663_PWR_ANLG_1,
1628 RT5663_PWR_MB_MASK | RT5663_PWR_VREF1_MASK |
1629 RT5663_PWR_VREF2_MASK, 0);
1617 if (rt5663->pdata.impedance_sensing_num) 1630 if (rt5663->pdata.impedance_sensing_num)
1618 break; 1631 break;
1619 1632
@@ -1638,6 +1651,9 @@ static int rt5663_jack_detect(struct snd_soc_component *component, int jack_inse
1638 if (rt5663->jack_type == SND_JACK_HEADSET) 1651 if (rt5663->jack_type == SND_JACK_HEADSET)
1639 rt5663_enable_push_button_irq(component, false); 1652 rt5663_enable_push_button_irq(component, false);
1640 rt5663->jack_type = 0; 1653 rt5663->jack_type = 0;
1654 snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1,
1655 RT5663_PWR_MB_MASK | RT5663_PWR_VREF1_MASK |
1656 RT5663_PWR_VREF2_MASK, 0);
1641 } 1657 }
1642 1658
1643 dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type); 1659 dev_dbg(component->dev, "jack_type = %d\n", rt5663->jack_type);
@@ -1840,8 +1856,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
1840 return IRQ_HANDLED; 1856 return IRQ_HANDLED;
1841} 1857}
1842 1858
1843int rt5663_set_jack_detect(struct snd_soc_component *component, 1859static int rt5663_set_jack_detect(struct snd_soc_component *component,
1844 struct snd_soc_jack *hs_jack) 1860 struct snd_soc_jack *hs_jack, void *data)
1845{ 1861{
1846 struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); 1862 struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
1847 1863
@@ -1851,7 +1867,6 @@ int rt5663_set_jack_detect(struct snd_soc_component *component,
1851 1867
1852 return 0; 1868 return 0;
1853} 1869}
1854EXPORT_SYMBOL_GPL(rt5663_set_jack_detect);
1855 1870
1856static bool rt5663_check_jd_status(struct snd_soc_component *component) 1871static bool rt5663_check_jd_status(struct snd_soc_component *component)
1857{ 1872{
@@ -2307,6 +2322,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
2307 RT5663_HP_SIG_SRC1_MASK, 2322 RT5663_HP_SIG_SRC1_MASK,
2308 RT5663_HP_SIG_SRC1_SILENCE); 2323 RT5663_HP_SIG_SRC1_SILENCE);
2309 } else { 2324 } else {
2325 snd_soc_component_update_bits(component,
2326 RT5663_DACREF_LDO, 0x3e0e, 0x3a0a);
2310 snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003); 2327 snd_soc_component_write(component, RT5663_DEPOP_2, 0x3003);
2311 snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1, 2328 snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
2312 RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS); 2329 RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS);
@@ -2332,6 +2349,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
2332 snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x0); 2349 snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0x0);
2333 snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1, 2350 snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1,
2334 RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); 2351 RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN);
2352 snd_soc_component_update_bits(component,
2353 RT5663_DACREF_LDO, 0x3e0e, 0);
2335 } 2354 }
2336 break; 2355 break;
2337 2356
@@ -3086,9 +3105,17 @@ static int rt5663_set_bias_level(struct snd_soc_component *component,
3086 break; 3105 break;
3087 3106
3088 case SND_SOC_BIAS_OFF: 3107 case SND_SOC_BIAS_OFF:
3089 snd_soc_component_update_bits(component, RT5663_PWR_ANLG_1, 3108 if (rt5663->jack_type != SND_JACK_HEADSET)
3090 RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK | 3109 snd_soc_component_update_bits(component,
3091 RT5663_PWR_FV1 | RT5663_PWR_FV2, 0x0); 3110 RT5663_PWR_ANLG_1,
3111 RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
3112 RT5663_PWR_FV1 | RT5663_PWR_FV2 |
3113 RT5663_PWR_MB_MASK, 0);
3114 else
3115 snd_soc_component_update_bits(component,
3116 RT5663_PWR_ANLG_1,
3117 RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
3118 RT5663_PWR_FV1 | RT5663_PWR_FV2);
3092 break; 3119 break;
3093 3120
3094 default: 3121 default:
@@ -3216,10 +3243,10 @@ static const struct snd_soc_component_driver soc_component_dev_rt5663 = {
3216 .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets), 3243 .num_dapm_widgets = ARRAY_SIZE(rt5663_dapm_widgets),
3217 .dapm_routes = rt5663_dapm_routes, 3244 .dapm_routes = rt5663_dapm_routes,
3218 .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes), 3245 .num_dapm_routes = ARRAY_SIZE(rt5663_dapm_routes),
3246 .set_jack = rt5663_set_jack_detect,
3219 .use_pmdown_time = 1, 3247 .use_pmdown_time = 1,
3220 .endianness = 1, 3248 .endianness = 1,
3221 .non_legacy_dai_naming = 1, 3249 .non_legacy_dai_naming = 1,
3222
3223}; 3250};
3224 3251
3225static const struct regmap_config rt5663_v2_regmap = { 3252static const struct regmap_config rt5663_v2_regmap = {
@@ -3310,6 +3337,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
3310 regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c); 3337 regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c);
3311 regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324); 3338 regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324);
3312 regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); 3339 regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001);
3340 regmap_write(rt5663->regmap, RT5663_VREFADJ_OP, 0x0f28);
3313 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b); 3341 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b);
3314 msleep(30); 3342 msleep(30);
3315 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b); 3343 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b);
@@ -3344,6 +3372,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
3344 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003); 3372 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003);
3345 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); 3373 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c);
3346 regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); 3374 regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32);
3375 regmap_write(rt5663->regmap, RT5663_DUMMY_2, 0x8089);
3347 regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b); 3376 regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b);
3348 msleep(40); 3377 msleep(40);
3349 regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000); 3378 regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000);
@@ -3578,15 +3607,9 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
3578 regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, 3607 regmap_update_bits(rt5663->regmap, RT5663_GPIO_1,
3579 RT5663_GPIO1_TYPE_MASK, RT5663_GPIO1_TYPE_EN); 3608 RT5663_GPIO1_TYPE_MASK, RT5663_GPIO1_TYPE_EN);
3580 regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); 3609 regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032);
3581 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be);
3582 msleep(20);
3583 regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be);
3584 regmap_update_bits(rt5663->regmap, RT5663_GPIO_2, 3610 regmap_update_bits(rt5663->regmap, RT5663_GPIO_2,
3585 RT5663_GP1_PIN_CONF_MASK | RT5663_SEL_GPIO1_MASK, 3611 RT5663_GP1_PIN_CONF_MASK | RT5663_SEL_GPIO1_MASK,
3586 RT5663_GP1_PIN_CONF_OUTPUT | RT5663_SEL_GPIO1_EN); 3612 RT5663_GP1_PIN_CONF_OUTPUT | RT5663_SEL_GPIO1_EN);
3587 /* DACREF LDO control */
3588 regmap_update_bits(rt5663->regmap, RT5663_DACREF_LDO, 0x3e0e,
3589 0x3a0a);
3590 regmap_update_bits(rt5663->regmap, RT5663_RECMIX, 3613 regmap_update_bits(rt5663->regmap, RT5663_RECMIX,
3591 RT5663_RECMIX1_BST1_MASK, RT5663_RECMIX1_BST1_ON); 3614 RT5663_RECMIX1_BST1_MASK, RT5663_RECMIX1_BST1_ON);
3592 regmap_update_bits(rt5663->regmap, RT5663_TDM_2, 3615 regmap_update_bits(rt5663->regmap, RT5663_TDM_2,
diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h
index 865203cc2034..794cf3fadf31 100644
--- a/sound/soc/codecs/rt5663.h
+++ b/sound/soc/codecs/rt5663.h
@@ -1125,8 +1125,6 @@ enum {
1125 RT5663_AD_STEREO_FILTER = 0x2, 1125 RT5663_AD_STEREO_FILTER = 0x2,
1126}; 1126};
1127 1127
1128int rt5663_set_jack_detect(struct snd_soc_component *component,
1129 struct snd_soc_jack *hs_jack);
1130int rt5663_sel_asrc_clk_src(struct snd_soc_component *component, 1128int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
1131 unsigned int filter_mask, unsigned int clk_src); 1129 unsigned int filter_mask, unsigned int clk_src);
1132 1130
diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c
new file mode 100644
index 000000000000..3c19d03f2446
--- /dev/null
+++ b/sound/soc/codecs/rt5668.c
@@ -0,0 +1,2639 @@
1/*
2 * rt5668.c -- RT5668B ALSA SoC audio component driver
3 *
4 * Copyright 2018 Realtek Semiconductor Corp.
5 * Author: Bard Liao <bardliao@realtek.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
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/spi/spi.h>
20#include <linux/acpi.h>
21#include <linux/gpio.h>
22#include <linux/of_gpio.h>
23#include <linux/regulator/consumer.h>
24#include <linux/mutex.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/jack.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33#include <sound/rt5668.h>
34
35#include "rl6231.h"
36#include "rt5668.h"
37
38#define RT5668_NUM_SUPPLIES 3
39
40static const char *rt5668_supply_names[RT5668_NUM_SUPPLIES] = {
41 "AVDD",
42 "MICVDD",
43 "VBAT",
44};
45
46struct rt5668_priv {
47 struct snd_soc_component *component;
48 struct rt5668_platform_data pdata;
49 struct regmap *regmap;
50 struct snd_soc_jack *hs_jack;
51 struct regulator_bulk_data supplies[RT5668_NUM_SUPPLIES];
52 struct delayed_work jack_detect_work;
53 struct delayed_work jd_check_work;
54 struct mutex calibrate_mutex;
55
56 int sysclk;
57 int sysclk_src;
58 int lrck[RT5668_AIFS];
59 int bclk[RT5668_AIFS];
60 int master[RT5668_AIFS];
61
62 int pll_src;
63 int pll_in;
64 int pll_out;
65
66 int jack_type;
67};
68
69static const struct reg_default rt5668_reg[] = {
70 {0x0002, 0x8080},
71 {0x0003, 0x8000},
72 {0x0005, 0x0000},
73 {0x0006, 0x0000},
74 {0x0008, 0x800f},
75 {0x000b, 0x0000},
76 {0x0010, 0x4040},
77 {0x0011, 0x0000},
78 {0x0012, 0x1404},
79 {0x0013, 0x1000},
80 {0x0014, 0xa00a},
81 {0x0015, 0x0404},
82 {0x0016, 0x0404},
83 {0x0019, 0xafaf},
84 {0x001c, 0x2f2f},
85 {0x001f, 0x0000},
86 {0x0022, 0x5757},
87 {0x0023, 0x0039},
88 {0x0024, 0x000b},
89 {0x0026, 0xc0c4},
90 {0x0029, 0x8080},
91 {0x002a, 0xa0a0},
92 {0x002b, 0x0300},
93 {0x0030, 0x0000},
94 {0x003c, 0x0080},
95 {0x0044, 0x0c0c},
96 {0x0049, 0x0000},
97 {0x0061, 0x0000},
98 {0x0062, 0x0000},
99 {0x0063, 0x003f},
100 {0x0064, 0x0000},
101 {0x0065, 0x0000},
102 {0x0066, 0x0030},
103 {0x0067, 0x0000},
104 {0x006b, 0x0000},
105 {0x006c, 0x0000},
106 {0x006d, 0x2200},
107 {0x006e, 0x0a10},
108 {0x0070, 0x8000},
109 {0x0071, 0x8000},
110 {0x0073, 0x0000},
111 {0x0074, 0x0000},
112 {0x0075, 0x0002},
113 {0x0076, 0x0001},
114 {0x0079, 0x0000},
115 {0x007a, 0x0000},
116 {0x007b, 0x0000},
117 {0x007c, 0x0100},
118 {0x007e, 0x0000},
119 {0x0080, 0x0000},
120 {0x0081, 0x0000},
121 {0x0082, 0x0000},
122 {0x0083, 0x0000},
123 {0x0084, 0x0000},
124 {0x0085, 0x0000},
125 {0x0086, 0x0005},
126 {0x0087, 0x0000},
127 {0x0088, 0x0000},
128 {0x008c, 0x0003},
129 {0x008d, 0x0000},
130 {0x008e, 0x0060},
131 {0x008f, 0x1000},
132 {0x0091, 0x0c26},
133 {0x0092, 0x0073},
134 {0x0093, 0x0000},
135 {0x0094, 0x0080},
136 {0x0098, 0x0000},
137 {0x009a, 0x0000},
138 {0x009b, 0x0000},
139 {0x009c, 0x0000},
140 {0x009d, 0x0000},
141 {0x009e, 0x100c},
142 {0x009f, 0x0000},
143 {0x00a0, 0x0000},
144 {0x00a3, 0x0002},
145 {0x00a4, 0x0001},
146 {0x00ae, 0x2040},
147 {0x00af, 0x0000},
148 {0x00b6, 0x0000},
149 {0x00b7, 0x0000},
150 {0x00b8, 0x0000},
151 {0x00b9, 0x0002},
152 {0x00be, 0x0000},
153 {0x00c0, 0x0160},
154 {0x00c1, 0x82a0},
155 {0x00c2, 0x0000},
156 {0x00d0, 0x0000},
157 {0x00d1, 0x2244},
158 {0x00d2, 0x3300},
159 {0x00d3, 0x2200},
160 {0x00d4, 0x0000},
161 {0x00d9, 0x0009},
162 {0x00da, 0x0000},
163 {0x00db, 0x0000},
164 {0x00dc, 0x00c0},
165 {0x00dd, 0x2220},
166 {0x00de, 0x3131},
167 {0x00df, 0x3131},
168 {0x00e0, 0x3131},
169 {0x00e2, 0x0000},
170 {0x00e3, 0x4000},
171 {0x00e4, 0x0aa0},
172 {0x00e5, 0x3131},
173 {0x00e6, 0x3131},
174 {0x00e7, 0x3131},
175 {0x00e8, 0x3131},
176 {0x00ea, 0xb320},
177 {0x00eb, 0x0000},
178 {0x00f0, 0x0000},
179 {0x00f1, 0x00d0},
180 {0x00f2, 0x00d0},
181 {0x00f6, 0x0000},
182 {0x00fa, 0x0000},
183 {0x00fb, 0x0000},
184 {0x00fc, 0x0000},
185 {0x00fd, 0x0000},
186 {0x00fe, 0x10ec},
187 {0x00ff, 0x6530},
188 {0x0100, 0xa0a0},
189 {0x010b, 0x0000},
190 {0x010c, 0xae00},
191 {0x010d, 0xaaa0},
192 {0x010e, 0x8aa2},
193 {0x010f, 0x02a2},
194 {0x0110, 0xc000},
195 {0x0111, 0x04a2},
196 {0x0112, 0x2800},
197 {0x0113, 0x0000},
198 {0x0117, 0x0100},
199 {0x0125, 0x0410},
200 {0x0132, 0x6026},
201 {0x0136, 0x5555},
202 {0x0138, 0x3700},
203 {0x013a, 0x2000},
204 {0x013b, 0x2000},
205 {0x013c, 0x2005},
206 {0x013f, 0x0000},
207 {0x0142, 0x0000},
208 {0x0145, 0x0002},
209 {0x0146, 0x0000},
210 {0x0147, 0x0000},
211 {0x0148, 0x0000},
212 {0x0149, 0x0000},
213 {0x0150, 0x79a1},
214 {0x0151, 0x0000},
215 {0x0160, 0x4ec0},
216 {0x0161, 0x0080},
217 {0x0162, 0x0200},
218 {0x0163, 0x0800},
219 {0x0164, 0x0000},
220 {0x0165, 0x0000},
221 {0x0166, 0x0000},
222 {0x0167, 0x000f},
223 {0x0168, 0x000f},
224 {0x0169, 0x0021},
225 {0x0190, 0x413d},
226 {0x0194, 0x0000},
227 {0x0195, 0x0000},
228 {0x0197, 0x0022},
229 {0x0198, 0x0000},
230 {0x0199, 0x0000},
231 {0x01af, 0x0000},
232 {0x01b0, 0x0400},
233 {0x01b1, 0x0000},
234 {0x01b2, 0x0000},
235 {0x01b3, 0x0000},
236 {0x01b4, 0x0000},
237 {0x01b5, 0x0000},
238 {0x01b6, 0x01c3},
239 {0x01b7, 0x02a0},
240 {0x01b8, 0x03e9},
241 {0x01b9, 0x1389},
242 {0x01ba, 0xc351},
243 {0x01bb, 0x0009},
244 {0x01bc, 0x0018},
245 {0x01bd, 0x002a},
246 {0x01be, 0x004c},
247 {0x01bf, 0x0097},
248 {0x01c0, 0x433d},
249 {0x01c1, 0x2800},
250 {0x01c2, 0x0000},
251 {0x01c3, 0x0000},
252 {0x01c4, 0x0000},
253 {0x01c5, 0x0000},
254 {0x01c6, 0x0000},
255 {0x01c7, 0x0000},
256 {0x01c8, 0x40af},
257 {0x01c9, 0x0702},
258 {0x01ca, 0x0000},
259 {0x01cb, 0x0000},
260 {0x01cc, 0x5757},
261 {0x01cd, 0x5757},
262 {0x01ce, 0x5757},
263 {0x01cf, 0x5757},
264 {0x01d0, 0x5757},
265 {0x01d1, 0x5757},
266 {0x01d2, 0x5757},
267 {0x01d3, 0x5757},
268 {0x01d4, 0x5757},
269 {0x01d5, 0x5757},
270 {0x01d6, 0x0000},
271 {0x01d7, 0x0008},
272 {0x01d8, 0x0029},
273 {0x01d9, 0x3333},
274 {0x01da, 0x0000},
275 {0x01db, 0x0004},
276 {0x01dc, 0x0000},
277 {0x01de, 0x7c00},
278 {0x01df, 0x0320},
279 {0x01e0, 0x06a1},
280 {0x01e1, 0x0000},
281 {0x01e2, 0x0000},
282 {0x01e3, 0x0000},
283 {0x01e4, 0x0000},
284 {0x01e6, 0x0001},
285 {0x01e7, 0x0000},
286 {0x01e8, 0x0000},
287 {0x01ea, 0x0000},
288 {0x01eb, 0x0000},
289 {0x01ec, 0x0000},
290 {0x01ed, 0x0000},
291 {0x01ee, 0x0000},
292 {0x01ef, 0x0000},
293 {0x01f0, 0x0000},
294 {0x01f1, 0x0000},
295 {0x01f2, 0x0000},
296 {0x01f3, 0x0000},
297 {0x01f4, 0x0000},
298 {0x0210, 0x6297},
299 {0x0211, 0xa005},
300 {0x0212, 0x824c},
301 {0x0213, 0xf7ff},
302 {0x0214, 0xf24c},
303 {0x0215, 0x0102},
304 {0x0216, 0x00a3},
305 {0x0217, 0x0048},
306 {0x0218, 0xa2c0},
307 {0x0219, 0x0400},
308 {0x021a, 0x00c8},
309 {0x021b, 0x00c0},
310 {0x021c, 0x0000},
311 {0x0250, 0x4500},
312 {0x0251, 0x40b3},
313 {0x0252, 0x0000},
314 {0x0253, 0x0000},
315 {0x0254, 0x0000},
316 {0x0255, 0x0000},
317 {0x0256, 0x0000},
318 {0x0257, 0x0000},
319 {0x0258, 0x0000},
320 {0x0259, 0x0000},
321 {0x025a, 0x0005},
322 {0x0270, 0x0000},
323 {0x02ff, 0x0110},
324 {0x0300, 0x001f},
325 {0x0301, 0x032c},
326 {0x0302, 0x5f21},
327 {0x0303, 0x4000},
328 {0x0304, 0x4000},
329 {0x0305, 0x06d5},
330 {0x0306, 0x8000},
331 {0x0307, 0x0700},
332 {0x0310, 0x4560},
333 {0x0311, 0xa4a8},
334 {0x0312, 0x7418},
335 {0x0313, 0x0000},
336 {0x0314, 0x0006},
337 {0x0315, 0xffff},
338 {0x0316, 0xc400},
339 {0x0317, 0x0000},
340 {0x03c0, 0x7e00},
341 {0x03c1, 0x8000},
342 {0x03c2, 0x8000},
343 {0x03c3, 0x8000},
344 {0x03c4, 0x8000},
345 {0x03c5, 0x8000},
346 {0x03c6, 0x8000},
347 {0x03c7, 0x8000},
348 {0x03c8, 0x8000},
349 {0x03c9, 0x8000},
350 {0x03ca, 0x8000},
351 {0x03cb, 0x8000},
352 {0x03cc, 0x8000},
353 {0x03d0, 0x0000},
354 {0x03d1, 0x0000},
355 {0x03d2, 0x0000},
356 {0x03d3, 0x0000},
357 {0x03d4, 0x2000},
358 {0x03d5, 0x2000},
359 {0x03d6, 0x0000},
360 {0x03d7, 0x0000},
361 {0x03d8, 0x2000},
362 {0x03d9, 0x2000},
363 {0x03da, 0x2000},
364 {0x03db, 0x2000},
365 {0x03dc, 0x0000},
366 {0x03dd, 0x0000},
367 {0x03de, 0x0000},
368 {0x03df, 0x2000},
369 {0x03e0, 0x0000},
370 {0x03e1, 0x0000},
371 {0x03e2, 0x0000},
372 {0x03e3, 0x0000},
373 {0x03e4, 0x0000},
374 {0x03e5, 0x0000},
375 {0x03e6, 0x0000},
376 {0x03e7, 0x0000},
377 {0x03e8, 0x0000},
378 {0x03e9, 0x0000},
379 {0x03ea, 0x0000},
380 {0x03eb, 0x0000},
381 {0x03ec, 0x0000},
382 {0x03ed, 0x0000},
383 {0x03ee, 0x0000},
384 {0x03ef, 0x0000},
385 {0x03f0, 0x0800},
386 {0x03f1, 0x0800},
387 {0x03f2, 0x0800},
388 {0x03f3, 0x0800},
389};
390
391static bool rt5668_volatile_register(struct device *dev, unsigned int reg)
392{
393 switch (reg) {
394 case RT5668_RESET:
395 case RT5668_CBJ_CTRL_2:
396 case RT5668_INT_ST_1:
397 case RT5668_4BTN_IL_CMD_1:
398 case RT5668_AJD1_CTRL:
399 case RT5668_HP_CALIB_CTRL_1:
400 case RT5668_DEVICE_ID:
401 case RT5668_I2C_MODE:
402 case RT5668_HP_CALIB_CTRL_10:
403 case RT5668_EFUSE_CTRL_2:
404 case RT5668_JD_TOP_VC_VTRL:
405 case RT5668_HP_IMP_SENS_CTRL_19:
406 case RT5668_IL_CMD_1:
407 case RT5668_SAR_IL_CMD_2:
408 case RT5668_SAR_IL_CMD_4:
409 case RT5668_SAR_IL_CMD_10:
410 case RT5668_SAR_IL_CMD_11:
411 case RT5668_EFUSE_CTRL_6...RT5668_EFUSE_CTRL_11:
412 case RT5668_HP_CALIB_STA_1...RT5668_HP_CALIB_STA_11:
413 return true;
414 default:
415 return false;
416 }
417}
418
419static bool rt5668_readable_register(struct device *dev, unsigned int reg)
420{
421 switch (reg) {
422 case RT5668_RESET:
423 case RT5668_VERSION_ID:
424 case RT5668_VENDOR_ID:
425 case RT5668_DEVICE_ID:
426 case RT5668_HP_CTRL_1:
427 case RT5668_HP_CTRL_2:
428 case RT5668_HPL_GAIN:
429 case RT5668_HPR_GAIN:
430 case RT5668_I2C_CTRL:
431 case RT5668_CBJ_BST_CTRL:
432 case RT5668_CBJ_CTRL_1:
433 case RT5668_CBJ_CTRL_2:
434 case RT5668_CBJ_CTRL_3:
435 case RT5668_CBJ_CTRL_4:
436 case RT5668_CBJ_CTRL_5:
437 case RT5668_CBJ_CTRL_6:
438 case RT5668_CBJ_CTRL_7:
439 case RT5668_DAC1_DIG_VOL:
440 case RT5668_STO1_ADC_DIG_VOL:
441 case RT5668_STO1_ADC_BOOST:
442 case RT5668_HP_IMP_GAIN_1:
443 case RT5668_HP_IMP_GAIN_2:
444 case RT5668_SIDETONE_CTRL:
445 case RT5668_STO1_ADC_MIXER:
446 case RT5668_AD_DA_MIXER:
447 case RT5668_STO1_DAC_MIXER:
448 case RT5668_A_DAC1_MUX:
449 case RT5668_DIG_INF2_DATA:
450 case RT5668_REC_MIXER:
451 case RT5668_CAL_REC:
452 case RT5668_ALC_BACK_GAIN:
453 case RT5668_PWR_DIG_1:
454 case RT5668_PWR_DIG_2:
455 case RT5668_PWR_ANLG_1:
456 case RT5668_PWR_ANLG_2:
457 case RT5668_PWR_ANLG_3:
458 case RT5668_PWR_MIXER:
459 case RT5668_PWR_VOL:
460 case RT5668_CLK_DET:
461 case RT5668_RESET_LPF_CTRL:
462 case RT5668_RESET_HPF_CTRL:
463 case RT5668_DMIC_CTRL_1:
464 case RT5668_I2S1_SDP:
465 case RT5668_I2S2_SDP:
466 case RT5668_ADDA_CLK_1:
467 case RT5668_ADDA_CLK_2:
468 case RT5668_I2S1_F_DIV_CTRL_1:
469 case RT5668_I2S1_F_DIV_CTRL_2:
470 case RT5668_TDM_CTRL:
471 case RT5668_TDM_ADDA_CTRL_1:
472 case RT5668_TDM_ADDA_CTRL_2:
473 case RT5668_DATA_SEL_CTRL_1:
474 case RT5668_TDM_TCON_CTRL:
475 case RT5668_GLB_CLK:
476 case RT5668_PLL_CTRL_1:
477 case RT5668_PLL_CTRL_2:
478 case RT5668_PLL_TRACK_1:
479 case RT5668_PLL_TRACK_2:
480 case RT5668_PLL_TRACK_3:
481 case RT5668_PLL_TRACK_4:
482 case RT5668_PLL_TRACK_5:
483 case RT5668_PLL_TRACK_6:
484 case RT5668_PLL_TRACK_11:
485 case RT5668_SDW_REF_CLK:
486 case RT5668_DEPOP_1:
487 case RT5668_DEPOP_2:
488 case RT5668_HP_CHARGE_PUMP_1:
489 case RT5668_HP_CHARGE_PUMP_2:
490 case RT5668_MICBIAS_1:
491 case RT5668_MICBIAS_2:
492 case RT5668_PLL_TRACK_12:
493 case RT5668_PLL_TRACK_14:
494 case RT5668_PLL2_CTRL_1:
495 case RT5668_PLL2_CTRL_2:
496 case RT5668_PLL2_CTRL_3:
497 case RT5668_PLL2_CTRL_4:
498 case RT5668_RC_CLK_CTRL:
499 case RT5668_I2S_M_CLK_CTRL_1:
500 case RT5668_I2S2_F_DIV_CTRL_1:
501 case RT5668_I2S2_F_DIV_CTRL_2:
502 case RT5668_EQ_CTRL_1:
503 case RT5668_EQ_CTRL_2:
504 case RT5668_IRQ_CTRL_1:
505 case RT5668_IRQ_CTRL_2:
506 case RT5668_IRQ_CTRL_3:
507 case RT5668_IRQ_CTRL_4:
508 case RT5668_INT_ST_1:
509 case RT5668_GPIO_CTRL_1:
510 case RT5668_GPIO_CTRL_2:
511 case RT5668_GPIO_CTRL_3:
512 case RT5668_HP_AMP_DET_CTRL_1:
513 case RT5668_HP_AMP_DET_CTRL_2:
514 case RT5668_MID_HP_AMP_DET:
515 case RT5668_LOW_HP_AMP_DET:
516 case RT5668_DELAY_BUF_CTRL:
517 case RT5668_SV_ZCD_1:
518 case RT5668_SV_ZCD_2:
519 case RT5668_IL_CMD_1:
520 case RT5668_IL_CMD_2:
521 case RT5668_IL_CMD_3:
522 case RT5668_IL_CMD_4:
523 case RT5668_IL_CMD_5:
524 case RT5668_IL_CMD_6:
525 case RT5668_4BTN_IL_CMD_1:
526 case RT5668_4BTN_IL_CMD_2:
527 case RT5668_4BTN_IL_CMD_3:
528 case RT5668_4BTN_IL_CMD_4:
529 case RT5668_4BTN_IL_CMD_5:
530 case RT5668_4BTN_IL_CMD_6:
531 case RT5668_4BTN_IL_CMD_7:
532 case RT5668_ADC_STO1_HP_CTRL_1:
533 case RT5668_ADC_STO1_HP_CTRL_2:
534 case RT5668_AJD1_CTRL:
535 case RT5668_JD1_THD:
536 case RT5668_JD2_THD:
537 case RT5668_JD_CTRL_1:
538 case RT5668_DUMMY_1:
539 case RT5668_DUMMY_2:
540 case RT5668_DUMMY_3:
541 case RT5668_DAC_ADC_DIG_VOL1:
542 case RT5668_BIAS_CUR_CTRL_2:
543 case RT5668_BIAS_CUR_CTRL_3:
544 case RT5668_BIAS_CUR_CTRL_4:
545 case RT5668_BIAS_CUR_CTRL_5:
546 case RT5668_BIAS_CUR_CTRL_6:
547 case RT5668_BIAS_CUR_CTRL_7:
548 case RT5668_BIAS_CUR_CTRL_8:
549 case RT5668_BIAS_CUR_CTRL_9:
550 case RT5668_BIAS_CUR_CTRL_10:
551 case RT5668_VREF_REC_OP_FB_CAP_CTRL:
552 case RT5668_CHARGE_PUMP_1:
553 case RT5668_DIG_IN_CTRL_1:
554 case RT5668_PAD_DRIVING_CTRL:
555 case RT5668_SOFT_RAMP_DEPOP:
556 case RT5668_CHOP_DAC:
557 case RT5668_CHOP_ADC:
558 case RT5668_CALIB_ADC_CTRL:
559 case RT5668_VOL_TEST:
560 case RT5668_SPKVDD_DET_STA:
561 case RT5668_TEST_MODE_CTRL_1:
562 case RT5668_TEST_MODE_CTRL_2:
563 case RT5668_TEST_MODE_CTRL_3:
564 case RT5668_TEST_MODE_CTRL_4:
565 case RT5668_TEST_MODE_CTRL_5:
566 case RT5668_PLL1_INTERNAL:
567 case RT5668_PLL2_INTERNAL:
568 case RT5668_STO_NG2_CTRL_1:
569 case RT5668_STO_NG2_CTRL_2:
570 case RT5668_STO_NG2_CTRL_3:
571 case RT5668_STO_NG2_CTRL_4:
572 case RT5668_STO_NG2_CTRL_5:
573 case RT5668_STO_NG2_CTRL_6:
574 case RT5668_STO_NG2_CTRL_7:
575 case RT5668_STO_NG2_CTRL_8:
576 case RT5668_STO_NG2_CTRL_9:
577 case RT5668_STO_NG2_CTRL_10:
578 case RT5668_STO1_DAC_SIL_DET:
579 case RT5668_SIL_PSV_CTRL1:
580 case RT5668_SIL_PSV_CTRL2:
581 case RT5668_SIL_PSV_CTRL3:
582 case RT5668_SIL_PSV_CTRL4:
583 case RT5668_SIL_PSV_CTRL5:
584 case RT5668_HP_IMP_SENS_CTRL_01:
585 case RT5668_HP_IMP_SENS_CTRL_02:
586 case RT5668_HP_IMP_SENS_CTRL_03:
587 case RT5668_HP_IMP_SENS_CTRL_04:
588 case RT5668_HP_IMP_SENS_CTRL_05:
589 case RT5668_HP_IMP_SENS_CTRL_06:
590 case RT5668_HP_IMP_SENS_CTRL_07:
591 case RT5668_HP_IMP_SENS_CTRL_08:
592 case RT5668_HP_IMP_SENS_CTRL_09:
593 case RT5668_HP_IMP_SENS_CTRL_10:
594 case RT5668_HP_IMP_SENS_CTRL_11:
595 case RT5668_HP_IMP_SENS_CTRL_12:
596 case RT5668_HP_IMP_SENS_CTRL_13:
597 case RT5668_HP_IMP_SENS_CTRL_14:
598 case RT5668_HP_IMP_SENS_CTRL_15:
599 case RT5668_HP_IMP_SENS_CTRL_16:
600 case RT5668_HP_IMP_SENS_CTRL_17:
601 case RT5668_HP_IMP_SENS_CTRL_18:
602 case RT5668_HP_IMP_SENS_CTRL_19:
603 case RT5668_HP_IMP_SENS_CTRL_20:
604 case RT5668_HP_IMP_SENS_CTRL_21:
605 case RT5668_HP_IMP_SENS_CTRL_22:
606 case RT5668_HP_IMP_SENS_CTRL_23:
607 case RT5668_HP_IMP_SENS_CTRL_24:
608 case RT5668_HP_IMP_SENS_CTRL_25:
609 case RT5668_HP_IMP_SENS_CTRL_26:
610 case RT5668_HP_IMP_SENS_CTRL_27:
611 case RT5668_HP_IMP_SENS_CTRL_28:
612 case RT5668_HP_IMP_SENS_CTRL_29:
613 case RT5668_HP_IMP_SENS_CTRL_30:
614 case RT5668_HP_IMP_SENS_CTRL_31:
615 case RT5668_HP_IMP_SENS_CTRL_32:
616 case RT5668_HP_IMP_SENS_CTRL_33:
617 case RT5668_HP_IMP_SENS_CTRL_34:
618 case RT5668_HP_IMP_SENS_CTRL_35:
619 case RT5668_HP_IMP_SENS_CTRL_36:
620 case RT5668_HP_IMP_SENS_CTRL_37:
621 case RT5668_HP_IMP_SENS_CTRL_38:
622 case RT5668_HP_IMP_SENS_CTRL_39:
623 case RT5668_HP_IMP_SENS_CTRL_40:
624 case RT5668_HP_IMP_SENS_CTRL_41:
625 case RT5668_HP_IMP_SENS_CTRL_42:
626 case RT5668_HP_IMP_SENS_CTRL_43:
627 case RT5668_HP_LOGIC_CTRL_1:
628 case RT5668_HP_LOGIC_CTRL_2:
629 case RT5668_HP_LOGIC_CTRL_3:
630 case RT5668_HP_CALIB_CTRL_1:
631 case RT5668_HP_CALIB_CTRL_2:
632 case RT5668_HP_CALIB_CTRL_3:
633 case RT5668_HP_CALIB_CTRL_4:
634 case RT5668_HP_CALIB_CTRL_5:
635 case RT5668_HP_CALIB_CTRL_6:
636 case RT5668_HP_CALIB_CTRL_7:
637 case RT5668_HP_CALIB_CTRL_9:
638 case RT5668_HP_CALIB_CTRL_10:
639 case RT5668_HP_CALIB_CTRL_11:
640 case RT5668_HP_CALIB_STA_1:
641 case RT5668_HP_CALIB_STA_2:
642 case RT5668_HP_CALIB_STA_3:
643 case RT5668_HP_CALIB_STA_4:
644 case RT5668_HP_CALIB_STA_5:
645 case RT5668_HP_CALIB_STA_6:
646 case RT5668_HP_CALIB_STA_7:
647 case RT5668_HP_CALIB_STA_8:
648 case RT5668_HP_CALIB_STA_9:
649 case RT5668_HP_CALIB_STA_10:
650 case RT5668_HP_CALIB_STA_11:
651 case RT5668_SAR_IL_CMD_1:
652 case RT5668_SAR_IL_CMD_2:
653 case RT5668_SAR_IL_CMD_3:
654 case RT5668_SAR_IL_CMD_4:
655 case RT5668_SAR_IL_CMD_5:
656 case RT5668_SAR_IL_CMD_6:
657 case RT5668_SAR_IL_CMD_7:
658 case RT5668_SAR_IL_CMD_8:
659 case RT5668_SAR_IL_CMD_9:
660 case RT5668_SAR_IL_CMD_10:
661 case RT5668_SAR_IL_CMD_11:
662 case RT5668_SAR_IL_CMD_12:
663 case RT5668_SAR_IL_CMD_13:
664 case RT5668_EFUSE_CTRL_1:
665 case RT5668_EFUSE_CTRL_2:
666 case RT5668_EFUSE_CTRL_3:
667 case RT5668_EFUSE_CTRL_4:
668 case RT5668_EFUSE_CTRL_5:
669 case RT5668_EFUSE_CTRL_6:
670 case RT5668_EFUSE_CTRL_7:
671 case RT5668_EFUSE_CTRL_8:
672 case RT5668_EFUSE_CTRL_9:
673 case RT5668_EFUSE_CTRL_10:
674 case RT5668_EFUSE_CTRL_11:
675 case RT5668_JD_TOP_VC_VTRL:
676 case RT5668_DRC1_CTRL_0:
677 case RT5668_DRC1_CTRL_1:
678 case RT5668_DRC1_CTRL_2:
679 case RT5668_DRC1_CTRL_3:
680 case RT5668_DRC1_CTRL_4:
681 case RT5668_DRC1_CTRL_5:
682 case RT5668_DRC1_CTRL_6:
683 case RT5668_DRC1_HARD_LMT_CTRL_1:
684 case RT5668_DRC1_HARD_LMT_CTRL_2:
685 case RT5668_DRC1_PRIV_1:
686 case RT5668_DRC1_PRIV_2:
687 case RT5668_DRC1_PRIV_3:
688 case RT5668_DRC1_PRIV_4:
689 case RT5668_DRC1_PRIV_5:
690 case RT5668_DRC1_PRIV_6:
691 case RT5668_DRC1_PRIV_7:
692 case RT5668_DRC1_PRIV_8:
693 case RT5668_EQ_AUTO_RCV_CTRL1:
694 case RT5668_EQ_AUTO_RCV_CTRL2:
695 case RT5668_EQ_AUTO_RCV_CTRL3:
696 case RT5668_EQ_AUTO_RCV_CTRL4:
697 case RT5668_EQ_AUTO_RCV_CTRL5:
698 case RT5668_EQ_AUTO_RCV_CTRL6:
699 case RT5668_EQ_AUTO_RCV_CTRL7:
700 case RT5668_EQ_AUTO_RCV_CTRL8:
701 case RT5668_EQ_AUTO_RCV_CTRL9:
702 case RT5668_EQ_AUTO_RCV_CTRL10:
703 case RT5668_EQ_AUTO_RCV_CTRL11:
704 case RT5668_EQ_AUTO_RCV_CTRL12:
705 case RT5668_EQ_AUTO_RCV_CTRL13:
706 case RT5668_ADC_L_EQ_LPF1_A1:
707 case RT5668_R_EQ_LPF1_A1:
708 case RT5668_L_EQ_LPF1_H0:
709 case RT5668_R_EQ_LPF1_H0:
710 case RT5668_L_EQ_BPF1_A1:
711 case RT5668_R_EQ_BPF1_A1:
712 case RT5668_L_EQ_BPF1_A2:
713 case RT5668_R_EQ_BPF1_A2:
714 case RT5668_L_EQ_BPF1_H0:
715 case RT5668_R_EQ_BPF1_H0:
716 case RT5668_L_EQ_BPF2_A1:
717 case RT5668_R_EQ_BPF2_A1:
718 case RT5668_L_EQ_BPF2_A2:
719 case RT5668_R_EQ_BPF2_A2:
720 case RT5668_L_EQ_BPF2_H0:
721 case RT5668_R_EQ_BPF2_H0:
722 case RT5668_L_EQ_BPF3_A1:
723 case RT5668_R_EQ_BPF3_A1:
724 case RT5668_L_EQ_BPF3_A2:
725 case RT5668_R_EQ_BPF3_A2:
726 case RT5668_L_EQ_BPF3_H0:
727 case RT5668_R_EQ_BPF3_H0:
728 case RT5668_L_EQ_BPF4_A1:
729 case RT5668_R_EQ_BPF4_A1:
730 case RT5668_L_EQ_BPF4_A2:
731 case RT5668_R_EQ_BPF4_A2:
732 case RT5668_L_EQ_BPF4_H0:
733 case RT5668_R_EQ_BPF4_H0:
734 case RT5668_L_EQ_HPF1_A1:
735 case RT5668_R_EQ_HPF1_A1:
736 case RT5668_L_EQ_HPF1_H0:
737 case RT5668_R_EQ_HPF1_H0:
738 case RT5668_L_EQ_PRE_VOL:
739 case RT5668_R_EQ_PRE_VOL:
740 case RT5668_L_EQ_POST_VOL:
741 case RT5668_R_EQ_POST_VOL:
742 case RT5668_I2C_MODE:
743 return true;
744 default:
745 return false;
746 }
747}
748
749static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2250, 150, 0);
750static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
751static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
752static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
753
754/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
755static const DECLARE_TLV_DB_RANGE(bst_tlv,
756 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
757 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
758 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
759 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
760 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
761 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
762 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
763);
764
765/* Interface data select */
766static const char * const rt5668_data_select[] = {
767 "L/R", "R/L", "L/L", "R/R"
768};
769
770static SOC_ENUM_SINGLE_DECL(rt5668_if2_adc_enum,
771 RT5668_DIG_INF2_DATA, RT5668_IF2_ADC_SEL_SFT, rt5668_data_select);
772
773static SOC_ENUM_SINGLE_DECL(rt5668_if1_01_adc_enum,
774 RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC1_SEL_SFT, rt5668_data_select);
775
776static SOC_ENUM_SINGLE_DECL(rt5668_if1_23_adc_enum,
777 RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC2_SEL_SFT, rt5668_data_select);
778
779static SOC_ENUM_SINGLE_DECL(rt5668_if1_45_adc_enum,
780 RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC3_SEL_SFT, rt5668_data_select);
781
782static SOC_ENUM_SINGLE_DECL(rt5668_if1_67_adc_enum,
783 RT5668_TDM_ADDA_CTRL_1, RT5668_IF1_ADC4_SEL_SFT, rt5668_data_select);
784
785static const struct snd_kcontrol_new rt5668_if2_adc_swap_mux =
786 SOC_DAPM_ENUM("IF2 ADC Swap Mux", rt5668_if2_adc_enum);
787
788static const struct snd_kcontrol_new rt5668_if1_01_adc_swap_mux =
789 SOC_DAPM_ENUM("IF1 01 ADC Swap Mux", rt5668_if1_01_adc_enum);
790
791static const struct snd_kcontrol_new rt5668_if1_23_adc_swap_mux =
792 SOC_DAPM_ENUM("IF1 23 ADC Swap Mux", rt5668_if1_23_adc_enum);
793
794static const struct snd_kcontrol_new rt5668_if1_45_adc_swap_mux =
795 SOC_DAPM_ENUM("IF1 45 ADC Swap Mux", rt5668_if1_45_adc_enum);
796
797static const struct snd_kcontrol_new rt5668_if1_67_adc_swap_mux =
798 SOC_DAPM_ENUM("IF1 67 ADC Swap Mux", rt5668_if1_67_adc_enum);
799
800static void rt5668_reset(struct regmap *regmap)
801{
802 regmap_write(regmap, RT5668_RESET, 0);
803 regmap_write(regmap, RT5668_I2C_MODE, 1);
804}
805/**
806 * rt5668_sel_asrc_clk_src - select ASRC clock source for a set of filters
807 * @component: SoC audio component device.
808 * @filter_mask: mask of filters.
809 * @clk_src: clock source
810 *
811 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can
812 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
813 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
814 * ASRC function will track i2s clock and generate a corresponding system clock
815 * for codec. This function provides an API to select the clock source for a
816 * set of filters specified by the mask. And the component driver will turn on
817 * ASRC for these filters if ASRC is selected as their clock source.
818 */
819int rt5668_sel_asrc_clk_src(struct snd_soc_component *component,
820 unsigned int filter_mask, unsigned int clk_src)
821{
822
823 switch (clk_src) {
824 case RT5668_CLK_SEL_SYS:
825 case RT5668_CLK_SEL_I2S1_ASRC:
826 case RT5668_CLK_SEL_I2S2_ASRC:
827 break;
828
829 default:
830 return -EINVAL;
831 }
832
833 if (filter_mask & RT5668_DA_STEREO1_FILTER) {
834 snd_soc_component_update_bits(component, RT5668_PLL_TRACK_2,
835 RT5668_FILTER_CLK_SEL_MASK,
836 clk_src << RT5668_FILTER_CLK_SEL_SFT);
837 }
838
839 if (filter_mask & RT5668_AD_STEREO1_FILTER) {
840 snd_soc_component_update_bits(component, RT5668_PLL_TRACK_3,
841 RT5668_FILTER_CLK_SEL_MASK,
842 clk_src << RT5668_FILTER_CLK_SEL_SFT);
843 }
844
845 return 0;
846}
847EXPORT_SYMBOL_GPL(rt5668_sel_asrc_clk_src);
848
849static int rt5668_button_detect(struct snd_soc_component *component)
850{
851 int btn_type, val;
852
853 val = snd_soc_component_read32(component, RT5668_4BTN_IL_CMD_1);
854 btn_type = val & 0xfff0;
855 snd_soc_component_write(component, RT5668_4BTN_IL_CMD_1, val);
856 pr_debug("%s btn_type=%x\n", __func__, btn_type);
857
858 return btn_type;
859}
860
861static void rt5668_enable_push_button_irq(struct snd_soc_component *component,
862 bool enable)
863{
864 if (enable) {
865 snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
866 RT5668_SAR_BUTT_DET_MASK, RT5668_SAR_BUTT_DET_EN);
867 snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_13,
868 RT5668_SAR_SOUR_MASK, RT5668_SAR_SOUR_BTN);
869 snd_soc_component_write(component, RT5668_IL_CMD_1, 0x0040);
870 snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
871 RT5668_4BTN_IL_MASK | RT5668_4BTN_IL_RST_MASK,
872 RT5668_4BTN_IL_EN | RT5668_4BTN_IL_NOR);
873 snd_soc_component_update_bits(component, RT5668_IRQ_CTRL_3,
874 RT5668_IL_IRQ_MASK, RT5668_IL_IRQ_EN);
875 } else {
876 snd_soc_component_update_bits(component, RT5668_IRQ_CTRL_3,
877 RT5668_IL_IRQ_MASK, RT5668_IL_IRQ_DIS);
878 snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
879 RT5668_SAR_BUTT_DET_MASK, RT5668_SAR_BUTT_DET_DIS);
880 snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
881 RT5668_4BTN_IL_MASK, RT5668_4BTN_IL_DIS);
882 snd_soc_component_update_bits(component, RT5668_4BTN_IL_CMD_2,
883 RT5668_4BTN_IL_RST_MASK, RT5668_4BTN_IL_RST);
884 snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_13,
885 RT5668_SAR_SOUR_MASK, RT5668_SAR_SOUR_TYPE);
886 }
887}
888
889/**
890 * rt5668_headset_detect - Detect headset.
891 * @component: SoC audio component device.
892 * @jack_insert: Jack insert or not.
893 *
894 * Detect whether is headset or not when jack inserted.
895 *
896 * Returns detect status.
897 */
898static int rt5668_headset_detect(struct snd_soc_component *component,
899 int jack_insert)
900{
901 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
902 struct snd_soc_dapm_context *dapm =
903 snd_soc_component_get_dapm(component);
904 unsigned int val, count;
905
906 if (jack_insert) {
907 snd_soc_dapm_force_enable_pin(dapm, "CBJ Power");
908 snd_soc_dapm_sync(dapm);
909 snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_1,
910 RT5668_TRIG_JD_MASK, RT5668_TRIG_JD_HIGH);
911
912 count = 0;
913 val = snd_soc_component_read32(component, RT5668_CBJ_CTRL_2)
914 & RT5668_JACK_TYPE_MASK;
915 while (val == 0 && count < 50) {
916 usleep_range(10000, 15000);
917 val = snd_soc_component_read32(component,
918 RT5668_CBJ_CTRL_2) & RT5668_JACK_TYPE_MASK;
919 count++;
920 }
921
922 switch (val) {
923 case 0x1:
924 case 0x2:
925 rt5668->jack_type = SND_JACK_HEADSET;
926 rt5668_enable_push_button_irq(component, true);
927 break;
928 default:
929 rt5668->jack_type = SND_JACK_HEADPHONE;
930 }
931
932 } else {
933 rt5668_enable_push_button_irq(component, false);
934 snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_1,
935 RT5668_TRIG_JD_MASK, RT5668_TRIG_JD_LOW);
936 snd_soc_dapm_disable_pin(dapm, "CBJ Power");
937 snd_soc_dapm_sync(dapm);
938
939 rt5668->jack_type = 0;
940 }
941
942 dev_dbg(component->dev, "jack_type = %d\n", rt5668->jack_type);
943 return rt5668->jack_type;
944}
945
946static irqreturn_t rt5668_irq(int irq, void *data)
947{
948 struct rt5668_priv *rt5668 = data;
949
950 mod_delayed_work(system_power_efficient_wq,
951 &rt5668->jack_detect_work, msecs_to_jiffies(250));
952
953 return IRQ_HANDLED;
954}
955
956static void rt5668_jd_check_handler(struct work_struct *work)
957{
958 struct rt5668_priv *rt5668 = container_of(work, struct rt5668_priv,
959 jd_check_work.work);
960
961 if (snd_soc_component_read32(rt5668->component, RT5668_AJD1_CTRL)
962 & RT5668_JDH_RS_MASK) {
963 /* jack out */
964 rt5668->jack_type = rt5668_headset_detect(rt5668->component, 0);
965
966 snd_soc_jack_report(rt5668->hs_jack, rt5668->jack_type,
967 SND_JACK_HEADSET |
968 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
969 SND_JACK_BTN_2 | SND_JACK_BTN_3);
970 } else {
971 schedule_delayed_work(&rt5668->jd_check_work, 500);
972 }
973}
974
975static int rt5668_set_jack_detect(struct snd_soc_component *component,
976 struct snd_soc_jack *hs_jack, void *data)
977{
978 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
979
980 switch (rt5668->pdata.jd_src) {
981 case RT5668_JD1:
982 snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_2,
983 RT5668_EXT_JD_SRC, RT5668_EXT_JD_SRC_MANUAL);
984 snd_soc_component_write(component, RT5668_CBJ_CTRL_1, 0xd002);
985 snd_soc_component_update_bits(component, RT5668_CBJ_CTRL_3,
986 RT5668_CBJ_IN_BUF_EN, RT5668_CBJ_IN_BUF_EN);
987 snd_soc_component_update_bits(component, RT5668_SAR_IL_CMD_1,
988 RT5668_SAR_POW_MASK, RT5668_SAR_POW_EN);
989 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
990 RT5668_GP1_PIN_MASK, RT5668_GP1_PIN_IRQ);
991 regmap_update_bits(rt5668->regmap, RT5668_RC_CLK_CTRL,
992 RT5668_POW_IRQ | RT5668_POW_JDH |
993 RT5668_POW_ANA, RT5668_POW_IRQ |
994 RT5668_POW_JDH | RT5668_POW_ANA);
995 regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_2,
996 RT5668_PWR_JDH | RT5668_PWR_JDL,
997 RT5668_PWR_JDH | RT5668_PWR_JDL);
998 regmap_update_bits(rt5668->regmap, RT5668_IRQ_CTRL_2,
999 RT5668_JD1_EN_MASK | RT5668_JD1_POL_MASK,
1000 RT5668_JD1_EN | RT5668_JD1_POL_NOR);
1001 mod_delayed_work(system_power_efficient_wq,
1002 &rt5668->jack_detect_work, msecs_to_jiffies(250));
1003 break;
1004
1005 case RT5668_JD_NULL:
1006 regmap_update_bits(rt5668->regmap, RT5668_IRQ_CTRL_2,
1007 RT5668_JD1_EN_MASK, RT5668_JD1_DIS);
1008 regmap_update_bits(rt5668->regmap, RT5668_RC_CLK_CTRL,
1009 RT5668_POW_JDH | RT5668_POW_JDL, 0);
1010 break;
1011
1012 default:
1013 dev_warn(component->dev, "Wrong JD source\n");
1014 break;
1015 }
1016
1017 rt5668->hs_jack = hs_jack;
1018
1019 return 0;
1020}
1021
1022static void rt5668_jack_detect_handler(struct work_struct *work)
1023{
1024 struct rt5668_priv *rt5668 =
1025 container_of(work, struct rt5668_priv, jack_detect_work.work);
1026 int val, btn_type;
1027
1028 while (!rt5668->component)
1029 usleep_range(10000, 15000);
1030
1031 while (!rt5668->component->card->instantiated)
1032 usleep_range(10000, 15000);
1033
1034 mutex_lock(&rt5668->calibrate_mutex);
1035
1036 val = snd_soc_component_read32(rt5668->component, RT5668_AJD1_CTRL)
1037 & RT5668_JDH_RS_MASK;
1038 if (!val) {
1039 /* jack in */
1040 if (rt5668->jack_type == 0) {
1041 /* jack was out, report jack type */
1042 rt5668->jack_type =
1043 rt5668_headset_detect(rt5668->component, 1);
1044 } else {
1045 /* jack is already in, report button event */
1046 rt5668->jack_type = SND_JACK_HEADSET;
1047 btn_type = rt5668_button_detect(rt5668->component);
1048 /**
1049 * rt5668 can report three kinds of button behavior,
1050 * one click, double click and hold. However,
1051 * currently we will report button pressed/released
1052 * event. So all the three button behaviors are
1053 * treated as button pressed.
1054 */
1055 switch (btn_type) {
1056 case 0x8000:
1057 case 0x4000:
1058 case 0x2000:
1059 rt5668->jack_type |= SND_JACK_BTN_0;
1060 break;
1061 case 0x1000:
1062 case 0x0800:
1063 case 0x0400:
1064 rt5668->jack_type |= SND_JACK_BTN_1;
1065 break;
1066 case 0x0200:
1067 case 0x0100:
1068 case 0x0080:
1069 rt5668->jack_type |= SND_JACK_BTN_2;
1070 break;
1071 case 0x0040:
1072 case 0x0020:
1073 case 0x0010:
1074 rt5668->jack_type |= SND_JACK_BTN_3;
1075 break;
1076 case 0x0000: /* unpressed */
1077 break;
1078 default:
1079 btn_type = 0;
1080 dev_err(rt5668->component->dev,
1081 "Unexpected button code 0x%04x\n",
1082 btn_type);
1083 break;
1084 }
1085 }
1086 } else {
1087 /* jack out */
1088 rt5668->jack_type = rt5668_headset_detect(rt5668->component, 0);
1089 }
1090
1091 snd_soc_jack_report(rt5668->hs_jack, rt5668->jack_type,
1092 SND_JACK_HEADSET |
1093 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1094 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1095
1096 if (rt5668->jack_type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1097 SND_JACK_BTN_2 | SND_JACK_BTN_3))
1098 schedule_delayed_work(&rt5668->jd_check_work, 0);
1099 else
1100 cancel_delayed_work_sync(&rt5668->jd_check_work);
1101
1102 mutex_unlock(&rt5668->calibrate_mutex);
1103}
1104
1105static const struct snd_kcontrol_new rt5668_snd_controls[] = {
1106 /* Headphone Output Volume */
1107 SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5668_HPL_GAIN,
1108 RT5668_HPR_GAIN, RT5668_G_HP_SFT, 15, 1, hp_vol_tlv),
1109
1110 /* DAC Digital Volume */
1111 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5668_DAC1_DIG_VOL,
1112 RT5668_L_VOL_SFT, RT5668_R_VOL_SFT, 175, 0, dac_vol_tlv),
1113
1114 /* IN Boost Volume */
1115 SOC_SINGLE_TLV("CBJ Boost Volume", RT5668_CBJ_BST_CTRL,
1116 RT5668_BST_CBJ_SFT, 8, 0, bst_tlv),
1117
1118 /* ADC Digital Volume Control */
1119 SOC_DOUBLE("STO1 ADC Capture Switch", RT5668_STO1_ADC_DIG_VOL,
1120 RT5668_L_MUTE_SFT, RT5668_R_MUTE_SFT, 1, 1),
1121 SOC_DOUBLE_TLV("STO1 ADC Capture Volume", RT5668_STO1_ADC_DIG_VOL,
1122 RT5668_L_VOL_SFT, RT5668_R_VOL_SFT, 127, 0, adc_vol_tlv),
1123
1124 /* ADC Boost Volume Control */
1125 SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5668_STO1_ADC_BOOST,
1126 RT5668_STO1_ADC_L_BST_SFT, RT5668_STO1_ADC_R_BST_SFT,
1127 3, 0, adc_bst_tlv),
1128};
1129
1130
1131static int rt5668_div_sel(struct rt5668_priv *rt5668,
1132 int target, const int div[], int size)
1133{
1134 int i;
1135
1136 if (rt5668->sysclk < target) {
1137 pr_err("sysclk rate %d is too low\n",
1138 rt5668->sysclk);
1139 return 0;
1140 }
1141
1142 for (i = 0; i < size - 1; i++) {
1143 pr_info("div[%d]=%d\n", i, div[i]);
1144 if (target * div[i] == rt5668->sysclk)
1145 return i;
1146 if (target * div[i + 1] > rt5668->sysclk) {
1147 pr_err("can't find div for sysclk %d\n",
1148 rt5668->sysclk);
1149 return i;
1150 }
1151 }
1152
1153 if (target * div[i] < rt5668->sysclk)
1154 pr_err("sysclk rate %d is too high\n",
1155 rt5668->sysclk);
1156
1157 return size - 1;
1158
1159}
1160
1161/**
1162 * set_dmic_clk - Set parameter of dmic.
1163 *
1164 * @w: DAPM widget.
1165 * @kcontrol: The kcontrol of this widget.
1166 * @event: Event id.
1167 *
1168 * Choose dmic clock between 1MHz and 3MHz.
1169 * It is better for clock to approximate 3MHz.
1170 */
1171static int set_dmic_clk(struct snd_soc_dapm_widget *w,
1172 struct snd_kcontrol *kcontrol, int event)
1173{
1174 struct snd_soc_component *component =
1175 snd_soc_dapm_to_component(w->dapm);
1176 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
1177 int idx = -EINVAL;
1178 static const int div[] = {2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128};
1179
1180 idx = rt5668_div_sel(rt5668, 1500000, div, ARRAY_SIZE(div));
1181
1182 snd_soc_component_update_bits(component, RT5668_DMIC_CTRL_1,
1183 RT5668_DMIC_CLK_MASK, idx << RT5668_DMIC_CLK_SFT);
1184
1185 return 0;
1186}
1187
1188static int set_filter_clk(struct snd_soc_dapm_widget *w,
1189 struct snd_kcontrol *kcontrol, int event)
1190{
1191 struct snd_soc_component *component =
1192 snd_soc_dapm_to_component(w->dapm);
1193 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
1194 int ref, val, reg, idx = -EINVAL;
1195 static const int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48};
1196
1197 val = snd_soc_component_read32(component, RT5668_GPIO_CTRL_1) &
1198 RT5668_GP4_PIN_MASK;
1199 if (w->shift == RT5668_PWR_ADC_S1F_BIT &&
1200 val == RT5668_GP4_PIN_ADCDAT2)
1201 ref = 256 * rt5668->lrck[RT5668_AIF2];
1202 else
1203 ref = 256 * rt5668->lrck[RT5668_AIF1];
1204
1205 idx = rt5668_div_sel(rt5668, ref, div, ARRAY_SIZE(div));
1206
1207 if (w->shift == RT5668_PWR_ADC_S1F_BIT)
1208 reg = RT5668_PLL_TRACK_3;
1209 else
1210 reg = RT5668_PLL_TRACK_2;
1211
1212 snd_soc_component_update_bits(component, reg,
1213 RT5668_FILTER_CLK_SEL_MASK, idx << RT5668_FILTER_CLK_SEL_SFT);
1214
1215 return 0;
1216}
1217
1218static int is_sys_clk_from_pll1(struct snd_soc_dapm_widget *w,
1219 struct snd_soc_dapm_widget *sink)
1220{
1221 unsigned int val;
1222 struct snd_soc_component *component =
1223 snd_soc_dapm_to_component(w->dapm);
1224
1225 val = snd_soc_component_read32(component, RT5668_GLB_CLK);
1226 val &= RT5668_SCLK_SRC_MASK;
1227 if (val == RT5668_SCLK_SRC_PLL1)
1228 return 1;
1229 else
1230 return 0;
1231}
1232
1233static int is_using_asrc(struct snd_soc_dapm_widget *w,
1234 struct snd_soc_dapm_widget *sink)
1235{
1236 unsigned int reg, shift, val;
1237 struct snd_soc_component *component =
1238 snd_soc_dapm_to_component(w->dapm);
1239
1240 switch (w->shift) {
1241 case RT5668_ADC_STO1_ASRC_SFT:
1242 reg = RT5668_PLL_TRACK_3;
1243 shift = RT5668_FILTER_CLK_SEL_SFT;
1244 break;
1245 case RT5668_DAC_STO1_ASRC_SFT:
1246 reg = RT5668_PLL_TRACK_2;
1247 shift = RT5668_FILTER_CLK_SEL_SFT;
1248 break;
1249 default:
1250 return 0;
1251 }
1252
1253 val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
1254 switch (val) {
1255 case RT5668_CLK_SEL_I2S1_ASRC:
1256 case RT5668_CLK_SEL_I2S2_ASRC:
1257 return 1;
1258 default:
1259 return 0;
1260 }
1261
1262}
1263
1264/* Digital Mixer */
1265static const struct snd_kcontrol_new rt5668_sto1_adc_l_mix[] = {
1266 SOC_DAPM_SINGLE("ADC1 Switch", RT5668_STO1_ADC_MIXER,
1267 RT5668_M_STO1_ADC_L1_SFT, 1, 1),
1268 SOC_DAPM_SINGLE("ADC2 Switch", RT5668_STO1_ADC_MIXER,
1269 RT5668_M_STO1_ADC_L2_SFT, 1, 1),
1270};
1271
1272static const struct snd_kcontrol_new rt5668_sto1_adc_r_mix[] = {
1273 SOC_DAPM_SINGLE("ADC1 Switch", RT5668_STO1_ADC_MIXER,
1274 RT5668_M_STO1_ADC_R1_SFT, 1, 1),
1275 SOC_DAPM_SINGLE("ADC2 Switch", RT5668_STO1_ADC_MIXER,
1276 RT5668_M_STO1_ADC_R2_SFT, 1, 1),
1277};
1278
1279static const struct snd_kcontrol_new rt5668_dac_l_mix[] = {
1280 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5668_AD_DA_MIXER,
1281 RT5668_M_ADCMIX_L_SFT, 1, 1),
1282 SOC_DAPM_SINGLE("DAC1 Switch", RT5668_AD_DA_MIXER,
1283 RT5668_M_DAC1_L_SFT, 1, 1),
1284};
1285
1286static const struct snd_kcontrol_new rt5668_dac_r_mix[] = {
1287 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5668_AD_DA_MIXER,
1288 RT5668_M_ADCMIX_R_SFT, 1, 1),
1289 SOC_DAPM_SINGLE("DAC1 Switch", RT5668_AD_DA_MIXER,
1290 RT5668_M_DAC1_R_SFT, 1, 1),
1291};
1292
1293static const struct snd_kcontrol_new rt5668_sto1_dac_l_mix[] = {
1294 SOC_DAPM_SINGLE("DAC L1 Switch", RT5668_STO1_DAC_MIXER,
1295 RT5668_M_DAC_L1_STO_L_SFT, 1, 1),
1296 SOC_DAPM_SINGLE("DAC R1 Switch", RT5668_STO1_DAC_MIXER,
1297 RT5668_M_DAC_R1_STO_L_SFT, 1, 1),
1298};
1299
1300static const struct snd_kcontrol_new rt5668_sto1_dac_r_mix[] = {
1301 SOC_DAPM_SINGLE("DAC L1 Switch", RT5668_STO1_DAC_MIXER,
1302 RT5668_M_DAC_L1_STO_R_SFT, 1, 1),
1303 SOC_DAPM_SINGLE("DAC R1 Switch", RT5668_STO1_DAC_MIXER,
1304 RT5668_M_DAC_R1_STO_R_SFT, 1, 1),
1305};
1306
1307/* Analog Input Mixer */
1308static const struct snd_kcontrol_new rt5668_rec1_l_mix[] = {
1309 SOC_DAPM_SINGLE("CBJ Switch", RT5668_REC_MIXER,
1310 RT5668_M_CBJ_RM1_L_SFT, 1, 1),
1311};
1312
1313/* STO1 ADC1 Source */
1314/* MX-26 [13] [5] */
1315static const char * const rt5668_sto1_adc1_src[] = {
1316 "DAC MIX", "ADC"
1317};
1318
1319static SOC_ENUM_SINGLE_DECL(
1320 rt5668_sto1_adc1l_enum, RT5668_STO1_ADC_MIXER,
1321 RT5668_STO1_ADC1L_SRC_SFT, rt5668_sto1_adc1_src);
1322
1323static const struct snd_kcontrol_new rt5668_sto1_adc1l_mux =
1324 SOC_DAPM_ENUM("Stereo1 ADC1L Source", rt5668_sto1_adc1l_enum);
1325
1326static SOC_ENUM_SINGLE_DECL(
1327 rt5668_sto1_adc1r_enum, RT5668_STO1_ADC_MIXER,
1328 RT5668_STO1_ADC1R_SRC_SFT, rt5668_sto1_adc1_src);
1329
1330static const struct snd_kcontrol_new rt5668_sto1_adc1r_mux =
1331 SOC_DAPM_ENUM("Stereo1 ADC1L Source", rt5668_sto1_adc1r_enum);
1332
1333/* STO1 ADC Source */
1334/* MX-26 [11:10] [3:2] */
1335static const char * const rt5668_sto1_adc_src[] = {
1336 "ADC1 L", "ADC1 R"
1337};
1338
1339static SOC_ENUM_SINGLE_DECL(
1340 rt5668_sto1_adcl_enum, RT5668_STO1_ADC_MIXER,
1341 RT5668_STO1_ADCL_SRC_SFT, rt5668_sto1_adc_src);
1342
1343static const struct snd_kcontrol_new rt5668_sto1_adcl_mux =
1344 SOC_DAPM_ENUM("Stereo1 ADCL Source", rt5668_sto1_adcl_enum);
1345
1346static SOC_ENUM_SINGLE_DECL(
1347 rt5668_sto1_adcr_enum, RT5668_STO1_ADC_MIXER,
1348 RT5668_STO1_ADCR_SRC_SFT, rt5668_sto1_adc_src);
1349
1350static const struct snd_kcontrol_new rt5668_sto1_adcr_mux =
1351 SOC_DAPM_ENUM("Stereo1 ADCR Source", rt5668_sto1_adcr_enum);
1352
1353/* STO1 ADC2 Source */
1354/* MX-26 [12] [4] */
1355static const char * const rt5668_sto1_adc2_src[] = {
1356 "DAC MIX", "DMIC"
1357};
1358
1359static SOC_ENUM_SINGLE_DECL(
1360 rt5668_sto1_adc2l_enum, RT5668_STO1_ADC_MIXER,
1361 RT5668_STO1_ADC2L_SRC_SFT, rt5668_sto1_adc2_src);
1362
1363static const struct snd_kcontrol_new rt5668_sto1_adc2l_mux =
1364 SOC_DAPM_ENUM("Stereo1 ADC2L Source", rt5668_sto1_adc2l_enum);
1365
1366static SOC_ENUM_SINGLE_DECL(
1367 rt5668_sto1_adc2r_enum, RT5668_STO1_ADC_MIXER,
1368 RT5668_STO1_ADC2R_SRC_SFT, rt5668_sto1_adc2_src);
1369
1370static const struct snd_kcontrol_new rt5668_sto1_adc2r_mux =
1371 SOC_DAPM_ENUM("Stereo1 ADC2R Source", rt5668_sto1_adc2r_enum);
1372
1373/* MX-79 [6:4] I2S1 ADC data location */
1374static const unsigned int rt5668_if1_adc_slot_values[] = {
1375 0,
1376 2,
1377 4,
1378 6,
1379};
1380
1381static const char * const rt5668_if1_adc_slot_src[] = {
1382 "Slot 0", "Slot 2", "Slot 4", "Slot 6"
1383};
1384
1385static SOC_VALUE_ENUM_SINGLE_DECL(rt5668_if1_adc_slot_enum,
1386 RT5668_TDM_CTRL, RT5668_TDM_ADC_LCA_SFT, RT5668_TDM_ADC_LCA_MASK,
1387 rt5668_if1_adc_slot_src, rt5668_if1_adc_slot_values);
1388
1389static const struct snd_kcontrol_new rt5668_if1_adc_slot_mux =
1390 SOC_DAPM_ENUM("IF1 ADC Slot location", rt5668_if1_adc_slot_enum);
1391
1392/* Analog DAC L1 Source, Analog DAC R1 Source*/
1393/* MX-2B [4], MX-2B [0]*/
1394static const char * const rt5668_alg_dac1_src[] = {
1395 "Stereo1 DAC Mixer", "DAC1"
1396};
1397
1398static SOC_ENUM_SINGLE_DECL(
1399 rt5668_alg_dac_l1_enum, RT5668_A_DAC1_MUX,
1400 RT5668_A_DACL1_SFT, rt5668_alg_dac1_src);
1401
1402static const struct snd_kcontrol_new rt5668_alg_dac_l1_mux =
1403 SOC_DAPM_ENUM("Analog DAC L1 Source", rt5668_alg_dac_l1_enum);
1404
1405static SOC_ENUM_SINGLE_DECL(
1406 rt5668_alg_dac_r1_enum, RT5668_A_DAC1_MUX,
1407 RT5668_A_DACR1_SFT, rt5668_alg_dac1_src);
1408
1409static const struct snd_kcontrol_new rt5668_alg_dac_r1_mux =
1410 SOC_DAPM_ENUM("Analog DAC R1 Source", rt5668_alg_dac_r1_enum);
1411
1412/* Out Switch */
1413static const struct snd_kcontrol_new hpol_switch =
1414 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_CTRL_1,
1415 RT5668_L_MUTE_SFT, 1, 1);
1416static const struct snd_kcontrol_new hpor_switch =
1417 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5668_HP_CTRL_1,
1418 RT5668_R_MUTE_SFT, 1, 1);
1419
1420static int rt5668_hp_event(struct snd_soc_dapm_widget *w,
1421 struct snd_kcontrol *kcontrol, int event)
1422{
1423 struct snd_soc_component *component =
1424 snd_soc_dapm_to_component(w->dapm);
1425
1426 switch (event) {
1427 case SND_SOC_DAPM_PRE_PMU:
1428 snd_soc_component_write(component,
1429 RT5668_HP_LOGIC_CTRL_2, 0x0012);
1430 snd_soc_component_write(component,
1431 RT5668_HP_CTRL_2, 0x6000);
1432 snd_soc_component_update_bits(component, RT5668_STO_NG2_CTRL_1,
1433 RT5668_NG2_EN_MASK, RT5668_NG2_EN);
1434 snd_soc_component_update_bits(component,
1435 RT5668_DEPOP_1, 0x60, 0x60);
1436 break;
1437
1438 case SND_SOC_DAPM_POST_PMD:
1439 snd_soc_component_update_bits(component,
1440 RT5668_DEPOP_1, 0x60, 0x0);
1441 snd_soc_component_write(component,
1442 RT5668_HP_CTRL_2, 0x0000);
1443 break;
1444
1445 default:
1446 return 0;
1447 }
1448
1449 return 0;
1450
1451}
1452
1453static int set_dmic_power(struct snd_soc_dapm_widget *w,
1454 struct snd_kcontrol *kcontrol, int event)
1455{
1456 switch (event) {
1457 case SND_SOC_DAPM_POST_PMU:
1458 /*Add delay to avoid pop noise*/
1459 msleep(150);
1460 break;
1461
1462 default:
1463 return 0;
1464 }
1465
1466 return 0;
1467}
1468
1469static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
1470 struct snd_kcontrol *kcontrol, int event)
1471{
1472 struct snd_soc_component *component =
1473 snd_soc_dapm_to_component(w->dapm);
1474
1475 switch (event) {
1476 case SND_SOC_DAPM_PRE_PMU:
1477 switch (w->shift) {
1478 case RT5668_PWR_VREF1_BIT:
1479 snd_soc_component_update_bits(component,
1480 RT5668_PWR_ANLG_1, RT5668_PWR_FV1, 0);
1481 break;
1482
1483 case RT5668_PWR_VREF2_BIT:
1484 snd_soc_component_update_bits(component,
1485 RT5668_PWR_ANLG_1, RT5668_PWR_FV2, 0);
1486 break;
1487
1488 default:
1489 break;
1490 }
1491 break;
1492
1493 case SND_SOC_DAPM_POST_PMU:
1494 usleep_range(15000, 20000);
1495 switch (w->shift) {
1496 case RT5668_PWR_VREF1_BIT:
1497 snd_soc_component_update_bits(component,
1498 RT5668_PWR_ANLG_1, RT5668_PWR_FV1,
1499 RT5668_PWR_FV1);
1500 break;
1501
1502 case RT5668_PWR_VREF2_BIT:
1503 snd_soc_component_update_bits(component,
1504 RT5668_PWR_ANLG_1, RT5668_PWR_FV2,
1505 RT5668_PWR_FV2);
1506 break;
1507
1508 default:
1509 break;
1510 }
1511 break;
1512
1513 default:
1514 return 0;
1515 }
1516
1517 return 0;
1518}
1519
1520static const unsigned int rt5668_adcdat_pin_values[] = {
1521 1,
1522 3,
1523};
1524
1525static const char * const rt5668_adcdat_pin_select[] = {
1526 "ADCDAT1",
1527 "ADCDAT2",
1528};
1529
1530static SOC_VALUE_ENUM_SINGLE_DECL(rt5668_adcdat_pin_enum,
1531 RT5668_GPIO_CTRL_1, RT5668_GP4_PIN_SFT, RT5668_GP4_PIN_MASK,
1532 rt5668_adcdat_pin_select, rt5668_adcdat_pin_values);
1533
1534static const struct snd_kcontrol_new rt5668_adcdat_pin_ctrl =
1535 SOC_DAPM_ENUM("ADCDAT", rt5668_adcdat_pin_enum);
1536
1537static const struct snd_soc_dapm_widget rt5668_dapm_widgets[] = {
1538 SND_SOC_DAPM_SUPPLY("LDO2", RT5668_PWR_ANLG_3, RT5668_PWR_LDO2_BIT,
1539 0, NULL, 0),
1540 SND_SOC_DAPM_SUPPLY("PLL1", RT5668_PWR_ANLG_3, RT5668_PWR_PLL_BIT,
1541 0, NULL, 0),
1542 SND_SOC_DAPM_SUPPLY("PLL2B", RT5668_PWR_ANLG_3, RT5668_PWR_PLL2B_BIT,
1543 0, NULL, 0),
1544 SND_SOC_DAPM_SUPPLY("PLL2F", RT5668_PWR_ANLG_3, RT5668_PWR_PLL2F_BIT,
1545 0, NULL, 0),
1546 SND_SOC_DAPM_SUPPLY("Vref1", RT5668_PWR_ANLG_1, RT5668_PWR_VREF1_BIT, 0,
1547 rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1548 SND_SOC_DAPM_SUPPLY("Vref2", RT5668_PWR_ANLG_1, RT5668_PWR_VREF2_BIT, 0,
1549 rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1550
1551 /* ASRC */
1552 SND_SOC_DAPM_SUPPLY_S("DAC STO1 ASRC", 1, RT5668_PLL_TRACK_1,
1553 RT5668_DAC_STO1_ASRC_SFT, 0, NULL, 0),
1554 SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5668_PLL_TRACK_1,
1555 RT5668_ADC_STO1_ASRC_SFT, 0, NULL, 0),
1556 SND_SOC_DAPM_SUPPLY_S("AD ASRC", 1, RT5668_PLL_TRACK_1,
1557 RT5668_AD_ASRC_SFT, 0, NULL, 0),
1558 SND_SOC_DAPM_SUPPLY_S("DA ASRC", 1, RT5668_PLL_TRACK_1,
1559 RT5668_DA_ASRC_SFT, 0, NULL, 0),
1560 SND_SOC_DAPM_SUPPLY_S("DMIC ASRC", 1, RT5668_PLL_TRACK_1,
1561 RT5668_DMIC_ASRC_SFT, 0, NULL, 0),
1562
1563 /* Input Side */
1564 SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5668_PWR_ANLG_2, RT5668_PWR_MB1_BIT,
1565 0, NULL, 0),
1566 SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5668_PWR_ANLG_2, RT5668_PWR_MB2_BIT,
1567 0, NULL, 0),
1568
1569 /* Input Lines */
1570 SND_SOC_DAPM_INPUT("DMIC L1"),
1571 SND_SOC_DAPM_INPUT("DMIC R1"),
1572
1573 SND_SOC_DAPM_INPUT("IN1P"),
1574
1575 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
1576 set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
1577 SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5668_DMIC_CTRL_1,
1578 RT5668_DMIC_1_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
1579
1580 /* Boost */
1581 SND_SOC_DAPM_PGA("BST1 CBJ", SND_SOC_NOPM,
1582 0, 0, NULL, 0),
1583
1584 SND_SOC_DAPM_SUPPLY("CBJ Power", RT5668_PWR_ANLG_3,
1585 RT5668_PWR_CBJ_BIT, 0, NULL, 0),
1586
1587 /* REC Mixer */
1588 SND_SOC_DAPM_MIXER("RECMIX1L", SND_SOC_NOPM, 0, 0, rt5668_rec1_l_mix,
1589 ARRAY_SIZE(rt5668_rec1_l_mix)),
1590 SND_SOC_DAPM_SUPPLY("RECMIX1L Power", RT5668_PWR_ANLG_2,
1591 RT5668_PWR_RM1_L_BIT, 0, NULL, 0),
1592
1593 /* ADCs */
1594 SND_SOC_DAPM_ADC("ADC1 L", NULL, SND_SOC_NOPM, 0, 0),
1595 SND_SOC_DAPM_ADC("ADC1 R", NULL, SND_SOC_NOPM, 0, 0),
1596
1597 SND_SOC_DAPM_SUPPLY("ADC1 L Power", RT5668_PWR_DIG_1,
1598 RT5668_PWR_ADC_L1_BIT, 0, NULL, 0),
1599 SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5668_PWR_DIG_1,
1600 RT5668_PWR_ADC_R1_BIT, 0, NULL, 0),
1601 SND_SOC_DAPM_SUPPLY("ADC1 clock", RT5668_CHOP_ADC,
1602 RT5668_CKGEN_ADC1_SFT, 0, NULL, 0),
1603
1604 /* ADC Mux */
1605 SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
1606 &rt5668_sto1_adc1l_mux),
1607 SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
1608 &rt5668_sto1_adc1r_mux),
1609 SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
1610 &rt5668_sto1_adc2l_mux),
1611 SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
1612 &rt5668_sto1_adc2r_mux),
1613 SND_SOC_DAPM_MUX("Stereo1 ADC L Mux", SND_SOC_NOPM, 0, 0,
1614 &rt5668_sto1_adcl_mux),
1615 SND_SOC_DAPM_MUX("Stereo1 ADC R Mux", SND_SOC_NOPM, 0, 0,
1616 &rt5668_sto1_adcr_mux),
1617 SND_SOC_DAPM_MUX("IF1_ADC Mux", SND_SOC_NOPM, 0, 0,
1618 &rt5668_if1_adc_slot_mux),
1619
1620 /* ADC Mixer */
1621 SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5668_PWR_DIG_2,
1622 RT5668_PWR_ADC_S1F_BIT, 0, set_filter_clk,
1623 SND_SOC_DAPM_PRE_PMU),
1624 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", RT5668_STO1_ADC_DIG_VOL,
1625 RT5668_L_MUTE_SFT, 1, rt5668_sto1_adc_l_mix,
1626 ARRAY_SIZE(rt5668_sto1_adc_l_mix)),
1627 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", RT5668_STO1_ADC_DIG_VOL,
1628 RT5668_R_MUTE_SFT, 1, rt5668_sto1_adc_r_mix,
1629 ARRAY_SIZE(rt5668_sto1_adc_r_mix)),
1630
1631 /* ADC PGA */
1632 SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
1633
1634 /* Digital Interface */
1635 SND_SOC_DAPM_SUPPLY("I2S1", RT5668_PWR_DIG_1, RT5668_PWR_I2S1_BIT,
1636 0, NULL, 0),
1637 SND_SOC_DAPM_SUPPLY("I2S2", RT5668_PWR_DIG_1, RT5668_PWR_I2S2_BIT,
1638 0, NULL, 0),
1639 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
1640 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
1641 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
1642
1643 /* Digital Interface Select */
1644 SND_SOC_DAPM_MUX("IF1 01 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1645 &rt5668_if1_01_adc_swap_mux),
1646 SND_SOC_DAPM_MUX("IF1 23 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1647 &rt5668_if1_23_adc_swap_mux),
1648 SND_SOC_DAPM_MUX("IF1 45 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1649 &rt5668_if1_45_adc_swap_mux),
1650 SND_SOC_DAPM_MUX("IF1 67 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1651 &rt5668_if1_67_adc_swap_mux),
1652 SND_SOC_DAPM_MUX("IF2 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
1653 &rt5668_if2_adc_swap_mux),
1654
1655 SND_SOC_DAPM_MUX("ADCDAT Mux", SND_SOC_NOPM, 0, 0,
1656 &rt5668_adcdat_pin_ctrl),
1657
1658 /* Audio Interface */
1659 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0,
1660 RT5668_I2S1_SDP, RT5668_SEL_ADCDAT_SFT, 1),
1661 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0,
1662 RT5668_I2S2_SDP, RT5668_I2S2_PIN_CFG_SFT, 1),
1663 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
1664
1665 /* Output Side */
1666 /* DAC mixer before sound effect */
1667 SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
1668 rt5668_dac_l_mix, ARRAY_SIZE(rt5668_dac_l_mix)),
1669 SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
1670 rt5668_dac_r_mix, ARRAY_SIZE(rt5668_dac_r_mix)),
1671
1672 /* DAC channel Mux */
1673 SND_SOC_DAPM_MUX("DAC L1 Source", SND_SOC_NOPM, 0, 0,
1674 &rt5668_alg_dac_l1_mux),
1675 SND_SOC_DAPM_MUX("DAC R1 Source", SND_SOC_NOPM, 0, 0,
1676 &rt5668_alg_dac_r1_mux),
1677
1678 /* DAC Mixer */
1679 SND_SOC_DAPM_SUPPLY("DAC Stereo1 Filter", RT5668_PWR_DIG_2,
1680 RT5668_PWR_DAC_S1F_BIT, 0, set_filter_clk,
1681 SND_SOC_DAPM_PRE_PMU),
1682 SND_SOC_DAPM_MIXER("Stereo1 DAC MIXL", SND_SOC_NOPM, 0, 0,
1683 rt5668_sto1_dac_l_mix, ARRAY_SIZE(rt5668_sto1_dac_l_mix)),
1684 SND_SOC_DAPM_MIXER("Stereo1 DAC MIXR", SND_SOC_NOPM, 0, 0,
1685 rt5668_sto1_dac_r_mix, ARRAY_SIZE(rt5668_sto1_dac_r_mix)),
1686
1687 /* DACs */
1688 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5668_PWR_DIG_1,
1689 RT5668_PWR_DAC_L1_BIT, 0),
1690 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5668_PWR_DIG_1,
1691 RT5668_PWR_DAC_R1_BIT, 0),
1692 SND_SOC_DAPM_SUPPLY_S("DAC 1 Clock", 3, RT5668_CHOP_DAC,
1693 RT5668_CKGEN_DAC1_SFT, 0, NULL, 0),
1694
1695 /* HPO */
1696 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5668_hp_event,
1697 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
1698
1699 SND_SOC_DAPM_SUPPLY("HP Amp L", RT5668_PWR_ANLG_1,
1700 RT5668_PWR_HA_L_BIT, 0, NULL, 0),
1701 SND_SOC_DAPM_SUPPLY("HP Amp R", RT5668_PWR_ANLG_1,
1702 RT5668_PWR_HA_R_BIT, 0, NULL, 0),
1703 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RT5668_DEPOP_1,
1704 RT5668_PUMP_EN_SFT, 0, NULL, 0),
1705 SND_SOC_DAPM_SUPPLY_S("Capless", 2, RT5668_DEPOP_1,
1706 RT5668_CAPLESS_EN_SFT, 0, NULL, 0),
1707
1708 SND_SOC_DAPM_SWITCH("HPOL Playback", SND_SOC_NOPM, 0, 0,
1709 &hpol_switch),
1710 SND_SOC_DAPM_SWITCH("HPOR Playback", SND_SOC_NOPM, 0, 0,
1711 &hpor_switch),
1712
1713 /* CLK DET */
1714 SND_SOC_DAPM_SUPPLY("CLKDET SYS", RT5668_CLK_DET,
1715 RT5668_SYS_CLK_DET_SFT, 0, NULL, 0),
1716 SND_SOC_DAPM_SUPPLY("CLKDET PLL1", RT5668_CLK_DET,
1717 RT5668_PLL1_CLK_DET_SFT, 0, NULL, 0),
1718 SND_SOC_DAPM_SUPPLY("CLKDET PLL2", RT5668_CLK_DET,
1719 RT5668_PLL2_CLK_DET_SFT, 0, NULL, 0),
1720 SND_SOC_DAPM_SUPPLY("CLKDET", RT5668_CLK_DET,
1721 RT5668_POW_CLK_DET_SFT, 0, NULL, 0),
1722
1723 /* Output Lines */
1724 SND_SOC_DAPM_OUTPUT("HPOL"),
1725 SND_SOC_DAPM_OUTPUT("HPOR"),
1726
1727};
1728
1729static const struct snd_soc_dapm_route rt5668_dapm_routes[] = {
1730 /*PLL*/
1731 {"ADC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
1732 {"DAC Stereo1 Filter", NULL, "PLL1", is_sys_clk_from_pll1},
1733
1734 /*ASRC*/
1735 {"ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc},
1736 {"DAC Stereo1 Filter", NULL, "DAC STO1 ASRC", is_using_asrc},
1737 {"ADC STO1 ASRC", NULL, "AD ASRC"},
1738 {"DAC STO1 ASRC", NULL, "DA ASRC"},
1739
1740 /*Vref*/
1741 {"MICBIAS1", NULL, "Vref1"},
1742 {"MICBIAS1", NULL, "Vref2"},
1743 {"MICBIAS2", NULL, "Vref1"},
1744 {"MICBIAS2", NULL, "Vref2"},
1745
1746 {"CLKDET SYS", NULL, "CLKDET"},
1747
1748 {"IN1P", NULL, "LDO2"},
1749
1750 {"BST1 CBJ", NULL, "IN1P"},
1751 {"BST1 CBJ", NULL, "CBJ Power"},
1752 {"CBJ Power", NULL, "Vref2"},
1753
1754 {"RECMIX1L", "CBJ Switch", "BST1 CBJ"},
1755 {"RECMIX1L", NULL, "RECMIX1L Power"},
1756
1757 {"ADC1 L", NULL, "RECMIX1L"},
1758 {"ADC1 L", NULL, "ADC1 L Power"},
1759 {"ADC1 L", NULL, "ADC1 clock"},
1760
1761 {"DMIC L1", NULL, "DMIC CLK"},
1762 {"DMIC L1", NULL, "DMIC1 Power"},
1763 {"DMIC R1", NULL, "DMIC CLK"},
1764 {"DMIC R1", NULL, "DMIC1 Power"},
1765 {"DMIC CLK", NULL, "DMIC ASRC"},
1766
1767 {"Stereo1 ADC L Mux", "ADC1 L", "ADC1 L"},
1768 {"Stereo1 ADC L Mux", "ADC1 R", "ADC1 R"},
1769 {"Stereo1 ADC R Mux", "ADC1 L", "ADC1 L"},
1770 {"Stereo1 ADC R Mux", "ADC1 R", "ADC1 R"},
1771
1772 {"Stereo1 ADC L1 Mux", "ADC", "Stereo1 ADC L Mux"},
1773 {"Stereo1 ADC L1 Mux", "DAC MIX", "Stereo1 DAC MIXL"},
1774 {"Stereo1 ADC L2 Mux", "DMIC", "DMIC L1"},
1775 {"Stereo1 ADC L2 Mux", "DAC MIX", "Stereo1 DAC MIXL"},
1776
1777 {"Stereo1 ADC R1 Mux", "ADC", "Stereo1 ADC R Mux"},
1778 {"Stereo1 ADC R1 Mux", "DAC MIX", "Stereo1 DAC MIXR"},
1779 {"Stereo1 ADC R2 Mux", "DMIC", "DMIC R1"},
1780 {"Stereo1 ADC R2 Mux", "DAC MIX", "Stereo1 DAC MIXR"},
1781
1782 {"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"},
1783 {"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"},
1784 {"Stereo1 ADC MIXL", NULL, "ADC Stereo1 Filter"},
1785
1786 {"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"},
1787 {"Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux"},
1788 {"Stereo1 ADC MIXR", NULL, "ADC Stereo1 Filter"},
1789
1790 {"Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL"},
1791 {"Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR"},
1792
1793 {"IF1 01 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1794 {"IF1 01 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1795 {"IF1 01 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1796 {"IF1 01 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1797 {"IF1 23 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1798 {"IF1 23 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1799 {"IF1 23 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1800 {"IF1 23 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1801 {"IF1 45 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1802 {"IF1 45 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1803 {"IF1 45 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1804 {"IF1 45 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1805 {"IF1 67 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1806 {"IF1 67 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1807 {"IF1 67 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1808 {"IF1 67 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1809
1810 {"IF1_ADC Mux", "Slot 0", "IF1 01 ADC Swap Mux"},
1811 {"IF1_ADC Mux", "Slot 2", "IF1 23 ADC Swap Mux"},
1812 {"IF1_ADC Mux", "Slot 4", "IF1 45 ADC Swap Mux"},
1813 {"IF1_ADC Mux", "Slot 6", "IF1 67 ADC Swap Mux"},
1814 {"IF1_ADC Mux", NULL, "I2S1"},
1815 {"ADCDAT Mux", "ADCDAT1", "IF1_ADC Mux"},
1816 {"AIF1TX", NULL, "ADCDAT Mux"},
1817 {"IF2 ADC Swap Mux", "L/R", "Stereo1 ADC MIX"},
1818 {"IF2 ADC Swap Mux", "R/L", "Stereo1 ADC MIX"},
1819 {"IF2 ADC Swap Mux", "L/L", "Stereo1 ADC MIX"},
1820 {"IF2 ADC Swap Mux", "R/R", "Stereo1 ADC MIX"},
1821 {"ADCDAT Mux", "ADCDAT2", "IF2 ADC Swap Mux"},
1822 {"AIF2TX", NULL, "ADCDAT Mux"},
1823
1824 {"IF1 DAC1 L", NULL, "AIF1RX"},
1825 {"IF1 DAC1 L", NULL, "I2S1"},
1826 {"IF1 DAC1 L", NULL, "DAC Stereo1 Filter"},
1827 {"IF1 DAC1 R", NULL, "AIF1RX"},
1828 {"IF1 DAC1 R", NULL, "I2S1"},
1829 {"IF1 DAC1 R", NULL, "DAC Stereo1 Filter"},
1830
1831 {"DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"},
1832 {"DAC1 MIXL", "DAC1 Switch", "IF1 DAC1 L"},
1833 {"DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"},
1834 {"DAC1 MIXR", "DAC1 Switch", "IF1 DAC1 R"},
1835
1836 {"Stereo1 DAC MIXL", "DAC L1 Switch", "DAC1 MIXL"},
1837 {"Stereo1 DAC MIXL", "DAC R1 Switch", "DAC1 MIXR"},
1838
1839 {"Stereo1 DAC MIXR", "DAC R1 Switch", "DAC1 MIXR"},
1840 {"Stereo1 DAC MIXR", "DAC L1 Switch", "DAC1 MIXL"},
1841
1842 {"DAC L1 Source", "DAC1", "DAC1 MIXL"},
1843 {"DAC L1 Source", "Stereo1 DAC Mixer", "Stereo1 DAC MIXL"},
1844 {"DAC R1 Source", "DAC1", "DAC1 MIXR"},
1845 {"DAC R1 Source", "Stereo1 DAC Mixer", "Stereo1 DAC MIXR"},
1846
1847 {"DAC L1", NULL, "DAC L1 Source"},
1848 {"DAC R1", NULL, "DAC R1 Source"},
1849
1850 {"DAC L1", NULL, "DAC 1 Clock"},
1851 {"DAC R1", NULL, "DAC 1 Clock"},
1852
1853 {"HP Amp", NULL, "DAC L1"},
1854 {"HP Amp", NULL, "DAC R1"},
1855 {"HP Amp", NULL, "HP Amp L"},
1856 {"HP Amp", NULL, "HP Amp R"},
1857 {"HP Amp", NULL, "Capless"},
1858 {"HP Amp", NULL, "Charge Pump"},
1859 {"HP Amp", NULL, "CLKDET SYS"},
1860 {"HP Amp", NULL, "CBJ Power"},
1861 {"HP Amp", NULL, "Vref2"},
1862 {"HPOL Playback", "Switch", "HP Amp"},
1863 {"HPOR Playback", "Switch", "HP Amp"},
1864 {"HPOL", NULL, "HPOL Playback"},
1865 {"HPOR", NULL, "HPOR Playback"},
1866};
1867
1868static int rt5668_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1869 unsigned int rx_mask, int slots, int slot_width)
1870{
1871 struct snd_soc_component *component = dai->component;
1872 unsigned int val = 0;
1873
1874 switch (slots) {
1875 case 4:
1876 val |= RT5668_TDM_TX_CH_4;
1877 val |= RT5668_TDM_RX_CH_4;
1878 break;
1879 case 6:
1880 val |= RT5668_TDM_TX_CH_6;
1881 val |= RT5668_TDM_RX_CH_6;
1882 break;
1883 case 8:
1884 val |= RT5668_TDM_TX_CH_8;
1885 val |= RT5668_TDM_RX_CH_8;
1886 break;
1887 case 2:
1888 break;
1889 default:
1890 return -EINVAL;
1891 }
1892
1893 snd_soc_component_update_bits(component, RT5668_TDM_CTRL,
1894 RT5668_TDM_TX_CH_MASK | RT5668_TDM_RX_CH_MASK, val);
1895
1896 switch (slot_width) {
1897 case 16:
1898 val = RT5668_TDM_CL_16;
1899 break;
1900 case 20:
1901 val = RT5668_TDM_CL_20;
1902 break;
1903 case 24:
1904 val = RT5668_TDM_CL_24;
1905 break;
1906 case 32:
1907 val = RT5668_TDM_CL_32;
1908 break;
1909 default:
1910 return -EINVAL;
1911 }
1912
1913 snd_soc_component_update_bits(component, RT5668_TDM_TCON_CTRL,
1914 RT5668_TDM_CL_MASK, val);
1915
1916 return 0;
1917}
1918
1919
1920static int rt5668_hw_params(struct snd_pcm_substream *substream,
1921 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1922{
1923 struct snd_soc_component *component = dai->component;
1924 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
1925 unsigned int len_1 = 0, len_2 = 0;
1926 int pre_div, frame_size;
1927
1928 rt5668->lrck[dai->id] = params_rate(params);
1929 pre_div = rl6231_get_clk_info(rt5668->sysclk, rt5668->lrck[dai->id]);
1930
1931 frame_size = snd_soc_params_to_frame_size(params);
1932 if (frame_size < 0) {
1933 dev_err(component->dev, "Unsupported frame size: %d\n",
1934 frame_size);
1935 return -EINVAL;
1936 }
1937
1938 dev_dbg(dai->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
1939 rt5668->lrck[dai->id], pre_div, dai->id);
1940
1941 switch (params_width(params)) {
1942 case 16:
1943 break;
1944 case 20:
1945 len_1 |= RT5668_I2S1_DL_20;
1946 len_2 |= RT5668_I2S2_DL_20;
1947 break;
1948 case 24:
1949 len_1 |= RT5668_I2S1_DL_24;
1950 len_2 |= RT5668_I2S2_DL_24;
1951 break;
1952 case 32:
1953 len_1 |= RT5668_I2S1_DL_32;
1954 len_2 |= RT5668_I2S2_DL_24;
1955 break;
1956 case 8:
1957 len_1 |= RT5668_I2S2_DL_8;
1958 len_2 |= RT5668_I2S2_DL_8;
1959 break;
1960 default:
1961 return -EINVAL;
1962 }
1963
1964 switch (dai->id) {
1965 case RT5668_AIF1:
1966 snd_soc_component_update_bits(component, RT5668_I2S1_SDP,
1967 RT5668_I2S1_DL_MASK, len_1);
1968 if (rt5668->master[RT5668_AIF1]) {
1969 snd_soc_component_update_bits(component,
1970 RT5668_ADDA_CLK_1, RT5668_I2S_M_DIV_MASK,
1971 pre_div << RT5668_I2S_M_DIV_SFT);
1972 }
1973 if (params_channels(params) == 1) /* mono mode */
1974 snd_soc_component_update_bits(component,
1975 RT5668_I2S1_SDP, RT5668_I2S1_MONO_MASK,
1976 RT5668_I2S1_MONO_EN);
1977 else
1978 snd_soc_component_update_bits(component,
1979 RT5668_I2S1_SDP, RT5668_I2S1_MONO_MASK,
1980 RT5668_I2S1_MONO_DIS);
1981 break;
1982 case RT5668_AIF2:
1983 snd_soc_component_update_bits(component, RT5668_I2S2_SDP,
1984 RT5668_I2S2_DL_MASK, len_2);
1985 if (rt5668->master[RT5668_AIF2]) {
1986 snd_soc_component_update_bits(component,
1987 RT5668_I2S_M_CLK_CTRL_1, RT5668_I2S2_M_PD_MASK,
1988 pre_div << RT5668_I2S2_M_PD_SFT);
1989 }
1990 if (params_channels(params) == 1) /* mono mode */
1991 snd_soc_component_update_bits(component,
1992 RT5668_I2S2_SDP, RT5668_I2S2_MONO_MASK,
1993 RT5668_I2S2_MONO_EN);
1994 else
1995 snd_soc_component_update_bits(component,
1996 RT5668_I2S2_SDP, RT5668_I2S2_MONO_MASK,
1997 RT5668_I2S2_MONO_DIS);
1998 break;
1999 default:
2000 dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
2001 return -EINVAL;
2002 }
2003
2004 return 0;
2005}
2006
2007static int rt5668_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2008{
2009 struct snd_soc_component *component = dai->component;
2010 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2011 unsigned int reg_val = 0, tdm_ctrl = 0;
2012
2013 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2014 case SND_SOC_DAIFMT_CBM_CFM:
2015 rt5668->master[dai->id] = 1;
2016 break;
2017 case SND_SOC_DAIFMT_CBS_CFS:
2018 rt5668->master[dai->id] = 0;
2019 break;
2020 default:
2021 return -EINVAL;
2022 }
2023
2024 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2025 case SND_SOC_DAIFMT_NB_NF:
2026 break;
2027 case SND_SOC_DAIFMT_IB_NF:
2028 reg_val |= RT5668_I2S_BP_INV;
2029 tdm_ctrl |= RT5668_TDM_S_BP_INV;
2030 break;
2031 case SND_SOC_DAIFMT_NB_IF:
2032 if (dai->id == RT5668_AIF1)
2033 tdm_ctrl |= RT5668_TDM_S_LP_INV | RT5668_TDM_M_BP_INV;
2034 else
2035 return -EINVAL;
2036 break;
2037 case SND_SOC_DAIFMT_IB_IF:
2038 if (dai->id == RT5668_AIF1)
2039 tdm_ctrl |= RT5668_TDM_S_BP_INV | RT5668_TDM_S_LP_INV |
2040 RT5668_TDM_M_BP_INV | RT5668_TDM_M_LP_INV;
2041 else
2042 return -EINVAL;
2043 break;
2044 default:
2045 return -EINVAL;
2046 }
2047
2048 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2049 case SND_SOC_DAIFMT_I2S:
2050 break;
2051 case SND_SOC_DAIFMT_LEFT_J:
2052 reg_val |= RT5668_I2S_DF_LEFT;
2053 tdm_ctrl |= RT5668_TDM_DF_LEFT;
2054 break;
2055 case SND_SOC_DAIFMT_DSP_A:
2056 reg_val |= RT5668_I2S_DF_PCM_A;
2057 tdm_ctrl |= RT5668_TDM_DF_PCM_A;
2058 break;
2059 case SND_SOC_DAIFMT_DSP_B:
2060 reg_val |= RT5668_I2S_DF_PCM_B;
2061 tdm_ctrl |= RT5668_TDM_DF_PCM_B;
2062 break;
2063 default:
2064 return -EINVAL;
2065 }
2066
2067 switch (dai->id) {
2068 case RT5668_AIF1:
2069 snd_soc_component_update_bits(component, RT5668_I2S1_SDP,
2070 RT5668_I2S_DF_MASK, reg_val);
2071 snd_soc_component_update_bits(component, RT5668_TDM_TCON_CTRL,
2072 RT5668_TDM_MS_MASK | RT5668_TDM_S_BP_MASK |
2073 RT5668_TDM_DF_MASK | RT5668_TDM_M_BP_MASK |
2074 RT5668_TDM_M_LP_MASK | RT5668_TDM_S_LP_MASK,
2075 tdm_ctrl | rt5668->master[dai->id]);
2076 break;
2077 case RT5668_AIF2:
2078 if (rt5668->master[dai->id] == 0)
2079 reg_val |= RT5668_I2S2_MS_S;
2080 snd_soc_component_update_bits(component, RT5668_I2S2_SDP,
2081 RT5668_I2S2_MS_MASK | RT5668_I2S_BP_MASK |
2082 RT5668_I2S_DF_MASK, reg_val);
2083 break;
2084 default:
2085 dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
2086 return -EINVAL;
2087 }
2088 return 0;
2089}
2090
2091static int rt5668_set_component_sysclk(struct snd_soc_component *component,
2092 int clk_id, int source, unsigned int freq, int dir)
2093{
2094 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2095 unsigned int reg_val = 0, src = 0;
2096
2097 if (freq == rt5668->sysclk && clk_id == rt5668->sysclk_src)
2098 return 0;
2099
2100 switch (clk_id) {
2101 case RT5668_SCLK_S_MCLK:
2102 reg_val |= RT5668_SCLK_SRC_MCLK;
2103 src = RT5668_CLK_SRC_MCLK;
2104 break;
2105 case RT5668_SCLK_S_PLL1:
2106 reg_val |= RT5668_SCLK_SRC_PLL1;
2107 src = RT5668_CLK_SRC_PLL1;
2108 break;
2109 case RT5668_SCLK_S_PLL2:
2110 reg_val |= RT5668_SCLK_SRC_PLL2;
2111 src = RT5668_CLK_SRC_PLL2;
2112 break;
2113 case RT5668_SCLK_S_RCCLK:
2114 reg_val |= RT5668_SCLK_SRC_RCCLK;
2115 src = RT5668_CLK_SRC_RCCLK;
2116 break;
2117 default:
2118 dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
2119 return -EINVAL;
2120 }
2121 snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2122 RT5668_SCLK_SRC_MASK, reg_val);
2123
2124 if (rt5668->master[RT5668_AIF2]) {
2125 snd_soc_component_update_bits(component,
2126 RT5668_I2S_M_CLK_CTRL_1, RT5668_I2S2_SRC_MASK,
2127 src << RT5668_I2S2_SRC_SFT);
2128 }
2129
2130 rt5668->sysclk = freq;
2131 rt5668->sysclk_src = clk_id;
2132
2133 dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
2134 freq, clk_id);
2135
2136 return 0;
2137}
2138
2139static int rt5668_set_component_pll(struct snd_soc_component *component,
2140 int pll_id, int source, unsigned int freq_in,
2141 unsigned int freq_out)
2142{
2143 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2144 struct rl6231_pll_code pll_code;
2145 int ret;
2146
2147 if (source == rt5668->pll_src && freq_in == rt5668->pll_in &&
2148 freq_out == rt5668->pll_out)
2149 return 0;
2150
2151 if (!freq_in || !freq_out) {
2152 dev_dbg(component->dev, "PLL disabled\n");
2153
2154 rt5668->pll_in = 0;
2155 rt5668->pll_out = 0;
2156 snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2157 RT5668_SCLK_SRC_MASK, RT5668_SCLK_SRC_MCLK);
2158 return 0;
2159 }
2160
2161 switch (source) {
2162 case RT5668_PLL1_S_MCLK:
2163 snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2164 RT5668_PLL1_SRC_MASK, RT5668_PLL1_SRC_MCLK);
2165 break;
2166 case RT5668_PLL1_S_BCLK1:
2167 snd_soc_component_update_bits(component, RT5668_GLB_CLK,
2168 RT5668_PLL1_SRC_MASK, RT5668_PLL1_SRC_BCLK1);
2169 break;
2170 default:
2171 dev_err(component->dev, "Unknown PLL Source %d\n", source);
2172 return -EINVAL;
2173 }
2174
2175 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
2176 if (ret < 0) {
2177 dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
2178 return ret;
2179 }
2180
2181 dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
2182 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
2183 pll_code.n_code, pll_code.k_code);
2184
2185 snd_soc_component_write(component, RT5668_PLL_CTRL_1,
2186 pll_code.n_code << RT5668_PLL_N_SFT | pll_code.k_code);
2187 snd_soc_component_write(component, RT5668_PLL_CTRL_2,
2188 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SFT |
2189 pll_code.m_bp << RT5668_PLL_M_BP_SFT);
2190
2191 rt5668->pll_in = freq_in;
2192 rt5668->pll_out = freq_out;
2193 rt5668->pll_src = source;
2194
2195 return 0;
2196}
2197
2198static int rt5668_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
2199{
2200 struct snd_soc_component *component = dai->component;
2201 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2202
2203 rt5668->bclk[dai->id] = ratio;
2204
2205 switch (ratio) {
2206 case 64:
2207 snd_soc_component_update_bits(component, RT5668_ADDA_CLK_2,
2208 RT5668_I2S2_BCLK_MS2_MASK,
2209 RT5668_I2S2_BCLK_MS2_64);
2210 break;
2211 case 32:
2212 snd_soc_component_update_bits(component, RT5668_ADDA_CLK_2,
2213 RT5668_I2S2_BCLK_MS2_MASK,
2214 RT5668_I2S2_BCLK_MS2_32);
2215 break;
2216 default:
2217 dev_err(dai->dev, "Invalid bclk ratio %d\n", ratio);
2218 return -EINVAL;
2219 }
2220
2221 return 0;
2222}
2223
2224static int rt5668_set_bias_level(struct snd_soc_component *component,
2225 enum snd_soc_bias_level level)
2226{
2227 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2228
2229 switch (level) {
2230 case SND_SOC_BIAS_PREPARE:
2231 regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2232 RT5668_PWR_MB | RT5668_PWR_BG,
2233 RT5668_PWR_MB | RT5668_PWR_BG);
2234 regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2235 RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO,
2236 RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO);
2237 break;
2238
2239 case SND_SOC_BIAS_STANDBY:
2240 regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2241 RT5668_PWR_MB, RT5668_PWR_MB);
2242 regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2243 RT5668_DIG_GATE_CTRL, RT5668_DIG_GATE_CTRL);
2244 break;
2245 case SND_SOC_BIAS_OFF:
2246 regmap_update_bits(rt5668->regmap, RT5668_PWR_DIG_1,
2247 RT5668_DIG_GATE_CTRL | RT5668_PWR_LDO, 0);
2248 regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2249 RT5668_PWR_MB | RT5668_PWR_BG, 0);
2250 break;
2251
2252 default:
2253 break;
2254 }
2255
2256 return 0;
2257}
2258
2259static int rt5668_probe(struct snd_soc_component *component)
2260{
2261 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2262
2263 rt5668->component = component;
2264
2265 return 0;
2266}
2267
2268static void rt5668_remove(struct snd_soc_component *component)
2269{
2270 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2271
2272 rt5668_reset(rt5668->regmap);
2273}
2274
2275#ifdef CONFIG_PM
2276static int rt5668_suspend(struct snd_soc_component *component)
2277{
2278 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2279
2280 regcache_cache_only(rt5668->regmap, true);
2281 regcache_mark_dirty(rt5668->regmap);
2282 return 0;
2283}
2284
2285static int rt5668_resume(struct snd_soc_component *component)
2286{
2287 struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
2288
2289 regcache_cache_only(rt5668->regmap, false);
2290 regcache_sync(rt5668->regmap);
2291
2292 return 0;
2293}
2294#else
2295#define rt5668_suspend NULL
2296#define rt5668_resume NULL
2297#endif
2298
2299#define RT5668_STEREO_RATES SNDRV_PCM_RATE_8000_192000
2300#define RT5668_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
2301 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
2302
2303static const struct snd_soc_dai_ops rt5668_aif1_dai_ops = {
2304 .hw_params = rt5668_hw_params,
2305 .set_fmt = rt5668_set_dai_fmt,
2306 .set_tdm_slot = rt5668_set_tdm_slot,
2307};
2308
2309static const struct snd_soc_dai_ops rt5668_aif2_dai_ops = {
2310 .hw_params = rt5668_hw_params,
2311 .set_fmt = rt5668_set_dai_fmt,
2312 .set_bclk_ratio = rt5668_set_bclk_ratio,
2313};
2314
2315static struct snd_soc_dai_driver rt5668_dai[] = {
2316 {
2317 .name = "rt5668-aif1",
2318 .id = RT5668_AIF1,
2319 .playback = {
2320 .stream_name = "AIF1 Playback",
2321 .channels_min = 1,
2322 .channels_max = 2,
2323 .rates = RT5668_STEREO_RATES,
2324 .formats = RT5668_FORMATS,
2325 },
2326 .capture = {
2327 .stream_name = "AIF1 Capture",
2328 .channels_min = 1,
2329 .channels_max = 2,
2330 .rates = RT5668_STEREO_RATES,
2331 .formats = RT5668_FORMATS,
2332 },
2333 .ops = &rt5668_aif1_dai_ops,
2334 },
2335 {
2336 .name = "rt5668-aif2",
2337 .id = RT5668_AIF2,
2338 .capture = {
2339 .stream_name = "AIF2 Capture",
2340 .channels_min = 1,
2341 .channels_max = 2,
2342 .rates = RT5668_STEREO_RATES,
2343 .formats = RT5668_FORMATS,
2344 },
2345 .ops = &rt5668_aif2_dai_ops,
2346 },
2347};
2348
2349static const struct snd_soc_component_driver soc_component_dev_rt5668 = {
2350 .probe = rt5668_probe,
2351 .remove = rt5668_remove,
2352 .suspend = rt5668_suspend,
2353 .resume = rt5668_resume,
2354 .set_bias_level = rt5668_set_bias_level,
2355 .controls = rt5668_snd_controls,
2356 .num_controls = ARRAY_SIZE(rt5668_snd_controls),
2357 .dapm_widgets = rt5668_dapm_widgets,
2358 .num_dapm_widgets = ARRAY_SIZE(rt5668_dapm_widgets),
2359 .dapm_routes = rt5668_dapm_routes,
2360 .num_dapm_routes = ARRAY_SIZE(rt5668_dapm_routes),
2361 .set_sysclk = rt5668_set_component_sysclk,
2362 .set_pll = rt5668_set_component_pll,
2363 .set_jack = rt5668_set_jack_detect,
2364 .use_pmdown_time = 1,
2365 .endianness = 1,
2366 .non_legacy_dai_naming = 1,
2367};
2368
2369static const struct regmap_config rt5668_regmap = {
2370 .reg_bits = 16,
2371 .val_bits = 16,
2372 .max_register = RT5668_I2C_MODE,
2373 .volatile_reg = rt5668_volatile_register,
2374 .readable_reg = rt5668_readable_register,
2375 .cache_type = REGCACHE_RBTREE,
2376 .reg_defaults = rt5668_reg,
2377 .num_reg_defaults = ARRAY_SIZE(rt5668_reg),
2378 .use_single_rw = true,
2379};
2380
2381static const struct i2c_device_id rt5668_i2c_id[] = {
2382 {"rt5668b", 0},
2383 {}
2384};
2385MODULE_DEVICE_TABLE(i2c, rt5668_i2c_id);
2386
2387static int rt5668_parse_dt(struct rt5668_priv *rt5668, struct device *dev)
2388{
2389
2390 of_property_read_u32(dev->of_node, "realtek,dmic1-data-pin",
2391 &rt5668->pdata.dmic1_data_pin);
2392 of_property_read_u32(dev->of_node, "realtek,dmic1-clk-pin",
2393 &rt5668->pdata.dmic1_clk_pin);
2394 of_property_read_u32(dev->of_node, "realtek,jd-src",
2395 &rt5668->pdata.jd_src);
2396
2397 rt5668->pdata.ldo1_en = of_get_named_gpio(dev->of_node,
2398 "realtek,ldo1-en-gpios", 0);
2399
2400 return 0;
2401}
2402
2403static void rt5668_calibrate(struct rt5668_priv *rt5668)
2404{
2405 int value, count;
2406
2407 mutex_lock(&rt5668->calibrate_mutex);
2408
2409 rt5668_reset(rt5668->regmap);
2410 regmap_write(rt5668->regmap, RT5668_PWR_ANLG_1, 0xa2bf);
2411 usleep_range(15000, 20000);
2412 regmap_write(rt5668->regmap, RT5668_PWR_ANLG_1, 0xf2bf);
2413 regmap_write(rt5668->regmap, RT5668_MICBIAS_2, 0x0380);
2414 regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x8001);
2415 regmap_write(rt5668->regmap, RT5668_TEST_MODE_CTRL_1, 0x0000);
2416 regmap_write(rt5668->regmap, RT5668_STO1_DAC_MIXER, 0x2080);
2417 regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0x4040);
2418 regmap_write(rt5668->regmap, RT5668_DEPOP_1, 0x0069);
2419 regmap_write(rt5668->regmap, RT5668_CHOP_DAC, 0x3000);
2420 regmap_write(rt5668->regmap, RT5668_HP_CTRL_2, 0x6000);
2421 regmap_write(rt5668->regmap, RT5668_HP_CHARGE_PUMP_1, 0x0f26);
2422 regmap_write(rt5668->regmap, RT5668_CALIB_ADC_CTRL, 0x7f05);
2423 regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0x686c);
2424 regmap_write(rt5668->regmap, RT5668_CAL_REC, 0x0d0d);
2425 regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_9, 0x000f);
2426 regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x8d01);
2427 regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_2, 0x0321);
2428 regmap_write(rt5668->regmap, RT5668_HP_LOGIC_CTRL_2, 0x0004);
2429 regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_1, 0x7c00);
2430 regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_3, 0x06a1);
2431 regmap_write(rt5668->regmap, RT5668_A_DAC1_MUX, 0x0311);
2432 regmap_write(rt5668->regmap, RT5668_RESET_HPF_CTRL, 0x0000);
2433 regmap_write(rt5668->regmap, RT5668_ADC_STO1_HP_CTRL_1, 0x3320);
2434
2435 regmap_write(rt5668->regmap, RT5668_HP_CALIB_CTRL_1, 0xfc00);
2436
2437 for (count = 0; count < 60; count++) {
2438 regmap_read(rt5668->regmap, RT5668_HP_CALIB_STA_1, &value);
2439 if (!(value & 0x8000))
2440 break;
2441
2442 usleep_range(10000, 10005);
2443 }
2444
2445 if (count >= 60)
2446 pr_err("HP Calibration Failure\n");
2447
2448 /* restore settings */
2449 regmap_write(rt5668->regmap, RT5668_STO1_ADC_MIXER, 0xc0c4);
2450 regmap_write(rt5668->regmap, RT5668_PWR_DIG_1, 0x0000);
2451
2452 mutex_unlock(&rt5668->calibrate_mutex);
2453
2454}
2455
2456static int rt5668_i2c_probe(struct i2c_client *i2c,
2457 const struct i2c_device_id *id)
2458{
2459 struct rt5668_platform_data *pdata = dev_get_platdata(&i2c->dev);
2460 struct rt5668_priv *rt5668;
2461 int i, ret;
2462 unsigned int val;
2463
2464 rt5668 = devm_kzalloc(&i2c->dev, sizeof(struct rt5668_priv),
2465 GFP_KERNEL);
2466
2467 if (rt5668 == NULL)
2468 return -ENOMEM;
2469
2470 i2c_set_clientdata(i2c, rt5668);
2471
2472 if (pdata)
2473 rt5668->pdata = *pdata;
2474 else
2475 rt5668_parse_dt(rt5668, &i2c->dev);
2476
2477 rt5668->regmap = devm_regmap_init_i2c(i2c, &rt5668_regmap);
2478 if (IS_ERR(rt5668->regmap)) {
2479 ret = PTR_ERR(rt5668->regmap);
2480 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2481 ret);
2482 return ret;
2483 }
2484
2485 for (i = 0; i < ARRAY_SIZE(rt5668->supplies); i++)
2486 rt5668->supplies[i].supply = rt5668_supply_names[i];
2487
2488 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(rt5668->supplies),
2489 rt5668->supplies);
2490 if (ret != 0) {
2491 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2492 return ret;
2493 }
2494
2495 ret = regulator_bulk_enable(ARRAY_SIZE(rt5668->supplies),
2496 rt5668->supplies);
2497 if (ret != 0) {
2498 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2499 return ret;
2500 }
2501
2502 if (gpio_is_valid(rt5668->pdata.ldo1_en)) {
2503 if (devm_gpio_request_one(&i2c->dev, rt5668->pdata.ldo1_en,
2504 GPIOF_OUT_INIT_HIGH, "rt5668"))
2505 dev_err(&i2c->dev, "Fail gpio_request gpio_ldo\n");
2506 }
2507
2508 /* Sleep for 300 ms miniumum */
2509 usleep_range(300000, 350000);
2510
2511 regmap_write(rt5668->regmap, RT5668_I2C_MODE, 0x1);
2512 usleep_range(10000, 15000);
2513
2514 regmap_read(rt5668->regmap, RT5668_DEVICE_ID, &val);
2515 if (val != DEVICE_ID) {
2516 pr_err("Device with ID register %x is not rt5668\n", val);
2517 return -ENODEV;
2518 }
2519
2520 rt5668_reset(rt5668->regmap);
2521
2522 rt5668_calibrate(rt5668);
2523
2524 regmap_write(rt5668->regmap, RT5668_DEPOP_1, 0x0000);
2525
2526 /* DMIC pin*/
2527 if (rt5668->pdata.dmic1_data_pin != RT5668_DMIC1_NULL) {
2528 switch (rt5668->pdata.dmic1_data_pin) {
2529 case RT5668_DMIC1_DATA_GPIO2: /* share with LRCK2 */
2530 regmap_update_bits(rt5668->regmap, RT5668_DMIC_CTRL_1,
2531 RT5668_DMIC_1_DP_MASK, RT5668_DMIC_1_DP_GPIO2);
2532 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2533 RT5668_GP2_PIN_MASK, RT5668_GP2_PIN_DMIC_SDA);
2534 break;
2535
2536 case RT5668_DMIC1_DATA_GPIO5: /* share with DACDAT1 */
2537 regmap_update_bits(rt5668->regmap, RT5668_DMIC_CTRL_1,
2538 RT5668_DMIC_1_DP_MASK, RT5668_DMIC_1_DP_GPIO5);
2539 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2540 RT5668_GP5_PIN_MASK, RT5668_GP5_PIN_DMIC_SDA);
2541 break;
2542
2543 default:
2544 dev_dbg(&i2c->dev, "invalid DMIC_DAT pin\n");
2545 break;
2546 }
2547
2548 switch (rt5668->pdata.dmic1_clk_pin) {
2549 case RT5668_DMIC1_CLK_GPIO1: /* share with IRQ */
2550 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2551 RT5668_GP1_PIN_MASK, RT5668_GP1_PIN_DMIC_CLK);
2552 break;
2553
2554 case RT5668_DMIC1_CLK_GPIO3: /* share with BCLK2 */
2555 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2556 RT5668_GP3_PIN_MASK, RT5668_GP3_PIN_DMIC_CLK);
2557 break;
2558
2559 default:
2560 dev_dbg(&i2c->dev, "invalid DMIC_CLK pin\n");
2561 break;
2562 }
2563 }
2564
2565 regmap_update_bits(rt5668->regmap, RT5668_PWR_ANLG_1,
2566 RT5668_LDO1_DVO_MASK | RT5668_HP_DRIVER_MASK,
2567 RT5668_LDO1_DVO_14 | RT5668_HP_DRIVER_5X);
2568 regmap_write(rt5668->regmap, RT5668_MICBIAS_2, 0x0380);
2569 regmap_update_bits(rt5668->regmap, RT5668_GPIO_CTRL_1,
2570 RT5668_GP4_PIN_MASK | RT5668_GP5_PIN_MASK,
2571 RT5668_GP4_PIN_ADCDAT1 | RT5668_GP5_PIN_DACDAT1);
2572 regmap_write(rt5668->regmap, RT5668_TEST_MODE_CTRL_1, 0x0000);
2573
2574 INIT_DELAYED_WORK(&rt5668->jack_detect_work,
2575 rt5668_jack_detect_handler);
2576 INIT_DELAYED_WORK(&rt5668->jd_check_work,
2577 rt5668_jd_check_handler);
2578
2579 mutex_init(&rt5668->calibrate_mutex);
2580
2581 if (i2c->irq) {
2582 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
2583 rt5668_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
2584 | IRQF_ONESHOT, "rt5668", rt5668);
2585 if (ret)
2586 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
2587
2588 }
2589
2590 return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5668,
2591 rt5668_dai, ARRAY_SIZE(rt5668_dai));
2592}
2593
2594static int rt5668_i2c_remove(struct i2c_client *i2c)
2595{
2596 snd_soc_unregister_component(&i2c->dev);
2597
2598 return 0;
2599}
2600
2601static void rt5668_i2c_shutdown(struct i2c_client *client)
2602{
2603 struct rt5668_priv *rt5668 = i2c_get_clientdata(client);
2604
2605 rt5668_reset(rt5668->regmap);
2606}
2607
2608#ifdef CONFIG_OF
2609static const struct of_device_id rt5668_of_match[] = {
2610 {.compatible = "realtek,rt5668b"},
2611 {},
2612};
2613MODULE_DEVICE_TABLE(of, rt5668_of_match);
2614#endif
2615
2616#ifdef CONFIG_ACPI
2617static const struct acpi_device_id rt5668_acpi_match[] = {
2618 {"10EC5668", 0,},
2619 {},
2620};
2621MODULE_DEVICE_TABLE(acpi, rt5668_acpi_match);
2622#endif
2623
2624static struct i2c_driver rt5668_i2c_driver = {
2625 .driver = {
2626 .name = "rt5668b",
2627 .of_match_table = of_match_ptr(rt5668_of_match),
2628 .acpi_match_table = ACPI_PTR(rt5668_acpi_match),
2629 },
2630 .probe = rt5668_i2c_probe,
2631 .remove = rt5668_i2c_remove,
2632 .shutdown = rt5668_i2c_shutdown,
2633 .id_table = rt5668_i2c_id,
2634};
2635module_i2c_driver(rt5668_i2c_driver);
2636
2637MODULE_DESCRIPTION("ASoC RT5668B driver");
2638MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
2639MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5668.h b/sound/soc/codecs/rt5668.h
new file mode 100644
index 000000000000..3e7bcfd569ec
--- /dev/null
+++ b/sound/soc/codecs/rt5668.h
@@ -0,0 +1,1318 @@
1/*
2 * rt5668.h -- RT5668/RT5658 ALSA SoC audio driver
3 *
4 * Copyright 2018 Realtek Microelectronics
5 * Author: Bard Liao <bardliao@realtek.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
12#ifndef __RT5668_H__
13#define __RT5668_H__
14
15#include <sound/rt5668.h>
16
17#define DEVICE_ID 0x6530
18
19/* Info */
20#define RT5668_RESET 0x0000
21#define RT5668_VERSION_ID 0x00fd
22#define RT5668_VENDOR_ID 0x00fe
23#define RT5668_DEVICE_ID 0x00ff
24/* I/O - Output */
25#define RT5668_HP_CTRL_1 0x0002
26#define RT5668_HP_CTRL_2 0x0003
27#define RT5668_HPL_GAIN 0x0005
28#define RT5668_HPR_GAIN 0x0006
29
30#define RT5668_I2C_CTRL 0x0008
31
32/* I/O - Input */
33#define RT5668_CBJ_BST_CTRL 0x000b
34#define RT5668_CBJ_CTRL_1 0x0010
35#define RT5668_CBJ_CTRL_2 0x0011
36#define RT5668_CBJ_CTRL_3 0x0012
37#define RT5668_CBJ_CTRL_4 0x0013
38#define RT5668_CBJ_CTRL_5 0x0014
39#define RT5668_CBJ_CTRL_6 0x0015
40#define RT5668_CBJ_CTRL_7 0x0016
41/* I/O - ADC/DAC/DMIC */
42#define RT5668_DAC1_DIG_VOL 0x0019
43#define RT5668_STO1_ADC_DIG_VOL 0x001c
44#define RT5668_STO1_ADC_BOOST 0x001f
45#define RT5668_HP_IMP_GAIN_1 0x0022
46#define RT5668_HP_IMP_GAIN_2 0x0023
47/* Mixer - D-D */
48#define RT5668_SIDETONE_CTRL 0x0024
49#define RT5668_STO1_ADC_MIXER 0x0026
50#define RT5668_AD_DA_MIXER 0x0029
51#define RT5668_STO1_DAC_MIXER 0x002a
52#define RT5668_A_DAC1_MUX 0x002b
53#define RT5668_DIG_INF2_DATA 0x0030
54/* Mixer - ADC */
55#define RT5668_REC_MIXER 0x003c
56#define RT5668_CAL_REC 0x0044
57#define RT5668_ALC_BACK_GAIN 0x0049
58/* Power */
59#define RT5668_PWR_DIG_1 0x0061
60#define RT5668_PWR_DIG_2 0x0062
61#define RT5668_PWR_ANLG_1 0x0063
62#define RT5668_PWR_ANLG_2 0x0064
63#define RT5668_PWR_ANLG_3 0x0065
64#define RT5668_PWR_MIXER 0x0066
65#define RT5668_PWR_VOL 0x0067
66/* Clock Detect */
67#define RT5668_CLK_DET 0x006b
68/* Filter Auto Reset */
69#define RT5668_RESET_LPF_CTRL 0x006c
70#define RT5668_RESET_HPF_CTRL 0x006d
71/* DMIC */
72#define RT5668_DMIC_CTRL_1 0x006e
73/* Format - ADC/DAC */
74#define RT5668_I2S1_SDP 0x0070
75#define RT5668_I2S2_SDP 0x0071
76#define RT5668_ADDA_CLK_1 0x0073
77#define RT5668_ADDA_CLK_2 0x0074
78#define RT5668_I2S1_F_DIV_CTRL_1 0x0075
79#define RT5668_I2S1_F_DIV_CTRL_2 0x0076
80/* Format - TDM Control */
81#define RT5668_TDM_CTRL 0x0079
82#define RT5668_TDM_ADDA_CTRL_1 0x007a
83#define RT5668_TDM_ADDA_CTRL_2 0x007b
84#define RT5668_DATA_SEL_CTRL_1 0x007c
85#define RT5668_TDM_TCON_CTRL 0x007e
86/* Function - Analog */
87#define RT5668_GLB_CLK 0x0080
88#define RT5668_PLL_CTRL_1 0x0081
89#define RT5668_PLL_CTRL_2 0x0082
90#define RT5668_PLL_TRACK_1 0x0083
91#define RT5668_PLL_TRACK_2 0x0084
92#define RT5668_PLL_TRACK_3 0x0085
93#define RT5668_PLL_TRACK_4 0x0086
94#define RT5668_PLL_TRACK_5 0x0087
95#define RT5668_PLL_TRACK_6 0x0088
96#define RT5668_PLL_TRACK_11 0x008c
97#define RT5668_SDW_REF_CLK 0x008d
98#define RT5668_DEPOP_1 0x008e
99#define RT5668_DEPOP_2 0x008f
100#define RT5668_HP_CHARGE_PUMP_1 0x0091
101#define RT5668_HP_CHARGE_PUMP_2 0x0092
102#define RT5668_MICBIAS_1 0x0093
103#define RT5668_MICBIAS_2 0x0094
104#define RT5668_PLL_TRACK_12 0x0098
105#define RT5668_PLL_TRACK_14 0x009a
106#define RT5668_PLL2_CTRL_1 0x009b
107#define RT5668_PLL2_CTRL_2 0x009c
108#define RT5668_PLL2_CTRL_3 0x009d
109#define RT5668_PLL2_CTRL_4 0x009e
110#define RT5668_RC_CLK_CTRL 0x009f
111#define RT5668_I2S_M_CLK_CTRL_1 0x00a0
112#define RT5668_I2S2_F_DIV_CTRL_1 0x00a3
113#define RT5668_I2S2_F_DIV_CTRL_2 0x00a4
114/* Function - Digital */
115#define RT5668_EQ_CTRL_1 0x00ae
116#define RT5668_EQ_CTRL_2 0x00af
117#define RT5668_IRQ_CTRL_1 0x00b6
118#define RT5668_IRQ_CTRL_2 0x00b7
119#define RT5668_IRQ_CTRL_3 0x00b8
120#define RT5668_IRQ_CTRL_4 0x00b9
121#define RT5668_INT_ST_1 0x00be
122#define RT5668_GPIO_CTRL_1 0x00c0
123#define RT5668_GPIO_CTRL_2 0x00c1
124#define RT5668_GPIO_CTRL_3 0x00c2
125#define RT5668_HP_AMP_DET_CTRL_1 0x00d0
126#define RT5668_HP_AMP_DET_CTRL_2 0x00d1
127#define RT5668_MID_HP_AMP_DET 0x00d2
128#define RT5668_LOW_HP_AMP_DET 0x00d3
129#define RT5668_DELAY_BUF_CTRL 0x00d4
130#define RT5668_SV_ZCD_1 0x00d9
131#define RT5668_SV_ZCD_2 0x00da
132#define RT5668_IL_CMD_1 0x00db
133#define RT5668_IL_CMD_2 0x00dc
134#define RT5668_IL_CMD_3 0x00dd
135#define RT5668_IL_CMD_4 0x00de
136#define RT5668_IL_CMD_5 0x00df
137#define RT5668_IL_CMD_6 0x00e0
138#define RT5668_4BTN_IL_CMD_1 0x00e2
139#define RT5668_4BTN_IL_CMD_2 0x00e3
140#define RT5668_4BTN_IL_CMD_3 0x00e4
141#define RT5668_4BTN_IL_CMD_4 0x00e5
142#define RT5668_4BTN_IL_CMD_5 0x00e6
143#define RT5668_4BTN_IL_CMD_6 0x00e7
144#define RT5668_4BTN_IL_CMD_7 0x00e8
145
146#define RT5668_ADC_STO1_HP_CTRL_1 0x00ea
147#define RT5668_ADC_STO1_HP_CTRL_2 0x00eb
148#define RT5668_AJD1_CTRL 0x00f0
149#define RT5668_JD1_THD 0x00f1
150#define RT5668_JD2_THD 0x00f2
151#define RT5668_JD_CTRL_1 0x00f6
152/* General Control */
153#define RT5668_DUMMY_1 0x00fa
154#define RT5668_DUMMY_2 0x00fb
155#define RT5668_DUMMY_3 0x00fc
156
157#define RT5668_DAC_ADC_DIG_VOL1 0x0100
158#define RT5668_BIAS_CUR_CTRL_2 0x010b
159#define RT5668_BIAS_CUR_CTRL_3 0x010c
160#define RT5668_BIAS_CUR_CTRL_4 0x010d
161#define RT5668_BIAS_CUR_CTRL_5 0x010e
162#define RT5668_BIAS_CUR_CTRL_6 0x010f
163#define RT5668_BIAS_CUR_CTRL_7 0x0110
164#define RT5668_BIAS_CUR_CTRL_8 0x0111
165#define RT5668_BIAS_CUR_CTRL_9 0x0112
166#define RT5668_BIAS_CUR_CTRL_10 0x0113
167#define RT5668_VREF_REC_OP_FB_CAP_CTRL 0x0117
168#define RT5668_CHARGE_PUMP_1 0x0125
169#define RT5668_DIG_IN_CTRL_1 0x0132
170#define RT5668_PAD_DRIVING_CTRL 0x0136
171#define RT5668_SOFT_RAMP_DEPOP 0x0138
172#define RT5668_CHOP_DAC 0x013a
173#define RT5668_CHOP_ADC 0x013b
174#define RT5668_CALIB_ADC_CTRL 0x013c
175#define RT5668_VOL_TEST 0x013f
176#define RT5668_SPKVDD_DET_STA 0x0142
177#define RT5668_TEST_MODE_CTRL_1 0x0145
178#define RT5668_TEST_MODE_CTRL_2 0x0146
179#define RT5668_TEST_MODE_CTRL_3 0x0147
180#define RT5668_TEST_MODE_CTRL_4 0x0148
181#define RT5668_TEST_MODE_CTRL_5 0x0149
182#define RT5668_PLL1_INTERNAL 0x0150
183#define RT5668_PLL2_INTERNAL 0x0151
184#define RT5668_STO_NG2_CTRL_1 0x0160
185#define RT5668_STO_NG2_CTRL_2 0x0161
186#define RT5668_STO_NG2_CTRL_3 0x0162
187#define RT5668_STO_NG2_CTRL_4 0x0163
188#define RT5668_STO_NG2_CTRL_5 0x0164
189#define RT5668_STO_NG2_CTRL_6 0x0165
190#define RT5668_STO_NG2_CTRL_7 0x0166
191#define RT5668_STO_NG2_CTRL_8 0x0167
192#define RT5668_STO_NG2_CTRL_9 0x0168
193#define RT5668_STO_NG2_CTRL_10 0x0169
194#define RT5668_STO1_DAC_SIL_DET 0x0190
195#define RT5668_SIL_PSV_CTRL1 0x0194
196#define RT5668_SIL_PSV_CTRL2 0x0195
197#define RT5668_SIL_PSV_CTRL3 0x0197
198#define RT5668_SIL_PSV_CTRL4 0x0198
199#define RT5668_SIL_PSV_CTRL5 0x0199
200#define RT5668_HP_IMP_SENS_CTRL_01 0x01af
201#define RT5668_HP_IMP_SENS_CTRL_02 0x01b0
202#define RT5668_HP_IMP_SENS_CTRL_03 0x01b1
203#define RT5668_HP_IMP_SENS_CTRL_04 0x01b2
204#define RT5668_HP_IMP_SENS_CTRL_05 0x01b3
205#define RT5668_HP_IMP_SENS_CTRL_06 0x01b4
206#define RT5668_HP_IMP_SENS_CTRL_07 0x01b5
207#define RT5668_HP_IMP_SENS_CTRL_08 0x01b6
208#define RT5668_HP_IMP_SENS_CTRL_09 0x01b7
209#define RT5668_HP_IMP_SENS_CTRL_10 0x01b8
210#define RT5668_HP_IMP_SENS_CTRL_11 0x01b9
211#define RT5668_HP_IMP_SENS_CTRL_12 0x01ba
212#define RT5668_HP_IMP_SENS_CTRL_13 0x01bb
213#define RT5668_HP_IMP_SENS_CTRL_14 0x01bc
214#define RT5668_HP_IMP_SENS_CTRL_15 0x01bd
215#define RT5668_HP_IMP_SENS_CTRL_16 0x01be
216#define RT5668_HP_IMP_SENS_CTRL_17 0x01bf
217#define RT5668_HP_IMP_SENS_CTRL_18 0x01c0
218#define RT5668_HP_IMP_SENS_CTRL_19 0x01c1
219#define RT5668_HP_IMP_SENS_CTRL_20 0x01c2
220#define RT5668_HP_IMP_SENS_CTRL_21 0x01c3
221#define RT5668_HP_IMP_SENS_CTRL_22 0x01c4
222#define RT5668_HP_IMP_SENS_CTRL_23 0x01c5
223#define RT5668_HP_IMP_SENS_CTRL_24 0x01c6
224#define RT5668_HP_IMP_SENS_CTRL_25 0x01c7
225#define RT5668_HP_IMP_SENS_CTRL_26 0x01c8
226#define RT5668_HP_IMP_SENS_CTRL_27 0x01c9
227#define RT5668_HP_IMP_SENS_CTRL_28 0x01ca
228#define RT5668_HP_IMP_SENS_CTRL_29 0x01cb
229#define RT5668_HP_IMP_SENS_CTRL_30 0x01cc
230#define RT5668_HP_IMP_SENS_CTRL_31 0x01cd
231#define RT5668_HP_IMP_SENS_CTRL_32 0x01ce
232#define RT5668_HP_IMP_SENS_CTRL_33 0x01cf
233#define RT5668_HP_IMP_SENS_CTRL_34 0x01d0
234#define RT5668_HP_IMP_SENS_CTRL_35 0x01d1
235#define RT5668_HP_IMP_SENS_CTRL_36 0x01d2
236#define RT5668_HP_IMP_SENS_CTRL_37 0x01d3
237#define RT5668_HP_IMP_SENS_CTRL_38 0x01d4
238#define RT5668_HP_IMP_SENS_CTRL_39 0x01d5
239#define RT5668_HP_IMP_SENS_CTRL_40 0x01d6
240#define RT5668_HP_IMP_SENS_CTRL_41 0x01d7
241#define RT5668_HP_IMP_SENS_CTRL_42 0x01d8
242#define RT5668_HP_IMP_SENS_CTRL_43 0x01d9
243#define RT5668_HP_LOGIC_CTRL_1 0x01da
244#define RT5668_HP_LOGIC_CTRL_2 0x01db
245#define RT5668_HP_LOGIC_CTRL_3 0x01dc
246#define RT5668_HP_CALIB_CTRL_1 0x01de
247#define RT5668_HP_CALIB_CTRL_2 0x01df
248#define RT5668_HP_CALIB_CTRL_3 0x01e0
249#define RT5668_HP_CALIB_CTRL_4 0x01e1
250#define RT5668_HP_CALIB_CTRL_5 0x01e2
251#define RT5668_HP_CALIB_CTRL_6 0x01e3
252#define RT5668_HP_CALIB_CTRL_7 0x01e4
253#define RT5668_HP_CALIB_CTRL_9 0x01e6
254#define RT5668_HP_CALIB_CTRL_10 0x01e7
255#define RT5668_HP_CALIB_CTRL_11 0x01e8
256#define RT5668_HP_CALIB_STA_1 0x01ea
257#define RT5668_HP_CALIB_STA_2 0x01eb
258#define RT5668_HP_CALIB_STA_3 0x01ec
259#define RT5668_HP_CALIB_STA_4 0x01ed
260#define RT5668_HP_CALIB_STA_5 0x01ee
261#define RT5668_HP_CALIB_STA_6 0x01ef
262#define RT5668_HP_CALIB_STA_7 0x01f0
263#define RT5668_HP_CALIB_STA_8 0x01f1
264#define RT5668_HP_CALIB_STA_9 0x01f2
265#define RT5668_HP_CALIB_STA_10 0x01f3
266#define RT5668_HP_CALIB_STA_11 0x01f4
267#define RT5668_SAR_IL_CMD_1 0x0210
268#define RT5668_SAR_IL_CMD_2 0x0211
269#define RT5668_SAR_IL_CMD_3 0x0212
270#define RT5668_SAR_IL_CMD_4 0x0213
271#define RT5668_SAR_IL_CMD_5 0x0214
272#define RT5668_SAR_IL_CMD_6 0x0215
273#define RT5668_SAR_IL_CMD_7 0x0216
274#define RT5668_SAR_IL_CMD_8 0x0217
275#define RT5668_SAR_IL_CMD_9 0x0218
276#define RT5668_SAR_IL_CMD_10 0x0219
277#define RT5668_SAR_IL_CMD_11 0x021a
278#define RT5668_SAR_IL_CMD_12 0x021b
279#define RT5668_SAR_IL_CMD_13 0x021c
280#define RT5668_EFUSE_CTRL_1 0x0250
281#define RT5668_EFUSE_CTRL_2 0x0251
282#define RT5668_EFUSE_CTRL_3 0x0252
283#define RT5668_EFUSE_CTRL_4 0x0253
284#define RT5668_EFUSE_CTRL_5 0x0254
285#define RT5668_EFUSE_CTRL_6 0x0255
286#define RT5668_EFUSE_CTRL_7 0x0256
287#define RT5668_EFUSE_CTRL_8 0x0257
288#define RT5668_EFUSE_CTRL_9 0x0258
289#define RT5668_EFUSE_CTRL_10 0x0259
290#define RT5668_EFUSE_CTRL_11 0x025a
291#define RT5668_JD_TOP_VC_VTRL 0x0270
292#define RT5668_DRC1_CTRL_0 0x02ff
293#define RT5668_DRC1_CTRL_1 0x0300
294#define RT5668_DRC1_CTRL_2 0x0301
295#define RT5668_DRC1_CTRL_3 0x0302
296#define RT5668_DRC1_CTRL_4 0x0303
297#define RT5668_DRC1_CTRL_5 0x0304
298#define RT5668_DRC1_CTRL_6 0x0305
299#define RT5668_DRC1_HARD_LMT_CTRL_1 0x0306
300#define RT5668_DRC1_HARD_LMT_CTRL_2 0x0307
301#define RT5668_DRC1_PRIV_1 0x0310
302#define RT5668_DRC1_PRIV_2 0x0311
303#define RT5668_DRC1_PRIV_3 0x0312
304#define RT5668_DRC1_PRIV_4 0x0313
305#define RT5668_DRC1_PRIV_5 0x0314
306#define RT5668_DRC1_PRIV_6 0x0315
307#define RT5668_DRC1_PRIV_7 0x0316
308#define RT5668_DRC1_PRIV_8 0x0317
309#define RT5668_EQ_AUTO_RCV_CTRL1 0x03c0
310#define RT5668_EQ_AUTO_RCV_CTRL2 0x03c1
311#define RT5668_EQ_AUTO_RCV_CTRL3 0x03c2
312#define RT5668_EQ_AUTO_RCV_CTRL4 0x03c3
313#define RT5668_EQ_AUTO_RCV_CTRL5 0x03c4
314#define RT5668_EQ_AUTO_RCV_CTRL6 0x03c5
315#define RT5668_EQ_AUTO_RCV_CTRL7 0x03c6
316#define RT5668_EQ_AUTO_RCV_CTRL8 0x03c7
317#define RT5668_EQ_AUTO_RCV_CTRL9 0x03c8
318#define RT5668_EQ_AUTO_RCV_CTRL10 0x03c9
319#define RT5668_EQ_AUTO_RCV_CTRL11 0x03ca
320#define RT5668_EQ_AUTO_RCV_CTRL12 0x03cb
321#define RT5668_EQ_AUTO_RCV_CTRL13 0x03cc
322#define RT5668_ADC_L_EQ_LPF1_A1 0x03d0
323#define RT5668_R_EQ_LPF1_A1 0x03d1
324#define RT5668_L_EQ_LPF1_H0 0x03d2
325#define RT5668_R_EQ_LPF1_H0 0x03d3
326#define RT5668_L_EQ_BPF1_A1 0x03d4
327#define RT5668_R_EQ_BPF1_A1 0x03d5
328#define RT5668_L_EQ_BPF1_A2 0x03d6
329#define RT5668_R_EQ_BPF1_A2 0x03d7
330#define RT5668_L_EQ_BPF1_H0 0x03d8
331#define RT5668_R_EQ_BPF1_H0 0x03d9
332#define RT5668_L_EQ_BPF2_A1 0x03da
333#define RT5668_R_EQ_BPF2_A1 0x03db
334#define RT5668_L_EQ_BPF2_A2 0x03dc
335#define RT5668_R_EQ_BPF2_A2 0x03dd
336#define RT5668_L_EQ_BPF2_H0 0x03de
337#define RT5668_R_EQ_BPF2_H0 0x03df
338#define RT5668_L_EQ_BPF3_A1 0x03e0
339#define RT5668_R_EQ_BPF3_A1 0x03e1
340#define RT5668_L_EQ_BPF3_A2 0x03e2
341#define RT5668_R_EQ_BPF3_A2 0x03e3
342#define RT5668_L_EQ_BPF3_H0 0x03e4
343#define RT5668_R_EQ_BPF3_H0 0x03e5
344#define RT5668_L_EQ_BPF4_A1 0x03e6
345#define RT5668_R_EQ_BPF4_A1 0x03e7
346#define RT5668_L_EQ_BPF4_A2 0x03e8
347#define RT5668_R_EQ_BPF4_A2 0x03e9
348#define RT5668_L_EQ_BPF4_H0 0x03ea
349#define RT5668_R_EQ_BPF4_H0 0x03eb
350#define RT5668_L_EQ_HPF1_A1 0x03ec
351#define RT5668_R_EQ_HPF1_A1 0x03ed
352#define RT5668_L_EQ_HPF1_H0 0x03ee
353#define RT5668_R_EQ_HPF1_H0 0x03ef
354#define RT5668_L_EQ_PRE_VOL 0x03f0
355#define RT5668_R_EQ_PRE_VOL 0x03f1
356#define RT5668_L_EQ_POST_VOL 0x03f2
357#define RT5668_R_EQ_POST_VOL 0x03f3
358#define RT5668_I2C_MODE 0xffff
359
360
361/* global definition */
362#define RT5668_L_MUTE (0x1 << 15)
363#define RT5668_L_MUTE_SFT 15
364#define RT5668_VOL_L_MUTE (0x1 << 14)
365#define RT5668_VOL_L_SFT 14
366#define RT5668_R_MUTE (0x1 << 7)
367#define RT5668_R_MUTE_SFT 7
368#define RT5668_VOL_R_MUTE (0x1 << 6)
369#define RT5668_VOL_R_SFT 6
370#define RT5668_L_VOL_MASK (0x3f << 8)
371#define RT5668_L_VOL_SFT 8
372#define RT5668_R_VOL_MASK (0x3f)
373#define RT5668_R_VOL_SFT 0
374
375/*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/
376#define RT5668_G_HP (0xf << 8)
377#define RT5668_G_HP_SFT 8
378#define RT5668_G_STO_DA_DMIX (0xf)
379#define RT5668_G_STO_DA_SFT 0
380
381/* CBJ Control (0x000b) */
382#define RT5668_BST_CBJ_MASK (0xf << 8)
383#define RT5668_BST_CBJ_SFT 8
384
385/* Embeeded Jack and Type Detection Control 1 (0x0010) */
386#define RT5668_EMB_JD_EN (0x1 << 15)
387#define RT5668_EMB_JD_EN_SFT 15
388#define RT5668_EMB_JD_RST (0x1 << 14)
389#define RT5668_JD_MODE (0x1 << 13)
390#define RT5668_JD_MODE_SFT 13
391#define RT5668_DET_TYPE (0x1 << 12)
392#define RT5668_DET_TYPE_SFT 12
393#define RT5668_POLA_EXT_JD_MASK (0x1 << 11)
394#define RT5668_POLA_EXT_JD_LOW (0x1 << 11)
395#define RT5668_POLA_EXT_JD_HIGH (0x0 << 11)
396#define RT5668_EXT_JD_DIG (0x1 << 9)
397#define RT5668_POL_FAST_OFF_MASK (0x1 << 8)
398#define RT5668_POL_FAST_OFF_HIGH (0x1 << 8)
399#define RT5668_POL_FAST_OFF_LOW (0x0 << 8)
400#define RT5668_FAST_OFF_MASK (0x1 << 7)
401#define RT5668_FAST_OFF_EN (0x1 << 7)
402#define RT5668_FAST_OFF_DIS (0x0 << 7)
403#define RT5668_VREF_POW_MASK (0x1 << 6)
404#define RT5668_VREF_POW_FSM (0x0 << 6)
405#define RT5668_VREF_POW_REG (0x1 << 6)
406#define RT5668_MB1_PATH_MASK (0x1 << 5)
407#define RT5668_CTRL_MB1_REG (0x1 << 5)
408#define RT5668_CTRL_MB1_FSM (0x0 << 5)
409#define RT5668_MB2_PATH_MASK (0x1 << 4)
410#define RT5668_CTRL_MB2_REG (0x1 << 4)
411#define RT5668_CTRL_MB2_FSM (0x0 << 4)
412#define RT5668_TRIG_JD_MASK (0x1 << 3)
413#define RT5668_TRIG_JD_HIGH (0x1 << 3)
414#define RT5668_TRIG_JD_LOW (0x0 << 3)
415#define RT5668_MIC_CAP_MASK (0x1 << 1)
416#define RT5668_MIC_CAP_HS (0x1 << 1)
417#define RT5668_MIC_CAP_HP (0x0 << 1)
418#define RT5668_MIC_CAP_SRC_MASK (0x1)
419#define RT5668_MIC_CAP_SRC_REG (0x1)
420#define RT5668_MIC_CAP_SRC_ANA (0x0)
421
422/* Embeeded Jack and Type Detection Control 2 (0x0011) */
423#define RT5668_EXT_JD_SRC (0x7 << 4)
424#define RT5668_EXT_JD_SRC_SFT 4
425#define RT5668_EXT_JD_SRC_GPIO_JD1 (0x0 << 4)
426#define RT5668_EXT_JD_SRC_GPIO_JD2 (0x1 << 4)
427#define RT5668_EXT_JD_SRC_JDH (0x2 << 4)
428#define RT5668_EXT_JD_SRC_JDL (0x3 << 4)
429#define RT5668_EXT_JD_SRC_MANUAL (0x4 << 4)
430#define RT5668_JACK_TYPE_MASK (0x3)
431
432/* Combo Jack and Type Detection Control 3 (0x0012) */
433#define RT5668_CBJ_IN_BUF_EN (0x1 << 7)
434
435/* Combo Jack and Type Detection Control 4 (0x0013) */
436#define RT5668_SEL_SHT_MID_TON_MASK (0x3 << 12)
437#define RT5668_SEL_SHT_MID_TON_2 (0x0 << 12)
438#define RT5668_SEL_SHT_MID_TON_3 (0x1 << 12)
439#define RT5668_CBJ_JD_TEST_MASK (0x1 << 6)
440#define RT5668_CBJ_JD_TEST_NORM (0x0 << 6)
441#define RT5668_CBJ_JD_TEST_MODE (0x1 << 6)
442
443/* DAC1 Digital Volume (0x0019) */
444#define RT5668_DAC_L1_VOL_MASK (0xff << 8)
445#define RT5668_DAC_L1_VOL_SFT 8
446#define RT5668_DAC_R1_VOL_MASK (0xff)
447#define RT5668_DAC_R1_VOL_SFT 0
448
449/* ADC Digital Volume Control (0x001c) */
450#define RT5668_ADC_L_VOL_MASK (0x7f << 8)
451#define RT5668_ADC_L_VOL_SFT 8
452#define RT5668_ADC_R_VOL_MASK (0x7f)
453#define RT5668_ADC_R_VOL_SFT 0
454
455/* Stereo1 ADC Boost Gain Control (0x001f) */
456#define RT5668_STO1_ADC_L_BST_MASK (0x3 << 14)
457#define RT5668_STO1_ADC_L_BST_SFT 14
458#define RT5668_STO1_ADC_R_BST_MASK (0x3 << 12)
459#define RT5668_STO1_ADC_R_BST_SFT 12
460
461/* Sidetone Control (0x0024) */
462#define RT5668_ST_SRC_SEL (0x1 << 8)
463#define RT5668_ST_SRC_SFT 8
464#define RT5668_ST_EN_MASK (0x1 << 6)
465#define RT5668_ST_DIS (0x0 << 6)
466#define RT5668_ST_EN (0x1 << 6)
467#define RT5668_ST_EN_SFT 6
468
469/* Stereo1 ADC Mixer Control (0x0026) */
470#define RT5668_M_STO1_ADC_L1 (0x1 << 15)
471#define RT5668_M_STO1_ADC_L1_SFT 15
472#define RT5668_M_STO1_ADC_L2 (0x1 << 14)
473#define RT5668_M_STO1_ADC_L2_SFT 14
474#define RT5668_STO1_ADC1L_SRC_MASK (0x1 << 13)
475#define RT5668_STO1_ADC1L_SRC_SFT 13
476#define RT5668_STO1_ADC1_SRC_ADC (0x1 << 13)
477#define RT5668_STO1_ADC1_SRC_DACMIX (0x0 << 13)
478#define RT5668_STO1_ADC2L_SRC_MASK (0x1 << 12)
479#define RT5668_STO1_ADC2L_SRC_SFT 12
480#define RT5668_STO1_ADCL_SRC_MASK (0x3 << 10)
481#define RT5668_STO1_ADCL_SRC_SFT 10
482#define RT5668_STO1_DD_L_SRC_MASK (0x1 << 9)
483#define RT5668_STO1_DD_L_SRC_SFT 9
484#define RT5668_STO1_DMIC_SRC_MASK (0x1 << 8)
485#define RT5668_STO1_DMIC_SRC_SFT 8
486#define RT5668_STO1_DMIC_SRC_DMIC2 (0x1 << 8)
487#define RT5668_STO1_DMIC_SRC_DMIC1 (0x0 << 8)
488#define RT5668_M_STO1_ADC_R1 (0x1 << 7)
489#define RT5668_M_STO1_ADC_R1_SFT 7
490#define RT5668_M_STO1_ADC_R2 (0x1 << 6)
491#define RT5668_M_STO1_ADC_R2_SFT 6
492#define RT5668_STO1_ADC1R_SRC_MASK (0x1 << 5)
493#define RT5668_STO1_ADC1R_SRC_SFT 5
494#define RT5668_STO1_ADC2R_SRC_MASK (0x1 << 4)
495#define RT5668_STO1_ADC2R_SRC_SFT 4
496#define RT5668_STO1_ADCR_SRC_MASK (0x3 << 2)
497#define RT5668_STO1_ADCR_SRC_SFT 2
498
499/* ADC Mixer to DAC Mixer Control (0x0029) */
500#define RT5668_M_ADCMIX_L (0x1 << 15)
501#define RT5668_M_ADCMIX_L_SFT 15
502#define RT5668_M_DAC1_L (0x1 << 14)
503#define RT5668_M_DAC1_L_SFT 14
504#define RT5668_DAC1_R_SEL_MASK (0x1 << 10)
505#define RT5668_DAC1_R_SEL_SFT 10
506#define RT5668_DAC1_L_SEL_MASK (0x1 << 8)
507#define RT5668_DAC1_L_SEL_SFT 8
508#define RT5668_M_ADCMIX_R (0x1 << 7)
509#define RT5668_M_ADCMIX_R_SFT 7
510#define RT5668_M_DAC1_R (0x1 << 6)
511#define RT5668_M_DAC1_R_SFT 6
512
513/* Stereo1 DAC Mixer Control (0x002a) */
514#define RT5668_M_DAC_L1_STO_L (0x1 << 15)
515#define RT5668_M_DAC_L1_STO_L_SFT 15
516#define RT5668_G_DAC_L1_STO_L_MASK (0x1 << 14)
517#define RT5668_G_DAC_L1_STO_L_SFT 14
518#define RT5668_M_DAC_R1_STO_L (0x1 << 13)
519#define RT5668_M_DAC_R1_STO_L_SFT 13
520#define RT5668_G_DAC_R1_STO_L_MASK (0x1 << 12)
521#define RT5668_G_DAC_R1_STO_L_SFT 12
522#define RT5668_M_DAC_L1_STO_R (0x1 << 7)
523#define RT5668_M_DAC_L1_STO_R_SFT 7
524#define RT5668_G_DAC_L1_STO_R_MASK (0x1 << 6)
525#define RT5668_G_DAC_L1_STO_R_SFT 6
526#define RT5668_M_DAC_R1_STO_R (0x1 << 5)
527#define RT5668_M_DAC_R1_STO_R_SFT 5
528#define RT5668_G_DAC_R1_STO_R_MASK (0x1 << 4)
529#define RT5668_G_DAC_R1_STO_R_SFT 4
530
531/* Analog DAC1 Input Source Control (0x002b) */
532#define RT5668_M_ST_STO_L (0x1 << 9)
533#define RT5668_M_ST_STO_L_SFT 9
534#define RT5668_M_ST_STO_R (0x1 << 8)
535#define RT5668_M_ST_STO_R_SFT 8
536#define RT5668_DAC_L1_SRC_MASK (0x3 << 4)
537#define RT5668_A_DACL1_SFT 4
538#define RT5668_DAC_R1_SRC_MASK (0x3)
539#define RT5668_A_DACR1_SFT 0
540
541/* Digital Interface Data Control (0x0030) */
542#define RT5668_IF2_ADC_SEL_MASK (0x3 << 0)
543#define RT5668_IF2_ADC_SEL_SFT 0
544
545/* REC Left Mixer Control 2 (0x003c) */
546#define RT5668_G_CBJ_RM1_L (0x7 << 10)
547#define RT5668_G_CBJ_RM1_L_SFT 10
548#define RT5668_M_CBJ_RM1_L (0x1 << 7)
549#define RT5668_M_CBJ_RM1_L_SFT 7
550
551/* Power Management for Digital 1 (0x0061) */
552#define RT5668_PWR_I2S1 (0x1 << 15)
553#define RT5668_PWR_I2S1_BIT 15
554#define RT5668_PWR_I2S2 (0x1 << 14)
555#define RT5668_PWR_I2S2_BIT 14
556#define RT5668_PWR_DAC_L1 (0x1 << 11)
557#define RT5668_PWR_DAC_L1_BIT 11
558#define RT5668_PWR_DAC_R1 (0x1 << 10)
559#define RT5668_PWR_DAC_R1_BIT 10
560#define RT5668_PWR_LDO (0x1 << 8)
561#define RT5668_PWR_LDO_BIT 8
562#define RT5668_PWR_ADC_L1 (0x1 << 4)
563#define RT5668_PWR_ADC_L1_BIT 4
564#define RT5668_PWR_ADC_R1 (0x1 << 3)
565#define RT5668_PWR_ADC_R1_BIT 3
566#define RT5668_DIG_GATE_CTRL (0x1 << 0)
567#define RT5668_DIG_GATE_CTRL_SFT 0
568
569
570/* Power Management for Digital 2 (0x0062) */
571#define RT5668_PWR_ADC_S1F (0x1 << 15)
572#define RT5668_PWR_ADC_S1F_BIT 15
573#define RT5668_PWR_DAC_S1F (0x1 << 10)
574#define RT5668_PWR_DAC_S1F_BIT 10
575
576/* Power Management for Analog 1 (0x0063) */
577#define RT5668_PWR_VREF1 (0x1 << 15)
578#define RT5668_PWR_VREF1_BIT 15
579#define RT5668_PWR_FV1 (0x1 << 14)
580#define RT5668_PWR_FV1_BIT 14
581#define RT5668_PWR_VREF2 (0x1 << 13)
582#define RT5668_PWR_VREF2_BIT 13
583#define RT5668_PWR_FV2 (0x1 << 12)
584#define RT5668_PWR_FV2_BIT 12
585#define RT5668_LDO1_DBG_MASK (0x3 << 10)
586#define RT5668_PWR_MB (0x1 << 9)
587#define RT5668_PWR_MB_BIT 9
588#define RT5668_PWR_BG (0x1 << 7)
589#define RT5668_PWR_BG_BIT 7
590#define RT5668_LDO1_BYPASS_MASK (0x1 << 6)
591#define RT5668_LDO1_BYPASS (0x1 << 6)
592#define RT5668_LDO1_NOT_BYPASS (0x0 << 6)
593#define RT5668_PWR_MA_BIT 6
594#define RT5668_LDO1_DVO_MASK (0x3 << 4)
595#define RT5668_LDO1_DVO_09 (0x0 << 4)
596#define RT5668_LDO1_DVO_10 (0x1 << 4)
597#define RT5668_LDO1_DVO_12 (0x2 << 4)
598#define RT5668_LDO1_DVO_14 (0x3 << 4)
599#define RT5668_HP_DRIVER_MASK (0x3 << 2)
600#define RT5668_HP_DRIVER_1X (0x0 << 2)
601#define RT5668_HP_DRIVER_3X (0x1 << 2)
602#define RT5668_HP_DRIVER_5X (0x3 << 2)
603#define RT5668_PWR_HA_L (0x1 << 1)
604#define RT5668_PWR_HA_L_BIT 1
605#define RT5668_PWR_HA_R (0x1 << 0)
606#define RT5668_PWR_HA_R_BIT 0
607
608/* Power Management for Analog 2 (0x0064) */
609#define RT5668_PWR_MB1 (0x1 << 11)
610#define RT5668_PWR_MB1_PWR_DOWN (0x0 << 11)
611#define RT5668_PWR_MB1_BIT 11
612#define RT5668_PWR_MB2 (0x1 << 10)
613#define RT5668_PWR_MB2_PWR_DOWN (0x0 << 10)
614#define RT5668_PWR_MB2_BIT 10
615#define RT5668_PWR_JDH (0x1 << 3)
616#define RT5668_PWR_JDH_BIT 3
617#define RT5668_PWR_JDL (0x1 << 2)
618#define RT5668_PWR_JDL_BIT 2
619#define RT5668_PWR_RM1_L (0x1 << 1)
620#define RT5668_PWR_RM1_L_BIT 1
621
622/* Power Management for Analog 3 (0x0065) */
623#define RT5668_PWR_CBJ (0x1 << 9)
624#define RT5668_PWR_CBJ_BIT 9
625#define RT5668_PWR_PLL (0x1 << 6)
626#define RT5668_PWR_PLL_BIT 6
627#define RT5668_PWR_PLL2B (0x1 << 5)
628#define RT5668_PWR_PLL2B_BIT 5
629#define RT5668_PWR_PLL2F (0x1 << 4)
630#define RT5668_PWR_PLL2F_BIT 4
631#define RT5668_PWR_LDO2 (0x1 << 2)
632#define RT5668_PWR_LDO2_BIT 2
633#define RT5668_PWR_DET_SPKVDD (0x1 << 1)
634#define RT5668_PWR_DET_SPKVDD_BIT 1
635
636/* Power Management for Mixer (0x0066) */
637#define RT5668_PWR_STO1_DAC_L (0x1 << 5)
638#define RT5668_PWR_STO1_DAC_L_BIT 5
639#define RT5668_PWR_STO1_DAC_R (0x1 << 4)
640#define RT5668_PWR_STO1_DAC_R_BIT 4
641
642/* MCLK and System Clock Detection Control (0x006b) */
643#define RT5668_SYS_CLK_DET (0x1 << 15)
644#define RT5668_SYS_CLK_DET_SFT 15
645#define RT5668_PLL1_CLK_DET (0x1 << 14)
646#define RT5668_PLL1_CLK_DET_SFT 14
647#define RT5668_PLL2_CLK_DET (0x1 << 13)
648#define RT5668_PLL2_CLK_DET_SFT 13
649#define RT5668_POW_CLK_DET2_SFT 8
650#define RT5668_POW_CLK_DET_SFT 0
651
652/* Digital Microphone Control 1 (0x006e) */
653#define RT5668_DMIC_1_EN_MASK (0x1 << 15)
654#define RT5668_DMIC_1_EN_SFT 15
655#define RT5668_DMIC_1_DIS (0x0 << 15)
656#define RT5668_DMIC_1_EN (0x1 << 15)
657#define RT5668_DMIC_1_DP_MASK (0x3 << 4)
658#define RT5668_DMIC_1_DP_SFT 4
659#define RT5668_DMIC_1_DP_GPIO2 (0x0 << 4)
660#define RT5668_DMIC_1_DP_GPIO5 (0x1 << 4)
661#define RT5668_DMIC_CLK_MASK (0xf << 0)
662#define RT5668_DMIC_CLK_SFT 0
663
664/* I2S1 Audio Serial Data Port Control (0x0070) */
665#define RT5668_SEL_ADCDAT_MASK (0x1 << 15)
666#define RT5668_SEL_ADCDAT_OUT (0x0 << 15)
667#define RT5668_SEL_ADCDAT_IN (0x1 << 15)
668#define RT5668_SEL_ADCDAT_SFT 15
669#define RT5668_I2S1_TX_CHL_MASK (0x7 << 12)
670#define RT5668_I2S1_TX_CHL_SFT 12
671#define RT5668_I2S1_TX_CHL_16 (0x0 << 12)
672#define RT5668_I2S1_TX_CHL_20 (0x1 << 12)
673#define RT5668_I2S1_TX_CHL_24 (0x2 << 12)
674#define RT5668_I2S1_TX_CHL_32 (0x3 << 12)
675#define RT5668_I2S1_TX_CHL_8 (0x4 << 12)
676#define RT5668_I2S1_RX_CHL_MASK (0x7 << 8)
677#define RT5668_I2S1_RX_CHL_SFT 8
678#define RT5668_I2S1_RX_CHL_16 (0x0 << 8)
679#define RT5668_I2S1_RX_CHL_20 (0x1 << 8)
680#define RT5668_I2S1_RX_CHL_24 (0x2 << 8)
681#define RT5668_I2S1_RX_CHL_32 (0x3 << 8)
682#define RT5668_I2S1_RX_CHL_8 (0x4 << 8)
683#define RT5668_I2S1_MONO_MASK (0x1 << 7)
684#define RT5668_I2S1_MONO_EN (0x1 << 7)
685#define RT5668_I2S1_MONO_DIS (0x0 << 7)
686#define RT5668_I2S2_MONO_MASK (0x1 << 6)
687#define RT5668_I2S2_MONO_EN (0x1 << 6)
688#define RT5668_I2S2_MONO_DIS (0x0 << 6)
689#define RT5668_I2S1_DL_MASK (0x7 << 4)
690#define RT5668_I2S1_DL_SFT 4
691#define RT5668_I2S1_DL_16 (0x0 << 4)
692#define RT5668_I2S1_DL_20 (0x1 << 4)
693#define RT5668_I2S1_DL_24 (0x2 << 4)
694#define RT5668_I2S1_DL_32 (0x3 << 4)
695#define RT5668_I2S1_DL_8 (0x4 << 4)
696
697/* I2S1/2 Audio Serial Data Port Control (0x0070)(0x0071) */
698#define RT5668_I2S2_MS_MASK (0x1 << 15)
699#define RT5668_I2S2_MS_SFT 15
700#define RT5668_I2S2_MS_M (0x0 << 15)
701#define RT5668_I2S2_MS_S (0x1 << 15)
702#define RT5668_I2S2_PIN_CFG_MASK (0x1 << 14)
703#define RT5668_I2S2_PIN_CFG_SFT 14
704#define RT5668_I2S2_CLK_SEL_MASK (0x1 << 11)
705#define RT5668_I2S2_CLK_SEL_SFT 11
706#define RT5668_I2S2_OUT_MASK (0x1 << 9)
707#define RT5668_I2S2_OUT_SFT 9
708#define RT5668_I2S2_OUT_UM (0x0 << 9)
709#define RT5668_I2S2_OUT_M (0x1 << 9)
710#define RT5668_I2S_BP_MASK (0x1 << 8)
711#define RT5668_I2S_BP_SFT 8
712#define RT5668_I2S_BP_NOR (0x0 << 8)
713#define RT5668_I2S_BP_INV (0x1 << 8)
714#define RT5668_I2S2_MONO_EN (0x1 << 6)
715#define RT5668_I2S2_MONO_DIS (0x0 << 6)
716#define RT5668_I2S2_DL_MASK (0x3 << 4)
717#define RT5668_I2S2_DL_SFT 4
718#define RT5668_I2S2_DL_16 (0x0 << 4)
719#define RT5668_I2S2_DL_20 (0x1 << 4)
720#define RT5668_I2S2_DL_24 (0x2 << 4)
721#define RT5668_I2S2_DL_8 (0x3 << 4)
722#define RT5668_I2S_DF_MASK (0x7)
723#define RT5668_I2S_DF_SFT 0
724#define RT5668_I2S_DF_I2S (0x0)
725#define RT5668_I2S_DF_LEFT (0x1)
726#define RT5668_I2S_DF_PCM_A (0x2)
727#define RT5668_I2S_DF_PCM_B (0x3)
728#define RT5668_I2S_DF_PCM_A_N (0x6)
729#define RT5668_I2S_DF_PCM_B_N (0x7)
730
731/* ADC/DAC Clock Control 1 (0x0073) */
732#define RT5668_ADC_OSR_MASK (0xf << 12)
733#define RT5668_ADC_OSR_SFT 12
734#define RT5668_ADC_OSR_D_1 (0x0 << 12)
735#define RT5668_ADC_OSR_D_2 (0x1 << 12)
736#define RT5668_ADC_OSR_D_4 (0x2 << 12)
737#define RT5668_ADC_OSR_D_6 (0x3 << 12)
738#define RT5668_ADC_OSR_D_8 (0x4 << 12)
739#define RT5668_ADC_OSR_D_12 (0x5 << 12)
740#define RT5668_ADC_OSR_D_16 (0x6 << 12)
741#define RT5668_ADC_OSR_D_24 (0x7 << 12)
742#define RT5668_ADC_OSR_D_32 (0x8 << 12)
743#define RT5668_ADC_OSR_D_48 (0x9 << 12)
744#define RT5668_I2S_M_DIV_MASK (0xf << 12)
745#define RT5668_I2S_M_DIV_SFT 8
746#define RT5668_I2S_M_D_1 (0x0 << 8)
747#define RT5668_I2S_M_D_2 (0x1 << 8)
748#define RT5668_I2S_M_D_3 (0x2 << 8)
749#define RT5668_I2S_M_D_4 (0x3 << 8)
750#define RT5668_I2S_M_D_6 (0x4 << 8)
751#define RT5668_I2S_M_D_8 (0x5 << 8)
752#define RT5668_I2S_M_D_12 (0x6 << 8)
753#define RT5668_I2S_M_D_16 (0x7 << 8)
754#define RT5668_I2S_M_D_24 (0x8 << 8)
755#define RT5668_I2S_M_D_32 (0x9 << 8)
756#define RT5668_I2S_M_D_48 (0x10 << 8)
757#define RT5668_I2S_CLK_SRC_MASK (0x7 << 4)
758#define RT5668_I2S_CLK_SRC_SFT 4
759#define RT5668_I2S_CLK_SRC_MCLK (0x0 << 4)
760#define RT5668_I2S_CLK_SRC_PLL1 (0x1 << 4)
761#define RT5668_I2S_CLK_SRC_PLL2 (0x2 << 4)
762#define RT5668_I2S_CLK_SRC_SDW (0x3 << 4)
763#define RT5668_I2S_CLK_SRC_RCCLK (0x4 << 4) /* 25M */
764#define RT5668_DAC_OSR_MASK (0xf << 0)
765#define RT5668_DAC_OSR_SFT 0
766#define RT5668_DAC_OSR_D_1 (0x0 << 0)
767#define RT5668_DAC_OSR_D_2 (0x1 << 0)
768#define RT5668_DAC_OSR_D_4 (0x2 << 0)
769#define RT5668_DAC_OSR_D_6 (0x3 << 0)
770#define RT5668_DAC_OSR_D_8 (0x4 << 0)
771#define RT5668_DAC_OSR_D_12 (0x5 << 0)
772#define RT5668_DAC_OSR_D_16 (0x6 << 0)
773#define RT5668_DAC_OSR_D_24 (0x7 << 0)
774#define RT5668_DAC_OSR_D_32 (0x8 << 0)
775#define RT5668_DAC_OSR_D_48 (0x9 << 0)
776
777/* ADC/DAC Clock Control 2 (0x0074) */
778#define RT5668_I2S2_BCLK_MS2_MASK (0x1 << 11)
779#define RT5668_I2S2_BCLK_MS2_SFT 11
780#define RT5668_I2S2_BCLK_MS2_32 (0x0 << 11)
781#define RT5668_I2S2_BCLK_MS2_64 (0x1 << 11)
782
783
784/* TDM control 1 (0x0079) */
785#define RT5668_TDM_TX_CH_MASK (0x3 << 12)
786#define RT5668_TDM_TX_CH_2 (0x0 << 12)
787#define RT5668_TDM_TX_CH_4 (0x1 << 12)
788#define RT5668_TDM_TX_CH_6 (0x2 << 12)
789#define RT5668_TDM_TX_CH_8 (0x3 << 12)
790#define RT5668_TDM_RX_CH_MASK (0x3 << 8)
791#define RT5668_TDM_RX_CH_2 (0x0 << 8)
792#define RT5668_TDM_RX_CH_4 (0x1 << 8)
793#define RT5668_TDM_RX_CH_6 (0x2 << 8)
794#define RT5668_TDM_RX_CH_8 (0x3 << 8)
795#define RT5668_TDM_ADC_LCA_MASK (0xf << 4)
796#define RT5668_TDM_ADC_LCA_SFT 4
797#define RT5668_TDM_ADC_DL_SFT 0
798
799/* TDM control 3 (0x007a) */
800#define RT5668_IF1_ADC1_SEL_SFT 14
801#define RT5668_IF1_ADC2_SEL_SFT 12
802#define RT5668_IF1_ADC3_SEL_SFT 10
803#define RT5668_IF1_ADC4_SEL_SFT 8
804#define RT5668_TDM_ADC_SEL_SFT 4
805
806/* TDM/I2S control (0x007e) */
807#define RT5668_TDM_S_BP_MASK (0x1 << 15)
808#define RT5668_TDM_S_BP_SFT 15
809#define RT5668_TDM_S_BP_NOR (0x0 << 15)
810#define RT5668_TDM_S_BP_INV (0x1 << 15)
811#define RT5668_TDM_S_LP_MASK (0x1 << 14)
812#define RT5668_TDM_S_LP_SFT 14
813#define RT5668_TDM_S_LP_NOR (0x0 << 14)
814#define RT5668_TDM_S_LP_INV (0x1 << 14)
815#define RT5668_TDM_DF_MASK (0x7 << 11)
816#define RT5668_TDM_DF_SFT 11
817#define RT5668_TDM_DF_I2S (0x0 << 11)
818#define RT5668_TDM_DF_LEFT (0x1 << 11)
819#define RT5668_TDM_DF_PCM_A (0x2 << 11)
820#define RT5668_TDM_DF_PCM_B (0x3 << 11)
821#define RT5668_TDM_DF_PCM_A_N (0x6 << 11)
822#define RT5668_TDM_DF_PCM_B_N (0x7 << 11)
823#define RT5668_TDM_CL_MASK (0x3 << 4)
824#define RT5668_TDM_CL_16 (0x0 << 4)
825#define RT5668_TDM_CL_20 (0x1 << 4)
826#define RT5668_TDM_CL_24 (0x2 << 4)
827#define RT5668_TDM_CL_32 (0x3 << 4)
828#define RT5668_TDM_M_BP_MASK (0x1 << 2)
829#define RT5668_TDM_M_BP_SFT 2
830#define RT5668_TDM_M_BP_NOR (0x0 << 2)
831#define RT5668_TDM_M_BP_INV (0x1 << 2)
832#define RT5668_TDM_M_LP_MASK (0x1 << 1)
833#define RT5668_TDM_M_LP_SFT 1
834#define RT5668_TDM_M_LP_NOR (0x0 << 1)
835#define RT5668_TDM_M_LP_INV (0x1 << 1)
836#define RT5668_TDM_MS_MASK (0x1 << 0)
837#define RT5668_TDM_MS_SFT 0
838#define RT5668_TDM_MS_M (0x0 << 0)
839#define RT5668_TDM_MS_S (0x1 << 0)
840
841/* Global Clock Control (0x0080) */
842#define RT5668_SCLK_SRC_MASK (0x7 << 13)
843#define RT5668_SCLK_SRC_SFT 13
844#define RT5668_SCLK_SRC_MCLK (0x0 << 13)
845#define RT5668_SCLK_SRC_PLL1 (0x1 << 13)
846#define RT5668_SCLK_SRC_PLL2 (0x2 << 13)
847#define RT5668_SCLK_SRC_SDW (0x3 << 13)
848#define RT5668_SCLK_SRC_RCCLK (0x4 << 13)
849#define RT5668_PLL1_SRC_MASK (0x3 << 10)
850#define RT5668_PLL1_SRC_SFT 10
851#define RT5668_PLL1_SRC_MCLK (0x0 << 10)
852#define RT5668_PLL1_SRC_BCLK1 (0x1 << 10)
853#define RT5668_PLL1_SRC_SDW (0x2 << 10)
854#define RT5668_PLL1_SRC_RC (0x3 << 10)
855#define RT5668_PLL2_SRC_MASK (0x3 << 8)
856#define RT5668_PLL2_SRC_SFT 8
857#define RT5668_PLL2_SRC_MCLK (0x0 << 8)
858#define RT5668_PLL2_SRC_BCLK1 (0x1 << 8)
859#define RT5668_PLL2_SRC_SDW (0x2 << 8)
860#define RT5668_PLL2_SRC_RC (0x3 << 8)
861
862
863
864#define RT5668_PLL_INP_MAX 40000000
865#define RT5668_PLL_INP_MIN 256000
866/* PLL M/N/K Code Control 1 (0x0081) */
867#define RT5668_PLL_N_MAX 0x001ff
868#define RT5668_PLL_N_MASK (RT5668_PLL_N_MAX << 7)
869#define RT5668_PLL_N_SFT 7
870#define RT5668_PLL_K_MAX 0x001f
871#define RT5668_PLL_K_MASK (RT5668_PLL_K_MAX)
872#define RT5668_PLL_K_SFT 0
873
874/* PLL M/N/K Code Control 2 (0x0082) */
875#define RT5668_PLL_M_MAX 0x00f
876#define RT5668_PLL_M_MASK (RT5668_PLL_M_MAX << 12)
877#define RT5668_PLL_M_SFT 12
878#define RT5668_PLL_M_BP (0x1 << 11)
879#define RT5668_PLL_M_BP_SFT 11
880#define RT5668_PLL_K_BP (0x1 << 10)
881#define RT5668_PLL_K_BP_SFT 10
882
883/* PLL tracking mode 1 (0x0083) */
884#define RT5668_DA_ASRC_MASK (0x1 << 13)
885#define RT5668_DA_ASRC_SFT 13
886#define RT5668_DAC_STO1_ASRC_MASK (0x1 << 12)
887#define RT5668_DAC_STO1_ASRC_SFT 12
888#define RT5668_AD_ASRC_MASK (0x1 << 8)
889#define RT5668_AD_ASRC_SFT 8
890#define RT5668_AD_ASRC_SEL_MASK (0x1 << 4)
891#define RT5668_AD_ASRC_SEL_SFT 4
892#define RT5668_DMIC_ASRC_MASK (0x1 << 3)
893#define RT5668_DMIC_ASRC_SFT 3
894#define RT5668_ADC_STO1_ASRC_MASK (0x1 << 2)
895#define RT5668_ADC_STO1_ASRC_SFT 2
896#define RT5668_DA_ASRC_SEL_MASK (0x1 << 0)
897#define RT5668_DA_ASRC_SEL_SFT 0
898
899/* PLL tracking mode 2 3 (0x0084)(0x0085)*/
900#define RT5668_FILTER_CLK_SEL_MASK (0x7 << 12)
901#define RT5668_FILTER_CLK_SEL_SFT 12
902
903/* ASRC Control 4 (0x0086) */
904#define RT5668_ASRCIN_FTK_N1_MASK (0x3 << 14)
905#define RT5668_ASRCIN_FTK_N1_SFT 14
906#define RT5668_ASRCIN_FTK_N2_MASK (0x3 << 12)
907#define RT5668_ASRCIN_FTK_N2_SFT 12
908#define RT5668_ASRCIN_FTK_M1_MASK (0x7 << 8)
909#define RT5668_ASRCIN_FTK_M1_SFT 8
910#define RT5668_ASRCIN_FTK_M2_MASK (0x7 << 4)
911#define RT5668_ASRCIN_FTK_M2_SFT 4
912
913/* SoundWire reference clk (0x008d) */
914#define RT5668_PLL2_OUT_MASK (0x1 << 8)
915#define RT5668_PLL2_OUT_98M (0x0 << 8)
916#define RT5668_PLL2_OUT_49M (0x1 << 8)
917#define RT5668_SDW_REF_2_MASK (0xf << 4)
918#define RT5668_SDW_REF_2_SFT 4
919#define RT5668_SDW_REF_2_48K (0x0 << 4)
920#define RT5668_SDW_REF_2_96K (0x1 << 4)
921#define RT5668_SDW_REF_2_192K (0x2 << 4)
922#define RT5668_SDW_REF_2_32K (0x3 << 4)
923#define RT5668_SDW_REF_2_24K (0x4 << 4)
924#define RT5668_SDW_REF_2_16K (0x5 << 4)
925#define RT5668_SDW_REF_2_12K (0x6 << 4)
926#define RT5668_SDW_REF_2_8K (0x7 << 4)
927#define RT5668_SDW_REF_2_44K (0x8 << 4)
928#define RT5668_SDW_REF_2_88K (0x9 << 4)
929#define RT5668_SDW_REF_2_176K (0xa << 4)
930#define RT5668_SDW_REF_2_353K (0xb << 4)
931#define RT5668_SDW_REF_2_22K (0xc << 4)
932#define RT5668_SDW_REF_2_384K (0xd << 4)
933#define RT5668_SDW_REF_2_11K (0xe << 4)
934#define RT5668_SDW_REF_1_MASK (0xf << 0)
935#define RT5668_SDW_REF_1_SFT 0
936#define RT5668_SDW_REF_1_48K (0x0 << 0)
937#define RT5668_SDW_REF_1_96K (0x1 << 0)
938#define RT5668_SDW_REF_1_192K (0x2 << 0)
939#define RT5668_SDW_REF_1_32K (0x3 << 0)
940#define RT5668_SDW_REF_1_24K (0x4 << 0)
941#define RT5668_SDW_REF_1_16K (0x5 << 0)
942#define RT5668_SDW_REF_1_12K (0x6 << 0)
943#define RT5668_SDW_REF_1_8K (0x7 << 0)
944#define RT5668_SDW_REF_1_44K (0x8 << 0)
945#define RT5668_SDW_REF_1_88K (0x9 << 0)
946#define RT5668_SDW_REF_1_176K (0xa << 0)
947#define RT5668_SDW_REF_1_353K (0xb << 0)
948#define RT5668_SDW_REF_1_22K (0xc << 0)
949#define RT5668_SDW_REF_1_384K (0xd << 0)
950#define RT5668_SDW_REF_1_11K (0xe << 0)
951
952/* Depop Mode Control 1 (0x008e) */
953#define RT5668_PUMP_EN (0x1 << 3)
954#define RT5668_PUMP_EN_SFT 3
955#define RT5668_CAPLESS_EN (0x1 << 0)
956#define RT5668_CAPLESS_EN_SFT 0
957
958/* Depop Mode Control 2 (0x8f) */
959#define RT5668_RAMP_MASK (0x1 << 12)
960#define RT5668_RAMP_SFT 12
961#define RT5668_RAMP_DIS (0x0 << 12)
962#define RT5668_RAMP_EN (0x1 << 12)
963#define RT5668_BPS_MASK (0x1 << 11)
964#define RT5668_BPS_SFT 11
965#define RT5668_BPS_DIS (0x0 << 11)
966#define RT5668_BPS_EN (0x1 << 11)
967#define RT5668_FAST_UPDN_MASK (0x1 << 10)
968#define RT5668_FAST_UPDN_SFT 10
969#define RT5668_FAST_UPDN_DIS (0x0 << 10)
970#define RT5668_FAST_UPDN_EN (0x1 << 10)
971#define RT5668_VLO_MASK (0x1 << 7)
972#define RT5668_VLO_SFT 7
973#define RT5668_VLO_3V (0x0 << 7)
974#define RT5668_VLO_33V (0x1 << 7)
975
976/* HPOUT charge pump 1 (0x0091) */
977#define RT5668_OSW_L_MASK (0x1 << 11)
978#define RT5668_OSW_L_SFT 11
979#define RT5668_OSW_L_DIS (0x0 << 11)
980#define RT5668_OSW_L_EN (0x1 << 11)
981#define RT5668_OSW_R_MASK (0x1 << 10)
982#define RT5668_OSW_R_SFT 10
983#define RT5668_OSW_R_DIS (0x0 << 10)
984#define RT5668_OSW_R_EN (0x1 << 10)
985#define RT5668_PM_HP_MASK (0x3 << 8)
986#define RT5668_PM_HP_SFT 8
987#define RT5668_PM_HP_LV (0x0 << 8)
988#define RT5668_PM_HP_MV (0x1 << 8)
989#define RT5668_PM_HP_HV (0x2 << 8)
990#define RT5668_IB_HP_MASK (0x3 << 6)
991#define RT5668_IB_HP_SFT 6
992#define RT5668_IB_HP_125IL (0x0 << 6)
993#define RT5668_IB_HP_25IL (0x1 << 6)
994#define RT5668_IB_HP_5IL (0x2 << 6)
995#define RT5668_IB_HP_1IL (0x3 << 6)
996
997/* Micbias Control1 (0x93) */
998#define RT5668_MIC1_OV_MASK (0x3 << 14)
999#define RT5668_MIC1_OV_SFT 14
1000#define RT5668_MIC1_OV_2V7 (0x0 << 14)
1001#define RT5668_MIC1_OV_2V4 (0x1 << 14)
1002#define RT5668_MIC1_OV_2V25 (0x3 << 14)
1003#define RT5668_MIC1_OV_1V8 (0x4 << 14)
1004#define RT5668_MIC1_CLK_MASK (0x1 << 13)
1005#define RT5668_MIC1_CLK_SFT 13
1006#define RT5668_MIC1_CLK_DIS (0x0 << 13)
1007#define RT5668_MIC1_CLK_EN (0x1 << 13)
1008#define RT5668_MIC1_OVCD_MASK (0x1 << 12)
1009#define RT5668_MIC1_OVCD_SFT 12
1010#define RT5668_MIC1_OVCD_DIS (0x0 << 12)
1011#define RT5668_MIC1_OVCD_EN (0x1 << 12)
1012#define RT5668_MIC1_OVTH_MASK (0x3 << 10)
1013#define RT5668_MIC1_OVTH_SFT 10
1014#define RT5668_MIC1_OVTH_768UA (0x0 << 10)
1015#define RT5668_MIC1_OVTH_960UA (0x1 << 10)
1016#define RT5668_MIC1_OVTH_1152UA (0x2 << 10)
1017#define RT5668_MIC1_OVTH_1960UA (0x3 << 10)
1018#define RT5668_MIC2_OV_MASK (0x3 << 8)
1019#define RT5668_MIC2_OV_SFT 8
1020#define RT5668_MIC2_OV_2V7 (0x0 << 8)
1021#define RT5668_MIC2_OV_2V4 (0x1 << 8)
1022#define RT5668_MIC2_OV_2V25 (0x3 << 8)
1023#define RT5668_MIC2_OV_1V8 (0x4 << 8)
1024#define RT5668_MIC2_CLK_MASK (0x1 << 7)
1025#define RT5668_MIC2_CLK_SFT 7
1026#define RT5668_MIC2_CLK_DIS (0x0 << 7)
1027#define RT5668_MIC2_CLK_EN (0x1 << 7)
1028#define RT5668_MIC2_OVTH_MASK (0x3 << 4)
1029#define RT5668_MIC2_OVTH_SFT 4
1030#define RT5668_MIC2_OVTH_768UA (0x0 << 4)
1031#define RT5668_MIC2_OVTH_960UA (0x1 << 4)
1032#define RT5668_MIC2_OVTH_1152UA (0x2 << 4)
1033#define RT5668_MIC2_OVTH_1960UA (0x3 << 4)
1034#define RT5668_PWR_MB_MASK (0x1 << 3)
1035#define RT5668_PWR_MB_SFT 3
1036#define RT5668_PWR_MB_PD (0x0 << 3)
1037#define RT5668_PWR_MB_PU (0x1 << 3)
1038
1039/* Micbias Control2 (0x0094) */
1040#define RT5668_PWR_CLK25M_MASK (0x1 << 9)
1041#define RT5668_PWR_CLK25M_SFT 9
1042#define RT5668_PWR_CLK25M_PD (0x0 << 9)
1043#define RT5668_PWR_CLK25M_PU (0x1 << 9)
1044#define RT5668_PWR_CLK1M_MASK (0x1 << 8)
1045#define RT5668_PWR_CLK1M_SFT 8
1046#define RT5668_PWR_CLK1M_PD (0x0 << 8)
1047#define RT5668_PWR_CLK1M_PU (0x1 << 8)
1048
1049/* RC Clock Control (0x009f) */
1050#define RT5668_POW_IRQ (0x1 << 15)
1051#define RT5668_POW_JDH (0x1 << 14)
1052#define RT5668_POW_JDL (0x1 << 13)
1053#define RT5668_POW_ANA (0x1 << 12)
1054
1055/* I2S Master Mode Clock Control 1 (0x00a0) */
1056#define RT5668_CLK_SRC_MCLK (0x0)
1057#define RT5668_CLK_SRC_PLL1 (0x1)
1058#define RT5668_CLK_SRC_PLL2 (0x2)
1059#define RT5668_CLK_SRC_SDW (0x3)
1060#define RT5668_CLK_SRC_RCCLK (0x4)
1061#define RT5668_I2S_PD_1 (0x0)
1062#define RT5668_I2S_PD_2 (0x1)
1063#define RT5668_I2S_PD_3 (0x2)
1064#define RT5668_I2S_PD_4 (0x3)
1065#define RT5668_I2S_PD_6 (0x4)
1066#define RT5668_I2S_PD_8 (0x5)
1067#define RT5668_I2S_PD_12 (0x6)
1068#define RT5668_I2S_PD_16 (0x7)
1069#define RT5668_I2S_PD_24 (0x8)
1070#define RT5668_I2S_PD_32 (0x9)
1071#define RT5668_I2S_PD_48 (0xa)
1072#define RT5668_I2S2_SRC_MASK (0x3 << 4)
1073#define RT5668_I2S2_SRC_SFT 4
1074#define RT5668_I2S2_M_PD_MASK (0xf << 0)
1075#define RT5668_I2S2_M_PD_SFT 0
1076
1077/* IRQ Control 1 (0x00b6) */
1078#define RT5668_JD1_PULSE_EN_MASK (0x1 << 10)
1079#define RT5668_JD1_PULSE_EN_SFT 10
1080#define RT5668_JD1_PULSE_DIS (0x0 << 10)
1081#define RT5668_JD1_PULSE_EN (0x1 << 10)
1082
1083/* IRQ Control 2 (0x00b7) */
1084#define RT5668_JD1_EN_MASK (0x1 << 15)
1085#define RT5668_JD1_EN_SFT 15
1086#define RT5668_JD1_DIS (0x0 << 15)
1087#define RT5668_JD1_EN (0x1 << 15)
1088#define RT5668_JD1_POL_MASK (0x1 << 13)
1089#define RT5668_JD1_POL_NOR (0x0 << 13)
1090#define RT5668_JD1_POL_INV (0x1 << 13)
1091
1092/* IRQ Control 3 (0x00b8) */
1093#define RT5668_IL_IRQ_MASK (0x1 << 7)
1094#define RT5668_IL_IRQ_DIS (0x0 << 7)
1095#define RT5668_IL_IRQ_EN (0x1 << 7)
1096
1097/* GPIO Control 1 (0x00c0) */
1098#define RT5668_GP1_PIN_MASK (0x3 << 14)
1099#define RT5668_GP1_PIN_SFT 14
1100#define RT5668_GP1_PIN_GPIO1 (0x0 << 14)
1101#define RT5668_GP1_PIN_IRQ (0x1 << 14)
1102#define RT5668_GP1_PIN_DMIC_CLK (0x2 << 14)
1103#define RT5668_GP2_PIN_MASK (0x3 << 12)
1104#define RT5668_GP2_PIN_SFT 12
1105#define RT5668_GP2_PIN_GPIO2 (0x0 << 12)
1106#define RT5668_GP2_PIN_LRCK2 (0x1 << 12)
1107#define RT5668_GP2_PIN_DMIC_SDA (0x2 << 12)
1108#define RT5668_GP3_PIN_MASK (0x3 << 10)
1109#define RT5668_GP3_PIN_SFT 10
1110#define RT5668_GP3_PIN_GPIO3 (0x0 << 10)
1111#define RT5668_GP3_PIN_BCLK2 (0x1 << 10)
1112#define RT5668_GP3_PIN_DMIC_CLK (0x2 << 10)
1113#define RT5668_GP4_PIN_MASK (0x3 << 8)
1114#define RT5668_GP4_PIN_SFT 8
1115#define RT5668_GP4_PIN_GPIO4 (0x0 << 8)
1116#define RT5668_GP4_PIN_ADCDAT1 (0x1 << 8)
1117#define RT5668_GP4_PIN_DMIC_CLK (0x2 << 8)
1118#define RT5668_GP4_PIN_ADCDAT2 (0x3 << 8)
1119#define RT5668_GP5_PIN_MASK (0x3 << 6)
1120#define RT5668_GP5_PIN_SFT 6
1121#define RT5668_GP5_PIN_GPIO5 (0x0 << 6)
1122#define RT5668_GP5_PIN_DACDAT1 (0x1 << 6)
1123#define RT5668_GP5_PIN_DMIC_SDA (0x2 << 6)
1124#define RT5668_GP6_PIN_MASK (0x1 << 5)
1125#define RT5668_GP6_PIN_SFT 5
1126#define RT5668_GP6_PIN_GPIO6 (0x0 << 5)
1127#define RT5668_GP6_PIN_LRCK1 (0x1 << 5)
1128
1129/* GPIO Control 2 (0x00c1)*/
1130#define RT5668_GP1_PF_MASK (0x1 << 15)
1131#define RT5668_GP1_PF_IN (0x0 << 15)
1132#define RT5668_GP1_PF_OUT (0x1 << 15)
1133#define RT5668_GP1_OUT_MASK (0x1 << 14)
1134#define RT5668_GP1_OUT_L (0x0 << 14)
1135#define RT5668_GP1_OUT_H (0x1 << 14)
1136#define RT5668_GP2_PF_MASK (0x1 << 13)
1137#define RT5668_GP2_PF_IN (0x0 << 13)
1138#define RT5668_GP2_PF_OUT (0x1 << 13)
1139#define RT5668_GP2_OUT_MASK (0x1 << 12)
1140#define RT5668_GP2_OUT_L (0x0 << 12)
1141#define RT5668_GP2_OUT_H (0x1 << 12)
1142#define RT5668_GP3_PF_MASK (0x1 << 11)
1143#define RT5668_GP3_PF_IN (0x0 << 11)
1144#define RT5668_GP3_PF_OUT (0x1 << 11)
1145#define RT5668_GP3_OUT_MASK (0x1 << 10)
1146#define RT5668_GP3_OUT_L (0x0 << 10)
1147#define RT5668_GP3_OUT_H (0x1 << 10)
1148#define RT5668_GP4_PF_MASK (0x1 << 9)
1149#define RT5668_GP4_PF_IN (0x0 << 9)
1150#define RT5668_GP4_PF_OUT (0x1 << 9)
1151#define RT5668_GP4_OUT_MASK (0x1 << 8)
1152#define RT5668_GP4_OUT_L (0x0 << 8)
1153#define RT5668_GP4_OUT_H (0x1 << 8)
1154#define RT5668_GP5_PF_MASK (0x1 << 7)
1155#define RT5668_GP5_PF_IN (0x0 << 7)
1156#define RT5668_GP5_PF_OUT (0x1 << 7)
1157#define RT5668_GP5_OUT_MASK (0x1 << 6)
1158#define RT5668_GP5_OUT_L (0x0 << 6)
1159#define RT5668_GP5_OUT_H (0x1 << 6)
1160#define RT5668_GP6_PF_MASK (0x1 << 5)
1161#define RT5668_GP6_PF_IN (0x0 << 5)
1162#define RT5668_GP6_PF_OUT (0x1 << 5)
1163#define RT5668_GP6_OUT_MASK (0x1 << 4)
1164#define RT5668_GP6_OUT_L (0x0 << 4)
1165#define RT5668_GP6_OUT_H (0x1 << 4)
1166
1167
1168/* GPIO Status (0x00c2) */
1169#define RT5668_GP6_STA (0x1 << 6)
1170#define RT5668_GP5_STA (0x1 << 5)
1171#define RT5668_GP4_STA (0x1 << 4)
1172#define RT5668_GP3_STA (0x1 << 3)
1173#define RT5668_GP2_STA (0x1 << 2)
1174#define RT5668_GP1_STA (0x1 << 1)
1175
1176/* Soft volume and zero cross control 1 (0x00d9) */
1177#define RT5668_SV_MASK (0x1 << 15)
1178#define RT5668_SV_SFT 15
1179#define RT5668_SV_DIS (0x0 << 15)
1180#define RT5668_SV_EN (0x1 << 15)
1181#define RT5668_ZCD_MASK (0x1 << 10)
1182#define RT5668_ZCD_SFT 10
1183#define RT5668_ZCD_PD (0x0 << 10)
1184#define RT5668_ZCD_PU (0x1 << 10)
1185#define RT5668_SV_DLY_MASK (0xf)
1186#define RT5668_SV_DLY_SFT 0
1187
1188/* Soft volume and zero cross control 2 (0x00da) */
1189#define RT5668_ZCD_BST1_CBJ_MASK (0x1 << 7)
1190#define RT5668_ZCD_BST1_CBJ_SFT 7
1191#define RT5668_ZCD_BST1_CBJ_DIS (0x0 << 7)
1192#define RT5668_ZCD_BST1_CBJ_EN (0x1 << 7)
1193#define RT5668_ZCD_RECMIX_MASK (0x1)
1194#define RT5668_ZCD_RECMIX_SFT 0
1195#define RT5668_ZCD_RECMIX_DIS (0x0)
1196#define RT5668_ZCD_RECMIX_EN (0x1)
1197
1198/* 4 Button Inline Command Control 2 (0x00e3) */
1199#define RT5668_4BTN_IL_MASK (0x1 << 15)
1200#define RT5668_4BTN_IL_EN (0x1 << 15)
1201#define RT5668_4BTN_IL_DIS (0x0 << 15)
1202#define RT5668_4BTN_IL_RST_MASK (0x1 << 14)
1203#define RT5668_4BTN_IL_NOR (0x1 << 14)
1204#define RT5668_4BTN_IL_RST (0x0 << 14)
1205
1206/* Analog JD Control (0x00f0) */
1207#define RT5668_JDH_RS_MASK (0x1 << 4)
1208#define RT5668_JDH_NO_PLUG (0x1 << 4)
1209#define RT5668_JDH_PLUG (0x0 << 4)
1210
1211/* Chopper and Clock control for DAC (0x013a)*/
1212#define RT5668_CKXEN_DAC1_MASK (0x1 << 13)
1213#define RT5668_CKXEN_DAC1_SFT 13
1214#define RT5668_CKGEN_DAC1_MASK (0x1 << 12)
1215#define RT5668_CKGEN_DAC1_SFT 12
1216
1217/* Chopper and Clock control for ADC (0x013b)*/
1218#define RT5668_CKXEN_ADC1_MASK (0x1 << 13)
1219#define RT5668_CKXEN_ADC1_SFT 13
1220#define RT5668_CKGEN_ADC1_MASK (0x1 << 12)
1221#define RT5668_CKGEN_ADC1_SFT 12
1222
1223/* Volume test (0x013f)*/
1224#define RT5668_SEL_CLK_VOL_MASK (0x1 << 15)
1225#define RT5668_SEL_CLK_VOL_EN (0x1 << 15)
1226#define RT5668_SEL_CLK_VOL_DIS (0x0 << 15)
1227
1228/* Test Mode Control 1 (0x0145) */
1229#define RT5668_AD2DA_LB_MASK (0x1 << 10)
1230#define RT5668_AD2DA_LB_SFT 10
1231
1232/* Stereo Noise Gate Control 1 (0x0160) */
1233#define RT5668_NG2_EN_MASK (0x1 << 15)
1234#define RT5668_NG2_EN (0x1 << 15)
1235#define RT5668_NG2_DIS (0x0 << 15)
1236
1237/* Stereo1 DAC Silence Detection Control (0x0190) */
1238#define RT5668_DEB_STO_DAC_MASK (0x7 << 4)
1239#define RT5668_DEB_80_MS (0x0 << 4)
1240
1241/* SAR ADC Inline Command Control 1 (0x0210) */
1242#define RT5668_SAR_BUTT_DET_MASK (0x1 << 15)
1243#define RT5668_SAR_BUTT_DET_EN (0x1 << 15)
1244#define RT5668_SAR_BUTT_DET_DIS (0x0 << 15)
1245#define RT5668_SAR_BUTDET_MODE_MASK (0x1 << 14)
1246#define RT5668_SAR_BUTDET_POW_SAV (0x1 << 14)
1247#define RT5668_SAR_BUTDET_POW_NORM (0x0 << 14)
1248#define RT5668_SAR_BUTDET_RST_MASK (0x1 << 13)
1249#define RT5668_SAR_BUTDET_RST_NORMAL (0x1 << 13)
1250#define RT5668_SAR_BUTDET_RST (0x0 << 13)
1251#define RT5668_SAR_POW_MASK (0x1 << 12)
1252#define RT5668_SAR_POW_EN (0x1 << 12)
1253#define RT5668_SAR_POW_DIS (0x0 << 12)
1254#define RT5668_SAR_RST_MASK (0x1 << 11)
1255#define RT5668_SAR_RST_NORMAL (0x1 << 11)
1256#define RT5668_SAR_RST (0x0 << 11)
1257#define RT5668_SAR_BYPASS_MASK (0x1 << 10)
1258#define RT5668_SAR_BYPASS_EN (0x1 << 10)
1259#define RT5668_SAR_BYPASS_DIS (0x0 << 10)
1260#define RT5668_SAR_SEL_MB1_MASK (0x1 << 9)
1261#define RT5668_SAR_SEL_MB1_SEL (0x1 << 9)
1262#define RT5668_SAR_SEL_MB1_NOSEL (0x0 << 9)
1263#define RT5668_SAR_SEL_MB2_MASK (0x1 << 8)
1264#define RT5668_SAR_SEL_MB2_SEL (0x1 << 8)
1265#define RT5668_SAR_SEL_MB2_NOSEL (0x0 << 8)
1266#define RT5668_SAR_SEL_MODE_MASK (0x1 << 7)
1267#define RT5668_SAR_SEL_MODE_CMP (0x1 << 7)
1268#define RT5668_SAR_SEL_MODE_ADC (0x0 << 7)
1269#define RT5668_SAR_SEL_MB1_MB2_MASK (0x1 << 5)
1270#define RT5668_SAR_SEL_MB1_MB2_AUTO (0x1 << 5)
1271#define RT5668_SAR_SEL_MB1_MB2_MANU (0x0 << 5)
1272#define RT5668_SAR_SEL_SIGNAL_MASK (0x1 << 4)
1273#define RT5668_SAR_SEL_SIGNAL_AUTO (0x1 << 4)
1274#define RT5668_SAR_SEL_SIGNAL_MANU (0x0 << 4)
1275
1276/* SAR ADC Inline Command Control 13 (0x021c) */
1277#define RT5668_SAR_SOUR_MASK (0x3f)
1278#define RT5668_SAR_SOUR_BTN (0x3f)
1279#define RT5668_SAR_SOUR_TYPE (0x0)
1280
1281
1282/* System Clock Source */
1283enum {
1284 RT5668_SCLK_S_MCLK,
1285 RT5668_SCLK_S_PLL1,
1286 RT5668_SCLK_S_PLL2,
1287 RT5668_SCLK_S_RCCLK,
1288};
1289
1290/* PLL Source */
1291enum {
1292 RT5668_PLL1_S_MCLK,
1293 RT5668_PLL1_S_BCLK1,
1294 RT5668_PLL1_S_RCCLK,
1295};
1296
1297enum {
1298 RT5668_AIF1,
1299 RT5668_AIF2,
1300 RT5668_AIFS
1301};
1302
1303/* filter mask */
1304enum {
1305 RT5668_DA_STEREO1_FILTER = 0x1,
1306 RT5668_AD_STEREO1_FILTER = (0x1 << 1),
1307};
1308
1309enum {
1310 RT5668_CLK_SEL_SYS,
1311 RT5668_CLK_SEL_I2S1_ASRC,
1312 RT5668_CLK_SEL_I2S2_ASRC,
1313};
1314
1315int rt5668_sel_asrc_clk_src(struct snd_soc_component *component,
1316 unsigned int filter_mask, unsigned int clk_src);
1317
1318#endif /* __RT5668_H__ */
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index dc7df337d5f8..732ef928b25d 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -71,7 +71,7 @@ static const struct regmap_range_cfg rt5670_ranges[] = {
71 71
72static const struct reg_sequence init_list[] = { 72static const struct reg_sequence init_list[] = {
73 { RT5670_PR_BASE + 0x14, 0x9a8a }, 73 { RT5670_PR_BASE + 0x14, 0x9a8a },
74 { RT5670_PR_BASE + 0x38, 0x3ba1 }, 74 { RT5670_PR_BASE + 0x38, 0x1fe1 },
75 { RT5670_PR_BASE + 0x3d, 0x3640 }, 75 { RT5670_PR_BASE + 0x3d, 0x3640 },
76 { 0x8a, 0x0123 }, 76 { 0x8a, 0x0123 },
77}; 77};
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index bc1a23dd7c2d..8a0181a2db08 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -5006,13 +5006,6 @@ static const struct regmap_config rt5677_regmap = {
5006 .num_ranges = ARRAY_SIZE(rt5677_ranges), 5006 .num_ranges = ARRAY_SIZE(rt5677_ranges),
5007}; 5007};
5008 5008
5009static const struct i2c_device_id rt5677_i2c_id[] = {
5010 { "rt5677", RT5677 },
5011 { "rt5676", RT5676 },
5012 { }
5013};
5014MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
5015
5016static const struct of_device_id rt5677_of_match[] = { 5009static const struct of_device_id rt5677_of_match[] = {
5017 { .compatible = "realtek,rt5677", RT5677 }, 5010 { .compatible = "realtek,rt5677", RT5677 },
5018 { } 5011 { }
@@ -5130,8 +5123,7 @@ static void rt5677_free_irq(struct i2c_client *i2c)
5130 regmap_del_irq_chip(i2c->irq, rt5677->irq_data); 5123 regmap_del_irq_chip(i2c->irq, rt5677->irq_data);
5131} 5124}
5132 5125
5133static int rt5677_i2c_probe(struct i2c_client *i2c, 5126static int rt5677_i2c_probe(struct i2c_client *i2c)
5134 const struct i2c_device_id *id)
5135{ 5127{
5136 struct rt5677_priv *rt5677; 5128 struct rt5677_priv *rt5677;
5137 int ret; 5129 int ret;
@@ -5278,9 +5270,8 @@ static struct i2c_driver rt5677_i2c_driver = {
5278 .of_match_table = rt5677_of_match, 5270 .of_match_table = rt5677_of_match,
5279 .acpi_match_table = ACPI_PTR(rt5677_acpi_match), 5271 .acpi_match_table = ACPI_PTR(rt5677_acpi_match),
5280 }, 5272 },
5281 .probe = rt5677_i2c_probe, 5273 .probe_new = rt5677_i2c_probe,
5282 .remove = rt5677_i2c_remove, 5274 .remove = rt5677_i2c_remove,
5283 .id_table = rt5677_i2c_id,
5284}; 5275};
5285module_i2c_driver(rt5677_i2c_driver); 5276module_i2c_driver(rt5677_i2c_driver);
5286 5277
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7c1d65830c05..60764f6201b1 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1,12 +1,8 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver 2//
3 * 3// sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved. 4//
5 * 5// Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10 6
11#include <linux/module.h> 7#include <linux/module.h>
12#include <linux/moduleparam.h> 8#include <linux/moduleparam.h>
@@ -457,7 +453,7 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol,
457 * avc_put_threshold function: register_value = 10^(dB/20) * 0.636 * 2^15 ==> 453 * avc_put_threshold function: register_value = 10^(dB/20) * 0.636 * 2^15 ==>
458 * dB = ( fls(register_value) - 14.347 ) * 6.02 454 * dB = ( fls(register_value) - 14.347 ) * 6.02
459 * 455 *
460 * As this calculation is expensive and the threshold dB values may not exeed 456 * As this calculation is expensive and the threshold dB values may not exceed
461 * 0 to 96 we use pre-calculated values. 457 * 0 to 96 we use pre-calculated values.
462 */ 458 */
463static int avc_get_threshold(struct snd_kcontrol *kcontrol, 459static int avc_get_threshold(struct snd_kcontrol *kcontrol,
@@ -490,7 +486,7 @@ static int avc_get_threshold(struct snd_kcontrol *kcontrol,
490 * 486 *
491 * The register value is calculated by following formula: 487 * The register value is calculated by following formula:
492 * register_value = 10^(dB/20) * 0.636 * 2^15 488 * register_value = 10^(dB/20) * 0.636 * 2^15
493 * As this calculation is expensive and the threshold dB values may not exeed 489 * As this calculation is expensive and the threshold dB values may not exceed
494 * 0 to 96 we use pre-calculated values. 490 * 0 to 96 we use pre-calculated values.
495 */ 491 */
496static int avc_put_threshold(struct snd_kcontrol *kcontrol, 492static int avc_put_threshold(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
index 28cf637155bb..18cae08bbd3a 100644
--- a/sound/soc/codecs/sgtl5000.h
+++ b/sound/soc/codecs/sgtl5000.h
@@ -1,11 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * sgtl5000.h - SGTL5000 audio codec interface 3 * sgtl5000.h - SGTL5000 audio codec interface
3 * 4 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. 5 * Copyright 2010-2011 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */ 6 */
10 7
11#ifndef _SGTL5000_H 8#ifndef _SGTL5000_H
diff --git a/sound/soc/codecs/ssm2305.c b/sound/soc/codecs/ssm2305.c
new file mode 100644
index 000000000000..2968959c4b75
--- /dev/null
+++ b/sound/soc/codecs/ssm2305.c
@@ -0,0 +1,104 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Analog Devices SSM2305 Amplifier Driver
4//
5// Copyright (C) 2018 Pengutronix, Marco Felsch <kernel@pengutronix.de>
6//
7
8#include <linux/gpio/consumer.h>
9#include <linux/module.h>
10#include <sound/soc.h>
11
12#define DRV_NAME "ssm2305"
13
14struct ssm2305 {
15 /* shutdown gpio */
16 struct gpio_desc *gpiod_shutdown;
17};
18
19static int ssm2305_power_event(struct snd_soc_dapm_widget *w,
20 struct snd_kcontrol *kctrl, int event)
21{
22 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
23 struct ssm2305 *data = snd_soc_component_get_drvdata(c);
24
25 gpiod_set_value_cansleep(data->gpiod_shutdown,
26 SND_SOC_DAPM_EVENT_ON(event));
27
28 return 0;
29}
30
31static const struct snd_soc_dapm_widget ssm2305_dapm_widgets[] = {
32 /* Stereo input/output */
33 SND_SOC_DAPM_INPUT("L_IN"),
34 SND_SOC_DAPM_INPUT("R_IN"),
35 SND_SOC_DAPM_OUTPUT("L_OUT"),
36 SND_SOC_DAPM_OUTPUT("R_OUT"),
37
38 SND_SOC_DAPM_SUPPLY("Power", SND_SOC_NOPM, 0, 0, ssm2305_power_event,
39 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
40};
41
42static const struct snd_soc_dapm_route ssm2305_dapm_routes[] = {
43 { "L_OUT", NULL, "L_IN" },
44 { "R_OUT", NULL, "R_IN" },
45 { "L_IN", NULL, "Power" },
46 { "R_IN", NULL, "Power" },
47};
48
49static const struct snd_soc_component_driver ssm2305_component_driver = {
50 .dapm_widgets = ssm2305_dapm_widgets,
51 .num_dapm_widgets = ARRAY_SIZE(ssm2305_dapm_widgets),
52 .dapm_routes = ssm2305_dapm_routes,
53 .num_dapm_routes = ARRAY_SIZE(ssm2305_dapm_routes),
54};
55
56static int ssm2305_probe(struct platform_device *pdev)
57{
58 struct device *dev = &pdev->dev;
59 struct ssm2305 *priv;
60 int err;
61
62 /* Allocate the private data */
63 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
64 if (!priv)
65 return -ENOMEM;
66
67 platform_set_drvdata(pdev, priv);
68
69 /* Get shutdown gpio */
70 priv->gpiod_shutdown = devm_gpiod_get(dev, "shutdown",
71 GPIOD_OUT_LOW);
72 if (IS_ERR(priv->gpiod_shutdown)) {
73 err = PTR_ERR(priv->gpiod_shutdown);
74 if (err != -EPROBE_DEFER)
75 dev_err(dev, "Failed to get 'shutdown' gpio: %d\n",
76 err);
77 return err;
78 }
79
80 return devm_snd_soc_register_component(dev, &ssm2305_component_driver,
81 NULL, 0);
82}
83
84#ifdef CONFIG_OF
85static const struct of_device_id ssm2305_of_match[] = {
86 { .compatible = "adi,ssm2305", },
87 { }
88};
89MODULE_DEVICE_TABLE(of, ssm2305_of_match);
90#endif
91
92static struct platform_driver ssm2305_driver = {
93 .driver = {
94 .name = DRV_NAME,
95 .of_match_table = of_match_ptr(ssm2305_of_match),
96 },
97 .probe = ssm2305_probe,
98};
99
100module_platform_driver(ssm2305_driver);
101
102MODULE_DESCRIPTION("ASoC SSM2305 amplifier driver");
103MODULE_AUTHOR("Marco Felsch <m.felsch@pengutronix.de>");
104MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 4f3a16c520a2..14999b999fd3 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/gpio/consumer.h>
19 20
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -43,6 +44,8 @@ struct tas6424_data {
43 unsigned int last_fault1; 44 unsigned int last_fault1;
44 unsigned int last_fault2; 45 unsigned int last_fault2;
45 unsigned int last_warn; 46 unsigned int last_warn;
47 struct gpio_desc *standby_gpio;
48 struct gpio_desc *mute_gpio;
46}; 49};
47 50
48/* 51/*
@@ -61,6 +64,8 @@ static const struct snd_kcontrol_new tas6424_snd_controls[] = {
61 TAS6424_CH3_VOL_CTRL, 0, 0xff, 0, dac_tlv), 64 TAS6424_CH3_VOL_CTRL, 0, 0xff, 0, dac_tlv),
62 SOC_SINGLE_TLV("Speaker Driver CH4 Playback Volume", 65 SOC_SINGLE_TLV("Speaker Driver CH4 Playback Volume",
63 TAS6424_CH4_VOL_CTRL, 0, 0xff, 0, dac_tlv), 66 TAS6424_CH4_VOL_CTRL, 0, 0xff, 0, dac_tlv),
67 SOC_SINGLE_STROBE("Auto Diagnostics Switch", TAS6424_DC_DIAG_CTRL1,
68 TAS6424_LDGBYPASS_SHIFT, 1),
64}; 69};
65 70
66static int tas6424_dac_event(struct snd_soc_dapm_widget *w, 71static int tas6424_dac_event(struct snd_soc_dapm_widget *w,
@@ -249,10 +254,16 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
249static int tas6424_mute(struct snd_soc_dai *dai, int mute) 254static int tas6424_mute(struct snd_soc_dai *dai, int mute)
250{ 255{
251 struct snd_soc_component *component = dai->component; 256 struct snd_soc_component *component = dai->component;
257 struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
252 unsigned int val; 258 unsigned int val;
253 259
254 dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute); 260 dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute);
255 261
262 if (tas6424->mute_gpio) {
263 gpiod_set_value_cansleep(tas6424->mute_gpio, mute);
264 return 0;
265 }
266
256 if (mute) 267 if (mute)
257 val = TAS6424_ALL_STATE_MUTE; 268 val = TAS6424_ALL_STATE_MUTE;
258 else 269 else
@@ -287,6 +298,12 @@ static int tas6424_power_on(struct snd_soc_component *component)
287{ 298{
288 struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component); 299 struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
289 int ret; 300 int ret;
301 u8 chan_states;
302 int no_auto_diags = 0;
303 unsigned int reg_val;
304
305 if (!regmap_read(tas6424->regmap, TAS6424_DC_DIAG_CTRL1, &reg_val))
306 no_auto_diags = reg_val & TAS6424_LDGBYPASS_MASK;
290 307
291 ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies), 308 ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
292 tas6424->supplies); 309 tas6424->supplies);
@@ -303,12 +320,25 @@ static int tas6424_power_on(struct snd_soc_component *component)
303 return ret; 320 return ret;
304 } 321 }
305 322
306 snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE); 323 if (tas6424->mute_gpio) {
324 gpiod_set_value_cansleep(tas6424->mute_gpio, 0);
325 /*
326 * channels are muted via the mute pin. Don't also mute
327 * them via the registers so that subsequent register
328 * access is not necessary to un-mute the channels
329 */
330 chan_states = TAS6424_ALL_STATE_PLAY;
331 } else {
332 chan_states = TAS6424_ALL_STATE_MUTE;
333 }
334 snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, chan_states);
307 335
308 /* any time we come out of HIZ, the output channels automatically run DC 336 /* any time we come out of HIZ, the output channels automatically run DC
309 * load diagnostics, wait here until this completes 337 * load diagnostics if autodiagnotics are enabled. wait here until this
338 * completes.
310 */ 339 */
311 msleep(230); 340 if (!no_auto_diags)
341 msleep(230);
312 342
313 return 0; 343 return 0;
314} 344}
@@ -627,6 +657,38 @@ static int tas6424_i2c_probe(struct i2c_client *client,
627 return ret; 657 return ret;
628 } 658 }
629 659
660 /*
661 * Get control of the standby pin and set it LOW to take the codec
662 * out of the stand-by mode.
663 * Note: The actual pin polarity is taken care of in the GPIO lib
664 * according the polarity specified in the DTS.
665 */
666 tas6424->standby_gpio = devm_gpiod_get_optional(dev, "standby",
667 GPIOD_OUT_LOW);
668 if (IS_ERR(tas6424->standby_gpio)) {
669 if (PTR_ERR(tas6424->standby_gpio) == -EPROBE_DEFER)
670 return -EPROBE_DEFER;
671 dev_info(dev, "failed to get standby GPIO: %ld\n",
672 PTR_ERR(tas6424->standby_gpio));
673 tas6424->standby_gpio = NULL;
674 }
675
676 /*
677 * Get control of the mute pin and set it HIGH in order to start with
678 * all the output muted.
679 * Note: The actual pin polarity is taken care of in the GPIO lib
680 * according the polarity specified in the DTS.
681 */
682 tas6424->mute_gpio = devm_gpiod_get_optional(dev, "mute",
683 GPIOD_OUT_HIGH);
684 if (IS_ERR(tas6424->mute_gpio)) {
685 if (PTR_ERR(tas6424->mute_gpio) == -EPROBE_DEFER)
686 return -EPROBE_DEFER;
687 dev_info(dev, "failed to get nmute GPIO: %ld\n",
688 PTR_ERR(tas6424->mute_gpio));
689 tas6424->mute_gpio = NULL;
690 }
691
630 for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++) 692 for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++)
631 tas6424->supplies[i].supply = tas6424_supply_names[i]; 693 tas6424->supplies[i].supply = tas6424_supply_names[i];
632 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies), 694 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies),
@@ -671,6 +733,10 @@ static int tas6424_i2c_remove(struct i2c_client *client)
671 733
672 cancel_delayed_work_sync(&tas6424->fault_check_work); 734 cancel_delayed_work_sync(&tas6424->fault_check_work);
673 735
736 /* put the codec in stand-by */
737 if (tas6424->standby_gpio)
738 gpiod_set_value_cansleep(tas6424->standby_gpio, 1);
739
674 ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies), 740 ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
675 tas6424->supplies); 741 tas6424->supplies);
676 if (ret < 0) { 742 if (ret < 0) {
diff --git a/sound/soc/codecs/tas6424.h b/sound/soc/codecs/tas6424.h
index 430588328a06..b5958c45ed0e 100644
--- a/sound/soc/codecs/tas6424.h
+++ b/sound/soc/codecs/tas6424.h
@@ -111,6 +111,10 @@
111 TAS6424_CH3_STATE_DIAG | \ 111 TAS6424_CH3_STATE_DIAG | \
112 TAS6424_CH4_STATE_DIAG) 112 TAS6424_CH4_STATE_DIAG)
113 113
114/* TAS6424_DC_DIAG_CTRL1 */
115#define TAS6424_LDGBYPASS_SHIFT 0
116#define TAS6424_LDGBYPASS_MASK BIT(TAS6424_LDGBYPASS_SHIFT)
117
114/* TAS6424_GLOB_FAULT1_REG */ 118/* TAS6424_GLOB_FAULT1_REG */
115#define TAS6424_FAULT_CLOCK BIT(4) 119#define TAS6424_FAULT_CLOCK BIT(4)
116#define TAS6424_FAULT_PVDD_OV BIT(3) 120#define TAS6424_FAULT_PVDD_OV BIT(3)
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c
index 6d213c6d3920..abc114a3ae2b 100644
--- a/sound/soc/codecs/tfa9879.c
+++ b/sound/soc/codecs/tfa9879.c
@@ -1,15 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * tfa9879.c -- driver for NXP Semiconductors TFA9879 2//
3 * 3// tfa9879.c -- driver for NXP Semiconductors TFA9879
4 * Copyright (C) 2014 Axentia Technologies AB 4//
5 * Author: Peter Rosin <peda@axentia.se> 5// Copyright (C) 2014 Axentia Technologies AB
6 * 6// Author: Peter Rosin <peda@axentia.se>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13 7
14#include <linux/module.h> 8#include <linux/module.h>
15#include <linux/init.h> 9#include <linux/init.h>
@@ -88,13 +82,14 @@ static int tfa9879_hw_params(struct snd_pcm_substream *substream,
88 } 82 }
89 83
90 if (tfa9879->lsb_justified) 84 if (tfa9879->lsb_justified)
91 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1, 85 snd_soc_component_update_bits(component,
92 TFA9879_I2S_SET_MASK, 86 TFA9879_SERIAL_INTERFACE_1,
93 i2s_set << TFA9879_I2S_SET_SHIFT); 87 TFA9879_I2S_SET_MASK,
88 i2s_set << TFA9879_I2S_SET_SHIFT);
94 89
95 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1, 90 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
96 TFA9879_I2S_FS_MASK, 91 TFA9879_I2S_FS_MASK,
97 fs << TFA9879_I2S_FS_SHIFT); 92 fs << TFA9879_I2S_FS_SHIFT);
98 return 0; 93 return 0;
99} 94}
100 95
@@ -103,8 +98,8 @@ static int tfa9879_digital_mute(struct snd_soc_dai *dai, int mute)
103 struct snd_soc_component *component = dai->component; 98 struct snd_soc_component *component = dai->component;
104 99
105 snd_soc_component_update_bits(component, TFA9879_MISC_CONTROL, 100 snd_soc_component_update_bits(component, TFA9879_MISC_CONTROL,
106 TFA9879_S_MUTE_MASK, 101 TFA9879_S_MUTE_MASK,
107 !!mute << TFA9879_S_MUTE_SHIFT); 102 !!mute << TFA9879_S_MUTE_SHIFT);
108 103
109 return 0; 104 return 0;
110} 105}
@@ -152,11 +147,11 @@ static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
152 } 147 }
153 148
154 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1, 149 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
155 TFA9879_SCK_POL_MASK, 150 TFA9879_SCK_POL_MASK,
156 sck_pol << TFA9879_SCK_POL_SHIFT); 151 sck_pol << TFA9879_SCK_POL_SHIFT);
157 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1, 152 snd_soc_component_update_bits(component, TFA9879_SERIAL_INTERFACE_1,
158 TFA9879_I2S_SET_MASK, 153 TFA9879_I2S_SET_MASK,
159 i2s_set << TFA9879_I2S_SET_SHIFT); 154 i2s_set << TFA9879_I2S_SET_SHIFT);
160 return 0; 155 return 0;
161} 156}
162 157
@@ -276,8 +271,7 @@ static struct snd_soc_dai_driver tfa9879_dai = {
276 .ops = &tfa9879_dai_ops, 271 .ops = &tfa9879_dai_ops,
277}; 272};
278 273
279static int tfa9879_i2c_probe(struct i2c_client *i2c, 274static int tfa9879_i2c_probe(struct i2c_client *i2c)
280 const struct i2c_device_id *id)
281{ 275{
282 struct tfa9879_priv *tfa9879; 276 struct tfa9879_priv *tfa9879;
283 int i; 277 int i;
@@ -298,7 +292,7 @@ static int tfa9879_i2c_probe(struct i2c_client *i2c,
298 tfa9879_regs[i].reg, tfa9879_regs[i].def); 292 tfa9879_regs[i].reg, tfa9879_regs[i].def);
299 293
300 return devm_snd_soc_register_component(&i2c->dev, &tfa9879_component, 294 return devm_snd_soc_register_component(&i2c->dev, &tfa9879_component,
301 &tfa9879_dai, 1); 295 &tfa9879_dai, 1);
302} 296}
303 297
304static const struct i2c_device_id tfa9879_i2c_id[] = { 298static const struct i2c_device_id tfa9879_i2c_id[] = {
@@ -318,7 +312,7 @@ static struct i2c_driver tfa9879_i2c_driver = {
318 .name = "tfa9879", 312 .name = "tfa9879",
319 .of_match_table = tfa9879_of_match, 313 .of_match_table = tfa9879_of_match,
320 }, 314 },
321 .probe = tfa9879_i2c_probe, 315 .probe_new = tfa9879_i2c_probe,
322 .id_table = tfa9879_i2c_id, 316 .id_table = tfa9879_i2c_id,
323}; 317};
324 318
diff --git a/sound/soc/codecs/tfa9879.h b/sound/soc/codecs/tfa9879.h
index 3408c90c4628..66c88d0396fe 100644
--- a/sound/soc/codecs/tfa9879.h
+++ b/sound/soc/codecs/tfa9879.h
@@ -1,14 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
1/* 2/*
2 * tfa9879.h -- driver for NXP Semiconductors TFA9879 3 * tfa9879.h -- driver for NXP Semiconductors TFA9879
3 * 4 *
4 * Copyright (C) 2014 Axentia Technologies AB 5 * Copyright (C) 2014 Axentia Technologies AB
5 * Author: Peter Rosin <peda@axentia.se> 6 * Author: Peter Rosin <peda@axentia.se>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */ 7 */
13 8
14#ifndef _TFA9879_H 9#ifndef _TFA9879_H
diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c
index bbfc73a79b18..d18ff17719cc 100644
--- a/sound/soc/codecs/tscs42xx.c
+++ b/sound/soc/codecs/tscs42xx.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/clk.h>
15#include <sound/tlv.h> 16#include <sound/tlv.h>
16#include <sound/pcm_params.h> 17#include <sound/pcm_params.h>
17#include <sound/soc.h> 18#include <sound/soc.h>
@@ -31,7 +32,6 @@ struct tscs42xx {
31 32
32 int bclk_ratio; 33 int bclk_ratio;
33 int samplerate; 34 int samplerate;
34 unsigned int blrcm;
35 struct mutex audio_params_lock; 35 struct mutex audio_params_lock;
36 36
37 u8 coeff_ram[COEFF_RAM_SIZE]; 37 u8 coeff_ram[COEFF_RAM_SIZE];
@@ -42,7 +42,8 @@ struct tscs42xx {
42 42
43 struct regmap *regmap; 43 struct regmap *regmap;
44 44
45 struct device *dev; 45 struct clk *sysclk;
46 int sysclk_src_id;
46}; 47};
47 48
48struct coeff_ram_ctl { 49struct coeff_ram_ctl {
@@ -204,7 +205,8 @@ static int power_up_audio_plls(struct snd_soc_component *component)
204 break; 205 break;
205 default: 206 default:
206 ret = -EINVAL; 207 ret = -EINVAL;
207 dev_err(component->dev, "Unrecognized PLL output freq (%d)\n", ret); 208 dev_err(component->dev,
209 "Unrecognized PLL output freq (%d)\n", ret);
208 return ret; 210 return ret;
209 } 211 }
210 212
@@ -261,7 +263,8 @@ exit:
261static int coeff_ram_get(struct snd_kcontrol *kcontrol, 263static int coeff_ram_get(struct snd_kcontrol *kcontrol,
262 struct snd_ctl_elem_value *ucontrol) 264 struct snd_ctl_elem_value *ucontrol)
263{ 265{
264 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 266 struct snd_soc_component *component =
267 snd_soc_kcontrol_component(kcontrol);
265 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component); 268 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
266 struct coeff_ram_ctl *ctl = 269 struct coeff_ram_ctl *ctl =
267 (struct coeff_ram_ctl *)kcontrol->private_value; 270 (struct coeff_ram_ctl *)kcontrol->private_value;
@@ -280,7 +283,8 @@ static int coeff_ram_get(struct snd_kcontrol *kcontrol,
280static int coeff_ram_put(struct snd_kcontrol *kcontrol, 283static int coeff_ram_put(struct snd_kcontrol *kcontrol,
281 struct snd_ctl_elem_value *ucontrol) 284 struct snd_ctl_elem_value *ucontrol)
282{ 285{
283 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 286 struct snd_soc_component *component =
287 snd_soc_kcontrol_component(kcontrol);
284 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component); 288 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
285 struct coeff_ram_ctl *ctl = 289 struct coeff_ram_ctl *ctl =
286 (struct coeff_ram_ctl *)kcontrol->private_value; 290 (struct coeff_ram_ctl *)kcontrol->private_value;
@@ -363,7 +367,8 @@ static int dapm_micb_event(struct snd_soc_dapm_widget *w,
363static int pll_event(struct snd_soc_dapm_widget *w, 367static int pll_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event) 368 struct snd_kcontrol *kcontrol, int event)
365{ 369{
366 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 370 struct snd_soc_component *component =
371 snd_soc_dapm_to_component(w->dapm);
367 int ret; 372 int ret;
368 373
369 if (SND_SOC_DAPM_EVENT_ON(event)) 374 if (SND_SOC_DAPM_EVENT_ON(event))
@@ -377,7 +382,8 @@ static int pll_event(struct snd_soc_dapm_widget *w,
377static int dac_event(struct snd_soc_dapm_widget *w, 382static int dac_event(struct snd_soc_dapm_widget *w,
378 struct snd_kcontrol *kcontrol, int event) 383 struct snd_kcontrol *kcontrol, int event)
379{ 384{
380 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 385 struct snd_soc_component *component =
386 snd_soc_dapm_to_component(w->dapm);
381 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component); 387 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
382 int ret; 388 int ret;
383 389
@@ -819,16 +825,19 @@ static int setup_sample_format(struct snd_soc_component *component,
819 dev_err(component->dev, "Unsupported format width (%d)\n", ret); 825 dev_err(component->dev, "Unsupported format width (%d)\n", ret);
820 return ret; 826 return ret;
821 } 827 }
822 ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_WL, width); 828 ret = snd_soc_component_update_bits(component,
829 R_AIC1, RM_AIC1_WL, width);
823 if (ret < 0) { 830 if (ret < 0) {
824 dev_err(component->dev, "Failed to set sample width (%d)\n", ret); 831 dev_err(component->dev,
832 "Failed to set sample width (%d)\n", ret);
825 return ret; 833 return ret;
826 } 834 }
827 835
828 return 0; 836 return 0;
829} 837}
830 838
831static int setup_sample_rate(struct snd_soc_component *component, unsigned int rate) 839static int setup_sample_rate(struct snd_soc_component *component,
840 unsigned int rate)
832{ 841{
833 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component); 842 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
834 unsigned int br, bm; 843 unsigned int br, bm;
@@ -881,24 +890,32 @@ static int setup_sample_rate(struct snd_soc_component *component, unsigned int r
881 } 890 }
882 891
883 /* DAC and ADC share bit and frame clock */ 892 /* DAC and ADC share bit and frame clock */
884 ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBR, br); 893 ret = snd_soc_component_update_bits(component,
894 R_DACSR, RM_DACSR_DBR, br);
885 if (ret < 0) { 895 if (ret < 0) {
886 dev_err(component->dev, "Failed to update register (%d)\n", ret); 896 dev_err(component->dev,
897 "Failed to update register (%d)\n", ret);
887 return ret; 898 return ret;
888 } 899 }
889 ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBM, bm); 900 ret = snd_soc_component_update_bits(component,
901 R_DACSR, RM_DACSR_DBM, bm);
890 if (ret < 0) { 902 if (ret < 0) {
891 dev_err(component->dev, "Failed to update register (%d)\n", ret); 903 dev_err(component->dev,
904 "Failed to update register (%d)\n", ret);
892 return ret; 905 return ret;
893 } 906 }
894 ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBR, br); 907 ret = snd_soc_component_update_bits(component,
908 R_ADCSR, RM_DACSR_DBR, br);
895 if (ret < 0) { 909 if (ret < 0) {
896 dev_err(component->dev, "Failed to update register (%d)\n", ret); 910 dev_err(component->dev,
911 "Failed to update register (%d)\n", ret);
897 return ret; 912 return ret;
898 } 913 }
899 ret = snd_soc_component_update_bits(component, R_ADCSR, RM_DACSR_DBM, bm); 914 ret = snd_soc_component_update_bits(component,
915 R_ADCSR, RM_DACSR_DBM, bm);
900 if (ret < 0) { 916 if (ret < 0) {
901 dev_err(component->dev, "Failed to update register (%d)\n", ret); 917 dev_err(component->dev,
918 "Failed to update register (%d)\n", ret);
902 return ret; 919 return ret;
903 } 920 }
904 921
@@ -1076,7 +1093,8 @@ static int tscs42xx_hw_params(struct snd_pcm_substream *substream,
1076 1093
1077 ret = setup_sample_rate(component, params_rate(params)); 1094 ret = setup_sample_rate(component, params_rate(params));
1078 if (ret < 0) { 1095 if (ret < 0) {
1079 dev_err(component->dev, "Failed to setup sample rate (%d)\n", ret); 1096 dev_err(component->dev,
1097 "Failed to setup sample rate (%d)\n", ret);
1080 return ret; 1098 return ret;
1081 } 1099 }
1082 1100
@@ -1087,7 +1105,8 @@ static inline int dac_mute(struct snd_soc_component *component)
1087{ 1105{
1088 int ret; 1106 int ret;
1089 1107
1090 ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU, 1108 ret = snd_soc_component_update_bits(component,
1109 R_CNVRTR1, RM_CNVRTR1_DACMU,
1091 RV_CNVRTR1_DACMU_ENABLE); 1110 RV_CNVRTR1_DACMU_ENABLE);
1092 if (ret < 0) { 1111 if (ret < 0) {
1093 dev_err(component->dev, "Failed to mute DAC (%d)\n", 1112 dev_err(component->dev, "Failed to mute DAC (%d)\n",
@@ -1102,7 +1121,8 @@ static inline int dac_unmute(struct snd_soc_component *component)
1102{ 1121{
1103 int ret; 1122 int ret;
1104 1123
1105 ret = snd_soc_component_update_bits(component, R_CNVRTR1, RM_CNVRTR1_DACMU, 1124 ret = snd_soc_component_update_bits(component,
1125 R_CNVRTR1, RM_CNVRTR1_DACMU,
1106 RV_CNVRTR1_DACMU_DISABLE); 1126 RV_CNVRTR1_DACMU_DISABLE);
1107 if (ret < 0) { 1127 if (ret < 0) {
1108 dev_err(component->dev, "Failed to unmute DAC (%d)\n", 1128 dev_err(component->dev, "Failed to unmute DAC (%d)\n",
@@ -1117,8 +1137,8 @@ static inline int adc_mute(struct snd_soc_component *component)
1117{ 1137{
1118 int ret; 1138 int ret;
1119 1139
1120 ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU, 1140 ret = snd_soc_component_update_bits(component,
1121 RV_CNVRTR0_ADCMU_ENABLE); 1141 R_CNVRTR0, RM_CNVRTR0_ADCMU, RV_CNVRTR0_ADCMU_ENABLE);
1122 if (ret < 0) { 1142 if (ret < 0) {
1123 dev_err(component->dev, "Failed to mute ADC (%d)\n", 1143 dev_err(component->dev, "Failed to mute ADC (%d)\n",
1124 ret); 1144 ret);
@@ -1132,8 +1152,8 @@ static inline int adc_unmute(struct snd_soc_component *component)
1132{ 1152{
1133 int ret; 1153 int ret;
1134 1154
1135 ret = snd_soc_component_update_bits(component, R_CNVRTR0, RM_CNVRTR0_ADCMU, 1155 ret = snd_soc_component_update_bits(component,
1136 RV_CNVRTR0_ADCMU_DISABLE); 1156 R_CNVRTR0, RM_CNVRTR0_ADCMU, RV_CNVRTR0_ADCMU_DISABLE);
1137 if (ret < 0) { 1157 if (ret < 0) {
1138 dev_err(component->dev, "Failed to unmute ADC (%d)\n", 1158 dev_err(component->dev, "Failed to unmute ADC (%d)\n",
1139 ret); 1159 ret);
@@ -1171,8 +1191,8 @@ static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
1171 /* Slave mode not supported since it needs always-on frame clock */ 1191 /* Slave mode not supported since it needs always-on frame clock */
1172 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1192 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1173 case SND_SOC_DAIFMT_CBM_CFM: 1193 case SND_SOC_DAIFMT_CBM_CFM:
1174 ret = snd_soc_component_update_bits(component, R_AIC1, RM_AIC1_MS, 1194 ret = snd_soc_component_update_bits(component,
1175 RV_AIC1_MS_MASTER); 1195 R_AIC1, RM_AIC1_MS, RV_AIC1_MS_MASTER);
1176 if (ret < 0) { 1196 if (ret < 0) {
1177 dev_err(component->dev, 1197 dev_err(component->dev,
1178 "Failed to set codec DAI master (%d)\n", ret); 1198 "Failed to set codec DAI master (%d)\n", ret);
@@ -1211,14 +1231,18 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
1211 return -EINVAL; 1231 return -EINVAL;
1212 } 1232 }
1213 1233
1214 ret = snd_soc_component_update_bits(component, R_DACSR, RM_DACSR_DBCM, value); 1234 ret = snd_soc_component_update_bits(component,
1235 R_DACSR, RM_DACSR_DBCM, value);
1215 if (ret < 0) { 1236 if (ret < 0) {
1216 dev_err(component->dev, "Failed to set DAC BCLK ratio (%d)\n", ret); 1237 dev_err(component->dev,
1238 "Failed to set DAC BCLK ratio (%d)\n", ret);
1217 return ret; 1239 return ret;
1218 } 1240 }
1219 ret = snd_soc_component_update_bits(component, R_ADCSR, RM_ADCSR_ABCM, value); 1241 ret = snd_soc_component_update_bits(component,
1242 R_ADCSR, RM_ADCSR_ABCM, value);
1220 if (ret < 0) { 1243 if (ret < 0) {
1221 dev_err(component->dev, "Failed to set ADC BCLK ratio (%d)\n", ret); 1244 dev_err(component->dev,
1245 "Failed to set ADC BCLK ratio (%d)\n", ret);
1222 return ret; 1246 return ret;
1223 } 1247 }
1224 1248
@@ -1231,13 +1255,46 @@ static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai,
1231 return 0; 1255 return 0;
1232} 1256}
1233 1257
1234static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, 1258static const struct snd_soc_dai_ops tscs42xx_dai_ops = {
1235 int clk_id, unsigned int freq, int dir) 1259 .hw_params = tscs42xx_hw_params,
1260 .mute_stream = tscs42xx_mute_stream,
1261 .set_fmt = tscs42xx_set_dai_fmt,
1262 .set_bclk_ratio = tscs42xx_set_dai_bclk_ratio,
1263};
1264
1265static int part_is_valid(struct tscs42xx *tscs42xx)
1236{ 1266{
1237 struct snd_soc_component *component = codec_dai->component; 1267 int val;
1238 int ret; 1268 int ret;
1269 unsigned int reg;
1270
1271 ret = regmap_read(tscs42xx->regmap, R_DEVIDH, &reg);
1272 if (ret < 0)
1273 return ret;
1274
1275 val = reg << 8;
1276 ret = regmap_read(tscs42xx->regmap, R_DEVIDL, &reg);
1277 if (ret < 0)
1278 return ret;
1279
1280 val |= reg;
1281
1282 switch (val) {
1283 case 0x4A74:
1284 case 0x4A73:
1285 return true;
1286 default:
1287 return false;
1288 };
1289}
1239 1290
1240 switch (clk_id) { 1291static int set_sysclk(struct snd_soc_component *component)
1292{
1293 struct tscs42xx *tscs42xx = snd_soc_component_get_drvdata(component);
1294 unsigned long freq;
1295 int ret;
1296
1297 switch (tscs42xx->sysclk_src_id) {
1241 case TSCS42XX_PLL_SRC_XTAL: 1298 case TSCS42XX_PLL_SRC_XTAL:
1242 case TSCS42XX_PLL_SRC_MCLK1: 1299 case TSCS42XX_PLL_SRC_MCLK1:
1243 ret = snd_soc_component_write(component, R_PLLREFSEL, 1300 ret = snd_soc_component_write(component, R_PLLREFSEL,
@@ -1265,6 +1322,7 @@ static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1265 return -EINVAL; 1322 return -EINVAL;
1266 } 1323 }
1267 1324
1325 freq = clk_get_rate(tscs42xx->sysclk);
1268 ret = set_pll_ctl_from_input_freq(component, freq); 1326 ret = set_pll_ctl_from_input_freq(component, freq);
1269 if (ret < 0) { 1327 if (ret < 0) {
1270 dev_err(component->dev, 1328 dev_err(component->dev,
@@ -1275,41 +1333,13 @@ static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1275 return 0; 1333 return 0;
1276} 1334}
1277 1335
1278static const struct snd_soc_dai_ops tscs42xx_dai_ops = { 1336static int tscs42xx_probe(struct snd_soc_component *component)
1279 .hw_params = tscs42xx_hw_params,
1280 .mute_stream = tscs42xx_mute_stream,
1281 .set_fmt = tscs42xx_set_dai_fmt,
1282 .set_bclk_ratio = tscs42xx_set_dai_bclk_ratio,
1283 .set_sysclk = tscs42xx_set_dai_sysclk,
1284};
1285
1286static int part_is_valid(struct tscs42xx *tscs42xx)
1287{ 1337{
1288 int val; 1338 return set_sysclk(component);
1289 int ret;
1290 unsigned int reg;
1291
1292 ret = regmap_read(tscs42xx->regmap, R_DEVIDH, &reg);
1293 if (ret < 0)
1294 return ret;
1295
1296 val = reg << 8;
1297 ret = regmap_read(tscs42xx->regmap, R_DEVIDL, &reg);
1298 if (ret < 0)
1299 return ret;
1300
1301 val |= reg;
1302
1303 switch (val) {
1304 case 0x4A74:
1305 case 0x4A73:
1306 return true;
1307 default:
1308 return false;
1309 };
1310} 1339}
1311 1340
1312static struct snd_soc_component_driver soc_codec_dev_tscs42xx = { 1341static const struct snd_soc_component_driver soc_codec_dev_tscs42xx = {
1342 .probe = tscs42xx_probe,
1313 .dapm_widgets = tscs42xx_dapm_widgets, 1343 .dapm_widgets = tscs42xx_dapm_widgets,
1314 .num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets), 1344 .num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets),
1315 .dapm_routes = tscs42xx_intercon, 1345 .dapm_routes = tscs42xx_intercon,
@@ -1367,11 +1397,15 @@ static const struct reg_sequence tscs42xx_patch[] = {
1367 { R_AIC2, RV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED }, 1397 { R_AIC2, RV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED },
1368}; 1398};
1369 1399
1400static char const * const src_names[TSCS42XX_PLL_SRC_CNT] = {
1401 "xtal", "mclk1", "mclk2"};
1402
1370static int tscs42xx_i2c_probe(struct i2c_client *i2c, 1403static int tscs42xx_i2c_probe(struct i2c_client *i2c,
1371 const struct i2c_device_id *id) 1404 const struct i2c_device_id *id)
1372{ 1405{
1373 struct tscs42xx *tscs42xx; 1406 struct tscs42xx *tscs42xx;
1374 int ret = 0; 1407 int src;
1408 int ret;
1375 1409
1376 tscs42xx = devm_kzalloc(&i2c->dev, sizeof(*tscs42xx), GFP_KERNEL); 1410 tscs42xx = devm_kzalloc(&i2c->dev, sizeof(*tscs42xx), GFP_KERNEL);
1377 if (!tscs42xx) { 1411 if (!tscs42xx) {
@@ -1381,12 +1415,29 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
1381 return ret; 1415 return ret;
1382 } 1416 }
1383 i2c_set_clientdata(i2c, tscs42xx); 1417 i2c_set_clientdata(i2c, tscs42xx);
1384 tscs42xx->dev = &i2c->dev; 1418
1419 for (src = TSCS42XX_PLL_SRC_XTAL; src < TSCS42XX_PLL_SRC_CNT; src++) {
1420 tscs42xx->sysclk = devm_clk_get(&i2c->dev, src_names[src]);
1421 if (!IS_ERR(tscs42xx->sysclk)) {
1422 break;
1423 } else if (PTR_ERR(tscs42xx->sysclk) != -ENOENT) {
1424 ret = PTR_ERR(tscs42xx->sysclk);
1425 dev_err(&i2c->dev, "Failed to get sysclk (%d)\n", ret);
1426 return ret;
1427 }
1428 }
1429 if (src == TSCS42XX_PLL_SRC_CNT) {
1430 ret = -EINVAL;
1431 dev_err(&i2c->dev, "Failed to get a valid clock name (%d)\n",
1432 ret);
1433 return ret;
1434 }
1435 tscs42xx->sysclk_src_id = src;
1385 1436
1386 tscs42xx->regmap = devm_regmap_init_i2c(i2c, &tscs42xx_regmap); 1437 tscs42xx->regmap = devm_regmap_init_i2c(i2c, &tscs42xx_regmap);
1387 if (IS_ERR(tscs42xx->regmap)) { 1438 if (IS_ERR(tscs42xx->regmap)) {
1388 ret = PTR_ERR(tscs42xx->regmap); 1439 ret = PTR_ERR(tscs42xx->regmap);
1389 dev_err(tscs42xx->dev, "Failed to allocate regmap (%d)\n", ret); 1440 dev_err(&i2c->dev, "Failed to allocate regmap (%d)\n", ret);
1390 return ret; 1441 return ret;
1391 } 1442 }
1392 1443
@@ -1394,21 +1445,21 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
1394 1445
1395 ret = part_is_valid(tscs42xx); 1446 ret = part_is_valid(tscs42xx);
1396 if (ret <= 0) { 1447 if (ret <= 0) {
1397 dev_err(tscs42xx->dev, "No valid part (%d)\n", ret); 1448 dev_err(&i2c->dev, "No valid part (%d)\n", ret);
1398 ret = -ENODEV; 1449 ret = -ENODEV;
1399 return ret; 1450 return ret;
1400 } 1451 }
1401 1452
1402 ret = regmap_write(tscs42xx->regmap, R_RESET, RV_RESET_ENABLE); 1453 ret = regmap_write(tscs42xx->regmap, R_RESET, RV_RESET_ENABLE);
1403 if (ret < 0) { 1454 if (ret < 0) {
1404 dev_err(tscs42xx->dev, "Failed to reset device (%d)\n", ret); 1455 dev_err(&i2c->dev, "Failed to reset device (%d)\n", ret);
1405 return ret; 1456 return ret;
1406 } 1457 }
1407 1458
1408 ret = regmap_register_patch(tscs42xx->regmap, tscs42xx_patch, 1459 ret = regmap_register_patch(tscs42xx->regmap, tscs42xx_patch,
1409 ARRAY_SIZE(tscs42xx_patch)); 1460 ARRAY_SIZE(tscs42xx_patch));
1410 if (ret < 0) { 1461 if (ret < 0) {
1411 dev_err(tscs42xx->dev, "Failed to apply patch (%d)\n", ret); 1462 dev_err(&i2c->dev, "Failed to apply patch (%d)\n", ret);
1412 return ret; 1463 return ret;
1413 } 1464 }
1414 1465
@@ -1416,10 +1467,10 @@ static int tscs42xx_i2c_probe(struct i2c_client *i2c,
1416 mutex_init(&tscs42xx->coeff_ram_lock); 1467 mutex_init(&tscs42xx->coeff_ram_lock);
1417 mutex_init(&tscs42xx->pll_lock); 1468 mutex_init(&tscs42xx->pll_lock);
1418 1469
1419 ret = devm_snd_soc_register_component(tscs42xx->dev, &soc_codec_dev_tscs42xx, 1470 ret = devm_snd_soc_register_component(&i2c->dev,
1420 &tscs42xx_dai, 1); 1471 &soc_codec_dev_tscs42xx, &tscs42xx_dai, 1);
1421 if (ret) { 1472 if (ret) {
1422 dev_err(tscs42xx->dev, "Failed to register codec (%d)\n", ret); 1473 dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
1423 return ret; 1474 return ret;
1424 } 1475 }
1425 1476
diff --git a/sound/soc/codecs/tscs42xx.h b/sound/soc/codecs/tscs42xx.h
index d4a30bcbf64b..814c8f3c4a68 100644
--- a/sound/soc/codecs/tscs42xx.h
+++ b/sound/soc/codecs/tscs42xx.h
@@ -7,10 +7,10 @@
7#define __WOOKIE_H__ 7#define __WOOKIE_H__
8 8
9enum { 9enum {
10 TSCS42XX_PLL_SRC_NONE,
11 TSCS42XX_PLL_SRC_XTAL, 10 TSCS42XX_PLL_SRC_XTAL,
12 TSCS42XX_PLL_SRC_MCLK1, 11 TSCS42XX_PLL_SRC_MCLK1,
13 TSCS42XX_PLL_SRC_MCLK2, 12 TSCS42XX_PLL_SRC_MCLK2,
13 TSCS42XX_PLL_SRC_CNT,
14}; 14};
15 15
16#define R_HPVOLL 0x0 16#define R_HPVOLL 0x0
diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c
new file mode 100644
index 000000000000..ff85a0bf6170
--- /dev/null
+++ b/sound/soc/codecs/tscs454.c
@@ -0,0 +1,3497 @@
1// SPDX-License-Identifier: GPL-2.0
2// tscs454.c -- TSCS454 ALSA SoC Audio driver
3// Copyright 2018 Tempo Semiconductor, Inc.
4// Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com>
5
6#include <linux/kernel.h>
7#include <linux/clk.h>
8#include <linux/device.h>
9#include <linux/regmap.h>
10#include <linux/i2c.h>
11#include <linux/err.h>
12#include <linux/string.h>
13#include <linux/module.h>
14#include <linux/delay.h>
15#include <linux/mutex.h>
16
17#include <sound/tlv.h>
18#include <sound/pcm_params.h>
19#include <sound/pcm.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include "tscs454.h"
24
25static const unsigned int PLL_48K_RATE = (48000 * 256);
26static const unsigned int PLL_44_1K_RATE = (44100 * 256);
27
28#define COEFF_SIZE 3
29#define BIQUAD_COEFF_COUNT 5
30#define BIQUAD_SIZE (COEFF_SIZE * BIQUAD_COEFF_COUNT)
31
32#define COEFF_RAM_MAX_ADDR 0xcd
33#define COEFF_RAM_COEFF_COUNT (COEFF_RAM_MAX_ADDR + 1)
34#define COEFF_RAM_SIZE (COEFF_SIZE * COEFF_RAM_COEFF_COUNT)
35
36enum {
37 TSCS454_DAI1_ID,
38 TSCS454_DAI2_ID,
39 TSCS454_DAI3_ID,
40 TSCS454_DAI_COUNT,
41};
42
43struct pll {
44 int id;
45 unsigned int users;
46 struct mutex lock;
47};
48
49static inline void pll_init(struct pll *pll, int id)
50{
51 pll->id = id;
52 mutex_init(&pll->lock);
53}
54
55struct internal_rate {
56 struct pll *pll;
57};
58
59struct aif {
60 unsigned int id;
61 bool master;
62 struct pll *pll;
63};
64
65static inline void aif_init(struct aif *aif, unsigned int id)
66{
67 aif->id = id;
68}
69
70struct coeff_ram {
71 u8 cache[COEFF_RAM_SIZE];
72 bool synced;
73 struct mutex lock;
74};
75
76static inline void init_coeff_ram_cache(u8 *cache)
77{
78 static const u8 norm_addrs[] = { 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19,
79 0x1f, 0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45,
80 0x4a, 0x4f, 0x54, 0x59, 0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74,
81 0x79, 0x7f, 0x80, 0x85, 0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3,
82 0xa8, 0xad, 0xaf, 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9};
83 int i;
84
85 for (i = 0; i < ARRAY_SIZE(norm_addrs); i++)
86 cache[((norm_addrs[i] + 1) * COEFF_SIZE) - 1] = 0x40;
87}
88
89static inline void coeff_ram_init(struct coeff_ram *ram)
90{
91 init_coeff_ram_cache(ram->cache);
92 mutex_init(&ram->lock);
93}
94
95struct aifs_status {
96 u8 streams;
97};
98
99static inline void set_aif_status_active(struct aifs_status *status,
100 int aif_id, bool playback)
101{
102 u8 mask = 0x01 << (aif_id * 2 + !playback);
103
104 status->streams |= mask;
105}
106
107static inline void set_aif_status_inactive(struct aifs_status *status,
108 int aif_id, bool playback)
109{
110 u8 mask = ~(0x01 << (aif_id * 2 + !playback));
111
112 status->streams &= mask;
113}
114
115static bool aifs_active(struct aifs_status *status)
116{
117 return status->streams;
118}
119
120static bool aif_active(struct aifs_status *status, int aif_id)
121{
122 return (0x03 << aif_id * 2) & status->streams;
123}
124
125struct tscs454 {
126 struct regmap *regmap;
127 struct aif aifs[TSCS454_DAI_COUNT];
128
129 struct aifs_status aifs_status;
130 struct mutex aifs_status_lock;
131
132 struct pll pll1;
133 struct pll pll2;
134 struct internal_rate internal_rate;
135
136 struct coeff_ram dac_ram;
137 struct coeff_ram spk_ram;
138 struct coeff_ram sub_ram;
139
140 struct clk *sysclk;
141 int sysclk_src_id;
142 unsigned int bclk_freq;
143};
144
145struct coeff_ram_ctl {
146 unsigned int addr;
147 struct soc_bytes_ext bytes_ext;
148};
149
150static const struct reg_sequence tscs454_patch[] = {
151 /* Assign ASRC out of the box so DAI 1 just works */
152 { R_AUDIOMUX1, FV_ASRCIMUX_I2S1 | FV_I2S2MUX_I2S2 },
153 { R_AUDIOMUX2, FV_ASRCOMUX_I2S1 | FV_DACMUX_I2S1 | FV_I2S3MUX_I2S3 },
154 { R_AUDIOMUX3, FV_CLSSDMUX_I2S1 | FV_SUBMUX_I2S1_LR },
155 { R_TDMCTL0, FV_TDMMD_256 },
156 { VIRT_ADDR(0x0A, 0x13), 1 << 3 },
157};
158
159static bool tscs454_volatile(struct device *dev, unsigned int reg)
160{
161 switch (reg) {
162 case R_PLLSTAT:
163
164 case R_SPKCRRDL:
165 case R_SPKCRRDM:
166 case R_SPKCRRDH:
167 case R_SPKCRS:
168
169 case R_DACCRRDL:
170 case R_DACCRRDM:
171 case R_DACCRRDH:
172 case R_DACCRS:
173
174 case R_SUBCRRDL:
175 case R_SUBCRRDM:
176 case R_SUBCRRDH:
177 case R_SUBCRS:
178 return true;
179 default:
180 return false;
181 };
182}
183
184static bool tscs454_writable(struct device *dev, unsigned int reg)
185{
186 switch (reg) {
187 case R_SPKCRRDL:
188 case R_SPKCRRDM:
189 case R_SPKCRRDH:
190
191 case R_DACCRRDL:
192 case R_DACCRRDM:
193 case R_DACCRRDH:
194
195 case R_SUBCRRDL:
196 case R_SUBCRRDM:
197 case R_SUBCRRDH:
198 return false;
199 default:
200 return true;
201 };
202}
203
204static bool tscs454_readable(struct device *dev, unsigned int reg)
205{
206 switch (reg) {
207 case R_SPKCRWDL:
208 case R_SPKCRWDM:
209 case R_SPKCRWDH:
210
211 case R_DACCRWDL:
212 case R_DACCRWDM:
213 case R_DACCRWDH:
214
215 case R_SUBCRWDL:
216 case R_SUBCRWDM:
217 case R_SUBCRWDH:
218 return false;
219 default:
220 return true;
221 };
222}
223
224static bool tscs454_precious(struct device *dev, unsigned int reg)
225{
226 switch (reg) {
227 case R_SPKCRWDL:
228 case R_SPKCRWDM:
229 case R_SPKCRWDH:
230 case R_SPKCRRDL:
231 case R_SPKCRRDM:
232 case R_SPKCRRDH:
233
234 case R_DACCRWDL:
235 case R_DACCRWDM:
236 case R_DACCRWDH:
237 case R_DACCRRDL:
238 case R_DACCRRDM:
239 case R_DACCRRDH:
240
241 case R_SUBCRWDL:
242 case R_SUBCRWDM:
243 case R_SUBCRWDH:
244 case R_SUBCRRDL:
245 case R_SUBCRRDM:
246 case R_SUBCRRDH:
247 return true;
248 default:
249 return false;
250 };
251}
252
253static const struct regmap_range_cfg tscs454_regmap_range_cfg = {
254 .name = "Pages",
255 .range_min = VIRT_BASE,
256 .range_max = VIRT_ADDR(0xFE, 0x02),
257 .selector_reg = R_PAGESEL,
258 .selector_mask = 0xff,
259 .selector_shift = 0,
260 .window_start = 0,
261 .window_len = 0x100,
262};
263
264static struct regmap_config const tscs454_regmap_cfg = {
265 .reg_bits = 8,
266 .val_bits = 8,
267 .writeable_reg = tscs454_writable,
268 .readable_reg = tscs454_readable,
269 .volatile_reg = tscs454_volatile,
270 .precious_reg = tscs454_precious,
271 .ranges = &tscs454_regmap_range_cfg,
272 .num_ranges = 1,
273 .max_register = VIRT_ADDR(0xFE, 0x02),
274 .cache_type = REGCACHE_RBTREE,
275};
276
277static inline int tscs454_data_init(struct tscs454 *tscs454,
278 struct i2c_client *i2c)
279{
280 int i;
281 int ret;
282
283 tscs454->regmap = devm_regmap_init_i2c(i2c, &tscs454_regmap_cfg);
284 if (IS_ERR(tscs454->regmap)) {
285 ret = PTR_ERR(tscs454->regmap);
286 return ret;
287 }
288
289 for (i = 0; i < TSCS454_DAI_COUNT; i++)
290 aif_init(&tscs454->aifs[i], i);
291
292 mutex_init(&tscs454->aifs_status_lock);
293 pll_init(&tscs454->pll1, 1);
294 pll_init(&tscs454->pll2, 2);
295
296 coeff_ram_init(&tscs454->dac_ram);
297 coeff_ram_init(&tscs454->spk_ram);
298 coeff_ram_init(&tscs454->sub_ram);
299
300 return 0;
301}
302
303struct reg_setting {
304 unsigned int addr;
305 unsigned int val;
306};
307
308static int coeff_ram_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol)
310{
311 struct snd_soc_component *component =
312 snd_soc_kcontrol_component(kcontrol);
313 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
314 struct coeff_ram_ctl *ctl =
315 (struct coeff_ram_ctl *)kcontrol->private_value;
316 struct soc_bytes_ext *params = &ctl->bytes_ext;
317 u8 *coeff_ram;
318 struct mutex *coeff_ram_lock;
319
320 if (strstr(kcontrol->id.name, "DAC")) {
321 coeff_ram = tscs454->dac_ram.cache;
322 coeff_ram_lock = &tscs454->dac_ram.lock;
323 } else if (strstr(kcontrol->id.name, "Speaker")) {
324 coeff_ram = tscs454->spk_ram.cache;
325 coeff_ram_lock = &tscs454->spk_ram.lock;
326 } else if (strstr(kcontrol->id.name, "Sub")) {
327 coeff_ram = tscs454->sub_ram.cache;
328 coeff_ram_lock = &tscs454->sub_ram.lock;
329 } else {
330 return -EINVAL;
331 }
332
333 mutex_lock(coeff_ram_lock);
334
335 memcpy(ucontrol->value.bytes.data,
336 &coeff_ram[ctl->addr * COEFF_SIZE], params->max);
337
338 mutex_unlock(coeff_ram_lock);
339
340 return 0;
341}
342
343#define DACCRSTAT_MAX_TRYS 10
344static int write_coeff_ram(struct snd_soc_component *component, u8 *coeff_ram,
345 unsigned int r_stat, unsigned int r_addr, unsigned int r_wr,
346 unsigned int coeff_addr, unsigned int coeff_cnt)
347{
348 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
349 unsigned int val;
350 int cnt;
351 int trys;
352 int ret;
353
354 for (cnt = 0; cnt < coeff_cnt; cnt++, coeff_addr++) {
355
356 for (trys = 0; trys < DACCRSTAT_MAX_TRYS; trys++) {
357 ret = snd_soc_component_read(component, r_stat, &val);
358 if (ret < 0) {
359 dev_err(component->dev,
360 "Failed to read stat (%d)\n", ret);
361 return ret;
362 }
363 if (!val)
364 break;
365 }
366
367 if (trys == DACCRSTAT_MAX_TRYS) {
368 ret = -EIO;
369 dev_err(component->dev,
370 "Coefficient write error (%d)\n", ret);
371 return ret;
372 }
373
374 ret = regmap_write(tscs454->regmap, r_addr, coeff_addr);
375 if (ret < 0) {
376 dev_err(component->dev,
377 "Failed to write dac ram address (%d)\n", ret);
378 return ret;
379 }
380
381 ret = regmap_bulk_write(tscs454->regmap, r_wr,
382 &coeff_ram[coeff_addr * COEFF_SIZE],
383 COEFF_SIZE);
384 if (ret < 0) {
385 dev_err(component->dev,
386 "Failed to write dac ram (%d)\n", ret);
387 return ret;
388 }
389 }
390
391 return 0;
392}
393
394static int coeff_ram_put(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
396{
397 struct snd_soc_component *component =
398 snd_soc_kcontrol_component(kcontrol);
399 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
400 struct coeff_ram_ctl *ctl =
401 (struct coeff_ram_ctl *)kcontrol->private_value;
402 struct soc_bytes_ext *params = &ctl->bytes_ext;
403 unsigned int coeff_cnt = params->max / COEFF_SIZE;
404 u8 *coeff_ram;
405 struct mutex *coeff_ram_lock;
406 bool *coeff_ram_synced;
407 unsigned int r_stat;
408 unsigned int r_addr;
409 unsigned int r_wr;
410 unsigned int val;
411 int ret;
412
413 if (strstr(kcontrol->id.name, "DAC")) {
414 coeff_ram = tscs454->dac_ram.cache;
415 coeff_ram_lock = &tscs454->dac_ram.lock;
416 coeff_ram_synced = &tscs454->dac_ram.synced;
417 r_stat = R_DACCRS;
418 r_addr = R_DACCRADD;
419 r_wr = R_DACCRWDL;
420 } else if (strstr(kcontrol->id.name, "Speaker")) {
421 coeff_ram = tscs454->spk_ram.cache;
422 coeff_ram_lock = &tscs454->spk_ram.lock;
423 coeff_ram_synced = &tscs454->spk_ram.synced;
424 r_stat = R_SPKCRS;
425 r_addr = R_SPKCRADD;
426 r_wr = R_SPKCRWDL;
427 } else if (strstr(kcontrol->id.name, "Sub")) {
428 coeff_ram = tscs454->sub_ram.cache;
429 coeff_ram_lock = &tscs454->sub_ram.lock;
430 coeff_ram_synced = &tscs454->sub_ram.synced;
431 r_stat = R_SUBCRS;
432 r_addr = R_SUBCRADD;
433 r_wr = R_SUBCRWDL;
434 } else {
435 return -EINVAL;
436 }
437
438 mutex_lock(coeff_ram_lock);
439
440 *coeff_ram_synced = false;
441
442 memcpy(&coeff_ram[ctl->addr * COEFF_SIZE],
443 ucontrol->value.bytes.data, params->max);
444
445 mutex_lock(&tscs454->pll1.lock);
446 mutex_lock(&tscs454->pll2.lock);
447
448 ret = snd_soc_component_read(component, R_PLLSTAT, &val);
449 if (ret < 0) {
450 dev_err(component->dev, "Failed to read PLL status (%d)\n",
451 ret);
452 goto exit;
453 }
454 if (val) { /* PLLs locked */
455 ret = write_coeff_ram(component, coeff_ram,
456 r_stat, r_addr, r_wr,
457 ctl->addr, coeff_cnt);
458 if (ret < 0) {
459 dev_err(component->dev,
460 "Failed to flush coeff ram cache (%d)\n", ret);
461 goto exit;
462 }
463 *coeff_ram_synced = true;
464 }
465
466 ret = 0;
467exit:
468 mutex_unlock(&tscs454->pll2.lock);
469 mutex_unlock(&tscs454->pll1.lock);
470 mutex_unlock(coeff_ram_lock);
471
472 return ret;
473}
474
475static inline int coeff_ram_sync(struct snd_soc_component *component,
476 struct tscs454 *tscs454)
477{
478 int ret;
479
480 mutex_lock(&tscs454->dac_ram.lock);
481 if (!tscs454->dac_ram.synced) {
482 ret = write_coeff_ram(component, tscs454->dac_ram.cache,
483 R_DACCRS, R_DACCRADD, R_DACCRWDL,
484 0x00, COEFF_RAM_COEFF_COUNT);
485 if (ret < 0) {
486 mutex_unlock(&tscs454->dac_ram.lock);
487 return ret;
488 }
489 }
490 mutex_unlock(&tscs454->dac_ram.lock);
491
492 mutex_lock(&tscs454->spk_ram.lock);
493 if (!tscs454->spk_ram.synced) {
494 ret = write_coeff_ram(component, tscs454->spk_ram.cache,
495 R_SPKCRS, R_SPKCRADD, R_SPKCRWDL,
496 0x00, COEFF_RAM_COEFF_COUNT);
497 if (ret < 0) {
498 mutex_unlock(&tscs454->spk_ram.lock);
499 return ret;
500 }
501 }
502 mutex_unlock(&tscs454->spk_ram.lock);
503
504 mutex_lock(&tscs454->sub_ram.lock);
505 if (!tscs454->sub_ram.synced) {
506 ret = write_coeff_ram(component, tscs454->sub_ram.cache,
507 R_SUBCRS, R_SUBCRADD, R_SUBCRWDL,
508 0x00, COEFF_RAM_COEFF_COUNT);
509 if (ret < 0) {
510 mutex_unlock(&tscs454->sub_ram.lock);
511 return ret;
512 }
513 }
514 mutex_unlock(&tscs454->sub_ram.lock);
515
516 return 0;
517}
518
519#define PLL_REG_SETTINGS_COUNT 11
520struct pll_ctl {
521 int freq_in;
522 struct reg_setting settings[PLL_REG_SETTINGS_COUNT];
523};
524
525#define PLL_CTL(f, t, c1, r1, o1, f1l, f1h, c2, r2, o2, f2l, f2h) \
526 { \
527 .freq_in = f, \
528 .settings = { \
529 {R_PLL1CTL, c1}, \
530 {R_PLL1RDIV, r1}, \
531 {R_PLL1ODIV, o1}, \
532 {R_PLL1FDIVL, f1l}, \
533 {R_PLL1FDIVH, f1h}, \
534 {R_PLL2CTL, c2}, \
535 {R_PLL2RDIV, r2}, \
536 {R_PLL2ODIV, o2}, \
537 {R_PLL2FDIVL, f2l}, \
538 {R_PLL2FDIVH, f2h}, \
539 {R_TIMEBASE, t}, \
540 }, \
541 }
542
543static const struct pll_ctl pll_ctls[] = {
544 PLL_CTL(1411200, 0x05,
545 0xB9, 0x07, 0x02, 0xC3, 0x04,
546 0x5A, 0x02, 0x03, 0xE0, 0x01),
547 PLL_CTL(1536000, 0x05,
548 0x5A, 0x02, 0x03, 0xE0, 0x01,
549 0x5A, 0x02, 0x03, 0xB9, 0x01),
550 PLL_CTL(2822400, 0x0A,
551 0x63, 0x07, 0x04, 0xC3, 0x04,
552 0x62, 0x07, 0x03, 0x48, 0x03),
553 PLL_CTL(3072000, 0x0B,
554 0x62, 0x07, 0x03, 0x48, 0x03,
555 0x5A, 0x04, 0x03, 0xB9, 0x01),
556 PLL_CTL(5644800, 0x15,
557 0x63, 0x0E, 0x04, 0xC3, 0x04,
558 0x5A, 0x08, 0x03, 0xE0, 0x01),
559 PLL_CTL(6144000, 0x17,
560 0x5A, 0x08, 0x03, 0xE0, 0x01,
561 0x5A, 0x08, 0x03, 0xB9, 0x01),
562 PLL_CTL(12000000, 0x2E,
563 0x5B, 0x19, 0x03, 0x00, 0x03,
564 0x6A, 0x19, 0x05, 0x98, 0x04),
565 PLL_CTL(19200000, 0x4A,
566 0x53, 0x14, 0x03, 0x80, 0x01,
567 0x5A, 0x19, 0x03, 0xB9, 0x01),
568 PLL_CTL(22000000, 0x55,
569 0x6A, 0x37, 0x05, 0x00, 0x06,
570 0x62, 0x26, 0x03, 0x49, 0x02),
571 PLL_CTL(22579200, 0x57,
572 0x62, 0x31, 0x03, 0x20, 0x03,
573 0x53, 0x1D, 0x03, 0xB3, 0x01),
574 PLL_CTL(24000000, 0x5D,
575 0x53, 0x19, 0x03, 0x80, 0x01,
576 0x5B, 0x19, 0x05, 0x4C, 0x02),
577 PLL_CTL(24576000, 0x5F,
578 0x53, 0x1D, 0x03, 0xB3, 0x01,
579 0x62, 0x40, 0x03, 0x72, 0x03),
580 PLL_CTL(27000000, 0x68,
581 0x62, 0x4B, 0x03, 0x00, 0x04,
582 0x6A, 0x7D, 0x03, 0x20, 0x06),
583 PLL_CTL(36000000, 0x8C,
584 0x5B, 0x4B, 0x03, 0x00, 0x03,
585 0x6A, 0x7D, 0x03, 0x98, 0x04),
586 PLL_CTL(11289600, 0x2B,
587 0x6A, 0x31, 0x03, 0x40, 0x06,
588 0x5A, 0x12, 0x03, 0x1C, 0x02),
589 PLL_CTL(26000000, 0x65,
590 0x63, 0x41, 0x05, 0x00, 0x06,
591 0x5A, 0x26, 0x03, 0xEF, 0x01),
592 PLL_CTL(12288000, 0x2F,
593 0x5A, 0x12, 0x03, 0x1C, 0x02,
594 0x62, 0x20, 0x03, 0x72, 0x03),
595 PLL_CTL(40000000, 0x9B,
596 0xA2, 0x7D, 0x03, 0x80, 0x04,
597 0x63, 0x7D, 0x05, 0xE4, 0x06),
598 PLL_CTL(512000, 0x01,
599 0x62, 0x01, 0x03, 0xD0, 0x02,
600 0x5B, 0x01, 0x04, 0x72, 0x03),
601 PLL_CTL(705600, 0x02,
602 0x62, 0x02, 0x03, 0x15, 0x04,
603 0x62, 0x01, 0x04, 0x80, 0x02),
604 PLL_CTL(1024000, 0x03,
605 0x62, 0x02, 0x03, 0xD0, 0x02,
606 0x5B, 0x02, 0x04, 0x72, 0x03),
607 PLL_CTL(2048000, 0x07,
608 0x62, 0x04, 0x03, 0xD0, 0x02,
609 0x5B, 0x04, 0x04, 0x72, 0x03),
610 PLL_CTL(2400000, 0x08,
611 0x62, 0x05, 0x03, 0x00, 0x03,
612 0x63, 0x05, 0x05, 0x98, 0x04),
613};
614
615static inline const struct pll_ctl *get_pll_ctl(unsigned long freq_in)
616{
617 int i;
618 struct pll_ctl const *pll_ctl = NULL;
619
620 for (i = 0; i < ARRAY_SIZE(pll_ctls); ++i)
621 if (pll_ctls[i].freq_in == freq_in) {
622 pll_ctl = &pll_ctls[i];
623 break;
624 }
625
626 return pll_ctl;
627}
628
629enum {
630 PLL_INPUT_XTAL = 0,
631 PLL_INPUT_MCLK1,
632 PLL_INPUT_MCLK2,
633 PLL_INPUT_BCLK,
634};
635
636static int set_sysclk(struct snd_soc_component *component)
637{
638 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
639 struct pll_ctl const *pll_ctl;
640 unsigned long freq;
641 int i;
642 int ret;
643
644 if (tscs454->sysclk_src_id < PLL_INPUT_BCLK)
645 freq = clk_get_rate(tscs454->sysclk);
646 else
647 freq = tscs454->bclk_freq;
648 pll_ctl = get_pll_ctl(freq);
649 if (!pll_ctl) {
650 ret = -EINVAL;
651 dev_err(component->dev,
652 "Invalid PLL input %lu (%d)\n", freq, ret);
653 return ret;
654 }
655
656 for (i = 0; i < PLL_REG_SETTINGS_COUNT; ++i) {
657 ret = snd_soc_component_write(component,
658 pll_ctl->settings[i].addr,
659 pll_ctl->settings[i].val);
660 if (ret < 0) {
661 dev_err(component->dev,
662 "Failed to set pll setting (%d)\n",
663 ret);
664 return ret;
665 }
666 }
667
668 return 0;
669}
670
671static inline void reserve_pll(struct pll *pll)
672{
673 mutex_lock(&pll->lock);
674 pll->users++;
675 mutex_unlock(&pll->lock);
676}
677
678static inline void free_pll(struct pll *pll)
679{
680 mutex_lock(&pll->lock);
681 pll->users--;
682 mutex_unlock(&pll->lock);
683}
684
685static int pll_connected(struct snd_soc_dapm_widget *source,
686 struct snd_soc_dapm_widget *sink)
687{
688 struct snd_soc_component *component =
689 snd_soc_dapm_to_component(source->dapm);
690 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
691 int users;
692
693 if (strstr(source->name, "PLL 1")) {
694 mutex_lock(&tscs454->pll1.lock);
695 users = tscs454->pll1.users;
696 mutex_unlock(&tscs454->pll1.lock);
697 dev_dbg(component->dev, "%s(): PLL 1 users = %d\n", __func__,
698 users);
699 } else {
700 mutex_lock(&tscs454->pll2.lock);
701 users = tscs454->pll2.users;
702 mutex_unlock(&tscs454->pll2.lock);
703 dev_dbg(component->dev, "%s(): PLL 2 users = %d\n", __func__,
704 users);
705 }
706
707 return users;
708}
709
710/*
711 * PLL must be enabled after power up and must be disabled before power down
712 * for proper clock switching.
713 */
714static int pll_power_event(struct snd_soc_dapm_widget *w,
715 struct snd_kcontrol *kcontrol, int event)
716{
717 struct snd_soc_component *component =
718 snd_soc_dapm_to_component(w->dapm);
719 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
720 bool enable;
721 bool pll1;
722 unsigned int msk;
723 unsigned int val;
724 int ret;
725
726 if (strstr(w->name, "PLL 1"))
727 pll1 = true;
728 else
729 pll1 = false;
730
731 msk = pll1 ? FM_PLLCTL_PLL1CLKEN : FM_PLLCTL_PLL2CLKEN;
732
733 if (event == SND_SOC_DAPM_POST_PMU)
734 enable = true;
735 else
736 enable = false;
737
738 if (enable)
739 val = pll1 ? FV_PLL1CLKEN_ENABLE : FV_PLL2CLKEN_ENABLE;
740 else
741 val = pll1 ? FV_PLL1CLKEN_DISABLE : FV_PLL2CLKEN_DISABLE;
742
743 ret = snd_soc_component_update_bits(component, R_PLLCTL, msk, val);
744 if (ret < 0) {
745 dev_err(component->dev, "Failed to %s PLL %d (%d)\n",
746 enable ? "enable" : "disable",
747 pll1 ? 1 : 2,
748 ret);
749 return ret;
750 }
751
752 if (enable) {
753 msleep(20); // Wait for lock
754 ret = coeff_ram_sync(component, tscs454);
755 if (ret < 0) {
756 dev_err(component->dev,
757 "Failed to sync coeff ram (%d)\n", ret);
758 return ret;
759 }
760 }
761
762 return 0;
763}
764
765static inline int aif_set_master(struct snd_soc_component *component,
766 unsigned int aif_id, bool master)
767{
768 unsigned int reg;
769 unsigned int mask;
770 unsigned int val;
771 int ret;
772
773 switch (aif_id) {
774 case TSCS454_DAI1_ID:
775 reg = R_I2SP1CTL;
776 break;
777 case TSCS454_DAI2_ID:
778 reg = R_I2SP2CTL;
779 break;
780 case TSCS454_DAI3_ID:
781 reg = R_I2SP3CTL;
782 break;
783 default:
784 ret = -ENODEV;
785 dev_err(component->dev, "Unknown DAI %d (%d)\n", aif_id, ret);
786 return ret;
787 }
788 mask = FM_I2SPCTL_PORTMS;
789 val = master ? FV_PORTMS_MASTER : FV_PORTMS_SLAVE;
790
791 ret = snd_soc_component_update_bits(component, reg, mask, val);
792 if (ret < 0) {
793 dev_err(component->dev, "Failed to set DAI %d to %s (%d)\n",
794 aif_id, master ? "master" : "slave", ret);
795 return ret;
796 }
797
798 return 0;
799}
800
801static inline
802int aif_prepare(struct snd_soc_component *component, struct aif *aif)
803{
804 int ret;
805
806 ret = aif_set_master(component, aif->id, aif->master);
807 if (ret < 0)
808 return ret;
809
810 return 0;
811}
812
813static inline int aif_free(struct snd_soc_component *component,
814 struct aif *aif, bool playback)
815{
816 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
817
818 mutex_lock(&tscs454->aifs_status_lock);
819
820 dev_dbg(component->dev, "%s(): aif %d\n", __func__, aif->id);
821
822 set_aif_status_inactive(&tscs454->aifs_status, aif->id, playback);
823
824 dev_dbg(component->dev, "Set aif %d inactive. Streams status is 0x%x\n",
825 aif->id, tscs454->aifs_status.streams);
826
827 if (!aif_active(&tscs454->aifs_status, aif->id)) {
828 /* Do config in slave mode */
829 aif_set_master(component, aif->id, false);
830 dev_dbg(component->dev, "Freeing pll %d from aif %d\n",
831 aif->pll->id, aif->id);
832 free_pll(aif->pll);
833 }
834
835 if (!aifs_active(&tscs454->aifs_status)) {
836 dev_dbg(component->dev, "Freeing pll %d from ir\n",
837 tscs454->internal_rate.pll->id);
838 free_pll(tscs454->internal_rate.pll);
839 }
840
841 mutex_unlock(&tscs454->aifs_status_lock);
842
843 return 0;
844}
845
846/* R_PLLCTL PG 0 ADDR 0x15 */
847static char const * const bclk_sel_txt[] = {
848 "BCLK 1", "BCLK 2", "BCLK 3"};
849
850static struct soc_enum const bclk_sel_enum =
851 SOC_ENUM_SINGLE(R_PLLCTL, FB_PLLCTL_BCLKSEL,
852 ARRAY_SIZE(bclk_sel_txt), bclk_sel_txt);
853
854/* R_ISRC PG 0 ADDR 0x16 */
855static char const * const isrc_br_txt[] = {
856 "44.1kHz", "48kHz"};
857
858static struct soc_enum const isrc_br_enum =
859 SOC_ENUM_SINGLE(R_ISRC, FB_ISRC_IBR,
860 ARRAY_SIZE(isrc_br_txt), isrc_br_txt);
861
862static char const * const isrc_bm_txt[] = {
863 "0.25x", "0.5x", "1.0x", "2.0x"};
864
865static struct soc_enum const isrc_bm_enum =
866 SOC_ENUM_SINGLE(R_ISRC, FB_ISRC_IBM,
867 ARRAY_SIZE(isrc_bm_txt), isrc_bm_txt);
868
869/* R_SCLKCTL PG 0 ADDR 0x18 */
870static char const * const modular_rate_txt[] = {
871 "Reserved", "Half", "Full", "Auto",};
872
873static struct soc_enum const adc_modular_rate_enum =
874 SOC_ENUM_SINGLE(R_SCLKCTL, FB_SCLKCTL_ASDM,
875 ARRAY_SIZE(modular_rate_txt), modular_rate_txt);
876
877static struct soc_enum const dac_modular_rate_enum =
878 SOC_ENUM_SINGLE(R_SCLKCTL, FB_SCLKCTL_DSDM,
879 ARRAY_SIZE(modular_rate_txt), modular_rate_txt);
880
881/* R_I2SIDCTL PG 0 ADDR 0x38 */
882static char const * const data_ctrl_txt[] = {
883 "L/R", "L/L", "R/R", "R/L"};
884
885static struct soc_enum const data_in_ctrl_enums[] = {
886 SOC_ENUM_SINGLE(R_I2SIDCTL, FB_I2SIDCTL_I2SI1DCTL,
887 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
888 SOC_ENUM_SINGLE(R_I2SIDCTL, FB_I2SIDCTL_I2SI2DCTL,
889 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
890 SOC_ENUM_SINGLE(R_I2SIDCTL, FB_I2SIDCTL_I2SI3DCTL,
891 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
892};
893
894/* R_I2SODCTL PG 0 ADDR 0x39 */
895static struct soc_enum const data_out_ctrl_enums[] = {
896 SOC_ENUM_SINGLE(R_I2SODCTL, FB_I2SODCTL_I2SO1DCTL,
897 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
898 SOC_ENUM_SINGLE(R_I2SODCTL, FB_I2SODCTL_I2SO2DCTL,
899 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
900 SOC_ENUM_SINGLE(R_I2SODCTL, FB_I2SODCTL_I2SO3DCTL,
901 ARRAY_SIZE(data_ctrl_txt), data_ctrl_txt),
902};
903
904/* R_AUDIOMUX1 PG 0 ADDR 0x3A */
905static char const * const asrc_mux_txt[] = {
906 "None", "DAI 1", "DAI 2", "DAI 3"};
907
908static struct soc_enum const asrc_in_mux_enum =
909 SOC_ENUM_SINGLE(R_AUDIOMUX1, FB_AUDIOMUX1_ASRCIMUX,
910 ARRAY_SIZE(asrc_mux_txt), asrc_mux_txt);
911
912static char const * const dai_mux_txt[] = {
913 "CH 0_1", "CH 2_3", "CH 4_5", "ADC/DMic 1",
914 "DMic 2", "ClassD", "DAC", "Sub"};
915
916static struct soc_enum const dai2_mux_enum =
917 SOC_ENUM_SINGLE(R_AUDIOMUX1, FB_AUDIOMUX1_I2S2MUX,
918 ARRAY_SIZE(dai_mux_txt), dai_mux_txt);
919
920static struct snd_kcontrol_new const dai2_mux_dapm_enum =
921 SOC_DAPM_ENUM("DAI 2 Mux", dai2_mux_enum);
922
923static struct soc_enum const dai1_mux_enum =
924 SOC_ENUM_SINGLE(R_AUDIOMUX1, FB_AUDIOMUX1_I2S1MUX,
925 ARRAY_SIZE(dai_mux_txt), dai_mux_txt);
926
927static struct snd_kcontrol_new const dai1_mux_dapm_enum =
928 SOC_DAPM_ENUM("DAI 1 Mux", dai1_mux_enum);
929
930/* R_AUDIOMUX2 PG 0 ADDR 0x3B */
931static struct soc_enum const asrc_out_mux_enum =
932 SOC_ENUM_SINGLE(R_AUDIOMUX2, FB_AUDIOMUX2_ASRCOMUX,
933 ARRAY_SIZE(asrc_mux_txt), asrc_mux_txt);
934
935static struct soc_enum const dac_mux_enum =
936 SOC_ENUM_SINGLE(R_AUDIOMUX2, FB_AUDIOMUX2_DACMUX,
937 ARRAY_SIZE(dai_mux_txt), dai_mux_txt);
938
939static struct snd_kcontrol_new const dac_mux_dapm_enum =
940 SOC_DAPM_ENUM("DAC Mux", dac_mux_enum);
941
942static struct soc_enum const dai3_mux_enum =
943 SOC_ENUM_SINGLE(R_AUDIOMUX2, FB_AUDIOMUX2_I2S3MUX,
944 ARRAY_SIZE(dai_mux_txt), dai_mux_txt);
945
946static struct snd_kcontrol_new const dai3_mux_dapm_enum =
947 SOC_DAPM_ENUM("DAI 3 Mux", dai3_mux_enum);
948
949/* R_AUDIOMUX3 PG 0 ADDR 0x3C */
950static char const * const sub_mux_txt[] = {
951 "CH 0", "CH 1", "CH 0 + 1",
952 "CH 2", "CH 3", "CH 2 + 3",
953 "CH 4", "CH 5", "CH 4 + 5",
954 "ADC/DMic 1 Left", "ADC/DMic 1 Right",
955 "ADC/DMic 1 Left Plus Right",
956 "DMic 2 Left", "DMic 2 Right", "DMic 2 Left Plus Right",
957 "ClassD Left", "ClassD Right", "ClassD Left Plus Right"};
958
959static struct soc_enum const sub_mux_enum =
960 SOC_ENUM_SINGLE(R_AUDIOMUX3, FB_AUDIOMUX3_SUBMUX,
961 ARRAY_SIZE(sub_mux_txt), sub_mux_txt);
962
963static struct snd_kcontrol_new const sub_mux_dapm_enum =
964 SOC_DAPM_ENUM("Sub Mux", sub_mux_enum);
965
966static struct soc_enum const classd_mux_enum =
967 SOC_ENUM_SINGLE(R_AUDIOMUX3, FB_AUDIOMUX3_CLSSDMUX,
968 ARRAY_SIZE(dai_mux_txt), dai_mux_txt);
969
970static struct snd_kcontrol_new const classd_mux_dapm_enum =
971 SOC_DAPM_ENUM("ClassD Mux", classd_mux_enum);
972
973/* R_HSDCTL1 PG 1 ADDR 0x01 */
974static char const * const jack_type_txt[] = {
975 "3 Terminal", "4 Terminal"};
976
977static struct soc_enum const hp_jack_type_enum =
978 SOC_ENUM_SINGLE(R_HSDCTL1, FB_HSDCTL1_HPJKTYPE,
979 ARRAY_SIZE(jack_type_txt), jack_type_txt);
980
981static char const * const hs_det_pol_txt[] = {
982 "Rising", "Falling"};
983
984static struct soc_enum const hs_det_pol_enum =
985 SOC_ENUM_SINGLE(R_HSDCTL1, FB_HSDCTL1_HSDETPOL,
986 ARRAY_SIZE(hs_det_pol_txt), hs_det_pol_txt);
987
988/* R_HSDCTL1 PG 1 ADDR 0x02 */
989static char const * const hs_mic_bias_force_txt[] = {
990 "Off", "Ring", "Sleeve"};
991
992static struct soc_enum const hs_mic_bias_force_enum =
993 SOC_ENUM_SINGLE(R_HSDCTL2, FB_HSDCTL2_FMICBIAS1,
994 ARRAY_SIZE(hs_mic_bias_force_txt),
995 hs_mic_bias_force_txt);
996
997static char const * const plug_type_txt[] = {
998 "OMTP", "CTIA", "Reserved", "Headphone"};
999
1000static struct soc_enum const plug_type_force_enum =
1001 SOC_ENUM_SINGLE(R_HSDCTL2, FB_HSDCTL2_FPLUGTYPE,
1002 ARRAY_SIZE(plug_type_txt), plug_type_txt);
1003
1004
1005/* R_CH0AIC PG 1 ADDR 0x06 */
1006static char const * const in_bst_mux_txt[] = {
1007 "Input 1", "Input 2", "Input 3", "D2S"};
1008
1009static struct soc_enum const in_bst_mux_ch0_enum =
1010 SOC_ENUM_SINGLE(R_CH0AIC, FB_CH0AIC_INSELL,
1011 ARRAY_SIZE(in_bst_mux_txt),
1012 in_bst_mux_txt);
1013static struct snd_kcontrol_new const in_bst_mux_ch0_dapm_enum =
1014 SOC_DAPM_ENUM("Input Boost Channel 0 Enum",
1015 in_bst_mux_ch0_enum);
1016
1017static DECLARE_TLV_DB_SCALE(in_bst_vol_tlv_arr, 0, 1000, 0);
1018
1019static char const * const adc_mux_txt[] = {
1020 "Input 1 Boost Bypass", "Input 2 Boost Bypass",
1021 "Input 3 Boost Bypass", "Input Boost"};
1022
1023static struct soc_enum const adc_mux_ch0_enum =
1024 SOC_ENUM_SINGLE(R_CH0AIC, FB_CH0AIC_LADCIN,
1025 ARRAY_SIZE(adc_mux_txt), adc_mux_txt);
1026static struct snd_kcontrol_new const adc_mux_ch0_dapm_enum =
1027 SOC_DAPM_ENUM("ADC Channel 0 Enum", adc_mux_ch0_enum);
1028
1029static char const * const in_proc_mux_txt[] = {
1030 "ADC", "DMic"};
1031
1032static struct soc_enum const in_proc_ch0_enum =
1033 SOC_ENUM_SINGLE(R_CH0AIC, FB_CH0AIC_IPCH0S,
1034 ARRAY_SIZE(in_proc_mux_txt), in_proc_mux_txt);
1035static struct snd_kcontrol_new const in_proc_mux_ch0_dapm_enum =
1036 SOC_DAPM_ENUM("Input Processor Channel 0 Enum",
1037 in_proc_ch0_enum);
1038
1039/* R_CH1AIC PG 1 ADDR 0x07 */
1040static struct soc_enum const in_bst_mux_ch1_enum =
1041 SOC_ENUM_SINGLE(R_CH1AIC, FB_CH1AIC_INSELR,
1042 ARRAY_SIZE(in_bst_mux_txt),
1043 in_bst_mux_txt);
1044static struct snd_kcontrol_new const in_bst_mux_ch1_dapm_enum =
1045 SOC_DAPM_ENUM("Input Boost Channel 1 Enum",
1046 in_bst_mux_ch1_enum);
1047
1048static struct soc_enum const adc_mux_ch1_enum =
1049 SOC_ENUM_SINGLE(R_CH1AIC, FB_CH1AIC_RADCIN,
1050 ARRAY_SIZE(adc_mux_txt), adc_mux_txt);
1051static struct snd_kcontrol_new const adc_mux_ch1_dapm_enum =
1052 SOC_DAPM_ENUM("ADC Channel 1 Enum", adc_mux_ch1_enum);
1053
1054static struct soc_enum const in_proc_ch1_enum =
1055 SOC_ENUM_SINGLE(R_CH1AIC, FB_CH1AIC_IPCH1S,
1056 ARRAY_SIZE(in_proc_mux_txt), in_proc_mux_txt);
1057static struct snd_kcontrol_new const in_proc_mux_ch1_dapm_enum =
1058 SOC_DAPM_ENUM("Input Processor Channel 1 Enum",
1059 in_proc_ch1_enum);
1060
1061/* R_ICTL0 PG 1 ADDR 0x0A */
1062static char const * const pol_txt[] = {
1063 "Normal", "Invert"};
1064
1065static struct soc_enum const in_pol_ch1_enum =
1066 SOC_ENUM_SINGLE(R_ICTL0, FB_ICTL0_IN0POL,
1067 ARRAY_SIZE(pol_txt), pol_txt);
1068
1069static struct soc_enum const in_pol_ch0_enum =
1070 SOC_ENUM_SINGLE(R_ICTL0, FB_ICTL0_IN1POL,
1071 ARRAY_SIZE(pol_txt), pol_txt);
1072
1073static char const * const in_proc_ch_sel_txt[] = {
1074 "Normal", "Mono Mix to Channel 0",
1075 "Mono Mix to Channel 1", "Add"};
1076
1077static struct soc_enum const in_proc_ch01_sel_enum =
1078 SOC_ENUM_SINGLE(R_ICTL0, FB_ICTL0_INPCH10SEL,
1079 ARRAY_SIZE(in_proc_ch_sel_txt),
1080 in_proc_ch_sel_txt);
1081
1082/* R_ICTL1 PG 1 ADDR 0x0B */
1083static struct soc_enum const in_pol_ch3_enum =
1084 SOC_ENUM_SINGLE(R_ICTL1, FB_ICTL1_IN2POL,
1085 ARRAY_SIZE(pol_txt), pol_txt);
1086
1087static struct soc_enum const in_pol_ch2_enum =
1088 SOC_ENUM_SINGLE(R_ICTL1, FB_ICTL1_IN3POL,
1089 ARRAY_SIZE(pol_txt), pol_txt);
1090
1091static struct soc_enum const in_proc_ch23_sel_enum =
1092 SOC_ENUM_SINGLE(R_ICTL1, FB_ICTL1_INPCH32SEL,
1093 ARRAY_SIZE(in_proc_ch_sel_txt),
1094 in_proc_ch_sel_txt);
1095
1096/* R_MICBIAS PG 1 ADDR 0x0C */
1097static char const * const mic_bias_txt[] = {
1098 "2.5V", "2.1V", "1.8V", "Vdd"};
1099
1100static struct soc_enum const mic_bias_2_enum =
1101 SOC_ENUM_SINGLE(R_MICBIAS, FB_MICBIAS_MICBOV2,
1102 ARRAY_SIZE(mic_bias_txt), mic_bias_txt);
1103
1104static struct soc_enum const mic_bias_1_enum =
1105 SOC_ENUM_SINGLE(R_MICBIAS, FB_MICBIAS_MICBOV1,
1106 ARRAY_SIZE(mic_bias_txt), mic_bias_txt);
1107
1108/* R_PGACTL0 PG 1 ADDR 0x0D */
1109/* R_PGACTL1 PG 1 ADDR 0x0E */
1110/* R_PGACTL2 PG 1 ADDR 0x0F */
1111/* R_PGACTL3 PG 1 ADDR 0x10 */
1112static DECLARE_TLV_DB_SCALE(in_pga_vol_tlv_arr, -1725, 75, 0);
1113
1114/* R_ICH0VOL PG1 ADDR 0x12 */
1115/* R_ICH1VOL PG1 ADDR 0x13 */
1116/* R_ICH2VOL PG1 ADDR 0x14 */
1117/* R_ICH3VOL PG1 ADDR 0x15 */
1118static DECLARE_TLV_DB_MINMAX(in_vol_tlv_arr, -7125, 2400);
1119
1120/* R_ASRCILVOL PG1 ADDR 0x16 */
1121/* R_ASRCIRVOL PG1 ADDR 0x17 */
1122/* R_ASRCOLVOL PG1 ADDR 0x18 */
1123/* R_ASRCORVOL PG1 ADDR 0x19 */
1124static DECLARE_TLV_DB_MINMAX(asrc_vol_tlv_arr, -9562, 600);
1125
1126/* R_ALCCTL0 PG1 ADDR 0x1D */
1127static char const * const alc_mode_txt[] = {
1128 "ALC", "Limiter"};
1129
1130static struct soc_enum const alc_mode_enum =
1131 SOC_ENUM_SINGLE(R_ALCCTL0, FB_ALCCTL0_ALCMODE,
1132 ARRAY_SIZE(alc_mode_txt), alc_mode_txt);
1133
1134static char const * const alc_ref_text[] = {
1135 "Channel 0", "Channel 1", "Channel 2", "Channel 3", "Peak"};
1136
1137static struct soc_enum const alc_ref_enum =
1138 SOC_ENUM_SINGLE(R_ALCCTL0, FB_ALCCTL0_ALCREF,
1139 ARRAY_SIZE(alc_ref_text), alc_ref_text);
1140
1141/* R_ALCCTL1 PG 1 ADDR 0x1E */
1142static DECLARE_TLV_DB_SCALE(alc_max_gain_tlv_arr, -1200, 600, 0);
1143static DECLARE_TLV_DB_SCALE(alc_target_tlv_arr, -2850, 150, 0);
1144
1145/* R_ALCCTL2 PG 1 ADDR 0x1F */
1146static DECLARE_TLV_DB_SCALE(alc_min_gain_tlv_arr, -1725, 600, 0);
1147
1148/* R_NGATE PG 1 ADDR 0x21 */
1149static DECLARE_TLV_DB_SCALE(ngth_tlv_arr, -7650, 150, 0);
1150
1151static char const * const ngate_type_txt[] = {
1152 "PGA Constant", "ADC Mute"};
1153
1154static struct soc_enum const ngate_type_enum =
1155 SOC_ENUM_SINGLE(R_NGATE, FB_NGATE_NGG,
1156 ARRAY_SIZE(ngate_type_txt), ngate_type_txt);
1157
1158/* R_DMICCTL PG 1 ADDR 0x22 */
1159static char const * const dmic_mono_sel_txt[] = {
1160 "Stereo", "Mono"};
1161
1162static struct soc_enum const dmic_mono_sel_enum =
1163 SOC_ENUM_SINGLE(R_DMICCTL, FB_DMICCTL_DMONO,
1164 ARRAY_SIZE(dmic_mono_sel_txt), dmic_mono_sel_txt);
1165
1166/* R_DACCTL PG 2 ADDR 0x01 */
1167static struct soc_enum const dac_pol_r_enum =
1168 SOC_ENUM_SINGLE(R_DACCTL, FB_DACCTL_DACPOLR,
1169 ARRAY_SIZE(pol_txt), pol_txt);
1170
1171static struct soc_enum const dac_pol_l_enum =
1172 SOC_ENUM_SINGLE(R_DACCTL, FB_DACCTL_DACPOLL,
1173 ARRAY_SIZE(pol_txt), pol_txt);
1174
1175static char const * const dac_dith_txt[] = {
1176 "Half", "Full", "Disabled", "Static"};
1177
1178static struct soc_enum const dac_dith_enum =
1179 SOC_ENUM_SINGLE(R_DACCTL, FB_DACCTL_DACDITH,
1180 ARRAY_SIZE(dac_dith_txt), dac_dith_txt);
1181
1182/* R_SPKCTL PG 2 ADDR 0x02 */
1183static struct soc_enum const spk_pol_r_enum =
1184 SOC_ENUM_SINGLE(R_SPKCTL, FB_SPKCTL_SPKPOLR,
1185 ARRAY_SIZE(pol_txt), pol_txt);
1186
1187static struct soc_enum const spk_pol_l_enum =
1188 SOC_ENUM_SINGLE(R_SPKCTL, FB_SPKCTL_SPKPOLL,
1189 ARRAY_SIZE(pol_txt), pol_txt);
1190
1191/* R_SUBCTL PG 2 ADDR 0x03 */
1192static struct soc_enum const sub_pol_enum =
1193 SOC_ENUM_SINGLE(R_SUBCTL, FB_SUBCTL_SUBPOL,
1194 ARRAY_SIZE(pol_txt), pol_txt);
1195
1196/* R_MVOLL PG 2 ADDR 0x08 */
1197/* R_MVOLR PG 2 ADDR 0x09 */
1198static DECLARE_TLV_DB_MINMAX(mvol_tlv_arr, -9562, 0);
1199
1200/* R_HPVOLL PG 2 ADDR 0x0A */
1201/* R_HPVOLR PG 2 ADDR 0x0B */
1202static DECLARE_TLV_DB_SCALE(hp_vol_tlv_arr, -8850, 75, 0);
1203
1204/* R_SPKVOLL PG 2 ADDR 0x0C */
1205/* R_SPKVOLR PG 2 ADDR 0x0D */
1206static DECLARE_TLV_DB_SCALE(spk_vol_tlv_arr, -7725, 75, 0);
1207
1208/* R_SPKEQFILT PG 3 ADDR 0x01 */
1209static char const * const eq_txt[] = {
1210 "Pre Scale",
1211 "Pre Scale + EQ Band 0",
1212 "Pre Scale + EQ Band 0 - 1",
1213 "Pre Scale + EQ Band 0 - 2",
1214 "Pre Scale + EQ Band 0 - 3",
1215 "Pre Scale + EQ Band 0 - 4",
1216 "Pre Scale + EQ Band 0 - 5",
1217};
1218
1219static struct soc_enum const spk_eq_enums[] = {
1220 SOC_ENUM_SINGLE(R_SPKEQFILT, FB_SPKEQFILT_EQ2BE,
1221 ARRAY_SIZE(eq_txt), eq_txt),
1222 SOC_ENUM_SINGLE(R_SPKEQFILT, FB_SPKEQFILT_EQ1BE,
1223 ARRAY_SIZE(eq_txt), eq_txt),
1224};
1225
1226/* R_SPKMBCCTL PG 3 ADDR 0x0B */
1227static char const * const lvl_mode_txt[] = {
1228 "Average", "Peak"};
1229
1230static struct soc_enum const spk_mbc3_lvl_det_mode_enum =
1231 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_LVLMODE3,
1232 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1233
1234static char const * const win_sel_txt[] = {
1235 "512", "64"};
1236
1237static struct soc_enum const spk_mbc3_win_sel_enum =
1238 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_WINSEL3,
1239 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1240
1241static struct soc_enum const spk_mbc2_lvl_det_mode_enum =
1242 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_LVLMODE2,
1243 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1244
1245static struct soc_enum const spk_mbc2_win_sel_enum =
1246 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_WINSEL2,
1247 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1248
1249static struct soc_enum const spk_mbc1_lvl_det_mode_enum =
1250 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_LVLMODE1,
1251 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1252
1253static struct soc_enum const spk_mbc1_win_sel_enum =
1254 SOC_ENUM_SINGLE(R_SPKMBCCTL, FB_SPKMBCCTL_WINSEL1,
1255 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1256
1257/* R_SPKMBCMUG1 PG 3 ADDR 0x0C */
1258static struct soc_enum const spk_mbc1_phase_pol_enum =
1259 SOC_ENUM_SINGLE(R_SPKMBCMUG1, FB_SPKMBCMUG_PHASE,
1260 ARRAY_SIZE(pol_txt), pol_txt);
1261
1262static DECLARE_TLV_DB_MINMAX(mbc_mug_tlv_arr, -4650, 0);
1263
1264/* R_SPKMBCTHR1 PG 3 ADDR 0x0D */
1265static DECLARE_TLV_DB_MINMAX(thr_tlv_arr, -9562, 0);
1266
1267/* R_SPKMBCRAT1 PG 3 ADDR 0x0E */
1268static char const * const comp_rat_txt[] = {
1269 "Reserved", "1.5:1", "2:1", "3:1", "4:1", "5:1", "6:1",
1270 "7:1", "8:1", "9:1", "10:1", "11:1", "12:1", "13:1", "14:1",
1271 "15:1", "16:1", "17:1", "18:1", "19:1", "20:1"};
1272
1273static struct soc_enum const spk_mbc1_comp_rat_enum =
1274 SOC_ENUM_SINGLE(R_SPKMBCRAT1, FB_SPKMBCRAT_RATIO,
1275 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1276
1277/* R_SPKMBCMUG2 PG 3 ADDR 0x13 */
1278static struct soc_enum const spk_mbc2_phase_pol_enum =
1279 SOC_ENUM_SINGLE(R_SPKMBCMUG2, FB_SPKMBCMUG_PHASE,
1280 ARRAY_SIZE(pol_txt), pol_txt);
1281
1282/* R_SPKMBCRAT2 PG 3 ADDR 0x15 */
1283static struct soc_enum const spk_mbc2_comp_rat_enum =
1284 SOC_ENUM_SINGLE(R_SPKMBCRAT2, FB_SPKMBCRAT_RATIO,
1285 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1286
1287/* R_SPKMBCMUG3 PG 3 ADDR 0x1A */
1288static struct soc_enum const spk_mbc3_phase_pol_enum =
1289 SOC_ENUM_SINGLE(R_SPKMBCMUG3, FB_SPKMBCMUG_PHASE,
1290 ARRAY_SIZE(pol_txt), pol_txt);
1291
1292/* R_SPKMBCRAT3 PG 3 ADDR 0x1C */
1293static struct soc_enum const spk_mbc3_comp_rat_enum =
1294 SOC_ENUM_SINGLE(R_SPKMBCRAT3, FB_SPKMBCRAT_RATIO,
1295 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1296
1297/* R_SPKCLECTL PG 3 ADDR 0x21 */
1298static struct soc_enum const spk_cle_lvl_mode_enum =
1299 SOC_ENUM_SINGLE(R_SPKCLECTL, FB_SPKCLECTL_LVLMODE,
1300 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1301
1302static struct soc_enum const spk_cle_win_sel_enum =
1303 SOC_ENUM_SINGLE(R_SPKCLECTL, FB_SPKCLECTL_WINSEL,
1304 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1305
1306/* R_SPKCLEMUG PG 3 ADDR 0x22 */
1307static DECLARE_TLV_DB_MINMAX(cle_mug_tlv_arr, 0, 4650);
1308
1309/* R_SPKCOMPRAT PG 3 ADDR 0x24 */
1310static struct soc_enum const spk_comp_rat_enum =
1311 SOC_ENUM_SINGLE(R_SPKCOMPRAT, FB_SPKCOMPRAT_RATIO,
1312 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1313
1314/* R_SPKEXPTHR PG 3 ADDR 0x2F */
1315static char const * const exp_rat_txt[] = {
1316 "Reserved", "Reserved", "1:2", "1:3",
1317 "1:4", "1:5", "1:6", "1:7"};
1318
1319static struct soc_enum const spk_exp_rat_enum =
1320 SOC_ENUM_SINGLE(R_SPKEXPRAT, FB_SPKEXPRAT_RATIO,
1321 ARRAY_SIZE(exp_rat_txt), exp_rat_txt);
1322
1323/* R_DACEQFILT PG 4 ADDR 0x01 */
1324static struct soc_enum const dac_eq_enums[] = {
1325 SOC_ENUM_SINGLE(R_DACEQFILT, FB_DACEQFILT_EQ2BE,
1326 ARRAY_SIZE(eq_txt), eq_txt),
1327 SOC_ENUM_SINGLE(R_DACEQFILT, FB_DACEQFILT_EQ1BE,
1328 ARRAY_SIZE(eq_txt), eq_txt),
1329};
1330
1331/* R_DACMBCCTL PG 4 ADDR 0x0B */
1332static struct soc_enum const dac_mbc3_lvl_det_mode_enum =
1333 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE3,
1334 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1335
1336static struct soc_enum const dac_mbc3_win_sel_enum =
1337 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL3,
1338 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1339
1340static struct soc_enum const dac_mbc2_lvl_det_mode_enum =
1341 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE2,
1342 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1343
1344static struct soc_enum const dac_mbc2_win_sel_enum =
1345 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL2,
1346 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1347
1348static struct soc_enum const dac_mbc1_lvl_det_mode_enum =
1349 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE1,
1350 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1351
1352static struct soc_enum const dac_mbc1_win_sel_enum =
1353 SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL1,
1354 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1355
1356/* R_DACMBCMUG1 PG 4 ADDR 0x0C */
1357static struct soc_enum const dac_mbc1_phase_pol_enum =
1358 SOC_ENUM_SINGLE(R_DACMBCMUG1, FB_DACMBCMUG_PHASE,
1359 ARRAY_SIZE(pol_txt), pol_txt);
1360
1361/* R_DACMBCRAT1 PG 4 ADDR 0x0E */
1362static struct soc_enum const dac_mbc1_comp_rat_enum =
1363 SOC_ENUM_SINGLE(R_DACMBCRAT1, FB_DACMBCRAT_RATIO,
1364 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1365
1366/* R_DACMBCMUG2 PG 4 ADDR 0x13 */
1367static struct soc_enum const dac_mbc2_phase_pol_enum =
1368 SOC_ENUM_SINGLE(R_DACMBCMUG2, FB_DACMBCMUG_PHASE,
1369 ARRAY_SIZE(pol_txt), pol_txt);
1370
1371/* R_DACMBCRAT2 PG 4 ADDR 0x15 */
1372static struct soc_enum const dac_mbc2_comp_rat_enum =
1373 SOC_ENUM_SINGLE(R_DACMBCRAT2, FB_DACMBCRAT_RATIO,
1374 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1375
1376/* R_DACMBCMUG3 PG 4 ADDR 0x1A */
1377static struct soc_enum const dac_mbc3_phase_pol_enum =
1378 SOC_ENUM_SINGLE(R_DACMBCMUG3, FB_DACMBCMUG_PHASE,
1379 ARRAY_SIZE(pol_txt), pol_txt);
1380
1381/* R_DACMBCRAT3 PG 4 ADDR 0x1C */
1382static struct soc_enum const dac_mbc3_comp_rat_enum =
1383 SOC_ENUM_SINGLE(R_DACMBCRAT3, FB_DACMBCRAT_RATIO,
1384 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1385
1386/* R_DACCLECTL PG 4 ADDR 0x21 */
1387static struct soc_enum const dac_cle_lvl_mode_enum =
1388 SOC_ENUM_SINGLE(R_DACCLECTL, FB_DACCLECTL_LVLMODE,
1389 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1390
1391static struct soc_enum const dac_cle_win_sel_enum =
1392 SOC_ENUM_SINGLE(R_DACCLECTL, FB_DACCLECTL_WINSEL,
1393 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1394
1395/* R_DACCOMPRAT PG 4 ADDR 0x24 */
1396static struct soc_enum const dac_comp_rat_enum =
1397 SOC_ENUM_SINGLE(R_DACCOMPRAT, FB_DACCOMPRAT_RATIO,
1398 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1399
1400/* R_DACEXPRAT PG 4 ADDR 0x30 */
1401static struct soc_enum const dac_exp_rat_enum =
1402 SOC_ENUM_SINGLE(R_DACEXPRAT, FB_DACEXPRAT_RATIO,
1403 ARRAY_SIZE(exp_rat_txt), exp_rat_txt);
1404
1405/* R_SUBEQFILT PG 5 ADDR 0x01 */
1406static struct soc_enum const sub_eq_enums[] = {
1407 SOC_ENUM_SINGLE(R_SUBEQFILT, FB_SUBEQFILT_EQ2BE,
1408 ARRAY_SIZE(eq_txt), eq_txt),
1409 SOC_ENUM_SINGLE(R_SUBEQFILT, FB_SUBEQFILT_EQ1BE,
1410 ARRAY_SIZE(eq_txt), eq_txt),
1411};
1412
1413/* R_SUBMBCCTL PG 5 ADDR 0x0B */
1414static struct soc_enum const sub_mbc3_lvl_det_mode_enum =
1415 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_LVLMODE3,
1416 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1417
1418static struct soc_enum const sub_mbc3_win_sel_enum =
1419 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_WINSEL3,
1420 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1421
1422static struct soc_enum const sub_mbc2_lvl_det_mode_enum =
1423 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_LVLMODE2,
1424 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1425
1426static struct soc_enum const sub_mbc2_win_sel_enum =
1427 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_WINSEL2,
1428 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1429
1430static struct soc_enum const sub_mbc1_lvl_det_mode_enum =
1431 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_LVLMODE1,
1432 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1433
1434static struct soc_enum const sub_mbc1_win_sel_enum =
1435 SOC_ENUM_SINGLE(R_SUBMBCCTL, FB_SUBMBCCTL_WINSEL1,
1436 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1437
1438/* R_SUBMBCMUG1 PG 5 ADDR 0x0C */
1439static struct soc_enum const sub_mbc1_phase_pol_enum =
1440 SOC_ENUM_SINGLE(R_SUBMBCMUG1, FB_SUBMBCMUG_PHASE,
1441 ARRAY_SIZE(pol_txt), pol_txt);
1442
1443/* R_SUBMBCRAT1 PG 5 ADDR 0x0E */
1444static struct soc_enum const sub_mbc1_comp_rat_enum =
1445 SOC_ENUM_SINGLE(R_SUBMBCRAT1, FB_SUBMBCRAT_RATIO,
1446 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1447
1448/* R_SUBMBCMUG2 PG 5 ADDR 0x13 */
1449static struct soc_enum const sub_mbc2_phase_pol_enum =
1450 SOC_ENUM_SINGLE(R_SUBMBCMUG2, FB_SUBMBCMUG_PHASE,
1451 ARRAY_SIZE(pol_txt), pol_txt);
1452
1453/* R_SUBMBCRAT2 PG 5 ADDR 0x15 */
1454static struct soc_enum const sub_mbc2_comp_rat_enum =
1455 SOC_ENUM_SINGLE(R_SUBMBCRAT2, FB_SUBMBCRAT_RATIO,
1456 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1457
1458/* R_SUBMBCMUG3 PG 5 ADDR 0x1A */
1459static struct soc_enum const sub_mbc3_phase_pol_enum =
1460 SOC_ENUM_SINGLE(R_SUBMBCMUG3, FB_SUBMBCMUG_PHASE,
1461 ARRAY_SIZE(pol_txt), pol_txt);
1462
1463/* R_SUBMBCRAT3 PG 5 ADDR 0x1C */
1464static struct soc_enum const sub_mbc3_comp_rat_enum =
1465 SOC_ENUM_SINGLE(R_SUBMBCRAT3, FB_SUBMBCRAT_RATIO,
1466 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1467
1468/* R_SUBCLECTL PG 5 ADDR 0x21 */
1469static struct soc_enum const sub_cle_lvl_mode_enum =
1470 SOC_ENUM_SINGLE(R_SUBCLECTL, FB_SUBCLECTL_LVLMODE,
1471 ARRAY_SIZE(lvl_mode_txt), lvl_mode_txt);
1472static struct soc_enum const sub_cle_win_sel_enum =
1473 SOC_ENUM_SINGLE(R_SUBCLECTL, FB_SUBCLECTL_WINSEL,
1474 ARRAY_SIZE(win_sel_txt), win_sel_txt);
1475
1476/* R_SUBCOMPRAT PG 5 ADDR 0x24 */
1477static struct soc_enum const sub_comp_rat_enum =
1478 SOC_ENUM_SINGLE(R_SUBCOMPRAT, FB_SUBCOMPRAT_RATIO,
1479 ARRAY_SIZE(comp_rat_txt), comp_rat_txt);
1480
1481/* R_SUBEXPRAT PG 5 ADDR 0x30 */
1482static struct soc_enum const sub_exp_rat_enum =
1483 SOC_ENUM_SINGLE(R_SUBEXPRAT, FB_SUBEXPRAT_RATIO,
1484 ARRAY_SIZE(exp_rat_txt), exp_rat_txt);
1485
1486static int bytes_info_ext(struct snd_kcontrol *kcontrol,
1487 struct snd_ctl_elem_info *ucontrol)
1488{
1489 struct coeff_ram_ctl *ctl =
1490 (struct coeff_ram_ctl *)kcontrol->private_value;
1491 struct soc_bytes_ext *params = &ctl->bytes_ext;
1492
1493 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1494 ucontrol->count = params->max;
1495
1496 return 0;
1497}
1498
1499/* CH 0_1 Input Mux */
1500static char const * const ch_0_1_mux_txt[] = {"DAI 1", "TDM 0_1"};
1501
1502static struct soc_enum const ch_0_1_mux_enum =
1503 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
1504 ARRAY_SIZE(ch_0_1_mux_txt), ch_0_1_mux_txt);
1505
1506static struct snd_kcontrol_new const ch_0_1_mux_dapm_enum =
1507 SOC_DAPM_ENUM("CH 0_1 Input Mux", ch_0_1_mux_enum);
1508
1509/* CH 2_3 Input Mux */
1510static char const * const ch_2_3_mux_txt[] = {"DAI 2", "TDM 2_3"};
1511
1512static struct soc_enum const ch_2_3_mux_enum =
1513 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
1514 ARRAY_SIZE(ch_2_3_mux_txt), ch_2_3_mux_txt);
1515
1516static struct snd_kcontrol_new const ch_2_3_mux_dapm_enum =
1517 SOC_DAPM_ENUM("CH 2_3 Input Mux", ch_2_3_mux_enum);
1518
1519/* CH 4_5 Input Mux */
1520static char const * const ch_4_5_mux_txt[] = {"DAI 3", "TDM 4_5"};
1521
1522static struct soc_enum const ch_4_5_mux_enum =
1523 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
1524 ARRAY_SIZE(ch_4_5_mux_txt), ch_4_5_mux_txt);
1525
1526static struct snd_kcontrol_new const ch_4_5_mux_dapm_enum =
1527 SOC_DAPM_ENUM("CH 4_5 Input Mux", ch_4_5_mux_enum);
1528
1529#define COEFF_RAM_CTL(xname, xcount, xaddr) \
1530{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1531 .info = bytes_info_ext, \
1532 .get = coeff_ram_get, .put = coeff_ram_put, \
1533 .private_value = (unsigned long)&(struct coeff_ram_ctl) { \
1534 .addr = xaddr, \
1535 .bytes_ext = {.max = xcount, }, \
1536 } \
1537}
1538
1539static struct snd_kcontrol_new const tscs454_snd_controls[] = {
1540 /* R_PLLCTL PG 0 ADDR 0x15 */
1541 SOC_ENUM("PLL BCLK Input", bclk_sel_enum),
1542 /* R_ISRC PG 0 ADDR 0x16 */
1543 SOC_ENUM("Internal Rate", isrc_br_enum),
1544 SOC_ENUM("Internal Rate Multiple", isrc_bm_enum),
1545 /* R_SCLKCTL PG 0 ADDR 0x18 */
1546 SOC_ENUM("ADC Modular Rate", adc_modular_rate_enum),
1547 SOC_ENUM("DAC Modular Rate", dac_modular_rate_enum),
1548 /* R_ASRC PG 0 ADDR 0x28 */
1549 SOC_SINGLE("ASRC Out High Bandwidth Switch",
1550 R_ASRC, FB_ASRC_ASRCOBW, 1, 0),
1551 SOC_SINGLE("ASRC In High Bandwidth Switch",
1552 R_ASRC, FB_ASRC_ASRCIBW, 1, 0),
1553 /* R_I2SIDCTL PG 0 ADDR 0x38 */
1554 SOC_ENUM("I2S 1 Data In Control", data_in_ctrl_enums[0]),
1555 SOC_ENUM("I2S 2 Data In Control", data_in_ctrl_enums[1]),
1556 SOC_ENUM("I2S 3 Data In Control", data_in_ctrl_enums[2]),
1557 /* R_I2SODCTL PG 0 ADDR 0x39 */
1558 SOC_ENUM("I2S 1 Data Out Control", data_out_ctrl_enums[0]),
1559 SOC_ENUM("I2S 2 Data Out Control", data_out_ctrl_enums[1]),
1560 SOC_ENUM("I2S 3 Data Out Control", data_out_ctrl_enums[2]),
1561 /* R_AUDIOMUX1 PG 0 ADDR 0x3A */
1562 SOC_ENUM("ASRC In", asrc_in_mux_enum),
1563 /* R_AUDIOMUX2 PG 0 ADDR 0x3B */
1564 SOC_ENUM("ASRC Out", asrc_out_mux_enum),
1565 /* R_HSDCTL1 PG 1 ADDR 0x01 */
1566 SOC_ENUM("Headphone Jack Type", hp_jack_type_enum),
1567 SOC_ENUM("Headset Detection Polarity", hs_det_pol_enum),
1568 SOC_SINGLE("Headphone Detection Switch",
1569 R_HSDCTL1, FB_HSDCTL1_HPID_EN, 1, 0),
1570 SOC_SINGLE("Headset OMTP/CTIA Switch",
1571 R_HSDCTL1, FB_HSDCTL1_GBLHS_EN, 1, 0),
1572 /* R_HSDCTL1 PG 1 ADDR 0x02 */
1573 SOC_ENUM("Headset Mic Bias Force", hs_mic_bias_force_enum),
1574 SOC_SINGLE("Manual Mic Bias Switch",
1575 R_HSDCTL2, FB_HSDCTL2_MB1MODE, 1, 0),
1576 SOC_SINGLE("Ring/Sleeve Auto Switch",
1577 R_HSDCTL2, FB_HSDCTL2_SWMODE, 1, 0),
1578 SOC_ENUM("Manual Mode Plug Type", plug_type_force_enum),
1579 /* R_CH0AIC PG 1 ADDR 0x06 */
1580 SOC_SINGLE_TLV("Input Boost Channel 0 Volume", R_CH0AIC,
1581 FB_CHAIC_MICBST, 0x3, 0, in_bst_vol_tlv_arr),
1582 /* R_CH1AIC PG 1 ADDR 0x07 */
1583 SOC_SINGLE_TLV("Input Boost Channel 1 Volume", R_CH1AIC,
1584 FB_CHAIC_MICBST, 0x3, 0, in_bst_vol_tlv_arr),
1585 /* R_CH2AIC PG 1 ADDR 0x08 */
1586 SOC_SINGLE_TLV("Input Boost Channel 2 Volume", R_CH2AIC,
1587 FB_CHAIC_MICBST, 0x3, 0, in_bst_vol_tlv_arr),
1588 /* R_CH3AIC PG 1 ADDR 0x09 */
1589 SOC_SINGLE_TLV("Input Boost Channel 3 Volume", R_CH3AIC,
1590 FB_CHAIC_MICBST, 0x3, 0, in_bst_vol_tlv_arr),
1591 /* R_ICTL0 PG 1 ADDR 0x0A */
1592 SOC_ENUM("Input Channel 1 Polarity", in_pol_ch1_enum),
1593 SOC_ENUM("Input Channel 0 Polarity", in_pol_ch0_enum),
1594 SOC_ENUM("Input Processor Channel 0/1 Operation",
1595 in_proc_ch01_sel_enum),
1596 SOC_SINGLE("Input Channel 1 Mute Switch",
1597 R_ICTL0, FB_ICTL0_IN1MUTE, 1, 0),
1598 SOC_SINGLE("Input Channel 0 Mute Switch",
1599 R_ICTL0, FB_ICTL0_IN0MUTE, 1, 0),
1600 SOC_SINGLE("Input Channel 1 HPF Disable Switch",
1601 R_ICTL0, FB_ICTL0_IN1HP, 1, 0),
1602 SOC_SINGLE("Input Channel 0 HPF Disable Switch",
1603 R_ICTL0, FB_ICTL0_IN0HP, 1, 0),
1604 /* R_ICTL1 PG 1 ADDR 0x0B */
1605 SOC_ENUM("Input Channel 3 Polarity", in_pol_ch3_enum),
1606 SOC_ENUM("Input Channel 2 Polarity", in_pol_ch2_enum),
1607 SOC_ENUM("Input Processor Channel 2/3 Operation",
1608 in_proc_ch23_sel_enum),
1609 SOC_SINGLE("Input Channel 3 Mute Switch",
1610 R_ICTL1, FB_ICTL1_IN3MUTE, 1, 0),
1611 SOC_SINGLE("Input Channel 2 Mute Switch",
1612 R_ICTL1, FB_ICTL1_IN2MUTE, 1, 0),
1613 SOC_SINGLE("Input Channel 3 HPF Disable Switch",
1614 R_ICTL1, FB_ICTL1_IN3HP, 1, 0),
1615 SOC_SINGLE("Input Channel 2 HPF Disable Switch",
1616 R_ICTL1, FB_ICTL1_IN2HP, 1, 0),
1617 /* R_MICBIAS PG 1 ADDR 0x0C */
1618 SOC_ENUM("Mic Bias 2 Voltage", mic_bias_2_enum),
1619 SOC_ENUM("Mic Bias 1 Voltage", mic_bias_1_enum),
1620 /* R_PGACTL0 PG 1 ADDR 0x0D */
1621 SOC_SINGLE("Input Channel 0 PGA Mute Switch",
1622 R_PGACTL0, FB_PGACTL_PGAMUTE, 1, 0),
1623 SOC_SINGLE_TLV("Input Channel 0 PGA Volume", R_PGACTL0,
1624 FB_PGACTL_PGAVOL,
1625 FM_PGACTL_PGAVOL, 0, in_pga_vol_tlv_arr),
1626 /* R_PGACTL1 PG 1 ADDR 0x0E */
1627 SOC_SINGLE("Input Channel 1 PGA Mute Switch",
1628 R_PGACTL1, FB_PGACTL_PGAMUTE, 1, 0),
1629 SOC_SINGLE_TLV("Input Channel 1 PGA Volume", R_PGACTL1,
1630 FB_PGACTL_PGAVOL,
1631 FM_PGACTL_PGAVOL, 0, in_pga_vol_tlv_arr),
1632 /* R_PGACTL2 PG 1 ADDR 0x0F */
1633 SOC_SINGLE("Input Channel 2 PGA Mute Switch",
1634 R_PGACTL2, FB_PGACTL_PGAMUTE, 1, 0),
1635 SOC_SINGLE_TLV("Input Channel 2 PGA Volume", R_PGACTL2,
1636 FB_PGACTL_PGAVOL,
1637 FM_PGACTL_PGAVOL, 0, in_pga_vol_tlv_arr),
1638 /* R_PGACTL3 PG 1 ADDR 0x10 */
1639 SOC_SINGLE("Input Channel 3 PGA Mute Switch",
1640 R_PGACTL3, FB_PGACTL_PGAMUTE, 1, 0),
1641 SOC_SINGLE_TLV("Input Channel 3 PGA Volume", R_PGACTL3,
1642 FB_PGACTL_PGAVOL,
1643 FM_PGACTL_PGAVOL, 0, in_pga_vol_tlv_arr),
1644 /* R_ICH0VOL PG 1 ADDR 0x12 */
1645 SOC_SINGLE_TLV("Input Channel 0 Volume", R_ICH0VOL,
1646 FB_ICHVOL_ICHVOL, FM_ICHVOL_ICHVOL, 0, in_vol_tlv_arr),
1647 /* R_ICH1VOL PG 1 ADDR 0x13 */
1648 SOC_SINGLE_TLV("Input Channel 1 Volume", R_ICH1VOL,
1649 FB_ICHVOL_ICHVOL, FM_ICHVOL_ICHVOL, 0, in_vol_tlv_arr),
1650 /* R_ICH2VOL PG 1 ADDR 0x14 */
1651 SOC_SINGLE_TLV("Input Channel 2 Volume", R_ICH2VOL,
1652 FB_ICHVOL_ICHVOL, FM_ICHVOL_ICHVOL, 0, in_vol_tlv_arr),
1653 /* R_ICH3VOL PG 1 ADDR 0x15 */
1654 SOC_SINGLE_TLV("Input Channel 3 Volume", R_ICH3VOL,
1655 FB_ICHVOL_ICHVOL, FM_ICHVOL_ICHVOL, 0, in_vol_tlv_arr),
1656 /* R_ASRCILVOL PG 1 ADDR 0x16 */
1657 SOC_SINGLE_TLV("ASRC Input Left Volume", R_ASRCILVOL,
1658 FB_ASRCILVOL_ASRCILVOL, FM_ASRCILVOL_ASRCILVOL,
1659 0, asrc_vol_tlv_arr),
1660 /* R_ASRCIRVOL PG 1 ADDR 0x17 */
1661 SOC_SINGLE_TLV("ASRC Input Right Volume", R_ASRCIRVOL,
1662 FB_ASRCIRVOL_ASRCIRVOL, FM_ASRCIRVOL_ASRCIRVOL,
1663 0, asrc_vol_tlv_arr),
1664 /* R_ASRCOLVOL PG 1 ADDR 0x18 */
1665 SOC_SINGLE_TLV("ASRC Output Left Volume", R_ASRCOLVOL,
1666 FB_ASRCOLVOL_ASRCOLVOL, FM_ASRCOLVOL_ASRCOLVOL,
1667 0, asrc_vol_tlv_arr),
1668 /* R_ASRCORVOL PG 1 ADDR 0x19 */
1669 SOC_SINGLE_TLV("ASRC Output Right Volume", R_ASRCORVOL,
1670 FB_ASRCORVOL_ASRCOLVOL, FM_ASRCORVOL_ASRCOLVOL,
1671 0, asrc_vol_tlv_arr),
1672 /* R_IVOLCTLU PG 1 ADDR 0x1C */
1673 /* R_ALCCTL0 PG 1 ADDR 0x1D */
1674 SOC_ENUM("ALC Mode", alc_mode_enum),
1675 SOC_ENUM("ALC Reference", alc_ref_enum),
1676 SOC_SINGLE("Input Channel 3 ALC Switch",
1677 R_ALCCTL0, FB_ALCCTL0_ALCEN3, 1, 0),
1678 SOC_SINGLE("Input Channel 2 ALC Switch",
1679 R_ALCCTL0, FB_ALCCTL0_ALCEN2, 1, 0),
1680 SOC_SINGLE("Input Channel 1 ALC Switch",
1681 R_ALCCTL0, FB_ALCCTL0_ALCEN1, 1, 0),
1682 SOC_SINGLE("Input Channel 0 ALC Switch",
1683 R_ALCCTL0, FB_ALCCTL0_ALCEN0, 1, 0),
1684 /* R_ALCCTL1 PG 1 ADDR 0x1E */
1685 SOC_SINGLE_TLV("ALC Max Gain Volume", R_ALCCTL1,
1686 FB_ALCCTL1_MAXGAIN, FM_ALCCTL1_MAXGAIN,
1687 0, alc_max_gain_tlv_arr),
1688 SOC_SINGLE_TLV("ALC Target Volume", R_ALCCTL1,
1689 FB_ALCCTL1_ALCL, FM_ALCCTL1_ALCL,
1690 0, alc_target_tlv_arr),
1691 /* R_ALCCTL2 PG 1 ADDR 0x1F */
1692 SOC_SINGLE("ALC Zero Cross Switch",
1693 R_ALCCTL2, FB_ALCCTL2_ALCZC, 1, 0),
1694 SOC_SINGLE_TLV("ALC Min Gain Volume", R_ALCCTL2,
1695 FB_ALCCTL2_MINGAIN, FM_ALCCTL2_MINGAIN,
1696 0, alc_min_gain_tlv_arr),
1697 SOC_SINGLE_RANGE("ALC Hold", R_ALCCTL2,
1698 FB_ALCCTL2_HLD, 0, FM_ALCCTL2_HLD, 0),
1699 /* R_ALCCTL3 PG 1 ADDR 0x20 */
1700 SOC_SINGLE_RANGE("ALC Decay", R_ALCCTL3,
1701 FB_ALCCTL3_DCY, 0, FM_ALCCTL3_DCY, 0),
1702 SOC_SINGLE_RANGE("ALC Attack", R_ALCCTL3,
1703 FB_ALCCTL3_ATK, 0, FM_ALCCTL3_ATK, 0),
1704 /* R_NGATE PG 1 ADDR 0x21 */
1705 SOC_SINGLE_TLV("Noise Gate Threshold Volume", R_NGATE,
1706 FB_NGATE_NGTH, FM_NGATE_NGTH, 0, ngth_tlv_arr),
1707 SOC_ENUM("Noise Gate Type", ngate_type_enum),
1708 SOC_SINGLE("Noise Gate Switch", R_NGATE, FB_NGATE_NGAT, 1, 0),
1709 /* R_DMICCTL PG 1 ADDR 0x22 */
1710 SOC_SINGLE("Digital Mic 2 Switch", R_DMICCTL, FB_DMICCTL_DMIC2EN, 1, 0),
1711 SOC_SINGLE("Digital Mic 1 Switch", R_DMICCTL, FB_DMICCTL_DMIC1EN, 1, 0),
1712 SOC_ENUM("Digital Mic Mono Select", dmic_mono_sel_enum),
1713 /* R_DACCTL PG 2 ADDR 0x01 */
1714 SOC_ENUM("DAC Polarity Left", dac_pol_r_enum),
1715 SOC_ENUM("DAC Polarity Right", dac_pol_l_enum),
1716 SOC_ENUM("DAC Dither", dac_dith_enum),
1717 SOC_SINGLE("DAC Mute Switch", R_DACCTL, FB_DACCTL_DACMUTE, 1, 0),
1718 SOC_SINGLE("DAC De-Emphasis Switch", R_DACCTL, FB_DACCTL_DACDEM, 1, 0),
1719 /* R_SPKCTL PG 2 ADDR 0x02 */
1720 SOC_ENUM("Speaker Polarity Right", spk_pol_r_enum),
1721 SOC_ENUM("Speaker Polarity Left", spk_pol_l_enum),
1722 SOC_SINGLE("Speaker Mute Switch", R_SPKCTL, FB_SPKCTL_SPKMUTE, 1, 0),
1723 SOC_SINGLE("Speaker De-Emphasis Switch",
1724 R_SPKCTL, FB_SPKCTL_SPKDEM, 1, 0),
1725 /* R_SUBCTL PG 2 ADDR 0x03 */
1726 SOC_ENUM("Sub Polarity", sub_pol_enum),
1727 SOC_SINGLE("SUB Mute Switch", R_SUBCTL, FB_SUBCTL_SUBMUTE, 1, 0),
1728 SOC_SINGLE("Sub De-Emphasis Switch", R_SUBCTL, FB_SUBCTL_SUBDEM, 1, 0),
1729 /* R_DCCTL PG 2 ADDR 0x04 */
1730 SOC_SINGLE("Sub DC Removal Switch", R_DCCTL, FB_DCCTL_SUBDCBYP, 1, 1),
1731 SOC_SINGLE("DAC DC Removal Switch", R_DCCTL, FB_DCCTL_DACDCBYP, 1, 1),
1732 SOC_SINGLE("Speaker DC Removal Switch",
1733 R_DCCTL, FB_DCCTL_SPKDCBYP, 1, 1),
1734 SOC_SINGLE("DC Removal Coefficient Switch", R_DCCTL, FB_DCCTL_DCCOEFSEL,
1735 FM_DCCTL_DCCOEFSEL, 0),
1736 /* R_OVOLCTLU PG 2 ADDR 0x06 */
1737 SOC_SINGLE("Output Fade Switch", R_OVOLCTLU, FB_OVOLCTLU_OFADE, 1, 0),
1738 /* R_MVOLL PG 2 ADDR 0x08 */
1739 /* R_MVOLR PG 2 ADDR 0x09 */
1740 SOC_DOUBLE_R_TLV("Master Volume", R_MVOLL, R_MVOLR,
1741 FB_MVOLL_MVOL_L, FM_MVOLL_MVOL_L, 0, mvol_tlv_arr),
1742 /* R_HPVOLL PG 2 ADDR 0x0A */
1743 /* R_HPVOLR PG 2 ADDR 0x0B */
1744 SOC_DOUBLE_R_TLV("Headphone Volume", R_HPVOLL, R_HPVOLR,
1745 FB_HPVOLL_HPVOL_L, FM_HPVOLL_HPVOL_L, 0,
1746 hp_vol_tlv_arr),
1747 /* R_SPKVOLL PG 2 ADDR 0x0C */
1748 /* R_SPKVOLR PG 2 ADDR 0x0D */
1749 SOC_DOUBLE_R_TLV("Speaker Volume", R_SPKVOLL, R_SPKVOLR,
1750 FB_SPKVOLL_SPKVOL_L, FM_SPKVOLL_SPKVOL_L, 0,
1751 spk_vol_tlv_arr),
1752 /* R_SUBVOL PG 2 ADDR 0x10 */
1753 SOC_SINGLE_TLV("Sub Volume", R_SUBVOL,
1754 FB_SUBVOL_SUBVOL, FM_SUBVOL_SUBVOL, 0, spk_vol_tlv_arr),
1755 /* R_SPKEQFILT PG 3 ADDR 0x01 */
1756 SOC_SINGLE("Speaker EQ 2 Switch",
1757 R_SPKEQFILT, FB_SPKEQFILT_EQ2EN, 1, 0),
1758 SOC_ENUM("Speaker EQ 2 Band", spk_eq_enums[0]),
1759 SOC_SINGLE("Speaker EQ 1 Switch",
1760 R_SPKEQFILT, FB_SPKEQFILT_EQ1EN, 1, 0),
1761 SOC_ENUM("Speaker EQ 1 Band", spk_eq_enums[1]),
1762 /* R_SPKMBCEN PG 3 ADDR 0x0A */
1763 SOC_SINGLE("Speaker MBC 3 Switch",
1764 R_SPKMBCEN, FB_SPKMBCEN_MBCEN3, 1, 0),
1765 SOC_SINGLE("Speaker MBC 2 Switch",
1766 R_SPKMBCEN, FB_SPKMBCEN_MBCEN2, 1, 0),
1767 SOC_SINGLE("Speaker MBC 1 Switch",
1768 R_SPKMBCEN, FB_SPKMBCEN_MBCEN1, 1, 0),
1769 /* R_SPKMBCCTL PG 3 ADDR 0x0B */
1770 SOC_ENUM("Speaker MBC 3 Mode", spk_mbc3_lvl_det_mode_enum),
1771 SOC_ENUM("Speaker MBC 3 Window", spk_mbc3_win_sel_enum),
1772 SOC_ENUM("Speaker MBC 2 Mode", spk_mbc2_lvl_det_mode_enum),
1773 SOC_ENUM("Speaker MBC 2 Window", spk_mbc2_win_sel_enum),
1774 SOC_ENUM("Speaker MBC 1 Mode", spk_mbc1_lvl_det_mode_enum),
1775 SOC_ENUM("Speaker MBC 1 Window", spk_mbc1_win_sel_enum),
1776 /* R_SPKMBCMUG1 PG 3 ADDR 0x0C */
1777 SOC_ENUM("Speaker MBC 1 Phase Polarity", spk_mbc1_phase_pol_enum),
1778 SOC_SINGLE_TLV("Speaker MBC1 Make-Up Gain Volume", R_SPKMBCMUG1,
1779 FB_SPKMBCMUG_MUGAIN, FM_SPKMBCMUG_MUGAIN,
1780 0, mbc_mug_tlv_arr),
1781 /* R_SPKMBCTHR1 PG 3 ADDR 0x0D */
1782 SOC_SINGLE_TLV("Speaker MBC 1 Compressor Threshold Volume",
1783 R_SPKMBCTHR1, FB_SPKMBCTHR_THRESH, FM_SPKMBCTHR_THRESH,
1784 0, thr_tlv_arr),
1785 /* R_SPKMBCRAT1 PG 3 ADDR 0x0E */
1786 SOC_ENUM("Speaker MBC 1 Compressor Ratio", spk_mbc1_comp_rat_enum),
1787 /* R_SPKMBCATK1L PG 3 ADDR 0x0F */
1788 /* R_SPKMBCATK1H PG 3 ADDR 0x10 */
1789 SND_SOC_BYTES("Speaker MBC 1 Attack", R_SPKMBCATK1L, 2),
1790 /* R_SPKMBCREL1L PG 3 ADDR 0x11 */
1791 /* R_SPKMBCREL1H PG 3 ADDR 0x12 */
1792 SND_SOC_BYTES("Speaker MBC 1 Release", R_SPKMBCREL1L, 2),
1793 /* R_SPKMBCMUG2 PG 3 ADDR 0x13 */
1794 SOC_ENUM("Speaker MBC 2 Phase Polarity", spk_mbc2_phase_pol_enum),
1795 SOC_SINGLE_TLV("Speaker MBC2 Make-Up Gain Volume", R_SPKMBCMUG2,
1796 FB_SPKMBCMUG_MUGAIN, FM_SPKMBCMUG_MUGAIN,
1797 0, mbc_mug_tlv_arr),
1798 /* R_SPKMBCTHR2 PG 3 ADDR 0x14 */
1799 SOC_SINGLE_TLV("Speaker MBC 2 Compressor Threshold Volume",
1800 R_SPKMBCTHR2, FB_SPKMBCTHR_THRESH, FM_SPKMBCTHR_THRESH,
1801 0, thr_tlv_arr),
1802 /* R_SPKMBCRAT2 PG 3 ADDR 0x15 */
1803 SOC_ENUM("Speaker MBC 2 Compressor Ratio", spk_mbc2_comp_rat_enum),
1804 /* R_SPKMBCATK2L PG 3 ADDR 0x16 */
1805 /* R_SPKMBCATK2H PG 3 ADDR 0x17 */
1806 SND_SOC_BYTES("Speaker MBC 2 Attack", R_SPKMBCATK2L, 2),
1807 /* R_SPKMBCREL2L PG 3 ADDR 0x18 */
1808 /* R_SPKMBCREL2H PG 3 ADDR 0x19 */
1809 SND_SOC_BYTES("Speaker MBC 2 Release", R_SPKMBCREL2L, 2),
1810 /* R_SPKMBCMUG3 PG 3 ADDR 0x1A */
1811 SOC_ENUM("Speaker MBC 3 Phase Polarity", spk_mbc3_phase_pol_enum),
1812 SOC_SINGLE_TLV("Speaker MBC 3 Make-Up Gain Volume", R_SPKMBCMUG3,
1813 FB_SPKMBCMUG_MUGAIN, FM_SPKMBCMUG_MUGAIN,
1814 0, mbc_mug_tlv_arr),
1815 /* R_SPKMBCTHR3 PG 3 ADDR 0x1B */
1816 SOC_SINGLE_TLV("Speaker MBC 3 Threshold Volume", R_SPKMBCTHR3,
1817 FB_SPKMBCTHR_THRESH, FM_SPKMBCTHR_THRESH,
1818 0, thr_tlv_arr),
1819 /* R_SPKMBCRAT3 PG 3 ADDR 0x1C */
1820 SOC_ENUM("Speaker MBC 3 Compressor Ratio", spk_mbc3_comp_rat_enum),
1821 /* R_SPKMBCATK3L PG 3 ADDR 0x1D */
1822 /* R_SPKMBCATK3H PG 3 ADDR 0x1E */
1823 SND_SOC_BYTES("Speaker MBC 3 Attack", R_SPKMBCATK3L, 3),
1824 /* R_SPKMBCREL3L PG 3 ADDR 0x1F */
1825 /* R_SPKMBCREL3H PG 3 ADDR 0x20 */
1826 SND_SOC_BYTES("Speaker MBC 3 Release", R_SPKMBCREL3L, 3),
1827 /* R_SPKCLECTL PG 3 ADDR 0x21 */
1828 SOC_ENUM("Speaker CLE Level Mode", spk_cle_lvl_mode_enum),
1829 SOC_ENUM("Speaker CLE Window", spk_cle_win_sel_enum),
1830 SOC_SINGLE("Speaker CLE Expander Switch",
1831 R_SPKCLECTL, FB_SPKCLECTL_EXPEN, 1, 0),
1832 SOC_SINGLE("Speaker CLE Limiter Switch",
1833 R_SPKCLECTL, FB_SPKCLECTL_LIMEN, 1, 0),
1834 SOC_SINGLE("Speaker CLE Compressor Switch",
1835 R_SPKCLECTL, FB_SPKCLECTL_COMPEN, 1, 0),
1836 /* R_SPKCLEMUG PG 3 ADDR 0x22 */
1837 SOC_SINGLE_TLV("Speaker CLE Make-Up Gain Volume", R_SPKCLEMUG,
1838 FB_SPKCLEMUG_MUGAIN, FM_SPKCLEMUG_MUGAIN,
1839 0, cle_mug_tlv_arr),
1840 /* R_SPKCOMPTHR PG 3 ADDR 0x23 */
1841 SOC_SINGLE_TLV("Speaker Compressor Threshold Volume", R_SPKCOMPTHR,
1842 FB_SPKCOMPTHR_THRESH, FM_SPKCOMPTHR_THRESH,
1843 0, thr_tlv_arr),
1844 /* R_SPKCOMPRAT PG 3 ADDR 0x24 */
1845 SOC_ENUM("Speaker Compressor Ratio", spk_comp_rat_enum),
1846 /* R_SPKCOMPATKL PG 3 ADDR 0x25 */
1847 /* R_SPKCOMPATKH PG 3 ADDR 0x26 */
1848 SND_SOC_BYTES("Speaker Compressor Attack", R_SPKCOMPATKL, 2),
1849 /* R_SPKCOMPRELL PG 3 ADDR 0x27 */
1850 /* R_SPKCOMPRELH PG 3 ADDR 0x28 */
1851 SND_SOC_BYTES("Speaker Compressor Release", R_SPKCOMPRELL, 2),
1852 /* R_SPKLIMTHR PG 3 ADDR 0x29 */
1853 SOC_SINGLE_TLV("Speaker Limiter Threshold Volume", R_SPKLIMTHR,
1854 FB_SPKLIMTHR_THRESH, FM_SPKLIMTHR_THRESH,
1855 0, thr_tlv_arr),
1856 /* R_SPKLIMTGT PG 3 ADDR 0x2A */
1857 SOC_SINGLE_TLV("Speaker Limiter Target Volume", R_SPKLIMTGT,
1858 FB_SPKLIMTGT_TARGET, FM_SPKLIMTGT_TARGET,
1859 0, thr_tlv_arr),
1860 /* R_SPKLIMATKL PG 3 ADDR 0x2B */
1861 /* R_SPKLIMATKH PG 3 ADDR 0x2C */
1862 SND_SOC_BYTES("Speaker Limiter Attack", R_SPKLIMATKL, 2),
1863 /* R_SPKLIMRELL PG 3 ADDR 0x2D */
1864 /* R_SPKLIMRELR PG 3 ADDR 0x2E */
1865 SND_SOC_BYTES("Speaker Limiter Release", R_SPKLIMRELL, 2),
1866 /* R_SPKEXPTHR PG 3 ADDR 0x2F */
1867 SOC_SINGLE_TLV("Speaker Expander Threshold Volume", R_SPKEXPTHR,
1868 FB_SPKEXPTHR_THRESH, FM_SPKEXPTHR_THRESH,
1869 0, thr_tlv_arr),
1870 /* R_SPKEXPRAT PG 3 ADDR 0x30 */
1871 SOC_ENUM("Speaker Expander Ratio", spk_exp_rat_enum),
1872 /* R_SPKEXPATKL PG 3 ADDR 0x31 */
1873 /* R_SPKEXPATKR PG 3 ADDR 0x32 */
1874 SND_SOC_BYTES("Speaker Expander Attack", R_SPKEXPATKL, 2),
1875 /* R_SPKEXPRELL PG 3 ADDR 0x33 */
1876 /* R_SPKEXPRELR PG 3 ADDR 0x34 */
1877 SND_SOC_BYTES("Speaker Expander Release", R_SPKEXPRELL, 2),
1878 /* R_SPKFXCTL PG 3 ADDR 0x35 */
1879 SOC_SINGLE("Speaker 3D Switch", R_SPKFXCTL, FB_SPKFXCTL_3DEN, 1, 0),
1880 SOC_SINGLE("Speaker Treble Enhancement Switch",
1881 R_SPKFXCTL, FB_SPKFXCTL_TEEN, 1, 0),
1882 SOC_SINGLE("Speaker Treble NLF Switch",
1883 R_SPKFXCTL, FB_SPKFXCTL_TNLFBYP, 1, 1),
1884 SOC_SINGLE("Speaker Bass Enhancement Switch",
1885 R_SPKFXCTL, FB_SPKFXCTL_BEEN, 1, 0),
1886 SOC_SINGLE("Speaker Bass NLF Switch",
1887 R_SPKFXCTL, FB_SPKFXCTL_BNLFBYP, 1, 1),
1888 /* R_DACEQFILT PG 4 ADDR 0x01 */
1889 SOC_SINGLE("DAC EQ 2 Switch",
1890 R_DACEQFILT, FB_DACEQFILT_EQ2EN, 1, 0),
1891 SOC_ENUM("DAC EQ 2 Band", dac_eq_enums[0]),
1892 SOC_SINGLE("DAC EQ 1 Switch", R_DACEQFILT, FB_DACEQFILT_EQ1EN, 1, 0),
1893 SOC_ENUM("DAC EQ 1 Band", dac_eq_enums[1]),
1894 /* R_DACMBCEN PG 4 ADDR 0x0A */
1895 SOC_SINGLE("DAC MBC 3 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN3, 1, 0),
1896 SOC_SINGLE("DAC MBC 2 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN2, 1, 0),
1897 SOC_SINGLE("DAC MBC 1 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN1, 1, 0),
1898 /* R_DACMBCCTL PG 4 ADDR 0x0B */
1899 SOC_ENUM("DAC MBC 3 Mode", dac_mbc3_lvl_det_mode_enum),
1900 SOC_ENUM("DAC MBC 3 Window", dac_mbc3_win_sel_enum),
1901 SOC_ENUM("DAC MBC 2 Mode", dac_mbc2_lvl_det_mode_enum),
1902 SOC_ENUM("DAC MBC 2 Window", dac_mbc2_win_sel_enum),
1903 SOC_ENUM("DAC MBC 1 Mode", dac_mbc1_lvl_det_mode_enum),
1904 SOC_ENUM("DAC MBC 1 Window", dac_mbc1_win_sel_enum),
1905 /* R_DACMBCMUG1 PG 4 ADDR 0x0C */
1906 SOC_ENUM("DAC MBC 1 Phase Polarity", dac_mbc1_phase_pol_enum),
1907 SOC_SINGLE_TLV("DAC MBC 1 Make-Up Gain Volume", R_DACMBCMUG1,
1908 FB_DACMBCMUG_MUGAIN, FM_DACMBCMUG_MUGAIN,
1909 0, mbc_mug_tlv_arr),
1910 /* R_DACMBCTHR1 PG 4 ADDR 0x0D */
1911 SOC_SINGLE_TLV("DAC MBC 1 Compressor Threshold Volume", R_DACMBCTHR1,
1912 FB_DACMBCTHR_THRESH, FM_DACMBCTHR_THRESH,
1913 0, thr_tlv_arr),
1914 /* R_DACMBCRAT1 PG 4 ADDR 0x0E */
1915 SOC_ENUM("DAC MBC 1 Compressor Ratio", dac_mbc1_comp_rat_enum),
1916 /* R_DACMBCATK1L PG 4 ADDR 0x0F */
1917 /* R_DACMBCATK1H PG 4 ADDR 0x10 */
1918 SND_SOC_BYTES("DAC MBC 1 Attack", R_DACMBCATK1L, 2),
1919 /* R_DACMBCREL1L PG 4 ADDR 0x11 */
1920 /* R_DACMBCREL1H PG 4 ADDR 0x12 */
1921 SND_SOC_BYTES("DAC MBC 1 Release", R_DACMBCREL1L, 2),
1922 /* R_DACMBCMUG2 PG 4 ADDR 0x13 */
1923 SOC_ENUM("DAC MBC 2 Phase Polarity", dac_mbc2_phase_pol_enum),
1924 SOC_SINGLE_TLV("DAC MBC 2 Make-Up Gain Volume", R_DACMBCMUG2,
1925 FB_DACMBCMUG_MUGAIN, FM_DACMBCMUG_MUGAIN,
1926 0, mbc_mug_tlv_arr),
1927 /* R_DACMBCTHR2 PG 4 ADDR 0x14 */
1928 SOC_SINGLE_TLV("DAC MBC 2 Compressor Threshold Volume", R_DACMBCTHR2,
1929 FB_DACMBCTHR_THRESH, FM_DACMBCTHR_THRESH,
1930 0, thr_tlv_arr),
1931 /* R_DACMBCRAT2 PG 4 ADDR 0x15 */
1932 SOC_ENUM("DAC MBC 2 Compressor Ratio", dac_mbc2_comp_rat_enum),
1933 /* R_DACMBCATK2L PG 4 ADDR 0x16 */
1934 /* R_DACMBCATK2H PG 4 ADDR 0x17 */
1935 SND_SOC_BYTES("DAC MBC 2 Attack", R_DACMBCATK2L, 2),
1936 /* R_DACMBCREL2L PG 4 ADDR 0x18 */
1937 /* R_DACMBCREL2H PG 4 ADDR 0x19 */
1938 SND_SOC_BYTES("DAC MBC 2 Release", R_DACMBCREL2L, 2),
1939 /* R_DACMBCMUG3 PG 4 ADDR 0x1A */
1940 SOC_ENUM("DAC MBC 3 Phase Polarity", dac_mbc3_phase_pol_enum),
1941 SOC_SINGLE_TLV("DAC MBC 3 Make-Up Gain Volume", R_DACMBCMUG3,
1942 FB_DACMBCMUG_MUGAIN, FM_DACMBCMUG_MUGAIN,
1943 0, mbc_mug_tlv_arr),
1944 /* R_DACMBCTHR3 PG 4 ADDR 0x1B */
1945 SOC_SINGLE_TLV("DAC MBC 3 Threshold Volume", R_DACMBCTHR3,
1946 FB_DACMBCTHR_THRESH, FM_DACMBCTHR_THRESH,
1947 0, thr_tlv_arr),
1948 /* R_DACMBCRAT3 PG 4 ADDR 0x1C */
1949 SOC_ENUM("DAC MBC 3 Compressor Ratio", dac_mbc3_comp_rat_enum),
1950 /* R_DACMBCATK3L PG 4 ADDR 0x1D */
1951 /* R_DACMBCATK3H PG 4 ADDR 0x1E */
1952 SND_SOC_BYTES("DAC MBC 3 Attack", R_DACMBCATK3L, 3),
1953 /* R_DACMBCREL3L PG 4 ADDR 0x1F */
1954 /* R_DACMBCREL3H PG 4 ADDR 0x20 */
1955 SND_SOC_BYTES("DAC MBC 3 Release", R_DACMBCREL3L, 3),
1956 /* R_DACCLECTL PG 4 ADDR 0x21 */
1957 SOC_ENUM("DAC CLE Level Mode", dac_cle_lvl_mode_enum),
1958 SOC_ENUM("DAC CLE Window", dac_cle_win_sel_enum),
1959 SOC_SINGLE("DAC CLE Expander Switch",
1960 R_DACCLECTL, FB_DACCLECTL_EXPEN, 1, 0),
1961 SOC_SINGLE("DAC CLE Limiter Switch",
1962 R_DACCLECTL, FB_DACCLECTL_LIMEN, 1, 0),
1963 SOC_SINGLE("DAC CLE Compressor Switch",
1964 R_DACCLECTL, FB_DACCLECTL_COMPEN, 1, 0),
1965 /* R_DACCLEMUG PG 4 ADDR 0x22 */
1966 SOC_SINGLE_TLV("DAC CLE Make-Up Gain Volume", R_DACCLEMUG,
1967 FB_DACCLEMUG_MUGAIN, FM_DACCLEMUG_MUGAIN,
1968 0, cle_mug_tlv_arr),
1969 /* R_DACCOMPTHR PG 4 ADDR 0x23 */
1970 SOC_SINGLE_TLV("DAC Compressor Threshold Volume", R_DACCOMPTHR,
1971 FB_DACCOMPTHR_THRESH, FM_DACCOMPTHR_THRESH,
1972 0, thr_tlv_arr),
1973 /* R_DACCOMPRAT PG 4 ADDR 0x24 */
1974 SOC_ENUM("DAC Compressor Ratio", dac_comp_rat_enum),
1975 /* R_DACCOMPATKL PG 4 ADDR 0x25 */
1976 /* R_DACCOMPATKH PG 4 ADDR 0x26 */
1977 SND_SOC_BYTES("DAC Compressor Attack", R_DACCOMPATKL, 2),
1978 /* R_DACCOMPRELL PG 4 ADDR 0x27 */
1979 /* R_DACCOMPRELH PG 4 ADDR 0x28 */
1980 SND_SOC_BYTES("DAC Compressor Release", R_DACCOMPRELL, 2),
1981 /* R_DACLIMTHR PG 4 ADDR 0x29 */
1982 SOC_SINGLE_TLV("DAC Limiter Threshold Volume", R_DACLIMTHR,
1983 FB_DACLIMTHR_THRESH, FM_DACLIMTHR_THRESH,
1984 0, thr_tlv_arr),
1985 /* R_DACLIMTGT PG 4 ADDR 0x2A */
1986 SOC_SINGLE_TLV("DAC Limiter Target Volume", R_DACLIMTGT,
1987 FB_DACLIMTGT_TARGET, FM_DACLIMTGT_TARGET,
1988 0, thr_tlv_arr),
1989 /* R_DACLIMATKL PG 4 ADDR 0x2B */
1990 /* R_DACLIMATKH PG 4 ADDR 0x2C */
1991 SND_SOC_BYTES("DAC Limiter Attack", R_DACLIMATKL, 2),
1992 /* R_DACLIMRELL PG 4 ADDR 0x2D */
1993 /* R_DACLIMRELR PG 4 ADDR 0x2E */
1994 SND_SOC_BYTES("DAC Limiter Release", R_DACLIMRELL, 2),
1995 /* R_DACEXPTHR PG 4 ADDR 0x2F */
1996 SOC_SINGLE_TLV("DAC Expander Threshold Volume", R_DACEXPTHR,
1997 FB_DACEXPTHR_THRESH, FM_DACEXPTHR_THRESH,
1998 0, thr_tlv_arr),
1999 /* R_DACEXPRAT PG 4 ADDR 0x30 */
2000 SOC_ENUM("DAC Expander Ratio", dac_exp_rat_enum),
2001 /* R_DACEXPATKL PG 4 ADDR 0x31 */
2002 /* R_DACEXPATKR PG 4 ADDR 0x32 */
2003 SND_SOC_BYTES("DAC Expander Attack", R_DACEXPATKL, 2),
2004 /* R_DACEXPRELL PG 4 ADDR 0x33 */
2005 /* R_DACEXPRELR PG 4 ADDR 0x34 */
2006 SND_SOC_BYTES("DAC Expander Release", R_DACEXPRELL, 2),
2007 /* R_DACFXCTL PG 4 ADDR 0x35 */
2008 SOC_SINGLE("DAC 3D Switch", R_DACFXCTL, FB_DACFXCTL_3DEN, 1, 0),
2009 SOC_SINGLE("DAC Treble Enhancement Switch",
2010 R_DACFXCTL, FB_DACFXCTL_TEEN, 1, 0),
2011 SOC_SINGLE("DAC Treble NLF Switch",
2012 R_DACFXCTL, FB_DACFXCTL_TNLFBYP, 1, 1),
2013 SOC_SINGLE("DAC Bass Enhancement Switch",
2014 R_DACFXCTL, FB_DACFXCTL_BEEN, 1, 0),
2015 SOC_SINGLE("DAC Bass NLF Switch",
2016 R_DACFXCTL, FB_DACFXCTL_BNLFBYP, 1, 1),
2017 /* R_SUBEQFILT PG 5 ADDR 0x01 */
2018 SOC_SINGLE("Sub EQ 2 Switch",
2019 R_SUBEQFILT, FB_SUBEQFILT_EQ2EN, 1, 0),
2020 SOC_ENUM("Sub EQ 2 Band", sub_eq_enums[0]),
2021 SOC_SINGLE("Sub EQ 1 Switch", R_SUBEQFILT, FB_SUBEQFILT_EQ1EN, 1, 0),
2022 SOC_ENUM("Sub EQ 1 Band", sub_eq_enums[1]),
2023 /* R_SUBMBCEN PG 5 ADDR 0x0A */
2024 SOC_SINGLE("Sub MBC 3 Switch", R_SUBMBCEN, FB_SUBMBCEN_MBCEN3, 1, 0),
2025 SOC_SINGLE("Sub MBC 2 Switch", R_SUBMBCEN, FB_SUBMBCEN_MBCEN2, 1, 0),
2026 SOC_SINGLE("Sub MBC 1 Switch", R_SUBMBCEN, FB_SUBMBCEN_MBCEN1, 1, 0),
2027 /* R_SUBMBCCTL PG 5 ADDR 0x0B */
2028 SOC_ENUM("Sub MBC 3 Mode", sub_mbc3_lvl_det_mode_enum),
2029 SOC_ENUM("Sub MBC 3 Window", sub_mbc3_win_sel_enum),
2030 SOC_ENUM("Sub MBC 2 Mode", sub_mbc2_lvl_det_mode_enum),
2031 SOC_ENUM("Sub MBC 2 Window", sub_mbc2_win_sel_enum),
2032 SOC_ENUM("Sub MBC 1 Mode", sub_mbc1_lvl_det_mode_enum),
2033 SOC_ENUM("Sub MBC 1 Window", sub_mbc1_win_sel_enum),
2034 /* R_SUBMBCMUG1 PG 5 ADDR 0x0C */
2035 SOC_ENUM("Sub MBC 1 Phase Polarity", sub_mbc1_phase_pol_enum),
2036 SOC_SINGLE_TLV("Sub MBC 1 Make-Up Gain Volume", R_SUBMBCMUG1,
2037 FB_SUBMBCMUG_MUGAIN, FM_SUBMBCMUG_MUGAIN,
2038 0, mbc_mug_tlv_arr),
2039 /* R_SUBMBCTHR1 PG 5 ADDR 0x0D */
2040 SOC_SINGLE_TLV("Sub MBC 1 Compressor Threshold Volume", R_SUBMBCTHR1,
2041 FB_SUBMBCTHR_THRESH, FM_SUBMBCTHR_THRESH,
2042 0, thr_tlv_arr),
2043 /* R_SUBMBCRAT1 PG 5 ADDR 0x0E */
2044 SOC_ENUM("Sub MBC 1 Compressor Ratio", sub_mbc1_comp_rat_enum),
2045 /* R_SUBMBCATK1L PG 5 ADDR 0x0F */
2046 /* R_SUBMBCATK1H PG 5 ADDR 0x10 */
2047 SND_SOC_BYTES("Sub MBC 1 Attack", R_SUBMBCATK1L, 2),
2048 /* R_SUBMBCREL1L PG 5 ADDR 0x11 */
2049 /* R_SUBMBCREL1H PG 5 ADDR 0x12 */
2050 SND_SOC_BYTES("Sub MBC 1 Release", R_SUBMBCREL1L, 2),
2051 /* R_SUBMBCMUG2 PG 5 ADDR 0x13 */
2052 SOC_ENUM("Sub MBC 2 Phase Polarity", sub_mbc2_phase_pol_enum),
2053 SOC_SINGLE_TLV("Sub MBC 2 Make-Up Gain Volume", R_SUBMBCMUG2,
2054 FB_SUBMBCMUG_MUGAIN, FM_SUBMBCMUG_MUGAIN,
2055 0, mbc_mug_tlv_arr),
2056 /* R_SUBMBCTHR2 PG 5 ADDR 0x14 */
2057 SOC_SINGLE_TLV("Sub MBC 2 Compressor Threshold Volume", R_SUBMBCTHR2,
2058 FB_SUBMBCTHR_THRESH, FM_SUBMBCTHR_THRESH,
2059 0, thr_tlv_arr),
2060 /* R_SUBMBCRAT2 PG 5 ADDR 0x15 */
2061 SOC_ENUM("Sub MBC 2 Compressor Ratio", sub_mbc2_comp_rat_enum),
2062 /* R_SUBMBCATK2L PG 5 ADDR 0x16 */
2063 /* R_SUBMBCATK2H PG 5 ADDR 0x17 */
2064 SND_SOC_BYTES("Sub MBC 2 Attack", R_SUBMBCATK2L, 2),
2065 /* R_SUBMBCREL2L PG 5 ADDR 0x18 */
2066 /* R_SUBMBCREL2H PG 5 ADDR 0x19 */
2067 SND_SOC_BYTES("Sub MBC 2 Release", R_SUBMBCREL2L, 2),
2068 /* R_SUBMBCMUG3 PG 5 ADDR 0x1A */
2069 SOC_ENUM("Sub MBC 3 Phase Polarity", sub_mbc3_phase_pol_enum),
2070 SOC_SINGLE_TLV("Sub MBC 3 Make-Up Gain Volume", R_SUBMBCMUG3,
2071 FB_SUBMBCMUG_MUGAIN, FM_SUBMBCMUG_MUGAIN,
2072 0, mbc_mug_tlv_arr),
2073 /* R_SUBMBCTHR3 PG 5 ADDR 0x1B */
2074 SOC_SINGLE_TLV("Sub MBC 3 Threshold Volume", R_SUBMBCTHR3,
2075 FB_SUBMBCTHR_THRESH, FM_SUBMBCTHR_THRESH,
2076 0, thr_tlv_arr),
2077 /* R_SUBMBCRAT3 PG 5 ADDR 0x1C */
2078 SOC_ENUM("Sub MBC 3 Compressor Ratio", sub_mbc3_comp_rat_enum),
2079 /* R_SUBMBCATK3L PG 5 ADDR 0x1D */
2080 /* R_SUBMBCATK3H PG 5 ADDR 0x1E */
2081 SND_SOC_BYTES("Sub MBC 3 Attack", R_SUBMBCATK3L, 3),
2082 /* R_SUBMBCREL3L PG 5 ADDR 0x1F */
2083 /* R_SUBMBCREL3H PG 5 ADDR 0x20 */
2084 SND_SOC_BYTES("Sub MBC 3 Release", R_SUBMBCREL3L, 3),
2085 /* R_SUBCLECTL PG 5 ADDR 0x21 */
2086 SOC_ENUM("Sub CLE Level Mode", sub_cle_lvl_mode_enum),
2087 SOC_ENUM("Sub CLE Window", sub_cle_win_sel_enum),
2088 SOC_SINGLE("Sub CLE Expander Switch",
2089 R_SUBCLECTL, FB_SUBCLECTL_EXPEN, 1, 0),
2090 SOC_SINGLE("Sub CLE Limiter Switch",
2091 R_SUBCLECTL, FB_SUBCLECTL_LIMEN, 1, 0),
2092 SOC_SINGLE("Sub CLE Compressor Switch",
2093 R_SUBCLECTL, FB_SUBCLECTL_COMPEN, 1, 0),
2094 /* R_SUBCLEMUG PG 5 ADDR 0x22 */
2095 SOC_SINGLE_TLV("Sub CLE Make-Up Gain Volume", R_SUBCLEMUG,
2096 FB_SUBCLEMUG_MUGAIN, FM_SUBCLEMUG_MUGAIN,
2097 0, cle_mug_tlv_arr),
2098 /* R_SUBCOMPTHR PG 5 ADDR 0x23 */
2099 SOC_SINGLE_TLV("Sub Compressor Threshold Volume", R_SUBCOMPTHR,
2100 FB_SUBCOMPTHR_THRESH, FM_SUBCOMPTHR_THRESH,
2101 0, thr_tlv_arr),
2102 /* R_SUBCOMPRAT PG 5 ADDR 0x24 */
2103 SOC_ENUM("Sub Compressor Ratio", sub_comp_rat_enum),
2104 /* R_SUBCOMPATKL PG 5 ADDR 0x25 */
2105 /* R_SUBCOMPATKH PG 5 ADDR 0x26 */
2106 SND_SOC_BYTES("Sub Compressor Attack", R_SUBCOMPATKL, 2),
2107 /* R_SUBCOMPRELL PG 5 ADDR 0x27 */
2108 /* R_SUBCOMPRELH PG 5 ADDR 0x28 */
2109 SND_SOC_BYTES("Sub Compressor Release", R_SUBCOMPRELL, 2),
2110 /* R_SUBLIMTHR PG 5 ADDR 0x29 */
2111 SOC_SINGLE_TLV("Sub Limiter Threshold Volume", R_SUBLIMTHR,
2112 FB_SUBLIMTHR_THRESH, FM_SUBLIMTHR_THRESH,
2113 0, thr_tlv_arr),
2114 /* R_SUBLIMTGT PG 5 ADDR 0x2A */
2115 SOC_SINGLE_TLV("Sub Limiter Target Volume", R_SUBLIMTGT,
2116 FB_SUBLIMTGT_TARGET, FM_SUBLIMTGT_TARGET,
2117 0, thr_tlv_arr),
2118 /* R_SUBLIMATKL PG 5 ADDR 0x2B */
2119 /* R_SUBLIMATKH PG 5 ADDR 0x2C */
2120 SND_SOC_BYTES("Sub Limiter Attack", R_SUBLIMATKL, 2),
2121 /* R_SUBLIMRELL PG 5 ADDR 0x2D */
2122 /* R_SUBLIMRELR PG 5 ADDR 0x2E */
2123 SND_SOC_BYTES("Sub Limiter Release", R_SUBLIMRELL, 2),
2124 /* R_SUBEXPTHR PG 5 ADDR 0x2F */
2125 SOC_SINGLE_TLV("Sub Expander Threshold Volume", R_SUBEXPTHR,
2126 FB_SUBEXPTHR_THRESH, FM_SUBEXPTHR_THRESH,
2127 0, thr_tlv_arr),
2128 /* R_SUBEXPRAT PG 5 ADDR 0x30 */
2129 SOC_ENUM("Sub Expander Ratio", sub_exp_rat_enum),
2130 /* R_SUBEXPATKL PG 5 ADDR 0x31 */
2131 /* R_SUBEXPATKR PG 5 ADDR 0x32 */
2132 SND_SOC_BYTES("Sub Expander Attack", R_SUBEXPATKL, 2),
2133 /* R_SUBEXPRELL PG 5 ADDR 0x33 */
2134 /* R_SUBEXPRELR PG 5 ADDR 0x34 */
2135 SND_SOC_BYTES("Sub Expander Release", R_SUBEXPRELL, 2),
2136 /* R_SUBFXCTL PG 5 ADDR 0x35 */
2137 SOC_SINGLE("Sub Treble Enhancement Switch",
2138 R_SUBFXCTL, FB_SUBFXCTL_TEEN, 1, 0),
2139 SOC_SINGLE("Sub Treble NLF Switch",
2140 R_SUBFXCTL, FB_SUBFXCTL_TNLFBYP, 1, 1),
2141 SOC_SINGLE("Sub Bass Enhancement Switch",
2142 R_SUBFXCTL, FB_SUBFXCTL_BEEN, 1, 0),
2143 SOC_SINGLE("Sub Bass NLF Switch",
2144 R_SUBFXCTL, FB_SUBFXCTL_BNLFBYP, 1, 1),
2145 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 1", BIQUAD_SIZE, 0x00),
2146 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 2", BIQUAD_SIZE, 0x05),
2147 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 3", BIQUAD_SIZE, 0x0a),
2148 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 4", BIQUAD_SIZE, 0x0f),
2149 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 5", BIQUAD_SIZE, 0x14),
2150 COEFF_RAM_CTL("DAC Cascade 1 Left BiQuad 6", BIQUAD_SIZE, 0x19),
2151
2152 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 1", BIQUAD_SIZE, 0x20),
2153 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 2", BIQUAD_SIZE, 0x25),
2154 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 3", BIQUAD_SIZE, 0x2a),
2155 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 4", BIQUAD_SIZE, 0x2f),
2156 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 5", BIQUAD_SIZE, 0x34),
2157 COEFF_RAM_CTL("DAC Cascade 1 Right BiQuad 6", BIQUAD_SIZE, 0x39),
2158
2159 COEFF_RAM_CTL("DAC Cascade 1 Left Prescale", COEFF_SIZE, 0x1f),
2160 COEFF_RAM_CTL("DAC Cascade 1 Right Prescale", COEFF_SIZE, 0x3f),
2161
2162 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 1", BIQUAD_SIZE, 0x40),
2163 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 2", BIQUAD_SIZE, 0x45),
2164 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 3", BIQUAD_SIZE, 0x4a),
2165 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 4", BIQUAD_SIZE, 0x4f),
2166 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 5", BIQUAD_SIZE, 0x54),
2167 COEFF_RAM_CTL("DAC Cascade 2 Left BiQuad 6", BIQUAD_SIZE, 0x59),
2168
2169 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 1", BIQUAD_SIZE, 0x60),
2170 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 2", BIQUAD_SIZE, 0x65),
2171 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 3", BIQUAD_SIZE, 0x6a),
2172 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 4", BIQUAD_SIZE, 0x6f),
2173 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 5", BIQUAD_SIZE, 0x74),
2174 COEFF_RAM_CTL("DAC Cascade 2 Right BiQuad 6", BIQUAD_SIZE, 0x79),
2175
2176 COEFF_RAM_CTL("DAC Cascade 2 Left Prescale", COEFF_SIZE, 0x5f),
2177 COEFF_RAM_CTL("DAC Cascade 2 Right Prescale", COEFF_SIZE, 0x7f),
2178
2179 COEFF_RAM_CTL("DAC Bass Extraction BiQuad 1", BIQUAD_SIZE, 0x80),
2180 COEFF_RAM_CTL("DAC Bass Extraction BiQuad 2", BIQUAD_SIZE, 0x85),
2181
2182 COEFF_RAM_CTL("DAC Bass Non Linear Function 1", COEFF_SIZE, 0x8a),
2183 COEFF_RAM_CTL("DAC Bass Non Linear Function 2", COEFF_SIZE, 0x8b),
2184
2185 COEFF_RAM_CTL("DAC Bass Limiter BiQuad", BIQUAD_SIZE, 0x8c),
2186
2187 COEFF_RAM_CTL("DAC Bass Cut Off BiQuad", BIQUAD_SIZE, 0x91),
2188
2189 COEFF_RAM_CTL("DAC Bass Mix", COEFF_SIZE, 0x96),
2190
2191 COEFF_RAM_CTL("DAC Treb Extraction BiQuad 1", BIQUAD_SIZE, 0x97),
2192 COEFF_RAM_CTL("DAC Treb Extraction BiQuad 2", BIQUAD_SIZE, 0x9c),
2193
2194 COEFF_RAM_CTL("DAC Treb Non Linear Function 1", COEFF_SIZE, 0xa1),
2195 COEFF_RAM_CTL("DAC Treb Non Linear Function 2", COEFF_SIZE, 0xa2),
2196
2197 COEFF_RAM_CTL("DAC Treb Limiter BiQuad", BIQUAD_SIZE, 0xa3),
2198
2199 COEFF_RAM_CTL("DAC Treb Cut Off BiQuad", BIQUAD_SIZE, 0xa8),
2200
2201 COEFF_RAM_CTL("DAC Treb Mix", COEFF_SIZE, 0xad),
2202
2203 COEFF_RAM_CTL("DAC 3D", COEFF_SIZE, 0xae),
2204
2205 COEFF_RAM_CTL("DAC 3D Mix", COEFF_SIZE, 0xaf),
2206
2207 COEFF_RAM_CTL("DAC MBC 1 BiQuad 1", BIQUAD_SIZE, 0xb0),
2208 COEFF_RAM_CTL("DAC MBC 1 BiQuad 2", BIQUAD_SIZE, 0xb5),
2209
2210 COEFF_RAM_CTL("DAC MBC 2 BiQuad 1", BIQUAD_SIZE, 0xba),
2211 COEFF_RAM_CTL("DAC MBC 2 BiQuad 2", BIQUAD_SIZE, 0xbf),
2212
2213 COEFF_RAM_CTL("DAC MBC 3 BiQuad 1", BIQUAD_SIZE, 0xc4),
2214 COEFF_RAM_CTL("DAC MBC 3 BiQuad 2", BIQUAD_SIZE, 0xc9),
2215
2216 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 1", BIQUAD_SIZE, 0x00),
2217 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 2", BIQUAD_SIZE, 0x05),
2218 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 3", BIQUAD_SIZE, 0x0a),
2219 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 4", BIQUAD_SIZE, 0x0f),
2220 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 5", BIQUAD_SIZE, 0x14),
2221 COEFF_RAM_CTL("Speaker Cascade 1 Left BiQuad 6", BIQUAD_SIZE, 0x19),
2222
2223 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 1", BIQUAD_SIZE, 0x20),
2224 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 2", BIQUAD_SIZE, 0x25),
2225 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 3", BIQUAD_SIZE, 0x2a),
2226 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 4", BIQUAD_SIZE, 0x2f),
2227 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 5", BIQUAD_SIZE, 0x34),
2228 COEFF_RAM_CTL("Speaker Cascade 1 Right BiQuad 6", BIQUAD_SIZE, 0x39),
2229
2230 COEFF_RAM_CTL("Speaker Cascade 1 Left Prescale", COEFF_SIZE, 0x1f),
2231 COEFF_RAM_CTL("Speaker Cascade 1 Right Prescale", COEFF_SIZE, 0x3f),
2232
2233 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 1", BIQUAD_SIZE, 0x40),
2234 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 2", BIQUAD_SIZE, 0x45),
2235 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 3", BIQUAD_SIZE, 0x4a),
2236 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 4", BIQUAD_SIZE, 0x4f),
2237 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 5", BIQUAD_SIZE, 0x54),
2238 COEFF_RAM_CTL("Speaker Cascade 2 Left BiQuad 6", BIQUAD_SIZE, 0x59),
2239
2240 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 1", BIQUAD_SIZE, 0x60),
2241 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 2", BIQUAD_SIZE, 0x65),
2242 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 3", BIQUAD_SIZE, 0x6a),
2243 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 4", BIQUAD_SIZE, 0x6f),
2244 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 5", BIQUAD_SIZE, 0x74),
2245 COEFF_RAM_CTL("Speaker Cascade 2 Right BiQuad 6", BIQUAD_SIZE, 0x79),
2246
2247 COEFF_RAM_CTL("Speaker Cascade 2 Left Prescale", COEFF_SIZE, 0x5f),
2248 COEFF_RAM_CTL("Speaker Cascade 2 Right Prescale", COEFF_SIZE, 0x7f),
2249
2250 COEFF_RAM_CTL("Speaker Bass Extraction BiQuad 1", BIQUAD_SIZE, 0x80),
2251 COEFF_RAM_CTL("Speaker Bass Extraction BiQuad 2", BIQUAD_SIZE, 0x85),
2252
2253 COEFF_RAM_CTL("Speaker Bass Non Linear Function 1", COEFF_SIZE, 0x8a),
2254 COEFF_RAM_CTL("Speaker Bass Non Linear Function 2", COEFF_SIZE, 0x8b),
2255
2256 COEFF_RAM_CTL("Speaker Bass Limiter BiQuad", BIQUAD_SIZE, 0x8c),
2257
2258 COEFF_RAM_CTL("Speaker Bass Cut Off BiQuad", BIQUAD_SIZE, 0x91),
2259
2260 COEFF_RAM_CTL("Speaker Bass Mix", COEFF_SIZE, 0x96),
2261
2262 COEFF_RAM_CTL("Speaker Treb Extraction BiQuad 1", BIQUAD_SIZE, 0x97),
2263 COEFF_RAM_CTL("Speaker Treb Extraction BiQuad 2", BIQUAD_SIZE, 0x9c),
2264
2265 COEFF_RAM_CTL("Speaker Treb Non Linear Function 1", COEFF_SIZE, 0xa1),
2266 COEFF_RAM_CTL("Speaker Treb Non Linear Function 2", COEFF_SIZE, 0xa2),
2267
2268 COEFF_RAM_CTL("Speaker Treb Limiter BiQuad", BIQUAD_SIZE, 0xa3),
2269
2270 COEFF_RAM_CTL("Speaker Treb Cut Off BiQuad", BIQUAD_SIZE, 0xa8),
2271
2272 COEFF_RAM_CTL("Speaker Treb Mix", COEFF_SIZE, 0xad),
2273
2274 COEFF_RAM_CTL("Speaker 3D", COEFF_SIZE, 0xae),
2275
2276 COEFF_RAM_CTL("Speaker 3D Mix", COEFF_SIZE, 0xaf),
2277
2278 COEFF_RAM_CTL("Speaker MBC 1 BiQuad 1", BIQUAD_SIZE, 0xb0),
2279 COEFF_RAM_CTL("Speaker MBC 1 BiQuad 2", BIQUAD_SIZE, 0xb5),
2280
2281 COEFF_RAM_CTL("Speaker MBC 2 BiQuad 1", BIQUAD_SIZE, 0xba),
2282 COEFF_RAM_CTL("Speaker MBC 2 BiQuad 2", BIQUAD_SIZE, 0xbf),
2283
2284 COEFF_RAM_CTL("Speaker MBC 3 BiQuad 1", BIQUAD_SIZE, 0xc4),
2285 COEFF_RAM_CTL("Speaker MBC 3 BiQuad 2", BIQUAD_SIZE, 0xc9),
2286
2287 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 1", BIQUAD_SIZE, 0x00),
2288 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 2", BIQUAD_SIZE, 0x05),
2289 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 3", BIQUAD_SIZE, 0x0a),
2290 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 4", BIQUAD_SIZE, 0x0f),
2291 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 5", BIQUAD_SIZE, 0x14),
2292 COEFF_RAM_CTL("Sub Cascade 1 Left BiQuad 6", BIQUAD_SIZE, 0x19),
2293
2294 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 1", BIQUAD_SIZE, 0x20),
2295 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 2", BIQUAD_SIZE, 0x25),
2296 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 3", BIQUAD_SIZE, 0x2a),
2297 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 4", BIQUAD_SIZE, 0x2f),
2298 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 5", BIQUAD_SIZE, 0x34),
2299 COEFF_RAM_CTL("Sub Cascade 1 Right BiQuad 6", BIQUAD_SIZE, 0x39),
2300
2301 COEFF_RAM_CTL("Sub Cascade 1 Left Prescale", COEFF_SIZE, 0x1f),
2302 COEFF_RAM_CTL("Sub Cascade 1 Right Prescale", COEFF_SIZE, 0x3f),
2303
2304 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 1", BIQUAD_SIZE, 0x40),
2305 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 2", BIQUAD_SIZE, 0x45),
2306 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 3", BIQUAD_SIZE, 0x4a),
2307 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 4", BIQUAD_SIZE, 0x4f),
2308 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 5", BIQUAD_SIZE, 0x54),
2309 COEFF_RAM_CTL("Sub Cascade 2 Left BiQuad 6", BIQUAD_SIZE, 0x59),
2310
2311 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 1", BIQUAD_SIZE, 0x60),
2312 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 2", BIQUAD_SIZE, 0x65),
2313 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 3", BIQUAD_SIZE, 0x6a),
2314 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 4", BIQUAD_SIZE, 0x6f),
2315 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 5", BIQUAD_SIZE, 0x74),
2316 COEFF_RAM_CTL("Sub Cascade 2 Right BiQuad 6", BIQUAD_SIZE, 0x79),
2317
2318 COEFF_RAM_CTL("Sub Cascade 2 Left Prescale", COEFF_SIZE, 0x5f),
2319 COEFF_RAM_CTL("Sub Cascade 2 Right Prescale", COEFF_SIZE, 0x7f),
2320
2321 COEFF_RAM_CTL("Sub Bass Extraction BiQuad 1", BIQUAD_SIZE, 0x80),
2322 COEFF_RAM_CTL("Sub Bass Extraction BiQuad 2", BIQUAD_SIZE, 0x85),
2323
2324 COEFF_RAM_CTL("Sub Bass Non Linear Function 1", COEFF_SIZE, 0x8a),
2325 COEFF_RAM_CTL("Sub Bass Non Linear Function 2", COEFF_SIZE, 0x8b),
2326
2327 COEFF_RAM_CTL("Sub Bass Limiter BiQuad", BIQUAD_SIZE, 0x8c),
2328
2329 COEFF_RAM_CTL("Sub Bass Cut Off BiQuad", BIQUAD_SIZE, 0x91),
2330
2331 COEFF_RAM_CTL("Sub Bass Mix", COEFF_SIZE, 0x96),
2332
2333 COEFF_RAM_CTL("Sub Treb Extraction BiQuad 1", BIQUAD_SIZE, 0x97),
2334 COEFF_RAM_CTL("Sub Treb Extraction BiQuad 2", BIQUAD_SIZE, 0x9c),
2335
2336 COEFF_RAM_CTL("Sub Treb Non Linear Function 1", COEFF_SIZE, 0xa1),
2337 COEFF_RAM_CTL("Sub Treb Non Linear Function 2", COEFF_SIZE, 0xa2),
2338
2339 COEFF_RAM_CTL("Sub Treb Limiter BiQuad", BIQUAD_SIZE, 0xa3),
2340
2341 COEFF_RAM_CTL("Sub Treb Cut Off BiQuad", BIQUAD_SIZE, 0xa8),
2342
2343 COEFF_RAM_CTL("Sub Treb Mix", COEFF_SIZE, 0xad),
2344
2345 COEFF_RAM_CTL("Sub 3D", COEFF_SIZE, 0xae),
2346
2347 COEFF_RAM_CTL("Sub 3D Mix", COEFF_SIZE, 0xaf),
2348
2349 COEFF_RAM_CTL("Sub MBC 1 BiQuad 1", BIQUAD_SIZE, 0xb0),
2350 COEFF_RAM_CTL("Sub MBC 1 BiQuad 2", BIQUAD_SIZE, 0xb5),
2351
2352 COEFF_RAM_CTL("Sub MBC 2 BiQuad 1", BIQUAD_SIZE, 0xba),
2353 COEFF_RAM_CTL("Sub MBC 2 BiQuad 2", BIQUAD_SIZE, 0xbf),
2354
2355 COEFF_RAM_CTL("Sub MBC 3 BiQuad 1", BIQUAD_SIZE, 0xc4),
2356 COEFF_RAM_CTL("Sub MBC 3 BiQuad 2", BIQUAD_SIZE, 0xc9),
2357};
2358
2359static struct snd_soc_dapm_widget const tscs454_dapm_widgets[] = {
2360 /* R_PLLCTL PG 0 ADDR 0x15 */
2361 SND_SOC_DAPM_SUPPLY("PLL 1 Power", R_PLLCTL, FB_PLLCTL_PU_PLL1, 0,
2362 pll_power_event,
2363 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
2364 SND_SOC_DAPM_SUPPLY("PLL 2 Power", R_PLLCTL, FB_PLLCTL_PU_PLL2, 0,
2365 pll_power_event,
2366 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
2367 /* R_I2SPINC0 PG 0 ADDR 0x22 */
2368 SND_SOC_DAPM_AIF_OUT("DAI 3 Out", "DAI 3 Capture", 0,
2369 R_I2SPINC0, FB_I2SPINC0_SDO3TRI, 1),
2370 SND_SOC_DAPM_AIF_OUT("DAI 2 Out", "DAI 2 Capture", 0,
2371 R_I2SPINC0, FB_I2SPINC0_SDO2TRI, 1),
2372 SND_SOC_DAPM_AIF_OUT("DAI 1 Out", "DAI 1 Capture", 0,
2373 R_I2SPINC0, FB_I2SPINC0_SDO1TRI, 1),
2374 /* R_PWRM0 PG 0 ADDR 0x33 */
2375 SND_SOC_DAPM_ADC("Input Processor Channel 3", NULL,
2376 R_PWRM0, FB_PWRM0_INPROC3PU, 0),
2377 SND_SOC_DAPM_ADC("Input Processor Channel 2", NULL,
2378 R_PWRM0, FB_PWRM0_INPROC2PU, 0),
2379 SND_SOC_DAPM_ADC("Input Processor Channel 1", NULL,
2380 R_PWRM0, FB_PWRM0_INPROC1PU, 0),
2381 SND_SOC_DAPM_ADC("Input Processor Channel 0", NULL,
2382 R_PWRM0, FB_PWRM0_INPROC0PU, 0),
2383 SND_SOC_DAPM_SUPPLY("Mic Bias 2",
2384 R_PWRM0, FB_PWRM0_MICB2PU, 0, NULL, 0),
2385 SND_SOC_DAPM_SUPPLY("Mic Bias 1", R_PWRM0,
2386 FB_PWRM0_MICB1PU, 0, NULL, 0),
2387 /* R_PWRM1 PG 0 ADDR 0x34 */
2388 SND_SOC_DAPM_SUPPLY("Sub Power", R_PWRM1, FB_PWRM1_SUBPU, 0, NULL, 0),
2389 SND_SOC_DAPM_SUPPLY("Headphone Left Power",
2390 R_PWRM1, FB_PWRM1_HPLPU, 0, NULL, 0),
2391 SND_SOC_DAPM_SUPPLY("Headphone Right Power",
2392 R_PWRM1, FB_PWRM1_HPRPU, 0, NULL, 0),
2393 SND_SOC_DAPM_SUPPLY("Speaker Left Power",
2394 R_PWRM1, FB_PWRM1_SPKLPU, 0, NULL, 0),
2395 SND_SOC_DAPM_SUPPLY("Speaker Right Power",
2396 R_PWRM1, FB_PWRM1_SPKRPU, 0, NULL, 0),
2397 SND_SOC_DAPM_SUPPLY("Differential Input 2 Power",
2398 R_PWRM1, FB_PWRM1_D2S2PU, 0, NULL, 0),
2399 SND_SOC_DAPM_SUPPLY("Differential Input 1 Power",
2400 R_PWRM1, FB_PWRM1_D2S1PU, 0, NULL, 0),
2401 /* R_PWRM2 PG 0 ADDR 0x35 */
2402 SND_SOC_DAPM_SUPPLY("DAI 3 Out Power",
2403 R_PWRM2, FB_PWRM2_I2S3OPU, 0, NULL, 0),
2404 SND_SOC_DAPM_SUPPLY("DAI 2 Out Power",
2405 R_PWRM2, FB_PWRM2_I2S2OPU, 0, NULL, 0),
2406 SND_SOC_DAPM_SUPPLY("DAI 1 Out Power",
2407 R_PWRM2, FB_PWRM2_I2S1OPU, 0, NULL, 0),
2408 SND_SOC_DAPM_SUPPLY("DAI 3 In Power",
2409 R_PWRM2, FB_PWRM2_I2S3IPU, 0, NULL, 0),
2410 SND_SOC_DAPM_SUPPLY("DAI 2 In Power",
2411 R_PWRM2, FB_PWRM2_I2S2IPU, 0, NULL, 0),
2412 SND_SOC_DAPM_SUPPLY("DAI 1 In Power",
2413 R_PWRM2, FB_PWRM2_I2S1IPU, 0, NULL, 0),
2414 /* R_PWRM3 PG 0 ADDR 0x36 */
2415 SND_SOC_DAPM_SUPPLY("Line Out Left Power",
2416 R_PWRM3, FB_PWRM3_LLINEPU, 0, NULL, 0),
2417 SND_SOC_DAPM_SUPPLY("Line Out Right Power",
2418 R_PWRM3, FB_PWRM3_RLINEPU, 0, NULL, 0),
2419 /* R_PWRM4 PG 0 ADDR 0x37 */
2420 SND_SOC_DAPM_DAC("Sub", NULL, R_PWRM4, FB_PWRM4_OPSUBPU, 0),
2421 SND_SOC_DAPM_DAC("DAC Left", NULL, R_PWRM4, FB_PWRM4_OPDACLPU, 0),
2422 SND_SOC_DAPM_DAC("DAC Right", NULL, R_PWRM4, FB_PWRM4_OPDACRPU, 0),
2423 SND_SOC_DAPM_DAC("ClassD Left", NULL, R_PWRM4, FB_PWRM4_OPSPKLPU, 0),
2424 SND_SOC_DAPM_DAC("ClassD Right", NULL, R_PWRM4, FB_PWRM4_OPSPKRPU, 0),
2425 /* R_AUDIOMUX1 PG 0 ADDR 0x3A */
2426 SND_SOC_DAPM_MUX("DAI 2 Out Mux", SND_SOC_NOPM, 0, 0,
2427 &dai2_mux_dapm_enum),
2428 SND_SOC_DAPM_MUX("DAI 1 Out Mux", SND_SOC_NOPM, 0, 0,
2429 &dai1_mux_dapm_enum),
2430 /* R_AUDIOMUX2 PG 0 ADDR 0x3B */
2431 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
2432 &dac_mux_dapm_enum),
2433 SND_SOC_DAPM_MUX("DAI 3 Out Mux", SND_SOC_NOPM, 0, 0,
2434 &dai3_mux_dapm_enum),
2435 /* R_AUDIOMUX3 PG 0 ADDR 0x3C */
2436 SND_SOC_DAPM_MUX("Sub Mux", SND_SOC_NOPM, 0, 0,
2437 &sub_mux_dapm_enum),
2438 SND_SOC_DAPM_MUX("Speaker Mux", SND_SOC_NOPM, 0, 0,
2439 &classd_mux_dapm_enum),
2440 /* R_HSDCTL1 PG 1 ADDR 0x01 */
2441 SND_SOC_DAPM_SUPPLY("GHS Detect Power", R_HSDCTL1,
2442 FB_HSDCTL1_CON_DET_PWD, 1, NULL, 0),
2443 /* R_CH0AIC PG 1 ADDR 0x06 */
2444 SND_SOC_DAPM_MUX("Input Boost Channel 0 Mux", SND_SOC_NOPM, 0, 0,
2445 &in_bst_mux_ch0_dapm_enum),
2446 SND_SOC_DAPM_MUX("ADC Channel 0 Mux", SND_SOC_NOPM, 0, 0,
2447 &adc_mux_ch0_dapm_enum),
2448 SND_SOC_DAPM_MUX("Input Processor Channel 0 Mux", SND_SOC_NOPM, 0, 0,
2449 &in_proc_mux_ch0_dapm_enum),
2450 /* R_CH1AIC PG 1 ADDR 0x07 */
2451 SND_SOC_DAPM_MUX("Input Boost Channel 1 Mux", SND_SOC_NOPM, 0, 0,
2452 &in_bst_mux_ch1_dapm_enum),
2453 SND_SOC_DAPM_MUX("ADC Channel 1 Mux", SND_SOC_NOPM, 0, 0,
2454 &adc_mux_ch1_dapm_enum),
2455 SND_SOC_DAPM_MUX("Input Processor Channel 1 Mux", SND_SOC_NOPM, 0, 0,
2456 &in_proc_mux_ch1_dapm_enum),
2457 /* Virtual */
2458 SND_SOC_DAPM_AIF_IN("DAI 3 In", "DAI 3 Playback", 0,
2459 SND_SOC_NOPM, 0, 0),
2460 SND_SOC_DAPM_AIF_IN("DAI 2 In", "DAI 2 Playback", 0,
2461 SND_SOC_NOPM, 0, 0),
2462 SND_SOC_DAPM_AIF_IN("DAI 1 In", "DAI 1 Playback", 0,
2463 SND_SOC_NOPM, 0, 0),
2464 SND_SOC_DAPM_SUPPLY("PLLs", SND_SOC_NOPM, 0, 0, NULL, 0),
2465 SND_SOC_DAPM_OUTPUT("Sub Out"),
2466 SND_SOC_DAPM_OUTPUT("Headphone Left"),
2467 SND_SOC_DAPM_OUTPUT("Headphone Right"),
2468 SND_SOC_DAPM_OUTPUT("Speaker Left"),
2469 SND_SOC_DAPM_OUTPUT("Speaker Right"),
2470 SND_SOC_DAPM_OUTPUT("Line Out Left"),
2471 SND_SOC_DAPM_OUTPUT("Line Out Right"),
2472 SND_SOC_DAPM_INPUT("D2S 2"),
2473 SND_SOC_DAPM_INPUT("D2S 1"),
2474 SND_SOC_DAPM_INPUT("Line In 1 Left"),
2475 SND_SOC_DAPM_INPUT("Line In 1 Right"),
2476 SND_SOC_DAPM_INPUT("Line In 2 Left"),
2477 SND_SOC_DAPM_INPUT("Line In 2 Right"),
2478 SND_SOC_DAPM_INPUT("Line In 3 Left"),
2479 SND_SOC_DAPM_INPUT("Line In 3 Right"),
2480 SND_SOC_DAPM_INPUT("DMic 1"),
2481 SND_SOC_DAPM_INPUT("DMic 2"),
2482
2483 SND_SOC_DAPM_MUX("CH 0_1 Mux", SND_SOC_NOPM, 0, 0,
2484 &ch_0_1_mux_dapm_enum),
2485 SND_SOC_DAPM_MUX("CH 2_3 Mux", SND_SOC_NOPM, 0, 0,
2486 &ch_2_3_mux_dapm_enum),
2487 SND_SOC_DAPM_MUX("CH 4_5 Mux", SND_SOC_NOPM, 0, 0,
2488 &ch_4_5_mux_dapm_enum),
2489};
2490
2491static struct snd_soc_dapm_route const tscs454_intercon[] = {
2492 /* PLLs */
2493 {"PLLs", NULL, "PLL 1 Power", pll_connected},
2494 {"PLLs", NULL, "PLL 2 Power", pll_connected},
2495 /* Inputs */
2496 {"DAI 3 In", NULL, "DAI 3 In Power"},
2497 {"DAI 2 In", NULL, "DAI 2 In Power"},
2498 {"DAI 1 In", NULL, "DAI 1 In Power"},
2499 /* Outputs */
2500 {"DAI 3 Out", NULL, "DAI 3 Out Power"},
2501 {"DAI 2 Out", NULL, "DAI 2 Out Power"},
2502 {"DAI 1 Out", NULL, "DAI 1 Out Power"},
2503 /* Ch Muxing */
2504 {"CH 0_1 Mux", "DAI 1", "DAI 1 In"},
2505 {"CH 0_1 Mux", "TDM 0_1", "DAI 1 In"},
2506 {"CH 2_3 Mux", "DAI 2", "DAI 2 In"},
2507 {"CH 2_3 Mux", "TDM 2_3", "DAI 1 In"},
2508 {"CH 4_5 Mux", "DAI 3", "DAI 2 In"},
2509 {"CH 4_5 Mux", "TDM 4_5", "DAI 1 In"},
2510 /* In/Out Muxing */
2511 {"DAI 1 Out Mux", "CH 0_1", "CH 0_1 Mux"},
2512 {"DAI 1 Out Mux", "CH 2_3", "CH 2_3 Mux"},
2513 {"DAI 1 Out Mux", "CH 4_5", "CH 4_5 Mux"},
2514 {"DAI 2 Out Mux", "CH 0_1", "CH 0_1 Mux"},
2515 {"DAI 2 Out Mux", "CH 2_3", "CH 2_3 Mux"},
2516 {"DAI 2 Out Mux", "CH 4_5", "CH 4_5 Mux"},
2517 {"DAI 3 Out Mux", "CH 0_1", "CH 0_1 Mux"},
2518 {"DAI 3 Out Mux", "CH 2_3", "CH 2_3 Mux"},
2519 {"DAI 3 Out Mux", "CH 4_5", "CH 4_5 Mux"},
2520 /******************
2521 * Playback Paths *
2522 ******************/
2523 /* DAC Path */
2524 {"DAC Mux", "CH 4_5", "CH 4_5 Mux"},
2525 {"DAC Mux", "CH 2_3", "CH 2_3 Mux"},
2526 {"DAC Mux", "CH 0_1", "CH 0_1 Mux"},
2527 {"DAC Left", NULL, "DAC Mux"},
2528 {"DAC Right", NULL, "DAC Mux"},
2529 {"DAC Left", NULL, "PLLs"},
2530 {"DAC Right", NULL, "PLLs"},
2531 {"Headphone Left", NULL, "Headphone Left Power"},
2532 {"Headphone Right", NULL, "Headphone Right Power"},
2533 {"Headphone Left", NULL, "DAC Left"},
2534 {"Headphone Right", NULL, "DAC Right"},
2535 /* Line Out */
2536 {"Line Out Left", NULL, "Line Out Left Power"},
2537 {"Line Out Right", NULL, "Line Out Right Power"},
2538 {"Line Out Left", NULL, "DAC Left"},
2539 {"Line Out Right", NULL, "DAC Right"},
2540 /* ClassD Path */
2541 {"Speaker Mux", "CH 4_5", "CH 4_5 Mux"},
2542 {"Speaker Mux", "CH 2_3", "CH 2_3 Mux"},
2543 {"Speaker Mux", "CH 0_1", "CH 0_1 Mux"},
2544 {"ClassD Left", NULL, "Speaker Mux"},
2545 {"ClassD Right", NULL, "Speaker Mux"},
2546 {"ClassD Left", NULL, "PLLs"},
2547 {"ClassD Right", NULL, "PLLs"},
2548 {"Speaker Left", NULL, "Speaker Left Power"},
2549 {"Speaker Right", NULL, "Speaker Right Power"},
2550 {"Speaker Left", NULL, "ClassD Left"},
2551 {"Speaker Right", NULL, "ClassD Right"},
2552 /* Sub Path */
2553 {"Sub Mux", "CH 4", "CH 4_5 Mux"},
2554 {"Sub Mux", "CH 5", "CH 4_5 Mux"},
2555 {"Sub Mux", "CH 4 + 5", "CH 4_5 Mux"},
2556 {"Sub Mux", "CH 2", "CH 2_3 Mux"},
2557 {"Sub Mux", "CH 3", "CH 2_3 Mux"},
2558 {"Sub Mux", "CH 2 + 3", "CH 2_3 Mux"},
2559 {"Sub Mux", "CH 0", "CH 0_1 Mux"},
2560 {"Sub Mux", "CH 1", "CH 0_1 Mux"},
2561 {"Sub Mux", "CH 0 + 1", "CH 0_1 Mux"},
2562 {"Sub Mux", "ADC/DMic 1 Left", "Input Processor Channel 0"},
2563 {"Sub Mux", "ADC/DMic 1 Right", "Input Processor Channel 1"},
2564 {"Sub Mux", "ADC/DMic 1 Left Plus Right", "Input Processor Channel 0"},
2565 {"Sub Mux", "ADC/DMic 1 Left Plus Right", "Input Processor Channel 1"},
2566 {"Sub Mux", "DMic 2 Left", "DMic 2"},
2567 {"Sub Mux", "DMic 2 Right", "DMic 2"},
2568 {"Sub Mux", "DMic 2 Left Plus Right", "DMic 2"},
2569 {"Sub Mux", "ClassD Left", "ClassD Left"},
2570 {"Sub Mux", "ClassD Right", "ClassD Right"},
2571 {"Sub Mux", "ClassD Left Plus Right", "ClassD Left"},
2572 {"Sub Mux", "ClassD Left Plus Right", "ClassD Right"},
2573 {"Sub", NULL, "Sub Mux"},
2574 {"Sub", NULL, "PLLs"},
2575 {"Sub Out", NULL, "Sub Power"},
2576 {"Sub Out", NULL, "Sub"},
2577 /*****************
2578 * Capture Paths *
2579 *****************/
2580 {"Input Boost Channel 0 Mux", "Input 3", "Line In 3 Left"},
2581 {"Input Boost Channel 0 Mux", "Input 2", "Line In 2 Left"},
2582 {"Input Boost Channel 0 Mux", "Input 1", "Line In 1 Left"},
2583 {"Input Boost Channel 0 Mux", "D2S", "D2S 1"},
2584
2585 {"Input Boost Channel 1 Mux", "Input 3", "Line In 3 Right"},
2586 {"Input Boost Channel 1 Mux", "Input 2", "Line In 2 Right"},
2587 {"Input Boost Channel 1 Mux", "Input 1", "Line In 1 Right"},
2588 {"Input Boost Channel 1 Mux", "D2S", "D2S 2"},
2589
2590 {"ADC Channel 0 Mux", "Input 3 Boost Bypass", "Line In 3 Left"},
2591 {"ADC Channel 0 Mux", "Input 2 Boost Bypass", "Line In 2 Left"},
2592 {"ADC Channel 0 Mux", "Input 1 Boost Bypass", "Line In 1 Left"},
2593 {"ADC Channel 0 Mux", "Input Boost", "Input Boost Channel 0 Mux"},
2594
2595 {"ADC Channel 1 Mux", "Input 3 Boost Bypass", "Line In 3 Right"},
2596 {"ADC Channel 1 Mux", "Input 2 Boost Bypass", "Line In 2 Right"},
2597 {"ADC Channel 1 Mux", "Input 1 Boost Bypass", "Line In 1 Right"},
2598 {"ADC Channel 1 Mux", "Input Boost", "Input Boost Channel 1 Mux"},
2599
2600 {"Input Processor Channel 0 Mux", "ADC", "ADC Channel 0 Mux"},
2601 {"Input Processor Channel 0 Mux", "DMic", "DMic 1"},
2602
2603 {"Input Processor Channel 0", NULL, "PLLs"},
2604 {"Input Processor Channel 0", NULL, "Input Processor Channel 0 Mux"},
2605
2606 {"Input Processor Channel 1 Mux", "ADC", "ADC Channel 1 Mux"},
2607 {"Input Processor Channel 1 Mux", "DMic", "DMic 1"},
2608
2609 {"Input Processor Channel 1", NULL, "PLLs"},
2610 {"Input Processor Channel 1", NULL, "Input Processor Channel 1 Mux"},
2611
2612 {"Input Processor Channel 2", NULL, "PLLs"},
2613 {"Input Processor Channel 2", NULL, "DMic 2"},
2614
2615 {"Input Processor Channel 3", NULL, "PLLs"},
2616 {"Input Processor Channel 3", NULL, "DMic 2"},
2617
2618 {"DAI 1 Out Mux", "ADC/DMic 1", "Input Processor Channel 0"},
2619 {"DAI 1 Out Mux", "ADC/DMic 1", "Input Processor Channel 1"},
2620 {"DAI 1 Out Mux", "DMic 2", "Input Processor Channel 2"},
2621 {"DAI 1 Out Mux", "DMic 2", "Input Processor Channel 3"},
2622
2623 {"DAI 2 Out Mux", "ADC/DMic 1", "Input Processor Channel 0"},
2624 {"DAI 2 Out Mux", "ADC/DMic 1", "Input Processor Channel 1"},
2625 {"DAI 2 Out Mux", "DMic 2", "Input Processor Channel 2"},
2626 {"DAI 2 Out Mux", "DMic 2", "Input Processor Channel 3"},
2627
2628 {"DAI 3 Out Mux", "ADC/DMic 1", "Input Processor Channel 0"},
2629 {"DAI 3 Out Mux", "ADC/DMic 1", "Input Processor Channel 1"},
2630 {"DAI 3 Out Mux", "DMic 2", "Input Processor Channel 2"},
2631 {"DAI 3 Out Mux", "DMic 2", "Input Processor Channel 3"},
2632
2633 {"DAI 1 Out", NULL, "DAI 1 Out Mux"},
2634 {"DAI 2 Out", NULL, "DAI 2 Out Mux"},
2635 {"DAI 3 Out", NULL, "DAI 3 Out Mux"},
2636};
2637
2638/* This is used when BCLK is sourcing the PLLs */
2639static int tscs454_set_sysclk(struct snd_soc_dai *dai,
2640 int clk_id, unsigned int freq, int dir)
2641{
2642 struct snd_soc_component *component = dai->component;
2643 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
2644 unsigned int val;
2645 int bclk_dai;
2646 int ret;
2647
2648 dev_dbg(component->dev, "%s(): freq = %u\n", __func__, freq);
2649
2650 ret = snd_soc_component_read(component, R_PLLCTL, &val);
2651 if (ret < 0)
2652 return ret;
2653
2654 bclk_dai = (val & FM_PLLCTL_BCLKSEL) >> FB_PLLCTL_BCLKSEL;
2655 if (bclk_dai != dai->id)
2656 return 0;
2657
2658 tscs454->bclk_freq = freq;
2659 return set_sysclk(component);
2660}
2661
2662static int tscs454_set_bclk_ratio(struct snd_soc_dai *dai,
2663 unsigned int ratio)
2664{
2665 unsigned int mask;
2666 int ret;
2667 struct snd_soc_component *component = dai->component;
2668 unsigned int val;
2669 int shift;
2670
2671 dev_dbg(component->dev, "set_bclk_ratio() id = %d ratio = %u\n",
2672 dai->id, ratio);
2673
2674 switch (dai->id) {
2675 case TSCS454_DAI1_ID:
2676 mask = FM_I2SCMC_BCMP1;
2677 shift = FB_I2SCMC_BCMP1;
2678 break;
2679 case TSCS454_DAI2_ID:
2680 mask = FM_I2SCMC_BCMP2;
2681 shift = FB_I2SCMC_BCMP2;
2682 break;
2683 case TSCS454_DAI3_ID:
2684 mask = FM_I2SCMC_BCMP3;
2685 shift = FB_I2SCMC_BCMP3;
2686 break;
2687 default:
2688 ret = -EINVAL;
2689 dev_err(component->dev, "Unknown audio interface (%d)\n", ret);
2690 return ret;
2691 }
2692
2693 switch (ratio) {
2694 case 32:
2695 val = I2SCMC_BCMP_32X;
2696 break;
2697 case 40:
2698 val = I2SCMC_BCMP_40X;
2699 break;
2700 case 64:
2701 val = I2SCMC_BCMP_64X;
2702 break;
2703 default:
2704 ret = -EINVAL;
2705 dev_err(component->dev, "Unsupported bclk ratio (%d)\n", ret);
2706 return ret;
2707 }
2708
2709 ret = snd_soc_component_update_bits(component,
2710 R_I2SCMC, mask, val << shift);
2711 if (ret < 0) {
2712 dev_err(component->dev,
2713 "Failed to set DAI BCLK ratio (%d)\n", ret);
2714 return ret;
2715 }
2716
2717 return 0;
2718}
2719
2720static inline int set_aif_master_from_fmt(struct snd_soc_component *component,
2721 struct aif *aif, unsigned int fmt)
2722{
2723 int ret;
2724
2725 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2726 case SND_SOC_DAIFMT_CBM_CFM:
2727 aif->master = true;
2728 break;
2729 case SND_SOC_DAIFMT_CBS_CFS:
2730 aif->master = false;
2731 break;
2732 default:
2733 ret = -EINVAL;
2734 dev_err(component->dev, "Unsupported format (%d)\n", ret);
2735 return ret;
2736 }
2737
2738 return 0;
2739}
2740
2741static inline int set_aif_tdm_delay(struct snd_soc_component *component,
2742 unsigned int dai_id, bool delay)
2743{
2744 unsigned int reg;
2745 int ret;
2746
2747 switch (dai_id) {
2748 case TSCS454_DAI1_ID:
2749 reg = R_TDMCTL0;
2750 break;
2751 case TSCS454_DAI2_ID:
2752 reg = R_PCMP2CTL0;
2753 break;
2754 case TSCS454_DAI3_ID:
2755 reg = R_PCMP3CTL0;
2756 break;
2757 default:
2758 ret = -EINVAL;
2759 dev_err(component->dev,
2760 "DAI %d unknown (%d)\n", dai_id + 1, ret);
2761 return ret;
2762 }
2763 ret = snd_soc_component_update_bits(component,
2764 reg, FM_TDMCTL0_BDELAY, delay);
2765 if (ret < 0) {
2766 dev_err(component->dev, "Failed to setup tdm format (%d)\n",
2767 ret);
2768 return ret;
2769 }
2770
2771 return 0;
2772}
2773
2774static inline int set_aif_format_from_fmt(struct snd_soc_component *component,
2775 unsigned int dai_id, unsigned int fmt)
2776{
2777 unsigned int reg;
2778 unsigned int val;
2779 int ret;
2780
2781 switch (dai_id) {
2782 case TSCS454_DAI1_ID:
2783 reg = R_I2SP1CTL;
2784 break;
2785 case TSCS454_DAI2_ID:
2786 reg = R_I2SP2CTL;
2787 break;
2788 case TSCS454_DAI3_ID:
2789 reg = R_I2SP3CTL;
2790 break;
2791 default:
2792 ret = -EINVAL;
2793 dev_err(component->dev,
2794 "DAI %d unknown (%d)\n", dai_id + 1, ret);
2795 return ret;
2796 }
2797
2798 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2799 case SND_SOC_DAIFMT_RIGHT_J:
2800 val = FV_FORMAT_RIGHT;
2801 break;
2802 case SND_SOC_DAIFMT_LEFT_J:
2803 val = FV_FORMAT_LEFT;
2804 break;
2805 case SND_SOC_DAIFMT_I2S:
2806 val = FV_FORMAT_I2S;
2807 break;
2808 case SND_SOC_DAIFMT_DSP_A:
2809 ret = set_aif_tdm_delay(component, dai_id, true);
2810 if (ret < 0)
2811 return ret;
2812 val = FV_FORMAT_TDM;
2813 break;
2814 case SND_SOC_DAIFMT_DSP_B:
2815 ret = set_aif_tdm_delay(component, dai_id, false);
2816 if (ret < 0)
2817 return ret;
2818 val = FV_FORMAT_TDM;
2819 break;
2820 default:
2821 ret = -EINVAL;
2822 dev_err(component->dev, "Format unsupported (%d)\n", ret);
2823 return ret;
2824 }
2825
2826 ret = snd_soc_component_update_bits(component,
2827 reg, FM_I2SPCTL_FORMAT, val);
2828 if (ret < 0) {
2829 dev_err(component->dev, "Failed to set DAI %d format (%d)\n",
2830 dai_id + 1, ret);
2831 return ret;
2832 }
2833
2834 return 0;
2835}
2836
2837static inline int
2838set_aif_clock_format_from_fmt(struct snd_soc_component *component,
2839 unsigned int dai_id, unsigned int fmt)
2840{
2841 unsigned int reg;
2842 unsigned int val;
2843 int ret;
2844
2845 switch (dai_id) {
2846 case TSCS454_DAI1_ID:
2847 reg = R_I2SP1CTL;
2848 break;
2849 case TSCS454_DAI2_ID:
2850 reg = R_I2SP2CTL;
2851 break;
2852 case TSCS454_DAI3_ID:
2853 reg = R_I2SP3CTL;
2854 break;
2855 default:
2856 ret = -EINVAL;
2857 dev_err(component->dev,
2858 "DAI %d unknown (%d)\n", dai_id + 1, ret);
2859 return ret;
2860 }
2861
2862 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2863 case SND_SOC_DAIFMT_NB_NF:
2864 val = FV_BCLKP_NOT_INVERTED | FV_LRCLKP_NOT_INVERTED;
2865 break;
2866 case SND_SOC_DAIFMT_NB_IF:
2867 val = FV_BCLKP_NOT_INVERTED | FV_LRCLKP_INVERTED;
2868 break;
2869 case SND_SOC_DAIFMT_IB_NF:
2870 val = FV_BCLKP_INVERTED | FV_LRCLKP_NOT_INVERTED;
2871 break;
2872 case SND_SOC_DAIFMT_IB_IF:
2873 val = FV_BCLKP_INVERTED | FV_LRCLKP_INVERTED;
2874 break;
2875 default:
2876 ret = -EINVAL;
2877 dev_err(component->dev, "Format unknown (%d)\n", ret);
2878 return ret;
2879 }
2880
2881 ret = snd_soc_component_update_bits(component, reg,
2882 FM_I2SPCTL_BCLKP | FM_I2SPCTL_LRCLKP, val);
2883 if (ret < 0) {
2884 dev_err(component->dev,
2885 "Failed to set clock polarity for DAI%d (%d)\n",
2886 dai_id + 1, ret);
2887 return ret;
2888 }
2889
2890 return 0;
2891}
2892
2893static int tscs454_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2894{
2895 struct snd_soc_component *component = dai->component;
2896 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
2897 struct aif *aif = &tscs454->aifs[dai->id];
2898 int ret;
2899
2900 ret = set_aif_master_from_fmt(component, aif, fmt);
2901 if (ret < 0)
2902 return ret;
2903
2904 ret = set_aif_format_from_fmt(component, dai->id, fmt);
2905 if (ret < 0)
2906 return ret;
2907
2908 ret = set_aif_clock_format_from_fmt(component, dai->id, fmt);
2909 if (ret < 0)
2910 return ret;
2911
2912 return 0;
2913}
2914
2915static int tscs454_dai1_set_tdm_slot(struct snd_soc_dai *dai,
2916 unsigned int tx_mask, unsigned int rx_mask, int slots,
2917 int slot_width)
2918{
2919 struct snd_soc_component *component = dai->component;
2920 unsigned int val;
2921 int ret;
2922
2923 if (!slots)
2924 return 0;
2925
2926 if (tx_mask >= (1 << slots) || rx_mask >= (1 << slots)) {
2927 ret = -EINVAL;
2928 dev_err(component->dev, "Invalid TDM slot mask (%d)\n", ret);
2929 return ret;
2930 }
2931
2932 switch (slots) {
2933 case 2:
2934 val = FV_TDMSO_2 | FV_TDMSI_2;
2935 break;
2936 case 4:
2937 val = FV_TDMSO_4 | FV_TDMSI_4;
2938 break;
2939 case 6:
2940 val = FV_TDMSO_6 | FV_TDMSI_6;
2941 break;
2942 default:
2943 ret = -EINVAL;
2944 dev_err(component->dev, "Invalid number of slots (%d)\n", ret);
2945 return ret;
2946 }
2947
2948 switch (slot_width) {
2949 case 16:
2950 val = val | FV_TDMDSS_16;
2951 break;
2952 case 24:
2953 val = val | FV_TDMDSS_24;
2954 break;
2955 case 32:
2956 val = val | FV_TDMDSS_32;
2957 break;
2958 default:
2959 ret = -EINVAL;
2960 dev_err(component->dev, "Invalid TDM slot width (%d)\n", ret);
2961 return ret;
2962 }
2963 ret = snd_soc_component_write(component, R_TDMCTL1, val);
2964 if (ret < 0) {
2965 dev_err(component->dev, "Failed to set slots (%d)\n", ret);
2966 return ret;
2967 }
2968
2969 return 0;
2970}
2971
2972static int tscs454_dai23_set_tdm_slot(struct snd_soc_dai *dai,
2973 unsigned int tx_mask, unsigned int rx_mask, int slots,
2974 int slot_width)
2975{
2976 struct snd_soc_component *component = dai->component;
2977 unsigned int reg;
2978 unsigned int val;
2979 int ret;
2980
2981 if (!slots)
2982 return 0;
2983
2984 if (tx_mask >= (1 << slots) || rx_mask >= (1 << slots)) {
2985 ret = -EINVAL;
2986 dev_err(component->dev, "Invalid TDM slot mask (%d)\n", ret);
2987 return ret;
2988 }
2989
2990 switch (dai->id) {
2991 case TSCS454_DAI2_ID:
2992 reg = R_PCMP2CTL1;
2993 break;
2994 case TSCS454_DAI3_ID:
2995 reg = R_PCMP3CTL1;
2996 break;
2997 default:
2998 ret = -EINVAL;
2999 dev_err(component->dev, "Unrecognized interface %d (%d)\n",
3000 dai->id, ret);
3001 return ret;
3002 }
3003
3004 switch (slots) {
3005 case 1:
3006 val = FV_PCMSOP_1 | FV_PCMSIP_1;
3007 break;
3008 case 2:
3009 val = FV_PCMSOP_2 | FV_PCMSIP_2;
3010 break;
3011 default:
3012 ret = -EINVAL;
3013 dev_err(component->dev, "Invalid number of slots (%d)\n", ret);
3014 return ret;
3015 }
3016
3017 switch (slot_width) {
3018 case 16:
3019 val = val | FV_PCMDSSP_16;
3020 break;
3021 case 24:
3022 val = val | FV_PCMDSSP_24;
3023 break;
3024 case 32:
3025 val = val | FV_PCMDSSP_32;
3026 break;
3027 default:
3028 ret = -EINVAL;
3029 dev_err(component->dev, "Invalid TDM slot width (%d)\n", ret);
3030 return ret;
3031 }
3032 ret = snd_soc_component_write(component, reg, val);
3033 if (ret < 0) {
3034 dev_err(component->dev, "Failed to set slots (%d)\n", ret);
3035 return ret;
3036 }
3037
3038 return 0;
3039}
3040
3041static int set_aif_fs(struct snd_soc_component *component,
3042 unsigned int id,
3043 unsigned int rate)
3044{
3045 unsigned int reg;
3046 unsigned int br;
3047 unsigned int bm;
3048 int ret;
3049
3050 switch (rate) {
3051 case 8000:
3052 br = FV_I2SMBR_32;
3053 bm = FV_I2SMBM_0PT25;
3054 break;
3055 case 16000:
3056 br = FV_I2SMBR_32;
3057 bm = FV_I2SMBM_0PT5;
3058 break;
3059 case 24000:
3060 br = FV_I2SMBR_48;
3061 bm = FV_I2SMBM_0PT5;
3062 break;
3063 case 32000:
3064 br = FV_I2SMBR_32;
3065 bm = FV_I2SMBM_1;
3066 break;
3067 case 48000:
3068 br = FV_I2SMBR_48;
3069 bm = FV_I2SMBM_1;
3070 break;
3071 case 96000:
3072 br = FV_I2SMBR_48;
3073 bm = FV_I2SMBM_2;
3074 break;
3075 case 11025:
3076 br = FV_I2SMBR_44PT1;
3077 bm = FV_I2SMBM_0PT25;
3078 break;
3079 case 22050:
3080 br = FV_I2SMBR_44PT1;
3081 bm = FV_I2SMBM_0PT5;
3082 break;
3083 case 44100:
3084 br = FV_I2SMBR_44PT1;
3085 bm = FV_I2SMBM_1;
3086 break;
3087 case 88200:
3088 br = FV_I2SMBR_44PT1;
3089 bm = FV_I2SMBM_2;
3090 break;
3091 default:
3092 ret = -EINVAL;
3093 dev_err(component->dev, "Unsupported sample rate (%d)\n", ret);
3094 return ret;
3095 }
3096
3097 switch (id) {
3098 case TSCS454_DAI1_ID:
3099 reg = R_I2S1MRATE;
3100 break;
3101 case TSCS454_DAI2_ID:
3102 reg = R_I2S2MRATE;
3103 break;
3104 case TSCS454_DAI3_ID:
3105 reg = R_I2S3MRATE;
3106 break;
3107 default:
3108 ret = -EINVAL;
3109 dev_err(component->dev, "DAI ID not recognized (%d)\n", ret);
3110 return ret;
3111 }
3112
3113 ret = snd_soc_component_update_bits(component, reg,
3114 FM_I2SMRATE_I2SMBR | FM_I2SMRATE_I2SMBM, br|bm);
3115 if (ret < 0) {
3116 dev_err(component->dev,
3117 "Failed to update register (%d)\n", ret);
3118 return ret;
3119 }
3120
3121 return 0;
3122}
3123
3124static int set_aif_sample_format(struct snd_soc_component *component,
3125 snd_pcm_format_t format,
3126 int aif_id)
3127{
3128 unsigned int reg;
3129 unsigned int width;
3130 int ret;
3131
3132 switch (format) {
3133 case SNDRV_PCM_FORMAT_S16_LE:
3134 width = FV_WL_16;
3135 break;
3136 case SNDRV_PCM_FORMAT_S20_3LE:
3137 width = FV_WL_20;
3138 break;
3139 case SNDRV_PCM_FORMAT_S24_3LE:
3140 width = FV_WL_24;
3141 break;
3142 case SNDRV_PCM_FORMAT_S24_LE:
3143 case SNDRV_PCM_FORMAT_S32_LE:
3144 width = FV_WL_32;
3145 break;
3146 default:
3147 ret = -EINVAL;
3148 dev_err(component->dev, "Unsupported format width (%d)\n", ret);
3149 return ret;
3150 }
3151
3152 switch (aif_id) {
3153 case TSCS454_DAI1_ID:
3154 reg = R_I2SP1CTL;
3155 break;
3156 case TSCS454_DAI2_ID:
3157 reg = R_I2SP2CTL;
3158 break;
3159 case TSCS454_DAI3_ID:
3160 reg = R_I2SP3CTL;
3161 break;
3162 default:
3163 ret = -EINVAL;
3164 dev_err(component->dev, "AIF ID not recognized (%d)\n", ret);
3165 return ret;
3166 }
3167
3168 ret = snd_soc_component_update_bits(component,
3169 reg, FM_I2SPCTL_WL, width);
3170 if (ret < 0) {
3171 dev_err(component->dev,
3172 "Failed to set sample width (%d)\n", ret);
3173 return ret;
3174 }
3175
3176 return 0;
3177}
3178
3179static int tscs454_hw_params(struct snd_pcm_substream *substream,
3180 struct snd_pcm_hw_params *params,
3181 struct snd_soc_dai *dai)
3182{
3183 struct snd_soc_component *component = dai->component;
3184 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
3185 unsigned int fs = params_rate(params);
3186 struct aif *aif = &tscs454->aifs[dai->id];
3187 unsigned int val;
3188 int ret;
3189
3190 mutex_lock(&tscs454->aifs_status_lock);
3191
3192 dev_dbg(component->dev, "%s(): aif %d fs = %u\n", __func__,
3193 aif->id, fs);
3194
3195 if (!aif_active(&tscs454->aifs_status, aif->id)) {
3196 if (PLL_44_1K_RATE % fs)
3197 aif->pll = &tscs454->pll1;
3198 else
3199 aif->pll = &tscs454->pll2;
3200
3201 dev_dbg(component->dev, "Reserving pll %d for aif %d\n",
3202 aif->pll->id, aif->id);
3203
3204 reserve_pll(aif->pll);
3205 }
3206
3207 if (!aifs_active(&tscs454->aifs_status)) { /* First active aif */
3208 ret = snd_soc_component_read(component, R_ISRC, &val);
3209 if (ret < 0)
3210 goto exit;
3211
3212 if ((val & FM_ISRC_IBR) == FV_IBR_48)
3213 tscs454->internal_rate.pll = &tscs454->pll1;
3214 else
3215 tscs454->internal_rate.pll = &tscs454->pll2;
3216
3217 dev_dbg(component->dev, "Reserving pll %d for ir\n",
3218 tscs454->internal_rate.pll->id);
3219
3220 reserve_pll(tscs454->internal_rate.pll);
3221 }
3222
3223 ret = set_aif_fs(component, aif->id, fs);
3224 if (ret < 0) {
3225 dev_err(component->dev, "Failed to set aif fs (%d)\n", ret);
3226 goto exit;
3227 }
3228
3229 ret = set_aif_sample_format(component, params_format(params), aif->id);
3230 if (ret < 0) {
3231 dev_err(component->dev,
3232 "Failed to set aif sample format (%d)\n", ret);
3233 goto exit;
3234 }
3235
3236 set_aif_status_active(&tscs454->aifs_status, aif->id,
3237 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
3238
3239 dev_dbg(component->dev, "Set aif %d active. Streams status is 0x%x\n",
3240 aif->id, tscs454->aifs_status.streams);
3241
3242 ret = 0;
3243exit:
3244 mutex_unlock(&tscs454->aifs_status_lock);
3245
3246 return ret;
3247}
3248
3249static int tscs454_hw_free(struct snd_pcm_substream *substream,
3250 struct snd_soc_dai *dai)
3251{
3252 struct snd_soc_component *component = dai->component;
3253 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
3254 struct aif *aif = &tscs454->aifs[dai->id];
3255
3256 return aif_free(component, aif,
3257 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
3258}
3259
3260static int tscs454_prepare(struct snd_pcm_substream *substream,
3261 struct snd_soc_dai *dai)
3262{
3263 int ret;
3264 struct snd_soc_component *component = dai->component;
3265 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
3266 struct aif *aif = &tscs454->aifs[dai->id];
3267
3268 ret = aif_prepare(component, aif);
3269 if (ret < 0)
3270 return ret;
3271
3272 return 0;
3273}
3274
3275static struct snd_soc_dai_ops const tscs454_dai1_ops = {
3276 .set_sysclk = tscs454_set_sysclk,
3277 .set_bclk_ratio = tscs454_set_bclk_ratio,
3278 .set_fmt = tscs454_set_dai_fmt,
3279 .set_tdm_slot = tscs454_dai1_set_tdm_slot,
3280 .hw_params = tscs454_hw_params,
3281 .hw_free = tscs454_hw_free,
3282 .prepare = tscs454_prepare,
3283};
3284
3285static struct snd_soc_dai_ops const tscs454_dai23_ops = {
3286 .set_sysclk = tscs454_set_sysclk,
3287 .set_bclk_ratio = tscs454_set_bclk_ratio,
3288 .set_fmt = tscs454_set_dai_fmt,
3289 .set_tdm_slot = tscs454_dai23_set_tdm_slot,
3290 .hw_params = tscs454_hw_params,
3291 .hw_free = tscs454_hw_free,
3292 .prepare = tscs454_prepare,
3293};
3294
3295static int tscs454_probe(struct snd_soc_component *component)
3296{
3297 struct tscs454 *tscs454 = snd_soc_component_get_drvdata(component);
3298 unsigned int val;
3299 int ret = 0;
3300
3301 switch (tscs454->sysclk_src_id) {
3302 case PLL_INPUT_XTAL:
3303 val = FV_PLLISEL_XTAL;
3304 break;
3305 case PLL_INPUT_MCLK1:
3306 val = FV_PLLISEL_MCLK1;
3307 break;
3308 case PLL_INPUT_MCLK2:
3309 val = FV_PLLISEL_MCLK2;
3310 break;
3311 case PLL_INPUT_BCLK:
3312 val = FV_PLLISEL_BCLK;
3313 break;
3314 default:
3315 ret = -EINVAL;
3316 dev_err(component->dev, "Invalid sysclk src id (%d)\n", ret);
3317 return ret;
3318 }
3319
3320 ret = snd_soc_component_update_bits(component, R_PLLCTL,
3321 FM_PLLCTL_PLLISEL, val);
3322 if (ret < 0) {
3323 dev_err(component->dev, "Failed to set PLL input (%d)\n", ret);
3324 return ret;
3325 }
3326
3327 if (tscs454->sysclk_src_id < PLL_INPUT_BCLK)
3328 ret = set_sysclk(component);
3329
3330 return ret;
3331}
3332
3333static const struct snd_soc_component_driver soc_component_dev_tscs454 = {
3334 .probe = tscs454_probe,
3335 .dapm_widgets = tscs454_dapm_widgets,
3336 .num_dapm_widgets = ARRAY_SIZE(tscs454_dapm_widgets),
3337 .dapm_routes = tscs454_intercon,
3338 .num_dapm_routes = ARRAY_SIZE(tscs454_intercon),
3339 .controls = tscs454_snd_controls,
3340 .num_controls = ARRAY_SIZE(tscs454_snd_controls),
3341};
3342
3343#define TSCS454_RATES SNDRV_PCM_RATE_8000_96000
3344
3345#define TSCS454_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
3346 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE \
3347 | SNDRV_PCM_FMTBIT_S32_LE)
3348
3349static struct snd_soc_dai_driver tscs454_dais[] = {
3350 {
3351 .name = "tscs454-dai1",
3352 .id = TSCS454_DAI1_ID,
3353 .playback = {
3354 .stream_name = "DAI 1 Playback",
3355 .channels_min = 1,
3356 .channels_max = 6,
3357 .rates = TSCS454_RATES,
3358 .formats = TSCS454_FORMATS,},
3359 .capture = {
3360 .stream_name = "DAI 1 Capture",
3361 .channels_min = 1,
3362 .channels_max = 6,
3363 .rates = TSCS454_RATES,
3364 .formats = TSCS454_FORMATS,},
3365 .ops = &tscs454_dai1_ops,
3366 .symmetric_rates = 1,
3367 .symmetric_channels = 1,
3368 .symmetric_samplebits = 1,
3369 },
3370 {
3371 .name = "tscs454-dai2",
3372 .id = TSCS454_DAI2_ID,
3373 .playback = {
3374 .stream_name = "DAI 2 Playback",
3375 .channels_min = 1,
3376 .channels_max = 2,
3377 .rates = TSCS454_RATES,
3378 .formats = TSCS454_FORMATS,},
3379 .capture = {
3380 .stream_name = "DAI 2 Capture",
3381 .channels_min = 1,
3382 .channels_max = 2,
3383 .rates = TSCS454_RATES,
3384 .formats = TSCS454_FORMATS,},
3385 .ops = &tscs454_dai23_ops,
3386 .symmetric_rates = 1,
3387 .symmetric_channels = 1,
3388 .symmetric_samplebits = 1,
3389 },
3390 {
3391 .name = "tscs454-dai3",
3392 .id = TSCS454_DAI3_ID,
3393 .playback = {
3394 .stream_name = "DAI 3 Playback",
3395 .channels_min = 1,
3396 .channels_max = 2,
3397 .rates = TSCS454_RATES,
3398 .formats = TSCS454_FORMATS,},
3399 .capture = {
3400 .stream_name = "DAI 3 Capture",
3401 .channels_min = 1,
3402 .channels_max = 2,
3403 .rates = TSCS454_RATES,
3404 .formats = TSCS454_FORMATS,},
3405 .ops = &tscs454_dai23_ops,
3406 .symmetric_rates = 1,
3407 .symmetric_channels = 1,
3408 .symmetric_samplebits = 1,
3409 },
3410};
3411
3412static char const * const src_names[] = {
3413 "xtal", "mclk1", "mclk2", "bclk"};
3414
3415static int tscs454_i2c_probe(struct i2c_client *i2c,
3416 const struct i2c_device_id *id)
3417{
3418 struct tscs454 *tscs454;
3419 int src;
3420 int ret;
3421
3422 tscs454 = devm_kzalloc(&i2c->dev, sizeof(*tscs454), GFP_KERNEL);
3423 if (!tscs454)
3424 return -ENOMEM;
3425
3426 ret = tscs454_data_init(tscs454, i2c);
3427 if (ret < 0)
3428 return ret;
3429
3430 i2c_set_clientdata(i2c, tscs454);
3431
3432 for (src = PLL_INPUT_XTAL; src < PLL_INPUT_BCLK; src++) {
3433 tscs454->sysclk = devm_clk_get(&i2c->dev, src_names[src]);
3434 if (!IS_ERR(tscs454->sysclk)) {
3435 break;
3436 } else if (PTR_ERR(tscs454->sysclk) != -ENOENT) {
3437 ret = PTR_ERR(tscs454->sysclk);
3438 dev_err(&i2c->dev, "Failed to get sysclk (%d)\n", ret);
3439 return ret;
3440 }
3441 }
3442 dev_dbg(&i2c->dev, "PLL input is %s\n", src_names[src]);
3443 tscs454->sysclk_src_id = src;
3444
3445 ret = regmap_write(tscs454->regmap,
3446 R_RESET, FV_RESET_PWR_ON_DEFAULTS);
3447 if (ret < 0) {
3448 dev_err(&i2c->dev, "Failed to reset the component (%d)\n", ret);
3449 return ret;
3450 }
3451 regcache_mark_dirty(tscs454->regmap);
3452
3453 ret = regmap_register_patch(tscs454->regmap, tscs454_patch,
3454 ARRAY_SIZE(tscs454_patch));
3455 if (ret < 0) {
3456 dev_err(&i2c->dev, "Failed to apply patch (%d)\n", ret);
3457 return ret;
3458 }
3459 /* Sync pg sel reg with cache */
3460 regmap_write(tscs454->regmap, R_PAGESEL, 0x00);
3461
3462 ret = snd_soc_register_component(&i2c->dev, &soc_component_dev_tscs454,
3463 tscs454_dais, ARRAY_SIZE(tscs454_dais));
3464 if (ret) {
3465 dev_err(&i2c->dev, "Failed to register component (%d)\n", ret);
3466 return ret;
3467 }
3468
3469 return 0;
3470}
3471
3472static const struct i2c_device_id tscs454_i2c_id[] = {
3473 { "tscs454", 0 },
3474 { }
3475};
3476MODULE_DEVICE_TABLE(i2c, tscs454_i2c_id);
3477
3478static const struct of_device_id tscs454_of_match[] = {
3479 { .compatible = "tempo,tscs454", },
3480 { }
3481};
3482MODULE_DEVICE_TABLE(of, tscs454_of_match);
3483
3484static struct i2c_driver tscs454_i2c_driver = {
3485 .driver = {
3486 .name = "tscs454",
3487 .of_match_table = tscs454_of_match,
3488 },
3489 .probe = tscs454_i2c_probe,
3490 .id_table = tscs454_i2c_id,
3491};
3492
3493module_i2c_driver(tscs454_i2c_driver);
3494
3495MODULE_AUTHOR("Tempo Semiconductor <steven.eckhoff.opensource@gmail.com");
3496MODULE_DESCRIPTION("ASoC TSCS454 driver");
3497MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/tscs454.h b/sound/soc/codecs/tscs454.h
new file mode 100644
index 000000000000..1142d73d3168
--- /dev/null
+++ b/sound/soc/codecs/tscs454.h
@@ -0,0 +1,2323 @@
1// SPDX-License-Identifier: GPL-2.0
2// tscs454.h -- TSCS454 ALSA SoC Audio driver
3// Copyright 2018 Tempo Semiconductor, Inc.
4// Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com>
5
6#ifndef __REDWOODPUBLIC_H__
7#define __REDWOODPUBLIC_H__
8
9#define VIRT_BASE 0x00
10#define PAGE_LEN 0x100
11#define VIRT_PAGE_BASE(page) (VIRT_BASE + (PAGE_LEN * page))
12#define VIRT_ADDR(page, address) (VIRT_PAGE_BASE(page) + address)
13#define ADDR(page, virt_address) (virt_address - VIRT_PAGE_BASE(page))
14
15#define R_PAGESEL 0x0
16#define R_RESET VIRT_ADDR(0x0, 0x1)
17#define R_IRQEN VIRT_ADDR(0x0, 0x2)
18#define R_IRQMASK VIRT_ADDR(0x0, 0x3)
19#define R_IRQSTAT VIRT_ADDR(0x0, 0x4)
20#define R_DEVADD0 VIRT_ADDR(0x0, 0x6)
21#define R_DEVID VIRT_ADDR(0x0, 0x8)
22#define R_DEVREV VIRT_ADDR(0x0, 0x9)
23#define R_PLLSTAT VIRT_ADDR(0x0, 0x0A)
24#define R_PLL1CTL VIRT_ADDR(0x0, 0x0B)
25#define R_PLL1RDIV VIRT_ADDR(0x0, 0x0C)
26#define R_PLL1ODIV VIRT_ADDR(0x0, 0x0D)
27#define R_PLL1FDIVL VIRT_ADDR(0x0, 0x0E)
28#define R_PLL1FDIVH VIRT_ADDR(0x0, 0x0F)
29#define R_PLL2CTL VIRT_ADDR(0x0, 0x10)
30#define R_PLL2RDIV VIRT_ADDR(0x0, 0x11)
31#define R_PLL2ODIV VIRT_ADDR(0x0, 0x12)
32#define R_PLL2FDIVL VIRT_ADDR(0x0, 0x13)
33#define R_PLL2FDIVH VIRT_ADDR(0x0, 0x14)
34#define R_PLLCTL VIRT_ADDR(0x0, 0x15)
35#define R_ISRC VIRT_ADDR(0x0, 0x16)
36#define R_SCLKCTL VIRT_ADDR(0x0, 0x18)
37#define R_TIMEBASE VIRT_ADDR(0x0, 0x19)
38#define R_I2SP1CTL VIRT_ADDR(0x0, 0x1A)
39#define R_I2SP2CTL VIRT_ADDR(0x0, 0x1B)
40#define R_I2SP3CTL VIRT_ADDR(0x0, 0x1C)
41#define R_I2S1MRATE VIRT_ADDR(0x0, 0x1D)
42#define R_I2S2MRATE VIRT_ADDR(0x0, 0x1E)
43#define R_I2S3MRATE VIRT_ADDR(0x0, 0x1F)
44#define R_I2SCMC VIRT_ADDR(0x0, 0x20)
45#define R_MCLK2PINC VIRT_ADDR(0x0, 0x21)
46#define R_I2SPINC0 VIRT_ADDR(0x0, 0x22)
47#define R_I2SPINC1 VIRT_ADDR(0x0, 0x23)
48#define R_I2SPINC2 VIRT_ADDR(0x0, 0x24)
49#define R_GPIOCTL0 VIRT_ADDR(0x0, 0x25)
50#define R_GPIOCTL1 VIRT_ADDR(0x0, 0x26)
51#define R_ASRC VIRT_ADDR(0x0, 0x28)
52#define R_TDMCTL0 VIRT_ADDR(0x0, 0x2D)
53#define R_TDMCTL1 VIRT_ADDR(0x0, 0x2E)
54#define R_PCMP2CTL0 VIRT_ADDR(0x0, 0x2F)
55#define R_PCMP2CTL1 VIRT_ADDR(0x0, 0x30)
56#define R_PCMP3CTL0 VIRT_ADDR(0x0, 0x31)
57#define R_PCMP3CTL1 VIRT_ADDR(0x0, 0x32)
58#define R_PWRM0 VIRT_ADDR(0x0, 0x33)
59#define R_PWRM1 VIRT_ADDR(0x0, 0x34)
60#define R_PWRM2 VIRT_ADDR(0x0, 0x35)
61#define R_PWRM3 VIRT_ADDR(0x0, 0x36)
62#define R_PWRM4 VIRT_ADDR(0x0, 0x37)
63#define R_I2SIDCTL VIRT_ADDR(0x0, 0x38)
64#define R_I2SODCTL VIRT_ADDR(0x0, 0x39)
65#define R_AUDIOMUX1 VIRT_ADDR(0x0, 0x3A)
66#define R_AUDIOMUX2 VIRT_ADDR(0x0, 0x3B)
67#define R_AUDIOMUX3 VIRT_ADDR(0x0, 0x3C)
68#define R_HSDCTL1 VIRT_ADDR(0x1, 0x1)
69#define R_HSDCTL2 VIRT_ADDR(0x1, 0x2)
70#define R_HSDSTAT VIRT_ADDR(0x1, 0x3)
71#define R_HSDDELAY VIRT_ADDR(0x1, 0x4)
72#define R_BUTCTL VIRT_ADDR(0x1, 0x5)
73#define R_CH0AIC VIRT_ADDR(0x1, 0x6)
74#define R_CH1AIC VIRT_ADDR(0x1, 0x7)
75#define R_CH2AIC VIRT_ADDR(0x1, 0x8)
76#define R_CH3AIC VIRT_ADDR(0x1, 0x9)
77#define R_ICTL0 VIRT_ADDR(0x1, 0x0A)
78#define R_ICTL1 VIRT_ADDR(0x1, 0x0B)
79#define R_MICBIAS VIRT_ADDR(0x1, 0x0C)
80#define R_PGACTL0 VIRT_ADDR(0x1, 0x0D)
81#define R_PGACTL1 VIRT_ADDR(0x1, 0x0E)
82#define R_PGACTL2 VIRT_ADDR(0x1, 0x0F)
83#define R_PGACTL3 VIRT_ADDR(0x1, 0x10)
84#define R_PGAZ VIRT_ADDR(0x1, 0x11)
85#define R_ICH0VOL VIRT_ADDR(0x1, 0x12)
86#define R_ICH1VOL VIRT_ADDR(0x1, 0x13)
87#define R_ICH2VOL VIRT_ADDR(0x1, 0x14)
88#define R_ICH3VOL VIRT_ADDR(0x1, 0x15)
89#define R_ASRCILVOL VIRT_ADDR(0x1, 0x16)
90#define R_ASRCIRVOL VIRT_ADDR(0x1, 0x17)
91#define R_ASRCOLVOL VIRT_ADDR(0x1, 0x18)
92#define R_ASRCORVOL VIRT_ADDR(0x1, 0x19)
93#define R_IVOLCTLU VIRT_ADDR(0x1, 0x1C)
94#define R_ALCCTL0 VIRT_ADDR(0x1, 0x1D)
95#define R_ALCCTL1 VIRT_ADDR(0x1, 0x1E)
96#define R_ALCCTL2 VIRT_ADDR(0x1, 0x1F)
97#define R_ALCCTL3 VIRT_ADDR(0x1, 0x20)
98#define R_NGATE VIRT_ADDR(0x1, 0x21)
99#define R_DMICCTL VIRT_ADDR(0x1, 0x22)
100#define R_DACCTL VIRT_ADDR(0x2, 0x1)
101#define R_SPKCTL VIRT_ADDR(0x2, 0x2)
102#define R_SUBCTL VIRT_ADDR(0x2, 0x3)
103#define R_DCCTL VIRT_ADDR(0x2, 0x4)
104#define R_OVOLCTLU VIRT_ADDR(0x2, 0x6)
105#define R_MUTEC VIRT_ADDR(0x2, 0x7)
106#define R_MVOLL VIRT_ADDR(0x2, 0x8)
107#define R_MVOLR VIRT_ADDR(0x2, 0x9)
108#define R_HPVOLL VIRT_ADDR(0x2, 0x0A)
109#define R_HPVOLR VIRT_ADDR(0x2, 0x0B)
110#define R_SPKVOLL VIRT_ADDR(0x2, 0x0C)
111#define R_SPKVOLR VIRT_ADDR(0x2, 0x0D)
112#define R_SUBVOL VIRT_ADDR(0x2, 0x10)
113#define R_COP0 VIRT_ADDR(0x2, 0x11)
114#define R_COP1 VIRT_ADDR(0x2, 0x12)
115#define R_COPSTAT VIRT_ADDR(0x2, 0x13)
116#define R_PWM0 VIRT_ADDR(0x2, 0x14)
117#define R_PWM1 VIRT_ADDR(0x2, 0x15)
118#define R_PWM2 VIRT_ADDR(0x2, 0x16)
119#define R_PWM3 VIRT_ADDR(0x2, 0x17)
120#define R_HPSW VIRT_ADDR(0x2, 0x18)
121#define R_THERMTS VIRT_ADDR(0x2, 0x19)
122#define R_THERMSPK1 VIRT_ADDR(0x2, 0x1A)
123#define R_THERMSTAT VIRT_ADDR(0x2, 0x1B)
124#define R_SCSTAT VIRT_ADDR(0x2, 0x1C)
125#define R_SDMON VIRT_ADDR(0x2, 0x1D)
126#define R_SPKEQFILT VIRT_ADDR(0x3, 0x1)
127#define R_SPKCRWDL VIRT_ADDR(0x3, 0x2)
128#define R_SPKCRWDM VIRT_ADDR(0x3, 0x3)
129#define R_SPKCRWDH VIRT_ADDR(0x3, 0x4)
130#define R_SPKCRRDL VIRT_ADDR(0x3, 0x5)
131#define R_SPKCRRDM VIRT_ADDR(0x3, 0x6)
132#define R_SPKCRRDH VIRT_ADDR(0x3, 0x7)
133#define R_SPKCRADD VIRT_ADDR(0x3, 0x8)
134#define R_SPKCRS VIRT_ADDR(0x3, 0x9)
135#define R_SPKMBCEN VIRT_ADDR(0x3, 0x0A)
136#define R_SPKMBCCTL VIRT_ADDR(0x3, 0x0B)
137#define R_SPKMBCMUG1 VIRT_ADDR(0x3, 0x0C)
138#define R_SPKMBCTHR1 VIRT_ADDR(0x3, 0x0D)
139#define R_SPKMBCRAT1 VIRT_ADDR(0x3, 0x0E)
140#define R_SPKMBCATK1L VIRT_ADDR(0x3, 0x0F)
141#define R_SPKMBCATK1H VIRT_ADDR(0x3, 0x10)
142#define R_SPKMBCREL1L VIRT_ADDR(0x3, 0x11)
143#define R_SPKMBCREL1H VIRT_ADDR(0x3, 0x12)
144#define R_SPKMBCMUG2 VIRT_ADDR(0x3, 0x13)
145#define R_SPKMBCTHR2 VIRT_ADDR(0x3, 0x14)
146#define R_SPKMBCRAT2 VIRT_ADDR(0x3, 0x15)
147#define R_SPKMBCATK2L VIRT_ADDR(0x3, 0x16)
148#define R_SPKMBCATK2H VIRT_ADDR(0x3, 0x17)
149#define R_SPKMBCREL2L VIRT_ADDR(0x3, 0x18)
150#define R_SPKMBCREL2H VIRT_ADDR(0x3, 0x19)
151#define R_SPKMBCMUG3 VIRT_ADDR(0x3, 0x1A)
152#define R_SPKMBCTHR3 VIRT_ADDR(0x3, 0x1B)
153#define R_SPKMBCRAT3 VIRT_ADDR(0x3, 0x1C)
154#define R_SPKMBCATK3L VIRT_ADDR(0x3, 0x1D)
155#define R_SPKMBCATK3H VIRT_ADDR(0x3, 0x1E)
156#define R_SPKMBCREL3L VIRT_ADDR(0x3, 0x1F)
157#define R_SPKMBCREL3H VIRT_ADDR(0x3, 0x20)
158#define R_SPKCLECTL VIRT_ADDR(0x3, 0x21)
159#define R_SPKCLEMUG VIRT_ADDR(0x3, 0x22)
160#define R_SPKCOMPTHR VIRT_ADDR(0x3, 0x23)
161#define R_SPKCOMPRAT VIRT_ADDR(0x3, 0x24)
162#define R_SPKCOMPATKL VIRT_ADDR(0x3, 0x25)
163#define R_SPKCOMPATKH VIRT_ADDR(0x3, 0x26)
164#define R_SPKCOMPRELL VIRT_ADDR(0x3, 0x27)
165#define R_SPKCOMPRELH VIRT_ADDR(0x3, 0x28)
166#define R_SPKLIMTHR VIRT_ADDR(0x3, 0x29)
167#define R_SPKLIMTGT VIRT_ADDR(0x3, 0x2A)
168#define R_SPKLIMATKL VIRT_ADDR(0x3, 0x2B)
169#define R_SPKLIMATKH VIRT_ADDR(0x3, 0x2C)
170#define R_SPKLIMRELL VIRT_ADDR(0x3, 0x2D)
171#define R_SPKLIMRELH VIRT_ADDR(0x3, 0x2E)
172#define R_SPKEXPTHR VIRT_ADDR(0x3, 0x2F)
173#define R_SPKEXPRAT VIRT_ADDR(0x3, 0x30)
174#define R_SPKEXPATKL VIRT_ADDR(0x3, 0x31)
175#define R_SPKEXPATKH VIRT_ADDR(0x3, 0x32)
176#define R_SPKEXPRELL VIRT_ADDR(0x3, 0x33)
177#define R_SPKEXPRELH VIRT_ADDR(0x3, 0x34)
178#define R_SPKFXCTL VIRT_ADDR(0x3, 0x35)
179#define R_DACEQFILT VIRT_ADDR(0x4, 0x1)
180#define R_DACCRWDL VIRT_ADDR(0x4, 0x2)
181#define R_DACCRWDM VIRT_ADDR(0x4, 0x3)
182#define R_DACCRWDH VIRT_ADDR(0x4, 0x4)
183#define R_DACCRRDL VIRT_ADDR(0x4, 0x5)
184#define R_DACCRRDM VIRT_ADDR(0x4, 0x6)
185#define R_DACCRRDH VIRT_ADDR(0x4, 0x7)
186#define R_DACCRADD VIRT_ADDR(0x4, 0x8)
187#define R_DACCRS VIRT_ADDR(0x4, 0x9)
188#define R_DACMBCEN VIRT_ADDR(0x4, 0x0A)
189#define R_DACMBCCTL VIRT_ADDR(0x4, 0x0B)
190#define R_DACMBCMUG1 VIRT_ADDR(0x4, 0x0C)
191#define R_DACMBCTHR1 VIRT_ADDR(0x4, 0x0D)
192#define R_DACMBCRAT1 VIRT_ADDR(0x4, 0x0E)
193#define R_DACMBCATK1L VIRT_ADDR(0x4, 0x0F)
194#define R_DACMBCATK1H VIRT_ADDR(0x4, 0x10)
195#define R_DACMBCREL1L VIRT_ADDR(0x4, 0x11)
196#define R_DACMBCREL1H VIRT_ADDR(0x4, 0x12)
197#define R_DACMBCMUG2 VIRT_ADDR(0x4, 0x13)
198#define R_DACMBCTHR2 VIRT_ADDR(0x4, 0x14)
199#define R_DACMBCRAT2 VIRT_ADDR(0x4, 0x15)
200#define R_DACMBCATK2L VIRT_ADDR(0x4, 0x16)
201#define R_DACMBCATK2H VIRT_ADDR(0x4, 0x17)
202#define R_DACMBCREL2L VIRT_ADDR(0x4, 0x18)
203#define R_DACMBCREL2H VIRT_ADDR(0x4, 0x19)
204#define R_DACMBCMUG3 VIRT_ADDR(0x4, 0x1A)
205#define R_DACMBCTHR3 VIRT_ADDR(0x4, 0x1B)
206#define R_DACMBCRAT3 VIRT_ADDR(0x4, 0x1C)
207#define R_DACMBCATK3L VIRT_ADDR(0x4, 0x1D)
208#define R_DACMBCATK3H VIRT_ADDR(0x4, 0x1E)
209#define R_DACMBCREL3L VIRT_ADDR(0x4, 0x1F)
210#define R_DACMBCREL3H VIRT_ADDR(0x4, 0x20)
211#define R_DACCLECTL VIRT_ADDR(0x4, 0x21)
212#define R_DACCLEMUG VIRT_ADDR(0x4, 0x22)
213#define R_DACCOMPTHR VIRT_ADDR(0x4, 0x23)
214#define R_DACCOMPRAT VIRT_ADDR(0x4, 0x24)
215#define R_DACCOMPATKL VIRT_ADDR(0x4, 0x25)
216#define R_DACCOMPATKH VIRT_ADDR(0x4, 0x26)
217#define R_DACCOMPRELL VIRT_ADDR(0x4, 0x27)
218#define R_DACCOMPRELH VIRT_ADDR(0x4, 0x28)
219#define R_DACLIMTHR VIRT_ADDR(0x4, 0x29)
220#define R_DACLIMTGT VIRT_ADDR(0x4, 0x2A)
221#define R_DACLIMATKL VIRT_ADDR(0x4, 0x2B)
222#define R_DACLIMATKH VIRT_ADDR(0x4, 0x2C)
223#define R_DACLIMRELL VIRT_ADDR(0x4, 0x2D)
224#define R_DACLIMRELH VIRT_ADDR(0x4, 0x2E)
225#define R_DACEXPTHR VIRT_ADDR(0x4, 0x2F)
226#define R_DACEXPRAT VIRT_ADDR(0x4, 0x30)
227#define R_DACEXPATKL VIRT_ADDR(0x4, 0x31)
228#define R_DACEXPATKH VIRT_ADDR(0x4, 0x32)
229#define R_DACEXPRELL VIRT_ADDR(0x4, 0x33)
230#define R_DACEXPRELH VIRT_ADDR(0x4, 0x34)
231#define R_DACFXCTL VIRT_ADDR(0x4, 0x35)
232#define R_SUBEQFILT VIRT_ADDR(0x5, 0x1)
233#define R_SUBCRWDL VIRT_ADDR(0x5, 0x2)
234#define R_SUBCRWDM VIRT_ADDR(0x5, 0x3)
235#define R_SUBCRWDH VIRT_ADDR(0x5, 0x4)
236#define R_SUBCRRDL VIRT_ADDR(0x5, 0x5)
237#define R_SUBCRRDM VIRT_ADDR(0x5, 0x6)
238#define R_SUBCRRDH VIRT_ADDR(0x5, 0x7)
239#define R_SUBCRADD VIRT_ADDR(0x5, 0x8)
240#define R_SUBCRS VIRT_ADDR(0x5, 0x9)
241#define R_SUBMBCEN VIRT_ADDR(0x5, 0x0A)
242#define R_SUBMBCCTL VIRT_ADDR(0x5, 0x0B)
243#define R_SUBMBCMUG1 VIRT_ADDR(0x5, 0x0C)
244#define R_SUBMBCTHR1 VIRT_ADDR(0x5, 0x0D)
245#define R_SUBMBCRAT1 VIRT_ADDR(0x5, 0x0E)
246#define R_SUBMBCATK1L VIRT_ADDR(0x5, 0x0F)
247#define R_SUBMBCATK1H VIRT_ADDR(0x5, 0x10)
248#define R_SUBMBCREL1L VIRT_ADDR(0x5, 0x11)
249#define R_SUBMBCREL1H VIRT_ADDR(0x5, 0x12)
250#define R_SUBMBCMUG2 VIRT_ADDR(0x5, 0x13)
251#define R_SUBMBCTHR2 VIRT_ADDR(0x5, 0x14)
252#define R_SUBMBCRAT2 VIRT_ADDR(0x5, 0x15)
253#define R_SUBMBCATK2L VIRT_ADDR(0x5, 0x16)
254#define R_SUBMBCATK2H VIRT_ADDR(0x5, 0x17)
255#define R_SUBMBCREL2L VIRT_ADDR(0x5, 0x18)
256#define R_SUBMBCREL2H VIRT_ADDR(0x5, 0x19)
257#define R_SUBMBCMUG3 VIRT_ADDR(0x5, 0x1A)
258#define R_SUBMBCTHR3 VIRT_ADDR(0x5, 0x1B)
259#define R_SUBMBCRAT3 VIRT_ADDR(0x5, 0x1C)
260#define R_SUBMBCATK3L VIRT_ADDR(0x5, 0x1D)
261#define R_SUBMBCATK3H VIRT_ADDR(0x5, 0x1E)
262#define R_SUBMBCREL3L VIRT_ADDR(0x5, 0x1F)
263#define R_SUBMBCREL3H VIRT_ADDR(0x5, 0x20)
264#define R_SUBCLECTL VIRT_ADDR(0x5, 0x21)
265#define R_SUBCLEMUG VIRT_ADDR(0x5, 0x22)
266#define R_SUBCOMPTHR VIRT_ADDR(0x5, 0x23)
267#define R_SUBCOMPRAT VIRT_ADDR(0x5, 0x24)
268#define R_SUBCOMPATKL VIRT_ADDR(0x5, 0x25)
269#define R_SUBCOMPATKH VIRT_ADDR(0x5, 0x26)
270#define R_SUBCOMPRELL VIRT_ADDR(0x5, 0x27)
271#define R_SUBCOMPRELH VIRT_ADDR(0x5, 0x28)
272#define R_SUBLIMTHR VIRT_ADDR(0x5, 0x29)
273#define R_SUBLIMTGT VIRT_ADDR(0x5, 0x2A)
274#define R_SUBLIMATKL VIRT_ADDR(0x5, 0x2B)
275#define R_SUBLIMATKH VIRT_ADDR(0x5, 0x2C)
276#define R_SUBLIMRELL VIRT_ADDR(0x5, 0x2D)
277#define R_SUBLIMRELH VIRT_ADDR(0x5, 0x2E)
278#define R_SUBEXPTHR VIRT_ADDR(0x5, 0x2F)
279#define R_SUBEXPRAT VIRT_ADDR(0x5, 0x30)
280#define R_SUBEXPATKL VIRT_ADDR(0x5, 0x31)
281#define R_SUBEXPATKH VIRT_ADDR(0x5, 0x32)
282#define R_SUBEXPRELL VIRT_ADDR(0x5, 0x33)
283#define R_SUBEXPRELH VIRT_ADDR(0x5, 0x34)
284#define R_SUBFXCTL VIRT_ADDR(0x5, 0x35)
285
286// *** PLLCTL ***
287#define FB_PLLCTL_VCCI_PLL 6
288#define FM_PLLCTL_VCCI_PLL 0xC0
289
290#define FB_PLLCTL_RZ_PLL 3
291#define FM_PLLCTL_RZ_PLL 0x38
292
293#define FB_PLLCTL_CP_PLL 0
294#define FM_PLLCTL_CP_PLL 0x7
295
296// *** PLLRDIV ***
297#define FB_PLLRDIV_REFDIV_PLL 0
298#define FM_PLLRDIV_REFDIV_PLL 0xFF
299
300// *** PLLODIV ***
301#define FB_PLLODIV_OUTDIV_PLL 0
302#define FM_PLLODIV_OUTDIV_PLL 0xFF
303
304// *** PLLFDIVL ***
305#define FB_PLLFDIVL_FBDIVL_PLL 0
306#define FM_PLLFDIVL_FBDIVL_PLL 0xFF
307
308// *** PLLFDIVH ***
309#define FB_PLLFDIVH_FBDIVH_PLL 0
310#define FM_PLLFDIVH_FBDIVH_PLL 0xF
311
312// *** I2SPCTL ***
313#define FB_I2SPCTL_BCLKSTAT 7
314#define FM_I2SPCTL_BCLKSTAT 0x80
315#define FV_BCLKSTAT_LOST 0x80
316#define FV_BCLKSTAT_NOT_LOST 0x0
317
318#define FB_I2SPCTL_BCLKP 6
319#define FM_I2SPCTL_BCLKP 0x40
320#define FV_BCLKP_NOT_INVERTED 0x0
321#define FV_BCLKP_INVERTED 0x40
322
323#define FB_I2SPCTL_PORTMS 5
324#define FM_I2SPCTL_PORTMS 0x20
325#define FV_PORTMS_SLAVE 0x0
326#define FV_PORTMS_MASTER 0x20
327
328#define FB_I2SPCTL_LRCLKP 4
329#define FM_I2SPCTL_LRCLKP 0x10
330#define FV_LRCLKP_NOT_INVERTED 0x0
331#define FV_LRCLKP_INVERTED 0x10
332
333#define FB_I2SPCTL_WL 2
334#define FM_I2SPCTL_WL 0xC
335#define FV_WL_16 0x0
336#define FV_WL_20 0x4
337#define FV_WL_24 0x8
338#define FV_WL_32 0xC
339
340#define FB_I2SPCTL_FORMAT 0
341#define FM_I2SPCTL_FORMAT 0x3
342#define FV_FORMAT_RIGHT 0x0
343#define FV_FORMAT_LEFT 0x1
344#define FV_FORMAT_I2S 0x2
345#define FV_FORMAT_TDM 0x3
346
347// *** I2SMRATE ***
348#define FB_I2SMRATE_I2SMCLKHALF 7
349#define FM_I2SMRATE_I2SMCLKHALF 0x80
350#define FV_I2SMCLKHALF_I2S1MCLKDIV_DIV_2 0x0
351#define FV_I2SMCLKHALF_I2S1MCLKDIV_ONLY 0x80
352
353#define FB_I2SMRATE_I2SMCLKDIV 5
354#define FM_I2SMRATE_I2SMCLKDIV 0x60
355#define FV_I2SMCLKDIV_125 0x0
356#define FV_I2SMCLKDIV_128 0x20
357#define FV_I2SMCLKDIV_136 0x40
358#define FV_I2SMCLKDIV_192 0x60
359
360#define FB_I2SMRATE_I2SMBR 3
361#define FM_I2SMRATE_I2SMBR 0x18
362#define FV_I2SMBR_32 0x0
363#define FV_I2SMBR_44PT1 0x8
364#define FV_I2SMBR_48 0x10
365#define FV_I2SMBR_MCLK_MODE 0x18
366
367#define FB_I2SMRATE_I2SMBM 0
368#define FM_I2SMRATE_I2SMBM 0x3
369#define FV_I2SMBM_0PT25 0x0
370#define FV_I2SMBM_0PT5 0x1
371#define FV_I2SMBM_1 0x2
372#define FV_I2SMBM_2 0x3
373
374// *** PCMPCTL0 ***
375#define FB_PCMPCTL0_PCMFLENP 2
376#define FM_PCMPCTL0_PCMFLENP 0x4
377#define FV_PCMFLENP_128 0x0
378#define FV_PCMFLENP_256 0x4
379
380#define FB_PCMPCTL0_SLSYNCP 1
381#define FM_PCMPCTL0_SLSYNCP 0x2
382#define FV_SLSYNCP_SHORT 0x0
383#define FV_SLSYNCP_LONG 0x2
384
385#define FB_PCMPCTL0_BDELAYP 0
386#define FM_PCMPCTL0_BDELAYP 0x1
387#define FV_BDELAYP_NO_DELAY 0x0
388#define FV_BDELAYP_1BCLK_DELAY 0x1
389
390// *** PCMPCTL1 ***
391#define FB_PCMPCTL1_PCMMOMP 6
392#define FM_PCMPCTL1_PCMMOMP 0x40
393
394#define FB_PCMPCTL1_PCMSOP 5
395#define FM_PCMPCTL1_PCMSOP 0x20
396#define FV_PCMSOP_1 0x0
397#define FV_PCMSOP_2 0x20
398
399#define FB_PCMPCTL1_PCMDSSP 3
400#define FM_PCMPCTL1_PCMDSSP 0x18
401#define FV_PCMDSSP_16 0x0
402#define FV_PCMDSSP_24 0x8
403#define FV_PCMDSSP_32 0x10
404
405#define FB_PCMPCTL1_PCMMIMP 1
406#define FM_PCMPCTL1_PCMMIMP 0x2
407
408#define FB_PCMPCTL1_PCMSIP 0
409#define FM_PCMPCTL1_PCMSIP 0x1
410#define FV_PCMSIP_1 0x0
411#define FV_PCMSIP_2 0x1
412
413// *** CHAIC ***
414#define FB_CHAIC_MICBST 4
415#define FM_CHAIC_MICBST 0x30
416
417// *** PGACTL ***
418#define FB_PGACTL_PGAMUTE 7
419#define FM_PGACTL_PGAMUTE 0x80
420
421#define FB_PGACTL_PGAVOL 0
422#define FM_PGACTL_PGAVOL 0x3F
423
424// *** ICHVOL ***
425#define FB_ICHVOL_ICHVOL 0
426#define FM_ICHVOL_ICHVOL 0xFF
427
428// *** SPKMBCMUG ***
429#define FB_SPKMBCMUG_PHASE 5
430#define FM_SPKMBCMUG_PHASE 0x20
431
432#define FB_SPKMBCMUG_MUGAIN 0
433#define FM_SPKMBCMUG_MUGAIN 0x1F
434
435// *** SPKMBCTHR ***
436#define FB_SPKMBCTHR_THRESH 0
437#define FM_SPKMBCTHR_THRESH 0xFF
438
439// *** SPKMBCRAT ***
440#define FB_SPKMBCRAT_RATIO 0
441#define FM_SPKMBCRAT_RATIO 0x1F
442
443// *** SPKMBCATKL ***
444#define FB_SPKMBCATKL_TCATKL 0
445#define FM_SPKMBCATKL_TCATKL 0xFF
446
447// *** SPKMBCATKH ***
448#define FB_SPKMBCATKH_TCATKH 0
449#define FM_SPKMBCATKH_TCATKH 0xFF
450
451// *** SPKMBCRELL ***
452#define FB_SPKMBCRELL_TCRELL 0
453#define FM_SPKMBCRELL_TCRELL 0xFF
454
455// *** SPKMBCRELH ***
456#define FB_SPKMBCRELH_TCRELH 0
457#define FM_SPKMBCRELH_TCRELH 0xFF
458
459// *** DACMBCMUG ***
460#define FB_DACMBCMUG_PHASE 5
461#define FM_DACMBCMUG_PHASE 0x20
462
463#define FB_DACMBCMUG_MUGAIN 0
464#define FM_DACMBCMUG_MUGAIN 0x1F
465
466// *** DACMBCTHR ***
467#define FB_DACMBCTHR_THRESH 0
468#define FM_DACMBCTHR_THRESH 0xFF
469
470// *** DACMBCRAT ***
471#define FB_DACMBCRAT_RATIO 0
472#define FM_DACMBCRAT_RATIO 0x1F
473
474// *** DACMBCATKL ***
475#define FB_DACMBCATKL_TCATKL 0
476#define FM_DACMBCATKL_TCATKL 0xFF
477
478// *** DACMBCATKH ***
479#define FB_DACMBCATKH_TCATKH 0
480#define FM_DACMBCATKH_TCATKH 0xFF
481
482// *** DACMBCRELL ***
483#define FB_DACMBCRELL_TCRELL 0
484#define FM_DACMBCRELL_TCRELL 0xFF
485
486// *** DACMBCRELH ***
487#define FB_DACMBCRELH_TCRELH 0
488#define FM_DACMBCRELH_TCRELH 0xFF
489
490// *** SUBMBCMUG ***
491#define FB_SUBMBCMUG_PHASE 5
492#define FM_SUBMBCMUG_PHASE 0x20
493
494#define FB_SUBMBCMUG_MUGAIN 0
495#define FM_SUBMBCMUG_MUGAIN 0x1F
496
497// *** SUBMBCTHR ***
498#define FB_SUBMBCTHR_THRESH 0
499#define FM_SUBMBCTHR_THRESH 0xFF
500
501// *** SUBMBCRAT ***
502#define FB_SUBMBCRAT_RATIO 0
503#define FM_SUBMBCRAT_RATIO 0x1F
504
505// *** SUBMBCATKL ***
506#define FB_SUBMBCATKL_TCATKL 0
507#define FM_SUBMBCATKL_TCATKL 0xFF
508
509// *** SUBMBCATKH ***
510#define FB_SUBMBCATKH_TCATKH 0
511#define FM_SUBMBCATKH_TCATKH 0xFF
512
513// *** SUBMBCRELL ***
514#define FB_SUBMBCRELL_TCRELL 0
515#define FM_SUBMBCRELL_TCRELL 0xFF
516
517// *** SUBMBCRELH ***
518#define FB_SUBMBCRELH_TCRELH 0
519#define FM_SUBMBCRELH_TCRELH 0xFF
520
521// *** PAGESEL ***
522#define FB_PAGESEL_PAGESEL 0
523#define FM_PAGESEL_PAGESEL 0xFF
524
525// *** RESET ***
526#define FB_RESET_RESET 0
527#define FM_RESET_RESET 0xFF
528#define FV_RESET_PWR_ON_DEFAULTS 0x85
529
530// *** IRQEN ***
531#define FB_IRQEN_THRMINTEN 6
532#define FM_IRQEN_THRMINTEN 0x40
533#define FV_THRMINTEN_ENABLED 0x40
534#define FV_THRMINTEN_DISABLED 0x0
535
536#define FB_IRQEN_HBPINTEN 5
537#define FM_IRQEN_HBPINTEN 0x20
538#define FV_HBPINTEN_ENABLED 0x20
539#define FV_HBPINTEN_DISABLED 0x0
540
541#define FB_IRQEN_HSDINTEN 4
542#define FM_IRQEN_HSDINTEN 0x10
543#define FV_HSDINTEN_ENABLED 0x10
544#define FV_HSDINTEN_DISABLED 0x0
545
546#define FB_IRQEN_HPDINTEN 3
547#define FM_IRQEN_HPDINTEN 0x8
548#define FV_HPDINTEN_ENABLED 0x8
549#define FV_HPDINTEN_DISABLED 0x0
550
551#define FB_IRQEN_GPIO3INTEN 1
552#define FM_IRQEN_GPIO3INTEN 0x2
553#define FV_GPIO3INTEN_ENABLED 0x2
554#define FV_GPIO3INTEN_DISABLED 0x0
555
556#define FB_IRQEN_GPIO2INTEN 0
557#define FM_IRQEN_GPIO2INTEN 0x1
558#define FV_GPIO2INTEN_ENABLED 0x1
559#define FV_GPIO2INTEN_DISABLED 0x0
560
561#define IRQEN_GPIOINTEN_ENABLED 0x1
562#define IRQEN_GPIOINTEN_DISABLED 0x0
563
564// *** IRQMASK ***
565#define FB_IRQMASK_THRMIM 6
566#define FM_IRQMASK_THRMIM 0x40
567#define FV_THRMIM_MASKED 0x0
568#define FV_THRMIM_NOT_MASKED 0x40
569
570#define FB_IRQMASK_HBPIM 5
571#define FM_IRQMASK_HBPIM 0x20
572#define FV_HBPIM_MASKED 0x0
573#define FV_HBPIM_NOT_MASKED 0x20
574
575#define FB_IRQMASK_HSDIM 4
576#define FM_IRQMASK_HSDIM 0x10
577#define FV_HSDIM_MASKED 0x0
578#define FV_HSDIM_NOT_MASKED 0x10
579
580#define FB_IRQMASK_HPDIM 3
581#define FM_IRQMASK_HPDIM 0x8
582#define FV_HPDIM_MASKED 0x0
583#define FV_HPDIM_NOT_MASKED 0x8
584
585#define FB_IRQMASK_GPIO3M 1
586#define FM_IRQMASK_GPIO3M 0x2
587#define FV_GPIO3M_MASKED 0x0
588#define FV_GPIO3M_NOT_MASKED 0x2
589
590#define FB_IRQMASK_GPIO2M 0
591#define FM_IRQMASK_GPIO2M 0x1
592#define FV_GPIO2M_MASKED 0x0
593#define FV_GPIO2M_NOT_MASKED 0x1
594
595#define IRQMASK_GPIOM_MASKED 0x0
596#define IRQMASK_GPIOM_NOT_MASKED 0x1
597
598// *** IRQSTAT ***
599#define FB_IRQSTAT_THRMINT 6
600#define FM_IRQSTAT_THRMINT 0x40
601#define FV_THRMINT_INTERRUPTED 0x40
602#define FV_THRMINT_NOT_INTERRUPTED 0x0
603
604#define FB_IRQSTAT_HBPINT 5
605#define FM_IRQSTAT_HBPINT 0x20
606#define FV_HBPINT_INTERRUPTED 0x20
607#define FV_HBPINT_NOT_INTERRUPTED 0x0
608
609#define FB_IRQSTAT_HSDINT 4
610#define FM_IRQSTAT_HSDINT 0x10
611#define FV_HSDINT_INTERRUPTED 0x10
612#define FV_HSDINT_NOT_INTERRUPTED 0x0
613
614#define FB_IRQSTAT_HPDINT 3
615#define FM_IRQSTAT_HPDINT 0x8
616#define FV_HPDINT_INTERRUPTED 0x8
617#define FV_HPDINT_NOT_INTERRUPTED 0x0
618
619#define FB_IRQSTAT_GPIO3INT 1
620#define FM_IRQSTAT_GPIO3INT 0x2
621#define FV_GPIO3INT_INTERRUPTED 0x2
622#define FV_GPIO3INT_NOT_INTERRUPTED 0x0
623
624#define FB_IRQSTAT_GPIO2INT 0
625#define FM_IRQSTAT_GPIO2INT 0x1
626#define FV_GPIO2INT_INTERRUPTED 0x1
627#define FV_GPIO2INT_NOT_INTERRUPTED 0x0
628
629#define IRQSTAT_GPIOINT_INTERRUPTED 0x1
630#define IRQSTAT_GPIOINT_NOT_INTERRUPTED 0x0
631
632// *** DEVADD0 ***
633#define FB_DEVADD0_DEVADD0 1
634#define FM_DEVADD0_DEVADD0 0xFE
635
636#define FB_DEVADD0_I2C_ADDRLK 0
637#define FM_DEVADD0_I2C_ADDRLK 0x1
638#define FV_I2C_ADDRLK_LOCK 0x1
639
640// *** DEVID ***
641#define FB_DEVID_DEV_ID 0
642#define FM_DEVID_DEV_ID 0xFF
643
644// *** DEVREV ***
645#define FB_DEVREV_MAJ_REV 4
646#define FM_DEVREV_MAJ_REV 0xF0
647
648#define FB_DEVREV_MIN_REV 0
649#define FM_DEVREV_MIN_REV 0xF
650
651// *** PLLSTAT ***
652#define FB_PLLSTAT_PLL2LK 1
653#define FM_PLLSTAT_PLL2LK 0x2
654#define FV_PLL2LK_LOCKED 0x2
655#define FV_PLL2LK_UNLOCKED 0x0
656
657#define FB_PLLSTAT_PLL1LK 0
658#define FM_PLLSTAT_PLL1LK 0x1
659#define FV_PLL1LK_LOCKED 0x1
660#define FV_PLL1LK_UNLOCKED 0x0
661
662#define PLLSTAT_PLLLK_LOCKED 0x1
663#define PLLSTAT_PLLLK_UNLOCKED 0x0
664
665// *** PLLCTL ***
666#define FB_PLLCTL_PU_PLL2 7
667#define FM_PLLCTL_PU_PLL2 0x80
668#define FV_PU_PLL2_PWR_UP 0x80
669#define FV_PU_PLL2_PWR_DWN 0x0
670
671#define FB_PLLCTL_PU_PLL1 6
672#define FM_PLLCTL_PU_PLL1 0x40
673#define FV_PU_PLL1_PWR_UP 0x40
674#define FV_PU_PLL1_PWR_DWN 0x0
675
676#define FB_PLLCTL_PLL2CLKEN 5
677#define FM_PLLCTL_PLL2CLKEN 0x20
678#define FV_PLL2CLKEN_ENABLE 0x20
679#define FV_PLL2CLKEN_DISABLE 0x0
680
681#define FB_PLLCTL_PLL1CLKEN 4
682#define FM_PLLCTL_PLL1CLKEN 0x10
683#define FV_PLL1CLKEN_ENABLE 0x10
684#define FV_PLL1CLKEN_DISABLE 0x0
685
686#define FB_PLLCTL_BCLKSEL 2
687#define FM_PLLCTL_BCLKSEL 0xC
688#define FV_BCLKSEL_BCLK1 0x0
689#define FV_BCLKSEL_BCLK2 0x4
690#define FV_BCLKSEL_BCLK3 0x8
691
692#define FB_PLLCTL_PLLISEL 0
693#define FM_PLLCTL_PLLISEL 0x3
694#define FV_PLLISEL_XTAL 0x0
695#define FV_PLLISEL_MCLK1 0x1
696#define FV_PLLISEL_MCLK2 0x2
697#define FV_PLLISEL_BCLK 0x3
698
699#define PLLCTL_PU_PLL_PWR_UP 0x1
700#define PLLCTL_PU_PLL_PWR_DWN 0x0
701#define PLLCTL_PLLCLKEN_ENABLE 0x1
702#define PLLCTL_PLLCLKEN_DISABLE 0x0
703
704// *** ISRC ***
705#define FB_ISRC_IBR 2
706#define FM_ISRC_IBR 0x4
707#define FV_IBR_44PT1 0x0
708#define FV_IBR_48 0x4
709
710#define FB_ISRC_IBM 0
711#define FM_ISRC_IBM 0x3
712#define FV_IBM_0PT25 0x0
713#define FV_IBM_0PT5 0x1
714#define FV_IBM_1 0x2
715#define FV_IBM_2 0x3
716
717// *** SCLKCTL ***
718#define FB_SCLKCTL_ASDM 6
719#define FM_SCLKCTL_ASDM 0xC0
720#define FV_ASDM_HALF 0x40
721#define FV_ASDM_FULL 0x80
722#define FV_ASDM_AUTO 0xC0
723
724#define FB_SCLKCTL_DSDM 4
725#define FM_SCLKCTL_DSDM 0x30
726#define FV_DSDM_HALF 0x10
727#define FV_DSDM_FULL 0x20
728#define FV_DSDM_AUTO 0x30
729
730// *** TIMEBASE ***
731#define FB_TIMEBASE_TIMEBASE 0
732#define FM_TIMEBASE_TIMEBASE 0xFF
733
734// *** I2SCMC ***
735#define FB_I2SCMC_BCMP3 4
736#define FM_I2SCMC_BCMP3 0x30
737#define FV_BCMP3_AUTO 0x0
738#define FV_BCMP3_32X 0x10
739#define FV_BCMP3_40X 0x20
740#define FV_BCMP3_64X 0x30
741
742#define FB_I2SCMC_BCMP2 2
743#define FM_I2SCMC_BCMP2 0xC
744#define FV_BCMP2_AUTO 0x0
745#define FV_BCMP2_32X 0x4
746#define FV_BCMP2_40X 0x8
747#define FV_BCMP2_64X 0xC
748
749#define FB_I2SCMC_BCMP1 0
750#define FM_I2SCMC_BCMP1 0x3
751#define FV_BCMP1_AUTO 0x0
752#define FV_BCMP1_32X 0x1
753#define FV_BCMP1_40X 0x2
754#define FV_BCMP1_64X 0x3
755
756#define I2SCMC_BCMP_AUTO 0x0
757#define I2SCMC_BCMP_32X 0x1
758#define I2SCMC_BCMP_40X 0x2
759#define I2SCMC_BCMP_64X 0x3
760
761// *** MCLK2PINC ***
762#define FB_MCLK2PINC_SLEWOUT 4
763#define FM_MCLK2PINC_SLEWOUT 0xF0
764
765#define FB_MCLK2PINC_MCLK2IO 2
766#define FM_MCLK2PINC_MCLK2IO 0x4
767#define FV_MCLK2IO_INPUT 0x0
768#define FV_MCLK2IO_OUTPUT 0x4
769
770#define FB_MCLK2PINC_MCLK2OS 0
771#define FM_MCLK2PINC_MCLK2OS 0x3
772#define FV_MCLK2OS_24PT576 0x0
773#define FV_MCLK2OS_22PT5792 0x1
774#define FV_MCLK2OS_PLL2 0x2
775
776// *** I2SPINC0 ***
777#define FB_I2SPINC0_SDO3TRI 7
778#define FM_I2SPINC0_SDO3TRI 0x80
779
780#define FB_I2SPINC0_SDO2TRI 6
781#define FM_I2SPINC0_SDO2TRI 0x40
782
783#define FB_I2SPINC0_SDO1TRI 5
784#define FM_I2SPINC0_SDO1TRI 0x20
785
786#define FB_I2SPINC0_PCM3TRI 2
787#define FM_I2SPINC0_PCM3TRI 0x4
788
789#define FB_I2SPINC0_PCM2TRI 1
790#define FM_I2SPINC0_PCM2TRI 0x2
791
792#define FB_I2SPINC0_PCM1TRI 0
793#define FM_I2SPINC0_PCM1TRI 0x1
794
795// *** I2SPINC1 ***
796#define FB_I2SPINC1_SDO3PDD 2
797#define FM_I2SPINC1_SDO3PDD 0x4
798
799#define FB_I2SPINC1_SDO2PDD 1
800#define FM_I2SPINC1_SDO2PDD 0x2
801
802#define FB_I2SPINC1_SDO1PDD 0
803#define FM_I2SPINC1_SDO1PDD 0x1
804
805// *** I2SPINC2 ***
806#define FB_I2SPINC2_LR3PDD 5
807#define FM_I2SPINC2_LR3PDD 0x20
808
809#define FB_I2SPINC2_BC3PDD 4
810#define FM_I2SPINC2_BC3PDD 0x10
811
812#define FB_I2SPINC2_LR2PDD 3
813#define FM_I2SPINC2_LR2PDD 0x8
814
815#define FB_I2SPINC2_BC2PDD 2
816#define FM_I2SPINC2_BC2PDD 0x4
817
818#define FB_I2SPINC2_LR1PDD 1
819#define FM_I2SPINC2_LR1PDD 0x2
820
821#define FB_I2SPINC2_BC1PDD 0
822#define FM_I2SPINC2_BC1PDD 0x1
823
824// *** GPIOCTL0 ***
825#define FB_GPIOCTL0_GPIO3INTP 7
826#define FM_GPIOCTL0_GPIO3INTP 0x80
827
828#define FB_GPIOCTL0_GPIO2INTP 6
829#define FM_GPIOCTL0_GPIO2INTP 0x40
830
831#define FB_GPIOCTL0_GPIO3CFG 5
832#define FM_GPIOCTL0_GPIO3CFG 0x20
833
834#define FB_GPIOCTL0_GPIO2CFG 4
835#define FM_GPIOCTL0_GPIO2CFG 0x10
836
837#define FB_GPIOCTL0_GPIO3IO 3
838#define FM_GPIOCTL0_GPIO3IO 0x8
839
840#define FB_GPIOCTL0_GPIO2IO 2
841#define FM_GPIOCTL0_GPIO2IO 0x4
842
843#define FB_GPIOCTL0_GPIO1IO 1
844#define FM_GPIOCTL0_GPIO1IO 0x2
845
846#define FB_GPIOCTL0_GPIO0IO 0
847#define FM_GPIOCTL0_GPIO0IO 0x1
848
849// *** GPIOCTL1 ***
850#define FB_GPIOCTL1_GPIO3 7
851#define FM_GPIOCTL1_GPIO3 0x80
852
853#define FB_GPIOCTL1_GPIO2 6
854#define FM_GPIOCTL1_GPIO2 0x40
855
856#define FB_GPIOCTL1_GPIO1 5
857#define FM_GPIOCTL1_GPIO1 0x20
858
859#define FB_GPIOCTL1_GPIO0 4
860#define FM_GPIOCTL1_GPIO0 0x10
861
862#define FB_GPIOCTL1_GPIO3RD 3
863#define FM_GPIOCTL1_GPIO3RD 0x8
864
865#define FB_GPIOCTL1_GPIO2RD 2
866#define FM_GPIOCTL1_GPIO2RD 0x4
867
868#define FB_GPIOCTL1_GPIO1RD 1
869#define FM_GPIOCTL1_GPIO1RD 0x2
870
871#define FB_GPIOCTL1_GPIO0RD 0
872#define FM_GPIOCTL1_GPIO0RD 0x1
873
874// *** ASRC ***
875#define FB_ASRC_ASRCOBW 7
876#define FM_ASRC_ASRCOBW 0x80
877
878#define FB_ASRC_ASRCIBW 6
879#define FM_ASRC_ASRCIBW 0x40
880
881#define FB_ASRC_ASRCOB 5
882#define FM_ASRC_ASRCOB 0x20
883#define FV_ASRCOB_ACTIVE 0x0
884#define FV_ASRCOB_BYPASSED 0x20
885
886#define FB_ASRC_ASRCIB 4
887#define FM_ASRC_ASRCIB 0x10
888#define FV_ASRCIB_ACTIVE 0x0
889#define FV_ASRCIB_BYPASSED 0x10
890
891#define FB_ASRC_ASRCOL 3
892#define FM_ASRC_ASRCOL 0x8
893
894#define FB_ASRC_ASRCIL 2
895#define FM_ASRC_ASRCIL 0x4
896
897// *** TDMCTL0 ***
898#define FB_TDMCTL0_TDMMD 2
899#define FM_TDMCTL0_TDMMD 0x4
900#define FV_TDMMD_200 0x0
901#define FV_TDMMD_256 0x4
902
903#define FB_TDMCTL0_SLSYNC 1
904#define FM_TDMCTL0_SLSYNC 0x2
905#define FV_SLSYNC_SHORT 0x0
906#define FV_SLSYNC_LONG 0x2
907
908#define FB_TDMCTL0_BDELAY 0
909#define FM_TDMCTL0_BDELAY 0x1
910#define FV_BDELAY_NO_DELAY 0x0
911#define FV_BDELAY_1BCLK_DELAY 0x1
912
913// *** TDMCTL1 ***
914#define FB_TDMCTL1_TDMSO 5
915#define FM_TDMCTL1_TDMSO 0x60
916#define FV_TDMSO_2 0x0
917#define FV_TDMSO_4 0x20
918#define FV_TDMSO_6 0x40
919
920#define FB_TDMCTL1_TDMDSS 3
921#define FM_TDMCTL1_TDMDSS 0x18
922#define FV_TDMDSS_16 0x0
923#define FV_TDMDSS_24 0x10
924#define FV_TDMDSS_32 0x18
925
926#define FB_TDMCTL1_TDMSI 0
927#define FM_TDMCTL1_TDMSI 0x3
928#define FV_TDMSI_2 0x0
929#define FV_TDMSI_4 0x1
930#define FV_TDMSI_6 0x2
931
932// *** PWRM0 ***
933#define FB_PWRM0_INPROC3PU 6
934#define FM_PWRM0_INPROC3PU 0x40
935
936#define FB_PWRM0_INPROC2PU 5
937#define FM_PWRM0_INPROC2PU 0x20
938
939#define FB_PWRM0_INPROC1PU 4
940#define FM_PWRM0_INPROC1PU 0x10
941
942#define FB_PWRM0_INPROC0PU 3
943#define FM_PWRM0_INPROC0PU 0x8
944
945#define FB_PWRM0_MICB2PU 2
946#define FM_PWRM0_MICB2PU 0x4
947
948#define FB_PWRM0_MICB1PU 1
949#define FM_PWRM0_MICB1PU 0x2
950
951#define FB_PWRM0_MCLKPEN 0
952#define FM_PWRM0_MCLKPEN 0x1
953
954// *** PWRM1 ***
955#define FB_PWRM1_SUBPU 7
956#define FM_PWRM1_SUBPU 0x80
957
958#define FB_PWRM1_HPLPU 6
959#define FM_PWRM1_HPLPU 0x40
960
961#define FB_PWRM1_HPRPU 5
962#define FM_PWRM1_HPRPU 0x20
963
964#define FB_PWRM1_SPKLPU 4
965#define FM_PWRM1_SPKLPU 0x10
966
967#define FB_PWRM1_SPKRPU 3
968#define FM_PWRM1_SPKRPU 0x8
969
970#define FB_PWRM1_D2S2PU 2
971#define FM_PWRM1_D2S2PU 0x4
972
973#define FB_PWRM1_D2S1PU 1
974#define FM_PWRM1_D2S1PU 0x2
975
976#define FB_PWRM1_VREFPU 0
977#define FM_PWRM1_VREFPU 0x1
978
979// *** PWRM2 ***
980#define FB_PWRM2_I2S3OPU 5
981#define FM_PWRM2_I2S3OPU 0x20
982#define FV_I2S3OPU_PWR_DOWN 0x0
983#define FV_I2S3OPU_PWR_UP 0x20
984
985#define FB_PWRM2_I2S2OPU 4
986#define FM_PWRM2_I2S2OPU 0x10
987#define FV_I2S2OPU_PWR_DOWN 0x0
988#define FV_I2S2OPU_PWR_UP 0x10
989
990#define FB_PWRM2_I2S1OPU 3
991#define FM_PWRM2_I2S1OPU 0x8
992#define FV_I2S1OPU_PWR_DOWN 0x0
993#define FV_I2S1OPU_PWR_UP 0x8
994
995#define FB_PWRM2_I2S3IPU 2
996#define FM_PWRM2_I2S3IPU 0x4
997#define FV_I2S3IPU_PWR_DOWN 0x0
998#define FV_I2S3IPU_PWR_UP 0x4
999
1000#define FB_PWRM2_I2S2IPU 1
1001#define FM_PWRM2_I2S2IPU 0x2
1002#define FV_I2S2IPU_PWR_DOWN 0x0
1003#define FV_I2S2IPU_PWR_UP 0x2
1004
1005#define FB_PWRM2_I2S1IPU 0
1006#define FM_PWRM2_I2S1IPU 0x1
1007#define FV_I2S1IPU_PWR_DOWN 0x0
1008#define FV_I2S1IPU_PWR_UP 0x1
1009
1010#define PWRM2_I2SOPU_PWR_DOWN 0x0
1011#define PWRM2_I2SOPU_PWR_UP 0x1
1012#define PWRM2_I2SIPU_PWR_DOWN 0x0
1013#define PWRM2_I2SIPU_PWR_UP 0x1
1014
1015// *** PWRM3 ***
1016#define FB_PWRM3_BGSBUP 6
1017#define FM_PWRM3_BGSBUP 0x40
1018#define FV_BGSBUP_ON 0x0
1019#define FV_BGSBUP_OFF 0x40
1020
1021#define FB_PWRM3_VGBAPU 5
1022#define FM_PWRM3_VGBAPU 0x20
1023#define FV_VGBAPU_ON 0x0
1024#define FV_VGBAPU_OFF 0x20
1025
1026#define FB_PWRM3_LLINEPU 4
1027#define FM_PWRM3_LLINEPU 0x10
1028
1029#define FB_PWRM3_RLINEPU 3
1030#define FM_PWRM3_RLINEPU 0x8
1031
1032// *** PWRM4 ***
1033#define FB_PWRM4_OPSUBPU 4
1034#define FM_PWRM4_OPSUBPU 0x10
1035
1036#define FB_PWRM4_OPDACLPU 3
1037#define FM_PWRM4_OPDACLPU 0x8
1038
1039#define FB_PWRM4_OPDACRPU 2
1040#define FM_PWRM4_OPDACRPU 0x4
1041
1042#define FB_PWRM4_OPSPKLPU 1
1043#define FM_PWRM4_OPSPKLPU 0x2
1044
1045#define FB_PWRM4_OPSPKRPU 0
1046#define FM_PWRM4_OPSPKRPU 0x1
1047
1048// *** I2SIDCTL ***
1049#define FB_I2SIDCTL_I2SI3DCTL 4
1050#define FM_I2SIDCTL_I2SI3DCTL 0x30
1051
1052#define FB_I2SIDCTL_I2SI2DCTL 2
1053#define FM_I2SIDCTL_I2SI2DCTL 0xC
1054
1055#define FB_I2SIDCTL_I2SI1DCTL 0
1056#define FM_I2SIDCTL_I2SI1DCTL 0x3
1057
1058// *** I2SODCTL ***
1059#define FB_I2SODCTL_I2SO3DCTL 4
1060#define FM_I2SODCTL_I2SO3DCTL 0x30
1061
1062#define FB_I2SODCTL_I2SO2DCTL 2
1063#define FM_I2SODCTL_I2SO2DCTL 0xC
1064
1065#define FB_I2SODCTL_I2SO1DCTL 0
1066#define FM_I2SODCTL_I2SO1DCTL 0x3
1067
1068// *** AUDIOMUX1 ***
1069#define FB_AUDIOMUX1_ASRCIMUX 6
1070#define FM_AUDIOMUX1_ASRCIMUX 0xC0
1071#define FV_ASRCIMUX_NONE 0x0
1072#define FV_ASRCIMUX_I2S1 0x40
1073#define FV_ASRCIMUX_I2S2 0x80
1074#define FV_ASRCIMUX_I2S3 0xC0
1075
1076#define FB_AUDIOMUX1_I2S2MUX 3
1077#define FM_AUDIOMUX1_I2S2MUX 0x38
1078#define FV_I2S2MUX_I2S1 0x0
1079#define FV_I2S2MUX_I2S2 0x8
1080#define FV_I2S2MUX_I2S3 0x10
1081#define FV_I2S2MUX_ADC_DMIC 0x18
1082#define FV_I2S2MUX_DMIC2 0x20
1083#define FV_I2S2MUX_CLASSD_DSP 0x28
1084#define FV_I2S2MUX_DAC_DSP 0x30
1085#define FV_I2S2MUX_SUB_DSP 0x38
1086
1087#define FB_AUDIOMUX1_I2S1MUX 0
1088#define FM_AUDIOMUX1_I2S1MUX 0x7
1089#define FV_I2S1MUX_I2S1 0x0
1090#define FV_I2S1MUX_I2S2 0x1
1091#define FV_I2S1MUX_I2S3 0x2
1092#define FV_I2S1MUX_ADC_DMIC 0x3
1093#define FV_I2S1MUX_DMIC2 0x4
1094#define FV_I2S1MUX_CLASSD_DSP 0x5
1095#define FV_I2S1MUX_DAC_DSP 0x6
1096#define FV_I2S1MUX_SUB_DSP 0x7
1097
1098#define AUDIOMUX1_I2SMUX_I2S1 0x0
1099#define AUDIOMUX1_I2SMUX_I2S2 0x1
1100#define AUDIOMUX1_I2SMUX_I2S3 0x2
1101#define AUDIOMUX1_I2SMUX_ADC_DMIC 0x3
1102#define AUDIOMUX1_I2SMUX_DMIC2 0x4
1103#define AUDIOMUX1_I2SMUX_CLASSD_DSP 0x5
1104#define AUDIOMUX1_I2SMUX_DAC_DSP 0x6
1105#define AUDIOMUX1_I2SMUX_SUB_DSP 0x7
1106
1107// *** AUDIOMUX2 ***
1108#define FB_AUDIOMUX2_ASRCOMUX 6
1109#define FM_AUDIOMUX2_ASRCOMUX 0xC0
1110#define FV_ASRCOMUX_NONE 0x0
1111#define FV_ASRCOMUX_I2S1 0x40
1112#define FV_ASRCOMUX_I2S2 0x80
1113#define FV_ASRCOMUX_I2S3 0xC0
1114
1115#define FB_AUDIOMUX2_DACMUX 3
1116#define FM_AUDIOMUX2_DACMUX 0x38
1117#define FV_DACMUX_I2S1 0x0
1118#define FV_DACMUX_I2S2 0x8
1119#define FV_DACMUX_I2S3 0x10
1120#define FV_DACMUX_ADC_DMIC 0x18
1121#define FV_DACMUX_DMIC2 0x20
1122#define FV_DACMUX_CLASSD_DSP 0x28
1123#define FV_DACMUX_DAC_DSP 0x30
1124#define FV_DACMUX_SUB_DSP 0x38
1125
1126#define FB_AUDIOMUX2_I2S3MUX 0
1127#define FM_AUDIOMUX2_I2S3MUX 0x7
1128#define FV_I2S3MUX_I2S1 0x0
1129#define FV_I2S3MUX_I2S2 0x1
1130#define FV_I2S3MUX_I2S3 0x2
1131#define FV_I2S3MUX_ADC_DMIC 0x3
1132#define FV_I2S3MUX_DMIC2 0x4
1133#define FV_I2S3MUX_CLASSD_DSP 0x5
1134#define FV_I2S3MUX_DAC_DSP 0x6
1135#define FV_I2S3MUX_SUB_DSP 0x7
1136
1137// *** AUDIOMUX3 ***
1138#define FB_AUDIOMUX3_SUBMUX 3
1139#define FM_AUDIOMUX3_SUBMUX 0xF8
1140#define FV_SUBMUX_I2S1_L 0x0
1141#define FV_SUBMUX_I2S1_R 0x8
1142#define FV_SUBMUX_I2S1_LR 0x10
1143#define FV_SUBMUX_I2S2_L 0x18
1144#define FV_SUBMUX_I2S2_R 0x20
1145#define FV_SUBMUX_I2S2_LR 0x28
1146#define FV_SUBMUX_I2S3_L 0x30
1147#define FV_SUBMUX_I2S3_R 0x38
1148#define FV_SUBMUX_I2S3_LR 0x40
1149#define FV_SUBMUX_ADC_DMIC_L 0x48
1150#define FV_SUBMUX_ADC_DMIC_R 0x50
1151#define FV_SUBMUX_ADC_DMIC_LR 0x58
1152#define FV_SUBMUX_DMIC_L 0x60
1153#define FV_SUBMUX_DMIC_R 0x68
1154#define FV_SUBMUX_DMIC_LR 0x70
1155#define FV_SUBMUX_CLASSD_DSP_L 0x78
1156#define FV_SUBMUX_CLASSD_DSP_R 0x80
1157#define FV_SUBMUX_CLASSD_DSP_LR 0x88
1158
1159#define FB_AUDIOMUX3_CLSSDMUX 0
1160#define FM_AUDIOMUX3_CLSSDMUX 0x7
1161#define FV_CLSSDMUX_I2S1 0x0
1162#define FV_CLSSDMUX_I2S2 0x1
1163#define FV_CLSSDMUX_I2S3 0x2
1164#define FV_CLSSDMUX_ADC_DMIC 0x3
1165#define FV_CLSSDMUX_DMIC2 0x4
1166#define FV_CLSSDMUX_CLASSD_DSP 0x5
1167#define FV_CLSSDMUX_DAC_DSP 0x6
1168#define FV_CLSSDMUX_SUB_DSP 0x7
1169
1170// *** HSDCTL1 ***
1171#define FB_HSDCTL1_HPJKTYPE 7
1172#define FM_HSDCTL1_HPJKTYPE 0x80
1173
1174#define FB_HSDCTL1_CON_DET_PWD 6
1175#define FM_HSDCTL1_CON_DET_PWD 0x40
1176
1177#define FB_HSDCTL1_DETCYC 4
1178#define FM_HSDCTL1_DETCYC 0x30
1179
1180#define FB_HSDCTL1_HPDLYBYP 3
1181#define FM_HSDCTL1_HPDLYBYP 0x8
1182
1183#define FB_HSDCTL1_HSDETPOL 2
1184#define FM_HSDCTL1_HSDETPOL 0x4
1185
1186#define FB_HSDCTL1_HPID_EN 1
1187#define FM_HSDCTL1_HPID_EN 0x2
1188
1189#define FB_HSDCTL1_GBLHS_EN 0
1190#define FM_HSDCTL1_GBLHS_EN 0x1
1191
1192// *** HSDCTL2 ***
1193#define FB_HSDCTL2_FMICBIAS1 6
1194#define FM_HSDCTL2_FMICBIAS1 0xC0
1195
1196#define FB_HSDCTL2_MB1MODE 5
1197#define FM_HSDCTL2_MB1MODE 0x20
1198#define FV_MB1MODE_AUTO 0x0
1199#define FV_MB1MODE_MANUAL 0x20
1200
1201#define FB_HSDCTL2_FORCETRG 4
1202#define FM_HSDCTL2_FORCETRG 0x10
1203
1204#define FB_HSDCTL2_SWMODE 3
1205#define FM_HSDCTL2_SWMODE 0x8
1206
1207#define FB_HSDCTL2_GHSHIZ 2
1208#define FM_HSDCTL2_GHSHIZ 0x4
1209
1210#define FB_HSDCTL2_FPLUGTYPE 0
1211#define FM_HSDCTL2_FPLUGTYPE 0x3
1212
1213// *** HSDSTAT ***
1214#define FB_HSDSTAT_MBIAS1DRV 5
1215#define FM_HSDSTAT_MBIAS1DRV 0x60
1216
1217#define FB_HSDSTAT_HSDETSTAT 3
1218#define FM_HSDSTAT_HSDETSTAT 0x8
1219
1220#define FB_HSDSTAT_PLUGTYPE 1
1221#define FM_HSDSTAT_PLUGTYPE 0x6
1222
1223#define FB_HSDSTAT_HSDETDONE 0
1224#define FM_HSDSTAT_HSDETDONE 0x1
1225
1226// *** HSDDELAY ***
1227#define FB_HSDDELAY_T_STABLE 0
1228#define FM_HSDDELAY_T_STABLE 0x7
1229
1230// *** BUTCTL ***
1231#define FB_BUTCTL_BPUSHSTAT 7
1232#define FM_BUTCTL_BPUSHSTAT 0x80
1233
1234#define FB_BUTCTL_BPUSHDET 6
1235#define FM_BUTCTL_BPUSHDET 0x40
1236
1237#define FB_BUTCTL_BPUSHEN 5
1238#define FM_BUTCTL_BPUSHEN 0x20
1239
1240#define FB_BUTCTL_BSTABLE_L 3
1241#define FM_BUTCTL_BSTABLE_L 0x18
1242
1243#define FB_BUTCTL_BSTABLE_S 0
1244#define FM_BUTCTL_BSTABLE_S 0x7
1245
1246// *** CH0AIC ***
1247#define FB_CH0AIC_INSELL 6
1248#define FM_CH0AIC_INSELL 0xC0
1249
1250#define FB_CH0AIC_MICBST0 4
1251#define FM_CH0AIC_MICBST0 0x30
1252
1253#define FB_CH0AIC_LADCIN 2
1254#define FM_CH0AIC_LADCIN 0xC
1255
1256#define FB_CH0AIC_IN_BYPS_L_SEL 1
1257#define FM_CH0AIC_IN_BYPS_L_SEL 0x2
1258
1259#define FB_CH0AIC_IPCH0S 0
1260#define FM_CH0AIC_IPCH0S 0x1
1261
1262// *** CH1AIC ***
1263#define FB_CH1AIC_INSELR 6
1264#define FM_CH1AIC_INSELR 0xC0
1265
1266#define FB_CH1AIC_MICBST1 4
1267#define FM_CH1AIC_MICBST1 0x30
1268
1269#define FB_CH1AIC_RADCIN 2
1270#define FM_CH1AIC_RADCIN 0xC
1271
1272#define FB_CH1AIC_IN_BYPS_R_SEL 1
1273#define FM_CH1AIC_IN_BYPS_R_SEL 0x2
1274
1275#define FB_CH1AIC_IPCH1S 0
1276#define FM_CH1AIC_IPCH1S 0x1
1277
1278// *** ICTL0 ***
1279#define FB_ICTL0_IN1POL 7
1280#define FM_ICTL0_IN1POL 0x80
1281
1282#define FB_ICTL0_IN0POL 6
1283#define FM_ICTL0_IN0POL 0x40
1284
1285#define FB_ICTL0_INPCH10SEL 4
1286#define FM_ICTL0_INPCH10SEL 0x30
1287
1288#define FB_ICTL0_IN1MUTE 3
1289#define FM_ICTL0_IN1MUTE 0x8
1290
1291#define FB_ICTL0_IN0MUTE 2
1292#define FM_ICTL0_IN0MUTE 0x4
1293
1294#define FB_ICTL0_IN1HP 1
1295#define FM_ICTL0_IN1HP 0x2
1296
1297#define FB_ICTL0_IN0HP 0
1298#define FM_ICTL0_IN0HP 0x1
1299
1300// *** ICTL1 ***
1301#define FB_ICTL1_IN3POL 7
1302#define FM_ICTL1_IN3POL 0x80
1303
1304#define FB_ICTL1_IN2POL 6
1305#define FM_ICTL1_IN2POL 0x40
1306
1307#define FB_ICTL1_INPCH32SEL 4
1308#define FM_ICTL1_INPCH32SEL 0x30
1309
1310#define FB_ICTL1_IN3MUTE 3
1311#define FM_ICTL1_IN3MUTE 0x8
1312
1313#define FB_ICTL1_IN2MUTE 2
1314#define FM_ICTL1_IN2MUTE 0x4
1315
1316#define FB_ICTL1_IN3HP 1
1317#define FM_ICTL1_IN3HP 0x2
1318
1319#define FB_ICTL1_IN2HP 0
1320#define FM_ICTL1_IN2HP 0x1
1321
1322// *** MICBIAS ***
1323#define FB_MICBIAS_MICBOV2 4
1324#define FM_MICBIAS_MICBOV2 0x30
1325
1326#define FB_MICBIAS_MICBOV1 6
1327#define FM_MICBIAS_MICBOV1 0xC0
1328
1329#define FB_MICBIAS_SPARE1 2
1330#define FM_MICBIAS_SPARE1 0xC
1331
1332#define FB_MICBIAS_SPARE2 0
1333#define FM_MICBIAS_SPARE2 0x3
1334
1335// *** PGAZ ***
1336#define FB_PGAZ_INHPOR 1
1337#define FM_PGAZ_INHPOR 0x2
1338
1339#define FB_PGAZ_TOEN 0
1340#define FM_PGAZ_TOEN 0x1
1341
1342// *** ASRCILVOL ***
1343#define FB_ASRCILVOL_ASRCILVOL 0
1344#define FM_ASRCILVOL_ASRCILVOL 0xFF
1345
1346// *** ASRCIRVOL ***
1347#define FB_ASRCIRVOL_ASRCIRVOL 0
1348#define FM_ASRCIRVOL_ASRCIRVOL 0xFF
1349
1350// *** ASRCOLVOL ***
1351#define FB_ASRCOLVOL_ASRCOLVOL 0
1352#define FM_ASRCOLVOL_ASRCOLVOL 0xFF
1353
1354// *** ASRCORVOL ***
1355#define FB_ASRCORVOL_ASRCOLVOL 0
1356#define FM_ASRCORVOL_ASRCOLVOL 0xFF
1357
1358// *** IVOLCTLU ***
1359#define FB_IVOLCTLU_IFADE 3
1360#define FM_IVOLCTLU_IFADE 0x8
1361
1362#define FB_IVOLCTLU_INPVOLU 2
1363#define FM_IVOLCTLU_INPVOLU 0x4
1364
1365#define FB_IVOLCTLU_PGAVOLU 1
1366#define FM_IVOLCTLU_PGAVOLU 0x2
1367
1368#define FB_IVOLCTLU_ASRCVOLU 0
1369#define FM_IVOLCTLU_ASRCVOLU 0x1
1370
1371// *** ALCCTL0 ***
1372#define FB_ALCCTL0_ALCMODE 7
1373#define FM_ALCCTL0_ALCMODE 0x80
1374
1375#define FB_ALCCTL0_ALCREF 4
1376#define FM_ALCCTL0_ALCREF 0x70
1377
1378#define FB_ALCCTL0_ALCEN3 3
1379#define FM_ALCCTL0_ALCEN3 0x8
1380
1381#define FB_ALCCTL0_ALCEN2 2
1382#define FM_ALCCTL0_ALCEN2 0x4
1383
1384#define FB_ALCCTL0_ALCEN1 1
1385#define FM_ALCCTL0_ALCEN1 0x2
1386
1387#define FB_ALCCTL0_ALCEN0 0
1388#define FM_ALCCTL0_ALCEN0 0x1
1389
1390// *** ALCCTL1 ***
1391#define FB_ALCCTL1_MAXGAIN 4
1392#define FM_ALCCTL1_MAXGAIN 0x70
1393
1394#define FB_ALCCTL1_ALCL 0
1395#define FM_ALCCTL1_ALCL 0xF
1396
1397// *** ALCCTL2 ***
1398#define FB_ALCCTL2_ALCZC 7
1399#define FM_ALCCTL2_ALCZC 0x80
1400
1401#define FB_ALCCTL2_MINGAIN 4
1402#define FM_ALCCTL2_MINGAIN 0x70
1403
1404#define FB_ALCCTL2_HLD 0
1405#define FM_ALCCTL2_HLD 0xF
1406
1407// *** ALCCTL3 ***
1408#define FB_ALCCTL3_DCY 4
1409#define FM_ALCCTL3_DCY 0xF0
1410
1411#define FB_ALCCTL3_ATK 0
1412#define FM_ALCCTL3_ATK 0xF
1413
1414// *** NGATE ***
1415#define FB_NGATE_NGTH 3
1416#define FM_NGATE_NGTH 0xF8
1417
1418#define FB_NGATE_NGG 1
1419#define FM_NGATE_NGG 0x6
1420
1421#define FB_NGATE_NGAT 0
1422#define FM_NGATE_NGAT 0x1
1423
1424// *** DMICCTL ***
1425#define FB_DMICCTL_DMIC2EN 7
1426#define FM_DMICCTL_DMIC2EN 0x80
1427
1428#define FB_DMICCTL_DMIC1EN 6
1429#define FM_DMICCTL_DMIC1EN 0x40
1430
1431#define FB_DMICCTL_DMONO 4
1432#define FM_DMICCTL_DMONO 0x10
1433
1434#define FB_DMICCTL_DMDCLK 2
1435#define FM_DMICCTL_DMDCLK 0xC
1436
1437#define FB_DMICCTL_DMRATE 0
1438#define FM_DMICCTL_DMRATE 0x3
1439
1440// *** DACCTL ***
1441#define FB_DACCTL_DACPOLR 7
1442#define FM_DACCTL_DACPOLR 0x80
1443#define FV_DACPOLR_NORMAL 0x0
1444#define FV_DACPOLR_INVERTED 0x80
1445
1446#define FB_DACCTL_DACPOLL 6
1447#define FM_DACCTL_DACPOLL 0x40
1448#define FV_DACPOLL_NORMAL 0x0
1449#define FV_DACPOLL_INVERTED 0x40
1450
1451#define FB_DACCTL_DACDITH 4
1452#define FM_DACCTL_DACDITH 0x30
1453#define FV_DACDITH_DYNAMIC_HALF 0x0
1454#define FV_DACDITH_DYNAMIC_FULL 0x10
1455#define FV_DACDITH_DISABLED 0x20
1456#define FV_DACDITH_STATIC 0x30
1457
1458#define FB_DACCTL_DACMUTE 3
1459#define FM_DACCTL_DACMUTE 0x8
1460#define FV_DACMUTE_ENABLE 0x8
1461#define FV_DACMUTE_DISABLE 0x0
1462
1463#define FB_DACCTL_DACDEM 2
1464#define FM_DACCTL_DACDEM 0x4
1465#define FV_DACDEM_ENABLE 0x4
1466#define FV_DACDEM_DISABLE 0x0
1467
1468#define FB_DACCTL_ABYPASS 0
1469#define FM_DACCTL_ABYPASS 0x1
1470
1471// *** SPKCTL ***
1472#define FB_SPKCTL_SPKPOLR 7
1473#define FM_SPKCTL_SPKPOLR 0x80
1474#define FV_SPKPOLR_NORMAL 0x0
1475#define FV_SPKPOLR_INVERTED 0x80
1476
1477#define FB_SPKCTL_SPKPOLL 6
1478#define FM_SPKCTL_SPKPOLL 0x40
1479#define FV_SPKPOLL_NORMAL 0x0
1480#define FV_SPKPOLL_INVERTED 0x40
1481
1482#define FB_SPKCTL_SPKMUTE 3
1483#define FM_SPKCTL_SPKMUTE 0x8
1484#define FV_SPKMUTE_ENABLE 0x8
1485#define FV_SPKMUTE_DISABLE 0x0
1486
1487#define FB_SPKCTL_SPKDEM 2
1488#define FM_SPKCTL_SPKDEM 0x4
1489#define FV_SPKDEM_ENABLE 0x4
1490#define FV_SPKDEM_DISABLE 0x0
1491
1492// *** SUBCTL ***
1493#define FB_SUBCTL_SUBPOL 7
1494#define FM_SUBCTL_SUBPOL 0x80
1495
1496#define FB_SUBCTL_SUBMUTE 3
1497#define FM_SUBCTL_SUBMUTE 0x8
1498
1499#define FB_SUBCTL_SUBDEM 2
1500#define FM_SUBCTL_SUBDEM 0x4
1501
1502#define FB_SUBCTL_SUBMUX 1
1503#define FM_SUBCTL_SUBMUX 0x2
1504
1505#define FB_SUBCTL_SUBILMDIS 0
1506#define FM_SUBCTL_SUBILMDIS 0x1
1507
1508// *** DCCTL ***
1509#define FB_DCCTL_SUBDCBYP 7
1510#define FM_DCCTL_SUBDCBYP 0x80
1511
1512#define FB_DCCTL_DACDCBYP 6
1513#define FM_DCCTL_DACDCBYP 0x40
1514
1515#define FB_DCCTL_SPKDCBYP 5
1516#define FM_DCCTL_SPKDCBYP 0x20
1517
1518#define FB_DCCTL_DCCOEFSEL 0
1519#define FM_DCCTL_DCCOEFSEL 0x7
1520
1521// *** OVOLCTLU ***
1522#define FB_OVOLCTLU_OFADE 4
1523#define FM_OVOLCTLU_OFADE 0x10
1524
1525#define FB_OVOLCTLU_SUBVOLU 3
1526#define FM_OVOLCTLU_SUBVOLU 0x8
1527
1528#define FB_OVOLCTLU_MVOLU 2
1529#define FM_OVOLCTLU_MVOLU 0x4
1530
1531#define FB_OVOLCTLU_SPKVOLU 1
1532#define FM_OVOLCTLU_SPKVOLU 0x2
1533
1534#define FB_OVOLCTLU_HPVOLU 0
1535#define FM_OVOLCTLU_HPVOLU 0x1
1536
1537// *** MUTEC ***
1538#define FB_MUTEC_ZDSTAT 7
1539#define FM_MUTEC_ZDSTAT 0x80
1540
1541#define FB_MUTEC_ZDLEN 4
1542#define FM_MUTEC_ZDLEN 0x30
1543
1544#define FB_MUTEC_APWD 3
1545#define FM_MUTEC_APWD 0x8
1546
1547#define FB_MUTEC_AMUTE 2
1548#define FM_MUTEC_AMUTE 0x4
1549
1550// *** MVOLL ***
1551#define FB_MVOLL_MVOL_L 0
1552#define FM_MVOLL_MVOL_L 0xFF
1553
1554// *** MVOLR ***
1555#define FB_MVOLR_MVOL_R 0
1556#define FM_MVOLR_MVOL_R 0xFF
1557
1558// *** HPVOLL ***
1559#define FB_HPVOLL_HPVOL_L 0
1560#define FM_HPVOLL_HPVOL_L 0x7F
1561
1562// *** HPVOLR ***
1563#define FB_HPVOLR_HPVOL_R 0
1564#define FM_HPVOLR_HPVOL_R 0x7F
1565
1566// *** SPKVOLL ***
1567#define FB_SPKVOLL_SPKVOL_L 0
1568#define FM_SPKVOLL_SPKVOL_L 0x7F
1569
1570// *** SPKVOLR ***
1571#define FB_SPKVOLR_SPKVOL_R 0
1572#define FM_SPKVOLR_SPKVOL_R 0x7F
1573
1574// *** SUBVOL ***
1575#define FB_SUBVOL_SUBVOL 0
1576#define FM_SUBVOL_SUBVOL 0x7F
1577
1578// *** COP0 ***
1579#define FB_COP0_COPATTEN 7
1580#define FM_COP0_COPATTEN 0x80
1581
1582#define FB_COP0_COPGAIN 6
1583#define FM_COP0_COPGAIN 0x40
1584
1585#define FB_COP0_HDELTAEN 5
1586#define FM_COP0_HDELTAEN 0x20
1587
1588#define FB_COP0_COPTARGET 0
1589#define FM_COP0_COPTARGET 0x1F
1590
1591// *** COP1 ***
1592#define FB_COP1_HDCOMPMODE 6
1593#define FM_COP1_HDCOMPMODE 0x40
1594
1595#define FB_COP1_AVGLENGTH 2
1596#define FM_COP1_AVGLENGTH 0x3C
1597
1598#define FB_COP1_MONRATE 0
1599#define FM_COP1_MONRATE 0x3
1600
1601// *** COPSTAT ***
1602#define FB_COPSTAT_HDELTADET 7
1603#define FM_COPSTAT_HDELTADET 0x80
1604
1605#define FB_COPSTAT_UV 6
1606#define FM_COPSTAT_UV 0x40
1607
1608#define FB_COPSTAT_COPADJ 0
1609#define FM_COPSTAT_COPADJ 0x3F
1610
1611// *** PWM0 ***
1612#define FB_PWM0_SCTO 6
1613#define FM_PWM0_SCTO 0xC0
1614
1615#define FB_PWM0_UVLO 5
1616#define FM_PWM0_UVLO 0x20
1617
1618#define FB_PWM0_BFDIS 3
1619#define FM_PWM0_BFDIS 0x8
1620
1621#define FB_PWM0_PWMMODE 2
1622#define FM_PWM0_PWMMODE 0x4
1623
1624#define FB_PWM0_NOOFFSET 0
1625#define FM_PWM0_NOOFFSET 0x1
1626
1627// *** PWM1 ***
1628#define FB_PWM1_DITHPOS 4
1629#define FM_PWM1_DITHPOS 0x70
1630
1631#define FB_PWM1_DYNDITH 1
1632#define FM_PWM1_DYNDITH 0x2
1633
1634#define FB_PWM1_DITHDIS 0
1635#define FM_PWM1_DITHDIS 0x1
1636
1637// *** PWM2 ***
1638// *** PWM3 ***
1639#define FB_PWM3_PWMMUX 6
1640#define FM_PWM3_PWMMUX 0xC0
1641
1642#define FB_PWM3_CVALUE 0
1643#define FM_PWM3_CVALUE 0x7
1644
1645// *** HPSW ***
1646#define FB_HPSW_HPDETSTATE 4
1647#define FM_HPSW_HPDETSTATE 0x10
1648
1649#define FB_HPSW_HPSWEN 2
1650#define FM_HPSW_HPSWEN 0xC
1651
1652#define FB_HPSW_HPSWPOL 1
1653#define FM_HPSW_HPSWPOL 0x2
1654
1655#define FB_HPSW_TSDEN 0
1656#define FM_HPSW_TSDEN 0x1
1657
1658// *** THERMTS ***
1659#define FB_THERMTS_TRIPHS 7
1660#define FM_THERMTS_TRIPHS 0x80
1661
1662#define FB_THERMTS_TRIPLS 6
1663#define FM_THERMTS_TRIPLS 0x40
1664
1665#define FB_THERMTS_TRIPSPLIT 4
1666#define FM_THERMTS_TRIPSPLIT 0x30
1667
1668#define FB_THERMTS_TRIPSHIFT 2
1669#define FM_THERMTS_TRIPSHIFT 0xC
1670
1671#define FB_THERMTS_TSPOLL 0
1672#define FM_THERMTS_TSPOLL 0x3
1673
1674// *** THERMSPK1 ***
1675#define FB_THERMSPK1_FORCEPWD 7
1676#define FM_THERMSPK1_FORCEPWD 0x80
1677
1678#define FB_THERMSPK1_INSTCUTMODE 6
1679#define FM_THERMSPK1_INSTCUTMODE 0x40
1680
1681#define FB_THERMSPK1_INCRATIO 4
1682#define FM_THERMSPK1_INCRATIO 0x30
1683
1684#define FB_THERMSPK1_INCSTEP 2
1685#define FM_THERMSPK1_INCSTEP 0xC
1686
1687#define FB_THERMSPK1_DECSTEP 0
1688#define FM_THERMSPK1_DECSTEP 0x3
1689
1690// *** THERMSTAT ***
1691#define FB_THERMSTAT_FPWDS 7
1692#define FM_THERMSTAT_FPWDS 0x80
1693
1694#define FB_THERMSTAT_VOLSTAT 0
1695#define FM_THERMSTAT_VOLSTAT 0x7F
1696
1697// *** SCSTAT ***
1698#define FB_SCSTAT_ESDF 3
1699#define FM_SCSTAT_ESDF 0x18
1700
1701#define FB_SCSTAT_CPF 2
1702#define FM_SCSTAT_CPF 0x4
1703
1704#define FB_SCSTAT_CLSDF 0
1705#define FM_SCSTAT_CLSDF 0x3
1706
1707// *** SDMON ***
1708#define FB_SDMON_SDFORCE 7
1709#define FM_SDMON_SDFORCE 0x80
1710
1711#define FB_SDMON_SDVALUE 0
1712#define FM_SDMON_SDVALUE 0x1F
1713
1714// *** SPKEQFILT ***
1715#define FB_SPKEQFILT_EQ2EN 7
1716#define FM_SPKEQFILT_EQ2EN 0x80
1717#define FV_EQ2EN_ENABLE 0x80
1718#define FV_EQ2EN_DISABLE 0x0
1719
1720#define FB_SPKEQFILT_EQ2BE 4
1721#define FM_SPKEQFILT_EQ2BE 0x70
1722
1723#define FB_SPKEQFILT_EQ1EN 3
1724#define FM_SPKEQFILT_EQ1EN 0x8
1725#define FV_EQ1EN_ENABLE 0x8
1726#define FV_EQ1EN_DISABLE 0x0
1727
1728#define FB_SPKEQFILT_EQ1BE 0
1729#define FM_SPKEQFILT_EQ1BE 0x7
1730
1731#define SPKEQFILT_EQEN_ENABLE 0x1
1732#define SPKEQFILT_EQEN_DISABLE 0x0
1733
1734// *** SPKCRWDL ***
1735#define FB_SPKCRWDL_WDATA_L 0
1736#define FM_SPKCRWDL_WDATA_L 0xFF
1737
1738// *** SPKCRWDM ***
1739#define FB_SPKCRWDM_WDATA_M 0
1740#define FM_SPKCRWDM_WDATA_M 0xFF
1741
1742// *** SPKCRWDH ***
1743#define FB_SPKCRWDH_WDATA_H 0
1744#define FM_SPKCRWDH_WDATA_H 0xFF
1745
1746// *** SPKCRRDL ***
1747#define FB_SPKCRRDL_RDATA_L 0
1748#define FM_SPKCRRDL_RDATA_L 0xFF
1749
1750// *** SPKCRRDM ***
1751#define FB_SPKCRRDM_RDATA_M 0
1752#define FM_SPKCRRDM_RDATA_M 0xFF
1753
1754// *** SPKCRRDH ***
1755#define FB_SPKCRRDH_RDATA_H 0
1756#define FM_SPKCRRDH_RDATA_H 0xFF
1757
1758// *** SPKCRADD ***
1759#define FB_SPKCRADD_ADDRESS 0
1760#define FM_SPKCRADD_ADDRESS 0xFF
1761
1762// *** SPKCRS ***
1763#define FB_SPKCRS_ACCSTAT 7
1764#define FM_SPKCRS_ACCSTAT 0x80
1765
1766// *** SPKMBCEN ***
1767#define FB_SPKMBCEN_MBCEN3 2
1768#define FM_SPKMBCEN_MBCEN3 0x4
1769#define FV_MBCEN3_ENABLE 0x4
1770#define FV_MBCEN3_DISABLE 0x0
1771
1772#define FB_SPKMBCEN_MBCEN2 1
1773#define FM_SPKMBCEN_MBCEN2 0x2
1774#define FV_MBCEN2_ENABLE 0x2
1775#define FV_MBCEN2_DISABLE 0x0
1776
1777#define FB_SPKMBCEN_MBCEN1 0
1778#define FM_SPKMBCEN_MBCEN1 0x1
1779#define FV_MBCEN1_ENABLE 0x1
1780#define FV_MBCEN1_DISABLE 0x0
1781
1782#define SPKMBCEN_MBCEN_ENABLE 0x1
1783#define SPKMBCEN_MBCEN_DISABLE 0x0
1784
1785// *** SPKMBCCTL ***
1786#define FB_SPKMBCCTL_LVLMODE3 5
1787#define FM_SPKMBCCTL_LVLMODE3 0x20
1788
1789#define FB_SPKMBCCTL_WINSEL3 4
1790#define FM_SPKMBCCTL_WINSEL3 0x10
1791
1792#define FB_SPKMBCCTL_LVLMODE2 3
1793#define FM_SPKMBCCTL_LVLMODE2 0x8
1794
1795#define FB_SPKMBCCTL_WINSEL2 2
1796#define FM_SPKMBCCTL_WINSEL2 0x4
1797
1798#define FB_SPKMBCCTL_LVLMODE1 1
1799#define FM_SPKMBCCTL_LVLMODE1 0x2
1800
1801#define FB_SPKMBCCTL_WINSEL1 0
1802#define FM_SPKMBCCTL_WINSEL1 0x1
1803
1804// *** SPKCLECTL ***
1805#define FB_SPKCLECTL_LVLMODE 4
1806#define FM_SPKCLECTL_LVLMODE 0x10
1807
1808#define FB_SPKCLECTL_WINSEL 3
1809#define FM_SPKCLECTL_WINSEL 0x8
1810
1811#define FB_SPKCLECTL_EXPEN 2
1812#define FM_SPKCLECTL_EXPEN 0x4
1813#define FV_EXPEN_ENABLE 0x4
1814#define FV_EXPEN_DISABLE 0x0
1815
1816#define FB_SPKCLECTL_LIMEN 1
1817#define FM_SPKCLECTL_LIMEN 0x2
1818#define FV_LIMEN_ENABLE 0x2
1819#define FV_LIMEN_DISABLE 0x0
1820
1821#define FB_SPKCLECTL_COMPEN 0
1822#define FM_SPKCLECTL_COMPEN 0x1
1823#define FV_COMPEN_ENABLE 0x1
1824#define FV_COMPEN_DISABLE 0x0
1825
1826// *** SPKCLEMUG ***
1827#define FB_SPKCLEMUG_MUGAIN 0
1828#define FM_SPKCLEMUG_MUGAIN 0x1F
1829
1830// *** SPKCOMPTHR ***
1831#define FB_SPKCOMPTHR_THRESH 0
1832#define FM_SPKCOMPTHR_THRESH 0xFF
1833
1834// *** SPKCOMPRAT ***
1835#define FB_SPKCOMPRAT_RATIO 0
1836#define FM_SPKCOMPRAT_RATIO 0x1F
1837
1838// *** SPKCOMPATKL ***
1839#define FB_SPKCOMPATKL_TCATKL 0
1840#define FM_SPKCOMPATKL_TCATKL 0xFF
1841
1842// *** SPKCOMPATKH ***
1843#define FB_SPKCOMPATKH_TCATKH 0
1844#define FM_SPKCOMPATKH_TCATKH 0xFF
1845
1846// *** SPKCOMPRELL ***
1847#define FB_SPKCOMPRELL_TCRELL 0
1848#define FM_SPKCOMPRELL_TCRELL 0xFF
1849
1850// *** SPKCOMPRELH ***
1851#define FB_SPKCOMPRELH_TCRELH 0
1852#define FM_SPKCOMPRELH_TCRELH 0xFF
1853
1854// *** SPKLIMTHR ***
1855#define FB_SPKLIMTHR_THRESH 0
1856#define FM_SPKLIMTHR_THRESH 0xFF
1857
1858// *** SPKLIMTGT ***
1859#define FB_SPKLIMTGT_TARGET 0
1860#define FM_SPKLIMTGT_TARGET 0xFF
1861
1862// *** SPKLIMATKL ***
1863#define FB_SPKLIMATKL_TCATKL 0
1864#define FM_SPKLIMATKL_TCATKL 0xFF
1865
1866// *** SPKLIMATKH ***
1867#define FB_SPKLIMATKH_TCATKH 0
1868#define FM_SPKLIMATKH_TCATKH 0xFF
1869
1870// *** SPKLIMRELL ***
1871#define FB_SPKLIMRELL_TCRELL 0
1872#define FM_SPKLIMRELL_TCRELL 0xFF
1873
1874// *** SPKLIMRELH ***
1875#define FB_SPKLIMRELH_TCRELH 0
1876#define FM_SPKLIMRELH_TCRELH 0xFF
1877
1878// *** SPKEXPTHR ***
1879#define FB_SPKEXPTHR_THRESH 0
1880#define FM_SPKEXPTHR_THRESH 0xFF
1881
1882// *** SPKEXPRAT ***
1883#define FB_SPKEXPRAT_RATIO 0
1884#define FM_SPKEXPRAT_RATIO 0x7
1885
1886// *** SPKEXPATKL ***
1887#define FB_SPKEXPATKL_TCATKL 0
1888#define FM_SPKEXPATKL_TCATKL 0xFF
1889
1890// *** SPKEXPATKH ***
1891#define FB_SPKEXPATKH_TCATKH 0
1892#define FM_SPKEXPATKH_TCATKH 0xFF
1893
1894// *** SPKEXPRELL ***
1895#define FB_SPKEXPRELL_TCRELL 0
1896#define FM_SPKEXPRELL_TCRELL 0xFF
1897
1898// *** SPKEXPRELH ***
1899#define FB_SPKEXPRELH_TCRELH 0
1900#define FM_SPKEXPRELH_TCRELH 0xFF
1901
1902// *** SPKFXCTL ***
1903#define FB_SPKFXCTL_3DEN 4
1904#define FM_SPKFXCTL_3DEN 0x10
1905
1906#define FB_SPKFXCTL_TEEN 3
1907#define FM_SPKFXCTL_TEEN 0x8
1908
1909#define FB_SPKFXCTL_TNLFBYP 2
1910#define FM_SPKFXCTL_TNLFBYP 0x4
1911
1912#define FB_SPKFXCTL_BEEN 1
1913#define FM_SPKFXCTL_BEEN 0x2
1914
1915#define FB_SPKFXCTL_BNLFBYP 0
1916#define FM_SPKFXCTL_BNLFBYP 0x1
1917
1918// *** DACEQFILT ***
1919#define FB_DACEQFILT_EQ2EN 7
1920#define FM_DACEQFILT_EQ2EN 0x80
1921#define FV_EQ2EN_ENABLE 0x80
1922#define FV_EQ2EN_DISABLE 0x0
1923
1924#define FB_DACEQFILT_EQ2BE 4
1925#define FM_DACEQFILT_EQ2BE 0x70
1926
1927#define FB_DACEQFILT_EQ1EN 3
1928#define FM_DACEQFILT_EQ1EN 0x8
1929#define FV_EQ1EN_ENABLE 0x8
1930#define FV_EQ1EN_DISABLE 0x0
1931
1932#define FB_DACEQFILT_EQ1BE 0
1933#define FM_DACEQFILT_EQ1BE 0x7
1934
1935#define DACEQFILT_EQEN_ENABLE 0x1
1936#define DACEQFILT_EQEN_DISABLE 0x0
1937
1938// *** DACCRWDL ***
1939#define FB_DACCRWDL_WDATA_L 0
1940#define FM_DACCRWDL_WDATA_L 0xFF
1941
1942// *** DACCRWDM ***
1943#define FB_DACCRWDM_WDATA_M 0
1944#define FM_DACCRWDM_WDATA_M 0xFF
1945
1946// *** DACCRWDH ***
1947#define FB_DACCRWDH_WDATA_H 0
1948#define FM_DACCRWDH_WDATA_H 0xFF
1949
1950// *** DACCRRDL ***
1951#define FB_DACCRRDL_RDATA_L 0
1952#define FM_DACCRRDL_RDATA_L 0xFF
1953
1954// *** DACCRRDM ***
1955#define FB_DACCRRDM_RDATA_M 0
1956#define FM_DACCRRDM_RDATA_M 0xFF
1957
1958// *** DACCRRDH ***
1959#define FB_DACCRRDH_RDATA_H 0
1960#define FM_DACCRRDH_RDATA_H 0xFF
1961
1962// *** DACCRADD ***
1963#define FB_DACCRADD_ADDRESS 0
1964#define FM_DACCRADD_ADDRESS 0xFF
1965
1966// *** DACCRS ***
1967#define FB_DACCRS_ACCSTAT 7
1968#define FM_DACCRS_ACCSTAT 0x80
1969
1970// *** DACMBCEN ***
1971#define FB_DACMBCEN_MBCEN3 2
1972#define FM_DACMBCEN_MBCEN3 0x4
1973#define FV_MBCEN3_ENABLE 0x4
1974#define FV_MBCEN3_DISABLE 0x0
1975
1976#define FB_DACMBCEN_MBCEN2 1
1977#define FM_DACMBCEN_MBCEN2 0x2
1978#define FV_MBCEN2_ENABLE 0x2
1979#define FV_MBCEN2_DISABLE 0x0
1980
1981#define FB_DACMBCEN_MBCEN1 0
1982#define FM_DACMBCEN_MBCEN1 0x1
1983#define FV_MBCEN1_ENABLE 0x1
1984#define FV_MBCEN1_DISABLE 0x0
1985
1986#define DACMBCEN_MBCEN_ENABLE 0x1
1987#define DACMBCEN_MBCEN_DISABLE 0x0
1988
1989// *** DACMBCCTL ***
1990#define FB_DACMBCCTL_LVLMODE3 5
1991#define FM_DACMBCCTL_LVLMODE3 0x20
1992
1993#define FB_DACMBCCTL_WINSEL3 4
1994#define FM_DACMBCCTL_WINSEL3 0x10
1995
1996#define FB_DACMBCCTL_LVLMODE2 3
1997#define FM_DACMBCCTL_LVLMODE2 0x8
1998
1999#define FB_DACMBCCTL_WINSEL2 2
2000#define FM_DACMBCCTL_WINSEL2 0x4
2001
2002#define FB_DACMBCCTL_LVLMODE1 1
2003#define FM_DACMBCCTL_LVLMODE1 0x2
2004
2005#define FB_DACMBCCTL_WINSEL1 0
2006#define FM_DACMBCCTL_WINSEL1 0x1
2007
2008// *** DACCLECTL ***
2009#define FB_DACCLECTL_LVLMODE 4
2010#define FM_DACCLECTL_LVLMODE 0x10
2011
2012#define FB_DACCLECTL_WINSEL 3
2013#define FM_DACCLECTL_WINSEL 0x8
2014
2015#define FB_DACCLECTL_EXPEN 2
2016#define FM_DACCLECTL_EXPEN 0x4
2017#define FV_EXPEN_ENABLE 0x4
2018#define FV_EXPEN_DISABLE 0x0
2019
2020#define FB_DACCLECTL_LIMEN 1
2021#define FM_DACCLECTL_LIMEN 0x2
2022#define FV_LIMEN_ENABLE 0x2
2023#define FV_LIMEN_DISABLE 0x0
2024
2025#define FB_DACCLECTL_COMPEN 0
2026#define FM_DACCLECTL_COMPEN 0x1
2027#define FV_COMPEN_ENABLE 0x1
2028#define FV_COMPEN_DISABLE 0x0
2029
2030// *** DACCLEMUG ***
2031#define FB_DACCLEMUG_MUGAIN 0
2032#define FM_DACCLEMUG_MUGAIN 0x1F
2033
2034// *** DACCOMPTHR ***
2035#define FB_DACCOMPTHR_THRESH 0
2036#define FM_DACCOMPTHR_THRESH 0xFF
2037
2038// *** DACCOMPRAT ***
2039#define FB_DACCOMPRAT_RATIO 0
2040#define FM_DACCOMPRAT_RATIO 0x1F
2041
2042// *** DACCOMPATKL ***
2043#define FB_DACCOMPATKL_TCATKL 0
2044#define FM_DACCOMPATKL_TCATKL 0xFF
2045
2046// *** DACCOMPATKH ***
2047#define FB_DACCOMPATKH_TCATKH 0
2048#define FM_DACCOMPATKH_TCATKH 0xFF
2049
2050// *** DACCOMPRELL ***
2051#define FB_DACCOMPRELL_TCRELL 0
2052#define FM_DACCOMPRELL_TCRELL 0xFF
2053
2054// *** DACCOMPRELH ***
2055#define FB_DACCOMPRELH_TCRELH 0
2056#define FM_DACCOMPRELH_TCRELH 0xFF
2057
2058// *** DACLIMTHR ***
2059#define FB_DACLIMTHR_THRESH 0
2060#define FM_DACLIMTHR_THRESH 0xFF
2061
2062// *** DACLIMTGT ***
2063#define FB_DACLIMTGT_TARGET 0
2064#define FM_DACLIMTGT_TARGET 0xFF
2065
2066// *** DACLIMATKL ***
2067#define FB_DACLIMATKL_TCATKL 0
2068#define FM_DACLIMATKL_TCATKL 0xFF
2069
2070// *** DACLIMATKH ***
2071#define FB_DACLIMATKH_TCATKH 0
2072#define FM_DACLIMATKH_TCATKH 0xFF
2073
2074// *** DACLIMRELL ***
2075#define FB_DACLIMRELL_TCRELL 0
2076#define FM_DACLIMRELL_TCRELL 0xFF
2077
2078// *** DACLIMRELH ***
2079#define FB_DACLIMRELH_TCRELH 0
2080#define FM_DACLIMRELH_TCRELH 0xFF
2081
2082// *** DACEXPTHR ***
2083#define FB_DACEXPTHR_THRESH 0
2084#define FM_DACEXPTHR_THRESH 0xFF
2085
2086// *** DACEXPRAT ***
2087#define FB_DACEXPRAT_RATIO 0
2088#define FM_DACEXPRAT_RATIO 0x7
2089
2090// *** DACEXPATKL ***
2091#define FB_DACEXPATKL_TCATKL 0
2092#define FM_DACEXPATKL_TCATKL 0xFF
2093
2094// *** DACEXPATKH ***
2095#define FB_DACEXPATKH_TCATKH 0
2096#define FM_DACEXPATKH_TCATKH 0xFF
2097
2098// *** DACEXPRELL ***
2099#define FB_DACEXPRELL_TCRELL 0
2100#define FM_DACEXPRELL_TCRELL 0xFF
2101
2102// *** DACEXPRELH ***
2103#define FB_DACEXPRELH_TCRELH 0
2104#define FM_DACEXPRELH_TCRELH 0xFF
2105
2106// *** DACFXCTL ***
2107#define FB_DACFXCTL_3DEN 4
2108#define FM_DACFXCTL_3DEN 0x10
2109
2110#define FB_DACFXCTL_TEEN 3
2111#define FM_DACFXCTL_TEEN 0x8
2112
2113#define FB_DACFXCTL_TNLFBYP 2
2114#define FM_DACFXCTL_TNLFBYP 0x4
2115
2116#define FB_DACFXCTL_BEEN 1
2117#define FM_DACFXCTL_BEEN 0x2
2118
2119#define FB_DACFXCTL_BNLFBYP 0
2120#define FM_DACFXCTL_BNLFBYP 0x1
2121
2122// *** SUBEQFILT ***
2123#define FB_SUBEQFILT_EQ2EN 7
2124#define FM_SUBEQFILT_EQ2EN 0x80
2125#define FV_EQ2EN_ENABLE 0x80
2126#define FV_EQ2EN_DISABLE 0x0
2127
2128#define FB_SUBEQFILT_EQ2BE 4
2129#define FM_SUBEQFILT_EQ2BE 0x70
2130
2131#define FB_SUBEQFILT_EQ1EN 3
2132#define FM_SUBEQFILT_EQ1EN 0x8
2133#define FV_EQ1EN_ENABLE 0x8
2134#define FV_EQ1EN_DISABLE 0x0
2135
2136#define FB_SUBEQFILT_EQ1BE 0
2137#define FM_SUBEQFILT_EQ1BE 0x7
2138
2139#define SUBEQFILT_EQEN_ENABLE 0x1
2140#define SUBEQFILT_EQEN_DISABLE 0x0
2141
2142// *** SUBCRWDL ***
2143#define FB_SUBCRWDL_WDATA_L 0
2144#define FM_SUBCRWDL_WDATA_L 0xFF
2145
2146// *** SUBCRWDM ***
2147#define FB_SUBCRWDM_WDATA_M 0
2148#define FM_SUBCRWDM_WDATA_M 0xFF
2149
2150// *** SUBCRWDH ***
2151#define FB_SUBCRWDH_WDATA_H 0
2152#define FM_SUBCRWDH_WDATA_H 0xFF
2153
2154// *** SUBCRRDL ***
2155#define FB_SUBCRRDL_RDATA_L 0
2156#define FM_SUBCRRDL_RDATA_L 0xFF
2157
2158// *** SUBCRRDM ***
2159#define FB_SUBCRRDM_RDATA_M 0
2160#define FM_SUBCRRDM_RDATA_M 0xFF
2161
2162// *** SUBCRRDH ***
2163#define FB_SUBCRRDH_RDATA_H 0
2164#define FM_SUBCRRDH_RDATA_H 0xFF
2165
2166// *** SUBCRADD ***
2167#define FB_SUBCRADD_ADDRESS 0
2168#define FM_SUBCRADD_ADDRESS 0xFF
2169
2170// *** SUBCRS ***
2171#define FB_SUBCRS_ACCSTAT 7
2172#define FM_SUBCRS_ACCSTAT 0x80
2173
2174// *** SUBMBCEN ***
2175#define FB_SUBMBCEN_MBCEN3 2
2176#define FM_SUBMBCEN_MBCEN3 0x4
2177#define FV_MBCEN3_ENABLE 0x4
2178#define FV_MBCEN3_DISABLE 0x0
2179
2180#define FB_SUBMBCEN_MBCEN2 1
2181#define FM_SUBMBCEN_MBCEN2 0x2
2182#define FV_MBCEN2_ENABLE 0x2
2183#define FV_MBCEN2_DISABLE 0x0
2184
2185#define FB_SUBMBCEN_MBCEN1 0
2186#define FM_SUBMBCEN_MBCEN1 0x1
2187#define FV_MBCEN1_ENABLE 0x1
2188#define FV_MBCEN1_DISABLE 0x0
2189
2190#define SUBMBCEN_MBCEN_ENABLE 0x1
2191#define SUBMBCEN_MBCEN_DISABLE 0x0
2192
2193// *** SUBMBCCTL ***
2194#define FB_SUBMBCCTL_LVLMODE3 5
2195#define FM_SUBMBCCTL_LVLMODE3 0x20
2196
2197#define FB_SUBMBCCTL_WINSEL3 4
2198#define FM_SUBMBCCTL_WINSEL3 0x10
2199
2200#define FB_SUBMBCCTL_LVLMODE2 3
2201#define FM_SUBMBCCTL_LVLMODE2 0x8
2202
2203#define FB_SUBMBCCTL_WINSEL2 2
2204#define FM_SUBMBCCTL_WINSEL2 0x4
2205
2206#define FB_SUBMBCCTL_LVLMODE1 1
2207#define FM_SUBMBCCTL_LVLMODE1 0x2
2208
2209#define FB_SUBMBCCTL_WINSEL1 0
2210#define FM_SUBMBCCTL_WINSEL1 0x1
2211
2212// *** SUBCLECTL ***
2213#define FB_SUBCLECTL_LVLMODE 4
2214#define FM_SUBCLECTL_LVLMODE 0x10
2215
2216#define FB_SUBCLECTL_WINSEL 3
2217#define FM_SUBCLECTL_WINSEL 0x8
2218
2219#define FB_SUBCLECTL_EXPEN 2
2220#define FM_SUBCLECTL_EXPEN 0x4
2221#define FV_EXPEN_ENABLE 0x4
2222#define FV_EXPEN_DISABLE 0x0
2223
2224#define FB_SUBCLECTL_LIMEN 1
2225#define FM_SUBCLECTL_LIMEN 0x2
2226#define FV_LIMEN_ENABLE 0x2
2227#define FV_LIMEN_DISABLE 0x0
2228
2229#define FB_SUBCLECTL_COMPEN 0
2230#define FM_SUBCLECTL_COMPEN 0x1
2231#define FV_COMPEN_ENABLE 0x1
2232#define FV_COMPEN_DISABLE 0x0
2233
2234// *** SUBCLEMUG ***
2235#define FB_SUBCLEMUG_MUGAIN 0
2236#define FM_SUBCLEMUG_MUGAIN 0x1F
2237
2238// *** SUBCOMPTHR ***
2239#define FB_SUBCOMPTHR_THRESH 0
2240#define FM_SUBCOMPTHR_THRESH 0xFF
2241
2242// *** SUBCOMPRAT ***
2243#define FB_SUBCOMPRAT_RATIO 0
2244#define FM_SUBCOMPRAT_RATIO 0x1F
2245
2246// *** SUBCOMPATKL ***
2247#define FB_SUBCOMPATKL_TCATKL 0
2248#define FM_SUBCOMPATKL_TCATKL 0xFF
2249
2250// *** SUBCOMPATKH ***
2251#define FB_SUBCOMPATKH_TCATKH 0
2252#define FM_SUBCOMPATKH_TCATKH 0xFF
2253
2254// *** SUBCOMPRELL ***
2255#define FB_SUBCOMPRELL_TCRELL 0
2256#define FM_SUBCOMPRELL_TCRELL 0xFF
2257
2258// *** SUBCOMPRELH ***
2259#define FB_SUBCOMPRELH_TCRELH 0
2260#define FM_SUBCOMPRELH_TCRELH 0xFF
2261
2262// *** SUBLIMTHR ***
2263#define FB_SUBLIMTHR_THRESH 0
2264#define FM_SUBLIMTHR_THRESH 0xFF
2265
2266// *** SUBLIMTGT ***
2267#define FB_SUBLIMTGT_TARGET 0
2268#define FM_SUBLIMTGT_TARGET 0xFF
2269
2270// *** SUBLIMATKL ***
2271#define FB_SUBLIMATKL_TCATKL 0
2272#define FM_SUBLIMATKL_TCATKL 0xFF
2273
2274// *** SUBLIMATKH ***
2275#define FB_SUBLIMATKH_TCATKH 0
2276#define FM_SUBLIMATKH_TCATKH 0xFF
2277
2278// *** SUBLIMRELL ***
2279#define FB_SUBLIMRELL_TCRELL 0
2280#define FM_SUBLIMRELL_TCRELL 0xFF
2281
2282// *** SUBLIMRELH ***
2283#define FB_SUBLIMRELH_TCRELH 0
2284#define FM_SUBLIMRELH_TCRELH 0xFF
2285
2286// *** SUBEXPTHR ***
2287#define FB_SUBEXPTHR_THRESH 0
2288#define FM_SUBEXPTHR_THRESH 0xFF
2289
2290// *** SUBEXPRAT ***
2291#define FB_SUBEXPRAT_RATIO 0
2292#define FM_SUBEXPRAT_RATIO 0x7
2293
2294// *** SUBEXPATKL ***
2295#define FB_SUBEXPATKL_TCATKL 0
2296#define FM_SUBEXPATKL_TCATKL 0xFF
2297
2298// *** SUBEXPATKH ***
2299#define FB_SUBEXPATKH_TCATKH 0
2300#define FM_SUBEXPATKH_TCATKH 0xFF
2301
2302// *** SUBEXPRELL ***
2303#define FB_SUBEXPRELL_TCRELL 0
2304#define FM_SUBEXPRELL_TCRELL 0xFF
2305
2306// *** SUBEXPRELH ***
2307#define FB_SUBEXPRELH_TCRELH 0
2308#define FM_SUBEXPRELH_TCRELH 0xFF
2309
2310// *** SUBFXCTL ***
2311#define FB_SUBFXCTL_TEEN 3
2312#define FM_SUBFXCTL_TEEN 0x8
2313
2314#define FB_SUBFXCTL_TNLFBYP 2
2315#define FM_SUBFXCTL_TNLFBYP 0x4
2316
2317#define FB_SUBFXCTL_BEEN 1
2318#define FM_SUBFXCTL_BEEN 0x2
2319
2320#define FB_SUBFXCTL_BNLFBYP 0
2321#define FM_SUBFXCTL_BNLFBYP 0x1
2322
2323#endif /* __REDWOODPUBLIC_H__ */
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index d5f4bbf27182..3663b9fd4d65 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1155,8 +1155,8 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1155SND_SOC_BYTES_MASK("EQL Coefficients", WM2200_EQL_1, 20, WM2200_EQL_ENA), 1155SND_SOC_BYTES_MASK("EQL Coefficients", WM2200_EQL_1, 20, WM2200_EQL_ENA),
1156SND_SOC_BYTES_MASK("EQR Coefficients", WM2200_EQR_1, 20, WM2200_EQR_ENA), 1156SND_SOC_BYTES_MASK("EQR Coefficients", WM2200_EQR_1, 20, WM2200_EQR_ENA),
1157 1157
1158SND_SOC_BYTES("LHPF1 Coefficeints", WM2200_HPLPF1_2, 1), 1158SND_SOC_BYTES("LHPF1 Coefficients", WM2200_HPLPF1_2, 1),
1159SND_SOC_BYTES("LHPF2 Coefficeints", WM2200_HPLPF2_2, 1), 1159SND_SOC_BYTES("LHPF2 Coefficients", WM2200_HPLPF2_2, 1),
1160 1160
1161SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L, 1161SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1162 WM2200_OUT1_OSR_SHIFT, 1, 0), 1162 WM2200_OUT1_OSR_SHIFT, 1, 0),
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 87f9a99ce978..ba89d9d711f7 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -573,10 +573,10 @@ SND_SOC_BYTES_MASK("EQ4 Coefficients", WM5100_EQ4_1, 20, WM5100_EQ4_ENA),
573SND_SOC_BYTES_MASK("DRC Coefficients", WM5100_DRC1_CTRL1, 5, 573SND_SOC_BYTES_MASK("DRC Coefficients", WM5100_DRC1_CTRL1, 5,
574 WM5100_DRCL_ENA | WM5100_DRCR_ENA), 574 WM5100_DRCL_ENA | WM5100_DRCR_ENA),
575 575
576SND_SOC_BYTES("LHPF1 Coefficeints", WM5100_HPLPF1_2, 1), 576SND_SOC_BYTES("LHPF1 Coefficients", WM5100_HPLPF1_2, 1),
577SND_SOC_BYTES("LHPF2 Coefficeints", WM5100_HPLPF2_2, 1), 577SND_SOC_BYTES("LHPF2 Coefficients", WM5100_HPLPF2_2, 1),
578SND_SOC_BYTES("LHPF3 Coefficeints", WM5100_HPLPF3_2, 1), 578SND_SOC_BYTES("LHPF3 Coefficients", WM5100_HPLPF3_2, 1),
579SND_SOC_BYTES("LHPF4 Coefficeints", WM5100_HPLPF4_2, 1), 579SND_SOC_BYTES("LHPF4 Coefficients", WM5100_HPLPF4_2, 1),
580 580
581SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L, 581SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
582 WM5100_OUT1_OSR_SHIFT, 1, 0), 582 WM5100_OUT1_OSR_SHIFT, 1, 0),
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index 7949703f3d04..317db9a149a7 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -67,9 +67,18 @@ static int wm8782_probe(struct platform_device *pdev)
67 &soc_component_dev_wm8782, &wm8782_dai, 1); 67 &soc_component_dev_wm8782, &wm8782_dai, 1);
68} 68}
69 69
70#ifdef CONFIG_OF
71static const struct of_device_id wm8782_of_match[] = {
72 { .compatible = "wlf,wm8782", },
73 { }
74};
75MODULE_DEVICE_TABLE(of, wm8782_of_match);
76#endif
77
70static struct platform_driver wm8782_codec_driver = { 78static struct platform_driver wm8782_codec_driver = {
71 .driver = { 79 .driver = {
72 .name = "wm8782", 80 .name = "wm8782",
81 .of_match_table = of_match_ptr(wm8782_of_match),
73 }, 82 },
74 .probe = wm8782_probe, 83 .probe = wm8782_probe,
75}; 84};
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 20fdcae06c6b..f13ef334c0d7 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -596,7 +596,7 @@ static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
596SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, 596SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
597 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), 597 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
598 598
599SOC_ENUM("Left Caputure Mode", lin_mode), 599SOC_ENUM("Left Capture Mode", lin_mode),
600SOC_ENUM("Right Capture Mode", rin_mode), 600SOC_ENUM("Right Capture Mode", rin_mode),
601 601
602/* No TLV since it depends on mode */ 602/* No TLV since it depends on mode */
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index af062c4f4017..2175dccdf388 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2665,9 +2665,9 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
2665 dsp->preloaded = ucontrol->value.integer.value[0]; 2665 dsp->preloaded = ucontrol->value.integer.value[0];
2666 2666
2667 if (ucontrol->value.integer.value[0]) 2667 if (ucontrol->value.integer.value[0])
2668 snd_soc_dapm_force_enable_pin(dapm, preload); 2668 snd_soc_component_force_enable_pin(component, preload);
2669 else 2669 else
2670 snd_soc_dapm_disable_pin(dapm, preload); 2670 snd_soc_component_disable_pin(component, preload);
2671 2671
2672 snd_soc_dapm_sync(dapm); 2672 snd_soc_dapm_sync(dapm);
2673 2673
@@ -2851,11 +2851,11 @@ EXPORT_SYMBOL_GPL(wm_adsp2_event);
2851 2851
2852int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component) 2852int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component)
2853{ 2853{
2854 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
2855 char preload[32]; 2854 char preload[32];
2856 2855
2857 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num); 2856 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num);
2858 snd_soc_dapm_disable_pin(dapm, preload); 2857
2858 snd_soc_component_disable_pin(component, preload);
2859 2859
2860 wm_adsp2_init_debugfs(dsp, component); 2860 wm_adsp2_init_debugfs(dsp, component);
2861 2861
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 6b732d8e5896..778faff28e0e 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -24,7 +24,7 @@ config SND_DAVINCI_SOC_I2S
24 24
25config SND_DAVINCI_SOC_MCASP 25config SND_DAVINCI_SOC_MCASP
26 tristate "Multichannel Audio Serial Port (McASP) support" 26 tristate "Multichannel Audio Serial Port (McASP) support"
27 depends on SND_OMAP_SOC || SND_EDMA_SOC 27 depends on SND_SDMA_SOC || SND_EDMA_SOC
28 help 28 help
29 Say Y or M here if you want to have support for McASP IP found in 29 Say Y or M here if you want to have support for McASP IP found in
30 various Texas Instruments SoCs like: 30 various Texas Instruments SoCs like:
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 03ba218160ca..1f96c9dbe9c4 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -36,9 +36,9 @@
36#include <sound/initval.h> 36#include <sound/initval.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/dmaengine_pcm.h> 38#include <sound/dmaengine_pcm.h>
39#include <sound/omap-pcm.h>
40 39
41#include "edma-pcm.h" 40#include "edma-pcm.h"
41#include "../omap/sdma-pcm.h"
42#include "davinci-mcasp.h" 42#include "davinci-mcasp.h"
43 43
44#define MCASP_MAX_AFIFO_DEPTH 64 44#define MCASP_MAX_AFIFO_DEPTH 64
@@ -789,7 +789,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
789 rx_ser < max_active_serializers) { 789 rx_ser < max_active_serializers) {
790 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); 790 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i));
791 rx_ser++; 791 rx_ser++;
792 } else { 792 } else if (mcasp->serial_dir[i] == INACTIVE_MODE) {
793 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 793 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
794 SRMOD_INACTIVE, SRMOD_MASK); 794 SRMOD_INACTIVE, SRMOD_MASK);
795 } 795 }
@@ -2048,10 +2048,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
2048#endif 2048#endif
2049 break; 2049 break;
2050 case PCM_SDMA: 2050 case PCM_SDMA:
2051#if IS_BUILTIN(CONFIG_SND_OMAP_SOC) || \ 2051#if IS_BUILTIN(CONFIG_SND_SDMA_SOC) || \
2052 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 2052 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
2053 IS_MODULE(CONFIG_SND_OMAP_SOC)) 2053 IS_MODULE(CONFIG_SND_SDMA_SOC))
2054 ret = omap_pcm_platform_register(&pdev->dev); 2054 ret = sdma_pcm_platform_register(&pdev->dev, NULL, NULL);
2055#else 2055#else
2056 dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n"); 2056 dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n");
2057 ret = -EINVAL; 2057 ret = -EINVAL;
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index da8fd98c7f51..8f43110373b8 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -1,12 +1,8 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver 2//
3 * 3// Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
4 * Copyright (C) 2014 Freescale Semiconductor, Inc. 4//
5 * 5// Copyright (C) 2014 Freescale Semiconductor, Inc.
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10 6
11#include <linux/clk.h> 7#include <linux/clk.h>
12#include <linux/dmaengine.h> 8#include <linux/dmaengine.h>
@@ -226,6 +222,12 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
226 unsigned long clk_rate; 222 unsigned long clk_rate;
227 int ret; 223 int ret;
228 224
225 if (freq == 0) {
226 dev_err(dai->dev, "%sput freq of HCK%c should not be 0Hz\n",
227 in ? "in" : "out", tx ? 'T' : 'R');
228 return -EINVAL;
229 }
230
229 /* Bypass divider settings if the requirement doesn't change */ 231 /* Bypass divider settings if the requirement doesn't change */
230 if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx]) 232 if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
231 return 0; 233 return 0;
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h
index 5e793bbb6b02..f873588d9045 100644
--- a/sound/soc/fsl/fsl_esai.h
+++ b/sound/soc/fsl/fsl_esai.h
@@ -1,13 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC 3 * fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC
3 * 4 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc. 5 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 * 6 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com> 7 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */ 8 */
12 9
13#ifndef _FSL_ESAI_DAI_H 10#ifndef _FSL_ESAI_DAI_H
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 18e5ce81527d..4163f2cfc06f 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1,14 +1,8 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * Freescale ALSA SoC Digital Audio Interface (SAI) driver. 2//
3 * 3// Freescale ALSA SoC Digital Audio Interface (SAI) driver.
4 * Copyright 2012-2015 Freescale Semiconductor, Inc. 4//
5 * 5// Copyright 2012-2015 Freescale Semiconductor, Inc.
6 * This program is free software, you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 2 of the License, or(at your
9 * option) any later version.
10 *
11 */
12 6
13#include <linux/clk.h> 7#include <linux/clk.h>
14#include <linux/delay.h> 8#include <linux/delay.h>
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index d9ed7be8cb34..24cb156bf995 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -1,9 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * Copyright 2012-2013 Freescale Semiconductor, Inc. 3 * Copyright 2012-2013 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */ 4 */
8 5
9#ifndef __FSL_SAI_H 6#ifndef __FSL_SAI_H
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 4f7469c1864c..9b59d87b61bf 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1,17 +1,13 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver 2//
3 * 3// Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver
4 * Copyright (C) 2013 Freescale Semiconductor, Inc. 4//
5 * 5// Copyright (C) 2013 Freescale Semiconductor, Inc.
6 * Based on stmp3xxx_spdif_dai.c 6//
7 * Vladimir Barinov <vbarinov@embeddedalley.com> 7// Based on stmp3xxx_spdif_dai.c
8 * Copyright 2008 SigmaTel, Inc 8// Vladimir Barinov <vbarinov@embeddedalley.com>
9 * Copyright 2008 Embedded Alley Solutions, Inc 9// Copyright 2008 SigmaTel, Inc
10 * 10// Copyright 2008 Embedded Alley Solutions, Inc
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15 11
16#include <linux/bitrev.h> 12#include <linux/bitrev.h>
17#include <linux/clk.h> 13#include <linux/clk.h>
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h
index 00bd3514c610..7666dabaccfd 100644
--- a/sound/soc/fsl/fsl_spdif.h
+++ b/sound/soc/fsl/fsl_spdif.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * fsl_spdif.h - ALSA S/PDIF interface for the Freescale i.MX SoC 3 * fsl_spdif.h - ALSA S/PDIF interface for the Freescale i.MX SoC
3 * 4 *
@@ -8,10 +9,6 @@
8 * Based on fsl_ssi.h 9 * Based on fsl_ssi.h
9 * Author: Timur Tabi <timur@freescale.com> 10 * Author: Timur Tabi <timur@freescale.com>
10 * Copyright 2007-2008 Freescale Semiconductor, Inc. 11 * Copyright 2007-2008 Freescale Semiconductor, Inc.
11 *
12 * This file is licensed under the terms of the GNU General Public License
13 * version 2. This program is licensed "as is" without any warranty of any
14 * kind, whether express or implied.
15 */ 12 */
16 13
17#ifndef _FSL_SPDIF_DAI_H 14#ifndef _FSL_SPDIF_DAI_H
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 89df2d9f63d7..0a648229e643 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1,34 +1,29 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver 2//
3 * 3// Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
4 * Author: Timur Tabi <timur@freescale.com> 4//
5 * 5// Author: Timur Tabi <timur@freescale.com>
6 * Copyright 2007-2010 Freescale Semiconductor, Inc. 6//
7 * 7// Copyright 2007-2010 Freescale Semiconductor, Inc.
8 * This file is licensed under the terms of the GNU General Public License 8//
9 * version 2. This program is licensed "as is" without any warranty of any 9// Some notes why imx-pcm-fiq is used instead of DMA on some boards:
10 * kind, whether express or implied. 10//
11 * 11// The i.MX SSI core has some nasty limitations in AC97 mode. While most
12 * 12// sane processor vendors have a FIFO per AC97 slot, the i.MX has only
13 * Some notes why imx-pcm-fiq is used instead of DMA on some boards: 13// one FIFO which combines all valid receive slots. We cannot even select
14 * 14// which slots we want to receive. The WM9712 with which this driver
15 * The i.MX SSI core has some nasty limitations in AC97 mode. While most 15// was developed with always sends GPIO status data in slot 12 which
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only 16// we receive in our (PCM-) data stream. The only chance we have is to
17 * one FIFO which combines all valid receive slots. We cannot even select 17// manually skip this data in the FIQ handler. With sampling rates different
18 * which slots we want to receive. The WM9712 with which this driver 18// from 48000Hz not every frame has valid receive data, so the ratio
19 * was developed with always sends GPIO status data in slot 12 which 19// between pcm data and GPIO status data changes. Our FIQ handler is not
20 * we receive in our (PCM-) data stream. The only chance we have is to 20// able to handle this, hence this driver only works with 48000Hz sampling
21 * manually skip this data in the FIQ handler. With sampling rates different 21// rate.
22 * from 48000Hz not every frame has valid receive data, so the ratio 22// Reading and writing AC97 registers is another challenge. The core
23 * between pcm data and GPIO status data changes. Our FIQ handler is not 23// provides us status bits when the read register is updated with *another*
24 * able to handle this, hence this driver only works with 48000Hz sampling 24// value. When we read the same register two times (and the register still
25 * rate. 25// contains the same value) these status bits are not set. We work
26 * Reading and writing AC97 registers is another challenge. The core 26// around this by not polling these bits but only wait a fixed delay.
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
31 */
32 27
33#include <linux/init.h> 28#include <linux/init.h>
34#include <linux/io.h> 29#include <linux/io.h>
@@ -385,8 +380,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
385{ 380{
386 struct fsl_ssi *ssi = dev_id; 381 struct fsl_ssi *ssi = dev_id;
387 struct regmap *regs = ssi->regs; 382 struct regmap *regs = ssi->regs;
388 __be32 sisr; 383 u32 sisr, sisr2;
389 __be32 sisr2;
390 384
391 regmap_read(regs, REG_SSI_SISR, &sisr); 385 regmap_read(regs, REG_SSI_SISR, &sisr);
392 386
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index 18f8dd5209d5..0bdda608d414 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -1,12 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 and i.MX SoC 3 * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 and i.MX SoC
3 * 4 *
4 * Author: Timur Tabi <timur@freescale.com> 5 * Author: Timur Tabi <timur@freescale.com>
5 * 6 *
6 * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed 7 * Copyright 2007-2008 Freescale Semiconductor, Inc.
7 * under the terms of the GNU General Public License version 2. This
8 * program is licensed "as is" without any warranty of any kind, whether
9 * express or implied.
10 */ 8 */
11 9
12#ifndef _MPC8610_I2S_H 10#ifndef _MPC8610_I2S_H
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c
index 0ff469c027dd..1255dfe19eef 100644
--- a/sound/soc/fsl/fsl_ssi_dbg.c
+++ b/sound/soc/fsl/fsl_ssi_dbg.c
@@ -1,14 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) debugging functions 2//
3 * 3// Freescale SSI ALSA SoC Digital Audio Interface (DAI) debugging functions
4 * Copyright 2014 Markus Pargmann <mpa@pengutronix.de>, Pengutronix 4//
5 * 5// Copyright 2014 Markus Pargmann <mpa@pengutronix.de>, Pengutronix
6 * Splitted from fsl_ssi.c 6//
7 * 7// Split from fsl_ssi.c
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12 8
13#include <linux/debugfs.h> 9#include <linux/debugfs.h>
14#include <linux/device.h> 10#include <linux/device.h>
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 6959a74a6f49..4a516c428b3d 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -135,6 +135,18 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
135 asoc_simple_card_clk_disable(&dai_props->codec_dai); 135 asoc_simple_card_clk_disable(&dai_props->codec_dai);
136} 136}
137 137
138static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
139 unsigned long rate)
140{
141 if (!simple_dai->clk)
142 return 0;
143
144 if (clk_get_rate(simple_dai->clk) == rate)
145 return 0;
146
147 return clk_set_rate(simple_dai->clk, rate);
148}
149
138static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, 150static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
139 struct snd_pcm_hw_params *params) 151 struct snd_pcm_hw_params *params)
140{ 152{
@@ -154,6 +166,15 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
154 166
155 if (mclk_fs) { 167 if (mclk_fs) {
156 mclk = params_rate(params) * mclk_fs; 168 mclk = params_rate(params) * mclk_fs;
169
170 ret = asoc_simple_set_clk_rate(&dai_props->codec_dai, mclk);
171 if (ret < 0)
172 return ret;
173
174 ret = asoc_simple_set_clk_rate(&dai_props->cpu_dai, mclk);
175 if (ret < 0)
176 return ret;
177
157 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 178 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
158 SND_SOC_CLOCK_IN); 179 SND_SOC_CLOCK_IN);
159 if (ret && ret != -ENOTSUPP) 180 if (ret && ret != -ENOTSUPP)
diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c
index 07a57209e055..53344a3b7a60 100644
--- a/sound/soc/hisilicon/hi6210-i2s.c
+++ b/sound/soc/hisilicon/hi6210-i2s.c
@@ -498,7 +498,7 @@ static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
498 hi6210_i2s_txctrl(cpu_dai, 0); 498 hi6210_i2s_txctrl(cpu_dai, 0);
499 break; 499 break;
500 default: 500 default:
501 dev_err(cpu_dai->dev, "uknown cmd\n"); 501 dev_err(cpu_dai->dev, "unknown cmd\n");
502 return -EINVAL; 502 return -EINVAL;
503 } 503 }
504 return 0; 504 return 0;
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index addac2a8e52a..0caa1f4eb94d 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -61,7 +61,7 @@ config SND_SOC_INTEL_HASWELL
61 61
62config SND_SOC_INTEL_BAYTRAIL 62config SND_SOC_INTEL_BAYTRAIL
63 tristate "Baytrail (legacy) Platforms" 63 tristate "Baytrail (legacy) Platforms"
64 depends on DMADEVICES && ACPI 64 depends on DMADEVICES && ACPI && SND_SST_ATOM_HIFI2_PLATFORM=n
65 select SND_SOC_INTEL_SST 65 select SND_SOC_INTEL_SST
66 select SND_SOC_INTEL_SST_ACPI 66 select SND_SOC_INTEL_SST_ACPI
67 select SND_SOC_INTEL_SST_FIRMWARE 67 select SND_SOC_INTEL_SST_FIRMWARE
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 668c0934e942..40eb979d5ac1 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -571,7 +571,7 @@ static int broxton_audio_probe(struct platform_device *pdev)
571{ 571{
572 struct bxt_card_private *ctx; 572 struct bxt_card_private *ctx;
573 573
574 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 574 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
575 if (!ctx) 575 if (!ctx)
576 return -ENOMEM; 576 return -ENOMEM;
577 577
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index c7e9024e65ef..b68c289558a8 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -593,7 +593,7 @@ static int broxton_audio_probe(struct platform_device *pdev)
593 } 593 }
594 } 594 }
595 595
596 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 596 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
597 if (!ctx) 597 if (!ctx)
598 return -ENOMEM; 598 return -ENOMEM;
599 599
diff --git a/sound/soc/intel/boards/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c
index 0f8b8209c020..f1283634b22b 100644
--- a/sound/soc/intel/boards/byt-max98090.c
+++ b/sound/soc/intel/boards/byt-max98090.c
@@ -151,7 +151,7 @@ static int byt_max98090_probe(struct platform_device *pdev)
151 struct byt_max98090_private *priv; 151 struct byt_max98090_private *priv;
152 int ret_val; 152 int ret_val;
153 153
154 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 154 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
155 if (!priv) { 155 if (!priv) {
156 dev_err(&pdev->dev, "allocation failed\n"); 156 dev_err(&pdev->dev, "allocation failed\n");
157 return -ENOMEM; 157 return -ENOMEM;
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 305e7f4fe55a..adc26dfc7d65 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -243,7 +243,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
243 int i; 243 int i;
244 int ret = 0; 244 int ret = 0;
245 245
246 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 246 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
247 if (!priv) 247 if (!priv)
248 return -ENOMEM; 248 return -ENOMEM;
249 249
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index a8d8bff788e7..33065ba294a9 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -17,6 +17,7 @@
17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 */ 18 */
19 19
20#include <linux/i2c.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
@@ -25,6 +26,7 @@
25#include <linux/clk.h> 26#include <linux/clk.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include <linux/dmi.h> 28#include <linux/dmi.h>
29#include <linux/input.h>
28#include <linux/slab.h> 30#include <linux/slab.h>
29#include <asm/cpu_device_id.h> 31#include <asm/cpu_device_id.h>
30#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
@@ -33,6 +35,7 @@
33#include <sound/soc.h> 35#include <sound/soc.h>
34#include <sound/jack.h> 36#include <sound/jack.h>
35#include <sound/soc-acpi.h> 37#include <sound/soc-acpi.h>
38#include <dt-bindings/sound/rt5640.h>
36#include "../../codecs/rt5640.h" 39#include "../../codecs/rt5640.h"
37#include "../atom/sst-atom-controls.h" 40#include "../atom/sst-atom-controls.h"
38#include "../common/sst-dsp.h" 41#include "../common/sst-dsp.h"
@@ -44,17 +47,53 @@ enum {
44 BYT_RT5640_IN3_MAP, 47 BYT_RT5640_IN3_MAP,
45}; 48};
46 49
47#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(7, 0)) 50enum {
48#define BYT_RT5640_DMIC_EN BIT(16) 51 BYT_RT5640_JD_SRC_GPIO1 = (RT5640_JD_SRC_GPIO1 << 4),
49#define BYT_RT5640_MONO_SPEAKER BIT(17) 52 BYT_RT5640_JD_SRC_JD1_IN4P = (RT5640_JD_SRC_JD1_IN4P << 4),
50#define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */ 53 BYT_RT5640_JD_SRC_JD2_IN4N = (RT5640_JD_SRC_JD2_IN4N << 4),
51#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ 54 BYT_RT5640_JD_SRC_GPIO2 = (RT5640_JD_SRC_GPIO2 << 4),
52#define BYT_RT5640_SSP0_AIF1 BIT(20) 55 BYT_RT5640_JD_SRC_GPIO3 = (RT5640_JD_SRC_GPIO3 << 4),
53#define BYT_RT5640_SSP0_AIF2 BIT(21) 56 BYT_RT5640_JD_SRC_GPIO4 = (RT5640_JD_SRC_GPIO4 << 4),
54#define BYT_RT5640_MCLK_EN BIT(22) 57};
55#define BYT_RT5640_MCLK_25MHZ BIT(23) 58
59enum {
60 BYT_RT5640_OVCD_TH_600UA = (6 << 8),
61 BYT_RT5640_OVCD_TH_1500UA = (15 << 8),
62 BYT_RT5640_OVCD_TH_2000UA = (20 << 8),
63};
64
65enum {
66 BYT_RT5640_OVCD_SF_0P5 = (RT5640_OVCD_SF_0P5 << 13),
67 BYT_RT5640_OVCD_SF_0P75 = (RT5640_OVCD_SF_0P75 << 13),
68 BYT_RT5640_OVCD_SF_1P0 = (RT5640_OVCD_SF_1P0 << 13),
69 BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13),
70};
71
72#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0))
73#define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
74#define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
75#define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
76#define BYT_RT5640_JD_NOT_INV BIT(16)
77#define BYT_RT5640_MONO_SPEAKER BIT(17)
78#define BYT_RT5640_DIFF_MIC BIT(18) /* default is single-ended */
79#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
80#define BYT_RT5640_SSP0_AIF1 BIT(20)
81#define BYT_RT5640_SSP0_AIF2 BIT(21)
82#define BYT_RT5640_MCLK_EN BIT(22)
83#define BYT_RT5640_MCLK_25MHZ BIT(23)
84
85#define BYTCR_INPUT_DEFAULTS \
86 (BYT_RT5640_IN3_MAP | \
87 BYT_RT5640_JD_SRC_JD1_IN4P | \
88 BYT_RT5640_OVCD_TH_2000UA | \
89 BYT_RT5640_OVCD_SF_0P75 | \
90 BYT_RT5640_DIFF_MIC)
91
92/* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
93#define MAX_NO_PROPS 6
56 94
57struct byt_rt5640_private { 95struct byt_rt5640_private {
96 struct snd_soc_jack jack;
58 struct clk *mclk; 97 struct clk *mclk;
59}; 98};
60static bool is_bytcr; 99static bool is_bytcr;
@@ -67,7 +106,6 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
67static void log_quirks(struct device *dev) 106static void log_quirks(struct device *dev)
68{ 107{
69 int map; 108 int map;
70 bool has_dmic = false;
71 bool has_mclk = false; 109 bool has_mclk = false;
72 bool has_ssp0 = false; 110 bool has_ssp0 = false;
73 bool has_ssp0_aif1 = false; 111 bool has_ssp0_aif1 = false;
@@ -78,11 +116,9 @@ static void log_quirks(struct device *dev)
78 switch (map) { 116 switch (map) {
79 case BYT_RT5640_DMIC1_MAP: 117 case BYT_RT5640_DMIC1_MAP:
80 dev_info(dev, "quirk DMIC1_MAP enabled\n"); 118 dev_info(dev, "quirk DMIC1_MAP enabled\n");
81 has_dmic = true;
82 break; 119 break;
83 case BYT_RT5640_DMIC2_MAP: 120 case BYT_RT5640_DMIC2_MAP:
84 dev_info(dev, "quirk DMIC2_MAP enabled\n"); 121 dev_info(dev, "quirk DMIC2_MAP enabled\n");
85 has_dmic = true;
86 break; 122 break;
87 case BYT_RT5640_IN1_MAP: 123 case BYT_RT5640_IN1_MAP:
88 dev_info(dev, "quirk IN1_MAP enabled\n"); 124 dev_info(dev, "quirk IN1_MAP enabled\n");
@@ -94,20 +130,20 @@ static void log_quirks(struct device *dev)
94 dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map); 130 dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
95 break; 131 break;
96 } 132 }
97 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) { 133 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
98 if (has_dmic) 134 dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
99 dev_info(dev, "quirk DMIC enabled\n"); 135 BYT_RT5640_JDSRC(byt_rt5640_quirk));
100 else 136 dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
101 dev_err(dev, "quirk DMIC enabled but no DMIC input set, will be ignored\n"); 137 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
138 dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
139 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
102 } 140 }
141 if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
142 dev_info(dev, "quirk JD_NOT_INV enabled\n");
103 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) 143 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
104 dev_info(dev, "quirk MONO_SPEAKER enabled\n"); 144 dev_info(dev, "quirk MONO_SPEAKER enabled\n");
105 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) { 145 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
106 if (!has_dmic) 146 dev_info(dev, "quirk DIFF_MIC enabled\n");
107 dev_info(dev, "quirk DIFF_MIC enabled\n");
108 else
109 dev_info(dev, "quirk DIFF_MIC enabled but DMIC input selected, will be ignored\n");
110 }
111 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { 147 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
112 dev_info(dev, "quirk SSP0_AIF1 enabled\n"); 148 dev_info(dev, "quirk SSP0_AIF1 enabled\n");
113 has_ssp0 = true; 149 has_ssp0 = true;
@@ -141,6 +177,52 @@ static void log_quirks(struct device *dev)
141 } 177 }
142} 178}
143 179
180static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
181 int rate)
182{
183 int ret;
184
185 /* Configure the PLL before selecting it */
186 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
187 /* use bitclock as PLL input */
188 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
189 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
190 /* 2x16 bit slots on SSP0 */
191 ret = snd_soc_dai_set_pll(codec_dai, 0,
192 RT5640_PLL1_S_BCLK1,
193 rate * 32, rate * 512);
194 } else {
195 /* 2x15 bit slots on SSP2 */
196 ret = snd_soc_dai_set_pll(codec_dai, 0,
197 RT5640_PLL1_S_BCLK1,
198 rate * 50, rate * 512);
199 }
200 } else {
201 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
202 ret = snd_soc_dai_set_pll(codec_dai, 0,
203 RT5640_PLL1_S_MCLK,
204 25000000, rate * 512);
205 } else {
206 ret = snd_soc_dai_set_pll(codec_dai, 0,
207 RT5640_PLL1_S_MCLK,
208 19200000, rate * 512);
209 }
210 }
211
212 if (ret < 0) {
213 dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
214 return ret;
215 }
216
217 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
218 rate * 512, SND_SOC_CLOCK_IN);
219 if (ret < 0) {
220 dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
221 return ret;
222 }
223
224 return 0;
225}
144 226
145#define BYT_CODEC_DAI1 "rt5640-aif1" 227#define BYT_CODEC_DAI1 "rt5640-aif1"
146#define BYT_CODEC_DAI2 "rt5640-aif2" 228#define BYT_CODEC_DAI2 "rt5640-aif2"
@@ -173,9 +255,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
173 return ret; 255 return ret;
174 } 256 }
175 } 257 }
176 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, 258 ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
177 48000 * 512,
178 SND_SOC_CLOCK_IN);
179 } else { 259 } else {
180 /* 260 /*
181 * Set codec clock source to internal clock before 261 * Set codec clock source to internal clock before
@@ -295,79 +375,72 @@ static const struct snd_kcontrol_new byt_rt5640_controls[] = {
295 SOC_DAPM_PIN_SWITCH("Speaker"), 375 SOC_DAPM_PIN_SWITCH("Speaker"),
296}; 376};
297 377
378static struct snd_soc_jack_pin rt5640_pins[] = {
379 {
380 .pin = "Headphone",
381 .mask = SND_JACK_HEADPHONE,
382 },
383 {
384 .pin = "Headset Mic",
385 .mask = SND_JACK_MICROPHONE,
386 },
387};
388
298static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, 389static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
299 struct snd_pcm_hw_params *params) 390 struct snd_pcm_hw_params *params)
300{ 391{
301 struct snd_soc_pcm_runtime *rtd = substream->private_data; 392 struct snd_soc_pcm_runtime *rtd = substream->private_data;
302 struct snd_soc_dai *codec_dai = rtd->codec_dai; 393 struct snd_soc_dai *dai = rtd->codec_dai;
303 int ret;
304 394
305 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, 395 return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
306 params_rate(params) * 512,
307 SND_SOC_CLOCK_IN);
308
309 if (ret < 0) {
310 dev_err(rtd->dev, "can't set codec clock %d\n", ret);
311 return ret;
312 }
313
314 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
315 /* use bitclock as PLL input */
316 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
317 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
318
319 /* 2x16 bit slots on SSP0 */
320 ret = snd_soc_dai_set_pll(codec_dai, 0,
321 RT5640_PLL1_S_BCLK1,
322 params_rate(params) * 32,
323 params_rate(params) * 512);
324 } else {
325 /* 2x15 bit slots on SSP2 */
326 ret = snd_soc_dai_set_pll(codec_dai, 0,
327 RT5640_PLL1_S_BCLK1,
328 params_rate(params) * 50,
329 params_rate(params) * 512);
330 }
331 } else {
332 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
333 ret = snd_soc_dai_set_pll(codec_dai, 0,
334 RT5640_PLL1_S_MCLK,
335 25000000,
336 params_rate(params) * 512);
337 } else {
338 ret = snd_soc_dai_set_pll(codec_dai, 0,
339 RT5640_PLL1_S_MCLK,
340 19200000,
341 params_rate(params) * 512);
342 }
343 }
344
345 if (ret < 0) {
346 dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
347 return ret;
348 }
349
350 return 0;
351}
352
353static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
354{
355 byt_rt5640_quirk = (unsigned long)id->driver_data;
356 return 1;
357} 396}
358 397
398/* Please keep this list alphabetically sorted */
359static const struct dmi_system_id byt_rt5640_quirk_table[] = { 399static const struct dmi_system_id byt_rt5640_quirk_table[] = {
400 { /* Acer Iconia Tab 8 W1-810 */
401 .matches = {
402 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
403 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
404 },
405 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
406 BYT_RT5640_JD_SRC_JD1_IN4P |
407 BYT_RT5640_OVCD_TH_2000UA |
408 BYT_RT5640_OVCD_SF_0P75 |
409 BYT_RT5640_SSP0_AIF1 |
410 BYT_RT5640_MCLK_EN),
411 },
412 {
413 .matches = {
414 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
415 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
416 },
417 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
418 BYT_RT5640_MCLK_EN |
419 BYT_RT5640_SSP0_AIF1),
420
421 },
422 {
423 .matches = {
424 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
425 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
426 },
427 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
428 BYT_RT5640_MONO_SPEAKER |
429 BYT_RT5640_SSP0_AIF1 |
430 BYT_RT5640_MCLK_EN),
431 },
360 { 432 {
361 .callback = byt_rt5640_quirk_cb,
362 .matches = { 433 .matches = {
363 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 434 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
364 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), 435 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
365 }, 436 },
366 .driver_data = (void *)(BYT_RT5640_IN1_MAP | 437 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
438 BYT_RT5640_JD_SRC_JD2_IN4N |
439 BYT_RT5640_OVCD_TH_2000UA |
440 BYT_RT5640_OVCD_SF_0P75 |
367 BYT_RT5640_MCLK_EN), 441 BYT_RT5640_MCLK_EN),
368 }, 442 },
369 { 443 {
370 .callback = byt_rt5640_quirk_cb,
371 .matches = { 444 .matches = {
372 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 445 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
373 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), 446 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
@@ -378,18 +451,38 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
378 BYT_RT5640_SSP0_AIF2 | 451 BYT_RT5640_SSP0_AIF2 |
379 BYT_RT5640_MCLK_EN), 452 BYT_RT5640_MCLK_EN),
380 }, 453 },
454 { /* Chuwi Vi8 (CWI506) */
455 .matches = {
456 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
457 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
458 /* The above are too generic, also match BIOS info */
459 DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
460 },
461 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
462 BYT_RT5640_MONO_SPEAKER |
463 BYT_RT5640_SSP0_AIF1 |
464 BYT_RT5640_MCLK_EN),
465 },
381 { 466 {
382 .callback = byt_rt5640_quirk_cb,
383 .matches = { 467 .matches = {
384 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."), 468 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
469 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
470 },
471 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
472 },
473 {
474 .matches = {
475 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
385 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), 476 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
386 }, 477 },
387 .driver_data = (void *)(BYT_RT5640_DMIC2_MAP | 478 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
388 BYT_RT5640_DMIC_EN | 479 BYT_RT5640_JD_SRC_JD2_IN4N |
480 BYT_RT5640_OVCD_TH_2000UA |
481 BYT_RT5640_OVCD_SF_0P75 |
482 BYT_RT5640_MONO_SPEAKER |
389 BYT_RT5640_MCLK_EN), 483 BYT_RT5640_MCLK_EN),
390 }, 484 },
391 { 485 {
392 .callback = byt_rt5640_quirk_cb,
393 .matches = { 486 .matches = {
394 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 487 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
395 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), 488 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
@@ -397,17 +490,112 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
397 .driver_data = (void *)(BYT_RT5640_IN1_MAP | 490 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
398 BYT_RT5640_MCLK_EN), 491 BYT_RT5640_MCLK_EN),
399 }, 492 },
400 { 493 { /* HP Pavilion x2 10-n000nd */
401 .callback = byt_rt5640_quirk_cb,
402 .matches = { 494 .matches = {
403 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), 495 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
404 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), 496 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
405 }, 497 },
406 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | 498 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
407 BYT_RT5640_DMIC_EN), 499 BYT_RT5640_JD_SRC_JD2_IN4N |
500 BYT_RT5640_OVCD_TH_1500UA |
501 BYT_RT5640_OVCD_SF_0P75 |
502 BYT_RT5640_SSP0_AIF1 |
503 BYT_RT5640_MCLK_EN),
504 },
505 { /* HP Stream 7 */
506 .matches = {
507 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
508 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
509 },
510 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
511 BYT_RT5640_MONO_SPEAKER |
512 BYT_RT5640_JD_NOT_INV |
513 BYT_RT5640_SSP0_AIF1 |
514 BYT_RT5640_MCLK_EN),
515 },
516 { /* I.T.Works TW891 */
517 .matches = {
518 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
519 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
520 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
521 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
522 },
523 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
524 BYT_RT5640_MONO_SPEAKER |
525 BYT_RT5640_SSP0_AIF1 |
526 BYT_RT5640_MCLK_EN),
527 },
528 { /* Lamina I8270 / T701BR.SE */
529 .matches = {
530 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
531 DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
532 },
533 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
534 BYT_RT5640_MONO_SPEAKER |
535 BYT_RT5640_JD_NOT_INV |
536 BYT_RT5640_SSP0_AIF1 |
537 BYT_RT5640_MCLK_EN),
538 },
539 { /* MSI S100 tablet */
540 .matches = {
541 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
542 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
543 },
544 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
545 BYT_RT5640_JD_SRC_JD2_IN4N |
546 BYT_RT5640_OVCD_TH_2000UA |
547 BYT_RT5640_OVCD_SF_0P75 |
548 BYT_RT5640_MONO_SPEAKER |
549 BYT_RT5640_DIFF_MIC |
550 BYT_RT5640_MCLK_EN),
551 },
552 { /* Pipo W4 */
553 .matches = {
554 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
555 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
556 /* The above are too generic, also match BIOS info */
557 DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
558 },
559 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
560 BYT_RT5640_MONO_SPEAKER |
561 BYT_RT5640_SSP0_AIF1 |
562 BYT_RT5640_MCLK_EN),
563 },
564 { /* Point of View Mobii TAB-P800W (V2.0) */
565 .matches = {
566 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
567 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
568 /* The above are too generic, also match BIOS info */
569 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
570 DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
571 },
572 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
573 BYT_RT5640_JD_SRC_JD2_IN4N |
574 BYT_RT5640_OVCD_TH_2000UA |
575 BYT_RT5640_OVCD_SF_0P75 |
576 BYT_RT5640_MONO_SPEAKER |
577 BYT_RT5640_DIFF_MIC |
578 BYT_RT5640_SSP0_AIF2 |
579 BYT_RT5640_MCLK_EN),
580 },
581 { /* Point of View Mobii TAB-P800W (V2.1) */
582 .matches = {
583 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
584 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
585 /* The above are too generic, also match BIOS info */
586 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
587 DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
588 },
589 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
590 BYT_RT5640_JD_SRC_JD2_IN4N |
591 BYT_RT5640_OVCD_TH_2000UA |
592 BYT_RT5640_OVCD_SF_0P75 |
593 BYT_RT5640_MONO_SPEAKER |
594 BYT_RT5640_DIFF_MIC |
595 BYT_RT5640_SSP0_AIF2 |
596 BYT_RT5640_MCLK_EN),
408 }, 597 },
409 { 598 {
410 .callback = byt_rt5640_quirk_cb,
411 .matches = { 599 .matches = {
412 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), 600 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
413 DMI_MATCH(DMI_BOARD_NAME, "tPAD"), 601 DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
@@ -416,23 +604,23 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
416 BYT_RT5640_MCLK_EN | 604 BYT_RT5640_MCLK_EN |
417 BYT_RT5640_SSP0_AIF1), 605 BYT_RT5640_SSP0_AIF1),
418 }, 606 },
419 { 607 { /* Toshiba Satellite Click Mini L9W-B */
420 .callback = byt_rt5640_quirk_cb,
421 .matches = { 608 .matches = {
422 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 609 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
423 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), 610 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
424 }, 611 },
425 .driver_data = (void *)(BYT_RT5640_IN1_MAP | 612 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
426 BYT_RT5640_MCLK_EN | 613 BYT_RT5640_JD_SRC_JD2_IN4N |
427 BYT_RT5640_SSP0_AIF1), 614 BYT_RT5640_OVCD_TH_1500UA |
428 615 BYT_RT5640_OVCD_SF_0P75 |
616 BYT_RT5640_SSP0_AIF1 |
617 BYT_RT5640_MCLK_EN),
429 }, 618 },
430 { 619 { /* Catch-all for generic Insyde tablets, must be last */
431 .callback = byt_rt5640_quirk_cb,
432 .matches = { 620 .matches = {
433 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), 621 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
434 }, 622 },
435 .driver_data = (void *)(BYT_RT5640_IN3_MAP | 623 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
436 BYT_RT5640_MCLK_EN | 624 BYT_RT5640_MCLK_EN |
437 BYT_RT5640_SSP0_AIF1), 625 BYT_RT5640_SSP0_AIF1),
438 626
@@ -440,6 +628,64 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
440 {} 628 {}
441}; 629};
442 630
631/*
632 * Note this MUST be called before snd_soc_register_card(), so that the props
633 * are in place before the codec component driver's probe function parses them.
634 */
635static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
636{
637 struct property_entry props[MAX_NO_PROPS] = {};
638 struct device *i2c_dev;
639 int ret, cnt = 0;
640
641 i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
642 if (!i2c_dev)
643 return -EPROBE_DEFER;
644
645 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
646 case BYT_RT5640_DMIC1_MAP:
647 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
648 RT5640_DMIC1_DATA_PIN_IN1P);
649 break;
650 case BYT_RT5640_DMIC2_MAP:
651 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
652 RT5640_DMIC2_DATA_PIN_IN1N);
653 break;
654 case BYT_RT5640_IN1_MAP:
655 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
656 props[cnt++] =
657 PROPERTY_ENTRY_BOOL("realtek,in1-differential");
658 break;
659 case BYT_RT5640_IN3_MAP:
660 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
661 props[cnt++] =
662 PROPERTY_ENTRY_BOOL("realtek,in3-differential");
663 break;
664 }
665
666 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
667 props[cnt++] = PROPERTY_ENTRY_U32(
668 "realtek,jack-detect-source",
669 BYT_RT5640_JDSRC(byt_rt5640_quirk));
670
671 props[cnt++] = PROPERTY_ENTRY_U32(
672 "realtek,over-current-threshold-microamp",
673 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
674
675 props[cnt++] = PROPERTY_ENTRY_U32(
676 "realtek,over-current-scale-factor",
677 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
678 }
679
680 if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
681 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
682
683 ret = device_add_properties(i2c_dev, props);
684 put_device(i2c_dev);
685
686 return ret;
687}
688
443static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) 689static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
444{ 690{
445 struct snd_soc_card *card = runtime->card; 691 struct snd_soc_card *card = runtime->card;
@@ -451,6 +697,11 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
451 697
452 card->dapm.idle_bias_off = true; 698 card->dapm.idle_bias_off = true;
453 699
700 /* Start with RC clk for jack-detect (we disable MCLK below) */
701 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
702 snd_soc_component_update_bits(component, RT5640_GLB_CLK,
703 RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
704
454 rt5640_sel_asrc_clk_src(component, 705 rt5640_sel_asrc_clk_src(component,
455 RT5640_DA_STEREO_FILTER | 706 RT5640_DA_STEREO_FILTER |
456 RT5640_DA_MONO_L_FILTER | 707 RT5640_DA_MONO_L_FILTER |
@@ -521,17 +772,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
521 if (ret) 772 if (ret)
522 return ret; 773 return ret;
523 774
524 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
525 snd_soc_component_update_bits(component, RT5640_IN1_IN2, RT5640_IN_DF1,
526 RT5640_IN_DF1);
527 }
528
529 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
530 ret = rt5640_dmic_enable(component, 0, 0);
531 if (ret)
532 return ret;
533 }
534
535 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); 775 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
536 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); 776 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
537 777
@@ -555,11 +795,27 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
555 else 795 else
556 ret = clk_set_rate(priv->mclk, 19200000); 796 ret = clk_set_rate(priv->mclk, 19200000);
557 797
558 if (ret) 798 if (ret) {
559 dev_err(card->dev, "unable to set MCLK rate\n"); 799 dev_err(card->dev, "unable to set MCLK rate\n");
800 return ret;
801 }
560 } 802 }
561 803
562 return ret; 804 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
805 ret = snd_soc_card_jack_new(card, "Headset",
806 SND_JACK_HEADSET | SND_JACK_BTN_0,
807 &priv->jack, rt5640_pins,
808 ARRAY_SIZE(rt5640_pins));
809 if (ret) {
810 dev_err(card->dev, "Jack creation failed %d\n", ret);
811 return ret;
812 }
813 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
814 KEY_PLAYPAUSE);
815 snd_soc_component_set_jack(component, &priv->jack, NULL);
816 }
817
818 return 0;
563} 819}
564 820
565static const struct snd_soc_pcm_stream byt_rt5640_dai_params = { 821static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
@@ -701,6 +957,48 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
701}; 957};
702 958
703/* SoC card */ 959/* SoC card */
960static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
961static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
962static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
963static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
964
965static int byt_rt5640_suspend(struct snd_soc_card *card)
966{
967 struct snd_soc_component *component;
968
969 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
970 return 0;
971
972 list_for_each_entry(component, &card->component_dev_list, card_list) {
973 if (!strcmp(component->name, byt_rt5640_codec_name)) {
974 dev_dbg(component->dev, "disabling jack detect before suspend\n");
975 snd_soc_component_set_jack(component, NULL, NULL);
976 break;
977 }
978 }
979
980 return 0;
981}
982
983static int byt_rt5640_resume(struct snd_soc_card *card)
984{
985 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
986 struct snd_soc_component *component;
987
988 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
989 return 0;
990
991 list_for_each_entry(component, &card->component_dev_list, card_list) {
992 if (!strcmp(component->name, byt_rt5640_codec_name)) {
993 dev_dbg(component->dev, "re-enabling jack detect after resume\n");
994 snd_soc_component_set_jack(component, &priv->jack, NULL);
995 break;
996 }
997 }
998
999 return 0;
1000}
1001
704static struct snd_soc_card byt_rt5640_card = { 1002static struct snd_soc_card byt_rt5640_card = {
705 .name = "bytcr-rt5640", 1003 .name = "bytcr-rt5640",
706 .owner = THIS_MODULE, 1004 .owner = THIS_MODULE,
@@ -711,12 +1009,10 @@ static struct snd_soc_card byt_rt5640_card = {
711 .dapm_routes = byt_rt5640_audio_map, 1009 .dapm_routes = byt_rt5640_audio_map,
712 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map), 1010 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
713 .fully_routed = true, 1011 .fully_routed = true,
1012 .suspend_pre = byt_rt5640_suspend,
1013 .resume_post = byt_rt5640_resume,
714}; 1014};
715 1015
716static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
717static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
718static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
719
720static bool is_valleyview(void) 1016static bool is_valleyview(void)
721{ 1017{
722 static const struct x86_cpu_id cpu_ids[] = { 1018 static const struct x86_cpu_id cpu_ids[] = {
@@ -736,6 +1032,8 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
736 1032
737static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) 1033static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
738{ 1034{
1035 const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
1036 const struct dmi_system_id *dmi_id;
739 struct byt_rt5640_private *priv; 1037 struct byt_rt5640_private *priv;
740 struct snd_soc_acpi_mach *mach; 1038 struct snd_soc_acpi_mach *mach;
741 const char *i2c_name = NULL; 1039 const char *i2c_name = NULL;
@@ -744,7 +1042,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
744 int i; 1042 int i;
745 1043
746 is_bytcr = false; 1044 is_bytcr = false;
747 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 1045 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
748 if (!priv) 1046 if (!priv)
749 return -ENOMEM; 1047 return -ENOMEM;
750 1048
@@ -829,20 +1127,29 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
829 } 1127 }
830 1128
831 /* change defaults for Baytrail-CR capture */ 1129 /* change defaults for Baytrail-CR capture */
832 byt_rt5640_quirk |= BYT_RT5640_IN1_MAP; 1130 byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
833 byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
834 } else { 1131 } else {
835 byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP | 1132 byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
836 BYT_RT5640_DMIC_EN); 1133 BYT_RT5640_JD_SRC_JD2_IN4N |
1134 BYT_RT5640_OVCD_TH_2000UA |
1135 BYT_RT5640_OVCD_SF_0P75;
837 } 1136 }
838 1137
839 /* check quirks before creating card */ 1138 /* check quirks before creating card */
840 dmi_check_system(byt_rt5640_quirk_table); 1139 dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1140 if (dmi_id)
1141 byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
841 if (quirk_override) { 1142 if (quirk_override) {
842 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n", 1143 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
843 (unsigned int)byt_rt5640_quirk, quirk_override); 1144 (unsigned int)byt_rt5640_quirk, quirk_override);
844 byt_rt5640_quirk = quirk_override; 1145 byt_rt5640_quirk = quirk_override;
845 } 1146 }
1147
1148 /* Must be called before register_card, also see declaration comment. */
1149 ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
1150 if (ret_val)
1151 return ret_val;
1152
846 log_quirks(&pdev->dev); 1153 log_quirks(&pdev->dev);
847 1154
848 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || 1155 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
@@ -889,6 +1196,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
889 } 1196 }
890 } 1197 }
891 1198
1199 snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1200 "bytcr-rt5640-%s-spk-%s-mic",
1201 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
1202 "mono" : "stereo",
1203 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1204 byt_rt5640_card.long_name = byt_rt5640_long_name;
1205
892 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); 1206 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
893 1207
894 if (ret_val) { 1208 if (ret_val) {
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index 1b1997f1d60c..987720e203f9 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -706,6 +706,7 @@ static struct snd_soc_card byt_rt5651_card = {
706static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN]; 706static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
707static char byt_rt5651_codec_aif_name[12]; /* = "rt5651-aif[1|2]" */ 707static char byt_rt5651_codec_aif_name[12]; /* = "rt5651-aif[1|2]" */
708static char byt_rt5651_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ 708static char byt_rt5651_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
709static char byt_rt5651_long_name[40]; /* = "bytcr-rt5651-*-spk-*-mic" */
709 710
710static bool is_valleyview(void) 711static bool is_valleyview(void)
711{ 712{
@@ -726,6 +727,10 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
726 727
727static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) 728static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
728{ 729{
730 const char * const intmic_name[] =
731 { "dmic", "in1", "in2", "in12", "in1", "in2" };
732 const char * const hsmic_name[] =
733 { "in2", "in2", "in1", "in3", "in3", "in3" };
729 struct byt_rt5651_private *priv; 734 struct byt_rt5651_private *priv;
730 struct snd_soc_acpi_mach *mach; 735 struct snd_soc_acpi_mach *mach;
731 const char *i2c_name = NULL; 736 const char *i2c_name = NULL;
@@ -734,7 +739,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
734 int dai_index = 0; 739 int dai_index = 0;
735 int i; 740 int i;
736 741
737 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 742 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
738 if (!priv) 743 if (!priv)
739 return -ENOMEM; 744 return -ENOMEM;
740 745
@@ -856,9 +861,10 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
856 if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { 861 if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
857 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); 862 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
858 if (IS_ERR(priv->mclk)) { 863 if (IS_ERR(priv->mclk)) {
864 ret_val = PTR_ERR(priv->mclk);
859 dev_err(&pdev->dev, 865 dev_err(&pdev->dev,
860 "Failed to get MCLK from pmc_plt_clk_3: %ld\n", 866 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
861 PTR_ERR(priv->mclk)); 867 ret_val);
862 /* 868 /*
863 * Fall back to bit clock usage for -ENOENT (clock not 869 * Fall back to bit clock usage for -ENOENT (clock not
864 * available likely due to missing dependencies), bail 870 * available likely due to missing dependencies), bail
@@ -870,6 +876,12 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
870 } 876 }
871 } 877 }
872 878
879 snprintf(byt_rt5651_long_name, sizeof(byt_rt5651_long_name),
880 "bytcr-rt5651-%s-intmic-%s-hsmic",
881 intmic_name[BYT_RT5651_MAP(byt_rt5651_quirk)],
882 hsmic_name[BYT_RT5651_MAP(byt_rt5651_quirk)]);
883 byt_rt5651_card.long_name = byt_rt5651_long_name;
884
873 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card); 885 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
874 886
875 if (ret_val) { 887 if (ret_val) {
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index d3e1c7e12004..db6976f4ddaa 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -391,7 +391,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
391 int ret_val = 0; 391 int ret_val = 0;
392 struct cht_mc_private *drv; 392 struct cht_mc_private *drv;
393 393
394 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 394 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
395 if (!drv) 395 if (!drv)
396 return -ENOMEM; 396 return -ENOMEM;
397 397
diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c
index 680f2b3a24f9..30c46977d53c 100644
--- a/sound/soc/intel/boards/cht_bsw_nau8824.c
+++ b/sound/soc/intel/boards/cht_bsw_nau8824.c
@@ -120,7 +120,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
120 * KEY_VOLUMEUP 120 * KEY_VOLUMEUP
121 * KEY_VOLUMEDOWN 121 * KEY_VOLUMEDOWN
122 */ 122 */
123 jack_type = SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 | 123 jack_type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
124 SND_JACK_BTN_2 | SND_JACK_BTN_3; 124 SND_JACK_BTN_2 | SND_JACK_BTN_3;
125 ret = snd_soc_card_jack_new(runtime->card, "Headset", jack_type, jack, 125 ret = snd_soc_card_jack_new(runtime->card, "Headset", jack_type, jack,
126 cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins)); 126 cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
@@ -248,7 +248,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
248 struct cht_mc_private *drv; 248 struct cht_mc_private *drv;
249 int ret_val; 249 int ret_val;
250 250
251 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 251 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
252 if (!drv) 252 if (!drv)
253 return -ENOMEM; 253 return -ENOMEM;
254 snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); 254 snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 49ba1a956a06..f5a5ea6a093c 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -539,7 +539,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
539 int ret_val = 0; 539 int ret_val = 0;
540 int i; 540 int i;
541 541
542 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 542 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
543 if (!drv) 543 if (!drv)
544 return -ENOMEM; 544 return -ENOMEM;
545 545
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index e68ec32720a4..e5aa13058dd7 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -189,13 +189,6 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
189 if (devm_acpi_dev_add_driver_gpios(component->dev, cht_rt5672_gpios)) 189 if (devm_acpi_dev_add_driver_gpios(component->dev, cht_rt5672_gpios))
190 dev_warn(runtime->dev, "Unable to add GPIO mapping table\n"); 190 dev_warn(runtime->dev, "Unable to add GPIO mapping table\n");
191 191
192 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
193 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
194 if (ret < 0) {
195 dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
196 return ret;
197 }
198
199 /* Select codec ASRC clock source to track I2S1 clock, because codec 192 /* Select codec ASRC clock source to track I2S1 clock, because codec
200 * is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot 193 * is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot
201 * be supported by RT5672. Otherwise, ASRC will be disabled and cause 194 * be supported by RT5672. Otherwise, ASRC will be disabled and cause
@@ -252,6 +245,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
252 SNDRV_PCM_HW_PARAM_RATE); 245 SNDRV_PCM_HW_PARAM_RATE);
253 struct snd_interval *channels = hw_param_interval(params, 246 struct snd_interval *channels = hw_param_interval(params,
254 SNDRV_PCM_HW_PARAM_CHANNELS); 247 SNDRV_PCM_HW_PARAM_CHANNELS);
248 int ret;
255 249
256 /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 250 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
257 rate->min = rate->max = 48000; 251 rate->min = rate->max = 48000;
@@ -259,6 +253,26 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
259 253
260 /* set SSP2 to 24-bit */ 254 /* set SSP2 to 24-bit */
261 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 255 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
256
257 /*
258 * Default mode for SSP configuration is TDM 4 slot
259 */
260 ret = snd_soc_dai_set_fmt(rtd->codec_dai,
261 SND_SOC_DAIFMT_DSP_B |
262 SND_SOC_DAIFMT_IB_NF |
263 SND_SOC_DAIFMT_CBS_CFS);
264 if (ret < 0) {
265 dev_err(rtd->dev, "can't set format to TDM %d\n", ret);
266 return ret;
267 }
268
269 /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
270 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dai, 0xF, 0xF, 4, 24);
271 if (ret < 0) {
272 dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret);
273 return ret;
274 }
275
262 return 0; 276 return 0;
263} 277}
264 278
@@ -315,8 +329,6 @@ static struct snd_soc_dai_link cht_dailink[] = {
315 .nonatomic = true, 329 .nonatomic = true,
316 .codec_dai_name = "rt5670-aif1", 330 .codec_dai_name = "rt5670-aif1",
317 .codec_name = "i2c-10EC5670:00", 331 .codec_name = "i2c-10EC5670:00",
318 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
319 | SND_SOC_DAIFMT_CBS_CFS,
320 .init = cht_codec_init, 332 .init = cht_codec_init,
321 .be_hw_params_fixup = cht_codec_fixup, 333 .be_hw_params_fixup = cht_codec_fixup,
322 .dpcm_playback = 1, 334 .dpcm_playback = 1,
diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
index e84baafd5f63..94294c27d1db 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
@@ -65,14 +65,6 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
65 return -EIO; 65 return -EIO;
66 } 66 }
67 67
68 /* Configure sysclk for codec */
69 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
70 SND_SOC_CLOCK_IN);
71 if (ret) {
72 dev_err(card->dev, "can't set codec sysclk configuration\n");
73 return ret;
74 }
75
76 if (SND_SOC_DAPM_EVENT_OFF(event)) { 68 if (SND_SOC_DAPM_EVENT_OFF(event)) {
77 ret = snd_soc_dai_set_pll(codec_dai, 0, 69 ret = snd_soc_dai_set_pll(codec_dai, 0,
78 DA7219_SYSCLK_MCLK, 0, 0); 70 DA7219_SYSCLK_MCLK, 0, 0);
@@ -169,9 +161,18 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
169{ 161{
170 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); 162 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
171 struct snd_soc_component *component = rtd->codec_dai->component; 163 struct snd_soc_component *component = rtd->codec_dai->component;
164 struct snd_soc_dai *codec_dai = rtd->codec_dai;
172 struct snd_soc_jack *jack; 165 struct snd_soc_jack *jack;
173 int ret; 166 int ret;
174 167
168 /* Configure sysclk for codec */
169 ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
170 SND_SOC_CLOCK_IN);
171 if (ret) {
172 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
173 return ret;
174 }
175
175 /* 176 /*
176 * Headset buttons map to the google Reference headset. 177 * Headset buttons map to the google Reference headset.
177 * These can be configured by userspace. 178 * These can be configured by userspace.
@@ -572,7 +573,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
572{ 573{
573 struct kbl_codec_private *ctx; 574 struct kbl_codec_private *ctx;
574 575
575 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 576 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
576 if (!ctx) 577 if (!ctx)
577 return -ENOMEM; 578 return -ENOMEM;
578 579
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index 0e6b7e79441c..3a61252fe450 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -299,7 +299,8 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
299 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 299 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
300 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 300 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
301 301
302 rt5663_set_jack_detect(component, &ctx->kabylake_headset); 302 snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL);
303
303 return ret; 304 return ret;
304} 305}
305 306
@@ -972,7 +973,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
972 struct skl_machine_pdata *pdata; 973 struct skl_machine_pdata *pdata;
973 int ret; 974 int ret;
974 975
975 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 976 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
976 if (!ctx) 977 if (!ctx)
977 return -ENOMEM; 978 return -ENOMEM;
978 979
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 69c3d8446f06..92f5fb2ae0a3 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -200,7 +200,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
200 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 200 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
201 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 201 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
202 202
203 rt5663_set_jack_detect(component, &ctx->kabylake_headset); 203 snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL);
204 204
205 ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); 205 ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
206 if (ret) 206 if (ret)
@@ -651,7 +651,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
651 struct kbl_codec_private *ctx; 651 struct kbl_codec_private *ctx;
652 struct skl_machine_pdata *pdata; 652 struct skl_machine_pdata *pdata;
653 653
654 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 654 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
655 if (!ctx) 655 if (!ctx)
656 return -ENOMEM; 656 return -ENOMEM;
657 657
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index 9a7a0646bffe..3ff6646cfa21 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -643,7 +643,7 @@ static int skylake_audio_probe(struct platform_device *pdev)
643 struct skl_nau8825_private *ctx; 643 struct skl_nau8825_private *ctx;
644 struct skl_machine_pdata *pdata; 644 struct skl_machine_pdata *pdata;
645 645
646 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 646 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
647 if (!ctx) 647 if (!ctx)
648 return -ENOMEM; 648 return -ENOMEM;
649 649
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 212ac8971e55..b0610bba3cfa 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -696,7 +696,7 @@ static int skylake_audio_probe(struct platform_device *pdev)
696 struct skl_nau88125_private *ctx; 696 struct skl_nau88125_private *ctx;
697 struct skl_machine_pdata *pdata; 697 struct skl_machine_pdata *pdata;
698 698
699 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 699 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
700 if (!ctx) 700 if (!ctx)
701 return -ENOMEM; 701 return -ENOMEM;
702 702
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 737d5615b0ef..38a1495c29cf 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -527,7 +527,7 @@ static int skylake_audio_probe(struct platform_device *pdev)
527{ 527{
528 struct skl_rt286_private *ctx; 528 struct skl_rt286_private *ctx;
529 529
530 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 530 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
531 if (!ctx) 531 if (!ctx)
532 return -ENOMEM; 532 return -ENOMEM;
533 533
diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c
index a016455a6ddb..5d7ac2ee7a3c 100644
--- a/sound/soc/intel/skylake/skl-debug.c
+++ b/sound/soc/intel/skylake/skl-debug.c
@@ -15,10 +15,10 @@
15 15
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/debugfs.h> 17#include <linux/debugfs.h>
18#include <uapi/sound/skl-tplg-interface.h>
18#include "skl.h" 19#include "skl.h"
19#include "skl-sst-dsp.h" 20#include "skl-sst-dsp.h"
20#include "skl-sst-ipc.h" 21#include "skl-sst-ipc.h"
21#include "skl-tplg-interface.h"
22#include "skl-topology.h" 22#include "skl-topology.h"
23#include "../common/sst-dsp.h" 23#include "../common/sst-dsp.h"
24#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
@@ -142,8 +142,8 @@ static ssize_t module_read(struct file *file, char __user *user_buf,
142 mconfig->max_out_queue, ret, false); 142 mconfig->max_out_queue, ret, false);
143 143
144 ret += snprintf(buf + ret, MOD_BUF - ret, 144 ret += snprintf(buf + ret, MOD_BUF - ret,
145 "Other:\n\tDomain %d\n\tHomogenous Input %s\n\t" 145 "Other:\n\tDomain %d\n\tHomogeneous Input %s\n\t"
146 "Homogenous Output %s\n\tIn Queue Mask %d\n\t" 146 "Homogeneous Output %s\n\tIn Queue Mask %d\n\t"
147 "Out Queue Mask %d\n\tDMA ID %d\n\tMem Pages %d\n\t" 147 "Out Queue Mask %d\n\tDMA ID %d\n\tMem Pages %d\n\t"
148 "Module Type %d\n\tModule State %d\n", 148 "Module Type %d\n\tModule State %d\n",
149 mconfig->domain, 149 mconfig->domain,
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 57d4a58522a6..d5f9c30eba32 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -21,6 +21,7 @@
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <uapi/sound/skl-tplg-interface.h>
24#include "skl-sst-dsp.h" 25#include "skl-sst-dsp.h"
25#include "cnl-sst-dsp.h" 26#include "cnl-sst-dsp.h"
26#include "skl-sst-ipc.h" 27#include "skl-sst-ipc.h"
@@ -28,7 +29,6 @@
28#include "../common/sst-dsp.h" 29#include "../common/sst-dsp.h"
29#include "../common/sst-dsp-priv.h" 30#include "../common/sst-dsp-priv.h"
30#include "skl-topology.h" 31#include "skl-topology.h"
31#include "skl-tplg-interface.h"
32 32
33static int skl_alloc_dma_buf(struct device *dev, 33static int skl_alloc_dma_buf(struct device *dev,
34 struct snd_dma_buffer *dmab, size_t size) 34 struct snd_dma_buffer *dmab, size_t size)
@@ -225,7 +225,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
225 .id = 0x9d71, 225 .id = 0x9d71,
226 .num_cores = 2, 226 .num_cores = 2,
227 .loader_ops = skl_get_loader_ops, 227 .loader_ops = skl_get_loader_ops,
228 .init = kbl_sst_dsp_init, 228 .init = skl_sst_dsp_init,
229 .init_fw = skl_sst_init_fw, 229 .init_fw = skl_sst_init_fw,
230 .cleanup = skl_sst_dsp_cleanup 230 .cleanup = skl_sst_dsp_cleanup
231 }, 231 },
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 15cb8ac3e374..afa86b9e4dcf 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -268,15 +268,31 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
268{ 268{
269 struct skl *skl = get_skl_ctx(dai->dev); 269 struct skl *skl = get_skl_ctx(dai->dev);
270 struct skl_module_cfg *mconfig; 270 struct skl_module_cfg *mconfig;
271 int ret;
271 272
272 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 273 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
273 274
274 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 275 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
275 276
276 /* In case of XRUN recovery, reset the FW pipe to clean state */ 277 /*
277 if (mconfig && (substream->runtime->status->state == 278 * In case of XRUN recovery or in the case when the application
278 SNDRV_PCM_STATE_XRUN)) 279 * calls prepare another time, reset the FW pipe to clean state
279 skl_reset_pipe(skl->skl_sst, mconfig->pipe); 280 */
281 if (mconfig &&
282 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN ||
283 mconfig->pipe->state == SKL_PIPE_CREATED ||
284 mconfig->pipe->state == SKL_PIPE_PAUSED)) {
285
286 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
287
288 if (ret < 0)
289 return ret;
290
291 ret = skl_pcm_host_dma_prepare(dai->dev,
292 mconfig->pipe->p_params);
293 if (ret < 0)
294 return ret;
295 }
280 296
281 return 0; 297 return 0;
282} 298}
@@ -366,9 +382,21 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
366{ 382{
367 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 383 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
368 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 384 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
385 struct skl *skl = get_skl_ctx(dai->dev);
386 struct skl_module_cfg *mconfig;
387 int ret;
369 388
370 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 389 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
371 390
391 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
392
393 if (mconfig) {
394 ret = skl_reset_pipe(skl->skl_sst, mconfig->pipe);
395 if (ret < 0)
396 dev_err(dai->dev, "%s:Reset failed ret =%d",
397 __func__, ret);
398 }
399
372 snd_hdac_stream_cleanup(hdac_stream(stream)); 400 snd_hdac_stream_cleanup(hdac_stream(stream));
373 hdac_stream(stream)->prepared = 0; 401 hdac_stream(stream)->prepared = 0;
374 402
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 12fc9a73dc8a..e1d6f6719f7e 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -231,9 +231,6 @@ int skl_dsp_boot(struct sst_dsp *ctx);
231int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 231int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
232 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 232 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
233 struct skl_sst **dsp); 233 struct skl_sst **dsp);
234int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
235 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
236 struct skl_sst **dsp);
237int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 234int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
238 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 235 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
239 struct skl_sst **dsp); 236 struct skl_sst **dsp);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 5a7e41b65ef3..5951bbdf1f1a 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -390,7 +390,7 @@ out:
390} 390}
391 391
392static int 392static int
393kbl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count) 393skl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
394{ 394{
395 struct skl_sst *skl = ctx->thread_context; 395 struct skl_sst *skl = ctx->thread_context;
396 struct firmware stripped_fw; 396 struct firmware stripped_fw;
@@ -508,16 +508,7 @@ static const struct skl_dsp_fw_ops skl_fw_ops = {
508 .set_state_D3 = skl_set_dsp_D3, 508 .set_state_D3 = skl_set_dsp_D3,
509 .load_fw = skl_load_base_firmware, 509 .load_fw = skl_load_base_firmware,
510 .get_fw_errcode = skl_get_errorcode, 510 .get_fw_errcode = skl_get_errorcode,
511 .load_mod = skl_load_module, 511 .load_library = skl_load_library,
512 .unload_mod = skl_unload_module,
513};
514
515static const struct skl_dsp_fw_ops kbl_fw_ops = {
516 .set_state_D0 = skl_set_dsp_D0,
517 .set_state_D3 = skl_set_dsp_D3,
518 .load_fw = skl_load_base_firmware,
519 .get_fw_errcode = skl_get_errorcode,
520 .load_library = kbl_load_library,
521 .load_mod = skl_load_module, 512 .load_mod = skl_load_module,
522 .unload_mod = skl_unload_module, 513 .unload_mod = skl_unload_module,
523}; 514};
@@ -573,27 +564,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
573} 564}
574EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 565EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
575 566
576int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
577 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
578 struct skl_sst **dsp)
579{
580 struct sst_dsp *sst;
581 int ret;
582
583 ret = skl_sst_dsp_init(dev, mmio_base, irq, fw_name, dsp_ops, dsp);
584 if (ret < 0) {
585 dev_err(dev, "%s: Init failed %d\n", __func__, ret);
586 return ret;
587 }
588
589 sst = (*dsp)->dsp;
590 sst->fw_ops = kbl_fw_ops;
591
592 return 0;
593
594}
595EXPORT_SYMBOL_GPL(kbl_sst_dsp_init);
596
597int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) 567int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
598{ 568{
599 int ret; 569 int ret;
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 3b1dca419883..2c5129782959 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -19,14 +19,15 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/firmware.h> 21#include <linux/firmware.h>
22#include <linux/uuid.h>
22#include <sound/soc.h> 23#include <sound/soc.h>
23#include <sound/soc-topology.h> 24#include <sound/soc-topology.h>
24#include <uapi/sound/snd_sst_tokens.h> 25#include <uapi/sound/snd_sst_tokens.h>
26#include <uapi/sound/skl-tplg-interface.h>
25#include "skl-sst-dsp.h" 27#include "skl-sst-dsp.h"
26#include "skl-sst-ipc.h" 28#include "skl-sst-ipc.h"
27#include "skl-topology.h" 29#include "skl-topology.h"
28#include "skl.h" 30#include "skl.h"
29#include "skl-tplg-interface.h"
30#include "../common/sst-dsp.h" 31#include "../common/sst-dsp.h"
31#include "../common/sst-dsp-priv.h" 32#include "../common/sst-dsp-priv.h"
32 33
@@ -2724,6 +2725,167 @@ static int skl_tplg_get_desc_blocks(struct device *dev,
2724 return -EINVAL; 2725 return -EINVAL;
2725} 2726}
2726 2727
2728/* Functions to parse private data from configuration file format v4 */
2729
2730/*
2731 * Add pipeline from topology binary into driver pipeline list
2732 *
2733 * If already added we return that instance
2734 * Otherwise we create a new instance and add into driver list
2735 */
2736static int skl_tplg_add_pipe_v4(struct device *dev,
2737 struct skl_module_cfg *mconfig, struct skl *skl,
2738 struct skl_dfw_v4_pipe *dfw_pipe)
2739{
2740 struct skl_pipeline *ppl;
2741 struct skl_pipe *pipe;
2742 struct skl_pipe_params *params;
2743
2744 list_for_each_entry(ppl, &skl->ppl_list, node) {
2745 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) {
2746 mconfig->pipe = ppl->pipe;
2747 return 0;
2748 }
2749 }
2750
2751 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
2752 if (!ppl)
2753 return -ENOMEM;
2754
2755 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
2756 if (!pipe)
2757 return -ENOMEM;
2758
2759 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
2760 if (!params)
2761 return -ENOMEM;
2762
2763 pipe->ppl_id = dfw_pipe->pipe_id;
2764 pipe->memory_pages = dfw_pipe->memory_pages;
2765 pipe->pipe_priority = dfw_pipe->pipe_priority;
2766 pipe->conn_type = dfw_pipe->conn_type;
2767 pipe->state = SKL_PIPE_INVALID;
2768 pipe->p_params = params;
2769 INIT_LIST_HEAD(&pipe->w_list);
2770
2771 ppl->pipe = pipe;
2772 list_add(&ppl->node, &skl->ppl_list);
2773
2774 mconfig->pipe = pipe;
2775
2776 return 0;
2777}
2778
2779static void skl_fill_module_pin_info_v4(struct skl_dfw_v4_module_pin *dfw_pin,
2780 struct skl_module_pin *m_pin,
2781 bool is_dynamic, int max_pin)
2782{
2783 int i;
2784
2785 for (i = 0; i < max_pin; i++) {
2786 m_pin[i].id.module_id = dfw_pin[i].module_id;
2787 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
2788 m_pin[i].in_use = false;
2789 m_pin[i].is_dynamic = is_dynamic;
2790 m_pin[i].pin_state = SKL_PIN_UNBIND;
2791 }
2792}
2793
2794static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt,
2795 struct skl_dfw_v4_module_fmt *src_fmt,
2796 int pins)
2797{
2798 int i;
2799
2800 for (i = 0; i < pins; i++) {
2801 dst_fmt[i].fmt.channels = src_fmt[i].channels;
2802 dst_fmt[i].fmt.s_freq = src_fmt[i].freq;
2803 dst_fmt[i].fmt.bit_depth = src_fmt[i].bit_depth;
2804 dst_fmt[i].fmt.valid_bit_depth = src_fmt[i].valid_bit_depth;
2805 dst_fmt[i].fmt.ch_cfg = src_fmt[i].ch_cfg;
2806 dst_fmt[i].fmt.ch_map = src_fmt[i].ch_map;
2807 dst_fmt[i].fmt.interleaving_style =
2808 src_fmt[i].interleaving_style;
2809 dst_fmt[i].fmt.sample_type = src_fmt[i].sample_type;
2810 }
2811}
2812
2813static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
2814 struct skl *skl, struct device *dev,
2815 struct skl_module_cfg *mconfig)
2816{
2817 struct skl_dfw_v4_module *dfw =
2818 (struct skl_dfw_v4_module *)tplg_w->priv.data;
2819 int ret;
2820
2821 dev_dbg(dev, "Parsing Skylake v4 widget topology data\n");
2822
2823 ret = guid_parse(dfw->uuid, (guid_t *)mconfig->guid);
2824 if (ret)
2825 return ret;
2826 mconfig->id.module_id = -1;
2827 mconfig->id.instance_id = dfw->instance_id;
2828 mconfig->module->resources[0].cps = dfw->max_mcps;
2829 mconfig->module->resources[0].ibs = dfw->ibs;
2830 mconfig->module->resources[0].obs = dfw->obs;
2831 mconfig->core_id = dfw->core_id;
2832 mconfig->module->max_input_pins = dfw->max_in_queue;
2833 mconfig->module->max_output_pins = dfw->max_out_queue;
2834 mconfig->module->loadable = dfw->is_loadable;
2835 skl_tplg_fill_fmt_v4(mconfig->module->formats[0].inputs, dfw->in_fmt,
2836 MAX_IN_QUEUE);
2837 skl_tplg_fill_fmt_v4(mconfig->module->formats[0].outputs, dfw->out_fmt,
2838 MAX_OUT_QUEUE);
2839
2840 mconfig->params_fixup = dfw->params_fixup;
2841 mconfig->converter = dfw->converter;
2842 mconfig->m_type = dfw->module_type;
2843 mconfig->vbus_id = dfw->vbus_id;
2844 mconfig->module->resources[0].is_pages = dfw->mem_pages;
2845
2846 ret = skl_tplg_add_pipe_v4(dev, mconfig, skl, &dfw->pipe);
2847 if (ret)
2848 return ret;
2849
2850 mconfig->dev_type = dfw->dev_type;
2851 mconfig->hw_conn_type = dfw->hw_conn_type;
2852 mconfig->time_slot = dfw->time_slot;
2853 mconfig->formats_config.caps_size = dfw->caps.caps_size;
2854
2855 mconfig->m_in_pin = devm_kzalloc(dev,
2856 MAX_IN_QUEUE * sizeof(*mconfig->m_in_pin),
2857 GFP_KERNEL);
2858 if (!mconfig->m_in_pin)
2859 return -ENOMEM;
2860
2861 mconfig->m_out_pin = devm_kzalloc(dev,
2862 MAX_OUT_QUEUE * sizeof(*mconfig->m_out_pin),
2863 GFP_KERNEL);
2864 if (!mconfig->m_out_pin)
2865 return -ENOMEM;
2866
2867 skl_fill_module_pin_info_v4(dfw->in_pin, mconfig->m_in_pin,
2868 dfw->is_dynamic_in_pin,
2869 mconfig->module->max_input_pins);
2870 skl_fill_module_pin_info_v4(dfw->out_pin, mconfig->m_out_pin,
2871 dfw->is_dynamic_out_pin,
2872 mconfig->module->max_output_pins);
2873
2874 if (mconfig->formats_config.caps_size) {
2875 mconfig->formats_config.set_params = dfw->caps.set_params;
2876 mconfig->formats_config.param_id = dfw->caps.param_id;
2877 mconfig->formats_config.caps =
2878 devm_kzalloc(dev, mconfig->formats_config.caps_size,
2879 GFP_KERNEL);
2880 if (!mconfig->formats_config.caps)
2881 return -ENOMEM;
2882 memcpy(mconfig->formats_config.caps, dfw->caps.caps,
2883 dfw->caps.caps_size);
2884 }
2885
2886 return 0;
2887}
2888
2727/* 2889/*
2728 * Parse the private data for the token and corresponding value. 2890 * Parse the private data for the token and corresponding value.
2729 * The private data can have multiple data blocks. So, a data block 2891 * The private data can have multiple data blocks. So, a data block
@@ -2739,6 +2901,13 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
2739 char *data; 2901 char *data;
2740 int ret; 2902 int ret;
2741 2903
2904 /*
2905 * v4 configuration files have a valid UUID at the start of
2906 * the widget's private data.
2907 */
2908 if (uuid_is_valid((char *)tplg_w->priv.data))
2909 return skl_tplg_get_pvt_data_v4(tplg_w, skl, dev, mconfig);
2910
2742 /* Read the NUM_DATA_BLOCKS descriptor */ 2911 /* Read the NUM_DATA_BLOCKS descriptor */
2743 array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data; 2912 array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;
2744 ret = skl_tplg_get_desc_blocks(dev, array); 2913 ret = skl_tplg_get_desc_blocks(dev, array);
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index b1e0667c0ae0..6d7e0569695f 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -25,8 +25,8 @@
25 25
26#include <sound/hdaudio_ext.h> 26#include <sound/hdaudio_ext.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <uapi/sound/skl-tplg-interface.h>
28#include "skl.h" 29#include "skl.h"
29#include "skl-tplg-interface.h"
30 30
31#define BITS_PER_BYTE 8 31#define BITS_PER_BYTE 8
32#define MAX_TS_GROUPS 8 32#define MAX_TS_GROUPS 8
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index abf324747b29..f0d9793f872a 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -127,10 +127,17 @@ static void skl_clock_power_gating(struct device *dev, bool enable)
127 */ 127 */
128static int skl_init_chip(struct hdac_bus *bus, bool full_reset) 128static int skl_init_chip(struct hdac_bus *bus, bool full_reset)
129{ 129{
130 struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
131 struct hdac_ext_link *hlink;
130 int ret; 132 int ret;
131 133
132 skl_enable_miscbdcge(bus->dev, false); 134 skl_enable_miscbdcge(bus->dev, false);
133 ret = snd_hdac_bus_init_chip(bus, full_reset); 135 ret = snd_hdac_bus_init_chip(bus, full_reset);
136
137 /* Reset stream-to-link mapping */
138 list_for_each_entry(hlink, &ebus->hlink_list, list)
139 bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
140
134 skl_enable_miscbdcge(bus->dev, true); 141 skl_enable_miscbdcge(bus->dev, true);
135 142
136 return ret; 143 return ret;
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index bc3c7b5ac752..132bb83f8e99 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -1,7 +1,6 @@
1config SND_KIRKWOOD_SOC 1config SND_KIRKWOOD_SOC
2 tristate "SoC Audio for the Marvell Kirkwood and Dove chips" 2 tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
3 depends on ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST 3 depends on ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
4 depends on HAS_DMA
5 help 4 help
6 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
7 the Kirkwood I2S interface. You will also need to select the 6 the Kirkwood I2S interface. You will also need to select the
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 5c68797f36c4..e731d40afcce 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -32,6 +32,26 @@ config SND_SOC_MT2701_WM8960
32 Select Y if you have such device. 32 Select Y if you have such device.
33 If unsure select "N". 33 If unsure select "N".
34 34
35config SND_SOC_MT6797
36 tristate "ASoC support for Mediatek MT6797 chip"
37 depends on ARCH_MEDIATEK
38 select SND_SOC_MEDIATEK
39 help
40 This adds ASoC driver for Mediatek MT6797 boards
41 that can be used with other codecs.
42 Select Y if you have such device.
43 If unsure select "N".
44
45config SND_SOC_MT6797_MT6351
46 tristate "ASoc Audio driver for MT6797 with MT6351 codec"
47 depends on SND_SOC_MT6797 && MTK_PMIC_WRAP
48 select SND_SOC_MT6351
49 help
50 This adds ASoC driver for Mediatek MT6797 boards
51 with the MT6351 codecs.
52 Select Y if you have such device.
53 If unsure select "N".
54
35config SND_SOC_MT8173 55config SND_SOC_MT8173
36 tristate "ASoC support for Mediatek MT8173 chip" 56 tristate "ASoC support for Mediatek MT8173 chip"
37 depends on ARCH_MEDIATEK 57 depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 6bcab35dc828..3bb2c47532f4 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,3 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
1obj-$(CONFIG_SND_SOC_MEDIATEK) += common/ 2obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
2obj-$(CONFIG_SND_SOC_MT2701) += mt2701/ 3obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
4obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
3obj-$(CONFIG_SND_SOC_MT8173) += mt8173/ 5obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
diff --git a/sound/soc/mediatek/common/Makefile b/sound/soc/mediatek/common/Makefile
index a55d33bc7b01..cdadabc5fd16 100644
--- a/sound/soc/mediatek/common/Makefile
+++ b/sound/soc/mediatek/common/Makefile
@@ -1,16 +1,4 @@
1# 1# SPDX-License-Identifier: GPL-2.0
2# Copyright (C) 2015 MediaTek Inc.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13
14# platform driver 2# platform driver
15snd-soc-mtk-common-objs := mtk-afe-platform-driver.o mtk-afe-fe-dai.o 3snd-soc-mtk-common-objs := mtk-afe-platform-driver.o mtk-afe-fe-dai.o
16obj-$(CONFIG_SND_SOC_MEDIATEK) += snd-soc-mtk-common.o 4obj-$(CONFIG_SND_SOC_MEDIATEK) += snd-soc-mtk-common.o
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index c91e5f4cd902..cf4978be062f 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mtk-afe-fe-dais.c -- Mediatek afe fe dai operator 3 * mtk-afe-fe-dais.c -- Mediatek afe fe dai operator
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
@@ -44,8 +36,7 @@ int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
44 struct snd_soc_dai *dai) 36 struct snd_soc_dai *dai)
45{ 37{
46 struct snd_soc_pcm_runtime *rtd = substream->private_data; 38 struct snd_soc_pcm_runtime *rtd = substream->private_data;
47 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 39 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
48 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
49 struct snd_pcm_runtime *runtime = substream->runtime; 40 struct snd_pcm_runtime *runtime = substream->runtime;
50 int memif_num = rtd->cpu_dai->id; 41 int memif_num = rtd->cpu_dai->id;
51 struct mtk_base_afe_memif *memif = &afe->memif[memif_num]; 42 struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
@@ -107,8 +98,7 @@ void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
107 struct snd_soc_dai *dai) 98 struct snd_soc_dai *dai)
108{ 99{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 101 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
111 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
112 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 102 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
113 int irq_id; 103 int irq_id;
114 104
@@ -131,8 +121,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
131 struct snd_soc_dai *dai) 121 struct snd_soc_dai *dai)
132{ 122{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 124 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
135 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
136 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 125 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
137 int msb_at_bit33 = 0; 126 int msb_at_bit33 = 0;
138 int ret, fs = 0; 127 int ret, fs = 0;
@@ -196,8 +185,7 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
196{ 185{
197 struct snd_soc_pcm_runtime *rtd = substream->private_data; 186 struct snd_soc_pcm_runtime *rtd = substream->private_data;
198 struct snd_pcm_runtime * const runtime = substream->runtime; 187 struct snd_pcm_runtime * const runtime = substream->runtime;
199 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 188 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
200 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
201 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 189 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
202 struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage]; 190 struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
203 const struct mtk_base_irq_data *irq_data = irqs->irq_data; 191 const struct mtk_base_irq_data *irq_data = irqs->irq_data;
@@ -260,8 +248,7 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
260 struct snd_soc_dai *dai) 248 struct snd_soc_dai *dai)
261{ 249{
262 struct snd_soc_pcm_runtime *rtd = substream->private_data; 250 struct snd_soc_pcm_runtime *rtd = substream->private_data;
263 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 251 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
264 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
265 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 252 struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
266 int hd_audio = 0; 253 int hd_audio = 0;
267 254
@@ -333,7 +320,7 @@ EXPORT_SYMBOL_GPL(mtk_dynamic_irq_release);
333 320
334int mtk_afe_dai_suspend(struct snd_soc_dai *dai) 321int mtk_afe_dai_suspend(struct snd_soc_dai *dai)
335{ 322{
336 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 323 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
337 struct device *dev = afe->dev; 324 struct device *dev = afe->dev;
338 struct regmap *regmap = afe->regmap; 325 struct regmap *regmap = afe->regmap;
339 int i; 326 int i;
@@ -358,7 +345,7 @@ EXPORT_SYMBOL_GPL(mtk_afe_dai_suspend);
358 345
359int mtk_afe_dai_resume(struct snd_soc_dai *dai) 346int mtk_afe_dai_resume(struct snd_soc_dai *dai)
360{ 347{
361 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 348 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
362 struct device *dev = afe->dev; 349 struct device *dev = afe->dev;
363 struct regmap *regmap = afe->regmap; 350 struct regmap *regmap = afe->regmap;
364 int i = 0; 351 int i = 0;
@@ -383,4 +370,3 @@ EXPORT_SYMBOL_GPL(mtk_afe_dai_resume);
383MODULE_DESCRIPTION("Mediatek simple fe dai operator"); 370MODULE_DESCRIPTION("Mediatek simple fe dai operator");
384MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); 371MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
385MODULE_LICENSE("GPL v2"); 372MODULE_LICENSE("GPL v2");
386
diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.h b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
index 28cb17854da1..55074fb9861a 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
@@ -1,17 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition 3 * mtk-afe-fe-dais.h -- Mediatek afe fe dai operator definition
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef _MTK_AFE_FE_DAI_H_ 9#ifndef _MTK_AFE_FE_DAI_H_
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.c b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
index 53215b52e4f2..51ec4ff6ed95 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.c
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mtk-afe-platform-driver.c -- Mediatek afe platform driver 3 * mtk-afe-platform-driver.c -- Mediatek afe platform driver
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
@@ -21,6 +13,86 @@
21#include "mtk-afe-platform-driver.h" 13#include "mtk-afe-platform-driver.h"
22#include "mtk-base-afe.h" 14#include "mtk-base-afe.h"
23 15
16int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe)
17{
18 struct snd_soc_dai_driver *sub_dai_drivers;
19 size_t num_dai_drivers = 0, dai_idx = 0;
20 int i;
21
22 if (!afe->sub_dais) {
23 dev_err(afe->dev, "%s(), sub_dais == NULL\n", __func__);
24 return -EINVAL;
25 }
26
27 /* calcualte total dai driver size */
28 for (i = 0; i < afe->num_sub_dais; i++) {
29 if (afe->sub_dais[i].dai_drivers &&
30 afe->sub_dais[i].num_dai_drivers != 0)
31 num_dai_drivers += afe->sub_dais[i].num_dai_drivers;
32 }
33
34 dev_info(afe->dev, "%s(), num of dai %zd\n", __func__, num_dai_drivers);
35
36 /* combine sub_dais */
37 afe->num_dai_drivers = num_dai_drivers;
38 afe->dai_drivers = devm_kcalloc(afe->dev,
39 num_dai_drivers,
40 sizeof(struct snd_soc_dai_driver),
41 GFP_KERNEL);
42 if (!afe->dai_drivers)
43 return -ENOMEM;
44
45 for (i = 0; i < afe->num_sub_dais; i++) {
46 if (afe->sub_dais[i].dai_drivers &&
47 afe->sub_dais[i].num_dai_drivers != 0) {
48 sub_dai_drivers = afe->sub_dais[i].dai_drivers;
49 /* dai driver */
50 memcpy(&afe->dai_drivers[dai_idx],
51 sub_dai_drivers,
52 afe->sub_dais[i].num_dai_drivers *
53 sizeof(struct snd_soc_dai_driver));
54 dai_idx += afe->sub_dais[i].num_dai_drivers;
55 }
56 }
57
58 return 0;
59}
60EXPORT_SYMBOL_GPL(mtk_afe_combine_sub_dai);
61
62int mtk_afe_add_sub_dai_control(struct snd_soc_component *component)
63{
64 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
65 int i;
66
67 if (!afe->sub_dais) {
68 dev_err(afe->dev, "%s(), sub_dais == NULL\n", __func__);
69 return -EINVAL;
70 }
71
72 for (i = 0; i < afe->num_sub_dais; i++) {
73 if (afe->sub_dais[i].controls)
74 snd_soc_add_component_controls(component,
75 afe->sub_dais[i].controls,
76 afe->sub_dais[i].num_controls);
77
78 if (afe->sub_dais[i].dapm_widgets)
79 snd_soc_dapm_new_controls(&component->dapm,
80 afe->sub_dais[i].dapm_widgets,
81 afe->sub_dais[i].num_dapm_widgets);
82
83 if (afe->sub_dais[i].dapm_routes)
84 snd_soc_dapm_add_routes(&component->dapm,
85 afe->sub_dais[i].dapm_routes,
86 afe->sub_dais[i].num_dapm_routes);
87 }
88
89 snd_soc_dapm_new_widgets(component->dapm.card);
90
91 return 0;
92
93}
94EXPORT_SYMBOL_GPL(mtk_afe_add_sub_dai_control);
95
24static snd_pcm_uframes_t mtk_afe_pcm_pointer 96static snd_pcm_uframes_t mtk_afe_pcm_pointer
25 (struct snd_pcm_substream *substream) 97 (struct snd_pcm_substream *substream)
26{ 98{
@@ -56,28 +128,31 @@ POINTER_RETURN_FRAMES:
56 return bytes_to_frames(substream->runtime, pcm_ptr_bytes); 128 return bytes_to_frames(substream->runtime, pcm_ptr_bytes);
57} 129}
58 130
59static const struct snd_pcm_ops mtk_afe_pcm_ops = { 131const struct snd_pcm_ops mtk_afe_pcm_ops = {
60 .ioctl = snd_pcm_lib_ioctl, 132 .ioctl = snd_pcm_lib_ioctl,
61 .pointer = mtk_afe_pcm_pointer, 133 .pointer = mtk_afe_pcm_pointer,
62}; 134};
135EXPORT_SYMBOL_GPL(mtk_afe_pcm_ops);
63 136
64static int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd) 137int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd)
65{ 138{
66 size_t size; 139 size_t size;
67 struct snd_card *card = rtd->card->snd_card;
68 struct snd_pcm *pcm = rtd->pcm; 140 struct snd_pcm *pcm = rtd->pcm;
69 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 141 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
70 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 142 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
71 143
72 size = afe->mtk_afe_hardware->buffer_bytes_max; 144 size = afe->mtk_afe_hardware->buffer_bytes_max;
73 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 145 return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
74 card->dev, size, size); 146 afe->dev,
147 size, size);
75} 148}
149EXPORT_SYMBOL_GPL(mtk_afe_pcm_new);
76 150
77static void mtk_afe_pcm_free(struct snd_pcm *pcm) 151void mtk_afe_pcm_free(struct snd_pcm *pcm)
78{ 152{
79 snd_pcm_lib_preallocate_free_for_all(pcm); 153 snd_pcm_lib_preallocate_free_for_all(pcm);
80} 154}
155EXPORT_SYMBOL_GPL(mtk_afe_pcm_free);
81 156
82const struct snd_soc_component_driver mtk_afe_pcm_platform = { 157const struct snd_soc_component_driver mtk_afe_pcm_platform = {
83 .name = AFE_PCM_NAME, 158 .name = AFE_PCM_NAME,
diff --git a/sound/soc/mediatek/common/mtk-afe-platform-driver.h b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
index 8dcdbed959ea..88df6797732f 100644
--- a/sound/soc/mediatek/common/mtk-afe-platform-driver.h
+++ b/sound/soc/mediatek/common/mtk-afe-platform-driver.h
@@ -1,24 +1,28 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition 3 * mtk-afe-platform-driver.h -- Mediatek afe platform driver definition
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef _MTK_AFE_PLATFORM_DRIVER_H_ 9#ifndef _MTK_AFE_PLATFORM_DRIVER_H_
18#define _MTK_AFE_PLATFORM_DRIVER_H_ 10#define _MTK_AFE_PLATFORM_DRIVER_H_
19 11
20#define AFE_PCM_NAME "mtk-afe-pcm" 12#define AFE_PCM_NAME "mtk-afe-pcm"
13extern const struct snd_pcm_ops mtk_afe_pcm_ops;
21extern const struct snd_soc_component_driver mtk_afe_pcm_platform; 14extern const struct snd_soc_component_driver mtk_afe_pcm_platform;
22 15
16struct mtk_base_afe;
17struct snd_pcm;
18struct snd_soc_component;
19struct snd_soc_pcm_runtime;
20
21
22int mtk_afe_pcm_new(struct snd_soc_pcm_runtime *rtd);
23void mtk_afe_pcm_free(struct snd_pcm *pcm);
24
25int mtk_afe_combine_sub_dai(struct mtk_base_afe *afe);
26int mtk_afe_add_sub_dai_control(struct snd_soc_component *component);
23#endif 27#endif
24 28
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index 3a78f6f17195..bcf562f029b6 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -1,22 +1,16 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mtk-base-afe.h -- Mediatek base afe structure 3 * mtk-base-afe.h -- Mediatek base afe structure
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef _MTK_BASE_AFE_H_ 9#ifndef _MTK_BASE_AFE_H_
18#define _MTK_BASE_AFE_H_ 10#define _MTK_BASE_AFE_H_
19 11
12#define MTK_STREAM_NUM (SNDRV_PCM_STREAM_LAST + 1)
13
20struct mtk_base_memif_data { 14struct mtk_base_memif_data {
21 int id; 15 int id;
22 const char *name; 16 const char *name;
@@ -54,6 +48,7 @@ struct mtk_base_irq_data {
54struct device; 48struct device;
55struct mtk_base_afe_memif; 49struct mtk_base_afe_memif;
56struct mtk_base_afe_irq; 50struct mtk_base_afe_irq;
51struct mtk_base_afe_dai;
57struct regmap; 52struct regmap;
58struct snd_pcm_substream; 53struct snd_pcm_substream;
59struct snd_soc_dai; 54struct snd_soc_dai;
@@ -77,6 +72,11 @@ struct mtk_base_afe {
77 struct mtk_base_afe_irq *irqs; 72 struct mtk_base_afe_irq *irqs;
78 int irqs_size; 73 int irqs_size;
79 74
75 struct mtk_base_afe_dai *sub_dais;
76 int num_sub_dais;
77 struct snd_soc_dai_driver *dai_drivers;
78 unsigned int num_dai_drivers;
79
80 const struct snd_pcm_hardware *mtk_afe_hardware; 80 const struct snd_pcm_hardware *mtk_afe_hardware;
81 int (*memif_fs)(struct snd_pcm_substream *substream, 81 int (*memif_fs)(struct snd_pcm_substream *substream,
82 unsigned int rate); 82 unsigned int rate);
@@ -100,5 +100,17 @@ struct mtk_base_afe_irq {
100 int irq_occupyed; 100 int irq_occupyed;
101}; 101};
102 102
103struct mtk_base_afe_dai {
104 struct snd_soc_dai_driver *dai_drivers;
105 unsigned int num_dai_drivers;
106
107 const struct snd_kcontrol_new *controls;
108 unsigned int num_controls;
109 const struct snd_soc_dapm_widget *dapm_widgets;
110 unsigned int num_dapm_widgets;
111 const struct snd_soc_dapm_route *dapm_routes;
112 unsigned int num_dapm_routes;
113};
114
103#endif 115#endif
104 116
diff --git a/sound/soc/mediatek/mt2701/Makefile b/sound/soc/mediatek/mt2701/Makefile
index c91deb6aca21..21d5e697cfa7 100644
--- a/sound/soc/mediatek/mt2701/Makefile
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -1,16 +1,4 @@
1# 1# SPDX-License-Identifier: GPL-2.0
2# Copyright (C) 2015 MediaTek Inc.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13
14# platform driver 2# platform driver
15snd-soc-mt2701-afe-objs := mt2701-afe-pcm.o mt2701-afe-clock-ctrl.o 3snd-soc-mt2701-afe-objs := mt2701-afe-pcm.o mt2701-afe-clock-ctrl.o
16obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o 4obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
index 949fc3a1d025..ae620890bb3a 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -1,17 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl 3 * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 * 7 * Ryder Lee <ryder.lee@mediatek.com>
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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 8 */
16 9
17#include "mt2701-afe-common.h" 10#include "mt2701-afe-common.h"
@@ -43,8 +36,9 @@ int mt2701_init_clock(struct mtk_base_afe *afe)
43 } 36 }
44 37
45 /* Get I2S related clocks */ 38 /* Get I2S related clocks */
46 for (i = 0; i < MT2701_I2S_NUM; i++) { 39 for (i = 0; i < afe_priv->soc->i2s_num; i++) {
47 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i]; 40 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
41 struct clk *i2s_ck;
48 char name[13]; 42 char name[13];
49 43
50 snprintf(name, sizeof(name), "i2s%d_src_sel", i); 44 snprintf(name, sizeof(name), "i2s%d_src_sel", i);
@@ -69,18 +63,20 @@ int mt2701_init_clock(struct mtk_base_afe *afe)
69 } 63 }
70 64
71 snprintf(name, sizeof(name), "i2so%d_hop_ck", i); 65 snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
72 i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name); 66 i2s_ck = devm_clk_get(afe->dev, name);
73 if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) { 67 if (IS_ERR(i2s_ck)) {
74 dev_err(afe->dev, "failed to get %s\n", name); 68 dev_err(afe->dev, "failed to get %s\n", name);
75 return PTR_ERR(i2s_path->hop_ck[I2S_OUT]); 69 return PTR_ERR(i2s_ck);
76 } 70 }
71 i2s_path->hop_ck[SNDRV_PCM_STREAM_PLAYBACK] = i2s_ck;
77 72
78 snprintf(name, sizeof(name), "i2si%d_hop_ck", i); 73 snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
79 i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name); 74 i2s_ck = devm_clk_get(afe->dev, name);
80 if (IS_ERR(i2s_path->hop_ck[I2S_IN])) { 75 if (IS_ERR(i2s_ck)) {
81 dev_err(afe->dev, "failed to get %s\n", name); 76 dev_err(afe->dev, "failed to get %s\n", name);
82 return PTR_ERR(i2s_path->hop_ck[I2S_IN]); 77 return PTR_ERR(i2s_ck);
83 } 78 }
79 i2s_path->hop_ck[SNDRV_PCM_STREAM_CAPTURE] = i2s_ck;
84 80
85 snprintf(name, sizeof(name), "asrc%d_out_ck", i); 81 snprintf(name, sizeof(name), "asrc%d_out_ck", i);
86 i2s_path->asrco_ck = devm_clk_get(afe->dev, name); 82 i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
@@ -102,10 +98,10 @@ int mt2701_init_clock(struct mtk_base_afe *afe)
102 return 0; 98 return 0;
103} 99}
104 100
105int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir) 101int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
102 struct mt2701_i2s_path *i2s_path,
103 int dir)
106{ 104{
107 struct mt2701_afe_private *afe_priv = afe->platform_priv;
108 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
109 int ret; 105 int ret;
110 106
111 ret = clk_prepare_enable(i2s_path->asrco_ck); 107 ret = clk_prepare_enable(i2s_path->asrco_ck);
@@ -128,11 +124,10 @@ err_hop_ck:
128 return ret; 124 return ret;
129} 125}
130 126
131void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir) 127void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
128 struct mt2701_i2s_path *i2s_path,
129 int dir)
132{ 130{
133 struct mt2701_afe_private *afe_priv = afe->platform_priv;
134 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
135
136 clk_disable_unprepare(i2s_path->hop_ck[dir]); 131 clk_disable_unprepare(i2s_path->hop_ck[dir]);
137 clk_disable_unprepare(i2s_path->asrco_ck); 132 clk_disable_unprepare(i2s_path->asrco_ck);
138} 133}
@@ -272,27 +267,32 @@ int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
272 return 0; 267 return 0;
273} 268}
274 269
275void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, 270int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)
276 int mclk) 271
277{ 272{
278 struct mt2701_afe_private *priv = afe->platform_priv; 273 struct mt2701_afe_private *priv = afe->platform_priv;
279 struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id]; 274 struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
280 int ret; 275 int ret = -EINVAL;
281 276
282 /* Set mclk source */ 277 /* Set mclk source */
283 if (domain == 0) 278 if (!(MT2701_PLL_DOMAIN_0_RATE % i2s_path->mclk_rate))
284 ret = clk_set_parent(i2s_path->sel_ck, 279 ret = clk_set_parent(i2s_path->sel_ck,
285 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]); 280 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
286 else 281 else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
287 ret = clk_set_parent(i2s_path->sel_ck, 282 ret = clk_set_parent(i2s_path->sel_ck,
288 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]); 283 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
289 284
290 if (ret) 285 if (ret) {
291 dev_err(afe->dev, "failed to set domain%d mclk source %d\n", 286 dev_err(afe->dev, "failed to set mclk source\n");
292 domain, ret); 287 return ret;
288 }
293 289
294 /* Set mclk divider */ 290 /* Set mclk divider */
295 ret = clk_set_rate(i2s_path->div_ck, mclk); 291 ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
296 if (ret) 292 if (ret) {
297 dev_err(afe->dev, "failed to set mclk divider %d\n", ret); 293 dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
294 return ret;
295 }
296
297 return 0;
298} 298}
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
index 15417d9d6597..580fead2ab05 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
@@ -1,37 +1,34 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mt2701-afe-clock-ctrl.h -- Mediatek 2701 afe clock ctrl definition 3 * mt2701-afe-clock-ctrl.h -- Mediatek 2701 afe clock ctrl definition
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 * 7 * Ryder Lee <ryder.lee@mediatek.com>
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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 8 */
16 9
17#ifndef _MT2701_AFE_CLOCK_CTRL_H_ 10#ifndef _MT2701_AFE_CLOCK_CTRL_H_
18#define _MT2701_AFE_CLOCK_CTRL_H_ 11#define _MT2701_AFE_CLOCK_CTRL_H_
19 12
20struct mtk_base_afe; 13struct mtk_base_afe;
14struct mt2701_i2s_path;
21 15
22int mt2701_init_clock(struct mtk_base_afe *afe); 16int mt2701_init_clock(struct mtk_base_afe *afe);
23int mt2701_afe_enable_clock(struct mtk_base_afe *afe); 17int mt2701_afe_enable_clock(struct mtk_base_afe *afe);
24int mt2701_afe_disable_clock(struct mtk_base_afe *afe); 18int mt2701_afe_disable_clock(struct mtk_base_afe *afe);
25 19
26int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir); 20int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
27void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir); 21 struct mt2701_i2s_path *path,
22 int dir);
23void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
24 struct mt2701_i2s_path *path,
25 int dir);
28int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id); 26int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id);
29void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id); 27void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id);
30 28
31int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe); 29int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe);
32void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe); 30void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe);
33 31
34void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, 32int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id);
35 int mclk);
36 33
37#endif 34#endif
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
index ae8ddeacfbfe..d44faba27d3c 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h
@@ -1,17 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mt2701-afe-common.h -- Mediatek 2701 audio driver definitions 3 * mt2701-afe-common.h -- Mediatek 2701 audio driver definitions
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef _MT_2701_AFE_COMMON_H_ 9#ifndef _MT_2701_AFE_COMMON_H_
@@ -23,10 +15,8 @@
23#include "mt2701-reg.h" 15#include "mt2701-reg.h"
24#include "../common/mtk-base-afe.h" 16#include "../common/mtk-base-afe.h"
25 17
26#define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1)
27#define MT2701_PLL_DOMAIN_0_RATE 98304000 18#define MT2701_PLL_DOMAIN_0_RATE 98304000
28#define MT2701_PLL_DOMAIN_1_RATE 90316800 19#define MT2701_PLL_DOMAIN_1_RATE 90316800
29#define MT2701_I2S_NUM 4
30 20
31enum { 21enum {
32 MT2701_MEMIF_DL1, 22 MT2701_MEMIF_DL1,
@@ -100,30 +90,30 @@ struct mt2701_i2s_data {
100 int i2s_asrc_fs_mask; 90 int i2s_asrc_fs_mask;
101}; 91};
102 92
103enum mt2701_i2s_dir {
104 I2S_OUT,
105 I2S_IN,
106 I2S_DIR_NUM,
107};
108
109struct mt2701_i2s_path { 93struct mt2701_i2s_path {
110 int dai_id;
111 int mclk_rate; 94 int mclk_rate;
112 int on[I2S_DIR_NUM]; 95 int on[MTK_STREAM_NUM];
113 int occupied[I2S_DIR_NUM]; 96 int occupied[MTK_STREAM_NUM];
114 const struct mt2701_i2s_data *i2s_data[I2S_DIR_NUM]; 97 const struct mt2701_i2s_data *i2s_data[MTK_STREAM_NUM];
115 struct clk *hop_ck[I2S_DIR_NUM]; 98 struct clk *hop_ck[MTK_STREAM_NUM];
116 struct clk *sel_ck; 99 struct clk *sel_ck;
117 struct clk *div_ck; 100 struct clk *div_ck;
118 struct clk *mclk_ck; 101 struct clk *mclk_ck;
119 struct clk *asrco_ck; 102 struct clk *asrco_ck;
120}; 103};
121 104
105struct mt2701_soc_variants {
106 bool has_one_heart_mode;
107 int i2s_num;
108};
109
122struct mt2701_afe_private { 110struct mt2701_afe_private {
123 struct mt2701_i2s_path i2s_path[MT2701_I2S_NUM]; 111 struct mt2701_i2s_path *i2s_path;
124 struct clk *base_ck[MT2701_BASE_CLK_NUM]; 112 struct clk *base_ck[MT2701_BASE_CLK_NUM];
125 struct clk *mrgif_ck; 113 struct clk *mrgif_ck;
126 bool mrg_enable[MT2701_STREAM_DIR_NUM]; 114 bool mrg_enable[MTK_STREAM_NUM];
115
116 const struct mt2701_soc_variants *soc;
127}; 117};
128 118
129#endif 119#endif
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 73cce33fa439..828d11c30c6a 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -1,18 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Mediatek ALSA SoC AFE platform driver for 2701 3 * Mediatek ALSA SoC AFE platform driver for 2701
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6 * Ir Lian <ir.lian@mediatek.com> 7 * Ir Lian <ir.lian@mediatek.com>
7 * 8 * Ryder Lee <ryder.lee@mediatek.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 and
10 * only version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */ 9 */
17 10
18#include <linux/delay.h> 11#include <linux/delay.h>
@@ -20,6 +13,7 @@
20#include <linux/mfd/syscon.h> 13#include <linux/mfd/syscon.h>
21#include <linux/of.h> 14#include <linux/of.h>
22#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/of_device.h>
23#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
24 18
25#include "mt2701-afe-common.h" 19#include "mt2701-afe-common.h"
@@ -36,7 +30,7 @@ static const struct snd_pcm_hardware mt2701_afe_hardware = {
36 .period_bytes_max = 1024 * 256, 30 .period_bytes_max = 1024 * 256,
37 .periods_min = 4, 31 .periods_min = 4,
38 .periods_max = 1024, 32 .periods_max = 1024,
39 .buffer_bytes_max = 1024 * 1024 * 16, 33 .buffer_bytes_max = 1024 * 1024,
40 .fifo_size = 0, 34 .fifo_size = 0,
41}; 35};
42 36
@@ -68,9 +62,10 @@ static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
68 62
69static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) 63static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
70{ 64{
65 struct mt2701_afe_private *afe_priv = afe->platform_priv;
71 int val = num - MT2701_IO_I2S; 66 int val = num - MT2701_IO_I2S;
72 67
73 if (val < 0 || val >= MT2701_I2S_NUM) { 68 if (val < 0 || val >= afe_priv->soc->i2s_num) {
74 dev_err(afe->dev, "%s, num not available, num %d, val %d\n", 69 dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
75 __func__, num, val); 70 __func__, num, val);
76 return -EINVAL; 71 return -EINVAL;
@@ -92,44 +87,26 @@ static int mt2701_afe_i2s_fs(unsigned int sample_rate)
92static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream, 87static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
93 struct snd_soc_dai *dai) 88 struct snd_soc_dai *dai)
94{ 89{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 90 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
96 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 91 struct mt2701_afe_private *afe_priv = afe->platform_priv;
97 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
98 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 92 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
93 bool mode = afe_priv->soc->has_one_heart_mode;
99 94
100 if (i2s_num < 0) 95 if (i2s_num < 0)
101 return i2s_num; 96 return i2s_num;
102 97
103 return mt2701_afe_enable_mclk(afe, i2s_num); 98 return mt2701_afe_enable_mclk(afe, mode ? 1 : i2s_num);
104} 99}
105 100
106static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream, 101static int mt2701_afe_i2s_path_disable(struct mtk_base_afe *afe,
107 struct snd_soc_dai *dai, 102 struct mt2701_i2s_path *i2s_path,
108 int i2s_num, 103 int stream_dir)
109 int dir_invert)
110{ 104{
111 struct snd_soc_pcm_runtime *rtd = substream->private_data; 105 const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
112 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
113 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
114 struct mt2701_afe_private *afe_priv = afe->platform_priv;
115 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
116 const struct mt2701_i2s_data *i2s_data;
117 int stream_dir = substream->stream;
118
119 if (dir_invert) {
120 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
121 stream_dir = SNDRV_PCM_STREAM_CAPTURE;
122 else
123 stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
124 }
125 i2s_data = i2s_path->i2s_data[stream_dir];
126 106
127 i2s_path->on[stream_dir]--; 107 if (--i2s_path->on[stream_dir] < 0)
128 if (i2s_path->on[stream_dir] < 0) {
129 dev_warn(afe->dev, "i2s_path->on: %d, dir: %d\n",
130 i2s_path->on[stream_dir], stream_dir);
131 i2s_path->on[stream_dir] = 0; 108 i2s_path->on[stream_dir] = 0;
132 } 109
133 if (i2s_path->on[stream_dir]) 110 if (i2s_path->on[stream_dir])
134 return 0; 111 return 0;
135 112
@@ -137,7 +114,7 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
137 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 114 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
138 ASYS_I2S_CON_I2S_EN, 0); 115 ASYS_I2S_CON_I2S_EN, 0);
139 116
140 mt2701_afe_disable_i2s(afe, i2s_num, stream_dir); 117 mt2701_afe_disable_i2s(afe, i2s_path, stream_dir);
141 118
142 return 0; 119 return 0;
143} 120}
@@ -145,12 +122,11 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
145static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream, 122static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
146 struct snd_soc_dai *dai) 123 struct snd_soc_dai *dai)
147{ 124{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 125 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
149 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
150 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
151 struct mt2701_afe_private *afe_priv = afe->platform_priv; 126 struct mt2701_afe_private *afe_priv = afe->platform_priv;
152 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 127 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
153 struct mt2701_i2s_path *i2s_path; 128 struct mt2701_i2s_path *i2s_path;
129 bool mode = afe_priv->soc->has_one_heart_mode;
154 130
155 if (i2s_num < 0) 131 if (i2s_num < 0)
156 return; 132 return;
@@ -160,50 +136,33 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
160 if (i2s_path->occupied[substream->stream]) 136 if (i2s_path->occupied[substream->stream])
161 i2s_path->occupied[substream->stream] = 0; 137 i2s_path->occupied[substream->stream] = 0;
162 else 138 else
163 goto I2S_UNSTART; 139 goto exit;
164 140
165 mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 0); 141 mt2701_afe_i2s_path_disable(afe, i2s_path, substream->stream);
166 142
167 /* need to disable i2s-out path when disable i2s-in */ 143 /* need to disable i2s-out path when disable i2s-in */
168 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 144 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
169 mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 1); 145 mt2701_afe_i2s_path_disable(afe, i2s_path, !substream->stream);
170 146
171I2S_UNSTART: 147exit:
172 /* disable mclk */ 148 /* disable mclk */
173 mt2701_afe_disable_mclk(afe, i2s_num); 149 mt2701_afe_disable_mclk(afe, mode ? 1 : i2s_num);
174} 150}
175 151
176static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream, 152static int mt2701_i2s_path_enable(struct mtk_base_afe *afe,
177 struct snd_soc_dai *dai, 153 struct mt2701_i2s_path *i2s_path,
178 int i2s_num, 154 int stream_dir, int rate)
179 int dir_invert)
180{ 155{
181 struct snd_soc_pcm_runtime *rtd = substream->private_data; 156 const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
182 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
183 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
184 struct mt2701_afe_private *afe_priv = afe->platform_priv; 157 struct mt2701_afe_private *afe_priv = afe->platform_priv;
185 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
186 const struct mt2701_i2s_data *i2s_data;
187 struct snd_pcm_runtime * const runtime = substream->runtime;
188 int reg, fs, w_len = 1; /* now we support bck 64bits only */ 158 int reg, fs, w_len = 1; /* now we support bck 64bits only */
189 int stream_dir = substream->stream; 159 unsigned int mask, val;
190 unsigned int mask = 0, val = 0;
191
192 if (dir_invert) {
193 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
194 stream_dir = SNDRV_PCM_STREAM_CAPTURE;
195 else
196 stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
197 }
198 i2s_data = i2s_path->i2s_data[stream_dir];
199 160
200 /* no need to enable if already done */ 161 /* no need to enable if already done */
201 i2s_path->on[stream_dir]++; 162 if (++i2s_path->on[stream_dir] != 1)
202
203 if (i2s_path->on[stream_dir] != 1)
204 return 0; 163 return 0;
205 164
206 fs = mt2701_afe_i2s_fs(runtime->rate); 165 fs = mt2701_afe_i2s_fs(rate);
207 166
208 mask = ASYS_I2S_CON_FS | 167 mask = ASYS_I2S_CON_FS |
209 ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */ 168 ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */
@@ -217,22 +176,24 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
217 if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) { 176 if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {
218 mask |= ASYS_I2S_IN_PHASE_FIX; 177 mask |= ASYS_I2S_IN_PHASE_FIX;
219 val |= ASYS_I2S_IN_PHASE_FIX; 178 val |= ASYS_I2S_IN_PHASE_FIX;
179 reg = ASMI_TIMING_CON1;
180 } else {
181 if (afe_priv->soc->has_one_heart_mode) {
182 mask |= ASYS_I2S_CON_ONE_HEART_MODE;
183 val |= ASYS_I2S_CON_ONE_HEART_MODE;
184 }
185 reg = ASMO_TIMING_CON1;
220 } 186 }
221 187
222 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val); 188 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);
223 189
224 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
225 reg = ASMO_TIMING_CON1;
226 else
227 reg = ASMI_TIMING_CON1;
228
229 regmap_update_bits(afe->regmap, reg, 190 regmap_update_bits(afe->regmap, reg,
230 i2s_data->i2s_asrc_fs_mask 191 i2s_data->i2s_asrc_fs_mask
231 << i2s_data->i2s_asrc_fs_shift, 192 << i2s_data->i2s_asrc_fs_shift,
232 fs << i2s_data->i2s_asrc_fs_shift); 193 fs << i2s_data->i2s_asrc_fs_shift);
233 194
234 /* enable i2s */ 195 /* enable i2s */
235 mt2701_afe_enable_i2s(afe, i2s_num, stream_dir); 196 mt2701_afe_enable_i2s(afe, i2s_path, stream_dir);
236 197
237 /* reset i2s hw status before enable */ 198 /* reset i2s hw status before enable */
238 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 199 regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
@@ -249,45 +210,33 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
249static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream, 210static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
250 struct snd_soc_dai *dai) 211 struct snd_soc_dai *dai)
251{ 212{
252 int clk_domain; 213 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
253 struct snd_soc_pcm_runtime *rtd = substream->private_data;
254 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
255 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
256 struct mt2701_afe_private *afe_priv = afe->platform_priv; 214 struct mt2701_afe_private *afe_priv = afe->platform_priv;
257 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 215 int ret, i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
258 struct mt2701_i2s_path *i2s_path; 216 struct mt2701_i2s_path *i2s_path;
259 int mclk_rate; 217 bool mode = afe_priv->soc->has_one_heart_mode;
260 218
261 if (i2s_num < 0) 219 if (i2s_num < 0)
262 return i2s_num; 220 return i2s_num;
263 221
264 i2s_path = &afe_priv->i2s_path[i2s_num]; 222 i2s_path = &afe_priv->i2s_path[i2s_num];
265 mclk_rate = i2s_path->mclk_rate;
266 223
267 if (i2s_path->occupied[substream->stream]) 224 if (i2s_path->occupied[substream->stream])
268 return -EBUSY; 225 return -EBUSY;
226
227 ret = mt2701_mclk_configuration(afe, mode ? 1 : i2s_num);
228 if (ret)
229 return ret;
230
269 i2s_path->occupied[substream->stream] = 1; 231 i2s_path->occupied[substream->stream] = 1;
270 232
271 if (MT2701_PLL_DOMAIN_0_RATE % mclk_rate == 0) { 233 /* need to enable i2s-out path when enable i2s-in */
272 clk_domain = 0; 234 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
273 } else if (MT2701_PLL_DOMAIN_1_RATE % mclk_rate == 0) { 235 mt2701_i2s_path_enable(afe, i2s_path, !substream->stream,
274 clk_domain = 1; 236 substream->runtime->rate);
275 } else {
276 dev_err(dai->dev, "%s() bad mclk rate %d\n",
277 __func__, mclk_rate);
278 return -EINVAL;
279 }
280 mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate);
281 237
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 238 mt2701_i2s_path_enable(afe, i2s_path, substream->stream,
283 mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0); 239 substream->runtime->rate);
284 } else {
285 /* need to enable i2s-out path when enable i2s-in */
286 /* prepare for another direction "out" */
287 mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 1);
288 /* prepare for "in" */
289 mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0);
290 }
291 240
292 return 0; 241 return 0;
293} 242}
@@ -295,30 +244,29 @@ static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
295static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 244static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
296 unsigned int freq, int dir) 245 unsigned int freq, int dir)
297{ 246{
298 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 247 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
299 struct mt2701_afe_private *afe_priv = afe->platform_priv; 248 struct mt2701_afe_private *afe_priv = afe->platform_priv;
300 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 249 int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
250 bool mode = afe_priv->soc->has_one_heart_mode;
301 251
302 if (i2s_num < 0) 252 if (i2s_num < 0)
303 return i2s_num; 253 return i2s_num;
304 254
305 /* mclk */ 255 /* mclk */
306 if (dir == SND_SOC_CLOCK_IN) { 256 if (dir == SND_SOC_CLOCK_IN) {
307 dev_warn(dai->dev, 257 dev_warn(dai->dev, "The SoCs doesn't support mclk input\n");
308 "%s() warning: mt2701 doesn't support mclk input\n",
309 __func__);
310 return -EINVAL; 258 return -EINVAL;
311 } 259 }
312 afe_priv->i2s_path[i2s_num].mclk_rate = freq; 260
261 afe_priv->i2s_path[mode ? 1 : i2s_num].mclk_rate = freq;
262
313 return 0; 263 return 0;
314} 264}
315 265
316static int mt2701_btmrg_startup(struct snd_pcm_substream *substream, 266static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
317 struct snd_soc_dai *dai) 267 struct snd_soc_dai *dai)
318{ 268{
319 struct snd_soc_pcm_runtime *rtd = substream->private_data; 269 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
320 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
321 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
322 struct mt2701_afe_private *afe_priv = afe->platform_priv; 270 struct mt2701_afe_private *afe_priv = afe->platform_priv;
323 int ret; 271 int ret;
324 272
@@ -327,6 +275,7 @@ static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
327 return ret; 275 return ret;
328 276
329 afe_priv->mrg_enable[substream->stream] = 1; 277 afe_priv->mrg_enable[substream->stream] = 1;
278
330 return 0; 279 return 0;
331} 280}
332 281
@@ -334,17 +283,14 @@ static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
334 struct snd_pcm_hw_params *params, 283 struct snd_pcm_hw_params *params,
335 struct snd_soc_dai *dai) 284 struct snd_soc_dai *dai)
336{ 285{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data; 286 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
338 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
339 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
340 int stream_fs; 287 int stream_fs;
341 u32 val, msk; 288 u32 val, msk;
342 289
343 stream_fs = params_rate(params); 290 stream_fs = params_rate(params);
344 291
345 if ((stream_fs != 8000) && (stream_fs != 16000)) { 292 if (stream_fs != 8000 && stream_fs != 16000) {
346 dev_err(afe->dev, "%s() btmgr not support this stream_fs %d\n", 293 dev_err(afe->dev, "unsupported rate %d\n", stream_fs);
347 __func__, stream_fs);
348 return -EINVAL; 294 return -EINVAL;
349 } 295 }
350 296
@@ -378,9 +324,7 @@ static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
378static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream, 324static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
379 struct snd_soc_dai *dai) 325 struct snd_soc_dai *dai)
380{ 326{
381 struct snd_soc_pcm_runtime *rtd = substream->private_data; 327 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
382 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
383 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
384 struct mt2701_afe_private *afe_priv = afe->platform_priv; 328 struct mt2701_afe_private *afe_priv = afe->platform_priv;
385 329
386 /* if the other direction stream is not occupied */ 330 /* if the other direction stream is not occupied */
@@ -393,28 +337,26 @@ static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
393 AFE_MRGIF_CON_MRG_I2S_EN, 0); 337 AFE_MRGIF_CON_MRG_I2S_EN, 0);
394 mt2701_disable_btmrg_clk(afe); 338 mt2701_disable_btmrg_clk(afe);
395 } 339 }
340
396 afe_priv->mrg_enable[substream->stream] = 0; 341 afe_priv->mrg_enable[substream->stream] = 0;
397} 342}
398 343
399static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream, 344static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
400 struct snd_soc_dai *dai) 345 struct snd_soc_dai *dai)
401{ 346{
402 struct snd_soc_pcm_runtime *rtd = substream->private_data; 347 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
403 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
404 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
405 int stream_dir = substream->stream;
406 int memif_num = rtd->cpu_dai->id;
407 struct mtk_base_afe_memif *memif_tmp; 348 struct mtk_base_afe_memif *memif_tmp;
349 int stream_dir = substream->stream;
408 350
409 /* can't run single DL & DLM at the same time */ 351 /* can't run single DL & DLM at the same time */
410 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) { 352 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
411 memif_tmp = &afe->memif[MT2701_MEMIF_DLM]; 353 memif_tmp = &afe->memif[MT2701_MEMIF_DLM];
412 if (memif_tmp->substream) { 354 if (memif_tmp->substream) {
413 dev_warn(afe->dev, "%s memif is not available, stream_dir %d, memif_num %d\n", 355 dev_warn(afe->dev, "memif is not available");
414 __func__, stream_dir, memif_num);
415 return -EBUSY; 356 return -EBUSY;
416 } 357 }
417 } 358 }
359
418 return mtk_afe_fe_startup(substream, dai); 360 return mtk_afe_fe_startup(substream, dai);
419} 361}
420 362
@@ -422,27 +364,23 @@ static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
422 struct snd_pcm_hw_params *params, 364 struct snd_pcm_hw_params *params,
423 struct snd_soc_dai *dai) 365 struct snd_soc_dai *dai)
424{ 366{
425 struct snd_soc_pcm_runtime *rtd = substream->private_data; 367 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
426 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
427 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
428 int stream_dir = substream->stream; 368 int stream_dir = substream->stream;
429 369
430 /* single DL use PAIR_INTERLEAVE */ 370 /* single DL use PAIR_INTERLEAVE */
431 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) { 371 if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
432 regmap_update_bits(afe->regmap, 372 regmap_update_bits(afe->regmap,
433 AFE_MEMIF_PBUF_SIZE, 373 AFE_MEMIF_PBUF_SIZE,
434 AFE_MEMIF_PBUF_SIZE_DLM_MASK, 374 AFE_MEMIF_PBUF_SIZE_DLM_MASK,
435 AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE); 375 AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);
436 } 376
437 return mtk_afe_fe_hw_params(substream, params, dai); 377 return mtk_afe_fe_hw_params(substream, params, dai);
438} 378}
439 379
440static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream, 380static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
441 struct snd_soc_dai *dai) 381 struct snd_soc_dai *dai)
442{ 382{
443 struct snd_soc_pcm_runtime *rtd = substream->private_data; 383 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
444 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
445 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
446 struct mtk_base_afe_memif *memif_tmp; 384 struct mtk_base_afe_memif *memif_tmp;
447 const struct mtk_base_memif_data *memif_data; 385 const struct mtk_base_memif_data *memif_data;
448 int i; 386 int i;
@@ -468,9 +406,7 @@ static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
468static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream, 406static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
469 struct snd_soc_dai *dai) 407 struct snd_soc_dai *dai)
470{ 408{
471 struct snd_soc_pcm_runtime *rtd = substream->private_data; 409 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
472 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
473 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
474 const struct mtk_base_memif_data *memif_data; 410 const struct mtk_base_memif_data *memif_data;
475 int i; 411 int i;
476 412
@@ -481,6 +417,7 @@ static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
481 1 << memif_data->agent_disable_shift, 417 1 << memif_data->agent_disable_shift,
482 1 << memif_data->agent_disable_shift); 418 1 << memif_data->agent_disable_shift);
483 } 419 }
420
484 return mtk_afe_fe_shutdown(substream, dai); 421 return mtk_afe_fe_shutdown(substream, dai);
485} 422}
486 423
@@ -488,9 +425,7 @@ static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
488 struct snd_pcm_hw_params *params, 425 struct snd_pcm_hw_params *params,
489 struct snd_soc_dai *dai) 426 struct snd_soc_dai *dai)
490{ 427{
491 struct snd_soc_pcm_runtime *rtd = substream->private_data; 428 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
492 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
493 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
494 int channels = params_channels(params); 429 int channels = params_channels(params);
495 430
496 regmap_update_bits(afe->regmap, 431 regmap_update_bits(afe->regmap,
@@ -512,9 +447,7 @@ static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
512static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream, 447static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
513 int cmd, struct snd_soc_dai *dai) 448 int cmd, struct snd_soc_dai *dai)
514{ 449{
515 struct snd_soc_pcm_runtime *rtd = substream->private_data; 450 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
516 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
517 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
518 struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1]; 451 struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
519 452
520 switch (cmd) { 453 switch (cmd) {
@@ -547,6 +480,7 @@ static int mt2701_memif_fs(struct snd_pcm_substream *substream,
547 fs = mt2701_afe_i2s_fs(rate); 480 fs = mt2701_afe_i2s_fs(rate);
548 else 481 else
549 fs = (rate == 16000 ? 1 : 0); 482 fs = (rate == 16000 ? 1 : 0);
483
550 return fs; 484 return fs;
551} 485}
552 486
@@ -1024,7 +958,17 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
1024 { "O31", "I35 Switch", "I35" }, 958 { "O31", "I35 Switch", "I35" },
1025}; 959};
1026 960
961static int mt2701_afe_pcm_probe(struct snd_soc_component *component)
962{
963 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
964
965 snd_soc_component_init_regmap(component, afe->regmap);
966
967 return 0;
968}
969
1027static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = { 970static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
971 .probe = mt2701_afe_pcm_probe,
1028 .name = "mt2701-afe-pcm-dai", 972 .name = "mt2701-afe-pcm-dai",
1029 .dapm_widgets = mt2701_afe_pcm_widgets, 973 .dapm_widgets = mt2701_afe_pcm_widgets,
1030 .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets), 974 .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),
@@ -1324,63 +1268,24 @@ static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
1324 } 1268 }
1325}; 1269};
1326 1270
1327static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { 1271static const struct mt2701_i2s_data mt2701_i2s_data[][2] = {
1328 { 1272 {
1329 { 1273 { ASYS_I2SO1_CON, 0, 0x1f },
1330 .i2s_ctrl_reg = ASYS_I2SO1_CON, 1274 { ASYS_I2SIN1_CON, 0, 0x1f },
1331 .i2s_asrc_fs_shift = 0,
1332 .i2s_asrc_fs_mask = 0x1f,
1333
1334 },
1335 {
1336 .i2s_ctrl_reg = ASYS_I2SIN1_CON,
1337 .i2s_asrc_fs_shift = 0,
1338 .i2s_asrc_fs_mask = 0x1f,
1339
1340 },
1341 }, 1275 },
1342 { 1276 {
1343 { 1277 { ASYS_I2SO2_CON, 5, 0x1f },
1344 .i2s_ctrl_reg = ASYS_I2SO2_CON, 1278 { ASYS_I2SIN2_CON, 5, 0x1f },
1345 .i2s_asrc_fs_shift = 5,
1346 .i2s_asrc_fs_mask = 0x1f,
1347
1348 },
1349 {
1350 .i2s_ctrl_reg = ASYS_I2SIN2_CON,
1351 .i2s_asrc_fs_shift = 5,
1352 .i2s_asrc_fs_mask = 0x1f,
1353
1354 },
1355 }, 1279 },
1356 { 1280 {
1357 { 1281 { ASYS_I2SO3_CON, 10, 0x1f },
1358 .i2s_ctrl_reg = ASYS_I2SO3_CON, 1282 { ASYS_I2SIN3_CON, 10, 0x1f },
1359 .i2s_asrc_fs_shift = 10,
1360 .i2s_asrc_fs_mask = 0x1f,
1361
1362 },
1363 {
1364 .i2s_ctrl_reg = ASYS_I2SIN3_CON,
1365 .i2s_asrc_fs_shift = 10,
1366 .i2s_asrc_fs_mask = 0x1f,
1367
1368 },
1369 }, 1283 },
1370 { 1284 {
1371 { 1285 { ASYS_I2SO4_CON, 15, 0x1f },
1372 .i2s_ctrl_reg = ASYS_I2SO4_CON, 1286 { ASYS_I2SIN4_CON, 15, 0x1f },
1373 .i2s_asrc_fs_shift = 15,
1374 .i2s_asrc_fs_mask = 0x1f,
1375
1376 },
1377 {
1378 .i2s_ctrl_reg = ASYS_I2SIN4_CON,
1379 .i2s_asrc_fs_shift = 15,
1380 .i2s_asrc_fs_mask = 0x1f,
1381
1382 },
1383 }, 1287 },
1288 /* TODO - extend control registers supported by newer SoCs */
1384}; 1289};
1385 1290
1386static irqreturn_t mt2701_asys_isr(int irq_id, void *dev) 1291static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
@@ -1398,10 +1303,12 @@ static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
1398 memif = &afe->memif[id]; 1303 memif = &afe->memif[id];
1399 if (memif->irq_usage < 0) 1304 if (memif->irq_usage < 0)
1400 continue; 1305 continue;
1306
1401 irq = &afe->irqs[memif->irq_usage]; 1307 irq = &afe->irqs[memif->irq_usage];
1402 if (status & 1 << (irq->irq_data->irq_clr_shift)) 1308 if (status & 1 << irq->irq_data->irq_clr_shift)
1403 snd_pcm_period_elapsed(memif->substream); 1309 snd_pcm_period_elapsed(memif->substream);
1404 } 1310 }
1311
1405 return IRQ_HANDLED; 1312 return IRQ_HANDLED;
1406} 1313}
1407 1314
@@ -1419,22 +1326,6 @@ static int mt2701_afe_runtime_resume(struct device *dev)
1419 return mt2701_afe_enable_clock(afe); 1326 return mt2701_afe_enable_clock(afe);
1420} 1327}
1421 1328
1422static int mt2701_afe_add_component(struct mtk_base_afe *afe)
1423{
1424 struct snd_soc_component *component;
1425
1426 component = kzalloc(sizeof(*component), GFP_KERNEL);
1427 if (!component)
1428 return -ENOMEM;
1429
1430 component->regmap = afe->regmap;
1431
1432 return snd_soc_add_component(afe->dev, component,
1433 &mt2701_afe_pcm_dai_component,
1434 mt2701_afe_pcm_dais,
1435 ARRAY_SIZE(mt2701_afe_pcm_dais));
1436}
1437
1438static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) 1329static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1439{ 1330{
1440 struct mtk_base_afe *afe; 1331 struct mtk_base_afe *afe;
@@ -1452,9 +1343,16 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1452 return -ENOMEM; 1343 return -ENOMEM;
1453 1344
1454 afe_priv = afe->platform_priv; 1345 afe_priv = afe->platform_priv;
1346 afe_priv->soc = of_device_get_match_data(&pdev->dev);
1455 afe->dev = &pdev->dev; 1347 afe->dev = &pdev->dev;
1456 dev = afe->dev; 1348 dev = afe->dev;
1457 1349
1350 afe_priv->i2s_path = devm_kzalloc(dev, afe_priv->soc->i2s_num *
1351 sizeof(struct mt2701_i2s_path),
1352 GFP_KERNEL);
1353 if (!afe_priv->i2s_path)
1354 return -ENOMEM;
1355
1458 irq_id = platform_get_irq_byname(pdev, "asys"); 1356 irq_id = platform_get_irq_byname(pdev, "asys");
1459 if (irq_id < 0) { 1357 if (irq_id < 0) {
1460 dev_err(dev, "unable to get ASYS IRQ\n"); 1358 dev_err(dev, "unable to get ASYS IRQ\n");
@@ -1499,11 +1397,11 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1499 afe->irqs[i].irq_data = &irq_data[i]; 1397 afe->irqs[i].irq_data = &irq_data[i];
1500 1398
1501 /* I2S initialize */ 1399 /* I2S initialize */
1502 for (i = 0; i < MT2701_I2S_NUM; i++) { 1400 for (i = 0; i < afe_priv->soc->i2s_num; i++) {
1503 afe_priv->i2s_path[i].i2s_data[I2S_OUT] 1401 afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_PLAYBACK] =
1504 = &mt2701_i2s_data[i][I2S_OUT]; 1402 &mt2701_i2s_data[i][SNDRV_PCM_STREAM_PLAYBACK];
1505 afe_priv->i2s_path[i].i2s_data[I2S_IN] 1403 afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_CAPTURE] =
1506 = &mt2701_i2s_data[i][I2S_IN]; 1404 &mt2701_i2s_data[i][SNDRV_PCM_STREAM_CAPTURE];
1507 } 1405 }
1508 1406
1509 afe->mtk_afe_hardware = &mt2701_afe_hardware; 1407 afe->mtk_afe_hardware = &mt2701_afe_hardware;
@@ -1538,7 +1436,10 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1538 goto err_platform; 1436 goto err_platform;
1539 } 1437 }
1540 1438
1541 ret = mt2701_afe_add_component(afe); 1439 ret = devm_snd_soc_register_component(&pdev->dev,
1440 &mt2701_afe_pcm_dai_component,
1441 mt2701_afe_pcm_dais,
1442 ARRAY_SIZE(mt2701_afe_pcm_dais));
1542 if (ret) { 1443 if (ret) {
1543 dev_warn(dev, "err_dai_component\n"); 1444 dev_warn(dev, "err_dai_component\n");
1544 goto err_platform; 1445 goto err_platform;
@@ -1564,8 +1465,18 @@ static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
1564 return 0; 1465 return 0;
1565} 1466}
1566 1467
1468static const struct mt2701_soc_variants mt2701_soc_v1 = {
1469 .i2s_num = 4,
1470};
1471
1472static const struct mt2701_soc_variants mt2701_soc_v2 = {
1473 .has_one_heart_mode = true,
1474 .i2s_num = 4,
1475};
1476
1567static const struct of_device_id mt2701_afe_pcm_dt_match[] = { 1477static const struct of_device_id mt2701_afe_pcm_dt_match[] = {
1568 { .compatible = "mediatek,mt2701-audio", }, 1478 { .compatible = "mediatek,mt2701-audio", .data = &mt2701_soc_v1 },
1479 { .compatible = "mediatek,mt7622-audio", .data = &mt2701_soc_v2 },
1569 {}, 1480 {},
1570}; 1481};
1571MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match); 1482MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
index 70f61d53fe05..666282b865a8 100644
--- a/sound/soc/mediatek/mt2701/mt2701-cs42448.c
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -1,19 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt2701-cs42448.c -- MT2701 CS42448 ALSA SoC machine driver 3 * mt2701-cs42448.c -- MT2701 CS42448 ALSA SoC machine driver
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Ir Lian <ir.lian@mediatek.com> 6 * Author: Ir Lian <ir.lian@mediatek.com>
6 * Garlic Tseng <garlic.tseng@mediatek.com> 7 * Garlic Tseng <garlic.tseng@mediatek.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 and
11 * only version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */ 8 */
18 9
19#include <linux/module.h> 10#include <linux/module.h>
diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h
index 18e676974f22..c84d14cdd7ae 100644
--- a/sound/soc/mediatek/mt2701/mt2701-reg.h
+++ b/sound/soc/mediatek/mt2701/mt2701-reg.h
@@ -1,17 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mt2701-reg.h -- Mediatek 2701 audio driver reg definition 3 * mt2701-reg.h -- Mediatek 2701 audio driver reg definition
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com> 6 * Author: Garlic Tseng <garlic.tseng@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#ifndef _MT2701_REG_H_ 9#ifndef _MT2701_REG_H_
@@ -138,6 +130,7 @@
138#define ASYS_I2S_CON_FS_SET(x) ((x) << 8) 130#define ASYS_I2S_CON_FS_SET(x) ((x) << 8)
139#define ASYS_I2S_CON_RESET (0x1 << 30) 131#define ASYS_I2S_CON_RESET (0x1 << 30)
140#define ASYS_I2S_CON_I2S_EN (0x1 << 0) 132#define ASYS_I2S_CON_I2S_EN (0x1 << 0)
133#define ASYS_I2S_CON_ONE_HEART_MODE (0x1 << 16)
141#define ASYS_I2S_CON_I2S_COUPLE_MODE (0x1 << 17) 134#define ASYS_I2S_CON_I2S_COUPLE_MODE (0x1 << 17)
142/* 0:EIAJ 1:I2S */ 135/* 0:EIAJ 1:I2S */
143#define ASYS_I2S_CON_I2S_MODE (0x1 << 3) 136#define ASYS_I2S_CON_I2S_MODE (0x1 << 3)
diff --git a/sound/soc/mediatek/mt2701/mt2701-wm8960.c b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
index a08ce2323bdc..89f34efd9747 100644
--- a/sound/soc/mediatek/mt2701/mt2701-wm8960.c
+++ b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt2701-wm8960.c -- MT2701 WM8960 ALSA SoC machine driver 3 * mt2701-wm8960.c -- MT2701 WM8960 ALSA SoC machine driver
3 * 4 *
4 * Copyright (c) 2017 MediaTek Inc. 5 * Copyright (c) 2017 MediaTek Inc.
5 * Author: Ryder Lee <ryder.lee@mediatek.com> 6 * Author: Ryder Lee <ryder.lee@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
diff --git a/sound/soc/mediatek/mt6797/Makefile b/sound/soc/mediatek/mt6797/Makefile
new file mode 100644
index 000000000000..bf6e179ea93f
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/Makefile
@@ -0,0 +1,14 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# platform driver
4snd-soc-mt6797-afe-objs := \
5 mt6797-afe-pcm.o \
6 mt6797-afe-clk.o \
7 mt6797-dai-pcm.o \
8 mt6797-dai-hostless.o \
9 mt6797-dai-adda.o
10
11obj-$(CONFIG_SND_SOC_MT6797) += snd-soc-mt6797-afe.o
12
13# machine driver
14obj-$(CONFIG_SND_SOC_MT6797_MT6351) += mt6797-mt6351.o
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-clk.c b/sound/soc/mediatek/mt6797/mt6797-afe-clk.c
new file mode 100644
index 000000000000..6f3e6acfcfab
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-clk.c
@@ -0,0 +1,123 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// mt6797-afe-clk.c -- Mediatek 6797 afe clock ctrl
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/clk.h>
9
10#include "mt6797-afe-common.h"
11#include "mt6797-afe-clk.h"
12
13enum {
14 CLK_INFRA_SYS_AUD,
15 CLK_INFRA_SYS_AUD_26M,
16 CLK_TOP_MUX_AUD,
17 CLK_TOP_MUX_AUD_BUS,
18 CLK_TOP_SYSPLL3_D4,
19 CLK_TOP_SYSPLL1_D4,
20 CLK_CLK26M,
21 CLK_NUM
22};
23
24static const char *aud_clks[CLK_NUM] = {
25 [CLK_INFRA_SYS_AUD] = "infra_sys_audio_clk",
26 [CLK_INFRA_SYS_AUD_26M] = "infra_sys_audio_26m",
27 [CLK_TOP_MUX_AUD] = "top_mux_audio",
28 [CLK_TOP_MUX_AUD_BUS] = "top_mux_aud_intbus",
29 [CLK_TOP_SYSPLL3_D4] = "top_sys_pll3_d4",
30 [CLK_TOP_SYSPLL1_D4] = "top_sys_pll1_d4",
31 [CLK_CLK26M] = "top_clk26m_clk",
32};
33
34int mt6797_init_clock(struct mtk_base_afe *afe)
35{
36 struct mt6797_afe_private *afe_priv = afe->platform_priv;
37 int i;
38
39 afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
40 GFP_KERNEL);
41 if (!afe_priv->clk)
42 return -ENOMEM;
43
44 for (i = 0; i < CLK_NUM; i++) {
45 afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
46 if (IS_ERR(afe_priv->clk[i])) {
47 dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
48 __func__, aud_clks[i],
49 PTR_ERR(afe_priv->clk[i]));
50 return PTR_ERR(afe_priv->clk[i]);
51 }
52 }
53
54 return 0;
55}
56
57int mt6797_afe_enable_clock(struct mtk_base_afe *afe)
58{
59 struct mt6797_afe_private *afe_priv = afe->platform_priv;
60 int ret;
61
62 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD]);
63 if (ret) {
64 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
65 __func__, aud_clks[CLK_INFRA_SYS_AUD], ret);
66 goto CLK_INFRA_SYS_AUDIO_ERR;
67 }
68
69 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
70 if (ret) {
71 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
72 __func__, aud_clks[CLK_INFRA_SYS_AUD_26M], ret);
73 goto CLK_INFRA_SYS_AUD_26M_ERR;
74 }
75
76 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD]);
77 if (ret) {
78 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
79 __func__, aud_clks[CLK_TOP_MUX_AUD], ret);
80 goto CLK_MUX_AUDIO_ERR;
81 }
82
83 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD],
84 afe_priv->clk[CLK_CLK26M]);
85 if (ret) {
86 dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
87 __func__, aud_clks[CLK_TOP_MUX_AUD],
88 aud_clks[CLK_CLK26M], ret);
89 goto CLK_MUX_AUDIO_ERR;
90 }
91
92 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
93 if (ret) {
94 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
95 __func__, aud_clks[CLK_TOP_MUX_AUD_BUS], ret);
96 goto CLK_MUX_AUDIO_INTBUS_ERR;
97 }
98
99 return ret;
100
101CLK_MUX_AUDIO_INTBUS_ERR:
102 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
103CLK_MUX_AUDIO_ERR:
104 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
105CLK_INFRA_SYS_AUD_26M_ERR:
106 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
107CLK_INFRA_SYS_AUDIO_ERR:
108 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
109
110 return 0;
111}
112
113int mt6797_afe_disable_clock(struct mtk_base_afe *afe)
114{
115 struct mt6797_afe_private *afe_priv = afe->platform_priv;
116
117 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
118 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
119 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
120 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
121
122 return 0;
123}
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-clk.h b/sound/soc/mediatek/mt6797/mt6797-afe-clk.h
new file mode 100644
index 000000000000..a6f0cb572711
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-clk.h
@@ -0,0 +1,17 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * mt6797-afe-clk.h -- Mediatek 6797 afe clock ctrl definition
4 *
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7 */
8
9#ifndef _MT6797_AFE_CLK_H_
10#define _MT6797_AFE_CLK_H_
11
12struct mtk_base_afe;
13
14int mt6797_init_clock(struct mtk_base_afe *afe);
15int mt6797_afe_enable_clock(struct mtk_base_afe *afe);
16int mt6797_afe_disable_clock(struct mtk_base_afe *afe);
17#endif
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-common.h b/sound/soc/mediatek/mt6797/mt6797-afe-common.h
new file mode 100644
index 000000000000..22eb7b455cf1
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-common.h
@@ -0,0 +1,58 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * mt6797-afe-common.h -- Mediatek 6797 audio driver definitions
4 *
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7 */
8
9#ifndef _MT_6797_AFE_COMMON_H_
10#define _MT_6797_AFE_COMMON_H_
11
12#include <sound/soc.h>
13#include <linux/regmap.h>
14#include "../common/mtk-base-afe.h"
15
16enum {
17 MT6797_MEMIF_DL1,
18 MT6797_MEMIF_DL2,
19 MT6797_MEMIF_DL3,
20 MT6797_MEMIF_VUL,
21 MT6797_MEMIF_AWB,
22 MT6797_MEMIF_VUL12,
23 MT6797_MEMIF_DAI,
24 MT6797_MEMIF_MOD_DAI,
25 MT6797_MEMIF_NUM,
26 MT6797_DAI_ADDA = MT6797_MEMIF_NUM,
27 MT6797_DAI_PCM_1,
28 MT6797_DAI_PCM_2,
29 MT6797_DAI_HOSTLESS_LPBK,
30 MT6797_DAI_HOSTLESS_SPEECH,
31 MT6797_DAI_NUM,
32};
33
34enum {
35 MT6797_IRQ_1,
36 MT6797_IRQ_2,
37 MT6797_IRQ_3,
38 MT6797_IRQ_4,
39 MT6797_IRQ_7,
40 MT6797_IRQ_NUM,
41};
42
43struct clk;
44
45struct mt6797_afe_private {
46 struct clk **clk;
47};
48
49unsigned int mt6797_general_rate_transform(struct device *dev,
50 unsigned int rate);
51unsigned int mt6797_rate_transform(struct device *dev,
52 unsigned int rate, int aud_blk);
53
54/* dai register */
55int mt6797_dai_adda_register(struct mtk_base_afe *afe);
56int mt6797_dai_pcm_register(struct mtk_base_afe *afe);
57int mt6797_dai_hostless_register(struct mtk_base_afe *afe);
58#endif
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
new file mode 100644
index 000000000000..6c5dd9fc9976
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
@@ -0,0 +1,914 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Mediatek ALSA SoC AFE platform driver for 6797
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/delay.h>
9#include <linux/module.h>
10#include <linux/mfd/syscon.h>
11#include <linux/of.h>
12#include <linux/of_address.h>
13#include <linux/pm_runtime.h>
14
15#include "mt6797-afe-common.h"
16#include "mt6797-afe-clk.h"
17#include "mt6797-interconnection.h"
18#include "mt6797-reg.h"
19#include "../common/mtk-afe-platform-driver.h"
20#include "../common/mtk-afe-fe-dai.h"
21
22enum {
23 MTK_AFE_RATE_8K = 0,
24 MTK_AFE_RATE_11K = 1,
25 MTK_AFE_RATE_12K = 2,
26 MTK_AFE_RATE_384K = 3,
27 MTK_AFE_RATE_16K = 4,
28 MTK_AFE_RATE_22K = 5,
29 MTK_AFE_RATE_24K = 6,
30 MTK_AFE_RATE_130K = 7,
31 MTK_AFE_RATE_32K = 8,
32 MTK_AFE_RATE_44K = 9,
33 MTK_AFE_RATE_48K = 10,
34 MTK_AFE_RATE_88K = 11,
35 MTK_AFE_RATE_96K = 12,
36 MTK_AFE_RATE_174K = 13,
37 MTK_AFE_RATE_192K = 14,
38 MTK_AFE_RATE_260K = 15,
39};
40
41enum {
42 MTK_AFE_DAI_MEMIF_RATE_8K = 0,
43 MTK_AFE_DAI_MEMIF_RATE_16K = 1,
44 MTK_AFE_DAI_MEMIF_RATE_32K = 2,
45};
46
47enum {
48 MTK_AFE_PCM_RATE_8K = 0,
49 MTK_AFE_PCM_RATE_16K = 1,
50 MTK_AFE_PCM_RATE_32K = 2,
51 MTK_AFE_PCM_RATE_48K = 3,
52};
53
54unsigned int mt6797_general_rate_transform(struct device *dev,
55 unsigned int rate)
56{
57 switch (rate) {
58 case 8000:
59 return MTK_AFE_RATE_8K;
60 case 11025:
61 return MTK_AFE_RATE_11K;
62 case 12000:
63 return MTK_AFE_RATE_12K;
64 case 16000:
65 return MTK_AFE_RATE_16K;
66 case 22050:
67 return MTK_AFE_RATE_22K;
68 case 24000:
69 return MTK_AFE_RATE_24K;
70 case 32000:
71 return MTK_AFE_RATE_32K;
72 case 44100:
73 return MTK_AFE_RATE_44K;
74 case 48000:
75 return MTK_AFE_RATE_48K;
76 case 88200:
77 return MTK_AFE_RATE_88K;
78 case 96000:
79 return MTK_AFE_RATE_96K;
80 case 130000:
81 return MTK_AFE_RATE_130K;
82 case 176400:
83 return MTK_AFE_RATE_174K;
84 case 192000:
85 return MTK_AFE_RATE_192K;
86 case 260000:
87 return MTK_AFE_RATE_260K;
88 default:
89 dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
90 __func__, rate, MTK_AFE_RATE_48K);
91 return MTK_AFE_RATE_48K;
92 }
93}
94
95static unsigned int dai_memif_rate_transform(struct device *dev,
96 unsigned int rate)
97{
98 switch (rate) {
99 case 8000:
100 return MTK_AFE_DAI_MEMIF_RATE_8K;
101 case 16000:
102 return MTK_AFE_DAI_MEMIF_RATE_16K;
103 case 32000:
104 return MTK_AFE_DAI_MEMIF_RATE_32K;
105 default:
106 dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
107 __func__, rate, MTK_AFE_DAI_MEMIF_RATE_16K);
108 return MTK_AFE_DAI_MEMIF_RATE_16K;
109 }
110}
111
112unsigned int mt6797_rate_transform(struct device *dev,
113 unsigned int rate, int aud_blk)
114{
115 switch (aud_blk) {
116 case MT6797_MEMIF_DAI:
117 case MT6797_MEMIF_MOD_DAI:
118 return dai_memif_rate_transform(dev, rate);
119 default:
120 return mt6797_general_rate_transform(dev, rate);
121 }
122}
123
124static const struct snd_pcm_hardware mt6797_afe_hardware = {
125 .info = SNDRV_PCM_INFO_MMAP |
126 SNDRV_PCM_INFO_INTERLEAVED |
127 SNDRV_PCM_INFO_MMAP_VALID,
128 .formats = SNDRV_PCM_FMTBIT_S16_LE |
129 SNDRV_PCM_FMTBIT_S24_LE |
130 SNDRV_PCM_FMTBIT_S32_LE,
131 .period_bytes_min = 256,
132 .period_bytes_max = 4 * 48 * 1024,
133 .periods_min = 2,
134 .periods_max = 256,
135 .buffer_bytes_max = 8 * 48 * 1024,
136 .fifo_size = 0,
137};
138
139static int mt6797_memif_fs(struct snd_pcm_substream *substream,
140 unsigned int rate)
141{
142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
143 struct snd_soc_component *component =
144 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
145 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
146 int id = rtd->cpu_dai->id;
147
148 return mt6797_rate_transform(afe->dev, rate, id);
149}
150
151static int mt6797_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
152{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_component *component =
155 snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
156 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
157
158 return mt6797_general_rate_transform(afe->dev, rate);
159}
160
161#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
162 SNDRV_PCM_RATE_88200 |\
163 SNDRV_PCM_RATE_96000 |\
164 SNDRV_PCM_RATE_176400 |\
165 SNDRV_PCM_RATE_192000)
166
167#define MTK_PCM_DAI_RATES (SNDRV_PCM_RATE_8000 |\
168 SNDRV_PCM_RATE_16000 |\
169 SNDRV_PCM_RATE_32000)
170
171#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
172 SNDRV_PCM_FMTBIT_S24_LE |\
173 SNDRV_PCM_FMTBIT_S32_LE)
174
175static struct snd_soc_dai_driver mt6797_memif_dai_driver[] = {
176 /* FE DAIs: memory intefaces to CPU */
177 {
178 .name = "DL1",
179 .id = MT6797_MEMIF_DL1,
180 .playback = {
181 .stream_name = "DL1",
182 .channels_min = 1,
183 .channels_max = 2,
184 .rates = MTK_PCM_RATES,
185 .formats = MTK_PCM_FORMATS,
186 },
187 .ops = &mtk_afe_fe_ops,
188 },
189 {
190 .name = "DL2",
191 .id = MT6797_MEMIF_DL2,
192 .playback = {
193 .stream_name = "DL2",
194 .channels_min = 1,
195 .channels_max = 2,
196 .rates = MTK_PCM_RATES,
197 .formats = MTK_PCM_FORMATS,
198 },
199 .ops = &mtk_afe_fe_ops,
200 },
201 {
202 .name = "DL3",
203 .id = MT6797_MEMIF_DL3,
204 .playback = {
205 .stream_name = "DL3",
206 .channels_min = 1,
207 .channels_max = 2,
208 .rates = MTK_PCM_RATES,
209 .formats = MTK_PCM_FORMATS,
210 },
211 .ops = &mtk_afe_fe_ops,
212 },
213 {
214 .name = "UL1",
215 .id = MT6797_MEMIF_VUL12,
216 .capture = {
217 .stream_name = "UL1",
218 .channels_min = 1,
219 .channels_max = 2,
220 .rates = MTK_PCM_RATES,
221 .formats = MTK_PCM_FORMATS,
222 },
223 .ops = &mtk_afe_fe_ops,
224 },
225 {
226 .name = "UL2",
227 .id = MT6797_MEMIF_AWB,
228 .capture = {
229 .stream_name = "UL2",
230 .channels_min = 1,
231 .channels_max = 2,
232 .rates = MTK_PCM_RATES,
233 .formats = MTK_PCM_FORMATS,
234 },
235 .ops = &mtk_afe_fe_ops,
236 },
237 {
238 .name = "UL3",
239 .id = MT6797_MEMIF_VUL,
240 .capture = {
241 .stream_name = "UL3",
242 .channels_min = 1,
243 .channels_max = 2,
244 .rates = MTK_PCM_RATES,
245 .formats = MTK_PCM_FORMATS,
246 },
247 .ops = &mtk_afe_fe_ops,
248 },
249 {
250 .name = "UL_MONO_1",
251 .id = MT6797_MEMIF_MOD_DAI,
252 .capture = {
253 .stream_name = "UL_MONO_1",
254 .channels_min = 1,
255 .channels_max = 1,
256 .rates = MTK_PCM_DAI_RATES,
257 .formats = MTK_PCM_FORMATS,
258 },
259 .ops = &mtk_afe_fe_ops,
260 },
261 {
262 .name = "UL_MONO_2",
263 .id = MT6797_MEMIF_DAI,
264 .capture = {
265 .stream_name = "UL_MONO_2",
266 .channels_min = 1,
267 .channels_max = 1,
268 .rates = MTK_PCM_DAI_RATES,
269 .formats = MTK_PCM_FORMATS,
270 },
271 .ops = &mtk_afe_fe_ops,
272 },
273};
274
275/* dma widget & routes*/
276static const struct snd_kcontrol_new memif_ul1_ch1_mix[] = {
277 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN21,
278 I_ADDA_UL_CH1, 1, 0),
279};
280
281static const struct snd_kcontrol_new memif_ul1_ch2_mix[] = {
282 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN22,
283 I_ADDA_UL_CH2, 1, 0),
284};
285
286static const struct snd_kcontrol_new memif_ul2_ch1_mix[] = {
287 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN5,
288 I_ADDA_UL_CH1, 1, 0),
289 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN5,
290 I_DL1_CH1, 1, 0),
291 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN5,
292 I_DL2_CH1, 1, 0),
293 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN5,
294 I_DL3_CH1, 1, 0),
295};
296
297static const struct snd_kcontrol_new memif_ul2_ch2_mix[] = {
298 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN6,
299 I_ADDA_UL_CH2, 1, 0),
300 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN6,
301 I_DL1_CH2, 1, 0),
302 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN6,
303 I_DL2_CH2, 1, 0),
304 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN6,
305 I_DL3_CH2, 1, 0),
306};
307
308static const struct snd_kcontrol_new memif_ul3_ch1_mix[] = {
309 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN9,
310 I_ADDA_UL_CH1, 1, 0),
311};
312
313static const struct snd_kcontrol_new memif_ul3_ch2_mix[] = {
314 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN10,
315 I_ADDA_UL_CH2, 1, 0),
316};
317
318static const struct snd_kcontrol_new memif_ul_mono_1_mix[] = {
319 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN12,
320 I_ADDA_UL_CH1, 1, 0),
321 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN12,
322 I_ADDA_UL_CH2, 1, 0),
323};
324
325static const struct snd_kcontrol_new memif_ul_mono_2_mix[] = {
326 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN11,
327 I_ADDA_UL_CH1, 1, 0),
328 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN11,
329 I_ADDA_UL_CH2, 1, 0),
330};
331
332static const struct snd_soc_dapm_widget mt6797_memif_widgets[] = {
333 /* memif */
334 SND_SOC_DAPM_MIXER("UL1_CH1", SND_SOC_NOPM, 0, 0,
335 memif_ul1_ch1_mix, ARRAY_SIZE(memif_ul1_ch1_mix)),
336 SND_SOC_DAPM_MIXER("UL1_CH2", SND_SOC_NOPM, 0, 0,
337 memif_ul1_ch2_mix, ARRAY_SIZE(memif_ul1_ch2_mix)),
338
339 SND_SOC_DAPM_MIXER("UL2_CH1", SND_SOC_NOPM, 0, 0,
340 memif_ul2_ch1_mix, ARRAY_SIZE(memif_ul2_ch1_mix)),
341 SND_SOC_DAPM_MIXER("UL2_CH2", SND_SOC_NOPM, 0, 0,
342 memif_ul2_ch2_mix, ARRAY_SIZE(memif_ul2_ch2_mix)),
343
344 SND_SOC_DAPM_MIXER("UL3_CH1", SND_SOC_NOPM, 0, 0,
345 memif_ul3_ch1_mix, ARRAY_SIZE(memif_ul3_ch1_mix)),
346 SND_SOC_DAPM_MIXER("UL3_CH2", SND_SOC_NOPM, 0, 0,
347 memif_ul3_ch2_mix, ARRAY_SIZE(memif_ul3_ch2_mix)),
348
349 SND_SOC_DAPM_MIXER("UL_MONO_1_CH1", SND_SOC_NOPM, 0, 0,
350 memif_ul_mono_1_mix,
351 ARRAY_SIZE(memif_ul_mono_1_mix)),
352
353 SND_SOC_DAPM_MIXER("UL_MONO_2_CH1", SND_SOC_NOPM, 0, 0,
354 memif_ul_mono_2_mix,
355 ARRAY_SIZE(memif_ul_mono_2_mix)),
356};
357
358static const struct snd_soc_dapm_route mt6797_memif_routes[] = {
359 /* capture */
360 {"UL1", NULL, "UL1_CH1"},
361 {"UL1", NULL, "UL1_CH2"},
362 {"UL1_CH1", "ADDA_UL_CH1", "ADDA Capture"},
363 {"UL1_CH2", "ADDA_UL_CH2", "ADDA Capture"},
364
365 {"UL2", NULL, "UL2_CH1"},
366 {"UL2", NULL, "UL2_CH2"},
367 {"UL2_CH1", "ADDA_UL_CH1", "ADDA Capture"},
368 {"UL2_CH2", "ADDA_UL_CH2", "ADDA Capture"},
369
370 {"UL3", NULL, "UL3_CH1"},
371 {"UL3", NULL, "UL3_CH2"},
372 {"UL3_CH1", "ADDA_UL_CH1", "ADDA Capture"},
373 {"UL3_CH2", "ADDA_UL_CH2", "ADDA Capture"},
374
375 {"UL_MONO_1", NULL, "UL_MONO_1_CH1"},
376 {"UL_MONO_1_CH1", "ADDA_UL_CH1", "ADDA Capture"},
377 {"UL_MONO_1_CH1", "ADDA_UL_CH2", "ADDA Capture"},
378
379 {"UL_MONO_2", NULL, "UL_MONO_2_CH1"},
380 {"UL_MONO_2_CH1", "ADDA_UL_CH1", "ADDA Capture"},
381 {"UL_MONO_2_CH1", "ADDA_UL_CH2", "ADDA Capture"},
382};
383
384static const struct snd_soc_component_driver mt6797_afe_pcm_dai_component = {
385 .name = "mt6797-afe-pcm-dai",
386};
387
388static const struct mtk_base_memif_data memif_data[MT6797_MEMIF_NUM] = {
389 [MT6797_MEMIF_DL1] = {
390 .name = "DL1",
391 .id = MT6797_MEMIF_DL1,
392 .reg_ofs_base = AFE_DL1_BASE,
393 .reg_ofs_cur = AFE_DL1_CUR,
394 .fs_reg = AFE_DAC_CON1,
395 .fs_shift = DL1_MODE_SFT,
396 .fs_maskbit = DL1_MODE_MASK,
397 .mono_reg = AFE_DAC_CON1,
398 .mono_shift = DL1_DATA_SFT,
399 .enable_reg = AFE_DAC_CON0,
400 .enable_shift = DL1_ON_SFT,
401 .hd_reg = AFE_MEMIF_HD_MODE,
402 .hd_shift = DL1_HD_SFT,
403 .agent_disable_reg = -1,
404 .agent_disable_shift = -1,
405 .msb_reg = -1,
406 .msb_shift = -1,
407 },
408 [MT6797_MEMIF_DL2] = {
409 .name = "DL2",
410 .id = MT6797_MEMIF_DL2,
411 .reg_ofs_base = AFE_DL2_BASE,
412 .reg_ofs_cur = AFE_DL2_CUR,
413 .fs_reg = AFE_DAC_CON1,
414 .fs_shift = DL2_MODE_SFT,
415 .fs_maskbit = DL2_MODE_MASK,
416 .mono_reg = AFE_DAC_CON1,
417 .mono_shift = DL2_DATA_SFT,
418 .enable_reg = AFE_DAC_CON0,
419 .enable_shift = DL2_ON_SFT,
420 .hd_reg = AFE_MEMIF_HD_MODE,
421 .hd_shift = DL2_HD_SFT,
422 .agent_disable_reg = -1,
423 .agent_disable_shift = -1,
424 .msb_reg = -1,
425 .msb_shift = -1,
426 },
427 [MT6797_MEMIF_DL3] = {
428 .name = "DL3",
429 .id = MT6797_MEMIF_DL3,
430 .reg_ofs_base = AFE_DL3_BASE,
431 .reg_ofs_cur = AFE_DL3_CUR,
432 .fs_reg = AFE_DAC_CON0,
433 .fs_shift = DL3_MODE_SFT,
434 .fs_maskbit = DL3_MODE_MASK,
435 .mono_reg = AFE_DAC_CON1,
436 .mono_shift = DL3_DATA_SFT,
437 .enable_reg = AFE_DAC_CON0,
438 .enable_shift = DL3_ON_SFT,
439 .hd_reg = AFE_MEMIF_HD_MODE,
440 .hd_shift = DL3_HD_SFT,
441 .agent_disable_reg = -1,
442 .agent_disable_shift = -1,
443 .msb_reg = -1,
444 .msb_shift = -1,
445 },
446 [MT6797_MEMIF_VUL] = {
447 .name = "VUL",
448 .id = MT6797_MEMIF_VUL,
449 .reg_ofs_base = AFE_VUL_BASE,
450 .reg_ofs_cur = AFE_VUL_CUR,
451 .fs_reg = AFE_DAC_CON1,
452 .fs_shift = VUL_MODE_SFT,
453 .fs_maskbit = VUL_MODE_MASK,
454 .mono_reg = AFE_DAC_CON1,
455 .mono_shift = VUL_DATA_SFT,
456 .enable_reg = AFE_DAC_CON0,
457 .enable_shift = VUL_ON_SFT,
458 .hd_reg = AFE_MEMIF_HD_MODE,
459 .hd_shift = VUL_HD_SFT,
460 .agent_disable_reg = -1,
461 .agent_disable_shift = -1,
462 .msb_reg = -1,
463 .msb_shift = -1,
464 },
465 [MT6797_MEMIF_AWB] = {
466 .name = "AWB",
467 .id = MT6797_MEMIF_AWB,
468 .reg_ofs_base = AFE_AWB_BASE,
469 .reg_ofs_cur = AFE_AWB_CUR,
470 .fs_reg = AFE_DAC_CON1,
471 .fs_shift = AWB_MODE_SFT,
472 .fs_maskbit = AWB_MODE_MASK,
473 .mono_reg = AFE_DAC_CON1,
474 .mono_shift = AWB_DATA_SFT,
475 .enable_reg = AFE_DAC_CON0,
476 .enable_shift = AWB_ON_SFT,
477 .hd_reg = AFE_MEMIF_HD_MODE,
478 .hd_shift = AWB_HD_SFT,
479 .agent_disable_reg = -1,
480 .agent_disable_shift = -1,
481 .msb_reg = -1,
482 .msb_shift = -1,
483 },
484 [MT6797_MEMIF_VUL12] = {
485 .name = "VUL12",
486 .id = MT6797_MEMIF_VUL12,
487 .reg_ofs_base = AFE_VUL_D2_BASE,
488 .reg_ofs_cur = AFE_VUL_D2_CUR,
489 .fs_reg = AFE_DAC_CON0,
490 .fs_shift = VUL_DATA2_MODE_SFT,
491 .fs_maskbit = VUL_DATA2_MODE_MASK,
492 .mono_reg = AFE_DAC_CON0,
493 .mono_shift = VUL_DATA2_DATA_SFT,
494 .enable_reg = AFE_DAC_CON0,
495 .enable_shift = VUL_DATA2_ON_SFT,
496 .hd_reg = AFE_MEMIF_HD_MODE,
497 .hd_shift = VUL_DATA2_HD_SFT,
498 .agent_disable_reg = -1,
499 .agent_disable_shift = -1,
500 .msb_reg = -1,
501 .msb_shift = -1,
502 },
503 [MT6797_MEMIF_DAI] = {
504 .name = "DAI",
505 .id = MT6797_MEMIF_DAI,
506 .reg_ofs_base = AFE_DAI_BASE,
507 .reg_ofs_cur = AFE_DAI_CUR,
508 .fs_reg = AFE_DAC_CON0,
509 .fs_shift = DAI_MODE_SFT,
510 .fs_maskbit = DAI_MODE_MASK,
511 .mono_reg = -1,
512 .mono_shift = 0,
513 .enable_reg = AFE_DAC_CON0,
514 .enable_shift = DAI_ON_SFT,
515 .hd_reg = AFE_MEMIF_HD_MODE,
516 .hd_shift = DAI_HD_SFT,
517 .agent_disable_reg = -1,
518 .agent_disable_shift = -1,
519 .msb_reg = -1,
520 .msb_shift = -1,
521 },
522 [MT6797_MEMIF_MOD_DAI] = {
523 .name = "MOD_DAI",
524 .id = MT6797_MEMIF_MOD_DAI,
525 .reg_ofs_base = AFE_MOD_DAI_BASE,
526 .reg_ofs_cur = AFE_MOD_DAI_CUR,
527 .fs_reg = AFE_DAC_CON1,
528 .fs_shift = MOD_DAI_MODE_SFT,
529 .fs_maskbit = MOD_DAI_MODE_MASK,
530 .mono_reg = -1,
531 .mono_shift = 0,
532 .enable_reg = AFE_DAC_CON0,
533 .enable_shift = MOD_DAI_ON_SFT,
534 .hd_reg = AFE_MEMIF_HD_MODE,
535 .hd_shift = MOD_DAI_HD_SFT,
536 .agent_disable_reg = -1,
537 .agent_disable_shift = -1,
538 .msb_reg = -1,
539 .msb_shift = -1,
540 },
541};
542
543static const struct mtk_base_irq_data irq_data[MT6797_IRQ_NUM] = {
544 [MT6797_IRQ_1] = {
545 .id = MT6797_IRQ_1,
546 .irq_cnt_reg = AFE_IRQ_MCU_CNT1,
547 .irq_cnt_shift = AFE_IRQ_MCU_CNT1_SFT,
548 .irq_cnt_maskbit = AFE_IRQ_MCU_CNT1_MASK,
549 .irq_fs_reg = AFE_IRQ_MCU_CON,
550 .irq_fs_shift = IRQ1_MCU_MODE_SFT,
551 .irq_fs_maskbit = IRQ1_MCU_MODE_MASK,
552 .irq_en_reg = AFE_IRQ_MCU_CON,
553 .irq_en_shift = IRQ1_MCU_ON_SFT,
554 .irq_clr_reg = AFE_IRQ_MCU_CLR,
555 .irq_clr_shift = IRQ1_MCU_CLR_SFT,
556 },
557 [MT6797_IRQ_2] = {
558 .id = MT6797_IRQ_2,
559 .irq_cnt_reg = AFE_IRQ_MCU_CNT2,
560 .irq_cnt_shift = AFE_IRQ_MCU_CNT2_SFT,
561 .irq_cnt_maskbit = AFE_IRQ_MCU_CNT2_MASK,
562 .irq_fs_reg = AFE_IRQ_MCU_CON,
563 .irq_fs_shift = IRQ2_MCU_MODE_SFT,
564 .irq_fs_maskbit = IRQ2_MCU_MODE_MASK,
565 .irq_en_reg = AFE_IRQ_MCU_CON,
566 .irq_en_shift = IRQ2_MCU_ON_SFT,
567 .irq_clr_reg = AFE_IRQ_MCU_CLR,
568 .irq_clr_shift = IRQ2_MCU_CLR_SFT,
569 },
570 [MT6797_IRQ_3] = {
571 .id = MT6797_IRQ_3,
572 .irq_cnt_reg = AFE_IRQ_MCU_CNT3,
573 .irq_cnt_shift = AFE_IRQ_MCU_CNT3_SFT,
574 .irq_cnt_maskbit = AFE_IRQ_MCU_CNT3_MASK,
575 .irq_fs_reg = AFE_IRQ_MCU_CON,
576 .irq_fs_shift = IRQ3_MCU_MODE_SFT,
577 .irq_fs_maskbit = IRQ3_MCU_MODE_MASK,
578 .irq_en_reg = AFE_IRQ_MCU_CON,
579 .irq_en_shift = IRQ3_MCU_ON_SFT,
580 .irq_clr_reg = AFE_IRQ_MCU_CLR,
581 .irq_clr_shift = IRQ3_MCU_CLR_SFT,
582 },
583 [MT6797_IRQ_4] = {
584 .id = MT6797_IRQ_4,
585 .irq_cnt_reg = AFE_IRQ_MCU_CNT4,
586 .irq_cnt_shift = AFE_IRQ_MCU_CNT4_SFT,
587 .irq_cnt_maskbit = AFE_IRQ_MCU_CNT4_MASK,
588 .irq_fs_reg = AFE_IRQ_MCU_CON,
589 .irq_fs_shift = IRQ4_MCU_MODE_SFT,
590 .irq_fs_maskbit = IRQ4_MCU_MODE_MASK,
591 .irq_en_reg = AFE_IRQ_MCU_CON,
592 .irq_en_shift = IRQ4_MCU_ON_SFT,
593 .irq_clr_reg = AFE_IRQ_MCU_CLR,
594 .irq_clr_shift = IRQ4_MCU_CLR_SFT,
595 },
596 [MT6797_IRQ_7] = {
597 .id = MT6797_IRQ_7,
598 .irq_cnt_reg = AFE_IRQ_MCU_CNT7,
599 .irq_cnt_shift = AFE_IRQ_MCU_CNT7_SFT,
600 .irq_cnt_maskbit = AFE_IRQ_MCU_CNT7_MASK,
601 .irq_fs_reg = AFE_IRQ_MCU_CON,
602 .irq_fs_shift = IRQ7_MCU_MODE_SFT,
603 .irq_fs_maskbit = IRQ7_MCU_MODE_MASK,
604 .irq_en_reg = AFE_IRQ_MCU_CON,
605 .irq_en_shift = IRQ7_MCU_ON_SFT,
606 .irq_clr_reg = AFE_IRQ_MCU_CLR,
607 .irq_clr_shift = IRQ7_MCU_CLR_SFT,
608 },
609};
610
611static const struct regmap_config mt6797_afe_regmap_config = {
612 .reg_bits = 32,
613 .reg_stride = 4,
614 .val_bits = 32,
615 .max_register = AFE_MAX_REGISTER,
616};
617
618static irqreturn_t mt6797_afe_irq_handler(int irq_id, void *dev)
619{
620 struct mtk_base_afe *afe = dev;
621 struct mtk_base_afe_irq *irq;
622 unsigned int status;
623 unsigned int mcu_en;
624 int ret;
625 int i;
626 irqreturn_t irq_ret = IRQ_HANDLED;
627
628 /* get irq that is sent to MCU */
629 regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
630
631 ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
632 if (ret || (status & mcu_en) == 0) {
633 dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n",
634 __func__, ret, status, mcu_en);
635
636 /* only clear IRQ which is sent to MCU */
637 status = mcu_en & AFE_IRQ_STATUS_BITS;
638
639 irq_ret = IRQ_NONE;
640 goto err_irq;
641 }
642
643 for (i = 0; i < MT6797_MEMIF_NUM; i++) {
644 struct mtk_base_afe_memif *memif = &afe->memif[i];
645
646 if (!memif->substream)
647 continue;
648
649 irq = &afe->irqs[memif->irq_usage];
650
651 if (status & (1 << irq->irq_data->irq_en_shift))
652 snd_pcm_period_elapsed(memif->substream);
653 }
654
655err_irq:
656 /* clear irq */
657 regmap_write(afe->regmap,
658 AFE_IRQ_MCU_CLR,
659 status & AFE_IRQ_STATUS_BITS);
660
661 return irq_ret;
662}
663
664static int mt6797_afe_runtime_suspend(struct device *dev)
665{
666 struct mtk_base_afe *afe = dev_get_drvdata(dev);
667 unsigned int afe_on_retm;
668 int retry = 0;
669
670 /* disable AFE */
671 regmap_update_bits(afe->regmap, AFE_DAC_CON0, AFE_ON_MASK_SFT, 0x0);
672 do {
673 regmap_read(afe->regmap, AFE_DAC_CON0, &afe_on_retm);
674 if ((afe_on_retm & AFE_ON_RETM_MASK_SFT) == 0)
675 break;
676
677 udelay(10);
678 } while (++retry < 100000);
679
680 if (retry)
681 dev_warn(afe->dev, "%s(), retry %d\n", __func__, retry);
682
683 /* make sure all irq status are cleared */
684 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff);
685
686 return mt6797_afe_disable_clock(afe);
687}
688
689static int mt6797_afe_runtime_resume(struct device *dev)
690{
691 struct mtk_base_afe *afe = dev_get_drvdata(dev);
692 int ret;
693
694 ret = mt6797_afe_enable_clock(afe);
695 if (ret)
696 return ret;
697
698 /* irq signal to mcu only */
699 regmap_write(afe->regmap, AFE_IRQ_MCU_EN, AFE_IRQ_MCU_EN_MASK_SFT);
700
701 /* force all memif use normal mode */
702 regmap_update_bits(afe->regmap, AFE_MEMIF_HDALIGN,
703 0x7ff << 16, 0x7ff << 16);
704 /* force cpu use normal mode when access sram data */
705 regmap_update_bits(afe->regmap, AFE_MEMIF_MSB,
706 CPU_COMPACT_MODE_MASK_SFT, 0);
707 /* force cpu use 8_24 format when writing 32bit data */
708 regmap_update_bits(afe->regmap, AFE_MEMIF_MSB,
709 CPU_HD_ALIGN_MASK_SFT, 0);
710
711 /* set all output port to 24bit */
712 regmap_update_bits(afe->regmap, AFE_CONN_24BIT,
713 0x3fffffff, 0x3fffffff);
714
715 /* enable AFE */
716 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
717 AFE_ON_MASK_SFT,
718 0x1 << AFE_ON_SFT);
719
720 return 0;
721}
722
723static int mt6797_afe_component_probe(struct snd_soc_component *component)
724{
725 return mtk_afe_add_sub_dai_control(component);
726}
727
728static const struct snd_soc_component_driver mt6797_afe_component = {
729 .name = AFE_PCM_NAME,
730 .ops = &mtk_afe_pcm_ops,
731 .pcm_new = mtk_afe_pcm_new,
732 .pcm_free = mtk_afe_pcm_free,
733 .probe = mt6797_afe_component_probe,
734};
735
736static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev)
737{
738 struct mtk_base_afe *afe;
739 struct mt6797_afe_private *afe_priv;
740 struct resource *res;
741 struct device *dev;
742 int i, irq_id, ret;
743
744 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
745 if (!afe)
746 return -ENOMEM;
747
748 afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
749 GFP_KERNEL);
750 if (!afe->platform_priv)
751 return -ENOMEM;
752
753 afe_priv = afe->platform_priv;
754 afe->dev = &pdev->dev;
755 dev = afe->dev;
756
757 /* initial audio related clock */
758 ret = mt6797_init_clock(afe);
759 if (ret) {
760 dev_err(dev, "init clock error\n");
761 return ret;
762 }
763
764 /* regmap init */
765 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
766
767 afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
768 if (IS_ERR(afe->base_addr))
769 return PTR_ERR(afe->base_addr);
770
771 afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
772 &mt6797_afe_regmap_config);
773 if (IS_ERR(afe->regmap))
774 return PTR_ERR(afe->regmap);
775
776 /* init memif */
777 afe->memif_size = MT6797_MEMIF_NUM;
778 afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
779 GFP_KERNEL);
780 if (!afe->memif)
781 return -ENOMEM;
782
783 for (i = 0; i < afe->memif_size; i++) {
784 afe->memif[i].data = &memif_data[i];
785 afe->memif[i].irq_usage = -1;
786 }
787
788 mutex_init(&afe->irq_alloc_lock);
789
790 /* irq initialize */
791 afe->irqs_size = MT6797_IRQ_NUM;
792 afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
793 GFP_KERNEL);
794 if (!afe->irqs)
795 return -ENOMEM;
796
797 for (i = 0; i < afe->irqs_size; i++)
798 afe->irqs[i].irq_data = &irq_data[i];
799
800 /* request irq */
801 irq_id = platform_get_irq(pdev, 0);
802 if (!irq_id) {
803 dev_err(dev, "%s no irq found\n", dev->of_node->name);
804 return -ENXIO;
805 }
806 ret = devm_request_irq(dev, irq_id, mt6797_afe_irq_handler,
807 IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
808 if (ret) {
809 dev_err(dev, "could not request_irq for asys-isr\n");
810 return ret;
811 }
812
813 /* init sub_dais */
814 afe->num_sub_dais = MT6797_DAI_NUM;
815 afe->sub_dais = devm_kcalloc(dev, afe->num_sub_dais,
816 sizeof(*afe->sub_dais),
817 GFP_KERNEL);
818 if (!afe->sub_dais)
819 return -ENOMEM;
820
821 mt6797_dai_adda_register(afe);
822 mt6797_dai_pcm_register(afe);
823 mt6797_dai_hostless_register(afe);
824
825 afe->sub_dais[MT6797_MEMIF_DL1].dai_drivers = mt6797_memif_dai_driver;
826 afe->sub_dais[MT6797_MEMIF_DL1].num_dai_drivers =
827 ARRAY_SIZE(mt6797_memif_dai_driver);
828 afe->sub_dais[MT6797_MEMIF_DL1].dapm_widgets = mt6797_memif_widgets;
829 afe->sub_dais[MT6797_MEMIF_DL1].num_dapm_widgets =
830 ARRAY_SIZE(mt6797_memif_widgets);
831 afe->sub_dais[MT6797_MEMIF_DL1].dapm_routes = mt6797_memif_routes;
832 afe->sub_dais[MT6797_MEMIF_DL1].num_dapm_routes =
833 ARRAY_SIZE(mt6797_memif_routes);
834
835 /* init dai_driver and component_driver */
836 mtk_afe_combine_sub_dai(afe);
837
838 afe->mtk_afe_hardware = &mt6797_afe_hardware;
839 afe->memif_fs = mt6797_memif_fs;
840 afe->irq_fs = mt6797_irq_fs;
841
842 afe->runtime_resume = mt6797_afe_runtime_resume;
843 afe->runtime_suspend = mt6797_afe_runtime_suspend;
844
845 platform_set_drvdata(pdev, afe);
846
847 pm_runtime_enable(dev);
848 if (!pm_runtime_enabled(dev))
849 goto err_pm_disable;
850 pm_runtime_get_sync(&pdev->dev);
851
852 /* register component */
853 ret = devm_snd_soc_register_component(dev, &mt6797_afe_component,
854 NULL, 0);
855 if (ret) {
856 dev_warn(dev, "err_platform\n");
857 goto err_pm_disable;
858 }
859
860 ret = devm_snd_soc_register_component(afe->dev,
861 &mt6797_afe_pcm_dai_component,
862 afe->dai_drivers,
863 afe->num_dai_drivers);
864 if (ret) {
865 dev_warn(dev, "err_dai_component\n");
866 goto err_pm_disable;
867 }
868
869 return 0;
870
871err_pm_disable:
872 pm_runtime_disable(dev);
873
874 return ret;
875}
876
877static int mt6797_afe_pcm_dev_remove(struct platform_device *pdev)
878{
879 pm_runtime_disable(&pdev->dev);
880 if (!pm_runtime_status_suspended(&pdev->dev))
881 mt6797_afe_runtime_suspend(&pdev->dev);
882 pm_runtime_put_sync(&pdev->dev);
883
884 return 0;
885}
886
887static const struct of_device_id mt6797_afe_pcm_dt_match[] = {
888 { .compatible = "mediatek,mt6797-audio", },
889 {},
890};
891MODULE_DEVICE_TABLE(of, mt6797_afe_pcm_dt_match);
892
893static const struct dev_pm_ops mt6797_afe_pm_ops = {
894 SET_RUNTIME_PM_OPS(mt6797_afe_runtime_suspend,
895 mt6797_afe_runtime_resume, NULL)
896};
897
898static struct platform_driver mt6797_afe_pcm_driver = {
899 .driver = {
900 .name = "mt6797-audio",
901 .of_match_table = mt6797_afe_pcm_dt_match,
902#ifdef CONFIG_PM
903 .pm = &mt6797_afe_pm_ops,
904#endif
905 },
906 .probe = mt6797_afe_pcm_dev_probe,
907 .remove = mt6797_afe_pcm_dev_remove,
908};
909
910module_platform_driver(mt6797_afe_pcm_driver);
911
912MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 6797");
913MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>");
914MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/mediatek/mt6797/mt6797-dai-adda.c b/sound/soc/mediatek/mt6797/mt6797-dai-adda.c
new file mode 100644
index 000000000000..ad083265ce94
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-dai-adda.c
@@ -0,0 +1,396 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// MediaTek ALSA SoC Audio DAI ADDA Control
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/regmap.h>
9#include <linux/delay.h>
10#include "mt6797-afe-common.h"
11#include "mt6797-interconnection.h"
12#include "mt6797-reg.h"
13
14enum {
15 MTK_AFE_ADDA_DL_RATE_8K = 0,
16 MTK_AFE_ADDA_DL_RATE_11K = 1,
17 MTK_AFE_ADDA_DL_RATE_12K = 2,
18 MTK_AFE_ADDA_DL_RATE_16K = 3,
19 MTK_AFE_ADDA_DL_RATE_22K = 4,
20 MTK_AFE_ADDA_DL_RATE_24K = 5,
21 MTK_AFE_ADDA_DL_RATE_32K = 6,
22 MTK_AFE_ADDA_DL_RATE_44K = 7,
23 MTK_AFE_ADDA_DL_RATE_48K = 8,
24 MTK_AFE_ADDA_DL_RATE_96K = 9,
25 MTK_AFE_ADDA_DL_RATE_192K = 10,
26};
27
28enum {
29 MTK_AFE_ADDA_UL_RATE_8K = 0,
30 MTK_AFE_ADDA_UL_RATE_16K = 1,
31 MTK_AFE_ADDA_UL_RATE_32K = 2,
32 MTK_AFE_ADDA_UL_RATE_48K = 3,
33 MTK_AFE_ADDA_UL_RATE_96K = 4,
34 MTK_AFE_ADDA_UL_RATE_192K = 5,
35 MTK_AFE_ADDA_UL_RATE_48K_HD = 6,
36};
37
38static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe,
39 unsigned int rate)
40{
41 switch (rate) {
42 case 8000:
43 return MTK_AFE_ADDA_DL_RATE_8K;
44 case 11025:
45 return MTK_AFE_ADDA_DL_RATE_11K;
46 case 12000:
47 return MTK_AFE_ADDA_DL_RATE_12K;
48 case 16000:
49 return MTK_AFE_ADDA_DL_RATE_16K;
50 case 22050:
51 return MTK_AFE_ADDA_DL_RATE_22K;
52 case 24000:
53 return MTK_AFE_ADDA_DL_RATE_24K;
54 case 32000:
55 return MTK_AFE_ADDA_DL_RATE_32K;
56 case 44100:
57 return MTK_AFE_ADDA_DL_RATE_44K;
58 case 48000:
59 return MTK_AFE_ADDA_DL_RATE_48K;
60 case 96000:
61 return MTK_AFE_ADDA_DL_RATE_96K;
62 case 192000:
63 return MTK_AFE_ADDA_DL_RATE_192K;
64 default:
65 dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
66 __func__, rate);
67 return MTK_AFE_ADDA_DL_RATE_48K;
68 }
69}
70
71static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe,
72 unsigned int rate)
73{
74 switch (rate) {
75 case 8000:
76 return MTK_AFE_ADDA_UL_RATE_8K;
77 case 16000:
78 return MTK_AFE_ADDA_UL_RATE_16K;
79 case 32000:
80 return MTK_AFE_ADDA_UL_RATE_32K;
81 case 48000:
82 return MTK_AFE_ADDA_UL_RATE_48K;
83 case 96000:
84 return MTK_AFE_ADDA_UL_RATE_96K;
85 case 192000:
86 return MTK_AFE_ADDA_UL_RATE_192K;
87 default:
88 dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
89 __func__, rate);
90 return MTK_AFE_ADDA_UL_RATE_48K;
91 }
92}
93
94/* dai component */
95static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = {
96 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0),
97 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0),
98 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0),
99 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3,
100 I_ADDA_UL_CH2, 1, 0),
101 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3,
102 I_ADDA_UL_CH1, 1, 0),
103 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3,
104 I_PCM_1_CAP_CH1, 1, 0),
105 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3,
106 I_PCM_2_CAP_CH1, 1, 0),
107};
108
109static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = {
110 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0),
111 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0),
112 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0),
113 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0),
114 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0),
115 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0),
116 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4,
117 I_ADDA_UL_CH2, 1, 0),
118 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4,
119 I_ADDA_UL_CH1, 1, 0),
120 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4,
121 I_PCM_1_CAP_CH1, 1, 0),
122 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4,
123 I_PCM_2_CAP_CH1, 1, 0),
124 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4,
125 I_PCM_1_CAP_CH2, 1, 0),
126 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4,
127 I_PCM_2_CAP_CH2, 1, 0),
128};
129
130static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
131 struct snd_kcontrol *kcontrol,
132 int event)
133{
134 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
135 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
136
137 dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
138 __func__, w->name, event);
139
140 switch (event) {
141 case SND_SOC_DAPM_POST_PMD:
142 /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
143 usleep_range(125, 135);
144 break;
145 default:
146 break;
147 }
148
149 return 0;
150}
151
152enum {
153 SUPPLY_SEQ_AUD_TOP_PDN,
154 SUPPLY_SEQ_ADDA_AFE_ON,
155 SUPPLY_SEQ_ADDA_DL_ON,
156 SUPPLY_SEQ_ADDA_UL_ON,
157};
158
159static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
160 /* adda */
161 SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0,
162 mtk_adda_dl_ch1_mix,
163 ARRAY_SIZE(mtk_adda_dl_ch1_mix)),
164 SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0,
165 mtk_adda_dl_ch2_mix,
166 ARRAY_SIZE(mtk_adda_dl_ch2_mix)),
167
168 SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
169 AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0,
170 NULL, 0),
171
172 SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
173 AFE_ADDA_DL_SRC2_CON0,
174 DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,
175 NULL, 0),
176
177 SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
178 AFE_ADDA_UL_SRC_CON0,
179 UL_SRC_ON_TMP_CTL_SFT, 0,
180 mtk_adda_ul_event,
181 SND_SOC_DAPM_POST_PMD),
182
183 SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN,
184 AUDIO_TOP_CON0, PDN_DAC_SFT, 1,
185 NULL, 0),
186 SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN,
187 AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1,
188 NULL, 0),
189
190 SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN,
191 AUDIO_TOP_CON0, PDN_ADC_SFT, 1,
192 NULL, 0),
193
194 SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"),
195};
196
197static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
198 /* playback */
199 {"ADDA_DL_CH1", "DL1_CH1", "DL1"},
200 {"ADDA_DL_CH2", "DL1_CH1", "DL1"},
201 {"ADDA_DL_CH2", "DL1_CH2", "DL1"},
202
203 {"ADDA_DL_CH1", "DL2_CH1", "DL2"},
204 {"ADDA_DL_CH2", "DL2_CH1", "DL2"},
205 {"ADDA_DL_CH2", "DL2_CH2", "DL2"},
206
207 {"ADDA_DL_CH1", "DL3_CH1", "DL3"},
208 {"ADDA_DL_CH2", "DL3_CH1", "DL3"},
209 {"ADDA_DL_CH2", "DL3_CH2", "DL3"},
210
211 {"ADDA Playback", NULL, "ADDA_DL_CH1"},
212 {"ADDA Playback", NULL, "ADDA_DL_CH2"},
213
214 /* adda enable */
215 {"ADDA Playback", NULL, "ADDA Enable"},
216 {"ADDA Playback", NULL, "ADDA Playback Enable"},
217 {"ADDA Capture", NULL, "ADDA Enable"},
218 {"ADDA Capture", NULL, "ADDA Capture Enable"},
219
220 /* clk */
221 {"ADDA Playback", NULL, "mtkaif_26m_clk"},
222 {"ADDA Playback", NULL, "aud_dac_clk"},
223 {"ADDA Playback", NULL, "aud_dac_predis_clk"},
224
225 {"ADDA Capture", NULL, "mtkaif_26m_clk"},
226 {"ADDA Capture", NULL, "aud_adc_clk"},
227};
228
229/* dai ops */
230static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
231 struct snd_pcm_hw_params *params,
232 struct snd_soc_dai *dai)
233{
234 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
235 unsigned int rate = params_rate(params);
236
237 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
238 __func__, dai->id, substream->stream, rate);
239
240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
241 unsigned int dl_src2_con0 = 0;
242 unsigned int dl_src2_con1 = 0;
243
244 /* clean predistortion */
245 regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
246 regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
247
248 /* set input sampling rate */
249 dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28;
250
251 /* set output mode */
252 switch (rate) {
253 case 192000:
254 dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */
255 dl_src2_con0 |= 1 << 14;
256 break;
257 case 96000:
258 dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */
259 dl_src2_con0 |= 1 << 14;
260 break;
261 default:
262 dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */
263 break;
264 }
265
266 /* turn off mute function */
267 dl_src2_con0 |= (0x03 << 11);
268
269 /* set voice input data if input sample rate is 8k or 16k */
270 if (rate == 8000 || rate == 16000)
271 dl_src2_con0 |= 0x01 << 5;
272
273 if (rate < 96000) {
274 /* SA suggest apply -0.3db to audio/speech path */
275 dl_src2_con1 = 0xf74f0000;
276 } else {
277 /* SA suggest apply -0.3db to audio/speech path
278 * with DL gain set to half,
279 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k
280 */
281 dl_src2_con1 = 0x7ba70000;
282 }
283
284 /* turn on down-link gain */
285 dl_src2_con0 = dl_src2_con0 | (0x01 << 1);
286
287 regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
288 regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
289 } else {
290 unsigned int voice_mode = 0;
291 unsigned int ul_src_con0 = 0; /* default value */
292
293 /* Using Internal ADC */
294 regmap_update_bits(afe->regmap,
295 AFE_ADDA_TOP_CON0,
296 0x1 << 0,
297 0x0 << 0);
298
299 voice_mode = adda_ul_rate_transform(afe, rate);
300
301 ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
302
303 /* up8x txif sat on */
304 regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201);
305
306 if (rate >= 96000) { /* hires */
307 /* use hires format [1 0 23] */
308 regmap_update_bits(afe->regmap,
309 AFE_ADDA_NEWIF_CFG0,
310 0x1 << 5,
311 0x1 << 5);
312
313 regmap_update_bits(afe->regmap,
314 AFE_ADDA_NEWIF_CFG2,
315 0xf << 28,
316 voice_mode << 28);
317 } else { /* normal 8~48k */
318 /* use fixed 260k anc path */
319 regmap_update_bits(afe->regmap,
320 AFE_ADDA_NEWIF_CFG2,
321 0xf << 28,
322 8 << 28);
323
324 /* ul_use_cic_out */
325 ul_src_con0 |= 0x1 << 20;
326 }
327
328 regmap_update_bits(afe->regmap,
329 AFE_ADDA_NEWIF_CFG2,
330 0xf << 28,
331 8 << 28);
332
333 regmap_update_bits(afe->regmap,
334 AFE_ADDA_UL_SRC_CON0,
335 0xfffffffe,
336 ul_src_con0);
337 }
338
339 return 0;
340}
341
342static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
343 .hw_params = mtk_dai_adda_hw_params,
344};
345
346/* dai driver */
347#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
348 SNDRV_PCM_RATE_96000 |\
349 SNDRV_PCM_RATE_192000)
350
351#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
352 SNDRV_PCM_RATE_16000 |\
353 SNDRV_PCM_RATE_32000 |\
354 SNDRV_PCM_RATE_48000 |\
355 SNDRV_PCM_RATE_96000 |\
356 SNDRV_PCM_RATE_192000)
357
358#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
359 SNDRV_PCM_FMTBIT_S24_LE |\
360 SNDRV_PCM_FMTBIT_S32_LE)
361
362static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
363 {
364 .name = "ADDA",
365 .id = MT6797_DAI_ADDA,
366 .playback = {
367 .stream_name = "ADDA Playback",
368 .channels_min = 1,
369 .channels_max = 2,
370 .rates = MTK_ADDA_PLAYBACK_RATES,
371 .formats = MTK_ADDA_FORMATS,
372 },
373 .capture = {
374 .stream_name = "ADDA Capture",
375 .channels_min = 1,
376 .channels_max = 2,
377 .rates = MTK_ADDA_CAPTURE_RATES,
378 .formats = MTK_ADDA_FORMATS,
379 },
380 .ops = &mtk_dai_adda_ops,
381 },
382};
383
384int mt6797_dai_adda_register(struct mtk_base_afe *afe)
385{
386 int id = MT6797_DAI_ADDA;
387
388 afe->sub_dais[id].dai_drivers = mtk_dai_adda_driver;
389 afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
390
391 afe->sub_dais[id].dapm_widgets = mtk_dai_adda_widgets;
392 afe->sub_dais[id].num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
393 afe->sub_dais[id].dapm_routes = mtk_dai_adda_routes;
394 afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
395 return 0;
396}
diff --git a/sound/soc/mediatek/mt6797/mt6797-dai-hostless.c b/sound/soc/mediatek/mt6797/mt6797-dai-hostless.c
new file mode 100644
index 000000000000..4cf985b15a11
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-dai-hostless.c
@@ -0,0 +1,112 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// MediaTek ALSA SoC Audio DAI Hostless Control
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include "mt6797-afe-common.h"
9
10/* dai component */
11static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = {
12 /* Hostless ADDA Loopback */
13 {"ADDA_DL_CH1", "ADDA_UL_CH1", "Hostless LPBK DL"},
14 {"ADDA_DL_CH1", "ADDA_UL_CH2", "Hostless LPBK DL"},
15 {"ADDA_DL_CH2", "ADDA_UL_CH1", "Hostless LPBK DL"},
16 {"ADDA_DL_CH2", "ADDA_UL_CH2", "Hostless LPBK DL"},
17 {"Hostless LPBK UL", NULL, "ADDA Capture"},
18
19 /* Hostless Speech */
20 {"ADDA_DL_CH1", "PCM_1_CAP_CH1", "Hostless Speech DL"},
21 {"ADDA_DL_CH2", "PCM_1_CAP_CH1", "Hostless Speech DL"},
22 {"ADDA_DL_CH2", "PCM_1_CAP_CH2", "Hostless Speech DL"},
23 {"ADDA_DL_CH1", "PCM_2_CAP_CH1", "Hostless Speech DL"},
24 {"ADDA_DL_CH2", "PCM_2_CAP_CH1", "Hostless Speech DL"},
25 {"ADDA_DL_CH2", "PCM_2_CAP_CH2", "Hostless Speech DL"},
26 {"PCM_1_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
27 {"PCM_1_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
28 {"PCM_2_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
29 {"PCM_2_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
30
31 {"Hostless Speech UL", NULL, "PCM 1 Capture"},
32 {"Hostless Speech UL", NULL, "PCM 2 Capture"},
33 {"Hostless Speech UL", NULL, "ADDA Capture"},
34};
35
36/* dai ops */
37static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,
38 struct snd_soc_dai *dai)
39{
40 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
41
42 return snd_soc_set_runtime_hwparams(substream, afe->mtk_afe_hardware);
43}
44
45static const struct snd_soc_dai_ops mtk_dai_hostless_ops = {
46 .startup = mtk_dai_hostless_startup,
47};
48
49/* dai driver */
50#define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\
51 SNDRV_PCM_RATE_88200 |\
52 SNDRV_PCM_RATE_96000 |\
53 SNDRV_PCM_RATE_176400 |\
54 SNDRV_PCM_RATE_192000)
55
56#define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
57 SNDRV_PCM_FMTBIT_S24_LE |\
58 SNDRV_PCM_FMTBIT_S32_LE)
59
60static struct snd_soc_dai_driver mtk_dai_hostless_driver[] = {
61 {
62 .name = "Hostless LPBK DAI",
63 .id = MT6797_DAI_HOSTLESS_LPBK,
64 .playback = {
65 .stream_name = "Hostless LPBK DL",
66 .channels_min = 1,
67 .channels_max = 2,
68 .rates = MTK_HOSTLESS_RATES,
69 .formats = MTK_HOSTLESS_FORMATS,
70 },
71 .capture = {
72 .stream_name = "Hostless LPBK UL",
73 .channels_min = 1,
74 .channels_max = 2,
75 .rates = MTK_HOSTLESS_RATES,
76 .formats = MTK_HOSTLESS_FORMATS,
77 },
78 .ops = &mtk_dai_hostless_ops,
79 },
80 {
81 .name = "Hostless Speech DAI",
82 .id = MT6797_DAI_HOSTLESS_SPEECH,
83 .playback = {
84 .stream_name = "Hostless Speech DL",
85 .channels_min = 1,
86 .channels_max = 2,
87 .rates = MTK_HOSTLESS_RATES,
88 .formats = MTK_HOSTLESS_FORMATS,
89 },
90 .capture = {
91 .stream_name = "Hostless Speech UL",
92 .channels_min = 1,
93 .channels_max = 2,
94 .rates = MTK_HOSTLESS_RATES,
95 .formats = MTK_HOSTLESS_FORMATS,
96 },
97 .ops = &mtk_dai_hostless_ops,
98 },
99};
100
101int mt6797_dai_hostless_register(struct mtk_base_afe *afe)
102{
103 int id = MT6797_DAI_HOSTLESS_LPBK;
104
105 afe->sub_dais[id].dai_drivers = mtk_dai_hostless_driver;
106 afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_hostless_driver);
107
108 afe->sub_dais[id].dapm_routes = mtk_dai_hostless_routes;
109 afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_hostless_routes);
110
111 return 0;
112}
diff --git a/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c b/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c
new file mode 100644
index 000000000000..16d5b5067204
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-dai-pcm.c
@@ -0,0 +1,312 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// MediaTek ALSA SoC Audio DAI I2S Control
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/regmap.h>
9#include <sound/pcm_params.h>
10#include "mt6797-afe-common.h"
11#include "mt6797-interconnection.h"
12#include "mt6797-reg.h"
13
14enum AUD_TX_LCH_RPT {
15 AUD_TX_LCH_RPT_NO_REPEAT = 0,
16 AUD_TX_LCH_RPT_REPEAT = 1
17};
18
19enum AUD_VBT_16K_MODE {
20 AUD_VBT_16K_MODE_DISABLE = 0,
21 AUD_VBT_16K_MODE_ENABLE = 1
22};
23
24enum AUD_EXT_MODEM {
25 AUD_EXT_MODEM_SELECT_INTERNAL = 0,
26 AUD_EXT_MODEM_SELECT_EXTERNAL = 1
27};
28
29enum AUD_PCM_SYNC_TYPE {
30 /* bck sync length = 1 */
31 AUD_PCM_ONE_BCK_CYCLE_SYNC = 0,
32 /* bck sync length = PCM_INTF_CON1[9:13] */
33 AUD_PCM_EXTENDED_BCK_CYCLE_SYNC = 1
34};
35
36enum AUD_BT_MODE {
37 AUD_BT_MODE_DUAL_MIC_ON_TX = 0,
38 AUD_BT_MODE_SINGLE_MIC_ON_TX = 1
39};
40
41enum AUD_PCM_AFIFO_SRC {
42 /* slave mode & external modem uses different crystal */
43 AUD_PCM_AFIFO_ASRC = 0,
44 /* slave mode & external modem uses the same crystal */
45 AUD_PCM_AFIFO_AFIFO = 1
46};
47
48enum AUD_PCM_CLOCK_SOURCE {
49 AUD_PCM_CLOCK_MASTER_MODE = 0,
50 AUD_PCM_CLOCK_SLAVE_MODE = 1
51};
52
53enum AUD_PCM_WLEN {
54 AUD_PCM_WLEN_PCM_32_BCK_CYCLES = 0,
55 AUD_PCM_WLEN_PCM_64_BCK_CYCLES = 1
56};
57
58enum AUD_PCM_MODE {
59 AUD_PCM_MODE_PCM_MODE_8K = 0,
60 AUD_PCM_MODE_PCM_MODE_16K = 1,
61 AUD_PCM_MODE_PCM_MODE_32K = 2,
62 AUD_PCM_MODE_PCM_MODE_48K = 3,
63};
64
65enum AUD_PCM_FMT {
66 AUD_PCM_FMT_I2S = 0,
67 AUD_PCM_FMT_EIAJ = 1,
68 AUD_PCM_FMT_PCM_MODE_A = 2,
69 AUD_PCM_FMT_PCM_MODE_B = 3
70};
71
72enum AUD_BCLK_OUT_INV {
73 AUD_BCLK_OUT_INV_NO_INVERSE = 0,
74 AUD_BCLK_OUT_INV_INVERSE = 1
75};
76
77enum AUD_PCM_EN {
78 AUD_PCM_EN_DISABLE = 0,
79 AUD_PCM_EN_ENABLE = 1
80};
81
82/* dai component */
83static const struct snd_kcontrol_new mtk_pcm_1_playback_ch1_mix[] = {
84 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN7,
85 I_ADDA_UL_CH1, 1, 0),
86 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN7,
87 I_DL2_CH1, 1, 0),
88};
89
90static const struct snd_kcontrol_new mtk_pcm_1_playback_ch2_mix[] = {
91 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN8,
92 I_ADDA_UL_CH2, 1, 0),
93 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN8,
94 I_DL2_CH2, 1, 0),
95};
96
97static const struct snd_kcontrol_new mtk_pcm_1_playback_ch4_mix[] = {
98 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN27,
99 I_DL1_CH1, 1, 0),
100};
101
102static const struct snd_kcontrol_new mtk_pcm_2_playback_ch1_mix[] = {
103 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN17,
104 I_ADDA_UL_CH1, 1, 0),
105 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN17,
106 I_DL2_CH1, 1, 0),
107};
108
109static const struct snd_kcontrol_new mtk_pcm_2_playback_ch2_mix[] = {
110 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN18,
111 I_ADDA_UL_CH2, 1, 0),
112 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN18,
113 I_DL2_CH2, 1, 0),
114};
115
116static const struct snd_kcontrol_new mtk_pcm_2_playback_ch4_mix[] = {
117 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN24,
118 I_DL1_CH1, 1, 0),
119};
120
121static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
122 /* inter-connections */
123 SND_SOC_DAPM_MIXER("PCM_1_PB_CH1", SND_SOC_NOPM, 0, 0,
124 mtk_pcm_1_playback_ch1_mix,
125 ARRAY_SIZE(mtk_pcm_1_playback_ch1_mix)),
126 SND_SOC_DAPM_MIXER("PCM_1_PB_CH2", SND_SOC_NOPM, 0, 0,
127 mtk_pcm_1_playback_ch2_mix,
128 ARRAY_SIZE(mtk_pcm_1_playback_ch2_mix)),
129 SND_SOC_DAPM_MIXER("PCM_1_PB_CH4", SND_SOC_NOPM, 0, 0,
130 mtk_pcm_1_playback_ch4_mix,
131 ARRAY_SIZE(mtk_pcm_1_playback_ch4_mix)),
132 SND_SOC_DAPM_MIXER("PCM_2_PB_CH1", SND_SOC_NOPM, 0, 0,
133 mtk_pcm_2_playback_ch1_mix,
134 ARRAY_SIZE(mtk_pcm_2_playback_ch1_mix)),
135 SND_SOC_DAPM_MIXER("PCM_2_PB_CH2", SND_SOC_NOPM, 0, 0,
136 mtk_pcm_2_playback_ch2_mix,
137 ARRAY_SIZE(mtk_pcm_2_playback_ch2_mix)),
138 SND_SOC_DAPM_MIXER("PCM_2_PB_CH4", SND_SOC_NOPM, 0, 0,
139 mtk_pcm_2_playback_ch4_mix,
140 ARRAY_SIZE(mtk_pcm_2_playback_ch4_mix)),
141
142 SND_SOC_DAPM_SUPPLY("PCM_1_EN", PCM_INTF_CON1, PCM_EN_SFT, 0,
143 NULL, 0),
144
145 SND_SOC_DAPM_SUPPLY("PCM_2_EN", PCM2_INTF_CON, PCM2_EN_SFT, 0,
146 NULL, 0),
147
148 SND_SOC_DAPM_INPUT("MD1_TO_AFE"),
149 SND_SOC_DAPM_INPUT("MD2_TO_AFE"),
150 SND_SOC_DAPM_OUTPUT("AFE_TO_MD1"),
151 SND_SOC_DAPM_OUTPUT("AFE_TO_MD2"),
152};
153
154static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
155 {"PCM 1 Playback", NULL, "PCM_1_PB_CH1"},
156 {"PCM 1 Playback", NULL, "PCM_1_PB_CH2"},
157 {"PCM 1 Playback", NULL, "PCM_1_PB_CH4"},
158 {"PCM 2 Playback", NULL, "PCM_2_PB_CH1"},
159 {"PCM 2 Playback", NULL, "PCM_2_PB_CH2"},
160 {"PCM 2 Playback", NULL, "PCM_2_PB_CH4"},
161
162 {"PCM 1 Playback", NULL, "PCM_1_EN"},
163 {"PCM 2 Playback", NULL, "PCM_2_EN"},
164 {"PCM 1 Capture", NULL, "PCM_1_EN"},
165 {"PCM 2 Capture", NULL, "PCM_2_EN"},
166
167 {"AFE_TO_MD1", NULL, "PCM 2 Playback"},
168 {"AFE_TO_MD2", NULL, "PCM 1 Playback"},
169 {"PCM 2 Capture", NULL, "MD1_TO_AFE"},
170 {"PCM 1 Capture", NULL, "MD2_TO_AFE"},
171
172 {"PCM_1_PB_CH1", "DL2_CH1", "DL2"},
173 {"PCM_1_PB_CH2", "DL2_CH2", "DL2"},
174 {"PCM_1_PB_CH4", "DL1_CH1", "DL1"},
175 {"PCM_2_PB_CH1", "DL2_CH1", "DL2"},
176 {"PCM_2_PB_CH2", "DL2_CH2", "DL2"},
177 {"PCM_2_PB_CH4", "DL1_CH1", "DL1"},
178};
179
180/* dai ops */
181static int mtk_dai_pcm_hw_params(struct snd_pcm_substream *substream,
182 struct snd_pcm_hw_params *params,
183 struct snd_soc_dai *dai)
184{
185 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
186 unsigned int rate = params_rate(params);
187 unsigned int rate_reg = mt6797_rate_transform(afe->dev, rate, dai->id);
188 unsigned int pcm_con = 0;
189
190 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d, rate_reg %d, widget active p %d, c %d\n",
191 __func__,
192 dai->id,
193 substream->stream,
194 rate,
195 rate_reg,
196 dai->playback_widget->active,
197 dai->capture_widget->active);
198
199 if (dai->playback_widget->active || dai->capture_widget->active)
200 return 0;
201
202 switch (dai->id) {
203 case MT6797_DAI_PCM_1:
204 pcm_con |= AUD_BCLK_OUT_INV_NO_INVERSE << PCM_BCLK_OUT_INV_SFT;
205 pcm_con |= AUD_TX_LCH_RPT_NO_REPEAT << PCM_TX_LCH_RPT_SFT;
206 pcm_con |= AUD_VBT_16K_MODE_DISABLE << PCM_VBT_16K_MODE_SFT;
207 pcm_con |= AUD_EXT_MODEM_SELECT_INTERNAL << PCM_EXT_MODEM_SFT;
208 pcm_con |= 0 << PCM_SYNC_LENGTH_SFT;
209 pcm_con |= AUD_PCM_ONE_BCK_CYCLE_SYNC << PCM_SYNC_TYPE_SFT;
210 pcm_con |= AUD_BT_MODE_DUAL_MIC_ON_TX << PCM_BT_MODE_SFT;
211 pcm_con |= AUD_PCM_AFIFO_AFIFO << PCM_BYP_ASRC_SFT;
212 pcm_con |= AUD_PCM_CLOCK_SLAVE_MODE << PCM_SLAVE_SFT;
213 pcm_con |= rate_reg << PCM_MODE_SFT;
214 pcm_con |= AUD_PCM_FMT_PCM_MODE_B << PCM_FMT_SFT;
215
216 regmap_update_bits(afe->regmap, PCM_INTF_CON1,
217 0xfffffffe, pcm_con);
218 break;
219 case MT6797_DAI_PCM_2:
220 pcm_con |= AUD_TX_LCH_RPT_NO_REPEAT << PCM2_TX_LCH_RPT_SFT;
221 pcm_con |= AUD_VBT_16K_MODE_DISABLE << PCM2_VBT_16K_MODE_SFT;
222 pcm_con |= AUD_BT_MODE_DUAL_MIC_ON_TX << PCM2_BT_MODE_SFT;
223 pcm_con |= AUD_PCM_AFIFO_AFIFO << PCM2_AFIFO_SFT;
224 pcm_con |= AUD_PCM_WLEN_PCM_32_BCK_CYCLES << PCM2_WLEN_SFT;
225 pcm_con |= rate_reg << PCM2_MODE_SFT;
226 pcm_con |= AUD_PCM_FMT_PCM_MODE_B << PCM2_FMT_SFT;
227
228 regmap_update_bits(afe->regmap, PCM2_INTF_CON,
229 0xfffffffe, pcm_con);
230 break;
231 default:
232 dev_warn(afe->dev, "%s(), id %d not support\n",
233 __func__, dai->id);
234 return -EINVAL;
235 }
236
237 return 0;
238}
239
240static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
241 .hw_params = mtk_dai_pcm_hw_params,
242};
243
244/* dai driver */
245#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000 |\
246 SNDRV_PCM_RATE_16000 |\
247 SNDRV_PCM_RATE_32000 |\
248 SNDRV_PCM_RATE_48000)
249
250#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
251 SNDRV_PCM_FMTBIT_S24_LE |\
252 SNDRV_PCM_FMTBIT_S32_LE)
253
254static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
255 {
256 .name = "PCM 1",
257 .id = MT6797_DAI_PCM_1,
258 .playback = {
259 .stream_name = "PCM 1 Playback",
260 .channels_min = 1,
261 .channels_max = 2,
262 .rates = MTK_PCM_RATES,
263 .formats = MTK_PCM_FORMATS,
264 },
265 .capture = {
266 .stream_name = "PCM 1 Capture",
267 .channels_min = 1,
268 .channels_max = 2,
269 .rates = MTK_PCM_RATES,
270 .formats = MTK_PCM_FORMATS,
271 },
272 .ops = &mtk_dai_pcm_ops,
273 .symmetric_rates = 1,
274 .symmetric_samplebits = 1,
275 },
276 {
277 .name = "PCM 2",
278 .id = MT6797_DAI_PCM_2,
279 .playback = {
280 .stream_name = "PCM 2 Playback",
281 .channels_min = 1,
282 .channels_max = 2,
283 .rates = MTK_PCM_RATES,
284 .formats = MTK_PCM_FORMATS,
285 },
286 .capture = {
287 .stream_name = "PCM 2 Capture",
288 .channels_min = 1,
289 .channels_max = 2,
290 .rates = MTK_PCM_RATES,
291 .formats = MTK_PCM_FORMATS,
292 },
293 .ops = &mtk_dai_pcm_ops,
294 .symmetric_rates = 1,
295 .symmetric_samplebits = 1,
296 },
297};
298
299int mt6797_dai_pcm_register(struct mtk_base_afe *afe)
300{
301 int id = MT6797_DAI_PCM_1;
302
303 afe->sub_dais[id].dai_drivers = mtk_dai_pcm_driver;
304 afe->sub_dais[id].num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
305
306 afe->sub_dais[id].dapm_widgets = mtk_dai_pcm_widgets;
307 afe->sub_dais[id].num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
308 afe->sub_dais[id].dapm_routes = mtk_dai_pcm_routes;
309 afe->sub_dais[id].num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
310
311 return 0;
312}
diff --git a/sound/soc/mediatek/mt6797/mt6797-interconnection.h b/sound/soc/mediatek/mt6797/mt6797-interconnection.h
new file mode 100644
index 000000000000..07b759b20079
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-interconnection.h
@@ -0,0 +1,33 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Mediatek MT6797 audio driver interconnection definition
4 *
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7 */
8
9#ifndef _MT6797_INTERCONNECTION_H_
10#define _MT6797_INTERCONNECTION_H_
11
12#define I_I2S0_CH1 0
13#define I_I2S0_CH2 1
14#define I_ADDA_UL_CH1 3
15#define I_ADDA_UL_CH2 4
16#define I_DL1_CH1 5
17#define I_DL1_CH2 6
18#define I_DL2_CH1 7
19#define I_DL2_CH2 8
20#define I_PCM_1_CAP_CH1 9
21#define I_GAIN1_OUT_CH1 10
22#define I_GAIN1_OUT_CH2 11
23#define I_GAIN2_OUT_CH1 12
24#define I_GAIN2_OUT_CH2 13
25#define I_PCM_2_CAP_CH1 14
26#define I_PCM_2_CAP_CH2 21
27#define I_PCM_1_CAP_CH2 22
28#define I_DL3_CH1 23
29#define I_DL3_CH2 24
30#define I_I2S2_CH1 25
31#define I_I2S2_CH2 26
32
33#endif
diff --git a/sound/soc/mediatek/mt6797/mt6797-mt6351.c b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
new file mode 100644
index 000000000000..b1558c57b9ca
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-mt6351.c
@@ -0,0 +1,223 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// mt6797-mt6351.c -- MT6797 MT6351 ALSA SoC machine driver
4//
5// Copyright (c) 2018 MediaTek Inc.
6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7
8#include <linux/module.h>
9#include <sound/soc.h>
10
11#include "mt6797-afe-common.h"
12
13static struct snd_soc_dai_link mt6797_mt6351_dai_links[] = {
14 /* FE */
15 {
16 .name = "Playback_1",
17 .stream_name = "Playback_1",
18 .cpu_dai_name = "DL1",
19 .codec_name = "snd-soc-dummy",
20 .codec_dai_name = "snd-soc-dummy-dai",
21 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
22 SND_SOC_DPCM_TRIGGER_PRE},
23 .dynamic = 1,
24 .dpcm_playback = 1,
25 },
26 {
27 .name = "Playback_2",
28 .stream_name = "Playback_2",
29 .cpu_dai_name = "DL2",
30 .codec_name = "snd-soc-dummy",
31 .codec_dai_name = "snd-soc-dummy-dai",
32 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
33 SND_SOC_DPCM_TRIGGER_PRE},
34 .dynamic = 1,
35 .dpcm_playback = 1,
36 },
37 {
38 .name = "Playback_3",
39 .stream_name = "Playback_3",
40 .cpu_dai_name = "DL3",
41 .codec_name = "snd-soc-dummy",
42 .codec_dai_name = "snd-soc-dummy-dai",
43 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
44 SND_SOC_DPCM_TRIGGER_PRE},
45 .dynamic = 1,
46 .dpcm_playback = 1,
47 },
48 {
49 .name = "Capture_1",
50 .stream_name = "Capture_1",
51 .cpu_dai_name = "UL1",
52 .codec_name = "snd-soc-dummy",
53 .codec_dai_name = "snd-soc-dummy-dai",
54 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
55 SND_SOC_DPCM_TRIGGER_PRE},
56 .dynamic = 1,
57 .dpcm_capture = 1,
58 },
59 {
60 .name = "Capture_2",
61 .stream_name = "Capture_2",
62 .cpu_dai_name = "UL2",
63 .codec_name = "snd-soc-dummy",
64 .codec_dai_name = "snd-soc-dummy-dai",
65 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
66 SND_SOC_DPCM_TRIGGER_PRE},
67 .dynamic = 1,
68 .dpcm_capture = 1,
69 },
70 {
71 .name = "Capture_3",
72 .stream_name = "Capture_3",
73 .cpu_dai_name = "UL3",
74 .codec_name = "snd-soc-dummy",
75 .codec_dai_name = "snd-soc-dummy-dai",
76 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
77 SND_SOC_DPCM_TRIGGER_PRE},
78 .dynamic = 1,
79 .dpcm_capture = 1,
80 },
81 {
82 .name = "Capture_Mono_1",
83 .stream_name = "Capture_Mono_1",
84 .cpu_dai_name = "UL_MONO_1",
85 .codec_name = "snd-soc-dummy",
86 .codec_dai_name = "snd-soc-dummy-dai",
87 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
88 SND_SOC_DPCM_TRIGGER_PRE},
89 .dynamic = 1,
90 .dpcm_capture = 1,
91 },
92 {
93 .name = "Hostless_LPBK",
94 .stream_name = "Hostless_LPBK",
95 .cpu_dai_name = "Hostless LPBK DAI",
96 .codec_name = "snd-soc-dummy",
97 .codec_dai_name = "snd-soc-dummy-dai",
98 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
99 SND_SOC_DPCM_TRIGGER_PRE},
100 .dynamic = 1,
101 .dpcm_playback = 1,
102 .dpcm_capture = 1,
103 .ignore_suspend = 1,
104 },
105 {
106 .name = "Hostless_Speech",
107 .stream_name = "Hostless_Speech",
108 .cpu_dai_name = "Hostless Speech DAI",
109 .codec_name = "snd-soc-dummy",
110 .codec_dai_name = "snd-soc-dummy-dai",
111 .trigger = {SND_SOC_DPCM_TRIGGER_PRE,
112 SND_SOC_DPCM_TRIGGER_PRE},
113 .dynamic = 1,
114 .dpcm_playback = 1,
115 .dpcm_capture = 1,
116 .ignore_suspend = 1,
117 },
118 /* BE */
119 {
120 .name = "Primary Codec",
121 .cpu_dai_name = "ADDA",
122 .codec_dai_name = "mt6351-snd-codec-aif1",
123 .no_pcm = 1,
124 .dpcm_playback = 1,
125 .dpcm_capture = 1,
126 .ignore_suspend = 1,
127 },
128 {
129 .name = "PCM 1",
130 .cpu_dai_name = "PCM 1",
131 .codec_name = "snd-soc-dummy",
132 .codec_dai_name = "snd-soc-dummy-dai",
133 .no_pcm = 1,
134 .dpcm_playback = 1,
135 .dpcm_capture = 1,
136 .ignore_suspend = 1,
137 },
138 {
139 .name = "PCM 2",
140 .cpu_dai_name = "PCM 2",
141 .codec_name = "snd-soc-dummy",
142 .codec_dai_name = "snd-soc-dummy-dai",
143 .no_pcm = 1,
144 .dpcm_playback = 1,
145 .dpcm_capture = 1,
146 .ignore_suspend = 1,
147 },
148};
149
150static struct snd_soc_card mt6797_mt6351_card = {
151 .name = "mt6797-mt6351",
152 .owner = THIS_MODULE,
153 .dai_link = mt6797_mt6351_dai_links,
154 .num_links = ARRAY_SIZE(mt6797_mt6351_dai_links),
155};
156
157static int mt6797_mt6351_dev_probe(struct platform_device *pdev)
158{
159 struct snd_soc_card *card = &mt6797_mt6351_card;
160 struct device_node *platform_node, *codec_node;
161 int ret, i;
162
163 card->dev = &pdev->dev;
164
165 platform_node = of_parse_phandle(pdev->dev.of_node,
166 "mediatek,platform", 0);
167 if (!platform_node) {
168 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
169 return -EINVAL;
170 }
171 for (i = 0; i < card->num_links; i++) {
172 if (mt6797_mt6351_dai_links[i].platform_name)
173 continue;
174 mt6797_mt6351_dai_links[i].platform_of_node = platform_node;
175 }
176
177 codec_node = of_parse_phandle(pdev->dev.of_node,
178 "mediatek,audio-codec", 0);
179 if (!codec_node) {
180 dev_err(&pdev->dev,
181 "Property 'audio-codec' missing or invalid\n");
182 return -EINVAL;
183 }
184 for (i = 0; i < card->num_links; i++) {
185 if (mt6797_mt6351_dai_links[i].codec_name)
186 continue;
187 mt6797_mt6351_dai_links[i].codec_of_node = codec_node;
188 }
189
190 ret = devm_snd_soc_register_card(&pdev->dev, card);
191 if (ret)
192 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
193 __func__, ret);
194
195 return ret;
196}
197
198#ifdef CONFIG_OF
199static const struct of_device_id mt6797_mt6351_dt_match[] = {
200 {.compatible = "mediatek,mt6797-mt6351-sound",},
201 {}
202};
203#endif
204
205static struct platform_driver mt6797_mt6351_driver = {
206 .driver = {
207 .name = "mt6797-mt6351",
208 .owner = THIS_MODULE,
209#ifdef CONFIG_OF
210 .of_match_table = mt6797_mt6351_dt_match,
211#endif
212 },
213 .probe = mt6797_mt6351_dev_probe,
214};
215
216module_platform_driver(mt6797_mt6351_driver);
217
218/* Module information */
219MODULE_DESCRIPTION("MT6797 MT6351 ALSA SoC machine driver");
220MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>");
221MODULE_LICENSE("GPL v2");
222MODULE_ALIAS("mt6797 mt6351 soc card");
223
diff --git a/sound/soc/mediatek/mt6797/mt6797-reg.h b/sound/soc/mediatek/mt6797/mt6797-reg.h
new file mode 100644
index 000000000000..978f146c143c
--- /dev/null
+++ b/sound/soc/mediatek/mt6797/mt6797-reg.h
@@ -0,0 +1,1015 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * mt6797-reg.h -- Mediatek 6797 audio driver reg definition
4 *
5 * Copyright (c) 2018 MediaTek Inc.
6 * Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7 */
8
9#ifndef _MT6797_REG_H_
10#define _MT6797_REG_H_
11
12#define AUDIO_TOP_CON0 0x0000
13#define AUDIO_TOP_CON1 0x0004
14#define AUDIO_TOP_CON3 0x000c
15#define AFE_DAC_CON0 0x0010
16#define AFE_DAC_CON1 0x0014
17#define AFE_I2S_CON 0x0018
18#define AFE_DAIBT_CON0 0x001c
19#define AFE_CONN0 0x0020
20#define AFE_CONN1 0x0024
21#define AFE_CONN2 0x0028
22#define AFE_CONN3 0x002c
23#define AFE_CONN4 0x0030
24#define AFE_I2S_CON1 0x0034
25#define AFE_I2S_CON2 0x0038
26#define AFE_MRGIF_CON 0x003c
27#define AFE_DL1_BASE 0x0040
28#define AFE_DL1_CUR 0x0044
29#define AFE_DL1_END 0x0048
30#define AFE_I2S_CON3 0x004c
31#define AFE_DL2_BASE 0x0050
32#define AFE_DL2_CUR 0x0054
33#define AFE_DL2_END 0x0058
34#define AFE_CONN5 0x005c
35#define AFE_CONN_24BIT 0x006c
36#define AFE_AWB_BASE 0x0070
37#define AFE_AWB_END 0x0078
38#define AFE_AWB_CUR 0x007c
39#define AFE_VUL_BASE 0x0080
40#define AFE_VUL_END 0x0088
41#define AFE_VUL_CUR 0x008c
42#define AFE_DAI_BASE 0x0090
43#define AFE_DAI_END 0x0098
44#define AFE_DAI_CUR 0x009c
45#define AFE_CONN6 0x00bc
46#define AFE_MEMIF_MSB 0x00cc
47#define AFE_MEMIF_MON0 0x00d0
48#define AFE_MEMIF_MON1 0x00d4
49#define AFE_MEMIF_MON2 0x00d8
50#define AFE_MEMIF_MON4 0x00e0
51#define AFE_ADDA_DL_SRC2_CON0 0x0108
52#define AFE_ADDA_DL_SRC2_CON1 0x010c
53#define AFE_ADDA_UL_SRC_CON0 0x0114
54#define AFE_ADDA_UL_SRC_CON1 0x0118
55#define AFE_ADDA_TOP_CON0 0x0120
56#define AFE_ADDA_UL_DL_CON0 0x0124
57#define AFE_ADDA_SRC_DEBUG 0x012c
58#define AFE_ADDA_SRC_DEBUG_MON0 0x0130
59#define AFE_ADDA_SRC_DEBUG_MON1 0x0134
60#define AFE_ADDA_NEWIF_CFG0 0x0138
61#define AFE_ADDA_NEWIF_CFG1 0x013c
62#define AFE_ADDA_NEWIF_CFG2 0x0140
63#define AFE_DMA_CTL 0x0150
64#define AFE_DMA_MON0 0x0154
65#define AFE_DMA_MON1 0x0158
66#define AFE_SIDETONE_DEBUG 0x01d0
67#define AFE_SIDETONE_MON 0x01d4
68#define AFE_SIDETONE_CON0 0x01e0
69#define AFE_SIDETONE_COEFF 0x01e4
70#define AFE_SIDETONE_CON1 0x01e8
71#define AFE_SIDETONE_GAIN 0x01ec
72#define AFE_SGEN_CON0 0x01f0
73#define AFE_SINEGEN_CON_TDM 0x01fc
74#define AFE_TOP_CON0 0x0200
75#define AFE_ADDA_PREDIS_CON0 0x0260
76#define AFE_ADDA_PREDIS_CON1 0x0264
77#define AFE_MRGIF_MON0 0x0270
78#define AFE_MRGIF_MON1 0x0274
79#define AFE_MRGIF_MON2 0x0278
80#define AFE_I2S_MON 0x027c
81#define AFE_MOD_DAI_BASE 0x0330
82#define AFE_MOD_DAI_END 0x0338
83#define AFE_MOD_DAI_CUR 0x033c
84#define AFE_VUL_D2_BASE 0x0350
85#define AFE_VUL_D2_END 0x0358
86#define AFE_VUL_D2_CUR 0x035c
87#define AFE_DL3_BASE 0x0360
88#define AFE_DL3_CUR 0x0364
89#define AFE_DL3_END 0x0368
90#define AFE_HDMI_OUT_CON0 0x0370
91#define AFE_HDMI_BASE 0x0374
92#define AFE_HDMI_CUR 0x0378
93#define AFE_HDMI_END 0x037c
94#define AFE_HDMI_CONN0 0x0390
95#define AFE_IRQ3_MCU_CNT_MON 0x0398
96#define AFE_IRQ4_MCU_CNT_MON 0x039c
97#define AFE_IRQ_MCU_CON 0x03a0
98#define AFE_IRQ_MCU_STATUS 0x03a4
99#define AFE_IRQ_MCU_CLR 0x03a8
100#define AFE_IRQ_MCU_CNT1 0x03ac
101#define AFE_IRQ_MCU_CNT2 0x03b0
102#define AFE_IRQ_MCU_EN 0x03b4
103#define AFE_IRQ_MCU_MON2 0x03b8
104#define AFE_IRQ_MCU_CNT5 0x03bc
105#define AFE_IRQ1_MCU_CNT_MON 0x03c0
106#define AFE_IRQ2_MCU_CNT_MON 0x03c4
107#define AFE_IRQ1_MCU_EN_CNT_MON 0x03c8
108#define AFE_IRQ5_MCU_CNT_MON 0x03cc
109#define AFE_MEMIF_MINLEN 0x03d0
110#define AFE_MEMIF_MAXLEN 0x03d4
111#define AFE_MEMIF_PBUF_SIZE 0x03d8
112#define AFE_IRQ_MCU_CNT7 0x03dc
113#define AFE_IRQ7_MCU_CNT_MON 0x03e0
114#define AFE_IRQ_MCU_CNT3 0x03e4
115#define AFE_IRQ_MCU_CNT4 0x03e8
116#define AFE_APLL1_TUNER_CFG 0x03f0
117#define AFE_APLL2_TUNER_CFG 0x03f4
118#define AFE_MEMIF_HD_MODE 0x03f8
119#define AFE_MEMIF_HDALIGN 0x03fc
120#define AFE_GAIN1_CON0 0x0410
121#define AFE_GAIN1_CON1 0x0414
122#define AFE_GAIN1_CON2 0x0418
123#define AFE_GAIN1_CON3 0x041c
124#define AFE_CONN7 0x0420
125#define AFE_GAIN1_CUR 0x0424
126#define AFE_GAIN2_CON0 0x0428
127#define AFE_GAIN2_CON1 0x042c
128#define AFE_GAIN2_CON2 0x0430
129#define AFE_GAIN2_CON3 0x0434
130#define AFE_CONN8 0x0438
131#define AFE_GAIN2_CUR 0x043c
132#define AFE_CONN9 0x0440
133#define AFE_CONN10 0x0444
134#define AFE_CONN11 0x0448
135#define AFE_CONN12 0x044c
136#define AFE_CONN13 0x0450
137#define AFE_CONN14 0x0454
138#define AFE_CONN15 0x0458
139#define AFE_CONN16 0x045c
140#define AFE_CONN17 0x0460
141#define AFE_CONN18 0x0464
142#define AFE_CONN19 0x0468
143#define AFE_CONN20 0x046c
144#define AFE_CONN21 0x0470
145#define AFE_CONN22 0x0474
146#define AFE_CONN23 0x0478
147#define AFE_CONN24 0x047c
148#define AFE_CONN_RS 0x0494
149#define AFE_CONN_DI 0x0498
150#define AFE_CONN25 0x04b0
151#define AFE_CONN26 0x04b4
152#define AFE_CONN27 0x04b8
153#define AFE_CONN28 0x04bc
154#define AFE_CONN29 0x04c0
155#define AFE_SRAM_DELSEL_CON0 0x04f0
156#define AFE_SRAM_DELSEL_CON1 0x04f4
157#define AFE_ASRC_CON0 0x0500
158#define AFE_ASRC_CON1 0x0504
159#define AFE_ASRC_CON2 0x0508
160#define AFE_ASRC_CON3 0x050c
161#define AFE_ASRC_CON4 0x0510
162#define AFE_ASRC_CON5 0x0514
163#define AFE_ASRC_CON6 0x0518
164#define AFE_ASRC_CON7 0x051c
165#define AFE_ASRC_CON8 0x0520
166#define AFE_ASRC_CON9 0x0524
167#define AFE_ASRC_CON10 0x0528
168#define AFE_ASRC_CON11 0x052c
169#define PCM_INTF_CON1 0x0530
170#define PCM_INTF_CON2 0x0538
171#define PCM2_INTF_CON 0x053c
172#define AFE_TDM_CON1 0x0548
173#define AFE_TDM_CON2 0x054c
174#define AFE_ASRC_CON13 0x0550
175#define AFE_ASRC_CON14 0x0554
176#define AFE_ASRC_CON15 0x0558
177#define AFE_ASRC_CON16 0x055c
178#define AFE_ASRC_CON17 0x0560
179#define AFE_ASRC_CON18 0x0564
180#define AFE_ASRC_CON19 0x0568
181#define AFE_ASRC_CON20 0x056c
182#define AFE_ASRC_CON21 0x0570
183#define CLK_AUDDIV_0 0x05a0
184#define CLK_AUDDIV_1 0x05a4
185#define CLK_AUDDIV_2 0x05a8
186#define CLK_AUDDIV_3 0x05ac
187#define AUDIO_TOP_DBG_CON 0x05c8
188#define AUDIO_TOP_DBG_MON0 0x05cc
189#define AUDIO_TOP_DBG_MON1 0x05d0
190#define AUDIO_TOP_DBG_MON2 0x05d4
191#define AFE_ADDA2_TOP_CON0 0x0600
192#define AFE_ASRC4_CON0 0x06c0
193#define AFE_ASRC4_CON1 0x06c4
194#define AFE_ASRC4_CON2 0x06c8
195#define AFE_ASRC4_CON3 0x06cc
196#define AFE_ASRC4_CON4 0x06d0
197#define AFE_ASRC4_CON5 0x06d4
198#define AFE_ASRC4_CON6 0x06d8
199#define AFE_ASRC4_CON7 0x06dc
200#define AFE_ASRC4_CON8 0x06e0
201#define AFE_ASRC4_CON9 0x06e4
202#define AFE_ASRC4_CON10 0x06e8
203#define AFE_ASRC4_CON11 0x06ec
204#define AFE_ASRC4_CON12 0x06f0
205#define AFE_ASRC4_CON13 0x06f4
206#define AFE_ASRC4_CON14 0x06f8
207#define AFE_ASRC2_CON0 0x0700
208#define AFE_ASRC2_CON1 0x0704
209#define AFE_ASRC2_CON2 0x0708
210#define AFE_ASRC2_CON3 0x070c
211#define AFE_ASRC2_CON4 0x0710
212#define AFE_ASRC2_CON5 0x0714
213#define AFE_ASRC2_CON6 0x0718
214#define AFE_ASRC2_CON7 0x071c
215#define AFE_ASRC2_CON8 0x0720
216#define AFE_ASRC2_CON9 0x0724
217#define AFE_ASRC2_CON10 0x0728
218#define AFE_ASRC2_CON11 0x072c
219#define AFE_ASRC2_CON12 0x0730
220#define AFE_ASRC2_CON13 0x0734
221#define AFE_ASRC2_CON14 0x0738
222#define AFE_ASRC3_CON0 0x0740
223#define AFE_ASRC3_CON1 0x0744
224#define AFE_ASRC3_CON2 0x0748
225#define AFE_ASRC3_CON3 0x074c
226#define AFE_ASRC3_CON4 0x0750
227#define AFE_ASRC3_CON5 0x0754
228#define AFE_ASRC3_CON6 0x0758
229#define AFE_ASRC3_CON7 0x075c
230#define AFE_ASRC3_CON8 0x0760
231#define AFE_ASRC3_CON9 0x0764
232#define AFE_ASRC3_CON10 0x0768
233#define AFE_ASRC3_CON11 0x076c
234#define AFE_ASRC3_CON12 0x0770
235#define AFE_ASRC3_CON13 0x0774
236#define AFE_ASRC3_CON14 0x0778
237#define AFE_GENERAL_REG0 0x0800
238#define AFE_GENERAL_REG1 0x0804
239#define AFE_GENERAL_REG2 0x0808
240#define AFE_GENERAL_REG3 0x080c
241#define AFE_GENERAL_REG4 0x0810
242#define AFE_GENERAL_REG5 0x0814
243#define AFE_GENERAL_REG6 0x0818
244#define AFE_GENERAL_REG7 0x081c
245#define AFE_GENERAL_REG8 0x0820
246#define AFE_GENERAL_REG9 0x0824
247#define AFE_GENERAL_REG10 0x0828
248#define AFE_GENERAL_REG11 0x082c
249#define AFE_GENERAL_REG12 0x0830
250#define AFE_GENERAL_REG13 0x0834
251#define AFE_GENERAL_REG14 0x0838
252#define AFE_GENERAL_REG15 0x083c
253#define AFE_CBIP_CFG0 0x0840
254#define AFE_CBIP_MON0 0x0844
255#define AFE_CBIP_SLV_MUX_MON0 0x0848
256#define AFE_CBIP_SLV_DECODER_MON0 0x084c
257
258#define AFE_MAX_REGISTER AFE_CBIP_SLV_DECODER_MON0
259#define AFE_IRQ_STATUS_BITS 0x5f
260
261/* AUDIO_TOP_CON0 */
262#define AHB_IDLE_EN_INT_SFT 30
263#define AHB_IDLE_EN_INT_MASK 0x1
264#define AHB_IDLE_EN_INT_MASK_SFT (0x1 << 30)
265#define AHB_IDLE_EN_EXT_SFT 29
266#define AHB_IDLE_EN_EXT_MASK 0x1
267#define AHB_IDLE_EN_EXT_MASK_SFT (0x1 << 29)
268#define PDN_TML_SFT 27
269#define PDN_TML_MASK 0x1
270#define PDN_TML_MASK_SFT (0x1 << 27)
271#define PDN_DAC_PREDIS_SFT 26
272#define PDN_DAC_PREDIS_MASK 0x1
273#define PDN_DAC_PREDIS_MASK_SFT (0x1 << 26)
274#define PDN_DAC_SFT 25
275#define PDN_DAC_MASK 0x1
276#define PDN_DAC_MASK_SFT (0x1 << 25)
277#define PDN_ADC_SFT 24
278#define PDN_ADC_MASK 0x1
279#define PDN_ADC_MASK_SFT (0x1 << 24)
280#define PDN_TDM_CK_SFT 20
281#define PDN_TDM_CK_MASK 0x1
282#define PDN_TDM_CK_MASK_SFT (0x1 << 20)
283#define PDN_APLL_TUNER_SFT 19
284#define PDN_APLL_TUNER_MASK 0x1
285#define PDN_APLL_TUNER_MASK_SFT (0x1 << 19)
286#define PDN_APLL2_TUNER_SFT 18
287#define PDN_APLL2_TUNER_MASK 0x1
288#define PDN_APLL2_TUNER_MASK_SFT (0x1 << 18)
289#define APB3_SEL_SFT 14
290#define APB3_SEL_MASK 0x1
291#define APB3_SEL_MASK_SFT (0x1 << 14)
292#define APB_R2T_SFT 13
293#define APB_R2T_MASK 0x1
294#define APB_R2T_MASK_SFT (0x1 << 13)
295#define APB_W2T_SFT 12
296#define APB_W2T_MASK 0x1
297#define APB_W2T_MASK_SFT (0x1 << 12)
298#define PDN_24M_SFT 9
299#define PDN_24M_MASK 0x1
300#define PDN_24M_MASK_SFT (0x1 << 9)
301#define PDN_22M_SFT 8
302#define PDN_22M_MASK 0x1
303#define PDN_22M_MASK_SFT (0x1 << 8)
304#define PDN_ADDA4_ADC_SFT 7
305#define PDN_ADDA4_ADC_MASK 0x1
306#define PDN_ADDA4_ADC_MASK_SFT (0x1 << 7)
307#define PDN_I2S_SFT 6
308#define PDN_I2S_MASK 0x1
309#define PDN_I2S_MASK_SFT (0x1 << 6)
310#define PDN_AFE_SFT 2
311#define PDN_AFE_MASK 0x1
312#define PDN_AFE_MASK_SFT (0x1 << 2)
313
314/* AUDIO_TOP_CON1 */
315#define PDN_ADC_HIRES_TML_SFT 17
316#define PDN_ADC_HIRES_TML_MASK 0x1
317#define PDN_ADC_HIRES_TML_MASK_SFT (0x1 << 17)
318#define PDN_ADC_HIRES_SFT 16
319#define PDN_ADC_HIRES_MASK 0x1
320#define PDN_ADC_HIRES_MASK_SFT (0x1 << 16)
321#define I2S4_BCLK_SW_CG_SFT 7
322#define I2S4_BCLK_SW_CG_MASK 0x1
323#define I2S4_BCLK_SW_CG_MASK_SFT (0x1 << 7)
324#define I2S3_BCLK_SW_CG_SFT 6
325#define I2S3_BCLK_SW_CG_MASK 0x1
326#define I2S3_BCLK_SW_CG_MASK_SFT (0x1 << 6)
327#define I2S2_BCLK_SW_CG_SFT 5
328#define I2S2_BCLK_SW_CG_MASK 0x1
329#define I2S2_BCLK_SW_CG_MASK_SFT (0x1 << 5)
330#define I2S1_BCLK_SW_CG_SFT 4
331#define I2S1_BCLK_SW_CG_MASK 0x1
332#define I2S1_BCLK_SW_CG_MASK_SFT (0x1 << 4)
333#define I2S_SOFT_RST2_SFT 2
334#define I2S_SOFT_RST2_MASK 0x1
335#define I2S_SOFT_RST2_MASK_SFT (0x1 << 2)
336#define I2S_SOFT_RST_SFT 1
337#define I2S_SOFT_RST_MASK 0x1
338#define I2S_SOFT_RST_MASK_SFT (0x1 << 1)
339
340/* AFE_DAC_CON0 */
341#define AFE_AWB_RETM_SFT 31
342#define AFE_AWB_RETM_MASK 0x1
343#define AFE_AWB_RETM_MASK_SFT (0x1 << 31)
344#define AFE_DL1_DATA2_RETM_SFT 30
345#define AFE_DL1_DATA2_RETM_MASK 0x1
346#define AFE_DL1_DATA2_RETM_MASK_SFT (0x1 << 30)
347#define AFE_DL2_RETM_SFT 29
348#define AFE_DL2_RETM_MASK 0x1
349#define AFE_DL2_RETM_MASK_SFT (0x1 << 29)
350#define AFE_DL1_RETM_SFT 28
351#define AFE_DL1_RETM_MASK 0x1
352#define AFE_DL1_RETM_MASK_SFT (0x1 << 28)
353#define AFE_ON_RETM_SFT 27
354#define AFE_ON_RETM_MASK 0x1
355#define AFE_ON_RETM_MASK_SFT (0x1 << 27)
356#define MOD_DAI_DUP_WR_SFT 26
357#define MOD_DAI_DUP_WR_MASK 0x1
358#define MOD_DAI_DUP_WR_MASK_SFT (0x1 << 26)
359#define DAI_MODE_SFT 24
360#define DAI_MODE_MASK 0x3
361#define DAI_MODE_MASK_SFT (0x3 << 24)
362#define VUL_DATA2_MODE_SFT 20
363#define VUL_DATA2_MODE_MASK 0xf
364#define VUL_DATA2_MODE_MASK_SFT (0xf << 20)
365#define DL1_DATA2_MODE_SFT 16
366#define DL1_DATA2_MODE_MASK 0xf
367#define DL1_DATA2_MODE_MASK_SFT (0xf << 16)
368#define DL3_MODE_SFT 12
369#define DL3_MODE_MASK 0xf
370#define DL3_MODE_MASK_SFT (0xf << 12)
371#define VUL_DATA2_R_MONO_SFT 11
372#define VUL_DATA2_R_MONO_MASK 0x1
373#define VUL_DATA2_R_MONO_MASK_SFT (0x1 << 11)
374#define VUL_DATA2_DATA_SFT 10
375#define VUL_DATA2_DATA_MASK 0x1
376#define VUL_DATA2_DATA_MASK_SFT (0x1 << 10)
377#define VUL_DATA2_ON_SFT 9
378#define VUL_DATA2_ON_MASK 0x1
379#define VUL_DATA2_ON_MASK_SFT (0x1 << 9)
380#define DL1_DATA2_ON_SFT 8
381#define DL1_DATA2_ON_MASK 0x1
382#define DL1_DATA2_ON_MASK_SFT (0x1 << 8)
383#define MOD_DAI_ON_SFT 7
384#define MOD_DAI_ON_MASK 0x1
385#define MOD_DAI_ON_MASK_SFT (0x1 << 7)
386#define AWB_ON_SFT 6
387#define AWB_ON_MASK 0x1
388#define AWB_ON_MASK_SFT (0x1 << 6)
389#define DL3_ON_SFT 5
390#define DL3_ON_MASK 0x1
391#define DL3_ON_MASK_SFT (0x1 << 5)
392#define DAI_ON_SFT 4
393#define DAI_ON_MASK 0x1
394#define DAI_ON_MASK_SFT (0x1 << 4)
395#define VUL_ON_SFT 3
396#define VUL_ON_MASK 0x1
397#define VUL_ON_MASK_SFT (0x1 << 3)
398#define DL2_ON_SFT 2
399#define DL2_ON_MASK 0x1
400#define DL2_ON_MASK_SFT (0x1 << 2)
401#define DL1_ON_SFT 1
402#define DL1_ON_MASK 0x1
403#define DL1_ON_MASK_SFT (0x1 << 1)
404#define AFE_ON_SFT 0
405#define AFE_ON_MASK 0x1
406#define AFE_ON_MASK_SFT (0x1 << 0)
407
408/* AFE_DAC_CON1 */
409#define MOD_DAI_MODE_SFT 30
410#define MOD_DAI_MODE_MASK 0x3
411#define MOD_DAI_MODE_MASK_SFT (0x3 << 30)
412#define DAI_DUP_WR_SFT 29
413#define DAI_DUP_WR_MASK 0x1
414#define DAI_DUP_WR_MASK_SFT (0x1 << 29)
415#define VUL_R_MONO_SFT 28
416#define VUL_R_MONO_MASK 0x1
417#define VUL_R_MONO_MASK_SFT (0x1 << 28)
418#define VUL_DATA_SFT 27
419#define VUL_DATA_MASK 0x1
420#define VUL_DATA_MASK_SFT (0x1 << 27)
421#define AXI_2X1_CG_DISABLE_SFT 26
422#define AXI_2X1_CG_DISABLE_MASK 0x1
423#define AXI_2X1_CG_DISABLE_MASK_SFT (0x1 << 26)
424#define AWB_R_MONO_SFT 25
425#define AWB_R_MONO_MASK 0x1
426#define AWB_R_MONO_MASK_SFT (0x1 << 25)
427#define AWB_DATA_SFT 24
428#define AWB_DATA_MASK 0x1
429#define AWB_DATA_MASK_SFT (0x1 << 24)
430#define DL3_DATA_SFT 23
431#define DL3_DATA_MASK 0x1
432#define DL3_DATA_MASK_SFT (0x1 << 23)
433#define DL2_DATA_SFT 22
434#define DL2_DATA_MASK 0x1
435#define DL2_DATA_MASK_SFT (0x1 << 22)
436#define DL1_DATA_SFT 21
437#define DL1_DATA_MASK 0x1
438#define DL1_DATA_MASK_SFT (0x1 << 21)
439#define DL1_DATA2_DATA_SFT 20
440#define DL1_DATA2_DATA_MASK 0x1
441#define DL1_DATA2_DATA_MASK_SFT (0x1 << 20)
442#define VUL_MODE_SFT 16
443#define VUL_MODE_MASK 0xf
444#define VUL_MODE_MASK_SFT (0xf << 16)
445#define AWB_MODE_SFT 12
446#define AWB_MODE_MASK 0xf
447#define AWB_MODE_MASK_SFT (0xf << 12)
448#define I2S_MODE_SFT 8
449#define I2S_MODE_MASK 0xf
450#define I2S_MODE_MASK_SFT (0xf << 8)
451#define DL2_MODE_SFT 4
452#define DL2_MODE_MASK 0xf
453#define DL2_MODE_MASK_SFT (0xf << 4)
454#define DL1_MODE_SFT 0
455#define DL1_MODE_MASK 0xf
456#define DL1_MODE_MASK_SFT (0xf << 0)
457
458/* AFE_ADDA_DL_SRC2_CON0 */
459#define DL_2_INPUT_MODE_CTL_SFT 28
460#define DL_2_INPUT_MODE_CTL_MASK 0xf
461#define DL_2_INPUT_MODE_CTL_MASK_SFT (0xf << 28)
462#define DL_2_CH1_SATURATION_EN_CTL_SFT 27
463#define DL_2_CH1_SATURATION_EN_CTL_MASK 0x1
464#define DL_2_CH1_SATURATION_EN_CTL_MASK_SFT (0x1 << 27)
465#define DL_2_CH2_SATURATION_EN_CTL_SFT 26
466#define DL_2_CH2_SATURATION_EN_CTL_MASK 0x1
467#define DL_2_CH2_SATURATION_EN_CTL_MASK_SFT (0x1 << 26)
468#define DL_2_OUTPUT_SEL_CTL_SFT 24
469#define DL_2_OUTPUT_SEL_CTL_MASK 0x3
470#define DL_2_OUTPUT_SEL_CTL_MASK_SFT (0x3 << 24)
471#define DL_2_FADEIN_0START_EN_SFT 16
472#define DL_2_FADEIN_0START_EN_MASK 0x3
473#define DL_2_FADEIN_0START_EN_MASK_SFT (0x3 << 16)
474#define DL_DISABLE_HW_CG_CTL_SFT 15
475#define DL_DISABLE_HW_CG_CTL_MASK 0x1
476#define DL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 15)
477#define C_DATA_EN_SEL_CTL_PRE_SFT 14
478#define C_DATA_EN_SEL_CTL_PRE_MASK 0x1
479#define C_DATA_EN_SEL_CTL_PRE_MASK_SFT (0x1 << 14)
480#define DL_2_SIDE_TONE_ON_CTL_PRE_SFT 13
481#define DL_2_SIDE_TONE_ON_CTL_PRE_MASK 0x1
482#define DL_2_SIDE_TONE_ON_CTL_PRE_MASK_SFT (0x1 << 13)
483#define DL_2_MUTE_CH1_OFF_CTL_PRE_SFT 12
484#define DL_2_MUTE_CH1_OFF_CTL_PRE_MASK 0x1
485#define DL_2_MUTE_CH1_OFF_CTL_PRE_MASK_SFT (0x1 << 12)
486#define DL_2_MUTE_CH2_OFF_CTL_PRE_SFT 11
487#define DL_2_MUTE_CH2_OFF_CTL_PRE_MASK 0x1
488#define DL_2_MUTE_CH2_OFF_CTL_PRE_MASK_SFT (0x1 << 11)
489#define DL2_ARAMPSP_CTL_PRE_SFT 9
490#define DL2_ARAMPSP_CTL_PRE_MASK 0x3
491#define DL2_ARAMPSP_CTL_PRE_MASK_SFT (0x3 << 9)
492#define DL_2_IIRMODE_CTL_PRE_SFT 6
493#define DL_2_IIRMODE_CTL_PRE_MASK 0x7
494#define DL_2_IIRMODE_CTL_PRE_MASK_SFT (0x7 << 6)
495#define DL_2_VOICE_MODE_CTL_PRE_SFT 5
496#define DL_2_VOICE_MODE_CTL_PRE_MASK 0x1
497#define DL_2_VOICE_MODE_CTL_PRE_MASK_SFT (0x1 << 5)
498#define D2_2_MUTE_CH1_ON_CTL_PRE_SFT 4
499#define D2_2_MUTE_CH1_ON_CTL_PRE_MASK 0x1
500#define D2_2_MUTE_CH1_ON_CTL_PRE_MASK_SFT (0x1 << 4)
501#define D2_2_MUTE_CH2_ON_CTL_PRE_SFT 3
502#define D2_2_MUTE_CH2_ON_CTL_PRE_MASK 0x1
503#define D2_2_MUTE_CH2_ON_CTL_PRE_MASK_SFT (0x1 << 3)
504#define DL_2_IIR_ON_CTL_PRE_SFT 2
505#define DL_2_IIR_ON_CTL_PRE_MASK 0x1
506#define DL_2_IIR_ON_CTL_PRE_MASK_SFT (0x1 << 2)
507#define DL_2_GAIN_ON_CTL_PRE_SFT 1
508#define DL_2_GAIN_ON_CTL_PRE_MASK 0x1
509#define DL_2_GAIN_ON_CTL_PRE_MASK_SFT (0x1 << 1)
510#define DL_2_SRC_ON_TMP_CTL_PRE_SFT 0
511#define DL_2_SRC_ON_TMP_CTL_PRE_MASK 0x1
512#define DL_2_SRC_ON_TMP_CTL_PRE_MASK_SFT (0x1 << 0)
513
514/* AFE_ADDA_DL_SRC2_CON1 */
515#define DL_2_GAIN_CTL_PRE_SFT 16
516#define DL_2_GAIN_CTL_PRE_MASK 0xffff
517#define DL_2_GAIN_CTL_PRE_MASK_SFT (0xffff << 16)
518#define DL_2_GAIN_MODE_CTL_SFT 0
519#define DL_2_GAIN_MODE_CTL_MASK 0x1
520#define DL_2_GAIN_MODE_CTL_MASK_SFT (0x1 << 0)
521
522/* AFE_ADDA_UL_SRC_CON0 */
523#define C_COMB_OUT_SIN_GEN_CTL_SFT 31
524#define C_COMB_OUT_SIN_GEN_CTL_MASK 0x1
525#define C_COMB_OUT_SIN_GEN_CTL_MASK_SFT (0x1 << 31)
526#define C_BASEBAND_SIN_GEN_CTL_SFT 30
527#define C_BASEBAND_SIN_GEN_CTL_MASK 0x1
528#define C_BASEBAND_SIN_GEN_CTL_MASK_SFT (0x1 << 30)
529#define C_DIGMIC_PHASE_SEL_CH1_CTL_SFT 27
530#define C_DIGMIC_PHASE_SEL_CH1_CTL_MASK 0x7
531#define C_DIGMIC_PHASE_SEL_CH1_CTL_MASK_SFT (0x7 << 27)
532#define C_DIGMIC_PHASE_SEL_CH2_CTL_SFT 24
533#define C_DIGMIC_PHASE_SEL_CH2_CTL_MASK 0x7
534#define C_DIGMIC_PHASE_SEL_CH2_CTL_MASK_SFT (0x7 << 24)
535#define C_TWO_DIGITAL_MIC_CTL_SFT 23
536#define C_TWO_DIGITAL_MIC_CTL_MASK 0x1
537#define C_TWO_DIGITAL_MIC_CTL_MASK_SFT (0x1 << 23)
538#define UL_MODE_3P25M_CH2_CTL_SFT 22
539#define UL_MODE_3P25M_CH2_CTL_MASK 0x1
540#define UL_MODE_3P25M_CH2_CTL_MASK_SFT (0x1 << 22)
541#define UL_MODE_3P25M_CH1_CTL_SFT 21
542#define UL_MODE_3P25M_CH1_CTL_MASK 0x1
543#define UL_MODE_3P25M_CH1_CTL_MASK_SFT (0x1 << 21)
544#define UL_SRC_USE_CIC_OUT_CTL_SFT 20
545#define UL_SRC_USE_CIC_OUT_CTL_MASK 0x1
546#define UL_SRC_USE_CIC_OUT_CTL_MASK_SFT (0x1 << 20)
547#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17
548#define UL_VOICE_MODE_CH1_CH2_CTL_MASK 0x7
549#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT (0x7 << 17)
550#define DMIC_LOW_POWER_MODE_CTL_SFT 14
551#define DMIC_LOW_POWER_MODE_CTL_MASK 0x3
552#define DMIC_LOW_POWER_MODE_CTL_MASK_SFT (0x3 << 14)
553#define DMIC_48K_SEL_CTL_SFT 13
554#define DMIC_48K_SEL_CTL_MASK 0x1
555#define DMIC_48K_SEL_CTL_MASK_SFT (0x1 << 13)
556#define UL_DISABLE_HW_CG_CTL_SFT 12
557#define UL_DISABLE_HW_CG_CTL_MASK 0x1
558#define UL_DISABLE_HW_CG_CTL_MASK_SFT (0x1 << 12)
559#define UL_IIR_ON_TMP_CTL_SFT 10
560#define UL_IIR_ON_TMP_CTL_MASK 0x1
561#define UL_IIR_ON_TMP_CTL_MASK_SFT (0x1 << 10)
562#define UL_IIRMODE_CTL_SFT 7
563#define UL_IIRMODE_CTL_MASK 0x7
564#define UL_IIRMODE_CTL_MASK_SFT (0x7 << 7)
565#define DIGMIC_3P25M_1P625M_SEL_CTL_SFT 5
566#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK 0x1
567#define DIGMIC_3P25M_1P625M_SEL_CTL_MASK_SFT (0x1 << 5)
568#define AGC_260K_SEL_CH2_CTL_SFT 4
569#define AGC_260K_SEL_CH2_CTL_MASK 0x1
570#define AGC_260K_SEL_CH2_CTL_MASK_SFT (0x1 << 4)
571#define AGC_260K_SEL_CH1_CTL_SFT 3
572#define AGC_260K_SEL_CH1_CTL_MASK 0x1
573#define AGC_260K_SEL_CH1_CTL_MASK_SFT (0x1 << 3)
574#define UL_LOOP_BACK_MODE_CTL_SFT 2
575#define UL_LOOP_BACK_MODE_CTL_MASK 0x1
576#define UL_LOOP_BACK_MODE_CTL_MASK_SFT (0x1 << 2)
577#define UL_SDM_3_LEVEL_CTL_SFT 1
578#define UL_SDM_3_LEVEL_CTL_MASK 0x1
579#define UL_SDM_3_LEVEL_CTL_MASK_SFT (0x1 << 1)
580#define UL_SRC_ON_TMP_CTL_SFT 0
581#define UL_SRC_ON_TMP_CTL_MASK 0x1
582#define UL_SRC_ON_TMP_CTL_MASK_SFT (0x1 << 0)
583
584/* AFE_ADDA_UL_SRC_CON1 */
585#define C_SDM_RESET_CTL_SFT 31
586#define C_SDM_RESET_CTL_MASK 0x1
587#define C_SDM_RESET_CTL_MASK_SFT (0x1 << 31)
588#define ADITHON_CTL_SFT 30
589#define ADITHON_CTL_MASK 0x1
590#define ADITHON_CTL_MASK_SFT (0x1 << 30)
591#define ADITHVAL_CTL_SFT 28
592#define ADITHVAL_CTL_MASK 0x3
593#define ADITHVAL_CTL_MASK_SFT (0x3 << 28)
594#define C_DAC_EN_CTL_SFT 27
595#define C_DAC_EN_CTL_MASK 0x1
596#define C_DAC_EN_CTL_MASK_SFT (0x1 << 27)
597#define C_MUTE_SW_CTL_SFT 26
598#define C_MUTE_SW_CTL_MASK 0x1
599#define C_MUTE_SW_CTL_MASK_SFT (0x1 << 26)
600#define ASDM_SRC_SEL_CTL_SFT 25
601#define ASDM_SRC_SEL_CTL_MASK 0x1
602#define ASDM_SRC_SEL_CTL_MASK_SFT (0x1 << 25)
603#define C_AMP_DIV_CH2_CTL_SFT 21
604#define C_AMP_DIV_CH2_CTL_MASK 0x7
605#define C_AMP_DIV_CH2_CTL_MASK_SFT (0x7 << 21)
606#define C_FREQ_DIV_CH2_CTL_SFT 16
607#define C_FREQ_DIV_CH2_CTL_MASK 0x1f
608#define C_FREQ_DIV_CH2_CTL_MASK_SFT (0x1f << 16)
609#define C_SINE_MODE_CH2_CTL_SFT 12
610#define C_SINE_MODE_CH2_CTL_MASK 0xf
611#define C_SINE_MODE_CH2_CTL_MASK_SFT (0xf << 12)
612#define C_AMP_DIV_CH1_CTL_SFT 9
613#define C_AMP_DIV_CH1_CTL_MASK 0x7
614#define C_AMP_DIV_CH1_CTL_MASK_SFT (0x7 << 9)
615#define C_FREQ_DIV_CH1_CTL_SFT 4
616#define C_FREQ_DIV_CH1_CTL_MASK 0x1f
617#define C_FREQ_DIV_CH1_CTL_MASK_SFT (0x1f << 4)
618#define C_SINE_MODE_CH1_CTL_SFT 0
619#define C_SINE_MODE_CH1_CTL_MASK 0xf
620#define C_SINE_MODE_CH1_CTL_MASK_SFT (0xf << 0)
621
622/* AFE_ADDA_TOP_CON0 */
623#define C_LOOP_BACK_MODE_CTL_SFT 12
624#define C_LOOP_BACK_MODE_CTL_MASK 0xf
625#define C_LOOP_BACK_MODE_CTL_MASK_SFT (0xf << 12)
626#define C_EXT_ADC_CTL_SFT 0
627#define C_EXT_ADC_CTL_MASK 0x1
628#define C_EXT_ADC_CTL_MASK_SFT (0x1 << 0)
629
630/* AFE_ADDA_UL_DL_CON0 */
631#define AFE_UL_DL_CON0_RESERVED_SFT 1
632#define AFE_UL_DL_CON0_RESERVED_MASK 0x3fff
633#define AFE_UL_DL_CON0_RESERVED_MASK_SFT (0x3fff << 1)
634#define ADDA_AFE_ON_SFT 0
635#define ADDA_AFE_ON_MASK 0x1
636#define ADDA_AFE_ON_MASK_SFT (0x1 << 0)
637
638/* AFE_IRQ_MCU_CON */
639#define IRQ7_MCU_MODE_SFT 24
640#define IRQ7_MCU_MODE_MASK 0xf
641#define IRQ7_MCU_MODE_MASK_SFT (0xf << 24)
642#define IRQ4_MCU_MODE_SFT 20
643#define IRQ4_MCU_MODE_MASK 0xf
644#define IRQ4_MCU_MODE_MASK_SFT (0xf << 20)
645#define IRQ3_MCU_MODE_SFT 16
646#define IRQ3_MCU_MODE_MASK 0xf
647#define IRQ3_MCU_MODE_MASK_SFT (0xf << 16)
648#define IRQ7_MCU_ON_SFT 14
649#define IRQ7_MCU_ON_MASK 0x1
650#define IRQ7_MCU_ON_MASK_SFT (0x1 << 14)
651#define IRQ5_MCU_ON_SFT 12
652#define IRQ5_MCU_ON_MASK 0x1
653#define IRQ5_MCU_ON_MASK_SFT (0x1 << 12)
654#define IRQ2_MCU_MODE_SFT 8
655#define IRQ2_MCU_MODE_MASK 0xf
656#define IRQ2_MCU_MODE_MASK_SFT (0xf << 8)
657#define IRQ1_MCU_MODE_SFT 4
658#define IRQ1_MCU_MODE_MASK 0xf
659#define IRQ1_MCU_MODE_MASK_SFT (0xf << 4)
660#define IRQ4_MCU_ON_SFT 3
661#define IRQ4_MCU_ON_MASK 0x1
662#define IRQ4_MCU_ON_MASK_SFT (0x1 << 3)
663#define IRQ3_MCU_ON_SFT 2
664#define IRQ3_MCU_ON_MASK 0x1
665#define IRQ3_MCU_ON_MASK_SFT (0x1 << 2)
666#define IRQ2_MCU_ON_SFT 1
667#define IRQ2_MCU_ON_MASK 0x1
668#define IRQ2_MCU_ON_MASK_SFT (0x1 << 1)
669#define IRQ1_MCU_ON_SFT 0
670#define IRQ1_MCU_ON_MASK 0x1
671#define IRQ1_MCU_ON_MASK_SFT (0x1 << 0)
672
673/* AFE_IRQ_MCU_EN */
674#define AFE_IRQ_CM4_EN_SFT 16
675#define AFE_IRQ_CM4_EN_MASK 0x7f
676#define AFE_IRQ_CM4_EN_MASK_SFT (0x7f << 16)
677#define AFE_IRQ_MD32_EN_SFT 8
678#define AFE_IRQ_MD32_EN_MASK 0x7f
679#define AFE_IRQ_MD32_EN_MASK_SFT (0x7f << 8)
680#define AFE_IRQ_MCU_EN_SFT 0
681#define AFE_IRQ_MCU_EN_MASK 0x7f
682#define AFE_IRQ_MCU_EN_MASK_SFT (0x7f << 0)
683
684/* AFE_IRQ_MCU_CLR */
685#define IRQ7_MCU_CLR_SFT 6
686#define IRQ7_MCU_CLR_MASK 0x1
687#define IRQ7_MCU_CLR_MASK_SFT (0x1 << 6)
688#define IRQ5_MCU_CLR_SFT 4
689#define IRQ5_MCU_CLR_MASK 0x1
690#define IRQ5_MCU_CLR_MASK_SFT (0x1 << 4)
691#define IRQ4_MCU_CLR_SFT 3
692#define IRQ4_MCU_CLR_MASK 0x1
693#define IRQ4_MCU_CLR_MASK_SFT (0x1 << 3)
694#define IRQ3_MCU_CLR_SFT 2
695#define IRQ3_MCU_CLR_MASK 0x1
696#define IRQ3_MCU_CLR_MASK_SFT (0x1 << 2)
697#define IRQ2_MCU_CLR_SFT 1
698#define IRQ2_MCU_CLR_MASK 0x1
699#define IRQ2_MCU_CLR_MASK_SFT (0x1 << 1)
700#define IRQ1_MCU_CLR_SFT 0
701#define IRQ1_MCU_CLR_MASK 0x1
702#define IRQ1_MCU_CLR_MASK_SFT (0x1 << 0)
703
704/* AFE_IRQ_MCU_CNT1 */
705#define AFE_IRQ_MCU_CNT1_SFT 0
706#define AFE_IRQ_MCU_CNT1_MASK 0x3ffff
707#define AFE_IRQ_MCU_CNT1_MASK_SFT (0x3ffff << 0)
708
709/* AFE_IRQ_MCU_CNT2 */
710#define AFE_IRQ_MCU_CNT2_SFT 0
711#define AFE_IRQ_MCU_CNT2_MASK 0x3ffff
712#define AFE_IRQ_MCU_CNT2_MASK_SFT (0x3ffff << 0)
713
714/* AFE_IRQ_MCU_CNT3 */
715#define AFE_IRQ_MCU_CNT3_SFT 0
716#define AFE_IRQ_MCU_CNT3_MASK 0x3ffff
717#define AFE_IRQ_MCU_CNT3_MASK_SFT (0x3ffff << 0)
718
719/* AFE_IRQ_MCU_CNT4 */
720#define AFE_IRQ_MCU_CNT4_SFT 0
721#define AFE_IRQ_MCU_CNT4_MASK 0x3ffff
722#define AFE_IRQ_MCU_CNT4_MASK_SFT (0x3ffff << 0)
723
724/* AFE_IRQ_MCU_CNT5 */
725#define AFE_IRQ_MCU_CNT5_SFT 0
726#define AFE_IRQ_MCU_CNT5_MASK 0x3ffff
727#define AFE_IRQ_MCU_CNT5_MASK_SFT (0x3ffff << 0)
728
729/* AFE_IRQ_MCU_CNT7 */
730#define AFE_IRQ_MCU_CNT7_SFT 0
731#define AFE_IRQ_MCU_CNT7_MASK 0x3ffff
732#define AFE_IRQ_MCU_CNT7_MASK_SFT (0x3ffff << 0)
733
734/* AFE_MEMIF_MSB */
735#define CPU_COMPACT_MODE_SFT 23
736#define CPU_COMPACT_MODE_MASK 0x1
737#define CPU_COMPACT_MODE_MASK_SFT (0x1 << 23)
738#define CPU_HD_ALIGN_SFT 22
739#define CPU_HD_ALIGN_MASK 0x1
740#define CPU_HD_ALIGN_MASK_SFT (0x1 << 22)
741
742/* AFE_MEMIF_HD_MODE */
743#define HDMI_HD_SFT 20
744#define HDMI_HD_MASK 0x3
745#define HDMI_HD_MASK_SFT (0x3 << 20)
746#define MOD_DAI_HD_SFT 18
747#define MOD_DAI_HD_MASK 0x3
748#define MOD_DAI_HD_MASK_SFT (0x3 << 18)
749#define DAI_HD_SFT 16
750#define DAI_HD_MASK 0x3
751#define DAI_HD_MASK_SFT (0x3 << 16)
752#define VUL_DATA2_HD_SFT 12
753#define VUL_DATA2_HD_MASK 0x3
754#define VUL_DATA2_HD_MASK_SFT (0x3 << 12)
755#define VUL_HD_SFT 10
756#define VUL_HD_MASK 0x3
757#define VUL_HD_MASK_SFT (0x3 << 10)
758#define AWB_HD_SFT 8
759#define AWB_HD_MASK 0x3
760#define AWB_HD_MASK_SFT (0x3 << 8)
761#define DL3_HD_SFT 6
762#define DL3_HD_MASK 0x3
763#define DL3_HD_MASK_SFT (0x3 << 6)
764#define DL2_HD_SFT 4
765#define DL2_HD_MASK 0x3
766#define DL2_HD_MASK_SFT (0x3 << 4)
767#define DL1_DATA2_HD_SFT 2
768#define DL1_DATA2_HD_MASK 0x3
769#define DL1_DATA2_HD_MASK_SFT (0x3 << 2)
770#define DL1_HD_SFT 0
771#define DL1_HD_MASK 0x3
772#define DL1_HD_MASK_SFT (0x3 << 0)
773
774/* AFE_MEMIF_HDALIGN */
775#define HDMI_NORMAL_MODE_SFT 26
776#define HDMI_NORMAL_MODE_MASK 0x1
777#define HDMI_NORMAL_MODE_MASK_SFT (0x1 << 26)
778#define MOD_DAI_NORMAL_MODE_SFT 25
779#define MOD_DAI_NORMAL_MODE_MASK 0x1
780#define MOD_DAI_NORMAL_MODE_MASK_SFT (0x1 << 25)
781#define DAI_NORMAL_MODE_SFT 24
782#define DAI_NORMAL_MODE_MASK 0x1
783#define DAI_NORMAL_MODE_MASK_SFT (0x1 << 24)
784#define VUL_DATA2_NORMAL_MODE_SFT 22
785#define VUL_DATA2_NORMAL_MODE_MASK 0x1
786#define VUL_DATA2_NORMAL_MODE_MASK_SFT (0x1 << 22)
787#define VUL_NORMAL_MODE_SFT 21
788#define VUL_NORMAL_MODE_MASK 0x1
789#define VUL_NORMAL_MODE_MASK_SFT (0x1 << 21)
790#define AWB_NORMAL_MODE_SFT 20
791#define AWB_NORMAL_MODE_MASK 0x1
792#define AWB_NORMAL_MODE_MASK_SFT (0x1 << 20)
793#define DL3_NORMAL_MODE_SFT 19
794#define DL3_NORMAL_MODE_MASK 0x1
795#define DL3_NORMAL_MODE_MASK_SFT (0x1 << 19)
796#define DL2_NORMAL_MODE_SFT 18
797#define DL2_NORMAL_MODE_MASK 0x1
798#define DL2_NORMAL_MODE_MASK_SFT (0x1 << 18)
799#define DL1_DATA2_NORMAL_MODE_SFT 17
800#define DL1_DATA2_NORMAL_MODE_MASK 0x1
801#define DL1_DATA2_NORMAL_MODE_MASK_SFT (0x1 << 17)
802#define DL1_NORMAL_MODE_SFT 16
803#define DL1_NORMAL_MODE_MASK 0x1
804#define DL1_NORMAL_MODE_MASK_SFT (0x1 << 16)
805#define HDMI_HD_ALIGN_SFT 10
806#define HDMI_HD_ALIGN_MASK 0x1
807#define HDMI_HD_ALIGN_MASK_SFT (0x1 << 10)
808#define MOD_DAI_HD_ALIGN_SFT 9
809#define MOD_DAI_HD_ALIGN_MASK 0x1
810#define MOD_DAI_HD_ALIGN_MASK_SFT (0x1 << 9)
811#define DAI_ALIGN_SFT 8
812#define DAI_ALIGN_MASK 0x1
813#define DAI_ALIGN_MASK_SFT (0x1 << 8)
814#define VUL2_HD_ALIGN_SFT 7
815#define VUL2_HD_ALIGN_MASK 0x1
816#define VUL2_HD_ALIGN_MASK_SFT (0x1 << 7)
817#define VUL_DATA2_HD_ALIGN_SFT 6
818#define VUL_DATA2_HD_ALIGN_MASK 0x1
819#define VUL_DATA2_HD_ALIGN_MASK_SFT (0x1 << 6)
820#define VUL_HD_ALIGN_SFT 5
821#define VUL_HD_ALIGN_MASK 0x1
822#define VUL_HD_ALIGN_MASK_SFT (0x1 << 5)
823#define AWB_HD_ALIGN_SFT 4
824#define AWB_HD_ALIGN_MASK 0x1
825#define AWB_HD_ALIGN_MASK_SFT (0x1 << 4)
826#define DL3_HD_ALIGN_SFT 3
827#define DL3_HD_ALIGN_MASK 0x1
828#define DL3_HD_ALIGN_MASK_SFT (0x1 << 3)
829#define DL2_HD_ALIGN_SFT 2
830#define DL2_HD_ALIGN_MASK 0x1
831#define DL2_HD_ALIGN_MASK_SFT (0x1 << 2)
832#define DL1_DATA2_HD_ALIGN_SFT 1
833#define DL1_DATA2_HD_ALIGN_MASK 0x1
834#define DL1_DATA2_HD_ALIGN_MASK_SFT (0x1 << 1)
835#define DL1_HD_ALIGN_SFT 0
836#define DL1_HD_ALIGN_MASK 0x1
837#define DL1_HD_ALIGN_MASK_SFT (0x1 << 0)
838
839/* PCM_INTF_CON1 */
840#define PCM_FIX_VALUE_SEL_SFT 31
841#define PCM_FIX_VALUE_SEL_MASK 0x1
842#define PCM_FIX_VALUE_SEL_MASK_SFT (0x1 << 31)
843#define PCM_BUFFER_LOOPBACK_SFT 30
844#define PCM_BUFFER_LOOPBACK_MASK 0x1
845#define PCM_BUFFER_LOOPBACK_MASK_SFT (0x1 << 30)
846#define PCM_PARALLEL_LOOPBACK_SFT 29
847#define PCM_PARALLEL_LOOPBACK_MASK 0x1
848#define PCM_PARALLEL_LOOPBACK_MASK_SFT (0x1 << 29)
849#define PCM_SERIAL_LOOPBACK_SFT 28
850#define PCM_SERIAL_LOOPBACK_MASK 0x1
851#define PCM_SERIAL_LOOPBACK_MASK_SFT (0x1 << 28)
852#define PCM_DAI_PCM_LOOPBACK_SFT 27
853#define PCM_DAI_PCM_LOOPBACK_MASK 0x1
854#define PCM_DAI_PCM_LOOPBACK_MASK_SFT (0x1 << 27)
855#define PCM_I2S_PCM_LOOPBACK_SFT 26
856#define PCM_I2S_PCM_LOOPBACK_MASK 0x1
857#define PCM_I2S_PCM_LOOPBACK_MASK_SFT (0x1 << 26)
858#define PCM_SYNC_DELSEL_SFT 25
859#define PCM_SYNC_DELSEL_MASK 0x1
860#define PCM_SYNC_DELSEL_MASK_SFT (0x1 << 25)
861#define PCM_TX_LR_SWAP_SFT 24
862#define PCM_TX_LR_SWAP_MASK 0x1
863#define PCM_TX_LR_SWAP_MASK_SFT (0x1 << 24)
864#define PCM_SYNC_OUT_INV_SFT 23
865#define PCM_SYNC_OUT_INV_MASK 0x1
866#define PCM_SYNC_OUT_INV_MASK_SFT (0x1 << 23)
867#define PCM_BCLK_OUT_INV_SFT 22
868#define PCM_BCLK_OUT_INV_MASK 0x1
869#define PCM_BCLK_OUT_INV_MASK_SFT (0x1 << 22)
870#define PCM_SYNC_IN_INV_SFT 21
871#define PCM_SYNC_IN_INV_MASK 0x1
872#define PCM_SYNC_IN_INV_MASK_SFT (0x1 << 21)
873#define PCM_BCLK_IN_INV_SFT 20
874#define PCM_BCLK_IN_INV_MASK 0x1
875#define PCM_BCLK_IN_INV_MASK_SFT (0x1 << 20)
876#define PCM_TX_LCH_RPT_SFT 19
877#define PCM_TX_LCH_RPT_MASK 0x1
878#define PCM_TX_LCH_RPT_MASK_SFT (0x1 << 19)
879#define PCM_VBT_16K_MODE_SFT 18
880#define PCM_VBT_16K_MODE_MASK 0x1
881#define PCM_VBT_16K_MODE_MASK_SFT (0x1 << 18)
882#define PCM_EXT_MODEM_SFT 17
883#define PCM_EXT_MODEM_MASK 0x1
884#define PCM_EXT_MODEM_MASK_SFT (0x1 << 17)
885#define PCM_24BIT_SFT 16
886#define PCM_24BIT_MASK 0x1
887#define PCM_24BIT_MASK_SFT (0x1 << 16)
888#define PCM_WLEN_SFT 14
889#define PCM_WLEN_MASK 0x3
890#define PCM_WLEN_MASK_SFT (0x3 << 14)
891#define PCM_SYNC_LENGTH_SFT 9
892#define PCM_SYNC_LENGTH_MASK 0x1f
893#define PCM_SYNC_LENGTH_MASK_SFT (0x1f << 9)
894#define PCM_SYNC_TYPE_SFT 8
895#define PCM_SYNC_TYPE_MASK 0x1
896#define PCM_SYNC_TYPE_MASK_SFT (0x1 << 8)
897#define PCM_BT_MODE_SFT 7
898#define PCM_BT_MODE_MASK 0x1
899#define PCM_BT_MODE_MASK_SFT (0x1 << 7)
900#define PCM_BYP_ASRC_SFT 6
901#define PCM_BYP_ASRC_MASK 0x1
902#define PCM_BYP_ASRC_MASK_SFT (0x1 << 6)
903#define PCM_SLAVE_SFT 5
904#define PCM_SLAVE_MASK 0x1
905#define PCM_SLAVE_MASK_SFT (0x1 << 5)
906#define PCM_MODE_SFT 3
907#define PCM_MODE_MASK 0x3
908#define PCM_MODE_MASK_SFT (0x3 << 3)
909#define PCM_FMT_SFT 1
910#define PCM_FMT_MASK 0x3
911#define PCM_FMT_MASK_SFT (0x3 << 1)
912#define PCM_EN_SFT 0
913#define PCM_EN_MASK 0x1
914#define PCM_EN_MASK_SFT (0x1 << 0)
915
916/* PCM_INTF_CON2 */
917#define PCM1_TX_FIFO_OV_SFT 31
918#define PCM1_TX_FIFO_OV_MASK 0x1
919#define PCM1_TX_FIFO_OV_MASK_SFT (0x1 << 31)
920#define PCM1_RX_FIFO_OV_SFT 30
921#define PCM1_RX_FIFO_OV_MASK 0x1
922#define PCM1_RX_FIFO_OV_MASK_SFT (0x1 << 30)
923#define PCM2_TX_FIFO_OV_SFT 29
924#define PCM2_TX_FIFO_OV_MASK 0x1
925#define PCM2_TX_FIFO_OV_MASK_SFT (0x1 << 29)
926#define PCM2_RX_FIFO_OV_SFT 28
927#define PCM2_RX_FIFO_OV_MASK 0x1
928#define PCM2_RX_FIFO_OV_MASK_SFT (0x1 << 28)
929#define PCM1_SYNC_GLITCH_SFT 27
930#define PCM1_SYNC_GLITCH_MASK 0x1
931#define PCM1_SYNC_GLITCH_MASK_SFT (0x1 << 27)
932#define PCM2_SYNC_GLITCH_SFT 26
933#define PCM2_SYNC_GLITCH_MASK 0x1
934#define PCM2_SYNC_GLITCH_MASK_SFT (0x1 << 26)
935#define PCM1_PCM2_LOOPBACK_SFT 15
936#define PCM1_PCM2_LOOPBACK_MASK 0x1
937#define PCM1_PCM2_LOOPBACK_MASK_SFT (0x1 << 15)
938#define DAI_PCM_LOOPBACK_CH_SFT 13
939#define DAI_PCM_LOOPBACK_CH_MASK 0x1
940#define DAI_PCM_LOOPBACK_CH_MASK_SFT (0x1 << 13)
941#define I2S_PCM_LOOPBACK_CH_SFT 12
942#define I2S_PCM_LOOPBACK_CH_MASK 0x1
943#define I2S_PCM_LOOPBACK_CH_MASK_SFT (0x1 << 12)
944#define PCM_USE_MD3_SFT 8
945#define PCM_USE_MD3_MASK 0x1
946#define PCM_USE_MD3_MASK_SFT (0x1 << 8)
947#define TX_FIX_VALUE_SFT 0
948#define TX_FIX_VALUE_MASK 0xff
949#define TX_FIX_VALUE_MASK_SFT (0xff << 0)
950
951/* PCM2_INTF_CON */
952#define PCM2_TX_FIX_VALUE_SFT 24
953#define PCM2_TX_FIX_VALUE_MASK 0xff
954#define PCM2_TX_FIX_VALUE_MASK_SFT (0xff << 24)
955#define PCM2_FIX_VALUE_SEL_SFT 23
956#define PCM2_FIX_VALUE_SEL_MASK 0x1
957#define PCM2_FIX_VALUE_SEL_MASK_SFT (0x1 << 23)
958#define PCM2_BUFFER_LOOPBACK_SFT 22
959#define PCM2_BUFFER_LOOPBACK_MASK 0x1
960#define PCM2_BUFFER_LOOPBACK_MASK_SFT (0x1 << 22)
961#define PCM2_PARALLEL_LOOPBACK_SFT 21
962#define PCM2_PARALLEL_LOOPBACK_MASK 0x1
963#define PCM2_PARALLEL_LOOPBACK_MASK_SFT (0x1 << 21)
964#define PCM2_SERIAL_LOOPBACK_SFT 20
965#define PCM2_SERIAL_LOOPBACK_MASK 0x1
966#define PCM2_SERIAL_LOOPBACK_MASK_SFT (0x1 << 20)
967#define PCM2_DAI_PCM_LOOPBACK_SFT 19
968#define PCM2_DAI_PCM_LOOPBACK_MASK 0x1
969#define PCM2_DAI_PCM_LOOPBACK_MASK_SFT (0x1 << 19)
970#define PCM2_I2S_PCM_LOOPBACK_SFT 18
971#define PCM2_I2S_PCM_LOOPBACK_MASK 0x1
972#define PCM2_I2S_PCM_LOOPBACK_MASK_SFT (0x1 << 18)
973#define PCM2_SYNC_DELSEL_SFT 17
974#define PCM2_SYNC_DELSEL_MASK 0x1
975#define PCM2_SYNC_DELSEL_MASK_SFT (0x1 << 17)
976#define PCM2_TX_LR_SWAP_SFT 16
977#define PCM2_TX_LR_SWAP_MASK 0x1
978#define PCM2_TX_LR_SWAP_MASK_SFT (0x1 << 16)
979#define PCM2_SYNC_IN_INV_SFT 15
980#define PCM2_SYNC_IN_INV_MASK 0x1
981#define PCM2_SYNC_IN_INV_MASK_SFT (0x1 << 15)
982#define PCM2_BCLK_IN_INV_SFT 14
983#define PCM2_BCLK_IN_INV_MASK 0x1
984#define PCM2_BCLK_IN_INV_MASK_SFT (0x1 << 14)
985#define PCM2_TX_LCH_RPT_SFT 13
986#define PCM2_TX_LCH_RPT_MASK 0x1
987#define PCM2_TX_LCH_RPT_MASK_SFT (0x1 << 13)
988#define PCM2_VBT_16K_MODE_SFT 12
989#define PCM2_VBT_16K_MODE_MASK 0x1
990#define PCM2_VBT_16K_MODE_MASK_SFT (0x1 << 12)
991#define PCM2_LOOPBACK_CH_SEL_SFT 10
992#define PCM2_LOOPBACK_CH_SEL_MASK 0x3
993#define PCM2_LOOPBACK_CH_SEL_MASK_SFT (0x3 << 10)
994#define PCM2_TX2_BT_MODE_SFT 8
995#define PCM2_TX2_BT_MODE_MASK 0x1
996#define PCM2_TX2_BT_MODE_MASK_SFT (0x1 << 8)
997#define PCM2_BT_MODE_SFT 7
998#define PCM2_BT_MODE_MASK 0x1
999#define PCM2_BT_MODE_MASK_SFT (0x1 << 7)
1000#define PCM2_AFIFO_SFT 6
1001#define PCM2_AFIFO_MASK 0x1
1002#define PCM2_AFIFO_MASK_SFT (0x1 << 6)
1003#define PCM2_WLEN_SFT 5
1004#define PCM2_WLEN_MASK 0x1
1005#define PCM2_WLEN_MASK_SFT (0x1 << 5)
1006#define PCM2_MODE_SFT 3
1007#define PCM2_MODE_MASK 0x3
1008#define PCM2_MODE_MASK_SFT (0x3 << 3)
1009#define PCM2_FMT_SFT 1
1010#define PCM2_FMT_MASK 0x3
1011#define PCM2_FMT_MASK_SFT (0x3 << 1)
1012#define PCM2_EN_SFT 0
1013#define PCM2_EN_MASK 0x1
1014#define PCM2_EN_MASK_SFT (0x1 << 0)
1015#endif
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
index 9a4837cc181a..396fe2355eea 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-common.h
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * mt8173_afe_common.h -- Mediatek 8173 audio driver common definitions 3 * mt8173_afe_common.h -- Mediatek 8173 audio driver common definitions
3 * 4 *
@@ -6,15 +7,6 @@
6 * Sascha Hauer <s.hauer@pengutronix.de> 7 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com> 8 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com> 9 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */ 10 */
19 11
20#ifndef _MT8173_AFE_COMMON_H_ 12#ifndef _MT8173_AFE_COMMON_H_
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 65d1433a0944..c0b6697503fd 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Mediatek 8173 ALSA SoC AFE platform driver 3 * Mediatek 8173 ALSA SoC AFE platform driver
3 * 4 *
@@ -6,15 +7,6 @@
6 * Sascha Hauer <s.hauer@pengutronix.de> 7 * Sascha Hauer <s.hauer@pengutronix.de>
7 * Hidalgo Huang <hidalgo.huang@mediatek.com> 8 * Hidalgo Huang <hidalgo.huang@mediatek.com>
8 * Ir Lian <ir.lian@mediatek.com> 9 * Ir Lian <ir.lian@mediatek.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 and
12 * only version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */ 10 */
19 11
20#include <linux/delay.h> 12#include <linux/delay.h>
@@ -303,9 +295,7 @@ static void mt8173_afe_dais_disable_clks(struct mtk_base_afe *afe,
303static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream, 295static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream,
304 struct snd_soc_dai *dai) 296 struct snd_soc_dai *dai)
305{ 297{
306 struct snd_soc_pcm_runtime *rtd = substream->private_data; 298 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
307 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
308 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
309 299
310 if (dai->active) 300 if (dai->active)
311 return 0; 301 return 0;
@@ -318,9 +308,7 @@ static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream,
318static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream, 308static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream,
319 struct snd_soc_dai *dai) 309 struct snd_soc_dai *dai)
320{ 310{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 311 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
322 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
323 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
324 312
325 if (dai->active) 313 if (dai->active)
326 return; 314 return;
@@ -334,10 +322,8 @@ static void mt8173_afe_i2s_shutdown(struct snd_pcm_substream *substream,
334static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream, 322static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream,
335 struct snd_soc_dai *dai) 323 struct snd_soc_dai *dai)
336{ 324{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_pcm_runtime * const runtime = substream->runtime; 325 struct snd_pcm_runtime * const runtime = substream->runtime;
339 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 326 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
340 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
341 struct mt8173_afe_private *afe_priv = afe->platform_priv; 327 struct mt8173_afe_private *afe_priv = afe->platform_priv;
342 int ret; 328 int ret;
343 329
@@ -358,9 +344,7 @@ static int mt8173_afe_i2s_prepare(struct snd_pcm_substream *substream,
358static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream, 344static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream,
359 struct snd_soc_dai *dai) 345 struct snd_soc_dai *dai)
360{ 346{
361 struct snd_soc_pcm_runtime *rtd = substream->private_data; 347 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
362 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
363 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
364 struct mt8173_afe_private *afe_priv = afe->platform_priv; 348 struct mt8173_afe_private *afe_priv = afe->platform_priv;
365 349
366 if (dai->active) 350 if (dai->active)
@@ -374,9 +358,7 @@ static int mt8173_afe_hdmi_startup(struct snd_pcm_substream *substream,
374static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream, 358static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
375 struct snd_soc_dai *dai) 359 struct snd_soc_dai *dai)
376{ 360{
377 struct snd_soc_pcm_runtime *rtd = substream->private_data; 361 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
378 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
379 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
380 struct mt8173_afe_private *afe_priv = afe->platform_priv; 362 struct mt8173_afe_private *afe_priv = afe->platform_priv;
381 363
382 if (dai->active) 364 if (dai->active)
@@ -389,10 +371,8 @@ static void mt8173_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
389static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream, 371static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream,
390 struct snd_soc_dai *dai) 372 struct snd_soc_dai *dai)
391{ 373{
392 struct snd_soc_pcm_runtime *rtd = substream->private_data;
393 struct snd_pcm_runtime * const runtime = substream->runtime; 374 struct snd_pcm_runtime * const runtime = substream->runtime;
394 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); 375 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
395 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
396 struct mt8173_afe_private *afe_priv = afe->platform_priv; 376 struct mt8173_afe_private *afe_priv = afe->platform_priv;
397 377
398 unsigned int val; 378 unsigned int val;
@@ -454,9 +434,7 @@ static int mt8173_afe_hdmi_prepare(struct snd_pcm_substream *substream,
454static int mt8173_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd, 434static int mt8173_afe_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
455 struct snd_soc_dai *dai) 435 struct snd_soc_dai *dai)
456{ 436{
457 struct snd_soc_pcm_runtime *rtd = substream->private_data; 437 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
458 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
459 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
460 438
461 dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name); 439 dev_info(afe->dev, "%s cmd=%d %s\n", __func__, cmd, dai->name);
462 440
diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index b49b527a7cf9..902d111016d6 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver 3 * mt8173-max98090.c -- MT8173 MAX98090 ALSA SoC machine driver
3 * 4 *
4 * Copyright (c) 2015 MediaTek Inc. 5 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com> 6 * Author: Koro Chen <koro.chen@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 904f3ee6b0eb..582174d98c6c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt8173-rt5650-rt5514.c -- MT8173 machine driver with RT5650/5514 codecs 3 * mt8173-rt5650-rt5514.c -- MT8173 machine driver with RT5650/5514 codecs
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com> 6 * Author: Koro Chen <koro.chen@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 9c61b8c099c5..b3670c8a5b8d 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs 3 * mt8173-rt5650-rt5676.c -- MT8173 machine driver with RT5650/5676 codecs
3 * 4 *
4 * Copyright (c) 2015 MediaTek Inc. 5 * Copyright (c) 2015 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com> 6 * Author: Koro Chen <koro.chen@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 84aa09d3dd98..7a89b4aad182 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -1,17 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * mt8173-rt5650.c -- MT8173 machine driver with RT5650 codecs 3 * mt8173-rt5650.c -- MT8173 machine driver with RT5650 codecs
3 * 4 *
4 * Copyright (c) 2016 MediaTek Inc. 5 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com> 6 * Author: Koro Chen <koro.chen@mediatek.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 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */ 7 */
16 8
17#include <linux/module.h> 9#include <linux/module.h>
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index f5451c78ede5..6dccea6fdaeb 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,7 +1,12 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for Texas Instruments OMAP chips (deprecated)"
3 depends on (ARCH_OMAP && DMA_OMAP) || (ARM && COMPILE_TEST) 3 depends on (ARCH_OMAP && DMA_OMAP) || (ARM && COMPILE_TEST)
4 select SND_DMAENGINE_PCM 4 select SND_SDMA_SOC
5
6config SND_SDMA_SOC
7 tristate "SoC Audio for Texas Instruments chips using sDMA"
8 depends on DMA_OMAP || COMPILE_TEST
9 select SND_SOC_GENERIC_DMAENGINE_PCM
5 10
6config SND_OMAP_SOC_DMIC 11config SND_OMAP_SOC_DMIC
7 tristate 12 tristate
@@ -14,7 +19,7 @@ config SND_OMAP_SOC_MCPDM
14 19
15config SND_OMAP_SOC_HDMI_AUDIO 20config SND_OMAP_SOC_HDMI_AUDIO
16 tristate "HDMI audio support for OMAP4+ based SoCs" 21 tristate "HDMI audio support for OMAP4+ based SoCs"
17 depends on SND_OMAP_SOC 22 depends on SND_SDMA_SOC
18 help 23 help
19 For HDMI audio to work OMAPDSS HDMI support should be 24 For HDMI audio to work OMAPDSS HDMI support should be
20 enabled. 25 enabled.
@@ -29,8 +34,7 @@ config SND_OMAP_SOC_HDMI_AUDIO
29 34
30config SND_OMAP_SOC_N810 35config SND_OMAP_SOC_N810
31 tristate "SoC Audio support for Nokia N810" 36 tristate "SoC Audio support for Nokia N810"
32 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C 37 depends on SND_SDMA_SOC && MACH_NOKIA_N810 && I2C
33 depends on OMAP_MUX
34 select SND_OMAP_SOC_MCBSP 38 select SND_OMAP_SOC_MCBSP
35 select SND_SOC_TLV320AIC3X 39 select SND_SOC_TLV320AIC3X
36 help 40 help
@@ -38,7 +42,7 @@ config SND_OMAP_SOC_N810
38 42
39config SND_OMAP_SOC_RX51 43config SND_OMAP_SOC_RX51
40 tristate "SoC Audio support for Nokia N900 (RX-51)" 44 tristate "SoC Audio support for Nokia N900 (RX-51)"
41 depends on SND_OMAP_SOC && ARM && I2C 45 depends on SND_SDMA_SOC && ARM && I2C
42 select SND_OMAP_SOC_MCBSP 46 select SND_OMAP_SOC_MCBSP
43 select SND_SOC_TLV320AIC3X 47 select SND_SOC_TLV320AIC3X
44 select SND_SOC_TPA6130A2 48 select SND_SOC_TPA6130A2
@@ -49,7 +53,7 @@ config SND_OMAP_SOC_RX51
49 53
50config SND_OMAP_SOC_AMS_DELTA 54config SND_OMAP_SOC_AMS_DELTA
51 tristate "SoC Audio support for Amstrad E3 (Delta) videophone" 55 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
52 depends on SND_OMAP_SOC && MACH_AMS_DELTA && TTY 56 depends on SND_SDMA_SOC && MACH_AMS_DELTA && TTY
53 select SND_OMAP_SOC_MCBSP 57 select SND_OMAP_SOC_MCBSP
54 select SND_SOC_CX20442 58 select SND_SOC_CX20442
55 help 59 help
@@ -68,7 +72,7 @@ config SND_OMAP_SOC_AMS_DELTA
68 72
69config SND_OMAP_SOC_OSK5912 73config SND_OMAP_SOC_OSK5912
70 tristate "SoC Audio support for omap osk5912" 74 tristate "SoC Audio support for omap osk5912"
71 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C 75 depends on SND_SDMA_SOC && MACH_OMAP_OSK && I2C
72 select SND_OMAP_SOC_MCBSP 76 select SND_OMAP_SOC_MCBSP
73 select SND_SOC_TLV320AIC23_I2C 77 select SND_SOC_TLV320AIC23_I2C
74 help 78 help
@@ -76,7 +80,7 @@ config SND_OMAP_SOC_OSK5912
76 80
77config SND_OMAP_SOC_AM3517EVM 81config SND_OMAP_SOC_AM3517EVM
78 tristate "SoC Audio support for OMAP3517 / AM3517 EVM" 82 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
79 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C 83 depends on SND_SDMA_SOC && MACH_OMAP3517EVM && I2C
80 select SND_OMAP_SOC_MCBSP 84 select SND_OMAP_SOC_MCBSP
81 select SND_SOC_TLV320AIC23_I2C 85 select SND_SOC_TLV320AIC23_I2C
82 help 86 help
@@ -85,7 +89,7 @@ config SND_OMAP_SOC_AM3517EVM
85 89
86config SND_OMAP_SOC_OMAP_TWL4030 90config SND_OMAP_SOC_OMAP_TWL4030
87 tristate "SoC Audio support for TI SoC based boards with twl4030 codec" 91 tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
88 depends on TWL4030_CORE && SND_OMAP_SOC 92 depends on TWL4030_CORE && SND_SDMA_SOC
89 select SND_OMAP_SOC_MCBSP 93 select SND_OMAP_SOC_MCBSP
90 select SND_SOC_TWL4030 94 select SND_SOC_TWL4030
91 help 95 help
@@ -100,7 +104,7 @@ config SND_OMAP_SOC_OMAP_TWL4030
100 104
101config SND_OMAP_SOC_OMAP_ABE_TWL6040 105config SND_OMAP_SOC_OMAP_ABE_TWL6040
102 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 106 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
103 depends on TWL6040_CORE && SND_OMAP_SOC && COMMON_CLK 107 depends on TWL6040_CORE && SND_SDMA_SOC && COMMON_CLK
104 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST 108 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST
105 select SND_OMAP_SOC_DMIC 109 select SND_OMAP_SOC_DMIC
106 select SND_OMAP_SOC_MCPDM 110 select SND_OMAP_SOC_MCPDM
@@ -118,7 +122,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
118 122
119config SND_OMAP_SOC_OMAP3_PANDORA 123config SND_OMAP_SOC_OMAP3_PANDORA
120 tristate "SoC Audio support for OMAP3 Pandora" 124 tristate "SoC Audio support for OMAP3 Pandora"
121 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA 125 depends on TWL4030_CORE && SND_SDMA_SOC && MACH_OMAP3_PANDORA
122 select SND_OMAP_SOC_MCBSP 126 select SND_OMAP_SOC_MCBSP
123 select SND_SOC_TWL4030 127 select SND_SOC_TWL4030
124 help 128 help
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index a6785dc4fc90..53eba3413485 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,12 +1,12 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# OMAP Platform Support 2# OMAP Platform Support
3snd-soc-omap-objs := omap-pcm.o 3snd-soc-sdma-objs := sdma-pcm.o
4snd-soc-omap-dmic-objs := omap-dmic.o 4snd-soc-omap-dmic-objs := omap-dmic.o
5snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o 5snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
6snd-soc-omap-mcpdm-objs := omap-mcpdm.o 6snd-soc-omap-mcpdm-objs := omap-mcpdm.o
7snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o 7snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o
8 8
9obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 9obj-$(CONFIG_SND_SDMA_SOC) += snd-soc-sdma.o
10obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o 10obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
11obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o 11obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
12obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o 12obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 71e5f31fa306..9cfefe44a75f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -80,9 +80,9 @@ static void n810_ext_control(struct snd_soc_dapm_context *dapm)
80 else 80 else
81 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); 81 snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
82 if (line1l) 82 if (line1l)
83 snd_soc_dapm_enable_pin_unlocked(dapm, "LINE1L"); 83 snd_soc_dapm_enable_pin_unlocked(dapm, "HS Mic");
84 else 84 else
85 snd_soc_dapm_disable_pin_unlocked(dapm, "LINE1L"); 85 snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
86 86
87 if (n810_dmic_func) 87 if (n810_dmic_func)
88 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic"); 88 snd_soc_dapm_enable_pin_unlocked(dapm, "DMic");
@@ -222,6 +222,7 @@ static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = {
222 SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event), 222 SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event),
223 SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), 223 SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event),
224 SND_SOC_DAPM_MIC("DMic", NULL), 224 SND_SOC_DAPM_MIC("DMic", NULL),
225 SND_SOC_DAPM_MIC("HS Mic", NULL),
225}; 226};
226 227
227static const struct snd_soc_dapm_route audio_map[] = { 228static const struct snd_soc_dapm_route audio_map[] = {
@@ -231,8 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
231 {"Ext Spk", NULL, "LLOUT"}, 232 {"Ext Spk", NULL, "LLOUT"},
232 {"Ext Spk", NULL, "RLOUT"}, 233 {"Ext Spk", NULL, "RLOUT"},
233 234
234 {"DMic Rate 64", NULL, "Mic Bias"}, 235 {"DMic Rate 64", NULL, "DMic"},
235 {"Mic Bias", NULL, "DMic"}, 236 {"DMic", NULL, "Mic Bias"},
237
238 /*
239 * Note that the mic bias is coming from Retu/Vilma and we don't have
240 * control over it atm. The analog HS mic is not working. <- TODO
241 */
242 {"LINE1L", NULL, "HS Mic"},
236}; 243};
237 244
238static const char *spk_function[] = {"Off", "On"}; 245static const char *spk_function[] = {"Off", "On"};
@@ -257,9 +264,9 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
257static struct snd_soc_dai_link n810_dai = { 264static struct snd_soc_dai_link n810_dai = {
258 .name = "TLV320AIC33", 265 .name = "TLV320AIC33",
259 .stream_name = "AIC33", 266 .stream_name = "AIC33",
260 .cpu_dai_name = "omap-mcbsp.2", 267 .cpu_dai_name = "48076000.mcbsp",
261 .platform_name = "omap-mcbsp.2", 268 .platform_name = "48076000.mcbsp",
262 .codec_name = "tlv320aic3x-codec.2-0018", 269 .codec_name = "tlv320aic3x-codec.1-0018",
263 .codec_dai_name = "tlv320aic3x-hifi", 270 .codec_dai_name = "tlv320aic3x-hifi",
264 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 271 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
265 SND_SOC_DAIFMT_CBM_CFM, 272 SND_SOC_DAIFMT_CBM_CFM,
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index b2f5d2fa354d..51dd7c65096b 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -40,9 +40,9 @@
40#include <sound/initval.h> 40#include <sound/initval.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h> 42#include <sound/dmaengine_pcm.h>
43#include <sound/omap-pcm.h>
44 43
45#include "omap-dmic.h" 44#include "omap-dmic.h"
45#include "sdma-pcm.h"
46 46
47struct omap_dmic { 47struct omap_dmic {
48 struct device *dev; 48 struct device *dev;
@@ -501,7 +501,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
501 if (ret) 501 if (ret)
502 return ret; 502 return ret;
503 503
504 ret = omap_pcm_platform_register(&pdev->dev); 504 ret = sdma_pcm_platform_register(&pdev->dev, NULL, "up_link");
505 if (ret) 505 if (ret)
506 return ret; 506 return ret;
507 507
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 8eeac7cab1c1..8a99a8837dc9 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -26,9 +26,10 @@
26#include <sound/dmaengine_pcm.h> 26#include <sound/dmaengine_pcm.h>
27#include <uapi/sound/asound.h> 27#include <uapi/sound/asound.h>
28#include <sound/asoundef.h> 28#include <sound/asoundef.h>
29#include <sound/omap-pcm.h>
30#include <sound/omap-hdmi-audio.h> 29#include <sound/omap-hdmi-audio.h>
31 30
31#include "sdma-pcm.h"
32
32#define DRV_NAME "omap-hdmi-audio" 33#define DRV_NAME "omap-hdmi-audio"
33 34
34struct hdmi_audio_data { 35struct hdmi_audio_data {
@@ -352,7 +353,7 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
352 if (ret) 353 if (ret)
353 return ret; 354 return ret;
354 355
355 ret = omap_pcm_platform_register(ad->dssdev); 356 ret = sdma_pcm_platform_register(ad->dssdev, "audio_tx", NULL);
356 if (ret) 357 if (ret)
357 return ret; 358 return ret;
358 359
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6b40bdbef336..d0ebb6b9bfac 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -34,11 +34,11 @@
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/dmaengine_pcm.h> 36#include <sound/dmaengine_pcm.h>
37#include <sound/omap-pcm.h>
38 37
39#include <linux/platform_data/asoc-ti-mcbsp.h> 38#include <linux/platform_data/asoc-ti-mcbsp.h>
40#include "mcbsp.h" 39#include "mcbsp.h"
41#include "omap-mcbsp.h" 40#include "omap-mcbsp.h"
41#include "sdma-pcm.h"
42 42
43#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 43#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
44 44
@@ -868,7 +868,7 @@ static int asoc_mcbsp_probe(struct platform_device *pdev)
868 if (ret) 868 if (ret)
869 return ret; 869 return ret;
870 870
871 return omap_pcm_platform_register(&pdev->dev); 871 return sdma_pcm_platform_register(&pdev->dev, NULL, NULL);
872} 872}
873 873
874static int asoc_mcbsp_remove(struct platform_device *pdev) 874static int asoc_mcbsp_remove(struct platform_device *pdev)
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 64609c77a79d..0e97360f9890 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -40,9 +40,9 @@
40#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h> 42#include <sound/dmaengine_pcm.h>
43#include <sound/omap-pcm.h>
44 43
45#include "omap-mcpdm.h" 44#include "omap-mcpdm.h"
45#include "sdma-pcm.h"
46 46
47struct mcpdm_link_config { 47struct mcpdm_link_config {
48 u32 link_mask; /* channel mask for the direction */ 48 u32 link_mask; /* channel mask for the direction */
@@ -548,7 +548,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
548 if (ret) 548 if (ret)
549 return ret; 549 return ret;
550 550
551 return omap_pcm_platform_register(&pdev->dev); 551 return sdma_pcm_platform_register(&pdev->dev, "dn_link", "up_link");
552} 552}
553 553
554static const struct of_device_id omap_mcpdm_of_match[] = { 554static const struct of_device_id omap_mcpdm_of_match[] = {
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
deleted file mode 100644
index 778cc8f75b6a..000000000000
--- a/sound/soc/omap/omap-pcm.c
+++ /dev/null
@@ -1,262 +0,0 @@
1/*
2 * omap-pcm.c -- ALSA PCM interface for the OMAP SoC
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/dma-mapping.h>
26#include <linux/slab.h>
27#include <linux/module.h>
28#include <linux/omap-dma.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/dmaengine_pcm.h>
33#include <sound/soc.h>
34#include <sound/omap-pcm.h>
35
36#ifdef CONFIG_ARCH_OMAP1
37#define pcm_omap1510() cpu_is_omap1510()
38#else
39#define pcm_omap1510() 0
40#endif
41
42static struct snd_pcm_hardware omap_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_INTERLEAVED |
46 SNDRV_PCM_INFO_PAUSE |
47 SNDRV_PCM_INFO_RESUME |
48 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
49 .period_bytes_min = 32,
50 .period_bytes_max = 64 * 1024,
51 .periods_min = 2,
52 .periods_max = 255,
53 .buffer_bytes_max = 128 * 1024,
54};
55
56/* sDMA supports only 1, 2, and 4 byte transfer elements. */
57static void omap_pcm_limit_supported_formats(void)
58{
59 int i;
60
61 for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
62 switch (snd_pcm_format_physical_width(i)) {
63 case 8:
64 case 16:
65 case 32:
66 omap_pcm_hardware.formats |= (1LL << i);
67 break;
68 default:
69 break;
70 }
71 }
72}
73
74/* this may get called several times by oss emulation */
75static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
76 struct snd_pcm_hw_params *params)
77{
78 struct snd_pcm_runtime *runtime = substream->runtime;
79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct omap_pcm_dma_data *dma_data;
81 struct dma_slave_config config;
82 struct dma_chan *chan;
83 int err = 0;
84
85 memset(&config, 0x00, sizeof(config));
86
87 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
88
89 /* return if this is a bufferless transfer e.g.
90 * codec <--> BT codec or GSM modem -- lg FIXME */
91 if (!dma_data)
92 return 0;
93
94 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
95 runtime->dma_bytes = params_buffer_bytes(params);
96
97 chan = snd_dmaengine_pcm_get_chan(substream);
98 if (!chan)
99 return -EINVAL;
100
101 /* fills in addr_width and direction */
102 err = snd_hwparams_to_dma_slave_config(substream, params, &config);
103 if (err)
104 return err;
105
106 snd_dmaengine_pcm_set_config_from_dai_data(substream,
107 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
108 &config);
109
110 return dmaengine_slave_config(chan, &config);
111}
112
113static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
114{
115 snd_pcm_set_runtime_buffer(substream, NULL);
116 return 0;
117}
118
119static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
120{
121 snd_pcm_uframes_t offset;
122
123 if (pcm_omap1510())
124 offset = snd_dmaengine_pcm_pointer_no_residue(substream);
125 else
126 offset = snd_dmaengine_pcm_pointer(substream);
127
128 return offset;
129}
130
131static int omap_pcm_open(struct snd_pcm_substream *substream)
132{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_dmaengine_dai_dma_data *dma_data;
135 int ret;
136
137 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
138
139 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
140
141 /* DT boot: filter_data is the DMA name */
142 if (rtd->cpu_dai->dev->of_node) {
143 struct dma_chan *chan;
144
145 chan = dma_request_slave_channel(rtd->cpu_dai->dev,
146 dma_data->filter_data);
147 ret = snd_dmaengine_pcm_open(substream, chan);
148 } else {
149 ret = snd_dmaengine_pcm_open_request_chan(substream,
150 omap_dma_filter_fn,
151 dma_data->filter_data);
152 }
153 return ret;
154}
155
156static int omap_pcm_mmap(struct snd_pcm_substream *substream,
157 struct vm_area_struct *vma)
158{
159 struct snd_pcm_runtime *runtime = substream->runtime;
160
161 return dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area,
162 runtime->dma_addr, runtime->dma_bytes);
163}
164
165static const struct snd_pcm_ops omap_pcm_ops = {
166 .open = omap_pcm_open,
167 .close = snd_dmaengine_pcm_close_release_chan,
168 .ioctl = snd_pcm_lib_ioctl,
169 .hw_params = omap_pcm_hw_params,
170 .hw_free = omap_pcm_hw_free,
171 .trigger = snd_dmaengine_pcm_trigger,
172 .pointer = omap_pcm_pointer,
173 .mmap = omap_pcm_mmap,
174};
175
176static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
177 int stream)
178{
179 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
180 struct snd_dma_buffer *buf = &substream->dma_buffer;
181 size_t size = omap_pcm_hardware.buffer_bytes_max;
182
183 buf->dev.type = SNDRV_DMA_TYPE_DEV;
184 buf->dev.dev = pcm->card->dev;
185 buf->private_data = NULL;
186 buf->area = dma_alloc_wc(pcm->card->dev, size, &buf->addr, GFP_KERNEL);
187 if (!buf->area)
188 return -ENOMEM;
189
190 buf->bytes = size;
191 return 0;
192}
193
194static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
195{
196 struct snd_pcm_substream *substream;
197 struct snd_dma_buffer *buf;
198 int stream;
199
200 for (stream = 0; stream < 2; stream++) {
201 substream = pcm->streams[stream].substream;
202 if (!substream)
203 continue;
204
205 buf = &substream->dma_buffer;
206 if (!buf->area)
207 continue;
208
209 dma_free_wc(pcm->card->dev, buf->bytes, buf->area, buf->addr);
210 buf->area = NULL;
211 }
212}
213
214static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
215{
216 struct snd_card *card = rtd->card->snd_card;
217 struct snd_pcm *pcm = rtd->pcm;
218 int ret;
219
220 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
221 if (ret)
222 return ret;
223
224 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
225 ret = omap_pcm_preallocate_dma_buffer(pcm,
226 SNDRV_PCM_STREAM_PLAYBACK);
227 if (ret)
228 goto out;
229 }
230
231 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
232 ret = omap_pcm_preallocate_dma_buffer(pcm,
233 SNDRV_PCM_STREAM_CAPTURE);
234 if (ret)
235 goto out;
236 }
237
238out:
239 /* free preallocated buffers in case of error */
240 if (ret)
241 omap_pcm_free_dma_buffers(pcm);
242
243 return ret;
244}
245
246static const struct snd_soc_component_driver omap_soc_component = {
247 .ops = &omap_pcm_ops,
248 .pcm_new = omap_pcm_new,
249 .pcm_free = omap_pcm_free_dma_buffers,
250};
251
252int omap_pcm_platform_register(struct device *dev)
253{
254 omap_pcm_limit_supported_formats();
255 return devm_snd_soc_register_component(dev, &omap_soc_component,
256 NULL, 0);
257}
258EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
259
260MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
261MODULE_DESCRIPTION("OMAP PCM DMA module");
262MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdma-pcm.c b/sound/soc/omap/sdma-pcm.c
new file mode 100644
index 000000000000..21a9c2499d48
--- /dev/null
+++ b/sound/soc/omap/sdma-pcm.c
@@ -0,0 +1,74 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 */
6
7#include <linux/device.h>
8#include <linux/module.h>
9#include <sound/core.h>
10#include <sound/pcm.h>
11#include <sound/pcm_params.h>
12#include <sound/soc.h>
13#include <sound/dmaengine_pcm.h>
14#include <linux/omap-dmaengine.h>
15
16#include "sdma-pcm.h"
17
18static const struct snd_pcm_hardware sdma_pcm_hardware = {
19 .info = SNDRV_PCM_INFO_MMAP |
20 SNDRV_PCM_INFO_MMAP_VALID |
21 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
22 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
23 SNDRV_PCM_INFO_INTERLEAVED,
24 .period_bytes_min = 32,
25 .period_bytes_max = 64 * 1024,
26 .buffer_bytes_max = 128 * 1024,
27 .periods_min = 2,
28 .periods_max = 255,
29};
30
31static const struct snd_dmaengine_pcm_config sdma_dmaengine_pcm_config = {
32 .pcm_hardware = &sdma_pcm_hardware,
33 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
34 .compat_filter_fn = omap_dma_filter_fn,
35 .prealloc_buffer_size = 128 * 1024,
36};
37
38int sdma_pcm_platform_register(struct device *dev,
39 char *txdmachan, char *rxdmachan)
40{
41 struct snd_dmaengine_pcm_config *config;
42 unsigned int flags = SND_DMAENGINE_PCM_FLAG_COMPAT;
43
44 /* Standard names for the directions: 'tx' and 'rx' */
45 if (!txdmachan && !rxdmachan)
46 return devm_snd_dmaengine_pcm_register(dev,
47 &sdma_dmaengine_pcm_config,
48 flags);
49
50 config = devm_kzalloc(dev, sizeof(*config), GFP_KERNEL);
51 if (!config)
52 return -ENOMEM;
53
54 *config = sdma_dmaengine_pcm_config;
55
56 if (!txdmachan || !rxdmachan) {
57 /* One direction only PCM */
58 flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX;
59 if (!txdmachan) {
60 txdmachan = rxdmachan;
61 rxdmachan = NULL;
62 }
63 }
64
65 config->chan_names[0] = txdmachan;
66 config->chan_names[1] = rxdmachan;
67
68 return devm_snd_dmaengine_pcm_register(dev, config, flags);
69}
70EXPORT_SYMBOL_GPL(sdma_pcm_platform_register);
71
72MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
73MODULE_DESCRIPTION("sDMA PCM ASoC platform driver");
74MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/sdma-pcm.h b/sound/soc/omap/sdma-pcm.h
new file mode 100644
index 000000000000..34a7f90b2587
--- /dev/null
+++ b/sound/soc/omap/sdma-pcm.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 */
6
7#ifndef __SDMA_PCM_H__
8#define __SDMA_PCM_H__
9
10#if IS_ENABLED(CONFIG_SND_SDMA_SOC)
11int sdma_pcm_platform_register(struct device *dev,
12 char *txdmachan, char *rxdmachan);
13#else
14static inline int sdma_pcm_platform_register(struct device *dev,
15 char *txdmachan, char *rxdmachan)
16{
17 return -ENODEV;
18}
19#endif /* CONFIG_SND_SDMA_SOC */
20
21#endif /* __SDMA_PCM_H__ */
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 484ab3c2ad67..960744e46edc 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,7 +1,6 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA || COMPILE_TEST 3 depends on ARCH_PXA || COMPILE_TEST
4 depends on HAS_DMA
5 select SND_PXA2XX_LIB 4 select SND_PXA2XX_LIB
6 help 5 help
7 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 0291c7cb64eb..6fc986080130 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -43,7 +43,8 @@
43struct ssp_priv { 43struct ssp_priv {
44 struct ssp_device *ssp; 44 struct ssp_device *ssp;
45 unsigned int sysclk; 45 unsigned int sysclk;
46 int dai_fmt; 46 unsigned int dai_fmt;
47 unsigned int configured_dai_fmt;
47#ifdef CONFIG_PM 48#ifdef CONFIG_PM
48 uint32_t cr0; 49 uint32_t cr0;
49 uint32_t cr1; 50 uint32_t cr1;
@@ -216,10 +217,9 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
216{ 217{
217 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); 218 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
218 struct ssp_device *ssp = priv->ssp; 219 struct ssp_device *ssp = priv->ssp;
219 int val;
220 220
221 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & 221 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
222 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 222 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
223 223
224 dev_dbg(&ssp->pdev->dev, 224 dev_dbg(&ssp->pdev->dev,
225 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n", 225 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n",
@@ -257,8 +257,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
257 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 257 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
258 if (ssp->type != PXA3xx_SSP) 258 if (ssp->type != PXA3xx_SSP)
259 clk_disable_unprepare(ssp->clk); 259 clk_disable_unprepare(ssp->clk);
260 val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0; 260 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
261 pxa_ssp_write_reg(ssp, SSCR0, val);
262 if (ssp->type != PXA3xx_SSP) 261 if (ssp->type != PXA3xx_SSP)
263 clk_prepare_enable(ssp->clk); 262 clk_prepare_enable(ssp->clk);
264 263
@@ -433,36 +432,72 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
433 return 0; 432 return 0;
434} 433}
435 434
435static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
436 unsigned int fmt)
437{
438 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
439
440 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
441 case SND_SOC_DAIFMT_CBM_CFM:
442 case SND_SOC_DAIFMT_CBM_CFS:
443 case SND_SOC_DAIFMT_CBS_CFS:
444 break;
445 default:
446 return -EINVAL;
447 }
448
449 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
450 case SND_SOC_DAIFMT_NB_NF:
451 case SND_SOC_DAIFMT_NB_IF:
452 case SND_SOC_DAIFMT_IB_IF:
453 case SND_SOC_DAIFMT_IB_NF:
454 break;
455 default:
456 return -EINVAL;
457 }
458
459 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
460 case SND_SOC_DAIFMT_I2S:
461 case SND_SOC_DAIFMT_DSP_A:
462 case SND_SOC_DAIFMT_DSP_B:
463 break;
464
465 default:
466 return -EINVAL;
467 }
468
469 /* Settings will be applied in hw_params() */
470 priv->dai_fmt = fmt;
471
472 return 0;
473}
474
436/* 475/*
437 * Set up the SSP DAI format. 476 * Set up the SSP DAI format.
438 * The SSP Port must be inactive before calling this function as the 477 * The SSP Port must be inactive before calling this function as the
439 * physical interface format is changed. 478 * physical interface format is changed.
440 */ 479 */
441static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 480static int pxa_ssp_configure_dai_fmt(struct ssp_priv *priv)
442 unsigned int fmt)
443{ 481{
444 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
445 struct ssp_device *ssp = priv->ssp; 482 struct ssp_device *ssp = priv->ssp;
446 u32 sscr0, sscr1, sspsp, scfr; 483 u32 sscr0, sscr1, sspsp, scfr;
447 484
448 /* check if we need to change anything at all */ 485 /* check if we need to change anything at all */
449 if (priv->dai_fmt == fmt) 486 if (priv->configured_dai_fmt == priv->dai_fmt)
450 return 0; 487 return 0;
451 488
452 /* we can only change the settings if the port is not in use */
453 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
454 dev_err(&ssp->pdev->dev,
455 "can't change hardware dai format: stream is in use");
456 return -EINVAL;
457 }
458
459 /* reset port settings */ 489 /* reset port settings */
460 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & 490 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
461 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 491 ~(SSCR0_PSP | SSCR0_MOD);
462 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); 492 sscr1 = pxa_ssp_read_reg(ssp, SSCR1) &
463 sspsp = 0; 493 ~(SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR |
494 SSCR1_RWOT | SSCR1_TRAIL | SSCR1_TFT | SSCR1_RFT);
495 sspsp = pxa_ssp_read_reg(ssp, SSPSP) &
496 ~(SSPSP_SFRMP | SSPSP_SCMODE(3));
464 497
465 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 498 sscr1 |= SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
499
500 switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) {
466 case SND_SOC_DAIFMT_CBM_CFM: 501 case SND_SOC_DAIFMT_CBM_CFM:
467 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR; 502 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR;
468 break; 503 break;
@@ -475,7 +510,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
475 return -EINVAL; 510 return -EINVAL;
476 } 511 }
477 512
478 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 513 switch (priv->dai_fmt & SND_SOC_DAIFMT_INV_MASK) {
479 case SND_SOC_DAIFMT_NB_NF: 514 case SND_SOC_DAIFMT_NB_NF:
480 sspsp |= SSPSP_SFRMP; 515 sspsp |= SSPSP_SFRMP;
481 break; 516 break;
@@ -491,7 +526,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
491 return -EINVAL; 526 return -EINVAL;
492 } 527 }
493 528
494 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 529 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
495 case SND_SOC_DAIFMT_I2S: 530 case SND_SOC_DAIFMT_I2S:
496 sscr0 |= SSCR0_PSP; 531 sscr0 |= SSCR0_PSP;
497 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; 532 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
@@ -513,7 +548,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
513 pxa_ssp_write_reg(ssp, SSCR1, sscr1); 548 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
514 pxa_ssp_write_reg(ssp, SSPSP, sspsp); 549 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
515 550
516 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 551 switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) {
517 case SND_SOC_DAIFMT_CBM_CFM: 552 case SND_SOC_DAIFMT_CBM_CFM:
518 case SND_SOC_DAIFMT_CBM_CFS: 553 case SND_SOC_DAIFMT_CBM_CFS:
519 scfr = pxa_ssp_read_reg(ssp, SSCR1) | SSCR1_SCFR; 554 scfr = pxa_ssp_read_reg(ssp, SSCR1) | SSCR1_SCFR;
@@ -530,7 +565,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
530 * we have to defer some things until hw_params() where we 565 * we have to defer some things until hw_params() where we
531 * know parameters like the sample size. 566 * know parameters like the sample size.
532 */ 567 */
533 priv->dai_fmt = fmt; 568 priv->configured_dai_fmt = priv->dai_fmt;
534 569
535 return 0; 570 return 0;
536} 571}
@@ -551,6 +586,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
551 int width = snd_pcm_format_physical_width(params_format(params)); 586 int width = snd_pcm_format_physical_width(params_format(params));
552 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; 587 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
553 struct snd_dmaengine_dai_dma_data *dma_data; 588 struct snd_dmaengine_dai_dma_data *dma_data;
589 int ret;
554 590
555 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); 591 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
556 592
@@ -566,6 +602,10 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
566 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 602 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
567 return 0; 603 return 0;
568 604
605 ret = pxa_ssp_configure_dai_fmt(priv);
606 if (ret < 0)
607 return ret;
608
569 /* clear selected SSP bits */ 609 /* clear selected SSP bits */
570 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); 610 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
571 611
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 8ec9a074b38b..87838fa27997 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -11,24 +11,21 @@ config SND_SOC_LPASS_CPU
11 11
12config SND_SOC_LPASS_PLATFORM 12config SND_SOC_LPASS_PLATFORM
13 tristate 13 tristate
14 depends on HAS_DMA
15 select REGMAP_MMIO 14 select REGMAP_MMIO
16 15
17config SND_SOC_LPASS_IPQ806X 16config SND_SOC_LPASS_IPQ806X
18 tristate 17 tristate
19 depends on HAS_DMA
20 select SND_SOC_LPASS_CPU 18 select SND_SOC_LPASS_CPU
21 select SND_SOC_LPASS_PLATFORM 19 select SND_SOC_LPASS_PLATFORM
22 20
23config SND_SOC_LPASS_APQ8016 21config SND_SOC_LPASS_APQ8016
24 tristate 22 tristate
25 depends on HAS_DMA
26 select SND_SOC_LPASS_CPU 23 select SND_SOC_LPASS_CPU
27 select SND_SOC_LPASS_PLATFORM 24 select SND_SOC_LPASS_PLATFORM
28 25
29config SND_SOC_STORM 26config SND_SOC_STORM
30 tristate "ASoC I2S support for Storm boards" 27 tristate "ASoC I2S support for Storm boards"
31 depends on SND_SOC_QCOM && HAS_DMA 28 depends on SND_SOC_QCOM
32 select SND_SOC_LPASS_IPQ806X 29 select SND_SOC_LPASS_IPQ806X
33 select SND_SOC_MAX98357A 30 select SND_SOC_MAX98357A
34 help 31 help
@@ -37,9 +34,59 @@ config SND_SOC_STORM
37 34
38config SND_SOC_APQ8016_SBC 35config SND_SOC_APQ8016_SBC
39 tristate "SoC Audio support for APQ8016 SBC platforms" 36 tristate "SoC Audio support for APQ8016 SBC platforms"
40 depends on SND_SOC_QCOM && HAS_DMA 37 depends on SND_SOC_QCOM
41 select SND_SOC_LPASS_APQ8016 38 select SND_SOC_LPASS_APQ8016
42 help 39 help
43 Support for Qualcomm Technologies LPASS audio block in 40 Support for Qualcomm Technologies LPASS audio block in
44 APQ8016 SOC-based systems. 41 APQ8016 SOC-based systems.
45 Say Y if you want to use audio devices on MI2S. 42 Say Y if you want to use audio devices on MI2S.
43
44config SND_SOC_QDSP6_COMMON
45 tristate
46
47config SND_SOC_QDSP6_CORE
48 tristate
49
50config SND_SOC_QDSP6_AFE
51 tristate
52
53config SND_SOC_QDSP6_AFE_DAI
54 tristate
55
56config SND_SOC_QDSP6_ADM
57 tristate
58
59config SND_SOC_QDSP6_ROUTING
60 tristate
61
62config SND_SOC_QDSP6_ASM
63 tristate
64
65config SND_SOC_QDSP6_ASM_DAI
66 tristate
67
68config SND_SOC_QDSP6
69 tristate "SoC ALSA audio driver for QDSP6"
70 depends on QCOM_APR && HAS_DMA
71 select SND_SOC_QDSP6_COMMON
72 select SND_SOC_QDSP6_CORE
73 select SND_SOC_QDSP6_AFE
74 select SND_SOC_QDSP6_AFE_DAI
75 select SND_SOC_QDSP6_ADM
76 select SND_SOC_QDSP6_ROUTING
77 select SND_SOC_QDSP6_ASM
78 select SND_SOC_QDSP6_ASM_DAI
79 help
80 To add support for MSM QDSP6 Soc Audio.
81 This will enable sound soc platform specific
82 audio drivers. This includes q6asm, q6adm,
83 q6afe interfaces to DSP using apr.
84
85config SND_SOC_MSM8996
86 tristate "SoC Machine driver for MSM8996 and APQ8096 boards"
87 depends on QCOM_APR
88 select SND_SOC_QDSP6
89 help
90 Support for Qualcomm Technologies LPASS audio block in
91 APQ8096 SoC-based systems.
92 Say Y if you want to use audio device on this SoCs
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index d5280355c24f..206945bb9ba1 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -13,6 +13,11 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o
13# Machine 13# Machine
14snd-soc-storm-objs := storm.o 14snd-soc-storm-objs := storm.o
15snd-soc-apq8016-sbc-objs := apq8016_sbc.o 15snd-soc-apq8016-sbc-objs := apq8016_sbc.o
16snd-soc-apq8096-objs := apq8096.o
16 17
17obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o 18obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
18obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o 19obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
20obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o
21
22#DSP lib
23obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
new file mode 100644
index 000000000000..561cd429e6f2
--- /dev/null
+++ b/sound/soc/qcom/apq8096.c
@@ -0,0 +1,255 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018, Linaro Limited
3
4#include <linux/soc/qcom/apr.h>
5#include <linux/module.h>
6#include <linux/component.h>
7#include <linux/platform_device.h>
8#include <linux/of_device.h>
9#include <sound/soc.h>
10#include <sound/soc-dapm.h>
11#include <sound/pcm.h>
12
13static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
14 struct snd_pcm_hw_params *params)
15{
16 struct snd_interval *rate = hw_param_interval(params,
17 SNDRV_PCM_HW_PARAM_RATE);
18 struct snd_interval *channels = hw_param_interval(params,
19 SNDRV_PCM_HW_PARAM_CHANNELS);
20
21 rate->min = rate->max = 48000;
22 channels->min = channels->max = 2;
23
24 return 0;
25}
26
27static int apq8096_sbc_parse_of(struct snd_soc_card *card)
28{
29 struct device_node *np;
30 struct device_node *codec = NULL;
31 struct device_node *platform = NULL;
32 struct device_node *cpu = NULL;
33 struct device *dev = card->dev;
34 struct snd_soc_dai_link *link;
35 int ret, num_links;
36
37 ret = snd_soc_of_parse_card_name(card, "qcom,model");
38 if (ret) {
39 dev_err(dev, "Error parsing card name: %d\n", ret);
40 return ret;
41 }
42
43 /* DAPM routes */
44 if (of_property_read_bool(dev->of_node, "qcom,audio-routing")) {
45 ret = snd_soc_of_parse_audio_routing(card,
46 "qcom,audio-routing");
47 if (ret)
48 return ret;
49 }
50
51 /* Populate links */
52 num_links = of_get_child_count(dev->of_node);
53
54 /* Allocate the DAI link array */
55 card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL);
56 if (!card->dai_link)
57 return -ENOMEM;
58
59 card->num_links = num_links;
60 link = card->dai_link;
61
62 for_each_child_of_node(dev->of_node, np) {
63 cpu = of_get_child_by_name(np, "cpu");
64 if (!cpu) {
65 dev_err(dev, "Can't find cpu DT node\n");
66 ret = -EINVAL;
67 goto err;
68 }
69
70 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
71 if (!link->cpu_of_node) {
72 dev_err(card->dev, "error getting cpu phandle\n");
73 ret = -EINVAL;
74 goto err;
75 }
76
77 ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
78 if (ret) {
79 dev_err(card->dev, "error getting cpu dai name\n");
80 goto err;
81 }
82
83 platform = of_get_child_by_name(np, "platform");
84 codec = of_get_child_by_name(np, "codec");
85 if (codec && platform) {
86 link->platform_of_node = of_parse_phandle(platform,
87 "sound-dai",
88 0);
89 if (!link->platform_of_node) {
90 dev_err(card->dev, "platform dai not found\n");
91 ret = -EINVAL;
92 goto err;
93 }
94
95 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
96 if (ret < 0) {
97 dev_err(card->dev, "codec dai not found\n");
98 goto err;
99 }
100 link->no_pcm = 1;
101 link->ignore_pmdown_time = 1;
102 link->be_hw_params_fixup = apq8096_be_hw_params_fixup;
103 } else {
104 link->platform_of_node = link->cpu_of_node;
105 link->codec_dai_name = "snd-soc-dummy-dai";
106 link->codec_name = "snd-soc-dummy";
107 link->dynamic = 1;
108 }
109
110 link->ignore_suspend = 1;
111 ret = of_property_read_string(np, "link-name", &link->name);
112 if (ret) {
113 dev_err(card->dev, "error getting codec dai_link name\n");
114 goto err;
115 }
116
117 link->dpcm_playback = 1;
118 link->dpcm_capture = 1;
119 link->stream_name = link->name;
120 link++;
121 }
122
123 return 0;
124err:
125 of_node_put(cpu);
126 of_node_put(codec);
127 of_node_put(platform);
128 kfree(card->dai_link);
129 return ret;
130}
131
132static int apq8096_bind(struct device *dev)
133{
134 struct snd_soc_card *card;
135 int ret;
136
137 card = kzalloc(sizeof(*card), GFP_KERNEL);
138 if (!card)
139 return -ENOMEM;
140
141 component_bind_all(dev, card);
142 card->dev = dev;
143 ret = apq8096_sbc_parse_of(card);
144 if (ret) {
145 dev_err(dev, "Error parsing OF data\n");
146 goto err;
147 }
148
149 ret = snd_soc_register_card(card);
150 if (ret)
151 goto err;
152
153 return 0;
154
155err:
156 component_unbind_all(dev, card);
157 kfree(card);
158 return ret;
159}
160
161static void apq8096_unbind(struct device *dev)
162{
163 struct snd_soc_card *card = dev_get_drvdata(dev);
164
165 snd_soc_unregister_card(card);
166 component_unbind_all(dev, card);
167 kfree(card->dai_link);
168 kfree(card);
169}
170
171static const struct component_master_ops apq8096_ops = {
172 .bind = apq8096_bind,
173 .unbind = apq8096_unbind,
174};
175
176static int apq8016_compare_of(struct device *dev, void *data)
177{
178 return dev->of_node == data;
179}
180
181static void apq8016_release_of(struct device *dev, void *data)
182{
183 of_node_put(data);
184}
185
186static int add_audio_components(struct device *dev,
187 struct component_match **matchptr)
188{
189 struct device_node *np, *platform, *cpu, *node, *dai_node;
190
191 node = dev->of_node;
192
193 for_each_child_of_node(node, np) {
194 cpu = of_get_child_by_name(np, "cpu");
195 if (cpu) {
196 dai_node = of_parse_phandle(cpu, "sound-dai", 0);
197 of_node_get(dai_node);
198 component_match_add_release(dev, matchptr,
199 apq8016_release_of,
200 apq8016_compare_of,
201 dai_node);
202 }
203
204 platform = of_get_child_by_name(np, "platform");
205 if (platform) {
206 dai_node = of_parse_phandle(platform, "sound-dai", 0);
207 component_match_add_release(dev, matchptr,
208 apq8016_release_of,
209 apq8016_compare_of,
210 dai_node);
211 }
212 }
213
214 return 0;
215}
216
217static int apq8096_platform_probe(struct platform_device *pdev)
218{
219 struct component_match *match = NULL;
220 int ret;
221
222 ret = add_audio_components(&pdev->dev, &match);
223 if (ret)
224 return ret;
225
226 return component_master_add_with_match(&pdev->dev, &apq8096_ops, match);
227}
228
229static int apq8096_platform_remove(struct platform_device *pdev)
230{
231 component_master_del(&pdev->dev, &apq8096_ops);
232
233 return 0;
234}
235
236static const struct of_device_id msm_snd_apq8096_dt_match[] = {
237 {.compatible = "qcom,apq8096-sndcard"},
238 {}
239};
240
241MODULE_DEVICE_TABLE(of, msm_snd_apq8096_dt_match);
242
243static struct platform_driver msm_snd_apq8096_driver = {
244 .probe = apq8096_platform_probe,
245 .remove = apq8096_platform_remove,
246 .driver = {
247 .name = "msm-snd-apq8096",
248 .owner = THIS_MODULE,
249 .of_match_table = msm_snd_apq8096_dt_match,
250 },
251};
252module_platform_driver(msm_snd_apq8096_driver);
253MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
254MODULE_DESCRIPTION("APQ8096 ASoC Machine Driver");
255MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
new file mode 100644
index 000000000000..c33b3cacbea1
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -0,0 +1,8 @@
1obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
2obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
3obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
4obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o
5obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
6obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
7obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
8obj-$(CONFIG_SND_SOC_QDSP6_ASM_DAI) += q6asm-dai.o
diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c
new file mode 100644
index 000000000000..9983c665a941
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6adm.c
@@ -0,0 +1,646 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/slab.h>
6#include <linux/wait.h>
7#include <linux/kernel.h>
8#include <linux/device.h>
9#include <linux/module.h>
10#include <linux/sched.h>
11#include <linux/jiffies.h>
12#include <linux/of.h>
13#include <linux/of_platform.h>
14#include <linux/kref.h>
15#include <linux/wait.h>
16#include <linux/soc/qcom/apr.h>
17#include <linux/platform_device.h>
18#include <sound/asound.h>
19#include "q6adm.h"
20#include "q6afe.h"
21#include "q6core.h"
22#include "q6dsp-errno.h"
23#include "q6dsp-common.h"
24
25#define ADM_CMD_DEVICE_OPEN_V5 0x00010326
26#define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329
27#define ADM_CMD_DEVICE_CLOSE_V5 0x00010327
28#define ADM_CMD_MATRIX_MAP_ROUTINGS_V5 0x00010325
29
30#define TIMEOUT_MS 1000
31#define RESET_COPP_ID 99
32#define INVALID_COPP_ID 0xFF
33/* Definition for a legacy device session. */
34#define ADM_LEGACY_DEVICE_SESSION 0
35#define ADM_MATRIX_ID_AUDIO_RX 0
36#define ADM_MATRIX_ID_AUDIO_TX 1
37
38struct q6copp {
39 int afe_port;
40 int copp_idx;
41 int id;
42 int topology;
43 int mode;
44 int rate;
45 int bit_width;
46 int channels;
47 int app_type;
48 int acdb_id;
49
50 struct aprv2_ibasic_rsp_result_t result;
51 struct kref refcount;
52 wait_queue_head_t wait;
53 struct list_head node;
54 struct q6adm *adm;
55};
56
57struct q6adm {
58 struct apr_device *apr;
59 struct device *dev;
60 struct q6core_svc_api_info ainfo;
61 unsigned long copp_bitmap[AFE_MAX_PORTS];
62 struct list_head copps_list;
63 spinlock_t copps_list_lock;
64 struct aprv2_ibasic_rsp_result_t result;
65 struct mutex lock;
66 wait_queue_head_t matrix_map_wait;
67 struct platform_device *pdev_routing;
68};
69
70struct q6adm_cmd_device_open_v5 {
71 u16 flags;
72 u16 mode_of_operation;
73 u16 endpoint_id_1;
74 u16 endpoint_id_2;
75 u32 topology_id;
76 u16 dev_num_channel;
77 u16 bit_width;
78 u32 sample_rate;
79 u8 dev_channel_mapping[8];
80} __packed;
81
82struct q6adm_cmd_matrix_map_routings_v5 {
83 u32 matrix_id;
84 u32 num_sessions;
85} __packed;
86
87struct q6adm_session_map_node_v5 {
88 u16 session_id;
89 u16 num_copps;
90} __packed;
91
92static struct q6copp *q6adm_find_copp(struct q6adm *adm, int port_idx,
93 int copp_idx)
94{
95 struct q6copp *c = NULL;
96 struct q6copp *ret = NULL;
97 unsigned long flags;
98
99 spin_lock_irqsave(&adm->copps_list_lock, flags);
100 list_for_each_entry(c, &adm->copps_list, node) {
101 if ((port_idx == c->afe_port) && (copp_idx == c->copp_idx)) {
102 ret = c;
103 kref_get(&c->refcount);
104 break;
105 }
106 }
107
108 spin_unlock_irqrestore(&adm->copps_list_lock, flags);
109
110 return ret;
111
112}
113
114static void q6adm_free_copp(struct kref *ref)
115{
116 struct q6copp *c = container_of(ref, struct q6copp, refcount);
117 struct q6adm *adm = c->adm;
118 unsigned long flags;
119
120 spin_lock_irqsave(&adm->copps_list_lock, flags);
121 clear_bit(c->copp_idx, &adm->copp_bitmap[c->afe_port]);
122 list_del(&c->node);
123 spin_unlock_irqrestore(&adm->copps_list_lock, flags);
124 kfree(c);
125}
126
127static int q6adm_callback(struct apr_device *adev, struct apr_resp_pkt *data)
128{
129 struct aprv2_ibasic_rsp_result_t *result = data->payload;
130 int port_idx, copp_idx;
131 struct apr_hdr *hdr = &data->hdr;
132 struct q6copp *copp;
133 struct q6adm *adm = dev_get_drvdata(&adev->dev);
134
135 if (!data->payload_size)
136 return 0;
137
138 copp_idx = (hdr->token) & 0XFF;
139 port_idx = ((hdr->token) >> 16) & 0xFF;
140 if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
141 dev_err(&adev->dev, "Invalid port idx %d token %d\n",
142 port_idx, hdr->token);
143 return 0;
144 }
145 if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
146 dev_err(&adev->dev, "Invalid copp idx %d token %d\n",
147 copp_idx, hdr->token);
148 return 0;
149 }
150
151 switch (hdr->opcode) {
152 case APR_BASIC_RSP_RESULT: {
153 if (result->status != 0) {
154 dev_err(&adev->dev, "cmd = 0x%x return error = 0x%x\n",
155 result->opcode, result->status);
156 }
157 switch (result->opcode) {
158 case ADM_CMD_DEVICE_OPEN_V5:
159 case ADM_CMD_DEVICE_CLOSE_V5:
160 copp = q6adm_find_copp(adm, port_idx, copp_idx);
161 if (!copp)
162 return 0;
163
164 copp->result = *result;
165 wake_up(&copp->wait);
166 kref_put(&copp->refcount, q6adm_free_copp);
167 break;
168 case ADM_CMD_MATRIX_MAP_ROUTINGS_V5:
169 adm->result = *result;
170 wake_up(&adm->matrix_map_wait);
171 break;
172
173 default:
174 dev_err(&adev->dev, "Unknown Cmd: 0x%x\n",
175 result->opcode);
176 break;
177 }
178 return 0;
179 }
180 case ADM_CMDRSP_DEVICE_OPEN_V5: {
181 struct adm_cmd_rsp_device_open_v5 {
182 u32 status;
183 u16 copp_id;
184 u16 reserved;
185 } __packed * open = data->payload;
186
187 copp = q6adm_find_copp(adm, port_idx, copp_idx);
188 if (!copp)
189 return 0;
190
191 if (open->copp_id == INVALID_COPP_ID) {
192 dev_err(&adev->dev, "Invalid coppid rxed %d\n",
193 open->copp_id);
194 copp->result.status = ADSP_EBADPARAM;
195 wake_up(&copp->wait);
196 kref_put(&copp->refcount, q6adm_free_copp);
197 break;
198 }
199 copp->result.opcode = hdr->opcode;
200 copp->id = open->copp_id;
201 wake_up(&copp->wait);
202 kref_put(&copp->refcount, q6adm_free_copp);
203 }
204 break;
205 default:
206 dev_err(&adev->dev, "Unknown cmd:0x%x\n",
207 hdr->opcode);
208 break;
209 }
210
211 return 0;
212}
213
214static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx)
215{
216 struct q6copp *c;
217 int idx;
218
219 idx = find_first_zero_bit(&adm->copp_bitmap[port_idx],
220 MAX_COPPS_PER_PORT);
221
222 if (idx > MAX_COPPS_PER_PORT)
223 return ERR_PTR(-EBUSY);
224
225 c = kzalloc(sizeof(*c), GFP_ATOMIC);
226 if (!c)
227 return ERR_PTR(-ENOMEM);
228
229 set_bit(idx, &adm->copp_bitmap[port_idx]);
230 c->copp_idx = idx;
231 c->afe_port = port_idx;
232 c->adm = adm;
233
234 init_waitqueue_head(&c->wait);
235
236 return c;
237}
238
239static int q6adm_apr_send_copp_pkt(struct q6adm *adm, struct q6copp *copp,
240 struct apr_pkt *pkt, uint32_t rsp_opcode)
241{
242 struct device *dev = adm->dev;
243 uint32_t opcode = pkt->hdr.opcode;
244 int ret;
245
246 mutex_lock(&adm->lock);
247 copp->result.opcode = 0;
248 copp->result.status = 0;
249 ret = apr_send_pkt(adm->apr, pkt);
250 if (ret < 0) {
251 dev_err(dev, "Failed to send APR packet\n");
252 ret = -EINVAL;
253 goto err;
254 }
255
256 /* Wait for the callback with copp id */
257 if (rsp_opcode)
258 ret = wait_event_timeout(copp->wait,
259 (copp->result.opcode == opcode) ||
260 (copp->result.opcode == rsp_opcode),
261 msecs_to_jiffies(TIMEOUT_MS));
262 else
263 ret = wait_event_timeout(copp->wait,
264 (copp->result.opcode == opcode),
265 msecs_to_jiffies(TIMEOUT_MS));
266
267 if (!ret) {
268 dev_err(dev, "ADM copp cmd timedout\n");
269 ret = -ETIMEDOUT;
270 } else if (copp->result.status > 0) {
271 dev_err(dev, "DSP returned error[%d]\n",
272 copp->result.status);
273 ret = -EINVAL;
274 }
275
276err:
277 mutex_unlock(&adm->lock);
278 return ret;
279}
280
281static int q6adm_device_close(struct q6adm *adm, struct q6copp *copp,
282 int port_id, int copp_idx)
283{
284 struct apr_pkt close;
285
286 close.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
287 APR_HDR_LEN(APR_HDR_SIZE),
288 APR_PKT_VER);
289 close.hdr.pkt_size = sizeof(close);
290 close.hdr.src_port = port_id;
291 close.hdr.dest_port = copp->id;
292 close.hdr.token = port_id << 16 | copp_idx;
293 close.hdr.opcode = ADM_CMD_DEVICE_CLOSE_V5;
294
295 return q6adm_apr_send_copp_pkt(adm, copp, &close, 0);
296}
297
298static struct q6copp *q6adm_find_matching_copp(struct q6adm *adm,
299 int port_id, int topology,
300 int mode, int rate,
301 int channel_mode, int bit_width,
302 int app_type)
303{
304 struct q6copp *c = NULL;
305 struct q6copp *ret = NULL;
306 unsigned long flags;
307
308 spin_lock_irqsave(&adm->copps_list_lock, flags);
309
310 list_for_each_entry(c, &adm->copps_list, node) {
311 if ((port_id == c->afe_port) && (topology == c->topology) &&
312 (mode == c->mode) && (rate == c->rate) &&
313 (bit_width == c->bit_width) && (app_type == c->app_type)) {
314 ret = c;
315 kref_get(&c->refcount);
316 }
317 }
318 spin_unlock_irqrestore(&adm->copps_list_lock, flags);
319
320 return ret;
321}
322
323static int q6adm_device_open(struct q6adm *adm, struct q6copp *copp,
324 int port_id, int path, int topology,
325 int channel_mode, int bit_width, int rate)
326{
327 struct q6adm_cmd_device_open_v5 *open;
328 int afe_port = q6afe_get_port_id(port_id);
329 struct apr_pkt *pkt;
330 void *p;
331 int ret, pkt_size;
332
333 pkt_size = APR_HDR_SIZE + sizeof(*open);
334 p = kzalloc(pkt_size, GFP_KERNEL);
335 if (!p)
336 return -ENOMEM;
337
338 pkt = p;
339 open = p + APR_HDR_SIZE;
340 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
341 APR_HDR_LEN(APR_HDR_SIZE),
342 APR_PKT_VER);
343 pkt->hdr.pkt_size = pkt_size;
344 pkt->hdr.src_port = afe_port;
345 pkt->hdr.dest_port = afe_port;
346 pkt->hdr.token = port_id << 16 | copp->copp_idx;
347 pkt->hdr.opcode = ADM_CMD_DEVICE_OPEN_V5;
348 open->flags = ADM_LEGACY_DEVICE_SESSION;
349 open->mode_of_operation = path;
350 open->endpoint_id_1 = afe_port;
351 open->topology_id = topology;
352 open->dev_num_channel = channel_mode & 0x00FF;
353 open->bit_width = bit_width;
354 open->sample_rate = rate;
355
356 ret = q6dsp_map_channels(&open->dev_channel_mapping[0],
357 channel_mode);
358 if (ret)
359 goto err;
360
361 ret = q6adm_apr_send_copp_pkt(adm, copp, pkt,
362 ADM_CMDRSP_DEVICE_OPEN_V5);
363
364err:
365 kfree(pkt);
366 return ret;
367}
368
369/**
370 * q6adm_open() - open adm and grab a free copp
371 *
372 * @dev: Pointer to adm child device.
373 * @port_id: port id
374 * @path: playback or capture path.
375 * @rate: rate at which copp is required.
376 * @channel_mode: channel mode
377 * @topology: adm topology id
378 * @perf_mode: performace mode.
379 * @bit_width: audio sample bit width
380 * @app_type: Application type.
381 * @acdb_id: ACDB id
382 *
383 * Return: Will be an negative on error or a valid copp pointer on success.
384 */
385struct q6copp *q6adm_open(struct device *dev, int port_id, int path, int rate,
386 int channel_mode, int topology, int perf_mode,
387 uint16_t bit_width, int app_type, int acdb_id)
388{
389 struct q6adm *adm = dev_get_drvdata(dev->parent);
390 struct q6copp *copp;
391 unsigned long flags;
392 int ret = 0;
393
394 if (port_id < 0) {
395 dev_err(dev, "Invalid port_id 0x%x\n", port_id);
396 return ERR_PTR(-EINVAL);
397 }
398
399 copp = q6adm_find_matching_copp(adm, port_id, topology, perf_mode,
400 rate, channel_mode, bit_width, app_type);
401 if (copp) {
402 dev_err(dev, "Found Matching Copp 0x%x\n", copp->copp_idx);
403 return copp;
404 }
405
406 spin_lock_irqsave(&adm->copps_list_lock, flags);
407 copp = q6adm_alloc_copp(adm, port_id);
408 if (IS_ERR_OR_NULL(copp)) {
409 spin_unlock_irqrestore(&adm->copps_list_lock, flags);
410 return ERR_CAST(copp);
411 }
412
413 list_add_tail(&copp->node, &adm->copps_list);
414 spin_unlock_irqrestore(&adm->copps_list_lock, flags);
415
416 kref_init(&copp->refcount);
417 copp->topology = topology;
418 copp->mode = perf_mode;
419 copp->rate = rate;
420 copp->channels = channel_mode;
421 copp->bit_width = bit_width;
422 copp->app_type = app_type;
423
424
425 ret = q6adm_device_open(adm, copp, port_id, path, topology,
426 channel_mode, bit_width, rate);
427 if (ret < 0) {
428 kref_put(&copp->refcount, q6adm_free_copp);
429 return ERR_PTR(ret);
430 }
431
432 return copp;
433}
434EXPORT_SYMBOL_GPL(q6adm_open);
435
436/**
437 * q6adm_get_copp_id() - get copp index
438 *
439 * @copp: Pointer to valid copp
440 *
441 * Return: Will be an negative on error or a valid copp index on success.
442 **/
443int q6adm_get_copp_id(struct q6copp *copp)
444{
445 if (!copp)
446 return -EINVAL;
447
448 return copp->copp_idx;
449}
450EXPORT_SYMBOL_GPL(q6adm_get_copp_id);
451
452/**
453 * q6adm_matrix_map() - Map asm streams and afe ports using payload
454 *
455 * @dev: Pointer to adm child device.
456 * @path: playback or capture path.
457 * @payload_map: map between session id and afe ports.
458 * @perf_mode: Performace mode.
459 *
460 * Return: Will be an negative on error or a zero on success.
461 */
462int q6adm_matrix_map(struct device *dev, int path,
463 struct route_payload payload_map, int perf_mode)
464{
465 struct q6adm *adm = dev_get_drvdata(dev->parent);
466 struct q6adm_cmd_matrix_map_routings_v5 *route;
467 struct q6adm_session_map_node_v5 *node;
468 struct apr_pkt *pkt;
469 uint16_t *copps_list;
470 int pkt_size, ret, i, copp_idx;
471 void *matrix_map = NULL;
472 struct q6copp *copp;
473
474 /* Assumes port_ids have already been validated during adm_open */
475 pkt_size = (APR_HDR_SIZE + sizeof(*route) + sizeof(*node) +
476 (sizeof(uint32_t) * payload_map.num_copps));
477
478 matrix_map = kzalloc(pkt_size, GFP_KERNEL);
479 if (!matrix_map)
480 return -ENOMEM;
481
482 pkt = matrix_map;
483 route = matrix_map + APR_HDR_SIZE;
484 node = matrix_map + APR_HDR_SIZE + sizeof(*route);
485 copps_list = matrix_map + APR_HDR_SIZE + sizeof(*route) + sizeof(*node);
486
487 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
488 APR_HDR_LEN(APR_HDR_SIZE),
489 APR_PKT_VER);
490 pkt->hdr.pkt_size = pkt_size;
491 pkt->hdr.token = 0;
492 pkt->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5;
493 route->num_sessions = 1;
494
495 switch (path) {
496 case ADM_PATH_PLAYBACK:
497 route->matrix_id = ADM_MATRIX_ID_AUDIO_RX;
498 break;
499 case ADM_PATH_LIVE_REC:
500 route->matrix_id = ADM_MATRIX_ID_AUDIO_TX;
501 break;
502 default:
503 dev_err(dev, "Wrong path set[%d]\n", path);
504 break;
505 }
506
507 node->session_id = payload_map.session_id;
508 node->num_copps = payload_map.num_copps;
509
510 for (i = 0; i < payload_map.num_copps; i++) {
511 int port_idx = payload_map.port_id[i];
512
513 if (port_idx < 0) {
514 dev_err(dev, "Invalid port_id 0x%x\n",
515 payload_map.port_id[i]);
516 kfree(pkt);
517 return -EINVAL;
518 }
519 copp_idx = payload_map.copp_idx[i];
520
521 copp = q6adm_find_copp(adm, port_idx, copp_idx);
522 if (!copp) {
523 kfree(pkt);
524 return -EINVAL;
525 }
526
527 copps_list[i] = copp->id;
528 kref_put(&copp->refcount, q6adm_free_copp);
529 }
530
531 mutex_lock(&adm->lock);
532 adm->result.status = 0;
533 adm->result.opcode = 0;
534
535 ret = apr_send_pkt(adm->apr, pkt);
536 if (ret < 0) {
537 dev_err(dev, "routing for stream %d failed ret %d\n",
538 payload_map.session_id, ret);
539 goto fail_cmd;
540 }
541 ret = wait_event_timeout(adm->matrix_map_wait,
542 adm->result.opcode == pkt->hdr.opcode,
543 msecs_to_jiffies(TIMEOUT_MS));
544 if (!ret) {
545 dev_err(dev, "routing for stream %d failed\n",
546 payload_map.session_id);
547 ret = -ETIMEDOUT;
548 goto fail_cmd;
549 } else if (adm->result.status > 0) {
550 dev_err(dev, "DSP returned error[%d]\n",
551 adm->result.status);
552 ret = -EINVAL;
553 goto fail_cmd;
554 }
555
556fail_cmd:
557 mutex_unlock(&adm->lock);
558 kfree(pkt);
559 return ret;
560}
561EXPORT_SYMBOL_GPL(q6adm_matrix_map);
562
563/**
564 * q6adm_close() - Close adm copp
565 *
566 * @dev: Pointer to adm child device.
567 * @copp: pointer to previously opened copp
568 *
569 * Return: Will be an negative on error or a zero on success.
570 */
571int q6adm_close(struct device *dev, struct q6copp *copp)
572{
573 struct q6adm *adm = dev_get_drvdata(dev->parent);
574 int ret = 0;
575
576 ret = q6adm_device_close(adm, copp, copp->afe_port, copp->copp_idx);
577 if (ret < 0) {
578 dev_err(adm->dev, "Failed to close copp %d\n", ret);
579 return ret;
580 }
581
582 kref_put(&copp->refcount, q6adm_free_copp);
583
584 return 0;
585}
586EXPORT_SYMBOL_GPL(q6adm_close);
587
588static int q6adm_probe(struct apr_device *adev)
589{
590 struct device *dev = &adev->dev;
591 struct device_node *dais_np;
592 struct q6adm *adm;
593
594 adm = devm_kzalloc(&adev->dev, sizeof(*adm), GFP_KERNEL);
595 if (!adm)
596 return -ENOMEM;
597
598 adm->apr = adev;
599 dev_set_drvdata(&adev->dev, adm);
600 adm->dev = dev;
601 q6core_get_svc_api_info(adev->svc_id, &adm->ainfo);
602 mutex_init(&adm->lock);
603 init_waitqueue_head(&adm->matrix_map_wait);
604
605 INIT_LIST_HEAD(&adm->copps_list);
606 spin_lock_init(&adm->copps_list_lock);
607
608 dais_np = of_get_child_by_name(dev->of_node, "routing");
609 if (dais_np) {
610 adm->pdev_routing = of_platform_device_create(dais_np,
611 "q6routing", dev);
612 of_node_put(dais_np);
613 }
614
615 return 0;
616}
617
618static int q6adm_remove(struct apr_device *adev)
619{
620 struct q6adm *adm = dev_get_drvdata(&adev->dev);
621
622 if (adm->pdev_routing)
623 of_platform_device_destroy(&adm->pdev_routing->dev, NULL);
624
625 return 0;
626}
627
628static const struct of_device_id q6adm_device_id[] = {
629 { .compatible = "qcom,q6adm" },
630 {},
631};
632MODULE_DEVICE_TABLE(of, q6adm_device_id);
633
634static struct apr_driver qcom_q6adm_driver = {
635 .probe = q6adm_probe,
636 .remove = q6adm_remove,
637 .callback = q6adm_callback,
638 .driver = {
639 .name = "qcom-q6adm",
640 .of_match_table = of_match_ptr(q6adm_device_id),
641 },
642};
643
644module_apr_driver(qcom_q6adm_driver);
645MODULE_DESCRIPTION("Q6 Audio Device Manager");
646MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6adm.h b/sound/soc/qcom/qdsp6/q6adm.h
new file mode 100644
index 000000000000..4f56999b7fab
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6adm.h
@@ -0,0 +1,27 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __Q6_ADM_V2_H__
3#define __Q6_ADM_V2_H__
4
5#define ADM_PATH_PLAYBACK 0x1
6#define ADM_PATH_LIVE_REC 0x2
7#define MAX_COPPS_PER_PORT 8
8#define NULL_COPP_TOPOLOGY 0x00010312
9
10/* multiple copp per stream. */
11struct route_payload {
12 int num_copps;
13 int session_id;
14 int copp_idx[MAX_COPPS_PER_PORT];
15 int port_id[MAX_COPPS_PER_PORT];
16};
17
18struct q6copp;
19struct q6copp *q6adm_open(struct device *dev, int port_id, int path, int rate,
20 int channel_mode, int topology, int perf_mode,
21 uint16_t bit_width, int app_type, int acdb_id);
22int q6adm_close(struct device *dev, struct q6copp *copp);
23int q6adm_get_copp_id(struct q6copp *copp);
24int q6adm_matrix_map(struct device *dev, int path,
25 struct route_payload payload_map, int perf_mode);
26
27#endif /* __Q6_ADM_V2_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
new file mode 100644
index 000000000000..5002dd05bf27
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -0,0 +1,1303 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/err.h>
6#include <linux/init.h>
7#include <linux/component.h>
8#include <linux/module.h>
9#include <linux/device.h>
10#include <linux/platform_device.h>
11#include <linux/slab.h>
12#include <sound/pcm.h>
13#include <sound/soc.h>
14#include <sound/pcm_params.h>
15#include "q6afe.h"
16
17#define Q6AFE_TDM_PB_DAI(pre, num, did) { \
18 .playback = { \
19 .stream_name = pre" TDM"#num" Playback", \
20 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
21 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
22 SNDRV_PCM_RATE_176400, \
23 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
24 SNDRV_PCM_FMTBIT_S24_LE | \
25 SNDRV_PCM_FMTBIT_S32_LE, \
26 .channels_min = 1, \
27 .channels_max = 8, \
28 .rate_min = 8000, \
29 .rate_max = 176400, \
30 }, \
31 .name = #did, \
32 .ops = &q6tdm_ops, \
33 .id = did, \
34 .probe = msm_dai_q6_dai_probe, \
35 .remove = msm_dai_q6_dai_remove, \
36 }
37
38#define Q6AFE_TDM_CAP_DAI(pre, num, did) { \
39 .capture = { \
40 .stream_name = pre" TDM"#num" Capture", \
41 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
42 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
43 SNDRV_PCM_RATE_176400, \
44 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
45 SNDRV_PCM_FMTBIT_S24_LE | \
46 SNDRV_PCM_FMTBIT_S32_LE, \
47 .channels_min = 1, \
48 .channels_max = 8, \
49 .rate_min = 8000, \
50 .rate_max = 176400, \
51 }, \
52 .name = #did, \
53 .ops = &q6tdm_ops, \
54 .id = did, \
55 .probe = msm_dai_q6_dai_probe, \
56 .remove = msm_dai_q6_dai_remove, \
57 }
58
59struct q6afe_dai_priv_data {
60 uint32_t sd_line_mask;
61 uint32_t sync_mode;
62 uint32_t sync_src;
63 uint32_t data_out_enable;
64 uint32_t invert_sync;
65 uint32_t data_delay;
66 uint32_t data_align;
67};
68
69struct q6afe_dai_data {
70 struct q6afe_port *port[AFE_PORT_MAX];
71 struct q6afe_port_config port_config[AFE_PORT_MAX];
72 bool is_port_started[AFE_PORT_MAX];
73 struct q6afe_dai_priv_data priv[AFE_PORT_MAX];
74};
75
76static int q6slim_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params,
78 struct snd_soc_dai *dai)
79{
80
81 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
82 struct q6afe_slim_cfg *slim = &dai_data->port_config[dai->id].slim;
83
84 slim->num_channels = params_channels(params);
85 slim->sample_rate = params_rate(params);
86
87 switch (params_format(params)) {
88 case SNDRV_PCM_FORMAT_S16_LE:
89 case SNDRV_PCM_FORMAT_SPECIAL:
90 slim->bit_width = 16;
91 break;
92 case SNDRV_PCM_FORMAT_S24_LE:
93 slim->bit_width = 24;
94 break;
95 case SNDRV_PCM_FORMAT_S32_LE:
96 slim->bit_width = 32;
97 break;
98 default:
99 pr_err("%s: format %d\n",
100 __func__, params_format(params));
101 return -EINVAL;
102 }
103
104 return 0;
105}
106
107static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
108 struct snd_pcm_hw_params *params,
109 struct snd_soc_dai *dai)
110{
111 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
112 int channels = params_channels(params);
113 struct q6afe_hdmi_cfg *hdmi = &dai_data->port_config[dai->id].hdmi;
114
115 hdmi->sample_rate = params_rate(params);
116 switch (params_format(params)) {
117 case SNDRV_PCM_FORMAT_S16_LE:
118 hdmi->bit_width = 16;
119 break;
120 case SNDRV_PCM_FORMAT_S24_LE:
121 hdmi->bit_width = 24;
122 break;
123 }
124
125 /* HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4 */
126 switch (channels) {
127 case 2:
128 hdmi->channel_allocation = 0;
129 break;
130 case 3:
131 hdmi->channel_allocation = 0x02;
132 break;
133 case 4:
134 hdmi->channel_allocation = 0x06;
135 break;
136 case 5:
137 hdmi->channel_allocation = 0x0A;
138 break;
139 case 6:
140 hdmi->channel_allocation = 0x0B;
141 break;
142 case 7:
143 hdmi->channel_allocation = 0x12;
144 break;
145 case 8:
146 hdmi->channel_allocation = 0x13;
147 break;
148 default:
149 dev_err(dai->dev, "invalid Channels = %u\n", channels);
150 return -EINVAL;
151 }
152
153 return 0;
154}
155
156static int q6i2s_hw_params(struct snd_pcm_substream *substream,
157 struct snd_pcm_hw_params *params,
158 struct snd_soc_dai *dai)
159{
160 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
161 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg;
162
163 i2s->sample_rate = params_rate(params);
164 i2s->bit_width = params_width(params);
165 i2s->num_channels = params_channels(params);
166 i2s->sd_line_mask = dai_data->priv[dai->id].sd_line_mask;
167
168 return 0;
169}
170
171static int q6i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
172{
173 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
174 struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg;
175
176 i2s->fmt = fmt;
177
178 return 0;
179}
180
181static int q6tdm_set_tdm_slot(struct snd_soc_dai *dai,
182 unsigned int tx_mask,
183 unsigned int rx_mask,
184 int slots, int slot_width)
185{
186
187 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
188 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
189 unsigned int cap_mask;
190 int rc = 0;
191
192 /* HW only supports 16 and 32 bit slot width configuration */
193 if ((slot_width != 16) && (slot_width != 32)) {
194 dev_err(dai->dev, "%s: invalid slot_width %d\n",
195 __func__, slot_width);
196 return -EINVAL;
197 }
198
199 /* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */
200 switch (slots) {
201 case 2:
202 cap_mask = 0x03;
203 break;
204 case 4:
205 cap_mask = 0x0F;
206 break;
207 case 8:
208 cap_mask = 0xFF;
209 break;
210 case 16:
211 cap_mask = 0xFFFF;
212 break;
213 default:
214 dev_err(dai->dev, "%s: invalid slots %d\n",
215 __func__, slots);
216 return -EINVAL;
217 }
218
219 switch (dai->id) {
220 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
221 tdm->nslots_per_frame = slots;
222 tdm->slot_width = slot_width;
223 /* TDM RX dais ids are even and tx are odd */
224 tdm->slot_mask = (dai->id & 0x1 ? tx_mask : rx_mask) & cap_mask;
225 break;
226 default:
227 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
228 __func__, dai->id);
229 return -EINVAL;
230 }
231
232 return rc;
233}
234
235static int q6tdm_set_channel_map(struct snd_soc_dai *dai,
236 unsigned int tx_num, unsigned int *tx_slot,
237 unsigned int rx_num, unsigned int *rx_slot)
238{
239
240 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
241 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
242 int rc = 0;
243 int i = 0;
244
245 switch (dai->id) {
246 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
247 if (dai->id & 0x1) {
248 if (!tx_slot) {
249 dev_err(dai->dev, "tx slot not found\n");
250 return -EINVAL;
251 }
252 if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
253 dev_err(dai->dev, "invalid tx num %d\n",
254 tx_num);
255 return -EINVAL;
256 }
257
258 for (i = 0; i < tx_num; i++)
259 tdm->ch_mapping[i] = tx_slot[i];
260
261 for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
262 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID;
263
264 tdm->num_channels = tx_num;
265 } else {
266 /* rx */
267 if (!rx_slot) {
268 dev_err(dai->dev, "rx slot not found\n");
269 return -EINVAL;
270 }
271 if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
272 dev_err(dai->dev, "invalid rx num %d\n",
273 rx_num);
274 return -EINVAL;
275 }
276
277 for (i = 0; i < rx_num; i++)
278 tdm->ch_mapping[i] = rx_slot[i];
279
280 for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
281 tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID;
282
283 tdm->num_channels = rx_num;
284 }
285
286 break;
287 default:
288 dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
289 __func__, dai->id);
290 return -EINVAL;
291 }
292
293 return rc;
294}
295
296static int q6tdm_hw_params(struct snd_pcm_substream *substream,
297 struct snd_pcm_hw_params *params,
298 struct snd_soc_dai *dai)
299{
300 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
301 struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
302
303 tdm->bit_width = params_width(params);
304 tdm->sample_rate = params_rate(params);
305 tdm->num_channels = params_channels(params);
306 tdm->data_align_type = dai_data->priv[dai->id].data_align;
307 tdm->sync_src = dai_data->priv[dai->id].sync_src;
308 tdm->sync_mode = dai_data->priv[dai->id].sync_mode;
309
310 return 0;
311}
312static void q6afe_dai_shutdown(struct snd_pcm_substream *substream,
313 struct snd_soc_dai *dai)
314{
315 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
316 int rc;
317
318 rc = q6afe_port_stop(dai_data->port[dai->id]);
319 if (rc < 0)
320 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc);
321
322 dai_data->is_port_started[dai->id] = false;
323
324}
325
326static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
327 struct snd_soc_dai *dai)
328{
329 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
330 int rc;
331
332 if (dai_data->is_port_started[dai->id]) {
333 /* stop the port and restart with new port config */
334 rc = q6afe_port_stop(dai_data->port[dai->id]);
335 if (rc < 0) {
336 dev_err(dai->dev, "fail to close AFE port (%d)\n", rc);
337 return rc;
338 }
339 }
340
341 switch (dai->id) {
342 case HDMI_RX:
343 q6afe_hdmi_port_prepare(dai_data->port[dai->id],
344 &dai_data->port_config[dai->id].hdmi);
345 break;
346 case SLIMBUS_0_RX ... SLIMBUS_6_TX:
347 q6afe_slim_port_prepare(dai_data->port[dai->id],
348 &dai_data->port_config[dai->id].slim);
349 break;
350 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
351 rc = q6afe_i2s_port_prepare(dai_data->port[dai->id],
352 &dai_data->port_config[dai->id].i2s_cfg);
353 if (rc < 0) {
354 dev_err(dai->dev, "fail to prepare AFE port %x\n",
355 dai->id);
356 return rc;
357 }
358 break;
359 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
360 q6afe_tdm_port_prepare(dai_data->port[dai->id],
361 &dai_data->port_config[dai->id].tdm);
362 break;
363 default:
364 return -EINVAL;
365 }
366
367 rc = q6afe_port_start(dai_data->port[dai->id]);
368 if (rc < 0) {
369 dev_err(dai->dev, "fail to start AFE port %x\n", dai->id);
370 return rc;
371 }
372 dai_data->is_port_started[dai->id] = true;
373
374 return 0;
375}
376
377static int q6slim_set_channel_map(struct snd_soc_dai *dai,
378 unsigned int tx_num, unsigned int *tx_slot,
379 unsigned int rx_num, unsigned int *rx_slot)
380{
381 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
382 struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id];
383 int i;
384
385 if (!rx_slot) {
386 pr_err("%s: rx slot not found\n", __func__);
387 return -EINVAL;
388 }
389
390 for (i = 0; i < rx_num; i++) {
391 pcfg->slim.ch_mapping[i] = rx_slot[i];
392 pr_debug("%s: find number of channels[%d] ch[%d]\n",
393 __func__, i, rx_slot[i]);
394 }
395
396 pcfg->slim.num_channels = rx_num;
397
398 pr_debug("%s: SLIMBUS_%d_RX cnt[%d] ch[%d %d]\n", __func__,
399 (dai->id - SLIMBUS_0_RX) / 2, rx_num,
400 pcfg->slim.ch_mapping[0],
401 pcfg->slim.ch_mapping[1]);
402
403 return 0;
404}
405
406static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai,
407 int clk_id, unsigned int freq, int dir)
408{
409 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
410 struct q6afe_port *port = dai_data->port[dai->id];
411
412 switch (clk_id) {
413 case LPAIF_DIG_CLK:
414 return q6afe_port_set_sysclk(port, clk_id, 0, 5, freq, dir);
415 case LPAIF_BIT_CLK:
416 case LPAIF_OSR_CLK:
417 return q6afe_port_set_sysclk(port, clk_id,
418 Q6AFE_LPASS_CLK_SRC_INTERNAL,
419 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
420 freq, dir);
421 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
422 case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
423 return q6afe_port_set_sysclk(port, clk_id,
424 Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
425 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
426 freq, dir);
427 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
428 return q6afe_port_set_sysclk(port, clk_id,
429 Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO,
430 Q6AFE_LPASS_CLK_ROOT_DEFAULT,
431 freq, dir);
432 }
433
434 return 0;
435}
436
437static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
438 {"HDMI Playback", NULL, "HDMI_RX"},
439 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"},
440 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"},
441 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"},
442 {"Slimbus4 Playback", NULL, "SLIMBUS_4_RX"},
443 {"Slimbus5 Playback", NULL, "SLIMBUS_5_RX"},
444 {"Slimbus6 Playback", NULL, "SLIMBUS_6_RX"},
445
446 {"Primary MI2S Playback", NULL, "PRI_MI2S_RX"},
447 {"Secondary MI2S Playback", NULL, "SEC_MI2S_RX"},
448 {"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"},
449 {"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"},
450
451 {"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"},
452 {"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"},
453 {"Primary TDM2 Playback", NULL, "PRIMARY_TDM_RX_2"},
454 {"Primary TDM3 Playback", NULL, "PRIMARY_TDM_RX_3"},
455 {"Primary TDM4 Playback", NULL, "PRIMARY_TDM_RX_4"},
456 {"Primary TDM5 Playback", NULL, "PRIMARY_TDM_RX_5"},
457 {"Primary TDM6 Playback", NULL, "PRIMARY_TDM_RX_6"},
458 {"Primary TDM7 Playback", NULL, "PRIMARY_TDM_RX_7"},
459
460 {"Secondary TDM0 Playback", NULL, "SEC_TDM_RX_0"},
461 {"Secondary TDM1 Playback", NULL, "SEC_TDM_RX_1"},
462 {"Secondary TDM2 Playback", NULL, "SEC_TDM_RX_2"},
463 {"Secondary TDM3 Playback", NULL, "SEC_TDM_RX_3"},
464 {"Secondary TDM4 Playback", NULL, "SEC_TDM_RX_4"},
465 {"Secondary TDM5 Playback", NULL, "SEC_TDM_RX_5"},
466 {"Secondary TDM6 Playback", NULL, "SEC_TDM_RX_6"},
467 {"Secondary TDM7 Playback", NULL, "SEC_TDM_RX_7"},
468
469 {"Tertiary TDM0 Playback", NULL, "TERT_TDM_RX_0"},
470 {"Tertiary TDM1 Playback", NULL, "TERT_TDM_RX_1"},
471 {"Tertiary TDM2 Playback", NULL, "TERT_TDM_RX_2"},
472 {"Tertiary TDM3 Playback", NULL, "TERT_TDM_RX_3"},
473 {"Tertiary TDM4 Playback", NULL, "TERT_TDM_RX_4"},
474 {"Tertiary TDM5 Playback", NULL, "TERT_TDM_RX_5"},
475 {"Tertiary TDM6 Playback", NULL, "TERT_TDM_RX_6"},
476 {"Tertiary TDM7 Playback", NULL, "TERT_TDM_RX_7"},
477
478 {"Quaternary TDM0 Playback", NULL, "QUAT_TDM_RX_0"},
479 {"Quaternary TDM1 Playback", NULL, "QUAT_TDM_RX_1"},
480 {"Quaternary TDM2 Playback", NULL, "QUAT_TDM_RX_2"},
481 {"Quaternary TDM3 Playback", NULL, "QUAT_TDM_RX_3"},
482 {"Quaternary TDM4 Playback", NULL, "QUAT_TDM_RX_4"},
483 {"Quaternary TDM5 Playback", NULL, "QUAT_TDM_RX_5"},
484 {"Quaternary TDM6 Playback", NULL, "QUAT_TDM_RX_6"},
485 {"Quaternary TDM7 Playback", NULL, "QUAT_TDM_RX_7"},
486
487 {"Quinary TDM0 Playback", NULL, "QUIN_TDM_RX_0"},
488 {"Quinary TDM1 Playback", NULL, "QUIN_TDM_RX_1"},
489 {"Quinary TDM2 Playback", NULL, "QUIN_TDM_RX_2"},
490 {"Quinary TDM3 Playback", NULL, "QUIN_TDM_RX_3"},
491 {"Quinary TDM4 Playback", NULL, "QUIN_TDM_RX_4"},
492 {"Quinary TDM5 Playback", NULL, "QUIN_TDM_RX_5"},
493 {"Quinary TDM6 Playback", NULL, "QUIN_TDM_RX_6"},
494 {"Quinary TDM7 Playback", NULL, "QUIN_TDM_RX_7"},
495
496 {"PRIMARY_TDM_TX_0", NULL, "Primary TDM0 Capture"},
497 {"PRIMARY_TDM_TX_1", NULL, "Primary TDM1 Capture"},
498 {"PRIMARY_TDM_TX_2", NULL, "Primary TDM2 Capture"},
499 {"PRIMARY_TDM_TX_3", NULL, "Primary TDM3 Capture"},
500 {"PRIMARY_TDM_TX_4", NULL, "Primary TDM4 Capture"},
501 {"PRIMARY_TDM_TX_5", NULL, "Primary TDM5 Capture"},
502 {"PRIMARY_TDM_TX_6", NULL, "Primary TDM6 Capture"},
503 {"PRIMARY_TDM_TX_7", NULL, "Primary TDM7 Capture"},
504
505 {"SEC_TDM_TX_0", NULL, "Secondary TDM0 Capture"},
506 {"SEC_TDM_TX_1", NULL, "Secondary TDM1 Capture"},
507 {"SEC_TDM_TX_2", NULL, "Secondary TDM2 Capture"},
508 {"SEC_TDM_TX_3", NULL, "Secondary TDM3 Capture"},
509 {"SEC_TDM_TX_4", NULL, "Secondary TDM4 Capture"},
510 {"SEC_TDM_TX_5", NULL, "Secondary TDM5 Capture"},
511 {"SEC_TDM_TX_6", NULL, "Secondary TDM6 Capture"},
512 {"SEC_TDM_TX_7", NULL, "Secondary TDM7 Capture"},
513
514 {"TERT_TDM_TX_0", NULL, "Tertiary TDM0 Capture"},
515 {"TERT_TDM_TX_1", NULL, "Tertiary TDM1 Capture"},
516 {"TERT_TDM_TX_2", NULL, "Tertiary TDM2 Capture"},
517 {"TERT_TDM_TX_3", NULL, "Tertiary TDM3 Capture"},
518 {"TERT_TDM_TX_4", NULL, "Tertiary TDM4 Capture"},
519 {"TERT_TDM_TX_5", NULL, "Tertiary TDM5 Capture"},
520 {"TERT_TDM_TX_6", NULL, "Tertiary TDM6 Capture"},
521 {"TERT_TDM_TX_7", NULL, "Tertiary TDM7 Capture"},
522
523 {"QUAT_TDM_TX_0", NULL, "Quaternary TDM0 Capture"},
524 {"QUAT_TDM_TX_1", NULL, "Quaternary TDM1 Capture"},
525 {"QUAT_TDM_TX_2", NULL, "Quaternary TDM2 Capture"},
526 {"QUAT_TDM_TX_3", NULL, "Quaternary TDM3 Capture"},
527 {"QUAT_TDM_TX_4", NULL, "Quaternary TDM4 Capture"},
528 {"QUAT_TDM_TX_5", NULL, "Quaternary TDM5 Capture"},
529 {"QUAT_TDM_TX_6", NULL, "Quaternary TDM6 Capture"},
530 {"QUAT_TDM_TX_7", NULL, "Quaternary TDM7 Capture"},
531
532 {"QUIN_TDM_TX_0", NULL, "Quinary TDM0 Capture"},
533 {"QUIN_TDM_TX_1", NULL, "Quinary TDM1 Capture"},
534 {"QUIN_TDM_TX_2", NULL, "Quinary TDM2 Capture"},
535 {"QUIN_TDM_TX_3", NULL, "Quinary TDM3 Capture"},
536 {"QUIN_TDM_TX_4", NULL, "Quinary TDM4 Capture"},
537 {"QUIN_TDM_TX_5", NULL, "Quinary TDM5 Capture"},
538 {"QUIN_TDM_TX_6", NULL, "Quinary TDM6 Capture"},
539 {"QUIN_TDM_TX_7", NULL, "Quinary TDM7 Capture"},
540
541 {"TERT_MI2S_TX", NULL, "Tertiary MI2S Capture"},
542 {"PRI_MI2S_TX", NULL, "Primary MI2S Capture"},
543 {"SEC_MI2S_TX", NULL, "Secondary MI2S Capture"},
544 {"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"},
545};
546
547static struct snd_soc_dai_ops q6hdmi_ops = {
548 .prepare = q6afe_dai_prepare,
549 .hw_params = q6hdmi_hw_params,
550 .shutdown = q6afe_dai_shutdown,
551};
552
553static struct snd_soc_dai_ops q6i2s_ops = {
554 .prepare = q6afe_dai_prepare,
555 .hw_params = q6i2s_hw_params,
556 .set_fmt = q6i2s_set_fmt,
557 .shutdown = q6afe_dai_shutdown,
558 .set_sysclk = q6afe_mi2s_set_sysclk,
559};
560
561static struct snd_soc_dai_ops q6slim_ops = {
562 .prepare = q6afe_dai_prepare,
563 .hw_params = q6slim_hw_params,
564 .shutdown = q6afe_dai_shutdown,
565 .set_channel_map = q6slim_set_channel_map,
566};
567
568static struct snd_soc_dai_ops q6tdm_ops = {
569 .prepare = q6afe_dai_prepare,
570 .shutdown = q6afe_dai_shutdown,
571 .set_sysclk = q6afe_mi2s_set_sysclk,
572 .set_tdm_slot = q6tdm_set_tdm_slot,
573 .set_channel_map = q6tdm_set_channel_map,
574 .hw_params = q6tdm_hw_params,
575};
576
577static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
578{
579 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
580 struct q6afe_port *port;
581
582 port = q6afe_port_get_from_id(dai->dev, dai->id);
583 if (IS_ERR(port)) {
584 dev_err(dai->dev, "Unable to get afe port\n");
585 return -EINVAL;
586 }
587 dai_data->port[dai->id] = port;
588
589 return 0;
590}
591
592static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
593{
594 struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
595
596 q6afe_port_put(dai_data->port[dai->id]);
597 dai_data->port[dai->id] = NULL;
598
599 return 0;
600}
601
602static struct snd_soc_dai_driver q6afe_dais[] = {
603 {
604 .playback = {
605 .stream_name = "HDMI Playback",
606 .rates = SNDRV_PCM_RATE_48000 |
607 SNDRV_PCM_RATE_96000 |
608 SNDRV_PCM_RATE_192000,
609 .formats = SNDRV_PCM_FMTBIT_S16_LE |
610 SNDRV_PCM_FMTBIT_S24_LE,
611 .channels_min = 2,
612 .channels_max = 8,
613 .rate_max = 192000,
614 .rate_min = 48000,
615 },
616 .ops = &q6hdmi_ops,
617 .id = HDMI_RX,
618 .name = "HDMI",
619 .probe = msm_dai_q6_dai_probe,
620 .remove = msm_dai_q6_dai_remove,
621 }, {
622 .name = "SLIMBUS_0_RX",
623 .ops = &q6slim_ops,
624 .id = SLIMBUS_0_RX,
625 .probe = msm_dai_q6_dai_probe,
626 .remove = msm_dai_q6_dai_remove,
627 .playback = {
628 .stream_name = "Slimbus Playback",
629 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
630 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
631 SNDRV_PCM_RATE_192000,
632 .formats = SNDRV_PCM_FMTBIT_S16_LE |
633 SNDRV_PCM_FMTBIT_S24_LE,
634 .channels_min = 1,
635 .channels_max = 8,
636 .rate_min = 8000,
637 .rate_max = 192000,
638 },
639 }, {
640 .playback = {
641 .stream_name = "Slimbus1 Playback",
642 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
643 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
644 SNDRV_PCM_RATE_192000,
645 .formats = SNDRV_PCM_FMTBIT_S16_LE |
646 SNDRV_PCM_FMTBIT_S24_LE,
647 .channels_min = 1,
648 .channels_max = 2,
649 .rate_min = 8000,
650 .rate_max = 192000,
651 },
652 .name = "SLIMBUS_1_RX",
653 .ops = &q6slim_ops,
654 .id = SLIMBUS_1_RX,
655 .probe = msm_dai_q6_dai_probe,
656 .remove = msm_dai_q6_dai_remove,
657 }, {
658 .playback = {
659 .stream_name = "Slimbus2 Playback",
660 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
661 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
662 SNDRV_PCM_RATE_192000,
663 .formats = SNDRV_PCM_FMTBIT_S16_LE |
664 SNDRV_PCM_FMTBIT_S24_LE,
665 .channels_min = 1,
666 .channels_max = 8,
667 .rate_min = 8000,
668 .rate_max = 192000,
669 },
670 .name = "SLIMBUS_2_RX",
671 .ops = &q6slim_ops,
672 .id = SLIMBUS_2_RX,
673 .probe = msm_dai_q6_dai_probe,
674 .remove = msm_dai_q6_dai_remove,
675 }, {
676 .playback = {
677 .stream_name = "Slimbus3 Playback",
678 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
679 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
680 SNDRV_PCM_RATE_192000,
681 .formats = SNDRV_PCM_FMTBIT_S16_LE |
682 SNDRV_PCM_FMTBIT_S24_LE,
683 .channels_min = 1,
684 .channels_max = 2,
685 .rate_min = 8000,
686 .rate_max = 192000,
687 },
688 .name = "SLIMBUS_3_RX",
689 .ops = &q6slim_ops,
690 .id = SLIMBUS_3_RX,
691 .probe = msm_dai_q6_dai_probe,
692 .remove = msm_dai_q6_dai_remove,
693 }, {
694 .playback = {
695 .stream_name = "Slimbus4 Playback",
696 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
697 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
698 SNDRV_PCM_RATE_192000,
699 .formats = SNDRV_PCM_FMTBIT_S16_LE |
700 SNDRV_PCM_FMTBIT_S24_LE,
701 .channels_min = 1,
702 .channels_max = 2,
703 .rate_min = 8000,
704 .rate_max = 192000,
705 },
706 .name = "SLIMBUS_4_RX",
707 .ops = &q6slim_ops,
708 .id = SLIMBUS_4_RX,
709 .probe = msm_dai_q6_dai_probe,
710 .remove = msm_dai_q6_dai_remove,
711 }, {
712 .playback = {
713 .stream_name = "Slimbus5 Playback",
714 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
715 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
716 SNDRV_PCM_RATE_192000,
717 .formats = SNDRV_PCM_FMTBIT_S16_LE |
718 SNDRV_PCM_FMTBIT_S24_LE,
719 .channels_min = 1,
720 .channels_max = 2,
721 .rate_min = 8000,
722 .rate_max = 192000,
723 },
724 .name = "SLIMBUS_5_RX",
725 .ops = &q6slim_ops,
726 .id = SLIMBUS_5_RX,
727 .probe = msm_dai_q6_dai_probe,
728 .remove = msm_dai_q6_dai_remove,
729 }, {
730 .playback = {
731 .stream_name = "Slimbus6 Playback",
732 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
733 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
734 SNDRV_PCM_RATE_192000,
735 .formats = SNDRV_PCM_FMTBIT_S16_LE |
736 SNDRV_PCM_FMTBIT_S24_LE,
737 .channels_min = 1,
738 .channels_max = 2,
739 .rate_min = 8000,
740 .rate_max = 192000,
741 },
742 .ops = &q6slim_ops,
743 .name = "SLIMBUS_6_RX",
744 .id = SLIMBUS_6_RX,
745 .probe = msm_dai_q6_dai_probe,
746 .remove = msm_dai_q6_dai_remove,
747 }, {
748 .playback = {
749 .stream_name = "Primary MI2S Playback",
750 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
751 SNDRV_PCM_RATE_16000,
752 .formats = SNDRV_PCM_FMTBIT_S16_LE |
753 SNDRV_PCM_FMTBIT_S24_LE,
754 .rate_min = 8000,
755 .rate_max = 48000,
756 },
757 .id = PRIMARY_MI2S_RX,
758 .name = "PRI_MI2S_RX",
759 .ops = &q6i2s_ops,
760 .probe = msm_dai_q6_dai_probe,
761 .remove = msm_dai_q6_dai_remove,
762 }, {
763 .capture = {
764 .stream_name = "Primary MI2S Capture",
765 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
766 SNDRV_PCM_RATE_16000,
767 .formats = SNDRV_PCM_FMTBIT_S16_LE |
768 SNDRV_PCM_FMTBIT_S24_LE,
769 .rate_min = 8000,
770 .rate_max = 48000,
771 },
772 .id = PRIMARY_MI2S_TX,
773 .name = "PRI_MI2S_TX",
774 .ops = &q6i2s_ops,
775 .probe = msm_dai_q6_dai_probe,
776 .remove = msm_dai_q6_dai_remove,
777 }, {
778 .playback = {
779 .stream_name = "Secondary MI2S Playback",
780 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
781 SNDRV_PCM_RATE_16000,
782 .formats = SNDRV_PCM_FMTBIT_S16_LE,
783 .rate_min = 8000,
784 .rate_max = 48000,
785 },
786 .name = "SEC_MI2S_RX",
787 .id = SECONDARY_MI2S_RX,
788 .ops = &q6i2s_ops,
789 .probe = msm_dai_q6_dai_probe,
790 .remove = msm_dai_q6_dai_remove,
791 }, {
792 .capture = {
793 .stream_name = "Secondary MI2S Capture",
794 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
795 SNDRV_PCM_RATE_16000,
796 .formats = SNDRV_PCM_FMTBIT_S16_LE |
797 SNDRV_PCM_FMTBIT_S24_LE,
798 .rate_min = 8000,
799 .rate_max = 48000,
800 },
801 .id = SECONDARY_MI2S_TX,
802 .name = "SEC_MI2S_TX",
803 .ops = &q6i2s_ops,
804 .probe = msm_dai_q6_dai_probe,
805 .remove = msm_dai_q6_dai_remove,
806 }, {
807 .playback = {
808 .stream_name = "Tertiary MI2S Playback",
809 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
810 SNDRV_PCM_RATE_16000,
811 .formats = SNDRV_PCM_FMTBIT_S16_LE,
812 .rate_min = 8000,
813 .rate_max = 48000,
814 },
815 .name = "TERT_MI2S_RX",
816 .id = TERTIARY_MI2S_RX,
817 .ops = &q6i2s_ops,
818 .probe = msm_dai_q6_dai_probe,
819 .remove = msm_dai_q6_dai_remove,
820 }, {
821 .capture = {
822 .stream_name = "Tertiary MI2S Capture",
823 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
824 SNDRV_PCM_RATE_16000,
825 .formats = SNDRV_PCM_FMTBIT_S16_LE |
826 SNDRV_PCM_FMTBIT_S24_LE,
827 .rate_min = 8000,
828 .rate_max = 48000,
829 },
830 .id = TERTIARY_MI2S_TX,
831 .name = "TERT_MI2S_TX",
832 .ops = &q6i2s_ops,
833 .probe = msm_dai_q6_dai_probe,
834 .remove = msm_dai_q6_dai_remove,
835 }, {
836 .playback = {
837 .stream_name = "Quaternary MI2S Playback",
838 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
839 SNDRV_PCM_RATE_16000,
840 .formats = SNDRV_PCM_FMTBIT_S16_LE,
841 .rate_min = 8000,
842 .rate_max = 48000,
843 },
844 .name = "QUAT_MI2S_RX",
845 .id = QUATERNARY_MI2S_RX,
846 .ops = &q6i2s_ops,
847 .probe = msm_dai_q6_dai_probe,
848 .remove = msm_dai_q6_dai_remove,
849 }, {
850 .capture = {
851 .stream_name = "Quaternary MI2S Capture",
852 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
853 SNDRV_PCM_RATE_16000,
854 .formats = SNDRV_PCM_FMTBIT_S16_LE |
855 SNDRV_PCM_FMTBIT_S24_LE,
856 .rate_min = 8000,
857 .rate_max = 48000,
858 },
859 .id = QUATERNARY_MI2S_TX,
860 .name = "QUAT_MI2S_TX",
861 .ops = &q6i2s_ops,
862 .probe = msm_dai_q6_dai_probe,
863 .remove = msm_dai_q6_dai_remove,
864 },
865 Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0),
866 Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1),
867 Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2),
868 Q6AFE_TDM_PB_DAI("Primary", 3, PRIMARY_TDM_RX_3),
869 Q6AFE_TDM_PB_DAI("Primary", 4, PRIMARY_TDM_RX_4),
870 Q6AFE_TDM_PB_DAI("Primary", 5, PRIMARY_TDM_RX_5),
871 Q6AFE_TDM_PB_DAI("Primary", 6, PRIMARY_TDM_RX_6),
872 Q6AFE_TDM_PB_DAI("Primary", 7, PRIMARY_TDM_RX_7),
873 Q6AFE_TDM_CAP_DAI("Primary", 0, PRIMARY_TDM_TX_0),
874 Q6AFE_TDM_CAP_DAI("Primary", 1, PRIMARY_TDM_TX_1),
875 Q6AFE_TDM_CAP_DAI("Primary", 2, PRIMARY_TDM_TX_2),
876 Q6AFE_TDM_CAP_DAI("Primary", 3, PRIMARY_TDM_TX_3),
877 Q6AFE_TDM_CAP_DAI("Primary", 4, PRIMARY_TDM_TX_4),
878 Q6AFE_TDM_CAP_DAI("Primary", 5, PRIMARY_TDM_TX_5),
879 Q6AFE_TDM_CAP_DAI("Primary", 6, PRIMARY_TDM_TX_6),
880 Q6AFE_TDM_CAP_DAI("Primary", 7, PRIMARY_TDM_TX_7),
881 Q6AFE_TDM_PB_DAI("Secondary", 0, SECONDARY_TDM_RX_0),
882 Q6AFE_TDM_PB_DAI("Secondary", 1, SECONDARY_TDM_RX_1),
883 Q6AFE_TDM_PB_DAI("Secondary", 2, SECONDARY_TDM_RX_2),
884 Q6AFE_TDM_PB_DAI("Secondary", 3, SECONDARY_TDM_RX_3),
885 Q6AFE_TDM_PB_DAI("Secondary", 4, SECONDARY_TDM_RX_4),
886 Q6AFE_TDM_PB_DAI("Secondary", 5, SECONDARY_TDM_RX_5),
887 Q6AFE_TDM_PB_DAI("Secondary", 6, SECONDARY_TDM_RX_6),
888 Q6AFE_TDM_PB_DAI("Secondary", 7, SECONDARY_TDM_RX_7),
889 Q6AFE_TDM_CAP_DAI("Secondary", 0, SECONDARY_TDM_TX_0),
890 Q6AFE_TDM_CAP_DAI("Secondary", 1, SECONDARY_TDM_TX_1),
891 Q6AFE_TDM_CAP_DAI("Secondary", 2, SECONDARY_TDM_TX_2),
892 Q6AFE_TDM_CAP_DAI("Secondary", 3, SECONDARY_TDM_TX_3),
893 Q6AFE_TDM_CAP_DAI("Secondary", 4, SECONDARY_TDM_TX_4),
894 Q6AFE_TDM_CAP_DAI("Secondary", 5, SECONDARY_TDM_TX_5),
895 Q6AFE_TDM_CAP_DAI("Secondary", 6, SECONDARY_TDM_TX_6),
896 Q6AFE_TDM_CAP_DAI("Secondary", 7, SECONDARY_TDM_TX_7),
897 Q6AFE_TDM_PB_DAI("Tertiary", 0, TERTIARY_TDM_RX_0),
898 Q6AFE_TDM_PB_DAI("Tertiary", 1, TERTIARY_TDM_RX_1),
899 Q6AFE_TDM_PB_DAI("Tertiary", 2, TERTIARY_TDM_RX_2),
900 Q6AFE_TDM_PB_DAI("Tertiary", 3, TERTIARY_TDM_RX_3),
901 Q6AFE_TDM_PB_DAI("Tertiary", 4, TERTIARY_TDM_RX_4),
902 Q6AFE_TDM_PB_DAI("Tertiary", 5, TERTIARY_TDM_RX_5),
903 Q6AFE_TDM_PB_DAI("Tertiary", 6, TERTIARY_TDM_RX_6),
904 Q6AFE_TDM_PB_DAI("Tertiary", 7, TERTIARY_TDM_RX_7),
905 Q6AFE_TDM_CAP_DAI("Tertiary", 0, TERTIARY_TDM_TX_0),
906 Q6AFE_TDM_CAP_DAI("Tertiary", 1, TERTIARY_TDM_TX_1),
907 Q6AFE_TDM_CAP_DAI("Tertiary", 2, TERTIARY_TDM_TX_2),
908 Q6AFE_TDM_CAP_DAI("Tertiary", 3, TERTIARY_TDM_TX_3),
909 Q6AFE_TDM_CAP_DAI("Tertiary", 4, TERTIARY_TDM_TX_4),
910 Q6AFE_TDM_CAP_DAI("Tertiary", 5, TERTIARY_TDM_TX_5),
911 Q6AFE_TDM_CAP_DAI("Tertiary", 6, TERTIARY_TDM_TX_6),
912 Q6AFE_TDM_CAP_DAI("Tertiary", 7, TERTIARY_TDM_TX_7),
913 Q6AFE_TDM_PB_DAI("Quaternary", 0, QUATERNARY_TDM_RX_0),
914 Q6AFE_TDM_PB_DAI("Quaternary", 1, QUATERNARY_TDM_RX_1),
915 Q6AFE_TDM_PB_DAI("Quaternary", 2, QUATERNARY_TDM_RX_2),
916 Q6AFE_TDM_PB_DAI("Quaternary", 3, QUATERNARY_TDM_RX_3),
917 Q6AFE_TDM_PB_DAI("Quaternary", 4, QUATERNARY_TDM_RX_4),
918 Q6AFE_TDM_PB_DAI("Quaternary", 5, QUATERNARY_TDM_RX_5),
919 Q6AFE_TDM_PB_DAI("Quaternary", 6, QUATERNARY_TDM_RX_6),
920 Q6AFE_TDM_PB_DAI("Quaternary", 7, QUATERNARY_TDM_RX_7),
921 Q6AFE_TDM_CAP_DAI("Quaternary", 0, QUATERNARY_TDM_TX_0),
922 Q6AFE_TDM_CAP_DAI("Quaternary", 1, QUATERNARY_TDM_TX_1),
923 Q6AFE_TDM_CAP_DAI("Quaternary", 2, QUATERNARY_TDM_TX_2),
924 Q6AFE_TDM_CAP_DAI("Quaternary", 3, QUATERNARY_TDM_TX_3),
925 Q6AFE_TDM_CAP_DAI("Quaternary", 4, QUATERNARY_TDM_TX_4),
926 Q6AFE_TDM_CAP_DAI("Quaternary", 5, QUATERNARY_TDM_TX_5),
927 Q6AFE_TDM_CAP_DAI("Quaternary", 6, QUATERNARY_TDM_TX_6),
928 Q6AFE_TDM_CAP_DAI("Quaternary", 7, QUATERNARY_TDM_TX_7),
929 Q6AFE_TDM_PB_DAI("Quinary", 0, QUINARY_TDM_RX_0),
930 Q6AFE_TDM_PB_DAI("Quinary", 1, QUINARY_TDM_RX_1),
931 Q6AFE_TDM_PB_DAI("Quinary", 2, QUINARY_TDM_RX_2),
932 Q6AFE_TDM_PB_DAI("Quinary", 3, QUINARY_TDM_RX_3),
933 Q6AFE_TDM_PB_DAI("Quinary", 4, QUINARY_TDM_RX_4),
934 Q6AFE_TDM_PB_DAI("Quinary", 5, QUINARY_TDM_RX_5),
935 Q6AFE_TDM_PB_DAI("Quinary", 6, QUINARY_TDM_RX_6),
936 Q6AFE_TDM_PB_DAI("Quinary", 7, QUINARY_TDM_RX_7),
937 Q6AFE_TDM_CAP_DAI("Quinary", 0, QUINARY_TDM_TX_0),
938 Q6AFE_TDM_CAP_DAI("Quinary", 1, QUINARY_TDM_TX_1),
939 Q6AFE_TDM_CAP_DAI("Quinary", 2, QUINARY_TDM_TX_2),
940 Q6AFE_TDM_CAP_DAI("Quinary", 3, QUINARY_TDM_TX_3),
941 Q6AFE_TDM_CAP_DAI("Quinary", 4, QUINARY_TDM_TX_4),
942 Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5),
943 Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6),
944 Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7),
945};
946
947static int q6afe_of_xlate_dai_name(struct snd_soc_component *component,
948 struct of_phandle_args *args,
949 const char **dai_name)
950{
951 int id = args->args[0];
952 int ret = -EINVAL;
953 int i;
954
955 for (i = 0; i < ARRAY_SIZE(q6afe_dais); i++) {
956 if (q6afe_dais[i].id == id) {
957 *dai_name = q6afe_dais[i].name;
958 ret = 0;
959 break;
960 }
961 }
962
963 return ret;
964}
965
966static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
967 SND_SOC_DAPM_AIF_OUT("HDMI_RX", "HDMI Playback", 0, 0, 0, 0),
968 SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
969 SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_RX", "Slimbus1 Playback", 0, 0, 0, 0),
970 SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0),
971 SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_RX", "Slimbus3 Playback", 0, 0, 0, 0),
972 SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_RX", "Slimbus4 Playback", 0, 0, 0, 0),
973 SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0),
974 SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_RX", "Slimbus6 Playback", 0, 0, 0, 0),
975 SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback",
976 0, 0, 0, 0),
977 SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture",
978 0, 0, 0, 0),
979 SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX", "Tertiary MI2S Playback",
980 0, 0, 0, 0),
981 SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX", "Tertiary MI2S Capture",
982 0, 0, 0, 0),
983 SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback",
984 0, 0, 0, 0),
985 SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
986 0, 0, 0, 0),
987 SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_SD1",
988 "Secondary MI2S Playback SD1",
989 0, 0, 0, 0),
990 SND_SOC_DAPM_AIF_OUT("PRI_MI2S_RX", "Primary MI2S Playback",
991 0, 0, 0, 0),
992 SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture",
993 0, 0, 0, 0),
994
995 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_0", "Primary TDM0 Playback",
996 0, 0, 0, 0),
997 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_1", "Primary TDM1 Playback",
998 0, 0, 0, 0),
999 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_2", "Primary TDM2 Playback",
1000 0, 0, 0, 0),
1001 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_3", "Primary TDM3 Playback",
1002 0, 0, 0, 0),
1003 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_4", "Primary TDM4 Playback",
1004 0, 0, 0, 0),
1005 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_5", "Primary TDM5 Playback",
1006 0, 0, 0, 0),
1007 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_6", "Primary TDM6 Playback",
1008 0, 0, 0, 0),
1009 SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_RX_7", "Primary TDM7 Playback",
1010 0, 0, 0, 0),
1011 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_0", "Primary TDM0 Capture",
1012 0, 0, 0, 0),
1013 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_1", "Primary TDM1 Capture",
1014 0, 0, 0, 0),
1015 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_2", "Primary TDM2 Capture",
1016 0, 0, 0, 0),
1017 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_3", "Primary TDM3 Capture",
1018 0, 0, 0, 0),
1019 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_4", "Primary TDM4 Capture",
1020 0, 0, 0, 0),
1021 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_5", "Primary TDM5 Capture",
1022 0, 0, 0, 0),
1023 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_6", "Primary TDM6 Capture",
1024 0, 0, 0, 0),
1025 SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_TX_7", "Primary TDM7 Capture",
1026 0, 0, 0, 0),
1027
1028 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_0", "Secondary TDM0 Playback",
1029 0, 0, 0, 0),
1030 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_1", "Secondary TDM1 Playback",
1031 0, 0, 0, 0),
1032 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_2", "Secondary TDM2 Playback",
1033 0, 0, 0, 0),
1034 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_3", "Secondary TDM3 Playback",
1035 0, 0, 0, 0),
1036 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_4", "Secondary TDM4 Playback",
1037 0, 0, 0, 0),
1038 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_5", "Secondary TDM5 Playback",
1039 0, 0, 0, 0),
1040 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_6", "Secondary TDM6 Playback",
1041 0, 0, 0, 0),
1042 SND_SOC_DAPM_AIF_OUT("SEC_TDM_RX_7", "Secondary TDM7 Playback",
1043 0, 0, 0, 0),
1044 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_0", "Secondary TDM0 Capture",
1045 0, 0, 0, 0),
1046 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_1", "Secondary TDM1 Capture",
1047 0, 0, 0, 0),
1048 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_2", "Secondary TDM2 Capture",
1049 0, 0, 0, 0),
1050 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_3", "Secondary TDM3 Capture",
1051 0, 0, 0, 0),
1052 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_4", "Secondary TDM4 Capture",
1053 0, 0, 0, 0),
1054 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_5", "Secondary TDM5 Capture",
1055 0, 0, 0, 0),
1056 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_6", "Secondary TDM6 Capture",
1057 0, 0, 0, 0),
1058 SND_SOC_DAPM_AIF_IN("SEC_TDM_TX_7", "Secondary TDM7 Capture",
1059 0, 0, 0, 0),
1060
1061 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_0", "Tertiary TDM0 Playback",
1062 0, 0, 0, 0),
1063 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_1", "Tertiary TDM1 Playback",
1064 0, 0, 0, 0),
1065 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_2", "Tertiary TDM2 Playback",
1066 0, 0, 0, 0),
1067 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_3", "Tertiary TDM3 Playback",
1068 0, 0, 0, 0),
1069 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_4", "Tertiary TDM4 Playback",
1070 0, 0, 0, 0),
1071 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_5", "Tertiary TDM5 Playback",
1072 0, 0, 0, 0),
1073 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_6", "Tertiary TDM6 Playback",
1074 0, 0, 0, 0),
1075 SND_SOC_DAPM_AIF_OUT("TERT_TDM_RX_7", "Tertiary TDM7 Playback",
1076 0, 0, 0, 0),
1077 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_0", "Tertiary TDM0 Capture",
1078 0, 0, 0, 0),
1079 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_1", "Tertiary TDM1 Capture",
1080 0, 0, 0, 0),
1081 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_2", "Tertiary TDM2 Capture",
1082 0, 0, 0, 0),
1083 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_3", "Tertiary TDM3 Capture",
1084 0, 0, 0, 0),
1085 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_4", "Tertiary TDM4 Capture",
1086 0, 0, 0, 0),
1087 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_5", "Tertiary TDM5 Capture",
1088 0, 0, 0, 0),
1089 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_6", "Tertiary TDM6 Capture",
1090 0, 0, 0, 0),
1091 SND_SOC_DAPM_AIF_IN("TERT_TDM_TX_7", "Tertiary TDM7 Capture",
1092 0, 0, 0, 0),
1093
1094 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_0", "Quaternary TDM0 Playback",
1095 0, 0, 0, 0),
1096 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_1", "Quaternary TDM1 Playback",
1097 0, 0, 0, 0),
1098 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_2", "Quaternary TDM2 Playback",
1099 0, 0, 0, 0),
1100 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_3", "Quaternary TDM3 Playback",
1101 0, 0, 0, 0),
1102 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_4", "Quaternary TDM4 Playback",
1103 0, 0, 0, 0),
1104 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_5", "Quaternary TDM5 Playback",
1105 0, 0, 0, 0),
1106 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_6", "Quaternary TDM6 Playback",
1107 0, 0, 0, 0),
1108 SND_SOC_DAPM_AIF_OUT("QUAT_TDM_RX_7", "Quaternary TDM7 Playback",
1109 0, 0, 0, 0),
1110 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_0", "Quaternary TDM0 Capture",
1111 0, 0, 0, 0),
1112 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_1", "Quaternary TDM1 Capture",
1113 0, 0, 0, 0),
1114 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_2", "Quaternary TDM2 Capture",
1115 0, 0, 0, 0),
1116 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_3", "Quaternary TDM3 Capture",
1117 0, 0, 0, 0),
1118 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_4", "Quaternary TDM4 Capture",
1119 0, 0, 0, 0),
1120 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_5", "Quaternary TDM5 Capture",
1121 0, 0, 0, 0),
1122 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_6", "Quaternary TDM6 Capture",
1123 0, 0, 0, 0),
1124 SND_SOC_DAPM_AIF_IN("QUAT_TDM_TX_7", "Quaternary TDM7 Capture",
1125 0, 0, 0, 0),
1126
1127 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_0", "Quinary TDM0 Playback",
1128 0, 0, 0, 0),
1129 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_1", "Quinary TDM1 Playback",
1130 0, 0, 0, 0),
1131 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_2", "Quinary TDM2 Playback",
1132 0, 0, 0, 0),
1133 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_3", "Quinary TDM3 Playback",
1134 0, 0, 0, 0),
1135 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_4", "Quinary TDM4 Playback",
1136 0, 0, 0, 0),
1137 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_5", "Quinary TDM5 Playback",
1138 0, 0, 0, 0),
1139 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_6", "Quinary TDM6 Playback",
1140 0, 0, 0, 0),
1141 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_RX_7", "Quinary TDM7 Playback",
1142 0, 0, 0, 0),
1143 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_0", "Quinary TDM0 Capture",
1144 0, 0, 0, 0),
1145 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_1", "Quinary TDM1 Capture",
1146 0, 0, 0, 0),
1147 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_2", "Quinary TDM2 Capture",
1148 0, 0, 0, 0),
1149 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_3", "Quinary TDM3 Capture",
1150 0, 0, 0, 0),
1151 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_4", "Quinary TDM4 Capture",
1152 0, 0, 0, 0),
1153 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_5", "Quinary TDM5 Capture",
1154 0, 0, 0, 0),
1155 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_6", "Quinary TDM6 Capture",
1156 0, 0, 0, 0),
1157 SND_SOC_DAPM_AIF_IN("QUIN_TDM_TX_7", "Quinary TDM7 Capture",
1158 0, 0, 0, 0),
1159};
1160
1161static const struct snd_soc_component_driver q6afe_dai_component = {
1162 .name = "q6afe-dai-component",
1163 .dapm_widgets = q6afe_dai_widgets,
1164 .num_dapm_widgets = ARRAY_SIZE(q6afe_dai_widgets),
1165 .dapm_routes = q6afe_dapm_routes,
1166 .num_dapm_routes = ARRAY_SIZE(q6afe_dapm_routes),
1167 .of_xlate_dai_name = q6afe_of_xlate_dai_name,
1168
1169};
1170
1171static void of_q6afe_parse_dai_data(struct device *dev,
1172 struct q6afe_dai_data *data)
1173{
1174 struct device_node *node;
1175 int ret;
1176
1177 for_each_child_of_node(dev->of_node, node) {
1178 unsigned int lines[Q6AFE_MAX_MI2S_LINES];
1179 struct q6afe_dai_priv_data *priv;
1180 int id, i, num_lines;
1181
1182 ret = of_property_read_u32(node, "reg", &id);
1183 if (ret || id > AFE_PORT_MAX) {
1184 dev_err(dev, "valid dai id not found:%d\n", ret);
1185 continue;
1186 }
1187
1188 switch (id) {
1189 /* MI2S specific properties */
1190 case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
1191 priv = &data->priv[id];
1192 ret = of_property_read_variable_u32_array(node,
1193 "qcom,sd-lines",
1194 lines, 0,
1195 Q6AFE_MAX_MI2S_LINES);
1196 if (ret < 0)
1197 num_lines = 0;
1198 else
1199 num_lines = ret;
1200
1201 priv->sd_line_mask = 0;
1202
1203 for (i = 0; i < num_lines; i++)
1204 priv->sd_line_mask |= BIT(lines[i]);
1205
1206 break;
1207 case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
1208 priv = &data->priv[id];
1209 ret = of_property_read_u32(node, "qcom,tdm-sync-mode",
1210 &priv->sync_mode);
1211 if (ret) {
1212 dev_err(dev, "No Sync mode from DT\n");
1213 break;
1214 }
1215 ret = of_property_read_u32(node, "qcom,tdm-sync-src",
1216 &priv->sync_src);
1217 if (ret) {
1218 dev_err(dev, "No Sync Src from DT\n");
1219 break;
1220 }
1221 ret = of_property_read_u32(node, "qcom,tdm-data-out",
1222 &priv->data_out_enable);
1223 if (ret) {
1224 dev_err(dev, "No Data out enable from DT\n");
1225 break;
1226 }
1227 ret = of_property_read_u32(node, "qcom,tdm-invert-sync",
1228 &priv->invert_sync);
1229 if (ret) {
1230 dev_err(dev, "No Invert sync from DT\n");
1231 break;
1232 }
1233 ret = of_property_read_u32(node, "qcom,tdm-data-delay",
1234 &priv->data_delay);
1235 if (ret) {
1236 dev_err(dev, "No Data Delay from DT\n");
1237 break;
1238 }
1239 ret = of_property_read_u32(node, "qcom,tdm-data-align",
1240 &priv->data_align);
1241 if (ret) {
1242 dev_err(dev, "No Data align from DT\n");
1243 break;
1244 }
1245 break;
1246 default:
1247 break;
1248 }
1249 }
1250}
1251
1252static int q6afe_dai_bind(struct device *dev, struct device *master, void *data)
1253{
1254 struct q6afe_dai_data *dai_data;
1255
1256 dai_data = kzalloc(sizeof(*dai_data), GFP_KERNEL);
1257 if (!dai_data)
1258 return -ENOMEM;
1259
1260 dev_set_drvdata(dev, dai_data);
1261
1262 of_q6afe_parse_dai_data(dev, dai_data);
1263
1264 return snd_soc_register_component(dev, &q6afe_dai_component,
1265 q6afe_dais, ARRAY_SIZE(q6afe_dais));
1266}
1267
1268static void q6afe_dai_unbind(struct device *dev, struct device *master,
1269 void *data)
1270{
1271 struct q6afe_dai_data *dai_data = dev_get_drvdata(dev);
1272
1273 snd_soc_unregister_component(dev);
1274 kfree(dai_data);
1275}
1276
1277static const struct component_ops q6afe_dai_comp_ops = {
1278 .bind = q6afe_dai_bind,
1279 .unbind = q6afe_dai_unbind,
1280};
1281
1282static int q6afe_dai_dev_probe(struct platform_device *pdev)
1283{
1284 return component_add(&pdev->dev, &q6afe_dai_comp_ops);
1285}
1286
1287static int q6afe_dai_dev_remove(struct platform_device *pdev)
1288{
1289 component_del(&pdev->dev, &q6afe_dai_comp_ops);
1290 return 0;
1291}
1292
1293static struct platform_driver q6afe_dai_platform_driver = {
1294 .driver = {
1295 .name = "q6afe-dai",
1296 },
1297 .probe = q6afe_dai_dev_probe,
1298 .remove = q6afe_dai_dev_remove,
1299};
1300module_platform_driver(q6afe_dai_platform_driver);
1301
1302MODULE_DESCRIPTION("Q6 Audio Fronend dai driver");
1303MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
new file mode 100644
index 000000000000..01f43218984b
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -0,0 +1,1495 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/slab.h>
6#include <linux/kernel.h>
7#include <linux/uaccess.h>
8#include <linux/wait.h>
9#include <linux/jiffies.h>
10#include <linux/sched.h>
11#include <linux/module.h>
12#include <linux/kref.h>
13#include <linux/of.h>
14#include <linux/of_platform.h>
15#include <linux/spinlock.h>
16#include <linux/delay.h>
17#include <linux/soc/qcom/apr.h>
18#include <sound/soc.h>
19#include <sound/soc-dai.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include "q6dsp-errno.h"
23#include "q6core.h"
24#include "q6afe.h"
25
26/* AFE CMDs */
27#define AFE_PORT_CMD_DEVICE_START 0x000100E5
28#define AFE_PORT_CMD_DEVICE_STOP 0x000100E6
29#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF
30#define AFE_SVC_CMD_SET_PARAM 0x000100f3
31#define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106
32#define AFE_PARAM_ID_HDMI_CONFIG 0x00010210
33#define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C
34#define AFE_MODULE_TDM 0x0001028A
35
36#define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG 0x00010235
37
38#define AFE_PARAM_ID_LPAIF_CLK_CONFIG 0x00010238
39#define AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG 0x00010239
40
41#define AFE_PARAM_ID_SLIMBUS_CONFIG 0x00010212
42#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
43#define AFE_PARAM_ID_TDM_CONFIG 0x0001029D
44#define AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG 0x00010297
45
46/* I2S config specific */
47#define AFE_API_VERSION_I2S_CONFIG 0x1
48#define AFE_PORT_I2S_SD0 0x1
49#define AFE_PORT_I2S_SD1 0x2
50#define AFE_PORT_I2S_SD2 0x3
51#define AFE_PORT_I2S_SD3 0x4
52#define AFE_PORT_I2S_SD0_MASK BIT(0x1)
53#define AFE_PORT_I2S_SD1_MASK BIT(0x2)
54#define AFE_PORT_I2S_SD2_MASK BIT(0x3)
55#define AFE_PORT_I2S_SD3_MASK BIT(0x4)
56#define AFE_PORT_I2S_SD0_1_MASK GENMASK(2, 1)
57#define AFE_PORT_I2S_SD2_3_MASK GENMASK(4, 3)
58#define AFE_PORT_I2S_SD0_1_2_MASK GENMASK(3, 1)
59#define AFE_PORT_I2S_SD0_1_2_3_MASK GENMASK(4, 1)
60#define AFE_PORT_I2S_QUAD01 0x5
61#define AFE_PORT_I2S_QUAD23 0x6
62#define AFE_PORT_I2S_6CHS 0x7
63#define AFE_PORT_I2S_8CHS 0x8
64#define AFE_PORT_I2S_MONO 0x0
65#define AFE_PORT_I2S_STEREO 0x1
66#define AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL 0x0
67#define AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL 0x1
68#define AFE_LINEAR_PCM_DATA 0x0
69
70
71/* Port IDs */
72#define AFE_API_VERSION_HDMI_CONFIG 0x1
73#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E
74
75#define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
76/* Clock set API version */
77#define AFE_API_VERSION_CLOCK_SET 1
78#define Q6AFE_LPASS_CLK_CONFIG_API_VERSION 0x1
79#define AFE_MODULE_CLOCK_SET 0x0001028F
80#define AFE_PARAM_ID_CLOCK_SET 0x00010290
81
82/* SLIMbus Rx port on channel 0. */
83#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX 0x4000
84/* SLIMbus Tx port on channel 0. */
85#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX 0x4001
86/* SLIMbus Rx port on channel 1. */
87#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX 0x4002
88/* SLIMbus Tx port on channel 1. */
89#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_TX 0x4003
90/* SLIMbus Rx port on channel 2. */
91#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX 0x4004
92/* SLIMbus Tx port on channel 2. */
93#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_TX 0x4005
94/* SLIMbus Rx port on channel 3. */
95#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX 0x4006
96/* SLIMbus Tx port on channel 3. */
97#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_TX 0x4007
98/* SLIMbus Rx port on channel 4. */
99#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX 0x4008
100/* SLIMbus Tx port on channel 4. */
101#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_TX 0x4009
102/* SLIMbus Rx port on channel 5. */
103#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX 0x400a
104/* SLIMbus Tx port on channel 5. */
105#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_TX 0x400b
106/* SLIMbus Rx port on channel 6. */
107#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX 0x400c
108/* SLIMbus Tx port on channel 6. */
109#define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_TX 0x400d
110#define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000
111#define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001
112#define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002
113#define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003
114#define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004
115#define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005
116#define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006
117#define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007
118
119/* Start of the range of port IDs for TDM devices. */
120#define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000
121
122/* End of the range of port IDs for TDM devices. */
123#define AFE_PORT_ID_TDM_PORT_RANGE_END \
124 (AFE_PORT_ID_TDM_PORT_RANGE_START+0x50-1)
125
126/* Size of the range of port IDs for TDM ports. */
127#define AFE_PORT_ID_TDM_PORT_RANGE_SIZE \
128 (AFE_PORT_ID_TDM_PORT_RANGE_END - \
129 AFE_PORT_ID_TDM_PORT_RANGE_START+1)
130
131#define AFE_PORT_ID_PRIMARY_TDM_RX \
132 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x00)
133#define AFE_PORT_ID_PRIMARY_TDM_RX_1 \
134 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x02)
135#define AFE_PORT_ID_PRIMARY_TDM_RX_2 \
136 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x04)
137#define AFE_PORT_ID_PRIMARY_TDM_RX_3 \
138 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x06)
139#define AFE_PORT_ID_PRIMARY_TDM_RX_4 \
140 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x08)
141#define AFE_PORT_ID_PRIMARY_TDM_RX_5 \
142 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0A)
143#define AFE_PORT_ID_PRIMARY_TDM_RX_6 \
144 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0C)
145#define AFE_PORT_ID_PRIMARY_TDM_RX_7 \
146 (AFE_PORT_ID_PRIMARY_TDM_RX + 0x0E)
147
148#define AFE_PORT_ID_PRIMARY_TDM_TX \
149 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x01)
150#define AFE_PORT_ID_PRIMARY_TDM_TX_1 \
151 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x02)
152#define AFE_PORT_ID_PRIMARY_TDM_TX_2 \
153 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x04)
154#define AFE_PORT_ID_PRIMARY_TDM_TX_3 \
155 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x06)
156#define AFE_PORT_ID_PRIMARY_TDM_TX_4 \
157 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x08)
158#define AFE_PORT_ID_PRIMARY_TDM_TX_5 \
159 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0A)
160#define AFE_PORT_ID_PRIMARY_TDM_TX_6 \
161 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0C)
162#define AFE_PORT_ID_PRIMARY_TDM_TX_7 \
163 (AFE_PORT_ID_PRIMARY_TDM_TX + 0x0E)
164
165#define AFE_PORT_ID_SECONDARY_TDM_RX \
166 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x10)
167#define AFE_PORT_ID_SECONDARY_TDM_RX_1 \
168 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x02)
169#define AFE_PORT_ID_SECONDARY_TDM_RX_2 \
170 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x04)
171#define AFE_PORT_ID_SECONDARY_TDM_RX_3 \
172 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x06)
173#define AFE_PORT_ID_SECONDARY_TDM_RX_4 \
174 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x08)
175#define AFE_PORT_ID_SECONDARY_TDM_RX_5 \
176 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0A)
177#define AFE_PORT_ID_SECONDARY_TDM_RX_6 \
178 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0C)
179#define AFE_PORT_ID_SECONDARY_TDM_RX_7 \
180 (AFE_PORT_ID_SECONDARY_TDM_RX + 0x0E)
181
182#define AFE_PORT_ID_SECONDARY_TDM_TX \
183 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x11)
184#define AFE_PORT_ID_SECONDARY_TDM_TX_1 \
185 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x02)
186#define AFE_PORT_ID_SECONDARY_TDM_TX_2 \
187 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x04)
188#define AFE_PORT_ID_SECONDARY_TDM_TX_3 \
189 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x06)
190#define AFE_PORT_ID_SECONDARY_TDM_TX_4 \
191 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x08)
192#define AFE_PORT_ID_SECONDARY_TDM_TX_5 \
193 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0A)
194#define AFE_PORT_ID_SECONDARY_TDM_TX_6 \
195 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0C)
196#define AFE_PORT_ID_SECONDARY_TDM_TX_7 \
197 (AFE_PORT_ID_SECONDARY_TDM_TX + 0x0E)
198
199#define AFE_PORT_ID_TERTIARY_TDM_RX \
200 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x20)
201#define AFE_PORT_ID_TERTIARY_TDM_RX_1 \
202 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x02)
203#define AFE_PORT_ID_TERTIARY_TDM_RX_2 \
204 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x04)
205#define AFE_PORT_ID_TERTIARY_TDM_RX_3 \
206 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x06)
207#define AFE_PORT_ID_TERTIARY_TDM_RX_4 \
208 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x08)
209#define AFE_PORT_ID_TERTIARY_TDM_RX_5 \
210 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0A)
211#define AFE_PORT_ID_TERTIARY_TDM_RX_6 \
212 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0C)
213#define AFE_PORT_ID_TERTIARY_TDM_RX_7 \
214 (AFE_PORT_ID_TERTIARY_TDM_RX + 0x0E)
215
216#define AFE_PORT_ID_TERTIARY_TDM_TX \
217 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x21)
218#define AFE_PORT_ID_TERTIARY_TDM_TX_1 \
219 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x02)
220#define AFE_PORT_ID_TERTIARY_TDM_TX_2 \
221 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x04)
222#define AFE_PORT_ID_TERTIARY_TDM_TX_3 \
223 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x06)
224#define AFE_PORT_ID_TERTIARY_TDM_TX_4 \
225 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x08)
226#define AFE_PORT_ID_TERTIARY_TDM_TX_5 \
227 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0A)
228#define AFE_PORT_ID_TERTIARY_TDM_TX_6 \
229 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0C)
230#define AFE_PORT_ID_TERTIARY_TDM_TX_7 \
231 (AFE_PORT_ID_TERTIARY_TDM_TX + 0x0E)
232
233#define AFE_PORT_ID_QUATERNARY_TDM_RX \
234 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x30)
235#define AFE_PORT_ID_QUATERNARY_TDM_RX_1 \
236 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x02)
237#define AFE_PORT_ID_QUATERNARY_TDM_RX_2 \
238 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x04)
239#define AFE_PORT_ID_QUATERNARY_TDM_RX_3 \
240 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x06)
241#define AFE_PORT_ID_QUATERNARY_TDM_RX_4 \
242 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x08)
243#define AFE_PORT_ID_QUATERNARY_TDM_RX_5 \
244 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0A)
245#define AFE_PORT_ID_QUATERNARY_TDM_RX_6 \
246 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0C)
247#define AFE_PORT_ID_QUATERNARY_TDM_RX_7 \
248 (AFE_PORT_ID_QUATERNARY_TDM_RX + 0x0E)
249
250#define AFE_PORT_ID_QUATERNARY_TDM_TX \
251 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x31)
252#define AFE_PORT_ID_QUATERNARY_TDM_TX_1 \
253 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x02)
254#define AFE_PORT_ID_QUATERNARY_TDM_TX_2 \
255 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x04)
256#define AFE_PORT_ID_QUATERNARY_TDM_TX_3 \
257 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x06)
258#define AFE_PORT_ID_QUATERNARY_TDM_TX_4 \
259 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x08)
260#define AFE_PORT_ID_QUATERNARY_TDM_TX_5 \
261 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0A)
262#define AFE_PORT_ID_QUATERNARY_TDM_TX_6 \
263 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0C)
264#define AFE_PORT_ID_QUATERNARY_TDM_TX_7 \
265 (AFE_PORT_ID_QUATERNARY_TDM_TX + 0x0E)
266
267#define AFE_PORT_ID_QUINARY_TDM_RX \
268 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x40)
269#define AFE_PORT_ID_QUINARY_TDM_RX_1 \
270 (AFE_PORT_ID_QUINARY_TDM_RX + 0x02)
271#define AFE_PORT_ID_QUINARY_TDM_RX_2 \
272 (AFE_PORT_ID_QUINARY_TDM_RX + 0x04)
273#define AFE_PORT_ID_QUINARY_TDM_RX_3 \
274 (AFE_PORT_ID_QUINARY_TDM_RX + 0x06)
275#define AFE_PORT_ID_QUINARY_TDM_RX_4 \
276 (AFE_PORT_ID_QUINARY_TDM_RX + 0x08)
277#define AFE_PORT_ID_QUINARY_TDM_RX_5 \
278 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0A)
279#define AFE_PORT_ID_QUINARY_TDM_RX_6 \
280 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0C)
281#define AFE_PORT_ID_QUINARY_TDM_RX_7 \
282 (AFE_PORT_ID_QUINARY_TDM_RX + 0x0E)
283
284#define AFE_PORT_ID_QUINARY_TDM_TX \
285 (AFE_PORT_ID_TDM_PORT_RANGE_START + 0x41)
286#define AFE_PORT_ID_QUINARY_TDM_TX_1 \
287 (AFE_PORT_ID_QUINARY_TDM_TX + 0x02)
288#define AFE_PORT_ID_QUINARY_TDM_TX_2 \
289 (AFE_PORT_ID_QUINARY_TDM_TX + 0x04)
290#define AFE_PORT_ID_QUINARY_TDM_TX_3 \
291 (AFE_PORT_ID_QUINARY_TDM_TX + 0x06)
292#define AFE_PORT_ID_QUINARY_TDM_TX_4 \
293 (AFE_PORT_ID_QUINARY_TDM_TX + 0x08)
294#define AFE_PORT_ID_QUINARY_TDM_TX_5 \
295 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0A)
296#define AFE_PORT_ID_QUINARY_TDM_TX_6 \
297 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0C)
298#define AFE_PORT_ID_QUINARY_TDM_TX_7 \
299 (AFE_PORT_ID_QUINARY_TDM_TX + 0x0E)
300
301#define Q6AFE_LPASS_MODE_CLK1_VALID 1
302#define Q6AFE_LPASS_MODE_CLK2_VALID 2
303#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
304#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
305#define AFE_API_VERSION_TDM_CONFIG 1
306#define AFE_API_VERSION_SLOT_MAPPING_CONFIG 1
307
308#define TIMEOUT_MS 1000
309#define AFE_CMD_RESP_AVAIL 0
310#define AFE_CMD_RESP_NONE 1
311
312struct q6afe {
313 struct apr_device *apr;
314 struct device *dev;
315 struct q6core_svc_api_info ainfo;
316 struct mutex lock;
317 struct list_head port_list;
318 spinlock_t port_list_lock;
319 struct platform_device *pdev_dais;
320};
321
322struct afe_port_cmd_device_start {
323 u16 port_id;
324 u16 reserved;
325} __packed;
326
327struct afe_port_cmd_device_stop {
328 u16 port_id;
329 u16 reserved;
330/* Reserved for 32-bit alignment. This field must be set to 0.*/
331} __packed;
332
333struct afe_port_param_data_v2 {
334 u32 module_id;
335 u32 param_id;
336 u16 param_size;
337 u16 reserved;
338} __packed;
339
340struct afe_svc_cmd_set_param {
341 uint32_t payload_size;
342 uint32_t payload_address_lsw;
343 uint32_t payload_address_msw;
344 uint32_t mem_map_handle;
345} __packed;
346
347struct afe_port_cmd_set_param_v2 {
348 u16 port_id;
349 u16 payload_size;
350 u32 payload_address_lsw;
351 u32 payload_address_msw;
352 u32 mem_map_handle;
353} __packed;
354
355struct afe_param_id_hdmi_multi_chan_audio_cfg {
356 u32 hdmi_cfg_minor_version;
357 u16 datatype;
358 u16 channel_allocation;
359 u32 sample_rate;
360 u16 bit_width;
361 u16 reserved;
362} __packed;
363
364struct afe_param_id_slimbus_cfg {
365 u32 sb_cfg_minor_version;
366/* Minor version used for tracking the version of the SLIMBUS
367 * configuration interface.
368 * Supported values: #AFE_API_VERSION_SLIMBUS_CONFIG
369 */
370
371 u16 slimbus_dev_id;
372/* SLIMbus hardware device ID, which is required to handle
373 * multiple SLIMbus hardware blocks.
374 * Supported values: - #AFE_SLIMBUS_DEVICE_1 - #AFE_SLIMBUS_DEVICE_2
375 */
376 u16 bit_width;
377/* Bit width of the sample.
378 * Supported values: 16, 24
379 */
380 u16 data_format;
381/* Data format supported by the SLIMbus hardware. The default is
382 * 0 (#AFE_SB_DATA_FORMAT_NOT_INDICATED), which indicates the
383 * hardware does not perform any format conversions before the data
384 * transfer.
385 */
386 u16 num_channels;
387/* Number of channels.
388 * Supported values: 1 to #AFE_PORT_MAX_AUDIO_CHAN_CNT
389 */
390 u8 shared_ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
391/* Mapping of shared channel IDs (128 to 255) to which the
392 * master port is to be connected.
393 * Shared_channel_mapping[i] represents the shared channel assigned
394 * for audio channel i in multichannel audio data.
395 */
396 u32 sample_rate;
397/* Sampling rate of the port.
398 * Supported values:
399 * - #AFE_PORT_SAMPLE_RATE_8K
400 * - #AFE_PORT_SAMPLE_RATE_16K
401 * - #AFE_PORT_SAMPLE_RATE_48K
402 * - #AFE_PORT_SAMPLE_RATE_96K
403 * - #AFE_PORT_SAMPLE_RATE_192K
404 */
405} __packed;
406
407struct afe_clk_cfg {
408 u32 i2s_cfg_minor_version;
409 u32 clk_val1;
410 u32 clk_val2;
411 u16 clk_src;
412 u16 clk_root;
413 u16 clk_set_mode;
414 u16 reserved;
415} __packed;
416
417struct afe_digital_clk_cfg {
418 u32 i2s_cfg_minor_version;
419 u32 clk_val;
420 u16 clk_root;
421 u16 reserved;
422} __packed;
423
424struct afe_param_id_i2s_cfg {
425 u32 i2s_cfg_minor_version;
426 u16 bit_width;
427 u16 channel_mode;
428 u16 mono_stereo;
429 u16 ws_src;
430 u32 sample_rate;
431 u16 data_format;
432 u16 reserved;
433} __packed;
434
435struct afe_param_id_tdm_cfg {
436 u32 tdm_cfg_minor_version;
437 u32 num_channels;
438 u32 sample_rate;
439 u32 bit_width;
440 u16 data_format;
441 u16 sync_mode;
442 u16 sync_src;
443 u16 nslots_per_frame;
444 u16 ctrl_data_out_enable;
445 u16 ctrl_invert_sync_pulse;
446 u16 ctrl_sync_data_delay;
447 u16 slot_width;
448 u32 slot_mask;
449} __packed;
450
451union afe_port_config {
452 struct afe_param_id_hdmi_multi_chan_audio_cfg hdmi_multi_ch;
453 struct afe_param_id_slimbus_cfg slim_cfg;
454 struct afe_param_id_i2s_cfg i2s_cfg;
455 struct afe_param_id_tdm_cfg tdm_cfg;
456} __packed;
457
458
459struct afe_clk_set {
460 uint32_t clk_set_minor_version;
461 uint32_t clk_id;
462 uint32_t clk_freq_in_hz;
463 uint16_t clk_attri;
464 uint16_t clk_root;
465 uint32_t enable;
466};
467
468struct afe_param_id_slot_mapping_cfg {
469 u32 minor_version;
470 u16 num_channels;
471 u16 bitwidth;
472 u32 data_align_type;
473 u16 ch_mapping[AFE_PORT_MAX_AUDIO_CHAN_CNT];
474} __packed;
475
476struct q6afe_port {
477 wait_queue_head_t wait;
478 union afe_port_config port_cfg;
479 struct afe_param_id_slot_mapping_cfg *scfg;
480 struct aprv2_ibasic_rsp_result_t result;
481 int token;
482 int id;
483 int cfg_type;
484 struct q6afe *afe;
485 struct kref refcount;
486 struct list_head node;
487};
488
489struct afe_port_map {
490 int port_id;
491 int token;
492 int is_rx;
493 int is_dig_pcm;
494};
495
496/*
497 * Mapping between Virtual Port IDs to DSP AFE Port ID
498 * On B Family SoCs DSP Port IDs are consistent across multiple SoCs
499 * on A Family SoCs DSP port IDs are same as virtual Port IDs.
500 */
501
502static struct afe_port_map port_maps[AFE_PORT_MAX] = {
503 [HDMI_RX] = { AFE_PORT_ID_MULTICHAN_HDMI_RX, HDMI_RX, 1, 1},
504 [SLIMBUS_0_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX,
505 SLIMBUS_0_RX, 1, 1},
506 [SLIMBUS_1_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX,
507 SLIMBUS_1_RX, 1, 1},
508 [SLIMBUS_2_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX,
509 SLIMBUS_2_RX, 1, 1},
510 [SLIMBUS_3_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX,
511 SLIMBUS_3_RX, 1, 1},
512 [SLIMBUS_4_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX,
513 SLIMBUS_4_RX, 1, 1},
514 [SLIMBUS_5_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX,
515 SLIMBUS_5_RX, 1, 1},
516 [SLIMBUS_6_RX] = { AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX,
517 SLIMBUS_6_RX, 1, 1},
518 [PRIMARY_MI2S_RX] = { AFE_PORT_ID_PRIMARY_MI2S_RX,
519 PRIMARY_MI2S_RX, 1, 1},
520 [PRIMARY_MI2S_TX] = { AFE_PORT_ID_PRIMARY_MI2S_TX,
521 PRIMARY_MI2S_RX, 0, 1},
522 [SECONDARY_MI2S_RX] = { AFE_PORT_ID_SECONDARY_MI2S_RX,
523 SECONDARY_MI2S_RX, 1, 1},
524 [SECONDARY_MI2S_TX] = { AFE_PORT_ID_SECONDARY_MI2S_TX,
525 SECONDARY_MI2S_TX, 0, 1},
526 [TERTIARY_MI2S_RX] = { AFE_PORT_ID_TERTIARY_MI2S_RX,
527 TERTIARY_MI2S_RX, 1, 1},
528 [TERTIARY_MI2S_TX] = { AFE_PORT_ID_TERTIARY_MI2S_TX,
529 TERTIARY_MI2S_TX, 0, 1},
530 [QUATERNARY_MI2S_RX] = { AFE_PORT_ID_QUATERNARY_MI2S_RX,
531 QUATERNARY_MI2S_RX, 1, 1},
532 [QUATERNARY_MI2S_TX] = { AFE_PORT_ID_QUATERNARY_MI2S_TX,
533 QUATERNARY_MI2S_TX, 0, 1},
534 [PRIMARY_TDM_RX_0] = { AFE_PORT_ID_PRIMARY_TDM_RX,
535 PRIMARY_TDM_RX_0, 1, 1},
536 [PRIMARY_TDM_TX_0] = { AFE_PORT_ID_PRIMARY_TDM_TX,
537 PRIMARY_TDM_TX_0, 0, 1},
538 [PRIMARY_TDM_RX_1] = { AFE_PORT_ID_PRIMARY_TDM_RX_1,
539 PRIMARY_TDM_RX_1, 1, 1},
540 [PRIMARY_TDM_TX_1] = { AFE_PORT_ID_PRIMARY_TDM_TX_1,
541 PRIMARY_TDM_TX_1, 0, 1},
542 [PRIMARY_TDM_RX_2] = { AFE_PORT_ID_PRIMARY_TDM_RX_2,
543 PRIMARY_TDM_RX_2, 1, 1},
544 [PRIMARY_TDM_TX_2] = { AFE_PORT_ID_PRIMARY_TDM_TX_2,
545 PRIMARY_TDM_TX_2, 0, 1},
546 [PRIMARY_TDM_RX_3] = { AFE_PORT_ID_PRIMARY_TDM_RX_3,
547 PRIMARY_TDM_RX_3, 1, 1},
548 [PRIMARY_TDM_TX_3] = { AFE_PORT_ID_PRIMARY_TDM_TX_3,
549 PRIMARY_TDM_TX_3, 0, 1},
550 [PRIMARY_TDM_RX_4] = { AFE_PORT_ID_PRIMARY_TDM_RX_4,
551 PRIMARY_TDM_RX_4, 1, 1},
552 [PRIMARY_TDM_TX_4] = { AFE_PORT_ID_PRIMARY_TDM_TX_4,
553 PRIMARY_TDM_TX_4, 0, 1},
554 [PRIMARY_TDM_RX_5] = { AFE_PORT_ID_PRIMARY_TDM_RX_5,
555 PRIMARY_TDM_RX_5, 1, 1},
556 [PRIMARY_TDM_TX_5] = { AFE_PORT_ID_PRIMARY_TDM_TX_5,
557 PRIMARY_TDM_TX_5, 0, 1},
558 [PRIMARY_TDM_RX_6] = { AFE_PORT_ID_PRIMARY_TDM_RX_6,
559 PRIMARY_TDM_RX_6, 1, 1},
560 [PRIMARY_TDM_TX_6] = { AFE_PORT_ID_PRIMARY_TDM_TX_6,
561 PRIMARY_TDM_TX_6, 0, 1},
562 [PRIMARY_TDM_RX_7] = { AFE_PORT_ID_PRIMARY_TDM_RX_7,
563 PRIMARY_TDM_RX_7, 1, 1},
564 [PRIMARY_TDM_TX_7] = { AFE_PORT_ID_PRIMARY_TDM_TX_7,
565 PRIMARY_TDM_TX_7, 0, 1},
566 [SECONDARY_TDM_RX_0] = { AFE_PORT_ID_SECONDARY_TDM_RX,
567 SECONDARY_TDM_RX_0, 1, 1},
568 [SECONDARY_TDM_TX_0] = { AFE_PORT_ID_SECONDARY_TDM_TX,
569 SECONDARY_TDM_TX_0, 0, 1},
570 [SECONDARY_TDM_RX_1] = { AFE_PORT_ID_SECONDARY_TDM_RX_1,
571 SECONDARY_TDM_RX_1, 1, 1},
572 [SECONDARY_TDM_TX_1] = { AFE_PORT_ID_SECONDARY_TDM_TX_1,
573 SECONDARY_TDM_TX_1, 0, 1},
574 [SECONDARY_TDM_RX_2] = { AFE_PORT_ID_SECONDARY_TDM_RX_2,
575 SECONDARY_TDM_RX_2, 1, 1},
576 [SECONDARY_TDM_TX_2] = { AFE_PORT_ID_SECONDARY_TDM_TX_2,
577 SECONDARY_TDM_TX_2, 0, 1},
578 [SECONDARY_TDM_RX_3] = { AFE_PORT_ID_SECONDARY_TDM_RX_3,
579 SECONDARY_TDM_RX_3, 1, 1},
580 [SECONDARY_TDM_TX_3] = { AFE_PORT_ID_SECONDARY_TDM_TX_3,
581 SECONDARY_TDM_TX_3, 0, 1},
582 [SECONDARY_TDM_RX_4] = { AFE_PORT_ID_SECONDARY_TDM_RX_4,
583 SECONDARY_TDM_RX_4, 1, 1},
584 [SECONDARY_TDM_TX_4] = { AFE_PORT_ID_SECONDARY_TDM_TX_4,
585 SECONDARY_TDM_TX_4, 0, 1},
586 [SECONDARY_TDM_RX_5] = { AFE_PORT_ID_SECONDARY_TDM_RX_5,
587 SECONDARY_TDM_RX_5, 1, 1},
588 [SECONDARY_TDM_TX_5] = { AFE_PORT_ID_SECONDARY_TDM_TX_5,
589 SECONDARY_TDM_TX_5, 0, 1},
590 [SECONDARY_TDM_RX_6] = { AFE_PORT_ID_SECONDARY_TDM_RX_6,
591 SECONDARY_TDM_RX_6, 1, 1},
592 [SECONDARY_TDM_TX_6] = { AFE_PORT_ID_SECONDARY_TDM_TX_6,
593 SECONDARY_TDM_TX_6, 0, 1},
594 [SECONDARY_TDM_RX_7] = { AFE_PORT_ID_SECONDARY_TDM_RX_7,
595 SECONDARY_TDM_RX_7, 1, 1},
596 [SECONDARY_TDM_TX_7] = { AFE_PORT_ID_SECONDARY_TDM_TX_7,
597 SECONDARY_TDM_TX_7, 0, 1},
598 [TERTIARY_TDM_RX_0] = { AFE_PORT_ID_TERTIARY_TDM_RX,
599 TERTIARY_TDM_RX_0, 1, 1},
600 [TERTIARY_TDM_TX_0] = { AFE_PORT_ID_TERTIARY_TDM_TX,
601 TERTIARY_TDM_TX_0, 0, 1},
602 [TERTIARY_TDM_RX_1] = { AFE_PORT_ID_TERTIARY_TDM_RX_1,
603 TERTIARY_TDM_RX_1, 1, 1},
604 [TERTIARY_TDM_TX_1] = { AFE_PORT_ID_TERTIARY_TDM_TX_1,
605 TERTIARY_TDM_TX_1, 0, 1},
606 [TERTIARY_TDM_RX_2] = { AFE_PORT_ID_TERTIARY_TDM_RX_2,
607 TERTIARY_TDM_RX_2, 1, 1},
608 [TERTIARY_TDM_TX_2] = { AFE_PORT_ID_TERTIARY_TDM_TX_2,
609 TERTIARY_TDM_TX_2, 0, 1},
610 [TERTIARY_TDM_RX_3] = { AFE_PORT_ID_TERTIARY_TDM_RX_3,
611 TERTIARY_TDM_RX_3, 1, 1},
612 [TERTIARY_TDM_TX_3] = { AFE_PORT_ID_TERTIARY_TDM_TX_3,
613 TERTIARY_TDM_TX_3, 0, 1},
614 [TERTIARY_TDM_RX_4] = { AFE_PORT_ID_TERTIARY_TDM_RX_4,
615 TERTIARY_TDM_RX_4, 1, 1},
616 [TERTIARY_TDM_TX_4] = { AFE_PORT_ID_TERTIARY_TDM_TX_4,
617 TERTIARY_TDM_TX_4, 0, 1},
618 [TERTIARY_TDM_RX_5] = { AFE_PORT_ID_TERTIARY_TDM_RX_5,
619 TERTIARY_TDM_RX_5, 1, 1},
620 [TERTIARY_TDM_TX_5] = { AFE_PORT_ID_TERTIARY_TDM_TX_5,
621 TERTIARY_TDM_TX_5, 0, 1},
622 [TERTIARY_TDM_RX_6] = { AFE_PORT_ID_TERTIARY_TDM_RX_6,
623 TERTIARY_TDM_RX_6, 1, 1},
624 [TERTIARY_TDM_TX_6] = { AFE_PORT_ID_TERTIARY_TDM_TX_6,
625 TERTIARY_TDM_TX_6, 0, 1},
626 [TERTIARY_TDM_RX_7] = { AFE_PORT_ID_TERTIARY_TDM_RX_7,
627 TERTIARY_TDM_RX_7, 1, 1},
628 [TERTIARY_TDM_TX_7] = { AFE_PORT_ID_TERTIARY_TDM_TX_7,
629 TERTIARY_TDM_TX_7, 0, 1},
630 [QUATERNARY_TDM_RX_0] = { AFE_PORT_ID_QUATERNARY_TDM_RX,
631 QUATERNARY_TDM_RX_0, 1, 1},
632 [QUATERNARY_TDM_TX_0] = { AFE_PORT_ID_QUATERNARY_TDM_TX,
633 QUATERNARY_TDM_TX_0, 0, 1},
634 [QUATERNARY_TDM_RX_1] = { AFE_PORT_ID_QUATERNARY_TDM_RX_1,
635 QUATERNARY_TDM_RX_1, 1, 1},
636 [QUATERNARY_TDM_TX_1] = { AFE_PORT_ID_QUATERNARY_TDM_TX_1,
637 QUATERNARY_TDM_TX_1, 0, 1},
638 [QUATERNARY_TDM_RX_2] = { AFE_PORT_ID_QUATERNARY_TDM_RX_2,
639 QUATERNARY_TDM_RX_2, 1, 1},
640 [QUATERNARY_TDM_TX_2] = { AFE_PORT_ID_QUATERNARY_TDM_TX_2,
641 QUATERNARY_TDM_TX_2, 0, 1},
642 [QUATERNARY_TDM_RX_3] = { AFE_PORT_ID_QUATERNARY_TDM_RX_3,
643 QUATERNARY_TDM_RX_3, 1, 1},
644 [QUATERNARY_TDM_TX_3] = { AFE_PORT_ID_QUATERNARY_TDM_TX_3,
645 QUATERNARY_TDM_TX_3, 0, 1},
646 [QUATERNARY_TDM_RX_4] = { AFE_PORT_ID_QUATERNARY_TDM_RX_4,
647 QUATERNARY_TDM_RX_4, 1, 1},
648 [QUATERNARY_TDM_TX_4] = { AFE_PORT_ID_QUATERNARY_TDM_TX_4,
649 QUATERNARY_TDM_TX_4, 0, 1},
650 [QUATERNARY_TDM_RX_5] = { AFE_PORT_ID_QUATERNARY_TDM_RX_5,
651 QUATERNARY_TDM_RX_5, 1, 1},
652 [QUATERNARY_TDM_TX_5] = { AFE_PORT_ID_QUATERNARY_TDM_TX_5,
653 QUATERNARY_TDM_TX_5, 0, 1},
654 [QUATERNARY_TDM_RX_6] = { AFE_PORT_ID_QUATERNARY_TDM_RX_6,
655 QUATERNARY_TDM_RX_6, 1, 1},
656 [QUATERNARY_TDM_TX_6] = { AFE_PORT_ID_QUATERNARY_TDM_TX_6,
657 QUATERNARY_TDM_TX_6, 0, 1},
658 [QUATERNARY_TDM_RX_7] = { AFE_PORT_ID_QUATERNARY_TDM_RX_7,
659 QUATERNARY_TDM_RX_7, 1, 1},
660 [QUATERNARY_TDM_TX_7] = { AFE_PORT_ID_QUATERNARY_TDM_TX_7,
661 QUATERNARY_TDM_TX_7, 0, 1},
662 [QUINARY_TDM_RX_0] = { AFE_PORT_ID_QUINARY_TDM_RX,
663 QUINARY_TDM_RX_0, 1, 1},
664 [QUINARY_TDM_TX_0] = { AFE_PORT_ID_QUINARY_TDM_TX,
665 QUINARY_TDM_TX_0, 0, 1},
666 [QUINARY_TDM_RX_1] = { AFE_PORT_ID_QUINARY_TDM_RX_1,
667 QUINARY_TDM_RX_1, 1, 1},
668 [QUINARY_TDM_TX_1] = { AFE_PORT_ID_QUINARY_TDM_TX_1,
669 QUINARY_TDM_TX_1, 0, 1},
670 [QUINARY_TDM_RX_2] = { AFE_PORT_ID_QUINARY_TDM_RX_2,
671 QUINARY_TDM_RX_2, 1, 1},
672 [QUINARY_TDM_TX_2] = { AFE_PORT_ID_QUINARY_TDM_TX_2,
673 QUINARY_TDM_TX_2, 0, 1},
674 [QUINARY_TDM_RX_3] = { AFE_PORT_ID_QUINARY_TDM_RX_3,
675 QUINARY_TDM_RX_3, 1, 1},
676 [QUINARY_TDM_TX_3] = { AFE_PORT_ID_QUINARY_TDM_TX_3,
677 QUINARY_TDM_TX_3, 0, 1},
678 [QUINARY_TDM_RX_4] = { AFE_PORT_ID_QUINARY_TDM_RX_4,
679 QUINARY_TDM_RX_4, 1, 1},
680 [QUINARY_TDM_TX_4] = { AFE_PORT_ID_QUINARY_TDM_TX_4,
681 QUINARY_TDM_TX_4, 0, 1},
682 [QUINARY_TDM_RX_5] = { AFE_PORT_ID_QUINARY_TDM_RX_5,
683 QUINARY_TDM_RX_5, 1, 1},
684 [QUINARY_TDM_TX_5] = { AFE_PORT_ID_QUINARY_TDM_TX_5,
685 QUINARY_TDM_TX_5, 0, 1},
686 [QUINARY_TDM_RX_6] = { AFE_PORT_ID_QUINARY_TDM_RX_6,
687 QUINARY_TDM_RX_6, 1, 1},
688 [QUINARY_TDM_TX_6] = { AFE_PORT_ID_QUINARY_TDM_TX_6,
689 QUINARY_TDM_TX_6, 0, 1},
690 [QUINARY_TDM_RX_7] = { AFE_PORT_ID_QUINARY_TDM_RX_7,
691 QUINARY_TDM_RX_7, 1, 1},
692 [QUINARY_TDM_TX_7] = { AFE_PORT_ID_QUINARY_TDM_TX_7,
693 QUINARY_TDM_TX_7, 0, 1},
694};
695
696static void q6afe_port_free(struct kref *ref)
697{
698 struct q6afe_port *port;
699 struct q6afe *afe;
700 unsigned long flags;
701
702 port = container_of(ref, struct q6afe_port, refcount);
703 afe = port->afe;
704 spin_lock_irqsave(&afe->port_list_lock, flags);
705 list_del(&port->node);
706 spin_unlock_irqrestore(&afe->port_list_lock, flags);
707 kfree(port->scfg);
708 kfree(port);
709}
710
711static struct q6afe_port *q6afe_find_port(struct q6afe *afe, int token)
712{
713 struct q6afe_port *p = NULL;
714 struct q6afe_port *ret = NULL;
715 unsigned long flags;
716
717 spin_lock_irqsave(&afe->port_list_lock, flags);
718 list_for_each_entry(p, &afe->port_list, node)
719 if (p->token == token) {
720 ret = p;
721 kref_get(&p->refcount);
722 break;
723 }
724
725 spin_unlock_irqrestore(&afe->port_list_lock, flags);
726 return ret;
727}
728
729static int q6afe_callback(struct apr_device *adev, struct apr_resp_pkt *data)
730{
731 struct q6afe *afe = dev_get_drvdata(&adev->dev);
732 struct aprv2_ibasic_rsp_result_t *res;
733 struct apr_hdr *hdr = &data->hdr;
734 struct q6afe_port *port;
735
736 if (!data->payload_size)
737 return 0;
738
739 res = data->payload;
740 switch (hdr->opcode) {
741 case APR_BASIC_RSP_RESULT: {
742 if (res->status) {
743 dev_err(afe->dev, "cmd = 0x%x returned error = 0x%x\n",
744 res->opcode, res->status);
745 }
746 switch (res->opcode) {
747 case AFE_PORT_CMD_SET_PARAM_V2:
748 case AFE_PORT_CMD_DEVICE_STOP:
749 case AFE_PORT_CMD_DEVICE_START:
750 case AFE_SVC_CMD_SET_PARAM:
751 port = q6afe_find_port(afe, hdr->token);
752 if (port) {
753 port->result = *res;
754 wake_up(&port->wait);
755 kref_put(&port->refcount, q6afe_port_free);
756 }
757 break;
758 default:
759 dev_err(afe->dev, "Unknown cmd 0x%x\n", res->opcode);
760 break;
761 }
762 }
763 break;
764 default:
765 break;
766 }
767
768 return 0;
769}
770
771/**
772 * q6afe_get_port_id() - Get port id from a given port index
773 *
774 * @index: port index
775 *
776 * Return: Will be an negative on error or valid port_id on success
777 */
778int q6afe_get_port_id(int index)
779{
780 if (index < 0 || index > AFE_PORT_MAX)
781 return -EINVAL;
782
783 return port_maps[index].port_id;
784}
785EXPORT_SYMBOL_GPL(q6afe_get_port_id);
786
787static int afe_apr_send_pkt(struct q6afe *afe, struct apr_pkt *pkt,
788 struct q6afe_port *port)
789{
790 wait_queue_head_t *wait = &port->wait;
791 struct apr_hdr *hdr = &pkt->hdr;
792 int ret;
793
794 mutex_lock(&afe->lock);
795 port->result.opcode = 0;
796 port->result.status = 0;
797
798 ret = apr_send_pkt(afe->apr, pkt);
799 if (ret < 0) {
800 dev_err(afe->dev, "packet not transmitted (%d)\n", ret);
801 ret = -EINVAL;
802 goto err;
803 }
804
805 ret = wait_event_timeout(*wait, (port->result.opcode == hdr->opcode),
806 msecs_to_jiffies(TIMEOUT_MS));
807 if (!ret) {
808 ret = -ETIMEDOUT;
809 } else if (port->result.status > 0) {
810 dev_err(afe->dev, "DSP returned error[%x]\n",
811 port->result.status);
812 ret = -EINVAL;
813 } else {
814 ret = 0;
815 }
816
817err:
818 mutex_unlock(&afe->lock);
819
820 return ret;
821}
822
823static int q6afe_port_set_param(struct q6afe_port *port, void *data,
824 int param_id, int module_id, int psize)
825{
826 struct afe_svc_cmd_set_param *param;
827 struct afe_port_param_data_v2 *pdata;
828 struct q6afe *afe = port->afe;
829 struct apr_pkt *pkt;
830 u16 port_id = port->id;
831 int ret, pkt_size;
832 void *p, *pl;
833
834 pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
835 p = kzalloc(pkt_size, GFP_KERNEL);
836 if (!p)
837 return -ENOMEM;
838
839 pkt = p;
840 param = p + APR_HDR_SIZE;
841 pdata = p + APR_HDR_SIZE + sizeof(*param);
842 pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
843 memcpy(pl, data, psize);
844
845 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
846 APR_HDR_LEN(APR_HDR_SIZE),
847 APR_PKT_VER);
848 pkt->hdr.pkt_size = pkt_size;
849 pkt->hdr.src_port = 0;
850 pkt->hdr.dest_port = 0;
851 pkt->hdr.token = port->token;
852 pkt->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
853
854 param->payload_size = sizeof(*pdata) + psize;
855 param->payload_address_lsw = 0x00;
856 param->payload_address_msw = 0x00;
857 param->mem_map_handle = 0x00;
858 pdata->module_id = module_id;
859 pdata->param_id = param_id;
860 pdata->param_size = psize;
861
862 ret = afe_apr_send_pkt(afe, pkt, port);
863 if (ret)
864 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
865 port_id, ret);
866
867 kfree(pkt);
868 return ret;
869}
870
871static int q6afe_port_set_param_v2(struct q6afe_port *port, void *data,
872 int param_id, int module_id, int psize)
873{
874 struct afe_port_cmd_set_param_v2 *param;
875 struct afe_port_param_data_v2 *pdata;
876 struct q6afe *afe = port->afe;
877 struct apr_pkt *pkt;
878 u16 port_id = port->id;
879 int ret, pkt_size;
880 void *p, *pl;
881
882 pkt_size = APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata) + psize;
883 p = kzalloc(pkt_size, GFP_KERNEL);
884 if (!p)
885 return -ENOMEM;
886
887 pkt = p;
888 param = p + APR_HDR_SIZE;
889 pdata = p + APR_HDR_SIZE + sizeof(*param);
890 pl = p + APR_HDR_SIZE + sizeof(*param) + sizeof(*pdata);
891 memcpy(pl, data, psize);
892
893 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
894 APR_HDR_LEN(APR_HDR_SIZE),
895 APR_PKT_VER);
896 pkt->hdr.pkt_size = pkt_size;
897 pkt->hdr.src_port = 0;
898 pkt->hdr.dest_port = 0;
899 pkt->hdr.token = port->token;
900 pkt->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
901
902 param->port_id = port_id;
903 param->payload_size = sizeof(*pdata) + psize;
904 param->payload_address_lsw = 0x00;
905 param->payload_address_msw = 0x00;
906 param->mem_map_handle = 0x00;
907 pdata->module_id = module_id;
908 pdata->param_id = param_id;
909 pdata->param_size = psize;
910
911 ret = afe_apr_send_pkt(afe, pkt, port);
912 if (ret)
913 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
914 port_id, ret);
915
916 kfree(pkt);
917 return ret;
918}
919
920static int q6afe_set_lpass_clock(struct q6afe_port *port,
921 struct afe_clk_cfg *cfg)
922{
923 return q6afe_port_set_param_v2(port, cfg,
924 AFE_PARAM_ID_LPAIF_CLK_CONFIG,
925 AFE_MODULE_AUDIO_DEV_INTERFACE,
926 sizeof(*cfg));
927}
928
929static int q6afe_set_lpass_clock_v2(struct q6afe_port *port,
930 struct afe_clk_set *cfg)
931{
932 return q6afe_port_set_param(port, cfg, AFE_PARAM_ID_CLOCK_SET,
933 AFE_MODULE_CLOCK_SET, sizeof(*cfg));
934}
935
936static int q6afe_set_digital_codec_core_clock(struct q6afe_port *port,
937 struct afe_digital_clk_cfg *cfg)
938{
939 return q6afe_port_set_param_v2(port, cfg,
940 AFE_PARAM_ID_INT_DIGITAL_CDC_CLK_CONFIG,
941 AFE_MODULE_AUDIO_DEV_INTERFACE,
942 sizeof(*cfg));
943}
944
945int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
946 int clk_src, int clk_root,
947 unsigned int freq, int dir)
948{
949 struct afe_clk_cfg ccfg = {0,};
950 struct afe_clk_set cset = {0,};
951 struct afe_digital_clk_cfg dcfg = {0,};
952 int ret;
953
954 switch (clk_id) {
955 case LPAIF_DIG_CLK:
956 dcfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
957 dcfg.clk_val = freq;
958 dcfg.clk_root = clk_root;
959 ret = q6afe_set_digital_codec_core_clock(port, &dcfg);
960 break;
961 case LPAIF_BIT_CLK:
962 ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
963 ccfg.clk_val1 = freq;
964 ccfg.clk_src = clk_src;
965 ccfg.clk_root = clk_root;
966 ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK1_VALID;
967 ret = q6afe_set_lpass_clock(port, &ccfg);
968 break;
969
970 case LPAIF_OSR_CLK:
971 ccfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
972 ccfg.clk_val2 = freq;
973 ccfg.clk_src = clk_src;
974 ccfg.clk_root = clk_root;
975 ccfg.clk_set_mode = Q6AFE_LPASS_MODE_CLK2_VALID;
976 ret = q6afe_set_lpass_clock(port, &ccfg);
977 break;
978 case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
979 case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
980 case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
981 cset.clk_set_minor_version = AFE_API_VERSION_CLOCK_SET;
982 cset.clk_id = clk_id;
983 cset.clk_freq_in_hz = freq;
984 cset.clk_attri = clk_src;
985 cset.clk_root = clk_root;
986 cset.enable = !!freq;
987 ret = q6afe_set_lpass_clock_v2(port, &cset);
988 break;
989 default:
990 ret = -EINVAL;
991 break;
992 }
993
994 return ret;
995}
996EXPORT_SYMBOL_GPL(q6afe_port_set_sysclk);
997
998/**
999 * q6afe_port_stop() - Stop a afe port
1000 *
1001 * @port: Instance of port to stop
1002 *
1003 * Return: Will be an negative on packet size on success.
1004 */
1005int q6afe_port_stop(struct q6afe_port *port)
1006{
1007 struct afe_port_cmd_device_stop *stop;
1008 struct q6afe *afe = port->afe;
1009 struct apr_pkt *pkt;
1010 int port_id = port->id;
1011 int ret = 0;
1012 int index, pkt_size;
1013 void *p;
1014
1015 port_id = port->id;
1016 index = port->token;
1017 if (index < 0 || index > AFE_PORT_MAX) {
1018 dev_err(afe->dev, "AFE port index[%d] invalid!\n", index);
1019 return -EINVAL;
1020 }
1021
1022 pkt_size = APR_HDR_SIZE + sizeof(*stop);
1023 p = kzalloc(pkt_size, GFP_KERNEL);
1024 if (!p)
1025 return -ENOMEM;
1026
1027 pkt = p;
1028 stop = p + APR_HDR_SIZE;
1029
1030 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1031 APR_HDR_LEN(APR_HDR_SIZE),
1032 APR_PKT_VER);
1033 pkt->hdr.pkt_size = pkt_size;
1034 pkt->hdr.src_port = 0;
1035 pkt->hdr.dest_port = 0;
1036 pkt->hdr.token = index;
1037 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_STOP;
1038 stop->port_id = port_id;
1039 stop->reserved = 0;
1040
1041 ret = afe_apr_send_pkt(afe, pkt, port);
1042 if (ret)
1043 dev_err(afe->dev, "AFE close failed %d\n", ret);
1044
1045 kfree(pkt);
1046 return ret;
1047}
1048EXPORT_SYMBOL_GPL(q6afe_port_stop);
1049
1050/**
1051 * q6afe_slim_port_prepare() - Prepare slim afe port.
1052 *
1053 * @port: Instance of afe port
1054 * @cfg: SLIM configuration for the afe port
1055 *
1056 */
1057void q6afe_slim_port_prepare(struct q6afe_port *port,
1058 struct q6afe_slim_cfg *cfg)
1059{
1060 union afe_port_config *pcfg = &port->port_cfg;
1061
1062 pcfg->slim_cfg.sb_cfg_minor_version = AFE_API_VERSION_SLIMBUS_CONFIG;
1063 pcfg->slim_cfg.sample_rate = cfg->sample_rate;
1064 pcfg->slim_cfg.bit_width = cfg->bit_width;
1065 pcfg->slim_cfg.num_channels = cfg->num_channels;
1066 pcfg->slim_cfg.data_format = cfg->data_format;
1067 pcfg->slim_cfg.shared_ch_mapping[0] = cfg->ch_mapping[0];
1068 pcfg->slim_cfg.shared_ch_mapping[1] = cfg->ch_mapping[1];
1069 pcfg->slim_cfg.shared_ch_mapping[2] = cfg->ch_mapping[2];
1070 pcfg->slim_cfg.shared_ch_mapping[3] = cfg->ch_mapping[3];
1071
1072}
1073EXPORT_SYMBOL_GPL(q6afe_slim_port_prepare);
1074
1075/**
1076 * q6afe_tdm_port_prepare() - Prepare tdm afe port.
1077 *
1078 * @port: Instance of afe port
1079 * @cfg: TDM configuration for the afe port
1080 *
1081 */
1082void q6afe_tdm_port_prepare(struct q6afe_port *port,
1083 struct q6afe_tdm_cfg *cfg)
1084{
1085 union afe_port_config *pcfg = &port->port_cfg;
1086
1087 pcfg->tdm_cfg.tdm_cfg_minor_version = AFE_API_VERSION_TDM_CONFIG;
1088 pcfg->tdm_cfg.num_channels = cfg->num_channels;
1089 pcfg->tdm_cfg.sample_rate = cfg->sample_rate;
1090 pcfg->tdm_cfg.bit_width = cfg->bit_width;
1091 pcfg->tdm_cfg.data_format = cfg->data_format;
1092 pcfg->tdm_cfg.sync_mode = cfg->sync_mode;
1093 pcfg->tdm_cfg.sync_src = cfg->sync_src;
1094 pcfg->tdm_cfg.nslots_per_frame = cfg->nslots_per_frame;
1095
1096 pcfg->tdm_cfg.slot_width = cfg->slot_width;
1097 pcfg->tdm_cfg.slot_mask = cfg->slot_mask;
1098 port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL);
1099 if (!port->scfg)
1100 return;
1101
1102 port->scfg->minor_version = AFE_API_VERSION_SLOT_MAPPING_CONFIG;
1103 port->scfg->num_channels = cfg->num_channels;
1104 port->scfg->bitwidth = cfg->bit_width;
1105 port->scfg->data_align_type = cfg->data_align_type;
1106 memcpy(port->scfg->ch_mapping, cfg->ch_mapping,
1107 sizeof(u16) * AFE_PORT_MAX_AUDIO_CHAN_CNT);
1108}
1109EXPORT_SYMBOL_GPL(q6afe_tdm_port_prepare);
1110
1111/**
1112 * q6afe_hdmi_port_prepare() - Prepare hdmi afe port.
1113 *
1114 * @port: Instance of afe port
1115 * @cfg: HDMI configuration for the afe port
1116 *
1117 */
1118void q6afe_hdmi_port_prepare(struct q6afe_port *port,
1119 struct q6afe_hdmi_cfg *cfg)
1120{
1121 union afe_port_config *pcfg = &port->port_cfg;
1122
1123 pcfg->hdmi_multi_ch.hdmi_cfg_minor_version =
1124 AFE_API_VERSION_HDMI_CONFIG;
1125 pcfg->hdmi_multi_ch.datatype = cfg->datatype;
1126 pcfg->hdmi_multi_ch.channel_allocation = cfg->channel_allocation;
1127 pcfg->hdmi_multi_ch.sample_rate = cfg->sample_rate;
1128 pcfg->hdmi_multi_ch.bit_width = cfg->bit_width;
1129}
1130EXPORT_SYMBOL_GPL(q6afe_hdmi_port_prepare);
1131
1132/**
1133 * q6afe_i2s_port_prepare() - Prepare i2s afe port.
1134 *
1135 * @port: Instance of afe port
1136 * @cfg: I2S configuration for the afe port
1137 * Return: Will be an negative on error and zero on success.
1138 */
1139int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg)
1140{
1141 union afe_port_config *pcfg = &port->port_cfg;
1142 struct device *dev = port->afe->dev;
1143 int num_sd_lines;
1144
1145 pcfg->i2s_cfg.i2s_cfg_minor_version = AFE_API_VERSION_I2S_CONFIG;
1146 pcfg->i2s_cfg.sample_rate = cfg->sample_rate;
1147 pcfg->i2s_cfg.bit_width = cfg->bit_width;
1148 pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA;
1149
1150 switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1151 case SND_SOC_DAIFMT_CBS_CFS:
1152 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL;
1153 break;
1154 case SND_SOC_DAIFMT_CBM_CFM:
1155 /* CPU is slave */
1156 pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL;
1157 break;
1158 default:
1159 break;
1160 }
1161
1162 num_sd_lines = hweight_long(cfg->sd_line_mask);
1163
1164 switch (num_sd_lines) {
1165 case 0:
1166 dev_err(dev, "no line is assigned\n");
1167 return -EINVAL;
1168 case 1:
1169 switch (cfg->sd_line_mask) {
1170 case AFE_PORT_I2S_SD0_MASK:
1171 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1172 break;
1173 case AFE_PORT_I2S_SD1_MASK:
1174 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD1;
1175 break;
1176 case AFE_PORT_I2S_SD2_MASK:
1177 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1178 break;
1179 case AFE_PORT_I2S_SD3_MASK:
1180 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD3;
1181 break;
1182 default:
1183 dev_err(dev, "Invalid SD lines\n");
1184 return -EINVAL;
1185 }
1186 break;
1187 case 2:
1188 switch (cfg->sd_line_mask) {
1189 case AFE_PORT_I2S_SD0_1_MASK:
1190 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD01;
1191 break;
1192 case AFE_PORT_I2S_SD2_3_MASK:
1193 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_QUAD23;
1194 break;
1195 default:
1196 dev_err(dev, "Invalid SD lines\n");
1197 return -EINVAL;
1198 }
1199 break;
1200 case 3:
1201 switch (cfg->sd_line_mask) {
1202 case AFE_PORT_I2S_SD0_1_2_MASK:
1203 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_6CHS;
1204 break;
1205 default:
1206 dev_err(dev, "Invalid SD lines\n");
1207 return -EINVAL;
1208 }
1209 break;
1210 case 4:
1211 switch (cfg->sd_line_mask) {
1212 case AFE_PORT_I2S_SD0_1_2_3_MASK:
1213 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_8CHS;
1214
1215 break;
1216 default:
1217 dev_err(dev, "Invalid SD lines\n");
1218 return -EINVAL;
1219 }
1220 break;
1221 default:
1222 dev_err(dev, "Invalid SD lines\n");
1223 return -EINVAL;
1224 }
1225
1226 switch (cfg->num_channels) {
1227 case 1:
1228 case 2:
1229 switch (pcfg->i2s_cfg.channel_mode) {
1230 case AFE_PORT_I2S_QUAD01:
1231 case AFE_PORT_I2S_6CHS:
1232 case AFE_PORT_I2S_8CHS:
1233 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD0;
1234 break;
1235 case AFE_PORT_I2S_QUAD23:
1236 pcfg->i2s_cfg.channel_mode = AFE_PORT_I2S_SD2;
1237 break;
1238 }
1239
1240 if (cfg->num_channels == 2)
1241 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_STEREO;
1242 else
1243 pcfg->i2s_cfg.mono_stereo = AFE_PORT_I2S_MONO;
1244
1245 break;
1246 case 3:
1247 case 4:
1248 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_QUAD01) {
1249 dev_err(dev, "Invalid Channel mode\n");
1250 return -EINVAL;
1251 }
1252 break;
1253 case 5:
1254 case 6:
1255 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_6CHS) {
1256 dev_err(dev, "Invalid Channel mode\n");
1257 return -EINVAL;
1258 }
1259 break;
1260 case 7:
1261 case 8:
1262 if (pcfg->i2s_cfg.channel_mode < AFE_PORT_I2S_8CHS) {
1263 dev_err(dev, "Invalid Channel mode\n");
1264 return -EINVAL;
1265 }
1266 break;
1267 default:
1268 break;
1269 }
1270
1271 return 0;
1272}
1273EXPORT_SYMBOL_GPL(q6afe_i2s_port_prepare);
1274
1275/**
1276 * q6afe_port_start() - Start a afe port
1277 *
1278 * @port: Instance of port to start
1279 *
1280 * Return: Will be an negative on packet size on success.
1281 */
1282int q6afe_port_start(struct q6afe_port *port)
1283{
1284 struct afe_port_cmd_device_start *start;
1285 struct q6afe *afe = port->afe;
1286 int port_id = port->id;
1287 int ret, param_id = port->cfg_type;
1288 struct apr_pkt *pkt;
1289 int pkt_size;
1290 void *p;
1291
1292 ret = q6afe_port_set_param_v2(port, &port->port_cfg, param_id,
1293 AFE_MODULE_AUDIO_DEV_INTERFACE,
1294 sizeof(port->port_cfg));
1295 if (ret) {
1296 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1297 port_id, ret);
1298 return ret;
1299 }
1300
1301 if (port->scfg) {
1302 ret = q6afe_port_set_param_v2(port, port->scfg,
1303 AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG,
1304 AFE_MODULE_TDM, sizeof(*port->scfg));
1305 if (ret) {
1306 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1307 port_id, ret);
1308 return ret;
1309 }
1310 }
1311
1312 pkt_size = APR_HDR_SIZE + sizeof(*start);
1313 p = kzalloc(pkt_size, GFP_KERNEL);
1314 if (!p)
1315 return -ENOMEM;
1316
1317 pkt = p;
1318 start = p + APR_HDR_SIZE;
1319
1320 pkt->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
1321 APR_HDR_LEN(APR_HDR_SIZE),
1322 APR_PKT_VER);
1323 pkt->hdr.pkt_size = pkt_size;
1324 pkt->hdr.src_port = 0;
1325 pkt->hdr.dest_port = 0;
1326 pkt->hdr.token = port->token;
1327 pkt->hdr.opcode = AFE_PORT_CMD_DEVICE_START;
1328
1329 start->port_id = port_id;
1330
1331 ret = afe_apr_send_pkt(afe, pkt, port);
1332 if (ret)
1333 dev_err(afe->dev, "AFE enable for port 0x%x failed %d\n",
1334 port_id, ret);
1335
1336 kfree(pkt);
1337 return ret;
1338}
1339EXPORT_SYMBOL_GPL(q6afe_port_start);
1340
1341/**
1342 * q6afe_port_get_from_id() - Get port instance from a port id
1343 *
1344 * @dev: Pointer to afe child device.
1345 * @id: port id
1346 *
1347 * Return: Will be an error pointer on error or a valid afe port
1348 * on success.
1349 */
1350struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
1351{
1352 int port_id;
1353 struct q6afe *afe = dev_get_drvdata(dev->parent);
1354 struct q6afe_port *port;
1355 unsigned long flags;
1356 int cfg_type;
1357
1358 if (id < 0 || id > AFE_PORT_MAX) {
1359 dev_err(dev, "AFE port token[%d] invalid!\n", id);
1360 return ERR_PTR(-EINVAL);
1361 }
1362
1363 /* if port is multiple times bind/unbind before callback finishes */
1364 port = q6afe_find_port(afe, id);
1365 if (port) {
1366 dev_err(dev, "AFE Port already open\n");
1367 return port;
1368 }
1369
1370 port_id = port_maps[id].port_id;
1371
1372 switch (port_id) {
1373 case AFE_PORT_ID_MULTICHAN_HDMI_RX:
1374 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
1375 break;
1376 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_RX:
1377 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX:
1378 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_2_RX:
1379 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_3_RX:
1380 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_4_RX:
1381 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_5_RX:
1382 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_6_RX:
1383 cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG;
1384 break;
1385
1386 case AFE_PORT_ID_PRIMARY_MI2S_RX:
1387 case AFE_PORT_ID_PRIMARY_MI2S_TX:
1388 case AFE_PORT_ID_SECONDARY_MI2S_RX:
1389 case AFE_PORT_ID_SECONDARY_MI2S_TX:
1390 case AFE_PORT_ID_TERTIARY_MI2S_RX:
1391 case AFE_PORT_ID_TERTIARY_MI2S_TX:
1392 case AFE_PORT_ID_QUATERNARY_MI2S_RX:
1393 case AFE_PORT_ID_QUATERNARY_MI2S_TX:
1394 cfg_type = AFE_PARAM_ID_I2S_CONFIG;
1395 break;
1396 case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
1397 cfg_type = AFE_PARAM_ID_TDM_CONFIG;
1398 break;
1399
1400 default:
1401 dev_err(dev, "Invalid port id 0x%x\n", port_id);
1402 return ERR_PTR(-EINVAL);
1403 }
1404
1405 port = kzalloc(sizeof(*port), GFP_KERNEL);
1406 if (!port)
1407 return ERR_PTR(-ENOMEM);
1408
1409 init_waitqueue_head(&port->wait);
1410
1411 port->token = id;
1412 port->id = port_id;
1413 port->afe = afe;
1414 port->cfg_type = cfg_type;
1415 kref_init(&port->refcount);
1416
1417 spin_lock_irqsave(&afe->port_list_lock, flags);
1418 list_add_tail(&port->node, &afe->port_list);
1419 spin_unlock_irqrestore(&afe->port_list_lock, flags);
1420
1421 return port;
1422
1423}
1424EXPORT_SYMBOL_GPL(q6afe_port_get_from_id);
1425
1426/**
1427 * q6afe_port_put() - Release port reference
1428 *
1429 * @port: Instance of port to put
1430 */
1431void q6afe_port_put(struct q6afe_port *port)
1432{
1433 kref_put(&port->refcount, q6afe_port_free);
1434}
1435EXPORT_SYMBOL_GPL(q6afe_port_put);
1436
1437static int q6afe_probe(struct apr_device *adev)
1438{
1439 struct q6afe *afe;
1440 struct device *dev = &adev->dev;
1441 struct device_node *dais_np;
1442
1443 afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
1444 if (!afe)
1445 return -ENOMEM;
1446
1447 q6core_get_svc_api_info(adev->svc_id, &afe->ainfo);
1448 afe->apr = adev;
1449 mutex_init(&afe->lock);
1450 afe->dev = dev;
1451 INIT_LIST_HEAD(&afe->port_list);
1452 spin_lock_init(&afe->port_list_lock);
1453
1454 dev_set_drvdata(dev, afe);
1455
1456 dais_np = of_get_child_by_name(dev->of_node, "dais");
1457 if (dais_np) {
1458 afe->pdev_dais = of_platform_device_create(dais_np,
1459 "q6afe-dai", dev);
1460 of_node_put(dais_np);
1461 }
1462
1463 return 0;
1464}
1465
1466static int q6afe_remove(struct apr_device *adev)
1467{
1468 struct q6afe *afe = dev_get_drvdata(&adev->dev);
1469
1470 if (afe->pdev_dais)
1471 of_platform_device_destroy(&afe->pdev_dais->dev, NULL);
1472
1473 return 0;
1474}
1475
1476static const struct of_device_id q6afe_device_id[] = {
1477 { .compatible = "qcom,q6afe" },
1478 {},
1479};
1480MODULE_DEVICE_TABLE(of, q6afe_device_id);
1481
1482static struct apr_driver qcom_q6afe_driver = {
1483 .probe = q6afe_probe,
1484 .remove = q6afe_remove,
1485 .callback = q6afe_callback,
1486 .driver = {
1487 .name = "qcom-q6afe",
1488 .of_match_table = of_match_ptr(q6afe_device_id),
1489
1490 },
1491};
1492
1493module_apr_driver(qcom_q6afe_driver);
1494MODULE_DESCRIPTION("Q6 Audio Front End");
1495MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
new file mode 100644
index 000000000000..c7ed5422baff
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6afe.h
@@ -0,0 +1,211 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __Q6AFE_H__
4#define __Q6AFE_H__
5
6#include <dt-bindings/sound/qcom,q6afe.h>
7
8#define AFE_PORT_MAX 105
9
10#define MSM_AFE_PORT_TYPE_RX 0
11#define MSM_AFE_PORT_TYPE_TX 1
12#define AFE_MAX_PORTS AFE_PORT_MAX
13
14#define Q6AFE_MAX_MI2S_LINES 4
15
16#define AFE_MAX_CHAN_COUNT 8
17#define AFE_PORT_MAX_AUDIO_CHAN_CNT 0x8
18
19#define Q6AFE_LPASS_CLK_SRC_INTERNAL 1
20#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
21
22#define LPAIF_DIG_CLK 1
23#define LPAIF_BIT_CLK 2
24#define LPAIF_OSR_CLK 3
25
26/* Clock ID for Primary I2S IBIT */
27#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT 0x100
28/* Clock ID for Primary I2S EBIT */
29#define Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT 0x101
30/* Clock ID for Secondary I2S IBIT */
31#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT 0x102
32/* Clock ID for Secondary I2S EBIT */
33#define Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT 0x103
34/* Clock ID for Tertiary I2S IBIT */
35#define Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT 0x104
36/* Clock ID for Tertiary I2S EBIT */
37#define Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT 0x105
38/* Clock ID for Quartnery I2S IBIT */
39#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT 0x106
40/* Clock ID for Quartnery I2S EBIT */
41#define Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT 0x107
42/* Clock ID for Speaker I2S IBIT */
43#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT 0x108
44/* Clock ID for Speaker I2S EBIT */
45#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT 0x109
46/* Clock ID for Speaker I2S OSR */
47#define Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR 0x10A
48
49/* Clock ID for QUINARY I2S IBIT */
50#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT 0x10B
51/* Clock ID for QUINARY I2S EBIT */
52#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT 0x10C
53/* Clock ID for SENARY I2S IBIT */
54#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_IBIT 0x10D
55/* Clock ID for SENARY I2S EBIT */
56#define Q6AFE_LPASS_CLK_ID_SEN_MI2S_EBIT 0x10E
57/* Clock ID for INT0 I2S IBIT */
58#define Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT 0x10F
59/* Clock ID for INT1 I2S IBIT */
60#define Q6AFE_LPASS_CLK_ID_INT1_MI2S_IBIT 0x110
61/* Clock ID for INT2 I2S IBIT */
62#define Q6AFE_LPASS_CLK_ID_INT2_MI2S_IBIT 0x111
63/* Clock ID for INT3 I2S IBIT */
64#define Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT 0x112
65/* Clock ID for INT4 I2S IBIT */
66#define Q6AFE_LPASS_CLK_ID_INT4_MI2S_IBIT 0x113
67/* Clock ID for INT5 I2S IBIT */
68#define Q6AFE_LPASS_CLK_ID_INT5_MI2S_IBIT 0x114
69/* Clock ID for INT6 I2S IBIT */
70#define Q6AFE_LPASS_CLK_ID_INT6_MI2S_IBIT 0x115
71
72/* Clock ID for QUINARY MI2S OSR CLK */
73#define Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR 0x116
74
75/* Clock ID for Primary PCM IBIT */
76#define Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT 0x200
77/* Clock ID for Primary PCM EBIT */
78#define Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT 0x201
79/* Clock ID for Secondary PCM IBIT */
80#define Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT 0x202
81/* Clock ID for Secondary PCM EBIT */
82#define Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT 0x203
83/* Clock ID for Tertiary PCM IBIT */
84#define Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT 0x204
85/* Clock ID for Tertiary PCM EBIT */
86#define Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT 0x205
87/* Clock ID for Quartery PCM IBIT */
88#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT 0x206
89/* Clock ID for Quartery PCM EBIT */
90#define Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT 0x207
91/* Clock ID for Quinary PCM IBIT */
92#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_IBIT 0x208
93/* Clock ID for Quinary PCM EBIT */
94#define Q6AFE_LPASS_CLK_ID_QUIN_PCM_EBIT 0x209
95/* Clock ID for QUINARY PCM OSR */
96#define Q6AFE_LPASS_CLK_ID_QUI_PCM_OSR 0x20A
97
98/** Clock ID for Primary TDM IBIT */
99#define Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT 0x200
100/** Clock ID for Primary TDM EBIT */
101#define Q6AFE_LPASS_CLK_ID_PRI_TDM_EBIT 0x201
102/** Clock ID for Secondary TDM IBIT */
103#define Q6AFE_LPASS_CLK_ID_SEC_TDM_IBIT 0x202
104/** Clock ID for Secondary TDM EBIT */
105#define Q6AFE_LPASS_CLK_ID_SEC_TDM_EBIT 0x203
106/** Clock ID for Tertiary TDM IBIT */
107#define Q6AFE_LPASS_CLK_ID_TER_TDM_IBIT 0x204
108/** Clock ID for Tertiary TDM EBIT */
109#define Q6AFE_LPASS_CLK_ID_TER_TDM_EBIT 0x205
110/** Clock ID for Quartery TDM IBIT */
111#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT 0x206
112/** Clock ID for Quartery TDM EBIT */
113#define Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT 0x207
114/** Clock ID for Quinary TDM IBIT */
115#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_IBIT 0x208
116/** Clock ID for Quinary TDM EBIT */
117#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT 0x209
118/** Clock ID for Quinary TDM OSR */
119#define Q6AFE_LPASS_CLK_ID_QUIN_TDM_OSR 0x20A
120
121/* Clock ID for MCLK1 */
122#define Q6AFE_LPASS_CLK_ID_MCLK_1 0x300
123/* Clock ID for MCLK2 */
124#define Q6AFE_LPASS_CLK_ID_MCLK_2 0x301
125/* Clock ID for MCLK3 */
126#define Q6AFE_LPASS_CLK_ID_MCLK_3 0x302
127/* Clock ID for MCLK4 */
128#define Q6AFE_LPASS_CLK_ID_MCLK_4 0x304
129/* Clock ID for Internal Digital Codec Core */
130#define Q6AFE_LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 0x303
131/* Clock ID for INT MCLK0 */
132#define Q6AFE_LPASS_CLK_ID_INT_MCLK_0 0x305
133/* Clock ID for INT MCLK1 */
134#define Q6AFE_LPASS_CLK_ID_INT_MCLK_1 0x306
135
136/* Clock attribute for invalid use (reserved for internal usage) */
137#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVALID 0x0
138/* Clock attribute for no couple case */
139#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
140/* Clock attribute for dividend couple case */
141#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2
142/* Clock attribute for divisor couple case */
143#define Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3
144/* Clock attribute for invert and no couple case */
145#define Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO 0x4
146
147#define Q6AFE_CMAP_INVALID 0xFFFF
148
149struct q6afe_hdmi_cfg {
150 u16 datatype;
151 u16 channel_allocation;
152 u32 sample_rate;
153 u16 bit_width;
154};
155
156struct q6afe_slim_cfg {
157 u32 sample_rate;
158 u16 bit_width;
159 u16 data_format;
160 u16 num_channels;
161 u8 ch_mapping[AFE_MAX_CHAN_COUNT];
162};
163
164struct q6afe_i2s_cfg {
165 u32 sample_rate;
166 u16 bit_width;
167 u16 data_format;
168 u16 num_channels;
169 u32 sd_line_mask;
170 int fmt;
171};
172
173struct q6afe_tdm_cfg {
174 u16 num_channels;
175 u32 sample_rate;
176 u16 bit_width;
177 u16 data_format;
178 u16 sync_mode;
179 u16 sync_src;
180 u16 nslots_per_frame;
181 u16 slot_width;
182 u16 slot_mask;
183 u32 data_align_type;
184 u16 ch_mapping[AFE_MAX_CHAN_COUNT];
185};
186
187struct q6afe_port_config {
188 struct q6afe_hdmi_cfg hdmi;
189 struct q6afe_slim_cfg slim;
190 struct q6afe_i2s_cfg i2s_cfg;
191 struct q6afe_tdm_cfg tdm;
192};
193
194struct q6afe_port;
195
196struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id);
197int q6afe_port_start(struct q6afe_port *port);
198int q6afe_port_stop(struct q6afe_port *port);
199void q6afe_port_put(struct q6afe_port *port);
200int q6afe_get_port_id(int index);
201void q6afe_hdmi_port_prepare(struct q6afe_port *port,
202 struct q6afe_hdmi_cfg *cfg);
203void q6afe_slim_port_prepare(struct q6afe_port *port,
204 struct q6afe_slim_cfg *cfg);
205int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg);
206void q6afe_tdm_port_prepare(struct q6afe_port *port, struct q6afe_tdm_cfg *cfg);
207
208int q6afe_port_set_sysclk(struct q6afe_port *port, int clk_id,
209 int clk_src, int clk_root,
210 unsigned int freq, int dir);
211#endif /* __Q6AFE_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
new file mode 100644
index 000000000000..349c6a883c63
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -0,0 +1,624 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/init.h>
6#include <linux/err.h>
7#include <linux/module.h>
8#include <linux/platform_device.h>
9#include <linux/slab.h>
10#include <linux/component.h>
11#include <sound/soc.h>
12#include <sound/soc.h>
13#include <sound/soc-dapm.h>
14#include <sound/pcm.h>
15#include <asm/dma.h>
16#include <linux/dma-mapping.h>
17#include <linux/of_device.h>
18#include <sound/pcm_params.h>
19#include "q6asm.h"
20#include "q6routing.h"
21#include "q6dsp-errno.h"
22
23#define DRV_NAME "q6asm-fe-dai"
24
25#define PLAYBACK_MIN_NUM_PERIODS 2
26#define PLAYBACK_MAX_NUM_PERIODS 8
27#define PLAYBACK_MAX_PERIOD_SIZE 65536
28#define PLAYBACK_MIN_PERIOD_SIZE 128
29#define CAPTURE_MIN_NUM_PERIODS 2
30#define CAPTURE_MAX_NUM_PERIODS 8
31#define CAPTURE_MAX_PERIOD_SIZE 4096
32#define CAPTURE_MIN_PERIOD_SIZE 320
33#define SID_MASK_DEFAULT 0xF
34
35enum stream_state {
36 Q6ASM_STREAM_IDLE = 0,
37 Q6ASM_STREAM_STOPPED,
38 Q6ASM_STREAM_RUNNING,
39};
40
41struct q6asm_dai_rtd {
42 struct snd_pcm_substream *substream;
43 phys_addr_t phys;
44 unsigned int pcm_size;
45 unsigned int pcm_count;
46 unsigned int pcm_irq_pos; /* IRQ position */
47 unsigned int periods;
48 uint16_t bits_per_sample;
49 uint16_t source; /* Encoding source bit mask */
50 struct audio_client *audio_client;
51 uint16_t session_id;
52 enum stream_state state;
53};
54
55struct q6asm_dai_data {
56 long long int sid;
57};
58
59static struct snd_pcm_hardware q6asm_dai_hardware_capture = {
60 .info = (SNDRV_PCM_INFO_MMAP |
61 SNDRV_PCM_INFO_BLOCK_TRANSFER |
62 SNDRV_PCM_INFO_MMAP_VALID |
63 SNDRV_PCM_INFO_INTERLEAVED |
64 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
65 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
66 SNDRV_PCM_FMTBIT_S24_LE),
67 .rates = SNDRV_PCM_RATE_8000_48000,
68 .rate_min = 8000,
69 .rate_max = 48000,
70 .channels_min = 1,
71 .channels_max = 4,
72 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
73 CAPTURE_MAX_PERIOD_SIZE,
74 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
75 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
76 .periods_min = CAPTURE_MIN_NUM_PERIODS,
77 .periods_max = CAPTURE_MAX_NUM_PERIODS,
78 .fifo_size = 0,
79};
80
81static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
82 .info = (SNDRV_PCM_INFO_MMAP |
83 SNDRV_PCM_INFO_BLOCK_TRANSFER |
84 SNDRV_PCM_INFO_MMAP_VALID |
85 SNDRV_PCM_INFO_INTERLEAVED |
86 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
87 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
88 SNDRV_PCM_FMTBIT_S24_LE),
89 .rates = SNDRV_PCM_RATE_8000_192000,
90 .rate_min = 8000,
91 .rate_max = 192000,
92 .channels_min = 1,
93 .channels_max = 8,
94 .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS *
95 PLAYBACK_MAX_PERIOD_SIZE),
96 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
97 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
98 .periods_min = PLAYBACK_MIN_NUM_PERIODS,
99 .periods_max = PLAYBACK_MAX_NUM_PERIODS,
100 .fifo_size = 0,
101};
102
103#define Q6ASM_FEDAI_DRIVER(num) { \
104 .playback = { \
105 .stream_name = "MultiMedia"#num" Playback", \
106 .rates = (SNDRV_PCM_RATE_8000_192000| \
107 SNDRV_PCM_RATE_KNOT), \
108 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \
109 SNDRV_PCM_FMTBIT_S24_LE), \
110 .channels_min = 1, \
111 .channels_max = 8, \
112 .rate_min = 8000, \
113 .rate_max = 192000, \
114 }, \
115 .capture = { \
116 .stream_name = "MultiMedia"#num" Capture", \
117 .rates = (SNDRV_PCM_RATE_8000_48000| \
118 SNDRV_PCM_RATE_KNOT), \
119 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \
120 SNDRV_PCM_FMTBIT_S24_LE), \
121 .channels_min = 1, \
122 .channels_max = 4, \
123 .rate_min = 8000, \
124 .rate_max = 48000, \
125 }, \
126 .name = "MultiMedia"#num, \
127 .probe = fe_dai_probe, \
128 .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \
129 }
130
131/* Conventional and unconventional sample rate supported */
132static unsigned int supported_sample_rates[] = {
133 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
134 88200, 96000, 176400, 192000
135};
136
137static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
138 .count = ARRAY_SIZE(supported_sample_rates),
139 .list = supported_sample_rates,
140 .mask = 0,
141};
142
143static void event_handler(uint32_t opcode, uint32_t token,
144 uint32_t *payload, void *priv)
145{
146 struct q6asm_dai_rtd *prtd = priv;
147 struct snd_pcm_substream *substream = prtd->substream;
148
149 switch (opcode) {
150 case ASM_CLIENT_EVENT_CMD_RUN_DONE:
151 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
152 q6asm_write_async(prtd->audio_client,
153 prtd->pcm_count, 0, 0, NO_TIMESTAMP);
154 break;
155 case ASM_CLIENT_EVENT_CMD_EOS_DONE:
156 prtd->state = Q6ASM_STREAM_STOPPED;
157 break;
158 case ASM_CLIENT_EVENT_DATA_WRITE_DONE: {
159 prtd->pcm_irq_pos += prtd->pcm_count;
160 snd_pcm_period_elapsed(substream);
161 if (prtd->state == Q6ASM_STREAM_RUNNING)
162 q6asm_write_async(prtd->audio_client,
163 prtd->pcm_count, 0, 0, NO_TIMESTAMP);
164
165 break;
166 }
167 case ASM_CLIENT_EVENT_DATA_READ_DONE:
168 prtd->pcm_irq_pos += prtd->pcm_count;
169 snd_pcm_period_elapsed(substream);
170 if (prtd->state == Q6ASM_STREAM_RUNNING)
171 q6asm_read(prtd->audio_client);
172
173 break;
174 default:
175 break;
176 }
177}
178
179static int q6asm_dai_prepare(struct snd_pcm_substream *substream)
180{
181 struct snd_pcm_runtime *runtime = substream->runtime;
182 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
183 struct q6asm_dai_rtd *prtd = runtime->private_data;
184 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
185 struct q6asm_dai_data *pdata;
186 int ret, i;
187
188 pdata = snd_soc_component_get_drvdata(c);
189 if (!pdata)
190 return -EINVAL;
191
192 if (!prtd || !prtd->audio_client) {
193 pr_err("%s: private data null or audio client freed\n",
194 __func__);
195 return -EINVAL;
196 }
197
198 prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
199 prtd->pcm_irq_pos = 0;
200 /* rate and channels are sent to audio driver */
201 if (prtd->state) {
202 /* clear the previous setup if any */
203 q6asm_cmd(prtd->audio_client, CMD_CLOSE);
204 q6asm_unmap_memory_regions(substream->stream,
205 prtd->audio_client);
206 q6routing_stream_close(soc_prtd->dai_link->id,
207 substream->stream);
208 }
209
210 ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client,
211 prtd->phys,
212 (prtd->pcm_size / prtd->periods),
213 prtd->periods);
214
215 if (ret < 0) {
216 pr_err("Audio Start: Buffer Allocation failed rc = %d\n",
217 ret);
218 return -ENOMEM;
219 }
220
221 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
222 ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM,
223 prtd->bits_per_sample);
224 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
225 ret = q6asm_open_read(prtd->audio_client, FORMAT_LINEAR_PCM,
226 prtd->bits_per_sample);
227 }
228
229 if (ret < 0) {
230 pr_err("%s: q6asm_open_write failed\n", __func__);
231 q6asm_audio_client_free(prtd->audio_client);
232 prtd->audio_client = NULL;
233 return -ENOMEM;
234 }
235
236 prtd->session_id = q6asm_get_session_id(prtd->audio_client);
237 ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE,
238 prtd->session_id, substream->stream);
239 if (ret) {
240 pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
241 return ret;
242 }
243
244 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
245 ret = q6asm_media_format_block_multi_ch_pcm(
246 prtd->audio_client, runtime->rate,
247 runtime->channels, NULL,
248 prtd->bits_per_sample);
249 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
250 ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client,
251 runtime->rate, runtime->channels,
252 prtd->bits_per_sample);
253
254 /* Queue the buffers */
255 for (i = 0; i < runtime->periods; i++)
256 q6asm_read(prtd->audio_client);
257
258 }
259 if (ret < 0)
260 pr_info("%s: CMD Format block failed\n", __func__);
261
262 prtd->state = Q6ASM_STREAM_RUNNING;
263
264 return 0;
265}
266
267static int q6asm_dai_trigger(struct snd_pcm_substream *substream, int cmd)
268{
269 int ret = 0;
270 struct snd_pcm_runtime *runtime = substream->runtime;
271 struct q6asm_dai_rtd *prtd = runtime->private_data;
272
273 switch (cmd) {
274 case SNDRV_PCM_TRIGGER_START:
275 case SNDRV_PCM_TRIGGER_RESUME:
276 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
277 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
278 break;
279 case SNDRV_PCM_TRIGGER_STOP:
280 prtd->state = Q6ASM_STREAM_STOPPED;
281 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
282 break;
283 case SNDRV_PCM_TRIGGER_SUSPEND:
284 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
286 break;
287 default:
288 ret = -EINVAL;
289 break;
290 }
291
292 return ret;
293}
294
295static int q6asm_dai_open(struct snd_pcm_substream *substream)
296{
297 struct snd_pcm_runtime *runtime = substream->runtime;
298 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
299 struct snd_soc_dai *cpu_dai = soc_prtd->cpu_dai;
300 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
301 struct q6asm_dai_rtd *prtd;
302 struct q6asm_dai_data *pdata;
303 struct device *dev = c->dev;
304 int ret = 0;
305 int stream_id;
306
307 stream_id = cpu_dai->driver->id;
308
309 pdata = snd_soc_component_get_drvdata(c);
310 if (!pdata) {
311 pr_err("Drv data not found ..\n");
312 return -EINVAL;
313 }
314
315 prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL);
316 if (prtd == NULL)
317 return -ENOMEM;
318
319 prtd->substream = substream;
320 prtd->audio_client = q6asm_audio_client_alloc(dev,
321 (q6asm_cb)event_handler, prtd, stream_id,
322 LEGACY_PCM_MODE);
323 if (!prtd->audio_client) {
324 pr_info("%s: Could not allocate memory\n", __func__);
325 kfree(prtd);
326 return -ENOMEM;
327 }
328
329 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
330 runtime->hw = q6asm_dai_hardware_playback;
331 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
332 runtime->hw = q6asm_dai_hardware_capture;
333
334 ret = snd_pcm_hw_constraint_list(runtime, 0,
335 SNDRV_PCM_HW_PARAM_RATE,
336 &constraints_sample_rates);
337 if (ret < 0)
338 pr_info("snd_pcm_hw_constraint_list failed\n");
339 /* Ensure that buffer size is a multiple of period size */
340 ret = snd_pcm_hw_constraint_integer(runtime,
341 SNDRV_PCM_HW_PARAM_PERIODS);
342 if (ret < 0)
343 pr_info("snd_pcm_hw_constraint_integer failed\n");
344
345 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
346 ret = snd_pcm_hw_constraint_minmax(runtime,
347 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
348 PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE,
349 PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE);
350 if (ret < 0) {
351 pr_err("constraint for buffer bytes min max ret = %d\n",
352 ret);
353 }
354 }
355
356 ret = snd_pcm_hw_constraint_step(runtime, 0,
357 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
358 if (ret < 0) {
359 pr_err("constraint for period bytes step ret = %d\n",
360 ret);
361 }
362 ret = snd_pcm_hw_constraint_step(runtime, 0,
363 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
364 if (ret < 0) {
365 pr_err("constraint for buffer bytes step ret = %d\n",
366 ret);
367 }
368
369 runtime->private_data = prtd;
370
371 snd_soc_set_runtime_hwparams(substream, &q6asm_dai_hardware_playback);
372
373 runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max;
374
375
376 if (pdata->sid < 0)
377 prtd->phys = substream->dma_buffer.addr;
378 else
379 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32);
380
381 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
382
383 return 0;
384}
385
386static int q6asm_dai_close(struct snd_pcm_substream *substream)
387{
388 struct snd_pcm_runtime *runtime = substream->runtime;
389 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
390 struct q6asm_dai_rtd *prtd = runtime->private_data;
391
392 if (prtd->audio_client) {
393 q6asm_cmd(prtd->audio_client, CMD_CLOSE);
394 q6asm_unmap_memory_regions(substream->stream,
395 prtd->audio_client);
396 q6asm_audio_client_free(prtd->audio_client);
397 prtd->audio_client = NULL;
398 }
399 q6routing_stream_close(soc_prtd->dai_link->id,
400 substream->stream);
401 kfree(prtd);
402 return 0;
403}
404
405static snd_pcm_uframes_t q6asm_dai_pointer(struct snd_pcm_substream *substream)
406{
407
408 struct snd_pcm_runtime *runtime = substream->runtime;
409 struct q6asm_dai_rtd *prtd = runtime->private_data;
410
411 if (prtd->pcm_irq_pos >= prtd->pcm_size)
412 prtd->pcm_irq_pos = 0;
413
414 return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
415}
416
417static int q6asm_dai_mmap(struct snd_pcm_substream *substream,
418 struct vm_area_struct *vma)
419{
420
421 struct snd_pcm_runtime *runtime = substream->runtime;
422 struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
423 struct snd_soc_component *c = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
424 struct device *dev = c->dev;
425
426 return dma_mmap_coherent(dev, vma,
427 runtime->dma_area, runtime->dma_addr,
428 runtime->dma_bytes);
429}
430
431static int q6asm_dai_hw_params(struct snd_pcm_substream *substream,
432 struct snd_pcm_hw_params *params)
433{
434 struct snd_pcm_runtime *runtime = substream->runtime;
435 struct q6asm_dai_rtd *prtd = runtime->private_data;
436
437 prtd->pcm_size = params_buffer_bytes(params);
438 prtd->periods = params_periods(params);
439
440 switch (params_format(params)) {
441 case SNDRV_PCM_FORMAT_S16_LE:
442 prtd->bits_per_sample = 16;
443 break;
444 case SNDRV_PCM_FORMAT_S24_LE:
445 prtd->bits_per_sample = 24;
446 break;
447 }
448
449 return 0;
450}
451
452static struct snd_pcm_ops q6asm_dai_ops = {
453 .open = q6asm_dai_open,
454 .hw_params = q6asm_dai_hw_params,
455 .close = q6asm_dai_close,
456 .ioctl = snd_pcm_lib_ioctl,
457 .prepare = q6asm_dai_prepare,
458 .trigger = q6asm_dai_trigger,
459 .pointer = q6asm_dai_pointer,
460 .mmap = q6asm_dai_mmap,
461};
462
463static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd)
464{
465 struct snd_pcm_substream *psubstream, *csubstream;
466 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
467 struct snd_pcm *pcm = rtd->pcm;
468 struct device *dev;
469 int size, ret;
470
471 dev = c->dev;
472 size = q6asm_dai_hardware_playback.buffer_bytes_max;
473 psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
474 if (psubstream) {
475 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size,
476 &psubstream->dma_buffer);
477 if (ret) {
478 dev_err(dev, "Cannot allocate buffer(s)\n");
479 return ret;
480 }
481 }
482
483 csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
484 if (csubstream) {
485 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size,
486 &csubstream->dma_buffer);
487 if (ret) {
488 dev_err(dev, "Cannot allocate buffer(s)\n");
489 if (psubstream)
490 snd_dma_free_pages(&psubstream->dma_buffer);
491 return ret;
492 }
493 }
494
495 return ret;
496}
497
498static void q6asm_dai_pcm_free(struct snd_pcm *pcm)
499{
500 struct snd_pcm_substream *substream;
501 int i;
502
503 for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
504 substream = pcm->streams[i].substream;
505 if (substream) {
506 snd_dma_free_pages(&substream->dma_buffer);
507 substream->dma_buffer.area = NULL;
508 substream->dma_buffer.addr = 0;
509 }
510 }
511}
512
513static const struct snd_soc_dapm_route afe_pcm_routes[] = {
514 {"MM_DL1", NULL, "MultiMedia1 Playback" },
515 {"MM_DL2", NULL, "MultiMedia2 Playback" },
516 {"MM_DL3", NULL, "MultiMedia3 Playback" },
517 {"MM_DL4", NULL, "MultiMedia4 Playback" },
518 {"MM_DL5", NULL, "MultiMedia5 Playback" },
519 {"MM_DL6", NULL, "MultiMedia6 Playback" },
520 {"MM_DL7", NULL, "MultiMedia7 Playback" },
521 {"MM_DL7", NULL, "MultiMedia8 Playback" },
522 {"MultiMedia1 Capture", NULL, "MM_UL1"},
523 {"MultiMedia2 Capture", NULL, "MM_UL2"},
524 {"MultiMedia3 Capture", NULL, "MM_UL3"},
525 {"MultiMedia4 Capture", NULL, "MM_UL4"},
526 {"MultiMedia5 Capture", NULL, "MM_UL5"},
527 {"MultiMedia6 Capture", NULL, "MM_UL6"},
528 {"MultiMedia7 Capture", NULL, "MM_UL7"},
529 {"MultiMedia8 Capture", NULL, "MM_UL8"},
530
531};
532
533static int fe_dai_probe(struct snd_soc_dai *dai)
534{
535 struct snd_soc_dapm_context *dapm;
536
537 dapm = snd_soc_component_get_dapm(dai->component);
538 snd_soc_dapm_add_routes(dapm, afe_pcm_routes,
539 ARRAY_SIZE(afe_pcm_routes));
540
541 return 0;
542}
543
544
545static const struct snd_soc_component_driver q6asm_fe_dai_component = {
546 .name = DRV_NAME,
547 .ops = &q6asm_dai_ops,
548 .pcm_new = q6asm_dai_pcm_new,
549 .pcm_free = q6asm_dai_pcm_free,
550
551};
552
553static struct snd_soc_dai_driver q6asm_fe_dais[] = {
554 Q6ASM_FEDAI_DRIVER(1),
555 Q6ASM_FEDAI_DRIVER(2),
556 Q6ASM_FEDAI_DRIVER(3),
557 Q6ASM_FEDAI_DRIVER(4),
558 Q6ASM_FEDAI_DRIVER(5),
559 Q6ASM_FEDAI_DRIVER(6),
560 Q6ASM_FEDAI_DRIVER(7),
561 Q6ASM_FEDAI_DRIVER(8),
562};
563
564static int q6asm_dai_bind(struct device *dev, struct device *master, void *data)
565{
566 struct device_node *node = dev->of_node;
567 struct of_phandle_args args;
568 struct q6asm_dai_data *pdata;
569 int rc;
570
571 pdata = kzalloc(sizeof(struct q6asm_dai_data), GFP_KERNEL);
572 if (!pdata)
573 return -ENOMEM;
574
575 rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args);
576 if (rc < 0)
577 pdata->sid = -1;
578 else
579 pdata->sid = args.args[0] & SID_MASK_DEFAULT;
580
581 dev_set_drvdata(dev, pdata);
582
583 return snd_soc_register_component(dev, &q6asm_fe_dai_component,
584 q6asm_fe_dais,
585 ARRAY_SIZE(q6asm_fe_dais));
586}
587static void q6asm_dai_unbind(struct device *dev, struct device *master,
588 void *data)
589{
590 struct q6asm_dai_data *pdata = dev_get_drvdata(dev);
591
592 snd_soc_unregister_component(dev);
593
594 kfree(pdata);
595
596}
597
598static const struct component_ops q6asm_dai_comp_ops = {
599 .bind = q6asm_dai_bind,
600 .unbind = q6asm_dai_unbind,
601};
602
603static int q6asm_dai_probe(struct platform_device *pdev)
604{
605 return component_add(&pdev->dev, &q6asm_dai_comp_ops);
606}
607
608static int q6asm_dai_dev_remove(struct platform_device *pdev)
609{
610 component_del(&pdev->dev, &q6asm_dai_comp_ops);
611 return 0;
612}
613
614static struct platform_driver q6asm_dai_platform_driver = {
615 .driver = {
616 .name = "q6asm-dai",
617 },
618 .probe = q6asm_dai_probe,
619 .remove = q6asm_dai_dev_remove,
620};
621module_platform_driver(q6asm_dai_platform_driver);
622
623MODULE_DESCRIPTION("Q6ASM dai driver");
624MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
new file mode 100644
index 000000000000..530852385cad
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -0,0 +1,1399 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/mutex.h>
6#include <linux/wait.h>
7#include <linux/module.h>
8#include <linux/soc/qcom/apr.h>
9#include <linux/device.h>
10#include <linux/of_platform.h>
11#include <linux/spinlock.h>
12#include <linux/kref.h>
13#include <linux/of.h>
14#include <linux/of_platform.h>
15#include <uapi/sound/asound.h>
16#include <linux/delay.h>
17#include <linux/slab.h>
18#include <linux/mm.h>
19#include "q6asm.h"
20#include "q6core.h"
21#include "q6dsp-errno.h"
22#include "q6dsp-common.h"
23
24#define ASM_STREAM_CMD_CLOSE 0x00010BCD
25#define ASM_STREAM_CMD_FLUSH 0x00010BCE
26#define ASM_SESSION_CMD_PAUSE 0x00010BD3
27#define ASM_DATA_CMD_EOS 0x00010BDB
28#define ASM_NULL_POPP_TOPOLOGY 0x00010C68
29#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09
30#define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10
31#define ASM_STREAM_POSTPROC_TOPO_ID_NONE 0x00010C68
32#define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92
33#define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010D93
34#define ASM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010D94
35#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2 0x00010D98
36#define ASM_DATA_EVENT_WRITE_DONE_V2 0x00010D99
37#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3
38#define ASM_SESSION_CMD_RUN_V2 0x00010DAA
39#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5
40#define ASM_DATA_CMD_WRITE_V2 0x00010DAB
41#define ASM_DATA_CMD_READ_V2 0x00010DAC
42#define ASM_SESSION_CMD_SUSPEND 0x00010DEC
43#define ASM_STREAM_CMD_OPEN_WRITE_V3 0x00010DB3
44#define ASM_STREAM_CMD_OPEN_READ_V3 0x00010DB4
45#define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A
46#define ASM_STREAM_CMD_OPEN_READWRITE_V2 0x00010D8D
47
48
49#define ASM_LEGACY_STREAM_SESSION 0
50/* Bit shift for the stream_perf_mode subfield. */
51#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ 29
52#define ASM_END_POINT_DEVICE_MATRIX 0
53#define ASM_DEFAULT_APP_TYPE 0
54#define ASM_SYNC_IO_MODE 0x0001
55#define ASM_ASYNC_IO_MODE 0x0002
56#define ASM_TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */
57#define ASM_TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */
58#define ASM_SHIFT_GAPLESS_MODE_FLAG 31
59#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3
60
61struct avs_cmd_shared_mem_map_regions {
62 u16 mem_pool_id;
63 u16 num_regions;
64 u32 property_flag;
65} __packed;
66
67struct avs_shared_map_region_payload {
68 u32 shm_addr_lsw;
69 u32 shm_addr_msw;
70 u32 mem_size_bytes;
71} __packed;
72
73struct avs_cmd_shared_mem_unmap_regions {
74 u32 mem_map_handle;
75} __packed;
76
77struct asm_data_cmd_media_fmt_update_v2 {
78 u32 fmt_blk_size;
79} __packed;
80
81struct asm_multi_channel_pcm_fmt_blk_v2 {
82 struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
83 u16 num_channels;
84 u16 bits_per_sample;
85 u32 sample_rate;
86 u16 is_signed;
87 u16 reserved;
88 u8 channel_mapping[PCM_MAX_NUM_CHANNEL];
89} __packed;
90
91struct asm_stream_cmd_set_encdec_param {
92 u32 param_id;
93 u32 param_size;
94} __packed;
95
96struct asm_enc_cfg_blk_param_v2 {
97 u32 frames_per_buf;
98 u32 enc_cfg_blk_size;
99} __packed;
100
101struct asm_multi_channel_pcm_enc_cfg_v2 {
102 struct asm_stream_cmd_set_encdec_param encdec;
103 struct asm_enc_cfg_blk_param_v2 encblk;
104 uint16_t num_channels;
105 uint16_t bits_per_sample;
106 uint32_t sample_rate;
107 uint16_t is_signed;
108 uint16_t reserved;
109 uint8_t channel_mapping[8];
110} __packed;
111
112struct asm_data_cmd_read_v2 {
113 u32 buf_addr_lsw;
114 u32 buf_addr_msw;
115 u32 mem_map_handle;
116 u32 buf_size;
117 u32 seq_id;
118} __packed;
119
120struct asm_data_cmd_read_v2_done {
121 u32 status;
122 u32 buf_addr_lsw;
123 u32 buf_addr_msw;
124};
125
126struct asm_stream_cmd_open_read_v3 {
127 u32 mode_flags;
128 u32 src_endpointype;
129 u32 preprocopo_id;
130 u32 enc_cfg_id;
131 u16 bits_per_sample;
132 u16 reserved;
133} __packed;
134
135struct asm_data_cmd_write_v2 {
136 u32 buf_addr_lsw;
137 u32 buf_addr_msw;
138 u32 mem_map_handle;
139 u32 buf_size;
140 u32 seq_id;
141 u32 timestamp_lsw;
142 u32 timestamp_msw;
143 u32 flags;
144} __packed;
145
146struct asm_stream_cmd_open_write_v3 {
147 uint32_t mode_flags;
148 uint16_t sink_endpointype;
149 uint16_t bits_per_sample;
150 uint32_t postprocopo_id;
151 uint32_t dec_fmt_id;
152} __packed;
153
154struct asm_session_cmd_run_v2 {
155 u32 flags;
156 u32 time_lsw;
157 u32 time_msw;
158} __packed;
159
160struct audio_buffer {
161 phys_addr_t phys;
162 uint32_t size; /* size of buffer */
163};
164
165struct audio_port_data {
166 struct audio_buffer *buf;
167 uint32_t num_periods;
168 uint32_t dsp_buf;
169 uint32_t mem_map_handle;
170};
171
172struct q6asm {
173 struct apr_device *adev;
174 struct device *dev;
175 struct q6core_svc_api_info ainfo;
176 wait_queue_head_t mem_wait;
177 struct platform_device *pcmdev;
178 spinlock_t slock;
179 struct audio_client *session[MAX_SESSIONS + 1];
180 struct platform_device *pdev_dais;
181};
182
183struct audio_client {
184 int session;
185 q6asm_cb cb;
186 void *priv;
187 uint32_t io_mode;
188 struct apr_device *adev;
189 struct mutex cmd_lock;
190 spinlock_t lock;
191 struct kref refcount;
192 /* idx:1 out port, 0: in port */
193 struct audio_port_data port[2];
194 wait_queue_head_t cmd_wait;
195 struct aprv2_ibasic_rsp_result_t result;
196 int perf_mode;
197 int stream_id;
198 struct q6asm *q6asm;
199 struct device *dev;
200};
201
202static inline void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
203 uint32_t pkt_size, bool cmd_flg,
204 uint32_t stream_id)
205{
206 hdr->hdr_field = APR_SEQ_CMD_HDR_FIELD;
207 hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id);
208 hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id);
209 hdr->pkt_size = pkt_size;
210 if (cmd_flg)
211 hdr->token = ac->session;
212}
213
214static int q6asm_apr_send_session_pkt(struct q6asm *a, struct audio_client *ac,
215 struct apr_pkt *pkt, uint32_t rsp_opcode)
216{
217 struct apr_hdr *hdr = &pkt->hdr;
218 int rc;
219
220 mutex_lock(&ac->cmd_lock);
221 ac->result.opcode = 0;
222 ac->result.status = 0;
223 rc = apr_send_pkt(a->adev, pkt);
224 if (rc < 0)
225 goto err;
226
227 if (rsp_opcode)
228 rc = wait_event_timeout(a->mem_wait,
229 (ac->result.opcode == hdr->opcode) ||
230 (ac->result.opcode == rsp_opcode),
231 5 * HZ);
232 else
233 rc = wait_event_timeout(a->mem_wait,
234 (ac->result.opcode == hdr->opcode),
235 5 * HZ);
236
237 if (!rc) {
238 dev_err(a->dev, "CMD timeout\n");
239 rc = -ETIMEDOUT;
240 } else if (ac->result.status > 0) {
241 dev_err(a->dev, "DSP returned error[%x]\n",
242 ac->result.status);
243 rc = -EINVAL;
244 }
245
246err:
247 mutex_unlock(&ac->cmd_lock);
248 return rc;
249}
250
251static int __q6asm_memory_unmap(struct audio_client *ac,
252 phys_addr_t buf_add, int dir)
253{
254 struct avs_cmd_shared_mem_unmap_regions *mem_unmap;
255 struct q6asm *a = dev_get_drvdata(ac->dev->parent);
256 struct apr_pkt *pkt;
257 int rc, pkt_size;
258 void *p;
259
260 if (ac->port[dir].mem_map_handle == 0) {
261 dev_err(ac->dev, "invalid mem handle\n");
262 return -EINVAL;
263 }
264
265 pkt_size = APR_HDR_SIZE + sizeof(*mem_unmap);
266 p = kzalloc(pkt_size, GFP_KERNEL);
267 if (!p)
268 return -ENOMEM;
269
270 pkt = p;
271 mem_unmap = p + APR_HDR_SIZE;
272
273 pkt->hdr.hdr_field = APR_SEQ_CMD_HDR_FIELD;
274 pkt->hdr.src_port = 0;
275 pkt->hdr.dest_port = 0;
276 pkt->hdr.pkt_size = pkt_size;
277 pkt->hdr.token = ((ac->session << 8) | dir);
278
279 pkt->hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS;
280 mem_unmap->mem_map_handle = ac->port[dir].mem_map_handle;
281
282 rc = q6asm_apr_send_session_pkt(a, ac, pkt, 0);
283 if (rc < 0) {
284 kfree(pkt);
285 return rc;
286 }
287
288 ac->port[dir].mem_map_handle = 0;
289
290 kfree(pkt);
291 return 0;
292}
293
294
295static void q6asm_audio_client_free_buf(struct audio_client *ac,
296 struct audio_port_data *port)
297{
298 unsigned long flags;
299
300 spin_lock_irqsave(&ac->lock, flags);
301 port->num_periods = 0;
302 kfree(port->buf);
303 port->buf = NULL;
304 spin_unlock_irqrestore(&ac->lock, flags);
305}
306
307/**
308 * q6asm_unmap_memory_regions() - unmap memory regions in the dsp.
309 *
310 * @dir: direction of audio stream
311 * @ac: audio client instanace
312 *
313 * Return: Will be an negative value on failure or zero on success
314 */
315int q6asm_unmap_memory_regions(unsigned int dir, struct audio_client *ac)
316{
317 struct audio_port_data *port;
318 int cnt = 0;
319 int rc = 0;
320
321 port = &ac->port[dir];
322 if (!port->buf) {
323 rc = -EINVAL;
324 goto err;
325 }
326
327 cnt = port->num_periods - 1;
328 if (cnt >= 0) {
329 rc = __q6asm_memory_unmap(ac, port->buf[dir].phys, dir);
330 if (rc < 0) {
331 dev_err(ac->dev, "%s: Memory_unmap_regions failed %d\n",
332 __func__, rc);
333 goto err;
334 }
335 }
336
337 q6asm_audio_client_free_buf(ac, port);
338
339err:
340 return rc;
341}
342EXPORT_SYMBOL_GPL(q6asm_unmap_memory_regions);
343
344static int __q6asm_memory_map_regions(struct audio_client *ac, int dir,
345 size_t period_sz, unsigned int periods,
346 bool is_contiguous)
347{
348 struct avs_cmd_shared_mem_map_regions *cmd = NULL;
349 struct avs_shared_map_region_payload *mregions = NULL;
350 struct q6asm *a = dev_get_drvdata(ac->dev->parent);
351 struct audio_port_data *port = NULL;
352 struct audio_buffer *ab = NULL;
353 struct apr_pkt *pkt;
354 void *p;
355 unsigned long flags;
356 uint32_t num_regions, buf_sz;
357 int rc, i, pkt_size;
358
359 if (is_contiguous) {
360 num_regions = 1;
361 buf_sz = period_sz * periods;
362 } else {
363 buf_sz = period_sz;
364 num_regions = periods;
365 }
366
367 /* DSP expects size should be aligned to 4K */
368 buf_sz = ALIGN(buf_sz, 4096);
369
370 pkt_size = APR_HDR_SIZE + sizeof(*cmd) +
371 (sizeof(*mregions) * num_regions);
372
373 p = kzalloc(pkt_size, GFP_KERNEL);
374 if (!p)
375 return -ENOMEM;
376
377 pkt = p;
378 cmd = p + APR_HDR_SIZE;
379 mregions = p + APR_HDR_SIZE + sizeof(*cmd);
380
381 pkt->hdr.hdr_field = APR_SEQ_CMD_HDR_FIELD;
382 pkt->hdr.src_port = 0;
383 pkt->hdr.dest_port = 0;
384 pkt->hdr.pkt_size = pkt_size;
385 pkt->hdr.token = ((ac->session << 8) | dir);
386 pkt->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS;
387
388 cmd->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
389 cmd->num_regions = num_regions;
390 cmd->property_flag = 0x00;
391
392 spin_lock_irqsave(&ac->lock, flags);
393 port = &ac->port[dir];
394
395 for (i = 0; i < num_regions; i++) {
396 ab = &port->buf[i];
397 mregions->shm_addr_lsw = lower_32_bits(ab->phys);
398 mregions->shm_addr_msw = upper_32_bits(ab->phys);
399 mregions->mem_size_bytes = buf_sz;
400 ++mregions;
401 }
402 spin_unlock_irqrestore(&ac->lock, flags);
403
404 rc = q6asm_apr_send_session_pkt(a, ac, pkt,
405 ASM_CMDRSP_SHARED_MEM_MAP_REGIONS);
406
407 kfree(pkt);
408
409 return rc;
410}
411
412/**
413 * q6asm_map_memory_regions() - map memory regions in the dsp.
414 *
415 * @dir: direction of audio stream
416 * @ac: audio client instanace
417 * @phys: physcial address that needs mapping.
418 * @period_sz: audio period size
419 * @periods: number of periods
420 *
421 * Return: Will be an negative value on failure or zero on success
422 */
423int q6asm_map_memory_regions(unsigned int dir, struct audio_client *ac,
424 phys_addr_t phys,
425 size_t period_sz, unsigned int periods)
426{
427 struct audio_buffer *buf;
428 unsigned long flags;
429 int cnt;
430 int rc;
431
432 spin_lock_irqsave(&ac->lock, flags);
433 if (ac->port[dir].buf) {
434 dev_err(ac->dev, "Buffer already allocated\n");
435 spin_unlock_irqrestore(&ac->lock, flags);
436 return 0;
437 }
438
439 buf = kzalloc(((sizeof(struct audio_buffer)) * periods), GFP_ATOMIC);
440 if (!buf) {
441 spin_unlock_irqrestore(&ac->lock, flags);
442 return -ENOMEM;
443 }
444
445
446 ac->port[dir].buf = buf;
447
448 buf[0].phys = phys;
449 buf[0].size = period_sz;
450
451 for (cnt = 1; cnt < periods; cnt++) {
452 if (period_sz > 0) {
453 buf[cnt].phys = buf[0].phys + (cnt * period_sz);
454 buf[cnt].size = period_sz;
455 }
456 }
457 ac->port[dir].num_periods = periods;
458
459 spin_unlock_irqrestore(&ac->lock, flags);
460
461 rc = __q6asm_memory_map_regions(ac, dir, period_sz, periods, 1);
462 if (rc < 0) {
463 dev_err(ac->dev, "Memory_map_regions failed\n");
464 q6asm_audio_client_free_buf(ac, &ac->port[dir]);
465 }
466
467 return rc;
468}
469EXPORT_SYMBOL_GPL(q6asm_map_memory_regions);
470
471static void q6asm_audio_client_release(struct kref *ref)
472{
473 struct audio_client *ac;
474 struct q6asm *a;
475 unsigned long flags;
476
477 ac = container_of(ref, struct audio_client, refcount);
478 a = ac->q6asm;
479
480 spin_lock_irqsave(&a->slock, flags);
481 a->session[ac->session] = NULL;
482 spin_unlock_irqrestore(&a->slock, flags);
483
484 kfree(ac);
485}
486
487/**
488 * q6asm_audio_client_free() - Freee allocated audio client
489 *
490 * @ac: audio client to free
491 */
492void q6asm_audio_client_free(struct audio_client *ac)
493{
494 kref_put(&ac->refcount, q6asm_audio_client_release);
495}
496EXPORT_SYMBOL_GPL(q6asm_audio_client_free);
497
498static struct audio_client *q6asm_get_audio_client(struct q6asm *a,
499 int session_id)
500{
501 struct audio_client *ac = NULL;
502 unsigned long flags;
503
504 spin_lock_irqsave(&a->slock, flags);
505 if ((session_id <= 0) || (session_id > MAX_SESSIONS)) {
506 dev_err(a->dev, "invalid session: %d\n", session_id);
507 goto err;
508 }
509
510 /* check for valid session */
511 if (!a->session[session_id])
512 goto err;
513 else if (a->session[session_id]->session != session_id)
514 goto err;
515
516 ac = a->session[session_id];
517 kref_get(&ac->refcount);
518err:
519 spin_unlock_irqrestore(&a->slock, flags);
520 return ac;
521}
522
523static int32_t q6asm_stream_callback(struct apr_device *adev,
524 struct apr_resp_pkt *data,
525 int session_id)
526{
527 struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
528 struct aprv2_ibasic_rsp_result_t *result;
529 struct apr_hdr *hdr = &data->hdr;
530 struct audio_port_data *port;
531 struct audio_client *ac;
532 uint32_t client_event = 0;
533 int ret = 0;
534
535 ac = q6asm_get_audio_client(q6asm, session_id);
536 if (!ac)/* Audio client might already be freed by now */
537 return 0;
538
539 result = data->payload;
540
541 switch (hdr->opcode) {
542 case APR_BASIC_RSP_RESULT:
543 switch (result->opcode) {
544 case ASM_SESSION_CMD_PAUSE:
545 client_event = ASM_CLIENT_EVENT_CMD_PAUSE_DONE;
546 break;
547 case ASM_SESSION_CMD_SUSPEND:
548 client_event = ASM_CLIENT_EVENT_CMD_SUSPEND_DONE;
549 break;
550 case ASM_DATA_CMD_EOS:
551 client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE;
552 break;
553 case ASM_STREAM_CMD_FLUSH:
554 client_event = ASM_CLIENT_EVENT_CMD_FLUSH_DONE;
555 break;
556 case ASM_SESSION_CMD_RUN_V2:
557 client_event = ASM_CLIENT_EVENT_CMD_RUN_DONE;
558 break;
559 case ASM_STREAM_CMD_CLOSE:
560 client_event = ASM_CLIENT_EVENT_CMD_CLOSE_DONE;
561 break;
562 case ASM_STREAM_CMD_FLUSH_READBUFS:
563 client_event = ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE;
564 break;
565 case ASM_STREAM_CMD_OPEN_WRITE_V3:
566 case ASM_STREAM_CMD_OPEN_READ_V3:
567 case ASM_STREAM_CMD_OPEN_READWRITE_V2:
568 case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
569 case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
570 if (result->status != 0) {
571 dev_err(ac->dev,
572 "cmd = 0x%x returned error = 0x%x\n",
573 result->opcode, result->status);
574 ac->result = *result;
575 wake_up(&ac->cmd_wait);
576 ret = 0;
577 goto done;
578 }
579 break;
580 default:
581 dev_err(ac->dev, "command[0x%x] not expecting rsp\n",
582 result->opcode);
583 break;
584 }
585
586 ac->result = *result;
587 wake_up(&ac->cmd_wait);
588
589 if (ac->cb)
590 ac->cb(client_event, hdr->token,
591 data->payload, ac->priv);
592
593 ret = 0;
594 goto done;
595
596 case ASM_DATA_EVENT_WRITE_DONE_V2:
597 client_event = ASM_CLIENT_EVENT_DATA_WRITE_DONE;
598 if (ac->io_mode & ASM_SYNC_IO_MODE) {
599 phys_addr_t phys;
600 unsigned long flags;
601
602 spin_lock_irqsave(&ac->lock, flags);
603
604 port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
605
606 if (!port->buf) {
607 spin_unlock_irqrestore(&ac->lock, flags);
608 ret = 0;
609 goto done;
610 }
611
612 phys = port->buf[hdr->token].phys;
613
614 if (lower_32_bits(phys) != result->opcode ||
615 upper_32_bits(phys) != result->status) {
616 dev_err(ac->dev, "Expected addr %pa\n",
617 &port->buf[hdr->token].phys);
618 spin_unlock_irqrestore(&ac->lock, flags);
619 ret = -EINVAL;
620 goto done;
621 }
622 spin_unlock_irqrestore(&ac->lock, flags);
623 }
624 break;
625 case ASM_DATA_EVENT_READ_DONE_V2:
626 client_event = ASM_CLIENT_EVENT_DATA_READ_DONE;
627 if (ac->io_mode & ASM_SYNC_IO_MODE) {
628 struct asm_data_cmd_read_v2_done *done = data->payload;
629 unsigned long flags;
630 phys_addr_t phys;
631
632 spin_lock_irqsave(&ac->lock, flags);
633 port = &ac->port[SNDRV_PCM_STREAM_CAPTURE];
634 if (!port->buf) {
635 spin_unlock_irqrestore(&ac->lock, flags);
636 ret = 0;
637 goto done;
638 }
639
640 phys = port->buf[hdr->token].phys;
641
642 if (upper_32_bits(phys) != done->buf_addr_msw ||
643 lower_32_bits(phys) != done->buf_addr_lsw) {
644 dev_err(ac->dev, "Expected addr %pa %08x-%08x\n",
645 &port->buf[hdr->token].phys,
646 done->buf_addr_lsw,
647 done->buf_addr_msw);
648 spin_unlock_irqrestore(&ac->lock, flags);
649 ret = -EINVAL;
650 goto done;
651 }
652 spin_unlock_irqrestore(&ac->lock, flags);
653 }
654
655 break;
656 }
657
658 if (ac->cb)
659 ac->cb(client_event, hdr->token, data->payload, ac->priv);
660
661done:
662 kref_put(&ac->refcount, q6asm_audio_client_release);
663 return ret;
664}
665
666static int q6asm_srvc_callback(struct apr_device *adev,
667 struct apr_resp_pkt *data)
668{
669 struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
670 struct aprv2_ibasic_rsp_result_t *result;
671 struct audio_port_data *port;
672 struct audio_client *ac = NULL;
673 struct apr_hdr *hdr = &data->hdr;
674 struct q6asm *a;
675 uint32_t sid = 0;
676 uint32_t dir = 0;
677 int session_id;
678
679 session_id = (hdr->dest_port >> 8) & 0xFF;
680 if (session_id)
681 return q6asm_stream_callback(adev, data, session_id);
682
683 sid = (hdr->token >> 8) & 0x0F;
684 ac = q6asm_get_audio_client(q6asm, sid);
685 if (!ac) {
686 dev_err(&adev->dev, "Audio Client not active\n");
687 return 0;
688 }
689
690 a = dev_get_drvdata(ac->dev->parent);
691 dir = (hdr->token & 0x0F);
692 port = &ac->port[dir];
693 result = data->payload;
694
695 switch (hdr->opcode) {
696 case APR_BASIC_RSP_RESULT:
697 switch (result->opcode) {
698 case ASM_CMD_SHARED_MEM_MAP_REGIONS:
699 case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
700 ac->result = *result;
701 wake_up(&a->mem_wait);
702 break;
703 default:
704 dev_err(&adev->dev, "command[0x%x] not expecting rsp\n",
705 result->opcode);
706 break;
707 }
708 goto done;
709 case ASM_CMDRSP_SHARED_MEM_MAP_REGIONS:
710 ac->result.status = 0;
711 ac->result.opcode = hdr->opcode;
712 port->mem_map_handle = result->opcode;
713 wake_up(&a->mem_wait);
714 break;
715 case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
716 ac->result.opcode = hdr->opcode;
717 ac->result.status = 0;
718 port->mem_map_handle = 0;
719 wake_up(&a->mem_wait);
720 break;
721 default:
722 dev_dbg(&adev->dev, "command[0x%x]success [0x%x]\n",
723 result->opcode, result->status);
724 break;
725 }
726
727 if (ac->cb)
728 ac->cb(hdr->opcode, hdr->token, data->payload, ac->priv);
729
730done:
731 kref_put(&ac->refcount, q6asm_audio_client_release);
732
733 return 0;
734}
735
736/**
737 * q6asm_get_session_id() - get session id for audio client
738 *
739 * @c: audio client pointer
740 *
741 * Return: Will be an session id of the audio client.
742 */
743int q6asm_get_session_id(struct audio_client *c)
744{
745 return c->session;
746}
747EXPORT_SYMBOL_GPL(q6asm_get_session_id);
748
749/**
750 * q6asm_audio_client_alloc() - Allocate a new audio client
751 *
752 * @dev: Pointer to asm child device.
753 * @cb: event callback.
754 * @priv: private data associated with this client.
755 * @stream_id: stream id
756 * @perf_mode: performace mode for this client
757 *
758 * Return: Will be an error pointer on error or a valid audio client
759 * on success.
760 */
761struct audio_client *q6asm_audio_client_alloc(struct device *dev, q6asm_cb cb,
762 void *priv, int stream_id,
763 int perf_mode)
764{
765 struct q6asm *a = dev_get_drvdata(dev->parent);
766 struct audio_client *ac;
767 unsigned long flags;
768
769 ac = q6asm_get_audio_client(a, stream_id + 1);
770 if (ac) {
771 dev_err(dev, "Audio Client already active\n");
772 return ac;
773 }
774
775 ac = kzalloc(sizeof(*ac), GFP_KERNEL);
776 if (!ac)
777 return ERR_PTR(-ENOMEM);
778
779 spin_lock_irqsave(&a->slock, flags);
780 a->session[stream_id + 1] = ac;
781 spin_unlock_irqrestore(&a->slock, flags);
782 ac->session = stream_id + 1;
783 ac->cb = cb;
784 ac->dev = dev;
785 ac->q6asm = a;
786 ac->priv = priv;
787 ac->io_mode = ASM_SYNC_IO_MODE;
788 ac->perf_mode = perf_mode;
789 /* DSP expects stream id from 1 */
790 ac->stream_id = 1;
791 ac->adev = a->adev;
792 kref_init(&ac->refcount);
793
794 init_waitqueue_head(&ac->cmd_wait);
795 mutex_init(&ac->cmd_lock);
796 spin_lock_init(&ac->lock);
797
798 return ac;
799}
800EXPORT_SYMBOL_GPL(q6asm_audio_client_alloc);
801
802static int q6asm_ac_send_cmd_sync(struct audio_client *ac, struct apr_pkt *pkt)
803{
804 struct apr_hdr *hdr = &pkt->hdr;
805 int rc;
806
807 mutex_lock(&ac->cmd_lock);
808 ac->result.opcode = 0;
809 ac->result.status = 0;
810
811 rc = apr_send_pkt(ac->adev, pkt);
812 if (rc < 0)
813 goto err;
814
815 rc = wait_event_timeout(ac->cmd_wait,
816 (ac->result.opcode == hdr->opcode), 5 * HZ);
817 if (!rc) {
818 dev_err(ac->dev, "CMD timeout\n");
819 rc = -ETIMEDOUT;
820 goto err;
821 }
822
823 if (ac->result.status > 0) {
824 dev_err(ac->dev, "DSP returned error[%x]\n",
825 ac->result.status);
826 rc = -EINVAL;
827 } else {
828 rc = 0;
829 }
830
831
832err:
833 mutex_unlock(&ac->cmd_lock);
834 return rc;
835}
836
837/**
838 * q6asm_open_write() - Open audio client for writing
839 *
840 * @ac: audio client pointer
841 * @format: audio sample format
842 * @bits_per_sample: bits per sample
843 *
844 * Return: Will be an negative value on error or zero on success
845 */
846int q6asm_open_write(struct audio_client *ac, uint32_t format,
847 uint16_t bits_per_sample)
848{
849 struct asm_stream_cmd_open_write_v3 *open;
850 struct apr_pkt *pkt;
851 void *p;
852 int rc, pkt_size;
853
854 pkt_size = APR_HDR_SIZE + sizeof(*open);
855
856 p = kzalloc(pkt_size, GFP_KERNEL);
857 if (!p)
858 return -ENOMEM;
859
860 pkt = p;
861 open = p + APR_HDR_SIZE;
862 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
863
864 pkt->hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
865 open->mode_flags = 0x00;
866 open->mode_flags |= ASM_LEGACY_STREAM_SESSION;
867
868 /* source endpoint : matrix */
869 open->sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
870 open->bits_per_sample = bits_per_sample;
871 open->postprocopo_id = ASM_NULL_POPP_TOPOLOGY;
872
873 switch (format) {
874 case FORMAT_LINEAR_PCM:
875 open->dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
876 break;
877 default:
878 dev_err(ac->dev, "Invalid format 0x%x\n", format);
879 rc = -EINVAL;
880 goto err;
881 }
882
883 rc = q6asm_ac_send_cmd_sync(ac, pkt);
884 if (rc < 0)
885 goto err;
886
887 ac->io_mode |= ASM_TUN_WRITE_IO_MODE;
888
889err:
890 kfree(pkt);
891 return rc;
892}
893EXPORT_SYMBOL_GPL(q6asm_open_write);
894
895static int __q6asm_run(struct audio_client *ac, uint32_t flags,
896 uint32_t msw_ts, uint32_t lsw_ts, bool wait)
897{
898 struct asm_session_cmd_run_v2 *run;
899 struct apr_pkt *pkt;
900 int pkt_size, rc;
901 void *p;
902
903 pkt_size = APR_HDR_SIZE + sizeof(*run);
904 p = kzalloc(pkt_size, GFP_ATOMIC);
905 if (!p)
906 return -ENOMEM;
907
908 pkt = p;
909 run = p + APR_HDR_SIZE;
910
911 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
912
913 pkt->hdr.opcode = ASM_SESSION_CMD_RUN_V2;
914 run->flags = flags;
915 run->time_lsw = lsw_ts;
916 run->time_msw = msw_ts;
917 if (wait) {
918 rc = q6asm_ac_send_cmd_sync(ac, pkt);
919 } else {
920 rc = apr_send_pkt(ac->adev, pkt);
921 if (rc == pkt_size)
922 rc = 0;
923 }
924
925 kfree(pkt);
926 return rc;
927}
928
929/**
930 * q6asm_run() - start the audio client
931 *
932 * @ac: audio client pointer
933 * @flags: flags associated with write
934 * @msw_ts: timestamp msw
935 * @lsw_ts: timestamp lsw
936 *
937 * Return: Will be an negative value on error or zero on success
938 */
939int q6asm_run(struct audio_client *ac, uint32_t flags,
940 uint32_t msw_ts, uint32_t lsw_ts)
941{
942 return __q6asm_run(ac, flags, msw_ts, lsw_ts, true);
943}
944EXPORT_SYMBOL_GPL(q6asm_run);
945
946/**
947 * q6asm_run_nowait() - start the audio client withou blocking
948 *
949 * @ac: audio client pointer
950 * @flags: flags associated with write
951 * @msw_ts: timestamp msw
952 * @lsw_ts: timestamp lsw
953 *
954 * Return: Will be an negative value on error or zero on success
955 */
956int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
957 uint32_t msw_ts, uint32_t lsw_ts)
958{
959 return __q6asm_run(ac, flags, msw_ts, lsw_ts, false);
960}
961EXPORT_SYMBOL_GPL(q6asm_run_nowait);
962
963/**
964 * q6asm_media_format_block_multi_ch_pcm() - setup pcm configuration
965 *
966 * @ac: audio client pointer
967 * @rate: audio sample rate
968 * @channels: number of audio channels.
969 * @channel_map: channel map pointer
970 * @bits_per_sample: bits per sample
971 *
972 * Return: Will be an negative value on error or zero on success
973 */
974int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
975 uint32_t rate, uint32_t channels,
976 u8 channel_map[PCM_MAX_NUM_CHANNEL],
977 uint16_t bits_per_sample)
978{
979 struct asm_multi_channel_pcm_fmt_blk_v2 *fmt;
980 struct apr_pkt *pkt;
981 u8 *channel_mapping;
982 void *p;
983 int rc, pkt_size;
984
985 pkt_size = APR_HDR_SIZE + sizeof(*fmt);
986 p = kzalloc(pkt_size, GFP_KERNEL);
987 if (!p)
988 return -ENOMEM;
989
990 pkt = p;
991 fmt = p + APR_HDR_SIZE;
992
993 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
994
995 pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
996 fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
997 fmt->num_channels = channels;
998 fmt->bits_per_sample = bits_per_sample;
999 fmt->sample_rate = rate;
1000 fmt->is_signed = 1;
1001
1002 channel_mapping = fmt->channel_mapping;
1003
1004 if (channel_map) {
1005 memcpy(channel_mapping, channel_map, PCM_MAX_NUM_CHANNEL);
1006 } else {
1007 if (q6dsp_map_channels(channel_mapping, channels)) {
1008 dev_err(ac->dev, " map channels failed %d\n", channels);
1009 rc = -EINVAL;
1010 goto err;
1011 }
1012 }
1013
1014 rc = q6asm_ac_send_cmd_sync(ac, pkt);
1015
1016err:
1017 kfree(pkt);
1018 return rc;
1019}
1020EXPORT_SYMBOL_GPL(q6asm_media_format_block_multi_ch_pcm);
1021
1022/**
1023 * q6asm_enc_cfg_blk_pcm_format_support() - setup pcm configuration for capture
1024 *
1025 * @ac: audio client pointer
1026 * @rate: audio sample rate
1027 * @channels: number of audio channels.
1028 * @bits_per_sample: bits per sample
1029 *
1030 * Return: Will be an negative value on error or zero on success
1031 */
1032int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
1033 uint32_t rate, uint32_t channels, uint16_t bits_per_sample)
1034{
1035 struct asm_multi_channel_pcm_enc_cfg_v2 *enc_cfg;
1036 struct apr_pkt *pkt;
1037 u8 *channel_mapping;
1038 u32 frames_per_buf = 0;
1039 int pkt_size, rc;
1040 void *p;
1041
1042 pkt_size = APR_HDR_SIZE + sizeof(*enc_cfg);
1043 p = kzalloc(pkt_size, GFP_KERNEL);
1044 if (!p)
1045 return -ENOMEM;
1046
1047 pkt = p;
1048 enc_cfg = p + APR_HDR_SIZE;
1049 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
1050
1051 pkt->hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1052 enc_cfg->encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
1053 enc_cfg->encdec.param_size = sizeof(*enc_cfg) - sizeof(enc_cfg->encdec);
1054 enc_cfg->encblk.frames_per_buf = frames_per_buf;
1055 enc_cfg->encblk.enc_cfg_blk_size = enc_cfg->encdec.param_size -
1056 sizeof(struct asm_enc_cfg_blk_param_v2);
1057
1058 enc_cfg->num_channels = channels;
1059 enc_cfg->bits_per_sample = bits_per_sample;
1060 enc_cfg->sample_rate = rate;
1061 enc_cfg->is_signed = 1;
1062 channel_mapping = enc_cfg->channel_mapping;
1063
1064 if (q6dsp_map_channels(channel_mapping, channels)) {
1065 rc = -EINVAL;
1066 goto err;
1067 }
1068
1069 rc = q6asm_ac_send_cmd_sync(ac, pkt);
1070err:
1071 kfree(pkt);
1072 return rc;
1073}
1074EXPORT_SYMBOL_GPL(q6asm_enc_cfg_blk_pcm_format_support);
1075
1076/**
1077 * q6asm_read() - read data of period size from audio client
1078 *
1079 * @ac: audio client pointer
1080 *
1081 * Return: Will be an negative value on error or zero on success
1082 */
1083int q6asm_read(struct audio_client *ac)
1084{
1085 struct asm_data_cmd_read_v2 *read;
1086 struct audio_port_data *port;
1087 struct audio_buffer *ab;
1088 struct apr_pkt *pkt;
1089 unsigned long flags;
1090 int pkt_size;
1091 int rc = 0;
1092 void *p;
1093
1094 pkt_size = APR_HDR_SIZE + sizeof(*read);
1095 p = kzalloc(pkt_size, GFP_ATOMIC);
1096 if (!p)
1097 return -ENOMEM;
1098
1099 pkt = p;
1100 read = p + APR_HDR_SIZE;
1101
1102 spin_lock_irqsave(&ac->lock, flags);
1103 port = &ac->port[SNDRV_PCM_STREAM_CAPTURE];
1104 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, false, ac->stream_id);
1105 ab = &port->buf[port->dsp_buf];
1106 pkt->hdr.opcode = ASM_DATA_CMD_READ_V2;
1107 read->buf_addr_lsw = lower_32_bits(ab->phys);
1108 read->buf_addr_msw = upper_32_bits(ab->phys);
1109 read->mem_map_handle = port->mem_map_handle;
1110
1111 read->buf_size = ab->size;
1112 read->seq_id = port->dsp_buf;
1113 pkt->hdr.token = port->dsp_buf;
1114
1115 port->dsp_buf++;
1116
1117 if (port->dsp_buf >= port->num_periods)
1118 port->dsp_buf = 0;
1119
1120 spin_unlock_irqrestore(&ac->lock, flags);
1121 rc = apr_send_pkt(ac->adev, pkt);
1122 if (rc == pkt_size)
1123 rc = 0;
1124 else
1125 pr_err("read op[0x%x]rc[%d]\n", pkt->hdr.opcode, rc);
1126
1127 kfree(pkt);
1128 return rc;
1129}
1130EXPORT_SYMBOL_GPL(q6asm_read);
1131
1132static int __q6asm_open_read(struct audio_client *ac,
1133 uint32_t format, uint16_t bits_per_sample)
1134{
1135 struct asm_stream_cmd_open_read_v3 *open;
1136 struct apr_pkt *pkt;
1137 int pkt_size, rc;
1138 void *p;
1139
1140 pkt_size = APR_HDR_SIZE + sizeof(*open);
1141 p = kzalloc(pkt_size, GFP_KERNEL);
1142 if (!p)
1143 return -ENOMEM;
1144
1145 pkt = p;
1146 open = p + APR_HDR_SIZE;
1147
1148 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, ac->stream_id);
1149 pkt->hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V3;
1150 /* Stream prio : High, provide meta info with encoded frames */
1151 open->src_endpointype = ASM_END_POINT_DEVICE_MATRIX;
1152
1153 open->preprocopo_id = ASM_STREAM_POSTPROC_TOPO_ID_NONE;
1154 open->bits_per_sample = bits_per_sample;
1155 open->mode_flags = 0x0;
1156
1157 open->mode_flags |= ASM_LEGACY_STREAM_SESSION <<
1158 ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
1159
1160 switch (format) {
1161 case FORMAT_LINEAR_PCM:
1162 open->mode_flags |= 0x00;
1163 open->enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
1164 break;
1165 default:
1166 pr_err("Invalid format[%d]\n", format);
1167 }
1168
1169 rc = q6asm_ac_send_cmd_sync(ac, pkt);
1170
1171 kfree(pkt);
1172 return rc;
1173}
1174
1175/**
1176 * q6asm_open_read() - Open audio client for reading
1177 *
1178 * @ac: audio client pointer
1179 * @format: audio sample format
1180 * @bits_per_sample: bits per sample
1181 *
1182 * Return: Will be an negative value on error or zero on success
1183 */
1184int q6asm_open_read(struct audio_client *ac, uint32_t format,
1185 uint16_t bits_per_sample)
1186{
1187 return __q6asm_open_read(ac, format, bits_per_sample);
1188}
1189EXPORT_SYMBOL_GPL(q6asm_open_read);
1190
1191/**
1192 * q6asm_write_async() - non blocking write
1193 *
1194 * @ac: audio client pointer
1195 * @len: lenght in bytes
1196 * @msw_ts: timestamp msw
1197 * @lsw_ts: timestamp lsw
1198 * @wflags: flags associated with write
1199 *
1200 * Return: Will be an negative value on error or zero on success
1201 */
1202int q6asm_write_async(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
1203 uint32_t lsw_ts, uint32_t wflags)
1204{
1205 struct asm_data_cmd_write_v2 *write;
1206 struct audio_port_data *port;
1207 struct audio_buffer *ab;
1208 unsigned long flags;
1209 struct apr_pkt *pkt;
1210 int pkt_size;
1211 int rc = 0;
1212 void *p;
1213
1214 pkt_size = APR_HDR_SIZE + sizeof(*write);
1215 p = kzalloc(pkt_size, GFP_ATOMIC);
1216 if (!p)
1217 return -ENOMEM;
1218
1219 pkt = p;
1220 write = p + APR_HDR_SIZE;
1221
1222 spin_lock_irqsave(&ac->lock, flags);
1223 port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
1224 q6asm_add_hdr(ac, &pkt->hdr, pkt_size, false, ac->stream_id);
1225
1226 ab = &port->buf[port->dsp_buf];
1227 pkt->hdr.token = port->dsp_buf;
1228 pkt->hdr.opcode = ASM_DATA_CMD_WRITE_V2;
1229 write->buf_addr_lsw = lower_32_bits(ab->phys);
1230 write->buf_addr_msw = upper_32_bits(ab->phys);
1231 write->buf_size = len;
1232 write->seq_id = port->dsp_buf;
1233 write->timestamp_lsw = lsw_ts;
1234 write->timestamp_msw = msw_ts;
1235 write->mem_map_handle =
1236 ac->port[SNDRV_PCM_STREAM_PLAYBACK].mem_map_handle;
1237
1238 if (wflags == NO_TIMESTAMP)
1239 write->flags = (wflags & 0x800000FF);
1240 else
1241 write->flags = (0x80000000 | wflags);
1242
1243 port->dsp_buf++;
1244
1245 if (port->dsp_buf >= port->num_periods)
1246 port->dsp_buf = 0;
1247
1248 spin_unlock_irqrestore(&ac->lock, flags);
1249 rc = apr_send_pkt(ac->adev, pkt);
1250 if (rc == pkt_size)
1251 rc = 0;
1252
1253 kfree(pkt);
1254 return rc;
1255}
1256EXPORT_SYMBOL_GPL(q6asm_write_async);
1257
1258static void q6asm_reset_buf_state(struct audio_client *ac)
1259{
1260 struct audio_port_data *port = NULL;
1261 unsigned long flags;
1262
1263 spin_lock_irqsave(&ac->lock, flags);
1264 port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
1265 port->dsp_buf = 0;
1266 port = &ac->port[SNDRV_PCM_STREAM_CAPTURE];
1267 port->dsp_buf = 0;
1268 spin_unlock_irqrestore(&ac->lock, flags);
1269}
1270
1271static int __q6asm_cmd(struct audio_client *ac, int cmd, bool wait)
1272{
1273 int stream_id = ac->stream_id;
1274 struct apr_pkt pkt;
1275 int rc;
1276
1277 q6asm_add_hdr(ac, &pkt.hdr, APR_HDR_SIZE, true, stream_id);
1278
1279 switch (cmd) {
1280 case CMD_PAUSE:
1281 pkt.hdr.opcode = ASM_SESSION_CMD_PAUSE;
1282 break;
1283 case CMD_SUSPEND:
1284 pkt.hdr.opcode = ASM_SESSION_CMD_SUSPEND;
1285 break;
1286 case CMD_FLUSH:
1287 pkt.hdr.opcode = ASM_STREAM_CMD_FLUSH;
1288 break;
1289 case CMD_OUT_FLUSH:
1290 pkt.hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS;
1291 break;
1292 case CMD_EOS:
1293 pkt.hdr.opcode = ASM_DATA_CMD_EOS;
1294 break;
1295 case CMD_CLOSE:
1296 pkt.hdr.opcode = ASM_STREAM_CMD_CLOSE;
1297 break;
1298 default:
1299 return -EINVAL;
1300 }
1301
1302 if (wait)
1303 rc = q6asm_ac_send_cmd_sync(ac, &pkt);
1304 else
1305 return apr_send_pkt(ac->adev, &pkt);
1306
1307 if (rc < 0)
1308 return rc;
1309
1310 if (cmd == CMD_FLUSH)
1311 q6asm_reset_buf_state(ac);
1312
1313 return 0;
1314}
1315
1316/**
1317 * q6asm_cmd() - run cmd on audio client
1318 *
1319 * @ac: audio client pointer
1320 * @cmd: command to run on audio client.
1321 *
1322 * Return: Will be an negative value on error or zero on success
1323 */
1324int q6asm_cmd(struct audio_client *ac, int cmd)
1325{
1326 return __q6asm_cmd(ac, cmd, true);
1327}
1328EXPORT_SYMBOL_GPL(q6asm_cmd);
1329
1330/**
1331 * q6asm_cmd_nowait() - non blocking, run cmd on audio client
1332 *
1333 * @ac: audio client pointer
1334 * @cmd: command to run on audio client.
1335 *
1336 * Return: Will be an negative value on error or zero on success
1337 */
1338int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
1339{
1340 return __q6asm_cmd(ac, cmd, false);
1341}
1342EXPORT_SYMBOL_GPL(q6asm_cmd_nowait);
1343
1344static int q6asm_probe(struct apr_device *adev)
1345{
1346 struct device *dev = &adev->dev;
1347 struct device_node *dais_np;
1348 struct q6asm *q6asm;
1349
1350 q6asm = devm_kzalloc(dev, sizeof(*q6asm), GFP_KERNEL);
1351 if (!q6asm)
1352 return -ENOMEM;
1353
1354 q6core_get_svc_api_info(adev->svc_id, &q6asm->ainfo);
1355
1356 q6asm->dev = dev;
1357 q6asm->adev = adev;
1358 init_waitqueue_head(&q6asm->mem_wait);
1359 spin_lock_init(&q6asm->slock);
1360 dev_set_drvdata(dev, q6asm);
1361
1362 dais_np = of_get_child_by_name(dev->of_node, "dais");
1363 if (dais_np) {
1364 q6asm->pdev_dais = of_platform_device_create(dais_np,
1365 "q6asm-dai", dev);
1366 of_node_put(dais_np);
1367 }
1368
1369 return 0;
1370}
1371
1372static int q6asm_remove(struct apr_device *adev)
1373{
1374 struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
1375
1376 if (q6asm->pdev_dais)
1377 of_platform_device_destroy(&q6asm->pdev_dais->dev, NULL);
1378
1379 return 0;
1380}
1381static const struct of_device_id q6asm_device_id[] = {
1382 { .compatible = "qcom,q6asm" },
1383 {},
1384};
1385MODULE_DEVICE_TABLE(of, q6asm_device_id);
1386
1387static struct apr_driver qcom_q6asm_driver = {
1388 .probe = q6asm_probe,
1389 .remove = q6asm_remove,
1390 .callback = q6asm_srvc_callback,
1391 .driver = {
1392 .name = "qcom-q6asm",
1393 .of_match_table = of_match_ptr(q6asm_device_id),
1394 },
1395};
1396
1397module_apr_driver(qcom_q6asm_driver);
1398MODULE_DESCRIPTION("Q6 Audio Stream Manager driver");
1399MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
new file mode 100644
index 000000000000..9f5fb573e4a0
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6asm.h
@@ -0,0 +1,69 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __Q6_ASM_H__
3#define __Q6_ASM_H__
4#include "q6dsp-common.h"
5#include <dt-bindings/sound/qcom,q6asm.h>
6
7/* ASM client callback events */
8#define CMD_PAUSE 0x0001
9#define ASM_CLIENT_EVENT_CMD_PAUSE_DONE 0x1001
10#define CMD_FLUSH 0x0002
11#define ASM_CLIENT_EVENT_CMD_FLUSH_DONE 0x1002
12#define CMD_EOS 0x0003
13#define ASM_CLIENT_EVENT_CMD_EOS_DONE 0x1003
14#define CMD_CLOSE 0x0004
15#define ASM_CLIENT_EVENT_CMD_CLOSE_DONE 0x1004
16#define CMD_OUT_FLUSH 0x0005
17#define ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE 0x1005
18#define CMD_SUSPEND 0x0006
19#define ASM_CLIENT_EVENT_CMD_SUSPEND_DONE 0x1006
20#define ASM_CLIENT_EVENT_CMD_RUN_DONE 0x1008
21#define ASM_CLIENT_EVENT_DATA_WRITE_DONE 0x1009
22#define ASM_CLIENT_EVENT_DATA_READ_DONE 0x100a
23
24enum {
25 LEGACY_PCM_MODE = 0,
26 LOW_LATENCY_PCM_MODE,
27 ULTRA_LOW_LATENCY_PCM_MODE,
28 ULL_POST_PROCESSING_PCM_MODE,
29};
30
31#define MAX_SESSIONS 8
32#define NO_TIMESTAMP 0xFF00
33#define FORMAT_LINEAR_PCM 0x0000
34
35typedef void (*q6asm_cb) (uint32_t opcode, uint32_t token,
36 void *payload, void *priv);
37struct audio_client;
38struct audio_client *q6asm_audio_client_alloc(struct device *dev,
39 q6asm_cb cb, void *priv,
40 int session_id, int perf_mode);
41void q6asm_audio_client_free(struct audio_client *ac);
42int q6asm_write_async(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
43 uint32_t lsw_ts, uint32_t flags);
44int q6asm_open_write(struct audio_client *ac, uint32_t format,
45 uint16_t bits_per_sample);
46
47int q6asm_open_read(struct audio_client *ac, uint32_t format,
48 uint16_t bits_per_sample);
49int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
50 uint32_t rate, uint32_t channels, uint16_t bits_per_sample);
51int q6asm_read(struct audio_client *ac);
52
53int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
54 uint32_t rate, uint32_t channels,
55 u8 channel_map[PCM_MAX_NUM_CHANNEL],
56 uint16_t bits_per_sample);
57int q6asm_run(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
58 uint32_t lsw_ts);
59int q6asm_run_nowait(struct audio_client *ac, uint32_t flags, uint32_t msw_ts,
60 uint32_t lsw_ts);
61int q6asm_cmd(struct audio_client *ac, int cmd);
62int q6asm_cmd_nowait(struct audio_client *ac, int cmd);
63int q6asm_get_session_id(struct audio_client *ac);
64int q6asm_map_memory_regions(unsigned int dir,
65 struct audio_client *ac,
66 phys_addr_t phys,
67 size_t bufsz, unsigned int bufcnt);
68int q6asm_unmap_memory_regions(unsigned int dir, struct audio_client *ac);
69#endif /* __Q6_ASM_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c
new file mode 100644
index 000000000000..06f03a5fe9bd
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6core.c
@@ -0,0 +1,380 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/slab.h>
6#include <linux/wait.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/sched.h>
10#include <linux/of.h>
11#include <linux/of_platform.h>
12#include <linux/jiffies.h>
13#include <linux/wait.h>
14#include <linux/soc/qcom/apr.h>
15#include "q6core.h"
16#include "q6dsp-errno.h"
17
18#define ADSP_STATE_READY_TIMEOUT_MS 3000
19#define Q6_READY_TIMEOUT_MS 100
20#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C
21#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D
22#define AVCS_GET_VERSIONS 0x00012905
23#define AVCS_GET_VERSIONS_RSP 0x00012906
24#define AVCS_CMD_GET_FWK_VERSION 0x001292c
25#define AVCS_CMDRSP_GET_FWK_VERSION 0x001292d
26
27struct avcs_svc_info {
28 uint32_t service_id;
29 uint32_t version;
30} __packed;
31
32struct avcs_cmdrsp_get_version {
33 uint32_t build_id;
34 uint32_t num_services;
35 struct avcs_svc_info svc_api_info[];
36} __packed;
37
38/* for ADSP2.8 and above */
39struct avcs_svc_api_info {
40 uint32_t service_id;
41 uint32_t api_version;
42 uint32_t api_branch_version;
43} __packed;
44
45struct avcs_cmdrsp_get_fwk_version {
46 uint32_t build_major_version;
47 uint32_t build_minor_version;
48 uint32_t build_branch_version;
49 uint32_t build_subbranch_version;
50 uint32_t num_services;
51 struct avcs_svc_api_info svc_api_info[];
52} __packed;
53
54struct q6core {
55 struct apr_device *adev;
56 wait_queue_head_t wait;
57 uint32_t avcs_state;
58 struct mutex lock;
59 bool resp_received;
60 uint32_t num_services;
61 struct avcs_cmdrsp_get_fwk_version *fwk_version;
62 struct avcs_cmdrsp_get_version *svc_version;
63 bool fwk_version_supported;
64 bool get_state_supported;
65 bool get_version_supported;
66 bool is_version_requested;
67};
68
69static struct q6core *g_core;
70
71static int q6core_callback(struct apr_device *adev, struct apr_resp_pkt *data)
72{
73 struct q6core *core = dev_get_drvdata(&adev->dev);
74 struct aprv2_ibasic_rsp_result_t *result;
75 struct apr_hdr *hdr = &data->hdr;
76
77 result = data->payload;
78 switch (hdr->opcode) {
79 case APR_BASIC_RSP_RESULT:{
80 result = data->payload;
81 switch (result->opcode) {
82 case AVCS_GET_VERSIONS:
83 if (result->status == ADSP_EUNSUPPORTED)
84 core->get_version_supported = false;
85 core->resp_received = true;
86 break;
87 case AVCS_CMD_GET_FWK_VERSION:
88 if (result->status == ADSP_EUNSUPPORTED)
89 core->fwk_version_supported = false;
90 core->resp_received = true;
91 break;
92 case AVCS_CMD_ADSP_EVENT_GET_STATE:
93 if (result->status == ADSP_EUNSUPPORTED)
94 core->get_state_supported = false;
95 core->resp_received = true;
96 break;
97 }
98 break;
99 }
100 case AVCS_CMDRSP_GET_FWK_VERSION: {
101 struct avcs_cmdrsp_get_fwk_version *fwk;
102 int bytes;
103
104 fwk = data->payload;
105 bytes = sizeof(*fwk) + fwk->num_services *
106 sizeof(fwk->svc_api_info[0]);
107
108 core->fwk_version = kzalloc(bytes, GFP_ATOMIC);
109 if (!core->fwk_version)
110 return -ENOMEM;
111
112 memcpy(core->fwk_version, data->payload, bytes);
113
114 core->fwk_version_supported = true;
115 core->resp_received = true;
116
117 break;
118 }
119 case AVCS_GET_VERSIONS_RSP: {
120 struct avcs_cmdrsp_get_version *v;
121 int len;
122
123 v = data->payload;
124
125 len = sizeof(*v) + v->num_services * sizeof(v->svc_api_info[0]);
126
127 core->svc_version = kzalloc(len, GFP_ATOMIC);
128 if (!core->svc_version)
129 return -ENOMEM;
130
131 memcpy(core->svc_version, data->payload, len);
132
133 core->get_version_supported = true;
134 core->resp_received = true;
135
136 break;
137 }
138 case AVCS_CMDRSP_ADSP_EVENT_GET_STATE:
139 core->get_state_supported = true;
140 core->avcs_state = result->opcode;
141
142 core->resp_received = true;
143 break;
144 default:
145 dev_err(&adev->dev, "Message id from adsp core svc: 0x%x\n",
146 hdr->opcode);
147 break;
148 }
149
150 if (core->resp_received)
151 wake_up(&core->wait);
152
153 return 0;
154}
155
156static int q6core_get_fwk_versions(struct q6core *core)
157{
158 struct apr_device *adev = core->adev;
159 struct apr_pkt pkt;
160 int rc;
161
162 pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
163 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
164 pkt.hdr.pkt_size = APR_HDR_SIZE;
165 pkt.hdr.opcode = AVCS_CMD_GET_FWK_VERSION;
166
167 rc = apr_send_pkt(adev, &pkt);
168 if (rc < 0)
169 return rc;
170
171 rc = wait_event_timeout(core->wait, (core->resp_received),
172 msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
173 if (rc > 0 && core->resp_received) {
174 core->resp_received = false;
175
176 if (!core->fwk_version_supported)
177 return -ENOTSUPP;
178 else
179 return 0;
180 }
181
182
183 return rc;
184}
185
186static int q6core_get_svc_versions(struct q6core *core)
187{
188 struct apr_device *adev = core->adev;
189 struct apr_pkt pkt;
190 int rc;
191
192 pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
193 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
194 pkt.hdr.pkt_size = APR_HDR_SIZE;
195 pkt.hdr.opcode = AVCS_GET_VERSIONS;
196
197 rc = apr_send_pkt(adev, &pkt);
198 if (rc < 0)
199 return rc;
200
201 rc = wait_event_timeout(core->wait, (core->resp_received),
202 msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
203 if (rc > 0 && core->resp_received) {
204 core->resp_received = false;
205 return 0;
206 }
207
208 return rc;
209}
210
211static bool __q6core_is_adsp_ready(struct q6core *core)
212{
213 struct apr_device *adev = core->adev;
214 struct apr_pkt pkt;
215 int rc;
216
217 core->get_state_supported = false;
218
219 pkt.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
220 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
221 pkt.hdr.pkt_size = APR_HDR_SIZE;
222 pkt.hdr.opcode = AVCS_CMD_ADSP_EVENT_GET_STATE;
223
224 rc = apr_send_pkt(adev, &pkt);
225 if (rc < 0)
226 return false;
227
228 rc = wait_event_timeout(core->wait, (core->resp_received),
229 msecs_to_jiffies(Q6_READY_TIMEOUT_MS));
230 if (rc > 0 && core->resp_received) {
231 core->resp_received = false;
232
233 if (core->avcs_state)
234 return true;
235 }
236
237 /* assume that the adsp is up if we not support this command */
238 if (!core->get_state_supported)
239 return true;
240
241 return false;
242}
243
244/**
245 * q6core_get_svc_api_info() - Get version number of a service.
246 *
247 * @svc_id: service id of the service.
248 * @ainfo: Valid struct pointer to fill svc api information.
249 *
250 * Return: zero on success and error code on failure or unsupported
251 */
252int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo)
253{
254 int i;
255 int ret = -ENOTSUPP;
256
257 if (!g_core || !ainfo)
258 return 0;
259
260 mutex_lock(&g_core->lock);
261 if (!g_core->is_version_requested) {
262 if (q6core_get_fwk_versions(g_core) == -ENOTSUPP)
263 q6core_get_svc_versions(g_core);
264 g_core->is_version_requested = true;
265 }
266
267 if (g_core->fwk_version_supported) {
268 for (i = 0; i < g_core->fwk_version->num_services; i++) {
269 struct avcs_svc_api_info *info;
270
271 info = &g_core->fwk_version->svc_api_info[i];
272 if (svc_id != info->service_id)
273 continue;
274
275 ainfo->api_version = info->api_version;
276 ainfo->api_branch_version = info->api_branch_version;
277 ret = 0;
278 break;
279 }
280 } else if (g_core->get_version_supported) {
281 for (i = 0; i < g_core->svc_version->num_services; i++) {
282 struct avcs_svc_info *info;
283
284 info = &g_core->svc_version->svc_api_info[i];
285 if (svc_id != info->service_id)
286 continue;
287
288 ainfo->api_version = info->version;
289 ainfo->api_branch_version = 0;
290 ret = 0;
291 break;
292 }
293 }
294
295 mutex_unlock(&g_core->lock);
296
297 return ret;
298}
299EXPORT_SYMBOL_GPL(q6core_get_svc_api_info);
300
301/**
302 * q6core_is_adsp_ready() - Get status of adsp
303 *
304 * Return: Will be an true if adsp is ready and false if not.
305 */
306bool q6core_is_adsp_ready(void)
307{
308 unsigned long timeout;
309 bool ret = false;
310
311 if (!g_core)
312 return false;
313
314 mutex_lock(&g_core->lock);
315 timeout = jiffies + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
316 for (;;) {
317 if (__q6core_is_adsp_ready(g_core)) {
318 ret = true;
319 break;
320 }
321
322 if (!time_after(timeout, jiffies)) {
323 ret = false;
324 break;
325 }
326 }
327
328 mutex_unlock(&g_core->lock);
329 return ret;
330}
331EXPORT_SYMBOL_GPL(q6core_is_adsp_ready);
332
333static int q6core_probe(struct apr_device *adev)
334{
335 g_core = kzalloc(sizeof(*g_core), GFP_KERNEL);
336 if (!g_core)
337 return -ENOMEM;
338
339 dev_set_drvdata(&adev->dev, g_core);
340
341 mutex_init(&g_core->lock);
342 g_core->adev = adev;
343 init_waitqueue_head(&g_core->wait);
344 return 0;
345}
346
347static int q6core_exit(struct apr_device *adev)
348{
349 struct q6core *core = dev_get_drvdata(&adev->dev);
350
351 if (core->fwk_version_supported)
352 kfree(core->fwk_version);
353 if (core->get_version_supported)
354 kfree(core->svc_version);
355
356 g_core = NULL;
357 kfree(core);
358
359 return 0;
360}
361
362static const struct of_device_id q6core_device_id[] = {
363 { .compatible = "qcom,q6core" },
364 {},
365};
366MODULE_DEVICE_TABLE(of, q6core_device_id);
367
368static struct apr_driver qcom_q6core_driver = {
369 .probe = q6core_probe,
370 .remove = q6core_exit,
371 .callback = q6core_callback,
372 .driver = {
373 .name = "qcom-q6core",
374 .of_match_table = of_match_ptr(q6core_device_id),
375 },
376};
377
378module_apr_driver(qcom_q6core_driver);
379MODULE_DESCRIPTION("q6 core");
380MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6core.h b/sound/soc/qcom/qdsp6/q6core.h
new file mode 100644
index 000000000000..4105b1d730be
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6core.h
@@ -0,0 +1,15 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __Q6CORE_H__
4#define __Q6CORE_H__
5
6struct q6core_svc_api_info {
7 uint32_t service_id;
8 uint32_t api_version;
9 uint32_t api_branch_version;
10};
11
12bool q6core_is_adsp_ready(void);
13int q6core_get_svc_api_info(int svc_id, struct q6core_svc_api_info *ainfo);
14
15#endif /* __Q6CORE_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.c b/sound/soc/qcom/qdsp6/q6dsp-common.c
new file mode 100644
index 000000000000..d393003492c7
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.c
@@ -0,0 +1,66 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include "q6dsp-common.h"
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/string.h>
9#include <linux/errno.h>
10
11int q6dsp_map_channels(u8 ch_map[PCM_MAX_NUM_CHANNEL], int ch)
12{
13 memset(ch_map, 0, PCM_MAX_NUM_CHANNEL);
14
15 switch (ch) {
16 case 1:
17 ch_map[0] = PCM_CHANNEL_FC;
18 break;
19 case 2:
20 ch_map[0] = PCM_CHANNEL_FL;
21 ch_map[1] = PCM_CHANNEL_FR;
22 break;
23 case 3:
24 ch_map[0] = PCM_CHANNEL_FL;
25 ch_map[1] = PCM_CHANNEL_FR;
26 ch_map[2] = PCM_CHANNEL_FC;
27 break;
28 case 4:
29 ch_map[0] = PCM_CHANNEL_FL;
30 ch_map[1] = PCM_CHANNEL_FR;
31 ch_map[2] = PCM_CHANNEL_LS;
32 ch_map[3] = PCM_CHANNEL_RS;
33 break;
34 case 5:
35 ch_map[0] = PCM_CHANNEL_FL;
36 ch_map[1] = PCM_CHANNEL_FR;
37 ch_map[2] = PCM_CHANNEL_FC;
38 ch_map[3] = PCM_CHANNEL_LS;
39 ch_map[4] = PCM_CHANNEL_RS;
40 break;
41 case 6:
42 ch_map[0] = PCM_CHANNEL_FL;
43 ch_map[1] = PCM_CHANNEL_FR;
44 ch_map[2] = PCM_CHANNEL_LFE;
45 ch_map[3] = PCM_CHANNEL_FC;
46 ch_map[4] = PCM_CHANNEL_LS;
47 ch_map[5] = PCM_CHANNEL_RS;
48 break;
49 case 8:
50 ch_map[0] = PCM_CHANNEL_FL;
51 ch_map[1] = PCM_CHANNEL_FR;
52 ch_map[2] = PCM_CHANNEL_LFE;
53 ch_map[3] = PCM_CHANNEL_FC;
54 ch_map[4] = PCM_CHANNEL_LS;
55 ch_map[5] = PCM_CHANNEL_RS;
56 ch_map[6] = PCM_CHANNEL_LB;
57 ch_map[7] = PCM_CHANNEL_RB;
58 break;
59 default:
60 return -EINVAL;
61 }
62
63 return 0;
64}
65EXPORT_SYMBOL_GPL(q6dsp_map_channels);
66MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.h b/sound/soc/qcom/qdsp6/q6dsp-common.h
new file mode 100644
index 000000000000..01094d108b8a
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.h
@@ -0,0 +1,24 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __Q6DSP_COMMON_H__
4#define __Q6DSP_COMMON_H__
5
6#include <linux/kernel.h>
7
8#define PCM_MAX_NUM_CHANNEL 8
9#define PCM_CHANNEL_NULL 0
10
11#define PCM_CHANNEL_FL 1 /* Front left channel. */
12#define PCM_CHANNEL_FR 2 /* Front right channel. */
13#define PCM_CHANNEL_FC 3 /* Front center channel. */
14#define PCM_CHANNEL_LS 4 /* Left surround channel. */
15#define PCM_CHANNEL_RS 5 /* Right surround channel. */
16#define PCM_CHANNEL_LFE 6 /* Low frequency effect channel. */
17#define PCM_CHANNEL_CS 7 /* Center surround channel; Rear center ch */
18#define PCM_CHANNEL_LB 8 /* Left back channel; Rear left channel. */
19#define PCM_CHANNEL_RB 9 /* Right back channel; Rear right channel. */
20#define PCM_CHANNELS 10 /* Top surround channel. */
21
22int q6dsp_map_channels(u8 ch_map[PCM_MAX_NUM_CHANNEL], int ch);
23
24#endif /* __Q6DSP_COMMON_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6dsp-errno.h b/sound/soc/qcom/qdsp6/q6dsp-errno.h
new file mode 100644
index 000000000000..1ec00ff8c1d2
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-errno.h
@@ -0,0 +1,51 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __Q6DSP_ERR_NO_H__
4#define __Q6DSP_ERR_NO_H__
5#include <linux/kernel.h>
6
7/* Success. The operation completed with no errors. */
8#define ADSP_EOK 0x00000000
9/* General failure. */
10#define ADSP_EFAILED 0x00000001
11/* Bad operation parameter. */
12#define ADSP_EBADPARAM 0x00000002
13/* Unsupported routine or operation. */
14#define ADSP_EUNSUPPORTED 0x00000003
15/* Unsupported version. */
16#define ADSP_EVERSION 0x00000004
17/* Unexpected problem encountered. */
18#define ADSP_EUNEXPECTED 0x00000005
19/* Unhandled problem occurred. */
20#define ADSP_EPANIC 0x00000006
21/* Unable to allocate resource. */
22#define ADSP_ENORESOURCE 0x00000007
23/* Invalid handle. */
24#define ADSP_EHANDLE 0x00000008
25/* Operation is already processed. */
26#define ADSP_EALREADY 0x00000009
27/* Operation is not ready to be processed. */
28#define ADSP_ENOTREADY 0x0000000A
29/* Operation is pending completion. */
30#define ADSP_EPENDING 0x0000000B
31/* Operation could not be accepted or processed. */
32#define ADSP_EBUSY 0x0000000C
33/* Operation aborted due to an error. */
34#define ADSP_EABORTED 0x0000000D
35/* Operation preempted by a higher priority. */
36#define ADSP_EPREEMPTED 0x0000000E
37/* Operation requests intervention to complete. */
38#define ADSP_ECONTINUE 0x0000000F
39/* Operation requests immediate intervention to complete. */
40#define ADSP_EIMMEDIATE 0x00000010
41/* Operation is not implemented. */
42#define ADSP_ENOTIMPL 0x00000011
43/* Operation needs more data or resources. */
44#define ADSP_ENEEDMORE 0x00000012
45/* Operation does not have memory. */
46#define ADSP_ENOMEMORY 0x00000014
47/* Item does not exist. */
48#define ADSP_ENOTEXIST 0x00000015
49/* Max count for adsp error code sent to HLOS*/
50
51#endif /*__Q6DSP_ERR_NO_H__ */
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
new file mode 100644
index 000000000000..593f66b8622f
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -0,0 +1,1006 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/init.h>
6#include <linux/err.h>
7#include <linux/module.h>
8#include <linux/platform_device.h>
9#include <linux/of_platform.h>
10#include <linux/bitops.h>
11#include <linux/component.h>
12#include <linux/mutex.h>
13#include <linux/of_device.h>
14#include <linux/slab.h>
15#include <sound/core.h>
16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18#include <sound/pcm.h>
19#include <sound/control.h>
20#include <sound/asound.h>
21#include <sound/pcm_params.h>
22#include "q6afe.h"
23#include "q6asm.h"
24#include "q6adm.h"
25#include "q6routing.h"
26
27#define DRV_NAME "q6routing-component"
28
29#define Q6ROUTING_RX_MIXERS(id) \
30 SOC_SINGLE_EXT("MultiMedia1", id, \
31 MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,\
32 msm_routing_put_audio_mixer), \
33 SOC_SINGLE_EXT("MultiMedia2", id, \
34 MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,\
35 msm_routing_put_audio_mixer), \
36 SOC_SINGLE_EXT("MultiMedia3", id, \
37 MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,\
38 msm_routing_put_audio_mixer), \
39 SOC_SINGLE_EXT("MultiMedia4", id, \
40 MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,\
41 msm_routing_put_audio_mixer), \
42 SOC_SINGLE_EXT("MultiMedia5", id, \
43 MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,\
44 msm_routing_put_audio_mixer), \
45 SOC_SINGLE_EXT("MultiMedia6", id, \
46 MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,\
47 msm_routing_put_audio_mixer), \
48 SOC_SINGLE_EXT("MultiMedia7", id, \
49 MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,\
50 msm_routing_put_audio_mixer), \
51 SOC_SINGLE_EXT("MultiMedia8", id, \
52 MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,\
53 msm_routing_put_audio_mixer),
54
55#define Q6ROUTING_RX_DAPM_ROUTE(mix_name, s) \
56 { mix_name, "MultiMedia1", "MM_DL1" }, \
57 { mix_name, "MultiMedia2", "MM_DL2" }, \
58 { mix_name, "MultiMedia3", "MM_DL3" }, \
59 { mix_name, "MultiMedia4", "MM_DL4" }, \
60 { mix_name, "MultiMedia5", "MM_DL5" }, \
61 { mix_name, "MultiMedia6", "MM_DL6" }, \
62 { mix_name, "MultiMedia7", "MM_DL7" }, \
63 { mix_name, "MultiMedia8", "MM_DL8" }, \
64 { s, NULL, mix_name }
65
66#define Q6ROUTING_TX_DAPM_ROUTE(mix_name) \
67 { mix_name, "PRI_MI2S_TX", "PRI_MI2S_TX" }, \
68 { mix_name, "SEC_MI2S_TX", "SEC_MI2S_TX" }, \
69 { mix_name, "QUAT_MI2S_TX", "QUAT_MI2S_TX" }, \
70 { mix_name, "TERT_MI2S_TX", "TERT_MI2S_TX" }, \
71 { mix_name, "PRIMARY_TDM_TX_0", "PRIMARY_TDM_TX_0"}, \
72 { mix_name, "PRIMARY_TDM_TX_1", "PRIMARY_TDM_TX_1"}, \
73 { mix_name, "PRIMARY_TDM_TX_2", "PRIMARY_TDM_TX_2"}, \
74 { mix_name, "PRIMARY_TDM_TX_3", "PRIMARY_TDM_TX_3"}, \
75 { mix_name, "PRIMARY_TDM_TX_4", "PRIMARY_TDM_TX_4"}, \
76 { mix_name, "PRIMARY_TDM_TX_5", "PRIMARY_TDM_TX_5"}, \
77 { mix_name, "PRIMARY_TDM_TX_6", "PRIMARY_TDM_TX_6"}, \
78 { mix_name, "PRIMARY_TDM_TX_7", "PRIMARY_TDM_TX_7"}, \
79 { mix_name, "SEC_TDM_TX_0", "SEC_TDM_TX_0"}, \
80 { mix_name, "SEC_TDM_TX_1", "SEC_TDM_TX_1"}, \
81 { mix_name, "SEC_TDM_TX_2", "SEC_TDM_TX_2"}, \
82 { mix_name, "SEC_TDM_TX_3", "SEC_TDM_TX_3"}, \
83 { mix_name, "SEC_TDM_TX_4", "SEC_TDM_TX_4"}, \
84 { mix_name, "SEC_TDM_TX_5", "SEC_TDM_TX_5"}, \
85 { mix_name, "SEC_TDM_TX_6", "SEC_TDM_TX_6"}, \
86 { mix_name, "SEC_TDM_TX_7", "SEC_TDM_TX_7"}, \
87 { mix_name, "TERT_TDM_TX_0", "TERT_TDM_TX_0"}, \
88 { mix_name, "TERT_TDM_TX_1", "TERT_TDM_TX_1"}, \
89 { mix_name, "TERT_TDM_TX_2", "TERT_TDM_TX_2"}, \
90 { mix_name, "TERT_TDM_TX_3", "TERT_TDM_TX_3"}, \
91 { mix_name, "TERT_TDM_TX_4", "TERT_TDM_TX_4"}, \
92 { mix_name, "TERT_TDM_TX_5", "TERT_TDM_TX_5"}, \
93 { mix_name, "TERT_TDM_TX_6", "TERT_TDM_TX_6"}, \
94 { mix_name, "TERT_TDM_TX_7", "TERT_TDM_TX_7"}, \
95 { mix_name, "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"}, \
96 { mix_name, "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, \
97 { mix_name, "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, \
98 { mix_name, "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, \
99 { mix_name, "QUAT_TDM_TX_4", "QUAT_TDM_TX_4"}, \
100 { mix_name, "QUAT_TDM_TX_5", "QUAT_TDM_TX_5"}, \
101 { mix_name, "QUAT_TDM_TX_6", "QUAT_TDM_TX_6"}, \
102 { mix_name, "QUAT_TDM_TX_7", "QUAT_TDM_TX_7"}, \
103 { mix_name, "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"}, \
104 { mix_name, "QUIN_TDM_TX_1", "QUIN_TDM_TX_1"}, \
105 { mix_name, "QUIN_TDM_TX_2", "QUIN_TDM_TX_2"}, \
106 { mix_name, "QUIN_TDM_TX_3", "QUIN_TDM_TX_3"}, \
107 { mix_name, "QUIN_TDM_TX_4", "QUIN_TDM_TX_4"}, \
108 { mix_name, "QUIN_TDM_TX_5", "QUIN_TDM_TX_5"}, \
109 { mix_name, "QUIN_TDM_TX_6", "QUIN_TDM_TX_6"}, \
110 { mix_name, "QUIN_TDM_TX_7", "QUIN_TDM_TX_7"}
111
112#define Q6ROUTING_TX_MIXERS(id) \
113 SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, \
114 id, 1, 0, msm_routing_get_audio_mixer, \
115 msm_routing_put_audio_mixer), \
116 SOC_SINGLE_EXT("SEC_MI2S_TX", SECONDARY_MI2S_TX, \
117 id, 1, 0, msm_routing_get_audio_mixer, \
118 msm_routing_put_audio_mixer), \
119 SOC_SINGLE_EXT("TERT_MI2S_TX", TERTIARY_MI2S_TX, \
120 id, 1, 0, msm_routing_get_audio_mixer, \
121 msm_routing_put_audio_mixer), \
122 SOC_SINGLE_EXT("QUAT_MI2S_TX", QUATERNARY_MI2S_TX, \
123 id, 1, 0, msm_routing_get_audio_mixer, \
124 msm_routing_put_audio_mixer), \
125 SOC_SINGLE_EXT("PRIMARY_TDM_TX_0", PRIMARY_TDM_TX_0, \
126 id, 1, 0, msm_routing_get_audio_mixer, \
127 msm_routing_put_audio_mixer), \
128 SOC_SINGLE_EXT("PRIMARY_TDM_TX_1", PRIMARY_TDM_TX_1, \
129 id, 1, 0, msm_routing_get_audio_mixer, \
130 msm_routing_put_audio_mixer), \
131 SOC_SINGLE_EXT("PRIMARY_TDM_TX_2", PRIMARY_TDM_TX_2, \
132 id, 1, 0, msm_routing_get_audio_mixer, \
133 msm_routing_put_audio_mixer), \
134 SOC_SINGLE_EXT("PRIMARY_TDM_TX_3", PRIMARY_TDM_TX_3, \
135 id, 1, 0, msm_routing_get_audio_mixer, \
136 msm_routing_put_audio_mixer), \
137 SOC_SINGLE_EXT("PRIMARY_TDM_TX_4", PRIMARY_TDM_TX_4, \
138 id, 1, 0, msm_routing_get_audio_mixer, \
139 msm_routing_put_audio_mixer), \
140 SOC_SINGLE_EXT("PRIMARY_TDM_TX_5", PRIMARY_TDM_TX_5, \
141 id, 1, 0, msm_routing_get_audio_mixer, \
142 msm_routing_put_audio_mixer), \
143 SOC_SINGLE_EXT("PRIMARY_TDM_TX_6", PRIMARY_TDM_TX_6, \
144 id, 1, 0, msm_routing_get_audio_mixer, \
145 msm_routing_put_audio_mixer), \
146 SOC_SINGLE_EXT("PRIMARY_TDM_TX_7", PRIMARY_TDM_TX_7, \
147 id, 1, 0, msm_routing_get_audio_mixer, \
148 msm_routing_put_audio_mixer), \
149 SOC_SINGLE_EXT("SEC_TDM_TX_0", SECONDARY_TDM_TX_0, \
150 id, 1, 0, msm_routing_get_audio_mixer, \
151 msm_routing_put_audio_mixer), \
152 SOC_SINGLE_EXT("SEC_TDM_TX_1", SECONDARY_TDM_TX_1, \
153 id, 1, 0, msm_routing_get_audio_mixer, \
154 msm_routing_put_audio_mixer), \
155 SOC_SINGLE_EXT("SEC_TDM_TX_2", SECONDARY_TDM_TX_2, \
156 id, 1, 0, msm_routing_get_audio_mixer, \
157 msm_routing_put_audio_mixer), \
158 SOC_SINGLE_EXT("SEC_TDM_TX_3", SECONDARY_TDM_TX_3, \
159 id, 1, 0, msm_routing_get_audio_mixer, \
160 msm_routing_put_audio_mixer), \
161 SOC_SINGLE_EXT("SEC_TDM_TX_4", SECONDARY_TDM_TX_4, \
162 id, 1, 0, msm_routing_get_audio_mixer, \
163 msm_routing_put_audio_mixer), \
164 SOC_SINGLE_EXT("SEC_TDM_TX_5", SECONDARY_TDM_TX_5, \
165 id, 1, 0, msm_routing_get_audio_mixer, \
166 msm_routing_put_audio_mixer), \
167 SOC_SINGLE_EXT("SEC_TDM_TX_6", SECONDARY_TDM_TX_6, \
168 id, 1, 0, msm_routing_get_audio_mixer, \
169 msm_routing_put_audio_mixer), \
170 SOC_SINGLE_EXT("SEC_TDM_TX_7", SECONDARY_TDM_TX_7, \
171 id, 1, 0, msm_routing_get_audio_mixer, \
172 msm_routing_put_audio_mixer), \
173 SOC_SINGLE_EXT("TERT_TDM_TX_0", TERTIARY_TDM_TX_0, \
174 id, 1, 0, msm_routing_get_audio_mixer, \
175 msm_routing_put_audio_mixer), \
176 SOC_SINGLE_EXT("TERT_TDM_TX_1", TERTIARY_TDM_TX_1, \
177 id, 1, 0, msm_routing_get_audio_mixer, \
178 msm_routing_put_audio_mixer), \
179 SOC_SINGLE_EXT("TERT_TDM_TX_2", TERTIARY_TDM_TX_2, \
180 id, 1, 0, msm_routing_get_audio_mixer, \
181 msm_routing_put_audio_mixer), \
182 SOC_SINGLE_EXT("TERT_TDM_TX_3", TERTIARY_TDM_TX_3, \
183 id, 1, 0, msm_routing_get_audio_mixer, \
184 msm_routing_put_audio_mixer), \
185 SOC_SINGLE_EXT("TERT_TDM_TX_4", TERTIARY_TDM_TX_4, \
186 id, 1, 0, msm_routing_get_audio_mixer, \
187 msm_routing_put_audio_mixer), \
188 SOC_SINGLE_EXT("TERT_TDM_TX_5", TERTIARY_TDM_TX_5, \
189 id, 1, 0, msm_routing_get_audio_mixer, \
190 msm_routing_put_audio_mixer), \
191 SOC_SINGLE_EXT("TERT_TDM_TX_6", TERTIARY_TDM_TX_6, \
192 id, 1, 0, msm_routing_get_audio_mixer, \
193 msm_routing_put_audio_mixer), \
194 SOC_SINGLE_EXT("TERT_TDM_TX_7", TERTIARY_TDM_TX_7, \
195 id, 1, 0, msm_routing_get_audio_mixer, \
196 msm_routing_put_audio_mixer), \
197 SOC_SINGLE_EXT("QUAT_TDM_TX_0", QUATERNARY_TDM_TX_0, \
198 id, 1, 0, msm_routing_get_audio_mixer, \
199 msm_routing_put_audio_mixer), \
200 SOC_SINGLE_EXT("QUAT_TDM_TX_1", QUATERNARY_TDM_TX_1, \
201 id, 1, 0, msm_routing_get_audio_mixer, \
202 msm_routing_put_audio_mixer), \
203 SOC_SINGLE_EXT("QUAT_TDM_TX_2", QUATERNARY_TDM_TX_2, \
204 id, 1, 0, msm_routing_get_audio_mixer, \
205 msm_routing_put_audio_mixer), \
206 SOC_SINGLE_EXT("QUAT_TDM_TX_3", QUATERNARY_TDM_TX_3, \
207 id, 1, 0, msm_routing_get_audio_mixer, \
208 msm_routing_put_audio_mixer), \
209 SOC_SINGLE_EXT("QUAT_TDM_TX_4", QUATERNARY_TDM_TX_4, \
210 id, 1, 0, msm_routing_get_audio_mixer, \
211 msm_routing_put_audio_mixer), \
212 SOC_SINGLE_EXT("QUAT_TDM_TX_5", QUATERNARY_TDM_TX_5, \
213 id, 1, 0, msm_routing_get_audio_mixer, \
214 msm_routing_put_audio_mixer), \
215 SOC_SINGLE_EXT("QUAT_TDM_TX_6", QUATERNARY_TDM_TX_6, \
216 id, 1, 0, msm_routing_get_audio_mixer, \
217 msm_routing_put_audio_mixer), \
218 SOC_SINGLE_EXT("QUAT_TDM_TX_7", QUATERNARY_TDM_TX_7, \
219 id, 1, 0, msm_routing_get_audio_mixer, \
220 msm_routing_put_audio_mixer), \
221 SOC_SINGLE_EXT("QUIN_TDM_TX_0", QUINARY_TDM_TX_0, \
222 id, 1, 0, msm_routing_get_audio_mixer, \
223 msm_routing_put_audio_mixer), \
224 SOC_SINGLE_EXT("QUIN_TDM_TX_1", QUINARY_TDM_TX_1, \
225 id, 1, 0, msm_routing_get_audio_mixer, \
226 msm_routing_put_audio_mixer), \
227 SOC_SINGLE_EXT("QUIN_TDM_TX_2", QUINARY_TDM_TX_2, \
228 id, 1, 0, msm_routing_get_audio_mixer, \
229 msm_routing_put_audio_mixer), \
230 SOC_SINGLE_EXT("QUIN_TDM_TX_3", QUINARY_TDM_TX_3, \
231 id, 1, 0, msm_routing_get_audio_mixer, \
232 msm_routing_put_audio_mixer), \
233 SOC_SINGLE_EXT("QUIN_TDM_TX_4", QUINARY_TDM_TX_4, \
234 id, 1, 0, msm_routing_get_audio_mixer, \
235 msm_routing_put_audio_mixer), \
236 SOC_SINGLE_EXT("QUIN_TDM_TX_5", QUINARY_TDM_TX_5, \
237 id, 1, 0, msm_routing_get_audio_mixer, \
238 msm_routing_put_audio_mixer), \
239 SOC_SINGLE_EXT("QUIN_TDM_TX_6", QUINARY_TDM_TX_6, \
240 id, 1, 0, msm_routing_get_audio_mixer, \
241 msm_routing_put_audio_mixer), \
242 SOC_SINGLE_EXT("QUIN_TDM_TX_7", QUINARY_TDM_TX_7, \
243 id, 1, 0, msm_routing_get_audio_mixer, \
244 msm_routing_put_audio_mixer),
245
246struct session_data {
247 int state;
248 int port_id;
249 int path_type;
250 int app_type;
251 int acdb_id;
252 int sample_rate;
253 int bits_per_sample;
254 int channels;
255 int perf_mode;
256 int numcopps;
257 int fedai_id;
258 unsigned long copp_map;
259 struct q6copp *copps[MAX_COPPS_PER_PORT];
260};
261
262struct msm_routing_data {
263 struct session_data sessions[MAX_SESSIONS];
264 struct session_data port_data[AFE_MAX_PORTS];
265 struct device *dev;
266 struct mutex lock;
267};
268
269static struct msm_routing_data *routing_data;
270
271/**
272 * q6routing_stream_open() - Register a new stream for route setup
273 *
274 * @fedai_id: Frontend dai id.
275 * @perf_mode: Performance mode.
276 * @stream_id: ASM stream id to map.
277 * @stream_type: Direction of stream
278 *
279 * Return: Will be an negative on error or a zero on success.
280 */
281int q6routing_stream_open(int fedai_id, int perf_mode,
282 int stream_id, int stream_type)
283{
284 int j, topology, num_copps = 0;
285 struct route_payload payload;
286 struct q6copp *copp;
287 int copp_idx;
288 struct session_data *session, *pdata;
289
290 if (!routing_data) {
291 pr_err("Routing driver not yet ready\n");
292 return -EINVAL;
293 }
294
295 session = &routing_data->sessions[stream_id - 1];
296 pdata = &routing_data->port_data[session->port_id];
297
298 mutex_lock(&routing_data->lock);
299 session->fedai_id = fedai_id;
300
301 session->path_type = pdata->path_type;
302 session->sample_rate = pdata->sample_rate;
303 session->channels = pdata->channels;
304 session->bits_per_sample = pdata->bits_per_sample;
305
306 payload.num_copps = 0; /* only RX needs to use payload */
307 topology = NULL_COPP_TOPOLOGY;
308 copp = q6adm_open(routing_data->dev, session->port_id,
309 session->path_type, session->sample_rate,
310 session->channels, topology, perf_mode,
311 session->bits_per_sample, 0, 0);
312
313 if (!copp) {
314 mutex_unlock(&routing_data->lock);
315 return -EINVAL;
316 }
317
318 copp_idx = q6adm_get_copp_id(copp);
319 set_bit(copp_idx, &session->copp_map);
320 session->copps[copp_idx] = copp;
321
322 for_each_set_bit(j, &session->copp_map, MAX_COPPS_PER_PORT) {
323 payload.port_id[num_copps] = session->port_id;
324 payload.copp_idx[num_copps] = j;
325 num_copps++;
326 }
327
328 if (num_copps) {
329 payload.num_copps = num_copps;
330 payload.session_id = stream_id;
331 q6adm_matrix_map(routing_data->dev, session->path_type,
332 payload, perf_mode);
333 }
334 mutex_unlock(&routing_data->lock);
335
336 return 0;
337}
338EXPORT_SYMBOL_GPL(q6routing_stream_open);
339
340static struct session_data *get_session_from_id(struct msm_routing_data *data,
341 int fedai_id)
342{
343 int i;
344
345 for (i = 0; i < MAX_SESSIONS; i++) {
346 if (fedai_id == data->sessions[i].fedai_id)
347 return &data->sessions[i];
348 }
349
350 return NULL;
351}
352/**
353 * q6routing_stream_close() - Deregister a stream
354 *
355 * @fedai_id: Frontend dai id.
356 * @stream_type: Direction of stream
357 *
358 * Return: Will be an negative on error or a zero on success.
359 */
360void q6routing_stream_close(int fedai_id, int stream_type)
361{
362 struct session_data *session;
363 int idx;
364
365 session = get_session_from_id(routing_data, fedai_id);
366 if (!session)
367 return;
368
369 for_each_set_bit(idx, &session->copp_map, MAX_COPPS_PER_PORT) {
370 if (session->copps[idx]) {
371 q6adm_close(routing_data->dev, session->copps[idx]);
372 session->copps[idx] = NULL;
373 }
374 }
375
376 session->fedai_id = -1;
377 session->copp_map = 0;
378}
379EXPORT_SYMBOL_GPL(q6routing_stream_close);
380
381static int msm_routing_get_audio_mixer(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383{
384 struct snd_soc_dapm_context *dapm =
385 snd_soc_dapm_kcontrol_dapm(kcontrol);
386 struct soc_mixer_control *mc =
387 (struct soc_mixer_control *)kcontrol->private_value;
388 int session_id = mc->shift;
389 struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
390 struct msm_routing_data *priv = dev_get_drvdata(c->dev);
391 struct session_data *session = &priv->sessions[session_id];
392
393 if (session->port_id == mc->reg)
394 ucontrol->value.integer.value[0] = 1;
395 else
396 ucontrol->value.integer.value[0] = 0;
397
398 return 0;
399}
400
401static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
403{
404 struct snd_soc_dapm_context *dapm =
405 snd_soc_dapm_kcontrol_dapm(kcontrol);
406 struct snd_soc_component *c = snd_soc_dapm_to_component(dapm);
407 struct msm_routing_data *data = dev_get_drvdata(c->dev);
408 struct soc_mixer_control *mc =
409 (struct soc_mixer_control *)kcontrol->private_value;
410 struct snd_soc_dapm_update *update = NULL;
411 int be_id = mc->reg;
412 int session_id = mc->shift;
413 struct session_data *session = &data->sessions[session_id];
414
415 if (ucontrol->value.integer.value[0]) {
416 session->port_id = be_id;
417 snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update);
418 } else {
419 session->port_id = -1;
420 snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update);
421 }
422
423 return 1;
424}
425
426static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
427 Q6ROUTING_RX_MIXERS(HDMI_RX) };
428
429static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
430 Q6ROUTING_RX_MIXERS(PRIMARY_MI2S_RX) };
431
432static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
433 Q6ROUTING_RX_MIXERS(SECONDARY_MI2S_RX) };
434
435static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
436 Q6ROUTING_RX_MIXERS(QUATERNARY_MI2S_RX) };
437
438static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = {
439 Q6ROUTING_RX_MIXERS(TERTIARY_MI2S_RX) };
440
441static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
442 Q6ROUTING_RX_MIXERS(SLIMBUS_0_RX) };
443
444static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
445 Q6ROUTING_RX_MIXERS(SLIMBUS_1_RX) };
446
447static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
448 Q6ROUTING_RX_MIXERS(SLIMBUS_2_RX) };
449
450static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
451 Q6ROUTING_RX_MIXERS(SLIMBUS_3_RX) };
452
453static const struct snd_kcontrol_new slimbus_4_rx_mixer_controls[] = {
454 Q6ROUTING_RX_MIXERS(SLIMBUS_4_RX) };
455
456static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = {
457 Q6ROUTING_RX_MIXERS(SLIMBUS_5_RX) };
458
459static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = {
460 Q6ROUTING_RX_MIXERS(SLIMBUS_6_RX) };
461
462static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = {
463 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_0) };
464
465static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = {
466 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_1) };
467
468static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = {
469 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_2) };
470
471static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = {
472 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_3) };
473
474static const struct snd_kcontrol_new pri_tdm_rx_4_mixer_controls[] = {
475 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_4) };
476
477static const struct snd_kcontrol_new pri_tdm_rx_5_mixer_controls[] = {
478 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_5) };
479
480static const struct snd_kcontrol_new pri_tdm_rx_6_mixer_controls[] = {
481 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_6) };
482
483static const struct snd_kcontrol_new pri_tdm_rx_7_mixer_controls[] = {
484 Q6ROUTING_RX_MIXERS(PRIMARY_TDM_RX_7) };
485
486static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = {
487 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_0) };
488
489static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = {
490 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_1) };
491
492static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = {
493 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_2) };
494
495static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = {
496 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_3) };
497
498static const struct snd_kcontrol_new sec_tdm_rx_4_mixer_controls[] = {
499 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_4) };
500
501static const struct snd_kcontrol_new sec_tdm_rx_5_mixer_controls[] = {
502 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_5) };
503
504static const struct snd_kcontrol_new sec_tdm_rx_6_mixer_controls[] = {
505 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_6) };
506
507static const struct snd_kcontrol_new sec_tdm_rx_7_mixer_controls[] = {
508 Q6ROUTING_RX_MIXERS(SECONDARY_TDM_RX_7) };
509
510static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = {
511 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_0) };
512
513static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = {
514 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_1) };
515
516static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = {
517 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_2) };
518
519static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = {
520 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_3) };
521
522static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = {
523 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_4) };
524
525static const struct snd_kcontrol_new tert_tdm_rx_5_mixer_controls[] = {
526 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_5) };
527
528static const struct snd_kcontrol_new tert_tdm_rx_6_mixer_controls[] = {
529 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_6) };
530
531static const struct snd_kcontrol_new tert_tdm_rx_7_mixer_controls[] = {
532 Q6ROUTING_RX_MIXERS(TERTIARY_TDM_RX_7) };
533
534static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = {
535 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_0) };
536
537static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = {
538 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_1) };
539
540static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = {
541 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_2) };
542
543static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = {
544 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_3) };
545
546static const struct snd_kcontrol_new quat_tdm_rx_4_mixer_controls[] = {
547 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_4) };
548
549static const struct snd_kcontrol_new quat_tdm_rx_5_mixer_controls[] = {
550 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_5) };
551
552static const struct snd_kcontrol_new quat_tdm_rx_6_mixer_controls[] = {
553 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_6) };
554
555static const struct snd_kcontrol_new quat_tdm_rx_7_mixer_controls[] = {
556 Q6ROUTING_RX_MIXERS(QUATERNARY_TDM_RX_7) };
557
558static const struct snd_kcontrol_new quin_tdm_rx_0_mixer_controls[] = {
559 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_0) };
560
561static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = {
562 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_1) };
563
564static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = {
565 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_2) };
566
567static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = {
568 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_3) };
569
570static const struct snd_kcontrol_new quin_tdm_rx_4_mixer_controls[] = {
571 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_4) };
572
573static const struct snd_kcontrol_new quin_tdm_rx_5_mixer_controls[] = {
574 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_5) };
575
576static const struct snd_kcontrol_new quin_tdm_rx_6_mixer_controls[] = {
577 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_6) };
578
579static const struct snd_kcontrol_new quin_tdm_rx_7_mixer_controls[] = {
580 Q6ROUTING_RX_MIXERS(QUINARY_TDM_RX_7) };
581
582
583static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
584 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA1) };
585
586static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
587 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA2) };
588
589static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
590 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA3) };
591
592static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
593 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA4) };
594
595static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
596 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA5) };
597
598static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
599 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA6) };
600
601static const struct snd_kcontrol_new mmul7_mixer_controls[] = {
602 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA7) };
603
604static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
605 Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA8) };
606
607static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
608 /* Frontend AIF */
609 SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
610 SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
611 SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
612 SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
613 SND_SOC_DAPM_AIF_IN("MM_DL5", "MultiMedia5 Playback", 0, 0, 0, 0),
614 SND_SOC_DAPM_AIF_IN("MM_DL6", "MultiMedia6 Playback", 0, 0, 0, 0),
615 SND_SOC_DAPM_AIF_IN("MM_DL7", "MultiMedia7 Playback", 0, 0, 0, 0),
616 SND_SOC_DAPM_AIF_IN("MM_DL8", "MultiMedia8 Playback", 0, 0, 0, 0),
617 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
618 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
619 SND_SOC_DAPM_AIF_OUT("MM_UL3", "MultiMedia3 Capture", 0, 0, 0, 0),
620 SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0),
621 SND_SOC_DAPM_AIF_OUT("MM_UL5", "MultiMedia5 Capture", 0, 0, 0, 0),
622 SND_SOC_DAPM_AIF_OUT("MM_UL6", "MultiMedia6 Capture", 0, 0, 0, 0),
623 SND_SOC_DAPM_AIF_OUT("MM_UL7", "MultiMedia7 Capture", 0, 0, 0, 0),
624 SND_SOC_DAPM_AIF_OUT("MM_UL8", "MultiMedia8 Capture", 0, 0, 0, 0),
625
626 /* Mixer definitions */
627 SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
628 hdmi_mixer_controls,
629 ARRAY_SIZE(hdmi_mixer_controls)),
630
631 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
632 slimbus_rx_mixer_controls,
633 ARRAY_SIZE(slimbus_rx_mixer_controls)),
634 SND_SOC_DAPM_MIXER("SLIMBUS_1_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
635 slimbus_1_rx_mixer_controls,
636 ARRAY_SIZE(slimbus_1_rx_mixer_controls)),
637 SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
638 slimbus_2_rx_mixer_controls,
639 ARRAY_SIZE(slimbus_2_rx_mixer_controls)),
640 SND_SOC_DAPM_MIXER("SLIMBUS_3_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
641 slimbus_3_rx_mixer_controls,
642 ARRAY_SIZE(slimbus_3_rx_mixer_controls)),
643 SND_SOC_DAPM_MIXER("SLIMBUS_4_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
644 slimbus_4_rx_mixer_controls,
645 ARRAY_SIZE(slimbus_4_rx_mixer_controls)),
646 SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
647 slimbus_5_rx_mixer_controls,
648 ARRAY_SIZE(slimbus_5_rx_mixer_controls)),
649 SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
650 slimbus_6_rx_mixer_controls,
651 ARRAY_SIZE(slimbus_6_rx_mixer_controls)),
652 SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
653 primary_mi2s_rx_mixer_controls,
654 ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
655 SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
656 secondary_mi2s_rx_mixer_controls,
657 ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
658 SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
659 quaternary_mi2s_rx_mixer_controls,
660 ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)),
661 SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
662 tertiary_mi2s_rx_mixer_controls,
663 ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)),
664 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
665 pri_tdm_rx_0_mixer_controls,
666 ARRAY_SIZE(pri_tdm_rx_0_mixer_controls)),
667 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
668 pri_tdm_rx_1_mixer_controls,
669 ARRAY_SIZE(pri_tdm_rx_1_mixer_controls)),
670 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
671 pri_tdm_rx_2_mixer_controls,
672 ARRAY_SIZE(pri_tdm_rx_2_mixer_controls)),
673 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
674 pri_tdm_rx_3_mixer_controls,
675 ARRAY_SIZE(pri_tdm_rx_3_mixer_controls)),
676 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
677 pri_tdm_rx_4_mixer_controls,
678 ARRAY_SIZE(pri_tdm_rx_4_mixer_controls)),
679 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
680 pri_tdm_rx_5_mixer_controls,
681 ARRAY_SIZE(pri_tdm_rx_5_mixer_controls)),
682 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
683 pri_tdm_rx_6_mixer_controls,
684 ARRAY_SIZE(pri_tdm_rx_6_mixer_controls)),
685 SND_SOC_DAPM_MIXER("PRIMARY_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
686 pri_tdm_rx_7_mixer_controls,
687 ARRAY_SIZE(pri_tdm_rx_7_mixer_controls)),
688
689 SND_SOC_DAPM_MIXER("SEC_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
690 sec_tdm_rx_0_mixer_controls,
691 ARRAY_SIZE(sec_tdm_rx_0_mixer_controls)),
692 SND_SOC_DAPM_MIXER("SEC_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
693 sec_tdm_rx_1_mixer_controls,
694 ARRAY_SIZE(sec_tdm_rx_1_mixer_controls)),
695 SND_SOC_DAPM_MIXER("SEC_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
696 sec_tdm_rx_2_mixer_controls,
697 ARRAY_SIZE(sec_tdm_rx_2_mixer_controls)),
698 SND_SOC_DAPM_MIXER("SEC_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
699 sec_tdm_rx_3_mixer_controls,
700 ARRAY_SIZE(sec_tdm_rx_3_mixer_controls)),
701 SND_SOC_DAPM_MIXER("SEC_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
702 sec_tdm_rx_4_mixer_controls,
703 ARRAY_SIZE(sec_tdm_rx_4_mixer_controls)),
704 SND_SOC_DAPM_MIXER("SEC_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
705 sec_tdm_rx_5_mixer_controls,
706 ARRAY_SIZE(sec_tdm_rx_5_mixer_controls)),
707 SND_SOC_DAPM_MIXER("SEC_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
708 sec_tdm_rx_6_mixer_controls,
709 ARRAY_SIZE(sec_tdm_rx_6_mixer_controls)),
710 SND_SOC_DAPM_MIXER("SEC_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
711 sec_tdm_rx_7_mixer_controls,
712 ARRAY_SIZE(sec_tdm_rx_7_mixer_controls)),
713
714 SND_SOC_DAPM_MIXER("TERT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
715 tert_tdm_rx_0_mixer_controls,
716 ARRAY_SIZE(tert_tdm_rx_0_mixer_controls)),
717 SND_SOC_DAPM_MIXER("TERT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
718 tert_tdm_rx_1_mixer_controls,
719 ARRAY_SIZE(tert_tdm_rx_1_mixer_controls)),
720 SND_SOC_DAPM_MIXER("TERT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
721 tert_tdm_rx_2_mixer_controls,
722 ARRAY_SIZE(tert_tdm_rx_2_mixer_controls)),
723 SND_SOC_DAPM_MIXER("TERT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
724 tert_tdm_rx_3_mixer_controls,
725 ARRAY_SIZE(tert_tdm_rx_3_mixer_controls)),
726 SND_SOC_DAPM_MIXER("TERT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
727 tert_tdm_rx_4_mixer_controls,
728 ARRAY_SIZE(tert_tdm_rx_4_mixer_controls)),
729 SND_SOC_DAPM_MIXER("TERT_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
730 tert_tdm_rx_5_mixer_controls,
731 ARRAY_SIZE(tert_tdm_rx_5_mixer_controls)),
732 SND_SOC_DAPM_MIXER("TERT_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
733 tert_tdm_rx_6_mixer_controls,
734 ARRAY_SIZE(tert_tdm_rx_6_mixer_controls)),
735 SND_SOC_DAPM_MIXER("TERT_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
736 tert_tdm_rx_7_mixer_controls,
737 ARRAY_SIZE(tert_tdm_rx_7_mixer_controls)),
738
739 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
740 quat_tdm_rx_0_mixer_controls,
741 ARRAY_SIZE(quat_tdm_rx_0_mixer_controls)),
742 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
743 quat_tdm_rx_1_mixer_controls,
744 ARRAY_SIZE(quat_tdm_rx_1_mixer_controls)),
745 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
746 quat_tdm_rx_2_mixer_controls,
747 ARRAY_SIZE(quat_tdm_rx_2_mixer_controls)),
748 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
749 quat_tdm_rx_3_mixer_controls,
750 ARRAY_SIZE(quat_tdm_rx_3_mixer_controls)),
751 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
752 quat_tdm_rx_4_mixer_controls,
753 ARRAY_SIZE(quat_tdm_rx_4_mixer_controls)),
754 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
755 quat_tdm_rx_5_mixer_controls,
756 ARRAY_SIZE(quat_tdm_rx_5_mixer_controls)),
757 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
758 quat_tdm_rx_6_mixer_controls,
759 ARRAY_SIZE(quat_tdm_rx_6_mixer_controls)),
760 SND_SOC_DAPM_MIXER("QUAT_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
761 quat_tdm_rx_7_mixer_controls,
762 ARRAY_SIZE(quat_tdm_rx_7_mixer_controls)),
763
764 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
765 quin_tdm_rx_0_mixer_controls,
766 ARRAY_SIZE(quin_tdm_rx_0_mixer_controls)),
767 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
768 quin_tdm_rx_1_mixer_controls,
769 ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)),
770 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
771 quin_tdm_rx_2_mixer_controls,
772 ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)),
773 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
774 quin_tdm_rx_3_mixer_controls,
775 ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)),
776 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
777 quin_tdm_rx_4_mixer_controls,
778 ARRAY_SIZE(quin_tdm_rx_4_mixer_controls)),
779 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
780 quin_tdm_rx_5_mixer_controls,
781 ARRAY_SIZE(quin_tdm_rx_5_mixer_controls)),
782 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
783 quin_tdm_rx_6_mixer_controls,
784 ARRAY_SIZE(quin_tdm_rx_6_mixer_controls)),
785 SND_SOC_DAPM_MIXER("QUIN_TDM_RX_7 Audio Mixer", SND_SOC_NOPM, 0, 0,
786 quin_tdm_rx_7_mixer_controls,
787 ARRAY_SIZE(quin_tdm_rx_7_mixer_controls)),
788 SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
789 mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
790 SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
791 mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
792 SND_SOC_DAPM_MIXER("MultiMedia3 Mixer", SND_SOC_NOPM, 0, 0,
793 mmul3_mixer_controls, ARRAY_SIZE(mmul3_mixer_controls)),
794 SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0,
795 mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)),
796 SND_SOC_DAPM_MIXER("MultiMedia5 Mixer", SND_SOC_NOPM, 0, 0,
797 mmul5_mixer_controls, ARRAY_SIZE(mmul5_mixer_controls)),
798 SND_SOC_DAPM_MIXER("MultiMedia6 Mixer", SND_SOC_NOPM, 0, 0,
799 mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)),
800 SND_SOC_DAPM_MIXER("MultiMedia7 Mixer", SND_SOC_NOPM, 0, 0,
801 mmul7_mixer_controls, ARRAY_SIZE(mmul7_mixer_controls)),
802 SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
803 mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
804
805};
806
807static const struct snd_soc_dapm_route intercon[] = {
808 Q6ROUTING_RX_DAPM_ROUTE("HDMI Mixer", "HDMI_RX"),
809 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_0_RX Audio Mixer", "SLIMBUS_0_RX"),
810 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_1_RX Audio Mixer", "SLIMBUS_1_RX"),
811 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_2_RX Audio Mixer", "SLIMBUS_2_RX"),
812 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_3_RX Audio Mixer", "SLIMBUS_3_RX"),
813 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_4_RX Audio Mixer", "SLIMBUS_4_RX"),
814 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_5_RX Audio Mixer", "SLIMBUS_5_RX"),
815 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_6_RX Audio Mixer", "SLIMBUS_6_RX"),
816 Q6ROUTING_RX_DAPM_ROUTE("QUAT_MI2S_RX Audio Mixer", "QUAT_MI2S_RX"),
817 Q6ROUTING_RX_DAPM_ROUTE("TERT_MI2S_RX Audio Mixer", "TERT_MI2S_RX"),
818 Q6ROUTING_RX_DAPM_ROUTE("SEC_MI2S_RX Audio Mixer", "SEC_MI2S_RX"),
819 Q6ROUTING_RX_DAPM_ROUTE("PRI_MI2S_RX Audio Mixer", "PRI_MI2S_RX"),
820 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_0 Audio Mixer",
821 "PRIMARY_TDM_RX_0"),
822 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_1 Audio Mixer",
823 "PRIMARY_TDM_RX_1"),
824 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_2 Audio Mixer",
825 "PRIMARY_TDM_RX_2"),
826 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_3 Audio Mixer",
827 "PRIMARY_TDM_RX_3"),
828 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_4 Audio Mixer",
829 "PRIMARY_TDM_RX_4"),
830 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_5 Audio Mixer",
831 "PRIMARY_TDM_RX_5"),
832 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_6 Audio Mixer",
833 "PRIMARY_TDM_RX_6"),
834 Q6ROUTING_RX_DAPM_ROUTE("PRIMARY_TDM_RX_7 Audio Mixer",
835 "PRIMARY_TDM_RX_7"),
836 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_0 Audio Mixer", "SEC_TDM_RX_0"),
837 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_1 Audio Mixer", "SEC_TDM_RX_1"),
838 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_2 Audio Mixer", "SEC_TDM_RX_2"),
839 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_3 Audio Mixer", "SEC_TDM_RX_3"),
840 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_4 Audio Mixer", "SEC_TDM_RX_4"),
841 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_5 Audio Mixer", "SEC_TDM_RX_5"),
842 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_6 Audio Mixer", "SEC_TDM_RX_6"),
843 Q6ROUTING_RX_DAPM_ROUTE("SEC_TDM_RX_7 Audio Mixer", "SEC_TDM_RX_7"),
844 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_0 Audio Mixer", "TERT_TDM_RX_0"),
845 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_1 Audio Mixer", "TERT_TDM_RX_1"),
846 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_2 Audio Mixer", "TERT_TDM_RX_2"),
847 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_3 Audio Mixer", "TERT_TDM_RX_3"),
848 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_4 Audio Mixer", "TERT_TDM_RX_4"),
849 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_5 Audio Mixer", "TERT_TDM_RX_5"),
850 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_6 Audio Mixer", "TERT_TDM_RX_6"),
851 Q6ROUTING_RX_DAPM_ROUTE("TERT_TDM_RX_7 Audio Mixer", "TERT_TDM_RX_7"),
852 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_0 Audio Mixer", "QUAT_TDM_RX_0"),
853 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_1 Audio Mixer", "QUAT_TDM_RX_1"),
854 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_2 Audio Mixer", "QUAT_TDM_RX_2"),
855 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_3 Audio Mixer", "QUAT_TDM_RX_3"),
856 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_4 Audio Mixer", "QUAT_TDM_RX_4"),
857 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_5 Audio Mixer", "QUAT_TDM_RX_5"),
858 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_6 Audio Mixer", "QUAT_TDM_RX_6"),
859 Q6ROUTING_RX_DAPM_ROUTE("QUAT_TDM_RX_7 Audio Mixer", "QUAT_TDM_RX_7"),
860 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_0 Audio Mixer", "QUIN_TDM_RX_0"),
861 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_1 Audio Mixer", "QUIN_TDM_RX_1"),
862 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_2 Audio Mixer", "QUIN_TDM_RX_2"),
863 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_3 Audio Mixer", "QUIN_TDM_RX_3"),
864 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_4 Audio Mixer", "QUIN_TDM_RX_4"),
865 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_5 Audio Mixer", "QUIN_TDM_RX_5"),
866 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_6 Audio Mixer", "QUIN_TDM_RX_6"),
867 Q6ROUTING_RX_DAPM_ROUTE("QUIN_TDM_RX_7 Audio Mixer", "QUIN_TDM_RX_7"),
868 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia1 Mixer"),
869 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia2 Mixer"),
870 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia3 Mixer"),
871 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia4 Mixer"),
872 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia5 Mixer"),
873 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia6 Mixer"),
874 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia7 Mixer"),
875 Q6ROUTING_TX_DAPM_ROUTE("MultiMedia8 Mixer"),
876
877 {"MM_UL1", NULL, "MultiMedia1 Mixer"},
878 {"MM_UL2", NULL, "MultiMedia2 Mixer"},
879 {"MM_UL3", NULL, "MultiMedia3 Mixer"},
880 {"MM_UL4", NULL, "MultiMedia4 Mixer"},
881 {"MM_UL5", NULL, "MultiMedia5 Mixer"},
882 {"MM_UL6", NULL, "MultiMedia6 Mixer"},
883 {"MM_UL7", NULL, "MultiMedia7 Mixer"},
884 {"MM_UL8", NULL, "MultiMedia8 Mixer"},
885};
886
887static int routing_hw_params(struct snd_pcm_substream *substream,
888 struct snd_pcm_hw_params *params)
889{
890 struct snd_soc_pcm_runtime *rtd = substream->private_data;
891 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
892 struct msm_routing_data *data = dev_get_drvdata(c->dev);
893 unsigned int be_id = rtd->cpu_dai->id;
894 struct session_data *session;
895 int path_type;
896
897 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
898 path_type = ADM_PATH_PLAYBACK;
899 else
900 path_type = ADM_PATH_LIVE_REC;
901
902 if (be_id > AFE_MAX_PORTS)
903 return -EINVAL;
904
905 session = &data->port_data[be_id];
906
907 mutex_lock(&data->lock);
908
909 session->path_type = path_type;
910 session->sample_rate = params_rate(params);
911 session->channels = params_channels(params);
912
913 switch (params_format(params)) {
914 case SNDRV_PCM_FORMAT_S16_LE:
915 session->bits_per_sample = 16;
916 break;
917 case SNDRV_PCM_FORMAT_S24_LE:
918 session->bits_per_sample = 24;
919 break;
920 default:
921 break;
922 }
923
924 mutex_unlock(&data->lock);
925 return 0;
926}
927
928static struct snd_pcm_ops q6pcm_routing_ops = {
929 .hw_params = routing_hw_params,
930};
931
932static int msm_routing_probe(struct snd_soc_component *c)
933{
934 int i;
935
936 for (i = 0; i < MAX_SESSIONS; i++)
937 routing_data->sessions[i].port_id = -1;
938
939 return 0;
940}
941
942static const struct snd_soc_component_driver msm_soc_routing_component = {
943 .ops = &q6pcm_routing_ops,
944 .probe = msm_routing_probe,
945 .name = DRV_NAME,
946 .dapm_widgets = msm_qdsp6_widgets,
947 .num_dapm_widgets = ARRAY_SIZE(msm_qdsp6_widgets),
948 .dapm_routes = intercon,
949 .num_dapm_routes = ARRAY_SIZE(intercon),
950};
951
952static int q6routing_dai_bind(struct device *dev, struct device *master,
953 void *data)
954{
955 routing_data = kzalloc(sizeof(*routing_data), GFP_KERNEL);
956 if (!routing_data)
957 return -ENOMEM;
958
959 routing_data->dev = dev;
960
961 mutex_init(&routing_data->lock);
962 dev_set_drvdata(dev, routing_data);
963
964 return snd_soc_register_component(dev, &msm_soc_routing_component,
965 NULL, 0);
966}
967
968static void q6routing_dai_unbind(struct device *dev, struct device *master,
969 void *d)
970{
971 struct msm_routing_data *data = dev_get_drvdata(dev);
972
973 snd_soc_unregister_component(dev);
974
975 kfree(data);
976
977 routing_data = NULL;
978}
979
980static const struct component_ops q6routing_dai_comp_ops = {
981 .bind = q6routing_dai_bind,
982 .unbind = q6routing_dai_unbind,
983};
984
985static int q6pcm_routing_probe(struct platform_device *pdev)
986{
987 return component_add(&pdev->dev, &q6routing_dai_comp_ops);
988}
989
990static int q6pcm_routing_remove(struct platform_device *pdev)
991{
992 component_del(&pdev->dev, &q6routing_dai_comp_ops);
993 return 0;
994}
995
996static struct platform_driver q6pcm_routing_platform_driver = {
997 .driver = {
998 .name = "q6routing",
999 },
1000 .probe = q6pcm_routing_probe,
1001 .remove = q6pcm_routing_remove,
1002};
1003module_platform_driver(q6pcm_routing_platform_driver);
1004
1005MODULE_DESCRIPTION("Q6 Routing platform");
1006MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6routing.h b/sound/soc/qcom/qdsp6/q6routing.h
new file mode 100644
index 000000000000..35514e651130
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6routing.h
@@ -0,0 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _Q6_PCM_ROUTING_H
3#define _Q6_PCM_ROUTING_H
4
5int q6routing_stream_open(int fedai_id, int perf_mode,
6 int stream_id, int stream_type);
7void q6routing_stream_close(int fedai_id, int stream_type);
8
9#endif /*_Q6_PCM_ROUTING_H */
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index 9a10181a0811..f184168f9a41 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -220,45 +220,6 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
220 return 0; 220 return 0;
221} 221}
222 222
223static int rockchip_sound_cdndp_hw_params(struct snd_pcm_substream *substream,
224 struct snd_pcm_hw_params *params)
225{
226 struct snd_soc_pcm_runtime *rtd = substream->private_data;
227 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
228 struct snd_soc_dai *codec_dai = rtd->codec_dai;
229 int mclk, ret;
230
231 /* in bypass mode, the mclk has to be one of the frequencies below */
232 switch (params_rate(params)) {
233 case 8000:
234 case 16000:
235 case 24000:
236 case 32000:
237 case 48000:
238 case 64000:
239 case 96000:
240 mclk = 12288000;
241 break;
242 case 11025:
243 case 22050:
244 case 44100:
245 case 88200:
246 mclk = 11289600;
247 break;
248 default:
249 return -EINVAL;
250 }
251
252 ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
253 SND_SOC_CLOCK_OUT);
254 if (ret < 0) {
255 dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
256 return ret;
257 }
258
259 return 0;
260}
261
262static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, 223static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
263 struct snd_pcm_hw_params *params) 224 struct snd_pcm_hw_params *params)
264{ 225{
@@ -293,10 +254,6 @@ static const struct snd_soc_ops rockchip_sound_da7219_ops = {
293 .hw_params = rockchip_sound_da7219_hw_params, 254 .hw_params = rockchip_sound_da7219_hw_params,
294}; 255};
295 256
296static const struct snd_soc_ops rockchip_sound_cdndp_ops = {
297 .hw_params = rockchip_sound_cdndp_hw_params,
298};
299
300static const struct snd_soc_ops rockchip_sound_dmic_ops = { 257static const struct snd_soc_ops rockchip_sound_dmic_ops = {
301 .hw_params = rockchip_sound_dmic_hw_params, 258 .hw_params = rockchip_sound_dmic_hw_params,
302}; 259};
@@ -323,8 +280,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
323 [DAILINK_CDNDP] = { 280 [DAILINK_CDNDP] = {
324 .name = "DP", 281 .name = "DP",
325 .stream_name = "DP PCM", 282 .stream_name = "DP PCM",
326 .codec_dai_name = "i2s-hifi", 283 .codec_dai_name = "spdif-hifi",
327 .ops = &rockchip_sound_cdndp_ops,
328 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 284 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
329 SND_SOC_DAIFMT_CBS_CFS, 285 SND_SOC_DAIFMT_CBS_CFS,
330 }, 286 },
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 1aa5cd77ca24..0ae0800bf3a8 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -1,5 +1,5 @@
1menu "SoC Audio support for SuperH" 1menu "SoC Audio support for Renesas SoCs"
2 depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST 2 depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
3 3
4config SND_SOC_PCM_SH7760 4config SND_SOC_PCM_SH7760
5 tristate "SoC Audio support for Renesas SH7760" 5 tristate "SoC Audio support for Renesas SH7760"
@@ -28,7 +28,7 @@ config SND_SOC_SH4_FSI
28 28
29config SND_SOC_SH4_SIU 29config SND_SOC_SH4_SIU
30 tristate 30 tristate
31 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK 31 depends on ARCH_SHMOBILE && HAVE_CLK
32 select DMA_ENGINE 32 select DMA_ENGINE
33 select DMADEVICES 33 select DMADEVICES
34 select SH_DMAE 34 select SH_DMAE
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
index f1d4fb566892..4221937ae79b 100644
--- a/sound/soc/sh/rcar/cmd.c
+++ b/sound/soc/sh/rcar/cmd.c
@@ -125,6 +125,13 @@ static struct rsnd_mod_ops rsnd_cmd_ops = {
125 .stop = rsnd_cmd_stop, 125 .stop = rsnd_cmd_stop,
126}; 126};
127 127
128static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
129{
130 if (WARN_ON(id < 0 || id >= rsnd_cmd_nr(priv)))
131 id = 0;
132
133 return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id);
134}
128int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id) 135int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id)
129{ 136{
130 struct rsnd_priv *priv = rsnd_io_to_priv(io); 137 struct rsnd_priv *priv = rsnd_io_to_priv(io);
@@ -133,14 +140,6 @@ int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id)
133 return rsnd_dai_connect(mod, io, mod->type); 140 return rsnd_dai_connect(mod, io, mod->type);
134} 141}
135 142
136struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
137{
138 if (WARN_ON(id < 0 || id >= rsnd_cmd_nr(priv)))
139 id = 0;
140
141 return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id);
142}
143
144int rsnd_cmd_probe(struct rsnd_priv *priv) 143int rsnd_cmd_probe(struct rsnd_priv *priv)
145{ 144{
146 struct device *dev = rsnd_priv_to_dev(priv); 145 struct device *dev = rsnd_priv_to_dev(priv);
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 94f081b93258..af04d41a4274 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -111,7 +111,7 @@
111static const struct of_device_id rsnd_of_match[] = { 111static const struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, 112 { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, 113 { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 },
114 { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */ 114 { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 },
115 {}, 115 {},
116}; 116};
117MODULE_DEVICE_TABLE(of, rsnd_of_match); 117MODULE_DEVICE_TABLE(of, rsnd_of_match);
@@ -1352,6 +1352,37 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
1352#define PREALLOC_BUFFER (32 * 1024) 1352#define PREALLOC_BUFFER (32 * 1024)
1353#define PREALLOC_BUFFER_MAX (32 * 1024) 1353#define PREALLOC_BUFFER_MAX (32 * 1024)
1354 1354
1355static int rsnd_preallocate_pages(struct snd_soc_pcm_runtime *rtd,
1356 struct rsnd_dai_stream *io,
1357 int stream)
1358{
1359 struct rsnd_priv *priv = rsnd_io_to_priv(io);
1360 struct device *dev = rsnd_priv_to_dev(priv);
1361 struct snd_pcm_substream *substream;
1362 int err;
1363
1364 /*
1365 * use Audio-DMAC dev if we can use IPMMU
1366 * see
1367 * rsnd_dmaen_attach()
1368 */
1369 if (io->dmac_dev)
1370 dev = io->dmac_dev;
1371
1372 for (substream = rtd->pcm->streams[stream].substream;
1373 substream;
1374 substream = substream->next) {
1375 err = snd_pcm_lib_preallocate_pages(substream,
1376 SNDRV_DMA_TYPE_DEV,
1377 dev,
1378 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
1379 if (err < 0)
1380 return err;
1381 }
1382
1383 return 0;
1384}
1385
1355static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) 1386static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
1356{ 1387{
1357 struct snd_soc_dai *dai = rtd->cpu_dai; 1388 struct snd_soc_dai *dai = rtd->cpu_dai;
@@ -1366,11 +1397,17 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
1366 if (ret) 1397 if (ret)
1367 return ret; 1398 return ret;
1368 1399
1369 return snd_pcm_lib_preallocate_pages_for_all( 1400 ret = rsnd_preallocate_pages(rtd, &rdai->playback,
1370 rtd->pcm, 1401 SNDRV_PCM_STREAM_PLAYBACK);
1371 SNDRV_DMA_TYPE_DEV, 1402 if (ret)
1372 rtd->card->snd_card->dev, 1403 return ret;
1373 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); 1404
1405 ret = rsnd_preallocate_pages(rtd, &rdai->capture,
1406 SNDRV_PCM_STREAM_CAPTURE);
1407 if (ret)
1408 return ret;
1409
1410 return 0;
1374} 1411}
1375 1412
1376static const struct snd_soc_component_driver rsnd_soc_component = { 1413static const struct snd_soc_component_driver rsnd_soc_component = {
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 41de23417c4a..ef82b94d038b 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -253,6 +253,13 @@ static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
253 return -EAGAIN; 253 return -EAGAIN;
254 } 254 }
255 255
256 /*
257 * use it for IPMMU if needed
258 * see
259 * rsnd_preallocate_pages()
260 */
261 io->dmac_dev = chan->device->dev;
262
256 dma_release_channel(chan); 263 dma_release_channel(chan);
257 264
258 dmac->dmaen_num++; 265 dmac->dmaen_num++;
@@ -695,7 +702,7 @@ static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
695 702
696 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to); 703 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
697 704
698 /* for Gen2 */ 705 /* for Gen2 or later */
699 if (mod_from && mod_to) { 706 if (mod_from && mod_to) {
700 ops = &rsnd_dmapp_ops; 707 ops = &rsnd_dmapp_ops;
701 attach = rsnd_dmapp_attach; 708 attach = rsnd_dmapp_attach;
@@ -773,7 +780,7 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
773 return 0; 780 return 0;
774 781
775 /* 782 /*
776 * for Gen2 783 * for Gen2 or later
777 */ 784 */
778 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); 785 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
779 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL); 786 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index f04c4100043a..25642e92dae0 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -414,7 +414,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv)
414 ret = -ENODEV; 414 ret = -ENODEV;
415 if (rsnd_is_gen1(priv)) 415 if (rsnd_is_gen1(priv))
416 ret = rsnd_gen1_probe(priv); 416 ret = rsnd_gen1_probe(priv);
417 else if (rsnd_is_gen2(priv)) 417 else if (rsnd_is_gen2(priv) ||
418 rsnd_is_gen3(priv))
418 ret = rsnd_gen2_probe(priv); 419 ret = rsnd_gen2_probe(priv);
419 420
420 if (ret < 0) 421 if (ret < 0)
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 172c8d612890..6d7280d2d9be 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -435,6 +435,7 @@ struct rsnd_dai_stream {
435 struct snd_pcm_substream *substream; 435 struct snd_pcm_substream *substream;
436 struct rsnd_mod *mod[RSND_MOD_MAX]; 436 struct rsnd_mod *mod[RSND_MOD_MAX];
437 struct rsnd_dai *rdai; 437 struct rsnd_dai *rdai;
438 struct device *dmac_dev; /* for IPMMU */
438 u32 parent_ssi_status; 439 u32 parent_ssi_status;
439}; 440};
440#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) 441#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
@@ -538,6 +539,7 @@ struct rsnd_priv {
538#define RSND_GEN_MASK (0xF << 0) 539#define RSND_GEN_MASK (0xF << 0)
539#define RSND_GEN1 (1 << 0) 540#define RSND_GEN1 (1 << 0)
540#define RSND_GEN2 (2 << 0) 541#define RSND_GEN2 (2 << 0)
542#define RSND_GEN3 (3 << 0)
541 543
542 /* 544 /*
543 * below value will be filled on rsnd_gen_probe() 545 * below value will be filled on rsnd_gen_probe()
@@ -609,6 +611,7 @@ struct rsnd_priv {
609 611
610#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) 612#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1)
611#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) 613#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2)
614#define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3)
612 615
613#define rsnd_flags_has(p, f) ((p)->flags & (f)) 616#define rsnd_flags_has(p, f) ((p)->flags & (f))
614#define rsnd_flags_set(p, f) ((p)->flags |= (f)) 617#define rsnd_flags_set(p, f) ((p)->flags |= (f))
@@ -775,7 +778,6 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
775int rsnd_cmd_probe(struct rsnd_priv *priv); 778int rsnd_cmd_probe(struct rsnd_priv *priv);
776void rsnd_cmd_remove(struct rsnd_priv *priv); 779void rsnd_cmd_remove(struct rsnd_priv *priv);
777int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); 780int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
778struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id);
779 781
780void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 782void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
781#ifdef DEBUG 783#ifdef DEBUG
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 333b802681ad..9538f76f8e20 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -171,7 +171,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
171 if (status & bit) 171 if (status & bit)
172 return; 172 return;
173 173
174 udelay(50); 174 udelay(5);
175 } 175 }
176 176
177 dev_warn(dev, "%s[%d] status check failed\n", 177 dev_warn(dev, "%s[%d] status check failed\n",
@@ -1004,19 +1004,26 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
1004 struct device *dev = rsnd_priv_to_dev(priv); 1004 struct device *dev = rsnd_priv_to_dev(priv);
1005 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); 1005 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
1006 struct rsnd_ssi *ssi; 1006 struct rsnd_ssi *ssi;
1007 struct device_node *remote_node = of_graph_get_port_parent(remote_ep);
1008
1009 /* support Gen3 only */
1010 if (!rsnd_is_gen3(priv))
1011 return;
1007 1012
1008 if (!mod) 1013 if (!mod)
1009 return; 1014 return;
1010 1015
1011 ssi = rsnd_mod_to_ssi(mod); 1016 ssi = rsnd_mod_to_ssi(mod);
1012 1017
1013 if (strstr(remote_ep->full_name, "hdmi0")) { 1018 /* HDMI0 */
1019 if (strstr(remote_node->full_name, "hdmi@fead0000")) {
1014 rsnd_flags_set(ssi, RSND_SSI_HDMI0); 1020 rsnd_flags_set(ssi, RSND_SSI_HDMI0);
1015 dev_dbg(dev, "%s[%d] connected to HDMI0\n", 1021 dev_dbg(dev, "%s[%d] connected to HDMI0\n",
1016 rsnd_mod_name(mod), rsnd_mod_id(mod)); 1022 rsnd_mod_name(mod), rsnd_mod_id(mod));
1017 } 1023 }
1018 1024
1019 if (strstr(remote_ep->full_name, "hdmi1")) { 1025 /* HDMI1 */
1026 if (strstr(remote_node->full_name, "hdmi@feae0000")) {
1020 rsnd_flags_set(ssi, RSND_SSI_HDMI1); 1027 rsnd_flags_set(ssi, RSND_SSI_HDMI1);
1021 dev_dbg(dev, "%s[%d] connected to HDMI1\n", 1028 dev_dbg(dev, "%s[%d] connected to HDMI1\n",
1022 rsnd_mod_name(mod), rsnd_mod_id(mod)); 1029 rsnd_mod_name(mod), rsnd_mod_id(mod));
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
deleted file mode 100644
index 07f43356f963..000000000000
--- a/sound/soc/soc-cache.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * soc-cache.c -- ASoC register cache helpers
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <sound/soc.h>
15#include <linux/export.h>
16#include <linux/slab.h>
17
18int snd_soc_cache_init(struct snd_soc_codec *codec)
19{
20 const struct snd_soc_codec_driver *codec_drv = codec->driver;
21 size_t reg_size;
22
23 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
24
25 if (!reg_size)
26 return 0;
27
28 dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
29 codec->component.name);
30
31 if (codec_drv->reg_cache_default)
32 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
33 reg_size, GFP_KERNEL);
34 else
35 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
36 if (!codec->reg_cache)
37 return -ENOMEM;
38
39 return 0;
40}
41
42/*
43 * NOTE: keep in mind that this function might be called
44 * multiple times.
45 */
46int snd_soc_cache_exit(struct snd_soc_codec *codec)
47{
48 dev_dbg(codec->dev, "ASoC: Destroying cache for %s codec\n",
49 codec->component.name);
50 kfree(codec->reg_cache);
51 codec->reg_cache = NULL;
52 return 0;
53}
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 82402688bd8e..e095115fa9f9 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -26,56 +26,79 @@
26#include <sound/initval.h> 26#include <sound/initval.h>
27#include <sound/soc-dpcm.h> 27#include <sound/soc-dpcm.h>
28 28
29static int soc_compr_open(struct snd_compr_stream *cstream) 29static int soc_compr_components_open(struct snd_compr_stream *cstream,
30 struct snd_soc_component **last)
30{ 31{
31 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 32 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
32 struct snd_soc_platform *platform = rtd->platform;
33 struct snd_soc_component *component; 33 struct snd_soc_component *component;
34 struct snd_soc_rtdcom_list *rtdcom; 34 struct snd_soc_rtdcom_list *rtdcom;
35 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 35 int ret;
36 int ret = 0, __ret;
37 36
38 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 37 for_each_rtdcom(rtd, rtdcom) {
38 component = rtdcom->component;
39 39
40 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) { 40 if (!component->driver->compr_ops ||
41 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai); 41 !component->driver->compr_ops->open)
42 if (ret < 0) { 42 continue;
43 dev_err(cpu_dai->dev,
44 "Compress ASoC: can't open interface %s: %d\n",
45 cpu_dai->name, ret);
46 goto out;
47 }
48 }
49 43
50 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) { 44 ret = component->driver->compr_ops->open(cstream);
51 ret = platform->driver->compr_ops->open(cstream);
52 if (ret < 0) { 45 if (ret < 0) {
53 dev_err(platform->dev, 46 dev_err(component->dev,
54 "Compress ASoC: can't open platform %s: %d\n", 47 "Compress ASoC: can't open platform %s: %d\n",
55 platform->component.name, ret); 48 component->name, ret);
56 goto plat_err; 49
50 *last = component;
51 return ret;
57 } 52 }
58 } 53 }
59 54
55 *last = NULL;
56 return 0;
57}
58
59static int soc_compr_components_free(struct snd_compr_stream *cstream,
60 struct snd_soc_component *last)
61{
62 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
63 struct snd_soc_component *component;
64 struct snd_soc_rtdcom_list *rtdcom;
65
60 for_each_rtdcom(rtd, rtdcom) { 66 for_each_rtdcom(rtd, rtdcom) {
61 component = rtdcom->component; 67 component = rtdcom->component;
62 68
63 /* ignore duplication for now */ 69 if (component == last)
64 if (platform && (component == &platform->component)) 70 break;
65 continue;
66 71
67 if (!component->driver->compr_ops || 72 if (!component->driver->compr_ops ||
68 !component->driver->compr_ops->open) 73 !component->driver->compr_ops->free)
69 continue; 74 continue;
70 75
71 __ret = component->driver->compr_ops->open(cstream); 76 component->driver->compr_ops->free(cstream);
72 if (__ret < 0) { 77 }
73 dev_err(component->dev, 78
74 "Compress ASoC: can't open platform %s: %d\n", 79 return 0;
75 component->name, __ret); 80}
76 ret = __ret; 81
82static int soc_compr_open(struct snd_compr_stream *cstream)
83{
84 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
85 struct snd_soc_component *component;
86 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
87 int ret;
88
89 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
90
91 if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
92 ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
93 if (ret < 0) {
94 dev_err(cpu_dai->dev,
95 "Compress ASoC: can't open interface %s: %d\n",
96 cpu_dai->name, ret);
97 goto out;
77 } 98 }
78 } 99 }
100
101 ret = soc_compr_components_open(cstream, &component);
79 if (ret < 0) 102 if (ret < 0)
80 goto machine_err; 103 goto machine_err;
81 104
@@ -96,23 +119,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
96 return 0; 119 return 0;
97 120
98machine_err: 121machine_err:
99 for_each_rtdcom(rtd, rtdcom) { 122 soc_compr_components_free(cstream, component);
100 component = rtdcom->component;
101
102 /* ignore duplication for now */
103 if (platform && (component == &platform->component))
104 continue;
105
106 if (!component->driver->compr_ops ||
107 !component->driver->compr_ops->free)
108 continue;
109 123
110 component->driver->compr_ops->free(cstream);
111 }
112
113 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
114 platform->driver->compr_ops->free(cstream);
115plat_err:
116 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) 124 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
117 cpu_dai->driver->cops->shutdown(cstream, cpu_dai); 125 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
118out: 126out:
@@ -125,14 +133,12 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
125 struct snd_soc_pcm_runtime *fe = cstream->private_data; 133 struct snd_soc_pcm_runtime *fe = cstream->private_data;
126 struct snd_pcm_substream *fe_substream = 134 struct snd_pcm_substream *fe_substream =
127 fe->pcm->streams[cstream->direction].substream; 135 fe->pcm->streams[cstream->direction].substream;
128 struct snd_soc_platform *platform = fe->platform;
129 struct snd_soc_component *component; 136 struct snd_soc_component *component;
130 struct snd_soc_rtdcom_list *rtdcom;
131 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 137 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
132 struct snd_soc_dpcm *dpcm; 138 struct snd_soc_dpcm *dpcm;
133 struct snd_soc_dapm_widget_list *list; 139 struct snd_soc_dapm_widget_list *list;
134 int stream; 140 int stream;
135 int ret = 0, __ret; 141 int ret;
136 142
137 if (cstream->direction == SND_COMPRESS_PLAYBACK) 143 if (cstream->direction == SND_COMPRESS_PLAYBACK)
138 stream = SNDRV_PCM_STREAM_PLAYBACK; 144 stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -151,35 +157,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
151 } 157 }
152 } 158 }
153 159
154 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) { 160 ret = soc_compr_components_open(cstream, &component);
155 ret = platform->driver->compr_ops->open(cstream);
156 if (ret < 0) {
157 dev_err(platform->dev,
158 "Compress ASoC: can't open platform %s: %d\n",
159 platform->component.name, ret);
160 goto plat_err;
161 }
162 }
163
164 for_each_rtdcom(fe, rtdcom) {
165 component = rtdcom->component;
166
167 /* ignore duplication for now */
168 if (platform && (component == &platform->component))
169 continue;
170
171 if (!component->driver->compr_ops ||
172 !component->driver->compr_ops->open)
173 continue;
174
175 __ret = component->driver->compr_ops->open(cstream);
176 if (__ret < 0) {
177 dev_err(component->dev,
178 "Compress ASoC: can't open platform %s: %d\n",
179 component->name, __ret);
180 ret = __ret;
181 }
182 }
183 if (ret < 0) 161 if (ret < 0)
184 goto machine_err; 162 goto machine_err;
185 163
@@ -235,23 +213,8 @@ fe_err:
235 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown) 213 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
236 fe->dai_link->compr_ops->shutdown(cstream); 214 fe->dai_link->compr_ops->shutdown(cstream);
237machine_err: 215machine_err:
238 for_each_rtdcom(fe, rtdcom) { 216 soc_compr_components_free(cstream, component);
239 component = rtdcom->component;
240
241 /* ignore duplication for now */
242 if (platform && (component == &platform->component))
243 continue;
244 217
245 if (!component->driver->compr_ops ||
246 !component->driver->compr_ops->free)
247 continue;
248
249 component->driver->compr_ops->free(cstream);
250 }
251
252 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
253 platform->driver->compr_ops->free(cstream);
254plat_err:
255 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) 218 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
256 cpu_dai->driver->cops->shutdown(cstream, cpu_dai); 219 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
257out: 220out:
@@ -292,9 +255,6 @@ static void close_delayed_work(struct work_struct *work)
292static int soc_compr_free(struct snd_compr_stream *cstream) 255static int soc_compr_free(struct snd_compr_stream *cstream)
293{ 256{
294 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 257 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
295 struct snd_soc_platform *platform = rtd->platform;
296 struct snd_soc_component *component;
297 struct snd_soc_rtdcom_list *rtdcom;
298 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 258 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
299 struct snd_soc_dai *codec_dai = rtd->codec_dai; 259 struct snd_soc_dai *codec_dai = rtd->codec_dai;
300 int stream; 260 int stream;
@@ -319,22 +279,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
319 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown) 279 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
320 rtd->dai_link->compr_ops->shutdown(cstream); 280 rtd->dai_link->compr_ops->shutdown(cstream);
321 281
322 for_each_rtdcom(rtd, rtdcom) { 282 soc_compr_components_free(cstream, NULL);
323 component = rtdcom->component;
324
325 /* ignore duplication for now */
326 if (platform && (component == &platform->component))
327 continue;
328
329 if (!component->driver->compr_ops ||
330 !component->driver->compr_ops->free)
331 continue;
332
333 component->driver->compr_ops->free(cstream);
334 }
335
336 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
337 platform->driver->compr_ops->free(cstream);
338 283
339 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) 284 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
340 cpu_dai->driver->cops->shutdown(cstream, cpu_dai); 285 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
@@ -342,8 +287,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
342 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 287 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
343 if (snd_soc_runtime_ignore_pmdown_time(rtd)) { 288 if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
344 snd_soc_dapm_stream_event(rtd, 289 snd_soc_dapm_stream_event(rtd,
345 SNDRV_PCM_STREAM_PLAYBACK, 290 SNDRV_PCM_STREAM_PLAYBACK,
346 SND_SOC_DAPM_STREAM_STOP); 291 SND_SOC_DAPM_STREAM_STOP);
347 } else { 292 } else {
348 rtd->pop_wait = 1; 293 rtd->pop_wait = 1;
349 queue_delayed_work(system_power_efficient_wq, 294 queue_delayed_work(system_power_efficient_wq,
@@ -353,8 +298,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
353 } else { 298 } else {
354 /* capture streams can be powered down now */ 299 /* capture streams can be powered down now */
355 snd_soc_dapm_stream_event(rtd, 300 snd_soc_dapm_stream_event(rtd,
356 SNDRV_PCM_STREAM_CAPTURE, 301 SNDRV_PCM_STREAM_CAPTURE,
357 SND_SOC_DAPM_STREAM_STOP); 302 SND_SOC_DAPM_STREAM_STOP);
358 } 303 }
359 304
360 mutex_unlock(&rtd->pcm_mutex); 305 mutex_unlock(&rtd->pcm_mutex);
@@ -364,9 +309,6 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
364static int soc_compr_free_fe(struct snd_compr_stream *cstream) 309static int soc_compr_free_fe(struct snd_compr_stream *cstream)
365{ 310{
366 struct snd_soc_pcm_runtime *fe = cstream->private_data; 311 struct snd_soc_pcm_runtime *fe = cstream->private_data;
367 struct snd_soc_platform *platform = fe->platform;
368 struct snd_soc_component *component;
369 struct snd_soc_rtdcom_list *rtdcom;
370 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 312 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
371 struct snd_soc_dpcm *dpcm; 313 struct snd_soc_dpcm *dpcm;
372 int stream, ret; 314 int stream, ret;
@@ -404,22 +346,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
404 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown) 346 if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
405 fe->dai_link->compr_ops->shutdown(cstream); 347 fe->dai_link->compr_ops->shutdown(cstream);
406 348
407 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free) 349 soc_compr_components_free(cstream, NULL);
408 platform->driver->compr_ops->free(cstream);
409
410 for_each_rtdcom(fe, rtdcom) {
411 component = rtdcom->component;
412
413 /* ignore duplication for now */
414 if (platform && (component == &platform->component))
415 continue;
416
417 if (!component->driver->compr_ops ||
418 !component->driver->compr_ops->free)
419 continue;
420
421 component->driver->compr_ops->free(cstream);
422 }
423 350
424 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown) 351 if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
425 cpu_dai->driver->cops->shutdown(cstream, cpu_dai); 352 cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
@@ -432,7 +359,6 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
432{ 359{
433 360
434 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 361 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
435 struct snd_soc_platform *platform = rtd->platform;
436 struct snd_soc_component *component; 362 struct snd_soc_component *component;
437 struct snd_soc_rtdcom_list *rtdcom; 363 struct snd_soc_rtdcom_list *rtdcom;
438 struct snd_soc_dai *codec_dai = rtd->codec_dai; 364 struct snd_soc_dai *codec_dai = rtd->codec_dai;
@@ -441,19 +367,9 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
441 367
442 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 368 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
443 369
444 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
445 ret = platform->driver->compr_ops->trigger(cstream, cmd);
446 if (ret < 0)
447 goto out;
448 }
449
450 for_each_rtdcom(rtd, rtdcom) { 370 for_each_rtdcom(rtd, rtdcom) {
451 component = rtdcom->component; 371 component = rtdcom->component;
452 372
453 /* ignore duplication for now */
454 if (platform && (component == &platform->component))
455 continue;
456
457 if (!component->driver->compr_ops || 373 if (!component->driver->compr_ops ||
458 !component->driver->compr_ops->trigger) 374 !component->driver->compr_ops->trigger)
459 continue; 375 continue;
@@ -485,7 +401,6 @@ out:
485static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) 401static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
486{ 402{
487 struct snd_soc_pcm_runtime *fe = cstream->private_data; 403 struct snd_soc_pcm_runtime *fe = cstream->private_data;
488 struct snd_soc_platform *platform = fe->platform;
489 struct snd_soc_component *component; 404 struct snd_soc_component *component;
490 struct snd_soc_rtdcom_list *rtdcom; 405 struct snd_soc_rtdcom_list *rtdcom;
491 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 406 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
@@ -494,19 +409,9 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
494 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN || 409 if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
495 cmd == SND_COMPR_TRIGGER_DRAIN) { 410 cmd == SND_COMPR_TRIGGER_DRAIN) {
496 411
497 if (platform &&
498 platform->driver->compr_ops &&
499 platform->driver->compr_ops->trigger)
500 return platform->driver->compr_ops->trigger(cstream,
501 cmd);
502
503 for_each_rtdcom(fe, rtdcom) { 412 for_each_rtdcom(fe, rtdcom) {
504 component = rtdcom->component; 413 component = rtdcom->component;
505 414
506 /* ignore duplication for now */
507 if (platform && (component == &platform->component))
508 continue;
509
510 if (!component->driver->compr_ops || 415 if (!component->driver->compr_ops ||
511 !component->driver->compr_ops->trigger) 416 !component->driver->compr_ops->trigger)
512 continue; 417 continue;
@@ -523,7 +428,6 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
523 else 428 else
524 stream = SNDRV_PCM_STREAM_CAPTURE; 429 stream = SNDRV_PCM_STREAM_CAPTURE;
525 430
526
527 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 431 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
528 432
529 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) { 433 if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger) {
@@ -532,19 +436,9 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
532 goto out; 436 goto out;
533 } 437 }
534 438
535 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
536 ret = platform->driver->compr_ops->trigger(cstream, cmd);
537 if (ret < 0)
538 goto out;
539 }
540
541 for_each_rtdcom(fe, rtdcom) { 439 for_each_rtdcom(fe, rtdcom) {
542 component = rtdcom->component; 440 component = rtdcom->component;
543 441
544 /* ignore duplication for now */
545 if (platform && (component == &platform->component))
546 continue;
547
548 if (!component->driver->compr_ops || 442 if (!component->driver->compr_ops ||
549 !component->driver->compr_ops->trigger) 443 !component->driver->compr_ops->trigger)
550 continue; 444 continue;
@@ -585,7 +479,6 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
585 struct snd_compr_params *params) 479 struct snd_compr_params *params)
586{ 480{
587 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 481 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
588 struct snd_soc_platform *platform = rtd->platform;
589 struct snd_soc_component *component; 482 struct snd_soc_component *component;
590 struct snd_soc_rtdcom_list *rtdcom; 483 struct snd_soc_rtdcom_list *rtdcom;
591 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 484 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -593,11 +486,12 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
593 486
594 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 487 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
595 488
596 /* first we call set_params for the platform driver 489 /*
597 * this should configure the soc side 490 * First we call set_params for the CPU DAI, then the component
598 * if the machine has compressed ops then we call that as well 491 * driver this should configure the SoC side. If the machine has
599 * expectation is that platform and machine will configure everything 492 * compressed ops then we call that as well. The expectation is
600 * for this compress path, like configuring pcm port for codec 493 * that these callbacks will configure everything for this compress
494 * path, like configuring a PCM port for a CODEC.
601 */ 495 */
602 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) { 496 if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_params) {
603 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai); 497 ret = cpu_dai->driver->cops->set_params(cstream, params, cpu_dai);
@@ -605,19 +499,9 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
605 goto err; 499 goto err;
606 } 500 }
607 501
608 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
609 ret = platform->driver->compr_ops->set_params(cstream, params);
610 if (ret < 0)
611 goto err;
612 }
613
614 for_each_rtdcom(rtd, rtdcom) { 502 for_each_rtdcom(rtd, rtdcom) {
615 component = rtdcom->component; 503 component = rtdcom->component;
616 504
617 /* ignore duplication for now */
618 if (platform && (component == &platform->component))
619 continue;
620
621 if (!component->driver->compr_ops || 505 if (!component->driver->compr_ops ||
622 !component->driver->compr_ops->set_params) 506 !component->driver->compr_ops->set_params)
623 continue; 507 continue;
@@ -637,10 +521,10 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
637 521
638 if (cstream->direction == SND_COMPRESS_PLAYBACK) 522 if (cstream->direction == SND_COMPRESS_PLAYBACK)
639 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 523 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
640 SND_SOC_DAPM_STREAM_START); 524 SND_SOC_DAPM_STREAM_START);
641 else 525 else
642 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, 526 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
643 SND_SOC_DAPM_STREAM_START); 527 SND_SOC_DAPM_STREAM_START);
644 528
645 /* cancel any delayed stream shutdown that is pending */ 529 /* cancel any delayed stream shutdown that is pending */
646 rtd->pop_wait = 0; 530 rtd->pop_wait = 0;
@@ -656,12 +540,11 @@ err:
656} 540}
657 541
658static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, 542static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
659 struct snd_compr_params *params) 543 struct snd_compr_params *params)
660{ 544{
661 struct snd_soc_pcm_runtime *fe = cstream->private_data; 545 struct snd_soc_pcm_runtime *fe = cstream->private_data;
662 struct snd_pcm_substream *fe_substream = 546 struct snd_pcm_substream *fe_substream =
663 fe->pcm->streams[cstream->direction].substream; 547 fe->pcm->streams[cstream->direction].substream;
664 struct snd_soc_platform *platform = fe->platform;
665 struct snd_soc_component *component; 548 struct snd_soc_component *component;
666 struct snd_soc_rtdcom_list *rtdcom; 549 struct snd_soc_rtdcom_list *rtdcom;
667 struct snd_soc_dai *cpu_dai = fe->cpu_dai; 550 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
@@ -680,19 +563,9 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
680 goto out; 563 goto out;
681 } 564 }
682 565
683 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
684 ret = platform->driver->compr_ops->set_params(cstream, params);
685 if (ret < 0)
686 goto out;
687 }
688
689 for_each_rtdcom(fe, rtdcom) { 566 for_each_rtdcom(fe, rtdcom) {
690 component = rtdcom->component; 567 component = rtdcom->component;
691 568
692 /* ignore duplication for now */
693 if (platform && (component == &platform->component))
694 continue;
695
696 if (!component->driver->compr_ops || 569 if (!component->driver->compr_ops ||
697 !component->driver->compr_ops->set_params) 570 !component->driver->compr_ops->set_params)
698 continue; 571 continue;
@@ -738,10 +611,9 @@ out:
738} 611}
739 612
740static int soc_compr_get_params(struct snd_compr_stream *cstream, 613static int soc_compr_get_params(struct snd_compr_stream *cstream,
741 struct snd_codec *params) 614 struct snd_codec *params)
742{ 615{
743 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 616 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
744 struct snd_soc_platform *platform = rtd->platform;
745 struct snd_soc_component *component; 617 struct snd_soc_component *component;
746 struct snd_soc_rtdcom_list *rtdcom; 618 struct snd_soc_rtdcom_list *rtdcom;
747 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 619 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -755,19 +627,9 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
755 goto err; 627 goto err;
756 } 628 }
757 629
758 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_params) {
759 ret = platform->driver->compr_ops->get_params(cstream, params);
760 if (ret < 0)
761 goto err;
762 }
763
764 for_each_rtdcom(rtd, rtdcom) { 630 for_each_rtdcom(rtd, rtdcom) {
765 component = rtdcom->component; 631 component = rtdcom->component;
766 632
767 /* ignore duplication for now */
768 if (platform && (component == &platform->component))
769 continue;
770
771 if (!component->driver->compr_ops || 633 if (!component->driver->compr_ops ||
772 !component->driver->compr_ops->get_params) 634 !component->driver->compr_ops->get_params)
773 continue; 635 continue;
@@ -783,29 +645,18 @@ err:
783} 645}
784 646
785static int soc_compr_get_caps(struct snd_compr_stream *cstream, 647static int soc_compr_get_caps(struct snd_compr_stream *cstream,
786 struct snd_compr_caps *caps) 648 struct snd_compr_caps *caps)
787{ 649{
788 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 650 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
789 struct snd_soc_platform *platform = rtd->platform;
790 struct snd_soc_component *component; 651 struct snd_soc_component *component;
791 struct snd_soc_rtdcom_list *rtdcom; 652 struct snd_soc_rtdcom_list *rtdcom;
792 int ret = 0, __ret; 653 int ret = 0, __ret;
793 654
794 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 655 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
795 656
796 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_caps) {
797 ret = platform->driver->compr_ops->get_caps(cstream, caps);
798 if (ret < 0)
799 goto err;
800 }
801
802 for_each_rtdcom(rtd, rtdcom) { 657 for_each_rtdcom(rtd, rtdcom) {
803 component = rtdcom->component; 658 component = rtdcom->component;
804 659
805 /* ignore duplication for now */
806 if (platform && (component == &platform->component))
807 continue;
808
809 if (!component->driver->compr_ops || 660 if (!component->driver->compr_ops ||
810 !component->driver->compr_ops->get_caps) 661 !component->driver->compr_ops->get_caps)
811 continue; 662 continue;
@@ -815,35 +666,23 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
815 ret = __ret; 666 ret = __ret;
816 } 667 }
817 668
818err:
819 mutex_unlock(&rtd->pcm_mutex); 669 mutex_unlock(&rtd->pcm_mutex);
820 return ret; 670 return ret;
821} 671}
822 672
823static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream, 673static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
824 struct snd_compr_codec_caps *codec) 674 struct snd_compr_codec_caps *codec)
825{ 675{
826 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 676 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
827 struct snd_soc_platform *platform = rtd->platform;
828 struct snd_soc_component *component; 677 struct snd_soc_component *component;
829 struct snd_soc_rtdcom_list *rtdcom; 678 struct snd_soc_rtdcom_list *rtdcom;
830 int ret = 0, __ret; 679 int ret = 0, __ret;
831 680
832 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 681 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
833 682
834 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) {
835 ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
836 if (ret < 0)
837 goto err;
838 }
839
840 for_each_rtdcom(rtd, rtdcom) { 683 for_each_rtdcom(rtd, rtdcom) {
841 component = rtdcom->component; 684 component = rtdcom->component;
842 685
843 /* ignore duplication for now */
844 if (platform && (component == &platform->component))
845 continue;
846
847 if (!component->driver->compr_ops || 686 if (!component->driver->compr_ops ||
848 !component->driver->compr_ops->get_codec_caps) 687 !component->driver->compr_ops->get_codec_caps)
849 continue; 688 continue;
@@ -853,7 +692,6 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
853 ret = __ret; 692 ret = __ret;
854 } 693 }
855 694
856err:
857 mutex_unlock(&rtd->pcm_mutex); 695 mutex_unlock(&rtd->pcm_mutex);
858 return ret; 696 return ret;
859} 697}
@@ -861,7 +699,6 @@ err:
861static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes) 699static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
862{ 700{
863 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 701 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
864 struct snd_soc_platform *platform = rtd->platform;
865 struct snd_soc_component *component; 702 struct snd_soc_component *component;
866 struct snd_soc_rtdcom_list *rtdcom; 703 struct snd_soc_rtdcom_list *rtdcom;
867 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 704 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -875,19 +712,9 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
875 goto err; 712 goto err;
876 } 713 }
877 714
878 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->ack) {
879 ret = platform->driver->compr_ops->ack(cstream, bytes);
880 if (ret < 0)
881 goto err;
882 }
883
884 for_each_rtdcom(rtd, rtdcom) { 715 for_each_rtdcom(rtd, rtdcom) {
885 component = rtdcom->component; 716 component = rtdcom->component;
886 717
887 /* ignore duplication for now */
888 if (platform && (component == &platform->component))
889 continue;
890
891 if (!component->driver->compr_ops || 718 if (!component->driver->compr_ops ||
892 !component->driver->compr_ops->ack) 719 !component->driver->compr_ops->ack)
893 continue; 720 continue;
@@ -903,10 +730,9 @@ err:
903} 730}
904 731
905static int soc_compr_pointer(struct snd_compr_stream *cstream, 732static int soc_compr_pointer(struct snd_compr_stream *cstream,
906 struct snd_compr_tstamp *tstamp) 733 struct snd_compr_tstamp *tstamp)
907{ 734{
908 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 735 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
909 struct snd_soc_platform *platform = rtd->platform;
910 struct snd_soc_component *component; 736 struct snd_soc_component *component;
911 struct snd_soc_rtdcom_list *rtdcom; 737 struct snd_soc_rtdcom_list *rtdcom;
912 int ret = 0, __ret; 738 int ret = 0, __ret;
@@ -917,19 +743,9 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
917 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer) 743 if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
918 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai); 744 cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
919 745
920 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->pointer) {
921 ret = platform->driver->compr_ops->pointer(cstream, tstamp);
922 if (ret < 0)
923 goto err;
924 }
925
926 for_each_rtdcom(rtd, rtdcom) { 746 for_each_rtdcom(rtd, rtdcom) {
927 component = rtdcom->component; 747 component = rtdcom->component;
928 748
929 /* ignore duplication for now */
930 if (platform && (component == &platform->component))
931 continue;
932
933 if (!component->driver->compr_ops || 749 if (!component->driver->compr_ops ||
934 !component->driver->compr_ops->pointer) 750 !component->driver->compr_ops->pointer)
935 continue; 751 continue;
@@ -939,7 +755,6 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
939 ret = __ret; 755 ret = __ret;
940 } 756 }
941 757
942err:
943 mutex_unlock(&rtd->pcm_mutex); 758 mutex_unlock(&rtd->pcm_mutex);
944 return ret; 759 return ret;
945} 760}
@@ -948,26 +763,15 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
948 char __user *buf, size_t count) 763 char __user *buf, size_t count)
949{ 764{
950 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 765 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
951 struct snd_soc_platform *platform = rtd->platform;
952 struct snd_soc_component *component; 766 struct snd_soc_component *component;
953 struct snd_soc_rtdcom_list *rtdcom; 767 struct snd_soc_rtdcom_list *rtdcom;
954 int ret = 0; 768 int ret = 0;
955 769
956 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 770 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
957 771
958 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy) {
959 ret = platform->driver->compr_ops->copy(cstream, buf, count);
960 if (ret < 0)
961 goto err;
962 }
963
964 for_each_rtdcom(rtd, rtdcom) { 772 for_each_rtdcom(rtd, rtdcom) {
965 component = rtdcom->component; 773 component = rtdcom->component;
966 774
967 /* ignore duplication for now */
968 if (platform && (component == &platform->component))
969 continue;
970
971 if (!component->driver->compr_ops || 775 if (!component->driver->compr_ops ||
972 !component->driver->compr_ops->copy) 776 !component->driver->compr_ops->copy)
973 continue; 777 continue;
@@ -976,16 +780,14 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
976 break; 780 break;
977 } 781 }
978 782
979err:
980 mutex_unlock(&rtd->pcm_mutex); 783 mutex_unlock(&rtd->pcm_mutex);
981 return ret; 784 return ret;
982} 785}
983 786
984static int soc_compr_set_metadata(struct snd_compr_stream *cstream, 787static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
985 struct snd_compr_metadata *metadata) 788 struct snd_compr_metadata *metadata)
986{ 789{
987 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 790 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
988 struct snd_soc_platform *platform = rtd->platform;
989 struct snd_soc_component *component; 791 struct snd_soc_component *component;
990 struct snd_soc_rtdcom_list *rtdcom; 792 struct snd_soc_rtdcom_list *rtdcom;
991 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 793 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -997,19 +799,9 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
997 return ret; 799 return ret;
998 } 800 }
999 801
1000 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) {
1001 ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
1002 if (ret < 0)
1003 return ret;
1004 }
1005
1006 for_each_rtdcom(rtd, rtdcom) { 802 for_each_rtdcom(rtd, rtdcom) {
1007 component = rtdcom->component; 803 component = rtdcom->component;
1008 804
1009 /* ignore duplication for now */
1010 if (platform && (component == &platform->component))
1011 continue;
1012
1013 if (!component->driver->compr_ops || 805 if (!component->driver->compr_ops ||
1014 !component->driver->compr_ops->set_metadata) 806 !component->driver->compr_ops->set_metadata)
1015 continue; 807 continue;
@@ -1023,10 +815,9 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
1023} 815}
1024 816
1025static int soc_compr_get_metadata(struct snd_compr_stream *cstream, 817static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
1026 struct snd_compr_metadata *metadata) 818 struct snd_compr_metadata *metadata)
1027{ 819{
1028 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 820 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
1029 struct snd_soc_platform *platform = rtd->platform;
1030 struct snd_soc_component *component; 821 struct snd_soc_component *component;
1031 struct snd_soc_rtdcom_list *rtdcom; 822 struct snd_soc_rtdcom_list *rtdcom;
1032 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 823 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -1038,19 +829,9 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
1038 return ret; 829 return ret;
1039 } 830 }
1040 831
1041 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) {
1042 ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
1043 if (ret < 0)
1044 return ret;
1045 }
1046
1047 for_each_rtdcom(rtd, rtdcom) { 832 for_each_rtdcom(rtd, rtdcom) {
1048 component = rtdcom->component; 833 component = rtdcom->component;
1049 834
1050 /* ignore duplication for now */
1051 if (platform && (component == &platform->component))
1052 continue;
1053
1054 if (!component->driver->compr_ops || 835 if (!component->driver->compr_ops ||
1055 !component->driver->compr_ops->get_metadata) 836 !component->driver->compr_ops->get_metadata)
1056 continue; 837 continue;
@@ -1103,7 +884,6 @@ static struct snd_compr_ops soc_compr_dyn_ops = {
1103 */ 884 */
1104int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 885int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
1105{ 886{
1106 struct snd_soc_platform *platform = rtd->platform;
1107 struct snd_soc_component *component; 887 struct snd_soc_component *component;
1108 struct snd_soc_rtdcom_list *rtdcom; 888 struct snd_soc_rtdcom_list *rtdcom;
1109 struct snd_soc_dai *codec_dai = rtd->codec_dai; 889 struct snd_soc_dai *codec_dai = rtd->codec_dai;
@@ -1184,26 +964,17 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
1184 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); 964 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
1185 } 965 }
1186 966
1187
1188 /* Add copy callback for not memory mapped DSPs */
1189 if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy)
1190 compr->ops->copy = soc_compr_copy;
1191
1192 for_each_rtdcom(rtd, rtdcom) { 967 for_each_rtdcom(rtd, rtdcom) {
1193 component = rtdcom->component; 968 component = rtdcom->component;
1194 969
1195 /* ignore duplication for now */
1196 if (platform && (component == &platform->component))
1197 continue;
1198
1199 if (!component->driver->compr_ops || 970 if (!component->driver->compr_ops ||
1200 !component->driver->compr_ops->copy) 971 !component->driver->compr_ops->copy)
1201 continue; 972 continue;
1202 973
1203 compr->ops->copy = soc_compr_copy; 974 compr->ops->copy = soc_compr_copy;
975 break;
1204 } 976 }
1205 977
1206
1207 mutex_init(&compr->lock); 978 mutex_init(&compr->lock);
1208 ret = snd_compress_new(rtd->card->snd_card, num, direction, 979 ret = snd_compress_new(rtd->card->snd_card, num, direction,
1209 new_name, compr); 980 new_name, compr);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index bf7ca32ab31f..3d56f1fe5914 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -56,8 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
56#endif 56#endif
57 57
58static DEFINE_MUTEX(client_mutex); 58static DEFINE_MUTEX(client_mutex);
59static LIST_HEAD(platform_list);
60static LIST_HEAD(codec_list);
61static LIST_HEAD(component_list); 59static LIST_HEAD(component_list);
62 60
63/* 61/*
@@ -83,98 +81,6 @@ static const char * const dmi_blacklist[] = {
83 NULL, /* terminator */ 81 NULL, /* terminator */
84}; 82};
85 83
86/* returns the minimum number of bytes needed to represent
87 * a particular given value */
88static int min_bytes_needed(unsigned long val)
89{
90 int c = 0;
91 int i;
92
93 for (i = (sizeof val * 8) - 1; i >= 0; --i, ++c)
94 if (val & (1UL << i))
95 break;
96 c = (sizeof val * 8) - c;
97 if (!c || (c % 8))
98 c = (c + 8) / 8;
99 else
100 c /= 8;
101 return c;
102}
103
104/* fill buf which is 'len' bytes with a formatted
105 * string of the form 'reg: value\n' */
106static int format_register_str(struct snd_soc_codec *codec,
107 unsigned int reg, char *buf, size_t len)
108{
109 int wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
110 int regsize = codec->driver->reg_word_size * 2;
111 int ret;
112
113 /* +2 for ': ' and + 1 for '\n' */
114 if (wordsize + regsize + 2 + 1 != len)
115 return -EINVAL;
116
117 sprintf(buf, "%.*x: ", wordsize, reg);
118 buf += wordsize + 2;
119
120 ret = snd_soc_read(codec, reg);
121 if (ret < 0)
122 memset(buf, 'X', regsize);
123 else
124 sprintf(buf, "%.*x", regsize, ret);
125 buf[regsize] = '\n';
126 /* no NUL-termination needed */
127 return 0;
128}
129
130/* codec register dump */
131static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf,
132 size_t count, loff_t pos)
133{
134 int i, step = 1;
135 int wordsize, regsize;
136 int len;
137 size_t total = 0;
138 loff_t p = 0;
139
140 wordsize = min_bytes_needed(codec->driver->reg_cache_size) * 2;
141 regsize = codec->driver->reg_word_size * 2;
142
143 len = wordsize + regsize + 2 + 1;
144
145 if (!codec->driver->reg_cache_size)
146 return 0;
147
148 if (codec->driver->reg_cache_step)
149 step = codec->driver->reg_cache_step;
150
151 for (i = 0; i < codec->driver->reg_cache_size; i += step) {
152 /* only support larger than PAGE_SIZE bytes debugfs
153 * entries for the default case */
154 if (p >= pos) {
155 if (total + len >= count - 1)
156 break;
157 format_register_str(codec, i, buf + total, len);
158 total += len;
159 }
160 p += len;
161 }
162
163 total = min(total, count - 1);
164
165 return total;
166}
167
168static ssize_t codec_reg_show(struct device *dev,
169 struct device_attribute *attr, char *buf)
170{
171 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
172
173 return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0);
174}
175
176static DEVICE_ATTR_RO(codec_reg);
177
178static ssize_t pmdown_time_show(struct device *dev, 84static ssize_t pmdown_time_show(struct device *dev,
179 struct device_attribute *attr, char *buf) 85 struct device_attribute *attr, char *buf)
180{ 86{
@@ -200,7 +106,6 @@ static ssize_t pmdown_time_set(struct device *dev,
200static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set); 106static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
201 107
202static struct attribute *soc_dev_attrs[] = { 108static struct attribute *soc_dev_attrs[] = {
203 &dev_attr_codec_reg.attr,
204 &dev_attr_pmdown_time.attr, 109 &dev_attr_pmdown_time.attr,
205 NULL 110 NULL
206}; 111};
@@ -233,71 +138,6 @@ static const struct attribute_group *soc_dev_attr_groups[] = {
233}; 138};
234 139
235#ifdef CONFIG_DEBUG_FS 140#ifdef CONFIG_DEBUG_FS
236static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
237 size_t count, loff_t *ppos)
238{
239 ssize_t ret;
240 struct snd_soc_codec *codec = file->private_data;
241 char *buf;
242
243 if (*ppos < 0 || !count)
244 return -EINVAL;
245
246 buf = kmalloc(count, GFP_KERNEL);
247 if (!buf)
248 return -ENOMEM;
249
250 ret = soc_codec_reg_show(codec, buf, count, *ppos);
251 if (ret >= 0) {
252 if (copy_to_user(user_buf, buf, ret)) {
253 kfree(buf);
254 return -EFAULT;
255 }
256 *ppos += ret;
257 }
258
259 kfree(buf);
260 return ret;
261}
262
263static ssize_t codec_reg_write_file(struct file *file,
264 const char __user *user_buf, size_t count, loff_t *ppos)
265{
266 char buf[32];
267 size_t buf_size;
268 char *start = buf;
269 unsigned long reg, value;
270 struct snd_soc_codec *codec = file->private_data;
271 int ret;
272
273 buf_size = min(count, (sizeof(buf)-1));
274 if (copy_from_user(buf, user_buf, buf_size))
275 return -EFAULT;
276 buf[buf_size] = 0;
277
278 while (*start == ' ')
279 start++;
280 reg = simple_strtoul(start, &start, 16);
281 while (*start == ' ')
282 start++;
283 ret = kstrtoul(start, 16, &value);
284 if (ret)
285 return ret;
286
287 /* Userspace has been fiddling around behind the kernel's back */
288 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
289
290 snd_soc_write(codec, reg, value);
291 return buf_size;
292}
293
294static const struct file_operations codec_reg_fops = {
295 .open = simple_open,
296 .read = codec_reg_read_file,
297 .write = codec_reg_write_file,
298 .llseek = default_llseek,
299};
300
301static void soc_init_component_debugfs(struct snd_soc_component *component) 141static void soc_init_component_debugfs(struct snd_soc_component *component)
302{ 142{
303 if (!component->card->debugfs_card_root) 143 if (!component->card->debugfs_card_root)
@@ -326,9 +166,6 @@ static void soc_init_component_debugfs(struct snd_soc_component *component)
326 166
327 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component), 167 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
328 component->debugfs_root); 168 component->debugfs_root);
329
330 if (component->init_debugfs)
331 component->init_debugfs(component);
332} 169}
333 170
334static void soc_cleanup_component_debugfs(struct snd_soc_component *component) 171static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
@@ -336,34 +173,6 @@ static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
336 debugfs_remove_recursive(component->debugfs_root); 173 debugfs_remove_recursive(component->debugfs_root);
337} 174}
338 175
339static void soc_init_codec_debugfs(struct snd_soc_component *component)
340{
341 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
342 struct dentry *debugfs_reg;
343
344 debugfs_reg = debugfs_create_file("codec_reg", 0644,
345 codec->component.debugfs_root,
346 codec, &codec_reg_fops);
347 if (!debugfs_reg)
348 dev_warn(codec->dev,
349 "ASoC: Failed to create codec register debugfs file\n");
350}
351
352static int codec_list_show(struct seq_file *m, void *v)
353{
354 struct snd_soc_codec *codec;
355
356 mutex_lock(&client_mutex);
357
358 list_for_each_entry(codec, &codec_list, list)
359 seq_printf(m, "%s\n", codec->component.name);
360
361 mutex_unlock(&client_mutex);
362
363 return 0;
364}
365DEFINE_SHOW_ATTRIBUTE(codec_list);
366
367static int dai_list_show(struct seq_file *m, void *v) 176static int dai_list_show(struct seq_file *m, void *v)
368{ 177{
369 struct snd_soc_component *component; 178 struct snd_soc_component *component;
@@ -381,20 +190,20 @@ static int dai_list_show(struct seq_file *m, void *v)
381} 190}
382DEFINE_SHOW_ATTRIBUTE(dai_list); 191DEFINE_SHOW_ATTRIBUTE(dai_list);
383 192
384static int platform_list_show(struct seq_file *m, void *v) 193static int component_list_show(struct seq_file *m, void *v)
385{ 194{
386 struct snd_soc_platform *platform; 195 struct snd_soc_component *component;
387 196
388 mutex_lock(&client_mutex); 197 mutex_lock(&client_mutex);
389 198
390 list_for_each_entry(platform, &platform_list, list) 199 list_for_each_entry(component, &component_list, list)
391 seq_printf(m, "%s\n", platform->component.name); 200 seq_printf(m, "%s\n", component->name);
392 201
393 mutex_unlock(&client_mutex); 202 mutex_unlock(&client_mutex);
394 203
395 return 0; 204 return 0;
396} 205}
397DEFINE_SHOW_ATTRIBUTE(platform_list); 206DEFINE_SHOW_ATTRIBUTE(component_list);
398 207
399static void soc_init_card_debugfs(struct snd_soc_card *card) 208static void soc_init_card_debugfs(struct snd_soc_card *card)
400{ 209{
@@ -431,17 +240,13 @@ static void snd_soc_debugfs_init(void)
431 return; 240 return;
432 } 241 }
433 242
434 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
435 &codec_list_fops))
436 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
437
438 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL, 243 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
439 &dai_list_fops)) 244 &dai_list_fops))
440 pr_warn("ASoC: Failed to create DAI list debugfs file\n"); 245 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
441 246
442 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL, 247 if (!debugfs_create_file("components", 0444, snd_soc_debugfs_root, NULL,
443 &platform_list_fops)) 248 &component_list_fops))
444 pr_warn("ASoC: Failed to create platform list debugfs file\n"); 249 pr_warn("ASoC: Failed to create component list debugfs file\n");
445} 250}
446 251
447static void snd_soc_debugfs_exit(void) 252static void snd_soc_debugfs_exit(void)
@@ -451,8 +256,6 @@ static void snd_soc_debugfs_exit(void)
451 256
452#else 257#else
453 258
454#define soc_init_codec_debugfs NULL
455
456static inline void soc_init_component_debugfs( 259static inline void soc_init_component_debugfs(
457 struct snd_soc_component *component) 260 struct snd_soc_component *component)
458{ 261{
@@ -732,8 +535,8 @@ int snd_soc_suspend(struct device *dev)
732 } 535 }
733 536
734 case SND_SOC_BIAS_OFF: 537 case SND_SOC_BIAS_OFF:
735 if (component->suspend) 538 if (component->driver->suspend)
736 component->suspend(component); 539 component->driver->suspend(component);
737 component->suspended = 1; 540 component->suspended = 1;
738 if (component->regmap) 541 if (component->regmap)
739 regcache_mark_dirty(component->regmap); 542 regcache_mark_dirty(component->regmap);
@@ -804,8 +607,8 @@ static void soc_resume_deferred(struct work_struct *work)
804 607
805 list_for_each_entry(component, &card->component_dev_list, card_list) { 608 list_for_each_entry(component, &card->component_dev_list, card_list) {
806 if (component->suspended) { 609 if (component->suspended) {
807 if (component->resume) 610 if (component->driver->resume)
808 component->resume(component); 611 component->driver->resume(component);
809 component->suspended = 0; 612 component->suspended = 0;
810 } 613 }
811 } 614 }
@@ -1045,7 +848,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
1045 struct snd_soc_dai_link_component cpu_dai_component; 848 struct snd_soc_dai_link_component cpu_dai_component;
1046 struct snd_soc_component *component; 849 struct snd_soc_component *component;
1047 struct snd_soc_dai **codec_dais; 850 struct snd_soc_dai **codec_dais;
1048 struct snd_soc_platform *platform;
1049 struct device_node *platform_of_node; 851 struct device_node *platform_of_node;
1050 const char *platform_name; 852 const char *platform_name;
1051 int i; 853 int i;
@@ -1089,7 +891,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
1089 891
1090 /* Single codec links expect codec and codec_dai in runtime data */ 892 /* Single codec links expect codec and codec_dai in runtime data */
1091 rtd->codec_dai = codec_dais[0]; 893 rtd->codec_dai = codec_dais[0];
1092 rtd->codec = rtd->codec_dai->codec;
1093 894
1094 /* if there's no platform we match on the empty platform */ 895 /* if there's no platform we match on the empty platform */
1095 platform_name = dai_link->platform_name; 896 platform_name = dai_link->platform_name;
@@ -1113,23 +914,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
1113 snd_soc_rtdcom_add(rtd, component); 914 snd_soc_rtdcom_add(rtd, component);
1114 } 915 }
1115 916
1116 /* find one from the set of registered platforms */
1117 list_for_each_entry(platform, &platform_list, list) {
1118 platform_of_node = platform->dev->of_node;
1119 if (!platform_of_node && platform->dev->parent->of_node)
1120 platform_of_node = platform->dev->parent->of_node;
1121
1122 if (dai_link->platform_of_node) {
1123 if (platform_of_node != dai_link->platform_of_node)
1124 continue;
1125 } else {
1126 if (strcmp(platform->component.name, platform_name))
1127 continue;
1128 }
1129
1130 rtd->platform = platform;
1131 }
1132
1133 soc_add_pcm_runtime(card, rtd); 917 soc_add_pcm_runtime(card, rtd);
1134 return 0; 918 return 0;
1135 919
@@ -1145,8 +929,8 @@ static void soc_remove_component(struct snd_soc_component *component)
1145 929
1146 list_del(&component->card_list); 930 list_del(&component->card_list);
1147 931
1148 if (component->remove) 932 if (component->driver->remove)
1149 component->remove(component); 933 component->driver->remove(component);
1150 934
1151 snd_soc_dapm_free(snd_soc_component_get_dapm(component)); 935 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
1152 936
@@ -1421,7 +1205,12 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1421 1205
1422 for (i = 0; i < card->num_configs; i++) { 1206 for (i = 0; i < card->num_configs; i++) {
1423 struct snd_soc_codec_conf *map = &card->codec_conf[i]; 1207 struct snd_soc_codec_conf *map = &card->codec_conf[i];
1424 if (map->of_node && component->dev->of_node != map->of_node) 1208 struct device_node *component_of_node = component->dev->of_node;
1209
1210 if (!component_of_node && component->dev->parent)
1211 component_of_node = component->dev->parent->of_node;
1212
1213 if (map->of_node && component_of_node != map->of_node)
1425 continue; 1214 continue;
1426 if (map->dev_name && strcmp(component->name, map->dev_name)) 1215 if (map->dev_name && strcmp(component->name, map->dev_name))
1427 continue; 1216 continue;
@@ -1480,8 +1269,8 @@ static int soc_probe_component(struct snd_soc_card *card,
1480 } 1269 }
1481 } 1270 }
1482 1271
1483 if (component->probe) { 1272 if (component->driver->probe) {
1484 ret = component->probe(component); 1273 ret = component->driver->probe(component);
1485 if (ret < 0) { 1274 if (ret < 0) {
1486 dev_err(component->dev, 1275 dev_err(component->dev,
1487 "ASoC: failed to probe component %d\n", ret); 1276 "ASoC: failed to probe component %d\n", ret);
@@ -1838,24 +1627,6 @@ static void soc_remove_aux_devices(struct snd_soc_card *card)
1838 } 1627 }
1839} 1628}
1840 1629
1841static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
1842{
1843 int ret;
1844
1845 if (codec->cache_init)
1846 return 0;
1847
1848 ret = snd_soc_cache_init(codec);
1849 if (ret < 0) {
1850 dev_err(codec->dev,
1851 "ASoC: Failed to set cache compression type: %d\n",
1852 ret);
1853 return ret;
1854 }
1855 codec->cache_init = 1;
1856 return 0;
1857}
1858
1859/** 1630/**
1860 * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime 1631 * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime
1861 * @rtd: The runtime for which the DAI link format should be changed 1632 * @rtd: The runtime for which the DAI link format should be changed
@@ -1890,8 +1661,7 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
1890 1661
1891 /* Flip the polarity for the "CPU" end of a CODEC<->CODEC link */ 1662 /* Flip the polarity for the "CPU" end of a CODEC<->CODEC link */
1892 /* the component which has non_legacy_dai_naming is Codec */ 1663 /* the component which has non_legacy_dai_naming is Codec */
1893 if (cpu_dai->codec || 1664 if (cpu_dai->component->driver->non_legacy_dai_naming) {
1894 cpu_dai->component->driver->non_legacy_dai_naming) {
1895 unsigned int inv_dai_fmt; 1665 unsigned int inv_dai_fmt;
1896 1666
1897 inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; 1667 inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK;
@@ -2078,7 +1848,6 @@ EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
2078 1848
2079static int snd_soc_instantiate_card(struct snd_soc_card *card) 1849static int snd_soc_instantiate_card(struct snd_soc_card *card)
2080{ 1850{
2081 struct snd_soc_codec *codec;
2082 struct snd_soc_pcm_runtime *rtd; 1851 struct snd_soc_pcm_runtime *rtd;
2083 struct snd_soc_dai_link *dai_link; 1852 struct snd_soc_dai_link *dai_link;
2084 int ret, i, order; 1853 int ret, i, order;
@@ -2104,15 +1873,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2104 for (i = 0; i < card->num_links; i++) 1873 for (i = 0; i < card->num_links; i++)
2105 snd_soc_add_dai_link(card, card->dai_link+i); 1874 snd_soc_add_dai_link(card, card->dai_link+i);
2106 1875
2107 /* initialize the register cache for each available codec */
2108 list_for_each_entry(codec, &codec_list, list) {
2109 if (codec->cache_init)
2110 continue;
2111 ret = snd_soc_init_codec_cache(codec);
2112 if (ret < 0)
2113 goto base_error;
2114 }
2115
2116 /* card bind complete so register a sound card */ 1876 /* card bind complete so register a sound card */
2117 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1877 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
2118 card->owner, 0, &card->snd_card); 1878 card->owner, 0, &card->snd_card);
@@ -2494,43 +2254,6 @@ int snd_soc_add_component_controls(struct snd_soc_component *component,
2494EXPORT_SYMBOL_GPL(snd_soc_add_component_controls); 2254EXPORT_SYMBOL_GPL(snd_soc_add_component_controls);
2495 2255
2496/** 2256/**
2497 * snd_soc_add_codec_controls - add an array of controls to a codec.
2498 * Convenience function to add a list of controls. Many codecs were
2499 * duplicating this code.
2500 *
2501 * @codec: codec to add controls to
2502 * @controls: array of controls to add
2503 * @num_controls: number of elements in the array
2504 *
2505 * Return 0 for success, else error.
2506 */
2507int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
2508 const struct snd_kcontrol_new *controls, unsigned int num_controls)
2509{
2510 return snd_soc_add_component_controls(&codec->component, controls,
2511 num_controls);
2512}
2513EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
2514
2515/**
2516 * snd_soc_add_platform_controls - add an array of controls to a platform.
2517 * Convenience function to add a list of controls.
2518 *
2519 * @platform: platform to add controls to
2520 * @controls: array of controls to add
2521 * @num_controls: number of elements in the array
2522 *
2523 * Return 0 for success, else error.
2524 */
2525int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
2526 const struct snd_kcontrol_new *controls, unsigned int num_controls)
2527{
2528 return snd_soc_add_component_controls(&platform->component, controls,
2529 num_controls);
2530}
2531EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
2532
2533/**
2534 * snd_soc_add_card_controls - add an array of controls to a SoC card. 2257 * snd_soc_add_card_controls - add an array of controls to a SoC card.
2535 * Convenience function to add a list of controls. 2258 * Convenience function to add a list of controls.
2536 * 2259 *
@@ -2591,27 +2314,6 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
2591EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); 2314EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
2592 2315
2593/** 2316/**
2594 * snd_soc_codec_set_sysclk - configure CODEC system or master clock.
2595 * @codec: CODEC
2596 * @clk_id: DAI specific clock ID
2597 * @source: Source for the clock
2598 * @freq: new clock frequency in Hz
2599 * @dir: new clock direction - input/output.
2600 *
2601 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
2602 */
2603int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
2604 int source, unsigned int freq, int dir)
2605{
2606 if (codec->driver->set_sysclk)
2607 return codec->driver->set_sysclk(codec, clk_id, source,
2608 freq, dir);
2609 else
2610 return -ENOTSUPP;
2611}
2612EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
2613
2614/**
2615 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock. 2317 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
2616 * @component: COMPONENT 2318 * @component: COMPONENT
2617 * @clk_id: DAI specific clock ID 2319 * @clk_id: DAI specific clock ID
@@ -2624,11 +2326,6 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk);
2624int snd_soc_component_set_sysclk(struct snd_soc_component *component, int clk_id, 2326int snd_soc_component_set_sysclk(struct snd_soc_component *component, int clk_id,
2625 int source, unsigned int freq, int dir) 2327 int source, unsigned int freq, int dir)
2626{ 2328{
2627 /* will be removed */
2628 if (component->set_sysclk)
2629 return component->set_sysclk(component, clk_id, source,
2630 freq, dir);
2631
2632 if (component->driver->set_sysclk) 2329 if (component->driver->set_sysclk)
2633 return component->driver->set_sysclk(component, clk_id, source, 2330 return component->driver->set_sysclk(component, clk_id, source,
2634 freq, dir); 2331 freq, dir);
@@ -2680,27 +2377,6 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2680EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); 2377EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
2681 2378
2682/* 2379/*
2683 * snd_soc_codec_set_pll - configure codec PLL.
2684 * @codec: CODEC
2685 * @pll_id: DAI specific PLL ID
2686 * @source: DAI specific source for the PLL
2687 * @freq_in: PLL input clock frequency in Hz
2688 * @freq_out: requested PLL output clock frequency in Hz
2689 *
2690 * Configures and enables PLL to generate output clock based on input clock.
2691 */
2692int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
2693 unsigned int freq_in, unsigned int freq_out)
2694{
2695 if (codec->driver->set_pll)
2696 return codec->driver->set_pll(codec, pll_id, source,
2697 freq_in, freq_out);
2698 else
2699 return -EINVAL;
2700}
2701EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
2702
2703/*
2704 * snd_soc_component_set_pll - configure component PLL. 2380 * snd_soc_component_set_pll - configure component PLL.
2705 * @component: COMPONENT 2381 * @component: COMPONENT
2706 * @pll_id: DAI specific PLL ID 2382 * @pll_id: DAI specific PLL ID
@@ -2714,11 +2390,6 @@ int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
2714 int source, unsigned int freq_in, 2390 int source, unsigned int freq_in,
2715 unsigned int freq_out) 2391 unsigned int freq_out)
2716{ 2392{
2717 /* will be removed */
2718 if (component->set_pll)
2719 return component->set_pll(component, pll_id, source,
2720 freq_in, freq_out);
2721
2722 if (component->driver->set_pll) 2393 if (component->driver->set_pll)
2723 return component->driver->set_pll(component, pll_id, source, 2394 return component->driver->set_pll(component, pll_id, source,
2724 freq_in, freq_out); 2395 freq_in, freq_out);
@@ -3112,8 +2783,7 @@ static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component,
3112 * parent's name. 2783 * parent's name.
3113 */ 2784 */
3114static int snd_soc_register_dais(struct snd_soc_component *component, 2785static int snd_soc_register_dais(struct snd_soc_component *component,
3115 struct snd_soc_dai_driver *dai_drv, size_t count, 2786 struct snd_soc_dai_driver *dai_drv, size_t count)
3116 bool legacy_dai_naming)
3117{ 2787{
3118 struct device *dev = component->dev; 2788 struct device *dev = component->dev;
3119 struct snd_soc_dai *dai; 2789 struct snd_soc_dai *dai;
@@ -3125,7 +2795,7 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
3125 for (i = 0; i < count; i++) { 2795 for (i = 0; i < count; i++) {
3126 2796
3127 dai = soc_add_dai(component, dai_drv + i, 2797 dai = soc_add_dai(component, dai_drv + i,
3128 count == 1 && legacy_dai_naming); 2798 count == 1 && !component->driver->non_legacy_dai_naming);
3129 if (dai == NULL) { 2799 if (dai == NULL) {
3130 ret = -ENOMEM; 2800 ret = -ENOMEM;
3131 goto err; 2801 goto err;
@@ -3198,22 +2868,6 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
3198 return component->driver->stream_event(component, event); 2868 return component->driver->stream_event(component, event);
3199} 2869}
3200 2870
3201static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
3202 struct snd_soc_pcm_runtime *rtd)
3203{
3204 if (component->driver->pcm_new)
3205 return component->driver->pcm_new(rtd);
3206
3207 return 0;
3208}
3209
3210static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
3211 struct snd_pcm *pcm)
3212{
3213 if (component->driver->pcm_free)
3214 component->driver->pcm_free(pcm);
3215}
3216
3217static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm, 2871static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm,
3218 enum snd_soc_bias_level level) 2872 enum snd_soc_bias_level level)
3219{ 2873{
@@ -3235,15 +2889,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
3235 2889
3236 component->dev = dev; 2890 component->dev = dev;
3237 component->driver = driver; 2891 component->driver = driver;
3238 component->probe = component->driver->probe;
3239 component->remove = component->driver->remove;
3240 component->suspend = component->driver->suspend;
3241 component->resume = component->driver->resume;
3242 component->set_sysclk = component->driver->set_sysclk;
3243 component->set_pll = component->driver->set_pll;
3244 component->set_jack = component->driver->set_jack;
3245 component->pcm_new = snd_soc_component_drv_pcm_new;
3246 component->pcm_free = snd_soc_component_drv_pcm_free;
3247 2892
3248 dapm = snd_soc_component_get_dapm(component); 2893 dapm = snd_soc_component_get_dapm(component);
3249 dapm->dev = dev; 2894 dapm->dev = dev;
@@ -3312,9 +2957,11 @@ EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
3312 2957
3313#endif 2958#endif
3314 2959
3315static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 2960static void snd_soc_component_add(struct snd_soc_component *component)
3316{ 2961{
3317 if (!component->write && !component->read) { 2962 mutex_lock(&client_mutex);
2963
2964 if (!component->driver->write && !component->driver->read) {
3318 if (!component->regmap) 2965 if (!component->regmap)
3319 component->regmap = dev_get_regmap(component->dev, NULL); 2966 component->regmap = dev_get_regmap(component->dev, NULL);
3320 if (component->regmap) 2967 if (component->regmap)
@@ -3323,12 +2970,7 @@ static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
3323 2970
3324 list_add(&component->list, &component_list); 2971 list_add(&component->list, &component_list);
3325 INIT_LIST_HEAD(&component->dobj_list); 2972 INIT_LIST_HEAD(&component->dobj_list);
3326}
3327 2973
3328static void snd_soc_component_add(struct snd_soc_component *component)
3329{
3330 mutex_lock(&client_mutex);
3331 snd_soc_component_add_unlocked(component);
3332 mutex_unlock(&client_mutex); 2974 mutex_unlock(&client_mutex);
3333} 2975}
3334 2976
@@ -3396,9 +3038,6 @@ int snd_soc_add_component(struct device *dev,
3396 if (ret) 3038 if (ret)
3397 goto err_free; 3039 goto err_free;
3398 3040
3399 component->ignore_pmdown_time = true;
3400 component->registered_as_component = true;
3401
3402 if (component_driver->endianness) { 3041 if (component_driver->endianness) {
3403 for (i = 0; i < num_dai; i++) { 3042 for (i = 0; i < num_dai; i++) {
3404 convert_endianness_formats(&dai_drv[i].playback); 3043 convert_endianness_formats(&dai_drv[i].playback);
@@ -3406,8 +3045,7 @@ int snd_soc_add_component(struct device *dev,
3406 } 3045 }
3407 } 3046 }
3408 3047
3409 ret = snd_soc_register_dais(component, dai_drv, num_dai, 3048 ret = snd_soc_register_dais(component, dai_drv, num_dai);
3410 !component_driver->non_legacy_dai_naming);
3411 if (ret < 0) { 3049 if (ret < 0) {
3412 dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); 3050 dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret);
3413 goto err_cleanup; 3051 goto err_cleanup;
@@ -3453,8 +3091,7 @@ static int __snd_soc_unregister_component(struct device *dev)
3453 3091
3454 mutex_lock(&client_mutex); 3092 mutex_lock(&client_mutex);
3455 list_for_each_entry(component, &component_list, list) { 3093 list_for_each_entry(component, &component_list, list) {
3456 if (dev != component->dev || 3094 if (dev != component->dev)
3457 !component->registered_as_component)
3458 continue; 3095 continue;
3459 3096
3460 snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); 3097 snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL);
@@ -3503,375 +3140,6 @@ struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
3503} 3140}
3504EXPORT_SYMBOL_GPL(snd_soc_lookup_component); 3141EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
3505 3142
3506static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
3507{
3508 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
3509
3510 return platform->driver->probe(platform);
3511}
3512
3513static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
3514{
3515 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
3516
3517 platform->driver->remove(platform);
3518}
3519
3520static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
3521 struct snd_soc_pcm_runtime *rtd)
3522{
3523 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
3524
3525 if (platform->driver->pcm_new)
3526 return platform->driver->pcm_new(rtd);
3527
3528 return 0;
3529}
3530
3531static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
3532 struct snd_pcm *pcm)
3533{
3534 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
3535
3536 if (platform->driver->pcm_free)
3537 platform->driver->pcm_free(pcm);
3538}
3539
3540/**
3541 * snd_soc_add_platform - Add a platform to the ASoC core
3542 * @dev: The parent device for the platform
3543 * @platform: The platform to add
3544 * @platform_drv: The driver for the platform
3545 */
3546int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
3547 const struct snd_soc_platform_driver *platform_drv)
3548{
3549 int ret;
3550
3551 ret = snd_soc_component_initialize(&platform->component,
3552 &platform_drv->component_driver, dev);
3553 if (ret)
3554 return ret;
3555
3556 platform->dev = dev;
3557 platform->driver = platform_drv;
3558
3559 if (platform_drv->probe)
3560 platform->component.probe = snd_soc_platform_drv_probe;
3561 if (platform_drv->remove)
3562 platform->component.remove = snd_soc_platform_drv_remove;
3563 if (platform_drv->pcm_new)
3564 platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
3565 if (platform_drv->pcm_free)
3566 platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
3567
3568#ifdef CONFIG_DEBUG_FS
3569 platform->component.debugfs_prefix = "platform";
3570#endif
3571
3572 mutex_lock(&client_mutex);
3573 snd_soc_component_add_unlocked(&platform->component);
3574 list_add(&platform->list, &platform_list);
3575 mutex_unlock(&client_mutex);
3576
3577 dev_dbg(dev, "ASoC: Registered platform '%s'\n",
3578 platform->component.name);
3579
3580 return 0;
3581}
3582EXPORT_SYMBOL_GPL(snd_soc_add_platform);
3583
3584/**
3585 * snd_soc_register_platform - Register a platform with the ASoC core
3586 *
3587 * @dev: The device for the platform
3588 * @platform_drv: The driver for the platform
3589 */
3590int snd_soc_register_platform(struct device *dev,
3591 const struct snd_soc_platform_driver *platform_drv)
3592{
3593 struct snd_soc_platform *platform;
3594 int ret;
3595
3596 dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev));
3597
3598 platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
3599 if (platform == NULL)
3600 return -ENOMEM;
3601
3602 ret = snd_soc_add_platform(dev, platform, platform_drv);
3603 if (ret)
3604 kfree(platform);
3605
3606 return ret;
3607}
3608EXPORT_SYMBOL_GPL(snd_soc_register_platform);
3609
3610/**
3611 * snd_soc_remove_platform - Remove a platform from the ASoC core
3612 * @platform: the platform to remove
3613 */
3614void snd_soc_remove_platform(struct snd_soc_platform *platform)
3615{
3616
3617 mutex_lock(&client_mutex);
3618 list_del(&platform->list);
3619 snd_soc_component_del_unlocked(&platform->component);
3620 mutex_unlock(&client_mutex);
3621
3622 dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n",
3623 platform->component.name);
3624
3625 snd_soc_component_cleanup(&platform->component);
3626}
3627EXPORT_SYMBOL_GPL(snd_soc_remove_platform);
3628
3629struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev)
3630{
3631 struct snd_soc_platform *platform;
3632
3633 mutex_lock(&client_mutex);
3634 list_for_each_entry(platform, &platform_list, list) {
3635 if (dev == platform->dev) {
3636 mutex_unlock(&client_mutex);
3637 return platform;
3638 }
3639 }
3640 mutex_unlock(&client_mutex);
3641
3642 return NULL;
3643}
3644EXPORT_SYMBOL_GPL(snd_soc_lookup_platform);
3645
3646/**
3647 * snd_soc_unregister_platform - Unregister a platform from the ASoC core
3648 *
3649 * @dev: platform to unregister
3650 */
3651void snd_soc_unregister_platform(struct device *dev)
3652{
3653 struct snd_soc_platform *platform;
3654
3655 platform = snd_soc_lookup_platform(dev);
3656 if (!platform)
3657 return;
3658
3659 snd_soc_remove_platform(platform);
3660 kfree(platform);
3661}
3662EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
3663
3664static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
3665{
3666 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3667
3668 return codec->driver->probe(codec);
3669}
3670
3671static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
3672{
3673 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3674
3675 codec->driver->remove(codec);
3676}
3677
3678static int snd_soc_codec_drv_suspend(struct snd_soc_component *component)
3679{
3680 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3681
3682 return codec->driver->suspend(codec);
3683}
3684
3685static int snd_soc_codec_drv_resume(struct snd_soc_component *component)
3686{
3687 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3688
3689 return codec->driver->resume(codec);
3690}
3691
3692static int snd_soc_codec_drv_write(struct snd_soc_component *component,
3693 unsigned int reg, unsigned int val)
3694{
3695 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3696
3697 return codec->driver->write(codec, reg, val);
3698}
3699
3700static int snd_soc_codec_drv_read(struct snd_soc_component *component,
3701 unsigned int reg, unsigned int *val)
3702{
3703 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3704
3705 *val = codec->driver->read(codec, reg);
3706
3707 return 0;
3708}
3709
3710static int snd_soc_codec_set_sysclk_(struct snd_soc_component *component,
3711 int clk_id, int source, unsigned int freq, int dir)
3712{
3713 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3714
3715 return snd_soc_codec_set_sysclk(codec, clk_id, source, freq, dir);
3716}
3717
3718static int snd_soc_codec_set_pll_(struct snd_soc_component *component,
3719 int pll_id, int source, unsigned int freq_in,
3720 unsigned int freq_out)
3721{
3722 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3723
3724 return snd_soc_codec_set_pll(codec, pll_id, source, freq_in, freq_out);
3725}
3726
3727static int snd_soc_codec_set_jack_(struct snd_soc_component *component,
3728 struct snd_soc_jack *jack, void *data)
3729{
3730 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
3731
3732 return snd_soc_codec_set_jack(codec, jack, data);
3733}
3734
3735static int snd_soc_codec_set_bias_level(struct snd_soc_dapm_context *dapm,
3736 enum snd_soc_bias_level level)
3737{
3738 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
3739
3740 return codec->driver->set_bias_level(codec, level);
3741}
3742
3743/**
3744 * snd_soc_register_codec - Register a codec with the ASoC core
3745 *
3746 * @dev: The parent device for this codec
3747 * @codec_drv: Codec driver
3748 * @dai_drv: The associated DAI driver
3749 * @num_dai: Number of DAIs
3750 */
3751int snd_soc_register_codec(struct device *dev,
3752 const struct snd_soc_codec_driver *codec_drv,
3753 struct snd_soc_dai_driver *dai_drv,
3754 int num_dai)
3755{
3756 struct snd_soc_dapm_context *dapm;
3757 struct snd_soc_codec *codec;
3758 struct snd_soc_dai *dai;
3759 int ret, i;
3760
3761 dev_dbg(dev, "codec register %s\n", dev_name(dev));
3762
3763 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
3764 if (codec == NULL)
3765 return -ENOMEM;
3766
3767 codec->component.codec = codec;
3768
3769 ret = snd_soc_component_initialize(&codec->component,
3770 &codec_drv->component_driver, dev);
3771 if (ret)
3772 goto err_free;
3773
3774 if (codec_drv->probe)
3775 codec->component.probe = snd_soc_codec_drv_probe;
3776 if (codec_drv->remove)
3777 codec->component.remove = snd_soc_codec_drv_remove;
3778 if (codec_drv->suspend)
3779 codec->component.suspend = snd_soc_codec_drv_suspend;
3780 if (codec_drv->resume)
3781 codec->component.resume = snd_soc_codec_drv_resume;
3782 if (codec_drv->write)
3783 codec->component.write = snd_soc_codec_drv_write;
3784 if (codec_drv->read)
3785 codec->component.read = snd_soc_codec_drv_read;
3786 if (codec_drv->set_sysclk)
3787 codec->component.set_sysclk = snd_soc_codec_set_sysclk_;
3788 if (codec_drv->set_pll)
3789 codec->component.set_pll = snd_soc_codec_set_pll_;
3790 if (codec_drv->set_jack)
3791 codec->component.set_jack = snd_soc_codec_set_jack_;
3792 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
3793
3794 dapm = snd_soc_codec_get_dapm(codec);
3795 dapm->idle_bias_off = codec_drv->idle_bias_off;
3796 dapm->suspend_bias_off = codec_drv->suspend_bias_off;
3797 if (codec_drv->seq_notifier)
3798 dapm->seq_notifier = codec_drv->seq_notifier;
3799 if (codec_drv->set_bias_level)
3800 dapm->set_bias_level = snd_soc_codec_set_bias_level;
3801 codec->dev = dev;
3802 codec->driver = codec_drv;
3803 codec->component.val_bytes = codec_drv->reg_word_size;
3804
3805#ifdef CONFIG_DEBUG_FS
3806 codec->component.init_debugfs = soc_init_codec_debugfs;
3807 codec->component.debugfs_prefix = "codec";
3808#endif
3809
3810 if (codec_drv->get_regmap)
3811 codec->component.regmap = codec_drv->get_regmap(dev);
3812
3813 for (i = 0; i < num_dai; i++) {
3814 convert_endianness_formats(&dai_drv[i].playback);
3815 convert_endianness_formats(&dai_drv[i].capture);
3816 }
3817
3818 ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false);
3819 if (ret < 0) {
3820 dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret);
3821 goto err_cleanup;
3822 }
3823
3824 list_for_each_entry(dai, &codec->component.dai_list, list)
3825 dai->codec = codec;
3826
3827 mutex_lock(&client_mutex);
3828 snd_soc_component_add_unlocked(&codec->component);
3829 list_add(&codec->list, &codec_list);
3830 mutex_unlock(&client_mutex);
3831
3832 dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n",
3833 codec->component.name);
3834 return 0;
3835
3836err_cleanup:
3837 snd_soc_component_cleanup(&codec->component);
3838err_free:
3839 kfree(codec);
3840 return ret;
3841}
3842EXPORT_SYMBOL_GPL(snd_soc_register_codec);
3843
3844/**
3845 * snd_soc_unregister_codec - Unregister a codec from the ASoC core
3846 *
3847 * @dev: codec to unregister
3848 */
3849void snd_soc_unregister_codec(struct device *dev)
3850{
3851 struct snd_soc_codec *codec;
3852
3853 mutex_lock(&client_mutex);
3854 list_for_each_entry(codec, &codec_list, list) {
3855 if (dev == codec->dev)
3856 goto found;
3857 }
3858 mutex_unlock(&client_mutex);
3859 return;
3860
3861found:
3862 list_del(&codec->list);
3863 snd_soc_component_del_unlocked(&codec->component);
3864 mutex_unlock(&client_mutex);
3865
3866 dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n",
3867 codec->component.name);
3868
3869 snd_soc_component_cleanup(&codec->component);
3870 snd_soc_cache_exit(codec);
3871 kfree(codec);
3872}
3873EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
3874
3875/* Retrieve a card's name from device tree */ 3143/* Retrieve a card's name from device tree */
3876int snd_soc_of_parse_card_name(struct snd_soc_card *card, 3144int snd_soc_of_parse_card_name(struct snd_soc_card *card,
3877 const char *propname) 3145 const char *propname)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2d9709104ec5..36a39ba30226 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -433,6 +433,8 @@ err_data:
433static void dapm_kcontrol_free(struct snd_kcontrol *kctl) 433static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
434{ 434{
435 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); 435 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
436
437 list_del(&data->paths);
436 kfree(data->wlist); 438 kfree(data->wlist);
437 kfree(data); 439 kfree(data);
438} 440}
@@ -724,18 +726,14 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
724 item = 0; 726 item = 0;
725 } 727 }
726 728
727 for (i = 0; i < e->items; i++) { 729 i = match_string(e->texts, e->items, control_name);
728 if (!(strcmp(control_name, e->texts[i]))) { 730 if (i < 0)
729 path->name = e->texts[i]; 731 return -ENODEV;
730 if (i == item) 732
731 path->connect = 1; 733 path->name = e->texts[i];
732 else 734 path->connect = (i == item);
733 path->connect = 0; 735 return 0;
734 return 0;
735 }
736 }
737 736
738 return -ENODEV;
739} 737}
740 738
741/* set up initial codec paths */ 739/* set up initial codec paths */
diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c
index a57921eeee81..7ac745df1412 100644
--- a/sound/soc/soc-devres.c
+++ b/sound/soc/soc-devres.c
@@ -52,41 +52,6 @@ int devm_snd_soc_register_component(struct device *dev,
52} 52}
53EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); 53EXPORT_SYMBOL_GPL(devm_snd_soc_register_component);
54 54
55static void devm_platform_release(struct device *dev, void *res)
56{
57 snd_soc_unregister_platform(*(struct device **)res);
58}
59
60/**
61 * devm_snd_soc_register_platform - resource managed platform registration
62 * @dev: Device used to manage platform
63 * @platform_drv: platform to register
64 *
65 * Register a platform driver with automatic unregistration when the device is
66 * unregistered.
67 */
68int devm_snd_soc_register_platform(struct device *dev,
69 const struct snd_soc_platform_driver *platform_drv)
70{
71 struct device **ptr;
72 int ret;
73
74 ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL);
75 if (!ptr)
76 return -ENOMEM;
77
78 ret = snd_soc_register_platform(dev, platform_drv);
79 if (ret == 0) {
80 *ptr = dev;
81 devres_add(dev, ptr);
82 } else {
83 devres_free(ptr);
84 }
85
86 return ret;
87}
88EXPORT_SYMBOL_GPL(devm_snd_soc_register_platform);
89
90static void devm_card_release(struct device *dev, void *res) 55static void devm_card_release(struct device *dev, void *res)
91{ 56{
92 snd_soc_unregister_card(*(struct snd_soc_card **)res); 57 snd_soc_unregister_card(*(struct snd_soc_card **)res);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index d36a192fbece..026cd5347e53 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -32,8 +32,6 @@ int snd_soc_component_read(struct snd_soc_component *component,
32 32
33 if (component->regmap) 33 if (component->regmap)
34 ret = regmap_read(component->regmap, reg, val); 34 ret = regmap_read(component->regmap, reg, val);
35 else if (component->read)
36 ret = component->read(component, reg, val);
37 else if (component->driver->read) { 35 else if (component->driver->read) {
38 *val = component->driver->read(component, reg); 36 *val = component->driver->read(component, reg);
39 ret = 0; 37 ret = 0;
@@ -72,8 +70,6 @@ int snd_soc_component_write(struct snd_soc_component *component,
72{ 70{
73 if (component->regmap) 71 if (component->regmap)
74 return regmap_write(component->regmap, reg, val); 72 return regmap_write(component->regmap, reg, val);
75 else if (component->write)
76 return component->write(component, reg, val);
77 else if (component->driver->write) 73 else if (component->driver->write)
78 return component->driver->write(component, reg, val); 74 return component->driver->write(component, reg, val);
79 else 75 else
@@ -209,82 +205,3 @@ int snd_soc_component_test_bits(struct snd_soc_component *component,
209 return old != new; 205 return old != new;
210} 206}
211EXPORT_SYMBOL_GPL(snd_soc_component_test_bits); 207EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
212
213unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
214{
215 unsigned int val;
216 int ret;
217
218 ret = snd_soc_component_read(&codec->component, reg, &val);
219 if (ret < 0)
220 return -1;
221
222 return val;
223}
224EXPORT_SYMBOL_GPL(snd_soc_read);
225
226int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
227 unsigned int val)
228{
229 return snd_soc_component_write(&codec->component, reg, val);
230}
231EXPORT_SYMBOL_GPL(snd_soc_write);
232
233/**
234 * snd_soc_update_bits - update codec register bits
235 * @codec: audio codec
236 * @reg: codec register
237 * @mask: register mask
238 * @value: new value
239 *
240 * Writes new register value.
241 *
242 * Returns 1 for change, 0 for no change, or negative error code.
243 */
244int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
245 unsigned int mask, unsigned int value)
246{
247 return snd_soc_component_update_bits(&codec->component, reg, mask,
248 value);
249}
250EXPORT_SYMBOL_GPL(snd_soc_update_bits);
251
252/**
253 * snd_soc_test_bits - test register for change
254 * @codec: audio codec
255 * @reg: codec register
256 * @mask: register mask
257 * @value: new value
258 *
259 * Tests a register with a new value and checks if the new value is
260 * different from the old value.
261 *
262 * Returns 1 for change else 0.
263 */
264int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
265 unsigned int mask, unsigned int value)
266{
267 return snd_soc_component_test_bits(&codec->component, reg, mask, value);
268}
269EXPORT_SYMBOL_GPL(snd_soc_test_bits);
270
271int snd_soc_platform_read(struct snd_soc_platform *platform,
272 unsigned int reg)
273{
274 unsigned int val;
275 int ret;
276
277 ret = snd_soc_component_read(&platform->component, reg, &val);
278 if (ret < 0)
279 return -1;
280
281 return val;
282}
283EXPORT_SYMBOL_GPL(snd_soc_platform_read);
284
285int snd_soc_platform_write(struct snd_soc_platform *platform,
286 unsigned int reg, unsigned int val)
287{
288 return snd_soc_component_write(&platform->component, reg, val);
289}
290EXPORT_SYMBOL_GPL(snd_soc_platform_write);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 99902ae1a2d9..b2b16044ae80 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -29,24 +29,6 @@ struct jack_gpio_tbl {
29}; 29};
30 30
31/** 31/**
32 * snd_soc_codec_set_jack - configure codec jack.
33 * @codec: CODEC
34 * @jack: structure to use for the jack
35 * @data: can be used if codec driver need extra data for configuring jack
36 *
37 * Configures and enables jack detection function.
38 */
39int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
40 struct snd_soc_jack *jack, void *data)
41{
42 if (codec->driver->set_jack)
43 return codec->driver->set_jack(codec, jack, data);
44 else
45 return -ENOTSUPP;
46}
47EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack);
48
49/**
50 * snd_soc_component_set_jack - configure component jack. 32 * snd_soc_component_set_jack - configure component jack.
51 * @component: COMPONENTs 33 * @component: COMPONENTs
52 * @jack: structure to use for the jack 34 * @jack: structure to use for the jack
@@ -57,10 +39,6 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack);
57int snd_soc_component_set_jack(struct snd_soc_component *component, 39int snd_soc_component_set_jack(struct snd_soc_component *component,
58 struct snd_soc_jack *jack, void *data) 40 struct snd_soc_jack *jack, void *data)
59{ 41{
60 /* will be removed */
61 if (component->set_jack)
62 return component->set_jack(component, jack, data);
63
64 if (component->driver->set_jack) 42 if (component->driver->set_jack)
65 return component->driver->set_jack(component, jack, data); 43 return component->driver->set_jack(component, jack, data);
66 44
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 68d9dc930096..5e7ae47a9658 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -135,7 +135,6 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
135{ 135{
136 struct snd_soc_rtdcom_list *rtdcom; 136 struct snd_soc_rtdcom_list *rtdcom;
137 struct snd_soc_component *component; 137 struct snd_soc_component *component;
138 int i;
139 bool ignore = true; 138 bool ignore = true;
140 139
141 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) 140 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
@@ -147,10 +146,6 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
147 ignore &= !component->driver->use_pmdown_time; 146 ignore &= !component->driver->use_pmdown_time;
148 } 147 }
149 148
150 /* this will be removed */
151 for (i = 0; i < rtd->num_codecs; i++)
152 ignore &= rtd->codec_dais[i]->component->ignore_pmdown_time;
153
154 return ignore; 149 return ignore;
155} 150}
156 151
@@ -456,13 +451,12 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
456/* 451/*
457 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 452 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
458 * then initialized and any private data can be allocated. This also calls 453 * then initialized and any private data can be allocated. This also calls
459 * startup for the cpu DAI, platform, machine and codec DAI. 454 * startup for the cpu DAI, component, machine and codec DAI.
460 */ 455 */
461static int soc_pcm_open(struct snd_pcm_substream *substream) 456static int soc_pcm_open(struct snd_pcm_substream *substream)
462{ 457{
463 struct snd_soc_pcm_runtime *rtd = substream->private_data; 458 struct snd_soc_pcm_runtime *rtd = substream->private_data;
464 struct snd_pcm_runtime *runtime = substream->runtime; 459 struct snd_pcm_runtime *runtime = substream->runtime;
465 struct snd_soc_platform *platform = rtd->platform;
466 struct snd_soc_component *component; 460 struct snd_soc_component *component;
467 struct snd_soc_rtdcom_list *rtdcom; 461 struct snd_soc_rtdcom_list *rtdcom;
468 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 462 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -492,23 +486,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
492 } 486 }
493 } 487 }
494 488
495 if (platform && platform->driver->ops && platform->driver->ops->open) {
496 ret = platform->driver->ops->open(substream);
497 if (ret < 0) {
498 dev_err(platform->dev, "ASoC: can't open platform"
499 " %s: %d\n", platform->component.name, ret);
500 goto platform_err;
501 }
502 }
503
504 ret = 0; 489 ret = 0;
505 for_each_rtdcom(rtd, rtdcom) { 490 for_each_rtdcom(rtd, rtdcom) {
506 component = rtdcom->component; 491 component = rtdcom->component;
507 492
508 /* ignore duplication for now */
509 if (platform && (component == &platform->component))
510 continue;
511
512 if (!component->driver->ops || 493 if (!component->driver->ops ||
513 !component->driver->ops->open) 494 !component->driver->ops->open)
514 continue; 495 continue;
@@ -517,7 +498,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
517 if (__ret < 0) { 498 if (__ret < 0) {
518 dev_err(component->dev, 499 dev_err(component->dev,
519 "ASoC: can't open component %s: %d\n", 500 "ASoC: can't open component %s: %d\n",
520 component->name, ret); 501 component->name, __ret);
521 ret = __ret; 502 ret = __ret;
522 } 503 }
523 } 504 }
@@ -634,10 +615,6 @@ component_err:
634 for_each_rtdcom(rtd, rtdcom) { 615 for_each_rtdcom(rtd, rtdcom) {
635 component = rtdcom->component; 616 component = rtdcom->component;
636 617
637 /* ignore duplication for now */
638 if (platform && (component == &platform->component))
639 continue;
640
641 if (!component->driver->ops || 618 if (!component->driver->ops ||
642 !component->driver->ops->close) 619 !component->driver->ops->close)
643 continue; 620 continue;
@@ -645,10 +622,6 @@ component_err:
645 component->driver->ops->close(substream); 622 component->driver->ops->close(substream);
646 } 623 }
647 624
648 if (platform && platform->driver->ops && platform->driver->ops->close)
649 platform->driver->ops->close(substream);
650
651platform_err:
652 if (cpu_dai->driver->ops->shutdown) 625 if (cpu_dai->driver->ops->shutdown)
653 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 626 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
654out: 627out:
@@ -701,13 +674,12 @@ static void close_delayed_work(struct work_struct *work)
701 674
702/* 675/*
703 * Called by ALSA when a PCM substream is closed. Private data can be 676 * Called by ALSA when a PCM substream is closed. Private data can be
704 * freed here. The cpu DAI, codec DAI, machine and platform are also 677 * freed here. The cpu DAI, codec DAI, machine and components are also
705 * shutdown. 678 * shutdown.
706 */ 679 */
707static int soc_pcm_close(struct snd_pcm_substream *substream) 680static int soc_pcm_close(struct snd_pcm_substream *substream)
708{ 681{
709 struct snd_soc_pcm_runtime *rtd = substream->private_data; 682 struct snd_soc_pcm_runtime *rtd = substream->private_data;
710 struct snd_soc_platform *platform = rtd->platform;
711 struct snd_soc_component *component; 683 struct snd_soc_component *component;
712 struct snd_soc_rtdcom_list *rtdcom; 684 struct snd_soc_rtdcom_list *rtdcom;
713 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 685 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -742,16 +714,9 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
742 if (rtd->dai_link->ops->shutdown) 714 if (rtd->dai_link->ops->shutdown)
743 rtd->dai_link->ops->shutdown(substream); 715 rtd->dai_link->ops->shutdown(substream);
744 716
745 if (platform && platform->driver->ops && platform->driver->ops->close)
746 platform->driver->ops->close(substream);
747
748 for_each_rtdcom(rtd, rtdcom) { 717 for_each_rtdcom(rtd, rtdcom) {
749 component = rtdcom->component; 718 component = rtdcom->component;
750 719
751 /* ignore duplication for now */
752 if (platform && (component == &platform->component))
753 continue;
754
755 if (!component->driver->ops || 720 if (!component->driver->ops ||
756 !component->driver->ops->close) 721 !component->driver->ops->close)
757 continue; 722 continue;
@@ -805,7 +770,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
805static int soc_pcm_prepare(struct snd_pcm_substream *substream) 770static int soc_pcm_prepare(struct snd_pcm_substream *substream)
806{ 771{
807 struct snd_soc_pcm_runtime *rtd = substream->private_data; 772 struct snd_soc_pcm_runtime *rtd = substream->private_data;
808 struct snd_soc_platform *platform = rtd->platform;
809 struct snd_soc_component *component; 773 struct snd_soc_component *component;
810 struct snd_soc_rtdcom_list *rtdcom; 774 struct snd_soc_rtdcom_list *rtdcom;
811 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 775 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -823,22 +787,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
823 } 787 }
824 } 788 }
825 789
826 if (platform && platform->driver->ops && platform->driver->ops->prepare) {
827 ret = platform->driver->ops->prepare(substream);
828 if (ret < 0) {
829 dev_err(platform->dev, "ASoC: platform prepare error:"
830 " %d\n", ret);
831 goto out;
832 }
833 }
834
835 for_each_rtdcom(rtd, rtdcom) { 790 for_each_rtdcom(rtd, rtdcom) {
836 component = rtdcom->component; 791 component = rtdcom->component;
837 792
838 /* ignore duplication for now */
839 if (platform && (component == &platform->component))
840 continue;
841
842 if (!component->driver->ops || 793 if (!component->driver->ops ||
843 !component->driver->ops->prepare) 794 !component->driver->ops->prepare)
844 continue; 795 continue;
@@ -932,7 +883,6 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
932 struct snd_pcm_hw_params *params) 883 struct snd_pcm_hw_params *params)
933{ 884{
934 struct snd_soc_pcm_runtime *rtd = substream->private_data; 885 struct snd_soc_pcm_runtime *rtd = substream->private_data;
935 struct snd_soc_platform *platform = rtd->platform;
936 struct snd_soc_component *component; 886 struct snd_soc_component *component;
937 struct snd_soc_rtdcom_list *rtdcom; 887 struct snd_soc_rtdcom_list *rtdcom;
938 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 888 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -994,23 +944,10 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
994 if (ret < 0) 944 if (ret < 0)
995 goto interface_err; 945 goto interface_err;
996 946
997 if (platform && platform->driver->ops && platform->driver->ops->hw_params) {
998 ret = platform->driver->ops->hw_params(substream, params);
999 if (ret < 0) {
1000 dev_err(platform->dev, "ASoC: %s hw params failed: %d\n",
1001 platform->component.name, ret);
1002 goto platform_err;
1003 }
1004 }
1005
1006 ret = 0; 947 ret = 0;
1007 for_each_rtdcom(rtd, rtdcom) { 948 for_each_rtdcom(rtd, rtdcom) {
1008 component = rtdcom->component; 949 component = rtdcom->component;
1009 950
1010 /* ignore duplication for now */
1011 if (platform && (component == &platform->component))
1012 continue;
1013
1014 if (!component->driver->ops || 951 if (!component->driver->ops ||
1015 !component->driver->ops->hw_params) 952 !component->driver->ops->hw_params)
1016 continue; 953 continue;
@@ -1019,7 +956,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
1019 if (__ret < 0) { 956 if (__ret < 0) {
1020 dev_err(component->dev, 957 dev_err(component->dev,
1021 "ASoC: %s hw params failed: %d\n", 958 "ASoC: %s hw params failed: %d\n",
1022 component->name, ret); 959 component->name, __ret);
1023 ret = __ret; 960 ret = __ret;
1024 } 961 }
1025 } 962 }
@@ -1043,10 +980,6 @@ component_err:
1043 for_each_rtdcom(rtd, rtdcom) { 980 for_each_rtdcom(rtd, rtdcom) {
1044 component = rtdcom->component; 981 component = rtdcom->component;
1045 982
1046 /* ignore duplication */
1047 if (platform && (component == &platform->component))
1048 continue;
1049
1050 if (!component->driver->ops || 983 if (!component->driver->ops ||
1051 !component->driver->ops->hw_free) 984 !component->driver->ops->hw_free)
1052 continue; 985 continue;
@@ -1054,10 +987,6 @@ component_err:
1054 component->driver->ops->hw_free(substream); 987 component->driver->ops->hw_free(substream);
1055 } 988 }
1056 989
1057 if (platform && platform->driver->ops && platform->driver->ops->hw_free)
1058 platform->driver->ops->hw_free(substream);
1059
1060platform_err:
1061 if (cpu_dai->driver->ops->hw_free) 990 if (cpu_dai->driver->ops->hw_free)
1062 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 991 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
1063 992
@@ -1085,7 +1014,6 @@ codec_err:
1085static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 1014static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1086{ 1015{
1087 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1016 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1088 struct snd_soc_platform *platform = rtd->platform;
1089 struct snd_soc_component *component; 1017 struct snd_soc_component *component;
1090 struct snd_soc_rtdcom_list *rtdcom; 1018 struct snd_soc_rtdcom_list *rtdcom;
1091 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1019 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -1123,18 +1051,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1123 if (rtd->dai_link->ops->hw_free) 1051 if (rtd->dai_link->ops->hw_free)
1124 rtd->dai_link->ops->hw_free(substream); 1052 rtd->dai_link->ops->hw_free(substream);
1125 1053
1126 /* free any DMA resources */
1127 if (platform && platform->driver->ops && platform->driver->ops->hw_free)
1128 platform->driver->ops->hw_free(substream);
1129
1130 /* free any component resources */ 1054 /* free any component resources */
1131 for_each_rtdcom(rtd, rtdcom) { 1055 for_each_rtdcom(rtd, rtdcom) {
1132 component = rtdcom->component; 1056 component = rtdcom->component;
1133 1057
1134 /* ignore duplication for now */
1135 if (platform && (component == &platform->component))
1136 continue;
1137
1138 if (!component->driver->ops || 1058 if (!component->driver->ops ||
1139 !component->driver->ops->hw_free) 1059 !component->driver->ops->hw_free)
1140 continue; 1060 continue;
@@ -1159,7 +1079,6 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1159static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 1079static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1160{ 1080{
1161 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1081 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1162 struct snd_soc_platform *platform = rtd->platform;
1163 struct snd_soc_component *component; 1082 struct snd_soc_component *component;
1164 struct snd_soc_rtdcom_list *rtdcom; 1083 struct snd_soc_rtdcom_list *rtdcom;
1165 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1084 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -1176,19 +1095,9 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1176 } 1095 }
1177 } 1096 }
1178 1097
1179 if (platform && platform->driver->ops && platform->driver->ops->trigger) {
1180 ret = platform->driver->ops->trigger(substream, cmd);
1181 if (ret < 0)
1182 return ret;
1183 }
1184
1185 for_each_rtdcom(rtd, rtdcom) { 1098 for_each_rtdcom(rtd, rtdcom) {
1186 component = rtdcom->component; 1099 component = rtdcom->component;
1187 1100
1188 /* ignore duplication for now */
1189 if (platform && (component == &platform->component))
1190 continue;
1191
1192 if (!component->driver->ops || 1101 if (!component->driver->ops ||
1193 !component->driver->ops->trigger) 1102 !component->driver->ops->trigger)
1194 continue; 1103 continue;
@@ -1240,13 +1149,12 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
1240} 1149}
1241/* 1150/*
1242 * soc level wrapper for pointer callback 1151 * soc level wrapper for pointer callback
1243 * If cpu_dai, codec_dai, platform driver has the delay callback, than 1152 * If cpu_dai, codec_dai, component driver has the delay callback, then
1244 * the runtime->delay will be updated accordingly. 1153 * the runtime->delay will be updated accordingly.
1245 */ 1154 */
1246static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) 1155static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1247{ 1156{
1248 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1157 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1249 struct snd_soc_platform *platform = rtd->platform;
1250 struct snd_soc_component *component; 1158 struct snd_soc_component *component;
1251 struct snd_soc_rtdcom_list *rtdcom; 1159 struct snd_soc_rtdcom_list *rtdcom;
1252 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1160 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -1257,16 +1165,9 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1257 snd_pcm_sframes_t codec_delay = 0; 1165 snd_pcm_sframes_t codec_delay = 0;
1258 int i; 1166 int i;
1259 1167
1260 if (platform && platform->driver->ops && platform->driver->ops->pointer)
1261 offset = platform->driver->ops->pointer(substream);
1262
1263 for_each_rtdcom(rtd, rtdcom) { 1168 for_each_rtdcom(rtd, rtdcom) {
1264 component = rtdcom->component; 1169 component = rtdcom->component;
1265 1170
1266 /* ignore duplication for now */
1267 if (platform && (component == &platform->component))
1268 continue;
1269
1270 if (!component->driver->ops || 1171 if (!component->driver->ops ||
1271 !component->driver->ops->pointer) 1172 !component->driver->ops->pointer)
1272 continue; 1173 continue;
@@ -1878,14 +1779,15 @@ static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
1878 1779
1879 /* Symmetry only applies if we've got an active stream. */ 1780 /* Symmetry only applies if we've got an active stream. */
1880 if (rtd->cpu_dai->active) { 1781 if (rtd->cpu_dai->active) {
1881 err = soc_pcm_apply_symmetry(be_substream, rtd->cpu_dai); 1782 err = soc_pcm_apply_symmetry(fe_substream,
1783 rtd->cpu_dai);
1882 if (err < 0) 1784 if (err < 0)
1883 return err; 1785 return err;
1884 } 1786 }
1885 1787
1886 for (i = 0; i < rtd->num_codecs; i++) { 1788 for (i = 0; i < rtd->num_codecs; i++) {
1887 if (rtd->codec_dais[i]->active) { 1789 if (rtd->codec_dais[i]->active) {
1888 err = soc_pcm_apply_symmetry(be_substream, 1790 err = soc_pcm_apply_symmetry(fe_substream,
1889 rtd->codec_dais[i]); 1791 rtd->codec_dais[i]);
1890 if (err < 0) 1792 if (err < 0)
1891 return err; 1793 return err;
@@ -1965,8 +1867,10 @@ int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1965 continue; 1867 continue;
1966 1868
1967 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && 1869 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1968 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) 1870 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) {
1969 continue; 1871 soc_pcm_hw_free(be_substream);
1872 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1873 }
1970 1874
1971 dev_dbg(be->dev, "ASoC: close BE %s\n", 1875 dev_dbg(be->dev, "ASoC: close BE %s\n",
1972 be->dai_link->name); 1876 be->dai_link->name);
@@ -2470,20 +2374,12 @@ static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
2470 unsigned int cmd, void *arg) 2374 unsigned int cmd, void *arg)
2471{ 2375{
2472 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2376 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2473 struct snd_soc_platform *platform = rtd->platform;
2474 struct snd_soc_component *component; 2377 struct snd_soc_component *component;
2475 struct snd_soc_rtdcom_list *rtdcom; 2378 struct snd_soc_rtdcom_list *rtdcom;
2476 2379
2477 if (platform && platform->driver->ops && platform->driver->ops->ioctl)
2478 return platform->driver->ops->ioctl(substream, cmd, arg);
2479
2480 for_each_rtdcom(rtd, rtdcom) { 2380 for_each_rtdcom(rtd, rtdcom) {
2481 component = rtdcom->component; 2381 component = rtdcom->component;
2482 2382
2483 /* ignore duplication for now */
2484 if (platform && (component == &platform->component))
2485 continue;
2486
2487 if (!component->driver->ops || 2383 if (!component->driver->ops ||
2488 !component->driver->ops->ioctl) 2384 !component->driver->ops->ioctl)
2489 continue; 2385 continue;
@@ -2847,8 +2743,8 @@ static void soc_pcm_private_free(struct snd_pcm *pcm)
2847 for_each_rtdcom(rtd, rtdcom) { 2743 for_each_rtdcom(rtd, rtdcom) {
2848 component = rtdcom->component; 2744 component = rtdcom->component;
2849 2745
2850 if (component->pcm_free) 2746 if (component->driver->pcm_free)
2851 component->pcm_free(component, pcm); 2747 component->driver->pcm_free(pcm);
2852 } 2748 }
2853} 2749}
2854 2750
@@ -2987,7 +2883,6 @@ static int soc_rtdcom_mmap(struct snd_pcm_substream *substream,
2987/* create a new pcm */ 2883/* create a new pcm */
2988int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2884int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2989{ 2885{
2990 struct snd_soc_platform *platform = rtd->platform;
2991 struct snd_soc_dai *codec_dai; 2886 struct snd_soc_dai *codec_dai;
2992 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2887 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2993 struct snd_soc_component *component; 2888 struct snd_soc_component *component;
@@ -3106,16 +3001,6 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3106 rtd->ops.mmap = soc_rtdcom_mmap; 3001 rtd->ops.mmap = soc_rtdcom_mmap;
3107 } 3002 }
3108 3003
3109 /* overwrite */
3110 if (platform && platform->driver->ops) {
3111 rtd->ops.ack = platform->driver->ops->ack;
3112 rtd->ops.copy_user = platform->driver->ops->copy_user;
3113 rtd->ops.copy_kernel = platform->driver->ops->copy_kernel;
3114 rtd->ops.fill_silence = platform->driver->ops->fill_silence;
3115 rtd->ops.page = platform->driver->ops->page;
3116 rtd->ops.mmap = platform->driver->ops->mmap;
3117 }
3118
3119 if (playback) 3004 if (playback)
3120 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops); 3005 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
3121 3006
@@ -3125,10 +3010,10 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3125 for_each_rtdcom(rtd, rtdcom) { 3010 for_each_rtdcom(rtd, rtdcom) {
3126 component = rtdcom->component; 3011 component = rtdcom->component;
3127 3012
3128 if (!component->pcm_new) 3013 if (!component->driver->pcm_new)
3129 continue; 3014 continue;
3130 3015
3131 ret = component->pcm_new(component, rtd); 3016 ret = component->driver->pcm_new(rtd);
3132 if (ret < 0) { 3017 if (ret < 0) {
3133 dev_err(component->dev, 3018 dev_err(component->dev,
3134 "ASoC: pcm constructor failed: %d\n", 3019 "ASoC: pcm constructor failed: %d\n",
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 986b8b2f90fb..3fd5d9c867b9 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -54,62 +54,6 @@
54#define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST 54#define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST
55#define SOC_TPLG_PASS_END SOC_TPLG_PASS_LINK 55#define SOC_TPLG_PASS_END SOC_TPLG_PASS_LINK
56 56
57/*
58 * Old version of ABI structs, supported for backward compatibility.
59 */
60
61/* Manifest v4 */
62struct snd_soc_tplg_manifest_v4 {
63 __le32 size; /* in bytes of this structure */
64 __le32 control_elems; /* number of control elements */
65 __le32 widget_elems; /* number of widget elements */
66 __le32 graph_elems; /* number of graph elements */
67 __le32 pcm_elems; /* number of PCM elements */
68 __le32 dai_link_elems; /* number of DAI link elements */
69 struct snd_soc_tplg_private priv;
70} __packed;
71
72/* Stream Capabilities v4 */
73struct snd_soc_tplg_stream_caps_v4 {
74 __le32 size; /* in bytes of this structure */
75 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
76 __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
77 __le32 rates; /* supported rates SNDRV_PCM_RATE_* */
78 __le32 rate_min; /* min rate */
79 __le32 rate_max; /* max rate */
80 __le32 channels_min; /* min channels */
81 __le32 channels_max; /* max channels */
82 __le32 periods_min; /* min number of periods */
83 __le32 periods_max; /* max number of periods */
84 __le32 period_size_min; /* min period size bytes */
85 __le32 period_size_max; /* max period size bytes */
86 __le32 buffer_size_min; /* min buffer size bytes */
87 __le32 buffer_size_max; /* max buffer size bytes */
88} __packed;
89
90/* PCM v4 */
91struct snd_soc_tplg_pcm_v4 {
92 __le32 size; /* in bytes of this structure */
93 char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
94 char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
95 __le32 pcm_id; /* unique ID - used to match with DAI link */
96 __le32 dai_id; /* unique ID - used to match */
97 __le32 playback; /* supports playback mode */
98 __le32 capture; /* supports capture mode */
99 __le32 compress; /* 1 = compressed; 0 = PCM */
100 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
101 __le32 num_streams; /* number of streams */
102 struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */
103} __packed;
104
105/* Physical link config v4 */
106struct snd_soc_tplg_link_config_v4 {
107 __le32 size; /* in bytes of this structure */
108 __le32 id; /* unique ID - used to match */
109 struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
110 __le32 num_streams; /* number of streams */
111} __packed;
112
113/* topology context */ 57/* topology context */
114struct soc_tplg { 58struct soc_tplg {
115 const struct firmware *fw; 59 const struct firmware *fw;
@@ -1754,6 +1698,9 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
1754 set_stream_info(stream, caps); 1698 set_stream_info(stream, caps);
1755 } 1699 }
1756 1700
1701 if (pcm->compress)
1702 dai_drv->compress_new = snd_soc_new_compress;
1703
1757 /* pass control to component driver for optional further init */ 1704 /* pass control to component driver for optional further init */
1758 ret = soc_tplg_dai_load(tplg, dai_drv); 1705 ret = soc_tplg_dai_load(tplg, dai_drv);
1759 if (ret < 0) { 1706 if (ret < 0) {
@@ -2006,6 +1953,21 @@ static void set_link_hw_format(struct snd_soc_dai_link *link,
2006 1953
2007 link->dai_fmt = hw_config->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 1954 link->dai_fmt = hw_config->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
2008 1955
1956 /* clock gating */
1957 switch (hw_config->clock_gated) {
1958 case SND_SOC_TPLG_DAI_CLK_GATE_GATED:
1959 link->dai_fmt |= SND_SOC_DAIFMT_GATED;
1960 break;
1961
1962 case SND_SOC_TPLG_DAI_CLK_GATE_CONT:
1963 link->dai_fmt |= SND_SOC_DAIFMT_CONT;
1964 break;
1965
1966 default:
1967 /* ignore the value */
1968 break;
1969 }
1970
2009 /* clock signal polarity */ 1971 /* clock signal polarity */
2010 invert_bclk = hw_config->invert_bclk; 1972 invert_bclk = hw_config->invert_bclk;
2011 invert_fsync = hw_config->invert_fsync; 1973 invert_fsync = hw_config->invert_fsync;
@@ -2019,13 +1981,15 @@ static void set_link_hw_format(struct snd_soc_dai_link *link,
2019 link->dai_fmt |= SND_SOC_DAIFMT_IB_IF; 1981 link->dai_fmt |= SND_SOC_DAIFMT_IB_IF;
2020 1982
2021 /* clock masters */ 1983 /* clock masters */
2022 bclk_master = hw_config->bclk_master; 1984 bclk_master = (hw_config->bclk_master ==
2023 fsync_master = hw_config->fsync_master; 1985 SND_SOC_TPLG_BCLK_CM);
2024 if (!bclk_master && !fsync_master) 1986 fsync_master = (hw_config->fsync_master ==
1987 SND_SOC_TPLG_FSYNC_CM);
1988 if (bclk_master && fsync_master)
2025 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 1989 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
2026 else if (bclk_master && !fsync_master)
2027 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFM;
2028 else if (!bclk_master && fsync_master) 1990 else if (!bclk_master && fsync_master)
1991 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFM;
1992 else if (bclk_master && !fsync_master)
2029 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; 1993 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFS;
2030 else 1994 else
2031 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; 1995 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
@@ -2293,8 +2257,11 @@ static int manifest_new_ver(struct soc_tplg *tplg,
2293 *manifest = NULL; 2257 *manifest = NULL;
2294 2258
2295 if (src->size != sizeof(*src_v4)) { 2259 if (src->size != sizeof(*src_v4)) {
2296 dev_err(tplg->dev, "ASoC: invalid manifest size\n"); 2260 dev_warn(tplg->dev, "ASoC: invalid manifest size %d\n",
2297 return -EINVAL; 2261 src->size);
2262 if (src->size)
2263 return -EINVAL;
2264 src->size = sizeof(*src_v4);
2298 } 2265 }
2299 2266
2300 dev_warn(tplg->dev, "ASoC: old version of manifest\n"); 2267 dev_warn(tplg->dev, "ASoC: old version of manifest\n");
diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-compress.c
index 4c1027aa615e..17f773ac5ca1 100644
--- a/sound/soc/uniphier/aio-compress.c
+++ b/sound/soc/uniphier/aio-compress.c
@@ -3,19 +3,6 @@
3// Socionext UniPhier AIO Compress Audio driver. 3// Socionext UniPhier AIO Compress Audio driver.
4// 4//
5// Copyright (c) 2017-2018 Socionext Inc. 5// Copyright (c) 2017-2018 Socionext Inc.
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; version 2
10// of the License.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, see <http://www.gnu.org/licenses/>.
19 6
20#include <linux/bitfield.h> 7#include <linux/bitfield.h>
21#include <linux/circ_buf.h> 8#include <linux/circ_buf.h>
diff --git a/sound/soc/uniphier/aio-core.c b/sound/soc/uniphier/aio-core.c
index 6d50042a4571..638cb3fc5f7b 100644
--- a/sound/soc/uniphier/aio-core.c
+++ b/sound/soc/uniphier/aio-core.c
@@ -3,19 +3,6 @@
3// Socionext UniPhier AIO ALSA common driver. 3// Socionext UniPhier AIO ALSA common driver.
4// 4//
5// Copyright (c) 2016-2018 Socionext Inc. 5// Copyright (c) 2016-2018 Socionext Inc.
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; version 2
10// of the License.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, see <http://www.gnu.org/licenses/>.
19 6
20#include <linux/bitfield.h> 7#include <linux/bitfield.h>
21#include <linux/errno.h> 8#include <linux/errno.h>
@@ -673,6 +660,64 @@ void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable)
673} 660}
674 661
675/** 662/**
663 * aio_port_get_volume - get volume of AIO port block
664 * @sub: the AIO substream pointer
665 *
666 * Return: current volume, range is 0x0000 - 0xffff
667 */
668int aio_port_get_volume(struct uniphier_aio_sub *sub)
669{
670 struct regmap *r = sub->aio->chip->regmap;
671 u32 v;
672
673 regmap_read(r, OPORTMXTYVOLGAINSTATUS(sub->swm->oport.map, 0), &v);
674
675 return FIELD_GET(OPORTMXTYVOLGAINSTATUS_CUR_MASK, v);
676}
677
678/**
679 * aio_port_set_volume - set volume of AIO port block
680 * @sub: the AIO substream pointer
681 * @vol: target volume, range is 0x0000 - 0xffff.
682 *
683 * Change digital volume and perfome fade-out/fade-in effect for specified
684 * output slot of port. Gained PCM value can calculate as the following:
685 * Gained = Original * vol / 0x4000
686 */
687void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol)
688{
689 struct regmap *r = sub->aio->chip->regmap;
690 int oport_map = sub->swm->oport.map;
691 int cur, diff, slope = 0, fs;
692
693 if (sub->swm->dir == PORT_DIR_INPUT)
694 return;
695
696 cur = aio_port_get_volume(sub);
697 diff = abs(vol - cur);
698 fs = params_rate(&sub->params);
699 if (fs)
700 slope = diff / AUD_VOL_FADE_TIME * 1000 / fs;
701 slope = max(1, slope);
702
703 regmap_update_bits(r, OPORTMXTYVOLPARA1(oport_map, 0),
704 OPORTMXTYVOLPARA1_SLOPEU_MASK, slope << 16);
705 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
706 OPORTMXTYVOLPARA2_TARGET_MASK, vol);
707
708 if (cur < vol)
709 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
710 OPORTMXTYVOLPARA2_FADE_MASK,
711 OPORTMXTYVOLPARA2_FADE_FADEIN);
712 else
713 regmap_update_bits(r, OPORTMXTYVOLPARA2(oport_map, 0),
714 OPORTMXTYVOLPARA2_FADE_MASK,
715 OPORTMXTYVOLPARA2_FADE_FADEOUT);
716
717 regmap_write(r, AOUTFADECTR0, BIT(oport_map));
718}
719
720/**
676 * aio_if_set_param - set parameters of AIO DMA I/F block 721 * aio_if_set_param - set parameters of AIO DMA I/F block
677 * @sub: the AIO substream pointer 722 * @sub: the AIO substream pointer
678 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM. 723 * @pass_through: Zero if sound data is LPCM, otherwise if data is not LPCM.
diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index 1e5eb8e6f8c7..80daec17be25 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -3,19 +3,6 @@
3// Socionext UniPhier AIO ALSA CPU DAI driver. 3// Socionext UniPhier AIO ALSA CPU DAI driver.
4// 4//
5// Copyright (c) 2016-2018 Socionext Inc. 5// Copyright (c) 2016-2018 Socionext Inc.
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; version 2
10// of the License.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, see <http://www.gnu.org/licenses/>.
19 6
20#include <linux/clk.h> 7#include <linux/clk.h>
21#include <linux/errno.h> 8#include <linux/errno.h>
@@ -45,6 +32,35 @@ static bool is_valid_pll(struct uniphier_aio_chip *chip, int pll_id)
45 return chip->plls[pll_id].enable; 32 return chip->plls[pll_id].enable;
46} 33}
47 34
35/**
36 * find_volume - find volume supported HW port by HW port number
37 * @chip: the AIO chip pointer
38 * @oport_hw: HW port number, one of AUD_HW_XXXX
39 *
40 * Find AIO device from device list by HW port number. Volume feature is
41 * available only in Output and PCM ports, this limitation comes from HW
42 * specifications.
43 *
44 * Return: The pointer of AIO substream if successful, otherwise NULL on error.
45 */
46static struct uniphier_aio_sub *find_volume(struct uniphier_aio_chip *chip,
47 int oport_hw)
48{
49 int i;
50
51 for (i = 0; i < chip->num_aios; i++) {
52 struct uniphier_aio_sub *sub = &chip->aios[i].sub[0];
53
54 if (!sub->swm)
55 continue;
56
57 if (sub->swm->oport.hw == oport_hw)
58 return sub;
59 }
60
61 return NULL;
62}
63
48static bool match_spec(const struct uniphier_aio_spec *spec, 64static bool match_spec(const struct uniphier_aio_spec *spec,
49 const char *name, int dir) 65 const char *name, int dir)
50{ 66{
@@ -300,6 +316,7 @@ static int uniphier_aio_hw_params(struct snd_pcm_substream *substream,
300 sub->setting = 1; 316 sub->setting = 1;
301 317
302 aio_port_reset(sub); 318 aio_port_reset(sub);
319 aio_port_set_volume(sub, sub->vol);
303 aio_src_reset(sub); 320 aio_src_reset(sub);
304 321
305 return 0; 322 return 0;
@@ -386,6 +403,8 @@ int uniphier_aio_dai_probe(struct snd_soc_dai *dai)
386 403
387 sub->swm = &spec->swm; 404 sub->swm = &spec->swm;
388 sub->spec = spec; 405 sub->spec = spec;
406
407 sub->vol = AUD_VOL_INIT;
389 } 408 }
390 409
391 aio_iecout_set_enable(aio->chip, true); 410 aio_iecout_set_enable(aio->chip, true);
@@ -462,8 +481,116 @@ err_out_clock:
462} 481}
463EXPORT_SYMBOL_GPL(uniphier_aio_dai_resume); 482EXPORT_SYMBOL_GPL(uniphier_aio_dai_resume);
464 483
484static int uniphier_aio_vol_info(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_info *uinfo)
486{
487 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
488 uinfo->count = 1;
489 uinfo->value.integer.min = 0;
490 uinfo->value.integer.max = AUD_VOL_MAX;
491
492 return 0;
493}
494
495static int uniphier_aio_vol_get(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
497{
498 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
499 struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp);
500 struct uniphier_aio_sub *sub;
501 int oport_hw = kcontrol->private_value;
502
503 sub = find_volume(chip, oport_hw);
504 if (!sub)
505 return 0;
506
507 ucontrol->value.integer.value[0] = sub->vol;
508
509 return 0;
510}
511
512static int uniphier_aio_vol_put(struct snd_kcontrol *kcontrol,
513 struct snd_ctl_elem_value *ucontrol)
514{
515 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
516 struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp);
517 struct uniphier_aio_sub *sub;
518 int oport_hw = kcontrol->private_value;
519
520 sub = find_volume(chip, oport_hw);
521 if (!sub)
522 return 0;
523
524 if (sub->vol == ucontrol->value.integer.value[0])
525 return 0;
526 sub->vol = ucontrol->value.integer.value[0];
527
528 aio_port_set_volume(sub, sub->vol);
529
530 return 0;
531}
532
533static const struct snd_kcontrol_new uniphier_aio_controls[] = {
534 {
535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
536 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
537 .name = "HPCMOUT1 Volume",
538 .info = uniphier_aio_vol_info,
539 .get = uniphier_aio_vol_get,
540 .put = uniphier_aio_vol_put,
541 .private_value = AUD_HW_HPCMOUT1,
542 },
543 {
544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
545 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
546 .name = "PCMOUT1 Volume",
547 .info = uniphier_aio_vol_info,
548 .get = uniphier_aio_vol_get,
549 .put = uniphier_aio_vol_put,
550 .private_value = AUD_HW_PCMOUT1,
551 },
552 {
553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
554 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
555 .name = "PCMOUT2 Volume",
556 .info = uniphier_aio_vol_info,
557 .get = uniphier_aio_vol_get,
558 .put = uniphier_aio_vol_put,
559 .private_value = AUD_HW_PCMOUT2,
560 },
561 {
562 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
563 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
564 .name = "PCMOUT3 Volume",
565 .info = uniphier_aio_vol_info,
566 .get = uniphier_aio_vol_get,
567 .put = uniphier_aio_vol_put,
568 .private_value = AUD_HW_PCMOUT3,
569 },
570 {
571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
572 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
573 .name = "HIECOUT1 Volume",
574 .info = uniphier_aio_vol_info,
575 .get = uniphier_aio_vol_get,
576 .put = uniphier_aio_vol_put,
577 .private_value = AUD_HW_HIECOUT1,
578 },
579 {
580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
581 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
582 .name = "IECOUT1 Volume",
583 .info = uniphier_aio_vol_info,
584 .get = uniphier_aio_vol_get,
585 .put = uniphier_aio_vol_put,
586 .private_value = AUD_HW_IECOUT1,
587 },
588};
589
465static const struct snd_soc_component_driver uniphier_aio_component = { 590static const struct snd_soc_component_driver uniphier_aio_component = {
466 .name = "uniphier-aio", 591 .name = "uniphier-aio",
592 .controls = uniphier_aio_controls,
593 .num_controls = ARRAY_SIZE(uniphier_aio_controls),
467}; 594};
468 595
469int uniphier_aio_probe(struct platform_device *pdev) 596int uniphier_aio_probe(struct platform_device *pdev)
diff --git a/sound/soc/uniphier/aio-dma.c b/sound/soc/uniphier/aio-dma.c
index ef7bafa8e171..4ec6b65bfb44 100644
--- a/sound/soc/uniphier/aio-dma.c
+++ b/sound/soc/uniphier/aio-dma.c
@@ -3,19 +3,6 @@
3// Socionext UniPhier AIO DMA driver. 3// Socionext UniPhier AIO DMA driver.
4// 4//
5// Copyright (c) 2016-2018 Socionext Inc. 5// Copyright (c) 2016-2018 Socionext Inc.
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; version 2
10// of the License.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, see <http://www.gnu.org/licenses/>.
19 6
20#include <linux/dma-mapping.h> 7#include <linux/dma-mapping.h>
21#include <linux/errno.h> 8#include <linux/errno.h>
diff --git a/sound/soc/uniphier/aio-ld11.c b/sound/soc/uniphier/aio-ld11.c
index 4c4dd3dd4dee..ab04d3331be9 100644
--- a/sound/soc/uniphier/aio-ld11.c
+++ b/sound/soc/uniphier/aio-ld11.c
@@ -3,19 +3,6 @@
3// Socionext UniPhier AIO ALSA driver for LD11/LD20. 3// Socionext UniPhier AIO ALSA driver for LD11/LD20.
4// 4//
5// Copyright (c) 2016-2018 Socionext Inc. 5// Copyright (c) 2016-2018 Socionext Inc.
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; version 2
10// of the License.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, see <http://www.gnu.org/licenses/>.
19 6
20#include <linux/module.h> 7#include <linux/module.h>
21 8
diff --git a/sound/soc/uniphier/aio-reg.h b/sound/soc/uniphier/aio-reg.h
index 136d3563cf44..45fdc6ae358a 100644
--- a/sound/soc/uniphier/aio-reg.h
+++ b/sound/soc/uniphier/aio-reg.h
@@ -3,19 +3,6 @@
3 * Socionext UniPhier AIO ALSA driver. 3 * Socionext UniPhier AIO ALSA driver.
4 * 4 *
5 * Copyright (c) 2016-2018 Socionext Inc. 5 * Copyright (c) 2016-2018 Socionext Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */ 6 */
20 7
21#ifndef SND_UNIPHIER_AIO_REG_H__ 8#ifndef SND_UNIPHIER_AIO_REG_H__
@@ -182,6 +169,7 @@
182#define PBINMXPAUSECTR1(n) (0x20208 + 0x40 * (n)) 169#define PBINMXPAUSECTR1(n) (0x20208 + 0x40 * (n))
183 170
184/* AOUT */ 171/* AOUT */
172#define AOUTFADECTR0 0x40020
185#define AOUTENCTR0 0x40040 173#define AOUTENCTR0 0x40040
186#define AOUTENCTR1 0x40044 174#define AOUTENCTR1 0x40044
187#define AOUTENCTR2 0x40048 175#define AOUTENCTR2 0x40048
@@ -192,6 +180,9 @@
192#define AOUTSRCRSTCTR1 0x400c4 180#define AOUTSRCRSTCTR1 0x400c4
193#define AOUTSRCRSTCTR2 0x400c8 181#define AOUTSRCRSTCTR2 0x400c8
194 182
183/* AOUT PCMOUT has 5 slots, slot0-3: D0-3, slot4: DMIX */
184#define OPORT_SLOT_MAX 5
185
195/* AOUT(PCMOUTN) */ 186/* AOUT(PCMOUTN) */
196#define OPORTMXCTR1(n) (0x42000 + 0x400 * (n)) 187#define OPORTMXCTR1(n) (0x42000 + 0x400 * (n))
197#define OPORTMXCTR1_I2SLRSEL_MASK (0x11 << 10) 188#define OPORTMXCTR1_I2SLRSEL_MASK (0x11 << 10)
@@ -372,11 +363,30 @@
372#define OPORTMXMASK_XCKMSK_ON (0x0 << 0) 363#define OPORTMXMASK_XCKMSK_ON (0x0 << 0)
373#define OPORTMXMASK_XCKMSK_OFF (0x7 << 0) 364#define OPORTMXMASK_XCKMSK_OFF (0x7 << 0)
374#define OPORTMXDEBUG(n) (0x420fc + 0x400 * (n)) 365#define OPORTMXDEBUG(n) (0x420fc + 0x400 * (n))
375#define OPORTMXT0RSTCTR(n) (0x4211c + 0x400 * (n)) 366#define OPORTMXTYVOLPARA1(n, m) (0x42100 + 0x400 * (n) + 0x20 * (m))
376#define OPORTMXT1RSTCTR(n) (0x4213c + 0x400 * (n)) 367#define OPORTMXTYVOLPARA1_SLOPEU_MASK GENMASK(31, 16)
377#define OPORTMXT2RSTCTR(n) (0x4215c + 0x400 * (n)) 368#define OPORTMXTYVOLPARA2(n, m) (0x42104 + 0x400 * (n) + 0x20 * (m))
378#define OPORTMXT3RSTCTR(n) (0x4217c + 0x400 * (n)) 369#define OPORTMXTYVOLPARA2_FADE_MASK GENMASK(17, 16)
379#define OPORTMXT4RSTCTR(n) (0x4219c + 0x400 * (n)) 370#define OPORTMXTYVOLPARA2_FADE_NOOP (0x0 << 16)
371#define OPORTMXTYVOLPARA2_FADE_FADEOUT (0x1 << 16)
372#define OPORTMXTYVOLPARA2_FADE_FADEIN (0x2 << 16)
373#define OPORTMXTYVOLPARA2_TARGET_MASK GENMASK(15, 0)
374#define OPORTMXTYVOLGAINSTATUS(n, m) (0x42108 + 0x400 * (n) + 0x20 * (m))
375#define OPORTMXTYVOLGAINSTATUS_CUR_MASK GENMASK(15, 0)
376#define OPORTMXTYSLOTCTR(n, m) (0x42114 + 0x400 * (n) + 0x20 * (m))
377#define OPORTMXTYSLOTCTR_SLOTSEL_MASK GENMASK(11, 8)
378#define OPORTMXTYSLOTCTR_SLOTSEL_SLOT0 (0x8 << 8)
379#define OPORTMXTYSLOTCTR_SLOTSEL_SLOT1 (0x9 << 8)
380#define OPORTMXTYSLOTCTR_SLOTSEL_SLOT2 (0xa << 8)
381#define OPORTMXTYSLOTCTR_SLOTSEL_SLOT3 (0xb << 8)
382#define OPORTMXTYSLOTCTR_SLOTSEL_SLOT4 (0xc << 8)
383#define OPORTMXT0SLOTCTR_MUTEOFF_MASK BIT(1)
384#define OPORTMXT0SLOTCTR_MUTEOFF_MUTE (0x0 << 1)
385#define OPORTMXT0SLOTCTR_MUTEOFF_UNMUTE (0x1 << 1)
386#define OPORTMXTYRSTCTR(n, m) (0x4211c + 0x400 * (n) + 0x20 * (m))
387#define OPORTMXT0RSTCTR_RST_MASK BIT(1)
388#define OPORTMXT0RSTCTR_RST_OFF (0x0 << 1)
389#define OPORTMXT0RSTCTR_RST_ON (0x1 << 1)
380 390
381#define SBF_(frame, shift) (((frame) * 2 - 1) << shift) 391#define SBF_(frame, shift) (((frame) * 2 - 1) << shift)
382 392
diff --git a/sound/soc/uniphier/aio.h b/sound/soc/uniphier/aio.h
index 8cab4a553a97..aa89c2f6fa24 100644
--- a/sound/soc/uniphier/aio.h
+++ b/sound/soc/uniphier/aio.h
@@ -3,19 +3,6 @@
3 * Socionext UniPhier AIO ALSA driver. 3 * Socionext UniPhier AIO ALSA driver.
4 * 4 *
5 * Copyright (c) 2016-2018 Socionext Inc. 5 * Copyright (c) 2016-2018 Socionext Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */ 6 */
20 7
21#ifndef SND_UNIPHIER_AIO_H__ 8#ifndef SND_UNIPHIER_AIO_H__
@@ -143,6 +130,10 @@ enum IEC61937_PC {
143#define AUD_PLLDIV_1_1 2 130#define AUD_PLLDIV_1_1 2
144#define AUD_PLLDIV_2_3 3 131#define AUD_PLLDIV_2_3 3
145 132
133#define AUD_VOL_INIT 0x4000 /* +0dB */
134#define AUD_VOL_MAX 0xffff /* +6dB */
135#define AUD_VOL_FADE_TIME 20 /* 20ms */
136
146#define AUD_RING_SIZE (128 * 1024) 137#define AUD_RING_SIZE (128 * 1024)
147 138
148#define AUD_MIN_FRAGMENT 4 139#define AUD_MIN_FRAGMENT 4
@@ -244,6 +235,7 @@ struct uniphier_aio_sub {
244 /* For PCM audio */ 235 /* For PCM audio */
245 struct snd_pcm_substream *substream; 236 struct snd_pcm_substream *substream;
246 struct snd_pcm_hw_params params; 237 struct snd_pcm_hw_params params;
238 int vol;
247 239
248 /* For compress audio */ 240 /* For compress audio */
249 struct snd_compr_stream *cstream; 241 struct snd_compr_stream *cstream;
@@ -336,6 +328,8 @@ int aio_port_set_clk(struct uniphier_aio_sub *sub);
336int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through, 328int aio_port_set_param(struct uniphier_aio_sub *sub, int pass_through,
337 const struct snd_pcm_hw_params *params); 329 const struct snd_pcm_hw_params *params);
338void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable); 330void aio_port_set_enable(struct uniphier_aio_sub *sub, int enable);
331int aio_port_get_volume(struct uniphier_aio_sub *sub);
332void aio_port_set_volume(struct uniphier_aio_sub *sub, int vol);
339int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through); 333int aio_if_set_param(struct uniphier_aio_sub *sub, int pass_through);
340int aio_oport_set_stream_type(struct uniphier_aio_sub *sub, 334int aio_oport_set_stream_type(struct uniphier_aio_sub *sub,
341 enum IEC61937_PC pc); 335 enum IEC61937_PC pc);
diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c
index 73fd6730095c..f9c10165fbc1 100644
--- a/sound/soc/uniphier/evea.c
+++ b/sound/soc/uniphier/evea.c
@@ -54,8 +54,21 @@ struct evea_priv {
54 int switch_hp; 54 int switch_hp;
55}; 55};
56 56
57static const char * const linsw1_sel1_text[] = {
58 "LIN1", "LIN2", "LIN3"
59};
60
61static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
62 ALINSW1, ALINSW1_SEL1_SHIFT,
63 linsw1_sel1_text);
64
65static const struct snd_kcontrol_new linesw1_mux[] = {
66 SOC_DAPM_ENUM("Line In 1 Source", linsw1_sel1_enum),
67};
68
57static const struct snd_soc_dapm_widget evea_widgets[] = { 69static const struct snd_soc_dapm_widget evea_widgets[] = {
58 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 70 SND_SOC_DAPM_ADC("ADC", NULL, SND_SOC_NOPM, 0, 0),
71 SND_SOC_DAPM_MUX("Line In 1 Mux", SND_SOC_NOPM, 0, 0, linesw1_mux),
59 SND_SOC_DAPM_INPUT("LIN1_LP"), 72 SND_SOC_DAPM_INPUT("LIN1_LP"),
60 SND_SOC_DAPM_INPUT("LIN1_RP"), 73 SND_SOC_DAPM_INPUT("LIN1_RP"),
61 SND_SOC_DAPM_INPUT("LIN2_LP"), 74 SND_SOC_DAPM_INPUT("LIN2_LP"),
@@ -63,7 +76,9 @@ static const struct snd_soc_dapm_widget evea_widgets[] = {
63 SND_SOC_DAPM_INPUT("LIN3_LP"), 76 SND_SOC_DAPM_INPUT("LIN3_LP"),
64 SND_SOC_DAPM_INPUT("LIN3_RP"), 77 SND_SOC_DAPM_INPUT("LIN3_RP"),
65 78
66 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), 79 SND_SOC_DAPM_DAC("DAC HP", NULL, SND_SOC_NOPM, 0, 0),
80 SND_SOC_DAPM_DAC("DAC LO1", NULL, SND_SOC_NOPM, 0, 0),
81 SND_SOC_DAPM_DAC("DAC LO2", NULL, SND_SOC_NOPM, 0, 0),
67 SND_SOC_DAPM_OUTPUT("HP1_L"), 82 SND_SOC_DAPM_OUTPUT("HP1_L"),
68 SND_SOC_DAPM_OUTPUT("HP1_R"), 83 SND_SOC_DAPM_OUTPUT("HP1_R"),
69 SND_SOC_DAPM_OUTPUT("LO2_L"), 84 SND_SOC_DAPM_OUTPUT("LO2_L"),
@@ -71,17 +86,22 @@ static const struct snd_soc_dapm_widget evea_widgets[] = {
71}; 86};
72 87
73static const struct snd_soc_dapm_route evea_routes[] = { 88static const struct snd_soc_dapm_route evea_routes[] = {
74 { "ADC", NULL, "LIN1_LP" }, 89 { "Line In 1", NULL, "ADC" },
75 { "ADC", NULL, "LIN1_RP" }, 90 { "ADC", NULL, "Line In 1 Mux" },
76 { "ADC", NULL, "LIN2_LP" }, 91 { "Line In 1 Mux", "LIN1", "LIN1_LP" },
77 { "ADC", NULL, "LIN2_RP" }, 92 { "Line In 1 Mux", "LIN1", "LIN1_RP" },
78 { "ADC", NULL, "LIN3_LP" }, 93 { "Line In 1 Mux", "LIN2", "LIN2_LP" },
79 { "ADC", NULL, "LIN3_RP" }, 94 { "Line In 1 Mux", "LIN2", "LIN2_RP" },
80 95 { "Line In 1 Mux", "LIN3", "LIN3_LP" },
81 { "HP1_L", NULL, "DAC" }, 96 { "Line In 1 Mux", "LIN3", "LIN3_RP" },
82 { "HP1_R", NULL, "DAC" }, 97
83 { "LO2_L", NULL, "DAC" }, 98 { "DAC HP", NULL, "Headphone 1" },
84 { "LO2_R", NULL, "DAC" }, 99 { "DAC LO1", NULL, "Line Out 1" },
100 { "DAC LO2", NULL, "Line Out 2" },
101 { "HP1_L", NULL, "DAC HP" },
102 { "HP1_R", NULL, "DAC HP" },
103 { "LO2_L", NULL, "DAC LO2" },
104 { "LO2_R", NULL, "DAC LO2" },
85}; 105};
86 106
87static void evea_set_power_state_on(struct evea_priv *evea) 107static void evea_set_power_state_on(struct evea_priv *evea)
@@ -280,16 +300,7 @@ static int evea_set_switch_hp(struct snd_kcontrol *kcontrol,
280 return evea_update_switch_hp(evea); 300 return evea_update_switch_hp(evea);
281} 301}
282 302
283static const char * const linsw1_sel1_text[] = {
284 "LIN1", "LIN2", "LIN3"
285};
286
287static SOC_ENUM_SINGLE_DECL(linsw1_sel1_enum,
288 ALINSW1, ALINSW1_SEL1_SHIFT,
289 linsw1_sel1_text);
290
291static const struct snd_kcontrol_new evea_controls[] = { 303static const struct snd_kcontrol_new evea_controls[] = {
292 SOC_ENUM("Line Capture Source", linsw1_sel1_enum),
293 SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0, 304 SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0,
294 evea_get_switch_lin, evea_set_switch_lin), 305 evea_get_switch_lin, evea_set_switch_lin),
295 SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0, 306 SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0,
diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c
index 9a0565937d1f..0d36630aa1a7 100644
--- a/sound/soc/zte/zx-i2s.c
+++ b/sound/soc/zte/zx-i2s.c
@@ -20,9 +20,6 @@
20#include <sound/core.h> 20#include <sound/core.h>
21#include <sound/dmaengine_pcm.h> 21#include <sound/dmaengine_pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26 23
27#define ZX_I2S_PROCESS_CTRL 0x04 24#define ZX_I2S_PROCESS_CTRL 0x04
28#define ZX_I2S_TIMING_CTRL 0x08 25#define ZX_I2S_TIMING_CTRL 0x08
@@ -197,7 +194,7 @@ static int zx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
197 val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_LSB_JUSTIF); 194 val |= (ZX_I2S_TIMING_I2S | ZX_I2S_TIMING_LSB_JUSTIF);
198 break; 195 break;
199 default: 196 default:
200 dev_err(cpu_dai->dev, "Unknown i2s timeing\n"); 197 dev_err(cpu_dai->dev, "Unknown i2s timing\n");
201 return -EINVAL; 198 return -EINVAL;
202 } 199 }
203 200