aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-12-23 02:33:52 -0500
committerTakashi Iwai <tiwai@suse.de>2015-12-23 02:33:52 -0500
commitf80e39e0225c01ee68764ef7594c3a29ab5ebabb (patch)
treef5a85085741a173c93fc8f21938528b65ed95e42
parent59c8231089be96165735585694a801ae58ec6c95 (diff)
parent822ad70a2f5c420da5baa9f4354e6b7813ca6da9 (diff)
Merge tag 'asoc-v4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v4.5 This is quite a busy release on the driver front with a lot of new drivers being added but comparatively quiet on the core side with only one big change going in and that a fairly straightforward refactoring. - Conversion of the array of DAI links to a list by Mengdong Lin, supporting dynamically adding and removing DAI links. - Some more fixes for the topology code, though it is still not final and ready for enabling in production. We really need to get to the point where that can be done. - A pile of changes for Intel SkyLake drivers which hopefully deliver some useful initial functionality for systems with this chipset, though there is more work still to come. - New drivers for a number of Imagination Technologies IPs. - Lots of new features and cleanups for the Renesas drivers. - ANC support for WM5110. - New driver for Atmel class D speaker drivers. - New drivers for Cirrus CS47L24 and WM1831. - New driver for Dialog DA7128. - New drivers for Realtek RT5659 and RT56156. - New driver for Rockchip RK3036. - New driver for TI PC3168A
-rw-r--r--Documentation/devicetree/bindings/sound/ak4613.txt10
-rw-r--r--Documentation/devicetree/bindings/sound/atmel-classd.txt6
-rw-r--r--Documentation/devicetree/bindings/sound/atmel-pdmic.txt55
-rw-r--r--Documentation/devicetree/bindings/sound/da7218.txt104
-rw-r--r--Documentation/devicetree/bindings/sound/da7219.txt8
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,asrc.txt5
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,esai.txt5
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,spdif.txt5
-rw-r--r--Documentation/devicetree/bindings/sound/img,i2s-in.txt47
-rw-r--r--Documentation/devicetree/bindings/sound/img,i2s-out.txt51
-rw-r--r--Documentation/devicetree/bindings/sound/img,parallel-out.txt44
-rw-r--r--Documentation/devicetree/bindings/sound/img,pistachio-internal-dac.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/img,spdif-in.txt41
-rw-r--r--Documentation/devicetree/bindings/sound/img,spdif-out.txt44
-rw-r--r--Documentation/devicetree/bindings/sound/inno-rk3036.txt20
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.txt82
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/rockchip-i2s.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/rt5616.txt26
-rw-r--r--Documentation/devicetree/bindings/sound/rt5659.txt75
-rw-r--r--Documentation/devicetree/bindings/sound/rt5677.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/sun4i-codec.txt3
-rw-r--r--Documentation/devicetree/bindings/sound/ti,pcm3168a.txt48
-rw-r--r--Documentation/devicetree/bindings/sound/wlf,wm8974.txt15
-rw-r--r--Documentation/sound/alsa/img,spdif-in.txt49
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c47
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h52
-rw-r--r--arch/arm/plat-samsung/devs.c23
-rw-r--r--arch/x86/include/asm/platform_sst_audio.h1
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--include/linux/platform_data/asoc-s3c.h8
-rw-r--r--include/sound/ac97_codec.h3
-rw-r--r--include/sound/da7218.h109
-rw-r--r--include/sound/da7219.h14
-rw-r--r--include/sound/designware_i2s.h5
-rw-r--r--include/sound/hdaudio_ext.h6
-rw-r--r--include/sound/rt5659.h49
-rw-r--r--include/sound/soc-dapm.h4
-rw-r--r--include/sound/soc-topology.h6
-rw-r--r--include/sound/soc.h42
-rw-r--r--include/uapi/sound/asoc.h2
-rw-r--r--include/uapi/sound/compress_params.h5
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-classd.c26
-rw-r--r--sound/soc/atmel/atmel-pdmic.c738
-rw-r--r--sound/soc/atmel/atmel-pdmic.h80
-rw-r--r--sound/soc/atmel/atmel_wm8904.c1
-rw-r--r--sound/soc/codecs/Kconfig56
-rw-r--r--sound/soc/codecs/Makefile18
-rw-r--r--sound/soc/codecs/ak4613.c118
-rw-r--r--sound/soc/codecs/arizona.c143
-rw-r--r--sound/soc/codecs/arizona.h17
-rw-r--r--sound/soc/codecs/cs47l24.c1148
-rw-r--r--sound/soc/codecs/cs47l24.h23
-rw-r--r--sound/soc/codecs/da7218.c3314
-rw-r--r--sound/soc/codecs/da7218.h1414
-rw-r--r--sound/soc/codecs/da7219.c89
-rw-r--r--sound/soc/codecs/da7219.h9
-rw-r--r--sound/soc/codecs/hdac_hdmi.c659
-rw-r--r--sound/soc/codecs/inno_rk3036.c490
-rw-r--r--sound/soc/codecs/inno_rk3036.h123
-rw-r--r--sound/soc/codecs/max98357a.c10
-rw-r--r--sound/soc/codecs/pcm3168a-i2c.c66
-rw-r--r--sound/soc/codecs/pcm3168a-spi.c65
-rw-r--r--sound/soc/codecs/pcm3168a.c767
-rw-r--r--sound/soc/codecs/pcm3168a.h100
-rw-r--r--sound/soc/codecs/rt286.c6
-rw-r--r--sound/soc/codecs/rt298.c2
-rw-r--r--sound/soc/codecs/rt5616.c1381
-rw-r--r--sound/soc/codecs/rt5616.h1819
-rw-r--r--sound/soc/codecs/rt5645.c292
-rw-r--r--sound/soc/codecs/rt5659.c4223
-rw-r--r--sound/soc/codecs/rt5659.h1819
-rw-r--r--sound/soc/codecs/rt5677.c13
-rw-r--r--sound/soc/codecs/ssm2518.c2
-rw-r--r--sound/soc/codecs/wm5110.c206
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8962.c3
-rw-r--r--sound/soc/codecs/wm8974.c7
-rw-r--r--sound/soc/codecs/wm8998.c46
-rw-r--r--sound/soc/codecs/wm9713.c296
-rw-r--r--sound/soc/codecs/wm_adsp.c769
-rw-r--r--sound/soc/codecs/wm_adsp.h23
-rw-r--r--sound/soc/dwc/designware_i2s.c113
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c21
-rw-r--r--sound/soc/fsl/fsl_asrc.c55
-rw-r--r--sound/soc/fsl/fsl_asrc.h2
-rw-r--r--sound/soc/fsl/fsl_esai.c63
-rw-r--r--sound/soc/fsl/fsl_sai.c98
-rw-r--r--sound/soc/fsl/fsl_sai.h3
-rw-r--r--sound/soc/fsl/fsl_spdif.c35
-rw-r--r--sound/soc/fsl/fsl_ssi.c25
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c2
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c4
-rw-r--r--sound/soc/fsl/imx-wm8962.c10
-rw-r--r--sound/soc/generic/simple-card.c12
-rw-r--r--sound/soc/img/Kconfig52
-rw-r--r--sound/soc/img/Makefile7
-rw-r--r--sound/soc/img/img-i2s-in.c516
-rw-r--r--sound/soc/img/img-i2s-out.c565
-rw-r--r--sound/soc/img/img-parallel-out.c327
-rw-r--r--sound/soc/img/img-spdif-in.c806
-rw-r--r--sound/soc/img/img-spdif-out.c441
-rw-r--r--sound/soc/img/pistachio-internal-dac.c287
-rw-r--r--sound/soc/intel/Kconfig46
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c5
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h1
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c32
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c67
-rw-r--r--sound/soc/intel/atom/sst/sst_stream.c2
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c2
-rw-r--r--sound/soc/intel/boards/Makefile4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c241
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c19
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c19
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c19
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c485
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c536
-rw-r--r--sound/soc/intel/boards/skl_rt286.c128
-rw-r--r--sound/soc/intel/common/Makefile7
-rw-r--r--sound/soc/intel/common/sst-acpi.c41
-rw-r--r--sound/soc/intel/common/sst-acpi.h33
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h8
-rw-r--r--sound/soc/intel/common/sst-dsp.c2
-rw-r--r--sound/soc/intel/common/sst-dsp.h2
-rw-r--r--sound/soc/intel/common/sst-firmware.c20
-rw-r--r--sound/soc/intel/common/sst-match-acpi.c43
-rw-r--r--sound/soc/intel/haswell/sst-haswell-dsp.c2
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c31
-rw-r--r--sound/soc/intel/skylake/skl-messages.c280
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c19
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c256
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c97
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h21
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c108
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h9
-rw-r--r--sound/soc/intel/skylake/skl-sst.c217
-rw-r--r--sound/soc/intel/skylake/skl-topology.c658
-rw-r--r--sound/soc/intel/skylake/skl-topology.h63
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h105
-rw-r--r--sound/soc/intel/skylake/skl.c158
-rw-r--r--sound/soc/intel/skylake/skl.h6
-rw-r--r--sound/soc/mediatek/mtk-afe-common.h1
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c59
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c2
-rw-r--r--sound/soc/pxa/brownstone.c3
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c6
-rw-r--r--sound/soc/qcom/lpass-cpu.c1
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c130
-rw-r--r--sound/soc/rockchip/rockchip_max98090.c6
-rw-r--r--sound/soc/rockchip/rockchip_rt5645.c6
-rw-r--r--sound/soc/samsung/Kconfig2
-rw-r--r--sound/soc/samsung/ac97.c29
-rw-r--r--sound/soc/samsung/bells.c40
-rw-r--r--sound/soc/samsung/dma.h6
-rw-r--r--sound/soc/samsung/dmaengine.c20
-rw-r--r--sound/soc/samsung/i2s.c31
-rw-r--r--sound/soc/samsung/littlemill.c32
-rw-r--r--sound/soc/samsung/odroidx2_max98090.c9
-rw-r--r--sound/soc/samsung/pcm.c25
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c16
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c16
-rw-r--r--sound/soc/samsung/snow.c9
-rw-r--r--sound/soc/samsung/spdif.c17
-rw-r--r--sound/soc/samsung/speyside.c12
-rw-r--r--sound/soc/samsung/tobermory.c21
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/fsi.c11
-rw-r--r--sound/soc/sh/rcar/Makefile2
-rw-r--r--sound/soc/sh/rcar/adg.c118
-rw-r--r--sound/soc/sh/rcar/cmd.c171
-rw-r--r--sound/soc/sh/rcar/core.c586
-rw-r--r--sound/soc/sh/rcar/ctu.c99
-rw-r--r--sound/soc/sh/rcar/dma.c245
-rw-r--r--sound/soc/sh/rcar/dvc.c273
-rw-r--r--sound/soc/sh/rcar/gen.c133
-rw-r--r--sound/soc/sh/rcar/mix.c158
-rw-r--r--sound/soc/sh/rcar/rcar_snd.h117
-rw-r--r--sound/soc/sh/rcar/rsnd.h335
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c129
-rw-r--r--sound/soc/sh/rcar/src.c898
-rw-r--r--sound/soc/sh/rcar/ssi.c744
-rw-r--r--sound/soc/sh/rcar/ssiu.c225
-rw-r--r--sound/soc/soc-ac97.c125
-rw-r--r--sound/soc/soc-core.c602
-rw-r--r--sound/soc/soc-dapm.c14
-rw-r--r--sound/soc/soc-ops.c4
-rw-r--r--sound/soc/soc-pcm.c82
-rw-r--r--sound/soc/sti/uniperif_player.c3
-rw-r--r--sound/soc/sunxi/sun4i-codec.c279
-rw-r--r--sound/soc/tegra/tegra_alc5632.c12
-rw-r--r--sound/soc/tegra/tegra_wm8903.c3
196 files changed, 30487 insertions, 4162 deletions
diff --git a/Documentation/devicetree/bindings/sound/ak4613.txt b/Documentation/devicetree/bindings/sound/ak4613.txt
index 15a919522b42..1783f9ef0930 100644
--- a/Documentation/devicetree/bindings/sound/ak4613.txt
+++ b/Documentation/devicetree/bindings/sound/ak4613.txt
@@ -7,6 +7,16 @@ Required properties:
7- compatible : "asahi-kasei,ak4613" 7- compatible : "asahi-kasei,ak4613"
8- reg : The chip select number on the I2C bus 8- reg : The chip select number on the I2C bus
9 9
10Optional properties:
11- asahi-kasei,in1-single-end : Boolean. Indicate input / output pins are single-ended.
12- asahi-kasei,in2-single-end rather than differential.
13- asahi-kasei,out1-single-end
14- asahi-kasei,out2-single-end
15- asahi-kasei,out3-single-end
16- asahi-kasei,out4-single-end
17- asahi-kasei,out5-single-end
18- asahi-kasei,out6-single-end
19
10Example: 20Example:
11 21
12&i2c { 22&i2c {
diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt
index 0018451c4351..549e701cb7a1 100644
--- a/Documentation/devicetree/bindings/sound/atmel-classd.txt
+++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt
@@ -16,6 +16,10 @@ Required properties:
16 Required elements: "pclk", "gclk" and "aclk". 16 Required elements: "pclk", "gclk" and "aclk".
17- clocks 17- clocks
18 Please refer to clock-bindings.txt. 18 Please refer to clock-bindings.txt.
19- assigned-clocks
20 Should be <&classd_gclk>.
21- assigned-clock-parents
22 Should be <&audio_pll_pmc>.
19 23
20Optional properties: 24Optional properties:
21- pinctrl-names, pinctrl-0 25- pinctrl-names, pinctrl-0
@@ -43,6 +47,8 @@ classd: classd@fc048000 {
43 dma-names = "tx"; 47 dma-names = "tx";
44 clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; 48 clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>;
45 clock-names = "pclk", "gclk", "aclk"; 49 clock-names = "pclk", "gclk", "aclk";
50 assigned-clocks = <&classd_gclk>;
51 assigned-clock-parents = <&audio_pll_pmc>;
46 52
47 pinctrl-names = "default"; 53 pinctrl-names = "default";
48 pinctrl-0 = <&pinctrl_classd_default>; 54 pinctrl-0 = <&pinctrl_classd_default>;
diff --git a/Documentation/devicetree/bindings/sound/atmel-pdmic.txt b/Documentation/devicetree/bindings/sound/atmel-pdmic.txt
new file mode 100644
index 000000000000..e0875f17c229
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-pdmic.txt
@@ -0,0 +1,55 @@
1* Atmel PDMIC driver under ALSA SoC architecture
2
3Required properties:
4- compatible
5 Should be "atmel,sama5d2-pdmic".
6- reg
7 Should contain PDMIC registers location and length.
8- interrupts
9 Should contain the IRQ line for the PDMIC.
10- dmas
11 One DMA specifiers as described in atmel-dma.txt and dma.txt files.
12- dma-names
13 Must be "rx".
14- clock-names
15 Required elements:
16 - "pclk" peripheral clock
17 - "gclk" generated clock
18- clocks
19 Must contain an entry for each required entry in clock-names.
20 Please refer to clock-bindings.txt.
21- atmel,mic-min-freq
22 The minimal frequency that the micphone supports.
23- atmel,mic-max-freq
24 The maximal frequency that the micphone supports.
25
26Optional properties:
27- pinctrl-names, pinctrl-0
28 Please refer to pinctrl-bindings.txt.
29- atmel,model
30 The user-visible name of this sound card.
31 The default value is "PDMIC".
32- atmel,mic-offset
33 The offset that should be added.
34 The range is from -32768 to 32767.
35 The default value is 0.
36
37Example:
38 pdmic@f8018000 {
39 compatible = "atmel,sama5d2-pdmic";
40 reg = <0xf8018000 0x124>;
41 interrupts = <48 IRQ_TYPE_LEVEL_HIGH 7>;
42 dmas = <&dma0
43 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
44 | AT91_XDMAC_DT_PERID(50))>;
45 dma-names = "rx";
46 clocks = <&pdmic_clk>, <&pdmic_gclk>;
47 clock-names = "pclk", "gclk";
48
49 pinctrl-names = "default";
50 pinctrl-0 = <&pinctrl_pdmic_default>;
51 atmel,model = "PDMIC @ sama5d2_xplained";
52 atmel,mic-min-freq = <1000000>;
53 atmel,mic-max-freq = <3246000>;
54 atmel,mic-offset = <0x0>;
55 };
diff --git a/Documentation/devicetree/bindings/sound/da7218.txt b/Documentation/devicetree/bindings/sound/da7218.txt
new file mode 100644
index 000000000000..5ca5a709b6aa
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/da7218.txt
@@ -0,0 +1,104 @@
1Dialog Semiconductor DA7218 Audio Codec bindings
2
3DA7218 is an audio codec with HP detect feature.
4
5======
6
7Required properties:
8- compatible : Should be "dlg,da7217" or "dlg,da7218"
9- reg: Specifies the I2C slave address
10
11- VDD-supply: VDD power supply for the device
12- VDDMIC-supply: VDDMIC power supply for the device
13- VDDIO-supply: VDDIO power supply for the device
14 (See Documentation/devicetree/bindings/regulator/regulator.txt for further
15 information relating to regulators)
16
17Optional properties:
18- interrupt-parent: Specifies the phandle of the interrupt controller to which
19 the IRQs from DA7218 are delivered to.
20- interrupts: IRQ line info for DA7218 chip.
21 (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
22 further information relating to interrupt properties)
23- interrupt-names : Name associated with interrupt line. Should be "wakeup" if
24 interrupt is to be used to wake system, otherwise "irq" should be used.
25- wakeup-source: Flag to indicate this device can wake system (suspend/resume).
26
27- clocks : phandle and clock specifier for codec MCLK.
28- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
29
30- dlg,micbias1-lvl-millivolt : Voltage (mV) for Mic Bias 1
31 [<1200>, <1600>, <1800>, <2000>, <2200>, <2400>, <2600>, <2800>, <3000>]
32- dlg,micbias2-lvl-millivolt : Voltage (mV) for Mic Bias 2
33 [<1200>, <1600>, <1800>, <2000>, <2200>, <2400>, <2600>, <2800>, <3000>]
34- dlg,mic1-amp-in-sel : Mic1 input source type
35 ["diff", "se_p", "se_n"]
36- dlg,mic2-amp-in-sel : Mic2 input source type
37 ["diff", "se_p", "se_n"]
38- dlg,dmic1-data-sel : DMIC1 channel select based on clock edge.
39 ["lrise_rfall", "lfall_rrise"]
40- dlg,dmic1-samplephase : When to sample audio from DMIC1.
41 ["on_clkedge", "between_clkedge"]
42- dlg,dmic1-clkrate-hz : DMic1 clock frequency (Hz).
43 [<1500000>, <3000000>]
44- dlg,dmic2-data-sel : DMic2 channel select based on clock edge.
45 ["lrise_rfall", "lfall_rrise"]
46- dlg,dmic2-samplephase : When to sample audio from DMic2.
47 ["on_clkedge", "between_clkedge"]
48- dlg,dmic2-clkrate-hz : DMic2 clock frequency (Hz).
49 [<1500000>, <3000000>]
50- dlg,hp-diff-single-supply : Boolean flag, use single supply for HP
51 (DA7217 only)
52
53======
54
55Optional Child node - 'da7218_hpldet' (DA7218 only):
56
57Optional properties:
58- dlg,jack-rate-us : Time between jack detect measurements (us)
59 [<5>, <10>, <20>, <40>, <80>, <160>, <320>, <640>]
60- dlg,jack-debounce : Number of debounce measurements taken for jack detect
61 [<0>, <2>, <3>, <4>]
62- dlg,jack-threshold-pct : Threshold level for jack detection (% of VDD)
63 [<84>, <88>, <92>, <96>]
64- dlg,comp-inv : Boolean flag, invert comparator output
65- dlg,hyst : Boolean flag, enable hysteresis
66- dlg,discharge : Boolean flag, auto discharge of Mic Bias on jack removal
67
68======
69
70Example:
71
72 codec: da7218@1a {
73 compatible = "dlg,da7218";
74 reg = <0x1a>;
75 interrupt-parent = <&gpio6>;
76 interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
77 wakeup-source;
78
79 VDD-supply = <&reg_audio>;
80 VDDMIC-supply = <&reg_audio>;
81 VDDIO-supply = <&reg_audio>;
82
83 clocks = <&clks 201>;
84 clock-names = "mclk";
85
86 dlg,micbias1-lvl-millivolt = <2600>;
87 dlg,micbias2-lvl-millivolt = <2600>;
88 dlg,mic1-amp-in-sel = "diff";
89 dlg,mic2-amp-in-sel = "diff";
90
91 dlg,dmic1-data-sel = "lrise_rfall";
92 dlg,dmic1-samplephase = "on_clkedge";
93 dlg,dmic1-clkrate-hz = <3000000>;
94 dlg,dmic2-data-sel = "lrise_rfall";
95 dlg,dmic2-samplephase = "on_clkedge";
96 dlg,dmic2-clkrate-hz = <3000000>;
97
98 da7218_hpldet {
99 dlg,jack-rate-us = <40>;
100 dlg,jack-debounce = <2>;
101 dlg,jack-threshold-pct = <84>;
102 dlg,hyst;
103 };
104 };
diff --git a/Documentation/devicetree/bindings/sound/da7219.txt b/Documentation/devicetree/bindings/sound/da7219.txt
index 1b7030911a3b..cf61681826b6 100644
--- a/Documentation/devicetree/bindings/sound/da7219.txt
+++ b/Documentation/devicetree/bindings/sound/da7219.txt
@@ -28,13 +28,15 @@ Optional properties:
28- clocks : phandle and clock specifier for codec MCLK. 28- clocks : phandle and clock specifier for codec MCLK.
29- clock-names : Clock name string for 'clocks' attribute, should be "mclk". 29- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
30 30
31- dlg,ldo-lvl : Required internal LDO voltage (mV) level for digital engine
32 [<1050>, <1100>, <1200>, <1400>]
33- dlg,micbias-lvl : Voltage (mV) for Mic Bias 31- dlg,micbias-lvl : Voltage (mV) for Mic Bias
34 [<1800>, <2000>, <2200>, <2400>, <2600>] 32 [<1600>, <1800>, <2000>, <2200>, <2400>, <2600>]
35- dlg,mic-amp-in-sel : Mic input source type 33- dlg,mic-amp-in-sel : Mic input source type
36 ["diff", "se_p", "se_n"] 34 ["diff", "se_p", "se_n"]
37 35
36Deprecated properties:
37- dlg,ldo-lvl : Required internal LDO voltage (mV) level for digital engine
38 (LDO unavailable in production HW so property no longer required).
39
38====== 40======
39 41
40Child node - 'da7219_aad': 42Child node - 'da7219_aad':
diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index b93362a570be..3e26a9478e57 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -25,6 +25,11 @@ Required properties:
25 "mem" Peripheral access clock to access registers. 25 "mem" Peripheral access clock to access registers.
26 "ipg" Peripheral clock to driver module. 26 "ipg" Peripheral clock to driver module.
27 "asrck_<0-f>" Clock sources for input and output clock. 27 "asrck_<0-f>" Clock sources for input and output clock.
28 "spba" The spba clock is required when ASRC is placed as a
29 bus slave of the Shared Peripheral Bus and when two
30 or more bus masters (CPU, DMA or DSP) try to access
31 it. This property is optional depending on the SoC
32 design.
28 33
29 - big-endian : If this property is absent, the little endian mode 34 - big-endian : If this property is absent, the little endian mode
30 will be in use as default. Otherwise, the big endian 35 will be in use as default. Otherwise, the big endian
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index d3b6b5f48010..cd3ee5d84f03 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -27,6 +27,11 @@ Required properties:
27 derive HCK, SCK and FS. 27 derive HCK, SCK and FS.
28 "fsys" The system clock derived from ahb clock used to 28 "fsys" The system clock derived from ahb clock used to
29 derive HCK, SCK and FS. 29 derive HCK, SCK and FS.
30 "spba" The spba clock is required when ESAI is placed as a
31 bus slave of the Shared Peripheral Bus and when two
32 or more bus masters (CPU, DMA or DSP) try to access
33 it. This property is optional depending on the SoC
34 design.
30 35
31 - fsl,fifo-depth : The number of elements in the transmit and receive 36 - fsl,fifo-depth : The number of elements in the transmit and receive
32 FIFOs. This number is the maximum allowed value for 37 FIFOs. This number is the maximum allowed value for
diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index b5ee32ee3706..4ca39ddc0417 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -27,6 +27,11 @@ Required properties:
27 Transceiver Clock Diagram" of SoC reference manual. 27 Transceiver Clock Diagram" of SoC reference manual.
28 It can also be referred to TxClk_Source bit of 28 It can also be referred to TxClk_Source bit of
29 register SPDIF_STC. 29 register SPDIF_STC.
30 "spba" The spba clock is required when SPDIF is placed as a
31 bus slave of the Shared Peripheral Bus and when two
32 or more bus masters (CPU, DMA or DSP) try to access
33 it. This property is optional depending on the SoC
34 design.
30 35
31 - big-endian : If this property is absent, the native endian mode 36 - big-endian : If this property is absent, the native endian mode
32 will be in use as default, or the big endian mode 37 will be in use as default, or the big endian mode
diff --git a/Documentation/devicetree/bindings/sound/img,i2s-in.txt b/Documentation/devicetree/bindings/sound/img,i2s-in.txt
new file mode 100644
index 000000000000..423265cfc3d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,i2s-in.txt
@@ -0,0 +1,47 @@
1Imagination Technologies I2S Input Controller
2
3Required Properties:
4
5 - compatible : Compatible list, must contain "img,i2s-in"
6
7 - #sound-dai-cells : Must be equal to 0
8
9 - reg : Offset and length of the register set for the device
10
11 - clocks : Contains an entry for each entry in clock-names
12
13 - clock-names : Must include the following entry:
14 "sys" The system clock
15
16 - dmas: Contains an entry for each entry in dma-names.
17
18 - dma-names: Must include the following entry:
19 "rx" Single DMA channel used by all active I2S channels
20
21 - img,i2s-channels : Number of I2S channels instantiated in the I2S in block
22
23Optional Properties:
24
25 - interrupts : Contains the I2S in interrupts. Depending on
26 the configuration, there may be no interrupts, one interrupt,
27 or an interrupt per I2S channel. For the case where there is
28 one interrupt per channel, the interrupts should be listed
29 in ascending channel order
30
31 - resets: Contains a phandle to the I2S in reset signal
32
33 - reset-names: Contains the reset signal name "rst"
34
35Example:
36
37i2s_in: i2s-in@18100800 {
38 compatible = "img,i2s-in";
39 reg = <0x18100800 0x200>;
40 interrupts = <GIC_SHARED 7 IRQ_TYPE_LEVEL_HIGH>;
41 dmas = <&mdc 30 0xffffffff 0>;
42 dma-names = "rx";
43 clocks = <&cr_periph SYS_CLK_I2S_IN>;
44 clock-names = "sys";
45 img,i2s-channels = <6>;
46 #sound-dai-cells = <0>;
47};
diff --git a/Documentation/devicetree/bindings/sound/img,i2s-out.txt b/Documentation/devicetree/bindings/sound/img,i2s-out.txt
new file mode 100644
index 000000000000..0159415b3338
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,i2s-out.txt
@@ -0,0 +1,51 @@
1Imagination Technologies I2S Output Controller
2
3Required Properties:
4
5 - compatible : Compatible list, must contain "img,i2s-out"
6
7 - #sound-dai-cells : Must be equal to 0
8
9 - reg : Offset and length of the register set for the device
10
11 - clocks : Contains an entry for each entry in clock-names
12
13 - clock-names : Must include the following entries:
14 "sys" The system clock
15 "ref" The reference clock
16
17 - dmas: Contains an entry for each entry in dma-names.
18
19 - dma-names: Must include the following entry:
20 "tx" Single DMA channel used by all active I2S channels
21
22 - img,i2s-channels : Number of I2S channels instantiated in the I2S out block
23
24 - resets: Contains a phandle to the I2S out reset signal
25
26 - reset-names: Contains the reset signal name "rst"
27
28Optional Properties:
29
30 - interrupts : Contains the I2S out interrupts. Depending on
31 the configuration, there may be no interrupts, one interrupt,
32 or an interrupt per I2S channel. For the case where there is
33 one interrupt per channel, the interrupts should be listed
34 in ascending channel order
35
36Example:
37
38i2s_out: i2s-out@18100A00 {
39 compatible = "img,i2s-out";
40 reg = <0x18100A00 0x200>;
41 interrupts = <GIC_SHARED 13 IRQ_TYPE_LEVEL_HIGH>;
42 dmas = <&mdc 23 0xffffffff 0>;
43 dma-names = "tx";
44 clocks = <&cr_periph SYS_CLK_I2S_OUT>,
45 <&clk_core CLK_I2S>;
46 clock-names = "sys", "ref";
47 img,i2s-channels = <6>;
48 resets = <&pistachio_reset PISTACHIO_RESET_I2S_OUT>;
49 reset-names = "rst";
50 #sound-dai-cells = <0>;
51};
diff --git a/Documentation/devicetree/bindings/sound/img,parallel-out.txt b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
new file mode 100644
index 000000000000..a3015d2a06e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
@@ -0,0 +1,44 @@
1Imagination Technologies Parallel Output Controller
2
3Required Properties:
4
5 - compatible : Compatible list, must contain "img,parallel-out".
6
7 - #sound-dai-cells : Must be equal to 0
8
9 - reg : Offset and length of the register set for the device.
10
11 - dmas: Contains an entry for each entry in dma-names.
12
13 - dma-names: Must include the following entry:
14 "tx"
15
16 - clocks : Contains an entry for each entry in clock-names.
17
18 - clock-names : Includes the following entries:
19 "sys" The system clock
20 "ref" The reference clock
21
22 - resets: Contains a phandle to the parallel out reset signal
23
24 - reset-names: Contains the reset signal name "rst"
25
26Optional Properties:
27
28 - interrupts : Contains the parallel out interrupt, if present
29
30Example:
31
32parallel_out: parallel-out@18100C00 {
33 compatible = "img,parallel-out";
34 reg = <0x18100C00 0x100>;
35 interrupts = <GIC_SHARED 19 IRQ_TYPE_LEVEL_HIGH>;
36 dmas = <&mdc 16 0xffffffff 0>;
37 dma-names = "tx";
38 clocks = <&cr_periph SYS_CLK_PAUD_OUT>,
39 <&clk_core CLK_AUDIO_DAC>;
40 clock-names = "sys", "ref";
41 resets = <&pistachio_reset PISTACHIO_RESET_PRL_OUT>;
42 reset-names = "rst";
43 #sound-dai-cells = <0>;
44};
diff --git a/Documentation/devicetree/bindings/sound/img,pistachio-internal-dac.txt b/Documentation/devicetree/bindings/sound/img,pistachio-internal-dac.txt
new file mode 100644
index 000000000000..4cc18fc0477e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,pistachio-internal-dac.txt
@@ -0,0 +1,18 @@
1Pistachio internal DAC DT bindings
2
3Required properties:
4
5 - compatible: "img,pistachio-internal-dac"
6
7 - img,cr-top : Must contain a phandle to the top level control syscon
8 node which contains the internal dac control registers
9
10 - VDD-supply : Digital power supply regulator (+1.8V or +3.3V)
11
12Examples:
13
14internal_dac: internal-dac {
15 compatible = "img,pistachio-internal-dac";
16 img,cr-top = <&cr_top>;
17 VDD-supply = <&supply3v3>;
18};
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-in.txt b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
new file mode 100644
index 000000000000..aab9a81f7e13
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
@@ -0,0 +1,41 @@
1Imagination Technologies SPDIF Input Controller
2
3Required Properties:
4
5 - compatible : Compatible list, must contain "img,spdif-in"
6
7 - #sound-dai-cells : Must be equal to 0
8
9 - reg : Offset and length of the register set for the device
10
11 - dmas: Contains an entry for each entry in dma-names.
12
13 - dma-names: Must include the following entry:
14 "rx"
15
16 - clocks : Contains an entry for each entry in clock-names
17
18 - clock-names : Includes the following entries:
19 "sys" The system clock
20
21Optional Properties:
22
23 - resets: Should contain a phandle to the spdif in reset signal, if any
24
25 - reset-names: Should contain the reset signal name "rst", if a
26 reset phandle is given
27
28 - interrupts : Contains the spdif in interrupt, if present
29
30Example:
31
32spdif_in: spdif-in@18100E00 {
33 compatible = "img,spdif-in";
34 reg = <0x18100E00 0x100>;
35 interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
36 dmas = <&mdc 15 0xffffffff 0>;
37 dma-names = "rx";
38 clocks = <&cr_periph SYS_CLK_SPDIF_IN>;
39 clock-names = "sys";
40 #sound-dai-cells = <0>;
41};
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-out.txt b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
new file mode 100644
index 000000000000..470a5191e101
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
@@ -0,0 +1,44 @@
1Imagination Technologies SPDIF Output Controller
2
3Required Properties:
4
5 - compatible : Compatible list, must contain "img,spdif-out"
6
7 - #sound-dai-cells : Must be equal to 0
8
9 - reg : Offset and length of the register set for the device
10
11 - dmas: Contains an entry for each entry in dma-names.
12
13 - dma-names: Must include the following entry:
14 "tx"
15
16 - clocks : Contains an entry for each entry in clock-names.
17
18 - clock-names : Includes the following entries:
19 "sys" The system clock
20 "ref" The reference clock
21
22 - resets: Contains a phandle to the spdif out reset signal
23
24 - reset-names: Contains the reset signal name "rst"
25
26Optional Properties:
27
28 - interrupts : Contains the parallel out interrupt, if present
29
30Example:
31
32spdif_out: spdif-out@18100D00 {
33 compatible = "img,spdif-out";
34 reg = <0x18100D00 0x100>;
35 interrupts = <GIC_SHARED 21 IRQ_TYPE_LEVEL_HIGH>;
36 dmas = <&mdc 14 0xffffffff 0>;
37 dma-names = "tx";
38 clocks = <&cr_periph SYS_CLK_SPDIF_OUT>,
39 <&clk_core CLK_SPDIF>;
40 clock-names = "sys", "ref";
41 resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>;
42 reset-names = "rst";
43 #sound-dai-cells = <0>;
44};
diff --git a/Documentation/devicetree/bindings/sound/inno-rk3036.txt b/Documentation/devicetree/bindings/sound/inno-rk3036.txt
new file mode 100644
index 000000000000..758de8e27561
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/inno-rk3036.txt
@@ -0,0 +1,20 @@
1Inno audio codec for RK3036
2
3Inno audio codec is integrated inside RK3036 SoC.
4
5Required properties:
6- compatible : Should be "rockchip,rk3036-codec".
7- reg : The registers of codec.
8- clock-names : Should be "acodec_pclk".
9- clocks : The clock of codec.
10- rockchip,grf : The phandle of grf device node.
11
12Example:
13
14 acodec: acodec-ana@20030000 {
15 compatible = "rk3036-codec";
16 reg = <0x20030000 0x4000>;
17 rockchip,grf = <&grf>;
18 clock-names = "acodec_pclk";
19 clocks = <&cru ACLK_VCODEC>;
20 };
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
index c57cbd65736c..8ee0fa91e4a0 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
@@ -7,8 +7,11 @@ Required properties:
7 "renesas,rcar_sound-gen3" if generation3 7 "renesas,rcar_sound-gen3" if generation3
8 Examples with soctypes are: 8 Examples with soctypes are:
9 - "renesas,rcar_sound-r8a7778" (R-Car M1A) 9 - "renesas,rcar_sound-r8a7778" (R-Car M1A)
10 - "renesas,rcar_sound-r8a7779" (R-Car H1)
10 - "renesas,rcar_sound-r8a7790" (R-Car H2) 11 - "renesas,rcar_sound-r8a7790" (R-Car H2)
11 - "renesas,rcar_sound-r8a7791" (R-Car M2-W) 12 - "renesas,rcar_sound-r8a7791" (R-Car M2-W)
13 - "renesas,rcar_sound-r8a7793" (R-Car M2-N)
14 - "renesas,rcar_sound-r8a7794" (R-Car E2)
12 - "renesas,rcar_sound-r8a7795" (R-Car H3) 15 - "renesas,rcar_sound-r8a7795" (R-Car H3)
13- reg : Should contain the register physical address. 16- reg : Should contain the register physical address.
14 required register is 17 required register is
@@ -34,6 +37,8 @@ Required properties:
34 see below for detail. 37 see below for detail.
35- #sound-dai-cells : it must be 0 if your system is using single DAI 38- #sound-dai-cells : it must be 0 if your system is using single DAI
36 it must be 1 if your system is using multi DAI 39 it must be 1 if your system is using multi DAI
40
41Optional properties:
37- #clock-cells : it must be 0 if your system has audio_clkout 42- #clock-cells : it must be 0 if your system has audio_clkout
38 it must be 1 if your system has audio_clkout0/1/2/3 43 it must be 1 if your system has audio_clkout0/1/2/3
39- clock-frequency : for all audio_clkout0/1/2/3 44- clock-frequency : for all audio_clkout0/1/2/3
@@ -244,3 +249,80 @@ rcar_sound: sound@ec500000 {
244 }; 249 };
245 }; 250 };
246}; 251};
252
253Example: simple sound card
254
255 rsnd_ak4643: sound {
256 compatible = "simple-audio-card";
257
258 simple-audio-card,format = "left_j";
259 simple-audio-card,bitclock-master = <&sndcodec>;
260 simple-audio-card,frame-master = <&sndcodec>;
261
262 sndcpu: simple-audio-card,cpu {
263 sound-dai = <&rcar_sound>;
264 };
265
266 sndcodec: simple-audio-card,codec {
267 sound-dai = <&ak4643>;
268 clocks = <&audio_clock>;
269 };
270 };
271
272&rcar_sound {
273 pinctrl-0 = <&sound_pins &sound_clk_pins>;
274 pinctrl-names = "default";
275
276 /* Single DAI */
277 #sound-dai-cells = <0>;
278
279 status = "okay";
280
281 rcar_sound,dai {
282 dai0 {
283 playback = <&ssi0 &src2 &dvc0>;
284 capture = <&ssi1 &src3 &dvc1>;
285 };
286 };
287};
288
289&ssi1 {
290 shared-pin;
291};
292
293Example: simple sound card for TDM
294
295 rsnd_tdm: sound {
296 compatible = "simple-audio-card";
297
298 simple-audio-card,format = "left_j";
299 simple-audio-card,bitclock-master = <&sndcodec>;
300 simple-audio-card,frame-master = <&sndcodec>;
301
302 sndcpu: simple-audio-card,cpu {
303 sound-dai = <&rcar_sound>;
304 dai-tdm-slot-num = <6>;
305 };
306
307 sndcodec: simple-audio-card,codec {
308 sound-dai = <&xxx>;
309 };
310 };
311
312Example: simple sound card for Multi channel
313
314&rcar_sound {
315 pinctrl-0 = <&sound_pins &sound_clk_pins>;
316 pinctrl-names = "default";
317
318 /* Single DAI */
319 #sound-dai-cells = <0>;
320
321 status = "okay";
322
323 rcar_sound,dai {
324 dai0 {
325 playback = <&ssi0 &ssi1 &ssi2 &src0 &dvc0>;
326 };
327 };
328};
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
index 962748a8d919..2b2caa281ce3 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
@@ -4,8 +4,8 @@ Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC
4 4
5Required properties: 5Required properties:
6 6
7- compatible : "renesas,rsrc-card,<board>" 7- compatible : "renesas,rsrc-card{,<board>}"
8 Examples with soctypes are: 8 Examples with boards are:
9 - "renesas,rsrc-card" 9 - "renesas,rsrc-card"
10 - "renesas,rsrc-card,lager" 10 - "renesas,rsrc-card,lager"
11 - "renesas,rsrc-card,koelsch" 11 - "renesas,rsrc-card,koelsch"
diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
index 2267d249ca0e..b7f3a9325ebd 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt
@@ -19,6 +19,7 @@ Required properties:
19- clock-names: should contain followings: 19- clock-names: should contain followings:
20 - "i2s_hclk": clock for I2S BUS 20 - "i2s_hclk": clock for I2S BUS
21 - "i2s_clk" : clock for I2S controller 21 - "i2s_clk" : clock for I2S controller
22- rockchip,playback-channels: max playback channels, if not set, 8 channels default.
22- rockchip,capture-channels: max capture channels, if not set, 2 channels default. 23- rockchip,capture-channels: max capture channels, if not set, 2 channels default.
23 24
24Example for rk3288 I2S controller: 25Example for rk3288 I2S controller:
@@ -31,5 +32,6 @@ i2s@ff890000 {
31 dma-names = "tx", "rx"; 32 dma-names = "tx", "rx";
32 clock-names = "i2s_hclk", "i2s_clk"; 33 clock-names = "i2s_hclk", "i2s_clk";
33 clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; 34 clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
35 rockchip,playback-channels = <8>;
34 rockchip,capture-channels = <2>; 36 rockchip,capture-channels = <2>;
35}; 37};
diff --git a/Documentation/devicetree/bindings/sound/rt5616.txt b/Documentation/devicetree/bindings/sound/rt5616.txt
new file mode 100644
index 000000000000..efc48c65198d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5616.txt
@@ -0,0 +1,26 @@
1RT5616 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5616".
8
9- reg : The I2C address of the device.
10
11Pins on the device (for linking into audio routes) for RT5616:
12
13 * IN1P
14 * IN2P
15 * IN2N
16 * LOUTL
17 * LOUTR
18 * HPOL
19 * HPOR
20
21Example:
22
23codec: rt5616@1b {
24 compatible = "realtek,rt5616";
25 reg = <0x1b>;
26};
diff --git a/Documentation/devicetree/bindings/sound/rt5659.txt b/Documentation/devicetree/bindings/sound/rt5659.txt
new file mode 100644
index 000000000000..5f79e7fde032
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rt5659.txt
@@ -0,0 +1,75 @@
1RT5659/RT5658 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : One of "realtek,rt5659" or "realtek,rt5658".
8
9- reg : The I2C address of the device.
10
11- interrupts : The CODEC's interrupt output.
12
13Optional properties:
14
15- realtek,in1-differential
16- realtek,in3-differential
17- realtek,in4-differential
18 Boolean. Indicate MIC1/3/4 input are differential, rather than single-ended.
19
20- realtek,dmic1-data-pin
21 0: dmic1 is not used
22 1: using IN2N pin as dmic1 data pin
23 2: using GPIO5 pin as dmic1 data pin
24 3: using GPIO9 pin as dmic1 data pin
25 4: using GPIO11 pin as dmic1 data pin
26
27- realtek,dmic2-data-pin
28 0: dmic2 is not used
29 1: using IN2P pin as dmic2 data pin
30 2: using GPIO6 pin as dmic2 data pin
31 3: using GPIO10 pin as dmic2 data pin
32 4: using GPIO12 pin as dmic2 data pin
33
34- realtek,jd-src
35 0: No JD is used
36 1: using JD3 as JD source
37
38- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
39- realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin.
40
41Pins on the device (for linking into audio routes) for RT5659/RT5658:
42
43 * DMIC L1
44 * DMIC R1
45 * DMIC L2
46 * DMIC R2
47 * IN1P
48 * IN1N
49 * IN2P
50 * IN2N
51 * IN3P
52 * IN3N
53 * IN4P
54 * IN4N
55 * HPOL
56 * HPOR
57 * SPOL
58 * SPOR
59 * LOUTL
60 * LOUTR
61 * MONOOUT
62 * PDML
63 * PDMR
64 * SPDIF
65
66Example:
67
68rt5659 {
69 compatible = "realtek,rt5659";
70 reg = <0x1b>;
71 interrupt-parent = <&gpio>;
72 interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
73 realtek,ldo1-en-gpios =
74 <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
75};
diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt b/Documentation/devicetree/bindings/sound/rt5677.txt
index f07078997f87..1b3c13d206ff 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -18,7 +18,7 @@ Required properties:
18Optional properties: 18Optional properties:
19 19
20- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. 20- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
21- realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin. 21- realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin. Active low.
22 22
23- realtek,in1-differential 23- realtek,in1-differential
24- realtek,in2-differential 24- realtek,in2-differential
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
index c92966bd5488..0dce690f78f5 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
@@ -14,6 +14,9 @@ Required properties:
14 - "apb": the parent APB clock for this controller 14 - "apb": the parent APB clock for this controller
15 - "codec": the parent module clock 15 - "codec": the parent module clock
16 16
17Optional properties:
18- allwinner,pa-gpios: gpio to enable external amplifier
19
17Example: 20Example:
18codec: codec@01c22c00 { 21codec: codec@01c22c00 {
19 #sound-dai-cells = <0>; 22 #sound-dai-cells = <0>;
diff --git a/Documentation/devicetree/bindings/sound/ti,pcm3168a.txt b/Documentation/devicetree/bindings/sound/ti,pcm3168a.txt
new file mode 100644
index 000000000000..5d9cb84c661d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,pcm3168a.txt
@@ -0,0 +1,48 @@
1Texas Instruments pcm3168a DT bindings
2
3This driver supports both SPI and I2C bus access for this codec
4
5Required properties:
6
7 - compatible: "ti,pcm3168a"
8
9 - clocks : Contains an entry for each entry in clock-names
10
11 - clock-names : Includes the following entries:
12 "scki" The system clock
13
14 - VDD1-supply : Digital power supply regulator 1 (+3.3V)
15
16 - VDD2-supply : Digital power supply regulator 2 (+3.3V)
17
18 - VCCAD1-supply : ADC power supply regulator 1 (+5V)
19
20 - VCCAD2-supply : ADC power supply regulator 2 (+5V)
21
22 - VCCDA1-supply : DAC power supply regulator 1 (+5V)
23
24 - VCCDA2-supply : DAC power supply regulator 2 (+5V)
25
26For required properties on SPI/I2C, consult SPI/I2C device tree documentation
27
28Examples:
29
30i2c0: i2c0@0 {
31
32 ...
33
34 pcm3168a: audio-codec@44 {
35 compatible = "ti,pcm3168a";
36 reg = <0x44>;
37 clocks = <&clk_core CLK_AUDIO>;
38 clock-names = "scki";
39 VDD1-supply = <&supply3v3>;
40 VDD2-supply = <&supply3v3>;
41 VCCAD1-supply = <&supply5v0>;
42 VCCAD2-supply = <&supply5v0>;
43 VCCDA1-supply = <&supply5v0>;
44 VCCDA2-supply = <&supply5v0>;
45 pinctrl-names = "default";
46 pinctrl-0 = <&dac_clk_pin>;
47 };
48};
diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8974.txt b/Documentation/devicetree/bindings/sound/wlf,wm8974.txt
new file mode 100644
index 000000000000..01d3a7c83419
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wlf,wm8974.txt
@@ -0,0 +1,15 @@
1WM8974 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required properties:
7 - compatible: "wlf,wm8974"
8 - reg: the I2C address or SPI chip select number of the device
9
10Examples:
11
12codec: wm8974@1a {
13 compatible = "wlf,wm8974";
14 reg = <0x1a>;
15};
diff --git a/Documentation/sound/alsa/img,spdif-in.txt b/Documentation/sound/alsa/img,spdif-in.txt
new file mode 100644
index 000000000000..8b7505785fa6
--- /dev/null
+++ b/Documentation/sound/alsa/img,spdif-in.txt
@@ -0,0 +1,49 @@
1The Imagination Technologies SPDIF Input controller contains the following
2controls:
3
4name='IEC958 Capture Mask',index=0
5
6This control returns a mask that shows which of the IEC958 status bits
7can be read using the 'IEC958 Capture Default' control.
8
9name='IEC958 Capture Default',index=0
10
11This control returns the status bits contained within the SPDIF stream that
12is being received. The 'IEC958 Capture Mask' shows which bits can be read
13from this control.
14
15name='SPDIF In Multi Frequency Acquire',index=0
16name='SPDIF In Multi Frequency Acquire',index=1
17name='SPDIF In Multi Frequency Acquire',index=2
18name='SPDIF In Multi Frequency Acquire',index=3
19
20This control is used to attempt acquisition of up to four different sample
21rates. The active rate can be obtained by reading the 'SPDIF In Lock Frequency'
22control.
23
24When the value of this control is set to {0,0,0,0}, the rate given to hw_params
25will determine the single rate the block will capture. Else, the rate given to
26hw_params will be ignored, and the block will attempt capture for each of the
27four sample rates set here.
28
29If less than four rates are required, the same rate can be specified more than
30once
31
32name='SPDIF In Lock Frequency',index=0
33
34This control returns the active capture rate, or 0 if a lock has not been
35acquired
36
37name='SPDIF In Lock TRK',index=0
38
39This control is used to modify the locking/jitter rejection characteristics
40of the block. Larger values increase the locking range, but reduce jitter
41rejection.
42
43name='SPDIF In Lock Acquire Threshold',index=0
44
45This control is used to change the threshold at which a lock is acquired.
46
47name='SPDIF In Lock Release Threshold',index=0
48
49This control is used to change the threshold at which a lock is released.
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index ff780a8d8366..b57783371d52 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -54,12 +54,13 @@ static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
54 54
55static struct resource s3c64xx_iis0_resource[] = { 55static struct resource s3c64xx_iis0_resource[] = {
56 [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256), 56 [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
57 [1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
58 [2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
59}; 57};
60 58
61static struct s3c_audio_pdata i2sv3_pdata = { 59static struct s3c_audio_pdata i2s0_pdata = {
62 .cfg_gpio = s3c64xx_i2s_cfg_gpio, 60 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
61 .dma_filter = pl08x_filter_id,
62 .dma_playback = DMACH_I2S0_OUT,
63 .dma_capture = DMACH_I2S0_IN,
63}; 64};
64 65
65struct platform_device s3c64xx_device_iis0 = { 66struct platform_device s3c64xx_device_iis0 = {
@@ -68,15 +69,20 @@ struct platform_device s3c64xx_device_iis0 = {
68 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), 69 .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
69 .resource = s3c64xx_iis0_resource, 70 .resource = s3c64xx_iis0_resource,
70 .dev = { 71 .dev = {
71 .platform_data = &i2sv3_pdata, 72 .platform_data = &i2s0_pdata,
72 }, 73 },
73}; 74};
74EXPORT_SYMBOL(s3c64xx_device_iis0); 75EXPORT_SYMBOL(s3c64xx_device_iis0);
75 76
76static struct resource s3c64xx_iis1_resource[] = { 77static struct resource s3c64xx_iis1_resource[] = {
77 [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256), 78 [0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
78 [1] = DEFINE_RES_DMA(DMACH_I2S1_OUT), 79};
79 [2] = DEFINE_RES_DMA(DMACH_I2S1_IN), 80
81static struct s3c_audio_pdata i2s1_pdata = {
82 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
83 .dma_filter = pl08x_filter_id,
84 .dma_playback = DMACH_I2S1_OUT,
85 .dma_capture = DMACH_I2S1_IN,
80}; 86};
81 87
82struct platform_device s3c64xx_device_iis1 = { 88struct platform_device s3c64xx_device_iis1 = {
@@ -85,19 +91,20 @@ struct platform_device s3c64xx_device_iis1 = {
85 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), 91 .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
86 .resource = s3c64xx_iis1_resource, 92 .resource = s3c64xx_iis1_resource,
87 .dev = { 93 .dev = {
88 .platform_data = &i2sv3_pdata, 94 .platform_data = &i2s1_pdata,
89 }, 95 },
90}; 96};
91EXPORT_SYMBOL(s3c64xx_device_iis1); 97EXPORT_SYMBOL(s3c64xx_device_iis1);
92 98
93static struct resource s3c64xx_iisv4_resource[] = { 99static struct resource s3c64xx_iisv4_resource[] = {
94 [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256), 100 [0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
95 [1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
96 [2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
97}; 101};
98 102
99static struct s3c_audio_pdata i2sv4_pdata = { 103static struct s3c_audio_pdata i2sv4_pdata = {
100 .cfg_gpio = s3c64xx_i2s_cfg_gpio, 104 .cfg_gpio = s3c64xx_i2s_cfg_gpio,
105 .dma_filter = pl08x_filter_id,
106 .dma_playback = DMACH_HSI_I2SV40_TX,
107 .dma_capture = DMACH_HSI_I2SV40_RX,
101 .type = { 108 .type = {
102 .i2s = { 109 .i2s = {
103 .quirks = QUIRK_PRI_6CHAN, 110 .quirks = QUIRK_PRI_6CHAN,
@@ -142,12 +149,13 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
142 149
143static struct resource s3c64xx_pcm0_resource[] = { 150static struct resource s3c64xx_pcm0_resource[] = {
144 [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256), 151 [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
145 [1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
146 [2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
147}; 152};
148 153
149static struct s3c_audio_pdata s3c_pcm0_pdata = { 154static struct s3c_audio_pdata s3c_pcm0_pdata = {
150 .cfg_gpio = s3c64xx_pcm_cfg_gpio, 155 .cfg_gpio = s3c64xx_pcm_cfg_gpio,
156 .dma_filter = pl08x_filter_id,
157 .dma_capture = DMACH_PCM0_RX,
158 .dma_playback = DMACH_PCM0_TX,
151}; 159};
152 160
153struct platform_device s3c64xx_device_pcm0 = { 161struct platform_device s3c64xx_device_pcm0 = {
@@ -163,12 +171,13 @@ EXPORT_SYMBOL(s3c64xx_device_pcm0);
163 171
164static struct resource s3c64xx_pcm1_resource[] = { 172static struct resource s3c64xx_pcm1_resource[] = {
165 [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256), 173 [0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
166 [1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
167 [2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
168}; 174};
169 175
170static struct s3c_audio_pdata s3c_pcm1_pdata = { 176static struct s3c_audio_pdata s3c_pcm1_pdata = {
171 .cfg_gpio = s3c64xx_pcm_cfg_gpio, 177 .cfg_gpio = s3c64xx_pcm_cfg_gpio,
178 .dma_filter = pl08x_filter_id,
179 .dma_playback = DMACH_PCM1_TX,
180 .dma_capture = DMACH_PCM1_RX,
172}; 181};
173 182
174struct platform_device s3c64xx_device_pcm1 = { 183struct platform_device s3c64xx_device_pcm1 = {
@@ -196,13 +205,15 @@ static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
196 205
197static struct resource s3c64xx_ac97_resource[] = { 206static struct resource s3c64xx_ac97_resource[] = {
198 [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256), 207 [0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
199 [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT), 208 [1] = DEFINE_RES_IRQ(IRQ_AC97),
200 [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
201 [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
202 [4] = DEFINE_RES_IRQ(IRQ_AC97),
203}; 209};
204 210
205static struct s3c_audio_pdata s3c_ac97_pdata; 211static struct s3c_audio_pdata s3c_ac97_pdata = {
212 .dma_playback = DMACH_AC97_PCMOUT,
213 .dma_filter = pl08x_filter_id,
214 .dma_capture = DMACH_AC97_PCMIN,
215 .dma_capture_mic = DMACH_AC97_MICIN,
216};
206 217
207static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32); 218static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
208 219
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 096e14073bd9..9c739eafe95c 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -14,38 +14,38 @@
14#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name)) 14#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
15 15
16/* DMA0/SDMA0 */ 16/* DMA0/SDMA0 */
17#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx") 17#define DMACH_UART0 "uart0_tx"
18#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx") 18#define DMACH_UART0_SRC2 "uart0_rx"
19#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx") 19#define DMACH_UART1 "uart1_tx"
20#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx") 20#define DMACH_UART1_SRC2 "uart1_rx"
21#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx") 21#define DMACH_UART2 "uart2_tx"
22#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx") 22#define DMACH_UART2_SRC2 "uart2_rx"
23#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx") 23#define DMACH_UART3 "uart3_tx"
24#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx") 24#define DMACH_UART3_SRC2 "uart3_rx"
25#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx") 25#define DMACH_PCM0_TX "pcm0_tx"
26#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx") 26#define DMACH_PCM0_RX "pcm0_rx"
27#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx") 27#define DMACH_I2S0_OUT "i2s0_tx"
28#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx") 28#define DMACH_I2S0_IN "i2s0_rx"
29#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx") 29#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
30#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx") 30#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
31#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx") 31#define DMACH_HSI_I2SV40_TX "i2s2_tx"
32#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx") 32#define DMACH_HSI_I2SV40_RX "i2s2_rx"
33 33
34/* DMA1/SDMA1 */ 34/* DMA1/SDMA1 */
35#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx") 35#define DMACH_PCM1_TX "pcm1_tx"
36#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx") 36#define DMACH_PCM1_RX "pcm1_rx"
37#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx") 37#define DMACH_I2S1_OUT "i2s1_tx"
38#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx") 38#define DMACH_I2S1_IN "i2s1_rx"
39#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx") 39#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
40#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx") 40#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
41#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out") 41#define DMACH_AC97_PCMOUT "ac97_out"
42#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in") 42#define DMACH_AC97_PCMIN "ac97_in"
43#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic") 43#define DMACH_AC97_MICIN "ac97_mic"
44#define DMACH_PWM S3C64XX_DMA_CHAN("pwm") 44#define DMACH_PWM "pwm"
45#define DMACH_IRDA S3C64XX_DMA_CHAN("irda") 45#define DMACH_IRDA "irda"
46#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external") 46#define DMACH_EXTERNAL "external"
47#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx") 47#define DMACH_SECURITY_RX "sec_rx"
48#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx") 48#define DMACH_SECURITY_TX "sec_tx"
49 49
50enum dma_ch { 50enum dma_ch {
51 DMACH_MAX = 32 51 DMACH_MAX = 32
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 82074625de5c..7263e95a6f35 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -65,6 +65,7 @@
65#include <linux/platform_data/usb-ohci-s3c2410.h> 65#include <linux/platform_data/usb-ohci-s3c2410.h>
66#include <plat/usb-phy.h> 66#include <plat/usb-phy.h>
67#include <plat/regs-spi.h> 67#include <plat/regs-spi.h>
68#include <linux/platform_data/asoc-s3c.h>
68#include <linux/platform_data/spi-s3c64xx.h> 69#include <linux/platform_data/spi-s3c64xx.h>
69 70
70static u64 samsung_device_dma_mask = DMA_BIT_MASK(32); 71static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
@@ -74,9 +75,15 @@ static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
74static struct resource s3c_ac97_resource[] = { 75static struct resource s3c_ac97_resource[] = {
75 [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97), 76 [0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
76 [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97), 77 [1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
77 [2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"), 78};
78 [3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"), 79
79 [4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"), 80static struct s3c_audio_pdata s3c_ac97_pdata = {
81#ifdef CONFIG_S3C24XX_DMAC
82 .dma_filter = s3c24xx_dma_filter,
83#endif
84 .dma_playback = (void *)DMACH_PCM_OUT,
85 .dma_capture = (void *)DMACH_PCM_IN,
86 .dma_capture_mic = (void *)DMACH_MIC_IN,
80}; 87};
81 88
82struct platform_device s3c_device_ac97 = { 89struct platform_device s3c_device_ac97 = {
@@ -87,6 +94,7 @@ struct platform_device s3c_device_ac97 = {
87 .dev = { 94 .dev = {
88 .dma_mask = &samsung_device_dma_mask, 95 .dma_mask = &samsung_device_dma_mask,
89 .coherent_dma_mask = DMA_BIT_MASK(32), 96 .coherent_dma_mask = DMA_BIT_MASK(32),
97 .platform_data = &s3c_ac97_pdata,
90 } 98 }
91}; 99};
92#endif /* CONFIG_CPU_S3C2440 */ 100#endif /* CONFIG_CPU_S3C2440 */
@@ -566,6 +574,14 @@ static struct resource s3c_iis_resource[] = {
566 [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS), 574 [0] = DEFINE_RES_MEM(S3C24XX_PA_IIS, S3C24XX_SZ_IIS),
567}; 575};
568 576
577static struct s3c_audio_pdata s3c_iis_platdata = {
578#ifdef CONFIG_S3C24XX_DMAC
579 .dma_filter = s3c24xx_dma_filter,
580#endif
581 .dma_playback = (void *)DMACH_I2S_OUT,
582 .dma_capture = (void *)DMACH_I2S_IN,
583};
584
569struct platform_device s3c_device_iis = { 585struct platform_device s3c_device_iis = {
570 .name = "s3c24xx-iis", 586 .name = "s3c24xx-iis",
571 .id = -1, 587 .id = -1,
@@ -574,6 +590,7 @@ struct platform_device s3c_device_iis = {
574 .dev = { 590 .dev = {
575 .dma_mask = &samsung_device_dma_mask, 591 .dma_mask = &samsung_device_dma_mask,
576 .coherent_dma_mask = DMA_BIT_MASK(32), 592 .coherent_dma_mask = DMA_BIT_MASK(32),
593 .platform_data = &s3c_iis_platdata,
577 } 594 }
578}; 595};
579#endif /* CONFIG_PLAT_S3C24XX */ 596#endif /* CONFIG_PLAT_S3C24XX */
diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h
index 7249e6d0902d..5973a2f3db3d 100644
--- a/arch/x86/include/asm/platform_sst_audio.h
+++ b/arch/x86/include/asm/platform_sst_audio.h
@@ -55,6 +55,7 @@ enum sst_audio_device_id_mrfld {
55 PIPE_MEDIA0_IN = 0x8F, 55 PIPE_MEDIA0_IN = 0x8F,
56 PIPE_MEDIA1_IN = 0x90, 56 PIPE_MEDIA1_IN = 0x90,
57 PIPE_MEDIA2_IN = 0x91, 57 PIPE_MEDIA2_IN = 0x91,
58 PIPE_MEDIA3_IN = 0x9C,
58 PIPE_RSVD = 0xFF, 59 PIPE_RSVD = 0xFF,
59}; 60};
60 61
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index e6cd1a32025a..17655d9ba518 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -432,7 +432,7 @@ config STE_DMA40
432 Support for ST-Ericsson DMA40 controller 432 Support for ST-Ericsson DMA40 controller
433 433
434config S3C24XX_DMAC 434config S3C24XX_DMAC
435 tristate "Samsung S3C24XX DMA support" 435 bool "Samsung S3C24XX DMA support"
436 depends on ARCH_S3C24XX 436 depends on ARCH_S3C24XX
437 select DMA_ENGINE 437 select DMA_ENGINE
438 select DMA_VIRTUAL_CHANNELS 438 select DMA_VIRTUAL_CHANNELS
diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h
index 5e0bc779e6c5..15bf56ee8af7 100644
--- a/include/linux/platform_data/asoc-s3c.h
+++ b/include/linux/platform_data/asoc-s3c.h
@@ -13,6 +13,9 @@
13 */ 13 */
14#define S3C64XX_AC97_GPD 0 14#define S3C64XX_AC97_GPD 0
15#define S3C64XX_AC97_GPE 1 15#define S3C64XX_AC97_GPE 1
16
17#include <linux/dmaengine.h>
18
16extern void s3c64xx_ac97_setup_gpio(int); 19extern void s3c64xx_ac97_setup_gpio(int);
17 20
18struct samsung_i2s { 21struct samsung_i2s {
@@ -39,6 +42,11 @@ struct samsung_i2s {
39 */ 42 */
40struct s3c_audio_pdata { 43struct s3c_audio_pdata {
41 int (*cfg_gpio)(struct platform_device *); 44 int (*cfg_gpio)(struct platform_device *);
45 dma_filter_fn dma_filter;
46 void *dma_playback;
47 void *dma_capture;
48 void *dma_play_sec;
49 void *dma_capture_mic;
42 union { 50 union {
43 struct samsung_i2s i2s; 51 struct samsung_i2s i2s;
44 } type; 52 } type;
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 74bc85473b58..15aa5f07c955 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -417,11 +417,13 @@
417#define AC97_RATES_MIC_ADC 4 417#define AC97_RATES_MIC_ADC 4
418#define AC97_RATES_SPDIF 5 418#define AC97_RATES_SPDIF 5
419 419
420#define AC97_NUM_GPIOS 16
420/* 421/*
421 * 422 *
422 */ 423 */
423 424
424struct snd_ac97; 425struct snd_ac97;
426struct snd_ac97_gpio_priv;
425struct snd_pcm_chmap; 427struct snd_pcm_chmap;
426 428
427struct snd_ac97_build_ops { 429struct snd_ac97_build_ops {
@@ -529,6 +531,7 @@ struct snd_ac97 {
529 struct delayed_work power_work; 531 struct delayed_work power_work;
530#endif 532#endif
531 struct device dev; 533 struct device dev;
534 struct snd_ac97_gpio_priv *gpio_priv;
532 535
533 struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */ 536 struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */
534}; 537};
diff --git a/include/sound/da7218.h b/include/sound/da7218.h
new file mode 100644
index 000000000000..0dbb818ac116
--- /dev/null
+++ b/include/sound/da7218.h
@@ -0,0 +1,109 @@
1/*
2 * da7218.h - DA7218 ASoC Codec Driver Platform Data
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.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#ifndef _DA7218_PDATA_H
15#define _DA7218_PDATA_H
16
17/* Mic Bias */
18enum da7218_micbias_voltage {
19 DA7218_MICBIAS_1_2V = -1,
20 DA7218_MICBIAS_1_6V,
21 DA7218_MICBIAS_1_8V,
22 DA7218_MICBIAS_2_0V,
23 DA7218_MICBIAS_2_2V,
24 DA7218_MICBIAS_2_4V,
25 DA7218_MICBIAS_2_6V,
26 DA7218_MICBIAS_2_8V,
27 DA7218_MICBIAS_3_0V,
28};
29
30enum da7218_mic_amp_in_sel {
31 DA7218_MIC_AMP_IN_SEL_DIFF = 0,
32 DA7218_MIC_AMP_IN_SEL_SE_P,
33 DA7218_MIC_AMP_IN_SEL_SE_N,
34};
35
36/* DMIC */
37enum da7218_dmic_data_sel {
38 DA7218_DMIC_DATA_LRISE_RFALL = 0,
39 DA7218_DMIC_DATA_LFALL_RRISE,
40};
41
42enum da7218_dmic_samplephase {
43 DA7218_DMIC_SAMPLE_ON_CLKEDGE = 0,
44 DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE,
45};
46
47enum da7218_dmic_clk_rate {
48 DA7218_DMIC_CLK_3_0MHZ = 0,
49 DA7218_DMIC_CLK_1_5MHZ,
50};
51
52/* Headphone Detect */
53enum da7218_hpldet_jack_rate {
54 DA7218_HPLDET_JACK_RATE_5US = 0,
55 DA7218_HPLDET_JACK_RATE_10US,
56 DA7218_HPLDET_JACK_RATE_20US,
57 DA7218_HPLDET_JACK_RATE_40US,
58 DA7218_HPLDET_JACK_RATE_80US,
59 DA7218_HPLDET_JACK_RATE_160US,
60 DA7218_HPLDET_JACK_RATE_320US,
61 DA7218_HPLDET_JACK_RATE_640US,
62};
63
64enum da7218_hpldet_jack_debounce {
65 DA7218_HPLDET_JACK_DEBOUNCE_OFF = 0,
66 DA7218_HPLDET_JACK_DEBOUNCE_2,
67 DA7218_HPLDET_JACK_DEBOUNCE_3,
68 DA7218_HPLDET_JACK_DEBOUNCE_4,
69};
70
71enum da7218_hpldet_jack_thr {
72 DA7218_HPLDET_JACK_THR_84PCT = 0,
73 DA7218_HPLDET_JACK_THR_88PCT,
74 DA7218_HPLDET_JACK_THR_92PCT,
75 DA7218_HPLDET_JACK_THR_96PCT,
76};
77
78struct da7218_hpldet_pdata {
79 enum da7218_hpldet_jack_rate jack_rate;
80 enum da7218_hpldet_jack_debounce jack_debounce;
81 enum da7218_hpldet_jack_thr jack_thr;
82 bool comp_inv;
83 bool hyst;
84 bool discharge;
85};
86
87struct da7218_pdata {
88 /* Mic */
89 enum da7218_micbias_voltage micbias1_lvl;
90 enum da7218_micbias_voltage micbias2_lvl;
91 enum da7218_mic_amp_in_sel mic1_amp_in_sel;
92 enum da7218_mic_amp_in_sel mic2_amp_in_sel;
93
94 /* DMIC */
95 enum da7218_dmic_data_sel dmic1_data_sel;
96 enum da7218_dmic_data_sel dmic2_data_sel;
97 enum da7218_dmic_samplephase dmic1_samplephase;
98 enum da7218_dmic_samplephase dmic2_samplephase;
99 enum da7218_dmic_clk_rate dmic1_clk_rate;
100 enum da7218_dmic_clk_rate dmic2_clk_rate;
101
102 /* HP Diff Supply - DA7217 only */
103 bool hp_diff_single_supply;
104
105 /* HP Detect - DA7218 only */
106 struct da7218_hpldet_pdata *hpldet_pdata;
107};
108
109#endif /* _DA7218_PDATA_H */
diff --git a/include/sound/da7219.h b/include/sound/da7219.h
index 3f39e135312d..02876acdc840 100644
--- a/include/sound/da7219.h
+++ b/include/sound/da7219.h
@@ -14,17 +14,10 @@
14#ifndef __DA7219_PDATA_H 14#ifndef __DA7219_PDATA_H
15#define __DA7219_PDATA_H 15#define __DA7219_PDATA_H
16 16
17/* LDO */
18enum da7219_ldo_lvl_sel {
19 DA7219_LDO_LVL_SEL_1_05V = 0,
20 DA7219_LDO_LVL_SEL_1_10V,
21 DA7219_LDO_LVL_SEL_1_20V,
22 DA7219_LDO_LVL_SEL_1_40V,
23};
24
25/* Mic Bias */ 17/* Mic Bias */
26enum da7219_micbias_voltage { 18enum da7219_micbias_voltage {
27 DA7219_MICBIAS_1_8V = 1, 19 DA7219_MICBIAS_1_6V = 0,
20 DA7219_MICBIAS_1_8V,
28 DA7219_MICBIAS_2_0V, 21 DA7219_MICBIAS_2_0V,
29 DA7219_MICBIAS_2_2V, 22 DA7219_MICBIAS_2_2V,
30 DA7219_MICBIAS_2_4V, 23 DA7219_MICBIAS_2_4V,
@@ -41,9 +34,6 @@ enum da7219_mic_amp_in_sel {
41struct da7219_aad_pdata; 34struct da7219_aad_pdata;
42 35
43struct da7219_pdata { 36struct da7219_pdata {
44 /* Internal LDO */
45 enum da7219_ldo_lvl_sel ldo_lvl_sel;
46
47 /* Mic */ 37 /* Mic */
48 enum da7219_micbias_voltage micbias_lvl; 38 enum da7219_micbias_voltage micbias_lvl;
49 enum da7219_mic_amp_in_sel mic_amp_in_sel; 39 enum da7219_mic_amp_in_sel mic_amp_in_sel;
diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h
index 8966ba7c9629..e0bb45807f29 100644
--- a/include/sound/designware_i2s.h
+++ b/include/sound/designware_i2s.h
@@ -45,6 +45,11 @@ struct i2s_platform_data {
45 u32 snd_fmts; 45 u32 snd_fmts;
46 u32 snd_rates; 46 u32 snd_rates;
47 47
48 #define DW_I2S_QUIRK_COMP_REG_OFFSET (1 << 0)
49 unsigned int quirks;
50 unsigned int i2s_reg_comp1;
51 unsigned int i2s_reg_comp2;
52
48 void *play_dma_data; 53 void *play_dma_data;
49 void *capture_dma_data; 54 void *capture_dma_data;
50 bool (*filter)(struct dma_chan *chan, void *slave); 55 bool (*filter)(struct dma_chan *chan, void *slave);
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index a4cadd9c297a..425af0674557 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -186,9 +186,15 @@ struct hdac_ext_device {
186 /* codec ops */ 186 /* codec ops */
187 struct hdac_ext_codec_ops ops; 187 struct hdac_ext_codec_ops ops;
188 188
189 struct snd_card *card;
190 void *scodec;
189 void *private_data; 191 void *private_data;
190}; 192};
191 193
194struct hdac_ext_dma_params {
195 u32 format;
196 u8 stream_tag;
197};
192#define to_ehdac_device(dev) (container_of((dev), \ 198#define to_ehdac_device(dev) (container_of((dev), \
193 struct hdac_ext_device, hdac)) 199 struct hdac_ext_device, hdac))
194/* 200/*
diff --git a/include/sound/rt5659.h b/include/sound/rt5659.h
new file mode 100644
index 000000000000..656c4d58948d
--- /dev/null
+++ b/include/sound/rt5659.h
@@ -0,0 +1,49 @@
1/*
2 * linux/sound/rt5659.h -- Platform data for RT5659
3 *
4 * Copyright 2013 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_RT5659_H
12#define __LINUX_SND_RT5659_H
13
14enum rt5659_dmic1_data_pin {
15 RT5659_DMIC1_NULL,
16 RT5659_DMIC1_DATA_IN2N,
17 RT5659_DMIC1_DATA_GPIO5,
18 RT5659_DMIC1_DATA_GPIO9,
19 RT5659_DMIC1_DATA_GPIO11,
20};
21
22enum rt5659_dmic2_data_pin {
23 RT5659_DMIC2_NULL,
24 RT5659_DMIC2_DATA_IN2P,
25 RT5659_DMIC2_DATA_GPIO6,
26 RT5659_DMIC2_DATA_GPIO10,
27 RT5659_DMIC2_DATA_GPIO12,
28};
29
30enum rt5659_jd_src {
31 RT5659_JD_NULL,
32 RT5659_JD3,
33};
34
35struct rt5659_platform_data {
36 bool in1_diff;
37 bool in3_diff;
38 bool in4_diff;
39
40 int ldo1_en; /* GPIO for LDO1_EN */
41 int reset; /* GPIO for RESET */
42
43 enum rt5659_dmic1_data_pin dmic1_data_pin;
44 enum rt5659_dmic2_data_pin dmic2_data_pin;
45 enum rt5659_jd_src jd_src;
46};
47
48#endif
49
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 95a937eafb79..97069466c38d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -49,6 +49,9 @@ struct device;
49#define SND_SOC_DAPM_SIGGEN(wname) \ 49#define SND_SOC_DAPM_SIGGEN(wname) \
50{ .id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \ 50{ .id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \
51 .num_kcontrols = 0, .reg = SND_SOC_NOPM } 51 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
52#define SND_SOC_DAPM_SINK(wname) \
53{ .id = snd_soc_dapm_sink, .name = wname, .kcontrol_news = NULL, \
54 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
52#define SND_SOC_DAPM_INPUT(wname) \ 55#define SND_SOC_DAPM_INPUT(wname) \
53{ .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \ 56{ .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
54 .num_kcontrols = 0, .reg = SND_SOC_NOPM } 57 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
@@ -485,6 +488,7 @@ enum snd_soc_dapm_type {
485 snd_soc_dapm_aif_in, /* audio interface input */ 488 snd_soc_dapm_aif_in, /* audio interface input */
486 snd_soc_dapm_aif_out, /* audio interface output */ 489 snd_soc_dapm_aif_out, /* audio interface output */
487 snd_soc_dapm_siggen, /* signal generator */ 490 snd_soc_dapm_siggen, /* signal generator */
491 snd_soc_dapm_sink,
488 snd_soc_dapm_dai_in, /* link to DAI structure */ 492 snd_soc_dapm_dai_in, /* link to DAI structure */
489 snd_soc_dapm_dai_out, 493 snd_soc_dapm_dai_out,
490 snd_soc_dapm_dai_link, /* link between two DAI structures */ 494 snd_soc_dapm_dai_link, /* link between two DAI structures */
diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h
index 086cd7ff6ddc..5b68e3f5aa85 100644
--- a/include/sound/soc-topology.h
+++ b/include/sound/soc-topology.h
@@ -92,8 +92,10 @@ struct snd_soc_tplg_kcontrol_ops {
92/* Bytes ext operations, for TLV byte controls */ 92/* Bytes ext operations, for TLV byte controls */
93struct snd_soc_tplg_bytes_ext_ops { 93struct snd_soc_tplg_bytes_ext_ops {
94 u32 id; 94 u32 id;
95 int (*get)(unsigned int __user *bytes, unsigned int size); 95 int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes,
96 int (*put)(const unsigned int __user *bytes, unsigned int size); 96 unsigned int size);
97 int (*put)(struct snd_kcontrol *kcontrol,
98 const unsigned int __user *bytes, unsigned int size);
97}; 99};
98 100
99/* 101/*
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a8b4b9c8b1d2..a2deeb954c21 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -110,6 +110,14 @@
110 .put = snd_soc_put_volsw, \ 110 .put = snd_soc_put_volsw, \
111 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ 111 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
112 max, invert, 0) } 112 max, invert, 0) }
113#define SOC_DOUBLE_STS(xname, reg, shift_left, shift_right, max, invert) \
114{ \
115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
116 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
117 .access = SNDRV_CTL_ELEM_ACCESS_READ | \
118 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
119 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
120 max, invert, 0) }
113#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 121#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
114{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 122{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
115 .info = snd_soc_info_volsw, \ 123 .info = snd_soc_info_volsw, \
@@ -293,6 +301,9 @@
293 {.base = xbase, .num_regs = xregs, \ 301 {.base = xbase, .num_regs = xregs, \
294 .mask = xmask }) } 302 .mask = xmask }) }
295 303
304/*
305 * SND_SOC_BYTES_EXT is deprecated, please USE SND_SOC_BYTES_TLV instead
306 */
296#define SND_SOC_BYTES_EXT(xname, xcount, xhandler_get, xhandler_put) \ 307#define SND_SOC_BYTES_EXT(xname, xcount, xhandler_get, xhandler_put) \
297{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 308{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
298 .info = snd_soc_bytes_info_ext, \ 309 .info = snd_soc_bytes_info_ext, \
@@ -1037,6 +1048,9 @@ struct snd_soc_dai_link {
1037 1048
1038 /* pmdown_time is ignored at stop */ 1049 /* pmdown_time is ignored at stop */
1039 unsigned int ignore_pmdown_time:1; 1050 unsigned int ignore_pmdown_time:1;
1051
1052 struct list_head list; /* DAI link list of the soc card */
1053 struct snd_soc_dobj dobj; /* For topology */
1040}; 1054};
1041 1055
1042struct snd_soc_codec_conf { 1056struct snd_soc_codec_conf {
@@ -1101,12 +1115,20 @@ struct snd_soc_card {
1101 struct snd_soc_dapm_context *dapm, 1115 struct snd_soc_dapm_context *dapm,
1102 enum snd_soc_bias_level level); 1116 enum snd_soc_bias_level level);
1103 1117
1118 int (*add_dai_link)(struct snd_soc_card *,
1119 struct snd_soc_dai_link *link);
1120 void (*remove_dai_link)(struct snd_soc_card *,
1121 struct snd_soc_dai_link *link);
1122
1104 long pmdown_time; 1123 long pmdown_time;
1105 1124
1106 /* CPU <--> Codec DAI links */ 1125 /* CPU <--> Codec DAI links */
1107 struct snd_soc_dai_link *dai_link; 1126 struct snd_soc_dai_link *dai_link; /* predefined links only */
1108 int num_links; 1127 int num_links; /* predefined links only */
1109 struct snd_soc_pcm_runtime *rtd; 1128 struct list_head dai_link_list; /* all links */
1129 int num_dai_links;
1130
1131 struct list_head rtd_list;
1110 int num_rtd; 1132 int num_rtd;
1111 1133
1112 /* optional codec specific configuration */ 1134 /* optional codec specific configuration */
@@ -1201,6 +1223,9 @@ struct snd_soc_pcm_runtime {
1201 struct dentry *debugfs_dpcm_root; 1223 struct dentry *debugfs_dpcm_root;
1202 struct dentry *debugfs_dpcm_state; 1224 struct dentry *debugfs_dpcm_state;
1203#endif 1225#endif
1226
1227 unsigned int num; /* 0-based and monotonic increasing */
1228 struct list_head list; /* rtd list of the soc card */
1204}; 1229};
1205 1230
1206/* mixer control */ 1231/* mixer control */
@@ -1225,8 +1250,10 @@ struct soc_bytes_ext {
1225 struct snd_soc_dobj dobj; 1250 struct snd_soc_dobj dobj;
1226 1251
1227 /* used for TLV byte control */ 1252 /* used for TLV byte control */
1228 int (*get)(unsigned int __user *bytes, unsigned int size); 1253 int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes,
1229 int (*put)(const unsigned int __user *bytes, unsigned int size); 1254 unsigned int size);
1255 int (*put)(struct snd_kcontrol *kcontrol, const unsigned int __user *bytes,
1256 unsigned int size);
1230}; 1257};
1231 1258
1232/* multi register control */ 1259/* multi register control */
@@ -1644,6 +1671,11 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
1644 struct device_node *of_node, 1671 struct device_node *of_node,
1645 struct snd_soc_dai_link *dai_link); 1672 struct snd_soc_dai_link *dai_link);
1646 1673
1674int snd_soc_add_dai_link(struct snd_soc_card *card,
1675 struct snd_soc_dai_link *dai_link);
1676void snd_soc_remove_dai_link(struct snd_soc_card *card,
1677 struct snd_soc_dai_link *dai_link);
1678
1647#include <sound/soc-dai.h> 1679#include <sound/soc-dai.h>
1648 1680
1649#ifdef CONFIG_DEBUG_FS 1681#ifdef CONFIG_DEBUG_FS
diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h
index 26539a7e4880..c4cc1e40b35c 100644
--- a/include/uapi/sound/asoc.h
+++ b/include/uapi/sound/asoc.h
@@ -243,7 +243,7 @@ struct snd_soc_tplg_manifest {
243 __le32 control_elems; /* number of control elements */ 243 __le32 control_elems; /* number of control elements */
244 __le32 widget_elems; /* number of widget elements */ 244 __le32 widget_elems; /* number of widget elements */
245 __le32 graph_elems; /* number of graph elements */ 245 __le32 graph_elems; /* number of graph elements */
246 __le32 dai_elems; /* number of DAI elements */ 246 __le32 pcm_elems; /* number of PCM elements */
247 __le32 dai_link_elems; /* number of DAI link elements */ 247 __le32 dai_link_elems; /* number of DAI link elements */
248 struct snd_soc_tplg_private priv; 248 struct snd_soc_tplg_private priv;
249} __attribute__((packed)); 249} __attribute__((packed));
diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h
index d9bd9ca0d5b0..9625484a4a2a 100644
--- a/include/uapi/sound/compress_params.h
+++ b/include/uapi/sound/compress_params.h
@@ -73,7 +73,8 @@
73#define SND_AUDIOCODEC_IEC61937 ((__u32) 0x0000000B) 73#define SND_AUDIOCODEC_IEC61937 ((__u32) 0x0000000B)
74#define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C) 74#define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C)
75#define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D) 75#define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D)
76#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_G729 76#define SND_AUDIOCODEC_BESPOKE ((__u32) 0x0000000E)
77#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_BESPOKE
77 78
78/* 79/*
79 * Profile and modes are listed with bit masks. This allows for a 80 * Profile and modes are listed with bit masks. This allows for a
@@ -312,7 +313,7 @@ struct snd_enc_flac {
312 313
313struct snd_enc_generic { 314struct snd_enc_generic {
314 __u32 bw; /* encoder bandwidth */ 315 __u32 bw; /* encoder bandwidth */
315 __s32 reserved[15]; 316 __s32 reserved[15]; /* Can be used for SND_AUDIOCODEC_BESPOKE */
316} __attribute__((packed, aligned(4))); 317} __attribute__((packed, aligned(4)));
317 318
318union snd_codec_options { 319union snd_codec_options {
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7ff7d88e46dd..a012b2655e84 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -50,6 +50,7 @@ source "sound/soc/jz4740/Kconfig"
50source "sound/soc/nuc900/Kconfig" 50source "sound/soc/nuc900/Kconfig"
51source "sound/soc/omap/Kconfig" 51source "sound/soc/omap/Kconfig"
52source "sound/soc/kirkwood/Kconfig" 52source "sound/soc/kirkwood/Kconfig"
53source "sound/soc/img/Kconfig"
53source "sound/soc/intel/Kconfig" 54source "sound/soc/intel/Kconfig"
54source "sound/soc/mediatek/Kconfig" 55source "sound/soc/mediatek/Kconfig"
55source "sound/soc/mxs/Kconfig" 56source "sound/soc/mxs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 8eb06db32fa0..78625fae78d6 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC) += davinci/
27obj-$(CONFIG_SND_SOC) += dwc/ 27obj-$(CONFIG_SND_SOC) += dwc/
28obj-$(CONFIG_SND_SOC) += fsl/ 28obj-$(CONFIG_SND_SOC) += fsl/
29obj-$(CONFIG_SND_SOC) += jz4740/ 29obj-$(CONFIG_SND_SOC) += jz4740/
30obj-$(CONFIG_SND_SOC) += img/
30obj-$(CONFIG_SND_SOC) += intel/ 31obj-$(CONFIG_SND_SOC) += intel/
31obj-$(CONFIG_SND_SOC) += mediatek/ 32obj-$(CONFIG_SND_SOC) += mediatek/
32obj-$(CONFIG_SND_SOC) += mxs/ 33obj-$(CONFIG_SND_SOC) += mxs/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 2d30464b81ce..06e099e802df 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -68,4 +68,13 @@ config SND_ATMEL_SOC_CLASSD
68 help 68 help
69 Say Y if you want to add support for Atmel ASoC driver for boards using 69 Say Y if you want to add support for Atmel ASoC driver for boards using
70 CLASSD. 70 CLASSD.
71
72config SND_ATMEL_SOC_PDMIC
73 tristate "Atmel ASoC driver for boards using PDMIC"
74 depends on OF && (ARCH_AT91 || COMPILE_TEST)
75 select SND_SOC_GENERIC_DMAENGINE_PCM
76 select REGMAP_MMIO
77 help
78 Say Y if you want to add support for Atmel ASoC driver for boards using
79 PDMIC.
71endif 80endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index f6f7db428216..a2b127bd9c87 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -12,8 +12,10 @@ snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
12snd-atmel-soc-wm8904-objs := atmel_wm8904.o 12snd-atmel-soc-wm8904-objs := atmel_wm8904.o
13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o 13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
14snd-atmel-soc-classd-objs := atmel-classd.o 14snd-atmel-soc-classd-objs := atmel-classd.o
15snd-atmel-soc-pdmic-objs := atmel-pdmic.o
15 16
16obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o 17obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
17obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o 18obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
18obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o 19obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
19obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o 20obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o
21obj-$(CONFIG_SND_ATMEL_SOC_PDMIC) += snd-atmel-soc-pdmic.o
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index 8276675730ef..6107de9c538b 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -106,7 +106,7 @@ static const struct snd_pcm_hardware atmel_classd_hw = {
106 .rates = ATMEL_CLASSD_RATES, 106 .rates = ATMEL_CLASSD_RATES,
107 .rate_min = 8000, 107 .rate_min = 8000,
108 .rate_max = 96000, 108 .rate_max = 96000,
109 .channels_min = 2, 109 .channels_min = 1,
110 .channels_max = 2, 110 .channels_max = 2,
111 .buffer_bytes_max = 64 * 1024, 111 .buffer_bytes_max = 64 * 1024,
112 .period_bytes_min = 256, 112 .period_bytes_min = 256,
@@ -145,7 +145,7 @@ static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = {
145 145
146static struct snd_soc_dai_driver atmel_classd_cpu_dai = { 146static struct snd_soc_dai_driver atmel_classd_cpu_dai = {
147 .playback = { 147 .playback = {
148 .channels_min = 2, 148 .channels_min = 1,
149 .channels_max = 2, 149 .channels_max = 2,
150 .rates = ATMEL_CLASSD_RATES, 150 .rates = ATMEL_CLASSD_RATES,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 151 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
@@ -171,9 +171,13 @@ atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
171 return -EINVAL; 171 return -EINVAL;
172 } 172 }
173 173
174 if (params_channels(params) == 1)
175 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
176 else
177 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
178
174 slave_config->direction = DMA_MEM_TO_DEV; 179 slave_config->direction = DMA_MEM_TO_DEV;
175 slave_config->dst_addr = dd->phy_base + CLASSD_THR; 180 slave_config->dst_addr = dd->phy_base + CLASSD_THR;
176 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
177 slave_config->dst_maxburst = 1; 181 slave_config->dst_maxburst = 1;
178 slave_config->src_maxburst = 1; 182 slave_config->src_maxburst = 1;
179 slave_config->device_fc = false; 183 slave_config->device_fc = false;
@@ -486,7 +490,7 @@ static struct snd_soc_dai_driver atmel_classd_codec_dai = {
486 .name = ATMEL_CLASSD_CODEC_DAI_NAME, 490 .name = ATMEL_CLASSD_CODEC_DAI_NAME,
487 .playback = { 491 .playback = {
488 .stream_name = "Playback", 492 .stream_name = "Playback",
489 .channels_min = 2, 493 .channels_min = 1,
490 .channels_max = 2, 494 .channels_max = 2,
491 .rates = ATMEL_CLASSD_RATES, 495 .rates = ATMEL_CLASSD_RATES,
492 .formats = SNDRV_PCM_FMTBIT_S16_LE, 496 .formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -636,8 +640,10 @@ static int atmel_classd_probe(struct platform_device *pdev)
636 640
637 /* register sound card */ 641 /* register sound card */
638 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); 642 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
639 if (!card) 643 if (!card) {
640 return -ENOMEM; 644 ret = -ENOMEM;
645 goto unregister_codec;
646 }
641 647
642 snd_soc_card_set_drvdata(card, dd); 648 snd_soc_card_set_drvdata(card, dd);
643 platform_set_drvdata(pdev, card); 649 platform_set_drvdata(pdev, card);
@@ -645,16 +651,20 @@ static int atmel_classd_probe(struct platform_device *pdev)
645 ret = atmel_classd_asoc_card_init(dev, card); 651 ret = atmel_classd_asoc_card_init(dev, card);
646 if (ret) { 652 if (ret) {
647 dev_err(dev, "failed to init sound card\n"); 653 dev_err(dev, "failed to init sound card\n");
648 return ret; 654 goto unregister_codec;
649 } 655 }
650 656
651 ret = devm_snd_soc_register_card(dev, card); 657 ret = devm_snd_soc_register_card(dev, card);
652 if (ret) { 658 if (ret) {
653 dev_err(dev, "failed to register sound card: %d\n", ret); 659 dev_err(dev, "failed to register sound card: %d\n", ret);
654 return ret; 660 goto unregister_codec;
655 } 661 }
656 662
657 return 0; 663 return 0;
664
665unregister_codec:
666 snd_soc_unregister_codec(dev);
667 return ret;
658} 668}
659 669
660static int atmel_classd_remove(struct platform_device *pdev) 670static int atmel_classd_remove(struct platform_device *pdev)
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
new file mode 100644
index 000000000000..aee4787a0b89
--- /dev/null
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -0,0 +1,738 @@
1/* Atmel PDMIC driver
2 *
3 * Copyright (C) 2015 Atmel
4 *
5 * Author: Songjun Wu <songjun.wu@atmel.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 or later
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/of.h>
13#include <linux/clk.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/dmaengine_pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include "atmel-pdmic.h"
22
23struct atmel_pdmic_pdata {
24 u32 mic_min_freq;
25 u32 mic_max_freq;
26 s32 mic_offset;
27 const char *card_name;
28};
29
30struct atmel_pdmic {
31 dma_addr_t phy_base;
32 struct regmap *regmap;
33 struct clk *pclk;
34 struct clk *gclk;
35 int irq;
36 struct snd_pcm_substream *substream;
37 const struct atmel_pdmic_pdata *pdata;
38};
39
40static const struct of_device_id atmel_pdmic_of_match[] = {
41 {
42 .compatible = "atmel,sama5d2-pdmic",
43 }, {
44 /* sentinel */
45 }
46};
47MODULE_DEVICE_TABLE(of, atmel_pdmic_of_match);
48
49#define PDMIC_OFFSET_MAX_VAL S16_MAX
50#define PDMIC_OFFSET_MIN_VAL S16_MIN
51
52static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev)
53{
54 struct device_node *np = dev->of_node;
55 struct atmel_pdmic_pdata *pdata;
56
57 if (!np) {
58 dev_err(dev, "device node not found\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
63 if (!pdata)
64 return ERR_PTR(-ENOMEM);
65
66 if (of_property_read_string(np, "atmel,model", &pdata->card_name))
67 pdata->card_name = "PDMIC";
68
69 if (of_property_read_u32(np, "atmel,mic-min-freq",
70 &pdata->mic_min_freq)) {
71 dev_err(dev, "failed to get mic-min-freq\n");
72 return ERR_PTR(-EINVAL);
73 }
74
75 if (of_property_read_u32(np, "atmel,mic-max-freq",
76 &pdata->mic_max_freq)) {
77 dev_err(dev, "failed to get mic-max-freq\n");
78 return ERR_PTR(-EINVAL);
79 }
80
81 if (pdata->mic_max_freq < pdata->mic_min_freq) {
82 dev_err(dev,
83 "mic-max-freq should not less than mic-min-freq\n");
84 return ERR_PTR(-EINVAL);
85 }
86
87 if (of_property_read_s32(np, "atmel,mic-offset", &pdata->mic_offset))
88 pdata->mic_offset = 0;
89
90 if (pdata->mic_offset > PDMIC_OFFSET_MAX_VAL) {
91 dev_warn(dev,
92 "mic-offset value %d is larger than the max value %d, the max value is specified\n",
93 pdata->mic_offset, PDMIC_OFFSET_MAX_VAL);
94 pdata->mic_offset = PDMIC_OFFSET_MAX_VAL;
95 } else if (pdata->mic_offset < PDMIC_OFFSET_MIN_VAL) {
96 dev_warn(dev,
97 "mic-offset value %d is less than the min value %d, the min value is specified\n",
98 pdata->mic_offset, PDMIC_OFFSET_MIN_VAL);
99 pdata->mic_offset = PDMIC_OFFSET_MIN_VAL;
100 }
101
102 return pdata;
103}
104
105/* cpu dai component */
106static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream,
107 struct snd_soc_dai *cpu_dai)
108{
109 struct snd_soc_pcm_runtime *rtd = substream->private_data;
110 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
111 int ret;
112
113 ret = clk_prepare_enable(dd->gclk);
114 if (ret)
115 return ret;
116
117 ret = clk_prepare_enable(dd->pclk);
118 if (ret)
119 return ret;
120
121 /* Clear all bits in the Control Register(PDMIC_CR) */
122 regmap_write(dd->regmap, PDMIC_CR, 0);
123
124 dd->substream = substream;
125
126 /* Enable the overrun error interrupt */
127 regmap_write(dd->regmap, PDMIC_IER, PDMIC_IER_OVRE);
128
129 return 0;
130}
131
132static void atmel_pdmic_cpu_dai_shutdown(struct snd_pcm_substream *substream,
133 struct snd_soc_dai *cpu_dai)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
137
138 /* Disable the overrun error interrupt */
139 regmap_write(dd->regmap, PDMIC_IDR, PDMIC_IDR_OVRE);
140
141 clk_disable_unprepare(dd->gclk);
142 clk_disable_unprepare(dd->pclk);
143}
144
145static int atmel_pdmic_cpu_dai_prepare(struct snd_pcm_substream *substream,
146 struct snd_soc_dai *cpu_dai)
147{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
150 u32 val;
151
152 /* Clean the PDMIC Converted Data Register */
153 return regmap_read(dd->regmap, PDMIC_CDR, &val);
154}
155
156static const struct snd_soc_dai_ops atmel_pdmic_cpu_dai_ops = {
157 .startup = atmel_pdmic_cpu_dai_startup,
158 .shutdown = atmel_pdmic_cpu_dai_shutdown,
159 .prepare = atmel_pdmic_cpu_dai_prepare,
160};
161
162#define ATMEL_PDMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
163
164static struct snd_soc_dai_driver atmel_pdmic_cpu_dai = {
165 .capture = {
166 .channels_min = 1,
167 .channels_max = 1,
168 .rates = SNDRV_PCM_RATE_KNOT,
169 .formats = ATMEL_PDMIC_FORMATS,},
170 .ops = &atmel_pdmic_cpu_dai_ops,
171};
172
173static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = {
174 .name = "atmel-pdmic",
175};
176
177/* platform */
178#define ATMEL_PDMIC_MAX_BUF_SIZE (64 * 1024)
179#define ATMEL_PDMIC_PREALLOC_BUF_SIZE ATMEL_PDMIC_MAX_BUF_SIZE
180
181static const struct snd_pcm_hardware atmel_pdmic_hw = {
182 .info = SNDRV_PCM_INFO_MMAP
183 | SNDRV_PCM_INFO_MMAP_VALID
184 | SNDRV_PCM_INFO_INTERLEAVED
185 | SNDRV_PCM_INFO_RESUME
186 | SNDRV_PCM_INFO_PAUSE,
187 .formats = ATMEL_PDMIC_FORMATS,
188 .buffer_bytes_max = ATMEL_PDMIC_MAX_BUF_SIZE,
189 .period_bytes_min = 256,
190 .period_bytes_max = 32 * 1024,
191 .periods_min = 2,
192 .periods_max = 256,
193};
194
195static int
196atmel_pdmic_platform_configure_dma(struct snd_pcm_substream *substream,
197 struct snd_pcm_hw_params *params,
198 struct dma_slave_config *slave_config)
199{
200 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
202 int ret;
203
204 ret = snd_hwparams_to_dma_slave_config(substream, params,
205 slave_config);
206 if (ret) {
207 dev_err(rtd->platform->dev,
208 "hw params to dma slave configure failed\n");
209 return ret;
210 }
211
212 slave_config->src_addr = dd->phy_base + PDMIC_CDR;
213 slave_config->src_maxburst = 1;
214 slave_config->dst_maxburst = 1;
215
216 return 0;
217}
218
219static const struct snd_dmaengine_pcm_config
220atmel_pdmic_dmaengine_pcm_config = {
221 .prepare_slave_config = atmel_pdmic_platform_configure_dma,
222 .pcm_hardware = &atmel_pdmic_hw,
223 .prealloc_buffer_size = ATMEL_PDMIC_PREALLOC_BUF_SIZE,
224};
225
226/* codec */
227/* Mic Gain = dgain * 2^(-scale) */
228struct mic_gain {
229 unsigned int dgain;
230 unsigned int scale;
231};
232
233/* range from -90 dB to 90 dB */
234static const struct mic_gain mic_gain_table[] = {
235{ 1, 15}, { 1, 14}, /* -90, -84 dB */
236{ 3, 15}, { 1, 13}, { 3, 14}, { 1, 12}, /* -81, -78, -75, -72 dB */
237{ 5, 14}, { 13, 15}, /* -70, -68 dB */
238{ 9, 14}, { 21, 15}, { 23, 15}, { 13, 14}, /* -65 ~ -62 dB */
239{ 29, 15}, { 33, 15}, { 37, 15}, { 41, 15}, /* -61 ~ -58 dB */
240{ 23, 14}, { 13, 13}, { 58, 15}, { 65, 15}, /* -57 ~ -54 dB */
241{ 73, 15}, { 41, 14}, { 23, 13}, { 13, 12}, /* -53 ~ -50 dB */
242{ 29, 13}, { 65, 14}, { 73, 14}, { 41, 13}, /* -49 ~ -46 dB */
243{ 23, 12}, { 207, 15}, { 29, 12}, { 65, 13}, /* -45 ~ -42 dB */
244{ 73, 13}, { 41, 12}, { 23, 11}, { 413, 15}, /* -41 ~ -38 dB */
245{ 463, 15}, { 519, 15}, { 583, 15}, { 327, 14}, /* -37 ~ -34 dB */
246{ 367, 14}, { 823, 15}, { 231, 13}, { 1036, 15}, /* -33 ~ -30 dB */
247{ 1163, 15}, { 1305, 15}, { 183, 12}, { 1642, 15}, /* -29 ~ -26 dB */
248{ 1843, 15}, { 2068, 15}, { 145, 11}, { 2603, 15}, /* -25 ~ -22 dB */
249{ 365, 12}, { 3277, 15}, { 3677, 15}, { 4125, 15}, /* -21 ~ -18 dB */
250{ 4629, 15}, { 5193, 15}, { 5827, 15}, { 3269, 14}, /* -17 ~ -14 dB */
251{ 917, 12}, { 8231, 15}, { 9235, 15}, { 5181, 14}, /* -13 ~ -10 dB */
252{11627, 15}, {13045, 15}, {14637, 15}, {16423, 15}, /* -9 ~ -6 dB */
253{18427, 15}, {20675, 15}, { 5799, 13}, {26029, 15}, /* -5 ~ -2 dB */
254{ 7301, 13}, { 1, 0}, {18383, 14}, {10313, 13}, /* -1 ~ 2 dB */
255{23143, 14}, {25967, 14}, {29135, 14}, {16345, 13}, /* 3 ~ 6 dB */
256{ 4585, 11}, {20577, 13}, { 1443, 9}, {25905, 13}, /* 7 ~ 10 dB */
257{14533, 12}, { 8153, 11}, { 2287, 9}, {20529, 12}, /* 11 ~ 14 dB */
258{11517, 11}, { 6461, 10}, {28997, 12}, { 4067, 9}, /* 15 ~ 18 dB */
259{18253, 11}, { 10, 0}, {22979, 11}, {25783, 11}, /* 19 ~ 22 dB */
260{28929, 11}, {32459, 11}, { 9105, 9}, {20431, 10}, /* 23 ~ 26 dB */
261{22925, 10}, {12861, 9}, { 7215, 8}, {16191, 9}, /* 27 ~ 30 dB */
262{ 9083, 8}, {20383, 9}, {11435, 8}, { 6145, 7}, /* 31 ~ 34 dB */
263{ 3599, 6}, {32305, 9}, {18123, 8}, {20335, 8}, /* 35 ~ 38 dB */
264{ 713, 3}, { 100, 0}, { 7181, 6}, { 8057, 6}, /* 39 ~ 42 dB */
265{ 565, 2}, {20287, 7}, {11381, 6}, {25539, 7}, /* 43 ~ 46 dB */
266{ 1791, 3}, { 4019, 4}, { 9019, 5}, {20239, 6}, /* 47 ~ 50 dB */
267{ 5677, 4}, {25479, 6}, { 7147, 4}, { 8019, 4}, /* 51 ~ 54 dB */
268{17995, 5}, {20191, 5}, {11327, 4}, {12709, 4}, /* 55 ~ 58 dB */
269{ 3565, 2}, { 1000, 0}, { 1122, 0}, { 1259, 0}, /* 59 ~ 62 dB */
270{ 2825, 1}, {12679, 3}, { 7113, 2}, { 7981, 2}, /* 63 ~ 66 dB */
271{ 8955, 2}, {20095, 3}, {22547, 3}, {12649, 2}, /* 67 ~ 70 dB */
272{28385, 3}, { 3981, 0}, {17867, 2}, {20047, 2}, /* 71 ~ 74 dB */
273{11247, 1}, {12619, 1}, {14159, 1}, {31773, 2}, /* 75 ~ 78 dB */
274{17825, 1}, {10000, 0}, {11220, 0}, {12589, 0}, /* 79 ~ 82 dB */
275{28251, 1}, {15849, 0}, {17783, 0}, {19953, 0}, /* 83 ~ 86 dB */
276{22387, 0}, {25119, 0}, {28184, 0}, {31623, 0}, /* 87 ~ 90 dB */
277};
278
279static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
280 0, 1, TLV_DB_SCALE_ITEM(-9000, 600, 0),
281 2, 5, TLV_DB_SCALE_ITEM(-8100, 300, 0),
282 6, 7, TLV_DB_SCALE_ITEM(-7000, 200, 0),
283 8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0),
284);
285
286int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
290 unsigned int dgain_val, scale_val;
291 int i;
292
293 dgain_val = (snd_soc_read(codec, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
294 >> PDMIC_DSPR1_DGAIN_SHIFT;
295
296 scale_val = (snd_soc_read(codec, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
297 >> PDMIC_DSPR0_SCALE_SHIFT;
298
299 for (i = 0; i < ARRAY_SIZE(mic_gain_table); i++) {
300 if ((mic_gain_table[i].dgain == dgain_val) &&
301 (mic_gain_table[i].scale == scale_val))
302 ucontrol->value.integer.value[0] = i;
303 }
304
305 return 0;
306}
307
308static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol)
310{
311 struct soc_mixer_control *mc =
312 (struct soc_mixer_control *)kcontrol->private_value;
313 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
314 int max = mc->max;
315 unsigned int val;
316 int ret;
317
318 val = ucontrol->value.integer.value[0];
319
320 if (val > max)
321 return -EINVAL;
322
323 ret = snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
324 mic_gain_table[val].dgain << PDMIC_DSPR1_DGAIN_SHIFT);
325 if (ret < 0)
326 return ret;
327
328 ret = snd_soc_update_bits(codec, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
329 mic_gain_table[val].scale << PDMIC_DSPR0_SCALE_SHIFT);
330 if (ret < 0)
331 return ret;
332
333 return 0;
334}
335
336static const struct snd_kcontrol_new atmel_pdmic_snd_controls[] = {
337SOC_SINGLE_EXT_TLV("Mic Capture Volume", PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_SHIFT,
338 ARRAY_SIZE(mic_gain_table)-1, 0,
339 pdmic_get_mic_volsw, pdmic_put_mic_volsw, mic_gain_tlv),
340
341SOC_SINGLE("High Pass Filter Switch", PDMIC_DSPR0,
342 PDMIC_DSPR0_HPFBYP_SHIFT, 1, 1),
343
344SOC_SINGLE("SINCC Filter Switch", PDMIC_DSPR0, PDMIC_DSPR0_SINBYP_SHIFT, 1, 1),
345};
346
347static int atmel_pdmic_codec_probe(struct snd_soc_codec *codec)
348{
349 struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
350 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
351
352 snd_soc_update_bits(codec, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
353 (u32)(dd->pdata->mic_offset << PDMIC_DSPR1_OFFSET_SHIFT));
354
355 return 0;
356}
357
358static struct snd_soc_codec_driver soc_codec_dev_pdmic = {
359 .probe = atmel_pdmic_codec_probe,
360 .controls = atmel_pdmic_snd_controls,
361 .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls),
362};
363
364/* codec dai component */
365#define PDMIC_MR_PRESCAL_MAX_VAL 127
366
367static int
368atmel_pdmic_codec_dai_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params,
370 struct snd_soc_dai *codec_dai)
371{
372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
373 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
374 struct snd_soc_codec *codec = codec_dai->codec;
375 unsigned int rate_min = substream->runtime->hw.rate_min;
376 unsigned int rate_max = substream->runtime->hw.rate_max;
377 int fs = params_rate(params);
378 int bits = params_width(params);
379 unsigned long pclk_rate, gclk_rate;
380 unsigned int f_pdmic;
381 u32 mr_val, dspr0_val, pclk_prescal, gclk_prescal;
382
383 if (params_channels(params) != 1) {
384 dev_err(codec->dev,
385 "only supports one channel\n");
386 return -EINVAL;
387 }
388
389 if ((fs < rate_min) || (fs > rate_max)) {
390 dev_err(codec->dev,
391 "sample rate is %dHz, min rate is %dHz, max rate is %dHz\n",
392 fs, rate_min, rate_max);
393
394 return -EINVAL;
395 }
396
397 switch (bits) {
398 case 16:
399 dspr0_val = (PDMIC_DSPR0_SIZE_16_BITS
400 << PDMIC_DSPR0_SIZE_SHIFT);
401 break;
402 case 32:
403 dspr0_val = (PDMIC_DSPR0_SIZE_32_BITS
404 << PDMIC_DSPR0_SIZE_SHIFT);
405 break;
406 default:
407 return -EINVAL;
408 }
409
410 if ((fs << 7) > (rate_max << 6)) {
411 f_pdmic = fs << 6;
412 dspr0_val |= PDMIC_DSPR0_OSR_64 << PDMIC_DSPR0_OSR_SHIFT;
413 } else {
414 f_pdmic = fs << 7;
415 dspr0_val |= PDMIC_DSPR0_OSR_128 << PDMIC_DSPR0_OSR_SHIFT;
416 }
417
418 pclk_rate = clk_get_rate(dd->pclk);
419 gclk_rate = clk_get_rate(dd->gclk);
420
421 /* PRESCAL = SELCK/(2*f_pdmic) - 1*/
422 pclk_prescal = (u32)(pclk_rate/(f_pdmic << 1)) - 1;
423 gclk_prescal = (u32)(gclk_rate/(f_pdmic << 1)) - 1;
424
425 if ((pclk_prescal > PDMIC_MR_PRESCAL_MAX_VAL) ||
426 (gclk_rate/((gclk_prescal + 1) << 1) <
427 pclk_rate/((pclk_prescal + 1) << 1))) {
428 mr_val = gclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
429 mr_val |= PDMIC_MR_CLKS_GCK << PDMIC_MR_CLKS_SHIFT;
430 } else {
431 mr_val = pclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
432 mr_val |= PDMIC_MR_CLKS_PCK << PDMIC_MR_CLKS_SHIFT;
433 }
434
435 snd_soc_update_bits(codec, PDMIC_MR,
436 PDMIC_MR_PRESCAL_MASK | PDMIC_MR_CLKS_MASK, mr_val);
437
438 snd_soc_update_bits(codec, PDMIC_DSPR0,
439 PDMIC_DSPR0_OSR_MASK | PDMIC_DSPR0_SIZE_MASK, dspr0_val);
440
441 return 0;
442}
443
444static int atmel_pdmic_codec_dai_prepare(struct snd_pcm_substream *substream,
445 struct snd_soc_dai *codec_dai)
446{
447 struct snd_soc_codec *codec = codec_dai->codec;
448
449 snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
450 PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
451
452 return 0;
453}
454
455static int atmel_pdmic_codec_dai_trigger(struct snd_pcm_substream *substream,
456 int cmd, struct snd_soc_dai *codec_dai)
457{
458 struct snd_soc_codec *codec = codec_dai->codec;
459 u32 val;
460
461 switch (cmd) {
462 case SNDRV_PCM_TRIGGER_START:
463 case SNDRV_PCM_TRIGGER_RESUME:
464 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
465 val = PDMIC_CR_ENPDM_EN << PDMIC_CR_ENPDM_SHIFT;
466 break;
467 case SNDRV_PCM_TRIGGER_STOP:
468 case SNDRV_PCM_TRIGGER_SUSPEND:
469 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
470 val = PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT;
471 break;
472 default:
473 return -EINVAL;
474 }
475
476 snd_soc_update_bits(codec, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);
477
478 return 0;
479}
480
481static const struct snd_soc_dai_ops atmel_pdmic_codec_dai_ops = {
482 .hw_params = atmel_pdmic_codec_dai_hw_params,
483 .prepare = atmel_pdmic_codec_dai_prepare,
484 .trigger = atmel_pdmic_codec_dai_trigger,
485};
486
487#define ATMEL_PDMIC_CODEC_DAI_NAME "atmel-pdmic-hifi"
488
489static struct snd_soc_dai_driver atmel_pdmic_codec_dai = {
490 .name = ATMEL_PDMIC_CODEC_DAI_NAME,
491 .capture = {
492 .stream_name = "Capture",
493 .channels_min = 1,
494 .channels_max = 1,
495 .rates = SNDRV_PCM_RATE_KNOT,
496 .formats = ATMEL_PDMIC_FORMATS,
497 },
498 .ops = &atmel_pdmic_codec_dai_ops,
499};
500
501/* ASoC sound card */
502static int atmel_pdmic_asoc_card_init(struct device *dev,
503 struct snd_soc_card *card)
504{
505 struct snd_soc_dai_link *dai_link;
506 struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
507
508 dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
509 if (!dai_link)
510 return -ENOMEM;
511
512 dai_link->name = "PDMIC";
513 dai_link->stream_name = "PDMIC PCM";
514 dai_link->codec_dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
515 dai_link->cpu_dai_name = dev_name(dev);
516 dai_link->codec_name = dev_name(dev);
517 dai_link->platform_name = dev_name(dev);
518
519 card->dai_link = dai_link;
520 card->num_links = 1;
521 card->name = dd->pdata->card_name;
522 card->dev = dev;
523
524 return 0;
525}
526
527static void atmel_pdmic_get_sample_rate(struct atmel_pdmic *dd,
528 unsigned int *rate_min, unsigned int *rate_max)
529{
530 u32 mic_min_freq = dd->pdata->mic_min_freq;
531 u32 mic_max_freq = dd->pdata->mic_max_freq;
532 u32 clk_max_rate = (u32)(clk_get_rate(dd->pclk) >> 1);
533 u32 clk_min_rate = (u32)(clk_get_rate(dd->gclk) >> 8);
534
535 if (mic_max_freq > clk_max_rate)
536 mic_max_freq = clk_max_rate;
537
538 if (mic_min_freq < clk_min_rate)
539 mic_min_freq = clk_min_rate;
540
541 *rate_min = DIV_ROUND_CLOSEST(mic_min_freq, 128);
542 *rate_max = mic_max_freq >> 6;
543}
544
545/* PDMIC interrupt handler */
546static irqreturn_t atmel_pdmic_interrupt(int irq, void *dev_id)
547{
548 struct atmel_pdmic *dd = (struct atmel_pdmic *)dev_id;
549 u32 pdmic_isr;
550 irqreturn_t ret = IRQ_NONE;
551
552 regmap_read(dd->regmap, PDMIC_ISR, &pdmic_isr);
553
554 if (pdmic_isr & PDMIC_ISR_OVRE) {
555 regmap_update_bits(dd->regmap, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
556 PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);
557
558 snd_pcm_stop_xrun(dd->substream);
559
560 ret = IRQ_HANDLED;
561 }
562
563 return ret;
564}
565
566/* regmap configuration */
567#define ATMEL_PDMIC_REG_MAX 0x124
568static const struct regmap_config atmel_pdmic_regmap_config = {
569 .reg_bits = 32,
570 .reg_stride = 4,
571 .val_bits = 32,
572 .max_register = ATMEL_PDMIC_REG_MAX,
573};
574
575static int atmel_pdmic_probe(struct platform_device *pdev)
576{
577 struct device *dev = &pdev->dev;
578 struct atmel_pdmic *dd;
579 struct resource *res;
580 void __iomem *io_base;
581 const struct atmel_pdmic_pdata *pdata;
582 struct snd_soc_card *card;
583 unsigned int rate_min, rate_max;
584 int ret;
585
586 pdata = atmel_pdmic_dt_init(dev);
587 if (IS_ERR(pdata))
588 return PTR_ERR(pdata);
589
590 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
591 if (!dd)
592 return -ENOMEM;
593
594 dd->pdata = pdata;
595
596 dd->irq = platform_get_irq(pdev, 0);
597 if (dd->irq < 0) {
598 ret = dd->irq;
599 dev_err(dev, "failed to could not get irq: %d\n", ret);
600 return ret;
601 }
602
603 dd->pclk = devm_clk_get(dev, "pclk");
604 if (IS_ERR(dd->pclk)) {
605 ret = PTR_ERR(dd->pclk);
606 dev_err(dev, "failed to get peripheral clock: %d\n", ret);
607 return ret;
608 }
609
610 dd->gclk = devm_clk_get(dev, "gclk");
611 if (IS_ERR(dd->gclk)) {
612 ret = PTR_ERR(dd->gclk);
613 dev_err(dev, "failed to get GCK: %d\n", ret);
614 return ret;
615 }
616
617 /* The gclk clock frequency must always be tree times
618 * lower than the pclk clock frequency
619 */
620 ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3);
621 if (ret) {
622 dev_err(dev, "failed to set GCK clock rate: %d\n", ret);
623 return ret;
624 }
625
626 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
627 if (!res) {
628 dev_err(dev, "no memory resource\n");
629 return -ENXIO;
630 }
631
632 io_base = devm_ioremap_resource(dev, res);
633 if (IS_ERR(io_base)) {
634 ret = PTR_ERR(io_base);
635 dev_err(dev, "failed to remap register memory: %d\n", ret);
636 return ret;
637 }
638
639 dd->phy_base = res->start;
640
641 dd->regmap = devm_regmap_init_mmio(dev, io_base,
642 &atmel_pdmic_regmap_config);
643 if (IS_ERR(dd->regmap)) {
644 ret = PTR_ERR(dd->regmap);
645 dev_err(dev, "failed to init register map: %d\n", ret);
646 return ret;
647 }
648
649 ret = devm_request_irq(dev, dd->irq, atmel_pdmic_interrupt, 0,
650 "PDMIC", (void *)dd);
651 if (ret < 0) {
652 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
653 dd->irq, ret);
654 return ret;
655 }
656
657 /* Get the minimal and maximal sample rate that micphone supports */
658 atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max);
659
660 /* register cpu dai */
661 atmel_pdmic_cpu_dai.capture.rate_min = rate_min;
662 atmel_pdmic_cpu_dai.capture.rate_max = rate_max;
663 ret = devm_snd_soc_register_component(dev,
664 &atmel_pdmic_cpu_dai_component,
665 &atmel_pdmic_cpu_dai, 1);
666 if (ret) {
667 dev_err(dev, "could not register CPU DAI: %d\n", ret);
668 return ret;
669 }
670
671 /* register platform */
672 ret = devm_snd_dmaengine_pcm_register(dev,
673 &atmel_pdmic_dmaengine_pcm_config,
674 0);
675 if (ret) {
676 dev_err(dev, "could not register platform: %d\n", ret);
677 return ret;
678 }
679
680 /* register codec and codec dai */
681 atmel_pdmic_codec_dai.capture.rate_min = rate_min;
682 atmel_pdmic_codec_dai.capture.rate_max = rate_max;
683 ret = snd_soc_register_codec(dev, &soc_codec_dev_pdmic,
684 &atmel_pdmic_codec_dai, 1);
685 if (ret) {
686 dev_err(dev, "could not register codec: %d\n", ret);
687 return ret;
688 }
689
690 /* register sound card */
691 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
692 if (!card) {
693 ret = -ENOMEM;
694 goto unregister_codec;
695 }
696
697 snd_soc_card_set_drvdata(card, dd);
698 platform_set_drvdata(pdev, card);
699
700 ret = atmel_pdmic_asoc_card_init(dev, card);
701 if (ret) {
702 dev_err(dev, "failed to init sound card: %d\n", ret);
703 goto unregister_codec;
704 }
705
706 ret = devm_snd_soc_register_card(dev, card);
707 if (ret) {
708 dev_err(dev, "failed to register sound card: %d\n", ret);
709 goto unregister_codec;
710 }
711
712 return 0;
713
714unregister_codec:
715 snd_soc_unregister_codec(dev);
716 return ret;
717}
718
719static int atmel_pdmic_remove(struct platform_device *pdev)
720{
721 snd_soc_unregister_codec(&pdev->dev);
722 return 0;
723}
724
725static struct platform_driver atmel_pdmic_driver = {
726 .driver = {
727 .name = "atmel-pdmic",
728 .of_match_table = of_match_ptr(atmel_pdmic_of_match),
729 .pm = &snd_soc_pm_ops,
730 },
731 .probe = atmel_pdmic_probe,
732 .remove = atmel_pdmic_remove,
733};
734module_platform_driver(atmel_pdmic_driver);
735
736MODULE_DESCRIPTION("Atmel PDMIC driver under ALSA SoC architecture");
737MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
738MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/atmel/atmel-pdmic.h b/sound/soc/atmel/atmel-pdmic.h
new file mode 100644
index 000000000000..4527ac741919
--- /dev/null
+++ b/sound/soc/atmel/atmel-pdmic.h
@@ -0,0 +1,80 @@
1#ifndef __ATMEL_PDMIC_H_
2#define __ATMEL_PDMIC_H_
3
4#include <linux/bitops.h>
5
6#define PDMIC_CR 0x00000000
7
8#define PDMIC_CR_SWRST 0x1
9#define PDMIC_CR_SWRST_MASK BIT(0)
10#define PDMIC_CR_SWRST_SHIFT (0)
11
12#define PDMIC_CR_ENPDM_DIS 0x0
13#define PDMIC_CR_ENPDM_EN 0x1
14#define PDMIC_CR_ENPDM_MASK BIT(4)
15#define PDMIC_CR_ENPDM_SHIFT (4)
16
17#define PDMIC_MR 0x00000004
18
19#define PDMIC_MR_CLKS_PCK 0x0
20#define PDMIC_MR_CLKS_GCK 0x1
21#define PDMIC_MR_CLKS_MASK BIT(4)
22#define PDMIC_MR_CLKS_SHIFT (4)
23
24#define PDMIC_MR_PRESCAL_MASK GENMASK(14, 8)
25#define PDMIC_MR_PRESCAL_SHIFT (8)
26
27#define PDMIC_CDR 0x00000014
28
29#define PDMIC_IER 0x00000018
30#define PDMIC_IER_OVRE BIT(25)
31
32#define PDMIC_IDR 0x0000001c
33#define PDMIC_IDR_OVRE BIT(25)
34
35#define PDMIC_IMR 0x00000020
36
37#define PDMIC_ISR 0x00000024
38#define PDMIC_ISR_OVRE BIT(25)
39
40#define PDMIC_DSPR0 0x00000058
41
42#define PDMIC_DSPR0_HPFBYP_DIS 0x1
43#define PDMIC_DSPR0_HPFBYP_EN 0x0
44#define PDMIC_DSPR0_HPFBYP_MASK BIT(1)
45#define PDMIC_DSPR0_HPFBYP_SHIFT (1)
46
47#define PDMIC_DSPR0_SINBYP_DIS 0x1
48#define PDMIC_DSPR0_SINBYP_EN 0x0
49#define PDMIC_DSPR0_SINBYP_MASK BIT(2)
50#define PDMIC_DSPR0_SINBYP_SHIFT (2)
51
52#define PDMIC_DSPR0_SIZE_16_BITS 0x0
53#define PDMIC_DSPR0_SIZE_32_BITS 0x1
54#define PDMIC_DSPR0_SIZE_MASK BIT(3)
55#define PDMIC_DSPR0_SIZE_SHIFT (3)
56
57#define PDMIC_DSPR0_OSR_128 0x0
58#define PDMIC_DSPR0_OSR_64 0x1
59#define PDMIC_DSPR0_OSR_MASK GENMASK(6, 4)
60#define PDMIC_DSPR0_OSR_SHIFT (4)
61
62#define PDMIC_DSPR0_SCALE_MASK GENMASK(11, 8)
63#define PDMIC_DSPR0_SCALE_SHIFT (8)
64
65#define PDMIC_DSPR0_SHIFT_MASK GENMASK(15, 12)
66#define PDMIC_DSPR0_SHIFT_SHIFT (12)
67
68#define PDMIC_DSPR1 0x0000005c
69
70#define PDMIC_DSPR1_DGAIN_MASK GENMASK(14, 0)
71#define PDMIC_DSPR1_DGAIN_SHIFT (0)
72
73#define PDMIC_DSPR1_OFFSET_MASK GENMASK(31, 16)
74#define PDMIC_DSPR1_OFFSET_SHIFT (16)
75
76#define PDMIC_WPMR 0x000000e4
77
78#define PDMIC_WPSR 0x000000e8
79
80#endif
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
index 1933bcd46cca..fdd28ed3e0b9 100644
--- a/sound/soc/atmel/atmel_wm8904.c
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -183,6 +183,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = {
183 .driver = { 183 .driver = {
184 .name = "atmel-wm8904-audio", 184 .name = "atmel-wm8904-audio",
185 .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids), 185 .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids),
186 .pm = &snd_soc_pm_ops,
186 }, 187 },
187 .probe = atmel_asoc_wm8904_probe, 188 .probe = atmel_asoc_wm8904_probe,
188 .remove = atmel_asoc_wm8904_remove, 189 .remove = atmel_asoc_wm8904_remove,
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cfdafc4c11ea..629ee56a22ce 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -55,9 +55,11 @@ config SND_SOC_ALL_CODECS
55 select SND_SOC_CS4271_SPI if SPI_MASTER 55 select SND_SOC_CS4271_SPI if SPI_MASTER
56 select SND_SOC_CS42XX8_I2C if I2C 56 select SND_SOC_CS42XX8_I2C if I2C
57 select SND_SOC_CS4349 if I2C 57 select SND_SOC_CS4349 if I2C
58 select SND_SOC_CS47L24 if MFD_CS47L24
58 select SND_SOC_CX20442 if TTY 59 select SND_SOC_CX20442 if TTY
59 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 60 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
60 select SND_SOC_DA7213 if I2C 61 select SND_SOC_DA7213 if I2C
62 select SND_SOC_DA7218 if I2C
61 select SND_SOC_DA7219 if I2C 63 select SND_SOC_DA7219 if I2C
62 select SND_SOC_DA732X if I2C 64 select SND_SOC_DA732X if I2C
63 select SND_SOC_DA9055 if I2C 65 select SND_SOC_DA9055 if I2C
@@ -66,7 +68,9 @@ config SND_SOC_ALL_CODECS
66 select SND_SOC_ES8328_SPI if SPI_MASTER 68 select SND_SOC_ES8328_SPI if SPI_MASTER
67 select SND_SOC_ES8328_I2C if I2C 69 select SND_SOC_ES8328_I2C if I2C
68 select SND_SOC_GTM601 70 select SND_SOC_GTM601
71 select SND_SOC_HDAC_HDMI
69 select SND_SOC_ICS43432 72 select SND_SOC_ICS43432
73 select SND_SOC_INNO_RK3036
70 select SND_SOC_ISABELLE if I2C 74 select SND_SOC_ISABELLE if I2C
71 select SND_SOC_JZ4740_CODEC 75 select SND_SOC_JZ4740_CODEC
72 select SND_SOC_LM4857 if I2C 76 select SND_SOC_LM4857 if I2C
@@ -85,14 +89,18 @@ config SND_SOC_ALL_CODECS
85 select SND_SOC_PCM1681 if I2C 89 select SND_SOC_PCM1681 if I2C
86 select SND_SOC_PCM1792A if SPI_MASTER 90 select SND_SOC_PCM1792A if SPI_MASTER
87 select SND_SOC_PCM3008 91 select SND_SOC_PCM3008
92 select SND_SOC_PCM3168A_I2C if I2C
93 select SND_SOC_PCM3168A_SPI if SPI_MASTER
88 select SND_SOC_PCM512x_I2C if I2C 94 select SND_SOC_PCM512x_I2C if I2C
89 select SND_SOC_PCM512x_SPI if SPI_MASTER 95 select SND_SOC_PCM512x_SPI if SPI_MASTER
90 select SND_SOC_RT286 if I2C 96 select SND_SOC_RT286 if I2C
91 select SND_SOC_RT298 if I2C 97 select SND_SOC_RT298 if I2C
98 select SND_SOC_RT5616 if I2C
92 select SND_SOC_RT5631 if I2C 99 select SND_SOC_RT5631 if I2C
93 select SND_SOC_RT5640 if I2C 100 select SND_SOC_RT5640 if I2C
94 select SND_SOC_RT5645 if I2C 101 select SND_SOC_RT5645 if I2C
95 select SND_SOC_RT5651 if I2C 102 select SND_SOC_RT5651 if I2C
103 select SND_SOC_RT5659 if I2C
96 select SND_SOC_RT5670 if I2C 104 select SND_SOC_RT5670 if I2C
97 select SND_SOC_RT5677 if I2C && SPI_MASTER 105 select SND_SOC_RT5677 if I2C && SPI_MASTER
98 select SND_SOC_SGTL5000 if I2C 106 select SND_SOC_SGTL5000 if I2C
@@ -195,10 +203,12 @@ config SND_SOC_88PM860X
195 203
196config SND_SOC_ARIZONA 204config SND_SOC_ARIZONA
197 tristate 205 tristate
206 default y if SND_SOC_CS47L24=y
198 default y if SND_SOC_WM5102=y 207 default y if SND_SOC_WM5102=y
199 default y if SND_SOC_WM5110=y 208 default y if SND_SOC_WM5110=y
200 default y if SND_SOC_WM8997=y 209 default y if SND_SOC_WM8997=y
201 default y if SND_SOC_WM8998=y 210 default y if SND_SOC_WM8998=y
211 default m if SND_SOC_CS47L24=m
202 default m if SND_SOC_WM5102=m 212 default m if SND_SOC_WM5102=m
203 default m if SND_SOC_WM5110=m 213 default m if SND_SOC_WM5110=m
204 default m if SND_SOC_WM8997=m 214 default m if SND_SOC_WM8997=m
@@ -211,9 +221,12 @@ config SND_SOC_WM_HUBS
211 221
212config SND_SOC_WM_ADSP 222config SND_SOC_WM_ADSP
213 tristate 223 tristate
224 select SND_SOC_COMPRESS
225 default y if SND_SOC_CS47L24=y
214 default y if SND_SOC_WM5102=y 226 default y if SND_SOC_WM5102=y
215 default y if SND_SOC_WM5110=y 227 default y if SND_SOC_WM5110=y
216 default y if SND_SOC_WM2200=y 228 default y if SND_SOC_WM2200=y
229 default m if SND_SOC_CS47L24=m
217 default m if SND_SOC_WM5102=m 230 default m if SND_SOC_WM5102=m
218 default m if SND_SOC_WM5110=m 231 default m if SND_SOC_WM5110=m
219 default m if SND_SOC_WM2200=m 232 default m if SND_SOC_WM2200=m
@@ -422,6 +435,9 @@ config SND_SOC_CS4349
422 tristate "Cirrus Logic CS4349 CODEC" 435 tristate "Cirrus Logic CS4349 CODEC"
423 depends on I2C 436 depends on I2C
424 437
438config SND_SOC_CS47L24
439 tristate
440
425config SND_SOC_CX20442 441config SND_SOC_CX20442
426 tristate 442 tristate
427 depends on TTY 443 depends on TTY
@@ -439,6 +455,9 @@ config SND_SOC_DA7210
439config SND_SOC_DA7213 455config SND_SOC_DA7213
440 tristate 456 tristate
441 457
458config SND_SOC_DA7218
459 tristate
460
442config SND_SOC_DA7219 461config SND_SOC_DA7219
443 tristate 462 tristate
444 463
@@ -468,9 +487,17 @@ config SND_SOC_ES8328_SPI
468config SND_SOC_GTM601 487config SND_SOC_GTM601
469 tristate 'GTM601 UMTS modem audio codec' 488 tristate 'GTM601 UMTS modem audio codec'
470 489
490config SND_SOC_HDAC_HDMI
491 tristate
492 select SND_HDA_EXT_CORE
493 select HDMI
494
471config SND_SOC_ICS43432 495config SND_SOC_ICS43432
472 tristate 496 tristate
473 497
498config SND_SOC_INNO_RK3036
499 tristate "Inno codec driver for RK3036 SoC"
500
474config SND_SOC_ISABELLE 501config SND_SOC_ISABELLE
475 tristate 502 tristate
476 503
@@ -506,6 +533,21 @@ config SND_SOC_PCM1792A
506config SND_SOC_PCM3008 533config SND_SOC_PCM3008
507 tristate 534 tristate
508 535
536config SND_SOC_PCM3168A
537 tristate
538
539config SND_SOC_PCM3168A_I2C
540 tristate "Texas Instruments PCM3168A CODEC - I2C"
541 depends on I2C
542 select SND_SOC_PCM3168A
543 select REGMAP_I2C
544
545config SND_SOC_PCM3168A_SPI
546 tristate "Texas Instruments PCM3168A CODEC - SPI"
547 depends on SPI_MASTER
548 select SND_SOC_PCM3168A
549 select REGMAP_SPI
550
509config SND_SOC_PCM512x 551config SND_SOC_PCM512x
510 tristate 552 tristate
511 553
@@ -523,14 +565,18 @@ config SND_SOC_PCM512x_SPI
523 565
524config SND_SOC_RL6231 566config SND_SOC_RL6231
525 tristate 567 tristate
568 default y if SND_SOC_RT5616=y
526 default y if SND_SOC_RT5640=y 569 default y if SND_SOC_RT5640=y
527 default y if SND_SOC_RT5645=y 570 default y if SND_SOC_RT5645=y
528 default y if SND_SOC_RT5651=y 571 default y if SND_SOC_RT5651=y
572 default y if SND_SOC_RT5659=y
529 default y if SND_SOC_RT5670=y 573 default y if SND_SOC_RT5670=y
530 default y if SND_SOC_RT5677=y 574 default y if SND_SOC_RT5677=y
575 default m if SND_SOC_RT5616=m
531 default m if SND_SOC_RT5640=m 576 default m if SND_SOC_RT5640=m
532 default m if SND_SOC_RT5645=m 577 default m if SND_SOC_RT5645=m
533 default m if SND_SOC_RT5651=m 578 default m if SND_SOC_RT5651=m
579 default m if SND_SOC_RT5659=m
534 default m if SND_SOC_RT5670=m 580 default m if SND_SOC_RT5670=m
535 default m if SND_SOC_RT5677=m 581 default m if SND_SOC_RT5677=m
536 582
@@ -549,6 +595,9 @@ config SND_SOC_RT298
549 tristate 595 tristate
550 depends on I2C 596 depends on I2C
551 597
598config SND_SOC_RT5616
599 tristate
600
552config SND_SOC_RT5631 601config SND_SOC_RT5631
553 tristate "Realtek ALC5631/RT5631 CODEC" 602 tristate "Realtek ALC5631/RT5631 CODEC"
554 depends on I2C 603 depends on I2C
@@ -562,6 +611,9 @@ config SND_SOC_RT5645
562config SND_SOC_RT5651 611config SND_SOC_RT5651
563 tristate 612 tristate
564 613
614config SND_SOC_RT5659
615 tristate
616
565config SND_SOC_RT5670 617config SND_SOC_RT5670
566 tristate 618 tristate
567 619
@@ -838,7 +890,8 @@ config SND_SOC_WM8971
838 tristate 890 tristate
839 891
840config SND_SOC_WM8974 892config SND_SOC_WM8974
841 tristate 893 tristate "Wolfson Microelectronics WM8974 codec"
894 depends on I2C
842 895
843config SND_SOC_WM8978 896config SND_SOC_WM8978
844 tristate "Wolfson Microelectronics WM8978 codec" 897 tristate "Wolfson Microelectronics WM8978 codec"
@@ -891,6 +944,7 @@ config SND_SOC_WM9712
891 944
892config SND_SOC_WM9713 945config SND_SOC_WM9713
893 tristate 946 tristate
947 select REGMAP_AC97
894 948
895# Amp 949# Amp
896config SND_SOC_LM4857 950config SND_SOC_LM4857
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f632fc42f59f..fb846e2ad33b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -47,9 +47,11 @@ snd-soc-cs4271-spi-objs := cs4271-spi.o
47snd-soc-cs42xx8-objs := cs42xx8.o 47snd-soc-cs42xx8-objs := cs42xx8.o
48snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 48snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
49snd-soc-cs4349-objs := cs4349.o 49snd-soc-cs4349-objs := cs4349.o
50snd-soc-cs47l24-objs := cs47l24.o
50snd-soc-cx20442-objs := cx20442.o 51snd-soc-cx20442-objs := cx20442.o
51snd-soc-da7210-objs := da7210.o 52snd-soc-da7210-objs := da7210.o
52snd-soc-da7213-objs := da7213.o 53snd-soc-da7213-objs := da7213.o
54snd-soc-da7218-objs := da7218.o
53snd-soc-da7219-objs := da7219.o da7219-aad.o 55snd-soc-da7219-objs := da7219.o da7219-aad.o
54snd-soc-da732x-objs := da732x.o 56snd-soc-da732x-objs := da732x.o
55snd-soc-da9055-objs := da9055.o 57snd-soc-da9055-objs := da9055.o
@@ -59,7 +61,9 @@ snd-soc-es8328-objs := es8328.o
59snd-soc-es8328-i2c-objs := es8328-i2c.o 61snd-soc-es8328-i2c-objs := es8328-i2c.o
60snd-soc-es8328-spi-objs := es8328-spi.o 62snd-soc-es8328-spi-objs := es8328-spi.o
61snd-soc-gtm601-objs := gtm601.o 63snd-soc-gtm601-objs := gtm601.o
64snd-soc-hdac-hdmi-objs := hdac_hdmi.o
62snd-soc-ics43432-objs := ics43432.o 65snd-soc-ics43432-objs := ics43432.o
66snd-soc-inno-rk3036-objs := inno_rk3036.o
63snd-soc-isabelle-objs := isabelle.o 67snd-soc-isabelle-objs := isabelle.o
64snd-soc-jz4740-codec-objs := jz4740.o 68snd-soc-jz4740-codec-objs := jz4740.o
65snd-soc-l3-objs := l3.o 69snd-soc-l3-objs := l3.o
@@ -78,6 +82,9 @@ snd-soc-nau8825-objs := nau8825.o
78snd-soc-pcm1681-objs := pcm1681.o 82snd-soc-pcm1681-objs := pcm1681.o
79snd-soc-pcm1792a-codec-objs := pcm1792a.o 83snd-soc-pcm1792a-codec-objs := pcm1792a.o
80snd-soc-pcm3008-objs := pcm3008.o 84snd-soc-pcm3008-objs := pcm3008.o
85snd-soc-pcm3168a-objs := pcm3168a.o
86snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o
87snd-soc-pcm3168a-spi-objs := pcm3168a-spi.o
81snd-soc-pcm512x-objs := pcm512x.o 88snd-soc-pcm512x-objs := pcm512x.o
82snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 89snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
83snd-soc-pcm512x-spi-objs := pcm512x-spi.o 90snd-soc-pcm512x-spi-objs := pcm512x-spi.o
@@ -85,10 +92,12 @@ snd-soc-rl6231-objs := rl6231.o
85snd-soc-rl6347a-objs := rl6347a.o 92snd-soc-rl6347a-objs := rl6347a.o
86snd-soc-rt286-objs := rt286.o 93snd-soc-rt286-objs := rt286.o
87snd-soc-rt298-objs := rt298.o 94snd-soc-rt298-objs := rt298.o
95snd-soc-rt5616-objs := rt5616.o
88snd-soc-rt5631-objs := rt5631.o 96snd-soc-rt5631-objs := rt5631.o
89snd-soc-rt5640-objs := rt5640.o 97snd-soc-rt5640-objs := rt5640.o
90snd-soc-rt5645-objs := rt5645.o 98snd-soc-rt5645-objs := rt5645.o
91snd-soc-rt5651-objs := rt5651.o 99snd-soc-rt5651-objs := rt5651.o
100snd-soc-rt5659-objs := rt5659.o
92snd-soc-rt5670-objs := rt5670.o 101snd-soc-rt5670-objs := rt5670.o
93snd-soc-rt5677-objs := rt5677.o 102snd-soc-rt5677-objs := rt5677.o
94snd-soc-rt5677-spi-objs := rt5677-spi.o 103snd-soc-rt5677-spi-objs := rt5677-spi.o
@@ -242,9 +251,11 @@ obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o
242obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o 251obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
243obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 252obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
244obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o 253obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
254obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
245obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 255obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
246obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 256obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
247obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 257obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
258obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o
248obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o 259obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
249obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 260obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
250obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 261obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
@@ -254,7 +265,9 @@ obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
254obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o 265obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
255obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o 266obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
256obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o 267obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o
268obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
257obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o 269obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
270obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
258obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o 271obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
259obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 272obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
260obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 273obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -273,6 +286,9 @@ obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
273obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 286obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
274obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o 287obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
275obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 288obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
289obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o
290obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o
291obj-$(CONFIG_SND_SOC_PCM3168A_SPI) += snd-soc-pcm3168a-spi.o
276obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o 292obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
277obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 293obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
278obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 294obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
@@ -280,10 +296,12 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
280obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o 296obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
281obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 297obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
282obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 298obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
299obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
283obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 300obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
284obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 301obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
285obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o 302obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
286obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o 303obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
304obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
287obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o 305obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
288obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o 306obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
289obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o 307obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 07a266460ec3..647f69de6baa 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -70,18 +70,11 @@
70#define FMT_MASK (0xf8) 70#define FMT_MASK (0xf8)
71 71
72/* CTRL2 */ 72/* CTRL2 */
73#define DFS_MASK (3 << 2)
73#define DFS_NORMAL_SPEED (0 << 2) 74#define DFS_NORMAL_SPEED (0 << 2)
74#define DFS_DOUBLE_SPEED (1 << 2) 75#define DFS_DOUBLE_SPEED (1 << 2)
75#define DFS_QUAD_SPEED (2 << 2) 76#define DFS_QUAD_SPEED (2 << 2)
76 77
77struct ak4613_priv {
78 struct mutex lock;
79
80 unsigned int fmt;
81 u8 fmt_ctrl;
82 int cnt;
83};
84
85struct ak4613_formats { 78struct ak4613_formats {
86 unsigned int width; 79 unsigned int width;
87 unsigned int fmt; 80 unsigned int fmt;
@@ -92,6 +85,16 @@ struct ak4613_interface {
92 struct ak4613_formats playback; 85 struct ak4613_formats playback;
93}; 86};
94 87
88struct ak4613_priv {
89 struct mutex lock;
90 const struct ak4613_interface *iface;
91
92 unsigned int fmt;
93 u8 oc;
94 u8 ic;
95 int cnt;
96};
97
95/* 98/*
96 * Playback Volume 99 * Playback Volume
97 * 100 *
@@ -126,7 +129,7 @@ static const struct reg_default ak4613_reg[] = {
126 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 }, 129 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 },
127}; 130};
128 131
129#define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3) 132#define AUDIO_IFACE_TO_VAL(fmts) ((fmts - ak4613_iface) << 3)
130#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt } 133#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt }
131static const struct ak4613_interface ak4613_iface[] = { 134static const struct ak4613_interface ak4613_iface[] = {
132 /* capture */ /* playback */ 135 /* capture */ /* playback */
@@ -240,7 +243,7 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
240 priv->cnt = 0; 243 priv->cnt = 0;
241 } 244 }
242 if (!priv->cnt) 245 if (!priv->cnt)
243 priv->fmt_ctrl = NO_FMT; 246 priv->iface = NULL;
244 mutex_unlock(&priv->lock); 247 mutex_unlock(&priv->lock);
245} 248}
246 249
@@ -265,13 +268,35 @@ static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
265 return 0; 268 return 0;
266} 269}
267 270
271static bool ak4613_dai_fmt_matching(const struct ak4613_interface *iface,
272 int is_play,
273 unsigned int fmt, unsigned int width)
274{
275 const struct ak4613_formats *fmts;
276
277 fmts = (is_play) ? &iface->playback : &iface->capture;
278
279 if (fmts->fmt != fmt)
280 return false;
281
282 if (fmt == SND_SOC_DAIFMT_RIGHT_J) {
283 if (fmts->width != width)
284 return false;
285 } else {
286 if (fmts->width < width)
287 return false;
288 }
289
290 return true;
291}
292
268static int ak4613_dai_hw_params(struct snd_pcm_substream *substream, 293static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
269 struct snd_pcm_hw_params *params, 294 struct snd_pcm_hw_params *params,
270 struct snd_soc_dai *dai) 295 struct snd_soc_dai *dai)
271{ 296{
272 struct snd_soc_codec *codec = dai->codec; 297 struct snd_soc_codec *codec = dai->codec;
273 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec); 298 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
274 const struct ak4613_formats *fmts; 299 const struct ak4613_interface *iface;
275 struct device *dev = codec->dev; 300 struct device *dev = codec->dev;
276 unsigned int width = params_width(params); 301 unsigned int width = params_width(params);
277 unsigned int fmt = priv->fmt; 302 unsigned int fmt = priv->fmt;
@@ -305,33 +330,27 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
305 * It doesn't support TDM at this point 330 * It doesn't support TDM at this point
306 */ 331 */
307 fmt_ctrl = NO_FMT; 332 fmt_ctrl = NO_FMT;
308 for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) { 333 ret = -EINVAL;
309 fmts = (is_play) ? &ak4613_iface[i].playback : 334 iface = NULL;
310 &ak4613_iface[i].capture;
311
312 if (fmts->fmt != fmt)
313 continue;
314 335
315 if (fmt == SND_SOC_DAIFMT_RIGHT_J) { 336 mutex_lock(&priv->lock);
316 if (fmts->width != width) 337 if (priv->iface) {
317 continue; 338 if (ak4613_dai_fmt_matching(priv->iface, is_play, fmt, width))
318 } else { 339 iface = priv->iface;
319 if (fmts->width < width) 340 } else {
341 for (i = ARRAY_SIZE(ak4613_iface); i >= 0; i--) {
342 if (!ak4613_dai_fmt_matching(ak4613_iface + i,
343 is_play,
344 fmt, width))
320 continue; 345 continue;
346 iface = ak4613_iface + i;
347 break;
321 } 348 }
322
323 fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i);
324 break;
325 } 349 }
326 350
327 ret = -EINVAL; 351 if ((priv->iface == NULL) ||
328 if (fmt_ctrl == NO_FMT) 352 (priv->iface == iface)) {
329 goto hw_params_end; 353 priv->iface = iface;
330
331 mutex_lock(&priv->lock);
332 if ((priv->fmt_ctrl == NO_FMT) ||
333 (priv->fmt_ctrl == fmt_ctrl)) {
334 priv->fmt_ctrl = fmt_ctrl;
335 priv->cnt++; 354 priv->cnt++;
336 ret = 0; 355 ret = 0;
337 } 356 }
@@ -340,8 +359,13 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
340 if (ret < 0) 359 if (ret < 0)
341 goto hw_params_end; 360 goto hw_params_end;
342 361
362 fmt_ctrl = AUDIO_IFACE_TO_VAL(iface);
363
343 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); 364 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
344 snd_soc_write(codec, CTRL2, ctrl2); 365 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
366
367 snd_soc_write(codec, ICTRL, priv->ic);
368 snd_soc_write(codec, OCTRL, priv->oc);
345 369
346hw_params_end: 370hw_params_end:
347 if (ret < 0) 371 if (ret < 0)
@@ -431,6 +455,28 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
431 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), 455 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon),
432}; 456};
433 457
458static void ak4613_parse_of(struct ak4613_priv *priv,
459 struct device *dev)
460{
461 struct device_node *np = dev->of_node;
462 char prop[32];
463 int i;
464
465 /* Input 1 - 2 */
466 for (i = 0; i < 2; i++) {
467 snprintf(prop, sizeof(prop), "asahi-kasei,in%d-single-end", i + 1);
468 if (!of_get_property(np, prop, NULL))
469 priv->ic |= 1 << i;
470 }
471
472 /* Output 1 - 6 */
473 for (i = 0; i < 6; i++) {
474 snprintf(prop, sizeof(prop), "asahi-kasei,out%d-single-end", i + 1);
475 if (!of_get_property(np, prop, NULL))
476 priv->oc |= 1 << i;
477 }
478}
479
434static int ak4613_i2c_probe(struct i2c_client *i2c, 480static int ak4613_i2c_probe(struct i2c_client *i2c,
435 const struct i2c_device_id *id) 481 const struct i2c_device_id *id)
436{ 482{
@@ -458,7 +504,9 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
458 if (!priv) 504 if (!priv)
459 return -ENOMEM; 505 return -ENOMEM;
460 506
461 priv->fmt_ctrl = NO_FMT; 507 ak4613_parse_of(priv, dev);
508
509 priv->iface = NULL;
462 priv->cnt = 0; 510 priv->cnt = 0;
463 511
464 mutex_init(&priv->lock); 512 mutex_init(&priv->lock);
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index b3ea24d64c50..38a73e3da508 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -310,7 +310,7 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
310} 310}
311EXPORT_SYMBOL_GPL(arizona_init_gpio); 311EXPORT_SYMBOL_GPL(arizona_init_gpio);
312 312
313const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 313const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
314 "None", 314 "None",
315 "Tone Generator 1", 315 "Tone Generator 1",
316 "Tone Generator 2", 316 "Tone Generator 2",
@@ -418,7 +418,7 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
418}; 418};
419EXPORT_SYMBOL_GPL(arizona_mixer_texts); 419EXPORT_SYMBOL_GPL(arizona_mixer_texts);
420 420
421int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 421unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
422 0x00, /* None */ 422 0x00, /* None */
423 0x04, /* Tone */ 423 0x04, /* Tone */
424 0x05, 424 0x05,
@@ -555,12 +555,12 @@ const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
555} 555}
556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name); 556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
557 557
558const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 558const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
560}; 560};
561EXPORT_SYMBOL_GPL(arizona_rate_text); 561EXPORT_SYMBOL_GPL(arizona_rate_text);
562 562
563const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { 563const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = {
564 0, 1, 2, 8, 564 0, 1, 2, 8,
565}; 565};
566EXPORT_SYMBOL_GPL(arizona_rate_val); 566EXPORT_SYMBOL_GPL(arizona_rate_val);
@@ -702,6 +702,100 @@ const struct soc_enum arizona_in_dmic_osr[] = {
702}; 702};
703EXPORT_SYMBOL_GPL(arizona_in_dmic_osr); 703EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
704 704
705static const char * const arizona_anc_input_src_text[] = {
706 "None", "IN1", "IN2", "IN3", "IN4",
707};
708
709static const char * const arizona_anc_channel_src_text[] = {
710 "None", "Left", "Right", "Combine",
711};
712
713const struct soc_enum arizona_anc_input_src[] = {
714 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
715 ARIZONA_IN_RXANCL_SEL_SHIFT,
716 ARRAY_SIZE(arizona_anc_input_src_text),
717 arizona_anc_input_src_text),
718 SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
719 ARIZONA_FCL_MIC_MODE_SEL,
720 ARRAY_SIZE(arizona_anc_channel_src_text),
721 arizona_anc_channel_src_text),
722 SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
723 ARIZONA_IN_RXANCR_SEL_SHIFT,
724 ARRAY_SIZE(arizona_anc_input_src_text),
725 arizona_anc_input_src_text),
726 SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
727 ARIZONA_FCR_MIC_MODE_SEL,
728 ARRAY_SIZE(arizona_anc_channel_src_text),
729 arizona_anc_channel_src_text),
730};
731EXPORT_SYMBOL_GPL(arizona_anc_input_src);
732
733static const char * const arizona_anc_ng_texts[] = {
734 "None",
735 "Internal",
736 "External",
737};
738
739SOC_ENUM_SINGLE_DECL(arizona_anc_ng_enum, SND_SOC_NOPM, 0,
740 arizona_anc_ng_texts);
741EXPORT_SYMBOL_GPL(arizona_anc_ng_enum);
742
743static const char * const arizona_output_anc_src_text[] = {
744 "None", "RXANCL", "RXANCR",
745};
746
747const struct soc_enum arizona_output_anc_src[] = {
748 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
749 ARIZONA_OUT1L_ANC_SRC_SHIFT,
750 ARRAY_SIZE(arizona_output_anc_src_text),
751 arizona_output_anc_src_text),
752 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1R,
753 ARIZONA_OUT1R_ANC_SRC_SHIFT,
754 ARRAY_SIZE(arizona_output_anc_src_text),
755 arizona_output_anc_src_text),
756 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L,
757 ARIZONA_OUT2L_ANC_SRC_SHIFT,
758 ARRAY_SIZE(arizona_output_anc_src_text),
759 arizona_output_anc_src_text),
760 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2R,
761 ARIZONA_OUT2R_ANC_SRC_SHIFT,
762 ARRAY_SIZE(arizona_output_anc_src_text),
763 arizona_output_anc_src_text),
764 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
765 ARIZONA_OUT3L_ANC_SRC_SHIFT,
766 ARRAY_SIZE(arizona_output_anc_src_text),
767 arizona_output_anc_src_text),
768 SOC_ENUM_SINGLE(ARIZONA_DAC_VOLUME_LIMIT_3R,
769 ARIZONA_OUT3R_ANC_SRC_SHIFT,
770 ARRAY_SIZE(arizona_output_anc_src_text),
771 arizona_output_anc_src_text),
772 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4L,
773 ARIZONA_OUT4L_ANC_SRC_SHIFT,
774 ARRAY_SIZE(arizona_output_anc_src_text),
775 arizona_output_anc_src_text),
776 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_4R,
777 ARIZONA_OUT4R_ANC_SRC_SHIFT,
778 ARRAY_SIZE(arizona_output_anc_src_text),
779 arizona_output_anc_src_text),
780 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5L,
781 ARIZONA_OUT5L_ANC_SRC_SHIFT,
782 ARRAY_SIZE(arizona_output_anc_src_text),
783 arizona_output_anc_src_text),
784 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_5R,
785 ARIZONA_OUT5R_ANC_SRC_SHIFT,
786 ARRAY_SIZE(arizona_output_anc_src_text),
787 arizona_output_anc_src_text),
788 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6L,
789 ARIZONA_OUT6L_ANC_SRC_SHIFT,
790 ARRAY_SIZE(arizona_output_anc_src_text),
791 arizona_output_anc_src_text),
792 SOC_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_6R,
793 ARIZONA_OUT6R_ANC_SRC_SHIFT,
794 ARRAY_SIZE(arizona_output_anc_src_text),
795 arizona_output_anc_src_text),
796};
797EXPORT_SYMBOL_GPL(arizona_output_anc_src);
798
705static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 799static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
706{ 800{
707 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 801 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
@@ -1023,6 +1117,31 @@ void arizona_init_dvfs(struct arizona_priv *priv)
1023} 1117}
1024EXPORT_SYMBOL_GPL(arizona_init_dvfs); 1118EXPORT_SYMBOL_GPL(arizona_init_dvfs);
1025 1119
1120int arizona_anc_ev(struct snd_soc_dapm_widget *w,
1121 struct snd_kcontrol *kcontrol,
1122 int event)
1123{
1124 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1125 unsigned int mask = 0x3 << w->shift;
1126 unsigned int val;
1127
1128 switch (event) {
1129 case SND_SOC_DAPM_POST_PMU:
1130 val = 1 << w->shift;
1131 break;
1132 case SND_SOC_DAPM_PRE_PMD:
1133 val = 1 << (w->shift + 1);
1134 break;
1135 default:
1136 return 0;
1137 }
1138
1139 snd_soc_update_bits(codec, ARIZONA_CLOCK_CONTROL, mask, val);
1140
1141 return 0;
1142}
1143EXPORT_SYMBOL_GPL(arizona_anc_ev);
1144
1026static unsigned int arizona_opclk_ref_48k_rates[] = { 1145static unsigned int arizona_opclk_ref_48k_rates[] = {
1027 6144000, 1146 6144000,
1028 12288000, 1147 12288000,
@@ -1095,7 +1214,7 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1095 unsigned int reg; 1214 unsigned int reg;
1096 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK; 1215 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
1097 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT; 1216 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
1098 unsigned int *clk; 1217 int *clk;
1099 1218
1100 switch (clk_id) { 1219 switch (clk_id) {
1101 case ARIZONA_CLK_SYSCLK: 1220 case ARIZONA_CLK_SYSCLK:
@@ -1901,18 +2020,18 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
1901 } 2020 }
1902 2021
1903 switch (fll->arizona->type) { 2022 switch (fll->arizona->type) {
2023 case WM5102:
2024 case WM8997:
2025 return init_ratio;
1904 case WM5110: 2026 case WM5110:
1905 case WM8280: 2027 case WM8280:
1906 if (fll->arizona->rev < 3 || sync) 2028 if (fll->arizona->rev < 3 || sync)
1907 return init_ratio; 2029 return init_ratio;
1908 break; 2030 break;
1909 case WM8998: 2031 default:
1910 case WM1814:
1911 if (sync) 2032 if (sync)
1912 return init_ratio; 2033 return init_ratio;
1913 break; 2034 break;
1914 default:
1915 return init_ratio;
1916 } 2035 }
1917 2036
1918 cfg->fratio = init_ratio - 1; 2037 cfg->fratio = init_ratio - 1;
@@ -2093,9 +2212,9 @@ static int arizona_enable_fll(struct arizona_fll *fll)
2093 /* Facilitate smooth refclk across the transition */ 2212 /* Facilitate smooth refclk across the transition */
2094 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9, 2213 regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x9,
2095 ARIZONA_FLL1_GAIN_MASK, 0); 2214 ARIZONA_FLL1_GAIN_MASK, 0);
2096 regmap_update_bits_async(fll->arizona->regmap, fll->base + 1, 2215 regmap_update_bits(fll->arizona->regmap, fll->base + 1,
2097 ARIZONA_FLL1_FREERUN, 2216 ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN);
2098 ARIZONA_FLL1_FREERUN); 2217 udelay(32);
2099 } 2218 }
2100 2219
2101 /* 2220 /*
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index fea8b8ae8e1a..8b6adb5419bb 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -57,7 +57,7 @@
57#define ARIZONA_CLK_98MHZ 5 57#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 6 58#define ARIZONA_CLK_147MHZ 6
59 59
60#define ARIZONA_MAX_DAI 6 60#define ARIZONA_MAX_DAI 8
61#define ARIZONA_MAX_ADSP 4 61#define ARIZONA_MAX_ADSP 4
62 62
63#define ARIZONA_DVFS_SR1_RQ 0x001 63#define ARIZONA_DVFS_SR1_RQ 0x001
@@ -96,8 +96,8 @@ struct arizona_priv {
96#define ARIZONA_NUM_MIXER_INPUTS 104 96#define ARIZONA_NUM_MIXER_INPUTS 104
97 97
98extern const unsigned int arizona_mixer_tlv[]; 98extern const unsigned int arizona_mixer_tlv[];
99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; 99extern const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; 100extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
101 101
102#define ARIZONA_GAINMUX_CONTROLS(name, base) \ 102#define ARIZONA_GAINMUX_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \ 103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
@@ -216,8 +216,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
216#define ARIZONA_RATE_ENUM_SIZE 4 216#define ARIZONA_RATE_ENUM_SIZE 4
217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14 217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14
218 218
219extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; 219extern const char * const arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
220extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; 220extern const unsigned int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; 221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE]; 222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
223 223
@@ -242,6 +242,10 @@ extern const struct soc_enum arizona_in_dmic_osr[];
242 242
243extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[]; 243extern const struct snd_kcontrol_new arizona_adsp2_rate_controls[];
244 244
245extern const struct soc_enum arizona_anc_input_src[];
246extern const struct soc_enum arizona_anc_ng_enum;
247extern const struct soc_enum arizona_output_anc_src[];
248
245extern int arizona_in_ev(struct snd_soc_dapm_widget *w, 249extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
246 struct snd_kcontrol *kcontrol, 250 struct snd_kcontrol *kcontrol,
247 int event); 251 int event);
@@ -251,6 +255,9 @@ extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
251extern int arizona_hp_ev(struct snd_soc_dapm_widget *w, 255extern int arizona_hp_ev(struct snd_soc_dapm_widget *w,
252 struct snd_kcontrol *kcontrol, 256 struct snd_kcontrol *kcontrol,
253 int event); 257 int event);
258extern int arizona_anc_ev(struct snd_soc_dapm_widget *w,
259 struct snd_kcontrol *kcontrol,
260 int event);
254 261
255extern int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol, 262extern int arizona_eq_coeff_put(struct snd_kcontrol *kcontrol,
256 struct snd_ctl_elem_value *ucontrol); 263 struct snd_ctl_elem_value *ucontrol);
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
new file mode 100644
index 000000000000..dc5ae7f7a1bd
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.c
@@ -0,0 +1,1148 @@
1/*
2 * cs47l24.h -- ALSA SoC Audio driver for Cirrus Logic CS47L24
3 *
4 * Copyright 2015 Cirrus Logic Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
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 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm_adsp.h"
34#include "cs47l24.h"
35
36struct cs47l24_priv {
37 struct arizona_priv core;
38 struct arizona_fll fll[2];
39};
40
41static const struct wm_adsp_region cs47l24_dsp2_regions[] = {
42 { .type = WMFW_ADSP2_PM, .base = 0x200000 },
43 { .type = WMFW_ADSP2_ZM, .base = 0x280000 },
44 { .type = WMFW_ADSP2_XM, .base = 0x290000 },
45 { .type = WMFW_ADSP2_YM, .base = 0x2a8000 },
46};
47
48static const struct wm_adsp_region cs47l24_dsp3_regions[] = {
49 { .type = WMFW_ADSP2_PM, .base = 0x300000 },
50 { .type = WMFW_ADSP2_ZM, .base = 0x380000 },
51 { .type = WMFW_ADSP2_XM, .base = 0x390000 },
52 { .type = WMFW_ADSP2_YM, .base = 0x3a8000 },
53};
54
55static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
56 cs47l24_dsp2_regions,
57 cs47l24_dsp3_regions,
58};
59
60static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
61static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
62static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
63static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
64
65#define CS47L24_NG_SRC(name, base) \
66 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
67 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
68 SOC_SINGLE(name " NG SPKOUT Switch", base, 6, 1, 0)
69
70static const struct snd_kcontrol_new cs47l24_snd_controls[] = {
71SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
72SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
73
74SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
75
76SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL,
77 ARIZONA_IN1L_HPF_SHIFT, 1, 0),
78SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL,
79 ARIZONA_IN1R_HPF_SHIFT, 1, 0),
80SOC_SINGLE("IN2L HPF Switch", ARIZONA_IN2L_CONTROL,
81 ARIZONA_IN2L_HPF_SHIFT, 1, 0),
82SOC_SINGLE("IN2R HPF Switch", ARIZONA_IN2R_CONTROL,
83 ARIZONA_IN2R_HPF_SHIFT, 1, 0),
84
85SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
86 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
87SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
88 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
89SOC_SINGLE_TLV("IN2L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
90 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
91SOC_SINGLE_TLV("IN2R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2R,
92 ARIZONA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
93
94SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
95SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
96
97ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
98ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
99
100ARIZONA_EQ_CONTROL("EQ1 Coefficients", ARIZONA_EQ1_2),
101SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
102 24, 0, eq_tlv),
103SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
104 24, 0, eq_tlv),
105SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
106 24, 0, eq_tlv),
107SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
110 24, 0, eq_tlv),
111
112ARIZONA_EQ_CONTROL("EQ2 Coefficients", ARIZONA_EQ2_2),
113SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
114 24, 0, eq_tlv),
115SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
116 24, 0, eq_tlv),
117SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
118 24, 0, eq_tlv),
119SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
120 24, 0, eq_tlv),
121SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
122 24, 0, eq_tlv),
123
124ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
125ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
126ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
127ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
128
129SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
130 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
131SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
132 ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
133
134ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
135ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
136ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
137ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
138
139ARIZONA_LHPF_CONTROL("LHPF1 Coefficients", ARIZONA_HPLPF1_2),
140ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2),
141ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2),
142ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2),
143
144SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
145SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
146SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
147SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
148
149SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
150SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
151SOC_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]),
152SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]),
153SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
154SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
155SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
156
157ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
158ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
159ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
160ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),
161
162SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
163 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
164
165ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
166ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
167ARIZONA_MIXER_CONTROLS("SPKOUT", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
168
169SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL,
170 ARIZONA_HP1_SC_ENA_SHIFT, 1, 0),
171
172SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
173 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
174SOC_SINGLE("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
175 ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
176
177SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
178 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
179 0xbf, 0, digital_tlv),
180SOC_SINGLE_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
181 ARIZONA_OUT4L_VOL_SHIFT,
182 0xbf, 0, digital_tlv),
183
184SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
185SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
186
187SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
188 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
189SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
190 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
191SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
192
193CS47L24_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L),
194CS47L24_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R),
195CS47L24_NG_SRC("SPKOUT", ARIZONA_NOISE_GATE_SELECT_4L),
196
197ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
198ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
199ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
200ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
201ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
202ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
203ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
204ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
205
206ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
207ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
208ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE),
209ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE),
210ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE),
211ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
212
213ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
214ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
215};
216
217ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
218ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
219
220ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
221ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
222ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
223ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
224
225ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
226ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
227ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
228ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
229
230ARIZONA_MIXER_ENUMS(DSP2L, ARIZONA_DSP2LMIX_INPUT_1_SOURCE);
231ARIZONA_MIXER_ENUMS(DSP2R, ARIZONA_DSP2RMIX_INPUT_1_SOURCE);
232ARIZONA_DSP_AUX_ENUMS(DSP2, ARIZONA_DSP2AUX1MIX_INPUT_1_SOURCE);
233
234ARIZONA_MIXER_ENUMS(DSP3L, ARIZONA_DSP3LMIX_INPUT_1_SOURCE);
235ARIZONA_MIXER_ENUMS(DSP3R, ARIZONA_DSP3RMIX_INPUT_1_SOURCE);
236ARIZONA_DSP_AUX_ENUMS(DSP3, ARIZONA_DSP3AUX1MIX_INPUT_1_SOURCE);
237
238ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
239ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
240
241ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
242ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
243ARIZONA_MIXER_ENUMS(SPKOUT, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
244
245ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
246ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
247ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
248ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
249ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
250ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
252ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
253
254ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
255ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
256ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE);
257ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE);
259ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE);
260
261ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
262ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
263
264ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
265ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
266ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
267ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
268
269ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
270ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
271ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE);
272ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE);
273
274ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
275ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
276ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE);
277ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE);
278
279ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
280ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
281ARIZONA_MUX_ENUMS(ISRC2INT3, ARIZONA_ISRC2INT3MIX_INPUT_1_SOURCE);
282ARIZONA_MUX_ENUMS(ISRC2INT4, ARIZONA_ISRC2INT4MIX_INPUT_1_SOURCE);
283
284ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
285ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
286ARIZONA_MUX_ENUMS(ISRC2DEC3, ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE);
287ARIZONA_MUX_ENUMS(ISRC2DEC4, ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE);
288
289ARIZONA_MUX_ENUMS(ISRC3INT1, ARIZONA_ISRC3INT1MIX_INPUT_1_SOURCE);
290ARIZONA_MUX_ENUMS(ISRC3INT2, ARIZONA_ISRC3INT2MIX_INPUT_1_SOURCE);
291ARIZONA_MUX_ENUMS(ISRC3INT3, ARIZONA_ISRC3INT3MIX_INPUT_1_SOURCE);
292ARIZONA_MUX_ENUMS(ISRC3INT4, ARIZONA_ISRC3INT4MIX_INPUT_1_SOURCE);
293
294ARIZONA_MUX_ENUMS(ISRC3DEC1, ARIZONA_ISRC3DEC1MIX_INPUT_1_SOURCE);
295ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE);
296ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE);
297ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE);
298
299static const char * const cs47l24_aec_loopback_texts[] = {
300 "HPOUT1L", "HPOUT1R", "SPKOUT",
301};
302
303static const unsigned int cs47l24_aec_loopback_values[] = {
304 0, 1, 6,
305};
306
307static const struct soc_enum cs47l24_aec_loopback =
308 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
309 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
310 ARRAY_SIZE(cs47l24_aec_loopback_texts),
311 cs47l24_aec_loopback_texts,
312 cs47l24_aec_loopback_values);
313
314static const struct snd_kcontrol_new cs47l24_aec_loopback_mux =
315 SOC_DAPM_ENUM("AEC Loopback", cs47l24_aec_loopback);
316
317static const struct snd_soc_dapm_widget cs47l24_dapm_widgets[] = {
318SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1,
319 ARIZONA_SYSCLK_ENA_SHIFT, 0, NULL, 0),
320SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
321 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
322SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
323 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
324SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
325 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
326
327SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
328SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
329SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0),
330
331SND_SOC_DAPM_SIGGEN("TONE"),
332SND_SOC_DAPM_SIGGEN("NOISE"),
333SND_SOC_DAPM_SIGGEN("HAPTICS"),
334
335SND_SOC_DAPM_INPUT("IN1L"),
336SND_SOC_DAPM_INPUT("IN1R"),
337SND_SOC_DAPM_INPUT("IN2L"),
338SND_SOC_DAPM_INPUT("IN2R"),
339
340SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
341SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
342
343SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
344 0, NULL, 0, arizona_in_ev,
345 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
346 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
347SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
348 0, NULL, 0, arizona_in_ev,
349 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
350 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
351SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
352 0, NULL, 0, arizona_in_ev,
353 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
354 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
355SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
356 0, NULL, 0, arizona_in_ev,
357 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
358 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
359
360SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
361 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
362SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
363 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
364
365SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
366 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
367
368SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
369 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
370SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
371 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
372
373SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
374SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
375
376SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
377 NULL, 0),
378SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
379 NULL, 0),
380SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
381 NULL, 0),
382SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
383 NULL, 0),
384
385SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
386 NULL, 0),
387SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
388 NULL, 0),
389SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
390 NULL, 0),
391SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
392 NULL, 0),
393
394SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
395 0, NULL, 0),
396SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
397 0, NULL, 0),
398
399SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
400 NULL, 0),
401SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
402 NULL, 0),
403SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
404 NULL, 0),
405SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
406 NULL, 0),
407
408WM_ADSP2("DSP2", 1),
409WM_ADSP2("DSP3", 2),
410
411SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
412 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
413SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
414 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
415SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3,
416 ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
417SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3,
418 ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
419
420SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
421 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
422SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
423 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
424SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3,
425 ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
426SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3,
427 ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
428
429SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
430 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
431SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
432 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
433SND_SOC_DAPM_PGA("ISRC2INT3", ARIZONA_ISRC_2_CTRL_3,
434 ARIZONA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0),
435SND_SOC_DAPM_PGA("ISRC2INT4", ARIZONA_ISRC_2_CTRL_3,
436 ARIZONA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0),
437
438SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
439 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
440SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
441 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
442SND_SOC_DAPM_PGA("ISRC2DEC3", ARIZONA_ISRC_2_CTRL_3,
443 ARIZONA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0),
444SND_SOC_DAPM_PGA("ISRC2DEC4", ARIZONA_ISRC_2_CTRL_3,
445 ARIZONA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0),
446
447SND_SOC_DAPM_PGA("ISRC3INT1", ARIZONA_ISRC_3_CTRL_3,
448 ARIZONA_ISRC3_INT0_ENA_SHIFT, 0, NULL, 0),
449SND_SOC_DAPM_PGA("ISRC3INT2", ARIZONA_ISRC_3_CTRL_3,
450 ARIZONA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0),
451SND_SOC_DAPM_PGA("ISRC3INT3", ARIZONA_ISRC_3_CTRL_3,
452 ARIZONA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0),
453SND_SOC_DAPM_PGA("ISRC3INT4", ARIZONA_ISRC_3_CTRL_3,
454 ARIZONA_ISRC3_INT3_ENA_SHIFT, 0, NULL, 0),
455
456SND_SOC_DAPM_PGA("ISRC3DEC1", ARIZONA_ISRC_3_CTRL_3,
457 ARIZONA_ISRC3_DEC0_ENA_SHIFT, 0, NULL, 0),
458SND_SOC_DAPM_PGA("ISRC3DEC2", ARIZONA_ISRC_3_CTRL_3,
459 ARIZONA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0),
460SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3,
461 ARIZONA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0),
462SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3,
463 ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0),
464
465SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
466 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
467 &cs47l24_aec_loopback_mux),
468
469SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
470 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
471SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
472 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
473SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
474 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
475SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
476 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
477SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
478 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
479SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
480 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
481SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
482 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
483SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
484 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
485
486SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
487 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
488SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
489 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
490SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
491 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
492SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
493 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
494SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
495 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
496SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
497 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
498SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
499 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
500SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
501 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
502
503SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
504 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
505SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
506 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
507SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
508 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
509SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
510 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
511SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
512 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
513SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
514 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
515
516SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
517 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
518SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
519 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
520SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
521 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
522SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
523 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
524SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
525 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
526SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
527 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
528
529SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
530 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
531SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
532 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
533
534SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
535 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
536SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
537 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
538
539SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
540 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
541 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
542 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
543SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
544 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
545 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
546 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
547
548ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
549ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
550
551ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
552ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
553ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
554ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
555
556ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
557ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
558ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
559ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
560
561ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
562ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
563
564ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
565ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
566ARIZONA_MIXER_WIDGETS(SPKOUT, "SPKOUT"),
567
568ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
569ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
570ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
571ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
572ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
573ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
574ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
575ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
576
577ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
578ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
579ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
580ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
581ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
582ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
583
584ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
585ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
586
587ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
588ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
589ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
590ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
591
592ARIZONA_DSP_WIDGETS(DSP2, "DSP2"),
593ARIZONA_DSP_WIDGETS(DSP3, "DSP3"),
594
595ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
596ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
597ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
598ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
599
600ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
601ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
602ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
603ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
604
605ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
606ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
607ARIZONA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"),
608ARIZONA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"),
609
610ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
611ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
612ARIZONA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"),
613ARIZONA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"),
614
615ARIZONA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"),
616ARIZONA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"),
617ARIZONA_MUX_WIDGETS(ISRC3DEC3, "ISRC3DEC3"),
618ARIZONA_MUX_WIDGETS(ISRC3DEC4, "ISRC3DEC4"),
619
620ARIZONA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"),
621ARIZONA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"),
622ARIZONA_MUX_WIDGETS(ISRC3INT3, "ISRC3INT3"),
623ARIZONA_MUX_WIDGETS(ISRC3INT4, "ISRC3INT4"),
624
625SND_SOC_DAPM_OUTPUT("HPOUT1L"),
626SND_SOC_DAPM_OUTPUT("HPOUT1R"),
627SND_SOC_DAPM_OUTPUT("SPKOUTN"),
628SND_SOC_DAPM_OUTPUT("SPKOUTP"),
629
630SND_SOC_DAPM_OUTPUT("MICSUPP"),
631};
632
633#define ARIZONA_MIXER_INPUT_ROUTES(name) \
634 { name, "Noise Generator", "Noise Generator" }, \
635 { name, "Tone Generator 1", "Tone Generator 1" }, \
636 { name, "Tone Generator 2", "Tone Generator 2" }, \
637 { name, "Haptics", "HAPTICS" }, \
638 { name, "AEC", "AEC Loopback" }, \
639 { name, "IN1L", "IN1L PGA" }, \
640 { name, "IN1R", "IN1R PGA" }, \
641 { name, "IN2L", "IN2L PGA" }, \
642 { name, "IN2R", "IN2R PGA" }, \
643 { name, "AIF1RX1", "AIF1RX1" }, \
644 { name, "AIF1RX2", "AIF1RX2" }, \
645 { name, "AIF1RX3", "AIF1RX3" }, \
646 { name, "AIF1RX4", "AIF1RX4" }, \
647 { name, "AIF1RX5", "AIF1RX5" }, \
648 { name, "AIF1RX6", "AIF1RX6" }, \
649 { name, "AIF1RX7", "AIF1RX7" }, \
650 { name, "AIF1RX8", "AIF1RX8" }, \
651 { name, "AIF2RX1", "AIF2RX1" }, \
652 { name, "AIF2RX2", "AIF2RX2" }, \
653 { name, "AIF2RX3", "AIF2RX3" }, \
654 { name, "AIF2RX4", "AIF2RX4" }, \
655 { name, "AIF2RX5", "AIF2RX5" }, \
656 { name, "AIF2RX6", "AIF2RX6" }, \
657 { name, "AIF3RX1", "AIF3RX1" }, \
658 { name, "AIF3RX2", "AIF3RX2" }, \
659 { name, "EQ1", "EQ1" }, \
660 { name, "EQ2", "EQ2" }, \
661 { name, "DRC1L", "DRC1L" }, \
662 { name, "DRC1R", "DRC1R" }, \
663 { name, "DRC2L", "DRC2L" }, \
664 { name, "DRC2R", "DRC2R" }, \
665 { name, "LHPF1", "LHPF1" }, \
666 { name, "LHPF2", "LHPF2" }, \
667 { name, "LHPF3", "LHPF3" }, \
668 { name, "LHPF4", "LHPF4" }, \
669 { name, "ASRC1L", "ASRC1L" }, \
670 { name, "ASRC1R", "ASRC1R" }, \
671 { name, "ASRC2L", "ASRC2L" }, \
672 { name, "ASRC2R", "ASRC2R" }, \
673 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
674 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
675 { name, "ISRC1DEC3", "ISRC1DEC3" }, \
676 { name, "ISRC1DEC4", "ISRC1DEC4" }, \
677 { name, "ISRC1INT1", "ISRC1INT1" }, \
678 { name, "ISRC1INT2", "ISRC1INT2" }, \
679 { name, "ISRC1INT3", "ISRC1INT3" }, \
680 { name, "ISRC1INT4", "ISRC1INT4" }, \
681 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
682 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
683 { name, "ISRC2DEC3", "ISRC2DEC3" }, \
684 { name, "ISRC2DEC4", "ISRC2DEC4" }, \
685 { name, "ISRC2INT1", "ISRC2INT1" }, \
686 { name, "ISRC2INT2", "ISRC2INT2" }, \
687 { name, "ISRC2INT3", "ISRC2INT3" }, \
688 { name, "ISRC2INT4", "ISRC2INT4" }, \
689 { name, "ISRC3DEC1", "ISRC3DEC1" }, \
690 { name, "ISRC3DEC2", "ISRC3DEC2" }, \
691 { name, "ISRC3DEC3", "ISRC3DEC3" }, \
692 { name, "ISRC3DEC4", "ISRC3DEC4" }, \
693 { name, "ISRC3INT1", "ISRC3INT1" }, \
694 { name, "ISRC3INT2", "ISRC3INT2" }, \
695 { name, "ISRC3INT3", "ISRC3INT3" }, \
696 { name, "ISRC3INT4", "ISRC3INT4" }, \
697 { name, "DSP2.1", "DSP2" }, \
698 { name, "DSP2.2", "DSP2" }, \
699 { name, "DSP2.3", "DSP2" }, \
700 { name, "DSP2.4", "DSP2" }, \
701 { name, "DSP2.5", "DSP2" }, \
702 { name, "DSP2.6", "DSP2" }, \
703 { name, "DSP3.1", "DSP3" }, \
704 { name, "DSP3.2", "DSP3" }, \
705 { name, "DSP3.3", "DSP3" }, \
706 { name, "DSP3.4", "DSP3" }, \
707 { name, "DSP3.5", "DSP3" }, \
708 { name, "DSP3.6", "DSP3" }
709
710static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = {
711 { "OUT1L", NULL, "CPVDD" },
712 { "OUT1R", NULL, "CPVDD" },
713
714 { "OUT4L", NULL, "SPKVDD" },
715
716 { "OUT1L", NULL, "SYSCLK" },
717 { "OUT1R", NULL, "SYSCLK" },
718 { "OUT4L", NULL, "SYSCLK" },
719
720 { "IN1L", NULL, "SYSCLK" },
721 { "IN1R", NULL, "SYSCLK" },
722 { "IN2L", NULL, "SYSCLK" },
723 { "IN2R", NULL, "SYSCLK" },
724
725 { "MICBIAS1", NULL, "MICVDD" },
726 { "MICBIAS2", NULL, "MICVDD" },
727
728 { "Noise Generator", NULL, "SYSCLK" },
729 { "Tone Generator 1", NULL, "SYSCLK" },
730 { "Tone Generator 2", NULL, "SYSCLK" },
731
732 { "Noise Generator", NULL, "NOISE" },
733 { "Tone Generator 1", NULL, "TONE" },
734 { "Tone Generator 2", NULL, "TONE" },
735
736 { "AIF1 Capture", NULL, "AIF1TX1" },
737 { "AIF1 Capture", NULL, "AIF1TX2" },
738 { "AIF1 Capture", NULL, "AIF1TX3" },
739 { "AIF1 Capture", NULL, "AIF1TX4" },
740 { "AIF1 Capture", NULL, "AIF1TX5" },
741 { "AIF1 Capture", NULL, "AIF1TX6" },
742 { "AIF1 Capture", NULL, "AIF1TX7" },
743 { "AIF1 Capture", NULL, "AIF1TX8" },
744
745 { "AIF1RX1", NULL, "AIF1 Playback" },
746 { "AIF1RX2", NULL, "AIF1 Playback" },
747 { "AIF1RX3", NULL, "AIF1 Playback" },
748 { "AIF1RX4", NULL, "AIF1 Playback" },
749 { "AIF1RX5", NULL, "AIF1 Playback" },
750 { "AIF1RX6", NULL, "AIF1 Playback" },
751 { "AIF1RX7", NULL, "AIF1 Playback" },
752 { "AIF1RX8", NULL, "AIF1 Playback" },
753
754 { "AIF2 Capture", NULL, "AIF2TX1" },
755 { "AIF2 Capture", NULL, "AIF2TX2" },
756 { "AIF2 Capture", NULL, "AIF2TX3" },
757 { "AIF2 Capture", NULL, "AIF2TX4" },
758 { "AIF2 Capture", NULL, "AIF2TX5" },
759 { "AIF2 Capture", NULL, "AIF2TX6" },
760
761 { "AIF2RX1", NULL, "AIF2 Playback" },
762 { "AIF2RX2", NULL, "AIF2 Playback" },
763 { "AIF2RX3", NULL, "AIF2 Playback" },
764 { "AIF2RX4", NULL, "AIF2 Playback" },
765 { "AIF2RX5", NULL, "AIF2 Playback" },
766 { "AIF2RX6", NULL, "AIF2 Playback" },
767
768 { "AIF3 Capture", NULL, "AIF3TX1" },
769 { "AIF3 Capture", NULL, "AIF3TX2" },
770
771 { "AIF3RX1", NULL, "AIF3 Playback" },
772 { "AIF3RX2", NULL, "AIF3 Playback" },
773
774 { "AIF1 Playback", NULL, "SYSCLK" },
775 { "AIF2 Playback", NULL, "SYSCLK" },
776 { "AIF3 Playback", NULL, "SYSCLK" },
777
778 { "AIF1 Capture", NULL, "SYSCLK" },
779 { "AIF2 Capture", NULL, "SYSCLK" },
780 { "AIF3 Capture", NULL, "SYSCLK" },
781
782 { "IN1L PGA", NULL, "IN1L" },
783 { "IN1R PGA", NULL, "IN1R" },
784
785 { "IN2L PGA", NULL, "IN2L" },
786 { "IN2R PGA", NULL, "IN2R" },
787
788 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
789 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
790
791 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUT"),
792
793 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
794 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
795
796 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
797 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
798 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
799 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
800 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
801 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
802 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
803 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
804
805 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
806 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
807 ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
808 ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
809 ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
810 ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
811
812 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
813 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
814
815 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
816 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
817
818 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
819 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
820 ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
821 ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
822
823 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
824 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
825 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
826 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
827
828 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
829 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
830 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
831 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
832
833 ARIZONA_DSP_ROUTES("DSP2"),
834 ARIZONA_DSP_ROUTES("DSP3"),
835
836 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
837 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
838 ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
839 ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
840
841 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
842 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
843 ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
844 ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
845
846 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
847 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
848 ARIZONA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"),
849 ARIZONA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"),
850
851 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
852 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
853 ARIZONA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"),
854 ARIZONA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"),
855
856 ARIZONA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"),
857 ARIZONA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"),
858 ARIZONA_MUX_ROUTES("ISRC3INT3", "ISRC3INT3"),
859 ARIZONA_MUX_ROUTES("ISRC3INT4", "ISRC3INT4"),
860
861 ARIZONA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"),
862 ARIZONA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"),
863 ARIZONA_MUX_ROUTES("ISRC3DEC3", "ISRC3DEC3"),
864 ARIZONA_MUX_ROUTES("ISRC3DEC4", "ISRC3DEC4"),
865
866 { "AEC Loopback", "HPOUT1L", "OUT1L" },
867 { "AEC Loopback", "HPOUT1R", "OUT1R" },
868 { "HPOUT1L", NULL, "OUT1L" },
869 { "HPOUT1R", NULL, "OUT1R" },
870
871 { "AEC Loopback", "SPKOUT", "OUT4L" },
872 { "SPKOUTN", NULL, "OUT4L" },
873 { "SPKOUTP", NULL, "OUT4L" },
874
875 { "MICSUPP", NULL, "SYSCLK" },
876
877 { "DRC1 Signal Activity", NULL, "DRC1L" },
878 { "DRC1 Signal Activity", NULL, "DRC1R" },
879 { "DRC2 Signal Activity", NULL, "DRC2L" },
880 { "DRC2 Signal Activity", NULL, "DRC2R" },
881};
882
883static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
884 unsigned int Fref, unsigned int Fout)
885{
886 struct cs47l24_priv *cs47l24 = snd_soc_codec_get_drvdata(codec);
887
888 switch (fll_id) {
889 case CS47L24_FLL1:
890 return arizona_set_fll(&cs47l24->fll[0], source, Fref, Fout);
891 case CS47L24_FLL2:
892 return arizona_set_fll(&cs47l24->fll[1], source, Fref, Fout);
893 case CS47L24_FLL1_REFCLK:
894 return arizona_set_fll_refclk(&cs47l24->fll[0], source, Fref,
895 Fout);
896 case CS47L24_FLL2_REFCLK:
897 return arizona_set_fll_refclk(&cs47l24->fll[1], source, Fref,
898 Fout);
899 default:
900 return -EINVAL;
901 }
902}
903
904#define CS47L24_RATES SNDRV_PCM_RATE_8000_192000
905
906#define CS47L24_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
907 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
908
909static struct snd_soc_dai_driver cs47l24_dai[] = {
910 {
911 .name = "cs47l24-aif1",
912 .id = 1,
913 .base = ARIZONA_AIF1_BCLK_CTRL,
914 .playback = {
915 .stream_name = "AIF1 Playback",
916 .channels_min = 1,
917 .channels_max = 8,
918 .rates = CS47L24_RATES,
919 .formats = CS47L24_FORMATS,
920 },
921 .capture = {
922 .stream_name = "AIF1 Capture",
923 .channels_min = 1,
924 .channels_max = 8,
925 .rates = CS47L24_RATES,
926 .formats = CS47L24_FORMATS,
927 },
928 .ops = &arizona_dai_ops,
929 .symmetric_rates = 1,
930 .symmetric_samplebits = 1,
931 },
932 {
933 .name = "cs47l24-aif2",
934 .id = 2,
935 .base = ARIZONA_AIF2_BCLK_CTRL,
936 .playback = {
937 .stream_name = "AIF2 Playback",
938 .channels_min = 1,
939 .channels_max = 6,
940 .rates = CS47L24_RATES,
941 .formats = CS47L24_FORMATS,
942 },
943 .capture = {
944 .stream_name = "AIF2 Capture",
945 .channels_min = 1,
946 .channels_max = 6,
947 .rates = CS47L24_RATES,
948 .formats = CS47L24_FORMATS,
949 },
950 .ops = &arizona_dai_ops,
951 .symmetric_rates = 1,
952 .symmetric_samplebits = 1,
953 },
954 {
955 .name = "cs47l24-aif3",
956 .id = 3,
957 .base = ARIZONA_AIF3_BCLK_CTRL,
958 .playback = {
959 .stream_name = "AIF3 Playback",
960 .channels_min = 1,
961 .channels_max = 2,
962 .rates = CS47L24_RATES,
963 .formats = CS47L24_FORMATS,
964 },
965 .capture = {
966 .stream_name = "AIF3 Capture",
967 .channels_min = 1,
968 .channels_max = 2,
969 .rates = CS47L24_RATES,
970 .formats = CS47L24_FORMATS,
971 },
972 .ops = &arizona_dai_ops,
973 .symmetric_rates = 1,
974 .symmetric_samplebits = 1,
975 },
976};
977
978static int cs47l24_codec_probe(struct snd_soc_codec *codec)
979{
980 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
981 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
982 int ret;
983
984 priv->core.arizona->dapm = dapm;
985
986 arizona_init_spk(codec);
987 arizona_init_gpio(codec);
988 arizona_init_mono(codec);
989
990 ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
991 if (ret)
992 goto err_adsp2_codec_probe;
993
994 ret = wm_adsp2_codec_probe(&priv->core.adsp[2], codec);
995 if (ret)
996 goto err_adsp2_codec_probe;
997
998 ret = snd_soc_add_codec_controls(codec,
999 &arizona_adsp2_rate_controls[1], 2);
1000 if (ret)
1001 goto err_adsp2_codec_probe;
1002
1003 snd_soc_dapm_disable_pin(dapm, "HAPTICS");
1004
1005 return 0;
1006
1007err_adsp2_codec_probe:
1008 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
1009 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
1010
1011 return ret;
1012}
1013
1014static int cs47l24_codec_remove(struct snd_soc_codec *codec)
1015{
1016 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
1017
1018
1019 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
1020 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
1021
1022 priv->core.arizona->dapm = NULL;
1023
1024 return 0;
1025}
1026
1027#define CS47L24_DIG_VU 0x0200
1028
1029static unsigned int cs47l24_digital_vu[] = {
1030 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1031 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1032 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1033};
1034
1035static struct regmap *cs47l24_get_regmap(struct device *dev)
1036{
1037 struct cs47l24_priv *priv = dev_get_drvdata(dev);
1038
1039 return priv->core.arizona->regmap;
1040}
1041
1042static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
1043 .probe = cs47l24_codec_probe,
1044 .remove = cs47l24_codec_remove,
1045 .get_regmap = cs47l24_get_regmap,
1046
1047 .idle_bias_off = true,
1048
1049 .set_sysclk = arizona_set_sysclk,
1050 .set_pll = cs47l24_set_fll,
1051
1052 .controls = cs47l24_snd_controls,
1053 .num_controls = ARRAY_SIZE(cs47l24_snd_controls),
1054 .dapm_widgets = cs47l24_dapm_widgets,
1055 .num_dapm_widgets = ARRAY_SIZE(cs47l24_dapm_widgets),
1056 .dapm_routes = cs47l24_dapm_routes,
1057 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
1058};
1059
1060static int cs47l24_probe(struct platform_device *pdev)
1061{
1062 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1063 struct cs47l24_priv *cs47l24;
1064 int i, ret;
1065
1066 BUILD_BUG_ON(ARRAY_SIZE(cs47l24_dai) > ARIZONA_MAX_DAI);
1067
1068 cs47l24 = devm_kzalloc(&pdev->dev, sizeof(struct cs47l24_priv),
1069 GFP_KERNEL);
1070 if (!cs47l24)
1071 return -ENOMEM;
1072
1073 platform_set_drvdata(pdev, cs47l24);
1074
1075 cs47l24->core.arizona = arizona;
1076 cs47l24->core.num_inputs = 4;
1077
1078 for (i = 1; i <= 2; i++) {
1079 cs47l24->core.adsp[i].part = "cs47l24";
1080 cs47l24->core.adsp[i].num = i + 1;
1081 cs47l24->core.adsp[i].type = WMFW_ADSP2;
1082 cs47l24->core.adsp[i].dev = arizona->dev;
1083 cs47l24->core.adsp[i].regmap = arizona->regmap;
1084
1085 cs47l24->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 +
1086 (0x100 * i);
1087 cs47l24->core.adsp[i].mem = cs47l24_dsp_regions[i - 1];
1088 cs47l24->core.adsp[i].num_mems =
1089 ARRAY_SIZE(cs47l24_dsp2_regions);
1090
1091 ret = wm_adsp2_init(&cs47l24->core.adsp[i]);
1092 if (ret != 0)
1093 return ret;
1094 }
1095
1096 for (i = 0; i < ARRAY_SIZE(cs47l24->fll); i++)
1097 cs47l24->fll[i].vco_mult = 3;
1098
1099 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1100 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
1101 &cs47l24->fll[0]);
1102 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1103 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1104 &cs47l24->fll[1]);
1105
1106 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1107 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1108 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1109 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1110 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1111
1112 for (i = 0; i < ARRAY_SIZE(cs47l24_dai); i++)
1113 arizona_init_dai(&cs47l24->core, i);
1114
1115 /* Latch volume update bits */
1116 for (i = 0; i < ARRAY_SIZE(cs47l24_digital_vu); i++)
1117 regmap_update_bits(arizona->regmap, cs47l24_digital_vu[i],
1118 CS47L24_DIG_VU, CS47L24_DIG_VU);
1119
1120 pm_runtime_enable(&pdev->dev);
1121 pm_runtime_idle(&pdev->dev);
1122
1123 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
1124 cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
1125}
1126
1127static int cs47l24_remove(struct platform_device *pdev)
1128{
1129 snd_soc_unregister_codec(&pdev->dev);
1130 pm_runtime_disable(&pdev->dev);
1131
1132 return 0;
1133}
1134
1135static struct platform_driver cs47l24_codec_driver = {
1136 .driver = {
1137 .name = "cs47l24-codec",
1138 },
1139 .probe = cs47l24_probe,
1140 .remove = cs47l24_remove,
1141};
1142
1143module_platform_driver(cs47l24_codec_driver);
1144
1145MODULE_DESCRIPTION("ASoC CS47L24 driver");
1146MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
1147MODULE_LICENSE("GPL v2");
1148MODULE_ALIAS("platform:cs47l24-codec");
diff --git a/sound/soc/codecs/cs47l24.h b/sound/soc/codecs/cs47l24.h
new file mode 100644
index 000000000000..77ab2b77b2e6
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.h
@@ -0,0 +1,23 @@
1/*
2 * cs47l24.h -- ALSA SoC Audio driver for Cirrus Logic CS47L24
3 *
4 * Copyright 2015 Cirrus Logic Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
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 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _CS47L24_H
14#define _CS47L24_H
15
16#include "arizona.h"
17
18#define CS47L24_FLL1 1
19#define CS47L24_FLL2 2
20#define CS47L24_FLL1_REFCLK 3
21#define CS47L24_FLL2_REFCLK 4
22
23#endif
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c
new file mode 100644
index 000000000000..72686517ff54
--- /dev/null
+++ b/sound/soc/codecs/da7218.c
@@ -0,0 +1,3314 @@
1/*
2 * da7218.c - DA7218 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.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 <linux/clk.h>
15#include <linux/i2c.h>
16#include <linux/of_device.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/pm.h>
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/regulator/consumer.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/jack.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include <sound/da7218.h>
33#include "da7218.h"
34
35
36/*
37 * TLVs and Enums
38 */
39
40/* Input TLVs */
41static const DECLARE_TLV_DB_SCALE(da7218_mic_gain_tlv, -600, 600, 0);
42static const DECLARE_TLV_DB_SCALE(da7218_mixin_gain_tlv, -450, 150, 0);
43static const DECLARE_TLV_DB_SCALE(da7218_in_dig_gain_tlv, -8325, 75, 0);
44static const DECLARE_TLV_DB_SCALE(da7218_ags_trigger_tlv, -9000, 600, 0);
45static const DECLARE_TLV_DB_SCALE(da7218_ags_att_max_tlv, 0, 600, 0);
46static const DECLARE_TLV_DB_SCALE(da7218_alc_threshold_tlv, -9450, 150, 0);
47static const DECLARE_TLV_DB_SCALE(da7218_alc_gain_tlv, 0, 600, 0);
48static const DECLARE_TLV_DB_SCALE(da7218_alc_ana_gain_tlv, 0, 600, 0);
49
50/* Input/Output TLVs */
51static const DECLARE_TLV_DB_SCALE(da7218_dmix_gain_tlv, -4200, 150, 0);
52
53/* Output TLVs */
54static const DECLARE_TLV_DB_SCALE(da7218_dgs_trigger_tlv, -9450, 150, 0);
55static const DECLARE_TLV_DB_SCALE(da7218_dgs_anticlip_tlv, -4200, 600, 0);
56static const DECLARE_TLV_DB_SCALE(da7218_dgs_signal_tlv, -9000, 600, 0);
57static const DECLARE_TLV_DB_SCALE(da7218_out_eq_band_tlv, -1050, 150, 0);
58static const DECLARE_TLV_DB_SCALE(da7218_out_dig_gain_tlv, -8325, 75, 0);
59static const DECLARE_TLV_DB_SCALE(da7218_dac_ng_threshold_tlv, -10200, 600, 0);
60static const DECLARE_TLV_DB_SCALE(da7218_mixout_gain_tlv, -100, 50, 0);
61static const DECLARE_TLV_DB_SCALE(da7218_hp_gain_tlv, -5700, 150, 0);
62
63/* Input Enums */
64static const char * const da7218_alc_attack_rate_txt[] = {
65 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",
66 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",
67 "30024/fs",
68};
69
70static const struct soc_enum da7218_alc_attack_rate =
71 SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_ATTACK_SHIFT,
72 DA7218_ALC_ATTACK_MAX, da7218_alc_attack_rate_txt);
73
74static const char * const da7218_alc_release_rate_txt[] = {
75 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",
76 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs",
77};
78
79static const struct soc_enum da7218_alc_release_rate =
80 SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_RELEASE_SHIFT,
81 DA7218_ALC_RELEASE_MAX, da7218_alc_release_rate_txt);
82
83static const char * const da7218_alc_hold_time_txt[] = {
84 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
85 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
86 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
87};
88
89static const struct soc_enum da7218_alc_hold_time =
90 SOC_ENUM_SINGLE(DA7218_ALC_CTRL3, DA7218_ALC_HOLD_SHIFT,
91 DA7218_ALC_HOLD_MAX, da7218_alc_hold_time_txt);
92
93static const char * const da7218_alc_anticlip_step_txt[] = {
94 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs",
95};
96
97static const struct soc_enum da7218_alc_anticlip_step =
98 SOC_ENUM_SINGLE(DA7218_ALC_ANTICLIP_CTRL,
99 DA7218_ALC_ANTICLIP_STEP_SHIFT,
100 DA7218_ALC_ANTICLIP_STEP_MAX,
101 da7218_alc_anticlip_step_txt);
102
103static const char * const da7218_integ_rate_txt[] = {
104 "1/4", "1/16", "1/256", "1/65536"
105};
106
107static const struct soc_enum da7218_integ_attack_rate =
108 SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_ATTACK_SHIFT,
109 DA7218_INTEG_MAX, da7218_integ_rate_txt);
110
111static const struct soc_enum da7218_integ_release_rate =
112 SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_RELEASE_SHIFT,
113 DA7218_INTEG_MAX, da7218_integ_rate_txt);
114
115/* Input/Output Enums */
116static const char * const da7218_gain_ramp_rate_txt[] = {
117 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",
118 "Nominal Rate / 16",
119};
120
121static const struct soc_enum da7218_gain_ramp_rate =
122 SOC_ENUM_SINGLE(DA7218_GAIN_RAMP_CTRL, DA7218_GAIN_RAMP_RATE_SHIFT,
123 DA7218_GAIN_RAMP_RATE_MAX, da7218_gain_ramp_rate_txt);
124
125static const char * const da7218_hpf_mode_txt[] = {
126 "Disabled", "Audio", "Voice",
127};
128
129static const unsigned int da7218_hpf_mode_val[] = {
130 DA7218_HPF_DISABLED, DA7218_HPF_AUDIO_EN, DA7218_HPF_VOICE_EN,
131};
132
133static const struct soc_enum da7218_in1_hpf_mode =
134 SOC_VALUE_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
135 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
136 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
137 da7218_hpf_mode_val);
138
139static const struct soc_enum da7218_in2_hpf_mode =
140 SOC_VALUE_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
141 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
142 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
143 da7218_hpf_mode_val);
144
145static const struct soc_enum da7218_out1_hpf_mode =
146 SOC_VALUE_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
147 DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,
148 DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,
149 da7218_hpf_mode_val);
150
151static const char * const da7218_audio_hpf_corner_txt[] = {
152 "2Hz", "4Hz", "8Hz", "16Hz",
153};
154
155static const struct soc_enum da7218_in1_audio_hpf_corner =
156 SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
157 DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT,
158 DA7218_AUDIO_HPF_CORNER_MAX,
159 da7218_audio_hpf_corner_txt);
160
161static const struct soc_enum da7218_in2_audio_hpf_corner =
162 SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
163 DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT,
164 DA7218_AUDIO_HPF_CORNER_MAX,
165 da7218_audio_hpf_corner_txt);
166
167static const struct soc_enum da7218_out1_audio_hpf_corner =
168 SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
169 DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT,
170 DA7218_AUDIO_HPF_CORNER_MAX,
171 da7218_audio_hpf_corner_txt);
172
173static const char * const da7218_voice_hpf_corner_txt[] = {
174 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz",
175};
176
177static const struct soc_enum da7218_in1_voice_hpf_corner =
178 SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,
179 DA7218_IN_1_VOICE_HPF_CORNER_SHIFT,
180 DA7218_VOICE_HPF_CORNER_MAX,
181 da7218_voice_hpf_corner_txt);
182
183static const struct soc_enum da7218_in2_voice_hpf_corner =
184 SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,
185 DA7218_IN_2_VOICE_HPF_CORNER_SHIFT,
186 DA7218_VOICE_HPF_CORNER_MAX,
187 da7218_voice_hpf_corner_txt);
188
189static const struct soc_enum da7218_out1_voice_hpf_corner =
190 SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,
191 DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT,
192 DA7218_VOICE_HPF_CORNER_MAX,
193 da7218_voice_hpf_corner_txt);
194
195static const char * const da7218_tonegen_dtmf_key_txt[] = {
196 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
197 "*", "#"
198};
199
200static const struct soc_enum da7218_tonegen_dtmf_key =
201 SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG1, DA7218_DTMF_REG_SHIFT,
202 DA7218_DTMF_REG_MAX, da7218_tonegen_dtmf_key_txt);
203
204static const char * const da7218_tonegen_swg_sel_txt[] = {
205 "Sum", "SWG1", "SWG2", "SWG1_1-Cos"
206};
207
208static const struct soc_enum da7218_tonegen_swg_sel =
209 SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG2, DA7218_SWG_SEL_SHIFT,
210 DA7218_SWG_SEL_MAX, da7218_tonegen_swg_sel_txt);
211
212/* Output Enums */
213static const char * const da7218_dgs_rise_coeff_txt[] = {
214 "1/1", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384",
215};
216
217static const struct soc_enum da7218_dgs_rise_coeff =
218 SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_RISE_COEFF_SHIFT,
219 DA7218_DGS_RISE_COEFF_MAX, da7218_dgs_rise_coeff_txt);
220
221static const char * const da7218_dgs_fall_coeff_txt[] = {
222 "1/4", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384", "1/65536",
223};
224
225static const struct soc_enum da7218_dgs_fall_coeff =
226 SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_FALL_COEFF_SHIFT,
227 DA7218_DGS_FALL_COEFF_MAX, da7218_dgs_fall_coeff_txt);
228
229static const char * const da7218_dac_ng_setup_time_txt[] = {
230 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples"
231};
232
233static const struct soc_enum da7218_dac_ng_setup_time =
234 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
235 DA7218_DAC_NG_SETUP_TIME_SHIFT,
236 DA7218_DAC_NG_SETUP_TIME_MAX,
237 da7218_dac_ng_setup_time_txt);
238
239static const char * const da7218_dac_ng_rampup_txt[] = {
240 "0.22ms/dB", "0.0138ms/dB"
241};
242
243static const struct soc_enum da7218_dac_ng_rampup_rate =
244 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
245 DA7218_DAC_NG_RAMPUP_RATE_SHIFT,
246 DA7218_DAC_NG_RAMPUP_RATE_MAX,
247 da7218_dac_ng_rampup_txt);
248
249static const char * const da7218_dac_ng_rampdown_txt[] = {
250 "0.88ms/dB", "14.08ms/dB"
251};
252
253static const struct soc_enum da7218_dac_ng_rampdown_rate =
254 SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,
255 DA7218_DAC_NG_RAMPDN_RATE_SHIFT,
256 DA7218_DAC_NG_RAMPDN_RATE_MAX,
257 da7218_dac_ng_rampdown_txt);
258
259static const char * const da7218_cp_mchange_txt[] = {
260 "Largest Volume", "DAC Volume", "Signal Magnitude"
261};
262
263static const unsigned int da7218_cp_mchange_val[] = {
264 DA7218_CP_MCHANGE_LARGEST_VOL, DA7218_CP_MCHANGE_DAC_VOL,
265 DA7218_CP_MCHANGE_SIG_MAG
266};
267
268static const struct soc_enum da7218_cp_mchange =
269 SOC_VALUE_ENUM_SINGLE(DA7218_CP_CTRL, DA7218_CP_MCHANGE_SHIFT,
270 DA7218_CP_MCHANGE_REL_MASK, DA7218_CP_MCHANGE_MAX,
271 da7218_cp_mchange_txt, da7218_cp_mchange_val);
272
273static const char * const da7218_cp_fcontrol_txt[] = {
274 "1MHz", "500KHz", "250KHz", "125KHz", "63KHz", "0KHz"
275};
276
277static const struct soc_enum da7218_cp_fcontrol =
278 SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_FCONTROL_SHIFT,
279 DA7218_CP_FCONTROL_MAX, da7218_cp_fcontrol_txt);
280
281static const char * const da7218_cp_tau_delay_txt[] = {
282 "0ms", "2ms", "4ms", "16ms", "64ms", "128ms", "256ms", "512ms"
283};
284
285static const struct soc_enum da7218_cp_tau_delay =
286 SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_TAU_DELAY_SHIFT,
287 DA7218_CP_TAU_DELAY_MAX, da7218_cp_tau_delay_txt);
288
289/*
290 * Control Functions
291 */
292
293/* ALC */
294static void da7218_alc_calib(struct snd_soc_codec *codec)
295{
296 u8 mic_1_ctrl, mic_2_ctrl;
297 u8 mixin_1_ctrl, mixin_2_ctrl;
298 u8 in_1l_filt_ctrl, in_1r_filt_ctrl, in_2l_filt_ctrl, in_2r_filt_ctrl;
299 u8 in_1_hpf_ctrl, in_2_hpf_ctrl;
300 u8 calib_ctrl;
301 int i = 0;
302 bool calibrated = false;
303
304 /* Save current state of MIC control registers */
305 mic_1_ctrl = snd_soc_read(codec, DA7218_MIC_1_CTRL);
306 mic_2_ctrl = snd_soc_read(codec, DA7218_MIC_2_CTRL);
307
308 /* Save current state of input mixer control registers */
309 mixin_1_ctrl = snd_soc_read(codec, DA7218_MIXIN_1_CTRL);
310 mixin_2_ctrl = snd_soc_read(codec, DA7218_MIXIN_2_CTRL);
311
312 /* Save current state of input filter control registers */
313 in_1l_filt_ctrl = snd_soc_read(codec, DA7218_IN_1L_FILTER_CTRL);
314 in_1r_filt_ctrl = snd_soc_read(codec, DA7218_IN_1R_FILTER_CTRL);
315 in_2l_filt_ctrl = snd_soc_read(codec, DA7218_IN_2L_FILTER_CTRL);
316 in_2r_filt_ctrl = snd_soc_read(codec, DA7218_IN_2R_FILTER_CTRL);
317
318 /* Save current state of input HPF control registers */
319 in_1_hpf_ctrl = snd_soc_read(codec, DA7218_IN_1_HPF_FILTER_CTRL);
320 in_2_hpf_ctrl = snd_soc_read(codec, DA7218_IN_2_HPF_FILTER_CTRL);
321
322 /* Enable then Mute MIC PGAs */
323 snd_soc_update_bits(codec, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,
324 DA7218_MIC_1_AMP_EN_MASK);
325 snd_soc_update_bits(codec, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,
326 DA7218_MIC_2_AMP_EN_MASK);
327 snd_soc_update_bits(codec, DA7218_MIC_1_CTRL,
328 DA7218_MIC_1_AMP_MUTE_EN_MASK,
329 DA7218_MIC_1_AMP_MUTE_EN_MASK);
330 snd_soc_update_bits(codec, DA7218_MIC_2_CTRL,
331 DA7218_MIC_2_AMP_MUTE_EN_MASK,
332 DA7218_MIC_2_AMP_MUTE_EN_MASK);
333
334 /* Enable input mixers unmuted */
335 snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
336 DA7218_MIXIN_1_AMP_EN_MASK |
337 DA7218_MIXIN_1_AMP_MUTE_EN_MASK,
338 DA7218_MIXIN_1_AMP_EN_MASK);
339 snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
340 DA7218_MIXIN_2_AMP_EN_MASK |
341 DA7218_MIXIN_2_AMP_MUTE_EN_MASK,
342 DA7218_MIXIN_2_AMP_EN_MASK);
343
344 /* Enable input filters unmuted */
345 snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
346 DA7218_IN_1L_FILTER_EN_MASK |
347 DA7218_IN_1L_MUTE_EN_MASK,
348 DA7218_IN_1L_FILTER_EN_MASK);
349 snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
350 DA7218_IN_1R_FILTER_EN_MASK |
351 DA7218_IN_1R_MUTE_EN_MASK,
352 DA7218_IN_1R_FILTER_EN_MASK);
353 snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
354 DA7218_IN_2L_FILTER_EN_MASK |
355 DA7218_IN_2L_MUTE_EN_MASK,
356 DA7218_IN_2L_FILTER_EN_MASK);
357 snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
358 DA7218_IN_2R_FILTER_EN_MASK |
359 DA7218_IN_2R_MUTE_EN_MASK,
360 DA7218_IN_2R_FILTER_EN_MASK);
361
362 /*
363 * Make sure input HPFs voice mode is disabled, otherwise for sampling
364 * rates above 32KHz the ADC signals will be stopped and will cause
365 * calibration to lock up.
366 */
367 snd_soc_update_bits(codec, DA7218_IN_1_HPF_FILTER_CTRL,
368 DA7218_IN_1_VOICE_EN_MASK, 0);
369 snd_soc_update_bits(codec, DA7218_IN_2_HPF_FILTER_CTRL,
370 DA7218_IN_2_VOICE_EN_MASK, 0);
371
372 /* Perform auto calibration */
373 snd_soc_update_bits(codec, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,
374 DA7218_CALIB_AUTO_EN_MASK);
375 do {
376 calib_ctrl = snd_soc_read(codec, DA7218_CALIB_CTRL);
377 if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) {
378 ++i;
379 usleep_range(DA7218_ALC_CALIB_DELAY_MIN,
380 DA7218_ALC_CALIB_DELAY_MAX);
381 } else {
382 calibrated = true;
383 }
384
385 } while ((i < DA7218_ALC_CALIB_MAX_TRIES) && (!calibrated));
386
387 /* If auto calibration fails, disable DC offset, hybrid ALC */
388 if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) {
389 dev_warn(codec->dev,
390 "ALC auto calibration failed - %s\n",
391 (calibrated) ? "overflow" : "timeout");
392 snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
393 DA7218_CALIB_OFFSET_EN_MASK, 0);
394 snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
395 DA7218_ALC_SYNC_MODE_MASK, 0);
396
397 } else {
398 /* Enable DC offset cancellation */
399 snd_soc_update_bits(codec, DA7218_CALIB_CTRL,
400 DA7218_CALIB_OFFSET_EN_MASK,
401 DA7218_CALIB_OFFSET_EN_MASK);
402
403 /* Enable ALC hybrid mode */
404 snd_soc_update_bits(codec, DA7218_ALC_CTRL1,
405 DA7218_ALC_SYNC_MODE_MASK,
406 DA7218_ALC_SYNC_MODE_CH1 |
407 DA7218_ALC_SYNC_MODE_CH2);
408 }
409
410 /* Restore input HPF control registers to original states */
411 snd_soc_write(codec, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);
412 snd_soc_write(codec, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);
413
414 /* Restore input filter control registers to original states */
415 snd_soc_write(codec, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);
416 snd_soc_write(codec, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);
417 snd_soc_write(codec, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);
418 snd_soc_write(codec, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);
419
420 /* Restore input mixer control registers to original state */
421 snd_soc_write(codec, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);
422 snd_soc_write(codec, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);
423
424 /* Restore MIC control registers to original states */
425 snd_soc_write(codec, DA7218_MIC_1_CTRL, mic_1_ctrl);
426 snd_soc_write(codec, DA7218_MIC_2_CTRL, mic_2_ctrl);
427}
428
429static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431{
432 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
433 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
434 int ret;
435
436 ret = snd_soc_put_volsw(kcontrol, ucontrol);
437
438 /*
439 * If ALC in operation and value of control has been updated,
440 * make sure calibrated offsets are updated.
441 */
442 if ((ret == 1) && (da7218->alc_en))
443 da7218_alc_calib(codec);
444
445 return ret;
446}
447
448static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,
449 struct snd_ctl_elem_value *ucontrol)
450{
451 struct soc_mixer_control *mc =
452 (struct soc_mixer_control *) kcontrol->private_value;
453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
454 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
455 unsigned int lvalue = ucontrol->value.integer.value[0];
456 unsigned int rvalue = ucontrol->value.integer.value[1];
457 unsigned int lshift = mc->shift;
458 unsigned int rshift = mc->rshift;
459 unsigned int mask = (mc->max << lshift) | (mc->max << rshift);
460
461 /* Force ALC offset calibration if enabling ALC */
462 if ((lvalue || rvalue) && (!da7218->alc_en))
463 da7218_alc_calib(codec);
464
465 /* Update bits to detail which channels are enabled/disabled */
466 da7218->alc_en &= ~mask;
467 da7218->alc_en |= (lvalue << lshift) | (rvalue << rshift);
468
469 return snd_soc_put_volsw(kcontrol, ucontrol);
470}
471
472/* ToneGen */
473static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_value *ucontrol)
475{
476 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
477 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
478 struct soc_mixer_control *mixer_ctrl =
479 (struct soc_mixer_control *) kcontrol->private_value;
480 unsigned int reg = mixer_ctrl->reg;
481 u16 val;
482 int ret;
483
484 /*
485 * Frequency value spans two 8-bit registers, lower then upper byte.
486 * Therefore we need to convert to host endianness here.
487 */
488 ret = regmap_raw_read(da7218->regmap, reg, &val, 2);
489 if (ret)
490 return ret;
491
492 ucontrol->value.integer.value[0] = le16_to_cpu(val);
493
494 return 0;
495}
496
497static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
501 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
502 struct soc_mixer_control *mixer_ctrl =
503 (struct soc_mixer_control *) kcontrol->private_value;
504 unsigned int reg = mixer_ctrl->reg;
505 u16 val;
506
507 /*
508 * Frequency value spans two 8-bit registers, lower then upper byte.
509 * Therefore we need to convert to little endian here to align with
510 * HW registers.
511 */
512 val = cpu_to_le16(ucontrol->value.integer.value[0]);
513
514 return regmap_raw_write(da7218->regmap, reg, &val, 2);
515}
516
517static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,
518 struct snd_ctl_elem_value *ucontrol)
519{
520 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
521 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
522 struct soc_mixer_control *mixer_ctrl =
523 (struct soc_mixer_control *) kcontrol->private_value;
524 unsigned int lvalue = ucontrol->value.integer.value[0];
525 unsigned int rvalue = ucontrol->value.integer.value[1];
526 unsigned int lshift = mixer_ctrl->shift;
527 unsigned int rshift = mixer_ctrl->rshift;
528 unsigned int mask = (mixer_ctrl->max << lshift) |
529 (mixer_ctrl->max << rshift);
530 da7218->mic_lvl_det_en &= ~mask;
531 da7218->mic_lvl_det_en |= (lvalue << lshift) | (rvalue << rshift);
532
533 /*
534 * Here we only enable the feature on paths which are already
535 * powered. If a channel is enabled here for level detect, but that path
536 * isn't powered, then the channel will actually be enabled when we do
537 * power the path (IN_FILTER widget events). This handling avoids
538 * unwanted level detect events.
539 */
540 return snd_soc_write(codec, mixer_ctrl->reg,
541 (da7218->in_filt_en & da7218->mic_lvl_det_en));
542}
543
544static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
546{
547 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
548 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
549 struct soc_mixer_control *mixer_ctrl =
550 (struct soc_mixer_control *) kcontrol->private_value;
551 unsigned int lshift = mixer_ctrl->shift;
552 unsigned int rshift = mixer_ctrl->rshift;
553 unsigned int lmask = (mixer_ctrl->max << lshift);
554 unsigned int rmask = (mixer_ctrl->max << rshift);
555
556 ucontrol->value.integer.value[0] =
557 (da7218->mic_lvl_det_en & lmask) >> lshift;
558 ucontrol->value.integer.value[1] =
559 (da7218->mic_lvl_det_en & rmask) >> rshift;
560
561 return 0;
562}
563
564static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566{
567 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
568 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
569 struct soc_bytes_ext *bytes_ext =
570 (struct soc_bytes_ext *) kcontrol->private_value;
571
572 /* Determine which BiQuads we're setting based on size of config data */
573 switch (bytes_ext->max) {
574 case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:
575 memcpy(ucontrol->value.bytes.data, da7218->biq_5stage_coeff,
576 bytes_ext->max);
577 break;
578 case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:
579 memcpy(ucontrol->value.bytes.data, da7218->stbiq_3stage_coeff,
580 bytes_ext->max);
581 break;
582 default:
583 return -EINVAL;
584 }
585
586 return 0;
587}
588
589static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
591{
592 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
593 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
594 struct soc_bytes_ext *bytes_ext =
595 (struct soc_bytes_ext *) kcontrol->private_value;
596 u8 reg, out_filt1l;
597 u8 cfg[DA7218_BIQ_CFG_SIZE];
598 int i;
599
600 /*
601 * Determine which BiQuads we're setting based on size of config data,
602 * and stored the data for use by get function.
603 */
604 switch (bytes_ext->max) {
605 case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:
606 reg = DA7218_OUT_1_BIQ_5STAGE_DATA;
607 memcpy(da7218->biq_5stage_coeff, ucontrol->value.bytes.data,
608 bytes_ext->max);
609 break;
610 case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:
611 reg = DA7218_SIDETONE_BIQ_3STAGE_DATA;
612 memcpy(da7218->stbiq_3stage_coeff, ucontrol->value.bytes.data,
613 bytes_ext->max);
614 break;
615 default:
616 return -EINVAL;
617 }
618
619 /* Make sure at least out filter1 enabled to allow programming */
620 out_filt1l = snd_soc_read(codec, DA7218_OUT_1L_FILTER_CTRL);
621 snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL,
622 out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK);
623
624 for (i = 0; i < bytes_ext->max; ++i) {
625 cfg[DA7218_BIQ_CFG_DATA] = ucontrol->value.bytes.data[i];
626 cfg[DA7218_BIQ_CFG_ADDR] = i;
627 regmap_raw_write(da7218->regmap, reg, cfg, DA7218_BIQ_CFG_SIZE);
628 }
629
630 /* Restore filter to previous setting */
631 snd_soc_write(codec, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);
632
633 return 0;
634}
635
636
637/*
638 * KControls
639 */
640
641static const struct snd_kcontrol_new da7218_snd_controls[] = {
642 /* Mics */
643 SOC_SINGLE_TLV("Mic1 Volume", DA7218_MIC_1_GAIN,
644 DA7218_MIC_1_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,
645 DA7218_NO_INVERT, da7218_mic_gain_tlv),
646 SOC_SINGLE("Mic1 Switch", DA7218_MIC_1_CTRL,
647 DA7218_MIC_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
648 DA7218_INVERT),
649 SOC_SINGLE_TLV("Mic2 Volume", DA7218_MIC_2_GAIN,
650 DA7218_MIC_2_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,
651 DA7218_NO_INVERT, da7218_mic_gain_tlv),
652 SOC_SINGLE("Mic2 Switch", DA7218_MIC_2_CTRL,
653 DA7218_MIC_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
654 DA7218_INVERT),
655
656 /* Mixer Input */
657 SOC_SINGLE_EXT_TLV("Mixin1 Volume", DA7218_MIXIN_1_GAIN,
658 DA7218_MIXIN_1_AMP_GAIN_SHIFT,
659 DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,
660 snd_soc_get_volsw, da7218_mixin_gain_put,
661 da7218_mixin_gain_tlv),
662 SOC_SINGLE("Mixin1 Switch", DA7218_MIXIN_1_CTRL,
663 DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
664 DA7218_INVERT),
665 SOC_SINGLE("Mixin1 Gain Ramp Switch", DA7218_MIXIN_1_CTRL,
666 DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
667 DA7218_NO_INVERT),
668 SOC_SINGLE("Mixin1 ZC Gain Switch", DA7218_MIXIN_1_CTRL,
669 DA7218_MIXIN_1_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,
670 DA7218_NO_INVERT),
671 SOC_SINGLE_EXT_TLV("Mixin2 Volume", DA7218_MIXIN_2_GAIN,
672 DA7218_MIXIN_2_AMP_GAIN_SHIFT,
673 DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,
674 snd_soc_get_volsw, da7218_mixin_gain_put,
675 da7218_mixin_gain_tlv),
676 SOC_SINGLE("Mixin2 Switch", DA7218_MIXIN_2_CTRL,
677 DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
678 DA7218_INVERT),
679 SOC_SINGLE("Mixin2 Gain Ramp Switch", DA7218_MIXIN_2_CTRL,
680 DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
681 DA7218_NO_INVERT),
682 SOC_SINGLE("Mixin2 ZC Gain Switch", DA7218_MIXIN_2_CTRL,
683 DA7218_MIXIN_2_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,
684 DA7218_NO_INVERT),
685
686 /* ADCs */
687 SOC_SINGLE("ADC1 AAF Switch", DA7218_ADC_1_CTRL,
688 DA7218_ADC_1_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
689 DA7218_NO_INVERT),
690 SOC_SINGLE("ADC2 AAF Switch", DA7218_ADC_2_CTRL,
691 DA7218_ADC_2_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
692 DA7218_NO_INVERT),
693 SOC_SINGLE("ADC LP Mode Switch", DA7218_ADC_MODE,
694 DA7218_ADC_LP_MODE_SHIFT, DA7218_SWITCH_EN_MAX,
695 DA7218_NO_INVERT),
696
697 /* Input Filters */
698 SOC_SINGLE_TLV("In Filter1L Volume", DA7218_IN_1L_GAIN,
699 DA7218_IN_1L_DIGITAL_GAIN_SHIFT,
700 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
701 da7218_in_dig_gain_tlv),
702 SOC_SINGLE("In Filter1L Switch", DA7218_IN_1L_FILTER_CTRL,
703 DA7218_IN_1L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
704 DA7218_INVERT),
705 SOC_SINGLE("In Filter1L Gain Ramp Switch", DA7218_IN_1L_FILTER_CTRL,
706 DA7218_IN_1L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
707 DA7218_NO_INVERT),
708 SOC_SINGLE_TLV("In Filter1R Volume", DA7218_IN_1R_GAIN,
709 DA7218_IN_1R_DIGITAL_GAIN_SHIFT,
710 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
711 da7218_in_dig_gain_tlv),
712 SOC_SINGLE("In Filter1R Switch", DA7218_IN_1R_FILTER_CTRL,
713 DA7218_IN_1R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
714 DA7218_INVERT),
715 SOC_SINGLE("In Filter1R Gain Ramp Switch",
716 DA7218_IN_1R_FILTER_CTRL, DA7218_IN_1R_RAMP_EN_SHIFT,
717 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
718 SOC_SINGLE_TLV("In Filter2L Volume", DA7218_IN_2L_GAIN,
719 DA7218_IN_2L_DIGITAL_GAIN_SHIFT,
720 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
721 da7218_in_dig_gain_tlv),
722 SOC_SINGLE("In Filter2L Switch", DA7218_IN_2L_FILTER_CTRL,
723 DA7218_IN_2L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
724 DA7218_INVERT),
725 SOC_SINGLE("In Filter2L Gain Ramp Switch", DA7218_IN_2L_FILTER_CTRL,
726 DA7218_IN_2L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
727 DA7218_NO_INVERT),
728 SOC_SINGLE_TLV("In Filter2R Volume", DA7218_IN_2R_GAIN,
729 DA7218_IN_2R_DIGITAL_GAIN_SHIFT,
730 DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
731 da7218_in_dig_gain_tlv),
732 SOC_SINGLE("In Filter2R Switch", DA7218_IN_2R_FILTER_CTRL,
733 DA7218_IN_2R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
734 DA7218_INVERT),
735 SOC_SINGLE("In Filter2R Gain Ramp Switch",
736 DA7218_IN_2R_FILTER_CTRL, DA7218_IN_2R_RAMP_EN_SHIFT,
737 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
738
739 /* AGS */
740 SOC_SINGLE_TLV("AGS Trigger", DA7218_AGS_TRIGGER,
741 DA7218_AGS_TRIGGER_SHIFT, DA7218_AGS_TRIGGER_MAX,
742 DA7218_INVERT, da7218_ags_trigger_tlv),
743 SOC_SINGLE_TLV("AGS Max Attenuation", DA7218_AGS_ATT_MAX,
744 DA7218_AGS_ATT_MAX_SHIFT, DA7218_AGS_ATT_MAX_MAX,
745 DA7218_NO_INVERT, da7218_ags_att_max_tlv),
746 SOC_SINGLE("AGS Anticlip Switch", DA7218_AGS_ANTICLIP_CTRL,
747 DA7218_AGS_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
748 DA7218_NO_INVERT),
749 SOC_SINGLE("AGS Channel1 Switch", DA7218_AGS_ENABLE,
750 DA7218_AGS_ENABLE_CHAN1_SHIFT, DA7218_SWITCH_EN_MAX,
751 DA7218_NO_INVERT),
752 SOC_SINGLE("AGS Channel2 Switch", DA7218_AGS_ENABLE,
753 DA7218_AGS_ENABLE_CHAN2_SHIFT, DA7218_SWITCH_EN_MAX,
754 DA7218_NO_INVERT),
755
756 /* ALC */
757 SOC_ENUM("ALC Attack Rate", da7218_alc_attack_rate),
758 SOC_ENUM("ALC Release Rate", da7218_alc_release_rate),
759 SOC_ENUM("ALC Hold Time", da7218_alc_hold_time),
760 SOC_SINGLE_TLV("ALC Noise Threshold", DA7218_ALC_NOISE,
761 DA7218_ALC_NOISE_SHIFT, DA7218_ALC_THRESHOLD_MAX,
762 DA7218_INVERT, da7218_alc_threshold_tlv),
763 SOC_SINGLE_TLV("ALC Min Threshold", DA7218_ALC_TARGET_MIN,
764 DA7218_ALC_THRESHOLD_MIN_SHIFT, DA7218_ALC_THRESHOLD_MAX,
765 DA7218_INVERT, da7218_alc_threshold_tlv),
766 SOC_SINGLE_TLV("ALC Max Threshold", DA7218_ALC_TARGET_MAX,
767 DA7218_ALC_THRESHOLD_MAX_SHIFT, DA7218_ALC_THRESHOLD_MAX,
768 DA7218_INVERT, da7218_alc_threshold_tlv),
769 SOC_SINGLE_TLV("ALC Max Attenuation", DA7218_ALC_GAIN_LIMITS,
770 DA7218_ALC_ATTEN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,
771 DA7218_NO_INVERT, da7218_alc_gain_tlv),
772 SOC_SINGLE_TLV("ALC Max Gain", DA7218_ALC_GAIN_LIMITS,
773 DA7218_ALC_GAIN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,
774 DA7218_NO_INVERT, da7218_alc_gain_tlv),
775 SOC_SINGLE_RANGE_TLV("ALC Min Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,
776 DA7218_ALC_ANA_GAIN_MIN_SHIFT,
777 DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,
778 DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),
779 SOC_SINGLE_RANGE_TLV("ALC Max Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,
780 DA7218_ALC_ANA_GAIN_MAX_SHIFT,
781 DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,
782 DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),
783 SOC_ENUM("ALC Anticlip Step", da7218_alc_anticlip_step),
784 SOC_SINGLE("ALC Anticlip Switch", DA7218_ALC_ANTICLIP_CTRL,
785 DA7218_ALC_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
786 DA7218_NO_INVERT),
787 SOC_DOUBLE_EXT("ALC Channel1 Switch", DA7218_ALC_CTRL1,
788 DA7218_ALC_CHAN1_L_EN_SHIFT, DA7218_ALC_CHAN1_R_EN_SHIFT,
789 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,
790 snd_soc_get_volsw, da7218_alc_sw_put),
791 SOC_DOUBLE_EXT("ALC Channel2 Switch", DA7218_ALC_CTRL1,
792 DA7218_ALC_CHAN2_L_EN_SHIFT, DA7218_ALC_CHAN2_R_EN_SHIFT,
793 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,
794 snd_soc_get_volsw, da7218_alc_sw_put),
795
796 /* Envelope Tracking */
797 SOC_ENUM("Envelope Tracking Attack Rate", da7218_integ_attack_rate),
798 SOC_ENUM("Envelope Tracking Release Rate", da7218_integ_release_rate),
799
800 /* Input High-Pass Filters */
801 SOC_ENUM("In Filter1 HPF Mode", da7218_in1_hpf_mode),
802 SOC_ENUM("In Filter1 HPF Corner Audio", da7218_in1_audio_hpf_corner),
803 SOC_ENUM("In Filter1 HPF Corner Voice", da7218_in1_voice_hpf_corner),
804 SOC_ENUM("In Filter2 HPF Mode", da7218_in2_hpf_mode),
805 SOC_ENUM("In Filter2 HPF Corner Audio", da7218_in2_audio_hpf_corner),
806 SOC_ENUM("In Filter2 HPF Corner Voice", da7218_in2_voice_hpf_corner),
807
808 /* Mic Level Detect */
809 SOC_DOUBLE_EXT("Mic Level Detect Channel1 Switch", DA7218_LVL_DET_CTRL,
810 DA7218_LVL_DET_EN_CHAN1L_SHIFT,
811 DA7218_LVL_DET_EN_CHAN1R_SHIFT, DA7218_SWITCH_EN_MAX,
812 DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,
813 da7218_mic_lvl_det_sw_put),
814 SOC_DOUBLE_EXT("Mic Level Detect Channel2 Switch", DA7218_LVL_DET_CTRL,
815 DA7218_LVL_DET_EN_CHAN2L_SHIFT,
816 DA7218_LVL_DET_EN_CHAN2R_SHIFT, DA7218_SWITCH_EN_MAX,
817 DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,
818 da7218_mic_lvl_det_sw_put),
819 SOC_SINGLE("Mic Level Detect Level", DA7218_LVL_DET_LEVEL,
820 DA7218_LVL_DET_LEVEL_SHIFT, DA7218_LVL_DET_LEVEL_MAX,
821 DA7218_NO_INVERT),
822
823 /* Digital Mixer (Input) */
824 SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIL Volume",
825 DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN,
826 DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT,
827 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
828 da7218_dmix_gain_tlv),
829 SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIR Volume",
830 DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN,
831 DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT,
832 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
833 da7218_dmix_gain_tlv),
834 SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIL Volume",
835 DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN,
836 DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT,
837 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
838 da7218_dmix_gain_tlv),
839 SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIR Volume",
840 DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN,
841 DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT,
842 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
843 da7218_dmix_gain_tlv),
844
845 SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIL Volume",
846 DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN,
847 DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT,
848 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
849 da7218_dmix_gain_tlv),
850 SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIR Volume",
851 DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN,
852 DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT,
853 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
854 da7218_dmix_gain_tlv),
855 SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIL Volume",
856 DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN,
857 DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT,
858 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
859 da7218_dmix_gain_tlv),
860 SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIR Volume",
861 DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN,
862 DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT,
863 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
864 da7218_dmix_gain_tlv),
865
866 SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIL Volume",
867 DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN,
868 DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT,
869 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
870 da7218_dmix_gain_tlv),
871 SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIR Volume",
872 DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN,
873 DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT,
874 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
875 da7218_dmix_gain_tlv),
876 SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIL Volume",
877 DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN,
878 DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT,
879 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
880 da7218_dmix_gain_tlv),
881 SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIR Volume",
882 DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN,
883 DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT,
884 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
885 da7218_dmix_gain_tlv),
886
887 SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIL Volume",
888 DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN,
889 DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT,
890 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
891 da7218_dmix_gain_tlv),
892 SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIR Volume",
893 DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN,
894 DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT,
895 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
896 da7218_dmix_gain_tlv),
897 SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIL Volume",
898 DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN,
899 DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT,
900 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
901 da7218_dmix_gain_tlv),
902 SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIR Volume",
903 DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN,
904 DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT,
905 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
906 da7218_dmix_gain_tlv),
907
908 SOC_SINGLE_TLV("DMix ToneGen Out1 DAIL Volume",
909 DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN,
910 DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT,
911 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
912 da7218_dmix_gain_tlv),
913 SOC_SINGLE_TLV("DMix ToneGen Out1 DAIR Volume",
914 DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN,
915 DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT,
916 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
917 da7218_dmix_gain_tlv),
918 SOC_SINGLE_TLV("DMix ToneGen Out2 DAIL Volume",
919 DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN,
920 DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT,
921 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
922 da7218_dmix_gain_tlv),
923 SOC_SINGLE_TLV("DMix ToneGen Out2 DAIR Volume",
924 DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN,
925 DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT,
926 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
927 da7218_dmix_gain_tlv),
928
929 SOC_SINGLE_TLV("DMix In DAIL Out1 DAIL Volume",
930 DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN,
931 DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT,
932 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
933 da7218_dmix_gain_tlv),
934 SOC_SINGLE_TLV("DMix In DAIL Out1 DAIR Volume",
935 DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN,
936 DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT,
937 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
938 da7218_dmix_gain_tlv),
939 SOC_SINGLE_TLV("DMix In DAIL Out2 DAIL Volume",
940 DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN,
941 DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT,
942 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
943 da7218_dmix_gain_tlv),
944 SOC_SINGLE_TLV("DMix In DAIL Out2 DAIR Volume",
945 DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN,
946 DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT,
947 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
948 da7218_dmix_gain_tlv),
949
950 SOC_SINGLE_TLV("DMix In DAIR Out1 DAIL Volume",
951 DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN,
952 DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT,
953 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
954 da7218_dmix_gain_tlv),
955 SOC_SINGLE_TLV("DMix In DAIR Out1 DAIR Volume",
956 DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN,
957 DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT,
958 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
959 da7218_dmix_gain_tlv),
960 SOC_SINGLE_TLV("DMix In DAIR Out2 DAIL Volume",
961 DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN,
962 DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT,
963 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
964 da7218_dmix_gain_tlv),
965 SOC_SINGLE_TLV("DMix In DAIR Out2 DAIR Volume",
966 DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN,
967 DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT,
968 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
969 da7218_dmix_gain_tlv),
970
971 /* Digital Mixer (Output) */
972 SOC_SINGLE_TLV("DMix In Filter1L Out FilterL Volume",
973 DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN,
974 DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT,
975 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
976 da7218_dmix_gain_tlv),
977 SOC_SINGLE_TLV("DMix In Filter1L Out FilterR Volume",
978 DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN,
979 DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT,
980 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
981 da7218_dmix_gain_tlv),
982
983 SOC_SINGLE_TLV("DMix In Filter1R Out FilterL Volume",
984 DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN,
985 DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT,
986 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
987 da7218_dmix_gain_tlv),
988 SOC_SINGLE_TLV("DMix In Filter1R Out FilterR Volume",
989 DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN,
990 DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT,
991 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
992 da7218_dmix_gain_tlv),
993
994 SOC_SINGLE_TLV("DMix In Filter2L Out FilterL Volume",
995 DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN,
996 DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT,
997 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
998 da7218_dmix_gain_tlv),
999 SOC_SINGLE_TLV("DMix In Filter2L Out FilterR Volume",
1000 DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN,
1001 DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT,
1002 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1003 da7218_dmix_gain_tlv),
1004
1005 SOC_SINGLE_TLV("DMix In Filter2R Out FilterL Volume",
1006 DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN,
1007 DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT,
1008 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1009 da7218_dmix_gain_tlv),
1010 SOC_SINGLE_TLV("DMix In Filter2R Out FilterR Volume",
1011 DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN,
1012 DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT,
1013 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1014 da7218_dmix_gain_tlv),
1015
1016 SOC_SINGLE_TLV("DMix ToneGen Out FilterL Volume",
1017 DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN,
1018 DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT,
1019 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1020 da7218_dmix_gain_tlv),
1021 SOC_SINGLE_TLV("DMix ToneGen Out FilterR Volume",
1022 DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN,
1023 DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT,
1024 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1025 da7218_dmix_gain_tlv),
1026
1027 SOC_SINGLE_TLV("DMix In DAIL Out FilterL Volume",
1028 DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN,
1029 DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT,
1030 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1031 da7218_dmix_gain_tlv),
1032 SOC_SINGLE_TLV("DMix In DAIL Out FilterR Volume",
1033 DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN,
1034 DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT,
1035 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1036 da7218_dmix_gain_tlv),
1037
1038 SOC_SINGLE_TLV("DMix In DAIR Out FilterL Volume",
1039 DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN,
1040 DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT,
1041 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1042 da7218_dmix_gain_tlv),
1043 SOC_SINGLE_TLV("DMix In DAIR Out FilterR Volume",
1044 DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN,
1045 DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT,
1046 DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,
1047 da7218_dmix_gain_tlv),
1048
1049 /* Sidetone Filter */
1050 SND_SOC_BYTES_EXT("Sidetone BiQuad Coefficients",
1051 DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE,
1052 da7218_biquad_coeff_get, da7218_biquad_coeff_put),
1053 SOC_SINGLE_TLV("Sidetone Volume", DA7218_SIDETONE_GAIN,
1054 DA7218_SIDETONE_GAIN_SHIFT, DA7218_DMIX_GAIN_MAX,
1055 DA7218_NO_INVERT, da7218_dmix_gain_tlv),
1056 SOC_SINGLE("Sidetone Switch", DA7218_SIDETONE_CTRL,
1057 DA7218_SIDETONE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1058 DA7218_INVERT),
1059
1060 /* Tone Generator */
1061 SOC_ENUM("ToneGen DTMF Key", da7218_tonegen_dtmf_key),
1062 SOC_SINGLE("ToneGen DTMF Switch", DA7218_TONE_GEN_CFG1,
1063 DA7218_DTMF_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1064 DA7218_NO_INVERT),
1065 SOC_ENUM("ToneGen Sinewave Gen Type", da7218_tonegen_swg_sel),
1066 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7218_TONE_GEN_FREQ1_L,
1067 DA7218_FREQ1_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,
1068 da7218_tonegen_freq_get, da7218_tonegen_freq_put),
1069 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7218_TONE_GEN_FREQ2_L,
1070 DA7218_FREQ2_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,
1071 da7218_tonegen_freq_get, da7218_tonegen_freq_put),
1072 SOC_SINGLE("ToneGen On Time", DA7218_TONE_GEN_ON_PER,
1073 DA7218_BEEP_ON_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,
1074 DA7218_NO_INVERT),
1075 SOC_SINGLE("ToneGen Off Time", DA7218_TONE_GEN_OFF_PER,
1076 DA7218_BEEP_OFF_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,
1077 DA7218_NO_INVERT),
1078
1079 /* Gain ramping */
1080 SOC_ENUM("Gain Ramp Rate", da7218_gain_ramp_rate),
1081
1082 /* DGS */
1083 SOC_SINGLE_TLV("DGS Trigger", DA7218_DGS_TRIGGER,
1084 DA7218_DGS_TRIGGER_LVL_SHIFT, DA7218_DGS_TRIGGER_MAX,
1085 DA7218_INVERT, da7218_dgs_trigger_tlv),
1086 SOC_ENUM("DGS Rise Coefficient", da7218_dgs_rise_coeff),
1087 SOC_ENUM("DGS Fall Coefficient", da7218_dgs_fall_coeff),
1088 SOC_SINGLE("DGS Sync Delay", DA7218_DGS_SYNC_DELAY,
1089 DA7218_DGS_SYNC_DELAY_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,
1090 DA7218_NO_INVERT),
1091 SOC_SINGLE("DGS Fast SR Sync Delay", DA7218_DGS_SYNC_DELAY2,
1092 DA7218_DGS_SYNC_DELAY2_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,
1093 DA7218_NO_INVERT),
1094 SOC_SINGLE("DGS Voice Filter Sync Delay", DA7218_DGS_SYNC_DELAY3,
1095 DA7218_DGS_SYNC_DELAY3_SHIFT, DA7218_DGS_SYNC_DELAY3_MAX,
1096 DA7218_NO_INVERT),
1097 SOC_SINGLE_TLV("DGS Anticlip Level", DA7218_DGS_LEVELS,
1098 DA7218_DGS_ANTICLIP_LVL_SHIFT,
1099 DA7218_DGS_ANTICLIP_LVL_MAX, DA7218_INVERT,
1100 da7218_dgs_anticlip_tlv),
1101 SOC_SINGLE_TLV("DGS Signal Level", DA7218_DGS_LEVELS,
1102 DA7218_DGS_SIGNAL_LVL_SHIFT, DA7218_DGS_SIGNAL_LVL_MAX,
1103 DA7218_INVERT, da7218_dgs_signal_tlv),
1104 SOC_SINGLE("DGS Gain Subrange Switch", DA7218_DGS_GAIN_CTRL,
1105 DA7218_DGS_SUBR_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1106 DA7218_NO_INVERT),
1107 SOC_SINGLE("DGS Gain Ramp Switch", DA7218_DGS_GAIN_CTRL,
1108 DA7218_DGS_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1109 DA7218_NO_INVERT),
1110 SOC_SINGLE("DGS Gain Steps", DA7218_DGS_GAIN_CTRL,
1111 DA7218_DGS_STEPS_SHIFT, DA7218_DGS_STEPS_MAX,
1112 DA7218_NO_INVERT),
1113 SOC_DOUBLE("DGS Switch", DA7218_DGS_ENABLE, DA7218_DGS_ENABLE_L_SHIFT,
1114 DA7218_DGS_ENABLE_R_SHIFT, DA7218_SWITCH_EN_MAX,
1115 DA7218_NO_INVERT),
1116
1117 /* Output High-Pass Filter */
1118 SOC_ENUM("Out Filter HPF Mode", da7218_out1_hpf_mode),
1119 SOC_ENUM("Out Filter HPF Corner Audio", da7218_out1_audio_hpf_corner),
1120 SOC_ENUM("Out Filter HPF Corner Voice", da7218_out1_voice_hpf_corner),
1121
1122 /* 5-Band Equaliser */
1123 SOC_SINGLE_TLV("Out EQ Band1 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,
1124 DA7218_OUT_1_EQ_BAND1_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1125 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1126 SOC_SINGLE_TLV("Out EQ Band2 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,
1127 DA7218_OUT_1_EQ_BAND2_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1128 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1129 SOC_SINGLE_TLV("Out EQ Band3 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,
1130 DA7218_OUT_1_EQ_BAND3_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1131 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1132 SOC_SINGLE_TLV("Out EQ Band4 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,
1133 DA7218_OUT_1_EQ_BAND4_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1134 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1135 SOC_SINGLE_TLV("Out EQ Band5 Volume", DA7218_OUT_1_EQ_5_FILTER_CTRL,
1136 DA7218_OUT_1_EQ_BAND5_SHIFT, DA7218_OUT_EQ_BAND_MAX,
1137 DA7218_NO_INVERT, da7218_out_eq_band_tlv),
1138 SOC_SINGLE("Out EQ Switch", DA7218_OUT_1_EQ_5_FILTER_CTRL,
1139 DA7218_OUT_1_EQ_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1140 DA7218_NO_INVERT),
1141
1142 /* BiQuad Filters */
1143 SND_SOC_BYTES_EXT("BiQuad Coefficients",
1144 DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE,
1145 da7218_biquad_coeff_get, da7218_biquad_coeff_put),
1146 SOC_SINGLE("BiQuad Filter Switch", DA7218_OUT_1_BIQ_5STAGE_CTRL,
1147 DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1148 DA7218_INVERT),
1149
1150 /* Output Filters */
1151 SOC_DOUBLE_R_RANGE_TLV("Out Filter Volume", DA7218_OUT_1L_GAIN,
1152 DA7218_OUT_1R_GAIN,
1153 DA7218_OUT_1L_DIGITAL_GAIN_SHIFT,
1154 DA7218_OUT_DIGITAL_GAIN_MIN,
1155 DA7218_OUT_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,
1156 da7218_out_dig_gain_tlv),
1157 SOC_DOUBLE_R("Out Filter Switch", DA7218_OUT_1L_FILTER_CTRL,
1158 DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_MUTE_EN_SHIFT,
1159 DA7218_SWITCH_EN_MAX, DA7218_INVERT),
1160 SOC_DOUBLE_R("Out Filter Gain Subrange Switch",
1161 DA7218_OUT_1L_FILTER_CTRL, DA7218_OUT_1R_FILTER_CTRL,
1162 DA7218_OUT_1L_SUBRANGE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1163 DA7218_NO_INVERT),
1164 SOC_DOUBLE_R("Out Filter Gain Ramp Switch", DA7218_OUT_1L_FILTER_CTRL,
1165 DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_RAMP_EN_SHIFT,
1166 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1167
1168 /* Mixer Output */
1169 SOC_DOUBLE_R_RANGE_TLV("Mixout Volume", DA7218_MIXOUT_L_GAIN,
1170 DA7218_MIXOUT_R_GAIN,
1171 DA7218_MIXOUT_L_AMP_GAIN_SHIFT,
1172 DA7218_MIXOUT_AMP_GAIN_MIN,
1173 DA7218_MIXOUT_AMP_GAIN_MAX, DA7218_NO_INVERT,
1174 da7218_mixout_gain_tlv),
1175
1176 /* DAC Noise Gate */
1177 SOC_ENUM("DAC NG Setup Time", da7218_dac_ng_setup_time),
1178 SOC_ENUM("DAC NG Rampup Rate", da7218_dac_ng_rampup_rate),
1179 SOC_ENUM("DAC NG Rampdown Rate", da7218_dac_ng_rampdown_rate),
1180 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7218_DAC_NG_OFF_THRESH,
1181 DA7218_DAC_NG_OFF_THRESHOLD_SHIFT,
1182 DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,
1183 da7218_dac_ng_threshold_tlv),
1184 SOC_SINGLE_TLV("DAC NG On Threshold", DA7218_DAC_NG_ON_THRESH,
1185 DA7218_DAC_NG_ON_THRESHOLD_SHIFT,
1186 DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,
1187 da7218_dac_ng_threshold_tlv),
1188 SOC_SINGLE("DAC NG Switch", DA7218_DAC_NG_CTRL, DA7218_DAC_NG_EN_SHIFT,
1189 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1190
1191 /* CP */
1192 SOC_ENUM("Charge Pump Track Mode", da7218_cp_mchange),
1193 SOC_ENUM("Charge Pump Frequency", da7218_cp_fcontrol),
1194 SOC_ENUM("Charge Pump Decay Rate", da7218_cp_tau_delay),
1195 SOC_SINGLE("Charge Pump Threshold", DA7218_CP_VOL_THRESHOLD1,
1196 DA7218_CP_THRESH_VDD2_SHIFT, DA7218_CP_THRESH_VDD2_MAX,
1197 DA7218_NO_INVERT),
1198
1199 /* Headphones */
1200 SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", DA7218_HP_L_GAIN,
1201 DA7218_HP_R_GAIN, DA7218_HP_L_AMP_GAIN_SHIFT,
1202 DA7218_HP_AMP_GAIN_MIN, DA7218_HP_AMP_GAIN_MAX,
1203 DA7218_NO_INVERT, da7218_hp_gain_tlv),
1204 SOC_DOUBLE_R("Headphone Switch", DA7218_HP_L_CTRL, DA7218_HP_R_CTRL,
1205 DA7218_HP_L_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,
1206 DA7218_INVERT),
1207 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7218_HP_L_CTRL,
1208 DA7218_HP_R_CTRL, DA7218_HP_L_AMP_RAMP_EN_SHIFT,
1209 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1210 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7218_HP_L_CTRL,
1211 DA7218_HP_R_CTRL, DA7218_HP_L_AMP_ZC_EN_SHIFT,
1212 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),
1213};
1214
1215
1216/*
1217 * DAPM Mux Controls
1218 */
1219
1220static const char * const da7218_mic_sel_text[] = { "Analog", "Digital" };
1221
1222static const struct soc_enum da7218_mic1_sel =
1223 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),
1224 da7218_mic_sel_text);
1225
1226static const struct snd_kcontrol_new da7218_mic1_sel_mux =
1227 SOC_DAPM_ENUM("Mic1 Mux", da7218_mic1_sel);
1228
1229static const struct soc_enum da7218_mic2_sel =
1230 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),
1231 da7218_mic_sel_text);
1232
1233static const struct snd_kcontrol_new da7218_mic2_sel_mux =
1234 SOC_DAPM_ENUM("Mic2 Mux", da7218_mic2_sel);
1235
1236static const char * const da7218_sidetone_in_sel_txt[] = {
1237 "In Filter1L", "In Filter1R", "In Filter2L", "In Filter2R"
1238};
1239
1240static const struct soc_enum da7218_sidetone_in_sel =
1241 SOC_ENUM_SINGLE(DA7218_SIDETONE_IN_SELECT,
1242 DA7218_SIDETONE_IN_SELECT_SHIFT,
1243 DA7218_SIDETONE_IN_SELECT_MAX,
1244 da7218_sidetone_in_sel_txt);
1245
1246static const struct snd_kcontrol_new da7218_sidetone_in_sel_mux =
1247 SOC_DAPM_ENUM("Sidetone Mux", da7218_sidetone_in_sel);
1248
1249static const char * const da7218_out_filt_biq_sel_txt[] = {
1250 "Bypass", "Enabled"
1251};
1252
1253static const struct soc_enum da7218_out_filtl_biq_sel =
1254 SOC_ENUM_SINGLE(DA7218_OUT_1L_FILTER_CTRL,
1255 DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT,
1256 DA7218_OUT_BIQ_5STAGE_SEL_MAX,
1257 da7218_out_filt_biq_sel_txt);
1258
1259static const struct snd_kcontrol_new da7218_out_filtl_biq_sel_mux =
1260 SOC_DAPM_ENUM("Out FilterL BiQuad Mux", da7218_out_filtl_biq_sel);
1261
1262static const struct soc_enum da7218_out_filtr_biq_sel =
1263 SOC_ENUM_SINGLE(DA7218_OUT_1R_FILTER_CTRL,
1264 DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT,
1265 DA7218_OUT_BIQ_5STAGE_SEL_MAX,
1266 da7218_out_filt_biq_sel_txt);
1267
1268static const struct snd_kcontrol_new da7218_out_filtr_biq_sel_mux =
1269 SOC_DAPM_ENUM("Out FilterR BiQuad Mux", da7218_out_filtr_biq_sel);
1270
1271
1272/*
1273 * DAPM Mixer Controls
1274 */
1275
1276#define DA7218_DMIX_CTRLS(reg) \
1277 SOC_DAPM_SINGLE("In Filter1L Switch", reg, \
1278 DA7218_DMIX_SRC_INFILT1L, \
1279 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1280 SOC_DAPM_SINGLE("In Filter1R Switch", reg, \
1281 DA7218_DMIX_SRC_INFILT1R, \
1282 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1283 SOC_DAPM_SINGLE("In Filter2L Switch", reg, \
1284 DA7218_DMIX_SRC_INFILT2L, \
1285 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1286 SOC_DAPM_SINGLE("In Filter2R Switch", reg, \
1287 DA7218_DMIX_SRC_INFILT2R, \
1288 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1289 SOC_DAPM_SINGLE("ToneGen Switch", reg, \
1290 DA7218_DMIX_SRC_TONEGEN, \
1291 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1292 SOC_DAPM_SINGLE("DAIL Switch", reg, DA7218_DMIX_SRC_DAIL, \
1293 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1294 SOC_DAPM_SINGLE("DAIR Switch", reg, DA7218_DMIX_SRC_DAIR, \
1295 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT)
1296
1297static const struct snd_kcontrol_new da7218_out_dai1l_mix_controls[] = {
1298 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1L),
1299};
1300
1301static const struct snd_kcontrol_new da7218_out_dai1r_mix_controls[] = {
1302 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1R),
1303};
1304
1305static const struct snd_kcontrol_new da7218_out_dai2l_mix_controls[] = {
1306 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2L),
1307};
1308
1309static const struct snd_kcontrol_new da7218_out_dai2r_mix_controls[] = {
1310 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2R),
1311};
1312
1313static const struct snd_kcontrol_new da7218_out_filtl_mix_controls[] = {
1314 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1L),
1315};
1316
1317static const struct snd_kcontrol_new da7218_out_filtr_mix_controls[] = {
1318 DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1R),
1319};
1320
1321#define DA7218_DMIX_ST_CTRLS(reg) \
1322 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \
1323 DA7218_DMIX_ST_SRC_OUTFILT1L, \
1324 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1325 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \
1326 DA7218_DMIX_ST_SRC_OUTFILT1R, \
1327 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \
1328 SOC_DAPM_SINGLE("Sidetone Switch", reg, \
1329 DA7218_DMIX_ST_SRC_SIDETONE, \
1330 DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT) \
1331
1332static const struct snd_kcontrol_new da7218_st_out_filtl_mix_controls[] = {
1333 DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1L),
1334};
1335
1336static const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = {
1337 DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1R),
1338};
1339
1340
1341/*
1342 * DAPM Events
1343 */
1344
1345/*
1346 * We keep track of which input filters are enabled. This is used in the logic
1347 * for controlling the mic level detect feature.
1348 */
1349static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,
1350 struct snd_kcontrol *kcontrol, int event)
1351{
1352 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1353 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1354 u8 mask;
1355
1356 switch (w->reg) {
1357 case DA7218_IN_1L_FILTER_CTRL:
1358 mask = (1 << DA7218_LVL_DET_EN_CHAN1L_SHIFT);
1359 break;
1360 case DA7218_IN_1R_FILTER_CTRL:
1361 mask = (1 << DA7218_LVL_DET_EN_CHAN1R_SHIFT);
1362 break;
1363 case DA7218_IN_2L_FILTER_CTRL:
1364 mask = (1 << DA7218_LVL_DET_EN_CHAN2L_SHIFT);
1365 break;
1366 case DA7218_IN_2R_FILTER_CTRL:
1367 mask = (1 << DA7218_LVL_DET_EN_CHAN2R_SHIFT);
1368 break;
1369 default:
1370 return -EINVAL;
1371 }
1372
1373 switch (event) {
1374 case SND_SOC_DAPM_POST_PMU:
1375 da7218->in_filt_en |= mask;
1376 /*
1377 * If we're enabling path for mic level detect, wait for path
1378 * to settle before enabling feature to avoid incorrect and
1379 * unwanted detect events.
1380 */
1381 if (mask & da7218->mic_lvl_det_en)
1382 msleep(DA7218_MIC_LVL_DET_DELAY);
1383 break;
1384 case SND_SOC_DAPM_PRE_PMD:
1385 da7218->in_filt_en &= ~mask;
1386 break;
1387 default:
1388 return -EINVAL;
1389 }
1390
1391 /* Enable configured level detection paths */
1392 snd_soc_write(codec, DA7218_LVL_DET_CTRL,
1393 (da7218->in_filt_en & da7218->mic_lvl_det_en));
1394
1395 return 0;
1396}
1397
1398static int da7218_dai_event(struct snd_soc_dapm_widget *w,
1399 struct snd_kcontrol *kcontrol, int event)
1400{
1401 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1402 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1403 u8 pll_ctrl, pll_status, refosc_cal;
1404 int i;
1405 bool success;
1406
1407 switch (event) {
1408 case SND_SOC_DAPM_POST_PMU:
1409 if (da7218->master)
1410 /* Enable DAI clks for master mode */
1411 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
1412 DA7218_DAI_CLK_EN_MASK,
1413 DA7218_DAI_CLK_EN_MASK);
1414
1415 /* Tune reference oscillator */
1416 snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
1417 DA7218_PLL_REFOSC_CAL_START_MASK);
1418 snd_soc_write(codec, DA7218_PLL_REFOSC_CAL,
1419 DA7218_PLL_REFOSC_CAL_START_MASK |
1420 DA7218_PLL_REFOSC_CAL_EN_MASK);
1421
1422 /* Check tuning complete */
1423 i = 0;
1424 success = false;
1425 do {
1426 refosc_cal = snd_soc_read(codec, DA7218_PLL_REFOSC_CAL);
1427 if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) {
1428 success = true;
1429 } else {
1430 ++i;
1431 usleep_range(DA7218_REF_OSC_CHECK_DELAY_MIN,
1432 DA7218_REF_OSC_CHECK_DELAY_MAX);
1433 }
1434 } while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success));
1435
1436 if (!success)
1437 dev_warn(codec->dev,
1438 "Reference oscillator failed calibration\n");
1439
1440 /* PC synchronised to DAI */
1441 snd_soc_write(codec, DA7218_PC_COUNT,
1442 DA7218_PC_RESYNC_AUTO_MASK);
1443
1444 /* If SRM not enabled, we don't need to check status */
1445 pll_ctrl = snd_soc_read(codec, DA7218_PLL_CTRL);
1446 if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM)
1447 return 0;
1448
1449 /* Check SRM has locked */
1450 i = 0;
1451 success = false;
1452 do {
1453 pll_status = snd_soc_read(codec, DA7218_PLL_STATUS);
1454 if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) {
1455 success = true;
1456 } else {
1457 ++i;
1458 msleep(DA7218_SRM_CHECK_DELAY);
1459 }
1460 } while ((i < DA7218_SRM_CHECK_TRIES) & (!success));
1461
1462 if (!success)
1463 dev_warn(codec->dev, "SRM failed to lock\n");
1464
1465 return 0;
1466 case SND_SOC_DAPM_POST_PMD:
1467 /* PC free-running */
1468 snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
1469
1470 if (da7218->master)
1471 /* Disable DAI clks for master mode */
1472 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
1473 DA7218_DAI_CLK_EN_MASK, 0);
1474
1475 return 0;
1476 default:
1477 return -EINVAL;
1478 }
1479}
1480
1481static int da7218_cp_event(struct snd_soc_dapm_widget *w,
1482 struct snd_kcontrol *kcontrol, int event)
1483{
1484 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1485 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1486
1487 /*
1488 * If this is DA7217 and we're using single supply for differential
1489 * output, we really don't want to touch the charge pump.
1490 */
1491 if (da7218->hp_single_supply)
1492 return 0;
1493
1494 switch (event) {
1495 case SND_SOC_DAPM_PRE_PMU:
1496 snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
1497 DA7218_CP_EN_MASK);
1498 return 0;
1499 case SND_SOC_DAPM_PRE_PMD:
1500 snd_soc_update_bits(codec, DA7218_CP_CTRL, DA7218_CP_EN_MASK,
1501 0);
1502 return 0;
1503 default:
1504 return -EINVAL;
1505 }
1506}
1507
1508static int da7218_hp_pga_event(struct snd_soc_dapm_widget *w,
1509 struct snd_kcontrol *kcontrol, int event)
1510{
1511 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1512
1513 switch (event) {
1514 case SND_SOC_DAPM_POST_PMU:
1515 /* Enable headphone output */
1516 snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK,
1517 DA7218_HP_AMP_OE_MASK);
1518 return 0;
1519 case SND_SOC_DAPM_PRE_PMD:
1520 /* Headphone output high impedance */
1521 snd_soc_update_bits(codec, w->reg, DA7218_HP_AMP_OE_MASK, 0);
1522 return 0;
1523 default:
1524 return -EINVAL;
1525 }
1526}
1527
1528
1529/*
1530 * DAPM Widgets
1531 */
1532
1533static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {
1534 /* Input Supplies */
1535 SND_SOC_DAPM_SUPPLY("Mic Bias1", DA7218_MICBIAS_EN,
1536 DA7218_MICBIAS_1_EN_SHIFT, DA7218_NO_INVERT,
1537 NULL, 0),
1538 SND_SOC_DAPM_SUPPLY("Mic Bias2", DA7218_MICBIAS_EN,
1539 DA7218_MICBIAS_2_EN_SHIFT, DA7218_NO_INVERT,
1540 NULL, 0),
1541 SND_SOC_DAPM_SUPPLY("DMic1 Left", DA7218_DMIC_1_CTRL,
1542 DA7218_DMIC_1L_EN_SHIFT, DA7218_NO_INVERT,
1543 NULL, 0),
1544 SND_SOC_DAPM_SUPPLY("DMic1 Right", DA7218_DMIC_1_CTRL,
1545 DA7218_DMIC_1R_EN_SHIFT, DA7218_NO_INVERT,
1546 NULL, 0),
1547 SND_SOC_DAPM_SUPPLY("DMic2 Left", DA7218_DMIC_2_CTRL,
1548 DA7218_DMIC_2L_EN_SHIFT, DA7218_NO_INVERT,
1549 NULL, 0),
1550 SND_SOC_DAPM_SUPPLY("DMic2 Right", DA7218_DMIC_2_CTRL,
1551 DA7218_DMIC_2R_EN_SHIFT, DA7218_NO_INVERT,
1552 NULL, 0),
1553
1554 /* Inputs */
1555 SND_SOC_DAPM_INPUT("MIC1"),
1556 SND_SOC_DAPM_INPUT("MIC2"),
1557 SND_SOC_DAPM_INPUT("DMIC1L"),
1558 SND_SOC_DAPM_INPUT("DMIC1R"),
1559 SND_SOC_DAPM_INPUT("DMIC2L"),
1560 SND_SOC_DAPM_INPUT("DMIC2R"),
1561
1562 /* Input Mixer Supplies */
1563 SND_SOC_DAPM_SUPPLY("Mixin1 Supply", DA7218_MIXIN_1_CTRL,
1564 DA7218_MIXIN_1_MIX_SEL_SHIFT, DA7218_NO_INVERT,
1565 NULL, 0),
1566 SND_SOC_DAPM_SUPPLY("Mixin2 Supply", DA7218_MIXIN_2_CTRL,
1567 DA7218_MIXIN_2_MIX_SEL_SHIFT, DA7218_NO_INVERT,
1568 NULL, 0),
1569
1570 /* Input PGAs */
1571 SND_SOC_DAPM_PGA("Mic1 PGA", DA7218_MIC_1_CTRL,
1572 DA7218_MIC_1_AMP_EN_SHIFT, DA7218_NO_INVERT,
1573 NULL, 0),
1574 SND_SOC_DAPM_PGA("Mic2 PGA", DA7218_MIC_2_CTRL,
1575 DA7218_MIC_2_AMP_EN_SHIFT, DA7218_NO_INVERT,
1576 NULL, 0),
1577 SND_SOC_DAPM_PGA("Mixin1 PGA", DA7218_MIXIN_1_CTRL,
1578 DA7218_MIXIN_1_AMP_EN_SHIFT, DA7218_NO_INVERT,
1579 NULL, 0),
1580 SND_SOC_DAPM_PGA("Mixin2 PGA", DA7218_MIXIN_2_CTRL,
1581 DA7218_MIXIN_2_AMP_EN_SHIFT, DA7218_NO_INVERT,
1582 NULL, 0),
1583
1584 /* Mic/DMic Muxes */
1585 SND_SOC_DAPM_MUX("Mic1 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic1_sel_mux),
1586 SND_SOC_DAPM_MUX("Mic2 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic2_sel_mux),
1587
1588 /* Input Filters */
1589 SND_SOC_DAPM_ADC_E("In Filter1L", NULL, DA7218_IN_1L_FILTER_CTRL,
1590 DA7218_IN_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1591 da7218_in_filter_event,
1592 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1593 SND_SOC_DAPM_ADC_E("In Filter1R", NULL, DA7218_IN_1R_FILTER_CTRL,
1594 DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1595 da7218_in_filter_event,
1596 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1597 SND_SOC_DAPM_ADC_E("In Filter2L", NULL, DA7218_IN_2L_FILTER_CTRL,
1598 DA7218_IN_2L_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1599 da7218_in_filter_event,
1600 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1601 SND_SOC_DAPM_ADC_E("In Filter2R", NULL, DA7218_IN_2R_FILTER_CTRL,
1602 DA7218_IN_2R_FILTER_EN_SHIFT, DA7218_NO_INVERT,
1603 da7218_in_filter_event,
1604 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1605
1606 /* Tone Generator */
1607 SND_SOC_DAPM_SIGGEN("TONE"),
1608 SND_SOC_DAPM_PGA("Tone Generator", DA7218_TONE_GEN_CFG1,
1609 DA7218_START_STOPN_SHIFT, DA7218_NO_INVERT, NULL, 0),
1610
1611 /* Sidetone Input */
1612 SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
1613 &da7218_sidetone_in_sel_mux),
1614 SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7218_SIDETONE_CTRL,
1615 DA7218_SIDETONE_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1616
1617 /* Input Mixers */
1618 SND_SOC_DAPM_MIXER("Mixer DAI1L", SND_SOC_NOPM, 0, 0,
1619 da7218_out_dai1l_mix_controls,
1620 ARRAY_SIZE(da7218_out_dai1l_mix_controls)),
1621 SND_SOC_DAPM_MIXER("Mixer DAI1R", SND_SOC_NOPM, 0, 0,
1622 da7218_out_dai1r_mix_controls,
1623 ARRAY_SIZE(da7218_out_dai1r_mix_controls)),
1624 SND_SOC_DAPM_MIXER("Mixer DAI2L", SND_SOC_NOPM, 0, 0,
1625 da7218_out_dai2l_mix_controls,
1626 ARRAY_SIZE(da7218_out_dai2l_mix_controls)),
1627 SND_SOC_DAPM_MIXER("Mixer DAI2R", SND_SOC_NOPM, 0, 0,
1628 da7218_out_dai2r_mix_controls,
1629 ARRAY_SIZE(da7218_out_dai2r_mix_controls)),
1630
1631 /* DAI Supply */
1632 SND_SOC_DAPM_SUPPLY("DAI", DA7218_DAI_CTRL, DA7218_DAI_EN_SHIFT,
1633 DA7218_NO_INVERT, da7218_dai_event,
1634 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1635
1636 /* DAI */
1637 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
1638 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
1639
1640 /* Output Mixers */
1641 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
1642 da7218_out_filtl_mix_controls,
1643 ARRAY_SIZE(da7218_out_filtl_mix_controls)),
1644 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
1645 da7218_out_filtr_mix_controls,
1646 ARRAY_SIZE(da7218_out_filtr_mix_controls)),
1647
1648 /* BiQuad Filters */
1649 SND_SOC_DAPM_MUX("Out FilterL BiQuad Mux", SND_SOC_NOPM, 0, 0,
1650 &da7218_out_filtl_biq_sel_mux),
1651 SND_SOC_DAPM_MUX("Out FilterR BiQuad Mux", SND_SOC_NOPM, 0, 0,
1652 &da7218_out_filtr_biq_sel_mux),
1653 SND_SOC_DAPM_DAC("BiQuad Filter", NULL, DA7218_OUT_1_BIQ_5STAGE_CTRL,
1654 DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT,
1655 DA7218_NO_INVERT),
1656
1657 /* Sidetone Mixers */
1658 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
1659 da7218_st_out_filtl_mix_controls,
1660 ARRAY_SIZE(da7218_st_out_filtl_mix_controls)),
1661 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
1662 da7218_st_out_filtr_mix_controls,
1663 ARRAY_SIZE(da7218_st_out_filtr_mix_controls)),
1664
1665 /* Output Filters */
1666 SND_SOC_DAPM_DAC("Out FilterL", NULL, DA7218_OUT_1L_FILTER_CTRL,
1667 DA7218_OUT_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1668 SND_SOC_DAPM_DAC("Out FilterR", NULL, DA7218_OUT_1R_FILTER_CTRL,
1669 DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT),
1670
1671 /* Output PGAs */
1672 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7218_MIXOUT_L_CTRL,
1673 DA7218_MIXOUT_L_AMP_EN_SHIFT, DA7218_NO_INVERT,
1674 NULL, 0),
1675 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7218_MIXOUT_R_CTRL,
1676 DA7218_MIXOUT_R_AMP_EN_SHIFT, DA7218_NO_INVERT,
1677 NULL, 0),
1678 SND_SOC_DAPM_PGA_E("Headphone Left PGA", DA7218_HP_L_CTRL,
1679 DA7218_HP_L_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,
1680 da7218_hp_pga_event,
1681 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1682 SND_SOC_DAPM_PGA_E("Headphone Right PGA", DA7218_HP_R_CTRL,
1683 DA7218_HP_R_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,
1684 da7218_hp_pga_event,
1685 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1686
1687 /* Output Supplies */
1688 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, da7218_cp_event,
1689 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1690
1691 /* Outputs */
1692 SND_SOC_DAPM_OUTPUT("HPL"),
1693 SND_SOC_DAPM_OUTPUT("HPR"),
1694};
1695
1696
1697/*
1698 * DAPM Mixer Routes
1699 */
1700
1701#define DA7218_DMIX_ROUTES(name) \
1702 {name, "In Filter1L Switch", "In Filter1L"}, \
1703 {name, "In Filter1R Switch", "In Filter1R"}, \
1704 {name, "In Filter2L Switch", "In Filter2L"}, \
1705 {name, "In Filter2R Switch", "In Filter2R"}, \
1706 {name, "ToneGen Switch", "Tone Generator"}, \
1707 {name, "DAIL Switch", "DAIIN"}, \
1708 {name, "DAIR Switch", "DAIIN"}
1709
1710#define DA7218_DMIX_ST_ROUTES(name) \
1711 {name, "Out FilterL Switch", "Out FilterL BiQuad Mux"}, \
1712 {name, "Out FilterR Switch", "Out FilterR BiQuad Mux"}, \
1713 {name, "Sidetone Switch", "Sidetone Filter"}
1714
1715
1716/*
1717 * DAPM audio route definition
1718 */
1719
1720static const struct snd_soc_dapm_route da7218_audio_map[] = {
1721 /* Input paths */
1722 {"MIC1", NULL, "Mic Bias1"},
1723 {"MIC2", NULL, "Mic Bias2"},
1724 {"DMIC1L", NULL, "Mic Bias1"},
1725 {"DMIC1L", NULL, "DMic1 Left"},
1726 {"DMIC1R", NULL, "Mic Bias1"},
1727 {"DMIC1R", NULL, "DMic1 Right"},
1728 {"DMIC2L", NULL, "Mic Bias2"},
1729 {"DMIC2L", NULL, "DMic2 Left"},
1730 {"DMIC2R", NULL, "Mic Bias2"},
1731 {"DMIC2R", NULL, "DMic2 Right"},
1732
1733 {"Mic1 PGA", NULL, "MIC1"},
1734 {"Mic2 PGA", NULL, "MIC2"},
1735
1736 {"Mixin1 PGA", NULL, "Mixin1 Supply"},
1737 {"Mixin2 PGA", NULL, "Mixin2 Supply"},
1738
1739 {"Mixin1 PGA", NULL, "Mic1 PGA"},
1740 {"Mixin2 PGA", NULL, "Mic2 PGA"},
1741
1742 {"Mic1 Mux", "Analog", "Mixin1 PGA"},
1743 {"Mic1 Mux", "Digital", "DMIC1L"},
1744 {"Mic1 Mux", "Digital", "DMIC1R"},
1745 {"Mic2 Mux", "Analog", "Mixin2 PGA"},
1746 {"Mic2 Mux", "Digital", "DMIC2L"},
1747 {"Mic2 Mux", "Digital", "DMIC2R"},
1748
1749 {"In Filter1L", NULL, "Mic1 Mux"},
1750 {"In Filter1R", NULL, "Mic1 Mux"},
1751 {"In Filter2L", NULL, "Mic2 Mux"},
1752 {"In Filter2R", NULL, "Mic2 Mux"},
1753
1754 {"Tone Generator", NULL, "TONE"},
1755
1756 {"Sidetone Mux", "In Filter1L", "In Filter1L"},
1757 {"Sidetone Mux", "In Filter1R", "In Filter1R"},
1758 {"Sidetone Mux", "In Filter2L", "In Filter2L"},
1759 {"Sidetone Mux", "In Filter2R", "In Filter2R"},
1760 {"Sidetone Filter", NULL, "Sidetone Mux"},
1761
1762 DA7218_DMIX_ROUTES("Mixer DAI1L"),
1763 DA7218_DMIX_ROUTES("Mixer DAI1R"),
1764 DA7218_DMIX_ROUTES("Mixer DAI2L"),
1765 DA7218_DMIX_ROUTES("Mixer DAI2R"),
1766
1767 {"DAIOUT", NULL, "Mixer DAI1L"},
1768 {"DAIOUT", NULL, "Mixer DAI1R"},
1769 {"DAIOUT", NULL, "Mixer DAI2L"},
1770 {"DAIOUT", NULL, "Mixer DAI2R"},
1771
1772 {"DAIOUT", NULL, "DAI"},
1773
1774 /* Output paths */
1775 {"DAIIN", NULL, "DAI"},
1776
1777 DA7218_DMIX_ROUTES("Mixer Out FilterL"),
1778 DA7218_DMIX_ROUTES("Mixer Out FilterR"),
1779
1780 {"BiQuad Filter", NULL, "Mixer Out FilterL"},
1781 {"BiQuad Filter", NULL, "Mixer Out FilterR"},
1782
1783 {"Out FilterL BiQuad Mux", "Bypass", "Mixer Out FilterL"},
1784 {"Out FilterL BiQuad Mux", "Enabled", "BiQuad Filter"},
1785 {"Out FilterR BiQuad Mux", "Bypass", "Mixer Out FilterR"},
1786 {"Out FilterR BiQuad Mux", "Enabled", "BiQuad Filter"},
1787
1788 DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterL"),
1789 DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterR"),
1790
1791 {"Out FilterL", NULL, "ST Mixer Out FilterL"},
1792 {"Out FilterR", NULL, "ST Mixer Out FilterR"},
1793
1794 {"Mixout Left PGA", NULL, "Out FilterL"},
1795 {"Mixout Right PGA", NULL, "Out FilterR"},
1796
1797 {"Headphone Left PGA", NULL, "Mixout Left PGA"},
1798 {"Headphone Right PGA", NULL, "Mixout Right PGA"},
1799
1800 {"HPL", NULL, "Headphone Left PGA"},
1801 {"HPR", NULL, "Headphone Right PGA"},
1802
1803 {"HPL", NULL, "Charge Pump"},
1804 {"HPR", NULL, "Charge Pump"},
1805};
1806
1807
1808/*
1809 * DAI operations
1810 */
1811
1812static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1813 int clk_id, unsigned int freq, int dir)
1814{
1815 struct snd_soc_codec *codec = codec_dai->codec;
1816 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1817 int ret;
1818
1819 if (da7218->mclk_rate == freq)
1820 return 0;
1821
1822 if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
1823 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1824 freq);
1825 return -EINVAL;
1826 }
1827
1828 switch (clk_id) {
1829 case DA7218_CLKSRC_MCLK_SQR:
1830 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1831 DA7218_PLL_MCLK_SQR_EN_MASK,
1832 DA7218_PLL_MCLK_SQR_EN_MASK);
1833 break;
1834 case DA7218_CLKSRC_MCLK:
1835 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1836 DA7218_PLL_MCLK_SQR_EN_MASK, 0);
1837 break;
1838 default:
1839 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1840 return -EINVAL;
1841 }
1842
1843 if (da7218->mclk) {
1844 freq = clk_round_rate(da7218->mclk, freq);
1845 ret = clk_set_rate(da7218->mclk, freq);
1846 if (ret) {
1847 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1848 freq);
1849 return ret;
1850 }
1851 }
1852
1853 da7218->mclk_rate = freq;
1854
1855 return 0;
1856}
1857
1858static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1859 int source, unsigned int fref, unsigned int fout)
1860{
1861 struct snd_soc_codec *codec = codec_dai->codec;
1862 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1863
1864 u8 pll_ctrl, indiv_bits, indiv;
1865 u8 pll_frac_top, pll_frac_bot, pll_integer;
1866 u32 freq_ref;
1867 u64 frac_div;
1868
1869 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
1870 if (da7218->mclk_rate == 32768) {
1871 indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
1872 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1873 } else if (da7218->mclk_rate < 2000000) {
1874 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1875 da7218->mclk_rate);
1876 return -EINVAL;
1877 } else if (da7218->mclk_rate <= 5000000) {
1878 indiv_bits = DA7218_PLL_INDIV_2_5_MHZ;
1879 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1880 } else if (da7218->mclk_rate <= 10000000) {
1881 indiv_bits = DA7218_PLL_INDIV_5_10_MHZ;
1882 indiv = DA7218_PLL_INDIV_2_10_MHZ_VAL;
1883 } else if (da7218->mclk_rate <= 20000000) {
1884 indiv_bits = DA7218_PLL_INDIV_10_20_MHZ;
1885 indiv = DA7218_PLL_INDIV_10_20_MHZ_VAL;
1886 } else if (da7218->mclk_rate <= 40000000) {
1887 indiv_bits = DA7218_PLL_INDIV_20_40_MHZ;
1888 indiv = DA7218_PLL_INDIV_20_40_MHZ_VAL;
1889 } else if (da7218->mclk_rate <= 54000000) {
1890 indiv_bits = DA7218_PLL_INDIV_40_54_MHZ;
1891 indiv = DA7218_PLL_INDIV_40_54_MHZ_VAL;
1892 } else {
1893 dev_err(codec->dev, "PLL input clock %d above valid range\n",
1894 da7218->mclk_rate);
1895 return -EINVAL;
1896 }
1897 freq_ref = (da7218->mclk_rate / indiv);
1898 pll_ctrl = indiv_bits;
1899
1900 /* Configure PLL */
1901 switch (source) {
1902 case DA7218_SYSCLK_MCLK:
1903 pll_ctrl |= DA7218_PLL_MODE_BYPASS;
1904 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1905 DA7218_PLL_INDIV_MASK |
1906 DA7218_PLL_MODE_MASK, pll_ctrl);
1907 return 0;
1908 case DA7218_SYSCLK_PLL:
1909 pll_ctrl |= DA7218_PLL_MODE_NORMAL;
1910 break;
1911 case DA7218_SYSCLK_PLL_SRM:
1912 pll_ctrl |= DA7218_PLL_MODE_SRM;
1913 break;
1914 case DA7218_SYSCLK_PLL_32KHZ:
1915 pll_ctrl |= DA7218_PLL_MODE_32KHZ;
1916 break;
1917 default:
1918 dev_err(codec->dev, "Invalid PLL config\n");
1919 return -EINVAL;
1920 }
1921
1922 /* Calculate dividers for PLL */
1923 pll_integer = fout / freq_ref;
1924 frac_div = (u64)(fout % freq_ref) * 8192ULL;
1925 do_div(frac_div, freq_ref);
1926 pll_frac_top = (frac_div >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK;
1927 pll_frac_bot = (frac_div) & DA7218_BYTE_MASK;
1928
1929 /* Write PLL config & dividers */
1930 snd_soc_write(codec, DA7218_PLL_FRAC_TOP, pll_frac_top);
1931 snd_soc_write(codec, DA7218_PLL_FRAC_BOT, pll_frac_bot);
1932 snd_soc_write(codec, DA7218_PLL_INTEGER, pll_integer);
1933 snd_soc_update_bits(codec, DA7218_PLL_CTRL,
1934 DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK,
1935 pll_ctrl);
1936
1937 return 0;
1938}
1939
1940static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1941{
1942 struct snd_soc_codec *codec = codec_dai->codec;
1943 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
1944 u8 dai_clk_mode = 0, dai_ctrl = 0;
1945
1946 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1947 case SND_SOC_DAIFMT_CBM_CFM:
1948 da7218->master = true;
1949 break;
1950 case SND_SOC_DAIFMT_CBS_CFS:
1951 da7218->master = false;
1952 break;
1953 default:
1954 return -EINVAL;
1955 }
1956
1957 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1958 case SND_SOC_DAIFMT_NB_NF:
1959 break;
1960 case SND_SOC_DAIFMT_NB_IF:
1961 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV;
1962 break;
1963 case SND_SOC_DAIFMT_IB_NF:
1964 dai_clk_mode |= DA7218_DAI_CLK_POL_INV;
1965 break;
1966 case SND_SOC_DAIFMT_IB_IF:
1967 dai_clk_mode |= DA7218_DAI_WCLK_POL_INV | DA7218_DAI_CLK_POL_INV;
1968 break;
1969 default:
1970 return -EINVAL;
1971 }
1972
1973 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1974 case SND_SOC_DAIFMT_I2S:
1975 dai_ctrl |= DA7218_DAI_FORMAT_I2S;
1976 break;
1977 case SND_SOC_DAIFMT_LEFT_J:
1978 dai_ctrl |= DA7218_DAI_FORMAT_LEFT_J;
1979 break;
1980 case SND_SOC_DAIFMT_RIGHT_J:
1981 dai_ctrl |= DA7218_DAI_FORMAT_RIGHT_J;
1982 break;
1983 case SND_SOC_DAIFMT_DSP_B:
1984 dai_ctrl |= DA7218_DAI_FORMAT_DSP;
1985 break;
1986 default:
1987 return -EINVAL;
1988 }
1989
1990 /* By default 64 BCLKs per WCLK is supported */
1991 dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64;
1992
1993 snd_soc_write(codec, DA7218_DAI_CLK_MODE, dai_clk_mode);
1994 snd_soc_update_bits(codec, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,
1995 dai_ctrl);
1996
1997 return 0;
1998}
1999
2000static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,
2001 unsigned int tx_mask, unsigned int rx_mask,
2002 int slots, int slot_width)
2003{
2004 struct snd_soc_codec *codec = dai->codec;
2005 u8 dai_bclks_per_wclk;
2006 u32 frame_size;
2007
2008 /* No channels enabled so disable TDM, revert to 64-bit frames */
2009 if (!tx_mask) {
2010 snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
2011 DA7218_DAI_TDM_CH_EN_MASK |
2012 DA7218_DAI_TDM_MODE_EN_MASK, 0);
2013 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
2014 DA7218_DAI_BCLKS_PER_WCLK_MASK,
2015 DA7218_DAI_BCLKS_PER_WCLK_64);
2016 return 0;
2017 }
2018
2019 /* Check we have valid slots */
2020 if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) {
2021 dev_err(codec->dev, "Invalid number of slots, max = %d\n",
2022 DA7218_DAI_TDM_MAX_SLOTS);
2023 return -EINVAL;
2024 }
2025
2026 /* Check we have a valid offset given (first 2 bytes of rx_mask) */
2027 if (rx_mask >> DA7218_2BYTE_SHIFT) {
2028 dev_err(codec->dev, "Invalid slot offset, max = %d\n",
2029 DA7218_2BYTE_MASK);
2030 return -EINVAL;
2031 }
2032
2033 /* Calculate & validate frame size based on slot info provided. */
2034 frame_size = slots * slot_width;
2035 switch (frame_size) {
2036 case 32:
2037 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_32;
2038 break;
2039 case 64:
2040 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_64;
2041 break;
2042 case 128:
2043 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_128;
2044 break;
2045 case 256:
2046 dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256;
2047 break;
2048 default:
2049 dev_err(codec->dev, "Invalid frame size\n");
2050 return -EINVAL;
2051 }
2052
2053 snd_soc_update_bits(codec, DA7218_DAI_CLK_MODE,
2054 DA7218_DAI_BCLKS_PER_WCLK_MASK,
2055 dai_bclks_per_wclk);
2056 snd_soc_write(codec, DA7218_DAI_OFFSET_LOWER,
2057 (rx_mask & DA7218_BYTE_MASK));
2058 snd_soc_write(codec, DA7218_DAI_OFFSET_UPPER,
2059 ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK));
2060 snd_soc_update_bits(codec, DA7218_DAI_TDM_CTRL,
2061 DA7218_DAI_TDM_CH_EN_MASK |
2062 DA7218_DAI_TDM_MODE_EN_MASK,
2063 (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) |
2064 DA7218_DAI_TDM_MODE_EN_MASK);
2065
2066 return 0;
2067}
2068
2069static int da7218_hw_params(struct snd_pcm_substream *substream,
2070 struct snd_pcm_hw_params *params,
2071 struct snd_soc_dai *dai)
2072{
2073 struct snd_soc_codec *codec = dai->codec;
2074 u8 dai_ctrl = 0, fs;
2075 unsigned int channels;
2076
2077 switch (params_width(params)) {
2078 case 16:
2079 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S16_LE;
2080 break;
2081 case 20:
2082 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S20_LE;
2083 break;
2084 case 24:
2085 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S24_LE;
2086 break;
2087 case 32:
2088 dai_ctrl |= DA7218_DAI_WORD_LENGTH_S32_LE;
2089 break;
2090 default:
2091 return -EINVAL;
2092 }
2093
2094 channels = params_channels(params);
2095 if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) {
2096 dev_err(codec->dev,
2097 "Invalid number of channels, only 1 to %d supported\n",
2098 DA7218_DAI_CH_NUM_MAX);
2099 return -EINVAL;
2100 }
2101 dai_ctrl |= channels << DA7218_DAI_CH_NUM_SHIFT;
2102
2103 switch (params_rate(params)) {
2104 case 8000:
2105 fs = DA7218_SR_8000;
2106 break;
2107 case 11025:
2108 fs = DA7218_SR_11025;
2109 break;
2110 case 12000:
2111 fs = DA7218_SR_12000;
2112 break;
2113 case 16000:
2114 fs = DA7218_SR_16000;
2115 break;
2116 case 22050:
2117 fs = DA7218_SR_22050;
2118 break;
2119 case 24000:
2120 fs = DA7218_SR_24000;
2121 break;
2122 case 32000:
2123 fs = DA7218_SR_32000;
2124 break;
2125 case 44100:
2126 fs = DA7218_SR_44100;
2127 break;
2128 case 48000:
2129 fs = DA7218_SR_48000;
2130 break;
2131 case 88200:
2132 fs = DA7218_SR_88200;
2133 break;
2134 case 96000:
2135 fs = DA7218_SR_96000;
2136 break;
2137 default:
2138 return -EINVAL;
2139 }
2140
2141 snd_soc_update_bits(codec, DA7218_DAI_CTRL,
2142 DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK,
2143 dai_ctrl);
2144 /* SRs tied for ADCs and DACs. */
2145 snd_soc_write(codec, DA7218_SR,
2146 (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT));
2147
2148 return 0;
2149}
2150
2151static const struct snd_soc_dai_ops da7218_dai_ops = {
2152 .hw_params = da7218_hw_params,
2153 .set_sysclk = da7218_set_dai_sysclk,
2154 .set_pll = da7218_set_dai_pll,
2155 .set_fmt = da7218_set_dai_fmt,
2156 .set_tdm_slot = da7218_set_dai_tdm_slot,
2157};
2158
2159#define DA7218_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2160 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2161
2162static struct snd_soc_dai_driver da7218_dai = {
2163 .name = "da7218-hifi",
2164 .playback = {
2165 .stream_name = "Playback",
2166 .channels_min = 1,
2167 .channels_max = 4, /* Only 2 channels of data */
2168 .rates = SNDRV_PCM_RATE_8000_96000,
2169 .formats = DA7218_FORMATS,
2170 },
2171 .capture = {
2172 .stream_name = "Capture",
2173 .channels_min = 1,
2174 .channels_max = 4,
2175 .rates = SNDRV_PCM_RATE_8000_96000,
2176 .formats = DA7218_FORMATS,
2177 },
2178 .ops = &da7218_dai_ops,
2179 .symmetric_rates = 1,
2180 .symmetric_channels = 1,
2181 .symmetric_samplebits = 1,
2182};
2183
2184
2185/*
2186 * HP Detect
2187 */
2188
2189int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2190{
2191 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2192
2193 if (da7218->dev_id == DA7217_DEV_ID)
2194 return -EINVAL;
2195
2196 da7218->jack = jack;
2197 snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
2198 DA7218_HPLDET_JACK_EN_MASK,
2199 jack ? DA7218_HPLDET_JACK_EN_MASK : 0);
2200
2201 return 0;
2202}
2203EXPORT_SYMBOL_GPL(da7218_hpldet);
2204
2205static void da7218_micldet_irq(struct snd_soc_codec *codec)
2206{
2207 char *envp[] = {
2208 "EVENT=MIC_LEVEL_DETECT",
2209 NULL,
2210 };
2211
2212 kobject_uevent_env(&codec->dev->kobj, KOBJ_CHANGE, envp);
2213}
2214
2215static void da7218_hpldet_irq(struct snd_soc_codec *codec)
2216{
2217 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2218 u8 jack_status;
2219 int report;
2220
2221 jack_status = snd_soc_read(codec, DA7218_EVENT_STATUS);
2222
2223 if (jack_status & DA7218_HPLDET_JACK_STS_MASK)
2224 report = SND_JACK_HEADPHONE;
2225 else
2226 report = 0;
2227
2228 snd_soc_jack_report(da7218->jack, report, SND_JACK_HEADPHONE);
2229}
2230
2231/*
2232 * IRQ
2233 */
2234
2235static irqreturn_t da7218_irq_thread(int irq, void *data)
2236{
2237 struct snd_soc_codec *codec = data;
2238 u8 status;
2239
2240 /* Read IRQ status reg */
2241 status = snd_soc_read(codec, DA7218_EVENT);
2242 if (!status)
2243 return IRQ_NONE;
2244
2245 /* Mic level detect */
2246 if (status & DA7218_LVL_DET_EVENT_MASK)
2247 da7218_micldet_irq(codec);
2248
2249 /* HP detect */
2250 if (status & DA7218_HPLDET_JACK_EVENT_MASK)
2251 da7218_hpldet_irq(codec);
2252
2253 /* Clear interrupts */
2254 snd_soc_write(codec, DA7218_EVENT, status);
2255
2256 return IRQ_HANDLED;
2257}
2258
2259/*
2260 * DT
2261 */
2262
2263static const struct of_device_id da7218_of_match[] = {
2264 { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID },
2265 { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID },
2266 { }
2267};
2268MODULE_DEVICE_TABLE(of, da7218_of_match);
2269
2270static inline int da7218_of_get_id(struct device *dev)
2271{
2272 const struct of_device_id *id = of_match_device(da7218_of_match, dev);
2273
2274 if (id)
2275 return (uintptr_t)id->data;
2276 else
2277 return -EINVAL;
2278}
2279
2280static enum da7218_micbias_voltage
2281 da7218_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
2282{
2283 switch (val) {
2284 case 1200:
2285 return DA7218_MICBIAS_1_2V;
2286 case 1600:
2287 return DA7218_MICBIAS_1_6V;
2288 case 1800:
2289 return DA7218_MICBIAS_1_8V;
2290 case 2000:
2291 return DA7218_MICBIAS_2_0V;
2292 case 2200:
2293 return DA7218_MICBIAS_2_2V;
2294 case 2400:
2295 return DA7218_MICBIAS_2_4V;
2296 case 2600:
2297 return DA7218_MICBIAS_2_6V;
2298 case 2800:
2299 return DA7218_MICBIAS_2_8V;
2300 case 3000:
2301 return DA7218_MICBIAS_3_0V;
2302 default:
2303 dev_warn(codec->dev, "Invalid micbias level");
2304 return DA7218_MICBIAS_1_6V;
2305 }
2306}
2307
2308static enum da7218_mic_amp_in_sel
2309 da7218_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
2310{
2311 if (!strcmp(str, "diff")) {
2312 return DA7218_MIC_AMP_IN_SEL_DIFF;
2313 } else if (!strcmp(str, "se_p")) {
2314 return DA7218_MIC_AMP_IN_SEL_SE_P;
2315 } else if (!strcmp(str, "se_n")) {
2316 return DA7218_MIC_AMP_IN_SEL_SE_N;
2317 } else {
2318 dev_warn(codec->dev, "Invalid mic input type selection");
2319 return DA7218_MIC_AMP_IN_SEL_DIFF;
2320 }
2321}
2322
2323static enum da7218_dmic_data_sel
2324 da7218_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
2325{
2326 if (!strcmp(str, "lrise_rfall")) {
2327 return DA7218_DMIC_DATA_LRISE_RFALL;
2328 } else if (!strcmp(str, "lfall_rrise")) {
2329 return DA7218_DMIC_DATA_LFALL_RRISE;
2330 } else {
2331 dev_warn(codec->dev, "Invalid DMIC data type selection");
2332 return DA7218_DMIC_DATA_LRISE_RFALL;
2333 }
2334}
2335
2336static enum da7218_dmic_samplephase
2337 da7218_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
2338{
2339 if (!strcmp(str, "on_clkedge")) {
2340 return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2341 } else if (!strcmp(str, "between_clkedge")) {
2342 return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE;
2343 } else {
2344 dev_warn(codec->dev, "Invalid DMIC sample phase");
2345 return DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2346 }
2347}
2348
2349static enum da7218_dmic_clk_rate
2350 da7218_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
2351{
2352 switch (val) {
2353 case 1500000:
2354 return DA7218_DMIC_CLK_1_5MHZ;
2355 case 3000000:
2356 return DA7218_DMIC_CLK_3_0MHZ;
2357 default:
2358 dev_warn(codec->dev, "Invalid DMIC clock rate");
2359 return DA7218_DMIC_CLK_3_0MHZ;
2360 }
2361}
2362
2363static enum da7218_hpldet_jack_rate
2364 da7218_of_jack_rate(struct snd_soc_codec *codec, u32 val)
2365{
2366 switch (val) {
2367 case 5:
2368 return DA7218_HPLDET_JACK_RATE_5US;
2369 case 10:
2370 return DA7218_HPLDET_JACK_RATE_10US;
2371 case 20:
2372 return DA7218_HPLDET_JACK_RATE_20US;
2373 case 40:
2374 return DA7218_HPLDET_JACK_RATE_40US;
2375 case 80:
2376 return DA7218_HPLDET_JACK_RATE_80US;
2377 case 160:
2378 return DA7218_HPLDET_JACK_RATE_160US;
2379 case 320:
2380 return DA7218_HPLDET_JACK_RATE_320US;
2381 case 640:
2382 return DA7218_HPLDET_JACK_RATE_640US;
2383 default:
2384 dev_warn(codec->dev, "Invalid jack detect rate");
2385 return DA7218_HPLDET_JACK_RATE_40US;
2386 }
2387}
2388
2389static enum da7218_hpldet_jack_debounce
2390 da7218_of_jack_debounce(struct snd_soc_codec *codec, u32 val)
2391{
2392 switch (val) {
2393 case 0:
2394 return DA7218_HPLDET_JACK_DEBOUNCE_OFF;
2395 case 2:
2396 return DA7218_HPLDET_JACK_DEBOUNCE_2;
2397 case 3:
2398 return DA7218_HPLDET_JACK_DEBOUNCE_3;
2399 case 4:
2400 return DA7218_HPLDET_JACK_DEBOUNCE_4;
2401 default:
2402 dev_warn(codec->dev, "Invalid jack debounce");
2403 return DA7218_HPLDET_JACK_DEBOUNCE_2;
2404 }
2405}
2406
2407static enum da7218_hpldet_jack_thr
2408 da7218_of_jack_thr(struct snd_soc_codec *codec, u32 val)
2409{
2410 switch (val) {
2411 case 84:
2412 return DA7218_HPLDET_JACK_THR_84PCT;
2413 case 88:
2414 return DA7218_HPLDET_JACK_THR_88PCT;
2415 case 92:
2416 return DA7218_HPLDET_JACK_THR_92PCT;
2417 case 96:
2418 return DA7218_HPLDET_JACK_THR_96PCT;
2419 default:
2420 dev_warn(codec->dev, "Invalid jack threshold level");
2421 return DA7218_HPLDET_JACK_THR_84PCT;
2422 }
2423}
2424
2425static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec)
2426{
2427 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2428 struct device_node *np = codec->dev->of_node;
2429 struct device_node *hpldet_np;
2430 struct da7218_pdata *pdata;
2431 struct da7218_hpldet_pdata *hpldet_pdata;
2432 const char *of_str;
2433 u32 of_val32;
2434
2435 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
2436 if (!pdata) {
2437 dev_warn(codec->dev, "Failed to allocate memory for pdata\n");
2438 return NULL;
2439 }
2440
2441 if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0)
2442 pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32);
2443 else
2444 pdata->micbias1_lvl = DA7218_MICBIAS_1_6V;
2445
2446 if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0)
2447 pdata->micbias2_lvl = da7218_of_micbias_lvl(codec, of_val32);
2448 else
2449 pdata->micbias2_lvl = DA7218_MICBIAS_1_6V;
2450
2451 if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str))
2452 pdata->mic1_amp_in_sel =
2453 da7218_of_mic_amp_in_sel(codec, of_str);
2454 else
2455 pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
2456
2457 if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str))
2458 pdata->mic2_amp_in_sel =
2459 da7218_of_mic_amp_in_sel(codec, of_str);
2460 else
2461 pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;
2462
2463 if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str))
2464 pdata->dmic1_data_sel = da7218_of_dmic_data_sel(codec, of_str);
2465 else
2466 pdata->dmic1_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
2467
2468 if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str))
2469 pdata->dmic1_samplephase =
2470 da7218_of_dmic_samplephase(codec, of_str);
2471 else
2472 pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2473
2474 if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0)
2475 pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
2476 else
2477 pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
2478
2479 if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str))
2480 pdata->dmic2_data_sel = da7218_of_dmic_data_sel(codec, of_str);
2481 else
2482 pdata->dmic2_data_sel = DA7218_DMIC_DATA_LRISE_RFALL;
2483
2484 if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str))
2485 pdata->dmic2_samplephase =
2486 da7218_of_dmic_samplephase(codec, of_str);
2487 else
2488 pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;
2489
2490 if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0)
2491 pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(codec, of_val32);
2492 else
2493 pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ;
2494
2495 if (da7218->dev_id == DA7217_DEV_ID) {
2496 if (of_property_read_bool(np, "dlg,hp-diff-single-supply"))
2497 pdata->hp_diff_single_supply = true;
2498 }
2499
2500 if (da7218->dev_id == DA7218_DEV_ID) {
2501 hpldet_np = of_find_node_by_name(np, "da7218_hpldet");
2502 if (!hpldet_np)
2503 return pdata;
2504
2505 hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata),
2506 GFP_KERNEL);
2507 if (!hpldet_pdata) {
2508 dev_warn(codec->dev,
2509 "Failed to allocate memory for hpldet pdata\n");
2510 of_node_put(hpldet_np);
2511 return pdata;
2512 }
2513 pdata->hpldet_pdata = hpldet_pdata;
2514
2515 if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us",
2516 &of_val32) >= 0)
2517 hpldet_pdata->jack_rate =
2518 da7218_of_jack_rate(codec, of_val32);
2519 else
2520 hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US;
2521
2522 if (of_property_read_u32(hpldet_np, "dlg,jack-debounce",
2523 &of_val32) >= 0)
2524 hpldet_pdata->jack_debounce =
2525 da7218_of_jack_debounce(codec, of_val32);
2526 else
2527 hpldet_pdata->jack_debounce =
2528 DA7218_HPLDET_JACK_DEBOUNCE_2;
2529
2530 if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct",
2531 &of_val32) >= 0)
2532 hpldet_pdata->jack_thr =
2533 da7218_of_jack_thr(codec, of_val32);
2534 else
2535 hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT;
2536
2537 if (of_property_read_bool(hpldet_np, "dlg,comp-inv"))
2538 hpldet_pdata->comp_inv = true;
2539
2540 if (of_property_read_bool(hpldet_np, "dlg,hyst"))
2541 hpldet_pdata->hyst = true;
2542
2543 if (of_property_read_bool(hpldet_np, "dlg,discharge"))
2544 hpldet_pdata->discharge = true;
2545
2546 of_node_put(hpldet_np);
2547 }
2548
2549 return pdata;
2550}
2551
2552
2553/*
2554 * Codec driver functions
2555 */
2556
2557static int da7218_set_bias_level(struct snd_soc_codec *codec,
2558 enum snd_soc_bias_level level)
2559{
2560 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2561 int ret;
2562
2563 switch (level) {
2564 case SND_SOC_BIAS_ON:
2565 case SND_SOC_BIAS_PREPARE:
2566 break;
2567 case SND_SOC_BIAS_STANDBY:
2568 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
2569 /* MCLK */
2570 if (da7218->mclk) {
2571 ret = clk_prepare_enable(da7218->mclk);
2572 if (ret) {
2573 dev_err(codec->dev,
2574 "Failed to enable mclk\n");
2575 return ret;
2576 }
2577 }
2578
2579 /* Master bias */
2580 snd_soc_update_bits(codec, DA7218_REFERENCES,
2581 DA7218_BIAS_EN_MASK,
2582 DA7218_BIAS_EN_MASK);
2583
2584 /* Internal LDO */
2585 snd_soc_update_bits(codec, DA7218_LDO_CTRL,
2586 DA7218_LDO_EN_MASK,
2587 DA7218_LDO_EN_MASK);
2588 }
2589 break;
2590 case SND_SOC_BIAS_OFF:
2591 /* Only disable if jack detection disabled */
2592 if (!da7218->jack) {
2593 /* Internal LDO */
2594 snd_soc_update_bits(codec, DA7218_LDO_CTRL,
2595 DA7218_LDO_EN_MASK, 0);
2596
2597 /* Master bias */
2598 snd_soc_update_bits(codec, DA7218_REFERENCES,
2599 DA7218_BIAS_EN_MASK, 0);
2600 }
2601
2602 /* MCLK */
2603 if (da7218->mclk)
2604 clk_disable_unprepare(da7218->mclk);
2605 break;
2606 }
2607
2608 return 0;
2609}
2610
2611static const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = {
2612 [DA7218_SUPPLY_VDD] = "VDD",
2613 [DA7218_SUPPLY_VDDMIC] = "VDDMIC",
2614 [DA7218_SUPPLY_VDDIO] = "VDDIO",
2615};
2616
2617static int da7218_handle_supplies(struct snd_soc_codec *codec)
2618{
2619 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2620 struct regulator *vddio;
2621 u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V;
2622 int i, ret;
2623
2624 /* Get required supplies */
2625 for (i = 0; i < DA7218_NUM_SUPPLIES; ++i)
2626 da7218->supplies[i].supply = da7218_supply_names[i];
2627
2628 ret = devm_regulator_bulk_get(codec->dev, DA7218_NUM_SUPPLIES,
2629 da7218->supplies);
2630 if (ret) {
2631 dev_err(codec->dev, "Failed to get supplies\n");
2632 return ret;
2633 }
2634
2635 /* Determine VDDIO voltage provided */
2636 vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer;
2637 ret = regulator_get_voltage(vddio);
2638 if (ret < 1500000)
2639 dev_warn(codec->dev, "Invalid VDDIO voltage\n");
2640 else if (ret < 2500000)
2641 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V;
2642
2643 /* Enable main supplies */
2644 ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies);
2645 if (ret) {
2646 dev_err(codec->dev, "Failed to enable supplies\n");
2647 return ret;
2648 }
2649
2650 /* Ensure device in active mode */
2651 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);
2652
2653 /* Update IO voltage level range */
2654 snd_soc_write(codec, DA7218_IO_CTRL, io_voltage_lvl);
2655
2656 return 0;
2657}
2658
2659static void da7218_handle_pdata(struct snd_soc_codec *codec)
2660{
2661 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2662 struct da7218_pdata *pdata = da7218->pdata;
2663
2664 if (pdata) {
2665 u8 micbias_lvl = 0, dmic_cfg = 0;
2666
2667 /* Mic Bias voltages */
2668 switch (pdata->micbias1_lvl) {
2669 case DA7218_MICBIAS_1_2V:
2670 micbias_lvl |= DA7218_MICBIAS_1_LP_MODE_MASK;
2671 break;
2672 case DA7218_MICBIAS_1_6V:
2673 case DA7218_MICBIAS_1_8V:
2674 case DA7218_MICBIAS_2_0V:
2675 case DA7218_MICBIAS_2_2V:
2676 case DA7218_MICBIAS_2_4V:
2677 case DA7218_MICBIAS_2_6V:
2678 case DA7218_MICBIAS_2_8V:
2679 case DA7218_MICBIAS_3_0V:
2680 micbias_lvl |= (pdata->micbias1_lvl <<
2681 DA7218_MICBIAS_1_LEVEL_SHIFT);
2682 break;
2683 }
2684
2685 switch (pdata->micbias2_lvl) {
2686 case DA7218_MICBIAS_1_2V:
2687 micbias_lvl |= DA7218_MICBIAS_2_LP_MODE_MASK;
2688 break;
2689 case DA7218_MICBIAS_1_6V:
2690 case DA7218_MICBIAS_1_8V:
2691 case DA7218_MICBIAS_2_0V:
2692 case DA7218_MICBIAS_2_2V:
2693 case DA7218_MICBIAS_2_4V:
2694 case DA7218_MICBIAS_2_6V:
2695 case DA7218_MICBIAS_2_8V:
2696 case DA7218_MICBIAS_3_0V:
2697 micbias_lvl |= (pdata->micbias2_lvl <<
2698 DA7218_MICBIAS_2_LEVEL_SHIFT);
2699 break;
2700 }
2701
2702 snd_soc_write(codec, DA7218_MICBIAS_CTRL, micbias_lvl);
2703
2704 /* Mic */
2705 switch (pdata->mic1_amp_in_sel) {
2706 case DA7218_MIC_AMP_IN_SEL_DIFF:
2707 case DA7218_MIC_AMP_IN_SEL_SE_P:
2708 case DA7218_MIC_AMP_IN_SEL_SE_N:
2709 snd_soc_write(codec, DA7218_MIC_1_SELECT,
2710 pdata->mic1_amp_in_sel);
2711 break;
2712 }
2713
2714 switch (pdata->mic2_amp_in_sel) {
2715 case DA7218_MIC_AMP_IN_SEL_DIFF:
2716 case DA7218_MIC_AMP_IN_SEL_SE_P:
2717 case DA7218_MIC_AMP_IN_SEL_SE_N:
2718 snd_soc_write(codec, DA7218_MIC_2_SELECT,
2719 pdata->mic2_amp_in_sel);
2720 break;
2721 }
2722
2723 /* DMic */
2724 switch (pdata->dmic1_data_sel) {
2725 case DA7218_DMIC_DATA_LFALL_RRISE:
2726 case DA7218_DMIC_DATA_LRISE_RFALL:
2727 dmic_cfg |= (pdata->dmic1_data_sel <<
2728 DA7218_DMIC_1_DATA_SEL_SHIFT);
2729 break;
2730 }
2731
2732 switch (pdata->dmic1_samplephase) {
2733 case DA7218_DMIC_SAMPLE_ON_CLKEDGE:
2734 case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:
2735 dmic_cfg |= (pdata->dmic1_samplephase <<
2736 DA7218_DMIC_1_SAMPLEPHASE_SHIFT);
2737 break;
2738 }
2739
2740 switch (pdata->dmic1_clk_rate) {
2741 case DA7218_DMIC_CLK_3_0MHZ:
2742 case DA7218_DMIC_CLK_1_5MHZ:
2743 dmic_cfg |= (pdata->dmic1_clk_rate <<
2744 DA7218_DMIC_1_CLK_RATE_SHIFT);
2745 break;
2746 }
2747
2748 snd_soc_update_bits(codec, DA7218_DMIC_1_CTRL,
2749 DA7218_DMIC_1_DATA_SEL_MASK |
2750 DA7218_DMIC_1_SAMPLEPHASE_MASK |
2751 DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg);
2752
2753 dmic_cfg = 0;
2754 switch (pdata->dmic2_data_sel) {
2755 case DA7218_DMIC_DATA_LFALL_RRISE:
2756 case DA7218_DMIC_DATA_LRISE_RFALL:
2757 dmic_cfg |= (pdata->dmic2_data_sel <<
2758 DA7218_DMIC_2_DATA_SEL_SHIFT);
2759 break;
2760 }
2761
2762 switch (pdata->dmic2_samplephase) {
2763 case DA7218_DMIC_SAMPLE_ON_CLKEDGE:
2764 case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:
2765 dmic_cfg |= (pdata->dmic2_samplephase <<
2766 DA7218_DMIC_2_SAMPLEPHASE_SHIFT);
2767 break;
2768 }
2769
2770 switch (pdata->dmic2_clk_rate) {
2771 case DA7218_DMIC_CLK_3_0MHZ:
2772 case DA7218_DMIC_CLK_1_5MHZ:
2773 dmic_cfg |= (pdata->dmic2_clk_rate <<
2774 DA7218_DMIC_2_CLK_RATE_SHIFT);
2775 break;
2776 }
2777
2778 snd_soc_update_bits(codec, DA7218_DMIC_2_CTRL,
2779 DA7218_DMIC_2_DATA_SEL_MASK |
2780 DA7218_DMIC_2_SAMPLEPHASE_MASK |
2781 DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg);
2782
2783 /* DA7217 Specific */
2784 if (da7218->dev_id == DA7217_DEV_ID) {
2785 da7218->hp_single_supply =
2786 pdata->hp_diff_single_supply;
2787
2788 if (da7218->hp_single_supply) {
2789 snd_soc_write(codec, DA7218_HP_DIFF_UNLOCK,
2790 DA7218_HP_DIFF_UNLOCK_VAL);
2791 snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
2792 DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK,
2793 DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK);
2794 }
2795 }
2796
2797 /* DA7218 Specific */
2798 if ((da7218->dev_id == DA7218_DEV_ID) &&
2799 (pdata->hpldet_pdata)) {
2800 struct da7218_hpldet_pdata *hpldet_pdata =
2801 pdata->hpldet_pdata;
2802 u8 hpldet_cfg = 0;
2803
2804 switch (hpldet_pdata->jack_rate) {
2805 case DA7218_HPLDET_JACK_RATE_5US:
2806 case DA7218_HPLDET_JACK_RATE_10US:
2807 case DA7218_HPLDET_JACK_RATE_20US:
2808 case DA7218_HPLDET_JACK_RATE_40US:
2809 case DA7218_HPLDET_JACK_RATE_80US:
2810 case DA7218_HPLDET_JACK_RATE_160US:
2811 case DA7218_HPLDET_JACK_RATE_320US:
2812 case DA7218_HPLDET_JACK_RATE_640US:
2813 hpldet_cfg |=
2814 (hpldet_pdata->jack_rate <<
2815 DA7218_HPLDET_JACK_RATE_SHIFT);
2816 break;
2817 }
2818
2819 switch (hpldet_pdata->jack_debounce) {
2820 case DA7218_HPLDET_JACK_DEBOUNCE_OFF:
2821 case DA7218_HPLDET_JACK_DEBOUNCE_2:
2822 case DA7218_HPLDET_JACK_DEBOUNCE_3:
2823 case DA7218_HPLDET_JACK_DEBOUNCE_4:
2824 hpldet_cfg |=
2825 (hpldet_pdata->jack_debounce <<
2826 DA7218_HPLDET_JACK_DEBOUNCE_SHIFT);
2827 break;
2828 }
2829
2830 switch (hpldet_pdata->jack_thr) {
2831 case DA7218_HPLDET_JACK_THR_84PCT:
2832 case DA7218_HPLDET_JACK_THR_88PCT:
2833 case DA7218_HPLDET_JACK_THR_92PCT:
2834 case DA7218_HPLDET_JACK_THR_96PCT:
2835 hpldet_cfg |=
2836 (hpldet_pdata->jack_thr <<
2837 DA7218_HPLDET_JACK_THR_SHIFT);
2838 break;
2839 }
2840 snd_soc_update_bits(codec, DA7218_HPLDET_JACK,
2841 DA7218_HPLDET_JACK_RATE_MASK |
2842 DA7218_HPLDET_JACK_DEBOUNCE_MASK |
2843 DA7218_HPLDET_JACK_THR_MASK,
2844 hpldet_cfg);
2845
2846 hpldet_cfg = 0;
2847 if (hpldet_pdata->comp_inv)
2848 hpldet_cfg |= DA7218_HPLDET_COMP_INV_MASK;
2849
2850 if (hpldet_pdata->hyst)
2851 hpldet_cfg |= DA7218_HPLDET_HYST_EN_MASK;
2852
2853 if (hpldet_pdata->discharge)
2854 hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK;
2855
2856 snd_soc_write(codec, DA7218_HPLDET_CTRL, hpldet_cfg);
2857 }
2858 }
2859}
2860
2861static int da7218_probe(struct snd_soc_codec *codec)
2862{
2863 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2864 int ret;
2865
2866 /* Regulator configuration */
2867 ret = da7218_handle_supplies(codec);
2868 if (ret)
2869 return ret;
2870
2871 /* Handle DT/Platform data */
2872 if (codec->dev->of_node)
2873 da7218->pdata = da7218_of_to_pdata(codec);
2874 else
2875 da7218->pdata = dev_get_platdata(codec->dev);
2876
2877 da7218_handle_pdata(codec);
2878
2879 /* Check if MCLK provided, if not the clock is NULL */
2880 da7218->mclk = devm_clk_get(codec->dev, "mclk");
2881 if (IS_ERR(da7218->mclk)) {
2882 if (PTR_ERR(da7218->mclk) != -ENOENT) {
2883 ret = PTR_ERR(da7218->mclk);
2884 goto err_disable_reg;
2885 } else {
2886 da7218->mclk = NULL;
2887 }
2888 }
2889
2890 /* Default PC to free-running */
2891 snd_soc_write(codec, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);
2892
2893 /*
2894 * Default Output Filter mixers to off otherwise DAPM will power
2895 * Mic to HP passthrough paths by default at startup.
2896 */
2897 snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1L, 0);
2898 snd_soc_write(codec, DA7218_DROUTING_OUTFILT_1R, 0);
2899
2900 /* Default CP to normal load, power mode */
2901 snd_soc_update_bits(codec, DA7218_CP_CTRL,
2902 DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0);
2903
2904 /* Default gain ramping */
2905 snd_soc_update_bits(codec, DA7218_MIXIN_1_CTRL,
2906 DA7218_MIXIN_1_AMP_RAMP_EN_MASK,
2907 DA7218_MIXIN_1_AMP_RAMP_EN_MASK);
2908 snd_soc_update_bits(codec, DA7218_MIXIN_2_CTRL,
2909 DA7218_MIXIN_2_AMP_RAMP_EN_MASK,
2910 DA7218_MIXIN_2_AMP_RAMP_EN_MASK);
2911 snd_soc_update_bits(codec, DA7218_IN_1L_FILTER_CTRL,
2912 DA7218_IN_1L_RAMP_EN_MASK,
2913 DA7218_IN_1L_RAMP_EN_MASK);
2914 snd_soc_update_bits(codec, DA7218_IN_1R_FILTER_CTRL,
2915 DA7218_IN_1R_RAMP_EN_MASK,
2916 DA7218_IN_1R_RAMP_EN_MASK);
2917 snd_soc_update_bits(codec, DA7218_IN_2L_FILTER_CTRL,
2918 DA7218_IN_2L_RAMP_EN_MASK,
2919 DA7218_IN_2L_RAMP_EN_MASK);
2920 snd_soc_update_bits(codec, DA7218_IN_2R_FILTER_CTRL,
2921 DA7218_IN_2R_RAMP_EN_MASK,
2922 DA7218_IN_2R_RAMP_EN_MASK);
2923 snd_soc_update_bits(codec, DA7218_DGS_GAIN_CTRL,
2924 DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK);
2925 snd_soc_update_bits(codec, DA7218_OUT_1L_FILTER_CTRL,
2926 DA7218_OUT_1L_RAMP_EN_MASK,
2927 DA7218_OUT_1L_RAMP_EN_MASK);
2928 snd_soc_update_bits(codec, DA7218_OUT_1R_FILTER_CTRL,
2929 DA7218_OUT_1R_RAMP_EN_MASK,
2930 DA7218_OUT_1R_RAMP_EN_MASK);
2931 snd_soc_update_bits(codec, DA7218_HP_L_CTRL,
2932 DA7218_HP_L_AMP_RAMP_EN_MASK,
2933 DA7218_HP_L_AMP_RAMP_EN_MASK);
2934 snd_soc_update_bits(codec, DA7218_HP_R_CTRL,
2935 DA7218_HP_R_AMP_RAMP_EN_MASK,
2936 DA7218_HP_R_AMP_RAMP_EN_MASK);
2937
2938 /* Default infinite tone gen, start/stop by Kcontrol */
2939 snd_soc_write(codec, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);
2940
2941 /* DA7217 specific config */
2942 if (da7218->dev_id == DA7217_DEV_ID) {
2943 snd_soc_update_bits(codec, DA7218_HP_DIFF_CTRL,
2944 DA7218_HP_AMP_DIFF_MODE_EN_MASK,
2945 DA7218_HP_AMP_DIFF_MODE_EN_MASK);
2946
2947 /* Only DA7218 supports HP detect, mask off for DA7217 */
2948 snd_soc_write(codec, DA7218_EVENT_MASK,
2949 DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK);
2950 }
2951
2952 if (da7218->irq) {
2953 ret = devm_request_threaded_irq(codec->dev, da7218->irq, NULL,
2954 da7218_irq_thread,
2955 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
2956 "da7218", codec);
2957 if (ret != 0) {
2958 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2959 da7218->irq, ret);
2960 goto err_disable_reg;
2961 }
2962
2963 }
2964
2965 return 0;
2966
2967err_disable_reg:
2968 regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
2969
2970 return ret;
2971}
2972
2973static int da7218_remove(struct snd_soc_codec *codec)
2974{
2975 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2976
2977 regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);
2978
2979 return 0;
2980}
2981
2982#ifdef CONFIG_PM
2983static int da7218_suspend(struct snd_soc_codec *codec)
2984{
2985 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2986
2987 da7218_set_bias_level(codec, SND_SOC_BIAS_OFF);
2988
2989 /* Put device into standby mode if jack detection disabled */
2990 if (!da7218->jack)
2991 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE, 0);
2992
2993 return 0;
2994}
2995
2996static int da7218_resume(struct snd_soc_codec *codec)
2997{
2998 struct da7218_priv *da7218 = snd_soc_codec_get_drvdata(codec);
2999
3000 /* Put device into active mode if previously moved to standby */
3001 if (!da7218->jack)
3002 snd_soc_write(codec, DA7218_SYSTEM_ACTIVE,
3003 DA7218_SYSTEM_ACTIVE_MASK);
3004
3005 da7218_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3006
3007 return 0;
3008}
3009#else
3010#define da7218_suspend NULL
3011#define da7218_resume NULL
3012#endif
3013
3014static struct snd_soc_codec_driver soc_codec_dev_da7218 = {
3015 .probe = da7218_probe,
3016 .remove = da7218_remove,
3017 .suspend = da7218_suspend,
3018 .resume = da7218_resume,
3019 .set_bias_level = da7218_set_bias_level,
3020
3021 .controls = da7218_snd_controls,
3022 .num_controls = ARRAY_SIZE(da7218_snd_controls),
3023
3024 .dapm_widgets = da7218_dapm_widgets,
3025 .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets),
3026 .dapm_routes = da7218_audio_map,
3027 .num_dapm_routes = ARRAY_SIZE(da7218_audio_map),
3028};
3029
3030
3031/*
3032 * Regmap configs
3033 */
3034
3035static struct reg_default da7218_reg_defaults[] = {
3036 { DA7218_SYSTEM_ACTIVE, 0x00 },
3037 { DA7218_CIF_CTRL, 0x00 },
3038 { DA7218_SPARE1, 0x00 },
3039 { DA7218_SR, 0xAA },
3040 { DA7218_PC_COUNT, 0x02 },
3041 { DA7218_GAIN_RAMP_CTRL, 0x00 },
3042 { DA7218_CIF_TIMEOUT_CTRL, 0x01 },
3043 { DA7218_SYSTEM_MODES_INPUT, 0x00 },
3044 { DA7218_SYSTEM_MODES_OUTPUT, 0x00 },
3045 { DA7218_IN_1L_FILTER_CTRL, 0x00 },
3046 { DA7218_IN_1R_FILTER_CTRL, 0x00 },
3047 { DA7218_IN_2L_FILTER_CTRL, 0x00 },
3048 { DA7218_IN_2R_FILTER_CTRL, 0x00 },
3049 { DA7218_OUT_1L_FILTER_CTRL, 0x40 },
3050 { DA7218_OUT_1R_FILTER_CTRL, 0x40 },
3051 { DA7218_OUT_1_HPF_FILTER_CTRL, 0x80 },
3052 { DA7218_OUT_1_EQ_12_FILTER_CTRL, 0x77 },
3053 { DA7218_OUT_1_EQ_34_FILTER_CTRL, 0x77 },
3054 { DA7218_OUT_1_EQ_5_FILTER_CTRL, 0x07 },
3055 { DA7218_OUT_1_BIQ_5STAGE_CTRL, 0x40 },
3056 { DA7218_OUT_1_BIQ_5STAGE_DATA, 0x00 },
3057 { DA7218_OUT_1_BIQ_5STAGE_ADDR, 0x00 },
3058 { DA7218_MIXIN_1_CTRL, 0x48 },
3059 { DA7218_MIXIN_1_GAIN, 0x03 },
3060 { DA7218_MIXIN_2_CTRL, 0x48 },
3061 { DA7218_MIXIN_2_GAIN, 0x03 },
3062 { DA7218_ALC_CTRL1, 0x00 },
3063 { DA7218_ALC_CTRL2, 0x00 },
3064 { DA7218_ALC_CTRL3, 0x00 },
3065 { DA7218_ALC_NOISE, 0x3F },
3066 { DA7218_ALC_TARGET_MIN, 0x3F },
3067 { DA7218_ALC_TARGET_MAX, 0x00 },
3068 { DA7218_ALC_GAIN_LIMITS, 0xFF },
3069 { DA7218_ALC_ANA_GAIN_LIMITS, 0x71 },
3070 { DA7218_ALC_ANTICLIP_CTRL, 0x00 },
3071 { DA7218_AGS_ENABLE, 0x00 },
3072 { DA7218_AGS_TRIGGER, 0x09 },
3073 { DA7218_AGS_ATT_MAX, 0x00 },
3074 { DA7218_AGS_TIMEOUT, 0x00 },
3075 { DA7218_AGS_ANTICLIP_CTRL, 0x00 },
3076 { DA7218_ENV_TRACK_CTRL, 0x00 },
3077 { DA7218_LVL_DET_CTRL, 0x00 },
3078 { DA7218_LVL_DET_LEVEL, 0x7F },
3079 { DA7218_DGS_TRIGGER, 0x24 },
3080 { DA7218_DGS_ENABLE, 0x00 },
3081 { DA7218_DGS_RISE_FALL, 0x50 },
3082 { DA7218_DGS_SYNC_DELAY, 0xA3 },
3083 { DA7218_DGS_SYNC_DELAY2, 0x31 },
3084 { DA7218_DGS_SYNC_DELAY3, 0x11 },
3085 { DA7218_DGS_LEVELS, 0x01 },
3086 { DA7218_DGS_GAIN_CTRL, 0x74 },
3087 { DA7218_DROUTING_OUTDAI_1L, 0x01 },
3088 { DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN, 0x1C },
3089 { DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN, 0x1C },
3090 { DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN, 0x1C },
3091 { DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN, 0x1C },
3092 { DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN, 0x1C },
3093 { DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN, 0x1C },
3094 { DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN, 0x1C },
3095 { DA7218_DROUTING_OUTDAI_1R, 0x04 },
3096 { DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN, 0x1C },
3097 { DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN, 0x1C },
3098 { DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN, 0x1C },
3099 { DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN, 0x1C },
3100 { DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN, 0x1C },
3101 { DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN, 0x1C },
3102 { DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN, 0x1C },
3103 { DA7218_DROUTING_OUTFILT_1L, 0x01 },
3104 { DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN, 0x1C },
3105 { DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN, 0x1C },
3106 { DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN, 0x1C },
3107 { DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN, 0x1C },
3108 { DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN, 0x1C },
3109 { DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN, 0x1C },
3110 { DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN, 0x1C },
3111 { DA7218_DROUTING_OUTFILT_1R, 0x04 },
3112 { DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN, 0x1C },
3113 { DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN, 0x1C },
3114 { DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN, 0x1C },
3115 { DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN, 0x1C },
3116 { DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN, 0x1C },
3117 { DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN, 0x1C },
3118 { DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN, 0x1C },
3119 { DA7218_DROUTING_OUTDAI_2L, 0x04 },
3120 { DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN, 0x1C },
3121 { DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN, 0x1C },
3122 { DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN, 0x1C },
3123 { DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN, 0x1C },
3124 { DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN, 0x1C },
3125 { DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN, 0x1C },
3126 { DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN, 0x1C },
3127 { DA7218_DROUTING_OUTDAI_2R, 0x08 },
3128 { DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN, 0x1C },
3129 { DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN, 0x1C },
3130 { DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN, 0x1C },
3131 { DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN, 0x1C },
3132 { DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN, 0x1C },
3133 { DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN, 0x1C },
3134 { DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN, 0x1C },
3135 { DA7218_DAI_CTRL, 0x28 },
3136 { DA7218_DAI_TDM_CTRL, 0x40 },
3137 { DA7218_DAI_OFFSET_LOWER, 0x00 },
3138 { DA7218_DAI_OFFSET_UPPER, 0x00 },
3139 { DA7218_DAI_CLK_MODE, 0x01 },
3140 { DA7218_PLL_CTRL, 0x04 },
3141 { DA7218_PLL_FRAC_TOP, 0x00 },
3142 { DA7218_PLL_FRAC_BOT, 0x00 },
3143 { DA7218_PLL_INTEGER, 0x20 },
3144 { DA7218_DAC_NG_CTRL, 0x00 },
3145 { DA7218_DAC_NG_SETUP_TIME, 0x00 },
3146 { DA7218_DAC_NG_OFF_THRESH, 0x00 },
3147 { DA7218_DAC_NG_ON_THRESH, 0x00 },
3148 { DA7218_TONE_GEN_CFG2, 0x00 },
3149 { DA7218_TONE_GEN_FREQ1_L, 0x55 },
3150 { DA7218_TONE_GEN_FREQ1_U, 0x15 },
3151 { DA7218_TONE_GEN_FREQ2_L, 0x00 },
3152 { DA7218_TONE_GEN_FREQ2_U, 0x40 },
3153 { DA7218_TONE_GEN_CYCLES, 0x00 },
3154 { DA7218_TONE_GEN_ON_PER, 0x02 },
3155 { DA7218_TONE_GEN_OFF_PER, 0x01 },
3156 { DA7218_CP_CTRL, 0x60 },
3157 { DA7218_CP_DELAY, 0x11 },
3158 { DA7218_CP_VOL_THRESHOLD1, 0x0E },
3159 { DA7218_MIC_1_CTRL, 0x40 },
3160 { DA7218_MIC_1_GAIN, 0x01 },
3161 { DA7218_MIC_1_SELECT, 0x00 },
3162 { DA7218_MIC_2_CTRL, 0x40 },
3163 { DA7218_MIC_2_GAIN, 0x01 },
3164 { DA7218_MIC_2_SELECT, 0x00 },
3165 { DA7218_IN_1_HPF_FILTER_CTRL, 0x80 },
3166 { DA7218_IN_2_HPF_FILTER_CTRL, 0x80 },
3167 { DA7218_ADC_1_CTRL, 0x07 },
3168 { DA7218_ADC_2_CTRL, 0x07 },
3169 { DA7218_MIXOUT_L_CTRL, 0x00 },
3170 { DA7218_MIXOUT_L_GAIN, 0x03 },
3171 { DA7218_MIXOUT_R_CTRL, 0x00 },
3172 { DA7218_MIXOUT_R_GAIN, 0x03 },
3173 { DA7218_HP_L_CTRL, 0x40 },
3174 { DA7218_HP_L_GAIN, 0x3B },
3175 { DA7218_HP_R_CTRL, 0x40 },
3176 { DA7218_HP_R_GAIN, 0x3B },
3177 { DA7218_HP_DIFF_CTRL, 0x00 },
3178 { DA7218_HP_DIFF_UNLOCK, 0xC3 },
3179 { DA7218_HPLDET_JACK, 0x0B },
3180 { DA7218_HPLDET_CTRL, 0x00 },
3181 { DA7218_REFERENCES, 0x08 },
3182 { DA7218_IO_CTRL, 0x00 },
3183 { DA7218_LDO_CTRL, 0x00 },
3184 { DA7218_SIDETONE_CTRL, 0x40 },
3185 { DA7218_SIDETONE_IN_SELECT, 0x00 },
3186 { DA7218_SIDETONE_GAIN, 0x1C },
3187 { DA7218_DROUTING_ST_OUTFILT_1L, 0x01 },
3188 { DA7218_DROUTING_ST_OUTFILT_1R, 0x02 },
3189 { DA7218_SIDETONE_BIQ_3STAGE_DATA, 0x00 },
3190 { DA7218_SIDETONE_BIQ_3STAGE_ADDR, 0x00 },
3191 { DA7218_EVENT_MASK, 0x00 },
3192 { DA7218_DMIC_1_CTRL, 0x00 },
3193 { DA7218_DMIC_2_CTRL, 0x00 },
3194 { DA7218_IN_1L_GAIN, 0x6F },
3195 { DA7218_IN_1R_GAIN, 0x6F },
3196 { DA7218_IN_2L_GAIN, 0x6F },
3197 { DA7218_IN_2R_GAIN, 0x6F },
3198 { DA7218_OUT_1L_GAIN, 0x6F },
3199 { DA7218_OUT_1R_GAIN, 0x6F },
3200 { DA7218_MICBIAS_CTRL, 0x00 },
3201 { DA7218_MICBIAS_EN, 0x00 },
3202};
3203
3204static bool da7218_volatile_register(struct device *dev, unsigned int reg)
3205{
3206 switch (reg) {
3207 case DA7218_STATUS1:
3208 case DA7218_SOFT_RESET:
3209 case DA7218_SYSTEM_STATUS:
3210 case DA7218_CALIB_CTRL:
3211 case DA7218_CALIB_OFFSET_AUTO_M_1:
3212 case DA7218_CALIB_OFFSET_AUTO_U_1:
3213 case DA7218_CALIB_OFFSET_AUTO_M_2:
3214 case DA7218_CALIB_OFFSET_AUTO_U_2:
3215 case DA7218_PLL_STATUS:
3216 case DA7218_PLL_REFOSC_CAL:
3217 case DA7218_TONE_GEN_CFG1:
3218 case DA7218_ADC_MODE:
3219 case DA7218_HP_SNGL_CTRL:
3220 case DA7218_HPLDET_TEST:
3221 case DA7218_EVENT_STATUS:
3222 case DA7218_EVENT:
3223 return true;
3224 default:
3225 return false;
3226 }
3227}
3228
3229static const struct regmap_config da7218_regmap_config = {
3230 .reg_bits = 8,
3231 .val_bits = 8,
3232
3233 .max_register = DA7218_MICBIAS_EN,
3234 .reg_defaults = da7218_reg_defaults,
3235 .num_reg_defaults = ARRAY_SIZE(da7218_reg_defaults),
3236 .volatile_reg = da7218_volatile_register,
3237 .cache_type = REGCACHE_RBTREE,
3238};
3239
3240
3241/*
3242 * I2C layer
3243 */
3244
3245static int da7218_i2c_probe(struct i2c_client *i2c,
3246 const struct i2c_device_id *id)
3247{
3248 struct da7218_priv *da7218;
3249 int ret;
3250
3251 da7218 = devm_kzalloc(&i2c->dev, sizeof(struct da7218_priv),
3252 GFP_KERNEL);
3253 if (!da7218)
3254 return -ENOMEM;
3255
3256 i2c_set_clientdata(i2c, da7218);
3257
3258 if (i2c->dev.of_node)
3259 da7218->dev_id = da7218_of_get_id(&i2c->dev);
3260 else
3261 da7218->dev_id = id->driver_data;
3262
3263 if ((da7218->dev_id != DA7217_DEV_ID) &&
3264 (da7218->dev_id != DA7218_DEV_ID)) {
3265 dev_err(&i2c->dev, "Invalid device Id\n");
3266 return -EINVAL;
3267 }
3268
3269 da7218->irq = i2c->irq;
3270
3271 da7218->regmap = devm_regmap_init_i2c(i2c, &da7218_regmap_config);
3272 if (IS_ERR(da7218->regmap)) {
3273 ret = PTR_ERR(da7218->regmap);
3274 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
3275 return ret;
3276 }
3277
3278 ret = snd_soc_register_codec(&i2c->dev,
3279 &soc_codec_dev_da7218, &da7218_dai, 1);
3280 if (ret < 0) {
3281 dev_err(&i2c->dev, "Failed to register da7218 codec: %d\n",
3282 ret);
3283 }
3284 return ret;
3285}
3286
3287static int da7218_i2c_remove(struct i2c_client *client)
3288{
3289 snd_soc_unregister_codec(&client->dev);
3290 return 0;
3291}
3292
3293static const struct i2c_device_id da7218_i2c_id[] = {
3294 { "da7217", DA7217_DEV_ID },
3295 { "da7218", DA7218_DEV_ID },
3296 { }
3297};
3298MODULE_DEVICE_TABLE(i2c, da7218_i2c_id);
3299
3300static struct i2c_driver da7218_i2c_driver = {
3301 .driver = {
3302 .name = "da7218",
3303 .of_match_table = of_match_ptr(da7218_of_match),
3304 },
3305 .probe = da7218_i2c_probe,
3306 .remove = da7218_i2c_remove,
3307 .id_table = da7218_i2c_id,
3308};
3309
3310module_i2c_driver(da7218_i2c_driver);
3311
3312MODULE_DESCRIPTION("ASoC DA7218 Codec driver");
3313MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
3314MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7218.h b/sound/soc/codecs/da7218.h
new file mode 100644
index 000000000000..c2c59049a2ad
--- /dev/null
+++ b/sound/soc/codecs/da7218.h
@@ -0,0 +1,1414 @@
1/*
2 * da7218.h - DA7218 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.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#ifndef _DA7218_H
15#define _DA7218_H
16
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <sound/da7218.h>
20
21
22/*
23 * Registers
24 */
25#define DA7218_SYSTEM_ACTIVE 0x0
26#define DA7218_CIF_CTRL 0x1
27#define DA7218_CHIP_ID1 0x4
28#define DA7218_CHIP_ID2 0x5
29#define DA7218_CHIP_REVISION 0x6
30#define DA7218_SPARE1 0x7
31#define DA7218_STATUS1 0x8
32#define DA7218_SOFT_RESET 0x9
33#define DA7218_SR 0xB
34#define DA7218_PC_COUNT 0xC
35#define DA7218_GAIN_RAMP_CTRL 0xD
36#define DA7218_CIF_TIMEOUT_CTRL 0x10
37#define DA7218_SYSTEM_MODES_INPUT 0x14
38#define DA7218_SYSTEM_MODES_OUTPUT 0x15
39#define DA7218_SYSTEM_STATUS 0x16
40#define DA7218_IN_1L_FILTER_CTRL 0x18
41#define DA7218_IN_1R_FILTER_CTRL 0x19
42#define DA7218_IN_2L_FILTER_CTRL 0x1A
43#define DA7218_IN_2R_FILTER_CTRL 0x1B
44#define DA7218_OUT_1L_FILTER_CTRL 0x20
45#define DA7218_OUT_1R_FILTER_CTRL 0x21
46#define DA7218_OUT_1_HPF_FILTER_CTRL 0x24
47#define DA7218_OUT_1_EQ_12_FILTER_CTRL 0x25
48#define DA7218_OUT_1_EQ_34_FILTER_CTRL 0x26
49#define DA7218_OUT_1_EQ_5_FILTER_CTRL 0x27
50#define DA7218_OUT_1_BIQ_5STAGE_CTRL 0x28
51#define DA7218_OUT_1_BIQ_5STAGE_DATA 0x29
52#define DA7218_OUT_1_BIQ_5STAGE_ADDR 0x2A
53#define DA7218_MIXIN_1_CTRL 0x2C
54#define DA7218_MIXIN_1_GAIN 0x2D
55#define DA7218_MIXIN_2_CTRL 0x2E
56#define DA7218_MIXIN_2_GAIN 0x2F
57#define DA7218_ALC_CTRL1 0x30
58#define DA7218_ALC_CTRL2 0x31
59#define DA7218_ALC_CTRL3 0x32
60#define DA7218_ALC_NOISE 0x33
61#define DA7218_ALC_TARGET_MIN 0x34
62#define DA7218_ALC_TARGET_MAX 0x35
63#define DA7218_ALC_GAIN_LIMITS 0x36
64#define DA7218_ALC_ANA_GAIN_LIMITS 0x37
65#define DA7218_ALC_ANTICLIP_CTRL 0x38
66#define DA7218_AGS_ENABLE 0x3C
67#define DA7218_AGS_TRIGGER 0x3D
68#define DA7218_AGS_ATT_MAX 0x3E
69#define DA7218_AGS_TIMEOUT 0x3F
70#define DA7218_AGS_ANTICLIP_CTRL 0x40
71#define DA7218_CALIB_CTRL 0x44
72#define DA7218_CALIB_OFFSET_AUTO_M_1 0x45
73#define DA7218_CALIB_OFFSET_AUTO_U_1 0x46
74#define DA7218_CALIB_OFFSET_AUTO_M_2 0x47
75#define DA7218_CALIB_OFFSET_AUTO_U_2 0x48
76#define DA7218_ENV_TRACK_CTRL 0x4C
77#define DA7218_LVL_DET_CTRL 0x50
78#define DA7218_LVL_DET_LEVEL 0x51
79#define DA7218_DGS_TRIGGER 0x54
80#define DA7218_DGS_ENABLE 0x55
81#define DA7218_DGS_RISE_FALL 0x56
82#define DA7218_DGS_SYNC_DELAY 0x57
83#define DA7218_DGS_SYNC_DELAY2 0x58
84#define DA7218_DGS_SYNC_DELAY3 0x59
85#define DA7218_DGS_LEVELS 0x5A
86#define DA7218_DGS_GAIN_CTRL 0x5B
87#define DA7218_DROUTING_OUTDAI_1L 0x5C
88#define DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN 0x5D
89#define DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN 0x5E
90#define DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN 0x5F
91#define DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN 0x60
92#define DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN 0x61
93#define DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN 0x62
94#define DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN 0x63
95#define DA7218_DROUTING_OUTDAI_1R 0x64
96#define DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN 0x65
97#define DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN 0x66
98#define DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN 0x67
99#define DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN 0x68
100#define DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN 0x69
101#define DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN 0x6A
102#define DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN 0x6B
103#define DA7218_DROUTING_OUTFILT_1L 0x6C
104#define DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN 0x6D
105#define DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN 0x6E
106#define DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN 0x6F
107#define DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN 0x70
108#define DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN 0x71
109#define DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN 0x72
110#define DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN 0x73
111#define DA7218_DROUTING_OUTFILT_1R 0x74
112#define DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN 0x75
113#define DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN 0x76
114#define DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN 0x77
115#define DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN 0x78
116#define DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN 0x79
117#define DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN 0x7A
118#define DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN 0x7B
119#define DA7218_DROUTING_OUTDAI_2L 0x7C
120#define DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN 0x7D
121#define DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN 0x7E
122#define DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN 0x7F
123#define DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN 0x80
124#define DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN 0x81
125#define DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN 0x82
126#define DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN 0x83
127#define DA7218_DROUTING_OUTDAI_2R 0x84
128#define DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN 0x85
129#define DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN 0x86
130#define DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN 0x87
131#define DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN 0x88
132#define DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN 0x89
133#define DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN 0x8A
134#define DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN 0x8B
135#define DA7218_DAI_CTRL 0x8C
136#define DA7218_DAI_TDM_CTRL 0x8D
137#define DA7218_DAI_OFFSET_LOWER 0x8E
138#define DA7218_DAI_OFFSET_UPPER 0x8F
139#define DA7218_DAI_CLK_MODE 0x90
140#define DA7218_PLL_CTRL 0x91
141#define DA7218_PLL_FRAC_TOP 0x92
142#define DA7218_PLL_FRAC_BOT 0x93
143#define DA7218_PLL_INTEGER 0x94
144#define DA7218_PLL_STATUS 0x95
145#define DA7218_PLL_REFOSC_CAL 0x98
146#define DA7218_DAC_NG_CTRL 0x9C
147#define DA7218_DAC_NG_SETUP_TIME 0x9D
148#define DA7218_DAC_NG_OFF_THRESH 0x9E
149#define DA7218_DAC_NG_ON_THRESH 0x9F
150#define DA7218_TONE_GEN_CFG1 0xA0
151#define DA7218_TONE_GEN_CFG2 0xA1
152#define DA7218_TONE_GEN_FREQ1_L 0xA2
153#define DA7218_TONE_GEN_FREQ1_U 0xA3
154#define DA7218_TONE_GEN_FREQ2_L 0xA4
155#define DA7218_TONE_GEN_FREQ2_U 0xA5
156#define DA7218_TONE_GEN_CYCLES 0xA6
157#define DA7218_TONE_GEN_ON_PER 0xA7
158#define DA7218_TONE_GEN_OFF_PER 0xA8
159#define DA7218_CP_CTRL 0xAC
160#define DA7218_CP_DELAY 0xAD
161#define DA7218_CP_VOL_THRESHOLD1 0xAE
162#define DA7218_MIC_1_CTRL 0xB4
163#define DA7218_MIC_1_GAIN 0xB5
164#define DA7218_MIC_1_SELECT 0xB7
165#define DA7218_MIC_2_CTRL 0xB8
166#define DA7218_MIC_2_GAIN 0xB9
167#define DA7218_MIC_2_SELECT 0xBB
168#define DA7218_IN_1_HPF_FILTER_CTRL 0xBC
169#define DA7218_IN_2_HPF_FILTER_CTRL 0xBD
170#define DA7218_ADC_1_CTRL 0xC0
171#define DA7218_ADC_2_CTRL 0xC1
172#define DA7218_ADC_MODE 0xC2
173#define DA7218_MIXOUT_L_CTRL 0xCC
174#define DA7218_MIXOUT_L_GAIN 0xCD
175#define DA7218_MIXOUT_R_CTRL 0xCE
176#define DA7218_MIXOUT_R_GAIN 0xCF
177#define DA7218_HP_L_CTRL 0xD0
178#define DA7218_HP_L_GAIN 0xD1
179#define DA7218_HP_R_CTRL 0xD2
180#define DA7218_HP_R_GAIN 0xD3
181#define DA7218_HP_SNGL_CTRL 0xD4
182#define DA7218_HP_DIFF_CTRL 0xD5
183#define DA7218_HP_DIFF_UNLOCK 0xD7
184#define DA7218_HPLDET_JACK 0xD8
185#define DA7218_HPLDET_CTRL 0xD9
186#define DA7218_HPLDET_TEST 0xDA
187#define DA7218_REFERENCES 0xDC
188#define DA7218_IO_CTRL 0xE0
189#define DA7218_LDO_CTRL 0xE1
190#define DA7218_SIDETONE_CTRL 0xE4
191#define DA7218_SIDETONE_IN_SELECT 0xE5
192#define DA7218_SIDETONE_GAIN 0xE6
193#define DA7218_DROUTING_ST_OUTFILT_1L 0xE8
194#define DA7218_DROUTING_ST_OUTFILT_1R 0xE9
195#define DA7218_SIDETONE_BIQ_3STAGE_DATA 0xEA
196#define DA7218_SIDETONE_BIQ_3STAGE_ADDR 0xEB
197#define DA7218_EVENT_STATUS 0xEC
198#define DA7218_EVENT 0xED
199#define DA7218_EVENT_MASK 0xEE
200#define DA7218_DMIC_1_CTRL 0xF0
201#define DA7218_DMIC_2_CTRL 0xF1
202#define DA7218_IN_1L_GAIN 0xF4
203#define DA7218_IN_1R_GAIN 0xF5
204#define DA7218_IN_2L_GAIN 0xF6
205#define DA7218_IN_2R_GAIN 0xF7
206#define DA7218_OUT_1L_GAIN 0xF8
207#define DA7218_OUT_1R_GAIN 0xF9
208#define DA7218_MICBIAS_CTRL 0xFC
209#define DA7218_MICBIAS_EN 0xFD
210
211
212/*
213 * Bit Fields
214 */
215
216#define DA7218_SWITCH_EN_MAX 0x1
217
218/* DA7218_SYSTEM_ACTIVE = 0x0 */
219#define DA7218_SYSTEM_ACTIVE_SHIFT 0
220#define DA7218_SYSTEM_ACTIVE_MASK (0x1 << 0)
221
222/* DA7218_CIF_CTRL = 0x1 */
223#define DA7218_CIF_I2C_WRITE_MODE_SHIFT 0
224#define DA7218_CIF_I2C_WRITE_MODE_MASK (0x1 << 0)
225
226/* DA7218_CHIP_ID1 = 0x4 */
227#define DA7218_CHIP_ID1_SHIFT 0
228#define DA7218_CHIP_ID1_MASK (0xFF << 0)
229
230/* DA7218_CHIP_ID2 = 0x5 */
231#define DA7218_CHIP_ID2_SHIFT 0
232#define DA7218_CHIP_ID2_MASK (0xFF << 0)
233
234/* DA7218_CHIP_REVISION = 0x6 */
235#define DA7218_CHIP_MINOR_SHIFT 0
236#define DA7218_CHIP_MINOR_MASK (0xF << 0)
237#define DA7218_CHIP_MAJOR_SHIFT 4
238#define DA7218_CHIP_MAJOR_MASK (0xF << 4)
239
240/* DA7218_SPARE1 = 0x7 */
241#define DA7218_SPARE1_SHIFT 0
242#define DA7218_SPARE1_MASK (0xFF << 0)
243
244/* DA7218_STATUS1 = 0x8 */
245#define DA7218_STATUS_SPARE1_SHIFT 0
246#define DA7218_STATUS_SPARE1_MASK (0xFF << 0)
247
248/* DA7218_SOFT_RESET = 0x9 */
249#define DA7218_CIF_REG_SOFT_RESET_SHIFT 7
250#define DA7218_CIF_REG_SOFT_RESET_MASK (0x1 << 7)
251
252/* DA7218_SR = 0xB */
253#define DA7218_SR_ADC_SHIFT 0
254#define DA7218_SR_ADC_MASK (0xF << 0)
255#define DA7218_SR_DAC_SHIFT 4
256#define DA7218_SR_DAC_MASK (0xF << 4)
257#define DA7218_SR_8000 0x01
258#define DA7218_SR_11025 0x02
259#define DA7218_SR_12000 0x03
260#define DA7218_SR_16000 0x05
261#define DA7218_SR_22050 0x06
262#define DA7218_SR_24000 0x07
263#define DA7218_SR_32000 0x09
264#define DA7218_SR_44100 0x0A
265#define DA7218_SR_48000 0x0B
266#define DA7218_SR_88200 0x0E
267#define DA7218_SR_96000 0x0F
268
269/* DA7218_PC_COUNT = 0xC */
270#define DA7218_PC_FREERUN_SHIFT 0
271#define DA7218_PC_FREERUN_MASK (0x1 << 0)
272#define DA7218_PC_RESYNC_AUTO_SHIFT 1
273#define DA7218_PC_RESYNC_AUTO_MASK (0x1 << 1)
274
275/* DA7218_GAIN_RAMP_CTRL = 0xD */
276#define DA7218_GAIN_RAMP_RATE_SHIFT 0
277#define DA7218_GAIN_RAMP_RATE_MASK (0x3 << 0)
278#define DA7218_GAIN_RAMP_RATE_MAX 4
279
280/* DA7218_CIF_TIMEOUT_CTRL = 0x10 */
281#define DA7218_I2C_TIMEOUT_EN_SHIFT 0
282#define DA7218_I2C_TIMEOUT_EN_MASK (0x1 << 0)
283
284/* DA7218_SYSTEM_MODES_INPUT = 0x14 */
285#define DA7218_MODE_SUBMIT_SHIFT 0
286#define DA7218_MODE_SUBMIT_MASK (0x1 << 0)
287#define DA7218_ADC_MODE_SHIFT 1
288#define DA7218_ADC_MODE_MASK (0x7F << 1)
289
290/* DA7218_SYSTEM_MODES_OUTPUT = 0x15 */
291#define DA7218_MODE_SUBMIT_SHIFT 0
292#define DA7218_MODE_SUBMIT_MASK (0x1 << 0)
293#define DA7218_DAC_MODE_SHIFT 1
294#define DA7218_DAC_MODE_MASK (0x7F << 1)
295
296/* DA7218_SYSTEM_STATUS = 0x16 */
297#define DA7218_SC1_BUSY_SHIFT 0
298#define DA7218_SC1_BUSY_MASK (0x1 << 0)
299#define DA7218_SC2_BUSY_SHIFT 1
300#define DA7218_SC2_BUSY_MASK (0x1 << 1)
301
302/* DA7218_IN_1L_FILTER_CTRL = 0x18 */
303#define DA7218_IN_1L_RAMP_EN_SHIFT 5
304#define DA7218_IN_1L_RAMP_EN_MASK (0x1 << 5)
305#define DA7218_IN_1L_MUTE_EN_SHIFT 6
306#define DA7218_IN_1L_MUTE_EN_MASK (0x1 << 6)
307#define DA7218_IN_1L_FILTER_EN_SHIFT 7
308#define DA7218_IN_1L_FILTER_EN_MASK (0x1 << 7)
309
310/* DA7218_IN_1R_FILTER_CTRL = 0x19 */
311#define DA7218_IN_1R_RAMP_EN_SHIFT 5
312#define DA7218_IN_1R_RAMP_EN_MASK (0x1 << 5)
313#define DA7218_IN_1R_MUTE_EN_SHIFT 6
314#define DA7218_IN_1R_MUTE_EN_MASK (0x1 << 6)
315#define DA7218_IN_1R_FILTER_EN_SHIFT 7
316#define DA7218_IN_1R_FILTER_EN_MASK (0x1 << 7)
317
318/* DA7218_IN_2L_FILTER_CTRL = 0x1A */
319#define DA7218_IN_2L_RAMP_EN_SHIFT 5
320#define DA7218_IN_2L_RAMP_EN_MASK (0x1 << 5)
321#define DA7218_IN_2L_MUTE_EN_SHIFT 6
322#define DA7218_IN_2L_MUTE_EN_MASK (0x1 << 6)
323#define DA7218_IN_2L_FILTER_EN_SHIFT 7
324#define DA7218_IN_2L_FILTER_EN_MASK (0x1 << 7)
325
326/* DA7218_IN_2R_FILTER_CTRL = 0x1B */
327#define DA7218_IN_2R_RAMP_EN_SHIFT 5
328#define DA7218_IN_2R_RAMP_EN_MASK (0x1 << 5)
329#define DA7218_IN_2R_MUTE_EN_SHIFT 6
330#define DA7218_IN_2R_MUTE_EN_MASK (0x1 << 6)
331#define DA7218_IN_2R_FILTER_EN_SHIFT 7
332#define DA7218_IN_2R_FILTER_EN_MASK (0x1 << 7)
333
334/* DA7218_OUT_1L_FILTER_CTRL = 0x20 */
335#define DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT 3
336#define DA7218_OUT_1L_BIQ_5STAGE_SEL_MASK (0x1 << 3)
337#define DA7218_OUT_BIQ_5STAGE_SEL_MAX 2
338#define DA7218_OUT_1L_SUBRANGE_EN_SHIFT 4
339#define DA7218_OUT_1L_SUBRANGE_EN_MASK (0x1 << 4)
340#define DA7218_OUT_1L_RAMP_EN_SHIFT 5
341#define DA7218_OUT_1L_RAMP_EN_MASK (0x1 << 5)
342#define DA7218_OUT_1L_MUTE_EN_SHIFT 6
343#define DA7218_OUT_1L_MUTE_EN_MASK (0x1 << 6)
344#define DA7218_OUT_1L_FILTER_EN_SHIFT 7
345#define DA7218_OUT_1L_FILTER_EN_MASK (0x1 << 7)
346
347/* DA7218_OUT_1R_FILTER_CTRL = 0x21 */
348#define DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT 3
349#define DA7218_OUT_1R_BIQ_5STAGE_SEL_MASK (0x1 << 3)
350#define DA7218_OUT_1R_SUBRANGE_EN_SHIFT 4
351#define DA7218_OUT_1R_SUBRANGE_EN_MASK (0x1 << 4)
352#define DA7218_OUT_1R_RAMP_EN_SHIFT 5
353#define DA7218_OUT_1R_RAMP_EN_MASK (0x1 << 5)
354#define DA7218_OUT_1R_MUTE_EN_SHIFT 6
355#define DA7218_OUT_1R_MUTE_EN_MASK (0x1 << 6)
356#define DA7218_OUT_1R_FILTER_EN_SHIFT 7
357#define DA7218_OUT_1R_FILTER_EN_MASK (0x1 << 7)
358
359/* DA7218_OUT_1_HPF_FILTER_CTRL = 0x24 */
360#define DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT 0
361#define DA7218_OUT_1_VOICE_HPF_CORNER_MASK (0x7 << 0)
362#define DA7218_VOICE_HPF_CORNER_MAX 8
363#define DA7218_OUT_1_VOICE_EN_SHIFT 3
364#define DA7218_OUT_1_VOICE_EN_MASK (0x1 << 3)
365#define DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT 4
366#define DA7218_OUT_1_AUDIO_HPF_CORNER_MASK (0x3 << 4)
367#define DA7218_AUDIO_HPF_CORNER_MAX 4
368#define DA7218_OUT_1_HPF_EN_SHIFT 7
369#define DA7218_OUT_1_HPF_EN_MASK (0x1 << 7)
370#define DA7218_HPF_MODE_SHIFT 0
371#define DA7218_HPF_DISABLED ((0x0 << 3) | (0x0 << 7))
372#define DA7218_HPF_AUDIO_EN ((0x0 << 3) | (0x1 << 7))
373#define DA7218_HPF_VOICE_EN ((0x1 << 3) | (0x1 << 7))
374#define DA7218_HPF_MODE_MASK ((0x1 << 3) | (0x1 << 7))
375#define DA7218_HPF_MODE_MAX 3
376
377/* DA7218_OUT_1_EQ_12_FILTER_CTRL = 0x25 */
378#define DA7218_OUT_1_EQ_BAND1_SHIFT 0
379#define DA7218_OUT_1_EQ_BAND1_MASK (0xF << 0)
380#define DA7218_OUT_EQ_BAND_MAX 0xF
381#define DA7218_OUT_1_EQ_BAND2_SHIFT 4
382#define DA7218_OUT_1_EQ_BAND2_MASK (0xF << 4)
383
384/* DA7218_OUT_1_EQ_34_FILTER_CTRL = 0x26 */
385#define DA7218_OUT_1_EQ_BAND3_SHIFT 0
386#define DA7218_OUT_1_EQ_BAND3_MASK (0xF << 0)
387#define DA7218_OUT_1_EQ_BAND4_SHIFT 4
388#define DA7218_OUT_1_EQ_BAND4_MASK (0xF << 4)
389
390/* DA7218_OUT_1_EQ_5_FILTER_CTRL = 0x27 */
391#define DA7218_OUT_1_EQ_BAND5_SHIFT 0
392#define DA7218_OUT_1_EQ_BAND5_MASK (0xF << 0)
393#define DA7218_OUT_1_EQ_EN_SHIFT 7
394#define DA7218_OUT_1_EQ_EN_MASK (0x1 << 7)
395
396/* DA7218_OUT_1_BIQ_5STAGE_CTRL = 0x28 */
397#define DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT 6
398#define DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_MASK (0x1 << 6)
399#define DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT 7
400#define DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_MASK (0x1 << 7)
401
402/* DA7218_OUT_1_BIQ_5STAGE_DATA = 0x29 */
403#define DA7218_OUT_1_BIQ_5STAGE_DATA_SHIFT 0
404#define DA7218_OUT_1_BIQ_5STAGE_DATA_MASK (0xFF << 0)
405
406/* DA7218_OUT_1_BIQ_5STAGE_ADDR = 0x2A */
407#define DA7218_OUT_1_BIQ_5STAGE_ADDR_SHIFT 0
408#define DA7218_OUT_1_BIQ_5STAGE_ADDR_MASK (0x3F << 0)
409#define DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE 50
410
411/* DA7218_MIXIN_1_CTRL = 0x2C */
412#define DA7218_MIXIN_1_MIX_SEL_SHIFT 3
413#define DA7218_MIXIN_1_MIX_SEL_MASK (0x1 << 3)
414#define DA7218_MIXIN_1_AMP_ZC_EN_SHIFT 4
415#define DA7218_MIXIN_1_AMP_ZC_EN_MASK (0x1 << 4)
416#define DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT 5
417#define DA7218_MIXIN_1_AMP_RAMP_EN_MASK (0x1 << 5)
418#define DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT 6
419#define DA7218_MIXIN_1_AMP_MUTE_EN_MASK (0x1 << 6)
420#define DA7218_MIXIN_1_AMP_EN_SHIFT 7
421#define DA7218_MIXIN_1_AMP_EN_MASK (0x1 << 7)
422
423/* DA7218_MIXIN_1_GAIN = 0x2D */
424#define DA7218_MIXIN_1_AMP_GAIN_SHIFT 0
425#define DA7218_MIXIN_1_AMP_GAIN_MASK (0xF << 0)
426#define DA7218_MIXIN_AMP_GAIN_MAX 0xF
427
428/* DA7218_MIXIN_2_CTRL = 0x2E */
429#define DA7218_MIXIN_2_MIX_SEL_SHIFT 3
430#define DA7218_MIXIN_2_MIX_SEL_MASK (0x1 << 3)
431#define DA7218_MIXIN_2_AMP_ZC_EN_SHIFT 4
432#define DA7218_MIXIN_2_AMP_ZC_EN_MASK (0x1 << 4)
433#define DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT 5
434#define DA7218_MIXIN_2_AMP_RAMP_EN_MASK (0x1 << 5)
435#define DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT 6
436#define DA7218_MIXIN_2_AMP_MUTE_EN_MASK (0x1 << 6)
437#define DA7218_MIXIN_2_AMP_EN_SHIFT 7
438#define DA7218_MIXIN_2_AMP_EN_MASK (0x1 << 7)
439
440/* DA7218_MIXIN_2_GAIN = 0x2F */
441#define DA7218_MIXIN_2_AMP_GAIN_SHIFT 0
442#define DA7218_MIXIN_2_AMP_GAIN_MASK (0xF << 0)
443
444/* DA7218_ALC_CTRL1 = 0x30 */
445#define DA7218_ALC_EN_SHIFT 0
446#define DA7218_ALC_EN_MASK (0xF << 0)
447#define DA7218_ALC_CHAN1_L_EN_SHIFT 0
448#define DA7218_ALC_CHAN1_R_EN_SHIFT 1
449#define DA7218_ALC_CHAN2_L_EN_SHIFT 2
450#define DA7218_ALC_CHAN2_R_EN_SHIFT 3
451#define DA7218_ALC_SYNC_MODE_SHIFT 4
452#define DA7218_ALC_SYNC_MODE_MASK (0xF << 4)
453#define DA7218_ALC_SYNC_MODE_CH1 (0x1 << 4)
454#define DA7218_ALC_SYNC_MODE_CH2 (0x4 << 4)
455
456/* DA7218_ALC_CTRL2 = 0x31 */
457#define DA7218_ALC_ATTACK_SHIFT 0
458#define DA7218_ALC_ATTACK_MASK (0xF << 0)
459#define DA7218_ALC_ATTACK_MAX 13
460#define DA7218_ALC_RELEASE_SHIFT 4
461#define DA7218_ALC_RELEASE_MASK (0xF << 4)
462#define DA7218_ALC_RELEASE_MAX 11
463
464/* DA7218_ALC_CTRL3 = 0x32 */
465#define DA7218_ALC_HOLD_SHIFT 0
466#define DA7218_ALC_HOLD_MASK (0xF << 0)
467#define DA7218_ALC_HOLD_MAX 16
468
469/* DA7218_ALC_NOISE = 0x33 */
470#define DA7218_ALC_NOISE_SHIFT 0
471#define DA7218_ALC_NOISE_MASK (0x3F << 0)
472#define DA7218_ALC_THRESHOLD_MAX 0x3F
473
474/* DA7218_ALC_TARGET_MIN = 0x34 */
475#define DA7218_ALC_THRESHOLD_MIN_SHIFT 0
476#define DA7218_ALC_THRESHOLD_MIN_MASK (0x3F << 0)
477
478/* DA7218_ALC_TARGET_MAX = 0x35 */
479#define DA7218_ALC_THRESHOLD_MAX_SHIFT 0
480#define DA7218_ALC_THRESHOLD_MAX_MASK (0x3F << 0)
481
482/* DA7218_ALC_GAIN_LIMITS = 0x36 */
483#define DA7218_ALC_ATTEN_MAX_SHIFT 0
484#define DA7218_ALC_ATTEN_MAX_MASK (0xF << 0)
485#define DA7218_ALC_ATTEN_GAIN_MAX 0xF
486#define DA7218_ALC_GAIN_MAX_SHIFT 4
487#define DA7218_ALC_GAIN_MAX_MASK (0xF << 4)
488
489/* DA7218_ALC_ANA_GAIN_LIMITS = 0x37 */
490#define DA7218_ALC_ANA_GAIN_MIN_SHIFT 0
491#define DA7218_ALC_ANA_GAIN_MIN_MASK (0x7 << 0)
492#define DA7218_ALC_ANA_GAIN_MIN 0x1
493#define DA7218_ALC_ANA_GAIN_MAX 0x7
494#define DA7218_ALC_ANA_GAIN_MAX_SHIFT 4
495#define DA7218_ALC_ANA_GAIN_MAX_MASK (0x7 << 4)
496
497/* DA7218_ALC_ANTICLIP_CTRL = 0x38 */
498#define DA7218_ALC_ANTICLIP_STEP_SHIFT 0
499#define DA7218_ALC_ANTICLIP_STEP_MASK (0x3 << 0)
500#define DA7218_ALC_ANTICLIP_STEP_MAX 4
501#define DA7218_ALC_ANTICLIP_EN_SHIFT 7
502#define DA7218_ALC_ANTICLIP_EN_MASK (0x1 << 7)
503
504/* DA7218_AGS_ENABLE = 0x3C */
505#define DA7218_AGS_ENABLE_SHIFT 0
506#define DA7218_AGS_ENABLE_MASK (0x3 << 0)
507#define DA7218_AGS_ENABLE_CHAN1_SHIFT 0
508#define DA7218_AGS_ENABLE_CHAN2_SHIFT 1
509
510/* DA7218_AGS_TRIGGER = 0x3D */
511#define DA7218_AGS_TRIGGER_SHIFT 0
512#define DA7218_AGS_TRIGGER_MASK (0xF << 0)
513#define DA7218_AGS_TRIGGER_MAX 0xF
514
515/* DA7218_AGS_ATT_MAX = 0x3E */
516#define DA7218_AGS_ATT_MAX_SHIFT 0
517#define DA7218_AGS_ATT_MAX_MASK (0x7 << 0)
518#define DA7218_AGS_ATT_MAX_MAX 0x7
519
520/* DA7218_AGS_TIMEOUT = 0x3F */
521#define DA7218_AGS_TIMEOUT_EN_SHIFT 0
522#define DA7218_AGS_TIMEOUT_EN_MASK (0x1 << 0)
523
524/* DA7218_AGS_ANTICLIP_CTRL = 0x40 */
525#define DA7218_AGS_ANTICLIP_EN_SHIFT 7
526#define DA7218_AGS_ANTICLIP_EN_MASK (0x1 << 7)
527
528/* DA7218_CALIB_CTRL = 0x44 */
529#define DA7218_CALIB_OFFSET_EN_SHIFT 0
530#define DA7218_CALIB_OFFSET_EN_MASK (0x1 << 0)
531#define DA7218_CALIB_AUTO_EN_SHIFT 2
532#define DA7218_CALIB_AUTO_EN_MASK (0x1 << 2)
533#define DA7218_CALIB_OVERFLOW_SHIFT 3
534#define DA7218_CALIB_OVERFLOW_MASK (0x1 << 3)
535
536/* DA7218_CALIB_OFFSET_AUTO_M_1 = 0x45 */
537#define DA7218_CALIB_OFFSET_AUTO_M_1_SHIFT 0
538#define DA7218_CALIB_OFFSET_AUTO_M_1_MASK (0xFF << 0)
539
540/* DA7218_CALIB_OFFSET_AUTO_U_1 = 0x46 */
541#define DA7218_CALIB_OFFSET_AUTO_U_1_SHIFT 0
542#define DA7218_CALIB_OFFSET_AUTO_U_1_MASK (0xF << 0)
543
544/* DA7218_CALIB_OFFSET_AUTO_M_2 = 0x47 */
545#define DA7218_CALIB_OFFSET_AUTO_M_2_SHIFT 0
546#define DA7218_CALIB_OFFSET_AUTO_M_2_MASK (0xFF << 0)
547
548/* DA7218_CALIB_OFFSET_AUTO_U_2 = 0x48 */
549#define DA7218_CALIB_OFFSET_AUTO_U_2_SHIFT 0
550#define DA7218_CALIB_OFFSET_AUTO_U_2_MASK (0xF << 0)
551
552/* DA7218_ENV_TRACK_CTRL = 0x4C */
553#define DA7218_INTEG_ATTACK_SHIFT 0
554#define DA7218_INTEG_ATTACK_MASK (0x3 << 0)
555#define DA7218_INTEG_RELEASE_SHIFT 4
556#define DA7218_INTEG_RELEASE_MASK (0x3 << 4)
557#define DA7218_INTEG_MAX 4
558
559/* DA7218_LVL_DET_CTRL = 0x50 */
560#define DA7218_LVL_DET_EN_SHIFT 0
561#define DA7218_LVL_DET_EN_MASK (0xF << 0)
562#define DA7218_LVL_DET_EN_CHAN1L_SHIFT 0
563#define DA7218_LVL_DET_EN_CHAN1R_SHIFT 1
564#define DA7218_LVL_DET_EN_CHAN2L_SHIFT 2
565#define DA7218_LVL_DET_EN_CHAN2R_SHIFT 3
566
567/* DA7218_LVL_DET_LEVEL = 0x51 */
568#define DA7218_LVL_DET_LEVEL_SHIFT 0
569#define DA7218_LVL_DET_LEVEL_MASK (0x7F << 0)
570#define DA7218_LVL_DET_LEVEL_MAX 0x7F
571
572/* DA7218_DGS_TRIGGER = 0x54 */
573#define DA7218_DGS_TRIGGER_LVL_SHIFT 0
574#define DA7218_DGS_TRIGGER_LVL_MASK (0x3F << 0)
575#define DA7218_DGS_TRIGGER_MAX 0x3F
576
577/* DA7218_DGS_ENABLE = 0x55 */
578#define DA7218_DGS_ENABLE_SHIFT 0
579#define DA7218_DGS_ENABLE_MASK (0x3 << 0)
580#define DA7218_DGS_ENABLE_L_SHIFT 0
581#define DA7218_DGS_ENABLE_R_SHIFT 1
582
583/* DA7218_DGS_RISE_FALL = 0x56 */
584#define DA7218_DGS_RISE_COEFF_SHIFT 0
585#define DA7218_DGS_RISE_COEFF_MASK (0x7 << 0)
586#define DA7218_DGS_RISE_COEFF_MAX 7
587#define DA7218_DGS_FALL_COEFF_SHIFT 4
588#define DA7218_DGS_FALL_COEFF_MASK (0x7 << 4)
589#define DA7218_DGS_FALL_COEFF_MAX 8
590
591/* DA7218_DGS_SYNC_DELAY = 0x57 */
592#define DA7218_DGS_SYNC_DELAY_SHIFT 0
593#define DA7218_DGS_SYNC_DELAY_MASK (0xFF << 0)
594#define DA7218_DGS_SYNC_DELAY_MAX 0xFF
595
596/* DA7218_DGS_SYNC_DELAY2 = 0x58 */
597#define DA7218_DGS_SYNC_DELAY2_SHIFT 0
598#define DA7218_DGS_SYNC_DELAY2_MASK (0xFF << 0)
599
600/* DA7218_DGS_SYNC_DELAY3 = 0x59 */
601#define DA7218_DGS_SYNC_DELAY3_SHIFT 0
602#define DA7218_DGS_SYNC_DELAY3_MASK (0x7F << 0)
603#define DA7218_DGS_SYNC_DELAY3_MAX 0x7F
604
605/* DA7218_DGS_LEVELS = 0x5A */
606#define DA7218_DGS_ANTICLIP_LVL_SHIFT 0
607#define DA7218_DGS_ANTICLIP_LVL_MASK (0x7 << 0)
608#define DA7218_DGS_ANTICLIP_LVL_MAX 0x7
609#define DA7218_DGS_SIGNAL_LVL_SHIFT 4
610#define DA7218_DGS_SIGNAL_LVL_MASK (0xF << 4)
611#define DA7218_DGS_SIGNAL_LVL_MAX 0xF
612
613/* DA7218_DGS_GAIN_CTRL = 0x5B */
614#define DA7218_DGS_STEPS_SHIFT 0
615#define DA7218_DGS_STEPS_MASK (0x1F << 0)
616#define DA7218_DGS_STEPS_MAX 0x1F
617#define DA7218_DGS_RAMP_EN_SHIFT 5
618#define DA7218_DGS_RAMP_EN_MASK (0x1 << 5)
619#define DA7218_DGS_SUBR_EN_SHIFT 6
620#define DA7218_DGS_SUBR_EN_MASK (0x1 << 6)
621
622/* DA7218_DROUTING_OUTDAI_1L = 0x5C */
623#define DA7218_OUTDAI_1L_SRC_SHIFT 0
624#define DA7218_OUTDAI_1L_SRC_MASK (0x7F << 0)
625#define DA7218_DMIX_SRC_INFILT1L 0
626#define DA7218_DMIX_SRC_INFILT1R 1
627#define DA7218_DMIX_SRC_INFILT2L 2
628#define DA7218_DMIX_SRC_INFILT2R 3
629#define DA7218_DMIX_SRC_TONEGEN 4
630#define DA7218_DMIX_SRC_DAIL 5
631#define DA7218_DMIX_SRC_DAIR 6
632
633/* DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN = 0x5D */
634#define DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT 0
635#define DA7218_OUTDAI_1L_INFILT_1L_GAIN_MASK (0x1F << 0)
636#define DA7218_DMIX_GAIN_MAX 0x1F
637
638/* DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN = 0x5E */
639#define DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT 0
640#define DA7218_OUTDAI_1L_INFILT_1R_GAIN_MASK (0x1F << 0)
641
642/* DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN = 0x5F */
643#define DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT 0
644#define DA7218_OUTDAI_1L_INFILT_2L_GAIN_MASK (0x1F << 0)
645
646/* DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN = 0x60 */
647#define DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT 0
648#define DA7218_OUTDAI_1L_INFILT_2R_GAIN_MASK (0x1F << 0)
649
650/* DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN = 0x61 */
651#define DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT 0
652#define DA7218_OUTDAI_1L_TONEGEN_GAIN_MASK (0x1F << 0)
653
654/* DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN = 0x62 */
655#define DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT 0
656#define DA7218_OUTDAI_1L_INDAI_1L_GAIN_MASK (0x1F << 0)
657
658/* DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN = 0x63 */
659#define DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT 0
660#define DA7218_OUTDAI_1L_INDAI_1R_GAIN_MASK (0x1F << 0)
661
662/* DA7218_DROUTING_OUTDAI_1R = 0x64 */
663#define DA7218_OUTDAI_1R_SRC_SHIFT 0
664#define DA7218_OUTDAI_1R_SRC_MASK (0x7F << 0)
665
666/* DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN = 0x65 */
667#define DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT 0
668#define DA7218_OUTDAI_1R_INFILT_1L_GAIN_MASK (0x1F << 0)
669
670/* DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN = 0x66 */
671#define DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT 0
672#define DA7218_OUTDAI_1R_INFILT_1R_GAIN_MASK (0x1F << 0)
673
674/* DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN = 0x67 */
675#define DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT 0
676#define DA7218_OUTDAI_1R_INFILT_2L_GAIN_MASK (0x1F << 0)
677
678/* DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN = 0x68 */
679#define DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT 0
680#define DA7218_OUTDAI_1R_INFILT_2R_GAIN_MASK (0x1F << 0)
681
682/* DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN = 0x69 */
683#define DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT 0
684#define DA7218_OUTDAI_1R_TONEGEN_GAIN_MASK (0x1F << 0)
685
686/* DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN = 0x6A */
687#define DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT 0
688#define DA7218_OUTDAI_1R_INDAI_1L_GAIN_MASK (0x1F << 0)
689
690/* DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN = 0x6B */
691#define DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT 0
692#define DA7218_OUTDAI_1R_INDAI_1R_GAIN_MASK (0x1F << 0)
693
694/* DA7218_DROUTING_OUTFILT_1L = 0x6C */
695#define DA7218_OUTFILT_1L_SRC_SHIFT 0
696#define DA7218_OUTFILT_1L_SRC_MASK (0x7F << 0)
697
698/* DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN = 0x6D */
699#define DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT 0
700#define DA7218_OUTFILT_1L_INFILT_1L_GAIN_MASK (0x1F << 0)
701
702/* DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN = 0x6E */
703#define DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT 0
704#define DA7218_OUTFILT_1L_INFILT_1R_GAIN_MASK (0x1F << 0)
705
706/* DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN = 0x6F */
707#define DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT 0
708#define DA7218_OUTFILT_1L_INFILT_2L_GAIN_MASK (0x1F << 0)
709
710/* DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN = 0x70 */
711#define DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT 0
712#define DA7218_OUTFILT_1L_INFILT_2R_GAIN_MASK (0x1F << 0)
713
714/* DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN = 0x71 */
715#define DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT 0
716#define DA7218_OUTFILT_1L_TONEGEN_GAIN_MASK (0x1F << 0)
717
718/* DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN = 0x72 */
719#define DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT 0
720#define DA7218_OUTFILT_1L_INDAI_1L_GAIN_MASK (0x1F << 0)
721
722/* DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN = 0x73 */
723#define DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT 0
724#define DA7218_OUTFILT_1L_INDAI_1R_GAIN_MASK (0x1F << 0)
725
726/* DA7218_DROUTING_OUTFILT_1R = 0x74 */
727#define DA7218_OUTFILT_1R_SRC_SHIFT 0
728#define DA7218_OUTFILT_1R_SRC_MASK (0x7F << 0)
729
730/* DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN = 0x75 */
731#define DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT 0
732#define DA7218_OUTFILT_1R_INFILT_1L_GAIN_MASK (0x1F << 0)
733
734/* DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN = 0x76 */
735#define DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT 0
736#define DA7218_OUTFILT_1R_INFILT_1R_GAIN_MASK (0x1F << 0)
737
738/* DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN = 0x77 */
739#define DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT 0
740#define DA7218_OUTFILT_1R_INFILT_2L_GAIN_MASK (0x1F << 0)
741
742/* DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN = 0x78 */
743#define DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT 0
744#define DA7218_OUTFILT_1R_INFILT_2R_GAIN_MASK (0x1F << 0)
745
746/* DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN = 0x79 */
747#define DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT 0
748#define DA7218_OUTFILT_1R_TONEGEN_GAIN_MASK (0x1F << 0)
749
750/* DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN = 0x7A */
751#define DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT 0
752#define DA7218_OUTFILT_1R_INDAI_1L_GAIN_MASK (0x1F << 0)
753
754/* DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN = 0x7B */
755#define DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT 0
756#define DA7218_OUTFILT_1R_INDAI_1R_GAIN_MASK (0x1F << 0)
757
758/* DA7218_DROUTING_OUTDAI_2L = 0x7C */
759#define DA7218_OUTDAI_2L_SRC_SHIFT 0
760#define DA7218_OUTDAI_2L_SRC_MASK (0x7F << 0)
761
762/* DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN = 0x7D */
763#define DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT 0
764#define DA7218_OUTDAI_2L_INFILT_1L_GAIN_MASK (0x1F << 0)
765
766/* DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN = 0x7E */
767#define DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT 0
768#define DA7218_OUTDAI_2L_INFILT_1R_GAIN_MASK (0x1F << 0)
769
770/* DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN = 0x7F */
771#define DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT 0
772#define DA7218_OUTDAI_2L_INFILT_2L_GAIN_MASK (0x1F << 0)
773
774/* DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN = 0x80 */
775#define DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT 0
776#define DA7218_OUTDAI_2L_INFILT_2R_GAIN_MASK (0x1F << 0)
777
778/* DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN = 0x81 */
779#define DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT 0
780#define DA7218_OUTDAI_2L_TONEGEN_GAIN_MASK (0x1F << 0)
781
782/* DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN = 0x82 */
783#define DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT 0
784#define DA7218_OUTDAI_2L_INDAI_1L_GAIN_MASK (0x1F << 0)
785
786/* DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN = 0x83 */
787#define DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT 0
788#define DA7218_OUTDAI_2L_INDAI_1R_GAIN_MASK (0x1F << 0)
789
790/* DA7218_DROUTING_OUTDAI_2R = 0x84 */
791#define DA7218_OUTDAI_2R_SRC_SHIFT 0
792#define DA7218_OUTDAI_2R_SRC_MASK (0x7F << 0)
793
794/* DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN = 0x85 */
795#define DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT 0
796#define DA7218_OUTDAI_2R_INFILT_1L_GAIN_MASK (0x1F << 0)
797
798/* DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN = 0x86 */
799#define DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT 0
800#define DA7218_OUTDAI_2R_INFILT_1R_GAIN_MASK (0x1F << 0)
801
802/* DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN = 0x87 */
803#define DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT 0
804#define DA7218_OUTDAI_2R_INFILT_2L_GAIN_MASK (0x1F << 0)
805
806/* DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN = 0x88 */
807#define DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT 0
808#define DA7218_OUTDAI_2R_INFILT_2R_GAIN_MASK (0x1F << 0)
809
810/* DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN = 0x89 */
811#define DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT 0
812#define DA7218_OUTDAI_2R_TONEGEN_GAIN_MASK (0x1F << 0)
813
814/* DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN = 0x8A */
815#define DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT 0
816#define DA7218_OUTDAI_2R_INDAI_1L_GAIN_MASK (0x1F << 0)
817
818/* DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN = 0x8B */
819#define DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT 0
820#define DA7218_OUTDAI_2R_INDAI_1R_GAIN_MASK (0x1F << 0)
821
822/* DA7218_DAI_CTRL = 0x8C */
823#define DA7218_DAI_FORMAT_SHIFT 0
824#define DA7218_DAI_FORMAT_MASK (0x3 << 0)
825#define DA7218_DAI_FORMAT_I2S (0x0 << 0)
826#define DA7218_DAI_FORMAT_LEFT_J (0x1 << 0)
827#define DA7218_DAI_FORMAT_RIGHT_J (0x2 << 0)
828#define DA7218_DAI_FORMAT_DSP (0x3 << 0)
829#define DA7218_DAI_WORD_LENGTH_SHIFT 2
830#define DA7218_DAI_WORD_LENGTH_MASK (0x3 << 2)
831#define DA7218_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
832#define DA7218_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
833#define DA7218_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
834#define DA7218_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
835#define DA7218_DAI_CH_NUM_SHIFT 4
836#define DA7218_DAI_CH_NUM_MASK (0x7 << 4)
837#define DA7218_DAI_CH_NUM_MAX 4
838#define DA7218_DAI_EN_SHIFT 7
839#define DA7218_DAI_EN_MASK (0x1 << 7)
840
841/* DA7218_DAI_TDM_CTRL = 0x8D */
842#define DA7218_DAI_TDM_CH_EN_SHIFT 0
843#define DA7218_DAI_TDM_CH_EN_MASK (0xF << 0)
844#define DA7218_DAI_TDM_MAX_SLOTS 4
845#define DA7218_DAI_OE_SHIFT 6
846#define DA7218_DAI_OE_MASK (0x1 << 6)
847#define DA7218_DAI_TDM_MODE_EN_SHIFT 7
848#define DA7218_DAI_TDM_MODE_EN_MASK (0x1 << 7)
849
850/* DA7218_DAI_OFFSET_LOWER = 0x8E */
851#define DA7218_DAI_OFFSET_LOWER_SHIFT 0
852#define DA7218_DAI_OFFSET_LOWER_MASK (0xFF << 0)
853
854/* DA7218_DAI_OFFSET_UPPER = 0x8F */
855#define DA7218_DAI_OFFSET_UPPER_SHIFT 0
856#define DA7218_DAI_OFFSET_UPPER_MASK (0x7 << 0)
857
858/* DA7218_DAI_CLK_MODE = 0x90 */
859#define DA7218_DAI_BCLKS_PER_WCLK_SHIFT 0
860#define DA7218_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
861#define DA7218_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
862#define DA7218_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
863#define DA7218_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
864#define DA7218_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
865#define DA7218_DAI_CLK_POL_SHIFT 2
866#define DA7218_DAI_CLK_POL_MASK (0x1 << 2)
867#define DA7218_DAI_CLK_POL_INV (0x1 << 2)
868#define DA7218_DAI_WCLK_POL_SHIFT 3
869#define DA7218_DAI_WCLK_POL_MASK (0x1 << 3)
870#define DA7218_DAI_WCLK_POL_INV (0x1 << 3)
871#define DA7218_DAI_WCLK_TRI_STATE_SHIFT 4
872#define DA7218_DAI_WCLK_TRI_STATE_MASK (0x1 << 4)
873#define DA7218_DAI_CLK_EN_SHIFT 7
874#define DA7218_DAI_CLK_EN_MASK (0x1 << 7)
875
876/* DA7218_PLL_CTRL = 0x91 */
877#define DA7218_PLL_INDIV_SHIFT 0
878#define DA7218_PLL_INDIV_MASK (0x7 << 0)
879#define DA7218_PLL_INDIV_2_5_MHZ (0x0 << 0)
880#define DA7218_PLL_INDIV_5_10_MHZ (0x1 << 0)
881#define DA7218_PLL_INDIV_10_20_MHZ (0x2 << 0)
882#define DA7218_PLL_INDIV_20_40_MHZ (0x3 << 0)
883#define DA7218_PLL_INDIV_40_54_MHZ (0x4 << 0)
884#define DA7218_PLL_INDIV_2_10_MHZ_VAL 2
885#define DA7218_PLL_INDIV_10_20_MHZ_VAL 4
886#define DA7218_PLL_INDIV_20_40_MHZ_VAL 8
887#define DA7218_PLL_INDIV_40_54_MHZ_VAL 16
888#define DA7218_PLL_MCLK_SQR_EN_SHIFT 4
889#define DA7218_PLL_MCLK_SQR_EN_MASK (0x1 << 4)
890#define DA7218_PLL_MODE_SHIFT 6
891#define DA7218_PLL_MODE_MASK (0x3 << 6)
892#define DA7218_PLL_MODE_BYPASS (0x0 << 6)
893#define DA7218_PLL_MODE_NORMAL (0x1 << 6)
894#define DA7218_PLL_MODE_SRM (0x2 << 6)
895#define DA7218_PLL_MODE_32KHZ (0x3 << 6)
896
897/* DA7218_PLL_FRAC_TOP = 0x92 */
898#define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0
899#define DA7218_PLL_FBDIV_FRAC_TOP_MASK (0x1F << 0)
900
901/* DA7218_PLL_FRAC_BOT = 0x93 */
902#define DA7218_PLL_FBDIV_FRAC_BOT_SHIFT 0
903#define DA7218_PLL_FBDIV_FRAC_BOT_MASK (0xFF << 0)
904
905/* DA7218_PLL_INTEGER = 0x94 */
906#define DA7218_PLL_FBDIV_INTEGER_SHIFT 0
907#define DA7218_PLL_FBDIV_INTEGER_MASK (0x7F << 0)
908
909/* DA7218_PLL_STATUS = 0x95 */
910#define DA7218_PLL_SRM_STATUS_SHIFT 0
911#define DA7218_PLL_SRM_STATUS_MASK (0xFF << 0)
912#define DA7218_PLL_SRM_STATUS_SRM_LOCK (0x1 << 7)
913
914/* DA7218_PLL_REFOSC_CAL = 0x98 */
915#define DA7218_PLL_REFOSC_CAL_CTRL_SHIFT 0
916#define DA7218_PLL_REFOSC_CAL_CTRL_MASK (0x1F << 0)
917#define DA7218_PLL_REFOSC_CAL_START_SHIFT 6
918#define DA7218_PLL_REFOSC_CAL_START_MASK (0x1 << 6)
919#define DA7218_PLL_REFOSC_CAL_EN_SHIFT 7
920#define DA7218_PLL_REFOSC_CAL_EN_MASK (0x1 << 7)
921
922/* DA7218_DAC_NG_CTRL = 0x9C */
923#define DA7218_DAC_NG_EN_SHIFT 7
924#define DA7218_DAC_NG_EN_MASK (0x1 << 7)
925
926/* DA7218_DAC_NG_SETUP_TIME = 0x9D */
927#define DA7218_DAC_NG_SETUP_TIME_SHIFT 0
928#define DA7218_DAC_NG_SETUP_TIME_MASK (0x3 << 0)
929#define DA7218_DAC_NG_SETUP_TIME_MAX 4
930#define DA7218_DAC_NG_RAMPUP_RATE_SHIFT 2
931#define DA7218_DAC_NG_RAMPUP_RATE_MASK (0x1 << 2)
932#define DA7218_DAC_NG_RAMPUP_RATE_MAX 2
933#define DA7218_DAC_NG_RAMPDN_RATE_SHIFT 3
934#define DA7218_DAC_NG_RAMPDN_RATE_MASK (0x1 << 3)
935#define DA7218_DAC_NG_RAMPDN_RATE_MAX 2
936
937/* DA7218_DAC_NG_OFF_THRESH = 0x9E */
938#define DA7218_DAC_NG_OFF_THRESHOLD_SHIFT 0
939#define DA7218_DAC_NG_OFF_THRESHOLD_MASK (0x7 << 0)
940#define DA7218_DAC_NG_THRESHOLD_MAX 0x7
941
942/* DA7218_DAC_NG_ON_THRESH = 0x9F */
943#define DA7218_DAC_NG_ON_THRESHOLD_SHIFT 0
944#define DA7218_DAC_NG_ON_THRESHOLD_MASK (0x7 << 0)
945
946/* DA7218_TONE_GEN_CFG1 = 0xA0 */
947#define DA7218_DTMF_REG_SHIFT 0
948#define DA7218_DTMF_REG_MASK (0xF << 0)
949#define DA7218_DTMF_REG_MAX 16
950#define DA7218_DTMF_EN_SHIFT 4
951#define DA7218_DTMF_EN_MASK (0x1 << 4)
952#define DA7218_START_STOPN_SHIFT 7
953#define DA7218_START_STOPN_MASK (0x1 << 7)
954
955/* DA7218_TONE_GEN_CFG2 = 0xA1 */
956#define DA7218_SWG_SEL_SHIFT 0
957#define DA7218_SWG_SEL_MASK (0x3 << 0)
958#define DA7218_SWG_SEL_MAX 4
959
960/* DA7218_TONE_GEN_FREQ1_L = 0xA2 */
961#define DA7218_FREQ1_L_SHIFT 0
962#define DA7218_FREQ1_L_MASK (0xFF << 0)
963#define DA7218_FREQ_MAX 0xFFFF
964
965/* DA7218_TONE_GEN_FREQ1_U = 0xA3 */
966#define DA7218_FREQ1_U_SHIFT 0
967#define DA7218_FREQ1_U_MASK (0xFF << 0)
968
969/* DA7218_TONE_GEN_FREQ2_L = 0xA4 */
970#define DA7218_FREQ2_L_SHIFT 0
971#define DA7218_FREQ2_L_MASK (0xFF << 0)
972
973/* DA7218_TONE_GEN_FREQ2_U = 0xA5 */
974#define DA7218_FREQ2_U_SHIFT 0
975#define DA7218_FREQ2_U_MASK (0xFF << 0)
976
977/* DA7218_TONE_GEN_CYCLES = 0xA6 */
978#define DA7218_BEEP_CYCLES_SHIFT 0
979#define DA7218_BEEP_CYCLES_MASK (0x7 << 0)
980
981/* DA7218_TONE_GEN_ON_PER = 0xA7 */
982#define DA7218_BEEP_ON_PER_SHIFT 0
983#define DA7218_BEEP_ON_PER_MASK (0x3F << 0)
984
985/* DA7218_TONE_GEN_OFF_PER = 0xA8 */
986#define DA7218_BEEP_OFF_PER_SHIFT 0
987#define DA7218_BEEP_OFF_PER_MASK (0x3F << 0)
988#define DA7218_BEEP_ON_OFF_MAX 0x3F
989
990/* DA7218_CP_CTRL = 0xAC */
991#define DA7218_CP_MOD_SHIFT 2
992#define DA7218_CP_MOD_MASK (0x3 << 2)
993#define DA7218_CP_MCHANGE_SHIFT 4
994#define DA7218_CP_MCHANGE_MASK (0x3 << 4)
995#define DA7218_CP_MCHANGE_REL_MASK 0x3
996#define DA7218_CP_MCHANGE_MAX 3
997#define DA7218_CP_MCHANGE_LARGEST_VOL 0x1
998#define DA7218_CP_MCHANGE_DAC_VOL 0x2
999#define DA7218_CP_MCHANGE_SIG_MAG 0x3
1000#define DA7218_CP_SMALL_SWITCH_FREQ_EN_SHIFT 6
1001#define DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK (0x1 << 6)
1002#define DA7218_CP_EN_SHIFT 7
1003#define DA7218_CP_EN_MASK (0x1 << 7)
1004
1005/* DA7218_CP_DELAY = 0xAD */
1006#define DA7218_CP_FCONTROL_SHIFT 0
1007#define DA7218_CP_FCONTROL_MASK (0x7 << 0)
1008#define DA7218_CP_FCONTROL_MAX 6
1009#define DA7218_CP_TAU_DELAY_SHIFT 3
1010#define DA7218_CP_TAU_DELAY_MASK (0x7 << 3)
1011#define DA7218_CP_TAU_DELAY_MAX 8
1012
1013/* DA7218_CP_VOL_THRESHOLD1 = 0xAE */
1014#define DA7218_CP_THRESH_VDD2_SHIFT 0
1015#define DA7218_CP_THRESH_VDD2_MASK (0x3F << 0)
1016#define DA7218_CP_THRESH_VDD2_MAX 0x3F
1017
1018/* DA7218_MIC_1_CTRL = 0xB4 */
1019#define DA7218_MIC_1_AMP_MUTE_EN_SHIFT 6
1020#define DA7218_MIC_1_AMP_MUTE_EN_MASK (0x1 << 6)
1021#define DA7218_MIC_1_AMP_EN_SHIFT 7
1022#define DA7218_MIC_1_AMP_EN_MASK (0x1 << 7)
1023
1024/* DA7218_MIC_1_GAIN = 0xB5 */
1025#define DA7218_MIC_1_AMP_GAIN_SHIFT 0
1026#define DA7218_MIC_1_AMP_GAIN_MASK (0x7 << 0)
1027#define DA7218_MIC_AMP_GAIN_MAX 0x7
1028
1029/* DA7218_MIC_1_SELECT = 0xB7 */
1030#define DA7218_MIC_1_AMP_IN_SEL_SHIFT 0
1031#define DA7218_MIC_1_AMP_IN_SEL_MASK (0x3 << 0)
1032
1033/* DA7218_MIC_2_CTRL = 0xB8 */
1034#define DA7218_MIC_2_AMP_MUTE_EN_SHIFT 6
1035#define DA7218_MIC_2_AMP_MUTE_EN_MASK (0x1 << 6)
1036#define DA7218_MIC_2_AMP_EN_SHIFT 7
1037#define DA7218_MIC_2_AMP_EN_MASK (0x1 << 7)
1038
1039/* DA7218_MIC_2_GAIN = 0xB9 */
1040#define DA7218_MIC_2_AMP_GAIN_SHIFT 0
1041#define DA7218_MIC_2_AMP_GAIN_MASK (0x7 << 0)
1042
1043/* DA7218_MIC_2_SELECT = 0xBB */
1044#define DA7218_MIC_2_AMP_IN_SEL_SHIFT 0
1045#define DA7218_MIC_2_AMP_IN_SEL_MASK (0x3 << 0)
1046
1047/* DA7218_IN_1_HPF_FILTER_CTRL = 0xBC */
1048#define DA7218_IN_1_VOICE_HPF_CORNER_SHIFT 0
1049#define DA7218_IN_1_VOICE_HPF_CORNER_MASK (0x7 << 0)
1050#define DA7218_IN_VOICE_HPF_CORNER_MAX 8
1051#define DA7218_IN_1_VOICE_EN_SHIFT 3
1052#define DA7218_IN_1_VOICE_EN_MASK (0x1 << 3)
1053#define DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT 4
1054#define DA7218_IN_1_AUDIO_HPF_CORNER_MASK (0x3 << 4)
1055#define DA7218_IN_1_HPF_EN_SHIFT 7
1056#define DA7218_IN_1_HPF_EN_MASK (0x1 << 7)
1057
1058/* DA7218_IN_2_HPF_FILTER_CTRL = 0xBD */
1059#define DA7218_IN_2_VOICE_HPF_CORNER_SHIFT 0
1060#define DA7218_IN_2_VOICE_HPF_CORNER_MASK (0x7 << 0)
1061#define DA7218_IN_2_VOICE_EN_SHIFT 3
1062#define DA7218_IN_2_VOICE_EN_MASK (0x1 << 3)
1063#define DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT 4
1064#define DA7218_IN_2_AUDIO_HPF_CORNER_MASK (0x3 << 4)
1065#define DA7218_IN_2_HPF_EN_SHIFT 7
1066#define DA7218_IN_2_HPF_EN_MASK (0x1 << 7)
1067
1068/* DA7218_ADC_1_CTRL = 0xC0 */
1069#define DA7218_ADC_1_AAF_EN_SHIFT 2
1070#define DA7218_ADC_1_AAF_EN_MASK (0x1 << 2)
1071
1072/* DA7218_ADC_2_CTRL = 0xC1 */
1073#define DA7218_ADC_2_AAF_EN_SHIFT 2
1074#define DA7218_ADC_2_AAF_EN_MASK (0x1 << 2)
1075
1076/* DA7218_ADC_MODE = 0xC2 */
1077#define DA7218_ADC_LP_MODE_SHIFT 0
1078#define DA7218_ADC_LP_MODE_MASK (0x1 << 0)
1079#define DA7218_ADC_LVLDET_MODE_SHIFT 1
1080#define DA7218_ADC_LVLDET_MODE_MASK (0x1 << 1)
1081#define DA7218_ADC_LVLDET_AUTO_EXIT_SHIFT 2
1082#define DA7218_ADC_LVLDET_AUTO_EXIT_MASK (0x1 << 2)
1083
1084/* DA7218_MIXOUT_L_CTRL = 0xCC */
1085#define DA7218_MIXOUT_L_AMP_EN_SHIFT 7
1086#define DA7218_MIXOUT_L_AMP_EN_MASK (0x1 << 7)
1087
1088/* DA7218_MIXOUT_L_GAIN = 0xCD */
1089#define DA7218_MIXOUT_L_AMP_GAIN_SHIFT 0
1090#define DA7218_MIXOUT_L_AMP_GAIN_MASK (0x3 << 0)
1091#define DA7218_MIXOUT_AMP_GAIN_MIN 0x1
1092#define DA7218_MIXOUT_AMP_GAIN_MAX 0x3
1093
1094/* DA7218_MIXOUT_R_CTRL = 0xCE */
1095#define DA7218_MIXOUT_R_AMP_EN_SHIFT 7
1096#define DA7218_MIXOUT_R_AMP_EN_MASK (0x1 << 7)
1097
1098/* DA7218_MIXOUT_R_GAIN = 0xCF */
1099#define DA7218_MIXOUT_R_AMP_GAIN_SHIFT 0
1100#define DA7218_MIXOUT_R_AMP_GAIN_MASK (0x3 << 0)
1101
1102/* DA7218_HP_L_CTRL = 0xD0 */
1103#define DA7218_HP_L_AMP_MIN_GAIN_EN_SHIFT 2
1104#define DA7218_HP_L_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
1105#define DA7218_HP_L_AMP_OE_SHIFT 3
1106#define DA7218_HP_L_AMP_OE_MASK (0x1 << 3)
1107#define DA7218_HP_L_AMP_ZC_EN_SHIFT 4
1108#define DA7218_HP_L_AMP_ZC_EN_MASK (0x1 << 4)
1109#define DA7218_HP_L_AMP_RAMP_EN_SHIFT 5
1110#define DA7218_HP_L_AMP_RAMP_EN_MASK (0x1 << 5)
1111#define DA7218_HP_L_AMP_MUTE_EN_SHIFT 6
1112#define DA7218_HP_L_AMP_MUTE_EN_MASK (0x1 << 6)
1113#define DA7218_HP_L_AMP_EN_SHIFT 7
1114#define DA7218_HP_L_AMP_EN_MASK (0x1 << 7)
1115#define DA7218_HP_AMP_OE_MASK (0x1 << 3)
1116
1117/* DA7218_HP_L_GAIN = 0xD1 */
1118#define DA7218_HP_L_AMP_GAIN_SHIFT 0
1119#define DA7218_HP_L_AMP_GAIN_MASK (0x3F << 0)
1120#define DA7218_HP_AMP_GAIN_MIN 0x15
1121#define DA7218_HP_AMP_GAIN_MAX 0x3F
1122
1123/* DA7218_HP_R_CTRL = 0xD2 */
1124#define DA7218_HP_R_AMP_MIN_GAIN_EN_SHIFT 2
1125#define DA7218_HP_R_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
1126#define DA7218_HP_R_AMP_OE_SHIFT 3
1127#define DA7218_HP_R_AMP_OE_MASK (0x1 << 3)
1128#define DA7218_HP_R_AMP_ZC_EN_SHIFT 4
1129#define DA7218_HP_R_AMP_ZC_EN_MASK (0x1 << 4)
1130#define DA7218_HP_R_AMP_RAMP_EN_SHIFT 5
1131#define DA7218_HP_R_AMP_RAMP_EN_MASK (0x1 << 5)
1132#define DA7218_HP_R_AMP_MUTE_EN_SHIFT 6
1133#define DA7218_HP_R_AMP_MUTE_EN_MASK (0x1 << 6)
1134#define DA7218_HP_R_AMP_EN_SHIFT 7
1135#define DA7218_HP_R_AMP_EN_MASK (0x1 << 7)
1136
1137/* DA7218_HP_R_GAIN = 0xD3 */
1138#define DA7218_HP_R_AMP_GAIN_SHIFT 0
1139#define DA7218_HP_R_AMP_GAIN_MASK (0x3F << 0)
1140
1141/* DA7218_HP_SNGL_CTRL = 0xD4 */
1142#define DA7218_HP_AMP_STEREO_DETECT_STATUS_SHIFT 0
1143#define DA7218_HP_AMP_STEREO_DETECT_STATUS_MASK (0x1 << 0)
1144#define DA7218_HPL_AMP_LOAD_DETECT_STATUS_SHIFT 1
1145#define DA7218_HPL_AMP_LOAD_DETECT_STATUS_MASK (0x1 << 1)
1146#define DA7218_HPR_AMP_LOAD_DETECT_STATUS_SHIFT 2
1147#define DA7218_HPR_AMP_LOAD_DETECT_STATUS_MASK (0x1 << 2)
1148#define DA7218_HP_AMP_LOAD_DETECT_EN_SHIFT 6
1149#define DA7218_HP_AMP_LOAD_DETECT_EN_MASK (0x1 << 6)
1150#define DA7218_HP_AMP_STEREO_DETECT_EN_SHIFT 7
1151#define DA7218_HP_AMP_STEREO_DETECT_EN_MASK (0x1 << 7)
1152
1153/* DA7218_HP_DIFF_CTRL = 0xD5 */
1154#define DA7218_HP_AMP_DIFF_MODE_EN_SHIFT 0
1155#define DA7218_HP_AMP_DIFF_MODE_EN_MASK (0x1 << 0)
1156#define DA7218_HP_AMP_SINGLE_SUPPLY_EN_SHIFT 4
1157#define DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK (0x1 << 4)
1158
1159/* DA7218_HP_DIFF_UNLOCK = 0xD7 */
1160#define DA7218_HP_DIFF_UNLOCK_SHIFT 0
1161#define DA7218_HP_DIFF_UNLOCK_MASK (0x1 << 0)
1162#define DA7218_HP_DIFF_UNLOCK_VAL 0xC3
1163
1164/* DA7218_HPLDET_JACK = 0xD8 */
1165#define DA7218_HPLDET_JACK_RATE_SHIFT 0
1166#define DA7218_HPLDET_JACK_RATE_MASK (0x7 << 0)
1167#define DA7218_HPLDET_JACK_DEBOUNCE_SHIFT 3
1168#define DA7218_HPLDET_JACK_DEBOUNCE_MASK (0x3 << 3)
1169#define DA7218_HPLDET_JACK_THR_SHIFT 5
1170#define DA7218_HPLDET_JACK_THR_MASK (0x3 << 5)
1171#define DA7218_HPLDET_JACK_EN_SHIFT 7
1172#define DA7218_HPLDET_JACK_EN_MASK (0x1 << 7)
1173
1174/* DA7218_HPLDET_CTRL = 0xD9 */
1175#define DA7218_HPLDET_COMP_INV_SHIFT 0
1176#define DA7218_HPLDET_COMP_INV_MASK (0x1 << 0)
1177#define DA7218_HPLDET_HYST_EN_SHIFT 1
1178#define DA7218_HPLDET_HYST_EN_MASK (0x1 << 1)
1179#define DA7218_HPLDET_DISCHARGE_EN_SHIFT 7
1180#define DA7218_HPLDET_DISCHARGE_EN_MASK (0x1 << 7)
1181
1182/* DA7218_HPLDET_TEST = 0xDA */
1183#define DA7218_HPLDET_COMP_STS_SHIFT 4
1184#define DA7218_HPLDET_COMP_STS_MASK (0x1 << 4)
1185
1186/* DA7218_REFERENCES = 0xDC */
1187#define DA7218_BIAS_EN_SHIFT 3
1188#define DA7218_BIAS_EN_MASK (0x1 << 3)
1189
1190/* DA7218_IO_CTRL = 0xE0 */
1191#define DA7218_IO_VOLTAGE_LEVEL_SHIFT 0
1192#define DA7218_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
1193#define DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V 0
1194#define DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V 1
1195
1196/* DA7218_LDO_CTRL = 0xE1 */
1197#define DA7218_LDO_LEVEL_SELECT_SHIFT 4
1198#define DA7218_LDO_LEVEL_SELECT_MASK (0x3 << 4)
1199#define DA7218_LDO_EN_SHIFT 7
1200#define DA7218_LDO_EN_MASK (0x1 << 7)
1201
1202/* DA7218_SIDETONE_CTRL = 0xE4 */
1203#define DA7218_SIDETONE_MUTE_EN_SHIFT 6
1204#define DA7218_SIDETONE_MUTE_EN_MASK (0x1 << 6)
1205#define DA7218_SIDETONE_FILTER_EN_SHIFT 7
1206#define DA7218_SIDETONE_FILTER_EN_MASK (0x1 << 7)
1207
1208/* DA7218_SIDETONE_IN_SELECT = 0xE5 */
1209#define DA7218_SIDETONE_IN_SELECT_SHIFT 0
1210#define DA7218_SIDETONE_IN_SELECT_MASK (0x3 << 0)
1211#define DA7218_SIDETONE_IN_SELECT_MAX 4
1212
1213/* DA7218_SIDETONE_GAIN = 0xE6 */
1214#define DA7218_SIDETONE_GAIN_SHIFT 0
1215#define DA7218_SIDETONE_GAIN_MASK (0x1F << 0)
1216
1217/* DA7218_DROUTING_ST_OUTFILT_1L = 0xE8 */
1218#define DA7218_OUTFILT_ST_1L_SRC_SHIFT 0
1219#define DA7218_OUTFILT_ST_1L_SRC_MASK (0x7 << 0)
1220#define DA7218_DMIX_ST_SRC_OUTFILT1L 0
1221#define DA7218_DMIX_ST_SRC_OUTFILT1R 1
1222#define DA7218_DMIX_ST_SRC_SIDETONE 2
1223
1224/* DA7218_DROUTING_ST_OUTFILT_1R = 0xE9 */
1225#define DA7218_OUTFILT_ST_1R_SRC_SHIFT 0
1226#define DA7218_OUTFILT_ST_1R_SRC_MASK (0x7 << 0)
1227
1228/* DA7218_SIDETONE_BIQ_3STAGE_DATA = 0xEA */
1229#define DA7218_SIDETONE_BIQ_3STAGE_DATA_SHIFT 0
1230#define DA7218_SIDETONE_BIQ_3STAGE_DATA_MASK (0xFF << 0)
1231
1232/* DA7218_SIDETONE_BIQ_3STAGE_ADDR = 0xEB */
1233#define DA7218_SIDETONE_BIQ_3STAGE_ADDR_SHIFT 0
1234#define DA7218_SIDETONE_BIQ_3STAGE_ADDR_MASK (0x1F << 0)
1235#define DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE 30
1236
1237/* DA7218_EVENT_STATUS = 0xEC */
1238#define DA7218_HPLDET_JACK_STS_SHIFT 7
1239#define DA7218_HPLDET_JACK_STS_MASK (0x1 << 7)
1240
1241/* DA7218_EVENT = 0xED */
1242#define DA7218_LVL_DET_EVENT_SHIFT 0
1243#define DA7218_LVL_DET_EVENT_MASK (0x1 << 0)
1244#define DA7218_HPLDET_JACK_EVENT_SHIFT 7
1245#define DA7218_HPLDET_JACK_EVENT_MASK (0x1 << 7)
1246
1247/* DA7218_EVENT_MASK = 0xEE */
1248#define DA7218_LVL_DET_EVENT_MSK_SHIFT 0
1249#define DA7218_LVL_DET_EVENT_MSK_MASK (0x1 << 0)
1250#define DA7218_HPLDET_JACK_EVENT_IRQ_MSK_SHIFT 7
1251#define DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK (0x1 << 7)
1252
1253/* DA7218_DMIC_1_CTRL = 0xF0 */
1254#define DA7218_DMIC_1_DATA_SEL_SHIFT 0
1255#define DA7218_DMIC_1_DATA_SEL_MASK (0x1 << 0)
1256#define DA7218_DMIC_1_SAMPLEPHASE_SHIFT 1
1257#define DA7218_DMIC_1_SAMPLEPHASE_MASK (0x1 << 1)
1258#define DA7218_DMIC_1_CLK_RATE_SHIFT 2
1259#define DA7218_DMIC_1_CLK_RATE_MASK (0x1 << 2)
1260#define DA7218_DMIC_1L_EN_SHIFT 6
1261#define DA7218_DMIC_1L_EN_MASK (0x1 << 6)
1262#define DA7218_DMIC_1R_EN_SHIFT 7
1263#define DA7218_DMIC_1R_EN_MASK (0x1 << 7)
1264
1265/* DA7218_DMIC_2_CTRL = 0xF1 */
1266#define DA7218_DMIC_2_DATA_SEL_SHIFT 0
1267#define DA7218_DMIC_2_DATA_SEL_MASK (0x1 << 0)
1268#define DA7218_DMIC_2_SAMPLEPHASE_SHIFT 1
1269#define DA7218_DMIC_2_SAMPLEPHASE_MASK (0x1 << 1)
1270#define DA7218_DMIC_2_CLK_RATE_SHIFT 2
1271#define DA7218_DMIC_2_CLK_RATE_MASK (0x1 << 2)
1272#define DA7218_DMIC_2L_EN_SHIFT 6
1273#define DA7218_DMIC_2L_EN_MASK (0x1 << 6)
1274#define DA7218_DMIC_2R_EN_SHIFT 7
1275#define DA7218_DMIC_2R_EN_MASK (0x1 << 7)
1276
1277/* DA7218_IN_1L_GAIN = 0xF4 */
1278#define DA7218_IN_1L_DIGITAL_GAIN_SHIFT 0
1279#define DA7218_IN_1L_DIGITAL_GAIN_MASK (0x7F << 0)
1280#define DA7218_IN_DIGITAL_GAIN_MAX 0x7F
1281
1282/* DA7218_IN_1R_GAIN = 0xF5 */
1283#define DA7218_IN_1R_DIGITAL_GAIN_SHIFT 0
1284#define DA7218_IN_1R_DIGITAL_GAIN_MASK (0x7F << 0)
1285
1286/* DA7218_IN_2L_GAIN = 0xF6 */
1287#define DA7218_IN_2L_DIGITAL_GAIN_SHIFT 0
1288#define DA7218_IN_2L_DIGITAL_GAIN_MASK (0x7F << 0)
1289
1290/* DA7218_IN_2R_GAIN = 0xF7 */
1291#define DA7218_IN_2R_DIGITAL_GAIN_SHIFT 0
1292#define DA7218_IN_2R_DIGITAL_GAIN_MASK (0x7F << 0)
1293
1294/* DA7218_OUT_1L_GAIN = 0xF8 */
1295#define DA7218_OUT_1L_DIGITAL_GAIN_SHIFT 0
1296#define DA7218_OUT_1L_DIGITAL_GAIN_MASK (0xFF << 0)
1297#define DA7218_OUT_DIGITAL_GAIN_MIN 0x0
1298#define DA7218_OUT_DIGITAL_GAIN_MAX 0x97
1299
1300/* DA7218_OUT_1R_GAIN = 0xF9 */
1301#define DA7218_OUT_1R_DIGITAL_GAIN_SHIFT 0
1302#define DA7218_OUT_1R_DIGITAL_GAIN_MASK (0xFF << 0)
1303
1304/* DA7218_MICBIAS_CTRL = 0xFC */
1305#define DA7218_MICBIAS_1_LEVEL_SHIFT 0
1306#define DA7218_MICBIAS_1_LEVEL_MASK (0x7 << 0)
1307#define DA7218_MICBIAS_1_LP_MODE_SHIFT 3
1308#define DA7218_MICBIAS_1_LP_MODE_MASK (0x1 << 3)
1309#define DA7218_MICBIAS_2_LEVEL_SHIFT 4
1310#define DA7218_MICBIAS_2_LEVEL_MASK (0x7 << 4)
1311#define DA7218_MICBIAS_2_LP_MODE_SHIFT 7
1312#define DA7218_MICBIAS_2_LP_MODE_MASK (0x1 << 7)
1313
1314/* DA7218_MICBIAS_EN = 0xFD */
1315#define DA7218_MICBIAS_1_EN_SHIFT 0
1316#define DA7218_MICBIAS_1_EN_MASK (0x1 << 0)
1317#define DA7218_MICBIAS_2_EN_SHIFT 4
1318#define DA7218_MICBIAS_2_EN_MASK (0x1 << 4)
1319
1320
1321/*
1322 * General defines & data
1323 */
1324
1325/* Register inversion */
1326#define DA7218_NO_INVERT 0
1327#define DA7218_INVERT 1
1328
1329/* Byte related defines */
1330#define DA7218_BYTE_SHIFT 8
1331#define DA7218_BYTE_MASK 0xFF
1332#define DA7218_2BYTE_SHIFT 16
1333#define DA7218_2BYTE_MASK 0xFFFF
1334
1335/* PLL Output Frequencies */
1336#define DA7218_PLL_FREQ_OUT_90316 90316800
1337#define DA7218_PLL_FREQ_OUT_98304 98304000
1338
1339/* ALC Calibration */
1340#define DA7218_ALC_CALIB_DELAY_MIN 2500
1341#define DA7218_ALC_CALIB_DELAY_MAX 5000
1342#define DA7218_ALC_CALIB_MAX_TRIES 5
1343
1344/* Ref Oscillator */
1345#define DA7218_REF_OSC_CHECK_DELAY_MIN 5000
1346#define DA7218_REF_OSC_CHECK_DELAY_MAX 10000
1347#define DA7218_REF_OSC_CHECK_TRIES 4
1348
1349/* SRM */
1350#define DA7218_SRM_CHECK_DELAY 50
1351#define DA7218_SRM_CHECK_TRIES 8
1352
1353/* Mic Level Detect */
1354#define DA7218_MIC_LVL_DET_DELAY 50
1355
1356enum da7218_biq_cfg {
1357 DA7218_BIQ_CFG_DATA = 0,
1358 DA7218_BIQ_CFG_ADDR,
1359 DA7218_BIQ_CFG_SIZE,
1360};
1361
1362enum da7218_clk_src {
1363 DA7218_CLKSRC_MCLK = 0,
1364 DA7218_CLKSRC_MCLK_SQR,
1365};
1366
1367enum da7218_sys_clk {
1368 DA7218_SYSCLK_MCLK = 0,
1369 DA7218_SYSCLK_PLL,
1370 DA7218_SYSCLK_PLL_SRM,
1371 DA7218_SYSCLK_PLL_32KHZ
1372};
1373
1374enum da7218_dev_id {
1375 DA7217_DEV_ID = 0,
1376 DA7218_DEV_ID,
1377};
1378
1379/* Regulators */
1380enum da7218_supplies {
1381 DA7218_SUPPLY_VDD = 0,
1382 DA7218_SUPPLY_VDDMIC,
1383 DA7218_SUPPLY_VDDIO,
1384 DA7218_NUM_SUPPLIES,
1385};
1386
1387/* Private data */
1388struct da7218_priv {
1389 struct da7218_pdata *pdata;
1390
1391 struct regulator_bulk_data supplies[DA7218_NUM_SUPPLIES];
1392 struct regmap *regmap;
1393 int dev_id;
1394
1395 struct snd_soc_jack *jack;
1396 int irq;
1397
1398 struct clk *mclk;
1399 unsigned int mclk_rate;
1400
1401 bool hp_single_supply;
1402 bool master;
1403 u8 alc_en;
1404 u8 in_filt_en;
1405 u8 mic_lvl_det_en;
1406
1407 u8 biq_5stage_coeff[DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE];
1408 u8 stbiq_3stage_coeff[DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE];
1409};
1410
1411/* HP detect control */
1412int da7218_hpldet(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
1413
1414#endif /* _DA7218_H */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index f238c1e8a69c..c6d3b32bb4ae 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -968,10 +968,11 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
968 {"Mixin PGA", NULL, "Mic PGA"}, 968 {"Mixin PGA", NULL, "Mic PGA"},
969 {"ADC", NULL, "Mixin PGA"}, 969 {"ADC", NULL, "Mixin PGA"},
970 970
971 {"Sidetone Filter", NULL, "ADC"},
972 {"Mixer In", NULL, "Mixer In Supply"}, 971 {"Mixer In", NULL, "Mixer In Supply"},
973 {"Mixer In", "Mic Switch", "ADC"}, 972 {"Mixer In", "Mic Switch", "ADC"},
974 973
974 {"Sidetone Filter", NULL, "Mixer In"},
975
975 {"Tone Generator", NULL, "TONE"}, 976 {"Tone Generator", NULL, "TONE"},
976 977
977 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"), 978 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"),
@@ -1073,11 +1074,8 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1073 u32 freq_ref; 1074 u32 freq_ref;
1074 u64 frac_div; 1075 u64 frac_div;
1075 1076
1076 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */ 1077 /* Verify 2MHz - 54MHz MCLK provided, and set input divider */
1077 if (da7219->mclk_rate == 32768) { 1078 if (da7219->mclk_rate < 2000000) {
1078 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1079 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1080 } else if (da7219->mclk_rate < 2000000) {
1081 dev_err(codec->dev, "PLL input clock %d below valid range\n", 1079 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1082 da7219->mclk_rate); 1080 da7219->mclk_rate);
1083 return -EINVAL; 1081 return -EINVAL;
@@ -1118,9 +1116,6 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1118 case DA7219_SYSCLK_PLL_SRM: 1116 case DA7219_SYSCLK_PLL_SRM:
1119 pll_ctrl |= DA7219_PLL_MODE_SRM; 1117 pll_ctrl |= DA7219_PLL_MODE_SRM;
1120 break; 1118 break;
1121 case DA7219_SYSCLK_PLL_32KHZ:
1122 pll_ctrl |= DA7219_PLL_MODE_32KHZ;
1123 break;
1124 default: 1119 default:
1125 dev_err(codec->dev, "Invalid PLL config\n"); 1120 dev_err(codec->dev, "Invalid PLL config\n");
1126 return -EINVAL; 1121 return -EINVAL;
@@ -1306,7 +1301,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
1306 } 1301 }
1307 1302
1308 channels = params_channels(params); 1303 channels = params_channels(params);
1309 if ((channels < 1) | (channels > DA7219_DAI_CH_NUM_MAX)) { 1304 if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
1310 dev_err(codec->dev, 1305 dev_err(codec->dev,
1311 "Invalid number of channels, only 1 to %d supported\n", 1306 "Invalid number of channels, only 1 to %d supported\n",
1312 DA7219_DAI_CH_NUM_MAX); 1307 DA7219_DAI_CH_NUM_MAX);
@@ -1405,28 +1400,12 @@ static const struct of_device_id da7219_of_match[] = {
1405}; 1400};
1406MODULE_DEVICE_TABLE(of, da7219_of_match); 1401MODULE_DEVICE_TABLE(of, da7219_of_match);
1407 1402
1408static enum da7219_ldo_lvl_sel da7219_of_ldo_lvl(struct snd_soc_codec *codec,
1409 u32 val)
1410{
1411 switch (val) {
1412 case 1050:
1413 return DA7219_LDO_LVL_SEL_1_05V;
1414 case 1100:
1415 return DA7219_LDO_LVL_SEL_1_10V;
1416 case 1200:
1417 return DA7219_LDO_LVL_SEL_1_20V;
1418 case 1400:
1419 return DA7219_LDO_LVL_SEL_1_40V;
1420 default:
1421 dev_warn(codec->dev, "Invalid LDO level");
1422 return DA7219_LDO_LVL_SEL_1_05V;
1423 }
1424}
1425
1426static enum da7219_micbias_voltage 1403static enum da7219_micbias_voltage
1427 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1404 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1428{ 1405{
1429 switch (val) { 1406 switch (val) {
1407 case 1600:
1408 return DA7219_MICBIAS_1_6V;
1430 case 1800: 1409 case 1800:
1431 return DA7219_MICBIAS_1_8V; 1410 return DA7219_MICBIAS_1_8V;
1432 case 2000: 1411 case 2000:
@@ -1469,9 +1448,6 @@ static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec)
1469 if (!pdata) 1448 if (!pdata)
1470 return NULL; 1449 return NULL;
1471 1450
1472 if (of_property_read_u32(np, "dlg,ldo-lvl", &of_val32) >= 0)
1473 pdata->ldo_lvl_sel = da7219_of_ldo_lvl(codec, of_val32);
1474
1475 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0) 1451 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0)
1476 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32); 1452 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32);
1477 else 1453 else
@@ -1516,24 +1492,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
1516 snd_soc_update_bits(codec, DA7219_REFERENCES, 1492 snd_soc_update_bits(codec, DA7219_REFERENCES,
1517 DA7219_BIAS_EN_MASK, 1493 DA7219_BIAS_EN_MASK,
1518 DA7219_BIAS_EN_MASK); 1494 DA7219_BIAS_EN_MASK);
1519
1520 /* Enable Internal Digital LDO */
1521 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1522 DA7219_LDO_EN_MASK,
1523 DA7219_LDO_EN_MASK);
1524 } 1495 }
1525 break; 1496 break;
1526 case SND_SOC_BIAS_OFF: 1497 case SND_SOC_BIAS_OFF:
1527 /* Only disable if jack detection not active */ 1498 /* Only disable master bias if jack detection not active */
1528 if (!da7219->aad->jack) { 1499 if (!da7219->aad->jack)
1529 /* Bypass Internal Digital LDO */
1530 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1531 DA7219_LDO_EN_MASK, 0);
1532
1533 /* Master bias */
1534 snd_soc_update_bits(codec, DA7219_REFERENCES, 1500 snd_soc_update_bits(codec, DA7219_REFERENCES,
1535 DA7219_BIAS_EN_MASK, 0); 1501 DA7219_BIAS_EN_MASK, 0);
1536 }
1537 1502
1538 /* MCLK */ 1503 /* MCLK */
1539 if (da7219->mclk) 1504 if (da7219->mclk)
@@ -1600,21 +1565,9 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
1600 if (pdata) { 1565 if (pdata) {
1601 u8 micbias_lvl = 0; 1566 u8 micbias_lvl = 0;
1602 1567
1603 /* Internal LDO */
1604 switch (pdata->ldo_lvl_sel) {
1605 case DA7219_LDO_LVL_SEL_1_05V:
1606 case DA7219_LDO_LVL_SEL_1_10V:
1607 case DA7219_LDO_LVL_SEL_1_20V:
1608 case DA7219_LDO_LVL_SEL_1_40V:
1609 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1610 DA7219_LDO_LEVEL_SELECT_MASK,
1611 (pdata->ldo_lvl_sel <<
1612 DA7219_LDO_LEVEL_SELECT_SHIFT));
1613 break;
1614 }
1615
1616 /* Mic Bias voltages */ 1568 /* Mic Bias voltages */
1617 switch (pdata->micbias_lvl) { 1569 switch (pdata->micbias_lvl) {
1570 case DA7219_MICBIAS_1_6V:
1618 case DA7219_MICBIAS_1_8V: 1571 case DA7219_MICBIAS_1_8V:
1619 case DA7219_MICBIAS_2_0V: 1572 case DA7219_MICBIAS_2_0V:
1620 case DA7219_MICBIAS_2_2V: 1573 case DA7219_MICBIAS_2_2V:
@@ -1662,10 +1615,12 @@ static int da7219_probe(struct snd_soc_codec *codec)
1662 /* Check if MCLK provided */ 1615 /* Check if MCLK provided */
1663 da7219->mclk = devm_clk_get(codec->dev, "mclk"); 1616 da7219->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7219->mclk)) { 1617 if (IS_ERR(da7219->mclk)) {
1665 if (PTR_ERR(da7219->mclk) != -ENOENT) 1618 if (PTR_ERR(da7219->mclk) != -ENOENT) {
1666 return PTR_ERR(da7219->mclk); 1619 ret = PTR_ERR(da7219->mclk);
1667 else 1620 goto err_disable_reg;
1621 } else {
1668 da7219->mclk = NULL; 1622 da7219->mclk = NULL;
1623 }
1669 } 1624 }
1670 1625
1671 /* Default PC counter to free-running */ 1626 /* Default PC counter to free-running */
@@ -1693,7 +1648,16 @@ static int da7219_probe(struct snd_soc_codec *codec)
1693 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK); 1648 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
1694 1649
1695 /* Initialise AAD block */ 1650 /* Initialise AAD block */
1696 return da7219_aad_init(codec); 1651 ret = da7219_aad_init(codec);
1652 if (ret)
1653 goto err_disable_reg;
1654
1655 return 0;
1656
1657err_disable_reg:
1658 regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
1659
1660 return ret;
1697} 1661}
1698 1662
1699static int da7219_remove(struct snd_soc_codec *codec) 1663static int da7219_remove(struct snd_soc_codec *codec)
@@ -1776,7 +1740,7 @@ static struct reg_default da7219_reg_defaults[] = {
1776 { DA7219_DIG_ROUTING_DAC, 0x32 }, 1740 { DA7219_DIG_ROUTING_DAC, 0x32 },
1777 { DA7219_DAI_OFFSET_LOWER, 0x00 }, 1741 { DA7219_DAI_OFFSET_LOWER, 0x00 },
1778 { DA7219_DAI_OFFSET_UPPER, 0x00 }, 1742 { DA7219_DAI_OFFSET_UPPER, 0x00 },
1779 { DA7219_REFERENCES, 0x00 }, 1743 { DA7219_REFERENCES, 0x08 },
1780 { DA7219_MIXIN_L_SELECT, 0x00 }, 1744 { DA7219_MIXIN_L_SELECT, 0x00 },
1781 { DA7219_MIXIN_L_GAIN, 0x03 }, 1745 { DA7219_MIXIN_L_GAIN, 0x03 },
1782 { DA7219_ADC_L_GAIN, 0x6F }, 1746 { DA7219_ADC_L_GAIN, 0x6F },
@@ -1811,7 +1775,6 @@ static struct reg_default da7219_reg_defaults[] = {
1811 { DA7219_CHIP_ID1, 0x23 }, 1775 { DA7219_CHIP_ID1, 0x23 },
1812 { DA7219_CHIP_ID2, 0x93 }, 1776 { DA7219_CHIP_ID2, 0x93 },
1813 { DA7219_CHIP_REVISION, 0x00 }, 1777 { DA7219_CHIP_REVISION, 0x00 },
1814 { DA7219_LDO_CTRL, 0x00 },
1815 { DA7219_IO_CTRL, 0x00 }, 1778 { DA7219_IO_CTRL, 0x00 },
1816 { DA7219_GAIN_RAMP_CTRL, 0x00 }, 1779 { DA7219_GAIN_RAMP_CTRL, 0x00 },
1817 { DA7219_PC_COUNT, 0x02 }, 1780 { DA7219_PC_COUNT, 0x02 },
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index b514268c6c56..5a787e738084 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -85,7 +85,6 @@
85#define DA7219_CHIP_ID1 0x81 85#define DA7219_CHIP_ID1 0x81
86#define DA7219_CHIP_ID2 0x82 86#define DA7219_CHIP_ID2 0x82
87#define DA7219_CHIP_REVISION 0x83 87#define DA7219_CHIP_REVISION 0x83
88#define DA7219_LDO_CTRL 0x90
89#define DA7219_IO_CTRL 0x91 88#define DA7219_IO_CTRL 0x91
90#define DA7219_GAIN_RAMP_CTRL 0x92 89#define DA7219_GAIN_RAMP_CTRL 0x92
91#define DA7219_PC_COUNT 0x94 90#define DA7219_PC_COUNT 0x94
@@ -207,7 +206,6 @@
207#define DA7219_PLL_MODE_BYPASS (0x0 << 6) 206#define DA7219_PLL_MODE_BYPASS (0x0 << 6)
208#define DA7219_PLL_MODE_NORMAL (0x1 << 6) 207#define DA7219_PLL_MODE_NORMAL (0x1 << 6)
209#define DA7219_PLL_MODE_SRM (0x2 << 6) 208#define DA7219_PLL_MODE_SRM (0x2 << 6)
210#define DA7219_PLL_MODE_32KHZ (0x3 << 6)
211 209
212/* DA7219_PLL_FRAC_TOP = 0x22 */ 210/* DA7219_PLL_FRAC_TOP = 0x22 */
213#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0 211#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0
@@ -569,12 +567,6 @@
569#define DA7219_CHIP_MAJOR_SHIFT 4 567#define DA7219_CHIP_MAJOR_SHIFT 4
570#define DA7219_CHIP_MAJOR_MASK (0xF << 4) 568#define DA7219_CHIP_MAJOR_MASK (0xF << 4)
571 569
572/* DA7219_LDO_CTRL = 0x90 */
573#define DA7219_LDO_LEVEL_SELECT_SHIFT 4
574#define DA7219_LDO_LEVEL_SELECT_MASK (0x3 << 4)
575#define DA7219_LDO_EN_SHIFT 7
576#define DA7219_LDO_EN_MASK (0x1 << 7)
577
578/* DA7219_IO_CTRL = 0x91 */ 570/* DA7219_IO_CTRL = 0x91 */
579#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0 571#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0
580#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0) 572#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
@@ -787,7 +779,6 @@ enum da7219_sys_clk {
787 DA7219_SYSCLK_MCLK = 0, 779 DA7219_SYSCLK_MCLK = 0,
788 DA7219_SYSCLK_PLL, 780 DA7219_SYSCLK_PLL,
789 DA7219_SYSCLK_PLL_SRM, 781 DA7219_SYSCLK_PLL_SRM,
790 DA7219_SYSCLK_PLL_32KHZ
791}; 782};
792 783
793/* Regulators */ 784/* Regulators */
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
new file mode 100644
index 000000000000..1a2f33b4abfc
--- /dev/null
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -0,0 +1,659 @@
1/*
2 * hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
3 *
4 * Copyright (C) 2014-2015 Intel Corp
5 * Author: Samreen Nilofer <samreen.nilofer@intel.com>
6 * Subhransu S. Prusty <subhransu.s.prusty@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 published by
11 * the Free Software Foundation; version 2 of the License.
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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 */
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/module.h>
23#include <linux/pm_runtime.h>
24#include <linux/hdmi.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/hdaudio_ext.h>
28#include <sound/hda_i915.h>
29#include "../../hda/local.h"
30
31#define AMP_OUT_MUTE 0xb080
32#define AMP_OUT_UNMUTE 0xb000
33#define PIN_OUT (AC_PINCTL_OUT_EN)
34
35#define HDA_MAX_CONNECTIONS 32
36
37struct hdac_hdmi_cvt_params {
38 unsigned int channels_min;
39 unsigned int channels_max;
40 u32 rates;
41 u64 formats;
42 unsigned int maxbps;
43};
44
45struct hdac_hdmi_cvt {
46 hda_nid_t nid;
47 struct hdac_hdmi_cvt_params params;
48};
49
50struct hdac_hdmi_pin {
51 hda_nid_t nid;
52 int num_mux_nids;
53 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
54};
55
56struct hdac_hdmi_dai_pin_map {
57 int dai_id;
58 struct hdac_hdmi_pin pin;
59 struct hdac_hdmi_cvt cvt;
60};
61
62struct hdac_hdmi_priv {
63 hda_nid_t pin_nid[3];
64 hda_nid_t cvt_nid[3];
65 struct hdac_hdmi_dai_pin_map dai_map[3];
66};
67
68static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
69{
70 struct hdac_device *hdac = container_of(dev, struct hdac_device, dev);
71
72 return container_of(hdac, struct hdac_ext_device, hdac);
73}
74
75static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
76 hda_nid_t cvt_nid, hda_nid_t pin_nid,
77 u32 stream_tag, int format)
78{
79 unsigned int val;
80
81 dev_dbg(&hdac->hdac.dev, "cvt nid %d pnid %d stream %d format 0x%x\n",
82 cvt_nid, pin_nid, stream_tag, format);
83
84 val = (stream_tag << 4);
85
86 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
87 AC_VERB_SET_CHANNEL_STREAMID, val);
88 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
89 AC_VERB_SET_STREAM_FORMAT, format);
90
91 return 0;
92}
93
94static void
95hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
96 int packet_index, int byte_index)
97{
98 int val;
99
100 val = (packet_index << 5) | (byte_index & 0x1f);
101
102 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
103 AC_VERB_SET_HDMI_DIP_INDEX, val);
104}
105
106static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
107 hda_nid_t cvt_nid, hda_nid_t pin_nid)
108{
109 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
110 struct hdmi_audio_infoframe frame;
111 u8 *dip = (u8 *)&frame;
112 int ret;
113 int i;
114
115 hdmi_audio_infoframe_init(&frame);
116
117 /* Default stereo for now */
118 frame.channels = 2;
119
120 /* setup channel count */
121 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
122 AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
123
124 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
125 if (ret < 0)
126 return ret;
127
128 /* stop infoframe transmission */
129 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
130 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
131 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
132
133
134 /* Fill infoframe. Index auto-incremented */
135 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
136 for (i = 0; i < sizeof(frame); i++)
137 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
138 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
139
140 /* Start infoframe */
141 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
142 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
143 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
144
145 return 0;
146}
147
148static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
149 struct hdac_hdmi_dai_pin_map *dai_map, unsigned int pwr_state)
150{
151 /* Power up pin widget */
152 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->pin.nid, pwr_state))
153 snd_hdac_codec_write(&edev->hdac, dai_map->pin.nid, 0,
154 AC_VERB_SET_POWER_STATE, pwr_state);
155
156 /* Power up converter */
157 if (!snd_hdac_check_power_state(&edev->hdac, dai_map->cvt.nid, pwr_state))
158 snd_hdac_codec_write(&edev->hdac, dai_map->cvt.nid, 0,
159 AC_VERB_SET_POWER_STATE, pwr_state);
160}
161
162static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai)
164{
165 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
166 struct hdac_hdmi_priv *hdmi = hdac->private_data;
167 struct hdac_hdmi_dai_pin_map *dai_map;
168 struct hdac_ext_dma_params *dd;
169 int ret;
170
171 if (dai->id > 0) {
172 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
173 return -ENODEV;
174 }
175
176 dai_map = &hdmi->dai_map[dai->id];
177
178 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
179 dev_dbg(&hdac->hdac.dev, "stream tag from cpu dai %d format in cvt 0x%x\n",
180 dd->stream_tag, dd->format);
181
182 ret = hdac_hdmi_setup_audio_infoframe(hdac, dai_map->cvt.nid,
183 dai_map->pin.nid);
184 if (ret < 0)
185 return ret;
186
187 return hdac_hdmi_setup_stream(hdac, dai_map->cvt.nid, dai_map->pin.nid,
188 dd->stream_tag, dd->format);
189}
190
191static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
192 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
193{
194 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
195 struct hdac_ext_dma_params *dd;
196
197 if (dai->id > 0) {
198 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
199 return -ENODEV;
200 }
201
202 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
203 if (!dd)
204 return -ENOMEM;
205 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
206 params_channels(hparams), params_format(hparams),
207 24, 0);
208
209 snd_soc_dai_set_dma_data(dai, substream, (void *)dd);
210
211 return 0;
212}
213
214static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream,
215 struct snd_soc_dai *dai)
216{
217 struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
218 struct hdac_ext_dma_params *dd;
219 struct hdac_hdmi_priv *hdmi = edev->private_data;
220 struct hdac_hdmi_dai_pin_map *dai_map;
221
222 dai_map = &hdmi->dai_map[dai->id];
223
224 snd_hdac_codec_write(&edev->hdac, dai_map->cvt.nid, 0,
225 AC_VERB_SET_CHANNEL_STREAMID, 0);
226 snd_hdac_codec_write(&edev->hdac, dai_map->cvt.nid, 0,
227 AC_VERB_SET_STREAM_FORMAT, 0);
228
229 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
230 snd_soc_dai_set_dma_data(dai, substream, NULL);
231
232 kfree(dd);
233
234 return 0;
235}
236
237static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
238 struct snd_soc_dai *dai)
239{
240 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
241 struct hdac_hdmi_priv *hdmi = hdac->private_data;
242 struct hdac_hdmi_dai_pin_map *dai_map;
243 int val;
244
245 if (dai->id > 0) {
246 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
247 return -ENODEV;
248 }
249
250 dai_map = &hdmi->dai_map[dai->id];
251
252 val = snd_hdac_codec_read(&hdac->hdac, dai_map->pin.nid, 0,
253 AC_VERB_GET_PIN_SENSE, 0);
254 dev_info(&hdac->hdac.dev, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val);
255
256 if ((!(val & AC_PINSENSE_PRESENCE)) || (!(val & AC_PINSENSE_ELDV))) {
257 dev_err(&hdac->hdac.dev, "Monitor presence invalid with val: %x\n", val);
258 return -ENODEV;
259 }
260
261 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
262
263 snd_hdac_codec_write(&hdac->hdac, dai_map->pin.nid, 0,
264 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
265
266 snd_pcm_hw_constraint_step(substream->runtime, 0,
267 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
268
269 return 0;
270}
271
272static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
273 struct snd_soc_dai *dai)
274{
275 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
276 struct hdac_hdmi_priv *hdmi = hdac->private_data;
277 struct hdac_hdmi_dai_pin_map *dai_map;
278
279 dai_map = &hdmi->dai_map[dai->id];
280
281 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
282
283 snd_hdac_codec_write(&hdac->hdac, dai_map->pin.nid, 0,
284 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
285}
286
287static int
288hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
289{
290 int err;
291
292 /* Only stereo supported as of now */
293 cvt->params.channels_min = cvt->params.channels_max = 2;
294
295 err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
296 &cvt->params.rates,
297 &cvt->params.formats,
298 &cvt->params.maxbps);
299 if (err < 0)
300 dev_err(&hdac->dev,
301 "Failed to query pcm params for nid %d: %d\n",
302 cvt->nid, err);
303
304 return err;
305}
306
307static int hdac_hdmi_query_pin_connlist(struct hdac_ext_device *hdac,
308 struct hdac_hdmi_pin *pin)
309{
310 if (!(get_wcaps(&hdac->hdac, pin->nid) & AC_WCAP_CONN_LIST)) {
311 dev_warn(&hdac->hdac.dev,
312 "HDMI: pin %d wcaps %#x does not support connection list\n",
313 pin->nid, get_wcaps(&hdac->hdac, pin->nid));
314 return -EINVAL;
315 }
316
317 pin->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid,
318 pin->mux_nids, HDA_MAX_CONNECTIONS);
319 if (pin->num_mux_nids == 0) {
320 dev_err(&hdac->hdac.dev, "No connections found\n");
321 return -ENODEV;
322 }
323
324 return pin->num_mux_nids;
325}
326
327static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,
328 enum snd_soc_dapm_type id,
329 const char *wname, const char *stream)
330{
331 w->id = id;
332 w->name = wname;
333 w->sname = stream;
334 w->reg = SND_SOC_NOPM;
335 w->shift = 0;
336 w->kcontrol_news = NULL;
337 w->num_kcontrols = 0;
338 w->priv = NULL;
339}
340
341static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
342 const char *sink, const char *control, const char *src)
343{
344 route->sink = sink;
345 route->source = src;
346 route->control = control;
347 route->connected = NULL;
348}
349
350static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,
351 struct hdac_hdmi_dai_pin_map *dai_map)
352{
353 struct snd_soc_dapm_route route[1];
354 struct snd_soc_dapm_widget widgets[2] = { {0} };
355
356 memset(&route, 0, sizeof(route));
357
358 hdac_hdmi_fill_widget_info(&widgets[0], snd_soc_dapm_output,
359 "hif1 Output", NULL);
360 hdac_hdmi_fill_widget_info(&widgets[1], snd_soc_dapm_aif_in,
361 "Coverter 1", "hif1");
362
363 hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");
364
365 snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));
366 snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));
367}
368
369static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev,
370 struct hdac_hdmi_dai_pin_map *dai_map,
371 hda_nid_t pin_nid, hda_nid_t cvt_nid, int dai_id)
372{
373 int ret;
374
375 dai_map->dai_id = dai_id;
376 dai_map->pin.nid = pin_nid;
377
378 ret = hdac_hdmi_query_pin_connlist(edev, &dai_map->pin);
379 if (ret < 0) {
380 dev_err(&edev->hdac.dev,
381 "Error querying connection list: %d\n", ret);
382 return ret;
383 }
384
385 dai_map->cvt.nid = cvt_nid;
386
387 /* Enable out path for this pin widget */
388 snd_hdac_codec_write(&edev->hdac, pin_nid, 0,
389 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
390
391 /* Enable transmission */
392 snd_hdac_codec_write(&edev->hdac, cvt_nid, 0,
393 AC_VERB_SET_DIGI_CONVERT_1, 1);
394
395 /* Category Code (CC) to zero */
396 snd_hdac_codec_write(&edev->hdac, cvt_nid, 0,
397 AC_VERB_SET_DIGI_CONVERT_2, 0);
398
399 snd_hdac_codec_write(&edev->hdac, pin_nid, 0,
400 AC_VERB_SET_CONNECT_SEL, 0);
401
402 return hdac_hdmi_query_cvt_params(&edev->hdac, &dai_map->cvt);
403}
404
405/*
406 * Parse all nodes and store the cvt/pin nids in array
407 * Add one time initialization for pin and cvt widgets
408 */
409static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)
410{
411 hda_nid_t nid;
412 int i, num_nodes;
413 struct hdac_device *hdac = &edev->hdac;
414 struct hdac_hdmi_priv *hdmi = edev->private_data;
415 int cvt_nid = 0, pin_nid = 0;
416
417 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
418 if (!nid || num_nodes < 0) {
419 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
420 return -EINVAL;
421 }
422
423 hdac->num_nodes = num_nodes;
424 hdac->start_nid = nid;
425
426 for (i = 0; i < hdac->num_nodes; i++, nid++) {
427 unsigned int caps;
428 unsigned int type;
429
430 caps = get_wcaps(hdac, nid);
431 type = get_wcaps_type(caps);
432
433 if (!(caps & AC_WCAP_DIGITAL))
434 continue;
435
436 switch (type) {
437
438 case AC_WID_AUD_OUT:
439 hdmi->cvt_nid[cvt_nid] = nid;
440 cvt_nid++;
441 break;
442
443 case AC_WID_PIN:
444 hdmi->pin_nid[pin_nid] = nid;
445 pin_nid++;
446 break;
447 }
448 }
449
450 hdac->end_nid = nid;
451
452 if (!pin_nid || !cvt_nid)
453 return -EIO;
454
455 /*
456 * Currently on board only 1 pin and 1 converter is enabled for
457 * simplification, more will be added eventually
458 * So using fixed map for dai_id:pin:cvt
459 */
460 return hdac_hdmi_init_dai_map(edev, &hdmi->dai_map[0], hdmi->pin_nid[0],
461 hdmi->cvt_nid[0], 0);
462}
463
464static int hdmi_codec_probe(struct snd_soc_codec *codec)
465{
466 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
467 struct hdac_hdmi_priv *hdmi = edev->private_data;
468 struct snd_soc_dapm_context *dapm =
469 snd_soc_component_get_dapm(&codec->component);
470
471 edev->scodec = codec;
472
473 create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);
474
475 /* Imp: Store the card pointer in hda_codec */
476 edev->card = dapm->card->snd_card;
477
478 /*
479 * hdac_device core already sets the state to active and calls
480 * get_noresume. So enable runtime and set the device to suspend.
481 */
482 pm_runtime_enable(&edev->hdac.dev);
483 pm_runtime_put(&edev->hdac.dev);
484 pm_runtime_suspend(&edev->hdac.dev);
485
486 return 0;
487}
488
489static int hdmi_codec_remove(struct snd_soc_codec *codec)
490{
491 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
492
493 pm_runtime_disable(&edev->hdac.dev);
494 return 0;
495}
496
497static struct snd_soc_codec_driver hdmi_hda_codec = {
498 .probe = hdmi_codec_probe,
499 .remove = hdmi_codec_remove,
500 .idle_bias_off = true,
501};
502
503static struct snd_soc_dai_ops hdmi_dai_ops = {
504 .startup = hdac_hdmi_pcm_open,
505 .shutdown = hdac_hdmi_pcm_close,
506 .hw_params = hdac_hdmi_set_hw_params,
507 .prepare = hdac_hdmi_playback_prepare,
508 .hw_free = hdac_hdmi_playback_cleanup,
509};
510
511static struct snd_soc_dai_driver hdmi_dais[] = {
512 { .name = "intel-hdmi-hif1",
513 .playback = {
514 .stream_name = "hif1",
515 .channels_min = 2,
516 .channels_max = 2,
517 .rates = SNDRV_PCM_RATE_32000 |
518 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
519 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
520 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
521 .formats = SNDRV_PCM_FMTBIT_S16_LE |
522 SNDRV_PCM_FMTBIT_S20_3LE |
523 SNDRV_PCM_FMTBIT_S24_LE |
524 SNDRV_PCM_FMTBIT_S32_LE,
525
526 },
527 .ops = &hdmi_dai_ops,
528 },
529};
530
531static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
532{
533 struct hdac_device *codec = &edev->hdac;
534 struct hdac_hdmi_priv *hdmi_priv;
535 int ret = 0;
536
537 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
538 if (hdmi_priv == NULL)
539 return -ENOMEM;
540
541 edev->private_data = hdmi_priv;
542
543 dev_set_drvdata(&codec->dev, edev);
544
545 ret = hdac_hdmi_parse_and_map_nid(edev);
546 if (ret < 0)
547 return ret;
548
549 /* ASoC specific initialization */
550 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
551 hdmi_dais, ARRAY_SIZE(hdmi_dais));
552}
553
554static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
555{
556 snd_soc_unregister_codec(&edev->hdac.dev);
557
558 return 0;
559}
560
561#ifdef CONFIG_PM
562static int hdac_hdmi_runtime_suspend(struct device *dev)
563{
564 struct hdac_ext_device *edev = to_hda_ext_device(dev);
565 struct hdac_device *hdac = &edev->hdac;
566 struct hdac_bus *bus = hdac->bus;
567 int err;
568
569 dev_dbg(dev, "Enter: %s\n", __func__);
570
571 /* controller may not have been initialized for the first time */
572 if (!bus)
573 return 0;
574
575 /* Power down afg */
576 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))
577 snd_hdac_codec_write(hdac, hdac->afg, 0,
578 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
579
580 err = snd_hdac_display_power(bus, false);
581 if (err < 0) {
582 dev_err(bus->dev, "Cannot turn on display power on i915\n");
583 return err;
584 }
585
586 return 0;
587}
588
589static int hdac_hdmi_runtime_resume(struct device *dev)
590{
591 struct hdac_ext_device *edev = to_hda_ext_device(dev);
592 struct hdac_device *hdac = &edev->hdac;
593 struct hdac_bus *bus = hdac->bus;
594 int err;
595
596 dev_dbg(dev, "Enter: %s\n", __func__);
597
598 /* controller may not have been initialized for the first time */
599 if (!bus)
600 return 0;
601
602 err = snd_hdac_display_power(bus, true);
603 if (err < 0) {
604 dev_err(bus->dev, "Cannot turn on display power on i915\n");
605 return err;
606 }
607
608 /* Power up afg */
609 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
610 snd_hdac_codec_write(hdac, hdac->afg, 0,
611 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
612
613 return 0;
614}
615#else
616#define hdac_hdmi_runtime_suspend NULL
617#define hdac_hdmi_runtime_resume NULL
618#endif
619
620static const struct dev_pm_ops hdac_hdmi_pm = {
621 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)
622};
623
624static const struct hda_device_id hdmi_list[] = {
625 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
626 {}
627};
628
629MODULE_DEVICE_TABLE(hdaudio, hdmi_list);
630
631static struct hdac_ext_driver hdmi_driver = {
632 . hdac = {
633 .driver = {
634 .name = "HDMI HDA Codec",
635 .pm = &hdac_hdmi_pm,
636 },
637 .id_table = hdmi_list,
638 },
639 .probe = hdac_hdmi_dev_probe,
640 .remove = hdac_hdmi_dev_remove,
641};
642
643static int __init hdmi_init(void)
644{
645 return snd_hda_ext_driver_register(&hdmi_driver);
646}
647
648static void __exit hdmi_exit(void)
649{
650 snd_hda_ext_driver_unregister(&hdmi_driver);
651}
652
653module_init(hdmi_init);
654module_exit(hdmi_exit);
655
656MODULE_LICENSE("GPL v2");
657MODULE_DESCRIPTION("HDMI HD codec");
658MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");
659MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
new file mode 100644
index 000000000000..9b6e8840a1b5
--- /dev/null
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -0,0 +1,490 @@
1/*
2 * Driver of Inno codec for rk3036 by Rockchip Inc.
3 *
4 * Author: Rockchip Inc.
5 * Author: Zheng ShunQian<zhengsq@rock-chips.com>
6 */
7
8#include <sound/soc.h>
9#include <sound/tlv.h>
10#include <sound/soc-dapm.h>
11#include <sound/soc-dai.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14
15#include <linux/platform_device.h>
16#include <linux/of.h>
17#include <linux/clk.h>
18#include <linux/regmap.h>
19#include <linux/device.h>
20#include <linux/mfd/syscon.h>
21#include <linux/module.h>
22#include <linux/io.h>
23
24#include "inno_rk3036.h"
25
26struct rk3036_codec_priv {
27 void __iomem *base;
28 struct clk *pclk;
29 struct regmap *regmap;
30 struct device *dev;
31};
32
33static const DECLARE_TLV_DB_MINMAX(rk3036_codec_hp_tlv, -39, 0);
34
35static int rk3036_codec_antipop_info(struct snd_kcontrol *kcontrol,
36 struct snd_ctl_elem_info *uinfo)
37{
38 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
39 uinfo->count = 2;
40 uinfo->value.integer.min = 0;
41 uinfo->value.integer.max = 1;
42
43 return 0;
44}
45
46static int rk3036_codec_antipop_get(struct snd_kcontrol *kcontrol,
47 struct snd_ctl_elem_value *ucontrol)
48{
49 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
50 int val, ret, regval;
51
52 ret = snd_soc_component_read(component, INNO_R09, &regval);
53 if (ret)
54 return ret;
55 val = ((regval >> INNO_R09_HPL_ANITPOP_SHIFT) &
56 INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
57 ucontrol->value.integer.value[0] = val;
58
59 val = ((regval >> INNO_R09_HPR_ANITPOP_SHIFT) &
60 INNO_R09_HP_ANTIPOP_MSK) == INNO_R09_HP_ANTIPOP_ON;
61 ucontrol->value.integer.value[1] = val;
62
63 return 0;
64}
65
66static int rk3036_codec_antipop_put(struct snd_kcontrol *kcontrol,
67 struct snd_ctl_elem_value *ucontrol)
68{
69 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
70 int val, ret, regmsk;
71
72 val = (ucontrol->value.integer.value[0] ?
73 INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
74 INNO_R09_HPL_ANITPOP_SHIFT;
75 val |= (ucontrol->value.integer.value[1] ?
76 INNO_R09_HP_ANTIPOP_ON : INNO_R09_HP_ANTIPOP_OFF) <<
77 INNO_R09_HPR_ANITPOP_SHIFT;
78
79 regmsk = INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPL_ANITPOP_SHIFT |
80 INNO_R09_HP_ANTIPOP_MSK << INNO_R09_HPR_ANITPOP_SHIFT;
81
82 ret = snd_soc_component_update_bits(component, INNO_R09,
83 regmsk, val);
84 if (ret < 0)
85 return ret;
86
87 return 0;
88}
89
90#define SOC_RK3036_CODEC_ANTIPOP_DECL(xname) \
91{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
92 .info = rk3036_codec_antipop_info, .get = rk3036_codec_antipop_get, \
93 .put = rk3036_codec_antipop_put, }
94
95static const struct snd_kcontrol_new rk3036_codec_dapm_controls[] = {
96 SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", INNO_R07, INNO_R08,
97 INNO_HP_GAIN_SHIFT, INNO_HP_GAIN_N39DB,
98 INNO_HP_GAIN_0DB, 0, rk3036_codec_hp_tlv),
99 SOC_DOUBLE("Zero Cross Switch", INNO_R06, INNO_R06_VOUTL_CZ_SHIFT,
100 INNO_R06_VOUTR_CZ_SHIFT, 1, 0),
101 SOC_DOUBLE("Headphone Switch", INNO_R09, INNO_R09_HPL_MUTE_SHIFT,
102 INNO_R09_HPR_MUTE_SHIFT, 1, 0),
103 SOC_RK3036_CODEC_ANTIPOP_DECL("Anti-pop Switch"),
104};
105
106static const struct snd_kcontrol_new rk3036_codec_hpl_mixer_controls[] = {
107 SOC_DAPM_SINGLE("DAC Left Out Switch", INNO_R09,
108 INNO_R09_DACL_SWITCH_SHIFT, 1, 0),
109};
110
111static const struct snd_kcontrol_new rk3036_codec_hpr_mixer_controls[] = {
112 SOC_DAPM_SINGLE("DAC Right Out Switch", INNO_R09,
113 INNO_R09_DACR_SWITCH_SHIFT, 1, 0),
114};
115
116static const struct snd_kcontrol_new rk3036_codec_hpl_switch_controls[] = {
117 SOC_DAPM_SINGLE("HP Left Out Switch", INNO_R05,
118 INNO_R05_HPL_WORK_SHIFT, 1, 0),
119};
120
121static const struct snd_kcontrol_new rk3036_codec_hpr_switch_controls[] = {
122 SOC_DAPM_SINGLE("HP Right Out Switch", INNO_R05,
123 INNO_R05_HPR_WORK_SHIFT, 1, 0),
124};
125
126static const struct snd_soc_dapm_widget rk3036_codec_dapm_widgets[] = {
127 SND_SOC_DAPM_SUPPLY_S("DAC PWR", 1, INNO_R06,
128 INNO_R06_DAC_EN_SHIFT, 0, NULL, 0),
129 SND_SOC_DAPM_SUPPLY_S("DACL VREF", 2, INNO_R04,
130 INNO_R04_DACL_VREF_SHIFT, 0, NULL, 0),
131 SND_SOC_DAPM_SUPPLY_S("DACR VREF", 2, INNO_R04,
132 INNO_R04_DACR_VREF_SHIFT, 0, NULL, 0),
133 SND_SOC_DAPM_SUPPLY_S("DACL HiLo VREF", 3, INNO_R06,
134 INNO_R06_DACL_HILO_VREF_SHIFT, 0, NULL, 0),
135 SND_SOC_DAPM_SUPPLY_S("DACR HiLo VREF", 3, INNO_R06,
136 INNO_R06_DACR_HILO_VREF_SHIFT, 0, NULL, 0),
137 SND_SOC_DAPM_SUPPLY_S("DACR CLK", 3, INNO_R04,
138 INNO_R04_DACR_CLK_SHIFT, 0, NULL, 0),
139 SND_SOC_DAPM_SUPPLY_S("DACL CLK", 3, INNO_R04,
140 INNO_R04_DACL_CLK_SHIFT, 0, NULL, 0),
141
142 SND_SOC_DAPM_DAC("DACL", "Left Playback", INNO_R04,
143 INNO_R04_DACL_SW_SHIFT, 0),
144 SND_SOC_DAPM_DAC("DACR", "Right Playback", INNO_R04,
145 INNO_R04_DACR_SW_SHIFT, 0),
146
147 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
148 rk3036_codec_hpl_mixer_controls,
149 ARRAY_SIZE(rk3036_codec_hpl_mixer_controls)),
150 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
151 rk3036_codec_hpr_mixer_controls,
152 ARRAY_SIZE(rk3036_codec_hpr_mixer_controls)),
153
154 SND_SOC_DAPM_PGA("HP Left Out", INNO_R05,
155 INNO_R05_HPL_EN_SHIFT, 0, NULL, 0),
156 SND_SOC_DAPM_PGA("HP Right Out", INNO_R05,
157 INNO_R05_HPR_EN_SHIFT, 0, NULL, 0),
158
159 SND_SOC_DAPM_MIXER("HP Left Switch", SND_SOC_NOPM, 0, 0,
160 rk3036_codec_hpl_switch_controls,
161 ARRAY_SIZE(rk3036_codec_hpl_switch_controls)),
162 SND_SOC_DAPM_MIXER("HP Right Switch", SND_SOC_NOPM, 0, 0,
163 rk3036_codec_hpr_switch_controls,
164 ARRAY_SIZE(rk3036_codec_hpr_switch_controls)),
165
166 SND_SOC_DAPM_OUTPUT("HPL"),
167 SND_SOC_DAPM_OUTPUT("HPR"),
168};
169
170static const struct snd_soc_dapm_route rk3036_codec_dapm_routes[] = {
171 {"DACL VREF", NULL, "DAC PWR"},
172 {"DACR VREF", NULL, "DAC PWR"},
173 {"DACL HiLo VREF", NULL, "DAC PWR"},
174 {"DACR HiLo VREF", NULL, "DAC PWR"},
175 {"DACL CLK", NULL, "DAC PWR"},
176 {"DACR CLK", NULL, "DAC PWR"},
177
178 {"DACL", NULL, "DACL VREF"},
179 {"DACL", NULL, "DACL HiLo VREF"},
180 {"DACL", NULL, "DACL CLK"},
181 {"DACR", NULL, "DACR VREF"},
182 {"DACR", NULL, "DACR HiLo VREF"},
183 {"DACR", NULL, "DACR CLK"},
184
185 {"Left Headphone Mixer", "DAC Left Out Switch", "DACL"},
186 {"Right Headphone Mixer", "DAC Right Out Switch", "DACR"},
187 {"HP Left Out", NULL, "Left Headphone Mixer"},
188 {"HP Right Out", NULL, "Right Headphone Mixer"},
189
190 {"HP Left Switch", "HP Left Out Switch", "HP Left Out"},
191 {"HP Right Switch", "HP Right Out Switch", "HP Right Out"},
192
193 {"HPL", NULL, "HP Left Switch"},
194 {"HPR", NULL, "HP Right Switch"},
195};
196
197static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
198{
199 struct snd_soc_codec *codec = dai->codec;
200 unsigned int reg01_val = 0, reg02_val = 0, reg03_val = 0;
201
202 dev_dbg(codec->dev, "rk3036_codec dai set fmt : %08x\n", fmt);
203
204 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
205 case SND_SOC_DAIFMT_CBS_CFS:
206 reg01_val |= INNO_R01_PINDIR_IN_SLAVE |
207 INNO_R01_I2SMODE_SLAVE;
208 break;
209 case SND_SOC_DAIFMT_CBM_CFM:
210 reg01_val |= INNO_R01_PINDIR_OUT_MASTER |
211 INNO_R01_I2SMODE_MASTER;
212 break;
213 default:
214 dev_err(codec->dev, "invalid fmt\n");
215 return -EINVAL;
216 }
217
218 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
219 case SND_SOC_DAIFMT_DSP_A:
220 reg02_val |= INNO_R02_DACM_PCM;
221 break;
222 case SND_SOC_DAIFMT_I2S:
223 reg02_val |= INNO_R02_DACM_I2S;
224 break;
225 case SND_SOC_DAIFMT_RIGHT_J:
226 reg02_val |= INNO_R02_DACM_RJM;
227 break;
228 case SND_SOC_DAIFMT_LEFT_J:
229 reg02_val |= INNO_R02_DACM_LJM;
230 break;
231 default:
232 dev_err(codec->dev, "set dai format failed\n");
233 return -EINVAL;
234 }
235
236 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
237 case SND_SOC_DAIFMT_NB_NF:
238 reg02_val |= INNO_R02_LRCP_NORMAL;
239 reg03_val |= INNO_R03_BCP_NORMAL;
240 break;
241 case SND_SOC_DAIFMT_IB_IF:
242 reg02_val |= INNO_R02_LRCP_REVERSAL;
243 reg03_val |= INNO_R03_BCP_REVERSAL;
244 break;
245 case SND_SOC_DAIFMT_IB_NF:
246 reg02_val |= INNO_R02_LRCP_REVERSAL;
247 reg03_val |= INNO_R03_BCP_NORMAL;
248 break;
249 case SND_SOC_DAIFMT_NB_IF:
250 reg02_val |= INNO_R02_LRCP_NORMAL;
251 reg03_val |= INNO_R03_BCP_REVERSAL;
252 break;
253 default:
254 dev_err(codec->dev, "set dai format failed\n");
255 return -EINVAL;
256 }
257
258 snd_soc_update_bits(codec, INNO_R01, INNO_R01_I2SMODE_MSK |
259 INNO_R01_PINDIR_MSK, reg01_val);
260 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
261 INNO_R02_DACM_MSK, reg02_val);
262 snd_soc_update_bits(codec, INNO_R03, INNO_R03_BCP_MSK, reg03_val);
263
264 return 0;
265}
266
267static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
268 struct snd_pcm_hw_params *hw_params,
269 struct snd_soc_dai *dai)
270{
271 struct snd_soc_codec *codec = dai->codec;
272 unsigned int reg02_val = 0, reg03_val = 0;
273
274 switch (params_format(hw_params)) {
275 case SNDRV_PCM_FORMAT_S16_LE:
276 reg02_val |= INNO_R02_VWL_16BIT;
277 break;
278 case SNDRV_PCM_FORMAT_S20_3LE:
279 reg02_val |= INNO_R02_VWL_20BIT;
280 break;
281 case SNDRV_PCM_FORMAT_S24_LE:
282 reg02_val |= INNO_R02_VWL_24BIT;
283 break;
284 case SNDRV_PCM_FORMAT_S32_LE:
285 reg02_val |= INNO_R02_VWL_32BIT;
286 break;
287 default:
288 return -EINVAL;
289 }
290
291 reg02_val |= INNO_R02_LRCP_NORMAL;
292 reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK;
293
294 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK |
295 INNO_R02_VWL_MSK, reg02_val);
296 snd_soc_update_bits(codec, INNO_R03, INNO_R03_DACR_MSK |
297 INNO_R03_FWL_MSK, reg03_val);
298 return 0;
299}
300
301#define RK3036_CODEC_RATES (SNDRV_PCM_RATE_8000 | \
302 SNDRV_PCM_RATE_16000 | \
303 SNDRV_PCM_RATE_32000 | \
304 SNDRV_PCM_RATE_44100 | \
305 SNDRV_PCM_RATE_48000 | \
306 SNDRV_PCM_RATE_96000)
307
308#define RK3036_CODEC_FMTS (SNDRV_PCM_FMTBIT_S16_LE | \
309 SNDRV_PCM_FMTBIT_S20_3LE | \
310 SNDRV_PCM_FMTBIT_S24_LE | \
311 SNDRV_PCM_FMTBIT_S32_LE)
312
313static struct snd_soc_dai_ops rk3036_codec_dai_ops = {
314 .set_fmt = rk3036_codec_dai_set_fmt,
315 .hw_params = rk3036_codec_dai_hw_params,
316};
317
318static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = {
319 {
320 .name = "rk3036-codec-dai",
321 .playback = {
322 .stream_name = "Playback",
323 .channels_min = 1,
324 .channels_max = 2,
325 .rates = RK3036_CODEC_RATES,
326 .formats = RK3036_CODEC_FMTS,
327 },
328 .ops = &rk3036_codec_dai_ops,
329 .symmetric_rates = 1,
330 },
331};
332
333static void rk3036_codec_reset(struct snd_soc_codec *codec)
334{
335 snd_soc_write(codec, INNO_R00,
336 INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET);
337 snd_soc_write(codec, INNO_R00,
338 INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK);
339}
340
341static int rk3036_codec_probe(struct snd_soc_codec *codec)
342{
343 rk3036_codec_reset(codec);
344 return 0;
345}
346
347static int rk3036_codec_remove(struct snd_soc_codec *codec)
348{
349 rk3036_codec_reset(codec);
350 return 0;
351}
352
353static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
354 enum snd_soc_bias_level level)
355{
356 switch (level) {
357 case SND_SOC_BIAS_STANDBY:
358 /* set a big current for capacitor charging. */
359 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
360 /* start precharge */
361 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_PRECHARGE);
362
363 break;
364
365 case SND_SOC_BIAS_OFF:
366 /* set a big current for capacitor discharging. */
367 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR);
368 /* start discharge. */
369 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_DISCHARGE);
370
371 break;
372 default:
373 break;
374 }
375
376 return 0;
377}
378
379static struct snd_soc_codec_driver rk3036_codec_driver = {
380 .probe = rk3036_codec_probe,
381 .remove = rk3036_codec_remove,
382 .set_bias_level = rk3036_codec_set_bias_level,
383 .controls = rk3036_codec_dapm_controls,
384 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls),
385 .dapm_routes = rk3036_codec_dapm_routes,
386 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes),
387 .dapm_widgets = rk3036_codec_dapm_widgets,
388 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets),
389};
390
391static const struct regmap_config rk3036_codec_regmap_config = {
392 .reg_bits = 32,
393 .reg_stride = 4,
394 .val_bits = 32,
395};
396
397#define GRF_SOC_CON0 0x00140
398#define GRF_ACODEC_SEL (BIT(10) | BIT(16 + 10))
399
400static int rk3036_codec_platform_probe(struct platform_device *pdev)
401{
402 struct rk3036_codec_priv *priv;
403 struct device_node *of_node = pdev->dev.of_node;
404 struct resource *res;
405 void __iomem *base;
406 struct regmap *grf;
407 int ret;
408
409 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
410 if (!priv)
411 return -ENOMEM;
412
413 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
414 base = devm_ioremap_resource(&pdev->dev, res);
415 if (IS_ERR(base))
416 return PTR_ERR(base);
417
418 priv->base = base;
419 priv->regmap = devm_regmap_init_mmio(&pdev->dev, priv->base,
420 &rk3036_codec_regmap_config);
421 if (IS_ERR(priv->regmap)) {
422 dev_err(&pdev->dev, "init regmap failed\n");
423 return PTR_ERR(priv->regmap);
424 }
425
426 grf = syscon_regmap_lookup_by_phandle(of_node, "rockchip,grf");
427 if (IS_ERR(grf)) {
428 dev_err(&pdev->dev, "needs 'rockchip,grf' property\n");
429 return PTR_ERR(grf);
430 }
431 ret = regmap_write(grf, GRF_SOC_CON0, GRF_ACODEC_SEL);
432 if (ret) {
433 dev_err(&pdev->dev, "Could not write to GRF: %d\n", ret);
434 return ret;
435 }
436
437 priv->pclk = devm_clk_get(&pdev->dev, "acodec_pclk");
438 if (IS_ERR(priv->pclk))
439 return PTR_ERR(priv->pclk);
440
441 ret = clk_prepare_enable(priv->pclk);
442 if (ret < 0) {
443 dev_err(&pdev->dev, "failed to enable clk\n");
444 return ret;
445 }
446
447 priv->dev = &pdev->dev;
448 dev_set_drvdata(&pdev->dev, priv);
449
450 ret = snd_soc_register_codec(&pdev->dev, &rk3036_codec_driver,
451 rk3036_codec_dai_driver,
452 ARRAY_SIZE(rk3036_codec_dai_driver));
453 if (ret) {
454 clk_disable_unprepare(priv->pclk);
455 dev_set_drvdata(&pdev->dev, NULL);
456 }
457
458 return ret;
459}
460
461static int rk3036_codec_platform_remove(struct platform_device *pdev)
462{
463 struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev);
464
465 snd_soc_unregister_codec(&pdev->dev);
466 clk_disable_unprepare(priv->pclk);
467
468 return 0;
469}
470
471static const struct of_device_id rk3036_codec_of_match[] = {
472 { .compatible = "rockchip,rk3036-codec", },
473 {}
474};
475MODULE_DEVICE_TABLE(of, rk3036_codec_of_match);
476
477static struct platform_driver rk3036_codec_platform_driver = {
478 .driver = {
479 .name = "rk3036-codec-platform",
480 .of_match_table = of_match_ptr(rk3036_codec_of_match),
481 },
482 .probe = rk3036_codec_platform_probe,
483 .remove = rk3036_codec_platform_remove,
484};
485
486module_platform_driver(rk3036_codec_platform_driver);
487
488MODULE_AUTHOR("Rockchip Inc.");
489MODULE_DESCRIPTION("Rockchip rk3036 codec driver");
490MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/inno_rk3036.h b/sound/soc/codecs/inno_rk3036.h
new file mode 100644
index 000000000000..da759c6c7501
--- /dev/null
+++ b/sound/soc/codecs/inno_rk3036.h
@@ -0,0 +1,123 @@
1/*
2 * Driver of Inno Codec for rk3036 by Rockchip Inc.
3 *
4 * Author: Zheng ShunQian<zhengsq@rock-chips.com>
5 */
6
7#ifndef _INNO_RK3036_CODEC_H
8#define _INNO_RK3036_CODEC_H
9
10/* codec registers */
11#define INNO_R00 0x00
12#define INNO_R01 0x0c
13#define INNO_R02 0x10
14#define INNO_R03 0x14
15#define INNO_R04 0x88
16#define INNO_R05 0x8c
17#define INNO_R06 0x90
18#define INNO_R07 0x94
19#define INNO_R08 0x98
20#define INNO_R09 0x9c
21#define INNO_R10 0xa0
22
23/* register bit filed */
24#define INNO_R00_CSR_RESET (0x0 << 0) /*codec system reset*/
25#define INNO_R00_CSR_WORK (0x1 << 0)
26#define INNO_R00_CDCR_RESET (0x0 << 1) /*codec digital core reset*/
27#define INNO_R00_CDCR_WORK (0x1 << 1)
28#define INNO_R00_PRB_DISABLE (0x0 << 6) /*power reset bypass*/
29#define INNO_R00_PRB_ENABLE (0x1 << 6)
30
31#define INNO_R01_I2SMODE_MSK (0x1 << 4)
32#define INNO_R01_I2SMODE_SLAVE (0x0 << 4)
33#define INNO_R01_I2SMODE_MASTER (0x1 << 4)
34#define INNO_R01_PINDIR_MSK (0x1 << 5)
35#define INNO_R01_PINDIR_IN_SLAVE (0x0 << 5) /*direction of pin*/
36#define INNO_R01_PINDIR_OUT_MASTER (0x1 << 5)
37
38#define INNO_R02_LRS_MSK (0x1 << 2)
39#define INNO_R02_LRS_NORMAL (0x0 << 2) /*DAC Left Right Swap*/
40#define INNO_R02_LRS_SWAP (0x1 << 2)
41#define INNO_R02_DACM_MSK (0x3 << 3)
42#define INNO_R02_DACM_PCM (0x3 << 3) /*DAC Mode*/
43#define INNO_R02_DACM_I2S (0x2 << 3)
44#define INNO_R02_DACM_LJM (0x1 << 3)
45#define INNO_R02_DACM_RJM (0x0 << 3)
46#define INNO_R02_VWL_MSK (0x3 << 5)
47#define INNO_R02_VWL_32BIT (0x3 << 5) /*1/2Frame Valid Word Len*/
48#define INNO_R02_VWL_24BIT (0x2 << 5)
49#define INNO_R02_VWL_20BIT (0x1 << 5)
50#define INNO_R02_VWL_16BIT (0x0 << 5)
51#define INNO_R02_LRCP_MSK (0x1 << 7)
52#define INNO_R02_LRCP_NORMAL (0x0 << 7) /*Left Right Polarity*/
53#define INNO_R02_LRCP_REVERSAL (0x1 << 7)
54
55#define INNO_R03_BCP_MSK (0x1 << 0)
56#define INNO_R03_BCP_NORMAL (0x0 << 0) /*DAC bit clock polarity*/
57#define INNO_R03_BCP_REVERSAL (0x1 << 0)
58#define INNO_R03_DACR_MSK (0x1 << 1)
59#define INNO_R03_DACR_RESET (0x0 << 1) /*DAC Reset*/
60#define INNO_R03_DACR_WORK (0x1 << 1)
61#define INNO_R03_FWL_MSK (0x3 << 2)
62#define INNO_R03_FWL_32BIT (0x3 << 2) /*1/2Frame Word Length*/
63#define INNO_R03_FWL_24BIT (0x2 << 2)
64#define INNO_R03_FWL_20BIT (0x1 << 2)
65#define INNO_R03_FWL_16BIT (0x0 << 2)
66
67#define INNO_R04_DACR_SW_SHIFT 0
68#define INNO_R04_DACL_SW_SHIFT 1
69#define INNO_R04_DACR_CLK_SHIFT 2
70#define INNO_R04_DACL_CLK_SHIFT 3
71#define INNO_R04_DACR_VREF_SHIFT 4
72#define INNO_R04_DACL_VREF_SHIFT 5
73
74#define INNO_R05_HPR_EN_SHIFT 0
75#define INNO_R05_HPL_EN_SHIFT 1
76#define INNO_R05_HPR_WORK_SHIFT 2
77#define INNO_R05_HPL_WORK_SHIFT 3
78
79#define INNO_R06_VOUTR_CZ_SHIFT 0
80#define INNO_R06_VOUTL_CZ_SHIFT 1
81#define INNO_R06_DACR_HILO_VREF_SHIFT 2
82#define INNO_R06_DACL_HILO_VREF_SHIFT 3
83#define INNO_R06_DAC_EN_SHIFT 5
84
85#define INNO_R06_DAC_PRECHARGE (0x0 << 4) /*PreCharge control for DAC*/
86#define INNO_R06_DAC_DISCHARGE (0x1 << 4)
87
88#define INNO_HP_GAIN_SHIFT 0
89/* Gain of output, 1.5db step: -39db(0x0) ~ 0db(0x1a) ~ 6db(0x1f) */
90#define INNO_HP_GAIN_0DB 0x1a
91#define INNO_HP_GAIN_N39DB 0x0
92
93#define INNO_R09_HP_ANTIPOP_MSK 0x3
94#define INNO_R09_HP_ANTIPOP_OFF 0x1
95#define INNO_R09_HP_ANTIPOP_ON 0x2
96#define INNO_R09_HPR_ANITPOP_SHIFT 0
97#define INNO_R09_HPL_ANITPOP_SHIFT 2
98#define INNO_R09_HPR_MUTE_SHIFT 4
99#define INNO_R09_HPL_MUTE_SHIFT 5
100#define INNO_R09_DACR_SWITCH_SHIFT 6
101#define INNO_R09_DACL_SWITCH_SHIFT 7
102
103#define INNO_R10_CHARGE_SEL_CUR_400I_YES (0x0 << 0)
104#define INNO_R10_CHARGE_SEL_CUR_400I_NO (0x1 << 0)
105#define INNO_R10_CHARGE_SEL_CUR_260I_YES (0x0 << 1)
106#define INNO_R10_CHARGE_SEL_CUR_260I_NO (0x1 << 1)
107#define INNO_R10_CHARGE_SEL_CUR_130I_YES (0x0 << 2)
108#define INNO_R10_CHARGE_SEL_CUR_130I_NO (0x1 << 2)
109#define INNO_R10_CHARGE_SEL_CUR_100I_YES (0x0 << 3)
110#define INNO_R10_CHARGE_SEL_CUR_100I_NO (0x1 << 3)
111#define INNO_R10_CHARGE_SEL_CUR_050I_YES (0x0 << 4)
112#define INNO_R10_CHARGE_SEL_CUR_050I_NO (0x1 << 4)
113#define INNO_R10_CHARGE_SEL_CUR_027I_YES (0x0 << 5)
114#define INNO_R10_CHARGE_SEL_CUR_027I_NO (0x1 << 5)
115
116#define INNO_R10_MAX_CUR (INNO_R10_CHARGE_SEL_CUR_400I_YES | \
117 INNO_R10_CHARGE_SEL_CUR_260I_YES | \
118 INNO_R10_CHARGE_SEL_CUR_130I_YES | \
119 INNO_R10_CHARGE_SEL_CUR_100I_YES | \
120 INNO_R10_CHARGE_SEL_CUR_050I_YES | \
121 INNO_R10_CHARGE_SEL_CUR_027I_YES)
122
123#endif
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index f5e3dce2633a..5b1dfb1518fb 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -12,6 +12,7 @@
12 * max98357a.c -- MAX98357A ALSA SoC Codec driver 12 * max98357a.c -- MAX98357A ALSA SoC Codec driver
13 */ 13 */
14 14
15#include <linux/acpi.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/err.h> 17#include <linux/err.h>
17#include <linux/gpio.h> 18#include <linux/gpio.h>
@@ -123,10 +124,19 @@ static const struct of_device_id max98357a_device_id[] = {
123MODULE_DEVICE_TABLE(of, max98357a_device_id); 124MODULE_DEVICE_TABLE(of, max98357a_device_id);
124#endif 125#endif
125 126
127#ifdef CONFIG_ACPI
128static const struct acpi_device_id max98357a_acpi_match[] = {
129 { "MX98357A", 0 },
130 {},
131};
132MODULE_DEVICE_TABLE(acpi, max98357a_acpi_match);
133#endif
134
126static struct platform_driver max98357a_platform_driver = { 135static struct platform_driver max98357a_platform_driver = {
127 .driver = { 136 .driver = {
128 .name = "max98357a", 137 .name = "max98357a",
129 .of_match_table = of_match_ptr(max98357a_device_id), 138 .of_match_table = of_match_ptr(max98357a_device_id),
139 .acpi_match_table = ACPI_PTR(max98357a_acpi_match),
130 }, 140 },
131 .probe = max98357a_platform_probe, 141 .probe = max98357a_platform_probe,
132 .remove = max98357a_platform_remove, 142 .remove = max98357a_platform_remove,
diff --git a/sound/soc/codecs/pcm3168a-i2c.c b/sound/soc/codecs/pcm3168a-i2c.c
new file mode 100644
index 000000000000..6feb0901dfeb
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a-i2c.c
@@ -0,0 +1,66 @@
1/*
2 * PCM3168A codec i2c driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/module.h>
16
17#include <sound/soc.h>
18
19#include "pcm3168a.h"
20
21static int pcm3168a_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *id)
23{
24 struct regmap *regmap;
25
26 regmap = devm_regmap_init_i2c(i2c, &pcm3168a_regmap);
27 if (IS_ERR(regmap))
28 return PTR_ERR(regmap);
29
30 return pcm3168a_probe(&i2c->dev, regmap);
31}
32
33static int pcm3168a_i2c_remove(struct i2c_client *i2c)
34{
35 pcm3168a_remove(&i2c->dev);
36
37 return 0;
38}
39
40static const struct i2c_device_id pcm3168a_i2c_id[] = {
41 { "pcm3168a", },
42 { }
43};
44MODULE_DEVICE_TABLE(i2c, pcm3168a_i2c_id);
45
46static const struct of_device_id pcm3168a_of_match[] = {
47 { .compatible = "ti,pcm3168a", },
48 { }
49};
50MODULE_DEVICE_TABLE(of, pcm3168a_of_match);
51
52static struct i2c_driver pcm3168a_i2c_driver = {
53 .probe = pcm3168a_i2c_probe,
54 .remove = pcm3168a_i2c_remove,
55 .id_table = pcm3168a_i2c_id,
56 .driver = {
57 .name = "pcm3168a",
58 .of_match_table = pcm3168a_of_match,
59 .pm = &pcm3168a_pm_ops,
60 },
61};
62module_i2c_driver(pcm3168a_i2c_driver);
63
64MODULE_DESCRIPTION("PCM3168A I2C codec driver");
65MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
66MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a-spi.c b/sound/soc/codecs/pcm3168a-spi.c
new file mode 100644
index 000000000000..03945a27ae40
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a-spi.c
@@ -0,0 +1,65 @@
1/*
2 * PCM3168A codec spi driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/spi/spi.h>
16
17#include <sound/soc.h>
18
19#include "pcm3168a.h"
20
21static int pcm3168a_spi_probe(struct spi_device *spi)
22{
23 struct regmap *regmap;
24
25 regmap = devm_regmap_init_spi(spi, &pcm3168a_regmap);
26 if (IS_ERR(regmap))
27 return PTR_ERR(regmap);
28
29 return pcm3168a_probe(&spi->dev, regmap);
30}
31
32static int pcm3168a_spi_remove(struct spi_device *spi)
33{
34 pcm3168a_remove(&spi->dev);
35
36 return 0;
37}
38
39static const struct spi_device_id pcm3168a_spi_id[] = {
40 { "pcm3168a", },
41 { },
42};
43MODULE_DEVICE_TABLE(spi, pcm3168a_spi_id);
44
45static const struct of_device_id pcm3168a_of_match[] = {
46 { .compatible = "ti,pcm3168a", },
47 { }
48};
49MODULE_DEVICE_TABLE(of, pcm3168a_of_match);
50
51static struct spi_driver pcm3168a_spi_driver = {
52 .probe = pcm3168a_spi_probe,
53 .remove = pcm3168a_spi_remove,
54 .id_table = pcm3168a_spi_id,
55 .driver = {
56 .name = "pcm3168a",
57 .of_match_table = pcm3168a_of_match,
58 .pm = &pcm3168a_pm_ops,
59 },
60};
61module_spi_driver(pcm3168a_spi_driver);
62
63MODULE_DESCRIPTION("PCM3168A SPI codec driver");
64MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
65MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
new file mode 100644
index 000000000000..44b268aa4dd8
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a.c
@@ -0,0 +1,767 @@
1/*
2 * PCM3168A codec driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/module.h>
16#include <linux/pm_runtime.h>
17#include <linux/regulator/consumer.h>
18
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22
23#include "pcm3168a.h"
24
25#define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
26 SNDRV_PCM_FMTBIT_S24_3LE | \
27 SNDRV_PCM_FMTBIT_S24_LE | \
28 SNDRV_PCM_FMTBIT_S32_LE)
29
30#define PCM3168A_FMT_I2S 0x0
31#define PCM3168A_FMT_LEFT_J 0x1
32#define PCM3168A_FMT_RIGHT_J 0x2
33#define PCM3168A_FMT_RIGHT_J_16 0x3
34#define PCM3168A_FMT_DSP_A 0x4
35#define PCM3168A_FMT_DSP_B 0x5
36#define PCM3168A_FMT_DSP_MASK 0x4
37
38#define PCM3168A_NUM_SUPPLIES 6
39static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
40 "VDD1",
41 "VDD2",
42 "VCCAD1",
43 "VCCAD2",
44 "VCCDA1",
45 "VCCDA2"
46};
47
48struct pcm3168a_priv {
49 struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
50 struct regmap *regmap;
51 struct clk *scki;
52 bool adc_master_mode;
53 bool dac_master_mode;
54 unsigned long sysclk;
55 unsigned int adc_fmt;
56 unsigned int dac_fmt;
57};
58
59static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
60
61static SOC_ENUM_SINGLE_DECL(pcm3168a_d1_roll_off, PCM3168A_DAC_OP_FLT,
62 PCM3168A_DAC_FLT_SHIFT, pcm3168a_roll_off);
63static SOC_ENUM_SINGLE_DECL(pcm3168a_d2_roll_off, PCM3168A_DAC_OP_FLT,
64 PCM3168A_DAC_FLT_SHIFT + 1, pcm3168a_roll_off);
65static SOC_ENUM_SINGLE_DECL(pcm3168a_d3_roll_off, PCM3168A_DAC_OP_FLT,
66 PCM3168A_DAC_FLT_SHIFT + 2, pcm3168a_roll_off);
67static SOC_ENUM_SINGLE_DECL(pcm3168a_d4_roll_off, PCM3168A_DAC_OP_FLT,
68 PCM3168A_DAC_FLT_SHIFT + 3, pcm3168a_roll_off);
69
70static const char *const pcm3168a_volume_type[] = {
71 "Individual", "Master + Individual" };
72
73static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_volume_type, PCM3168A_DAC_ATT_DEMP_ZF,
74 PCM3168A_DAC_ATMDDA_SHIFT, pcm3168a_volume_type);
75
76static const char *const pcm3168a_att_speed_mult[] = { "2048", "4096" };
77
78static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_att_mult, PCM3168A_DAC_ATT_DEMP_ZF,
79 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_att_speed_mult);
80
81static const char *const pcm3168a_demp[] = {
82 "Disabled", "48khz", "44.1khz", "32khz" };
83
84static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_demp, PCM3168A_DAC_ATT_DEMP_ZF,
85 PCM3168A_DAC_DEMP_SHIFT, pcm3168a_demp);
86
87static const char *const pcm3168a_zf_func[] = {
88 "DAC 1/2/3/4 AND", "DAC 1/2/3/4 OR", "DAC 1/2/3 AND",
89 "DAC 1/2/3 OR", "DAC 4 AND", "DAC 4 OR" };
90
91static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_func, PCM3168A_DAC_ATT_DEMP_ZF,
92 PCM3168A_DAC_AZRO_SHIFT, pcm3168a_zf_func);
93
94static const char *const pcm3168a_pol[] = { "Active High", "Active Low" };
95
96static SOC_ENUM_SINGLE_DECL(pcm3168a_dac_zf_pol, PCM3168A_DAC_ATT_DEMP_ZF,
97 PCM3168A_DAC_ATSPDA_SHIFT, pcm3168a_pol);
98
99static const char *const pcm3168a_con[] = { "Differential", "Single-Ended" };
100
101static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc1_con, PCM3168A_ADC_SEAD,
102 0, 1, pcm3168a_con);
103static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc2_con, PCM3168A_ADC_SEAD,
104 2, 3, pcm3168a_con);
105static SOC_ENUM_DOUBLE_DECL(pcm3168a_adc3_con, PCM3168A_ADC_SEAD,
106 4, 5, pcm3168a_con);
107
108static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_volume_type, PCM3168A_ADC_ATT_OVF,
109 PCM3168A_ADC_ATMDAD_SHIFT, pcm3168a_volume_type);
110
111static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_att_mult, PCM3168A_ADC_ATT_OVF,
112 PCM3168A_ADC_ATSPAD_SHIFT, pcm3168a_att_speed_mult);
113
114static SOC_ENUM_SINGLE_DECL(pcm3168a_adc_ov_pol, PCM3168A_ADC_ATT_OVF,
115 PCM3168A_ADC_OVFP_SHIFT, pcm3168a_pol);
116
117/* -100db to 0db, register values 0-54 cause mute */
118static const DECLARE_TLV_DB_SCALE(pcm3168a_dac_tlv, -10050, 50, 1);
119
120/* -100db to 20db, register values 0-14 cause mute */
121static const DECLARE_TLV_DB_SCALE(pcm3168a_adc_tlv, -10050, 50, 1);
122
123static const struct snd_kcontrol_new pcm3168a_snd_controls[] = {
124 SOC_SINGLE("DAC Power-Save Switch", PCM3168A_DAC_PWR_MST_FMT,
125 PCM3168A_DAC_PSMDA_SHIFT, 1, 1),
126 SOC_ENUM("DAC1 Digital Filter roll-off", pcm3168a_d1_roll_off),
127 SOC_ENUM("DAC2 Digital Filter roll-off", pcm3168a_d2_roll_off),
128 SOC_ENUM("DAC3 Digital Filter roll-off", pcm3168a_d3_roll_off),
129 SOC_ENUM("DAC4 Digital Filter roll-off", pcm3168a_d4_roll_off),
130 SOC_DOUBLE("DAC1 Invert Switch", PCM3168A_DAC_INV, 0, 1, 1, 0),
131 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
132 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
133 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
134 SOC_DOUBLE_STS("DAC1 Zero Flag", PCM3168A_DAC_ZERO, 0, 1, 1, 0),
135 SOC_DOUBLE_STS("DAC2 Zero Flag", PCM3168A_DAC_ZERO, 2, 3, 1, 0),
136 SOC_DOUBLE_STS("DAC3 Zero Flag", PCM3168A_DAC_ZERO, 4, 5, 1, 0),
137 SOC_DOUBLE_STS("DAC4 Zero Flag", PCM3168A_DAC_ZERO, 6, 7, 1, 0),
138 SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type),
139 SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult),
140 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
141 SOC_ENUM("DAC Zero Flag Function", pcm3168a_dac_zf_func),
142 SOC_ENUM("DAC Zero Flag Polarity", pcm3168a_dac_zf_pol),
143 SOC_SINGLE_RANGE_TLV("Master Playback Volume",
144 PCM3168A_DAC_VOL_MASTER, 0, 54, 255, 0,
145 pcm3168a_dac_tlv),
146 SOC_DOUBLE_R_RANGE_TLV("DAC1 Playback Volume",
147 PCM3168A_DAC_VOL_CHAN_START,
148 PCM3168A_DAC_VOL_CHAN_START + 1,
149 0, 54, 255, 0, pcm3168a_dac_tlv),
150 SOC_DOUBLE_R_RANGE_TLV("DAC2 Playback Volume",
151 PCM3168A_DAC_VOL_CHAN_START + 2,
152 PCM3168A_DAC_VOL_CHAN_START + 3,
153 0, 54, 255, 0, pcm3168a_dac_tlv),
154 SOC_DOUBLE_R_RANGE_TLV("DAC3 Playback Volume",
155 PCM3168A_DAC_VOL_CHAN_START + 4,
156 PCM3168A_DAC_VOL_CHAN_START + 5,
157 0, 54, 255, 0, pcm3168a_dac_tlv),
158 SOC_DOUBLE_R_RANGE_TLV("DAC4 Playback Volume",
159 PCM3168A_DAC_VOL_CHAN_START + 6,
160 PCM3168A_DAC_VOL_CHAN_START + 7,
161 0, 54, 255, 0, pcm3168a_dac_tlv),
162 SOC_SINGLE("ADC1 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
163 PCM3168A_ADC_BYP_SHIFT, 1, 1),
164 SOC_SINGLE("ADC2 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
165 PCM3168A_ADC_BYP_SHIFT + 1, 1, 1),
166 SOC_SINGLE("ADC3 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
167 PCM3168A_ADC_BYP_SHIFT + 2, 1, 1),
168 SOC_ENUM("ADC1 Connection Type", pcm3168a_adc1_con),
169 SOC_ENUM("ADC2 Connection Type", pcm3168a_adc2_con),
170 SOC_ENUM("ADC3 Connection Type", pcm3168a_adc3_con),
171 SOC_DOUBLE("ADC1 Invert Switch", PCM3168A_ADC_INV, 0, 1, 1, 0),
172 SOC_DOUBLE("ADC2 Invert Switch", PCM3168A_ADC_INV, 2, 3, 1, 0),
173 SOC_DOUBLE("ADC3 Invert Switch", PCM3168A_ADC_INV, 4, 5, 1, 0),
174 SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0),
175 SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0),
176 SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0),
177 SOC_DOUBLE_STS("ADC1 Overflow Flag", PCM3168A_ADC_OV, 0, 1, 1, 0),
178 SOC_DOUBLE_STS("ADC2 Overflow Flag", PCM3168A_ADC_OV, 2, 3, 1, 0),
179 SOC_DOUBLE_STS("ADC3 Overflow Flag", PCM3168A_ADC_OV, 4, 5, 1, 0),
180 SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type),
181 SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult),
182 SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol),
183 SOC_SINGLE_RANGE_TLV("Master Capture Volume",
184 PCM3168A_ADC_VOL_MASTER, 0, 14, 255, 0,
185 pcm3168a_adc_tlv),
186 SOC_DOUBLE_R_RANGE_TLV("ADC1 Capture Volume",
187 PCM3168A_ADC_VOL_CHAN_START,
188 PCM3168A_ADC_VOL_CHAN_START + 1,
189 0, 14, 255, 0, pcm3168a_adc_tlv),
190 SOC_DOUBLE_R_RANGE_TLV("ADC2 Capture Volume",
191 PCM3168A_ADC_VOL_CHAN_START + 2,
192 PCM3168A_ADC_VOL_CHAN_START + 3,
193 0, 14, 255, 0, pcm3168a_adc_tlv),
194 SOC_DOUBLE_R_RANGE_TLV("ADC3 Capture Volume",
195 PCM3168A_ADC_VOL_CHAN_START + 4,
196 PCM3168A_ADC_VOL_CHAN_START + 5,
197 0, 14, 255, 0, pcm3168a_adc_tlv)
198};
199
200static const struct snd_soc_dapm_widget pcm3168a_dapm_widgets[] = {
201 SND_SOC_DAPM_DAC("DAC1", "Playback", PCM3168A_DAC_OP_FLT,
202 PCM3168A_DAC_OPEDA_SHIFT, 1),
203 SND_SOC_DAPM_DAC("DAC2", "Playback", PCM3168A_DAC_OP_FLT,
204 PCM3168A_DAC_OPEDA_SHIFT + 1, 1),
205 SND_SOC_DAPM_DAC("DAC3", "Playback", PCM3168A_DAC_OP_FLT,
206 PCM3168A_DAC_OPEDA_SHIFT + 2, 1),
207 SND_SOC_DAPM_DAC("DAC4", "Playback", PCM3168A_DAC_OP_FLT,
208 PCM3168A_DAC_OPEDA_SHIFT + 3, 1),
209
210 SND_SOC_DAPM_OUTPUT("AOUT1L"),
211 SND_SOC_DAPM_OUTPUT("AOUT1R"),
212 SND_SOC_DAPM_OUTPUT("AOUT2L"),
213 SND_SOC_DAPM_OUTPUT("AOUT2R"),
214 SND_SOC_DAPM_OUTPUT("AOUT3L"),
215 SND_SOC_DAPM_OUTPUT("AOUT3R"),
216 SND_SOC_DAPM_OUTPUT("AOUT4L"),
217 SND_SOC_DAPM_OUTPUT("AOUT4R"),
218
219 SND_SOC_DAPM_ADC("ADC1", "Capture", PCM3168A_ADC_PWR_HPFB,
220 PCM3168A_ADC_PSVAD_SHIFT, 1),
221 SND_SOC_DAPM_ADC("ADC2", "Capture", PCM3168A_ADC_PWR_HPFB,
222 PCM3168A_ADC_PSVAD_SHIFT + 1, 1),
223 SND_SOC_DAPM_ADC("ADC3", "Capture", PCM3168A_ADC_PWR_HPFB,
224 PCM3168A_ADC_PSVAD_SHIFT + 2, 1),
225
226 SND_SOC_DAPM_INPUT("AIN1L"),
227 SND_SOC_DAPM_INPUT("AIN1R"),
228 SND_SOC_DAPM_INPUT("AIN2L"),
229 SND_SOC_DAPM_INPUT("AIN2R"),
230 SND_SOC_DAPM_INPUT("AIN3L"),
231 SND_SOC_DAPM_INPUT("AIN3R")
232};
233
234static const struct snd_soc_dapm_route pcm3168a_dapm_routes[] = {
235 /* Playback */
236 { "AOUT1L", NULL, "DAC1" },
237 { "AOUT1R", NULL, "DAC1" },
238
239 { "AOUT2L", NULL, "DAC2" },
240 { "AOUT2R", NULL, "DAC2" },
241
242 { "AOUT3L", NULL, "DAC3" },
243 { "AOUT3R", NULL, "DAC3" },
244
245 { "AOUT4L", NULL, "DAC4" },
246 { "AOUT4R", NULL, "DAC4" },
247
248 /* Capture */
249 { "ADC1", NULL, "AIN1L" },
250 { "ADC1", NULL, "AIN1R" },
251
252 { "ADC2", NULL, "AIN2L" },
253 { "ADC2", NULL, "AIN2R" },
254
255 { "ADC3", NULL, "AIN3L" },
256 { "ADC3", NULL, "AIN3R" }
257};
258
259static unsigned int pcm3168a_scki_ratios[] = {
260 768,
261 512,
262 384,
263 256,
264 192,
265 128
266};
267
268#define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios)
269#define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
270
271#define PCM1368A_MAX_SYSCLK 36864000
272
273static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
274{
275 int ret;
276
277 ret = regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE, 0);
278 if (ret)
279 return ret;
280
281 /* Internal reset is de-asserted after 3846 SCKI cycles */
282 msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk));
283
284 return regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE,
285 PCM3168A_MRST_MASK | PCM3168A_SRST_MASK);
286}
287
288static int pcm3168a_digital_mute(struct snd_soc_dai *dai, int mute)
289{
290 struct snd_soc_codec *codec = dai->codec;
291 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
292
293 regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0);
294
295 return 0;
296}
297
298static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
299 int clk_id, unsigned int freq, int dir)
300{
301 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);
302
303 if (freq > PCM1368A_MAX_SYSCLK)
304 return -EINVAL;
305
306 pcm3168a->sysclk = freq;
307
308 return 0;
309}
310
311static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
312 unsigned int format, bool dac)
313{
314 struct snd_soc_codec *codec = dai->codec;
315 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
316 u32 fmt, reg, mask, shift;
317 bool master_mode;
318
319 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
320 case SND_SOC_DAIFMT_LEFT_J:
321 fmt = PCM3168A_FMT_LEFT_J;
322 break;
323 case SND_SOC_DAIFMT_I2S:
324 fmt = PCM3168A_FMT_I2S;
325 break;
326 case SND_SOC_DAIFMT_RIGHT_J:
327 fmt = PCM3168A_FMT_RIGHT_J;
328 break;
329 case SND_SOC_DAIFMT_DSP_A:
330 fmt = PCM3168A_FMT_DSP_A;
331 break;
332 case SND_SOC_DAIFMT_DSP_B:
333 fmt = PCM3168A_FMT_DSP_B;
334 break;
335 default:
336 dev_err(codec->dev, "unsupported dai format\n");
337 return -EINVAL;
338 }
339
340 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
341 case SND_SOC_DAIFMT_CBS_CFS:
342 master_mode = false;
343 break;
344 case SND_SOC_DAIFMT_CBM_CFM:
345 master_mode = true;
346 break;
347 default:
348 dev_err(codec->dev, "unsupported master/slave mode\n");
349 return -EINVAL;
350 }
351
352 switch (format & SND_SOC_DAIFMT_INV_MASK) {
353 case SND_SOC_DAIFMT_NB_NF:
354 break;
355 default:
356 return -EINVAL;
357 }
358
359 if (dac) {
360 reg = PCM3168A_DAC_PWR_MST_FMT;
361 mask = PCM3168A_DAC_FMT_MASK;
362 shift = PCM3168A_DAC_FMT_SHIFT;
363 pcm3168a->dac_master_mode = master_mode;
364 pcm3168a->dac_fmt = fmt;
365 } else {
366 reg = PCM3168A_ADC_MST_FMT;
367 mask = PCM3168A_ADC_FMTAD_MASK;
368 shift = PCM3168A_ADC_FMTAD_SHIFT;
369 pcm3168a->adc_master_mode = master_mode;
370 pcm3168a->adc_fmt = fmt;
371 }
372
373 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
374
375 return 0;
376}
377
378static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
379 unsigned int format)
380{
381 return pcm3168a_set_dai_fmt(dai, format, true);
382}
383
384static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
385 unsigned int format)
386{
387 return pcm3168a_set_dai_fmt(dai, format, false);
388}
389
390static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
391 struct snd_pcm_hw_params *params,
392 struct snd_soc_dai *dai)
393{
394 struct snd_soc_codec *codec = dai->codec;
395 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
396 bool tx, master_mode;
397 u32 val, mask, shift, reg;
398 unsigned int rate, channels, fmt, ratio, max_ratio;
399 int i, min_frame_size;
400 snd_pcm_format_t format;
401
402 rate = params_rate(params);
403 format = params_format(params);
404 channels = params_channels(params);
405
406 ratio = pcm3168a->sysclk / rate;
407
408 tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
409 if (tx) {
410 max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
411 reg = PCM3168A_DAC_PWR_MST_FMT;
412 mask = PCM3168A_DAC_MSDA_MASK;
413 shift = PCM3168A_DAC_MSDA_SHIFT;
414 master_mode = pcm3168a->dac_master_mode;
415 fmt = pcm3168a->dac_fmt;
416 } else {
417 max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
418 reg = PCM3168A_ADC_MST_FMT;
419 mask = PCM3168A_ADC_MSAD_MASK;
420 shift = PCM3168A_ADC_MSAD_SHIFT;
421 master_mode = pcm3168a->adc_master_mode;
422 fmt = pcm3168a->adc_fmt;
423 }
424
425 for (i = 0; i < max_ratio; i++) {
426 if (pcm3168a_scki_ratios[i] == ratio)
427 break;
428 }
429
430 if (i == max_ratio) {
431 dev_err(codec->dev, "unsupported sysclk ratio\n");
432 return -EINVAL;
433 }
434
435 min_frame_size = params_width(params) * 2;
436 switch (min_frame_size) {
437 case 32:
438 if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
439 dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
440 return -EINVAL;
441 }
442 fmt = PCM3168A_FMT_RIGHT_J_16;
443 break;
444 case 48:
445 if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
446 dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
447 return -EINVAL;
448 }
449 break;
450 case 64:
451 break;
452 default:
453 dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
454 return -EINVAL;
455 }
456
457 if (master_mode)
458 val = ((i + 1) << shift);
459 else
460 val = 0;
461
462 regmap_update_bits(pcm3168a->regmap, reg, mask, val);
463
464 if (tx) {
465 mask = PCM3168A_DAC_FMT_MASK;
466 shift = PCM3168A_DAC_FMT_SHIFT;
467 } else {
468 mask = PCM3168A_ADC_FMTAD_MASK;
469 shift = PCM3168A_ADC_FMTAD_SHIFT;
470 }
471
472 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
473
474 return 0;
475}
476
477static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
478 .set_fmt = pcm3168a_set_dai_fmt_dac,
479 .set_sysclk = pcm3168a_set_dai_sysclk,
480 .hw_params = pcm3168a_hw_params,
481 .digital_mute = pcm3168a_digital_mute
482};
483
484static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
485 .set_fmt = pcm3168a_set_dai_fmt_adc,
486 .set_sysclk = pcm3168a_set_dai_sysclk,
487 .hw_params = pcm3168a_hw_params
488};
489
490static struct snd_soc_dai_driver pcm3168a_dais[] = {
491 {
492 .name = "pcm3168a-dac",
493 .playback = {
494 .stream_name = "Playback",
495 .channels_min = 1,
496 .channels_max = 8,
497 .rates = SNDRV_PCM_RATE_8000_192000,
498 .formats = PCM3168A_FORMATS
499 },
500 .ops = &pcm3168a_dac_dai_ops
501 },
502 {
503 .name = "pcm3168a-adc",
504 .capture = {
505 .stream_name = "Capture",
506 .channels_min = 1,
507 .channels_max = 6,
508 .rates = SNDRV_PCM_RATE_8000_96000,
509 .formats = PCM3168A_FORMATS
510 },
511 .ops = &pcm3168a_adc_dai_ops
512 },
513};
514
515static const struct reg_default pcm3168a_reg_default[] = {
516 { PCM3168A_RST_SMODE, PCM3168A_MRST_MASK | PCM3168A_SRST_MASK },
517 { PCM3168A_DAC_PWR_MST_FMT, 0x00 },
518 { PCM3168A_DAC_OP_FLT, 0x00 },
519 { PCM3168A_DAC_INV, 0x00 },
520 { PCM3168A_DAC_MUTE, 0x00 },
521 { PCM3168A_DAC_ZERO, 0x00 },
522 { PCM3168A_DAC_ATT_DEMP_ZF, 0x00 },
523 { PCM3168A_DAC_VOL_MASTER, 0xff },
524 { PCM3168A_DAC_VOL_CHAN_START, 0xff },
525 { PCM3168A_DAC_VOL_CHAN_START + 1, 0xff },
526 { PCM3168A_DAC_VOL_CHAN_START + 2, 0xff },
527 { PCM3168A_DAC_VOL_CHAN_START + 3, 0xff },
528 { PCM3168A_DAC_VOL_CHAN_START + 4, 0xff },
529 { PCM3168A_DAC_VOL_CHAN_START + 5, 0xff },
530 { PCM3168A_DAC_VOL_CHAN_START + 6, 0xff },
531 { PCM3168A_DAC_VOL_CHAN_START + 7, 0xff },
532 { PCM3168A_ADC_SMODE, 0x00 },
533 { PCM3168A_ADC_MST_FMT, 0x00 },
534 { PCM3168A_ADC_PWR_HPFB, 0x00 },
535 { PCM3168A_ADC_SEAD, 0x00 },
536 { PCM3168A_ADC_INV, 0x00 },
537 { PCM3168A_ADC_MUTE, 0x00 },
538 { PCM3168A_ADC_OV, 0x00 },
539 { PCM3168A_ADC_ATT_OVF, 0x00 },
540 { PCM3168A_ADC_VOL_MASTER, 0xd3 },
541 { PCM3168A_ADC_VOL_CHAN_START, 0xd3 },
542 { PCM3168A_ADC_VOL_CHAN_START + 1, 0xd3 },
543 { PCM3168A_ADC_VOL_CHAN_START + 2, 0xd3 },
544 { PCM3168A_ADC_VOL_CHAN_START + 3, 0xd3 },
545 { PCM3168A_ADC_VOL_CHAN_START + 4, 0xd3 },
546 { PCM3168A_ADC_VOL_CHAN_START + 5, 0xd3 }
547};
548
549static bool pcm3168a_readable_register(struct device *dev, unsigned int reg)
550{
551 if (reg >= PCM3168A_RST_SMODE)
552 return true;
553 else
554 return false;
555}
556
557static bool pcm3168a_volatile_register(struct device *dev, unsigned int reg)
558{
559 switch (reg) {
560 case PCM3168A_DAC_ZERO:
561 case PCM3168A_ADC_OV:
562 return true;
563 default:
564 return false;
565 }
566}
567
568static bool pcm3168a_writeable_register(struct device *dev, unsigned int reg)
569{
570 if (reg < PCM3168A_RST_SMODE)
571 return false;
572
573 switch (reg) {
574 case PCM3168A_DAC_ZERO:
575 case PCM3168A_ADC_OV:
576 return false;
577 default:
578 return true;
579 }
580}
581
582const struct regmap_config pcm3168a_regmap = {
583 .reg_bits = 8,
584 .val_bits = 8,
585
586 .max_register = PCM3168A_ADC_VOL_CHAN_START + 5,
587 .reg_defaults = pcm3168a_reg_default,
588 .num_reg_defaults = ARRAY_SIZE(pcm3168a_reg_default),
589 .readable_reg = pcm3168a_readable_register,
590 .volatile_reg = pcm3168a_volatile_register,
591 .writeable_reg = pcm3168a_writeable_register,
592 .cache_type = REGCACHE_FLAT
593};
594EXPORT_SYMBOL_GPL(pcm3168a_regmap);
595
596static const struct snd_soc_codec_driver pcm3168a_driver = {
597 .idle_bias_off = true,
598 .controls = pcm3168a_snd_controls,
599 .num_controls = ARRAY_SIZE(pcm3168a_snd_controls),
600 .dapm_widgets = pcm3168a_dapm_widgets,
601 .num_dapm_widgets = ARRAY_SIZE(pcm3168a_dapm_widgets),
602 .dapm_routes = pcm3168a_dapm_routes,
603 .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes)
604};
605
606int pcm3168a_probe(struct device *dev, struct regmap *regmap)
607{
608 struct pcm3168a_priv *pcm3168a;
609 int ret, i;
610
611 pcm3168a = devm_kzalloc(dev, sizeof(*pcm3168a), GFP_KERNEL);
612 if (pcm3168a == NULL)
613 return -ENOMEM;
614
615 dev_set_drvdata(dev, pcm3168a);
616
617 pcm3168a->scki = devm_clk_get(dev, "scki");
618 if (IS_ERR(pcm3168a->scki)) {
619 ret = PTR_ERR(pcm3168a->scki);
620 if (ret != -EPROBE_DEFER)
621 dev_err(dev, "failed to acquire clock 'scki': %d\n", ret);
622 return ret;
623 }
624
625 ret = clk_prepare_enable(pcm3168a->scki);
626 if (ret) {
627 dev_err(dev, "Failed to enable mclk: %d\n", ret);
628 return ret;
629 }
630
631 pcm3168a->sysclk = clk_get_rate(pcm3168a->scki);
632
633 for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++)
634 pcm3168a->supplies[i].supply = pcm3168a_supply_names[i];
635
636 ret = devm_regulator_bulk_get(dev,
637 ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies);
638 if (ret) {
639 if (ret != -EPROBE_DEFER)
640 dev_err(dev, "failed to request supplies: %d\n", ret);
641 goto err_clk;
642 }
643
644 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
645 pcm3168a->supplies);
646 if (ret) {
647 dev_err(dev, "failed to enable supplies: %d\n", ret);
648 goto err_clk;
649 }
650
651 pcm3168a->regmap = regmap;
652 if (IS_ERR(pcm3168a->regmap)) {
653 ret = PTR_ERR(pcm3168a->regmap);
654 dev_err(dev, "failed to allocate regmap: %d\n", ret);
655 goto err_regulator;
656 }
657
658 ret = pcm3168a_reset(pcm3168a);
659 if (ret) {
660 dev_err(dev, "Failed to reset device: %d\n", ret);
661 goto err_regulator;
662 }
663
664 pm_runtime_set_active(dev);
665 pm_runtime_enable(dev);
666 pm_runtime_idle(dev);
667
668 ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
669 ARRAY_SIZE(pcm3168a_dais));
670 if (ret) {
671 dev_err(dev, "failed to register codec: %d\n", ret);
672 goto err_regulator;
673 }
674
675 return 0;
676
677err_regulator:
678 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
679 pcm3168a->supplies);
680err_clk:
681 clk_disable_unprepare(pcm3168a->scki);
682
683 return ret;
684}
685EXPORT_SYMBOL_GPL(pcm3168a_probe);
686
687void pcm3168a_remove(struct device *dev)
688{
689 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
690
691 snd_soc_unregister_codec(dev);
692 pm_runtime_disable(dev);
693 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
694 pcm3168a->supplies);
695 clk_disable_unprepare(pcm3168a->scki);
696}
697EXPORT_SYMBOL_GPL(pcm3168a_remove);
698
699#ifdef CONFIG_PM
700static int pcm3168a_rt_resume(struct device *dev)
701{
702 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
703 int ret;
704
705 ret = clk_prepare_enable(pcm3168a->scki);
706 if (ret) {
707 dev_err(dev, "Failed to enable mclk: %d\n", ret);
708 return ret;
709 }
710
711 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies),
712 pcm3168a->supplies);
713 if (ret) {
714 dev_err(dev, "Failed to enable supplies: %d\n", ret);
715 goto err_clk;
716 }
717
718 ret = pcm3168a_reset(pcm3168a);
719 if (ret) {
720 dev_err(dev, "Failed to reset device: %d\n", ret);
721 goto err_regulator;
722 }
723
724 regcache_cache_only(pcm3168a->regmap, false);
725
726 regcache_mark_dirty(pcm3168a->regmap);
727
728 ret = regcache_sync(pcm3168a->regmap);
729 if (ret) {
730 dev_err(dev, "Failed to sync regmap: %d\n", ret);
731 goto err_regulator;
732 }
733
734 return 0;
735
736err_regulator:
737 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
738 pcm3168a->supplies);
739err_clk:
740 clk_disable_unprepare(pcm3168a->scki);
741
742 return ret;
743}
744
745static int pcm3168a_rt_suspend(struct device *dev)
746{
747 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
748
749 regcache_cache_only(pcm3168a->regmap, true);
750
751 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
752 pcm3168a->supplies);
753
754 clk_disable_unprepare(pcm3168a->scki);
755
756 return 0;
757}
758#endif
759
760const struct dev_pm_ops pcm3168a_pm_ops = {
761 SET_RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL)
762};
763EXPORT_SYMBOL_GPL(pcm3168a_pm_ops);
764
765MODULE_DESCRIPTION("PCM3168A codec driver");
766MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
767MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm3168a.h b/sound/soc/codecs/pcm3168a.h
new file mode 100644
index 000000000000..56c8332d82fb
--- /dev/null
+++ b/sound/soc/codecs/pcm3168a.h
@@ -0,0 +1,100 @@
1/*
2 * PCM3168A codec driver header
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#ifndef __PCM3168A_H__
14#define __PCM3168A_H__
15
16extern const struct dev_pm_ops pcm3168a_pm_ops;
17extern const struct regmap_config pcm3168a_regmap;
18
19extern int pcm3168a_probe(struct device *dev, struct regmap *regmap);
20extern void pcm3168a_remove(struct device *dev);
21
22#define PCM3168A_RST_SMODE 0x40
23#define PCM3168A_MRST_MASK 0x80
24#define PCM3168A_SRST_MASK 0x40
25#define PCM3168A_DAC_SRDA_SHIFT 0
26#define PCM3168A_DAC_SRDA_MASK 0x3
27
28#define PCM3168A_DAC_PWR_MST_FMT 0x41
29#define PCM3168A_DAC_PSMDA_SHIFT 7
30#define PCM3168A_DAC_PSMDA_MASK 0x80
31#define PCM3168A_DAC_MSDA_SHIFT 4
32#define PCM3168A_DAC_MSDA_MASK 0x70
33#define PCM3168A_DAC_FMT_SHIFT 0
34#define PCM3168A_DAC_FMT_MASK 0xf
35
36#define PCM3168A_DAC_OP_FLT 0x42
37#define PCM3168A_DAC_OPEDA_SHIFT 4
38#define PCM3168A_DAC_OPEDA_MASK 0xf0
39#define PCM3168A_DAC_FLT_SHIFT 0
40#define PCM3168A_DAC_FLT_MASK 0xf
41
42#define PCM3168A_DAC_INV 0x43
43
44#define PCM3168A_DAC_MUTE 0x44
45
46#define PCM3168A_DAC_ZERO 0x45
47
48#define PCM3168A_DAC_ATT_DEMP_ZF 0x46
49#define PCM3168A_DAC_ATMDDA_MASK 0x80
50#define PCM3168A_DAC_ATMDDA_SHIFT 7
51#define PCM3168A_DAC_ATSPDA_MASK 0x40
52#define PCM3168A_DAC_ATSPDA_SHIFT 6
53#define PCM3168A_DAC_DEMP_SHIFT 4
54#define PCM3168A_DAC_DEMP_MASK 0x30
55#define PCM3168A_DAC_AZRO_SHIFT 1
56#define PCM3168A_DAC_AZRO_MASK 0xe
57#define PCM3168A_DAC_ZREV_MASK 0x1
58#define PCM3168A_DAC_ZREV_SHIFT 0
59
60#define PCM3168A_DAC_VOL_MASTER 0x47
61
62#define PCM3168A_DAC_VOL_CHAN_START 0x48
63
64#define PCM3168A_ADC_SMODE 0x50
65#define PCM3168A_ADC_SRAD_SHIFT 0
66#define PCM3168A_ADC_SRAD_MASK 0x3
67
68#define PCM3168A_ADC_MST_FMT 0x51
69#define PCM3168A_ADC_MSAD_SHIFT 4
70#define PCM3168A_ADC_MSAD_MASK 0x70
71#define PCM3168A_ADC_FMTAD_SHIFT 0
72#define PCM3168A_ADC_FMTAD_MASK 0x7
73
74#define PCM3168A_ADC_PWR_HPFB 0x52
75#define PCM3168A_ADC_PSVAD_SHIFT 4
76#define PCM3168A_ADC_PSVAD_MASK 0x70
77#define PCM3168A_ADC_BYP_SHIFT 0
78#define PCM3168A_ADC_BYP_MASK 0x7
79
80#define PCM3168A_ADC_SEAD 0x53
81
82#define PCM3168A_ADC_INV 0x54
83
84#define PCM3168A_ADC_MUTE 0x55
85
86#define PCM3168A_ADC_OV 0x56
87
88#define PCM3168A_ADC_ATT_OVF 0x57
89#define PCM3168A_ADC_ATMDAD_MASK 0x80
90#define PCM3168A_ADC_ATMDAD_SHIFT 7
91#define PCM3168A_ADC_ATSPAD_MASK 0x40
92#define PCM3168A_ADC_ATSPAD_SHIFT 6
93#define PCM3168A_ADC_OVFP_MASK 0x1
94#define PCM3168A_ADC_OVFP_SHIFT 0
95
96#define PCM3168A_ADC_VOL_MASTER 0x58
97
98#define PCM3168A_ADC_VOL_CHAN_START 0x59
99
100#endif
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index af2ed774b552..bc08f0c5a5f6 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1114,6 +1114,12 @@ static const struct dmi_system_id force_combo_jack_table[] = {
1114 DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS") 1114 DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS")
1115 } 1115 }
1116 }, 1116 },
1117 {
1118 .ident = "Intel Skylake RVP",
1119 .matches = {
1120 DMI_MATCH(DMI_PRODUCT_NAME, "Skylake Client platform")
1121 }
1122 },
1117 { } 1123 { }
1118}; 1124};
1119 1125
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index b3f795c60749..30c6de62ae6c 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -855,8 +855,6 @@ static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
855 snd_soc_update_bits(codec, 855 snd_soc_update_bits(codec,
856 RT298_I2S_CTRL2, 0x0100, 0x0100); 856 RT298_I2S_CTRL2, 0x0100, 0x0100);
857 snd_soc_update_bits(codec, 857 snd_soc_update_bits(codec,
858 RT298_PLL_CTRL, 0x4, 0x4);
859 snd_soc_update_bits(codec,
860 RT298_PLL_CTRL1, 0x20, 0x0); 858 RT298_PLL_CTRL1, 0x20, 0x0);
861 } 859 }
862 860
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
new file mode 100644
index 000000000000..1c10d8ed39d2
--- /dev/null
+++ b/sound/soc/codecs/rt5616.c
@@ -0,0 +1,1381 @@
1/*
2 * rt5616.c -- RT5616 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 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 <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/initval.h>
26#include <sound/tlv.h>
27
28#include "rl6231.h"
29#include "rt5616.h"
30
31#define RT5616_PR_RANGE_BASE (0xff + 1)
32#define RT5616_PR_SPACING 0x100
33
34#define RT5616_PR_BASE (RT5616_PR_RANGE_BASE + (0 * RT5616_PR_SPACING))
35
36static const struct regmap_range_cfg rt5616_ranges[] = {
37 {
38 .name = "PR",
39 .range_min = RT5616_PR_BASE,
40 .range_max = RT5616_PR_BASE + 0xf8,
41 .selector_reg = RT5616_PRIV_INDEX,
42 .selector_mask = 0xff,
43 .selector_shift = 0x0,
44 .window_start = RT5616_PRIV_DATA,
45 .window_len = 0x1,
46 },
47};
48
49static const struct reg_sequence init_list[] = {
50 {RT5616_PR_BASE + 0x3d, 0x3e00},
51 {RT5616_PR_BASE + 0x25, 0x6110},
52 {RT5616_PR_BASE + 0x20, 0x611f},
53 {RT5616_PR_BASE + 0x21, 0x4040},
54 {RT5616_PR_BASE + 0x23, 0x0004},
55};
56#define RT5616_INIT_REG_LEN ARRAY_SIZE(init_list)
57
58static const struct reg_default rt5616_reg[] = {
59 { 0x00, 0x0021 },
60 { 0x02, 0xc8c8 },
61 { 0x03, 0xc8c8 },
62 { 0x05, 0x0000 },
63 { 0x0d, 0x0000 },
64 { 0x0f, 0x0808 },
65 { 0x19, 0xafaf },
66 { 0x1c, 0x2f2f },
67 { 0x1e, 0x0000 },
68 { 0x27, 0x7860 },
69 { 0x29, 0x8080 },
70 { 0x2a, 0x5252 },
71 { 0x3b, 0x0000 },
72 { 0x3c, 0x006f },
73 { 0x3d, 0x0000 },
74 { 0x3e, 0x006f },
75 { 0x45, 0x6000 },
76 { 0x4d, 0x0000 },
77 { 0x4e, 0x0000 },
78 { 0x4f, 0x0279 },
79 { 0x50, 0x0000 },
80 { 0x51, 0x0000 },
81 { 0x52, 0x0279 },
82 { 0x53, 0xf000 },
83 { 0x61, 0x0000 },
84 { 0x62, 0x0000 },
85 { 0x63, 0x00c0 },
86 { 0x64, 0x0000 },
87 { 0x65, 0x0000 },
88 { 0x66, 0x0000 },
89 { 0x70, 0x8000 },
90 { 0x73, 0x1104 },
91 { 0x74, 0x0c00 },
92 { 0x80, 0x0000 },
93 { 0x81, 0x0000 },
94 { 0x82, 0x0000 },
95 { 0x8b, 0x0600 },
96 { 0x8e, 0x0004 },
97 { 0x8f, 0x1100 },
98 { 0x90, 0x0000 },
99 { 0x91, 0x0000 },
100 { 0x92, 0x0000 },
101 { 0x93, 0x2000 },
102 { 0x94, 0x0200 },
103 { 0x95, 0x0000 },
104 { 0xb0, 0x2080 },
105 { 0xb1, 0x0000 },
106 { 0xb2, 0x0000 },
107 { 0xb4, 0x2206 },
108 { 0xb5, 0x1f00 },
109 { 0xb6, 0x0000 },
110 { 0xb7, 0x0000 },
111 { 0xbb, 0x0000 },
112 { 0xbc, 0x0000 },
113 { 0xbd, 0x0000 },
114 { 0xbe, 0x0000 },
115 { 0xbf, 0x0000 },
116 { 0xc0, 0x0100 },
117 { 0xc1, 0x0000 },
118 { 0xc2, 0x0000 },
119 { 0xc8, 0x0000 },
120 { 0xc9, 0x0000 },
121 { 0xca, 0x0000 },
122 { 0xcb, 0x0000 },
123 { 0xcc, 0x0000 },
124 { 0xcd, 0x0000 },
125 { 0xce, 0x0000 },
126 { 0xcf, 0x0013 },
127 { 0xd0, 0x0680 },
128 { 0xd1, 0x1c17 },
129 { 0xd3, 0xb320 },
130 { 0xd4, 0x0000 },
131 { 0xd6, 0x0000 },
132 { 0xd7, 0x0000 },
133 { 0xd9, 0x0809 },
134 { 0xda, 0x0000 },
135 { 0xfa, 0x0010 },
136 { 0xfb, 0x0000 },
137 { 0xfc, 0x0000 },
138 { 0xfe, 0x10ec },
139 { 0xff, 0x6281 },
140};
141
142struct rt5616_priv {
143 struct snd_soc_codec *codec;
144 struct delayed_work patch_work;
145 struct regmap *regmap;
146
147 int sysclk;
148 int sysclk_src;
149 int lrck[RT5616_AIFS];
150 int bclk[RT5616_AIFS];
151 int master[RT5616_AIFS];
152
153 int pll_src;
154 int pll_in;
155 int pll_out;
156
157};
158
159static bool rt5616_volatile_register(struct device *dev, unsigned int reg)
160{
161 int i;
162
163 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
164 if (reg >= rt5616_ranges[i].range_min &&
165 reg <= rt5616_ranges[i].range_max) {
166 return true;
167 }
168 }
169
170 switch (reg) {
171 case RT5616_RESET:
172 case RT5616_PRIV_DATA:
173 case RT5616_EQ_CTRL1:
174 case RT5616_DRC_AGC_1:
175 case RT5616_IRQ_CTRL2:
176 case RT5616_INT_IRQ_ST:
177 case RT5616_PGM_REG_ARR1:
178 case RT5616_PGM_REG_ARR3:
179 case RT5616_VENDOR_ID:
180 case RT5616_DEVICE_ID:
181 return true;
182 default:
183 return false;
184 }
185}
186
187static bool rt5616_readable_register(struct device *dev, unsigned int reg)
188{
189 int i;
190
191 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
192 if (reg >= rt5616_ranges[i].range_min &&
193 reg <= rt5616_ranges[i].range_max) {
194 return true;
195 }
196 }
197
198 switch (reg) {
199 case RT5616_RESET:
200 case RT5616_VERSION_ID:
201 case RT5616_VENDOR_ID:
202 case RT5616_DEVICE_ID:
203 case RT5616_HP_VOL:
204 case RT5616_LOUT_CTRL1:
205 case RT5616_LOUT_CTRL2:
206 case RT5616_IN1_IN2:
207 case RT5616_INL1_INR1_VOL:
208 case RT5616_DAC1_DIG_VOL:
209 case RT5616_ADC_DIG_VOL:
210 case RT5616_ADC_BST_VOL:
211 case RT5616_STO1_ADC_MIXER:
212 case RT5616_AD_DA_MIXER:
213 case RT5616_STO_DAC_MIXER:
214 case RT5616_REC_L1_MIXER:
215 case RT5616_REC_L2_MIXER:
216 case RT5616_REC_R1_MIXER:
217 case RT5616_REC_R2_MIXER:
218 case RT5616_HPO_MIXER:
219 case RT5616_OUT_L1_MIXER:
220 case RT5616_OUT_L2_MIXER:
221 case RT5616_OUT_L3_MIXER:
222 case RT5616_OUT_R1_MIXER:
223 case RT5616_OUT_R2_MIXER:
224 case RT5616_OUT_R3_MIXER:
225 case RT5616_LOUT_MIXER:
226 case RT5616_PWR_DIG1:
227 case RT5616_PWR_DIG2:
228 case RT5616_PWR_ANLG1:
229 case RT5616_PWR_ANLG2:
230 case RT5616_PWR_MIXER:
231 case RT5616_PWR_VOL:
232 case RT5616_PRIV_INDEX:
233 case RT5616_PRIV_DATA:
234 case RT5616_I2S1_SDP:
235 case RT5616_ADDA_CLK1:
236 case RT5616_ADDA_CLK2:
237 case RT5616_GLB_CLK:
238 case RT5616_PLL_CTRL1:
239 case RT5616_PLL_CTRL2:
240 case RT5616_HP_OVCD:
241 case RT5616_DEPOP_M1:
242 case RT5616_DEPOP_M2:
243 case RT5616_DEPOP_M3:
244 case RT5616_CHARGE_PUMP:
245 case RT5616_PV_DET_SPK_G:
246 case RT5616_MICBIAS:
247 case RT5616_A_JD_CTL1:
248 case RT5616_A_JD_CTL2:
249 case RT5616_EQ_CTRL1:
250 case RT5616_EQ_CTRL2:
251 case RT5616_WIND_FILTER:
252 case RT5616_DRC_AGC_1:
253 case RT5616_DRC_AGC_2:
254 case RT5616_DRC_AGC_3:
255 case RT5616_SVOL_ZC:
256 case RT5616_JD_CTRL1:
257 case RT5616_JD_CTRL2:
258 case RT5616_IRQ_CTRL1:
259 case RT5616_IRQ_CTRL2:
260 case RT5616_INT_IRQ_ST:
261 case RT5616_GPIO_CTRL1:
262 case RT5616_GPIO_CTRL2:
263 case RT5616_GPIO_CTRL3:
264 case RT5616_PGM_REG_ARR1:
265 case RT5616_PGM_REG_ARR2:
266 case RT5616_PGM_REG_ARR3:
267 case RT5616_PGM_REG_ARR4:
268 case RT5616_PGM_REG_ARR5:
269 case RT5616_SCB_FUNC:
270 case RT5616_SCB_CTRL:
271 case RT5616_BASE_BACK:
272 case RT5616_MP3_PLUS1:
273 case RT5616_MP3_PLUS2:
274 case RT5616_ADJ_HPF_CTRL1:
275 case RT5616_ADJ_HPF_CTRL2:
276 case RT5616_HP_CALIB_AMP_DET:
277 case RT5616_HP_CALIB2:
278 case RT5616_SV_ZCD1:
279 case RT5616_SV_ZCD2:
280 case RT5616_D_MISC:
281 case RT5616_DUMMY2:
282 case RT5616_DUMMY3:
283 return true;
284 default:
285 return false;
286 }
287}
288
289static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
290static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
291static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
292static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
293static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
294
295/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
296static unsigned int bst_tlv[] = {
297 TLV_DB_RANGE_HEAD(7),
298 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
299 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
300 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
301 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
302 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
303 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
304 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
305};
306
307static const struct snd_kcontrol_new rt5616_snd_controls[] = {
308 /* Headphone Output Volume */
309 SOC_DOUBLE("HP Playback Switch", RT5616_HP_VOL,
310 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
311 SOC_DOUBLE_TLV("HP Playback Volume", RT5616_HP_VOL,
312 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
313 /* OUTPUT Control */
314 SOC_DOUBLE("OUT Playback Switch", RT5616_LOUT_CTRL1,
315 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
316 SOC_DOUBLE("OUT Channel Switch", RT5616_LOUT_CTRL1,
317 RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1),
318 SOC_DOUBLE_TLV("OUT Playback Volume", RT5616_LOUT_CTRL1,
319 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
320
321 /* DAC Digital Volume */
322 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5616_DAC1_DIG_VOL,
323 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
324 175, 0, dac_vol_tlv),
325 /* IN1/IN2 Control */
326 SOC_SINGLE_TLV("IN1 Boost Volume", RT5616_IN1_IN2,
327 RT5616_BST_SFT1, 8, 0, bst_tlv),
328 SOC_SINGLE_TLV("IN2 Boost Volume", RT5616_IN1_IN2,
329 RT5616_BST_SFT2, 8, 0, bst_tlv),
330 /* INL/INR Volume Control */
331 SOC_DOUBLE_TLV("IN Capture Volume", RT5616_INL1_INR1_VOL,
332 RT5616_INL_VOL_SFT, RT5616_INR_VOL_SFT,
333 31, 1, in_vol_tlv),
334 /* ADC Digital Volume Control */
335 SOC_DOUBLE("ADC Capture Switch", RT5616_ADC_DIG_VOL,
336 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
337 SOC_DOUBLE_TLV("ADC Capture Volume", RT5616_ADC_DIG_VOL,
338 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
339 127, 0, adc_vol_tlv),
340
341 /* ADC Boost Volume Control */
342 SOC_DOUBLE_TLV("ADC Boost Volume", RT5616_ADC_BST_VOL,
343 RT5616_ADC_L_BST_SFT, RT5616_ADC_R_BST_SFT,
344 3, 0, adc_bst_tlv),
345};
346
347static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
348 struct snd_soc_dapm_widget *sink)
349{
350 unsigned int val;
351
352 val = snd_soc_read(snd_soc_dapm_to_codec(source->dapm), RT5616_GLB_CLK);
353 val &= RT5616_SCLK_SRC_MASK;
354 if (val == RT5616_SCLK_SRC_PLL1)
355 return 1;
356 else
357 return 0;
358}
359
360/* Digital Mixer */
361static const struct snd_kcontrol_new rt5616_sto1_adc_l_mix[] = {
362 SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER,
363 RT5616_M_STO1_ADC_L1_SFT, 1, 1),
364};
365
366static const struct snd_kcontrol_new rt5616_sto1_adc_r_mix[] = {
367 SOC_DAPM_SINGLE("ADC1 Switch", RT5616_STO1_ADC_MIXER,
368 RT5616_M_STO1_ADC_R1_SFT, 1, 1),
369};
370
371static const struct snd_kcontrol_new rt5616_dac_l_mix[] = {
372 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER,
373 RT5616_M_ADCMIX_L_SFT, 1, 1),
374 SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER,
375 RT5616_M_IF1_DAC_L_SFT, 1, 1),
376};
377
378static const struct snd_kcontrol_new rt5616_dac_r_mix[] = {
379 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5616_AD_DA_MIXER,
380 RT5616_M_ADCMIX_R_SFT, 1, 1),
381 SOC_DAPM_SINGLE("INF1 Switch", RT5616_AD_DA_MIXER,
382 RT5616_M_IF1_DAC_R_SFT, 1, 1),
383};
384
385static const struct snd_kcontrol_new rt5616_sto_dac_l_mix[] = {
386 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER,
387 RT5616_M_DAC_L1_MIXL_SFT, 1, 1),
388 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER,
389 RT5616_M_DAC_R1_MIXL_SFT, 1, 1),
390};
391
392static const struct snd_kcontrol_new rt5616_sto_dac_r_mix[] = {
393 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_STO_DAC_MIXER,
394 RT5616_M_DAC_R1_MIXR_SFT, 1, 1),
395 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_STO_DAC_MIXER,
396 RT5616_M_DAC_L1_MIXR_SFT, 1, 1),
397};
398
399/* Analog Input Mixer */
400static const struct snd_kcontrol_new rt5616_rec_l_mix[] = {
401 SOC_DAPM_SINGLE("INL1 Switch", RT5616_REC_L2_MIXER,
402 RT5616_M_IN1_L_RM_L_SFT, 1, 1),
403 SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_L2_MIXER,
404 RT5616_M_BST2_RM_L_SFT, 1, 1),
405 SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_L2_MIXER,
406 RT5616_M_BST1_RM_L_SFT, 1, 1),
407};
408
409static const struct snd_kcontrol_new rt5616_rec_r_mix[] = {
410 SOC_DAPM_SINGLE("INR1 Switch", RT5616_REC_R2_MIXER,
411 RT5616_M_IN1_R_RM_R_SFT, 1, 1),
412 SOC_DAPM_SINGLE("BST2 Switch", RT5616_REC_R2_MIXER,
413 RT5616_M_BST2_RM_R_SFT, 1, 1),
414 SOC_DAPM_SINGLE("BST1 Switch", RT5616_REC_R2_MIXER,
415 RT5616_M_BST1_RM_R_SFT, 1, 1),
416};
417
418/* Analog Output Mixer */
419
420static const struct snd_kcontrol_new rt5616_out_l_mix[] = {
421 SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_L3_MIXER,
422 RT5616_M_BST1_OM_L_SFT, 1, 1),
423 SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_L3_MIXER,
424 RT5616_M_BST2_OM_L_SFT, 1, 1),
425 SOC_DAPM_SINGLE("INL1 Switch", RT5616_OUT_L3_MIXER,
426 RT5616_M_IN1_L_OM_L_SFT, 1, 1),
427 SOC_DAPM_SINGLE("REC MIXL Switch", RT5616_OUT_L3_MIXER,
428 RT5616_M_RM_L_OM_L_SFT, 1, 1),
429 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_OUT_L3_MIXER,
430 RT5616_M_DAC_L1_OM_L_SFT, 1, 1),
431};
432
433static const struct snd_kcontrol_new rt5616_out_r_mix[] = {
434 SOC_DAPM_SINGLE("BST2 Switch", RT5616_OUT_R3_MIXER,
435 RT5616_M_BST2_OM_R_SFT, 1, 1),
436 SOC_DAPM_SINGLE("BST1 Switch", RT5616_OUT_R3_MIXER,
437 RT5616_M_BST1_OM_R_SFT, 1, 1),
438 SOC_DAPM_SINGLE("INR1 Switch", RT5616_OUT_R3_MIXER,
439 RT5616_M_IN1_R_OM_R_SFT, 1, 1),
440 SOC_DAPM_SINGLE("REC MIXR Switch", RT5616_OUT_R3_MIXER,
441 RT5616_M_RM_R_OM_R_SFT, 1, 1),
442 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_OUT_R3_MIXER,
443 RT5616_M_DAC_R1_OM_R_SFT, 1, 1),
444};
445
446static const struct snd_kcontrol_new rt5616_hpo_mix[] = {
447 SOC_DAPM_SINGLE("DAC1 Switch", RT5616_HPO_MIXER,
448 RT5616_M_DAC1_HM_SFT, 1, 1),
449 SOC_DAPM_SINGLE("HPVOL Switch", RT5616_HPO_MIXER,
450 RT5616_M_HPVOL_HM_SFT, 1, 1),
451};
452
453static const struct snd_kcontrol_new rt5616_lout_mix[] = {
454 SOC_DAPM_SINGLE("DAC L1 Switch", RT5616_LOUT_MIXER,
455 RT5616_M_DAC_L1_LM_SFT, 1, 1),
456 SOC_DAPM_SINGLE("DAC R1 Switch", RT5616_LOUT_MIXER,
457 RT5616_M_DAC_R1_LM_SFT, 1, 1),
458 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5616_LOUT_MIXER,
459 RT5616_M_OV_L_LM_SFT, 1, 1),
460 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5616_LOUT_MIXER,
461 RT5616_M_OV_R_LM_SFT, 1, 1),
462};
463
464static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
465 struct snd_kcontrol *kcontrol, int event)
466{
467 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
468
469 switch (event) {
470 case SND_SOC_DAPM_POST_PMU:
471 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
472 RT5616_L_MUTE | RT5616_R_MUTE, 0);
473 break;
474
475 case SND_SOC_DAPM_POST_PMD:
476 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
477 RT5616_L_MUTE | RT5616_R_MUTE,
478 RT5616_L_MUTE | RT5616_R_MUTE);
479 break;
480
481 default:
482 return 0;
483 }
484
485 return 0;
486}
487
488static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
489 struct snd_kcontrol *kcontrol, int event)
490{
491 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
492
493 switch (event) {
494 case SND_SOC_DAPM_POST_PMU:
495 /* depop parameters */
496 snd_soc_update_bits(codec, RT5616_DEPOP_M2,
497 RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);
498 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
499 RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
500 RT5616_HP_CB_MASK, RT5616_HP_CP_PU |
501 RT5616_HP_SG_DIS | RT5616_HP_CB_PU);
502 snd_soc_write(codec, RT5616_PR_BASE +
503 RT5616_HP_DCC_INT1, 0x9f00);
504 /* headphone amp power on */
505 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
506 RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);
507 snd_soc_update_bits(codec, RT5616_PWR_VOL,
508 RT5616_PWR_HV_L | RT5616_PWR_HV_R,
509 RT5616_PWR_HV_L | RT5616_PWR_HV_R);
510 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
511 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
512 RT5616_PWR_HA, RT5616_PWR_HP_L |
513 RT5616_PWR_HP_R | RT5616_PWR_HA);
514 msleep(50);
515 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
516 RT5616_PWR_FV1 | RT5616_PWR_FV2,
517 RT5616_PWR_FV1 | RT5616_PWR_FV2);
518
519 snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,
520 RT5616_PM_HP_MASK, RT5616_PM_HP_HV);
521 snd_soc_update_bits(codec, RT5616_PR_BASE +
522 RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);
523 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
524 RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,
525 RT5616_HP_CO_EN | RT5616_HP_SG_EN);
526 break;
527 case SND_SOC_DAPM_PRE_PMD:
528 snd_soc_update_bits(codec, RT5616_PR_BASE +
529 RT5616_CHOP_DAC_ADC, 0x0200, 0x0);
530 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
531 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
532 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
533 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
534 /* headphone amp power down */
535 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
536 RT5616_SMT_TRIG_MASK | RT5616_HP_CD_PD_MASK |
537 RT5616_HP_CO_MASK | RT5616_HP_CP_MASK |
538 RT5616_HP_SG_MASK | RT5616_HP_CB_MASK,
539 RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |
540 RT5616_HP_CO_DIS | RT5616_HP_CP_PD |
541 RT5616_HP_SG_EN | RT5616_HP_CB_PD);
542 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
543 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
544 RT5616_PWR_HA, 0);
545 break;
546 default:
547 return 0;
548 }
549
550 return 0;
551}
552
553static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
554 struct snd_kcontrol *kcontrol, int event)
555{
556 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
557
558 switch (event) {
559 case SND_SOC_DAPM_POST_PMU:
560 /* headphone unmute sequence */
561 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
562 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
563 RT5616_CP_FQ3_MASK,
564 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT) |
565 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |
566 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT));
567 snd_soc_write(codec, RT5616_PR_BASE +
568 RT5616_MAMP_INT_REG2, 0xfc00);
569 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
570 RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);
571 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
572 RT5616_RSTN_MASK, RT5616_RSTN_EN);
573 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
574 RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |
575 RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |
576 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
577 snd_soc_update_bits(codec, RT5616_HP_VOL,
578 RT5616_L_MUTE | RT5616_R_MUTE, 0);
579 msleep(100);
580 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
581 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
582 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
583 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
584 msleep(20);
585 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
586 RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);
587 break;
588
589 case SND_SOC_DAPM_PRE_PMD:
590 /* headphone mute sequence */
591 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
592 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
593 RT5616_CP_FQ3_MASK,
594 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT) |
595 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |
596 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT));
597 snd_soc_write(codec, RT5616_PR_BASE +
598 RT5616_MAMP_INT_REG2, 0xfc00);
599 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
600 RT5616_HP_SG_MASK, RT5616_HP_SG_EN);
601 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
602 RT5616_RSTP_MASK, RT5616_RSTP_EN);
603 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
604 RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |
605 RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |
606 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
607 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
608 RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);
609 msleep(90);
610 snd_soc_update_bits(codec, RT5616_HP_VOL,
611 RT5616_L_MUTE | RT5616_R_MUTE,
612 RT5616_L_MUTE | RT5616_R_MUTE);
613 msleep(30);
614 break;
615
616 default:
617 return 0;
618 }
619
620 return 0;
621}
622
623static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
624 struct snd_kcontrol *kcontrol, int event)
625{
626 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
627
628 switch (event) {
629 case SND_SOC_DAPM_POST_PMU:
630 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
631 RT5616_PWR_LM, RT5616_PWR_LM);
632 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
633 RT5616_L_MUTE | RT5616_R_MUTE, 0);
634 break;
635
636 case SND_SOC_DAPM_PRE_PMD:
637 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
638 RT5616_L_MUTE | RT5616_R_MUTE,
639 RT5616_L_MUTE | RT5616_R_MUTE);
640 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
641 RT5616_PWR_LM, 0);
642 break;
643
644 default:
645 return 0;
646 }
647
648 return 0;
649}
650
651static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
652 struct snd_kcontrol *kcontrol, int event)
653{
654 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
655
656 switch (event) {
657 case SND_SOC_DAPM_POST_PMU:
658 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
659 RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);
660 break;
661
662 case SND_SOC_DAPM_PRE_PMD:
663 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
664 RT5616_PWR_BST1_OP2, 0);
665 break;
666
667 default:
668 return 0;
669 }
670
671 return 0;
672}
673
674static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,
675 struct snd_kcontrol *kcontrol, int event)
676{
677 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
678
679 switch (event) {
680 case SND_SOC_DAPM_POST_PMU:
681 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
682 RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);
683 break;
684
685 case SND_SOC_DAPM_PRE_PMD:
686 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
687 RT5616_PWR_BST2_OP2, 0);
688 break;
689
690 default:
691 return 0;
692 }
693
694 return 0;
695}
696
697static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = {
698 SND_SOC_DAPM_SUPPLY("PLL1", RT5616_PWR_ANLG2,
699 RT5616_PWR_PLL_BIT, 0, NULL, 0),
700 /* Input Side */
701 /* micbias */
702 SND_SOC_DAPM_SUPPLY("LDO", RT5616_PWR_ANLG1,
703 RT5616_PWR_LDO_BIT, 0, NULL, 0),
704 SND_SOC_DAPM_SUPPLY("micbias1", RT5616_PWR_ANLG2,
705 RT5616_PWR_MB1_BIT, 0, NULL, 0),
706
707 /* Input Lines */
708 SND_SOC_DAPM_INPUT("MIC1"),
709 SND_SOC_DAPM_INPUT("MIC2"),
710
711 SND_SOC_DAPM_INPUT("IN1P"),
712 SND_SOC_DAPM_INPUT("IN2P"),
713 SND_SOC_DAPM_INPUT("IN2N"),
714
715 /* Boost */
716 SND_SOC_DAPM_PGA_E("BST1", RT5616_PWR_ANLG2,
717 RT5616_PWR_BST1_BIT, 0, NULL, 0, rt5616_bst1_event,
718 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
719 SND_SOC_DAPM_PGA_E("BST2", RT5616_PWR_ANLG2,
720 RT5616_PWR_BST2_BIT, 0, NULL, 0, rt5616_bst2_event,
721 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
722 /* Input Volume */
723 SND_SOC_DAPM_PGA("INL1 VOL", RT5616_PWR_VOL,
724 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
725 SND_SOC_DAPM_PGA("INR1 VOL", RT5616_PWR_VOL,
726 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
727 SND_SOC_DAPM_PGA("INL2 VOL", RT5616_PWR_VOL,
728 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
729 SND_SOC_DAPM_PGA("INR2 VOL", RT5616_PWR_VOL,
730 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
731
732 /* REC Mixer */
733 SND_SOC_DAPM_MIXER("RECMIXL", RT5616_PWR_MIXER, RT5616_PWR_RM_L_BIT, 0,
734 rt5616_rec_l_mix, ARRAY_SIZE(rt5616_rec_l_mix)),
735 SND_SOC_DAPM_MIXER("RECMIXR", RT5616_PWR_MIXER, RT5616_PWR_RM_R_BIT, 0,
736 rt5616_rec_r_mix, ARRAY_SIZE(rt5616_rec_r_mix)),
737 /* ADCs */
738 SND_SOC_DAPM_ADC_E("ADC L", NULL, RT5616_PWR_DIG1,
739 RT5616_PWR_ADC_L_BIT, 0, rt5616_adc_event,
740 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
741 SND_SOC_DAPM_ADC_E("ADC R", NULL, RT5616_PWR_DIG1,
742 RT5616_PWR_ADC_R_BIT, 0, rt5616_adc_event,
743 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
744
745 /* ADC Mixer */
746 SND_SOC_DAPM_SUPPLY("stereo1 filter", RT5616_PWR_DIG2,
747 RT5616_PWR_ADC_STO1_F_BIT, 0, NULL, 0),
748 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0,
749 rt5616_sto1_adc_l_mix, ARRAY_SIZE(rt5616_sto1_adc_l_mix)),
750 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0,
751 rt5616_sto1_adc_r_mix, ARRAY_SIZE(rt5616_sto1_adc_r_mix)),
752
753 /* Digital Interface */
754 SND_SOC_DAPM_SUPPLY("I2S1", RT5616_PWR_DIG1,
755 RT5616_PWR_I2S1_BIT, 0, NULL, 0),
756 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
757 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
758 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
759 SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
760
761 /* Digital Interface Select */
762
763 /* Audio Interface */
764 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
765 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
766
767 /* Audio DSP */
768 SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0),
769
770 /* Output Side */
771 /* DAC mixer before sound effect */
772 SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
773 rt5616_dac_l_mix, ARRAY_SIZE(rt5616_dac_l_mix)),
774 SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
775 rt5616_dac_r_mix, ARRAY_SIZE(rt5616_dac_r_mix)),
776
777 SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5616_PWR_DIG2,
778 RT5616_PWR_DAC_STO1_F_BIT, 0, NULL, 0),
779
780 /* DAC Mixer */
781 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
782 rt5616_sto_dac_l_mix, ARRAY_SIZE(rt5616_sto_dac_l_mix)),
783 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
784 rt5616_sto_dac_r_mix, ARRAY_SIZE(rt5616_sto_dac_r_mix)),
785
786 /* DACs */
787 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5616_PWR_DIG1,
788 RT5616_PWR_DAC_L1_BIT, 0),
789 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5616_PWR_DIG1,
790 RT5616_PWR_DAC_R1_BIT, 0),
791 /* OUT Mixer */
792 SND_SOC_DAPM_MIXER("OUT MIXL", RT5616_PWR_MIXER, RT5616_PWR_OM_L_BIT,
793 0, rt5616_out_l_mix, ARRAY_SIZE(rt5616_out_l_mix)),
794 SND_SOC_DAPM_MIXER("OUT MIXR", RT5616_PWR_MIXER, RT5616_PWR_OM_R_BIT,
795 0, rt5616_out_r_mix, ARRAY_SIZE(rt5616_out_r_mix)),
796 /* Output Volume */
797 SND_SOC_DAPM_PGA("OUTVOL L", RT5616_PWR_VOL,
798 RT5616_PWR_OV_L_BIT, 0, NULL, 0),
799 SND_SOC_DAPM_PGA("OUTVOL R", RT5616_PWR_VOL,
800 RT5616_PWR_OV_R_BIT, 0, NULL, 0),
801 SND_SOC_DAPM_PGA("HPOVOL L", RT5616_PWR_VOL,
802 RT5616_PWR_HV_L_BIT, 0, NULL, 0),
803 SND_SOC_DAPM_PGA("HPOVOL R", RT5616_PWR_VOL,
804 RT5616_PWR_HV_R_BIT, 0, NULL, 0),
805 SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
806 0, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
808 0, 0, NULL, 0),
809 SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
810 0, 0, NULL, 0),
811 SND_SOC_DAPM_PGA("INL1", RT5616_PWR_VOL,
812 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
813 SND_SOC_DAPM_PGA("INR1", RT5616_PWR_VOL,
814 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
815 SND_SOC_DAPM_PGA("INL2", RT5616_PWR_VOL,
816 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
817 SND_SOC_DAPM_PGA("INR2", RT5616_PWR_VOL,
818 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
819 /* HPO/LOUT/Mono Mixer */
820 SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
821 rt5616_hpo_mix, ARRAY_SIZE(rt5616_hpo_mix)),
822 SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0,
823 rt5616_lout_mix, ARRAY_SIZE(rt5616_lout_mix)),
824
825 SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0,
826 rt5616_hp_event, SND_SOC_DAPM_PRE_PMD |
827 SND_SOC_DAPM_POST_PMU),
828 SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0,
829 rt5616_lout_event, SND_SOC_DAPM_PRE_PMD |
830 SND_SOC_DAPM_POST_PMU),
831
832 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, SND_SOC_NOPM, 0, 0,
833 rt5616_charge_pump_event, SND_SOC_DAPM_POST_PMU |
834 SND_SOC_DAPM_PRE_PMD),
835
836 /* Output Lines */
837 SND_SOC_DAPM_OUTPUT("HPOL"),
838 SND_SOC_DAPM_OUTPUT("HPOR"),
839 SND_SOC_DAPM_OUTPUT("LOUTL"),
840 SND_SOC_DAPM_OUTPUT("LOUTR"),
841};
842
843static const struct snd_soc_dapm_route rt5616_dapm_routes[] = {
844 {"IN1P", NULL, "LDO"},
845 {"IN2P", NULL, "LDO"},
846
847 {"IN1P", NULL, "MIC1"},
848 {"IN2P", NULL, "MIC2"},
849 {"IN2N", NULL, "MIC2"},
850
851 {"BST1", NULL, "IN1P"},
852 {"BST2", NULL, "IN2P"},
853 {"BST2", NULL, "IN2N"},
854 {"BST1", NULL, "micbias1"},
855 {"BST2", NULL, "micbias1"},
856
857 {"INL1 VOL", NULL, "IN2P"},
858 {"INR1 VOL", NULL, "IN2N"},
859
860 {"RECMIXL", "INL1 Switch", "INL1 VOL"},
861 {"RECMIXL", "BST2 Switch", "BST2"},
862 {"RECMIXL", "BST1 Switch", "BST1"},
863
864 {"RECMIXR", "INR1 Switch", "INR1 VOL"},
865 {"RECMIXR", "BST2 Switch", "BST2"},
866 {"RECMIXR", "BST1 Switch", "BST1"},
867
868 {"ADC L", NULL, "RECMIXL"},
869 {"ADC R", NULL, "RECMIXR"},
870
871 {"Stereo1 ADC MIXL", "ADC1 Switch", "ADC L"},
872 {"Stereo1 ADC MIXL", NULL, "stereo1 filter"},
873 {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll},
874
875 {"Stereo1 ADC MIXR", "ADC1 Switch", "ADC R"},
876 {"Stereo1 ADC MIXR", NULL, "stereo1 filter"},
877 {"stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll},
878
879 {"IF1 ADC1", NULL, "Stereo1 ADC MIXL"},
880 {"IF1 ADC1", NULL, "Stereo1 ADC MIXR"},
881 {"IF1 ADC1", NULL, "I2S1"},
882
883 {"AIF1TX", NULL, "IF1 ADC1"},
884
885 {"IF1 DAC", NULL, "AIF1RX"},
886 {"IF1 DAC", NULL, "I2S1"},
887
888 {"IF1 DAC1 L", NULL, "IF1 DAC"},
889 {"IF1 DAC1 R", NULL, "IF1 DAC"},
890
891 {"DAC MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"},
892 {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"},
893 {"DAC MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"},
894 {"DAC MIXR", "INF1 Switch", "IF1 DAC1 R"},
895
896 {"Audio DSP", NULL, "DAC MIXL"},
897 {"Audio DSP", NULL, "DAC MIXR"},
898
899 {"Stereo DAC MIXL", "DAC L1 Switch", "Audio DSP"},
900 {"Stereo DAC MIXL", "DAC R1 Switch", "DAC MIXR"},
901 {"Stereo DAC MIXL", NULL, "Stero1 DAC Power"},
902 {"Stereo DAC MIXR", "DAC R1 Switch", "Audio DSP"},
903 {"Stereo DAC MIXR", "DAC L1 Switch", "DAC MIXL"},
904 {"Stereo DAC MIXR", NULL, "Stero1 DAC Power"},
905
906 {"DAC L1", NULL, "Stereo DAC MIXL"},
907 {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
908 {"DAC R1", NULL, "Stereo DAC MIXR"},
909 {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
910
911 {"OUT MIXL", "BST1 Switch", "BST1"},
912 {"OUT MIXL", "BST2 Switch", "BST2"},
913 {"OUT MIXL", "INL1 Switch", "INL1 VOL"},
914 {"OUT MIXL", "REC MIXL Switch", "RECMIXL"},
915 {"OUT MIXL", "DAC L1 Switch", "DAC L1"},
916
917 {"OUT MIXR", "BST2 Switch", "BST2"},
918 {"OUT MIXR", "BST1 Switch", "BST1"},
919 {"OUT MIXR", "INR1 Switch", "INR1 VOL"},
920 {"OUT MIXR", "REC MIXR Switch", "RECMIXR"},
921 {"OUT MIXR", "DAC R1 Switch", "DAC R1"},
922
923 {"HPOVOL L", NULL, "OUT MIXL"},
924 {"HPOVOL R", NULL, "OUT MIXR"},
925 {"OUTVOL L", NULL, "OUT MIXL"},
926 {"OUTVOL R", NULL, "OUT MIXR"},
927
928 {"DAC 1", NULL, "DAC L1"},
929 {"DAC 1", NULL, "DAC R1"},
930 {"HPOVOL", NULL, "HPOVOL L"},
931 {"HPOVOL", NULL, "HPOVOL R"},
932 {"HPO MIX", "DAC1 Switch", "DAC 1"},
933 {"HPO MIX", "HPVOL Switch", "HPOVOL"},
934
935 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
936 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
937 {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"},
938 {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"},
939
940 {"HP amp", NULL, "HPO MIX"},
941 {"HP amp", NULL, "Charge Pump"},
942 {"HPOL", NULL, "HP amp"},
943 {"HPOR", NULL, "HP amp"},
944
945 {"LOUT amp", NULL, "LOUT MIX"},
946 {"LOUT amp", NULL, "Charge Pump"},
947 {"LOUTL", NULL, "LOUT amp"},
948 {"LOUTR", NULL, "LOUT amp"},
949
950};
951
952static int rt5616_hw_params(struct snd_pcm_substream *substream,
953 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
954{
955 struct snd_soc_pcm_runtime *rtd = substream->private_data;
956 struct snd_soc_codec *codec = rtd->codec;
957 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
958 unsigned int val_len = 0, val_clk, mask_clk;
959 int pre_div, bclk_ms, frame_size;
960
961 rt5616->lrck[dai->id] = params_rate(params);
962
963 pre_div = rl6231_get_clk_info(rt5616->sysclk, rt5616->lrck[dai->id]);
964
965 if (pre_div < 0) {
966 dev_err(codec->dev, "Unsupported clock setting\n");
967 return -EINVAL;
968 }
969 frame_size = snd_soc_params_to_frame_size(params);
970 if (frame_size < 0) {
971 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
972 return -EINVAL;
973 }
974 bclk_ms = frame_size > 32 ? 1 : 0;
975 rt5616->bclk[dai->id] = rt5616->lrck[dai->id] * (32 << bclk_ms);
976
977 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
978 rt5616->bclk[dai->id], rt5616->lrck[dai->id]);
979 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
980 bclk_ms, pre_div, dai->id);
981
982 switch (params_format(params)) {
983 case SNDRV_PCM_FORMAT_S16_LE:
984 break;
985 case SNDRV_PCM_FORMAT_S20_3LE:
986 val_len |= RT5616_I2S_DL_20;
987 break;
988 case SNDRV_PCM_FORMAT_S24_LE:
989 val_len |= RT5616_I2S_DL_24;
990 break;
991 case SNDRV_PCM_FORMAT_S8:
992 val_len |= RT5616_I2S_DL_8;
993 break;
994 default:
995 return -EINVAL;
996 }
997
998 mask_clk = RT5616_I2S_PD1_MASK;
999 val_clk = pre_div << RT5616_I2S_PD1_SFT;
1000 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1001 RT5616_I2S_DL_MASK, val_len);
1002 snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);
1003
1004
1005 return 0;
1006}
1007
1008static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1009{
1010 struct snd_soc_codec *codec = dai->codec;
1011 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1012 unsigned int reg_val = 0;
1013
1014 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1015 case SND_SOC_DAIFMT_CBM_CFM:
1016 rt5616->master[dai->id] = 1;
1017 break;
1018 case SND_SOC_DAIFMT_CBS_CFS:
1019 reg_val |= RT5616_I2S_MS_S;
1020 rt5616->master[dai->id] = 0;
1021 break;
1022 default:
1023 return -EINVAL;
1024 }
1025
1026 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1027 case SND_SOC_DAIFMT_NB_NF:
1028 break;
1029 case SND_SOC_DAIFMT_IB_NF:
1030 reg_val |= RT5616_I2S_BP_INV;
1031 break;
1032 default:
1033 return -EINVAL;
1034 }
1035
1036 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1037 case SND_SOC_DAIFMT_I2S:
1038 break;
1039 case SND_SOC_DAIFMT_LEFT_J:
1040 reg_val |= RT5616_I2S_DF_LEFT;
1041 break;
1042 case SND_SOC_DAIFMT_DSP_A:
1043 reg_val |= RT5616_I2S_DF_PCM_A;
1044 break;
1045 case SND_SOC_DAIFMT_DSP_B:
1046 reg_val |= RT5616_I2S_DF_PCM_B;
1047 break;
1048 default:
1049 return -EINVAL;
1050 }
1051
1052 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1053 RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |
1054 RT5616_I2S_DF_MASK, reg_val);
1055
1056
1057 return 0;
1058}
1059
1060static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
1061 int clk_id, unsigned int freq, int dir)
1062{
1063 struct snd_soc_codec *codec = dai->codec;
1064 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1065 unsigned int reg_val = 0;
1066
1067 if (freq == rt5616->sysclk && clk_id == rt5616->sysclk_src)
1068 return 0;
1069
1070 switch (clk_id) {
1071 case RT5616_SCLK_S_MCLK:
1072 reg_val |= RT5616_SCLK_SRC_MCLK;
1073 break;
1074 case RT5616_SCLK_S_PLL1:
1075 reg_val |= RT5616_SCLK_SRC_PLL1;
1076 break;
1077 default:
1078 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1079 return -EINVAL;
1080 }
1081 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1082 RT5616_SCLK_SRC_MASK, reg_val);
1083 rt5616->sysclk = freq;
1084 rt5616->sysclk_src = clk_id;
1085
1086 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
1087
1088 return 0;
1089}
1090
1091static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1092 unsigned int freq_in, unsigned int freq_out)
1093{
1094 struct snd_soc_codec *codec = dai->codec;
1095 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1096 struct rl6231_pll_code pll_code;
1097 int ret;
1098
1099 if (source == rt5616->pll_src && freq_in == rt5616->pll_in &&
1100 freq_out == rt5616->pll_out)
1101 return 0;
1102
1103 if (!freq_in || !freq_out) {
1104 dev_dbg(codec->dev, "PLL disabled\n");
1105
1106 rt5616->pll_in = 0;
1107 rt5616->pll_out = 0;
1108 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1109 RT5616_SCLK_SRC_MASK, RT5616_SCLK_SRC_MCLK);
1110 return 0;
1111 }
1112
1113 switch (source) {
1114 case RT5616_PLL1_S_MCLK:
1115 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1116 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_MCLK);
1117 break;
1118 case RT5616_PLL1_S_BCLK1:
1119 case RT5616_PLL1_S_BCLK2:
1120 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1121 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_BCLK1);
1122 break;
1123 default:
1124 dev_err(codec->dev, "Unknown PLL source %d\n", source);
1125 return -EINVAL;
1126 }
1127
1128 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
1129 if (ret < 0) {
1130 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
1131 return ret;
1132 }
1133
1134 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
1135 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
1136 pll_code.n_code, pll_code.k_code);
1137
1138 snd_soc_write(codec, RT5616_PLL_CTRL1,
1139 pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);
1140 snd_soc_write(codec, RT5616_PLL_CTRL2,
1141 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5616_PLL_M_SFT |
1142 pll_code.m_bp << RT5616_PLL_M_BP_SFT);
1143
1144 rt5616->pll_in = freq_in;
1145 rt5616->pll_out = freq_out;
1146 rt5616->pll_src = source;
1147
1148 return 0;
1149}
1150
1151static int rt5616_set_bias_level(struct snd_soc_codec *codec,
1152 enum snd_soc_bias_level level)
1153{
1154 switch (level) {
1155 case SND_SOC_BIAS_STANDBY:
1156 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1157 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1158 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1159 RT5616_PWR_BG | RT5616_PWR_VREF2,
1160 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1161 RT5616_PWR_BG | RT5616_PWR_VREF2);
1162 mdelay(10);
1163 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1164 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1165 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1166 snd_soc_update_bits(codec, RT5616_D_MISC,
1167 RT5616_D_GATE_EN, RT5616_D_GATE_EN);
1168 }
1169 break;
1170
1171 case SND_SOC_BIAS_OFF:
1172 snd_soc_update_bits(codec, RT5616_D_MISC, RT5616_D_GATE_EN, 0);
1173 snd_soc_write(codec, RT5616_PWR_DIG1, 0x0000);
1174 snd_soc_write(codec, RT5616_PWR_DIG2, 0x0000);
1175 snd_soc_write(codec, RT5616_PWR_VOL, 0x0000);
1176 snd_soc_write(codec, RT5616_PWR_MIXER, 0x0000);
1177 snd_soc_write(codec, RT5616_PWR_ANLG1, 0x0000);
1178 snd_soc_write(codec, RT5616_PWR_ANLG2, 0x0000);
1179 break;
1180
1181 default:
1182 break;
1183 }
1184
1185 return 0;
1186}
1187
1188static int rt5616_probe(struct snd_soc_codec *codec)
1189{
1190 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1191
1192 rt5616->codec = codec;
1193
1194 return 0;
1195}
1196
1197#ifdef CONFIG_PM
1198static int rt5616_suspend(struct snd_soc_codec *codec)
1199{
1200 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1201
1202 regcache_cache_only(rt5616->regmap, true);
1203 regcache_mark_dirty(rt5616->regmap);
1204
1205 return 0;
1206}
1207
1208static int rt5616_resume(struct snd_soc_codec *codec)
1209{
1210 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1211
1212 regcache_cache_only(rt5616->regmap, false);
1213 regcache_sync(rt5616->regmap);
1214 return 0;
1215}
1216#else
1217#define rt5616_suspend NULL
1218#define rt5616_resume NULL
1219#endif
1220
1221#define RT5616_STEREO_RATES SNDRV_PCM_RATE_8000_96000
1222#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1223 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1224
1225
1226struct snd_soc_dai_ops rt5616_aif_dai_ops = {
1227 .hw_params = rt5616_hw_params,
1228 .set_fmt = rt5616_set_dai_fmt,
1229 .set_sysclk = rt5616_set_dai_sysclk,
1230 .set_pll = rt5616_set_dai_pll,
1231};
1232
1233struct snd_soc_dai_driver rt5616_dai[] = {
1234 {
1235 .name = "rt5616-aif1",
1236 .id = RT5616_AIF1,
1237 .playback = {
1238 .stream_name = "AIF1 Playback",
1239 .channels_min = 1,
1240 .channels_max = 2,
1241 .rates = RT5616_STEREO_RATES,
1242 .formats = RT5616_FORMATS,
1243 },
1244 .capture = {
1245 .stream_name = "AIF1 Capture",
1246 .channels_min = 1,
1247 .channels_max = 2,
1248 .rates = RT5616_STEREO_RATES,
1249 .formats = RT5616_FORMATS,
1250 },
1251 .ops = &rt5616_aif_dai_ops,
1252 },
1253};
1254
1255static struct snd_soc_codec_driver soc_codec_dev_rt5616 = {
1256 .probe = rt5616_probe,
1257 .suspend = rt5616_suspend,
1258 .resume = rt5616_resume,
1259 .set_bias_level = rt5616_set_bias_level,
1260 .idle_bias_off = true,
1261 .controls = rt5616_snd_controls,
1262 .num_controls = ARRAY_SIZE(rt5616_snd_controls),
1263 .dapm_widgets = rt5616_dapm_widgets,
1264 .num_dapm_widgets = ARRAY_SIZE(rt5616_dapm_widgets),
1265 .dapm_routes = rt5616_dapm_routes,
1266 .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes),
1267};
1268
1269static const struct regmap_config rt5616_regmap = {
1270 .reg_bits = 8,
1271 .val_bits = 16,
1272 .use_single_rw = true,
1273 .max_register = RT5616_DEVICE_ID + 1 + (ARRAY_SIZE(rt5616_ranges) *
1274 RT5616_PR_SPACING),
1275 .volatile_reg = rt5616_volatile_register,
1276 .readable_reg = rt5616_readable_register,
1277 .cache_type = REGCACHE_RBTREE,
1278 .reg_defaults = rt5616_reg,
1279 .num_reg_defaults = ARRAY_SIZE(rt5616_reg),
1280 .ranges = rt5616_ranges,
1281 .num_ranges = ARRAY_SIZE(rt5616_ranges),
1282};
1283
1284static const struct i2c_device_id rt5616_i2c_id[] = {
1285 { "rt5616", 0 },
1286 { }
1287};
1288MODULE_DEVICE_TABLE(i2c, rt5616_i2c_id);
1289
1290#if defined(CONFIG_OF)
1291static const struct of_device_id rt5616_of_match[] = {
1292 { .compatible = "realtek,rt5616", },
1293 {},
1294};
1295MODULE_DEVICE_TABLE(of, rt5616_of_match);
1296#endif
1297
1298static int rt5616_i2c_probe(struct i2c_client *i2c,
1299 const struct i2c_device_id *id)
1300{
1301 struct rt5616_priv *rt5616;
1302 unsigned int val;
1303 int ret;
1304
1305 rt5616 = devm_kzalloc(&i2c->dev, sizeof(struct rt5616_priv),
1306 GFP_KERNEL);
1307 if (rt5616 == NULL)
1308 return -ENOMEM;
1309
1310 i2c_set_clientdata(i2c, rt5616);
1311
1312 rt5616->regmap = devm_regmap_init_i2c(i2c, &rt5616_regmap);
1313 if (IS_ERR(rt5616->regmap)) {
1314 ret = PTR_ERR(rt5616->regmap);
1315 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1316 ret);
1317 return ret;
1318 }
1319
1320 regmap_read(rt5616->regmap, RT5616_DEVICE_ID, &val);
1321 if (val != 0x6281) {
1322 dev_err(&i2c->dev,
1323 "Device with ID register %#x is not rt5616\n",
1324 val);
1325 return -ENODEV;
1326 }
1327 regmap_write(rt5616->regmap, RT5616_RESET, 0);
1328 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1329 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1330 RT5616_PWR_BG | RT5616_PWR_VREF2,
1331 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1332 RT5616_PWR_BG | RT5616_PWR_VREF2);
1333 mdelay(10);
1334 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1335 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1336 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1337
1338 ret = regmap_register_patch(rt5616->regmap, init_list,
1339 ARRAY_SIZE(init_list));
1340 if (ret != 0)
1341 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1342
1343 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1344 RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);
1345
1346 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,
1347 rt5616_dai, ARRAY_SIZE(rt5616_dai));
1348
1349}
1350
1351static int rt5616_i2c_remove(struct i2c_client *i2c)
1352{
1353 snd_soc_unregister_codec(&i2c->dev);
1354
1355 return 0;
1356}
1357
1358static void rt5616_i2c_shutdown(struct i2c_client *client)
1359{
1360 struct rt5616_priv *rt5616 = i2c_get_clientdata(client);
1361
1362 regmap_write(rt5616->regmap, RT5616_HP_VOL, 0xc8c8);
1363 regmap_write(rt5616->regmap, RT5616_LOUT_CTRL1, 0xc8c8);
1364
1365}
1366
1367static struct i2c_driver rt5616_i2c_driver = {
1368 .driver = {
1369 .name = "rt5616",
1370 .of_match_table = of_match_ptr(rt5616_of_match),
1371 },
1372 .probe = rt5616_i2c_probe,
1373 .remove = rt5616_i2c_remove,
1374 .shutdown = rt5616_i2c_shutdown,
1375 .id_table = rt5616_i2c_id,
1376};
1377module_i2c_driver(rt5616_i2c_driver);
1378
1379MODULE_DESCRIPTION("ASoC RT5616 driver");
1380MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
1381MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/rt5616.h b/sound/soc/codecs/rt5616.h
new file mode 100644
index 000000000000..f88cdddbc34a
--- /dev/null
+++ b/sound/soc/codecs/rt5616.h
@@ -0,0 +1,1819 @@
1/*
2 * rt5616.h -- RT5616 ALSA SoC audio driver
3 *
4 * Copyright 2011 Realtek Microelectronics
5 * Author: Johnny Hsu <johnnyhsu@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 __RT5616_H__
13#define __RT5616_H__
14
15/* Info */
16#define RT5616_RESET 0x00
17#define RT5616_VERSION_ID 0xfd
18#define RT5616_VENDOR_ID 0xfe
19#define RT5616_DEVICE_ID 0xff
20/* I/O - Output */
21#define RT5616_HP_VOL 0x02
22#define RT5616_LOUT_CTRL1 0x03
23#define RT5616_LOUT_CTRL2 0x05
24/* I/O - Input */
25#define RT5616_IN1_IN2 0x0d
26#define RT5616_INL1_INR1_VOL 0x0f
27/* I/O - ADC/DAC/DMIC */
28#define RT5616_DAC1_DIG_VOL 0x19
29#define RT5616_ADC_DIG_VOL 0x1c
30#define RT5616_ADC_BST_VOL 0x1e
31/* Mixer - D-D */
32#define RT5616_STO1_ADC_MIXER 0x27
33#define RT5616_AD_DA_MIXER 0x29
34#define RT5616_STO_DAC_MIXER 0x2a
35
36/* Mixer - ADC */
37#define RT5616_REC_L1_MIXER 0x3b
38#define RT5616_REC_L2_MIXER 0x3c
39#define RT5616_REC_R1_MIXER 0x3d
40#define RT5616_REC_R2_MIXER 0x3e
41/* Mixer - DAC */
42#define RT5616_HPO_MIXER 0x45
43#define RT5616_OUT_L1_MIXER 0x4d
44#define RT5616_OUT_L2_MIXER 0x4e
45#define RT5616_OUT_L3_MIXER 0x4f
46#define RT5616_OUT_R1_MIXER 0x50
47#define RT5616_OUT_R2_MIXER 0x51
48#define RT5616_OUT_R3_MIXER 0x52
49#define RT5616_LOUT_MIXER 0x53
50/* Power */
51#define RT5616_PWR_DIG1 0x61
52#define RT5616_PWR_DIG2 0x62
53#define RT5616_PWR_ANLG1 0x63
54#define RT5616_PWR_ANLG2 0x64
55#define RT5616_PWR_MIXER 0x65
56#define RT5616_PWR_VOL 0x66
57/* Private Register Control */
58#define RT5616_PRIV_INDEX 0x6a
59#define RT5616_PRIV_DATA 0x6c
60/* Format - ADC/DAC */
61#define RT5616_I2S1_SDP 0x70
62#define RT5616_ADDA_CLK1 0x73
63#define RT5616_ADDA_CLK2 0x74
64
65/* Function - Analog */
66#define RT5616_GLB_CLK 0x80
67#define RT5616_PLL_CTRL1 0x81
68#define RT5616_PLL_CTRL2 0x82
69#define RT5616_HP_OVCD 0x8b
70#define RT5616_DEPOP_M1 0x8e
71#define RT5616_DEPOP_M2 0x8f
72#define RT5616_DEPOP_M3 0x90
73#define RT5616_CHARGE_PUMP 0x91
74#define RT5616_PV_DET_SPK_G 0x92
75#define RT5616_MICBIAS 0x93
76#define RT5616_A_JD_CTL1 0x94
77#define RT5616_A_JD_CTL2 0x95
78/* Function - Digital */
79#define RT5616_EQ_CTRL1 0xb0
80#define RT5616_EQ_CTRL2 0xb1
81#define RT5616_WIND_FILTER 0xb2
82#define RT5616_DRC_AGC_1 0xb4
83#define RT5616_DRC_AGC_2 0xb5
84#define RT5616_DRC_AGC_3 0xb6
85#define RT5616_SVOL_ZC 0xb7
86#define RT5616_JD_CTRL1 0xbb
87#define RT5616_JD_CTRL2 0xbc
88#define RT5616_IRQ_CTRL1 0xbd
89#define RT5616_IRQ_CTRL2 0xbe
90#define RT5616_INT_IRQ_ST 0xbf
91#define RT5616_GPIO_CTRL1 0xc0
92#define RT5616_GPIO_CTRL2 0xc1
93#define RT5616_GPIO_CTRL3 0xc2
94#define RT5616_PGM_REG_ARR1 0xc8
95#define RT5616_PGM_REG_ARR2 0xc9
96#define RT5616_PGM_REG_ARR3 0xca
97#define RT5616_PGM_REG_ARR4 0xcb
98#define RT5616_PGM_REG_ARR5 0xcc
99#define RT5616_SCB_FUNC 0xcd
100#define RT5616_SCB_CTRL 0xce
101#define RT5616_BASE_BACK 0xcf
102#define RT5616_MP3_PLUS1 0xd0
103#define RT5616_MP3_PLUS2 0xd1
104#define RT5616_ADJ_HPF_CTRL1 0xd3
105#define RT5616_ADJ_HPF_CTRL2 0xd4
106#define RT5616_HP_CALIB_AMP_DET 0xd6
107#define RT5616_HP_CALIB2 0xd7
108#define RT5616_SV_ZCD1 0xd9
109#define RT5616_SV_ZCD2 0xda
110#define RT5616_D_MISC 0xfa
111/* Dummy Register */
112#define RT5616_DUMMY2 0xfb
113#define RT5616_DUMMY3 0xfc
114
115
116/* Index of Codec Private Register definition */
117#define RT5616_BIAS_CUR1 0x12
118#define RT5616_BIAS_CUR3 0x14
119#define RT5616_CLSD_INT_REG1 0x1c
120#define RT5616_MAMP_INT_REG2 0x37
121#define RT5616_CHOP_DAC_ADC 0x3d
122#define RT5616_3D_SPK 0x63
123#define RT5616_WND_1 0x6c
124#define RT5616_WND_2 0x6d
125#define RT5616_WND_3 0x6e
126#define RT5616_WND_4 0x6f
127#define RT5616_WND_5 0x70
128#define RT5616_WND_8 0x73
129#define RT5616_DIP_SPK_INF 0x75
130#define RT5616_HP_DCC_INT1 0x77
131#define RT5616_EQ_BW_LOP 0xa0
132#define RT5616_EQ_GN_LOP 0xa1
133#define RT5616_EQ_FC_BP1 0xa2
134#define RT5616_EQ_BW_BP1 0xa3
135#define RT5616_EQ_GN_BP1 0xa4
136#define RT5616_EQ_FC_BP2 0xa5
137#define RT5616_EQ_BW_BP2 0xa6
138#define RT5616_EQ_GN_BP2 0xa7
139#define RT5616_EQ_FC_BP3 0xa8
140#define RT5616_EQ_BW_BP3 0xa9
141#define RT5616_EQ_GN_BP3 0xaa
142#define RT5616_EQ_FC_BP4 0xab
143#define RT5616_EQ_BW_BP4 0xac
144#define RT5616_EQ_GN_BP4 0xad
145#define RT5616_EQ_FC_HIP1 0xae
146#define RT5616_EQ_GN_HIP1 0xaf
147#define RT5616_EQ_FC_HIP2 0xb0
148#define RT5616_EQ_BW_HIP2 0xb1
149#define RT5616_EQ_GN_HIP2 0xb2
150#define RT5616_EQ_PRE_VOL 0xb3
151#define RT5616_EQ_PST_VOL 0xb4
152
153
154/* global definition */
155#define RT5616_L_MUTE (0x1 << 15)
156#define RT5616_L_MUTE_SFT 15
157#define RT5616_VOL_L_MUTE (0x1 << 14)
158#define RT5616_VOL_L_SFT 14
159#define RT5616_R_MUTE (0x1 << 7)
160#define RT5616_R_MUTE_SFT 7
161#define RT5616_VOL_R_MUTE (0x1 << 6)
162#define RT5616_VOL_R_SFT 6
163#define RT5616_L_VOL_MASK (0x3f << 8)
164#define RT5616_L_VOL_SFT 8
165#define RT5616_R_VOL_MASK (0x3f)
166#define RT5616_R_VOL_SFT 0
167
168/* LOUT Control 2(0x05) */
169#define RT5616_EN_DFO (0x1 << 15)
170
171/* IN1 and IN2 Control (0x0d) */
172/* IN3 and IN4 Control (0x0e) */
173#define RT5616_BST_MASK1 (0xf<<12)
174#define RT5616_BST_SFT1 12
175#define RT5616_BST_MASK2 (0xf<<8)
176#define RT5616_BST_SFT2 8
177#define RT5616_IN_DF1 (0x1 << 7)
178#define RT5616_IN_SFT1 7
179#define RT5616_IN_DF2 (0x1 << 6)
180#define RT5616_IN_SFT2 6
181
182/* INL1 and INR1 Volume Control (0x0f) */
183#define RT5616_INL_VOL_MASK (0x1f << 8)
184#define RT5616_INL_VOL_SFT 8
185#define RT5616_INR_SEL_MASK (0x1 << 7)
186#define RT5616_INR_SEL_SFT 7
187#define RT5616_INR_SEL_IN4N (0x0 << 7)
188#define RT5616_INR_SEL_MONON (0x1 << 7)
189#define RT5616_INR_VOL_MASK (0x1f)
190#define RT5616_INR_VOL_SFT 0
191
192/* DAC1 Digital Volume (0x19) */
193#define RT5616_DAC_L1_VOL_MASK (0xff << 8)
194#define RT5616_DAC_L1_VOL_SFT 8
195#define RT5616_DAC_R1_VOL_MASK (0xff)
196#define RT5616_DAC_R1_VOL_SFT 0
197
198/* DAC2 Digital Volume (0x1a) */
199#define RT5616_DAC_L2_VOL_MASK (0xff << 8)
200#define RT5616_DAC_L2_VOL_SFT 8
201#define RT5616_DAC_R2_VOL_MASK (0xff)
202#define RT5616_DAC_R2_VOL_SFT 0
203
204/* ADC Digital Volume Control (0x1c) */
205#define RT5616_ADC_L_VOL_MASK (0x7f << 8)
206#define RT5616_ADC_L_VOL_SFT 8
207#define RT5616_ADC_R_VOL_MASK (0x7f)
208#define RT5616_ADC_R_VOL_SFT 0
209
210/* Mono ADC Digital Volume Control (0x1d) */
211#define RT5616_M_MONO_ADC_L (0x1 << 15)
212#define RT5616_M_MONO_ADC_L_SFT 15
213#define RT5616_MONO_ADC_L_VOL_MASK (0x7f << 8)
214#define RT5616_MONO_ADC_L_VOL_SFT 8
215#define RT5616_M_MONO_ADC_R (0x1 << 7)
216#define RT5616_M_MONO_ADC_R_SFT 7
217#define RT5616_MONO_ADC_R_VOL_MASK (0x7f)
218#define RT5616_MONO_ADC_R_VOL_SFT 0
219
220/* ADC Boost Volume Control (0x1e) */
221#define RT5616_ADC_L_BST_MASK (0x3 << 14)
222#define RT5616_ADC_L_BST_SFT 14
223#define RT5616_ADC_R_BST_MASK (0x3 << 12)
224#define RT5616_ADC_R_BST_SFT 12
225#define RT5616_ADC_COMP_MASK (0x3 << 10)
226#define RT5616_ADC_COMP_SFT 10
227
228/* Stereo ADC1 Mixer Control (0x27) */
229#define RT5616_M_STO1_ADC_L1 (0x1 << 14)
230#define RT5616_M_STO1_ADC_L1_SFT 14
231#define RT5616_M_STO1_ADC_R1 (0x1 << 6)
232#define RT5616_M_STO1_ADC_R1_SFT 6
233
234/* ADC Mixer to DAC Mixer Control (0x29) */
235#define RT5616_M_ADCMIX_L (0x1 << 15)
236#define RT5616_M_ADCMIX_L_SFT 15
237#define RT5616_M_IF1_DAC_L (0x1 << 14)
238#define RT5616_M_IF1_DAC_L_SFT 14
239#define RT5616_M_ADCMIX_R (0x1 << 7)
240#define RT5616_M_ADCMIX_R_SFT 7
241#define RT5616_M_IF1_DAC_R (0x1 << 6)
242#define RT5616_M_IF1_DAC_R_SFT 6
243
244/* Stereo DAC Mixer Control (0x2a) */
245#define RT5616_M_DAC_L1_MIXL (0x1 << 14)
246#define RT5616_M_DAC_L1_MIXL_SFT 14
247#define RT5616_DAC_L1_STO_L_VOL_MASK (0x1 << 13)
248#define RT5616_DAC_L1_STO_L_VOL_SFT 13
249#define RT5616_M_DAC_R1_MIXL (0x1 << 9)
250#define RT5616_M_DAC_R1_MIXL_SFT 9
251#define RT5616_DAC_R1_STO_L_VOL_MASK (0x1 << 8)
252#define RT5616_DAC_R1_STO_L_VOL_SFT 8
253#define RT5616_M_DAC_R1_MIXR (0x1 << 6)
254#define RT5616_M_DAC_R1_MIXR_SFT 6
255#define RT5616_DAC_R1_STO_R_VOL_MASK (0x1 << 5)
256#define RT5616_DAC_R1_STO_R_VOL_SFT 5
257#define RT5616_M_DAC_L1_MIXR (0x1 << 1)
258#define RT5616_M_DAC_L1_MIXR_SFT 1
259#define RT5616_DAC_L1_STO_R_VOL_MASK (0x1)
260#define RT5616_DAC_L1_STO_R_VOL_SFT 0
261
262/* DD Mixer Control (0x2b) */
263#define RT5616_M_STO_DD_L1 (0x1 << 14)
264#define RT5616_M_STO_DD_L1_SFT 14
265#define RT5616_STO_DD_L1_VOL_MASK (0x1 << 13)
266#define RT5616_DAC_DD_L1_VOL_SFT 13
267#define RT5616_M_STO_DD_L2 (0x1 << 12)
268#define RT5616_M_STO_DD_L2_SFT 12
269#define RT5616_STO_DD_L2_VOL_MASK (0x1 << 11)
270#define RT5616_STO_DD_L2_VOL_SFT 11
271#define RT5616_M_STO_DD_R2_L (0x1 << 10)
272#define RT5616_M_STO_DD_R2_L_SFT 10
273#define RT5616_STO_DD_R2_L_VOL_MASK (0x1 << 9)
274#define RT5616_STO_DD_R2_L_VOL_SFT 9
275#define RT5616_M_STO_DD_R1 (0x1 << 6)
276#define RT5616_M_STO_DD_R1_SFT 6
277#define RT5616_STO_DD_R1_VOL_MASK (0x1 << 5)
278#define RT5616_STO_DD_R1_VOL_SFT 5
279#define RT5616_M_STO_DD_R2 (0x1 << 4)
280#define RT5616_M_STO_DD_R2_SFT 4
281#define RT5616_STO_DD_R2_VOL_MASK (0x1 << 3)
282#define RT5616_STO_DD_R2_VOL_SFT 3
283#define RT5616_M_STO_DD_L2_R (0x1 << 2)
284#define RT5616_M_STO_DD_L2_R_SFT 2
285#define RT5616_STO_DD_L2_R_VOL_MASK (0x1 << 1)
286#define RT5616_STO_DD_L2_R_VOL_SFT 1
287
288/* Digital Mixer Control (0x2c) */
289#define RT5616_M_STO_L_DAC_L (0x1 << 15)
290#define RT5616_M_STO_L_DAC_L_SFT 15
291#define RT5616_STO_L_DAC_L_VOL_MASK (0x1 << 14)
292#define RT5616_STO_L_DAC_L_VOL_SFT 14
293#define RT5616_M_DAC_L2_DAC_L (0x1 << 13)
294#define RT5616_M_DAC_L2_DAC_L_SFT 13
295#define RT5616_DAC_L2_DAC_L_VOL_MASK (0x1 << 12)
296#define RT5616_DAC_L2_DAC_L_VOL_SFT 12
297#define RT5616_M_STO_R_DAC_R (0x1 << 11)
298#define RT5616_M_STO_R_DAC_R_SFT 11
299#define RT5616_STO_R_DAC_R_VOL_MASK (0x1 << 10)
300#define RT5616_STO_R_DAC_R_VOL_SFT 10
301#define RT5616_M_DAC_R2_DAC_R (0x1 << 9)
302#define RT5616_M_DAC_R2_DAC_R_SFT 9
303#define RT5616_DAC_R2_DAC_R_VOL_MASK (0x1 << 8)
304#define RT5616_DAC_R2_DAC_R_VOL_SFT 8
305
306/* DSP Path Control 1 (0x2d) */
307#define RT5616_RXDP_SRC_MASK (0x1 << 15)
308#define RT5616_RXDP_SRC_SFT 15
309#define RT5616_RXDP_SRC_NOR (0x0 << 15)
310#define RT5616_RXDP_SRC_DIV3 (0x1 << 15)
311#define RT5616_TXDP_SRC_MASK (0x1 << 14)
312#define RT5616_TXDP_SRC_SFT 14
313#define RT5616_TXDP_SRC_NOR (0x0 << 14)
314#define RT5616_TXDP_SRC_DIV3 (0x1 << 14)
315
316/* DSP Path Control 2 (0x2e) */
317#define RT5616_DAC_L2_SEL_MASK (0x3 << 14)
318#define RT5616_DAC_L2_SEL_SFT 14
319#define RT5616_DAC_L2_SEL_IF2 (0x0 << 14)
320#define RT5616_DAC_L2_SEL_IF3 (0x1 << 14)
321#define RT5616_DAC_L2_SEL_TXDC (0x2 << 14)
322#define RT5616_DAC_L2_SEL_BASS (0x3 << 14)
323#define RT5616_DAC_R2_SEL_MASK (0x3 << 12)
324#define RT5616_DAC_R2_SEL_SFT 12
325#define RT5616_DAC_R2_SEL_IF2 (0x0 << 12)
326#define RT5616_DAC_R2_SEL_IF3 (0x1 << 12)
327#define RT5616_DAC_R2_SEL_TXDC (0x2 << 12)
328#define RT5616_IF2_ADC_L_SEL_MASK (0x1 << 11)
329#define RT5616_IF2_ADC_L_SEL_SFT 11
330#define RT5616_IF2_ADC_L_SEL_TXDP (0x0 << 11)
331#define RT5616_IF2_ADC_L_SEL_PASS (0x1 << 11)
332#define RT5616_IF2_ADC_R_SEL_MASK (0x1 << 10)
333#define RT5616_IF2_ADC_R_SEL_SFT 10
334#define RT5616_IF2_ADC_R_SEL_TXDP (0x0 << 10)
335#define RT5616_IF2_ADC_R_SEL_PASS (0x1 << 10)
336#define RT5616_RXDC_SEL_MASK (0x3 << 8)
337#define RT5616_RXDC_SEL_SFT 8
338#define RT5616_RXDC_SEL_NOR (0x0 << 8)
339#define RT5616_RXDC_SEL_L2R (0x1 << 8)
340#define RT5616_RXDC_SEL_R2L (0x2 << 8)
341#define RT5616_RXDC_SEL_SWAP (0x3 << 8)
342#define RT5616_RXDP_SEL_MASK (0x3 << 6)
343#define RT5616_RXDP_SEL_SFT 6
344#define RT5616_RXDP_SEL_NOR (0x0 << 6)
345#define RT5616_RXDP_SEL_L2R (0x1 << 6)
346#define RT5616_RXDP_SEL_R2L (0x2 << 6)
347#define RT5616_RXDP_SEL_SWAP (0x3 << 6)
348#define RT5616_TXDC_SEL_MASK (0x3 << 4)
349#define RT5616_TXDC_SEL_SFT 4
350#define RT5616_TXDC_SEL_NOR (0x0 << 4)
351#define RT5616_TXDC_SEL_L2R (0x1 << 4)
352#define RT5616_TXDC_SEL_R2L (0x2 << 4)
353#define RT5616_TXDC_SEL_SWAP (0x3 << 4)
354#define RT5616_TXDP_SEL_MASK (0x3 << 2)
355#define RT5616_TXDP_SEL_SFT 2
356#define RT5616_TXDP_SEL_NOR (0x0 << 2)
357#define RT5616_TXDP_SEL_L2R (0x1 << 2)
358#define RT5616_TXDP_SEL_R2L (0x2 << 2)
359#define RT5616_TRXDP_SEL_SWAP (0x3 << 2)
360
361/* REC Left Mixer Control 1 (0x3b) */
362#define RT5616_G_LN_L2_RM_L_MASK (0x7 << 13)
363#define RT5616_G_IN_L2_RM_L_SFT 13
364#define RT5616_G_LN_L1_RM_L_MASK (0x7 << 10)
365#define RT5616_G_IN_L1_RM_L_SFT 10
366#define RT5616_G_BST3_RM_L_MASK (0x7 << 4)
367#define RT5616_G_BST3_RM_L_SFT 4
368#define RT5616_G_BST2_RM_L_MASK (0x7 << 1)
369#define RT5616_G_BST2_RM_L_SFT 1
370
371/* REC Left Mixer Control 2 (0x3c) */
372#define RT5616_G_BST1_RM_L_MASK (0x7 << 13)
373#define RT5616_G_BST1_RM_L_SFT 13
374#define RT5616_G_OM_L_RM_L_MASK (0x7 << 10)
375#define RT5616_G_OM_L_RM_L_SFT 10
376#define RT5616_M_IN2_L_RM_L (0x1 << 6)
377#define RT5616_M_IN2_L_RM_L_SFT 6
378#define RT5616_M_IN1_L_RM_L (0x1 << 5)
379#define RT5616_M_IN1_L_RM_L_SFT 5
380#define RT5616_M_BST3_RM_L (0x1 << 3)
381#define RT5616_M_BST3_RM_L_SFT 3
382#define RT5616_M_BST2_RM_L (0x1 << 2)
383#define RT5616_M_BST2_RM_L_SFT 2
384#define RT5616_M_BST1_RM_L (0x1 << 1)
385#define RT5616_M_BST1_RM_L_SFT 1
386#define RT5616_M_OM_L_RM_L (0x1)
387#define RT5616_M_OM_L_RM_L_SFT 0
388
389/* REC Right Mixer Control 1 (0x3d) */
390#define RT5616_G_IN2_R_RM_R_MASK (0x7 << 13)
391#define RT5616_G_IN2_R_RM_R_SFT 13
392#define RT5616_G_IN1_R_RM_R_MASK (0x7 << 10)
393#define RT5616_G_IN1_R_RM_R_SFT 10
394#define RT5616_G_BST3_RM_R_MASK (0x7 << 4)
395#define RT5616_G_BST3_RM_R_SFT 4
396#define RT5616_G_BST2_RM_R_MASK (0x7 << 1)
397#define RT5616_G_BST2_RM_R_SFT 1
398
399/* REC Right Mixer Control 2 (0x3e) */
400#define RT5616_G_BST1_RM_R_MASK (0x7 << 13)
401#define RT5616_G_BST1_RM_R_SFT 13
402#define RT5616_G_OM_R_RM_R_MASK (0x7 << 10)
403#define RT5616_G_OM_R_RM_R_SFT 10
404#define RT5616_M_IN2_R_RM_R (0x1 << 6)
405#define RT5616_M_IN2_R_RM_R_SFT 6
406#define RT5616_M_IN1_R_RM_R (0x1 << 5)
407#define RT5616_M_IN1_R_RM_R_SFT 5
408#define RT5616_M_BST3_RM_R (0x1 << 3)
409#define RT5616_M_BST3_RM_R_SFT 3
410#define RT5616_M_BST2_RM_R (0x1 << 2)
411#define RT5616_M_BST2_RM_R_SFT 2
412#define RT5616_M_BST1_RM_R (0x1 << 1)
413#define RT5616_M_BST1_RM_R_SFT 1
414#define RT5616_M_OM_R_RM_R (0x1)
415#define RT5616_M_OM_R_RM_R_SFT 0
416
417/* HPMIX Control (0x45) */
418#define RT5616_M_DAC1_HM (0x1 << 14)
419#define RT5616_M_DAC1_HM_SFT 14
420#define RT5616_M_HPVOL_HM (0x1 << 13)
421#define RT5616_M_HPVOL_HM_SFT 13
422#define RT5616_G_HPOMIX_MASK (0x1 << 12)
423#define RT5616_G_HPOMIX_SFT 12
424
425/* SPK Left Mixer Control (0x46) */
426#define RT5616_G_RM_L_SM_L_MASK (0x3 << 14)
427#define RT5616_G_RM_L_SM_L_SFT 14
428#define RT5616_G_IN_L_SM_L_MASK (0x3 << 12)
429#define RT5616_G_IN_L_SM_L_SFT 12
430#define RT5616_G_DAC_L1_SM_L_MASK (0x3 << 10)
431#define RT5616_G_DAC_L1_SM_L_SFT 10
432#define RT5616_G_DAC_L2_SM_L_MASK (0x3 << 8)
433#define RT5616_G_DAC_L2_SM_L_SFT 8
434#define RT5616_G_OM_L_SM_L_MASK (0x3 << 6)
435#define RT5616_G_OM_L_SM_L_SFT 6
436#define RT5616_M_RM_L_SM_L (0x1 << 5)
437#define RT5616_M_RM_L_SM_L_SFT 5
438#define RT5616_M_IN_L_SM_L (0x1 << 4)
439#define RT5616_M_IN_L_SM_L_SFT 4
440#define RT5616_M_DAC_L1_SM_L (0x1 << 3)
441#define RT5616_M_DAC_L1_SM_L_SFT 3
442#define RT5616_M_DAC_L2_SM_L (0x1 << 2)
443#define RT5616_M_DAC_L2_SM_L_SFT 2
444#define RT5616_M_OM_L_SM_L (0x1 << 1)
445#define RT5616_M_OM_L_SM_L_SFT 1
446
447/* SPK Right Mixer Control (0x47) */
448#define RT5616_G_RM_R_SM_R_MASK (0x3 << 14)
449#define RT5616_G_RM_R_SM_R_SFT 14
450#define RT5616_G_IN_R_SM_R_MASK (0x3 << 12)
451#define RT5616_G_IN_R_SM_R_SFT 12
452#define RT5616_G_DAC_R1_SM_R_MASK (0x3 << 10)
453#define RT5616_G_DAC_R1_SM_R_SFT 10
454#define RT5616_G_DAC_R2_SM_R_MASK (0x3 << 8)
455#define RT5616_G_DAC_R2_SM_R_SFT 8
456#define RT5616_G_OM_R_SM_R_MASK (0x3 << 6)
457#define RT5616_G_OM_R_SM_R_SFT 6
458#define RT5616_M_RM_R_SM_R (0x1 << 5)
459#define RT5616_M_RM_R_SM_R_SFT 5
460#define RT5616_M_IN_R_SM_R (0x1 << 4)
461#define RT5616_M_IN_R_SM_R_SFT 4
462#define RT5616_M_DAC_R1_SM_R (0x1 << 3)
463#define RT5616_M_DAC_R1_SM_R_SFT 3
464#define RT5616_M_DAC_R2_SM_R (0x1 << 2)
465#define RT5616_M_DAC_R2_SM_R_SFT 2
466#define RT5616_M_OM_R_SM_R (0x1 << 1)
467#define RT5616_M_OM_R_SM_R_SFT 1
468
469/* SPOLMIX Control (0x48) */
470#define RT5616_M_DAC_R1_SPM_L (0x1 << 15)
471#define RT5616_M_DAC_R1_SPM_L_SFT 15
472#define RT5616_M_DAC_L1_SPM_L (0x1 << 14)
473#define RT5616_M_DAC_L1_SPM_L_SFT 14
474#define RT5616_M_SV_R_SPM_L (0x1 << 13)
475#define RT5616_M_SV_R_SPM_L_SFT 13
476#define RT5616_M_SV_L_SPM_L (0x1 << 12)
477#define RT5616_M_SV_L_SPM_L_SFT 12
478#define RT5616_M_BST1_SPM_L (0x1 << 11)
479#define RT5616_M_BST1_SPM_L_SFT 11
480
481/* SPORMIX Control (0x49) */
482#define RT5616_M_DAC_R1_SPM_R (0x1 << 13)
483#define RT5616_M_DAC_R1_SPM_R_SFT 13
484#define RT5616_M_SV_R_SPM_R (0x1 << 12)
485#define RT5616_M_SV_R_SPM_R_SFT 12
486#define RT5616_M_BST1_SPM_R (0x1 << 11)
487#define RT5616_M_BST1_SPM_R_SFT 11
488
489/* SPOLMIX / SPORMIX Ratio Control (0x4a) */
490#define RT5616_SPO_CLSD_RATIO_MASK (0x7)
491#define RT5616_SPO_CLSD_RATIO_SFT 0
492
493/* Mono Output Mixer Control (0x4c) */
494#define RT5616_M_DAC_R2_MM (0x1 << 15)
495#define RT5616_M_DAC_R2_MM_SFT 15
496#define RT5616_M_DAC_L2_MM (0x1 << 14)
497#define RT5616_M_DAC_L2_MM_SFT 14
498#define RT5616_M_OV_R_MM (0x1 << 13)
499#define RT5616_M_OV_R_MM_SFT 13
500#define RT5616_M_OV_L_MM (0x1 << 12)
501#define RT5616_M_OV_L_MM_SFT 12
502#define RT5616_M_BST1_MM (0x1 << 11)
503#define RT5616_M_BST1_MM_SFT 11
504#define RT5616_G_MONOMIX_MASK (0x1 << 10)
505#define RT5616_G_MONOMIX_SFT 10
506
507/* Output Left Mixer Control 1 (0x4d) */
508#define RT5616_G_BST2_OM_L_MASK (0x7 << 10)
509#define RT5616_G_BST2_OM_L_SFT 10
510#define RT5616_G_BST1_OM_L_MASK (0x7 << 7)
511#define RT5616_G_BST1_OM_L_SFT 7
512#define RT5616_G_IN1_L_OM_L_MASK (0x7 << 4)
513#define RT5616_G_IN1_L_OM_L_SFT 4
514#define RT5616_G_RM_L_OM_L_MASK (0x7 << 1)
515#define RT5616_G_RM_L_OM_L_SFT 1
516
517/* Output Left Mixer Control 2 (0x4e) */
518#define RT5616_G_DAC_L1_OM_L_MASK (0x7 << 7)
519#define RT5616_G_DAC_L1_OM_L_SFT 7
520#define RT5616_G_IN2_L_OM_L_MASK (0x7 << 4)
521#define RT5616_G_IN2_L_OM_L_SFT 4
522
523/* Output Left Mixer Control 3 (0x4f) */
524#define RT5616_M_IN2_L_OM_L (0x1 << 9)
525#define RT5616_M_IN2_L_OM_L_SFT 9
526#define RT5616_M_BST2_OM_L (0x1 << 6)
527#define RT5616_M_BST2_OM_L_SFT 6
528#define RT5616_M_BST1_OM_L (0x1 << 5)
529#define RT5616_M_BST1_OM_L_SFT 5
530#define RT5616_M_IN1_L_OM_L (0x1 << 4)
531#define RT5616_M_IN1_L_OM_L_SFT 4
532#define RT5616_M_RM_L_OM_L (0x1 << 3)
533#define RT5616_M_RM_L_OM_L_SFT 3
534#define RT5616_M_DAC_L1_OM_L (0x1)
535#define RT5616_M_DAC_L1_OM_L_SFT 0
536
537/* Output Right Mixer Control 1 (0x50) */
538#define RT5616_G_BST2_OM_R_MASK (0x7 << 10)
539#define RT5616_G_BST2_OM_R_SFT 10
540#define RT5616_G_BST1_OM_R_MASK (0x7 << 7)
541#define RT5616_G_BST1_OM_R_SFT 7
542#define RT5616_G_IN1_R_OM_R_MASK (0x7 << 4)
543#define RT5616_G_IN1_R_OM_R_SFT 4
544#define RT5616_G_RM_R_OM_R_MASK (0x7 << 1)
545#define RT5616_G_RM_R_OM_R_SFT 1
546
547/* Output Right Mixer Control 2 (0x51) */
548#define RT5616_G_DAC_R1_OM_R_MASK (0x7 << 7)
549#define RT5616_G_DAC_R1_OM_R_SFT 7
550#define RT5616_G_IN2_R_OM_R_MASK (0x7 << 4)
551#define RT5616_G_IN2_R_OM_R_SFT 4
552
553/* Output Right Mixer Control 3 (0x52) */
554#define RT5616_M_IN2_R_OM_R (0x1 << 9)
555#define RT5616_M_IN2_R_OM_R_SFT 9
556#define RT5616_M_BST2_OM_R (0x1 << 6)
557#define RT5616_M_BST2_OM_R_SFT 6
558#define RT5616_M_BST1_OM_R (0x1 << 5)
559#define RT5616_M_BST1_OM_R_SFT 5
560#define RT5616_M_IN1_R_OM_R (0x1 << 4)
561#define RT5616_M_IN1_R_OM_R_SFT 4
562#define RT5616_M_RM_R_OM_R (0x1 << 3)
563#define RT5616_M_RM_R_OM_R_SFT 3
564#define RT5616_M_DAC_R1_OM_R (0x1)
565#define RT5616_M_DAC_R1_OM_R_SFT 0
566
567/* LOUT Mixer Control (0x53) */
568#define RT5616_M_DAC_L1_LM (0x1 << 15)
569#define RT5616_M_DAC_L1_LM_SFT 15
570#define RT5616_M_DAC_R1_LM (0x1 << 14)
571#define RT5616_M_DAC_R1_LM_SFT 14
572#define RT5616_M_OV_L_LM (0x1 << 13)
573#define RT5616_M_OV_L_LM_SFT 13
574#define RT5616_M_OV_R_LM (0x1 << 12)
575#define RT5616_M_OV_R_LM_SFT 12
576#define RT5616_G_LOUTMIX_MASK (0x1 << 11)
577#define RT5616_G_LOUTMIX_SFT 11
578
579/* Power Management for Digital 1 (0x61) */
580#define RT5616_PWR_I2S1 (0x1 << 15)
581#define RT5616_PWR_I2S1_BIT 15
582#define RT5616_PWR_I2S2 (0x1 << 14)
583#define RT5616_PWR_I2S2_BIT 14
584#define RT5616_PWR_DAC_L1 (0x1 << 12)
585#define RT5616_PWR_DAC_L1_BIT 12
586#define RT5616_PWR_DAC_R1 (0x1 << 11)
587#define RT5616_PWR_DAC_R1_BIT 11
588#define RT5616_PWR_ADC_L (0x1 << 2)
589#define RT5616_PWR_ADC_L_BIT 2
590#define RT5616_PWR_ADC_R (0x1 << 1)
591#define RT5616_PWR_ADC_R_BIT 1
592
593/* Power Management for Digital 2 (0x62) */
594#define RT5616_PWR_ADC_STO1_F (0x1 << 15)
595#define RT5616_PWR_ADC_STO1_F_BIT 15
596#define RT5616_PWR_DAC_STO1_F (0x1 << 11)
597#define RT5616_PWR_DAC_STO1_F_BIT 11
598
599/* Power Management for Analog 1 (0x63) */
600#define RT5616_PWR_VREF1 (0x1 << 15)
601#define RT5616_PWR_VREF1_BIT 15
602#define RT5616_PWR_FV1 (0x1 << 14)
603#define RT5616_PWR_FV1_BIT 14
604#define RT5616_PWR_MB (0x1 << 13)
605#define RT5616_PWR_MB_BIT 13
606#define RT5616_PWR_LM (0x1 << 12)
607#define RT5616_PWR_LM_BIT 12
608#define RT5616_PWR_BG (0x1 << 11)
609#define RT5616_PWR_BG_BIT 11
610#define RT5616_PWR_HP_L (0x1 << 7)
611#define RT5616_PWR_HP_L_BIT 7
612#define RT5616_PWR_HP_R (0x1 << 6)
613#define RT5616_PWR_HP_R_BIT 6
614#define RT5616_PWR_HA (0x1 << 5)
615#define RT5616_PWR_HA_BIT 5
616#define RT5616_PWR_VREF2 (0x1 << 4)
617#define RT5616_PWR_VREF2_BIT 4
618#define RT5616_PWR_FV2 (0x1 << 3)
619#define RT5616_PWR_FV2_BIT 3
620#define RT5616_PWR_LDO (0x1 << 2)
621#define RT5616_PWR_LDO_BIT 2
622#define RT5616_PWR_LDO_DVO_MASK (0x3)
623#define RT5616_PWR_LDO_DVO_1_0V 0
624#define RT5616_PWR_LDO_DVO_1_1V 1
625#define RT5616_PWR_LDO_DVO_1_2V 2
626#define RT5616_PWR_LDO_DVO_1_3V 3
627
628/* Power Management for Analog 2 (0x64) */
629#define RT5616_PWR_BST1 (0x1 << 15)
630#define RT5616_PWR_BST1_BIT 15
631#define RT5616_PWR_BST2 (0x1 << 14)
632#define RT5616_PWR_BST2_BIT 14
633#define RT5616_PWR_MB1 (0x1 << 11)
634#define RT5616_PWR_MB1_BIT 11
635#define RT5616_PWR_PLL (0x1 << 9)
636#define RT5616_PWR_PLL_BIT 9
637#define RT5616_PWR_BST1_OP2 (0x1 << 5)
638#define RT5616_PWR_BST1_OP2_BIT 5
639#define RT5616_PWR_BST2_OP2 (0x1 << 4)
640#define RT5616_PWR_BST2_OP2_BIT 4
641#define RT5616_PWR_BST3_OP2 (0x1 << 3)
642#define RT5616_PWR_BST3_OP2_BIT 3
643#define RT5616_PWR_JD_M (0x1 << 2)
644#define RT5616_PWM_JD_M_BIT 2
645#define RT5616_PWR_JD2 (0x1 << 1)
646#define RT5616_PWM_JD2_BIT 1
647#define RT5616_PWR_JD3 (0x1)
648#define RT5616_PWM_JD3_BIT 0
649
650/* Power Management for Mixer (0x65) */
651#define RT5616_PWR_OM_L (0x1 << 15)
652#define RT5616_PWR_OM_L_BIT 15
653#define RT5616_PWR_OM_R (0x1 << 14)
654#define RT5616_PWR_OM_R_BIT 14
655#define RT5616_PWR_RM_L (0x1 << 11)
656#define RT5616_PWR_RM_L_BIT 11
657#define RT5616_PWR_RM_R (0x1 << 10)
658#define RT5616_PWR_RM_R_BIT 10
659
660/* Power Management for Volume (0x66) */
661#define RT5616_PWR_OV_L (0x1 << 13)
662#define RT5616_PWR_OV_L_BIT 13
663#define RT5616_PWR_OV_R (0x1 << 12)
664#define RT5616_PWR_OV_R_BIT 12
665#define RT5616_PWR_HV_L (0x1 << 11)
666#define RT5616_PWR_HV_L_BIT 11
667#define RT5616_PWR_HV_R (0x1 << 10)
668#define RT5616_PWR_HV_R_BIT 10
669#define RT5616_PWR_IN1_L (0x1 << 9)
670#define RT5616_PWR_IN1_L_BIT 9
671#define RT5616_PWR_IN1_R (0x1 << 8)
672#define RT5616_PWR_IN1_R_BIT 8
673#define RT5616_PWR_IN2_L (0x1 << 7)
674#define RT5616_PWR_IN2_L_BIT 7
675#define RT5616_PWR_IN2_R (0x1 << 6)
676#define RT5616_PWR_IN2_R_BIT 6
677
678/* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71) */
679#define RT5616_I2S_MS_MASK (0x1 << 15)
680#define RT5616_I2S_MS_SFT 15
681#define RT5616_I2S_MS_M (0x0 << 15)
682#define RT5616_I2S_MS_S (0x1 << 15)
683#define RT5616_I2S_O_CP_MASK (0x3 << 10)
684#define RT5616_I2S_O_CP_SFT 10
685#define RT5616_I2S_O_CP_OFF (0x0 << 10)
686#define RT5616_I2S_O_CP_U_LAW (0x1 << 10)
687#define RT5616_I2S_O_CP_A_LAW (0x2 << 10)
688#define RT5616_I2S_I_CP_MASK (0x3 << 8)
689#define RT5616_I2S_I_CP_SFT 8
690#define RT5616_I2S_I_CP_OFF (0x0 << 8)
691#define RT5616_I2S_I_CP_U_LAW (0x1 << 8)
692#define RT5616_I2S_I_CP_A_LAW (0x2 << 8)
693#define RT5616_I2S_BP_MASK (0x1 << 7)
694#define RT5616_I2S_BP_SFT 7
695#define RT5616_I2S_BP_NOR (0x0 << 7)
696#define RT5616_I2S_BP_INV (0x1 << 7)
697#define RT5616_I2S_DL_MASK (0x3 << 2)
698#define RT5616_I2S_DL_SFT 2
699#define RT5616_I2S_DL_16 (0x0 << 2)
700#define RT5616_I2S_DL_20 (0x1 << 2)
701#define RT5616_I2S_DL_24 (0x2 << 2)
702#define RT5616_I2S_DL_8 (0x3 << 2)
703#define RT5616_I2S_DF_MASK (0x3)
704#define RT5616_I2S_DF_SFT 0
705#define RT5616_I2S_DF_I2S (0x0)
706#define RT5616_I2S_DF_LEFT (0x1)
707#define RT5616_I2S_DF_PCM_A (0x2)
708#define RT5616_I2S_DF_PCM_B (0x3)
709
710/* ADC/DAC Clock Control 1 (0x73) */
711#define RT5616_I2S_PD1_MASK (0x7 << 12)
712#define RT5616_I2S_PD1_SFT 12
713#define RT5616_I2S_PD1_1 (0x0 << 12)
714#define RT5616_I2S_PD1_2 (0x1 << 12)
715#define RT5616_I2S_PD1_3 (0x2 << 12)
716#define RT5616_I2S_PD1_4 (0x3 << 12)
717#define RT5616_I2S_PD1_6 (0x4 << 12)
718#define RT5616_I2S_PD1_8 (0x5 << 12)
719#define RT5616_I2S_PD1_12 (0x6 << 12)
720#define RT5616_I2S_PD1_16 (0x7 << 12)
721#define RT5616_I2S_BCLK_MS2_MASK (0x1 << 11)
722#define RT5616_DAC_OSR_MASK (0x3 << 2)
723#define RT5616_DAC_OSR_SFT 2
724#define RT5616_DAC_OSR_128 (0x0 << 2)
725#define RT5616_DAC_OSR_64 (0x1 << 2)
726#define RT5616_DAC_OSR_32 (0x2 << 2)
727#define RT5616_DAC_OSR_128_3 (0x3 << 2)
728#define RT5616_ADC_OSR_MASK (0x3)
729#define RT5616_ADC_OSR_SFT 0
730#define RT5616_ADC_OSR_128 (0x0)
731#define RT5616_ADC_OSR_64 (0x1)
732#define RT5616_ADC_OSR_32 (0x2)
733#define RT5616_ADC_OSR_128_3 (0x3)
734
735/* ADC/DAC Clock Control 2 (0x74) */
736#define RT5616_DAHPF_EN (0x1 << 11)
737#define RT5616_DAHPF_EN_SFT 11
738#define RT5616_ADHPF_EN (0x1 << 10)
739#define RT5616_ADHPF_EN_SFT 10
740
741/* TDM Control 1 (0x77) */
742#define RT5616_TDM_INTEL_SEL_MASK (0x1 << 15)
743#define RT5616_TDM_INTEL_SEL_SFT 15
744#define RT5616_TDM_INTEL_SEL_64 (0x0 << 15)
745#define RT5616_TDM_INTEL_SEL_50 (0x1 << 15)
746#define RT5616_TDM_MODE_SEL_MASK (0x1 << 14)
747#define RT5616_TDM_MODE_SEL_SFT 14
748#define RT5616_TDM_MODE_SEL_NOR (0x0 << 14)
749#define RT5616_TDM_MODE_SEL_TDM (0x1 << 14)
750#define RT5616_TDM_CH_NUM_SEL_MASK (0x3 << 12)
751#define RT5616_TDM_CH_NUM_SEL_SFT 12
752#define RT5616_TDM_CH_NUM_SEL_2 (0x0 << 12)
753#define RT5616_TDM_CH_NUM_SEL_4 (0x1 << 12)
754#define RT5616_TDM_CH_NUM_SEL_6 (0x2 << 12)
755#define RT5616_TDM_CH_NUM_SEL_8 (0x3 << 12)
756#define RT5616_TDM_CH_LEN_SEL_MASK (0x3 << 10)
757#define RT5616_TDM_CH_LEN_SEL_SFT 10
758#define RT5616_TDM_CH_LEN_SEL_16 (0x0 << 10)
759#define RT5616_TDM_CH_LEN_SEL_20 (0x1 << 10)
760#define RT5616_TDM_CH_LEN_SEL_24 (0x2 << 10)
761#define RT5616_TDM_CH_LEN_SEL_32 (0x3 << 10)
762#define RT5616_TDM_ADC_SEL_MASK (0x1 << 9)
763#define RT5616_TDM_ADC_SEL_SFT 9
764#define RT5616_TDM_ADC_SEL_NOR (0x0 << 9)
765#define RT5616_TDM_ADC_SEL_SWAP (0x1 << 9)
766#define RT5616_TDM_ADC_START_SEL_MASK (0x1 << 8)
767#define RT5616_TDM_ADC_START_SEL_SFT 8
768#define RT5616_TDM_ADC_START_SEL_SL0 (0x0 << 8)
769#define RT5616_TDM_ADC_START_SEL_SL4 (0x1 << 8)
770#define RT5616_TDM_I2S_CH2_SEL_MASK (0x3 << 6)
771#define RT5616_TDM_I2S_CH2_SEL_SFT 6
772#define RT5616_TDM_I2S_CH2_SEL_LR (0x0 << 6)
773#define RT5616_TDM_I2S_CH2_SEL_RL (0x1 << 6)
774#define RT5616_TDM_I2S_CH2_SEL_LL (0x2 << 6)
775#define RT5616_TDM_I2S_CH2_SEL_RR (0x3 << 6)
776#define RT5616_TDM_I2S_CH4_SEL_MASK (0x3 << 4)
777#define RT5616_TDM_I2S_CH4_SEL_SFT 4
778#define RT5616_TDM_I2S_CH4_SEL_LR (0x0 << 4)
779#define RT5616_TDM_I2S_CH4_SEL_RL (0x1 << 4)
780#define RT5616_TDM_I2S_CH4_SEL_LL (0x2 << 4)
781#define RT5616_TDM_I2S_CH4_SEL_RR (0x3 << 4)
782#define RT5616_TDM_I2S_CH6_SEL_MASK (0x3 << 2)
783#define RT5616_TDM_I2S_CH6_SEL_SFT 2
784#define RT5616_TDM_I2S_CH6_SEL_LR (0x0 << 2)
785#define RT5616_TDM_I2S_CH6_SEL_RL (0x1 << 2)
786#define RT5616_TDM_I2S_CH6_SEL_LL (0x2 << 2)
787#define RT5616_TDM_I2S_CH6_SEL_RR (0x3 << 2)
788#define RT5616_TDM_I2S_CH8_SEL_MASK (0x3)
789#define RT5616_TDM_I2S_CH8_SEL_SFT 0
790#define RT5616_TDM_I2S_CH8_SEL_LR (0x0)
791#define RT5616_TDM_I2S_CH8_SEL_RL (0x1)
792#define RT5616_TDM_I2S_CH8_SEL_LL (0x2)
793#define RT5616_TDM_I2S_CH8_SEL_RR (0x3)
794
795/* TDM Control 2 (0x78) */
796#define RT5616_TDM_LRCK_POL_SEL_MASK (0x1 << 15)
797#define RT5616_TDM_LRCK_POL_SEL_SFT 15
798#define RT5616_TDM_LRCK_POL_SEL_NOR (0x0 << 15)
799#define RT5616_TDM_LRCK_POL_SEL_INV (0x1 << 15)
800#define RT5616_TDM_CH_VAL_SEL_MASK (0x1 << 14)
801#define RT5616_TDM_CH_VAL_SEL_SFT 14
802#define RT5616_TDM_CH_VAL_SEL_CH01 (0x0 << 14)
803#define RT5616_TDM_CH_VAL_SEL_CH0123 (0x1 << 14)
804#define RT5616_TDM_CH_VAL_EN (0x1 << 13)
805#define RT5616_TDM_CH_VAL_SFT 13
806#define RT5616_TDM_LPBK_EN (0x1 << 12)
807#define RT5616_TDM_LPBK_SFT 12
808#define RT5616_TDM_LRCK_PULSE_SEL_MASK (0x1 << 11)
809#define RT5616_TDM_LRCK_PULSE_SEL_SFT 11
810#define RT5616_TDM_LRCK_PULSE_SEL_BCLK (0x0 << 11)
811#define RT5616_TDM_LRCK_PULSE_SEL_CH (0x1 << 11)
812#define RT5616_TDM_END_EDGE_SEL_MASK (0x1 << 10)
813#define RT5616_TDM_END_EDGE_SEL_SFT 10
814#define RT5616_TDM_END_EDGE_SEL_POS (0x0 << 10)
815#define RT5616_TDM_END_EDGE_SEL_NEG (0x1 << 10)
816#define RT5616_TDM_END_EDGE_EN (0x1 << 9)
817#define RT5616_TDM_END_EDGE_EN_SFT 9
818#define RT5616_TDM_TRAN_EDGE_SEL_MASK (0x1 << 8)
819#define RT5616_TDM_TRAN_EDGE_SEL_SFT 8
820#define RT5616_TDM_TRAN_EDGE_SEL_POS (0x0 << 8)
821#define RT5616_TDM_TRAN_EDGE_SEL_NEG (0x1 << 8)
822#define RT5616_M_TDM2_L (0x1 << 7)
823#define RT5616_M_TDM2_L_SFT 7
824#define RT5616_M_TDM2_R (0x1 << 6)
825#define RT5616_M_TDM2_R_SFT 6
826#define RT5616_M_TDM4_L (0x1 << 5)
827#define RT5616_M_TDM4_L_SFT 5
828#define RT5616_M_TDM4_R (0x1 << 4)
829#define RT5616_M_TDM4_R_SFT 4
830
831/* Global Clock Control (0x80) */
832#define RT5616_SCLK_SRC_MASK (0x3 << 14)
833#define RT5616_SCLK_SRC_SFT 14
834#define RT5616_SCLK_SRC_MCLK (0x0 << 14)
835#define RT5616_SCLK_SRC_PLL1 (0x1 << 14)
836#define RT5616_PLL1_SRC_MASK (0x3 << 12)
837#define RT5616_PLL1_SRC_SFT 12
838#define RT5616_PLL1_SRC_MCLK (0x0 << 12)
839#define RT5616_PLL1_SRC_BCLK1 (0x1 << 12)
840#define RT5616_PLL1_SRC_BCLK2 (0x2 << 12)
841#define RT5616_PLL1_PD_MASK (0x1 << 3)
842#define RT5616_PLL1_PD_SFT 3
843#define RT5616_PLL1_PD_1 (0x0 << 3)
844#define RT5616_PLL1_PD_2 (0x1 << 3)
845
846#define RT5616_PLL_INP_MAX 40000000
847#define RT5616_PLL_INP_MIN 256000
848/* PLL M/N/K Code Control 1 (0x81) */
849#define RT5616_PLL_N_MAX 0x1ff
850#define RT5616_PLL_N_MASK (RT5616_PLL_N_MAX << 7)
851#define RT5616_PLL_N_SFT 7
852#define RT5616_PLL_K_MAX 0x1f
853#define RT5616_PLL_K_MASK (RT5616_PLL_K_MAX)
854#define RT5616_PLL_K_SFT 0
855
856/* PLL M/N/K Code Control 2 (0x82) */
857#define RT5616_PLL_M_MAX 0xf
858#define RT5616_PLL_M_MASK (RT5616_PLL_M_MAX << 12)
859#define RT5616_PLL_M_SFT 12
860#define RT5616_PLL_M_BP (0x1 << 11)
861#define RT5616_PLL_M_BP_SFT 11
862
863/* PLL tracking mode 1 (0x83) */
864#define RT5616_STO1_T_MASK (0x1 << 15)
865#define RT5616_STO1_T_SFT 15
866#define RT5616_STO1_T_SCLK (0x0 << 15)
867#define RT5616_STO1_T_LRCK1 (0x1 << 15)
868#define RT5616_STO2_T_MASK (0x1 << 12)
869#define RT5616_STO2_T_SFT 12
870#define RT5616_STO2_T_I2S2 (0x0 << 12)
871#define RT5616_STO2_T_LRCK2 (0x1 << 12)
872#define RT5616_ASRC2_REF_MASK (0x1 << 11)
873#define RT5616_ASRC2_REF_SFT 11
874#define RT5616_ASRC2_REF_LRCK2 (0x0 << 11)
875#define RT5616_ASRC2_REF_LRCK1 (0x1 << 11)
876#define RT5616_DMIC_1_M_MASK (0x1 << 9)
877#define RT5616_DMIC_1_M_SFT 9
878#define RT5616_DMIC_1_M_NOR (0x0 << 9)
879#define RT5616_DMIC_1_M_ASYN (0x1 << 9)
880
881/* PLL tracking mode 2 (0x84) */
882#define RT5616_STO1_ASRC_EN (0x1 << 15)
883#define RT5616_STO1_ASRC_EN_SFT 15
884#define RT5616_STO2_ASRC_EN (0x1 << 14)
885#define RT5616_STO2_ASRC_EN_SFT 14
886#define RT5616_STO1_DAC_M_MASK (0x1 << 13)
887#define RT5616_STO1_DAC_M_SFT 13
888#define RT5616_STO1_DAC_M_NOR (0x0 << 13)
889#define RT5616_STO1_DAC_M_ASRC (0x1 << 13)
890#define RT5616_STO2_DAC_M_MASK (0x1 << 12)
891#define RT5616_STO2_DAC_M_SFT 12
892#define RT5616_STO2_DAC_M_NOR (0x0 << 12)
893#define RT5616_STO2_DAC_M_ASRC (0x1 << 12)
894#define RT5616_ADC_M_MASK (0x1 << 11)
895#define RT5616_ADC_M_SFT 11
896#define RT5616_ADC_M_NOR (0x0 << 11)
897#define RT5616_ADC_M_ASRC (0x1 << 11)
898#define RT5616_I2S1_R_D_MASK (0x1 << 4)
899#define RT5616_I2S1_R_D_SFT 4
900#define RT5616_I2S1_R_D_DIS (0x0 << 4)
901#define RT5616_I2S1_R_D_EN (0x1 << 4)
902#define RT5616_I2S2_R_D_MASK (0x1 << 3)
903#define RT5616_I2S2_R_D_SFT 3
904#define RT5616_I2S2_R_D_DIS (0x0 << 3)
905#define RT5616_I2S2_R_D_EN (0x1 << 3)
906#define RT5616_PRE_SCLK_MASK (0x3)
907#define RT5616_PRE_SCLK_SFT 0
908#define RT5616_PRE_SCLK_512 (0x0)
909#define RT5616_PRE_SCLK_1024 (0x1)
910#define RT5616_PRE_SCLK_2048 (0x2)
911
912/* PLL tracking mode 3 (0x85) */
913#define RT5616_I2S1_RATE_MASK (0xf << 12)
914#define RT5616_I2S1_RATE_SFT 12
915#define RT5616_I2S2_RATE_MASK (0xf << 8)
916#define RT5616_I2S2_RATE_SFT 8
917#define RT5616_G_ASRC_LP_MASK (0x1 << 3)
918#define RT5616_G_ASRC_LP_SFT 3
919#define RT5616_ASRC_LP_F_M (0x1 << 2)
920#define RT5616_ASRC_LP_F_SFT 2
921#define RT5616_ASRC_LP_F_NOR (0x0 << 2)
922#define RT5616_ASRC_LP_F_SB (0x1 << 2)
923#define RT5616_FTK_PH_DET_MASK (0x3)
924#define RT5616_FTK_PH_DET_SFT 0
925#define RT5616_FTK_PH_DET_DIV1 (0x0)
926#define RT5616_FTK_PH_DET_DIV2 (0x1)
927#define RT5616_FTK_PH_DET_DIV4 (0x2)
928#define RT5616_FTK_PH_DET_DIV8 (0x3)
929
930/*PLL tracking mode 6 (0x89) */
931#define RT5616_I2S1_PD_MASK (0x7 << 12)
932#define RT5616_I2S1_PD_SFT 12
933#define RT5616_I2S2_PD_MASK (0x7 << 8)
934#define RT5616_I2S2_PD_SFT 8
935
936/*PLL tracking mode 7 (0x8a) */
937#define RT5616_FSI1_RATE_MASK (0xf << 12)
938#define RT5616_FSI1_RATE_SFT 12
939#define RT5616_FSI2_RATE_MASK (0xf << 8)
940#define RT5616_FSI2_RATE_SFT 8
941
942/* HPOUT Over Current Detection (0x8b) */
943#define RT5616_HP_OVCD_MASK (0x1 << 10)
944#define RT5616_HP_OVCD_SFT 10
945#define RT5616_HP_OVCD_DIS (0x0 << 10)
946#define RT5616_HP_OVCD_EN (0x1 << 10)
947#define RT5616_HP_OC_TH_MASK (0x3 << 8)
948#define RT5616_HP_OC_TH_SFT 8
949#define RT5616_HP_OC_TH_90 (0x0 << 8)
950#define RT5616_HP_OC_TH_105 (0x1 << 8)
951#define RT5616_HP_OC_TH_120 (0x2 << 8)
952#define RT5616_HP_OC_TH_135 (0x3 << 8)
953
954/* Depop Mode Control 1 (0x8e) */
955#define RT5616_SMT_TRIG_MASK (0x1 << 15)
956#define RT5616_SMT_TRIG_SFT 15
957#define RT5616_SMT_TRIG_DIS (0x0 << 15)
958#define RT5616_SMT_TRIG_EN (0x1 << 15)
959#define RT5616_HP_L_SMT_MASK (0x1 << 9)
960#define RT5616_HP_L_SMT_SFT 9
961#define RT5616_HP_L_SMT_DIS (0x0 << 9)
962#define RT5616_HP_L_SMT_EN (0x1 << 9)
963#define RT5616_HP_R_SMT_MASK (0x1 << 8)
964#define RT5616_HP_R_SMT_SFT 8
965#define RT5616_HP_R_SMT_DIS (0x0 << 8)
966#define RT5616_HP_R_SMT_EN (0x1 << 8)
967#define RT5616_HP_CD_PD_MASK (0x1 << 7)
968#define RT5616_HP_CD_PD_SFT 7
969#define RT5616_HP_CD_PD_DIS (0x0 << 7)
970#define RT5616_HP_CD_PD_EN (0x1 << 7)
971#define RT5616_RSTN_MASK (0x1 << 6)
972#define RT5616_RSTN_SFT 6
973#define RT5616_RSTN_DIS (0x0 << 6)
974#define RT5616_RSTN_EN (0x1 << 6)
975#define RT5616_RSTP_MASK (0x1 << 5)
976#define RT5616_RSTP_SFT 5
977#define RT5616_RSTP_DIS (0x0 << 5)
978#define RT5616_RSTP_EN (0x1 << 5)
979#define RT5616_HP_CO_MASK (0x1 << 4)
980#define RT5616_HP_CO_SFT 4
981#define RT5616_HP_CO_DIS (0x0 << 4)
982#define RT5616_HP_CO_EN (0x1 << 4)
983#define RT5616_HP_CP_MASK (0x1 << 3)
984#define RT5616_HP_CP_SFT 3
985#define RT5616_HP_CP_PD (0x0 << 3)
986#define RT5616_HP_CP_PU (0x1 << 3)
987#define RT5616_HP_SG_MASK (0x1 << 2)
988#define RT5616_HP_SG_SFT 2
989#define RT5616_HP_SG_DIS (0x0 << 2)
990#define RT5616_HP_SG_EN (0x1 << 2)
991#define RT5616_HP_DP_MASK (0x1 << 1)
992#define RT5616_HP_DP_SFT 1
993#define RT5616_HP_DP_PD (0x0 << 1)
994#define RT5616_HP_DP_PU (0x1 << 1)
995#define RT5616_HP_CB_MASK (0x1)
996#define RT5616_HP_CB_SFT 0
997#define RT5616_HP_CB_PD (0x0)
998#define RT5616_HP_CB_PU (0x1)
999
1000/* Depop Mode Control 2 (0x8f) */
1001#define RT5616_DEPOP_MASK (0x1 << 13)
1002#define RT5616_DEPOP_SFT 13
1003#define RT5616_DEPOP_AUTO (0x0 << 13)
1004#define RT5616_DEPOP_MAN (0x1 << 13)
1005#define RT5616_RAMP_MASK (0x1 << 12)
1006#define RT5616_RAMP_SFT 12
1007#define RT5616_RAMP_DIS (0x0 << 12)
1008#define RT5616_RAMP_EN (0x1 << 12)
1009#define RT5616_BPS_MASK (0x1 << 11)
1010#define RT5616_BPS_SFT 11
1011#define RT5616_BPS_DIS (0x0 << 11)
1012#define RT5616_BPS_EN (0x1 << 11)
1013#define RT5616_FAST_UPDN_MASK (0x1 << 10)
1014#define RT5616_FAST_UPDN_SFT 10
1015#define RT5616_FAST_UPDN_DIS (0x0 << 10)
1016#define RT5616_FAST_UPDN_EN (0x1 << 10)
1017#define RT5616_MRES_MASK (0x3 << 8)
1018#define RT5616_MRES_SFT 8
1019#define RT5616_MRES_15MO (0x0 << 8)
1020#define RT5616_MRES_25MO (0x1 << 8)
1021#define RT5616_MRES_35MO (0x2 << 8)
1022#define RT5616_MRES_45MO (0x3 << 8)
1023#define RT5616_VLO_MASK (0x1 << 7)
1024#define RT5616_VLO_SFT 7
1025#define RT5616_VLO_3V (0x0 << 7)
1026#define RT5616_VLO_32V (0x1 << 7)
1027#define RT5616_DIG_DP_MASK (0x1 << 6)
1028#define RT5616_DIG_DP_SFT 6
1029#define RT5616_DIG_DP_DIS (0x0 << 6)
1030#define RT5616_DIG_DP_EN (0x1 << 6)
1031#define RT5616_DP_TH_MASK (0x3 << 4)
1032#define RT5616_DP_TH_SFT 4
1033
1034/* Depop Mode Control 3 (0x90) */
1035#define RT5616_CP_SYS_MASK (0x7 << 12)
1036#define RT5616_CP_SYS_SFT 12
1037#define RT5616_CP_FQ1_MASK (0x7 << 8)
1038#define RT5616_CP_FQ1_SFT 8
1039#define RT5616_CP_FQ2_MASK (0x7 << 4)
1040#define RT5616_CP_FQ2_SFT 4
1041#define RT5616_CP_FQ3_MASK (0x7)
1042#define RT5616_CP_FQ3_SFT 0
1043#define RT5616_CP_FQ_1_5_KHZ 0
1044#define RT5616_CP_FQ_3_KHZ 1
1045#define RT5616_CP_FQ_6_KHZ 2
1046#define RT5616_CP_FQ_12_KHZ 3
1047#define RT5616_CP_FQ_24_KHZ 4
1048#define RT5616_CP_FQ_48_KHZ 5
1049#define RT5616_CP_FQ_96_KHZ 6
1050#define RT5616_CP_FQ_192_KHZ 7
1051
1052/* HPOUT charge pump (0x91) */
1053#define RT5616_OSW_L_MASK (0x1 << 11)
1054#define RT5616_OSW_L_SFT 11
1055#define RT5616_OSW_L_DIS (0x0 << 11)
1056#define RT5616_OSW_L_EN (0x1 << 11)
1057#define RT5616_OSW_R_MASK (0x1 << 10)
1058#define RT5616_OSW_R_SFT 10
1059#define RT5616_OSW_R_DIS (0x0 << 10)
1060#define RT5616_OSW_R_EN (0x1 << 10)
1061#define RT5616_PM_HP_MASK (0x3 << 8)
1062#define RT5616_PM_HP_SFT 8
1063#define RT5616_PM_HP_LV (0x0 << 8)
1064#define RT5616_PM_HP_MV (0x1 << 8)
1065#define RT5616_PM_HP_HV (0x2 << 8)
1066#define RT5616_IB_HP_MASK (0x3 << 6)
1067#define RT5616_IB_HP_SFT 6
1068#define RT5616_IB_HP_125IL (0x0 << 6)
1069#define RT5616_IB_HP_25IL (0x1 << 6)
1070#define RT5616_IB_HP_5IL (0x2 << 6)
1071#define RT5616_IB_HP_1IL (0x3 << 6)
1072
1073/* Micbias Control (0x93) */
1074#define RT5616_MIC1_BS_MASK (0x1 << 15)
1075#define RT5616_MIC1_BS_SFT 15
1076#define RT5616_MIC1_BS_9AV (0x0 << 15)
1077#define RT5616_MIC1_BS_75AV (0x1 << 15)
1078#define RT5616_MIC1_CLK_MASK (0x1 << 13)
1079#define RT5616_MIC1_CLK_SFT 13
1080#define RT5616_MIC1_CLK_DIS (0x0 << 13)
1081#define RT5616_MIC1_CLK_EN (0x1 << 13)
1082#define RT5616_MIC1_OVCD_MASK (0x1 << 11)
1083#define RT5616_MIC1_OVCD_SFT 11
1084#define RT5616_MIC1_OVCD_DIS (0x0 << 11)
1085#define RT5616_MIC1_OVCD_EN (0x1 << 11)
1086#define RT5616_MIC1_OVTH_MASK (0x3 << 9)
1087#define RT5616_MIC1_OVTH_SFT 9
1088#define RT5616_MIC1_OVTH_600UA (0x0 << 9)
1089#define RT5616_MIC1_OVTH_1500UA (0x1 << 9)
1090#define RT5616_MIC1_OVTH_2000UA (0x2 << 9)
1091#define RT5616_PWR_MB_MASK (0x1 << 5)
1092#define RT5616_PWR_MB_SFT 5
1093#define RT5616_PWR_MB_PD (0x0 << 5)
1094#define RT5616_PWR_MB_PU (0x1 << 5)
1095#define RT5616_PWR_CLK12M_MASK (0x1 << 4)
1096#define RT5616_PWR_CLK12M_SFT 4
1097#define RT5616_PWR_CLK12M_PD (0x0 << 4)
1098#define RT5616_PWR_CLK12M_PU (0x1 << 4)
1099
1100/* Analog JD Control 1 (0x94) */
1101#define RT5616_JD2_CMP_MASK (0x7 << 12)
1102#define RT5616_JD2_CMP_SFT 12
1103#define RT5616_JD_PU (0x1 << 11)
1104#define RT5616_JD_PU_SFT 11
1105#define RT5616_JD_PD (0x1 << 10)
1106#define RT5616_JD_PD_SFT 10
1107#define RT5616_JD_MODE_SEL_MASK (0x3 << 8)
1108#define RT5616_JD_MODE_SEL_SFT 8
1109#define RT5616_JD_MODE_SEL_M0 (0x0 << 8)
1110#define RT5616_JD_MODE_SEL_M1 (0x1 << 8)
1111#define RT5616_JD_MODE_SEL_M2 (0x2 << 8)
1112#define RT5616_JD_M_CMP (0x7 << 4)
1113#define RT5616_JD_M_CMP_SFT 4
1114#define RT5616_JD_M_PU (0x1 << 3)
1115#define RT5616_JD_M_PU_SFT 3
1116#define RT5616_JD_M_PD (0x1 << 2)
1117#define RT5616_JD_M_PD_SFT 2
1118#define RT5616_JD_M_MODE_SEL_MASK (0x3)
1119#define RT5616_JD_M_MODE_SEL_SFT 0
1120#define RT5616_JD_M_MODE_SEL_M0 (0x0)
1121#define RT5616_JD_M_MODE_SEL_M1 (0x1)
1122#define RT5616_JD_M_MODE_SEL_M2 (0x2)
1123
1124/* Analog JD Control 2 (0x95) */
1125#define RT5616_JD3_CMP_MASK (0x7 << 12)
1126#define RT5616_JD3_CMP_SFT 12
1127
1128/* EQ Control 1 (0xb0) */
1129#define RT5616_EQ_SRC_MASK (0x1 << 15)
1130#define RT5616_EQ_SRC_SFT 15
1131#define RT5616_EQ_SRC_DAC (0x0 << 15)
1132#define RT5616_EQ_SRC_ADC (0x1 << 15)
1133#define RT5616_EQ_UPD (0x1 << 14)
1134#define RT5616_EQ_UPD_BIT 14
1135#define RT5616_EQ_CD_MASK (0x1 << 13)
1136#define RT5616_EQ_CD_SFT 13
1137#define RT5616_EQ_CD_DIS (0x0 << 13)
1138#define RT5616_EQ_CD_EN (0x1 << 13)
1139#define RT5616_EQ_DITH_MASK (0x3 << 8)
1140#define RT5616_EQ_DITH_SFT 8
1141#define RT5616_EQ_DITH_NOR (0x0 << 8)
1142#define RT5616_EQ_DITH_LSB (0x1 << 8)
1143#define RT5616_EQ_DITH_LSB_1 (0x2 << 8)
1144#define RT5616_EQ_DITH_LSB_2 (0x3 << 8)
1145#define RT5616_EQ_CD_F (0x1 << 7)
1146#define RT5616_EQ_CD_F_BIT 7
1147#define RT5616_EQ_STA_HP2 (0x1 << 6)
1148#define RT5616_EQ_STA_HP2_BIT 6
1149#define RT5616_EQ_STA_HP1 (0x1 << 5)
1150#define RT5616_EQ_STA_HP1_BIT 5
1151#define RT5616_EQ_STA_BP4 (0x1 << 4)
1152#define RT5616_EQ_STA_BP4_BIT 4
1153#define RT5616_EQ_STA_BP3 (0x1 << 3)
1154#define RT5616_EQ_STA_BP3_BIT 3
1155#define RT5616_EQ_STA_BP2 (0x1 << 2)
1156#define RT5616_EQ_STA_BP2_BIT 2
1157#define RT5616_EQ_STA_BP1 (0x1 << 1)
1158#define RT5616_EQ_STA_BP1_BIT 1
1159#define RT5616_EQ_STA_LP (0x1)
1160#define RT5616_EQ_STA_LP_BIT 0
1161
1162/* EQ Control 2 (0xb1) */
1163#define RT5616_EQ_HPF1_M_MASK (0x1 << 8)
1164#define RT5616_EQ_HPF1_M_SFT 8
1165#define RT5616_EQ_HPF1_M_HI (0x0 << 8)
1166#define RT5616_EQ_HPF1_M_1ST (0x1 << 8)
1167#define RT5616_EQ_LPF1_M_MASK (0x1 << 7)
1168#define RT5616_EQ_LPF1_M_SFT 7
1169#define RT5616_EQ_LPF1_M_LO (0x0 << 7)
1170#define RT5616_EQ_LPF1_M_1ST (0x1 << 7)
1171#define RT5616_EQ_HPF2_MASK (0x1 << 6)
1172#define RT5616_EQ_HPF2_SFT 6
1173#define RT5616_EQ_HPF2_DIS (0x0 << 6)
1174#define RT5616_EQ_HPF2_EN (0x1 << 6)
1175#define RT5616_EQ_HPF1_MASK (0x1 << 5)
1176#define RT5616_EQ_HPF1_SFT 5
1177#define RT5616_EQ_HPF1_DIS (0x0 << 5)
1178#define RT5616_EQ_HPF1_EN (0x1 << 5)
1179#define RT5616_EQ_BPF4_MASK (0x1 << 4)
1180#define RT5616_EQ_BPF4_SFT 4
1181#define RT5616_EQ_BPF4_DIS (0x0 << 4)
1182#define RT5616_EQ_BPF4_EN (0x1 << 4)
1183#define RT5616_EQ_BPF3_MASK (0x1 << 3)
1184#define RT5616_EQ_BPF3_SFT 3
1185#define RT5616_EQ_BPF3_DIS (0x0 << 3)
1186#define RT5616_EQ_BPF3_EN (0x1 << 3)
1187#define RT5616_EQ_BPF2_MASK (0x1 << 2)
1188#define RT5616_EQ_BPF2_SFT 2
1189#define RT5616_EQ_BPF2_DIS (0x0 << 2)
1190#define RT5616_EQ_BPF2_EN (0x1 << 2)
1191#define RT5616_EQ_BPF1_MASK (0x1 << 1)
1192#define RT5616_EQ_BPF1_SFT 1
1193#define RT5616_EQ_BPF1_DIS (0x0 << 1)
1194#define RT5616_EQ_BPF1_EN (0x1 << 1)
1195#define RT5616_EQ_LPF_MASK (0x1)
1196#define RT5616_EQ_LPF_SFT 0
1197#define RT5616_EQ_LPF_DIS (0x0)
1198#define RT5616_EQ_LPF_EN (0x1)
1199#define RT5616_EQ_CTRL_MASK (0x7f)
1200
1201/* Memory Test (0xb2) */
1202#define RT5616_MT_MASK (0x1 << 15)
1203#define RT5616_MT_SFT 15
1204#define RT5616_MT_DIS (0x0 << 15)
1205#define RT5616_MT_EN (0x1 << 15)
1206
1207/* DRC/AGC Control 1 (0xb4) */
1208#define RT5616_DRC_AGC_P_MASK (0x1 << 15)
1209#define RT5616_DRC_AGC_P_SFT 15
1210#define RT5616_DRC_AGC_P_DAC (0x0 << 15)
1211#define RT5616_DRC_AGC_P_ADC (0x1 << 15)
1212#define RT5616_DRC_AGC_MASK (0x1 << 14)
1213#define RT5616_DRC_AGC_SFT 14
1214#define RT5616_DRC_AGC_DIS (0x0 << 14)
1215#define RT5616_DRC_AGC_EN (0x1 << 14)
1216#define RT5616_DRC_AGC_UPD (0x1 << 13)
1217#define RT5616_DRC_AGC_UPD_BIT 13
1218#define RT5616_DRC_AGC_AR_MASK (0x1f << 8)
1219#define RT5616_DRC_AGC_AR_SFT 8
1220#define RT5616_DRC_AGC_R_MASK (0x7 << 5)
1221#define RT5616_DRC_AGC_R_SFT 5
1222#define RT5616_DRC_AGC_R_48K (0x1 << 5)
1223#define RT5616_DRC_AGC_R_96K (0x2 << 5)
1224#define RT5616_DRC_AGC_R_192K (0x3 << 5)
1225#define RT5616_DRC_AGC_R_441K (0x5 << 5)
1226#define RT5616_DRC_AGC_R_882K (0x6 << 5)
1227#define RT5616_DRC_AGC_R_1764K (0x7 << 5)
1228#define RT5616_DRC_AGC_RC_MASK (0x1f)
1229#define RT5616_DRC_AGC_RC_SFT 0
1230
1231/* DRC/AGC Control 2 (0xb5) */
1232#define RT5616_DRC_AGC_POB_MASK (0x3f << 8)
1233#define RT5616_DRC_AGC_POB_SFT 8
1234#define RT5616_DRC_AGC_CP_MASK (0x1 << 7)
1235#define RT5616_DRC_AGC_CP_SFT 7
1236#define RT5616_DRC_AGC_CP_DIS (0x0 << 7)
1237#define RT5616_DRC_AGC_CP_EN (0x1 << 7)
1238#define RT5616_DRC_AGC_CPR_MASK (0x3 << 5)
1239#define RT5616_DRC_AGC_CPR_SFT 5
1240#define RT5616_DRC_AGC_CPR_1_1 (0x0 << 5)
1241#define RT5616_DRC_AGC_CPR_1_2 (0x1 << 5)
1242#define RT5616_DRC_AGC_CPR_1_3 (0x2 << 5)
1243#define RT5616_DRC_AGC_CPR_1_4 (0x3 << 5)
1244#define RT5616_DRC_AGC_PRB_MASK (0x1f)
1245#define RT5616_DRC_AGC_PRB_SFT 0
1246
1247/* DRC/AGC Control 3 (0xb6) */
1248#define RT5616_DRC_AGC_NGB_MASK (0xf << 12)
1249#define RT5616_DRC_AGC_NGB_SFT 12
1250#define RT5616_DRC_AGC_TAR_MASK (0x1f << 7)
1251#define RT5616_DRC_AGC_TAR_SFT 7
1252#define RT5616_DRC_AGC_NG_MASK (0x1 << 6)
1253#define RT5616_DRC_AGC_NG_SFT 6
1254#define RT5616_DRC_AGC_NG_DIS (0x0 << 6)
1255#define RT5616_DRC_AGC_NG_EN (0x1 << 6)
1256#define RT5616_DRC_AGC_NGH_MASK (0x1 << 5)
1257#define RT5616_DRC_AGC_NGH_SFT 5
1258#define RT5616_DRC_AGC_NGH_DIS (0x0 << 5)
1259#define RT5616_DRC_AGC_NGH_EN (0x1 << 5)
1260#define RT5616_DRC_AGC_NGT_MASK (0x1f)
1261#define RT5616_DRC_AGC_NGT_SFT 0
1262
1263/* Jack Detect Control 1 (0xbb) */
1264#define RT5616_JD_MASK (0x7 << 13)
1265#define RT5616_JD_SFT 13
1266#define RT5616_JD_DIS (0x0 << 13)
1267#define RT5616_JD_GPIO1 (0x1 << 13)
1268#define RT5616_JD_GPIO2 (0x2 << 13)
1269#define RT5616_JD_GPIO3 (0x3 << 13)
1270#define RT5616_JD_GPIO4 (0x4 << 13)
1271#define RT5616_JD_GPIO5 (0x5 << 13)
1272#define RT5616_JD_GPIO6 (0x6 << 13)
1273#define RT5616_JD_HP_MASK (0x1 << 11)
1274#define RT5616_JD_HP_SFT 11
1275#define RT5616_JD_HP_DIS (0x0 << 11)
1276#define RT5616_JD_HP_EN (0x1 << 11)
1277#define RT5616_JD_HP_TRG_MASK (0x1 << 10)
1278#define RT5616_JD_HP_TRG_SFT 10
1279#define RT5616_JD_HP_TRG_LO (0x0 << 10)
1280#define RT5616_JD_HP_TRG_HI (0x1 << 10)
1281#define RT5616_JD_SPL_MASK (0x1 << 9)
1282#define RT5616_JD_SPL_SFT 9
1283#define RT5616_JD_SPL_DIS (0x0 << 9)
1284#define RT5616_JD_SPL_EN (0x1 << 9)
1285#define RT5616_JD_SPL_TRG_MASK (0x1 << 8)
1286#define RT5616_JD_SPL_TRG_SFT 8
1287#define RT5616_JD_SPL_TRG_LO (0x0 << 8)
1288#define RT5616_JD_SPL_TRG_HI (0x1 << 8)
1289#define RT5616_JD_SPR_MASK (0x1 << 7)
1290#define RT5616_JD_SPR_SFT 7
1291#define RT5616_JD_SPR_DIS (0x0 << 7)
1292#define RT5616_JD_SPR_EN (0x1 << 7)
1293#define RT5616_JD_SPR_TRG_MASK (0x1 << 6)
1294#define RT5616_JD_SPR_TRG_SFT 6
1295#define RT5616_JD_SPR_TRG_LO (0x0 << 6)
1296#define RT5616_JD_SPR_TRG_HI (0x1 << 6)
1297#define RT5616_JD_LO_MASK (0x1 << 3)
1298#define RT5616_JD_LO_SFT 3
1299#define RT5616_JD_LO_DIS (0x0 << 3)
1300#define RT5616_JD_LO_EN (0x1 << 3)
1301#define RT5616_JD_LO_TRG_MASK (0x1 << 2)
1302#define RT5616_JD_LO_TRG_SFT 2
1303#define RT5616_JD_LO_TRG_LO (0x0 << 2)
1304#define RT5616_JD_LO_TRG_HI (0x1 << 2)
1305
1306/* Jack Detect Control 2 (0xbc) */
1307#define RT5616_JD_TRG_SEL_MASK (0x7 << 9)
1308#define RT5616_JD_TRG_SEL_SFT 9
1309#define RT5616_JD_TRG_SEL_GPIO (0x0 << 9)
1310#define RT5616_JD_TRG_SEL_JD1_1 (0x1 << 9)
1311#define RT5616_JD_TRG_SEL_JD1_2 (0x2 << 9)
1312#define RT5616_JD_TRG_SEL_JD2 (0x3 << 9)
1313#define RT5616_JD_TRG_SEL_JD3 (0x4 << 9)
1314#define RT5616_JD3_IRQ_EN (0x1 << 8)
1315#define RT5616_JD3_IRQ_EN_SFT 8
1316#define RT5616_JD3_EN_STKY (0x1 << 7)
1317#define RT5616_JD3_EN_STKY_SFT 7
1318#define RT5616_JD3_INV (0x1 << 6)
1319#define RT5616_JD3_INV_SFT 6
1320
1321/* IRQ Control 1 (0xbd) */
1322#define RT5616_IRQ_JD_MASK (0x1 << 15)
1323#define RT5616_IRQ_JD_SFT 15
1324#define RT5616_IRQ_JD_BP (0x0 << 15)
1325#define RT5616_IRQ_JD_NOR (0x1 << 15)
1326#define RT5616_JD_STKY_MASK (0x1 << 13)
1327#define RT5616_JD_STKY_SFT 13
1328#define RT5616_JD_STKY_DIS (0x0 << 13)
1329#define RT5616_JD_STKY_EN (0x1 << 13)
1330#define RT5616_JD_P_MASK (0x1 << 11)
1331#define RT5616_JD_P_SFT 11
1332#define RT5616_JD_P_NOR (0x0 << 11)
1333#define RT5616_JD_P_INV (0x1 << 11)
1334#define RT5616_JD1_1_IRQ_EN (0x1 << 9)
1335#define RT5616_JD1_1_IRQ_EN_SFT 9
1336#define RT5616_JD1_1_EN_STKY (0x1 << 8)
1337#define RT5616_JD1_1_EN_STKY_SFT 8
1338#define RT5616_JD1_1_INV (0x1 << 7)
1339#define RT5616_JD1_1_INV_SFT 7
1340#define RT5616_JD1_2_IRQ_EN (0x1 << 6)
1341#define RT5616_JD1_2_IRQ_EN_SFT 6
1342#define RT5616_JD1_2_EN_STKY (0x1 << 5)
1343#define RT5616_JD1_2_EN_STKY_SFT 5
1344#define RT5616_JD1_2_INV (0x1 << 4)
1345#define RT5616_JD1_2_INV_SFT 4
1346#define RT5616_JD2_IRQ_EN (0x1 << 3)
1347#define RT5616_JD2_IRQ_EN_SFT 3
1348#define RT5616_JD2_EN_STKY (0x1 << 2)
1349#define RT5616_JD2_EN_STKY_SFT 2
1350#define RT5616_JD2_INV (0x1 << 1)
1351#define RT5616_JD2_INV_SFT 1
1352
1353/* IRQ Control 2 (0xbe) */
1354#define RT5616_IRQ_MB1_OC_MASK (0x1 << 15)
1355#define RT5616_IRQ_MB1_OC_SFT 15
1356#define RT5616_IRQ_MB1_OC_BP (0x0 << 15)
1357#define RT5616_IRQ_MB1_OC_NOR (0x1 << 15)
1358#define RT5616_MB1_OC_STKY_MASK (0x1 << 11)
1359#define RT5616_MB1_OC_STKY_SFT 11
1360#define RT5616_MB1_OC_STKY_DIS (0x0 << 11)
1361#define RT5616_MB1_OC_STKY_EN (0x1 << 11)
1362#define RT5616_MB1_OC_P_MASK (0x1 << 7)
1363#define RT5616_MB1_OC_P_SFT 7
1364#define RT5616_MB1_OC_P_NOR (0x0 << 7)
1365#define RT5616_MB1_OC_P_INV (0x1 << 7)
1366#define RT5616_MB2_OC_P_MASK (0x1 << 6)
1367#define RT5616_MB1_OC_CLR (0x1 << 3)
1368#define RT5616_MB1_OC_CLR_SFT 3
1369#define RT5616_STA_GPIO8 (0x1)
1370#define RT5616_STA_GPIO8_BIT 0
1371
1372/* Internal Status and GPIO status (0xbf) */
1373#define RT5616_STA_JD3 (0x1 << 15)
1374#define RT5616_STA_JD3_BIT 15
1375#define RT5616_STA_JD2 (0x1 << 14)
1376#define RT5616_STA_JD2_BIT 14
1377#define RT5616_STA_JD1_2 (0x1 << 13)
1378#define RT5616_STA_JD1_2_BIT 13
1379#define RT5616_STA_JD1_1 (0x1 << 12)
1380#define RT5616_STA_JD1_1_BIT 12
1381#define RT5616_STA_GP7 (0x1 << 11)
1382#define RT5616_STA_GP7_BIT 11
1383#define RT5616_STA_GP6 (0x1 << 10)
1384#define RT5616_STA_GP6_BIT 10
1385#define RT5616_STA_GP5 (0x1 << 9)
1386#define RT5616_STA_GP5_BIT 9
1387#define RT5616_STA_GP1 (0x1 << 8)
1388#define RT5616_STA_GP1_BIT 8
1389#define RT5616_STA_GP2 (0x1 << 7)
1390#define RT5616_STA_GP2_BIT 7
1391#define RT5616_STA_GP3 (0x1 << 6)
1392#define RT5616_STA_GP3_BIT 6
1393#define RT5616_STA_GP4 (0x1 << 5)
1394#define RT5616_STA_GP4_BIT 5
1395#define RT5616_STA_GP_JD (0x1 << 4)
1396#define RT5616_STA_GP_JD_BIT 4
1397
1398/* GPIO Control 1 (0xc0) */
1399#define RT5616_GP1_PIN_MASK (0x1 << 15)
1400#define RT5616_GP1_PIN_SFT 15
1401#define RT5616_GP1_PIN_GPIO1 (0x0 << 15)
1402#define RT5616_GP1_PIN_IRQ (0x1 << 15)
1403#define RT5616_GP2_PIN_MASK (0x1 << 14)
1404#define RT5616_GP2_PIN_SFT 14
1405#define RT5616_GP2_PIN_GPIO2 (0x0 << 14)
1406#define RT5616_GP2_PIN_DMIC1_SCL (0x1 << 14)
1407#define RT5616_GPIO_M_MASK (0x1 << 9)
1408#define RT5616_GPIO_M_SFT 9
1409#define RT5616_GPIO_M_FLT (0x0 << 9)
1410#define RT5616_GPIO_M_PH (0x1 << 9)
1411#define RT5616_I2S2_SEL_MASK (0x1 << 8)
1412#define RT5616_I2S2_SEL_SFT 8
1413#define RT5616_I2S2_SEL_I2S (0x0 << 8)
1414#define RT5616_I2S2_SEL_GPIO (0x1 << 8)
1415#define RT5616_GP5_PIN_MASK (0x1 << 7)
1416#define RT5616_GP5_PIN_SFT 7
1417#define RT5616_GP5_PIN_GPIO5 (0x0 << 7)
1418#define RT5616_GP5_PIN_IRQ (0x1 << 7)
1419#define RT5616_GP6_PIN_MASK (0x1 << 6)
1420#define RT5616_GP6_PIN_SFT 6
1421#define RT5616_GP6_PIN_GPIO6 (0x0 << 6)
1422#define RT5616_GP6_PIN_DMIC_SDA (0x1 << 6)
1423#define RT5616_GP7_PIN_MASK (0x1 << 5)
1424#define RT5616_GP7_PIN_SFT 5
1425#define RT5616_GP7_PIN_GPIO7 (0x0 << 5)
1426#define RT5616_GP7_PIN_IRQ (0x1 << 5)
1427#define RT5616_GP8_PIN_MASK (0x1 << 4)
1428#define RT5616_GP8_PIN_SFT 4
1429#define RT5616_GP8_PIN_GPIO8 (0x0 << 4)
1430#define RT5616_GP8_PIN_DMIC_SDA (0x1 << 4)
1431#define RT5616_GPIO_PDM_SEL_MASK (0x1 << 3)
1432#define RT5616_GPIO_PDM_SEL_SFT 3
1433#define RT5616_GPIO_PDM_SEL_GPIO (0x0 << 3)
1434#define RT5616_GPIO_PDM_SEL_PDM (0x1 << 3)
1435
1436/* GPIO Control 2 (0xc1) */
1437#define RT5616_GP5_DR_MASK (0x1 << 14)
1438#define RT5616_GP5_DR_SFT 14
1439#define RT5616_GP5_DR_IN (0x0 << 14)
1440#define RT5616_GP5_DR_OUT (0x1 << 14)
1441#define RT5616_GP5_OUT_MASK (0x1 << 13)
1442#define RT5616_GP5_OUT_SFT 13
1443#define RT5616_GP5_OUT_LO (0x0 << 13)
1444#define RT5616_GP5_OUT_HI (0x1 << 13)
1445#define RT5616_GP5_P_MASK (0x1 << 12)
1446#define RT5616_GP5_P_SFT 12
1447#define RT5616_GP5_P_NOR (0x0 << 12)
1448#define RT5616_GP5_P_INV (0x1 << 12)
1449#define RT5616_GP4_DR_MASK (0x1 << 11)
1450#define RT5616_GP4_DR_SFT 11
1451#define RT5616_GP4_DR_IN (0x0 << 11)
1452#define RT5616_GP4_DR_OUT (0x1 << 11)
1453#define RT5616_GP4_OUT_MASK (0x1 << 10)
1454#define RT5616_GP4_OUT_SFT 10
1455#define RT5616_GP4_OUT_LO (0x0 << 10)
1456#define RT5616_GP4_OUT_HI (0x1 << 10)
1457#define RT5616_GP4_P_MASK (0x1 << 9)
1458#define RT5616_GP4_P_SFT 9
1459#define RT5616_GP4_P_NOR (0x0 << 9)
1460#define RT5616_GP4_P_INV (0x1 << 9)
1461#define RT5616_GP3_DR_MASK (0x1 << 8)
1462#define RT5616_GP3_DR_SFT 8
1463#define RT5616_GP3_DR_IN (0x0 << 8)
1464#define RT5616_GP3_DR_OUT (0x1 << 8)
1465#define RT5616_GP3_OUT_MASK (0x1 << 7)
1466#define RT5616_GP3_OUT_SFT 7
1467#define RT5616_GP3_OUT_LO (0x0 << 7)
1468#define RT5616_GP3_OUT_HI (0x1 << 7)
1469#define RT5616_GP3_P_MASK (0x1 << 6)
1470#define RT5616_GP3_P_SFT 6
1471#define RT5616_GP3_P_NOR (0x0 << 6)
1472#define RT5616_GP3_P_INV (0x1 << 6)
1473#define RT5616_GP2_DR_MASK (0x1 << 5)
1474#define RT5616_GP2_DR_SFT 5
1475#define RT5616_GP2_DR_IN (0x0 << 5)
1476#define RT5616_GP2_DR_OUT (0x1 << 5)
1477#define RT5616_GP2_OUT_MASK (0x1 << 4)
1478#define RT5616_GP2_OUT_SFT 4
1479#define RT5616_GP2_OUT_LO (0x0 << 4)
1480#define RT5616_GP2_OUT_HI (0x1 << 4)
1481#define RT5616_GP2_P_MASK (0x1 << 3)
1482#define RT5616_GP2_P_SFT 3
1483#define RT5616_GP2_P_NOR (0x0 << 3)
1484#define RT5616_GP2_P_INV (0x1 << 3)
1485#define RT5616_GP1_DR_MASK (0x1 << 2)
1486#define RT5616_GP1_DR_SFT 2
1487#define RT5616_GP1_DR_IN (0x0 << 2)
1488#define RT5616_GP1_DR_OUT (0x1 << 2)
1489#define RT5616_GP1_OUT_MASK (0x1 << 1)
1490#define RT5616_GP1_OUT_SFT 1
1491#define RT5616_GP1_OUT_LO (0x0 << 1)
1492#define RT5616_GP1_OUT_HI (0x1 << 1)
1493#define RT5616_GP1_P_MASK (0x1)
1494#define RT5616_GP1_P_SFT 0
1495#define RT5616_GP1_P_NOR (0x0)
1496#define RT5616_GP1_P_INV (0x1)
1497
1498/* GPIO Control 3 (0xc2) */
1499#define RT5616_GP8_DR_MASK (0x1 << 8)
1500#define RT5616_GP8_DR_SFT 8
1501#define RT5616_GP8_DR_IN (0x0 << 8)
1502#define RT5616_GP8_DR_OUT (0x1 << 8)
1503#define RT5616_GP8_OUT_MASK (0x1 << 7)
1504#define RT5616_GP8_OUT_SFT 7
1505#define RT5616_GP8_OUT_LO (0x0 << 7)
1506#define RT5616_GP8_OUT_HI (0x1 << 7)
1507#define RT5616_GP8_P_MASK (0x1 << 6)
1508#define RT5616_GP8_P_SFT 6
1509#define RT5616_GP8_P_NOR (0x0 << 6)
1510#define RT5616_GP8_P_INV (0x1 << 6)
1511#define RT5616_GP7_DR_MASK (0x1 << 5)
1512#define RT5616_GP7_DR_SFT 5
1513#define RT5616_GP7_DR_IN (0x0 << 5)
1514#define RT5616_GP7_DR_OUT (0x1 << 5)
1515#define RT5616_GP7_OUT_MASK (0x1 << 4)
1516#define RT5616_GP7_OUT_SFT 4
1517#define RT5616_GP7_OUT_LO (0x0 << 4)
1518#define RT5616_GP7_OUT_HI (0x1 << 4)
1519#define RT5616_GP7_P_MASK (0x1 << 3)
1520#define RT5616_GP7_P_SFT 3
1521#define RT5616_GP7_P_NOR (0x0 << 3)
1522#define RT5616_GP7_P_INV (0x1 << 3)
1523#define RT5616_GP6_DR_MASK (0x1 << 2)
1524#define RT5616_GP6_DR_SFT 2
1525#define RT5616_GP6_DR_IN (0x0 << 2)
1526#define RT5616_GP6_DR_OUT (0x1 << 2)
1527#define RT5616_GP6_OUT_MASK (0x1 << 1)
1528#define RT5616_GP6_OUT_SFT 1
1529#define RT5616_GP6_OUT_LO (0x0 << 1)
1530#define RT5616_GP6_OUT_HI (0x1 << 1)
1531#define RT5616_GP6_P_MASK (0x1)
1532#define RT5616_GP6_P_SFT 0
1533#define RT5616_GP6_P_NOR (0x0)
1534#define RT5616_GP6_P_INV (0x1)
1535
1536/* Scramble Control (0xce) */
1537#define RT5616_SCB_SWAP_MASK (0x1 << 15)
1538#define RT5616_SCB_SWAP_SFT 15
1539#define RT5616_SCB_SWAP_DIS (0x0 << 15)
1540#define RT5616_SCB_SWAP_EN (0x1 << 15)
1541#define RT5616_SCB_MASK (0x1 << 14)
1542#define RT5616_SCB_SFT 14
1543#define RT5616_SCB_DIS (0x0 << 14)
1544#define RT5616_SCB_EN (0x1 << 14)
1545
1546/* Baseback Control (0xcf) */
1547#define RT5616_BB_MASK (0x1 << 15)
1548#define RT5616_BB_SFT 15
1549#define RT5616_BB_DIS (0x0 << 15)
1550#define RT5616_BB_EN (0x1 << 15)
1551#define RT5616_BB_CT_MASK (0x7 << 12)
1552#define RT5616_BB_CT_SFT 12
1553#define RT5616_BB_CT_A (0x0 << 12)
1554#define RT5616_BB_CT_B (0x1 << 12)
1555#define RT5616_BB_CT_C (0x2 << 12)
1556#define RT5616_BB_CT_D (0x3 << 12)
1557#define RT5616_M_BB_L_MASK (0x1 << 9)
1558#define RT5616_M_BB_L_SFT 9
1559#define RT5616_M_BB_R_MASK (0x1 << 8)
1560#define RT5616_M_BB_R_SFT 8
1561#define RT5616_M_BB_HPF_L_MASK (0x1 << 7)
1562#define RT5616_M_BB_HPF_L_SFT 7
1563#define RT5616_M_BB_HPF_R_MASK (0x1 << 6)
1564#define RT5616_M_BB_HPF_R_SFT 6
1565#define RT5616_G_BB_BST_MASK (0x3f)
1566#define RT5616_G_BB_BST_SFT 0
1567
1568/* MP3 Plus Control 1 (0xd0) */
1569#define RT5616_M_MP3_L_MASK (0x1 << 15)
1570#define RT5616_M_MP3_L_SFT 15
1571#define RT5616_M_MP3_R_MASK (0x1 << 14)
1572#define RT5616_M_MP3_R_SFT 14
1573#define RT5616_M_MP3_MASK (0x1 << 13)
1574#define RT5616_M_MP3_SFT 13
1575#define RT5616_M_MP3_DIS (0x0 << 13)
1576#define RT5616_M_MP3_EN (0x1 << 13)
1577#define RT5616_EG_MP3_MASK (0x1f << 8)
1578#define RT5616_EG_MP3_SFT 8
1579#define RT5616_MP3_HLP_MASK (0x1 << 7)
1580#define RT5616_MP3_HLP_SFT 7
1581#define RT5616_MP3_HLP_DIS (0x0 << 7)
1582#define RT5616_MP3_HLP_EN (0x1 << 7)
1583#define RT5616_M_MP3_ORG_L_MASK (0x1 << 6)
1584#define RT5616_M_MP3_ORG_L_SFT 6
1585#define RT5616_M_MP3_ORG_R_MASK (0x1 << 5)
1586#define RT5616_M_MP3_ORG_R_SFT 5
1587
1588/* MP3 Plus Control 2 (0xd1) */
1589#define RT5616_MP3_WT_MASK (0x1 << 13)
1590#define RT5616_MP3_WT_SFT 13
1591#define RT5616_MP3_WT_1_4 (0x0 << 13)
1592#define RT5616_MP3_WT_1_2 (0x1 << 13)
1593#define RT5616_OG_MP3_MASK (0x1f << 8)
1594#define RT5616_OG_MP3_SFT 8
1595#define RT5616_HG_MP3_MASK (0x3f)
1596#define RT5616_HG_MP3_SFT 0
1597
1598/* 3D HP Control 1 (0xd2) */
1599#define RT5616_3D_CF_MASK (0x1 << 15)
1600#define RT5616_3D_CF_SFT 15
1601#define RT5616_3D_CF_DIS (0x0 << 15)
1602#define RT5616_3D_CF_EN (0x1 << 15)
1603#define RT5616_3D_HP_MASK (0x1 << 14)
1604#define RT5616_3D_HP_SFT 14
1605#define RT5616_3D_HP_DIS (0x0 << 14)
1606#define RT5616_3D_HP_EN (0x1 << 14)
1607#define RT5616_3D_BT_MASK (0x1 << 13)
1608#define RT5616_3D_BT_SFT 13
1609#define RT5616_3D_BT_DIS (0x0 << 13)
1610#define RT5616_3D_BT_EN (0x1 << 13)
1611#define RT5616_3D_1F_MIX_MASK (0x3 << 11)
1612#define RT5616_3D_1F_MIX_SFT 11
1613#define RT5616_3D_HP_M_MASK (0x1 << 10)
1614#define RT5616_3D_HP_M_SFT 10
1615#define RT5616_3D_HP_M_SUR (0x0 << 10)
1616#define RT5616_3D_HP_M_FRO (0x1 << 10)
1617#define RT5616_M_3D_HRTF_MASK (0x1 << 9)
1618#define RT5616_M_3D_HRTF_SFT 9
1619#define RT5616_M_3D_D2H_MASK (0x1 << 8)
1620#define RT5616_M_3D_D2H_SFT 8
1621#define RT5616_M_3D_D2R_MASK (0x1 << 7)
1622#define RT5616_M_3D_D2R_SFT 7
1623#define RT5616_M_3D_REVB_MASK (0x1 << 6)
1624#define RT5616_M_3D_REVB_SFT 6
1625
1626/* Adjustable high pass filter control 1 (0xd3) */
1627#define RT5616_2ND_HPF_MASK (0x1 << 15)
1628#define RT5616_2ND_HPF_SFT 15
1629#define RT5616_2ND_HPF_DIS (0x0 << 15)
1630#define RT5616_2ND_HPF_EN (0x1 << 15)
1631#define RT5616_HPF_CF_L_MASK (0x7 << 12)
1632#define RT5616_HPF_CF_L_SFT 12
1633#define RT5616_HPF_CF_R_MASK (0x7 << 8)
1634#define RT5616_HPF_CF_R_SFT 8
1635#define RT5616_ZD_T_MASK (0x3 << 6)
1636#define RT5616_ZD_T_SFT 6
1637#define RT5616_ZD_F_MASK (0x3 << 4)
1638#define RT5616_ZD_F_SFT 4
1639#define RT5616_ZD_F_IM (0x0 << 4)
1640#define RT5616_ZD_F_ZC_IM (0x1 << 4)
1641#define RT5616_ZD_F_ZC_IOD (0x2 << 4)
1642#define RT5616_ZD_F_UN (0x3 << 4)
1643
1644/* Adjustable high pass filter control 2 (0xd4) */
1645#define RT5616_HPF_CF_L_NUM_MASK (0x3f << 8)
1646#define RT5616_HPF_CF_L_NUM_SFT 8
1647#define RT5616_HPF_CF_R_NUM_MASK (0x3f)
1648#define RT5616_HPF_CF_R_NUM_SFT 0
1649
1650/* HP calibration control and Amp detection (0xd6) */
1651#define RT5616_SI_DAC_MASK (0x1 << 11)
1652#define RT5616_SI_DAC_SFT 11
1653#define RT5616_SI_DAC_AUTO (0x0 << 11)
1654#define RT5616_SI_DAC_TEST (0x1 << 11)
1655#define RT5616_DC_CAL_M_MASK (0x1 << 10)
1656#define RT5616_DC_CAL_M_SFT 10
1657#define RT5616_DC_CAL_M_NOR (0x0 << 10)
1658#define RT5616_DC_CAL_M_CAL (0x1 << 10)
1659#define RT5616_DC_CAL_MASK (0x1 << 9)
1660#define RT5616_DC_CAL_SFT 9
1661#define RT5616_DC_CAL_DIS (0x0 << 9)
1662#define RT5616_DC_CAL_EN (0x1 << 9)
1663#define RT5616_HPD_RCV_MASK (0x7 << 6)
1664#define RT5616_HPD_RCV_SFT 6
1665#define RT5616_HPD_PS_MASK (0x1 << 5)
1666#define RT5616_HPD_PS_SFT 5
1667#define RT5616_HPD_PS_DIS (0x0 << 5)
1668#define RT5616_HPD_PS_EN (0x1 << 5)
1669#define RT5616_CAL_M_MASK (0x1 << 4)
1670#define RT5616_CAL_M_SFT 4
1671#define RT5616_CAL_M_DEP (0x0 << 4)
1672#define RT5616_CAL_M_CAL (0x1 << 4)
1673#define RT5616_CAL_MASK (0x1 << 3)
1674#define RT5616_CAL_SFT 3
1675#define RT5616_CAL_DIS (0x0 << 3)
1676#define RT5616_CAL_EN (0x1 << 3)
1677#define RT5616_CAL_TEST_MASK (0x1 << 2)
1678#define RT5616_CAL_TEST_SFT 2
1679#define RT5616_CAL_TEST_DIS (0x0 << 2)
1680#define RT5616_CAL_TEST_EN (0x1 << 2)
1681#define RT5616_CAL_P_MASK (0x3)
1682#define RT5616_CAL_P_SFT 0
1683#define RT5616_CAL_P_NONE (0x0)
1684#define RT5616_CAL_P_CAL (0x1)
1685#define RT5616_CAL_P_DAC_CAL (0x2)
1686
1687/* Soft volume and zero cross control 1 (0xd9) */
1688#define RT5616_SV_MASK (0x1 << 15)
1689#define RT5616_SV_SFT 15
1690#define RT5616_SV_DIS (0x0 << 15)
1691#define RT5616_SV_EN (0x1 << 15)
1692#define RT5616_OUT_SV_MASK (0x1 << 13)
1693#define RT5616_OUT_SV_SFT 13
1694#define RT5616_OUT_SV_DIS (0x0 << 13)
1695#define RT5616_OUT_SV_EN (0x1 << 13)
1696#define RT5616_HP_SV_MASK (0x1 << 12)
1697#define RT5616_HP_SV_SFT 12
1698#define RT5616_HP_SV_DIS (0x0 << 12)
1699#define RT5616_HP_SV_EN (0x1 << 12)
1700#define RT5616_ZCD_DIG_MASK (0x1 << 11)
1701#define RT5616_ZCD_DIG_SFT 11
1702#define RT5616_ZCD_DIG_DIS (0x0 << 11)
1703#define RT5616_ZCD_DIG_EN (0x1 << 11)
1704#define RT5616_ZCD_MASK (0x1 << 10)
1705#define RT5616_ZCD_SFT 10
1706#define RT5616_ZCD_PD (0x0 << 10)
1707#define RT5616_ZCD_PU (0x1 << 10)
1708#define RT5616_M_ZCD_MASK (0x3f << 4)
1709#define RT5616_M_ZCD_SFT 4
1710#define RT5616_M_ZCD_OM_L (0x1 << 7)
1711#define RT5616_M_ZCD_OM_R (0x1 << 6)
1712#define RT5616_M_ZCD_RM_L (0x1 << 5)
1713#define RT5616_M_ZCD_RM_R (0x1 << 4)
1714#define RT5616_SV_DLY_MASK (0xf)
1715#define RT5616_SV_DLY_SFT 0
1716
1717/* Soft volume and zero cross control 2 (0xda) */
1718#define RT5616_ZCD_HP_MASK (0x1 << 15)
1719#define RT5616_ZCD_HP_SFT 15
1720#define RT5616_ZCD_HP_DIS (0x0 << 15)
1721#define RT5616_ZCD_HP_EN (0x1 << 15)
1722
1723/* Digital Misc Control (0xfa) */
1724#define RT5616_I2S2_MS_SP_MASK (0x1 << 8)
1725#define RT5616_I2S2_MS_SP_SEL 8
1726#define RT5616_I2S2_MS_SP_64 (0x0 << 8)
1727#define RT5616_I2S2_MS_SP_50 (0x1 << 8)
1728#define RT5616_CLK_DET_EN (0x1 << 3)
1729#define RT5616_CLK_DET_EN_SFT 3
1730#define RT5616_AMP_DET_EN (0x1 << 1)
1731#define RT5616_AMP_DET_EN_SFT 1
1732#define RT5616_D_GATE_EN (0x1)
1733#define RT5616_D_GATE_EN_SFT 0
1734
1735/* Codec Private Register definition */
1736/* 3D Speaker Control (0x63) */
1737#define RT5616_3D_SPK_MASK (0x1 << 15)
1738#define RT5616_3D_SPK_SFT 15
1739#define RT5616_3D_SPK_DIS (0x0 << 15)
1740#define RT5616_3D_SPK_EN (0x1 << 15)
1741#define RT5616_3D_SPK_M_MASK (0x3 << 13)
1742#define RT5616_3D_SPK_M_SFT 13
1743#define RT5616_3D_SPK_CG_MASK (0x1f << 8)
1744#define RT5616_3D_SPK_CG_SFT 8
1745#define RT5616_3D_SPK_SG_MASK (0x1f)
1746#define RT5616_3D_SPK_SG_SFT 0
1747
1748/* Wind Noise Detection Control 1 (0x6c) */
1749#define RT5616_WND_MASK (0x1 << 15)
1750#define RT5616_WND_SFT 15
1751#define RT5616_WND_DIS (0x0 << 15)
1752#define RT5616_WND_EN (0x1 << 15)
1753
1754/* Wind Noise Detection Control 2 (0x6d) */
1755#define RT5616_WND_FC_NW_MASK (0x3f << 10)
1756#define RT5616_WND_FC_NW_SFT 10
1757#define RT5616_WND_FC_WK_MASK (0x3f << 4)
1758#define RT5616_WND_FC_WK_SFT 4
1759
1760/* Wind Noise Detection Control 3 (0x6e) */
1761#define RT5616_HPF_FC_MASK (0x3f << 6)
1762#define RT5616_HPF_FC_SFT 6
1763#define RT5616_WND_FC_ST_MASK (0x3f)
1764#define RT5616_WND_FC_ST_SFT 0
1765
1766/* Wind Noise Detection Control 4 (0x6f) */
1767#define RT5616_WND_TH_LO_MASK (0x3ff)
1768#define RT5616_WND_TH_LO_SFT 0
1769
1770/* Wind Noise Detection Control 5 (0x70) */
1771#define RT5616_WND_TH_HI_MASK (0x3ff)
1772#define RT5616_WND_TH_HI_SFT 0
1773
1774/* Wind Noise Detection Control 8 (0x73) */
1775#define RT5616_WND_WIND_MASK (0x1 << 13) /* Read-Only */
1776#define RT5616_WND_WIND_SFT 13
1777#define RT5616_WND_STRONG_MASK (0x1 << 12) /* Read-Only */
1778#define RT5616_WND_STRONG_SFT 12
1779enum {
1780 RT5616_NO_WIND,
1781 RT5616_BREEZE,
1782 RT5616_STORM,
1783};
1784
1785/* Dipole Speaker Interface (0x75) */
1786#define RT5616_DP_ATT_MASK (0x3 << 14)
1787#define RT5616_DP_ATT_SFT 14
1788#define RT5616_DP_SPK_MASK (0x1 << 10)
1789#define RT5616_DP_SPK_SFT 10
1790#define RT5616_DP_SPK_DIS (0x0 << 10)
1791#define RT5616_DP_SPK_EN (0x1 << 10)
1792
1793/* EQ Pre Volume Control (0xb3) */
1794#define RT5616_EQ_PRE_VOL_MASK (0xffff)
1795#define RT5616_EQ_PRE_VOL_SFT 0
1796
1797/* EQ Post Volume Control (0xb4) */
1798#define RT5616_EQ_PST_VOL_MASK (0xffff)
1799#define RT5616_EQ_PST_VOL_SFT 0
1800
1801/* System Clock Source */
1802enum {
1803 RT5616_SCLK_S_MCLK,
1804 RT5616_SCLK_S_PLL1,
1805};
1806
1807/* PLL1 Source */
1808enum {
1809 RT5616_PLL1_S_MCLK,
1810 RT5616_PLL1_S_BCLK1,
1811 RT5616_PLL1_S_BCLK2,
1812};
1813
1814enum {
1815 RT5616_AIF1,
1816 RT5616_AIFS,
1817};
1818
1819#endif /* __RT5616_H__ */
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index ef76940f9dcb..3e8d66661b7e 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -226,6 +226,163 @@ static const struct reg_default rt5645_reg[] = {
226 { 0xff, 0x6308 }, 226 { 0xff, 0x6308 },
227}; 227};
228 228
229static const struct reg_default rt5650_reg[] = {
230 { 0x00, 0x0000 },
231 { 0x01, 0xc8c8 },
232 { 0x02, 0xc8c8 },
233 { 0x03, 0xc8c8 },
234 { 0x0a, 0x0002 },
235 { 0x0b, 0x2827 },
236 { 0x0c, 0xe000 },
237 { 0x0d, 0x0000 },
238 { 0x0e, 0x0000 },
239 { 0x0f, 0x0808 },
240 { 0x14, 0x3333 },
241 { 0x16, 0x4b00 },
242 { 0x18, 0x018b },
243 { 0x19, 0xafaf },
244 { 0x1a, 0xafaf },
245 { 0x1b, 0x0001 },
246 { 0x1c, 0x2f2f },
247 { 0x1d, 0x2f2f },
248 { 0x1e, 0x0000 },
249 { 0x20, 0x0000 },
250 { 0x27, 0x7060 },
251 { 0x28, 0x7070 },
252 { 0x29, 0x8080 },
253 { 0x2a, 0x5656 },
254 { 0x2b, 0x5454 },
255 { 0x2c, 0xaaa0 },
256 { 0x2d, 0x0000 },
257 { 0x2f, 0x1002 },
258 { 0x31, 0x5000 },
259 { 0x32, 0x0000 },
260 { 0x33, 0x0000 },
261 { 0x34, 0x0000 },
262 { 0x35, 0x0000 },
263 { 0x3b, 0x0000 },
264 { 0x3c, 0x007f },
265 { 0x3d, 0x0000 },
266 { 0x3e, 0x007f },
267 { 0x3f, 0x0000 },
268 { 0x40, 0x001f },
269 { 0x41, 0x0000 },
270 { 0x42, 0x001f },
271 { 0x45, 0x6000 },
272 { 0x46, 0x003e },
273 { 0x47, 0x003e },
274 { 0x48, 0xf807 },
275 { 0x4a, 0x0004 },
276 { 0x4d, 0x0000 },
277 { 0x4e, 0x0000 },
278 { 0x4f, 0x01ff },
279 { 0x50, 0x0000 },
280 { 0x51, 0x0000 },
281 { 0x52, 0x01ff },
282 { 0x53, 0xf000 },
283 { 0x56, 0x0111 },
284 { 0x57, 0x0064 },
285 { 0x58, 0xef0e },
286 { 0x59, 0xf0f0 },
287 { 0x5a, 0xef0e },
288 { 0x5b, 0xf0f0 },
289 { 0x5c, 0xef0e },
290 { 0x5d, 0xf0f0 },
291 { 0x5e, 0xf000 },
292 { 0x5f, 0x0000 },
293 { 0x61, 0x0300 },
294 { 0x62, 0x0000 },
295 { 0x63, 0x00c2 },
296 { 0x64, 0x0000 },
297 { 0x65, 0x0000 },
298 { 0x66, 0x0000 },
299 { 0x6a, 0x0000 },
300 { 0x6c, 0x0aaa },
301 { 0x70, 0x8000 },
302 { 0x71, 0x8000 },
303 { 0x72, 0x8000 },
304 { 0x73, 0x7770 },
305 { 0x74, 0x3e00 },
306 { 0x75, 0x2409 },
307 { 0x76, 0x000a },
308 { 0x77, 0x0c00 },
309 { 0x78, 0x0000 },
310 { 0x79, 0x0123 },
311 { 0x7a, 0x0123 },
312 { 0x80, 0x0000 },
313 { 0x81, 0x0000 },
314 { 0x82, 0x0000 },
315 { 0x83, 0x0000 },
316 { 0x84, 0x0000 },
317 { 0x85, 0x0000 },
318 { 0x8a, 0x0000 },
319 { 0x8e, 0x0004 },
320 { 0x8f, 0x1100 },
321 { 0x90, 0x0646 },
322 { 0x91, 0x0c06 },
323 { 0x93, 0x0000 },
324 { 0x94, 0x0200 },
325 { 0x95, 0x0000 },
326 { 0x9a, 0x2184 },
327 { 0x9b, 0x010a },
328 { 0x9c, 0x0aea },
329 { 0x9d, 0x000c },
330 { 0x9e, 0x0400 },
331 { 0xa0, 0xa0a8 },
332 { 0xa1, 0x0059 },
333 { 0xa2, 0x0001 },
334 { 0xae, 0x6000 },
335 { 0xaf, 0x0000 },
336 { 0xb0, 0x6000 },
337 { 0xb1, 0x0000 },
338 { 0xb2, 0x0000 },
339 { 0xb3, 0x001f },
340 { 0xb4, 0x020c },
341 { 0xb5, 0x1f00 },
342 { 0xb6, 0x0000 },
343 { 0xbb, 0x0000 },
344 { 0xbc, 0x0000 },
345 { 0xbd, 0x0000 },
346 { 0xbe, 0x0000 },
347 { 0xbf, 0x3100 },
348 { 0xc0, 0x0000 },
349 { 0xc1, 0x0000 },
350 { 0xc2, 0x0000 },
351 { 0xc3, 0x2000 },
352 { 0xcd, 0x0000 },
353 { 0xce, 0x0000 },
354 { 0xcf, 0x1813 },
355 { 0xd0, 0x0690 },
356 { 0xd1, 0x1c17 },
357 { 0xd3, 0xb320 },
358 { 0xd4, 0x0000 },
359 { 0xd6, 0x0400 },
360 { 0xd9, 0x0809 },
361 { 0xda, 0x0000 },
362 { 0xdb, 0x0003 },
363 { 0xdc, 0x0049 },
364 { 0xdd, 0x001b },
365 { 0xdf, 0x0008 },
366 { 0xe0, 0x4000 },
367 { 0xe6, 0x8000 },
368 { 0xe7, 0x0200 },
369 { 0xec, 0xb300 },
370 { 0xed, 0x0000 },
371 { 0xf0, 0x001f },
372 { 0xf1, 0x020c },
373 { 0xf2, 0x1f00 },
374 { 0xf3, 0x0000 },
375 { 0xf4, 0x4000 },
376 { 0xf8, 0x0000 },
377 { 0xf9, 0x0000 },
378 { 0xfa, 0x2060 },
379 { 0xfb, 0x4040 },
380 { 0xfc, 0x0000 },
381 { 0xfd, 0x0002 },
382 { 0xfe, 0x10ec },
383 { 0xff, 0x6308 },
384};
385
229struct rt5645_eq_param_s { 386struct rt5645_eq_param_s {
230 unsigned short reg; 387 unsigned short reg;
231 unsigned short val; 388 unsigned short val;
@@ -572,14 +729,12 @@ static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
572 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); 729 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
573 int ret; 730 int ret;
574 731
575 cancel_delayed_work_sync(&rt5645->rcclock_work);
576
577 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, 732 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
578 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU); 733 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
579 734
580 ret = snd_soc_put_volsw(kcontrol, ucontrol); 735 ret = snd_soc_put_volsw(kcontrol, ucontrol);
581 736
582 queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work, 737 mod_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
583 msecs_to_jiffies(200)); 738 msecs_to_jiffies(200));
584 739
585 return ret; 740 return ret;
@@ -3318,6 +3473,31 @@ static const struct regmap_config rt5645_regmap = {
3318 .num_ranges = ARRAY_SIZE(rt5645_ranges), 3473 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3319}; 3474};
3320 3475
3476static const struct regmap_config rt5650_regmap = {
3477 .reg_bits = 8,
3478 .val_bits = 16,
3479 .use_single_rw = true,
3480 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
3481 RT5645_PR_SPACING),
3482 .volatile_reg = rt5645_volatile_register,
3483 .readable_reg = rt5645_readable_register,
3484
3485 .cache_type = REGCACHE_RBTREE,
3486 .reg_defaults = rt5650_reg,
3487 .num_reg_defaults = ARRAY_SIZE(rt5650_reg),
3488 .ranges = rt5645_ranges,
3489 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3490};
3491
3492static const struct regmap_config temp_regmap = {
3493 .name="nocache",
3494 .reg_bits = 8,
3495 .val_bits = 16,
3496 .use_single_rw = true,
3497 .max_register = RT5645_VENDOR_ID2 + 1,
3498 .cache_type = REGCACHE_NONE,
3499};
3500
3321static const struct i2c_device_id rt5645_i2c_id[] = { 3501static const struct i2c_device_id rt5645_i2c_id[] = {
3322 { "rt5645", 0 }, 3502 { "rt5645", 0 },
3323 { "rt5650", 0 }, 3503 { "rt5650", 0 },
@@ -3334,69 +3514,23 @@ static struct acpi_device_id rt5645_acpi_match[] = {
3334MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); 3514MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
3335#endif 3515#endif
3336 3516
3337static struct rt5645_platform_data *rt5645_pdata; 3517static struct rt5645_platform_data general_platform_data = {
3338
3339static struct rt5645_platform_data strago_platform_data = {
3340 .dmic1_data_pin = RT5645_DMIC1_DISABLE, 3518 .dmic1_data_pin = RT5645_DMIC1_DISABLE,
3341 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, 3519 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3342 .jd_mode = 3, 3520 .jd_mode = 3,
3343}; 3521};
3344 3522
3345static int strago_quirk_cb(const struct dmi_system_id *id)
3346{
3347 rt5645_pdata = &strago_platform_data;
3348
3349 return 1;
3350}
3351
3352static const struct dmi_system_id dmi_platform_intel_braswell[] = { 3523static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3353 { 3524 {
3354 .ident = "Intel Strago", 3525 .ident = "Intel Strago",
3355 .callback = strago_quirk_cb,
3356 .matches = { 3526 .matches = {
3357 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), 3527 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"),
3358 }, 3528 },
3359 }, 3529 },
3360 { 3530 {
3361 .ident = "Google Celes", 3531 .ident = "Google Chrome",
3362 .callback = strago_quirk_cb,
3363 .matches = {
3364 DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
3365 },
3366 },
3367 {
3368 .ident = "Google Ultima",
3369 .callback = strago_quirk_cb,
3370 .matches = {
3371 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
3372 },
3373 },
3374 {
3375 .ident = "Google Reks",
3376 .callback = strago_quirk_cb,
3377 .matches = {
3378 DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
3379 },
3380 },
3381 {
3382 .ident = "Google Edgar",
3383 .callback = strago_quirk_cb,
3384 .matches = {
3385 DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"),
3386 },
3387 },
3388 {
3389 .ident = "Google Wizpig",
3390 .callback = strago_quirk_cb,
3391 .matches = {
3392 DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"),
3393 },
3394 },
3395 {
3396 .ident = "Google Terra",
3397 .callback = strago_quirk_cb,
3398 .matches = { 3532 .matches = {
3399 DMI_MATCH(DMI_PRODUCT_NAME, "Terra"), 3533 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
3400 }, 3534 },
3401 }, 3535 },
3402 { } 3536 { }
@@ -3409,17 +3543,9 @@ static struct rt5645_platform_data buddy_platform_data = {
3409 .jd_invert = true, 3543 .jd_invert = true,
3410}; 3544};
3411 3545
3412static int buddy_quirk_cb(const struct dmi_system_id *id)
3413{
3414 rt5645_pdata = &buddy_platform_data;
3415
3416 return 1;
3417}
3418
3419static struct dmi_system_id dmi_platform_intel_broadwell[] = { 3546static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3420 { 3547 {
3421 .ident = "Chrome Buddy", 3548 .ident = "Chrome Buddy",
3422 .callback = buddy_quirk_cb,
3423 .matches = { 3549 .matches = {
3424 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), 3550 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3425 }, 3551 },
@@ -3427,6 +3553,16 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3427 { } 3553 { }
3428}; 3554};
3429 3555
3556static bool rt5645_check_dp(struct device *dev)
3557{
3558 if (device_property_present(dev, "realtek,in2-differential") ||
3559 device_property_present(dev, "realtek,dmic1-data-pin") ||
3560 device_property_present(dev, "realtek,dmic2-data-pin") ||
3561 device_property_present(dev, "realtek,jd-mode"))
3562 return true;
3563
3564 return false;
3565}
3430 3566
3431static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) 3567static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3432{ 3568{
@@ -3449,6 +3585,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3449 struct rt5645_priv *rt5645; 3585 struct rt5645_priv *rt5645;
3450 int ret, i; 3586 int ret, i;
3451 unsigned int val; 3587 unsigned int val;
3588 struct regmap *regmap;
3452 3589
3453 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), 3590 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
3454 GFP_KERNEL); 3591 GFP_KERNEL);
@@ -3460,11 +3597,12 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3460 3597
3461 if (pdata) 3598 if (pdata)
3462 rt5645->pdata = *pdata; 3599 rt5645->pdata = *pdata;
3463 else if (dmi_check_system(dmi_platform_intel_braswell) || 3600 else if (dmi_check_system(dmi_platform_intel_broadwell))
3464 dmi_check_system(dmi_platform_intel_broadwell)) 3601 rt5645->pdata = buddy_platform_data;
3465 rt5645->pdata = *rt5645_pdata; 3602 else if (rt5645_check_dp(&i2c->dev))
3466 else
3467 rt5645_parse_dt(rt5645, &i2c->dev); 3603 rt5645_parse_dt(rt5645, &i2c->dev);
3604 else if (dmi_check_system(dmi_platform_intel_braswell))
3605 rt5645->pdata = general_platform_data;
3468 3606
3469 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", 3607 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
3470 GPIOD_IN); 3608 GPIOD_IN);
@@ -3474,14 +3612,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3474 return PTR_ERR(rt5645->gpiod_hp_det); 3612 return PTR_ERR(rt5645->gpiod_hp_det);
3475 } 3613 }
3476 3614
3477 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3478 if (IS_ERR(rt5645->regmap)) {
3479 ret = PTR_ERR(rt5645->regmap);
3480 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3481 ret);
3482 return ret;
3483 }
3484
3485 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) 3615 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
3486 rt5645->supplies[i].supply = rt5645_supply_names[i]; 3616 rt5645->supplies[i].supply = rt5645_supply_names[i];
3487 3617
@@ -3500,13 +3630,22 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3500 return ret; 3630 return ret;
3501 } 3631 }
3502 3632
3503 regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); 3633 regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
3634 if (IS_ERR(regmap)) {
3635 ret = PTR_ERR(regmap);
3636 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
3637 ret);
3638 return ret;
3639 }
3640 regmap_read(regmap, RT5645_VENDOR_ID2, &val);
3504 3641
3505 switch (val) { 3642 switch (val) {
3506 case RT5645_DEVICE_ID: 3643 case RT5645_DEVICE_ID:
3644 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3507 rt5645->codec_type = CODEC_TYPE_RT5645; 3645 rt5645->codec_type = CODEC_TYPE_RT5645;
3508 break; 3646 break;
3509 case RT5650_DEVICE_ID: 3647 case RT5650_DEVICE_ID:
3648 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5650_regmap);
3510 rt5645->codec_type = CODEC_TYPE_RT5650; 3649 rt5645->codec_type = CODEC_TYPE_RT5650;
3511 break; 3650 break;
3512 default: 3651 default:
@@ -3517,6 +3656,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3517 goto err_enable; 3656 goto err_enable;
3518 } 3657 }
3519 3658
3659 if (IS_ERR(rt5645->regmap)) {
3660 ret = PTR_ERR(rt5645->regmap);
3661 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3662 ret);
3663 return ret;
3664 }
3665
3520 regmap_write(rt5645->regmap, RT5645_RESET, 0); 3666 regmap_write(rt5645->regmap, RT5645_RESET, 0);
3521 3667
3522 ret = regmap_register_patch(rt5645->regmap, init_list, 3668 ret = regmap_register_patch(rt5645->regmap, init_list,
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
new file mode 100644
index 000000000000..820d8fa62b5e
--- /dev/null
+++ b/sound/soc/codecs/rt5659.c
@@ -0,0 +1,4223 @@
1/*
2 * rt5659.c -- RT5659/RT5658 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 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/gpio/consumer.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/jack.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31#include <sound/rt5659.h>
32
33#include "rl6231.h"
34#include "rt5659.h"
35
36static const struct reg_default rt5659_reg[] = {
37 { 0x0000, 0x0000 },
38 { 0x0001, 0x4848 },
39 { 0x0002, 0x8080 },
40 { 0x0003, 0xc8c8 },
41 { 0x0004, 0xc80a },
42 { 0x0005, 0x0000 },
43 { 0x0006, 0x0000 },
44 { 0x0007, 0x0103 },
45 { 0x0008, 0x0080 },
46 { 0x0009, 0x0000 },
47 { 0x000a, 0x0000 },
48 { 0x000c, 0x0000 },
49 { 0x000d, 0x0000 },
50 { 0x000f, 0x0808 },
51 { 0x0010, 0x3080 },
52 { 0x0011, 0x4a00 },
53 { 0x0012, 0x4e00 },
54 { 0x0015, 0x42c1 },
55 { 0x0016, 0x0000 },
56 { 0x0018, 0x000b },
57 { 0x0019, 0xafaf },
58 { 0x001a, 0xafaf },
59 { 0x001b, 0x0011 },
60 { 0x001c, 0x2f2f },
61 { 0x001d, 0x2f2f },
62 { 0x001e, 0x2f2f },
63 { 0x001f, 0x0000 },
64 { 0x0020, 0x0000 },
65 { 0x0021, 0x0000 },
66 { 0x0022, 0x5757 },
67 { 0x0023, 0x0039 },
68 { 0x0026, 0xc060 },
69 { 0x0027, 0xd8d8 },
70 { 0x0029, 0x8080 },
71 { 0x002a, 0xaaaa },
72 { 0x002b, 0xaaaa },
73 { 0x002c, 0x00af },
74 { 0x002d, 0x0000 },
75 { 0x002f, 0x1002 },
76 { 0x0031, 0x5000 },
77 { 0x0032, 0x0000 },
78 { 0x0033, 0x0000 },
79 { 0x0034, 0x0000 },
80 { 0x0035, 0x0000 },
81 { 0x0036, 0x0000 },
82 { 0x003a, 0x0000 },
83 { 0x003b, 0x0000 },
84 { 0x003c, 0x007f },
85 { 0x003d, 0x0000 },
86 { 0x003e, 0x007f },
87 { 0x0040, 0x0808 },
88 { 0x0046, 0x001f },
89 { 0x0047, 0x001f },
90 { 0x0048, 0x0003 },
91 { 0x0049, 0xe061 },
92 { 0x004a, 0x0000 },
93 { 0x004b, 0x031f },
94 { 0x004d, 0x0000 },
95 { 0x004e, 0x001f },
96 { 0x004f, 0x0000 },
97 { 0x0050, 0x001f },
98 { 0x0052, 0xf000 },
99 { 0x0053, 0x0111 },
100 { 0x0054, 0x0064 },
101 { 0x0055, 0x0080 },
102 { 0x0056, 0xef0e },
103 { 0x0057, 0xf0f0 },
104 { 0x0058, 0xef0e },
105 { 0x0059, 0xf0f0 },
106 { 0x005a, 0xef0e },
107 { 0x005b, 0xf0f0 },
108 { 0x005c, 0xf000 },
109 { 0x005d, 0x0000 },
110 { 0x005e, 0x1f2c },
111 { 0x005f, 0x1f2c },
112 { 0x0060, 0x2717 },
113 { 0x0061, 0x0000 },
114 { 0x0062, 0x0000 },
115 { 0x0063, 0x003e },
116 { 0x0064, 0x0000 },
117 { 0x0065, 0x0000 },
118 { 0x0066, 0x0000 },
119 { 0x0067, 0x0000 },
120 { 0x006a, 0x0000 },
121 { 0x006b, 0x0000 },
122 { 0x006c, 0x0000 },
123 { 0x006e, 0x0000 },
124 { 0x006f, 0x0000 },
125 { 0x0070, 0x8000 },
126 { 0x0071, 0x8000 },
127 { 0x0072, 0x8000 },
128 { 0x0073, 0x1110 },
129 { 0x0074, 0xfe00 },
130 { 0x0075, 0x2409 },
131 { 0x0076, 0x000a },
132 { 0x0077, 0x00f0 },
133 { 0x0078, 0x0000 },
134 { 0x0079, 0x0000 },
135 { 0x007a, 0x0123 },
136 { 0x007b, 0x8003 },
137 { 0x0080, 0x0000 },
138 { 0x0081, 0x0000 },
139 { 0x0082, 0x0000 },
140 { 0x0083, 0x0000 },
141 { 0x0084, 0x0000 },
142 { 0x0085, 0x0000 },
143 { 0x0086, 0x0008 },
144 { 0x0087, 0x0000 },
145 { 0x0088, 0x0000 },
146 { 0x0089, 0x0000 },
147 { 0x008a, 0x0000 },
148 { 0x008b, 0x0000 },
149 { 0x008c, 0x0003 },
150 { 0x008e, 0x0000 },
151 { 0x008f, 0x1000 },
152 { 0x0090, 0x0646 },
153 { 0x0091, 0x0c16 },
154 { 0x0092, 0x0073 },
155 { 0x0093, 0x0000 },
156 { 0x0094, 0x0080 },
157 { 0x0097, 0x0000 },
158 { 0x0098, 0x0000 },
159 { 0x0099, 0x0000 },
160 { 0x009a, 0x0000 },
161 { 0x009b, 0x0000 },
162 { 0x009c, 0x007f },
163 { 0x009d, 0x0000 },
164 { 0x009e, 0x007f },
165 { 0x009f, 0x0000 },
166 { 0x00a0, 0x0060 },
167 { 0x00a1, 0x90a1 },
168 { 0x00ae, 0x2000 },
169 { 0x00af, 0x0000 },
170 { 0x00b0, 0x2000 },
171 { 0x00b1, 0x0000 },
172 { 0x00b2, 0x0000 },
173 { 0x00b6, 0x0000 },
174 { 0x00b7, 0x0000 },
175 { 0x00b8, 0x0000 },
176 { 0x00b9, 0x0000 },
177 { 0x00ba, 0x0000 },
178 { 0x00bb, 0x0000 },
179 { 0x00be, 0x0000 },
180 { 0x00bf, 0x0000 },
181 { 0x00c0, 0x0000 },
182 { 0x00c1, 0x0000 },
183 { 0x00c2, 0x0000 },
184 { 0x00c3, 0x0000 },
185 { 0x00c4, 0x0003 },
186 { 0x00c5, 0x0000 },
187 { 0x00cb, 0xa02f },
188 { 0x00cc, 0x0000 },
189 { 0x00cd, 0x0e02 },
190 { 0x00d6, 0x0000 },
191 { 0x00d7, 0x2244 },
192 { 0x00d9, 0x0809 },
193 { 0x00da, 0x0000 },
194 { 0x00db, 0x0008 },
195 { 0x00dc, 0x00c0 },
196 { 0x00dd, 0x6724 },
197 { 0x00de, 0x3131 },
198 { 0x00df, 0x0008 },
199 { 0x00e0, 0x4000 },
200 { 0x00e1, 0x3131 },
201 { 0x00e4, 0x400c },
202 { 0x00e5, 0x8031 },
203 { 0x00ea, 0xb320 },
204 { 0x00eb, 0x0000 },
205 { 0x00ec, 0xb300 },
206 { 0x00ed, 0x0000 },
207 { 0x00f0, 0x0000 },
208 { 0x00f1, 0x0202 },
209 { 0x00f2, 0x0ddd },
210 { 0x00f3, 0x0ddd },
211 { 0x00f4, 0x0ddd },
212 { 0x00f6, 0x0000 },
213 { 0x00f7, 0x0000 },
214 { 0x00f8, 0x0000 },
215 { 0x00f9, 0x0000 },
216 { 0x00fa, 0x8000 },
217 { 0x00fb, 0x0000 },
218 { 0x00fc, 0x0000 },
219 { 0x00fd, 0x0001 },
220 { 0x00fe, 0x10ec },
221 { 0x00ff, 0x6311 },
222 { 0x0100, 0xaaaa },
223 { 0x010a, 0xaaaa },
224 { 0x010b, 0x00a0 },
225 { 0x010c, 0xaeae },
226 { 0x010d, 0xaaaa },
227 { 0x010e, 0xaaa8 },
228 { 0x010f, 0xa0aa },
229 { 0x0110, 0xe02a },
230 { 0x0111, 0xa702 },
231 { 0x0112, 0xaaaa },
232 { 0x0113, 0x2800 },
233 { 0x0116, 0x0000 },
234 { 0x0117, 0x0f00 },
235 { 0x011a, 0x0020 },
236 { 0x011b, 0x0011 },
237 { 0x011c, 0x0150 },
238 { 0x011d, 0x0000 },
239 { 0x011e, 0x0000 },
240 { 0x011f, 0x0000 },
241 { 0x0120, 0x0000 },
242 { 0x0121, 0x009b },
243 { 0x0122, 0x5014 },
244 { 0x0123, 0x0421 },
245 { 0x0124, 0x7cea },
246 { 0x0125, 0x0420 },
247 { 0x0126, 0x5550 },
248 { 0x0132, 0x0000 },
249 { 0x0133, 0x0000 },
250 { 0x0137, 0x5055 },
251 { 0x0138, 0x3700 },
252 { 0x0139, 0x79a1 },
253 { 0x013a, 0x2020 },
254 { 0x013b, 0x2020 },
255 { 0x013c, 0x2005 },
256 { 0x013e, 0x1f00 },
257 { 0x013f, 0x0000 },
258 { 0x0145, 0x0002 },
259 { 0x0146, 0x0000 },
260 { 0x0147, 0x0000 },
261 { 0x0148, 0x0000 },
262 { 0x0150, 0x1813 },
263 { 0x0151, 0x0690 },
264 { 0x0152, 0x1c17 },
265 { 0x0153, 0x6883 },
266 { 0x0154, 0xd3ce },
267 { 0x0155, 0x352d },
268 { 0x0156, 0x00eb },
269 { 0x0157, 0x3717 },
270 { 0x0158, 0x4c6a },
271 { 0x0159, 0xe41b },
272 { 0x015a, 0x2a13 },
273 { 0x015b, 0xb600 },
274 { 0x015c, 0xc730 },
275 { 0x015d, 0x35d4 },
276 { 0x015e, 0x00bf },
277 { 0x0160, 0x0ec0 },
278 { 0x0161, 0x0020 },
279 { 0x0162, 0x0080 },
280 { 0x0163, 0x0800 },
281 { 0x0164, 0x0000 },
282 { 0x0165, 0x0000 },
283 { 0x0166, 0x0000 },
284 { 0x0167, 0x001f },
285 { 0x0170, 0x4e80 },
286 { 0x0171, 0x0020 },
287 { 0x0172, 0x0080 },
288 { 0x0173, 0x0800 },
289 { 0x0174, 0x000c },
290 { 0x0175, 0x0000 },
291 { 0x0190, 0x3300 },
292 { 0x0191, 0x2200 },
293 { 0x0192, 0x0000 },
294 { 0x01b0, 0x4b38 },
295 { 0x01b1, 0x0000 },
296 { 0x01b2, 0x0000 },
297 { 0x01b3, 0x0000 },
298 { 0x01c0, 0x0045 },
299 { 0x01c1, 0x0540 },
300 { 0x01c2, 0x0000 },
301 { 0x01c3, 0x0030 },
302 { 0x01c7, 0x0000 },
303 { 0x01c8, 0x5757 },
304 { 0x01c9, 0x5757 },
305 { 0x01ca, 0x5757 },
306 { 0x01cb, 0x5757 },
307 { 0x01cc, 0x5757 },
308 { 0x01cd, 0x5757 },
309 { 0x01ce, 0x006f },
310 { 0x01da, 0x0000 },
311 { 0x01db, 0x0000 },
312 { 0x01de, 0x7d00 },
313 { 0x01df, 0x10c0 },
314 { 0x01e0, 0x06a1 },
315 { 0x01e1, 0x0000 },
316 { 0x01e2, 0x0000 },
317 { 0x01e3, 0x0000 },
318 { 0x01e4, 0x0001 },
319 { 0x01e6, 0x0000 },
320 { 0x01e7, 0x0000 },
321 { 0x01e8, 0x0000 },
322 { 0x01ea, 0x0000 },
323 { 0x01eb, 0x0000 },
324 { 0x01ec, 0x0000 },
325 { 0x01ed, 0x0000 },
326 { 0x01ee, 0x0000 },
327 { 0x01ef, 0x0000 },
328 { 0x01f0, 0x0000 },
329 { 0x01f1, 0x0000 },
330 { 0x01f2, 0x0000 },
331 { 0x01f6, 0x1e04 },
332 { 0x01f7, 0x01a1 },
333 { 0x01f8, 0x0000 },
334 { 0x01f9, 0x0000 },
335 { 0x01fa, 0x0002 },
336 { 0x01fb, 0x0000 },
337 { 0x01fc, 0x0000 },
338 { 0x01fd, 0x0000 },
339 { 0x01fe, 0x0000 },
340 { 0x0200, 0x066c },
341 { 0x0201, 0x7fff },
342 { 0x0202, 0x7fff },
343 { 0x0203, 0x0000 },
344 { 0x0204, 0x0000 },
345 { 0x0205, 0x0000 },
346 { 0x0206, 0x0000 },
347 { 0x0207, 0x0000 },
348 { 0x0208, 0x0000 },
349 { 0x0256, 0x0000 },
350 { 0x0257, 0x0000 },
351 { 0x0258, 0x0000 },
352 { 0x0259, 0x0000 },
353 { 0x025a, 0x0000 },
354 { 0x025b, 0x3333 },
355 { 0x025c, 0x3333 },
356 { 0x025d, 0x3333 },
357 { 0x025e, 0x0000 },
358 { 0x025f, 0x0000 },
359 { 0x0260, 0x0000 },
360 { 0x0261, 0x0022 },
361 { 0x0262, 0x0300 },
362 { 0x0265, 0x1e80 },
363 { 0x0266, 0x0131 },
364 { 0x0267, 0x0003 },
365 { 0x0268, 0x0000 },
366 { 0x0269, 0x0000 },
367 { 0x026a, 0x0000 },
368 { 0x026b, 0x0000 },
369 { 0x026c, 0x0000 },
370 { 0x026d, 0x0000 },
371 { 0x026e, 0x0000 },
372 { 0x026f, 0x0000 },
373 { 0x0270, 0x0000 },
374 { 0x0271, 0x0000 },
375 { 0x0272, 0x0000 },
376 { 0x0273, 0x0000 },
377 { 0x0280, 0x0000 },
378 { 0x0281, 0x0000 },
379 { 0x0282, 0x0418 },
380 { 0x0283, 0x7fff },
381 { 0x0284, 0x7000 },
382 { 0x0290, 0x01d0 },
383 { 0x0291, 0x0100 },
384 { 0x02fa, 0x0000 },
385 { 0x02fb, 0x0000 },
386 { 0x02fc, 0x0000 },
387 { 0x0300, 0x001f },
388 { 0x0301, 0x032c },
389 { 0x0302, 0x5f21 },
390 { 0x0303, 0x4000 },
391 { 0x0304, 0x4000 },
392 { 0x0305, 0x0600 },
393 { 0x0306, 0x8000 },
394 { 0x0307, 0x0700 },
395 { 0x0308, 0x001f },
396 { 0x0309, 0x032c },
397 { 0x030a, 0x5f21 },
398 { 0x030b, 0x4000 },
399 { 0x030c, 0x4000 },
400 { 0x030d, 0x0600 },
401 { 0x030e, 0x8000 },
402 { 0x030f, 0x0700 },
403 { 0x0310, 0x4560 },
404 { 0x0311, 0xa4a8 },
405 { 0x0312, 0x7418 },
406 { 0x0313, 0x0000 },
407 { 0x0314, 0x0006 },
408 { 0x0315, 0x00ff },
409 { 0x0316, 0xc400 },
410 { 0x0317, 0x4560 },
411 { 0x0318, 0xa4a8 },
412 { 0x0319, 0x7418 },
413 { 0x031a, 0x0000 },
414 { 0x031b, 0x0006 },
415 { 0x031c, 0x00ff },
416 { 0x031d, 0xc400 },
417 { 0x0320, 0x0f20 },
418 { 0x0321, 0x8700 },
419 { 0x0322, 0x7dc2 },
420 { 0x0323, 0xa178 },
421 { 0x0324, 0x5383 },
422 { 0x0325, 0x7dc2 },
423 { 0x0326, 0xa178 },
424 { 0x0327, 0x5383 },
425 { 0x0328, 0x003e },
426 { 0x0329, 0x02c1 },
427 { 0x032a, 0xd37d },
428 { 0x0330, 0x00a6 },
429 { 0x0331, 0x04c3 },
430 { 0x0332, 0x27c8 },
431 { 0x0333, 0xbf50 },
432 { 0x0334, 0x0045 },
433 { 0x0335, 0x2007 },
434 { 0x0336, 0x7418 },
435 { 0x0337, 0x0501 },
436 { 0x0338, 0x0000 },
437 { 0x0339, 0x0010 },
438 { 0x033a, 0x1010 },
439 { 0x0340, 0x0800 },
440 { 0x0341, 0x0800 },
441 { 0x0342, 0x0800 },
442 { 0x0343, 0x0800 },
443 { 0x0344, 0x0000 },
444 { 0x0345, 0x0000 },
445 { 0x0346, 0x0000 },
446 { 0x0347, 0x0000 },
447 { 0x0348, 0x0000 },
448 { 0x0349, 0x0000 },
449 { 0x034a, 0x0000 },
450 { 0x034b, 0x0000 },
451 { 0x034c, 0x0000 },
452 { 0x034d, 0x0000 },
453 { 0x034e, 0x0000 },
454 { 0x034f, 0x0000 },
455 { 0x0350, 0x0000 },
456 { 0x0351, 0x0000 },
457 { 0x0352, 0x0000 },
458 { 0x0353, 0x0000 },
459 { 0x0354, 0x0000 },
460 { 0x0355, 0x0000 },
461 { 0x0356, 0x0000 },
462 { 0x0357, 0x0000 },
463 { 0x0358, 0x0000 },
464 { 0x0359, 0x0000 },
465 { 0x035a, 0x0000 },
466 { 0x035b, 0x0000 },
467 { 0x035c, 0x0000 },
468 { 0x035d, 0x0000 },
469 { 0x035e, 0x2000 },
470 { 0x035f, 0x0000 },
471 { 0x0360, 0x2000 },
472 { 0x0361, 0x2000 },
473 { 0x0362, 0x0000 },
474 { 0x0363, 0x2000 },
475 { 0x0364, 0x0200 },
476 { 0x0365, 0x0000 },
477 { 0x0366, 0x0000 },
478 { 0x0367, 0x0000 },
479 { 0x0368, 0x0000 },
480 { 0x0369, 0x0000 },
481 { 0x036a, 0x0000 },
482 { 0x036b, 0x0000 },
483 { 0x036c, 0x0000 },
484 { 0x036d, 0x0000 },
485 { 0x036e, 0x0200 },
486 { 0x036f, 0x0000 },
487 { 0x0370, 0x0000 },
488 { 0x0371, 0x0000 },
489 { 0x0372, 0x0000 },
490 { 0x0373, 0x0000 },
491 { 0x0374, 0x0000 },
492 { 0x0375, 0x0000 },
493 { 0x0376, 0x0000 },
494 { 0x0377, 0x0000 },
495 { 0x03d0, 0x0000 },
496 { 0x03d1, 0x0000 },
497 { 0x03d2, 0x0000 },
498 { 0x03d3, 0x0000 },
499 { 0x03d4, 0x2000 },
500 { 0x03d5, 0x2000 },
501 { 0x03d6, 0x0000 },
502 { 0x03d7, 0x0000 },
503 { 0x03d8, 0x2000 },
504 { 0x03d9, 0x2000 },
505 { 0x03da, 0x2000 },
506 { 0x03db, 0x2000 },
507 { 0x03dc, 0x0000 },
508 { 0x03dd, 0x0000 },
509 { 0x03de, 0x0000 },
510 { 0x03df, 0x2000 },
511 { 0x03e0, 0x0000 },
512 { 0x03e1, 0x0000 },
513 { 0x03e2, 0x0000 },
514 { 0x03e3, 0x0000 },
515 { 0x03e4, 0x0000 },
516 { 0x03e5, 0x0000 },
517 { 0x03e6, 0x0000 },
518 { 0x03e7, 0x0000 },
519 { 0x03e8, 0x0000 },
520 { 0x03e9, 0x0000 },
521 { 0x03ea, 0x0000 },
522 { 0x03eb, 0x0000 },
523 { 0x03ec, 0x0000 },
524 { 0x03ed, 0x0000 },
525 { 0x03ee, 0x0000 },
526 { 0x03ef, 0x0000 },
527 { 0x03f0, 0x0800 },
528 { 0x03f1, 0x0800 },
529 { 0x03f2, 0x0800 },
530 { 0x03f3, 0x0800 },
531};
532
533static bool rt5659_volatile_register(struct device *dev, unsigned int reg)
534{
535 switch (reg) {
536 case RT5659_RESET:
537 case RT5659_EJD_CTRL_2:
538 case RT5659_SILENCE_CTRL:
539 case RT5659_DAC2_DIG_VOL:
540 case RT5659_HP_IMP_GAIN_2:
541 case RT5659_PDM_OUT_CTRL:
542 case RT5659_PDM_DATA_CTRL_1:
543 case RT5659_PDM_DATA_CTRL_4:
544 case RT5659_HAPTIC_GEN_CTRL_1:
545 case RT5659_HAPTIC_GEN_CTRL_3:
546 case RT5659_HAPTIC_LPF_CTRL_3:
547 case RT5659_CLK_DET:
548 case RT5659_MICBIAS_1:
549 case RT5659_ASRC_11:
550 case RT5659_ADC_EQ_CTRL_1:
551 case RT5659_DAC_EQ_CTRL_1:
552 case RT5659_INT_ST_1:
553 case RT5659_INT_ST_2:
554 case RT5659_GPIO_STA:
555 case RT5659_SINE_GEN_CTRL_1:
556 case RT5659_IL_CMD_1:
557 case RT5659_4BTN_IL_CMD_1:
558 case RT5659_PSV_IL_CMD_1:
559 case RT5659_AJD1_CTRL:
560 case RT5659_AJD2_AJD3_CTRL:
561 case RT5659_JD_CTRL_3:
562 case RT5659_VENDOR_ID:
563 case RT5659_VENDOR_ID_1:
564 case RT5659_DEVICE_ID:
565 case RT5659_MEMORY_TEST:
566 case RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL:
567 case RT5659_VOL_TEST:
568 case RT5659_STO_NG2_CTRL_1:
569 case RT5659_STO_NG2_CTRL_5:
570 case RT5659_STO_NG2_CTRL_6:
571 case RT5659_STO_NG2_CTRL_7:
572 case RT5659_MONO_NG2_CTRL_1:
573 case RT5659_MONO_NG2_CTRL_5:
574 case RT5659_MONO_NG2_CTRL_6:
575 case RT5659_HP_IMP_SENS_CTRL_1:
576 case RT5659_HP_IMP_SENS_CTRL_3:
577 case RT5659_HP_IMP_SENS_CTRL_4:
578 case RT5659_HP_CALIB_CTRL_1:
579 case RT5659_HP_CALIB_CTRL_9:
580 case RT5659_HP_CALIB_STA_1:
581 case RT5659_HP_CALIB_STA_2:
582 case RT5659_HP_CALIB_STA_3:
583 case RT5659_HP_CALIB_STA_4:
584 case RT5659_HP_CALIB_STA_5:
585 case RT5659_HP_CALIB_STA_6:
586 case RT5659_HP_CALIB_STA_7:
587 case RT5659_HP_CALIB_STA_8:
588 case RT5659_HP_CALIB_STA_9:
589 case RT5659_MONO_AMP_CALIB_CTRL_1:
590 case RT5659_MONO_AMP_CALIB_CTRL_3:
591 case RT5659_MONO_AMP_CALIB_STA_1:
592 case RT5659_MONO_AMP_CALIB_STA_2:
593 case RT5659_MONO_AMP_CALIB_STA_3:
594 case RT5659_MONO_AMP_CALIB_STA_4:
595 case RT5659_SPK_PWR_LMT_STA_1:
596 case RT5659_SPK_PWR_LMT_STA_2:
597 case RT5659_SPK_PWR_LMT_STA_3:
598 case RT5659_SPK_PWR_LMT_STA_4:
599 case RT5659_SPK_PWR_LMT_STA_5:
600 case RT5659_SPK_PWR_LMT_STA_6:
601 case RT5659_SPK_DC_CAILB_CTRL_1:
602 case RT5659_SPK_DC_CAILB_STA_1:
603 case RT5659_SPK_DC_CAILB_STA_2:
604 case RT5659_SPK_DC_CAILB_STA_3:
605 case RT5659_SPK_DC_CAILB_STA_4:
606 case RT5659_SPK_DC_CAILB_STA_5:
607 case RT5659_SPK_DC_CAILB_STA_6:
608 case RT5659_SPK_DC_CAILB_STA_7:
609 case RT5659_SPK_DC_CAILB_STA_8:
610 case RT5659_SPK_DC_CAILB_STA_9:
611 case RT5659_SPK_DC_CAILB_STA_10:
612 case RT5659_SPK_VDD_STA_1:
613 case RT5659_SPK_VDD_STA_2:
614 case RT5659_SPK_DC_DET_CTRL_1:
615 case RT5659_PURE_DC_DET_CTRL_1:
616 case RT5659_PURE_DC_DET_CTRL_2:
617 case RT5659_DRC1_PRIV_1:
618 case RT5659_DRC1_PRIV_4:
619 case RT5659_DRC1_PRIV_5:
620 case RT5659_DRC1_PRIV_6:
621 case RT5659_DRC1_PRIV_7:
622 case RT5659_DRC2_PRIV_1:
623 case RT5659_DRC2_PRIV_4:
624 case RT5659_DRC2_PRIV_5:
625 case RT5659_DRC2_PRIV_6:
626 case RT5659_DRC2_PRIV_7:
627 case RT5659_ALC_PGA_STA_1:
628 case RT5659_ALC_PGA_STA_2:
629 case RT5659_ALC_PGA_STA_3:
630 return true;
631 default:
632 return false;
633 }
634}
635
636static bool rt5659_readable_register(struct device *dev, unsigned int reg)
637{
638 switch (reg) {
639 case RT5659_RESET:
640 case RT5659_SPO_VOL:
641 case RT5659_HP_VOL:
642 case RT5659_LOUT:
643 case RT5659_MONO_OUT:
644 case RT5659_HPL_GAIN:
645 case RT5659_HPR_GAIN:
646 case RT5659_MONO_GAIN:
647 case RT5659_SPDIF_CTRL_1:
648 case RT5659_SPDIF_CTRL_2:
649 case RT5659_CAL_BST_CTRL:
650 case RT5659_IN1_IN2:
651 case RT5659_IN3_IN4:
652 case RT5659_INL1_INR1_VOL:
653 case RT5659_EJD_CTRL_1:
654 case RT5659_EJD_CTRL_2:
655 case RT5659_EJD_CTRL_3:
656 case RT5659_SILENCE_CTRL:
657 case RT5659_PSV_CTRL:
658 case RT5659_SIDETONE_CTRL:
659 case RT5659_DAC1_DIG_VOL:
660 case RT5659_DAC2_DIG_VOL:
661 case RT5659_DAC_CTRL:
662 case RT5659_STO1_ADC_DIG_VOL:
663 case RT5659_MONO_ADC_DIG_VOL:
664 case RT5659_STO2_ADC_DIG_VOL:
665 case RT5659_STO1_BOOST:
666 case RT5659_MONO_BOOST:
667 case RT5659_STO2_BOOST:
668 case RT5659_HP_IMP_GAIN_1:
669 case RT5659_HP_IMP_GAIN_2:
670 case RT5659_STO1_ADC_MIXER:
671 case RT5659_MONO_ADC_MIXER:
672 case RT5659_AD_DA_MIXER:
673 case RT5659_STO_DAC_MIXER:
674 case RT5659_MONO_DAC_MIXER:
675 case RT5659_DIG_MIXER:
676 case RT5659_A_DAC_MUX:
677 case RT5659_DIG_INF23_DATA:
678 case RT5659_PDM_OUT_CTRL:
679 case RT5659_PDM_DATA_CTRL_1:
680 case RT5659_PDM_DATA_CTRL_2:
681 case RT5659_PDM_DATA_CTRL_3:
682 case RT5659_PDM_DATA_CTRL_4:
683 case RT5659_SPDIF_CTRL:
684 case RT5659_REC1_GAIN:
685 case RT5659_REC1_L1_MIXER:
686 case RT5659_REC1_L2_MIXER:
687 case RT5659_REC1_R1_MIXER:
688 case RT5659_REC1_R2_MIXER:
689 case RT5659_CAL_REC:
690 case RT5659_REC2_L1_MIXER:
691 case RT5659_REC2_L2_MIXER:
692 case RT5659_REC2_R1_MIXER:
693 case RT5659_REC2_R2_MIXER:
694 case RT5659_SPK_L_MIXER:
695 case RT5659_SPK_R_MIXER:
696 case RT5659_SPO_AMP_GAIN:
697 case RT5659_ALC_BACK_GAIN:
698 case RT5659_MONOMIX_GAIN:
699 case RT5659_MONOMIX_IN_GAIN:
700 case RT5659_OUT_L_GAIN:
701 case RT5659_OUT_L_MIXER:
702 case RT5659_OUT_R_GAIN:
703 case RT5659_OUT_R_MIXER:
704 case RT5659_LOUT_MIXER:
705 case RT5659_HAPTIC_GEN_CTRL_1:
706 case RT5659_HAPTIC_GEN_CTRL_2:
707 case RT5659_HAPTIC_GEN_CTRL_3:
708 case RT5659_HAPTIC_GEN_CTRL_4:
709 case RT5659_HAPTIC_GEN_CTRL_5:
710 case RT5659_HAPTIC_GEN_CTRL_6:
711 case RT5659_HAPTIC_GEN_CTRL_7:
712 case RT5659_HAPTIC_GEN_CTRL_8:
713 case RT5659_HAPTIC_GEN_CTRL_9:
714 case RT5659_HAPTIC_GEN_CTRL_10:
715 case RT5659_HAPTIC_GEN_CTRL_11:
716 case RT5659_HAPTIC_LPF_CTRL_1:
717 case RT5659_HAPTIC_LPF_CTRL_2:
718 case RT5659_HAPTIC_LPF_CTRL_3:
719 case RT5659_PWR_DIG_1:
720 case RT5659_PWR_DIG_2:
721 case RT5659_PWR_ANLG_1:
722 case RT5659_PWR_ANLG_2:
723 case RT5659_PWR_ANLG_3:
724 case RT5659_PWR_MIXER:
725 case RT5659_PWR_VOL:
726 case RT5659_PRIV_INDEX:
727 case RT5659_CLK_DET:
728 case RT5659_PRIV_DATA:
729 case RT5659_PRE_DIV_1:
730 case RT5659_PRE_DIV_2:
731 case RT5659_I2S1_SDP:
732 case RT5659_I2S2_SDP:
733 case RT5659_I2S3_SDP:
734 case RT5659_ADDA_CLK_1:
735 case RT5659_ADDA_CLK_2:
736 case RT5659_DMIC_CTRL_1:
737 case RT5659_DMIC_CTRL_2:
738 case RT5659_TDM_CTRL_1:
739 case RT5659_TDM_CTRL_2:
740 case RT5659_TDM_CTRL_3:
741 case RT5659_TDM_CTRL_4:
742 case RT5659_TDM_CTRL_5:
743 case RT5659_GLB_CLK:
744 case RT5659_PLL_CTRL_1:
745 case RT5659_PLL_CTRL_2:
746 case RT5659_ASRC_1:
747 case RT5659_ASRC_2:
748 case RT5659_ASRC_3:
749 case RT5659_ASRC_4:
750 case RT5659_ASRC_5:
751 case RT5659_ASRC_6:
752 case RT5659_ASRC_7:
753 case RT5659_ASRC_8:
754 case RT5659_ASRC_9:
755 case RT5659_ASRC_10:
756 case RT5659_DEPOP_1:
757 case RT5659_DEPOP_2:
758 case RT5659_DEPOP_3:
759 case RT5659_HP_CHARGE_PUMP_1:
760 case RT5659_HP_CHARGE_PUMP_2:
761 case RT5659_MICBIAS_1:
762 case RT5659_MICBIAS_2:
763 case RT5659_ASRC_11:
764 case RT5659_ASRC_12:
765 case RT5659_ASRC_13:
766 case RT5659_REC_M1_M2_GAIN_CTRL:
767 case RT5659_RC_CLK_CTRL:
768 case RT5659_CLASSD_CTRL_1:
769 case RT5659_CLASSD_CTRL_2:
770 case RT5659_ADC_EQ_CTRL_1:
771 case RT5659_ADC_EQ_CTRL_2:
772 case RT5659_DAC_EQ_CTRL_1:
773 case RT5659_DAC_EQ_CTRL_2:
774 case RT5659_DAC_EQ_CTRL_3:
775 case RT5659_IRQ_CTRL_1:
776 case RT5659_IRQ_CTRL_2:
777 case RT5659_IRQ_CTRL_3:
778 case RT5659_IRQ_CTRL_4:
779 case RT5659_IRQ_CTRL_5:
780 case RT5659_IRQ_CTRL_6:
781 case RT5659_INT_ST_1:
782 case RT5659_INT_ST_2:
783 case RT5659_GPIO_CTRL_1:
784 case RT5659_GPIO_CTRL_2:
785 case RT5659_GPIO_CTRL_3:
786 case RT5659_GPIO_CTRL_4:
787 case RT5659_GPIO_CTRL_5:
788 case RT5659_GPIO_STA:
789 case RT5659_SINE_GEN_CTRL_1:
790 case RT5659_SINE_GEN_CTRL_2:
791 case RT5659_SINE_GEN_CTRL_3:
792 case RT5659_HP_AMP_DET_CTRL_1:
793 case RT5659_HP_AMP_DET_CTRL_2:
794 case RT5659_SV_ZCD_1:
795 case RT5659_SV_ZCD_2:
796 case RT5659_IL_CMD_1:
797 case RT5659_IL_CMD_2:
798 case RT5659_IL_CMD_3:
799 case RT5659_IL_CMD_4:
800 case RT5659_4BTN_IL_CMD_1:
801 case RT5659_4BTN_IL_CMD_2:
802 case RT5659_4BTN_IL_CMD_3:
803 case RT5659_PSV_IL_CMD_1:
804 case RT5659_PSV_IL_CMD_2:
805 case RT5659_ADC_STO1_HP_CTRL_1:
806 case RT5659_ADC_STO1_HP_CTRL_2:
807 case RT5659_ADC_MONO_HP_CTRL_1:
808 case RT5659_ADC_MONO_HP_CTRL_2:
809 case RT5659_AJD1_CTRL:
810 case RT5659_AJD2_AJD3_CTRL:
811 case RT5659_JD1_THD:
812 case RT5659_JD2_THD:
813 case RT5659_JD3_THD:
814 case RT5659_JD_CTRL_1:
815 case RT5659_JD_CTRL_2:
816 case RT5659_JD_CTRL_3:
817 case RT5659_JD_CTRL_4:
818 case RT5659_DIG_MISC:
819 case RT5659_DUMMY_2:
820 case RT5659_DUMMY_3:
821 case RT5659_VENDOR_ID:
822 case RT5659_VENDOR_ID_1:
823 case RT5659_DEVICE_ID:
824 case RT5659_DAC_ADC_DIG_VOL:
825 case RT5659_BIAS_CUR_CTRL_1:
826 case RT5659_BIAS_CUR_CTRL_2:
827 case RT5659_BIAS_CUR_CTRL_3:
828 case RT5659_BIAS_CUR_CTRL_4:
829 case RT5659_BIAS_CUR_CTRL_5:
830 case RT5659_BIAS_CUR_CTRL_6:
831 case RT5659_BIAS_CUR_CTRL_7:
832 case RT5659_BIAS_CUR_CTRL_8:
833 case RT5659_BIAS_CUR_CTRL_9:
834 case RT5659_BIAS_CUR_CTRL_10:
835 case RT5659_MEMORY_TEST:
836 case RT5659_VREF_REC_OP_FB_CAP_CTRL:
837 case RT5659_CLASSD_0:
838 case RT5659_CLASSD_1:
839 case RT5659_CLASSD_2:
840 case RT5659_CLASSD_3:
841 case RT5659_CLASSD_4:
842 case RT5659_CLASSD_5:
843 case RT5659_CLASSD_6:
844 case RT5659_CLASSD_7:
845 case RT5659_CLASSD_8:
846 case RT5659_CLASSD_9:
847 case RT5659_CLASSD_10:
848 case RT5659_CHARGE_PUMP_1:
849 case RT5659_CHARGE_PUMP_2:
850 case RT5659_DIG_IN_CTRL_1:
851 case RT5659_DIG_IN_CTRL_2:
852 case RT5659_PAD_DRIVING_CTRL:
853 case RT5659_SOFT_RAMP_DEPOP:
854 case RT5659_PLL:
855 case RT5659_CHOP_DAC:
856 case RT5659_CHOP_ADC:
857 case RT5659_CALIB_ADC_CTRL:
858 case RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL:
859 case RT5659_VOL_TEST:
860 case RT5659_TEST_MODE_CTRL_1:
861 case RT5659_TEST_MODE_CTRL_2:
862 case RT5659_TEST_MODE_CTRL_3:
863 case RT5659_TEST_MODE_CTRL_4:
864 case RT5659_BASSBACK_CTRL:
865 case RT5659_MP3_PLUS_CTRL_1:
866 case RT5659_MP3_PLUS_CTRL_2:
867 case RT5659_MP3_HPF_A1:
868 case RT5659_MP3_HPF_A2:
869 case RT5659_MP3_HPF_H0:
870 case RT5659_MP3_LPF_H0:
871 case RT5659_3D_SPK_CTRL:
872 case RT5659_3D_SPK_COEF_1:
873 case RT5659_3D_SPK_COEF_2:
874 case RT5659_3D_SPK_COEF_3:
875 case RT5659_3D_SPK_COEF_4:
876 case RT5659_3D_SPK_COEF_5:
877 case RT5659_3D_SPK_COEF_6:
878 case RT5659_3D_SPK_COEF_7:
879 case RT5659_STO_NG2_CTRL_1:
880 case RT5659_STO_NG2_CTRL_2:
881 case RT5659_STO_NG2_CTRL_3:
882 case RT5659_STO_NG2_CTRL_4:
883 case RT5659_STO_NG2_CTRL_5:
884 case RT5659_STO_NG2_CTRL_6:
885 case RT5659_STO_NG2_CTRL_7:
886 case RT5659_STO_NG2_CTRL_8:
887 case RT5659_MONO_NG2_CTRL_1:
888 case RT5659_MONO_NG2_CTRL_2:
889 case RT5659_MONO_NG2_CTRL_3:
890 case RT5659_MONO_NG2_CTRL_4:
891 case RT5659_MONO_NG2_CTRL_5:
892 case RT5659_MONO_NG2_CTRL_6:
893 case RT5659_MID_HP_AMP_DET:
894 case RT5659_LOW_HP_AMP_DET:
895 case RT5659_LDO_CTRL:
896 case RT5659_HP_DECROSS_CTRL_1:
897 case RT5659_HP_DECROSS_CTRL_2:
898 case RT5659_HP_DECROSS_CTRL_3:
899 case RT5659_HP_DECROSS_CTRL_4:
900 case RT5659_HP_IMP_SENS_CTRL_1:
901 case RT5659_HP_IMP_SENS_CTRL_2:
902 case RT5659_HP_IMP_SENS_CTRL_3:
903 case RT5659_HP_IMP_SENS_CTRL_4:
904 case RT5659_HP_IMP_SENS_MAP_1:
905 case RT5659_HP_IMP_SENS_MAP_2:
906 case RT5659_HP_IMP_SENS_MAP_3:
907 case RT5659_HP_IMP_SENS_MAP_4:
908 case RT5659_HP_IMP_SENS_MAP_5:
909 case RT5659_HP_IMP_SENS_MAP_6:
910 case RT5659_HP_IMP_SENS_MAP_7:
911 case RT5659_HP_IMP_SENS_MAP_8:
912 case RT5659_HP_LOGIC_CTRL_1:
913 case RT5659_HP_LOGIC_CTRL_2:
914 case RT5659_HP_CALIB_CTRL_1:
915 case RT5659_HP_CALIB_CTRL_2:
916 case RT5659_HP_CALIB_CTRL_3:
917 case RT5659_HP_CALIB_CTRL_4:
918 case RT5659_HP_CALIB_CTRL_5:
919 case RT5659_HP_CALIB_CTRL_6:
920 case RT5659_HP_CALIB_CTRL_7:
921 case RT5659_HP_CALIB_CTRL_9:
922 case RT5659_HP_CALIB_CTRL_10:
923 case RT5659_HP_CALIB_CTRL_11:
924 case RT5659_HP_CALIB_STA_1:
925 case RT5659_HP_CALIB_STA_2:
926 case RT5659_HP_CALIB_STA_3:
927 case RT5659_HP_CALIB_STA_4:
928 case RT5659_HP_CALIB_STA_5:
929 case RT5659_HP_CALIB_STA_6:
930 case RT5659_HP_CALIB_STA_7:
931 case RT5659_HP_CALIB_STA_8:
932 case RT5659_HP_CALIB_STA_9:
933 case RT5659_MONO_AMP_CALIB_CTRL_1:
934 case RT5659_MONO_AMP_CALIB_CTRL_2:
935 case RT5659_MONO_AMP_CALIB_CTRL_3:
936 case RT5659_MONO_AMP_CALIB_CTRL_4:
937 case RT5659_MONO_AMP_CALIB_CTRL_5:
938 case RT5659_MONO_AMP_CALIB_STA_1:
939 case RT5659_MONO_AMP_CALIB_STA_2:
940 case RT5659_MONO_AMP_CALIB_STA_3:
941 case RT5659_MONO_AMP_CALIB_STA_4:
942 case RT5659_SPK_PWR_LMT_CTRL_1:
943 case RT5659_SPK_PWR_LMT_CTRL_2:
944 case RT5659_SPK_PWR_LMT_CTRL_3:
945 case RT5659_SPK_PWR_LMT_STA_1:
946 case RT5659_SPK_PWR_LMT_STA_2:
947 case RT5659_SPK_PWR_LMT_STA_3:
948 case RT5659_SPK_PWR_LMT_STA_4:
949 case RT5659_SPK_PWR_LMT_STA_5:
950 case RT5659_SPK_PWR_LMT_STA_6:
951 case RT5659_FLEX_SPK_BST_CTRL_1:
952 case RT5659_FLEX_SPK_BST_CTRL_2:
953 case RT5659_FLEX_SPK_BST_CTRL_3:
954 case RT5659_FLEX_SPK_BST_CTRL_4:
955 case RT5659_SPK_EX_LMT_CTRL_1:
956 case RT5659_SPK_EX_LMT_CTRL_2:
957 case RT5659_SPK_EX_LMT_CTRL_3:
958 case RT5659_SPK_EX_LMT_CTRL_4:
959 case RT5659_SPK_EX_LMT_CTRL_5:
960 case RT5659_SPK_EX_LMT_CTRL_6:
961 case RT5659_SPK_EX_LMT_CTRL_7:
962 case RT5659_ADJ_HPF_CTRL_1:
963 case RT5659_ADJ_HPF_CTRL_2:
964 case RT5659_SPK_DC_CAILB_CTRL_1:
965 case RT5659_SPK_DC_CAILB_CTRL_2:
966 case RT5659_SPK_DC_CAILB_CTRL_3:
967 case RT5659_SPK_DC_CAILB_CTRL_4:
968 case RT5659_SPK_DC_CAILB_CTRL_5:
969 case RT5659_SPK_DC_CAILB_STA_1:
970 case RT5659_SPK_DC_CAILB_STA_2:
971 case RT5659_SPK_DC_CAILB_STA_3:
972 case RT5659_SPK_DC_CAILB_STA_4:
973 case RT5659_SPK_DC_CAILB_STA_5:
974 case RT5659_SPK_DC_CAILB_STA_6:
975 case RT5659_SPK_DC_CAILB_STA_7:
976 case RT5659_SPK_DC_CAILB_STA_8:
977 case RT5659_SPK_DC_CAILB_STA_9:
978 case RT5659_SPK_DC_CAILB_STA_10:
979 case RT5659_SPK_VDD_STA_1:
980 case RT5659_SPK_VDD_STA_2:
981 case RT5659_SPK_DC_DET_CTRL_1:
982 case RT5659_SPK_DC_DET_CTRL_2:
983 case RT5659_SPK_DC_DET_CTRL_3:
984 case RT5659_PURE_DC_DET_CTRL_1:
985 case RT5659_PURE_DC_DET_CTRL_2:
986 case RT5659_DUMMY_4:
987 case RT5659_DUMMY_5:
988 case RT5659_DUMMY_6:
989 case RT5659_DRC1_CTRL_1:
990 case RT5659_DRC1_CTRL_2:
991 case RT5659_DRC1_CTRL_3:
992 case RT5659_DRC1_CTRL_4:
993 case RT5659_DRC1_CTRL_5:
994 case RT5659_DRC1_CTRL_6:
995 case RT5659_DRC1_HARD_LMT_CTRL_1:
996 case RT5659_DRC1_HARD_LMT_CTRL_2:
997 case RT5659_DRC2_CTRL_1:
998 case RT5659_DRC2_CTRL_2:
999 case RT5659_DRC2_CTRL_3:
1000 case RT5659_DRC2_CTRL_4:
1001 case RT5659_DRC2_CTRL_5:
1002 case RT5659_DRC2_CTRL_6:
1003 case RT5659_DRC2_HARD_LMT_CTRL_1:
1004 case RT5659_DRC2_HARD_LMT_CTRL_2:
1005 case RT5659_DRC1_PRIV_1:
1006 case RT5659_DRC1_PRIV_2:
1007 case RT5659_DRC1_PRIV_3:
1008 case RT5659_DRC1_PRIV_4:
1009 case RT5659_DRC1_PRIV_5:
1010 case RT5659_DRC1_PRIV_6:
1011 case RT5659_DRC1_PRIV_7:
1012 case RT5659_DRC2_PRIV_1:
1013 case RT5659_DRC2_PRIV_2:
1014 case RT5659_DRC2_PRIV_3:
1015 case RT5659_DRC2_PRIV_4:
1016 case RT5659_DRC2_PRIV_5:
1017 case RT5659_DRC2_PRIV_6:
1018 case RT5659_DRC2_PRIV_7:
1019 case RT5659_MULTI_DRC_CTRL:
1020 case RT5659_CROSS_OVER_1:
1021 case RT5659_CROSS_OVER_2:
1022 case RT5659_CROSS_OVER_3:
1023 case RT5659_CROSS_OVER_4:
1024 case RT5659_CROSS_OVER_5:
1025 case RT5659_CROSS_OVER_6:
1026 case RT5659_CROSS_OVER_7:
1027 case RT5659_CROSS_OVER_8:
1028 case RT5659_CROSS_OVER_9:
1029 case RT5659_CROSS_OVER_10:
1030 case RT5659_ALC_PGA_CTRL_1:
1031 case RT5659_ALC_PGA_CTRL_2:
1032 case RT5659_ALC_PGA_CTRL_3:
1033 case RT5659_ALC_PGA_CTRL_4:
1034 case RT5659_ALC_PGA_CTRL_5:
1035 case RT5659_ALC_PGA_CTRL_6:
1036 case RT5659_ALC_PGA_CTRL_7:
1037 case RT5659_ALC_PGA_CTRL_8:
1038 case RT5659_ALC_PGA_STA_1:
1039 case RT5659_ALC_PGA_STA_2:
1040 case RT5659_ALC_PGA_STA_3:
1041 case RT5659_DAC_L_EQ_PRE_VOL:
1042 case RT5659_DAC_R_EQ_PRE_VOL:
1043 case RT5659_DAC_L_EQ_POST_VOL:
1044 case RT5659_DAC_R_EQ_POST_VOL:
1045 case RT5659_DAC_L_EQ_LPF1_A1:
1046 case RT5659_DAC_L_EQ_LPF1_H0:
1047 case RT5659_DAC_R_EQ_LPF1_A1:
1048 case RT5659_DAC_R_EQ_LPF1_H0:
1049 case RT5659_DAC_L_EQ_BPF2_A1:
1050 case RT5659_DAC_L_EQ_BPF2_A2:
1051 case RT5659_DAC_L_EQ_BPF2_H0:
1052 case RT5659_DAC_R_EQ_BPF2_A1:
1053 case RT5659_DAC_R_EQ_BPF2_A2:
1054 case RT5659_DAC_R_EQ_BPF2_H0:
1055 case RT5659_DAC_L_EQ_BPF3_A1:
1056 case RT5659_DAC_L_EQ_BPF3_A2:
1057 case RT5659_DAC_L_EQ_BPF3_H0:
1058 case RT5659_DAC_R_EQ_BPF3_A1:
1059 case RT5659_DAC_R_EQ_BPF3_A2:
1060 case RT5659_DAC_R_EQ_BPF3_H0:
1061 case RT5659_DAC_L_EQ_BPF4_A1:
1062 case RT5659_DAC_L_EQ_BPF4_A2:
1063 case RT5659_DAC_L_EQ_BPF4_H0:
1064 case RT5659_DAC_R_EQ_BPF4_A1:
1065 case RT5659_DAC_R_EQ_BPF4_A2:
1066 case RT5659_DAC_R_EQ_BPF4_H0:
1067 case RT5659_DAC_L_EQ_HPF1_A1:
1068 case RT5659_DAC_L_EQ_HPF1_H0:
1069 case RT5659_DAC_R_EQ_HPF1_A1:
1070 case RT5659_DAC_R_EQ_HPF1_H0:
1071 case RT5659_DAC_L_EQ_HPF2_A1:
1072 case RT5659_DAC_L_EQ_HPF2_A2:
1073 case RT5659_DAC_L_EQ_HPF2_H0:
1074 case RT5659_DAC_R_EQ_HPF2_A1:
1075 case RT5659_DAC_R_EQ_HPF2_A2:
1076 case RT5659_DAC_R_EQ_HPF2_H0:
1077 case RT5659_DAC_L_BI_EQ_BPF1_H0_1:
1078 case RT5659_DAC_L_BI_EQ_BPF1_H0_2:
1079 case RT5659_DAC_L_BI_EQ_BPF1_B1_1:
1080 case RT5659_DAC_L_BI_EQ_BPF1_B1_2:
1081 case RT5659_DAC_L_BI_EQ_BPF1_B2_1:
1082 case RT5659_DAC_L_BI_EQ_BPF1_B2_2:
1083 case RT5659_DAC_L_BI_EQ_BPF1_A1_1:
1084 case RT5659_DAC_L_BI_EQ_BPF1_A1_2:
1085 case RT5659_DAC_L_BI_EQ_BPF1_A2_1:
1086 case RT5659_DAC_L_BI_EQ_BPF1_A2_2:
1087 case RT5659_DAC_R_BI_EQ_BPF1_H0_1:
1088 case RT5659_DAC_R_BI_EQ_BPF1_H0_2:
1089 case RT5659_DAC_R_BI_EQ_BPF1_B1_1:
1090 case RT5659_DAC_R_BI_EQ_BPF1_B1_2:
1091 case RT5659_DAC_R_BI_EQ_BPF1_B2_1:
1092 case RT5659_DAC_R_BI_EQ_BPF1_B2_2:
1093 case RT5659_DAC_R_BI_EQ_BPF1_A1_1:
1094 case RT5659_DAC_R_BI_EQ_BPF1_A1_2:
1095 case RT5659_DAC_R_BI_EQ_BPF1_A2_1:
1096 case RT5659_DAC_R_BI_EQ_BPF1_A2_2:
1097 case RT5659_ADC_L_EQ_LPF1_A1:
1098 case RT5659_ADC_R_EQ_LPF1_A1:
1099 case RT5659_ADC_L_EQ_LPF1_H0:
1100 case RT5659_ADC_R_EQ_LPF1_H0:
1101 case RT5659_ADC_L_EQ_BPF1_A1:
1102 case RT5659_ADC_R_EQ_BPF1_A1:
1103 case RT5659_ADC_L_EQ_BPF1_A2:
1104 case RT5659_ADC_R_EQ_BPF1_A2:
1105 case RT5659_ADC_L_EQ_BPF1_H0:
1106 case RT5659_ADC_R_EQ_BPF1_H0:
1107 case RT5659_ADC_L_EQ_BPF2_A1:
1108 case RT5659_ADC_R_EQ_BPF2_A1:
1109 case RT5659_ADC_L_EQ_BPF2_A2:
1110 case RT5659_ADC_R_EQ_BPF2_A2:
1111 case RT5659_ADC_L_EQ_BPF2_H0:
1112 case RT5659_ADC_R_EQ_BPF2_H0:
1113 case RT5659_ADC_L_EQ_BPF3_A1:
1114 case RT5659_ADC_R_EQ_BPF3_A1:
1115 case RT5659_ADC_L_EQ_BPF3_A2:
1116 case RT5659_ADC_R_EQ_BPF3_A2:
1117 case RT5659_ADC_L_EQ_BPF3_H0:
1118 case RT5659_ADC_R_EQ_BPF3_H0:
1119 case RT5659_ADC_L_EQ_BPF4_A1:
1120 case RT5659_ADC_R_EQ_BPF4_A1:
1121 case RT5659_ADC_L_EQ_BPF4_A2:
1122 case RT5659_ADC_R_EQ_BPF4_A2:
1123 case RT5659_ADC_L_EQ_BPF4_H0:
1124 case RT5659_ADC_R_EQ_BPF4_H0:
1125 case RT5659_ADC_L_EQ_HPF1_A1:
1126 case RT5659_ADC_R_EQ_HPF1_A1:
1127 case RT5659_ADC_L_EQ_HPF1_H0:
1128 case RT5659_ADC_R_EQ_HPF1_H0:
1129 case RT5659_ADC_L_EQ_PRE_VOL:
1130 case RT5659_ADC_R_EQ_PRE_VOL:
1131 case RT5659_ADC_L_EQ_POST_VOL:
1132 case RT5659_ADC_R_EQ_POST_VOL:
1133 return true;
1134 default:
1135 return false;
1136 }
1137}
1138
1139static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -2325, 75, 0);
1140static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
1141static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
1142static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
1143static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
1144static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
1145static const DECLARE_TLV_DB_SCALE(in_bst_tlv, -1200, 75, 0);
1146
1147/* Interface data select */
1148static const char * const rt5659_data_select[] = {
1149 "L/R", "R/L", "L/L", "R/R"
1150};
1151
1152static const SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum,
1153 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT01_SFT, rt5659_data_select);
1154
1155static const SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum,
1156 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT23_SFT, rt5659_data_select);
1157
1158static const SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum,
1159 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT45_SFT, rt5659_data_select);
1160
1161static const SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum,
1162 RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT67_SFT, rt5659_data_select);
1163
1164static const SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum,
1165 RT5659_DIG_INF23_DATA, RT5659_IF2_DAC_SEL_SFT, rt5659_data_select);
1166
1167static const SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum,
1168 RT5659_DIG_INF23_DATA, RT5659_IF2_ADC_SEL_SFT, rt5659_data_select);
1169
1170static const SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum,
1171 RT5659_DIG_INF23_DATA, RT5659_IF3_DAC_SEL_SFT, rt5659_data_select);
1172
1173static const SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum,
1174 RT5659_DIG_INF23_DATA, RT5659_IF3_ADC_SEL_SFT, rt5659_data_select);
1175
1176static const struct snd_kcontrol_new rt5659_if1_01_adc_swap_mux =
1177 SOC_DAPM_ENUM("IF1 01 ADC Swap Source", rt5659_if1_01_adc_enum);
1178
1179static const struct snd_kcontrol_new rt5659_if1_23_adc_swap_mux =
1180 SOC_DAPM_ENUM("IF1 23 ADC1 Swap Source", rt5659_if1_23_adc_enum);
1181
1182static const struct snd_kcontrol_new rt5659_if1_45_adc_swap_mux =
1183 SOC_DAPM_ENUM("IF1 45 ADC1 Swap Source", rt5659_if1_45_adc_enum);
1184
1185static const struct snd_kcontrol_new rt5659_if1_67_adc_swap_mux =
1186 SOC_DAPM_ENUM("IF1 67 ADC1 Swap Source", rt5659_if1_67_adc_enum);
1187
1188static const struct snd_kcontrol_new rt5659_if2_dac_swap_mux =
1189 SOC_DAPM_ENUM("IF2 DAC Swap Source", rt5659_if2_dac_enum);
1190
1191static const struct snd_kcontrol_new rt5659_if2_adc_swap_mux =
1192 SOC_DAPM_ENUM("IF2 ADC Swap Source", rt5659_if2_adc_enum);
1193
1194static const struct snd_kcontrol_new rt5659_if3_dac_swap_mux =
1195 SOC_DAPM_ENUM("IF3 DAC Swap Source", rt5659_if3_dac_enum);
1196
1197static const struct snd_kcontrol_new rt5659_if3_adc_swap_mux =
1198 SOC_DAPM_ENUM("IF3 ADC Swap Source", rt5659_if3_adc_enum);
1199
1200static const char * const rt5659_asrc_clk_src[] = {
1201 "clk_sysy_div_out", "clk_i2s1_track", "clk_i2s2_track",
1202 "clk_i2s3_track", "clk_sys2", "clk_sys3"
1203};
1204
1205static unsigned int rt5659_asrc_clk_map_values[] = {
1206 0, 1, 2, 3, 5, 6,
1207};
1208
1209static const SOC_VALUE_ENUM_SINGLE_DECL(
1210 rt5659_da_sto_asrc_enum, RT5659_ASRC_2, RT5659_DA_STO_T_SFT, 0x7,
1211 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1212
1213static const SOC_VALUE_ENUM_SINGLE_DECL(
1214 rt5659_da_monol_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_L_T_SFT, 0x7,
1215 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1216
1217static const SOC_VALUE_ENUM_SINGLE_DECL(
1218 rt5659_da_monor_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_R_T_SFT, 0x7,
1219 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1220
1221static const SOC_VALUE_ENUM_SINGLE_DECL(
1222 rt5659_ad_sto1_asrc_enum, RT5659_ASRC_2, RT5659_AD_STO1_T_SFT, 0x7,
1223 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1224
1225static const SOC_VALUE_ENUM_SINGLE_DECL(
1226 rt5659_ad_sto2_asrc_enum, RT5659_ASRC_3, RT5659_AD_STO2_T_SFT, 0x7,
1227 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1228
1229static const SOC_VALUE_ENUM_SINGLE_DECL(
1230 rt5659_ad_monol_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_L_T_SFT, 0x7,
1231 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1232
1233static const SOC_VALUE_ENUM_SINGLE_DECL(
1234 rt5659_ad_monor_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_R_T_SFT, 0x7,
1235 rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
1236
1237static int rt5659_hp_vol_put(struct snd_kcontrol *kcontrol,
1238 struct snd_ctl_elem_value *ucontrol)
1239{
1240 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
1241 int ret = snd_soc_put_volsw(kcontrol, ucontrol);
1242
1243 if (snd_soc_read(codec, RT5659_STO_NG2_CTRL_1) & RT5659_NG2_EN) {
1244 snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
1245 RT5659_NG2_EN_MASK, RT5659_NG2_DIS);
1246 snd_soc_update_bits(codec, RT5659_STO_NG2_CTRL_1,
1247 RT5659_NG2_EN_MASK, RT5659_NG2_EN);
1248 }
1249
1250 return ret;
1251}
1252
1253static void rt5659_enable_push_button_irq(struct snd_soc_codec *codec,
1254 bool enable)
1255{
1256 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1257
1258 if (enable) {
1259 snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, 0x000b);
1260
1261 /* MICBIAS1 and Mic Det Power for button detect*/
1262 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
1263 snd_soc_dapm_force_enable_pin(dapm,
1264 "Mic Det Power");
1265 snd_soc_dapm_sync(dapm);
1266
1267 snd_soc_update_bits(codec, RT5659_PWR_ANLG_2,
1268 RT5659_PWR_MB1, RT5659_PWR_MB1);
1269 snd_soc_update_bits(codec, RT5659_PWR_VOL,
1270 RT5659_PWR_MIC_DET, RT5659_PWR_MIC_DET);
1271
1272 snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
1273 RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
1274 snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
1275 RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
1276 } else {
1277 snd_soc_update_bits(codec, RT5659_4BTN_IL_CMD_2,
1278 RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_DIS);
1279 snd_soc_update_bits(codec, RT5659_IRQ_CTRL_2,
1280 RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_DIS);
1281 /* MICBIAS1 and Mic Det Power for button detect*/
1282 snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
1283 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1284 snd_soc_dapm_sync(dapm);
1285 }
1286}
1287
1288/**
1289 * rt5659_headset_detect - Detect headset.
1290 * @codec: SoC audio codec device.
1291 * @jack_insert: Jack insert or not.
1292 *
1293 * Detect whether is headset or not when jack inserted.
1294 *
1295 * Returns detect status.
1296 */
1297
1298static int rt5659_headset_detect(struct snd_soc_codec *codec, int jack_insert)
1299{
1300 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1301 int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
1302 int reg_63;
1303
1304 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1305
1306 if (jack_insert) {
1307 snd_soc_dapm_force_enable_pin(dapm,
1308 "Mic Det Power");
1309 snd_soc_dapm_sync(dapm);
1310 reg_63 = snd_soc_read(codec, RT5659_PWR_ANLG_1);
1311
1312 snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
1313 RT5659_PWR_VREF2 | RT5659_PWR_MB,
1314 RT5659_PWR_VREF2 | RT5659_PWR_MB);
1315 msleep(20);
1316 snd_soc_update_bits(codec, RT5659_PWR_ANLG_1,
1317 RT5659_PWR_FV2, RT5659_PWR_FV2);
1318
1319 snd_soc_write(codec, RT5659_EJD_CTRL_2, 0x4160);
1320 snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
1321 0x20, 0x0);
1322 msleep(20);
1323 snd_soc_update_bits(codec, RT5659_EJD_CTRL_1,
1324 0x20, 0x20);
1325
1326 while (i < 5) {
1327 msleep(sleep_time[i]);
1328 val = snd_soc_read(codec, RT5659_EJD_CTRL_2) & 0x0003;
1329 i++;
1330 if (val == 0x1 || val == 0x2 || val == 0x3)
1331 break;
1332 }
1333
1334 switch (val) {
1335 case 1:
1336 rt5659->jack_type = SND_JACK_HEADSET;
1337 rt5659_enable_push_button_irq(codec, true);
1338 break;
1339 default:
1340 snd_soc_write(codec, RT5659_PWR_ANLG_1, reg_63);
1341 rt5659->jack_type = SND_JACK_HEADPHONE;
1342 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1343 snd_soc_dapm_sync(dapm);
1344 break;
1345 }
1346 } else {
1347 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
1348 snd_soc_dapm_sync(dapm);
1349 if (rt5659->jack_type == SND_JACK_HEADSET)
1350 rt5659_enable_push_button_irq(codec, false);
1351 rt5659->jack_type = 0;
1352 }
1353
1354 dev_dbg(codec->dev, "jack_type = %d\n", rt5659->jack_type);
1355 return rt5659->jack_type;
1356}
1357
1358static int rt5659_button_detect(struct snd_soc_codec *codec)
1359{
1360 int btn_type, val;
1361
1362 val = snd_soc_read(codec, RT5659_4BTN_IL_CMD_1);
1363 btn_type = val & 0xfff0;
1364 snd_soc_write(codec, RT5659_4BTN_IL_CMD_1, val);
1365
1366 return btn_type;
1367}
1368
1369static irqreturn_t rt5659_irq(int irq, void *data)
1370{
1371 struct rt5659_priv *rt5659 = data;
1372
1373 queue_delayed_work(system_power_efficient_wq,
1374 &rt5659->jack_detect_work, msecs_to_jiffies(250));
1375
1376 return IRQ_HANDLED;
1377}
1378
1379int rt5659_set_jack_detect(struct snd_soc_codec *codec,
1380 struct snd_soc_jack *hs_jack)
1381{
1382 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1383
1384 rt5659->hs_jack = hs_jack;
1385
1386 rt5659_irq(0, rt5659);
1387
1388 return 0;
1389}
1390EXPORT_SYMBOL_GPL(rt5659_set_jack_detect);
1391
1392static void rt5659_jack_detect_work(struct work_struct *work)
1393{
1394 struct rt5659_priv *rt5659 =
1395 container_of(work, struct rt5659_priv, jack_detect_work.work);
1396 int val, btn_type, report = 0;
1397
1398 if (!rt5659->codec)
1399 return;
1400
1401 val = snd_soc_read(rt5659->codec, RT5659_INT_ST_1) & 0x0080;
1402 if (!val) {
1403 /* jack in */
1404 if (rt5659->jack_type == 0) {
1405 /* jack was out, report jack type */
1406 report = rt5659_headset_detect(rt5659->codec, 1);
1407 } else {
1408 /* jack is already in, report button event */
1409 report = SND_JACK_HEADSET;
1410 btn_type = rt5659_button_detect(rt5659->codec);
1411 /**
1412 * rt5659 can report three kinds of button behavior,
1413 * one click, double click and hold. However,
1414 * currently we will report button pressed/released
1415 * event. So all the three button behaviors are
1416 * treated as button pressed.
1417 */
1418 switch (btn_type) {
1419 case 0x8000:
1420 case 0x4000:
1421 case 0x2000:
1422 report |= SND_JACK_BTN_0;
1423 break;
1424 case 0x1000:
1425 case 0x0800:
1426 case 0x0400:
1427 report |= SND_JACK_BTN_1;
1428 break;
1429 case 0x0200:
1430 case 0x0100:
1431 case 0x0080:
1432 report |= SND_JACK_BTN_2;
1433 break;
1434 case 0x0040:
1435 case 0x0020:
1436 case 0x0010:
1437 report |= SND_JACK_BTN_3;
1438 break;
1439 case 0x0000: /* unpressed */
1440 break;
1441 default:
1442 btn_type = 0;
1443 dev_err(rt5659->codec->dev,
1444 "Unexpected button code 0x%04x\n",
1445 btn_type);
1446 break;
1447 }
1448
1449 /* button release or spurious interrput*/
1450 if (btn_type == 0)
1451 report = rt5659->jack_type;
1452 }
1453 } else {
1454 /* jack out */
1455 report = rt5659_headset_detect(rt5659->codec, 0);
1456 }
1457
1458 snd_soc_jack_report(rt5659->hs_jack, report, SND_JACK_HEADSET |
1459 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1460 SND_JACK_BTN_2 | SND_JACK_BTN_3);
1461}
1462
1463static const struct snd_kcontrol_new rt5659_snd_controls[] = {
1464 /* Speaker Output Volume */
1465 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5659_SPO_VOL,
1466 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 39, 1, out_vol_tlv),
1467
1468 /* Headphone Output Volume */
1469 SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5659_HPL_GAIN,
1470 RT5659_HPR_GAIN, RT5659_G_HP_SFT, 31, 1, snd_soc_get_volsw,
1471 rt5659_hp_vol_put, hp_vol_tlv),
1472
1473 /* Mono Output Volume */
1474 SOC_SINGLE_TLV("Mono Playback Volume", RT5659_MONO_OUT,
1475 RT5659_L_VOL_SFT, 39, 1, out_vol_tlv),
1476
1477 /* Output Volume */
1478 SOC_DOUBLE_TLV("OUT Playback Volume", RT5659_LOUT,
1479 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 39, 1, out_vol_tlv),
1480
1481 /* DAC Digital Volume */
1482 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5659_DAC1_DIG_VOL,
1483 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 175, 0, dac_vol_tlv),
1484 SOC_DOUBLE("DAC1 Playback Switch", RT5659_AD_DA_MIXER,
1485 RT5659_M_DAC1_L_SFT, RT5659_M_DAC1_R_SFT, 1, 1),
1486
1487 SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5659_DAC2_DIG_VOL,
1488 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 175, 0, dac_vol_tlv),
1489 SOC_DOUBLE("DAC2 Playback Switch", RT5659_DAC_CTRL,
1490 RT5659_M_DAC2_L_VOL_SFT, RT5659_M_DAC2_R_VOL_SFT, 1, 1),
1491
1492 /* IN1/IN2/IN3/IN4 Volume */
1493 SOC_SINGLE_TLV("IN1 Boost Volume", RT5659_IN1_IN2,
1494 RT5659_BST1_SFT, 69, 0, in_bst_tlv),
1495 SOC_SINGLE_TLV("IN2 Boost Volume", RT5659_IN1_IN2,
1496 RT5659_BST2_SFT, 69, 0, in_bst_tlv),
1497 SOC_SINGLE_TLV("IN3 Boost Volume", RT5659_IN3_IN4,
1498 RT5659_BST3_SFT, 69, 0, in_bst_tlv),
1499 SOC_SINGLE_TLV("IN4 Boost Volume", RT5659_IN3_IN4,
1500 RT5659_BST4_SFT, 69, 0, in_bst_tlv),
1501
1502 /* INL/INR Volume Control */
1503 SOC_DOUBLE_TLV("IN Capture Volume", RT5659_INL1_INR1_VOL,
1504 RT5659_INL_VOL_SFT, RT5659_INR_VOL_SFT, 31, 1, in_vol_tlv),
1505
1506 /* ADC Digital Volume Control */
1507 SOC_DOUBLE("STO1 ADC Capture Switch", RT5659_STO1_ADC_DIG_VOL,
1508 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1509 SOC_DOUBLE_TLV("STO1 ADC Capture Volume", RT5659_STO1_ADC_DIG_VOL,
1510 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1511 SOC_DOUBLE("Mono ADC Capture Switch", RT5659_MONO_ADC_DIG_VOL,
1512 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1513 SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5659_MONO_ADC_DIG_VOL,
1514 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1515 SOC_DOUBLE("STO2 ADC Capture Switch", RT5659_STO2_ADC_DIG_VOL,
1516 RT5659_L_MUTE_SFT, RT5659_R_MUTE_SFT, 1, 1),
1517 SOC_DOUBLE_TLV("STO2 ADC Capture Volume", RT5659_STO2_ADC_DIG_VOL,
1518 RT5659_L_VOL_SFT, RT5659_R_VOL_SFT, 127, 0, adc_vol_tlv),
1519
1520 /* ADC Boost Volume Control */
1521 SOC_DOUBLE_TLV("STO1 ADC Boost Gain Volume", RT5659_STO1_BOOST,
1522 RT5659_STO1_ADC_L_BST_SFT, RT5659_STO1_ADC_R_BST_SFT,
1523 3, 0, adc_bst_tlv),
1524
1525 SOC_DOUBLE_TLV("Mono ADC Boost Gain Volume", RT5659_MONO_BOOST,
1526 RT5659_MONO_ADC_L_BST_SFT, RT5659_MONO_ADC_R_BST_SFT,
1527 3, 0, adc_bst_tlv),
1528
1529 SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5659_STO2_BOOST,
1530 RT5659_STO2_ADC_L_BST_SFT, RT5659_STO2_ADC_R_BST_SFT,
1531 3, 0, adc_bst_tlv),
1532
1533 SOC_SINGLE("DAC IF1 DAC1 L Data Switch", RT5659_TDM_CTRL_4, 12, 7, 0),
1534 SOC_SINGLE("DAC IF1 DAC1 R Data Switch", RT5659_TDM_CTRL_4, 8, 7, 0),
1535 SOC_SINGLE("DAC IF1 DAC2 L Data Switch", RT5659_TDM_CTRL_4, 4, 7, 0),
1536 SOC_SINGLE("DAC IF1 DAC2 R Data Switch", RT5659_TDM_CTRL_4, 0, 7, 0),
1537};
1538
1539/**
1540 * set_dmic_clk - Set parameter of dmic.
1541 *
1542 * @w: DAPM widget.
1543 * @kcontrol: The kcontrol of this widget.
1544 * @event: Event id.
1545 *
1546 * Choose dmic clock between 1MHz and 3MHz.
1547 * It is better for clock to approximate 3MHz.
1548 */
1549static int set_dmic_clk(struct snd_soc_dapm_widget *w,
1550 struct snd_kcontrol *kcontrol, int event)
1551{
1552 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1553 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
1554 int pd, idx = -EINVAL;
1555
1556 pd = rl6231_get_pre_div(rt5659->regmap,
1557 RT5659_ADDA_CLK_1, RT5659_I2S_PD1_SFT);
1558 idx = rl6231_calc_dmic_clk(rt5659->sysclk / pd);
1559
1560 if (idx < 0)
1561 dev_err(codec->dev, "Failed to set DMIC clock\n");
1562 else {
1563 snd_soc_update_bits(codec, RT5659_DMIC_CTRL_1,
1564 RT5659_DMIC_CLK_MASK, idx << RT5659_DMIC_CLK_SFT);
1565 }
1566 return idx;
1567}
1568
1569static int set_adc_clk(struct snd_soc_dapm_widget *w,
1570 struct snd_kcontrol *kcontrol, int event)
1571{
1572 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1573
1574 switch (event) {
1575 case SND_SOC_DAPM_POST_PMU:
1576 snd_soc_update_bits(codec, RT5659_CHOP_ADC,
1577 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK,
1578 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK);
1579 break;
1580
1581 case SND_SOC_DAPM_PRE_PMD:
1582 snd_soc_update_bits(codec, RT5659_CHOP_ADC,
1583 RT5659_CKXEN_ADCC_MASK | RT5659_CKGEN_ADCC_MASK, 0);
1584 break;
1585
1586 default:
1587 return 0;
1588 }
1589
1590 return 0;
1591
1592}
1593
1594static int rt5659_charge_pump_event(struct snd_soc_dapm_widget *w,
1595 struct snd_kcontrol *kcontrol, int event)
1596{
1597 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1598
1599 switch (event) {
1600 case SND_SOC_DAPM_PRE_PMU:
1601 /* Depop */
1602 snd_soc_write(codec, RT5659_DEPOP_1, 0x0009);
1603 break;
1604 case SND_SOC_DAPM_POST_PMD:
1605 snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
1606 break;
1607 default:
1608 return 0;
1609 }
1610
1611 return 0;
1612}
1613
1614static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
1615 struct snd_soc_dapm_widget *sink)
1616{
1617 unsigned int val;
1618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1619
1620 val = snd_soc_read(codec, RT5659_GLB_CLK);
1621 val &= RT5659_SCLK_SRC_MASK;
1622 if (val == RT5659_SCLK_SRC_PLL1)
1623 return 1;
1624 else
1625 return 0;
1626}
1627
1628static int is_using_asrc(struct snd_soc_dapm_widget *w,
1629 struct snd_soc_dapm_widget *sink)
1630{
1631 unsigned int reg, shift, val;
1632 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1633
1634 switch (w->shift) {
1635 case RT5659_ADC_MONO_R_ASRC_SFT:
1636 reg = RT5659_ASRC_3;
1637 shift = RT5659_AD_MONO_R_T_SFT;
1638 break;
1639 case RT5659_ADC_MONO_L_ASRC_SFT:
1640 reg = RT5659_ASRC_3;
1641 shift = RT5659_AD_MONO_L_T_SFT;
1642 break;
1643 case RT5659_ADC_STO1_ASRC_SFT:
1644 reg = RT5659_ASRC_2;
1645 shift = RT5659_AD_STO1_T_SFT;
1646 break;
1647 case RT5659_DAC_MONO_R_ASRC_SFT:
1648 reg = RT5659_ASRC_2;
1649 shift = RT5659_DA_MONO_R_T_SFT;
1650 break;
1651 case RT5659_DAC_MONO_L_ASRC_SFT:
1652 reg = RT5659_ASRC_2;
1653 shift = RT5659_DA_MONO_L_T_SFT;
1654 break;
1655 case RT5659_DAC_STO_ASRC_SFT:
1656 reg = RT5659_ASRC_2;
1657 shift = RT5659_DA_STO_T_SFT;
1658 break;
1659 default:
1660 return 0;
1661 }
1662
1663 val = (snd_soc_read(codec, reg) >> shift) & 0xf;
1664 switch (val) {
1665 case 1:
1666 case 2:
1667 case 3:
1668 /* I2S_Pre_Div1 should be 1 in asrc mode */
1669 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
1670 RT5659_I2S_PD1_MASK, RT5659_I2S_PD1_2);
1671 return 1;
1672 default:
1673 return 0;
1674 }
1675
1676}
1677
1678/* Digital Mixer */
1679static const struct snd_kcontrol_new rt5659_sto1_adc_l_mix[] = {
1680 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_STO1_ADC_MIXER,
1681 RT5659_M_STO1_ADC_L1_SFT, 1, 1),
1682 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_STO1_ADC_MIXER,
1683 RT5659_M_STO1_ADC_L2_SFT, 1, 1),
1684};
1685
1686static const struct snd_kcontrol_new rt5659_sto1_adc_r_mix[] = {
1687 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_STO1_ADC_MIXER,
1688 RT5659_M_STO1_ADC_R1_SFT, 1, 1),
1689 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_STO1_ADC_MIXER,
1690 RT5659_M_STO1_ADC_R2_SFT, 1, 1),
1691};
1692
1693static const struct snd_kcontrol_new rt5659_mono_adc_l_mix[] = {
1694 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_MONO_ADC_MIXER,
1695 RT5659_M_MONO_ADC_L1_SFT, 1, 1),
1696 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_MONO_ADC_MIXER,
1697 RT5659_M_MONO_ADC_L2_SFT, 1, 1),
1698};
1699
1700static const struct snd_kcontrol_new rt5659_mono_adc_r_mix[] = {
1701 SOC_DAPM_SINGLE("ADC1 Switch", RT5659_MONO_ADC_MIXER,
1702 RT5659_M_MONO_ADC_R1_SFT, 1, 1),
1703 SOC_DAPM_SINGLE("ADC2 Switch", RT5659_MONO_ADC_MIXER,
1704 RT5659_M_MONO_ADC_R2_SFT, 1, 1),
1705};
1706
1707static const struct snd_kcontrol_new rt5659_dac_l_mix[] = {
1708 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5659_AD_DA_MIXER,
1709 RT5659_M_ADCMIX_L_SFT, 1, 1),
1710 SOC_DAPM_SINGLE("DAC1 Switch", RT5659_AD_DA_MIXER,
1711 RT5659_M_DAC1_L_SFT, 1, 1),
1712};
1713
1714static const struct snd_kcontrol_new rt5659_dac_r_mix[] = {
1715 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5659_AD_DA_MIXER,
1716 RT5659_M_ADCMIX_R_SFT, 1, 1),
1717 SOC_DAPM_SINGLE("DAC1 Switch", RT5659_AD_DA_MIXER,
1718 RT5659_M_DAC1_R_SFT, 1, 1),
1719};
1720
1721static const struct snd_kcontrol_new rt5659_sto_dac_l_mix[] = {
1722 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_STO_DAC_MIXER,
1723 RT5659_M_DAC_L1_STO_L_SFT, 1, 1),
1724 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_STO_DAC_MIXER,
1725 RT5659_M_DAC_R1_STO_L_SFT, 1, 1),
1726 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_STO_DAC_MIXER,
1727 RT5659_M_DAC_L2_STO_L_SFT, 1, 1),
1728 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_STO_DAC_MIXER,
1729 RT5659_M_DAC_R2_STO_L_SFT, 1, 1),
1730};
1731
1732static const struct snd_kcontrol_new rt5659_sto_dac_r_mix[] = {
1733 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_STO_DAC_MIXER,
1734 RT5659_M_DAC_L1_STO_R_SFT, 1, 1),
1735 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_STO_DAC_MIXER,
1736 RT5659_M_DAC_R1_STO_R_SFT, 1, 1),
1737 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_STO_DAC_MIXER,
1738 RT5659_M_DAC_L2_STO_R_SFT, 1, 1),
1739 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_STO_DAC_MIXER,
1740 RT5659_M_DAC_R2_STO_R_SFT, 1, 1),
1741};
1742
1743static const struct snd_kcontrol_new rt5659_mono_dac_l_mix[] = {
1744 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_MONO_DAC_MIXER,
1745 RT5659_M_DAC_L1_MONO_L_SFT, 1, 1),
1746 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_MONO_DAC_MIXER,
1747 RT5659_M_DAC_R1_MONO_L_SFT, 1, 1),
1748 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONO_DAC_MIXER,
1749 RT5659_M_DAC_L2_MONO_L_SFT, 1, 1),
1750 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONO_DAC_MIXER,
1751 RT5659_M_DAC_R2_MONO_L_SFT, 1, 1),
1752};
1753
1754static const struct snd_kcontrol_new rt5659_mono_dac_r_mix[] = {
1755 SOC_DAPM_SINGLE("DAC L1 Switch", RT5659_MONO_DAC_MIXER,
1756 RT5659_M_DAC_L1_MONO_R_SFT, 1, 1),
1757 SOC_DAPM_SINGLE("DAC R1 Switch", RT5659_MONO_DAC_MIXER,
1758 RT5659_M_DAC_R1_MONO_R_SFT, 1, 1),
1759 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONO_DAC_MIXER,
1760 RT5659_M_DAC_L2_MONO_R_SFT, 1, 1),
1761 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONO_DAC_MIXER,
1762 RT5659_M_DAC_R2_MONO_R_SFT, 1, 1),
1763};
1764
1765/* Analog Input Mixer */
1766static const struct snd_kcontrol_new rt5659_rec1_l_mix[] = {
1767 SOC_DAPM_SINGLE("SPKVOLL Switch", RT5659_REC1_L2_MIXER,
1768 RT5659_M_SPKVOLL_RM1_L_SFT, 1, 1),
1769 SOC_DAPM_SINGLE("INL Switch", RT5659_REC1_L2_MIXER,
1770 RT5659_M_INL_RM1_L_SFT, 1, 1),
1771 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC1_L2_MIXER,
1772 RT5659_M_BST4_RM1_L_SFT, 1, 1),
1773 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC1_L2_MIXER,
1774 RT5659_M_BST3_RM1_L_SFT, 1, 1),
1775 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC1_L2_MIXER,
1776 RT5659_M_BST2_RM1_L_SFT, 1, 1),
1777 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC1_L2_MIXER,
1778 RT5659_M_BST1_RM1_L_SFT, 1, 1),
1779};
1780
1781static const struct snd_kcontrol_new rt5659_rec1_r_mix[] = {
1782 SOC_DAPM_SINGLE("HPOVOLR Switch", RT5659_REC1_L2_MIXER,
1783 RT5659_M_HPOVOLR_RM1_R_SFT, 1, 1),
1784 SOC_DAPM_SINGLE("INR Switch", RT5659_REC1_R2_MIXER,
1785 RT5659_M_INR_RM1_R_SFT, 1, 1),
1786 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC1_R2_MIXER,
1787 RT5659_M_BST4_RM1_R_SFT, 1, 1),
1788 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC1_R2_MIXER,
1789 RT5659_M_BST3_RM1_R_SFT, 1, 1),
1790 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC1_R2_MIXER,
1791 RT5659_M_BST2_RM1_R_SFT, 1, 1),
1792 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC1_R2_MIXER,
1793 RT5659_M_BST1_RM1_R_SFT, 1, 1),
1794};
1795
1796static const struct snd_kcontrol_new rt5659_rec2_l_mix[] = {
1797 SOC_DAPM_SINGLE("SPKVOLL Switch", RT5659_REC2_L2_MIXER,
1798 RT5659_M_SPKVOL_RM2_L_SFT, 1, 1),
1799 SOC_DAPM_SINGLE("OUTVOLL Switch", RT5659_REC2_L2_MIXER,
1800 RT5659_M_OUTVOLL_RM2_L_SFT, 1, 1),
1801 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC2_L2_MIXER,
1802 RT5659_M_BST4_RM2_L_SFT, 1, 1),
1803 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC2_L2_MIXER,
1804 RT5659_M_BST3_RM2_L_SFT, 1, 1),
1805 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC2_L2_MIXER,
1806 RT5659_M_BST2_RM2_L_SFT, 1, 1),
1807 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC2_L2_MIXER,
1808 RT5659_M_BST1_RM2_L_SFT, 1, 1),
1809};
1810
1811static const struct snd_kcontrol_new rt5659_rec2_r_mix[] = {
1812 SOC_DAPM_SINGLE("MONOVOL Switch", RT5659_REC2_R2_MIXER,
1813 RT5659_M_MONOVOL_RM2_R_SFT, 1, 1),
1814 SOC_DAPM_SINGLE("OUTVOLR Switch", RT5659_REC2_R2_MIXER,
1815 RT5659_M_OUTVOLR_RM2_R_SFT, 1, 1),
1816 SOC_DAPM_SINGLE("BST4 Switch", RT5659_REC2_R2_MIXER,
1817 RT5659_M_BST4_RM2_R_SFT, 1, 1),
1818 SOC_DAPM_SINGLE("BST3 Switch", RT5659_REC2_R2_MIXER,
1819 RT5659_M_BST3_RM2_R_SFT, 1, 1),
1820 SOC_DAPM_SINGLE("BST2 Switch", RT5659_REC2_R2_MIXER,
1821 RT5659_M_BST2_RM2_R_SFT, 1, 1),
1822 SOC_DAPM_SINGLE("BST1 Switch", RT5659_REC2_R2_MIXER,
1823 RT5659_M_BST1_RM2_R_SFT, 1, 1),
1824};
1825
1826static const struct snd_kcontrol_new rt5659_spk_l_mix[] = {
1827 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_SPK_L_MIXER,
1828 RT5659_M_DAC_L2_SM_L_SFT, 1, 1),
1829 SOC_DAPM_SINGLE("BST1 Switch", RT5659_SPK_L_MIXER,
1830 RT5659_M_BST1_SM_L_SFT, 1, 1),
1831 SOC_DAPM_SINGLE("INL Switch", RT5659_SPK_L_MIXER,
1832 RT5659_M_IN_L_SM_L_SFT, 1, 1),
1833 SOC_DAPM_SINGLE("INR Switch", RT5659_SPK_L_MIXER,
1834 RT5659_M_IN_R_SM_L_SFT, 1, 1),
1835 SOC_DAPM_SINGLE("BST3 Switch", RT5659_SPK_L_MIXER,
1836 RT5659_M_BST3_SM_L_SFT, 1, 1),
1837};
1838
1839static const struct snd_kcontrol_new rt5659_spk_r_mix[] = {
1840 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_SPK_R_MIXER,
1841 RT5659_M_DAC_R2_SM_R_SFT, 1, 1),
1842 SOC_DAPM_SINGLE("BST4 Switch", RT5659_SPK_R_MIXER,
1843 RT5659_M_BST4_SM_R_SFT, 1, 1),
1844 SOC_DAPM_SINGLE("INL Switch", RT5659_SPK_R_MIXER,
1845 RT5659_M_IN_L_SM_R_SFT, 1, 1),
1846 SOC_DAPM_SINGLE("INR Switch", RT5659_SPK_R_MIXER,
1847 RT5659_M_IN_R_SM_R_SFT, 1, 1),
1848 SOC_DAPM_SINGLE("BST3 Switch", RT5659_SPK_R_MIXER,
1849 RT5659_M_BST3_SM_R_SFT, 1, 1),
1850};
1851
1852static const struct snd_kcontrol_new rt5659_monovol_mix[] = {
1853 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONOMIX_IN_GAIN,
1854 RT5659_M_DAC_L2_MM_SFT, 1, 1),
1855 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_MONOMIX_IN_GAIN,
1856 RT5659_M_DAC_R2_MM_SFT, 1, 1),
1857 SOC_DAPM_SINGLE("BST1 Switch", RT5659_MONOMIX_IN_GAIN,
1858 RT5659_M_BST1_MM_SFT, 1, 1),
1859 SOC_DAPM_SINGLE("BST2 Switch", RT5659_MONOMIX_IN_GAIN,
1860 RT5659_M_BST2_MM_SFT, 1, 1),
1861 SOC_DAPM_SINGLE("BST3 Switch", RT5659_MONOMIX_IN_GAIN,
1862 RT5659_M_BST3_MM_SFT, 1, 1),
1863};
1864
1865static const struct snd_kcontrol_new rt5659_out_l_mix[] = {
1866 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_OUT_L_MIXER,
1867 RT5659_M_DAC_L2_OM_L_SFT, 1, 1),
1868 SOC_DAPM_SINGLE("INL Switch", RT5659_OUT_L_MIXER,
1869 RT5659_M_IN_L_OM_L_SFT, 1, 1),
1870 SOC_DAPM_SINGLE("BST1 Switch", RT5659_OUT_L_MIXER,
1871 RT5659_M_BST1_OM_L_SFT, 1, 1),
1872 SOC_DAPM_SINGLE("BST2 Switch", RT5659_OUT_L_MIXER,
1873 RT5659_M_BST2_OM_L_SFT, 1, 1),
1874 SOC_DAPM_SINGLE("BST3 Switch", RT5659_OUT_L_MIXER,
1875 RT5659_M_BST3_OM_L_SFT, 1, 1),
1876};
1877
1878static const struct snd_kcontrol_new rt5659_out_r_mix[] = {
1879 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_OUT_R_MIXER,
1880 RT5659_M_DAC_R2_OM_R_SFT, 1, 1),
1881 SOC_DAPM_SINGLE("INR Switch", RT5659_OUT_R_MIXER,
1882 RT5659_M_IN_R_OM_R_SFT, 1, 1),
1883 SOC_DAPM_SINGLE("BST2 Switch", RT5659_OUT_R_MIXER,
1884 RT5659_M_BST2_OM_R_SFT, 1, 1),
1885 SOC_DAPM_SINGLE("BST3 Switch", RT5659_OUT_R_MIXER,
1886 RT5659_M_BST3_OM_R_SFT, 1, 1),
1887 SOC_DAPM_SINGLE("BST4 Switch", RT5659_OUT_R_MIXER,
1888 RT5659_M_BST4_OM_R_SFT, 1, 1),
1889};
1890
1891static const struct snd_kcontrol_new rt5659_spo_l_mix[] = {
1892 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_SPO_AMP_GAIN,
1893 RT5659_M_DAC_L2_SPKOMIX_SFT, 1, 0),
1894 SOC_DAPM_SINGLE("SPKVOL L Switch", RT5659_SPO_AMP_GAIN,
1895 RT5659_M_SPKVOLL_SPKOMIX_SFT, 1, 0),
1896};
1897
1898static const struct snd_kcontrol_new rt5659_spo_r_mix[] = {
1899 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_SPO_AMP_GAIN,
1900 RT5659_M_DAC_R2_SPKOMIX_SFT, 1, 0),
1901 SOC_DAPM_SINGLE("SPKVOL R Switch", RT5659_SPO_AMP_GAIN,
1902 RT5659_M_SPKVOLR_SPKOMIX_SFT, 1, 0),
1903};
1904
1905static const struct snd_kcontrol_new rt5659_mono_mix[] = {
1906 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_MONOMIX_IN_GAIN,
1907 RT5659_M_DAC_L2_MA_SFT, 1, 1),
1908 SOC_DAPM_SINGLE("MONOVOL Switch", RT5659_MONOMIX_IN_GAIN,
1909 RT5659_M_MONOVOL_MA_SFT, 1, 1),
1910};
1911
1912static const struct snd_kcontrol_new rt5659_lout_l_mix[] = {
1913 SOC_DAPM_SINGLE("DAC L2 Switch", RT5659_LOUT_MIXER,
1914 RT5659_M_DAC_L2_LM_SFT, 1, 1),
1915 SOC_DAPM_SINGLE("OUTVOL L Switch", RT5659_LOUT_MIXER,
1916 RT5659_M_OV_L_LM_SFT, 1, 1),
1917};
1918
1919static const struct snd_kcontrol_new rt5659_lout_r_mix[] = {
1920 SOC_DAPM_SINGLE("DAC R2 Switch", RT5659_LOUT_MIXER,
1921 RT5659_M_DAC_R2_LM_SFT, 1, 1),
1922 SOC_DAPM_SINGLE("OUTVOL R Switch", RT5659_LOUT_MIXER,
1923 RT5659_M_OV_R_LM_SFT, 1, 1),
1924};
1925
1926/*DAC L2, DAC R2*/
1927/*MX-1B [6:4], MX-1B [2:0]*/
1928static const char * const rt5659_dac2_src[] = {
1929 "IF1 DAC2", "IF2 DAC", "IF3 DAC", "Mono ADC MIX"
1930};
1931
1932static const SOC_ENUM_SINGLE_DECL(
1933 rt5659_dac_l2_enum, RT5659_DAC_CTRL,
1934 RT5659_DAC_L2_SEL_SFT, rt5659_dac2_src);
1935
1936static const struct snd_kcontrol_new rt5659_dac_l2_mux =
1937 SOC_DAPM_ENUM("DAC L2 Source", rt5659_dac_l2_enum);
1938
1939static const SOC_ENUM_SINGLE_DECL(
1940 rt5659_dac_r2_enum, RT5659_DAC_CTRL,
1941 RT5659_DAC_R2_SEL_SFT, rt5659_dac2_src);
1942
1943static const struct snd_kcontrol_new rt5659_dac_r2_mux =
1944 SOC_DAPM_ENUM("DAC R2 Source", rt5659_dac_r2_enum);
1945
1946
1947/* STO1 ADC1 Source */
1948/* MX-26 [13] */
1949static const char * const rt5659_sto1_adc1_src[] = {
1950 "DAC MIX", "ADC"
1951};
1952
1953static const SOC_ENUM_SINGLE_DECL(
1954 rt5659_sto1_adc1_enum, RT5659_STO1_ADC_MIXER,
1955 RT5659_STO1_ADC1_SRC_SFT, rt5659_sto1_adc1_src);
1956
1957static const struct snd_kcontrol_new rt5659_sto1_adc1_mux =
1958 SOC_DAPM_ENUM("Stereo1 ADC1 Source", rt5659_sto1_adc1_enum);
1959
1960/* STO1 ADC Source */
1961/* MX-26 [12] */
1962static const char * const rt5659_sto1_adc_src[] = {
1963 "ADC1", "ADC2"
1964};
1965
1966static const SOC_ENUM_SINGLE_DECL(
1967 rt5659_sto1_adc_enum, RT5659_STO1_ADC_MIXER,
1968 RT5659_STO1_ADC_SRC_SFT, rt5659_sto1_adc_src);
1969
1970static const struct snd_kcontrol_new rt5659_sto1_adc_mux =
1971 SOC_DAPM_ENUM("Stereo1 ADC Source", rt5659_sto1_adc_enum);
1972
1973/* STO1 ADC2 Source */
1974/* MX-26 [11] */
1975static const char * const rt5659_sto1_adc2_src[] = {
1976 "DAC MIX", "DMIC"
1977};
1978
1979static const SOC_ENUM_SINGLE_DECL(
1980 rt5659_sto1_adc2_enum, RT5659_STO1_ADC_MIXER,
1981 RT5659_STO1_ADC2_SRC_SFT, rt5659_sto1_adc2_src);
1982
1983static const struct snd_kcontrol_new rt5659_sto1_adc2_mux =
1984 SOC_DAPM_ENUM("Stereo1 ADC2 Source", rt5659_sto1_adc2_enum);
1985
1986/* STO1 DMIC Source */
1987/* MX-26 [8] */
1988static const char * const rt5659_sto1_dmic_src[] = {
1989 "DMIC1", "DMIC2"
1990};
1991
1992static const SOC_ENUM_SINGLE_DECL(
1993 rt5659_sto1_dmic_enum, RT5659_STO1_ADC_MIXER,
1994 RT5659_STO1_DMIC_SRC_SFT, rt5659_sto1_dmic_src);
1995
1996static const struct snd_kcontrol_new rt5659_sto1_dmic_mux =
1997 SOC_DAPM_ENUM("Stereo1 DMIC Source", rt5659_sto1_dmic_enum);
1998
1999
2000/* MONO ADC L2 Source */
2001/* MX-27 [12] */
2002static const char * const rt5659_mono_adc_l2_src[] = {
2003 "Mono DAC MIXL", "DMIC"
2004};
2005
2006static const SOC_ENUM_SINGLE_DECL(
2007 rt5659_mono_adc_l2_enum, RT5659_MONO_ADC_MIXER,
2008 RT5659_MONO_ADC_L2_SRC_SFT, rt5659_mono_adc_l2_src);
2009
2010static const struct snd_kcontrol_new rt5659_mono_adc_l2_mux =
2011 SOC_DAPM_ENUM("Mono ADC L2 Source", rt5659_mono_adc_l2_enum);
2012
2013
2014/* MONO ADC L1 Source */
2015/* MX-27 [11] */
2016static const char * const rt5659_mono_adc_l1_src[] = {
2017 "Mono DAC MIXL", "ADC"
2018};
2019
2020static const SOC_ENUM_SINGLE_DECL(
2021 rt5659_mono_adc_l1_enum, RT5659_MONO_ADC_MIXER,
2022 RT5659_MONO_ADC_L1_SRC_SFT, rt5659_mono_adc_l1_src);
2023
2024static const struct snd_kcontrol_new rt5659_mono_adc_l1_mux =
2025 SOC_DAPM_ENUM("Mono ADC L1 Source", rt5659_mono_adc_l1_enum);
2026
2027/* MONO ADC L Source, MONO ADC R Source*/
2028/* MX-27 [10:9], MX-27 [2:1] */
2029static const char * const rt5659_mono_adc_src[] = {
2030 "ADC1 L", "ADC1 R", "ADC2 L", "ADC2 R"
2031};
2032
2033static const SOC_ENUM_SINGLE_DECL(
2034 rt5659_mono_adc_l_enum, RT5659_MONO_ADC_MIXER,
2035 RT5659_MONO_ADC_L_SRC_SFT, rt5659_mono_adc_src);
2036
2037static const struct snd_kcontrol_new rt5659_mono_adc_l_mux =
2038 SOC_DAPM_ENUM("Mono ADC L Source", rt5659_mono_adc_l_enum);
2039
2040static const SOC_ENUM_SINGLE_DECL(
2041 rt5659_mono_adcr_enum, RT5659_MONO_ADC_MIXER,
2042 RT5659_MONO_ADC_R_SRC_SFT, rt5659_mono_adc_src);
2043
2044static const struct snd_kcontrol_new rt5659_mono_adc_r_mux =
2045 SOC_DAPM_ENUM("Mono ADC R Source", rt5659_mono_adcr_enum);
2046
2047/* MONO DMIC L Source */
2048/* MX-27 [8] */
2049static const char * const rt5659_mono_dmic_l_src[] = {
2050 "DMIC1 L", "DMIC2 L"
2051};
2052
2053static const SOC_ENUM_SINGLE_DECL(
2054 rt5659_mono_dmic_l_enum, RT5659_MONO_ADC_MIXER,
2055 RT5659_MONO_DMIC_L_SRC_SFT, rt5659_mono_dmic_l_src);
2056
2057static const struct snd_kcontrol_new rt5659_mono_dmic_l_mux =
2058 SOC_DAPM_ENUM("Mono DMIC L Source", rt5659_mono_dmic_l_enum);
2059
2060/* MONO ADC R2 Source */
2061/* MX-27 [4] */
2062static const char * const rt5659_mono_adc_r2_src[] = {
2063 "Mono DAC MIXR", "DMIC"
2064};
2065
2066static const SOC_ENUM_SINGLE_DECL(
2067 rt5659_mono_adc_r2_enum, RT5659_MONO_ADC_MIXER,
2068 RT5659_MONO_ADC_R2_SRC_SFT, rt5659_mono_adc_r2_src);
2069
2070static const struct snd_kcontrol_new rt5659_mono_adc_r2_mux =
2071 SOC_DAPM_ENUM("Mono ADC R2 Source", rt5659_mono_adc_r2_enum);
2072
2073/* MONO ADC R1 Source */
2074/* MX-27 [3] */
2075static const char * const rt5659_mono_adc_r1_src[] = {
2076 "Mono DAC MIXR", "ADC"
2077};
2078
2079static const SOC_ENUM_SINGLE_DECL(
2080 rt5659_mono_adc_r1_enum, RT5659_MONO_ADC_MIXER,
2081 RT5659_MONO_ADC_R1_SRC_SFT, rt5659_mono_adc_r1_src);
2082
2083static const struct snd_kcontrol_new rt5659_mono_adc_r1_mux =
2084 SOC_DAPM_ENUM("Mono ADC R1 Source", rt5659_mono_adc_r1_enum);
2085
2086/* MONO DMIC R Source */
2087/* MX-27 [0] */
2088static const char * const rt5659_mono_dmic_r_src[] = {
2089 "DMIC1 R", "DMIC2 R"
2090};
2091
2092static const SOC_ENUM_SINGLE_DECL(
2093 rt5659_mono_dmic_r_enum, RT5659_MONO_ADC_MIXER,
2094 RT5659_MONO_DMIC_R_SRC_SFT, rt5659_mono_dmic_r_src);
2095
2096static const struct snd_kcontrol_new rt5659_mono_dmic_r_mux =
2097 SOC_DAPM_ENUM("Mono DMIC R Source", rt5659_mono_dmic_r_enum);
2098
2099
2100/* DAC R1 Source, DAC L1 Source*/
2101/* MX-29 [11:10], MX-29 [9:8]*/
2102static const char * const rt5659_dac1_src[] = {
2103 "IF1 DAC1", "IF2 DAC", "IF3 DAC"
2104};
2105
2106static const SOC_ENUM_SINGLE_DECL(
2107 rt5659_dac_r1_enum, RT5659_AD_DA_MIXER,
2108 RT5659_DAC1_R_SEL_SFT, rt5659_dac1_src);
2109
2110static const struct snd_kcontrol_new rt5659_dac_r1_mux =
2111 SOC_DAPM_ENUM("DAC R1 Source", rt5659_dac_r1_enum);
2112
2113static const SOC_ENUM_SINGLE_DECL(
2114 rt5659_dac_l1_enum, RT5659_AD_DA_MIXER,
2115 RT5659_DAC1_L_SEL_SFT, rt5659_dac1_src);
2116
2117static const struct snd_kcontrol_new rt5659_dac_l1_mux =
2118 SOC_DAPM_ENUM("DAC L1 Source", rt5659_dac_l1_enum);
2119
2120/* DAC Digital Mixer L Source, DAC Digital Mixer R Source*/
2121/* MX-2C [6], MX-2C [4]*/
2122static const char * const rt5659_dig_dac_mix_src[] = {
2123 "Stereo DAC Mixer", "Mono DAC Mixer"
2124};
2125
2126static const SOC_ENUM_SINGLE_DECL(
2127 rt5659_dig_dac_mixl_enum, RT5659_DIG_MIXER,
2128 RT5659_DAC_MIX_L_SFT, rt5659_dig_dac_mix_src);
2129
2130static const struct snd_kcontrol_new rt5659_dig_dac_mixl_mux =
2131 SOC_DAPM_ENUM("DAC Digital Mixer L Source", rt5659_dig_dac_mixl_enum);
2132
2133static const SOC_ENUM_SINGLE_DECL(
2134 rt5659_dig_dac_mixr_enum, RT5659_DIG_MIXER,
2135 RT5659_DAC_MIX_R_SFT, rt5659_dig_dac_mix_src);
2136
2137static const struct snd_kcontrol_new rt5659_dig_dac_mixr_mux =
2138 SOC_DAPM_ENUM("DAC Digital Mixer R Source", rt5659_dig_dac_mixr_enum);
2139
2140/* Analog DAC L1 Source, Analog DAC R1 Source*/
2141/* MX-2D [3], MX-2D [2]*/
2142static const char * const rt5659_alg_dac1_src[] = {
2143 "DAC", "Stereo DAC Mixer"
2144};
2145
2146static const SOC_ENUM_SINGLE_DECL(
2147 rt5659_alg_dac_l1_enum, RT5659_A_DAC_MUX,
2148 RT5659_A_DACL1_SFT, rt5659_alg_dac1_src);
2149
2150static const struct snd_kcontrol_new rt5659_alg_dac_l1_mux =
2151 SOC_DAPM_ENUM("Analog DACL1 Source", rt5659_alg_dac_l1_enum);
2152
2153static const SOC_ENUM_SINGLE_DECL(
2154 rt5659_alg_dac_r1_enum, RT5659_A_DAC_MUX,
2155 RT5659_A_DACR1_SFT, rt5659_alg_dac1_src);
2156
2157static const struct snd_kcontrol_new rt5659_alg_dac_r1_mux =
2158 SOC_DAPM_ENUM("Analog DACR1 Source", rt5659_alg_dac_r1_enum);
2159
2160/* Analog DAC LR Source, Analog DAC R2 Source*/
2161/* MX-2D [1], MX-2D [0]*/
2162static const char * const rt5659_alg_dac2_src[] = {
2163 "Stereo DAC Mixer", "Mono DAC Mixer"
2164};
2165
2166static const SOC_ENUM_SINGLE_DECL(
2167 rt5659_alg_dac_l2_enum, RT5659_A_DAC_MUX,
2168 RT5659_A_DACL2_SFT, rt5659_alg_dac2_src);
2169
2170static const struct snd_kcontrol_new rt5659_alg_dac_l2_mux =
2171 SOC_DAPM_ENUM("Analog DAC L2 Source", rt5659_alg_dac_l2_enum);
2172
2173static const SOC_ENUM_SINGLE_DECL(
2174 rt5659_alg_dac_r2_enum, RT5659_A_DAC_MUX,
2175 RT5659_A_DACR2_SFT, rt5659_alg_dac2_src);
2176
2177static const struct snd_kcontrol_new rt5659_alg_dac_r2_mux =
2178 SOC_DAPM_ENUM("Analog DAC R2 Source", rt5659_alg_dac_r2_enum);
2179
2180/* Interface2 ADC Data Input*/
2181/* MX-2F [13:12] */
2182static const char * const rt5659_if2_adc_in_src[] = {
2183 "IF_ADC1", "IF_ADC2", "DAC_REF", "IF_ADC3"
2184};
2185
2186static const SOC_ENUM_SINGLE_DECL(
2187 rt5659_if2_adc_in_enum, RT5659_DIG_INF23_DATA,
2188 RT5659_IF2_ADC_IN_SFT, rt5659_if2_adc_in_src);
2189
2190static const struct snd_kcontrol_new rt5659_if2_adc_in_mux =
2191 SOC_DAPM_ENUM("IF2 ADC IN Source", rt5659_if2_adc_in_enum);
2192
2193/* Interface3 ADC Data Input*/
2194/* MX-2F [1:0] */
2195static const char * const rt5659_if3_adc_in_src[] = {
2196 "IF_ADC1", "IF_ADC2", "DAC_REF", "Stereo2_ADC_L/R"
2197};
2198
2199static const SOC_ENUM_SINGLE_DECL(
2200 rt5659_if3_adc_in_enum, RT5659_DIG_INF23_DATA,
2201 RT5659_IF3_ADC_IN_SFT, rt5659_if3_adc_in_src);
2202
2203static const struct snd_kcontrol_new rt5659_if3_adc_in_mux =
2204 SOC_DAPM_ENUM("IF3 ADC IN Source", rt5659_if3_adc_in_enum);
2205
2206/* PDM 1 L/R*/
2207/* MX-31 [15] [13] */
2208static const char * const rt5659_pdm_src[] = {
2209 "Mono DAC", "Stereo DAC"
2210};
2211
2212static const SOC_ENUM_SINGLE_DECL(
2213 rt5659_pdm_l_enum, RT5659_PDM_OUT_CTRL,
2214 RT5659_PDM1_L_SFT, rt5659_pdm_src);
2215
2216static const struct snd_kcontrol_new rt5659_pdm_l_mux =
2217 SOC_DAPM_ENUM("PDM L Source", rt5659_pdm_l_enum);
2218
2219static const SOC_ENUM_SINGLE_DECL(
2220 rt5659_pdm_r_enum, RT5659_PDM_OUT_CTRL,
2221 RT5659_PDM1_R_SFT, rt5659_pdm_src);
2222
2223static const struct snd_kcontrol_new rt5659_pdm_r_mux =
2224 SOC_DAPM_ENUM("PDM R Source", rt5659_pdm_r_enum);
2225
2226/* SPDIF Output source*/
2227/* MX-36 [1:0] */
2228static const char * const rt5659_spdif_src[] = {
2229 "IF1_DAC1", "IF1_DAC2", "IF2_DAC", "IF3_DAC"
2230};
2231
2232static const SOC_ENUM_SINGLE_DECL(
2233 rt5659_spdif_enum, RT5659_SPDIF_CTRL,
2234 RT5659_SPDIF_SEL_SFT, rt5659_spdif_src);
2235
2236static const struct snd_kcontrol_new rt5659_spdif_mux =
2237 SOC_DAPM_ENUM("SPDIF Source", rt5659_spdif_enum);
2238
2239/* I2S1 TDM ADCDAT Source */
2240/* MX-78[4:0] */
2241static const char * const rt5659_rx_adc_data_src[] = {
2242 "AD1:AD2:DAC:NUL", "AD1:AD2:NUL:DAC", "AD1:DAC:AD2:NUL",
2243 "AD1:DAC:NUL:AD2", "AD1:NUL:DAC:AD2", "AD1:NUL:AD2:DAC",
2244 "AD2:AD1:DAC:NUL", "AD2:AD1:NUL:DAC", "AD2:DAC:AD1:NUL",
2245 "AD2:DAC:NUL:AD1", "AD2:NUL:DAC:AD1", "AD1:NUL:AD1:DAC",
2246 "DAC:AD1:AD2:NUL", "DAC:AD1:NUL:AD2", "DAC:AD2:AD1:NUL",
2247 "DAC:AD2:NUL:AD1", "DAC:NUL:DAC:AD2", "DAC:NUL:AD2:DAC",
2248 "NUL:AD1:AD2:DAC", "NUL:AD1:DAC:AD2", "NUL:AD2:AD1:DAC",
2249 "NUL:AD2:DAC:AD1", "NUL:DAC:DAC:AD2", "NUL:DAC:AD2:DAC"
2250};
2251
2252static const SOC_ENUM_SINGLE_DECL(
2253 rt5659_rx_adc_data_enum, RT5659_TDM_CTRL_2,
2254 RT5659_ADCDAT_SRC_SFT, rt5659_rx_adc_data_src);
2255
2256static const struct snd_kcontrol_new rt5659_rx_adc_dac_mux =
2257 SOC_DAPM_ENUM("TDM ADCDAT Source", rt5659_rx_adc_data_enum);
2258
2259/* Out Volume Switch */
2260static const struct snd_kcontrol_new spkvol_l_switch =
2261 SOC_DAPM_SINGLE("Switch", RT5659_SPO_VOL, RT5659_VOL_L_SFT, 1, 1);
2262
2263static const struct snd_kcontrol_new spkvol_r_switch =
2264 SOC_DAPM_SINGLE("Switch", RT5659_SPO_VOL, RT5659_VOL_R_SFT, 1, 1);
2265
2266static const struct snd_kcontrol_new monovol_switch =
2267 SOC_DAPM_SINGLE("Switch", RT5659_MONO_OUT, RT5659_VOL_L_SFT, 1, 1);
2268
2269static const struct snd_kcontrol_new outvol_l_switch =
2270 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_VOL_L_SFT, 1, 1);
2271
2272static const struct snd_kcontrol_new outvol_r_switch =
2273 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_VOL_R_SFT, 1, 1);
2274
2275/* Out Switch */
2276static const struct snd_kcontrol_new spo_switch =
2277 SOC_DAPM_SINGLE("Switch", RT5659_CLASSD_2, RT5659_M_RF_DIG_SFT, 1, 1);
2278
2279static const struct snd_kcontrol_new mono_switch =
2280 SOC_DAPM_SINGLE("Switch", RT5659_MONO_OUT, RT5659_L_MUTE_SFT, 1, 1);
2281
2282static const struct snd_kcontrol_new hpo_l_switch =
2283 SOC_DAPM_SINGLE("Switch", RT5659_HP_VOL, RT5659_L_MUTE_SFT, 1, 1);
2284
2285static const struct snd_kcontrol_new hpo_r_switch =
2286 SOC_DAPM_SINGLE("Switch", RT5659_HP_VOL, RT5659_R_MUTE_SFT, 1, 1);
2287
2288static const struct snd_kcontrol_new lout_l_switch =
2289 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_L_MUTE_SFT, 1, 1);
2290
2291static const struct snd_kcontrol_new lout_r_switch =
2292 SOC_DAPM_SINGLE("Switch", RT5659_LOUT, RT5659_R_MUTE_SFT, 1, 1);
2293
2294static const struct snd_kcontrol_new pdm_l_switch =
2295 SOC_DAPM_SINGLE("Switch", RT5659_PDM_OUT_CTRL, RT5659_M_PDM1_L_SFT, 1,
2296 1);
2297
2298static const struct snd_kcontrol_new pdm_r_switch =
2299 SOC_DAPM_SINGLE("Switch", RT5659_PDM_OUT_CTRL, RT5659_M_PDM1_R_SFT, 1,
2300 1);
2301
2302static int rt5659_spk_event(struct snd_soc_dapm_widget *w,
2303 struct snd_kcontrol *kcontrol, int event)
2304{
2305 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2306
2307 switch (event) {
2308 case SND_SOC_DAPM_PRE_PMU:
2309 snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
2310 RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_EN);
2311 snd_soc_update_bits(codec, RT5659_CLASSD_2,
2312 RT5659_M_RI_DIG, RT5659_M_RI_DIG);
2313 snd_soc_write(codec, RT5659_CLASSD_1, 0x0803);
2314 snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
2315 break;
2316
2317 case SND_SOC_DAPM_POST_PMD:
2318 snd_soc_write(codec, RT5659_CLASSD_1, 0x0011);
2319 snd_soc_update_bits(codec, RT5659_CLASSD_2,
2320 RT5659_M_RI_DIG, 0x0);
2321 snd_soc_write(codec, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
2322 snd_soc_update_bits(codec, RT5659_CLASSD_CTRL_1,
2323 RT5659_POW_CLSD_DB_MASK, RT5659_POW_CLSD_DB_DIS);
2324 break;
2325
2326 default:
2327 return 0;
2328 }
2329
2330 return 0;
2331
2332}
2333
2334static int rt5659_mono_event(struct snd_soc_dapm_widget *w,
2335 struct snd_kcontrol *kcontrol, int event)
2336{
2337 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2338
2339 switch (event) {
2340 case SND_SOC_DAPM_PRE_PMU:
2341 snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
2342 break;
2343
2344 case SND_SOC_DAPM_POST_PMD:
2345 snd_soc_write(codec, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
2346 break;
2347
2348 default:
2349 return 0;
2350 }
2351
2352 return 0;
2353
2354}
2355
2356static int rt5659_hp_event(struct snd_soc_dapm_widget *w,
2357 struct snd_kcontrol *kcontrol, int event)
2358{
2359 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2360
2361 switch (event) {
2362 case SND_SOC_DAPM_POST_PMU:
2363 snd_soc_write(codec, RT5659_HP_CHARGE_PUMP_1, 0x0e1e);
2364 snd_soc_update_bits(codec, RT5659_DEPOP_1, 0x0010, 0x0010);
2365 break;
2366
2367 case SND_SOC_DAPM_PRE_PMD:
2368 snd_soc_write(codec, RT5659_DEPOP_1, 0x0000);
2369 break;
2370
2371 default:
2372 return 0;
2373 }
2374
2375 return 0;
2376}
2377
2378static int set_dmic_power(struct snd_soc_dapm_widget *w,
2379 struct snd_kcontrol *kcontrol, int event)
2380{
2381 switch (event) {
2382 case SND_SOC_DAPM_POST_PMU:
2383 /*Add delay to avoid pop noise*/
2384 msleep(450);
2385 break;
2386
2387 default:
2388 return 0;
2389 }
2390
2391 return 0;
2392}
2393
2394static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
2395 SND_SOC_DAPM_SUPPLY("LDO2", RT5659_PWR_ANLG_3, RT5659_PWR_LDO2_BIT, 0,
2396 NULL, 0),
2397 SND_SOC_DAPM_SUPPLY("PLL", RT5659_PWR_ANLG_3, RT5659_PWR_PLL_BIT, 0,
2398 NULL, 0),
2399 SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5659_PWR_VOL,
2400 RT5659_PWR_MIC_DET_BIT, 0, NULL, 0),
2401 SND_SOC_DAPM_SUPPLY("Mono Vref", RT5659_PWR_ANLG_1,
2402 RT5659_PWR_VREF3_BIT, 0, NULL, 0),
2403
2404 /* ASRC */
2405 SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5659_ASRC_1,
2406 RT5659_I2S1_ASRC_SFT, 0, NULL, 0),
2407 SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5659_ASRC_1,
2408 RT5659_I2S2_ASRC_SFT, 0, NULL, 0),
2409 SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5659_ASRC_1,
2410 RT5659_I2S3_ASRC_SFT, 0, NULL, 0),
2411 SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5659_ASRC_1,
2412 RT5659_DAC_STO_ASRC_SFT, 0, NULL, 0),
2413 SND_SOC_DAPM_SUPPLY_S("DAC Mono L ASRC", 1, RT5659_ASRC_1,
2414 RT5659_DAC_MONO_L_ASRC_SFT, 0, NULL, 0),
2415 SND_SOC_DAPM_SUPPLY_S("DAC Mono R ASRC", 1, RT5659_ASRC_1,
2416 RT5659_DAC_MONO_R_ASRC_SFT, 0, NULL, 0),
2417 SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5659_ASRC_1,
2418 RT5659_ADC_STO1_ASRC_SFT, 0, NULL, 0),
2419 SND_SOC_DAPM_SUPPLY_S("ADC Mono L ASRC", 1, RT5659_ASRC_1,
2420 RT5659_ADC_MONO_L_ASRC_SFT, 0, NULL, 0),
2421 SND_SOC_DAPM_SUPPLY_S("ADC Mono R ASRC", 1, RT5659_ASRC_1,
2422 RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0),
2423
2424 /* Input Side */
2425 SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5659_PWR_ANLG_2, RT5659_PWR_MB1_BIT,
2426 0, NULL, 0),
2427 SND_SOC_DAPM_SUPPLY("MICBIAS2", RT5659_PWR_ANLG_2, RT5659_PWR_MB2_BIT,
2428 0, NULL, 0),
2429 SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT,
2430 0, NULL, 0),
2431
2432 /* Input Lines */
2433 SND_SOC_DAPM_INPUT("DMIC L1"),
2434 SND_SOC_DAPM_INPUT("DMIC R1"),
2435 SND_SOC_DAPM_INPUT("DMIC L2"),
2436 SND_SOC_DAPM_INPUT("DMIC R2"),
2437
2438 SND_SOC_DAPM_INPUT("IN1P"),
2439 SND_SOC_DAPM_INPUT("IN1N"),
2440 SND_SOC_DAPM_INPUT("IN2P"),
2441 SND_SOC_DAPM_INPUT("IN2N"),
2442 SND_SOC_DAPM_INPUT("IN3P"),
2443 SND_SOC_DAPM_INPUT("IN3N"),
2444 SND_SOC_DAPM_INPUT("IN4P"),
2445 SND_SOC_DAPM_INPUT("IN4N"),
2446
2447 SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2448 SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2449
2450 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
2451 set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
2452 SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5659_DMIC_CTRL_1,
2453 RT5659_DMIC_1_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
2454 SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5659_DMIC_CTRL_1,
2455 RT5659_DMIC_2_EN_SFT, 0, set_dmic_power, SND_SOC_DAPM_POST_PMU),
2456
2457 /* Boost */
2458 SND_SOC_DAPM_PGA("BST1", RT5659_PWR_ANLG_2,
2459 RT5659_PWR_BST1_P_BIT, 0, NULL, 0),
2460 SND_SOC_DAPM_PGA("BST2", RT5659_PWR_ANLG_2,
2461 RT5659_PWR_BST2_P_BIT, 0, NULL, 0),
2462 SND_SOC_DAPM_PGA("BST3", RT5659_PWR_ANLG_2,
2463 RT5659_PWR_BST3_P_BIT, 0, NULL, 0),
2464 SND_SOC_DAPM_PGA("BST4", RT5659_PWR_ANLG_2,
2465 RT5659_PWR_BST4_P_BIT, 0, NULL, 0),
2466 SND_SOC_DAPM_SUPPLY("BST1 Power", RT5659_PWR_ANLG_2,
2467 RT5659_PWR_BST1_BIT, 0, NULL, 0),
2468 SND_SOC_DAPM_SUPPLY("BST2 Power", RT5659_PWR_ANLG_2,
2469 RT5659_PWR_BST2_BIT, 0, NULL, 0),
2470 SND_SOC_DAPM_SUPPLY("BST3 Power", RT5659_PWR_ANLG_2,
2471 RT5659_PWR_BST3_BIT, 0, NULL, 0),
2472 SND_SOC_DAPM_SUPPLY("BST4 Power", RT5659_PWR_ANLG_2,
2473 RT5659_PWR_BST4_BIT, 0, NULL, 0),
2474
2475
2476 /* Input Volume */
2477 SND_SOC_DAPM_PGA("INL VOL", RT5659_PWR_VOL, RT5659_PWR_IN_L_BIT,
2478 0, NULL, 0),
2479 SND_SOC_DAPM_PGA("INR VOL", RT5659_PWR_VOL, RT5659_PWR_IN_R_BIT,
2480 0, NULL, 0),
2481
2482 /* REC Mixer */
2483 SND_SOC_DAPM_MIXER("RECMIX1L", RT5659_PWR_MIXER, RT5659_PWR_RM1_L_BIT,
2484 0, rt5659_rec1_l_mix, ARRAY_SIZE(rt5659_rec1_l_mix)),
2485 SND_SOC_DAPM_MIXER("RECMIX1R", RT5659_PWR_MIXER, RT5659_PWR_RM1_R_BIT,
2486 0, rt5659_rec1_r_mix, ARRAY_SIZE(rt5659_rec1_r_mix)),
2487 SND_SOC_DAPM_MIXER("RECMIX2L", RT5659_PWR_MIXER, RT5659_PWR_RM2_L_BIT,
2488 0, rt5659_rec2_l_mix, ARRAY_SIZE(rt5659_rec2_l_mix)),
2489 SND_SOC_DAPM_MIXER("RECMIX2R", RT5659_PWR_MIXER, RT5659_PWR_RM2_R_BIT,
2490 0, rt5659_rec2_r_mix, ARRAY_SIZE(rt5659_rec2_r_mix)),
2491
2492 /* ADCs */
2493 SND_SOC_DAPM_ADC("ADC1 L", NULL, SND_SOC_NOPM, 0, 0),
2494 SND_SOC_DAPM_ADC("ADC1 R", NULL, SND_SOC_NOPM, 0, 0),
2495 SND_SOC_DAPM_ADC("ADC2 L", NULL, SND_SOC_NOPM, 0, 0),
2496 SND_SOC_DAPM_ADC("ADC2 R", NULL, SND_SOC_NOPM, 0, 0),
2497
2498 SND_SOC_DAPM_SUPPLY("ADC1 L Power", RT5659_PWR_DIG_1,
2499 RT5659_PWR_ADC_L1_BIT, 0, NULL, 0),
2500 SND_SOC_DAPM_SUPPLY("ADC1 R Power", RT5659_PWR_DIG_1,
2501 RT5659_PWR_ADC_R1_BIT, 0, NULL, 0),
2502 SND_SOC_DAPM_SUPPLY("ADC2 L Power", RT5659_PWR_DIG_2,
2503 RT5659_PWR_ADC_L2_BIT, 0, NULL, 0),
2504 SND_SOC_DAPM_SUPPLY("ADC2 R Power", RT5659_PWR_DIG_2,
2505 RT5659_PWR_ADC_R2_BIT, 0, NULL, 0),
2506 SND_SOC_DAPM_SUPPLY("ADC1 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
2507 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2508 SND_SOC_DAPM_SUPPLY("ADC2 clock", SND_SOC_NOPM, 0, 0, set_adc_clk,
2509 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2510
2511 /* ADC Mux */
2512 SND_SOC_DAPM_MUX("Stereo1 DMIC L Mux", SND_SOC_NOPM, 0, 0,
2513 &rt5659_sto1_dmic_mux),
2514 SND_SOC_DAPM_MUX("Stereo1 DMIC R Mux", SND_SOC_NOPM, 0, 0,
2515 &rt5659_sto1_dmic_mux),
2516 SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
2517 &rt5659_sto1_adc1_mux),
2518 SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
2519 &rt5659_sto1_adc1_mux),
2520 SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
2521 &rt5659_sto1_adc2_mux),
2522 SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
2523 &rt5659_sto1_adc2_mux),
2524 SND_SOC_DAPM_MUX("Stereo1 ADC L Mux", SND_SOC_NOPM, 0, 0,
2525 &rt5659_sto1_adc_mux),
2526 SND_SOC_DAPM_MUX("Stereo1 ADC R Mux", SND_SOC_NOPM, 0, 0,
2527 &rt5659_sto1_adc_mux),
2528 SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
2529 &rt5659_mono_adc_l2_mux),
2530 SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
2531 &rt5659_mono_adc_r2_mux),
2532 SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
2533 &rt5659_mono_adc_l1_mux),
2534 SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
2535 &rt5659_mono_adc_r1_mux),
2536 SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
2537 &rt5659_mono_dmic_l_mux),
2538 SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
2539 &rt5659_mono_dmic_r_mux),
2540 SND_SOC_DAPM_MUX("Mono ADC L Mux", SND_SOC_NOPM, 0, 0,
2541 &rt5659_mono_adc_l_mux),
2542 SND_SOC_DAPM_MUX("Mono ADC R Mux", SND_SOC_NOPM, 0, 0,
2543 &rt5659_mono_adc_r_mux),
2544 /* ADC Mixer */
2545 SND_SOC_DAPM_SUPPLY("ADC Stereo1 Filter", RT5659_PWR_DIG_2,
2546 RT5659_PWR_ADC_S1F_BIT, 0, NULL, 0),
2547 SND_SOC_DAPM_SUPPLY("ADC Stereo2 Filter", RT5659_PWR_DIG_2,
2548 RT5659_PWR_ADC_S2F_BIT, 0, NULL, 0),
2549 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM,
2550 0, 0, rt5659_sto1_adc_l_mix,
2551 ARRAY_SIZE(rt5659_sto1_adc_l_mix)),
2552 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM,
2553 0, 0, rt5659_sto1_adc_r_mix,
2554 ARRAY_SIZE(rt5659_sto1_adc_r_mix)),
2555 SND_SOC_DAPM_SUPPLY("ADC Mono Left Filter", RT5659_PWR_DIG_2,
2556 RT5659_PWR_ADC_MF_L_BIT, 0, NULL, 0),
2557 SND_SOC_DAPM_MIXER("Mono ADC MIXL", RT5659_MONO_ADC_DIG_VOL,
2558 RT5659_L_MUTE_SFT, 1, rt5659_mono_adc_l_mix,
2559 ARRAY_SIZE(rt5659_mono_adc_l_mix)),
2560 SND_SOC_DAPM_SUPPLY("ADC Mono Right Filter", RT5659_PWR_DIG_2,
2561 RT5659_PWR_ADC_MF_R_BIT, 0, NULL, 0),
2562 SND_SOC_DAPM_MIXER("Mono ADC MIXR", RT5659_MONO_ADC_DIG_VOL,
2563 RT5659_R_MUTE_SFT, 1, rt5659_mono_adc_r_mix,
2564 ARRAY_SIZE(rt5659_mono_adc_r_mix)),
2565
2566 /* ADC PGA */
2567 SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2568 SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2569 SND_SOC_DAPM_PGA("IF_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
2570 SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2571 SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2572 SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
2573 SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
2574 SND_SOC_DAPM_PGA("Stereo2 ADC LR", SND_SOC_NOPM, 0, 0, NULL, 0),
2575
2576 SND_SOC_DAPM_PGA("Stereo1 ADC Volume L", RT5659_STO1_ADC_DIG_VOL,
2577 RT5659_L_MUTE_SFT, 1, NULL, 0),
2578 SND_SOC_DAPM_PGA("Stereo1 ADC Volume R", RT5659_STO1_ADC_DIG_VOL,
2579 RT5659_R_MUTE_SFT, 1, NULL, 0),
2580
2581 /* Digital Interface */
2582 SND_SOC_DAPM_SUPPLY("I2S1", RT5659_PWR_DIG_1, RT5659_PWR_I2S1_BIT,
2583 0, NULL, 0),
2584 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2585 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2586 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
2587 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
2588 SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0),
2589 SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0),
2590 SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2591 SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2592 SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2593 SND_SOC_DAPM_SUPPLY("I2S2", RT5659_PWR_DIG_1, RT5659_PWR_I2S2_BIT, 0,
2594 NULL, 0),
2595 SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2596 SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2597 SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2598 SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2599 SND_SOC_DAPM_PGA("IF2 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2600 SND_SOC_DAPM_PGA("IF2 ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2601 SND_SOC_DAPM_SUPPLY("I2S3", RT5659_PWR_DIG_1, RT5659_PWR_I2S3_BIT, 0,
2602 NULL, 0),
2603 SND_SOC_DAPM_PGA("IF3 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2604 SND_SOC_DAPM_PGA("IF3 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2605 SND_SOC_DAPM_PGA("IF3 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2606 SND_SOC_DAPM_PGA("IF3 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
2607 SND_SOC_DAPM_PGA("IF3 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
2608 SND_SOC_DAPM_PGA("IF3 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
2609
2610 /* Digital Interface Select */
2611 SND_SOC_DAPM_PGA("TDM AD1:AD2:DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2612 SND_SOC_DAPM_PGA("TDM AD2:DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
2613 SND_SOC_DAPM_MUX("TDM Data Mux", SND_SOC_NOPM, 0, 0,
2614 &rt5659_rx_adc_dac_mux),
2615 SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, 0, 0,
2616 &rt5659_if2_adc_in_mux),
2617 SND_SOC_DAPM_MUX("IF3 ADC Mux", SND_SOC_NOPM, 0, 0,
2618 &rt5659_if3_adc_in_mux),
2619 SND_SOC_DAPM_MUX("IF1 01 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2620 &rt5659_if1_01_adc_swap_mux),
2621 SND_SOC_DAPM_MUX("IF1 23 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2622 &rt5659_if1_23_adc_swap_mux),
2623 SND_SOC_DAPM_MUX("IF1 45 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2624 &rt5659_if1_45_adc_swap_mux),
2625 SND_SOC_DAPM_MUX("IF1 67 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2626 &rt5659_if1_67_adc_swap_mux),
2627 SND_SOC_DAPM_MUX("IF2 DAC Swap Mux", SND_SOC_NOPM, 0, 0,
2628 &rt5659_if2_dac_swap_mux),
2629 SND_SOC_DAPM_MUX("IF2 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2630 &rt5659_if2_adc_swap_mux),
2631 SND_SOC_DAPM_MUX("IF3 DAC Swap Mux", SND_SOC_NOPM, 0, 0,
2632 &rt5659_if3_dac_swap_mux),
2633 SND_SOC_DAPM_MUX("IF3 ADC Swap Mux", SND_SOC_NOPM, 0, 0,
2634 &rt5659_if3_adc_swap_mux),
2635
2636 /* Audio Interface */
2637 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2638 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
2639 SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2640 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2641 SND_SOC_DAPM_AIF_IN("AIF3RX", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2642 SND_SOC_DAPM_AIF_OUT("AIF3TX", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2643
2644 /* Output Side */
2645 /* DAC mixer before sound effect */
2646 SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
2647 rt5659_dac_l_mix, ARRAY_SIZE(rt5659_dac_l_mix)),
2648 SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
2649 rt5659_dac_r_mix, ARRAY_SIZE(rt5659_dac_r_mix)),
2650
2651 /* DAC channel Mux */
2652 SND_SOC_DAPM_MUX("DAC L1 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_l1_mux),
2653 SND_SOC_DAPM_MUX("DAC R1 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_r1_mux),
2654 SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_l2_mux),
2655 SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5659_dac_r2_mux),
2656
2657 SND_SOC_DAPM_MUX("DAC L1 Source", SND_SOC_NOPM, 0, 0,
2658 &rt5659_alg_dac_l1_mux),
2659 SND_SOC_DAPM_MUX("DAC R1 Source", SND_SOC_NOPM, 0, 0,
2660 &rt5659_alg_dac_r1_mux),
2661 SND_SOC_DAPM_MUX("DAC L2 Source", SND_SOC_NOPM, 0, 0,
2662 &rt5659_alg_dac_l2_mux),
2663 SND_SOC_DAPM_MUX("DAC R2 Source", SND_SOC_NOPM, 0, 0,
2664 &rt5659_alg_dac_r2_mux),
2665
2666 /* DAC Mixer */
2667 SND_SOC_DAPM_SUPPLY("DAC Stereo1 Filter", RT5659_PWR_DIG_2,
2668 RT5659_PWR_DAC_S1F_BIT, 0, NULL, 0),
2669 SND_SOC_DAPM_SUPPLY("DAC Mono Left Filter", RT5659_PWR_DIG_2,
2670 RT5659_PWR_DAC_MF_L_BIT, 0, NULL, 0),
2671 SND_SOC_DAPM_SUPPLY("DAC Mono Right Filter", RT5659_PWR_DIG_2,
2672 RT5659_PWR_DAC_MF_R_BIT, 0, NULL, 0),
2673 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
2674 rt5659_sto_dac_l_mix, ARRAY_SIZE(rt5659_sto_dac_l_mix)),
2675 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
2676 rt5659_sto_dac_r_mix, ARRAY_SIZE(rt5659_sto_dac_r_mix)),
2677 SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
2678 rt5659_mono_dac_l_mix, ARRAY_SIZE(rt5659_mono_dac_l_mix)),
2679 SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
2680 rt5659_mono_dac_r_mix, ARRAY_SIZE(rt5659_mono_dac_r_mix)),
2681 SND_SOC_DAPM_MUX("DAC MIXL", SND_SOC_NOPM, 0, 0,
2682 &rt5659_dig_dac_mixl_mux),
2683 SND_SOC_DAPM_MUX("DAC MIXR", SND_SOC_NOPM, 0, 0,
2684 &rt5659_dig_dac_mixr_mux),
2685
2686 /* DACs */
2687 SND_SOC_DAPM_SUPPLY_S("DAC L1 Power", 1, RT5659_PWR_DIG_1,
2688 RT5659_PWR_DAC_L1_BIT, 0, NULL, 0),
2689 SND_SOC_DAPM_SUPPLY_S("DAC R1 Power", 1, RT5659_PWR_DIG_1,
2690 RT5659_PWR_DAC_R1_BIT, 0, NULL, 0),
2691 SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0),
2692 SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0),
2693
2694 SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5659_PWR_DIG_1,
2695 RT5659_PWR_DAC_L2_BIT, 0, NULL, 0),
2696 SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5659_PWR_DIG_1,
2697 RT5659_PWR_DAC_R2_BIT, 0, NULL, 0),
2698 SND_SOC_DAPM_DAC("DAC L2", NULL, SND_SOC_NOPM, 0, 0),
2699 SND_SOC_DAPM_DAC("DAC R2", NULL, SND_SOC_NOPM, 0, 0),
2700 SND_SOC_DAPM_PGA("DAC_REF", SND_SOC_NOPM, 0, 0, NULL, 0),
2701
2702 /* OUT Mixer */
2703 SND_SOC_DAPM_MIXER("SPK MIXL", RT5659_PWR_MIXER, RT5659_PWR_SM_L_BIT,
2704 0, rt5659_spk_l_mix, ARRAY_SIZE(rt5659_spk_l_mix)),
2705 SND_SOC_DAPM_MIXER("SPK MIXR", RT5659_PWR_MIXER, RT5659_PWR_SM_R_BIT,
2706 0, rt5659_spk_r_mix, ARRAY_SIZE(rt5659_spk_r_mix)),
2707 SND_SOC_DAPM_MIXER("MONOVOL MIX", RT5659_PWR_MIXER, RT5659_PWR_MM_BIT,
2708 0, rt5659_monovol_mix, ARRAY_SIZE(rt5659_monovol_mix)),
2709 SND_SOC_DAPM_MIXER("OUT MIXL", RT5659_PWR_MIXER, RT5659_PWR_OM_L_BIT,
2710 0, rt5659_out_l_mix, ARRAY_SIZE(rt5659_out_l_mix)),
2711 SND_SOC_DAPM_MIXER("OUT MIXR", RT5659_PWR_MIXER, RT5659_PWR_OM_R_BIT,
2712 0, rt5659_out_r_mix, ARRAY_SIZE(rt5659_out_r_mix)),
2713
2714 /* Output Volume */
2715 SND_SOC_DAPM_SWITCH("SPKVOL L", RT5659_PWR_VOL, RT5659_PWR_SV_L_BIT, 0,
2716 &spkvol_l_switch),
2717 SND_SOC_DAPM_SWITCH("SPKVOL R", RT5659_PWR_VOL, RT5659_PWR_SV_R_BIT, 0,
2718 &spkvol_r_switch),
2719 SND_SOC_DAPM_SWITCH("MONOVOL", RT5659_PWR_VOL, RT5659_PWR_MV_BIT, 0,
2720 &monovol_switch),
2721 SND_SOC_DAPM_SWITCH("OUTVOL L", RT5659_PWR_VOL, RT5659_PWR_OV_L_BIT, 0,
2722 &outvol_l_switch),
2723 SND_SOC_DAPM_SWITCH("OUTVOL R", RT5659_PWR_VOL, RT5659_PWR_OV_R_BIT, 0,
2724 &outvol_r_switch),
2725
2726 /* SPO/MONO/HPO/LOUT */
2727 SND_SOC_DAPM_MIXER("SPO L MIX", SND_SOC_NOPM, 0, 0, rt5659_spo_l_mix,
2728 ARRAY_SIZE(rt5659_spo_l_mix)),
2729 SND_SOC_DAPM_MIXER("SPO R MIX", SND_SOC_NOPM, 0, 0, rt5659_spo_r_mix,
2730 ARRAY_SIZE(rt5659_spo_r_mix)),
2731 SND_SOC_DAPM_MIXER("Mono MIX", SND_SOC_NOPM, 0, 0, rt5659_mono_mix,
2732 ARRAY_SIZE(rt5659_mono_mix)),
2733 SND_SOC_DAPM_MIXER("LOUT L MIX", SND_SOC_NOPM, 0, 0, rt5659_lout_l_mix,
2734 ARRAY_SIZE(rt5659_lout_l_mix)),
2735 SND_SOC_DAPM_MIXER("LOUT R MIX", SND_SOC_NOPM, 0, 0, rt5659_lout_r_mix,
2736 ARRAY_SIZE(rt5659_lout_r_mix)),
2737
2738 SND_SOC_DAPM_PGA_S("SPK Amp", 1, RT5659_PWR_DIG_1, RT5659_PWR_CLS_D_BIT,
2739 0, rt5659_spk_event, SND_SOC_DAPM_POST_PMD |
2740 SND_SOC_DAPM_PRE_PMU),
2741 SND_SOC_DAPM_PGA_S("Mono Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_MA_BIT,
2742 0, rt5659_mono_event, SND_SOC_DAPM_POST_PMD |
2743 SND_SOC_DAPM_PRE_PMU),
2744 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
2745 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
2746 SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
2747
2748 SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
2749 rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
2750 SND_SOC_DAPM_POST_PMD),
2751
2752 SND_SOC_DAPM_SWITCH("SPO Playback", SND_SOC_NOPM, 0, 0, &spo_switch),
2753 SND_SOC_DAPM_SWITCH("Mono Playback", SND_SOC_NOPM, 0, 0,
2754 &mono_switch),
2755 SND_SOC_DAPM_SWITCH("HPO L Playback", SND_SOC_NOPM, 0, 0,
2756 &hpo_l_switch),
2757 SND_SOC_DAPM_SWITCH("HPO R Playback", SND_SOC_NOPM, 0, 0,
2758 &hpo_r_switch),
2759 SND_SOC_DAPM_SWITCH("LOUT L Playback", SND_SOC_NOPM, 0, 0,
2760 &lout_l_switch),
2761 SND_SOC_DAPM_SWITCH("LOUT R Playback", SND_SOC_NOPM, 0, 0,
2762 &lout_r_switch),
2763 SND_SOC_DAPM_SWITCH("PDM L Playback", SND_SOC_NOPM, 0, 0,
2764 &pdm_l_switch),
2765 SND_SOC_DAPM_SWITCH("PDM R Playback", SND_SOC_NOPM, 0, 0,
2766 &pdm_r_switch),
2767
2768 /* PDM */
2769 SND_SOC_DAPM_SUPPLY("PDM Power", RT5659_PWR_DIG_2,
2770 RT5659_PWR_PDM1_BIT, 0, NULL, 0),
2771 SND_SOC_DAPM_MUX("PDM L Mux", RT5659_PDM_OUT_CTRL,
2772 RT5659_M_PDM1_L_SFT, 1, &rt5659_pdm_l_mux),
2773 SND_SOC_DAPM_MUX("PDM R Mux", RT5659_PDM_OUT_CTRL,
2774 RT5659_M_PDM1_R_SFT, 1, &rt5659_pdm_r_mux),
2775
2776 /* SPDIF */
2777 SND_SOC_DAPM_MUX("SPDIF Mux", SND_SOC_NOPM, 0, 0, &rt5659_spdif_mux),
2778
2779 SND_SOC_DAPM_SUPPLY("SYS CLK DET", RT5659_CLK_DET, 3, 0, NULL, 0),
2780 SND_SOC_DAPM_SUPPLY("CLKDET", RT5659_CLK_DET, 0, 0, NULL, 0),
2781
2782 /* Output Lines */
2783 SND_SOC_DAPM_OUTPUT("HPOL"),
2784 SND_SOC_DAPM_OUTPUT("HPOR"),
2785 SND_SOC_DAPM_OUTPUT("SPOL"),
2786 SND_SOC_DAPM_OUTPUT("SPOR"),
2787 SND_SOC_DAPM_OUTPUT("LOUTL"),
2788 SND_SOC_DAPM_OUTPUT("LOUTR"),
2789 SND_SOC_DAPM_OUTPUT("MONOOUT"),
2790 SND_SOC_DAPM_OUTPUT("PDML"),
2791 SND_SOC_DAPM_OUTPUT("PDMR"),
2792 SND_SOC_DAPM_OUTPUT("SPDIF"),
2793};
2794
2795static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
2796 /*PLL*/
2797 { "ADC Stereo1 Filter", NULL, "PLL", is_sys_clk_from_pll },
2798 { "ADC Stereo2 Filter", NULL, "PLL", is_sys_clk_from_pll },
2799 { "ADC Mono Left Filter", NULL, "PLL", is_sys_clk_from_pll },
2800 { "ADC Mono Right Filter", NULL, "PLL", is_sys_clk_from_pll },
2801 { "DAC Stereo1 Filter", NULL, "PLL", is_sys_clk_from_pll },
2802 { "DAC Mono Left Filter", NULL, "PLL", is_sys_clk_from_pll },
2803 { "DAC Mono Right Filter", NULL, "PLL", is_sys_clk_from_pll },
2804
2805 /*ASRC*/
2806 { "ADC Stereo1 Filter", NULL, "ADC STO1 ASRC", is_using_asrc },
2807 { "ADC Mono Left Filter", NULL, "ADC Mono L ASRC", is_using_asrc },
2808 { "ADC Mono Right Filter", NULL, "ADC Mono R ASRC", is_using_asrc },
2809 { "DAC Mono Left Filter", NULL, "DAC Mono L ASRC", is_using_asrc },
2810 { "DAC Mono Right Filter", NULL, "DAC Mono R ASRC", is_using_asrc },
2811 { "DAC Stereo1 Filter", NULL, "DAC STO ASRC", is_using_asrc },
2812
2813 { "SYS CLK DET", NULL, "CLKDET" },
2814
2815 { "I2S1", NULL, "I2S1 ASRC" },
2816 { "I2S2", NULL, "I2S2 ASRC" },
2817 { "I2S3", NULL, "I2S3 ASRC" },
2818
2819 { "IN1P", NULL, "LDO2" },
2820 { "IN2P", NULL, "LDO2" },
2821 { "IN3P", NULL, "LDO2" },
2822 { "IN4P", NULL, "LDO2" },
2823
2824 { "DMIC1", NULL, "DMIC L1" },
2825 { "DMIC1", NULL, "DMIC R1" },
2826 { "DMIC2", NULL, "DMIC L2" },
2827 { "DMIC2", NULL, "DMIC R2" },
2828
2829 { "BST1", NULL, "IN1P" },
2830 { "BST1", NULL, "IN1N" },
2831 { "BST1", NULL, "BST1 Power" },
2832 { "BST2", NULL, "IN2P" },
2833 { "BST2", NULL, "IN2N" },
2834 { "BST2", NULL, "BST2 Power" },
2835 { "BST3", NULL, "IN3P" },
2836 { "BST3", NULL, "IN3N" },
2837 { "BST3", NULL, "BST3 Power" },
2838 { "BST4", NULL, "IN4P" },
2839 { "BST4", NULL, "IN4N" },
2840 { "BST4", NULL, "BST4 Power" },
2841
2842 { "INL VOL", NULL, "IN2P" },
2843 { "INR VOL", NULL, "IN2N" },
2844
2845 { "RECMIX1L", "SPKVOLL Switch", "SPKVOL L" },
2846 { "RECMIX1L", "INL Switch", "INL VOL" },
2847 { "RECMIX1L", "BST4 Switch", "BST4" },
2848 { "RECMIX1L", "BST3 Switch", "BST3" },
2849 { "RECMIX1L", "BST2 Switch", "BST2" },
2850 { "RECMIX1L", "BST1 Switch", "BST1" },
2851
2852 { "RECMIX1R", "HPOVOLR Switch", "HPO R Playback" },
2853 { "RECMIX1R", "INR Switch", "INR VOL" },
2854 { "RECMIX1R", "BST4 Switch", "BST4" },
2855 { "RECMIX1R", "BST3 Switch", "BST3" },
2856 { "RECMIX1R", "BST2 Switch", "BST2" },
2857 { "RECMIX1R", "BST1 Switch", "BST1" },
2858
2859 { "RECMIX2L", "SPKVOLL Switch", "SPKVOL L" },
2860 { "RECMIX2L", "OUTVOLL Switch", "OUTVOL L" },
2861 { "RECMIX2L", "BST4 Switch", "BST4" },
2862 { "RECMIX2L", "BST3 Switch", "BST3" },
2863 { "RECMIX2L", "BST2 Switch", "BST2" },
2864 { "RECMIX2L", "BST1 Switch", "BST1" },
2865
2866 { "RECMIX2R", "MONOVOL Switch", "MONOVOL" },
2867 { "RECMIX2R", "OUTVOLR Switch", "OUTVOL R" },
2868 { "RECMIX2R", "BST4 Switch", "BST4" },
2869 { "RECMIX2R", "BST3 Switch", "BST3" },
2870 { "RECMIX2R", "BST2 Switch", "BST2" },
2871 { "RECMIX2R", "BST1 Switch", "BST1" },
2872
2873 { "ADC1 L", NULL, "RECMIX1L" },
2874 { "ADC1 L", NULL, "ADC1 L Power" },
2875 { "ADC1 L", NULL, "ADC1 clock" },
2876 { "ADC1 R", NULL, "RECMIX1R" },
2877 { "ADC1 R", NULL, "ADC1 R Power" },
2878 { "ADC1 R", NULL, "ADC1 clock" },
2879
2880 { "ADC2 L", NULL, "RECMIX2L" },
2881 { "ADC2 L", NULL, "ADC2 L Power" },
2882 { "ADC2 L", NULL, "ADC2 clock" },
2883 { "ADC2 R", NULL, "RECMIX2R" },
2884 { "ADC2 R", NULL, "ADC2 R Power" },
2885 { "ADC2 R", NULL, "ADC2 clock" },
2886
2887 { "DMIC L1", NULL, "DMIC CLK" },
2888 { "DMIC L1", NULL, "DMIC1 Power" },
2889 { "DMIC R1", NULL, "DMIC CLK" },
2890 { "DMIC R1", NULL, "DMIC1 Power" },
2891 { "DMIC L2", NULL, "DMIC CLK" },
2892 { "DMIC L2", NULL, "DMIC2 Power" },
2893 { "DMIC R2", NULL, "DMIC CLK" },
2894 { "DMIC R2", NULL, "DMIC2 Power" },
2895
2896 { "Stereo1 DMIC L Mux", "DMIC1", "DMIC L1" },
2897 { "Stereo1 DMIC L Mux", "DMIC2", "DMIC L2" },
2898
2899 { "Stereo1 DMIC R Mux", "DMIC1", "DMIC R1" },
2900 { "Stereo1 DMIC R Mux", "DMIC2", "DMIC R2" },
2901
2902 { "Mono DMIC L Mux", "DMIC1 L", "DMIC L1" },
2903 { "Mono DMIC L Mux", "DMIC2 L", "DMIC L2" },
2904
2905 { "Mono DMIC R Mux", "DMIC1 R", "DMIC R1" },
2906 { "Mono DMIC R Mux", "DMIC2 R", "DMIC R2" },
2907
2908 { "Stereo1 ADC L Mux", "ADC1", "ADC1 L" },
2909 { "Stereo1 ADC L Mux", "ADC2", "ADC2 L" },
2910 { "Stereo1 ADC R Mux", "ADC1", "ADC1 R" },
2911 { "Stereo1 ADC R Mux", "ADC2", "ADC2 R" },
2912
2913 { "Stereo1 ADC L1 Mux", "ADC", "Stereo1 ADC L Mux" },
2914 { "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
2915 { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC L Mux" },
2916 { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
2917
2918 { "Stereo1 ADC R1 Mux", "ADC", "Stereo1 ADC R Mux" },
2919 { "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
2920 { "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC R Mux" },
2921 { "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
2922
2923 { "Mono ADC L Mux", "ADC1 L", "ADC1 L" },
2924 { "Mono ADC L Mux", "ADC1 R", "ADC1 R" },
2925 { "Mono ADC L Mux", "ADC2 L", "ADC2 L" },
2926 { "Mono ADC L Mux", "ADC2 R", "ADC2 R" },
2927
2928 { "Mono ADC R Mux", "ADC1 L", "ADC1 L" },
2929 { "Mono ADC R Mux", "ADC1 R", "ADC1 R" },
2930 { "Mono ADC R Mux", "ADC2 L", "ADC2 L" },
2931 { "Mono ADC R Mux", "ADC2 R", "ADC2 R" },
2932
2933 { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
2934 { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
2935 { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
2936 { "Mono ADC L1 Mux", "ADC", "Mono ADC L Mux" },
2937
2938 { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
2939 { "Mono ADC R1 Mux", "ADC", "Mono ADC R Mux" },
2940 { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
2941 { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
2942
2943 { "Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
2944 { "Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
2945 { "Stereo1 ADC MIXL", NULL, "ADC Stereo1 Filter" },
2946
2947 { "Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
2948 { "Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
2949 { "Stereo1 ADC MIXR", NULL, "ADC Stereo1 Filter" },
2950
2951 { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
2952 { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
2953 { "Mono ADC MIXL", NULL, "ADC Mono Left Filter" },
2954
2955 { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
2956 { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
2957 { "Mono ADC MIXR", NULL, "ADC Mono Right Filter" },
2958
2959 { "Stereo1 ADC Volume L", NULL, "Stereo1 ADC MIXL" },
2960 { "Stereo1 ADC Volume R", NULL, "Stereo1 ADC MIXR" },
2961
2962 { "IF_ADC1", NULL, "Stereo1 ADC Volume L" },
2963 { "IF_ADC1", NULL, "Stereo1 ADC Volume R" },
2964 { "IF_ADC2", NULL, "Mono ADC MIXL" },
2965 { "IF_ADC2", NULL, "Mono ADC MIXR" },
2966
2967 { "TDM AD1:AD2:DAC", NULL, "IF_ADC1" },
2968 { "TDM AD1:AD2:DAC", NULL, "IF_ADC2" },
2969 { "TDM AD1:AD2:DAC", NULL, "DAC_REF" },
2970 { "TDM AD2:DAC", NULL, "IF_ADC2" },
2971 { "TDM AD2:DAC", NULL, "DAC_REF" },
2972 { "TDM Data Mux", "AD1:AD2:DAC:NUL", "TDM AD1:AD2:DAC" },
2973 { "TDM Data Mux", "AD1:AD2:NUL:DAC", "TDM AD1:AD2:DAC" },
2974 { "TDM Data Mux", "AD1:DAC:AD2:NUL", "TDM AD1:AD2:DAC" },
2975 { "TDM Data Mux", "AD1:DAC:NUL:AD2", "TDM AD1:AD2:DAC" },
2976 { "TDM Data Mux", "AD1:NUL:DAC:AD2", "TDM AD1:AD2:DAC" },
2977 { "TDM Data Mux", "AD1:NUL:AD2:DAC", "TDM AD1:AD2:DAC" },
2978 { "TDM Data Mux", "AD2:AD1:DAC:NUL", "TDM AD1:AD2:DAC" },
2979 { "TDM Data Mux", "AD2:AD1:NUL:DAC", "TDM AD1:AD2:DAC" },
2980 { "TDM Data Mux", "AD2:DAC:AD1:NUL", "TDM AD1:AD2:DAC" },
2981 { "TDM Data Mux", "AD2:DAC:NUL:AD1", "TDM AD1:AD2:DAC" },
2982 { "TDM Data Mux", "AD2:NUL:DAC:AD1", "TDM AD1:AD2:DAC" },
2983 { "TDM Data Mux", "AD1:NUL:AD1:DAC", "TDM AD1:AD2:DAC" },
2984 { "TDM Data Mux", "DAC:AD1:AD2:NUL", "TDM AD1:AD2:DAC" },
2985 { "TDM Data Mux", "DAC:AD1:NUL:AD2", "TDM AD1:AD2:DAC" },
2986 { "TDM Data Mux", "DAC:AD2:AD1:NUL", "TDM AD1:AD2:DAC" },
2987 { "TDM Data Mux", "DAC:AD2:NUL:AD1", "TDM AD1:AD2:DAC" },
2988 { "TDM Data Mux", "DAC:NUL:DAC:AD2", "TDM AD2:DAC" },
2989 { "TDM Data Mux", "DAC:NUL:AD2:DAC", "TDM AD2:DAC" },
2990 { "TDM Data Mux", "NUL:AD1:AD2:DAC", "TDM AD1:AD2:DAC" },
2991 { "TDM Data Mux", "NUL:AD1:DAC:AD2", "TDM AD1:AD2:DAC" },
2992 { "TDM Data Mux", "NUL:AD2:AD1:DAC", "TDM AD1:AD2:DAC" },
2993 { "TDM Data Mux", "NUL:AD2:DAC:AD1", "TDM AD1:AD2:DAC" },
2994 { "TDM Data Mux", "NUL:DAC:DAC:AD2", "TDM AD2:DAC" },
2995 { "TDM Data Mux", "NUL:DAC:AD2:DAC", "TDM AD2:DAC" },
2996 { "IF1 01 ADC Swap Mux", "L/R", "TDM Data Mux" },
2997 { "IF1 01 ADC Swap Mux", "R/L", "TDM Data Mux" },
2998 { "IF1 01 ADC Swap Mux", "L/L", "TDM Data Mux" },
2999 { "IF1 01 ADC Swap Mux", "R/R", "TDM Data Mux" },
3000 { "IF1 23 ADC Swap Mux", "L/R", "TDM Data Mux" },
3001 { "IF1 23 ADC Swap Mux", "R/L", "TDM Data Mux" },
3002 { "IF1 23 ADC Swap Mux", "L/L", "TDM Data Mux" },
3003 { "IF1 23 ADC Swap Mux", "R/R", "TDM Data Mux" },
3004 { "IF1 45 ADC Swap Mux", "L/R", "TDM Data Mux" },
3005 { "IF1 45 ADC Swap Mux", "R/L", "TDM Data Mux" },
3006 { "IF1 45 ADC Swap Mux", "L/L", "TDM Data Mux" },
3007 { "IF1 45 ADC Swap Mux", "R/R", "TDM Data Mux" },
3008 { "IF1 67 ADC Swap Mux", "L/R", "TDM Data Mux" },
3009 { "IF1 67 ADC Swap Mux", "R/L", "TDM Data Mux" },
3010 { "IF1 67 ADC Swap Mux", "L/L", "TDM Data Mux" },
3011 { "IF1 67 ADC Swap Mux", "R/R", "TDM Data Mux" },
3012 { "IF1 ADC", NULL, "IF1 01 ADC Swap Mux" },
3013 { "IF1 ADC", NULL, "IF1 23 ADC Swap Mux" },
3014 { "IF1 ADC", NULL, "IF1 45 ADC Swap Mux" },
3015 { "IF1 ADC", NULL, "IF1 67 ADC Swap Mux" },
3016 { "IF1 ADC", NULL, "I2S1" },
3017
3018 { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
3019 { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
3020 { "IF2 ADC Mux", "IF_ADC3", "IF_ADC3" },
3021 { "IF2 ADC Mux", "DAC_REF", "DAC_REF" },
3022 { "IF2 ADC", NULL, "IF2 ADC Mux"},
3023 { "IF2 ADC", NULL, "I2S2" },
3024
3025 { "IF3 ADC Mux", "IF_ADC1", "IF_ADC1" },
3026 { "IF3 ADC Mux", "IF_ADC2", "IF_ADC2" },
3027 { "IF3 ADC Mux", "Stereo2_ADC_L/R", "Stereo2 ADC LR" },
3028 { "IF3 ADC Mux", "DAC_REF", "DAC_REF" },
3029 { "IF3 ADC", NULL, "IF3 ADC Mux"},
3030 { "IF3 ADC", NULL, "I2S3" },
3031
3032 { "AIF1TX", NULL, "IF1 ADC" },
3033 { "IF2 ADC Swap Mux", "L/R", "IF2 ADC" },
3034 { "IF2 ADC Swap Mux", "R/L", "IF2 ADC" },
3035 { "IF2 ADC Swap Mux", "L/L", "IF2 ADC" },
3036 { "IF2 ADC Swap Mux", "R/R", "IF2 ADC" },
3037 { "AIF2TX", NULL, "IF2 ADC Swap Mux" },
3038 { "IF3 ADC Swap Mux", "L/R", "IF3 ADC" },
3039 { "IF3 ADC Swap Mux", "R/L", "IF3 ADC" },
3040 { "IF3 ADC Swap Mux", "L/L", "IF3 ADC" },
3041 { "IF3 ADC Swap Mux", "R/R", "IF3 ADC" },
3042 { "AIF3TX", NULL, "IF3 ADC Swap Mux" },
3043
3044 { "IF1 DAC1", NULL, "AIF1RX" },
3045 { "IF1 DAC2", NULL, "AIF1RX" },
3046 { "IF2 DAC Swap Mux", "L/R", "AIF2RX" },
3047 { "IF2 DAC Swap Mux", "R/L", "AIF2RX" },
3048 { "IF2 DAC Swap Mux", "L/L", "AIF2RX" },
3049 { "IF2 DAC Swap Mux", "R/R", "AIF2RX" },
3050 { "IF2 DAC", NULL, "IF2 DAC Swap Mux" },
3051 { "IF3 DAC Swap Mux", "L/R", "AIF3RX" },
3052 { "IF3 DAC Swap Mux", "R/L", "AIF3RX" },
3053 { "IF3 DAC Swap Mux", "L/L", "AIF3RX" },
3054 { "IF3 DAC Swap Mux", "R/R", "AIF3RX" },
3055 { "IF3 DAC", NULL, "IF3 DAC Swap Mux" },
3056
3057 { "IF1 DAC1", NULL, "I2S1" },
3058 { "IF1 DAC2", NULL, "I2S1" },
3059 { "IF2 DAC", NULL, "I2S2" },
3060 { "IF3 DAC", NULL, "I2S3" },
3061
3062 { "IF1 DAC2 L", NULL, "IF1 DAC2" },
3063 { "IF1 DAC2 R", NULL, "IF1 DAC2" },
3064 { "IF1 DAC1 L", NULL, "IF1 DAC1" },
3065 { "IF1 DAC1 R", NULL, "IF1 DAC1" },
3066 { "IF2 DAC L", NULL, "IF2 DAC" },
3067 { "IF2 DAC R", NULL, "IF2 DAC" },
3068 { "IF3 DAC L", NULL, "IF3 DAC" },
3069 { "IF3 DAC R", NULL, "IF3 DAC" },
3070
3071 { "DAC L1 Mux", "IF1 DAC1", "IF1 DAC1 L" },
3072 { "DAC L1 Mux", "IF2 DAC", "IF2 DAC L" },
3073 { "DAC L1 Mux", "IF3 DAC", "IF3 DAC L" },
3074 { "DAC L1 Mux", NULL, "DAC Stereo1 Filter" },
3075
3076 { "DAC R1 Mux", "IF1 DAC1", "IF1 DAC1 R" },
3077 { "DAC R1 Mux", "IF2 DAC", "IF2 DAC R" },
3078 { "DAC R1 Mux", "IF3 DAC", "IF3 DAC R" },
3079 { "DAC R1 Mux", NULL, "DAC Stereo1 Filter" },
3080
3081 { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC Volume L" },
3082 { "DAC1 MIXL", "DAC1 Switch", "DAC L1 Mux" },
3083 { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC Volume R" },
3084 { "DAC1 MIXR", "DAC1 Switch", "DAC R1 Mux" },
3085
3086 { "DAC_REF", NULL, "DAC1 MIXL" },
3087 { "DAC_REF", NULL, "DAC1 MIXR" },
3088
3089 { "DAC L2 Mux", "IF1 DAC2", "IF1 DAC2 L" },
3090 { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
3091 { "DAC L2 Mux", "IF3 DAC", "IF3 DAC L" },
3092 { "DAC L2 Mux", "Mono ADC MIX", "Mono ADC MIXL" },
3093 { "DAC L2 Mux", NULL, "DAC Mono Left Filter" },
3094
3095 { "DAC R2 Mux", "IF1 DAC2", "IF1 DAC2 R" },
3096 { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
3097 { "DAC R2 Mux", "IF3 DAC", "IF3 DAC R" },
3098 { "DAC R2 Mux", "Mono ADC MIX", "Mono ADC MIXR" },
3099 { "DAC R2 Mux", NULL, "DAC Mono Right Filter" },
3100
3101 { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
3102 { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
3103 { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux" },
3104 { "Stereo DAC MIXL", "DAC R2 Switch", "DAC R2 Mux" },
3105
3106 { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
3107 { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
3108 { "Stereo DAC MIXR", "DAC L2 Switch", "DAC L2 Mux" },
3109 { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux" },
3110
3111 { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
3112 { "Mono DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
3113 { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux" },
3114 { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux" },
3115 { "Mono DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
3116 { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
3117 { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux" },
3118 { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux" },
3119
3120 { "DAC MIXL", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3121 { "DAC MIXL", "Mono DAC Mixer", "Mono DAC MIXL" },
3122 { "DAC MIXR", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3123 { "DAC MIXR", "Mono DAC Mixer", "Mono DAC MIXR" },
3124
3125 { "DAC L1 Source", NULL, "DAC L1 Power" },
3126 { "DAC L1 Source", "DAC", "DAC1 MIXL" },
3127 { "DAC L1 Source", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3128 { "DAC R1 Source", NULL, "DAC R1 Power" },
3129 { "DAC R1 Source", "DAC", "DAC1 MIXR" },
3130 { "DAC R1 Source", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3131 { "DAC L2 Source", "Stereo DAC Mixer", "Stereo DAC MIXL" },
3132 { "DAC L2 Source", "Mono DAC Mixer", "Mono DAC MIXL" },
3133 { "DAC L2 Source", NULL, "DAC L2 Power" },
3134 { "DAC R2 Source", "Stereo DAC Mixer", "Stereo DAC MIXR" },
3135 { "DAC R2 Source", "Mono DAC Mixer", "Mono DAC MIXR" },
3136 { "DAC R2 Source", NULL, "DAC R2 Power" },
3137
3138 { "DAC L1", NULL, "DAC L1 Source" },
3139 { "DAC R1", NULL, "DAC R1 Source" },
3140 { "DAC L2", NULL, "DAC L2 Source" },
3141 { "DAC R2", NULL, "DAC R2 Source" },
3142
3143 { "SPK MIXL", "DAC L2 Switch", "DAC L2" },
3144 { "SPK MIXL", "BST1 Switch", "BST1" },
3145 { "SPK MIXL", "INL Switch", "INL VOL" },
3146 { "SPK MIXL", "INR Switch", "INR VOL" },
3147 { "SPK MIXL", "BST3 Switch", "BST3" },
3148 { "SPK MIXR", "DAC R2 Switch", "DAC R2" },
3149 { "SPK MIXR", "BST4 Switch", "BST4" },
3150 { "SPK MIXR", "INL Switch", "INL VOL" },
3151 { "SPK MIXR", "INR Switch", "INR VOL" },
3152 { "SPK MIXR", "BST3 Switch", "BST3" },
3153
3154 { "MONOVOL MIX", "DAC L2 Switch", "DAC L2" },
3155 { "MONOVOL MIX", "DAC R2 Switch", "DAC R2" },
3156 { "MONOVOL MIX", "BST1 Switch", "BST1" },
3157 { "MONOVOL MIX", "BST2 Switch", "BST2" },
3158 { "MONOVOL MIX", "BST3 Switch", "BST3" },
3159
3160 { "OUT MIXL", "DAC L2 Switch", "DAC L2" },
3161 { "OUT MIXL", "INL Switch", "INL VOL" },
3162 { "OUT MIXL", "BST1 Switch", "BST1" },
3163 { "OUT MIXL", "BST2 Switch", "BST2" },
3164 { "OUT MIXL", "BST3 Switch", "BST3" },
3165 { "OUT MIXR", "DAC R2 Switch", "DAC R2" },
3166 { "OUT MIXR", "INR Switch", "INR VOL" },
3167 { "OUT MIXR", "BST2 Switch", "BST2" },
3168 { "OUT MIXR", "BST3 Switch", "BST3" },
3169 { "OUT MIXR", "BST4 Switch", "BST4" },
3170
3171 { "SPKVOL L", "Switch", "SPK MIXL" },
3172 { "SPKVOL R", "Switch", "SPK MIXR" },
3173 { "SPO L MIX", "DAC L2 Switch", "DAC L2" },
3174 { "SPO L MIX", "SPKVOL L Switch", "SPKVOL L" },
3175 { "SPO R MIX", "DAC R2 Switch", "DAC R2" },
3176 { "SPO R MIX", "SPKVOL R Switch", "SPKVOL R" },
3177 { "SPK Amp", NULL, "SPO L MIX" },
3178 { "SPK Amp", NULL, "SPO R MIX" },
3179 { "SPK Amp", NULL, "SYS CLK DET" },
3180 { "SPO Playback", "Switch", "SPK Amp" },
3181 { "SPOL", NULL, "SPO Playback" },
3182 { "SPOR", NULL, "SPO Playback" },
3183
3184 { "MONOVOL", "Switch", "MONOVOL MIX" },
3185 { "Mono MIX", "DAC L2 Switch", "DAC L2" },
3186 { "Mono MIX", "MONOVOL Switch", "MONOVOL" },
3187 { "Mono Amp", NULL, "Mono MIX" },
3188 { "Mono Amp", NULL, "Mono Vref" },
3189 { "Mono Amp", NULL, "SYS CLK DET" },
3190 { "Mono Playback", "Switch", "Mono Amp" },
3191 { "MONOOUT", NULL, "Mono Playback" },
3192
3193 { "HP Amp", NULL, "DAC L1" },
3194 { "HP Amp", NULL, "DAC R1" },
3195 { "HP Amp", NULL, "Charge Pump" },
3196 { "HP Amp", NULL, "SYS CLK DET" },
3197 { "HPO L Playback", "Switch", "HP Amp"},
3198 { "HPO R Playback", "Switch", "HP Amp"},
3199 { "HPOL", NULL, "HPO L Playback" },
3200 { "HPOR", NULL, "HPO R Playback" },
3201
3202 { "OUTVOL L", "Switch", "OUT MIXL" },
3203 { "OUTVOL R", "Switch", "OUT MIXR" },
3204 { "LOUT L MIX", "DAC L2 Switch", "DAC L2" },
3205 { "LOUT L MIX", "OUTVOL L Switch", "OUTVOL L" },
3206 { "LOUT R MIX", "DAC R2 Switch", "DAC R2" },
3207 { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
3208 { "LOUT Amp", NULL, "LOUT L MIX" },
3209 { "LOUT Amp", NULL, "LOUT R MIX" },
3210 { "LOUT Amp", NULL, "SYS CLK DET" },
3211 { "LOUT L Playback", "Switch", "LOUT Amp" },
3212 { "LOUT R Playback", "Switch", "LOUT Amp" },
3213 { "LOUTL", NULL, "LOUT L Playback" },
3214 { "LOUTR", NULL, "LOUT R Playback" },
3215
3216 { "PDM L Mux", "Mono DAC", "Mono DAC MIXL" },
3217 { "PDM L Mux", "Stereo DAC", "Stereo DAC MIXL" },
3218 { "PDM L Mux", NULL, "PDM Power" },
3219 { "PDM R Mux", "Mono DAC", "Mono DAC MIXR" },
3220 { "PDM R Mux", "Stereo DAC", "Stereo DAC MIXR" },
3221 { "PDM R Mux", NULL, "PDM Power" },
3222 { "PDM L Playback", "Switch", "PDM L Mux" },
3223 { "PDM R Playback", "Switch", "PDM R Mux" },
3224 { "PDML", NULL, "PDM L Playback" },
3225 { "PDMR", NULL, "PDM R Playback" },
3226
3227 { "SPDIF Mux", "IF3_DAC", "IF3 DAC" },
3228 { "SPDIF Mux", "IF2_DAC", "IF2 DAC" },
3229 { "SPDIF Mux", "IF1_DAC2", "IF1 DAC2" },
3230 { "SPDIF Mux", "IF1_DAC1", "IF1 DAC1" },
3231 { "SPDIF", NULL, "SPDIF Mux" },
3232};
3233
3234static int rt5659_hw_params(struct snd_pcm_substream *substream,
3235 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
3236{
3237 struct snd_soc_codec *codec = dai->codec;
3238 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3239 unsigned int val_len = 0, val_clk, mask_clk;
3240 int pre_div, frame_size;
3241
3242 rt5659->lrck[dai->id] = params_rate(params);
3243 pre_div = rl6231_get_clk_info(rt5659->sysclk, rt5659->lrck[dai->id]);
3244 if (pre_div < 0) {
3245 dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n",
3246 rt5659->lrck[dai->id], dai->id);
3247 return -EINVAL;
3248 }
3249 frame_size = snd_soc_params_to_frame_size(params);
3250 if (frame_size < 0) {
3251 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
3252 return -EINVAL;
3253 }
3254
3255 dev_dbg(dai->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
3256 rt5659->lrck[dai->id], pre_div, dai->id);
3257
3258 switch (params_width(params)) {
3259 case 16:
3260 break;
3261 case 20:
3262 val_len |= RT5659_I2S_DL_20;
3263 break;
3264 case 24:
3265 val_len |= RT5659_I2S_DL_24;
3266 break;
3267 case 8:
3268 val_len |= RT5659_I2S_DL_8;
3269 break;
3270 default:
3271 return -EINVAL;
3272 }
3273
3274 switch (dai->id) {
3275 case RT5659_AIF1:
3276 mask_clk = RT5659_I2S_PD1_MASK;
3277 val_clk = pre_div << RT5659_I2S_PD1_SFT;
3278 snd_soc_update_bits(codec, RT5659_I2S1_SDP,
3279 RT5659_I2S_DL_MASK, val_len);
3280 break;
3281 case RT5659_AIF2:
3282 mask_clk = RT5659_I2S_PD2_MASK;
3283 val_clk = pre_div << RT5659_I2S_PD2_SFT;
3284 snd_soc_update_bits(codec, RT5659_I2S2_SDP,
3285 RT5659_I2S_DL_MASK, val_len);
3286 break;
3287 case RT5659_AIF3:
3288 mask_clk = RT5659_I2S_PD3_MASK;
3289 val_clk = pre_div << RT5659_I2S_PD3_SFT;
3290 snd_soc_update_bits(codec, RT5659_I2S3_SDP,
3291 RT5659_I2S_DL_MASK, val_len);
3292 break;
3293 default:
3294 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
3295 return -EINVAL;
3296 }
3297
3298 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1, mask_clk, val_clk);
3299
3300 switch (rt5659->lrck[dai->id]) {
3301 case 192000:
3302 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3303 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_32);
3304 break;
3305 case 96000:
3306 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3307 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_64);
3308 break;
3309 default:
3310 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3311 RT5659_DAC_OSR_MASK, RT5659_DAC_OSR_128);
3312 break;
3313 }
3314
3315 return 0;
3316}
3317
3318static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3319{
3320 struct snd_soc_codec *codec = dai->codec;
3321 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3322 unsigned int reg_val = 0;
3323
3324 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3325 case SND_SOC_DAIFMT_CBM_CFM:
3326 rt5659->master[dai->id] = 1;
3327 break;
3328 case SND_SOC_DAIFMT_CBS_CFS:
3329 reg_val |= RT5659_I2S_MS_S;
3330 rt5659->master[dai->id] = 0;
3331 break;
3332 default:
3333 return -EINVAL;
3334 }
3335
3336 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3337 case SND_SOC_DAIFMT_NB_NF:
3338 break;
3339 case SND_SOC_DAIFMT_IB_NF:
3340 reg_val |= RT5659_I2S_BP_INV;
3341 break;
3342 default:
3343 return -EINVAL;
3344 }
3345
3346 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3347 case SND_SOC_DAIFMT_I2S:
3348 break;
3349 case SND_SOC_DAIFMT_LEFT_J:
3350 reg_val |= RT5659_I2S_DF_LEFT;
3351 break;
3352 case SND_SOC_DAIFMT_DSP_A:
3353 reg_val |= RT5659_I2S_DF_PCM_A;
3354 break;
3355 case SND_SOC_DAIFMT_DSP_B:
3356 reg_val |= RT5659_I2S_DF_PCM_B;
3357 break;
3358 default:
3359 return -EINVAL;
3360 }
3361
3362 switch (dai->id) {
3363 case RT5659_AIF1:
3364 snd_soc_update_bits(codec, RT5659_I2S1_SDP,
3365 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3366 RT5659_I2S_DF_MASK, reg_val);
3367 break;
3368 case RT5659_AIF2:
3369 snd_soc_update_bits(codec, RT5659_I2S2_SDP,
3370 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3371 RT5659_I2S_DF_MASK, reg_val);
3372 break;
3373 case RT5659_AIF3:
3374 snd_soc_update_bits(codec, RT5659_I2S3_SDP,
3375 RT5659_I2S_MS_MASK | RT5659_I2S_BP_MASK |
3376 RT5659_I2S_DF_MASK, reg_val);
3377 break;
3378 default:
3379 dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id);
3380 return -EINVAL;
3381 }
3382 return 0;
3383}
3384
3385static int rt5659_set_dai_sysclk(struct snd_soc_dai *dai,
3386 int clk_id, unsigned int freq, int dir)
3387{
3388 struct snd_soc_codec *codec = dai->codec;
3389 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3390 unsigned int reg_val = 0;
3391
3392 if (freq == rt5659->sysclk && clk_id == rt5659->sysclk_src)
3393 return 0;
3394
3395 switch (clk_id) {
3396 case RT5659_SCLK_S_MCLK:
3397 reg_val |= RT5659_SCLK_SRC_MCLK;
3398 break;
3399 case RT5659_SCLK_S_PLL1:
3400 reg_val |= RT5659_SCLK_SRC_PLL1;
3401 break;
3402 case RT5659_SCLK_S_RCCLK:
3403 reg_val |= RT5659_SCLK_SRC_RCCLK;
3404 break;
3405 default:
3406 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
3407 return -EINVAL;
3408 }
3409 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3410 RT5659_SCLK_SRC_MASK, reg_val);
3411 rt5659->sysclk = freq;
3412 rt5659->sysclk_src = clk_id;
3413
3414 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
3415
3416 return 0;
3417}
3418
3419static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
3420 unsigned int freq_in, unsigned int freq_out)
3421{
3422 struct snd_soc_codec *codec = dai->codec;
3423 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3424 struct rl6231_pll_code pll_code;
3425 int ret;
3426
3427 if (Source == rt5659->pll_src && freq_in == rt5659->pll_in &&
3428 freq_out == rt5659->pll_out)
3429 return 0;
3430
3431 if (!freq_in || !freq_out) {
3432 dev_dbg(codec->dev, "PLL disabled\n");
3433
3434 rt5659->pll_in = 0;
3435 rt5659->pll_out = 0;
3436 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3437 RT5659_SCLK_SRC_MASK, RT5659_SCLK_SRC_MCLK);
3438 return 0;
3439 }
3440
3441 switch (Source) {
3442 case RT5659_PLL1_S_MCLK:
3443 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3444 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_MCLK);
3445 break;
3446 case RT5659_PLL1_S_BCLK1:
3447 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3448 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK1);
3449 break;
3450 case RT5659_PLL1_S_BCLK2:
3451 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3452 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK2);
3453 break;
3454 case RT5659_PLL1_S_BCLK3:
3455 snd_soc_update_bits(codec, RT5659_GLB_CLK,
3456 RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK3);
3457 break;
3458 default:
3459 dev_err(codec->dev, "Unknown PLL Source %d\n", Source);
3460 return -EINVAL;
3461 }
3462
3463 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
3464 if (ret < 0) {
3465 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
3466 return ret;
3467 }
3468
3469 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
3470 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
3471 pll_code.n_code, pll_code.k_code);
3472
3473 snd_soc_write(codec, RT5659_PLL_CTRL_1,
3474 pll_code.n_code << RT5659_PLL_N_SFT | pll_code.k_code);
3475 snd_soc_write(codec, RT5659_PLL_CTRL_2,
3476 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5659_PLL_M_SFT |
3477 pll_code.m_bp << RT5659_PLL_M_BP_SFT);
3478
3479 rt5659->pll_in = freq_in;
3480 rt5659->pll_out = freq_out;
3481 rt5659->pll_src = Source;
3482
3483 return 0;
3484}
3485
3486static int rt5659_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
3487 unsigned int rx_mask, int slots, int slot_width)
3488{
3489 struct snd_soc_codec *codec = dai->codec;
3490 unsigned int val = 0;
3491
3492 if (rx_mask || tx_mask)
3493 val |= (1 << 15);
3494
3495 switch (slots) {
3496 case 4:
3497 val |= (1 << 10);
3498 val |= (1 << 8);
3499 break;
3500 case 6:
3501 val |= (2 << 10);
3502 val |= (2 << 8);
3503 break;
3504 case 8:
3505 val |= (3 << 10);
3506 val |= (3 << 8);
3507 break;
3508 case 2:
3509 break;
3510 default:
3511 return -EINVAL;
3512 }
3513
3514 switch (slot_width) {
3515 case 20:
3516 val |= (1 << 6);
3517 val |= (1 << 4);
3518 break;
3519 case 24:
3520 val |= (2 << 6);
3521 val |= (2 << 4);
3522 break;
3523 case 32:
3524 val |= (3 << 6);
3525 val |= (3 << 4);
3526 break;
3527 case 16:
3528 break;
3529 default:
3530 return -EINVAL;
3531 }
3532
3533 snd_soc_update_bits(codec, RT5659_TDM_CTRL_1, 0x8ff0, val);
3534
3535 return 0;
3536}
3537
3538static int rt5659_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
3539{
3540 struct snd_soc_codec *codec = dai->codec;
3541 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3542
3543 dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
3544
3545 rt5659->bclk[dai->id] = ratio;
3546
3547 if (ratio == 64) {
3548 switch (dai->id) {
3549 case RT5659_AIF2:
3550 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3551 RT5659_I2S_BCLK_MS2_MASK,
3552 RT5659_I2S_BCLK_MS2_64);
3553 break;
3554 case RT5659_AIF3:
3555 snd_soc_update_bits(codec, RT5659_ADDA_CLK_1,
3556 RT5659_I2S_BCLK_MS3_MASK,
3557 RT5659_I2S_BCLK_MS3_64);
3558 break;
3559 }
3560 }
3561
3562 return 0;
3563}
3564
3565static int rt5659_set_bias_level(struct snd_soc_codec *codec,
3566 enum snd_soc_bias_level level)
3567{
3568 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3569
3570 switch (level) {
3571 case SND_SOC_BIAS_PREPARE:
3572 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
3573 RT5659_DIG_GATE_CTRL, RT5659_DIG_GATE_CTRL);
3574 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
3575 RT5659_PWR_LDO, RT5659_PWR_LDO);
3576 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3577 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2,
3578 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2);
3579 msleep(20);
3580 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3581 RT5659_PWR_FV1 | RT5659_PWR_FV2,
3582 RT5659_PWR_FV1 | RT5659_PWR_FV2);
3583 break;
3584
3585 case SND_SOC_BIAS_OFF:
3586 regmap_update_bits(rt5659->regmap, RT5659_PWR_DIG_1,
3587 RT5659_PWR_LDO, 0);
3588 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
3589 RT5659_PWR_MB | RT5659_PWR_VREF1 | RT5659_PWR_VREF2
3590 | RT5659_PWR_FV1 | RT5659_PWR_FV2,
3591 RT5659_PWR_MB | RT5659_PWR_VREF2);
3592 regmap_update_bits(rt5659->regmap, RT5659_DIG_MISC,
3593 RT5659_DIG_GATE_CTRL, 0);
3594 break;
3595
3596 default:
3597 break;
3598 }
3599
3600 return 0;
3601}
3602
3603static int rt5659_probe(struct snd_soc_codec *codec)
3604{
3605 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3606
3607 rt5659->codec = codec;
3608
3609 return 0;
3610}
3611
3612static int rt5659_remove(struct snd_soc_codec *codec)
3613{
3614 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3615
3616 regmap_write(rt5659->regmap, RT5659_RESET, 0);
3617
3618 return 0;
3619}
3620
3621#ifdef CONFIG_PM
3622static int rt5659_suspend(struct snd_soc_codec *codec)
3623{
3624 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3625
3626 regcache_cache_only(rt5659->regmap, true);
3627 regcache_mark_dirty(rt5659->regmap);
3628 return 0;
3629}
3630
3631static int rt5659_resume(struct snd_soc_codec *codec)
3632{
3633 struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
3634
3635 regcache_cache_only(rt5659->regmap, false);
3636 regcache_sync(rt5659->regmap);
3637
3638 return 0;
3639}
3640#else
3641#define rt5659_suspend NULL
3642#define rt5659_resume NULL
3643#endif
3644
3645#define RT5659_STEREO_RATES SNDRV_PCM_RATE_8000_192000
3646#define RT5659_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
3647 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
3648
3649static const struct snd_soc_dai_ops rt5659_aif_dai_ops = {
3650 .hw_params = rt5659_hw_params,
3651 .set_fmt = rt5659_set_dai_fmt,
3652 .set_sysclk = rt5659_set_dai_sysclk,
3653 .set_tdm_slot = rt5659_set_tdm_slot,
3654 .set_pll = rt5659_set_dai_pll,
3655 .set_bclk_ratio = rt5659_set_bclk_ratio,
3656};
3657
3658static struct snd_soc_dai_driver rt5659_dai[] = {
3659 {
3660 .name = "rt5659-aif1",
3661 .id = RT5659_AIF1,
3662 .playback = {
3663 .stream_name = "AIF1 Playback",
3664 .channels_min = 1,
3665 .channels_max = 2,
3666 .rates = RT5659_STEREO_RATES,
3667 .formats = RT5659_FORMATS,
3668 },
3669 .capture = {
3670 .stream_name = "AIF1 Capture",
3671 .channels_min = 1,
3672 .channels_max = 2,
3673 .rates = RT5659_STEREO_RATES,
3674 .formats = RT5659_FORMATS,
3675 },
3676 .ops = &rt5659_aif_dai_ops,
3677 },
3678 {
3679 .name = "rt5659-aif2",
3680 .id = RT5659_AIF2,
3681 .playback = {
3682 .stream_name = "AIF2 Playback",
3683 .channels_min = 1,
3684 .channels_max = 2,
3685 .rates = RT5659_STEREO_RATES,
3686 .formats = RT5659_FORMATS,
3687 },
3688 .capture = {
3689 .stream_name = "AIF2 Capture",
3690 .channels_min = 1,
3691 .channels_max = 2,
3692 .rates = RT5659_STEREO_RATES,
3693 .formats = RT5659_FORMATS,
3694 },
3695 .ops = &rt5659_aif_dai_ops,
3696 },
3697 {
3698 .name = "rt5659-aif3",
3699 .id = RT5659_AIF3,
3700 .playback = {
3701 .stream_name = "AIF3 Playback",
3702 .channels_min = 1,
3703 .channels_max = 2,
3704 .rates = RT5659_STEREO_RATES,
3705 .formats = RT5659_FORMATS,
3706 },
3707 .capture = {
3708 .stream_name = "AIF3 Capture",
3709 .channels_min = 1,
3710 .channels_max = 2,
3711 .rates = RT5659_STEREO_RATES,
3712 .formats = RT5659_FORMATS,
3713 },
3714 .ops = &rt5659_aif_dai_ops,
3715 },
3716};
3717
3718static struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
3719 .probe = rt5659_probe,
3720 .remove = rt5659_remove,
3721 .suspend = rt5659_suspend,
3722 .resume = rt5659_resume,
3723 .set_bias_level = rt5659_set_bias_level,
3724 .idle_bias_off = true,
3725 .controls = rt5659_snd_controls,
3726 .num_controls = ARRAY_SIZE(rt5659_snd_controls),
3727 .dapm_widgets = rt5659_dapm_widgets,
3728 .num_dapm_widgets = ARRAY_SIZE(rt5659_dapm_widgets),
3729 .dapm_routes = rt5659_dapm_routes,
3730 .num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
3731};
3732
3733
3734static const struct regmap_config rt5659_regmap = {
3735 .reg_bits = 16,
3736 .val_bits = 16,
3737 .max_register = 0x0400,
3738 .volatile_reg = rt5659_volatile_register,
3739 .readable_reg = rt5659_readable_register,
3740 .cache_type = REGCACHE_RBTREE,
3741 .reg_defaults = rt5659_reg,
3742 .num_reg_defaults = ARRAY_SIZE(rt5659_reg),
3743};
3744
3745static const struct i2c_device_id rt5659_i2c_id[] = {
3746 { "rt5658", 0 },
3747 { "rt5659", 0 },
3748 { }
3749};
3750MODULE_DEVICE_TABLE(i2c, rt5659_i2c_id);
3751
3752static int rt5659_parse_dt(struct rt5659_priv *rt5659, struct device *dev)
3753{
3754 rt5659->pdata.in1_diff = device_property_read_bool(dev,
3755 "realtek,in1-differential");
3756 rt5659->pdata.in3_diff = device_property_read_bool(dev,
3757 "realtek,in3-differential");
3758 rt5659->pdata.in4_diff = device_property_read_bool(dev,
3759 "realtek,in4-differential");
3760
3761
3762 device_property_read_u32(dev, "realtek,dmic1-data-pin",
3763 &rt5659->pdata.dmic1_data_pin);
3764 device_property_read_u32(dev, "realtek,dmic2-data-pin",
3765 &rt5659->pdata.dmic2_data_pin);
3766 device_property_read_u32(dev, "realtek,jd-src",
3767 &rt5659->pdata.jd_src);
3768
3769 return 0;
3770}
3771
3772static void rt5659_calibrate(struct rt5659_priv *rt5659)
3773{
3774 int value, count;
3775
3776 /* Calibrate HPO Start */
3777 /* Fine tune HP Performance */
3778 regmap_write(rt5659->regmap, RT5659_BIAS_CUR_CTRL_8, 0xa502);
3779 regmap_write(rt5659->regmap, RT5659_CHOP_DAC, 0x3030);
3780
3781 regmap_write(rt5659->regmap, RT5659_PRE_DIV_1, 0xef00);
3782 regmap_write(rt5659->regmap, RT5659_PRE_DIV_2, 0xeffc);
3783 regmap_write(rt5659->regmap, RT5659_MICBIAS_2, 0x0280);
3784 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x0001);
3785 regmap_write(rt5659->regmap, RT5659_GLB_CLK, 0x8000);
3786
3787 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xaa7e);
3788 msleep(60);
3789 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xfe7e);
3790 msleep(50);
3791 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0004);
3792 regmap_write(rt5659->regmap, RT5659_PWR_DIG_2, 0x0400);
3793 msleep(50);
3794 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0080);
3795 usleep_range(10000, 10005);
3796 regmap_write(rt5659->regmap, RT5659_DEPOP_1, 0x0009);
3797 msleep(50);
3798 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0f80);
3799 msleep(50);
3800 regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0e16);
3801 msleep(50);
3802
3803 /* Enalbe K ADC Power And Clock */
3804 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0505);
3805 msleep(50);
3806 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0184);
3807 regmap_write(rt5659->regmap, RT5659_CALIB_ADC_CTRL, 0x3c05);
3808 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c1);
3809
3810 /* K Headphone */
3811 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3812 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x5100);
3813 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0014);
3814 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0xd100);
3815 msleep(60);
3816
3817 /* Manual K ADC Offset */
3818 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3819 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x4900);
3820 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0016);
3821 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_1,
3822 0x8000, 0x8000);
3823
3824 count = 0;
3825 while (true) {
3826 regmap_read(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, &value);
3827 if (value & 0x8000)
3828 usleep_range(10000, 10005);
3829 else
3830 break;
3831
3832 if (count > 30) {
3833 dev_err(rt5659->codec->dev,
3834 "HP Calibration 1 Failure\n");
3835 return;
3836 }
3837
3838 count++;
3839 }
3840
3841 /* Manual K Internal Path Offset */
3842 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x2cc1);
3843 regmap_write(rt5659->regmap, RT5659_HP_VOL, 0x0000);
3844 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, 0x4500);
3845 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x001f);
3846 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_1,
3847 0x8000, 0x8000);
3848
3849 count = 0;
3850 while (true) {
3851 regmap_read(rt5659->regmap, RT5659_HP_CALIB_CTRL_1, &value);
3852 if (value & 0x8000)
3853 usleep_range(10000, 10005);
3854 else
3855 break;
3856
3857 if (count > 85) {
3858 dev_err(rt5659->codec->dev,
3859 "HP Calibration 2 Failure\n");
3860 return;
3861 }
3862
3863 count++;
3864 }
3865
3866 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_7, 0x0000);
3867 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c0);
3868 /* Calibrate HPO End */
3869
3870 /* Calibrate SPO Start */
3871 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x2021);
3872 regmap_write(rt5659->regmap, RT5659_CLASSD_CTRL_1, 0x0260);
3873 regmap_write(rt5659->regmap, RT5659_PWR_MIXER, 0x3000);
3874 regmap_write(rt5659->regmap, RT5659_PWR_VOL, 0xc000);
3875 regmap_write(rt5659->regmap, RT5659_A_DAC_MUX, 0x000c);
3876 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x8000);
3877 regmap_write(rt5659->regmap, RT5659_SPO_VOL, 0x0808);
3878 regmap_write(rt5659->regmap, RT5659_SPK_L_MIXER, 0x001e);
3879 regmap_write(rt5659->regmap, RT5659_SPK_R_MIXER, 0x001e);
3880 regmap_write(rt5659->regmap, RT5659_CLASSD_1, 0x0803);
3881 regmap_write(rt5659->regmap, RT5659_CLASSD_2, 0x0554);
3882 regmap_write(rt5659->regmap, RT5659_SPO_AMP_GAIN, 0x1103);
3883
3884 /* Enalbe K ADC Power And Clock */
3885 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0909);
3886 regmap_update_bits(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x0001,
3887 0x0001);
3888
3889 /* Start Calibration */
3890 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x0000);
3891 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x0021);
3892 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_1, 0x3e80);
3893 regmap_update_bits(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_1,
3894 0x8000, 0x8000);
3895
3896 count = 0;
3897 while (true) {
3898 regmap_read(rt5659->regmap,
3899 RT5659_SPK_DC_CAILB_CTRL_1, &value);
3900 if (value & 0x8000)
3901 usleep_range(10000, 10005);
3902 else
3903 break;
3904
3905 if (count > 10) {
3906 dev_err(rt5659->codec->dev,
3907 "SPK Calibration Failure\n");
3908 return;
3909 }
3910
3911 count++;
3912 }
3913 /* Calibrate SPO End */
3914
3915 /* Calibrate MONO Start */
3916 regmap_write(rt5659->regmap, RT5659_DIG_MISC, 0x0000);
3917 regmap_write(rt5659->regmap, RT5659_MONOMIX_IN_GAIN, 0x021f);
3918 regmap_write(rt5659->regmap, RT5659_MONO_OUT, 0x480a);
3919 /* MONO NG2 GAIN 5dB */
3920 regmap_write(rt5659->regmap, RT5659_MONO_GAIN, 0x0003);
3921 regmap_write(rt5659->regmap, RT5659_MONO_NG2_CTRL_5, 0x0009);
3922
3923 /* Start Calibration */
3924 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x000f);
3925 regmap_write(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e00);
3926 regmap_update_bits(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1,
3927 0x8000, 0x8000);
3928
3929 count = 0;
3930 while (true) {
3931 regmap_read(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1,
3932 &value);
3933 if (value & 0x8000)
3934 usleep_range(10000, 10005);
3935 else
3936 break;
3937
3938 if (count > 35) {
3939 dev_err(rt5659->codec->dev,
3940 "Mono Calibration Failure\n");
3941 return;
3942 }
3943
3944 count++;
3945 }
3946
3947 regmap_write(rt5659->regmap, RT5659_SPK_DC_CAILB_CTRL_3, 0x0003);
3948 /* Calibrate MONO End */
3949
3950 /* Power Off */
3951 regmap_write(rt5659->regmap, RT5659_CAL_REC, 0x0808);
3952 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_3, 0x0000);
3953 regmap_write(rt5659->regmap, RT5659_CALIB_ADC_CTRL, 0x2005);
3954 regmap_write(rt5659->regmap, RT5659_HP_CALIB_CTRL_2, 0x20c0);
3955 regmap_write(rt5659->regmap, RT5659_DEPOP_1, 0x0000);
3956 regmap_write(rt5659->regmap, RT5659_CLASSD_1, 0x0011);
3957 regmap_write(rt5659->regmap, RT5659_CLASSD_2, 0x0150);
3958 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0xfe3e);
3959 regmap_write(rt5659->regmap, RT5659_MONO_OUT, 0xc80a);
3960 regmap_write(rt5659->regmap, RT5659_MONO_AMP_CALIB_CTRL_1, 0x1e04);
3961 regmap_write(rt5659->regmap, RT5659_PWR_MIXER, 0x0000);
3962 regmap_write(rt5659->regmap, RT5659_PWR_VOL, 0x0000);
3963 regmap_write(rt5659->regmap, RT5659_PWR_DIG_1, 0x0000);
3964 regmap_write(rt5659->regmap, RT5659_PWR_DIG_2, 0x0000);
3965 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_1, 0x003e);
3966 regmap_write(rt5659->regmap, RT5659_CLASSD_CTRL_1, 0x0060);
3967 regmap_write(rt5659->regmap, RT5659_CLASSD_0, 0x2021);
3968 regmap_write(rt5659->regmap, RT5659_GLB_CLK, 0x0000);
3969 regmap_write(rt5659->regmap, RT5659_MICBIAS_2, 0x0080);
3970 regmap_write(rt5659->regmap, RT5659_HP_VOL, 0x8080);
3971 regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
3972}
3973
3974static int rt5659_i2c_probe(struct i2c_client *i2c,
3975 const struct i2c_device_id *id)
3976{
3977 struct rt5659_platform_data *pdata = dev_get_platdata(&i2c->dev);
3978 struct rt5659_priv *rt5659;
3979 int ret;
3980 unsigned int val;
3981
3982 rt5659 = devm_kzalloc(&i2c->dev, sizeof(struct rt5659_priv),
3983 GFP_KERNEL);
3984
3985 if (rt5659 == NULL)
3986 return -ENOMEM;
3987
3988 rt5659->i2c = i2c;
3989 i2c_set_clientdata(i2c, rt5659);
3990
3991 if (pdata)
3992 rt5659->pdata = *pdata;
3993 else
3994 rt5659_parse_dt(rt5659, &i2c->dev);
3995
3996 rt5659->gpiod_ldo1_en = devm_gpiod_get_optional(&i2c->dev, "ldo1-en",
3997 GPIOD_OUT_HIGH);
3998 if (IS_ERR(rt5659->gpiod_ldo1_en))
3999 dev_warn(&i2c->dev, "Request ldo1-en GPIO failed\n");
4000
4001 rt5659->gpiod_reset = devm_gpiod_get_optional(&i2c->dev, "reset",
4002 GPIOD_OUT_HIGH);
4003
4004 /* Sleep for 300 ms miniumum */
4005 usleep_range(300000, 350000);
4006
4007 rt5659->regmap = devm_regmap_init_i2c(i2c, &rt5659_regmap);
4008 if (IS_ERR(rt5659->regmap)) {
4009 ret = PTR_ERR(rt5659->regmap);
4010 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
4011 ret);
4012 return ret;
4013 }
4014
4015 regmap_read(rt5659->regmap, RT5659_DEVICE_ID, &val);
4016 if (val != DEVICE_ID) {
4017 dev_err(&i2c->dev,
4018 "Device with ID register %x is not rt5659\n", val);
4019 return -ENODEV;
4020 }
4021
4022 regmap_write(rt5659->regmap, RT5659_RESET, 0);
4023
4024 rt5659_calibrate(rt5659);
4025
4026 /* line in diff mode*/
4027 if (rt5659->pdata.in1_diff)
4028 regmap_update_bits(rt5659->regmap, RT5659_IN1_IN2,
4029 RT5659_IN1_DF_MASK, RT5659_IN1_DF_MASK);
4030 if (rt5659->pdata.in3_diff)
4031 regmap_update_bits(rt5659->regmap, RT5659_IN3_IN4,
4032 RT5659_IN3_DF_MASK, RT5659_IN3_DF_MASK);
4033 if (rt5659->pdata.in4_diff)
4034 regmap_update_bits(rt5659->regmap, RT5659_IN3_IN4,
4035 RT5659_IN4_DF_MASK, RT5659_IN4_DF_MASK);
4036
4037 /* DMIC pin*/
4038 if (rt5659->pdata.dmic1_data_pin != RT5659_DMIC1_NULL ||
4039 rt5659->pdata.dmic2_data_pin != RT5659_DMIC2_NULL) {
4040 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4041 RT5659_GP2_PIN_MASK, RT5659_GP2_PIN_DMIC1_SCL);
4042
4043 switch (rt5659->pdata.dmic1_data_pin) {
4044 case RT5659_DMIC1_DATA_IN2N:
4045 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4046 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_IN2N);
4047 break;
4048
4049 case RT5659_DMIC1_DATA_GPIO5:
4050 regmap_update_bits(rt5659->regmap,
4051 RT5659_GPIO_CTRL_3,
4052 RT5659_I2S2_PIN_MASK,
4053 RT5659_I2S2_PIN_GPIO);
4054 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4055 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO5);
4056 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4057 RT5659_GP5_PIN_MASK, RT5659_GP5_PIN_DMIC1_SDA);
4058 break;
4059
4060 case RT5659_DMIC1_DATA_GPIO9:
4061 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4062 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO9);
4063 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4064 RT5659_GP9_PIN_MASK, RT5659_GP9_PIN_DMIC1_SDA);
4065 break;
4066
4067 case RT5659_DMIC1_DATA_GPIO11:
4068 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4069 RT5659_DMIC_1_DP_MASK, RT5659_DMIC_1_DP_GPIO11);
4070 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4071 RT5659_GP11_PIN_MASK,
4072 RT5659_GP11_PIN_DMIC1_SDA);
4073 break;
4074
4075 default:
4076 dev_dbg(&i2c->dev, "no DMIC1\n");
4077 break;
4078 }
4079
4080 switch (rt5659->pdata.dmic2_data_pin) {
4081 case RT5659_DMIC2_DATA_IN2P:
4082 regmap_update_bits(rt5659->regmap,
4083 RT5659_DMIC_CTRL_1,
4084 RT5659_DMIC_2_DP_MASK,
4085 RT5659_DMIC_2_DP_IN2P);
4086 break;
4087
4088 case RT5659_DMIC2_DATA_GPIO6:
4089 regmap_update_bits(rt5659->regmap,
4090 RT5659_DMIC_CTRL_1,
4091 RT5659_DMIC_2_DP_MASK,
4092 RT5659_DMIC_2_DP_GPIO6);
4093 regmap_update_bits(rt5659->regmap,
4094 RT5659_GPIO_CTRL_1,
4095 RT5659_GP6_PIN_MASK,
4096 RT5659_GP6_PIN_DMIC2_SDA);
4097 break;
4098
4099 case RT5659_DMIC2_DATA_GPIO10:
4100 regmap_update_bits(rt5659->regmap,
4101 RT5659_DMIC_CTRL_1,
4102 RT5659_DMIC_2_DP_MASK,
4103 RT5659_DMIC_2_DP_GPIO10);
4104 regmap_update_bits(rt5659->regmap,
4105 RT5659_GPIO_CTRL_1,
4106 RT5659_GP10_PIN_MASK,
4107 RT5659_GP10_PIN_DMIC2_SDA);
4108 break;
4109
4110 case RT5659_DMIC2_DATA_GPIO12:
4111 regmap_update_bits(rt5659->regmap,
4112 RT5659_DMIC_CTRL_1,
4113 RT5659_DMIC_2_DP_MASK,
4114 RT5659_DMIC_2_DP_GPIO12);
4115 regmap_update_bits(rt5659->regmap,
4116 RT5659_GPIO_CTRL_1,
4117 RT5659_GP12_PIN_MASK,
4118 RT5659_GP12_PIN_DMIC2_SDA);
4119 break;
4120
4121 default:
4122 dev_dbg(&i2c->dev, "no DMIC2\n");
4123 break;
4124
4125 }
4126 } else {
4127 regmap_update_bits(rt5659->regmap, RT5659_GPIO_CTRL_1,
4128 RT5659_GP2_PIN_MASK | RT5659_GP5_PIN_MASK |
4129 RT5659_GP9_PIN_MASK | RT5659_GP11_PIN_MASK |
4130 RT5659_GP6_PIN_MASK | RT5659_GP10_PIN_MASK |
4131 RT5659_GP12_PIN_MASK,
4132 RT5659_GP2_PIN_GPIO2 | RT5659_GP5_PIN_GPIO5 |
4133 RT5659_GP9_PIN_GPIO9 | RT5659_GP11_PIN_GPIO11 |
4134 RT5659_GP6_PIN_GPIO6 | RT5659_GP10_PIN_GPIO10 |
4135 RT5659_GP12_PIN_GPIO12);
4136 regmap_update_bits(rt5659->regmap, RT5659_DMIC_CTRL_1,
4137 RT5659_DMIC_1_DP_MASK | RT5659_DMIC_2_DP_MASK,
4138 RT5659_DMIC_1_DP_IN2N | RT5659_DMIC_2_DP_IN2P);
4139 }
4140
4141 switch (rt5659->pdata.jd_src) {
4142 case RT5659_JD3:
4143 regmap_write(rt5659->regmap, RT5659_EJD_CTRL_1, 0xa880);
4144 regmap_write(rt5659->regmap, RT5659_RC_CLK_CTRL, 0x9000);
4145 regmap_write(rt5659->regmap, RT5659_GPIO_CTRL_1, 0xc800);
4146 regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
4147 RT5659_PWR_MB, RT5659_PWR_MB);
4148 regmap_write(rt5659->regmap, RT5659_PWR_ANLG_2, 0x0001);
4149 regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_2, 0x0040);
4150 break;
4151 case RT5659_JD_NULL:
4152 break;
4153 default:
4154 dev_warn(&i2c->dev, "Currently, support JD3 only\n");
4155 break;
4156 }
4157
4158 INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
4159
4160 if (rt5659->i2c->irq) {
4161 ret = request_threaded_irq(rt5659->i2c->irq, NULL, rt5659_irq,
4162 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
4163 | IRQF_ONESHOT, "rt5659", rt5659);
4164 if (ret)
4165 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
4166
4167 }
4168
4169 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
4170 rt5659_dai, ARRAY_SIZE(rt5659_dai));
4171
4172 if (ret) {
4173 if (rt5659->i2c->irq)
4174 free_irq(rt5659->i2c->irq, rt5659);
4175 }
4176
4177 return 0;
4178}
4179
4180static int rt5659_i2c_remove(struct i2c_client *i2c)
4181{
4182 snd_soc_unregister_codec(&i2c->dev);
4183
4184 return 0;
4185}
4186
4187void rt5659_i2c_shutdown(struct i2c_client *client)
4188{
4189 struct rt5659_priv *rt5659 = i2c_get_clientdata(client);
4190
4191 regmap_write(rt5659->regmap, RT5659_RESET, 0);
4192}
4193
4194static const struct of_device_id rt5659_of_match[] = {
4195 { .compatible = "realtek,rt5658", },
4196 { .compatible = "realtek,rt5659", },
4197 {},
4198};
4199
4200static struct acpi_device_id rt5659_acpi_match[] = {
4201 { "10EC5658", 0},
4202 { "10EC5659", 0},
4203 { },
4204};
4205MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match);
4206
4207struct i2c_driver rt5659_i2c_driver = {
4208 .driver = {
4209 .name = "rt5659",
4210 .owner = THIS_MODULE,
4211 .of_match_table = rt5659_of_match,
4212 .acpi_match_table = ACPI_PTR(rt5659_acpi_match),
4213 },
4214 .probe = rt5659_i2c_probe,
4215 .remove = rt5659_i2c_remove,
4216 .shutdown = rt5659_i2c_shutdown,
4217 .id_table = rt5659_i2c_id,
4218};
4219module_i2c_driver(rt5659_i2c_driver);
4220
4221MODULE_DESCRIPTION("ASoC RT5659 driver");
4222MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
4223MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h
new file mode 100644
index 000000000000..8f07ee903eaa
--- /dev/null
+++ b/sound/soc/codecs/rt5659.h
@@ -0,0 +1,1819 @@
1/*
2 * rt5659.h -- RT5659/RT5658 ALSA SoC audio driver
3 *
4 * Copyright 2015 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 __RT5659_H__
13#define __RT5659_H__
14
15#include <sound/rt5659.h>
16
17#define DEVICE_ID 0x6311
18
19/* Info */
20#define RT5659_RESET 0x0000
21#define RT5659_VENDOR_ID 0x00fd
22#define RT5659_VENDOR_ID_1 0x00fe
23#define RT5659_DEVICE_ID 0x00ff
24/* I/O - Output */
25#define RT5659_SPO_VOL 0x0001
26#define RT5659_HP_VOL 0x0002
27#define RT5659_LOUT 0x0003
28#define RT5659_MONO_OUT 0x0004
29#define RT5659_HPL_GAIN 0x0005
30#define RT5659_HPR_GAIN 0x0006
31#define RT5659_MONO_GAIN 0x0007
32#define RT5659_SPDIF_CTRL_1 0x0008
33#define RT5659_SPDIF_CTRL_2 0x0009
34/* I/O - Input */
35#define RT5659_CAL_BST_CTRL 0x000a
36#define RT5659_IN1_IN2 0x000c
37#define RT5659_IN3_IN4 0x000d
38#define RT5659_INL1_INR1_VOL 0x000f
39/* I/O - Speaker */
40#define RT5659_EJD_CTRL_1 0x0010
41#define RT5659_EJD_CTRL_2 0x0011
42#define RT5659_EJD_CTRL_3 0x0012
43#define RT5659_SILENCE_CTRL 0x0015
44#define RT5659_PSV_CTRL 0x0016
45/* I/O - Sidetone */
46#define RT5659_SIDETONE_CTRL 0x0018
47/* I/O - ADC/DAC/DMIC */
48#define RT5659_DAC1_DIG_VOL 0x0019
49#define RT5659_DAC2_DIG_VOL 0x001a
50#define RT5659_DAC_CTRL 0x001b
51#define RT5659_STO1_ADC_DIG_VOL 0x001c
52#define RT5659_MONO_ADC_DIG_VOL 0x001d
53#define RT5659_STO2_ADC_DIG_VOL 0x001e
54#define RT5659_STO1_BOOST 0x001f
55#define RT5659_MONO_BOOST 0x0020
56#define RT5659_STO2_BOOST 0x0021
57#define RT5659_HP_IMP_GAIN_1 0x0022
58#define RT5659_HP_IMP_GAIN_2 0x0023
59/* Mixer - D-D */
60#define RT5659_STO1_ADC_MIXER 0x0026
61#define RT5659_MONO_ADC_MIXER 0x0027
62#define RT5659_AD_DA_MIXER 0x0029
63#define RT5659_STO_DAC_MIXER 0x002a
64#define RT5659_MONO_DAC_MIXER 0x002b
65#define RT5659_DIG_MIXER 0x002c
66#define RT5659_A_DAC_MUX 0x002d
67#define RT5659_DIG_INF23_DATA 0x002f
68/* Mixer - PDM */
69#define RT5659_PDM_OUT_CTRL 0x0031
70#define RT5659_PDM_DATA_CTRL_1 0x0032
71#define RT5659_PDM_DATA_CTRL_2 0x0033
72#define RT5659_PDM_DATA_CTRL_3 0x0034
73#define RT5659_PDM_DATA_CTRL_4 0x0035
74#define RT5659_SPDIF_CTRL 0x0036
75
76/* Mixer - ADC */
77#define RT5659_REC1_GAIN 0x003a
78#define RT5659_REC1_L1_MIXER 0x003b
79#define RT5659_REC1_L2_MIXER 0x003c
80#define RT5659_REC1_R1_MIXER 0x003d
81#define RT5659_REC1_R2_MIXER 0x003e
82#define RT5659_CAL_REC 0x0040
83#define RT5659_REC2_L1_MIXER 0x009b
84#define RT5659_REC2_L2_MIXER 0x009c
85#define RT5659_REC2_R1_MIXER 0x009d
86#define RT5659_REC2_R2_MIXER 0x009e
87#define RT5659_RC_CLK_CTRL 0x009f
88/* Mixer - DAC */
89#define RT5659_SPK_L_MIXER 0x0046
90#define RT5659_SPK_R_MIXER 0x0047
91#define RT5659_SPO_AMP_GAIN 0x0048
92#define RT5659_ALC_BACK_GAIN 0x0049
93#define RT5659_MONOMIX_GAIN 0x004a
94#define RT5659_MONOMIX_IN_GAIN 0x004b
95#define RT5659_OUT_L_GAIN 0x004d
96#define RT5659_OUT_L_MIXER 0x004e
97#define RT5659_OUT_R_GAIN 0x004f
98#define RT5659_OUT_R_MIXER 0x0050
99#define RT5659_LOUT_MIXER 0x0052
100
101#define RT5659_HAPTIC_GEN_CTRL_1 0x0053
102#define RT5659_HAPTIC_GEN_CTRL_2 0x0054
103#define RT5659_HAPTIC_GEN_CTRL_3 0x0055
104#define RT5659_HAPTIC_GEN_CTRL_4 0x0056
105#define RT5659_HAPTIC_GEN_CTRL_5 0x0057
106#define RT5659_HAPTIC_GEN_CTRL_6 0x0058
107#define RT5659_HAPTIC_GEN_CTRL_7 0x0059
108#define RT5659_HAPTIC_GEN_CTRL_8 0x005a
109#define RT5659_HAPTIC_GEN_CTRL_9 0x005b
110#define RT5659_HAPTIC_GEN_CTRL_10 0x005c
111#define RT5659_HAPTIC_GEN_CTRL_11 0x005d
112#define RT5659_HAPTIC_LPF_CTRL_1 0x005e
113#define RT5659_HAPTIC_LPF_CTRL_2 0x005f
114#define RT5659_HAPTIC_LPF_CTRL_3 0x0060
115/* Power */
116#define RT5659_PWR_DIG_1 0x0061
117#define RT5659_PWR_DIG_2 0x0062
118#define RT5659_PWR_ANLG_1 0x0063
119#define RT5659_PWR_ANLG_2 0x0064
120#define RT5659_PWR_ANLG_3 0x0065
121#define RT5659_PWR_MIXER 0x0066
122#define RT5659_PWR_VOL 0x0067
123/* Private Register Control */
124#define RT5659_PRIV_INDEX 0x006a
125#define RT5659_CLK_DET 0x006b
126#define RT5659_PRIV_DATA 0x006c
127/* System Clock Pre Divider Gating Control */
128#define RT5659_PRE_DIV_1 0x006e
129#define RT5659_PRE_DIV_2 0x006f
130/* Format - ADC/DAC */
131#define RT5659_I2S1_SDP 0x0070
132#define RT5659_I2S2_SDP 0x0071
133#define RT5659_I2S3_SDP 0x0072
134#define RT5659_ADDA_CLK_1 0x0073
135#define RT5659_ADDA_CLK_2 0x0074
136#define RT5659_DMIC_CTRL_1 0x0075
137#define RT5659_DMIC_CTRL_2 0x0076
138/* Format - TDM Control */
139#define RT5659_TDM_CTRL_1 0x0077
140#define RT5659_TDM_CTRL_2 0x0078
141#define RT5659_TDM_CTRL_3 0x0079
142#define RT5659_TDM_CTRL_4 0x007a
143#define RT5659_TDM_CTRL_5 0x007b
144
145/* Function - Analog */
146#define RT5659_GLB_CLK 0x0080
147#define RT5659_PLL_CTRL_1 0x0081
148#define RT5659_PLL_CTRL_2 0x0082
149#define RT5659_ASRC_1 0x0083
150#define RT5659_ASRC_2 0x0084
151#define RT5659_ASRC_3 0x0085
152#define RT5659_ASRC_4 0x0086
153#define RT5659_ASRC_5 0x0087
154#define RT5659_ASRC_6 0x0088
155#define RT5659_ASRC_7 0x0089
156#define RT5659_ASRC_8 0x008a
157#define RT5659_ASRC_9 0x008b
158#define RT5659_ASRC_10 0x008c
159#define RT5659_DEPOP_1 0x008e
160#define RT5659_DEPOP_2 0x008f
161#define RT5659_DEPOP_3 0x0090
162#define RT5659_HP_CHARGE_PUMP_1 0x0091
163#define RT5659_HP_CHARGE_PUMP_2 0x0092
164#define RT5659_MICBIAS_1 0x0093
165#define RT5659_MICBIAS_2 0x0094
166#define RT5659_ASRC_11 0x0097
167#define RT5659_ASRC_12 0x0098
168#define RT5659_ASRC_13 0x0099
169#define RT5659_REC_M1_M2_GAIN_CTRL 0x009a
170#define RT5659_CLASSD_CTRL_1 0x00a0
171#define RT5659_CLASSD_CTRL_2 0x00a1
172
173/* Function - Digital */
174#define RT5659_ADC_EQ_CTRL_1 0x00ae
175#define RT5659_ADC_EQ_CTRL_2 0x00af
176#define RT5659_DAC_EQ_CTRL_1 0x00b0
177#define RT5659_DAC_EQ_CTRL_2 0x00b1
178#define RT5659_DAC_EQ_CTRL_3 0x00b2
179
180#define RT5659_IRQ_CTRL_1 0x00b6
181#define RT5659_IRQ_CTRL_2 0x00b7
182#define RT5659_IRQ_CTRL_3 0x00b8
183#define RT5659_IRQ_CTRL_4 0x00b9
184#define RT5659_IRQ_CTRL_5 0x00ba
185#define RT5659_IRQ_CTRL_6 0x00bb
186#define RT5659_INT_ST_1 0x00be
187#define RT5659_INT_ST_2 0x00bf
188#define RT5659_GPIO_CTRL_1 0x00c0
189#define RT5659_GPIO_CTRL_2 0x00c1
190#define RT5659_GPIO_CTRL_3 0x00c2
191#define RT5659_GPIO_CTRL_4 0x00c3
192#define RT5659_GPIO_CTRL_5 0x00c4
193#define RT5659_GPIO_STA 0x00c5
194#define RT5659_SINE_GEN_CTRL_1 0x00cb
195#define RT5659_SINE_GEN_CTRL_2 0x00cc
196#define RT5659_SINE_GEN_CTRL_3 0x00cd
197#define RT5659_HP_AMP_DET_CTRL_1 0x00d6
198#define RT5659_HP_AMP_DET_CTRL_2 0x00d7
199#define RT5659_SV_ZCD_1 0x00d9
200#define RT5659_SV_ZCD_2 0x00da
201#define RT5659_IL_CMD_1 0x00db
202#define RT5659_IL_CMD_2 0x00dc
203#define RT5659_IL_CMD_3 0x00dd
204#define RT5659_IL_CMD_4 0x00de
205#define RT5659_4BTN_IL_CMD_1 0x00df
206#define RT5659_4BTN_IL_CMD_2 0x00e0
207#define RT5659_4BTN_IL_CMD_3 0x00e1
208#define RT5659_PSV_IL_CMD_1 0x00e4
209#define RT5659_PSV_IL_CMD_2 0x00e5
210
211#define RT5659_ADC_STO1_HP_CTRL_1 0x00ea
212#define RT5659_ADC_STO1_HP_CTRL_2 0x00eb
213#define RT5659_ADC_MONO_HP_CTRL_1 0x00ec
214#define RT5659_ADC_MONO_HP_CTRL_2 0x00ed
215#define RT5659_AJD1_CTRL 0x00f0
216#define RT5659_AJD2_AJD3_CTRL 0x00f1
217#define RT5659_JD1_THD 0x00f2
218#define RT5659_JD2_THD 0x00f3
219#define RT5659_JD3_THD 0x00f4
220#define RT5659_JD_CTRL_1 0x00f6
221#define RT5659_JD_CTRL_2 0x00f7
222#define RT5659_JD_CTRL_3 0x00f8
223#define RT5659_JD_CTRL_4 0x00f9
224/* General Control */
225#define RT5659_DIG_MISC 0x00fa
226#define RT5659_DUMMY_2 0x00fb
227#define RT5659_DUMMY_3 0x00fc
228
229#define RT5659_DAC_ADC_DIG_VOL 0x0100
230#define RT5659_BIAS_CUR_CTRL_1 0x010a
231#define RT5659_BIAS_CUR_CTRL_2 0x010b
232#define RT5659_BIAS_CUR_CTRL_3 0x010c
233#define RT5659_BIAS_CUR_CTRL_4 0x010d
234#define RT5659_BIAS_CUR_CTRL_5 0x010e
235#define RT5659_BIAS_CUR_CTRL_6 0x010f
236#define RT5659_BIAS_CUR_CTRL_7 0x0110
237#define RT5659_BIAS_CUR_CTRL_8 0x0111
238#define RT5659_BIAS_CUR_CTRL_9 0x0112
239#define RT5659_BIAS_CUR_CTRL_10 0x0113
240#define RT5659_MEMORY_TEST 0x0116
241#define RT5659_VREF_REC_OP_FB_CAP_CTRL 0x0117
242#define RT5659_CLASSD_0 0x011a
243#define RT5659_CLASSD_1 0x011b
244#define RT5659_CLASSD_2 0x011c
245#define RT5659_CLASSD_3 0x011d
246#define RT5659_CLASSD_4 0x011e
247#define RT5659_CLASSD_5 0x011f
248#define RT5659_CLASSD_6 0x0120
249#define RT5659_CLASSD_7 0x0121
250#define RT5659_CLASSD_8 0x0122
251#define RT5659_CLASSD_9 0x0123
252#define RT5659_CLASSD_10 0x0124
253#define RT5659_CHARGE_PUMP_1 0x0125
254#define RT5659_CHARGE_PUMP_2 0x0126
255#define RT5659_DIG_IN_CTRL_1 0x0132
256#define RT5659_DIG_IN_CTRL_2 0x0133
257#define RT5659_PAD_DRIVING_CTRL 0x0137
258#define RT5659_SOFT_RAMP_DEPOP 0x0138
259#define RT5659_PLL 0x0139
260#define RT5659_CHOP_DAC 0x013a
261#define RT5659_CHOP_ADC 0x013b
262#define RT5659_CALIB_ADC_CTRL 0x013c
263#define RT5659_SOFT_RAMP_DEPOP_DAC_CLK_CTRL 0x013e
264#define RT5659_VOL_TEST 0x013f
265#define RT5659_TEST_MODE_CTRL_1 0x0145
266#define RT5659_TEST_MODE_CTRL_2 0x0146
267#define RT5659_TEST_MODE_CTRL_3 0x0147
268#define RT5659_TEST_MODE_CTRL_4 0x0148
269#define RT5659_BASSBACK_CTRL 0x0150
270#define RT5659_MP3_PLUS_CTRL_1 0x0151
271#define RT5659_MP3_PLUS_CTRL_2 0x0152
272#define RT5659_MP3_HPF_A1 0x0153
273#define RT5659_MP3_HPF_A2 0x0154
274#define RT5659_MP3_HPF_H0 0x0155
275#define RT5659_MP3_LPF_H0 0x0156
276#define RT5659_3D_SPK_CTRL 0x0157
277#define RT5659_3D_SPK_COEF_1 0x0158
278#define RT5659_3D_SPK_COEF_2 0x0159
279#define RT5659_3D_SPK_COEF_3 0x015a
280#define RT5659_3D_SPK_COEF_4 0x015b
281#define RT5659_3D_SPK_COEF_5 0x015c
282#define RT5659_3D_SPK_COEF_6 0x015d
283#define RT5659_3D_SPK_COEF_7 0x015e
284#define RT5659_STO_NG2_CTRL_1 0x0160
285#define RT5659_STO_NG2_CTRL_2 0x0161
286#define RT5659_STO_NG2_CTRL_3 0x0162
287#define RT5659_STO_NG2_CTRL_4 0x0163
288#define RT5659_STO_NG2_CTRL_5 0x0164
289#define RT5659_STO_NG2_CTRL_6 0x0165
290#define RT5659_STO_NG2_CTRL_7 0x0166
291#define RT5659_STO_NG2_CTRL_8 0x0167
292#define RT5659_MONO_NG2_CTRL_1 0x0170
293#define RT5659_MONO_NG2_CTRL_2 0x0171
294#define RT5659_MONO_NG2_CTRL_3 0x0172
295#define RT5659_MONO_NG2_CTRL_4 0x0173
296#define RT5659_MONO_NG2_CTRL_5 0x0174
297#define RT5659_MONO_NG2_CTRL_6 0x0175
298#define RT5659_MID_HP_AMP_DET 0x0190
299#define RT5659_LOW_HP_AMP_DET 0x0191
300#define RT5659_LDO_CTRL 0x0192
301#define RT5659_HP_DECROSS_CTRL_1 0x01b0
302#define RT5659_HP_DECROSS_CTRL_2 0x01b1
303#define RT5659_HP_DECROSS_CTRL_3 0x01b2
304#define RT5659_HP_DECROSS_CTRL_4 0x01b3
305#define RT5659_HP_IMP_SENS_CTRL_1 0x01c0
306#define RT5659_HP_IMP_SENS_CTRL_2 0x01c1
307#define RT5659_HP_IMP_SENS_CTRL_3 0x01c2
308#define RT5659_HP_IMP_SENS_CTRL_4 0x01c3
309#define RT5659_HP_IMP_SENS_MAP_1 0x01c7
310#define RT5659_HP_IMP_SENS_MAP_2 0x01c8
311#define RT5659_HP_IMP_SENS_MAP_3 0x01c9
312#define RT5659_HP_IMP_SENS_MAP_4 0x01ca
313#define RT5659_HP_IMP_SENS_MAP_5 0x01cb
314#define RT5659_HP_IMP_SENS_MAP_6 0x01cc
315#define RT5659_HP_IMP_SENS_MAP_7 0x01cd
316#define RT5659_HP_IMP_SENS_MAP_8 0x01ce
317#define RT5659_HP_LOGIC_CTRL_1 0x01da
318#define RT5659_HP_LOGIC_CTRL_2 0x01db
319#define RT5659_HP_CALIB_CTRL_1 0x01de
320#define RT5659_HP_CALIB_CTRL_2 0x01df
321#define RT5659_HP_CALIB_CTRL_3 0x01e0
322#define RT5659_HP_CALIB_CTRL_4 0x01e1
323#define RT5659_HP_CALIB_CTRL_5 0x01e2
324#define RT5659_HP_CALIB_CTRL_6 0x01e3
325#define RT5659_HP_CALIB_CTRL_7 0x01e4
326#define RT5659_HP_CALIB_CTRL_9 0x01e6
327#define RT5659_HP_CALIB_CTRL_10 0x01e7
328#define RT5659_HP_CALIB_CTRL_11 0x01e8
329#define RT5659_HP_CALIB_STA_1 0x01ea
330#define RT5659_HP_CALIB_STA_2 0x01eb
331#define RT5659_HP_CALIB_STA_3 0x01ec
332#define RT5659_HP_CALIB_STA_4 0x01ed
333#define RT5659_HP_CALIB_STA_5 0x01ee
334#define RT5659_HP_CALIB_STA_6 0x01ef
335#define RT5659_HP_CALIB_STA_7 0x01f0
336#define RT5659_HP_CALIB_STA_8 0x01f1
337#define RT5659_HP_CALIB_STA_9 0x01f2
338#define RT5659_MONO_AMP_CALIB_CTRL_1 0x01f6
339#define RT5659_MONO_AMP_CALIB_CTRL_2 0x01f7
340#define RT5659_MONO_AMP_CALIB_CTRL_3 0x01f8
341#define RT5659_MONO_AMP_CALIB_CTRL_4 0x01f9
342#define RT5659_MONO_AMP_CALIB_CTRL_5 0x01fa
343#define RT5659_MONO_AMP_CALIB_STA_1 0x01fb
344#define RT5659_MONO_AMP_CALIB_STA_2 0x01fc
345#define RT5659_MONO_AMP_CALIB_STA_3 0x01fd
346#define RT5659_MONO_AMP_CALIB_STA_4 0x01fe
347#define RT5659_SPK_PWR_LMT_CTRL_1 0x0200
348#define RT5659_SPK_PWR_LMT_CTRL_2 0x0201
349#define RT5659_SPK_PWR_LMT_CTRL_3 0x0202
350#define RT5659_SPK_PWR_LMT_STA_1 0x0203
351#define RT5659_SPK_PWR_LMT_STA_2 0x0204
352#define RT5659_SPK_PWR_LMT_STA_3 0x0205
353#define RT5659_SPK_PWR_LMT_STA_4 0x0206
354#define RT5659_SPK_PWR_LMT_STA_5 0x0207
355#define RT5659_SPK_PWR_LMT_STA_6 0x0208
356#define RT5659_FLEX_SPK_BST_CTRL_1 0x0256
357#define RT5659_FLEX_SPK_BST_CTRL_2 0x0257
358#define RT5659_FLEX_SPK_BST_CTRL_3 0x0258
359#define RT5659_FLEX_SPK_BST_CTRL_4 0x0259
360#define RT5659_SPK_EX_LMT_CTRL_1 0x025a
361#define RT5659_SPK_EX_LMT_CTRL_2 0x025b
362#define RT5659_SPK_EX_LMT_CTRL_3 0x025c
363#define RT5659_SPK_EX_LMT_CTRL_4 0x025d
364#define RT5659_SPK_EX_LMT_CTRL_5 0x025e
365#define RT5659_SPK_EX_LMT_CTRL_6 0x025f
366#define RT5659_SPK_EX_LMT_CTRL_7 0x0260
367#define RT5659_ADJ_HPF_CTRL_1 0x0261
368#define RT5659_ADJ_HPF_CTRL_2 0x0262
369#define RT5659_SPK_DC_CAILB_CTRL_1 0x0265
370#define RT5659_SPK_DC_CAILB_CTRL_2 0x0266
371#define RT5659_SPK_DC_CAILB_CTRL_3 0x0267
372#define RT5659_SPK_DC_CAILB_CTRL_4 0x0268
373#define RT5659_SPK_DC_CAILB_CTRL_5 0x0269
374#define RT5659_SPK_DC_CAILB_STA_1 0x026a
375#define RT5659_SPK_DC_CAILB_STA_2 0x026b
376#define RT5659_SPK_DC_CAILB_STA_3 0x026c
377#define RT5659_SPK_DC_CAILB_STA_4 0x026d
378#define RT5659_SPK_DC_CAILB_STA_5 0x026e
379#define RT5659_SPK_DC_CAILB_STA_6 0x026f
380#define RT5659_SPK_DC_CAILB_STA_7 0x0270
381#define RT5659_SPK_DC_CAILB_STA_8 0x0271
382#define RT5659_SPK_DC_CAILB_STA_9 0x0272
383#define RT5659_SPK_DC_CAILB_STA_10 0x0273
384#define RT5659_SPK_VDD_STA_1 0x0280
385#define RT5659_SPK_VDD_STA_2 0x0281
386#define RT5659_SPK_DC_DET_CTRL_1 0x0282
387#define RT5659_SPK_DC_DET_CTRL_2 0x0283
388#define RT5659_SPK_DC_DET_CTRL_3 0x0284
389#define RT5659_PURE_DC_DET_CTRL_1 0x0290
390#define RT5659_PURE_DC_DET_CTRL_2 0x0291
391#define RT5659_DUMMY_4 0x02fa
392#define RT5659_DUMMY_5 0x02fb
393#define RT5659_DUMMY_6 0x02fc
394#define RT5659_DRC1_CTRL_1 0x0300
395#define RT5659_DRC1_CTRL_2 0x0301
396#define RT5659_DRC1_CTRL_3 0x0302
397#define RT5659_DRC1_CTRL_4 0x0303
398#define RT5659_DRC1_CTRL_5 0x0304
399#define RT5659_DRC1_CTRL_6 0x0305
400#define RT5659_DRC1_HARD_LMT_CTRL_1 0x0306
401#define RT5659_DRC1_HARD_LMT_CTRL_2 0x0307
402#define RT5659_DRC2_CTRL_1 0x0308
403#define RT5659_DRC2_CTRL_2 0x0309
404#define RT5659_DRC2_CTRL_3 0x030a
405#define RT5659_DRC2_CTRL_4 0x030b
406#define RT5659_DRC2_CTRL_5 0x030c
407#define RT5659_DRC2_CTRL_6 0x030d
408#define RT5659_DRC2_HARD_LMT_CTRL_1 0x030e
409#define RT5659_DRC2_HARD_LMT_CTRL_2 0x030f
410#define RT5659_DRC1_PRIV_1 0x0310
411#define RT5659_DRC1_PRIV_2 0x0311
412#define RT5659_DRC1_PRIV_3 0x0312
413#define RT5659_DRC1_PRIV_4 0x0313
414#define RT5659_DRC1_PRIV_5 0x0314
415#define RT5659_DRC1_PRIV_6 0x0315
416#define RT5659_DRC1_PRIV_7 0x0316
417#define RT5659_DRC2_PRIV_1 0x0317
418#define RT5659_DRC2_PRIV_2 0x0318
419#define RT5659_DRC2_PRIV_3 0x0319
420#define RT5659_DRC2_PRIV_4 0x031a
421#define RT5659_DRC2_PRIV_5 0x031b
422#define RT5659_DRC2_PRIV_6 0x031c
423#define RT5659_DRC2_PRIV_7 0x031d
424#define RT5659_MULTI_DRC_CTRL 0x0320
425#define RT5659_CROSS_OVER_1 0x0321
426#define RT5659_CROSS_OVER_2 0x0322
427#define RT5659_CROSS_OVER_3 0x0323
428#define RT5659_CROSS_OVER_4 0x0324
429#define RT5659_CROSS_OVER_5 0x0325
430#define RT5659_CROSS_OVER_6 0x0326
431#define RT5659_CROSS_OVER_7 0x0327
432#define RT5659_CROSS_OVER_8 0x0328
433#define RT5659_CROSS_OVER_9 0x0329
434#define RT5659_CROSS_OVER_10 0x032a
435#define RT5659_ALC_PGA_CTRL_1 0x0330
436#define RT5659_ALC_PGA_CTRL_2 0x0331
437#define RT5659_ALC_PGA_CTRL_3 0x0332
438#define RT5659_ALC_PGA_CTRL_4 0x0333
439#define RT5659_ALC_PGA_CTRL_5 0x0334
440#define RT5659_ALC_PGA_CTRL_6 0x0335
441#define RT5659_ALC_PGA_CTRL_7 0x0336
442#define RT5659_ALC_PGA_CTRL_8 0x0337
443#define RT5659_ALC_PGA_STA_1 0x0338
444#define RT5659_ALC_PGA_STA_2 0x0339
445#define RT5659_ALC_PGA_STA_3 0x033a
446#define RT5659_DAC_L_EQ_PRE_VOL 0x0340
447#define RT5659_DAC_R_EQ_PRE_VOL 0x0341
448#define RT5659_DAC_L_EQ_POST_VOL 0x0342
449#define RT5659_DAC_R_EQ_POST_VOL 0x0343
450#define RT5659_DAC_L_EQ_LPF1_A1 0x0344
451#define RT5659_DAC_L_EQ_LPF1_H0 0x0345
452#define RT5659_DAC_R_EQ_LPF1_A1 0x0346
453#define RT5659_DAC_R_EQ_LPF1_H0 0x0347
454#define RT5659_DAC_L_EQ_BPF2_A1 0x0348
455#define RT5659_DAC_L_EQ_BPF2_A2 0x0349
456#define RT5659_DAC_L_EQ_BPF2_H0 0x034a
457#define RT5659_DAC_R_EQ_BPF2_A1 0x034b
458#define RT5659_DAC_R_EQ_BPF2_A2 0x034c
459#define RT5659_DAC_R_EQ_BPF2_H0 0x034d
460#define RT5659_DAC_L_EQ_BPF3_A1 0x034e
461#define RT5659_DAC_L_EQ_BPF3_A2 0x034f
462#define RT5659_DAC_L_EQ_BPF3_H0 0x0350
463#define RT5659_DAC_R_EQ_BPF3_A1 0x0351
464#define RT5659_DAC_R_EQ_BPF3_A2 0x0352
465#define RT5659_DAC_R_EQ_BPF3_H0 0x0353
466#define RT5659_DAC_L_EQ_BPF4_A1 0x0354
467#define RT5659_DAC_L_EQ_BPF4_A2 0x0355
468#define RT5659_DAC_L_EQ_BPF4_H0 0x0356
469#define RT5659_DAC_R_EQ_BPF4_A1 0x0357
470#define RT5659_DAC_R_EQ_BPF4_A2 0x0358
471#define RT5659_DAC_R_EQ_BPF4_H0 0x0359
472#define RT5659_DAC_L_EQ_HPF1_A1 0x035a
473#define RT5659_DAC_L_EQ_HPF1_H0 0x035b
474#define RT5659_DAC_R_EQ_HPF1_A1 0x035c
475#define RT5659_DAC_R_EQ_HPF1_H0 0x035d
476#define RT5659_DAC_L_EQ_HPF2_A1 0x035e
477#define RT5659_DAC_L_EQ_HPF2_A2 0x035f
478#define RT5659_DAC_L_EQ_HPF2_H0 0x0360
479#define RT5659_DAC_R_EQ_HPF2_A1 0x0361
480#define RT5659_DAC_R_EQ_HPF2_A2 0x0362
481#define RT5659_DAC_R_EQ_HPF2_H0 0x0363
482#define RT5659_DAC_L_BI_EQ_BPF1_H0_1 0x0364
483#define RT5659_DAC_L_BI_EQ_BPF1_H0_2 0x0365
484#define RT5659_DAC_L_BI_EQ_BPF1_B1_1 0x0366
485#define RT5659_DAC_L_BI_EQ_BPF1_B1_2 0x0367
486#define RT5659_DAC_L_BI_EQ_BPF1_B2_1 0x0368
487#define RT5659_DAC_L_BI_EQ_BPF1_B2_2 0x0369
488#define RT5659_DAC_L_BI_EQ_BPF1_A1_1 0x036a
489#define RT5659_DAC_L_BI_EQ_BPF1_A1_2 0x036b
490#define RT5659_DAC_L_BI_EQ_BPF1_A2_1 0x036c
491#define RT5659_DAC_L_BI_EQ_BPF1_A2_2 0x036d
492#define RT5659_DAC_R_BI_EQ_BPF1_H0_1 0x036e
493#define RT5659_DAC_R_BI_EQ_BPF1_H0_2 0x036f
494#define RT5659_DAC_R_BI_EQ_BPF1_B1_1 0x0370
495#define RT5659_DAC_R_BI_EQ_BPF1_B1_2 0x0371
496#define RT5659_DAC_R_BI_EQ_BPF1_B2_1 0x0372
497#define RT5659_DAC_R_BI_EQ_BPF1_B2_2 0x0373
498#define RT5659_DAC_R_BI_EQ_BPF1_A1_1 0x0374
499#define RT5659_DAC_R_BI_EQ_BPF1_A1_2 0x0375
500#define RT5659_DAC_R_BI_EQ_BPF1_A2_1 0x0376
501#define RT5659_DAC_R_BI_EQ_BPF1_A2_2 0x0377
502#define RT5659_ADC_L_EQ_LPF1_A1 0x03d0
503#define RT5659_ADC_R_EQ_LPF1_A1 0x03d1
504#define RT5659_ADC_L_EQ_LPF1_H0 0x03d2
505#define RT5659_ADC_R_EQ_LPF1_H0 0x03d3
506#define RT5659_ADC_L_EQ_BPF1_A1 0x03d4
507#define RT5659_ADC_R_EQ_BPF1_A1 0x03d5
508#define RT5659_ADC_L_EQ_BPF1_A2 0x03d6
509#define RT5659_ADC_R_EQ_BPF1_A2 0x03d7
510#define RT5659_ADC_L_EQ_BPF1_H0 0x03d8
511#define RT5659_ADC_R_EQ_BPF1_H0 0x03d9
512#define RT5659_ADC_L_EQ_BPF2_A1 0x03da
513#define RT5659_ADC_R_EQ_BPF2_A1 0x03db
514#define RT5659_ADC_L_EQ_BPF2_A2 0x03dc
515#define RT5659_ADC_R_EQ_BPF2_A2 0x03dd
516#define RT5659_ADC_L_EQ_BPF2_H0 0x03de
517#define RT5659_ADC_R_EQ_BPF2_H0 0x03df
518#define RT5659_ADC_L_EQ_BPF3_A1 0x03e0
519#define RT5659_ADC_R_EQ_BPF3_A1 0x03e1
520#define RT5659_ADC_L_EQ_BPF3_A2 0x03e2
521#define RT5659_ADC_R_EQ_BPF3_A2 0x03e3
522#define RT5659_ADC_L_EQ_BPF3_H0 0x03e4
523#define RT5659_ADC_R_EQ_BPF3_H0 0x03e5
524#define RT5659_ADC_L_EQ_BPF4_A1 0x03e6
525#define RT5659_ADC_R_EQ_BPF4_A1 0x03e7
526#define RT5659_ADC_L_EQ_BPF4_A2 0x03e8
527#define RT5659_ADC_R_EQ_BPF4_A2 0x03e9
528#define RT5659_ADC_L_EQ_BPF4_H0 0x03ea
529#define RT5659_ADC_R_EQ_BPF4_H0 0x03eb
530#define RT5659_ADC_L_EQ_HPF1_A1 0x03ec
531#define RT5659_ADC_R_EQ_HPF1_A1 0x03ed
532#define RT5659_ADC_L_EQ_HPF1_H0 0x03ee
533#define RT5659_ADC_R_EQ_HPF1_H0 0x03ef
534#define RT5659_ADC_L_EQ_PRE_VOL 0x03f0
535#define RT5659_ADC_R_EQ_PRE_VOL 0x03f1
536#define RT5659_ADC_L_EQ_POST_VOL 0x03f2
537#define RT5659_ADC_R_EQ_POST_VOL 0x03f3
538
539
540
541/* global definition */
542#define RT5659_L_MUTE (0x1 << 15)
543#define RT5659_L_MUTE_SFT 15
544#define RT5659_VOL_L_MUTE (0x1 << 14)
545#define RT5659_VOL_L_SFT 14
546#define RT5659_R_MUTE (0x1 << 7)
547#define RT5659_R_MUTE_SFT 7
548#define RT5659_VOL_R_MUTE (0x1 << 6)
549#define RT5659_VOL_R_SFT 6
550#define RT5659_L_VOL_MASK (0x3f << 8)
551#define RT5659_L_VOL_SFT 8
552#define RT5659_R_VOL_MASK (0x3f)
553#define RT5659_R_VOL_SFT 0
554
555/*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/
556#define RT5659_G_HP (0x1f << 8)
557#define RT5659_G_HP_SFT 8
558#define RT5659_G_STO_DA_DMIX (0x1f)
559#define RT5659_G_STO_DA_SFT 0
560
561/* IN1/IN2 Control (0x000c) */
562#define RT5659_IN1_DF_MASK (0x1 << 15)
563#define RT5659_IN1_DF 15
564#define RT5659_BST1_MASK (0x7f << 8)
565#define RT5659_BST1_SFT 8
566#define RT5659_BST2_MASK (0x7f)
567#define RT5659_BST2_SFT 0
568
569/* IN3/IN4 Control (0x000d) */
570#define RT5659_IN3_DF_MASK (0x1 << 15)
571#define RT5659_IN3_DF 15
572#define RT5659_BST3_MASK (0x7f << 8)
573#define RT5659_BST3_SFT 8
574#define RT5659_IN4_DF_MASK (0x1 << 7)
575#define RT5659_IN4_DF 7
576#define RT5659_BST4_MASK (0x7f)
577#define RT5659_BST4_SFT 0
578
579/* INL and INR Volume Control (0x000f) */
580#define RT5659_INL_VOL_MASK (0x1f << 8)
581#define RT5659_INL_VOL_SFT 8
582#define RT5659_INR_VOL_MASK (0x1f)
583#define RT5659_INR_VOL_SFT 0
584
585/* Embeeded Jack and Type Detection Control 1 (0x0010) */
586#define RT5659_EMB_JD_EN (0x1 << 15)
587#define RT5659_EMB_JD_EN_SFT 15
588#define RT5659_JD_MODE (0x1 << 13)
589#define RT5659_JD_MODE_SFT 13
590#define RT5659_EXT_JD_EN (0x1 << 11)
591#define RT5659_EXT_JD_EN_SFT 11
592#define RT5659_EXT_JD_DIG (0x1 << 9)
593
594/* Embeeded Jack and Type Detection Control 2 (0x0011) */
595#define RT5659_EXT_JD_SRC (0x7 << 4)
596#define RT5659_EXT_JD_SRC_SFT 4
597#define RT5659_EXT_JD_SRC_GPIO_JD1 (0x0 << 4)
598#define RT5659_EXT_JD_SRC_GPIO_JD2 (0x1 << 4)
599#define RT5659_EXT_JD_SRC_JD1_1 (0x2 << 4)
600#define RT5659_EXT_JD_SRC_JD1_2 (0x3 << 4)
601#define RT5659_EXT_JD_SRC_JD2 (0x4 << 4)
602#define RT5659_EXT_JD_SRC_JD3 (0x5 << 4)
603#define RT5659_EXT_JD_SRC_MANUAL (0x6 << 4)
604
605/* Slience Detection Control (0x0015) */
606#define RT5659_SIL_DET_MASK (0x1 << 15)
607#define RT5659_SIL_DET_DIS (0x0 << 15)
608#define RT5659_SIL_DET_EN (0x1 << 15)
609
610/* Sidetone Control (0x0018) */
611#define RT5659_ST_SEL_MASK (0x7 << 9)
612#define RT5659_ST_SEL_SFT 9
613#define RT5659_ST_EN (0x1 << 6)
614#define RT5659_ST_EN_SFT 6
615
616/* DAC1 Digital Volume (0x0019) */
617#define RT5659_DAC_L1_VOL_MASK (0xff << 8)
618#define RT5659_DAC_L1_VOL_SFT 8
619#define RT5659_DAC_R1_VOL_MASK (0xff)
620#define RT5659_DAC_R1_VOL_SFT 0
621
622/* DAC2 Digital Volume (0x001a) */
623#define RT5659_DAC_L2_VOL_MASK (0xff << 8)
624#define RT5659_DAC_L2_VOL_SFT 8
625#define RT5659_DAC_R2_VOL_MASK (0xff)
626#define RT5659_DAC_R2_VOL_SFT 0
627
628/* DAC2 Control (0x001b) */
629#define RT5659_M_DAC2_L_VOL (0x1 << 13)
630#define RT5659_M_DAC2_L_VOL_SFT 13
631#define RT5659_M_DAC2_R_VOL (0x1 << 12)
632#define RT5659_M_DAC2_R_VOL_SFT 12
633#define RT5659_DAC_L2_SEL_MASK (0x7 << 4)
634#define RT5659_DAC_L2_SEL_SFT 4
635#define RT5659_DAC_R2_SEL_MASK (0x7 << 0)
636#define RT5659_DAC_R2_SEL_SFT 0
637
638/* ADC Digital Volume Control (0x001c) */
639#define RT5659_ADC_L_VOL_MASK (0x7f << 8)
640#define RT5659_ADC_L_VOL_SFT 8
641#define RT5659_ADC_R_VOL_MASK (0x7f)
642#define RT5659_ADC_R_VOL_SFT 0
643
644/* Mono ADC Digital Volume Control (0x001d) */
645#define RT5659_MONO_ADC_L_VOL_MASK (0x7f << 8)
646#define RT5659_MONO_ADC_L_VOL_SFT 8
647#define RT5659_MONO_ADC_R_VOL_MASK (0x7f)
648#define RT5659_MONO_ADC_R_VOL_SFT 0
649
650/* Stereo1 ADC Boost Gain Control (0x001f) */
651#define RT5659_STO1_ADC_L_BST_MASK (0x3 << 14)
652#define RT5659_STO1_ADC_L_BST_SFT 14
653#define RT5659_STO1_ADC_R_BST_MASK (0x3 << 12)
654#define RT5659_STO1_ADC_R_BST_SFT 12
655
656/* Mono ADC Boost Gain Control (0x0020) */
657#define RT5659_MONO_ADC_L_BST_MASK (0x3 << 14)
658#define RT5659_MONO_ADC_L_BST_SFT 14
659#define RT5659_MONO_ADC_R_BST_MASK (0x3 << 12)
660#define RT5659_MONO_ADC_R_BST_SFT 12
661
662/* Stereo1 ADC Boost Gain Control (0x001f) */
663#define RT5659_STO2_ADC_L_BST_MASK (0x3 << 14)
664#define RT5659_STO2_ADC_L_BST_SFT 14
665#define RT5659_STO2_ADC_R_BST_MASK (0x3 << 12)
666#define RT5659_STO2_ADC_R_BST_SFT 12
667
668/* Stereo ADC Mixer Control (0x0026) */
669#define RT5659_M_STO1_ADC_L1 (0x1 << 15)
670#define RT5659_M_STO1_ADC_L1_SFT 15
671#define RT5659_M_STO1_ADC_L2 (0x1 << 14)
672#define RT5659_M_STO1_ADC_L2_SFT 14
673#define RT5659_STO1_ADC1_SRC_MASK (0x1 << 13)
674#define RT5659_STO1_ADC1_SRC_SFT 13
675#define RT5659_STO1_ADC1_SRC_ADC (0x1 << 13)
676#define RT5659_STO1_ADC1_SRC_DACMIX (0x0 << 13)
677#define RT5659_STO1_ADC_SRC_MASK (0x1 << 12)
678#define RT5659_STO1_ADC_SRC_SFT 12
679#define RT5659_STO1_ADC_SRC_ADC1 (0x1 << 12)
680#define RT5659_STO1_ADC_SRC_ADC2 (0x0 << 12)
681#define RT5659_STO1_ADC2_SRC_MASK (0x1 << 11)
682#define RT5659_STO1_ADC2_SRC_SFT 11
683#define RT5659_STO1_DMIC_SRC_MASK (0x1 << 8)
684#define RT5659_STO1_DMIC_SRC_SFT 8
685#define RT5659_STO1_DMIC_SRC_DMIC2 (0x1 << 8)
686#define RT5659_STO1_DMIC_SRC_DMIC1 (0x0 << 8)
687#define RT5659_M_STO1_ADC_R1 (0x1 << 6)
688#define RT5659_M_STO1_ADC_R1_SFT 6
689#define RT5659_M_STO1_ADC_R2 (0x1 << 5)
690#define RT5659_M_STO1_ADC_R2_SFT 5
691
692/* Mono1 ADC Mixer control (0x0027) */
693#define RT5659_M_MONO_ADC_L1 (0x1 << 15)
694#define RT5659_M_MONO_ADC_L1_SFT 15
695#define RT5659_M_MONO_ADC_L2 (0x1 << 14)
696#define RT5659_M_MONO_ADC_L2_SFT 14
697#define RT5659_MONO_ADC_L2_SRC_MASK (0x1 << 12)
698#define RT5659_MONO_ADC_L2_SRC_SFT 12
699#define RT5659_MONO_ADC_L1_SRC_MASK (0x1 << 11)
700#define RT5659_MONO_ADC_L1_SRC_SFT 11
701#define RT5659_MONO_ADC_L_SRC_MASK (0x3 << 9)
702#define RT5659_MONO_ADC_L_SRC_SFT 9
703#define RT5659_MONO_DMIC_L_SRC_MASK (0x1 << 8)
704#define RT5659_MONO_DMIC_L_SRC_SFT 8
705#define RT5659_M_MONO_ADC_R1 (0x1 << 7)
706#define RT5659_M_MONO_ADC_R1_SFT 7
707#define RT5659_M_MONO_ADC_R2 (0x1 << 6)
708#define RT5659_M_MONO_ADC_R2_SFT 6
709#define RT5659_STO2_ADC_SRC_MASK (0x1 << 5)
710#define RT5659_STO2_ADC_SRC_SFT 5
711#define RT5659_MONO_ADC_R2_SRC_MASK (0x1 << 4)
712#define RT5659_MONO_ADC_R2_SRC_SFT 4
713#define RT5659_MONO_ADC_R1_SRC_MASK (0x1 << 3)
714#define RT5659_MONO_ADC_R1_SRC_SFT 3
715#define RT5659_MONO_ADC_R_SRC_MASK (0x3 << 1)
716#define RT5659_MONO_ADC_R_SRC_SFT 1
717#define RT5659_MONO_DMIC_R_SRC_MASK 0x1
718#define RT5659_MONO_DMIC_R_SRC_SFT 0
719
720/* ADC Mixer to DAC Mixer Control (0x0029) */
721#define RT5659_M_ADCMIX_L (0x1 << 15)
722#define RT5659_M_ADCMIX_L_SFT 15
723#define RT5659_M_DAC1_L (0x1 << 14)
724#define RT5659_M_DAC1_L_SFT 14
725#define RT5659_DAC1_R_SEL_MASK (0x3 << 10)
726#define RT5659_DAC1_R_SEL_SFT 10
727#define RT5659_DAC1_R_SEL_IF1 (0x0 << 10)
728#define RT5659_DAC1_R_SEL_IF2 (0x1 << 10)
729#define RT5659_DAC1_R_SEL_IF3 (0x2 << 10)
730#define RT5659_DAC1_L_SEL_MASK (0x3 << 8)
731#define RT5659_DAC1_L_SEL_SFT 8
732#define RT5659_DAC1_L_SEL_IF1 (0x0 << 8)
733#define RT5659_DAC1_L_SEL_IF2 (0x1 << 8)
734#define RT5659_DAC1_L_SEL_IF3 (0x2 << 8)
735#define RT5659_M_ADCMIX_R (0x1 << 7)
736#define RT5659_M_ADCMIX_R_SFT 7
737#define RT5659_M_DAC1_R (0x1 << 6)
738#define RT5659_M_DAC1_R_SFT 6
739
740/* Stereo DAC Mixer Control (0x002a) */
741#define RT5659_M_DAC_L1_STO_L (0x1 << 15)
742#define RT5659_M_DAC_L1_STO_L_SFT 15
743#define RT5659_G_DAC_L1_STO_L_MASK (0x1 << 14)
744#define RT5659_G_DAC_L1_STO_L_SFT 14
745#define RT5659_M_DAC_R1_STO_L (0x1 << 13)
746#define RT5659_M_DAC_R1_STO_L_SFT 13
747#define RT5659_G_DAC_R1_STO_L_MASK (0x1 << 12)
748#define RT5659_G_DAC_R1_STO_L_SFT 12
749#define RT5659_M_DAC_L2_STO_L (0x1 << 11)
750#define RT5659_M_DAC_L2_STO_L_SFT 11
751#define RT5659_G_DAC_L2_STO_L_MASK (0x1 << 10)
752#define RT5659_G_DAC_L2_STO_L_SFT 10
753#define RT5659_M_DAC_R2_STO_L (0x1 << 9)
754#define RT5659_M_DAC_R2_STO_L_SFT 9
755#define RT5659_G_DAC_R2_STO_L_MASK (0x1 << 8)
756#define RT5659_G_DAC_R2_STO_L_SFT 8
757#define RT5659_M_DAC_L1_STO_R (0x1 << 7)
758#define RT5659_M_DAC_L1_STO_R_SFT 7
759#define RT5659_G_DAC_L1_STO_R_MASK (0x1 << 6)
760#define RT5659_G_DAC_L1_STO_R_SFT 6
761#define RT5659_M_DAC_R1_STO_R (0x1 << 5)
762#define RT5659_M_DAC_R1_STO_R_SFT 5
763#define RT5659_G_DAC_R1_STO_R_MASK (0x1 << 4)
764#define RT5659_G_DAC_R1_STO_R_SFT 4
765#define RT5659_M_DAC_L2_STO_R (0x1 << 3)
766#define RT5659_M_DAC_L2_STO_R_SFT 3
767#define RT5659_G_DAC_L2_STO_R_MASK (0x1 << 2)
768#define RT5659_G_DAC_L2_STO_R_SFT 2
769#define RT5659_M_DAC_R2_STO_R (0x1 << 1)
770#define RT5659_M_DAC_R2_STO_R_SFT 1
771#define RT5659_G_DAC_R2_STO_R_MASK (0x1)
772#define RT5659_G_DAC_R2_STO_R_SFT 0
773
774/* Mono DAC Mixer Control (0x002b) */
775#define RT5659_M_DAC_L1_MONO_L (0x1 << 15)
776#define RT5659_M_DAC_L1_MONO_L_SFT 15
777#define RT5659_G_DAC_L1_MONO_L_MASK (0x1 << 14)
778#define RT5659_G_DAC_L1_MONO_L_SFT 14
779#define RT5659_M_DAC_R1_MONO_L (0x1 << 13)
780#define RT5659_M_DAC_R1_MONO_L_SFT 13
781#define RT5659_G_DAC_R1_MONO_L_MASK (0x1 << 12)
782#define RT5659_G_DAC_R1_MONO_L_SFT 12
783#define RT5659_M_DAC_L2_MONO_L (0x1 << 11)
784#define RT5659_M_DAC_L2_MONO_L_SFT 11
785#define RT5659_G_DAC_L2_MONO_L_MASK (0x1 << 10)
786#define RT5659_G_DAC_L2_MONO_L_SFT 10
787#define RT5659_M_DAC_R2_MONO_L (0x1 << 9)
788#define RT5659_M_DAC_R2_MONO_L_SFT 9
789#define RT5659_G_DAC_R2_MONO_L_MASK (0x1 << 8)
790#define RT5659_G_DAC_R2_MONO_L_SFT 8
791#define RT5659_M_DAC_L1_MONO_R (0x1 << 7)
792#define RT5659_M_DAC_L1_MONO_R_SFT 7
793#define RT5659_G_DAC_L1_MONO_R_MASK (0x1 << 6)
794#define RT5659_G_DAC_L1_MONO_R_SFT 6
795#define RT5659_M_DAC_R1_MONO_R (0x1 << 5)
796#define RT5659_M_DAC_R1_MONO_R_SFT 5
797#define RT5659_G_DAC_R1_MONO_R_MASK (0x1 << 4)
798#define RT5659_G_DAC_R1_MONO_R_SFT 4
799#define RT5659_M_DAC_L2_MONO_R (0x1 << 3)
800#define RT5659_M_DAC_L2_MONO_R_SFT 3
801#define RT5659_G_DAC_L2_MONO_R_MASK (0x1 << 2)
802#define RT5659_G_DAC_L2_MONO_R_SFT 2
803#define RT5659_M_DAC_R2_MONO_R (0x1 << 1)
804#define RT5659_M_DAC_R2_MONO_R_SFT 1
805#define RT5659_G_DAC_R2_MONO_R_MASK (0x1)
806#define RT5659_G_DAC_R2_MONO_R_SFT 0
807
808/* Digital Mixer Control (0x002c) */
809#define RT5659_M_DAC_MIX_L (0x1 << 7)
810#define RT5659_M_DAC_MIX_L_SFT 7
811#define RT5659_DAC_MIX_L_MASK (0x1 << 6)
812#define RT5659_DAC_MIX_L_SFT 6
813#define RT5659_M_DAC_MIX_R (0x1 << 5)
814#define RT5659_M_DAC_MIX_R_SFT 5
815#define RT5659_DAC_MIX_R_MASK (0x1 << 4)
816#define RT5659_DAC_MIX_R_SFT 4
817
818/* Analog DAC Input Source Control (0x002d) */
819#define RT5659_A_DACL1_SEL (0x1 << 3)
820#define RT5659_A_DACL1_SFT 3
821#define RT5659_A_DACR1_SEL (0x1 << 2)
822#define RT5659_A_DACR1_SFT 2
823#define RT5659_A_DACL2_SEL (0x1 << 1)
824#define RT5659_A_DACL2_SFT 1
825#define RT5659_A_DACR2_SEL (0x1 << 0)
826#define RT5659_A_DACR2_SFT 0
827
828/* Digital Interface Data Control (0x002f) */
829#define RT5659_IF2_ADC3_IN_MASK (0x3 << 14)
830#define RT5659_IF2_ADC3_IN_SFT 14
831#define RT5659_IF2_ADC_IN_MASK (0x3 << 12)
832#define RT5659_IF2_ADC_IN_SFT 12
833#define RT5659_IF2_DAC_SEL_MASK (0x3 << 10)
834#define RT5659_IF2_DAC_SEL_SFT 10
835#define RT5659_IF2_ADC_SEL_MASK (0x3 << 8)
836#define RT5659_IF2_ADC_SEL_SFT 8
837#define RT5659_IF3_DAC_SEL_MASK (0x3 << 6)
838#define RT5659_IF3_DAC_SEL_SFT 6
839#define RT5659_IF3_ADC_SEL_MASK (0x3 << 4)
840#define RT5659_IF3_ADC_SEL_SFT 4
841#define RT5659_IF3_ADC_IN_MASK (0x3 << 0)
842#define RT5659_IF3_ADC_IN_SFT 0
843
844/* PDM Output Control (0x0031) */
845#define RT5659_PDM1_L_MASK (0x1 << 15)
846#define RT5659_PDM1_L_SFT 15
847#define RT5659_M_PDM1_L (0x1 << 14)
848#define RT5659_M_PDM1_L_SFT 14
849#define RT5659_PDM1_R_MASK (0x1 << 13)
850#define RT5659_PDM1_R_SFT 13
851#define RT5659_M_PDM1_R (0x1 << 12)
852#define RT5659_M_PDM1_R_SFT 12
853#define RT5659_PDM2_BUSY (0x1 << 7)
854#define RT5659_PDM1_BUSY (0x1 << 6)
855#define RT5659_PDM_PATTERN (0x1 << 5)
856#define RT5659_PDM_GAIN (0x1 << 4)
857#define RT5659_PDM_DIV_MASK (0x3)
858
859/*S/PDIF Output Control (0x0036) */
860#define RT5659_SPDIF_SEL_MASK (0x3 << 0)
861#define RT5659_SPDIF_SEL_SFT 0
862
863/* REC Left Mixer Control 2 (0x003c) */
864#define RT5659_M_BST1_RM1_L (0x1 << 5)
865#define RT5659_M_BST1_RM1_L_SFT 5
866#define RT5659_M_BST2_RM1_L (0x1 << 4)
867#define RT5659_M_BST2_RM1_L_SFT 4
868#define RT5659_M_BST3_RM1_L (0x1 << 3)
869#define RT5659_M_BST3_RM1_L_SFT 3
870#define RT5659_M_BST4_RM1_L (0x1 << 2)
871#define RT5659_M_BST4_RM1_L_SFT 2
872#define RT5659_M_INL_RM1_L (0x1 << 1)
873#define RT5659_M_INL_RM1_L_SFT 1
874#define RT5659_M_SPKVOLL_RM1_L (0x1)
875#define RT5659_M_SPKVOLL_RM1_L_SFT 0
876
877/* REC Right Mixer Control 2 (0x003e) */
878#define RT5659_M_BST1_RM1_R (0x1 << 5)
879#define RT5659_M_BST1_RM1_R_SFT 5
880#define RT5659_M_BST2_RM1_R (0x1 << 4)
881#define RT5659_M_BST2_RM1_R_SFT 4
882#define RT5659_M_BST3_RM1_R (0x1 << 3)
883#define RT5659_M_BST3_RM1_R_SFT 3
884#define RT5659_M_BST4_RM1_R (0x1 << 2)
885#define RT5659_M_BST4_RM1_R_SFT 2
886#define RT5659_M_INR_RM1_R (0x1 << 1)
887#define RT5659_M_INR_RM1_R_SFT 1
888#define RT5659_M_HPOVOLR_RM1_R (0x1)
889#define RT5659_M_HPOVOLR_RM1_R_SFT 0
890
891/* SPK Left Mixer Control (0x0046) */
892#define RT5659_M_BST3_SM_L (0x1 << 4)
893#define RT5659_M_BST3_SM_L_SFT 4
894#define RT5659_M_IN_R_SM_L (0x1 << 3)
895#define RT5659_M_IN_R_SM_L_SFT 3
896#define RT5659_M_IN_L_SM_L (0x1 << 2)
897#define RT5659_M_IN_L_SM_L_SFT 2
898#define RT5659_M_BST1_SM_L (0x1 << 1)
899#define RT5659_M_BST1_SM_L_SFT 1
900#define RT5659_M_DAC_L2_SM_L (0x1)
901#define RT5659_M_DAC_L2_SM_L_SFT 0
902
903/* SPK Right Mixer Control (0x0047) */
904#define RT5659_M_BST3_SM_R (0x1 << 4)
905#define RT5659_M_BST3_SM_R_SFT 4
906#define RT5659_M_IN_R_SM_R (0x1 << 3)
907#define RT5659_M_IN_R_SM_R_SFT 3
908#define RT5659_M_IN_L_SM_R (0x1 << 2)
909#define RT5659_M_IN_L_SM_R_SFT 2
910#define RT5659_M_BST4_SM_R (0x1 << 1)
911#define RT5659_M_BST4_SM_R_SFT 1
912#define RT5659_M_DAC_R2_SM_R (0x1)
913#define RT5659_M_DAC_R2_SM_R_SFT 0
914
915/* SPO Amp Input and Gain Control (0x0048) */
916#define RT5659_M_DAC_L2_SPKOMIX (0x1 << 13)
917#define RT5659_M_DAC_L2_SPKOMIX_SFT 13
918#define RT5659_M_SPKVOLL_SPKOMIX (0x1 << 12)
919#define RT5659_M_SPKVOLL_SPKOMIX_SFT 12
920#define RT5659_M_DAC_R2_SPKOMIX (0x1 << 9)
921#define RT5659_M_DAC_R2_SPKOMIX_SFT 9
922#define RT5659_M_SPKVOLR_SPKOMIX (0x1 << 8)
923#define RT5659_M_SPKVOLR_SPKOMIX_SFT 8
924
925/* MONOMIX Input and Gain Control (0x004b) */
926#define RT5659_M_MONOVOL_MA (0x1 << 9)
927#define RT5659_M_MONOVOL_MA_SFT 9
928#define RT5659_M_DAC_L2_MA (0x1 << 8)
929#define RT5659_M_DAC_L2_MA_SFT 8
930#define RT5659_M_BST3_MM (0x1 << 4)
931#define RT5659_M_BST3_MM_SFT 4
932#define RT5659_M_BST2_MM (0x1 << 3)
933#define RT5659_M_BST2_MM_SFT 3
934#define RT5659_M_BST1_MM (0x1 << 2)
935#define RT5659_M_BST1_MM_SFT 2
936#define RT5659_M_DAC_R2_MM (0x1 << 1)
937#define RT5659_M_DAC_R2_MM_SFT 1
938#define RT5659_M_DAC_L2_MM (0x1)
939#define RT5659_M_DAC_L2_MM_SFT 0
940
941/* Output Left Mixer Control 1 (0x004d) */
942#define RT5659_G_BST3_OM_L_MASK (0x7 << 12)
943#define RT5659_G_BST3_OM_L_SFT 12
944#define RT5659_G_BST2_OM_L_MASK (0x7 << 9)
945#define RT5659_G_BST2_OM_L_SFT 9
946#define RT5659_G_BST1_OM_L_MASK (0x7 << 6)
947#define RT5659_G_BST1_OM_L_SFT 6
948#define RT5659_G_IN_L_OM_L_MASK (0x7 << 3)
949#define RT5659_G_IN_L_OM_L_SFT 3
950#define RT5659_G_DAC_L2_OM_L_MASK (0x7 << 0)
951#define RT5659_G_DAC_L2_OM_L_SFT 0
952
953/* Output Left Mixer Input Control (0x004e) */
954#define RT5659_M_BST3_OM_L (0x1 << 4)
955#define RT5659_M_BST3_OM_L_SFT 4
956#define RT5659_M_BST2_OM_L (0x1 << 3)
957#define RT5659_M_BST2_OM_L_SFT 3
958#define RT5659_M_BST1_OM_L (0x1 << 2)
959#define RT5659_M_BST1_OM_L_SFT 2
960#define RT5659_M_IN_L_OM_L (0x1 << 1)
961#define RT5659_M_IN_L_OM_L_SFT 1
962#define RT5659_M_DAC_L2_OM_L (0x1)
963#define RT5659_M_DAC_L2_OM_L_SFT 0
964
965/* Output Right Mixer Input Control (0x0050) */
966#define RT5659_M_BST4_OM_R (0x1 << 4)
967#define RT5659_M_BST4_OM_R_SFT 4
968#define RT5659_M_BST3_OM_R (0x1 << 3)
969#define RT5659_M_BST3_OM_R_SFT 3
970#define RT5659_M_BST2_OM_R (0x1 << 2)
971#define RT5659_M_BST2_OM_R_SFT 2
972#define RT5659_M_IN_R_OM_R (0x1 << 1)
973#define RT5659_M_IN_R_OM_R_SFT 1
974#define RT5659_M_DAC_R2_OM_R (0x1)
975#define RT5659_M_DAC_R2_OM_R_SFT 0
976
977/* LOUT Mixer Control (0x0052) */
978#define RT5659_M_DAC_L2_LM (0x1 << 15)
979#define RT5659_M_DAC_L2_LM_SFT 15
980#define RT5659_M_DAC_R2_LM (0x1 << 14)
981#define RT5659_M_DAC_R2_LM_SFT 14
982#define RT5659_M_OV_L_LM (0x1 << 13)
983#define RT5659_M_OV_L_LM_SFT 13
984#define RT5659_M_OV_R_LM (0x1 << 12)
985#define RT5659_M_OV_R_LM_SFT 12
986
987/* Power Management for Digital 1 (0x0061) */
988#define RT5659_PWR_I2S1 (0x1 << 15)
989#define RT5659_PWR_I2S1_BIT 15
990#define RT5659_PWR_I2S2 (0x1 << 14)
991#define RT5659_PWR_I2S2_BIT 14
992#define RT5659_PWR_I2S3 (0x1 << 13)
993#define RT5659_PWR_I2S3_BIT 13
994#define RT5659_PWR_SPDIF (0x1 << 12)
995#define RT5659_PWR_SPDIF_BIT 12
996#define RT5659_PWR_DAC_L1 (0x1 << 11)
997#define RT5659_PWR_DAC_L1_BIT 11
998#define RT5659_PWR_DAC_R1 (0x1 << 10)
999#define RT5659_PWR_DAC_R1_BIT 10
1000#define RT5659_PWR_DAC_L2 (0x1 << 9)
1001#define RT5659_PWR_DAC_L2_BIT 9
1002#define RT5659_PWR_DAC_R2 (0x1 << 8)
1003#define RT5659_PWR_DAC_R2_BIT 8
1004#define RT5659_PWR_LDO (0x1 << 7)
1005#define RT5659_PWR_LDO_BIT 7
1006#define RT5659_PWR_ADC_L1 (0x1 << 4)
1007#define RT5659_PWR_ADC_L1_BIT 4
1008#define RT5659_PWR_ADC_R1 (0x1 << 3)
1009#define RT5659_PWR_ADC_R1_BIT 3
1010#define RT5659_PWR_ADC_L2 (0x1 << 2)
1011#define RT5659_PWR_ADC_L2_BIT 4
1012#define RT5659_PWR_ADC_R2 (0x1 << 1)
1013#define RT5659_PWR_ADC_R2_BIT 1
1014#define RT5659_PWR_CLS_D (0x1)
1015#define RT5659_PWR_CLS_D_BIT 0
1016
1017/* Power Management for Digital 2 (0x0062) */
1018#define RT5659_PWR_ADC_S1F (0x1 << 15)
1019#define RT5659_PWR_ADC_S1F_BIT 15
1020#define RT5659_PWR_ADC_S2F (0x1 << 14)
1021#define RT5659_PWR_ADC_S2F_BIT 14
1022#define RT5659_PWR_ADC_MF_L (0x1 << 13)
1023#define RT5659_PWR_ADC_MF_L_BIT 13
1024#define RT5659_PWR_ADC_MF_R (0x1 << 12)
1025#define RT5659_PWR_ADC_MF_R_BIT 12
1026#define RT5659_PWR_DAC_S1F (0x1 << 10)
1027#define RT5659_PWR_DAC_S1F_BIT 10
1028#define RT5659_PWR_DAC_MF_L (0x1 << 9)
1029#define RT5659_PWR_DAC_MF_L_BIT 9
1030#define RT5659_PWR_DAC_MF_R (0x1 << 8)
1031#define RT5659_PWR_DAC_MF_R_BIT 8
1032#define RT5659_PWR_PDM1 (0x1 << 7)
1033#define RT5659_PWR_PDM1_BIT 7
1034
1035/* Power Management for Analog 1 (0x0063) */
1036#define RT5659_PWR_VREF1 (0x1 << 15)
1037#define RT5659_PWR_VREF1_BIT 15
1038#define RT5659_PWR_FV1 (0x1 << 14)
1039#define RT5659_PWR_FV1_BIT 14
1040#define RT5659_PWR_VREF2 (0x1 << 13)
1041#define RT5659_PWR_VREF2_BIT 13
1042#define RT5659_PWR_FV2 (0x1 << 12)
1043#define RT5659_PWR_FV2_BIT 12
1044#define RT5659_PWR_VREF3 (0x1 << 11)
1045#define RT5659_PWR_VREF3_BIT 11
1046#define RT5659_PWR_FV3 (0x1 << 10)
1047#define RT5659_PWR_FV3_BIT 10
1048#define RT5659_PWR_MB (0x1 << 9)
1049#define RT5659_PWR_MB_BIT 9
1050#define RT5659_PWR_LM (0x1 << 8)
1051#define RT5659_PWR_LM_BIT 8
1052#define RT5659_PWR_BG (0x1 << 7)
1053#define RT5659_PWR_BG_BIT 7
1054#define RT5659_PWR_MA (0x1 << 6)
1055#define RT5659_PWR_MA_BIT 6
1056#define RT5659_PWR_HA_L (0x1 << 5)
1057#define RT5659_PWR_HA_L_BIT 5
1058#define RT5659_PWR_HA_R (0x1 << 4)
1059#define RT5659_PWR_HA_R_BIT 4
1060
1061/* Power Management for Analog 2 (0x0064) */
1062#define RT5659_PWR_BST1 (0x1 << 15)
1063#define RT5659_PWR_BST1_BIT 15
1064#define RT5659_PWR_BST2 (0x1 << 14)
1065#define RT5659_PWR_BST2_BIT 14
1066#define RT5659_PWR_BST3 (0x1 << 13)
1067#define RT5659_PWR_BST3_BIT 13
1068#define RT5659_PWR_BST4 (0x1 << 12)
1069#define RT5659_PWR_BST4_BIT 12
1070#define RT5659_PWR_MB1 (0x1 << 11)
1071#define RT5659_PWR_MB1_BIT 11
1072#define RT5659_PWR_MB2 (0x1 << 10)
1073#define RT5659_PWR_MB2_BIT 10
1074#define RT5659_PWR_MB3 (0x1 << 9)
1075#define RT5659_PWR_MB3_BIT 9
1076#define RT5659_PWR_BST1_P (0x1 << 6)
1077#define RT5659_PWR_BST1_P_BIT 6
1078#define RT5659_PWR_BST2_P (0x1 << 5)
1079#define RT5659_PWR_BST2_P_BIT 5
1080#define RT5659_PWR_BST3_P (0x1 << 4)
1081#define RT5659_PWR_BST3_P_BIT 4
1082#define RT5659_PWR_BST4_P (0x1 << 3)
1083#define RT5659_PWR_BST4_P_BIT 3
1084#define RT5659_PWR_JD1 (0x1 << 2)
1085#define RT5659_PWR_JD1_BIT 2
1086#define RT5659_PWR_JD2 (0x1 << 1)
1087#define RT5659_PWR_JD2_BIT 1
1088#define RT5659_PWR_JD3 (0x1)
1089#define RT5659_PWR_JD3_BIT 0
1090
1091/* Power Management for Analog 3 (0x0065) */
1092#define RT5659_PWR_BST_L (0x1 << 8)
1093#define RT5659_PWR_BST_L_BIT 8
1094#define RT5659_PWR_BST_R (0x1 << 7)
1095#define RT5659_PWR_BST_R_BIT 7
1096#define RT5659_PWR_PLL (0x1 << 6)
1097#define RT5659_PWR_PLL_BIT 6
1098#define RT5659_PWR_LDO5 (0x1 << 5)
1099#define RT5659_PWR_LDO5_BIT 5
1100#define RT5659_PWR_LDO4 (0x1 << 4)
1101#define RT5659_PWR_LDO4_BIT 4
1102#define RT5659_PWR_LDO3 (0x1 << 3)
1103#define RT5659_PWR_LDO3_BIT 3
1104#define RT5659_PWR_LDO2 (0x1 << 2)
1105#define RT5659_PWR_LDO2_BIT 2
1106#define RT5659_PWR_SVD (0x1 << 1)
1107#define RT5659_PWR_SVD_BIT 1
1108
1109/* Power Management for Mixer (0x0066) */
1110#define RT5659_PWR_OM_L (0x1 << 15)
1111#define RT5659_PWR_OM_L_BIT 15
1112#define RT5659_PWR_OM_R (0x1 << 14)
1113#define RT5659_PWR_OM_R_BIT 14
1114#define RT5659_PWR_SM_L (0x1 << 13)
1115#define RT5659_PWR_SM_L_BIT 13
1116#define RT5659_PWR_SM_R (0x1 << 12)
1117#define RT5659_PWR_SM_R_BIT 12
1118#define RT5659_PWR_RM1_L (0x1 << 11)
1119#define RT5659_PWR_RM1_L_BIT 11
1120#define RT5659_PWR_RM1_R (0x1 << 10)
1121#define RT5659_PWR_RM1_R_BIT 10
1122#define RT5659_PWR_MM (0x1 << 8)
1123#define RT5659_PWR_MM_BIT 8
1124#define RT5659_PWR_RM2_L (0x1 << 3)
1125#define RT5659_PWR_RM2_L_BIT 3
1126#define RT5659_PWR_RM2_R (0x1 << 2)
1127#define RT5659_PWR_RM2_R_BIT 2
1128
1129/* Power Management for Volume (0x0067) */
1130#define RT5659_PWR_SV_L (0x1 << 15)
1131#define RT5659_PWR_SV_L_BIT 15
1132#define RT5659_PWR_SV_R (0x1 << 14)
1133#define RT5659_PWR_SV_R_BIT 14
1134#define RT5659_PWR_OV_L (0x1 << 13)
1135#define RT5659_PWR_OV_L_BIT 13
1136#define RT5659_PWR_OV_R (0x1 << 12)
1137#define RT5659_PWR_OV_R_BIT 12
1138#define RT5659_PWR_IN_L (0x1 << 9)
1139#define RT5659_PWR_IN_L_BIT 9
1140#define RT5659_PWR_IN_R (0x1 << 8)
1141#define RT5659_PWR_IN_R_BIT 8
1142#define RT5659_PWR_MV (0x1 << 7)
1143#define RT5659_PWR_MV_BIT 7
1144#define RT5659_PWR_MIC_DET (0x1 << 5)
1145#define RT5659_PWR_MIC_DET_BIT 5
1146
1147/* I2S1/2/3 Audio Serial Data Port Control (0x0070 0x0071 0x0072) */
1148#define RT5659_I2S_MS_MASK (0x1 << 15)
1149#define RT5659_I2S_MS_SFT 15
1150#define RT5659_I2S_MS_M (0x0 << 15)
1151#define RT5659_I2S_MS_S (0x1 << 15)
1152#define RT5659_I2S_O_CP_MASK (0x3 << 12)
1153#define RT5659_I2S_O_CP_SFT 12
1154#define RT5659_I2S_O_CP_OFF (0x0 << 12)
1155#define RT5659_I2S_O_CP_U_LAW (0x1 << 12)
1156#define RT5659_I2S_O_CP_A_LAW (0x2 << 12)
1157#define RT5659_I2S_I_CP_MASK (0x3 << 10)
1158#define RT5659_I2S_I_CP_SFT 10
1159#define RT5659_I2S_I_CP_OFF (0x0 << 10)
1160#define RT5659_I2S_I_CP_U_LAW (0x1 << 10)
1161#define RT5659_I2S_I_CP_A_LAW (0x2 << 10)
1162#define RT5659_I2S_BP_MASK (0x1 << 8)
1163#define RT5659_I2S_BP_SFT 8
1164#define RT5659_I2S_BP_NOR (0x0 << 8)
1165#define RT5659_I2S_BP_INV (0x1 << 8)
1166#define RT5659_I2S_DL_MASK (0x3 << 4)
1167#define RT5659_I2S_DL_SFT 4
1168#define RT5659_I2S_DL_16 (0x0 << 4)
1169#define RT5659_I2S_DL_20 (0x1 << 4)
1170#define RT5659_I2S_DL_24 (0x2 << 4)
1171#define RT5659_I2S_DL_8 (0x3 << 4)
1172#define RT5659_I2S_DF_MASK (0x7)
1173#define RT5659_I2S_DF_SFT 0
1174#define RT5659_I2S_DF_I2S (0x0)
1175#define RT5659_I2S_DF_LEFT (0x1)
1176#define RT5659_I2S_DF_PCM_A (0x2)
1177#define RT5659_I2S_DF_PCM_B (0x3)
1178#define RT5659_I2S_DF_PCM_A_N (0x6)
1179#define RT5659_I2S_DF_PCM_B_N (0x7)
1180
1181/* ADC/DAC Clock Control 1 (0x0073) */
1182#define RT5659_I2S_PD1_MASK (0x7 << 12)
1183#define RT5659_I2S_PD1_SFT 12
1184#define RT5659_I2S_PD1_1 (0x0 << 12)
1185#define RT5659_I2S_PD1_2 (0x1 << 12)
1186#define RT5659_I2S_PD1_3 (0x2 << 12)
1187#define RT5659_I2S_PD1_4 (0x3 << 12)
1188#define RT5659_I2S_PD1_6 (0x4 << 12)
1189#define RT5659_I2S_PD1_8 (0x5 << 12)
1190#define RT5659_I2S_PD1_12 (0x6 << 12)
1191#define RT5659_I2S_PD1_16 (0x7 << 12)
1192#define RT5659_I2S_BCLK_MS2_MASK (0x1 << 11)
1193#define RT5659_I2S_BCLK_MS2_SFT 11
1194#define RT5659_I2S_BCLK_MS2_32 (0x0 << 11)
1195#define RT5659_I2S_BCLK_MS2_64 (0x1 << 11)
1196#define RT5659_I2S_PD2_MASK (0x7 << 8)
1197#define RT5659_I2S_PD2_SFT 8
1198#define RT5659_I2S_PD2_1 (0x0 << 8)
1199#define RT5659_I2S_PD2_2 (0x1 << 8)
1200#define RT5659_I2S_PD2_3 (0x2 << 8)
1201#define RT5659_I2S_PD2_4 (0x3 << 8)
1202#define RT5659_I2S_PD2_6 (0x4 << 8)
1203#define RT5659_I2S_PD2_8 (0x5 << 8)
1204#define RT5659_I2S_PD2_12 (0x6 << 8)
1205#define RT5659_I2S_PD2_16 (0x7 << 8)
1206#define RT5659_I2S_BCLK_MS3_MASK (0x1 << 7)
1207#define RT5659_I2S_BCLK_MS3_SFT 7
1208#define RT5659_I2S_BCLK_MS3_32 (0x0 << 7)
1209#define RT5659_I2S_BCLK_MS3_64 (0x1 << 7)
1210#define RT5659_I2S_PD3_MASK (0x7 << 4)
1211#define RT5659_I2S_PD3_SFT 4
1212#define RT5659_I2S_PD3_1 (0x0 << 4)
1213#define RT5659_I2S_PD3_2 (0x1 << 4)
1214#define RT5659_I2S_PD3_3 (0x2 << 4)
1215#define RT5659_I2S_PD3_4 (0x3 << 4)
1216#define RT5659_I2S_PD3_6 (0x4 << 4)
1217#define RT5659_I2S_PD3_8 (0x5 << 4)
1218#define RT5659_I2S_PD3_12 (0x6 << 4)
1219#define RT5659_I2S_PD3_16 (0x7 << 4)
1220#define RT5659_DAC_OSR_MASK (0x3 << 2)
1221#define RT5659_DAC_OSR_SFT 2
1222#define RT5659_DAC_OSR_128 (0x0 << 2)
1223#define RT5659_DAC_OSR_64 (0x1 << 2)
1224#define RT5659_DAC_OSR_32 (0x2 << 2)
1225#define RT5659_DAC_OSR_16 (0x3 << 2)
1226#define RT5659_ADC_OSR_MASK (0x3)
1227#define RT5659_ADC_OSR_SFT 0
1228#define RT5659_ADC_OSR_128 (0x0)
1229#define RT5659_ADC_OSR_64 (0x1)
1230#define RT5659_ADC_OSR_32 (0x2)
1231#define RT5659_ADC_OSR_16 (0x3)
1232
1233/* Digital Microphone Control (0x0075) */
1234#define RT5659_DMIC_1_EN_MASK (0x1 << 15)
1235#define RT5659_DMIC_1_EN_SFT 15
1236#define RT5659_DMIC_1_DIS (0x0 << 15)
1237#define RT5659_DMIC_1_EN (0x1 << 15)
1238#define RT5659_DMIC_2_EN_MASK (0x1 << 14)
1239#define RT5659_DMIC_2_EN_SFT 14
1240#define RT5659_DMIC_2_DIS (0x0 << 14)
1241#define RT5659_DMIC_2_EN (0x1 << 14)
1242#define RT5659_DMIC_1L_LH_MASK (0x1 << 13)
1243#define RT5659_DMIC_1L_LH_SFT 13
1244#define RT5659_DMIC_1L_LH_RISING (0x0 << 13)
1245#define RT5659_DMIC_1L_LH_FALLING (0x1 << 13)
1246#define RT5659_DMIC_1R_LH_MASK (0x1 << 12)
1247#define RT5659_DMIC_1R_LH_SFT 12
1248#define RT5659_DMIC_1R_LH_RISING (0x0 << 12)
1249#define RT5659_DMIC_1R_LH_FALLING (0x1 << 12)
1250#define RT5659_DMIC_2_DP_MASK (0x3 << 10)
1251#define RT5659_DMIC_2_DP_SFT 10
1252#define RT5659_DMIC_2_DP_GPIO6 (0x0 << 10)
1253#define RT5659_DMIC_2_DP_GPIO10 (0x1 << 10)
1254#define RT5659_DMIC_2_DP_GPIO12 (0x2 << 10)
1255#define RT5659_DMIC_2_DP_IN2P (0x3 << 10)
1256#define RT5659_DMIC_CLK_MASK (0x7 << 5)
1257#define RT5659_DMIC_CLK_SFT 5
1258#define RT5659_DMIC_1_DP_MASK (0x3 << 0)
1259#define RT5659_DMIC_1_DP_SFT 0
1260#define RT5659_DMIC_1_DP_GPIO5 (0x0 << 0)
1261#define RT5659_DMIC_1_DP_GPIO9 (0x1 << 0)
1262#define RT5659_DMIC_1_DP_GPIO11 (0x2 << 0)
1263#define RT5659_DMIC_1_DP_IN2N (0x3 << 0)
1264
1265/* TDM control 1 (0x0078)*/
1266#define RT5659_DS_ADC_SLOT01_SFT 14
1267#define RT5659_DS_ADC_SLOT23_SFT 12
1268#define RT5659_DS_ADC_SLOT45_SFT 10
1269#define RT5659_DS_ADC_SLOT67_SFT 8
1270#define RT5659_ADCDAT_SRC_MASK 0x1f
1271#define RT5659_ADCDAT_SRC_SFT 0
1272
1273/* Global Clock Control (0x0080) */
1274#define RT5659_SCLK_SRC_MASK (0x3 << 14)
1275#define RT5659_SCLK_SRC_SFT 14
1276#define RT5659_SCLK_SRC_MCLK (0x0 << 14)
1277#define RT5659_SCLK_SRC_PLL1 (0x1 << 14)
1278#define RT5659_SCLK_SRC_RCCLK (0x2 << 14)
1279#define RT5659_PLL1_SRC_MASK (0x7 << 11)
1280#define RT5659_PLL1_SRC_SFT 11
1281#define RT5659_PLL1_SRC_MCLK (0x0 << 11)
1282#define RT5659_PLL1_SRC_BCLK1 (0x1 << 11)
1283#define RT5659_PLL1_SRC_BCLK2 (0x2 << 11)
1284#define RT5659_PLL1_SRC_BCLK3 (0x3 << 11)
1285#define RT5659_PLL1_PD_MASK (0x1 << 3)
1286#define RT5659_PLL1_PD_SFT 3
1287#define RT5659_PLL1_PD_1 (0x0 << 3)
1288#define RT5659_PLL1_PD_2 (0x1 << 3)
1289
1290#define RT5659_PLL_INP_MAX 40000000
1291#define RT5659_PLL_INP_MIN 256000
1292/* PLL M/N/K Code Control 1 (0x0081) */
1293#define RT5659_PLL_N_MAX 0x001ff
1294#define RT5659_PLL_N_MASK (RT5659_PLL_N_MAX << 7)
1295#define RT5659_PLL_N_SFT 7
1296#define RT5659_PLL_K_MAX 0x001f
1297#define RT5659_PLL_K_MASK (RT5659_PLL_K_MAX)
1298#define RT5659_PLL_K_SFT 0
1299
1300/* PLL M/N/K Code Control 2 (0x0082) */
1301#define RT5659_PLL_M_MAX 0x00f
1302#define RT5659_PLL_M_MASK (RT5659_PLL_M_MAX << 12)
1303#define RT5659_PLL_M_SFT 12
1304#define RT5659_PLL_M_BP (0x1 << 11)
1305#define RT5659_PLL_M_BP_SFT 11
1306
1307/* PLL tracking mode 1 (0x0083) */
1308#define RT5659_I2S3_ASRC_MASK (0x1 << 13)
1309#define RT5659_I2S3_ASRC_SFT 13
1310#define RT5659_I2S2_ASRC_MASK (0x1 << 12)
1311#define RT5659_I2S2_ASRC_SFT 12
1312#define RT5659_I2S1_ASRC_MASK (0x1 << 11)
1313#define RT5659_I2S1_ASRC_SFT 11
1314#define RT5659_DAC_STO_ASRC_MASK (0x1 << 10)
1315#define RT5659_DAC_STO_ASRC_SFT 10
1316#define RT5659_DAC_MONO_L_ASRC_MASK (0x1 << 9)
1317#define RT5659_DAC_MONO_L_ASRC_SFT 9
1318#define RT5659_DAC_MONO_R_ASRC_MASK (0x1 << 8)
1319#define RT5659_DAC_MONO_R_ASRC_SFT 8
1320#define RT5659_DMIC_STO1_ASRC_MASK (0x1 << 7)
1321#define RT5659_DMIC_STO1_ASRC_SFT 7
1322#define RT5659_DMIC_MONO_L_ASRC_MASK (0x1 << 5)
1323#define RT5659_DMIC_MONO_L_ASRC_SFT 5
1324#define RT5659_DMIC_MONO_R_ASRC_MASK (0x1 << 4)
1325#define RT5659_DMIC_MONO_R_ASRC_SFT 4
1326#define RT5659_ADC_STO1_ASRC_MASK (0x1 << 3)
1327#define RT5659_ADC_STO1_ASRC_SFT 3
1328#define RT5659_ADC_MONO_L_ASRC_MASK (0x1 << 1)
1329#define RT5659_ADC_MONO_L_ASRC_SFT 1
1330#define RT5659_ADC_MONO_R_ASRC_MASK (0x1)
1331#define RT5659_ADC_MONO_R_ASRC_SFT 0
1332
1333/* PLL tracking mode 2 (0x0084)*/
1334#define RT5659_DA_STO_T_MASK (0x7 << 12)
1335#define RT5659_DA_STO_T_SFT 12
1336#define RT5659_DA_MONO_L_T_MASK (0x7 << 8)
1337#define RT5659_DA_MONO_L_T_SFT 8
1338#define RT5659_DA_MONO_R_T_MASK (0x7 << 4)
1339#define RT5659_DA_MONO_R_T_SFT 4
1340#define RT5659_AD_STO1_T_MASK (0x7)
1341#define RT5659_AD_STO1_T_SFT 0
1342
1343/* PLL tracking mode 3 (0x0085)*/
1344#define RT5659_AD_STO2_T_MASK (0x7 << 8)
1345#define RT5659_AD_STO2_T_SFT 8
1346#define RT5659_AD_MONO_L_T_MASK (0x7 << 4)
1347#define RT5659_AD_MONO_L_T_SFT 4
1348#define RT5659_AD_MONO_R_T_MASK (0x7)
1349#define RT5659_AD_MONO_R_T_SFT 0
1350
1351/* ASRC Control 4 (0x0086) */
1352#define RT5659_I2S1_RATE_MASK (0xf << 12)
1353#define RT5659_I2S1_RATE_SFT 12
1354#define RT5659_I2S2_RATE_MASK (0xf << 8)
1355#define RT5659_I2S2_RATE_SFT 8
1356#define RT5659_I2S3_RATE_MASK (0xf << 4)
1357#define RT5659_I2S3_RATE_SFT 4
1358
1359/* Depop Mode Control 1 (0x8e) */
1360#define RT5659_SMT_TRIG_MASK (0x1 << 15)
1361#define RT5659_SMT_TRIG_SFT 15
1362#define RT5659_SMT_TRIG_DIS (0x0 << 15)
1363#define RT5659_SMT_TRIG_EN (0x1 << 15)
1364#define RT5659_HP_L_SMT_MASK (0x1 << 9)
1365#define RT5659_HP_L_SMT_SFT 9
1366#define RT5659_HP_L_SMT_DIS (0x0 << 9)
1367#define RT5659_HP_L_SMT_EN (0x1 << 9)
1368#define RT5659_HP_R_SMT_MASK (0x1 << 8)
1369#define RT5659_HP_R_SMT_SFT 8
1370#define RT5659_HP_R_SMT_DIS (0x0 << 8)
1371#define RT5659_HP_R_SMT_EN (0x1 << 8)
1372#define RT5659_HP_CD_PD_MASK (0x1 << 7)
1373#define RT5659_HP_CD_PD_SFT 7
1374#define RT5659_HP_CD_PD_DIS (0x0 << 7)
1375#define RT5659_HP_CD_PD_EN (0x1 << 7)
1376#define RT5659_RSTN_MASK (0x1 << 6)
1377#define RT5659_RSTN_SFT 6
1378#define RT5659_RSTN_DIS (0x0 << 6)
1379#define RT5659_RSTN_EN (0x1 << 6)
1380#define RT5659_RSTP_MASK (0x1 << 5)
1381#define RT5659_RSTP_SFT 5
1382#define RT5659_RSTP_DIS (0x0 << 5)
1383#define RT5659_RSTP_EN (0x1 << 5)
1384#define RT5659_HP_CO_MASK (0x1 << 4)
1385#define RT5659_HP_CO_SFT 4
1386#define RT5659_HP_CO_DIS (0x0 << 4)
1387#define RT5659_HP_CO_EN (0x1 << 4)
1388#define RT5659_HP_CP_MASK (0x1 << 3)
1389#define RT5659_HP_CP_SFT 3
1390#define RT5659_HP_CP_PD (0x0 << 3)
1391#define RT5659_HP_CP_PU (0x1 << 3)
1392#define RT5659_HP_SG_MASK (0x1 << 2)
1393#define RT5659_HP_SG_SFT 2
1394#define RT5659_HP_SG_DIS (0x0 << 2)
1395#define RT5659_HP_SG_EN (0x1 << 2)
1396#define RT5659_HP_DP_MASK (0x1 << 1)
1397#define RT5659_HP_DP_SFT 1
1398#define RT5659_HP_DP_PD (0x0 << 1)
1399#define RT5659_HP_DP_PU (0x1 << 1)
1400#define RT5659_HP_CB_MASK (0x1)
1401#define RT5659_HP_CB_SFT 0
1402#define RT5659_HP_CB_PD (0x0)
1403#define RT5659_HP_CB_PU (0x1)
1404
1405/* Depop Mode Control 2 (0x8f) */
1406#define RT5659_DEPOP_MASK (0x1 << 13)
1407#define RT5659_DEPOP_SFT 13
1408#define RT5659_DEPOP_AUTO (0x0 << 13)
1409#define RT5659_DEPOP_MAN (0x1 << 13)
1410#define RT5659_RAMP_MASK (0x1 << 12)
1411#define RT5659_RAMP_SFT 12
1412#define RT5659_RAMP_DIS (0x0 << 12)
1413#define RT5659_RAMP_EN (0x1 << 12)
1414#define RT5659_BPS_MASK (0x1 << 11)
1415#define RT5659_BPS_SFT 11
1416#define RT5659_BPS_DIS (0x0 << 11)
1417#define RT5659_BPS_EN (0x1 << 11)
1418#define RT5659_FAST_UPDN_MASK (0x1 << 10)
1419#define RT5659_FAST_UPDN_SFT 10
1420#define RT5659_FAST_UPDN_DIS (0x0 << 10)
1421#define RT5659_FAST_UPDN_EN (0x1 << 10)
1422#define RT5659_MRES_MASK (0x3 << 8)
1423#define RT5659_MRES_SFT 8
1424#define RT5659_MRES_15MO (0x0 << 8)
1425#define RT5659_MRES_25MO (0x1 << 8)
1426#define RT5659_MRES_35MO (0x2 << 8)
1427#define RT5659_MRES_45MO (0x3 << 8)
1428#define RT5659_VLO_MASK (0x1 << 7)
1429#define RT5659_VLO_SFT 7
1430#define RT5659_VLO_3V (0x0 << 7)
1431#define RT5659_VLO_32V (0x1 << 7)
1432#define RT5659_DIG_DP_MASK (0x1 << 6)
1433#define RT5659_DIG_DP_SFT 6
1434#define RT5659_DIG_DP_DIS (0x0 << 6)
1435#define RT5659_DIG_DP_EN (0x1 << 6)
1436#define RT5659_DP_TH_MASK (0x3 << 4)
1437#define RT5659_DP_TH_SFT 4
1438
1439/* Depop Mode Control 3 (0x90) */
1440#define RT5659_CP_SYS_MASK (0x7 << 12)
1441#define RT5659_CP_SYS_SFT 12
1442#define RT5659_CP_FQ1_MASK (0x7 << 8)
1443#define RT5659_CP_FQ1_SFT 8
1444#define RT5659_CP_FQ2_MASK (0x7 << 4)
1445#define RT5659_CP_FQ2_SFT 4
1446#define RT5659_CP_FQ3_MASK (0x7)
1447#define RT5659_CP_FQ3_SFT 0
1448#define RT5659_CP_FQ_1_5_KHZ 0
1449#define RT5659_CP_FQ_3_KHZ 1
1450#define RT5659_CP_FQ_6_KHZ 2
1451#define RT5659_CP_FQ_12_KHZ 3
1452#define RT5659_CP_FQ_24_KHZ 4
1453#define RT5659_CP_FQ_48_KHZ 5
1454#define RT5659_CP_FQ_96_KHZ 6
1455#define RT5659_CP_FQ_192_KHZ 7
1456
1457/* HPOUT charge pump 1 (0x0091) */
1458#define RT5659_OSW_L_MASK (0x1 << 11)
1459#define RT5659_OSW_L_SFT 11
1460#define RT5659_OSW_L_DIS (0x0 << 11)
1461#define RT5659_OSW_L_EN (0x1 << 11)
1462#define RT5659_OSW_R_MASK (0x1 << 10)
1463#define RT5659_OSW_R_SFT 10
1464#define RT5659_OSW_R_DIS (0x0 << 10)
1465#define RT5659_OSW_R_EN (0x1 << 10)
1466#define RT5659_PM_HP_MASK (0x3 << 8)
1467#define RT5659_PM_HP_SFT 8
1468#define RT5659_PM_HP_LV (0x0 << 8)
1469#define RT5659_PM_HP_MV (0x1 << 8)
1470#define RT5659_PM_HP_HV (0x2 << 8)
1471#define RT5659_IB_HP_MASK (0x3 << 6)
1472#define RT5659_IB_HP_SFT 6
1473#define RT5659_IB_HP_125IL (0x0 << 6)
1474#define RT5659_IB_HP_25IL (0x1 << 6)
1475#define RT5659_IB_HP_5IL (0x2 << 6)
1476#define RT5659_IB_HP_1IL (0x3 << 6)
1477
1478/* PV detection and SPK gain control (0x92) */
1479#define RT5659_PVDD_DET_MASK (0x1 << 15)
1480#define RT5659_PVDD_DET_SFT 15
1481#define RT5659_PVDD_DET_DIS (0x0 << 15)
1482#define RT5659_PVDD_DET_EN (0x1 << 15)
1483#define RT5659_SPK_AG_MASK (0x1 << 14)
1484#define RT5659_SPK_AG_SFT 14
1485#define RT5659_SPK_AG_DIS (0x0 << 14)
1486#define RT5659_SPK_AG_EN (0x1 << 14)
1487
1488/* Micbias Control (0x93) */
1489#define RT5659_MIC1_BS_MASK (0x1 << 15)
1490#define RT5659_MIC1_BS_SFT 15
1491#define RT5659_MIC1_BS_9AV (0x0 << 15)
1492#define RT5659_MIC1_BS_75AV (0x1 << 15)
1493#define RT5659_MIC2_BS_MASK (0x1 << 14)
1494#define RT5659_MIC2_BS_SFT 14
1495#define RT5659_MIC2_BS_9AV (0x0 << 14)
1496#define RT5659_MIC2_BS_75AV (0x1 << 14)
1497#define RT5659_MIC1_CLK_MASK (0x1 << 13)
1498#define RT5659_MIC1_CLK_SFT 13
1499#define RT5659_MIC1_CLK_DIS (0x0 << 13)
1500#define RT5659_MIC1_CLK_EN (0x1 << 13)
1501#define RT5659_MIC2_CLK_MASK (0x1 << 12)
1502#define RT5659_MIC2_CLK_SFT 12
1503#define RT5659_MIC2_CLK_DIS (0x0 << 12)
1504#define RT5659_MIC2_CLK_EN (0x1 << 12)
1505#define RT5659_MIC1_OVCD_MASK (0x1 << 11)
1506#define RT5659_MIC1_OVCD_SFT 11
1507#define RT5659_MIC1_OVCD_DIS (0x0 << 11)
1508#define RT5659_MIC1_OVCD_EN (0x1 << 11)
1509#define RT5659_MIC1_OVTH_MASK (0x3 << 9)
1510#define RT5659_MIC1_OVTH_SFT 9
1511#define RT5659_MIC1_OVTH_600UA (0x0 << 9)
1512#define RT5659_MIC1_OVTH_1500UA (0x1 << 9)
1513#define RT5659_MIC1_OVTH_2000UA (0x2 << 9)
1514#define RT5659_MIC2_OVCD_MASK (0x1 << 8)
1515#define RT5659_MIC2_OVCD_SFT 8
1516#define RT5659_MIC2_OVCD_DIS (0x0 << 8)
1517#define RT5659_MIC2_OVCD_EN (0x1 << 8)
1518#define RT5659_MIC2_OVTH_MASK (0x3 << 6)
1519#define RT5659_MIC2_OVTH_SFT 6
1520#define RT5659_MIC2_OVTH_600UA (0x0 << 6)
1521#define RT5659_MIC2_OVTH_1500UA (0x1 << 6)
1522#define RT5659_MIC2_OVTH_2000UA (0x2 << 6)
1523#define RT5659_PWR_MB_MASK (0x1 << 5)
1524#define RT5659_PWR_MB_SFT 5
1525#define RT5659_PWR_MB_PD (0x0 << 5)
1526#define RT5659_PWR_MB_PU (0x1 << 5)
1527#define RT5659_PWR_CLK25M_MASK (0x1 << 4)
1528#define RT5659_PWR_CLK25M_SFT 4
1529#define RT5659_PWR_CLK25M_PD (0x0 << 4)
1530#define RT5659_PWR_CLK25M_PU (0x1 << 4)
1531
1532/* REC Mixer 2 Left Control 2 (0x009c) */
1533#define RT5659_M_BST1_RM2_L (0x1 << 5)
1534#define RT5659_M_BST1_RM2_L_SFT 5
1535#define RT5659_M_BST2_RM2_L (0x1 << 4)
1536#define RT5659_M_BST2_RM2_L_SFT 4
1537#define RT5659_M_BST3_RM2_L (0x1 << 3)
1538#define RT5659_M_BST3_RM2_L_SFT 3
1539#define RT5659_M_BST4_RM2_L (0x1 << 2)
1540#define RT5659_M_BST4_RM2_L_SFT 2
1541#define RT5659_M_OUTVOLL_RM2_L (0x1 << 1)
1542#define RT5659_M_OUTVOLL_RM2_L_SFT 1
1543#define RT5659_M_SPKVOL_RM2_L (0x1)
1544#define RT5659_M_SPKVOL_RM2_L_SFT 0
1545
1546/* REC Mixer 2 Right Control 2 (0x009e) */
1547#define RT5659_M_BST1_RM2_R (0x1 << 5)
1548#define RT5659_M_BST1_RM2_R_SFT 5
1549#define RT5659_M_BST2_RM2_R (0x1 << 4)
1550#define RT5659_M_BST2_RM2_R_SFT 4
1551#define RT5659_M_BST3_RM2_R (0x1 << 3)
1552#define RT5659_M_BST3_RM2_R_SFT 3
1553#define RT5659_M_BST4_RM2_R (0x1 << 2)
1554#define RT5659_M_BST4_RM2_R_SFT 2
1555#define RT5659_M_OUTVOLR_RM2_R (0x1 << 1)
1556#define RT5659_M_OUTVOLR_RM2_R_SFT 1
1557#define RT5659_M_MONOVOL_RM2_R (0x1)
1558#define RT5659_M_MONOVOL_RM2_R_SFT 0
1559
1560/* Class D Output Control (0x00a0) */
1561#define RT5659_POW_CLSD_DB_MASK (0x1 << 9)
1562#define RT5659_POW_CLSD_DB_EN (0x1 << 9)
1563#define RT5659_POW_CLSD_DB_DIS (0x0 << 9)
1564
1565/* EQ Control 1 (0x00b0) */
1566#define RT5659_EQ_SRC_DAC (0x0 << 15)
1567#define RT5659_EQ_SRC_ADC (0x1 << 15)
1568#define RT5659_EQ_UPD (0x1 << 14)
1569#define RT5659_EQ_UPD_BIT 14
1570#define RT5659_EQ_CD_MASK (0x1 << 13)
1571#define RT5659_EQ_CD_SFT 13
1572#define RT5659_EQ_CD_DIS (0x0 << 13)
1573#define RT5659_EQ_CD_EN (0x1 << 13)
1574#define RT5659_EQ_DITH_MASK (0x3 << 8)
1575#define RT5659_EQ_DITH_SFT 8
1576#define RT5659_EQ_DITH_NOR (0x0 << 8)
1577#define RT5659_EQ_DITH_LSB (0x1 << 8)
1578#define RT5659_EQ_DITH_LSB_1 (0x2 << 8)
1579#define RT5659_EQ_DITH_LSB_2 (0x3 << 8)
1580
1581/* IRQ Control 1 (0x00b7) */
1582#define RT5659_JD1_1_EN_MASK (0x1 << 15)
1583#define RT5659_JD1_1_EN_SFT 15
1584#define RT5659_JD1_1_DIS (0x0 << 15)
1585#define RT5659_JD1_1_EN (0x1 << 15)
1586#define RT5659_JD1_2_EN_MASK (0x1 << 12)
1587#define RT5659_JD1_2_EN_SFT 12
1588#define RT5659_JD1_2_DIS (0x0 << 12)
1589#define RT5659_JD1_2_EN (0x1 << 12)
1590#define RT5659_IL_IRQ_MASK (0x1 << 3)
1591#define RT5659_IL_IRQ_DIS (0x0 << 3)
1592#define RT5659_IL_IRQ_EN (0x1 << 3)
1593
1594/* IRQ Control 5 (0x00ba) */
1595#define RT5659_IRQ_JD_EN (0x1 << 3)
1596#define RT5659_IRQ_JD_EN_SFT 3
1597
1598/* GPIO Control 1 (0x00c0) */
1599#define RT5659_GP1_PIN_MASK (0x1 << 15)
1600#define RT5659_GP1_PIN_SFT 15
1601#define RT5659_GP1_PIN_GPIO1 (0x0 << 15)
1602#define RT5659_GP1_PIN_IRQ (0x1 << 15)
1603#define RT5659_GP2_PIN_MASK (0x1 << 14)
1604#define RT5659_GP2_PIN_SFT 14
1605#define RT5659_GP2_PIN_GPIO2 (0x0 << 14)
1606#define RT5659_GP2_PIN_DMIC1_SCL (0x1 << 14)
1607#define RT5659_GP3_PIN_MASK (0x1 << 13)
1608#define RT5659_GP3_PIN_SFT 13
1609#define RT5659_GP3_PIN_GPIO3 (0x0 << 13)
1610#define RT5659_GP3_PIN_PDM_SCL (0x1 << 13)
1611#define RT5659_GP4_PIN_MASK (0x1 << 12)
1612#define RT5659_GP4_PIN_SFT 12
1613#define RT5659_GP4_PIN_GPIO4 (0x0 << 12)
1614#define RT5659_GP4_PIN_PDM_SDA (0x1 << 12)
1615#define RT5659_GP5_PIN_MASK (0x1 << 11)
1616#define RT5659_GP5_PIN_SFT 11
1617#define RT5659_GP5_PIN_GPIO5 (0x0 << 11)
1618#define RT5659_GP5_PIN_DMIC1_SDA (0x1 << 11)
1619#define RT5659_GP6_PIN_MASK (0x1 << 10)
1620#define RT5659_GP6_PIN_SFT 10
1621#define RT5659_GP6_PIN_GPIO6 (0x0 << 10)
1622#define RT5659_GP6_PIN_DMIC2_SDA (0x1 << 10)
1623#define RT5659_GP7_PIN_MASK (0x1 << 9)
1624#define RT5659_GP7_PIN_SFT 9
1625#define RT5659_GP7_PIN_GPIO7 (0x0 << 9)
1626#define RT5659_GP7_PIN_PDM_SCL (0x1 << 9)
1627#define RT5659_GP8_PIN_MASK (0x1 << 8)
1628#define RT5659_GP8_PIN_SFT 8
1629#define RT5659_GP8_PIN_GPIO8 (0x0 << 8)
1630#define RT5659_GP8_PIN_PDM_SDA (0x1 << 8)
1631#define RT5659_GP9_PIN_MASK (0x1 << 7)
1632#define RT5659_GP9_PIN_SFT 7
1633#define RT5659_GP9_PIN_GPIO9 (0x0 << 7)
1634#define RT5659_GP9_PIN_DMIC1_SDA (0x1 << 7)
1635#define RT5659_GP10_PIN_MASK (0x1 << 6)
1636#define RT5659_GP10_PIN_SFT 6
1637#define RT5659_GP10_PIN_GPIO10 (0x0 << 6)
1638#define RT5659_GP10_PIN_DMIC2_SDA (0x1 << 6)
1639#define RT5659_GP11_PIN_MASK (0x1 << 5)
1640#define RT5659_GP11_PIN_SFT 5
1641#define RT5659_GP11_PIN_GPIO11 (0x0 << 5)
1642#define RT5659_GP11_PIN_DMIC1_SDA (0x1 << 5)
1643#define RT5659_GP12_PIN_MASK (0x1 << 4)
1644#define RT5659_GP12_PIN_SFT 4
1645#define RT5659_GP12_PIN_GPIO12 (0x0 << 4)
1646#define RT5659_GP12_PIN_DMIC2_SDA (0x1 << 4)
1647#define RT5659_GP13_PIN_MASK (0x3 << 2)
1648#define RT5659_GP13_PIN_SFT 2
1649#define RT5659_GP13_PIN_GPIO13 (0x0 << 2)
1650#define RT5659_GP13_PIN_SPDIF_SDA (0x1 << 2)
1651#define RT5659_GP13_PIN_DMIC2_SCL (0x2 << 2)
1652#define RT5659_GP13_PIN_PDM_SCL (0x3 << 2)
1653#define RT5659_GP15_PIN_MASK (0x3)
1654#define RT5659_GP15_PIN_SFT 0
1655#define RT5659_GP15_PIN_GPIO15 (0x0)
1656#define RT5659_GP15_PIN_DMIC3_SCL (0x1)
1657#define RT5659_GP15_PIN_PDM_SDA (0x2)
1658
1659/* GPIO Control 2 (0x00c1)*/
1660#define RT5659_GP1_PF_IN (0x0 << 2)
1661#define RT5659_GP1_PF_OUT (0x1 << 2)
1662#define RT5659_GP1_PF_MASK (0x1 << 2)
1663#define RT5659_GP1_PF_SFT 2
1664
1665/* GPIO Control 3 (0x00c2) */
1666#define RT5659_I2S2_PIN_MASK (0x1 << 15)
1667#define RT5659_I2S2_PIN_SFT 15
1668#define RT5659_I2S2_PIN_I2S (0x0 << 15)
1669#define RT5659_I2S2_PIN_GPIO (0x1 << 15)
1670
1671/* Soft volume and zero cross control 1 (0x00d9) */
1672#define RT5659_SV_MASK (0x1 << 15)
1673#define RT5659_SV_SFT 15
1674#define RT5659_SV_DIS (0x0 << 15)
1675#define RT5659_SV_EN (0x1 << 15)
1676#define RT5659_OUT_SV_MASK (0x1 << 13)
1677#define RT5659_OUT_SV_SFT 13
1678#define RT5659_OUT_SV_DIS (0x0 << 13)
1679#define RT5659_OUT_SV_EN (0x1 << 13)
1680#define RT5659_HP_SV_MASK (0x1 << 12)
1681#define RT5659_HP_SV_SFT 12
1682#define RT5659_HP_SV_DIS (0x0 << 12)
1683#define RT5659_HP_SV_EN (0x1 << 12)
1684#define RT5659_ZCD_DIG_MASK (0x1 << 11)
1685#define RT5659_ZCD_DIG_SFT 11
1686#define RT5659_ZCD_DIG_DIS (0x0 << 11)
1687#define RT5659_ZCD_DIG_EN (0x1 << 11)
1688#define RT5659_ZCD_MASK (0x1 << 10)
1689#define RT5659_ZCD_SFT 10
1690#define RT5659_ZCD_PD (0x0 << 10)
1691#define RT5659_ZCD_PU (0x1 << 10)
1692#define RT5659_SV_DLY_MASK (0xf)
1693#define RT5659_SV_DLY_SFT 0
1694
1695/* Soft volume and zero cross control 2 (0x00da) */
1696#define RT5659_ZCD_HP_MASK (0x1 << 15)
1697#define RT5659_ZCD_HP_SFT 15
1698#define RT5659_ZCD_HP_DIS (0x0 << 15)
1699#define RT5659_ZCD_HP_EN (0x1 << 15)
1700
1701/* 4 Button Inline Command Control 2 (0x00e0) */
1702#define RT5659_4BTN_IL_MASK (0x1 << 15)
1703#define RT5659_4BTN_IL_EN (0x1 << 15)
1704#define RT5659_4BTN_IL_DIS (0x0 << 15)
1705
1706/* Analog JD Control 1 (0x00f0) */
1707#define RT5659_JD1_MODE_MASK (0x3 << 0)
1708#define RT5659_JD1_MODE_0 (0x0 << 0)
1709#define RT5659_JD1_MODE_1 (0x1 << 0)
1710#define RT5659_JD1_MODE_2 (0x2 << 0)
1711
1712/* Jack Detect Control 3 (0x00f8) */
1713#define RT5659_JD_TRI_HPO_SEL_MASK (0x7)
1714#define RT5659_JD_TRI_HPO_SEL_SFT (0)
1715#define RT5659_JD_HPO_GPIO_JD1 (0x0)
1716#define RT5659_JD_HPO_JD1_1 (0x1)
1717#define RT5659_JD_HPO_JD1_2 (0x2)
1718#define RT5659_JD_HPO_JD2 (0x3)
1719#define RT5659_JD_HPO_GPIO_JD2 (0x4)
1720#define RT5659_JD_HPO_JD3 (0x5)
1721#define RT5659_JD_HPO_JD_D (0x6)
1722
1723/* Digital Misc Control (0x00fa) */
1724#define RT5659_AM_MASK (0x1 << 7)
1725#define RT5659_AM_EN (0x1 << 7)
1726#define RT5659_AM_DIS (0x1 << 7)
1727#define RT5659_DIG_GATE_CTRL 0x1
1728#define RT5659_DIG_GATE_CTRL_SFT (0)
1729
1730/* Chopper and Clock control for ADC (0x011c)*/
1731#define RT5659_M_RF_DIG_MASK (0x1 << 12)
1732#define RT5659_M_RF_DIG_SFT 12
1733#define RT5659_M_RI_DIG (0x1 << 11)
1734
1735/* Chopper and Clock control for DAC (0x013a)*/
1736#define RT5659_CKXEN_DAC1_MASK (0x1 << 13)
1737#define RT5659_CKXEN_DAC1_SFT 13
1738#define RT5659_CKGEN_DAC1_MASK (0x1 << 12)
1739#define RT5659_CKGEN_DAC1_SFT 12
1740#define RT5659_CKXEN_DAC2_MASK (0x1 << 5)
1741#define RT5659_CKXEN_DAC2_SFT 5
1742#define RT5659_CKGEN_DAC2_MASK (0x1 << 4)
1743#define RT5659_CKGEN_DAC2_SFT 4
1744
1745/* Chopper and Clock control for ADC (0x013b)*/
1746#define RT5659_CKXEN_ADCC_MASK (0x1 << 13)
1747#define RT5659_CKXEN_ADCC_SFT 13
1748#define RT5659_CKGEN_ADCC_MASK (0x1 << 12)
1749#define RT5659_CKGEN_ADCC_SFT 12
1750
1751/* Test Mode Control 1 (0x0145) */
1752#define RT5659_AD2DA_LB_MASK (0x1 << 9)
1753#define RT5659_AD2DA_LB_SFT 9
1754
1755/* Stereo Noise Gate Control 1 (0x0160) */
1756#define RT5659_NG2_EN_MASK (0x1 << 15)
1757#define RT5659_NG2_EN (0x1 << 15)
1758#define RT5659_NG2_DIS (0x0 << 15)
1759
1760/* System Clock Source */
1761enum {
1762 RT5659_SCLK_S_MCLK,
1763 RT5659_SCLK_S_PLL1,
1764 RT5659_SCLK_S_RCCLK,
1765};
1766
1767/* PLL1 Source */
1768enum {
1769 RT5659_PLL1_S_MCLK,
1770 RT5659_PLL1_S_BCLK1,
1771 RT5659_PLL1_S_BCLK2,
1772 RT5659_PLL1_S_BCLK3,
1773 RT5659_PLL1_S_BCLK4,
1774};
1775
1776enum {
1777 RT5659_AIF1,
1778 RT5659_AIF2,
1779 RT5659_AIF3,
1780 RT5659_AIF4,
1781 RT5659_AIFS,
1782};
1783
1784struct rt5659_pll_code {
1785 bool m_bp;
1786 int m_code;
1787 int n_code;
1788 int k_code;
1789};
1790
1791struct rt5659_priv {
1792 struct snd_soc_codec *codec;
1793 struct rt5659_platform_data pdata;
1794 struct regmap *regmap;
1795 struct i2c_client *i2c;
1796 struct gpio_desc *gpiod_ldo1_en;
1797 struct gpio_desc *gpiod_reset;
1798 struct snd_soc_jack *hs_jack;
1799 struct delayed_work jack_detect_work;
1800
1801 int sysclk;
1802 int sysclk_src;
1803 int lrck[RT5659_AIFS];
1804 int bclk[RT5659_AIFS];
1805 int master[RT5659_AIFS];
1806 int v_id;
1807
1808 int pll_src;
1809 int pll_in;
1810 int pll_out;
1811
1812 int jack_type;
1813
1814};
1815
1816int rt5659_set_jack_detect(struct snd_soc_codec *codec,
1817 struct snd_soc_jack *hs_jack);
1818
1819#endif /* __RT5659_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 69d987a9935c..967678e7f48e 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -297,8 +297,6 @@ static bool rt5677_volatile_register(struct device *dev, unsigned int reg)
297 case RT5677_HAP_GENE_CTRL2: 297 case RT5677_HAP_GENE_CTRL2:
298 case RT5677_PWR_DSP_ST: 298 case RT5677_PWR_DSP_ST:
299 case RT5677_PRIV_DATA: 299 case RT5677_PRIV_DATA:
300 case RT5677_PLL1_CTRL2:
301 case RT5677_PLL2_CTRL2:
302 case RT5677_ASRC_22: 300 case RT5677_ASRC_22:
303 case RT5677_ASRC_23: 301 case RT5677_ASRC_23:
304 case RT5677_VAD_CTRL5: 302 case RT5677_VAD_CTRL5:
@@ -4788,7 +4786,7 @@ static int rt5677_remove(struct snd_soc_codec *codec)
4788 4786
4789 regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); 4787 regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
4790 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); 4788 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
4791 gpiod_set_value_cansleep(rt5677->reset_pin, 0); 4789 gpiod_set_value_cansleep(rt5677->reset_pin, 1);
4792 4790
4793 return 0; 4791 return 0;
4794} 4792}
@@ -4803,7 +4801,7 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
4803 regcache_mark_dirty(rt5677->regmap); 4801 regcache_mark_dirty(rt5677->regmap);
4804 4802
4805 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); 4803 gpiod_set_value_cansleep(rt5677->pow_ldo2, 0);
4806 gpiod_set_value_cansleep(rt5677->reset_pin, 0); 4804 gpiod_set_value_cansleep(rt5677->reset_pin, 1);
4807 } 4805 }
4808 4806
4809 return 0; 4807 return 0;
@@ -4814,8 +4812,11 @@ static int rt5677_resume(struct snd_soc_codec *codec)
4814 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); 4812 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
4815 4813
4816 if (!rt5677->dsp_vad_en) { 4814 if (!rt5677->dsp_vad_en) {
4815 rt5677->pll_src = 0;
4816 rt5677->pll_in = 0;
4817 rt5677->pll_out = 0;
4817 gpiod_set_value_cansleep(rt5677->pow_ldo2, 1); 4818 gpiod_set_value_cansleep(rt5677->pow_ldo2, 1);
4818 gpiod_set_value_cansleep(rt5677->reset_pin, 1); 4819 gpiod_set_value_cansleep(rt5677->reset_pin, 0);
4819 if (rt5677->pow_ldo2 || rt5677->reset_pin) 4820 if (rt5677->pow_ldo2 || rt5677->reset_pin)
4820 msleep(10); 4821 msleep(10);
4821 4822
@@ -5160,7 +5161,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
5160 return ret; 5161 return ret;
5161 } 5162 }
5162 rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev, 5163 rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev,
5163 "realtek,reset", GPIOD_OUT_HIGH); 5164 "realtek,reset", GPIOD_OUT_LOW);
5164 if (IS_ERR(rt5677->reset_pin)) { 5165 if (IS_ERR(rt5677->reset_pin)) {
5165 ret = PTR_ERR(rt5677->reset_pin); 5166 ret = PTR_ERR(rt5677->reset_pin);
5166 dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret); 5167 dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret);
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index 86b81a60ac52..e2e0bfa7ec20 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -309,7 +309,7 @@ static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
309 .count = ARRAY_SIZE(ssm2518_rates_12288000), 309 .count = ARRAY_SIZE(ssm2518_rates_12288000),
310}; 310};
311 311
312static unsigned int ssm2518_lookup_mcs(struct ssm2518 *ssm2518, 312static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
313 unsigned int rate) 313 unsigned int rate)
314{ 314{
315 const unsigned int *sysclks = NULL; 315 const unsigned int *sysclks = NULL;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index c04c0bc6f58a..c36409601835 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -575,6 +575,33 @@ static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
575 SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \ 575 SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \
576 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0) 576 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0)
577 577
578#define WM5110_RXANC_INPUT_ROUTES(widget, name) \
579 { widget, NULL, name " NG Mux" }, \
580 { name " NG Internal", NULL, "RXANC NG Clock" }, \
581 { name " NG Internal", NULL, name " Channel" }, \
582 { name " NG External", NULL, "RXANC NG External Clock" }, \
583 { name " NG External", NULL, name " Channel" }, \
584 { name " NG Mux", "None", name " Channel" }, \
585 { name " NG Mux", "Internal", name " NG Internal" }, \
586 { name " NG Mux", "External", name " NG External" }, \
587 { name " Channel", "Left", name " Left Input" }, \
588 { name " Channel", "Combine", name " Left Input" }, \
589 { name " Channel", "Right", name " Right Input" }, \
590 { name " Channel", "Combine", name " Right Input" }, \
591 { name " Left Input", "IN1", "IN1L PGA" }, \
592 { name " Right Input", "IN1", "IN1R PGA" }, \
593 { name " Left Input", "IN2", "IN2L PGA" }, \
594 { name " Right Input", "IN2", "IN2R PGA" }, \
595 { name " Left Input", "IN3", "IN3L PGA" }, \
596 { name " Right Input", "IN3", "IN3R PGA" }, \
597 { name " Left Input", "IN4", "IN4L PGA" }, \
598 { name " Right Input", "IN4", "IN4R PGA" }
599
600#define WM5110_RXANC_OUTPUT_ROUTES(widget, name) \
601 { widget, NULL, name " ANC Source" }, \
602 { name " ANC Source", "RXANCL", "RXANCL" }, \
603 { name " ANC Source", "RXANCR", "RXANCR" }
604
578static const struct snd_kcontrol_new wm5110_snd_controls[] = { 605static const struct snd_kcontrol_new wm5110_snd_controls[] = {
579SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]), 606SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
580SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]), 607SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
@@ -639,6 +666,15 @@ SOC_SINGLE_TLV("IN4R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4R,
639SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), 666SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
640SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), 667SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
641 668
669SND_SOC_BYTES("RXANC Coefficients", ARIZONA_ANC_COEFF_START,
670 ARIZONA_ANC_COEFF_END - ARIZONA_ANC_COEFF_START + 1),
671SND_SOC_BYTES("RXANCL Config", ARIZONA_FCL_FILTER_CONTROL, 1),
672SND_SOC_BYTES("RXANCL Coefficients", ARIZONA_FCL_COEFF_START,
673 ARIZONA_FCL_COEFF_END - ARIZONA_FCL_COEFF_START + 1),
674SND_SOC_BYTES("RXANCR Config", ARIZONA_FCR_FILTER_CONTROL, 1),
675SND_SOC_BYTES("RXANCR Coefficients", ARIZONA_FCR_COEFF_START,
676 ARIZONA_FCR_COEFF_END - ARIZONA_FCR_COEFF_START + 1),
677
642ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE), 678ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
643ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE), 679ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
644ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE), 680ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
@@ -995,6 +1031,31 @@ static const struct soc_enum wm5110_aec_loopback =
995static const struct snd_kcontrol_new wm5110_aec_loopback_mux = 1031static const struct snd_kcontrol_new wm5110_aec_loopback_mux =
996 SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback); 1032 SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback);
997 1033
1034static const struct snd_kcontrol_new wm5110_anc_input_mux[] = {
1035 SOC_DAPM_ENUM("RXANCL Input", arizona_anc_input_src[0]),
1036 SOC_DAPM_ENUM("RXANCL Channel", arizona_anc_input_src[1]),
1037 SOC_DAPM_ENUM("RXANCR Input", arizona_anc_input_src[2]),
1038 SOC_DAPM_ENUM("RXANCR Channel", arizona_anc_input_src[3]),
1039};
1040
1041static const struct snd_kcontrol_new wm5110_anc_ng_mux =
1042 SOC_DAPM_ENUM("RXANC NG Source", arizona_anc_ng_enum);
1043
1044static const struct snd_kcontrol_new wm5110_output_anc_src[] = {
1045 SOC_DAPM_ENUM("HPOUT1L ANC Source", arizona_output_anc_src[0]),
1046 SOC_DAPM_ENUM("HPOUT1R ANC Source", arizona_output_anc_src[1]),
1047 SOC_DAPM_ENUM("HPOUT2L ANC Source", arizona_output_anc_src[2]),
1048 SOC_DAPM_ENUM("HPOUT2R ANC Source", arizona_output_anc_src[3]),
1049 SOC_DAPM_ENUM("HPOUT3L ANC Source", arizona_output_anc_src[4]),
1050 SOC_DAPM_ENUM("HPOUT3R ANC Source", arizona_output_anc_src[5]),
1051 SOC_DAPM_ENUM("SPKOUTL ANC Source", arizona_output_anc_src[6]),
1052 SOC_DAPM_ENUM("SPKOUTR ANC Source", arizona_output_anc_src[7]),
1053 SOC_DAPM_ENUM("SPKDAT1L ANC Source", arizona_output_anc_src[8]),
1054 SOC_DAPM_ENUM("SPKDAT1R ANC Source", arizona_output_anc_src[9]),
1055 SOC_DAPM_ENUM("SPKDAT2L ANC Source", arizona_output_anc_src[10]),
1056 SOC_DAPM_ENUM("SPKDAT2R ANC Source", arizona_output_anc_src[11]),
1057};
1058
998static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { 1059static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
999SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, 1060SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
1000 0, wm5110_sysclk_ev, SND_SOC_DAPM_POST_PMU), 1061 0, wm5110_sysclk_ev, SND_SOC_DAPM_POST_PMU),
@@ -1185,6 +1246,65 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
1185 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, 1246 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
1186 &wm5110_aec_loopback_mux), 1247 &wm5110_aec_loopback_mux),
1187 1248
1249SND_SOC_DAPM_SUPPLY("RXANC NG External Clock", SND_SOC_NOPM,
1250 ARIZONA_EXT_NG_SEL_SET_SHIFT, 0, arizona_anc_ev,
1251 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1252SND_SOC_DAPM_PGA("RXANCL NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
1253SND_SOC_DAPM_PGA("RXANCR NG External", SND_SOC_NOPM, 0, 0, NULL, 0),
1254
1255SND_SOC_DAPM_SUPPLY("RXANC NG Clock", SND_SOC_NOPM,
1256 ARIZONA_CLK_NG_ENA_SET_SHIFT, 0, arizona_anc_ev,
1257 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1258SND_SOC_DAPM_PGA("RXANCL NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
1259SND_SOC_DAPM_PGA("RXANCR NG Internal", SND_SOC_NOPM, 0, 0, NULL, 0),
1260
1261SND_SOC_DAPM_MUX("RXANCL Left Input", SND_SOC_NOPM, 0, 0,
1262 &wm5110_anc_input_mux[0]),
1263SND_SOC_DAPM_MUX("RXANCL Right Input", SND_SOC_NOPM, 0, 0,
1264 &wm5110_anc_input_mux[0]),
1265SND_SOC_DAPM_MUX("RXANCL Channel", SND_SOC_NOPM, 0, 0,
1266 &wm5110_anc_input_mux[1]),
1267SND_SOC_DAPM_MUX("RXANCL NG Mux", SND_SOC_NOPM, 0, 0, &wm5110_anc_ng_mux),
1268SND_SOC_DAPM_MUX("RXANCR Left Input", SND_SOC_NOPM, 0, 0,
1269 &wm5110_anc_input_mux[2]),
1270SND_SOC_DAPM_MUX("RXANCR Right Input", SND_SOC_NOPM, 0, 0,
1271 &wm5110_anc_input_mux[2]),
1272SND_SOC_DAPM_MUX("RXANCR Channel", SND_SOC_NOPM, 0, 0,
1273 &wm5110_anc_input_mux[3]),
1274SND_SOC_DAPM_MUX("RXANCR NG Mux", SND_SOC_NOPM, 0, 0, &wm5110_anc_ng_mux),
1275
1276SND_SOC_DAPM_PGA_E("RXANCL", SND_SOC_NOPM, ARIZONA_CLK_L_ENA_SET_SHIFT,
1277 0, NULL, 0, arizona_anc_ev,
1278 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1279SND_SOC_DAPM_PGA_E("RXANCR", SND_SOC_NOPM, ARIZONA_CLK_R_ENA_SET_SHIFT,
1280 0, NULL, 0, arizona_anc_ev,
1281 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1282
1283SND_SOC_DAPM_MUX("HPOUT1L ANC Source", SND_SOC_NOPM, 0, 0,
1284 &wm5110_output_anc_src[0]),
1285SND_SOC_DAPM_MUX("HPOUT1R ANC Source", SND_SOC_NOPM, 0, 0,
1286 &wm5110_output_anc_src[1]),
1287SND_SOC_DAPM_MUX("HPOUT2L ANC Source", SND_SOC_NOPM, 0, 0,
1288 &wm5110_output_anc_src[2]),
1289SND_SOC_DAPM_MUX("HPOUT2R ANC Source", SND_SOC_NOPM, 0, 0,
1290 &wm5110_output_anc_src[3]),
1291SND_SOC_DAPM_MUX("HPOUT3L ANC Source", SND_SOC_NOPM, 0, 0,
1292 &wm5110_output_anc_src[4]),
1293SND_SOC_DAPM_MUX("HPOUT3R ANC Source", SND_SOC_NOPM, 0, 0,
1294 &wm5110_output_anc_src[5]),
1295SND_SOC_DAPM_MUX("SPKOUTL ANC Source", SND_SOC_NOPM, 0, 0,
1296 &wm5110_output_anc_src[6]),
1297SND_SOC_DAPM_MUX("SPKOUTR ANC Source", SND_SOC_NOPM, 0, 0,
1298 &wm5110_output_anc_src[7]),
1299SND_SOC_DAPM_MUX("SPKDAT1L ANC Source", SND_SOC_NOPM, 0, 0,
1300 &wm5110_output_anc_src[8]),
1301SND_SOC_DAPM_MUX("SPKDAT1R ANC Source", SND_SOC_NOPM, 0, 0,
1302 &wm5110_output_anc_src[9]),
1303SND_SOC_DAPM_MUX("SPKDAT2L ANC Source", SND_SOC_NOPM, 0, 0,
1304 &wm5110_output_anc_src[10]),
1305SND_SOC_DAPM_MUX("SPKDAT2R ANC Source", SND_SOC_NOPM, 0, 0,
1306 &wm5110_output_anc_src[11]),
1307
1188SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, 1308SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
1189 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), 1309 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
1190SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, 1310SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
@@ -1690,6 +1810,9 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1690 { "Slim2 Capture", NULL, "SYSCLK" }, 1810 { "Slim2 Capture", NULL, "SYSCLK" },
1691 { "Slim3 Capture", NULL, "SYSCLK" }, 1811 { "Slim3 Capture", NULL, "SYSCLK" },
1692 1812
1813 { "Voice Control DSP", NULL, "DSP3" },
1814 { "Voice Control DSP", NULL, "SYSCLK" },
1815
1693 { "IN1L PGA", NULL, "IN1L" }, 1816 { "IN1L PGA", NULL, "IN1L" },
1694 { "IN1R PGA", NULL, "IN1R" }, 1817 { "IN1R PGA", NULL, "IN1R" },
1695 1818
@@ -1838,6 +1961,22 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1838 { "SPKDAT2L", NULL, "OUT6L" }, 1961 { "SPKDAT2L", NULL, "OUT6L" },
1839 { "SPKDAT2R", NULL, "OUT6R" }, 1962 { "SPKDAT2R", NULL, "OUT6R" },
1840 1963
1964 WM5110_RXANC_INPUT_ROUTES("RXANCL", "RXANCL"),
1965 WM5110_RXANC_INPUT_ROUTES("RXANCR", "RXANCR"),
1966
1967 WM5110_RXANC_OUTPUT_ROUTES("OUT1L", "HPOUT1L"),
1968 WM5110_RXANC_OUTPUT_ROUTES("OUT1R", "HPOUT1R"),
1969 WM5110_RXANC_OUTPUT_ROUTES("OUT2L", "HPOUT2L"),
1970 WM5110_RXANC_OUTPUT_ROUTES("OUT2R", "HPOUT2R"),
1971 WM5110_RXANC_OUTPUT_ROUTES("OUT3L", "HPOUT3L"),
1972 WM5110_RXANC_OUTPUT_ROUTES("OUT3R", "HPOUT3R"),
1973 WM5110_RXANC_OUTPUT_ROUTES("OUT4L", "SPKOUTL"),
1974 WM5110_RXANC_OUTPUT_ROUTES("OUT4R", "SPKOUTR"),
1975 WM5110_RXANC_OUTPUT_ROUTES("OUT5L", "SPKDAT1L"),
1976 WM5110_RXANC_OUTPUT_ROUTES("OUT5R", "SPKDAT1R"),
1977 WM5110_RXANC_OUTPUT_ROUTES("OUT6L", "SPKDAT2L"),
1978 WM5110_RXANC_OUTPUT_ROUTES("OUT6R", "SPKDAT2R"),
1979
1841 { "MICSUPP", NULL, "SYSCLK" }, 1980 { "MICSUPP", NULL, "SYSCLK" },
1842 1981
1843 { "DRC1 Signal Activity", NULL, "DRC1L" }, 1982 { "DRC1 Signal Activity", NULL, "DRC1L" },
@@ -1996,8 +2135,48 @@ static struct snd_soc_dai_driver wm5110_dai[] = {
1996 }, 2135 },
1997 .ops = &arizona_simple_dai_ops, 2136 .ops = &arizona_simple_dai_ops,
1998 }, 2137 },
2138 {
2139 .name = "wm5110-cpu-voicectrl",
2140 .capture = {
2141 .stream_name = "Voice Control CPU",
2142 .channels_min = 1,
2143 .channels_max = 1,
2144 .rates = WM5110_RATES,
2145 .formats = WM5110_FORMATS,
2146 },
2147 .compress_new = snd_soc_new_compress,
2148 },
2149 {
2150 .name = "wm5110-dsp-voicectrl",
2151 .capture = {
2152 .stream_name = "Voice Control DSP",
2153 .channels_min = 1,
2154 .channels_max = 1,
2155 .rates = WM5110_RATES,
2156 .formats = WM5110_FORMATS,
2157 },
2158 },
1999}; 2159};
2000 2160
2161static int wm5110_open(struct snd_compr_stream *stream)
2162{
2163 struct snd_soc_pcm_runtime *rtd = stream->private_data;
2164 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
2165 struct arizona *arizona = priv->core.arizona;
2166 int n_adsp;
2167
2168 if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) {
2169 n_adsp = 2;
2170 } else {
2171 dev_err(arizona->dev,
2172 "No suitable compressed stream for DAI '%s'\n",
2173 rtd->codec_dai->name);
2174 return -EINVAL;
2175 }
2176
2177 return wm_adsp_compr_open(&priv->core.adsp[n_adsp], stream);
2178}
2179
2001static int wm5110_codec_probe(struct snd_soc_codec *codec) 2180static int wm5110_codec_probe(struct snd_soc_codec *codec)
2002{ 2181{
2003 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2182 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
@@ -2088,6 +2267,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
2088 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), 2267 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
2089}; 2268};
2090 2269
2270static struct snd_compr_ops wm5110_compr_ops = {
2271 .open = wm5110_open,
2272 .free = wm_adsp_compr_free,
2273 .set_params = wm_adsp_compr_set_params,
2274 .get_caps = wm_adsp_compr_get_caps,
2275 .trigger = wm_adsp_compr_trigger,
2276};
2277
2278static struct snd_soc_platform_driver wm5110_compr_platform = {
2279 .compr_ops = &wm5110_compr_ops,
2280};
2281
2091static int wm5110_probe(struct platform_device *pdev) 2282static int wm5110_probe(struct platform_device *pdev)
2092{ 2283{
2093 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 2284 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -2148,8 +2339,21 @@ static int wm5110_probe(struct platform_device *pdev)
2148 pm_runtime_enable(&pdev->dev); 2339 pm_runtime_enable(&pdev->dev);
2149 pm_runtime_idle(&pdev->dev); 2340 pm_runtime_idle(&pdev->dev);
2150 2341
2151 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110, 2342 ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
2343 if (ret < 0) {
2344 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
2345 goto error;
2346 }
2347
2348 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
2152 wm5110_dai, ARRAY_SIZE(wm5110_dai)); 2349 wm5110_dai, ARRAY_SIZE(wm5110_dai));
2350 if (ret < 0) {
2351 dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
2352 snd_soc_unregister_platform(&pdev->dev);
2353 }
2354
2355error:
2356 return ret;
2153} 2357}
2154 2358
2155static int wm5110_remove(struct platform_device *pdev) 2359static int wm5110_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index e4cc41e6c23e..2ed6419c181e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1804,7 +1804,7 @@ static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1804 1804
1805 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg); 1805 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg);
1806 1806
1807 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; 1807 return !!((reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT);
1808} 1808}
1809 1809
1810static int wm8903_gpio_direction_out(struct gpio_chip *chip, 1810static int wm8903_gpio_direction_out(struct gpio_chip *chip,
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 2aa23f1b9e3c..8172e499e6ed 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -312,7 +312,7 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg)
312 case WM8904_FLL_NCO_TEST_1: 312 case WM8904_FLL_NCO_TEST_1:
313 return true; 313 return true;
314 default: 314 default:
315 return true; 315 return false;
316 } 316 }
317} 317}
318 318
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index a7e79784fc16..949f632fc3f8 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -131,7 +131,7 @@ static const struct reg_default wm8962_reg[] = {
131 { 15, 0x6243 }, /* R15 - Software Reset */ 131 { 15, 0x6243 }, /* R15 - Software Reset */
132 132
133 { 17, 0x007B }, /* R17 - ALC1 */ 133 { 17, 0x007B }, /* R17 - ALC1 */
134 134 { 18, 0x0000 }, /* R18 - ALC2 */
135 { 19, 0x1C32 }, /* R19 - ALC3 */ 135 { 19, 0x1C32 }, /* R19 - ALC3 */
136 { 20, 0x3200 }, /* R20 - Noise Gate */ 136 { 20, 0x3200 }, /* R20 - Noise Gate */
137 { 21, 0x00C0 }, /* R21 - Left ADC volume */ 137 { 21, 0x00C0 }, /* R21 - Left ADC volume */
@@ -794,7 +794,6 @@ static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
794 case WM8962_CLOCKING1: 794 case WM8962_CLOCKING1:
795 case WM8962_CLOCKING2: 795 case WM8962_CLOCKING2:
796 case WM8962_SOFTWARE_RESET: 796 case WM8962_SOFTWARE_RESET:
797 case WM8962_ALC2:
798 case WM8962_THERMAL_SHUTDOWN_STATUS: 797 case WM8962_THERMAL_SHUTDOWN_STATUS:
799 case WM8962_ADDITIONAL_CONTROL_4: 798 case WM8962_ADDITIONAL_CONTROL_4:
800 case WM8962_DC_SERVO_6: 799 case WM8962_DC_SERVO_6:
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 4c29bd2ae75c..c284c7b6db8b 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -632,9 +632,16 @@ static const struct i2c_device_id wm8974_i2c_id[] = {
632}; 632};
633MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id); 633MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
634 634
635static const struct of_device_id wm8974_of_match[] = {
636 { .compatible = "wlf,wm8974", },
637 { }
638};
639MODULE_DEVICE_TABLE(of, wm8974_of_match);
640
635static struct i2c_driver wm8974_i2c_driver = { 641static struct i2c_driver wm8974_i2c_driver = {
636 .driver = { 642 .driver = {
637 .name = "wm8974", 643 .name = "wm8974",
644 .of_match_table = wm8974_of_match,
638 }, 645 },
639 .probe = wm8974_i2c_probe, 646 .probe = wm8974_i2c_probe,
640 .remove = wm8974_i2c_remove, 647 .remove = wm8974_i2c_remove,
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 8782dfb628ab..7719bc509e50 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -199,20 +199,20 @@ static const char * const wm8998_inmux_texts[] = {
199 "B", 199 "B",
200}; 200};
201 201
202static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum, 202static SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum,
203 ARIZONA_ADC_DIGITAL_VOLUME_1L, 203 ARIZONA_ADC_DIGITAL_VOLUME_1L,
204 ARIZONA_IN1L_SRC_SHIFT, 204 ARIZONA_IN1L_SRC_SHIFT,
205 wm8998_inmux_texts); 205 wm8998_inmux_texts);
206 206
207static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum, 207static SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum,
208 ARIZONA_ADC_DIGITAL_VOLUME_1R, 208 ARIZONA_ADC_DIGITAL_VOLUME_1R,
209 ARIZONA_IN1R_SRC_SHIFT, 209 ARIZONA_IN1R_SRC_SHIFT,
210 wm8998_inmux_texts); 210 wm8998_inmux_texts);
211 211
212static const SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum, 212static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
213 ARIZONA_ADC_DIGITAL_VOLUME_2L, 213 ARIZONA_ADC_DIGITAL_VOLUME_2L,
214 ARIZONA_IN2L_SRC_SHIFT, 214 ARIZONA_IN2L_SRC_SHIFT,
215 wm8998_inmux_texts); 215 wm8998_inmux_texts);
216 216
217static const struct snd_kcontrol_new wm8998_in1mux[2] = { 217static const struct snd_kcontrol_new wm8998_in1mux[2] = {
218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum, 218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
@@ -522,17 +522,17 @@ static const unsigned int wm8998_aec_loopback_values[] = {
522 0, 1, 2, 3, 4, 6, 7, 8, 9, 522 0, 1, 2, 3, 4, 6, 7, 8, 9,
523}; 523};
524 524
525static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback, 525static SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback,
526 ARIZONA_DAC_AEC_CONTROL_1, 526 ARIZONA_DAC_AEC_CONTROL_1,
527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, 527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
528 wm8998_aec_loopback_texts, 528 wm8998_aec_loopback_texts,
529 wm8998_aec_loopback_values); 529 wm8998_aec_loopback_values);
530 530
531static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback, 531static SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback,
532 ARIZONA_DAC_AEC_CONTROL_2, 532 ARIZONA_DAC_AEC_CONTROL_2,
533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, 533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
534 wm8998_aec_loopback_texts, 534 wm8998_aec_loopback_texts,
535 wm8998_aec_loopback_values); 535 wm8998_aec_loopback_values);
536 536
537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = { 537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = {
538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback), 538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback),
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 4083a5130cbd..79e143625ac3 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -19,6 +19,7 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/regmap.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/ac97_codec.h> 25#include <sound/ac97_codec.h>
@@ -39,34 +40,6 @@ struct wm9713_priv {
39 struct mutex lock; 40 struct mutex lock;
40}; 41};
41 42
42static unsigned int ac97_read(struct snd_soc_codec *codec,
43 unsigned int reg);
44static int ac97_write(struct snd_soc_codec *codec,
45 unsigned int reg, unsigned int val);
46
47/*
48 * WM9713 register cache
49 * Reg 0x3c bit 15 is used by touch driver.
50 */
51static const u16 wm9713_reg[] = {
52 0x6174, 0x8080, 0x8080, 0x8080,
53 0xc880, 0xe808, 0xe808, 0x0808,
54 0x00da, 0x8000, 0xd600, 0xaaa0,
55 0xaaa0, 0xaaa0, 0x0000, 0x0000,
56 0x0f0f, 0x0040, 0x0000, 0x7f00,
57 0x0405, 0x0410, 0xbb80, 0xbb80,
58 0x0000, 0xbb80, 0x0000, 0x4523,
59 0x0000, 0x2000, 0x7eff, 0xffff,
60 0x0000, 0x0000, 0x0080, 0x0000,
61 0x0000, 0x0000, 0xfffe, 0xffff,
62 0x0000, 0x0000, 0x0000, 0xfffe,
63 0x4000, 0x0000, 0x0000, 0x0000,
64 0xb032, 0x3e00, 0x0000, 0x0000,
65 0x0000, 0x0000, 0x0000, 0x0000,
66 0x0000, 0x0000, 0x0000, 0x0006,
67 0x0001, 0x0000, 0x574d, 0x4c13,
68};
69
70#define HPL_MIXER 0 43#define HPL_MIXER 0
71#define HPR_MIXER 1 44#define HPR_MIXER 1
72 45
@@ -220,18 +193,15 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
220 struct snd_kcontrol *kcontrol, int event) 193 struct snd_kcontrol *kcontrol, int event)
221{ 194{
222 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 195 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
223 u16 status, rate;
224 196
225 if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD)) 197 if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
226 return -EINVAL; 198 return -EINVAL;
227 199
228 /* Gracefully shut down the voice interface. */ 200 /* Gracefully shut down the voice interface. */
229 status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000; 201 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0200);
230 rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF;
231 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200);
232 schedule_timeout_interruptible(msecs_to_jiffies(1)); 202 schedule_timeout_interruptible(msecs_to_jiffies(1));
233 ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); 203 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, 0x0f00);
234 ac97_write(codec, AC97_EXTENDED_MID, status); 204 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x1000, 0x1000);
235 205
236 return 0; 206 return 0;
237} 207}
@@ -674,39 +644,97 @@ static const struct snd_soc_dapm_route wm9713_audio_map[] = {
674 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
675}; 645};
676 646
677static unsigned int ac97_read(struct snd_soc_codec *codec, 647static bool wm9713_readable_reg(struct device *dev, unsigned int reg)
678 unsigned int reg)
679{ 648{
680 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 649 switch (reg) {
681 u16 *cache = codec->reg_cache; 650 case AC97_RESET ... AC97_PCM_SURR_DAC_RATE:
682 651 case AC97_PCM_LR_ADC_RATE:
683 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 652 case AC97_CENTER_LFE_MASTER:
684 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 653 case AC97_SPDIF ... AC97_LINE1_LEVEL:
685 reg == AC97_CD) 654 case AC97_GPIO_CFG ... 0x5c:
686 return soc_ac97_ops->read(wm9713->ac97, reg); 655 case AC97_CODEC_CLASS_REV ... AC97_PCI_SID:
687 else { 656 case 0x74 ... AC97_VENDOR_ID2:
688 reg = reg >> 1; 657 return true;
689 658 default:
690 if (reg >= (ARRAY_SIZE(wm9713_reg))) 659 return false;
691 return -EIO;
692
693 return cache[reg];
694 } 660 }
695} 661}
696 662
697static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 663static bool wm9713_writeable_reg(struct device *dev, unsigned int reg)
698 unsigned int val)
699{ 664{
700 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 665 switch (reg) {
666 case AC97_VENDOR_ID1:
667 case AC97_VENDOR_ID2:
668 return false;
669 default:
670 return wm9713_readable_reg(dev, reg);
671 }
672}
701 673
702 u16 *cache = codec->reg_cache; 674static const struct reg_default wm9713_reg_defaults[] = {
703 soc_ac97_ops->write(wm9713->ac97, reg, val); 675 { 0x02, 0x8080 }, /* Speaker Output Volume */
704 reg = reg >> 1; 676 { 0x04, 0x8080 }, /* Headphone Output Volume */
705 if (reg < (ARRAY_SIZE(wm9713_reg))) 677 { 0x06, 0x8080 }, /* Out3/OUT4 Volume */
706 cache[reg] = val; 678 { 0x08, 0xc880 }, /* Mono Volume */
679 { 0x0a, 0xe808 }, /* LINEIN Volume */
680 { 0x0c, 0xe808 }, /* DAC PGA Volume */
681 { 0x0e, 0x0808 }, /* MIC PGA Volume */
682 { 0x10, 0x00da }, /* MIC Routing Control */
683 { 0x12, 0x8000 }, /* Record PGA Volume */
684 { 0x14, 0xd600 }, /* Record Routing */
685 { 0x16, 0xaaa0 }, /* PCBEEP Volume */
686 { 0x18, 0xaaa0 }, /* VxDAC Volume */
687 { 0x1a, 0xaaa0 }, /* AUXDAC Volume */
688 { 0x1c, 0x0000 }, /* Output PGA Mux */
689 { 0x1e, 0x0000 }, /* DAC 3D control */
690 { 0x20, 0x0f0f }, /* DAC Tone Control*/
691 { 0x22, 0x0040 }, /* MIC Input Select & Bias */
692 { 0x24, 0x0000 }, /* Output Volume Mapping & Jack */
693 { 0x26, 0x7f00 }, /* Powerdown Ctrl/Stat*/
694 { 0x28, 0x0405 }, /* Extended Audio ID */
695 { 0x2a, 0x0410 }, /* Extended Audio Start/Ctrl */
696 { 0x2c, 0xbb80 }, /* Audio DACs Sample Rate */
697 { 0x2e, 0xbb80 }, /* AUXDAC Sample Rate */
698 { 0x32, 0xbb80 }, /* Audio ADCs Sample Rate */
699 { 0x36, 0x4523 }, /* PCM codec control */
700 { 0x3a, 0x2000 }, /* SPDIF control */
701 { 0x3c, 0xfdff }, /* Powerdown 1 */
702 { 0x3e, 0xffff }, /* Powerdown 2 */
703 { 0x40, 0x0000 }, /* General Purpose */
704 { 0x42, 0x0000 }, /* Fast Power-Up Control */
705 { 0x44, 0x0080 }, /* MCLK/PLL Control */
706 { 0x46, 0x0000 }, /* MCLK/PLL Control */
707 { 0x4c, 0xfffe }, /* GPIO Pin Configuration */
708 { 0x4e, 0xffff }, /* GPIO Pin Polarity / Type */
709 { 0x50, 0x0000 }, /* GPIO Pin Sticky */
710 { 0x52, 0x0000 }, /* GPIO Pin Wake-Up */
711 /* GPIO Pin Status */
712 { 0x56, 0xfffe }, /* GPIO Pin Sharing */
713 { 0x58, 0x4000 }, /* GPIO PullUp/PullDown */
714 { 0x5a, 0x0000 }, /* Additional Functions 1 */
715 { 0x5c, 0x0000 }, /* Additional Functions 2 */
716 { 0x60, 0xb032 }, /* ALC Control */
717 { 0x62, 0x3e00 }, /* ALC / Noise Gate Control */
718 { 0x64, 0x0000 }, /* AUXDAC input control */
719 { 0x74, 0x0000 }, /* Digitiser Reg 1 */
720 { 0x76, 0x0006 }, /* Digitiser Reg 2 */
721 { 0x78, 0x0001 }, /* Digitiser Reg 3 */
722 { 0x7a, 0x0000 }, /* Digitiser Read Back */
723};
707 724
708 return 0; 725static const struct regmap_config wm9713_regmap_config = {
709} 726 .reg_bits = 16,
727 .reg_stride = 2,
728 .val_bits = 16,
729 .max_register = 0x7e,
730 .cache_type = REGCACHE_RBTREE,
731
732 .reg_defaults = wm9713_reg_defaults,
733 .num_reg_defaults = ARRAY_SIZE(wm9713_reg_defaults),
734 .volatile_reg = regmap_ac97_default_volatile,
735 .readable_reg = wm9713_readable_reg,
736 .writeable_reg = wm9713_writeable_reg,
737};
710 738
711/* PLL divisors */ 739/* PLL divisors */
712struct _pll_div { 740struct _pll_div {
@@ -793,10 +821,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
793 /* turn PLL off ? */ 821 /* turn PLL off ? */
794 if (freq_in == 0) { 822 if (freq_in == 0) {
795 /* disable PLL power and select ext source */ 823 /* disable PLL power and select ext source */
796 reg = ac97_read(codec, AC97_HANDSET_RATE); 824 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0080);
797 ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080); 825 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0200);
798 reg = ac97_read(codec, AC97_EXTENDED_MID);
799 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200);
800 wm9713->pll_in = 0; 826 wm9713->pll_in = 0;
801 return 0; 827 return 0;
802 } 828 }
@@ -806,7 +832,7 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
806 if (pll_div.k == 0) { 832 if (pll_div.k == 0) {
807 reg = (pll_div.n << 12) | (pll_div.lf << 11) | 833 reg = (pll_div.n << 12) | (pll_div.lf << 11) |
808 (pll_div.divsel << 9) | (pll_div.divctl << 8); 834 (pll_div.divsel << 9) | (pll_div.divctl << 8);
809 ac97_write(codec, AC97_LINE1_LEVEL, reg); 835 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
810 } else { 836 } else {
811 /* write the fractional k to the reg 0x46 pages */ 837 /* write the fractional k to the reg 0x46 pages */
812 reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) | 838 reg2 = (pll_div.n << 12) | (pll_div.lf << 11) | (1 << 10) |
@@ -814,33 +840,31 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
814 840
815 /* K [21:20] */ 841 /* K [21:20] */
816 reg = reg2 | (0x5 << 4) | (pll_div.k >> 20); 842 reg = reg2 | (0x5 << 4) | (pll_div.k >> 20);
817 ac97_write(codec, AC97_LINE1_LEVEL, reg); 843 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
818 844
819 /* K [19:16] */ 845 /* K [19:16] */
820 reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf); 846 reg = reg2 | (0x4 << 4) | ((pll_div.k >> 16) & 0xf);
821 ac97_write(codec, AC97_LINE1_LEVEL, reg); 847 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
822 848
823 /* K [15:12] */ 849 /* K [15:12] */
824 reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf); 850 reg = reg2 | (0x3 << 4) | ((pll_div.k >> 12) & 0xf);
825 ac97_write(codec, AC97_LINE1_LEVEL, reg); 851 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
826 852
827 /* K [11:8] */ 853 /* K [11:8] */
828 reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf); 854 reg = reg2 | (0x2 << 4) | ((pll_div.k >> 8) & 0xf);
829 ac97_write(codec, AC97_LINE1_LEVEL, reg); 855 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
830 856
831 /* K [7:4] */ 857 /* K [7:4] */
832 reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf); 858 reg = reg2 | (0x1 << 4) | ((pll_div.k >> 4) & 0xf);
833 ac97_write(codec, AC97_LINE1_LEVEL, reg); 859 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
834 860
835 reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */ 861 reg = reg2 | (0x0 << 4) | (pll_div.k & 0xf); /* K [3:0] */
836 ac97_write(codec, AC97_LINE1_LEVEL, reg); 862 snd_soc_write(codec, AC97_LINE1_LEVEL, reg);
837 } 863 }
838 864
839 /* turn PLL on and select as source */ 865 /* turn PLL on and select as source */
840 reg = ac97_read(codec, AC97_EXTENDED_MID); 866 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x0200, 0x0000);
841 ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff); 867 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0080, 0x0000);
842 reg = ac97_read(codec, AC97_HANDSET_RATE);
843 ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f);
844 wm9713->pll_in = freq_in; 868 wm9713->pll_in = freq_in;
845 869
846 /* wait 10ms AC97 link frames for the link to stabilise */ 870 /* wait 10ms AC97 link frames for the link to stabilise */
@@ -863,10 +887,10 @@ static int wm9713_set_dai_tristate(struct snd_soc_dai *codec_dai,
863 int tristate) 887 int tristate)
864{ 888{
865 struct snd_soc_codec *codec = codec_dai->codec; 889 struct snd_soc_codec *codec = codec_dai->codec;
866 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0x9fff;
867 890
868 if (tristate) 891 if (tristate)
869 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg); 892 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
893 0x6000, 0x0000);
870 894
871 return 0; 895 return 0;
872} 896}
@@ -879,36 +903,30 @@ static int wm9713_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
879 int div_id, int div) 903 int div_id, int div)
880{ 904{
881 struct snd_soc_codec *codec = codec_dai->codec; 905 struct snd_soc_codec *codec = codec_dai->codec;
882 u16 reg;
883 906
884 switch (div_id) { 907 switch (div_id) {
885 case WM9713_PCMCLK_DIV: 908 case WM9713_PCMCLK_DIV:
886 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xf0ff; 909 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0f00, div);
887 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
888 break; 910 break;
889 case WM9713_CLKA_MULT: 911 case WM9713_CLKA_MULT:
890 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffd; 912 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0002, div);
891 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
892 break; 913 break;
893 case WM9713_CLKB_MULT: 914 case WM9713_CLKB_MULT:
894 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffb; 915 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x0004, div);
895 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
896 break; 916 break;
897 case WM9713_HIFI_DIV: 917 case WM9713_HIFI_DIV:
898 reg = ac97_read(codec, AC97_HANDSET_RATE) & 0x8fff; 918 snd_soc_update_bits(codec, AC97_HANDSET_RATE, 0x7000, div);
899 ac97_write(codec, AC97_HANDSET_RATE, reg | div);
900 break; 919 break;
901 case WM9713_PCMBCLK_DIV: 920 case WM9713_PCMBCLK_DIV:
902 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xf1ff; 921 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER, 0x0e00, div);
903 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg | div);
904 break; 922 break;
905 case WM9713_PCMCLK_PLL_DIV: 923 case WM9713_PCMCLK_PLL_DIV:
906 reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80; 924 snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
907 ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x60 | div); 925 0x007f, div | 0x60);
908 break; 926 break;
909 case WM9713_HIFI_PLL_DIV: 927 case WM9713_HIFI_PLL_DIV:
910 reg = ac97_read(codec, AC97_LINE1_LEVEL) & 0xff80; 928 snd_soc_update_bits(codec, AC97_LINE1_LEVEL,
911 ac97_write(codec, AC97_LINE1_LEVEL, reg | 0x70 | div); 929 0x007f, div | 0x70);
912 break; 930 break;
913 default: 931 default:
914 return -EINVAL; 932 return -EINVAL;
@@ -921,7 +939,7 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
921 unsigned int fmt) 939 unsigned int fmt)
922{ 940{
923 struct snd_soc_codec *codec = codec_dai->codec; 941 struct snd_soc_codec *codec = codec_dai->codec;
924 u16 gpio = ac97_read(codec, AC97_GPIO_CFG) & 0xffc5; 942 u16 gpio = snd_soc_read(codec, AC97_GPIO_CFG) & 0xffc5;
925 u16 reg = 0x8000; 943 u16 reg = 0x8000;
926 944
927 /* clock masters */ 945 /* clock masters */
@@ -974,8 +992,8 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
974 break; 992 break;
975 } 993 }
976 994
977 ac97_write(codec, AC97_GPIO_CFG, gpio); 995 snd_soc_write(codec, AC97_GPIO_CFG, gpio);
978 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg); 996 snd_soc_write(codec, AC97_CENTER_LFE_MASTER, reg);
979 return 0; 997 return 0;
980} 998}
981 999
@@ -984,24 +1002,24 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
984 struct snd_soc_dai *dai) 1002 struct snd_soc_dai *dai)
985{ 1003{
986 struct snd_soc_codec *codec = dai->codec; 1004 struct snd_soc_codec *codec = dai->codec;
987 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
988 1005
1006 /* enable PCM interface in master mode */
989 switch (params_width(params)) { 1007 switch (params_width(params)) {
990 case 16: 1008 case 16:
991 break; 1009 break;
992 case 20: 1010 case 20:
993 reg |= 0x0004; 1011 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1012 0x000c, 0x0004);
994 break; 1013 break;
995 case 24: 1014 case 24:
996 reg |= 0x0008; 1015 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1016 0x000c, 0x0008);
997 break; 1017 break;
998 case 32: 1018 case 32:
999 reg |= 0x000c; 1019 snd_soc_update_bits(codec, AC97_CENTER_LFE_MASTER,
1020 0x000c, 0x000c);
1000 break; 1021 break;
1001 } 1022 }
1002
1003 /* enable PCM interface in master mode */
1004 ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
1005 return 0; 1023 return 0;
1006} 1024}
1007 1025
@@ -1011,17 +1029,15 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
1011 struct snd_soc_codec *codec = dai->codec; 1029 struct snd_soc_codec *codec = dai->codec;
1012 struct snd_pcm_runtime *runtime = substream->runtime; 1030 struct snd_pcm_runtime *runtime = substream->runtime;
1013 int reg; 1031 int reg;
1014 u16 vra;
1015 1032
1016 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 1033 snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1017 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
1018 1034
1019 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1035 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1020 reg = AC97_PCM_FRONT_DAC_RATE; 1036 reg = AC97_PCM_FRONT_DAC_RATE;
1021 else 1037 else
1022 reg = AC97_PCM_LR_ADC_RATE; 1038 reg = AC97_PCM_LR_ADC_RATE;
1023 1039
1024 return ac97_write(codec, reg, runtime->rate); 1040 return snd_soc_write(codec, reg, runtime->rate);
1025} 1041}
1026 1042
1027static int ac97_aux_prepare(struct snd_pcm_substream *substream, 1043static int ac97_aux_prepare(struct snd_pcm_substream *substream,
@@ -1029,17 +1045,14 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
1029{ 1045{
1030 struct snd_soc_codec *codec = dai->codec; 1046 struct snd_soc_codec *codec = dai->codec;
1031 struct snd_pcm_runtime *runtime = substream->runtime; 1047 struct snd_pcm_runtime *runtime = substream->runtime;
1032 u16 vra, xsle;
1033 1048
1034 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 1049 snd_soc_update_bits(codec, AC97_EXTENDED_STATUS, 0x0001, 0x0001);
1035 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); 1050 snd_soc_update_bits(codec, AC97_PCI_SID, 0x8000, 0x8000);
1036 xsle = ac97_read(codec, AC97_PCI_SID);
1037 ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
1038 1051
1039 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 1052 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
1040 return -ENODEV; 1053 return -ENODEV;
1041 1054
1042 return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate); 1055 return snd_soc_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
1043} 1056}
1044 1057
1045#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \ 1058#define WM9713_RATES (SNDRV_PCM_RATE_8000 | \
@@ -1128,27 +1141,23 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1128static int wm9713_set_bias_level(struct snd_soc_codec *codec, 1141static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1129 enum snd_soc_bias_level level) 1142 enum snd_soc_bias_level level)
1130{ 1143{
1131 u16 reg;
1132
1133 switch (level) { 1144 switch (level) {
1134 case SND_SOC_BIAS_ON: 1145 case SND_SOC_BIAS_ON:
1135 /* enable thermal shutdown */ 1146 /* enable thermal shutdown */
1136 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff; 1147 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xe400, 0x0000);
1137 ac97_write(codec, AC97_EXTENDED_MID, reg);
1138 break; 1148 break;
1139 case SND_SOC_BIAS_PREPARE: 1149 case SND_SOC_BIAS_PREPARE:
1140 break; 1150 break;
1141 case SND_SOC_BIAS_STANDBY: 1151 case SND_SOC_BIAS_STANDBY:
1142 /* enable master bias and vmid */ 1152 /* enable master bias and vmid */
1143 reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff; 1153 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0xc400, 0x0000);
1144 ac97_write(codec, AC97_EXTENDED_MID, reg); 1154 snd_soc_write(codec, AC97_POWERDOWN, 0x0000);
1145 ac97_write(codec, AC97_POWERDOWN, 0x0000);
1146 break; 1155 break;
1147 case SND_SOC_BIAS_OFF: 1156 case SND_SOC_BIAS_OFF:
1148 /* disable everything including AC link */ 1157 /* disable everything including AC link */
1149 ac97_write(codec, AC97_EXTENDED_MID, 0xffff); 1158 snd_soc_write(codec, AC97_EXTENDED_MID, 0xffff);
1150 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 1159 snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
1151 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1160 snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
1152 break; 1161 break;
1153 } 1162 }
1154 return 0; 1163 return 0;
@@ -1156,16 +1165,14 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1156 1165
1157static int wm9713_soc_suspend(struct snd_soc_codec *codec) 1166static int wm9713_soc_suspend(struct snd_soc_codec *codec)
1158{ 1167{
1159 u16 reg;
1160
1161 /* Disable everything except touchpanel - that will be handled 1168 /* Disable everything except touchpanel - that will be handled
1162 * by the touch driver and left disabled if touch is not in 1169 * by the touch driver and left disabled if touch is not in
1163 * use. */ 1170 * use. */
1164 reg = ac97_read(codec, AC97_EXTENDED_MID); 1171 snd_soc_update_bits(codec, AC97_EXTENDED_MID, 0x7fff,
1165 ac97_write(codec, AC97_EXTENDED_MID, reg | 0x7fff); 1172 0x7fff);
1166 ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff); 1173 snd_soc_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
1167 ac97_write(codec, AC97_POWERDOWN, 0x6f00); 1174 snd_soc_write(codec, AC97_POWERDOWN, 0x6f00);
1168 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1175 snd_soc_write(codec, AC97_POWERDOWN, 0xffff);
1169 1176
1170 return 0; 1177 return 0;
1171} 1178}
@@ -1173,8 +1180,7 @@ static int wm9713_soc_suspend(struct snd_soc_codec *codec)
1173static int wm9713_soc_resume(struct snd_soc_codec *codec) 1180static int wm9713_soc_resume(struct snd_soc_codec *codec)
1174{ 1181{
1175 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1182 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1176 int i, ret; 1183 int ret;
1177 u16 *cache = codec->reg_cache;
1178 1184
1179 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID, 1185 ret = snd_ac97_reset(wm9713->ac97, true, WM9713_VENDOR_ID,
1180 WM9713_VENDOR_ID_MASK); 1186 WM9713_VENDOR_ID_MASK);
@@ -1189,12 +1195,8 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1189 1195
1190 /* only synchronise the codec if warm reset failed */ 1196 /* only synchronise the codec if warm reset failed */
1191 if (ret == 0) { 1197 if (ret == 0) {
1192 for (i = 2; i < ARRAY_SIZE(wm9713_reg) << 1; i += 2) { 1198 regcache_mark_dirty(codec->component.regmap);
1193 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1199 snd_soc_cache_sync(codec);
1194 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1195 continue;
1196 soc_ac97_ops->write(wm9713->ac97, i, cache[i>>1]);
1197 }
1198 } 1200 }
1199 1201
1200 return ret; 1202 return ret;
@@ -1203,16 +1205,23 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1203static int wm9713_soc_probe(struct snd_soc_codec *codec) 1205static int wm9713_soc_probe(struct snd_soc_codec *codec)
1204{ 1206{
1205 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1207 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1206 int reg; 1208 struct regmap *regmap;
1207 1209
1208 wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID, 1210 wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
1209 WM9713_VENDOR_ID_MASK); 1211 WM9713_VENDOR_ID_MASK);
1210 if (IS_ERR(wm9713->ac97)) 1212 if (IS_ERR(wm9713->ac97))
1211 return PTR_ERR(wm9713->ac97); 1213 return PTR_ERR(wm9713->ac97);
1212 1214
1215 regmap = devm_regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
1216 if (IS_ERR(regmap)) {
1217 snd_soc_free_ac97_codec(wm9713->ac97);
1218 return PTR_ERR(regmap);
1219 }
1220
1221 snd_soc_codec_init_regmap(codec, regmap);
1222
1213 /* unmute the adc - move to kcontrol */ 1223 /* unmute the adc - move to kcontrol */
1214 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1224 snd_soc_update_bits(codec, AC97_CD, 0x7fff, 0x0000);
1215 ac97_write(codec, AC97_CD, reg);
1216 1225
1217 return 0; 1226 return 0;
1218} 1227}
@@ -1221,6 +1230,7 @@ static int wm9713_soc_remove(struct snd_soc_codec *codec)
1221{ 1230{
1222 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1231 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1223 1232
1233 snd_soc_codec_exit_regmap(codec);
1224 snd_soc_free_ac97_codec(wm9713->ac97); 1234 snd_soc_free_ac97_codec(wm9713->ac97);
1225 return 0; 1235 return 0;
1226} 1236}
@@ -1230,13 +1240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1230 .remove = wm9713_soc_remove, 1240 .remove = wm9713_soc_remove,
1231 .suspend = wm9713_soc_suspend, 1241 .suspend = wm9713_soc_suspend,
1232 .resume = wm9713_soc_resume, 1242 .resume = wm9713_soc_resume,
1233 .read = ac97_read,
1234 .write = ac97_write,
1235 .set_bias_level = wm9713_set_bias_level, 1243 .set_bias_level = wm9713_set_bias_level,
1236 .reg_cache_size = ARRAY_SIZE(wm9713_reg),
1237 .reg_word_size = sizeof(u16),
1238 .reg_cache_step = 2,
1239 .reg_cache_default = wm9713_reg,
1240 1244
1241 .controls = wm9713_snd_ac97_controls, 1245 .controls = wm9713_snd_ac97_controls,
1242 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls), 1246 .num_controls = ARRAY_SIZE(wm9713_snd_ac97_controls),
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 0bb415a28723..ac879d16c6a6 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -201,27 +201,186 @@ static void wm_adsp_buf_free(struct list_head *list)
201 } 201 }
202} 202}
203 203
204#define WM_ADSP_NUM_FW 4 204#define WM_ADSP_FW_MBC_VSS 0
205 205#define WM_ADSP_FW_HIFI 1
206#define WM_ADSP_FW_MBC_VSS 0 206#define WM_ADSP_FW_TX 2
207#define WM_ADSP_FW_TX 1 207#define WM_ADSP_FW_TX_SPK 3
208#define WM_ADSP_FW_TX_SPK 2 208#define WM_ADSP_FW_RX 4
209#define WM_ADSP_FW_RX_ANC 3 209#define WM_ADSP_FW_RX_ANC 5
210#define WM_ADSP_FW_CTRL 6
211#define WM_ADSP_FW_ASR 7
212#define WM_ADSP_FW_TRACE 8
213#define WM_ADSP_FW_SPK_PROT 9
214#define WM_ADSP_FW_MISC 10
215
216#define WM_ADSP_NUM_FW 11
210 217
211static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { 218static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
212 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", 219 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS",
213 [WM_ADSP_FW_TX] = "Tx", 220 [WM_ADSP_FW_HIFI] = "MasterHiFi",
214 [WM_ADSP_FW_TX_SPK] = "Tx Speaker", 221 [WM_ADSP_FW_TX] = "Tx",
215 [WM_ADSP_FW_RX_ANC] = "Rx ANC", 222 [WM_ADSP_FW_TX_SPK] = "Tx Speaker",
223 [WM_ADSP_FW_RX] = "Rx",
224 [WM_ADSP_FW_RX_ANC] = "Rx ANC",
225 [WM_ADSP_FW_CTRL] = "Voice Ctrl",
226 [WM_ADSP_FW_ASR] = "ASR Assist",
227 [WM_ADSP_FW_TRACE] = "Dbg Trace",
228 [WM_ADSP_FW_SPK_PROT] = "Protection",
229 [WM_ADSP_FW_MISC] = "Misc",
230};
231
232struct wm_adsp_system_config_xm_hdr {
233 __be32 sys_enable;
234 __be32 fw_id;
235 __be32 fw_rev;
236 __be32 boot_status;
237 __be32 watchdog;
238 __be32 dma_buffer_size;
239 __be32 rdma[6];
240 __be32 wdma[8];
241 __be32 build_job_name[3];
242 __be32 build_job_number;
243};
244
245struct wm_adsp_alg_xm_struct {
246 __be32 magic;
247 __be32 smoothing;
248 __be32 threshold;
249 __be32 host_buf_ptr;
250 __be32 start_seq;
251 __be32 high_water_mark;
252 __be32 low_water_mark;
253 __be64 smoothed_power;
254};
255
256struct wm_adsp_buffer {
257 __be32 X_buf_base; /* XM base addr of first X area */
258 __be32 X_buf_size; /* Size of 1st X area in words */
259 __be32 X_buf_base2; /* XM base addr of 2nd X area */
260 __be32 X_buf_brk; /* Total X size in words */
261 __be32 Y_buf_base; /* YM base addr of Y area */
262 __be32 wrap; /* Total size X and Y in words */
263 __be32 high_water_mark; /* Point at which IRQ is asserted */
264 __be32 irq_count; /* bits 1-31 count IRQ assertions */
265 __be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */
266 __be32 next_write_index; /* word index of next write */
267 __be32 next_read_index; /* word index of next read */
268 __be32 error; /* error if any */
269 __be32 oldest_block_index; /* word index of oldest surviving */
270 __be32 requested_rewind; /* how many blocks rewind was done */
271 __be32 reserved_space; /* internal */
272 __be32 min_free; /* min free space since stream start */
273 __be32 blocks_written[2]; /* total blocks written (64 bit) */
274 __be32 words_written[2]; /* total words written (64 bit) */
275};
276
277struct wm_adsp_compr_buf {
278 struct wm_adsp *dsp;
279
280 struct wm_adsp_buffer_region *regions;
281 u32 host_buf_ptr;
282};
283
284struct wm_adsp_compr {
285 struct wm_adsp *dsp;
286 struct wm_adsp_compr_buf *buf;
287
288 struct snd_compr_stream *stream;
289 struct snd_compressed_buffer size;
290};
291
292#define WM_ADSP_DATA_WORD_SIZE 3
293
294#define WM_ADSP_MIN_FRAGMENTS 1
295#define WM_ADSP_MAX_FRAGMENTS 256
296#define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE)
297#define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE)
298
299#define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7
300
301#define HOST_BUFFER_FIELD(field) \
302 (offsetof(struct wm_adsp_buffer, field) / sizeof(__be32))
303
304#define ALG_XM_FIELD(field) \
305 (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32))
306
307static int wm_adsp_buffer_init(struct wm_adsp *dsp);
308static int wm_adsp_buffer_free(struct wm_adsp *dsp);
309
310struct wm_adsp_buffer_region {
311 unsigned int offset;
312 unsigned int cumulative_size;
313 unsigned int mem_type;
314 unsigned int base_addr;
315};
316
317struct wm_adsp_buffer_region_def {
318 unsigned int mem_type;
319 unsigned int base_offset;
320 unsigned int size_offset;
321};
322
323static struct wm_adsp_buffer_region_def ez2control_regions[] = {
324 {
325 .mem_type = WMFW_ADSP2_XM,
326 .base_offset = HOST_BUFFER_FIELD(X_buf_base),
327 .size_offset = HOST_BUFFER_FIELD(X_buf_size),
328 },
329 {
330 .mem_type = WMFW_ADSP2_XM,
331 .base_offset = HOST_BUFFER_FIELD(X_buf_base2),
332 .size_offset = HOST_BUFFER_FIELD(X_buf_brk),
333 },
334 {
335 .mem_type = WMFW_ADSP2_YM,
336 .base_offset = HOST_BUFFER_FIELD(Y_buf_base),
337 .size_offset = HOST_BUFFER_FIELD(wrap),
338 },
339};
340
341struct wm_adsp_fw_caps {
342 u32 id;
343 struct snd_codec_desc desc;
344 int num_regions;
345 struct wm_adsp_buffer_region_def *region_defs;
346};
347
348static const struct wm_adsp_fw_caps ez2control_caps[] = {
349 {
350 .id = SND_AUDIOCODEC_BESPOKE,
351 .desc = {
352 .max_ch = 1,
353 .sample_rates = { 16000 },
354 .num_sample_rates = 1,
355 .formats = SNDRV_PCM_FMTBIT_S16_LE,
356 },
357 .num_regions = ARRAY_SIZE(ez2control_regions),
358 .region_defs = ez2control_regions,
359 },
216}; 360};
217 361
218static struct { 362static const struct {
219 const char *file; 363 const char *file;
364 int compr_direction;
365 int num_caps;
366 const struct wm_adsp_fw_caps *caps;
220} wm_adsp_fw[WM_ADSP_NUM_FW] = { 367} wm_adsp_fw[WM_ADSP_NUM_FW] = {
221 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, 368 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" },
222 [WM_ADSP_FW_TX] = { .file = "tx" }, 369 [WM_ADSP_FW_HIFI] = { .file = "hifi" },
223 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, 370 [WM_ADSP_FW_TX] = { .file = "tx" },
224 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 371 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" },
372 [WM_ADSP_FW_RX] = { .file = "rx" },
373 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
374 [WM_ADSP_FW_CTRL] = {
375 .file = "ctrl",
376 .compr_direction = SND_COMPRESS_CAPTURE,
377 .num_caps = ARRAY_SIZE(ez2control_caps),
378 .caps = ez2control_caps,
379 },
380 [WM_ADSP_FW_ASR] = { .file = "asr" },
381 [WM_ADSP_FW_TRACE] = { .file = "trace" },
382 [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },
383 [WM_ADSP_FW_MISC] = { .file = "misc" },
225}; 384};
226 385
227struct wm_coeff_ctl_ops { 386struct wm_coeff_ctl_ops {
@@ -254,30 +413,24 @@ static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
254{ 413{
255 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 414 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
256 415
257 mutex_lock(&dsp->debugfs_lock);
258 kfree(dsp->wmfw_file_name); 416 kfree(dsp->wmfw_file_name);
259 dsp->wmfw_file_name = tmp; 417 dsp->wmfw_file_name = tmp;
260 mutex_unlock(&dsp->debugfs_lock);
261} 418}
262 419
263static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) 420static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
264{ 421{
265 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 422 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
266 423
267 mutex_lock(&dsp->debugfs_lock);
268 kfree(dsp->bin_file_name); 424 kfree(dsp->bin_file_name);
269 dsp->bin_file_name = tmp; 425 dsp->bin_file_name = tmp;
270 mutex_unlock(&dsp->debugfs_lock);
271} 426}
272 427
273static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) 428static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
274{ 429{
275 mutex_lock(&dsp->debugfs_lock);
276 kfree(dsp->wmfw_file_name); 430 kfree(dsp->wmfw_file_name);
277 kfree(dsp->bin_file_name); 431 kfree(dsp->bin_file_name);
278 dsp->wmfw_file_name = NULL; 432 dsp->wmfw_file_name = NULL;
279 dsp->bin_file_name = NULL; 433 dsp->bin_file_name = NULL;
280 mutex_unlock(&dsp->debugfs_lock);
281} 434}
282 435
283static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, 436static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
@@ -287,7 +440,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
287 struct wm_adsp *dsp = file->private_data; 440 struct wm_adsp *dsp = file->private_data;
288 ssize_t ret; 441 ssize_t ret;
289 442
290 mutex_lock(&dsp->debugfs_lock); 443 mutex_lock(&dsp->pwr_lock);
291 444
292 if (!dsp->wmfw_file_name || !dsp->running) 445 if (!dsp->wmfw_file_name || !dsp->running)
293 ret = 0; 446 ret = 0;
@@ -296,7 +449,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
296 dsp->wmfw_file_name, 449 dsp->wmfw_file_name,
297 strlen(dsp->wmfw_file_name)); 450 strlen(dsp->wmfw_file_name));
298 451
299 mutex_unlock(&dsp->debugfs_lock); 452 mutex_unlock(&dsp->pwr_lock);
300 return ret; 453 return ret;
301} 454}
302 455
@@ -307,7 +460,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
307 struct wm_adsp *dsp = file->private_data; 460 struct wm_adsp *dsp = file->private_data;
308 ssize_t ret; 461 ssize_t ret;
309 462
310 mutex_lock(&dsp->debugfs_lock); 463 mutex_lock(&dsp->pwr_lock);
311 464
312 if (!dsp->bin_file_name || !dsp->running) 465 if (!dsp->bin_file_name || !dsp->running)
313 ret = 0; 466 ret = 0;
@@ -316,7 +469,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
316 dsp->bin_file_name, 469 dsp->bin_file_name,
317 strlen(dsp->bin_file_name)); 470 strlen(dsp->bin_file_name));
318 471
319 mutex_unlock(&dsp->debugfs_lock); 472 mutex_unlock(&dsp->pwr_lock);
320 return ret; 473 return ret;
321} 474}
322 475
@@ -436,6 +589,7 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
436 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 589 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
437 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 590 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
438 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 591 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
592 int ret = 0;
439 593
440 if (ucontrol->value.integer.value[0] == dsp[e->shift_l].fw) 594 if (ucontrol->value.integer.value[0] == dsp[e->shift_l].fw)
441 return 0; 595 return 0;
@@ -443,12 +597,16 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
443 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW) 597 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW)
444 return -EINVAL; 598 return -EINVAL;
445 599
446 if (dsp[e->shift_l].running) 600 mutex_lock(&dsp[e->shift_l].pwr_lock);
447 return -EBUSY;
448 601
449 dsp[e->shift_l].fw = ucontrol->value.integer.value[0]; 602 if (dsp[e->shift_l].running || dsp[e->shift_l].compr)
603 ret = -EBUSY;
604 else
605 dsp[e->shift_l].fw = ucontrol->value.integer.value[0];
450 606
451 return 0; 607 mutex_unlock(&dsp[e->shift_l].pwr_lock);
608
609 return ret;
452} 610}
453 611
454static const struct soc_enum wm_adsp_fw_enum[] = { 612static const struct soc_enum wm_adsp_fw_enum[] = {
@@ -523,10 +681,10 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
523 be16_to_cpu(scratch[3])); 681 be16_to_cpu(scratch[3]));
524} 682}
525 683
526static int wm_coeff_info(struct snd_kcontrol *kcontrol, 684static int wm_coeff_info(struct snd_kcontrol *kctl,
527 struct snd_ctl_elem_info *uinfo) 685 struct snd_ctl_elem_info *uinfo)
528{ 686{
529 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 687 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
530 688
531 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 689 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
532 uinfo->count = ctl->len; 690 uinfo->count = ctl->len;
@@ -572,19 +730,24 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
572 return 0; 730 return 0;
573} 731}
574 732
575static int wm_coeff_put(struct snd_kcontrol *kcontrol, 733static int wm_coeff_put(struct snd_kcontrol *kctl,
576 struct snd_ctl_elem_value *ucontrol) 734 struct snd_ctl_elem_value *ucontrol)
577{ 735{
578 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 736 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
579 char *p = ucontrol->value.bytes.data; 737 char *p = ucontrol->value.bytes.data;
738 int ret = 0;
739
740 mutex_lock(&ctl->dsp->pwr_lock);
580 741
581 memcpy(ctl->cache, p, ctl->len); 742 memcpy(ctl->cache, p, ctl->len);
582 743
583 ctl->set = 1; 744 ctl->set = 1;
584 if (!ctl->enabled) 745 if (ctl->enabled)
585 return 0; 746 ret = wm_coeff_write_control(ctl, p, ctl->len);
747
748 mutex_unlock(&ctl->dsp->pwr_lock);
586 749
587 return wm_coeff_write_control(ctl, p, ctl->len); 750 return ret;
588} 751}
589 752
590static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, 753static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
@@ -626,22 +789,30 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
626 return 0; 789 return 0;
627} 790}
628 791
629static int wm_coeff_get(struct snd_kcontrol *kcontrol, 792static int wm_coeff_get(struct snd_kcontrol *kctl,
630 struct snd_ctl_elem_value *ucontrol) 793 struct snd_ctl_elem_value *ucontrol)
631{ 794{
632 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 795 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kctl->private_value;
633 char *p = ucontrol->value.bytes.data; 796 char *p = ucontrol->value.bytes.data;
797 int ret = 0;
798
799 mutex_lock(&ctl->dsp->pwr_lock);
634 800
635 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 801 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
636 if (ctl->enabled) 802 if (ctl->enabled)
637 return wm_coeff_read_control(ctl, p, ctl->len); 803 ret = wm_coeff_read_control(ctl, p, ctl->len);
638 else 804 else
639 return -EPERM; 805 ret = -EPERM;
806 } else {
807 if (!ctl->flags && ctl->enabled)
808 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
809
810 memcpy(p, ctl->cache, ctl->len);
640 } 811 }
641 812
642 memcpy(p, ctl->cache, ctl->len); 813 mutex_unlock(&ctl->dsp->pwr_lock);
643 814
644 return 0; 815 return ret;
645} 816}
646 817
647struct wmfw_ctl_work { 818struct wmfw_ctl_work {
@@ -808,8 +979,7 @@ static int wm_adsp_create_control(struct wm_adsp *dsp,
808 break; 979 break;
809 } 980 }
810 981
811 list_for_each_entry(ctl, &dsp->ctl_list, 982 list_for_each_entry(ctl, &dsp->ctl_list, list) {
812 list) {
813 if (!strcmp(ctl->name, name)) { 983 if (!strcmp(ctl->name, name)) {
814 if (!ctl->enabled) 984 if (!ctl->enabled)
815 ctl->enabled = 1; 985 ctl->enabled = 1;
@@ -1088,7 +1258,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1088 goto out_fw; 1258 goto out_fw;
1089 } 1259 }
1090 1260
1091 header = (void*)&firmware->data[0]; 1261 header = (void *)&firmware->data[0];
1092 1262
1093 if (memcmp(&header->magic[0], "WMFW", 4) != 0) { 1263 if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
1094 adsp_err(dsp, "%s: invalid magic\n", file); 1264 adsp_err(dsp, "%s: invalid magic\n", file);
@@ -1168,7 +1338,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1168 offset = le32_to_cpu(region->offset) & 0xffffff; 1338 offset = le32_to_cpu(region->offset) & 0xffffff;
1169 type = be32_to_cpu(region->type) & 0xff; 1339 type = be32_to_cpu(region->type) & 0xff;
1170 mem = wm_adsp_find_region(dsp, type); 1340 mem = wm_adsp_find_region(dsp, type);
1171 1341
1172 switch (type) { 1342 switch (type) {
1173 case WMFW_NAME_TEXT: 1343 case WMFW_NAME_TEXT:
1174 region_name = "Firmware name"; 1344 region_name = "Firmware name";
@@ -1333,6 +1503,19 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
1333 return alg; 1503 return alg;
1334} 1504}
1335 1505
1506static struct wm_adsp_alg_region *
1507 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id)
1508{
1509 struct wm_adsp_alg_region *alg_region;
1510
1511 list_for_each_entry(alg_region, &dsp->alg_regions, list) {
1512 if (id == alg_region->alg && type == alg_region->type)
1513 return alg_region;
1514 }
1515
1516 return NULL;
1517}
1518
1336static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, 1519static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp,
1337 int type, __be32 id, 1520 int type, __be32 id,
1338 __be32 base) 1521 __be32 base)
@@ -1625,7 +1808,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1625 goto out_fw; 1808 goto out_fw;
1626 } 1809 }
1627 1810
1628 hdr = (void*)&firmware->data[0]; 1811 hdr = (void *)&firmware->data[0];
1629 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 1812 if (memcmp(hdr->magic, "WMDR", 4) != 0) {
1630 adsp_err(dsp, "%s: invalid magic\n", file); 1813 adsp_err(dsp, "%s: invalid magic\n", file);
1631 goto out_fw; 1814 goto out_fw;
@@ -1651,7 +1834,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1651 blocks = 0; 1834 blocks = 0;
1652 while (pos < firmware->size && 1835 while (pos < firmware->size &&
1653 pos - firmware->size > sizeof(*blk)) { 1836 pos - firmware->size > sizeof(*blk)) {
1654 blk = (void*)(&firmware->data[pos]); 1837 blk = (void *)(&firmware->data[pos]);
1655 1838
1656 type = le16_to_cpu(blk->type); 1839 type = le16_to_cpu(blk->type);
1657 offset = le16_to_cpu(blk->offset); 1840 offset = le16_to_cpu(blk->offset);
@@ -1705,22 +1888,16 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1705 break; 1888 break;
1706 } 1889 }
1707 1890
1708 reg = 0; 1891 alg_region = wm_adsp_find_alg_region(dsp, type,
1709 list_for_each_entry(alg_region, 1892 le32_to_cpu(blk->id));
1710 &dsp->alg_regions, list) { 1893 if (alg_region) {
1711 if (le32_to_cpu(blk->id) == alg_region->alg && 1894 reg = alg_region->base;
1712 type == alg_region->type) { 1895 reg = wm_adsp_region_to_reg(mem, reg);
1713 reg = alg_region->base; 1896 reg += offset;
1714 reg = wm_adsp_region_to_reg(mem, 1897 } else {
1715 reg);
1716 reg += offset;
1717 break;
1718 }
1719 }
1720
1721 if (reg == 0)
1722 adsp_err(dsp, "No %x for algorithm %x\n", 1898 adsp_err(dsp, "No %x for algorithm %x\n",
1723 type, le32_to_cpu(blk->id)); 1899 type, le32_to_cpu(blk->id));
1900 }
1724 break; 1901 break;
1725 1902
1726 default: 1903 default:
@@ -1778,9 +1955,8 @@ int wm_adsp1_init(struct wm_adsp *dsp)
1778{ 1955{
1779 INIT_LIST_HEAD(&dsp->alg_regions); 1956 INIT_LIST_HEAD(&dsp->alg_regions);
1780 1957
1781#ifdef CONFIG_DEBUG_FS 1958 mutex_init(&dsp->pwr_lock);
1782 mutex_init(&dsp->debugfs_lock); 1959
1783#endif
1784 return 0; 1960 return 0;
1785} 1961}
1786EXPORT_SYMBOL_GPL(wm_adsp1_init); 1962EXPORT_SYMBOL_GPL(wm_adsp1_init);
@@ -1795,10 +1971,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1795 struct wm_adsp_alg_region *alg_region; 1971 struct wm_adsp_alg_region *alg_region;
1796 struct wm_coeff_ctl *ctl; 1972 struct wm_coeff_ctl *ctl;
1797 int ret; 1973 int ret;
1798 int val; 1974 unsigned int val;
1799 1975
1800 dsp->card = codec->component.card; 1976 dsp->card = codec->component.card;
1801 1977
1978 mutex_lock(&dsp->pwr_lock);
1979
1802 switch (event) { 1980 switch (event) {
1803 case SND_SOC_DAPM_POST_PMU: 1981 case SND_SOC_DAPM_POST_PMU:
1804 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1982 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1808,12 +1986,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1808 * For simplicity set the DSP clock rate to be the 1986 * For simplicity set the DSP clock rate to be the
1809 * SYSCLK rate rather than making it configurable. 1987 * SYSCLK rate rather than making it configurable.
1810 */ 1988 */
1811 if(dsp->sysclk_reg) { 1989 if (dsp->sysclk_reg) {
1812 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 1990 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
1813 if (ret != 0) { 1991 if (ret != 0) {
1814 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 1992 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1815 ret); 1993 ret);
1816 return ret; 1994 goto err_mutex;
1817 } 1995 }
1818 1996
1819 val = (val & dsp->sysclk_mask) 1997 val = (val & dsp->sysclk_mask)
@@ -1825,31 +2003,31 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1825 if (ret != 0) { 2003 if (ret != 0) {
1826 adsp_err(dsp, "Failed to set clock rate: %d\n", 2004 adsp_err(dsp, "Failed to set clock rate: %d\n",
1827 ret); 2005 ret);
1828 return ret; 2006 goto err_mutex;
1829 } 2007 }
1830 } 2008 }
1831 2009
1832 ret = wm_adsp_load(dsp); 2010 ret = wm_adsp_load(dsp);
1833 if (ret != 0) 2011 if (ret != 0)
1834 goto err; 2012 goto err_ena;
1835 2013
1836 ret = wm_adsp1_setup_algs(dsp); 2014 ret = wm_adsp1_setup_algs(dsp);
1837 if (ret != 0) 2015 if (ret != 0)
1838 goto err; 2016 goto err_ena;
1839 2017
1840 ret = wm_adsp_load_coeff(dsp); 2018 ret = wm_adsp_load_coeff(dsp);
1841 if (ret != 0) 2019 if (ret != 0)
1842 goto err; 2020 goto err_ena;
1843 2021
1844 /* Initialize caches for enabled and unset controls */ 2022 /* Initialize caches for enabled and unset controls */
1845 ret = wm_coeff_init_control_caches(dsp); 2023 ret = wm_coeff_init_control_caches(dsp);
1846 if (ret != 0) 2024 if (ret != 0)
1847 goto err; 2025 goto err_ena;
1848 2026
1849 /* Sync set controls */ 2027 /* Sync set controls */
1850 ret = wm_coeff_sync_controls(dsp); 2028 ret = wm_coeff_sync_controls(dsp);
1851 if (ret != 0) 2029 if (ret != 0)
1852 goto err; 2030 goto err_ena;
1853 2031
1854 /* Start the core running */ 2032 /* Start the core running */
1855 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2033 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1884,11 +2062,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1884 break; 2062 break;
1885 } 2063 }
1886 2064
2065 mutex_unlock(&dsp->pwr_lock);
2066
1887 return 0; 2067 return 0;
1888 2068
1889err: 2069err_ena:
1890 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2070 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1891 ADSP1_SYS_ENA, 0); 2071 ADSP1_SYS_ENA, 0);
2072err_mutex:
2073 mutex_unlock(&dsp->pwr_lock);
2074
1892 return ret; 2075 return ret;
1893} 2076}
1894EXPORT_SYMBOL_GPL(wm_adsp1_event); 2077EXPORT_SYMBOL_GPL(wm_adsp1_event);
@@ -1934,6 +2117,8 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1934 int ret; 2117 int ret;
1935 unsigned int val; 2118 unsigned int val;
1936 2119
2120 mutex_lock(&dsp->pwr_lock);
2121
1937 /* 2122 /*
1938 * For simplicity set the DSP clock rate to be the 2123 * For simplicity set the DSP clock rate to be the
1939 * SYSCLK rate rather than making it configurable. 2124 * SYSCLK rate rather than making it configurable.
@@ -1941,7 +2126,7 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1941 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); 2126 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1942 if (ret != 0) { 2127 if (ret != 0) {
1943 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); 2128 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
1944 return; 2129 goto err_mutex;
1945 } 2130 }
1946 val = (val & ARIZONA_SYSCLK_FREQ_MASK) 2131 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1947 >> ARIZONA_SYSCLK_FREQ_SHIFT; 2132 >> ARIZONA_SYSCLK_FREQ_SHIFT;
@@ -1951,42 +2136,46 @@ static void wm_adsp2_boot_work(struct work_struct *work)
1951 ADSP2_CLK_SEL_MASK, val); 2136 ADSP2_CLK_SEL_MASK, val);
1952 if (ret != 0) { 2137 if (ret != 0) {
1953 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2138 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
1954 return; 2139 goto err_mutex;
1955 } 2140 }
1956 2141
1957 ret = wm_adsp2_ena(dsp); 2142 ret = wm_adsp2_ena(dsp);
1958 if (ret != 0) 2143 if (ret != 0)
1959 return; 2144 goto err_mutex;
1960 2145
1961 ret = wm_adsp_load(dsp); 2146 ret = wm_adsp_load(dsp);
1962 if (ret != 0) 2147 if (ret != 0)
1963 goto err; 2148 goto err_ena;
1964 2149
1965 ret = wm_adsp2_setup_algs(dsp); 2150 ret = wm_adsp2_setup_algs(dsp);
1966 if (ret != 0) 2151 if (ret != 0)
1967 goto err; 2152 goto err_ena;
1968 2153
1969 ret = wm_adsp_load_coeff(dsp); 2154 ret = wm_adsp_load_coeff(dsp);
1970 if (ret != 0) 2155 if (ret != 0)
1971 goto err; 2156 goto err_ena;
1972 2157
1973 /* Initialize caches for enabled and unset controls */ 2158 /* Initialize caches for enabled and unset controls */
1974 ret = wm_coeff_init_control_caches(dsp); 2159 ret = wm_coeff_init_control_caches(dsp);
1975 if (ret != 0) 2160 if (ret != 0)
1976 goto err; 2161 goto err_ena;
1977 2162
1978 /* Sync set controls */ 2163 /* Sync set controls */
1979 ret = wm_coeff_sync_controls(dsp); 2164 ret = wm_coeff_sync_controls(dsp);
1980 if (ret != 0) 2165 if (ret != 0)
1981 goto err; 2166 goto err_ena;
1982 2167
1983 dsp->running = true; 2168 dsp->running = true;
1984 2169
2170 mutex_unlock(&dsp->pwr_lock);
2171
1985 return; 2172 return;
1986 2173
1987err: 2174err_ena:
1988 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2175 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1989 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2176 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
2177err_mutex:
2178 mutex_unlock(&dsp->pwr_lock);
1990} 2179}
1991 2180
1992int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2181int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
@@ -2033,12 +2222,18 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2033 ADSP2_CORE_ENA | ADSP2_START); 2222 ADSP2_CORE_ENA | ADSP2_START);
2034 if (ret != 0) 2223 if (ret != 0)
2035 goto err; 2224 goto err;
2225
2226 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2227 ret = wm_adsp_buffer_init(dsp);
2228
2036 break; 2229 break;
2037 2230
2038 case SND_SOC_DAPM_PRE_PMD: 2231 case SND_SOC_DAPM_PRE_PMD:
2039 /* Log firmware state, it can be useful for analysis */ 2232 /* Log firmware state, it can be useful for analysis */
2040 wm_adsp2_show_fw_status(dsp); 2233 wm_adsp2_show_fw_status(dsp);
2041 2234
2235 mutex_lock(&dsp->pwr_lock);
2236
2042 wm_adsp_debugfs_clear(dsp); 2237 wm_adsp_debugfs_clear(dsp);
2043 2238
2044 dsp->fw_id = 0; 2239 dsp->fw_id = 0;
@@ -2065,6 +2260,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2065 kfree(alg_region); 2260 kfree(alg_region);
2066 } 2261 }
2067 2262
2263 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2264 wm_adsp_buffer_free(dsp);
2265
2266 mutex_unlock(&dsp->pwr_lock);
2267
2068 adsp_dbg(dsp, "Shutdown complete\n"); 2268 adsp_dbg(dsp, "Shutdown complete\n");
2069 break; 2269 break;
2070 2270
@@ -2117,11 +2317,406 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2117 INIT_LIST_HEAD(&dsp->ctl_list); 2317 INIT_LIST_HEAD(&dsp->ctl_list);
2118 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2318 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
2119 2319
2120#ifdef CONFIG_DEBUG_FS 2320 mutex_init(&dsp->pwr_lock);
2121 mutex_init(&dsp->debugfs_lock); 2321
2122#endif
2123 return 0; 2322 return 0;
2124} 2323}
2125EXPORT_SYMBOL_GPL(wm_adsp2_init); 2324EXPORT_SYMBOL_GPL(wm_adsp2_init);
2126 2325
2326int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream)
2327{
2328 struct wm_adsp_compr *compr;
2329 int ret = 0;
2330
2331 mutex_lock(&dsp->pwr_lock);
2332
2333 if (wm_adsp_fw[dsp->fw].num_caps == 0) {
2334 adsp_err(dsp, "Firmware does not support compressed API\n");
2335 ret = -ENXIO;
2336 goto out;
2337 }
2338
2339 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) {
2340 adsp_err(dsp, "Firmware does not support stream direction\n");
2341 ret = -EINVAL;
2342 goto out;
2343 }
2344
2345 if (dsp->compr) {
2346 /* It is expect this limitation will be removed in future */
2347 adsp_err(dsp, "Only a single stream supported per DSP\n");
2348 ret = -EBUSY;
2349 goto out;
2350 }
2351
2352 compr = kzalloc(sizeof(*compr), GFP_KERNEL);
2353 if (!compr) {
2354 ret = -ENOMEM;
2355 goto out;
2356 }
2357
2358 compr->dsp = dsp;
2359 compr->stream = stream;
2360
2361 dsp->compr = compr;
2362
2363 stream->runtime->private_data = compr;
2364
2365out:
2366 mutex_unlock(&dsp->pwr_lock);
2367
2368 return ret;
2369}
2370EXPORT_SYMBOL_GPL(wm_adsp_compr_open);
2371
2372int wm_adsp_compr_free(struct snd_compr_stream *stream)
2373{
2374 struct wm_adsp_compr *compr = stream->runtime->private_data;
2375 struct wm_adsp *dsp = compr->dsp;
2376
2377 mutex_lock(&dsp->pwr_lock);
2378
2379 dsp->compr = NULL;
2380
2381 kfree(compr);
2382
2383 mutex_unlock(&dsp->pwr_lock);
2384
2385 return 0;
2386}
2387EXPORT_SYMBOL_GPL(wm_adsp_compr_free);
2388
2389static int wm_adsp_compr_check_params(struct snd_compr_stream *stream,
2390 struct snd_compr_params *params)
2391{
2392 struct wm_adsp_compr *compr = stream->runtime->private_data;
2393 struct wm_adsp *dsp = compr->dsp;
2394 const struct wm_adsp_fw_caps *caps;
2395 const struct snd_codec_desc *desc;
2396 int i, j;
2397
2398 if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE ||
2399 params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE ||
2400 params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS ||
2401 params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS ||
2402 params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) {
2403 adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n",
2404 params->buffer.fragment_size,
2405 params->buffer.fragments);
2406
2407 return -EINVAL;
2408 }
2409
2410 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) {
2411 caps = &wm_adsp_fw[dsp->fw].caps[i];
2412 desc = &caps->desc;
2413
2414 if (caps->id != params->codec.id)
2415 continue;
2416
2417 if (stream->direction == SND_COMPRESS_PLAYBACK) {
2418 if (desc->max_ch < params->codec.ch_out)
2419 continue;
2420 } else {
2421 if (desc->max_ch < params->codec.ch_in)
2422 continue;
2423 }
2424
2425 if (!(desc->formats & (1 << params->codec.format)))
2426 continue;
2427
2428 for (j = 0; j < desc->num_sample_rates; ++j)
2429 if (desc->sample_rates[j] == params->codec.sample_rate)
2430 return 0;
2431 }
2432
2433 adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n",
2434 params->codec.id, params->codec.ch_in, params->codec.ch_out,
2435 params->codec.sample_rate, params->codec.format);
2436 return -EINVAL;
2437}
2438
2439int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
2440 struct snd_compr_params *params)
2441{
2442 struct wm_adsp_compr *compr = stream->runtime->private_data;
2443 int ret;
2444
2445 ret = wm_adsp_compr_check_params(stream, params);
2446 if (ret)
2447 return ret;
2448
2449 compr->size = params->buffer;
2450
2451 adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n",
2452 compr->size.fragment_size, compr->size.fragments);
2453
2454 return 0;
2455}
2456EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);
2457
2458int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
2459 struct snd_compr_caps *caps)
2460{
2461 struct wm_adsp_compr *compr = stream->runtime->private_data;
2462 int fw = compr->dsp->fw;
2463 int i;
2464
2465 if (wm_adsp_fw[fw].caps) {
2466 for (i = 0; i < wm_adsp_fw[fw].num_caps; i++)
2467 caps->codecs[i] = wm_adsp_fw[fw].caps[i].id;
2468
2469 caps->num_codecs = i;
2470 caps->direction = wm_adsp_fw[fw].compr_direction;
2471
2472 caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE;
2473 caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE;
2474 caps->min_fragments = WM_ADSP_MIN_FRAGMENTS;
2475 caps->max_fragments = WM_ADSP_MAX_FRAGMENTS;
2476 }
2477
2478 return 0;
2479}
2480EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps);
2481
2482static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
2483 unsigned int mem_addr,
2484 unsigned int num_words, u32 *data)
2485{
2486 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2487 unsigned int i, reg;
2488 int ret;
2489
2490 if (!mem)
2491 return -EINVAL;
2492
2493 reg = wm_adsp_region_to_reg(mem, mem_addr);
2494
2495 ret = regmap_raw_read(dsp->regmap, reg, data,
2496 sizeof(*data) * num_words);
2497 if (ret < 0)
2498 return ret;
2499
2500 for (i = 0; i < num_words; ++i)
2501 data[i] = be32_to_cpu(data[i]) & 0x00ffffffu;
2502
2503 return 0;
2504}
2505
2506static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type,
2507 unsigned int mem_addr, u32 *data)
2508{
2509 return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data);
2510}
2511
2512static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type,
2513 unsigned int mem_addr, u32 data)
2514{
2515 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
2516 unsigned int reg;
2517
2518 if (!mem)
2519 return -EINVAL;
2520
2521 reg = wm_adsp_region_to_reg(mem, mem_addr);
2522
2523 data = cpu_to_be32(data & 0x00ffffffu);
2524
2525 return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data));
2526}
2527
2528static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf,
2529 unsigned int field_offset, u32 *data)
2530{
2531 return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM,
2532 buf->host_buf_ptr + field_offset, data);
2533}
2534
2535static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf,
2536 unsigned int field_offset, u32 data)
2537{
2538 return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM,
2539 buf->host_buf_ptr + field_offset, data);
2540}
2541
2542static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf)
2543{
2544 struct wm_adsp_alg_region *alg_region;
2545 struct wm_adsp *dsp = buf->dsp;
2546 u32 xmalg, addr, magic;
2547 int i, ret;
2548
2549 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
2550 xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32);
2551
2552 addr = alg_region->base + xmalg + ALG_XM_FIELD(magic);
2553 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic);
2554 if (ret < 0)
2555 return ret;
2556
2557 if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC)
2558 return -EINVAL;
2559
2560 addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr);
2561 for (i = 0; i < 5; ++i) {
2562 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr,
2563 &buf->host_buf_ptr);
2564 if (ret < 0)
2565 return ret;
2566
2567 if (buf->host_buf_ptr)
2568 break;
2569
2570 usleep_range(1000, 2000);
2571 }
2572
2573 if (!buf->host_buf_ptr)
2574 return -EIO;
2575
2576 adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr);
2577
2578 return 0;
2579}
2580
2581static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
2582{
2583 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps;
2584 struct wm_adsp_buffer_region *region;
2585 u32 offset = 0;
2586 int i, ret;
2587
2588 for (i = 0; i < caps->num_regions; ++i) {
2589 region = &buf->regions[i];
2590
2591 region->offset = offset;
2592 region->mem_type = caps->region_defs[i].mem_type;
2593
2594 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
2595 &region->base_addr);
2596 if (ret < 0)
2597 return ret;
2598
2599 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
2600 &offset);
2601 if (ret < 0)
2602 return ret;
2603
2604 region->cumulative_size = offset;
2605
2606 adsp_dbg(buf->dsp,
2607 "region=%d type=%d base=%04x off=%04x size=%04x\n",
2608 i, region->mem_type, region->base_addr,
2609 region->offset, region->cumulative_size);
2610 }
2611
2612 return 0;
2613}
2614
2615static int wm_adsp_buffer_init(struct wm_adsp *dsp)
2616{
2617 struct wm_adsp_compr_buf *buf;
2618 int ret;
2619
2620 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
2621 if (!buf)
2622 return -ENOMEM;
2623
2624 buf->dsp = dsp;
2625
2626 ret = wm_adsp_buffer_locate(buf);
2627 if (ret < 0) {
2628 adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret);
2629 goto err_buffer;
2630 }
2631
2632 buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions,
2633 sizeof(*buf->regions), GFP_KERNEL);
2634 if (!buf->regions) {
2635 ret = -ENOMEM;
2636 goto err_buffer;
2637 }
2638
2639 ret = wm_adsp_buffer_populate(buf);
2640 if (ret < 0) {
2641 adsp_err(dsp, "Failed to populate host buffer: %d\n", ret);
2642 goto err_regions;
2643 }
2644
2645 dsp->buffer = buf;
2646
2647 return 0;
2648
2649err_regions:
2650 kfree(buf->regions);
2651err_buffer:
2652 kfree(buf);
2653 return ret;
2654}
2655
2656static int wm_adsp_buffer_free(struct wm_adsp *dsp)
2657{
2658 if (dsp->buffer) {
2659 kfree(dsp->buffer->regions);
2660 kfree(dsp->buffer);
2661
2662 dsp->buffer = NULL;
2663 }
2664
2665 return 0;
2666}
2667
2668static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr)
2669{
2670 return compr->buf != NULL;
2671}
2672
2673static int wm_adsp_compr_attach(struct wm_adsp_compr *compr)
2674{
2675 /*
2676 * Note this will be more complex once each DSP can support multiple
2677 * streams
2678 */
2679 if (!compr->dsp->buffer)
2680 return -EINVAL;
2681
2682 compr->buf = compr->dsp->buffer;
2683
2684 return 0;
2685}
2686
2687int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
2688{
2689 struct wm_adsp_compr *compr = stream->runtime->private_data;
2690 struct wm_adsp *dsp = compr->dsp;
2691 int ret = 0;
2692
2693 adsp_dbg(dsp, "Trigger: %d\n", cmd);
2694
2695 mutex_lock(&dsp->pwr_lock);
2696
2697 switch (cmd) {
2698 case SNDRV_PCM_TRIGGER_START:
2699 if (wm_adsp_compr_attached(compr))
2700 break;
2701
2702 ret = wm_adsp_compr_attach(compr);
2703 if (ret < 0) {
2704 adsp_err(dsp, "Failed to link buffer and stream: %d\n",
2705 ret);
2706 break;
2707 }
2708 break;
2709 case SNDRV_PCM_TRIGGER_STOP:
2710 break;
2711 default:
2712 ret = -EINVAL;
2713 break;
2714 }
2715
2716 mutex_unlock(&dsp->pwr_lock);
2717
2718 return ret;
2719}
2720EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger);
2721
2127MODULE_LICENSE("GPL v2"); 2722MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 2d117cf0e953..43af093fafcf 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -15,6 +15,7 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/soc-dapm.h> 17#include <sound/soc-dapm.h>
18#include <sound/compress_driver.h>
18 19
19#include "wmfw.h" 20#include "wmfw.h"
20 21
@@ -30,6 +31,9 @@ struct wm_adsp_alg_region {
30 unsigned int base; 31 unsigned int base;
31}; 32};
32 33
34struct wm_adsp_compr;
35struct wm_adsp_compr_buf;
36
33struct wm_adsp { 37struct wm_adsp {
34 const char *part; 38 const char *part;
35 int num; 39 int num;
@@ -45,8 +49,8 @@ struct wm_adsp {
45 49
46 struct list_head alg_regions; 50 struct list_head alg_regions;
47 51
48 int fw_id; 52 unsigned int fw_id;
49 int fw_id_version; 53 unsigned int fw_id_version;
50 54
51 const struct wm_adsp_region *mem; 55 const struct wm_adsp_region *mem;
52 int num_mems; 56 int num_mems;
@@ -59,9 +63,13 @@ struct wm_adsp {
59 63
60 struct work_struct boot_work; 64 struct work_struct boot_work;
61 65
66 struct wm_adsp_compr *compr;
67 struct wm_adsp_compr_buf *buffer;
68
69 struct mutex pwr_lock;
70
62#ifdef CONFIG_DEBUG_FS 71#ifdef CONFIG_DEBUG_FS
63 struct dentry *debugfs_root; 72 struct dentry *debugfs_root;
64 struct mutex debugfs_lock;
65 char *wmfw_file_name; 73 char *wmfw_file_name;
66 char *bin_file_name; 74 char *bin_file_name;
67#endif 75#endif
@@ -96,4 +104,13 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
96int wm_adsp2_event(struct snd_soc_dapm_widget *w, 104int wm_adsp2_event(struct snd_soc_dapm_widget *w,
97 struct snd_kcontrol *kcontrol, int event); 105 struct snd_kcontrol *kcontrol, int event);
98 106
107extern int wm_adsp_compr_open(struct wm_adsp *dsp,
108 struct snd_compr_stream *stream);
109extern int wm_adsp_compr_free(struct snd_compr_stream *stream);
110extern int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
111 struct snd_compr_params *params);
112extern int wm_adsp_compr_get_caps(struct snd_compr_stream *stream,
113 struct snd_compr_caps *caps);
114extern int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd);
115
99#endif 116#endif
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 6e6a70c5c2bd..825a1f480aab 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/pm_runtime.h>
21#include <sound/designware_i2s.h> 22#include <sound/designware_i2s.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -93,7 +94,12 @@ struct dw_i2s_dev {
93 struct clk *clk; 94 struct clk *clk;
94 int active; 95 int active;
95 unsigned int capability; 96 unsigned int capability;
97 unsigned int quirks;
98 unsigned int i2s_reg_comp1;
99 unsigned int i2s_reg_comp2;
96 struct device *dev; 100 struct device *dev;
101 u32 ccr;
102 u32 xfer_resolution;
97 103
98 /* data related to DMA transfers b/w i2s and DMAC */ 104 /* data related to DMA transfers b/w i2s and DMAC */
99 union dw_i2s_snd_dma_data play_dma_data; 105 union dw_i2s_snd_dma_data play_dma_data;
@@ -213,31 +219,58 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream,
213 return 0; 219 return 0;
214} 220}
215 221
222static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
223{
224 u32 ch_reg, irq;
225 struct i2s_clk_config_data *config = &dev->config;
226
227
228 i2s_disable_channels(dev, stream);
229
230 for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) {
231 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
232 i2s_write_reg(dev->i2s_base, TCR(ch_reg),
233 dev->xfer_resolution);
234 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
235 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
236 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
237 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
238 } else {
239 i2s_write_reg(dev->i2s_base, RCR(ch_reg),
240 dev->xfer_resolution);
241 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
242 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
243 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
244 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
245 }
246
247 }
248}
249
216static int dw_i2s_hw_params(struct snd_pcm_substream *substream, 250static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
217 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 251 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
218{ 252{
219 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 253 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
220 struct i2s_clk_config_data *config = &dev->config; 254 struct i2s_clk_config_data *config = &dev->config;
221 u32 ccr, xfer_resolution, ch_reg, irq;
222 int ret; 255 int ret;
223 256
224 switch (params_format(params)) { 257 switch (params_format(params)) {
225 case SNDRV_PCM_FORMAT_S16_LE: 258 case SNDRV_PCM_FORMAT_S16_LE:
226 config->data_width = 16; 259 config->data_width = 16;
227 ccr = 0x00; 260 dev->ccr = 0x00;
228 xfer_resolution = 0x02; 261 dev->xfer_resolution = 0x02;
229 break; 262 break;
230 263
231 case SNDRV_PCM_FORMAT_S24_LE: 264 case SNDRV_PCM_FORMAT_S24_LE:
232 config->data_width = 24; 265 config->data_width = 24;
233 ccr = 0x08; 266 dev->ccr = 0x08;
234 xfer_resolution = 0x04; 267 dev->xfer_resolution = 0x04;
235 break; 268 break;
236 269
237 case SNDRV_PCM_FORMAT_S32_LE: 270 case SNDRV_PCM_FORMAT_S32_LE:
238 config->data_width = 32; 271 config->data_width = 32;
239 ccr = 0x10; 272 dev->ccr = 0x10;
240 xfer_resolution = 0x05; 273 dev->xfer_resolution = 0x05;
241 break; 274 break;
242 275
243 default: 276 default:
@@ -258,27 +291,9 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
258 return -EINVAL; 291 return -EINVAL;
259 } 292 }
260 293
261 i2s_disable_channels(dev, substream->stream); 294 dw_i2s_config(dev, substream->stream);
262 295
263 for (ch_reg = 0; ch_reg < (config->chan_nr / 2); ch_reg++) { 296 i2s_write_reg(dev->i2s_base, CCR, dev->ccr);
264 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
265 i2s_write_reg(dev->i2s_base, TCR(ch_reg),
266 xfer_resolution);
267 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
268 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
269 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
270 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
271 } else {
272 i2s_write_reg(dev->i2s_base, RCR(ch_reg),
273 xfer_resolution);
274 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
275 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
276 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
277 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
278 }
279 }
280
281 i2s_write_reg(dev->i2s_base, CCR, ccr);
282 297
283 config->sample_rate = params_rate(params); 298 config->sample_rate = params_rate(params);
284 299
@@ -394,6 +409,23 @@ static const struct snd_soc_component_driver dw_i2s_component = {
394}; 409};
395 410
396#ifdef CONFIG_PM 411#ifdef CONFIG_PM
412static int dw_i2s_runtime_suspend(struct device *dev)
413{
414 struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
415
416 if (dw_dev->capability & DW_I2S_MASTER)
417 clk_disable(dw_dev->clk);
418 return 0;
419}
420
421static int dw_i2s_runtime_resume(struct device *dev)
422{
423 struct dw_i2s_dev *dw_dev = dev_get_drvdata(dev);
424
425 if (dw_dev->capability & DW_I2S_MASTER)
426 clk_enable(dw_dev->clk);
427 return 0;
428}
397 429
398static int dw_i2s_suspend(struct snd_soc_dai *dai) 430static int dw_i2s_suspend(struct snd_soc_dai *dai)
399{ 431{
@@ -410,6 +442,11 @@ static int dw_i2s_resume(struct snd_soc_dai *dai)
410 442
411 if (dev->capability & DW_I2S_MASTER) 443 if (dev->capability & DW_I2S_MASTER)
412 clk_enable(dev->clk); 444 clk_enable(dev->clk);
445
446 if (dai->playback_active)
447 dw_i2s_config(dev, SNDRV_PCM_STREAM_PLAYBACK);
448 if (dai->capture_active)
449 dw_i2s_config(dev, SNDRV_PCM_STREAM_CAPTURE);
413 return 0; 450 return 0;
414} 451}
415 452
@@ -459,8 +496,8 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
459 * Read component parameter registers to extract 496 * Read component parameter registers to extract
460 * the I2S block's configuration. 497 * the I2S block's configuration.
461 */ 498 */
462 u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); 499 u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
463 u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); 500 u32 comp2 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp2);
464 u32 idx; 501 u32 idx;
465 502
466 if (COMP1_TX_ENABLED(comp1)) { 503 if (COMP1_TX_ENABLED(comp1)) {
@@ -503,7 +540,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev,
503 struct resource *res, 540 struct resource *res,
504 const struct i2s_platform_data *pdata) 541 const struct i2s_platform_data *pdata)
505{ 542{
506 u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); 543 u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
507 u32 idx = COMP1_APB_DATA_WIDTH(comp1); 544 u32 idx = COMP1_APB_DATA_WIDTH(comp1);
508 int ret; 545 int ret;
509 546
@@ -607,6 +644,14 @@ static int dw_i2s_probe(struct platform_device *pdev)
607 if (pdata) { 644 if (pdata) {
608 dev->capability = pdata->cap; 645 dev->capability = pdata->cap;
609 clk_id = NULL; 646 clk_id = NULL;
647 dev->quirks = pdata->quirks;
648 if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
649 dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
650 dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
651 } else {
652 dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
653 dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
654 }
610 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); 655 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
611 } else { 656 } else {
612 clk_id = "i2sclk"; 657 clk_id = "i2sclk";
@@ -649,7 +694,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
649 goto err_clk_disable; 694 goto err_clk_disable;
650 } 695 }
651 } 696 }
652 697 pm_runtime_enable(&pdev->dev);
653 return 0; 698 return 0;
654 699
655err_clk_disable: 700err_clk_disable:
@@ -665,6 +710,7 @@ static int dw_i2s_remove(struct platform_device *pdev)
665 if (dev->capability & DW_I2S_MASTER) 710 if (dev->capability & DW_I2S_MASTER)
666 clk_disable_unprepare(dev->clk); 711 clk_disable_unprepare(dev->clk);
667 712
713 pm_runtime_disable(&pdev->dev);
668 return 0; 714 return 0;
669} 715}
670 716
@@ -677,12 +723,17 @@ static const struct of_device_id dw_i2s_of_match[] = {
677MODULE_DEVICE_TABLE(of, dw_i2s_of_match); 723MODULE_DEVICE_TABLE(of, dw_i2s_of_match);
678#endif 724#endif
679 725
726static const struct dev_pm_ops dwc_pm_ops = {
727 SET_RUNTIME_PM_OPS(dw_i2s_runtime_suspend, dw_i2s_runtime_resume, NULL)
728};
729
680static struct platform_driver dw_i2s_driver = { 730static struct platform_driver dw_i2s_driver = {
681 .probe = dw_i2s_probe, 731 .probe = dw_i2s_probe,
682 .remove = dw_i2s_remove, 732 .remove = dw_i2s_remove,
683 .driver = { 733 .driver = {
684 .name = "designware-i2s", 734 .name = "designware-i2s",
685 .of_match_table = of_match_ptr(dw_i2s_of_match), 735 .of_match_table = of_match_ptr(dw_i2s_of_match),
736 .pm = &dwc_pm_ops,
686 }, 737 },
687}; 738};
688 739
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 1b05d1c5d9fd..562b3bd22d9a 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -107,6 +107,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
107 {"CPU-Capture", NULL, "Capture"}, 107 {"CPU-Capture", NULL, "Capture"},
108}; 108};
109 109
110static const struct snd_soc_dapm_route audio_map_ac97[] = {
111 {"AC97 Playback", NULL, "ASRC-Playback"},
112 {"Playback", NULL, "AC97 Playback"},
113 {"ASRC-Capture", NULL, "AC97 Capture"},
114 {"AC97 Capture", NULL, "Capture"},
115};
116
110/* Add all possible widgets into here without being redundant */ 117/* Add all possible widgets into here without being redundant */
111static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = { 118static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
112 SND_SOC_DAPM_LINE("Line Out Jack", NULL), 119 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -222,12 +229,15 @@ static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card,
222 enum snd_soc_bias_level level) 229 enum snd_soc_bias_level level)
223{ 230{
224 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 231 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
225 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 232 struct snd_soc_pcm_runtime *rtd;
233 struct snd_soc_dai *codec_dai;
226 struct codec_priv *codec_priv = &priv->codec_priv; 234 struct codec_priv *codec_priv = &priv->codec_priv;
227 struct device *dev = card->dev; 235 struct device *dev = card->dev;
228 unsigned int pll_out; 236 unsigned int pll_out;
229 int ret; 237 int ret;
230 238
239 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
240 codec_dai = rtd->codec_dai;
231 if (dapm->dev != codec_dai->dev) 241 if (dapm->dev != codec_dai->dev)
232 return 0; 242 return 0;
233 243
@@ -414,14 +424,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
414static int fsl_asoc_card_late_probe(struct snd_soc_card *card) 424static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
415{ 425{
416 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); 426 struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
417 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 427 struct snd_soc_pcm_runtime *rtd = list_first_entry(
428 &card->rtd_list, struct snd_soc_pcm_runtime, list);
429 struct snd_soc_dai *codec_dai = rtd->codec_dai;
418 struct codec_priv *codec_priv = &priv->codec_priv; 430 struct codec_priv *codec_priv = &priv->codec_priv;
419 struct device *dev = card->dev; 431 struct device *dev = card->dev;
420 int ret; 432 int ret;
421 433
422 if (fsl_asoc_card_is_ac97(priv)) { 434 if (fsl_asoc_card_is_ac97(priv)) {
423#if IS_ENABLED(CONFIG_SND_AC97_CODEC) 435#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
424 struct snd_soc_codec *codec = card->rtd[0].codec; 436 struct snd_soc_codec *codec = rtd->codec;
425 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); 437 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
426 438
427 /* 439 /*
@@ -574,7 +586,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
574 priv->card.dev = &pdev->dev; 586 priv->card.dev = &pdev->dev;
575 priv->card.name = priv->name; 587 priv->card.name = priv->name;
576 priv->card.dai_link = priv->dai_link; 588 priv->card.dai_link = priv->dai_link;
577 priv->card.dapm_routes = audio_map; 589 priv->card.dapm_routes = fsl_asoc_card_is_ac97(priv) ?
590 audio_map_ac97 : audio_map;
578 priv->card.late_probe = fsl_asoc_card_late_probe; 591 priv->card.late_probe = fsl_asoc_card_late_probe;
579 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); 592 priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
580 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets; 593 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 9f087d4f73ed..dd1263b95dc7 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -31,21 +31,21 @@
31 dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) 31 dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
32 32
33/* Sample rates are aligned with that defined in pcm.h file */ 33/* Sample rates are aligned with that defined in pcm.h file */
34static const u8 process_option[][8][2] = { 34static const u8 process_option[][12][2] = {
35 /* 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */ 35 /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
36 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */ 36 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
37 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */ 37 {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
38 {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */ 38 {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
39 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */ 39 {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
40 {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */ 40 {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
41 {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */ 41 {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
42 {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */ 42 {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
43 {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */ 43 {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
44 {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */ 44 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
45 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */ 45 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
46 {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */ 46 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
47 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */ 47 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
48 {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */ 48 {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
49}; 49};
50 50
51/* Corresponding to process_option */ 51/* Corresponding to process_option */
@@ -55,7 +55,7 @@ static int supported_input_rate[] = {
55}; 55};
56 56
57static int supported_asrc_rate[] = { 57static int supported_asrc_rate[] = {
58 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, 58 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
59}; 59};
60 60
61/** 61/**
@@ -286,6 +286,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
286 return -EINVAL; 286 return -EINVAL;
287 } 287 }
288 288
289 if ((outrate > 8000 && outrate < 30000) &&
290 (outrate/inrate > 24 || inrate/outrate > 8)) {
291 pair_err("exceed supported ratio range [1/24, 8] for \
292 inrate/outrate: %d/%d\n", inrate, outrate);
293 return -EINVAL;
294 }
295
289 /* Validate input and output clock sources */ 296 /* Validate input and output clock sources */
290 clk_index[IN] = clk_map[IN][config->inclk]; 297 clk_index[IN] = clk_map[IN][config->inclk];
291 clk_index[OUT] = clk_map[OUT][config->outclk]; 298 clk_index[OUT] = clk_map[OUT][config->outclk];
@@ -447,7 +454,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
447 struct snd_soc_dai *dai) 454 struct snd_soc_dai *dai)
448{ 455{
449 struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai); 456 struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai);
450 int width = snd_pcm_format_width(params_format(params)); 457 int width = params_width(params);
451 struct snd_pcm_runtime *runtime = substream->runtime; 458 struct snd_pcm_runtime *runtime = substream->runtime;
452 struct fsl_asrc_pair *pair = runtime->private_data; 459 struct fsl_asrc_pair *pair = runtime->private_data;
453 unsigned int channels = params_channels(params); 460 unsigned int channels = params_channels(params);
@@ -859,6 +866,10 @@ static int fsl_asrc_probe(struct platform_device *pdev)
859 return PTR_ERR(asrc_priv->ipg_clk); 866 return PTR_ERR(asrc_priv->ipg_clk);
860 } 867 }
861 868
869 asrc_priv->spba_clk = devm_clk_get(&pdev->dev, "spba");
870 if (IS_ERR(asrc_priv->spba_clk))
871 dev_warn(&pdev->dev, "failed to get spba clock\n");
872
862 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) { 873 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
863 sprintf(tmp, "asrck_%x", i); 874 sprintf(tmp, "asrck_%x", i);
864 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp); 875 asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
@@ -939,6 +950,11 @@ static int fsl_asrc_runtime_resume(struct device *dev)
939 ret = clk_prepare_enable(asrc_priv->ipg_clk); 950 ret = clk_prepare_enable(asrc_priv->ipg_clk);
940 if (ret) 951 if (ret)
941 goto disable_mem_clk; 952 goto disable_mem_clk;
953 if (!IS_ERR(asrc_priv->spba_clk)) {
954 ret = clk_prepare_enable(asrc_priv->spba_clk);
955 if (ret)
956 goto disable_ipg_clk;
957 }
942 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) { 958 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
943 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]); 959 ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
944 if (ret) 960 if (ret)
@@ -950,6 +966,9 @@ static int fsl_asrc_runtime_resume(struct device *dev)
950disable_asrck_clk: 966disable_asrck_clk:
951 for (i--; i >= 0; i--) 967 for (i--; i >= 0; i--)
952 clk_disable_unprepare(asrc_priv->asrck_clk[i]); 968 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
969 if (!IS_ERR(asrc_priv->spba_clk))
970 clk_disable_unprepare(asrc_priv->spba_clk);
971disable_ipg_clk:
953 clk_disable_unprepare(asrc_priv->ipg_clk); 972 clk_disable_unprepare(asrc_priv->ipg_clk);
954disable_mem_clk: 973disable_mem_clk:
955 clk_disable_unprepare(asrc_priv->mem_clk); 974 clk_disable_unprepare(asrc_priv->mem_clk);
@@ -963,6 +982,8 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
963 982
964 for (i = 0; i < ASRC_CLK_MAX_NUM; i++) 983 for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
965 clk_disable_unprepare(asrc_priv->asrck_clk[i]); 984 clk_disable_unprepare(asrc_priv->asrck_clk[i]);
985 if (!IS_ERR(asrc_priv->spba_clk))
986 clk_disable_unprepare(asrc_priv->spba_clk);
966 clk_disable_unprepare(asrc_priv->ipg_clk); 987 clk_disable_unprepare(asrc_priv->ipg_clk);
967 clk_disable_unprepare(asrc_priv->mem_clk); 988 clk_disable_unprepare(asrc_priv->mem_clk);
968 989
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 4aed63c4b431..68802cdc3f28 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -426,6 +426,7 @@ struct fsl_asrc_pair {
426 * @paddr: physical address to the base address of registers 426 * @paddr: physical address to the base address of registers
427 * @mem_clk: clock source to access register 427 * @mem_clk: clock source to access register
428 * @ipg_clk: clock source to drive peripheral 428 * @ipg_clk: clock source to drive peripheral
429 * @spba_clk: SPBA clock (optional, depending on SoC design)
429 * @asrck_clk: clock sources to driver ASRC internal logic 430 * @asrck_clk: clock sources to driver ASRC internal logic
430 * @lock: spin lock for resource protection 431 * @lock: spin lock for resource protection
431 * @pair: pair pointers 432 * @pair: pair pointers
@@ -442,6 +443,7 @@ struct fsl_asrc {
442 unsigned long paddr; 443 unsigned long paddr;
443 struct clk *mem_clk; 444 struct clk *mem_clk;
444 struct clk *ipg_clk; 445 struct clk *ipg_clk;
446 struct clk *spba_clk;
445 struct clk *asrck_clk[ASRC_CLK_MAX_NUM]; 447 struct clk *asrck_clk[ASRC_CLK_MAX_NUM];
446 spinlock_t lock; 448 spinlock_t lock;
447 449
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 59f234e51971..26a90e12ede4 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -35,6 +35,7 @@
35 * @coreclk: clock source to access register 35 * @coreclk: clock source to access register
36 * @extalclk: esai clock source to derive HCK, SCK and FS 36 * @extalclk: esai clock source to derive HCK, SCK and FS
37 * @fsysclk: system clock source to derive HCK, SCK and FS 37 * @fsysclk: system clock source to derive HCK, SCK and FS
38 * @spbaclk: SPBA clock (optional, depending on SoC design)
38 * @fifo_depth: depth of tx/rx FIFO 39 * @fifo_depth: depth of tx/rx FIFO
39 * @slot_width: width of each DAI slot 40 * @slot_width: width of each DAI slot
40 * @slots: number of slots 41 * @slots: number of slots
@@ -54,6 +55,7 @@ struct fsl_esai {
54 struct clk *coreclk; 55 struct clk *coreclk;
55 struct clk *extalclk; 56 struct clk *extalclk;
56 struct clk *fsysclk; 57 struct clk *fsysclk;
58 struct clk *spbaclk;
57 u32 fifo_depth; 59 u32 fifo_depth;
58 u32 slot_width; 60 u32 slot_width;
59 u32 slots; 61 u32 slots;
@@ -469,6 +471,11 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
469 ret = clk_prepare_enable(esai_priv->coreclk); 471 ret = clk_prepare_enable(esai_priv->coreclk);
470 if (ret) 472 if (ret)
471 return ret; 473 return ret;
474 if (!IS_ERR(esai_priv->spbaclk)) {
475 ret = clk_prepare_enable(esai_priv->spbaclk);
476 if (ret)
477 goto err_spbaclk;
478 }
472 if (!IS_ERR(esai_priv->extalclk)) { 479 if (!IS_ERR(esai_priv->extalclk)) {
473 ret = clk_prepare_enable(esai_priv->extalclk); 480 ret = clk_prepare_enable(esai_priv->extalclk);
474 if (ret) 481 if (ret)
@@ -499,6 +506,9 @@ err_fsysclk:
499 if (!IS_ERR(esai_priv->extalclk)) 506 if (!IS_ERR(esai_priv->extalclk))
500 clk_disable_unprepare(esai_priv->extalclk); 507 clk_disable_unprepare(esai_priv->extalclk);
501err_extalck: 508err_extalck:
509 if (!IS_ERR(esai_priv->spbaclk))
510 clk_disable_unprepare(esai_priv->spbaclk);
511err_spbaclk:
502 clk_disable_unprepare(esai_priv->coreclk); 512 clk_disable_unprepare(esai_priv->coreclk);
503 513
504 return ret; 514 return ret;
@@ -510,7 +520,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
510{ 520{
511 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 521 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
512 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 522 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
513 u32 width = snd_pcm_format_width(params_format(params)); 523 u32 width = params_width(params);
514 u32 channels = params_channels(params); 524 u32 channels = params_channels(params);
515 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); 525 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
516 u32 slot_width = width; 526 u32 slot_width = width;
@@ -564,6 +574,8 @@ static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
564 clk_disable_unprepare(esai_priv->fsysclk); 574 clk_disable_unprepare(esai_priv->fsysclk);
565 if (!IS_ERR(esai_priv->extalclk)) 575 if (!IS_ERR(esai_priv->extalclk))
566 clk_disable_unprepare(esai_priv->extalclk); 576 clk_disable_unprepare(esai_priv->extalclk);
577 if (!IS_ERR(esai_priv->spbaclk))
578 clk_disable_unprepare(esai_priv->spbaclk);
567 clk_disable_unprepare(esai_priv->coreclk); 579 clk_disable_unprepare(esai_priv->coreclk);
568} 580}
569 581
@@ -653,21 +665,28 @@ static const struct snd_soc_component_driver fsl_esai_component = {
653}; 665};
654 666
655static const struct reg_default fsl_esai_reg_defaults[] = { 667static const struct reg_default fsl_esai_reg_defaults[] = {
656 {0x8, 0x00000000}, 668 {REG_ESAI_ETDR, 0x00000000},
657 {0x10, 0x00000000}, 669 {REG_ESAI_ECR, 0x00000000},
658 {0x18, 0x00000000}, 670 {REG_ESAI_TFCR, 0x00000000},
659 {0x98, 0x00000000}, 671 {REG_ESAI_RFCR, 0x00000000},
660 {0xd0, 0x00000000}, 672 {REG_ESAI_TX0, 0x00000000},
661 {0xd4, 0x00000000}, 673 {REG_ESAI_TX1, 0x00000000},
662 {0xd8, 0x00000000}, 674 {REG_ESAI_TX2, 0x00000000},
663 {0xdc, 0x00000000}, 675 {REG_ESAI_TX3, 0x00000000},
664 {0xe0, 0x00000000}, 676 {REG_ESAI_TX4, 0x00000000},
665 {0xe4, 0x0000ffff}, 677 {REG_ESAI_TX5, 0x00000000},
666 {0xe8, 0x0000ffff}, 678 {REG_ESAI_TSR, 0x00000000},
667 {0xec, 0x0000ffff}, 679 {REG_ESAI_SAICR, 0x00000000},
668 {0xf0, 0x0000ffff}, 680 {REG_ESAI_TCR, 0x00000000},
669 {0xf8, 0x00000000}, 681 {REG_ESAI_TCCR, 0x00000000},
670 {0xfc, 0x00000000}, 682 {REG_ESAI_RCR, 0x00000000},
683 {REG_ESAI_RCCR, 0x00000000},
684 {REG_ESAI_TSMA, 0x0000ffff},
685 {REG_ESAI_TSMB, 0x0000ffff},
686 {REG_ESAI_RSMA, 0x0000ffff},
687 {REG_ESAI_RSMB, 0x0000ffff},
688 {REG_ESAI_PRRC, 0x00000000},
689 {REG_ESAI_PCRC, 0x00000000},
671}; 690};
672 691
673static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 692static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
@@ -705,17 +724,10 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
705static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg) 724static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
706{ 725{
707 switch (reg) { 726 switch (reg) {
708 case REG_ESAI_ETDR:
709 case REG_ESAI_ERDR: 727 case REG_ESAI_ERDR:
710 case REG_ESAI_ESR: 728 case REG_ESAI_ESR:
711 case REG_ESAI_TFSR: 729 case REG_ESAI_TFSR:
712 case REG_ESAI_RFSR: 730 case REG_ESAI_RFSR:
713 case REG_ESAI_TX0:
714 case REG_ESAI_TX1:
715 case REG_ESAI_TX2:
716 case REG_ESAI_TX3:
717 case REG_ESAI_TX4:
718 case REG_ESAI_TX5:
719 case REG_ESAI_RX0: 731 case REG_ESAI_RX0:
720 case REG_ESAI_RX1: 732 case REG_ESAI_RX1:
721 case REG_ESAI_RX2: 733 case REG_ESAI_RX2:
@@ -819,6 +831,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
819 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n", 831 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
820 PTR_ERR(esai_priv->fsysclk)); 832 PTR_ERR(esai_priv->fsysclk));
821 833
834 esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
835 if (IS_ERR(esai_priv->spbaclk))
836 dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
837 PTR_ERR(esai_priv->spbaclk));
838
822 irq = platform_get_irq(pdev, 0); 839 irq = platform_get_irq(pdev, 0);
823 if (irq < 0) { 840 if (irq < 0) {
824 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); 841 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 08b460ba06ef..fef264d27fd3 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -126,6 +126,17 @@ out:
126 return IRQ_HANDLED; 126 return IRQ_HANDLED;
127} 127}
128 128
129static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
130 u32 rx_mask, int slots, int slot_width)
131{
132 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
133
134 sai->slots = slots;
135 sai->slot_width = slot_width;
136
137 return 0;
138}
139
129static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, 140static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
130 int clk_id, unsigned int freq, int fsl_dir) 141 int clk_id, unsigned int freq, int fsl_dir)
131{ 142{
@@ -354,13 +365,25 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
354 return -EINVAL; 365 return -EINVAL;
355 } 366 }
356 367
357 if ((tx && sai->synchronous[TX]) || (!tx && !sai->synchronous[RX])) { 368 /*
369 * 1) For Asynchronous mode, we must set RCR2 register for capture, and
370 * set TCR2 register for playback.
371 * 2) For Tx sync with Rx clock, we must set RCR2 register for playback
372 * and capture.
373 * 3) For Rx sync with Tx clock, we must set TCR2 register for playback
374 * and capture.
375 * 4) For Tx and Rx are both Synchronous with another SAI, we just
376 * ignore it.
377 */
378 if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
379 (!tx && !sai->synchronous[RX])) {
358 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 380 regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
359 FSL_SAI_CR2_MSEL_MASK, 381 FSL_SAI_CR2_MSEL_MASK,
360 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 382 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
361 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, 383 regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
362 FSL_SAI_CR2_DIV_MASK, savediv - 1); 384 FSL_SAI_CR2_DIV_MASK, savediv - 1);
363 } else { 385 } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
386 (tx && !sai->synchronous[TX])) {
364 regmap_update_bits(sai->regmap, FSL_SAI_TCR2, 387 regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
365 FSL_SAI_CR2_MSEL_MASK, 388 FSL_SAI_CR2_MSEL_MASK,
366 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); 389 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
@@ -381,13 +404,21 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
381 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 404 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
382 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 405 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
383 unsigned int channels = params_channels(params); 406 unsigned int channels = params_channels(params);
384 u32 word_width = snd_pcm_format_width(params_format(params)); 407 u32 word_width = params_width(params);
385 u32 val_cr4 = 0, val_cr5 = 0; 408 u32 val_cr4 = 0, val_cr5 = 0;
409 u32 slots = (channels == 1) ? 2 : channels;
410 u32 slot_width = word_width;
386 int ret; 411 int ret;
387 412
413 if (sai->slots)
414 slots = sai->slots;
415
416 if (sai->slot_width)
417 slot_width = sai->slot_width;
418
388 if (!sai->is_slave_mode) { 419 if (!sai->is_slave_mode) {
389 ret = fsl_sai_set_bclk(cpu_dai, tx, 420 ret = fsl_sai_set_bclk(cpu_dai, tx,
390 2 * word_width * params_rate(params)); 421 slots * slot_width * params_rate(params));
391 if (ret) 422 if (ret)
392 return ret; 423 return ret;
393 424
@@ -399,21 +430,49 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
399 430
400 sai->mclk_streams |= BIT(substream->stream); 431 sai->mclk_streams |= BIT(substream->stream);
401 } 432 }
402
403 } 433 }
404 434
405 if (!sai->is_dsp_mode) 435 if (!sai->is_dsp_mode)
406 val_cr4 |= FSL_SAI_CR4_SYWD(word_width); 436 val_cr4 |= FSL_SAI_CR4_SYWD(slot_width);
407 437
408 val_cr5 |= FSL_SAI_CR5_WNW(word_width); 438 val_cr5 |= FSL_SAI_CR5_WNW(slot_width);
409 val_cr5 |= FSL_SAI_CR5_W0W(word_width); 439 val_cr5 |= FSL_SAI_CR5_W0W(slot_width);
410 440
411 if (sai->is_lsb_first) 441 if (sai->is_lsb_first)
412 val_cr5 |= FSL_SAI_CR5_FBT(0); 442 val_cr5 |= FSL_SAI_CR5_FBT(0);
413 else 443 else
414 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); 444 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
415 445
416 val_cr4 |= FSL_SAI_CR4_FRSZ(channels); 446 val_cr4 |= FSL_SAI_CR4_FRSZ(slots);
447
448 /*
449 * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will
450 * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4),
451 * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync
452 * error.
453 */
454
455 if (!sai->is_slave_mode) {
456 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
457 regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
458 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
459 val_cr4);
460 regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
461 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
462 FSL_SAI_CR5_FBT_MASK, val_cr5);
463 regmap_write(sai->regmap, FSL_SAI_TMR,
464 ~0UL - ((1 << channels) - 1));
465 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
466 regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
467 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
468 val_cr4);
469 regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
470 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
471 FSL_SAI_CR5_FBT_MASK, val_cr5);
472 regmap_write(sai->regmap, FSL_SAI_RMR,
473 ~0UL - ((1 << channels) - 1));
474 }
475 }
417 476
418 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), 477 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
419 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, 478 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
@@ -569,6 +628,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
569static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { 628static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
570 .set_sysclk = fsl_sai_set_dai_sysclk, 629 .set_sysclk = fsl_sai_set_dai_sysclk,
571 .set_fmt = fsl_sai_set_dai_fmt, 630 .set_fmt = fsl_sai_set_dai_fmt,
631 .set_tdm_slot = fsl_sai_set_dai_tdm_slot,
572 .hw_params = fsl_sai_hw_params, 632 .hw_params = fsl_sai_hw_params,
573 .hw_free = fsl_sai_hw_free, 633 .hw_free = fsl_sai_hw_free,
574 .trigger = fsl_sai_trigger, 634 .trigger = fsl_sai_trigger,
@@ -627,6 +687,22 @@ static const struct snd_soc_component_driver fsl_component = {
627 .name = "fsl-sai", 687 .name = "fsl-sai",
628}; 688};
629 689
690static struct reg_default fsl_sai_reg_defaults[] = {
691 {FSL_SAI_TCR1, 0},
692 {FSL_SAI_TCR2, 0},
693 {FSL_SAI_TCR3, 0},
694 {FSL_SAI_TCR4, 0},
695 {FSL_SAI_TCR5, 0},
696 {FSL_SAI_TDR, 0},
697 {FSL_SAI_TMR, 0},
698 {FSL_SAI_RCR1, 0},
699 {FSL_SAI_RCR2, 0},
700 {FSL_SAI_RCR3, 0},
701 {FSL_SAI_RCR4, 0},
702 {FSL_SAI_RCR5, 0},
703 {FSL_SAI_RMR, 0},
704};
705
630static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) 706static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
631{ 707{
632 switch (reg) { 708 switch (reg) {
@@ -660,13 +736,11 @@ static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
660 case FSL_SAI_RCSR: 736 case FSL_SAI_RCSR:
661 case FSL_SAI_TFR: 737 case FSL_SAI_TFR:
662 case FSL_SAI_RFR: 738 case FSL_SAI_RFR:
663 case FSL_SAI_TDR:
664 case FSL_SAI_RDR: 739 case FSL_SAI_RDR:
665 return true; 740 return true;
666 default: 741 default:
667 return false; 742 return false;
668 } 743 }
669
670} 744}
671 745
672static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) 746static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
@@ -699,6 +773,8 @@ static const struct regmap_config fsl_sai_regmap_config = {
699 .val_bits = 32, 773 .val_bits = 32,
700 774
701 .max_register = FSL_SAI_RMR, 775 .max_register = FSL_SAI_RMR,
776 .reg_defaults = fsl_sai_reg_defaults,
777 .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
702 .readable_reg = fsl_sai_readable_reg, 778 .readable_reg = fsl_sai_readable_reg,
703 .volatile_reg = fsl_sai_volatile_reg, 779 .volatile_reg = fsl_sai_volatile_reg,
704 .writeable_reg = fsl_sai_writeable_reg, 780 .writeable_reg = fsl_sai_writeable_reg,
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index b95fbc3f68eb..d9ed7be8cb34 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -143,6 +143,9 @@ struct fsl_sai {
143 143
144 unsigned int mclk_id[2]; 144 unsigned int mclk_id[2];
145 unsigned int mclk_streams; 145 unsigned int mclk_streams;
146 unsigned int slots;
147 unsigned int slot_width;
148
146 struct snd_dmaengine_dai_dma_data dma_params_rx; 149 struct snd_dmaengine_dai_dma_data dma_params_rx;
147 struct snd_dmaengine_dai_dma_data dma_params_tx; 150 struct snd_dmaengine_dai_dma_data dma_params_tx;
148}; 151};
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 3d59bb6719f2..151849f79863 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -88,6 +88,7 @@ struct spdif_mixer_control {
88 * @rxclk: rx clock sources for capture 88 * @rxclk: rx clock sources for capture
89 * @coreclk: core clock for register access via DMA 89 * @coreclk: core clock for register access via DMA
90 * @sysclk: system clock for rx clock rate measurement 90 * @sysclk: system clock for rx clock rate measurement
91 * @spbaclk: SPBA clock (optional, depending on SoC design)
91 * @dma_params_tx: DMA parameters for transmit channel 92 * @dma_params_tx: DMA parameters for transmit channel
92 * @dma_params_rx: DMA parameters for receive channel 93 * @dma_params_rx: DMA parameters for receive channel
93 */ 94 */
@@ -106,6 +107,7 @@ struct fsl_spdif_priv {
106 struct clk *rxclk; 107 struct clk *rxclk;
107 struct clk *coreclk; 108 struct clk *coreclk;
108 struct clk *sysclk; 109 struct clk *sysclk;
110 struct clk *spbaclk;
109 struct snd_dmaengine_dai_dma_data dma_params_tx; 111 struct snd_dmaengine_dai_dma_data dma_params_tx;
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 112 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 /* regcache for SRPC */ 113 /* regcache for SRPC */
@@ -474,6 +476,14 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream,
474 return ret; 476 return ret;
475 } 477 }
476 478
479 if (!IS_ERR(spdif_priv->spbaclk)) {
480 ret = clk_prepare_enable(spdif_priv->spbaclk);
481 if (ret) {
482 dev_err(&pdev->dev, "failed to enable spba clock\n");
483 goto err_spbaclk;
484 }
485 }
486
477 ret = spdif_softreset(spdif_priv); 487 ret = spdif_softreset(spdif_priv);
478 if (ret) { 488 if (ret) {
479 dev_err(&pdev->dev, "failed to soft reset\n"); 489 dev_err(&pdev->dev, "failed to soft reset\n");
@@ -515,6 +525,9 @@ disable_txclk:
515 for (i--; i >= 0; i--) 525 for (i--; i >= 0; i--)
516 clk_disable_unprepare(spdif_priv->txclk[i]); 526 clk_disable_unprepare(spdif_priv->txclk[i]);
517err: 527err:
528 if (!IS_ERR(spdif_priv->spbaclk))
529 clk_disable_unprepare(spdif_priv->spbaclk);
530err_spbaclk:
518 clk_disable_unprepare(spdif_priv->coreclk); 531 clk_disable_unprepare(spdif_priv->coreclk);
519 532
520 return ret; 533 return ret;
@@ -548,6 +561,8 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
548 spdif_intr_status_clear(spdif_priv); 561 spdif_intr_status_clear(spdif_priv);
549 regmap_update_bits(regmap, REG_SPDIF_SCR, 562 regmap_update_bits(regmap, REG_SPDIF_SCR,
550 SCR_LOW_POWER, SCR_LOW_POWER); 563 SCR_LOW_POWER, SCR_LOW_POWER);
564 if (!IS_ERR(spdif_priv->spbaclk))
565 clk_disable_unprepare(spdif_priv->spbaclk);
551 clk_disable_unprepare(spdif_priv->coreclk); 566 clk_disable_unprepare(spdif_priv->coreclk);
552 } 567 }
553} 568}
@@ -1006,12 +1021,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
1006 1021
1007/* FSL SPDIF REGMAP */ 1022/* FSL SPDIF REGMAP */
1008static const struct reg_default fsl_spdif_reg_defaults[] = { 1023static const struct reg_default fsl_spdif_reg_defaults[] = {
1009 {0x0, 0x00000400}, 1024 {REG_SPDIF_SCR, 0x00000400},
1010 {0x4, 0x00000000}, 1025 {REG_SPDIF_SRCD, 0x00000000},
1011 {0xc, 0x00000000}, 1026 {REG_SPDIF_SIE, 0x00000000},
1012 {0x34, 0x00000000}, 1027 {REG_SPDIF_STL, 0x00000000},
1013 {0x38, 0x00000000}, 1028 {REG_SPDIF_STR, 0x00000000},
1014 {0x50, 0x00020f00}, 1029 {REG_SPDIF_STCSCH, 0x00000000},
1030 {REG_SPDIF_STCSCL, 0x00000000},
1031 {REG_SPDIF_STC, 0x00020f00},
1015}; 1032};
1016 1033
1017static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 1034static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
@@ -1049,8 +1066,6 @@ static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg)
1049 case REG_SPDIF_SRCSL: 1066 case REG_SPDIF_SRCSL:
1050 case REG_SPDIF_SRU: 1067 case REG_SPDIF_SRU:
1051 case REG_SPDIF_SRQ: 1068 case REG_SPDIF_SRQ:
1052 case REG_SPDIF_STL:
1053 case REG_SPDIF_STR:
1054 case REG_SPDIF_SRFM: 1069 case REG_SPDIF_SRFM:
1055 return true; 1070 return true;
1056 default: 1071 default:
@@ -1261,6 +1276,10 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1261 return PTR_ERR(spdif_priv->coreclk); 1276 return PTR_ERR(spdif_priv->coreclk);
1262 } 1277 }
1263 1278
1279 spdif_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
1280 if (IS_ERR(spdif_priv->spbaclk))
1281 dev_warn(&pdev->dev, "no spba clock in devicetree\n");
1282
1264 /* Select clock source for rx/tx clock */ 1283 /* Select clock source for rx/tx clock */
1265 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); 1284 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
1266 if (IS_ERR(spdif_priv->rxclk)) { 1285 if (IS_ERR(spdif_priv->rxclk)) {
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 95d2392303eb..e3abad5f980a 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -113,17 +113,17 @@ struct fsl_ssi_rxtx_reg_val {
113}; 113};
114 114
115static const struct reg_default fsl_ssi_reg_defaults[] = { 115static const struct reg_default fsl_ssi_reg_defaults[] = {
116 {0x10, 0x00000000}, 116 {CCSR_SSI_SCR, 0x00000000},
117 {0x18, 0x00003003}, 117 {CCSR_SSI_SIER, 0x00003003},
118 {0x1c, 0x00000200}, 118 {CCSR_SSI_STCR, 0x00000200},
119 {0x20, 0x00000200}, 119 {CCSR_SSI_SRCR, 0x00000200},
120 {0x24, 0x00040000}, 120 {CCSR_SSI_STCCR, 0x00040000},
121 {0x28, 0x00040000}, 121 {CCSR_SSI_SRCCR, 0x00040000},
122 {0x38, 0x00000000}, 122 {CCSR_SSI_SACNT, 0x00000000},
123 {0x48, 0x00000000}, 123 {CCSR_SSI_STMSK, 0x00000000},
124 {0x4c, 0x00000000}, 124 {CCSR_SSI_SRMSK, 0x00000000},
125 {0x54, 0x00000000}, 125 {CCSR_SSI_SACCEN, 0x00000000},
126 {0x58, 0x00000000}, 126 {CCSR_SSI_SACCDIS, 0x00000000},
127}; 127};
128 128
129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) 129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
@@ -767,8 +767,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
767 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 767 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
768 struct regmap *regs = ssi_private->regs; 768 struct regmap *regs = ssi_private->regs;
769 unsigned int channels = params_channels(hw_params); 769 unsigned int channels = params_channels(hw_params);
770 unsigned int sample_size = 770 unsigned int sample_size = params_width(hw_params);
771 snd_pcm_format_width(params_format(hw_params));
772 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 771 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
773 int ret; 772 int ret;
774 u32 scr_val; 773 u32 scr_val;
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 1fc01ed3279d..f3d3d1ffa84e 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -62,6 +62,8 @@ int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
62 62
63 config = devm_kzalloc(&pdev->dev, 63 config = devm_kzalloc(&pdev->dev,
64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL); 64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
65 if (!config)
66 return -ENOMEM;
65 *config = imx_dmaengine_pcm_config; 67 *config = imx_dmaengine_pcm_config;
66 if (size) 68 if (size)
67 config->prealloc_buffer_size = size; 69 config->prealloc_buffer_size = size;
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 7abf6a079574..49d7513f429e 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -220,9 +220,9 @@ static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
220 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, 220 ret = dma_mmap_writecombine(substream->pcm->card->dev, vma,
221 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); 221 runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
222 222
223 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, 223 pr_debug("%s: ret: %d %p %pad 0x%08x\n", __func__, ret,
224 runtime->dma_area, 224 runtime->dma_area,
225 runtime->dma_addr, 225 &runtime->dma_addr,
226 runtime->dma_bytes); 226 runtime->dma_bytes);
227 return ret; 227 return ret;
228} 228}
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index b38b98cae855..201a70d1027a 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -69,13 +69,16 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
69 struct snd_soc_dapm_context *dapm, 69 struct snd_soc_dapm_context *dapm,
70 enum snd_soc_bias_level level) 70 enum snd_soc_bias_level level)
71{ 71{
72 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 72 struct snd_soc_pcm_runtime *rtd;
73 struct snd_soc_dai *codec_dai;
73 struct imx_priv *priv = &card_priv; 74 struct imx_priv *priv = &card_priv;
74 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
75 struct device *dev = &priv->pdev->dev; 76 struct device *dev = &priv->pdev->dev;
76 unsigned int pll_out; 77 unsigned int pll_out;
77 int ret; 78 int ret;
78 79
80 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
81 codec_dai = rtd->codec_dai;
79 if (dapm->dev != codec_dai->dev) 82 if (dapm->dev != codec_dai->dev)
80 return 0; 83 return 0;
81 84
@@ -135,12 +138,15 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
135 138
136static int imx_wm8962_late_probe(struct snd_soc_card *card) 139static int imx_wm8962_late_probe(struct snd_soc_card *card)
137{ 140{
138 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 141 struct snd_soc_pcm_runtime *rtd;
142 struct snd_soc_dai *codec_dai;
139 struct imx_priv *priv = &card_priv; 143 struct imx_priv *priv = &card_priv;
140 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
141 struct device *dev = &priv->pdev->dev; 145 struct device *dev = &priv->pdev->dev;
142 int ret; 146 int ret;
143 147
148 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
149 codec_dai = rtd->codec_dai;
144 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK, 150 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
145 data->clk_frequency, SND_SOC_CLOCK_IN); 151 data->clk_frequency, SND_SOC_CLOCK_IN);
146 if (ret < 0) 152 if (ret < 0)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 54c33204541f..1ded8811598e 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -45,7 +45,7 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
45 struct snd_soc_pcm_runtime *rtd = substream->private_data; 45 struct snd_soc_pcm_runtime *rtd = substream->private_data;
46 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 46 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
47 struct simple_dai_props *dai_props = 47 struct simple_dai_props *dai_props =
48 &priv->dai_props[rtd - rtd->card->rtd]; 48 &priv->dai_props[rtd->num];
49 int ret; 49 int ret;
50 50
51 ret = clk_prepare_enable(dai_props->cpu_dai.clk); 51 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
@@ -64,7 +64,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
64 struct snd_soc_pcm_runtime *rtd = substream->private_data; 64 struct snd_soc_pcm_runtime *rtd = substream->private_data;
65 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 65 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
66 struct simple_dai_props *dai_props = 66 struct simple_dai_props *dai_props =
67 &priv->dai_props[rtd - rtd->card->rtd]; 67 &priv->dai_props[rtd->num];
68 68
69 clk_disable_unprepare(dai_props->cpu_dai.clk); 69 clk_disable_unprepare(dai_props->cpu_dai.clk);
70 70
@@ -78,8 +78,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
78 struct snd_soc_dai *codec_dai = rtd->codec_dai; 78 struct snd_soc_dai *codec_dai = rtd->codec_dai;
79 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 79 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
80 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 80 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
81 struct simple_dai_props *dai_props = 81 struct simple_dai_props *dai_props = &priv->dai_props[rtd->num];
82 &priv->dai_props[rtd - rtd->card->rtd];
83 unsigned int mclk, mclk_fs = 0; 82 unsigned int mclk, mclk_fs = 0;
84 int ret = 0; 83 int ret = 0;
85 84
@@ -174,10 +173,9 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
174 struct snd_soc_dai *codec = rtd->codec_dai; 173 struct snd_soc_dai *codec = rtd->codec_dai;
175 struct snd_soc_dai *cpu = rtd->cpu_dai; 174 struct snd_soc_dai *cpu = rtd->cpu_dai;
176 struct simple_dai_props *dai_props; 175 struct simple_dai_props *dai_props;
177 int num, ret; 176 int ret;
178 177
179 num = rtd - rtd->card->rtd; 178 dai_props = &priv->dai_props[rtd->num];
180 dai_props = &priv->dai_props[num];
181 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai); 179 ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
182 if (ret < 0) 180 if (ret < 0)
183 return ret; 181 return ret;
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
new file mode 100644
index 000000000000..857a9510ee1c
--- /dev/null
+++ b/sound/soc/img/Kconfig
@@ -0,0 +1,52 @@
1config SND_SOC_IMG
2 bool "Audio support for Imagination Technologies designs"
3 help
4 Audio support for Imagination Technologies audio hardware
5
6config SND_SOC_IMG_I2S_IN
7 tristate "Imagination I2S Input Device Driver"
8 depends on SND_SOC_IMG
9 select SND_SOC_GENERIC_DMAENGINE_PCM
10 help
11 Say Y or M if you want to add support for I2S in driver for
12 Imagination Technologies I2S in device.
13
14config SND_SOC_IMG_I2S_OUT
15 tristate "Imagination I2S Output Device Driver"
16 depends on SND_SOC_IMG
17 select SND_SOC_GENERIC_DMAENGINE_PCM
18 help
19 Say Y or M if you want to add support for I2S out driver for
20 Imagination Technologies I2S out device.
21
22config SND_SOC_IMG_PARALLEL_OUT
23 tristate "Imagination Parallel Output Device Driver"
24 depends on SND_SOC_IMG
25 select SND_SOC_GENERIC_DMAENGINE_PCM
26 help
27 Say Y or M if you want to add support for parallel out driver for
28 Imagination Technologies parallel out device.
29
30config SND_SOC_IMG_SPDIF_IN
31 tristate "Imagination SPDIF Input Device Driver"
32 depends on SND_SOC_IMG
33 select SND_SOC_GENERIC_DMAENGINE_PCM
34 help
35 Say Y or M if you want to add support for SPDIF input driver for
36 Imagination Technologies SPDIF input device.
37
38config SND_SOC_IMG_SPDIF_OUT
39 tristate "Imagination SPDIF Output Device Driver"
40 depends on SND_SOC_IMG
41 select SND_SOC_GENERIC_DMAENGINE_PCM
42 help
43 Say Y or M if you want to add support for SPDIF out driver for
44 Imagination Technologies SPDIF out device.
45
46
47config SND_SOC_IMG_PISTACHIO_INTERNAL_DAC
48 tristate "Support for Pistachio SoC Internal DAC Driver"
49 depends on SND_SOC_IMG
50 help
51 Say Y or M if you want to add support for Pistachio internal DAC
52 driver for Imagination Technologies Pistachio internal DAC device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
new file mode 100644
index 000000000000..0508c1ced636
--- /dev/null
+++ b/sound/soc/img/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
2obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
3obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
4obj-$(CONFIG_SND_SOC_IMG_SPDIF_IN) += img-spdif-in.o
5obj-$(CONFIG_SND_SOC_IMG_SPDIF_OUT) += img-spdif-out.o
6
7obj-$(CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC) += pistachio-internal-dac.o
diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
new file mode 100644
index 000000000000..0389203f8560
--- /dev/null
+++ b/sound/soc/img/img-i2s-in.c
@@ -0,0 +1,516 @@
1/*
2 * IMG I2S input controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/reset.h>
20
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27
28#define IMG_I2S_IN_RX_FIFO 0x0
29
30#define IMG_I2S_IN_CTL 0x4
31#define IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK 0xfffffffc
32#define IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT 2
33#define IMG_I2S_IN_CTL_16PACK_MASK BIT(1)
34#define IMG_I2S_IN_CTL_ME_MASK BIT(0)
35
36#define IMG_I2S_IN_CH_CTL 0x4
37#define IMG_I2S_IN_CH_CTL_CCDEL_MASK 0x38000
38#define IMG_I2S_IN_CH_CTL_CCDEL_SHIFT 15
39#define IMG_I2S_IN_CH_CTL_FEN_MASK BIT(14)
40#define IMG_I2S_IN_CH_CTL_FMODE_MASK BIT(13)
41#define IMG_I2S_IN_CH_CTL_16PACK_MASK BIT(12)
42#define IMG_I2S_IN_CH_CTL_JUST_MASK BIT(10)
43#define IMG_I2S_IN_CH_CTL_PACKH_MASK BIT(9)
44#define IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK BIT(8)
45#define IMG_I2S_IN_CH_CTL_BLKP_MASK BIT(7)
46#define IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK BIT(6)
47#define IMG_I2S_IN_CH_CTL_LRD_MASK BIT(3)
48#define IMG_I2S_IN_CH_CTL_FW_MASK BIT(2)
49#define IMG_I2S_IN_CH_CTL_SW_MASK BIT(1)
50#define IMG_I2S_IN_CH_CTL_ME_MASK BIT(0)
51
52#define IMG_I2S_IN_CH_STRIDE 0x20
53
54struct img_i2s_in {
55 void __iomem *base;
56 struct clk *clk_sys;
57 struct snd_dmaengine_dai_dma_data dma_data;
58 struct device *dev;
59 unsigned int max_i2s_chan;
60 void __iomem *channel_base;
61 unsigned int active_channels;
62 struct snd_soc_dai_driver dai_driver;
63};
64
65static inline void img_i2s_in_writel(struct img_i2s_in *i2s, u32 val, u32 reg)
66{
67 writel(val, i2s->base + reg);
68}
69
70static inline u32 img_i2s_in_readl(struct img_i2s_in *i2s, u32 reg)
71{
72 return readl(i2s->base + reg);
73}
74
75static inline void img_i2s_in_ch_writel(struct img_i2s_in *i2s, u32 chan,
76 u32 val, u32 reg)
77{
78 writel(val, i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
79}
80
81static inline u32 img_i2s_in_ch_readl(struct img_i2s_in *i2s, u32 chan,
82 u32 reg)
83{
84 return readl(i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
85}
86
87static inline void img_i2s_in_ch_disable(struct img_i2s_in *i2s, u32 chan)
88{
89 u32 reg;
90
91 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
92 reg &= ~IMG_I2S_IN_CH_CTL_ME_MASK;
93 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
94}
95
96static inline void img_i2s_in_ch_enable(struct img_i2s_in *i2s, u32 chan)
97{
98 u32 reg;
99
100 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
101 reg |= IMG_I2S_IN_CH_CTL_ME_MASK;
102 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
103}
104
105static inline void img_i2s_in_disable(struct img_i2s_in *i2s)
106{
107 u32 reg;
108
109 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
110 reg &= ~IMG_I2S_IN_CTL_ME_MASK;
111 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
112}
113
114static inline void img_i2s_in_enable(struct img_i2s_in *i2s)
115{
116 u32 reg;
117
118 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
119 reg |= IMG_I2S_IN_CTL_ME_MASK;
120 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
121}
122
123static inline void img_i2s_in_flush(struct img_i2s_in *i2s)
124{
125 int i;
126 u32 reg;
127
128 for (i = 0; i < i2s->active_channels; i++) {
129 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
130 reg |= IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
131 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
132 reg &= ~IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
133 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
134 }
135}
136
137static int img_i2s_in_trigger(struct snd_pcm_substream *substream, int cmd,
138 struct snd_soc_dai *dai)
139{
140 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
141
142 switch (cmd) {
143 case SNDRV_PCM_TRIGGER_START:
144 case SNDRV_PCM_TRIGGER_RESUME:
145 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
146 img_i2s_in_enable(i2s);
147 break;
148
149 case SNDRV_PCM_TRIGGER_STOP:
150 case SNDRV_PCM_TRIGGER_SUSPEND:
151 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
152 img_i2s_in_disable(i2s);
153 break;
154 default:
155 return -EINVAL;
156 }
157
158 return 0;
159}
160
161static int img_i2s_in_check_rate(struct img_i2s_in *i2s,
162 unsigned int sample_rate, unsigned int frame_size,
163 unsigned int *bclk_filter_enable,
164 unsigned int *bclk_filter_value)
165{
166 unsigned int bclk_freq, cur_freq;
167
168 bclk_freq = sample_rate * frame_size;
169
170 cur_freq = clk_get_rate(i2s->clk_sys);
171
172 if (cur_freq >= bclk_freq * 8) {
173 *bclk_filter_enable = 1;
174 *bclk_filter_value = 0;
175 } else if (cur_freq >= bclk_freq * 7) {
176 *bclk_filter_enable = 1;
177 *bclk_filter_value = 1;
178 } else if (cur_freq >= bclk_freq * 6) {
179 *bclk_filter_enable = 0;
180 *bclk_filter_value = 0;
181 } else {
182 dev_err(i2s->dev,
183 "Sys clock rate %u insufficient for sample rate %u\n",
184 cur_freq, sample_rate);
185 return -EINVAL;
186 }
187
188 return 0;
189}
190
191static int img_i2s_in_hw_params(struct snd_pcm_substream *substream,
192 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
193{
194 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
195 unsigned int rate, channels, i2s_channels, frame_size;
196 unsigned int bclk_filter_enable, bclk_filter_value;
197 int i, ret = 0;
198 u32 reg, control_mask, chan_control_mask;
199 u32 control_set = 0, chan_control_set = 0;
200 snd_pcm_format_t format;
201
202 rate = params_rate(params);
203 format = params_format(params);
204 channels = params_channels(params);
205 i2s_channels = channels / 2;
206
207 switch (format) {
208 case SNDRV_PCM_FORMAT_S32_LE:
209 frame_size = 64;
210 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
211 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
212 chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
213 break;
214 case SNDRV_PCM_FORMAT_S24_LE:
215 frame_size = 64;
216 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
217 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
218 break;
219 case SNDRV_PCM_FORMAT_S16_LE:
220 frame_size = 32;
221 control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
222 chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
223 break;
224 default:
225 return -EINVAL;
226 }
227
228 if ((channels < 2) ||
229 (channels > (i2s->max_i2s_chan * 2)) ||
230 (channels % 2))
231 return -EINVAL;
232
233 control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);
234
235 ret = img_i2s_in_check_rate(i2s, rate, frame_size,
236 &bclk_filter_enable, &bclk_filter_value);
237 if (ret < 0)
238 return ret;
239
240 if (bclk_filter_enable)
241 chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;
242
243 if (bclk_filter_value)
244 chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;
245
246 control_mask = IMG_I2S_IN_CTL_16PACK_MASK |
247 IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;
248
249 chan_control_mask = IMG_I2S_IN_CH_CTL_16PACK_MASK |
250 IMG_I2S_IN_CH_CTL_FEN_MASK |
251 IMG_I2S_IN_CH_CTL_FMODE_MASK |
252 IMG_I2S_IN_CH_CTL_SW_MASK |
253 IMG_I2S_IN_CH_CTL_FW_MASK |
254 IMG_I2S_IN_CH_CTL_PACKH_MASK;
255
256 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
257 reg = (reg & ~control_mask) | control_set;
258 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
259
260 for (i = 0; i < i2s->active_channels; i++)
261 img_i2s_in_ch_disable(i2s, i);
262
263 for (i = 0; i < i2s->max_i2s_chan; i++) {
264 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
265 reg = (reg & ~chan_control_mask) | chan_control_set;
266 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
267 }
268
269 i2s->active_channels = i2s_channels;
270
271 img_i2s_in_flush(i2s);
272
273 for (i = 0; i < i2s->active_channels; i++)
274 img_i2s_in_ch_enable(i2s, i);
275
276 return 0;
277}
278
279static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
280{
281 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
282 int i;
283 u32 chan_control_mask, lrd_set = 0, blkp_set = 0, chan_control_set = 0;
284 u32 reg;
285
286 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
287 case SND_SOC_DAIFMT_NB_NF:
288 lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
289 break;
290 case SND_SOC_DAIFMT_NB_IF:
291 break;
292 case SND_SOC_DAIFMT_IB_NF:
293 lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
294 blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
295 break;
296 case SND_SOC_DAIFMT_IB_IF:
297 blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
304 case SND_SOC_DAIFMT_I2S:
305 chan_control_set |= IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
306 break;
307 case SND_SOC_DAIFMT_LEFT_J:
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
314 case SND_SOC_DAIFMT_CBM_CFM:
315 break;
316 default:
317 return -EINVAL;
318 }
319
320 chan_control_mask = IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
321
322 for (i = 0; i < i2s->active_channels; i++)
323 img_i2s_in_ch_disable(i2s, i);
324
325 /*
326 * BLKP and LRD must be set during separate register writes
327 */
328 for (i = 0; i < i2s->max_i2s_chan; i++) {
329 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
330 reg = (reg & ~chan_control_mask) | chan_control_set;
331 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
332 reg = (reg & ~IMG_I2S_IN_CH_CTL_BLKP_MASK) | blkp_set;
333 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
334 reg = (reg & ~IMG_I2S_IN_CH_CTL_LRD_MASK) | lrd_set;
335 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
336 }
337
338 for (i = 0; i < i2s->active_channels; i++)
339 img_i2s_in_ch_enable(i2s, i);
340
341 return 0;
342}
343
344static const struct snd_soc_dai_ops img_i2s_in_dai_ops = {
345 .trigger = img_i2s_in_trigger,
346 .hw_params = img_i2s_in_hw_params,
347 .set_fmt = img_i2s_in_set_fmt
348};
349
350static int img_i2s_in_dai_probe(struct snd_soc_dai *dai)
351{
352 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
353
354 snd_soc_dai_init_dma_data(dai, NULL, &i2s->dma_data);
355
356 return 0;
357}
358
359static const struct snd_soc_component_driver img_i2s_in_component = {
360 .name = "img-i2s-in"
361};
362
363static int img_i2s_in_dma_prepare_slave_config(struct snd_pcm_substream *st,
364 struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
365{
366 unsigned int i2s_channels = params_channels(params) / 2;
367 struct snd_soc_pcm_runtime *rtd = st->private_data;
368 struct snd_dmaengine_dai_dma_data *dma_data;
369 int ret;
370
371 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
372
373 ret = snd_hwparams_to_dma_slave_config(st, params, sc);
374 if (ret)
375 return ret;
376
377 sc->src_addr = dma_data->addr;
378 sc->src_addr_width = dma_data->addr_width;
379 sc->src_maxburst = 4 * i2s_channels;
380
381 return 0;
382}
383
384static const struct snd_dmaengine_pcm_config img_i2s_in_dma_config = {
385 .prepare_slave_config = img_i2s_in_dma_prepare_slave_config
386};
387
388static int img_i2s_in_probe(struct platform_device *pdev)
389{
390 struct img_i2s_in *i2s;
391 struct resource *res;
392 void __iomem *base;
393 int ret, i;
394 struct reset_control *rst;
395 unsigned int max_i2s_chan_pow_2;
396 struct device *dev = &pdev->dev;
397
398 i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
399 if (!i2s)
400 return -ENOMEM;
401
402 platform_set_drvdata(pdev, i2s);
403
404 i2s->dev = dev;
405
406 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
407 base = devm_ioremap_resource(dev, res);
408 if (IS_ERR(base))
409 return PTR_ERR(base);
410
411 i2s->base = base;
412
413 if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
414 &i2s->max_i2s_chan)) {
415 dev_err(dev, "No img,i2s-channels property\n");
416 return -EINVAL;
417 }
418
419 max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
420
421 i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
422
423 i2s->clk_sys = devm_clk_get(dev, "sys");
424 if (IS_ERR(i2s->clk_sys)) {
425 if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
426 dev_err(dev, "Failed to acquire clock 'sys'\n");
427 return PTR_ERR(i2s->clk_sys);
428 }
429
430 ret = clk_prepare_enable(i2s->clk_sys);
431 if (ret)
432 return ret;
433
434 i2s->active_channels = 1;
435 i2s->dma_data.addr = res->start + IMG_I2S_IN_RX_FIFO;
436 i2s->dma_data.addr_width = 4;
437
438 i2s->dai_driver.probe = img_i2s_in_dai_probe;
439 i2s->dai_driver.capture.channels_min = 2;
440 i2s->dai_driver.capture.channels_max = i2s->max_i2s_chan * 2;
441 i2s->dai_driver.capture.rates = SNDRV_PCM_RATE_8000_192000;
442 i2s->dai_driver.capture.formats = SNDRV_PCM_FMTBIT_S32_LE |
443 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE;
444 i2s->dai_driver.ops = &img_i2s_in_dai_ops;
445
446 rst = devm_reset_control_get(dev, "rst");
447 if (IS_ERR(rst)) {
448 if (PTR_ERR(rst) == -EPROBE_DEFER) {
449 ret = -EPROBE_DEFER;
450 goto err_clk_disable;
451 }
452
453 dev_dbg(dev, "No top level reset found\n");
454
455 img_i2s_in_disable(i2s);
456
457 for (i = 0; i < i2s->max_i2s_chan; i++)
458 img_i2s_in_ch_disable(i2s, i);
459 } else {
460 reset_control_assert(rst);
461 reset_control_deassert(rst);
462 }
463
464 img_i2s_in_writel(i2s, 0, IMG_I2S_IN_CTL);
465
466 for (i = 0; i < i2s->max_i2s_chan; i++)
467 img_i2s_in_ch_writel(i2s, i,
468 (4 << IMG_I2S_IN_CH_CTL_CCDEL_SHIFT) |
469 IMG_I2S_IN_CH_CTL_JUST_MASK |
470 IMG_I2S_IN_CH_CTL_FW_MASK, IMG_I2S_IN_CH_CTL);
471
472 ret = devm_snd_soc_register_component(dev, &img_i2s_in_component,
473 &i2s->dai_driver, 1);
474 if (ret)
475 goto err_clk_disable;
476
477 ret = devm_snd_dmaengine_pcm_register(dev, &img_i2s_in_dma_config, 0);
478 if (ret)
479 goto err_clk_disable;
480
481 return 0;
482
483err_clk_disable:
484 clk_disable_unprepare(i2s->clk_sys);
485
486 return ret;
487}
488
489static int img_i2s_in_dev_remove(struct platform_device *pdev)
490{
491 struct img_i2s_in *i2s = platform_get_drvdata(pdev);
492
493 clk_disable_unprepare(i2s->clk_sys);
494
495 return 0;
496}
497
498static const struct of_device_id img_i2s_in_of_match[] = {
499 { .compatible = "img,i2s-in" },
500 {}
501};
502MODULE_DEVICE_TABLE(of, img_i2s_in_of_match);
503
504static struct platform_driver img_i2s_in_driver = {
505 .driver = {
506 .name = "img-i2s-in",
507 .of_match_table = img_i2s_in_of_match
508 },
509 .probe = img_i2s_in_probe,
510 .remove = img_i2s_in_dev_remove
511};
512module_platform_driver(img_i2s_in_driver);
513
514MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
515MODULE_DESCRIPTION("IMG I2S Input Driver");
516MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c
new file mode 100644
index 000000000000..5f997135a8ae
--- /dev/null
+++ b/sound/soc/img/img-i2s-out.c
@@ -0,0 +1,565 @@
1/*
2 * IMG I2S output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_I2S_OUT_TX_FIFO 0x0
30
31#define IMG_I2S_OUT_CTL 0x4
32#define IMG_I2S_OUT_CTL_DATA_EN_MASK BIT(24)
33#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK 0xffe000
34#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT 13
35#define IMG_I2S_OUT_CTL_FRM_SIZE_MASK BIT(8)
36#define IMG_I2S_OUT_CTL_MASTER_MASK BIT(6)
37#define IMG_I2S_OUT_CTL_CLK_MASK BIT(5)
38#define IMG_I2S_OUT_CTL_CLK_EN_MASK BIT(4)
39#define IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK BIT(3)
40#define IMG_I2S_OUT_CTL_BCLK_POL_MASK BIT(2)
41#define IMG_I2S_OUT_CTL_ME_MASK BIT(0)
42
43#define IMG_I2S_OUT_CH_CTL 0x4
44#define IMG_I2S_OUT_CHAN_CTL_CH_MASK BIT(11)
45#define IMG_I2S_OUT_CHAN_CTL_LT_MASK BIT(10)
46#define IMG_I2S_OUT_CHAN_CTL_FMT_MASK 0xf0
47#define IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT 4
48#define IMG_I2S_OUT_CHAN_CTL_JUST_MASK BIT(3)
49#define IMG_I2S_OUT_CHAN_CTL_CLKT_MASK BIT(1)
50#define IMG_I2S_OUT_CHAN_CTL_ME_MASK BIT(0)
51
52#define IMG_I2S_OUT_CH_STRIDE 0x20
53
54struct img_i2s_out {
55 void __iomem *base;
56 struct clk *clk_sys;
57 struct clk *clk_ref;
58 struct snd_dmaengine_dai_dma_data dma_data;
59 struct device *dev;
60 unsigned int max_i2s_chan;
61 void __iomem *channel_base;
62 bool force_clk_active;
63 unsigned int active_channels;
64 struct reset_control *rst;
65 struct snd_soc_dai_driver dai_driver;
66};
67
68static int img_i2s_out_suspend(struct device *dev)
69{
70 struct img_i2s_out *i2s = dev_get_drvdata(dev);
71
72 if (!i2s->force_clk_active)
73 clk_disable_unprepare(i2s->clk_ref);
74
75 return 0;
76}
77
78static int img_i2s_out_resume(struct device *dev)
79{
80 struct img_i2s_out *i2s = dev_get_drvdata(dev);
81 int ret;
82
83 if (!i2s->force_clk_active) {
84 ret = clk_prepare_enable(i2s->clk_ref);
85 if (ret) {
86 dev_err(dev, "clk_enable failed: %d\n", ret);
87 return ret;
88 }
89 }
90
91 return 0;
92}
93
94static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
95 u32 reg)
96{
97 writel(val, i2s->base + reg);
98}
99
100static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
101{
102 return readl(i2s->base + reg);
103}
104
105static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
106 u32 chan, u32 val, u32 reg)
107{
108 writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
109}
110
111static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
112 u32 reg)
113{
114 return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
115}
116
117static inline void img_i2s_out_ch_disable(struct img_i2s_out *i2s, u32 chan)
118{
119 u32 reg;
120
121 reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
122 reg &= ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
123 img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
124}
125
126static inline void img_i2s_out_ch_enable(struct img_i2s_out *i2s, u32 chan)
127{
128 u32 reg;
129
130 reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
131 reg |= IMG_I2S_OUT_CHAN_CTL_ME_MASK;
132 img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
133}
134
135static inline void img_i2s_out_disable(struct img_i2s_out *i2s)
136{
137 u32 reg;
138
139 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
140 reg &= ~IMG_I2S_OUT_CTL_ME_MASK;
141 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
142}
143
144static inline void img_i2s_out_enable(struct img_i2s_out *i2s)
145{
146 u32 reg;
147
148 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
149 reg |= IMG_I2S_OUT_CTL_ME_MASK;
150 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
151}
152
153static void img_i2s_out_reset(struct img_i2s_out *i2s)
154{
155 int i;
156 u32 core_ctl, chan_ctl;
157
158 core_ctl = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL) &
159 ~IMG_I2S_OUT_CTL_ME_MASK &
160 ~IMG_I2S_OUT_CTL_DATA_EN_MASK;
161
162 if (!i2s->force_clk_active)
163 core_ctl &= ~IMG_I2S_OUT_CTL_CLK_EN_MASK;
164
165 chan_ctl = img_i2s_out_ch_readl(i2s, 0, IMG_I2S_OUT_CH_CTL) &
166 ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
167
168 reset_control_assert(i2s->rst);
169 reset_control_deassert(i2s->rst);
170
171 for (i = 0; i < i2s->max_i2s_chan; i++)
172 img_i2s_out_ch_writel(i2s, i, chan_ctl, IMG_I2S_OUT_CH_CTL);
173
174 for (i = 0; i < i2s->active_channels; i++)
175 img_i2s_out_ch_enable(i2s, i);
176
177 img_i2s_out_writel(i2s, core_ctl, IMG_I2S_OUT_CTL);
178 img_i2s_out_enable(i2s);
179}
180
181static int img_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd,
182 struct snd_soc_dai *dai)
183{
184 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
185 u32 reg;
186
187 switch (cmd) {
188 case SNDRV_PCM_TRIGGER_START:
189 case SNDRV_PCM_TRIGGER_RESUME:
190 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
191 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
192 if (!i2s->force_clk_active)
193 reg |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
194 reg |= IMG_I2S_OUT_CTL_DATA_EN_MASK;
195 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
196 break;
197 case SNDRV_PCM_TRIGGER_STOP:
198 case SNDRV_PCM_TRIGGER_SUSPEND:
199 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
200 img_i2s_out_reset(i2s);
201 break;
202 default:
203 return -EINVAL;
204 }
205
206 return 0;
207}
208
209static int img_i2s_out_hw_params(struct snd_pcm_substream *substream,
210 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
211{
212 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
213 unsigned int channels, i2s_channels;
214 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
215 int i;
216 u32 reg, control_mask, control_set = 0;
217 snd_pcm_format_t format;
218
219 rate = params_rate(params);
220 format = params_format(params);
221 channels = params_channels(params);
222 i2s_channels = channels / 2;
223
224 if (format != SNDRV_PCM_FORMAT_S32_LE)
225 return -EINVAL;
226
227 if ((channels < 2) ||
228 (channels > (i2s->max_i2s_chan * 2)) ||
229 (channels % 2))
230 return -EINVAL;
231
232 pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
233 if (pre_div_a < 0)
234 return pre_div_a;
235 pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
236 if (pre_div_b < 0)
237 return pre_div_b;
238
239 diff_a = abs((pre_div_a / 256) - rate);
240 diff_b = abs((pre_div_b / 384) - rate);
241
242 /* If diffs are equal, use lower clock rate */
243 if (diff_a > diff_b)
244 clk_set_rate(i2s->clk_ref, pre_div_b);
245 else
246 clk_set_rate(i2s->clk_ref, pre_div_a);
247
248 /*
249 * Another driver (eg alsa machine driver) may have rejected the above
250 * change. Get the current rate and set the register bit according to
251 * the new minimum diff
252 */
253 clk_rate = clk_get_rate(i2s->clk_ref);
254
255 diff_a = abs((clk_rate / 256) - rate);
256 diff_b = abs((clk_rate / 384) - rate);
257
258 if (diff_a > diff_b)
259 control_set |= IMG_I2S_OUT_CTL_CLK_MASK;
260
261 control_set |= ((i2s_channels - 1) <<
262 IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
263 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
264
265 control_mask = IMG_I2S_OUT_CTL_CLK_MASK |
266 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
267
268 img_i2s_out_disable(i2s);
269
270 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
271 reg = (reg & ~control_mask) | control_set;
272 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
273
274 for (i = 0; i < i2s_channels; i++)
275 img_i2s_out_ch_enable(i2s, i);
276
277 for (; i < i2s->max_i2s_chan; i++)
278 img_i2s_out_ch_disable(i2s, i);
279
280 img_i2s_out_enable(i2s);
281
282 i2s->active_channels = i2s_channels;
283
284 return 0;
285}
286
287static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
288{
289 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
290 int i;
291 bool force_clk_active;
292 u32 chan_control_mask, control_mask, chan_control_set = 0;
293 u32 reg, control_set = 0;
294
295 force_clk_active = ((fmt & SND_SOC_DAIFMT_CLOCK_MASK) ==
296 SND_SOC_DAIFMT_CONT);
297
298 if (force_clk_active)
299 control_set |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
300
301 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
302 case SND_SOC_DAIFMT_CBM_CFM:
303 break;
304 case SND_SOC_DAIFMT_CBS_CFS:
305 control_set |= IMG_I2S_OUT_CTL_MASTER_MASK;
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
312 case SND_SOC_DAIFMT_NB_NF:
313 control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
314 break;
315 case SND_SOC_DAIFMT_NB_IF:
316 control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
317 control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
318 break;
319 case SND_SOC_DAIFMT_IB_NF:
320 break;
321 case SND_SOC_DAIFMT_IB_IF:
322 control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
329 case SND_SOC_DAIFMT_I2S:
330 chan_control_set |= IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
331 break;
332 case SND_SOC_DAIFMT_LEFT_J:
333 break;
334 default:
335 return -EINVAL;
336 }
337
338 control_mask = IMG_I2S_OUT_CTL_CLK_EN_MASK |
339 IMG_I2S_OUT_CTL_MASTER_MASK |
340 IMG_I2S_OUT_CTL_BCLK_POL_MASK |
341 IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
342
343 chan_control_mask = IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
344
345 img_i2s_out_disable(i2s);
346
347 reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
348 reg = (reg & ~control_mask) | control_set;
349 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
350
351 for (i = 0; i < i2s->active_channels; i++)
352 img_i2s_out_ch_disable(i2s, i);
353
354 for (i = 0; i < i2s->max_i2s_chan; i++) {
355 reg = img_i2s_out_ch_readl(i2s, i, IMG_I2S_OUT_CH_CTL);
356 reg = (reg & ~chan_control_mask) | chan_control_set;
357 img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
358 }
359
360 for (i = 0; i < i2s->active_channels; i++)
361 img_i2s_out_ch_enable(i2s, i);
362
363 img_i2s_out_enable(i2s);
364
365 i2s->force_clk_active = force_clk_active;
366
367 return 0;
368}
369
370static const struct snd_soc_dai_ops img_i2s_out_dai_ops = {
371 .trigger = img_i2s_out_trigger,
372 .hw_params = img_i2s_out_hw_params,
373 .set_fmt = img_i2s_out_set_fmt
374};
375
376static int img_i2s_out_dai_probe(struct snd_soc_dai *dai)
377{
378 struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
379
380 snd_soc_dai_init_dma_data(dai, &i2s->dma_data, NULL);
381
382 return 0;
383}
384
385static const struct snd_soc_component_driver img_i2s_out_component = {
386 .name = "img-i2s-out"
387};
388
389static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st,
390 struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
391{
392 unsigned int i2s_channels = params_channels(params) / 2;
393 struct snd_soc_pcm_runtime *rtd = st->private_data;
394 struct snd_dmaengine_dai_dma_data *dma_data;
395 int ret;
396
397 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
398
399 ret = snd_hwparams_to_dma_slave_config(st, params, sc);
400 if (ret)
401 return ret;
402
403 sc->dst_addr = dma_data->addr;
404 sc->dst_addr_width = dma_data->addr_width;
405 sc->dst_maxburst = 4 * i2s_channels;
406
407 return 0;
408}
409
410static const struct snd_dmaengine_pcm_config img_i2s_out_dma_config = {
411 .prepare_slave_config = img_i2s_out_dma_prepare_slave_config
412};
413
414static int img_i2s_out_probe(struct platform_device *pdev)
415{
416 struct img_i2s_out *i2s;
417 struct resource *res;
418 void __iomem *base;
419 int i, ret;
420 unsigned int max_i2s_chan_pow_2;
421 u32 reg;
422 struct device *dev = &pdev->dev;
423
424 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
425 if (!i2s)
426 return -ENOMEM;
427
428 platform_set_drvdata(pdev, i2s);
429
430 i2s->dev = &pdev->dev;
431
432 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
433 base = devm_ioremap_resource(&pdev->dev, res);
434 if (IS_ERR(base))
435 return PTR_ERR(base);
436
437 i2s->base = base;
438
439 if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
440 &i2s->max_i2s_chan)) {
441 dev_err(&pdev->dev, "No img,i2s-channels property\n");
442 return -EINVAL;
443 }
444
445 max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
446
447 i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
448
449 i2s->rst = devm_reset_control_get(&pdev->dev, "rst");
450 if (IS_ERR(i2s->rst)) {
451 if (PTR_ERR(i2s->rst) != -EPROBE_DEFER)
452 dev_err(&pdev->dev, "No top level reset found\n");
453 return PTR_ERR(i2s->rst);
454 }
455
456 i2s->clk_sys = devm_clk_get(&pdev->dev, "sys");
457 if (IS_ERR(i2s->clk_sys)) {
458 if (PTR_ERR(i2s->clk_sys) != -EPROBE_DEFER)
459 dev_err(dev, "Failed to acquire clock 'sys'\n");
460 return PTR_ERR(i2s->clk_sys);
461 }
462
463 i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
464 if (IS_ERR(i2s->clk_ref)) {
465 if (PTR_ERR(i2s->clk_ref) != -EPROBE_DEFER)
466 dev_err(dev, "Failed to acquire clock 'ref'\n");
467 return PTR_ERR(i2s->clk_ref);
468 }
469
470 ret = clk_prepare_enable(i2s->clk_sys);
471 if (ret)
472 return ret;
473
474 reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK;
475 img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
476
477 reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK |
478 IMG_I2S_OUT_CHAN_CTL_LT_MASK |
479 IMG_I2S_OUT_CHAN_CTL_CH_MASK |
480 (8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT);
481
482 for (i = 0; i < i2s->max_i2s_chan; i++)
483 img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
484
485 img_i2s_out_reset(i2s);
486
487 pm_runtime_enable(&pdev->dev);
488 if (!pm_runtime_enabled(&pdev->dev)) {
489 ret = img_i2s_out_resume(&pdev->dev);
490 if (ret)
491 goto err_pm_disable;
492 }
493
494 i2s->active_channels = 1;
495 i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO;
496 i2s->dma_data.addr_width = 4;
497 i2s->dma_data.maxburst = 4;
498
499 i2s->dai_driver.probe = img_i2s_out_dai_probe;
500 i2s->dai_driver.playback.channels_min = 2;
501 i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2;
502 i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000;
503 i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE;
504 i2s->dai_driver.ops = &img_i2s_out_dai_ops;
505
506 ret = devm_snd_soc_register_component(&pdev->dev,
507 &img_i2s_out_component, &i2s->dai_driver, 1);
508 if (ret)
509 goto err_suspend;
510
511 ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
512 &img_i2s_out_dma_config, 0);
513 if (ret)
514 goto err_suspend;
515
516 return 0;
517
518err_suspend:
519 if (!pm_runtime_status_suspended(&pdev->dev))
520 img_i2s_out_suspend(&pdev->dev);
521err_pm_disable:
522 pm_runtime_disable(&pdev->dev);
523 clk_disable_unprepare(i2s->clk_sys);
524
525 return ret;
526}
527
528static int img_i2s_out_dev_remove(struct platform_device *pdev)
529{
530 struct img_i2s_out *i2s = platform_get_drvdata(pdev);
531
532 pm_runtime_disable(&pdev->dev);
533 if (!pm_runtime_status_suspended(&pdev->dev))
534 img_i2s_out_suspend(&pdev->dev);
535
536 clk_disable_unprepare(i2s->clk_sys);
537
538 return 0;
539}
540
541static const struct of_device_id img_i2s_out_of_match[] = {
542 { .compatible = "img,i2s-out" },
543 {}
544};
545MODULE_DEVICE_TABLE(of, img_i2s_out_of_match);
546
547static const struct dev_pm_ops img_i2s_out_pm_ops = {
548 SET_RUNTIME_PM_OPS(img_i2s_out_suspend,
549 img_i2s_out_resume, NULL)
550};
551
552static struct platform_driver img_i2s_out_driver = {
553 .driver = {
554 .name = "img-i2s-out",
555 .of_match_table = img_i2s_out_of_match,
556 .pm = &img_i2s_out_pm_ops
557 },
558 .probe = img_i2s_out_probe,
559 .remove = img_i2s_out_dev_remove
560};
561module_platform_driver(img_i2s_out_driver);
562
563MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
564MODULE_DESCRIPTION("IMG I2S Output Driver");
565MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c
new file mode 100644
index 000000000000..c1610a054d65
--- /dev/null
+++ b/sound/soc/img/img-parallel-out.c
@@ -0,0 +1,327 @@
1/*
2 * IMG parallel output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_PRL_OUT_TX_FIFO 0
30
31#define IMG_PRL_OUT_CTL 0x4
32#define IMG_PRL_OUT_CTL_CH_MASK BIT(4)
33#define IMG_PRL_OUT_CTL_PACKH_MASK BIT(3)
34#define IMG_PRL_OUT_CTL_EDGE_MASK BIT(2)
35#define IMG_PRL_OUT_CTL_ME_MASK BIT(1)
36#define IMG_PRL_OUT_CTL_SRST_MASK BIT(0)
37
38struct img_prl_out {
39 void __iomem *base;
40 struct clk *clk_sys;
41 struct clk *clk_ref;
42 struct snd_dmaengine_dai_dma_data dma_data;
43 struct device *dev;
44 struct reset_control *rst;
45};
46
47static int img_prl_out_suspend(struct device *dev)
48{
49 struct img_prl_out *prl = dev_get_drvdata(dev);
50
51 clk_disable_unprepare(prl->clk_ref);
52
53 return 0;
54}
55
56static int img_prl_out_resume(struct device *dev)
57{
58 struct img_prl_out *prl = dev_get_drvdata(dev);
59 int ret;
60
61 ret = clk_prepare_enable(prl->clk_ref);
62 if (ret) {
63 dev_err(dev, "clk_enable failed: %d\n", ret);
64 return ret;
65 }
66
67 return 0;
68}
69
70static inline void img_prl_out_writel(struct img_prl_out *prl,
71 u32 val, u32 reg)
72{
73 writel(val, prl->base + reg);
74}
75
76static inline u32 img_prl_out_readl(struct img_prl_out *prl, u32 reg)
77{
78 return readl(prl->base + reg);
79}
80
81static void img_prl_out_reset(struct img_prl_out *prl)
82{
83 u32 ctl;
84
85 ctl = img_prl_out_readl(prl, IMG_PRL_OUT_CTL) &
86 ~IMG_PRL_OUT_CTL_ME_MASK;
87
88 reset_control_assert(prl->rst);
89 reset_control_deassert(prl->rst);
90
91 img_prl_out_writel(prl, ctl, IMG_PRL_OUT_CTL);
92}
93
94static int img_prl_out_trigger(struct snd_pcm_substream *substream, int cmd,
95 struct snd_soc_dai *dai)
96{
97 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
98 u32 reg;
99
100 switch (cmd) {
101 case SNDRV_PCM_TRIGGER_START:
102 case SNDRV_PCM_TRIGGER_RESUME:
103 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
104 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
105 reg |= IMG_PRL_OUT_CTL_ME_MASK;
106 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
107 break;
108 case SNDRV_PCM_TRIGGER_STOP:
109 case SNDRV_PCM_TRIGGER_SUSPEND:
110 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
111 img_prl_out_reset(prl);
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120static int img_prl_out_hw_params(struct snd_pcm_substream *substream,
121 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
122{
123 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
124 unsigned int rate, channels;
125 u32 reg, control_set = 0;
126 snd_pcm_format_t format;
127
128 rate = params_rate(params);
129 format = params_format(params);
130 channels = params_channels(params);
131
132 switch (params_format(params)) {
133 case SNDRV_PCM_FORMAT_S32_LE:
134 control_set |= IMG_PRL_OUT_CTL_PACKH_MASK;
135 break;
136 case SNDRV_PCM_FORMAT_S24_LE:
137 break;
138 default:
139 return -EINVAL;
140 }
141
142 if (channels != 2)
143 return -EINVAL;
144
145 clk_set_rate(prl->clk_ref, rate * 256);
146
147 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
148 reg = (reg & ~IMG_PRL_OUT_CTL_PACKH_MASK) | control_set;
149 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
150
151 return 0;
152}
153
154static int img_prl_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
155{
156 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
157 u32 reg, control_set = 0;
158
159 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
160 case SND_SOC_DAIFMT_NB_NF:
161 break;
162 case SND_SOC_DAIFMT_NB_IF:
163 control_set |= IMG_PRL_OUT_CTL_EDGE_MASK;
164 break;
165 default:
166 return -EINVAL;
167 }
168
169 reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
170 reg = (reg & ~IMG_PRL_OUT_CTL_EDGE_MASK) | control_set;
171 img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
172
173 return 0;
174}
175
176static const struct snd_soc_dai_ops img_prl_out_dai_ops = {
177 .trigger = img_prl_out_trigger,
178 .hw_params = img_prl_out_hw_params,
179 .set_fmt = img_prl_out_set_fmt
180};
181
182static int img_prl_out_dai_probe(struct snd_soc_dai *dai)
183{
184 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
185
186 snd_soc_dai_init_dma_data(dai, &prl->dma_data, NULL);
187
188 return 0;
189}
190
191static struct snd_soc_dai_driver img_prl_out_dai = {
192 .probe = img_prl_out_dai_probe,
193 .playback = {
194 .channels_min = 2,
195 .channels_max = 2,
196 .rates = SNDRV_PCM_RATE_8000_192000,
197 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE
198 },
199 .ops = &img_prl_out_dai_ops
200};
201
202static const struct snd_soc_component_driver img_prl_out_component = {
203 .name = "img-prl-out"
204};
205
206static int img_prl_out_probe(struct platform_device *pdev)
207{
208 struct img_prl_out *prl;
209 struct resource *res;
210 void __iomem *base;
211 int ret;
212 struct device *dev = &pdev->dev;
213
214 prl = devm_kzalloc(&pdev->dev, sizeof(*prl), GFP_KERNEL);
215 if (!prl)
216 return -ENOMEM;
217
218 platform_set_drvdata(pdev, prl);
219
220 prl->dev = &pdev->dev;
221
222 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
223 base = devm_ioremap_resource(&pdev->dev, res);
224 if (IS_ERR(base))
225 return PTR_ERR(base);
226
227 prl->base = base;
228
229 prl->rst = devm_reset_control_get(&pdev->dev, "rst");
230 if (IS_ERR(prl->rst)) {
231 if (PTR_ERR(prl->rst) != -EPROBE_DEFER)
232 dev_err(&pdev->dev, "No top level reset found\n");
233 return PTR_ERR(prl->rst);
234 }
235
236 prl->clk_sys = devm_clk_get(&pdev->dev, "sys");
237 if (IS_ERR(prl->clk_sys)) {
238 if (PTR_ERR(prl->clk_sys) != -EPROBE_DEFER)
239 dev_err(dev, "Failed to acquire clock 'sys'\n");
240 return PTR_ERR(prl->clk_sys);
241 }
242
243 prl->clk_ref = devm_clk_get(&pdev->dev, "ref");
244 if (IS_ERR(prl->clk_ref)) {
245 if (PTR_ERR(prl->clk_ref) != -EPROBE_DEFER)
246 dev_err(dev, "Failed to acquire clock 'ref'\n");
247 return PTR_ERR(prl->clk_ref);
248 }
249
250 ret = clk_prepare_enable(prl->clk_sys);
251 if (ret)
252 return ret;
253
254 img_prl_out_writel(prl, IMG_PRL_OUT_CTL_EDGE_MASK, IMG_PRL_OUT_CTL);
255 img_prl_out_reset(prl);
256
257 pm_runtime_enable(&pdev->dev);
258 if (!pm_runtime_enabled(&pdev->dev)) {
259 ret = img_prl_out_resume(&pdev->dev);
260 if (ret)
261 goto err_pm_disable;
262 }
263
264 prl->dma_data.addr = res->start + IMG_PRL_OUT_TX_FIFO;
265 prl->dma_data.addr_width = 4;
266 prl->dma_data.maxburst = 4;
267
268 ret = devm_snd_soc_register_component(&pdev->dev,
269 &img_prl_out_component,
270 &img_prl_out_dai, 1);
271 if (ret)
272 goto err_suspend;
273
274 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
275 if (ret)
276 goto err_suspend;
277
278 return 0;
279
280err_suspend:
281 if (!pm_runtime_status_suspended(&pdev->dev))
282 img_prl_out_suspend(&pdev->dev);
283err_pm_disable:
284 pm_runtime_disable(&pdev->dev);
285 clk_disable_unprepare(prl->clk_sys);
286
287 return ret;
288}
289
290static int img_prl_out_dev_remove(struct platform_device *pdev)
291{
292 struct img_prl_out *prl = platform_get_drvdata(pdev);
293
294 pm_runtime_disable(&pdev->dev);
295 if (!pm_runtime_status_suspended(&pdev->dev))
296 img_prl_out_suspend(&pdev->dev);
297
298 clk_disable_unprepare(prl->clk_sys);
299
300 return 0;
301}
302
303static const struct of_device_id img_prl_out_of_match[] = {
304 { .compatible = "img,parallel-out" },
305 {}
306};
307MODULE_DEVICE_TABLE(of, img_prl_out_of_match);
308
309static const struct dev_pm_ops img_prl_out_pm_ops = {
310 SET_RUNTIME_PM_OPS(img_prl_out_suspend,
311 img_prl_out_resume, NULL)
312};
313
314static struct platform_driver img_prl_out_driver = {
315 .driver = {
316 .name = "img-parallel-out",
317 .of_match_table = img_prl_out_of_match,
318 .pm = &img_prl_out_pm_ops
319 },
320 .probe = img_prl_out_probe,
321 .remove = img_prl_out_dev_remove
322};
323module_platform_driver(img_prl_out_driver);
324
325MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
326MODULE_DESCRIPTION("IMG Parallel Output Driver");
327MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
new file mode 100644
index 000000000000..4d9953d318af
--- /dev/null
+++ b/sound/soc/img/img-spdif-in.c
@@ -0,0 +1,806 @@
1/*
2 * IMG SPDIF input controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/reset.h>
20
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/initval.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27
28#define IMG_SPDIF_IN_RX_FIFO_OFFSET 0
29
30#define IMG_SPDIF_IN_CTL 0x4
31#define IMG_SPDIF_IN_CTL_LOCKLO_MASK 0xff
32#define IMG_SPDIF_IN_CTL_LOCKLO_SHIFT 0
33#define IMG_SPDIF_IN_CTL_LOCKHI_MASK 0xff00
34#define IMG_SPDIF_IN_CTL_LOCKHI_SHIFT 8
35#define IMG_SPDIF_IN_CTL_TRK_MASK 0xff0000
36#define IMG_SPDIF_IN_CTL_TRK_SHIFT 16
37#define IMG_SPDIF_IN_CTL_SRD_MASK 0x70000000
38#define IMG_SPDIF_IN_CTL_SRD_SHIFT 28
39#define IMG_SPDIF_IN_CTL_SRT_MASK BIT(31)
40
41#define IMG_SPDIF_IN_STATUS 0x8
42#define IMG_SPDIF_IN_STATUS_SAM_MASK 0x7000
43#define IMG_SPDIF_IN_STATUS_SAM_SHIFT 12
44#define IMG_SPDIF_IN_STATUS_LOCK_MASK BIT(15)
45#define IMG_SPDIF_IN_STATUS_LOCK_SHIFT 15
46
47#define IMG_SPDIF_IN_CLKGEN 0x1c
48#define IMG_SPDIF_IN_CLKGEN_NOM_MASK 0x3ff
49#define IMG_SPDIF_IN_CLKGEN_NOM_SHIFT 0
50#define IMG_SPDIF_IN_CLKGEN_HLD_MASK 0x3ff0000
51#define IMG_SPDIF_IN_CLKGEN_HLD_SHIFT 16
52
53#define IMG_SPDIF_IN_CSL 0x20
54
55#define IMG_SPDIF_IN_CSH 0x24
56#define IMG_SPDIF_IN_CSH_MASK 0xff
57#define IMG_SPDIF_IN_CSH_SHIFT 0
58
59#define IMG_SPDIF_IN_SOFT_RESET 0x28
60#define IMG_SPDIF_IN_SOFT_RESET_MASK BIT(0)
61
62#define IMG_SPDIF_IN_ACLKGEN_START 0x2c
63#define IMG_SPDIF_IN_ACLKGEN_NOM_MASK 0x3ff
64#define IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT 0
65#define IMG_SPDIF_IN_ACLKGEN_HLD_MASK 0xffc00
66#define IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT 10
67#define IMG_SPDIF_IN_ACLKGEN_TRK_MASK 0xff00000
68#define IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT 20
69
70#define IMG_SPDIF_IN_NUM_ACLKGEN 4
71
72struct img_spdif_in {
73 spinlock_t lock;
74 void __iomem *base;
75 struct clk *clk_sys;
76 struct snd_dmaengine_dai_dma_data dma_data;
77 struct device *dev;
78 unsigned int trk;
79 bool multi_freq;
80 int lock_acquire;
81 int lock_release;
82 unsigned int single_freq;
83 unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
84 bool active;
85
86 /* Write-only registers */
87 unsigned int aclkgen_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
88};
89
90static inline void img_spdif_in_writel(struct img_spdif_in *spdif,
91 u32 val, u32 reg)
92{
93 writel(val, spdif->base + reg);
94}
95
96static inline u32 img_spdif_in_readl(struct img_spdif_in *spdif, u32 reg)
97{
98 return readl(spdif->base + reg);
99}
100
101static inline void img_spdif_in_aclkgen_writel(struct img_spdif_in *spdif,
102 u32 index)
103{
104 img_spdif_in_writel(spdif, spdif->aclkgen_regs[index],
105 IMG_SPDIF_IN_ACLKGEN_START + (index * 0x4));
106}
107
108static int img_spdif_in_check_max_rate(struct img_spdif_in *spdif,
109 unsigned int sample_rate, unsigned long *actual_freq)
110{
111 unsigned long min_freq, freq_t;
112
113 /* Clock rate must be at least 24x the bit rate */
114 min_freq = sample_rate * 2 * 32 * 24;
115
116 freq_t = clk_get_rate(spdif->clk_sys);
117
118 if (freq_t < min_freq)
119 return -EINVAL;
120
121 *actual_freq = freq_t;
122
123 return 0;
124}
125
126static int img_spdif_in_do_clkgen_calc(unsigned int rate, unsigned int *pnom,
127 unsigned int *phld, unsigned long clk_rate)
128{
129 unsigned int ori, nom, hld;
130
131 /*
132 * Calculate oversampling ratio, nominal phase increment and hold
133 * increment for the given rate / frequency
134 */
135
136 if (!rate)
137 return -EINVAL;
138
139 ori = clk_rate / (rate * 64);
140
141 if (!ori)
142 return -EINVAL;
143
144 nom = (4096 / ori) + 1;
145 do
146 hld = 4096 - (--nom * (ori - 1));
147 while (hld < 120);
148
149 *pnom = nom;
150 *phld = hld;
151
152 return 0;
153}
154
155static int img_spdif_in_do_clkgen_single(struct img_spdif_in *spdif,
156 unsigned int rate)
157{
158 unsigned int nom, hld;
159 unsigned long flags, clk_rate;
160 int ret = 0;
161 u32 reg;
162
163 ret = img_spdif_in_check_max_rate(spdif, rate, &clk_rate);
164 if (ret)
165 return ret;
166
167 ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
168 if (ret)
169 return ret;
170
171 reg = (nom << IMG_SPDIF_IN_CLKGEN_NOM_SHIFT) &
172 IMG_SPDIF_IN_CLKGEN_NOM_MASK;
173 reg |= (hld << IMG_SPDIF_IN_CLKGEN_HLD_SHIFT) &
174 IMG_SPDIF_IN_CLKGEN_HLD_MASK;
175
176 spin_lock_irqsave(&spdif->lock, flags);
177
178 if (spdif->active) {
179 spin_unlock_irqrestore(&spdif->lock, flags);
180 return -EBUSY;
181 }
182
183 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CLKGEN);
184
185 spdif->single_freq = rate;
186
187 spin_unlock_irqrestore(&spdif->lock, flags);
188
189 return 0;
190}
191
192static int img_spdif_in_do_clkgen_multi(struct img_spdif_in *spdif,
193 unsigned int multi_freqs[])
194{
195 unsigned int nom, hld, rate, max_rate = 0;
196 unsigned long flags, clk_rate;
197 int i, ret = 0;
198 u32 reg, trk_reg, temp_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
199
200 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++)
201 if (multi_freqs[i] > max_rate)
202 max_rate = multi_freqs[i];
203
204 ret = img_spdif_in_check_max_rate(spdif, max_rate, &clk_rate);
205 if (ret)
206 return ret;
207
208 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
209 rate = multi_freqs[i];
210
211 ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
212 if (ret)
213 return ret;
214
215 reg = (nom << IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT) &
216 IMG_SPDIF_IN_ACLKGEN_NOM_MASK;
217 reg |= (hld << IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT) &
218 IMG_SPDIF_IN_ACLKGEN_HLD_MASK;
219 temp_regs[i] = reg;
220 }
221
222 spin_lock_irqsave(&spdif->lock, flags);
223
224 if (spdif->active) {
225 spin_unlock_irqrestore(&spdif->lock, flags);
226 return -EBUSY;
227 }
228
229 trk_reg = spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT;
230
231 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
232 spdif->aclkgen_regs[i] = temp_regs[i] | trk_reg;
233 img_spdif_in_aclkgen_writel(spdif, i);
234 }
235
236 spdif->multi_freq = true;
237 spdif->multi_freqs[0] = multi_freqs[0];
238 spdif->multi_freqs[1] = multi_freqs[1];
239 spdif->multi_freqs[2] = multi_freqs[2];
240 spdif->multi_freqs[3] = multi_freqs[3];
241
242 spin_unlock_irqrestore(&spdif->lock, flags);
243
244 return 0;
245}
246
247static int img_spdif_in_iec958_info(struct snd_kcontrol *kcontrol,
248 struct snd_ctl_elem_info *uinfo)
249{
250 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
251 uinfo->count = 1;
252
253 return 0;
254}
255
256static int img_spdif_in_get_status_mask(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
258{
259 ucontrol->value.iec958.status[0] = 0xff;
260 ucontrol->value.iec958.status[1] = 0xff;
261 ucontrol->value.iec958.status[2] = 0xff;
262 ucontrol->value.iec958.status[3] = 0xff;
263 ucontrol->value.iec958.status[4] = 0xff;
264
265 return 0;
266}
267
268static int img_spdif_in_get_status(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
272 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
273 u32 reg;
274
275 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSL);
276 ucontrol->value.iec958.status[0] = reg & 0xff;
277 ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
278 ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
279 ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
280 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSH);
281 ucontrol->value.iec958.status[4] = (reg & IMG_SPDIF_IN_CSH_MASK)
282 >> IMG_SPDIF_IN_CSH_SHIFT;
283
284 return 0;
285}
286
287static int img_spdif_in_info_multi_freq(struct snd_kcontrol *kcontrol,
288 struct snd_ctl_elem_info *uinfo)
289{
290 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
291 uinfo->count = IMG_SPDIF_IN_NUM_ACLKGEN;
292 uinfo->value.integer.min = 0;
293 uinfo->value.integer.max = LONG_MAX;
294
295 return 0;
296}
297
298static int img_spdif_in_get_multi_freq(struct snd_kcontrol *kcontrol,
299 struct snd_ctl_elem_value *ucontrol)
300{
301 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
302 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
303 unsigned long flags;
304
305 spin_lock_irqsave(&spdif->lock, flags);
306 if (spdif->multi_freq) {
307 ucontrol->value.integer.value[0] = spdif->multi_freqs[0];
308 ucontrol->value.integer.value[1] = spdif->multi_freqs[1];
309 ucontrol->value.integer.value[2] = spdif->multi_freqs[2];
310 ucontrol->value.integer.value[3] = spdif->multi_freqs[3];
311 } else {
312 ucontrol->value.integer.value[0] = 0;
313 ucontrol->value.integer.value[1] = 0;
314 ucontrol->value.integer.value[2] = 0;
315 ucontrol->value.integer.value[3] = 0;
316 }
317 spin_unlock_irqrestore(&spdif->lock, flags);
318
319 return 0;
320}
321
322static int img_spdif_in_set_multi_freq(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
324{
325 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
326 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
327 unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
328 bool multi_freq;
329 unsigned long flags;
330
331 if ((ucontrol->value.integer.value[0] == 0) &&
332 (ucontrol->value.integer.value[1] == 0) &&
333 (ucontrol->value.integer.value[2] == 0) &&
334 (ucontrol->value.integer.value[3] == 0)) {
335 multi_freq = false;
336 } else {
337 multi_freqs[0] = ucontrol->value.integer.value[0];
338 multi_freqs[1] = ucontrol->value.integer.value[1];
339 multi_freqs[2] = ucontrol->value.integer.value[2];
340 multi_freqs[3] = ucontrol->value.integer.value[3];
341 multi_freq = true;
342 }
343
344 if (multi_freq)
345 return img_spdif_in_do_clkgen_multi(spdif, multi_freqs);
346
347 spin_lock_irqsave(&spdif->lock, flags);
348
349 if (spdif->active) {
350 spin_unlock_irqrestore(&spdif->lock, flags);
351 return -EBUSY;
352 }
353
354 spdif->multi_freq = false;
355
356 spin_unlock_irqrestore(&spdif->lock, flags);
357
358 return 0;
359}
360
361static int img_spdif_in_info_lock_freq(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_info *uinfo)
363{
364 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
365 uinfo->count = 1;
366 uinfo->value.integer.min = 0;
367 uinfo->value.integer.max = LONG_MAX;
368
369 return 0;
370}
371
372static int img_spdif_in_get_lock_freq(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *uc)
374{
375 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
376 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
377 u32 reg;
378 int i;
379 unsigned long flags;
380
381 spin_lock_irqsave(&spdif->lock, flags);
382
383 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_STATUS);
384 if (reg & IMG_SPDIF_IN_STATUS_LOCK_MASK) {
385 if (spdif->multi_freq) {
386 i = ((reg & IMG_SPDIF_IN_STATUS_SAM_MASK) >>
387 IMG_SPDIF_IN_STATUS_SAM_SHIFT) - 1;
388 uc->value.integer.value[0] = spdif->multi_freqs[i];
389 } else {
390 uc->value.integer.value[0] = spdif->single_freq;
391 }
392 } else {
393 uc->value.integer.value[0] = 0;
394 }
395
396 spin_unlock_irqrestore(&spdif->lock, flags);
397
398 return 0;
399}
400
401static int img_spdif_in_info_trk(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_info *uinfo)
403{
404 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
405 uinfo->count = 1;
406 uinfo->value.integer.min = 0;
407 uinfo->value.integer.max = 255;
408
409 return 0;
410}
411
412static int img_spdif_in_get_trk(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414{
415 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
416 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
417
418 ucontrol->value.integer.value[0] = spdif->trk;
419
420 return 0;
421}
422
423static int img_spdif_in_set_trk(struct snd_kcontrol *kcontrol,
424 struct snd_ctl_elem_value *ucontrol)
425{
426 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
427 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
428 unsigned long flags;
429 int i;
430 u32 reg;
431
432 spin_lock_irqsave(&spdif->lock, flags);
433
434 if (spdif->active) {
435 spin_unlock_irqrestore(&spdif->lock, flags);
436 return -EBUSY;
437 }
438
439 spdif->trk = ucontrol->value.integer.value[0];
440
441 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
442 reg &= ~IMG_SPDIF_IN_CTL_TRK_MASK;
443 reg |= spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT;
444 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
445
446 for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
447 spdif->aclkgen_regs[i] = (spdif->aclkgen_regs[i] &
448 ~IMG_SPDIF_IN_ACLKGEN_TRK_MASK) |
449 (spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT);
450
451 img_spdif_in_aclkgen_writel(spdif, i);
452 }
453
454 spin_unlock_irqrestore(&spdif->lock, flags);
455
456 return 0;
457}
458
459static int img_spdif_in_info_lock(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_info *uinfo)
461{
462 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
463 uinfo->count = 1;
464 uinfo->value.integer.min = -128;
465 uinfo->value.integer.max = 127;
466
467 return 0;
468}
469
470static int img_spdif_in_get_lock_acquire(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
472{
473 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
474 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
475
476 ucontrol->value.integer.value[0] = spdif->lock_acquire;
477
478 return 0;
479}
480
481static int img_spdif_in_set_lock_acquire(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
483{
484 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
485 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
486 unsigned long flags;
487 u32 reg;
488
489 spin_lock_irqsave(&spdif->lock, flags);
490
491 if (spdif->active) {
492 spin_unlock_irqrestore(&spdif->lock, flags);
493 return -EBUSY;
494 }
495
496 spdif->lock_acquire = ucontrol->value.integer.value[0];
497
498 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
499 reg &= ~IMG_SPDIF_IN_CTL_LOCKHI_MASK;
500 reg |= (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
501 IMG_SPDIF_IN_CTL_LOCKHI_MASK;
502 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
503
504 spin_unlock_irqrestore(&spdif->lock, flags);
505
506 return 0;
507}
508
509static int img_spdif_in_get_lock_release(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
513 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
514
515 ucontrol->value.integer.value[0] = spdif->lock_release;
516
517 return 0;
518}
519
520static int img_spdif_in_set_lock_release(struct snd_kcontrol *kcontrol,
521 struct snd_ctl_elem_value *ucontrol)
522{
523 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
524 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
525 unsigned long flags;
526 u32 reg;
527
528 spin_lock_irqsave(&spdif->lock, flags);
529
530 if (spdif->active) {
531 spin_unlock_irqrestore(&spdif->lock, flags);
532 return -EBUSY;
533 }
534
535 spdif->lock_release = ucontrol->value.integer.value[0];
536
537 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
538 reg &= ~IMG_SPDIF_IN_CTL_LOCKLO_MASK;
539 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
540 IMG_SPDIF_IN_CTL_LOCKLO_MASK;
541 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
542
543 spin_unlock_irqrestore(&spdif->lock, flags);
544
545 return 0;
546}
547
548static struct snd_kcontrol_new img_spdif_in_controls[] = {
549 {
550 .access = SNDRV_CTL_ELEM_ACCESS_READ,
551 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
552 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
553 .info = img_spdif_in_iec958_info,
554 .get = img_spdif_in_get_status_mask
555 },
556 {
557 .access = SNDRV_CTL_ELEM_ACCESS_READ |
558 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
559 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
560 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
561 .info = img_spdif_in_iec958_info,
562 .get = img_spdif_in_get_status
563 },
564 {
565 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
566 .name = "SPDIF In Multi Frequency Acquire",
567 .info = img_spdif_in_info_multi_freq,
568 .get = img_spdif_in_get_multi_freq,
569 .put = img_spdif_in_set_multi_freq
570 },
571 {
572 .access = SNDRV_CTL_ELEM_ACCESS_READ |
573 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
574 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
575 .name = "SPDIF In Lock Frequency",
576 .info = img_spdif_in_info_lock_freq,
577 .get = img_spdif_in_get_lock_freq
578 },
579 {
580 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
581 .name = "SPDIF In Lock TRK",
582 .info = img_spdif_in_info_trk,
583 .get = img_spdif_in_get_trk,
584 .put = img_spdif_in_set_trk
585 },
586 {
587 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
588 .name = "SPDIF In Lock Acquire Threshold",
589 .info = img_spdif_in_info_lock,
590 .get = img_spdif_in_get_lock_acquire,
591 .put = img_spdif_in_set_lock_acquire
592 },
593 {
594 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
595 .name = "SPDIF In Lock Release Threshold",
596 .info = img_spdif_in_info_lock,
597 .get = img_spdif_in_get_lock_release,
598 .put = img_spdif_in_set_lock_release
599 }
600};
601
602static int img_spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
603 struct snd_soc_dai *dai)
604{
605 unsigned long flags;
606 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
607 int ret = 0;
608 u32 reg;
609
610 spin_lock_irqsave(&spdif->lock, flags);
611
612 switch (cmd) {
613 case SNDRV_PCM_TRIGGER_START:
614 case SNDRV_PCM_TRIGGER_RESUME:
615 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
616 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
617 if (spdif->multi_freq)
618 reg &= ~IMG_SPDIF_IN_CTL_SRD_MASK;
619 else
620 reg |= (1UL << IMG_SPDIF_IN_CTL_SRD_SHIFT);
621 reg |= IMG_SPDIF_IN_CTL_SRT_MASK;
622 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
623 spdif->active = true;
624 break;
625 case SNDRV_PCM_TRIGGER_STOP:
626 case SNDRV_PCM_TRIGGER_SUSPEND:
627 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
628 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
629 reg &= ~IMG_SPDIF_IN_CTL_SRT_MASK;
630 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
631 spdif->active = false;
632 break;
633 default:
634 ret = -EINVAL;
635 }
636
637 spin_unlock_irqrestore(&spdif->lock, flags);
638
639 return ret;
640}
641
642static int img_spdif_in_hw_params(struct snd_pcm_substream *substream,
643 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
644{
645 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
646 unsigned int rate, channels;
647 snd_pcm_format_t format;
648
649 rate = params_rate(params);
650 channels = params_channels(params);
651 format = params_format(params);
652
653 if (format != SNDRV_PCM_FORMAT_S32_LE)
654 return -EINVAL;
655
656 if (channels != 2)
657 return -EINVAL;
658
659 return img_spdif_in_do_clkgen_single(spdif, rate);
660}
661
662static const struct snd_soc_dai_ops img_spdif_in_dai_ops = {
663 .trigger = img_spdif_in_trigger,
664 .hw_params = img_spdif_in_hw_params
665};
666
667static int img_spdif_in_dai_probe(struct snd_soc_dai *dai)
668{
669 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
670
671 snd_soc_dai_init_dma_data(dai, NULL, &spdif->dma_data);
672
673 snd_soc_add_dai_controls(dai, img_spdif_in_controls,
674 ARRAY_SIZE(img_spdif_in_controls));
675
676 return 0;
677}
678
679static struct snd_soc_dai_driver img_spdif_in_dai = {
680 .probe = img_spdif_in_dai_probe,
681 .capture = {
682 .channels_min = 2,
683 .channels_max = 2,
684 .rates = SNDRV_PCM_RATE_8000_192000,
685 .formats = SNDRV_PCM_FMTBIT_S32_LE
686 },
687 .ops = &img_spdif_in_dai_ops
688};
689
690static const struct snd_soc_component_driver img_spdif_in_component = {
691 .name = "img-spdif-in"
692};
693
694static int img_spdif_in_probe(struct platform_device *pdev)
695{
696 struct img_spdif_in *spdif;
697 struct resource *res;
698 void __iomem *base;
699 int ret;
700 struct reset_control *rst;
701 u32 reg;
702 struct device *dev = &pdev->dev;
703
704 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
705 if (!spdif)
706 return -ENOMEM;
707
708 platform_set_drvdata(pdev, spdif);
709
710 spdif->dev = &pdev->dev;
711
712 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
713 base = devm_ioremap_resource(&pdev->dev, res);
714 if (IS_ERR(base))
715 return PTR_ERR(base);
716
717 spdif->base = base;
718
719 spdif->clk_sys = devm_clk_get(dev, "sys");
720 if (IS_ERR(spdif->clk_sys)) {
721 if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER)
722 dev_err(dev, "Failed to acquire clock 'sys'\n");
723 return PTR_ERR(spdif->clk_sys);
724 }
725
726 ret = clk_prepare_enable(spdif->clk_sys);
727 if (ret)
728 return ret;
729
730 rst = devm_reset_control_get(&pdev->dev, "rst");
731 if (IS_ERR(rst)) {
732 if (PTR_ERR(rst) == -EPROBE_DEFER) {
733 ret = -EPROBE_DEFER;
734 goto err_clk_disable;
735 }
736 dev_dbg(dev, "No top level reset found\n");
737 img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK,
738 IMG_SPDIF_IN_SOFT_RESET);
739 img_spdif_in_writel(spdif, 0, IMG_SPDIF_IN_SOFT_RESET);
740 } else {
741 reset_control_assert(rst);
742 reset_control_deassert(rst);
743 }
744
745 spin_lock_init(&spdif->lock);
746
747 spdif->dma_data.addr = res->start + IMG_SPDIF_IN_RX_FIFO_OFFSET;
748 spdif->dma_data.addr_width = 4;
749 spdif->dma_data.maxburst = 4;
750 spdif->trk = 0x80;
751 spdif->lock_acquire = 4;
752 spdif->lock_release = -128;
753
754 reg = (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
755 IMG_SPDIF_IN_CTL_LOCKHI_MASK;
756 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
757 IMG_SPDIF_IN_CTL_LOCKLO_MASK;
758 reg |= (spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT) &
759 IMG_SPDIF_IN_CTL_TRK_MASK;
760 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
761
762 ret = devm_snd_soc_register_component(&pdev->dev,
763 &img_spdif_in_component, &img_spdif_in_dai, 1);
764 if (ret)
765 goto err_clk_disable;
766
767 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
768 if (ret)
769 goto err_clk_disable;
770
771 return 0;
772
773err_clk_disable:
774 clk_disable_unprepare(spdif->clk_sys);
775
776 return ret;
777}
778
779static int img_spdif_in_dev_remove(struct platform_device *pdev)
780{
781 struct img_spdif_in *spdif = platform_get_drvdata(pdev);
782
783 clk_disable_unprepare(spdif->clk_sys);
784
785 return 0;
786}
787
788static const struct of_device_id img_spdif_in_of_match[] = {
789 { .compatible = "img,spdif-in" },
790 {}
791};
792MODULE_DEVICE_TABLE(of, img_spdif_in_of_match);
793
794static struct platform_driver img_spdif_in_driver = {
795 .driver = {
796 .name = "img-spdif-in",
797 .of_match_table = img_spdif_in_of_match
798 },
799 .probe = img_spdif_in_probe,
800 .remove = img_spdif_in_dev_remove
801};
802module_platform_driver(img_spdif_in_driver);
803
804MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
805MODULE_DESCRIPTION("IMG SPDIF Input driver");
806MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c
new file mode 100644
index 000000000000..08f93a5dadfe
--- /dev/null
+++ b/sound/soc/img/img-spdif-out.c
@@ -0,0 +1,441 @@
1/*
2 * IMG SPDIF output controller driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/reset.h>
21
22#include <sound/core.h>
23#include <sound/dmaengine_pcm.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#define IMG_SPDIF_OUT_TX_FIFO 0x0
30
31#define IMG_SPDIF_OUT_CTL 0x4
32#define IMG_SPDIF_OUT_CTL_FS_MASK BIT(4)
33#define IMG_SPDIF_OUT_CTL_CLK_MASK BIT(2)
34#define IMG_SPDIF_OUT_CTL_SRT_MASK BIT(0)
35
36#define IMG_SPDIF_OUT_CSL 0x14
37
38#define IMG_SPDIF_OUT_CSH_UV 0x18
39#define IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT 0
40#define IMG_SPDIF_OUT_CSH_UV_CSH_MASK 0xff
41
42struct img_spdif_out {
43 spinlock_t lock;
44 void __iomem *base;
45 struct clk *clk_sys;
46 struct clk *clk_ref;
47 struct snd_dmaengine_dai_dma_data dma_data;
48 struct device *dev;
49 struct reset_control *rst;
50};
51
52static int img_spdif_out_suspend(struct device *dev)
53{
54 struct img_spdif_out *spdif = dev_get_drvdata(dev);
55
56 clk_disable_unprepare(spdif->clk_ref);
57
58 return 0;
59}
60
61static int img_spdif_out_resume(struct device *dev)
62{
63 struct img_spdif_out *spdif = dev_get_drvdata(dev);
64 int ret;
65
66 ret = clk_prepare_enable(spdif->clk_ref);
67 if (ret) {
68 dev_err(dev, "clk_enable failed: %d\n", ret);
69 return ret;
70 }
71
72 return 0;
73}
74
75static inline void img_spdif_out_writel(struct img_spdif_out *spdif, u32 val,
76 u32 reg)
77{
78 writel(val, spdif->base + reg);
79}
80
81static inline u32 img_spdif_out_readl(struct img_spdif_out *spdif, u32 reg)
82{
83 return readl(spdif->base + reg);
84}
85
86static void img_spdif_out_reset(struct img_spdif_out *spdif)
87{
88 u32 ctl, status_low, status_high;
89
90 ctl = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL) &
91 ~IMG_SPDIF_OUT_CTL_SRT_MASK;
92 status_low = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
93 status_high = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
94
95 reset_control_assert(spdif->rst);
96 reset_control_deassert(spdif->rst);
97
98 img_spdif_out_writel(spdif, ctl, IMG_SPDIF_OUT_CTL);
99 img_spdif_out_writel(spdif, status_low, IMG_SPDIF_OUT_CSL);
100 img_spdif_out_writel(spdif, status_high, IMG_SPDIF_OUT_CSH_UV);
101}
102
103static int img_spdif_out_info(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_info *uinfo)
105{
106 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
107 uinfo->count = 1;
108
109 return 0;
110}
111
112static int img_spdif_out_get_status_mask(struct snd_kcontrol *kcontrol,
113 struct snd_ctl_elem_value *ucontrol)
114{
115 ucontrol->value.iec958.status[0] = 0xff;
116 ucontrol->value.iec958.status[1] = 0xff;
117 ucontrol->value.iec958.status[2] = 0xff;
118 ucontrol->value.iec958.status[3] = 0xff;
119 ucontrol->value.iec958.status[4] = 0xff;
120
121 return 0;
122}
123
124static int img_spdif_out_get_status(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol)
126{
127 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
128 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
129 u32 reg;
130 unsigned long flags;
131
132 spin_lock_irqsave(&spdif->lock, flags);
133
134 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
135 ucontrol->value.iec958.status[0] = reg & 0xff;
136 ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
137 ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
138 ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
139
140 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
141 ucontrol->value.iec958.status[4] =
142 (reg & IMG_SPDIF_OUT_CSH_UV_CSH_MASK) >>
143 IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
144
145 spin_unlock_irqrestore(&spdif->lock, flags);
146
147 return 0;
148}
149
150static int img_spdif_out_set_status(struct snd_kcontrol *kcontrol,
151 struct snd_ctl_elem_value *ucontrol)
152{
153 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
154 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
155 u32 reg;
156 unsigned long flags;
157
158 reg = ((u32)ucontrol->value.iec958.status[3] << 24);
159 reg |= ((u32)ucontrol->value.iec958.status[2] << 16);
160 reg |= ((u32)ucontrol->value.iec958.status[1] << 8);
161 reg |= (u32)ucontrol->value.iec958.status[0];
162
163 spin_lock_irqsave(&spdif->lock, flags);
164
165 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSL);
166
167 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
168 reg &= ~IMG_SPDIF_OUT_CSH_UV_CSH_MASK;
169 reg |= (u32)ucontrol->value.iec958.status[4] <<
170 IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
171 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSH_UV);
172
173 spin_unlock_irqrestore(&spdif->lock, flags);
174
175 return 0;
176}
177
178static struct snd_kcontrol_new img_spdif_out_controls[] = {
179 {
180 .access = SNDRV_CTL_ELEM_ACCESS_READ,
181 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
182 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
183 .info = img_spdif_out_info,
184 .get = img_spdif_out_get_status_mask
185 },
186 {
187 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
188 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
189 .info = img_spdif_out_info,
190 .get = img_spdif_out_get_status,
191 .put = img_spdif_out_set_status
192 }
193};
194
195static int img_spdif_out_trigger(struct snd_pcm_substream *substream, int cmd,
196 struct snd_soc_dai *dai)
197{
198 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
199 u32 reg;
200 unsigned long flags;
201
202 switch (cmd) {
203 case SNDRV_PCM_TRIGGER_START:
204 case SNDRV_PCM_TRIGGER_RESUME:
205 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
206 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
207 reg |= IMG_SPDIF_OUT_CTL_SRT_MASK;
208 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
209 break;
210 case SNDRV_PCM_TRIGGER_STOP:
211 case SNDRV_PCM_TRIGGER_SUSPEND:
212 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
213 spin_lock_irqsave(&spdif->lock, flags);
214 img_spdif_out_reset(spdif);
215 spin_unlock_irqrestore(&spdif->lock, flags);
216 break;
217 default:
218 return -EINVAL;
219 }
220
221 return 0;
222}
223
224static int img_spdif_out_hw_params(struct snd_pcm_substream *substream,
225 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
226{
227 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
228 unsigned int channels;
229 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
230 u32 reg;
231 snd_pcm_format_t format;
232
233 rate = params_rate(params);
234 format = params_format(params);
235 channels = params_channels(params);
236
237 dev_dbg(spdif->dev, "hw_params rate %ld channels %u format %u\n",
238 rate, channels, format);
239
240 if (format != SNDRV_PCM_FORMAT_S32_LE)
241 return -EINVAL;
242
243 if (channels != 2)
244 return -EINVAL;
245
246 pre_div_a = clk_round_rate(spdif->clk_ref, rate * 256);
247 if (pre_div_a < 0)
248 return pre_div_a;
249 pre_div_b = clk_round_rate(spdif->clk_ref, rate * 384);
250 if (pre_div_b < 0)
251 return pre_div_b;
252
253 diff_a = abs((pre_div_a / 256) - rate);
254 diff_b = abs((pre_div_b / 384) - rate);
255
256 /* If diffs are equal, use lower clock rate */
257 if (diff_a > diff_b)
258 clk_set_rate(spdif->clk_ref, pre_div_b);
259 else
260 clk_set_rate(spdif->clk_ref, pre_div_a);
261
262 /*
263 * Another driver (eg machine driver) may have rejected the above
264 * change. Get the current rate and set the register bit according to
265 * the new min diff
266 */
267 clk_rate = clk_get_rate(spdif->clk_ref);
268
269 diff_a = abs((clk_rate / 256) - rate);
270 diff_b = abs((clk_rate / 384) - rate);
271
272 reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
273 if (diff_a <= diff_b)
274 reg &= ~IMG_SPDIF_OUT_CTL_CLK_MASK;
275 else
276 reg |= IMG_SPDIF_OUT_CTL_CLK_MASK;
277 img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
278
279 return 0;
280}
281
282static const struct snd_soc_dai_ops img_spdif_out_dai_ops = {
283 .trigger = img_spdif_out_trigger,
284 .hw_params = img_spdif_out_hw_params
285};
286
287static int img_spdif_out_dai_probe(struct snd_soc_dai *dai)
288{
289 struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
290
291 snd_soc_dai_init_dma_data(dai, &spdif->dma_data, NULL);
292
293 snd_soc_add_dai_controls(dai, img_spdif_out_controls,
294 ARRAY_SIZE(img_spdif_out_controls));
295
296 return 0;
297}
298
299static struct snd_soc_dai_driver img_spdif_out_dai = {
300 .probe = img_spdif_out_dai_probe,
301 .playback = {
302 .channels_min = 2,
303 .channels_max = 2,
304 .rates = SNDRV_PCM_RATE_8000_192000,
305 .formats = SNDRV_PCM_FMTBIT_S32_LE
306 },
307 .ops = &img_spdif_out_dai_ops
308};
309
310static const struct snd_soc_component_driver img_spdif_out_component = {
311 .name = "img-spdif-out"
312};
313
314static int img_spdif_out_probe(struct platform_device *pdev)
315{
316 struct img_spdif_out *spdif;
317 struct resource *res;
318 void __iomem *base;
319 int ret;
320 struct device *dev = &pdev->dev;
321
322 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
323 if (!spdif)
324 return -ENOMEM;
325
326 platform_set_drvdata(pdev, spdif);
327
328 spdif->dev = &pdev->dev;
329
330 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
331 base = devm_ioremap_resource(&pdev->dev, res);
332 if (IS_ERR(base))
333 return PTR_ERR(base);
334
335 spdif->base = base;
336
337 spdif->rst = devm_reset_control_get(&pdev->dev, "rst");
338 if (IS_ERR(spdif->rst)) {
339 if (PTR_ERR(spdif->rst) != -EPROBE_DEFER)
340 dev_err(&pdev->dev, "No top level reset found\n");
341 return PTR_ERR(spdif->rst);
342 }
343
344 spdif->clk_sys = devm_clk_get(&pdev->dev, "sys");
345 if (IS_ERR(spdif->clk_sys)) {
346 if (PTR_ERR(spdif->clk_sys) != -EPROBE_DEFER)
347 dev_err(dev, "Failed to acquire clock 'sys'\n");
348 return PTR_ERR(spdif->clk_sys);
349 }
350
351 spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
352 if (IS_ERR(spdif->clk_ref)) {
353 if (PTR_ERR(spdif->clk_ref) != -EPROBE_DEFER)
354 dev_err(dev, "Failed to acquire clock 'ref'\n");
355 return PTR_ERR(spdif->clk_ref);
356 }
357
358 ret = clk_prepare_enable(spdif->clk_sys);
359 if (ret)
360 return ret;
361
362 img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK,
363 IMG_SPDIF_OUT_CTL);
364
365 img_spdif_out_reset(spdif);
366
367 pm_runtime_enable(&pdev->dev);
368 if (!pm_runtime_enabled(&pdev->dev)) {
369 ret = img_spdif_out_resume(&pdev->dev);
370 if (ret)
371 goto err_pm_disable;
372 }
373
374 spin_lock_init(&spdif->lock);
375
376 spdif->dma_data.addr = res->start + IMG_SPDIF_OUT_TX_FIFO;
377 spdif->dma_data.addr_width = 4;
378 spdif->dma_data.maxburst = 4;
379
380 ret = devm_snd_soc_register_component(&pdev->dev,
381 &img_spdif_out_component,
382 &img_spdif_out_dai, 1);
383 if (ret)
384 goto err_suspend;
385
386 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
387 if (ret)
388 goto err_suspend;
389
390 dev_dbg(&pdev->dev, "Probe successful\n");
391
392 return 0;
393
394err_suspend:
395 if (!pm_runtime_status_suspended(&pdev->dev))
396 img_spdif_out_suspend(&pdev->dev);
397err_pm_disable:
398 pm_runtime_disable(&pdev->dev);
399 clk_disable_unprepare(spdif->clk_sys);
400
401 return ret;
402}
403
404static int img_spdif_out_dev_remove(struct platform_device *pdev)
405{
406 struct img_spdif_out *spdif = platform_get_drvdata(pdev);
407
408 pm_runtime_disable(&pdev->dev);
409 if (!pm_runtime_status_suspended(&pdev->dev))
410 img_spdif_out_suspend(&pdev->dev);
411
412 clk_disable_unprepare(spdif->clk_sys);
413
414 return 0;
415}
416
417static const struct of_device_id img_spdif_out_of_match[] = {
418 { .compatible = "img,spdif-out" },
419 {}
420};
421MODULE_DEVICE_TABLE(of, img_spdif_out_of_match);
422
423static const struct dev_pm_ops img_spdif_out_pm_ops = {
424 SET_RUNTIME_PM_OPS(img_spdif_out_suspend,
425 img_spdif_out_resume, NULL)
426};
427
428static struct platform_driver img_spdif_out_driver = {
429 .driver = {
430 .name = "img-spdif-out",
431 .of_match_table = img_spdif_out_of_match,
432 .pm = &img_spdif_out_pm_ops
433 },
434 .probe = img_spdif_out_probe,
435 .remove = img_spdif_out_dev_remove
436};
437module_platform_driver(img_spdif_out_driver);
438
439MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
440MODULE_DESCRIPTION("IMG SPDIF Output driver");
441MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c
new file mode 100644
index 000000000000..162a0fd68c7b
--- /dev/null
+++ b/sound/soc/img/pistachio-internal-dac.c
@@ -0,0 +1,287 @@
1/*
2 * Pistachio internal dac driver
3 *
4 * Copyright (C) 2015 Imagination Technologies Ltd.
5 *
6 * Author: Damien Horsley <Damien.Horsley@imgtec.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/mfd/syscon.h>
16#include <linux/module.h>
17#include <linux/pm_runtime.h>
18#include <linux/regmap.h>
19#include <linux/regulator/consumer.h>
20
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23
24#define PISTACHIO_INTERNAL_DAC_CTRL 0x40
25#define PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK 0x2
26#define PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK 0x1
27
28#define PISTACHIO_INTERNAL_DAC_SRST 0x44
29#define PISTACHIO_INTERNAL_DAC_SRST_MASK 0x1
30
31#define PISTACHIO_INTERNAL_DAC_GTI_CTRL 0x48
32#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_SHIFT 0
33#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_MASK 0xFFF
34#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK 0x1000
35#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_SHIFT 13
36#define PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_MASK 0x1FE000
37
38#define PISTACHIO_INTERNAL_DAC_PWR 0x1
39#define PISTACHIO_INTERNAL_DAC_PWR_MASK 0x1
40
41#define PISTACHIO_INTERNAL_DAC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
42 SNDRV_PCM_FMTBIT_S32_LE)
43
44/* codec private data */
45struct pistachio_internal_dac {
46 struct regmap *regmap;
47 struct regulator *supply;
48 bool mute;
49};
50
51static const struct snd_kcontrol_new pistachio_internal_dac_snd_controls[] = {
52 SOC_SINGLE("Playback Switch", PISTACHIO_INTERNAL_DAC_CTRL, 2, 1, 1)
53};
54
55static const struct snd_soc_dapm_widget pistachio_internal_dac_widgets[] = {
56 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
57 SND_SOC_DAPM_OUTPUT("AOUTL"),
58 SND_SOC_DAPM_OUTPUT("AOUTR"),
59};
60
61static const struct snd_soc_dapm_route pistachio_internal_dac_routes[] = {
62 { "AOUTL", NULL, "DAC" },
63 { "AOUTR", NULL, "DAC" },
64};
65
66static void pistachio_internal_dac_reg_writel(struct regmap *top_regs,
67 u32 val, u32 reg)
68{
69 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
70 PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_MASK,
71 reg << PISTACHIO_INTERNAL_DAC_GTI_CTRL_ADDR_SHIFT);
72
73 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
74 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_MASK,
75 val << PISTACHIO_INTERNAL_DAC_GTI_CTRL_WDATA_SHIFT);
76
77 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
78 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK,
79 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK);
80
81 regmap_update_bits(top_regs, PISTACHIO_INTERNAL_DAC_GTI_CTRL,
82 PISTACHIO_INTERNAL_DAC_GTI_CTRL_WE_MASK, 0);
83}
84
85static void pistachio_internal_dac_pwr_off(struct pistachio_internal_dac *dac)
86{
87 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
88 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK,
89 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK);
90
91 pistachio_internal_dac_reg_writel(dac->regmap, 0,
92 PISTACHIO_INTERNAL_DAC_PWR);
93}
94
95static void pistachio_internal_dac_pwr_on(struct pistachio_internal_dac *dac)
96{
97 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_SRST,
98 PISTACHIO_INTERNAL_DAC_SRST_MASK,
99 PISTACHIO_INTERNAL_DAC_SRST_MASK);
100
101 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_SRST,
102 PISTACHIO_INTERNAL_DAC_SRST_MASK, 0);
103
104 pistachio_internal_dac_reg_writel(dac->regmap,
105 PISTACHIO_INTERNAL_DAC_PWR_MASK,
106 PISTACHIO_INTERNAL_DAC_PWR);
107
108 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
109 PISTACHIO_INTERNAL_DAC_CTRL_PWRDN_MASK, 0);
110}
111
112static struct snd_soc_dai_driver pistachio_internal_dac_dais[] = {
113 {
114 .name = "pistachio_internal_dac",
115 .playback = {
116 .stream_name = "Playback",
117 .channels_min = 2,
118 .channels_max = 2,
119 .rates = SNDRV_PCM_RATE_8000_48000,
120 .formats = PISTACHIO_INTERNAL_DAC_FORMATS,
121 }
122 },
123};
124
125static int pistachio_internal_dac_codec_probe(struct snd_soc_codec *codec)
126{
127 struct pistachio_internal_dac *dac = snd_soc_codec_get_drvdata(codec);
128
129 snd_soc_codec_init_regmap(codec, dac->regmap);
130
131 return 0;
132}
133
134static const struct snd_soc_codec_driver pistachio_internal_dac_driver = {
135 .probe = pistachio_internal_dac_codec_probe,
136 .idle_bias_off = true,
137 .controls = pistachio_internal_dac_snd_controls,
138 .num_controls = ARRAY_SIZE(pistachio_internal_dac_snd_controls),
139 .dapm_widgets = pistachio_internal_dac_widgets,
140 .num_dapm_widgets = ARRAY_SIZE(pistachio_internal_dac_widgets),
141 .dapm_routes = pistachio_internal_dac_routes,
142 .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes),
143};
144
145static int pistachio_internal_dac_probe(struct platform_device *pdev)
146{
147 struct pistachio_internal_dac *dac;
148 int ret, voltage;
149 struct device *dev = &pdev->dev;
150 u32 reg;
151
152 dac = devm_kzalloc(dev, sizeof(*dac), GFP_KERNEL);
153
154 if (!dac)
155 return -ENOMEM;
156
157 platform_set_drvdata(pdev, dac);
158
159 dac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
160 "img,cr-top");
161 if (IS_ERR(dac->regmap))
162 return PTR_ERR(dac->regmap);
163
164 dac->supply = devm_regulator_get(dev, "VDD");
165 if (IS_ERR(dac->supply)) {
166 ret = PTR_ERR(dac->supply);
167 if (ret != -EPROBE_DEFER)
168 dev_err(dev, "failed to acquire supply 'VDD-supply': %d\n", ret);
169 return ret;
170 }
171
172 ret = regulator_enable(dac->supply);
173 if (ret) {
174 dev_err(dev, "failed to enable supply: %d\n", ret);
175 return ret;
176 }
177
178 voltage = regulator_get_voltage(dac->supply);
179
180 switch (voltage) {
181 case 1800000:
182 reg = 0;
183 break;
184 case 3300000:
185 reg = PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK;
186 break;
187 default:
188 dev_err(dev, "invalid voltage: %d\n", voltage);
189 ret = -EINVAL;
190 goto err_regulator;
191 }
192
193 regmap_update_bits(dac->regmap, PISTACHIO_INTERNAL_DAC_CTRL,
194 PISTACHIO_INTERNAL_DAC_CTRL_PWR_SEL_MASK, reg);
195
196 pistachio_internal_dac_pwr_off(dac);
197 pistachio_internal_dac_pwr_on(dac);
198
199 pm_runtime_set_active(dev);
200 pm_runtime_enable(dev);
201 pm_runtime_idle(dev);
202
203 ret = snd_soc_register_codec(dev, &pistachio_internal_dac_driver,
204 pistachio_internal_dac_dais,
205 ARRAY_SIZE(pistachio_internal_dac_dais));
206 if (ret) {
207 dev_err(dev, "failed to register codec: %d\n", ret);
208 goto err_pwr;
209 }
210
211 return 0;
212
213err_pwr:
214 pm_runtime_disable(&pdev->dev);
215 pistachio_internal_dac_pwr_off(dac);
216err_regulator:
217 regulator_disable(dac->supply);
218
219 return ret;
220}
221
222static int pistachio_internal_dac_remove(struct platform_device *pdev)
223{
224 struct pistachio_internal_dac *dac = dev_get_drvdata(&pdev->dev);
225
226 snd_soc_unregister_codec(&pdev->dev);
227 pm_runtime_disable(&pdev->dev);
228 pistachio_internal_dac_pwr_off(dac);
229 regulator_disable(dac->supply);
230
231 return 0;
232}
233
234#ifdef CONFIG_PM
235static int pistachio_internal_dac_rt_resume(struct device *dev)
236{
237 struct pistachio_internal_dac *dac = dev_get_drvdata(dev);
238 int ret;
239
240 ret = regulator_enable(dac->supply);
241 if (ret) {
242 dev_err(dev, "failed to enable supply: %d\n", ret);
243 return ret;
244 }
245
246 pistachio_internal_dac_pwr_on(dac);
247
248 return 0;
249}
250
251static int pistachio_internal_dac_rt_suspend(struct device *dev)
252{
253 struct pistachio_internal_dac *dac = dev_get_drvdata(dev);
254
255 pistachio_internal_dac_pwr_off(dac);
256
257 regulator_disable(dac->supply);
258
259 return 0;
260}
261#endif
262
263static const struct dev_pm_ops pistachio_internal_dac_pm_ops = {
264 SET_RUNTIME_PM_OPS(pistachio_internal_dac_rt_suspend,
265 pistachio_internal_dac_rt_resume, NULL)
266};
267
268static const struct of_device_id pistachio_internal_dac_of_match[] = {
269 { .compatible = "img,pistachio-internal-dac" },
270 {}
271};
272MODULE_DEVICE_TABLE(of, pistachio_internal_dac_of_match);
273
274static struct platform_driver pistachio_internal_dac_plat_driver = {
275 .driver = {
276 .name = "img-pistachio-internal-dac",
277 .of_match_table = pistachio_internal_dac_of_match,
278 .pm = &pistachio_internal_dac_pm_ops
279 },
280 .probe = pistachio_internal_dac_probe,
281 .remove = pistachio_internal_dac_remove
282};
283module_platform_driver(pistachio_internal_dac_plat_driver);
284
285MODULE_DESCRIPTION("Pistachio Internal DAC driver");
286MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
287MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index d430ef5a4f38..337e178c1acb 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -24,6 +24,7 @@ config SND_SST_IPC_PCI
24config SND_SST_IPC_ACPI 24config SND_SST_IPC_ACPI
25 tristate 25 tristate
26 select SND_SST_IPC 26 select SND_SST_IPC
27 select SND_SOC_INTEL_SST
27 depends on ACPI 28 depends on ACPI
28 29
29config SND_SOC_INTEL_SST 30config SND_SOC_INTEL_SST
@@ -43,7 +44,7 @@ config SND_SOC_INTEL_BAYTRAIL
43config SND_SOC_INTEL_HASWELL_MACH 44config SND_SOC_INTEL_HASWELL_MACH
44 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" 45 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
45 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM 46 depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
46 depends on DW_DMAC_CORE 47 depends on DW_DMAC_CORE=y
47 select SND_SOC_INTEL_SST 48 select SND_SOC_INTEL_SST
48 select SND_SOC_INTEL_HASWELL 49 select SND_SOC_INTEL_HASWELL
49 select SND_SOC_RT5640 50 select SND_SOC_RT5640
@@ -56,18 +57,19 @@ config SND_SOC_INTEL_HASWELL_MACH
56config SND_SOC_INTEL_BYT_RT5640_MACH 57config SND_SOC_INTEL_BYT_RT5640_MACH
57 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" 58 tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
58 depends on X86_INTEL_LPSS && I2C 59 depends on X86_INTEL_LPSS && I2C
59 depends on DW_DMAC_CORE 60 depends on DW_DMAC_CORE=y && (SND_SOC_INTEL_BYTCR_RT5640_MACH = n)
60 select SND_SOC_INTEL_SST 61 select SND_SOC_INTEL_SST
61 select SND_SOC_INTEL_BAYTRAIL 62 select SND_SOC_INTEL_BAYTRAIL
62 select SND_SOC_RT5640 63 select SND_SOC_RT5640
63 help 64 help
64 This adds audio driver for Intel Baytrail platform based boards 65 This adds audio driver for Intel Baytrail platform based boards
65 with the RT5640 audio codec. 66 with the RT5640 audio codec. This driver is deprecated, use
67 SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality
66 68
67config SND_SOC_INTEL_BYT_MAX98090_MACH 69config SND_SOC_INTEL_BYT_MAX98090_MACH
68 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" 70 tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
69 depends on X86_INTEL_LPSS && I2C 71 depends on X86_INTEL_LPSS && I2C
70 depends on DW_DMAC_CORE 72 depends on DW_DMAC_CORE=y
71 select SND_SOC_INTEL_SST 73 select SND_SOC_INTEL_SST
72 select SND_SOC_INTEL_BAYTRAIL 74 select SND_SOC_INTEL_BAYTRAIL
73 select SND_SOC_MAX98090 75 select SND_SOC_MAX98090
@@ -79,7 +81,7 @@ config SND_SOC_INTEL_BROADWELL_MACH
79 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" 81 tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
80 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ 82 depends on X86_INTEL_LPSS && I2C && DW_DMAC && \
81 I2C_DESIGNWARE_PLATFORM 83 I2C_DESIGNWARE_PLATFORM
82 depends on DW_DMAC_CORE 84 depends on DW_DMAC_CORE=y
83 select SND_SOC_INTEL_SST 85 select SND_SOC_INTEL_SST
84 select SND_SOC_INTEL_HASWELL 86 select SND_SOC_INTEL_HASWELL
85 select SND_SOC_RT286 87 select SND_SOC_RT286
@@ -90,14 +92,14 @@ config SND_SOC_INTEL_BROADWELL_MACH
90 If unsure select "N". 92 If unsure select "N".
91 93
92config SND_SOC_INTEL_BYTCR_RT5640_MACH 94config SND_SOC_INTEL_BYTCR_RT5640_MACH
93 tristate "ASoC Audio DSP Support for MID BYT Platform" 95 tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
94 depends on X86 && I2C 96 depends on X86 && I2C
95 select SND_SOC_RT5640 97 select SND_SOC_RT5640
96 select SND_SST_MFLD_PLATFORM 98 select SND_SST_MFLD_PLATFORM
97 select SND_SST_IPC_ACPI 99 select SND_SST_IPC_ACPI
98 help 100 help
99 This adds support for ASoC machine driver for Intel(R) MID Baytrail platform 101 This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
100 used as alsa device in audio substem in Intel(R) MID devices 102 platforms with RT5640 audio codec.
101 Say Y if you have such a device 103 Say Y if you have such a device
102 If unsure select "N". 104 If unsure select "N".
103 105
@@ -154,3 +156,31 @@ config SND_SOC_INTEL_SKL_RT286_MACH
154 with RT286 I2S audio codec. 156 with RT286 I2S audio codec.
155 Say Y if you have such a device 157 Say Y if you have such a device
156 If unsure select "N". 158 If unsure select "N".
159
160config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
161 tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode"
162 depends on X86_INTEL_LPSS && I2C
163 select SND_SOC_INTEL_SST
164 select SND_SOC_INTEL_SKYLAKE
165 select SND_SOC_NAU8825
166 select SND_SOC_SSM4567
167 select SND_SOC_DMIC
168 help
169 This adds support for ASoC Onboard Codec I2S machine driver. This will
170 create an alsa sound card for NAU88L25 + SSM4567.
171 Say Y if you have such a device
172 If unsure select "N".
173
174config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
175 tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode"
176 depends on X86_INTEL_LPSS && I2C
177 select SND_SOC_INTEL_SST
178 select SND_SOC_INTEL_SKYLAKE
179 select SND_SOC_NAU8825
180 select SND_SOC_MAX98357A
181 select SND_SOC_DMIC
182 help
183 This adds support for ASoC Onboard Codec I2S machine driver. This will
184 create an alsa sound card for NAU88L25 + MAX98357A.
185 Say Y if you have such a device
186 If unsure select "N".
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index d55388e082e1..b97e6adcf1b2 100644
--- a/sound/soc/intel/atom/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
@@ -443,7 +443,7 @@ static int sst_gain_get(struct snd_kcontrol *kcontrol,
443 break; 443 break;
444 444
445 case SST_GAIN_MUTE: 445 case SST_GAIN_MUTE:
446 ucontrol->value.integer.value[0] = gv->mute ? 1 : 0; 446 ucontrol->value.integer.value[0] = gv->mute ? 0 : 1;
447 break; 447 break;
448 448
449 case SST_GAIN_RAMP_DURATION: 449 case SST_GAIN_RAMP_DURATION:
@@ -479,7 +479,7 @@ static int sst_gain_put(struct snd_kcontrol *kcontrol,
479 break; 479 break;
480 480
481 case SST_GAIN_MUTE: 481 case SST_GAIN_MUTE:
482 gv->mute = !!ucontrol->value.integer.value[0]; 482 gv->mute = !ucontrol->value.integer.value[0];
483 dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute); 483 dev_dbg(cmpnt->dev, "%s: Mute %d\n", mc->pname, gv->mute);
484 break; 484 break;
485 485
@@ -1109,6 +1109,7 @@ static const struct snd_soc_dapm_route intercon[] = {
1109 {"media0_in", NULL, "Compress Playback"}, 1109 {"media0_in", NULL, "Compress Playback"},
1110 {"media1_in", NULL, "Headset Playback"}, 1110 {"media1_in", NULL, "Headset Playback"},
1111 {"media2_in", NULL, "pcm0_out"}, 1111 {"media2_in", NULL, "pcm0_out"},
1112 {"media3_in", NULL, "Deepbuffer Playback"},
1112 1113
1113 {"media0_out mix 0", "media0_in Switch", "media0_in"}, 1114 {"media0_out mix 0", "media0_in Switch", "media0_in"},
1114 {"media0_out mix 0", "media1_in Switch", "media1_in"}, 1115 {"media0_out mix 0", "media1_in Switch", "media1_in"},
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index 93de8045d4e1..e0113112f668 100644
--- a/sound/soc/intel/atom/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
@@ -28,6 +28,7 @@
28 28
29enum { 29enum {
30 MERR_DPCM_AUDIO = 0, 30 MERR_DPCM_AUDIO = 0,
31 MERR_DPCM_DEEP_BUFFER,
31 MERR_DPCM_COMPR, 32 MERR_DPCM_COMPR,
32}; 33};
33 34
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 0487cfaac538..55c33dc76ce4 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -98,6 +98,7 @@ static struct sst_dev_stream_map dpcm_strm_map[] = {
98 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0}, 98 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0},
99 {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0}, 99 {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0},
100 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0}, 100 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0},
101 {MERR_DPCM_DEEP_BUFFER, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA3_IN, SST_TASK_ID_MEDIA, 0},
101}; 102};
102 103
103static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream) 104static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
@@ -500,14 +501,25 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
500 .channels_min = SST_STEREO, 501 .channels_min = SST_STEREO,
501 .channels_max = SST_STEREO, 502 .channels_max = SST_STEREO,
502 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, 503 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
503 .formats = SNDRV_PCM_FMTBIT_S16_LE, 504 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
504 }, 505 },
505 .capture = { 506 .capture = {
506 .stream_name = "Headset Capture", 507 .stream_name = "Headset Capture",
507 .channels_min = 1, 508 .channels_min = 1,
508 .channels_max = 2, 509 .channels_max = 2,
509 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000, 510 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
510 .formats = SNDRV_PCM_FMTBIT_S16_LE, 511 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
512 },
513},
514{
515 .name = "deepbuffer-cpu-dai",
516 .ops = &sst_media_dai_ops,
517 .playback = {
518 .stream_name = "Deepbuffer Playback",
519 .channels_min = SST_STEREO,
520 .channels_max = SST_STEREO,
521 .rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
522 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
511 }, 523 },
512}, 524},
513{ 525{
@@ -516,10 +528,6 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
516 .ops = &sst_compr_dai_ops, 528 .ops = &sst_compr_dai_ops,
517 .playback = { 529 .playback = {
518 .stream_name = "Compress Playback", 530 .stream_name = "Compress Playback",
519 .channels_min = SST_STEREO,
520 .channels_max = SST_STEREO,
521 .rates = SNDRV_PCM_RATE_48000,
522 .formats = SNDRV_PCM_FMTBIT_S16_LE,
523 }, 531 },
524}, 532},
525/* BE CPU Dais */ 533/* BE CPU Dais */
@@ -760,15 +768,15 @@ static int sst_platform_remove(struct platform_device *pdev)
760static int sst_soc_prepare(struct device *dev) 768static int sst_soc_prepare(struct device *dev)
761{ 769{
762 struct sst_data *drv = dev_get_drvdata(dev); 770 struct sst_data *drv = dev_get_drvdata(dev);
763 int i; 771 struct snd_soc_pcm_runtime *rtd;
764 772
765 /* suspend all pcms first */ 773 /* suspend all pcms first */
766 snd_soc_suspend(drv->soc_card->dev); 774 snd_soc_suspend(drv->soc_card->dev);
767 snd_soc_poweroff(drv->soc_card->dev); 775 snd_soc_poweroff(drv->soc_card->dev);
768 776
769 /* set the SSPs to idle */ 777 /* set the SSPs to idle */
770 for (i = 0; i < drv->soc_card->num_rtd; i++) { 778 list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
771 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai; 779 struct snd_soc_dai *dai = rtd->cpu_dai;
772 780
773 if (dai->active) { 781 if (dai->active) {
774 send_ssp_cmd(dai, dai->name, 0); 782 send_ssp_cmd(dai, dai->name, 0);
@@ -782,11 +790,11 @@ static int sst_soc_prepare(struct device *dev)
782static void sst_soc_complete(struct device *dev) 790static void sst_soc_complete(struct device *dev)
783{ 791{
784 struct sst_data *drv = dev_get_drvdata(dev); 792 struct sst_data *drv = dev_get_drvdata(dev);
785 int i; 793 struct snd_soc_pcm_runtime *rtd;
786 794
787 /* restart SSPs */ 795 /* restart SSPs */
788 for (i = 0; i < drv->soc_card->num_rtd; i++) { 796 list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
789 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai; 797 struct snd_soc_dai *dai = rtd->cpu_dai;
790 798
791 if (dai->active) { 799 if (dai->active) {
792 sst_handle_vb_timer(dai, true); 800 sst_handle_vb_timer(dai, true);
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index bb19b5801466..f424460b917e 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -40,18 +40,9 @@
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include "../sst-mfld-platform.h" 41#include "../sst-mfld-platform.h"
42#include "../../common/sst-dsp.h" 42#include "../../common/sst-dsp.h"
43#include "../../common/sst-acpi.h"
43#include "sst.h" 44#include "sst.h"
44 45
45struct sst_machines {
46 char *codec_id;
47 char board[32];
48 char machine[32];
49 void (*machine_quirk)(void);
50 char firmware[FW_NAME_SIZE];
51 struct sst_platform_info *pdata;
52
53};
54
55/* LPE viewpoint addresses */ 46/* LPE viewpoint addresses */
56#define SST_BYT_IRAM_PHY_START 0xff2c0000 47#define SST_BYT_IRAM_PHY_START 0xff2c0000
57#define SST_BYT_IRAM_PHY_END 0xff2d4000 48#define SST_BYT_IRAM_PHY_END 0xff2d4000
@@ -223,37 +214,16 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
223 return 0; 214 return 0;
224} 215}
225 216
226static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
227 void *context, void **ret)
228{
229 *(bool *)context = true;
230 return AE_OK;
231}
232
233static struct sst_machines *sst_acpi_find_machine(
234 struct sst_machines *machines)
235{
236 struct sst_machines *mach;
237 bool found = false;
238
239 for (mach = machines; mach->codec_id; mach++)
240 if (ACPI_SUCCESS(acpi_get_devices(mach->codec_id,
241 sst_acpi_mach_match,
242 &found, NULL)) && found)
243 return mach;
244
245 return NULL;
246}
247
248static int sst_acpi_probe(struct platform_device *pdev) 217static int sst_acpi_probe(struct platform_device *pdev)
249{ 218{
250 struct device *dev = &pdev->dev; 219 struct device *dev = &pdev->dev;
251 int ret = 0; 220 int ret = 0;
252 struct intel_sst_drv *ctx; 221 struct intel_sst_drv *ctx;
253 const struct acpi_device_id *id; 222 const struct acpi_device_id *id;
254 struct sst_machines *mach; 223 struct sst_acpi_mach *mach;
255 struct platform_device *mdev; 224 struct platform_device *mdev;
256 struct platform_device *plat_dev; 225 struct platform_device *plat_dev;
226 struct sst_platform_info *pdata;
257 unsigned int dev_id; 227 unsigned int dev_id;
258 228
259 id = acpi_match_device(dev->driver->acpi_match_table, dev); 229 id = acpi_match_device(dev->driver->acpi_match_table, dev);
@@ -261,12 +231,13 @@ static int sst_acpi_probe(struct platform_device *pdev)
261 return -ENODEV; 231 return -ENODEV;
262 dev_dbg(dev, "for %s", id->id); 232 dev_dbg(dev, "for %s", id->id);
263 233
264 mach = (struct sst_machines *)id->driver_data; 234 mach = (struct sst_acpi_mach *)id->driver_data;
265 mach = sst_acpi_find_machine(mach); 235 mach = sst_acpi_find_machine(mach);
266 if (mach == NULL) { 236 if (mach == NULL) {
267 dev_err(dev, "No matching machine driver found\n"); 237 dev_err(dev, "No matching machine driver found\n");
268 return -ENODEV; 238 return -ENODEV;
269 } 239 }
240 pdata = mach->pdata;
270 241
271 ret = kstrtouint(id->id, 16, &dev_id); 242 ret = kstrtouint(id->id, 16, &dev_id);
272 if (ret < 0) { 243 if (ret < 0) {
@@ -276,16 +247,16 @@ static int sst_acpi_probe(struct platform_device *pdev)
276 247
277 dev_dbg(dev, "ACPI device id: %x\n", dev_id); 248 dev_dbg(dev, "ACPI device id: %x\n", dev_id);
278 249
279 plat_dev = platform_device_register_data(dev, mach->pdata->platform, -1, NULL, 0); 250 plat_dev = platform_device_register_data(dev, pdata->platform, -1, NULL, 0);
280 if (IS_ERR(plat_dev)) { 251 if (IS_ERR(plat_dev)) {
281 dev_err(dev, "Failed to create machine device: %s\n", mach->pdata->platform); 252 dev_err(dev, "Failed to create machine device: %s\n", pdata->platform);
282 return PTR_ERR(plat_dev); 253 return PTR_ERR(plat_dev);
283 } 254 }
284 255
285 /* Create platform device for sst machine driver */ 256 /* Create platform device for sst machine driver */
286 mdev = platform_device_register_data(dev, mach->machine, -1, NULL, 0); 257 mdev = platform_device_register_data(dev, mach->drv_name, -1, NULL, 0);
287 if (IS_ERR(mdev)) { 258 if (IS_ERR(mdev)) {
288 dev_err(dev, "Failed to create machine device: %s\n", mach->machine); 259 dev_err(dev, "Failed to create machine device: %s\n", mach->drv_name);
289 return PTR_ERR(mdev); 260 return PTR_ERR(mdev);
290 } 261 }
291 262
@@ -294,8 +265,8 @@ static int sst_acpi_probe(struct platform_device *pdev)
294 return ret; 265 return ret;
295 266
296 /* Fill sst platform data */ 267 /* Fill sst platform data */
297 ctx->pdata = mach->pdata; 268 ctx->pdata = pdata;
298 strcpy(ctx->firmware_name, mach->firmware); 269 strcpy(ctx->firmware_name, mach->fw_filename);
299 270
300 ret = sst_platform_get_resources(ctx); 271 ret = sst_platform_get_resources(ctx);
301 if (ret) 272 if (ret)
@@ -342,22 +313,22 @@ static int sst_acpi_remove(struct platform_device *pdev)
342 return 0; 313 return 0;
343} 314}
344 315
345static struct sst_machines sst_acpi_bytcr[] = { 316static struct sst_acpi_mach sst_acpi_bytcr[] = {
346 {"10EC5640", "T100", "bytt100_rt5640", NULL, "intel/fw_sst_0f28.bin", 317 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL,
347 &byt_rvp_platform_data }, 318 &byt_rvp_platform_data },
348 {}, 319 {},
349}; 320};
350 321
351/* Cherryview-based platforms: CherryTrail and Braswell */ 322/* Cherryview-based platforms: CherryTrail and Braswell */
352static struct sst_machines sst_acpi_chv[] = { 323static struct sst_acpi_mach sst_acpi_chv[] = {
353 {"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "intel/fw_sst_22a8.bin", 324 {"10EC5670", "cht-bsw-rt5672", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
325 &chv_platform_data },
326 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
354 &chv_platform_data }, 327 &chv_platform_data },
355 {"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 328 {"10EC5650", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
356 &chv_platform_data }, 329 &chv_platform_data },
357 {"10EC5650", "cht-bsw", "cht-bsw-rt5645", NULL, "intel/fw_sst_22a8.bin", 330 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
358 &chv_platform_data }, 331 &chv_platform_data },
359 {"193C9890", "cht-bsw", "cht-bsw-max98090", NULL,
360 "intel/fw_sst_22a8.bin", &chv_platform_data },
361 {}, 332 {},
362}; 333};
363 334
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index a74c64c7053c..4ccc80e5e8cc 100644
--- a/sound/soc/intel/atom/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -108,7 +108,7 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
108 str_id, pipe_id); 108 str_id, pipe_id);
109 ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD, 109 ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
110 IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param), 110 IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
111 &alloc_param, data, true, true, false, true); 111 &alloc_param, &data, true, true, false, true);
112 112
113 if (ret < 0) { 113 if (ret < 0) {
114 dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret); 114 dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index 79547bec558b..4765ad474544 100644
--- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -377,6 +377,8 @@ static int sst_byt_pcm_probe(struct snd_soc_platform *platform)
377 377
378 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), 378 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data),
379 GFP_KERNEL); 379 GFP_KERNEL);
380 if (!priv_data)
381 return -ENOMEM;
380 priv_data->byt = plat_data->dsp; 382 priv_data->byt = plat_data->dsp;
381 snd_soc_platform_set_drvdata(platform, priv_data); 383 snd_soc_platform_set_drvdata(platform, priv_data);
382 384
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 371c4565cad8..2485ea9434ad 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -7,6 +7,8 @@ snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
9snd-soc-skl_rt286-objs := skl_rt286.o 9snd-soc-skl_rt286-objs := skl_rt286.o
10snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
11snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
10 12
11obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 13obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
12obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 14obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
@@ -17,3 +19,5 @@ obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 19obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
18obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 20obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
19obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o 21obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
22obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
23obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 7a5c9a36c1db..a81389d10e17 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -20,51 +20,75 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/acpi.h>
23#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/dmi.h>
24#include <linux/slab.h> 26#include <linux/slab.h>
25#include <linux/input.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/jack.h>
29#include "../../codecs/rt5640.h" 31#include "../../codecs/rt5640.h"
30#include "../atom/sst-atom-controls.h" 32#include "../atom/sst-atom-controls.h"
31 33
32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { 34static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
33 SND_SOC_DAPM_HP("Headphone", NULL), 35 SND_SOC_DAPM_HP("Headphone", NULL),
34 SND_SOC_DAPM_MIC("Headset Mic", NULL), 36 SND_SOC_DAPM_MIC("Headset Mic", NULL),
35 SND_SOC_DAPM_MIC("Int Mic", NULL), 37 SND_SOC_DAPM_MIC("Internal Mic", NULL),
36 SND_SOC_DAPM_SPK("Ext Spk", NULL), 38 SND_SOC_DAPM_SPK("Speaker", NULL),
37}; 39};
38 40
39static const struct snd_soc_dapm_route byt_audio_map[] = { 41static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
40 {"IN2P", NULL, "Headset Mic"},
41 {"IN2N", NULL, "Headset Mic"},
42 {"Headset Mic", NULL, "MICBIAS1"},
43 {"IN1P", NULL, "MICBIAS1"},
44 {"LDO2", NULL, "Int Mic"},
45 {"Headphone", NULL, "HPOL"},
46 {"Headphone", NULL, "HPOR"},
47 {"Ext Spk", NULL, "SPOLP"},
48 {"Ext Spk", NULL, "SPOLN"},
49 {"Ext Spk", NULL, "SPORP"},
50 {"Ext Spk", NULL, "SPORN"},
51
52 {"AIF1 Playback", NULL, "ssp2 Tx"}, 42 {"AIF1 Playback", NULL, "ssp2 Tx"},
53 {"ssp2 Tx", NULL, "codec_out0"}, 43 {"ssp2 Tx", NULL, "codec_out0"},
54 {"ssp2 Tx", NULL, "codec_out1"}, 44 {"ssp2 Tx", NULL, "codec_out1"},
55 {"codec_in0", NULL, "ssp2 Rx"}, 45 {"codec_in0", NULL, "ssp2 Rx"},
56 {"codec_in1", NULL, "ssp2 Rx"}, 46 {"codec_in1", NULL, "ssp2 Rx"},
57 {"ssp2 Rx", NULL, "AIF1 Capture"}, 47 {"ssp2 Rx", NULL, "AIF1 Capture"},
48
49 {"Headset Mic", NULL, "MICBIAS1"},
50 {"IN2P", NULL, "Headset Mic"},
51 {"Headphone", NULL, "HPOL"},
52 {"Headphone", NULL, "HPOR"},
53 {"Speaker", NULL, "SPOLP"},
54 {"Speaker", NULL, "SPOLN"},
55 {"Speaker", NULL, "SPORP"},
56 {"Speaker", NULL, "SPORN"},
57};
58
59static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
60 {"DMIC1", NULL, "Internal Mic"},
61};
62
63static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
64 {"DMIC2", NULL, "Internal Mic"},
65};
66
67static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
68 {"Internal Mic", NULL, "MICBIAS1"},
69 {"IN1P", NULL, "Internal Mic"},
58}; 70};
59 71
60static const struct snd_kcontrol_new byt_mc_controls[] = { 72enum {
73 BYT_RT5640_DMIC1_MAP,
74 BYT_RT5640_DMIC2_MAP,
75 BYT_RT5640_IN1_MAP,
76};
77
78#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
79#define BYT_RT5640_DMIC_EN BIT(16)
80
81static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
82 BYT_RT5640_DMIC_EN;
83
84static const struct snd_kcontrol_new byt_rt5640_controls[] = {
61 SOC_DAPM_PIN_SWITCH("Headphone"), 85 SOC_DAPM_PIN_SWITCH("Headphone"),
62 SOC_DAPM_PIN_SWITCH("Headset Mic"), 86 SOC_DAPM_PIN_SWITCH("Headset Mic"),
63 SOC_DAPM_PIN_SWITCH("Int Mic"), 87 SOC_DAPM_PIN_SWITCH("Internal Mic"),
64 SOC_DAPM_PIN_SWITCH("Ext Spk"), 88 SOC_DAPM_PIN_SWITCH("Speaker"),
65}; 89};
66 90
67static int byt_aif1_hw_params(struct snd_pcm_substream *substream, 91static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
68 struct snd_pcm_hw_params *params) 92 struct snd_pcm_hw_params *params)
69{ 93{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data; 94 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -92,7 +116,82 @@ static int byt_aif1_hw_params(struct snd_pcm_substream *substream,
92 return 0; 116 return 0;
93} 117}
94 118
95static const struct snd_soc_pcm_stream byt_dai_params = { 119static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
120{
121 byt_rt5640_quirk = (unsigned long)id->driver_data;
122 return 1;
123}
124
125static const struct dmi_system_id byt_rt5640_quirk_table[] = {
126 {
127 .callback = byt_rt5640_quirk_cb,
128 .matches = {
129 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
130 DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
131 },
132 .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
133 },
134 {
135 .callback = byt_rt5640_quirk_cb,
136 .matches = {
137 DMI_MATCH(DMI_SYS_VENDOR, "DellInc."),
138 DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
139 },
140 .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
141 BYT_RT5640_DMIC_EN),
142 },
143 {}
144};
145
146static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
147{
148 int ret;
149 struct snd_soc_codec *codec = runtime->codec;
150 struct snd_soc_card *card = runtime->card;
151 const struct snd_soc_dapm_route *custom_map;
152 int num_routes;
153
154 card->dapm.idle_bias_off = true;
155
156 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
157 ARRAY_SIZE(byt_rt5640_controls));
158 if (ret) {
159 dev_err(card->dev, "unable to add card controls\n");
160 return ret;
161 }
162
163 dmi_check_system(byt_rt5640_quirk_table);
164 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
165 case BYT_RT5640_IN1_MAP:
166 custom_map = byt_rt5640_intmic_in1_map;
167 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
168 break;
169 case BYT_RT5640_DMIC2_MAP:
170 custom_map = byt_rt5640_intmic_dmic2_map;
171 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
172 break;
173 default:
174 custom_map = byt_rt5640_intmic_dmic1_map;
175 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
176 }
177
178 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
179 if (ret)
180 return ret;
181
182 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
183 ret = rt5640_dmic_enable(codec, 0, 0);
184 if (ret)
185 return ret;
186 }
187
188 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
189 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
190
191 return ret;
192}
193
194static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
96 .formats = SNDRV_PCM_FMTBIT_S24_LE, 195 .formats = SNDRV_PCM_FMTBIT_S24_LE,
97 .rate_min = 48000, 196 .rate_min = 48000,
98 .rate_max = 48000, 197 .rate_max = 48000,
@@ -100,13 +199,14 @@ static const struct snd_soc_pcm_stream byt_dai_params = {
100 .channels_max = 2, 199 .channels_max = 2,
101}; 200};
102 201
103static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd, 202static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
104 struct snd_pcm_hw_params *params) 203 struct snd_pcm_hw_params *params)
105{ 204{
106 struct snd_interval *rate = hw_param_interval(params, 205 struct snd_interval *rate = hw_param_interval(params,
107 SNDRV_PCM_HW_PARAM_RATE); 206 SNDRV_PCM_HW_PARAM_RATE);
108 struct snd_interval *channels = hw_param_interval(params, 207 struct snd_interval *channels = hw_param_interval(params,
109 SNDRV_PCM_HW_PARAM_CHANNELS); 208 SNDRV_PCM_HW_PARAM_CHANNELS);
209 int ret;
110 210
111 /* The DSP will covert the FE rate to 48k, stereo, 24bits */ 211 /* The DSP will covert the FE rate to 48k, stereo, 24bits */
112 rate->min = rate->max = 48000; 212 rate->min = rate->max = 48000;
@@ -114,24 +214,46 @@ static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd,
114 214
115 /* set SSP2 to 24-bit */ 215 /* set SSP2 to 24-bit */
116 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); 216 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
217
218 /*
219 * Default mode for SSP configuration is TDM 4 slot, override config
220 * with explicit setting to I2S 2ch 24-bit. The word length is set with
221 * dai_set_tdm_slot() since there is no other API exposed
222 */
223 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
224 SND_SOC_DAIFMT_I2S |
225 SND_SOC_DAIFMT_NB_IF |
226 SND_SOC_DAIFMT_CBS_CFS
227 );
228 if (ret < 0) {
229 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
230 return ret;
231 }
232
233 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
234 if (ret < 0) {
235 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
236 return ret;
237 }
238
117 return 0; 239 return 0;
118} 240}
119 241
120static int byt_aif1_startup(struct snd_pcm_substream *substream) 242static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
121{ 243{
122 return snd_pcm_hw_constraint_single(substream->runtime, 244 return snd_pcm_hw_constraint_single(substream->runtime,
123 SNDRV_PCM_HW_PARAM_RATE, 48000); 245 SNDRV_PCM_HW_PARAM_RATE, 48000);
124} 246}
125 247
126static struct snd_soc_ops byt_aif1_ops = { 248static struct snd_soc_ops byt_rt5640_aif1_ops = {
127 .startup = byt_aif1_startup, 249 .startup = byt_rt5640_aif1_startup,
128}; 250};
129 251
130static struct snd_soc_ops byt_be_ssp2_ops = { 252static struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
131 .hw_params = byt_aif1_hw_params, 253 .hw_params = byt_rt5640_aif1_hw_params,
132}; 254};
133 255
134static struct snd_soc_dai_link byt_dailink[] = { 256static struct snd_soc_dai_link byt_rt5640_dais[] = {
135 [MERR_DPCM_AUDIO] = { 257 [MERR_DPCM_AUDIO] = {
136 .name = "Baytrail Audio Port", 258 .name = "Baytrail Audio Port",
137 .stream_name = "Baytrail Audio", 259 .stream_name = "Baytrail Audio",
@@ -143,7 +265,20 @@ static struct snd_soc_dai_link byt_dailink[] = {
143 .dynamic = 1, 265 .dynamic = 1,
144 .dpcm_playback = 1, 266 .dpcm_playback = 1,
145 .dpcm_capture = 1, 267 .dpcm_capture = 1,
146 .ops = &byt_aif1_ops, 268 .ops = &byt_rt5640_aif1_ops,
269 },
270 [MERR_DPCM_DEEP_BUFFER] = {
271 .name = "Deep-Buffer Audio Port",
272 .stream_name = "Deep-Buffer Audio",
273 .cpu_dai_name = "deepbuffer-cpu-dai",
274 .codec_dai_name = "snd-soc-dummy-dai",
275 .codec_name = "snd-soc-dummy",
276 .platform_name = "sst-mfld-platform",
277 .ignore_suspend = 1,
278 .nonatomic = true,
279 .dynamic = 1,
280 .dpcm_playback = 1,
281 .ops = &byt_rt5640_aif1_ops,
147 }, 282 },
148 [MERR_DPCM_COMPR] = { 283 [MERR_DPCM_COMPR] = {
149 .name = "Baytrail Compressed Port", 284 .name = "Baytrail Compressed Port",
@@ -164,55 +299,57 @@ static struct snd_soc_dai_link byt_dailink[] = {
164 .codec_name = "i2c-10EC5640:00", 299 .codec_name = "i2c-10EC5640:00",
165 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF 300 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
166 | SND_SOC_DAIFMT_CBS_CFS, 301 | SND_SOC_DAIFMT_CBS_CFS,
167 .be_hw_params_fixup = byt_codec_fixup, 302 .be_hw_params_fixup = byt_rt5640_codec_fixup,
168 .ignore_suspend = 1, 303 .ignore_suspend = 1,
169 .dpcm_playback = 1, 304 .dpcm_playback = 1,
170 .dpcm_capture = 1, 305 .dpcm_capture = 1,
171 .ops = &byt_be_ssp2_ops, 306 .init = byt_rt5640_init,
307 .ops = &byt_rt5640_be_ssp2_ops,
172 }, 308 },
173}; 309};
174 310
175/* SoC card */ 311/* SoC card */
176static struct snd_soc_card snd_soc_card_byt = { 312static struct snd_soc_card byt_rt5640_card = {
177 .name = "baytrailcraudio", 313 .name = "bytcr-rt5640",
178 .owner = THIS_MODULE, 314 .owner = THIS_MODULE,
179 .dai_link = byt_dailink, 315 .dai_link = byt_rt5640_dais,
180 .num_links = ARRAY_SIZE(byt_dailink), 316 .num_links = ARRAY_SIZE(byt_rt5640_dais),
181 .dapm_widgets = byt_dapm_widgets, 317 .dapm_widgets = byt_rt5640_widgets,
182 .num_dapm_widgets = ARRAY_SIZE(byt_dapm_widgets), 318 .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
183 .dapm_routes = byt_audio_map, 319 .dapm_routes = byt_rt5640_audio_map,
184 .num_dapm_routes = ARRAY_SIZE(byt_audio_map), 320 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
185 .controls = byt_mc_controls, 321 .fully_routed = true,
186 .num_controls = ARRAY_SIZE(byt_mc_controls),
187}; 322};
188 323
189static int snd_byt_mc_probe(struct platform_device *pdev) 324static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
190{ 325{
191 int ret_val = 0; 326 int ret_val = 0;
192 327
193 /* register the soc card */ 328 /* register the soc card */
194 snd_soc_card_byt.dev = &pdev->dev; 329 byt_rt5640_card.dev = &pdev->dev;
330
331 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
195 332
196 ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_byt);
197 if (ret_val) { 333 if (ret_val) {
198 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); 334 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
335 ret_val);
199 return ret_val; 336 return ret_val;
200 } 337 }
201 platform_set_drvdata(pdev, &snd_soc_card_byt); 338 platform_set_drvdata(pdev, &byt_rt5640_card);
202 return ret_val; 339 return ret_val;
203} 340}
204 341
205static struct platform_driver snd_byt_mc_driver = { 342static struct platform_driver snd_byt_rt5640_mc_driver = {
206 .driver = { 343 .driver = {
207 .name = "bytt100_rt5640", 344 .name = "bytcr_rt5640",
208 .pm = &snd_soc_pm_ops, 345 .pm = &snd_soc_pm_ops,
209 }, 346 },
210 .probe = snd_byt_mc_probe, 347 .probe = snd_byt_rt5640_mc_probe,
211}; 348};
212 349
213module_platform_driver(snd_byt_mc_driver); 350module_platform_driver(snd_byt_rt5640_mc_driver);
214 351
215MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); 352MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
216MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>"); 353MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
217MODULE_LICENSE("GPL v2"); 354MODULE_LICENSE("GPL v2");
218MODULE_ALIAS("platform:bytt100_rt5640"); 355MODULE_ALIAS("platform:bytcr_rt5640");
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 4e2fcf188dd1..90588d6e64fc 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -41,12 +41,9 @@ struct cht_mc_private {
41 41
42static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 42static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
43{ 43{
44 int i; 44 struct snd_soc_pcm_runtime *rtd;
45 45
46 for (i = 0; i < card->num_rtd; i++) { 46 list_for_each_entry(rtd, &card->rtd_list, list) {
47 struct snd_soc_pcm_runtime *rtd;
48
49 rtd = card->rtd + i;
50 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 47 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
51 strlen(CHT_CODEC_DAI))) 48 strlen(CHT_CODEC_DAI)))
52 return rtd->codec_dai; 49 return rtd->codec_dai;
@@ -235,6 +232,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
235 .dpcm_capture = 1, 232 .dpcm_capture = 1,
236 .ops = &cht_aif1_ops, 233 .ops = &cht_aif1_ops,
237 }, 234 },
235 [MERR_DPCM_DEEP_BUFFER] = {
236 .name = "Deep-Buffer Audio Port",
237 .stream_name = "Deep-Buffer Audio",
238 .cpu_dai_name = "deepbuffer-cpu-dai",
239 .codec_dai_name = "snd-soc-dummy-dai",
240 .codec_name = "snd-soc-dummy",
241 .platform_name = "sst-mfld-platform",
242 .nonatomic = true,
243 .dynamic = 1,
244 .dpcm_playback = 1,
245 .ops = &cht_aif1_ops,
246 },
238 [MERR_DPCM_COMPR] = { 247 [MERR_DPCM_COMPR] = {
239 .name = "Compressed Port", 248 .name = "Compressed Port",
240 .stream_name = "Compress", 249 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 38d65a3529c4..2d3afddb0a2e 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -47,12 +47,9 @@ struct cht_mc_private {
47 47
48static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 48static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
49{ 49{
50 int i; 50 struct snd_soc_pcm_runtime *rtd;
51
52 for (i = 0; i < card->num_rtd; i++) {
53 struct snd_soc_pcm_runtime *rtd;
54 51
55 rtd = card->rtd + i; 52 list_for_each_entry(rtd, &card->rtd_list, list) {
56 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 53 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
57 strlen(CHT_CODEC_DAI))) 54 strlen(CHT_CODEC_DAI)))
58 return rtd->codec_dai; 55 return rtd->codec_dai;
@@ -263,6 +260,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
263 .dpcm_capture = 1, 260 .dpcm_capture = 1,
264 .ops = &cht_aif1_ops, 261 .ops = &cht_aif1_ops,
265 }, 262 },
263 [MERR_DPCM_DEEP_BUFFER] = {
264 .name = "Deep-Buffer Audio Port",
265 .stream_name = "Deep-Buffer Audio",
266 .cpu_dai_name = "deepbuffer-cpu-dai",
267 .codec_dai_name = "snd-soc-dummy-dai",
268 .codec_name = "snd-soc-dummy",
269 .platform_name = "sst-mfld-platform",
270 .nonatomic = true,
271 .dynamic = 1,
272 .dpcm_playback = 1,
273 .ops = &cht_aif1_ops,
274 },
266 [MERR_DPCM_COMPR] = { 275 [MERR_DPCM_COMPR] = {
267 .name = "Compressed Port", 276 .name = "Compressed Port",
268 .stream_name = "Compress", 277 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 5621ccd92992..2e5347f8f96c 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -46,12 +46,9 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
46 46
47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
48{ 48{
49 int i; 49 struct snd_soc_pcm_runtime *rtd;
50 50
51 for (i = 0; i < card->num_rtd; i++) { 51 list_for_each_entry(rtd, &card->rtd_list, list) {
52 struct snd_soc_pcm_runtime *rtd;
53
54 rtd = card->rtd + i;
55 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, 52 if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
56 strlen(CHT_CODEC_DAI))) 53 strlen(CHT_CODEC_DAI)))
57 return rtd->codec_dai; 54 return rtd->codec_dai;
@@ -251,6 +248,18 @@ static struct snd_soc_dai_link cht_dailink[] = {
251 .dpcm_capture = 1, 248 .dpcm_capture = 1,
252 .ops = &cht_aif1_ops, 249 .ops = &cht_aif1_ops,
253 }, 250 },
251 [MERR_DPCM_DEEP_BUFFER] = {
252 .name = "Deep-Buffer Audio Port",
253 .stream_name = "Deep-Buffer Audio",
254 .cpu_dai_name = "deepbuffer-cpu-dai",
255 .codec_dai_name = "snd-soc-dummy-dai",
256 .codec_name = "snd-soc-dummy",
257 .platform_name = "sst-mfld-platform",
258 .nonatomic = true,
259 .dynamic = 1,
260 .dpcm_playback = 1,
261 .ops = &cht_aif1_ops,
262 },
254 [MERR_DPCM_COMPR] = { 263 [MERR_DPCM_COMPR] = {
255 .name = "Compressed Port", 264 .name = "Compressed Port",
256 .stream_name = "Compress", 265 .stream_name = "Compress",
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
new file mode 100644
index 000000000000..ab7da9c304b2
--- /dev/null
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -0,0 +1,485 @@
1/*
2 * Intel Skylake I2S Machine Driver with MAXIM98357A
3 * and NAU88L25
4 *
5 * Copyright (C) 2015, Intel Corporation. All rights reserved.
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 version
9 * 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 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/jack.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include "../../codecs/nau8825.h"
25
26#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
27#define SKL_MAXIM_CODEC_DAI "HiFi"
28
29static struct snd_soc_jack skylake_headset;
30static struct snd_soc_card skylake_audio_card;
31
32static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
33{
34 struct snd_soc_pcm_runtime *rtd;
35
36 list_for_each_entry(rtd, &card->rtd_list, list) {
37
38 if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
39 strlen(SKL_NUVOTON_CODEC_DAI)))
40 return rtd->codec_dai;
41 }
42
43 return NULL;
44}
45
46static int platform_clock_control(struct snd_soc_dapm_widget *w,
47 struct snd_kcontrol *k, int event)
48{
49 struct snd_soc_dapm_context *dapm = w->dapm;
50 struct snd_soc_card *card = dapm->card;
51 struct snd_soc_dai *codec_dai;
52 int ret;
53
54 codec_dai = skl_get_codec_dai(card);
55 if (!codec_dai) {
56 dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
57 return -EIO;
58 }
59
60 if (SND_SOC_DAPM_EVENT_ON(event)) {
61 ret = snd_soc_dai_set_sysclk(codec_dai,
62 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
63 if (ret < 0) {
64 dev_err(card->dev, "set sysclk err = %d\n", ret);
65 return -EIO;
66 }
67 } else {
68 ret = snd_soc_dai_set_sysclk(codec_dai,
69 NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
70 if (ret < 0) {
71 dev_err(card->dev, "set sysclk err = %d\n", ret);
72 return -EIO;
73 }
74 }
75
76 return ret;
77}
78
79static const struct snd_kcontrol_new skylake_controls[] = {
80 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
81 SOC_DAPM_PIN_SWITCH("Headset Mic"),
82 SOC_DAPM_PIN_SWITCH("Spk"),
83};
84
85static const struct snd_soc_dapm_widget skylake_widgets[] = {
86 SND_SOC_DAPM_HP("Headphone Jack", NULL),
87 SND_SOC_DAPM_MIC("Headset Mic", NULL),
88 SND_SOC_DAPM_SPK("Spk", NULL),
89 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
90 SND_SOC_DAPM_SINK("WoV Sink"),
91 SND_SOC_DAPM_SPK("DP", NULL),
92 SND_SOC_DAPM_SPK("HDMI", NULL),
93 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
94 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
95 SND_SOC_DAPM_POST_PMD),
96};
97
98static const struct snd_soc_dapm_route skylake_map[] = {
99 /* HP jack connectors - unknown if we have jack detection */
100 { "Headphone Jack", NULL, "HPOL" },
101 { "Headphone Jack", NULL, "HPOR" },
102
103 /* speaker */
104 { "Spk", NULL, "Speaker" },
105
106 /* other jacks */
107 { "MIC", NULL, "Headset Mic" },
108 { "DMic", NULL, "SoC DMIC" },
109
110 {"WoV Sink", NULL, "hwd_in sink"},
111 {"HDMI", NULL, "hif5 Output"},
112 {"DP", NULL, "hif6 Output"},
113
114 /* CODEC BE connections */
115 { "HiFi Playback", NULL, "ssp0 Tx" },
116 { "ssp0 Tx", NULL, "codec0_out" },
117
118 { "Playback", NULL, "ssp1 Tx" },
119 { "ssp1 Tx", NULL, "codec1_out" },
120
121 { "codec0_in", NULL, "ssp1 Rx" },
122 { "ssp1 Rx", NULL, "Capture" },
123
124 /* DMIC */
125 { "dmic01_hifi", NULL, "DMIC01 Rx" },
126 { "DMIC01 Rx", NULL, "DMIC AIF" },
127 { "hifi1", NULL, "iDisp Tx"},
128 { "iDisp Tx", NULL, "iDisp_out"},
129 { "Headphone Jack", NULL, "Platform Clock" },
130 { "Headset Mic", NULL, "Platform Clock" },
131};
132
133static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
134 struct snd_pcm_hw_params *params)
135{
136 struct snd_interval *rate = hw_param_interval(params,
137 SNDRV_PCM_HW_PARAM_RATE);
138 struct snd_interval *channels = hw_param_interval(params,
139 SNDRV_PCM_HW_PARAM_CHANNELS);
140 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
141
142 /* The ADSP will covert the FE rate to 48k, stereo */
143 rate->min = rate->max = 48000;
144 channels->min = channels->max = 2;
145
146 /* set SSP0 to 24 bit */
147 snd_mask_none(fmt);
148 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
149
150 return 0;
151}
152
153static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
154{
155 int ret;
156 struct snd_soc_codec *codec = rtd->codec;
157
158 /*
159 * Headset buttons map to the google Reference headset.
160 * These can be configured by userspace.
161 */
162 ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack",
163 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
164 SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset,
165 NULL, 0);
166 if (ret) {
167 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
168 return ret;
169 }
170
171 nau8825_enable_jack_detect(codec, &skylake_headset);
172
173 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
174 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
175
176 return ret;
177}
178
179static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
180{
181 struct snd_soc_dapm_context *dapm;
182 struct snd_soc_component *component = rtd->cpu_dai->component;
183
184 dapm = snd_soc_component_get_dapm(component);
185 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
186
187 return 0;
188}
189
190static unsigned int rates[] = {
191 48000,
192};
193
194static struct snd_pcm_hw_constraint_list constraints_rates = {
195 .count = ARRAY_SIZE(rates),
196 .list = rates,
197 .mask = 0,
198};
199
200static unsigned int channels[] = {
201 2,
202};
203
204static struct snd_pcm_hw_constraint_list constraints_channels = {
205 .count = ARRAY_SIZE(channels),
206 .list = channels,
207 .mask = 0,
208};
209
210static int skl_fe_startup(struct snd_pcm_substream *substream)
211{
212 struct snd_pcm_runtime *runtime = substream->runtime;
213
214 /*
215 * On this platform for PCM device we support,
216 * 48Khz
217 * stereo
218 * 16 bit audio
219 */
220
221 runtime->hw.channels_max = 2;
222 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
223 &constraints_channels);
224
225 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
226 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
227
228 snd_pcm_hw_constraint_list(runtime, 0,
229 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
230
231 return 0;
232}
233
234static const struct snd_soc_ops skylake_nau8825_fe_ops = {
235 .startup = skl_fe_startup,
236};
237
238static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params)
240{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct snd_soc_dai *codec_dai = rtd->codec_dai;
243 int ret;
244
245 ret = snd_soc_dai_set_sysclk(codec_dai,
246 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
247
248 if (ret < 0)
249 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
250
251 return ret;
252}
253
254static struct snd_soc_ops skylake_nau8825_ops = {
255 .hw_params = skylake_nau8825_hw_params,
256};
257
258static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
259 struct snd_pcm_hw_params *params)
260{
261 struct snd_interval *channels = hw_param_interval(params,
262 SNDRV_PCM_HW_PARAM_CHANNELS);
263
264 if (params_channels(params) == 2)
265 channels->min = channels->max = 2;
266 else
267 channels->min = channels->max = 4;
268
269 return 0;
270}
271
272static unsigned int channels_dmic[] = {
273 2, 4,
274};
275
276static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
277 .count = ARRAY_SIZE(channels_dmic),
278 .list = channels_dmic,
279 .mask = 0,
280};
281
282static int skylake_dmic_startup(struct snd_pcm_substream *substream)
283{
284 struct snd_pcm_runtime *runtime = substream->runtime;
285
286 runtime->hw.channels_max = 4;
287 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
288 &constraints_dmic_channels);
289
290 return snd_pcm_hw_constraint_list(substream->runtime, 0,
291 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
292}
293
294static struct snd_soc_ops skylake_dmic_ops = {
295 .startup = skylake_dmic_startup,
296};
297
298static unsigned int rates_16000[] = {
299 16000,
300};
301
302static struct snd_pcm_hw_constraint_list constraints_16000 = {
303 .count = ARRAY_SIZE(rates_16000),
304 .list = rates_16000,
305};
306
307static int skylake_refcap_startup(struct snd_pcm_substream *substream)
308{
309 return snd_pcm_hw_constraint_list(substream->runtime, 0,
310 SNDRV_PCM_HW_PARAM_RATE,
311 &constraints_16000);
312}
313
314static struct snd_soc_ops skylaye_refcap_ops = {
315 .startup = skylake_refcap_startup,
316};
317
318/* skylake digital audio interface glue - connects codec <--> CPU */
319static struct snd_soc_dai_link skylake_dais[] = {
320 /* Front End DAI links */
321 {
322 .name = "Skl Audio Port",
323 .stream_name = "Audio",
324 .cpu_dai_name = "System Pin",
325 .platform_name = "0000:00:1f.3",
326 .dynamic = 1,
327 .codec_name = "snd-soc-dummy",
328 .codec_dai_name = "snd-soc-dummy-dai",
329 .nonatomic = 1,
330 .init = skylake_nau8825_fe_init,
331 .trigger = {
332 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
333 .dpcm_playback = 1,
334 .ops = &skylake_nau8825_fe_ops,
335 },
336 {
337 .name = "Skl Audio Capture Port",
338 .stream_name = "Audio Record",
339 .cpu_dai_name = "System Pin",
340 .platform_name = "0000:00:1f.3",
341 .dynamic = 1,
342 .codec_name = "snd-soc-dummy",
343 .codec_dai_name = "snd-soc-dummy-dai",
344 .nonatomic = 1,
345 .trigger = {
346 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
347 .dpcm_capture = 1,
348 .ops = &skylake_nau8825_fe_ops,
349 },
350 {
351 .name = "Skl Audio Reference cap",
352 .stream_name = "Wake on Voice",
353 .cpu_dai_name = "Reference Pin",
354 .codec_name = "snd-soc-dummy",
355 .codec_dai_name = "snd-soc-dummy-dai",
356 .platform_name = "0000:00:1f.3",
357 .init = NULL,
358 .dpcm_capture = 1,
359 .ignore_suspend = 1,
360 .nonatomic = 1,
361 .dynamic = 1,
362 .ops = &skylaye_refcap_ops,
363 },
364 {
365 .name = "Skl Audio DMIC cap",
366 .stream_name = "dmiccap",
367 .cpu_dai_name = "DMIC Pin",
368 .codec_name = "snd-soc-dummy",
369 .codec_dai_name = "snd-soc-dummy-dai",
370 .platform_name = "0000:00:1f.3",
371 .init = NULL,
372 .dpcm_capture = 1,
373 .nonatomic = 1,
374 .dynamic = 1,
375 .ops = &skylake_dmic_ops,
376 },
377 {
378 .name = "Skl HDMI Port",
379 .stream_name = "Hdmi",
380 .cpu_dai_name = "HDMI Pin",
381 .codec_name = "snd-soc-dummy",
382 .codec_dai_name = "snd-soc-dummy-dai",
383 .platform_name = "0000:00:1f.3",
384 .dpcm_playback = 1,
385 .init = NULL,
386 .nonatomic = 1,
387 .dynamic = 1,
388 },
389
390 /* Back End DAI links */
391 {
392 /* SSP0 - Codec */
393 .name = "SSP0-Codec",
394 .be_id = 0,
395 .cpu_dai_name = "SSP0 Pin",
396 .platform_name = "0000:00:1f.3",
397 .no_pcm = 1,
398 .codec_name = "MX98357A:00",
399 .codec_dai_name = SKL_MAXIM_CODEC_DAI,
400 .dai_fmt = SND_SOC_DAIFMT_I2S |
401 SND_SOC_DAIFMT_NB_NF |
402 SND_SOC_DAIFMT_CBS_CFS,
403 .ignore_pmdown_time = 1,
404 .be_hw_params_fixup = skylake_ssp_fixup,
405 .dpcm_playback = 1,
406 },
407 {
408 /* SSP1 - Codec */
409 .name = "SSP1-Codec",
410 .be_id = 0,
411 .cpu_dai_name = "SSP1 Pin",
412 .platform_name = "0000:00:1f.3",
413 .no_pcm = 1,
414 .codec_name = "i2c-10508825:00",
415 .codec_dai_name = SKL_NUVOTON_CODEC_DAI,
416 .init = skylake_nau8825_codec_init,
417 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
418 SND_SOC_DAIFMT_CBS_CFS,
419 .ignore_pmdown_time = 1,
420 .be_hw_params_fixup = skylake_ssp_fixup,
421 .ops = &skylake_nau8825_ops,
422 .dpcm_playback = 1,
423 .dpcm_capture = 1,
424 },
425 {
426 .name = "dmic01",
427 .be_id = 1,
428 .cpu_dai_name = "DMIC01 Pin",
429 .codec_name = "dmic-codec",
430 .codec_dai_name = "dmic-hifi",
431 .platform_name = "0000:00:1f.3",
432 .be_hw_params_fixup = skylake_dmic_fixup,
433 .ignore_suspend = 1,
434 .dpcm_capture = 1,
435 .no_pcm = 1,
436 },
437 {
438 .name = "iDisp",
439 .be_id = 3,
440 .cpu_dai_name = "iDisp Pin",
441 .codec_name = "ehdaudio0D2",
442 .codec_dai_name = "intel-hdmi-hifi1",
443 .platform_name = "0000:00:1f.3",
444 .dpcm_playback = 1,
445 .no_pcm = 1,
446 },
447};
448
449/* skylake audio machine driver for SPT + NAU88L25 */
450static struct snd_soc_card skylake_audio_card = {
451 .name = "sklnau8825max",
452 .owner = THIS_MODULE,
453 .dai_link = skylake_dais,
454 .num_links = ARRAY_SIZE(skylake_dais),
455 .controls = skylake_controls,
456 .num_controls = ARRAY_SIZE(skylake_controls),
457 .dapm_widgets = skylake_widgets,
458 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
459 .dapm_routes = skylake_map,
460 .num_dapm_routes = ARRAY_SIZE(skylake_map),
461 .fully_routed = true,
462};
463
464static int skylake_audio_probe(struct platform_device *pdev)
465{
466 skylake_audio_card.dev = &pdev->dev;
467
468 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
469}
470
471static struct platform_driver skylake_audio = {
472 .probe = skylake_audio_probe,
473 .driver = {
474 .name = "skl_nau88l25_max98357a_i2s",
475 .pm = &snd_soc_pm_ops,
476 },
477};
478
479module_platform_driver(skylake_audio)
480
481/* Module information */
482MODULE_DESCRIPTION("Audio Machine driver-NAU88L25 & MAX98357A in I2S mode");
483MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com");
484MODULE_LICENSE("GPL v2");
485MODULE_ALIAS("platform:skl_nau88l25_max98357a_i2s");
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
new file mode 100644
index 000000000000..c071812f31e5
--- /dev/null
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -0,0 +1,536 @@
1/*
2 * Intel Skylake I2S Machine Driver for NAU88L25+SSM4567
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
5 *
6 * Modified from:
7 * Intel Skylake I2S Machine Driver for NAU88L25 and SSM4567
8 *
9 * Copyright (C) 2015, Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License version
13 * 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <sound/pcm_params.h>
28#include "../../codecs/nau8825.h"
29
30#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
31#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
32
33static struct snd_soc_jack skylake_headset;
34static struct snd_soc_card skylake_audio_card;
35
36static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
37{
38 struct snd_soc_pcm_runtime *rtd;
39
40 list_for_each_entry(rtd, &card->rtd_list, list) {
41
42 if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
43 strlen(SKL_NUVOTON_CODEC_DAI)))
44 return rtd->codec_dai;
45 }
46
47 return NULL;
48}
49
50static const struct snd_kcontrol_new skylake_controls[] = {
51 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
52 SOC_DAPM_PIN_SWITCH("Headset Mic"),
53 SOC_DAPM_PIN_SWITCH("Left Speaker"),
54 SOC_DAPM_PIN_SWITCH("Right Speaker"),
55};
56
57static int platform_clock_control(struct snd_soc_dapm_widget *w,
58 struct snd_kcontrol *k, int event)
59{
60 struct snd_soc_dapm_context *dapm = w->dapm;
61 struct snd_soc_card *card = dapm->card;
62 struct snd_soc_dai *codec_dai;
63 int ret;
64
65 codec_dai = skl_get_codec_dai(card);
66 if (!codec_dai) {
67 dev_err(card->dev, "Codec dai not found\n");
68 return -EIO;
69 }
70
71 if (SND_SOC_DAPM_EVENT_ON(event)) {
72 ret = snd_soc_dai_set_sysclk(codec_dai,
73 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
74 if (ret < 0) {
75 dev_err(card->dev, "set sysclk err = %d\n", ret);
76 return -EIO;
77 }
78 } else {
79 ret = snd_soc_dai_set_sysclk(codec_dai,
80 NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
81 if (ret < 0) {
82 dev_err(card->dev, "set sysclk err = %d\n", ret);
83 return -EIO;
84 }
85 }
86 return ret;
87}
88
89static const struct snd_soc_dapm_widget skylake_widgets[] = {
90 SND_SOC_DAPM_HP("Headphone Jack", NULL),
91 SND_SOC_DAPM_MIC("Headset Mic", NULL),
92 SND_SOC_DAPM_SPK("Left Speaker", NULL),
93 SND_SOC_DAPM_SPK("Right Speaker", NULL),
94 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
95 SND_SOC_DAPM_SINK("WoV Sink"),
96 SND_SOC_DAPM_SPK("DP", NULL),
97 SND_SOC_DAPM_SPK("HDMI", NULL),
98 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
99 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
100 SND_SOC_DAPM_POST_PMD),
101};
102
103static const struct snd_soc_dapm_route skylake_map[] = {
104 /* HP jack connectors - unknown if we have jack detection */
105 {"Headphone Jack", NULL, "HPOL"},
106 {"Headphone Jack", NULL, "HPOR"},
107
108 /* speaker */
109 {"Left Speaker", NULL, "Left OUT"},
110 {"Right Speaker", NULL, "Right OUT"},
111
112 /* other jacks */
113 {"MIC", NULL, "Headset Mic"},
114 {"DMic", NULL, "SoC DMIC"},
115
116 {"WoV Sink", NULL, "hwd_in sink"},
117
118 {"HDMI", NULL, "hif5 Output"},
119 {"DP", NULL, "hif6 Output"},
120 /* CODEC BE connections */
121 { "Left Playback", NULL, "ssp0 Tx"},
122 { "Right Playback", NULL, "ssp0 Tx"},
123 { "ssp0 Tx", NULL, "codec0_out"},
124
125 { "Playback", NULL, "ssp1 Tx"},
126 { "ssp1 Tx", NULL, "codec1_out"},
127
128 { "codec0_in", NULL, "ssp1 Rx" },
129 { "ssp1 Rx", NULL, "Capture" },
130
131 /* DMIC */
132 { "dmic01_hifi", NULL, "DMIC01 Rx" },
133 { "DMIC01 Rx", NULL, "DMIC AIF" },
134 { "hifi1", NULL, "iDisp Tx"},
135 { "iDisp Tx", NULL, "iDisp_out"},
136 { "Headphone Jack", NULL, "Platform Clock" },
137 { "Headset Mic", NULL, "Platform Clock" },
138};
139
140static struct snd_soc_codec_conf ssm4567_codec_conf[] = {
141 {
142 .dev_name = "i2c-INT343B:00",
143 .name_prefix = "Left",
144 },
145 {
146 .dev_name = "i2c-INT343B:01",
147 .name_prefix = "Right",
148 },
149};
150
151static struct snd_soc_dai_link_component ssm4567_codec_components[] = {
152 { /* Left */
153 .name = "i2c-INT343B:00",
154 .dai_name = SKL_SSM_CODEC_DAI,
155 },
156 { /* Right */
157 .name = "i2c-INT343B:01",
158 .dai_name = SKL_SSM_CODEC_DAI,
159 },
160};
161
162static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd)
163{
164 int ret;
165
166 /* Slot 1 for left */
167 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[0], 0x01, 0x01, 2, 48);
168 if (ret < 0)
169 return ret;
170
171 /* Slot 2 for right */
172 ret = snd_soc_dai_set_tdm_slot(rtd->codec_dais[1], 0x02, 0x02, 2, 48);
173 if (ret < 0)
174 return ret;
175
176 return ret;
177}
178
179static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
180{
181 int ret;
182 struct snd_soc_codec *codec = rtd->codec;
183
184 /*
185 * 4 buttons here map to the google Reference headset
186 * The use of these buttons can be decided by the user space.
187 */
188 ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack",
189 SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
190 SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset,
191 NULL, 0);
192 if (ret) {
193 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
194 return ret;
195 }
196
197 nau8825_enable_jack_detect(codec, &skylake_headset);
198
199 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
200 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
201
202 return ret;
203}
204
205static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
206{
207 struct snd_soc_dapm_context *dapm;
208 struct snd_soc_component *component = rtd->cpu_dai->component;
209
210 dapm = snd_soc_component_get_dapm(component);
211 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
212
213 return 0;
214}
215
216static unsigned int rates[] = {
217 48000,
218};
219
220static struct snd_pcm_hw_constraint_list constraints_rates = {
221 .count = ARRAY_SIZE(rates),
222 .list = rates,
223 .mask = 0,
224};
225
226static unsigned int channels[] = {
227 2,
228};
229
230static struct snd_pcm_hw_constraint_list constraints_channels = {
231 .count = ARRAY_SIZE(channels),
232 .list = channels,
233 .mask = 0,
234};
235
236static int skl_fe_startup(struct snd_pcm_substream *substream)
237{
238 struct snd_pcm_runtime *runtime = substream->runtime;
239
240 /*
241 * on this platform for PCM device we support,
242 * 48Khz
243 * stereo
244 * 16 bit audio
245 */
246
247 runtime->hw.channels_max = 2;
248 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
249 &constraints_channels);
250
251 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
252 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
253
254 snd_pcm_hw_constraint_list(runtime, 0,
255 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
256
257 return 0;
258}
259
260static const struct snd_soc_ops skylake_nau8825_fe_ops = {
261 .startup = skl_fe_startup,
262};
263
264static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
265 struct snd_pcm_hw_params *params)
266{
267 struct snd_interval *rate = hw_param_interval(params,
268 SNDRV_PCM_HW_PARAM_RATE);
269 struct snd_interval *channels = hw_param_interval(params,
270 SNDRV_PCM_HW_PARAM_CHANNELS);
271 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
272
273 /* The ADSP will covert the FE rate to 48k, stereo */
274 rate->min = rate->max = 48000;
275 channels->min = channels->max = 2;
276
277 /* set SSP0 to 24 bit */
278 snd_mask_none(fmt);
279 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
280 return 0;
281}
282
283static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
284 struct snd_pcm_hw_params *params)
285{
286 struct snd_interval *channels = hw_param_interval(params,
287 SNDRV_PCM_HW_PARAM_CHANNELS);
288 if (params_channels(params) == 2)
289 channels->min = channels->max = 2;
290 else
291 channels->min = channels->max = 4;
292
293 return 0;
294}
295
296static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream,
297 struct snd_pcm_hw_params *params)
298{
299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct snd_soc_dai *codec_dai = rtd->codec_dai;
301 int ret;
302
303 ret = snd_soc_dai_set_sysclk(codec_dai,
304 NAU8825_CLK_MCLK, 24000000, SND_SOC_CLOCK_IN);
305
306 if (ret < 0)
307 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
308
309 return ret;
310}
311
312static struct snd_soc_ops skylake_nau8825_ops = {
313 .hw_params = skylake_nau8825_hw_params,
314};
315
316static unsigned int channels_dmic[] = {
317 2, 4,
318};
319
320static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
321 .count = ARRAY_SIZE(channels_dmic),
322 .list = channels_dmic,
323 .mask = 0,
324};
325
326static int skylake_dmic_startup(struct snd_pcm_substream *substream)
327{
328 struct snd_pcm_runtime *runtime = substream->runtime;
329
330 runtime->hw.channels_max = 4;
331 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
332 &constraints_dmic_channels);
333
334 return snd_pcm_hw_constraint_list(substream->runtime, 0,
335 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
336}
337
338static struct snd_soc_ops skylake_dmic_ops = {
339 .startup = skylake_dmic_startup,
340};
341
342static unsigned int rates_16000[] = {
343 16000,
344};
345
346static struct snd_pcm_hw_constraint_list constraints_16000 = {
347 .count = ARRAY_SIZE(rates_16000),
348 .list = rates_16000,
349};
350
351static int skylake_refcap_startup(struct snd_pcm_substream *substream)
352{
353 return snd_pcm_hw_constraint_list(substream->runtime, 0,
354 SNDRV_PCM_HW_PARAM_RATE,
355 &constraints_16000);
356}
357
358static struct snd_soc_ops skylaye_refcap_ops = {
359 .startup = skylake_refcap_startup,
360};
361
362/* skylake digital audio interface glue - connects codec <--> CPU */
363static struct snd_soc_dai_link skylake_dais[] = {
364 /* Front End DAI links */
365 {
366 .name = "Skl Audio Port",
367 .stream_name = "Audio",
368 .cpu_dai_name = "System Pin",
369 .platform_name = "0000:00:1f.3",
370 .dynamic = 1,
371 .codec_name = "snd-soc-dummy",
372 .codec_dai_name = "snd-soc-dummy-dai",
373 .nonatomic = 1,
374 .init = skylake_nau8825_fe_init,
375 .trigger = {
376 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
377 .dpcm_playback = 1,
378 .ops = &skylake_nau8825_fe_ops,
379 },
380 {
381 .name = "Skl Audio Capture Port",
382 .stream_name = "Audio Record",
383 .cpu_dai_name = "System Pin",
384 .platform_name = "0000:00:1f.3",
385 .dynamic = 1,
386 .codec_name = "snd-soc-dummy",
387 .codec_dai_name = "snd-soc-dummy-dai",
388 .nonatomic = 1,
389 .trigger = {
390 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
391 .dpcm_capture = 1,
392 .ops = &skylake_nau8825_fe_ops,
393 },
394 {
395 .name = "Skl Audio Reference cap",
396 .stream_name = "Wake on Voice",
397 .cpu_dai_name = "Reference Pin",
398 .codec_name = "snd-soc-dummy",
399 .codec_dai_name = "snd-soc-dummy-dai",
400 .platform_name = "0000:00:1f.3",
401 .init = NULL,
402 .dpcm_capture = 1,
403 .ignore_suspend = 1,
404 .nonatomic = 1,
405 .dynamic = 1,
406 .ops = &skylaye_refcap_ops,
407 },
408 {
409 .name = "Skl Audio DMIC cap",
410 .stream_name = "dmiccap",
411 .cpu_dai_name = "DMIC Pin",
412 .codec_name = "snd-soc-dummy",
413 .codec_dai_name = "snd-soc-dummy-dai",
414 .platform_name = "0000:00:1f.3",
415 .init = NULL,
416 .dpcm_capture = 1,
417 .nonatomic = 1,
418 .dynamic = 1,
419 .ops = &skylake_dmic_ops,
420 },
421 {
422 .name = "Skl HDMI Port",
423 .stream_name = "Hdmi",
424 .cpu_dai_name = "HDMI Pin",
425 .codec_name = "snd-soc-dummy",
426 .codec_dai_name = "snd-soc-dummy-dai",
427 .platform_name = "0000:00:1f.3",
428 .dpcm_playback = 1,
429 .init = NULL,
430 .nonatomic = 1,
431 .dynamic = 1,
432 },
433
434 /* Back End DAI links */
435 {
436 /* SSP0 - Codec */
437 .name = "SSP0-Codec",
438 .be_id = 0,
439 .cpu_dai_name = "SSP0 Pin",
440 .platform_name = "0000:00:1f.3",
441 .no_pcm = 1,
442 .codecs = ssm4567_codec_components,
443 .num_codecs = ARRAY_SIZE(ssm4567_codec_components),
444 .dai_fmt = SND_SOC_DAIFMT_DSP_A |
445 SND_SOC_DAIFMT_IB_NF |
446 SND_SOC_DAIFMT_CBS_CFS,
447 .init = skylake_ssm4567_codec_init,
448 .ignore_pmdown_time = 1,
449 .be_hw_params_fixup = skylake_ssp_fixup,
450 .dpcm_playback = 1,
451 },
452 {
453 /* SSP1 - Codec */
454 .name = "SSP1-Codec",
455 .be_id = 0,
456 .cpu_dai_name = "SSP1 Pin",
457 .platform_name = "0000:00:1f.3",
458 .no_pcm = 1,
459 .codec_name = "i2c-10508825:00",
460 .codec_dai_name = SKL_NUVOTON_CODEC_DAI,
461 .init = skylake_nau8825_codec_init,
462 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
463 SND_SOC_DAIFMT_CBS_CFS,
464 .ignore_pmdown_time = 1,
465 .be_hw_params_fixup = skylake_ssp_fixup,
466 .ops = &skylake_nau8825_ops,
467 .dpcm_playback = 1,
468 .dpcm_capture = 1,
469 },
470 {
471 .name = "dmic01",
472 .be_id = 1,
473 .cpu_dai_name = "DMIC01 Pin",
474 .codec_name = "dmic-codec",
475 .codec_dai_name = "dmic-hifi",
476 .platform_name = "0000:00:1f.3",
477 .ignore_suspend = 1,
478 .be_hw_params_fixup = skylake_dmic_fixup,
479 .dpcm_capture = 1,
480 .no_pcm = 1,
481 },
482 {
483 .name = "iDisp",
484 .be_id = 3,
485 .cpu_dai_name = "iDisp Pin",
486 .codec_name = "ehdaudio0D2",
487 .codec_dai_name = "intel-hdmi-hifi1",
488 .platform_name = "0000:00:1f.3",
489 .dpcm_playback = 1,
490 .no_pcm = 1,
491 },
492};
493
494/* skylake audio machine driver for SPT + NAU88L25 */
495static struct snd_soc_card skylake_audio_card = {
496 .name = "sklnau8825adi",
497 .owner = THIS_MODULE,
498 .dai_link = skylake_dais,
499 .num_links = ARRAY_SIZE(skylake_dais),
500 .controls = skylake_controls,
501 .num_controls = ARRAY_SIZE(skylake_controls),
502 .dapm_widgets = skylake_widgets,
503 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
504 .dapm_routes = skylake_map,
505 .num_dapm_routes = ARRAY_SIZE(skylake_map),
506 .codec_conf = ssm4567_codec_conf,
507 .num_configs = ARRAY_SIZE(ssm4567_codec_conf),
508 .fully_routed = true,
509};
510
511static int skylake_audio_probe(struct platform_device *pdev)
512{
513 skylake_audio_card.dev = &pdev->dev;
514
515 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
516}
517
518static struct platform_driver skylake_audio = {
519 .probe = skylake_audio_probe,
520 .driver = {
521 .name = "skl_nau88l25_ssm4567_i2s",
522 .pm = &snd_soc_pm_ops,
523 },
524};
525
526module_platform_driver(skylake_audio)
527
528/* Module information */
529MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
530MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
531MODULE_AUTHOR("Naveen M <naveen.m@intel.com>");
532MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
533MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
534MODULE_DESCRIPTION("Intel Audio Machine driver for SKL with NAU88L25 and SSM4567 in I2S Mode");
535MODULE_LICENSE("GPL v2");
536MODULE_ALIAS("platform:skl_nau88l25_ssm4567_i2s");
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index a73a431bd8b7..7396ddb427d8 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -52,6 +52,7 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = {
52 SND_SOC_DAPM_MIC("Mic Jack", NULL), 52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL), 53 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL), 54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55 SND_SOC_DAPM_SINK("WoV Sink"),
55}; 56};
56 57
57static const struct snd_soc_dapm_route skylake_rt286_map[] = { 58static const struct snd_soc_dapm_route skylake_rt286_map[] = {
@@ -67,7 +68,9 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
67 68
68 /* digital mics */ 69 /* digital mics */
69 {"DMIC1 Pin", NULL, "DMIC2"}, 70 {"DMIC1 Pin", NULL, "DMIC2"},
70 {"DMIC AIF", NULL, "SoC DMIC"}, 71 {"DMic", NULL, "SoC DMIC"},
72
73 {"WoV Sink", NULL, "hwd_in sink"},
71 74
72 /* CODEC BE connections */ 75 /* CODEC BE connections */
73 { "AIF1 Playback", NULL, "ssp0 Tx"}, 76 { "AIF1 Playback", NULL, "ssp0 Tx"},
@@ -79,13 +82,24 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = {
79 { "ssp0 Rx", NULL, "AIF1 Capture" }, 82 { "ssp0 Rx", NULL, "AIF1 Capture" },
80 83
81 { "dmic01_hifi", NULL, "DMIC01 Rx" }, 84 { "dmic01_hifi", NULL, "DMIC01 Rx" },
82 { "DMIC01 Rx", NULL, "Capture" }, 85 { "DMIC01 Rx", NULL, "DMIC AIF" },
83 86
84 { "hif1", NULL, "iDisp Tx"}, 87 { "hif1", NULL, "iDisp Tx"},
85 { "iDisp Tx", NULL, "iDisp_out"}, 88 { "iDisp Tx", NULL, "iDisp_out"},
86 89
87}; 90};
88 91
92static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
93{
94 struct snd_soc_dapm_context *dapm;
95 struct snd_soc_component *component = rtd->cpu_dai->component;
96
97 dapm = snd_soc_component_get_dapm(component);
98 snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
99
100 return 0;
101}
102
89static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) 103static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
90{ 104{
91 struct snd_soc_codec *codec = rtd->codec; 105 struct snd_soc_codec *codec = rtd->codec;
@@ -101,9 +115,59 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
101 115
102 rt286_mic_detect(codec, &skylake_headset); 116 rt286_mic_detect(codec, &skylake_headset);
103 117
118 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
119 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
120
104 return 0; 121 return 0;
105} 122}
106 123
124static unsigned int rates[] = {
125 48000,
126};
127
128static struct snd_pcm_hw_constraint_list constraints_rates = {
129 .count = ARRAY_SIZE(rates),
130 .list = rates,
131 .mask = 0,
132};
133
134static unsigned int channels[] = {
135 2,
136};
137
138static struct snd_pcm_hw_constraint_list constraints_channels = {
139 .count = ARRAY_SIZE(channels),
140 .list = channels,
141 .mask = 0,
142};
143
144static int skl_fe_startup(struct snd_pcm_substream *substream)
145{
146 struct snd_pcm_runtime *runtime = substream->runtime;
147
148 /*
149 * on this platform for PCM device we support,
150 * 48Khz
151 * stereo
152 * 16 bit audio
153 */
154
155 runtime->hw.channels_max = 2;
156 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
157 &constraints_channels);
158
159 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
160 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
161
162 snd_pcm_hw_constraint_list(runtime, 0,
163 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
164
165 return 0;
166}
167
168static const struct snd_soc_ops skylake_rt286_fe_ops = {
169 .startup = skl_fe_startup,
170};
107 171
108static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, 172static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
109 struct snd_pcm_hw_params *params) 173 struct snd_pcm_hw_params *params)
@@ -112,12 +176,15 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
112 SNDRV_PCM_HW_PARAM_RATE); 176 SNDRV_PCM_HW_PARAM_RATE);
113 struct snd_interval *channels = hw_param_interval(params, 177 struct snd_interval *channels = hw_param_interval(params,
114 SNDRV_PCM_HW_PARAM_CHANNELS); 178 SNDRV_PCM_HW_PARAM_CHANNELS);
179 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
115 180
116 /* The output is 48KHz, stereo, 16bits */ 181 /* The output is 48KHz, stereo, 16bits */
117 rate->min = rate->max = 48000; 182 rate->min = rate->max = 48000;
118 channels->min = channels->max = 2; 183 channels->min = channels->max = 2;
119 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
120 184
185 /* set SSP0 to 24 bit */
186 snd_mask_none(fmt);
187 snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
121 return 0; 188 return 0;
122} 189}
123 190
@@ -140,6 +207,42 @@ static struct snd_soc_ops skylake_rt286_ops = {
140 .hw_params = skylake_rt286_hw_params, 207 .hw_params = skylake_rt286_hw_params,
141}; 208};
142 209
210static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
211 struct snd_pcm_hw_params *params)
212{
213 struct snd_interval *channels = hw_param_interval(params,
214 SNDRV_PCM_HW_PARAM_CHANNELS);
215 channels->min = channels->max = 4;
216
217 return 0;
218}
219
220static unsigned int channels_dmic[] = {
221 2, 4,
222};
223
224static struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
225 .count = ARRAY_SIZE(channels_dmic),
226 .list = channels_dmic,
227 .mask = 0,
228};
229
230static int skylake_dmic_startup(struct snd_pcm_substream *substream)
231{
232 struct snd_pcm_runtime *runtime = substream->runtime;
233
234 runtime->hw.channels_max = 4;
235 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
236 &constraints_dmic_channels);
237
238 return snd_pcm_hw_constraint_list(substream->runtime, 0,
239 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
240}
241
242static struct snd_soc_ops skylake_dmic_ops = {
243 .startup = skylake_dmic_startup,
244};
245
143/* skylake digital audio interface glue - connects codec <--> CPU */ 246/* skylake digital audio interface glue - connects codec <--> CPU */
144static struct snd_soc_dai_link skylake_rt286_dais[] = { 247static struct snd_soc_dai_link skylake_rt286_dais[] = {
145 /* Front End DAI links */ 248 /* Front End DAI links */
@@ -152,11 +255,13 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
152 .dynamic = 1, 255 .dynamic = 1,
153 .codec_name = "snd-soc-dummy", 256 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai", 257 .codec_dai_name = "snd-soc-dummy-dai",
258 .init = skylake_rt286_fe_init,
155 .trigger = { 259 .trigger = {
156 SND_SOC_DPCM_TRIGGER_POST, 260 SND_SOC_DPCM_TRIGGER_POST,
157 SND_SOC_DPCM_TRIGGER_POST 261 SND_SOC_DPCM_TRIGGER_POST
158 }, 262 },
159 .dpcm_playback = 1, 263 .dpcm_playback = 1,
264 .ops = &skylake_rt286_fe_ops,
160 }, 265 },
161 { 266 {
162 .name = "Skl Audio Capture Port", 267 .name = "Skl Audio Capture Port",
@@ -172,6 +277,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
172 SND_SOC_DPCM_TRIGGER_POST 277 SND_SOC_DPCM_TRIGGER_POST
173 }, 278 },
174 .dpcm_capture = 1, 279 .dpcm_capture = 1,
280 .ops = &skylake_rt286_fe_ops,
175 }, 281 },
176 { 282 {
177 .name = "Skl Audio Reference cap", 283 .name = "Skl Audio Reference cap",
@@ -186,6 +292,19 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
186 .nonatomic = 1, 292 .nonatomic = 1,
187 .dynamic = 1, 293 .dynamic = 1,
188 }, 294 },
295 {
296 .name = "Skl Audio DMIC cap",
297 .stream_name = "dmiccap",
298 .cpu_dai_name = "DMIC Pin",
299 .codec_name = "snd-soc-dummy",
300 .codec_dai_name = "snd-soc-dummy-dai",
301 .platform_name = "0000:00:1f.3",
302 .init = NULL,
303 .dpcm_capture = 1,
304 .nonatomic = 1,
305 .dynamic = 1,
306 .ops = &skylake_dmic_ops,
307 },
189 308
190 /* Back End DAI links */ 309 /* Back End DAI links */
191 { 310 {
@@ -201,7 +320,6 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
201 .dai_fmt = SND_SOC_DAIFMT_I2S | 320 .dai_fmt = SND_SOC_DAIFMT_I2S |
202 SND_SOC_DAIFMT_NB_NF | 321 SND_SOC_DAIFMT_NB_NF |
203 SND_SOC_DAIFMT_CBS_CFS, 322 SND_SOC_DAIFMT_CBS_CFS,
204 .ignore_suspend = 1,
205 .ignore_pmdown_time = 1, 323 .ignore_pmdown_time = 1,
206 .be_hw_params_fixup = skylake_ssp0_fixup, 324 .be_hw_params_fixup = skylake_ssp0_fixup,
207 .ops = &skylake_rt286_ops, 325 .ops = &skylake_rt286_ops,
@@ -215,6 +333,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
215 .codec_name = "dmic-codec", 333 .codec_name = "dmic-codec",
216 .codec_dai_name = "dmic-hifi", 334 .codec_dai_name = "dmic-hifi",
217 .platform_name = "0000:00:1f.3", 335 .platform_name = "0000:00:1f.3",
336 .be_hw_params_fixup = skylake_dmic_fixup,
218 .ignore_suspend = 1, 337 .ignore_suspend = 1,
219 .dpcm_capture = 1, 338 .dpcm_capture = 1,
220 .no_pcm = 1, 339 .no_pcm = 1,
@@ -247,6 +366,7 @@ static struct platform_driver skylake_audio = {
247 .probe = skylake_audio_probe, 366 .probe = skylake_audio_probe,
248 .driver = { 367 .driver = {
249 .name = "skl_alc286s_i2s", 368 .name = "skl_alc286s_i2s",
369 .pm = &snd_soc_pm_ops,
250 }, 370 },
251}; 371};
252 372
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index d9105584c51f..3b9332e7a094 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,11 +1,8 @@
1snd-soc-sst-dsp-objs := sst-dsp.o 1snd-soc-sst-dsp-objs := sst-dsp.o
2snd-soc-sst-acpi-objs := sst-acpi.o 2snd-soc-sst-acpi-objs := sst-acpi.o sst-match-acpi.o
3snd-soc-sst-ipc-objs := sst-ipc.o 3snd-soc-sst-ipc-objs := sst-ipc.o
4 4
5ifneq ($(CONFIG_DW_DMAC_CORE),) 5snd-soc-sst-dsp-$(CONFIG_DW_DMAC_CORE) += sst-firmware.o
6snd-soc-sst-dsp-objs += sst-firmware.o
7endif
8 6
9obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 7obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
10obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o 8obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
11
diff --git a/sound/soc/intel/common/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index 67b6d3d52f57..7a85c576dad3 100644
--- a/sound/soc/intel/common/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -21,21 +21,12 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22 22
23#include "sst-dsp.h" 23#include "sst-dsp.h"
24#include "sst-acpi.h"
24 25
25#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000 26#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000
26#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000 27#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
27#define SST_LPT_DSP_DMA_SIZE (1024 - 1) 28#define SST_LPT_DSP_DMA_SIZE (1024 - 1)
28 29
29/* Descriptor for SST ASoC machine driver */
30struct sst_acpi_mach {
31 /* ACPI ID for the matching machine driver. Audio codec for instance */
32 const u8 id[ACPI_ID_LEN];
33 /* machine driver name */
34 const char *drv_name;
35 /* firmware file name */
36 const char *fw_filename;
37};
38
39/* Descriptor for setting up SST platform data */ 30/* Descriptor for setting up SST platform data */
40struct sst_acpi_desc { 31struct sst_acpi_desc {
41 const char *drv_name; 32 const char *drv_name;
@@ -88,28 +79,6 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
88 return; 79 return;
89} 80}
90 81
91static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
92 void *context, void **ret)
93{
94 *(bool *)context = true;
95 return AE_OK;
96}
97
98static struct sst_acpi_mach *sst_acpi_find_machine(
99 struct sst_acpi_mach *machines)
100{
101 struct sst_acpi_mach *mach;
102 bool found = false;
103
104 for (mach = machines; mach->id[0]; mach++)
105 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
106 sst_acpi_mach_match,
107 &found, NULL)) && found)
108 return mach;
109
110 return NULL;
111}
112
113static int sst_acpi_probe(struct platform_device *pdev) 82static int sst_acpi_probe(struct platform_device *pdev)
114{ 83{
115 const struct acpi_device_id *id; 84 const struct acpi_device_id *id;
@@ -211,7 +180,7 @@ static int sst_acpi_remove(struct platform_device *pdev)
211} 180}
212 181
213static struct sst_acpi_mach haswell_machines[] = { 182static struct sst_acpi_mach haswell_machines[] = {
214 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin" }, 183 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin", NULL, NULL, NULL },
215 {} 184 {}
216}; 185};
217 186
@@ -229,7 +198,7 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
229}; 198};
230 199
231static struct sst_acpi_mach broadwell_machines[] = { 200static struct sst_acpi_mach broadwell_machines[] = {
232 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin" }, 201 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
233 {} 202 {}
234}; 203};
235 204
@@ -247,8 +216,8 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
247}; 216};
248 217
249static struct sst_acpi_mach baytrail_machines[] = { 218static struct sst_acpi_mach baytrail_machines[] = {
250 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, 219 { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
251 { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master" }, 220 { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
252 {} 221 {}
253}; 222};
254 223
diff --git a/sound/soc/intel/common/sst-acpi.h b/sound/soc/intel/common/sst-acpi.h
new file mode 100644
index 000000000000..3ee3b7ab5d03
--- /dev/null
+++ b/sound/soc/intel/common/sst-acpi.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2013-15, Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License version
6 * 2 as 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
15#include <linux/acpi.h>
16
17/* acpi match */
18struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines);
19
20/* Descriptor for SST ASoC machine driver */
21struct sst_acpi_mach {
22 /* ACPI ID for the matching machine driver. Audio codec for instance */
23 const u8 id[ACPI_ID_LEN];
24 /* machine driver name */
25 const char *drv_name;
26 /* firmware file name */
27 const char *fw_filename;
28
29 /* board name */
30 const char *board;
31 void (*machine_quirk)(void);
32 void *pdata;
33};
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index 2151652d37b7..81aa1ed64201 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -243,7 +243,7 @@ struct sst_mem_block {
243 u32 size; /* block size */ 243 u32 size; /* block size */
244 u32 index; /* block index 0..N */ 244 u32 index; /* block index 0..N */
245 enum sst_mem_type type; /* block memory type IRAM/DRAM */ 245 enum sst_mem_type type; /* block memory type IRAM/DRAM */
246 struct sst_block_ops *ops; /* block operations, if any */ 246 const struct sst_block_ops *ops;/* block operations, if any */
247 247
248 /* block status */ 248 /* block status */
249 u32 bytes_used; /* bytes in use by modules */ 249 u32 bytes_used; /* bytes in use by modules */
@@ -308,6 +308,8 @@ struct sst_dsp {
308 308
309 /* SKL data */ 309 /* SKL data */
310 310
311 const char *fw_name;
312
311 /* To allocate CL dma buffers */ 313 /* To allocate CL dma buffers */
312 struct skl_dsp_loader_ops dsp_ops; 314 struct skl_dsp_loader_ops dsp_ops;
313 struct skl_dsp_fw_ops fw_ops; 315 struct skl_dsp_fw_ops fw_ops;
@@ -376,8 +378,8 @@ void sst_block_free_scratch(struct sst_dsp *dsp);
376 378
377/* Register the DSPs memory blocks - would be nice to read from ACPI */ 379/* Register the DSPs memory blocks - would be nice to read from ACPI */
378struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, 380struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
379 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, 381 u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
380 void *private); 382 u32 index, void *private);
381void sst_mem_block_unregister_all(struct sst_dsp *dsp); 383void sst_mem_block_unregister_all(struct sst_dsp *dsp);
382 384
383/* Create/Free DMA resources */ 385/* Create/Free DMA resources */
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index c9452e02e0dd..b5bbdf4fe93a 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -420,7 +420,7 @@ void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
420} 420}
421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
422 422
423#if IS_ENABLED(CONFIG_DW_DMAC_CORE) 423#ifdef CONFIG_DW_DMAC_CORE
424struct sst_dsp *sst_dsp_new(struct device *dev, 424struct sst_dsp *sst_dsp_new(struct device *dev,
425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata) 425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
426{ 426{
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index 859f0de00339..0b84c719ec48 100644
--- a/sound/soc/intel/common/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -216,7 +216,7 @@ struct sst_pdata {
216 void *dsp; 216 void *dsp;
217}; 217};
218 218
219#if IS_ENABLED(CONFIG_DW_DMAC_CORE) 219#ifdef CONFIG_DW_DMAC_CORE
220/* Initialization */ 220/* Initialization */
221struct sst_dsp *sst_dsp_new(struct device *dev, 221struct sst_dsp *sst_dsp_new(struct device *dev,
222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata); 222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index 1636a1eeb002..ef4881e7753a 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -51,8 +51,22 @@ struct sst_dma {
51 51
52static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) 52static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes)
53{ 53{
54 u32 tmp = 0;
55 int i, m, n;
56 const u8 *src_byte = src;
57
58 m = bytes / 4;
59 n = bytes % 4;
60
54 /* __iowrite32_copy use 32bit size values so divide by 4 */ 61 /* __iowrite32_copy use 32bit size values so divide by 4 */
55 __iowrite32_copy((void *)dest, src, bytes/4); 62 __iowrite32_copy((void *)dest, src, m);
63
64 if (n) {
65 for (i = 0; i < n; i++)
66 tmp |= (u32)*(src_byte + m * 4 + i) << (i * 8);
67 __iowrite32_copy((void *)(dest + m * 4), &tmp, 1);
68 }
69
56} 70}
57 71
58static void sst_dma_transfer_complete(void *arg) 72static void sst_dma_transfer_complete(void *arg)
@@ -1014,8 +1028,8 @@ EXPORT_SYMBOL_GPL(sst_module_runtime_restore);
1014 1028
1015/* register a DSP memory block for use with FW based modules */ 1029/* register a DSP memory block for use with FW based modules */
1016struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset, 1030struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
1017 u32 size, enum sst_mem_type type, struct sst_block_ops *ops, u32 index, 1031 u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
1018 void *private) 1032 u32 index, void *private)
1019{ 1033{
1020 struct sst_mem_block *block; 1034 struct sst_mem_block *block;
1021 1035
diff --git a/sound/soc/intel/common/sst-match-acpi.c b/sound/soc/intel/common/sst-match-acpi.c
new file mode 100644
index 000000000000..dd077e116d25
--- /dev/null
+++ b/sound/soc/intel/common/sst-match-acpi.c
@@ -0,0 +1,43 @@
1/*
2 * sst_match_apci.c - SST (LPE) match for ACPI enumeration.
3 *
4 * Copyright (c) 2013-15, Intel Corporation.
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions 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 it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16#include <linux/acpi.h>
17#include <linux/device.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20
21#include "sst-acpi.h"
22
23static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
24 void *context, void **ret)
25{
26 *(bool *)context = true;
27 return AE_OK;
28}
29
30struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
31{
32 struct sst_acpi_mach *mach;
33 bool found = false;
34
35 for (mach = machines; mach->id[0]; mach++)
36 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
37 sst_acpi_mach_match,
38 &found, NULL)) && found)
39 return mach;
40
41 return NULL;
42}
43EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
diff --git a/sound/soc/intel/haswell/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c
index 7f94920c8a4d..b2bec36d074c 100644
--- a/sound/soc/intel/haswell/sst-haswell-dsp.c
+++ b/sound/soc/intel/haswell/sst-haswell-dsp.c
@@ -607,7 +607,7 @@ static int hsw_block_disable(struct sst_mem_block *block)
607 return 0; 607 return 0;
608} 608}
609 609
610static struct sst_block_ops sst_hsw_ops = { 610static const struct sst_block_ops sst_hsw_ops = {
611 .enable = hsw_block_enable, 611 .enable = hsw_block_enable,
612 .disable = hsw_block_disable, 612 .disable = hsw_block_disable,
613}; 613};
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index b27f25f70730..ac60f1301e21 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -778,7 +778,6 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
778 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst); 778 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst);
779 struct sst_generic_ipc *ipc = &hsw->ipc; 779 struct sst_generic_ipc *ipc = &hsw->ipc;
780 u32 ipcx, ipcd; 780 u32 ipcx, ipcd;
781 int handled;
782 unsigned long flags; 781 unsigned long flags;
783 782
784 spin_lock_irqsave(&sst->spinlock, flags); 783 spin_lock_irqsave(&sst->spinlock, flags);
@@ -790,34 +789,30 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
790 if (ipcx & SST_IPCX_DONE) { 789 if (ipcx & SST_IPCX_DONE) {
791 790
792 /* Handle Immediate reply from DSP Core */ 791 /* Handle Immediate reply from DSP Core */
793 handled = hsw_process_reply(hsw, ipcx); 792 hsw_process_reply(hsw, ipcx);
794 793
795 if (handled > 0) { 794 /* clear DONE bit - tell DSP we have completed */
796 /* clear DONE bit - tell DSP we have completed */ 795 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCX,
797 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCX, 796 SST_IPCX_DONE, 0);
798 SST_IPCX_DONE, 0);
799 797
800 /* unmask Done interrupt */ 798 /* unmask Done interrupt */
801 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 799 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
802 SST_IMRX_DONE, 0); 800 SST_IMRX_DONE, 0);
803 }
804 } 801 }
805 802
806 /* new message from DSP */ 803 /* new message from DSP */
807 if (ipcd & SST_IPCD_BUSY) { 804 if (ipcd & SST_IPCD_BUSY) {
808 805
809 /* Handle Notification and Delayed reply from DSP Core */ 806 /* Handle Notification and Delayed reply from DSP Core */
810 handled = hsw_process_notification(hsw); 807 hsw_process_notification(hsw);
811 808
812 /* clear BUSY bit and set DONE bit - accept new messages */ 809 /* clear BUSY bit and set DONE bit - accept new messages */
813 if (handled > 0) { 810 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCD,
814 sst_dsp_shim_update_bits_unlocked(sst, SST_IPCD, 811 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
815 SST_IPCD_BUSY | SST_IPCD_DONE, SST_IPCD_DONE);
816 812
817 /* unmask busy interrupt */ 813 /* unmask busy interrupt */
818 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX, 814 sst_dsp_shim_update_bits_unlocked(sst, SST_IMRX,
819 SST_IMRX_BUSY, 0); 815 SST_IMRX_BUSY, 0);
820 }
821 } 816 }
822 817
823 spin_unlock_irqrestore(&sst->spinlock, flags); 818 spin_unlock_irqrestore(&sst->spinlock, flags);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 50a109503a3f..de6dac496a0d 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -96,7 +96,7 @@ int skl_init_dsp(struct skl *skl)
96 } 96 }
97 97
98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq, 98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
99 loader_ops, &skl->skl_sst); 99 skl->fw_name, loader_ops, &skl->skl_sst);
100 if (ret < 0) 100 if (ret < 0)
101 return ret; 101 return ret;
102 102
@@ -182,94 +182,6 @@ enum skl_bitdepth skl_get_bit_depth(int params)
182 } 182 }
183} 183}
184 184
185static u32 skl_create_channel_map(enum skl_ch_cfg ch_cfg)
186{
187 u32 config;
188
189 switch (ch_cfg) {
190 case SKL_CH_CFG_MONO:
191 config = (0xFFFFFFF0 | SKL_CHANNEL_LEFT);
192 break;
193
194 case SKL_CH_CFG_STEREO:
195 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
196 | (SKL_CHANNEL_RIGHT << 4));
197 break;
198
199 case SKL_CH_CFG_2_1:
200 config = (0xFFFFF000 | SKL_CHANNEL_LEFT
201 | (SKL_CHANNEL_RIGHT << 4)
202 | (SKL_CHANNEL_LFE << 8));
203 break;
204
205 case SKL_CH_CFG_3_0:
206 config = (0xFFFFF000 | SKL_CHANNEL_LEFT
207 | (SKL_CHANNEL_CENTER << 4)
208 | (SKL_CHANNEL_RIGHT << 8));
209 break;
210
211 case SKL_CH_CFG_3_1:
212 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
213 | (SKL_CHANNEL_CENTER << 4)
214 | (SKL_CHANNEL_RIGHT << 8)
215 | (SKL_CHANNEL_LFE << 12));
216 break;
217
218 case SKL_CH_CFG_QUATRO:
219 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
220 | (SKL_CHANNEL_RIGHT << 4)
221 | (SKL_CHANNEL_LEFT_SURROUND << 8)
222 | (SKL_CHANNEL_RIGHT_SURROUND << 12));
223 break;
224
225 case SKL_CH_CFG_4_0:
226 config = (0xFFFF0000 | SKL_CHANNEL_LEFT
227 | (SKL_CHANNEL_CENTER << 4)
228 | (SKL_CHANNEL_RIGHT << 8)
229 | (SKL_CHANNEL_CENTER_SURROUND << 12));
230 break;
231
232 case SKL_CH_CFG_5_0:
233 config = (0xFFF00000 | SKL_CHANNEL_LEFT
234 | (SKL_CHANNEL_CENTER << 4)
235 | (SKL_CHANNEL_RIGHT << 8)
236 | (SKL_CHANNEL_LEFT_SURROUND << 12)
237 | (SKL_CHANNEL_RIGHT_SURROUND << 16));
238 break;
239
240 case SKL_CH_CFG_5_1:
241 config = (0xFF000000 | SKL_CHANNEL_CENTER
242 | (SKL_CHANNEL_LEFT << 4)
243 | (SKL_CHANNEL_RIGHT << 8)
244 | (SKL_CHANNEL_LEFT_SURROUND << 12)
245 | (SKL_CHANNEL_RIGHT_SURROUND << 16)
246 | (SKL_CHANNEL_LFE << 20));
247 break;
248
249 case SKL_CH_CFG_DUAL_MONO:
250 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
251 | (SKL_CHANNEL_LEFT << 4));
252 break;
253
254 case SKL_CH_CFG_I2S_DUAL_STEREO_0:
255 config = (0xFFFFFF00 | SKL_CHANNEL_LEFT
256 | (SKL_CHANNEL_RIGHT << 4));
257 break;
258
259 case SKL_CH_CFG_I2S_DUAL_STEREO_1:
260 config = (0xFFFF00FF | (SKL_CHANNEL_LEFT << 8)
261 | (SKL_CHANNEL_RIGHT << 12));
262 break;
263
264 default:
265 config = 0xFFFFFFFF;
266 break;
267
268 }
269
270 return config;
271}
272
273/* 185/*
274 * Each module in DSP expects a base module configuration, which consists of 186 * Each module in DSP expects a base module configuration, which consists of
275 * PCM format information, which we calculate in driver and resource values 187 * PCM format information, which we calculate in driver and resource values
@@ -280,7 +192,7 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
280 struct skl_module_cfg *mconfig, 192 struct skl_module_cfg *mconfig,
281 struct skl_base_cfg *base_cfg) 193 struct skl_base_cfg *base_cfg)
282{ 194{
283 struct skl_module_fmt *format = &mconfig->in_fmt; 195 struct skl_module_fmt *format = &mconfig->in_fmt[0];
284 196
285 base_cfg->audio_fmt.number_of_channels = (u8)format->channels; 197 base_cfg->audio_fmt.number_of_channels = (u8)format->channels;
286 198
@@ -293,14 +205,14 @@ static void skl_set_base_module_format(struct skl_sst *ctx,
293 format->bit_depth, format->valid_bit_depth, 205 format->bit_depth, format->valid_bit_depth,
294 format->ch_cfg); 206 format->ch_cfg);
295 207
296 base_cfg->audio_fmt.channel_map = skl_create_channel_map( 208 base_cfg->audio_fmt.channel_map = format->ch_map;
297 base_cfg->audio_fmt.ch_cfg);
298 209
299 base_cfg->audio_fmt.interleaving = SKL_INTERLEAVING_PER_CHANNEL; 210 base_cfg->audio_fmt.interleaving = format->interleaving_style;
300 211
301 base_cfg->cps = mconfig->mcps; 212 base_cfg->cps = mconfig->mcps;
302 base_cfg->ibs = mconfig->ibs; 213 base_cfg->ibs = mconfig->ibs;
303 base_cfg->obs = mconfig->obs; 214 base_cfg->obs = mconfig->obs;
215 base_cfg->is_pages = mconfig->mem_pages;
304} 216}
305 217
306/* 218/*
@@ -399,7 +311,7 @@ static void skl_setup_out_format(struct skl_sst *ctx,
399 struct skl_module_cfg *mconfig, 311 struct skl_module_cfg *mconfig,
400 struct skl_audio_data_format *out_fmt) 312 struct skl_audio_data_format *out_fmt)
401{ 313{
402 struct skl_module_fmt *format = &mconfig->out_fmt; 314 struct skl_module_fmt *format = &mconfig->out_fmt[0];
403 315
404 out_fmt->number_of_channels = (u8)format->channels; 316 out_fmt->number_of_channels = (u8)format->channels;
405 out_fmt->s_freq = format->s_freq; 317 out_fmt->s_freq = format->s_freq;
@@ -407,8 +319,9 @@ static void skl_setup_out_format(struct skl_sst *ctx,
407 out_fmt->valid_bit_depth = format->valid_bit_depth; 319 out_fmt->valid_bit_depth = format->valid_bit_depth;
408 out_fmt->ch_cfg = format->ch_cfg; 320 out_fmt->ch_cfg = format->ch_cfg;
409 321
410 out_fmt->channel_map = skl_create_channel_map(out_fmt->ch_cfg); 322 out_fmt->channel_map = format->ch_map;
411 out_fmt->interleaving = SKL_INTERLEAVING_PER_CHANNEL; 323 out_fmt->interleaving = format->interleaving_style;
324 out_fmt->sample_type = format->sample_type;
412 325
413 dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", 326 dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
414 out_fmt->number_of_channels, format->s_freq, format->bit_depth); 327 out_fmt->number_of_channels, format->s_freq, format->bit_depth);
@@ -423,7 +336,7 @@ static void skl_set_src_format(struct skl_sst *ctx,
423 struct skl_module_cfg *mconfig, 336 struct skl_module_cfg *mconfig,
424 struct skl_src_module_cfg *src_mconfig) 337 struct skl_src_module_cfg *src_mconfig)
425{ 338{
426 struct skl_module_fmt *fmt = &mconfig->out_fmt; 339 struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
427 340
428 skl_set_base_module_format(ctx, mconfig, 341 skl_set_base_module_format(ctx, mconfig,
429 (struct skl_base_cfg *)src_mconfig); 342 (struct skl_base_cfg *)src_mconfig);
@@ -440,7 +353,7 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
440 struct skl_module_cfg *mconfig, 353 struct skl_module_cfg *mconfig,
441 struct skl_up_down_mixer_cfg *mixer_mconfig) 354 struct skl_up_down_mixer_cfg *mixer_mconfig)
442{ 355{
443 struct skl_module_fmt *fmt = &mconfig->out_fmt; 356 struct skl_module_fmt *fmt = &mconfig->out_fmt[0];
444 int i = 0; 357 int i = 0;
445 358
446 skl_set_base_module_format(ctx, mconfig, 359 skl_set_base_module_format(ctx, mconfig,
@@ -475,6 +388,47 @@ static void skl_set_copier_format(struct skl_sst *ctx,
475 skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); 388 skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig);
476} 389}
477 390
391/*
392 * Algo module are DSP pre processing modules. Algo module take base module
393 * configuration and params
394 */
395
396static void skl_set_algo_format(struct skl_sst *ctx,
397 struct skl_module_cfg *mconfig,
398 struct skl_algo_cfg *algo_mcfg)
399{
400 struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
401
402 skl_set_base_module_format(ctx, mconfig, base_cfg);
403
404 if (mconfig->formats_config.caps_size == 0)
405 return;
406
407 memcpy(algo_mcfg->params,
408 mconfig->formats_config.caps,
409 mconfig->formats_config.caps_size);
410
411}
412
413/*
414 * Mic select module allows selecting one or many input channels, thus
415 * acting as a demux.
416 *
417 * Mic select module take base module configuration and out-format
418 * configuration
419 */
420static void skl_set_base_outfmt_format(struct skl_sst *ctx,
421 struct skl_module_cfg *mconfig,
422 struct skl_base_outfmt_cfg *base_outfmt_mcfg)
423{
424 struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt;
425 struct skl_base_cfg *base_cfg =
426 (struct skl_base_cfg *)base_outfmt_mcfg;
427
428 skl_set_base_module_format(ctx, mconfig, base_cfg);
429 skl_setup_out_format(ctx, mconfig, out_fmt);
430}
431
478static u16 skl_get_module_param_size(struct skl_sst *ctx, 432static u16 skl_get_module_param_size(struct skl_sst *ctx,
479 struct skl_module_cfg *mconfig) 433 struct skl_module_cfg *mconfig)
480{ 434{
@@ -492,6 +446,14 @@ static u16 skl_get_module_param_size(struct skl_sst *ctx,
492 case SKL_MODULE_TYPE_UPDWMIX: 446 case SKL_MODULE_TYPE_UPDWMIX:
493 return sizeof(struct skl_up_down_mixer_cfg); 447 return sizeof(struct skl_up_down_mixer_cfg);
494 448
449 case SKL_MODULE_TYPE_ALGO:
450 param_size = sizeof(struct skl_base_cfg);
451 param_size += mconfig->formats_config.caps_size;
452 return param_size;
453
454 case SKL_MODULE_TYPE_BASE_OUTFMT:
455 return sizeof(struct skl_base_outfmt_cfg);
456
495 default: 457 default:
496 /* 458 /*
497 * return only base cfg when no specific module type is 459 * return only base cfg when no specific module type is
@@ -538,6 +500,14 @@ static int skl_set_module_format(struct skl_sst *ctx,
538 skl_set_updown_mixer_format(ctx, module_config, *param_data); 500 skl_set_updown_mixer_format(ctx, module_config, *param_data);
539 break; 501 break;
540 502
503 case SKL_MODULE_TYPE_ALGO:
504 skl_set_algo_format(ctx, module_config, *param_data);
505 break;
506
507 case SKL_MODULE_TYPE_BASE_OUTFMT:
508 skl_set_base_outfmt_format(ctx, module_config, *param_data);
509 break;
510
541 default: 511 default:
542 skl_set_base_module_format(ctx, module_config, *param_data); 512 skl_set_base_module_format(ctx, module_config, *param_data);
543 break; 513 break;
@@ -571,10 +541,10 @@ static int skl_get_queue_index(struct skl_module_pin *mpin,
571 * In static, the pin_index is fixed based on module_id and instance id 541 * In static, the pin_index is fixed based on module_id and instance id
572 */ 542 */
573static int skl_alloc_queue(struct skl_module_pin *mpin, 543static int skl_alloc_queue(struct skl_module_pin *mpin,
574 struct skl_module_inst_id id, int max) 544 struct skl_module_cfg *tgt_cfg, int max)
575{ 545{
576 int i; 546 int i;
577 547 struct skl_module_inst_id id = tgt_cfg->id;
578 /* 548 /*
579 * if pin in dynamic, find first free pin 549 * if pin in dynamic, find first free pin
580 * otherwise find match module and instance id pin as topology will 550 * otherwise find match module and instance id pin as topology will
@@ -583,16 +553,23 @@ static int skl_alloc_queue(struct skl_module_pin *mpin,
583 */ 553 */
584 for (i = 0; i < max; i++) { 554 for (i = 0; i < max; i++) {
585 if (mpin[i].is_dynamic) { 555 if (mpin[i].is_dynamic) {
586 if (!mpin[i].in_use) { 556 if (!mpin[i].in_use &&
557 mpin[i].pin_state == SKL_PIN_UNBIND) {
558
587 mpin[i].in_use = true; 559 mpin[i].in_use = true;
588 mpin[i].id.module_id = id.module_id; 560 mpin[i].id.module_id = id.module_id;
589 mpin[i].id.instance_id = id.instance_id; 561 mpin[i].id.instance_id = id.instance_id;
562 mpin[i].tgt_mcfg = tgt_cfg;
590 return i; 563 return i;
591 } 564 }
592 } else { 565 } else {
593 if (mpin[i].id.module_id == id.module_id && 566 if (mpin[i].id.module_id == id.module_id &&
594 mpin[i].id.instance_id == id.instance_id) 567 mpin[i].id.instance_id == id.instance_id &&
568 mpin[i].pin_state == SKL_PIN_UNBIND) {
569
570 mpin[i].tgt_mcfg = tgt_cfg;
595 return i; 571 return i;
572 }
596 } 573 }
597 } 574 }
598 575
@@ -606,6 +583,28 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
606 mpin[q_index].id.module_id = 0; 583 mpin[q_index].id.module_id = 0;
607 mpin[q_index].id.instance_id = 0; 584 mpin[q_index].id.instance_id = 0;
608 } 585 }
586 mpin[q_index].pin_state = SKL_PIN_UNBIND;
587 mpin[q_index].tgt_mcfg = NULL;
588}
589
590/* Module state will be set to unint, if all the out pin state is UNBIND */
591
592static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
593 struct skl_module_cfg *mcfg)
594{
595 int i;
596 bool found = false;
597
598 for (i = 0; i < max; i++) {
599 if (mpin[i].pin_state == SKL_PIN_UNBIND)
600 continue;
601 found = true;
602 break;
603 }
604
605 if (!found)
606 mcfg->m_state = SKL_MODULE_UNINIT;
607 return;
609} 608}
610 609
611/* 610/*
@@ -615,7 +614,7 @@ static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
615 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper 614 * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
616 */ 615 */
617int skl_init_module(struct skl_sst *ctx, 616int skl_init_module(struct skl_sst *ctx,
618 struct skl_module_cfg *mconfig, char *param) 617 struct skl_module_cfg *mconfig)
619{ 618{
620 u16 module_config_size = 0; 619 u16 module_config_size = 0;
621 void *param_data = NULL; 620 void *param_data = NULL;
@@ -682,37 +681,30 @@ int skl_unbind_modules(struct skl_sst *ctx,
682 struct skl_module_inst_id dst_id = dst_mcfg->id; 681 struct skl_module_inst_id dst_id = dst_mcfg->id;
683 int in_max = dst_mcfg->max_in_queue; 682 int in_max = dst_mcfg->max_in_queue;
684 int out_max = src_mcfg->max_out_queue; 683 int out_max = src_mcfg->max_out_queue;
685 int src_index, dst_index; 684 int src_index, dst_index, src_pin_state, dst_pin_state;
686 685
687 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 686 skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
688 687
689 if (src_mcfg->m_state != SKL_MODULE_BIND_DONE)
690 return 0;
691
692 /*
693 * if intra module unbind, check if both modules are BIND,
694 * then send unbind
695 */
696 if ((src_mcfg->pipe->ppl_id != dst_mcfg->pipe->ppl_id) &&
697 dst_mcfg->m_state != SKL_MODULE_BIND_DONE)
698 return 0;
699 else if (src_mcfg->m_state < SKL_MODULE_INIT_DONE &&
700 dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
701 return 0;
702
703 /* get src queue index */ 688 /* get src queue index */
704 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); 689 src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
705 if (src_index < 0) 690 if (src_index < 0)
706 return -EINVAL; 691 return -EINVAL;
707 692
708 msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; 693 msg.src_queue = src_index;
709 694
710 /* get dst queue index */ 695 /* get dst queue index */
711 dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); 696 dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
712 if (dst_index < 0) 697 if (dst_index < 0)
713 return -EINVAL; 698 return -EINVAL;
714 699
715 msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; 700 msg.dst_queue = dst_index;
701
702 src_pin_state = src_mcfg->m_out_pin[src_index].pin_state;
703 dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state;
704
705 if (src_pin_state != SKL_PIN_BIND_DONE ||
706 dst_pin_state != SKL_PIN_BIND_DONE)
707 return 0;
716 708
717 msg.module_id = src_mcfg->id.module_id; 709 msg.module_id = src_mcfg->id.module_id;
718 msg.instance_id = src_mcfg->id.instance_id; 710 msg.instance_id = src_mcfg->id.instance_id;
@@ -722,10 +714,15 @@ int skl_unbind_modules(struct skl_sst *ctx,
722 714
723 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 715 ret = skl_ipc_bind_unbind(&ctx->ipc, &msg);
724 if (!ret) { 716 if (!ret) {
725 src_mcfg->m_state = SKL_MODULE_UNINIT;
726 /* free queue only if unbind is success */ 717 /* free queue only if unbind is success */
727 skl_free_queue(src_mcfg->m_out_pin, src_index); 718 skl_free_queue(src_mcfg->m_out_pin, src_index);
728 skl_free_queue(dst_mcfg->m_in_pin, dst_index); 719 skl_free_queue(dst_mcfg->m_in_pin, dst_index);
720
721 /*
722 * check only if src module bind state, bind is
723 * always from src -> sink
724 */
725 skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg);
729 } 726 }
730 727
731 return ret; 728 return ret;
@@ -744,8 +741,6 @@ int skl_bind_modules(struct skl_sst *ctx,
744{ 741{
745 int ret; 742 int ret;
746 struct skl_ipc_bind_unbind_msg msg; 743 struct skl_ipc_bind_unbind_msg msg;
747 struct skl_module_inst_id src_id = src_mcfg->id;
748 struct skl_module_inst_id dst_id = dst_mcfg->id;
749 int in_max = dst_mcfg->max_in_queue; 744 int in_max = dst_mcfg->max_in_queue;
750 int out_max = src_mcfg->max_out_queue; 745 int out_max = src_mcfg->max_out_queue;
751 int src_index, dst_index; 746 int src_index, dst_index;
@@ -756,18 +751,18 @@ int skl_bind_modules(struct skl_sst *ctx,
756 dst_mcfg->m_state < SKL_MODULE_INIT_DONE) 751 dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
757 return 0; 752 return 0;
758 753
759 src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_id, out_max); 754 src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max);
760 if (src_index < 0) 755 if (src_index < 0)
761 return -EINVAL; 756 return -EINVAL;
762 757
763 msg.src_queue = src_mcfg->m_out_pin[src_index].pin_index; 758 msg.src_queue = src_index;
764 dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_id, in_max); 759 dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max);
765 if (dst_index < 0) { 760 if (dst_index < 0) {
766 skl_free_queue(src_mcfg->m_out_pin, src_index); 761 skl_free_queue(src_mcfg->m_out_pin, src_index);
767 return -EINVAL; 762 return -EINVAL;
768 } 763 }
769 764
770 msg.dst_queue = dst_mcfg->m_in_pin[dst_index].pin_index; 765 msg.dst_queue = dst_index;
771 766
772 dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", 767 dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n",
773 msg.src_queue, msg.dst_queue); 768 msg.src_queue, msg.dst_queue);
@@ -782,6 +777,8 @@ int skl_bind_modules(struct skl_sst *ctx,
782 777
783 if (!ret) { 778 if (!ret) {
784 src_mcfg->m_state = SKL_MODULE_BIND_DONE; 779 src_mcfg->m_state = SKL_MODULE_BIND_DONE;
780 src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE;
781 dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE;
785 } else { 782 } else {
786 /* error case , if IPC fails, clear the queue index */ 783 /* error case , if IPC fails, clear the queue index */
787 skl_free_queue(src_mcfg->m_out_pin, src_index); 784 skl_free_queue(src_mcfg->m_out_pin, src_index);
@@ -852,6 +849,8 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
852 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 849 ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id);
853 if (ret < 0) 850 if (ret < 0)
854 dev_err(ctx->dev, "Failed to delete pipeline\n"); 851 dev_err(ctx->dev, "Failed to delete pipeline\n");
852
853 pipe->state = SKL_PIPE_INVALID;
855 } 854 }
856 855
857 return ret; 856 return ret;
@@ -916,3 +915,30 @@ int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
916 915
917 return 0; 916 return 0;
918} 917}
918
919/* Algo parameter set helper function */
920int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
921 u32 param_id, struct skl_module_cfg *mcfg)
922{
923 struct skl_ipc_large_config_msg msg;
924
925 msg.module_id = mcfg->id.module_id;
926 msg.instance_id = mcfg->id.instance_id;
927 msg.param_data_size = size;
928 msg.large_param_id = param_id;
929
930 return skl_ipc_set_large_config(&ctx->ipc, &msg, params);
931}
932
933int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
934 u32 param_id, struct skl_module_cfg *mcfg)
935{
936 struct skl_ipc_large_config_msg msg;
937
938 msg.module_id = mcfg->id.module_id;
939 msg.instance_id = mcfg->id.instance_id;
940 msg.param_data_size = size;
941 msg.large_param_id = param_id;
942
943 return skl_ipc_get_large_config(&ctx->ipc, &msg, params);
944}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index b0c7bd113aac..6e4b21cdb1bd 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -55,7 +55,7 @@ void skl_nhlt_free(void *addr)
55 55
56static struct nhlt_specific_cfg *skl_get_specific_cfg( 56static struct nhlt_specific_cfg *skl_get_specific_cfg(
57 struct device *dev, struct nhlt_fmt *fmt, 57 struct device *dev, struct nhlt_fmt *fmt,
58 u8 no_ch, u32 rate, u16 bps) 58 u8 no_ch, u32 rate, u16 bps, u8 linktype)
59{ 59{
60 struct nhlt_specific_cfg *sp_config; 60 struct nhlt_specific_cfg *sp_config;
61 struct wav_fmt *wfmt; 61 struct wav_fmt *wfmt;
@@ -68,11 +68,17 @@ static struct nhlt_specific_cfg *skl_get_specific_cfg(
68 wfmt = &fmt_config->fmt_ext.fmt; 68 wfmt = &fmt_config->fmt_ext.fmt;
69 dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels, 69 dev_dbg(dev, "ch=%d fmt=%d s_rate=%d\n", wfmt->channels,
70 wfmt->bits_per_sample, wfmt->samples_per_sec); 70 wfmt->bits_per_sample, wfmt->samples_per_sec);
71 if (wfmt->channels == no_ch && wfmt->samples_per_sec == rate && 71 if (wfmt->channels == no_ch && wfmt->bits_per_sample == bps) {
72 wfmt->bits_per_sample == bps) { 72 /*
73 * if link type is dmic ignore rate check as the blob is
74 * generic for all rates
75 */
73 sp_config = &fmt_config->config; 76 sp_config = &fmt_config->config;
77 if (linktype == NHLT_LINK_DMIC)
78 return sp_config;
74 79
75 return sp_config; 80 if (wfmt->samples_per_sec == rate)
81 return sp_config;
76 } 82 }
77 83
78 fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps + 84 fmt_config = (struct nhlt_fmt_cfg *)(fmt_config->config.caps +
@@ -115,7 +121,7 @@ struct nhlt_specific_cfg
115 struct device *dev = bus->dev; 121 struct device *dev = bus->dev;
116 struct nhlt_specific_cfg *sp_config; 122 struct nhlt_specific_cfg *sp_config;
117 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; 123 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
118 u16 bps = num_ch * s_fmt; 124 u16 bps = (s_fmt == 16) ? 16 : 32;
119 u8 j; 125 u8 j;
120 126
121 dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps); 127 dump_config(dev, instance, link_type, s_fmt, num_ch, s_rate, dirn, bps);
@@ -128,7 +134,8 @@ struct nhlt_specific_cfg
128 if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) { 134 if (skl_check_ep_match(dev, epnt, instance, link_type, dirn)) {
129 fmt = (struct nhlt_fmt *)(epnt->config.caps + 135 fmt = (struct nhlt_fmt *)(epnt->config.caps +
130 epnt->config.size); 136 epnt->config.size);
131 sp_config = skl_get_specific_cfg(dev, fmt, num_ch, s_rate, bps); 137 sp_config = skl_get_specific_cfg(dev, fmt, num_ch,
138 s_rate, bps, link_type);
132 if (sp_config) 139 if (sp_config)
133 return sp_config; 140 return sp_config;
134 } 141 }
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index a2f94ce1679d..b89ae6f7c096 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -28,6 +28,7 @@
28 28
29#define HDA_MONO 1 29#define HDA_MONO 1
30#define HDA_STEREO 2 30#define HDA_STEREO 2
31#define HDA_QUAD 4
31 32
32static struct snd_pcm_hardware azx_pcm_hw = { 33static struct snd_pcm_hardware azx_pcm_hw = {
33 .info = (SNDRV_PCM_INFO_MMAP | 34 .info = (SNDRV_PCM_INFO_MMAP |
@@ -39,12 +40,15 @@ static struct snd_pcm_hardware azx_pcm_hw = {
39 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */ 40 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
40 SNDRV_PCM_INFO_HAS_LINK_ATIME | 41 SNDRV_PCM_INFO_HAS_LINK_ATIME |
41 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), 42 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
42 .formats = SNDRV_PCM_FMTBIT_S16_LE, 43 .formats = SNDRV_PCM_FMTBIT_S16_LE |
43 .rates = SNDRV_PCM_RATE_48000, 44 SNDRV_PCM_FMTBIT_S32_LE |
44 .rate_min = 48000, 45 SNDRV_PCM_FMTBIT_S24_LE,
46 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 |
47 SNDRV_PCM_RATE_8000,
48 .rate_min = 8000,
45 .rate_max = 48000, 49 .rate_max = 48000,
46 .channels_min = 2, 50 .channels_min = 1,
47 .channels_max = 2, 51 .channels_max = HDA_QUAD,
48 .buffer_bytes_max = AZX_MAX_BUF_SIZE, 52 .buffer_bytes_max = AZX_MAX_BUF_SIZE,
49 .period_bytes_min = 128, 53 .period_bytes_min = 128,
50 .period_bytes_max = AZX_MAX_BUF_SIZE / 2, 54 .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
@@ -105,6 +109,31 @@ static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *e
105 return HDAC_EXT_STREAM_TYPE_COUPLED; 109 return HDAC_EXT_STREAM_TYPE_COUPLED;
106} 110}
107 111
112/*
113 * check if the stream opened is marked as ignore_suspend by machine, if so
114 * then enable suspend_active refcount
115 *
116 * The count supend_active does not need lock as it is used in open/close
117 * and suspend context
118 */
119static void skl_set_suspend_active(struct snd_pcm_substream *substream,
120 struct snd_soc_dai *dai, bool enable)
121{
122 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
123 struct snd_soc_dapm_widget *w;
124 struct skl *skl = ebus_to_skl(ebus);
125
126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
127 w = dai->playback_widget;
128 else
129 w = dai->capture_widget;
130
131 if (w->ignore_suspend && enable)
132 skl->supend_active++;
133 else if (w->ignore_suspend && !enable)
134 skl->supend_active--;
135}
136
108static int skl_pcm_open(struct snd_pcm_substream *substream, 137static int skl_pcm_open(struct snd_pcm_substream *substream,
109 struct snd_soc_dai *dai) 138 struct snd_soc_dai *dai)
110{ 139{
@@ -112,12 +141,8 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
112 struct hdac_ext_stream *stream; 141 struct hdac_ext_stream *stream;
113 struct snd_pcm_runtime *runtime = substream->runtime; 142 struct snd_pcm_runtime *runtime = substream->runtime;
114 struct skl_dma_params *dma_params; 143 struct skl_dma_params *dma_params;
115 int ret;
116 144
117 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 145 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
118 ret = pm_runtime_get_sync(dai->dev);
119 if (ret < 0)
120 return ret;
121 146
122 stream = snd_hdac_ext_stream_assign(ebus, substream, 147 stream = snd_hdac_ext_stream_assign(ebus, substream,
123 skl_get_host_stream_type(ebus)); 148 skl_get_host_stream_type(ebus));
@@ -146,6 +171,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
146 171
147 dev_dbg(dai->dev, "stream tag set in dma params=%d\n", 172 dev_dbg(dai->dev, "stream tag set in dma params=%d\n",
148 dma_params->stream_tag); 173 dma_params->stream_tag);
174 skl_set_suspend_active(substream, dai, true);
149 snd_pcm_set_sync(substream); 175 snd_pcm_set_sync(substream);
150 176
151 return 0; 177 return 0;
@@ -185,10 +211,6 @@ static int skl_pcm_prepare(struct snd_pcm_substream *substream,
185 int err; 211 int err;
186 212
187 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 213 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
188 if (hdac_stream(stream)->prepared) {
189 dev_dbg(dai->dev, "already stream is prepared - returning\n");
190 return 0;
191 }
192 214
193 format_val = skl_get_format(substream, dai); 215 format_val = skl_get_format(substream, dai);
194 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n", 216 dev_dbg(dai->dev, "stream_tag=%d formatvalue=%d\n",
@@ -261,9 +283,8 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
261 * dma_params 283 * dma_params
262 */ 284 */
263 snd_soc_dai_set_dma_data(dai, substream, NULL); 285 snd_soc_dai_set_dma_data(dai, substream, NULL);
286 skl_set_suspend_active(substream, dai, false);
264 287
265 pm_runtime_mark_last_busy(dai->dev);
266 pm_runtime_put_autosuspend(dai->dev);
267 kfree(dma_params); 288 kfree(dma_params);
268} 289}
269 290
@@ -291,7 +312,53 @@ static int skl_be_hw_params(struct snd_pcm_substream *substream,
291 p_params.ch = params_channels(params); 312 p_params.ch = params_channels(params);
292 p_params.s_freq = params_rate(params); 313 p_params.s_freq = params_rate(params);
293 p_params.stream = substream->stream; 314 p_params.stream = substream->stream;
294 skl_tplg_be_update_params(dai, &p_params); 315
316 return skl_tplg_be_update_params(dai, &p_params);
317}
318
319static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
320 int cmd)
321{
322 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
323 struct hdac_bus *bus = ebus_to_hbus(ebus);
324 struct hdac_ext_stream *stream;
325 int start;
326 unsigned long cookie;
327 struct hdac_stream *hstr;
328
329 stream = get_hdac_ext_stream(substream);
330 hstr = hdac_stream(stream);
331
332 if (!hstr->prepared)
333 return -EPIPE;
334
335 switch (cmd) {
336 case SNDRV_PCM_TRIGGER_START:
337 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
338 case SNDRV_PCM_TRIGGER_RESUME:
339 start = 1;
340 break;
341
342 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
343 case SNDRV_PCM_TRIGGER_SUSPEND:
344 case SNDRV_PCM_TRIGGER_STOP:
345 start = 0;
346 break;
347
348 default:
349 return -EINVAL;
350 }
351
352 spin_lock_irqsave(&bus->reg_lock, cookie);
353
354 if (start) {
355 snd_hdac_stream_start(hdac_stream(stream), true);
356 snd_hdac_stream_timecounter_init(hstr, 0);
357 } else {
358 snd_hdac_stream_stop(hdac_stream(stream));
359 }
360
361 spin_unlock_irqrestore(&bus->reg_lock, cookie);
295 362
296 return 0; 363 return 0;
297} 364}
@@ -302,23 +369,54 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
302 struct skl *skl = get_skl_ctx(dai->dev); 369 struct skl *skl = get_skl_ctx(dai->dev);
303 struct skl_sst *ctx = skl->skl_sst; 370 struct skl_sst *ctx = skl->skl_sst;
304 struct skl_module_cfg *mconfig; 371 struct skl_module_cfg *mconfig;
372 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
373 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
374 int ret;
305 375
306 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); 376 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
307 if (!mconfig) 377 if (!mconfig)
308 return -EIO; 378 return -EIO;
309 379
310 switch (cmd) { 380 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
312 case SNDRV_PCM_TRIGGER_RESUME: 381 case SNDRV_PCM_TRIGGER_RESUME:
382 skl_pcm_prepare(substream, dai);
383 case SNDRV_PCM_TRIGGER_START:
384 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
385 /*
386 * Start HOST DMA and Start FE Pipe.This is to make sure that
387 * there are no underrun/overrun in the case when the FE
388 * pipeline is started but there is a delay in starting the
389 * DMA channel on the host.
390 */
391 snd_hdac_ext_stream_decouple(ebus, stream, true);
392 ret = skl_decoupled_trigger(substream, cmd);
393 if (ret < 0)
394 return ret;
313 return skl_run_pipe(ctx, mconfig->pipe); 395 return skl_run_pipe(ctx, mconfig->pipe);
396 break;
314 397
315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 398 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
316 case SNDRV_PCM_TRIGGER_SUSPEND: 399 case SNDRV_PCM_TRIGGER_SUSPEND:
317 return skl_stop_pipe(ctx, mconfig->pipe); 400 case SNDRV_PCM_TRIGGER_STOP:
401 /*
402 * Stop FE Pipe first and stop DMA. This is to make sure that
403 * there are no underrun/overrun in the case if there is a delay
404 * between the two operations.
405 */
406 ret = skl_stop_pipe(ctx, mconfig->pipe);
407 if (ret < 0)
408 return ret;
409
410 ret = skl_decoupled_trigger(substream, cmd);
411 if (cmd == SNDRV_PCM_TRIGGER_SUSPEND)
412 snd_hdac_ext_stream_decouple(ebus, stream, false);
413 break;
318 414
319 default: 415 default:
320 return 0; 416 return -EINVAL;
321 } 417 }
418
419 return 0;
322} 420}
323 421
324static int skl_link_hw_params(struct snd_pcm_substream *substream, 422static int skl_link_hw_params(struct snd_pcm_substream *substream,
@@ -352,9 +450,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
352 p_params.stream = substream->stream; 450 p_params.stream = substream->stream;
353 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1; 451 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
354 452
355 skl_tplg_be_update_params(dai, &p_params); 453 return skl_tplg_be_update_params(dai, &p_params);
356
357 return 0;
358} 454}
359 455
360static int skl_link_pcm_prepare(struct snd_pcm_substream *substream, 456static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
@@ -443,19 +539,6 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
443 return 0; 539 return 0;
444} 540}
445 541
446static int skl_be_startup(struct snd_pcm_substream *substream,
447 struct snd_soc_dai *dai)
448{
449 return pm_runtime_get_sync(dai->dev);
450}
451
452static void skl_be_shutdown(struct snd_pcm_substream *substream,
453 struct snd_soc_dai *dai)
454{
455 pm_runtime_mark_last_busy(dai->dev);
456 pm_runtime_put_autosuspend(dai->dev);
457}
458
459static struct snd_soc_dai_ops skl_pcm_dai_ops = { 542static struct snd_soc_dai_ops skl_pcm_dai_ops = {
460 .startup = skl_pcm_open, 543 .startup = skl_pcm_open,
461 .shutdown = skl_pcm_close, 544 .shutdown = skl_pcm_close,
@@ -466,24 +549,18 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
466}; 549};
467 550
468static struct snd_soc_dai_ops skl_dmic_dai_ops = { 551static struct snd_soc_dai_ops skl_dmic_dai_ops = {
469 .startup = skl_be_startup,
470 .hw_params = skl_be_hw_params, 552 .hw_params = skl_be_hw_params,
471 .shutdown = skl_be_shutdown,
472}; 553};
473 554
474static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { 555static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
475 .startup = skl_be_startup,
476 .hw_params = skl_be_hw_params, 556 .hw_params = skl_be_hw_params,
477 .shutdown = skl_be_shutdown,
478}; 557};
479 558
480static struct snd_soc_dai_ops skl_link_dai_ops = { 559static struct snd_soc_dai_ops skl_link_dai_ops = {
481 .startup = skl_be_startup,
482 .prepare = skl_link_pcm_prepare, 560 .prepare = skl_link_pcm_prepare,
483 .hw_params = skl_link_hw_params, 561 .hw_params = skl_link_hw_params,
484 .hw_free = skl_link_hw_free, 562 .hw_free = skl_link_hw_free,
485 .trigger = skl_link_pcm_trigger, 563 .trigger = skl_link_pcm_trigger,
486 .shutdown = skl_be_shutdown,
487}; 564};
488 565
489static struct snd_soc_dai_driver skl_platform_dai[] = { 566static struct snd_soc_dai_driver skl_platform_dai[] = {
@@ -511,7 +588,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
511 .capture = { 588 .capture = {
512 .stream_name = "Reference Capture", 589 .stream_name = "Reference Capture",
513 .channels_min = HDA_MONO, 590 .channels_min = HDA_MONO,
514 .channels_max = HDA_STEREO, 591 .channels_max = HDA_QUAD,
515 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 592 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
516 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 593 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
517 }, 594 },
@@ -538,6 +615,18 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
538 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 615 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
539 }, 616 },
540}, 617},
618{
619 .name = "DMIC Pin",
620 .ops = &skl_pcm_dai_ops,
621 .capture = {
622 .stream_name = "DMIC Capture",
623 .channels_min = HDA_MONO,
624 .channels_max = HDA_QUAD,
625 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
626 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
627 },
628},
629
541/* BE CPU Dais */ 630/* BE CPU Dais */
542{ 631{
543 .name = "SSP0 Pin", 632 .name = "SSP0 Pin",
@@ -558,6 +647,24 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
558 }, 647 },
559}, 648},
560{ 649{
650 .name = "SSP1 Pin",
651 .ops = &skl_be_ssp_dai_ops,
652 .playback = {
653 .stream_name = "ssp1 Tx",
654 .channels_min = HDA_STEREO,
655 .channels_max = HDA_STEREO,
656 .rates = SNDRV_PCM_RATE_48000,
657 .formats = SNDRV_PCM_FMTBIT_S16_LE,
658 },
659 .capture = {
660 .stream_name = "ssp1 Rx",
661 .channels_min = HDA_STEREO,
662 .channels_max = HDA_STEREO,
663 .rates = SNDRV_PCM_RATE_48000,
664 .formats = SNDRV_PCM_FMTBIT_S16_LE,
665 },
666},
667{
561 .name = "iDisp Pin", 668 .name = "iDisp Pin",
562 .ops = &skl_link_dai_ops, 669 .ops = &skl_link_dai_ops,
563 .playback = { 670 .playback = {
@@ -573,8 +680,8 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
573 .ops = &skl_dmic_dai_ops, 680 .ops = &skl_dmic_dai_ops,
574 .capture = { 681 .capture = {
575 .stream_name = "DMIC01 Rx", 682 .stream_name = "DMIC01 Rx",
576 .channels_min = HDA_STEREO, 683 .channels_min = HDA_MONO,
577 .channels_max = HDA_STEREO, 684 .channels_max = HDA_QUAD,
578 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 685 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
579 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 686 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
580 }, 687 },
@@ -688,66 +795,15 @@ static int skl_coupled_trigger(struct snd_pcm_substream *substream,
688 return 0; 795 return 0;
689} 796}
690 797
691static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
692 int cmd)
693{
694 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
695 struct hdac_bus *bus = ebus_to_hbus(ebus);
696 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
697 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
698 struct hdac_ext_stream *stream;
699 int start;
700 unsigned long cookie;
701 struct hdac_stream *hstr;
702
703 dev_dbg(bus->dev, "In %s cmd=%d streamname=%s\n", __func__, cmd, cpu_dai->name);
704
705 stream = get_hdac_ext_stream(substream);
706 hstr = hdac_stream(stream);
707
708 if (!hstr->prepared)
709 return -EPIPE;
710
711 switch (cmd) {
712 case SNDRV_PCM_TRIGGER_START:
713 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
714 case SNDRV_PCM_TRIGGER_RESUME:
715 start = 1;
716 break;
717
718 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
719 case SNDRV_PCM_TRIGGER_SUSPEND:
720 case SNDRV_PCM_TRIGGER_STOP:
721 start = 0;
722 break;
723
724 default:
725 return -EINVAL;
726 }
727
728 spin_lock_irqsave(&bus->reg_lock, cookie);
729
730 if (start)
731 snd_hdac_stream_start(hdac_stream(stream), true);
732 else
733 snd_hdac_stream_stop(hdac_stream(stream));
734
735 if (start)
736 snd_hdac_stream_timecounter_init(hstr, 0);
737
738 spin_unlock_irqrestore(&bus->reg_lock, cookie);
739
740 return 0;
741}
742static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream, 798static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
743 int cmd) 799 int cmd)
744{ 800{
745 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 801 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
746 802
747 if (ebus->ppcap) 803 if (!ebus->ppcap)
748 return skl_decoupled_trigger(substream, cmd);
749 else
750 return skl_coupled_trigger(substream, cmd); 804 return skl_coupled_trigger(substream, cmd);
805
806 return 0;
751} 807}
752 808
753/* calculate runtime delay from LPIB */ 809/* calculate runtime delay from LPIB */
@@ -789,7 +845,7 @@ static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
789{ 845{
790 struct hdac_stream *hstr = hdac_stream(hstream); 846 struct hdac_stream *hstr = hdac_stream(hstream);
791 struct snd_pcm_substream *substream = hstr->substream; 847 struct snd_pcm_substream *substream = hstr->substream;
792 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 848 struct hdac_ext_bus *ebus;
793 unsigned int pos; 849 unsigned int pos;
794 int delay; 850 int delay;
795 851
@@ -800,6 +856,7 @@ static unsigned int skl_get_position(struct hdac_ext_stream *hstream,
800 pos = 0; 856 pos = 0;
801 857
802 if (substream->runtime) { 858 if (substream->runtime) {
859 ebus = get_bus_ctx(substream);
803 delay = skl_get_delay_from_lpib(ebus, hstream, pos) 860 delay = skl_get_delay_from_lpib(ebus, hstream, pos)
804 + codec_delay; 861 + codec_delay;
805 substream->runtime->delay += delay; 862 substream->runtime->delay += delay;
@@ -941,7 +998,6 @@ int skl_platform_register(struct device *dev)
941 struct skl *skl = ebus_to_skl(ebus); 998 struct skl *skl = ebus_to_skl(ebus);
942 999
943 INIT_LIST_HEAD(&skl->ppl_list); 1000 INIT_LIST_HEAD(&skl->ppl_list);
944 INIT_LIST_HEAD(&skl->dapm_path_list);
945 1001
946 ret = snd_soc_register_platform(dev, &skl_platform_drv); 1002 ret = snd_soc_register_platform(dev, &skl_platform_drv);
947 if (ret) { 1003 if (ret) {
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index 44748ba98da2..da2329d17f4d 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/kthread.h> 20#include <linux/kthread.h>
21#include <linux/delay.h>
21#include "../common/sst-dsp.h" 22#include "../common/sst-dsp.h"
22#include "../common/sst-dsp-priv.h" 23#include "../common/sst-dsp-priv.h"
23 24
@@ -33,6 +34,53 @@ void skl_cldma_int_disable(struct sst_dsp *ctx)
33 SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0); 34 SKL_ADSP_REG_ADSPIC, SKL_ADSPIC_CL_DMA, 0);
34} 35}
35 36
37static void skl_cldma_stream_run(struct sst_dsp *ctx, bool enable)
38{
39 unsigned char val;
40 int timeout;
41
42 sst_dsp_shim_update_bits_unlocked(ctx,
43 SKL_ADSP_REG_CL_SD_CTL,
44 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(enable));
45
46 udelay(3);
47 timeout = 300;
48 do {
49 /* waiting for hardware to report that the stream Run bit set */
50 val = sst_dsp_shim_read(ctx, SKL_ADSP_REG_CL_SD_CTL) &
51 CL_SD_CTL_RUN_MASK;
52 if (enable && val)
53 break;
54 else if (!enable && !val)
55 break;
56 udelay(3);
57 } while (--timeout);
58
59 if (timeout == 0)
60 dev_err(ctx->dev, "Failed to set Run bit=%d enable=%d\n", val, enable);
61}
62
63static void skl_cldma_stream_clear(struct sst_dsp *ctx)
64{
65 /* make sure Run bit is cleared before setting stream register */
66 skl_cldma_stream_run(ctx, 0);
67
68 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
69 CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(0));
70 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
71 CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(0));
72 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
73 CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(0));
74 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
75 CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(0));
76
77 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, CL_SD_BDLPLBA(0));
78 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 0);
79
80 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, 0);
81 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, 0);
82}
83
36/* Code loader helper APIs */ 84/* Code loader helper APIs */
37static void skl_cldma_setup_bdle(struct sst_dsp *ctx, 85static void skl_cldma_setup_bdle(struct sst_dsp *ctx,
38 struct snd_dma_buffer *dmab_data, 86 struct snd_dma_buffer *dmab_data,
@@ -68,6 +116,7 @@ static void skl_cldma_setup_controller(struct sst_dsp *ctx,
68 struct snd_dma_buffer *dmab_bdl, unsigned int max_size, 116 struct snd_dma_buffer *dmab_bdl, unsigned int max_size,
69 u32 count) 117 u32 count)
70{ 118{
119 skl_cldma_stream_clear(ctx);
71 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, 120 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL,
72 CL_SD_BDLPLBA(dmab_bdl->addr)); 121 CL_SD_BDLPLBA(dmab_bdl->addr));
73 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 122 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU,
@@ -107,36 +156,13 @@ static void skl_cldma_cleanup_spb(struct sst_dsp *ctx)
107 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0); 156 sst_dsp_shim_write_unlocked(ctx, SKL_ADSP_REG_CL_SPBFIFO_SPIB, 0);
108} 157}
109 158
110static void skl_cldma_trigger(struct sst_dsp *ctx, bool enable)
111{
112 if (enable)
113 sst_dsp_shim_update_bits_unlocked(ctx,
114 SKL_ADSP_REG_CL_SD_CTL,
115 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(1));
116 else
117 sst_dsp_shim_update_bits_unlocked(ctx,
118 SKL_ADSP_REG_CL_SD_CTL,
119 CL_SD_CTL_RUN_MASK, CL_SD_CTL_RUN(0));
120}
121
122static void skl_cldma_cleanup(struct sst_dsp *ctx) 159static void skl_cldma_cleanup(struct sst_dsp *ctx)
123{ 160{
124 skl_cldma_cleanup_spb(ctx); 161 skl_cldma_cleanup_spb(ctx);
162 skl_cldma_stream_clear(ctx);
125 163
126 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL, 164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data);
127 CL_SD_CTL_IOCE_MASK, CL_SD_CTL_IOCE(0)); 165 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl);
128 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
129 CL_SD_CTL_FEIE_MASK, CL_SD_CTL_FEIE(0));
130 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
131 CL_SD_CTL_DEIE_MASK, CL_SD_CTL_DEIE(0));
132 sst_dsp_shim_update_bits(ctx, SKL_ADSP_REG_CL_SD_CTL,
133 CL_SD_CTL_STRM_MASK, CL_SD_CTL_STRM(0));
134
135 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPL, CL_SD_BDLPLBA(0));
136 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_BDLPU, 0);
137
138 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_CBL, 0);
139 sst_dsp_shim_write(ctx, SKL_ADSP_REG_CL_SD_LVI, 0);
140} 166}
141 167
142static int skl_cldma_wait_interruptible(struct sst_dsp *ctx) 168static int skl_cldma_wait_interruptible(struct sst_dsp *ctx)
@@ -164,7 +190,7 @@ cleanup:
164 190
165static void skl_cldma_stop(struct sst_dsp *ctx) 191static void skl_cldma_stop(struct sst_dsp *ctx)
166{ 192{
167 ctx->cl_dev.ops.cl_trigger(ctx, false); 193 skl_cldma_stream_run(ctx, false);
168} 194}
169 195
170static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size, 196static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
@@ -175,6 +201,21 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
175 ctx->cl_dev.dma_buffer_offset, trigger); 201 ctx->cl_dev.dma_buffer_offset, trigger);
176 dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos); 202 dev_dbg(ctx->dev, "spib position: %d\n", ctx->cl_dev.curr_spib_pos);
177 203
204 /*
205 * Check if the size exceeds buffer boundary. If it exceeds
206 * max_buffer size, then copy till buffer size and then copy
207 * remaining buffer from the start of ring buffer.
208 */
209 if (ctx->cl_dev.dma_buffer_offset + size > ctx->cl_dev.bufsize) {
210 unsigned int size_b = ctx->cl_dev.bufsize -
211 ctx->cl_dev.dma_buffer_offset;
212 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
213 curr_pos, size_b);
214 size -= size_b;
215 curr_pos += size_b;
216 ctx->cl_dev.dma_buffer_offset = 0;
217 }
218
178 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset, 219 memcpy(ctx->cl_dev.dmab_data.area + ctx->cl_dev.dma_buffer_offset,
179 curr_pos, size); 220 curr_pos, size);
180 221
@@ -291,7 +332,7 @@ int skl_cldma_prepare(struct sst_dsp *ctx)
291 ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller; 332 ctx->cl_dev.ops.cl_setup_controller = skl_cldma_setup_controller;
292 ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb; 333 ctx->cl_dev.ops.cl_setup_spb = skl_cldma_setup_spb;
293 ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb; 334 ctx->cl_dev.ops.cl_cleanup_spb = skl_cldma_cleanup_spb;
294 ctx->cl_dev.ops.cl_trigger = skl_cldma_trigger; 335 ctx->cl_dev.ops.cl_trigger = skl_cldma_stream_run;
295 ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup; 336 ctx->cl_dev.ops.cl_cleanup_controller = skl_cldma_cleanup;
296 ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf; 337 ctx->cl_dev.ops.cl_copy_to_dmabuf = skl_cldma_copy_to_buf;
297 ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop; 338 ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop;
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 6bfcef449bdc..cbb40751c37e 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -58,9 +58,9 @@ struct sst_dsp_device;
58 58
59#define SKL_ADSP_MMIO_LEN 0x10000 59#define SKL_ADSP_MMIO_LEN 0x10000
60 60
61#define SKL_ADSP_W0_STAT_SZ 0x800 61#define SKL_ADSP_W0_STAT_SZ 0x1000
62 62
63#define SKL_ADSP_W0_UP_SZ 0x800 63#define SKL_ADSP_W0_UP_SZ 0x1000
64 64
65#define SKL_ADSP_W1_SZ 0x1000 65#define SKL_ADSP_W1_SZ 0x1000
66 66
@@ -114,6 +114,9 @@ struct skl_dsp_fw_ops {
114 int (*set_state_D0)(struct sst_dsp *ctx); 114 int (*set_state_D0)(struct sst_dsp *ctx);
115 int (*set_state_D3)(struct sst_dsp *ctx); 115 int (*set_state_D3)(struct sst_dsp *ctx);
116 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); 116 unsigned int (*get_fw_errcode)(struct sst_dsp *ctx);
117 int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, char *mod_name);
118 int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id);
119
117}; 120};
118 121
119struct skl_dsp_loader_ops { 122struct skl_dsp_loader_ops {
@@ -123,6 +126,17 @@ struct skl_dsp_loader_ops {
123 struct snd_dma_buffer *dmab); 126 struct snd_dma_buffer *dmab);
124}; 127};
125 128
129struct skl_load_module_info {
130 u16 mod_id;
131 const struct firmware *fw;
132};
133
134struct skl_module_table {
135 struct skl_load_module_info *mod_info;
136 unsigned int usage_cnt;
137 struct list_head list;
138};
139
126void skl_cldma_process_intr(struct sst_dsp *ctx); 140void skl_cldma_process_intr(struct sst_dsp *ctx);
127void skl_cldma_int_disable(struct sst_dsp *ctx); 141void skl_cldma_int_disable(struct sst_dsp *ctx);
128int skl_cldma_prepare(struct sst_dsp *ctx); 142int skl_cldma_prepare(struct sst_dsp *ctx);
@@ -139,7 +153,8 @@ void skl_dsp_free(struct sst_dsp *dsp);
139 153
140int skl_dsp_boot(struct sst_dsp *ctx); 154int skl_dsp_boot(struct sst_dsp *ctx);
141int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 155int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
142 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp); 156 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
157 struct skl_sst **dsp);
143void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 158void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
144 159
145#endif /*__SKL_SST_DSP_H__*/ 160#endif /*__SKL_SST_DSP_H__*/
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 3345ea0d4414..62e665a3b8f7 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -130,6 +130,11 @@
130#define IPC_SRC_QUEUE_MASK 0x7 130#define IPC_SRC_QUEUE_MASK 0x7
131#define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \ 131#define IPC_SRC_QUEUE(x) (((x) & IPC_SRC_QUEUE_MASK) \
132 << IPC_SRC_QUEUE_SHIFT) 132 << IPC_SRC_QUEUE_SHIFT)
133/* Load Module count */
134#define IPC_LOAD_MODULE_SHIFT 0
135#define IPC_LOAD_MODULE_MASK 0xFF
136#define IPC_LOAD_MODULE_CNT(x) (((x) & IPC_LOAD_MODULE_MASK) \
137 << IPC_LOAD_MODULE_SHIFT)
133 138
134/* Save pipeline messgae extension register */ 139/* Save pipeline messgae extension register */
135#define IPC_DMA_ID_SHIFT 0 140#define IPC_DMA_ID_SHIFT 0
@@ -344,6 +349,8 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
344 switch (reply) { 349 switch (reply) {
345 case IPC_GLB_REPLY_SUCCESS: 350 case IPC_GLB_REPLY_SUCCESS:
346 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary); 351 dev_info(ipc->dev, "ipc FW reply %x: success\n", header.primary);
352 /* copy the rx data from the mailbox */
353 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
347 break; 354 break;
348 355
349 case IPC_GLB_REPLY_OUT_OF_MEMORY: 356 case IPC_GLB_REPLY_OUT_OF_MEMORY:
@@ -650,7 +657,7 @@ int skl_ipc_set_dx(struct sst_generic_ipc *ipc, u8 instance_id,
650 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__, 657 dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
651 header.primary, header.extension); 658 header.primary, header.extension);
652 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, 659 ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
653 dx, sizeof(dx), NULL, 0); 660 dx, sizeof(*dx), NULL, 0);
654 if (ret < 0) { 661 if (ret < 0) {
655 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret); 662 dev_err(ipc->dev, "ipc: set dx failed, err %d\n", ret);
656 return ret; 663 return ret;
@@ -728,6 +735,54 @@ int skl_ipc_bind_unbind(struct sst_generic_ipc *ipc,
728} 735}
729EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind); 736EXPORT_SYMBOL_GPL(skl_ipc_bind_unbind);
730 737
738/*
739 * In order to load a module we need to send IPC to initiate that. DMA will
740 * performed to load the module memory. The FW supports multiple module load
741 * at single shot, so we can send IPC with N modules represented by
742 * module_cnt
743 */
744int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
745 u8 module_cnt, void *data)
746{
747 struct skl_ipc_header header = {0};
748 u64 *ipc_header = (u64 *)(&header);
749 int ret;
750
751 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
752 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
753 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
754 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
755
756 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
757 (sizeof(u16) * module_cnt), NULL, 0);
758 if (ret < 0)
759 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
760
761 return ret;
762}
763EXPORT_SYMBOL_GPL(skl_ipc_load_modules);
764
765int skl_ipc_unload_modules(struct sst_generic_ipc *ipc, u8 module_cnt,
766 void *data)
767{
768 struct skl_ipc_header header = {0};
769 u64 *ipc_header = (u64 *)(&header);
770 int ret;
771
772 header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
773 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
774 header.primary |= IPC_GLB_TYPE(IPC_GLB_UNLOAD_MULTIPLE_MODS);
775 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
776
777 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data,
778 (sizeof(u16) * module_cnt), NULL, 0);
779 if (ret < 0)
780 dev_err(ipc->dev, "ipc: unload modules failed :%d\n", ret);
781
782 return ret;
783}
784EXPORT_SYMBOL_GPL(skl_ipc_unload_modules);
785
731int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, 786int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
732 struct skl_ipc_large_config_msg *msg, u32 *param) 787 struct skl_ipc_large_config_msg *msg, u32 *param)
733{ 788{
@@ -781,3 +836,54 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
781 return ret; 836 return ret;
782} 837}
783EXPORT_SYMBOL_GPL(skl_ipc_set_large_config); 838EXPORT_SYMBOL_GPL(skl_ipc_set_large_config);
839
840int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
841 struct skl_ipc_large_config_msg *msg, u32 *param)
842{
843 struct skl_ipc_header header = {0};
844 u64 *ipc_header = (u64 *)(&header);
845 int ret = 0;
846 size_t sz_remaining, rx_size, data_offset;
847
848 header.primary = IPC_MSG_TARGET(IPC_MOD_MSG);
849 header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
850 header.primary |= IPC_GLB_TYPE(IPC_MOD_LARGE_CONFIG_GET);
851 header.primary |= IPC_MOD_INSTANCE_ID(msg->instance_id);
852 header.primary |= IPC_MOD_ID(msg->module_id);
853
854 header.extension = IPC_DATA_OFFSET_SZ(msg->param_data_size);
855 header.extension |= IPC_LARGE_PARAM_ID(msg->large_param_id);
856 header.extension |= IPC_FINAL_BLOCK(1);
857 header.extension |= IPC_INITIAL_BLOCK(1);
858
859 sz_remaining = msg->param_data_size;
860 data_offset = 0;
861
862 while (sz_remaining != 0) {
863 rx_size = sz_remaining > SKL_ADSP_W1_SZ
864 ? SKL_ADSP_W1_SZ : sz_remaining;
865 if (rx_size == sz_remaining)
866 header.extension |= IPC_FINAL_BLOCK(1);
867
868 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0,
869 ((char *)param) + data_offset,
870 msg->param_data_size);
871 if (ret < 0) {
872 dev_err(ipc->dev,
873 "ipc: get large config fail, err: %d\n", ret);
874 return ret;
875 }
876 sz_remaining -= rx_size;
877 data_offset = msg->param_data_size - sz_remaining;
878
879 /* clear the fields */
880 header.extension &= IPC_INITIAL_BLOCK_CLEAR;
881 header.extension &= IPC_DATA_OFFSET_SZ_CLEAR;
882 /* fill the fields */
883 header.extension |= IPC_INITIAL_BLOCK(1);
884 header.extension |= IPC_DATA_OFFSET_SZ(data_offset);
885 }
886
887 return ret;
888}
889EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index f1a154e45dc3..1bbcdb471cf2 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -108,12 +108,21 @@ int skl_ipc_init_instance(struct sst_generic_ipc *sst_ipc,
108int skl_ipc_bind_unbind(struct sst_generic_ipc *sst_ipc, 108int skl_ipc_bind_unbind(struct sst_generic_ipc *sst_ipc,
109 struct skl_ipc_bind_unbind_msg *msg); 109 struct skl_ipc_bind_unbind_msg *msg);
110 110
111int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
112 u8 module_cnt, void *data);
113
114int skl_ipc_unload_modules(struct sst_generic_ipc *ipc,
115 u8 module_cnt, void *data);
116
111int skl_ipc_set_dx(struct sst_generic_ipc *ipc, 117int skl_ipc_set_dx(struct sst_generic_ipc *ipc,
112 u8 instance_id, u16 module_id, struct skl_ipc_dxstate_info *dx); 118 u8 instance_id, u16 module_id, struct skl_ipc_dxstate_info *dx);
113 119
114int skl_ipc_set_large_config(struct sst_generic_ipc *ipc, 120int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
115 struct skl_ipc_large_config_msg *msg, u32 *param); 121 struct skl_ipc_large_config_msg *msg, u32 *param);
116 122
123int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
124 struct skl_ipc_large_config_msg *msg, u32 *param);
125
117void skl_ipc_int_enable(struct sst_dsp *dsp); 126void skl_ipc_int_enable(struct sst_dsp *dsp);
118void skl_ipc_op_int_enable(struct sst_dsp *ctx); 127void skl_ipc_op_int_enable(struct sst_dsp *ctx);
119void skl_ipc_op_int_disable(struct sst_dsp *ctx); 128void skl_ipc_op_int_disable(struct sst_dsp *ctx);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index 3b83dc99f1d4..e26f4746afb7 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/err.h>
22#include "../common/sst-dsp.h" 23#include "../common/sst-dsp.h"
23#include "../common/sst-dsp-priv.h" 24#include "../common/sst-dsp-priv.h"
24#include "../common/sst-ipc.h" 25#include "../common/sst-ipc.h"
@@ -37,6 +38,8 @@
37#define SKL_INSTANCE_ID 0 38#define SKL_INSTANCE_ID 0
38#define SKL_BASE_FW_MODULE_ID 0 39#define SKL_BASE_FW_MODULE_ID 0
39 40
41#define SKL_NUM_MODULES 1
42
40static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status) 43static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)
41{ 44{
42 u32 cur_sts; 45 u32 cur_sts;
@@ -77,7 +80,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
77 init_waitqueue_head(&skl->boot_wait); 80 init_waitqueue_head(&skl->boot_wait);
78 81
79 if (ctx->fw == NULL) { 82 if (ctx->fw == NULL) {
80 ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev); 83 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
81 if (ret < 0) { 84 if (ret < 0) {
82 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 85 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
83 skl_dsp_disable_core(ctx); 86 skl_dsp_disable_core(ctx);
@@ -115,27 +118,28 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
115 dev_err(ctx->dev, 118 dev_err(ctx->dev,
116 "Timeout waiting for ROM init done, reg:0x%x\n", reg); 119 "Timeout waiting for ROM init done, reg:0x%x\n", reg);
117 ret = -EIO; 120 ret = -EIO;
118 goto skl_load_base_firmware_failed; 121 goto transfer_firmware_failed;
119 } 122 }
120 123
121 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size); 124 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
122 if (ret < 0) { 125 if (ret < 0) {
123 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 126 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
124 goto skl_load_base_firmware_failed; 127 goto transfer_firmware_failed;
125 } else { 128 } else {
126 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete, 129 ret = wait_event_timeout(skl->boot_wait, skl->boot_complete,
127 msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); 130 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
128 if (ret == 0) { 131 if (ret == 0) {
129 dev_err(ctx->dev, "DSP boot failed, FW Ready timed-out\n"); 132 dev_err(ctx->dev, "DSP boot failed, FW Ready timed-out\n");
130 ret = -EIO; 133 ret = -EIO;
131 goto skl_load_base_firmware_failed; 134 goto transfer_firmware_failed;
132 } 135 }
133 136
134 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 137 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
135 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 138 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
136 } 139 }
137 return 0; 140 return 0;
138 141transfer_firmware_failed:
142 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
139skl_load_base_firmware_failed: 143skl_load_base_firmware_failed:
140 skl_dsp_disable_core(ctx); 144 skl_dsp_disable_core(ctx);
141 release_firmware(ctx->fw); 145 release_firmware(ctx->fw);
@@ -175,10 +179,15 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
175 dx.core_mask = SKL_DSP_CORE0_MASK; 179 dx.core_mask = SKL_DSP_CORE0_MASK;
176 dx.dx_mask = SKL_IPC_D3_MASK; 180 dx.dx_mask = SKL_IPC_D3_MASK;
177 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx); 181 ret = skl_ipc_set_dx(&skl->ipc, SKL_INSTANCE_ID, SKL_BASE_FW_MODULE_ID, &dx);
178 if (ret < 0) { 182 if (ret < 0)
179 dev_err(ctx->dev, "Failed to set DSP to D3 state\n"); 183 dev_err(ctx->dev,
180 return ret; 184 "D3 request to FW failed, continuing reset: %d", ret);
181 } 185
186 /* disable Interrupt */
187 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
188 skl_cldma_int_disable(ctx);
189 skl_ipc_op_int_disable(ctx);
190 skl_ipc_int_disable(ctx);
182 191
183 ret = skl_dsp_disable_core(ctx); 192 ret = skl_dsp_disable_core(ctx);
184 if (ret < 0) { 193 if (ret < 0) {
@@ -187,12 +196,6 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
187 } 196 }
188 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); 197 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
189 198
190 /* disable Interrupt */
191 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
192 skl_cldma_int_disable(ctx);
193 skl_ipc_op_int_disable(ctx);
194 skl_ipc_int_disable(ctx);
195
196 return ret; 199 return ret;
197} 200}
198 201
@@ -201,11 +204,182 @@ static unsigned int skl_get_errorcode(struct sst_dsp *ctx)
201 return sst_dsp_shim_read(ctx, SKL_ADSP_ERROR_CODE); 204 return sst_dsp_shim_read(ctx, SKL_ADSP_ERROR_CODE);
202} 205}
203 206
207/*
208 * since get/set_module are called from DAPM context,
209 * we don't need lock for usage count
210 */
211static int skl_get_module(struct sst_dsp *ctx, u16 mod_id)
212{
213 struct skl_module_table *module;
214
215 list_for_each_entry(module, &ctx->module_list, list) {
216 if (module->mod_info->mod_id == mod_id)
217 return ++module->usage_cnt;
218 }
219
220 return -EINVAL;
221}
222
223static int skl_put_module(struct sst_dsp *ctx, u16 mod_id)
224{
225 struct skl_module_table *module;
226
227 list_for_each_entry(module, &ctx->module_list, list) {
228 if (module->mod_info->mod_id == mod_id)
229 return --module->usage_cnt;
230 }
231
232 return -EINVAL;
233}
234
235static struct skl_module_table *skl_fill_module_table(struct sst_dsp *ctx,
236 char *mod_name, int mod_id)
237{
238 const struct firmware *fw;
239 struct skl_module_table *skl_module;
240 unsigned int size;
241 int ret;
242
243 ret = request_firmware(&fw, mod_name, ctx->dev);
244 if (ret < 0) {
245 dev_err(ctx->dev, "Request Module %s failed :%d\n",
246 mod_name, ret);
247 return NULL;
248 }
249
250 skl_module = devm_kzalloc(ctx->dev, sizeof(*skl_module), GFP_KERNEL);
251 if (skl_module == NULL) {
252 release_firmware(fw);
253 return NULL;
254 }
255
256 size = sizeof(*skl_module->mod_info);
257 skl_module->mod_info = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
258 if (skl_module->mod_info == NULL) {
259 release_firmware(fw);
260 return NULL;
261 }
262
263 skl_module->mod_info->mod_id = mod_id;
264 skl_module->mod_info->fw = fw;
265 list_add(&skl_module->list, &ctx->module_list);
266
267 return skl_module;
268}
269
270/* get a module from it's unique ID */
271static struct skl_module_table *skl_module_get_from_id(
272 struct sst_dsp *ctx, u16 mod_id)
273{
274 struct skl_module_table *module;
275
276 if (list_empty(&ctx->module_list)) {
277 dev_err(ctx->dev, "Module list is empty\n");
278 return NULL;
279 }
280
281 list_for_each_entry(module, &ctx->module_list, list) {
282 if (module->mod_info->mod_id == mod_id)
283 return module;
284 }
285
286 return NULL;
287}
288
289static int skl_transfer_module(struct sst_dsp *ctx,
290 struct skl_load_module_info *module)
291{
292 int ret;
293 struct skl_sst *skl = ctx->thread_context;
294
295 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, module->fw->data,
296 module->fw->size);
297 if (ret < 0)
298 return ret;
299
300 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES,
301 (void *)&module->mod_id);
302 if (ret < 0)
303 dev_err(ctx->dev, "Failed to Load module: %d\n", ret);
304
305 ctx->cl_dev.ops.cl_stop_dma(ctx);
306
307 return ret;
308}
309
310static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, char *guid)
311{
312 struct skl_module_table *module_entry = NULL;
313 int ret = 0;
314 char mod_name[64]; /* guid str = 32 chars + 4 hyphens */
315
316 snprintf(mod_name, sizeof(mod_name), "%s%s%s",
317 "intel/dsp_fw_", guid, ".bin");
318
319 module_entry = skl_module_get_from_id(ctx, mod_id);
320 if (module_entry == NULL) {
321 module_entry = skl_fill_module_table(ctx, mod_name, mod_id);
322 if (module_entry == NULL) {
323 dev_err(ctx->dev, "Failed to Load module\n");
324 return -EINVAL;
325 }
326 }
327
328 if (!module_entry->usage_cnt) {
329 ret = skl_transfer_module(ctx, module_entry->mod_info);
330 if (ret < 0) {
331 dev_err(ctx->dev, "Failed to Load module\n");
332 return ret;
333 }
334 }
335
336 ret = skl_get_module(ctx, mod_id);
337
338 return ret;
339}
340
341static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
342{
343 int usage_cnt;
344 struct skl_sst *skl = ctx->thread_context;
345 int ret = 0;
346
347 usage_cnt = skl_put_module(ctx, mod_id);
348 if (usage_cnt < 0) {
349 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt);
350 return -EIO;
351 }
352 ret = skl_ipc_unload_modules(&skl->ipc,
353 SKL_NUM_MODULES, &mod_id);
354 if (ret < 0) {
355 dev_err(ctx->dev, "Failed to UnLoad module\n");
356 skl_get_module(ctx, mod_id);
357 return ret;
358 }
359
360 return ret;
361}
362
363static void skl_clear_module_table(struct sst_dsp *ctx)
364{
365 struct skl_module_table *module, *tmp;
366
367 if (list_empty(&ctx->module_list))
368 return;
369
370 list_for_each_entry_safe(module, tmp, &ctx->module_list, list) {
371 list_del(&module->list);
372 release_firmware(module->mod_info->fw);
373 }
374}
375
204static struct skl_dsp_fw_ops skl_fw_ops = { 376static struct skl_dsp_fw_ops skl_fw_ops = {
205 .set_state_D0 = skl_set_dsp_D0, 377 .set_state_D0 = skl_set_dsp_D0,
206 .set_state_D3 = skl_set_dsp_D3, 378 .set_state_D3 = skl_set_dsp_D3,
207 .load_fw = skl_load_base_firmware, 379 .load_fw = skl_load_base_firmware,
208 .get_fw_errcode = skl_get_errorcode, 380 .get_fw_errcode = skl_get_errorcode,
381 .load_mod = skl_load_module,
382 .unload_mod = skl_unload_module,
209}; 383};
210 384
211static struct sst_ops skl_ops = { 385static struct sst_ops skl_ops = {
@@ -223,7 +397,7 @@ static struct sst_dsp_device skl_dev = {
223}; 397};
224 398
225int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 399int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
226 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp) 400 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp)
227{ 401{
228 struct skl_sst *skl; 402 struct skl_sst *skl;
229 struct sst_dsp *sst; 403 struct sst_dsp *sst;
@@ -244,11 +418,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
244 418
245 sst = skl->dsp; 419 sst = skl->dsp;
246 420
421 sst->fw_name = fw_name;
247 sst->addr.lpe = mmio_base; 422 sst->addr.lpe = mmio_base;
248 sst->addr.shim = mmio_base; 423 sst->addr.shim = mmio_base;
249 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 424 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
250 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 425 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
251 426
427 INIT_LIST_HEAD(&sst->module_list);
252 sst->dsp_ops = dsp_ops; 428 sst->dsp_ops = dsp_ops;
253 sst->fw_ops = skl_fw_ops; 429 sst->fw_ops = skl_fw_ops;
254 430
@@ -259,23 +435,24 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
259 ret = sst->fw_ops.load_fw(sst); 435 ret = sst->fw_ops.load_fw(sst);
260 if (ret < 0) { 436 if (ret < 0) {
261 dev_err(dev, "Load base fw failed : %d", ret); 437 dev_err(dev, "Load base fw failed : %d", ret);
262 return ret; 438 goto cleanup;
263 } 439 }
264 440
265 if (dsp) 441 if (dsp)
266 *dsp = skl; 442 *dsp = skl;
267 443
268 return 0; 444 return ret;
269 445
270 skl_ipc_free(&skl->ipc); 446cleanup:
447 skl_sst_dsp_cleanup(dev, skl);
271 return ret; 448 return ret;
272} 449}
273EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 450EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
274 451
275void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 452void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
276{ 453{
454 skl_clear_module_table(ctx->dsp);
277 skl_ipc_free(&ctx->ipc); 455 skl_ipc_free(&ctx->ipc);
278 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
279 ctx->dsp->ops->free(ctx->dsp); 456 ctx->dsp->ops->free(ctx->dsp);
280} 457}
281EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup); 458EXPORT_SYMBOL_GPL(skl_sst_dsp_cleanup);
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index ffea427aeca8..5315b7422b98 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -26,6 +26,8 @@
26#include "skl-topology.h" 26#include "skl-topology.h"
27#include "skl.h" 27#include "skl.h"
28#include "skl-tplg-interface.h" 28#include "skl-tplg-interface.h"
29#include "../common/sst-dsp.h"
30#include "../common/sst-dsp-priv.h"
29 31
30#define SKL_CH_FIXUP_MASK (1 << 0) 32#define SKL_CH_FIXUP_MASK (1 << 0)
31#define SKL_RATE_FIXUP_MASK (1 << 1) 33#define SKL_RATE_FIXUP_MASK (1 << 1)
@@ -129,17 +131,15 @@ static void skl_dump_mconfig(struct skl_sst *ctx,
129{ 131{
130 dev_dbg(ctx->dev, "Dumping config\n"); 132 dev_dbg(ctx->dev, "Dumping config\n");
131 dev_dbg(ctx->dev, "Input Format:\n"); 133 dev_dbg(ctx->dev, "Input Format:\n");
132 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels); 134 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels);
133 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq); 135 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq);
134 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg); 136 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg);
135 dev_dbg(ctx->dev, "valid bit depth = %d\n", 137 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth);
136 mcfg->in_fmt.valid_bit_depth);
137 dev_dbg(ctx->dev, "Output Format:\n"); 138 dev_dbg(ctx->dev, "Output Format:\n");
138 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels); 139 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels);
139 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq); 140 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq);
140 dev_dbg(ctx->dev, "valid bit depth = %d\n", 141 dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth);
141 mcfg->out_fmt.valid_bit_depth); 142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg);
142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg);
143} 143}
144 144
145static void skl_tplg_update_params(struct skl_module_fmt *fmt, 145static void skl_tplg_update_params(struct skl_module_fmt *fmt,
@@ -149,8 +149,24 @@ static void skl_tplg_update_params(struct skl_module_fmt *fmt,
149 fmt->s_freq = params->s_freq; 149 fmt->s_freq = params->s_freq;
150 if (fixup & SKL_CH_FIXUP_MASK) 150 if (fixup & SKL_CH_FIXUP_MASK)
151 fmt->channels = params->ch; 151 fmt->channels = params->ch;
152 if (fixup & SKL_FMT_FIXUP_MASK) 152 if (fixup & SKL_FMT_FIXUP_MASK) {
153 fmt->valid_bit_depth = params->s_fmt; 153 fmt->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
154
155 /*
156 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
157 * container so update bit depth accordingly
158 */
159 switch (fmt->valid_bit_depth) {
160 case SKL_DEPTH_16BIT:
161 fmt->bit_depth = fmt->valid_bit_depth;
162 break;
163
164 default:
165 fmt->bit_depth = SKL_DEPTH_32BIT;
166 break;
167 }
168 }
169
154} 170}
155 171
156/* 172/*
@@ -171,8 +187,9 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
171 int in_fixup, out_fixup; 187 int in_fixup, out_fixup;
172 struct skl_module_fmt *in_fmt, *out_fmt; 188 struct skl_module_fmt *in_fmt, *out_fmt;
173 189
174 in_fmt = &m_cfg->in_fmt; 190 /* Fixups will be applied to pin 0 only */
175 out_fmt = &m_cfg->out_fmt; 191 in_fmt = &m_cfg->in_fmt[0];
192 out_fmt = &m_cfg->out_fmt[0];
176 193
177 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { 194 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 if (is_fe) { 195 if (is_fe) {
@@ -209,18 +226,25 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
209 struct skl_module_cfg *mcfg) 226 struct skl_module_cfg *mcfg)
210{ 227{
211 int multiplier = 1; 228 int multiplier = 1;
229 struct skl_module_fmt *in_fmt, *out_fmt;
230
231
232 /* Since fixups is applied to pin 0 only, ibs, obs needs
233 * change for pin 0 only
234 */
235 in_fmt = &mcfg->in_fmt[0];
236 out_fmt = &mcfg->out_fmt[0];
212 237
213 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) 238 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
214 multiplier = 5; 239 multiplier = 5;
215 240 mcfg->ibs = (in_fmt->s_freq / 1000) *
216 mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) * 241 (mcfg->in_fmt->channels) *
217 (mcfg->in_fmt.channels) * 242 (mcfg->in_fmt->bit_depth >> 3) *
218 (mcfg->in_fmt.bit_depth >> 3) *
219 multiplier; 243 multiplier;
220 244
221 mcfg->obs = (mcfg->out_fmt.s_freq / 1000) * 245 mcfg->obs = (mcfg->out_fmt->s_freq / 1000) *
222 (mcfg->out_fmt.channels) * 246 (mcfg->out_fmt->channels) *
223 (mcfg->out_fmt.bit_depth >> 3) * 247 (mcfg->out_fmt->bit_depth >> 3) *
224 multiplier; 248 multiplier;
225} 249}
226 250
@@ -292,6 +316,83 @@ static int skl_tplg_alloc_pipe_widget(struct device *dev,
292} 316}
293 317
294/* 318/*
319 * some modules can have multiple params set from user control and
320 * need to be set after module is initialized. If set_param flag is
321 * set module params will be done after module is initialised.
322 */
323static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
324 struct skl_sst *ctx)
325{
326 int i, ret;
327 struct skl_module_cfg *mconfig = w->priv;
328 const struct snd_kcontrol_new *k;
329 struct soc_bytes_ext *sb;
330 struct skl_algo_data *bc;
331 struct skl_specific_cfg *sp_cfg;
332
333 if (mconfig->formats_config.caps_size > 0 &&
334 mconfig->formats_config.set_params == SKL_PARAM_SET) {
335 sp_cfg = &mconfig->formats_config;
336 ret = skl_set_module_params(ctx, sp_cfg->caps,
337 sp_cfg->caps_size,
338 sp_cfg->param_id, mconfig);
339 if (ret < 0)
340 return ret;
341 }
342
343 for (i = 0; i < w->num_kcontrols; i++) {
344 k = &w->kcontrol_news[i];
345 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
346 sb = (void *) k->private_value;
347 bc = (struct skl_algo_data *)sb->dobj.private;
348
349 if (bc->set_params == SKL_PARAM_SET) {
350 ret = skl_set_module_params(ctx,
351 (u32 *)bc->params, bc->max,
352 bc->param_id, mconfig);
353 if (ret < 0)
354 return ret;
355 }
356 }
357 }
358
359 return 0;
360}
361
362/*
363 * some module param can set from user control and this is required as
364 * when module is initailzed. if module param is required in init it is
365 * identifed by set_param flag. if set_param flag is not set, then this
366 * parameter needs to set as part of module init.
367 */
368static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
369{
370 const struct snd_kcontrol_new *k;
371 struct soc_bytes_ext *sb;
372 struct skl_algo_data *bc;
373 struct skl_module_cfg *mconfig = w->priv;
374 int i;
375
376 for (i = 0; i < w->num_kcontrols; i++) {
377 k = &w->kcontrol_news[i];
378 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
379 sb = (struct soc_bytes_ext *)k->private_value;
380 bc = (struct skl_algo_data *)sb->dobj.private;
381
382 if (bc->set_params != SKL_PARAM_INIT)
383 continue;
384
385 mconfig->formats_config.caps = (u32 *)&bc->params;
386 mconfig->formats_config.caps_size = bc->max;
387
388 break;
389 }
390 }
391
392 return 0;
393}
394
395/*
295 * Inside a pipe instance, we can have various modules. These modules need 396 * Inside a pipe instance, we can have various modules. These modules need
296 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by 397 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
297 * skl_init_module() routine, so invoke that for all modules in a pipeline 398 * skl_init_module() routine, so invoke that for all modules in a pipeline
@@ -313,12 +414,25 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
313 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) 414 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
314 return -ENOMEM; 415 return -ENOMEM;
315 416
417 if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
418 ret = ctx->dsp->fw_ops.load_mod(ctx->dsp,
419 mconfig->id.module_id, mconfig->guid);
420 if (ret < 0)
421 return ret;
422 }
423
316 /* 424 /*
317 * apply fix/conversion to module params based on 425 * apply fix/conversion to module params based on
318 * FE/BE params 426 * FE/BE params
319 */ 427 */
320 skl_tplg_update_module_params(w, ctx); 428 skl_tplg_update_module_params(w, ctx);
321 ret = skl_init_module(ctx, mconfig, NULL); 429
430 skl_tplg_set_module_init_data(w);
431 ret = skl_init_module(ctx, mconfig);
432 if (ret < 0)
433 return ret;
434
435 ret = skl_tplg_set_module_params(w, ctx);
322 if (ret < 0) 436 if (ret < 0)
323 return ret; 437 return ret;
324 } 438 }
@@ -326,6 +440,24 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
326 return 0; 440 return 0;
327} 441}
328 442
443static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
444 struct skl_pipe *pipe)
445{
446 struct skl_pipe_module *w_module = NULL;
447 struct skl_module_cfg *mconfig = NULL;
448
449 list_for_each_entry(w_module, &pipe->w_list, node) {
450 mconfig = w_module->w->priv;
451
452 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod)
453 return ctx->dsp->fw_ops.unload_mod(ctx->dsp,
454 mconfig->id.module_id);
455 }
456
457 /* no modules to unload in this path, so return */
458 return 0;
459}
460
329/* 461/*
330 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we 462 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
331 * need create the pipeline. So we do following: 463 * need create the pipeline. So we do following:
@@ -397,41 +529,24 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
397 return 0; 529 return 0;
398} 530}
399 531
400/* 532static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
401 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA 533 struct skl *skl,
402 * we need to do following: 534 struct skl_module_cfg *src_mconfig)
403 * - Bind to sink pipeline
404 * Since the sink pipes can be running and we don't get mixer event on
405 * connect for already running mixer, we need to find the sink pipes
406 * here and bind to them. This way dynamic connect works.
407 * - Start sink pipeline, if not running
408 * - Then run current pipe
409 */
410static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
411 struct skl *skl)
412{ 535{
413 struct snd_soc_dapm_path *p; 536 struct snd_soc_dapm_path *p;
414 struct skl_dapm_path_list *path_list; 537 struct snd_soc_dapm_widget *sink = NULL, *next_sink = NULL;
415 struct snd_soc_dapm_widget *source, *sink; 538 struct skl_module_cfg *sink_mconfig;
416 struct skl_module_cfg *src_mconfig, *sink_mconfig;
417 struct skl_sst *ctx = skl->skl_sst; 539 struct skl_sst *ctx = skl->skl_sst;
418 int ret = 0; 540 int ret;
419
420 source = w;
421 src_mconfig = source->priv;
422 541
423 /* 542 snd_soc_dapm_widget_for_each_sink_path(w, p) {
424 * find which sink it is connected to, bind with the sink,
425 * if sink is not started, start sink pipe first, then start
426 * this pipe
427 */
428 snd_soc_dapm_widget_for_each_source_path(w, p) {
429 if (!p->connect) 543 if (!p->connect)
430 continue; 544 continue;
431 545
432 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name); 546 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
433 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); 547 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
434 548
549 next_sink = p->sink;
435 /* 550 /*
436 * here we will check widgets in sink pipelines, so that 551 * here we will check widgets in sink pipelines, so that
437 * can be any widgets type and we are only interested if 552 * can be any widgets type and we are only interested if
@@ -441,7 +556,6 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
441 is_skl_dsp_widget_type(p->sink)) { 556 is_skl_dsp_widget_type(p->sink)) {
442 557
443 sink = p->sink; 558 sink = p->sink;
444 src_mconfig = source->priv;
445 sink_mconfig = sink->priv; 559 sink_mconfig = sink->priv;
446 560
447 /* Bind source to sink, mixin is always source */ 561 /* Bind source to sink, mixin is always source */
@@ -451,32 +565,89 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
451 565
452 /* Start sinks pipe first */ 566 /* Start sinks pipe first */
453 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) { 567 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
454 ret = skl_run_pipe(ctx, sink_mconfig->pipe); 568 if (sink_mconfig->pipe->conn_type !=
569 SKL_PIPE_CONN_TYPE_FE)
570 ret = skl_run_pipe(ctx,
571 sink_mconfig->pipe);
455 if (ret) 572 if (ret)
456 return ret; 573 return ret;
457 } 574 }
458
459 path_list = kzalloc(
460 sizeof(struct skl_dapm_path_list),
461 GFP_KERNEL);
462 if (path_list == NULL)
463 return -ENOMEM;
464
465 /* Add connected path to one global list */
466 path_list->dapm_path = p;
467 list_add_tail(&path_list->node, &skl->dapm_path_list);
468 break;
469 } 575 }
470 } 576 }
471 577
472 /* Start source pipe last after starting all sinks */ 578 if (!sink)
473 ret = skl_run_pipe(ctx, src_mconfig->pipe); 579 return skl_tplg_bind_sinks(next_sink, skl, src_mconfig);
580
581 return 0;
582}
583
584/*
585 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
586 * we need to do following:
587 * - Bind to sink pipeline
588 * Since the sink pipes can be running and we don't get mixer event on
589 * connect for already running mixer, we need to find the sink pipes
590 * here and bind to them. This way dynamic connect works.
591 * - Start sink pipeline, if not running
592 * - Then run current pipe
593 */
594static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
595 struct skl *skl)
596{
597 struct skl_module_cfg *src_mconfig;
598 struct skl_sst *ctx = skl->skl_sst;
599 int ret = 0;
600
601 src_mconfig = w->priv;
602
603 /*
604 * find which sink it is connected to, bind with the sink,
605 * if sink is not started, start sink pipe first, then start
606 * this pipe
607 */
608 ret = skl_tplg_bind_sinks(w, skl, src_mconfig);
474 if (ret) 609 if (ret)
475 return ret; 610 return ret;
476 611
612 /* Start source pipe last after starting all sinks */
613 if (src_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
614 return skl_run_pipe(ctx, src_mconfig->pipe);
615
477 return 0; 616 return 0;
478} 617}
479 618
619static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
620 struct snd_soc_dapm_widget *w, struct skl *skl)
621{
622 struct snd_soc_dapm_path *p;
623 struct snd_soc_dapm_widget *src_w = NULL;
624 struct skl_sst *ctx = skl->skl_sst;
625
626 snd_soc_dapm_widget_for_each_source_path(w, p) {
627 src_w = p->source;
628 if (!p->connect)
629 continue;
630
631 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
632 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
633
634 /*
635 * here we will check widgets in sink pipelines, so that can
636 * be any widgets type and we are only interested if they are
637 * ones used for SKL so check that first
638 */
639 if ((p->source->priv != NULL) &&
640 is_skl_dsp_widget_type(p->source)) {
641 return p->source;
642 }
643 }
644
645 if (src_w != NULL)
646 return skl_get_src_dsp_widget(src_w, skl);
647
648 return NULL;
649}
650
480/* 651/*
481 * in the Post-PMU event of mixer we need to do following: 652 * in the Post-PMU event of mixer we need to do following:
482 * - Check if this pipe is running 653 * - Check if this pipe is running
@@ -490,7 +661,6 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
490 struct skl *skl) 661 struct skl *skl)
491{ 662{
492 int ret = 0; 663 int ret = 0;
493 struct snd_soc_dapm_path *p;
494 struct snd_soc_dapm_widget *source, *sink; 664 struct snd_soc_dapm_widget *source, *sink;
495 struct skl_module_cfg *src_mconfig, *sink_mconfig; 665 struct skl_module_cfg *src_mconfig, *sink_mconfig;
496 struct skl_sst *ctx = skl->skl_sst; 666 struct skl_sst *ctx = skl->skl_sst;
@@ -504,32 +674,18 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
504 * one more sink before this sink got connected, Since source is 674 * one more sink before this sink got connected, Since source is
505 * started, bind this sink to source and start this pipe. 675 * started, bind this sink to source and start this pipe.
506 */ 676 */
507 snd_soc_dapm_widget_for_each_sink_path(w, p) { 677 source = skl_get_src_dsp_widget(w, skl);
508 if (!p->connect) 678 if (source != NULL) {
509 continue; 679 src_mconfig = source->priv;
510 680 sink_mconfig = sink->priv;
511 dev_dbg(ctx->dev, "sink widget=%s\n", w->name); 681 src_pipe_started = 1;
512 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
513 682
514 /* 683 /*
515 * here we will check widgets in sink pipelines, so that 684 * check pipe state, then no need to bind or start the
516 * can be any widgets type and we are only interested if 685 * pipe
517 * they are ones used for SKL so check that first
518 */ 686 */
519 if ((p->source->priv != NULL) && 687 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
520 is_skl_dsp_widget_type(p->source)) { 688 src_pipe_started = 0;
521 source = p->source;
522 src_mconfig = source->priv;
523 sink_mconfig = sink->priv;
524 src_pipe_started = 1;
525
526 /*
527 * check pipe state, then no need to bind or start
528 * the pipe
529 */
530 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
531 src_pipe_started = 0;
532 }
533 } 689 }
534 690
535 if (src_pipe_started) { 691 if (src_pipe_started) {
@@ -537,7 +693,8 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
537 if (ret) 693 if (ret)
538 return ret; 694 return ret;
539 695
540 ret = skl_run_pipe(ctx, sink_mconfig->pipe); 696 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
697 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
541 } 698 }
542 699
543 return ret; 700 return ret;
@@ -552,52 +709,35 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
552static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, 709static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
553 struct skl *skl) 710 struct skl *skl)
554{ 711{
555 struct snd_soc_dapm_widget *source, *sink;
556 struct skl_module_cfg *src_mconfig, *sink_mconfig; 712 struct skl_module_cfg *src_mconfig, *sink_mconfig;
557 int ret = 0, path_found = 0; 713 int ret = 0, i;
558 struct skl_dapm_path_list *path_list, *tmp_list;
559 struct skl_sst *ctx = skl->skl_sst; 714 struct skl_sst *ctx = skl->skl_sst;
560 715
561 sink = w; 716 sink_mconfig = w->priv;
562 sink_mconfig = sink->priv;
563 717
564 /* Stop the pipe */ 718 /* Stop the pipe */
565 ret = skl_stop_pipe(ctx, sink_mconfig->pipe); 719 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
566 if (ret) 720 if (ret)
567 return ret; 721 return ret;
568 722
569 /* 723 for (i = 0; i < sink_mconfig->max_in_queue; i++) {
570 * This list, dapm_path_list handling here does not need any locks 724 if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) {
571 * as we are under dapm lock while handling widget events. 725 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
572 * List can be manipulated safely only under dapm widgets handler 726 if (!src_mconfig)
573 * routines 727 continue;
574 */ 728 /*
575 list_for_each_entry_safe(path_list, tmp_list, 729 * If path_found == 1, that means pmd for source
576 &skl->dapm_path_list, node) { 730 * pipe has not occurred, source is connected to
577 if (path_list->dapm_path->sink == sink) { 731 * some other sink. so its responsibility of sink
578 dev_dbg(ctx->dev, "Path found = %s\n", 732 * to unbind itself from source.
579 path_list->dapm_path->name); 733 */
580 source = path_list->dapm_path->source; 734 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
581 src_mconfig = source->priv; 735 if (ret < 0)
582 path_found = 1; 736 return ret;
583
584 list_del(&path_list->node);
585 kfree(path_list);
586 break;
587 }
588 }
589
590 /*
591 * If path_found == 1, that means pmd for source pipe has
592 * not occurred, source is connected to some other sink.
593 * so its responsibility of sink to unbind itself from source.
594 */
595 if (path_found) {
596 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
597 if (ret < 0)
598 return ret;
599 737
600 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig); 738 ret = skl_unbind_modules(ctx,
739 src_mconfig, sink_mconfig);
740 }
601 } 741 }
602 742
603 return ret; 743 return ret;
@@ -622,10 +762,12 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
622 int ret = 0; 762 int ret = 0;
623 763
624 skl_tplg_free_pipe_mcps(skl, mconfig); 764 skl_tplg_free_pipe_mcps(skl, mconfig);
765 skl_tplg_free_pipe_mem(skl, mconfig);
625 766
626 list_for_each_entry(w_module, &s_pipe->w_list, node) { 767 list_for_each_entry(w_module, &s_pipe->w_list, node) {
627 dst_module = w_module->w->priv; 768 dst_module = w_module->w->priv;
628 769
770 skl_tplg_free_pipe_mcps(skl, dst_module);
629 if (src_module == NULL) { 771 if (src_module == NULL) {
630 src_module = dst_module; 772 src_module = dst_module;
631 continue; 773 continue;
@@ -639,9 +781,8 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
639 } 781 }
640 782
641 ret = skl_delete_pipe(ctx, mconfig->pipe); 783 ret = skl_delete_pipe(ctx, mconfig->pipe);
642 skl_tplg_free_pipe_mem(skl, mconfig);
643 784
644 return ret; 785 return skl_tplg_unload_pipe_modules(ctx, s_pipe);
645} 786}
646 787
647/* 788/*
@@ -653,47 +794,34 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
653static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, 794static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
654 struct skl *skl) 795 struct skl *skl)
655{ 796{
656 struct snd_soc_dapm_widget *source, *sink;
657 struct skl_module_cfg *src_mconfig, *sink_mconfig; 797 struct skl_module_cfg *src_mconfig, *sink_mconfig;
658 int ret = 0, path_found = 0; 798 int ret = 0, i;
659 struct skl_dapm_path_list *path_list, *tmp_path_list;
660 struct skl_sst *ctx = skl->skl_sst; 799 struct skl_sst *ctx = skl->skl_sst;
661 800
662 source = w; 801 src_mconfig = w->priv;
663 src_mconfig = source->priv;
664 802
665 skl_tplg_free_pipe_mcps(skl, src_mconfig);
666 /* Stop the pipe since this is a mixin module */ 803 /* Stop the pipe since this is a mixin module */
667 ret = skl_stop_pipe(ctx, src_mconfig->pipe); 804 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
668 if (ret) 805 if (ret)
669 return ret; 806 return ret;
670 807
671 list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) { 808 for (i = 0; i < src_mconfig->max_out_queue; i++) {
672 if (path_list->dapm_path->source == source) { 809 if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) {
673 dev_dbg(ctx->dev, "Path found = %s\n", 810 sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg;
674 path_list->dapm_path->name); 811 if (!sink_mconfig)
675 sink = path_list->dapm_path->sink; 812 continue;
676 sink_mconfig = sink->priv; 813 /*
677 path_found = 1; 814 * This is a connecter and if path is found that means
678 815 * unbind between source and sink has not happened yet
679 list_del(&path_list->node); 816 */
680 kfree(path_list); 817 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
681 break; 818 if (ret < 0)
819 return ret;
820 ret = skl_unbind_modules(ctx, src_mconfig,
821 sink_mconfig);
682 } 822 }
683 } 823 }
684 824
685 /*
686 * This is a connector and if path is found that means
687 * unbind between source and sink has not happened yet
688 */
689 if (path_found) {
690 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
691 if (ret < 0)
692 return ret;
693
694 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
695 }
696
697 return ret; 825 return ret;
698} 826}
699 827
@@ -774,6 +902,67 @@ static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
774 return 0; 902 return 0;
775} 903}
776 904
905static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
906 unsigned int __user *data, unsigned int size)
907{
908 struct soc_bytes_ext *sb =
909 (struct soc_bytes_ext *)kcontrol->private_value;
910 struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
911 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
912 struct skl_module_cfg *mconfig = w->priv;
913 struct skl *skl = get_skl_ctx(w->dapm->dev);
914
915 if (w->power)
916 skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
917 bc->max, bc->param_id, mconfig);
918
919 if (bc->params) {
920 if (copy_to_user(data, &bc->param_id, sizeof(u32)))
921 return -EFAULT;
922 if (copy_to_user(data + 1, &size, sizeof(u32)))
923 return -EFAULT;
924 if (copy_to_user(data + 2, bc->params, size))
925 return -EFAULT;
926 }
927
928 return 0;
929}
930
931#define SKL_PARAM_VENDOR_ID 0xff
932
933static int skl_tplg_tlv_control_set(struct snd_kcontrol *kcontrol,
934 const unsigned int __user *data, unsigned int size)
935{
936 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
937 struct skl_module_cfg *mconfig = w->priv;
938 struct soc_bytes_ext *sb =
939 (struct soc_bytes_ext *)kcontrol->private_value;
940 struct skl_algo_data *ac = (struct skl_algo_data *)sb->dobj.private;
941 struct skl *skl = get_skl_ctx(w->dapm->dev);
942
943 if (ac->params) {
944 /*
945 * if the param_is is of type Vendor, firmware expects actual
946 * parameter id and size from the control.
947 */
948 if (ac->param_id == SKL_PARAM_VENDOR_ID) {
949 if (copy_from_user(ac->params, data, size))
950 return -EFAULT;
951 } else {
952 if (copy_from_user(ac->params,
953 data + 2 * sizeof(u32), size))
954 return -EFAULT;
955 }
956
957 if (w->power)
958 return skl_set_module_params(skl->skl_sst,
959 (u32 *)ac->params, ac->max,
960 ac->param_id, mconfig);
961 }
962
963 return 0;
964}
965
777/* 966/*
778 * The FE params are passed by hw_params of the DAI. 967 * The FE params are passed by hw_params of the DAI.
779 * On hw_params, the params are stored in Gateway module of the FE and we 968 * On hw_params, the params are stored in Gateway module of the FE and we
@@ -790,9 +979,9 @@ int skl_tplg_update_pipe_params(struct device *dev,
790 memcpy(pipe->p_params, params, sizeof(*params)); 979 memcpy(pipe->p_params, params, sizeof(*params));
791 980
792 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) 981 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
793 format = &mconfig->in_fmt; 982 format = &mconfig->in_fmt[0];
794 else 983 else
795 format = &mconfig->out_fmt; 984 format = &mconfig->out_fmt[0];
796 985
797 /* set the hw_params */ 986 /* set the hw_params */
798 format->s_freq = params->s_freq; 987 format->s_freq = params->s_freq;
@@ -809,6 +998,7 @@ int skl_tplg_update_pipe_params(struct device *dev,
809 break; 998 break;
810 999
811 case SKL_DEPTH_24BIT: 1000 case SKL_DEPTH_24BIT:
1001 case SKL_DEPTH_32BIT:
812 format->bit_depth = SKL_DEPTH_32BIT; 1002 format->bit_depth = SKL_DEPTH_32BIT;
813 break; 1003 break;
814 1004
@@ -846,7 +1036,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
846 w = dai->playback_widget; 1036 w = dai->playback_widget;
847 snd_soc_dapm_widget_for_each_sink_path(w, p) { 1037 snd_soc_dapm_widget_for_each_sink_path(w, p) {
848 if (p->connect && p->sink->power && 1038 if (p->connect && p->sink->power &&
849 is_skl_dsp_widget_type(p->sink)) 1039 !is_skl_dsp_widget_type(p->sink))
850 continue; 1040 continue;
851 1041
852 if (p->sink->priv) { 1042 if (p->sink->priv) {
@@ -859,7 +1049,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
859 w = dai->capture_widget; 1049 w = dai->capture_widget;
860 snd_soc_dapm_widget_for_each_source_path(w, p) { 1050 snd_soc_dapm_widget_for_each_source_path(w, p) {
861 if (p->connect && p->source->power && 1051 if (p->connect && p->source->power &&
862 is_skl_dsp_widget_type(p->source)) 1052 !is_skl_dsp_widget_type(p->source))
863 continue; 1053 continue;
864 1054
865 if (p->source->priv) { 1055 if (p->source->priv) {
@@ -920,6 +1110,9 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
920 1110
921 memcpy(pipe->p_params, params, sizeof(*params)); 1111 memcpy(pipe->p_params, params, sizeof(*params));
922 1112
1113 if (link_type == NHLT_LINK_HDA)
1114 return 0;
1115
923 /* update the blob based on virtual bus_id*/ 1116 /* update the blob based on virtual bus_id*/
924 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type, 1117 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
925 params->s_fmt, params->ch, 1118 params->s_fmt, params->ch,
@@ -950,18 +1143,13 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
950 if (p->connect && is_skl_dsp_widget_type(p->source) && 1143 if (p->connect && is_skl_dsp_widget_type(p->source) &&
951 p->source->priv) { 1144 p->source->priv) {
952 1145
953 if (!p->source->power) { 1146 ret = skl_tplg_be_fill_pipe_params(dai,
954 ret = skl_tplg_be_fill_pipe_params( 1147 p->source->priv, params);
955 dai, p->source->priv, 1148 if (ret < 0)
956 params); 1149 return ret;
957 if (ret < 0)
958 return ret;
959 } else {
960 return -EBUSY;
961 }
962 } else { 1150 } else {
963 ret = skl_tplg_be_set_src_pipe_params( 1151 ret = skl_tplg_be_set_src_pipe_params(dai,
964 dai, p->source, params); 1152 p->source, params);
965 if (ret < 0) 1153 if (ret < 0)
966 return ret; 1154 return ret;
967 } 1155 }
@@ -980,15 +1168,10 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
980 if (p->connect && is_skl_dsp_widget_type(p->sink) && 1168 if (p->connect && is_skl_dsp_widget_type(p->sink) &&
981 p->sink->priv) { 1169 p->sink->priv) {
982 1170
983 if (!p->sink->power) { 1171 ret = skl_tplg_be_fill_pipe_params(dai,
984 ret = skl_tplg_be_fill_pipe_params( 1172 p->sink->priv, params);
985 dai, p->sink->priv, params); 1173 if (ret < 0)
986 if (ret < 0) 1174 return ret;
987 return ret;
988 } else {
989 return -EBUSY;
990 }
991
992 } else { 1175 } else {
993 ret = skl_tplg_be_set_sink_pipe_params( 1176 ret = skl_tplg_be_set_sink_pipe_params(
994 dai, p->sink, params); 1177 dai, p->sink, params);
@@ -1030,6 +1213,11 @@ static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1030 {SKL_PGA_EVENT, skl_tplg_pga_event}, 1213 {SKL_PGA_EVENT, skl_tplg_pga_event},
1031}; 1214};
1032 1215
1216static const struct snd_soc_tplg_bytes_ext_ops skl_tlv_ops[] = {
1217 {SKL_CONTROL_TYPE_BYTE_TLV, skl_tplg_tlv_control_get,
1218 skl_tplg_tlv_control_set},
1219};
1220
1033/* 1221/*
1034 * The topology binary passes the pin info for a module so initialize the pin 1222 * The topology binary passes the pin info for a module so initialize the pin
1035 * info passed into module instance 1223 * info passed into module instance
@@ -1045,6 +1233,7 @@ static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1045 m_pin[i].id.instance_id = dfw_pin[i].instance_id; 1233 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
1046 m_pin[i].in_use = false; 1234 m_pin[i].in_use = false;
1047 m_pin[i].is_dynamic = is_dynamic; 1235 m_pin[i].is_dynamic = is_dynamic;
1236 m_pin[i].pin_state = SKL_PIN_UNBIND;
1048 } 1237 }
1049} 1238}
1050 1239
@@ -1092,6 +1281,24 @@ static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
1092 return ppl->pipe; 1281 return ppl->pipe;
1093} 1282}
1094 1283
1284static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
1285 struct skl_dfw_module_fmt *src_fmt,
1286 int pins)
1287{
1288 int i;
1289
1290 for (i = 0; i < pins; i++) {
1291 dst_fmt[i].channels = src_fmt[i].channels;
1292 dst_fmt[i].s_freq = src_fmt[i].freq;
1293 dst_fmt[i].bit_depth = src_fmt[i].bit_depth;
1294 dst_fmt[i].valid_bit_depth = src_fmt[i].valid_bit_depth;
1295 dst_fmt[i].ch_cfg = src_fmt[i].ch_cfg;
1296 dst_fmt[i].ch_map = src_fmt[i].ch_map;
1297 dst_fmt[i].interleaving_style = src_fmt[i].interleaving_style;
1298 dst_fmt[i].sample_type = src_fmt[i].sample_type;
1299 }
1300}
1301
1095/* 1302/*
1096 * Topology core widget load callback 1303 * Topology core widget load callback
1097 * 1304 *
@@ -1130,22 +1337,16 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1130 mconfig->max_in_queue = dfw_config->max_in_queue; 1337 mconfig->max_in_queue = dfw_config->max_in_queue;
1131 mconfig->max_out_queue = dfw_config->max_out_queue; 1338 mconfig->max_out_queue = dfw_config->max_out_queue;
1132 mconfig->is_loadable = dfw_config->is_loadable; 1339 mconfig->is_loadable = dfw_config->is_loadable;
1133 mconfig->in_fmt.channels = dfw_config->in_fmt.channels; 1340 skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
1134 mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq; 1341 MODULE_MAX_IN_PINS);
1135 mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth; 1342 skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
1136 mconfig->in_fmt.valid_bit_depth = 1343 MODULE_MAX_OUT_PINS);
1137 dfw_config->in_fmt.valid_bit_depth; 1344
1138 mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg;
1139 mconfig->out_fmt.channels = dfw_config->out_fmt.channels;
1140 mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq;
1141 mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth;
1142 mconfig->out_fmt.valid_bit_depth =
1143 dfw_config->out_fmt.valid_bit_depth;
1144 mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg;
1145 mconfig->params_fixup = dfw_config->params_fixup; 1345 mconfig->params_fixup = dfw_config->params_fixup;
1146 mconfig->converter = dfw_config->converter; 1346 mconfig->converter = dfw_config->converter;
1147 mconfig->m_type = dfw_config->module_type; 1347 mconfig->m_type = dfw_config->module_type;
1148 mconfig->vbus_id = dfw_config->vbus_id; 1348 mconfig->vbus_id = dfw_config->vbus_id;
1349 mconfig->mem_pages = dfw_config->mem_pages;
1149 1350
1150 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe); 1351 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1151 if (pipe) 1352 if (pipe)
@@ -1156,10 +1357,13 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1156 mconfig->time_slot = dfw_config->time_slot; 1357 mconfig->time_slot = dfw_config->time_slot;
1157 mconfig->formats_config.caps_size = dfw_config->caps.caps_size; 1358 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1158 1359
1159 mconfig->m_in_pin = devm_kzalloc(bus->dev, 1360 if (dfw_config->is_loadable)
1160 (mconfig->max_in_queue) * 1361 memcpy(mconfig->guid, dfw_config->uuid,
1161 sizeof(*mconfig->m_in_pin), 1362 ARRAY_SIZE(dfw_config->uuid));
1162 GFP_KERNEL); 1363
1364 mconfig->m_in_pin = devm_kzalloc(bus->dev, (mconfig->max_in_queue) *
1365 sizeof(*mconfig->m_in_pin),
1366 GFP_KERNEL);
1163 if (!mconfig->m_in_pin) 1367 if (!mconfig->m_in_pin)
1164 return -ENOMEM; 1368 return -ENOMEM;
1165 1369
@@ -1188,7 +1392,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1188 return -ENOMEM; 1392 return -ENOMEM;
1189 1393
1190 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps, 1394 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1191 dfw_config->caps.caps_size); 1395 dfw_config->caps.caps_size);
1396 mconfig->formats_config.param_id = dfw_config->caps.param_id;
1397 mconfig->formats_config.set_params = dfw_config->caps.set_params;
1192 1398
1193bind_event: 1399bind_event:
1194 if (tplg_w->event_type == 0) { 1400 if (tplg_w->event_type == 0) {
@@ -1209,8 +1415,70 @@ bind_event:
1209 return 0; 1415 return 0;
1210} 1416}
1211 1417
1418static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be,
1419 struct snd_soc_tplg_bytes_control *bc)
1420{
1421 struct skl_algo_data *ac;
1422 struct skl_dfw_algo_data *dfw_ac =
1423 (struct skl_dfw_algo_data *)bc->priv.data;
1424
1425 ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
1426 if (!ac)
1427 return -ENOMEM;
1428
1429 /* Fill private data */
1430 ac->max = dfw_ac->max;
1431 ac->param_id = dfw_ac->param_id;
1432 ac->set_params = dfw_ac->set_params;
1433
1434 if (ac->max) {
1435 ac->params = (char *) devm_kzalloc(dev, ac->max, GFP_KERNEL);
1436 if (!ac->params)
1437 return -ENOMEM;
1438
1439 if (dfw_ac->params)
1440 memcpy(ac->params, dfw_ac->params, ac->max);
1441 }
1442
1443 be->dobj.private = ac;
1444 return 0;
1445}
1446
1447static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
1448 struct snd_kcontrol_new *kctl,
1449 struct snd_soc_tplg_ctl_hdr *hdr)
1450{
1451 struct soc_bytes_ext *sb;
1452 struct snd_soc_tplg_bytes_control *tplg_bc;
1453 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1454 struct hdac_bus *bus = ebus_to_hbus(ebus);
1455
1456 switch (hdr->ops.info) {
1457 case SND_SOC_TPLG_CTL_BYTES:
1458 tplg_bc = container_of(hdr,
1459 struct snd_soc_tplg_bytes_control, hdr);
1460 if (kctl->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1461 sb = (struct soc_bytes_ext *)kctl->private_value;
1462 if (tplg_bc->priv.size)
1463 return skl_init_algo_data(
1464 bus->dev, sb, tplg_bc);
1465 }
1466 break;
1467
1468 default:
1469 dev_warn(bus->dev, "Control load not supported %d:%d:%d\n",
1470 hdr->ops.get, hdr->ops.put, hdr->ops.info);
1471 break;
1472 }
1473
1474 return 0;
1475}
1476
1212static struct snd_soc_tplg_ops skl_tplg_ops = { 1477static struct snd_soc_tplg_ops skl_tplg_ops = {
1213 .widget_load = skl_tplg_widget_load, 1478 .widget_load = skl_tplg_widget_load,
1479 .control_load = skl_tplg_control_load,
1480 .bytes_ext_ops = skl_tlv_ops,
1481 .bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
1214}; 1482};
1215 1483
1216/* This will be read from topology manifest, currently defined here */ 1484/* This will be read from topology manifest, currently defined here */
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 76053a8de41c..9aa2a2b6598a 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -36,6 +36,9 @@
36/* Maximum number of coefficients up down mixer module */ 36/* Maximum number of coefficients up down mixer module */
37#define UP_DOWN_MIXER_MAX_COEFF 6 37#define UP_DOWN_MIXER_MAX_COEFF 6
38 38
39#define MODULE_MAX_IN_PINS 8
40#define MODULE_MAX_OUT_PINS 8
41
39enum skl_channel_index { 42enum skl_channel_index {
40 SKL_CHANNEL_LEFT = 0, 43 SKL_CHANNEL_LEFT = 0,
41 SKL_CHANNEL_RIGHT = 1, 44 SKL_CHANNEL_RIGHT = 1,
@@ -55,12 +58,6 @@ enum skl_bitdepth {
55 SKL_DEPTH_INVALID 58 SKL_DEPTH_INVALID
56}; 59};
57 60
58enum skl_interleaving {
59 /* [s1_ch1...s1_chN,...,sM_ch1...sM_chN] */
60 SKL_INTERLEAVING_PER_CHANNEL = 0,
61 /* [s1_ch1...sM_ch1,...,s1_chN...sM_chN] */
62 SKL_INTERLEAVING_PER_SAMPLE = 1,
63};
64 61
65enum skl_s_freq { 62enum skl_s_freq {
66 SKL_FS_8000 = 8000, 63 SKL_FS_8000 = 8000,
@@ -143,6 +140,16 @@ struct skl_up_down_mixer_cfg {
143 s32 coeff[UP_DOWN_MIXER_MAX_COEFF]; 140 s32 coeff[UP_DOWN_MIXER_MAX_COEFF];
144} __packed; 141} __packed;
145 142
143struct skl_algo_cfg {
144 struct skl_base_cfg base_cfg;
145 char params[0];
146} __packed;
147
148struct skl_base_outfmt_cfg {
149 struct skl_base_cfg base_cfg;
150 struct skl_audio_data_format out_fmt;
151} __packed;
152
146enum skl_dma_type { 153enum skl_dma_type {
147 SKL_DMA_HDA_HOST_OUTPUT_CLASS = 0, 154 SKL_DMA_HDA_HOST_OUTPUT_CLASS = 0,
148 SKL_DMA_HDA_HOST_INPUT_CLASS = 1, 155 SKL_DMA_HDA_HOST_INPUT_CLASS = 1,
@@ -178,21 +185,34 @@ struct skl_module_fmt {
178 u32 bit_depth; 185 u32 bit_depth;
179 u32 valid_bit_depth; 186 u32 valid_bit_depth;
180 u32 ch_cfg; 187 u32 ch_cfg;
188 u32 interleaving_style;
189 u32 sample_type;
190 u32 ch_map;
181}; 191};
182 192
193struct skl_module_cfg;
194
183struct skl_module_inst_id { 195struct skl_module_inst_id {
184 u32 module_id; 196 u32 module_id;
185 u32 instance_id; 197 u32 instance_id;
186}; 198};
187 199
200enum skl_module_pin_state {
201 SKL_PIN_UNBIND = 0,
202 SKL_PIN_BIND_DONE = 1,
203};
204
188struct skl_module_pin { 205struct skl_module_pin {
189 struct skl_module_inst_id id; 206 struct skl_module_inst_id id;
190 u8 pin_index;
191 bool is_dynamic; 207 bool is_dynamic;
192 bool in_use; 208 bool in_use;
209 enum skl_module_pin_state pin_state;
210 struct skl_module_cfg *tgt_mcfg;
193}; 211};
194 212
195struct skl_specific_cfg { 213struct skl_specific_cfg {
214 u32 set_params;
215 u32 param_id;
196 u32 caps_size; 216 u32 caps_size;
197 u32 *caps; 217 u32 *caps;
198}; 218};
@@ -238,9 +258,13 @@ enum skl_module_state {
238}; 258};
239 259
240struct skl_module_cfg { 260struct skl_module_cfg {
261 char guid[SKL_UUID_STR_SZ];
241 struct skl_module_inst_id id; 262 struct skl_module_inst_id id;
242 struct skl_module_fmt in_fmt; 263 u8 domain;
243 struct skl_module_fmt out_fmt; 264 bool homogenous_inputs;
265 bool homogenous_outputs;
266 struct skl_module_fmt in_fmt[MODULE_MAX_IN_PINS];
267 struct skl_module_fmt out_fmt[MODULE_MAX_OUT_PINS];
244 u8 max_in_queue; 268 u8 max_in_queue;
245 u8 max_out_queue; 269 u8 max_out_queue;
246 u8 in_queue_mask; 270 u8 in_queue_mask;
@@ -258,6 +282,7 @@ struct skl_module_cfg {
258 u32 params_fixup; 282 u32 params_fixup;
259 u32 converter; 283 u32 converter;
260 u32 vbus_id; 284 u32 vbus_id;
285 u32 mem_pages;
261 struct skl_module_pin *m_in_pin; 286 struct skl_module_pin *m_in_pin;
262 struct skl_module_pin *m_out_pin; 287 struct skl_module_pin *m_out_pin;
263 enum skl_module_type m_type; 288 enum skl_module_type m_type;
@@ -267,13 +292,15 @@ struct skl_module_cfg {
267 struct skl_specific_cfg formats_config; 292 struct skl_specific_cfg formats_config;
268}; 293};
269 294
270struct skl_pipeline { 295struct skl_algo_data {
271 struct skl_pipe *pipe; 296 u32 param_id;
272 struct list_head node; 297 u32 set_params;
298 u32 max;
299 char *params;
273}; 300};
274 301
275struct skl_dapm_path_list { 302struct skl_pipeline {
276 struct snd_soc_dapm_path *dapm_path; 303 struct skl_pipe *pipe;
277 struct list_head node; 304 struct list_head node;
278}; 305};
279 306
@@ -305,8 +332,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
305 332
306int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 333int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
307 334
308int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config, 335int skl_init_module(struct skl_sst *ctx, struct skl_module_cfg *module_config);
309 char *param);
310 336
311int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg 337int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
312 *src_module, struct skl_module_cfg *dst_module); 338 *src_module, struct skl_module_cfg *dst_module);
@@ -314,5 +340,10 @@ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg
314int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg 340int skl_unbind_modules(struct skl_sst *ctx, struct skl_module_cfg
315 *src_module, struct skl_module_cfg *dst_module); 341 *src_module, struct skl_module_cfg *dst_module);
316 342
343int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size,
344 u32 param_id, struct skl_module_cfg *mcfg);
345int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
346 u32 param_id, struct skl_module_cfg *mcfg);
347
317enum skl_bitdepth skl_get_bit_depth(int params); 348enum skl_bitdepth skl_get_bit_depth(int params);
318#endif 349#endif
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index 2bc396d54cbe..c9ae010b3cc8 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -23,15 +23,13 @@
23 * Default types range from 0~12. type can range from 0 to 0xff 23 * Default types range from 0~12. type can range from 0 to 0xff
24 * SST types start at higher to avoid any overlapping in future 24 * SST types start at higher to avoid any overlapping in future
25 */ 25 */
26#define SOC_CONTROL_TYPE_HDA_SST_ALGO_PARAMS 0x100 26#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
27#define SOC_CONTROL_TYPE_HDA_SST_MUX 0x101
28#define SOC_CONTROL_TYPE_HDA_SST_MIX 0x101
29#define SOC_CONTROL_TYPE_HDA_SST_BYTE 0x103
30 27
31#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/ 28#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
32#define MAX_IN_QUEUE 8 29#define MAX_IN_QUEUE 8
33#define MAX_OUT_QUEUE 8 30#define MAX_OUT_QUEUE 8
34 31
32#define SKL_UUID_STR_SZ 40
35/* Event types goes here */ 33/* Event types goes here */
36/* Reserve event type 0 for no event handlers */ 34/* Reserve event type 0 for no event handlers */
37enum skl_event_types { 35enum skl_event_types {
@@ -72,6 +70,7 @@ enum skl_ch_cfg {
72 SKL_CH_CFG_DUAL_MONO = 9, 70 SKL_CH_CFG_DUAL_MONO = 9,
73 SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10, 71 SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
74 SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11, 72 SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
73 SKL_CH_CFG_4_CHANNEL = 12,
75 SKL_CH_CFG_INVALID 74 SKL_CH_CFG_INVALID
76}; 75};
77 76
@@ -79,7 +78,9 @@ enum skl_module_type {
79 SKL_MODULE_TYPE_MIXER = 0, 78 SKL_MODULE_TYPE_MIXER = 0,
80 SKL_MODULE_TYPE_COPIER, 79 SKL_MODULE_TYPE_COPIER,
81 SKL_MODULE_TYPE_UPDWMIX, 80 SKL_MODULE_TYPE_UPDWMIX,
82 SKL_MODULE_TYPE_SRCINT 81 SKL_MODULE_TYPE_SRCINT,
82 SKL_MODULE_TYPE_ALGO,
83 SKL_MODULE_TYPE_BASE_OUTFMT
83}; 84};
84 85
85enum skl_core_affinity { 86enum skl_core_affinity {
@@ -110,6 +111,42 @@ enum skl_dev_type {
110 SKL_DEVICE_NONE 111 SKL_DEVICE_NONE
111}; 112};
112 113
114/**
115 * enum skl_interleaving - interleaving style
116 *
117 * @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN]
118 * @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN]
119 */
120enum skl_interleaving {
121 SKL_INTERLEAVING_PER_CHANNEL = 0,
122 SKL_INTERLEAVING_PER_SAMPLE = 1,
123};
124
125enum skl_sample_type {
126 SKL_SAMPLE_TYPE_INT_MSB = 0,
127 SKL_SAMPLE_TYPE_INT_LSB = 1,
128 SKL_SAMPLE_TYPE_INT_SIGNED = 2,
129 SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
130 SKL_SAMPLE_TYPE_FLOAT = 4
131};
132
133enum module_pin_type {
134 /* All pins of the module takes same PCM inputs or outputs
135 * e.g. mixout
136 */
137 SKL_PIN_TYPE_HOMOGENEOUS,
138 /* All pins of the module takes different PCM inputs or outputs
139 * e.g mux
140 */
141 SKL_PIN_TYPE_HETEROGENEOUS,
142};
143
144enum skl_module_param_type {
145 SKL_PARAM_DEFAULT = 0,
146 SKL_PARAM_INIT,
147 SKL_PARAM_SET
148};
149
113struct skl_dfw_module_pin { 150struct skl_dfw_module_pin {
114 u16 module_id; 151 u16 module_id;
115 u16 instance_id; 152 u16 instance_id;
@@ -121,9 +158,15 @@ struct skl_dfw_module_fmt {
121 u32 bit_depth; 158 u32 bit_depth;
122 u32 valid_bit_depth; 159 u32 valid_bit_depth;
123 u32 ch_cfg; 160 u32 ch_cfg;
161 u32 interleaving_style;
162 u32 sample_type;
163 u32 ch_map;
124} __packed; 164} __packed;
125 165
126struct skl_dfw_module_caps { 166struct skl_dfw_module_caps {
167 u32 set_params:2;
168 u32 rsvd:30;
169 u32 param_id;
127 u32 caps_size; 170 u32 caps_size;
128 u32 caps[HDA_SST_CFG_MAX]; 171 u32 caps[HDA_SST_CFG_MAX];
129}; 172};
@@ -131,41 +174,57 @@ struct skl_dfw_module_caps {
131struct skl_dfw_pipe { 174struct skl_dfw_pipe {
132 u8 pipe_id; 175 u8 pipe_id;
133 u8 pipe_priority; 176 u8 pipe_priority;
134 u16 conn_type; 177 u16 conn_type:4;
135 u32 memory_pages; 178 u16 rsvd:4;
179 u16 memory_pages:8;
136} __packed; 180} __packed;
137 181
138struct skl_dfw_module { 182struct skl_dfw_module {
183 char uuid[SKL_UUID_STR_SZ];
184
139 u16 module_id; 185 u16 module_id;
140 u16 instance_id; 186 u16 instance_id;
141 u32 max_mcps; 187 u32 max_mcps;
142 u8 core_id; 188 u32 mem_pages;
143 u8 max_in_queue;
144 u8 max_out_queue;
145 u8 is_loadable;
146 u8 conn_type;
147 u8 dev_type;
148 u8 hw_conn_type;
149 u8 time_slot;
150 u32 obs; 189 u32 obs;
151 u32 ibs; 190 u32 ibs;
152 u32 params_fixup;
153 u32 converter;
154 u32 module_type;
155 u32 vbus_id; 191 u32 vbus_id;
156 u8 is_dynamic_in_pin; 192
157 u8 is_dynamic_out_pin; 193 u32 max_in_queue:8;
194 u32 max_out_queue:8;
195 u32 time_slot:8;
196 u32 core_id:4;
197 u32 rsvd1:4;
198
199 u32 module_type:8;
200 u32 conn_type:4;
201 u32 dev_type:4;
202 u32 hw_conn_type:4;
203 u32 rsvd2:12;
204
205 u32 params_fixup:8;
206 u32 converter:8;
207 u32 input_pin_type:1;
208 u32 output_pin_type:1;
209 u32 is_dynamic_in_pin:1;
210 u32 is_dynamic_out_pin:1;
211 u32 is_loadable:1;
212 u32 rsvd3:11;
213
158 struct skl_dfw_pipe pipe; 214 struct skl_dfw_pipe pipe;
159 struct skl_dfw_module_fmt in_fmt; 215 struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
160 struct skl_dfw_module_fmt out_fmt; 216 struct skl_dfw_module_fmt out_fmt[MAX_OUT_QUEUE];
161 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE]; 217 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
162 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE]; 218 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
163 struct skl_dfw_module_caps caps; 219 struct skl_dfw_module_caps caps;
164} __packed; 220} __packed;
165 221
166struct skl_dfw_algo_data { 222struct skl_dfw_algo_data {
223 u32 set_params:2;
224 u32 rsvd:30;
225 u32 param_id;
167 u32 max; 226 u32 max;
168 char *params; 227 char params[0];
169} __packed; 228} __packed;
170 229
171#endif 230#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 5319529aedf7..c38bf99ced10 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -26,6 +26,7 @@
26#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include "../common/sst-acpi.h"
29#include "skl.h" 30#include "skl.h"
30 31
31/* 32/*
@@ -129,6 +130,37 @@ static int skl_acquire_irq(struct hdac_ext_bus *ebus, int do_disconnect)
129 return 0; 130 return 0;
130} 131}
131 132
133#ifdef CONFIG_PM
134static int _skl_suspend(struct hdac_ext_bus *ebus)
135{
136 struct skl *skl = ebus_to_skl(ebus);
137 struct hdac_bus *bus = ebus_to_hbus(ebus);
138 int ret;
139
140 snd_hdac_ext_bus_link_power_down_all(ebus);
141
142 ret = skl_suspend_dsp(skl);
143 if (ret < 0)
144 return ret;
145
146 snd_hdac_bus_stop_chip(bus);
147 snd_hdac_bus_enter_link_reset(bus);
148
149 return 0;
150}
151
152static int _skl_resume(struct hdac_ext_bus *ebus)
153{
154 struct skl *skl = ebus_to_skl(ebus);
155 struct hdac_bus *bus = ebus_to_hbus(ebus);
156
157 skl_init_pci(skl);
158 snd_hdac_bus_init_chip(bus, true);
159
160 return skl_resume_dsp(skl);
161}
162#endif
163
132#ifdef CONFIG_PM_SLEEP 164#ifdef CONFIG_PM_SLEEP
133/* 165/*
134 * power management 166 * power management
@@ -137,26 +169,40 @@ static int skl_suspend(struct device *dev)
137{ 169{
138 struct pci_dev *pci = to_pci_dev(dev); 170 struct pci_dev *pci = to_pci_dev(dev);
139 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 171 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
140 struct hdac_bus *bus = ebus_to_hbus(ebus); 172 struct skl *skl = ebus_to_skl(ebus);
141
142 snd_hdac_bus_stop_chip(bus);
143 snd_hdac_bus_enter_link_reset(bus);
144 173
145 return 0; 174 /*
175 * Do not suspend if streams which are marked ignore suspend are
176 * running, we need to save the state for these and continue
177 */
178 if (skl->supend_active) {
179 pci_save_state(pci);
180 pci_disable_device(pci);
181 return 0;
182 } else {
183 return _skl_suspend(ebus);
184 }
146} 185}
147 186
148static int skl_resume(struct device *dev) 187static int skl_resume(struct device *dev)
149{ 188{
150 struct pci_dev *pci = to_pci_dev(dev); 189 struct pci_dev *pci = to_pci_dev(dev);
151 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 190 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
152 struct hdac_bus *bus = ebus_to_hbus(ebus); 191 struct skl *skl = ebus_to_skl(ebus);
153 struct skl *hda = ebus_to_skl(ebus); 192 int ret;
154
155 skl_init_pci(hda);
156 193
157 snd_hdac_bus_init_chip(bus, 1); 194 /*
195 * resume only when we are not in suspend active, otherwise need to
196 * restore the device
197 */
198 if (skl->supend_active) {
199 pci_restore_state(pci);
200 ret = pci_enable_device(pci);
201 } else {
202 ret = _skl_resume(ebus);
203 }
158 204
159 return 0; 205 return ret;
160} 206}
161#endif /* CONFIG_PM_SLEEP */ 207#endif /* CONFIG_PM_SLEEP */
162 208
@@ -166,24 +212,10 @@ static int skl_runtime_suspend(struct device *dev)
166 struct pci_dev *pci = to_pci_dev(dev); 212 struct pci_dev *pci = to_pci_dev(dev);
167 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 213 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
168 struct hdac_bus *bus = ebus_to_hbus(ebus); 214 struct hdac_bus *bus = ebus_to_hbus(ebus);
169 struct skl *skl = ebus_to_skl(ebus);
170 int ret;
171 215
172 dev_dbg(bus->dev, "in %s\n", __func__); 216 dev_dbg(bus->dev, "in %s\n", __func__);
173 217
174 /* enable controller wake up event */ 218 return _skl_suspend(ebus);
175 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
176
177 snd_hdac_ext_bus_link_power_down_all(ebus);
178
179 ret = skl_suspend_dsp(skl);
180 if (ret < 0)
181 return ret;
182
183 snd_hdac_bus_stop_chip(bus);
184 snd_hdac_bus_enter_link_reset(bus);
185
186 return 0;
187} 219}
188 220
189static int skl_runtime_resume(struct device *dev) 221static int skl_runtime_resume(struct device *dev)
@@ -191,20 +223,10 @@ static int skl_runtime_resume(struct device *dev)
191 struct pci_dev *pci = to_pci_dev(dev); 223 struct pci_dev *pci = to_pci_dev(dev);
192 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 224 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
193 struct hdac_bus *bus = ebus_to_hbus(ebus); 225 struct hdac_bus *bus = ebus_to_hbus(ebus);
194 struct skl *skl = ebus_to_skl(ebus);
195 int status;
196 226
197 dev_dbg(bus->dev, "in %s\n", __func__); 227 dev_dbg(bus->dev, "in %s\n", __func__);
198 228
199 /* Read STATESTS before controller reset */ 229 return _skl_resume(ebus);
200 status = snd_hdac_chip_readw(bus, STATESTS);
201
202 skl_init_pci(skl);
203 snd_hdac_bus_init_chip(bus, true);
204 /* disable controller Wake Up event */
205 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
206
207 return skl_resume_dsp(skl);
208} 230}
209#endif /* CONFIG_PM */ 231#endif /* CONFIG_PM */
210 232
@@ -241,6 +263,43 @@ static int skl_free(struct hdac_ext_bus *ebus)
241 return 0; 263 return 0;
242} 264}
243 265
266static int skl_machine_device_register(struct skl *skl, void *driver_data)
267{
268 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
269 struct platform_device *pdev;
270 struct sst_acpi_mach *mach = driver_data;
271 int ret;
272
273 mach = sst_acpi_find_machine(mach);
274 if (mach == NULL) {
275 dev_err(bus->dev, "No matching machine driver found\n");
276 return -ENODEV;
277 }
278 skl->fw_name = mach->fw_filename;
279
280 pdev = platform_device_alloc(mach->drv_name, -1);
281 if (pdev == NULL) {
282 dev_err(bus->dev, "platform device alloc failed\n");
283 return -EIO;
284 }
285
286 ret = platform_device_add(pdev);
287 if (ret) {
288 dev_err(bus->dev, "failed to add machine device\n");
289 platform_device_put(pdev);
290 return -EIO;
291 }
292 skl->i2s_dev = pdev;
293
294 return 0;
295}
296
297static void skl_machine_device_unregister(struct skl *skl)
298{
299 if (skl->i2s_dev)
300 platform_device_unregister(skl->i2s_dev);
301}
302
244static int skl_dmic_device_register(struct skl *skl) 303static int skl_dmic_device_register(struct skl *skl)
245{ 304{
246 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); 305 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
@@ -434,8 +493,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
434 493
435 /* codec detection */ 494 /* codec detection */
436 if (!bus->codec_mask) { 495 if (!bus->codec_mask) {
437 dev_err(bus->dev, "no codecs found!\n"); 496 dev_info(bus->dev, "no hda codecs found!\n");
438 return -ENODEV;
439 } 497 }
440 498
441 return 0; 499 return 0;
@@ -470,10 +528,15 @@ static int skl_probe(struct pci_dev *pci,
470 528
471 /* check if dsp is there */ 529 /* check if dsp is there */
472 if (ebus->ppcap) { 530 if (ebus->ppcap) {
531 err = skl_machine_device_register(skl,
532 (void *)pci_id->driver_data);
533 if (err < 0)
534 goto out_free;
535
473 err = skl_init_dsp(skl); 536 err = skl_init_dsp(skl);
474 if (err < 0) { 537 if (err < 0) {
475 dev_dbg(bus->dev, "error failed to register dsp\n"); 538 dev_dbg(bus->dev, "error failed to register dsp\n");
476 goto out_free; 539 goto out_mach_free;
477 } 540 }
478 } 541 }
479 if (ebus->mlcap) 542 if (ebus->mlcap)
@@ -508,6 +571,8 @@ out_dmic_free:
508 skl_dmic_device_unregister(skl); 571 skl_dmic_device_unregister(skl);
509out_dsp_free: 572out_dsp_free:
510 skl_free_dsp(skl); 573 skl_free_dsp(skl);
574out_mach_free:
575 skl_machine_device_unregister(skl);
511out_free: 576out_free:
512 skl->init_failed = 1; 577 skl->init_failed = 1;
513 skl_free(ebus); 578 skl_free(ebus);
@@ -525,15 +590,26 @@ static void skl_remove(struct pci_dev *pci)
525 pci_dev_put(pci); 590 pci_dev_put(pci);
526 skl_platform_unregister(&pci->dev); 591 skl_platform_unregister(&pci->dev);
527 skl_free_dsp(skl); 592 skl_free_dsp(skl);
593 skl_machine_device_unregister(skl);
528 skl_dmic_device_unregister(skl); 594 skl_dmic_device_unregister(skl);
529 skl_free(ebus); 595 skl_free(ebus);
530 dev_set_drvdata(&pci->dev, NULL); 596 dev_set_drvdata(&pci->dev, NULL);
531} 597}
532 598
599static struct sst_acpi_mach sst_skl_devdata[] = {
600 { "INT343A", "skl_alc286s_i2s", "intel/dsp_fw_release.bin", NULL, NULL, NULL },
601 { "INT343B", "skl_nau88l25_ssm4567_i2s", "intel/dsp_fw_release.bin",
602 NULL, NULL, NULL },
603 { "MX98357A", "skl_nau88l25_max98357a_i2s", "intel/dsp_fw_release.bin",
604 NULL, NULL, NULL },
605 {}
606};
607
533/* PCI IDs */ 608/* PCI IDs */
534static const struct pci_device_id skl_ids[] = { 609static const struct pci_device_id skl_ids[] = {
535 /* Sunrise Point-LP */ 610 /* Sunrise Point-LP */
536 { PCI_DEVICE(0x8086, 0x9d70), 0}, 611 { PCI_DEVICE(0x8086, 0x9d70),
612 .driver_data = (unsigned long)&sst_skl_devdata},
537 { 0, } 613 { 0, }
538}; 614};
539MODULE_DEVICE_TABLE(pci, skl_ids); 615MODULE_DEVICE_TABLE(pci, skl_ids);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index dd2e79ae45a8..3d167eed0f59 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -61,13 +61,17 @@ struct skl {
61 61
62 unsigned int init_failed:1; /* delayed init failed */ 62 unsigned int init_failed:1; /* delayed init failed */
63 struct platform_device *dmic_dev; 63 struct platform_device *dmic_dev;
64 struct platform_device *i2s_dev;
64 65
65 void *nhlt; /* nhlt ptr */ 66 void *nhlt; /* nhlt ptr */
66 struct skl_sst *skl_sst; /* sst skl ctx */ 67 struct skl_sst *skl_sst; /* sst skl ctx */
67 68
68 struct skl_dsp_resource resource; 69 struct skl_dsp_resource resource;
69 struct list_head ppl_list; 70 struct list_head ppl_list;
70 struct list_head dapm_path_list; 71
72 const char *fw_name;
73
74 int supend_active;
71}; 75};
72 76
73#define skl_to_ebus(s) (&(s)->ebus) 77#define skl_to_ebus(s) (&(s)->ebus)
diff --git a/sound/soc/mediatek/mtk-afe-common.h b/sound/soc/mediatek/mtk-afe-common.h
index cc4393cb1130..9b1af1a70874 100644
--- a/sound/soc/mediatek/mtk-afe-common.h
+++ b/sound/soc/mediatek/mtk-afe-common.h
@@ -92,7 +92,6 @@ struct mtk_afe_memif_data {
92struct mtk_afe_memif { 92struct mtk_afe_memif {
93 unsigned int phys_buf_addr; 93 unsigned int phys_buf_addr;
94 int buffer_size; 94 int buffer_size;
95 unsigned int hw_ptr; /* Previous IRQ's HW ptr */
96 struct snd_pcm_substream *substream; 95 struct snd_pcm_substream *substream;
97 const struct mtk_afe_memif_data *data; 96 const struct mtk_afe_memif_data *data;
98 const struct mtk_afe_irq_data *irqdata; 97 const struct mtk_afe_irq_data *irqdata;
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index f5baf3c38863..08af9f5dc4ab 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -175,8 +175,17 @@ static snd_pcm_uframes_t mtk_afe_pcm_pointer
175 struct snd_soc_pcm_runtime *rtd = substream->private_data; 175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 176 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
177 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; 177 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
178 unsigned int hw_ptr;
179 int ret;
180
181 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur, &hw_ptr);
182 if (ret || hw_ptr == 0) {
183 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
184 hw_ptr = memif->phys_buf_addr;
185 }
178 186
179 return bytes_to_frames(substream->runtime, memif->hw_ptr); 187 return bytes_to_frames(substream->runtime,
188 hw_ptr - memif->phys_buf_addr);
180} 189}
181 190
182static const struct snd_pcm_ops mtk_afe_pcm_ops = { 191static const struct snd_pcm_ops mtk_afe_pcm_ops = {
@@ -299,8 +308,6 @@ static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
299 dev_err(afe->dev, "Failed to enable m_ck\n"); 308 dev_err(afe->dev, "Failed to enable m_ck\n");
300 return ret; 309 return ret;
301 } 310 }
302 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
303 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
304 } 311 }
305 312
306 if (b_ck) { 313 if (b_ck) {
@@ -340,12 +347,8 @@ static int mtk_afe_dais_set_clks(struct mtk_afe *afe,
340static void mtk_afe_dais_disable_clks(struct mtk_afe *afe, 347static void mtk_afe_dais_disable_clks(struct mtk_afe *afe,
341 struct clk *m_ck, struct clk *b_ck) 348 struct clk *m_ck, struct clk *b_ck)
342{ 349{
343 if (m_ck) { 350 if (m_ck)
344 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
345 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
346 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
347 clk_disable_unprepare(m_ck); 351 clk_disable_unprepare(m_ck);
348 }
349 if (b_ck) 352 if (b_ck)
350 clk_disable_unprepare(b_ck); 353 clk_disable_unprepare(b_ck);
351} 354}
@@ -360,6 +363,8 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream,
360 return 0; 363 return 0;
361 364
362 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 365 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
366 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
367 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
363 return 0; 368 return 0;
364} 369}
365 370
@@ -373,10 +378,10 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream,
373 return; 378 return;
374 379
375 mtk_afe_set_i2s_enable(afe, false); 380 mtk_afe_set_i2s_enable(afe, false);
381 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
383 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
376 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL); 384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
377
378 /* disable AFE */
379 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
380} 385}
381 386
382static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, 387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
@@ -425,9 +430,6 @@ static void mtk_afe_hdmi_shutdown(struct snd_pcm_substream *substream,
425 430
426 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M], 431 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S3_M],
427 afe->clocks[MTK_CLK_I2S3_B]); 432 afe->clocks[MTK_CLK_I2S3_B]);
428
429 /* disable AFE */
430 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
431} 433}
432 434
433static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream, 435static int mtk_afe_hdmi_prepare(struct snd_pcm_substream *substream,
@@ -603,7 +605,6 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream,
603 605
604 memif->phys_buf_addr = substream->runtime->dma_addr; 606 memif->phys_buf_addr = substream->runtime->dma_addr;
605 memif->buffer_size = substream->runtime->dma_bytes; 607 memif->buffer_size = substream->runtime->dma_bytes;
606 memif->hw_ptr = 0;
607 608
608 /* start */ 609 /* start */
609 regmap_write(afe->regmap, 610 regmap_write(afe->regmap,
@@ -672,17 +673,6 @@ static int mtk_afe_dais_hw_free(struct snd_pcm_substream *substream,
672 return snd_pcm_lib_free_pages(substream); 673 return snd_pcm_lib_free_pages(substream);
673} 674}
674 675
675static int mtk_afe_dais_prepare(struct snd_pcm_substream *substream,
676 struct snd_soc_dai *dai)
677{
678 struct snd_soc_pcm_runtime *rtd = substream->private_data;
679 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
680
681 /* enable AFE */
682 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
683 return 0;
684}
685
686static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd, 676static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
687 struct snd_soc_dai *dai) 677 struct snd_soc_dai *dai)
688{ 678{
@@ -738,7 +728,6 @@ static int mtk_afe_dais_trigger(struct snd_pcm_substream *substream, int cmd,
738 /* and clear pending IRQ */ 728 /* and clear pending IRQ */
739 regmap_write(afe->regmap, AFE_IRQ_CLR, 729 regmap_write(afe->regmap, AFE_IRQ_CLR,
740 1 << memif->data->irq_clr_shift); 730 1 << memif->data->irq_clr_shift);
741 memif->hw_ptr = 0;
742 return 0; 731 return 0;
743 default: 732 default:
744 return -EINVAL; 733 return -EINVAL;
@@ -751,7 +740,6 @@ static const struct snd_soc_dai_ops mtk_afe_dai_ops = {
751 .shutdown = mtk_afe_dais_shutdown, 740 .shutdown = mtk_afe_dais_shutdown,
752 .hw_params = mtk_afe_dais_hw_params, 741 .hw_params = mtk_afe_dais_hw_params,
753 .hw_free = mtk_afe_dais_hw_free, 742 .hw_free = mtk_afe_dais_hw_free,
754 .prepare = mtk_afe_dais_prepare,
755 .trigger = mtk_afe_dais_trigger, 743 .trigger = mtk_afe_dais_trigger,
756}; 744};
757 745
@@ -1082,7 +1070,7 @@ static const struct regmap_config mtk_afe_regmap_config = {
1082static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id) 1070static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1083{ 1071{
1084 struct mtk_afe *afe = dev_id; 1072 struct mtk_afe *afe = dev_id;
1085 unsigned int reg_value, hw_ptr; 1073 unsigned int reg_value;
1086 int i, ret; 1074 int i, ret;
1087 1075
1088 ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &reg_value); 1076 ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &reg_value);
@@ -1098,13 +1086,6 @@ static irqreturn_t mtk_afe_irq_handler(int irq, void *dev_id)
1098 if (!(reg_value & (1 << memif->data->irq_clr_shift))) 1086 if (!(reg_value & (1 << memif->data->irq_clr_shift)))
1099 continue; 1087 continue;
1100 1088
1101 ret = regmap_read(afe->regmap, memif->data->reg_ofs_cur,
1102 &hw_ptr);
1103 if (ret || hw_ptr == 0) {
1104 dev_err(afe->dev, "%s hw_ptr err\n", __func__);
1105 hw_ptr = memif->phys_buf_addr;
1106 }
1107 memif->hw_ptr = hw_ptr - memif->phys_buf_addr;
1108 snd_pcm_period_elapsed(memif->substream); 1089 snd_pcm_period_elapsed(memif->substream);
1109 } 1090 }
1110 1091
@@ -1119,6 +1100,9 @@ static int mtk_afe_runtime_suspend(struct device *dev)
1119{ 1100{
1120 struct mtk_afe *afe = dev_get_drvdata(dev); 1101 struct mtk_afe *afe = dev_get_drvdata(dev);
1121 1102
1103 /* disable AFE */
1104 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0);
1105
1122 /* disable AFE clk */ 1106 /* disable AFE clk */
1123 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 1107 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
1124 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE); 1108 AUD_TCON0_PDN_AFE, AUD_TCON0_PDN_AFE);
@@ -1165,6 +1149,9 @@ static int mtk_afe_runtime_resume(struct device *dev)
1165 1149
1166 /* unmask all IRQs */ 1150 /* unmask all IRQs */
1167 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff); 1151 regmap_update_bits(afe->regmap, AFE_IRQ_MCU_EN, 0xff, 0xff);
1152
1153 /* enable AFE */
1154 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
1168 return 0; 1155 return 0;
1169 1156
1170err_bck0: 1157err_bck0:
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index 584b2372339e..f83cc2bc0fc4 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -368,6 +368,8 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev)
368 card->owner = THIS_MODULE; 368 card->owner = THIS_MODULE;
369 card->dai_link = 369 card->dai_link =
370 devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL); 370 devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL);
371 if (!card->dai_link)
372 return -ENOMEM;
371 card->dai_link->name = card->name; 373 card->dai_link->name = card->name;
372 card->dai_link->stream_name = card->name; 374 card->dai_link->stream_name = card->name;
373 card->dai_link->cpu_dai_name = dev_name(ad->dssdev); 375 card->dai_link->cpu_dai_name = dev_name(ad->dssdev);
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 6147e86e9b0f..416ea646c3b1 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -63,8 +63,7 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
63 sysclk = params_rate(params) * 512; 63 sysclk = params_rate(params) * 512;
64 sspa_mclk = params_rate(params) * 64; 64 sspa_mclk = params_rate(params) * 64;
65 } 65 }
66 sspa_div = freq_out; 66 sspa_div = freq_out / sspa_mclk;
67 do_div(sspa_div, sspa_mclk);
68 67
69 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0); 68 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
70 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk); 69 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 29bc60e85e92..5c8f9db50a47 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -81,8 +81,12 @@ static int rear_amp_power(struct snd_soc_codec *codec, int power)
81static int rear_amp_event(struct snd_soc_dapm_widget *widget, 81static int rear_amp_event(struct snd_soc_dapm_widget *widget,
82 struct snd_kcontrol *kctl, int event) 82 struct snd_kcontrol *kctl, int event)
83{ 83{
84 struct snd_soc_codec *codec = widget->dapm->card->rtd[0].codec; 84 struct snd_soc_card *card = widget->dapm->card;
85 struct snd_soc_pcm_runtime *rtd;
86 struct snd_soc_codec *codec;
85 87
88 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
89 codec = rtd->codec;
86 return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event)); 90 return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
87} 91}
88 92
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index e5101e0d2d37..00b6c9d039cf 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -355,6 +355,7 @@ static struct regmap_config lpass_cpu_regmap_config = {
355 .readable_reg = lpass_cpu_regmap_readable, 355 .readable_reg = lpass_cpu_regmap_readable,
356 .volatile_reg = lpass_cpu_regmap_volatile, 356 .volatile_reg = lpass_cpu_regmap_volatile,
357 .cache_type = REGCACHE_FLAT, 357 .cache_type = REGCACHE_FLAT,
358 .val_format_endian = REGMAP_ENDIAN_LITTLE,
358}; 359};
359 360
360int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) 361int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 58ee64594f07..8b0a588ed622 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -34,13 +34,7 @@ struct rk_i2s_dev {
34 34
35 struct regmap *regmap; 35 struct regmap *regmap;
36 36
37/* 37 bool is_master_mode;
38 * Used to indicate the tx/rx status.
39 * I2S controller hopes to start the tx and rx together,
40 * also to stop them when they are both try to stop.
41*/
42 bool tx_start;
43 bool rx_start;
44}; 38};
45 39
46static int i2s_runtime_suspend(struct device *dev) 40static int i2s_runtime_suspend(struct device *dev)
@@ -81,37 +75,29 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
81 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); 75 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
82 76
83 regmap_update_bits(i2s->regmap, I2S_XFER, 77 regmap_update_bits(i2s->regmap, I2S_XFER,
84 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 78 I2S_XFER_TXS_START,
85 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 79 I2S_XFER_TXS_START);
86
87 i2s->tx_start = true;
88 } else { 80 } else {
89 i2s->tx_start = false;
90
91 regmap_update_bits(i2s->regmap, I2S_DMACR, 81 regmap_update_bits(i2s->regmap, I2S_DMACR,
92 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); 82 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
93 83
94 if (!i2s->rx_start) { 84 regmap_update_bits(i2s->regmap, I2S_XFER,
95 regmap_update_bits(i2s->regmap, I2S_XFER, 85 I2S_XFER_TXS_START,
96 I2S_XFER_TXS_START | 86 I2S_XFER_TXS_STOP);
97 I2S_XFER_RXS_START,
98 I2S_XFER_TXS_STOP |
99 I2S_XFER_RXS_STOP);
100 87
101 regmap_update_bits(i2s->regmap, I2S_CLR, 88 regmap_update_bits(i2s->regmap, I2S_CLR,
102 I2S_CLR_TXC | I2S_CLR_RXC, 89 I2S_CLR_TXC,
103 I2S_CLR_TXC | I2S_CLR_RXC); 90 I2S_CLR_TXC);
104 91
105 regmap_read(i2s->regmap, I2S_CLR, &val); 92 regmap_read(i2s->regmap, I2S_CLR, &val);
106 93
107 /* Should wait for clear operation to finish */ 94 /* Should wait for clear operation to finish */
108 while (val) { 95 while (val & I2S_CLR_TXC) {
109 regmap_read(i2s->regmap, I2S_CLR, &val); 96 regmap_read(i2s->regmap, I2S_CLR, &val);
110 retry--; 97 retry--;
111 if (!retry) { 98 if (!retry) {
112 dev_warn(i2s->dev, "fail to clear\n"); 99 dev_warn(i2s->dev, "fail to clear\n");
113 break; 100 break;
114 }
115 } 101 }
116 } 102 }
117 } 103 }
@@ -127,37 +113,29 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
127 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); 113 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
128 114
129 regmap_update_bits(i2s->regmap, I2S_XFER, 115 regmap_update_bits(i2s->regmap, I2S_XFER,
130 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 116 I2S_XFER_RXS_START,
131 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 117 I2S_XFER_RXS_START);
132
133 i2s->rx_start = true;
134 } else { 118 } else {
135 i2s->rx_start = false;
136
137 regmap_update_bits(i2s->regmap, I2S_DMACR, 119 regmap_update_bits(i2s->regmap, I2S_DMACR,
138 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); 120 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
139 121
140 if (!i2s->tx_start) { 122 regmap_update_bits(i2s->regmap, I2S_XFER,
141 regmap_update_bits(i2s->regmap, I2S_XFER, 123 I2S_XFER_RXS_START,
142 I2S_XFER_TXS_START | 124 I2S_XFER_RXS_STOP);
143 I2S_XFER_RXS_START,
144 I2S_XFER_TXS_STOP |
145 I2S_XFER_RXS_STOP);
146 125
147 regmap_update_bits(i2s->regmap, I2S_CLR, 126 regmap_update_bits(i2s->regmap, I2S_CLR,
148 I2S_CLR_TXC | I2S_CLR_RXC, 127 I2S_CLR_RXC,
149 I2S_CLR_TXC | I2S_CLR_RXC); 128 I2S_CLR_RXC);
150 129
151 regmap_read(i2s->regmap, I2S_CLR, &val); 130 regmap_read(i2s->regmap, I2S_CLR, &val);
152 131
153 /* Should wait for clear operation to finish */ 132 /* Should wait for clear operation to finish */
154 while (val) { 133 while (val & I2S_CLR_RXC) {
155 regmap_read(i2s->regmap, I2S_CLR, &val); 134 regmap_read(i2s->regmap, I2S_CLR, &val);
156 retry--; 135 retry--;
157 if (!retry) { 136 if (!retry) {
158 dev_warn(i2s->dev, "fail to clear\n"); 137 dev_warn(i2s->dev, "fail to clear\n");
159 break; 138 break;
160 }
161 } 139 }
162 } 140 }
163 } 141 }
@@ -174,9 +152,11 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
174 case SND_SOC_DAIFMT_CBS_CFS: 152 case SND_SOC_DAIFMT_CBS_CFS:
175 /* Set source clock in Master mode */ 153 /* Set source clock in Master mode */
176 val = I2S_CKR_MSS_MASTER; 154 val = I2S_CKR_MSS_MASTER;
155 i2s->is_master_mode = true;
177 break; 156 break;
178 case SND_SOC_DAIFMT_CBM_CFM: 157 case SND_SOC_DAIFMT_CBM_CFM:
179 val = I2S_CKR_MSS_SLAVE; 158 val = I2S_CKR_MSS_SLAVE;
159 i2s->is_master_mode = false;
180 break; 160 break;
181 default: 161 default:
182 return -EINVAL; 162 return -EINVAL;
@@ -228,6 +208,26 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
228 struct rk_i2s_dev *i2s = to_info(dai); 208 struct rk_i2s_dev *i2s = to_info(dai);
229 struct snd_soc_pcm_runtime *rtd = substream->private_data; 209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
230 unsigned int val = 0; 210 unsigned int val = 0;
211 unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck;
212
213 if (i2s->is_master_mode) {
214 mclk_rate = clk_get_rate(i2s->mclk);
215 bclk_rate = 2 * 32 * params_rate(params);
216 if (bclk_rate && mclk_rate % bclk_rate)
217 return -EINVAL;
218
219 div_bclk = mclk_rate / bclk_rate;
220 div_lrck = bclk_rate / params_rate(params);
221 regmap_update_bits(i2s->regmap, I2S_CKR,
222 I2S_CKR_MDIV_MASK,
223 I2S_CKR_MDIV(div_bclk));
224
225 regmap_update_bits(i2s->regmap, I2S_CKR,
226 I2S_CKR_TSD_MASK |
227 I2S_CKR_RSD_MASK,
228 I2S_CKR_TSD(div_lrck) |
229 I2S_CKR_RSD(div_lrck));
230 }
231 231
232 switch (params_format(params)) { 232 switch (params_format(params)) {
233 case SNDRV_PCM_FORMAT_S8: 233 case SNDRV_PCM_FORMAT_S8:
@@ -451,6 +451,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
451{ 451{
452 struct device_node *node = pdev->dev.of_node; 452 struct device_node *node = pdev->dev.of_node;
453 struct rk_i2s_dev *i2s; 453 struct rk_i2s_dev *i2s;
454 struct snd_soc_dai_driver *soc_dai;
454 struct resource *res; 455 struct resource *res;
455 void __iomem *regs; 456 void __iomem *regs;
456 int ret; 457 int ret;
@@ -511,17 +512,26 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
511 goto err_pm_disable; 512 goto err_pm_disable;
512 } 513 }
513 514
514 /* refine capture channels */ 515 soc_dai = devm_kzalloc(&pdev->dev,
516 sizeof(*soc_dai), GFP_KERNEL);
517 if (!soc_dai)
518 return -ENOMEM;
519
520 memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai));
521 if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
522 if (val >= 2 && val <= 8)
523 soc_dai->playback.channels_max = val;
524 }
525
515 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { 526 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
516 if (val >= 2 && val <= 8) 527 if (val >= 2 && val <= 8)
517 rockchip_i2s_dai.capture.channels_max = val; 528 soc_dai->capture.channels_max = val;
518 else
519 rockchip_i2s_dai.capture.channels_max = 2;
520 } 529 }
521 530
522 ret = devm_snd_soc_register_component(&pdev->dev, 531 ret = devm_snd_soc_register_component(&pdev->dev,
523 &rockchip_i2s_component, 532 &rockchip_i2s_component,
524 &rockchip_i2s_dai, 1); 533 soc_dai, 1);
534
525 if (ret) { 535 if (ret) {
526 dev_err(&pdev->dev, "Could not register DAI\n"); 536 dev_err(&pdev->dev, "Could not register DAI\n");
527 goto err_suspend; 537 goto err_suspend;
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c
index 26567b10393a..543610282cdb 100644
--- a/sound/soc/rockchip/rockchip_max98090.c
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -80,11 +80,17 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
80 switch (params_rate(params)) { 80 switch (params_rate(params)) {
81 case 8000: 81 case 8000:
82 case 16000: 82 case 16000:
83 case 24000:
84 case 32000:
83 case 48000: 85 case 48000:
86 case 64000:
84 case 96000: 87 case 96000:
85 mclk = 12288000; 88 mclk = 12288000;
86 break; 89 break;
90 case 11025:
91 case 22050:
87 case 44100: 92 case 44100:
93 case 88200:
88 mclk = 11289600; 94 mclk = 11289600;
89 break; 95 break;
90 default: 96 default:
diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
index 68c62e4c2316..440a8026346a 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -79,11 +79,17 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
79 switch (params_rate(params)) { 79 switch (params_rate(params)) {
80 case 8000: 80 case 8000:
81 case 16000: 81 case 16000:
82 case 24000:
83 case 32000:
82 case 48000: 84 case 48000:
85 case 64000:
83 case 96000: 86 case 96000:
84 mclk = 12288000; 87 mclk = 12288000;
85 break; 88 break;
89 case 11025:
90 case 22050:
86 case 44100: 91 case 44100:
92 case 88200:
87 mclk = 11289600; 93 mclk = 11289600;
88 break; 94 break;
89 default: 95 default:
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 3744c9ed5370..78baa26e938b 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,8 +1,6 @@
1config SND_SOC_SAMSUNG 1config SND_SOC_SAMSUNG
2 tristate "ASoC support for Samsung" 2 tristate "ASoC support for Samsung"
3 depends on (PLAT_SAMSUNG || ARCH_EXYNOS) 3 depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
4 depends on S3C64XX_PL080 || !ARCH_S3C64XX
5 depends on S3C24XX_DMAC || !ARCH_S3C24XX
6 select SND_SOC_GENERIC_DMAENGINE_PCM 4 select SND_SOC_GENERIC_DMAENGINE_PCM
7 help 5 help
8 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/samsung/ac97.c b/sound/soc/samsung/ac97.c
index e4145509d63c..4a7a503fe13c 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -324,7 +324,7 @@ static const struct snd_soc_component_driver s3c_ac97_component = {
324 324
325static int s3c_ac97_probe(struct platform_device *pdev) 325static int s3c_ac97_probe(struct platform_device *pdev)
326{ 326{
327 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; 327 struct resource *mem_res, *irq_res;
328 struct s3c_audio_pdata *ac97_pdata; 328 struct s3c_audio_pdata *ac97_pdata;
329 int ret; 329 int ret;
330 330
@@ -335,24 +335,6 @@ static int s3c_ac97_probe(struct platform_device *pdev)
335 } 335 }
336 336
337 /* Check for availability of necessary resource */ 337 /* Check for availability of necessary resource */
338 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
339 if (!dmatx_res) {
340 dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
341 return -ENXIO;
342 }
343
344 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
345 if (!dmarx_res) {
346 dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
347 return -ENXIO;
348 }
349
350 dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
351 if (!dmamic_res) {
352 dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
353 return -ENXIO;
354 }
355
356 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 338 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
357 if (!irq_res) { 339 if (!irq_res) {
358 dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); 340 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
@@ -364,11 +346,11 @@ static int s3c_ac97_probe(struct platform_device *pdev)
364 if (IS_ERR(s3c_ac97.regs)) 346 if (IS_ERR(s3c_ac97.regs))
365 return PTR_ERR(s3c_ac97.regs); 347 return PTR_ERR(s3c_ac97.regs);
366 348
367 s3c_ac97_pcm_out.channel = dmatx_res->start; 349 s3c_ac97_pcm_out.slave = ac97_pdata->dma_playback;
368 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 350 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
369 s3c_ac97_pcm_in.channel = dmarx_res->start; 351 s3c_ac97_pcm_in.slave = ac97_pdata->dma_capture;
370 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 352 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
371 s3c_ac97_mic_in.channel = dmamic_res->start; 353 s3c_ac97_mic_in.slave = ac97_pdata->dma_capture_mic;
372 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; 354 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
373 355
374 init_completion(&s3c_ac97.done); 356 init_completion(&s3c_ac97.done);
@@ -406,7 +388,8 @@ static int s3c_ac97_probe(struct platform_device *pdev)
406 if (ret) 388 if (ret)
407 goto err5; 389 goto err5;
408 390
409 ret = samsung_asoc_dma_platform_register(&pdev->dev); 391 ret = samsung_asoc_dma_platform_register(&pdev->dev,
392 ac97_pdata->dma_filter);
410 if (ret) { 393 if (ret) {
411 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 394 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
412 goto err5; 395 goto err5;
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index e5f05e62fa3c..3dd246fa0059 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -58,11 +58,16 @@ static int bells_set_bias_level(struct snd_soc_card *card,
58 struct snd_soc_dapm_context *dapm, 58 struct snd_soc_dapm_context *dapm,
59 enum snd_soc_bias_level level) 59 enum snd_soc_bias_level level)
60{ 60{
61 struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 61 struct snd_soc_pcm_runtime *rtd;
62 struct snd_soc_codec *codec = codec_dai->codec; 62 struct snd_soc_dai *codec_dai;
63 struct snd_soc_codec *codec;
63 struct bells_drvdata *bells = card->drvdata; 64 struct bells_drvdata *bells = card->drvdata;
64 int ret; 65 int ret;
65 66
67 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
68 codec_dai = rtd->codec_dai;
69 codec = codec_dai->codec;
70
66 if (dapm->dev != codec_dai->dev) 71 if (dapm->dev != codec_dai->dev)
67 return 0; 72 return 0;
68 73
@@ -99,11 +104,16 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
99 struct snd_soc_dapm_context *dapm, 104 struct snd_soc_dapm_context *dapm,
100 enum snd_soc_bias_level level) 105 enum snd_soc_bias_level level)
101{ 106{
102 struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 107 struct snd_soc_pcm_runtime *rtd;
103 struct snd_soc_codec *codec = codec_dai->codec; 108 struct snd_soc_dai *codec_dai;
109 struct snd_soc_codec *codec;
104 struct bells_drvdata *bells = card->drvdata; 110 struct bells_drvdata *bells = card->drvdata;
105 int ret; 111 int ret;
106 112
113 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
114 codec_dai = rtd->codec_dai;
115 codec = codec_dai->codec;
116
107 if (dapm->dev != codec_dai->dev) 117 if (dapm->dev != codec_dai->dev)
108 return 0; 118 return 0;
109 119
@@ -137,14 +147,22 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
137static int bells_late_probe(struct snd_soc_card *card) 147static int bells_late_probe(struct snd_soc_card *card)
138{ 148{
139 struct bells_drvdata *bells = card->drvdata; 149 struct bells_drvdata *bells = card->drvdata;
140 struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec; 150 struct snd_soc_pcm_runtime *rtd;
141 struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec; 151 struct snd_soc_codec *wm0010;
142 struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai; 152 struct snd_soc_codec *codec;
153 struct snd_soc_dai *aif1_dai;
143 struct snd_soc_dai *aif2_dai; 154 struct snd_soc_dai *aif2_dai;
144 struct snd_soc_dai *aif3_dai; 155 struct snd_soc_dai *aif3_dai;
145 struct snd_soc_dai *wm9081_dai; 156 struct snd_soc_dai *wm9081_dai;
146 int ret; 157 int ret;
147 158
159 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name);
160 wm0010 = rtd->codec;
161
162 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
163 codec = rtd->codec;
164 aif1_dai = rtd->codec_dai;
165
148 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, 166 ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
149 ARIZONA_CLK_SRC_FLL1, 167 ARIZONA_CLK_SRC_FLL1,
150 bells->sysclk_rate, 168 bells->sysclk_rate,
@@ -181,7 +199,8 @@ static int bells_late_probe(struct snd_soc_card *card)
181 return ret; 199 return ret;
182 } 200 }
183 201
184 aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai; 202 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_CP].name);
203 aif2_dai = rtd->cpu_dai;
185 204
186 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0); 205 ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
187 if (ret != 0) { 206 if (ret != 0) {
@@ -192,8 +211,9 @@ static int bells_late_probe(struct snd_soc_card *card)
192 if (card->num_rtd == DAI_CODEC_SUB) 211 if (card->num_rtd == DAI_CODEC_SUB)
193 return 0; 212 return 0;
194 213
195 aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai; 214 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_SUB].name);
196 wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai; 215 aif3_dai = rtd->cpu_dai;
216 wm9081_dai = rtd->codec_dai;
197 217
198 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0); 218 ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
199 if (ret != 0) { 219 if (ret != 0) {
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 0e85dcfec023..a7616cc9b39e 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -13,9 +13,10 @@
13#define _S3C_AUDIO_H 13#define _S3C_AUDIO_H
14 14
15#include <sound/dmaengine_pcm.h> 15#include <sound/dmaengine_pcm.h>
16#include <linux/dmaengine.h>
16 17
17struct s3c_dma_params { 18struct s3c_dma_params {
18 int channel; /* Channel ID */ 19 void *slave; /* Channel ID */
19 dma_addr_t dma_addr; 20 dma_addr_t dma_addr;
20 int dma_size; /* Size of the DMA transfer */ 21 int dma_size; /* Size of the DMA transfer */
21 char *ch_name; 22 char *ch_name;
@@ -25,6 +26,7 @@ struct s3c_dma_params {
25void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 26void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
26 struct s3c_dma_params *playback, 27 struct s3c_dma_params *playback,
27 struct s3c_dma_params *capture); 28 struct s3c_dma_params *capture);
28int samsung_asoc_dma_platform_register(struct device *dev); 29int samsung_asoc_dma_platform_register(struct device *dev,
30 dma_filter_fn fn);
29 31
30#endif 32#endif
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index 506f5bf6d082..063125937311 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -28,17 +28,8 @@
28 28
29#include "dma.h" 29#include "dma.h"
30 30
31#ifdef CONFIG_ARCH_S3C64XX 31static struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
32#define filter_fn pl08x_filter_id
33#elif defined(CONFIG_ARCH_S3C24XX)
34#define filter_fn s3c24xx_dma_filter
35#else
36#define filter_fn NULL
37#endif
38
39static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = {
40 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 32 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
41 .compat_filter_fn = filter_fn,
42}; 33};
43 34
44void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, 35void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
@@ -50,14 +41,14 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
50 41
51 if (playback) { 42 if (playback) {
52 playback_data = &playback->dma_data; 43 playback_data = &playback->dma_data;
53 playback_data->filter_data = (void *)playback->channel; 44 playback_data->filter_data = playback->slave;
54 playback_data->chan_name = playback->ch_name; 45 playback_data->chan_name = playback->ch_name;
55 playback_data->addr = playback->dma_addr; 46 playback_data->addr = playback->dma_addr;
56 playback_data->addr_width = playback->dma_size; 47 playback_data->addr_width = playback->dma_size;
57 } 48 }
58 if (capture) { 49 if (capture) {
59 capture_data = &capture->dma_data; 50 capture_data = &capture->dma_data;
60 capture_data->filter_data = (void *)capture->channel; 51 capture_data->filter_data = capture->slave;
61 capture_data->chan_name = capture->ch_name; 52 capture_data->chan_name = capture->ch_name;
62 capture_data->addr = capture->dma_addr; 53 capture_data->addr = capture->dma_addr;
63 capture_data->addr_width = capture->dma_size; 54 capture_data->addr_width = capture->dma_size;
@@ -67,8 +58,11 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
67} 58}
68EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); 59EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
69 60
70int samsung_asoc_dma_platform_register(struct device *dev) 61int samsung_asoc_dma_platform_register(struct device *dev,
62 dma_filter_fn filter)
71{ 63{
64 samsung_dmaengine_pcm_config.compat_filter_fn = filter;
65
72 return devm_snd_dmaengine_pcm_register(dev, 66 return devm_snd_dmaengine_pcm_register(dev,
73 &samsung_dmaengine_pcm_config, 67 &samsung_dmaengine_pcm_config,
74 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | 68 SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index ea4ab374a223..84d9e77c0fbe 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -89,6 +89,7 @@ struct i2s_dai {
89 struct s3c_dma_params dma_playback; 89 struct s3c_dma_params dma_playback;
90 struct s3c_dma_params dma_capture; 90 struct s3c_dma_params dma_capture;
91 struct s3c_dma_params idma_playback; 91 struct s3c_dma_params idma_playback;
92 dma_filter_fn filter;
92 u32 quirks; 93 u32 quirks;
93 u32 suspend_i2smod; 94 u32 suspend_i2smod;
94 u32 suspend_i2scon; 95 u32 suspend_i2scon;
@@ -1244,7 +1245,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1244 if (ret != 0) 1245 if (ret != 0)
1245 return ret; 1246 return ret;
1246 1247
1247 return samsung_asoc_dma_platform_register(&pdev->dev); 1248 return samsung_asoc_dma_platform_register(&pdev->dev,
1249 sec_dai->filter);
1248 } 1250 }
1249 1251
1250 pri_dai = i2s_alloc_dai(pdev, false); 1252 pri_dai = i2s_alloc_dai(pdev, false);
@@ -1257,27 +1259,15 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1257 pri_dai->lock = &pri_dai->spinlock; 1259 pri_dai->lock = &pri_dai->spinlock;
1258 1260
1259 if (!np) { 1261 if (!np) {
1260 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1261 if (!res) {
1262 dev_err(&pdev->dev,
1263 "Unable to get I2S-TX dma resource\n");
1264 return -ENXIO;
1265 }
1266 pri_dai->dma_playback.channel = res->start;
1267
1268 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1269 if (!res) {
1270 dev_err(&pdev->dev,
1271 "Unable to get I2S-RX dma resource\n");
1272 return -ENXIO;
1273 }
1274 pri_dai->dma_capture.channel = res->start;
1275
1276 if (i2s_pdata == NULL) { 1262 if (i2s_pdata == NULL) {
1277 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); 1263 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1278 return -EINVAL; 1264 return -EINVAL;
1279 } 1265 }
1280 1266
1267 pri_dai->dma_playback.slave = i2s_pdata->dma_playback;
1268 pri_dai->dma_capture.slave = i2s_pdata->dma_capture;
1269 pri_dai->filter = i2s_pdata->dma_filter;
1270
1281 if (&i2s_pdata->type) 1271 if (&i2s_pdata->type)
1282 i2s_cfg = &i2s_pdata->type.i2s; 1272 i2s_cfg = &i2s_pdata->type.i2s;
1283 1273
@@ -1339,9 +1329,8 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1339 sec_dai->dma_playback.ch_name = "tx-sec"; 1329 sec_dai->dma_playback.ch_name = "tx-sec";
1340 1330
1341 if (!np) { 1331 if (!np) {
1342 res = platform_get_resource(pdev, IORESOURCE_DMA, 2); 1332 sec_dai->dma_playback.slave = i2s_pdata->dma_play_sec;
1343 if (res) 1333 sec_dai->filter = i2s_pdata->dma_filter;
1344 sec_dai->dma_playback.channel = res->start;
1345 } 1334 }
1346 1335
1347 sec_dai->dma_playback.dma_size = 4; 1336 sec_dai->dma_playback.dma_size = 4;
@@ -1364,7 +1353,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1364 1353
1365 pm_runtime_enable(&pdev->dev); 1354 pm_runtime_enable(&pdev->dev);
1366 1355
1367 ret = samsung_asoc_dma_platform_register(&pdev->dev); 1356 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter);
1368 if (ret != 0) 1357 if (ret != 0)
1369 return ret; 1358 return ret;
1370 1359
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 31a820eb0ac3..7cb204e649ca 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -23,9 +23,13 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
23 struct snd_soc_dapm_context *dapm, 23 struct snd_soc_dapm_context *dapm,
24 enum snd_soc_bias_level level) 24 enum snd_soc_bias_level level)
25{ 25{
26 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 26 struct snd_soc_pcm_runtime *rtd;
27 struct snd_soc_dai *aif1_dai;
27 int ret; 28 int ret;
28 29
30 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
31 aif1_dai = rtd->codec_dai;
32
29 if (dapm->dev != aif1_dai->dev) 33 if (dapm->dev != aif1_dai->dev)
30 return 0; 34 return 0;
31 35
@@ -66,9 +70,13 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
66 struct snd_soc_dapm_context *dapm, 70 struct snd_soc_dapm_context *dapm,
67 enum snd_soc_bias_level level) 71 enum snd_soc_bias_level level)
68{ 72{
69 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 73 struct snd_soc_pcm_runtime *rtd;
74 struct snd_soc_dai *aif1_dai;
70 int ret; 75 int ret;
71 76
77 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
78 aif1_dai = rtd->codec_dai;
79
72 if (dapm->dev != aif1_dai->dev) 80 if (dapm->dev != aif1_dai->dev)
73 return 0; 81 return 0;
74 82
@@ -168,9 +176,13 @@ static int bbclk_ev(struct snd_soc_dapm_widget *w,
168 struct snd_kcontrol *kcontrol, int event) 176 struct snd_kcontrol *kcontrol, int event)
169{ 177{
170 struct snd_soc_card *card = w->dapm->card; 178 struct snd_soc_card *card = w->dapm->card;
171 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; 179 struct snd_soc_pcm_runtime *rtd;
180 struct snd_soc_dai *aif2_dai;
172 int ret; 181 int ret;
173 182
183 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
184 aif2_dai = rtd->cpu_dai;
185
174 switch (event) { 186 switch (event) {
175 case SND_SOC_DAPM_PRE_PMU: 187 case SND_SOC_DAPM_PRE_PMU:
176 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2, 188 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
@@ -245,11 +257,19 @@ static struct snd_soc_jack littlemill_headset;
245 257
246static int littlemill_late_probe(struct snd_soc_card *card) 258static int littlemill_late_probe(struct snd_soc_card *card)
247{ 259{
248 struct snd_soc_codec *codec = card->rtd[0].codec; 260 struct snd_soc_pcm_runtime *rtd;
249 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai; 261 struct snd_soc_codec *codec;
250 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai; 262 struct snd_soc_dai *aif1_dai;
263 struct snd_soc_dai *aif2_dai;
251 int ret; 264 int ret;
252 265
266 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
267 codec = rtd->codec;
268 aif1_dai = rtd->codec_dai;
269
270 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
271 aif2_dai = rtd->cpu_dai;
272
253 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, 273 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
254 32768, SND_SOC_CLOCK_IN); 274 32768, SND_SOC_CLOCK_IN);
255 if (ret < 0) 275 if (ret < 0)
diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c
index 596f1180a369..04217279fe25 100644
--- a/sound/soc/samsung/odroidx2_max98090.c
+++ b/sound/soc/samsung/odroidx2_max98090.c
@@ -25,10 +25,15 @@ static struct snd_soc_dai_link odroidx2_dai[];
25 25
26static int odroidx2_late_probe(struct snd_soc_card *card) 26static int odroidx2_late_probe(struct snd_soc_card *card)
27{ 27{
28 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 28 struct snd_soc_pcm_runtime *rtd;
29 struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai; 29 struct snd_soc_dai *codec_dai;
30 struct snd_soc_dai *cpu_dai;
30 int ret; 31 int ret;
31 32
33 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
34 codec_dai = rtd->codec_dai;
35 cpu_dai = rtd->cpu_dai;
36
32 ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK, 37 ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK,
33 SND_SOC_CLOCK_IN); 38 SND_SOC_CLOCK_IN);
34 39
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index b320a9d3fbf8..498f563a4c9c 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -486,8 +486,9 @@ static const struct snd_soc_component_driver s3c_pcm_component = {
486static int s3c_pcm_dev_probe(struct platform_device *pdev) 486static int s3c_pcm_dev_probe(struct platform_device *pdev)
487{ 487{
488 struct s3c_pcm_info *pcm; 488 struct s3c_pcm_info *pcm;
489 struct resource *mem_res, *dmatx_res, *dmarx_res; 489 struct resource *mem_res;
490 struct s3c_audio_pdata *pcm_pdata; 490 struct s3c_audio_pdata *pcm_pdata;
491 dma_filter_fn filter;
491 int ret; 492 int ret;
492 493
493 /* Check for valid device index */ 494 /* Check for valid device index */
@@ -499,18 +500,6 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
499 pcm_pdata = pdev->dev.platform_data; 500 pcm_pdata = pdev->dev.platform_data;
500 501
501 /* Check for availability of necessary resource */ 502 /* Check for availability of necessary resource */
502 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
503 if (!dmatx_res) {
504 dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
505 return -ENXIO;
506 }
507
508 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
509 if (!dmarx_res) {
510 dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
511 return -ENXIO;
512 }
513
514 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 503 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
515 if (!mem_res) { 504 if (!mem_res) {
516 dev_err(&pdev->dev, "Unable to get register resource\n"); 505 dev_err(&pdev->dev, "Unable to get register resource\n");
@@ -568,8 +557,12 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
568 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start 557 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
569 + S3C_PCM_TXFIFO; 558 + S3C_PCM_TXFIFO;
570 559
571 s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; 560 filter = NULL;
572 s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; 561 if (pcm_pdata) {
562 s3c_pcm_stereo_in[pdev->id].slave = pcm_pdata->dma_capture;
563 s3c_pcm_stereo_out[pdev->id].slave = pcm_pdata->dma_playback;
564 filter = pcm_pdata->dma_filter;
565 }
573 566
574 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; 567 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
575 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; 568 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
@@ -583,7 +576,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
583 goto err5; 576 goto err5;
584 } 577 }
585 578
586 ret = samsung_asoc_dma_platform_register(&pdev->dev); 579 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
587 if (ret) { 580 if (ret) {
588 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 581 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
589 goto err5; 582 goto err5;
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 2b766d212ce0..204029d12f5b 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -25,7 +25,6 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27 27
28#include <mach/dma.h>
29#include <mach/gpio-samsung.h> 28#include <mach/gpio-samsung.h>
30#include <plat/gpio-cfg.h> 29#include <plat/gpio-cfg.h>
31 30
@@ -33,14 +32,14 @@
33#include "regs-i2s-v2.h" 32#include "regs-i2s-v2.h"
34#include "s3c2412-i2s.h" 33#include "s3c2412-i2s.h"
35 34
35#include <linux/platform_data/asoc-s3c.h>
36
36static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { 37static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
37 .channel = DMACH_I2S_OUT,
38 .ch_name = "tx", 38 .ch_name = "tx",
39 .dma_size = 4, 39 .dma_size = 4,
40}; 40};
41 41
42static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { 42static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
43 .channel = DMACH_I2S_IN,
44 .ch_name = "rx", 43 .ch_name = "rx",
45 .dma_size = 4, 44 .dma_size = 4,
46}; 45};
@@ -152,6 +151,12 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
152{ 151{
153 int ret = 0; 152 int ret = 0;
154 struct resource *res; 153 struct resource *res;
154 struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev);
155
156 if (!pdata) {
157 dev_err(&pdev->dev, "missing platform data");
158 return -ENXIO;
159 }
155 160
156 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
157 s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res); 162 s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
@@ -159,7 +164,9 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
159 return PTR_ERR(s3c2412_i2s.regs); 164 return PTR_ERR(s3c2412_i2s.regs);
160 165
161 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD; 166 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
167 s3c2412_i2s_pcm_stereo_out.slave = pdata->dma_playback;
162 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD; 168 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
169 s3c2412_i2s_pcm_stereo_in.slave = pdata->dma_capture;
163 170
164 ret = s3c_i2sv2_register_component(&pdev->dev, -1, 171 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
165 &s3c2412_i2s_component, 172 &s3c2412_i2s_component,
@@ -169,7 +176,8 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
169 return ret; 176 return ret;
170 } 177 }
171 178
172 ret = samsung_asoc_dma_platform_register(&pdev->dev); 179 ret = samsung_asoc_dma_platform_register(&pdev->dev,
180 pdata->dma_filter);
173 if (ret) 181 if (ret)
174 pr_err("failed to register the DMA: %d\n", ret); 182 pr_err("failed to register the DMA: %d\n", ret);
175 183
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 5bf723689692..b3a475d73ba7 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25 25
26#include <mach/dma.h>
27#include <mach/gpio-samsung.h> 26#include <mach/gpio-samsung.h>
28#include <plat/gpio-cfg.h> 27#include <plat/gpio-cfg.h>
29#include "regs-iis.h" 28#include "regs-iis.h"
@@ -31,14 +30,14 @@
31#include "dma.h" 30#include "dma.h"
32#include "s3c24xx-i2s.h" 31#include "s3c24xx-i2s.h"
33 32
33#include <linux/platform_data/asoc-s3c.h>
34
34static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { 35static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
35 .channel = DMACH_I2S_OUT,
36 .ch_name = "tx", 36 .ch_name = "tx",
37 .dma_size = 2, 37 .dma_size = 2,
38}; 38};
39 39
40static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { 40static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
41 .channel = DMACH_I2S_IN,
42 .ch_name = "rx", 41 .ch_name = "rx",
43 .dma_size = 2, 42 .dma_size = 2,
44}; 43};
@@ -454,6 +453,12 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
454{ 453{
455 int ret = 0; 454 int ret = 0;
456 struct resource *res; 455 struct resource *res;
456 struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev);
457
458 if (!pdata) {
459 dev_err(&pdev->dev, "missing platform data");
460 return -ENXIO;
461 }
457 462
458 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 463 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
459 if (!res) { 464 if (!res) {
@@ -465,7 +470,9 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
465 return PTR_ERR(s3c24xx_i2s.regs); 470 return PTR_ERR(s3c24xx_i2s.regs);
466 471
467 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO; 472 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
473 s3c24xx_i2s_pcm_stereo_out.slave = pdata->dma_playback;
468 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO; 474 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
475 s3c24xx_i2s_pcm_stereo_in.slave = pdata->dma_capture;
469 476
470 ret = devm_snd_soc_register_component(&pdev->dev, 477 ret = devm_snd_soc_register_component(&pdev->dev,
471 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); 478 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
@@ -474,7 +481,8 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
474 return ret; 481 return ret;
475 } 482 }
476 483
477 ret = samsung_asoc_dma_platform_register(&pdev->dev); 484 ret = samsung_asoc_dma_platform_register(&pdev->dev,
485 pdata->dma_filter);
478 if (ret) 486 if (ret)
479 pr_err("failed to register the dma: %d\n", ret); 487 pr_err("failed to register the dma: %d\n", ret);
480 488
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c
index 07ce2cfa4845..d8ac907bbb0d 100644
--- a/sound/soc/samsung/snow.c
+++ b/sound/soc/samsung/snow.c
@@ -35,10 +35,15 @@ static struct snd_soc_dai_link snow_dai[] = {
35 35
36static int snow_late_probe(struct snd_soc_card *card) 36static int snow_late_probe(struct snd_soc_card *card)
37{ 37{
38 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 38 struct snd_soc_pcm_runtime *rtd;
39 struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai; 39 struct snd_soc_dai *codec_dai;
40 struct snd_soc_dai *cpu_dai;
40 int ret; 41 int ret;
41 42
43 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
44 codec_dai = rtd->codec_dai;
45 cpu_dai = rtd->cpu_dai;
46
42 /* Set the MCLK rate for the codec */ 47 /* Set the MCLK rate for the codec */
43 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 48 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
44 FIN_PLL_RATE, SND_SOC_CLOCK_IN); 49 FIN_PLL_RATE, SND_SOC_CLOCK_IN);
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 36dbc0e96004..4687f521197c 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -359,20 +359,15 @@ static const struct snd_soc_component_driver samsung_spdif_component = {
359static int spdif_probe(struct platform_device *pdev) 359static int spdif_probe(struct platform_device *pdev)
360{ 360{
361 struct s3c_audio_pdata *spdif_pdata; 361 struct s3c_audio_pdata *spdif_pdata;
362 struct resource *mem_res, *dma_res; 362 struct resource *mem_res;
363 struct samsung_spdif_info *spdif; 363 struct samsung_spdif_info *spdif;
364 dma_filter_fn filter;
364 int ret; 365 int ret;
365 366
366 spdif_pdata = pdev->dev.platform_data; 367 spdif_pdata = pdev->dev.platform_data;
367 368
368 dev_dbg(&pdev->dev, "Entered %s\n", __func__); 369 dev_dbg(&pdev->dev, "Entered %s\n", __func__);
369 370
370 dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
371 if (!dma_res) {
372 dev_err(&pdev->dev, "Unable to get dma resource.\n");
373 return -ENXIO;
374 }
375
376 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 371 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
377 if (!mem_res) { 372 if (!mem_res) {
378 dev_err(&pdev->dev, "Unable to get register resource.\n"); 373 dev_err(&pdev->dev, "Unable to get register resource.\n");
@@ -432,11 +427,15 @@ static int spdif_probe(struct platform_device *pdev)
432 427
433 spdif_stereo_out.dma_size = 2; 428 spdif_stereo_out.dma_size = 2;
434 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; 429 spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
435 spdif_stereo_out.channel = dma_res->start; 430 filter = NULL;
431 if (spdif_pdata) {
432 spdif_stereo_out.slave = spdif_pdata->dma_playback;
433 filter = spdif_pdata->dma_filter;
434 }
436 435
437 spdif->dma_playback = &spdif_stereo_out; 436 spdif->dma_playback = &spdif_stereo_out;
438 437
439 ret = samsung_asoc_dma_platform_register(&pdev->dev); 438 ret = samsung_asoc_dma_platform_register(&pdev->dev, filter);
440 if (ret) { 439 if (ret) {
441 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); 440 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
442 goto err4; 441 goto err4;
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index d1ae21c5e253..083ef5e21b17 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -25,9 +25,13 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
25 struct snd_soc_dapm_context *dapm, 25 struct snd_soc_dapm_context *dapm,
26 enum snd_soc_bias_level level) 26 enum snd_soc_bias_level level)
27{ 27{
28 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; 28 struct snd_soc_pcm_runtime *rtd;
29 struct snd_soc_dai *codec_dai;
29 int ret; 30 int ret;
30 31
32 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
33 codec_dai = rtd->codec_dai;
34
31 if (dapm->dev != codec_dai->dev) 35 if (dapm->dev != codec_dai->dev)
32 return 0; 36 return 0;
33 37
@@ -57,9 +61,13 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
57 struct snd_soc_dapm_context *dapm, 61 struct snd_soc_dapm_context *dapm,
58 enum snd_soc_bias_level level) 62 enum snd_soc_bias_level level)
59{ 63{
60 struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai; 64 struct snd_soc_pcm_runtime *rtd;
65 struct snd_soc_dai *codec_dai;
61 int ret; 66 int ret;
62 67
68 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
69 codec_dai = rtd->codec_dai;
70
63 if (dapm->dev != codec_dai->dev) 71 if (dapm->dev != codec_dai->dev)
64 return 0; 72 return 0;
65 73
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index 85ccfb7188cb..3310eda7cf53 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -23,9 +23,13 @@ static int tobermory_set_bias_level(struct snd_soc_card *card,
23 struct snd_soc_dapm_context *dapm, 23 struct snd_soc_dapm_context *dapm,
24 enum snd_soc_bias_level level) 24 enum snd_soc_bias_level level)
25{ 25{
26 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 26 struct snd_soc_pcm_runtime *rtd;
27 struct snd_soc_dai *codec_dai;
27 int ret; 28 int ret;
28 29
30 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
31 codec_dai = rtd->codec_dai;
32
29 if (dapm->dev != codec_dai->dev) 33 if (dapm->dev != codec_dai->dev)
30 return 0; 34 return 0;
31 35
@@ -62,9 +66,13 @@ static int tobermory_set_bias_level_post(struct snd_soc_card *card,
62 struct snd_soc_dapm_context *dapm, 66 struct snd_soc_dapm_context *dapm,
63 enum snd_soc_bias_level level) 67 enum snd_soc_bias_level level)
64{ 68{
65 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 69 struct snd_soc_pcm_runtime *rtd;
70 struct snd_soc_dai *codec_dai;
66 int ret; 71 int ret;
67 72
73 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
74 codec_dai = rtd->codec_dai;
75
68 if (dapm->dev != codec_dai->dev) 76 if (dapm->dev != codec_dai->dev)
69 return 0; 77 return 0;
70 78
@@ -170,10 +178,15 @@ static struct snd_soc_jack_pin tobermory_headset_pins[] = {
170 178
171static int tobermory_late_probe(struct snd_soc_card *card) 179static int tobermory_late_probe(struct snd_soc_card *card)
172{ 180{
173 struct snd_soc_codec *codec = card->rtd[0].codec; 181 struct snd_soc_pcm_runtime *rtd;
174 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 182 struct snd_soc_codec *codec;
183 struct snd_soc_dai *codec_dai;
175 int ret; 184 int ret;
176 185
186 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
187 codec = rtd->codec;
188 codec_dai = rtd->codec_dai;
189
177 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK, 190 ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
178 32768, SND_SOC_CLOCK_IN); 191 32768, SND_SOC_CLOCK_IN);
179 if (ret < 0) 192 if (ret < 0)
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 206d1edab07c..c9902a6d6fa0 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -36,7 +36,6 @@ config SND_SOC_SH4_SIU
36 36
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF
40 depends on COMMON_CLK 39 depends on COMMON_CLK
41 select SND_SIMPLE_CARD 40 select SND_SIMPLE_CARD
42 select REGMAP_MMIO 41 select REGMAP_MMIO
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 0215c78cbddf..ead520182e26 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1362,15 +1362,18 @@ static int fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1362 1362
1363static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) 1363static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
1364{ 1364{
1365 dma_cap_mask_t mask;
1366 int is_play = fsi_stream_is_play(fsi, io); 1365 int is_play = fsi_stream_is_play(fsi, io);
1367 1366
1367#ifdef CONFIG_SUPERH
1368 dma_cap_mask_t mask;
1368 dma_cap_zero(mask); 1369 dma_cap_zero(mask);
1369 dma_cap_set(DMA_SLAVE, mask); 1370 dma_cap_set(DMA_SLAVE, mask);
1370 1371
1371 io->chan = dma_request_slave_channel_compat(mask, 1372 io->chan = dma_request_channel(mask, shdma_chan_filter,
1372 shdma_chan_filter, (void *)io->dma_id, 1373 (void *)io->dma_id);
1373 dev, is_play ? "tx" : "rx"); 1374#else
1375 io->chan = dma_request_slave_channel(dev, is_play ? "tx" : "rx");
1376#endif
1374 if (io->chan) { 1377 if (io->chan) {
1375 struct dma_slave_config cfg = {}; 1378 struct dma_slave_config cfg = {};
1376 int ret; 1379 int ret;
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 8b258501aa35..a89ddf758695 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,4 +1,4 @@
1snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o 1snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
3 3
4snd-soc-rsrc-card-objs := rsrc-card.o 4snd-soc-rsrc-card-objs := rsrc-card.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 2a5b3a293cd2..6d3ef366d536 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -68,8 +68,8 @@ static u32 rsnd_adg_calculate_rbgx(unsigned long div)
68 68
69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) 69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
70{ 70{
71 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); 71 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
72 int id = rsnd_mod_id(mod); 72 int id = rsnd_mod_id(ssi_mod);
73 int ws = id; 73 int ws = id;
74 74
75 if (rsnd_ssi_is_pin_sharing(io)) { 75 if (rsnd_ssi_is_pin_sharing(io)) {
@@ -90,13 +90,13 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
90 return (0x6 + ws) << 8; 90 return (0x6 + ws) << 8;
91} 91}
92 92
93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, 93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
94 struct rsnd_dai_stream *io) 94 struct rsnd_dai_stream *io)
95{ 95{
96 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 96 struct rsnd_priv *priv = rsnd_mod_to_priv(cmd_mod);
97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg); 98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
99 int id = rsnd_mod_id(mod); 99 int id = rsnd_mod_id(cmd_mod);
100 int shift = (id % 2) ? 16 : 0; 100 int shift = (id % 2) ? 16 : 0;
101 u32 mask, val; 101 u32 mask, val;
102 102
@@ -242,68 +242,6 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,
242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val); 242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
243} 243}
244 244
245int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
246 struct rsnd_mod *mod,
247 unsigned int src_rate,
248 unsigned int dst_rate)
249{
250 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
251 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
252 struct device *dev = rsnd_priv_to_dev(priv);
253 int idx, sel, div, shift;
254 u32 mask, val;
255 int id = rsnd_mod_id(mod);
256 unsigned int sel_rate [] = {
257 clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */
258 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
259 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
260 0, /* 011: MLBCLK (not used) */
261 adg->rbga_rate_for_441khz, /* 100: RBGA */
262 adg->rbgb_rate_for_48khz, /* 101: RBGB */
263 };
264
265 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
266 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
267 for (div = 128, idx = 0;
268 div <= 2048;
269 div *= 2, idx++) {
270 if (src_rate == sel_rate[sel] / div) {
271 val = (idx << 4) | sel;
272 goto find_rate;
273 }
274 }
275 }
276 dev_err(dev, "can't find convert src clk\n");
277 return -EINVAL;
278
279find_rate:
280 shift = (id % 4) * 8;
281 mask = 0xFF << shift;
282 val = val << shift;
283
284 dev_dbg(dev, "adg convert src clk = %02x\n", val);
285
286 switch (id / 4) {
287 case 0:
288 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);
289 break;
290 case 1:
291 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);
292 break;
293 case 2:
294 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);
295 break;
296 }
297
298 /*
299 * Gen1 doesn't need dst_rate settings,
300 * since it uses SSI WS pin.
301 * see also rsnd_src_set_route_if_gen1()
302 */
303
304 return 0;
305}
306
307static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val) 245static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
308{ 246{
309 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 247 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
@@ -337,20 +275,16 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
337 } 275 }
338} 276}
339 277
340int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) 278int rsnd_adg_ssi_clk_stop(struct rsnd_mod *ssi_mod)
341{ 279{
342 /* 280 rsnd_adg_set_ssi_clk(ssi_mod, 0);
343 * "mod" = "ssi" here.
344 * we can get "ssi id" from mod
345 */
346 rsnd_adg_set_ssi_clk(mod, 0);
347 281
348 return 0; 282 return 0;
349} 283}
350 284
351int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) 285int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
352{ 286{
353 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 287 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
354 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 288 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
355 struct device *dev = rsnd_priv_to_dev(priv); 289 struct device *dev = rsnd_priv_to_dev(priv);
356 struct clk *clk; 290 struct clk *clk;
@@ -394,14 +328,10 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
394 328
395found_clock: 329found_clock:
396 330
397 /* 331 rsnd_adg_set_ssi_clk(ssi_mod, data);
398 * This "mod" = "ssi" here.
399 * we can get "ssi id" from mod
400 */
401 rsnd_adg_set_ssi_clk(mod, data);
402 332
403 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", 333 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
404 rsnd_mod_name(mod), rsnd_mod_id(mod), 334 rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod),
405 data, rate); 335 data, rate);
406 336
407 return 0; 337 return 0;
@@ -418,15 +348,20 @@ static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
418 [CLKC] = "clk_c", 348 [CLKC] = "clk_c",
419 [CLKI] = "clk_i", 349 [CLKI] = "clk_i",
420 }; 350 };
421 int i; 351 int i, ret;
422 352
423 for (i = 0; i < CLKMAX; i++) { 353 for (i = 0; i < CLKMAX; i++) {
424 clk = devm_clk_get(dev, clk_name[i]); 354 clk = devm_clk_get(dev, clk_name[i]);
425 adg->clk[i] = IS_ERR(clk) ? NULL : clk; 355 adg->clk[i] = IS_ERR(clk) ? NULL : clk;
426 } 356 }
427 357
428 for_each_rsnd_clk(clk, adg, i) 358 for_each_rsnd_clk(clk, adg, i) {
359 ret = clk_prepare_enable(clk);
360 if (ret < 0)
361 dev_warn(dev, "can't use clk %d\n", i);
362
429 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 363 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
364 }
430} 365}
431 366
432static void rsnd_adg_get_clkout(struct rsnd_priv *priv, 367static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
@@ -437,7 +372,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
437 struct device *dev = rsnd_priv_to_dev(priv); 372 struct device *dev = rsnd_priv_to_dev(priv);
438 struct device_node *np = dev->of_node; 373 struct device_node *np = dev->of_node;
439 u32 ckr, rbgx, rbga, rbgb; 374 u32 ckr, rbgx, rbga, rbgb;
440 u32 rate, req_rate, div; 375 u32 rate, req_rate = 0, div;
441 uint32_t count = 0; 376 uint32_t count = 0;
442 unsigned long req_48kHz_rate, req_441kHz_rate; 377 unsigned long req_48kHz_rate, req_441kHz_rate;
443 int i; 378 int i;
@@ -572,9 +507,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
572 ckr, rbga, rbgb); 507 ckr, rbga, rbgb);
573} 508}
574 509
575int rsnd_adg_probe(struct platform_device *pdev, 510int rsnd_adg_probe(struct rsnd_priv *priv)
576 const struct rsnd_of_data *of_data,
577 struct rsnd_priv *priv)
578{ 511{
579 struct rsnd_adg *adg; 512 struct rsnd_adg *adg;
580 struct device *dev = rsnd_priv_to_dev(priv); 513 struct device *dev = rsnd_priv_to_dev(priv);
@@ -600,3 +533,14 @@ int rsnd_adg_probe(struct platform_device *pdev,
600 533
601 return 0; 534 return 0;
602} 535}
536
537void rsnd_adg_remove(struct rsnd_priv *priv)
538{
539 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
540 struct clk *clk;
541 int i;
542
543 for_each_rsnd_clk(clk, adg, i) {
544 clk_disable_unprepare(clk);
545 }
546}
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
new file mode 100644
index 000000000000..cd1f064e63c4
--- /dev/null
+++ b/sound/soc/sh/rcar/cmd.c
@@ -0,0 +1,171 @@
1/*
2 * Renesas R-Car CMD support
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13struct rsnd_cmd {
14 struct rsnd_mod mod;
15};
16
17#define CMD_NAME "cmd"
18
19#define rsnd_cmd_nr(priv) ((priv)->cmd_nr)
20#define for_each_rsnd_cmd(pos, priv, i) \
21 for ((i) = 0; \
22 ((i) < rsnd_cmd_nr(priv)) && \
23 ((pos) = (struct rsnd_cmd *)(priv)->cmd + i); \
24 i++)
25
26static int rsnd_cmd_init(struct rsnd_mod *mod,
27 struct rsnd_dai_stream *io,
28 struct rsnd_priv *priv)
29{
30 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
31 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
32 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
33 struct device *dev = rsnd_priv_to_dev(priv);
34 u32 data;
35
36 if (!mix && !dvc)
37 return 0;
38
39 if (mix) {
40 struct rsnd_dai *rdai;
41 int i;
42 u32 path[] = {
43 [0] = 0,
44 [1] = 1 << 0,
45 [2] = 0,
46 [3] = 0,
47 [4] = 0,
48 [5] = 1 << 8
49 };
50
51 /*
52 * it is assuming that integrater is well understanding about
53 * data path. Here doesn't check impossible connection,
54 * like src2 + src5
55 */
56 data = 0;
57 for_each_rsnd_dai(rdai, priv, i) {
58 io = &rdai->playback;
59 if (mix == rsnd_io_to_mod_mix(io))
60 data |= path[rsnd_mod_id(src)];
61
62 io = &rdai->capture;
63 if (mix == rsnd_io_to_mod_mix(io))
64 data |= path[rsnd_mod_id(src)];
65 }
66
67 } else {
68 u32 path[] = {
69 [0] = 0x30000,
70 [1] = 0x30001,
71 [2] = 0x40000,
72 [3] = 0x10000,
73 [4] = 0x20000,
74 [5] = 0x40100
75 };
76
77 data = path[rsnd_mod_id(src)];
78 }
79
80 dev_dbg(dev, "ctu/mix path = 0x%08x", data);
81
82 rsnd_mod_write(mod, CMD_ROUTE_SLCT, data);
83 rsnd_mod_write(mod, CMD_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
84
85 rsnd_adg_set_cmd_timsel_gen2(mod, io);
86
87 return 0;
88}
89
90static int rsnd_cmd_start(struct rsnd_mod *mod,
91 struct rsnd_dai_stream *io,
92 struct rsnd_priv *priv)
93{
94 rsnd_mod_write(mod, CMD_CTRL, 0x10);
95
96 return 0;
97}
98
99static int rsnd_cmd_stop(struct rsnd_mod *mod,
100 struct rsnd_dai_stream *io,
101 struct rsnd_priv *priv)
102{
103 rsnd_mod_write(mod, CMD_CTRL, 0);
104
105 return 0;
106}
107
108static struct rsnd_mod_ops rsnd_cmd_ops = {
109 .name = CMD_NAME,
110 .init = rsnd_cmd_init,
111 .start = rsnd_cmd_start,
112 .stop = rsnd_cmd_stop,
113};
114
115int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id)
116{
117 struct rsnd_priv *priv = rsnd_io_to_priv(io);
118 struct rsnd_mod *mod = rsnd_cmd_mod_get(priv, id);
119
120 return rsnd_dai_connect(mod, io, mod->type);
121}
122
123struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
124{
125 if (WARN_ON(id < 0 || id >= rsnd_cmd_nr(priv)))
126 id = 0;
127
128 return rsnd_mod_get((struct rsnd_cmd *)(priv->cmd) + id);
129}
130
131int rsnd_cmd_probe(struct rsnd_priv *priv)
132{
133 struct device *dev = rsnd_priv_to_dev(priv);
134 struct rsnd_cmd *cmd;
135 int i, nr, ret;
136
137 /* This driver doesn't support Gen1 at this point */
138 if (rsnd_is_gen1(priv))
139 return 0;
140
141 /* same number as DVC */
142 nr = priv->dvc_nr;
143 if (!nr)
144 return 0;
145
146 cmd = devm_kzalloc(dev, sizeof(*cmd) * nr, GFP_KERNEL);
147 if (!cmd)
148 return -ENOMEM;
149
150 priv->cmd_nr = nr;
151 priv->cmd = cmd;
152
153 for_each_rsnd_cmd(cmd, priv, i) {
154 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd),
155 &rsnd_cmd_ops, NULL, RSND_MOD_CMD, i);
156 if (ret)
157 return ret;
158 }
159
160 return 0;
161}
162
163void rsnd_cmd_remove(struct rsnd_priv *priv)
164{
165 struct rsnd_cmd *cmd;
166 int i;
167
168 for_each_rsnd_cmd(cmd, priv, i) {
169 rsnd_mod_quit(rsnd_mod_get(cmd));
170 }
171}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index deed48ef28b8..02b4b085b8d7 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -99,34 +99,17 @@
99#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
101 101
102static const struct rsnd_of_data rsnd_of_data_gen1 = {
103 .flags = RSND_GEN1,
104};
105
106static const struct rsnd_of_data rsnd_of_data_gen2 = {
107 .flags = RSND_GEN2,
108};
109
110static const struct of_device_id rsnd_of_match[] = { 102static const struct of_device_id rsnd_of_match[] = {
111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 103 { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 },
112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 104 { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 },
113 { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */ 105 { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */
114 {}, 106 {},
115}; 107};
116MODULE_DEVICE_TABLE(of, rsnd_of_match); 108MODULE_DEVICE_TABLE(of, rsnd_of_match);
117 109
118/* 110/*
119 * rsnd_platform functions 111 * rsnd_mod functions
120 */ 112 */
121#define rsnd_platform_call(priv, dai, func, param...) \
122 (!(priv->info->func) ? 0 : \
123 priv->info->func(param))
124
125#define rsnd_is_enable_path(io, name) \
126 ((io)->info ? (io)->info->name : NULL)
127#define rsnd_info_id(priv, io, name) \
128 ((io)->info->name - priv->info->name##_info)
129
130void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) 113void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
131{ 114{
132 if (mod->type != type) { 115 if (mod->type != type) {
@@ -138,9 +121,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
138 } 121 }
139} 122}
140 123
141/*
142 * rsnd_mod functions
143 */
144char *rsnd_mod_name(struct rsnd_mod *mod) 124char *rsnd_mod_name(struct rsnd_mod *mod)
145{ 125{
146 if (!mod || !mod->ops) 126 if (!mod || !mod->ops)
@@ -192,19 +172,16 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod,
192 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 172 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
193 struct rsnd_dai_stream *io; 173 struct rsnd_dai_stream *io;
194 struct rsnd_dai *rdai; 174 struct rsnd_dai *rdai;
195 int i, j; 175 int i;
196
197 for_each_rsnd_dai(rdai, priv, j) {
198 176
199 for (i = 0; i < RSND_MOD_MAX; i++) { 177 for_each_rsnd_dai(rdai, priv, i) {
200 io = &rdai->playback; 178 io = &rdai->playback;
201 if (mod == io->mod[i]) 179 if (mod == io->mod[mod->type])
202 callback(mod, io); 180 callback(mod, io);
203 181
204 io = &rdai->capture; 182 io = &rdai->capture;
205 if (mod == io->mod[i]) 183 if (mod == io->mod[mod->type])
206 callback(mod, io); 184 callback(mod, io);
207 }
208 } 185 }
209} 186}
210 187
@@ -214,6 +191,43 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io)
214 return !!io->substream; 191 return !!io->substream;
215} 192}
216 193
194void rsnd_set_slot(struct rsnd_dai *rdai,
195 int slots, int num)
196{
197 rdai->slots = slots;
198 rdai->slots_num = num;
199}
200
201int rsnd_get_slot(struct rsnd_dai_stream *io)
202{
203 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
204
205 return rdai->slots;
206}
207
208int rsnd_get_slot_num(struct rsnd_dai_stream *io)
209{
210 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
211
212 return rdai->slots_num;
213}
214
215int rsnd_get_slot_width(struct rsnd_dai_stream *io)
216{
217 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
218 int chan = runtime->channels;
219
220 /* Multi channel Mode */
221 if (rsnd_ssi_multi_slaves(io))
222 chan /= rsnd_get_slot_num(io);
223
224 /* TDM Extend Mode needs 8ch */
225 if (chan == 6)
226 chan = 8;
227
228 return chan;
229}
230
217/* 231/*
218 * ADINR function 232 * ADINR function
219 */ 233 */
@@ -222,21 +236,17 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
222 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 236 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
223 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 237 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
224 struct device *dev = rsnd_priv_to_dev(priv); 238 struct device *dev = rsnd_priv_to_dev(priv);
225 u32 adinr = runtime->channels;
226 239
227 switch (runtime->sample_bits) { 240 switch (runtime->sample_bits) {
228 case 16: 241 case 16:
229 adinr |= (8 << 16); 242 return 8 << 16;
230 break;
231 case 32: 243 case 32:
232 adinr |= (0 << 16); 244 return 0 << 16;
233 break;
234 default:
235 dev_warn(dev, "not supported sample bits\n");
236 return 0;
237 } 245 }
238 246
239 return adinr; 247 dev_warn(dev, "not supported sample bits\n");
248
249 return 0;
240} 250}
241 251
242u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io) 252u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
@@ -267,13 +277,22 @@ u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
267 */ 277 */
268u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) 278u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
269{ 279{
270 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
271 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 280 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
272 struct rsnd_mod *target = src ? src : ssi; 281 struct rsnd_mod *target;
273 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 282 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
274 u32 val = 0x76543210; 283 u32 val = 0x76543210;
275 u32 mask = ~0; 284 u32 mask = ~0;
276 285
286 if (rsnd_io_is_play(io)) {
287 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
288
289 target = src ? src : ssi;
290 } else {
291 struct rsnd_mod *cmd = rsnd_io_to_mod_cmd(io);
292
293 target = cmd ? cmd : ssi;
294 }
295
277 mask <<= runtime->channels * 4; 296 mask <<= runtime->channels * 4;
278 val = val & mask; 297 val = val & mask;
279 298
@@ -300,20 +319,22 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
300/* 319/*
301 * rsnd_dai functions 320 * rsnd_dai functions
302 */ 321 */
303#define rsnd_mod_call(mod, io, func, param...) \ 322#define rsnd_mod_call(idx, io, func, param...) \
304({ \ 323({ \
305 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 324 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
325 struct rsnd_mod *mod = (io)->mod[idx]; \
306 struct device *dev = rsnd_priv_to_dev(priv); \ 326 struct device *dev = rsnd_priv_to_dev(priv); \
327 u32 *status = (io)->mod_status + idx; \
307 u32 mask = 0xF << __rsnd_mod_shift_##func; \ 328 u32 mask = 0xF << __rsnd_mod_shift_##func; \
308 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ 329 u8 val = (*status >> __rsnd_mod_shift_##func) & 0xF; \
309 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ 330 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \
310 int ret = 0; \ 331 int ret = 0; \
311 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \ 332 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
312 mod->status = (mod->status & ~mask) + \ 333 *status = (*status & ~mask) + \
313 (add << __rsnd_mod_shift_##func); \ 334 (add << __rsnd_mod_shift_##func); \
314 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \ 335 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \
315 rsnd_mod_name(mod), rsnd_mod_id(mod), \ 336 rsnd_mod_name(mod), rsnd_mod_id(mod), \
316 mod->status, call ? #func : ""); \ 337 *status, call ? #func : ""); \
317 if (call) \ 338 if (call) \
318 ret = (mod)->ops->func(mod, io, param); \ 339 ret = (mod)->ops->func(mod, io, param); \
319 ret; \ 340 ret; \
@@ -327,13 +348,14 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
327 mod = (io)->mod[i]; \ 348 mod = (io)->mod[i]; \
328 if (!mod) \ 349 if (!mod) \
329 continue; \ 350 continue; \
330 ret |= rsnd_mod_call(mod, io, fn, param); \ 351 ret |= rsnd_mod_call(i, io, fn, param); \
331 } \ 352 } \
332 ret; \ 353 ret; \
333}) 354})
334 355
335static int rsnd_dai_connect(struct rsnd_mod *mod, 356int rsnd_dai_connect(struct rsnd_mod *mod,
336 struct rsnd_dai_stream *io) 357 struct rsnd_dai_stream *io,
358 enum rsnd_mod_type type)
337{ 359{
338 struct rsnd_priv *priv; 360 struct rsnd_priv *priv;
339 struct device *dev; 361 struct device *dev;
@@ -341,10 +363,13 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
341 if (!mod) 363 if (!mod)
342 return -EIO; 364 return -EIO;
343 365
366 if (io->mod[type])
367 return -EINVAL;
368
344 priv = rsnd_mod_to_priv(mod); 369 priv = rsnd_mod_to_priv(mod);
345 dev = rsnd_priv_to_dev(priv); 370 dev = rsnd_priv_to_dev(priv);
346 371
347 io->mod[mod->type] = mod; 372 io->mod[type] = mod;
348 373
349 dev_dbg(dev, "%s[%d] is connected to io (%s)\n", 374 dev_dbg(dev, "%s[%d] is connected to io (%s)\n",
350 rsnd_mod_name(mod), rsnd_mod_id(mod), 375 rsnd_mod_name(mod), rsnd_mod_id(mod),
@@ -354,9 +379,10 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
354} 379}
355 380
356static void rsnd_dai_disconnect(struct rsnd_mod *mod, 381static void rsnd_dai_disconnect(struct rsnd_mod *mod,
357 struct rsnd_dai_stream *io) 382 struct rsnd_dai_stream *io,
383 enum rsnd_mod_type type)
358{ 384{
359 io->mod[mod->type] = NULL; 385 io->mod[type] = NULL;
360} 386}
361 387
362struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id) 388struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id)
@@ -469,7 +495,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
469 struct rsnd_priv *priv = rsnd_dai_to_priv(dai); 495 struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
470 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); 496 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
471 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); 497 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
472 int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io));
473 int ret; 498 int ret;
474 unsigned long flags; 499 unsigned long flags;
475 500
@@ -479,10 +504,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
479 case SNDRV_PCM_TRIGGER_START: 504 case SNDRV_PCM_TRIGGER_START:
480 rsnd_dai_stream_init(io, substream); 505 rsnd_dai_stream_init(io, substream);
481 506
482 ret = rsnd_platform_call(priv, dai, start, ssi_id);
483 if (ret < 0)
484 goto dai_trigger_end;
485
486 ret = rsnd_dai_call(init, io, priv); 507 ret = rsnd_dai_call(init, io, priv);
487 if (ret < 0) 508 if (ret < 0)
488 goto dai_trigger_end; 509 goto dai_trigger_end;
@@ -496,8 +517,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
496 517
497 ret |= rsnd_dai_call(quit, io, priv); 518 ret |= rsnd_dai_call(quit, io, priv);
498 519
499 ret |= rsnd_platform_call(priv, dai, stop, ssi_id);
500
501 rsnd_dai_stream_quit(io); 520 rsnd_dai_stream_quit(io);
502 break; 521 break;
503 default: 522 default:
@@ -567,332 +586,157 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
567 return 0; 586 return 0;
568} 587}
569 588
570static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { 589static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
571 .trigger = rsnd_soc_dai_trigger, 590 u32 tx_mask, u32 rx_mask,
572 .set_fmt = rsnd_soc_dai_set_fmt, 591 int slots, int slot_width)
573};
574
575#define rsnd_path_add(priv, io, type) \
576({ \
577 struct rsnd_mod *mod; \
578 int ret = 0; \
579 int id = -1; \
580 \
581 if (rsnd_is_enable_path(io, type)) { \
582 id = rsnd_info_id(priv, io, type); \
583 if (id >= 0) { \
584 mod = rsnd_##type##_mod_get(priv, id); \
585 ret = rsnd_dai_connect(mod, io); \
586 } \
587 } \
588 ret; \
589})
590
591#define rsnd_path_remove(priv, io, type) \
592{ \
593 struct rsnd_mod *mod; \
594 int id = -1; \
595 \
596 if (rsnd_is_enable_path(io, type)) { \
597 id = rsnd_info_id(priv, io, type); \
598 if (id >= 0) { \
599 mod = rsnd_##type##_mod_get(priv, id); \
600 rsnd_dai_disconnect(mod, io); \
601 } \
602 } \
603}
604
605void rsnd_path_parse(struct rsnd_priv *priv,
606 struct rsnd_dai_stream *io)
607{ 592{
608 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 593 struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
609 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); 594 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
610 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
611 struct rsnd_mod *cmd;
612 struct device *dev = rsnd_priv_to_dev(priv); 595 struct device *dev = rsnd_priv_to_dev(priv);
613 u32 data;
614 596
615 /* Gen1 is not supported */ 597 switch (slots) {
616 if (rsnd_is_gen1(priv)) 598 case 6:
617 return; 599 /* TDM Extend Mode */
618 600 rsnd_set_slot(rdai, slots, 1);
619 if (!mix && !dvc) 601 break;
620 return; 602 default:
621 603 dev_err(dev, "unsupported TDM slots (%d)\n", slots);
622 if (mix) { 604 return -EINVAL;
623 struct rsnd_dai *rdai;
624 int i;
625 u32 path[] = {
626 [0] = 0,
627 [1] = 1 << 0,
628 [2] = 0,
629 [3] = 0,
630 [4] = 0,
631 [5] = 1 << 8
632 };
633
634 /*
635 * it is assuming that integrater is well understanding about
636 * data path. Here doesn't check impossible connection,
637 * like src2 + src5
638 */
639 data = 0;
640 for_each_rsnd_dai(rdai, priv, i) {
641 io = &rdai->playback;
642 if (mix == rsnd_io_to_mod_mix(io))
643 data |= path[rsnd_mod_id(src)];
644
645 io = &rdai->capture;
646 if (mix == rsnd_io_to_mod_mix(io))
647 data |= path[rsnd_mod_id(src)];
648 }
649
650 /*
651 * We can't use ctu = rsnd_io_ctu() here.
652 * Since, ID of dvc/mix are 0 or 1 (= same as CMD number)
653 * but ctu IDs are 0 - 7 (= CTU00 - CTU13)
654 */
655 cmd = mix;
656 } else {
657 u32 path[] = {
658 [0] = 0x30000,
659 [1] = 0x30001,
660 [2] = 0x40000,
661 [3] = 0x10000,
662 [4] = 0x20000,
663 [5] = 0x40100
664 };
665
666 data = path[rsnd_mod_id(src)];
667
668 cmd = dvc;
669 } 605 }
670 606
671 dev_dbg(dev, "ctu/mix path = 0x%08x", data); 607 return 0;
672
673 rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
674
675 rsnd_mod_write(cmd, CMD_CTRL, 0x10);
676} 608}
677 609
678static int rsnd_path_init(struct rsnd_priv *priv, 610static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
679 struct rsnd_dai *rdai, 611 .trigger = rsnd_soc_dai_trigger,
680 struct rsnd_dai_stream *io) 612 .set_fmt = rsnd_soc_dai_set_fmt,
681{ 613 .set_tdm_slot = rsnd_soc_set_dai_tdm_slot,
682 int ret; 614};
683
684 /*
685 * Gen1 is created by SRU/SSI, and this SRU is base module of
686 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
687 *
688 * Easy image is..
689 * Gen1 SRU = Gen2 SCU + SSIU + etc
690 *
691 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
692 * using fixed path.
693 */
694
695 /* SSI */
696 ret = rsnd_path_add(priv, io, ssi);
697 if (ret < 0)
698 return ret;
699
700 /* SRC */
701 ret = rsnd_path_add(priv, io, src);
702 if (ret < 0)
703 return ret;
704 615
705 /* CTU */ 616void rsnd_parse_connect_common(struct rsnd_dai *rdai,
706 ret = rsnd_path_add(priv, io, ctu); 617 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
707 if (ret < 0) 618 struct device_node *node,
708 return ret; 619 struct device_node *playback,
620 struct device_node *capture)
621{
622 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
623 struct device_node *np;
624 struct rsnd_mod *mod;
625 int i;
709 626
710 /* MIX */ 627 if (!node)
711 ret = rsnd_path_add(priv, io, mix); 628 return;
712 if (ret < 0)
713 return ret;
714 629
715 /* DVC */ 630 i = 0;
716 ret = rsnd_path_add(priv, io, dvc); 631 for_each_child_of_node(node, np) {
717 if (ret < 0) 632 mod = mod_get(priv, i);
718 return ret; 633 if (np == playback)
634 rsnd_dai_connect(mod, &rdai->playback, mod->type);
635 if (np == capture)
636 rsnd_dai_connect(mod, &rdai->capture, mod->type);
637 i++;
638 }
719 639
720 return ret; 640 of_node_put(node);
721} 641}
722 642
723static void rsnd_of_parse_dai(struct platform_device *pdev, 643static int rsnd_dai_probe(struct rsnd_priv *priv)
724 const struct rsnd_of_data *of_data,
725 struct rsnd_priv *priv)
726{ 644{
727 struct device_node *dai_node, *dai_np; 645 struct device_node *dai_node;
728 struct device_node *ssi_node, *ssi_np; 646 struct device_node *dai_np;
729 struct device_node *src_node, *src_np;
730 struct device_node *ctu_node, *ctu_np;
731 struct device_node *mix_node, *mix_np;
732 struct device_node *dvc_node, *dvc_np;
733 struct device_node *playback, *capture; 647 struct device_node *playback, *capture;
734 struct rsnd_dai_platform_info *dai_info; 648 struct rsnd_dai_stream *io_playback;
735 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 649 struct rsnd_dai_stream *io_capture;
736 struct device *dev = &pdev->dev; 650 struct snd_soc_dai_driver *rdrv, *drv;
737 int nr, i; 651 struct rsnd_dai *rdai;
738 int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i; 652 struct device *dev = rsnd_priv_to_dev(priv);
739 653 int nr, dai_i, io_i;
740 if (!of_data) 654 int ret;
741 return;
742
743 dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai");
744 if (!dai_node)
745 return;
746 655
656 dai_node = rsnd_dai_of_node(priv);
747 nr = of_get_child_count(dai_node); 657 nr = of_get_child_count(dai_node);
748 if (!nr) 658 if (!nr) {
749 return; 659 ret = -EINVAL;
660 goto rsnd_dai_probe_done;
661 }
750 662
751 dai_info = devm_kzalloc(dev, 663 rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL);
752 sizeof(struct rsnd_dai_platform_info) * nr, 664 rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL);
753 GFP_KERNEL); 665 if (!rdrv || !rdai) {
754 if (!dai_info) { 666 ret = -ENOMEM;
755 dev_err(dev, "dai info allocation error\n"); 667 goto rsnd_dai_probe_done;
756 return;
757 } 668 }
758 669
759 info->dai_info_nr = nr; 670 priv->rdai_nr = nr;
760 info->dai_info = dai_info; 671 priv->daidrv = rdrv;
761 672 priv->rdai = rdai;
762 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
763 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
764 ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
765 mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
766 dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
767
768#define mod_parse(name) \
769if (name##_node) { \
770 struct rsnd_##name##_platform_info *name##_info; \
771 \
772 name##_i = 0; \
773 for_each_child_of_node(name##_node, name##_np) { \
774 name##_info = info->name##_info + name##_i; \
775 \
776 if (name##_np == playback) \
777 dai_info->playback.name = name##_info; \
778 if (name##_np == capture) \
779 dai_info->capture.name = name##_info; \
780 \
781 name##_i++; \
782 } \
783}
784 673
785 /* 674 /*
786 * parse all dai 675 * parse all dai
787 */ 676 */
788 dai_i = 0; 677 dai_i = 0;
789 for_each_child_of_node(dai_node, dai_np) { 678 for_each_child_of_node(dai_node, dai_np) {
790 dai_info = info->dai_info + dai_i; 679 rdai = rsnd_rdai_get(priv, dai_i);
791 680 drv = rdrv + dai_i;
792 for (i = 0;; i++) { 681 io_playback = &rdai->playback;
793 682 io_capture = &rdai->capture;
794 playback = of_parse_phandle(dai_np, "playback", i); 683
795 capture = of_parse_phandle(dai_np, "capture", i); 684 snprintf(rdai->name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", dai_i);
685
686 rdai->priv = priv;
687 drv->name = rdai->name;
688 drv->ops = &rsnd_soc_dai_ops;
689
690 snprintf(rdai->playback.name, RSND_DAI_NAME_SIZE,
691 "DAI%d Playback", dai_i);
692 drv->playback.rates = RSND_RATES;
693 drv->playback.formats = RSND_FMTS;
694 drv->playback.channels_min = 2;
695 drv->playback.channels_max = 6;
696 drv->playback.stream_name = rdai->playback.name;
697
698 snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE,
699 "DAI%d Capture", dai_i);
700 drv->capture.rates = RSND_RATES;
701 drv->capture.formats = RSND_FMTS;
702 drv->capture.channels_min = 2;
703 drv->capture.channels_max = 6;
704 drv->capture.stream_name = rdai->capture.name;
705
706 rdai->playback.rdai = rdai;
707 rdai->capture.rdai = rdai;
708 rsnd_set_slot(rdai, 2, 1); /* default */
709
710 for (io_i = 0;; io_i++) {
711 playback = of_parse_phandle(dai_np, "playback", io_i);
712 capture = of_parse_phandle(dai_np, "capture", io_i);
796 713
797 if (!playback && !capture) 714 if (!playback && !capture)
798 break; 715 break;
799 716
800 mod_parse(ssi); 717 rsnd_parse_connect_ssi(rdai, playback, capture);
801 mod_parse(src); 718 rsnd_parse_connect_src(rdai, playback, capture);
802 mod_parse(ctu); 719 rsnd_parse_connect_ctu(rdai, playback, capture);
803 mod_parse(mix); 720 rsnd_parse_connect_mix(rdai, playback, capture);
804 mod_parse(dvc); 721 rsnd_parse_connect_dvc(rdai, playback, capture);
805 722
806 of_node_put(playback); 723 of_node_put(playback);
807 of_node_put(capture); 724 of_node_put(capture);
808 } 725 }
809 726
810 dai_i++; 727 dai_i++;
811 }
812}
813
814static int rsnd_dai_probe(struct platform_device *pdev,
815 const struct rsnd_of_data *of_data,
816 struct rsnd_priv *priv)
817{
818 struct snd_soc_dai_driver *drv;
819 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
820 struct rsnd_dai *rdai;
821 struct rsnd_ssi_platform_info *pmod, *cmod;
822 struct device *dev = rsnd_priv_to_dev(priv);
823 int dai_nr;
824 int i;
825
826 rsnd_of_parse_dai(pdev, of_data, priv);
827 728
828 dai_nr = info->dai_info_nr; 729 dev_dbg(dev, "%s (%s/%s)\n", rdai->name,
829 if (!dai_nr) { 730 rsnd_io_to_mod_ssi(io_playback) ? "play" : " -- ",
830 dev_err(dev, "no dai\n"); 731 rsnd_io_to_mod_ssi(io_capture) ? "capture" : " -- ");
831 return -EIO;
832 } 732 }
833 733
834 drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); 734 ret = 0;
835 rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL);
836 if (!drv || !rdai) {
837 dev_err(dev, "dai allocate failed\n");
838 return -ENOMEM;
839 }
840
841 priv->rdai_nr = dai_nr;
842 priv->daidrv = drv;
843 priv->rdai = rdai;
844 735
845 for (i = 0; i < dai_nr; i++) { 736rsnd_dai_probe_done:
737 of_node_put(dai_node);
846 738
847 pmod = info->dai_info[i].playback.ssi; 739 return ret;
848 cmod = info->dai_info[i].capture.ssi;
849
850 /*
851 * init rsnd_dai
852 */
853 snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
854 rdai[i].priv = priv;
855
856 /*
857 * init snd_soc_dai_driver
858 */
859 drv[i].name = rdai[i].name;
860 drv[i].ops = &rsnd_soc_dai_ops;
861 if (pmod) {
862 snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
863 "DAI%d Playback", i);
864
865 drv[i].playback.rates = RSND_RATES;
866 drv[i].playback.formats = RSND_FMTS;
867 drv[i].playback.channels_min = 2;
868 drv[i].playback.channels_max = 2;
869 drv[i].playback.stream_name = rdai[i].playback.name;
870
871 rdai[i].playback.info = &info->dai_info[i].playback;
872 rdai[i].playback.rdai = rdai + i;
873 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
874 }
875 if (cmod) {
876 snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
877 "DAI%d Capture", i);
878
879 drv[i].capture.rates = RSND_RATES;
880 drv[i].capture.formats = RSND_FMTS;
881 drv[i].capture.channels_min = 2;
882 drv[i].capture.channels_max = 2;
883 drv[i].capture.stream_name = rdai[i].capture.name;
884
885 rdai[i].capture.info = &info->dai_info[i].capture;
886 rdai[i].capture.rdai = rdai + i;
887 rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
888 }
889
890 dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
891 pmod ? "play" : " -- ",
892 cmod ? "capture" : " -- ");
893 }
894
895 return 0;
896} 740}
897 741
898/* 742/*
@@ -1033,14 +877,13 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1033 void (*update)(struct rsnd_dai_stream *io, 877 void (*update)(struct rsnd_dai_stream *io,
1034 struct rsnd_mod *mod)) 878 struct rsnd_mod *mod))
1035{ 879{
1036 struct snd_soc_card *soc_card = rtd->card;
1037 struct snd_card *card = rtd->card->snd_card; 880 struct snd_card *card = rtd->card->snd_card;
1038 struct snd_kcontrol *kctrl; 881 struct snd_kcontrol *kctrl;
1039 struct snd_kcontrol_new knew = { 882 struct snd_kcontrol_new knew = {
1040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1041 .name = name, 884 .name = name,
1042 .info = rsnd_kctrl_info, 885 .info = rsnd_kctrl_info,
1043 .index = rtd - soc_card->rtd, 886 .index = rtd->num,
1044 .get = rsnd_kctrl_get, 887 .get = rsnd_kctrl_get,
1045 .put = rsnd_kctrl_put, 888 .put = rsnd_kctrl_put,
1046 .private_value = (unsigned long)cfg, 889 .private_value = (unsigned long)cfg,
@@ -1077,10 +920,14 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod,
1077 void (*update)(struct rsnd_dai_stream *io, 920 void (*update)(struct rsnd_dai_stream *io,
1078 struct rsnd_mod *mod), 921 struct rsnd_mod *mod),
1079 struct rsnd_kctrl_cfg_m *_cfg, 922 struct rsnd_kctrl_cfg_m *_cfg,
923 int ch_size,
1080 u32 max) 924 u32 max)
1081{ 925{
926 if (ch_size > RSND_DVC_CHANNELS)
927 return -EINVAL;
928
1082 _cfg->cfg.max = max; 929 _cfg->cfg.max = max;
1083 _cfg->cfg.size = RSND_DVC_CHANNELS; 930 _cfg->cfg.size = ch_size;
1084 _cfg->cfg.val = _cfg->val; 931 _cfg->cfg.val = _cfg->val;
1085 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update); 932 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1086} 933}
@@ -1161,6 +1008,9 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1161 1008
1162 ret = rsnd_dai_call(probe, io, priv); 1009 ret = rsnd_dai_call(probe, io, priv);
1163 if (ret == -EAGAIN) { 1010 if (ret == -EAGAIN) {
1011 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
1012 int i;
1013
1164 /* 1014 /*
1165 * Fallback to PIO mode 1015 * Fallback to PIO mode
1166 */ 1016 */
@@ -1175,10 +1025,12 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1175 rsnd_dai_call(remove, io, priv); 1025 rsnd_dai_call(remove, io, priv);
1176 1026
1177 /* 1027 /*
1178 * remove SRC/DVC from DAI, 1028 * remove all mod from io
1029 * and, re connect ssi
1179 */ 1030 */
1180 rsnd_path_remove(priv, io, src); 1031 for (i = 0; i < RSND_MOD_MAX; i++)
1181 rsnd_path_remove(priv, io, dvc); 1032 rsnd_dai_disconnect((io)->mod[i], io, i);
1033 rsnd_dai_connect(ssi_mod, io, RSND_MOD_SSI);
1182 1034
1183 /* 1035 /*
1184 * fallback 1036 * fallback
@@ -1200,33 +1052,25 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv,
1200 */ 1052 */
1201static int rsnd_probe(struct platform_device *pdev) 1053static int rsnd_probe(struct platform_device *pdev)
1202{ 1054{
1203 struct rcar_snd_info *info;
1204 struct rsnd_priv *priv; 1055 struct rsnd_priv *priv;
1205 struct device *dev = &pdev->dev; 1056 struct device *dev = &pdev->dev;
1206 struct rsnd_dai *rdai; 1057 struct rsnd_dai *rdai;
1207 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); 1058 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev);
1208 const struct rsnd_of_data *of_data; 1059 int (*probe_func[])(struct rsnd_priv *priv) = {
1209 int (*probe_func[])(struct platform_device *pdev,
1210 const struct rsnd_of_data *of_data,
1211 struct rsnd_priv *priv) = {
1212 rsnd_gen_probe, 1060 rsnd_gen_probe,
1213 rsnd_dma_probe, 1061 rsnd_dma_probe,
1214 rsnd_ssi_probe, 1062 rsnd_ssi_probe,
1063 rsnd_ssiu_probe,
1215 rsnd_src_probe, 1064 rsnd_src_probe,
1216 rsnd_ctu_probe, 1065 rsnd_ctu_probe,
1217 rsnd_mix_probe, 1066 rsnd_mix_probe,
1218 rsnd_dvc_probe, 1067 rsnd_dvc_probe,
1068 rsnd_cmd_probe,
1219 rsnd_adg_probe, 1069 rsnd_adg_probe,
1220 rsnd_dai_probe, 1070 rsnd_dai_probe,
1221 }; 1071 };
1222 int ret, i; 1072 int ret, i;
1223 1073
1224 info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info),
1225 GFP_KERNEL);
1226 if (!info)
1227 return -ENOMEM;
1228 of_data = of_id->data;
1229
1230 /* 1074 /*
1231 * init priv data 1075 * init priv data
1232 */ 1076 */
@@ -1237,14 +1081,14 @@ static int rsnd_probe(struct platform_device *pdev)
1237 } 1081 }
1238 1082
1239 priv->pdev = pdev; 1083 priv->pdev = pdev;
1240 priv->info = info; 1084 priv->flags = (unsigned long)of_id->data;
1241 spin_lock_init(&priv->lock); 1085 spin_lock_init(&priv->lock);
1242 1086
1243 /* 1087 /*
1244 * init each module 1088 * init each module
1245 */ 1089 */
1246 for (i = 0; i < ARRAY_SIZE(probe_func); i++) { 1090 for (i = 0; i < ARRAY_SIZE(probe_func); i++) {
1247 ret = probe_func[i](pdev, of_data, priv); 1091 ret = probe_func[i](priv);
1248 if (ret) 1092 if (ret)
1249 return ret; 1093 return ret;
1250 } 1094 }
@@ -1297,13 +1141,15 @@ static int rsnd_remove(struct platform_device *pdev)
1297{ 1141{
1298 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 1142 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
1299 struct rsnd_dai *rdai; 1143 struct rsnd_dai *rdai;
1300 void (*remove_func[])(struct platform_device *pdev, 1144 void (*remove_func[])(struct rsnd_priv *priv) = {
1301 struct rsnd_priv *priv) = {
1302 rsnd_ssi_remove, 1145 rsnd_ssi_remove,
1146 rsnd_ssiu_remove,
1303 rsnd_src_remove, 1147 rsnd_src_remove,
1304 rsnd_ctu_remove, 1148 rsnd_ctu_remove,
1305 rsnd_mix_remove, 1149 rsnd_mix_remove,
1306 rsnd_dvc_remove, 1150 rsnd_dvc_remove,
1151 rsnd_cmd_remove,
1152 rsnd_adg_remove,
1307 }; 1153 };
1308 int ret = 0, i; 1154 int ret = 0, i;
1309 1155
@@ -1315,7 +1161,7 @@ static int rsnd_remove(struct platform_device *pdev)
1315 } 1161 }
1316 1162
1317 for (i = 0; i < ARRAY_SIZE(remove_func); i++) 1163 for (i = 0; i < ARRAY_SIZE(remove_func); i++)
1318 remove_func[i](pdev, priv); 1164 remove_func[i](priv);
1319 1165
1320 snd_soc_unregister_component(&pdev->dev); 1166 snd_soc_unregister_component(&pdev->dev);
1321 snd_soc_unregister_platform(&pdev->dev); 1167 snd_soc_unregister_platform(&pdev->dev);
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 3cb214ab848b..d53a225d19e9 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -13,7 +13,6 @@
13#define CTU_NAME "ctu" 13#define CTU_NAME "ctu"
14 14
15struct rsnd_ctu { 15struct rsnd_ctu {
16 struct rsnd_ctu_platform_info *info; /* rcar_snd.h */
17 struct rsnd_mod mod; 16 struct rsnd_mod mod;
18}; 17};
19 18
@@ -24,6 +23,7 @@ struct rsnd_ctu {
24 ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \ 23 ((pos) = (struct rsnd_ctu *)(priv)->ctu + i); \
25 i++) 24 i++)
26 25
26#define rsnd_ctu_get(priv, id) ((struct rsnd_ctu *)(priv->ctu) + id)
27#define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1) 27#define rsnd_ctu_initialize_lock(mod) __rsnd_ctu_initialize_lock(mod, 1)
28#define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0) 28#define rsnd_ctu_initialize_unlock(mod) __rsnd_ctu_initialize_lock(mod, 0)
29static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable) 29static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
@@ -31,6 +31,13 @@ static void __rsnd_ctu_initialize_lock(struct rsnd_mod *mod, u32 enable)
31 rsnd_mod_write(mod, CTU_CTUIR, enable); 31 rsnd_mod_write(mod, CTU_CTUIR, enable);
32} 32}
33 33
34static int rsnd_ctu_probe_(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv)
37{
38 return rsnd_cmd_attach(io, rsnd_mod_id(mod) / 4);
39}
40
34static int rsnd_ctu_init(struct rsnd_mod *mod, 41static int rsnd_ctu_init(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io, 42 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv) 43 struct rsnd_priv *priv)
@@ -57,6 +64,7 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod,
57 64
58static struct rsnd_mod_ops rsnd_ctu_ops = { 65static struct rsnd_mod_ops rsnd_ctu_ops = {
59 .name = CTU_NAME, 66 .name = CTU_NAME,
67 .probe = rsnd_ctu_probe_,
60 .init = rsnd_ctu_init, 68 .init = rsnd_ctu_init,
61 .quit = rsnd_ctu_quit, 69 .quit = rsnd_ctu_quit,
62}; 70};
@@ -66,51 +74,13 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) 74 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
67 id = 0; 75 id = 0;
68 76
69 return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id); 77 return rsnd_mod_get(rsnd_ctu_get(priv, id));
70} 78}
71 79
72static void rsnd_of_parse_ctu(struct platform_device *pdev, 80int rsnd_ctu_probe(struct rsnd_priv *priv)
73 const struct rsnd_of_data *of_data,
74 struct rsnd_priv *priv)
75{ 81{
76 struct device_node *node; 82 struct device_node *node;
77 struct rsnd_ctu_platform_info *ctu_info; 83 struct device_node *np;
78 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
79 struct device *dev = &pdev->dev;
80 int nr;
81
82 if (!of_data)
83 return;
84
85 node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
86 if (!node)
87 return;
88
89 nr = of_get_child_count(node);
90 if (!nr)
91 goto rsnd_of_parse_ctu_end;
92
93 ctu_info = devm_kzalloc(dev,
94 sizeof(struct rsnd_ctu_platform_info) * nr,
95 GFP_KERNEL);
96 if (!ctu_info) {
97 dev_err(dev, "ctu info allocation error\n");
98 goto rsnd_of_parse_ctu_end;
99 }
100
101 info->ctu_info = ctu_info;
102 info->ctu_info_nr = nr;
103
104rsnd_of_parse_ctu_end:
105 of_node_put(node);
106
107}
108
109int rsnd_ctu_probe(struct platform_device *pdev,
110 const struct rsnd_of_data *of_data,
111 struct rsnd_priv *priv)
112{
113 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
114 struct device *dev = rsnd_priv_to_dev(priv); 84 struct device *dev = rsnd_priv_to_dev(priv);
115 struct rsnd_ctu *ctu; 85 struct rsnd_ctu *ctu;
116 struct clk *clk; 86 struct clk *clk;
@@ -121,20 +91,30 @@ int rsnd_ctu_probe(struct platform_device *pdev,
121 if (rsnd_is_gen1(priv)) 91 if (rsnd_is_gen1(priv))
122 return 0; 92 return 0;
123 93
124 rsnd_of_parse_ctu(pdev, of_data, priv); 94 node = rsnd_ctu_of_node(priv);
95 if (!node)
96 return 0; /* not used is not error */
125 97
126 nr = info->ctu_info_nr; 98 nr = of_get_child_count(node);
127 if (!nr) 99 if (!nr) {
128 return 0; 100 ret = -EINVAL;
101 goto rsnd_ctu_probe_done;
102 }
129 103
130 ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL); 104 ctu = devm_kzalloc(dev, sizeof(*ctu) * nr, GFP_KERNEL);
131 if (!ctu) 105 if (!ctu) {
132 return -ENOMEM; 106 ret = -ENOMEM;
107 goto rsnd_ctu_probe_done;
108 }
133 109
134 priv->ctu_nr = nr; 110 priv->ctu_nr = nr;
135 priv->ctu = ctu; 111 priv->ctu = ctu;
136 112
137 for_each_rsnd_ctu(ctu, priv, i) { 113 i = 0;
114 ret = 0;
115 for_each_child_of_node(node, np) {
116 ctu = rsnd_ctu_get(priv, i);
117
138 /* 118 /*
139 * CTU00, CTU01, CTU02, CTU03 => CTU0 119 * CTU00, CTU01, CTU02, CTU03 => CTU0
140 * CTU10, CTU11, CTU12, CTU13 => CTU1 120 * CTU10, CTU11, CTU12, CTU13 => CTU1
@@ -143,22 +123,27 @@ int rsnd_ctu_probe(struct platform_device *pdev,
143 CTU_NAME, i / 4); 123 CTU_NAME, i / 4);
144 124
145 clk = devm_clk_get(dev, name); 125 clk = devm_clk_get(dev, name);
146 if (IS_ERR(clk)) 126 if (IS_ERR(clk)) {
147 return PTR_ERR(clk); 127 ret = PTR_ERR(clk);
148 128 goto rsnd_ctu_probe_done;
149 ctu->info = &info->ctu_info[i]; 129 }
150 130
151 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, 131 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
152 clk, RSND_MOD_CTU, i); 132 clk, RSND_MOD_CTU, i);
153 if (ret) 133 if (ret)
154 return ret; 134 goto rsnd_ctu_probe_done;
135
136 i++;
155 } 137 }
156 138
157 return 0; 139
140rsnd_ctu_probe_done:
141 of_node_put(node);
142
143 return ret;
158} 144}
159 145
160void rsnd_ctu_remove(struct platform_device *pdev, 146void rsnd_ctu_remove(struct rsnd_priv *priv)
161 struct rsnd_priv *priv)
162{ 147{
163 struct rsnd_ctu *ctu; 148 struct rsnd_ctu *ctu;
164 int i; 149 int i;
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 5d084d040961..418e6fdd06a3 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -22,21 +22,36 @@
22/* PDMACHCR */ 22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0) 23#define PDMACHCR_DE (1 << 0)
24 24
25
26struct rsnd_dmaen {
27 struct dma_chan *chan;
28};
29
30struct rsnd_dmapp {
31 int dmapp_id;
32 u32 chcr;
33};
34
35struct rsnd_dma {
36 struct rsnd_mod mod;
37 dma_addr_t src_addr;
38 dma_addr_t dst_addr;
39 union {
40 struct rsnd_dmaen en;
41 struct rsnd_dmapp pp;
42 } dma;
43};
44
25struct rsnd_dma_ctrl { 45struct rsnd_dma_ctrl {
26 void __iomem *base; 46 void __iomem *base;
47 int dmaen_num;
27 int dmapp_num; 48 int dmapp_num;
28}; 49};
29 50
30struct rsnd_dma_ops {
31 char *name;
32 void (*start)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
33 void (*stop)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
34 int (*init)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
35 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
36 void (*quit)(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
37};
38
39#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma) 51#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
52#define rsnd_mod_to_dma(_mod) container_of((_mod), struct rsnd_dma, mod)
53#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
54#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
40 55
41/* 56/*
42 * Audio DMAC 57 * Audio DMAC
@@ -77,18 +92,24 @@ static void rsnd_dmaen_complete(void *data)
77 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete); 92 rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
78} 93}
79 94
80static void rsnd_dmaen_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 95static int rsnd_dmaen_stop(struct rsnd_mod *mod,
96 struct rsnd_dai_stream *io,
97 struct rsnd_priv *priv)
81{ 98{
99 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
82 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 100 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
83 101
84 dmaengine_terminate_all(dmaen->chan); 102 dmaengine_terminate_all(dmaen->chan);
103
104 return 0;
85} 105}
86 106
87static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 107static int rsnd_dmaen_start(struct rsnd_mod *mod,
108 struct rsnd_dai_stream *io,
109 struct rsnd_priv *priv)
88{ 110{
111 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
89 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 112 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
90 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
91 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
92 struct snd_pcm_substream *substream = io->substream; 113 struct snd_pcm_substream *substream = io->substream;
93 struct device *dev = rsnd_priv_to_dev(priv); 114 struct device *dev = rsnd_priv_to_dev(priv);
94 struct dma_async_tx_descriptor *desc; 115 struct dma_async_tx_descriptor *desc;
@@ -103,18 +124,20 @@ static void rsnd_dmaen_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
103 124
104 if (!desc) { 125 if (!desc) {
105 dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); 126 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
106 return; 127 return -EIO;
107 } 128 }
108 129
109 desc->callback = rsnd_dmaen_complete; 130 desc->callback = rsnd_dmaen_complete;
110 desc->callback_param = mod; 131 desc->callback_param = rsnd_mod_get(dma);
111 132
112 if (dmaengine_submit(desc) < 0) { 133 if (dmaengine_submit(desc) < 0) {
113 dev_err(dev, "dmaengine_submit() fail\n"); 134 dev_err(dev, "dmaengine_submit() fail\n");
114 return; 135 return -EIO;
115 } 136 }
116 137
117 dma_async_issue_pending(dmaen->chan); 138 dma_async_issue_pending(dmaen->chan);
139
140 return 0;
118} 141}
119 142
120struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 143struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
@@ -152,12 +175,29 @@ static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
152 return rsnd_mod_dma_req(io, mod_to); 175 return rsnd_mod_dma_req(io, mod_to);
153} 176}
154 177
155static int rsnd_dmaen_init(struct rsnd_dai_stream *io, 178static int rsnd_dmaen_remove(struct rsnd_mod *mod,
179 struct rsnd_dai_stream *io,
180 struct rsnd_priv *priv)
181{
182 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
183 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
184
185 if (dmaen->chan)
186 dma_release_channel(dmaen->chan);
187
188 dmaen->chan = NULL;
189
190 return 0;
191}
192
193static int rsnd_dmaen_attach(struct rsnd_dai_stream *io,
156 struct rsnd_dma *dma, int id, 194 struct rsnd_dma *dma, int id,
157 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 195 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
158{ 196{
197 struct rsnd_mod *mod = rsnd_mod_get(dma);
159 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); 198 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
160 struct rsnd_priv *priv = rsnd_io_to_priv(io); 199 struct rsnd_priv *priv = rsnd_io_to_priv(io);
200 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
161 struct device *dev = rsnd_priv_to_dev(priv); 201 struct device *dev = rsnd_priv_to_dev(priv);
162 struct dma_slave_config cfg = {}; 202 struct dma_slave_config cfg = {};
163 int is_play = rsnd_io_is_play(io); 203 int is_play = rsnd_io_is_play(io);
@@ -191,18 +231,20 @@ static int rsnd_dmaen_init(struct rsnd_dai_stream *io,
191 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 231 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
192 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 232 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
193 233
194 dev_dbg(dev, "%s %pad -> %pad\n", 234 dev_dbg(dev, "%s[%d] %pad -> %pad\n",
195 dma->ops->name, 235 rsnd_mod_name(mod), rsnd_mod_id(mod),
196 &cfg.src_addr, &cfg.dst_addr); 236 &cfg.src_addr, &cfg.dst_addr);
197 237
198 ret = dmaengine_slave_config(dmaen->chan, &cfg); 238 ret = dmaengine_slave_config(dmaen->chan, &cfg);
199 if (ret < 0) 239 if (ret < 0)
200 goto rsnd_dma_init_err; 240 goto rsnd_dma_attach_err;
241
242 dmac->dmaen_num++;
201 243
202 return 0; 244 return 0;
203 245
204rsnd_dma_init_err: 246rsnd_dma_attach_err:
205 rsnd_dma_quit(io, dma); 247 rsnd_dmaen_remove(mod, io, priv);
206rsnd_dma_channel_err: 248rsnd_dma_channel_err:
207 249
208 /* 250 /*
@@ -214,22 +256,11 @@ rsnd_dma_channel_err:
214 return -EAGAIN; 256 return -EAGAIN;
215} 257}
216 258
217static void rsnd_dmaen_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 259static struct rsnd_mod_ops rsnd_dmaen_ops = {
218{
219 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
220
221 if (dmaen->chan)
222 dma_release_channel(dmaen->chan);
223
224 dmaen->chan = NULL;
225}
226
227static struct rsnd_dma_ops rsnd_dmaen_ops = {
228 .name = "audmac", 260 .name = "audmac",
229 .start = rsnd_dmaen_start, 261 .start = rsnd_dmaen_start,
230 .stop = rsnd_dmaen_stop, 262 .stop = rsnd_dmaen_stop,
231 .init = rsnd_dmaen_init, 263 .remove = rsnd_dmaen_remove,
232 .quit = rsnd_dmaen_quit,
233}; 264};
234 265
235/* 266/*
@@ -307,7 +338,7 @@ static u32 rsnd_dmapp_get_chcr(struct rsnd_dai_stream *io,
307 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id)) 338 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
308static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) 339static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
309{ 340{
310 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 341 struct rsnd_mod *mod = rsnd_mod_get(dma);
311 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 342 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
312 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 343 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
313 struct device *dev = rsnd_priv_to_dev(priv); 344 struct device *dev = rsnd_priv_to_dev(priv);
@@ -319,38 +350,48 @@ static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
319 350
320static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) 351static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
321{ 352{
322 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 353 struct rsnd_mod *mod = rsnd_mod_get(dma);
323 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 354 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
324 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 355 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
325 356
326 return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); 357 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
327} 358}
328 359
329static void rsnd_dmapp_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 360static int rsnd_dmapp_stop(struct rsnd_mod *mod,
361 struct rsnd_dai_stream *io,
362 struct rsnd_priv *priv)
330{ 363{
364 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
331 int i; 365 int i;
332 366
333 rsnd_dmapp_write(dma, 0, PDMACHCR); 367 rsnd_dmapp_write(dma, 0, PDMACHCR);
334 368
335 for (i = 0; i < 1024; i++) { 369 for (i = 0; i < 1024; i++) {
336 if (0 == rsnd_dmapp_read(dma, PDMACHCR)) 370 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
337 return; 371 return 0;
338 udelay(1); 372 udelay(1);
339 } 373 }
374
375 return -EIO;
340} 376}
341 377
342static void rsnd_dmapp_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 378static int rsnd_dmapp_start(struct rsnd_mod *mod,
379 struct rsnd_dai_stream *io,
380 struct rsnd_priv *priv)
343{ 381{
382 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
344 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 383 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
345 384
346 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); 385 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
347 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); 386 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
348 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); 387 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
388
389 return 0;
349} 390}
350 391
351static int rsnd_dmapp_init(struct rsnd_dai_stream *io, 392static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
352 struct rsnd_dma *dma, int id, 393 struct rsnd_dma *dma, int id,
353 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to) 394 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
354{ 395{
355 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); 396 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
356 struct rsnd_priv *priv = rsnd_io_to_priv(io); 397 struct rsnd_priv *priv = rsnd_io_to_priv(io);
@@ -362,19 +403,16 @@ static int rsnd_dmapp_init(struct rsnd_dai_stream *io,
362 403
363 dmac->dmapp_num++; 404 dmac->dmapp_num++;
364 405
365 rsnd_dmapp_stop(io, dma);
366
367 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n", 406 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
368 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); 407 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
369 408
370 return 0; 409 return 0;
371} 410}
372 411
373static struct rsnd_dma_ops rsnd_dmapp_ops = { 412static struct rsnd_mod_ops rsnd_dmapp_ops = {
374 .name = "audmac-pp", 413 .name = "audmac-pp",
375 .start = rsnd_dmapp_start, 414 .start = rsnd_dmapp_start,
376 .stop = rsnd_dmapp_stop, 415 .stop = rsnd_dmapp_stop,
377 .init = rsnd_dmapp_init,
378 .quit = rsnd_dmapp_stop, 416 .quit = rsnd_dmapp_stop,
379}; 417};
380 418
@@ -497,13 +535,12 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io,
497} 535}
498 536
499#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */ 537#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
500static void rsnd_dma_of_path(struct rsnd_dma *dma, 538static void rsnd_dma_of_path(struct rsnd_mod *this,
501 struct rsnd_dai_stream *io, 539 struct rsnd_dai_stream *io,
502 int is_play, 540 int is_play,
503 struct rsnd_mod **mod_from, 541 struct rsnd_mod **mod_from,
504 struct rsnd_mod **mod_to) 542 struct rsnd_mod **mod_to)
505{ 543{
506 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
507 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 544 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
508 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 545 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
509 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io); 546 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
@@ -513,7 +550,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
513 struct rsnd_mod *mod_start, *mod_end; 550 struct rsnd_mod *mod_start, *mod_end;
514 struct rsnd_priv *priv = rsnd_mod_to_priv(this); 551 struct rsnd_priv *priv = rsnd_mod_to_priv(this);
515 struct device *dev = rsnd_priv_to_dev(priv); 552 struct device *dev = rsnd_priv_to_dev(priv);
516 int nr, i; 553 int nr, i, idx;
517 554
518 if (!ssi) 555 if (!ssi)
519 return; 556 return;
@@ -542,23 +579,24 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
542 mod_start = (is_play) ? NULL : ssi; 579 mod_start = (is_play) ? NULL : ssi;
543 mod_end = (is_play) ? ssi : NULL; 580 mod_end = (is_play) ? ssi : NULL;
544 581
545 mod[0] = mod_start; 582 idx = 0;
583 mod[idx++] = mod_start;
546 for (i = 1; i < nr; i++) { 584 for (i = 1; i < nr; i++) {
547 if (src) { 585 if (src) {
548 mod[i] = src; 586 mod[idx++] = src;
549 src = NULL; 587 src = NULL;
550 } else if (ctu) { 588 } else if (ctu) {
551 mod[i] = ctu; 589 mod[idx++] = ctu;
552 ctu = NULL; 590 ctu = NULL;
553 } else if (mix) { 591 } else if (mix) {
554 mod[i] = mix; 592 mod[idx++] = mix;
555 mix = NULL; 593 mix = NULL;
556 } else if (dvc) { 594 } else if (dvc) {
557 mod[i] = dvc; 595 mod[idx++] = dvc;
558 dvc = NULL; 596 dvc = NULL;
559 } 597 }
560 } 598 }
561 mod[i] = mod_end; 599 mod[idx] = mod_end;
562 600
563 /* 601 /*
564 * | SSI | SRC | 602 * | SSI | SRC |
@@ -567,8 +605,8 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
567 * !is_play | * | o | 605 * !is_play | * | o |
568 */ 606 */
569 if ((this == ssi) == (is_play)) { 607 if ((this == ssi) == (is_play)) {
570 *mod_from = mod[nr - 1]; 608 *mod_from = mod[idx - 1];
571 *mod_to = mod[nr]; 609 *mod_to = mod[idx];
572 } else { 610 } else {
573 *mod_from = mod[0]; 611 *mod_from = mod[0];
574 *mod_to = mod[1]; 612 *mod_to = mod[1];
@@ -576,7 +614,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
576 614
577 dev_dbg(dev, "module connection (this is %s[%d])\n", 615 dev_dbg(dev, "module connection (this is %s[%d])\n",
578 rsnd_mod_name(this), rsnd_mod_id(this)); 616 rsnd_mod_name(this), rsnd_mod_id(this));
579 for (i = 0; i <= nr; i++) { 617 for (i = 0; i <= idx; i++) {
580 dev_dbg(dev, " %s[%d]%s\n", 618 dev_dbg(dev, " %s[%d]%s\n",
581 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]), 619 rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]),
582 (mod[i] == *mod_from) ? " from" : 620 (mod[i] == *mod_from) ? " from" :
@@ -584,36 +622,22 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
584 } 622 }
585} 623}
586 624
587void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma) 625struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
588{ 626 struct rsnd_mod *mod, int id)
589 dma->ops->stop(io, dma);
590}
591
592void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
593{
594 dma->ops->start(io, dma);
595}
596
597void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma)
598{
599 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
600 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
601 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
602
603 if (!dmac)
604 return;
605
606 dma->ops->quit(io, dma);
607}
608
609int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
610{ 627{
628 struct rsnd_mod *dma_mod;
611 struct rsnd_mod *mod_from = NULL; 629 struct rsnd_mod *mod_from = NULL;
612 struct rsnd_mod *mod_to = NULL; 630 struct rsnd_mod *mod_to = NULL;
613 struct rsnd_priv *priv = rsnd_io_to_priv(io); 631 struct rsnd_priv *priv = rsnd_io_to_priv(io);
614 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); 632 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
633 struct rsnd_dma *dma;
615 struct device *dev = rsnd_priv_to_dev(priv); 634 struct device *dev = rsnd_priv_to_dev(priv);
635 struct rsnd_mod_ops *ops;
636 enum rsnd_mod_type type;
637 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id,
638 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
616 int is_play = rsnd_io_is_play(io); 639 int is_play = rsnd_io_is_play(io);
640 int ret, dma_id;
617 641
618 /* 642 /*
619 * DMA failed. try to PIO mode 643 * DMA failed. try to PIO mode
@@ -622,35 +646,64 @@ int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id)
622 * rsnd_rdai_continuance_probe() 646 * rsnd_rdai_continuance_probe()
623 */ 647 */
624 if (!dmac) 648 if (!dmac)
625 return -EAGAIN; 649 return ERR_PTR(-EAGAIN);
626 650
627 rsnd_dma_of_path(dma, io, is_play, &mod_from, &mod_to); 651 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
652 if (!dma)
653 return ERR_PTR(-ENOMEM);
654
655 rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to);
628 656
629 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); 657 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1);
630 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); 658 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0);
631 659
632 /* for Gen2 */ 660 /* for Gen2 */
633 if (mod_from && mod_to) 661 if (mod_from && mod_to) {
634 dma->ops = &rsnd_dmapp_ops; 662 ops = &rsnd_dmapp_ops;
635 else 663 attach = rsnd_dmapp_attach;
636 dma->ops = &rsnd_dmaen_ops; 664 dma_id = dmac->dmapp_num;
665 type = RSND_MOD_AUDMAPP;
666 } else {
667 ops = &rsnd_dmaen_ops;
668 attach = rsnd_dmaen_attach;
669 dma_id = dmac->dmaen_num;
670 type = RSND_MOD_AUDMA;
671 }
637 672
638 /* for Gen1, overwrite */ 673 /* for Gen1, overwrite */
639 if (rsnd_is_gen1(priv)) 674 if (rsnd_is_gen1(priv)) {
640 dma->ops = &rsnd_dmaen_ops; 675 ops = &rsnd_dmaen_ops;
676 attach = rsnd_dmaen_attach;
677 dma_id = dmac->dmaen_num;
678 type = RSND_MOD_AUDMA;
679 }
680
681 dma_mod = rsnd_mod_get(dma);
682
683 ret = rsnd_mod_init(priv, dma_mod,
684 ops, NULL, type, dma_id);
685 if (ret < 0)
686 return ERR_PTR(ret);
641 687
642 dev_dbg(dev, "%s %s[%d] -> %s[%d]\n", 688 dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n",
643 dma->ops->name, 689 rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod),
644 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), 690 rsnd_mod_name(mod_from), rsnd_mod_id(mod_from),
645 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); 691 rsnd_mod_name(mod_to), rsnd_mod_id(mod_to));
646 692
647 return dma->ops->init(io, dma, id, mod_from, mod_to); 693 ret = attach(io, dma, id, mod_from, mod_to);
694 if (ret < 0)
695 return ERR_PTR(ret);
696
697 ret = rsnd_dai_connect(dma_mod, io, type);
698 if (ret < 0)
699 return ERR_PTR(ret);
700
701 return rsnd_mod_get(dma);
648} 702}
649 703
650int rsnd_dma_probe(struct platform_device *pdev, 704int rsnd_dma_probe(struct rsnd_priv *priv)
651 const struct rsnd_of_data *of_data,
652 struct rsnd_priv *priv)
653{ 705{
706 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
654 struct device *dev = rsnd_priv_to_dev(priv); 707 struct device *dev = rsnd_priv_to_dev(priv);
655 struct rsnd_dma_ctrl *dmac; 708 struct rsnd_dma_ctrl *dmac;
656 struct resource *res; 709 struct resource *res;
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 58f690900e6d..d45ffe496397 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -15,7 +15,6 @@
15#define DVC_NAME "dvc" 15#define DVC_NAME "dvc"
16 16
17struct rsnd_dvc { 17struct rsnd_dvc {
18 struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
19 struct rsnd_mod mod; 18 struct rsnd_mod mod;
20 struct rsnd_kctrl_cfg_m volume; 19 struct rsnd_kctrl_cfg_m volume;
21 struct rsnd_kctrl_cfg_m mute; 20 struct rsnd_kctrl_cfg_m mute;
@@ -24,6 +23,7 @@ struct rsnd_dvc {
24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 23 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
25}; 24};
26 25
26#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
27#define rsnd_dvc_nr(priv) ((priv)->dvc_nr) 27#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
28#define rsnd_dvc_of_node(priv) \ 28#define rsnd_dvc_of_node(priv) \
29 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") 29 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
@@ -64,79 +64,142 @@ static const char * const dvc_ramp_rate[] = {
64 "0.125 dB/8192 steps", /* 10111 */ 64 "0.125 dB/8192 steps", /* 10111 */
65}; 65};
66 66
67static void rsnd_dvc_soft_reset(struct rsnd_mod *mod) 67static void rsnd_dvc_activation(struct rsnd_mod *mod)
68{ 68{
69 rsnd_mod_write(mod, DVC_SWRSR, 0); 69 rsnd_mod_write(mod, DVC_SWRSR, 0);
70 rsnd_mod_write(mod, DVC_SWRSR, 1); 70 rsnd_mod_write(mod, DVC_SWRSR, 1);
71} 71}
72 72
73#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1) 73static void rsnd_dvc_halt(struct rsnd_mod *mod)
74#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0)
75static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
76{ 74{
77 rsnd_mod_write(mod, DVC_DVUIR, enable); 75 rsnd_mod_write(mod, DVC_DVUIR, 1);
76 rsnd_mod_write(mod, DVC_SWRSR, 0);
78} 77}
79 78
80static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, 79#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
81 struct rsnd_mod *mod) 80#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
81
82static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
83 struct rsnd_mod *mod)
82{ 84{
83 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 85 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
84 u32 val[RSND_DVC_CHANNELS]; 86 u32 val[RSND_DVC_CHANNELS];
85 u32 dvucr = 0;
86 u32 mute = 0;
87 int i; 87 int i;
88 88
89 for (i = 0; i < dvc->mute.cfg.size; i++) 89 /* Enable Ramp */
90 mute |= (!!dvc->mute.cfg.val[i]) << i; 90 if (dvc->ren.val)
91 for (i = 0; i < RSND_DVC_CHANNELS; i++)
92 val[i] = dvc->volume.cfg.max;
93 else
94 for (i = 0; i < RSND_DVC_CHANNELS; i++)
95 val[i] = dvc->volume.val[i];
91 96
92 /* Disable DVC Register access */ 97 /* Enable Digital Volume */
93 rsnd_mod_write(mod, DVC_DVUER, 0); 98 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
99 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
100 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
101 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
102 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
103 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
104 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
105 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
106}
107
108static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
109 struct rsnd_mod *mod)
110{
111 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
112 u32 adinr = 0;
113 u32 dvucr = 0;
114 u32 vrctr = 0;
115 u32 vrpdr = 0;
116 u32 vrdbr = 0;
117
118 adinr = rsnd_get_adinr_bit(mod, io) |
119 rsnd_get_adinr_chan(mod, io);
120
121 /* Enable Digital Volume, Zero Cross Mute Mode */
122 dvucr |= 0x101;
94 123
95 /* Enable Ramp */ 124 /* Enable Ramp */
96 if (dvc->ren.val) { 125 if (dvc->ren.val) {
97 dvucr |= 0x10; 126 dvucr |= 0x10;
98 127
99 /* Digital Volume Max */
100 for (i = 0; i < RSND_DVC_CHANNELS; i++)
101 val[i] = dvc->volume.cfg.max;
102
103 rsnd_mod_write(mod, DVC_VRCTR, 0xff);
104 rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
105 dvc->rdown.val);
106 /* 128 /*
107 * FIXME !! 129 * FIXME !!
108 * use scale-downed Digital Volume 130 * use scale-downed Digital Volume
109 * as Volume Ramp 131 * as Volume Ramp
110 * 7F FFFF -> 3FF 132 * 7F FFFF -> 3FF
111 */ 133 */
112 rsnd_mod_write(mod, DVC_VRDBR, 134 vrctr = 0xff;
113 0x3ff - (dvc->volume.val[0] >> 13)); 135 vrpdr = rsnd_dvc_get_vrpdr(dvc);
114 136 vrdbr = rsnd_dvc_get_vrdbr(dvc);
115 } else {
116 for (i = 0; i < RSND_DVC_CHANNELS; i++)
117 val[i] = dvc->volume.val[i];
118 } 137 }
119 138
120 /* Enable Digital Volume */ 139 /* Initialize operation */
121 dvucr |= 0x100; 140 rsnd_mod_write(mod, DVC_DVUIR, 1);
122 rsnd_mod_write(mod, DVC_VOL0R, val[0]); 141
123 rsnd_mod_write(mod, DVC_VOL1R, val[1]); 142 /* General Information */
143 rsnd_mod_write(mod, DVC_ADINR, adinr);
144 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
145
146 /* Volume Ramp Parameter */
147 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
148 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
149 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
150
151 /* Digital Volume Function Parameter */
152 rsnd_dvc_volume_parameter(io, mod);
153
154 /* cancel operation */
155 rsnd_mod_write(mod, DVC_DVUIR, 0);
156}
157
158static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
159 struct rsnd_mod *mod)
160{
161 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
162 u32 zcmcr = 0;
163 u32 vrpdr = 0;
164 u32 vrdbr = 0;
165 int i;
166
167 for (i = 0; i < dvc->mute.cfg.size; i++)
168 zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
124 169
125 /* Enable Mute */ 170 if (dvc->ren.val) {
126 if (mute) { 171 vrpdr = rsnd_dvc_get_vrpdr(dvc);
127 dvucr |= 0x1; 172 vrdbr = rsnd_dvc_get_vrdbr(dvc);
128 rsnd_mod_write(mod, DVC_ZCMCR, mute);
129 } 173 }
130 174
131 rsnd_mod_write(mod, DVC_DVUCR, dvucr); 175 /* Disable DVC Register access */
176 rsnd_mod_write(mod, DVC_DVUER, 0);
177
178 /* Zero Cross Mute Function */
179 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
180
181 /* Volume Ramp Function */
182 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
183 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
184 /* add DVC_VRWTR here */
185
186 /* Digital Volume Function Parameter */
187 rsnd_dvc_volume_parameter(io, mod);
132 188
133 /* Enable DVC Register access */ 189 /* Enable DVC Register access */
134 rsnd_mod_write(mod, DVC_DVUER, 1); 190 rsnd_mod_write(mod, DVC_DVUER, 1);
135} 191}
136 192
137static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 193static int rsnd_dvc_probe_(struct rsnd_mod *mod,
138 struct rsnd_dai_stream *io, 194 struct rsnd_dai_stream *io,
139 struct rsnd_priv *priv) 195 struct rsnd_priv *priv)
196{
197 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
198}
199
200static int rsnd_dvc_remove_(struct rsnd_mod *mod,
201 struct rsnd_dai_stream *io,
202 struct rsnd_priv *priv)
140{ 203{
141 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 204 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
142 205
@@ -155,19 +218,12 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
155{ 218{
156 rsnd_mod_power_on(mod); 219 rsnd_mod_power_on(mod);
157 220
158 rsnd_dvc_soft_reset(mod); 221 rsnd_dvc_activation(mod);
159
160 rsnd_dvc_initialize_lock(mod);
161
162 rsnd_path_parse(priv, io);
163 222
164 rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io)); 223 rsnd_dvc_volume_init(io, mod);
165 224
166 /* ch0/ch1 Volume */
167 rsnd_dvc_volume_update(io, mod); 225 rsnd_dvc_volume_update(io, mod);
168 226
169 rsnd_adg_set_cmd_timsel_gen2(mod, io);
170
171 return 0; 227 return 0;
172} 228}
173 229
@@ -175,27 +231,9 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod,
175 struct rsnd_dai_stream *io, 231 struct rsnd_dai_stream *io,
176 struct rsnd_priv *priv) 232 struct rsnd_priv *priv)
177{ 233{
178 rsnd_mod_power_off(mod); 234 rsnd_dvc_halt(mod);
179 235
180 return 0; 236 rsnd_mod_power_off(mod);
181}
182
183static int rsnd_dvc_start(struct rsnd_mod *mod,
184 struct rsnd_dai_stream *io,
185 struct rsnd_priv *priv)
186{
187 rsnd_dvc_initialize_unlock(mod);
188
189 rsnd_mod_write(mod, CMD_CTRL, 0x10);
190
191 return 0;
192}
193
194static int rsnd_dvc_stop(struct rsnd_mod *mod,
195 struct rsnd_dai_stream *io,
196 struct rsnd_priv *priv)
197{
198 rsnd_mod_write(mod, CMD_CTRL, 0);
199 237
200 return 0; 238 return 0;
201} 239}
@@ -206,6 +244,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
206{ 244{
207 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 245 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
208 int is_play = rsnd_io_is_play(io); 246 int is_play = rsnd_io_is_play(io);
247 int slots = rsnd_get_slot(io);
209 int ret; 248 int ret;
210 249
211 /* Volume */ 250 /* Volume */
@@ -213,7 +252,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
213 is_play ? 252 is_play ?
214 "DVC Out Playback Volume" : "DVC In Capture Volume", 253 "DVC Out Playback Volume" : "DVC In Capture Volume",
215 rsnd_dvc_volume_update, 254 rsnd_dvc_volume_update,
216 &dvc->volume, 0x00800000 - 1); 255 &dvc->volume, slots,
256 0x00800000 - 1);
217 if (ret < 0) 257 if (ret < 0)
218 return ret; 258 return ret;
219 259
@@ -222,7 +262,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
222 is_play ? 262 is_play ?
223 "DVC Out Mute Switch" : "DVC In Mute Switch", 263 "DVC Out Mute Switch" : "DVC In Mute Switch",
224 rsnd_dvc_volume_update, 264 rsnd_dvc_volume_update,
225 &dvc->mute, 1); 265 &dvc->mute, slots,
266 1);
226 if (ret < 0) 267 if (ret < 0)
227 return ret; 268 return ret;
228 269
@@ -269,11 +310,10 @@ static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
269static struct rsnd_mod_ops rsnd_dvc_ops = { 310static struct rsnd_mod_ops rsnd_dvc_ops = {
270 .name = DVC_NAME, 311 .name = DVC_NAME,
271 .dma_req = rsnd_dvc_dma_req, 312 .dma_req = rsnd_dvc_dma_req,
272 .remove = rsnd_dvc_remove_gen2, 313 .probe = rsnd_dvc_probe_,
314 .remove = rsnd_dvc_remove_,
273 .init = rsnd_dvc_init, 315 .init = rsnd_dvc_init,
274 .quit = rsnd_dvc_quit, 316 .quit = rsnd_dvc_quit,
275 .start = rsnd_dvc_start,
276 .stop = rsnd_dvc_stop,
277 .pcm_new = rsnd_dvc_pcm_new, 317 .pcm_new = rsnd_dvc_pcm_new,
278}; 318};
279 319
@@ -282,50 +322,13 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) 322 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
283 id = 0; 323 id = 0;
284 324
285 return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id); 325 return rsnd_mod_get(rsnd_dvc_get(priv, id));
286} 326}
287 327
288static void rsnd_of_parse_dvc(struct platform_device *pdev, 328int rsnd_dvc_probe(struct rsnd_priv *priv)
289 const struct rsnd_of_data *of_data,
290 struct rsnd_priv *priv)
291{ 329{
292 struct device_node *node; 330 struct device_node *node;
293 struct rsnd_dvc_platform_info *dvc_info; 331 struct device_node *np;
294 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
295 struct device *dev = &pdev->dev;
296 int nr;
297
298 if (!of_data)
299 return;
300
301 node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
302 if (!node)
303 return;
304
305 nr = of_get_child_count(node);
306 if (!nr)
307 goto rsnd_of_parse_dvc_end;
308
309 dvc_info = devm_kzalloc(dev,
310 sizeof(struct rsnd_dvc_platform_info) * nr,
311 GFP_KERNEL);
312 if (!dvc_info) {
313 dev_err(dev, "dvc info allocation error\n");
314 goto rsnd_of_parse_dvc_end;
315 }
316
317 info->dvc_info = dvc_info;
318 info->dvc_info_nr = nr;
319
320rsnd_of_parse_dvc_end:
321 of_node_put(node);
322}
323
324int rsnd_dvc_probe(struct platform_device *pdev,
325 const struct rsnd_of_data *of_data,
326 struct rsnd_priv *priv)
327{
328 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
329 struct device *dev = rsnd_priv_to_dev(priv); 332 struct device *dev = rsnd_priv_to_dev(priv);
330 struct rsnd_dvc *dvc; 333 struct rsnd_dvc *dvc;
331 struct clk *clk; 334 struct clk *clk;
@@ -336,40 +339,54 @@ int rsnd_dvc_probe(struct platform_device *pdev,
336 if (rsnd_is_gen1(priv)) 339 if (rsnd_is_gen1(priv))
337 return 0; 340 return 0;
338 341
339 rsnd_of_parse_dvc(pdev, of_data, priv); 342 node = rsnd_dvc_of_node(priv);
343 if (!node)
344 return 0; /* not used is not error */
340 345
341 nr = info->dvc_info_nr; 346 nr = of_get_child_count(node);
342 if (!nr) 347 if (!nr) {
343 return 0; 348 ret = -EINVAL;
349 goto rsnd_dvc_probe_done;
350 }
344 351
345 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); 352 dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
346 if (!dvc) 353 if (!dvc) {
347 return -ENOMEM; 354 ret = -ENOMEM;
355 goto rsnd_dvc_probe_done;
356 }
348 357
349 priv->dvc_nr = nr; 358 priv->dvc_nr = nr;
350 priv->dvc = dvc; 359 priv->dvc = dvc;
351 360
352 for_each_rsnd_dvc(dvc, priv, i) { 361 i = 0;
362 ret = 0;
363 for_each_child_of_node(node, np) {
364 dvc = rsnd_dvc_get(priv, i);
365
353 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d", 366 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
354 DVC_NAME, i); 367 DVC_NAME, i);
355 368
356 clk = devm_clk_get(dev, name); 369 clk = devm_clk_get(dev, name);
357 if (IS_ERR(clk)) 370 if (IS_ERR(clk)) {
358 return PTR_ERR(clk); 371 ret = PTR_ERR(clk);
359 372 goto rsnd_dvc_probe_done;
360 dvc->info = &info->dvc_info[i]; 373 }
361 374
362 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, 375 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
363 clk, RSND_MOD_DVC, i); 376 clk, RSND_MOD_DVC, i);
364 if (ret) 377 if (ret)
365 return ret; 378 goto rsnd_dvc_probe_done;
379
380 i++;
366 } 381 }
367 382
368 return 0; 383rsnd_dvc_probe_done:
384 of_node_put(node);
385
386 return ret;
369} 387}
370 388
371void rsnd_dvc_remove(struct platform_device *pdev, 389void rsnd_dvc_remove(struct rsnd_priv *priv)
372 struct rsnd_priv *priv)
373{ 390{
374 struct rsnd_dvc *dvc; 391 struct rsnd_dvc *dvc;
375 int i; 392 int i;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index edcf4cc2e84f..ea24247eba73 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -31,29 +31,33 @@ struct rsnd_gen {
31 31
32 /* RSND_REG_MAX base */ 32 /* RSND_REG_MAX base */
33 struct regmap_field *regs[RSND_REG_MAX]; 33 struct regmap_field *regs[RSND_REG_MAX];
34 const char *reg_name[RSND_REG_MAX];
34}; 35};
35 36
36#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 37#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
38#define rsnd_reg_name(gen, id) ((gen)->reg_name[id])
37 39
38struct rsnd_regmap_field_conf { 40struct rsnd_regmap_field_conf {
39 int idx; 41 int idx;
40 unsigned int reg_offset; 42 unsigned int reg_offset;
41 unsigned int id_offset; 43 unsigned int id_offset;
44 const char *reg_name;
42}; 45};
43 46
44#define RSND_REG_SET(id, offset, _id_offset) \ 47#define RSND_REG_SET(id, offset, _id_offset, n) \
45{ \ 48{ \
46 .idx = id, \ 49 .idx = id, \
47 .reg_offset = offset, \ 50 .reg_offset = offset, \
48 .id_offset = _id_offset, \ 51 .id_offset = _id_offset, \
52 .reg_name = n, \
49} 53}
50/* single address mapping */ 54/* single address mapping */
51#define RSND_GEN_S_REG(id, offset) \ 55#define RSND_GEN_S_REG(id, offset) \
52 RSND_REG_SET(RSND_REG_##id, offset, 0) 56 RSND_REG_SET(RSND_REG_##id, offset, 0, #id)
53 57
54/* multi address mapping */ 58/* multi address mapping */
55#define RSND_GEN_M_REG(id, offset, _id_offset) \ 59#define RSND_GEN_M_REG(id, offset, _id_offset) \
56 RSND_REG_SET(RSND_REG_##id, offset, _id_offset) 60 RSND_REG_SET(RSND_REG_##id, offset, _id_offset, #id)
57 61
58/* 62/*
59 * basic function 63 * basic function
@@ -83,8 +87,9 @@ u32 rsnd_read(struct rsnd_priv *priv,
83 87
84 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 88 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
85 89
86 dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 90 dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n",
87 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 91 rsnd_mod_name(mod), rsnd_mod_id(mod),
92 rsnd_reg_name(gen, reg), reg, val);
88 93
89 return val; 94 return val;
90} 95}
@@ -99,10 +104,11 @@ void rsnd_write(struct rsnd_priv *priv,
99 if (!rsnd_is_accessible_reg(priv, gen, reg)) 104 if (!rsnd_is_accessible_reg(priv, gen, reg))
100 return; 105 return;
101 106
102 dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
103 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
104
105 regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 107 regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
108
109 dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n",
110 rsnd_mod_name(mod), rsnd_mod_id(mod),
111 rsnd_reg_name(gen, reg), reg, data);
106} 112}
107 113
108void rsnd_force_write(struct rsnd_priv *priv, 114void rsnd_force_write(struct rsnd_priv *priv,
@@ -115,10 +121,11 @@ void rsnd_force_write(struct rsnd_priv *priv,
115 if (!rsnd_is_accessible_reg(priv, gen, reg)) 121 if (!rsnd_is_accessible_reg(priv, gen, reg))
116 return; 122 return;
117 123
118 dev_dbg(dev, "w %s[%d] - %4d : %08x\n",
119 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data);
120
121 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data); 124 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data);
125
126 dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n",
127 rsnd_mod_name(mod), rsnd_mod_id(mod),
128 rsnd_reg_name(gen, reg), reg, data);
122} 129}
123 130
124void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 131void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
@@ -130,11 +137,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
130 if (!rsnd_is_accessible_reg(priv, gen, reg)) 137 if (!rsnd_is_accessible_reg(priv, gen, reg))
131 return; 138 return;
132 139
133 dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n",
134 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask);
135
136 regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 140 regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
137 mask, data); 141 mask, data);
142
143 dev_dbg(dev, "b %s[%d] - %-18s (%4d) : %08x/%08x\n",
144 rsnd_mod_name(mod), rsnd_mod_id(mod),
145 rsnd_reg_name(gen, reg), reg, data, mask);
146
138} 147}
139 148
140phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id) 149phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
@@ -150,7 +159,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
150 int id_size, 159 int id_size,
151 int reg_id, 160 int reg_id,
152 const char *name, 161 const char *name,
153 struct rsnd_regmap_field_conf *conf, 162 const struct rsnd_regmap_field_conf *conf,
154 int conf_size) 163 int conf_size)
155{ 164{
156 struct platform_device *pdev = rsnd_priv_to_pdev(priv); 165 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
@@ -203,6 +212,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
203 212
204 /* RSND_REG_MAX base */ 213 /* RSND_REG_MAX base */
205 gen->regs[conf[i].idx] = regs; 214 gen->regs[conf[i].idx] = regs;
215 gen->reg_name[conf[i].idx] = conf[i].reg_name;
206 } 216 }
207 217
208 return 0; 218 return 0;
@@ -211,25 +221,31 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
211/* 221/*
212 * Gen2 222 * Gen2
213 */ 223 */
214static int rsnd_gen2_probe(struct platform_device *pdev, 224static int rsnd_gen2_probe(struct rsnd_priv *priv)
215 struct rsnd_priv *priv)
216{ 225{
217 struct rsnd_regmap_field_conf conf_ssiu[] = { 226 const static struct rsnd_regmap_field_conf conf_ssiu[] = {
218 RSND_GEN_S_REG(SSI_MODE0, 0x800), 227 RSND_GEN_S_REG(SSI_MODE0, 0x800),
219 RSND_GEN_S_REG(SSI_MODE1, 0x804), 228 RSND_GEN_S_REG(SSI_MODE1, 0x804),
229 RSND_GEN_S_REG(SSI_MODE2, 0x808),
230 RSND_GEN_S_REG(SSI_CONTROL, 0x810),
231
220 /* FIXME: it needs SSI_MODE2/3 in the future */ 232 /* FIXME: it needs SSI_MODE2/3 in the future */
221 RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), 233 RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80),
222 RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), 234 RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80),
223 RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80), 235 RSND_GEN_M_REG(SSI_BUSIF_DALIGN,0x8, 0x80),
236 RSND_GEN_M_REG(SSI_MODE, 0xc, 0x80),
224 RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), 237 RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80),
225 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), 238 RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
226 }; 239 };
227 struct rsnd_regmap_field_conf conf_scu[] = { 240
228 RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), 241 const static struct rsnd_regmap_field_conf conf_scu[] = {
242 RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20),
243 RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20),
229 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), 244 RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20),
230 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 245 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20),
231 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 246 RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20),
232 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 247 RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20),
248 RSND_GEN_M_REG(CMD_BUSIF_DALIGN,0x188, 0x20),
233 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 249 RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20),
234 RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 250 RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20),
235 RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), 251 RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
@@ -266,9 +282,15 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
266 RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), 282 RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100),
267 RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), 283 RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100),
268 RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), 284 RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
285 RSND_GEN_M_REG(DVC_VOL2R, 0xe30, 0x100),
286 RSND_GEN_M_REG(DVC_VOL3R, 0xe34, 0x100),
287 RSND_GEN_M_REG(DVC_VOL4R, 0xe38, 0x100),
288 RSND_GEN_M_REG(DVC_VOL5R, 0xe3c, 0x100),
289 RSND_GEN_M_REG(DVC_VOL6R, 0xe40, 0x100),
290 RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
269 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 291 RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
270 }; 292 };
271 struct rsnd_regmap_field_conf conf_adg[] = { 293 const static struct rsnd_regmap_field_conf conf_adg[] = {
272 RSND_GEN_S_REG(BRRA, 0x00), 294 RSND_GEN_S_REG(BRRA, 0x00),
273 RSND_GEN_S_REG(BRRB, 0x04), 295 RSND_GEN_S_REG(BRRB, 0x04),
274 RSND_GEN_S_REG(SSICKR, 0x08), 296 RSND_GEN_S_REG(SSICKR, 0x08),
@@ -288,7 +310,7 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
288 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 310 RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
289 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 311 RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
290 }; 312 };
291 struct rsnd_regmap_field_conf conf_ssi[] = { 313 const static struct rsnd_regmap_field_conf conf_ssi[] = {
292 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 314 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
293 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 315 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
294 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 316 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
@@ -317,65 +339,30 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
317 * Gen1 339 * Gen1
318 */ 340 */
319 341
320static int rsnd_gen1_probe(struct platform_device *pdev, 342static int rsnd_gen1_probe(struct rsnd_priv *priv)
321 struct rsnd_priv *priv)
322{ 343{
323 struct rsnd_regmap_field_conf conf_sru[] = { 344 const static struct rsnd_regmap_field_conf conf_adg[] = {
324 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00),
325 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08),
326 RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c),
327 RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10),
328 RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0),
329 RSND_GEN_S_REG(SSI_MODE0, 0xD0),
330 RSND_GEN_S_REG(SSI_MODE1, 0xD4),
331 RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4),
332 RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8),
333 RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40),
334 RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40),
335 RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40),
336 RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40),
337 RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40),
338 RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40),
339 RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40),
340 /*
341 * ADD US
342 *
343 * SRC_STATUS
344 * SRC_INT_EN
345 * SCU_SYS_STATUS0
346 * SCU_SYS_STATUS1
347 * SCU_SYS_INT_EN0
348 * SCU_SYS_INT_EN1
349 */
350 };
351 struct rsnd_regmap_field_conf conf_adg[] = {
352 RSND_GEN_S_REG(BRRA, 0x00), 345 RSND_GEN_S_REG(BRRA, 0x00),
353 RSND_GEN_S_REG(BRRB, 0x04), 346 RSND_GEN_S_REG(BRRB, 0x04),
354 RSND_GEN_S_REG(SSICKR, 0x08), 347 RSND_GEN_S_REG(SSICKR, 0x08),
355 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 348 RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
356 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 349 RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
357 RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18),
358 RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c),
359 RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20),
360 }; 350 };
361 struct rsnd_regmap_field_conf conf_ssi[] = { 351 const static struct rsnd_regmap_field_conf conf_ssi[] = {
362 RSND_GEN_M_REG(SSICR, 0x00, 0x40), 352 RSND_GEN_M_REG(SSICR, 0x00, 0x40),
363 RSND_GEN_M_REG(SSISR, 0x04, 0x40), 353 RSND_GEN_M_REG(SSISR, 0x04, 0x40),
364 RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 354 RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
365 RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 355 RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40),
366 RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 356 RSND_GEN_M_REG(SSIWSR, 0x20, 0x40),
367 }; 357 };
368 int ret_sru;
369 int ret_adg; 358 int ret_adg;
370 int ret_ssi; 359 int ret_ssi;
371 360
372 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru);
373 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); 361 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
374 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); 362 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
375 if (ret_sru < 0 || 363 if (ret_adg < 0 ||
376 ret_adg < 0 ||
377 ret_ssi < 0) 364 ret_ssi < 0)
378 return ret_sru | ret_adg | ret_ssi; 365 return ret_adg | ret_ssi;
379 366
380 return 0; 367 return 0;
381} 368}
@@ -383,28 +370,12 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
383/* 370/*
384 * Gen 371 * Gen
385 */ 372 */
386static void rsnd_of_parse_gen(struct platform_device *pdev, 373int rsnd_gen_probe(struct rsnd_priv *priv)
387 const struct rsnd_of_data *of_data,
388 struct rsnd_priv *priv)
389{
390 struct rcar_snd_info *info = priv->info;
391
392 if (!of_data)
393 return;
394
395 info->flags = of_data->flags;
396}
397
398int rsnd_gen_probe(struct platform_device *pdev,
399 const struct rsnd_of_data *of_data,
400 struct rsnd_priv *priv)
401{ 374{
402 struct device *dev = rsnd_priv_to_dev(priv); 375 struct device *dev = rsnd_priv_to_dev(priv);
403 struct rsnd_gen *gen; 376 struct rsnd_gen *gen;
404 int ret; 377 int ret;
405 378
406 rsnd_of_parse_gen(pdev, of_data, priv);
407
408 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 379 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
409 if (!gen) { 380 if (!gen) {
410 dev_err(dev, "GEN allocate failed\n"); 381 dev_err(dev, "GEN allocate failed\n");
@@ -415,9 +386,9 @@ int rsnd_gen_probe(struct platform_device *pdev,
415 386
416 ret = -ENODEV; 387 ret = -ENODEV;
417 if (rsnd_is_gen1(priv)) 388 if (rsnd_is_gen1(priv))
418 ret = rsnd_gen1_probe(pdev, priv); 389 ret = rsnd_gen1_probe(priv);
419 else if (rsnd_is_gen2(priv)) 390 else if (rsnd_is_gen2(priv))
420 ret = rsnd_gen2_probe(pdev, priv); 391 ret = rsnd_gen2_probe(priv);
421 392
422 if (ret < 0) 393 if (ret < 0)
423 dev_err(dev, "unknown generation R-Car sound device\n"); 394 dev_err(dev, "unknown generation R-Car sound device\n");
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 953dd0be9b60..65542b6a89e9 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -13,10 +13,10 @@
13#define MIX_NAME "mix" 13#define MIX_NAME "mix"
14 14
15struct rsnd_mix { 15struct rsnd_mix {
16 struct rsnd_mix_platform_info *info; /* rcar_snd.h */
17 struct rsnd_mod mod; 16 struct rsnd_mod mod;
18}; 17};
19 18
19#define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id)
20#define rsnd_mix_nr(priv) ((priv)->mix_nr) 20#define rsnd_mix_nr(priv) ((priv)->mix_nr)
21#define for_each_rsnd_mix(pos, priv, i) \ 21#define for_each_rsnd_mix(pos, priv, i) \
22 for ((i) = 0; \ 22 for ((i) = 0; \
@@ -24,58 +24,77 @@ struct rsnd_mix {
24 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \ 24 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \
25 i++) 25 i++)
26 26
27 27static void rsnd_mix_activation(struct rsnd_mod *mod)
28static void rsnd_mix_soft_reset(struct rsnd_mod *mod)
29{ 28{
30 rsnd_mod_write(mod, MIX_SWRSR, 0); 29 rsnd_mod_write(mod, MIX_SWRSR, 0);
31 rsnd_mod_write(mod, MIX_SWRSR, 1); 30 rsnd_mod_write(mod, MIX_SWRSR, 1);
32} 31}
33 32
34#define rsnd_mix_initialize_lock(mod) __rsnd_mix_initialize_lock(mod, 1) 33static void rsnd_mix_halt(struct rsnd_mod *mod)
35#define rsnd_mix_initialize_unlock(mod) __rsnd_mix_initialize_lock(mod, 0) 34{
36static void __rsnd_mix_initialize_lock(struct rsnd_mod *mod, u32 enable) 35 rsnd_mod_write(mod, MIX_MIXIR, 1);
36 rsnd_mod_write(mod, MIX_SWRSR, 0);
37}
38
39static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
40 struct rsnd_mod *mod)
37{ 41{
38 rsnd_mod_write(mod, MIX_MIXIR, enable); 42 rsnd_mod_write(mod, MIX_MDBAR, 0);
43 rsnd_mod_write(mod, MIX_MDBBR, 0);
44 rsnd_mod_write(mod, MIX_MDBCR, 0);
45 rsnd_mod_write(mod, MIX_MDBDR, 0);
46}
47
48static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
49 struct rsnd_mod *mod)
50{
51 rsnd_mod_write(mod, MIX_MIXIR, 1);
52
53 /* General Information */
54 rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
55
56 /* volume step */
57 rsnd_mod_write(mod, MIX_MIXMR, 0);
58 rsnd_mod_write(mod, MIX_MVPDR, 0);
59
60 /* common volume parameter */
61 rsnd_mix_volume_parameter(io, mod);
62
63 rsnd_mod_write(mod, MIX_MIXIR, 0);
39} 64}
40 65
41static void rsnd_mix_volume_update(struct rsnd_dai_stream *io, 66static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
42 struct rsnd_mod *mod) 67 struct rsnd_mod *mod)
43{ 68{
44
45 /* Disable MIX dB setting */ 69 /* Disable MIX dB setting */
46 rsnd_mod_write(mod, MIX_MDBER, 0); 70 rsnd_mod_write(mod, MIX_MDBER, 0);
47 71
48 rsnd_mod_write(mod, MIX_MDBAR, 0); 72 /* common volume parameter */
49 rsnd_mod_write(mod, MIX_MDBBR, 0); 73 rsnd_mix_volume_parameter(io, mod);
50 rsnd_mod_write(mod, MIX_MDBCR, 0);
51 rsnd_mod_write(mod, MIX_MDBDR, 0);
52 74
53 /* Enable MIX dB setting */ 75 /* Enable MIX dB setting */
54 rsnd_mod_write(mod, MIX_MDBER, 1); 76 rsnd_mod_write(mod, MIX_MDBER, 1);
55} 77}
56 78
79static int rsnd_mix_probe_(struct rsnd_mod *mod,
80 struct rsnd_dai_stream *io,
81 struct rsnd_priv *priv)
82{
83 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
84}
85
57static int rsnd_mix_init(struct rsnd_mod *mod, 86static int rsnd_mix_init(struct rsnd_mod *mod,
58 struct rsnd_dai_stream *io, 87 struct rsnd_dai_stream *io,
59 struct rsnd_priv *priv) 88 struct rsnd_priv *priv)
60{ 89{
61 rsnd_mod_power_on(mod); 90 rsnd_mod_power_on(mod);
62 91
63 rsnd_mix_soft_reset(mod); 92 rsnd_mix_activation(mod);
64
65 rsnd_mix_initialize_lock(mod);
66
67 rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
68
69 rsnd_path_parse(priv, io);
70 93
71 /* volume step */ 94 rsnd_mix_volume_init(io, mod);
72 rsnd_mod_write(mod, MIX_MIXMR, 0);
73 rsnd_mod_write(mod, MIX_MVPDR, 0);
74 95
75 rsnd_mix_volume_update(io, mod); 96 rsnd_mix_volume_update(io, mod);
76 97
77 rsnd_mix_initialize_unlock(mod);
78
79 return 0; 98 return 0;
80} 99}
81 100
@@ -83,6 +102,8 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
83 struct rsnd_dai_stream *io, 102 struct rsnd_dai_stream *io,
84 struct rsnd_priv *priv) 103 struct rsnd_priv *priv)
85{ 104{
105 rsnd_mix_halt(mod);
106
86 rsnd_mod_power_off(mod); 107 rsnd_mod_power_off(mod);
87 108
88 return 0; 109 return 0;
@@ -90,6 +111,7 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
90 111
91static struct rsnd_mod_ops rsnd_mix_ops = { 112static struct rsnd_mod_ops rsnd_mix_ops = {
92 .name = MIX_NAME, 113 .name = MIX_NAME,
114 .probe = rsnd_mix_probe_,
93 .init = rsnd_mix_init, 115 .init = rsnd_mix_init,
94 .quit = rsnd_mix_quit, 116 .quit = rsnd_mix_quit,
95}; 117};
@@ -99,51 +121,13 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) 121 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
100 id = 0; 122 id = 0;
101 123
102 return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id); 124 return rsnd_mod_get(rsnd_mix_get(priv, id));
103} 125}
104 126
105static void rsnd_of_parse_mix(struct platform_device *pdev, 127int rsnd_mix_probe(struct rsnd_priv *priv)
106 const struct rsnd_of_data *of_data,
107 struct rsnd_priv *priv)
108{ 128{
109 struct device_node *node; 129 struct device_node *node;
110 struct rsnd_mix_platform_info *mix_info; 130 struct device_node *np;
111 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
112 struct device *dev = &pdev->dev;
113 int nr;
114
115 if (!of_data)
116 return;
117
118 node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
119 if (!node)
120 return;
121
122 nr = of_get_child_count(node);
123 if (!nr)
124 goto rsnd_of_parse_mix_end;
125
126 mix_info = devm_kzalloc(dev,
127 sizeof(struct rsnd_mix_platform_info) * nr,
128 GFP_KERNEL);
129 if (!mix_info) {
130 dev_err(dev, "mix info allocation error\n");
131 goto rsnd_of_parse_mix_end;
132 }
133
134 info->mix_info = mix_info;
135 info->mix_info_nr = nr;
136
137rsnd_of_parse_mix_end:
138 of_node_put(node);
139
140}
141
142int rsnd_mix_probe(struct platform_device *pdev,
143 const struct rsnd_of_data *of_data,
144 struct rsnd_priv *priv)
145{
146 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
147 struct device *dev = rsnd_priv_to_dev(priv); 131 struct device *dev = rsnd_priv_to_dev(priv);
148 struct rsnd_mix *mix; 132 struct rsnd_mix *mix;
149 struct clk *clk; 133 struct clk *clk;
@@ -154,40 +138,54 @@ int rsnd_mix_probe(struct platform_device *pdev,
154 if (rsnd_is_gen1(priv)) 138 if (rsnd_is_gen1(priv))
155 return 0; 139 return 0;
156 140
157 rsnd_of_parse_mix(pdev, of_data, priv); 141 node = rsnd_mix_of_node(priv);
142 if (!node)
143 return 0; /* not used is not error */
158 144
159 nr = info->mix_info_nr; 145 nr = of_get_child_count(node);
160 if (!nr) 146 if (!nr) {
161 return 0; 147 ret = -EINVAL;
148 goto rsnd_mix_probe_done;
149 }
162 150
163 mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL); 151 mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL);
164 if (!mix) 152 if (!mix) {
165 return -ENOMEM; 153 ret = -ENOMEM;
154 goto rsnd_mix_probe_done;
155 }
166 156
167 priv->mix_nr = nr; 157 priv->mix_nr = nr;
168 priv->mix = mix; 158 priv->mix = mix;
169 159
170 for_each_rsnd_mix(mix, priv, i) { 160 i = 0;
161 ret = 0;
162 for_each_child_of_node(node, np) {
163 mix = rsnd_mix_get(priv, i);
164
171 snprintf(name, MIX_NAME_SIZE, "%s.%d", 165 snprintf(name, MIX_NAME_SIZE, "%s.%d",
172 MIX_NAME, i); 166 MIX_NAME, i);
173 167
174 clk = devm_clk_get(dev, name); 168 clk = devm_clk_get(dev, name);
175 if (IS_ERR(clk)) 169 if (IS_ERR(clk)) {
176 return PTR_ERR(clk); 170 ret = PTR_ERR(clk);
177 171 goto rsnd_mix_probe_done;
178 mix->info = &info->mix_info[i]; 172 }
179 173
180 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, 174 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
181 clk, RSND_MOD_MIX, i); 175 clk, RSND_MOD_MIX, i);
182 if (ret) 176 if (ret)
183 return ret; 177 goto rsnd_mix_probe_done;
178
179 i++;
184 } 180 }
185 181
186 return 0; 182rsnd_mix_probe_done:
183 of_node_put(node);
184
185 return ret;
187} 186}
188 187
189void rsnd_mix_remove(struct platform_device *pdev, 188void rsnd_mix_remove(struct rsnd_priv *priv)
190 struct rsnd_priv *priv)
191{ 189{
192 struct rsnd_mix *mix; 190 struct rsnd_mix *mix;
193 int i; 191 int i;
diff --git a/sound/soc/sh/rcar/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h
deleted file mode 100644
index d8e33d38da43..000000000000
--- a/sound/soc/sh/rcar/rcar_snd.h
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * Renesas R-Car SRU/SCU/SSIU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef RCAR_SND_H
13#define RCAR_SND_H
14
15
16#define RSND_GEN1_SRU 0
17#define RSND_GEN1_ADG 1
18#define RSND_GEN1_SSI 2
19
20#define RSND_GEN2_SCU 0
21#define RSND_GEN2_ADG 1
22#define RSND_GEN2_SSIU 2
23#define RSND_GEN2_SSI 3
24
25#define RSND_BASE_MAX 4
26
27/*
28 * flags
29 *
30 * 0xAB000000
31 *
32 * A : clock sharing settings
33 * B : SSI direction
34 */
35#define RSND_SSI_CLK_PIN_SHARE (1 << 31)
36#define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */
37
38#define RSND_SSI(_dma_id, _irq, _flags) \
39{ .dma_id = _dma_id, .irq = _irq, .flags = _flags }
40#define RSND_SSI_UNUSED \
41{ .dma_id = -1, .irq = -1, .flags = 0 }
42
43struct rsnd_ssi_platform_info {
44 int dma_id;
45 int irq;
46 u32 flags;
47};
48
49#define RSND_SRC(rate, _dma_id) \
50{ .convert_rate = rate, .dma_id = _dma_id, }
51#define RSND_SRC_UNUSED \
52{ .convert_rate = 0, .dma_id = -1, }
53
54struct rsnd_src_platform_info {
55 u32 convert_rate; /* sampling rate convert */
56 int dma_id; /* for Gen2 SCU */
57 int irq;
58};
59
60/*
61 * flags
62 */
63struct rsnd_ctu_platform_info {
64 u32 flags;
65};
66
67struct rsnd_mix_platform_info {
68 u32 flags;
69};
70
71struct rsnd_dvc_platform_info {
72 u32 flags;
73};
74
75struct rsnd_dai_path_info {
76 struct rsnd_ssi_platform_info *ssi;
77 struct rsnd_src_platform_info *src;
78 struct rsnd_ctu_platform_info *ctu;
79 struct rsnd_mix_platform_info *mix;
80 struct rsnd_dvc_platform_info *dvc;
81};
82
83struct rsnd_dai_platform_info {
84 struct rsnd_dai_path_info playback;
85 struct rsnd_dai_path_info capture;
86};
87
88/*
89 * flags
90 *
91 * 0x0000000A
92 *
93 * A : generation
94 */
95#define RSND_GEN_MASK (0xF << 0)
96#define RSND_GEN1 (1 << 0) /* fixme */
97#define RSND_GEN2 (2 << 0) /* fixme */
98
99struct rcar_snd_info {
100 u32 flags;
101 struct rsnd_ssi_platform_info *ssi_info;
102 int ssi_info_nr;
103 struct rsnd_src_platform_info *src_info;
104 int src_info_nr;
105 struct rsnd_ctu_platform_info *ctu_info;
106 int ctu_info_nr;
107 struct rsnd_mix_platform_info *mix_info;
108 int mix_info_nr;
109 struct rsnd_dvc_platform_info *dvc_info;
110 int dvc_info_nr;
111 struct rsnd_dai_platform_info *dai_info;
112 int dai_info_nr;
113 int (*start)(int id);
114 int (*stop)(int id);
115};
116
117#endif
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 085329878525..317dd793149a 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -24,7 +24,16 @@
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26 26
27#include "rcar_snd.h" 27#define RSND_GEN1_SRU 0
28#define RSND_GEN1_ADG 1
29#define RSND_GEN1_SSI 2
30
31#define RSND_GEN2_SCU 0
32#define RSND_GEN2_ADG 1
33#define RSND_GEN2_SSIU 2
34#define RSND_GEN2_SSI 3
35
36#define RSND_BASE_MAX 4
28 37
29/* 38/*
30 * pseudo register 39 * pseudo register
@@ -34,10 +43,19 @@
34 * see gen1/gen2 for detail 43 * see gen1/gen2 for detail
35 */ 44 */
36enum rsnd_reg { 45enum rsnd_reg {
37 /* SRU/SCU/SSIU */ 46 /* SCU (SRC/SSIU/MIX/CTU/DVC) */
47 RSND_REG_SSI_MODE, /* Gen2 only */
38 RSND_REG_SSI_MODE0, 48 RSND_REG_SSI_MODE0,
39 RSND_REG_SSI_MODE1, 49 RSND_REG_SSI_MODE1,
40 RSND_REG_SRC_BUSIF_MODE, 50 RSND_REG_SSI_MODE2,
51 RSND_REG_SSI_CONTROL,
52 RSND_REG_SSI_CTRL, /* Gen2 only */
53 RSND_REG_SSI_BUSIF_MODE, /* Gen2 only */
54 RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */
55 RSND_REG_SSI_BUSIF_DALIGN, /* Gen2 only */
56 RSND_REG_SSI_INT_ENABLE, /* Gen2 only */
57 RSND_REG_SRC_I_BUSIF_MODE,
58 RSND_REG_SRC_O_BUSIF_MODE,
41 RSND_REG_SRC_ROUTE_MODE0, 59 RSND_REG_SRC_ROUTE_MODE0,
42 RSND_REG_SRC_SWRSR, 60 RSND_REG_SRC_SWRSR,
43 RSND_REG_SRC_SRCIR, 61 RSND_REG_SRC_SRCIR,
@@ -45,9 +63,29 @@ enum rsnd_reg {
45 RSND_REG_SRC_IFSCR, 63 RSND_REG_SRC_IFSCR,
46 RSND_REG_SRC_IFSVR, 64 RSND_REG_SRC_IFSVR,
47 RSND_REG_SRC_SRCCR, 65 RSND_REG_SRC_SRCCR,
66 RSND_REG_SRC_CTRL, /* Gen2 only */
67 RSND_REG_SRC_BSDSR, /* Gen2 only */
68 RSND_REG_SRC_BSISR, /* Gen2 only */
69 RSND_REG_SRC_INT_ENABLE0, /* Gen2 only */
70 RSND_REG_SRC_BUSIF_DALIGN, /* Gen2 only */
71 RSND_REG_SRCIN_TIMSEL0, /* Gen2 only */
72 RSND_REG_SRCIN_TIMSEL1, /* Gen2 only */
73 RSND_REG_SRCIN_TIMSEL2, /* Gen2 only */
74 RSND_REG_SRCIN_TIMSEL3, /* Gen2 only */
75 RSND_REG_SRCIN_TIMSEL4, /* Gen2 only */
76 RSND_REG_SRCOUT_TIMSEL0, /* Gen2 only */
77 RSND_REG_SRCOUT_TIMSEL1, /* Gen2 only */
78 RSND_REG_SRCOUT_TIMSEL2, /* Gen2 only */
79 RSND_REG_SRCOUT_TIMSEL3, /* Gen2 only */
80 RSND_REG_SRCOUT_TIMSEL4, /* Gen2 only */
48 RSND_REG_SCU_SYS_STATUS0, 81 RSND_REG_SCU_SYS_STATUS0,
82 RSND_REG_SCU_SYS_STATUS1, /* Gen2 only */
49 RSND_REG_SCU_SYS_INT_EN0, 83 RSND_REG_SCU_SYS_INT_EN0,
84 RSND_REG_SCU_SYS_INT_EN1, /* Gen2 only */
85 RSND_REG_CMD_CTRL, /* Gen2 only */
86 RSND_REG_CMD_BUSIF_DALIGN, /* Gen2 only */
50 RSND_REG_CMD_ROUTE_SLCT, 87 RSND_REG_CMD_ROUTE_SLCT,
88 RSND_REG_CMDOUT_TIMSEL, /* Gen2 only */
51 RSND_REG_CTU_CTUIR, 89 RSND_REG_CTU_CTUIR,
52 RSND_REG_CTU_ADINR, 90 RSND_REG_CTU_ADINR,
53 RSND_REG_MIX_SWRSR, 91 RSND_REG_MIX_SWRSR,
@@ -67,14 +105,25 @@ enum rsnd_reg {
67 RSND_REG_DVC_ZCMCR, 105 RSND_REG_DVC_ZCMCR,
68 RSND_REG_DVC_VOL0R, 106 RSND_REG_DVC_VOL0R,
69 RSND_REG_DVC_VOL1R, 107 RSND_REG_DVC_VOL1R,
108 RSND_REG_DVC_VOL2R,
109 RSND_REG_DVC_VOL3R,
110 RSND_REG_DVC_VOL4R,
111 RSND_REG_DVC_VOL5R,
112 RSND_REG_DVC_VOL6R,
113 RSND_REG_DVC_VOL7R,
70 RSND_REG_DVC_DVUER, 114 RSND_REG_DVC_DVUER,
115 RSND_REG_DVC_VRCTR, /* Gen2 only */
116 RSND_REG_DVC_VRPDR, /* Gen2 only */
117 RSND_REG_DVC_VRDBR, /* Gen2 only */
71 118
72 /* ADG */ 119 /* ADG */
73 RSND_REG_BRRA, 120 RSND_REG_BRRA,
74 RSND_REG_BRRB, 121 RSND_REG_BRRB,
75 RSND_REG_SSICKR, 122 RSND_REG_SSICKR,
123 RSND_REG_DIV_EN, /* Gen2 only */
76 RSND_REG_AUDIO_CLK_SEL0, 124 RSND_REG_AUDIO_CLK_SEL0,
77 RSND_REG_AUDIO_CLK_SEL1, 125 RSND_REG_AUDIO_CLK_SEL1,
126 RSND_REG_AUDIO_CLK_SEL2, /* Gen2 only */
78 127
79 /* SSI */ 128 /* SSI */
80 RSND_REG_SSICR, 129 RSND_REG_SSICR,
@@ -83,83 +132,9 @@ enum rsnd_reg {
83 RSND_REG_SSIRDR, 132 RSND_REG_SSIRDR,
84 RSND_REG_SSIWSR, 133 RSND_REG_SSIWSR,
85 134
86 /* SHARE see below */
87 RSND_REG_SHARE01,
88 RSND_REG_SHARE02,
89 RSND_REG_SHARE03,
90 RSND_REG_SHARE04,
91 RSND_REG_SHARE05,
92 RSND_REG_SHARE06,
93 RSND_REG_SHARE07,
94 RSND_REG_SHARE08,
95 RSND_REG_SHARE09,
96 RSND_REG_SHARE10,
97 RSND_REG_SHARE11,
98 RSND_REG_SHARE12,
99 RSND_REG_SHARE13,
100 RSND_REG_SHARE14,
101 RSND_REG_SHARE15,
102 RSND_REG_SHARE16,
103 RSND_REG_SHARE17,
104 RSND_REG_SHARE18,
105 RSND_REG_SHARE19,
106 RSND_REG_SHARE20,
107 RSND_REG_SHARE21,
108 RSND_REG_SHARE22,
109 RSND_REG_SHARE23,
110 RSND_REG_SHARE24,
111 RSND_REG_SHARE25,
112 RSND_REG_SHARE26,
113 RSND_REG_SHARE27,
114 RSND_REG_SHARE28,
115 RSND_REG_SHARE29,
116
117 RSND_REG_MAX, 135 RSND_REG_MAX,
118}; 136};
119 137
120/* Gen1 only */
121#define RSND_REG_SRC_ROUTE_SEL RSND_REG_SHARE01
122#define RSND_REG_SRC_TMG_SEL0 RSND_REG_SHARE02
123#define RSND_REG_SRC_TMG_SEL1 RSND_REG_SHARE03
124#define RSND_REG_SRC_TMG_SEL2 RSND_REG_SHARE04
125#define RSND_REG_SRC_ROUTE_CTRL RSND_REG_SHARE05
126#define RSND_REG_SRC_MNFSR RSND_REG_SHARE06
127#define RSND_REG_AUDIO_CLK_SEL3 RSND_REG_SHARE07
128#define RSND_REG_AUDIO_CLK_SEL4 RSND_REG_SHARE08
129#define RSND_REG_AUDIO_CLK_SEL5 RSND_REG_SHARE09
130
131/* Gen2 only */
132#define RSND_REG_SRC_CTRL RSND_REG_SHARE01
133#define RSND_REG_SSI_CTRL RSND_REG_SHARE02
134#define RSND_REG_SSI_BUSIF_MODE RSND_REG_SHARE03
135#define RSND_REG_SSI_BUSIF_ADINR RSND_REG_SHARE04
136#define RSND_REG_SSI_INT_ENABLE RSND_REG_SHARE05
137#define RSND_REG_SRC_BSDSR RSND_REG_SHARE06
138#define RSND_REG_SRC_BSISR RSND_REG_SHARE07
139#define RSND_REG_DIV_EN RSND_REG_SHARE08
140#define RSND_REG_SRCIN_TIMSEL0 RSND_REG_SHARE09
141#define RSND_REG_SRCIN_TIMSEL1 RSND_REG_SHARE10
142#define RSND_REG_SRCIN_TIMSEL2 RSND_REG_SHARE11
143#define RSND_REG_SRCIN_TIMSEL3 RSND_REG_SHARE12
144#define RSND_REG_SRCIN_TIMSEL4 RSND_REG_SHARE13
145#define RSND_REG_SRCOUT_TIMSEL0 RSND_REG_SHARE14
146#define RSND_REG_SRCOUT_TIMSEL1 RSND_REG_SHARE15
147#define RSND_REG_SRCOUT_TIMSEL2 RSND_REG_SHARE16
148#define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17
149#define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18
150#define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19
151#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
152#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
153#define RSND_REG_SSI_BUSIF_DALIGN RSND_REG_SHARE22
154#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
155#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
156#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
157#define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26
158#define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27
159#define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28
160#define RSND_REG_SRC_BUSIF_DALIGN RSND_REG_SHARE29
161
162struct rsnd_of_data;
163struct rsnd_priv; 138struct rsnd_priv;
164struct rsnd_mod; 139struct rsnd_mod;
165struct rsnd_dai; 140struct rsnd_dai;
@@ -187,43 +162,13 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
187u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 162u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
188u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 163u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
189u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 164u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
190void rsnd_path_parse(struct rsnd_priv *priv,
191 struct rsnd_dai_stream *io);
192 165
193/* 166/*
194 * R-Car DMA 167 * R-Car DMA
195 */ 168 */
196struct rsnd_dma; 169struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io,
197 170 struct rsnd_mod *mod, int id);
198struct rsnd_dmaen { 171int rsnd_dma_probe(struct rsnd_priv *priv);
199 struct dma_chan *chan;
200};
201
202struct rsnd_dmapp {
203 int dmapp_id;
204 u32 chcr;
205};
206
207struct rsnd_dma {
208 struct rsnd_dma_ops *ops;
209 dma_addr_t src_addr;
210 dma_addr_t dst_addr;
211 union {
212 struct rsnd_dmaen en;
213 struct rsnd_dmapp pp;
214 } dma;
215};
216#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
217#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
218#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
219
220void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
221void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
222int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id);
223void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
224int rsnd_dma_probe(struct platform_device *pdev,
225 const struct rsnd_of_data *of_data,
226 struct rsnd_priv *priv);
227struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 172struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
228 struct rsnd_mod *mod, char *name); 173 struct rsnd_mod *mod, char *name);
229 174
@@ -231,11 +176,19 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
231 * R-Car sound mod 176 * R-Car sound mod
232 */ 177 */
233enum rsnd_mod_type { 178enum rsnd_mod_type {
234 RSND_MOD_DVC = 0, 179 RSND_MOD_AUDMAPP,
180 RSND_MOD_AUDMA,
181 RSND_MOD_DVC,
235 RSND_MOD_MIX, 182 RSND_MOD_MIX,
236 RSND_MOD_CTU, 183 RSND_MOD_CTU,
184 RSND_MOD_CMD,
237 RSND_MOD_SRC, 185 RSND_MOD_SRC,
186 RSND_MOD_SSIM3, /* SSI multi 3 */
187 RSND_MOD_SSIM2, /* SSI multi 2 */
188 RSND_MOD_SSIM1, /* SSI multi 1 */
189 RSND_MOD_SSIP, /* SSI parent */
238 RSND_MOD_SSI, 190 RSND_MOD_SSI,
191 RSND_MOD_SSIU,
239 RSND_MOD_MAX, 192 RSND_MOD_MAX,
240}; 193};
241 194
@@ -278,10 +231,8 @@ struct rsnd_mod {
278 int id; 231 int id;
279 enum rsnd_mod_type type; 232 enum rsnd_mod_type type;
280 struct rsnd_mod_ops *ops; 233 struct rsnd_mod_ops *ops;
281 struct rsnd_dma dma;
282 struct rsnd_priv *priv; 234 struct rsnd_priv *priv;
283 struct clk *clk; 235 struct clk *clk;
284 u32 status;
285}; 236};
286/* 237/*
287 * status 238 * status
@@ -328,7 +279,6 @@ struct rsnd_mod {
328#define __rsnd_mod_call_hw_params 0 279#define __rsnd_mod_call_hw_params 0
329 280
330#define rsnd_mod_to_priv(mod) ((mod)->priv) 281#define rsnd_mod_to_priv(mod) ((mod)->priv)
331#define rsnd_mod_to_dma(mod) (&(mod)->dma)
332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) 282#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
333#define rsnd_mod_power_on(mod) clk_enable((mod)->clk) 283#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
334#define rsnd_mod_power_off(mod) clk_disable((mod)->clk) 284#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
@@ -347,6 +297,17 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
347void rsnd_mod_interrupt(struct rsnd_mod *mod, 297void rsnd_mod_interrupt(struct rsnd_mod *mod,
348 void (*callback)(struct rsnd_mod *mod, 298 void (*callback)(struct rsnd_mod *mod,
349 struct rsnd_dai_stream *io)); 299 struct rsnd_dai_stream *io));
300void rsnd_parse_connect_common(struct rsnd_dai *rdai,
301 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
302 struct device_node *node,
303 struct device_node *playback,
304 struct device_node *capture);
305
306void rsnd_set_slot(struct rsnd_dai *rdai,
307 int slots, int slots_total);
308int rsnd_get_slot(struct rsnd_dai_stream *io);
309int rsnd_get_slot_width(struct rsnd_dai_stream *io);
310int rsnd_get_slot_num(struct rsnd_dai_stream *io);
350 311
351/* 312/*
352 * R-Car sound DAI 313 * R-Car sound DAI
@@ -358,6 +319,7 @@ struct rsnd_dai_stream {
358 struct rsnd_mod *mod[RSND_MOD_MAX]; 319 struct rsnd_mod *mod[RSND_MOD_MAX];
359 struct rsnd_dai_path_info *info; /* rcar_snd.h */ 320 struct rsnd_dai_path_info *info; /* rcar_snd.h */
360 struct rsnd_dai *rdai; 321 struct rsnd_dai *rdai;
322 u32 mod_status[RSND_MOD_MAX];
361 int byte_pos; 323 int byte_pos;
362 int period_pos; 324 int period_pos;
363 int byte_per_period; 325 int byte_per_period;
@@ -365,10 +327,12 @@ struct rsnd_dai_stream {
365}; 327};
366#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) 328#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
367#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) 329#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
330#define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP)
368#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC) 331#define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC)
369#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) 332#define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU)
370#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) 333#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX)
371#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC) 334#define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC)
335#define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD)
372#define rsnd_io_to_rdai(io) ((io)->rdai) 336#define rsnd_io_to_rdai(io) ((io)->rdai)
373#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) 337#define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
374#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) 338#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
@@ -382,6 +346,9 @@ struct rsnd_dai {
382 struct rsnd_dai_stream capture; 346 struct rsnd_dai_stream capture;
383 struct rsnd_priv *priv; 347 struct rsnd_priv *priv;
384 348
349 int slots;
350 int slots_num;
351
385 unsigned int clk_master:1; 352 unsigned int clk_master:1;
386 unsigned int bit_clk_inv:1; 353 unsigned int bit_clk_inv:1;
387 unsigned int frm_clk_inv:1; 354 unsigned int frm_clk_inv:1;
@@ -403,33 +370,28 @@ struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id);
403bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); 370bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
404void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); 371void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
405int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); 372int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
373int rsnd_dai_connect(struct rsnd_mod *mod,
374 struct rsnd_dai_stream *io,
375 enum rsnd_mod_type type);
376#define rsnd_dai_of_node(priv) \
377 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dai")
406 378
407/* 379/*
408 * R-Car Gen1/Gen2 380 * R-Car Gen1/Gen2
409 */ 381 */
410int rsnd_gen_probe(struct platform_device *pdev, 382int rsnd_gen_probe(struct rsnd_priv *priv);
411 const struct rsnd_of_data *of_data,
412 struct rsnd_priv *priv);
413void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 383void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
414 struct rsnd_mod *mod, 384 struct rsnd_mod *mod,
415 enum rsnd_reg reg); 385 enum rsnd_reg reg);
416phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); 386phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
417 387
418#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
419#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
420
421/* 388/*
422 * R-Car ADG 389 * R-Car ADG
423 */ 390 */
424int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); 391int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
425int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); 392int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
426int rsnd_adg_probe(struct platform_device *pdev, 393int rsnd_adg_probe(struct rsnd_priv *priv);
427 const struct rsnd_of_data *of_data, 394void rsnd_adg_remove(struct rsnd_priv *priv);
428 struct rsnd_priv *priv);
429int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
430 struct rsnd_mod *mod,
431 unsigned int src_rate,
432 unsigned int dst_rate);
433int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, 395int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
434 struct rsnd_dai_stream *io, 396 struct rsnd_dai_stream *io,
435 unsigned int src_rate, 397 unsigned int src_rate,
@@ -442,15 +404,14 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
442/* 404/*
443 * R-Car sound priv 405 * R-Car sound priv
444 */ 406 */
445struct rsnd_of_data {
446 u32 flags;
447};
448
449struct rsnd_priv { 407struct rsnd_priv {
450 408
451 struct platform_device *pdev; 409 struct platform_device *pdev;
452 struct rcar_snd_info *info;
453 spinlock_t lock; 410 spinlock_t lock;
411 unsigned long flags;
412#define RSND_GEN_MASK (0xF << 0)
413#define RSND_GEN1 (1 << 0)
414#define RSND_GEN2 (2 << 0)
454 415
455 /* 416 /*
456 * below value will be filled on rsnd_gen_probe() 417 * below value will be filled on rsnd_gen_probe()
@@ -474,6 +435,12 @@ struct rsnd_priv {
474 int ssi_nr; 435 int ssi_nr;
475 436
476 /* 437 /*
438 * below value will be filled on rsnd_ssiu_probe()
439 */
440 void *ssiu;
441 int ssiu_nr;
442
443 /*
477 * below value will be filled on rsnd_src_probe() 444 * below value will be filled on rsnd_src_probe()
478 */ 445 */
479 void *src; 446 void *src;
@@ -498,6 +465,12 @@ struct rsnd_priv {
498 int dvc_nr; 465 int dvc_nr;
499 466
500 /* 467 /*
468 * below value will be filled on rsnd_cmd_probe()
469 */
470 void *cmd;
471 int cmd_nr;
472
473 /*
501 * below value will be filled on rsnd_dai_probe() 474 * below value will be filled on rsnd_dai_probe()
502 */ 475 */
503 struct snd_soc_dai_driver *daidrv; 476 struct snd_soc_dai_driver *daidrv;
@@ -507,7 +480,9 @@ struct rsnd_priv {
507 480
508#define rsnd_priv_to_pdev(priv) ((priv)->pdev) 481#define rsnd_priv_to_pdev(priv) ((priv)->pdev)
509#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) 482#define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev))
510#define rsnd_priv_to_info(priv) ((priv)->info) 483
484#define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1)
485#define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2)
511 486
512/* 487/*
513 * rsnd_kctrl 488 * rsnd_kctrl
@@ -523,7 +498,7 @@ struct rsnd_kctrl_cfg {
523 struct snd_kcontrol *kctrl; 498 struct snd_kcontrol *kctrl;
524}; 499};
525 500
526#define RSND_DVC_CHANNELS 2 501#define RSND_DVC_CHANNELS 8
527struct rsnd_kctrl_cfg_m { 502struct rsnd_kctrl_cfg_m {
528 struct rsnd_kctrl_cfg cfg; 503 struct rsnd_kctrl_cfg cfg;
529 u32 val[RSND_DVC_CHANNELS]; 504 u32 val[RSND_DVC_CHANNELS];
@@ -544,6 +519,7 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod,
544 void (*update)(struct rsnd_dai_stream *io, 519 void (*update)(struct rsnd_dai_stream *io,
545 struct rsnd_mod *mod), 520 struct rsnd_mod *mod),
546 struct rsnd_kctrl_cfg_m *_cfg, 521 struct rsnd_kctrl_cfg_m *_cfg,
522 int ch_size,
547 u32 max); 523 u32 max);
548int rsnd_kctrl_new_s(struct rsnd_mod *mod, 524int rsnd_kctrl_new_s(struct rsnd_mod *mod,
549 struct rsnd_dai_stream *io, 525 struct rsnd_dai_stream *io,
@@ -566,70 +542,93 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
566/* 542/*
567 * R-Car SSI 543 * R-Car SSI
568 */ 544 */
569int rsnd_ssi_probe(struct platform_device *pdev, 545int rsnd_ssi_probe(struct rsnd_priv *priv);
570 const struct rsnd_of_data *of_data, 546void rsnd_ssi_remove(struct rsnd_priv *priv);
571 struct rsnd_priv *priv);
572void rsnd_ssi_remove(struct platform_device *pdev,
573 struct rsnd_priv *priv);
574struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 547struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 548int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); 549int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
550u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io);
577 551
578#define rsnd_ssi_is_pin_sharing(io) \ 552#define rsnd_ssi_is_pin_sharing(io) \
579 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) 553 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
580int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 554int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
581 555
556#define rsnd_ssi_of_node(priv) \
557 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
558void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
559 struct device_node *playback,
560 struct device_node *capture);
561
562/*
563 * R-Car SSIU
564 */
565int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
566 struct rsnd_mod *mod);
567int rsnd_ssiu_probe(struct rsnd_priv *priv);
568void rsnd_ssiu_remove(struct rsnd_priv *priv);
569
582/* 570/*
583 * R-Car SRC 571 * R-Car SRC
584 */ 572 */
585int rsnd_src_probe(struct platform_device *pdev, 573int rsnd_src_probe(struct rsnd_priv *priv);
586 const struct rsnd_of_data *of_data, 574void rsnd_src_remove(struct rsnd_priv *priv);
587 struct rsnd_priv *priv);
588void rsnd_src_remove(struct platform_device *pdev,
589 struct rsnd_priv *priv);
590struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 575struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
591unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 576unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
592 struct rsnd_dai_stream *io, 577 struct rsnd_dai_stream *io,
593 struct snd_pcm_runtime *runtime); 578 struct snd_pcm_runtime *runtime);
594int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 579#define rsnd_src_of_node(priv) \
595 struct rsnd_dai_stream *io, 580 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
596 int use_busif); 581#define rsnd_parse_connect_src(rdai, playback, capture) \
597int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, 582 rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \
598 struct rsnd_dai_stream *io); 583 rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \
599int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); 584 playback, capture)
600int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
601 585
602/* 586/*
603 * R-Car CTU 587 * R-Car CTU
604 */ 588 */
605int rsnd_ctu_probe(struct platform_device *pdev, 589int rsnd_ctu_probe(struct rsnd_priv *priv);
606 const struct rsnd_of_data *of_data, 590void rsnd_ctu_remove(struct rsnd_priv *priv);
607 struct rsnd_priv *priv);
608
609void rsnd_ctu_remove(struct platform_device *pdev,
610 struct rsnd_priv *priv);
611struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); 591struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
592#define rsnd_ctu_of_node(priv) \
593 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu")
594#define rsnd_parse_connect_ctu(rdai, playback, capture) \
595 rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \
596 rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \
597 playback, capture)
612 598
613/* 599/*
614 * R-Car MIX 600 * R-Car MIX
615 */ 601 */
616int rsnd_mix_probe(struct platform_device *pdev, 602int rsnd_mix_probe(struct rsnd_priv *priv);
617 const struct rsnd_of_data *of_data, 603void rsnd_mix_remove(struct rsnd_priv *priv);
618 struct rsnd_priv *priv);
619
620void rsnd_mix_remove(struct platform_device *pdev,
621 struct rsnd_priv *priv);
622struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); 604struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
605#define rsnd_mix_of_node(priv) \
606 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix")
607#define rsnd_parse_connect_mix(rdai, playback, capture) \
608 rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \
609 rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \
610 playback, capture)
623 611
624/* 612/*
625 * R-Car DVC 613 * R-Car DVC
626 */ 614 */
627int rsnd_dvc_probe(struct platform_device *pdev, 615int rsnd_dvc_probe(struct rsnd_priv *priv);
628 const struct rsnd_of_data *of_data, 616void rsnd_dvc_remove(struct rsnd_priv *priv);
629 struct rsnd_priv *priv);
630void rsnd_dvc_remove(struct platform_device *pdev,
631 struct rsnd_priv *priv);
632struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); 617struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
618#define rsnd_dvc_of_node(priv) \
619 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
620#define rsnd_parse_connect_dvc(rdai, playback, capture) \
621 rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \
622 rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \
623 playback, capture)
624
625/*
626 * R-Car CMD
627 */
628int rsnd_cmd_probe(struct rsnd_priv *priv);
629void rsnd_cmd_remove(struct rsnd_priv *priv);
630int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
631struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id);
633 632
634#ifdef DEBUG 633#ifdef DEBUG
635void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 634void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
index d61db9c385ea..8a357fdf1077 100644
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -48,8 +48,11 @@ MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
48 48
49#define DAI_NAME_NUM 32 49#define DAI_NAME_NUM 32
50struct rsrc_card_dai { 50struct rsrc_card_dai {
51 unsigned int fmt;
52 unsigned int sysclk; 51 unsigned int sysclk;
52 unsigned int tx_slot_mask;
53 unsigned int rx_slot_mask;
54 int slots;
55 int slot_width;
53 struct clk *clk; 56 struct clk *clk;
54 char dai_name[DAI_NAME_NUM]; 57 char dai_name[DAI_NAME_NUM];
55}; 58};
@@ -75,7 +78,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream)
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 79 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
77 struct rsrc_card_dai *dai_props = 80 struct rsrc_card_dai *dai_props =
78 rsrc_priv_to_props(priv, rtd - rtd->card->rtd); 81 rsrc_priv_to_props(priv, rtd->num);
79 82
80 return clk_prepare_enable(dai_props->clk); 83 return clk_prepare_enable(dai_props->clk);
81} 84}
@@ -85,7 +88,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
85 struct snd_soc_pcm_runtime *rtd = substream->private_data; 88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); 89 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
87 struct rsrc_card_dai *dai_props = 90 struct rsrc_card_dai *dai_props =
88 rsrc_priv_to_props(priv, rtd - rtd->card->rtd); 91 rsrc_priv_to_props(priv, rtd->num);
89 92
90 clk_disable_unprepare(dai_props->clk); 93 clk_disable_unprepare(dai_props->clk);
91} 94}
@@ -101,7 +104,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
101 struct snd_soc_dai *dai; 104 struct snd_soc_dai *dai;
102 struct snd_soc_dai_link *dai_link; 105 struct snd_soc_dai_link *dai_link;
103 struct rsrc_card_dai *dai_props; 106 struct rsrc_card_dai *dai_props;
104 int num = rtd - rtd->card->rtd; 107 int num = rtd->num;
105 int ret; 108 int ret;
106 109
107 dai_link = rsrc_priv_to_link(priv, num); 110 dai_link = rsrc_priv_to_link(priv, num);
@@ -110,18 +113,22 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
110 rtd->cpu_dai : 113 rtd->cpu_dai :
111 rtd->codec_dai; 114 rtd->codec_dai;
112 115
113 if (dai_props->fmt) { 116 if (dai_props->sysclk) {
114 ret = snd_soc_dai_set_fmt(dai, dai_props->fmt); 117 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0);
115 if (ret && ret != -ENOTSUPP) { 118 if (ret && ret != -ENOTSUPP) {
116 dev_err(dai->dev, "set_fmt error\n"); 119 dev_err(dai->dev, "set_sysclk error\n");
117 goto err; 120 goto err;
118 } 121 }
119 } 122 }
120 123
121 if (dai_props->sysclk) { 124 if (dai_props->slots) {
122 ret = snd_soc_dai_set_sysclk(dai, 0, dai_props->sysclk, 0); 125 ret = snd_soc_dai_set_tdm_slot(dai,
126 dai_props->tx_slot_mask,
127 dai_props->rx_slot_mask,
128 dai_props->slots,
129 dai_props->slot_width);
123 if (ret && ret != -ENOTSUPP) { 130 if (ret && ret != -ENOTSUPP) {
124 dev_err(dai->dev, "set_sysclk error\n"); 131 dev_err(dai->dev, "set_tdm_slot error\n");
125 goto err; 132 goto err;
126 } 133 }
127 } 134 }
@@ -148,14 +155,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
148} 155}
149 156
150static int rsrc_card_parse_daifmt(struct device_node *node, 157static int rsrc_card_parse_daifmt(struct device_node *node,
151 struct device_node *np, 158 struct device_node *codec,
152 struct rsrc_card_priv *priv, 159 struct rsrc_card_priv *priv,
153 int idx, bool is_fe) 160 struct snd_soc_dai_link *dai_link,
161 unsigned int *retfmt)
154{ 162{
155 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
156 struct device_node *bitclkmaster = NULL; 163 struct device_node *bitclkmaster = NULL;
157 struct device_node *framemaster = NULL; 164 struct device_node *framemaster = NULL;
158 struct device_node *codec = is_fe ? NULL : np;
159 unsigned int daifmt; 165 unsigned int daifmt;
160 166
161 daifmt = snd_soc_of_parse_daifmt(node, NULL, 167 daifmt = snd_soc_of_parse_daifmt(node, NULL,
@@ -172,11 +178,11 @@ static int rsrc_card_parse_daifmt(struct device_node *node,
172 daifmt |= (codec == framemaster) ? 178 daifmt |= (codec == framemaster) ?
173 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; 179 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
174 180
175 dai_props->fmt = daifmt;
176
177 of_node_put(bitclkmaster); 181 of_node_put(bitclkmaster);
178 of_node_put(framemaster); 182 of_node_put(framemaster);
179 183
184 *retfmt = daifmt;
185
180 return 0; 186 return 0;
181} 187}
182 188
@@ -198,6 +204,15 @@ static int rsrc_card_parse_links(struct device_node *np,
198 if (ret) 204 if (ret)
199 return ret; 205 return ret;
200 206
207 /* Parse TDM slot */
208 ret = snd_soc_of_parse_tdm_slot(np,
209 &dai_props->tx_slot_mask,
210 &dai_props->rx_slot_mask,
211 &dai_props->slots,
212 &dai_props->slot_width);
213 if (ret)
214 return ret;
215
201 if (is_fe) { 216 if (is_fe) {
202 /* BE is dummy */ 217 /* BE is dummy */
203 dai_link->codec_of_node = NULL; 218 dai_link->codec_of_node = NULL;
@@ -208,7 +223,9 @@ static int rsrc_card_parse_links(struct device_node *np,
208 dai_link->dynamic = 1; 223 dai_link->dynamic = 1;
209 dai_link->dpcm_merged_format = 1; 224 dai_link->dpcm_merged_format = 1;
210 dai_link->cpu_of_node = args.np; 225 dai_link->cpu_of_node = args.np;
211 snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name); 226 ret = snd_soc_of_get_dai_name(np, &dai_link->cpu_dai_name);
227 if (ret < 0)
228 return ret;
212 229
213 /* set dai_name */ 230 /* set dai_name */
214 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", 231 snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s",
@@ -240,7 +257,9 @@ static int rsrc_card_parse_links(struct device_node *np,
240 dai_link->no_pcm = 1; 257 dai_link->no_pcm = 1;
241 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup; 258 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
242 dai_link->codec_of_node = args.np; 259 dai_link->codec_of_node = args.np;
243 snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name); 260 ret = snd_soc_of_get_dai_name(np, &dai_link->codec_dai_name);
261 if (ret < 0)
262 return ret;
244 263
245 /* additional name prefix */ 264 /* additional name prefix */
246 if (of_data) { 265 if (of_data) {
@@ -305,23 +324,16 @@ static int rsrc_card_parse_clk(struct device_node *np,
305 return 0; 324 return 0;
306} 325}
307 326
308static int rsrc_card_dai_link_of(struct device_node *node, 327static int rsrc_card_dai_sub_link_of(struct device_node *node,
309 struct device_node *np, 328 struct device_node *np,
310 struct rsrc_card_priv *priv, 329 struct rsrc_card_priv *priv,
311 int idx) 330 int idx, bool is_fe)
312{ 331{
313 struct device *dev = rsrc_priv_to_dev(priv); 332 struct device *dev = rsrc_priv_to_dev(priv);
333 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
314 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); 334 struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx);
315 bool is_fe = false;
316 int ret; 335 int ret;
317 336
318 if (0 == strcmp(np->name, "cpu"))
319 is_fe = true;
320
321 ret = rsrc_card_parse_daifmt(node, np, priv, idx, is_fe);
322 if (ret < 0)
323 return ret;
324
325 ret = rsrc_card_parse_links(np, priv, idx, is_fe); 337 ret = rsrc_card_parse_links(np, priv, idx, is_fe);
326 if (ret < 0) 338 if (ret < 0)
327 return ret; 339 return ret;
@@ -332,12 +344,54 @@ static int rsrc_card_dai_link_of(struct device_node *node,
332 344
333 dev_dbg(dev, "\t%s / %04x / %d\n", 345 dev_dbg(dev, "\t%s / %04x / %d\n",
334 dai_props->dai_name, 346 dai_props->dai_name,
335 dai_props->fmt, 347 dai_link->dai_fmt,
336 dai_props->sysclk); 348 dai_props->sysclk);
337 349
338 return ret; 350 return ret;
339} 351}
340 352
353static int rsrc_card_dai_link_of(struct device_node *node,
354 struct rsrc_card_priv *priv)
355{
356 struct snd_soc_dai_link *dai_link;
357 struct device_node *np;
358 unsigned int daifmt = 0;
359 int ret, i;
360 bool is_fe;
361
362 /* find 1st codec */
363 i = 0;
364 for_each_child_of_node(node, np) {
365 dai_link = rsrc_priv_to_link(priv, i);
366
367 if (strcmp(np->name, "codec") == 0) {
368 ret = rsrc_card_parse_daifmt(node, np, priv,
369 dai_link, &daifmt);
370 if (ret < 0)
371 return ret;
372 break;
373 }
374 i++;
375 }
376
377 i = 0;
378 for_each_child_of_node(node, np) {
379 dai_link = rsrc_priv_to_link(priv, i);
380 dai_link->dai_fmt = daifmt;
381
382 is_fe = false;
383 if (strcmp(np->name, "cpu") == 0)
384 is_fe = true;
385
386 ret = rsrc_card_dai_sub_link_of(node, np, priv, i, is_fe);
387 if (ret < 0)
388 return ret;
389 i++;
390 }
391
392 return 0;
393}
394
341static int rsrc_card_parse_of(struct device_node *node, 395static int rsrc_card_parse_of(struct device_node *node,
342 struct rsrc_card_priv *priv, 396 struct rsrc_card_priv *priv,
343 struct device *dev) 397 struct device *dev)
@@ -345,9 +399,8 @@ static int rsrc_card_parse_of(struct device_node *node,
345 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev); 399 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
346 struct rsrc_card_dai *props; 400 struct rsrc_card_dai *props;
347 struct snd_soc_dai_link *links; 401 struct snd_soc_dai_link *links;
348 struct device_node *np;
349 int ret; 402 int ret;
350 int i, num; 403 int num;
351 404
352 if (!node) 405 if (!node)
353 return -EINVAL; 406 return -EINVAL;
@@ -388,13 +441,9 @@ static int rsrc_card_parse_of(struct device_node *node,
388 priv->snd_card.name ? priv->snd_card.name : "", 441 priv->snd_card.name ? priv->snd_card.name : "",
389 priv->convert_rate); 442 priv->convert_rate);
390 443
391 i = 0; 444 ret = rsrc_card_dai_link_of(node, priv);
392 for_each_child_of_node(node, np) { 445 if (ret < 0)
393 ret = rsrc_card_dai_link_of(node, np, priv, i); 446 return ret;
394 if (ret < 0)
395 return ret;
396 i++;
397 }
398 447
399 if (!priv->snd_card.name) 448 if (!priv->snd_card.name)
400 priv->snd_card.name = priv->snd_card.dai_link->name; 449 priv->snd_card.name = priv->snd_card.dai_link->name;
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 68b439ed22d7..5eda056d9f20 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -20,20 +20,21 @@
20#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) 20#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id))
21 21
22struct rsnd_src { 22struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
24 struct rsnd_mod mod; 23 struct rsnd_mod mod;
24 struct rsnd_mod *dma;
25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ 25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
26 struct rsnd_kctrl_cfg_s sync; /* sync convert */ 26 struct rsnd_kctrl_cfg_s sync; /* sync convert */
27 u32 convert_rate; /* sampling rate convert */ 27 u32 convert_rate; /* sampling rate convert */
28 int err; 28 int err;
29 int irq;
29}; 30};
30 31
31#define RSND_SRC_NAME_SIZE 16 32#define RSND_SRC_NAME_SIZE 16
32 33
34#define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id)
35#define rsnd_src_to_dma(src) ((src)->dma)
33#define rsnd_src_nr(priv) ((priv)->src_nr) 36#define rsnd_src_nr(priv) ((priv)->src_nr)
34#define rsnd_enable_sync_convert(src) ((src)->sen.val) 37#define rsnd_enable_sync_convert(src) ((src)->sen.val)
35#define rsnd_src_of_node(priv) \
36 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
37 38
38#define rsnd_mod_to_src(_mod) \ 39#define rsnd_mod_to_src(_mod) \
39 container_of((_mod), struct rsnd_src, mod) 40 container_of((_mod), struct rsnd_src, mod)
@@ -69,67 +70,16 @@ struct rsnd_src {
69 * |-----------------| 70 * |-----------------|
70 */ 71 */
71 72
72/* 73static void rsnd_src_activation(struct rsnd_mod *mod)
73 * How to use SRC bypass mode for debugging
74 *
75 * SRC has bypass mode, and it is useful for debugging.
76 * In Gen2 case,
77 * SRCm_MODE controls whether SRC is used or not
78 * SSI_MODE0 controls whether SSIU which receives SRC data
79 * is used or not.
80 * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
81 * but SRC bypass mode needs SSI_MODE0 only.
82 *
83 * This driver request
84 * struct rsnd_src_platform_info {
85 * u32 convert_rate;
86 * int dma_id;
87 * }
88 *
89 * rsnd_src_convert_rate() indicates
90 * above convert_rate, and it controls
91 * whether SRC is used or not.
92 *
93 * ex) doesn't use SRC
94 * static struct rsnd_dai_platform_info rsnd_dai = {
95 * .playback = { .ssi = &rsnd_ssi[0], },
96 * };
97 *
98 * ex) uses SRC
99 * static struct rsnd_src_platform_info rsnd_src[] = {
100 * RSND_SCU(48000, 0),
101 * ...
102 * };
103 * static struct rsnd_dai_platform_info rsnd_dai = {
104 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
105 * };
106 *
107 * ex) uses SRC bypass mode
108 * static struct rsnd_src_platform_info rsnd_src[] = {
109 * RSND_SCU(0, 0),
110 * ...
111 * };
112 * static struct rsnd_dai_platform_info rsnd_dai = {
113 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
114 * };
115 *
116 */
117
118/*
119 * Gen1/Gen2 common functions
120 */
121static void rsnd_src_soft_reset(struct rsnd_mod *mod)
122{ 74{
123 rsnd_mod_write(mod, SRC_SWRSR, 0); 75 rsnd_mod_write(mod, SRC_SWRSR, 0);
124 rsnd_mod_write(mod, SRC_SWRSR, 1); 76 rsnd_mod_write(mod, SRC_SWRSR, 1);
125} 77}
126 78
127 79static void rsnd_src_halt(struct rsnd_mod *mod)
128#define rsnd_src_initialize_lock(mod) __rsnd_src_initialize_lock(mod, 1)
129#define rsnd_src_initialize_unlock(mod) __rsnd_src_initialize_lock(mod, 0)
130static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable)
131{ 80{
132 rsnd_mod_write(mod, SRC_SRCIR, enable); 81 rsnd_mod_write(mod, SRC_SRCIR, 1);
82 rsnd_mod_write(mod, SRC_SWRSR, 0);
133} 83}
134 84
135static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, 85static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
@@ -143,99 +93,6 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
143 is_play ? "rx" : "tx"); 93 is_play ? "rx" : "tx");
144} 94}
145 95
146int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
147 struct rsnd_dai_stream *io,
148 int use_busif)
149{
150 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
151 int ssi_id = rsnd_mod_id(ssi_mod);
152
153 /*
154 * SSI_MODE0
155 */
156 rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
157 !use_busif << ssi_id);
158
159 /*
160 * SSI_MODE1
161 */
162 if (rsnd_ssi_is_pin_sharing(io)) {
163 int shift = -1;
164 switch (ssi_id) {
165 case 1:
166 shift = 0;
167 break;
168 case 2:
169 shift = 2;
170 break;
171 case 4:
172 shift = 16;
173 break;
174 }
175
176 if (shift >= 0)
177 rsnd_mod_bset(ssi_mod, SSI_MODE1,
178 0x3 << shift,
179 rsnd_rdai_is_clk_master(rdai) ?
180 0x2 << shift : 0x1 << shift);
181 }
182
183 /*
184 * DMA settings for SSIU
185 */
186 if (use_busif) {
187 u32 val = rsnd_get_dalign(ssi_mod, io);
188
189 rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
190 rsnd_get_adinr_bit(ssi_mod, io));
191 rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
192 rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
193
194 rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
195 }
196
197 return 0;
198}
199
200int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
201 struct rsnd_dai_stream *io)
202{
203 /*
204 * DMA settings for SSIU
205 */
206 rsnd_mod_write(ssi_mod, SSI_CTRL, 0);
207
208 return 0;
209}
210
211int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
212{
213 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
214
215 if (rsnd_is_gen1(priv))
216 return 0;
217
218 /* enable SSI interrupt if Gen2 */
219 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
220 rsnd_ssi_is_dma_mode(ssi_mod) ?
221 0x0e000000 : 0x0f000000);
222
223 return 0;
224}
225
226int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
227{
228 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
229
230 if (rsnd_is_gen1(priv))
231 return 0;
232
233 /* disable SSI interrupt if Gen2 */
234 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
235
236 return 0;
237}
238
239static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, 96static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
240 struct rsnd_src *src) 97 struct rsnd_src *src)
241{ 98{
@@ -283,34 +140,6 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
283 return rate; 140 return rate;
284} 141}
285 142
286static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
287 struct rsnd_dai_stream *io)
288{
289 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
290 struct rsnd_src *src = rsnd_mod_to_src(mod);
291 u32 convert_rate = rsnd_src_convert_rate(io, src);
292 u32 fsrate = 0;
293
294 if (convert_rate)
295 fsrate = 0x0400000 / convert_rate * runtime->rate;
296
297 /* Set channel number and output bit length */
298 rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io));
299
300 /* Enable the initial value of IFS */
301 if (fsrate) {
302 rsnd_mod_write(mod, SRC_IFSCR, 1);
303
304 /* Set initial value of IFS */
305 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
306 }
307
308 /* use DMA transfer */
309 rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
310
311 return 0;
312}
313
314static int rsnd_src_hw_params(struct rsnd_mod *mod, 143static int rsnd_src_hw_params(struct rsnd_mod *mod,
315 struct rsnd_dai_stream *io, 144 struct rsnd_dai_stream *io,
316 struct snd_pcm_substream *substream, 145 struct snd_pcm_substream *substream,
@@ -319,9 +148,6 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct rsnd_src *src = rsnd_mod_to_src(mod); 148 struct rsnd_src *src = rsnd_mod_to_src(mod);
320 struct snd_soc_pcm_runtime *fe = substream->private_data; 149 struct snd_soc_pcm_runtime *fe = substream->private_data;
321 150
322 /* default value (mainly for non-DT) */
323 src->convert_rate = src->info->convert_rate;
324
325 /* 151 /*
326 * SRC assumes that it is used under DPCM if user want to use 152 * SRC assumes that it is used under DPCM if user want to use
327 * sampling rate convert. Then, SRC should be FE. 153 * sampling rate convert. Then, SRC should be FE.
@@ -347,250 +173,112 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
347 return 0; 173 return 0;
348} 174}
349 175
350static int rsnd_src_init(struct rsnd_mod *mod, 176static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
351 struct rsnd_priv *priv) 177 struct rsnd_mod *mod)
352{
353 struct rsnd_src *src = rsnd_mod_to_src(mod);
354
355 rsnd_mod_power_on(mod);
356
357 rsnd_src_soft_reset(mod);
358
359 rsnd_src_initialize_lock(mod);
360
361 src->err = 0;
362
363 /* reset sync convert_rate */
364 src->sync.val = 0;
365
366 return 0;
367}
368
369static int rsnd_src_quit(struct rsnd_mod *mod,
370 struct rsnd_dai_stream *io,
371 struct rsnd_priv *priv)
372{ 178{
373 struct rsnd_src *src = rsnd_mod_to_src(mod); 179 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
374 struct device *dev = rsnd_priv_to_dev(priv); 180 struct device *dev = rsnd_priv_to_dev(priv);
181 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
182 struct rsnd_src *src = rsnd_mod_to_src(mod);
183 u32 convert_rate = rsnd_src_convert_rate(io, src);
184 u32 ifscr, fsrate, adinr;
185 u32 cr, route;
186 u32 bsdsr, bsisr;
187 uint ratio;
375 188
376 rsnd_mod_power_off(mod); 189 if (!runtime)
377 190 return;
378 if (src->err)
379 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
380 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
381
382 src->convert_rate = 0;
383
384 /* reset sync convert_rate */
385 src->sync.val = 0;
386
387 return 0;
388}
389
390static int rsnd_src_start(struct rsnd_mod *mod)
391{
392 rsnd_src_initialize_unlock(mod);
393
394 return 0;
395}
396
397static int rsnd_src_stop(struct rsnd_mod *mod)
398{
399 /* nothing to do */
400 return 0;
401}
402 191
403/* 192 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
404 * Gen1 functions 193 if (!convert_rate)
405 */ 194 ratio = 0;
406static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, 195 else if (convert_rate > runtime->rate)
407 struct rsnd_mod *mod) 196 ratio = 100 * convert_rate / runtime->rate;
408{ 197 else
409 struct src_route_config { 198 ratio = 100 * runtime->rate / convert_rate;
410 u32 mask;
411 int shift;
412 } routes[] = {
413 { 0xF, 0, }, /* 0 */
414 { 0xF, 4, }, /* 1 */
415 { 0xF, 8, }, /* 2 */
416 { 0x7, 12, }, /* 3 */
417 { 0x7, 16, }, /* 4 */
418 { 0x7, 20, }, /* 5 */
419 { 0x7, 24, }, /* 6 */
420 { 0x3, 28, }, /* 7 */
421 { 0x3, 30, }, /* 8 */
422 };
423 u32 mask;
424 u32 val;
425 int id;
426 199
427 id = rsnd_mod_id(mod); 200 if (ratio > 600) {
428 if (id < 0 || id >= ARRAY_SIZE(routes)) 201 dev_err(dev, "FSO/FSI ratio error\n");
429 return -EIO; 202 return;
203 }
430 204
431 /* 205 /*
432 * SRC_ROUTE_SELECT 206 * SRC_ADINR
433 */ 207 */
434 val = rsnd_io_is_play(io) ? 0x1 : 0x2; 208 adinr = rsnd_get_adinr_bit(mod, io) |
435 val = val << routes[id].shift; 209 rsnd_get_adinr_chan(mod, io);
436 mask = routes[id].mask << routes[id].shift;
437
438 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
439
440 return 0;
441}
442
443static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
444 struct rsnd_mod *mod)
445{
446 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
447 struct rsnd_src *src = rsnd_mod_to_src(mod);
448 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
449 u32 convert_rate = rsnd_src_convert_rate(io, src);
450 u32 mask;
451 u32 val;
452 int shift;
453 int id = rsnd_mod_id(mod);
454 int ret;
455 210
456 /* 211 /*
457 * SRC_TIMING_SELECT 212 * SRC_IFSCR / SRC_IFSVR
458 */ 213 */
459 shift = (id % 4) * 8; 214 ifscr = 0;
460 mask = 0x1F << shift; 215 fsrate = 0;
216 if (convert_rate) {
217 ifscr = 1;
218 fsrate = 0x0400000 / convert_rate * runtime->rate;
219 }
461 220
462 /* 221 /*
463 * ADG is used as source clock if SRC was used, 222 * SRC_SRCCR / SRC_ROUTE_MODE0
464 * then, SSI WS is used as destination clock.
465 * SSI WS is used as source clock if SRC is not used
466 * (when playback, source/destination become reverse when capture)
467 */ 223 */
468 ret = 0; 224 cr = 0x00011110;
225 route = 0x0;
469 if (convert_rate) { 226 if (convert_rate) {
470 /* use ADG */ 227 route = 0x1;
471 val = 0;
472 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
473 runtime->rate,
474 convert_rate);
475 } else if (8 == id) {
476 /* use SSI WS, but SRU8 is special */
477 val = id << shift;
478 } else {
479 /* use SSI WS */
480 val = (id + 1) << shift;
481 }
482 228
483 if (ret < 0) 229 if (rsnd_enable_sync_convert(src)) {
484 return ret; 230 cr |= 0x1;
231 route |= rsnd_io_is_play(io) ?
232 (0x1 << 24) : (0x1 << 25);
233 }
234 }
485 235
486 switch (id / 4) { 236 /*
487 case 0: 237 * SRC_BSDSR / SRC_BSISR
488 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); 238 */
489 break; 239 switch (rsnd_mod_id(mod)) {
490 case 1: 240 case 5:
491 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); 241 case 6:
242 case 7:
243 case 8:
244 bsdsr = 0x02400000; /* 6 - 1/6 */
245 bsisr = 0x00100060; /* 6 - 1/6 */
492 break; 246 break;
493 case 2: 247 default:
494 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); 248 bsdsr = 0x01800000; /* 6 - 1/6 */
249 bsisr = 0x00100060 ;/* 6 - 1/6 */
495 break; 250 break;
496 } 251 }
497 252
498 return 0; 253 rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */
499} 254 rsnd_mod_write(mod, SRC_ADINR, adinr);
500 255 rsnd_mod_write(mod, SRC_IFSCR, ifscr);
501static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, 256 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
502 struct rsnd_dai_stream *io) 257 rsnd_mod_write(mod, SRC_SRCCR, cr);
503{ 258 rsnd_mod_write(mod, SRC_BSDSR, bsdsr);
504 struct rsnd_src *src = rsnd_mod_to_src(mod); 259 rsnd_mod_write(mod, SRC_BSISR, bsisr);
505 int ret; 260 rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */
506
507 ret = rsnd_src_set_convert_rate(mod, io);
508 if (ret < 0)
509 return ret;
510
511 /* Select SRC mode (fixed value) */
512 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
513
514 /* Set the restriction value of the FS ratio (98%) */
515 rsnd_mod_write(mod, SRC_MNFSR,
516 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
517
518 /* Gen1/Gen2 are not compatible */
519 if (rsnd_src_convert_rate(io, src))
520 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
521
522 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
523
524 return 0;
525}
526
527static int rsnd_src_init_gen1(struct rsnd_mod *mod,
528 struct rsnd_dai_stream *io,
529 struct rsnd_priv *priv)
530{
531 int ret;
532
533 ret = rsnd_src_init(mod, priv);
534 if (ret < 0)
535 return ret;
536
537 ret = rsnd_src_set_route_gen1(io, mod);
538 if (ret < 0)
539 return ret;
540
541 ret = rsnd_src_set_convert_rate_gen1(mod, io);
542 if (ret < 0)
543 return ret;
544
545 ret = rsnd_src_set_convert_timing_gen1(io, mod);
546 if (ret < 0)
547 return ret;
548
549 return 0;
550}
551
552static int rsnd_src_start_gen1(struct rsnd_mod *mod,
553 struct rsnd_dai_stream *io,
554 struct rsnd_priv *priv)
555{
556 int id = rsnd_mod_id(mod);
557
558 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
559
560 return rsnd_src_start(mod);
561}
562
563static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
564 struct rsnd_dai_stream *io,
565 struct rsnd_priv *priv)
566{
567 int id = rsnd_mod_id(mod);
568 261
569 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); 262 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
263 rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1);
264 rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1);
265 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
570 266
571 return rsnd_src_stop(mod); 267 if (convert_rate)
268 rsnd_adg_set_convert_clk_gen2(mod, io,
269 runtime->rate,
270 convert_rate);
271 else
272 rsnd_adg_set_convert_timing_gen2(mod, io);
572} 273}
573 274
574static struct rsnd_mod_ops rsnd_src_gen1_ops = { 275#define rsnd_src_irq_enable(mod) rsnd_src_irq_ctrol(mod, 1)
575 .name = SRC_NAME, 276#define rsnd_src_irq_disable(mod) rsnd_src_irq_ctrol(mod, 0)
576 .dma_req = rsnd_src_dma_req, 277static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable)
577 .init = rsnd_src_init_gen1,
578 .quit = rsnd_src_quit,
579 .start = rsnd_src_start_gen1,
580 .stop = rsnd_src_stop_gen1,
581 .hw_params = rsnd_src_hw_params,
582};
583
584/*
585 * Gen2 functions
586 */
587#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
588#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
589static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
590{ 278{
591 struct rsnd_src *src = rsnd_mod_to_src(mod); 279 struct rsnd_src *src = rsnd_mod_to_src(mod);
592 u32 sys_int_val, int_val, sys_int_mask; 280 u32 sys_int_val, int_val, sys_int_mask;
593 int irq = src->info->irq; 281 int irq = src->irq;
594 int id = rsnd_mod_id(mod); 282 int id = rsnd_mod_id(mod);
595 283
596 sys_int_val = 284 sys_int_val =
@@ -600,7 +288,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
600 /* 288 /*
601 * IRQ is not supported on non-DT 289 * IRQ is not supported on non-DT
602 * see 290 * see
603 * rsnd_src_probe_gen2() 291 * rsnd_src_probe_()
604 */ 292 */
605 if ((irq <= 0) || !enable) { 293 if ((irq <= 0) || !enable) {
606 sys_int_val = 0; 294 sys_int_val = 0;
@@ -620,7 +308,7 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
620 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); 308 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
621} 309}
622 310
623static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) 311static void rsnd_src_status_clear(struct rsnd_mod *mod)
624{ 312{
625 u32 val = OUF_SRC(rsnd_mod_id(mod)); 313 u32 val = OUF_SRC(rsnd_mod_id(mod));
626 314
@@ -628,7 +316,7 @@ static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
628 rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); 316 rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
629} 317}
630 318
631static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) 319static bool rsnd_src_record_error(struct rsnd_mod *mod)
632{ 320{
633 struct rsnd_src *src = rsnd_mod_to_src(mod); 321 struct rsnd_src *src = rsnd_mod_to_src(mod);
634 u32 val0, val1; 322 u32 val0, val1;
@@ -652,22 +340,16 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
652 ret = true; 340 ret = true;
653 } 341 }
654 342
655 /* clear error static */
656 rsnd_src_error_clear_gen2(mod);
657
658 return ret; 343 return ret;
659} 344}
660 345
661static int _rsnd_src_start_gen2(struct rsnd_mod *mod, 346static int rsnd_src_start(struct rsnd_mod *mod,
662 struct rsnd_dai_stream *io) 347 struct rsnd_dai_stream *io,
348 struct rsnd_priv *priv)
663{ 349{
664 struct rsnd_src *src = rsnd_mod_to_src(mod); 350 struct rsnd_src *src = rsnd_mod_to_src(mod);
665 u32 val; 351 u32 val;
666 352
667 val = rsnd_get_dalign(mod, io);
668
669 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);
670
671 /* 353 /*
672 * WORKAROUND 354 * WORKAROUND
673 * 355 *
@@ -678,247 +360,149 @@ static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
678 360
679 rsnd_mod_write(mod, SRC_CTRL, val); 361 rsnd_mod_write(mod, SRC_CTRL, val);
680 362
681 rsnd_src_error_clear_gen2(mod); 363 return 0;
682 364}
683 rsnd_src_start(mod);
684 365
685 rsnd_src_irq_enable_gen2(mod); 366static int rsnd_src_stop(struct rsnd_mod *mod,
367 struct rsnd_dai_stream *io,
368 struct rsnd_priv *priv)
369{
370 /*
371 * stop SRC output only
372 * see rsnd_src_quit
373 */
374 rsnd_mod_write(mod, SRC_CTRL, 0x01);
686 375
687 return 0; 376 return 0;
688} 377}
689 378
690static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) 379static int rsnd_src_init(struct rsnd_mod *mod,
380 struct rsnd_dai_stream *io,
381 struct rsnd_priv *priv)
691{ 382{
692 rsnd_src_irq_disable_gen2(mod); 383 struct rsnd_src *src = rsnd_mod_to_src(mod);
693 384
694 rsnd_mod_write(mod, SRC_CTRL, 0); 385 rsnd_mod_power_on(mod);
386
387 rsnd_src_activation(mod);
388
389 rsnd_src_set_convert_rate(io, mod);
695 390
696 rsnd_src_error_record_gen2(mod); 391 rsnd_src_status_clear(mod);
392
393 rsnd_src_irq_enable(mod);
394
395 src->err = 0;
697 396
698 return rsnd_src_stop(mod); 397 /* reset sync convert_rate */
398 src->sync.val = 0;
399
400 return 0;
699} 401}
700 402
701static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, 403static int rsnd_src_quit(struct rsnd_mod *mod,
702 struct rsnd_dai_stream *io) 404 struct rsnd_dai_stream *io,
405 struct rsnd_priv *priv)
703{ 406{
704 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 407 struct rsnd_src *src = rsnd_mod_to_src(mod);
705 408 struct device *dev = rsnd_priv_to_dev(priv);
706 spin_lock(&priv->lock);
707 409
708 /* ignore all cases if not working */ 410 rsnd_src_irq_disable(mod);
709 if (!rsnd_io_is_working(io))
710 goto rsnd_src_interrupt_gen2_out;
711 411
712 if (rsnd_src_error_record_gen2(mod)) { 412 /* stop both out/in */
713 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 413 rsnd_mod_write(mod, SRC_CTRL, 0);
714 struct rsnd_src *src = rsnd_mod_to_src(mod);
715 struct device *dev = rsnd_priv_to_dev(priv);
716 414
717 dev_dbg(dev, "%s[%d] restart\n", 415 rsnd_src_halt(mod);
718 rsnd_mod_name(mod), rsnd_mod_id(mod));
719 416
720 _rsnd_src_stop_gen2(mod); 417 rsnd_mod_power_off(mod);
721 if (src->err < 1024)
722 _rsnd_src_start_gen2(mod, io);
723 else
724 dev_warn(dev, "no more SRC restart\n");
725 }
726 418
727rsnd_src_interrupt_gen2_out: 419 if (src->err)
728 spin_unlock(&priv->lock); 420 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
729} 421 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
730 422
731static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) 423 src->convert_rate = 0;
732{
733 struct rsnd_mod *mod = data;
734 424
735 rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); 425 /* reset sync convert_rate */
426 src->sync.val = 0;
736 427
737 return IRQ_HANDLED; 428 return 0;
738} 429}
739 430
740static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, 431static void __rsnd_src_interrupt(struct rsnd_mod *mod,
741 struct rsnd_dai_stream *io) 432 struct rsnd_dai_stream *io)
742{ 433{
743 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 434 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
744 struct device *dev = rsnd_priv_to_dev(priv);
745 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
746 struct rsnd_src *src = rsnd_mod_to_src(mod); 435 struct rsnd_src *src = rsnd_mod_to_src(mod);
747 u32 convert_rate = rsnd_src_convert_rate(io, src); 436 struct device *dev = rsnd_priv_to_dev(priv);
748 u32 cr, route;
749 uint ratio;
750 int ret;
751 437
752 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ 438 spin_lock(&priv->lock);
753 if (!convert_rate)
754 ratio = 0;
755 else if (convert_rate > runtime->rate)
756 ratio = 100 * convert_rate / runtime->rate;
757 else
758 ratio = 100 * runtime->rate / convert_rate;
759 439
760 if (ratio > 600) { 440 /* ignore all cases if not working */
761 dev_err(dev, "FSO/FSI ratio error\n"); 441 if (!rsnd_io_is_working(io))
762 return -EINVAL; 442 goto rsnd_src_interrupt_out;
763 }
764 443
765 ret = rsnd_src_set_convert_rate(mod, io); 444 if (rsnd_src_record_error(mod)) {
766 if (ret < 0)
767 return ret;
768 445
769 cr = 0x00011110; 446 dev_dbg(dev, "%s[%d] restart\n",
770 route = 0x0; 447 rsnd_mod_name(mod), rsnd_mod_id(mod));
771 if (convert_rate) {
772 route = 0x1;
773 448
774 if (rsnd_enable_sync_convert(src)) { 449 rsnd_src_stop(mod, io, priv);
775 cr |= 0x1; 450 rsnd_src_start(mod, io, priv);
776 route |= rsnd_io_is_play(io) ?
777 (0x1 << 24) : (0x1 << 25);
778 }
779 } 451 }
780 452
781 rsnd_mod_write(mod, SRC_SRCCR, cr); 453 if (src->err > 1024) {
782 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); 454 rsnd_src_irq_disable(mod);
783 455
784 switch (rsnd_mod_id(mod)) { 456 dev_warn(dev, "no more %s[%d] restart\n",
785 case 5: 457 rsnd_mod_name(mod), rsnd_mod_id(mod));
786 case 6:
787 case 7:
788 case 8:
789 rsnd_mod_write(mod, SRC_BSDSR, 0x02400000);
790 break;
791 default:
792 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
793 break;
794 } 458 }
795 459
796 rsnd_mod_write(mod, SRC_BSISR, 0x00100060); 460 rsnd_src_status_clear(mod);
461rsnd_src_interrupt_out:
797 462
798 return 0; 463 spin_unlock(&priv->lock);
799} 464}
800 465
801static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, 466static irqreturn_t rsnd_src_interrupt(int irq, void *data)
802 struct rsnd_mod *mod)
803{ 467{
804 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 468 struct rsnd_mod *mod = data;
805 struct rsnd_src *src = rsnd_mod_to_src(mod);
806 u32 convert_rate = rsnd_src_convert_rate(io, src);
807 int ret;
808 469
809 if (convert_rate) 470 rsnd_mod_interrupt(mod, __rsnd_src_interrupt);
810 ret = rsnd_adg_set_convert_clk_gen2(mod, io,
811 runtime->rate,
812 convert_rate);
813 else
814 ret = rsnd_adg_set_convert_timing_gen2(mod, io);
815 471
816 return ret; 472 return IRQ_HANDLED;
817} 473}
818 474
819static int rsnd_src_probe_gen2(struct rsnd_mod *mod, 475static int rsnd_src_probe_(struct rsnd_mod *mod,
820 struct rsnd_dai_stream *io, 476 struct rsnd_dai_stream *io,
821 struct rsnd_priv *priv) 477 struct rsnd_priv *priv)
822{ 478{
823 struct rsnd_src *src = rsnd_mod_to_src(mod); 479 struct rsnd_src *src = rsnd_mod_to_src(mod);
824 struct device *dev = rsnd_priv_to_dev(priv); 480 struct device *dev = rsnd_priv_to_dev(priv);
825 int irq = src->info->irq; 481 int irq = src->irq;
826 int ret; 482 int ret;
827 483
828 if (irq > 0) { 484 if (irq > 0) {
829 /* 485 /*
830 * IRQ is not supported on non-DT 486 * IRQ is not supported on non-DT
831 * see 487 * see
832 * rsnd_src_irq_enable_gen2() 488 * rsnd_src_irq_enable()
833 */ 489 */
834 ret = devm_request_irq(dev, irq, 490 ret = devm_request_irq(dev, irq,
835 rsnd_src_interrupt_gen2, 491 rsnd_src_interrupt,
836 IRQF_SHARED, 492 IRQF_SHARED,
837 dev_name(dev), mod); 493 dev_name(dev), mod);
838 if (ret) 494 if (ret)
839 return ret; 495 return ret;
840 } 496 }
841 497
842 ret = rsnd_dma_init(io, 498 src->dma = rsnd_dma_attach(io, mod, 0);
843 rsnd_mod_to_dma(mod), 499 if (IS_ERR(src->dma))
844 src->info->dma_id); 500 return PTR_ERR(src->dma);
845 501
846 return ret; 502 return ret;
847} 503}
848 504
849static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 505static int rsnd_src_pcm_new(struct rsnd_mod *mod,
850 struct rsnd_dai_stream *io,
851 struct rsnd_priv *priv)
852{
853 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
854
855 return 0;
856}
857
858static int rsnd_src_init_gen2(struct rsnd_mod *mod,
859 struct rsnd_dai_stream *io,
860 struct rsnd_priv *priv)
861{
862 int ret;
863
864 ret = rsnd_src_init(mod, priv);
865 if (ret < 0)
866 return ret;
867
868 ret = rsnd_src_set_convert_rate_gen2(mod, io);
869 if (ret < 0)
870 return ret;
871
872 ret = rsnd_src_set_convert_timing_gen2(io, mod);
873 if (ret < 0)
874 return ret;
875
876 return 0;
877}
878
879static int rsnd_src_start_gen2(struct rsnd_mod *mod,
880 struct rsnd_dai_stream *io,
881 struct rsnd_priv *priv)
882{
883 rsnd_dma_start(io, rsnd_mod_to_dma(mod));
884
885 return _rsnd_src_start_gen2(mod, io);
886}
887
888static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
889 struct rsnd_dai_stream *io,
890 struct rsnd_priv *priv)
891{
892 int ret;
893
894 ret = _rsnd_src_stop_gen2(mod);
895
896 rsnd_dma_stop(io, rsnd_mod_to_dma(mod));
897
898 return ret;
899}
900
901static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
902 struct rsnd_mod *mod)
903{
904 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
905 struct rsnd_src *src = rsnd_mod_to_src(mod);
906 u32 convert_rate = rsnd_src_convert_rate(io, src);
907 u32 fsrate;
908
909 if (!runtime)
910 return;
911
912 if (!convert_rate)
913 convert_rate = runtime->rate;
914
915 fsrate = 0x0400000 / convert_rate * runtime->rate;
916
917 /* update IFS */
918 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
919}
920
921static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
922 struct rsnd_dai_stream *io, 506 struct rsnd_dai_stream *io,
923 struct snd_soc_pcm_runtime *rtd) 507 struct snd_soc_pcm_runtime *rtd)
924{ 508{
@@ -950,7 +534,7 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
950 rsnd_io_is_play(io) ? 534 rsnd_io_is_play(io) ?
951 "SRC Out Rate Switch" : 535 "SRC Out Rate Switch" :
952 "SRC In Rate Switch", 536 "SRC In Rate Switch",
953 rsnd_src_reconvert_update, 537 rsnd_src_set_convert_rate,
954 &src->sen, 1); 538 &src->sen, 1);
955 if (ret < 0) 539 if (ret < 0)
956 return ret; 540 return ret;
@@ -959,23 +543,22 @@ static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
959 rsnd_io_is_play(io) ? 543 rsnd_io_is_play(io) ?
960 "SRC Out Rate" : 544 "SRC Out Rate" :
961 "SRC In Rate", 545 "SRC In Rate",
962 rsnd_src_reconvert_update, 546 rsnd_src_set_convert_rate,
963 &src->sync, 192000); 547 &src->sync, 192000);
964 548
965 return ret; 549 return ret;
966} 550}
967 551
968static struct rsnd_mod_ops rsnd_src_gen2_ops = { 552static struct rsnd_mod_ops rsnd_src_ops = {
969 .name = SRC_NAME, 553 .name = SRC_NAME,
970 .dma_req = rsnd_src_dma_req, 554 .dma_req = rsnd_src_dma_req,
971 .probe = rsnd_src_probe_gen2, 555 .probe = rsnd_src_probe_,
972 .remove = rsnd_src_remove_gen2, 556 .init = rsnd_src_init,
973 .init = rsnd_src_init_gen2,
974 .quit = rsnd_src_quit, 557 .quit = rsnd_src_quit,
975 .start = rsnd_src_start_gen2, 558 .start = rsnd_src_start,
976 .stop = rsnd_src_stop_gen2, 559 .stop = rsnd_src_stop,
977 .hw_params = rsnd_src_hw_params, 560 .hw_params = rsnd_src_hw_params,
978 .pcm_new = rsnd_src_pcm_new_gen2, 561 .pcm_new = rsnd_src_pcm_new,
979}; 562};
980 563
981struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 564struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -983,113 +566,78 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
983 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 566 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
984 id = 0; 567 id = 0;
985 568
986 return rsnd_mod_get((struct rsnd_src *)(priv->src) + id); 569 return rsnd_mod_get(rsnd_src_get(priv, id));
987} 570}
988 571
989static void rsnd_of_parse_src(struct platform_device *pdev, 572int rsnd_src_probe(struct rsnd_priv *priv)
990 const struct rsnd_of_data *of_data,
991 struct rsnd_priv *priv)
992{ 573{
993 struct device_node *src_node; 574 struct device_node *node;
994 struct device_node *np; 575 struct device_node *np;
995 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
996 struct rsnd_src_platform_info *src_info;
997 struct device *dev = &pdev->dev;
998 int nr, i;
999
1000 if (!of_data)
1001 return;
1002
1003 src_node = rsnd_src_of_node(priv);
1004 if (!src_node)
1005 return;
1006
1007 nr = of_get_child_count(src_node);
1008 if (!nr)
1009 goto rsnd_of_parse_src_end;
1010
1011 src_info = devm_kzalloc(dev,
1012 sizeof(struct rsnd_src_platform_info) * nr,
1013 GFP_KERNEL);
1014 if (!src_info) {
1015 dev_err(dev, "src info allocation error\n");
1016 goto rsnd_of_parse_src_end;
1017 }
1018
1019 info->src_info = src_info;
1020 info->src_info_nr = nr;
1021
1022 i = 0;
1023 for_each_child_of_node(src_node, np) {
1024 src_info[i].irq = irq_of_parse_and_map(np, 0);
1025
1026 i++;
1027 }
1028
1029rsnd_of_parse_src_end:
1030 of_node_put(src_node);
1031}
1032
1033int rsnd_src_probe(struct platform_device *pdev,
1034 const struct rsnd_of_data *of_data,
1035 struct rsnd_priv *priv)
1036{
1037 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
1038 struct device *dev = rsnd_priv_to_dev(priv); 576 struct device *dev = rsnd_priv_to_dev(priv);
1039 struct rsnd_src *src; 577 struct rsnd_src *src;
1040 struct rsnd_mod_ops *ops;
1041 struct clk *clk; 578 struct clk *clk;
1042 char name[RSND_SRC_NAME_SIZE]; 579 char name[RSND_SRC_NAME_SIZE];
1043 int i, nr, ret; 580 int i, nr, ret;
1044 581
1045 ops = NULL; 582 /* This driver doesn't support Gen1 at this point */
1046 if (rsnd_is_gen1(priv)) { 583 if (rsnd_is_gen1(priv))
1047 ops = &rsnd_src_gen1_ops; 584 return 0;
1048 dev_warn(dev, "Gen1 support will be removed soon\n");
1049 }
1050 if (rsnd_is_gen2(priv))
1051 ops = &rsnd_src_gen2_ops;
1052 if (!ops) {
1053 dev_err(dev, "unknown Generation\n");
1054 return -EIO;
1055 }
1056 585
1057 rsnd_of_parse_src(pdev, of_data, priv); 586 node = rsnd_src_of_node(priv);
587 if (!node)
588 return 0; /* not used is not error */
1058 589
1059 /* 590 nr = of_get_child_count(node);
1060 * init SRC 591 if (!nr) {
1061 */ 592 ret = -EINVAL;
1062 nr = info->src_info_nr; 593 goto rsnd_src_probe_done;
1063 if (!nr) 594 }
1064 return 0;
1065 595
1066 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); 596 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
1067 if (!src) 597 if (!src) {
1068 return -ENOMEM; 598 ret = -ENOMEM;
599 goto rsnd_src_probe_done;
600 }
1069 601
1070 priv->src_nr = nr; 602 priv->src_nr = nr;
1071 priv->src = src; 603 priv->src = src;
1072 604
1073 for_each_rsnd_src(src, priv, i) { 605 i = 0;
606 for_each_child_of_node(node, np) {
607 src = rsnd_src_get(priv, i);
608
1074 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", 609 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
1075 SRC_NAME, i); 610 SRC_NAME, i);
1076 611
1077 clk = devm_clk_get(dev, name); 612 src->irq = irq_of_parse_and_map(np, 0);
1078 if (IS_ERR(clk)) 613 if (!src->irq) {
1079 return PTR_ERR(clk); 614 ret = -EINVAL;
615 goto rsnd_src_probe_done;
616 }
1080 617
1081 src->info = &info->src_info[i]; 618 clk = devm_clk_get(dev, name);
619 if (IS_ERR(clk)) {
620 ret = PTR_ERR(clk);
621 goto rsnd_src_probe_done;
622 }
1082 623
1083 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i); 624 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
625 &rsnd_src_ops, clk, RSND_MOD_SRC, i);
1084 if (ret) 626 if (ret)
1085 return ret; 627 goto rsnd_src_probe_done;
628
629 i++;
1086 } 630 }
1087 631
1088 return 0; 632 ret = 0;
633
634rsnd_src_probe_done:
635 of_node_put(node);
636
637 return ret;
1089} 638}
1090 639
1091void rsnd_src_remove(struct platform_device *pdev, 640void rsnd_src_remove(struct rsnd_priv *priv)
1092 struct rsnd_priv *priv)
1093{ 641{
1094 struct rsnd_src *src; 642 struct rsnd_src *src;
1095 int i; 643 int i;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 1427ec21bd7e..7db05fdfb656 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -24,7 +24,9 @@
24#define OIEN (1 << 26) /* Overflow Interrupt Enable */ 24#define OIEN (1 << 26) /* Overflow Interrupt Enable */
25#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */ 25#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */
26#define DIEN (1 << 24) /* Data Interrupt Enable */ 26#define DIEN (1 << 24) /* Data Interrupt Enable */
27 27#define CHNL_4 (1 << 22) /* Channels */
28#define CHNL_6 (2 << 22) /* Channels */
29#define CHNL_8 (3 << 22) /* Channels */
28#define DWL_8 (0 << 19) /* Data Word Length */ 30#define DWL_8 (0 << 19) /* Data Word Length */
29#define DWL_16 (1 << 19) /* Data Word Length */ 31#define DWL_16 (1 << 19) /* Data Word Length */
30#define DWL_18 (2 << 19) /* Data Word Length */ 32#define DWL_18 (2 << 19) /* Data Word Length */
@@ -39,6 +41,7 @@
39#define SCKP (1 << 13) /* Serial Bit Clock Polarity */ 41#define SCKP (1 << 13) /* Serial Bit Clock Polarity */
40#define SWSP (1 << 12) /* Serial WS Polarity */ 42#define SWSP (1 << 12) /* Serial WS Polarity */
41#define SDTA (1 << 10) /* Serial Data Alignment */ 43#define SDTA (1 << 10) /* Serial Data Alignment */
44#define PDTA (1 << 9) /* Parallel Data Alignment */
42#define DEL (1 << 8) /* Serial Data Delay */ 45#define DEL (1 << 8) /* Serial Data Delay */
43#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */ 46#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */
44#define TRMD (1 << 1) /* Transmit/Receive Mode Select */ 47#define TRMD (1 << 1) /* Transmit/Receive Mode Select */
@@ -56,35 +59,44 @@
56 * SSIWSR 59 * SSIWSR
57 */ 60 */
58#define CONT (1 << 8) /* WS Continue Function */ 61#define CONT (1 << 8) /* WS Continue Function */
62#define WS_MODE (1 << 0) /* WS Mode */
59 63
60#define SSI_NAME "ssi" 64#define SSI_NAME "ssi"
61 65
62struct rsnd_ssi { 66struct rsnd_ssi {
63 struct rsnd_ssi_platform_info *info; /* rcar_snd.h */
64 struct rsnd_ssi *parent; 67 struct rsnd_ssi *parent;
65 struct rsnd_mod mod; 68 struct rsnd_mod mod;
69 struct rsnd_mod *dma;
66 70
71 u32 flags;
67 u32 cr_own; 72 u32 cr_own;
68 u32 cr_clk; 73 u32 cr_clk;
74 u32 cr_mode;
75 u32 wsr;
69 int chan; 76 int chan;
77 int rate;
70 int err; 78 int err;
79 int irq;
71 unsigned int usrcnt; 80 unsigned int usrcnt;
72}; 81};
73 82
83/* flags */
84#define RSND_SSI_CLK_PIN_SHARE (1 << 0)
85#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */
86
74#define for_each_rsnd_ssi(pos, priv, i) \ 87#define for_each_rsnd_ssi(pos, priv, i) \
75 for (i = 0; \ 88 for (i = 0; \
76 (i < rsnd_ssi_nr(priv)) && \ 89 (i < rsnd_ssi_nr(priv)) && \
77 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \ 90 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \
78 i++) 91 i++)
79 92
93#define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
94#define rsnd_ssi_to_dma(mod) ((ssi)->dma)
80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr) 95#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 96#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 97#define rsnd_ssi_mode_flags(p) ((p)->flags)
83#define rsnd_ssi_parent(ssi) ((ssi)->parent) 98#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
84#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 99#define rsnd_ssi_is_multi_slave(ssi, io) ((mod) != rsnd_io_to_mod_ssi(io))
85#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
86#define rsnd_ssi_of_node(priv) \
87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
88 100
89int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) 101int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
90{ 102{
@@ -103,6 +115,16 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
103 return use_busif; 115 return use_busif;
104} 116}
105 117
118static void rsnd_ssi_status_clear(struct rsnd_mod *mod)
119{
120 rsnd_mod_write(mod, SSISR, 0);
121}
122
123static u32 rsnd_ssi_status_get(struct rsnd_mod *mod)
124{
125 return rsnd_mod_read(mod, SSISR);
126}
127
106static void rsnd_ssi_status_check(struct rsnd_mod *mod, 128static void rsnd_ssi_status_check(struct rsnd_mod *mod,
107 u32 bit) 129 u32 bit)
108{ 130{
@@ -112,7 +134,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
112 int i; 134 int i;
113 135
114 for (i = 0; i < 1024; i++) { 136 for (i = 0; i < 1024; i++) {
115 status = rsnd_mod_read(mod, SSISR); 137 status = rsnd_ssi_status_get(mod);
116 if (status & bit) 138 if (status & bit)
117 return; 139 return;
118 140
@@ -122,13 +144,79 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
122 dev_warn(dev, "status check failed\n"); 144 dev_warn(dev, "status check failed\n");
123} 145}
124 146
147static int rsnd_ssi_irq_enable(struct rsnd_mod *ssi_mod)
148{
149 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
150
151 if (rsnd_is_gen1(priv))
152 return 0;
153
154 /* enable SSI interrupt if Gen2 */
155 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
156 rsnd_ssi_is_dma_mode(ssi_mod) ?
157 0x0e000000 : 0x0f000000);
158
159 return 0;
160}
161
162static int rsnd_ssi_irq_disable(struct rsnd_mod *ssi_mod)
163{
164 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
165
166 if (rsnd_is_gen1(priv))
167 return 0;
168
169 /* disable SSI interrupt if Gen2 */
170 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
171
172 return 0;
173}
174
175u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io)
176{
177 struct rsnd_mod *mod;
178 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
180 struct device *dev = rsnd_priv_to_dev(priv);
181 enum rsnd_mod_type types[] = {
182 RSND_MOD_SSIM1,
183 RSND_MOD_SSIM2,
184 RSND_MOD_SSIM3,
185 };
186 int i, mask;
187
188 switch (runtime->channels) {
189 case 2: /* Multi channel is not needed for Stereo */
190 return 0;
191 case 6:
192 break;
193 default:
194 dev_err(dev, "unsupported channel\n");
195 return 0;
196 }
197
198 mask = 0;
199 for (i = 0; i < ARRAY_SIZE(types); i++) {
200 mod = rsnd_io_to_mod(io, types[i]);
201 if (!mod)
202 continue;
203
204 mask |= 1 << rsnd_mod_id(mod);
205 }
206
207 return mask;
208}
209
125static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, 210static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
126 struct rsnd_dai_stream *io) 211 struct rsnd_dai_stream *io)
127{ 212{
128 struct rsnd_priv *priv = rsnd_io_to_priv(io); 213 struct rsnd_priv *priv = rsnd_io_to_priv(io);
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 214 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 struct device *dev = rsnd_priv_to_dev(priv); 215 struct device *dev = rsnd_priv_to_dev(priv);
216 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
131 struct rsnd_mod *mod = rsnd_mod_get(ssi); 217 struct rsnd_mod *mod = rsnd_mod_get(ssi);
218 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
219 int slots = rsnd_get_slot_width(io);
132 int j, ret; 220 int j, ret;
133 int ssi_clk_mul_table[] = { 221 int ssi_clk_mul_table[] = {
134 1, 2, 4, 8, 16, 6, 12, 222 1, 2, 4, 8, 16, 6, 12,
@@ -136,6 +224,24 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
136 unsigned int main_rate; 224 unsigned int main_rate;
137 unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime); 225 unsigned int rate = rsnd_src_get_ssi_rate(priv, io, runtime);
138 226
227 if (!rsnd_rdai_is_clk_master(rdai))
228 return 0;
229
230 if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io))
231 return 0;
232
233 if (rsnd_ssi_is_multi_slave(mod, io))
234 return 0;
235
236 if (ssi->usrcnt > 1) {
237 if (ssi->rate != rate) {
238 dev_err(dev, "SSI parent/child should use same rate\n");
239 return -EINVAL;
240 }
241
242 return 0;
243 }
244
139 /* 245 /*
140 * Find best clock, and try to start ADG 246 * Find best clock, and try to start ADG
141 */ 247 */
@@ -143,15 +249,18 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
143 249
144 /* 250 /*
145 * this driver is assuming that 251 * this driver is assuming that
146 * system word is 64fs (= 2 x 32bit) 252 * system word is 32bit x slots
147 * see rsnd_ssi_init() 253 * see rsnd_ssi_init()
148 */ 254 */
149 main_rate = rate * 32 * 2 * ssi_clk_mul_table[j]; 255 main_rate = rate * 32 * slots * ssi_clk_mul_table[j];
150 256
151 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate); 257 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
152 if (0 == ret) { 258 if (0 == ret) {
153 ssi->cr_clk = FORCE | SWL_32 | 259 ssi->cr_clk = FORCE | SWL_32 |
154 SCKD | SWSD | CKDV(j); 260 SCKD | SWSD | CKDV(j);
261 ssi->wsr = CONT;
262
263 ssi->rate = rate;
155 264
156 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 265 dev_dbg(dev, "%s[%d] outputs %u Hz\n",
157 rsnd_mod_name(mod), 266 rsnd_mod_name(mod),
@@ -165,113 +274,91 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
165 return -EIO; 274 return -EIO;
166} 275}
167 276
168static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) 277static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi,
278 struct rsnd_dai_stream *io)
169{ 279{
280 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
170 struct rsnd_mod *mod = rsnd_mod_get(ssi); 281 struct rsnd_mod *mod = rsnd_mod_get(ssi);
282 struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
283
284 if (!rsnd_rdai_is_clk_master(rdai))
285 return;
286
287 if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io))
288 return;
289
290 if (ssi->usrcnt > 1)
291 return;
292
293 ssi->cr_clk = 0;
294 ssi->rate = 0;
171 295
172 ssi->cr_clk = 0;
173 rsnd_adg_ssi_clk_stop(mod); 296 rsnd_adg_ssi_clk_stop(mod);
174} 297}
175 298
176static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, 299static int rsnd_ssi_config_init(struct rsnd_ssi *ssi,
177 struct rsnd_dai_stream *io) 300 struct rsnd_dai_stream *io)
178{ 301{
179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
180 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 302 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
181 struct device *dev = rsnd_priv_to_dev(priv); 303 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
182 struct rsnd_mod *mod = rsnd_mod_get(ssi); 304 u32 cr_own;
183 u32 cr_mode; 305 u32 cr_mode;
184 u32 cr; 306 u32 wsr;
307 int is_tdm;
185 308
186 if (0 == ssi->usrcnt) { 309 is_tdm = (rsnd_get_slot_width(io) >= 6) ? 1 : 0;
187 rsnd_mod_power_on(mod);
188 310
189 if (rsnd_rdai_is_clk_master(rdai)) { 311 /*
190 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 312 * always use 32bit system word.
313 * see also rsnd_ssi_master_clk_enable()
314 */
315 cr_own = FORCE | SWL_32 | PDTA;
191 316
192 if (ssi_parent) 317 if (rdai->bit_clk_inv)
193 rsnd_ssi_hw_start(ssi_parent, io); 318 cr_own |= SCKP;
194 else 319 if (rdai->frm_clk_inv ^ is_tdm)
195 rsnd_ssi_master_clk_start(ssi, io); 320 cr_own |= SWSP;
196 } 321 if (rdai->data_alignment)
322 cr_own |= SDTA;
323 if (rdai->sys_delay)
324 cr_own |= DEL;
325 if (rsnd_io_is_play(io))
326 cr_own |= TRMD;
327
328 switch (runtime->sample_bits) {
329 case 16:
330 cr_own |= DWL_16;
331 break;
332 case 32:
333 cr_own |= DWL_24;
334 break;
335 default:
336 return -EINVAL;
197 } 337 }
198 338
199 if (rsnd_ssi_is_dma_mode(mod)) { 339 if (rsnd_ssi_is_dma_mode(rsnd_mod_get(ssi))) {
200 cr_mode = UIEN | OIEN | /* over/under run */ 340 cr_mode = UIEN | OIEN | /* over/under run */
201 DMEN; /* DMA : enable DMA */ 341 DMEN; /* DMA : enable DMA */
202 } else { 342 } else {
203 cr_mode = DIEN; /* PIO : enable Data interrupt */ 343 cr_mode = DIEN; /* PIO : enable Data interrupt */
204 } 344 }
205 345
206 cr = ssi->cr_own | 346 /*
207 ssi->cr_clk | 347 * TDM Extend Mode
208 cr_mode | 348 * see
209 EN; 349 * rsnd_ssiu_init_gen2()
210 350 */
211 rsnd_mod_write(mod, SSICR, cr); 351 wsr = ssi->wsr;
212 352 if (is_tdm) {
213 /* enable WS continue */ 353 wsr |= WS_MODE;
214 if (rsnd_rdai_is_clk_master(rdai)) 354 cr_own |= CHNL_8;
215 rsnd_mod_write(mod, SSIWSR, CONT);
216
217 /* clear error status */
218 rsnd_mod_write(mod, SSISR, 0);
219
220 ssi->usrcnt++;
221
222 dev_dbg(dev, "%s[%d] hw started\n",
223 rsnd_mod_name(mod), rsnd_mod_id(mod));
224}
225
226static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
227{
228 struct rsnd_mod *mod = rsnd_mod_get(ssi);
229 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
230 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
231 struct device *dev = rsnd_priv_to_dev(priv);
232 u32 cr;
233
234 if (0 == ssi->usrcnt) {
235 dev_err(dev, "%s called without starting\n", __func__);
236 return;
237 } 355 }
238 356
239 ssi->usrcnt--; 357 ssi->cr_own = cr_own;
240 358 ssi->cr_mode = cr_mode;
241 if (0 == ssi->usrcnt) { 359 ssi->wsr = wsr;
242 /*
243 * disable all IRQ,
244 * and, wait all data was sent
245 */
246 cr = ssi->cr_own |
247 ssi->cr_clk;
248
249 rsnd_mod_write(mod, SSICR, cr | EN);
250 rsnd_ssi_status_check(mod, DIRQ);
251
252 /*
253 * disable SSI,
254 * and, wait idle state
255 */
256 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
257 rsnd_ssi_status_check(mod, IIRQ);
258
259 if (rsnd_rdai_is_clk_master(rdai)) {
260 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
261 360
262 if (ssi_parent) 361 return 0;
263 rsnd_ssi_hw_stop(io, ssi_parent);
264 else
265 rsnd_ssi_master_clk_stop(ssi);
266 }
267
268 rsnd_mod_power_off(mod);
269
270 ssi->chan = 0;
271 }
272
273 dev_dbg(dev, "%s[%d] hw stopped\n",
274 rsnd_mod_name(mod), rsnd_mod_id(mod));
275} 362}
276 363
277/* 364/*
@@ -282,49 +369,30 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
282 struct rsnd_priv *priv) 369 struct rsnd_priv *priv)
283{ 370{
284 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 371 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
285 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 372 int ret;
286 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
287 u32 cr;
288 373
289 cr = FORCE; 374 ssi->usrcnt++;
290 375
291 /* 376 rsnd_mod_power_on(mod);
292 * always use 32bit system word for easy clock calculation.
293 * see also rsnd_ssi_master_clk_enable()
294 */
295 cr |= SWL_32;
296 377
297 /* 378 ret = rsnd_ssi_master_clk_start(ssi, io);
298 * init clock settings for SSICR 379 if (ret < 0)
299 */ 380 return ret;
300 switch (runtime->sample_bits) {
301 case 16:
302 cr |= DWL_16;
303 break;
304 case 32:
305 cr |= DWL_24;
306 break;
307 default:
308 return -EIO;
309 }
310 381
311 if (rdai->bit_clk_inv) 382 if (rsnd_ssi_is_parent(mod, io))
312 cr |= SCKP; 383 return 0;
313 if (rdai->frm_clk_inv) 384
314 cr |= SWSP; 385 ret = rsnd_ssi_config_init(ssi, io);
315 if (rdai->data_alignment) 386 if (ret < 0)
316 cr |= SDTA; 387 return ret;
317 if (rdai->sys_delay)
318 cr |= DEL;
319 if (rsnd_io_is_play(io))
320 cr |= TRMD;
321 388
322 /*
323 * set ssi parameter
324 */
325 ssi->cr_own = cr;
326 ssi->err = -1; /* ignore 1st error */ 389 ssi->err = -1; /* ignore 1st error */
327 390
391 /* clear error status */
392 rsnd_ssi_status_clear(mod);
393
394 rsnd_ssi_irq_enable(mod);
395
328 return 0; 396 return 0;
329} 397}
330 398
@@ -335,6 +403,9 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
335 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 403 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
336 struct device *dev = rsnd_priv_to_dev(priv); 404 struct device *dev = rsnd_priv_to_dev(priv);
337 405
406 if (rsnd_ssi_is_parent(mod, io))
407 goto rsnd_ssi_quit_end;
408
338 if (ssi->err > 0) 409 if (ssi->err > 0)
339 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 410 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
340 rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err); 411 rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err);
@@ -342,6 +413,19 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
342 ssi->cr_own = 0; 413 ssi->cr_own = 0;
343 ssi->err = 0; 414 ssi->err = 0;
344 415
416 rsnd_ssi_irq_disable(mod);
417
418rsnd_ssi_quit_end:
419 rsnd_ssi_master_clk_stop(ssi, io);
420
421 rsnd_mod_power_off(mod);
422
423 ssi->usrcnt--;
424
425 if (ssi->usrcnt < 0)
426 dev_err(dev, "%s[%d] usrcnt error\n",
427 rsnd_mod_name(mod), rsnd_mod_id(mod));
428
345 return 0; 429 return 0;
346} 430}
347 431
@@ -351,14 +435,13 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
351 struct snd_pcm_hw_params *params) 435 struct snd_pcm_hw_params *params)
352{ 436{
353 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 437 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
354 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
355 int chan = params_channels(params); 438 int chan = params_channels(params);
356 439
357 /* 440 /*
358 * Already working. 441 * Already working.
359 * It will happen if SSI has parent/child connection. 442 * It will happen if SSI has parent/child connection.
360 */ 443 */
361 if (ssi->usrcnt) { 444 if (ssi->usrcnt > 1) {
362 /* 445 /*
363 * it is error if child <-> parent SSI uses 446 * it is error if child <-> parent SSI uses
364 * different channels. 447 * different channels.
@@ -367,39 +450,83 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
367 return -EIO; 450 return -EIO;
368 } 451 }
369 452
370 /* It will be removed on rsnd_ssi_hw_stop */
371 ssi->chan = chan; 453 ssi->chan = chan;
372 if (ssi_parent)
373 return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io,
374 substream, params);
375 454
376 return 0; 455 return 0;
377} 456}
378 457
379static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) 458static u32 rsnd_ssi_record_error(struct rsnd_ssi *ssi)
380{ 459{
381 struct rsnd_mod *mod = rsnd_mod_get(ssi); 460 struct rsnd_mod *mod = rsnd_mod_get(ssi);
461 u32 status = rsnd_ssi_status_get(mod);
382 462
383 /* under/over flow error */ 463 /* under/over flow error */
384 if (status & (UIRQ | OIRQ)) { 464 if (status & (UIRQ | OIRQ))
385 ssi->err++; 465 ssi->err++;
386 466
387 /* clear error status */ 467 return status;
388 rsnd_mod_write(mod, SSISR, 0); 468}
389 } 469
470static int __rsnd_ssi_start(struct rsnd_mod *mod,
471 struct rsnd_dai_stream *io,
472 struct rsnd_priv *priv)
473{
474 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
475 u32 cr;
476
477 cr = ssi->cr_own |
478 ssi->cr_clk |
479 ssi->cr_mode;
480
481 /*
482 * EN will be set via SSIU :: SSI_CONTROL
483 * if Multi channel mode
484 */
485 if (!rsnd_ssi_multi_slaves(io))
486 cr |= EN;
487
488 rsnd_mod_write(mod, SSICR, cr);
489 rsnd_mod_write(mod, SSIWSR, ssi->wsr);
490
491 return 0;
390} 492}
391 493
392static int rsnd_ssi_start(struct rsnd_mod *mod, 494static int rsnd_ssi_start(struct rsnd_mod *mod,
393 struct rsnd_dai_stream *io, 495 struct rsnd_dai_stream *io,
394 struct rsnd_priv *priv) 496 struct rsnd_priv *priv)
395{ 497{
498 /*
499 * no limit to start
500 * see also
501 * rsnd_ssi_stop
502 * rsnd_ssi_interrupt
503 */
504 return __rsnd_ssi_start(mod, io, priv);
505}
506
507static int __rsnd_ssi_stop(struct rsnd_mod *mod,
508 struct rsnd_dai_stream *io,
509 struct rsnd_priv *priv)
510{
396 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 511 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
512 u32 cr;
397 513
398 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io)); 514 /*
515 * disable all IRQ,
516 * and, wait all data was sent
517 */
518 cr = ssi->cr_own |
519 ssi->cr_clk;
399 520
400 rsnd_ssi_hw_start(ssi, io); 521 rsnd_mod_write(mod, SSICR, cr | EN);
522 rsnd_ssi_status_check(mod, DIRQ);
401 523
402 rsnd_src_ssi_irq_enable(mod); 524 /*
525 * disable SSI,
526 * and, wait idle state
527 */
528 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
529 rsnd_ssi_status_check(mod, IIRQ);
403 530
404 return 0; 531 return 0;
405} 532}
@@ -410,15 +537,16 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
410{ 537{
411 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 538 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
412 539
413 rsnd_src_ssi_irq_disable(mod); 540 /*
414 541 * don't stop if not last user
415 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); 542 * see also
416 543 * rsnd_ssi_start
417 rsnd_ssi_hw_stop(io, ssi); 544 * rsnd_ssi_interrupt
418 545 */
419 rsnd_src_ssiu_stop(mod, io); 546 if (ssi->usrcnt > 1)
547 return 0;
420 548
421 return 0; 549 return __rsnd_ssi_stop(mod, io, priv);
422} 550}
423 551
424static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, 552static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
@@ -426,6 +554,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
426{ 554{
427 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 555 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
428 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 556 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
557 struct device *dev = rsnd_priv_to_dev(priv);
429 int is_dma = rsnd_ssi_is_dma_mode(mod); 558 int is_dma = rsnd_ssi_is_dma_mode(mod);
430 u32 status; 559 u32 status;
431 bool elapsed = false; 560 bool elapsed = false;
@@ -436,7 +565,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
436 if (!rsnd_io_is_working(io)) 565 if (!rsnd_io_is_working(io))
437 goto rsnd_ssi_interrupt_out; 566 goto rsnd_ssi_interrupt_out;
438 567
439 status = rsnd_mod_read(mod, SSISR); 568 status = rsnd_ssi_record_error(ssi);
440 569
441 /* PIO only */ 570 /* PIO only */
442 if (!is_dma && (status & DIRQ)) { 571 if (!is_dma && (status & DIRQ)) {
@@ -459,23 +588,24 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
459 588
460 /* DMA only */ 589 /* DMA only */
461 if (is_dma && (status & (UIRQ | OIRQ))) { 590 if (is_dma && (status & (UIRQ | OIRQ))) {
462 struct device *dev = rsnd_priv_to_dev(priv);
463
464 /* 591 /*
465 * restart SSI 592 * restart SSI
466 */ 593 */
467 dev_dbg(dev, "%s[%d] restart\n", 594 dev_dbg(dev, "%s[%d] restart\n",
468 rsnd_mod_name(mod), rsnd_mod_id(mod)); 595 rsnd_mod_name(mod), rsnd_mod_id(mod));
469 596
470 rsnd_ssi_stop(mod, io, priv); 597 __rsnd_ssi_stop(mod, io, priv);
471 if (ssi->err < 1024) 598 __rsnd_ssi_start(mod, io, priv);
472 rsnd_ssi_start(mod, io, priv);
473 else
474 dev_warn(dev, "no more SSI restart\n");
475 } 599 }
476 600
477 rsnd_ssi_record_error(ssi, status); 601 if (ssi->err > 1024) {
602 rsnd_ssi_irq_disable(mod);
478 603
604 dev_warn(dev, "no more %s[%d] restart\n",
605 rsnd_mod_name(mod), rsnd_mod_id(mod));
606 }
607
608 rsnd_ssi_status_clear(mod);
479rsnd_ssi_interrupt_out: 609rsnd_ssi_interrupt_out:
480 spin_unlock(&priv->lock); 610 spin_unlock(&priv->lock);
481 611
@@ -495,15 +625,49 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
495/* 625/*
496 * SSI PIO 626 * SSI PIO
497 */ 627 */
498static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, 628static void rsnd_ssi_parent_attach(struct rsnd_mod *mod,
499 struct rsnd_dai_stream *io, 629 struct rsnd_dai_stream *io,
500 struct rsnd_priv *priv) 630 struct rsnd_priv *priv)
631{
632 if (!__rsnd_ssi_is_pin_sharing(mod))
633 return;
634
635 switch (rsnd_mod_id(mod)) {
636 case 1:
637 case 2:
638 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 0), io, RSND_MOD_SSIP);
639 break;
640 case 4:
641 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 3), io, RSND_MOD_SSIP);
642 break;
643 case 8:
644 rsnd_dai_connect(rsnd_ssi_mod_get(priv, 7), io, RSND_MOD_SSIP);
645 break;
646 }
647}
648
649static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
650 struct rsnd_dai_stream *io,
651 struct rsnd_priv *priv)
501{ 652{
502 struct device *dev = rsnd_priv_to_dev(priv); 653 struct device *dev = rsnd_priv_to_dev(priv);
503 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 654 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
504 int ret; 655 int ret;
505 656
506 ret = devm_request_irq(dev, ssi->info->irq, 657 /*
658 * SSIP/SSIU/IRQ are not needed on
659 * SSI Multi slaves
660 */
661 if (rsnd_ssi_is_multi_slave(mod, io))
662 return 0;
663
664 rsnd_ssi_parent_attach(mod, io, priv);
665
666 ret = rsnd_ssiu_attach(io, mod);
667 if (ret < 0)
668 return ret;
669
670 ret = devm_request_irq(dev, ssi->irq,
507 rsnd_ssi_interrupt, 671 rsnd_ssi_interrupt,
508 IRQF_SHARED, 672 IRQF_SHARED,
509 dev_name(dev), mod); 673 dev_name(dev), mod);
@@ -513,7 +677,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
513 677
514static struct rsnd_mod_ops rsnd_ssi_pio_ops = { 678static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
515 .name = SSI_NAME, 679 .name = SSI_NAME,
516 .probe = rsnd_ssi_pio_probe, 680 .probe = rsnd_ssi_common_probe,
517 .init = rsnd_ssi_init, 681 .init = rsnd_ssi_init,
518 .quit = rsnd_ssi_quit, 682 .quit = rsnd_ssi_quit,
519 .start = rsnd_ssi_start, 683 .start = rsnd_ssi_start,
@@ -526,20 +690,23 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
526 struct rsnd_priv *priv) 690 struct rsnd_priv *priv)
527{ 691{
528 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 692 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
529 struct device *dev = rsnd_priv_to_dev(priv); 693 int dma_id = 0; /* not needed */
530 int dma_id = ssi->info->dma_id;
531 int ret; 694 int ret;
532 695
533 ret = devm_request_irq(dev, ssi->info->irq, 696 /*
534 rsnd_ssi_interrupt, 697 * SSIP/SSIU/IRQ/DMA are not needed on
535 IRQF_SHARED, 698 * SSI Multi slaves
536 dev_name(dev), mod); 699 */
700 if (rsnd_ssi_is_multi_slave(mod, io))
701 return 0;
702
703 ret = rsnd_ssi_common_probe(mod, io, priv);
537 if (ret) 704 if (ret)
538 return ret; 705 return ret;
539 706
540 ret = rsnd_dma_init( 707 ssi->dma = rsnd_dma_attach(io, mod, dma_id);
541 io, rsnd_mod_to_dma(mod), 708 if (IS_ERR(ssi->dma))
542 dma_id); 709 return PTR_ERR(ssi->dma);
543 710
544 return ret; 711 return ret;
545} 712}
@@ -550,9 +717,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
550{ 717{
551 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 718 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
552 struct device *dev = rsnd_priv_to_dev(priv); 719 struct device *dev = rsnd_priv_to_dev(priv);
553 int irq = ssi->info->irq; 720 int irq = ssi->irq;
554
555 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
556 721
557 /* PIO will request IRQ again */ 722 /* PIO will request IRQ again */
558 devm_free_irq(dev, irq, mod); 723 devm_free_irq(dev, irq, mod);
@@ -581,32 +746,6 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod,
581 return 0; 746 return 0;
582} 747}
583 748
584static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
585 struct rsnd_dai_stream *io,
586 struct rsnd_priv *priv)
587{
588 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
589
590 rsnd_dma_start(io, dma);
591
592 rsnd_ssi_start(mod, io, priv);
593
594 return 0;
595}
596
597static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
598 struct rsnd_dai_stream *io,
599 struct rsnd_priv *priv)
600{
601 struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
602
603 rsnd_ssi_stop(mod, io, priv);
604
605 rsnd_dma_stop(io, dma);
606
607 return 0;
608}
609
610static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io, 749static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
611 struct rsnd_mod *mod) 750 struct rsnd_mod *mod)
612{ 751{
@@ -630,8 +769,8 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
630 .remove = rsnd_ssi_dma_remove, 769 .remove = rsnd_ssi_dma_remove,
631 .init = rsnd_ssi_init, 770 .init = rsnd_ssi_init,
632 .quit = rsnd_ssi_quit, 771 .quit = rsnd_ssi_quit,
633 .start = rsnd_ssi_dma_start, 772 .start = rsnd_ssi_start,
634 .stop = rsnd_ssi_dma_stop, 773 .stop = rsnd_ssi_stop,
635 .fallback = rsnd_ssi_fallback, 774 .fallback = rsnd_ssi_fallback,
636 .hw_params = rsnd_ssi_hw_params, 775 .hw_params = rsnd_ssi_hw_params,
637}; 776};
@@ -652,110 +791,76 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
652/* 791/*
653 * ssi mod function 792 * ssi mod function
654 */ 793 */
655struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) 794static void rsnd_ssi_connect(struct rsnd_mod *mod,
795 struct rsnd_dai_stream *io)
656{ 796{
657 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 797 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
658 id = 0; 798 enum rsnd_mod_type types[] = {
659 799 RSND_MOD_SSI,
660 return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id); 800 RSND_MOD_SSIM1,
661} 801 RSND_MOD_SSIM2,
662 802 RSND_MOD_SSIM3,
663int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) 803 };
664{ 804 enum rsnd_mod_type type;
665 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 805 int i;
666
667 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
668}
669
670static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
671{
672 struct rsnd_mod *mod = rsnd_mod_get(ssi);
673
674 if (!__rsnd_ssi_is_pin_sharing(mod))
675 return;
676 806
677 switch (rsnd_mod_id(mod)) { 807 /* try SSI -> SSIM1 -> SSIM2 -> SSIM3 */
678 case 1: 808 for (i = 0; i < ARRAY_SIZE(types); i++) {
679 case 2: 809 type = types[i];
680 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); 810 if (!rsnd_io_to_mod(io, type)) {
681 break; 811 rsnd_dai_connect(mod, io, type);
682 case 4: 812 rsnd_set_slot(rdai, 2 * (i + 1), (i + 1));
683 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 3)); 813 return;
684 break; 814 }
685 case 8:
686 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 7));
687 break;
688 } 815 }
689} 816}
690 817
691 818void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
692static void rsnd_of_parse_ssi(struct platform_device *pdev, 819 struct device_node *playback,
693 const struct rsnd_of_data *of_data, 820 struct device_node *capture)
694 struct rsnd_priv *priv)
695{ 821{
822 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
696 struct device_node *node; 823 struct device_node *node;
697 struct device_node *np; 824 struct device_node *np;
698 struct rsnd_ssi_platform_info *ssi_info; 825 struct rsnd_mod *mod;
699 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 826 int i;
700 struct device *dev = &pdev->dev;
701 int nr, i;
702 827
703 node = rsnd_ssi_of_node(priv); 828 node = rsnd_ssi_of_node(priv);
704 if (!node) 829 if (!node)
705 return; 830 return;
706 831
707 nr = of_get_child_count(node); 832 i = 0;
708 if (!nr)
709 goto rsnd_of_parse_ssi_end;
710
711 ssi_info = devm_kzalloc(dev,
712 sizeof(struct rsnd_ssi_platform_info) * nr,
713 GFP_KERNEL);
714 if (!ssi_info) {
715 dev_err(dev, "ssi info allocation error\n");
716 goto rsnd_of_parse_ssi_end;
717 }
718
719 info->ssi_info = ssi_info;
720 info->ssi_info_nr = nr;
721
722 i = -1;
723 for_each_child_of_node(node, np) { 833 for_each_child_of_node(node, np) {
834 mod = rsnd_ssi_mod_get(priv, i);
835 if (np == playback)
836 rsnd_ssi_connect(mod, &rdai->playback);
837 if (np == capture)
838 rsnd_ssi_connect(mod, &rdai->capture);
724 i++; 839 i++;
840 }
725 841
726 ssi_info = info->ssi_info + i; 842 of_node_put(node);
727 843}
728 /*
729 * pin settings
730 */
731 if (of_get_property(np, "shared-pin", NULL))
732 ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE;
733 844
734 /* 845struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
735 * irq 846{
736 */ 847 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
737 ssi_info->irq = irq_of_parse_and_map(np, 0); 848 id = 0;
738 849
739 /* 850 return rsnd_mod_get(rsnd_ssi_get(priv, id));
740 * DMA 851}
741 */
742 ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ?
743 0 : 1;
744 852
745 if (of_get_property(np, "no-busif", NULL)) 853int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
746 ssi_info->flags |= RSND_SSI_NO_BUSIF; 854{
747 } 855 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
748 856
749rsnd_of_parse_ssi_end: 857 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
750 of_node_put(node);
751} 858}
752 859
753int rsnd_ssi_probe(struct platform_device *pdev, 860int rsnd_ssi_probe(struct rsnd_priv *priv)
754 const struct rsnd_of_data *of_data,
755 struct rsnd_priv *priv)
756{ 861{
757 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 862 struct device_node *node;
758 struct rsnd_ssi_platform_info *pinfo; 863 struct device_node *np;
759 struct device *dev = rsnd_priv_to_dev(priv); 864 struct device *dev = rsnd_priv_to_dev(priv);
760 struct rsnd_mod_ops *ops; 865 struct rsnd_mod_ops *ops;
761 struct clk *clk; 866 struct clk *clk;
@@ -763,50 +868,73 @@ int rsnd_ssi_probe(struct platform_device *pdev,
763 char name[RSND_SSI_NAME_SIZE]; 868 char name[RSND_SSI_NAME_SIZE];
764 int i, nr, ret; 869 int i, nr, ret;
765 870
766 rsnd_of_parse_ssi(pdev, of_data, priv); 871 node = rsnd_ssi_of_node(priv);
872 if (!node)
873 return -EINVAL;
874
875 nr = of_get_child_count(node);
876 if (!nr) {
877 ret = -EINVAL;
878 goto rsnd_ssi_probe_done;
879 }
767 880
768 /*
769 * init SSI
770 */
771 nr = info->ssi_info_nr;
772 ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL); 881 ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL);
773 if (!ssi) 882 if (!ssi) {
774 return -ENOMEM; 883 ret = -ENOMEM;
884 goto rsnd_ssi_probe_done;
885 }
775 886
776 priv->ssi = ssi; 887 priv->ssi = ssi;
777 priv->ssi_nr = nr; 888 priv->ssi_nr = nr;
778 889
779 for_each_rsnd_ssi(ssi, priv, i) { 890 i = 0;
780 pinfo = &info->ssi_info[i]; 891 for_each_child_of_node(node, np) {
892 ssi = rsnd_ssi_get(priv, i);
781 893
782 snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d", 894 snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
783 SSI_NAME, i); 895 SSI_NAME, i);
784 896
785 clk = devm_clk_get(dev, name); 897 clk = devm_clk_get(dev, name);
786 if (IS_ERR(clk)) 898 if (IS_ERR(clk)) {
787 return PTR_ERR(clk); 899 ret = PTR_ERR(clk);
900 goto rsnd_ssi_probe_done;
901 }
788 902
789 ssi->info = pinfo; 903 if (of_get_property(np, "shared-pin", NULL))
904 ssi->flags |= RSND_SSI_CLK_PIN_SHARE;
905
906 if (of_get_property(np, "no-busif", NULL))
907 ssi->flags |= RSND_SSI_NO_BUSIF;
908
909 ssi->irq = irq_of_parse_and_map(np, 0);
910 if (!ssi->irq) {
911 ret = -EINVAL;
912 goto rsnd_ssi_probe_done;
913 }
790 914
791 ops = &rsnd_ssi_non_ops; 915 ops = &rsnd_ssi_non_ops;
792 if (pinfo->dma_id > 0) 916 if (of_get_property(np, "pio-transfer", NULL))
793 ops = &rsnd_ssi_dma_ops;
794 else if (rsnd_ssi_pio_available(ssi))
795 ops = &rsnd_ssi_pio_ops; 917 ops = &rsnd_ssi_pio_ops;
918 else
919 ops = &rsnd_ssi_dma_ops;
796 920
797 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, 921 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
798 RSND_MOD_SSI, i); 922 RSND_MOD_SSI, i);
799 if (ret) 923 if (ret)
800 return ret; 924 goto rsnd_ssi_probe_done;
801 925
802 rsnd_ssi_parent_setup(priv, ssi); 926 i++;
803 } 927 }
804 928
805 return 0; 929 ret = 0;
930
931rsnd_ssi_probe_done:
932 of_node_put(node);
933
934 return ret;
806} 935}
807 936
808void rsnd_ssi_remove(struct platform_device *pdev, 937void rsnd_ssi_remove(struct rsnd_priv *priv)
809 struct rsnd_priv *priv)
810{ 938{
811 struct rsnd_ssi *ssi; 939 struct rsnd_ssi *ssi;
812 int i; 940 int i;
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
new file mode 100644
index 000000000000..3fe9e08e81a3
--- /dev/null
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -0,0 +1,225 @@
1/*
2 * Renesas R-Car SSIU support
3 *
4 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
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#include "rsnd.h"
11
12#define SSIU_NAME "ssiu"
13
14struct rsnd_ssiu {
15 struct rsnd_mod mod;
16};
17
18#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
19#define for_each_rsnd_ssiu(pos, priv, i) \
20 for (i = 0; \
21 (i < rsnd_ssiu_nr(priv)) && \
22 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
23 i++)
24
25static int rsnd_ssiu_init(struct rsnd_mod *mod,
26 struct rsnd_dai_stream *io,
27 struct rsnd_priv *priv)
28{
29 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
30 u32 multi_ssi_slaves = rsnd_ssi_multi_slaves(io);
31 int use_busif = rsnd_ssi_use_busif(io);
32 int id = rsnd_mod_id(mod);
33 u32 mask1, val1;
34 u32 mask2, val2;
35
36 /*
37 * SSI_MODE0
38 */
39 rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
40
41 /*
42 * SSI_MODE1
43 */
44 mask1 = (1 << 4) | (1 << 20); /* mask sync bit */
45 mask2 = (1 << 4); /* mask sync bit */
46 val1 = val2 = 0;
47 if (rsnd_ssi_is_pin_sharing(io)) {
48 int shift = -1;
49
50 switch (id) {
51 case 1:
52 shift = 0;
53 break;
54 case 2:
55 shift = 2;
56 break;
57 case 4:
58 shift = 16;
59 break;
60 default:
61 return -EINVAL;
62 }
63
64 mask1 |= 0x3 << shift;
65 val1 = rsnd_rdai_is_clk_master(rdai) ?
66 0x2 << shift : 0x1 << shift;
67
68 } else if (multi_ssi_slaves) {
69
70 mask2 |= 0x00000007;
71 mask1 |= 0x0000000f;
72
73 switch (multi_ssi_slaves) {
74 case 0x0206: /* SSI0/1/2/9 */
75 val2 = (1 << 4) | /* SSI0129 sync */
76 rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1;
77 /* fall through */
78 case 0x0006: /* SSI0/1/2 */
79 val1 = rsnd_rdai_is_clk_master(rdai) ?
80 0xa : 0x5;
81
82 if (!val2) /* SSI012 sync */
83 val1 |= (1 << 4);
84 }
85 }
86
87 rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
88 rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);
89
90 return 0;
91}
92
93static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
94 .name = SSIU_NAME,
95 .init = rsnd_ssiu_init,
96};
97
98static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
99 struct rsnd_dai_stream *io,
100 struct rsnd_priv *priv)
101{
102 int ret;
103
104 ret = rsnd_ssiu_init(mod, io, priv);
105 if (ret < 0)
106 return ret;
107
108 if (rsnd_get_slot_width(io) >= 6) {
109 /*
110 * TDM Extend Mode
111 * see
112 * rsnd_ssi_config_init()
113 */
114 rsnd_mod_write(mod, SSI_MODE, 0x1);
115 }
116
117 if (rsnd_ssi_use_busif(io)) {
118 u32 val = rsnd_get_dalign(mod, io);
119
120 rsnd_mod_write(mod, SSI_BUSIF_ADINR,
121 rsnd_get_adinr_bit(mod, io) |
122 rsnd_get_adinr_chan(mod, io));
123 rsnd_mod_write(mod, SSI_BUSIF_MODE, 1);
124 rsnd_mod_write(mod, SSI_BUSIF_DALIGN, val);
125 }
126
127 return 0;
128}
129
130static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
131 struct rsnd_dai_stream *io,
132 struct rsnd_priv *priv)
133{
134 if (!rsnd_ssi_use_busif(io))
135 return 0;
136
137 rsnd_mod_write(mod, SSI_CTRL, 0x1);
138
139 if (rsnd_ssi_multi_slaves(io))
140 rsnd_mod_write(mod, SSI_CONTROL, 0x1);
141
142 return 0;
143}
144
145static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
146 struct rsnd_dai_stream *io,
147 struct rsnd_priv *priv)
148{
149 if (!rsnd_ssi_use_busif(io))
150 return 0;
151
152 rsnd_mod_write(mod, SSI_CTRL, 0);
153
154 if (rsnd_ssi_multi_slaves(io))
155 rsnd_mod_write(mod, SSI_CONTROL, 0);
156
157 return 0;
158}
159
160static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
161 .name = SSIU_NAME,
162 .init = rsnd_ssiu_init_gen2,
163 .start = rsnd_ssiu_start_gen2,
164 .stop = rsnd_ssiu_stop_gen2,
165};
166
167static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
168{
169 if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
170 id = 0;
171
172 return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
173}
174
175int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
176 struct rsnd_mod *ssi_mod)
177{
178 struct rsnd_priv *priv = rsnd_io_to_priv(io);
179 struct rsnd_mod *mod = rsnd_ssiu_mod_get(priv, rsnd_mod_id(ssi_mod));
180
181 rsnd_mod_confirm_ssi(ssi_mod);
182
183 return rsnd_dai_connect(mod, io, mod->type);
184}
185
186int rsnd_ssiu_probe(struct rsnd_priv *priv)
187{
188 struct device *dev = rsnd_priv_to_dev(priv);
189 struct rsnd_ssiu *ssiu;
190 static struct rsnd_mod_ops *ops;
191 int i, nr, ret;
192
193 /* same number to SSI */
194 nr = priv->ssi_nr;
195 ssiu = devm_kzalloc(dev, sizeof(*ssiu) * nr, GFP_KERNEL);
196 if (!ssiu)
197 return -ENOMEM;
198
199 priv->ssiu = ssiu;
200 priv->ssiu_nr = nr;
201
202 if (rsnd_is_gen1(priv))
203 ops = &rsnd_ssiu_ops_gen1;
204 else
205 ops = &rsnd_ssiu_ops_gen2;
206
207 for_each_rsnd_ssiu(ssiu, priv, i) {
208 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
209 ops, NULL, RSND_MOD_SSIU, i);
210 if (ret)
211 return ret;
212 }
213
214 return 0;
215}
216
217void rsnd_ssiu_remove(struct rsnd_priv *priv)
218{
219 struct rsnd_ssiu *ssiu;
220 int i;
221
222 for_each_rsnd_ssiu(ssiu, priv, i) {
223 rsnd_mod_quit(rsnd_mod_get(ssiu));
224 }
225}
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index d40efc9fe0a9..733f5128eeff 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -20,6 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/gpio/driver.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/of_gpio.h> 25#include <linux/of_gpio.h>
25#include <linux/of.h> 26#include <linux/of.h>
@@ -38,6 +39,14 @@ struct snd_ac97_reset_cfg {
38 int gpio_reset; 39 int gpio_reset;
39}; 40};
40 41
42struct snd_ac97_gpio_priv {
43#ifdef CONFIG_GPIOLIB
44 struct gpio_chip gpio_chip;
45#endif
46 unsigned int gpios_set;
47 struct snd_soc_codec *codec;
48};
49
41static struct snd_ac97_bus soc_ac97_bus = { 50static struct snd_ac97_bus soc_ac97_bus = {
42 .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */ 51 .ops = NULL, /* Gets initialized in snd_soc_set_ac97_ops() */
43}; 52};
@@ -47,6 +56,117 @@ static void soc_ac97_device_release(struct device *dev)
47 kfree(to_ac97_t(dev)); 56 kfree(to_ac97_t(dev));
48} 57}
49 58
59#ifdef CONFIG_GPIOLIB
60static inline struct snd_soc_codec *gpio_to_codec(struct gpio_chip *chip)
61{
62 struct snd_ac97_gpio_priv *gpio_priv =
63 container_of(chip, struct snd_ac97_gpio_priv, gpio_chip);
64
65 return gpio_priv->codec;
66}
67
68static int snd_soc_ac97_gpio_request(struct gpio_chip *chip, unsigned offset)
69{
70 if (offset >= AC97_NUM_GPIOS)
71 return -EINVAL;
72
73 return 0;
74}
75
76static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip,
77 unsigned offset)
78{
79 struct snd_soc_codec *codec = gpio_to_codec(chip);
80
81 dev_dbg(codec->dev, "set gpio %d to output\n", offset);
82 return snd_soc_update_bits(codec, AC97_GPIO_CFG,
83 1 << offset, 1 << offset);
84}
85
86static int snd_soc_ac97_gpio_get(struct gpio_chip *chip, unsigned offset)
87{
88 struct snd_soc_codec *codec = gpio_to_codec(chip);
89 int ret;
90
91 ret = snd_soc_read(codec, AC97_GPIO_STATUS);
92 dev_dbg(codec->dev, "get gpio %d : %d\n", offset,
93 ret < 0 ? ret : ret & (1 << offset));
94
95 return ret < 0 ? ret : !!(ret & (1 << offset));
96}
97
98static void snd_soc_ac97_gpio_set(struct gpio_chip *chip, unsigned offset,
99 int value)
100{
101 struct snd_ac97_gpio_priv *gpio_priv =
102 container_of(chip, struct snd_ac97_gpio_priv, gpio_chip);
103 struct snd_soc_codec *codec = gpio_to_codec(chip);
104
105 gpio_priv->gpios_set &= ~(1 << offset);
106 gpio_priv->gpios_set |= (!!value) << offset;
107 snd_soc_write(codec, AC97_GPIO_STATUS, gpio_priv->gpios_set);
108 dev_dbg(codec->dev, "set gpio %d to %d\n", offset, !!value);
109}
110
111static int snd_soc_ac97_gpio_direction_out(struct gpio_chip *chip,
112 unsigned offset, int value)
113{
114 struct snd_soc_codec *codec = gpio_to_codec(chip);
115
116 dev_dbg(codec->dev, "set gpio %d to output\n", offset);
117 snd_soc_ac97_gpio_set(chip, offset, value);
118 return snd_soc_update_bits(codec, AC97_GPIO_CFG, 1 << offset, 0);
119}
120
121static struct gpio_chip snd_soc_ac97_gpio_chip = {
122 .label = "snd_soc_ac97",
123 .owner = THIS_MODULE,
124 .request = snd_soc_ac97_gpio_request,
125 .direction_input = snd_soc_ac97_gpio_direction_in,
126 .get = snd_soc_ac97_gpio_get,
127 .direction_output = snd_soc_ac97_gpio_direction_out,
128 .set = snd_soc_ac97_gpio_set,
129 .can_sleep = 1,
130};
131
132static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
133 struct snd_soc_codec *codec)
134{
135 struct snd_ac97_gpio_priv *gpio_priv;
136 int ret;
137
138 gpio_priv = devm_kzalloc(codec->dev, sizeof(*gpio_priv), GFP_KERNEL);
139 if (!gpio_priv)
140 return -ENOMEM;
141 ac97->gpio_priv = gpio_priv;
142 gpio_priv->codec = codec;
143 gpio_priv->gpio_chip = snd_soc_ac97_gpio_chip;
144 gpio_priv->gpio_chip.ngpio = AC97_NUM_GPIOS;
145 gpio_priv->gpio_chip.dev = codec->dev;
146 gpio_priv->gpio_chip.base = -1;
147
148 ret = gpiochip_add(&gpio_priv->gpio_chip);
149 if (ret != 0)
150 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
151 return ret;
152}
153
154static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
155{
156 gpiochip_remove(&ac97->gpio_priv->gpio_chip);
157}
158#else
159static int snd_soc_ac97_init_gpio(struct snd_ac97 *ac97,
160 struct snd_soc_codec *codec)
161{
162 return 0;
163}
164
165static void snd_soc_ac97_free_gpio(struct snd_ac97 *ac97)
166{
167}
168#endif
169
50/** 170/**
51 * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device 171 * snd_soc_alloc_ac97_codec() - Allocate new a AC'97 device
52 * @codec: The CODEC for which to create the AC'97 device 172 * @codec: The CODEC for which to create the AC'97 device
@@ -119,6 +239,10 @@ struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
119 if (ret) 239 if (ret)
120 goto err_put_device; 240 goto err_put_device;
121 241
242 ret = snd_soc_ac97_init_gpio(ac97, codec);
243 if (ret)
244 goto err_put_device;
245
122 return ac97; 246 return ac97;
123 247
124err_put_device: 248err_put_device:
@@ -135,6 +259,7 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
135 */ 259 */
136void snd_soc_free_ac97_codec(struct snd_ac97 *ac97) 260void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
137{ 261{
262 snd_soc_ac97_free_gpio(ac97);
138 device_del(&ac97->dev); 263 device_del(&ac97->dev);
139 ac97->bus = NULL; 264 ac97->bus = NULL;
140 put_device(&ac97->dev); 265 put_device(&ac97->dev);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a1305f827a98..19f7486bf335 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -537,26 +537,75 @@ static inline void snd_soc_debugfs_exit(void)
537struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 537struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
538 const char *dai_link, int stream) 538 const char *dai_link, int stream)
539{ 539{
540 int i; 540 struct snd_soc_pcm_runtime *rtd;
541 541
542 for (i = 0; i < card->num_links; i++) { 542 list_for_each_entry(rtd, &card->rtd_list, list) {
543 if (card->rtd[i].dai_link->no_pcm && 543 if (rtd->dai_link->no_pcm &&
544 !strcmp(card->rtd[i].dai_link->name, dai_link)) 544 !strcmp(rtd->dai_link->name, dai_link))
545 return card->rtd[i].pcm->streams[stream].substream; 545 return rtd->pcm->streams[stream].substream;
546 } 546 }
547 dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link); 547 dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link);
548 return NULL; 548 return NULL;
549} 549}
550EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream); 550EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
551 551
552static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
553 struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
554{
555 struct snd_soc_pcm_runtime *rtd;
556
557 rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
558 if (!rtd)
559 return NULL;
560
561 rtd->card = card;
562 rtd->dai_link = dai_link;
563 rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
564 dai_link->num_codecs,
565 GFP_KERNEL);
566 if (!rtd->codec_dais) {
567 kfree(rtd);
568 return NULL;
569 }
570
571 return rtd;
572}
573
574static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
575{
576 if (rtd && rtd->codec_dais)
577 kfree(rtd->codec_dais);
578 kfree(rtd);
579}
580
581static void soc_add_pcm_runtime(struct snd_soc_card *card,
582 struct snd_soc_pcm_runtime *rtd)
583{
584 list_add_tail(&rtd->list, &card->rtd_list);
585 rtd->num = card->num_rtd;
586 card->num_rtd++;
587}
588
589static void soc_remove_pcm_runtimes(struct snd_soc_card *card)
590{
591 struct snd_soc_pcm_runtime *rtd, *_rtd;
592
593 list_for_each_entry_safe(rtd, _rtd, &card->rtd_list, list) {
594 list_del(&rtd->list);
595 soc_free_pcm_runtime(rtd);
596 }
597
598 card->num_rtd = 0;
599}
600
552struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, 601struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
553 const char *dai_link) 602 const char *dai_link)
554{ 603{
555 int i; 604 struct snd_soc_pcm_runtime *rtd;
556 605
557 for (i = 0; i < card->num_links; i++) { 606 list_for_each_entry(rtd, &card->rtd_list, list) {
558 if (!strcmp(card->rtd[i].dai_link->name, dai_link)) 607 if (!strcmp(rtd->dai_link->name, dai_link))
559 return &card->rtd[i]; 608 return rtd;
560 } 609 }
561 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link); 610 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link);
562 return NULL; 611 return NULL;
@@ -578,7 +627,8 @@ int snd_soc_suspend(struct device *dev)
578{ 627{
579 struct snd_soc_card *card = dev_get_drvdata(dev); 628 struct snd_soc_card *card = dev_get_drvdata(dev);
580 struct snd_soc_codec *codec; 629 struct snd_soc_codec *codec;
581 int i, j; 630 struct snd_soc_pcm_runtime *rtd;
631 int i;
582 632
583 /* If the card is not initialized yet there is nothing to do */ 633 /* If the card is not initialized yet there is nothing to do */
584 if (!card->instantiated) 634 if (!card->instantiated)
@@ -595,13 +645,13 @@ int snd_soc_suspend(struct device *dev)
595 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); 645 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
596 646
597 /* mute any active DACs */ 647 /* mute any active DACs */
598 for (i = 0; i < card->num_rtd; i++) { 648 list_for_each_entry(rtd, &card->rtd_list, list) {
599 649
600 if (card->rtd[i].dai_link->ignore_suspend) 650 if (rtd->dai_link->ignore_suspend)
601 continue; 651 continue;
602 652
603 for (j = 0; j < card->rtd[i].num_codecs; j++) { 653 for (i = 0; i < rtd->num_codecs; i++) {
604 struct snd_soc_dai *dai = card->rtd[i].codec_dais[j]; 654 struct snd_soc_dai *dai = rtd->codec_dais[i];
605 struct snd_soc_dai_driver *drv = dai->driver; 655 struct snd_soc_dai_driver *drv = dai->driver;
606 656
607 if (drv->ops->digital_mute && dai->playback_active) 657 if (drv->ops->digital_mute && dai->playback_active)
@@ -610,20 +660,20 @@ int snd_soc_suspend(struct device *dev)
610 } 660 }
611 661
612 /* suspend all pcms */ 662 /* suspend all pcms */
613 for (i = 0; i < card->num_rtd; i++) { 663 list_for_each_entry(rtd, &card->rtd_list, list) {
614 if (card->rtd[i].dai_link->ignore_suspend) 664 if (rtd->dai_link->ignore_suspend)
615 continue; 665 continue;
616 666
617 snd_pcm_suspend_all(card->rtd[i].pcm); 667 snd_pcm_suspend_all(rtd->pcm);
618 } 668 }
619 669
620 if (card->suspend_pre) 670 if (card->suspend_pre)
621 card->suspend_pre(card); 671 card->suspend_pre(card);
622 672
623 for (i = 0; i < card->num_rtd; i++) { 673 list_for_each_entry(rtd, &card->rtd_list, list) {
624 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 674 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
625 675
626 if (card->rtd[i].dai_link->ignore_suspend) 676 if (rtd->dai_link->ignore_suspend)
627 continue; 677 continue;
628 678
629 if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control) 679 if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control)
@@ -631,19 +681,19 @@ int snd_soc_suspend(struct device *dev)
631 } 681 }
632 682
633 /* close any waiting streams */ 683 /* close any waiting streams */
634 for (i = 0; i < card->num_rtd; i++) 684 list_for_each_entry(rtd, &card->rtd_list, list)
635 flush_delayed_work(&card->rtd[i].delayed_work); 685 flush_delayed_work(&rtd->delayed_work);
636 686
637 for (i = 0; i < card->num_rtd; i++) { 687 list_for_each_entry(rtd, &card->rtd_list, list) {
638 688
639 if (card->rtd[i].dai_link->ignore_suspend) 689 if (rtd->dai_link->ignore_suspend)
640 continue; 690 continue;
641 691
642 snd_soc_dapm_stream_event(&card->rtd[i], 692 snd_soc_dapm_stream_event(rtd,
643 SNDRV_PCM_STREAM_PLAYBACK, 693 SNDRV_PCM_STREAM_PLAYBACK,
644 SND_SOC_DAPM_STREAM_SUSPEND); 694 SND_SOC_DAPM_STREAM_SUSPEND);
645 695
646 snd_soc_dapm_stream_event(&card->rtd[i], 696 snd_soc_dapm_stream_event(rtd,
647 SNDRV_PCM_STREAM_CAPTURE, 697 SNDRV_PCM_STREAM_CAPTURE,
648 SND_SOC_DAPM_STREAM_SUSPEND); 698 SND_SOC_DAPM_STREAM_SUSPEND);
649 } 699 }
@@ -690,10 +740,10 @@ int snd_soc_suspend(struct device *dev)
690 } 740 }
691 } 741 }
692 742
693 for (i = 0; i < card->num_rtd; i++) { 743 list_for_each_entry(rtd, &card->rtd_list, list) {
694 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 744 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
695 745
696 if (card->rtd[i].dai_link->ignore_suspend) 746 if (rtd->dai_link->ignore_suspend)
697 continue; 747 continue;
698 748
699 if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control) 749 if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control)
@@ -717,8 +767,9 @@ static void soc_resume_deferred(struct work_struct *work)
717{ 767{
718 struct snd_soc_card *card = 768 struct snd_soc_card *card =
719 container_of(work, struct snd_soc_card, deferred_resume_work); 769 container_of(work, struct snd_soc_card, deferred_resume_work);
770 struct snd_soc_pcm_runtime *rtd;
720 struct snd_soc_codec *codec; 771 struct snd_soc_codec *codec;
721 int i, j; 772 int i;
722 773
723 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, 774 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
724 * so userspace apps are blocked from touching us 775 * so userspace apps are blocked from touching us
@@ -733,10 +784,10 @@ static void soc_resume_deferred(struct work_struct *work)
733 card->resume_pre(card); 784 card->resume_pre(card);
734 785
735 /* resume control bus DAIs */ 786 /* resume control bus DAIs */
736 for (i = 0; i < card->num_rtd; i++) { 787 list_for_each_entry(rtd, &card->rtd_list, list) {
737 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 788 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
738 789
739 if (card->rtd[i].dai_link->ignore_suspend) 790 if (rtd->dai_link->ignore_suspend)
740 continue; 791 continue;
741 792
742 if (cpu_dai->driver->resume && cpu_dai->driver->bus_control) 793 if (cpu_dai->driver->resume && cpu_dai->driver->bus_control)
@@ -751,28 +802,28 @@ static void soc_resume_deferred(struct work_struct *work)
751 } 802 }
752 } 803 }
753 804
754 for (i = 0; i < card->num_rtd; i++) { 805 list_for_each_entry(rtd, &card->rtd_list, list) {
755 806
756 if (card->rtd[i].dai_link->ignore_suspend) 807 if (rtd->dai_link->ignore_suspend)
757 continue; 808 continue;
758 809
759 snd_soc_dapm_stream_event(&card->rtd[i], 810 snd_soc_dapm_stream_event(rtd,
760 SNDRV_PCM_STREAM_PLAYBACK, 811 SNDRV_PCM_STREAM_PLAYBACK,
761 SND_SOC_DAPM_STREAM_RESUME); 812 SND_SOC_DAPM_STREAM_RESUME);
762 813
763 snd_soc_dapm_stream_event(&card->rtd[i], 814 snd_soc_dapm_stream_event(rtd,
764 SNDRV_PCM_STREAM_CAPTURE, 815 SNDRV_PCM_STREAM_CAPTURE,
765 SND_SOC_DAPM_STREAM_RESUME); 816 SND_SOC_DAPM_STREAM_RESUME);
766 } 817 }
767 818
768 /* unmute any active DACs */ 819 /* unmute any active DACs */
769 for (i = 0; i < card->num_rtd; i++) { 820 list_for_each_entry(rtd, &card->rtd_list, list) {
770 821
771 if (card->rtd[i].dai_link->ignore_suspend) 822 if (rtd->dai_link->ignore_suspend)
772 continue; 823 continue;
773 824
774 for (j = 0; j < card->rtd[i].num_codecs; j++) { 825 for (i = 0; i < rtd->num_codecs; i++) {
775 struct snd_soc_dai *dai = card->rtd[i].codec_dais[j]; 826 struct snd_soc_dai *dai = rtd->codec_dais[i];
776 struct snd_soc_dai_driver *drv = dai->driver; 827 struct snd_soc_dai_driver *drv = dai->driver;
777 828
778 if (drv->ops->digital_mute && dai->playback_active) 829 if (drv->ops->digital_mute && dai->playback_active)
@@ -780,10 +831,10 @@ static void soc_resume_deferred(struct work_struct *work)
780 } 831 }
781 } 832 }
782 833
783 for (i = 0; i < card->num_rtd; i++) { 834 list_for_each_entry(rtd, &card->rtd_list, list) {
784 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 835 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
785 836
786 if (card->rtd[i].dai_link->ignore_suspend) 837 if (rtd->dai_link->ignore_suspend)
787 continue; 838 continue;
788 839
789 if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control) 840 if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control)
@@ -808,15 +859,14 @@ int snd_soc_resume(struct device *dev)
808{ 859{
809 struct snd_soc_card *card = dev_get_drvdata(dev); 860 struct snd_soc_card *card = dev_get_drvdata(dev);
810 bool bus_control = false; 861 bool bus_control = false;
811 int i; 862 struct snd_soc_pcm_runtime *rtd;
812 863
813 /* If the card is not initialized yet there is nothing to do */ 864 /* If the card is not initialized yet there is nothing to do */
814 if (!card->instantiated) 865 if (!card->instantiated)
815 return 0; 866 return 0;
816 867
817 /* activate pins from sleep state */ 868 /* activate pins from sleep state */
818 for (i = 0; i < card->num_rtd; i++) { 869 list_for_each_entry(rtd, &card->rtd_list, list) {
819 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
820 struct snd_soc_dai **codec_dais = rtd->codec_dais; 870 struct snd_soc_dai **codec_dais = rtd->codec_dais;
821 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 871 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
822 int j; 872 int j;
@@ -837,8 +887,8 @@ int snd_soc_resume(struct device *dev)
837 * have that problem and may take a substantial amount of time to resume 887 * have that problem and may take a substantial amount of time to resume
838 * due to I/O costs and anti-pop so handle them out of line. 888 * due to I/O costs and anti-pop so handle them out of line.
839 */ 889 */
840 for (i = 0; i < card->num_rtd; i++) { 890 list_for_each_entry(rtd, &card->rtd_list, list) {
841 struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai; 891 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
842 bus_control |= cpu_dai->driver->bus_control; 892 bus_control |= cpu_dai->driver->bus_control;
843 } 893 }
844 if (bus_control) { 894 if (bus_control) {
@@ -910,18 +960,41 @@ static struct snd_soc_dai *snd_soc_find_dai(
910 return NULL; 960 return NULL;
911} 961}
912 962
913static int soc_bind_dai_link(struct snd_soc_card *card, int num) 963static bool soc_is_dai_link_bound(struct snd_soc_card *card,
964 struct snd_soc_dai_link *dai_link)
965{
966 struct snd_soc_pcm_runtime *rtd;
967
968 list_for_each_entry(rtd, &card->rtd_list, list) {
969 if (rtd->dai_link == dai_link)
970 return true;
971 }
972
973 return false;
974}
975
976static int soc_bind_dai_link(struct snd_soc_card *card,
977 struct snd_soc_dai_link *dai_link)
914{ 978{
915 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 979 struct snd_soc_pcm_runtime *rtd;
916 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
917 struct snd_soc_dai_link_component *codecs = dai_link->codecs; 980 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
918 struct snd_soc_dai_link_component cpu_dai_component; 981 struct snd_soc_dai_link_component cpu_dai_component;
919 struct snd_soc_dai **codec_dais = rtd->codec_dais; 982 struct snd_soc_dai **codec_dais;
920 struct snd_soc_platform *platform; 983 struct snd_soc_platform *platform;
921 const char *platform_name; 984 const char *platform_name;
922 int i; 985 int i;
923 986
924 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 987 dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
988
989 rtd = soc_new_pcm_runtime(card, dai_link);
990 if (!rtd)
991 return -ENOMEM;
992
993 if (soc_is_dai_link_bound(card, dai_link)) {
994 dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
995 dai_link->name);
996 return 0;
997 }
925 998
926 cpu_dai_component.name = dai_link->cpu_name; 999 cpu_dai_component.name = dai_link->cpu_name;
927 cpu_dai_component.of_node = dai_link->cpu_of_node; 1000 cpu_dai_component.of_node = dai_link->cpu_of_node;
@@ -930,18 +1003,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
930 if (!rtd->cpu_dai) { 1003 if (!rtd->cpu_dai) {
931 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", 1004 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
932 dai_link->cpu_dai_name); 1005 dai_link->cpu_dai_name);
933 return -EPROBE_DEFER; 1006 goto _err_defer;
934 } 1007 }
935 1008
936 rtd->num_codecs = dai_link->num_codecs; 1009 rtd->num_codecs = dai_link->num_codecs;
937 1010
938 /* Find CODEC from registered CODECs */ 1011 /* Find CODEC from registered CODECs */
1012 codec_dais = rtd->codec_dais;
939 for (i = 0; i < rtd->num_codecs; i++) { 1013 for (i = 0; i < rtd->num_codecs; i++) {
940 codec_dais[i] = snd_soc_find_dai(&codecs[i]); 1014 codec_dais[i] = snd_soc_find_dai(&codecs[i]);
941 if (!codec_dais[i]) { 1015 if (!codec_dais[i]) {
942 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", 1016 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
943 codecs[i].dai_name); 1017 codecs[i].dai_name);
944 return -EPROBE_DEFER; 1018 goto _err_defer;
945 } 1019 }
946 } 1020 }
947 1021
@@ -973,9 +1047,12 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
973 return -EPROBE_DEFER; 1047 return -EPROBE_DEFER;
974 } 1048 }
975 1049
976 card->num_rtd++; 1050 soc_add_pcm_runtime(card, rtd);
977
978 return 0; 1051 return 0;
1052
1053_err_defer:
1054 soc_free_pcm_runtime(rtd);
1055 return -EPROBE_DEFER;
979} 1056}
980 1057
981static void soc_remove_component(struct snd_soc_component *component) 1058static void soc_remove_component(struct snd_soc_component *component)
@@ -1014,9 +1091,9 @@ static void soc_remove_dai(struct snd_soc_dai *dai, int order)
1014 } 1091 }
1015} 1092}
1016 1093
1017static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) 1094static void soc_remove_link_dais(struct snd_soc_card *card,
1095 struct snd_soc_pcm_runtime *rtd, int order)
1018{ 1096{
1019 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1020 int i; 1097 int i;
1021 1098
1022 /* unregister the rtd device */ 1099 /* unregister the rtd device */
@@ -1032,10 +1109,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1032 soc_remove_dai(rtd->cpu_dai, order); 1109 soc_remove_dai(rtd->cpu_dai, order);
1033} 1110}
1034 1111
1035static void soc_remove_link_components(struct snd_soc_card *card, int num, 1112static void soc_remove_link_components(struct snd_soc_card *card,
1036 int order) 1113 struct snd_soc_pcm_runtime *rtd, int order)
1037{ 1114{
1038 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1039 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1115 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1040 struct snd_soc_platform *platform = rtd->platform; 1116 struct snd_soc_platform *platform = rtd->platform;
1041 struct snd_soc_component *component; 1117 struct snd_soc_component *component;
@@ -1061,23 +1137,200 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
1061 1137
1062static void soc_remove_dai_links(struct snd_soc_card *card) 1138static void soc_remove_dai_links(struct snd_soc_card *card)
1063{ 1139{
1064 int dai, order; 1140 int order;
1141 struct snd_soc_pcm_runtime *rtd;
1142 struct snd_soc_dai_link *link, *_link;
1065 1143
1066 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1144 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1067 order++) { 1145 order++) {
1068 for (dai = 0; dai < card->num_rtd; dai++) 1146 list_for_each_entry(rtd, &card->rtd_list, list)
1069 soc_remove_link_dais(card, dai, order); 1147 soc_remove_link_dais(card, rtd, order);
1070 } 1148 }
1071 1149
1072 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1150 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1073 order++) { 1151 order++) {
1074 for (dai = 0; dai < card->num_rtd; dai++) 1152 list_for_each_entry(rtd, &card->rtd_list, list)
1075 soc_remove_link_components(card, dai, order); 1153 soc_remove_link_components(card, rtd, order);
1076 } 1154 }
1077 1155
1078 card->num_rtd = 0; 1156 list_for_each_entry_safe(link, _link, &card->dai_link_list, list) {
1157 if (link->dobj.type == SND_SOC_DOBJ_DAI_LINK)
1158 dev_warn(card->dev, "Topology forgot to remove link %s?\n",
1159 link->name);
1160
1161 list_del(&link->list);
1162 card->num_dai_links--;
1163 }
1164}
1165
1166static int snd_soc_init_multicodec(struct snd_soc_card *card,
1167 struct snd_soc_dai_link *dai_link)
1168{
1169 /* Legacy codec/codec_dai link is a single entry in multicodec */
1170 if (dai_link->codec_name || dai_link->codec_of_node ||
1171 dai_link->codec_dai_name) {
1172 dai_link->num_codecs = 1;
1173
1174 dai_link->codecs = devm_kzalloc(card->dev,
1175 sizeof(struct snd_soc_dai_link_component),
1176 GFP_KERNEL);
1177 if (!dai_link->codecs)
1178 return -ENOMEM;
1179
1180 dai_link->codecs[0].name = dai_link->codec_name;
1181 dai_link->codecs[0].of_node = dai_link->codec_of_node;
1182 dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
1183 }
1184
1185 if (!dai_link->codecs) {
1186 dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
1187 return -EINVAL;
1188 }
1189
1190 return 0;
1191}
1192
1193static int soc_init_dai_link(struct snd_soc_card *card,
1194 struct snd_soc_dai_link *link)
1195{
1196 int i, ret;
1197
1198 ret = snd_soc_init_multicodec(card, link);
1199 if (ret) {
1200 dev_err(card->dev, "ASoC: failed to init multicodec\n");
1201 return ret;
1202 }
1203
1204 for (i = 0; i < link->num_codecs; i++) {
1205 /*
1206 * Codec must be specified by 1 of name or OF node,
1207 * not both or neither.
1208 */
1209 if (!!link->codecs[i].name ==
1210 !!link->codecs[i].of_node) {
1211 dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
1212 link->name);
1213 return -EINVAL;
1214 }
1215 /* Codec DAI name must be specified */
1216 if (!link->codecs[i].dai_name) {
1217 dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
1218 link->name);
1219 return -EINVAL;
1220 }
1221 }
1222
1223 /*
1224 * Platform may be specified by either name or OF node, but
1225 * can be left unspecified, and a dummy platform will be used.
1226 */
1227 if (link->platform_name && link->platform_of_node) {
1228 dev_err(card->dev,
1229 "ASoC: Both platform name/of_node are set for %s\n",
1230 link->name);
1231 return -EINVAL;
1232 }
1233
1234 /*
1235 * CPU device may be specified by either name or OF node, but
1236 * can be left unspecified, and will be matched based on DAI
1237 * name alone..
1238 */
1239 if (link->cpu_name && link->cpu_of_node) {
1240 dev_err(card->dev,
1241 "ASoC: Neither/both cpu name/of_node are set for %s\n",
1242 link->name);
1243 return -EINVAL;
1244 }
1245 /*
1246 * At least one of CPU DAI name or CPU device name/node must be
1247 * specified
1248 */
1249 if (!link->cpu_dai_name &&
1250 !(link->cpu_name || link->cpu_of_node)) {
1251 dev_err(card->dev,
1252 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
1253 link->name);
1254 return -EINVAL;
1255 }
1256
1257 return 0;
1079} 1258}
1080 1259
1260/**
1261 * snd_soc_add_dai_link - Add a DAI link dynamically
1262 * @card: The ASoC card to which the DAI link is added
1263 * @dai_link: The new DAI link to add
1264 *
1265 * This function adds a DAI link to the ASoC card's link list.
1266 *
1267 * Note: Topology can use this API to add DAI links when probing the
1268 * topology component. And machine drivers can still define static
1269 * DAI links in dai_link array.
1270 */
1271int snd_soc_add_dai_link(struct snd_soc_card *card,
1272 struct snd_soc_dai_link *dai_link)
1273{
1274 if (dai_link->dobj.type
1275 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
1276 dev_err(card->dev, "Invalid dai link type %d\n",
1277 dai_link->dobj.type);
1278 return -EINVAL;
1279 }
1280
1281 lockdep_assert_held(&client_mutex);
1282 /* Notify the machine driver for extra initialization
1283 * on the link created by topology.
1284 */
1285 if (dai_link->dobj.type && card->add_dai_link)
1286 card->add_dai_link(card, dai_link);
1287
1288 list_add_tail(&dai_link->list, &card->dai_link_list);
1289 card->num_dai_links++;
1290
1291 return 0;
1292}
1293EXPORT_SYMBOL_GPL(snd_soc_add_dai_link);
1294
1295/**
1296 * snd_soc_remove_dai_link - Remove a DAI link from the list
1297 * @card: The ASoC card that owns the link
1298 * @dai_link: The DAI link to remove
1299 *
1300 * This function removes a DAI link from the ASoC card's link list.
1301 *
1302 * For DAI links previously added by topology, topology should
1303 * remove them by using the dobj embedded in the link.
1304 */
1305void snd_soc_remove_dai_link(struct snd_soc_card *card,
1306 struct snd_soc_dai_link *dai_link)
1307{
1308 struct snd_soc_dai_link *link, *_link;
1309
1310 if (dai_link->dobj.type
1311 && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
1312 dev_err(card->dev, "Invalid dai link type %d\n",
1313 dai_link->dobj.type);
1314 return;
1315 }
1316
1317 lockdep_assert_held(&client_mutex);
1318 /* Notify the machine driver for extra destruction
1319 * on the link created by topology.
1320 */
1321 if (dai_link->dobj.type && card->remove_dai_link)
1322 card->remove_dai_link(card, dai_link);
1323
1324 list_for_each_entry_safe(link, _link, &card->dai_link_list, list) {
1325 if (link == dai_link) {
1326 list_del(&link->list);
1327 card->num_dai_links--;
1328 return;
1329 }
1330 }
1331}
1332EXPORT_SYMBOL_GPL(snd_soc_remove_dai_link);
1333
1081static void soc_set_name_prefix(struct snd_soc_card *card, 1334static void soc_set_name_prefix(struct snd_soc_card *card,
1082 struct snd_soc_component *component) 1335 struct snd_soc_component *component)
1083{ 1336{
@@ -1220,10 +1473,10 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1220 return 0; 1473 return 0;
1221} 1474}
1222 1475
1223static int soc_probe_link_components(struct snd_soc_card *card, int num, 1476static int soc_probe_link_components(struct snd_soc_card *card,
1477 struct snd_soc_pcm_runtime *rtd,
1224 int order) 1478 int order)
1225{ 1479{
1226 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1227 struct snd_soc_platform *platform = rtd->platform; 1480 struct snd_soc_platform *platform = rtd->platform;
1228 struct snd_soc_component *component; 1481 struct snd_soc_component *component;
1229 int i, ret; 1482 int i, ret;
@@ -1283,35 +1536,35 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1283{ 1536{
1284 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1537 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1285 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1538 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1286 struct snd_soc_dapm_widget *play_w, *capture_w; 1539 struct snd_soc_dapm_widget *sink, *source;
1287 int ret; 1540 int ret;
1288 1541
1289 if (rtd->num_codecs > 1) 1542 if (rtd->num_codecs > 1)
1290 dev_warn(card->dev, "ASoC: Multiple codecs not supported yet\n"); 1543 dev_warn(card->dev, "ASoC: Multiple codecs not supported yet\n");
1291 1544
1292 /* link the DAI widgets */ 1545 /* link the DAI widgets */
1293 play_w = codec_dai->playback_widget; 1546 sink = codec_dai->playback_widget;
1294 capture_w = cpu_dai->capture_widget; 1547 source = cpu_dai->capture_widget;
1295 if (play_w && capture_w) { 1548 if (sink && source) {
1296 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1549 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1297 dai_link->num_params, capture_w, 1550 dai_link->num_params,
1298 play_w); 1551 source, sink);
1299 if (ret != 0) { 1552 if (ret != 0) {
1300 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1553 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1301 play_w->name, capture_w->name, ret); 1554 sink->name, source->name, ret);
1302 return ret; 1555 return ret;
1303 } 1556 }
1304 } 1557 }
1305 1558
1306 play_w = cpu_dai->playback_widget; 1559 sink = cpu_dai->playback_widget;
1307 capture_w = codec_dai->capture_widget; 1560 source = codec_dai->capture_widget;
1308 if (play_w && capture_w) { 1561 if (sink && source) {
1309 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1562 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1310 dai_link->num_params, capture_w, 1563 dai_link->num_params,
1311 play_w); 1564 source, sink);
1312 if (ret != 0) { 1565 if (ret != 0) {
1313 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1566 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1314 play_w->name, capture_w->name, ret); 1567 sink->name, source->name, ret);
1315 return ret; 1568 return ret;
1316 } 1569 }
1317 } 1570 }
@@ -1319,15 +1572,15 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1319 return 0; 1572 return 0;
1320} 1573}
1321 1574
1322static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) 1575static int soc_probe_link_dais(struct snd_soc_card *card,
1576 struct snd_soc_pcm_runtime *rtd, int order)
1323{ 1577{
1324 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1578 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1325 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1326 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1579 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1327 int i, ret; 1580 int i, ret;
1328 1581
1329 dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", 1582 dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
1330 card->name, num, order); 1583 card->name, rtd->num, order);
1331 1584
1332 /* set default power off timeout */ 1585 /* set default power off timeout */
1333 rtd->pmdown_time = pmdown_time; 1586 rtd->pmdown_time = pmdown_time;
@@ -1372,7 +1625,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1372 1625
1373 if (cpu_dai->driver->compress_new) { 1626 if (cpu_dai->driver->compress_new) {
1374 /*create compress_device"*/ 1627 /*create compress_device"*/
1375 ret = cpu_dai->driver->compress_new(rtd, num); 1628 ret = cpu_dai->driver->compress_new(rtd, rtd->num);
1376 if (ret < 0) { 1629 if (ret < 0) {
1377 dev_err(card->dev, "ASoC: can't create compress %s\n", 1630 dev_err(card->dev, "ASoC: can't create compress %s\n",
1378 dai_link->stream_name); 1631 dai_link->stream_name);
@@ -1382,7 +1635,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1382 1635
1383 if (!dai_link->params) { 1636 if (!dai_link->params) {
1384 /* create the pcm */ 1637 /* create the pcm */
1385 ret = soc_new_pcm(rtd, num); 1638 ret = soc_new_pcm(rtd, rtd->num);
1386 if (ret < 0) { 1639 if (ret < 0) {
1387 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n", 1640 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
1388 dai_link->stream_name, ret); 1641 dai_link->stream_name, ret);
@@ -1552,6 +1805,8 @@ EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
1552static int snd_soc_instantiate_card(struct snd_soc_card *card) 1805static int snd_soc_instantiate_card(struct snd_soc_card *card)
1553{ 1806{
1554 struct snd_soc_codec *codec; 1807 struct snd_soc_codec *codec;
1808 struct snd_soc_pcm_runtime *rtd;
1809 struct snd_soc_dai_link *dai_link;
1555 int ret, i, order; 1810 int ret, i, order;
1556 1811
1557 mutex_lock(&client_mutex); 1812 mutex_lock(&client_mutex);
@@ -1559,7 +1814,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1559 1814
1560 /* bind DAIs */ 1815 /* bind DAIs */
1561 for (i = 0; i < card->num_links; i++) { 1816 for (i = 0; i < card->num_links; i++) {
1562 ret = soc_bind_dai_link(card, i); 1817 ret = soc_bind_dai_link(card, &card->dai_link[i]);
1563 if (ret != 0) 1818 if (ret != 0)
1564 goto base_error; 1819 goto base_error;
1565 } 1820 }
@@ -1571,6 +1826,10 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1571 goto base_error; 1826 goto base_error;
1572 } 1827 }
1573 1828
1829 /* add predefined DAI links to the list */
1830 for (i = 0; i < card->num_links; i++)
1831 snd_soc_add_dai_link(card, card->dai_link+i);
1832
1574 /* initialize the register cache for each available codec */ 1833 /* initialize the register cache for each available codec */
1575 list_for_each_entry(codec, &codec_list, list) { 1834 list_for_each_entry(codec, &codec_list, list) {
1576 if (codec->cache_init) 1835 if (codec->cache_init)
@@ -1624,8 +1883,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1624 /* probe all components used by DAI links on this card */ 1883 /* probe all components used by DAI links on this card */
1625 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1884 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1626 order++) { 1885 order++) {
1627 for (i = 0; i < card->num_links; i++) { 1886 list_for_each_entry(rtd, &card->rtd_list, list) {
1628 ret = soc_probe_link_components(card, i, order); 1887 ret = soc_probe_link_components(card, rtd, order);
1629 if (ret < 0) { 1888 if (ret < 0) {
1630 dev_err(card->dev, 1889 dev_err(card->dev,
1631 "ASoC: failed to instantiate card %d\n", 1890 "ASoC: failed to instantiate card %d\n",
@@ -1635,11 +1894,26 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1635 } 1894 }
1636 } 1895 }
1637 1896
1897 /* Find new DAI links added during probing components and bind them.
1898 * Components with topology may bring new DAIs and DAI links.
1899 */
1900 list_for_each_entry(dai_link, &card->dai_link_list, list) {
1901 if (soc_is_dai_link_bound(card, dai_link))
1902 continue;
1903
1904 ret = soc_init_dai_link(card, dai_link);
1905 if (ret)
1906 goto probe_dai_err;
1907 ret = soc_bind_dai_link(card, dai_link);
1908 if (ret)
1909 goto probe_dai_err;
1910 }
1911
1638 /* probe all DAI links on this card */ 1912 /* probe all DAI links on this card */
1639 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1913 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1640 order++) { 1914 order++) {
1641 for (i = 0; i < card->num_links; i++) { 1915 list_for_each_entry(rtd, &card->rtd_list, list) {
1642 ret = soc_probe_link_dais(card, i, order); 1916 ret = soc_probe_link_dais(card, rtd, order);
1643 if (ret < 0) { 1917 if (ret < 0) {
1644 dev_err(card->dev, 1918 dev_err(card->dev,
1645 "ASoC: failed to instantiate card %d\n", 1919 "ASoC: failed to instantiate card %d\n",
@@ -1733,6 +2007,7 @@ card_probe_error:
1733 snd_card_free(card->snd_card); 2007 snd_card_free(card->snd_card);
1734 2008
1735base_error: 2009base_error:
2010 soc_remove_pcm_runtimes(card);
1736 mutex_unlock(&card->mutex); 2011 mutex_unlock(&card->mutex);
1737 mutex_unlock(&client_mutex); 2012 mutex_unlock(&client_mutex);
1738 2013
@@ -1763,13 +2038,12 @@ static int soc_probe(struct platform_device *pdev)
1763 2038
1764static int soc_cleanup_card_resources(struct snd_soc_card *card) 2039static int soc_cleanup_card_resources(struct snd_soc_card *card)
1765{ 2040{
2041 struct snd_soc_pcm_runtime *rtd;
1766 int i; 2042 int i;
1767 2043
1768 /* make sure any delayed work runs */ 2044 /* make sure any delayed work runs */
1769 for (i = 0; i < card->num_rtd; i++) { 2045 list_for_each_entry(rtd, &card->rtd_list, list)
1770 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1771 flush_delayed_work(&rtd->delayed_work); 2046 flush_delayed_work(&rtd->delayed_work);
1772 }
1773 2047
1774 /* remove auxiliary devices */ 2048 /* remove auxiliary devices */
1775 for (i = 0; i < card->num_aux_devs; i++) 2049 for (i = 0; i < card->num_aux_devs; i++)
@@ -1777,6 +2051,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1777 2051
1778 /* remove and free each DAI */ 2052 /* remove and free each DAI */
1779 soc_remove_dai_links(card); 2053 soc_remove_dai_links(card);
2054 soc_remove_pcm_runtimes(card);
1780 2055
1781 soc_cleanup_card_debugfs(card); 2056 soc_cleanup_card_debugfs(card);
1782 2057
@@ -1803,29 +2078,26 @@ static int soc_remove(struct platform_device *pdev)
1803int snd_soc_poweroff(struct device *dev) 2078int snd_soc_poweroff(struct device *dev)
1804{ 2079{
1805 struct snd_soc_card *card = dev_get_drvdata(dev); 2080 struct snd_soc_card *card = dev_get_drvdata(dev);
1806 int i; 2081 struct snd_soc_pcm_runtime *rtd;
1807 2082
1808 if (!card->instantiated) 2083 if (!card->instantiated)
1809 return 0; 2084 return 0;
1810 2085
1811 /* Flush out pmdown_time work - we actually do want to run it 2086 /* Flush out pmdown_time work - we actually do want to run it
1812 * now, we're shutting down so no imminent restart. */ 2087 * now, we're shutting down so no imminent restart. */
1813 for (i = 0; i < card->num_rtd; i++) { 2088 list_for_each_entry(rtd, &card->rtd_list, list)
1814 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1815 flush_delayed_work(&rtd->delayed_work); 2089 flush_delayed_work(&rtd->delayed_work);
1816 }
1817 2090
1818 snd_soc_dapm_shutdown(card); 2091 snd_soc_dapm_shutdown(card);
1819 2092
1820 /* deactivate pins to sleep state */ 2093 /* deactivate pins to sleep state */
1821 for (i = 0; i < card->num_rtd; i++) { 2094 list_for_each_entry(rtd, &card->rtd_list, list) {
1822 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1823 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2095 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1824 int j; 2096 int i;
1825 2097
1826 pinctrl_pm_select_sleep_state(cpu_dai->dev); 2098 pinctrl_pm_select_sleep_state(cpu_dai->dev);
1827 for (j = 0; j < rtd->num_codecs; j++) { 2099 for (i = 0; i < rtd->num_codecs; i++) {
1828 struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; 2100 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
1829 pinctrl_pm_select_sleep_state(codec_dai->dev); 2101 pinctrl_pm_select_sleep_state(codec_dai->dev);
1830 } 2102 }
1831 } 2103 }
@@ -2301,33 +2573,6 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
2301} 2573}
2302EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 2574EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
2303 2575
2304static int snd_soc_init_multicodec(struct snd_soc_card *card,
2305 struct snd_soc_dai_link *dai_link)
2306{
2307 /* Legacy codec/codec_dai link is a single entry in multicodec */
2308 if (dai_link->codec_name || dai_link->codec_of_node ||
2309 dai_link->codec_dai_name) {
2310 dai_link->num_codecs = 1;
2311
2312 dai_link->codecs = devm_kzalloc(card->dev,
2313 sizeof(struct snd_soc_dai_link_component),
2314 GFP_KERNEL);
2315 if (!dai_link->codecs)
2316 return -ENOMEM;
2317
2318 dai_link->codecs[0].name = dai_link->codec_name;
2319 dai_link->codecs[0].of_node = dai_link->codec_of_node;
2320 dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
2321 }
2322
2323 if (!dai_link->codecs) {
2324 dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
2325 return -EINVAL;
2326 }
2327
2328 return 0;
2329}
2330
2331/** 2576/**
2332 * snd_soc_register_card - Register a card with the ASoC core 2577 * snd_soc_register_card - Register a card with the ASoC core
2333 * 2578 *
@@ -2336,7 +2581,8 @@ static int snd_soc_init_multicodec(struct snd_soc_card *card,
2336 */ 2581 */
2337int snd_soc_register_card(struct snd_soc_card *card) 2582int snd_soc_register_card(struct snd_soc_card *card)
2338{ 2583{
2339 int i, j, ret; 2584 int i, ret;
2585 struct snd_soc_pcm_runtime *rtd;
2340 2586
2341 if (!card->name || !card->dev) 2587 if (!card->name || !card->dev)
2342 return -EINVAL; 2588 return -EINVAL;
@@ -2344,63 +2590,11 @@ int snd_soc_register_card(struct snd_soc_card *card)
2344 for (i = 0; i < card->num_links; i++) { 2590 for (i = 0; i < card->num_links; i++) {
2345 struct snd_soc_dai_link *link = &card->dai_link[i]; 2591 struct snd_soc_dai_link *link = &card->dai_link[i];
2346 2592
2347 ret = snd_soc_init_multicodec(card, link); 2593 ret = soc_init_dai_link(card, link);
2348 if (ret) { 2594 if (ret) {
2349 dev_err(card->dev, "ASoC: failed to init multicodec\n"); 2595 dev_err(card->dev, "ASoC: failed to init link %s\n",
2350 return ret;
2351 }
2352
2353 for (j = 0; j < link->num_codecs; j++) {
2354 /*
2355 * Codec must be specified by 1 of name or OF node,
2356 * not both or neither.
2357 */
2358 if (!!link->codecs[j].name ==
2359 !!link->codecs[j].of_node) {
2360 dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
2361 link->name);
2362 return -EINVAL;
2363 }
2364 /* Codec DAI name must be specified */
2365 if (!link->codecs[j].dai_name) {
2366 dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
2367 link->name);
2368 return -EINVAL;
2369 }
2370 }
2371
2372 /*
2373 * Platform may be specified by either name or OF node, but
2374 * can be left unspecified, and a dummy platform will be used.
2375 */
2376 if (link->platform_name && link->platform_of_node) {
2377 dev_err(card->dev,
2378 "ASoC: Both platform name/of_node are set for %s\n",
2379 link->name);
2380 return -EINVAL;
2381 }
2382
2383 /*
2384 * CPU device may be specified by either name or OF node, but
2385 * can be left unspecified, and will be matched based on DAI
2386 * name alone..
2387 */
2388 if (link->cpu_name && link->cpu_of_node) {
2389 dev_err(card->dev,
2390 "ASoC: Neither/both cpu name/of_node are set for %s\n",
2391 link->name);
2392 return -EINVAL;
2393 }
2394 /*
2395 * At least one of CPU DAI name or CPU device name/node must be
2396 * specified
2397 */
2398 if (!link->cpu_dai_name &&
2399 !(link->cpu_name || link->cpu_of_node)) {
2400 dev_err(card->dev,
2401 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
2402 link->name); 2596 link->name);
2403 return -EINVAL; 2597 return ret;
2404 } 2598 }
2405 } 2599 }
2406 2600
@@ -2408,25 +2602,18 @@ int snd_soc_register_card(struct snd_soc_card *card)
2408 2602
2409 snd_soc_initialize_card_lists(card); 2603 snd_soc_initialize_card_lists(card);
2410 2604
2411 card->rtd = devm_kzalloc(card->dev, 2605 INIT_LIST_HEAD(&card->dai_link_list);
2606 card->num_dai_links = 0;
2607
2608 INIT_LIST_HEAD(&card->rtd_list);
2609 card->num_rtd = 0;
2610
2611 card->rtd_aux = devm_kzalloc(card->dev,
2412 sizeof(struct snd_soc_pcm_runtime) * 2612 sizeof(struct snd_soc_pcm_runtime) *
2413 (card->num_links + card->num_aux_devs), 2613 card->num_aux_devs,
2414 GFP_KERNEL); 2614 GFP_KERNEL);
2415 if (card->rtd == NULL) 2615 if (card->rtd_aux == NULL)
2416 return -ENOMEM; 2616 return -ENOMEM;
2417 card->num_rtd = 0;
2418 card->rtd_aux = &card->rtd[card->num_links];
2419
2420 for (i = 0; i < card->num_links; i++) {
2421 card->rtd[i].card = card;
2422 card->rtd[i].dai_link = &card->dai_link[i];
2423 card->rtd[i].codec_dais = devm_kzalloc(card->dev,
2424 sizeof(struct snd_soc_dai *) *
2425 (card->rtd[i].dai_link->num_codecs),
2426 GFP_KERNEL);
2427 if (card->rtd[i].codec_dais == NULL)
2428 return -ENOMEM;
2429 }
2430 2617
2431 for (i = 0; i < card->num_aux_devs; i++) 2618 for (i = 0; i < card->num_aux_devs; i++)
2432 card->rtd_aux[i].card = card; 2619 card->rtd_aux[i].card = card;
@@ -2442,8 +2629,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2442 return ret; 2629 return ret;
2443 2630
2444 /* deactivate pins to sleep state */ 2631 /* deactivate pins to sleep state */
2445 for (i = 0; i < card->num_rtd; i++) { 2632 list_for_each_entry(rtd, &card->rtd_list, list) {
2446 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
2447 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2633 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2448 int j; 2634 int j;
2449 2635
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7d009428934a..5a2812fa8946 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1300,7 +1300,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
1300 1300
1301static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w) 1301static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w)
1302{ 1302{
1303 return 1; 1303 return w->connected;
1304} 1304}
1305 1305
1306static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 1306static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
@@ -3358,6 +3358,11 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
3358 w->is_ep = SND_SOC_DAPM_EP_SOURCE; 3358 w->is_ep = SND_SOC_DAPM_EP_SOURCE;
3359 w->power_check = dapm_always_on_check_power; 3359 w->power_check = dapm_always_on_check_power;
3360 break; 3360 break;
3361 case snd_soc_dapm_sink:
3362 w->is_ep = SND_SOC_DAPM_EP_SINK;
3363 w->power_check = dapm_always_on_check_power;
3364 break;
3365
3361 case snd_soc_dapm_mux: 3366 case snd_soc_dapm_mux:
3362 case snd_soc_dapm_demux: 3367 case snd_soc_dapm_demux:
3363 case snd_soc_dapm_switch: 3368 case snd_soc_dapm_switch:
@@ -3900,13 +3905,10 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
3900 3905
3901void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) 3906void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
3902{ 3907{
3903 struct snd_soc_pcm_runtime *rtd = card->rtd; 3908 struct snd_soc_pcm_runtime *rtd;
3904 int i;
3905 3909
3906 /* for each BE DAI link... */ 3910 /* for each BE DAI link... */
3907 for (i = 0; i < card->num_rtd; i++) { 3911 list_for_each_entry(rtd, &card->rtd_list, list) {
3908 rtd = &card->rtd[i];
3909
3910 /* 3912 /*
3911 * dynamic FE links have no fixed DAI mapping. 3913 * dynamic FE links have no fixed DAI mapping.
3912 * CODEC<->CODEC links have no direct connection. 3914 * CODEC<->CODEC links have no direct connection.
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 2f67ba6d7a8f..a513a34a51d2 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -779,11 +779,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
779 switch (op_flag) { 779 switch (op_flag) {
780 case SNDRV_CTL_TLV_OP_READ: 780 case SNDRV_CTL_TLV_OP_READ:
781 if (params->get) 781 if (params->get)
782 ret = params->get(tlv, count); 782 ret = params->get(kcontrol, tlv, count);
783 break; 783 break;
784 case SNDRV_CTL_TLV_OP_WRITE: 784 case SNDRV_CTL_TLV_OP_WRITE:
785 if (params->put) 785 if (params->put)
786 ret = params->put(tlv, count); 786 ret = params->put(kcontrol, tlv, count);
787 break; 787 break;
788 } 788 }
789 return ret; 789 return ret;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index c86dc96e8986..2a2ca2209656 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1213,11 +1213,10 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1213 struct snd_soc_dapm_widget *widget, int stream) 1213 struct snd_soc_dapm_widget *widget, int stream)
1214{ 1214{
1215 struct snd_soc_pcm_runtime *be; 1215 struct snd_soc_pcm_runtime *be;
1216 int i, j; 1216 int i;
1217 1217
1218 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1218 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1219 for (i = 0; i < card->num_links; i++) { 1219 list_for_each_entry(be, &card->rtd_list, list) {
1220 be = &card->rtd[i];
1221 1220
1222 if (!be->dai_link->no_pcm) 1221 if (!be->dai_link->no_pcm)
1223 continue; 1222 continue;
@@ -1225,16 +1224,15 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1225 if (be->cpu_dai->playback_widget == widget) 1224 if (be->cpu_dai->playback_widget == widget)
1226 return be; 1225 return be;
1227 1226
1228 for (j = 0; j < be->num_codecs; j++) { 1227 for (i = 0; i < be->num_codecs; i++) {
1229 struct snd_soc_dai *dai = be->codec_dais[j]; 1228 struct snd_soc_dai *dai = be->codec_dais[i];
1230 if (dai->playback_widget == widget) 1229 if (dai->playback_widget == widget)
1231 return be; 1230 return be;
1232 } 1231 }
1233 } 1232 }
1234 } else { 1233 } else {
1235 1234
1236 for (i = 0; i < card->num_links; i++) { 1235 list_for_each_entry(be, &card->rtd_list, list) {
1237 be = &card->rtd[i];
1238 1236
1239 if (!be->dai_link->no_pcm) 1237 if (!be->dai_link->no_pcm)
1240 continue; 1238 continue;
@@ -1242,8 +1240,8 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1242 if (be->cpu_dai->capture_widget == widget) 1240 if (be->cpu_dai->capture_widget == widget)
1243 return be; 1241 return be;
1244 1242
1245 for (j = 0; j < be->num_codecs; j++) { 1243 for (i = 0; i < be->num_codecs; i++) {
1246 struct snd_soc_dai *dai = be->codec_dais[j]; 1244 struct snd_soc_dai *dai = be->codec_dais[i];
1247 if (dai->capture_widget == widget) 1245 if (dai->capture_widget == widget)
1248 return be; 1246 return be;
1249 } 1247 }
@@ -1616,6 +1614,56 @@ static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe,
1616 snd_pcm_stream_unlock_irq(substream); 1614 snd_pcm_stream_unlock_irq(substream);
1617} 1615}
1618 1616
1617static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
1618 int stream)
1619{
1620 struct snd_soc_dpcm *dpcm;
1621 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1622 struct snd_soc_dai *fe_cpu_dai = fe->cpu_dai;
1623 int err;
1624
1625 /* apply symmetry for FE */
1626 if (soc_pcm_has_symmetry(fe_substream))
1627 fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1628
1629 /* Symmetry only applies if we've got an active stream. */
1630 if (fe_cpu_dai->active) {
1631 err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai);
1632 if (err < 0)
1633 return err;
1634 }
1635
1636 /* apply symmetry for BE */
1637 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1638 struct snd_soc_pcm_runtime *be = dpcm->be;
1639 struct snd_pcm_substream *be_substream =
1640 snd_soc_dpcm_get_substream(be, stream);
1641 struct snd_soc_pcm_runtime *rtd = be_substream->private_data;
1642 int i;
1643
1644 if (soc_pcm_has_symmetry(be_substream))
1645 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1646
1647 /* Symmetry only applies if we've got an active stream. */
1648 if (rtd->cpu_dai->active) {
1649 err = soc_pcm_apply_symmetry(be_substream, rtd->cpu_dai);
1650 if (err < 0)
1651 return err;
1652 }
1653
1654 for (i = 0; i < rtd->num_codecs; i++) {
1655 if (rtd->codec_dais[i]->active) {
1656 err = soc_pcm_apply_symmetry(be_substream,
1657 rtd->codec_dais[i]);
1658 if (err < 0)
1659 return err;
1660 }
1661 }
1662 }
1663
1664 return 0;
1665}
1666
1619static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) 1667static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1620{ 1668{
1621 struct snd_soc_pcm_runtime *fe = fe_substream->private_data; 1669 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
@@ -1644,6 +1692,13 @@ static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1644 dpcm_set_fe_runtime(fe_substream); 1692 dpcm_set_fe_runtime(fe_substream);
1645 snd_pcm_limit_hw_rates(runtime); 1693 snd_pcm_limit_hw_rates(runtime);
1646 1694
1695 ret = dpcm_apply_symmetry(fe_substream, stream);
1696 if (ret < 0) {
1697 dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n",
1698 ret);
1699 goto unwind;
1700 }
1701
1647 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO); 1702 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
1648 return 0; 1703 return 0;
1649 1704
@@ -2115,7 +2170,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
2115 continue; 2170 continue;
2116 2171
2117 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && 2172 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
2118 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) 2173 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
2174 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
2119 continue; 2175 continue;
2120 2176
2121 dev_dbg(be->dev, "ASoC: prepare BE %s\n", 2177 dev_dbg(be->dev, "ASoC: prepare BE %s\n",
@@ -2343,12 +2399,12 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
2343 */ 2399 */
2344int soc_dpcm_runtime_update(struct snd_soc_card *card) 2400int soc_dpcm_runtime_update(struct snd_soc_card *card)
2345{ 2401{
2346 int i, old, new, paths; 2402 struct snd_soc_pcm_runtime *fe;
2403 int old, new, paths;
2347 2404
2348 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 2405 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2349 for (i = 0; i < card->num_rtd; i++) { 2406 list_for_each_entry(fe, &card->rtd_list, list) {
2350 struct snd_soc_dapm_widget_list *list; 2407 struct snd_soc_dapm_widget_list *list;
2351 struct snd_soc_pcm_runtime *fe = &card->rtd[i];
2352 2408
2353 /* make sure link is FE */ 2409 /* make sure link is FE */
2354 if (!fe->dai_link->dynamic) 2410 if (!fe->dai_link->dynamic)
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index 5c2bc53f0a9b..7aca6b92f718 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -251,8 +251,7 @@ static void uni_player_set_channel_status(struct uniperif *player,
251 * set one. 251 * set one.
252 */ 252 */
253 mutex_lock(&player->ctrl_lock); 253 mutex_lock(&player->ctrl_lock);
254 if (runtime && (player->stream_settings.iec958.status[3] 254 if (runtime) {
255 == IEC958_AES3_CON_FS_NOTID)) {
256 switch (runtime->rate) { 255 switch (runtime->rate) {
257 case 22050: 256 case 22050:
258 player->stream_settings.iec958.status[3] = 257 player->stream_settings.iec958.status[3] =
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 1bb896d78d09..44f170c73b06 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -28,6 +28,7 @@
28#include <linux/of_address.h> 28#include <linux/of_address.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/regmap.h> 30#include <linux/regmap.h>
31#include <linux/gpio/consumer.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/pcm.h> 34#include <sound/pcm.h>
@@ -70,6 +71,7 @@
70 71
71/* Codec ADC register offsets and bit fields */ 72/* Codec ADC register offsets and bit fields */
72#define SUN4I_CODEC_ADC_FIFOC (0x1c) 73#define SUN4I_CODEC_ADC_FIFOC (0x1c)
74#define SUN4I_CODEC_ADC_FIFOC_ADC_FS (29)
73#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28) 75#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
74#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24) 76#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24)
75#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8) 77#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8)
@@ -102,17 +104,14 @@ struct sun4i_codec {
102 struct regmap *regmap; 104 struct regmap *regmap;
103 struct clk *clk_apb; 105 struct clk *clk_apb;
104 struct clk *clk_module; 106 struct clk *clk_module;
107 struct gpio_desc *gpio_pa;
105 108
109 struct snd_dmaengine_dai_dma_data capture_dma_data;
106 struct snd_dmaengine_dai_dma_data playback_dma_data; 110 struct snd_dmaengine_dai_dma_data playback_dma_data;
107}; 111};
108 112
109static void sun4i_codec_start_playback(struct sun4i_codec *scodec) 113static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
110{ 114{
111 /*
112 * FIXME: according to the BSP, we might need to drive a PA
113 * GPIO high here on some boards
114 */
115
116 /* Flush TX FIFO */ 115 /* Flush TX FIFO */
117 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 116 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
118 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), 117 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
@@ -126,37 +125,50 @@ static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
126 125
127static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) 126static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
128{ 127{
129 /*
130 * FIXME: according to the BSP, we might need to drive a PA
131 * GPIO low here on some boards
132 */
133
134 /* Disable DAC DRQ */ 128 /* Disable DAC DRQ */
135 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 129 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
136 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), 130 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
137 0); 131 0);
138} 132}
139 133
134static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
135{
136 /* Enable ADC DRQ */
137 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
138 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
139 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
140}
141
142static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
143{
144 /* Disable ADC DRQ */
145 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
146 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
147}
148
140static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, 149static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
141 struct snd_soc_dai *dai) 150 struct snd_soc_dai *dai)
142{ 151{
143 struct snd_soc_pcm_runtime *rtd = substream->private_data; 152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
144 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 153 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
145 154
146 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
147 return -ENOTSUPP;
148
149 switch (cmd) { 155 switch (cmd) {
150 case SNDRV_PCM_TRIGGER_START: 156 case SNDRV_PCM_TRIGGER_START:
151 case SNDRV_PCM_TRIGGER_RESUME: 157 case SNDRV_PCM_TRIGGER_RESUME:
152 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 158 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
153 sun4i_codec_start_playback(scodec); 159 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
160 sun4i_codec_start_playback(scodec);
161 else
162 sun4i_codec_start_capture(scodec);
154 break; 163 break;
155 164
156 case SNDRV_PCM_TRIGGER_STOP: 165 case SNDRV_PCM_TRIGGER_STOP:
157 case SNDRV_PCM_TRIGGER_SUSPEND: 166 case SNDRV_PCM_TRIGGER_SUSPEND:
158 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 167 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
159 sun4i_codec_stop_playback(scodec); 168 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 sun4i_codec_stop_playback(scodec);
170 else
171 sun4i_codec_stop_capture(scodec);
160 break; 172 break;
161 173
162 default: 174 default:
@@ -166,15 +178,54 @@ static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
166 return 0; 178 return 0;
167} 179}
168 180
169static int sun4i_codec_prepare(struct snd_pcm_substream *substream, 181static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
170 struct snd_soc_dai *dai) 182 struct snd_soc_dai *dai)
171{ 183{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data; 184 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 185 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
174 u32 val;
175 186
176 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 187
177 return -ENOTSUPP; 188 /* Flush RX FIFO */
189 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
190 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
191 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
192
193
194 /* Set RX FIFO trigger level */
195 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
196 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
197 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
198
199 /*
200 * FIXME: Undocumented in the datasheet, but
201 * Allwinner's code mentions that it is related
202 * related to microphone gain
203 */
204 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
205 0x3 << 25,
206 0x1 << 25);
207
208 if (of_device_is_compatible(scodec->dev->of_node,
209 "allwinner,sun7i-a20-codec"))
210 /* FIXME: Undocumented bits */
211 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
212 0x3 << 8,
213 0x1 << 8);
214
215 /* Fill most significant bits with valid data MSB */
216 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
217 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
218 BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
219
220 return 0;
221}
222
223static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
224 struct snd_soc_dai *dai)
225{
226 struct snd_soc_pcm_runtime *rtd = substream->private_data;
227 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
228 u32 val;
178 229
179 /* Flush the TX FIFO */ 230 /* Flush the TX FIFO */
180 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 231 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -203,6 +254,15 @@ static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
203 0); 254 0);
204 255
205 return 0; 256 return 0;
257};
258
259static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
260 struct snd_soc_dai *dai)
261{
262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
263 return sun4i_codec_prepare_playback(substream, dai);
264
265 return sun4i_codec_prepare_capture(substream, dai);
206} 266}
207 267
208static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params) 268static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
@@ -277,30 +337,32 @@ static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
277 } 337 }
278} 338}
279 339
280static int sun4i_codec_hw_params(struct snd_pcm_substream *substream, 340static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
281 struct snd_pcm_hw_params *params, 341 struct snd_pcm_hw_params *params,
282 struct snd_soc_dai *dai) 342 unsigned int hwrate)
283{ 343{
284 struct snd_soc_pcm_runtime *rtd = substream->private_data; 344 /* Set ADC sample rate */
285 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); 345 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
286 unsigned long clk_freq; 346 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
287 int ret, hwrate; 347 hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
288 u32 val;
289
290 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
291 return -ENOTSUPP;
292 348
293 clk_freq = sun4i_codec_get_mod_freq(params); 349 /* Set the number of channels we want to use */
294 if (!clk_freq) 350 if (params_channels(params) == 1)
295 return -EINVAL; 351 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
352 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
353 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
354 else
355 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_FIFOC,
356 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), 0);
296 357
297 ret = clk_set_rate(scodec->clk_module, clk_freq); 358 return 0;
298 if (ret) 359}
299 return ret;
300 360
301 hwrate = sun4i_codec_get_hw_rate(params); 361static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
302 if (hwrate < 0) 362 struct snd_pcm_hw_params *params,
303 return hwrate; 363 unsigned int hwrate)
364{
365 u32 val;
304 366
305 /* Set DAC sample rate */ 367 /* Set DAC sample rate */
306 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 368 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
@@ -345,6 +407,35 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
345 return 0; 407 return 0;
346} 408}
347 409
410static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
411 struct snd_pcm_hw_params *params,
412 struct snd_soc_dai *dai)
413{
414 struct snd_soc_pcm_runtime *rtd = substream->private_data;
415 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
416 unsigned long clk_freq;
417 int ret, hwrate;
418
419 clk_freq = sun4i_codec_get_mod_freq(params);
420 if (!clk_freq)
421 return -EINVAL;
422
423 ret = clk_set_rate(scodec->clk_module, clk_freq);
424 if (ret)
425 return ret;
426
427 hwrate = sun4i_codec_get_hw_rate(params);
428 if (hwrate < 0)
429 return hwrate;
430
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
432 return sun4i_codec_hw_params_playback(scodec, params,
433 hwrate);
434
435 return sun4i_codec_hw_params_capture(scodec, params,
436 hwrate);
437}
438
348static int sun4i_codec_startup(struct snd_pcm_substream *substream, 439static int sun4i_codec_startup(struct snd_pcm_substream *substream,
349 struct snd_soc_dai *dai) 440 struct snd_soc_dai *dai)
350{ 441{
@@ -395,6 +486,20 @@ static struct snd_soc_dai_driver sun4i_codec_dai = {
395 SNDRV_PCM_FMTBIT_S32_LE, 486 SNDRV_PCM_FMTBIT_S32_LE,
396 .sig_bits = 24, 487 .sig_bits = 24,
397 }, 488 },
489 .capture = {
490 .stream_name = "Codec Capture",
491 .channels_min = 1,
492 .channels_max = 2,
493 .rate_min = 8000,
494 .rate_max = 192000,
495 .rates = SNDRV_PCM_RATE_8000_48000 |
496 SNDRV_PCM_RATE_96000 |
497 SNDRV_PCM_RATE_192000 |
498 SNDRV_PCM_RATE_KNOT,
499 .formats = SNDRV_PCM_FMTBIT_S16_LE |
500 SNDRV_PCM_FMTBIT_S32_LE,
501 .sig_bits = 24,
502 },
398}; 503};
399 504
400/*** Codec ***/ 505/*** Codec ***/
@@ -429,12 +534,23 @@ static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
429 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0), 534 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
430}; 535};
431 536
432static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = { 537static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
538 /* Digital parts of the ADCs */
539 SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
540 SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
541 NULL, 0),
542
433 /* Digital parts of the DACs */ 543 /* Digital parts of the DACs */
434 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC, 544 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
435 SUN4I_CODEC_DAC_DPC_EN_DA, 0, 545 SUN4I_CODEC_DAC_DPC_EN_DA, 0,
436 NULL, 0), 546 NULL, 0),
437 547
548 /* Analog parts of the ADCs */
549 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
550 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
551 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
552 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
553
438 /* Analog parts of the DACs */ 554 /* Analog parts of the DACs */
439 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL, 555 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
440 SUN4I_CODEC_DAC_ACTL_DACAENL, 0), 556 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
@@ -453,6 +569,14 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
453 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL, 569 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
454 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0), 570 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
455 571
572 /* VMIC */
573 SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
574 SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
575
576 /* Mic Pre-Amplifiers */
577 SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
578 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
579
456 /* Power Amplifier */ 580 /* Power Amplifier */
457 SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL, 581 SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
458 SUN4I_CODEC_ADC_ACTL_PA_EN, 0, 582 SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
@@ -461,15 +585,19 @@ static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
461 SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0, 585 SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
462 &sun4i_codec_pa_mute), 586 &sun4i_codec_pa_mute),
463 587
588 SND_SOC_DAPM_INPUT("Mic1"),
589
464 SND_SOC_DAPM_OUTPUT("HP Right"), 590 SND_SOC_DAPM_OUTPUT("HP Right"),
465 SND_SOC_DAPM_OUTPUT("HP Left"), 591 SND_SOC_DAPM_OUTPUT("HP Left"),
466}; 592};
467 593
468static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = { 594static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
469 /* Left DAC Routes */ 595 /* Left ADC / DAC Routes */
596 { "Left ADC", NULL, "ADC" },
470 { "Left DAC", NULL, "DAC" }, 597 { "Left DAC", NULL, "DAC" },
471 598
472 /* Right DAC Routes */ 599 /* Right ADC / DAC Routes */
600 { "Right ADC", NULL, "ADC" },
473 { "Right DAC", NULL, "DAC" }, 601 { "Right DAC", NULL, "DAC" },
474 602
475 /* Right Mixer Routes */ 603 /* Right Mixer Routes */
@@ -491,15 +619,21 @@ static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
491 { "Power Amplifier Mute", "Switch", "Power Amplifier" }, 619 { "Power Amplifier Mute", "Switch", "Power Amplifier" },
492 { "HP Right", NULL, "Power Amplifier Mute" }, 620 { "HP Right", NULL, "Power Amplifier Mute" },
493 { "HP Left", NULL, "Power Amplifier Mute" }, 621 { "HP Left", NULL, "Power Amplifier Mute" },
622
623 /* Mic1 Routes */
624 { "Left ADC", NULL, "MIC1 Pre-Amplifier" },
625 { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
626 { "MIC1 Pre-Amplifier", NULL, "Mic1"},
627 { "Mic1", NULL, "VMIC" },
494}; 628};
495 629
496static struct snd_soc_codec_driver sun4i_codec_codec = { 630static struct snd_soc_codec_driver sun4i_codec_codec = {
497 .controls = sun4i_codec_widgets, 631 .controls = sun4i_codec_widgets,
498 .num_controls = ARRAY_SIZE(sun4i_codec_widgets), 632 .num_controls = ARRAY_SIZE(sun4i_codec_widgets),
499 .dapm_widgets = sun4i_codec_dapm_widgets, 633 .dapm_widgets = sun4i_codec_codec_dapm_widgets,
500 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_dapm_widgets), 634 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
501 .dapm_routes = sun4i_codec_dapm_routes, 635 .dapm_routes = sun4i_codec_codec_dapm_routes,
502 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_dapm_routes), 636 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
503}; 637};
504 638
505static const struct snd_soc_component_driver sun4i_codec_component = { 639static const struct snd_soc_component_driver sun4i_codec_component = {
@@ -516,7 +650,7 @@ static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
516 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 650 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
517 651
518 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data, 652 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
519 NULL); 653 &scodec->capture_dma_data);
520 654
521 return 0; 655 return 0;
522} 656}
@@ -532,6 +666,14 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
532 .formats = SUN4I_CODEC_FORMATS, 666 .formats = SUN4I_CODEC_FORMATS,
533 .sig_bits = 24, 667 .sig_bits = 24,
534 }, 668 },
669 .capture = {
670 .stream_name = "Capture",
671 .channels_min = 1,
672 .channels_max = 2,
673 .rates = SUN4I_CODEC_RATES,
674 .formats = SUN4I_CODEC_FORMATS,
675 .sig_bits = 24,
676 },
535}; 677};
536 678
537static const struct regmap_config sun4i_codec_regmap_config = { 679static const struct regmap_config sun4i_codec_regmap_config = {
@@ -569,6 +711,27 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
569 return link; 711 return link;
570}; 712};
571 713
714static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w,
715 struct snd_kcontrol *k, int event)
716{
717 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
718
719 if (scodec->gpio_pa)
720 gpiod_set_value_cansleep(scodec->gpio_pa,
721 !!SND_SOC_DAPM_EVENT_ON(event));
722
723 return 0;
724}
725
726static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = {
727 SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
728};
729
730static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = {
731 { "Speaker", NULL, "HP Right" },
732 { "Speaker", NULL, "HP Left" },
733};
734
572static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) 735static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
573{ 736{
574 struct snd_soc_card *card; 737 struct snd_soc_card *card;
@@ -583,6 +746,10 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
583 746
584 card->dev = dev; 747 card->dev = dev;
585 card->name = "sun4i-codec"; 748 card->name = "sun4i-codec";
749 card->dapm_widgets = sun4i_codec_card_dapm_widgets;
750 card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
751 card->dapm_routes = sun4i_codec_card_dapm_routes;
752 card->num_dapm_routes = ARRAY_SIZE(sun4i_codec_card_dapm_routes);
586 753
587 return card; 754 return card;
588}; 755};
@@ -634,11 +801,25 @@ static int sun4i_codec_probe(struct platform_device *pdev)
634 return -EINVAL; 801 return -EINVAL;
635 } 802 }
636 803
804 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
805 GPIOD_OUT_LOW);
806 if (IS_ERR(scodec->gpio_pa)) {
807 ret = PTR_ERR(scodec->gpio_pa);
808 if (ret != -EPROBE_DEFER)
809 dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
810 return ret;
811 }
812
637 /* DMA configuration for TX FIFO */ 813 /* DMA configuration for TX FIFO */
638 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; 814 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
639 scodec->playback_dma_data.maxburst = 4; 815 scodec->playback_dma_data.maxburst = 4;
640 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 816 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
641 817
818 /* DMA configuration for RX FIFO */
819 scodec->capture_dma_data.addr = res->start + SUN4I_CODEC_ADC_RXDATA;
820 scodec->capture_dma_data.maxburst = 4;
821 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
822
642 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec, 823 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
643 &sun4i_codec_dai, 1); 824 &sun4i_codec_dai, 1);
644 if (ret) { 825 if (ret) {
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index ba272e21a6fa..deb597f7c302 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -101,12 +101,16 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
101 101
102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
103{ 103{
104 int ret;
104 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card); 105 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
105 106
106 snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET, 107 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
107 &tegra_alc5632_hs_jack, 108 SND_JACK_HEADSET,
108 tegra_alc5632_hs_jack_pins, 109 &tegra_alc5632_hs_jack,
109 ARRAY_SIZE(tegra_alc5632_hs_jack_pins)); 110 tegra_alc5632_hs_jack_pins,
111 ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
112 if (ret)
113 return ret;
110 114
111 if (gpio_is_valid(machine->gpio_hp_det)) { 115 if (gpio_is_valid(machine->gpio_hp_det)) {
112 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 116 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 21604009bc1a..e485278e027a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -199,7 +199,8 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
199 199
200static int tegra_wm8903_remove(struct snd_soc_card *card) 200static int tegra_wm8903_remove(struct snd_soc_card *card)
201{ 201{
202 struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]); 202 struct snd_soc_pcm_runtime *rtd =
203 snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
203 struct snd_soc_dai *codec_dai = rtd->codec_dai; 204 struct snd_soc_dai *codec_dai = rtd->codec_dai;
204 struct snd_soc_codec *codec = codec_dai->codec; 205 struct snd_soc_codec *codec = codec_dai->codec;
205 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 206 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);