aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-05-02 02:25:25 -0400
committerTakashi Iwai <tiwai@suse.de>2017-05-02 02:25:25 -0400
commita5c3b32a1146e44f6b38fdfdfffc27842953420c (patch)
treeeca93f51c8deabe77ed079a3e9190717b6380009 /sound/soc
parentd7dc450d5a7162de96edbed6b1792240c2f3a55f (diff)
parent20d5c84bef067b7e804a163e2abca16c47125bad (diff)
Merge tag 'asoc-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.12 A quiet release for the core, but lots of new drivers this time around: - A new, generalized, API for hooking up jacks which makes it easier to write generic machine drivers for simple cases. - Continuing fixes for issues with the x86 CPU drivers. - New drivers for Cirrus CS35L35, DIO DIO2125, Everest ES7132, HiSilicon hi6210, Maxim MAX98927, MT2701 systems with WM8960, Nuvoton NAU8824, Odroid systems, ST STM32 SAI controllers and x86 systems with DA7213
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c2
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c2
-rw-r--r--sound/soc/codecs/Kconfig30
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ak4613.c10
-rw-r--r--sound/soc/codecs/cs35l35.c1580
-rw-r--r--sound/soc/codecs/cs35l35.h294
-rw-r--r--sound/soc/codecs/cs4271.c2
-rw-r--r--sound/soc/codecs/cs53l30.c1
-rw-r--r--sound/soc/codecs/da7213.c13
-rw-r--r--sound/soc/codecs/dio2125.c120
-rw-r--r--sound/soc/codecs/es7134.c116
-rw-r--r--sound/soc/codecs/es8328.c51
-rw-r--r--sound/soc/codecs/hdac_hdmi.c4
-rw-r--r--sound/soc/codecs/max9867.c4
-rw-r--r--sound/soc/codecs/max98927.c841
-rw-r--r--sound/soc/codecs/max98927.h272
-rw-r--r--sound/soc/codecs/nau8540.c1224
-rw-r--r--sound/soc/codecs/nau8540.h310
-rw-r--r--sound/soc/codecs/nau8824.c1831
-rw-r--r--sound/soc/codecs/nau8824.h466
-rw-r--r--sound/soc/codecs/rt5514.c36
-rw-r--r--sound/soc/codecs/rt5645.c10
-rw-r--r--sound/soc/codecs/rt5665.c222
-rw-r--r--sound/soc/codecs/rt5665.h2
-rw-r--r--sound/soc/codecs/rt5670.c21
-rw-r--r--sound/soc/codecs/rt5677.c7
-rw-r--r--sound/soc/codecs/sgtl5000.c19
-rw-r--r--sound/soc/codecs/ssm4567.c9
-rw-r--r--sound/soc/codecs/sta529.c7
-rw-r--r--sound/soc/codecs/tas2552.c6
-rw-r--r--sound/soc/codecs/tlv320aic23.c7
-rw-r--r--sound/soc/codecs/twl6040.c8
-rw-r--r--sound/soc/codecs/uda1380.c7
-rw-r--r--sound/soc/codecs/wm5100.c2
-rw-r--r--sound/soc/codecs/wm8903.c31
-rw-r--r--sound/soc/codecs/wm8960.c195
-rw-r--r--sound/soc/codecs/wm8978.c7
-rw-r--r--sound/soc/codecs/wm_adsp.c324
-rw-r--r--sound/soc/codecs/wm_adsp.h24
-rw-r--r--sound/soc/dwc/Kconfig4
-rw-r--r--sound/soc/dwc/Makefile6
-rw-r--r--sound/soc/dwc/dwc-i2s.c (renamed from sound/soc/dwc/designware_i2s.c)0
-rw-r--r--sound/soc/dwc/dwc-pcm.c (renamed from sound/soc/dwc/designware_pcm.c)3
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c2
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c2
-rw-r--r--sound/soc/fsl/fsl_esai.c5
-rw-r--r--sound/soc/fsl/fsl_ssi.c27
-rw-r--r--sound/soc/fsl/imx-mc13783.c2
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c28
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c2
-rw-r--r--sound/soc/fsl/imx-wm8962.c72
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c2
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c2
-rw-r--r--sound/soc/fsl/p1022_ds.c2
-rw-r--r--sound/soc/fsl/p1022_rdk.c2
-rw-r--r--sound/soc/fsl/phycore-ac97.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c2
-rw-r--r--sound/soc/generic/simple-card.c43
-rw-r--r--sound/soc/generic/simple-scu-card.c37
-rw-r--r--sound/soc/hisilicon/Kconfig5
-rw-r--r--sound/soc/hisilicon/Makefile1
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.c618
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.h276
-rw-r--r--sound/soc/intel/Kconfig24
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c41
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c4
-rw-r--r--sound/soc/intel/boards/Makefile4
-rw-r--r--sound/soc/intel/boards/bdw-rt5677.c5
-rw-r--r--sound/soc/intel/boards/broadwell.c3
-rw-r--r--sound/soc/intel/boards/bxt_da7219_max98357a.c97
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c3
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c283
-rw-r--r--sound/soc/intel/boards/bytcht_nocodec.c208
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c109
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c6
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c118
-rw-r--r--sound/soc/intel/skylake/skl-messages.c16
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c7
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c118
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c26
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.h2
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h40
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c76
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h17
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c140
-rw-r--r--sound/soc/intel/skylake/skl-sst.c175
-rw-r--r--sound/soc/intel/skylake/skl-topology.c247
-rw-r--r--sound/soc/intel/skylake/skl-topology.h17
-rw-r--r--sound/soc/intel/skylake/skl.c2
-rw-r--r--sound/soc/intel/skylake/skl.h1
-rw-r--r--sound/soc/mediatek/Kconfig10
-rw-r--r--sound/soc/mediatek/mt2701/Makefile1
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c16
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-cs42448.c2
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-wm8960.c176
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-max98090.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c2
-rw-r--r--sound/soc/omap/am3517evm.c2
-rw-r--r--sound/soc/omap/n810.c2
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c2
-rw-r--r--sound/soc/omap/omap-twl4030.c2
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/rx51.c7
-rw-r--r--sound/soc/pxa/brownstone.c2
-rw-r--r--sound/soc/pxa/corgi.c2
-rw-r--r--sound/soc/pxa/e750_wm9705.c2
-rw-r--r--sound/soc/pxa/e800_wm9712.c2
-rw-r--r--sound/soc/pxa/em-x270.c2
-rw-r--r--sound/soc/pxa/hx4700.c2
-rw-r--r--sound/soc/pxa/imote2.c2
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c2
-rw-r--r--sound/soc/pxa/mmp-pcm.c1
-rw-r--r--sound/soc/pxa/mmp-sspa.c1
-rw-r--r--sound/soc/pxa/poodle.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c15
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c5
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c8
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c2
-rw-r--r--sound/soc/pxa/raumfeld.c8
-rw-r--r--sound/soc/pxa/spitz.c6
-rw-r--r--sound/soc/pxa/tosa.c4
-rw-r--r--sound/soc/pxa/z2.c6
-rw-r--r--sound/soc/pxa/zylonite.c2
-rw-r--r--sound/soc/qcom/lpass-apq8016.c12
-rw-r--r--sound/soc/qcom/lpass-cpu.c22
-rw-r--r--sound/soc/qcom/lpass-ipq806x.c6
-rw-r--r--sound/soc/qcom/lpass.h2
-rw-r--r--sound/soc/rockchip/rk3288_hdmi_analog.c3
-rw-r--r--sound/soc/samsung/Kconfig8
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/bells.c1
-rw-r--r--sound/soc/samsung/i2s-regs.h2
-rw-r--r--sound/soc/samsung/i2s.c1
-rw-r--r--sound/soc/samsung/odroid.c219
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c1
-rw-r--r--sound/soc/sh/rcar/adg.c75
-rw-r--r--sound/soc/sh/rcar/core.c111
-rw-r--r--sound/soc/sh/rcar/dvc.c24
-rw-r--r--sound/soc/sh/rcar/rsnd.h55
-rw-r--r--sound/soc/sh/rcar/src.c3
-rw-r--r--sound/soc/sh/rcar/ssi.c9
-rw-r--r--sound/soc/sirf/sirf-audio-port.c1
-rw-r--r--sound/soc/sirf/sirf-audio.c1
-rw-r--r--sound/soc/sirf/sirf-usp.c3
-rw-r--r--sound/soc/soc-core.c27
-rw-r--r--sound/soc/soc-jack.c48
-rw-r--r--sound/soc/soc-topology.c5
-rw-r--r--sound/soc/sti/uniperif_player.c2
-rw-r--r--sound/soc/stm/Kconfig8
-rw-r--r--sound/soc/stm/Makefile6
-rw-r--r--sound/soc/stm/stm32_sai.c115
-rw-r--r--sound/soc/stm/stm32_sai.h200
-rw-r--r--sound/soc/stm/stm32_sai_sub.c884
-rw-r--r--sound/soc/sunxi/sun8i-codec-analog.c168
-rw-r--r--sound/soc/sunxi/sun8i-codec.c10
-rw-r--r--sound/soc/tegra/tegra20_ac97.c1
-rw-r--r--sound/soc/tegra/tegra20_das.c2
-rw-r--r--sound/soc/tegra/tegra20_i2s.c1
-rw-r--r--sound/soc/tegra/tegra20_spdif.c5
-rw-r--r--sound/soc/tegra/tegra30_ahub.c5
-rw-r--r--sound/soc/tegra/tegra30_i2s.c1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c4
-rw-r--r--sound/soc/tegra/tegra_max98090.c4
-rw-r--r--sound/soc/tegra/tegra_rt5640.c4
-rw-r--r--sound/soc/tegra/tegra_sgtl5000.c4
-rw-r--r--sound/soc/tegra/tegra_wm8753.c4
-rw-r--r--sound/soc/tegra/tegra_wm8903.c4
-rw-r--r--sound/soc/tegra/tegra_wm9712.c4
-rw-r--r--sound/soc/tegra/trimslice.c4
-rw-r--r--sound/soc/txx9/txx9aclc.c5
-rw-r--r--sound/soc/ux500/mop500.c4
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c4
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c1
-rw-r--r--sound/soc/zte/Kconfig8
-rw-r--r--sound/soc/zte/Makefile1
-rw-r--r--sound/soc/zte/zx-tdm.c461
184 files changed, 12069 insertions, 1879 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 182d92efc7c8..c0abad2067e1 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/cirrus/Kconfig"
47source "sound/soc/davinci/Kconfig" 47source "sound/soc/davinci/Kconfig"
48source "sound/soc/dwc/Kconfig" 48source "sound/soc/dwc/Kconfig"
49source "sound/soc/fsl/Kconfig" 49source "sound/soc/fsl/Kconfig"
50source "sound/soc/hisilicon/Kconfig"
50source "sound/soc/jz4740/Kconfig" 51source "sound/soc/jz4740/Kconfig"
51source "sound/soc/nuc900/Kconfig" 52source "sound/soc/nuc900/Kconfig"
52source "sound/soc/omap/Kconfig" 53source "sound/soc/omap/Kconfig"
@@ -63,6 +64,7 @@ source "sound/soc/sh/Kconfig"
63source "sound/soc/sirf/Kconfig" 64source "sound/soc/sirf/Kconfig"
64source "sound/soc/spear/Kconfig" 65source "sound/soc/spear/Kconfig"
65source "sound/soc/sti/Kconfig" 66source "sound/soc/sti/Kconfig"
67source "sound/soc/stm/Kconfig"
66source "sound/soc/sunxi/Kconfig" 68source "sound/soc/sunxi/Kconfig"
67source "sound/soc/tegra/Kconfig" 69source "sound/soc/tegra/Kconfig"
68source "sound/soc/txx9/Kconfig" 70source "sound/soc/txx9/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9a30f21d16ee..39c27a58158d 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC) += cirrus/
27obj-$(CONFIG_SND_SOC) += davinci/ 27obj-$(CONFIG_SND_SOC) += davinci/
28obj-$(CONFIG_SND_SOC) += dwc/ 28obj-$(CONFIG_SND_SOC) += dwc/
29obj-$(CONFIG_SND_SOC) += fsl/ 29obj-$(CONFIG_SND_SOC) += fsl/
30obj-$(CONFIG_SND_SOC) += hisilicon/
30obj-$(CONFIG_SND_SOC) += jz4740/ 31obj-$(CONFIG_SND_SOC) += jz4740/
31obj-$(CONFIG_SND_SOC) += img/ 32obj-$(CONFIG_SND_SOC) += img/
32obj-$(CONFIG_SND_SOC) += intel/ 33obj-$(CONFIG_SND_SOC) += intel/
@@ -43,6 +44,7 @@ obj-$(CONFIG_SND_SOC) += sh/
43obj-$(CONFIG_SND_SOC) += sirf/ 44obj-$(CONFIG_SND_SOC) += sirf/
44obj-$(CONFIG_SND_SOC) += spear/ 45obj-$(CONFIG_SND_SOC) += spear/
45obj-$(CONFIG_SND_SOC) += sti/ 46obj-$(CONFIG_SND_SOC) += sti/
47obj-$(CONFIG_SND_SOC) += stm/
46obj-$(CONFIG_SND_SOC) += sunxi/ 48obj-$(CONFIG_SND_SOC) += sunxi/
47obj-$(CONFIG_SND_SOC) += tegra/ 49obj-$(CONFIG_SND_SOC) += tegra/
48obj-$(CONFIG_SND_SOC) += txx9/ 50obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 72ac78988426..64b88fdc1f6c 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -119,7 +119,7 @@ static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd)
119 119
120 return ret; 120 return ret;
121} 121}
122static struct snd_soc_ops bfin_eval_adau1373_ops = { 122static const struct snd_soc_ops bfin_eval_adau1373_ops = {
123 .hw_params = bfin_eval_adau1373_hw_params, 123 .hw_params = bfin_eval_adau1373_hw_params,
124}; 124};
125 125
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 1037477d10b2..99e5ecabdcda 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -64,7 +64,7 @@ static int bfin_eval_adav80x_codec_init(struct snd_soc_pcm_runtime *rtd)
64 return 0; 64 return 0;
65} 65}
66 66
67static struct snd_soc_ops bfin_eval_adav80x_ops = { 67static const struct snd_soc_ops bfin_eval_adav80x_ops = {
68 .hw_params = bfin_eval_adav80x_hw_params, 68 .hw_params = bfin_eval_adav80x_hw_params,
69}; 69};
70 70
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e49e9da7f1f6..883ed4c8a551 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -49,6 +49,7 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_CS35L32 if I2C 49 select SND_SOC_CS35L32 if I2C
50 select SND_SOC_CS35L33 if I2C 50 select SND_SOC_CS35L33 if I2C
51 select SND_SOC_CS35L34 if I2C 51 select SND_SOC_CS35L34 if I2C
52 select SND_SOC_CS35L35 if I2C
52 select SND_SOC_CS42L42 if I2C 53 select SND_SOC_CS42L42 if I2C
53 select SND_SOC_CS42L51_I2C if I2C 54 select SND_SOC_CS42L51_I2C if I2C
54 select SND_SOC_CS42L52 if I2C && INPUT 55 select SND_SOC_CS42L52 if I2C && INPUT
@@ -69,9 +70,11 @@ config SND_SOC_ALL_CODECS
69 select SND_SOC_DA7219 if I2C 70 select SND_SOC_DA7219 if I2C
70 select SND_SOC_DA732X if I2C 71 select SND_SOC_DA732X if I2C
71 select SND_SOC_DA9055 if I2C 72 select SND_SOC_DA9055 if I2C
73 select SND_SOC_DIO2125
72 select SND_SOC_DMIC 74 select SND_SOC_DMIC
73 select SND_SOC_ES8328_SPI if SPI_MASTER 75 select SND_SOC_ES8328_SPI if SPI_MASTER
74 select SND_SOC_ES8328_I2C if I2C 76 select SND_SOC_ES8328_I2C if I2C
77 select SND_SOC_ES7134
75 select SND_SOC_GTM601 78 select SND_SOC_GTM601
76 select SND_SOC_HDAC_HDMI 79 select SND_SOC_HDAC_HDMI
77 select SND_SOC_ICS43432 80 select SND_SOC_ICS43432
@@ -89,6 +92,7 @@ config SND_SOC_ALL_CODECS
89 select SND_SOC_MAX9867 if I2C 92 select SND_SOC_MAX9867 if I2C
90 select SND_SOC_MAX98925 if I2C 93 select SND_SOC_MAX98925 if I2C
91 select SND_SOC_MAX98926 if I2C 94 select SND_SOC_MAX98926 if I2C
95 select SND_SOC_MAX98927 if I2C
92 select SND_SOC_MAX9850 if I2C 96 select SND_SOC_MAX9850 if I2C
93 select SND_SOC_MAX9860 if I2C 97 select SND_SOC_MAX9860 if I2C
94 select SND_SOC_MAX9768 if I2C 98 select SND_SOC_MAX9768 if I2C
@@ -97,6 +101,7 @@ config SND_SOC_ALL_CODECS
97 select SND_SOC_ML26124 if I2C 101 select SND_SOC_ML26124 if I2C
98 select SND_SOC_NAU8540 if I2C 102 select SND_SOC_NAU8540 if I2C
99 select SND_SOC_NAU8810 if I2C 103 select SND_SOC_NAU8810 if I2C
104 select SND_SOC_NAU8824 if I2C
100 select SND_SOC_NAU8825 if I2C 105 select SND_SOC_NAU8825 if I2C
101 select SND_SOC_HDMI_CODEC 106 select SND_SOC_HDMI_CODEC
102 select SND_SOC_PCM1681 if I2C 107 select SND_SOC_PCM1681 if I2C
@@ -303,12 +308,14 @@ config SND_SOC_ADAU1761
303 select SND_SOC_ADAU17X1 308 select SND_SOC_ADAU17X1
304 309
305config SND_SOC_ADAU1761_I2C 310config SND_SOC_ADAU1761_I2C
306 tristate 311 tristate "Analog Devices AU1761 CODEC - I2C"
312 depends on I2C
307 select SND_SOC_ADAU1761 313 select SND_SOC_ADAU1761
308 select REGMAP_I2C 314 select REGMAP_I2C
309 315
310config SND_SOC_ADAU1761_SPI 316config SND_SOC_ADAU1761_SPI
311 tristate 317 tristate "Analog Devices AU1761 CODEC - SPI"
318 depends on SPI
312 select SND_SOC_ADAU1761 319 select SND_SOC_ADAU1761
313 select REGMAP_SPI 320 select REGMAP_SPI
314 321
@@ -408,6 +415,10 @@ config SND_SOC_CS35L34
408 tristate "Cirrus Logic CS35L34 CODEC" 415 tristate "Cirrus Logic CS35L34 CODEC"
409 depends on I2C 416 depends on I2C
410 417
418config SND_SOC_CS35L35
419 tristate "Cirrus Logic CS35L35 CODEC"
420 depends on I2C
421
411config SND_SOC_CS42L42 422config SND_SOC_CS42L42
412 tristate "Cirrus Logic CS42L42 CODEC" 423 tristate "Cirrus Logic CS42L42 CODEC"
413 depends on I2C 424 depends on I2C
@@ -516,6 +527,10 @@ config SND_SOC_DA732X
516config SND_SOC_DA9055 527config SND_SOC_DA9055
517 tristate 528 tristate
518 529
530config SND_SOC_DIO2125
531 tristate "Dioo DIO2125 Amplifier"
532 select GPIOLIB
533
519config SND_SOC_DMIC 534config SND_SOC_DMIC
520 tristate 535 tristate
521 536
@@ -525,6 +540,9 @@ config SND_SOC_HDMI_CODEC
525 select SND_PCM_IEC958 540 select SND_PCM_IEC958
526 select HDMI 541 select HDMI
527 542
543config SND_SOC_ES7134
544 tristate "Everest Semi ES7134 CODEC"
545
528config SND_SOC_ES8328 546config SND_SOC_ES8328
529 tristate 547 tristate
530 548
@@ -588,6 +606,10 @@ config SND_SOC_MAX98925
588config SND_SOC_MAX98926 606config SND_SOC_MAX98926
589 tristate 607 tristate
590 608
609config SND_SOC_MAX98927
610 tristate "Maxim Integrated MAX98927 Speaker Amplifier"
611 depends on I2C
612
591config SND_SOC_MAX9850 613config SND_SOC_MAX9850
592 tristate 614 tristate
593 615
@@ -1116,6 +1138,10 @@ config SND_SOC_NAU8810
1116 tristate "Nuvoton Technology Corporation NAU88C10 CODEC" 1138 tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
1117 depends on I2C 1139 depends on I2C
1118 1140
1141config SND_SOC_NAU8824
1142 tristate "Nuvoton Technology Corporation NAU88L24 CODEC"
1143 depends on I2C
1144
1119config SND_SOC_NAU8825 1145config SND_SOC_NAU8825
1120 tristate 1146 tristate
1121 1147
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1796cb987e71..28a63fdaf982 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -39,6 +39,7 @@ snd-soc-cq93vc-objs := cq93vc.o
39snd-soc-cs35l32-objs := cs35l32.o 39snd-soc-cs35l32-objs := cs35l32.o
40snd-soc-cs35l33-objs := cs35l33.o 40snd-soc-cs35l33-objs := cs35l33.o
41snd-soc-cs35l34-objs := cs35l34.o 41snd-soc-cs35l34-objs := cs35l34.o
42snd-soc-cs35l35-objs := cs35l35.o
42snd-soc-cs42l42-objs := cs42l42.o 43snd-soc-cs42l42-objs := cs42l42.o
43snd-soc-cs42l51-objs := cs42l51.o 44snd-soc-cs42l51-objs := cs42l51.o
44snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o 45snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
@@ -63,6 +64,7 @@ snd-soc-da7219-objs := da7219.o da7219-aad.o
63snd-soc-da732x-objs := da732x.o 64snd-soc-da732x-objs := da732x.o
64snd-soc-da9055-objs := da9055.o 65snd-soc-da9055-objs := da9055.o
65snd-soc-dmic-objs := dmic.o 66snd-soc-dmic-objs := dmic.o
67snd-soc-es7134-objs := es7134.o
66snd-soc-es8328-objs := es8328.o 68snd-soc-es8328-objs := es8328.o
67snd-soc-es8328-i2c-objs := es8328-i2c.o 69snd-soc-es8328-i2c-objs := es8328-i2c.o
68snd-soc-es8328-spi-objs := es8328-spi.o 70snd-soc-es8328-spi-objs := es8328-spi.o
@@ -84,6 +86,7 @@ snd-soc-max98371-objs := max98371.o
84snd-soc-max9867-objs := max9867.o 86snd-soc-max9867-objs := max9867.o
85snd-soc-max98925-objs := max98925.o 87snd-soc-max98925-objs := max98925.o
86snd-soc-max98926-objs := max98926.o 88snd-soc-max98926-objs := max98926.o
89snd-soc-max98927-objs := max98927.o
87snd-soc-max9850-objs := max9850.o 90snd-soc-max9850-objs := max9850.o
88snd-soc-max9860-objs := max9860.o 91snd-soc-max9860-objs := max9860.o
89snd-soc-mc13783-objs := mc13783.o 92snd-soc-mc13783-objs := mc13783.o
@@ -92,6 +95,7 @@ snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
92snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o 95snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
93snd-soc-nau8540-objs := nau8540.o 96snd-soc-nau8540-objs := nau8540.o
94snd-soc-nau8810-objs := nau8810.o 97snd-soc-nau8810-objs := nau8810.o
98snd-soc-nau8824-objs := nau8824.o
95snd-soc-nau8825-objs := nau8825.o 99snd-soc-nau8825-objs := nau8825.o
96snd-soc-hdmi-codec-objs := hdmi-codec.o 100snd-soc-hdmi-codec-objs := hdmi-codec.o
97snd-soc-pcm1681-objs := pcm1681.o 101snd-soc-pcm1681-objs := pcm1681.o
@@ -221,6 +225,7 @@ snd-soc-wm9712-objs := wm9712.o
221snd-soc-wm9713-objs := wm9713.o 225snd-soc-wm9713-objs := wm9713.o
222snd-soc-wm-hubs-objs := wm_hubs.o 226snd-soc-wm-hubs-objs := wm_hubs.o
223# Amp 227# Amp
228snd-soc-dio2125-objs := dio2125.o
224snd-soc-max9877-objs := max9877.o 229snd-soc-max9877-objs := max9877.o
225snd-soc-max98504-objs := max98504.o 230snd-soc-max98504-objs := max98504.o
226snd-soc-tpa6130a2-objs := tpa6130a2.o 231snd-soc-tpa6130a2-objs := tpa6130a2.o
@@ -269,6 +274,7 @@ obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
269obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o 274obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
270obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o 275obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
271obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o 276obj-$(CONFIG_SND_SOC_CS35L34) += snd-soc-cs35l34.o
277obj-$(CONFIG_SND_SOC_CS35L35) += snd-soc-cs35l35.o
272obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o 278obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o
273obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 279obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
274obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o 280obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
@@ -293,6 +299,7 @@ obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
293obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 299obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
294obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 300obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
295obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 301obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
302obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o
296obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o 303obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
297obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o 304obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
298obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o 305obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
@@ -313,6 +320,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
313obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o 320obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
314obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o 321obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
315obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o 322obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
323obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
316obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 324obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
317obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o 325obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
318obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 326obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
@@ -321,6 +329,7 @@ obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
321obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o 329obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
322obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o 330obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
323obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o 331obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
332obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o
324obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 333obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
325obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 334obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
326obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 335obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
@@ -448,6 +457,7 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
448obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 457obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
449 458
450# Amp 459# Amp
460obj-$(CONFIG_SND_SOC_DIO2125) += snd-soc-dio2125.o
451obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 461obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
452obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o 462obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
453obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 463obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index e819dd8c82fd..b2dfddead227 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -75,6 +75,12 @@
75#define DFS_DOUBLE_SPEED (1 << 2) 75#define DFS_DOUBLE_SPEED (1 << 2)
76#define DFS_QUAD_SPEED (2 << 2) 76#define DFS_QUAD_SPEED (2 << 2)
77 77
78/* ICTRL */
79#define ICTRL_MASK (0x3)
80
81/* OCTRL */
82#define OCTRL_MASK (0x3F)
83
78struct ak4613_formats { 84struct ak4613_formats {
79 unsigned int width; 85 unsigned int width;
80 unsigned int fmt; 86 unsigned int fmt;
@@ -365,8 +371,8 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
365 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl); 371 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
366 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2); 372 snd_soc_update_bits(codec, CTRL2, DFS_MASK, ctrl2);
367 373
368 snd_soc_write(codec, ICTRL, priv->ic); 374 snd_soc_update_bits(codec, ICTRL, ICTRL_MASK, priv->ic);
369 snd_soc_write(codec, OCTRL, priv->oc); 375 snd_soc_update_bits(codec, OCTRL, OCTRL_MASK, priv->oc);
370 376
371hw_params_end: 377hw_params_end:
372 if (ret < 0) 378 if (ret < 0)
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
new file mode 100644
index 000000000000..f8aef5869b03
--- /dev/null
+++ b/sound/soc/codecs/cs35l35.c
@@ -0,0 +1,1580 @@
1/*
2 * cs35l35.c -- CS35L35 ALSA SoC audio driver
3 *
4 * Copyright 2017 Cirrus Logic, Inc.
5 *
6 * Author: Brian Austin <brian.austin@cirrus.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
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/gpio/consumer.h>
25#include <linux/of_device.h>
26#include <linux/of_gpio.h>
27#include <linux/regmap.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <linux/gpio.h>
34#include <sound/initval.h>
35#include <sound/tlv.h>
36#include <sound/cs35l35.h>
37#include <linux/of_irq.h>
38#include <linux/completion.h>
39
40#include "cs35l35.h"
41
42/*
43 * Some fields take zero as a valid value so use a high bit flag that won't
44 * get written to the device to mark those.
45 */
46#define CS35L35_VALID_PDATA 0x80000000
47
48static const struct reg_default cs35l35_reg[] = {
49 {CS35L35_PWRCTL1, 0x01},
50 {CS35L35_PWRCTL2, 0x11},
51 {CS35L35_PWRCTL3, 0x00},
52 {CS35L35_CLK_CTL1, 0x04},
53 {CS35L35_CLK_CTL2, 0x12},
54 {CS35L35_CLK_CTL3, 0xCF},
55 {CS35L35_SP_FMT_CTL1, 0x20},
56 {CS35L35_SP_FMT_CTL2, 0x00},
57 {CS35L35_SP_FMT_CTL3, 0x02},
58 {CS35L35_MAG_COMP_CTL, 0x00},
59 {CS35L35_AMP_INP_DRV_CTL, 0x01},
60 {CS35L35_AMP_DIG_VOL_CTL, 0x12},
61 {CS35L35_AMP_DIG_VOL, 0x00},
62 {CS35L35_ADV_DIG_VOL, 0x00},
63 {CS35L35_PROTECT_CTL, 0x06},
64 {CS35L35_AMP_GAIN_AUD_CTL, 0x13},
65 {CS35L35_AMP_GAIN_PDM_CTL, 0x00},
66 {CS35L35_AMP_GAIN_ADV_CTL, 0x00},
67 {CS35L35_GPI_CTL, 0x00},
68 {CS35L35_BST_CVTR_V_CTL, 0x00},
69 {CS35L35_BST_PEAK_I, 0x07},
70 {CS35L35_BST_RAMP_CTL, 0x85},
71 {CS35L35_BST_CONV_COEF_1, 0x24},
72 {CS35L35_BST_CONV_COEF_2, 0x24},
73 {CS35L35_BST_CONV_SLOPE_COMP, 0x4E},
74 {CS35L35_BST_CONV_SW_FREQ, 0x04},
75 {CS35L35_CLASS_H_CTL, 0x0B},
76 {CS35L35_CLASS_H_HEADRM_CTL, 0x0B},
77 {CS35L35_CLASS_H_RELEASE_RATE, 0x08},
78 {CS35L35_CLASS_H_FET_DRIVE_CTL, 0x41},
79 {CS35L35_CLASS_H_VP_CTL, 0xC5},
80 {CS35L35_VPBR_CTL, 0x0A},
81 {CS35L35_VPBR_VOL_CTL, 0x90},
82 {CS35L35_VPBR_TIMING_CTL, 0x6A},
83 {CS35L35_VPBR_MODE_VOL_CTL, 0x00},
84 {CS35L35_SPKR_MON_CTL, 0xC0},
85 {CS35L35_IMON_SCALE_CTL, 0x30},
86 {CS35L35_AUDIN_RXLOC_CTL, 0x00},
87 {CS35L35_ADVIN_RXLOC_CTL, 0x80},
88 {CS35L35_VMON_TXLOC_CTL, 0x00},
89 {CS35L35_IMON_TXLOC_CTL, 0x80},
90 {CS35L35_VPMON_TXLOC_CTL, 0x04},
91 {CS35L35_VBSTMON_TXLOC_CTL, 0x84},
92 {CS35L35_VPBR_STATUS_TXLOC_CTL, 0x04},
93 {CS35L35_ZERO_FILL_LOC_CTL, 0x00},
94 {CS35L35_AUDIN_DEPTH_CTL, 0x0F},
95 {CS35L35_SPKMON_DEPTH_CTL, 0x0F},
96 {CS35L35_SUPMON_DEPTH_CTL, 0x0F},
97 {CS35L35_ZEROFILL_DEPTH_CTL, 0x00},
98 {CS35L35_MULT_DEV_SYNCH1, 0x02},
99 {CS35L35_MULT_DEV_SYNCH2, 0x80},
100 {CS35L35_PROT_RELEASE_CTL, 0x00},
101 {CS35L35_DIAG_MODE_REG_LOCK, 0x00},
102 {CS35L35_DIAG_MODE_CTL_1, 0x40},
103 {CS35L35_DIAG_MODE_CTL_2, 0x00},
104 {CS35L35_INT_MASK_1, 0xFF},
105 {CS35L35_INT_MASK_2, 0xFF},
106 {CS35L35_INT_MASK_3, 0xFF},
107 {CS35L35_INT_MASK_4, 0xFF},
108
109};
110
111static bool cs35l35_volatile_register(struct device *dev, unsigned int reg)
112{
113 switch (reg) {
114 case CS35L35_INT_STATUS_1:
115 case CS35L35_INT_STATUS_2:
116 case CS35L35_INT_STATUS_3:
117 case CS35L35_INT_STATUS_4:
118 case CS35L35_PLL_STATUS:
119 case CS35L35_OTP_TRIM_STATUS:
120 return true;
121 default:
122 return false;
123 }
124}
125
126static bool cs35l35_readable_register(struct device *dev, unsigned int reg)
127{
128 switch (reg) {
129 case CS35L35_DEVID_AB ... CS35L35_PWRCTL3:
130 case CS35L35_CLK_CTL1 ... CS35L35_SP_FMT_CTL3:
131 case CS35L35_MAG_COMP_CTL ... CS35L35_AMP_GAIN_AUD_CTL:
132 case CS35L35_AMP_GAIN_PDM_CTL ... CS35L35_BST_PEAK_I:
133 case CS35L35_BST_RAMP_CTL ... CS35L35_BST_CONV_SW_FREQ:
134 case CS35L35_CLASS_H_CTL ... CS35L35_CLASS_H_VP_CTL:
135 case CS35L35_CLASS_H_STATUS:
136 case CS35L35_VPBR_CTL ... CS35L35_VPBR_MODE_VOL_CTL:
137 case CS35L35_VPBR_ATTEN_STATUS:
138 case CS35L35_SPKR_MON_CTL:
139 case CS35L35_IMON_SCALE_CTL ... CS35L35_ZEROFILL_DEPTH_CTL:
140 case CS35L35_MULT_DEV_SYNCH1 ... CS35L35_PROT_RELEASE_CTL:
141 case CS35L35_DIAG_MODE_REG_LOCK ... CS35L35_DIAG_MODE_CTL_2:
142 case CS35L35_INT_MASK_1 ... CS35L35_PLL_STATUS:
143 case CS35L35_OTP_TRIM_STATUS:
144 return true;
145 default:
146 return false;
147 }
148}
149
150static bool cs35l35_precious_register(struct device *dev, unsigned int reg)
151{
152 switch (reg) {
153 case CS35L35_INT_STATUS_1:
154 case CS35L35_INT_STATUS_2:
155 case CS35L35_INT_STATUS_3:
156 case CS35L35_INT_STATUS_4:
157 case CS35L35_PLL_STATUS:
158 case CS35L35_OTP_TRIM_STATUS:
159 return true;
160 default:
161 return false;
162 }
163}
164
165static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
166{
167 int ret;
168
169 if (cs35l35->pdata.ext_bst) {
170 usleep_range(5000, 5500);
171 return 0;
172 }
173
174 reinit_completion(&cs35l35->pdn_done);
175
176 ret = wait_for_completion_timeout(&cs35l35->pdn_done,
177 msecs_to_jiffies(100));
178 if (ret == 0) {
179 dev_err(cs35l35->dev, "PDN_DONE did not complete\n");
180 return -ETIMEDOUT;
181 }
182
183 return 0;
184}
185
186static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
187 struct snd_kcontrol *kcontrol, int event)
188{
189 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
190 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
191 int ret = 0;
192
193 switch (event) {
194 case SND_SOC_DAPM_PRE_PMU:
195 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
196 CS35L35_MCLK_DIS_MASK,
197 0 << CS35L35_MCLK_DIS_SHIFT);
198 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
199 CS35L35_DISCHG_FILT_MASK,
200 0 << CS35L35_DISCHG_FILT_SHIFT);
201 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
202 CS35L35_PDN_ALL_MASK, 0);
203 break;
204 case SND_SOC_DAPM_POST_PMD:
205 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
206 CS35L35_DISCHG_FILT_MASK,
207 1 << CS35L35_DISCHG_FILT_SHIFT);
208 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
209 CS35L35_PDN_ALL_MASK, 1);
210
211 /* Already muted, so disable volume ramp for faster shutdown */
212 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
213 CS35L35_AMP_DIGSFT_MASK, 0);
214
215 ret = cs35l35_wait_for_pdn(cs35l35);
216
217 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
218 CS35L35_MCLK_DIS_MASK,
219 1 << CS35L35_MCLK_DIS_SHIFT);
220
221 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
222 CS35L35_AMP_DIGSFT_MASK,
223 1 << CS35L35_AMP_DIGSFT_SHIFT);
224 break;
225 default:
226 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
227 ret = -EINVAL;
228 }
229 return ret;
230}
231
232static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
233 struct snd_kcontrol *kcontrol, int event)
234{
235 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
236 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
237 unsigned int reg[4];
238 int i;
239
240 switch (event) {
241 case SND_SOC_DAPM_PRE_PMU:
242 if (cs35l35->pdata.bst_pdn_fet_on)
243 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
244 CS35L35_PDN_BST_MASK,
245 0 << CS35L35_PDN_BST_FETON_SHIFT);
246 else
247 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
248 CS35L35_PDN_BST_MASK,
249 0 << CS35L35_PDN_BST_FETOFF_SHIFT);
250 break;
251 case SND_SOC_DAPM_POST_PMU:
252 usleep_range(5000, 5100);
253 /* If in PDM mode we must use VP for Voltage control */
254 if (cs35l35->pdm_mode)
255 regmap_update_bits(cs35l35->regmap,
256 CS35L35_BST_CVTR_V_CTL,
257 CS35L35_BST_CTL_MASK,
258 0 << CS35L35_BST_CTL_SHIFT);
259
260 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
261 CS35L35_AMP_MUTE_MASK, 0);
262
263 for (i = 0; i < 2; i++)
264 regmap_bulk_read(cs35l35->regmap, CS35L35_INT_STATUS_1,
265 &reg, ARRAY_SIZE(reg));
266
267 break;
268 case SND_SOC_DAPM_PRE_PMD:
269 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
270 CS35L35_AMP_MUTE_MASK,
271 1 << CS35L35_AMP_MUTE_SHIFT);
272 if (cs35l35->pdata.bst_pdn_fet_on)
273 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
274 CS35L35_PDN_BST_MASK,
275 1 << CS35L35_PDN_BST_FETON_SHIFT);
276 else
277 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
278 CS35L35_PDN_BST_MASK,
279 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
280 break;
281 case SND_SOC_DAPM_POST_PMD:
282 usleep_range(5000, 5100);
283 /*
284 * If PDM mode we should switch back to pdata value
285 * for Voltage control when we go down
286 */
287 if (cs35l35->pdm_mode)
288 regmap_update_bits(cs35l35->regmap,
289 CS35L35_BST_CVTR_V_CTL,
290 CS35L35_BST_CTL_MASK,
291 cs35l35->pdata.bst_vctl
292 << CS35L35_BST_CTL_SHIFT);
293
294 break;
295 default:
296 dev_err(codec->dev, "Invalid event = 0x%x\n", event);
297 }
298 return 0;
299}
300
301static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
302static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
303
304static const struct snd_kcontrol_new cs35l35_aud_controls[] = {
305 SOC_SINGLE_SX_TLV("Digital Audio Volume", CS35L35_AMP_DIG_VOL,
306 0, 0x34, 0xE4, dig_vol_tlv),
307 SOC_SINGLE_TLV("Analog Audio Volume", CS35L35_AMP_GAIN_AUD_CTL, 0, 19, 0,
308 amp_gain_tlv),
309 SOC_SINGLE_TLV("PDM Volume", CS35L35_AMP_GAIN_PDM_CTL, 0, 19, 0,
310 amp_gain_tlv),
311};
312
313static const struct snd_kcontrol_new cs35l35_adv_controls[] = {
314 SOC_SINGLE_SX_TLV("Digital Advisory Volume", CS35L35_ADV_DIG_VOL,
315 0, 0x34, 0xE4, dig_vol_tlv),
316 SOC_SINGLE_TLV("Analog Advisory Volume", CS35L35_AMP_GAIN_ADV_CTL, 0, 19, 0,
317 amp_gain_tlv),
318};
319
320static const struct snd_soc_dapm_widget cs35l35_dapm_widgets[] = {
321 SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L35_PWRCTL3, 1, 1,
322 cs35l35_sdin_event, SND_SOC_DAPM_PRE_PMU |
323 SND_SOC_DAPM_POST_PMD),
324 SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L35_PWRCTL3, 2, 1),
325
326 SND_SOC_DAPM_OUTPUT("SPK"),
327
328 SND_SOC_DAPM_INPUT("VP"),
329 SND_SOC_DAPM_INPUT("VBST"),
330 SND_SOC_DAPM_INPUT("ISENSE"),
331 SND_SOC_DAPM_INPUT("VSENSE"),
332
333 SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L35_PWRCTL2, 7, 1),
334 SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L35_PWRCTL2, 6, 1),
335 SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L35_PWRCTL3, 3, 1),
336 SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L35_PWRCTL3, 4, 1),
337 SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L35_PWRCTL2, 5, 1),
338
339 SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L35_PWRCTL2, 0, 1, NULL, 0,
340 cs35l35_main_amp_event, SND_SOC_DAPM_PRE_PMU |
341 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU |
342 SND_SOC_DAPM_PRE_PMD),
343};
344
345static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
346 {"VPMON ADC", NULL, "VP"},
347 {"VBSTMON ADC", NULL, "VBST"},
348 {"IMON ADC", NULL, "ISENSE"},
349 {"VMON ADC", NULL, "VSENSE"},
350 {"SDOUT", NULL, "IMON ADC"},
351 {"SDOUT", NULL, "VMON ADC"},
352 {"SDOUT", NULL, "VBSTMON ADC"},
353 {"SDOUT", NULL, "VPMON ADC"},
354 {"AMP Capture", NULL, "SDOUT"},
355
356 {"SDIN", NULL, "AMP Playback"},
357 {"CLASS H", NULL, "SDIN"},
358 {"Main AMP", NULL, "CLASS H"},
359 {"SPK", NULL, "Main AMP"},
360};
361
362static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
363{
364 struct snd_soc_codec *codec = codec_dai->codec;
365 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
366
367 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
368 case SND_SOC_DAIFMT_CBM_CFM:
369 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
370 CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);
371 cs35l35->slave_mode = false;
372 break;
373 case SND_SOC_DAIFMT_CBS_CFS:
374 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
375 CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);
376 cs35l35->slave_mode = true;
377 break;
378 default:
379 return -EINVAL;
380 }
381
382 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
383 case SND_SOC_DAIFMT_I2S:
384 cs35l35->i2s_mode = true;
385 cs35l35->pdm_mode = false;
386 break;
387 case SND_SOC_DAIFMT_PDM:
388 cs35l35->pdm_mode = true;
389 cs35l35->i2s_mode = false;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398struct cs35l35_sysclk_config {
399 int sysclk;
400 int srate;
401 u8 clk_cfg;
402};
403
404static struct cs35l35_sysclk_config cs35l35_clk_ctl[] = {
405
406 /* SYSCLK, Sample Rate, Serial Port Cfg */
407 {5644800, 44100, 0x00},
408 {5644800, 88200, 0x40},
409 {6144000, 48000, 0x10},
410 {6144000, 96000, 0x50},
411 {11289600, 44100, 0x01},
412 {11289600, 88200, 0x41},
413 {11289600, 176400, 0x81},
414 {12000000, 44100, 0x03},
415 {12000000, 48000, 0x13},
416 {12000000, 88200, 0x43},
417 {12000000, 96000, 0x53},
418 {12000000, 176400, 0x83},
419 {12000000, 192000, 0x93},
420 {12288000, 48000, 0x11},
421 {12288000, 96000, 0x51},
422 {12288000, 192000, 0x91},
423 {13000000, 44100, 0x07},
424 {13000000, 48000, 0x17},
425 {13000000, 88200, 0x47},
426 {13000000, 96000, 0x57},
427 {13000000, 176400, 0x87},
428 {13000000, 192000, 0x97},
429 {22579200, 44100, 0x02},
430 {22579200, 88200, 0x42},
431 {22579200, 176400, 0x82},
432 {24000000, 44100, 0x0B},
433 {24000000, 48000, 0x1B},
434 {24000000, 88200, 0x4B},
435 {24000000, 96000, 0x5B},
436 {24000000, 176400, 0x8B},
437 {24000000, 192000, 0x9B},
438 {24576000, 48000, 0x12},
439 {24576000, 96000, 0x52},
440 {24576000, 192000, 0x92},
441 {26000000, 44100, 0x0F},
442 {26000000, 48000, 0x1F},
443 {26000000, 88200, 0x4F},
444 {26000000, 96000, 0x5F},
445 {26000000, 176400, 0x8F},
446 {26000000, 192000, 0x9F},
447};
448
449static int cs35l35_get_clk_config(int sysclk, int srate)
450{
451 int i;
452
453 for (i = 0; i < ARRAY_SIZE(cs35l35_clk_ctl); i++) {
454 if (cs35l35_clk_ctl[i].sysclk == sysclk &&
455 cs35l35_clk_ctl[i].srate == srate)
456 return cs35l35_clk_ctl[i].clk_cfg;
457 }
458 return -EINVAL;
459}
460
461static int cs35l35_hw_params(struct snd_pcm_substream *substream,
462 struct snd_pcm_hw_params *params,
463 struct snd_soc_dai *dai)
464{
465 struct snd_soc_codec *codec = dai->codec;
466 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
467 struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
468 int srate = params_rate(params);
469 int ret = 0;
470 u8 sp_sclks;
471 int audin_format;
472 int errata_chk;
473
474 int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
475
476 if (clk_ctl < 0) {
477 dev_err(codec->dev, "Invalid CLK:Rate %d:%d\n",
478 cs35l35->sysclk, srate);
479 return -EINVAL;
480 }
481
482 ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
483 CS35L35_CLK_CTL2_MASK, clk_ctl);
484 if (ret != 0) {
485 dev_err(codec->dev, "Failed to set port config %d\n", ret);
486 return ret;
487 }
488
489 /*
490 * Rev A0 Errata
491 * When configured for the weak-drive detection path (CH_WKFET_DIS = 0)
492 * the Class H algorithm does not enable weak-drive operation for
493 * nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10
494 */
495 errata_chk = clk_ctl & CS35L35_SP_RATE_MASK;
496
497 if (classh->classh_wk_fet_disable == 0x00 &&
498 (errata_chk == 0x01 || errata_chk == 0x03)) {
499 ret = regmap_update_bits(cs35l35->regmap,
500 CS35L35_CLASS_H_FET_DRIVE_CTL,
501 CS35L35_CH_WKFET_DEL_MASK,
502 0 << CS35L35_CH_WKFET_DEL_SHIFT);
503 if (ret != 0) {
504 dev_err(codec->dev, "Failed to set fet config %d\n",
505 ret);
506 return ret;
507 }
508 }
509
510 /*
511 * You can pull more Monitor data from the SDOUT pin than going to SDIN
512 * Just make sure your SCLK is fast enough to fill the frame
513 */
514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
515 switch (params_width(params)) {
516 case 8:
517 audin_format = CS35L35_SDIN_DEPTH_8;
518 break;
519 case 16:
520 audin_format = CS35L35_SDIN_DEPTH_16;
521 break;
522 case 24:
523 audin_format = CS35L35_SDIN_DEPTH_24;
524 break;
525 default:
526 dev_err(codec->dev, "Unsupported Width %d\n",
527 params_width(params));
528 return -EINVAL;
529 }
530 regmap_update_bits(cs35l35->regmap,
531 CS35L35_AUDIN_DEPTH_CTL,
532 CS35L35_AUDIN_DEPTH_MASK,
533 audin_format <<
534 CS35L35_AUDIN_DEPTH_SHIFT);
535 if (cs35l35->pdata.stereo) {
536 regmap_update_bits(cs35l35->regmap,
537 CS35L35_AUDIN_DEPTH_CTL,
538 CS35L35_ADVIN_DEPTH_MASK,
539 audin_format <<
540 CS35L35_ADVIN_DEPTH_SHIFT);
541 }
542 }
543
544 if (cs35l35->i2s_mode) {
545 /* We have to take the SCLK to derive num sclks
546 * to configure the CLOCK_CTL3 register correctly
547 */
548 if ((cs35l35->sclk / srate) % 4) {
549 dev_err(codec->dev, "Unsupported sclk/fs ratio %d:%d\n",
550 cs35l35->sclk, srate);
551 return -EINVAL;
552 }
553 sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;
554
555 /* Only certain ratios are supported in I2S Slave Mode */
556 if (cs35l35->slave_mode) {
557 switch (sp_sclks) {
558 case CS35L35_SP_SCLKS_32FS:
559 case CS35L35_SP_SCLKS_48FS:
560 case CS35L35_SP_SCLKS_64FS:
561 break;
562 default:
563 dev_err(codec->dev, "ratio not supported\n");
564 return -EINVAL;
565 }
566 } else {
567 /* Only certain ratios supported in I2S MASTER Mode */
568 switch (sp_sclks) {
569 case CS35L35_SP_SCLKS_32FS:
570 case CS35L35_SP_SCLKS_64FS:
571 break;
572 default:
573 dev_err(codec->dev, "ratio not supported\n");
574 return -EINVAL;
575 }
576 }
577 ret = regmap_update_bits(cs35l35->regmap,
578 CS35L35_CLK_CTL3,
579 CS35L35_SP_SCLKS_MASK, sp_sclks <<
580 CS35L35_SP_SCLKS_SHIFT);
581 if (ret != 0) {
582 dev_err(codec->dev, "Failed to set fsclk %d\n", ret);
583 return ret;
584 }
585 }
586
587 return ret;
588}
589
590static const unsigned int cs35l35_src_rates[] = {
591 44100, 48000, 88200, 96000, 176400, 192000
592};
593
594static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
595 .count = ARRAY_SIZE(cs35l35_src_rates),
596 .list = cs35l35_src_rates,
597};
598
599static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
600 struct snd_soc_dai *dai)
601{
602 struct snd_soc_codec *codec = dai->codec;
603 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
604
605 if (!substream->runtime)
606 return 0;
607
608 snd_pcm_hw_constraint_list(substream->runtime, 0,
609 SNDRV_PCM_HW_PARAM_RATE, &cs35l35_constraints);
610
611 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
612 CS35L35_PDM_MODE_MASK,
613 0 << CS35L35_PDM_MODE_SHIFT);
614
615 return 0;
616}
617
618static const unsigned int cs35l35_pdm_rates[] = {
619 44100, 48000, 88200, 96000
620};
621
622static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
623 .count = ARRAY_SIZE(cs35l35_pdm_rates),
624 .list = cs35l35_pdm_rates,
625};
626
627static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
628 struct snd_soc_dai *dai)
629{
630 struct snd_soc_codec *codec = dai->codec;
631 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
632
633 if (!substream->runtime)
634 return 0;
635
636 snd_pcm_hw_constraint_list(substream->runtime, 0,
637 SNDRV_PCM_HW_PARAM_RATE,
638 &cs35l35_pdm_constraints);
639
640 regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
641 CS35L35_PDM_MODE_MASK,
642 1 << CS35L35_PDM_MODE_SHIFT);
643
644 return 0;
645}
646
647static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
648 int clk_id, unsigned int freq, int dir)
649{
650 struct snd_soc_codec *codec = dai->codec;
651 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
652
653 /* Need the SCLK Frequency regardless of sysclk source for I2S */
654 cs35l35->sclk = freq;
655
656 return 0;
657}
658
659static const struct snd_soc_dai_ops cs35l35_ops = {
660 .startup = cs35l35_pcm_startup,
661 .set_fmt = cs35l35_set_dai_fmt,
662 .hw_params = cs35l35_hw_params,
663 .set_sysclk = cs35l35_dai_set_sysclk,
664};
665
666static const struct snd_soc_dai_ops cs35l35_pdm_ops = {
667 .startup = cs35l35_pdm_startup,
668 .set_fmt = cs35l35_set_dai_fmt,
669 .hw_params = cs35l35_hw_params,
670};
671
672static struct snd_soc_dai_driver cs35l35_dai[] = {
673 {
674 .name = "cs35l35-pcm",
675 .id = 0,
676 .playback = {
677 .stream_name = "AMP Playback",
678 .channels_min = 1,
679 .channels_max = 8,
680 .rates = SNDRV_PCM_RATE_KNOT,
681 .formats = CS35L35_FORMATS,
682 },
683 .capture = {
684 .stream_name = "AMP Capture",
685 .channels_min = 1,
686 .channels_max = 8,
687 .rates = SNDRV_PCM_RATE_KNOT,
688 .formats = CS35L35_FORMATS,
689 },
690 .ops = &cs35l35_ops,
691 .symmetric_rates = 1,
692 },
693 {
694 .name = "cs35l35-pdm",
695 .id = 1,
696 .playback = {
697 .stream_name = "PDM Playback",
698 .channels_min = 1,
699 .channels_max = 2,
700 .rates = SNDRV_PCM_RATE_KNOT,
701 .formats = CS35L35_FORMATS,
702 },
703 .ops = &cs35l35_pdm_ops,
704 },
705};
706
707static int cs35l35_codec_set_sysclk(struct snd_soc_codec *codec,
708 int clk_id, int source, unsigned int freq,
709 int dir)
710{
711 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
712 int clksrc;
713 int ret = 0;
714
715 switch (clk_id) {
716 case 0:
717 clksrc = CS35L35_CLK_SOURCE_MCLK;
718 break;
719 case 1:
720 clksrc = CS35L35_CLK_SOURCE_SCLK;
721 break;
722 case 2:
723 clksrc = CS35L35_CLK_SOURCE_PDM;
724 break;
725 default:
726 dev_err(codec->dev, "Invalid CLK Source\n");
727 return -EINVAL;
728 }
729
730 switch (freq) {
731 case 5644800:
732 case 6144000:
733 case 11289600:
734 case 12000000:
735 case 12288000:
736 case 13000000:
737 case 22579200:
738 case 24000000:
739 case 24576000:
740 case 26000000:
741 cs35l35->sysclk = freq;
742 break;
743 default:
744 dev_err(codec->dev, "Invalid CLK Frequency Input : %d\n", freq);
745 return -EINVAL;
746 }
747
748 ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
749 CS35L35_CLK_SOURCE_MASK,
750 clksrc << CS35L35_CLK_SOURCE_SHIFT);
751 if (ret != 0) {
752 dev_err(codec->dev, "Failed to set sysclk %d\n", ret);
753 return ret;
754 }
755
756 return ret;
757}
758
759static int cs35l35_codec_probe(struct snd_soc_codec *codec)
760{
761 struct cs35l35_private *cs35l35 = snd_soc_codec_get_drvdata(codec);
762 struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
763 struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
764 int ret;
765
766 /* Set Platform Data */
767 if (cs35l35->pdata.bst_vctl)
768 regmap_update_bits(cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,
769 CS35L35_BST_CTL_MASK,
770 cs35l35->pdata.bst_vctl);
771
772 if (cs35l35->pdata.bst_ipk)
773 regmap_update_bits(cs35l35->regmap, CS35L35_BST_PEAK_I,
774 CS35L35_BST_IPK_MASK,
775 cs35l35->pdata.bst_ipk <<
776 CS35L35_BST_IPK_SHIFT);
777
778 if (cs35l35->pdata.gain_zc)
779 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
780 CS35L35_AMP_GAIN_ZC_MASK,
781 cs35l35->pdata.gain_zc <<
782 CS35L35_AMP_GAIN_ZC_SHIFT);
783
784 if (cs35l35->pdata.aud_channel)
785 regmap_update_bits(cs35l35->regmap,
786 CS35L35_AUDIN_RXLOC_CTL,
787 CS35L35_AUD_IN_LR_MASK,
788 cs35l35->pdata.aud_channel <<
789 CS35L35_AUD_IN_LR_SHIFT);
790
791 if (cs35l35->pdata.stereo) {
792 regmap_update_bits(cs35l35->regmap,
793 CS35L35_ADVIN_RXLOC_CTL,
794 CS35L35_ADV_IN_LR_MASK,
795 cs35l35->pdata.adv_channel <<
796 CS35L35_ADV_IN_LR_SHIFT);
797 if (cs35l35->pdata.shared_bst)
798 regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
799 CS35L35_CH_STEREO_MASK,
800 1 << CS35L35_CH_STEREO_SHIFT);
801 ret = snd_soc_add_codec_controls(codec, cs35l35_adv_controls,
802 ARRAY_SIZE(cs35l35_adv_controls));
803 if (ret)
804 return ret;
805 }
806
807 if (cs35l35->pdata.sp_drv_str)
808 regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
809 CS35L35_SP_DRV_MASK,
810 cs35l35->pdata.sp_drv_str <<
811 CS35L35_SP_DRV_SHIFT);
812 if (cs35l35->pdata.sp_drv_unused)
813 regmap_update_bits(cs35l35->regmap, CS35L35_SP_FMT_CTL3,
814 CS35L35_SP_I2S_DRV_MASK,
815 cs35l35->pdata.sp_drv_unused <<
816 CS35L35_SP_I2S_DRV_SHIFT);
817
818 if (classh->classh_algo_enable) {
819 if (classh->classh_bst_override)
820 regmap_update_bits(cs35l35->regmap,
821 CS35L35_CLASS_H_CTL,
822 CS35L35_CH_BST_OVR_MASK,
823 classh->classh_bst_override <<
824 CS35L35_CH_BST_OVR_SHIFT);
825 if (classh->classh_bst_max_limit)
826 regmap_update_bits(cs35l35->regmap,
827 CS35L35_CLASS_H_CTL,
828 CS35L35_CH_BST_LIM_MASK,
829 classh->classh_bst_max_limit <<
830 CS35L35_CH_BST_LIM_SHIFT);
831 if (classh->classh_mem_depth)
832 regmap_update_bits(cs35l35->regmap,
833 CS35L35_CLASS_H_CTL,
834 CS35L35_CH_MEM_DEPTH_MASK,
835 classh->classh_mem_depth <<
836 CS35L35_CH_MEM_DEPTH_SHIFT);
837 if (classh->classh_headroom)
838 regmap_update_bits(cs35l35->regmap,
839 CS35L35_CLASS_H_HEADRM_CTL,
840 CS35L35_CH_HDRM_CTL_MASK,
841 classh->classh_headroom <<
842 CS35L35_CH_HDRM_CTL_SHIFT);
843 if (classh->classh_release_rate)
844 regmap_update_bits(cs35l35->regmap,
845 CS35L35_CLASS_H_RELEASE_RATE,
846 CS35L35_CH_REL_RATE_MASK,
847 classh->classh_release_rate <<
848 CS35L35_CH_REL_RATE_SHIFT);
849 if (classh->classh_wk_fet_disable)
850 regmap_update_bits(cs35l35->regmap,
851 CS35L35_CLASS_H_FET_DRIVE_CTL,
852 CS35L35_CH_WKFET_DIS_MASK,
853 classh->classh_wk_fet_disable <<
854 CS35L35_CH_WKFET_DIS_SHIFT);
855 if (classh->classh_wk_fet_delay)
856 regmap_update_bits(cs35l35->regmap,
857 CS35L35_CLASS_H_FET_DRIVE_CTL,
858 CS35L35_CH_WKFET_DEL_MASK,
859 classh->classh_wk_fet_delay <<
860 CS35L35_CH_WKFET_DEL_SHIFT);
861 if (classh->classh_wk_fet_thld)
862 regmap_update_bits(cs35l35->regmap,
863 CS35L35_CLASS_H_FET_DRIVE_CTL,
864 CS35L35_CH_WKFET_THLD_MASK,
865 classh->classh_wk_fet_thld <<
866 CS35L35_CH_WKFET_THLD_SHIFT);
867 if (classh->classh_vpch_auto)
868 regmap_update_bits(cs35l35->regmap,
869 CS35L35_CLASS_H_VP_CTL,
870 CS35L35_CH_VP_AUTO_MASK,
871 classh->classh_vpch_auto <<
872 CS35L35_CH_VP_AUTO_SHIFT);
873 if (classh->classh_vpch_rate)
874 regmap_update_bits(cs35l35->regmap,
875 CS35L35_CLASS_H_VP_CTL,
876 CS35L35_CH_VP_RATE_MASK,
877 classh->classh_vpch_rate <<
878 CS35L35_CH_VP_RATE_SHIFT);
879 if (classh->classh_vpch_man)
880 regmap_update_bits(cs35l35->regmap,
881 CS35L35_CLASS_H_VP_CTL,
882 CS35L35_CH_VP_MAN_MASK,
883 classh->classh_vpch_man <<
884 CS35L35_CH_VP_MAN_SHIFT);
885 }
886
887 if (monitor_config->is_present) {
888 if (monitor_config->vmon_specs) {
889 regmap_update_bits(cs35l35->regmap,
890 CS35L35_SPKMON_DEPTH_CTL,
891 CS35L35_VMON_DEPTH_MASK,
892 monitor_config->vmon_dpth <<
893 CS35L35_VMON_DEPTH_SHIFT);
894 regmap_update_bits(cs35l35->regmap,
895 CS35L35_VMON_TXLOC_CTL,
896 CS35L35_MON_TXLOC_MASK,
897 monitor_config->vmon_loc <<
898 CS35L35_MON_TXLOC_SHIFT);
899 regmap_update_bits(cs35l35->regmap,
900 CS35L35_VMON_TXLOC_CTL,
901 CS35L35_MON_FRM_MASK,
902 monitor_config->vmon_frm <<
903 CS35L35_MON_FRM_SHIFT);
904 }
905 if (monitor_config->imon_specs) {
906 regmap_update_bits(cs35l35->regmap,
907 CS35L35_SPKMON_DEPTH_CTL,
908 CS35L35_IMON_DEPTH_MASK,
909 monitor_config->imon_dpth <<
910 CS35L35_IMON_DEPTH_SHIFT);
911 regmap_update_bits(cs35l35->regmap,
912 CS35L35_IMON_TXLOC_CTL,
913 CS35L35_MON_TXLOC_MASK,
914 monitor_config->imon_loc <<
915 CS35L35_MON_TXLOC_SHIFT);
916 regmap_update_bits(cs35l35->regmap,
917 CS35L35_IMON_TXLOC_CTL,
918 CS35L35_MON_FRM_MASK,
919 monitor_config->imon_frm <<
920 CS35L35_MON_FRM_SHIFT);
921 regmap_update_bits(cs35l35->regmap,
922 CS35L35_IMON_SCALE_CTL,
923 CS35L35_IMON_SCALE_MASK,
924 monitor_config->imon_scale <<
925 CS35L35_IMON_SCALE_SHIFT);
926 }
927 if (monitor_config->vpmon_specs) {
928 regmap_update_bits(cs35l35->regmap,
929 CS35L35_SUPMON_DEPTH_CTL,
930 CS35L35_VPMON_DEPTH_MASK,
931 monitor_config->vpmon_dpth <<
932 CS35L35_VPMON_DEPTH_SHIFT);
933 regmap_update_bits(cs35l35->regmap,
934 CS35L35_VPMON_TXLOC_CTL,
935 CS35L35_MON_TXLOC_MASK,
936 monitor_config->vpmon_loc <<
937 CS35L35_MON_TXLOC_SHIFT);
938 regmap_update_bits(cs35l35->regmap,
939 CS35L35_VPMON_TXLOC_CTL,
940 CS35L35_MON_FRM_MASK,
941 monitor_config->vpmon_frm <<
942 CS35L35_MON_FRM_SHIFT);
943 }
944 if (monitor_config->vbstmon_specs) {
945 regmap_update_bits(cs35l35->regmap,
946 CS35L35_SUPMON_DEPTH_CTL,
947 CS35L35_VBSTMON_DEPTH_MASK,
948 monitor_config->vpmon_dpth <<
949 CS35L35_VBSTMON_DEPTH_SHIFT);
950 regmap_update_bits(cs35l35->regmap,
951 CS35L35_VBSTMON_TXLOC_CTL,
952 CS35L35_MON_TXLOC_MASK,
953 monitor_config->vbstmon_loc <<
954 CS35L35_MON_TXLOC_SHIFT);
955 regmap_update_bits(cs35l35->regmap,
956 CS35L35_VBSTMON_TXLOC_CTL,
957 CS35L35_MON_FRM_MASK,
958 monitor_config->vbstmon_frm <<
959 CS35L35_MON_FRM_SHIFT);
960 }
961 if (monitor_config->vpbrstat_specs) {
962 regmap_update_bits(cs35l35->regmap,
963 CS35L35_SUPMON_DEPTH_CTL,
964 CS35L35_VPBRSTAT_DEPTH_MASK,
965 monitor_config->vpbrstat_dpth <<
966 CS35L35_VPBRSTAT_DEPTH_SHIFT);
967 regmap_update_bits(cs35l35->regmap,
968 CS35L35_VPBR_STATUS_TXLOC_CTL,
969 CS35L35_MON_TXLOC_MASK,
970 monitor_config->vpbrstat_loc <<
971 CS35L35_MON_TXLOC_SHIFT);
972 regmap_update_bits(cs35l35->regmap,
973 CS35L35_VPBR_STATUS_TXLOC_CTL,
974 CS35L35_MON_FRM_MASK,
975 monitor_config->vpbrstat_frm <<
976 CS35L35_MON_FRM_SHIFT);
977 }
978 if (monitor_config->zerofill_specs) {
979 regmap_update_bits(cs35l35->regmap,
980 CS35L35_SUPMON_DEPTH_CTL,
981 CS35L35_ZEROFILL_DEPTH_MASK,
982 monitor_config->zerofill_dpth <<
983 CS35L35_ZEROFILL_DEPTH_SHIFT);
984 regmap_update_bits(cs35l35->regmap,
985 CS35L35_ZERO_FILL_LOC_CTL,
986 CS35L35_MON_TXLOC_MASK,
987 monitor_config->zerofill_loc <<
988 CS35L35_MON_TXLOC_SHIFT);
989 regmap_update_bits(cs35l35->regmap,
990 CS35L35_ZERO_FILL_LOC_CTL,
991 CS35L35_MON_FRM_MASK,
992 monitor_config->zerofill_frm <<
993 CS35L35_MON_FRM_SHIFT);
994 }
995 }
996
997 return 0;
998}
999
1000static struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
1001 .probe = cs35l35_codec_probe,
1002 .set_sysclk = cs35l35_codec_set_sysclk,
1003 .component_driver = {
1004 .dapm_widgets = cs35l35_dapm_widgets,
1005 .num_dapm_widgets = ARRAY_SIZE(cs35l35_dapm_widgets),
1006
1007 .dapm_routes = cs35l35_audio_map,
1008 .num_dapm_routes = ARRAY_SIZE(cs35l35_audio_map),
1009
1010 .controls = cs35l35_aud_controls,
1011 .num_controls = ARRAY_SIZE(cs35l35_aud_controls),
1012 },
1013
1014};
1015
1016static struct regmap_config cs35l35_regmap = {
1017 .reg_bits = 8,
1018 .val_bits = 8,
1019
1020 .max_register = CS35L35_MAX_REGISTER,
1021 .reg_defaults = cs35l35_reg,
1022 .num_reg_defaults = ARRAY_SIZE(cs35l35_reg),
1023 .volatile_reg = cs35l35_volatile_register,
1024 .readable_reg = cs35l35_readable_register,
1025 .precious_reg = cs35l35_precious_register,
1026 .cache_type = REGCACHE_RBTREE,
1027};
1028
1029static irqreturn_t cs35l35_irq(int irq, void *data)
1030{
1031 struct cs35l35_private *cs35l35 = data;
1032 unsigned int sticky1, sticky2, sticky3, sticky4;
1033 unsigned int mask1, mask2, mask3, mask4, current1;
1034
1035 /* ack the irq by reading all status registers */
1036 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_4, &sticky4);
1037 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_3, &sticky3);
1038 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_2, &sticky2);
1039 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &sticky1);
1040
1041 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_4, &mask4);
1042 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_3, &mask3);
1043 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_2, &mask2);
1044 regmap_read(cs35l35->regmap, CS35L35_INT_MASK_1, &mask1);
1045
1046 /* Check to see if unmasked bits are active */
1047 if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)
1048 && !(sticky4 & ~mask4))
1049 return IRQ_NONE;
1050
1051 if (sticky2 & CS35L35_PDN_DONE)
1052 complete(&cs35l35->pdn_done);
1053
1054 /* read the current values */
1055 regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &current1);
1056
1057 /* handle the interrupts */
1058 if (sticky1 & CS35L35_CAL_ERR) {
1059 dev_crit(cs35l35->dev, "Calibration Error\n");
1060
1061 /* error is no longer asserted; safe to reset */
1062 if (!(current1 & CS35L35_CAL_ERR)) {
1063 pr_debug("%s : Cal error release\n", __func__);
1064 regmap_update_bits(cs35l35->regmap,
1065 CS35L35_PROT_RELEASE_CTL,
1066 CS35L35_CAL_ERR_RLS, 0);
1067 regmap_update_bits(cs35l35->regmap,
1068 CS35L35_PROT_RELEASE_CTL,
1069 CS35L35_CAL_ERR_RLS,
1070 CS35L35_CAL_ERR_RLS);
1071 regmap_update_bits(cs35l35->regmap,
1072 CS35L35_PROT_RELEASE_CTL,
1073 CS35L35_CAL_ERR_RLS, 0);
1074 }
1075 }
1076
1077 if (sticky1 & CS35L35_AMP_SHORT) {
1078 dev_crit(cs35l35->dev, "AMP Short Error\n");
1079 /* error is no longer asserted; safe to reset */
1080 if (!(current1 & CS35L35_AMP_SHORT)) {
1081 dev_dbg(cs35l35->dev, "Amp short error release\n");
1082 regmap_update_bits(cs35l35->regmap,
1083 CS35L35_PROT_RELEASE_CTL,
1084 CS35L35_SHORT_RLS, 0);
1085 regmap_update_bits(cs35l35->regmap,
1086 CS35L35_PROT_RELEASE_CTL,
1087 CS35L35_SHORT_RLS,
1088 CS35L35_SHORT_RLS);
1089 regmap_update_bits(cs35l35->regmap,
1090 CS35L35_PROT_RELEASE_CTL,
1091 CS35L35_SHORT_RLS, 0);
1092 }
1093 }
1094
1095 if (sticky1 & CS35L35_OTW) {
1096 dev_warn(cs35l35->dev, "Over temperature warning\n");
1097
1098 /* error is no longer asserted; safe to reset */
1099 if (!(current1 & CS35L35_OTW)) {
1100 dev_dbg(cs35l35->dev, "Over temperature warn release\n");
1101 regmap_update_bits(cs35l35->regmap,
1102 CS35L35_PROT_RELEASE_CTL,
1103 CS35L35_OTW_RLS, 0);
1104 regmap_update_bits(cs35l35->regmap,
1105 CS35L35_PROT_RELEASE_CTL,
1106 CS35L35_OTW_RLS,
1107 CS35L35_OTW_RLS);
1108 regmap_update_bits(cs35l35->regmap,
1109 CS35L35_PROT_RELEASE_CTL,
1110 CS35L35_OTW_RLS, 0);
1111 }
1112 }
1113
1114 if (sticky1 & CS35L35_OTE) {
1115 dev_crit(cs35l35->dev, "Over temperature error\n");
1116 /* error is no longer asserted; safe to reset */
1117 if (!(current1 & CS35L35_OTE)) {
1118 dev_dbg(cs35l35->dev, "Over temperature error release\n");
1119 regmap_update_bits(cs35l35->regmap,
1120 CS35L35_PROT_RELEASE_CTL,
1121 CS35L35_OTE_RLS, 0);
1122 regmap_update_bits(cs35l35->regmap,
1123 CS35L35_PROT_RELEASE_CTL,
1124 CS35L35_OTE_RLS,
1125 CS35L35_OTE_RLS);
1126 regmap_update_bits(cs35l35->regmap,
1127 CS35L35_PROT_RELEASE_CTL,
1128 CS35L35_OTE_RLS, 0);
1129 }
1130 }
1131
1132 if (sticky3 & CS35L35_BST_HIGH) {
1133 dev_crit(cs35l35->dev, "VBST error: powering off!\n");
1134 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1135 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1136 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1137 CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1138 }
1139
1140 if (sticky3 & CS35L35_LBST_SHORT) {
1141 dev_crit(cs35l35->dev, "LBST error: powering off!\n");
1142 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1143 CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1144 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1145 CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1146 }
1147
1148 if (sticky2 & CS35L35_VPBR_ERR)
1149 dev_dbg(cs35l35->dev, "Error: Reactive Brownout\n");
1150
1151 if (sticky4 & CS35L35_VMON_OVFL)
1152 dev_dbg(cs35l35->dev, "Error: VMON overflow\n");
1153
1154 if (sticky4 & CS35L35_IMON_OVFL)
1155 dev_dbg(cs35l35->dev, "Error: IMON overflow\n");
1156
1157 return IRQ_HANDLED;
1158}
1159
1160
1161static int cs35l35_handle_of_data(struct i2c_client *i2c_client,
1162 struct cs35l35_platform_data *pdata)
1163{
1164 struct device_node *np = i2c_client->dev.of_node;
1165 struct device_node *classh, *signal_format;
1166 struct classh_cfg *classh_config = &pdata->classh_algo;
1167 struct monitor_cfg *monitor_config = &pdata->mon_cfg;
1168 unsigned int val32 = 0;
1169 u8 monitor_array[4];
1170 const int imon_array_size = ARRAY_SIZE(monitor_array);
1171 const int mon_array_size = imon_array_size - 1;
1172 int ret = 0;
1173
1174 if (!np)
1175 return 0;
1176
1177 pdata->bst_pdn_fet_on = of_property_read_bool(np,
1178 "cirrus,boost-pdn-fet-on");
1179
1180 ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val32);
1181 if (ret >= 0) {
1182 if (val32 < 2600 || val32 > 9000) {
1183 dev_err(&i2c_client->dev,
1184 "Invalid Boost Voltage %d mV\n", val32);
1185 return -EINVAL;
1186 }
1187 pdata->bst_vctl = ((val32 - 2600) / 100) + 1;
1188 }
1189
1190 ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val32);
1191 if (ret >= 0) {
1192 if (val32 < 1680 || val32 > 4480) {
1193 dev_err(&i2c_client->dev,
1194 "Invalid Boost Peak Current %u mA\n", val32);
1195 return -EINVAL;
1196 }
1197
1198 pdata->bst_ipk = (val32 - 1680) / 110;
1199 }
1200
1201 if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)
1202 pdata->sp_drv_str = val32;
1203 if (of_property_read_u32(np, "cirrus,sp-drv-unused", &val32) >= 0)
1204 pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;
1205
1206 pdata->stereo = of_property_read_bool(np, "cirrus,stereo-config");
1207
1208 if (pdata->stereo) {
1209 ret = of_property_read_u32(np, "cirrus,audio-channel", &val32);
1210 if (ret >= 0)
1211 pdata->aud_channel = val32;
1212
1213 ret = of_property_read_u32(np, "cirrus,advisory-channel",
1214 &val32);
1215 if (ret >= 0)
1216 pdata->adv_channel = val32;
1217
1218 pdata->shared_bst = of_property_read_bool(np,
1219 "cirrus,shared-boost");
1220 }
1221
1222 pdata->ext_bst = of_property_read_bool(np, "cirrus,external-boost");
1223
1224 pdata->gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc");
1225
1226 classh = of_get_child_by_name(np, "cirrus,classh-internal-algo");
1227 classh_config->classh_algo_enable = classh ? true : false;
1228
1229 if (classh_config->classh_algo_enable) {
1230 classh_config->classh_bst_override =
1231 of_property_read_bool(np, "cirrus,classh-bst-overide");
1232
1233 ret = of_property_read_u32(classh,
1234 "cirrus,classh-bst-max-limit",
1235 &val32);
1236 if (ret >= 0) {
1237 val32 |= CS35L35_VALID_PDATA;
1238 classh_config->classh_bst_max_limit = val32;
1239 }
1240
1241 ret = of_property_read_u32(classh,
1242 "cirrus,classh-bst-max-limit",
1243 &val32);
1244 if (ret >= 0) {
1245 val32 |= CS35L35_VALID_PDATA;
1246 classh_config->classh_bst_max_limit = val32;
1247 }
1248
1249 ret = of_property_read_u32(classh, "cirrus,classh-mem-depth",
1250 &val32);
1251 if (ret >= 0) {
1252 val32 |= CS35L35_VALID_PDATA;
1253 classh_config->classh_mem_depth = val32;
1254 }
1255
1256 ret = of_property_read_u32(classh, "cirrus,classh-release-rate",
1257 &val32);
1258 if (ret >= 0)
1259 classh_config->classh_release_rate = val32;
1260
1261 ret = of_property_read_u32(classh, "cirrus,classh-headroom",
1262 &val32);
1263 if (ret >= 0) {
1264 val32 |= CS35L35_VALID_PDATA;
1265 classh_config->classh_headroom = val32;
1266 }
1267
1268 ret = of_property_read_u32(classh,
1269 "cirrus,classh-wk-fet-disable",
1270 &val32);
1271 if (ret >= 0)
1272 classh_config->classh_wk_fet_disable = val32;
1273
1274 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-delay",
1275 &val32);
1276 if (ret >= 0) {
1277 val32 |= CS35L35_VALID_PDATA;
1278 classh_config->classh_wk_fet_delay = val32;
1279 }
1280
1281 ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-thld",
1282 &val32);
1283 if (ret >= 0)
1284 classh_config->classh_wk_fet_thld = val32;
1285
1286 ret = of_property_read_u32(classh, "cirrus,classh-vpch-auto",
1287 &val32);
1288 if (ret >= 0) {
1289 val32 |= CS35L35_VALID_PDATA;
1290 classh_config->classh_vpch_auto = val32;
1291 }
1292
1293 ret = of_property_read_u32(classh, "cirrus,classh-vpch-rate",
1294 &val32);
1295 if (ret >= 0) {
1296 val32 |= CS35L35_VALID_PDATA;
1297 classh_config->classh_vpch_rate = val32;
1298 }
1299
1300 ret = of_property_read_u32(classh, "cirrus,classh-vpch-man",
1301 &val32);
1302 if (ret >= 0)
1303 classh_config->classh_vpch_man = val32;
1304 }
1305 of_node_put(classh);
1306
1307 /* frame depth location */
1308 signal_format = of_get_child_by_name(np, "cirrus,monitor-signal-format");
1309 monitor_config->is_present = signal_format ? true : false;
1310 if (monitor_config->is_present) {
1311 ret = of_property_read_u8_array(signal_format, "cirrus,imon",
1312 monitor_array, imon_array_size);
1313 if (!ret) {
1314 monitor_config->imon_specs = true;
1315 monitor_config->imon_dpth = monitor_array[0];
1316 monitor_config->imon_loc = monitor_array[1];
1317 monitor_config->imon_frm = monitor_array[2];
1318 monitor_config->imon_scale = monitor_array[3];
1319 }
1320 ret = of_property_read_u8_array(signal_format, "cirrus,vmon",
1321 monitor_array, mon_array_size);
1322 if (!ret) {
1323 monitor_config->vmon_specs = true;
1324 monitor_config->vmon_dpth = monitor_array[0];
1325 monitor_config->vmon_loc = monitor_array[1];
1326 monitor_config->vmon_frm = monitor_array[2];
1327 }
1328 ret = of_property_read_u8_array(signal_format, "cirrus,vpmon",
1329 monitor_array, mon_array_size);
1330 if (!ret) {
1331 monitor_config->vpmon_specs = true;
1332 monitor_config->vpmon_dpth = monitor_array[0];
1333 monitor_config->vpmon_loc = monitor_array[1];
1334 monitor_config->vpmon_frm = monitor_array[2];
1335 }
1336 ret = of_property_read_u8_array(signal_format, "cirrus,vbstmon",
1337 monitor_array, mon_array_size);
1338 if (!ret) {
1339 monitor_config->vbstmon_specs = true;
1340 monitor_config->vbstmon_dpth = monitor_array[0];
1341 monitor_config->vbstmon_loc = monitor_array[1];
1342 monitor_config->vbstmon_frm = monitor_array[2];
1343 }
1344 ret = of_property_read_u8_array(signal_format, "cirrus,vpbrstat",
1345 monitor_array, mon_array_size);
1346 if (!ret) {
1347 monitor_config->vpbrstat_specs = true;
1348 monitor_config->vpbrstat_dpth = monitor_array[0];
1349 monitor_config->vpbrstat_loc = monitor_array[1];
1350 monitor_config->vpbrstat_frm = monitor_array[2];
1351 }
1352 ret = of_property_read_u8_array(signal_format, "cirrus,zerofill",
1353 monitor_array, mon_array_size);
1354 if (!ret) {
1355 monitor_config->zerofill_specs = true;
1356 monitor_config->zerofill_dpth = monitor_array[0];
1357 monitor_config->zerofill_loc = monitor_array[1];
1358 monitor_config->zerofill_frm = monitor_array[2];
1359 }
1360 }
1361 of_node_put(signal_format);
1362
1363 return 0;
1364}
1365
1366/* Errata Rev A0 */
1367static const struct reg_sequence cs35l35_errata_patch[] = {
1368
1369 { 0x7F, 0x99 },
1370 { 0x00, 0x99 },
1371 { 0x52, 0x22 },
1372 { 0x04, 0x14 },
1373 { 0x6D, 0x44 },
1374 { 0x24, 0x10 },
1375 { 0x58, 0xC4 },
1376 { 0x00, 0x98 },
1377 { 0x18, 0x08 },
1378 { 0x00, 0x00 },
1379 { 0x7F, 0x00 },
1380};
1381
1382static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
1383 const struct i2c_device_id *id)
1384{
1385 struct cs35l35_private *cs35l35;
1386 struct device *dev = &i2c_client->dev;
1387 struct cs35l35_platform_data *pdata = dev_get_platdata(dev);
1388 int i;
1389 int ret;
1390 unsigned int devid = 0;
1391 unsigned int reg;
1392
1393 cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);
1394 if (!cs35l35)
1395 return -ENOMEM;
1396
1397 cs35l35->dev = dev;
1398
1399 i2c_set_clientdata(i2c_client, cs35l35);
1400 cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);
1401 if (IS_ERR(cs35l35->regmap)) {
1402 ret = PTR_ERR(cs35l35->regmap);
1403 dev_err(dev, "regmap_init() failed: %d\n", ret);
1404 goto err;
1405 }
1406
1407 for (i = 0; i < ARRAY_SIZE(cs35l35_supplies); i++)
1408 cs35l35->supplies[i].supply = cs35l35_supplies[i];
1409
1410 cs35l35->num_supplies = ARRAY_SIZE(cs35l35_supplies);
1411
1412 ret = devm_regulator_bulk_get(dev, cs35l35->num_supplies,
1413 cs35l35->supplies);
1414 if (ret != 0) {
1415 dev_err(dev, "Failed to request core supplies: %d\n", ret);
1416 return ret;
1417 }
1418
1419 if (pdata) {
1420 cs35l35->pdata = *pdata;
1421 } else {
1422 pdata = devm_kzalloc(dev, sizeof(struct cs35l35_platform_data),
1423 GFP_KERNEL);
1424 if (!pdata)
1425 return -ENOMEM;
1426 if (i2c_client->dev.of_node) {
1427 ret = cs35l35_handle_of_data(i2c_client, pdata);
1428 if (ret != 0)
1429 return ret;
1430
1431 }
1432 cs35l35->pdata = *pdata;
1433 }
1434
1435 ret = regulator_bulk_enable(cs35l35->num_supplies,
1436 cs35l35->supplies);
1437 if (ret != 0) {
1438 dev_err(dev, "Failed to enable core supplies: %d\n", ret);
1439 return ret;
1440 }
1441
1442 /* returning NULL can be valid if in stereo mode */
1443 cs35l35->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1444 GPIOD_OUT_LOW);
1445 if (IS_ERR(cs35l35->reset_gpio)) {
1446 ret = PTR_ERR(cs35l35->reset_gpio);
1447 cs35l35->reset_gpio = NULL;
1448 if (ret == -EBUSY) {
1449 dev_info(dev,
1450 "Reset line busy, assuming shared reset\n");
1451 } else {
1452 dev_err(dev, "Failed to get reset GPIO: %d\n", ret);
1453 goto err;
1454 }
1455 }
1456
1457 gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);
1458
1459 init_completion(&cs35l35->pdn_done);
1460
1461 ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l35_irq,
1462 IRQF_ONESHOT | IRQF_TRIGGER_LOW |
1463 IRQF_SHARED, "cs35l35", cs35l35);
1464 if (ret != 0) {
1465 dev_err(dev, "Failed to request IRQ: %d\n", ret);
1466 goto err;
1467 }
1468 /* initialize codec */
1469 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_AB, &reg);
1470
1471 devid = (reg & 0xFF) << 12;
1472 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_CD, &reg);
1473 devid |= (reg & 0xFF) << 4;
1474 ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_E, &reg);
1475 devid |= (reg & 0xF0) >> 4;
1476
1477 if (devid != CS35L35_CHIP_ID) {
1478 dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",
1479 devid, CS35L35_CHIP_ID);
1480 ret = -ENODEV;
1481 goto err;
1482 }
1483
1484 ret = regmap_read(cs35l35->regmap, CS35L35_REV_ID, &reg);
1485 if (ret < 0) {
1486 dev_err(dev, "Get Revision ID failed: %d\n", ret);
1487 goto err;
1488 }
1489
1490 ret = regmap_register_patch(cs35l35->regmap, cs35l35_errata_patch,
1491 ARRAY_SIZE(cs35l35_errata_patch));
1492 if (ret < 0) {
1493 dev_err(dev, "Failed to apply errata patch: %d\n", ret);
1494 goto err;
1495 }
1496
1497 dev_info(dev, "Cirrus Logic CS35L35 (%x), Revision: %02X\n",
1498 devid, reg & 0xFF);
1499
1500 /* Set the INT Masks for critical errors */
1501 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_1,
1502 CS35L35_INT1_CRIT_MASK);
1503 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_2,
1504 CS35L35_INT2_CRIT_MASK);
1505 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_3,
1506 CS35L35_INT3_CRIT_MASK);
1507 regmap_write(cs35l35->regmap, CS35L35_INT_MASK_4,
1508 CS35L35_INT4_CRIT_MASK);
1509
1510 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1511 CS35L35_PWR2_PDN_MASK,
1512 CS35L35_PWR2_PDN_MASK);
1513
1514 if (cs35l35->pdata.bst_pdn_fet_on)
1515 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1516 CS35L35_PDN_BST_MASK,
1517 1 << CS35L35_PDN_BST_FETON_SHIFT);
1518 else
1519 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1520 CS35L35_PDN_BST_MASK,
1521 1 << CS35L35_PDN_BST_FETOFF_SHIFT);
1522
1523 regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL3,
1524 CS35L35_PWR3_PDN_MASK,
1525 CS35L35_PWR3_PDN_MASK);
1526
1527 regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
1528 CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
1529
1530 ret = snd_soc_register_codec(dev, &soc_codec_dev_cs35l35, cs35l35_dai,
1531 ARRAY_SIZE(cs35l35_dai));
1532 if (ret < 0) {
1533 dev_err(dev, "Failed to register codec: %d\n", ret);
1534 goto err;
1535 }
1536
1537 return 0;
1538
1539err:
1540 regulator_bulk_disable(cs35l35->num_supplies,
1541 cs35l35->supplies);
1542 gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
1543
1544 return ret;
1545}
1546
1547static int cs35l35_i2c_remove(struct i2c_client *client)
1548{
1549 snd_soc_unregister_codec(&client->dev);
1550 return 0;
1551}
1552
1553static const struct of_device_id cs35l35_of_match[] = {
1554 {.compatible = "cirrus,cs35l35"},
1555 {},
1556};
1557MODULE_DEVICE_TABLE(of, cs35l35_of_match);
1558
1559static const struct i2c_device_id cs35l35_id[] = {
1560 {"cs35l35", 0},
1561 {}
1562};
1563
1564MODULE_DEVICE_TABLE(i2c, cs35l35_id);
1565
1566static struct i2c_driver cs35l35_i2c_driver = {
1567 .driver = {
1568 .name = "cs35l35",
1569 .of_match_table = cs35l35_of_match,
1570 },
1571 .id_table = cs35l35_id,
1572 .probe = cs35l35_i2c_probe,
1573 .remove = cs35l35_i2c_remove,
1574};
1575
1576module_i2c_driver(cs35l35_i2c_driver);
1577
1578MODULE_DESCRIPTION("ASoC CS35L35 driver");
1579MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1580MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs35l35.h b/sound/soc/codecs/cs35l35.h
new file mode 100644
index 000000000000..5a6e43a87c4d
--- /dev/null
+++ b/sound/soc/codecs/cs35l35.h
@@ -0,0 +1,294 @@
1/*
2 * cs35l35.h -- CS35L35 ALSA SoC audio driver
3 *
4 * Copyright 2016 Cirrus Logic, Inc.
5 *
6 * Author: Brian Austin <brian.austin@cirrus.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
14#ifndef __CS35L35_H__
15#define __CS35L35_H__
16
17#define CS35L35_FIRSTREG 0x01
18#define CS35L35_LASTREG 0x7E
19#define CS35L35_CHIP_ID 0x00035A35
20#define CS35L35_DEVID_AB 0x01 /* Device ID A & B [RO] */
21#define CS35L35_DEVID_CD 0x02 /* Device ID C & D [RO] */
22#define CS35L35_DEVID_E 0x03 /* Device ID E [RO] */
23#define CS35L35_FAB_ID 0x04 /* Fab ID [RO] */
24#define CS35L35_REV_ID 0x05 /* Revision ID [RO] */
25#define CS35L35_PWRCTL1 0x06 /* Power Ctl 1 */
26#define CS35L35_PWRCTL2 0x07 /* Power Ctl 2 */
27#define CS35L35_PWRCTL3 0x08 /* Power Ctl 3 */
28#define CS35L35_CLK_CTL1 0x0A /* Clocking Ctl 1 */
29#define CS35L35_CLK_CTL2 0x0B /* Clocking Ctl 2 */
30#define CS35L35_CLK_CTL3 0x0C /* Clocking Ctl 3 */
31#define CS35L35_SP_FMT_CTL1 0x0D /* Serial Port Format CTL1 */
32#define CS35L35_SP_FMT_CTL2 0x0E /* Serial Port Format CTL2 */
33#define CS35L35_SP_FMT_CTL3 0x0F /* Serial Port Format CTL3 */
34#define CS35L35_MAG_COMP_CTL 0x13 /* Magnitude Comp CTL */
35#define CS35L35_AMP_INP_DRV_CTL 0x14 /* Amp Input Drive Ctl */
36#define CS35L35_AMP_DIG_VOL_CTL 0x15 /* Amplifier Dig Volume Ctl */
37#define CS35L35_AMP_DIG_VOL 0x16 /* Amplifier Dig Volume */
38#define CS35L35_ADV_DIG_VOL 0x17 /* Advisory Digital Volume */
39#define CS35L35_PROTECT_CTL 0x18 /* Amp Gain - Prot Ctl Param */
40#define CS35L35_AMP_GAIN_AUD_CTL 0x19 /* Amp Serial Port Gain Ctl */
41#define CS35L35_AMP_GAIN_PDM_CTL 0x1A /* Amplifier Gain PDM Ctl */
42#define CS35L35_AMP_GAIN_ADV_CTL 0x1B /* Amplifier Gain Ctl */
43#define CS35L35_GPI_CTL 0x1C /* GPI Ctl */
44#define CS35L35_BST_CVTR_V_CTL 0x1D /* Boost Conv Voltage Ctl */
45#define CS35L35_BST_PEAK_I 0x1E /* Boost Conv Peak Current */
46#define CS35L35_BST_RAMP_CTL 0x20 /* Boost Conv Soft Ramp Ctl */
47#define CS35L35_BST_CONV_COEF_1 0x21 /* Boost Conv Coefficients 1 */
48#define CS35L35_BST_CONV_COEF_2 0x22 /* Boost Conv Coefficients 2 */
49#define CS35L35_BST_CONV_SLOPE_COMP 0x23 /* Boost Conv Slope Comp */
50#define CS35L35_BST_CONV_SW_FREQ 0x24 /* Boost Conv L BST SW Freq */
51#define CS35L35_CLASS_H_CTL 0x30 /* CLS H Control */
52#define CS35L35_CLASS_H_HEADRM_CTL 0x31 /* CLS H Headroom Ctl */
53#define CS35L35_CLASS_H_RELEASE_RATE 0x32 /* CLS H Release Rate */
54#define CS35L35_CLASS_H_FET_DRIVE_CTL 0x33 /* CLS H Weak FET Drive Ctl */
55#define CS35L35_CLASS_H_VP_CTL 0x34 /* CLS H VP Ctl */
56#define CS35L35_CLASS_H_STATUS 0x38 /* CLS H Status */
57#define CS35L35_VPBR_CTL 0x3A /* VPBR Ctl */
58#define CS35L35_VPBR_VOL_CTL 0x3B /* VPBR Volume Ctl */
59#define CS35L35_VPBR_TIMING_CTL 0x3C /* VPBR Timing Ctl */
60#define CS35L35_VPBR_MODE_VOL_CTL 0x3D /* VPBR Mode/Attack Vol Ctl */
61#define CS35L35_VPBR_ATTEN_STATUS 0x4B /* VPBR Attenuation Status */
62#define CS35L35_SPKR_MON_CTL 0x4E /* Speaker Monitoring Ctl */
63#define CS35L35_IMON_SCALE_CTL 0x51 /* IMON Scale Ctl */
64#define CS35L35_AUDIN_RXLOC_CTL 0x52 /* Audio Input RX Loc Ctl */
65#define CS35L35_ADVIN_RXLOC_CTL 0x53 /* Advisory Input RX Loc Ctl */
66#define CS35L35_VMON_TXLOC_CTL 0x54 /* VMON TX Loc Ctl */
67#define CS35L35_IMON_TXLOC_CTL 0x55 /* IMON TX Loc Ctl */
68#define CS35L35_VPMON_TXLOC_CTL 0x56 /* VPMON TX Loc Ctl */
69#define CS35L35_VBSTMON_TXLOC_CTL 0x57 /* VBSTMON TX Loc Ctl */
70#define CS35L35_VPBR_STATUS_TXLOC_CTL 0x58 /* VPBR Status TX Loc Ctl */
71#define CS35L35_ZERO_FILL_LOC_CTL 0x59 /* Zero Fill Loc Ctl */
72#define CS35L35_AUDIN_DEPTH_CTL 0x5A /* Audio Input Depth Ctl */
73#define CS35L35_SPKMON_DEPTH_CTL 0x5B /* SPK Mon Output Depth Ctl */
74#define CS35L35_SUPMON_DEPTH_CTL 0x5C /* Supply Mon Out Depth Ctl */
75#define CS35L35_ZEROFILL_DEPTH_CTL 0x5D /* Zero Fill Mon Output Ctl */
76#define CS35L35_MULT_DEV_SYNCH1 0x62 /* Multidevice Synch */
77#define CS35L35_MULT_DEV_SYNCH2 0x63 /* Multidevice Synch 2 */
78#define CS35L35_PROT_RELEASE_CTL 0x64 /* Protection Release Ctl */
79#define CS35L35_DIAG_MODE_REG_LOCK 0x68 /* Diagnostic Mode Reg Lock */
80#define CS35L35_DIAG_MODE_CTL_1 0x69 /* Diagnostic Mode Ctl 1 */
81#define CS35L35_DIAG_MODE_CTL_2 0x6A /* Diagnostic Mode Ctl 2 */
82#define CS35L35_INT_MASK_1 0x70 /* Interrupt Mask 1 */
83#define CS35L35_INT_MASK_2 0x71 /* Interrupt Mask 2 */
84#define CS35L35_INT_MASK_3 0x72 /* Interrupt Mask 3 */
85#define CS35L35_INT_MASK_4 0x73 /* Interrupt Mask 4 */
86#define CS35L35_INT_STATUS_1 0x74 /* Interrupt Status 1 */
87#define CS35L35_INT_STATUS_2 0x75 /* Interrupt Status 2 */
88#define CS35L35_INT_STATUS_3 0x76 /* Interrupt Status 3 */
89#define CS35L35_INT_STATUS_4 0x77 /* Interrupt Status 4 */
90#define CS35L35_PLL_STATUS 0x78 /* PLL Status */
91#define CS35L35_OTP_TRIM_STATUS 0x7E /* OTP Trim Status */
92
93#define CS35L35_MAX_REGISTER 0x7F
94
95/* CS35L35_PWRCTL1 */
96#define CS35L35_SFT_RST 0x80
97#define CS35L35_DISCHG_FLT 0x02
98#define CS35L35_PDN_ALL 0x01
99
100/* CS35L35_PWRCTL2 */
101#define CS35L35_PDN_VMON 0x80
102#define CS35L35_PDN_IMON 0x40
103#define CS35L35_PDN_CLASSH 0x20
104#define CS35L35_PDN_VPBR 0x10
105#define CS35L35_PDN_BST 0x04
106#define CS35L35_PDN_AMP 0x01
107
108/* CS35L35_PWRCTL3 */
109#define CS35L35_PDN_VBSTMON_OUT 0x10
110#define CS35L35_PDN_VMON_OUT 0x08
111
112#define CS35L35_AUDIN_DEPTH_MASK 0x03
113#define CS35L35_AUDIN_DEPTH_SHIFT 0
114#define CS35L35_ADVIN_DEPTH_MASK 0x0C
115#define CS35L35_ADVIN_DEPTH_SHIFT 2
116#define CS35L35_SDIN_DEPTH_8 0x01
117#define CS35L35_SDIN_DEPTH_16 0x02
118#define CS35L35_SDIN_DEPTH_24 0x03
119
120#define CS35L35_SDOUT_DEPTH_8 0x01
121#define CS35L35_SDOUT_DEPTH_12 0x02
122#define CS35L35_SDOUT_DEPTH_16 0x03
123
124#define CS35L35_AUD_IN_LR_MASK 0x80
125#define CS35L35_AUD_IN_LR_SHIFT 7
126#define CS35L35_ADV_IN_LR_MASK 0x80
127#define CS35L35_ADV_IN_LR_SHIFT 7
128#define CS35L35_AUD_IN_LOC_MASK 0x0F
129#define CS35L35_AUD_IN_LOC_SHIFT 0
130#define CS35L35_ADV_IN_LOC_MASK 0x0F
131#define CS35L35_ADV_IN_LOC_SHIFT 0
132
133#define CS35L35_IMON_DEPTH_MASK 0x03
134#define CS35L35_IMON_DEPTH_SHIFT 0
135#define CS35L35_VMON_DEPTH_MASK 0x0C
136#define CS35L35_VMON_DEPTH_SHIFT 2
137#define CS35L35_VBSTMON_DEPTH_MASK 0x03
138#define CS35L35_VBSTMON_DEPTH_SHIFT 0
139#define CS35L35_VPMON_DEPTH_MASK 0x0C
140#define CS35L35_VPMON_DEPTH_SHIFT 2
141#define CS35L35_VPBRSTAT_DEPTH_MASK 0x30
142#define CS35L35_VPBRSTAT_DEPTH_SHIFT 4
143#define CS35L35_ZEROFILL_DEPTH_MASK 0x03
144#define CS35L35_ZEROFILL_DEPTH_SHIFT 0x00
145
146#define CS35L35_MON_TXLOC_MASK 0x3F
147#define CS35L35_MON_TXLOC_SHIFT 0
148#define CS35L35_MON_FRM_MASK 0x80
149#define CS35L35_MON_FRM_SHIFT 7
150
151#define CS35L35_IMON_SCALE_MASK 0xF8
152#define CS35L35_IMON_SCALE_SHIFT 3
153
154#define CS35L35_MS_MASK 0x80
155#define CS35L35_MS_SHIFT 7
156#define CS35L35_SPMODE_MASK 0x40
157#define CS35L35_SP_DRV_MASK 0x10
158#define CS35L35_SP_DRV_SHIFT 4
159#define CS35L35_CLK_CTL2_MASK 0xFF
160#define CS35L35_PDM_MODE_MASK 0x40
161#define CS35L35_PDM_MODE_SHIFT 6
162#define CS35L35_CLK_SOURCE_MASK 0x03
163#define CS35L35_CLK_SOURCE_SHIFT 0
164#define CS35L35_CLK_SOURCE_MCLK 0
165#define CS35L35_CLK_SOURCE_SCLK 1
166#define CS35L35_CLK_SOURCE_PDM 2
167
168#define CS35L35_SP_SCLKS_MASK 0x0F
169#define CS35L35_SP_SCLKS_SHIFT 0x00
170#define CS35L35_SP_SCLKS_16FS 0x03
171#define CS35L35_SP_SCLKS_32FS 0x07
172#define CS35L35_SP_SCLKS_48FS 0x0B
173#define CS35L35_SP_SCLKS_64FS 0x0F
174#define CS35L35_SP_RATE_MASK 0xC0
175
176#define CS35L35_PDN_BST_MASK 0x06
177#define CS35L35_PDN_BST_FETON_SHIFT 1
178#define CS35L35_PDN_BST_FETOFF_SHIFT 2
179#define CS35L35_PWR2_PDN_MASK 0xE0
180#define CS35L35_PWR3_PDN_MASK 0x1E
181#define CS35L35_PDN_ALL_MASK 0x01
182#define CS35L35_DISCHG_FILT_MASK 0x02
183#define CS35L35_DISCHG_FILT_SHIFT 1
184#define CS35L35_MCLK_DIS_MASK 0x04
185#define CS35L35_MCLK_DIS_SHIFT 2
186
187#define CS35L35_BST_CTL_MASK 0x7F
188#define CS35L35_BST_CTL_SHIFT 0
189#define CS35L35_BST_IPK_MASK 0x1F
190#define CS35L35_BST_IPK_SHIFT 0
191#define CS35L35_AMP_MUTE_MASK 0x20
192#define CS35L35_AMP_MUTE_SHIFT 5
193#define CS35L35_AMP_GAIN_ZC_MASK 0x10
194#define CS35L35_AMP_GAIN_ZC_SHIFT 4
195
196#define CS35L35_AMP_DIGSFT_MASK 0x02
197#define CS35L35_AMP_DIGSFT_SHIFT 1
198
199/* CS35L35_SP_FMT_CTL3 */
200#define CS35L35_SP_I2S_DRV_MASK 0x03
201#define CS35L35_SP_I2S_DRV_SHIFT 0
202
203/* Class H Algorithm Control */
204#define CS35L35_CH_STEREO_MASK 0x40
205#define CS35L35_CH_STEREO_SHIFT 6
206#define CS35L35_CH_BST_OVR_MASK 0x04
207#define CS35L35_CH_BST_OVR_SHIFT 2
208#define CS35L35_CH_BST_LIM_MASK 0x08
209#define CS35L35_CH_BST_LIM_SHIFT 3
210#define CS35L35_CH_MEM_DEPTH_MASK 0x01
211#define CS35L35_CH_MEM_DEPTH_SHIFT 0
212#define CS35L35_CH_HDRM_CTL_MASK 0x3F
213#define CS35L35_CH_HDRM_CTL_SHIFT 0
214#define CS35L35_CH_REL_RATE_MASK 0xFF
215#define CS35L35_CH_REL_RATE_SHIFT 0
216#define CS35L35_CH_WKFET_DIS_MASK 0x80
217#define CS35L35_CH_WKFET_DIS_SHIFT 7
218#define CS35L35_CH_WKFET_DEL_MASK 0x70
219#define CS35L35_CH_WKFET_DEL_SHIFT 4
220#define CS35L35_CH_WKFET_THLD_MASK 0x0F
221#define CS35L35_CH_WKFET_THLD_SHIFT 0
222#define CS35L35_CH_VP_AUTO_MASK 0x80
223#define CS35L35_CH_VP_AUTO_SHIFT 7
224#define CS35L35_CH_VP_RATE_MASK 0x60
225#define CS35L35_CH_VP_RATE_SHIFT 5
226#define CS35L35_CH_VP_MAN_MASK 0x1F
227#define CS35L35_CH_VP_MAN_SHIFT 0
228
229/* CS35L35_PROT_RELEASE_CTL */
230#define CS35L35_CAL_ERR_RLS 0x80
231#define CS35L35_SHORT_RLS 0x04
232#define CS35L35_OTW_RLS 0x02
233#define CS35L35_OTE_RLS 0x01
234
235/* INT Mask Registers */
236#define CS35L35_INT1_CRIT_MASK 0x38
237#define CS35L35_INT2_CRIT_MASK 0xEF
238#define CS35L35_INT3_CRIT_MASK 0xEE
239#define CS35L35_INT4_CRIT_MASK 0xFF
240
241/* PDN DONE Masks */
242#define CS35L35_M_PDN_DONE_SHIFT 4
243#define CS35L35_M_PDN_DONE_MASK 0x10
244
245/* CS35L35_INT_1 */
246#define CS35L35_CAL_ERR 0x80
247#define CS35L35_OTP_ERR 0x40
248#define CS35L35_LRCLK_ERR 0x20
249#define CS35L35_SPCLK_ERR 0x10
250#define CS35L35_MCLK_ERR 0x08
251#define CS35L35_AMP_SHORT 0x04
252#define CS35L35_OTW 0x02
253#define CS35L35_OTE 0x01
254
255/* CS35L35_INT_2 */
256#define CS35L35_PDN_DONE 0x10
257#define CS35L35_VPBR_ERR 0x02
258#define CS35L35_VPBR_CLR 0x01
259
260/* CS35L35_INT_3 */
261#define CS35L35_BST_HIGH 0x10
262#define CS35L35_BST_HIGH_FLAG 0x08
263#define CS35L35_BST_IPK_FLAG 0x04
264#define CS35L35_LBST_SHORT 0x01
265
266/* CS35L35_INT_4 */
267#define CS35L35_VMON_OVFL 0x08
268#define CS35L35_IMON_OVFL 0x04
269
270#define CS35L35_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | \
271 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
272
273struct cs35l35_private {
274 struct device *dev;
275 struct cs35l35_platform_data pdata;
276 struct regmap *regmap;
277 struct regulator_bulk_data supplies[2];
278 int num_supplies;
279 int sysclk;
280 int sclk;
281 bool pdm_mode;
282 bool i2s_mode;
283 bool slave_mode;
284 /* GPIO for /RST */
285 struct gpio_desc *reset_gpio;
286 struct completion pdn_done;
287};
288
289static const char * const cs35l35_supplies[] = {
290 "VA",
291 "VP",
292};
293
294#endif
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 8c0f3b89b5bc..e78b5f055f25 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -498,7 +498,7 @@ static int cs4271_reset(struct snd_soc_codec *codec)
498 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 498 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
499 499
500 if (gpio_is_valid(cs4271->gpio_nreset)) { 500 if (gpio_is_valid(cs4271->gpio_nreset)) {
501 gpio_set_value(cs4271->gpio_nreset, 0); 501 gpio_direction_output(cs4271->gpio_nreset, 0);
502 mdelay(1); 502 mdelay(1);
503 gpio_set_value(cs4271->gpio_nreset, 1); 503 gpio_set_value(cs4271->gpio_nreset, 1);
504 mdelay(1); 504 mdelay(1);
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index cb47fb595ff4..1e0d5973b758 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -1130,6 +1130,7 @@ MODULE_DEVICE_TABLE(i2c, cs53l30_id);
1130static struct i2c_driver cs53l30_i2c_driver = { 1130static struct i2c_driver cs53l30_i2c_driver = {
1131 .driver = { 1131 .driver = {
1132 .name = "cs53l30", 1132 .name = "cs53l30",
1133 .of_match_table = cs53l30_of_match,
1133 .pm = &cs53l30_runtime_pm, 1134 .pm = &cs53l30_runtime_pm,
1134 }, 1135 },
1135 .id_table = cs53l30_id, 1136 .id_table = cs53l30_id,
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 12da55882c06..6dd7578f0bb8 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -12,6 +12,7 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/acpi.h>
15#include <linux/clk.h> 16#include <linux/clk.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/i2c.h> 18#include <linux/i2c.h>
@@ -1528,12 +1529,23 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1528 return 0; 1529 return 0;
1529} 1530}
1530 1531
1532#if defined(CONFIG_OF)
1531/* DT */ 1533/* DT */
1532static const struct of_device_id da7213_of_match[] = { 1534static const struct of_device_id da7213_of_match[] = {
1533 { .compatible = "dlg,da7213", }, 1535 { .compatible = "dlg,da7213", },
1534 { } 1536 { }
1535}; 1537};
1536MODULE_DEVICE_TABLE(of, da7213_of_match); 1538MODULE_DEVICE_TABLE(of, da7213_of_match);
1539#endif
1540
1541#ifdef CONFIG_ACPI
1542static const struct acpi_device_id da7213_acpi_match[] = {
1543 { "DLGS7212", 0},
1544 { "DLGS7213", 0},
1545 { },
1546};
1547MODULE_DEVICE_TABLE(acpi, da7213_acpi_match);
1548#endif
1537 1549
1538static enum da7213_micbias_voltage 1550static enum da7213_micbias_voltage
1539 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val) 1551 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
@@ -1844,6 +1856,7 @@ static struct i2c_driver da7213_i2c_driver = {
1844 .driver = { 1856 .driver = {
1845 .name = "da7213", 1857 .name = "da7213",
1846 .of_match_table = of_match_ptr(da7213_of_match), 1858 .of_match_table = of_match_ptr(da7213_of_match),
1859 .acpi_match_table = ACPI_PTR(da7213_acpi_match),
1847 }, 1860 },
1848 .probe = da7213_i2c_probe, 1861 .probe = da7213_i2c_probe,
1849 .remove = da7213_remove, 1862 .remove = da7213_remove,
diff --git a/sound/soc/codecs/dio2125.c b/sound/soc/codecs/dio2125.c
new file mode 100644
index 000000000000..09451cd44f9b
--- /dev/null
+++ b/sound/soc/codecs/dio2125.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Jerome Brunet <jbrunet@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * The full GNU General Public License is included in this distribution
17 * in the file called COPYING.
18 */
19
20#include <linux/gpio/consumer.h>
21#include <linux/module.h>
22#include <sound/soc.h>
23
24#define DRV_NAME "dio2125"
25
26struct dio2125 {
27 struct gpio_desc *gpiod_enable;
28};
29
30static int drv_event(struct snd_soc_dapm_widget *w,
31 struct snd_kcontrol *control, int event)
32{
33 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
34 struct dio2125 *priv = snd_soc_component_get_drvdata(c);
35 int val;
36
37 switch (event) {
38 case SND_SOC_DAPM_POST_PMU:
39 val = 1;
40 break;
41 case SND_SOC_DAPM_PRE_PMD:
42 val = 0;
43 break;
44 default:
45 WARN(1, "Unexpected event");
46 return -EINVAL;
47 }
48
49 gpiod_set_value_cansleep(priv->gpiod_enable, val);
50
51 return 0;
52}
53
54static const struct snd_soc_dapm_widget dio2125_dapm_widgets[] = {
55 SND_SOC_DAPM_INPUT("INL"),
56 SND_SOC_DAPM_INPUT("INR"),
57 SND_SOC_DAPM_OUT_DRV_E("DRV", SND_SOC_NOPM, 0, 0, NULL, 0, drv_event,
58 (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
59 SND_SOC_DAPM_OUTPUT("OUTL"),
60 SND_SOC_DAPM_OUTPUT("OUTR"),
61};
62
63static const struct snd_soc_dapm_route dio2125_dapm_routes[] = {
64 { "DRV", NULL, "INL" },
65 { "DRV", NULL, "INR" },
66 { "OUTL", NULL, "DRV" },
67 { "OUTR", NULL, "DRV" },
68};
69
70static const struct snd_soc_component_driver dio2125_component_driver = {
71 .dapm_widgets = dio2125_dapm_widgets,
72 .num_dapm_widgets = ARRAY_SIZE(dio2125_dapm_widgets),
73 .dapm_routes = dio2125_dapm_routes,
74 .num_dapm_routes = ARRAY_SIZE(dio2125_dapm_routes),
75};
76
77static int dio2125_probe(struct platform_device *pdev)
78{
79 struct device *dev = &pdev->dev;
80 struct dio2125 *priv;
81 int err;
82
83 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
84 if (priv == NULL)
85 return -ENOMEM;
86 platform_set_drvdata(pdev, priv);
87
88 priv->gpiod_enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
89 if (IS_ERR(priv->gpiod_enable)) {
90 err = PTR_ERR(priv->gpiod_enable);
91 if (err != -EPROBE_DEFER)
92 dev_err(dev, "Failed to get 'enable' gpio: %d", err);
93 return err;
94 }
95
96 return devm_snd_soc_register_component(dev, &dio2125_component_driver,
97 NULL, 0);
98}
99
100#ifdef CONFIG_OF
101static const struct of_device_id dio2125_ids[] = {
102 { .compatible = "dioo,dio2125", },
103 { }
104};
105MODULE_DEVICE_TABLE(of, dio2125_ids);
106#endif
107
108static struct platform_driver dio2125_driver = {
109 .driver = {
110 .name = DRV_NAME,
111 .of_match_table = of_match_ptr(dio2125_ids),
112 },
113 .probe = dio2125_probe,
114};
115
116module_platform_driver(dio2125_driver);
117
118MODULE_DESCRIPTION("ASoC DIO2125 output driver");
119MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
120MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c
new file mode 100644
index 000000000000..25ede825d349
--- /dev/null
+++ b/sound/soc/codecs/es7134.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) 2017 BayLibre, SAS.
3 * Author: Jerome Brunet <jbrunet@baylibre.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 * The full GNU General Public License is included in this distribution
17 * in the file called COPYING.
18 */
19
20#include <linux/module.h>
21#include <sound/soc.h>
22
23/*
24 * The everest 7134 is a very simple DA converter with no register
25 */
26
27static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
28{
29 fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK |
30 SND_SOC_DAIFMT_MASTER_MASK);
31
32 if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
33 SND_SOC_DAIFMT_CBS_CFS)) {
34 dev_err(codec_dai->dev, "Invalid DAI format\n");
35 return -EINVAL;
36 }
37
38 return 0;
39}
40
41static const struct snd_soc_dai_ops es7134_dai_ops = {
42 .set_fmt = es7134_set_fmt,
43};
44
45static struct snd_soc_dai_driver es7134_dai = {
46 .name = "es7134-hifi",
47 .playback = {
48 .stream_name = "Playback",
49 .channels_min = 2,
50 .channels_max = 2,
51 .rates = SNDRV_PCM_RATE_8000_192000,
52 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
53 SNDRV_PCM_FMTBIT_S18_3LE |
54 SNDRV_PCM_FMTBIT_S20_3LE |
55 SNDRV_PCM_FMTBIT_S24_3LE |
56 SNDRV_PCM_FMTBIT_S24_LE),
57 },
58 .ops = &es7134_dai_ops,
59};
60
61static const struct snd_soc_dapm_widget es7134_dapm_widgets[] = {
62 SND_SOC_DAPM_OUTPUT("AOUTL"),
63 SND_SOC_DAPM_OUTPUT("AOUTR"),
64 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
65};
66
67static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
68 { "AOUTL", NULL, "DAC" },
69 { "AOUTR", NULL, "DAC" },
70};
71
72static struct snd_soc_codec_driver es7134_codec_driver = {
73 .component_driver = {
74 .dapm_widgets = es7134_dapm_widgets,
75 .num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets),
76 .dapm_routes = es7134_dapm_routes,
77 .num_dapm_routes = ARRAY_SIZE(es7134_dapm_routes),
78 },
79};
80
81static int es7134_probe(struct platform_device *pdev)
82{
83 return snd_soc_register_codec(&pdev->dev,
84 &es7134_codec_driver,
85 &es7134_dai, 1);
86}
87
88static int es7134_remove(struct platform_device *pdev)
89{
90 snd_soc_unregister_codec(&pdev->dev);
91 return 0;
92}
93
94#ifdef CONFIG_OF
95static const struct of_device_id es7134_ids[] = {
96 { .compatible = "everest,es7134", },
97 { .compatible = "everest,es7144", },
98 { }
99};
100MODULE_DEVICE_TABLE(of, es7134_ids);
101#endif
102
103static struct platform_driver es7134_driver = {
104 .driver = {
105 .name = "es7134",
106 .of_match_table = of_match_ptr(es7134_ids),
107 },
108 .probe = es7134_probe,
109 .remove = es7134_remove,
110};
111
112module_platform_driver(es7134_driver);
113
114MODULE_DESCRIPTION("ASoC ES7134 audio codec driver");
115MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
116MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 3f84fbd071e2..ed7cc42d1ee2 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -69,14 +69,10 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = {
69 "HPVDD", 69 "HPVDD",
70}; 70};
71 71
72#define ES8328_RATES (SNDRV_PCM_RATE_96000 | \ 72#define ES8328_RATES (SNDRV_PCM_RATE_192000 | \
73 SNDRV_PCM_RATE_48000 | \ 73 SNDRV_PCM_RATE_96000 | \
74 SNDRV_PCM_RATE_44100 | \ 74 SNDRV_PCM_RATE_88200 | \
75 SNDRV_PCM_RATE_32000 | \ 75 SNDRV_PCM_RATE_8000_48000)
76 SNDRV_PCM_RATE_22050 | \
77 SNDRV_PCM_RATE_16000 | \
78 SNDRV_PCM_RATE_11025 | \
79 SNDRV_PCM_RATE_8000)
80#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 76#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
81 SNDRV_PCM_FMTBIT_S18_3LE | \ 77 SNDRV_PCM_FMTBIT_S18_3LE | \
82 SNDRV_PCM_FMTBIT_S20_3LE | \ 78 SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -91,6 +87,7 @@ struct es8328_priv {
91 int mclkdiv2; 87 int mclkdiv2;
92 const struct snd_pcm_hw_constraint_list *sysclk_constraints; 88 const struct snd_pcm_hw_constraint_list *sysclk_constraints;
93 const int *mclk_ratios; 89 const int *mclk_ratios;
90 bool master;
94 struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; 91 struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM];
95}; 92};
96 93
@@ -469,7 +466,7 @@ static int es8328_startup(struct snd_pcm_substream *substream,
469 struct snd_soc_codec *codec = dai->codec; 466 struct snd_soc_codec *codec = dai->codec;
470 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 467 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
471 468
472 if (es8328->sysclk_constraints) 469 if (es8328->master && es8328->sysclk_constraints)
473 snd_pcm_hw_constraint_list(substream->runtime, 0, 470 snd_pcm_hw_constraint_list(substream->runtime, 0,
474 SNDRV_PCM_HW_PARAM_RATE, 471 SNDRV_PCM_HW_PARAM_RATE,
475 es8328->sysclk_constraints); 472 es8328->sysclk_constraints);
@@ -488,27 +485,34 @@ static int es8328_hw_params(struct snd_pcm_substream *substream,
488 int wl; 485 int wl;
489 int ratio; 486 int ratio;
490 487
491 if (!es8328->sysclk_constraints) {
492 dev_err(codec->dev, "No MCLK configured\n");
493 return -EINVAL;
494 }
495
496 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 488 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
497 reg = ES8328_DACCONTROL2; 489 reg = ES8328_DACCONTROL2;
498 else 490 else
499 reg = ES8328_ADCCONTROL5; 491 reg = ES8328_ADCCONTROL5;
500 492
501 for (i = 0; i < es8328->sysclk_constraints->count; i++) 493 if (es8328->master) {
502 if (es8328->sysclk_constraints->list[i] == params_rate(params)) 494 if (!es8328->sysclk_constraints) {
503 break; 495 dev_err(codec->dev, "No MCLK configured\n");
496 return -EINVAL;
497 }
504 498
505 if (i == es8328->sysclk_constraints->count) { 499 for (i = 0; i < es8328->sysclk_constraints->count; i++)
506 dev_err(codec->dev, "LRCLK %d unsupported with current clock\n", 500 if (es8328->sysclk_constraints->list[i] ==
507 params_rate(params)); 501 params_rate(params))
508 return -EINVAL; 502 break;
503
504 if (i == es8328->sysclk_constraints->count) {
505 dev_err(codec->dev,
506 "LRCLK %d unsupported with current clock\n",
507 params_rate(params));
508 return -EINVAL;
509 }
510 ratio = es8328->mclk_ratios[i];
511 } else {
512 ratio = 0;
513 es8328->mclkdiv2 = 0;
509 } 514 }
510 515
511 ratio = es8328->mclk_ratios[i];
512 snd_soc_update_bits(codec, ES8328_MASTERMODE, 516 snd_soc_update_bits(codec, ES8328_MASTERMODE,
513 ES8328_MASTERMODE_MCLKDIV2, 517 ES8328_MASTERMODE_MCLKDIV2,
514 es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0); 518 es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);
@@ -586,6 +590,7 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
586 unsigned int fmt) 590 unsigned int fmt)
587{ 591{
588 struct snd_soc_codec *codec = codec_dai->codec; 592 struct snd_soc_codec *codec = codec_dai->codec;
593 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
589 u8 dac_mode = 0; 594 u8 dac_mode = 0;
590 u8 adc_mode = 0; 595 u8 adc_mode = 0;
591 596
@@ -595,11 +600,13 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
595 snd_soc_update_bits(codec, ES8328_MASTERMODE, 600 snd_soc_update_bits(codec, ES8328_MASTERMODE,
596 ES8328_MASTERMODE_MSC, 601 ES8328_MASTERMODE_MSC,
597 ES8328_MASTERMODE_MSC); 602 ES8328_MASTERMODE_MSC);
603 es8328->master = true;
598 break; 604 break;
599 case SND_SOC_DAIFMT_CBS_CFS: 605 case SND_SOC_DAIFMT_CBS_CFS:
600 /* Slave serial port mode */ 606 /* Slave serial port mode */
601 snd_soc_update_bits(codec, ES8328_MASTERMODE, 607 snd_soc_update_bits(codec, ES8328_MASTERMODE,
602 ES8328_MASTERMODE_MSC, 0); 608 ES8328_MASTERMODE_MSC, 0);
609 es8328->master = false;
603 break; 610 break;
604 default: 611 default:
605 return -EINVAL; 612 return -EINVAL;
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index fd272a40485b..bc2e74ff3b2d 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -469,7 +469,7 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
469 469
470 format = snd_hdac_calc_stream_format(params_rate(hparams), 470 format = snd_hdac_calc_stream_format(params_rate(hparams),
471 params_channels(hparams), params_format(hparams), 471 params_channels(hparams), params_format(hparams),
472 24, 0); 472 dai->driver->playback.sig_bits, 0);
473 473
474 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt); 474 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
475 if (!pcm) 475 if (!pcm)
@@ -1419,8 +1419,8 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
1419 hdmi_dais[i].playback.rate_min = rate_min; 1419 hdmi_dais[i].playback.rate_min = rate_min;
1420 hdmi_dais[i].playback.channels_min = 2; 1420 hdmi_dais[i].playback.channels_min = 2;
1421 hdmi_dais[i].playback.channels_max = 2; 1421 hdmi_dais[i].playback.channels_max = 2;
1422 hdmi_dais[i].playback.sig_bits = bps;
1422 hdmi_dais[i].ops = &hdmi_dai_ops; 1423 hdmi_dais[i].ops = &hdmi_dai_ops;
1423
1424 i++; 1424 i++;
1425 } 1425 }
1426 1426
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 6cdf15ab46de..0247edc9c84e 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -516,13 +516,13 @@ static const struct i2c_device_id max9867_i2c_id[] = {
516 { "max9867", 0 }, 516 { "max9867", 0 },
517 { } 517 { }
518}; 518};
519MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
519 520
520static const struct of_device_id max9867_of_match[] = { 521static const struct of_device_id max9867_of_match[] = {
521 { .compatible = "maxim,max9867", }, 522 { .compatible = "maxim,max9867", },
522 { } 523 { }
523}; 524};
524 525MODULE_DEVICE_TABLE(of, max9867_of_match);
525MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
526 526
527static const struct dev_pm_ops max9867_pm_ops = { 527static const struct dev_pm_ops max9867_pm_ops = {
528 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume) 528 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume)
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
new file mode 100644
index 000000000000..b5ee29499e16
--- /dev/null
+++ b/sound/soc/codecs/max98927.c
@@ -0,0 +1,841 @@
1/*
2 * max98927.c -- MAX98927 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2016 Maxim Integrated Products
5 * Author: Ryan Lee <ryans.lee@maximintegrated.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/acpi.h>
14#include <linux/i2c.h>
15#include <linux/module.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/cdev.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <linux/gpio.h>
23#include <linux/of_gpio.h>
24#include <sound/tlv.h>
25#include "max98927.h"
26
27static struct reg_default max98927_reg[] = {
28 {MAX98927_R0001_INT_RAW1, 0x00},
29 {MAX98927_R0002_INT_RAW2, 0x00},
30 {MAX98927_R0003_INT_RAW3, 0x00},
31 {MAX98927_R0004_INT_STATE1, 0x00},
32 {MAX98927_R0005_INT_STATE2, 0x00},
33 {MAX98927_R0006_INT_STATE3, 0x00},
34 {MAX98927_R0007_INT_FLAG1, 0x00},
35 {MAX98927_R0008_INT_FLAG2, 0x00},
36 {MAX98927_R0009_INT_FLAG3, 0x00},
37 {MAX98927_R000A_INT_EN1, 0x00},
38 {MAX98927_R000B_INT_EN2, 0x00},
39 {MAX98927_R000C_INT_EN3, 0x00},
40 {MAX98927_R000D_INT_FLAG_CLR1, 0x00},
41 {MAX98927_R000E_INT_FLAG_CLR2, 0x00},
42 {MAX98927_R000F_INT_FLAG_CLR3, 0x00},
43 {MAX98927_R0010_IRQ_CTRL, 0x00},
44 {MAX98927_R0011_CLK_MON, 0x00},
45 {MAX98927_R0012_WDOG_CTRL, 0x00},
46 {MAX98927_R0013_WDOG_RST, 0x00},
47 {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00},
48 {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00},
49 {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00},
50 {MAX98927_R0017_PIN_CFG, 0x55},
51 {MAX98927_R0018_PCM_RX_EN_A, 0x00},
52 {MAX98927_R0019_PCM_RX_EN_B, 0x00},
53 {MAX98927_R001A_PCM_TX_EN_A, 0x00},
54 {MAX98927_R001B_PCM_TX_EN_B, 0x00},
55 {MAX98927_R001C_PCM_TX_HIZ_CTRL_A, 0x00},
56 {MAX98927_R001D_PCM_TX_HIZ_CTRL_B, 0x00},
57 {MAX98927_R001E_PCM_TX_CH_SRC_A, 0x00},
58 {MAX98927_R001F_PCM_TX_CH_SRC_B, 0x00},
59 {MAX98927_R0020_PCM_MODE_CFG, 0x40},
60 {MAX98927_R0021_PCM_MASTER_MODE, 0x00},
61 {MAX98927_R0022_PCM_CLK_SETUP, 0x22},
62 {MAX98927_R0023_PCM_SR_SETUP1, 0x00},
63 {MAX98927_R0024_PCM_SR_SETUP2, 0x00},
64 {MAX98927_R0025_PCM_TO_SPK_MONOMIX_A, 0x00},
65 {MAX98927_R0026_PCM_TO_SPK_MONOMIX_B, 0x00},
66 {MAX98927_R0027_ICC_RX_EN_A, 0x00},
67 {MAX98927_R0028_ICC_RX_EN_B, 0x00},
68 {MAX98927_R002B_ICC_TX_EN_A, 0x00},
69 {MAX98927_R002C_ICC_TX_EN_B, 0x00},
70 {MAX98927_R002E_ICC_HIZ_MANUAL_MODE, 0x00},
71 {MAX98927_R002F_ICC_TX_HIZ_EN_A, 0x00},
72 {MAX98927_R0030_ICC_TX_HIZ_EN_B, 0x00},
73 {MAX98927_R0031_ICC_LNK_EN, 0x00},
74 {MAX98927_R0032_PDM_TX_EN, 0x00},
75 {MAX98927_R0033_PDM_TX_HIZ_CTRL, 0x00},
76 {MAX98927_R0034_PDM_TX_CTRL, 0x00},
77 {MAX98927_R0035_PDM_RX_CTRL, 0x00},
78 {MAX98927_R0036_AMP_VOL_CTRL, 0x00},
79 {MAX98927_R0037_AMP_DSP_CFG, 0x02},
80 {MAX98927_R0038_TONE_GEN_DC_CFG, 0x00},
81 {MAX98927_R0039_DRE_CTRL, 0x01},
82 {MAX98927_R003A_AMP_EN, 0x00},
83 {MAX98927_R003B_SPK_SRC_SEL, 0x00},
84 {MAX98927_R003C_SPK_GAIN, 0x00},
85 {MAX98927_R003D_SSM_CFG, 0x01},
86 {MAX98927_R003E_MEAS_EN, 0x00},
87 {MAX98927_R003F_MEAS_DSP_CFG, 0x04},
88 {MAX98927_R0040_BOOST_CTRL0, 0x00},
89 {MAX98927_R0041_BOOST_CTRL3, 0x00},
90 {MAX98927_R0042_BOOST_CTRL1, 0x00},
91 {MAX98927_R0043_MEAS_ADC_CFG, 0x00},
92 {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00},
93 {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00},
94 {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00},
95 {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00},
96 {MAX98927_R0048_ADC_CH2_DIVIDE, 0x00},
97 {MAX98927_R0049_ADC_CH0_FILT_CFG, 0x00},
98 {MAX98927_R004A_ADC_CH1_FILT_CFG, 0x00},
99 {MAX98927_R004B_ADC_CH2_FILT_CFG, 0x00},
100 {MAX98927_R004C_MEAS_ADC_CH0_READ, 0x00},
101 {MAX98927_R004D_MEAS_ADC_CH1_READ, 0x00},
102 {MAX98927_R004E_MEAS_ADC_CH2_READ, 0x00},
103 {MAX98927_R0051_BROWNOUT_STATUS, 0x00},
104 {MAX98927_R0052_BROWNOUT_EN, 0x00},
105 {MAX98927_R0053_BROWNOUT_INFINITE_HOLD, 0x00},
106 {MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR, 0x00},
107 {MAX98927_R0055_BROWNOUT_LVL_HOLD, 0x00},
108 {MAX98927_R005A_BROWNOUT_LVL1_THRESH, 0x00},
109 {MAX98927_R005B_BROWNOUT_LVL2_THRESH, 0x00},
110 {MAX98927_R005C_BROWNOUT_LVL3_THRESH, 0x00},
111 {MAX98927_R005D_BROWNOUT_LVL4_THRESH, 0x00},
112 {MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS, 0x00},
113 {MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL, 0x00},
114 {MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL, 0x00},
115 {MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE, 0x00},
116 {MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT, 0x00},
117 {MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1, 0x00},
118 {MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2, 0x00},
119 {MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3, 0x00},
120 {MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT, 0x00},
121 {MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1, 0x00},
122 {MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2, 0x00},
123 {MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3, 0x00},
124 {MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT, 0x00},
125 {MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1, 0x00},
126 {MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2, 0x00},
127 {MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3, 0x00},
128 {MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT, 0x00},
129 {MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1, 0x00},
130 {MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2, 0x00},
131 {MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3, 0x00},
132 {MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM, 0x00},
133 {MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY, 0x00},
134 {MAX98927_R0084_ENV_TRACK_REL_RATE, 0x00},
135 {MAX98927_R0085_ENV_TRACK_HOLD_RATE, 0x00},
136 {MAX98927_R0086_ENV_TRACK_CTRL, 0x00},
137 {MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ, 0x00},
138 {MAX98927_R00FF_GLOBAL_SHDN, 0x00},
139 {MAX98927_R0100_SOFT_RESET, 0x00},
140 {MAX98927_R01FF_REV_ID, 0x40},
141};
142
143static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
144{
145 struct snd_soc_codec *codec = codec_dai->codec;
146 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
147 unsigned int mode = 0;
148 unsigned int format = 0;
149 unsigned int invert = 0;
150
151 dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
152
153 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
154 case SND_SOC_DAIFMT_CBS_CFS:
155 mode = MAX98927_PCM_MASTER_MODE_SLAVE;
156 break;
157 case SND_SOC_DAIFMT_CBM_CFM:
158 max98927->master = true;
159 mode = MAX98927_PCM_MASTER_MODE_MASTER;
160 break;
161 default:
162 dev_err(codec->dev, "DAI clock mode unsupported");
163 return -EINVAL;
164 }
165
166 regmap_update_bits(max98927->regmap,
167 MAX98927_R0021_PCM_MASTER_MODE,
168 MAX98927_PCM_MASTER_MODE_MASK,
169 mode);
170
171 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
172 case SND_SOC_DAIFMT_NB_NF:
173 break;
174 case SND_SOC_DAIFMT_IB_NF:
175 invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
176 break;
177 default:
178 dev_err(codec->dev, "DAI invert mode unsupported");
179 return -EINVAL;
180 }
181
182 regmap_update_bits(max98927->regmap,
183 MAX98927_R0020_PCM_MODE_CFG,
184 MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE,
185 invert);
186
187 /* interface format */
188 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
189 case SND_SOC_DAIFMT_I2S:
190 max98927->iface |= SND_SOC_DAIFMT_I2S;
191 format = MAX98927_PCM_FORMAT_I2S;
192 break;
193 case SND_SOC_DAIFMT_LEFT_J:
194 max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
195 format = MAX98927_PCM_FORMAT_LJ;
196 break;
197 case SND_SOC_DAIFMT_PDM:
198 max98927->iface |= SND_SOC_DAIFMT_PDM;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 /* pcm channel configuration */
205 if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
206 regmap_update_bits(max98927->regmap,
207 MAX98927_R0018_PCM_RX_EN_A,
208 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
209 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN);
210
211 regmap_update_bits(max98927->regmap,
212 MAX98927_R0020_PCM_MODE_CFG,
213 MAX98927_PCM_MODE_CFG_FORMAT_MASK,
214 format << MAX98927_PCM_MODE_CFG_FORMAT_SHIFT);
215
216 regmap_update_bits(max98927->regmap,
217 MAX98927_R003B_SPK_SRC_SEL,
218 MAX98927_SPK_SRC_MASK, 0);
219
220 } else
221 regmap_update_bits(max98927->regmap,
222 MAX98927_R0018_PCM_RX_EN_A,
223 MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
224
225 /* pdm channel configuration */
226 if (max98927->iface & SND_SOC_DAIFMT_PDM) {
227 regmap_update_bits(max98927->regmap,
228 MAX98927_R0035_PDM_RX_CTRL,
229 MAX98927_PDM_RX_EN_MASK, 1);
230
231 regmap_update_bits(max98927->regmap,
232 MAX98927_R003B_SPK_SRC_SEL,
233 MAX98927_SPK_SRC_MASK, 3);
234 } else
235 regmap_update_bits(max98927->regmap,
236 MAX98927_R0035_PDM_RX_CTRL,
237 MAX98927_PDM_RX_EN_MASK, 0);
238 return 0;
239}
240
241/* codec MCLK rate in master mode */
242static const int rate_table[] = {
243 5644800, 6000000, 6144000, 6500000,
244 9600000, 11289600, 12000000, 12288000,
245 13000000, 19200000,
246};
247
248static int max98927_set_clock(struct max98927_priv *max98927,
249 struct snd_pcm_hw_params *params)
250{
251 struct snd_soc_codec *codec = max98927->codec;
252 /* BCLK/LRCLK ratio calculation */
253 int blr_clk_ratio = params_channels(params) * max98927->ch_size;
254 int value;
255
256 if (max98927->master) {
257 int i;
258 /* match rate to closest value */
259 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
260 if (rate_table[i] >= max98927->sysclk)
261 break;
262 }
263 if (i == ARRAY_SIZE(rate_table)) {
264 dev_err(codec->dev, "failed to find proper clock rate.\n");
265 return -EINVAL;
266 }
267 regmap_update_bits(max98927->regmap,
268 MAX98927_R0021_PCM_MASTER_MODE,
269 MAX98927_PCM_MASTER_MODE_MCLK_MASK,
270 i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
271 }
272
273 switch (blr_clk_ratio) {
274 case 32:
275 value = 2;
276 break;
277 case 48:
278 value = 3;
279 break;
280 case 64:
281 value = 4;
282 break;
283 default:
284 return -EINVAL;
285 }
286 regmap_update_bits(max98927->regmap,
287 MAX98927_R0022_PCM_CLK_SETUP,
288 MAX98927_PCM_CLK_SETUP_BSEL_MASK,
289 value);
290 return 0;
291}
292
293static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
294 struct snd_pcm_hw_params *params,
295 struct snd_soc_dai *dai)
296{
297 struct snd_soc_codec *codec = dai->codec;
298 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
299 unsigned int sampling_rate = 0;
300 unsigned int chan_sz = 0;
301
302 /* pcm mode configuration */
303 switch (snd_pcm_format_width(params_format(params))) {
304 case 16:
305 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
306 break;
307 case 24:
308 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
309 break;
310 case 32:
311 chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
312 break;
313 default:
314 dev_err(codec->dev, "format unsupported %d",
315 params_format(params));
316 goto err;
317 }
318
319 max98927->ch_size = snd_pcm_format_width(params_format(params));
320
321 regmap_update_bits(max98927->regmap,
322 MAX98927_R0020_PCM_MODE_CFG,
323 MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
324
325 dev_dbg(codec->dev, "format supported %d",
326 params_format(params));
327
328 /* sampling rate configuration */
329 switch (params_rate(params)) {
330 case 8000:
331 sampling_rate = MAX98927_PCM_SR_SET1_SR_8000;
332 break;
333 case 11025:
334 sampling_rate = MAX98927_PCM_SR_SET1_SR_11025;
335 break;
336 case 12000:
337 sampling_rate = MAX98927_PCM_SR_SET1_SR_12000;
338 break;
339 case 16000:
340 sampling_rate = MAX98927_PCM_SR_SET1_SR_16000;
341 break;
342 case 22050:
343 sampling_rate = MAX98927_PCM_SR_SET1_SR_22050;
344 break;
345 case 24000:
346 sampling_rate = MAX98927_PCM_SR_SET1_SR_24000;
347 break;
348 case 32000:
349 sampling_rate = MAX98927_PCM_SR_SET1_SR_32000;
350 break;
351 case 44100:
352 sampling_rate = MAX98927_PCM_SR_SET1_SR_44100;
353 break;
354 case 48000:
355 sampling_rate = MAX98927_PCM_SR_SET1_SR_48000;
356 break;
357 default:
358 dev_err(codec->dev, "rate %d not supported\n",
359 params_rate(params));
360 goto err;
361 }
362 /* set DAI_SR to correct LRCLK frequency */
363 regmap_update_bits(max98927->regmap,
364 MAX98927_R0023_PCM_SR_SETUP1,
365 MAX98927_PCM_SR_SET1_SR_MASK,
366 sampling_rate);
367 regmap_update_bits(max98927->regmap,
368 MAX98927_R0024_PCM_SR_SETUP2,
369 MAX98927_PCM_SR_SET2_SR_MASK,
370 sampling_rate << MAX98927_PCM_SR_SET2_SR_SHIFT);
371
372 /* set sampling rate of IV */
373 if (max98927->interleave_mode &&
374 sampling_rate > MAX98927_PCM_SR_SET1_SR_16000)
375 regmap_update_bits(max98927->regmap,
376 MAX98927_R0024_PCM_SR_SETUP2,
377 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
378 sampling_rate - 3);
379 else
380 regmap_update_bits(max98927->regmap,
381 MAX98927_R0024_PCM_SR_SETUP2,
382 MAX98927_PCM_SR_SET2_IVADC_SR_MASK,
383 sampling_rate);
384 return max98927_set_clock(max98927, params);
385err:
386 return -EINVAL;
387}
388
389#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
390
391#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
392 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
393
394static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
395 int clk_id, unsigned int freq, int dir)
396{
397 struct snd_soc_codec *codec = dai->codec;
398 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
399
400 max98927->sysclk = freq;
401 return 0;
402}
403
404static const struct snd_soc_dai_ops max98927_dai_ops = {
405 .set_sysclk = max98927_dai_set_sysclk,
406 .set_fmt = max98927_dai_set_fmt,
407 .hw_params = max98927_dai_hw_params,
408};
409
410static int max98927_dac_event(struct snd_soc_dapm_widget *w,
411 struct snd_kcontrol *kcontrol, int event)
412{
413 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
414 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
415
416 switch (event) {
417 case SND_SOC_DAPM_POST_PMU:
418 regmap_update_bits(max98927->regmap,
419 MAX98927_R003A_AMP_EN,
420 MAX98927_AMP_EN_MASK, 1);
421 /* enable VMON and IMON */
422 regmap_update_bits(max98927->regmap,
423 MAX98927_R003E_MEAS_EN,
424 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
425 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
426 regmap_update_bits(max98927->regmap,
427 MAX98927_R00FF_GLOBAL_SHDN,
428 MAX98927_GLOBAL_EN_MASK, 1);
429 break;
430 case SND_SOC_DAPM_POST_PMD:
431 regmap_update_bits(max98927->regmap,
432 MAX98927_R00FF_GLOBAL_SHDN,
433 MAX98927_GLOBAL_EN_MASK, 0);
434 regmap_update_bits(max98927->regmap,
435 MAX98927_R003A_AMP_EN,
436 MAX98927_AMP_EN_MASK, 0);
437 /* disable VMON and IMON */
438 regmap_update_bits(max98927->regmap,
439 MAX98927_R003E_MEAS_EN,
440 MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
441 break;
442 default:
443 return 0;
444 }
445 return 0;
446}
447
448static const char * const max98927_switch_text[] = {
449 "Left", "Right", "LeftRight"};
450
451static const struct soc_enum dai_sel_enum =
452 SOC_ENUM_SINGLE(MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
453 MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT,
454 3, max98927_switch_text);
455
456static const struct snd_kcontrol_new max98927_dai_controls =
457 SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
458
459static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
460 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
461 SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
462 0, 0, max98927_dac_event,
463 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
464 SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
465 &max98927_dai_controls),
466 SND_SOC_DAPM_OUTPUT("BE_OUT"),
467};
468
469static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
470static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
471
472static bool max98927_readable_register(struct device *dev, unsigned int reg)
473{
474 switch (reg) {
475 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0028_ICC_RX_EN_B:
476 case MAX98927_R002B_ICC_TX_EN_A ... MAX98927_R002C_ICC_TX_EN_B:
477 case MAX98927_R002E_ICC_HIZ_MANUAL_MODE
478 ... MAX98927_R004E_MEAS_ADC_CH2_READ:
479 case MAX98927_R0051_BROWNOUT_STATUS
480 ... MAX98927_R0055_BROWNOUT_LVL_HOLD:
481 case MAX98927_R005A_BROWNOUT_LVL1_THRESH
482 ... MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE:
483 case MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT
484 ... MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
485 case MAX98927_R00FF_GLOBAL_SHDN:
486 case MAX98927_R0100_SOFT_RESET:
487 case MAX98927_R01FF_REV_ID:
488 return true;
489 default:
490 return false;
491 }
492};
493
494static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
495{
496 switch (reg) {
497 case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
498 return true;
499 default:
500 return false;
501 }
502}
503
504static const char * const max98927_boost_voltage_text[] = {
505 "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
506 "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
507 "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
508 "9.5V", "9.625V", "9.75V", "9.875V", "10V"
509};
510
511static SOC_ENUM_SINGLE_DECL(max98927_boost_voltage,
512 MAX98927_R0040_BOOST_CTRL0, 0,
513 max98927_boost_voltage_text);
514
515static const char * const max98927_current_limit_text[] = {
516 "1.00A", "1.10A", "1.20A", "1.30A", "1.40A", "1.50A", "1.60A", "1.70A",
517 "1.80A", "1.90A", "2.00A", "2.10A", "2.20A", "2.30A", "2.40A", "2.50A",
518 "2.60A", "2.70A", "2.80A", "2.90A", "3.00A", "3.10A", "3.20A", "3.30A",
519 "3.40A", "3.50A", "3.60A", "3.70A", "3.80A", "3.90A", "4.00A", "4.10A"
520};
521
522static SOC_ENUM_SINGLE_DECL(max98927_current_limit,
523 MAX98927_R0042_BOOST_CTRL1, 1,
524 max98927_current_limit_text);
525
526static const struct snd_kcontrol_new max98927_snd_controls[] = {
527 SOC_SINGLE_TLV("Speaker Volume", MAX98927_R003C_SPK_GAIN,
528 0, 6, 0,
529 max98927_spk_tlv),
530 SOC_SINGLE_TLV("Digital Volume", MAX98927_R0036_AMP_VOL_CTRL,
531 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
532 max98927_digital_tlv),
533 SOC_SINGLE("Amp DSP Switch", MAX98927_R0052_BROWNOUT_EN,
534 MAX98927_BROWNOUT_DSP_SHIFT, 1, 0),
535 SOC_SINGLE("Ramp Switch", MAX98927_R0037_AMP_DSP_CFG,
536 MAX98927_AMP_DSP_CFG_RMP_SHIFT, 1, 0),
537 SOC_SINGLE("DRE Switch", MAX98927_R0039_DRE_CTRL,
538 MAX98927_DRE_EN_SHIFT, 1, 0),
539 SOC_SINGLE("Volume Location Switch", MAX98927_R0036_AMP_VOL_CTRL,
540 MAX98927_AMP_VOL_SEL_SHIFT, 1, 0),
541 SOC_ENUM("Boost Output Voltage", max98927_boost_voltage),
542 SOC_ENUM("Current Limit", max98927_current_limit),
543};
544
545static const struct snd_soc_dapm_route max98927_audio_map[] = {
546 {"Amp Enable", NULL, "DAI_OUT"},
547 {"DAI Sel Mux", "Left", "Amp Enable"},
548 {"DAI Sel Mux", "Right", "Amp Enable"},
549 {"DAI Sel Mux", "LeftRight", "Amp Enable"},
550 {"BE_OUT", NULL, "DAI Sel Mux"},
551};
552
553static struct snd_soc_dai_driver max98927_dai[] = {
554 {
555 .name = "max98927-aif1",
556 .playback = {
557 .stream_name = "HiFi Playback",
558 .channels_min = 1,
559 .channels_max = 2,
560 .rates = MAX98927_RATES,
561 .formats = MAX98927_FORMATS,
562 },
563 .capture = {
564 .stream_name = "HiFi Capture",
565 .channels_min = 1,
566 .channels_max = 2,
567 .rates = MAX98927_RATES,
568 .formats = MAX98927_FORMATS,
569 },
570 .ops = &max98927_dai_ops,
571 }
572};
573
574static int max98927_probe(struct snd_soc_codec *codec)
575{
576 struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
577
578 max98927->codec = codec;
579 codec->control_data = max98927->regmap;
580 codec->cache_bypass = 1;
581
582 /* Software Reset */
583 regmap_write(max98927->regmap,
584 MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
585
586 /* IV default slot configuration */
587 regmap_write(max98927->regmap,
588 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
589 0xFF);
590 regmap_write(max98927->regmap,
591 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
592 0xFF);
593 regmap_write(max98927->regmap,
594 MAX98927_R0025_PCM_TO_SPK_MONOMIX_A,
595 0x80);
596 regmap_write(max98927->regmap,
597 MAX98927_R0026_PCM_TO_SPK_MONOMIX_B,
598 0x1);
599 /* Set inital volume (+13dB) */
600 regmap_write(max98927->regmap,
601 MAX98927_R0036_AMP_VOL_CTRL,
602 0x38);
603 regmap_write(max98927->regmap,
604 MAX98927_R003C_SPK_GAIN,
605 0x05);
606 /* Enable DC blocker */
607 regmap_write(max98927->regmap,
608 MAX98927_R0037_AMP_DSP_CFG,
609 0x03);
610 /* Enable IMON VMON DC blocker */
611 regmap_write(max98927->regmap,
612 MAX98927_R003F_MEAS_DSP_CFG,
613 0xF7);
614 /* Boost Output Voltage & Current limit */
615 regmap_write(max98927->regmap,
616 MAX98927_R0040_BOOST_CTRL0,
617 0x1C);
618 regmap_write(max98927->regmap,
619 MAX98927_R0042_BOOST_CTRL1,
620 0x3E);
621 /* Measurement ADC config */
622 regmap_write(max98927->regmap,
623 MAX98927_R0043_MEAS_ADC_CFG,
624 0x04);
625 regmap_write(max98927->regmap,
626 MAX98927_R0044_MEAS_ADC_BASE_MSB,
627 0x00);
628 regmap_write(max98927->regmap,
629 MAX98927_R0045_MEAS_ADC_BASE_LSB,
630 0x24);
631 /* Brownout Level */
632 regmap_write(max98927->regmap,
633 MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1,
634 0x06);
635 /* Envelope Tracking configuration */
636 regmap_write(max98927->regmap,
637 MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM,
638 0x08);
639 regmap_write(max98927->regmap,
640 MAX98927_R0086_ENV_TRACK_CTRL,
641 0x01);
642 regmap_write(max98927->regmap,
643 MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ,
644 0x10);
645
646 /* voltage, current slot configuration */
647 regmap_write(max98927->regmap,
648 MAX98927_R001E_PCM_TX_CH_SRC_A,
649 (max98927->i_l_slot<<MAX98927_PCM_TX_CH_SRC_A_I_SHIFT|
650 max98927->v_l_slot)&0xFF);
651
652 if (max98927->v_l_slot < 8) {
653 regmap_update_bits(max98927->regmap,
654 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
655 1 << max98927->v_l_slot, 0);
656 regmap_update_bits(max98927->regmap,
657 MAX98927_R001A_PCM_TX_EN_A,
658 1 << max98927->v_l_slot,
659 1 << max98927->v_l_slot);
660 } else {
661 regmap_update_bits(max98927->regmap,
662 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
663 1 << (max98927->v_l_slot - 8), 0);
664 regmap_update_bits(max98927->regmap,
665 MAX98927_R001B_PCM_TX_EN_B,
666 1 << (max98927->v_l_slot - 8),
667 1 << (max98927->v_l_slot - 8));
668 }
669
670 if (max98927->i_l_slot < 8) {
671 regmap_update_bits(max98927->regmap,
672 MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
673 1 << max98927->i_l_slot, 0);
674 regmap_update_bits(max98927->regmap,
675 MAX98927_R001A_PCM_TX_EN_A,
676 1 << max98927->i_l_slot,
677 1 << max98927->i_l_slot);
678 } else {
679 regmap_update_bits(max98927->regmap,
680 MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
681 1 << (max98927->i_l_slot - 8), 0);
682 regmap_update_bits(max98927->regmap,
683 MAX98927_R001B_PCM_TX_EN_B,
684 1 << (max98927->i_l_slot - 8),
685 1 << (max98927->i_l_slot - 8));
686 }
687
688 /* Set interleave mode */
689 if (max98927->interleave_mode)
690 regmap_update_bits(max98927->regmap,
691 MAX98927_R001F_PCM_TX_CH_SRC_B,
692 MAX98927_PCM_TX_CH_INTERLEAVE_MASK,
693 MAX98927_PCM_TX_CH_INTERLEAVE_MASK);
694 return 0;
695}
696
697static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
698 .probe = max98927_probe,
699 .component_driver = {
700 .controls = max98927_snd_controls,
701 .num_controls = ARRAY_SIZE(max98927_snd_controls),
702 .dapm_widgets = max98927_dapm_widgets,
703 .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
704 .dapm_routes = max98927_audio_map,
705 .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
706 },
707};
708
709static const struct regmap_config max98927_regmap = {
710 .reg_bits = 16,
711 .val_bits = 8,
712 .max_register = MAX98927_R01FF_REV_ID,
713 .reg_defaults = max98927_reg,
714 .num_reg_defaults = ARRAY_SIZE(max98927_reg),
715 .readable_reg = max98927_readable_register,
716 .volatile_reg = max98927_volatile_reg,
717 .cache_type = REGCACHE_RBTREE,
718};
719
720static void max98927_slot_config(struct i2c_client *i2c,
721 struct max98927_priv *max98927)
722{
723 int value;
724
725 if (!of_property_read_u32(i2c->dev.of_node,
726 "vmon-slot-no", &value))
727 max98927->v_l_slot = value & 0xF;
728 else
729 max98927->v_l_slot = 0;
730 if (!of_property_read_u32(i2c->dev.of_node,
731 "imon-slot-no", &value))
732 max98927->i_l_slot = value & 0xF;
733 else
734 max98927->i_l_slot = 1;
735}
736
737static int max98927_i2c_probe(struct i2c_client *i2c,
738 const struct i2c_device_id *id)
739{
740
741 int ret = 0, value;
742 int reg = 0;
743 struct max98927_priv *max98927 = NULL;
744
745 max98927 = devm_kzalloc(&i2c->dev,
746 sizeof(*max98927), GFP_KERNEL);
747
748 if (!max98927) {
749 ret = -ENOMEM;
750 return ret;
751 }
752 i2c_set_clientdata(i2c, max98927);
753
754 /* update interleave mode info */
755 if (!of_property_read_u32(i2c->dev.of_node,
756 "interleave_mode", &value)) {
757 if (value > 0)
758 max98927->interleave_mode = 1;
759 else
760 max98927->interleave_mode = 0;
761 } else
762 max98927->interleave_mode = 0;
763
764 /* regmap initialization */
765 max98927->regmap
766 = devm_regmap_init_i2c(i2c, &max98927_regmap);
767 if (IS_ERR(max98927->regmap)) {
768 ret = PTR_ERR(max98927->regmap);
769 dev_err(&i2c->dev,
770 "Failed to allocate regmap: %d\n", ret);
771 return ret;
772 }
773
774 /* Check Revision ID */
775 ret = regmap_read(max98927->regmap,
776 MAX98927_R01FF_REV_ID, &reg);
777 if (ret < 0) {
778 dev_err(&i2c->dev,
779 "Failed to read: 0x%02X\n", MAX98927_R01FF_REV_ID);
780 return ret;
781 }
782 dev_info(&i2c->dev, "MAX98927 revisionID: 0x%02X\n", reg);
783
784 /* voltage/current slot configuration */
785 max98927_slot_config(i2c, max98927);
786
787 /* codec registeration */
788 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
789 max98927_dai, ARRAY_SIZE(max98927_dai));
790 if (ret < 0)
791 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
792
793 return ret;
794}
795
796static int max98927_i2c_remove(struct i2c_client *client)
797{
798 snd_soc_unregister_codec(&client->dev);
799 return 0;
800}
801
802static const struct i2c_device_id max98927_i2c_id[] = {
803 { "max98927", 0},
804 { },
805};
806
807MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
808
809#if defined(CONFIG_OF)
810static const struct of_device_id max98927_of_match[] = {
811 { .compatible = "maxim,max98927", },
812 { }
813};
814MODULE_DEVICE_TABLE(of, max98927_of_match);
815#endif
816
817#ifdef CONFIG_ACPI
818static const struct acpi_device_id max98927_acpi_match[] = {
819 { "MX98927", 0 },
820 {},
821};
822MODULE_DEVICE_TABLE(acpi, max98927_acpi_match);
823#endif
824
825static struct i2c_driver max98927_i2c_driver = {
826 .driver = {
827 .name = "max98927",
828 .of_match_table = of_match_ptr(max98927_of_match),
829 .acpi_match_table = ACPI_PTR(max98927_acpi_match),
830 .pm = NULL,
831 },
832 .probe = max98927_i2c_probe,
833 .remove = max98927_i2c_remove,
834 .id_table = max98927_i2c_id,
835};
836
837module_i2c_driver(max98927_i2c_driver)
838
839MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
840MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>");
841MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
new file mode 100644
index 000000000000..ece6a608cbe1
--- /dev/null
+++ b/sound/soc/codecs/max98927.h
@@ -0,0 +1,272 @@
1/*
2 * max98927.h -- MAX98927 ALSA Soc Audio driver
3 *
4 * Copyright 2013-15 Maxim Integrated Products
5 * Author: Ryan Lee <ryans.lee@maximintegrated.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#ifndef _MAX98927_H
14#define _MAX98927_H
15
16/* Register Values */
17#define MAX98927_R0001_INT_RAW1 0x0001
18#define MAX98927_R0002_INT_RAW2 0x0002
19#define MAX98927_R0003_INT_RAW3 0x0003
20#define MAX98927_R0004_INT_STATE1 0x0004
21#define MAX98927_R0005_INT_STATE2 0x0005
22#define MAX98927_R0006_INT_STATE3 0x0006
23#define MAX98927_R0007_INT_FLAG1 0x0007
24#define MAX98927_R0008_INT_FLAG2 0x0008
25#define MAX98927_R0009_INT_FLAG3 0x0009
26#define MAX98927_R000A_INT_EN1 0x000A
27#define MAX98927_R000B_INT_EN2 0x000B
28#define MAX98927_R000C_INT_EN3 0x000C
29#define MAX98927_R000D_INT_FLAG_CLR1 0x000D
30#define MAX98927_R000E_INT_FLAG_CLR2 0x000E
31#define MAX98927_R000F_INT_FLAG_CLR3 0x000F
32#define MAX98927_R0010_IRQ_CTRL 0x0010
33#define MAX98927_R0011_CLK_MON 0x0011
34#define MAX98927_R0012_WDOG_CTRL 0x0012
35#define MAX98927_R0013_WDOG_RST 0x0013
36#define MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH 0x0014
37#define MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH 0x0015
38#define MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS 0x0016
39#define MAX98927_R0017_PIN_CFG 0x0017
40#define MAX98927_R0018_PCM_RX_EN_A 0x0018
41#define MAX98927_R0019_PCM_RX_EN_B 0x0019
42#define MAX98927_R001A_PCM_TX_EN_A 0x001A
43#define MAX98927_R001B_PCM_TX_EN_B 0x001B
44#define MAX98927_R001C_PCM_TX_HIZ_CTRL_A 0x001C
45#define MAX98927_R001D_PCM_TX_HIZ_CTRL_B 0x001D
46#define MAX98927_R001E_PCM_TX_CH_SRC_A 0x001E
47#define MAX98927_R001F_PCM_TX_CH_SRC_B 0x001F
48#define MAX98927_R0020_PCM_MODE_CFG 0x0020
49#define MAX98927_R0021_PCM_MASTER_MODE 0x0021
50#define MAX98927_R0022_PCM_CLK_SETUP 0x0022
51#define MAX98927_R0023_PCM_SR_SETUP1 0x0023
52#define MAX98927_R0024_PCM_SR_SETUP2 0x0024
53#define MAX98927_R0025_PCM_TO_SPK_MONOMIX_A 0x0025
54#define MAX98927_R0026_PCM_TO_SPK_MONOMIX_B 0x0026
55#define MAX98927_R0027_ICC_RX_EN_A 0x0027
56#define MAX98927_R0028_ICC_RX_EN_B 0x0028
57#define MAX98927_R002B_ICC_TX_EN_A 0x002B
58#define MAX98927_R002C_ICC_TX_EN_B 0x002C
59#define MAX98927_R002E_ICC_HIZ_MANUAL_MODE 0x002E
60#define MAX98927_R002F_ICC_TX_HIZ_EN_A 0x002F
61#define MAX98927_R0030_ICC_TX_HIZ_EN_B 0x0030
62#define MAX98927_R0031_ICC_LNK_EN 0x0031
63#define MAX98927_R0032_PDM_TX_EN 0x0032
64#define MAX98927_R0033_PDM_TX_HIZ_CTRL 0x0033
65#define MAX98927_R0034_PDM_TX_CTRL 0x0034
66#define MAX98927_R0035_PDM_RX_CTRL 0x0035
67#define MAX98927_R0036_AMP_VOL_CTRL 0x0036
68#define MAX98927_R0037_AMP_DSP_CFG 0x0037
69#define MAX98927_R0038_TONE_GEN_DC_CFG 0x0038
70#define MAX98927_R0039_DRE_CTRL 0x0039
71#define MAX98927_R003A_AMP_EN 0x003A
72#define MAX98927_R003B_SPK_SRC_SEL 0x003B
73#define MAX98927_R003C_SPK_GAIN 0x003C
74#define MAX98927_R003D_SSM_CFG 0x003D
75#define MAX98927_R003E_MEAS_EN 0x003E
76#define MAX98927_R003F_MEAS_DSP_CFG 0x003F
77#define MAX98927_R0040_BOOST_CTRL0 0x0040
78#define MAX98927_R0041_BOOST_CTRL3 0x0041
79#define MAX98927_R0042_BOOST_CTRL1 0x0042
80#define MAX98927_R0043_MEAS_ADC_CFG 0x0043
81#define MAX98927_R0044_MEAS_ADC_BASE_MSB 0x0044
82#define MAX98927_R0045_MEAS_ADC_BASE_LSB 0x0045
83#define MAX98927_R0046_ADC_CH0_DIVIDE 0x0046
84#define MAX98927_R0047_ADC_CH1_DIVIDE 0x0047
85#define MAX98927_R0048_ADC_CH2_DIVIDE 0x0048
86#define MAX98927_R0049_ADC_CH0_FILT_CFG 0x0049
87#define MAX98927_R004A_ADC_CH1_FILT_CFG 0x004A
88#define MAX98927_R004B_ADC_CH2_FILT_CFG 0x004B
89#define MAX98927_R004C_MEAS_ADC_CH0_READ 0x004C
90#define MAX98927_R004D_MEAS_ADC_CH1_READ 0x004D
91#define MAX98927_R004E_MEAS_ADC_CH2_READ 0x004E
92#define MAX98927_R0051_BROWNOUT_STATUS 0x0051
93#define MAX98927_R0052_BROWNOUT_EN 0x0052
94#define MAX98927_R0053_BROWNOUT_INFINITE_HOLD 0x0053
95#define MAX98927_R0054_BROWNOUT_INFINITE_HOLD_CLR 0x0054
96#define MAX98927_R0055_BROWNOUT_LVL_HOLD 0x0055
97#define MAX98927_R005A_BROWNOUT_LVL1_THRESH 0x005A
98#define MAX98927_R005B_BROWNOUT_LVL2_THRESH 0x005B
99#define MAX98927_R005C_BROWNOUT_LVL3_THRESH 0x005C
100#define MAX98927_R005D_BROWNOUT_LVL4_THRESH 0x005D
101#define MAX98927_R005E_BROWNOUT_THRESH_HYSTERYSIS 0x005E
102#define MAX98927_R005F_BROWNOUT_AMP_LIMITER_ATK_REL 0x005F
103#define MAX98927_R0060_BROWNOUT_AMP_GAIN_ATK_REL 0x0060
104#define MAX98927_R0061_BROWNOUT_AMP1_CLIP_MODE 0x0061
105#define MAX98927_R0072_BROWNOUT_LVL1_CUR_LIMIT 0x0072
106#define MAX98927_R0073_BROWNOUT_LVL1_AMP1_CTRL1 0x0073
107#define MAX98927_R0074_BROWNOUT_LVL1_AMP1_CTRL2 0x0074
108#define MAX98927_R0075_BROWNOUT_LVL1_AMP1_CTRL3 0x0075
109#define MAX98927_R0076_BROWNOUT_LVL2_CUR_LIMIT 0x0076
110#define MAX98927_R0077_BROWNOUT_LVL2_AMP1_CTRL1 0x0077
111#define MAX98927_R0078_BROWNOUT_LVL2_AMP1_CTRL2 0x0078
112#define MAX98927_R0079_BROWNOUT_LVL2_AMP1_CTRL3 0x0079
113#define MAX98927_R007A_BROWNOUT_LVL3_CUR_LIMIT 0x007A
114#define MAX98927_R007B_BROWNOUT_LVL3_AMP1_CTRL1 0x007B
115#define MAX98927_R007C_BROWNOUT_LVL3_AMP1_CTRL2 0x007C
116#define MAX98927_R007D_BROWNOUT_LVL3_AMP1_CTRL3 0x007D
117#define MAX98927_R007E_BROWNOUT_LVL4_CUR_LIMIT 0x007E
118#define MAX98927_R007F_BROWNOUT_LVL4_AMP1_CTRL1 0x007F
119#define MAX98927_R0080_BROWNOUT_LVL4_AMP1_CTRL2 0x0080
120#define MAX98927_R0081_BROWNOUT_LVL4_AMP1_CTRL3 0x0081
121#define MAX98927_R0082_ENV_TRACK_VOUT_HEADROOM 0x0082
122#define MAX98927_R0083_ENV_TRACK_BOOST_VOUT_DELAY 0x0083
123#define MAX98927_R0084_ENV_TRACK_REL_RATE 0x0084
124#define MAX98927_R0085_ENV_TRACK_HOLD_RATE 0x0085
125#define MAX98927_R0086_ENV_TRACK_CTRL 0x0086
126#define MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ 0x0087
127#define MAX98927_R00FF_GLOBAL_SHDN 0x00FF
128#define MAX98927_R0100_SOFT_RESET 0x0100
129#define MAX98927_R01FF_REV_ID 0x01FF
130
131/* MAX98927_R0018_PCM_RX_EN_A */
132#define MAX98927_PCM_RX_CH0_EN (0x1 << 0)
133#define MAX98927_PCM_RX_CH1_EN (0x1 << 1)
134#define MAX98927_PCM_RX_CH2_EN (0x1 << 2)
135#define MAX98927_PCM_RX_CH3_EN (0x1 << 3)
136#define MAX98927_PCM_RX_CH4_EN (0x1 << 4)
137#define MAX98927_PCM_RX_CH5_EN (0x1 << 5)
138#define MAX98927_PCM_RX_CH6_EN (0x1 << 6)
139#define MAX98927_PCM_RX_CH7_EN (0x1 << 7)
140
141/* MAX98927_R001A_PCM_TX_EN_A */
142#define MAX98927_PCM_TX_CH0_EN (0x1 << 0)
143#define MAX98927_PCM_TX_CH1_EN (0x1 << 1)
144#define MAX98927_PCM_TX_CH2_EN (0x1 << 2)
145#define MAX98927_PCM_TX_CH3_EN (0x1 << 3)
146#define MAX98927_PCM_TX_CH4_EN (0x1 << 4)
147#define MAX98927_PCM_TX_CH5_EN (0x1 << 5)
148#define MAX98927_PCM_TX_CH6_EN (0x1 << 6)
149#define MAX98927_PCM_TX_CH7_EN (0x1 << 7)
150
151/* MAX98927_R001E_PCM_TX_CH_SRC_A */
152#define MAX98927_PCM_TX_CH_SRC_A_V_SHIFT (0)
153#define MAX98927_PCM_TX_CH_SRC_A_I_SHIFT (4)
154
155/* MAX98927_R001F_PCM_TX_CH_SRC_B */
156#define MAX98927_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 5)
157
158/* MAX98927_R0020_PCM_MODE_CFG */
159#define MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 2)
160#define MAX98927_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3)
161#define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
162#define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
163#define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
164
165#define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
166#define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
167#define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
168#define MAX98927_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6)
169
170/* MAX98927_R0021_PCM_MASTER_MODE */
171#define MAX98927_PCM_MASTER_MODE_MASK (0x3 << 0)
172#define MAX98927_PCM_MASTER_MODE_SLAVE (0x0 << 0)
173#define MAX98927_PCM_MASTER_MODE_MASTER (0x3 << 0)
174
175#define MAX98927_PCM_MASTER_MODE_MCLK_MASK (0xF << 2)
176#define MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT (2)
177
178/* MAX98927_R0022_PCM_CLK_SETUP */
179#define MAX98927_PCM_CLK_SETUP_BSEL_MASK (0xF << 0)
180
181/* MAX98927_R0023_PCM_SR_SETUP1 */
182#define MAX98927_PCM_SR_SET1_SR_MASK (0xF << 0)
183
184#define MAX98927_PCM_SR_SET1_SR_8000 (0x0 << 0)
185#define MAX98927_PCM_SR_SET1_SR_11025 (0x1 << 0)
186#define MAX98927_PCM_SR_SET1_SR_12000 (0x2 << 0)
187#define MAX98927_PCM_SR_SET1_SR_16000 (0x3 << 0)
188#define MAX98927_PCM_SR_SET1_SR_22050 (0x4 << 0)
189#define MAX98927_PCM_SR_SET1_SR_24000 (0x5 << 0)
190#define MAX98927_PCM_SR_SET1_SR_32000 (0x6 << 0)
191#define MAX98927_PCM_SR_SET1_SR_44100 (0x7 << 0)
192#define MAX98927_PCM_SR_SET1_SR_48000 (0x8 << 0)
193
194/* MAX98927_R0024_PCM_SR_SETUP2 */
195#define MAX98927_PCM_SR_SET2_SR_MASK (0xF << 4)
196#define MAX98927_PCM_SR_SET2_SR_SHIFT (4)
197#define MAX98927_PCM_SR_SET2_IVADC_SR_MASK (0xf << 0)
198
199/* MAX98927_R0025_PCM_TO_SPK_MONOMIX_A */
200#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6)
201#define MAX98927_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6)
202
203/* MAX98927_R0035_PDM_RX_CTRL */
204#define MAX98927_PDM_RX_EN_MASK (0x1 << 0)
205
206/* MAX98927_R0036_AMP_VOL_CTRL */
207#define MAX98927_AMP_VOL_SEL (0x1 << 7)
208#define MAX98927_AMP_VOL_SEL_WIDTH (1)
209#define MAX98927_AMP_VOL_SEL_SHIFT (7)
210#define MAX98927_AMP_VOL_MASK (0x7f << 0)
211#define MAX98927_AMP_VOL_WIDTH (7)
212#define MAX98927_AMP_VOL_SHIFT (0)
213
214/* MAX98927_R0037_AMP_DSP_CFG */
215#define MAX98927_AMP_DSP_CFG_DCBLK_EN (0x1 << 0)
216#define MAX98927_AMP_DSP_CFG_DITH_EN (0x1 << 1)
217#define MAX98927_AMP_DSP_CFG_RMP_BYPASS (0x1 << 4)
218#define MAX98927_AMP_DSP_CFG_DAC_INV (0x1 << 5)
219#define MAX98927_AMP_DSP_CFG_RMP_SHIFT (4)
220
221/* MAX98927_R0039_DRE_CTRL */
222#define MAX98927_DRE_CTRL_DRE_EN (0x1 << 0)
223#define MAX98927_DRE_EN_SHIFT 0x1
224
225/* MAX98927_R003A_AMP_EN */
226#define MAX98927_AMP_EN_MASK (0x1 << 0)
227
228/* MAX98927_R003B_SPK_SRC_SEL */
229#define MAX98927_SPK_SRC_MASK (0x3 << 0)
230
231/* MAX98927_R003C_SPK_GAIN */
232#define MAX98927_SPK_PCM_GAIN_MASK (0x7 << 0)
233#define MAX98927_SPK_PDM_GAIN_MASK (0x7 << 4)
234#define MAX98927_SPK_GAIN_WIDTH (3)
235
236/* MAX98927_R003E_MEAS_EN */
237#define MAX98927_MEAS_V_EN (0x1 << 0)
238#define MAX98927_MEAS_I_EN (0x1 << 1)
239
240/* MAX98927_R0040_BOOST_CTRL0 */
241#define MAX98927_BOOST_CTRL0_VOUT_MASK (0x1f << 0)
242#define MAX98927_BOOST_CTRL0_PVDD_MASK (0x1 << 7)
243#define MAX98927_BOOST_CTRL0_PVDD_EN_SHIFT (7)
244
245/* MAX98927_R0052_BROWNOUT_EN */
246#define MAX98927_BROWNOUT_BDE_EN (0x1 << 0)
247#define MAX98927_BROWNOUT_AMP_EN (0x1 << 1)
248#define MAX98927_BROWNOUT_DSP_EN (0x1 << 2)
249#define MAX98927_BROWNOUT_DSP_SHIFT (2)
250
251/* MAX98927_R0100_SOFT_RESET */
252#define MAX98927_SOFT_RESET (0x1 << 0)
253
254/* MAX98927_R00FF_GLOBAL_SHDN */
255#define MAX98927_GLOBAL_EN_MASK (0x1 << 0)
256
257struct max98927_priv {
258 struct regmap *regmap;
259 struct snd_soc_codec *codec;
260 struct max98927_pdata *pdata;
261 unsigned int spk_gain;
262 unsigned int sysclk;
263 unsigned int v_l_slot;
264 unsigned int i_l_slot;
265 bool interleave_mode;
266 unsigned int ch_size;
267 unsigned int rate;
268 unsigned int iface;
269 unsigned int master;
270 unsigned int digital_gain;
271};
272#endif
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c
index 9e8f0f4aa51a..c8bcb1db966d 100644
--- a/sound/soc/codecs/nau8540.c
+++ b/sound/soc/codecs/nau8540.c
@@ -39,147 +39,147 @@
39 39
40/* scaling for mclk from sysclk_src output */ 40/* scaling for mclk from sysclk_src output */
41static const struct nau8540_fll_attr mclk_src_scaling[] = { 41static const struct nau8540_fll_attr mclk_src_scaling[] = {
42 { 1, 0x0 }, 42 { 1, 0x0 },
43 { 2, 0x2 }, 43 { 2, 0x2 },
44 { 4, 0x3 }, 44 { 4, 0x3 },
45 { 8, 0x4 }, 45 { 8, 0x4 },
46 { 16, 0x5 }, 46 { 16, 0x5 },
47 { 32, 0x6 }, 47 { 32, 0x6 },
48 { 3, 0x7 }, 48 { 3, 0x7 },
49 { 6, 0xa }, 49 { 6, 0xa },
50 { 12, 0xb }, 50 { 12, 0xb },
51 { 24, 0xc }, 51 { 24, 0xc },
52}; 52};
53 53
54/* ratio for input clk freq */ 54/* ratio for input clk freq */
55static const struct nau8540_fll_attr fll_ratio[] = { 55static const struct nau8540_fll_attr fll_ratio[] = {
56 { 512000, 0x01 }, 56 { 512000, 0x01 },
57 { 256000, 0x02 }, 57 { 256000, 0x02 },
58 { 128000, 0x04 }, 58 { 128000, 0x04 },
59 { 64000, 0x08 }, 59 { 64000, 0x08 },
60 { 32000, 0x10 }, 60 { 32000, 0x10 },
61 { 8000, 0x20 }, 61 { 8000, 0x20 },
62 { 4000, 0x40 }, 62 { 4000, 0x40 },
63}; 63};
64 64
65static const struct nau8540_fll_attr fll_pre_scalar[] = { 65static const struct nau8540_fll_attr fll_pre_scalar[] = {
66 { 1, 0x0 }, 66 { 1, 0x0 },
67 { 2, 0x1 }, 67 { 2, 0x1 },
68 { 4, 0x2 }, 68 { 4, 0x2 },
69 { 8, 0x3 }, 69 { 8, 0x3 },
70}; 70};
71 71
72/* over sampling rate */ 72/* over sampling rate */
73static const struct nau8540_osr_attr osr_adc_sel[] = { 73static const struct nau8540_osr_attr osr_adc_sel[] = {
74 { 32, 3 }, /* OSR 32, SRC 1/8 */ 74 { 32, 3 }, /* OSR 32, SRC 1/8 */
75 { 64, 2 }, /* OSR 64, SRC 1/4 */ 75 { 64, 2 }, /* OSR 64, SRC 1/4 */
76 { 128, 1 }, /* OSR 128, SRC 1/2 */ 76 { 128, 1 }, /* OSR 128, SRC 1/2 */
77 { 256, 0 }, /* OSR 256, SRC 1 */ 77 { 256, 0 }, /* OSR 256, SRC 1 */
78}; 78};
79 79
80static const struct reg_default nau8540_reg_defaults[] = { 80static const struct reg_default nau8540_reg_defaults[] = {
81 {NAU8540_REG_POWER_MANAGEMENT, 0x0000}, 81 {NAU8540_REG_POWER_MANAGEMENT, 0x0000},
82 {NAU8540_REG_CLOCK_CTRL, 0x0000}, 82 {NAU8540_REG_CLOCK_CTRL, 0x0000},
83 {NAU8540_REG_CLOCK_SRC, 0x0000}, 83 {NAU8540_REG_CLOCK_SRC, 0x0000},
84 {NAU8540_REG_FLL1, 0x0001}, 84 {NAU8540_REG_FLL1, 0x0001},
85 {NAU8540_REG_FLL2, 0x3126}, 85 {NAU8540_REG_FLL2, 0x3126},
86 {NAU8540_REG_FLL3, 0x0008}, 86 {NAU8540_REG_FLL3, 0x0008},
87 {NAU8540_REG_FLL4, 0x0010}, 87 {NAU8540_REG_FLL4, 0x0010},
88 {NAU8540_REG_FLL5, 0xC000}, 88 {NAU8540_REG_FLL5, 0xC000},
89 {NAU8540_REG_FLL6, 0x6000}, 89 {NAU8540_REG_FLL6, 0x6000},
90 {NAU8540_REG_FLL_VCO_RSV, 0xF13C}, 90 {NAU8540_REG_FLL_VCO_RSV, 0xF13C},
91 {NAU8540_REG_PCM_CTRL0, 0x000B}, 91 {NAU8540_REG_PCM_CTRL0, 0x000B},
92 {NAU8540_REG_PCM_CTRL1, 0x3010}, 92 {NAU8540_REG_PCM_CTRL1, 0x3010},
93 {NAU8540_REG_PCM_CTRL2, 0x0800}, 93 {NAU8540_REG_PCM_CTRL2, 0x0800},
94 {NAU8540_REG_PCM_CTRL3, 0x0000}, 94 {NAU8540_REG_PCM_CTRL3, 0x0000},
95 {NAU8540_REG_PCM_CTRL4, 0x000F}, 95 {NAU8540_REG_PCM_CTRL4, 0x000F},
96 {NAU8540_REG_ALC_CONTROL_1, 0x0000}, 96 {NAU8540_REG_ALC_CONTROL_1, 0x0000},
97 {NAU8540_REG_ALC_CONTROL_2, 0x700B}, 97 {NAU8540_REG_ALC_CONTROL_2, 0x700B},
98 {NAU8540_REG_ALC_CONTROL_3, 0x0022}, 98 {NAU8540_REG_ALC_CONTROL_3, 0x0022},
99 {NAU8540_REG_ALC_CONTROL_4, 0x1010}, 99 {NAU8540_REG_ALC_CONTROL_4, 0x1010},
100 {NAU8540_REG_ALC_CONTROL_5, 0x1010}, 100 {NAU8540_REG_ALC_CONTROL_5, 0x1010},
101 {NAU8540_REG_NOTCH_FIL1_CH1, 0x0000}, 101 {NAU8540_REG_NOTCH_FIL1_CH1, 0x0000},
102 {NAU8540_REG_NOTCH_FIL2_CH1, 0x0000}, 102 {NAU8540_REG_NOTCH_FIL2_CH1, 0x0000},
103 {NAU8540_REG_NOTCH_FIL1_CH2, 0x0000}, 103 {NAU8540_REG_NOTCH_FIL1_CH2, 0x0000},
104 {NAU8540_REG_NOTCH_FIL2_CH2, 0x0000}, 104 {NAU8540_REG_NOTCH_FIL2_CH2, 0x0000},
105 {NAU8540_REG_NOTCH_FIL1_CH3, 0x0000}, 105 {NAU8540_REG_NOTCH_FIL1_CH3, 0x0000},
106 {NAU8540_REG_NOTCH_FIL2_CH3, 0x0000}, 106 {NAU8540_REG_NOTCH_FIL2_CH3, 0x0000},
107 {NAU8540_REG_NOTCH_FIL1_CH4, 0x0000}, 107 {NAU8540_REG_NOTCH_FIL1_CH4, 0x0000},
108 {NAU8540_REG_NOTCH_FIL2_CH4, 0x0000}, 108 {NAU8540_REG_NOTCH_FIL2_CH4, 0x0000},
109 {NAU8540_REG_HPF_FILTER_CH12, 0x0000}, 109 {NAU8540_REG_HPF_FILTER_CH12, 0x0000},
110 {NAU8540_REG_HPF_FILTER_CH34, 0x0000}, 110 {NAU8540_REG_HPF_FILTER_CH34, 0x0000},
111 {NAU8540_REG_ADC_SAMPLE_RATE, 0x0002}, 111 {NAU8540_REG_ADC_SAMPLE_RATE, 0x0002},
112 {NAU8540_REG_DIGITAL_GAIN_CH1, 0x0400}, 112 {NAU8540_REG_DIGITAL_GAIN_CH1, 0x0400},
113 {NAU8540_REG_DIGITAL_GAIN_CH2, 0x0400}, 113 {NAU8540_REG_DIGITAL_GAIN_CH2, 0x0400},
114 {NAU8540_REG_DIGITAL_GAIN_CH3, 0x0400}, 114 {NAU8540_REG_DIGITAL_GAIN_CH3, 0x0400},
115 {NAU8540_REG_DIGITAL_GAIN_CH4, 0x0400}, 115 {NAU8540_REG_DIGITAL_GAIN_CH4, 0x0400},
116 {NAU8540_REG_DIGITAL_MUX, 0x00E4}, 116 {NAU8540_REG_DIGITAL_MUX, 0x00E4},
117 {NAU8540_REG_GPIO_CTRL, 0x0000}, 117 {NAU8540_REG_GPIO_CTRL, 0x0000},
118 {NAU8540_REG_MISC_CTRL, 0x0000}, 118 {NAU8540_REG_MISC_CTRL, 0x0000},
119 {NAU8540_REG_I2C_CTRL, 0xEFFF}, 119 {NAU8540_REG_I2C_CTRL, 0xEFFF},
120 {NAU8540_REG_VMID_CTRL, 0x0000}, 120 {NAU8540_REG_VMID_CTRL, 0x0000},
121 {NAU8540_REG_MUTE, 0x0000}, 121 {NAU8540_REG_MUTE, 0x0000},
122 {NAU8540_REG_ANALOG_ADC1, 0x0011}, 122 {NAU8540_REG_ANALOG_ADC1, 0x0011},
123 {NAU8540_REG_ANALOG_ADC2, 0x0020}, 123 {NAU8540_REG_ANALOG_ADC2, 0x0020},
124 {NAU8540_REG_ANALOG_PWR, 0x0000}, 124 {NAU8540_REG_ANALOG_PWR, 0x0000},
125 {NAU8540_REG_MIC_BIAS, 0x0004}, 125 {NAU8540_REG_MIC_BIAS, 0x0004},
126 {NAU8540_REG_REFERENCE, 0x0000}, 126 {NAU8540_REG_REFERENCE, 0x0000},
127 {NAU8540_REG_FEPGA1, 0x0000}, 127 {NAU8540_REG_FEPGA1, 0x0000},
128 {NAU8540_REG_FEPGA2, 0x0000}, 128 {NAU8540_REG_FEPGA2, 0x0000},
129 {NAU8540_REG_FEPGA3, 0x0101}, 129 {NAU8540_REG_FEPGA3, 0x0101},
130 {NAU8540_REG_FEPGA4, 0x0101}, 130 {NAU8540_REG_FEPGA4, 0x0101},
131 {NAU8540_REG_PWR, 0x0000}, 131 {NAU8540_REG_PWR, 0x0000},
132}; 132};
133 133
134static bool nau8540_readable_reg(struct device *dev, unsigned int reg) 134static bool nau8540_readable_reg(struct device *dev, unsigned int reg)
135{ 135{
136 switch (reg) { 136 switch (reg) {
137 case NAU8540_REG_POWER_MANAGEMENT ... NAU8540_REG_FLL_VCO_RSV: 137 case NAU8540_REG_POWER_MANAGEMENT ... NAU8540_REG_FLL_VCO_RSV:
138 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4: 138 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:
139 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5: 139 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:
140 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ADC_SAMPLE_RATE: 140 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ADC_SAMPLE_RATE:
141 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX: 141 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:
142 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_I2C_CTRL: 142 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_I2C_CTRL:
143 case NAU8540_REG_I2C_DEVICE_ID: 143 case NAU8540_REG_I2C_DEVICE_ID:
144 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE: 144 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:
145 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR: 145 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:
146 return true; 146 return true;
147 default: 147 default:
148 return false; 148 return false;
149 } 149 }
150 150
151} 151}
152 152
153static bool nau8540_writeable_reg(struct device *dev, unsigned int reg) 153static bool nau8540_writeable_reg(struct device *dev, unsigned int reg)
154{ 154{
155 switch (reg) { 155 switch (reg) {
156 case NAU8540_REG_SW_RESET ... NAU8540_REG_FLL_VCO_RSV: 156 case NAU8540_REG_SW_RESET ... NAU8540_REG_FLL_VCO_RSV:
157 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4: 157 case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:
158 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5: 158 case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:
159 case NAU8540_REG_NOTCH_FIL1_CH1 ... NAU8540_REG_ADC_SAMPLE_RATE: 159 case NAU8540_REG_NOTCH_FIL1_CH1 ... NAU8540_REG_ADC_SAMPLE_RATE:
160 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX: 160 case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:
161 case NAU8540_REG_GPIO_CTRL ... NAU8540_REG_I2C_CTRL: 161 case NAU8540_REG_GPIO_CTRL ... NAU8540_REG_I2C_CTRL:
162 case NAU8540_REG_RST: 162 case NAU8540_REG_RST:
163 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE: 163 case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:
164 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR: 164 case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:
165 return true; 165 return true;
166 default: 166 default:
167 return false; 167 return false;
168 } 168 }
169} 169}
170 170
171static bool nau8540_volatile_reg(struct device *dev, unsigned int reg) 171static bool nau8540_volatile_reg(struct device *dev, unsigned int reg)
172{ 172{
173 switch (reg) { 173 switch (reg) {
174 case NAU8540_REG_SW_RESET: 174 case NAU8540_REG_SW_RESET:
175 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ALC_STATUS: 175 case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ALC_STATUS:
176 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_PEAK_CH4: 176 case NAU8540_REG_P2P_CH1 ... NAU8540_REG_PEAK_CH4:
177 case NAU8540_REG_I2C_DEVICE_ID: 177 case NAU8540_REG_I2C_DEVICE_ID:
178 case NAU8540_REG_RST: 178 case NAU8540_REG_RST:
179 return true; 179 return true;
180 default: 180 default:
181 return false; 181 return false;
182 } 182 }
183} 183}
184 184
185 185
@@ -187,255 +187,255 @@ static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -12800, 3600);
187static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600); 187static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600);
188 188
189static const struct snd_kcontrol_new nau8540_snd_controls[] = { 189static const struct snd_kcontrol_new nau8540_snd_controls[] = {
190 SOC_SINGLE_TLV("Mic1 Volume", NAU8540_REG_DIGITAL_GAIN_CH1, 190 SOC_SINGLE_TLV("Mic1 Volume", NAU8540_REG_DIGITAL_GAIN_CH1,
191 0, 0x520, 0, adc_vol_tlv), 191 0, 0x520, 0, adc_vol_tlv),
192 SOC_SINGLE_TLV("Mic2 Volume", NAU8540_REG_DIGITAL_GAIN_CH2, 192 SOC_SINGLE_TLV("Mic2 Volume", NAU8540_REG_DIGITAL_GAIN_CH2,
193 0, 0x520, 0, adc_vol_tlv), 193 0, 0x520, 0, adc_vol_tlv),
194 SOC_SINGLE_TLV("Mic3 Volume", NAU8540_REG_DIGITAL_GAIN_CH3, 194 SOC_SINGLE_TLV("Mic3 Volume", NAU8540_REG_DIGITAL_GAIN_CH3,
195 0, 0x520, 0, adc_vol_tlv), 195 0, 0x520, 0, adc_vol_tlv),
196 SOC_SINGLE_TLV("Mic4 Volume", NAU8540_REG_DIGITAL_GAIN_CH4, 196 SOC_SINGLE_TLV("Mic4 Volume", NAU8540_REG_DIGITAL_GAIN_CH4,
197 0, 0x520, 0, adc_vol_tlv), 197 0, 0x520, 0, adc_vol_tlv),
198 198
199 SOC_SINGLE_TLV("Frontend PGA1 Volume", NAU8540_REG_FEPGA3, 199 SOC_SINGLE_TLV("Frontend PGA1 Volume", NAU8540_REG_FEPGA3,
200 0, 0x25, 0, fepga_gain_tlv), 200 0, 0x25, 0, fepga_gain_tlv),
201 SOC_SINGLE_TLV("Frontend PGA2 Volume", NAU8540_REG_FEPGA3, 201 SOC_SINGLE_TLV("Frontend PGA2 Volume", NAU8540_REG_FEPGA3,
202 8, 0x25, 0, fepga_gain_tlv), 202 8, 0x25, 0, fepga_gain_tlv),
203 SOC_SINGLE_TLV("Frontend PGA3 Volume", NAU8540_REG_FEPGA4, 203 SOC_SINGLE_TLV("Frontend PGA3 Volume", NAU8540_REG_FEPGA4,
204 0, 0x25, 0, fepga_gain_tlv), 204 0, 0x25, 0, fepga_gain_tlv),
205 SOC_SINGLE_TLV("Frontend PGA4 Volume", NAU8540_REG_FEPGA4, 205 SOC_SINGLE_TLV("Frontend PGA4 Volume", NAU8540_REG_FEPGA4,
206 8, 0x25, 0, fepga_gain_tlv), 206 8, 0x25, 0, fepga_gain_tlv),
207}; 207};
208 208
209static const char * const adc_channel[] = { 209static const char * const adc_channel[] = {
210 "ADC channel 1", "ADC channel 2", "ADC channel 3", "ADC channel 4" 210 "ADC channel 1", "ADC channel 2", "ADC channel 3", "ADC channel 4"
211}; 211};
212static SOC_ENUM_SINGLE_DECL( 212static SOC_ENUM_SINGLE_DECL(
213 digital_ch4_enum, NAU8540_REG_DIGITAL_MUX, 6, adc_channel); 213 digital_ch4_enum, NAU8540_REG_DIGITAL_MUX, 6, adc_channel);
214 214
215static const struct snd_kcontrol_new digital_ch4_mux = 215static const struct snd_kcontrol_new digital_ch4_mux =
216 SOC_DAPM_ENUM("Digital CH4 Select", digital_ch4_enum); 216 SOC_DAPM_ENUM("Digital CH4 Select", digital_ch4_enum);
217 217
218static SOC_ENUM_SINGLE_DECL( 218static SOC_ENUM_SINGLE_DECL(
219 digital_ch3_enum, NAU8540_REG_DIGITAL_MUX, 4, adc_channel); 219 digital_ch3_enum, NAU8540_REG_DIGITAL_MUX, 4, adc_channel);
220 220
221static const struct snd_kcontrol_new digital_ch3_mux = 221static const struct snd_kcontrol_new digital_ch3_mux =
222 SOC_DAPM_ENUM("Digital CH3 Select", digital_ch3_enum); 222 SOC_DAPM_ENUM("Digital CH3 Select", digital_ch3_enum);
223 223
224static SOC_ENUM_SINGLE_DECL( 224static SOC_ENUM_SINGLE_DECL(
225 digital_ch2_enum, NAU8540_REG_DIGITAL_MUX, 2, adc_channel); 225 digital_ch2_enum, NAU8540_REG_DIGITAL_MUX, 2, adc_channel);
226 226
227static const struct snd_kcontrol_new digital_ch2_mux = 227static const struct snd_kcontrol_new digital_ch2_mux =
228 SOC_DAPM_ENUM("Digital CH2 Select", digital_ch2_enum); 228 SOC_DAPM_ENUM("Digital CH2 Select", digital_ch2_enum);
229 229
230static SOC_ENUM_SINGLE_DECL( 230static SOC_ENUM_SINGLE_DECL(
231 digital_ch1_enum, NAU8540_REG_DIGITAL_MUX, 0, adc_channel); 231 digital_ch1_enum, NAU8540_REG_DIGITAL_MUX, 0, adc_channel);
232 232
233static const struct snd_kcontrol_new digital_ch1_mux = 233static const struct snd_kcontrol_new digital_ch1_mux =
234 SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); 234 SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum);
235 235
236static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { 236static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = {
237 SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0), 237 SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0),
238 SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0), 238 SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0),
239 239
240 SND_SOC_DAPM_INPUT("MIC1"), 240 SND_SOC_DAPM_INPUT("MIC1"),
241 SND_SOC_DAPM_INPUT("MIC2"), 241 SND_SOC_DAPM_INPUT("MIC2"),
242 SND_SOC_DAPM_INPUT("MIC3"), 242 SND_SOC_DAPM_INPUT("MIC3"),
243 SND_SOC_DAPM_INPUT("MIC4"), 243 SND_SOC_DAPM_INPUT("MIC4"),
244 244
245 SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0), 245 SND_SOC_DAPM_PGA("Frontend PGA1", NAU8540_REG_PWR, 12, 0, NULL, 0),
246 SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0), 246 SND_SOC_DAPM_PGA("Frontend PGA2", NAU8540_REG_PWR, 13, 0, NULL, 0),
247 SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), 247 SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0),
248 SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), 248 SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0),
249 249
250 SND_SOC_DAPM_ADC("ADC1", NULL, 250 SND_SOC_DAPM_ADC("ADC1", NULL,
251 NAU8540_REG_POWER_MANAGEMENT, 0, 0), 251 NAU8540_REG_POWER_MANAGEMENT, 0, 0),
252 SND_SOC_DAPM_ADC("ADC2", NULL, 252 SND_SOC_DAPM_ADC("ADC2", NULL,
253 NAU8540_REG_POWER_MANAGEMENT, 1, 0), 253 NAU8540_REG_POWER_MANAGEMENT, 1, 0),
254 SND_SOC_DAPM_ADC("ADC3", NULL, 254 SND_SOC_DAPM_ADC("ADC3", NULL,
255 NAU8540_REG_POWER_MANAGEMENT, 2, 0), 255 NAU8540_REG_POWER_MANAGEMENT, 2, 0),
256 SND_SOC_DAPM_ADC("ADC4", NULL, 256 SND_SOC_DAPM_ADC("ADC4", NULL,
257 NAU8540_REG_POWER_MANAGEMENT, 3, 0), 257 NAU8540_REG_POWER_MANAGEMENT, 3, 0),
258 258
259 SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), 259 SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0),
260 SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), 260 SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0),
261 SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0), 261 SND_SOC_DAPM_PGA("ADC CH3", NAU8540_REG_ANALOG_PWR, 2, 0, NULL, 0),
262 SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0), 262 SND_SOC_DAPM_PGA("ADC CH4", NAU8540_REG_ANALOG_PWR, 3, 0, NULL, 0),
263 263
264 SND_SOC_DAPM_MUX("Digital CH4 Mux", 264 SND_SOC_DAPM_MUX("Digital CH4 Mux",
265 SND_SOC_NOPM, 0, 0, &digital_ch4_mux), 265 SND_SOC_NOPM, 0, 0, &digital_ch4_mux),
266 SND_SOC_DAPM_MUX("Digital CH3 Mux", 266 SND_SOC_DAPM_MUX("Digital CH3 Mux",
267 SND_SOC_NOPM, 0, 0, &digital_ch3_mux), 267 SND_SOC_NOPM, 0, 0, &digital_ch3_mux),
268 SND_SOC_DAPM_MUX("Digital CH2 Mux", 268 SND_SOC_DAPM_MUX("Digital CH2 Mux",
269 SND_SOC_NOPM, 0, 0, &digital_ch2_mux), 269 SND_SOC_NOPM, 0, 0, &digital_ch2_mux),
270 SND_SOC_DAPM_MUX("Digital CH1 Mux", 270 SND_SOC_DAPM_MUX("Digital CH1 Mux",
271 SND_SOC_NOPM, 0, 0, &digital_ch1_mux), 271 SND_SOC_NOPM, 0, 0, &digital_ch1_mux),
272 272
273 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), 273 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0),
274}; 274};
275 275
276static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { 276static const struct snd_soc_dapm_route nau8540_dapm_routes[] = {
277 {"Frontend PGA1", NULL, "MIC1"}, 277 {"Frontend PGA1", NULL, "MIC1"},
278 {"Frontend PGA2", NULL, "MIC2"}, 278 {"Frontend PGA2", NULL, "MIC2"},
279 {"Frontend PGA3", NULL, "MIC3"}, 279 {"Frontend PGA3", NULL, "MIC3"},
280 {"Frontend PGA4", NULL, "MIC4"}, 280 {"Frontend PGA4", NULL, "MIC4"},
281 281
282 {"ADC1", NULL, "Frontend PGA1"}, 282 {"ADC1", NULL, "Frontend PGA1"},
283 {"ADC2", NULL, "Frontend PGA2"}, 283 {"ADC2", NULL, "Frontend PGA2"},
284 {"ADC3", NULL, "Frontend PGA3"}, 284 {"ADC3", NULL, "Frontend PGA3"},
285 {"ADC4", NULL, "Frontend PGA4"}, 285 {"ADC4", NULL, "Frontend PGA4"},
286 286
287 {"ADC CH1", NULL, "ADC1"}, 287 {"ADC CH1", NULL, "ADC1"},
288 {"ADC CH2", NULL, "ADC2"}, 288 {"ADC CH2", NULL, "ADC2"},
289 {"ADC CH3", NULL, "ADC3"}, 289 {"ADC CH3", NULL, "ADC3"},
290 {"ADC CH4", NULL, "ADC4"}, 290 {"ADC CH4", NULL, "ADC4"},
291 291
292 {"ADC1", NULL, "MICBIAS1"}, 292 {"ADC1", NULL, "MICBIAS1"},
293 {"ADC2", NULL, "MICBIAS1"}, 293 {"ADC2", NULL, "MICBIAS1"},
294 {"ADC3", NULL, "MICBIAS2"}, 294 {"ADC3", NULL, "MICBIAS2"},
295 {"ADC4", NULL, "MICBIAS2"}, 295 {"ADC4", NULL, "MICBIAS2"},
296 296
297 {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"}, 297 {"Digital CH1 Mux", "ADC channel 1", "ADC CH1"},
298 {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"}, 298 {"Digital CH1 Mux", "ADC channel 2", "ADC CH2"},
299 {"Digital CH1 Mux", "ADC channel 3", "ADC CH3"}, 299 {"Digital CH1 Mux", "ADC channel 3", "ADC CH3"},
300 {"Digital CH1 Mux", "ADC channel 4", "ADC CH4"}, 300 {"Digital CH1 Mux", "ADC channel 4", "ADC CH4"},
301 301
302 {"Digital CH2 Mux", "ADC channel 1", "ADC CH1"}, 302 {"Digital CH2 Mux", "ADC channel 1", "ADC CH1"},
303 {"Digital CH2 Mux", "ADC channel 2", "ADC CH2"}, 303 {"Digital CH2 Mux", "ADC channel 2", "ADC CH2"},
304 {"Digital CH2 Mux", "ADC channel 3", "ADC CH3"}, 304 {"Digital CH2 Mux", "ADC channel 3", "ADC CH3"},
305 {"Digital CH2 Mux", "ADC channel 4", "ADC CH4"}, 305 {"Digital CH2 Mux", "ADC channel 4", "ADC CH4"},
306 306
307 {"Digital CH3 Mux", "ADC channel 1", "ADC CH1"}, 307 {"Digital CH3 Mux", "ADC channel 1", "ADC CH1"},
308 {"Digital CH3 Mux", "ADC channel 2", "ADC CH2"}, 308 {"Digital CH3 Mux", "ADC channel 2", "ADC CH2"},
309 {"Digital CH3 Mux", "ADC channel 3", "ADC CH3"}, 309 {"Digital CH3 Mux", "ADC channel 3", "ADC CH3"},
310 {"Digital CH3 Mux", "ADC channel 4", "ADC CH4"}, 310 {"Digital CH3 Mux", "ADC channel 4", "ADC CH4"},
311 311
312 {"Digital CH4 Mux", "ADC channel 1", "ADC CH1"}, 312 {"Digital CH4 Mux", "ADC channel 1", "ADC CH1"},
313 {"Digital CH4 Mux", "ADC channel 2", "ADC CH2"}, 313 {"Digital CH4 Mux", "ADC channel 2", "ADC CH2"},
314 {"Digital CH4 Mux", "ADC channel 3", "ADC CH3"}, 314 {"Digital CH4 Mux", "ADC channel 3", "ADC CH3"},
315 {"Digital CH4 Mux", "ADC channel 4", "ADC CH4"}, 315 {"Digital CH4 Mux", "ADC channel 4", "ADC CH4"},
316 316
317 {"AIFTX", NULL, "Digital CH1 Mux"}, 317 {"AIFTX", NULL, "Digital CH1 Mux"},
318 {"AIFTX", NULL, "Digital CH2 Mux"}, 318 {"AIFTX", NULL, "Digital CH2 Mux"},
319 {"AIFTX", NULL, "Digital CH3 Mux"}, 319 {"AIFTX", NULL, "Digital CH3 Mux"},
320 {"AIFTX", NULL, "Digital CH4 Mux"}, 320 {"AIFTX", NULL, "Digital CH4 Mux"},
321}; 321};
322 322
323static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr) 323static int nau8540_clock_check(struct nau8540 *nau8540, int rate, int osr)
324{ 324{
325 int osrate; 325 int osrate;
326 326
327 if (osr >= ARRAY_SIZE(osr_adc_sel)) 327 if (osr >= ARRAY_SIZE(osr_adc_sel))
328 return -EINVAL; 328 return -EINVAL;
329 osrate = osr_adc_sel[osr].osr; 329 osrate = osr_adc_sel[osr].osr;
330 330
331 if (rate * osr > CLK_ADC_MAX) { 331 if (rate * osr > CLK_ADC_MAX) {
332 dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n"); 332 dev_err(nau8540->dev, "exceed the maximum frequency of CLK_ADC\n");
333 return -EINVAL; 333 return -EINVAL;
334 } 334 }
335 335
336 return 0; 336 return 0;
337} 337}
338 338
339static int nau8540_hw_params(struct snd_pcm_substream *substream, 339static int nau8540_hw_params(struct snd_pcm_substream *substream,
340 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 340 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
341{ 341{
342 struct snd_soc_codec *codec = dai->codec; 342 struct snd_soc_codec *codec = dai->codec;
343 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 343 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
344 unsigned int val_len = 0, osr; 344 unsigned int val_len = 0, osr;
345 345
346 /* CLK_ADC = OSR * FS 346 /* CLK_ADC = OSR * FS
347 * ADC clock frequency is defined as Over Sampling Rate (OSR) 347 * ADC clock frequency is defined as Over Sampling Rate (OSR)
348 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs 348 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs
349 * values must be selected such that the maximum frequency is less 349 * values must be selected such that the maximum frequency is less
350 * than 6.144 MHz. 350 * than 6.144 MHz.
351 */ 351 */
352 regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr); 352 regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);
353 osr &= NAU8540_ADC_OSR_MASK; 353 osr &= NAU8540_ADC_OSR_MASK;
354 if (nau8540_clock_check(nau8540, params_rate(params), osr)) 354 if (nau8540_clock_check(nau8540, params_rate(params), osr))
355 return -EINVAL; 355 return -EINVAL;
356 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 356 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
357 NAU8540_CLK_ADC_SRC_MASK, 357 NAU8540_CLK_ADC_SRC_MASK,
358 osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT); 358 osr_adc_sel[osr].clk_src << NAU8540_CLK_ADC_SRC_SFT);
359 359
360 switch (params_width(params)) { 360 switch (params_width(params)) {
361 case 16: 361 case 16:
362 val_len |= NAU8540_I2S_DL_16; 362 val_len |= NAU8540_I2S_DL_16;
363 break; 363 break;
364 case 20: 364 case 20:
365 val_len |= NAU8540_I2S_DL_20; 365 val_len |= NAU8540_I2S_DL_20;
366 break; 366 break;
367 case 24: 367 case 24:
368 val_len |= NAU8540_I2S_DL_24; 368 val_len |= NAU8540_I2S_DL_24;
369 break; 369 break;
370 case 32: 370 case 32:
371 val_len |= NAU8540_I2S_DL_32; 371 val_len |= NAU8540_I2S_DL_32;
372 break; 372 break;
373 default: 373 default:
374 return -EINVAL; 374 return -EINVAL;
375 } 375 }
376 376
377 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0, 377 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,
378 NAU8540_I2S_DL_MASK, val_len); 378 NAU8540_I2S_DL_MASK, val_len);
379 379
380 return 0; 380 return 0;
381} 381}
382 382
383static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 383static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
384{ 384{
385 struct snd_soc_codec *codec = dai->codec; 385 struct snd_soc_codec *codec = dai->codec;
386 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 386 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
387 unsigned int ctrl1_val = 0, ctrl2_val = 0; 387 unsigned int ctrl1_val = 0, ctrl2_val = 0;
388 388
389 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 389 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
390 case SND_SOC_DAIFMT_CBM_CFM: 390 case SND_SOC_DAIFMT_CBM_CFM:
391 ctrl2_val |= NAU8540_I2S_MS_MASTER; 391 ctrl2_val |= NAU8540_I2S_MS_MASTER;
392 break; 392 break;
393 case SND_SOC_DAIFMT_CBS_CFS: 393 case SND_SOC_DAIFMT_CBS_CFS:
394 break; 394 break;
395 default: 395 default:
396 return -EINVAL; 396 return -EINVAL;
397 } 397 }
398 398
399 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 399 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
400 case SND_SOC_DAIFMT_NB_NF: 400 case SND_SOC_DAIFMT_NB_NF:
401 break; 401 break;
402 case SND_SOC_DAIFMT_IB_NF: 402 case SND_SOC_DAIFMT_IB_NF:
403 ctrl1_val |= NAU8540_I2S_BP_INV; 403 ctrl1_val |= NAU8540_I2S_BP_INV;
404 break; 404 break;
405 default: 405 default:
406 return -EINVAL; 406 return -EINVAL;
407 } 407 }
408 408
409 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 409 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
410 case SND_SOC_DAIFMT_I2S: 410 case SND_SOC_DAIFMT_I2S:
411 ctrl1_val |= NAU8540_I2S_DF_I2S; 411 ctrl1_val |= NAU8540_I2S_DF_I2S;
412 break; 412 break;
413 case SND_SOC_DAIFMT_LEFT_J: 413 case SND_SOC_DAIFMT_LEFT_J:
414 ctrl1_val |= NAU8540_I2S_DF_LEFT; 414 ctrl1_val |= NAU8540_I2S_DF_LEFT;
415 break; 415 break;
416 case SND_SOC_DAIFMT_RIGHT_J: 416 case SND_SOC_DAIFMT_RIGHT_J:
417 ctrl1_val |= NAU8540_I2S_DF_RIGTH; 417 ctrl1_val |= NAU8540_I2S_DF_RIGTH;
418 break; 418 break;
419 case SND_SOC_DAIFMT_DSP_A: 419 case SND_SOC_DAIFMT_DSP_A:
420 ctrl1_val |= NAU8540_I2S_DF_PCM_AB; 420 ctrl1_val |= NAU8540_I2S_DF_PCM_AB;
421 break; 421 break;
422 case SND_SOC_DAIFMT_DSP_B: 422 case SND_SOC_DAIFMT_DSP_B:
423 ctrl1_val |= NAU8540_I2S_DF_PCM_AB; 423 ctrl1_val |= NAU8540_I2S_DF_PCM_AB;
424 ctrl1_val |= NAU8540_I2S_PCMB_EN; 424 ctrl1_val |= NAU8540_I2S_PCMB_EN;
425 break; 425 break;
426 default: 426 default:
427 return -EINVAL; 427 return -EINVAL;
428 } 428 }
429 429
430 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0, 430 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,
431 NAU8540_I2S_DL_MASK | NAU8540_I2S_DF_MASK | 431 NAU8540_I2S_DL_MASK | NAU8540_I2S_DF_MASK |
432 NAU8540_I2S_BP_INV | NAU8540_I2S_PCMB_EN, ctrl1_val); 432 NAU8540_I2S_BP_INV | NAU8540_I2S_PCMB_EN, ctrl1_val);
433 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, 433 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,
434 NAU8540_I2S_MS_MASK | NAU8540_I2S_DO12_OE, ctrl2_val); 434 NAU8540_I2S_MS_MASK | NAU8540_I2S_DO12_OE, ctrl2_val);
435 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, 435 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,
436 NAU8540_I2S_DO34_OE, 0); 436 NAU8540_I2S_DO34_OE, 0);
437 437
438 return 0; 438 return 0;
439} 439}
440 440
441/** 441/**
@@ -451,55 +451,55 @@ static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
451 * Configures a DAI for TDM operation. Only support 4 slots TDM. 451 * Configures a DAI for TDM operation. Only support 4 slots TDM.
452 */ 452 */
453static int nau8540_set_tdm_slot(struct snd_soc_dai *dai, 453static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,
454 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 454 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
455{ 455{
456 struct snd_soc_codec *codec = dai->codec; 456 struct snd_soc_codec *codec = dai->codec;
457 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 457 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
458 unsigned int ctrl2_val = 0, ctrl4_val = 0; 458 unsigned int ctrl2_val = 0, ctrl4_val = 0;
459 459
460 if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf))) 460 if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)))
461 return -EINVAL; 461 return -EINVAL;
462 462
463 ctrl4_val |= (NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN); 463 ctrl4_val |= (NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN);
464 if (tx_mask & 0xf0) { 464 if (tx_mask & 0xf0) {
465 ctrl2_val = 4 * slot_width; 465 ctrl2_val = 4 * slot_width;
466 ctrl4_val |= (tx_mask >> 4); 466 ctrl4_val |= (tx_mask >> 4);
467 } else { 467 } else {
468 ctrl4_val |= tx_mask; 468 ctrl4_val |= tx_mask;
469 } 469 }
470 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL4, 470 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL4,
471 NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN | 471 NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN |
472 NAU8540_TDM_TX_MASK, ctrl4_val); 472 NAU8540_TDM_TX_MASK, ctrl4_val);
473 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, 473 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,
474 NAU8540_I2S_DO12_OE, NAU8540_I2S_DO12_OE); 474 NAU8540_I2S_DO12_OE, NAU8540_I2S_DO12_OE);
475 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, 475 regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,
476 NAU8540_I2S_DO34_OE | NAU8540_I2S_TSLOT_L_MASK, 476 NAU8540_I2S_DO34_OE | NAU8540_I2S_TSLOT_L_MASK,
477 NAU8540_I2S_DO34_OE | ctrl2_val); 477 NAU8540_I2S_DO34_OE | ctrl2_val);
478 478
479 return 0; 479 return 0;
480} 480}
481 481
482 482
483static const struct snd_soc_dai_ops nau8540_dai_ops = { 483static const struct snd_soc_dai_ops nau8540_dai_ops = {
484 .hw_params = nau8540_hw_params, 484 .hw_params = nau8540_hw_params,
485 .set_fmt = nau8540_set_fmt, 485 .set_fmt = nau8540_set_fmt,
486 .set_tdm_slot = nau8540_set_tdm_slot, 486 .set_tdm_slot = nau8540_set_tdm_slot,
487}; 487};
488 488
489#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000 489#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000
490#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ 490#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
491 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 491 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
492 492
493static struct snd_soc_dai_driver nau8540_dai = { 493static struct snd_soc_dai_driver nau8540_dai = {
494 .name = "nau8540-hifi", 494 .name = "nau8540-hifi",
495 .capture = { 495 .capture = {
496 .stream_name = "Capture", 496 .stream_name = "Capture",
497 .channels_min = 1, 497 .channels_min = 1,
498 .channels_max = 4, 498 .channels_max = 4,
499 .rates = NAU8540_RATES, 499 .rates = NAU8540_RATES,
500 .formats = NAU8540_FORMATS, 500 .formats = NAU8540_FORMATS,
501 }, 501 },
502 .ops = &nau8540_dai_ops, 502 .ops = &nau8540_dai_ops,
503}; 503};
504 504
505/** 505/**
@@ -513,320 +513,320 @@ static struct snd_soc_dai_driver nau8540_dai = {
513 * Returns 0 for success or negative error code. 513 * Returns 0 for success or negative error code.
514 */ 514 */
515static int nau8540_calc_fll_param(unsigned int fll_in, 515static int nau8540_calc_fll_param(unsigned int fll_in,
516 unsigned int fs, struct nau8540_fll *fll_param) 516 unsigned int fs, struct nau8540_fll *fll_param)
517{ 517{
518 u64 fvco, fvco_max; 518 u64 fvco, fvco_max;
519 unsigned int fref, i, fvco_sel; 519 unsigned int fref, i, fvco_sel;
520 520
521 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing 521 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
522 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar. 522 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
523 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK 523 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK
524 */ 524 */
525 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) { 525 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
526 fref = fll_in / fll_pre_scalar[i].param; 526 fref = fll_in / fll_pre_scalar[i].param;
527 if (fref <= NAU_FREF_MAX) 527 if (fref <= NAU_FREF_MAX)
528 break; 528 break;
529 } 529 }
530 if (i == ARRAY_SIZE(fll_pre_scalar)) 530 if (i == ARRAY_SIZE(fll_pre_scalar))
531 return -EINVAL; 531 return -EINVAL;
532 fll_param->clk_ref_div = fll_pre_scalar[i].val; 532 fll_param->clk_ref_div = fll_pre_scalar[i].val;
533 533
534 /* Choose the FLL ratio based on FREF */ 534 /* Choose the FLL ratio based on FREF */
535 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) { 535 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
536 if (fref >= fll_ratio[i].param) 536 if (fref >= fll_ratio[i].param)
537 break; 537 break;
538 } 538 }
539 if (i == ARRAY_SIZE(fll_ratio)) 539 if (i == ARRAY_SIZE(fll_ratio))
540 return -EINVAL; 540 return -EINVAL;
541 fll_param->ratio = fll_ratio[i].val; 541 fll_param->ratio = fll_ratio[i].val;
542 542
543 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. 543 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
544 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be 544 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
545 * guaranteed across the full range of operation. 545 * guaranteed across the full range of operation.
546 * FDCO = freq_out * 2 * mclk_src_scaling 546 * FDCO = freq_out * 2 * mclk_src_scaling
547 */ 547 */
548 fvco_max = 0; 548 fvco_max = 0;
549 fvco_sel = ARRAY_SIZE(mclk_src_scaling); 549 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
550 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 550 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
551 fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 551 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
552 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX && 552 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
553 fvco_max < fvco) { 553 fvco_max < fvco) {
554 fvco_max = fvco; 554 fvco_max = fvco;
555 fvco_sel = i; 555 fvco_sel = i;
556 } 556 }
557 } 557 }
558 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel) 558 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
559 return -EINVAL; 559 return -EINVAL;
560 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val; 560 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
561 561
562 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 562 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
563 * input based on FDCO, FREF and FLL ratio. 563 * input based on FDCO, FREF and FLL ratio.
564 */ 564 */
565 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); 565 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
566 fll_param->fll_int = (fvco >> 16) & 0x3FF; 566 fll_param->fll_int = (fvco >> 16) & 0x3FF;
567 fll_param->fll_frac = fvco & 0xFFFF; 567 fll_param->fll_frac = fvco & 0xFFFF;
568 return 0; 568 return 0;
569} 569}
570 570
571static void nau8540_fll_apply(struct regmap *regmap, 571static void nau8540_fll_apply(struct regmap *regmap,
572 struct nau8540_fll *fll_param) 572 struct nau8540_fll *fll_param)
573{ 573{
574 regmap_update_bits(regmap, NAU8540_REG_CLOCK_SRC, 574 regmap_update_bits(regmap, NAU8540_REG_CLOCK_SRC,
575 NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK, 575 NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK,
576 NAU8540_CLK_SRC_MCLK | fll_param->mclk_src); 576 NAU8540_CLK_SRC_MCLK | fll_param->mclk_src);
577 regmap_update_bits(regmap, NAU8540_REG_FLL1, 577 regmap_update_bits(regmap, NAU8540_REG_FLL1,
578 NAU8540_FLL_RATIO_MASK, fll_param->ratio); 578 NAU8540_FLL_RATIO_MASK, fll_param->ratio);
579 /* FLL 16-bit fractional input */ 579 /* FLL 16-bit fractional input */
580 regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac); 580 regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac);
581 /* FLL 10-bit integer input */ 581 /* FLL 10-bit integer input */
582 regmap_update_bits(regmap, NAU8540_REG_FLL3, 582 regmap_update_bits(regmap, NAU8540_REG_FLL3,
583 NAU8540_FLL_INTEGER_MASK, fll_param->fll_int); 583 NAU8540_FLL_INTEGER_MASK, fll_param->fll_int);
584 /* FLL pre-scaler */ 584 /* FLL pre-scaler */
585 regmap_update_bits(regmap, NAU8540_REG_FLL4, 585 regmap_update_bits(regmap, NAU8540_REG_FLL4,
586 NAU8540_FLL_REF_DIV_MASK, 586 NAU8540_FLL_REF_DIV_MASK,
587 fll_param->clk_ref_div << NAU8540_FLL_REF_DIV_SFT); 587 fll_param->clk_ref_div << NAU8540_FLL_REF_DIV_SFT);
588 regmap_update_bits(regmap, NAU8540_REG_FLL5, 588 regmap_update_bits(regmap, NAU8540_REG_FLL5,
589 NAU8540_FLL_CLK_SW_MASK, NAU8540_FLL_CLK_SW_REF); 589 NAU8540_FLL_CLK_SW_MASK, NAU8540_FLL_CLK_SW_REF);
590 regmap_update_bits(regmap, 590 regmap_update_bits(regmap,
591 NAU8540_REG_FLL6, NAU8540_DCO_EN, 0); 591 NAU8540_REG_FLL6, NAU8540_DCO_EN, 0);
592 if (fll_param->fll_frac) { 592 if (fll_param->fll_frac) {
593 regmap_update_bits(regmap, NAU8540_REG_FLL5, 593 regmap_update_bits(regmap, NAU8540_REG_FLL5,
594 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 594 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
595 NAU8540_FLL_FTR_SW_MASK, 595 NAU8540_FLL_FTR_SW_MASK,
596 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 596 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
597 NAU8540_FLL_FTR_SW_FILTER); 597 NAU8540_FLL_FTR_SW_FILTER);
598 regmap_update_bits(regmap, NAU8540_REG_FLL6, 598 regmap_update_bits(regmap, NAU8540_REG_FLL6,
599 NAU8540_SDM_EN, NAU8540_SDM_EN); 599 NAU8540_SDM_EN, NAU8540_SDM_EN);
600 } else { 600 } else {
601 regmap_update_bits(regmap, NAU8540_REG_FLL5, 601 regmap_update_bits(regmap, NAU8540_REG_FLL5,
602 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | 602 NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |
603 NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU); 603 NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU);
604 regmap_update_bits(regmap, 604 regmap_update_bits(regmap,
605 NAU8540_REG_FLL6, NAU8540_SDM_EN, 0); 605 NAU8540_REG_FLL6, NAU8540_SDM_EN, 0);
606 } 606 }
607} 607}
608 608
609/* freq_out must be 256*Fs in order to achieve the best performance */ 609/* freq_out must be 256*Fs in order to achieve the best performance */
610static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 610static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
611 unsigned int freq_in, unsigned int freq_out) 611 unsigned int freq_in, unsigned int freq_out)
612{ 612{
613 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 613 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
614 struct nau8540_fll fll_param; 614 struct nau8540_fll fll_param;
615 int ret, fs; 615 int ret, fs;
616 616
617 switch (pll_id) { 617 switch (pll_id) {
618 case NAU8540_CLK_FLL_MCLK: 618 case NAU8540_CLK_FLL_MCLK:
619 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 619 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
620 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_MCLK); 620 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_MCLK);
621 break; 621 break;
622 622
623 case NAU8540_CLK_FLL_BLK: 623 case NAU8540_CLK_FLL_BLK:
624 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 624 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
625 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_BLK); 625 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_BLK);
626 break; 626 break;
627 627
628 case NAU8540_CLK_FLL_FS: 628 case NAU8540_CLK_FLL_FS:
629 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, 629 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,
630 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_FS); 630 NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_FS);
631 break; 631 break;
632 632
633 default: 633 default:
634 dev_err(nau8540->dev, "Invalid clock id (%d)\n", pll_id); 634 dev_err(nau8540->dev, "Invalid clock id (%d)\n", pll_id);
635 return -EINVAL; 635 return -EINVAL;
636 } 636 }
637 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n", 637 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",
638 freq_out, pll_id); 638 freq_out, pll_id);
639 639
640 fs = freq_out / 256; 640 fs = freq_out / 256;
641 ret = nau8540_calc_fll_param(freq_in, fs, &fll_param); 641 ret = nau8540_calc_fll_param(freq_in, fs, &fll_param);
642 if (ret < 0) { 642 if (ret < 0) {
643 dev_err(nau8540->dev, "Unsupported input clock %d\n", freq_in); 643 dev_err(nau8540->dev, "Unsupported input clock %d\n", freq_in);
644 return ret; 644 return ret;
645 } 645 }
646 dev_dbg(nau8540->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n", 646 dev_dbg(nau8540->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
647 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac, 647 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
648 fll_param.fll_int, fll_param.clk_ref_div); 648 fll_param.fll_int, fll_param.clk_ref_div);
649 649
650 nau8540_fll_apply(nau8540->regmap, &fll_param); 650 nau8540_fll_apply(nau8540->regmap, &fll_param);
651 mdelay(2); 651 mdelay(2);
652 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 652 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
653 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO); 653 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);
654 654
655 return 0; 655 return 0;
656} 656}
657 657
658static int nau8540_set_sysclk(struct snd_soc_codec *codec, 658static int nau8540_set_sysclk(struct snd_soc_codec *codec,
659 int clk_id, int source, unsigned int freq, int dir) 659 int clk_id, int source, unsigned int freq, int dir)
660{ 660{
661 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 661 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
662 662
663 switch (clk_id) { 663 switch (clk_id) {
664 case NAU8540_CLK_DIS: 664 case NAU8540_CLK_DIS:
665 case NAU8540_CLK_MCLK: 665 case NAU8540_CLK_MCLK:
666 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 666 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
667 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_MCLK); 667 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_MCLK);
668 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6, 668 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,
669 NAU8540_DCO_EN, 0); 669 NAU8540_DCO_EN, 0);
670 break; 670 break;
671 671
672 case NAU8540_CLK_INTERNAL: 672 case NAU8540_CLK_INTERNAL:
673 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6, 673 regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,
674 NAU8540_DCO_EN, NAU8540_DCO_EN); 674 NAU8540_DCO_EN, NAU8540_DCO_EN);
675 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC, 675 regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,
676 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO); 676 NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);
677 break; 677 break;
678 678
679 default: 679 default:
680 dev_err(nau8540->dev, "Invalid clock id (%d)\n", clk_id); 680 dev_err(nau8540->dev, "Invalid clock id (%d)\n", clk_id);
681 return -EINVAL; 681 return -EINVAL;
682 } 682 }
683 683
684 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n", 684 dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",
685 freq, clk_id); 685 freq, clk_id);
686 686
687 return 0; 687 return 0;
688} 688}
689 689
690static void nau8540_reset_chip(struct regmap *regmap) 690static void nau8540_reset_chip(struct regmap *regmap)
691{ 691{
692 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00); 692 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);
693 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00); 693 regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);
694} 694}
695 695
696static void nau8540_init_regs(struct nau8540 *nau8540) 696static void nau8540_init_regs(struct nau8540 *nau8540)
697{ 697{
698 struct regmap *regmap = nau8540->regmap; 698 struct regmap *regmap = nau8540->regmap;
699 699
700 /* Enable Bias/VMID/VMID Tieoff */ 700 /* Enable Bias/VMID/VMID Tieoff */
701 regmap_update_bits(regmap, NAU8540_REG_VMID_CTRL, 701 regmap_update_bits(regmap, NAU8540_REG_VMID_CTRL,
702 NAU8540_VMID_EN | NAU8540_VMID_SEL_MASK, 702 NAU8540_VMID_EN | NAU8540_VMID_SEL_MASK,
703 NAU8540_VMID_EN | (0x2 << NAU8540_VMID_SEL_SFT)); 703 NAU8540_VMID_EN | (0x2 << NAU8540_VMID_SEL_SFT));
704 regmap_update_bits(regmap, NAU8540_REG_REFERENCE, 704 regmap_update_bits(regmap, NAU8540_REG_REFERENCE,
705 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN, 705 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN,
706 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN); 706 NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN);
707 mdelay(2); 707 mdelay(2);
708 regmap_update_bits(regmap, NAU8540_REG_MIC_BIAS, 708 regmap_update_bits(regmap, NAU8540_REG_MIC_BIAS,
709 NAU8540_PU_PRE, NAU8540_PU_PRE); 709 NAU8540_PU_PRE, NAU8540_PU_PRE);
710 regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, 710 regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,
711 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN, 711 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN,
712 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN); 712 NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN);
713 /* ADC OSR selection, CLK_ADC = Fs * OSR */ 713 /* ADC OSR selection, CLK_ADC = Fs * OSR */
714 regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE, 714 regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE,
715 NAU8540_ADC_OSR_MASK, NAU8540_ADC_OSR_64); 715 NAU8540_ADC_OSR_MASK, NAU8540_ADC_OSR_64);
716} 716}
717 717
718static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec) 718static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec)
719{ 719{
720 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 720 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
721 721
722 regcache_cache_only(nau8540->regmap, true); 722 regcache_cache_only(nau8540->regmap, true);
723 regcache_mark_dirty(nau8540->regmap); 723 regcache_mark_dirty(nau8540->regmap);
724 724
725 return 0; 725 return 0;
726} 726}
727 727
728static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec) 728static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
729{ 729{
730 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); 730 struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec);
731 731
732 regcache_cache_only(nau8540->regmap, false); 732 regcache_cache_only(nau8540->regmap, false);
733 regcache_sync(nau8540->regmap); 733 regcache_sync(nau8540->regmap);
734 734
735 return 0; 735 return 0;
736} 736}
737 737
738static struct snd_soc_codec_driver nau8540_codec_driver = { 738static struct snd_soc_codec_driver nau8540_codec_driver = {
739 .set_sysclk = nau8540_set_sysclk, 739 .set_sysclk = nau8540_set_sysclk,
740 .set_pll = nau8540_set_pll, 740 .set_pll = nau8540_set_pll,
741 .suspend = nau8540_suspend, 741 .suspend = nau8540_suspend,
742 .resume = nau8540_resume, 742 .resume = nau8540_resume,
743 .suspend_bias_off = true, 743 .suspend_bias_off = true,
744 744
745 .component_driver = { 745 .component_driver = {
746 .controls = nau8540_snd_controls, 746 .controls = nau8540_snd_controls,
747 .num_controls = ARRAY_SIZE(nau8540_snd_controls), 747 .num_controls = ARRAY_SIZE(nau8540_snd_controls),
748 .dapm_widgets = nau8540_dapm_widgets, 748 .dapm_widgets = nau8540_dapm_widgets,
749 .num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets), 749 .num_dapm_widgets = ARRAY_SIZE(nau8540_dapm_widgets),
750 .dapm_routes = nau8540_dapm_routes, 750 .dapm_routes = nau8540_dapm_routes,
751 .num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes), 751 .num_dapm_routes = ARRAY_SIZE(nau8540_dapm_routes),
752 }, 752 },
753}; 753};
754 754
755static const struct regmap_config nau8540_regmap_config = { 755static const struct regmap_config nau8540_regmap_config = {
756 .val_bits = 16, 756 .val_bits = 16,
757 .reg_bits = 16, 757 .reg_bits = 16,
758 758
759 .max_register = NAU8540_REG_MAX, 759 .max_register = NAU8540_REG_MAX,
760 .readable_reg = nau8540_readable_reg, 760 .readable_reg = nau8540_readable_reg,
761 .writeable_reg = nau8540_writeable_reg, 761 .writeable_reg = nau8540_writeable_reg,
762 .volatile_reg = nau8540_volatile_reg, 762 .volatile_reg = nau8540_volatile_reg,
763 763
764 .cache_type = REGCACHE_RBTREE, 764 .cache_type = REGCACHE_RBTREE,
765 .reg_defaults = nau8540_reg_defaults, 765 .reg_defaults = nau8540_reg_defaults,
766 .num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults), 766 .num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults),
767}; 767};
768 768
769static int nau8540_i2c_probe(struct i2c_client *i2c, 769static int nau8540_i2c_probe(struct i2c_client *i2c,
770 const struct i2c_device_id *id) 770 const struct i2c_device_id *id)
771{ 771{
772 struct device *dev = &i2c->dev; 772 struct device *dev = &i2c->dev;
773 struct nau8540 *nau8540 = dev_get_platdata(dev); 773 struct nau8540 *nau8540 = dev_get_platdata(dev);
774 int ret, value; 774 int ret, value;
775 775
776 if (!nau8540) { 776 if (!nau8540) {
777 nau8540 = devm_kzalloc(dev, sizeof(*nau8540), GFP_KERNEL); 777 nau8540 = devm_kzalloc(dev, sizeof(*nau8540), GFP_KERNEL);
778 if (!nau8540) 778 if (!nau8540)
779 return -ENOMEM; 779 return -ENOMEM;
780 } 780 }
781 i2c_set_clientdata(i2c, nau8540); 781 i2c_set_clientdata(i2c, nau8540);
782 782
783 nau8540->regmap = devm_regmap_init_i2c(i2c, &nau8540_regmap_config); 783 nau8540->regmap = devm_regmap_init_i2c(i2c, &nau8540_regmap_config);
784 if (IS_ERR(nau8540->regmap)) 784 if (IS_ERR(nau8540->regmap))
785 return PTR_ERR(nau8540->regmap); 785 return PTR_ERR(nau8540->regmap);
786 ret = regmap_read(nau8540->regmap, NAU8540_REG_I2C_DEVICE_ID, &value); 786 ret = regmap_read(nau8540->regmap, NAU8540_REG_I2C_DEVICE_ID, &value);
787 if (ret < 0) { 787 if (ret < 0) {
788 dev_err(dev, "Failed to read device id from the NAU85L40: %d\n", 788 dev_err(dev, "Failed to read device id from the NAU85L40: %d\n",
789 ret); 789 ret);
790 return ret; 790 return ret;
791 } 791 }
792 792
793 nau8540->dev = dev; 793 nau8540->dev = dev;
794 nau8540_reset_chip(nau8540->regmap); 794 nau8540_reset_chip(nau8540->regmap);
795 nau8540_init_regs(nau8540); 795 nau8540_init_regs(nau8540);
796 796
797 return snd_soc_register_codec(dev, 797 return snd_soc_register_codec(dev,
798 &nau8540_codec_driver, &nau8540_dai, 1); 798 &nau8540_codec_driver, &nau8540_dai, 1);
799} 799}
800 800
801static int nau8540_i2c_remove(struct i2c_client *client) 801static int nau8540_i2c_remove(struct i2c_client *client)
802{ 802{
803 snd_soc_unregister_codec(&client->dev); 803 snd_soc_unregister_codec(&client->dev);
804 return 0; 804 return 0;
805} 805}
806 806
807 807
808static const struct i2c_device_id nau8540_i2c_ids[] = { 808static const struct i2c_device_id nau8540_i2c_ids[] = {
809 { "nau8540", 0 }, 809 { "nau8540", 0 },
810 { } 810 { }
811}; 811};
812MODULE_DEVICE_TABLE(i2c, nau8540_i2c_ids); 812MODULE_DEVICE_TABLE(i2c, nau8540_i2c_ids);
813 813
814#ifdef CONFIG_OF 814#ifdef CONFIG_OF
815static const struct of_device_id nau8540_of_ids[] = { 815static const struct of_device_id nau8540_of_ids[] = {
816 { .compatible = "nuvoton,nau8540", }, 816 { .compatible = "nuvoton,nau8540", },
817 {} 817 {}
818}; 818};
819MODULE_DEVICE_TABLE(of, nau8540_of_ids); 819MODULE_DEVICE_TABLE(of, nau8540_of_ids);
820#endif 820#endif
821 821
822static struct i2c_driver nau8540_i2c_driver = { 822static struct i2c_driver nau8540_i2c_driver = {
823 .driver = { 823 .driver = {
824 .name = "nau8540", 824 .name = "nau8540",
825 .of_match_table = of_match_ptr(nau8540_of_ids), 825 .of_match_table = of_match_ptr(nau8540_of_ids),
826 }, 826 },
827 .probe = nau8540_i2c_probe, 827 .probe = nau8540_i2c_probe,
828 .remove = nau8540_i2c_remove, 828 .remove = nau8540_i2c_remove,
829 .id_table = nau8540_i2c_ids, 829 .id_table = nau8540_i2c_ids,
830}; 830};
831module_i2c_driver(nau8540_i2c_driver); 831module_i2c_driver(nau8540_i2c_driver);
832 832
diff --git a/sound/soc/codecs/nau8540.h b/sound/soc/codecs/nau8540.h
index d06e65188cd5..5db5b224944d 100644
--- a/sound/soc/codecs/nau8540.h
+++ b/sound/soc/codecs/nau8540.h
@@ -12,211 +12,211 @@
12#ifndef __NAU8540_H__ 12#ifndef __NAU8540_H__
13#define __NAU8540_H__ 13#define __NAU8540_H__
14 14
15#define NAU8540_REG_SW_RESET 0x00 15#define NAU8540_REG_SW_RESET 0x00
16#define NAU8540_REG_POWER_MANAGEMENT 0x01 16#define NAU8540_REG_POWER_MANAGEMENT 0x01
17#define NAU8540_REG_CLOCK_CTRL 0x02 17#define NAU8540_REG_CLOCK_CTRL 0x02
18#define NAU8540_REG_CLOCK_SRC 0x03 18#define NAU8540_REG_CLOCK_SRC 0x03
19#define NAU8540_REG_FLL1 0x04 19#define NAU8540_REG_FLL1 0x04
20#define NAU8540_REG_FLL2 0x05 20#define NAU8540_REG_FLL2 0x05
21#define NAU8540_REG_FLL3 0x06 21#define NAU8540_REG_FLL3 0x06
22#define NAU8540_REG_FLL4 0x07 22#define NAU8540_REG_FLL4 0x07
23#define NAU8540_REG_FLL5 0x08 23#define NAU8540_REG_FLL5 0x08
24#define NAU8540_REG_FLL6 0x09 24#define NAU8540_REG_FLL6 0x09
25#define NAU8540_REG_FLL_VCO_RSV 0x0A 25#define NAU8540_REG_FLL_VCO_RSV 0x0A
26#define NAU8540_REG_PCM_CTRL0 0x10 26#define NAU8540_REG_PCM_CTRL0 0x10
27#define NAU8540_REG_PCM_CTRL1 0x11 27#define NAU8540_REG_PCM_CTRL1 0x11
28#define NAU8540_REG_PCM_CTRL2 0x12 28#define NAU8540_REG_PCM_CTRL2 0x12
29#define NAU8540_REG_PCM_CTRL3 0x13 29#define NAU8540_REG_PCM_CTRL3 0x13
30#define NAU8540_REG_PCM_CTRL4 0x14 30#define NAU8540_REG_PCM_CTRL4 0x14
31#define NAU8540_REG_ALC_CONTROL_1 0x20 31#define NAU8540_REG_ALC_CONTROL_1 0x20
32#define NAU8540_REG_ALC_CONTROL_2 0x21 32#define NAU8540_REG_ALC_CONTROL_2 0x21
33#define NAU8540_REG_ALC_CONTROL_3 0x22 33#define NAU8540_REG_ALC_CONTROL_3 0x22
34#define NAU8540_REG_ALC_CONTROL_4 0x23 34#define NAU8540_REG_ALC_CONTROL_4 0x23
35#define NAU8540_REG_ALC_CONTROL_5 0x24 35#define NAU8540_REG_ALC_CONTROL_5 0x24
36#define NAU8540_REG_ALC_GAIN_CH12 0x2D 36#define NAU8540_REG_ALC_GAIN_CH12 0x2D
37#define NAU8540_REG_ALC_GAIN_CH34 0x2E 37#define NAU8540_REG_ALC_GAIN_CH34 0x2E
38#define NAU8540_REG_ALC_STATUS 0x2F 38#define NAU8540_REG_ALC_STATUS 0x2F
39#define NAU8540_REG_NOTCH_FIL1_CH1 0x30 39#define NAU8540_REG_NOTCH_FIL1_CH1 0x30
40#define NAU8540_REG_NOTCH_FIL2_CH1 0x31 40#define NAU8540_REG_NOTCH_FIL2_CH1 0x31
41#define NAU8540_REG_NOTCH_FIL1_CH2 0x32 41#define NAU8540_REG_NOTCH_FIL1_CH2 0x32
42#define NAU8540_REG_NOTCH_FIL2_CH2 0x33 42#define NAU8540_REG_NOTCH_FIL2_CH2 0x33
43#define NAU8540_REG_NOTCH_FIL1_CH3 0x34 43#define NAU8540_REG_NOTCH_FIL1_CH3 0x34
44#define NAU8540_REG_NOTCH_FIL2_CH3 0x35 44#define NAU8540_REG_NOTCH_FIL2_CH3 0x35
45#define NAU8540_REG_NOTCH_FIL1_CH4 0x36 45#define NAU8540_REG_NOTCH_FIL1_CH4 0x36
46#define NAU8540_REG_NOTCH_FIL2_CH4 0x37 46#define NAU8540_REG_NOTCH_FIL2_CH4 0x37
47#define NAU8540_REG_HPF_FILTER_CH12 0x38 47#define NAU8540_REG_HPF_FILTER_CH12 0x38
48#define NAU8540_REG_HPF_FILTER_CH34 0x39 48#define NAU8540_REG_HPF_FILTER_CH34 0x39
49#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A 49#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A
50#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40 50#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40
51#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41 51#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41
52#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42 52#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42
53#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43 53#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43
54#define NAU8540_REG_DIGITAL_MUX 0x44 54#define NAU8540_REG_DIGITAL_MUX 0x44
55#define NAU8540_REG_P2P_CH1 0x48 55#define NAU8540_REG_P2P_CH1 0x48
56#define NAU8540_REG_P2P_CH2 0x49 56#define NAU8540_REG_P2P_CH2 0x49
57#define NAU8540_REG_P2P_CH3 0x4A 57#define NAU8540_REG_P2P_CH3 0x4A
58#define NAU8540_REG_P2P_CH4 0x4B 58#define NAU8540_REG_P2P_CH4 0x4B
59#define NAU8540_REG_PEAK_CH1 0x4C 59#define NAU8540_REG_PEAK_CH1 0x4C
60#define NAU8540_REG_PEAK_CH2 0x4D 60#define NAU8540_REG_PEAK_CH2 0x4D
61#define NAU8540_REG_PEAK_CH3 0x4E 61#define NAU8540_REG_PEAK_CH3 0x4E
62#define NAU8540_REG_PEAK_CH4 0x4F 62#define NAU8540_REG_PEAK_CH4 0x4F
63#define NAU8540_REG_GPIO_CTRL 0x50 63#define NAU8540_REG_GPIO_CTRL 0x50
64#define NAU8540_REG_MISC_CTRL 0x51 64#define NAU8540_REG_MISC_CTRL 0x51
65#define NAU8540_REG_I2C_CTRL 0x52 65#define NAU8540_REG_I2C_CTRL 0x52
66#define NAU8540_REG_I2C_DEVICE_ID 0x58 66#define NAU8540_REG_I2C_DEVICE_ID 0x58
67#define NAU8540_REG_RST 0x5A 67#define NAU8540_REG_RST 0x5A
68#define NAU8540_REG_VMID_CTRL 0x60 68#define NAU8540_REG_VMID_CTRL 0x60
69#define NAU8540_REG_MUTE 0x61 69#define NAU8540_REG_MUTE 0x61
70#define NAU8540_REG_ANALOG_ADC1 0x64 70#define NAU8540_REG_ANALOG_ADC1 0x64
71#define NAU8540_REG_ANALOG_ADC2 0x65 71#define NAU8540_REG_ANALOG_ADC2 0x65
72#define NAU8540_REG_ANALOG_PWR 0x66 72#define NAU8540_REG_ANALOG_PWR 0x66
73#define NAU8540_REG_MIC_BIAS 0x67 73#define NAU8540_REG_MIC_BIAS 0x67
74#define NAU8540_REG_REFERENCE 0x68 74#define NAU8540_REG_REFERENCE 0x68
75#define NAU8540_REG_FEPGA1 0x69 75#define NAU8540_REG_FEPGA1 0x69
76#define NAU8540_REG_FEPGA2 0x6A 76#define NAU8540_REG_FEPGA2 0x6A
77#define NAU8540_REG_FEPGA3 0x6B 77#define NAU8540_REG_FEPGA3 0x6B
78#define NAU8540_REG_FEPGA4 0x6C 78#define NAU8540_REG_FEPGA4 0x6C
79#define NAU8540_REG_PWR 0x6D 79#define NAU8540_REG_PWR 0x6D
80#define NAU8540_REG_MAX NAU8540_REG_PWR 80#define NAU8540_REG_MAX NAU8540_REG_PWR
81 81
82 82
83/* POWER_MANAGEMENT (0x01) */ 83/* POWER_MANAGEMENT (0x01) */
84#define NAU8540_ADC4_EN (0x1 << 3) 84#define NAU8540_ADC4_EN (0x1 << 3)
85#define NAU8540_ADC3_EN (0x1 << 2) 85#define NAU8540_ADC3_EN (0x1 << 2)
86#define NAU8540_ADC2_EN (0x1 << 1) 86#define NAU8540_ADC2_EN (0x1 << 1)
87#define NAU8540_ADC1_EN 0x1 87#define NAU8540_ADC1_EN 0x1
88 88
89/* CLOCK_CTRL (0x02) */ 89/* CLOCK_CTRL (0x02) */
90#define NAU8540_CLK_ADC_EN (0x1 << 15) 90#define NAU8540_CLK_ADC_EN (0x1 << 15)
91#define NAU8540_CLK_I2S_EN (0x1 << 1) 91#define NAU8540_CLK_I2S_EN (0x1 << 1)
92 92
93/* CLOCK_SRC (0x03) */ 93/* CLOCK_SRC (0x03) */
94#define NAU8540_CLK_SRC_SFT 15 94#define NAU8540_CLK_SRC_SFT 15
95#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT) 95#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT)
96#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT) 96#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT)
97#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT) 97#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT)
98#define NAU8540_CLK_ADC_SRC_SFT 6 98#define NAU8540_CLK_ADC_SRC_SFT 6
99#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT) 99#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT)
100#define NAU8540_CLK_MCLK_SRC_MASK 0xf 100#define NAU8540_CLK_MCLK_SRC_MASK 0xf
101 101
102/* FLL1 (0x04) */ 102/* FLL1 (0x04) */
103#define NAU8540_FLL_RATIO_MASK 0x7f 103#define NAU8540_FLL_RATIO_MASK 0x7f
104 104
105/* FLL3 (0x06) */ 105/* FLL3 (0x06) */
106#define NAU8540_FLL_CLK_SRC_SFT 10 106#define NAU8540_FLL_CLK_SRC_SFT 10
107#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT) 107#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT)
108#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT) 108#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT)
109#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT) 109#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT)
110#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT) 110#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT)
111#define NAU8540_FLL_INTEGER_MASK 0x3ff 111#define NAU8540_FLL_INTEGER_MASK 0x3ff
112 112
113/* FLL4 (0x07) */ 113/* FLL4 (0x07) */
114#define NAU8540_FLL_REF_DIV_SFT 10 114#define NAU8540_FLL_REF_DIV_SFT 10
115#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT) 115#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT)
116 116
117/* FLL5 (0x08) */ 117/* FLL5 (0x08) */
118#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15) 118#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15)
119#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14) 119#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14)
120#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13) 120#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13)
121#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13) 121#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13)
122#define NAU8540_FLL_CLK_SW_REF (0x0 << 13) 122#define NAU8540_FLL_CLK_SW_REF (0x0 << 13)
123#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12) 123#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12)
124#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12) 124#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12)
125#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12) 125#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12)
126 126
127/* FLL6 (0x9) */ 127/* FLL6 (0x9) */
128#define NAU8540_DCO_EN (0x1 << 15) 128#define NAU8540_DCO_EN (0x1 << 15)
129#define NAU8540_SDM_EN (0x1 << 14) 129#define NAU8540_SDM_EN (0x1 << 14)
130 130
131/* PCM_CTRL0 (0x10) */ 131/* PCM_CTRL0 (0x10) */
132#define NAU8540_I2S_BP_SFT 7 132#define NAU8540_I2S_BP_SFT 7
133#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT) 133#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT)
134#define NAU8540_I2S_PCMB_SFT 6 134#define NAU8540_I2S_PCMB_SFT 6
135#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT) 135#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT)
136#define NAU8540_I2S_DL_SFT 2 136#define NAU8540_I2S_DL_SFT 2
137#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT) 137#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT)
138#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT) 138#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT)
139#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT) 139#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT)
140#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT) 140#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT)
141#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT) 141#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT)
142#define NAU8540_I2S_DF_MASK 0x3 142#define NAU8540_I2S_DF_MASK 0x3
143#define NAU8540_I2S_DF_RIGTH 0 143#define NAU8540_I2S_DF_RIGTH 0
144#define NAU8540_I2S_DF_LEFT 0x1 144#define NAU8540_I2S_DF_LEFT 0x1
145#define NAU8540_I2S_DF_I2S 0x2 145#define NAU8540_I2S_DF_I2S 0x2
146#define NAU8540_I2S_DF_PCM_AB 0x3 146#define NAU8540_I2S_DF_PCM_AB 0x3
147 147
148/* PCM_CTRL1 (0x11) */ 148/* PCM_CTRL1 (0x11) */
149#define NAU8540_I2S_LRC_DIV_SFT 12 149#define NAU8540_I2S_LRC_DIV_SFT 12
150#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT) 150#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT)
151#define NAU8540_I2S_DO12_OE (0x1 << 4) 151#define NAU8540_I2S_DO12_OE (0x1 << 4)
152#define NAU8540_I2S_MS_SFT 3 152#define NAU8540_I2S_MS_SFT 3
153#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT) 153#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT)
154#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT) 154#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT)
155#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT) 155#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT)
156#define NAU8540_I2S_BLK_DIV_MASK 0x7 156#define NAU8540_I2S_BLK_DIV_MASK 0x7
157 157
158/* PCM_CTRL1 (0x12) */ 158/* PCM_CTRL1 (0x12) */
159#define NAU8540_I2S_DO34_OE (0x1 << 11) 159#define NAU8540_I2S_DO34_OE (0x1 << 11)
160#define NAU8540_I2S_TSLOT_L_MASK 0x3ff 160#define NAU8540_I2S_TSLOT_L_MASK 0x3ff
161 161
162/* PCM_CTRL4 (0x14) */ 162/* PCM_CTRL4 (0x14) */
163#define NAU8540_TDM_MODE (0x1 << 15) 163#define NAU8540_TDM_MODE (0x1 << 15)
164#define NAU8540_TDM_OFFSET_EN (0x1 << 14) 164#define NAU8540_TDM_OFFSET_EN (0x1 << 14)
165#define NAU8540_TDM_TX_MASK 0xf 165#define NAU8540_TDM_TX_MASK 0xf
166 166
167/* ADC_SAMPLE_RATE (0x3A) */ 167/* ADC_SAMPLE_RATE (0x3A) */
168#define NAU8540_ADC_OSR_MASK 0x3 168#define NAU8540_ADC_OSR_MASK 0x3
169#define NAU8540_ADC_OSR_256 0x3 169#define NAU8540_ADC_OSR_256 0x3
170#define NAU8540_ADC_OSR_128 0x2 170#define NAU8540_ADC_OSR_128 0x2
171#define NAU8540_ADC_OSR_64 0x1 171#define NAU8540_ADC_OSR_64 0x1
172#define NAU8540_ADC_OSR_32 0x0 172#define NAU8540_ADC_OSR_32 0x0
173 173
174/* VMID_CTRL (0x60) */ 174/* VMID_CTRL (0x60) */
175#define NAU8540_VMID_EN (1 << 6) 175#define NAU8540_VMID_EN (1 << 6)
176#define NAU8540_VMID_SEL_SFT 4 176#define NAU8540_VMID_SEL_SFT 4
177#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT) 177#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
178 178
179/* MIC_BIAS (0x67) */ 179/* MIC_BIAS (0x67) */
180#define NAU8540_PU_PRE (0x1 << 8) 180#define NAU8540_PU_PRE (0x1 << 8)
181 181
182/* REFERENCE (0x68) */ 182/* REFERENCE (0x68) */
183#define NAU8540_PRECHARGE_DIS (0x1 << 13) 183#define NAU8540_PRECHARGE_DIS (0x1 << 13)
184#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) 184#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12)
185 185
186 186
187/* System Clock Source */ 187/* System Clock Source */
188enum { 188enum {
189 NAU8540_CLK_DIS, 189 NAU8540_CLK_DIS,
190 NAU8540_CLK_MCLK, 190 NAU8540_CLK_MCLK,
191 NAU8540_CLK_INTERNAL, 191 NAU8540_CLK_INTERNAL,
192 NAU8540_CLK_FLL_MCLK, 192 NAU8540_CLK_FLL_MCLK,
193 NAU8540_CLK_FLL_BLK, 193 NAU8540_CLK_FLL_BLK,
194 NAU8540_CLK_FLL_FS, 194 NAU8540_CLK_FLL_FS,
195}; 195};
196 196
197struct nau8540 { 197struct nau8540 {
198 struct device *dev; 198 struct device *dev;
199 struct regmap *regmap; 199 struct regmap *regmap;
200}; 200};
201 201
202struct nau8540_fll { 202struct nau8540_fll {
203 int mclk_src; 203 int mclk_src;
204 int ratio; 204 int ratio;
205 int fll_frac; 205 int fll_frac;
206 int fll_int; 206 int fll_int;
207 int clk_ref_div; 207 int clk_ref_div;
208}; 208};
209 209
210struct nau8540_fll_attr { 210struct nau8540_fll_attr {
211 unsigned int param; 211 unsigned int param;
212 unsigned int val; 212 unsigned int val;
213}; 213};
214 214
215/* over sampling rate */ 215/* over sampling rate */
216struct nau8540_osr_attr { 216struct nau8540_osr_attr {
217 unsigned int osr; 217 unsigned int osr;
218 unsigned int clk_src; 218 unsigned int clk_src;
219}; 219};
220 220
221 221
222#endif /* __NAU8540_H__ */ 222#endif /* __NAU8540_H__ */
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c
new file mode 100644
index 000000000000..cca974d26136
--- /dev/null
+++ b/sound/soc/codecs/nau8824.c
@@ -0,0 +1,1831 @@
1/*
2 * NAU88L24 ALSA SoC audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 * Author: John Hsu <KCHSU0@nuvoton.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/delay.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/clk.h>
19#include <linux/acpi.h>
20#include <linux/math64.h>
21#include <linux/semaphore.h>
22
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30
31#include "nau8824.h"
32
33
34static int nau8824_config_sysclk(struct nau8824 *nau8824,
35 int clk_id, unsigned int freq);
36static bool nau8824_is_jack_inserted(struct nau8824 *nau8824);
37
38/* the ADC threshold of headset */
39#define DMIC_CLK 3072000
40
41/* the ADC threshold of headset */
42#define HEADSET_SARADC_THD 0x80
43
44/* the parameter threshold of FLL */
45#define NAU_FREF_MAX 13500000
46#define NAU_FVCO_MAX 124000000
47#define NAU_FVCO_MIN 90000000
48
49/* scaling for mclk from sysclk_src output */
50static const struct nau8824_fll_attr mclk_src_scaling[] = {
51 { 1, 0x0 },
52 { 2, 0x2 },
53 { 4, 0x3 },
54 { 8, 0x4 },
55 { 16, 0x5 },
56 { 32, 0x6 },
57 { 3, 0x7 },
58 { 6, 0xa },
59 { 12, 0xb },
60 { 24, 0xc },
61};
62
63/* ratio for input clk freq */
64static const struct nau8824_fll_attr fll_ratio[] = {
65 { 512000, 0x01 },
66 { 256000, 0x02 },
67 { 128000, 0x04 },
68 { 64000, 0x08 },
69 { 32000, 0x10 },
70 { 8000, 0x20 },
71 { 4000, 0x40 },
72};
73
74static const struct nau8824_fll_attr fll_pre_scalar[] = {
75 { 1, 0x0 },
76 { 2, 0x1 },
77 { 4, 0x2 },
78 { 8, 0x3 },
79};
80
81/* the maximum frequency of CLK_ADC and CLK_DAC */
82#define CLK_DA_AD_MAX 6144000
83
84/* over sampling rate */
85static const struct nau8824_osr_attr osr_dac_sel[] = {
86 { 64, 2 }, /* OSR 64, SRC 1/4 */
87 { 256, 0 }, /* OSR 256, SRC 1 */
88 { 128, 1 }, /* OSR 128, SRC 1/2 */
89 { 0, 0 },
90 { 32, 3 }, /* OSR 32, SRC 1/8 */
91};
92
93static const struct nau8824_osr_attr osr_adc_sel[] = {
94 { 32, 3 }, /* OSR 32, SRC 1/8 */
95 { 64, 2 }, /* OSR 64, SRC 1/4 */
96 { 128, 1 }, /* OSR 128, SRC 1/2 */
97 { 256, 0 }, /* OSR 256, SRC 1 */
98};
99
100static const struct reg_default nau8824_reg_defaults[] = {
101 { NAU8824_REG_ENA_CTRL, 0x0000 },
102 { NAU8824_REG_CLK_GATING_ENA, 0x0000 },
103 { NAU8824_REG_CLK_DIVIDER, 0x0000 },
104 { NAU8824_REG_FLL1, 0x0000 },
105 { NAU8824_REG_FLL2, 0x3126 },
106 { NAU8824_REG_FLL3, 0x0008 },
107 { NAU8824_REG_FLL4, 0x0010 },
108 { NAU8824_REG_FLL5, 0xC000 },
109 { NAU8824_REG_FLL6, 0x6000 },
110 { NAU8824_REG_FLL_VCO_RSV, 0xF13C },
111 { NAU8824_REG_JACK_DET_CTRL, 0x0000 },
112 { NAU8824_REG_INTERRUPT_SETTING_1, 0x0000 },
113 { NAU8824_REG_IRQ, 0x0000 },
114 { NAU8824_REG_CLEAR_INT_REG, 0x0000 },
115 { NAU8824_REG_INTERRUPT_SETTING, 0x1000 },
116 { NAU8824_REG_SAR_ADC, 0x0015 },
117 { NAU8824_REG_VDET_COEFFICIENT, 0x0110 },
118 { NAU8824_REG_VDET_THRESHOLD_1, 0x0000 },
119 { NAU8824_REG_VDET_THRESHOLD_2, 0x0000 },
120 { NAU8824_REG_VDET_THRESHOLD_3, 0x0000 },
121 { NAU8824_REG_VDET_THRESHOLD_4, 0x0000 },
122 { NAU8824_REG_GPIO_SEL, 0x0000 },
123 { NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 0x000B },
124 { NAU8824_REG_PORT0_I2S_PCM_CTRL_2, 0x0010 },
125 { NAU8824_REG_PORT0_LEFT_TIME_SLOT, 0x0000 },
126 { NAU8824_REG_PORT0_RIGHT_TIME_SLOT, 0x0000 },
127 { NAU8824_REG_TDM_CTRL, 0x0000 },
128 { NAU8824_REG_ADC_HPF_FILTER, 0x0000 },
129 { NAU8824_REG_ADC_FILTER_CTRL, 0x0002 },
130 { NAU8824_REG_DAC_FILTER_CTRL_1, 0x0000 },
131 { NAU8824_REG_DAC_FILTER_CTRL_2, 0x0000 },
132 { NAU8824_REG_NOTCH_FILTER_1, 0x0000 },
133 { NAU8824_REG_NOTCH_FILTER_2, 0x0000 },
134 { NAU8824_REG_EQ1_LOW, 0x112C },
135 { NAU8824_REG_EQ2_EQ3, 0x2C2C },
136 { NAU8824_REG_EQ4_EQ5, 0x2C2C },
137 { NAU8824_REG_ADC_CH0_DGAIN_CTRL, 0x0100 },
138 { NAU8824_REG_ADC_CH1_DGAIN_CTRL, 0x0100 },
139 { NAU8824_REG_ADC_CH2_DGAIN_CTRL, 0x0100 },
140 { NAU8824_REG_ADC_CH3_DGAIN_CTRL, 0x0100 },
141 { NAU8824_REG_DAC_MUTE_CTRL, 0x0000 },
142 { NAU8824_REG_DAC_CH0_DGAIN_CTRL, 0x0100 },
143 { NAU8824_REG_DAC_CH1_DGAIN_CTRL, 0x0100 },
144 { NAU8824_REG_ADC_TO_DAC_ST, 0x0000 },
145 { NAU8824_REG_DRC_KNEE_IP12_ADC_CH01, 0x1486 },
146 { NAU8824_REG_DRC_KNEE_IP34_ADC_CH01, 0x0F12 },
147 { NAU8824_REG_DRC_SLOPE_ADC_CH01, 0x25FF },
148 { NAU8824_REG_DRC_ATKDCY_ADC_CH01, 0x3457 },
149 { NAU8824_REG_DRC_KNEE_IP12_ADC_CH23, 0x1486 },
150 { NAU8824_REG_DRC_KNEE_IP34_ADC_CH23, 0x0F12 },
151 { NAU8824_REG_DRC_SLOPE_ADC_CH23, 0x25FF },
152 { NAU8824_REG_DRC_ATKDCY_ADC_CH23, 0x3457 },
153 { NAU8824_REG_DRC_GAINL_ADC0, 0x0200 },
154 { NAU8824_REG_DRC_GAINL_ADC1, 0x0200 },
155 { NAU8824_REG_DRC_GAINL_ADC2, 0x0200 },
156 { NAU8824_REG_DRC_GAINL_ADC3, 0x0200 },
157 { NAU8824_REG_DRC_KNEE_IP12_DAC, 0x1486 },
158 { NAU8824_REG_DRC_KNEE_IP34_DAC, 0x0F12 },
159 { NAU8824_REG_DRC_SLOPE_DAC, 0x25F9 },
160 { NAU8824_REG_DRC_ATKDCY_DAC, 0x3457 },
161 { NAU8824_REG_DRC_GAIN_DAC_CH0, 0x0200 },
162 { NAU8824_REG_DRC_GAIN_DAC_CH1, 0x0200 },
163 { NAU8824_REG_MODE, 0x0000 },
164 { NAU8824_REG_MODE1, 0x0000 },
165 { NAU8824_REG_MODE2, 0x0000 },
166 { NAU8824_REG_CLASSG, 0x0000 },
167 { NAU8824_REG_OTP_EFUSE, 0x0000 },
168 { NAU8824_REG_OTPDOUT_1, 0x0000 },
169 { NAU8824_REG_OTPDOUT_2, 0x0000 },
170 { NAU8824_REG_MISC_CTRL, 0x0000 },
171 { NAU8824_REG_I2C_TIMEOUT, 0xEFFF },
172 { NAU8824_REG_TEST_MODE, 0x0000 },
173 { NAU8824_REG_I2C_DEVICE_ID, 0x1AF1 },
174 { NAU8824_REG_SAR_ADC_DATA_OUT, 0x00FF },
175 { NAU8824_REG_BIAS_ADJ, 0x0000 },
176 { NAU8824_REG_PGA_GAIN, 0x0000 },
177 { NAU8824_REG_TRIM_SETTINGS, 0x0000 },
178 { NAU8824_REG_ANALOG_CONTROL_1, 0x0000 },
179 { NAU8824_REG_ANALOG_CONTROL_2, 0x0000 },
180 { NAU8824_REG_ENABLE_LO, 0x0000 },
181 { NAU8824_REG_GAIN_LO, 0x0000 },
182 { NAU8824_REG_CLASSD_GAIN_1, 0x0000 },
183 { NAU8824_REG_CLASSD_GAIN_2, 0x0000 },
184 { NAU8824_REG_ANALOG_ADC_1, 0x0011 },
185 { NAU8824_REG_ANALOG_ADC_2, 0x0020 },
186 { NAU8824_REG_RDAC, 0x0008 },
187 { NAU8824_REG_MIC_BIAS, 0x0006 },
188 { NAU8824_REG_HS_VOLUME_CONTROL, 0x0000 },
189 { NAU8824_REG_BOOST, 0x0000 },
190 { NAU8824_REG_FEPGA, 0x0000 },
191 { NAU8824_REG_FEPGA_II, 0x0000 },
192 { NAU8824_REG_FEPGA_SE, 0x0000 },
193 { NAU8824_REG_FEPGA_ATTENUATION, 0x0000 },
194 { NAU8824_REG_ATT_PORT0, 0x0000 },
195 { NAU8824_REG_ATT_PORT1, 0x0000 },
196 { NAU8824_REG_POWER_UP_CONTROL, 0x0000 },
197 { NAU8824_REG_CHARGE_PUMP_CONTROL, 0x0300 },
198 { NAU8824_REG_CHARGE_PUMP_INPUT, 0x0013 },
199};
200
201static int nau8824_sema_acquire(struct nau8824 *nau8824, long timeout)
202{
203 int ret;
204
205 if (timeout) {
206 ret = down_timeout(&nau8824->jd_sem, timeout);
207 if (ret < 0)
208 dev_warn(nau8824->dev, "Acquire semaphone timeout\n");
209 } else {
210 ret = down_interruptible(&nau8824->jd_sem);
211 if (ret < 0)
212 dev_warn(nau8824->dev, "Acquire semaphone fail\n");
213 }
214
215 return ret;
216}
217
218static inline void nau8824_sema_release(struct nau8824 *nau8824)
219{
220 up(&nau8824->jd_sem);
221}
222
223static bool nau8824_readable_reg(struct device *dev, unsigned int reg)
224{
225 switch (reg) {
226 case NAU8824_REG_ENA_CTRL ... NAU8824_REG_FLL_VCO_RSV:
227 case NAU8824_REG_JACK_DET_CTRL:
228 case NAU8824_REG_INTERRUPT_SETTING_1:
229 case NAU8824_REG_IRQ:
230 case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4:
231 case NAU8824_REG_GPIO_SEL:
232 case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL:
233 case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5:
234 case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST:
235 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 ... NAU8824_REG_DRC_GAINL_ADC3:
236 case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_GAIN_DAC_CH1:
237 case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE:
238 case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2:
239 case NAU8824_REG_I2C_TIMEOUT:
240 case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT:
241 case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2:
242 case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1:
243 case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_INPUT:
244 return true;
245 default:
246 return false;
247 }
248
249}
250
251static bool nau8824_writeable_reg(struct device *dev, unsigned int reg)
252{
253 switch (reg) {
254 case NAU8824_REG_RESET ... NAU8824_REG_FLL_VCO_RSV:
255 case NAU8824_REG_JACK_DET_CTRL:
256 case NAU8824_REG_INTERRUPT_SETTING_1:
257 case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4:
258 case NAU8824_REG_GPIO_SEL:
259 case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL:
260 case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5:
261 case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST:
262 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01:
263 case NAU8824_REG_DRC_KNEE_IP34_ADC_CH01:
264 case NAU8824_REG_DRC_SLOPE_ADC_CH01:
265 case NAU8824_REG_DRC_ATKDCY_ADC_CH01:
266 case NAU8824_REG_DRC_KNEE_IP12_ADC_CH23:
267 case NAU8824_REG_DRC_KNEE_IP34_ADC_CH23:
268 case NAU8824_REG_DRC_SLOPE_ADC_CH23:
269 case NAU8824_REG_DRC_ATKDCY_ADC_CH23:
270 case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_ATKDCY_DAC:
271 case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE:
272 case NAU8824_REG_I2C_TIMEOUT:
273 case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2:
274 case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1:
275 case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_CONTROL:
276 return true;
277 default:
278 return false;
279 }
280}
281
282static bool nau8824_volatile_reg(struct device *dev, unsigned int reg)
283{
284 switch (reg) {
285 case NAU8824_REG_RESET:
286 case NAU8824_REG_IRQ ... NAU8824_REG_CLEAR_INT_REG:
287 case NAU8824_REG_DRC_GAINL_ADC0 ... NAU8824_REG_DRC_GAINL_ADC3:
288 case NAU8824_REG_DRC_GAIN_DAC_CH0 ... NAU8824_REG_DRC_GAIN_DAC_CH1:
289 case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2:
290 case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT:
291 case NAU8824_REG_CHARGE_PUMP_INPUT:
292 return true;
293 default:
294 return false;
295 }
296}
297
298static const char * const nau8824_companding[] = {
299 "Off", "NC", "u-law", "A-law" };
300
301static const struct soc_enum nau8824_companding_adc_enum =
302 SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 12,
303 ARRAY_SIZE(nau8824_companding), nau8824_companding);
304
305static const struct soc_enum nau8824_companding_dac_enum =
306 SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 14,
307 ARRAY_SIZE(nau8824_companding), nau8824_companding);
308
309static const char * const nau8824_adc_decimation[] = {
310 "32", "64", "128", "256" };
311
312static const struct soc_enum nau8824_adc_decimation_enum =
313 SOC_ENUM_SINGLE(NAU8824_REG_ADC_FILTER_CTRL, 0,
314 ARRAY_SIZE(nau8824_adc_decimation), nau8824_adc_decimation);
315
316static const char * const nau8824_dac_oversampl[] = {
317 "64", "256", "128", "", "32" };
318
319static const struct soc_enum nau8824_dac_oversampl_enum =
320 SOC_ENUM_SINGLE(NAU8824_REG_DAC_FILTER_CTRL_1, 0,
321 ARRAY_SIZE(nau8824_dac_oversampl), nau8824_dac_oversampl);
322
323static const char * const nau8824_input_channel[] = {
324 "Input CH0", "Input CH1", "Input CH2", "Input CH3" };
325
326static const struct soc_enum nau8824_adc_ch0_enum =
327 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH0_DGAIN_CTRL, 9,
328 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
329
330static const struct soc_enum nau8824_adc_ch1_enum =
331 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH1_DGAIN_CTRL, 9,
332 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
333
334static const struct soc_enum nau8824_adc_ch2_enum =
335 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH2_DGAIN_CTRL, 9,
336 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
337
338static const struct soc_enum nau8824_adc_ch3_enum =
339 SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH3_DGAIN_CTRL, 9,
340 ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel);
341
342static const char * const nau8824_tdm_slot[] = {
343 "Slot 0", "Slot 1", "Slot 2", "Slot 3" };
344
345static const struct soc_enum nau8824_dac_left_sel_enum =
346 SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 6,
347 ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot);
348
349static const struct soc_enum nau8824_dac_right_sel_enum =
350 SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 4,
351 ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot);
352
353static const DECLARE_TLV_DB_MINMAX_MUTE(spk_vol_tlv, 0, 2400);
354static const DECLARE_TLV_DB_MINMAX(hp_vol_tlv, -3000, 0);
355static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 200, 0);
356static const DECLARE_TLV_DB_SCALE(dmic_vol_tlv, -12800, 50, 0);
357
358static const struct snd_kcontrol_new nau8824_snd_controls[] = {
359 SOC_ENUM("ADC Companding", nau8824_companding_adc_enum),
360 SOC_ENUM("DAC Companding", nau8824_companding_dac_enum),
361
362 SOC_ENUM("ADC Decimation Rate", nau8824_adc_decimation_enum),
363 SOC_ENUM("DAC Oversampling Rate", nau8824_dac_oversampl_enum),
364
365 SOC_SINGLE_TLV("Speaker Right DACR Volume",
366 NAU8824_REG_CLASSD_GAIN_1, 8, 0x1f, 0, spk_vol_tlv),
367 SOC_SINGLE_TLV("Speaker Left DACL Volume",
368 NAU8824_REG_CLASSD_GAIN_2, 0, 0x1f, 0, spk_vol_tlv),
369 SOC_SINGLE_TLV("Speaker Left DACR Volume",
370 NAU8824_REG_CLASSD_GAIN_1, 0, 0x1f, 0, spk_vol_tlv),
371 SOC_SINGLE_TLV("Speaker Right DACL Volume",
372 NAU8824_REG_CLASSD_GAIN_2, 8, 0x1f, 0, spk_vol_tlv),
373
374 SOC_SINGLE_TLV("Headphone Right DACR Volume",
375 NAU8824_REG_ATT_PORT0, 8, 0x1f, 0, hp_vol_tlv),
376 SOC_SINGLE_TLV("Headphone Left DACL Volume",
377 NAU8824_REG_ATT_PORT0, 0, 0x1f, 0, hp_vol_tlv),
378 SOC_SINGLE_TLV("Headphone Right DACL Volume",
379 NAU8824_REG_ATT_PORT1, 8, 0x1f, 0, hp_vol_tlv),
380 SOC_SINGLE_TLV("Headphone Left DACR Volume",
381 NAU8824_REG_ATT_PORT1, 0, 0x1f, 0, hp_vol_tlv),
382
383 SOC_SINGLE_TLV("MIC1 Volume", NAU8824_REG_FEPGA_II,
384 NAU8824_FEPGA_GAINL_SFT, 0x12, 0, mic_vol_tlv),
385 SOC_SINGLE_TLV("MIC2 Volume", NAU8824_REG_FEPGA_II,
386 NAU8824_FEPGA_GAINR_SFT, 0x12, 0, mic_vol_tlv),
387
388 SOC_SINGLE_TLV("DMIC1 Volume", NAU8824_REG_ADC_CH0_DGAIN_CTRL,
389 0, 0x164, 0, dmic_vol_tlv),
390 SOC_SINGLE_TLV("DMIC2 Volume", NAU8824_REG_ADC_CH1_DGAIN_CTRL,
391 0, 0x164, 0, dmic_vol_tlv),
392 SOC_SINGLE_TLV("DMIC3 Volume", NAU8824_REG_ADC_CH2_DGAIN_CTRL,
393 0, 0x164, 0, dmic_vol_tlv),
394 SOC_SINGLE_TLV("DMIC4 Volume", NAU8824_REG_ADC_CH3_DGAIN_CTRL,
395 0, 0x164, 0, dmic_vol_tlv),
396
397 SOC_ENUM("ADC CH0 Select", nau8824_adc_ch0_enum),
398 SOC_ENUM("ADC CH1 Select", nau8824_adc_ch1_enum),
399 SOC_ENUM("ADC CH2 Select", nau8824_adc_ch2_enum),
400 SOC_ENUM("ADC CH3 Select", nau8824_adc_ch3_enum),
401
402 SOC_SINGLE("ADC CH0 TX Switch", NAU8824_REG_TDM_CTRL, 0, 1, 0),
403 SOC_SINGLE("ADC CH1 TX Switch", NAU8824_REG_TDM_CTRL, 1, 1, 0),
404 SOC_SINGLE("ADC CH2 TX Switch", NAU8824_REG_TDM_CTRL, 2, 1, 0),
405 SOC_SINGLE("ADC CH3 TX Switch", NAU8824_REG_TDM_CTRL, 3, 1, 0),
406
407 SOC_ENUM("DACL Channel Source", nau8824_dac_left_sel_enum),
408 SOC_ENUM("DACR Channel Source", nau8824_dac_right_sel_enum),
409
410 SOC_SINGLE("DACL LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 0, 1, 0),
411 SOC_SINGLE("DACR LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 1, 1, 0),
412};
413
414static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w,
415 struct snd_kcontrol *kcontrol, int event)
416{
417 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
418 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
419
420 switch (event) {
421 case SND_SOC_DAPM_PRE_PMU:
422 /* Disables the TESTDAC to let DAC signal pass through. */
423 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO,
424 NAU8824_TEST_DAC_EN, 0);
425 break;
426 case SND_SOC_DAPM_POST_PMD:
427 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO,
428 NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN);
429 break;
430 default:
431 return -EINVAL;
432 }
433
434 return 0;
435}
436
437static int nau8824_spk_event(struct snd_soc_dapm_widget *w,
438 struct snd_kcontrol *kcontrol, int event)
439{
440 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
441 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
442
443 switch (event) {
444 case SND_SOC_DAPM_PRE_PMU:
445 regmap_update_bits(nau8824->regmap,
446 NAU8824_REG_ANALOG_CONTROL_2,
447 NAU8824_CLASSD_CLAMP_DIS, NAU8824_CLASSD_CLAMP_DIS);
448 break;
449 case SND_SOC_DAPM_POST_PMD:
450 regmap_update_bits(nau8824->regmap,
451 NAU8824_REG_ANALOG_CONTROL_2,
452 NAU8824_CLASSD_CLAMP_DIS, 0);
453 break;
454 default:
455 return -EINVAL;
456 }
457
458 return 0;
459}
460
461static int nau8824_pump_event(struct snd_soc_dapm_widget *w,
462 struct snd_kcontrol *kcontrol, int event)
463{
464 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
465 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
466
467 switch (event) {
468 case SND_SOC_DAPM_POST_PMU:
469 /* Prevent startup click by letting charge pump to ramp up */
470 msleep(10);
471 regmap_update_bits(nau8824->regmap,
472 NAU8824_REG_CHARGE_PUMP_CONTROL,
473 NAU8824_JAMNODCLOW, NAU8824_JAMNODCLOW);
474 break;
475 case SND_SOC_DAPM_PRE_PMD:
476 regmap_update_bits(nau8824->regmap,
477 NAU8824_REG_CHARGE_PUMP_CONTROL,
478 NAU8824_JAMNODCLOW, 0);
479 break;
480 default:
481 return -EINVAL;
482 }
483
484 return 0;
485}
486
487static int system_clock_control(struct snd_soc_dapm_widget *w,
488 struct snd_kcontrol *k, int event)
489{
490 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
491 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
492
493 if (SND_SOC_DAPM_EVENT_OFF(event)) {
494 /* Set clock source to disable or internal clock before the
495 * playback or capture end. Codec needs clock for Jack
496 * detection and button press if jack inserted; otherwise,
497 * the clock should be closed.
498 */
499 if (nau8824_is_jack_inserted(nau8824)) {
500 nau8824_config_sysclk(nau8824,
501 NAU8824_CLK_INTERNAL, 0);
502 } else {
503 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
504 }
505 }
506 return 0;
507}
508
509static int dmic_clock_control(struct snd_soc_dapm_widget *w,
510 struct snd_kcontrol *k, int event)
511{
512 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
513 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
514 int src;
515
516 /* The DMIC clock is gotten from system clock (256fs) divided by
517 * DMIC_SRC (1, 2, 4, 8, 16, 32). The clock has to be equal or
518 * less than 3.072 MHz.
519 */
520 for (src = 0; src < 5; src++) {
521 if ((0x1 << (8 - src)) * nau8824->fs <= DMIC_CLK)
522 break;
523 }
524 dev_dbg(nau8824->dev, "dmic src %d for mclk %d\n", src, nau8824->fs * 256);
525 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
526 NAU8824_CLK_DMIC_SRC_MASK, (src << NAU8824_CLK_DMIC_SRC_SFT));
527
528 return 0;
529}
530
531static const struct snd_kcontrol_new nau8824_adc_ch0_dmic =
532 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
533 NAU8824_ADC_CH0_DMIC_SFT, 1, 0);
534
535static const struct snd_kcontrol_new nau8824_adc_ch1_dmic =
536 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
537 NAU8824_ADC_CH1_DMIC_SFT, 1, 0);
538
539static const struct snd_kcontrol_new nau8824_adc_ch2_dmic =
540 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
541 NAU8824_ADC_CH2_DMIC_SFT, 1, 0);
542
543static const struct snd_kcontrol_new nau8824_adc_ch3_dmic =
544 SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL,
545 NAU8824_ADC_CH3_DMIC_SFT, 1, 0);
546
547static const struct snd_kcontrol_new nau8824_adc_left_mixer[] = {
548 SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA,
549 NAU8824_FEPGA_MODEL_MIC1_SFT, 1, 0),
550 SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA,
551 NAU8824_FEPGA_MODEL_HSMIC_SFT, 1, 0),
552};
553
554static const struct snd_kcontrol_new nau8824_adc_right_mixer[] = {
555 SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA,
556 NAU8824_FEPGA_MODER_MIC2_SFT, 1, 0),
557 SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA,
558 NAU8824_FEPGA_MODER_HSMIC_SFT, 1, 0),
559};
560
561static const struct snd_kcontrol_new nau8824_hp_left_mixer[] = {
562 SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO,
563 NAU8824_DACR_HPL_EN_SFT, 1, 0),
564 SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO,
565 NAU8824_DACL_HPL_EN_SFT, 1, 0),
566};
567
568static const struct snd_kcontrol_new nau8824_hp_right_mixer[] = {
569 SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO,
570 NAU8824_DACL_HPR_EN_SFT, 1, 0),
571 SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO,
572 NAU8824_DACR_HPR_EN_SFT, 1, 0),
573};
574
575static const char * const nau8824_dac_src[] = { "DACL", "DACR" };
576
577static SOC_ENUM_SINGLE_DECL(
578 nau8824_dacl_enum, NAU8824_REG_DAC_CH0_DGAIN_CTRL,
579 NAU8824_DAC_CH0_SEL_SFT, nau8824_dac_src);
580
581static SOC_ENUM_SINGLE_DECL(
582 nau8824_dacr_enum, NAU8824_REG_DAC_CH1_DGAIN_CTRL,
583 NAU8824_DAC_CH1_SEL_SFT, nau8824_dac_src);
584
585static const struct snd_kcontrol_new nau8824_dacl_mux =
586 SOC_DAPM_ENUM("DACL Source", nau8824_dacl_enum);
587
588static const struct snd_kcontrol_new nau8824_dacr_mux =
589 SOC_DAPM_ENUM("DACR Source", nau8824_dacr_enum);
590
591
592static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = {
593 SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0,
594 system_clock_control, SND_SOC_DAPM_POST_PMD),
595
596 SND_SOC_DAPM_INPUT("HSMIC1"),
597 SND_SOC_DAPM_INPUT("HSMIC2"),
598 SND_SOC_DAPM_INPUT("MIC1"),
599 SND_SOC_DAPM_INPUT("MIC2"),
600 SND_SOC_DAPM_INPUT("DMIC1"),
601 SND_SOC_DAPM_INPUT("DMIC2"),
602 SND_SOC_DAPM_INPUT("DMIC3"),
603 SND_SOC_DAPM_INPUT("DMIC4"),
604
605 SND_SOC_DAPM_SUPPLY("SAR", NAU8824_REG_SAR_ADC,
606 NAU8824_SAR_ADC_EN_SFT, 0, NULL, 0),
607 SND_SOC_DAPM_SUPPLY("MICBIAS", NAU8824_REG_MIC_BIAS,
608 NAU8824_MICBIAS_POWERUP_SFT, 0, NULL, 0),
609 SND_SOC_DAPM_SUPPLY("DMIC12 Power", NAU8824_REG_BIAS_ADJ,
610 NAU8824_DMIC1_EN_SFT, 0, NULL, 0),
611 SND_SOC_DAPM_SUPPLY("DMIC34 Power", NAU8824_REG_BIAS_ADJ,
612 NAU8824_DMIC2_EN_SFT, 0, NULL, 0),
613 SND_SOC_DAPM_SUPPLY("DMIC Clock", SND_SOC_NOPM, 0, 0,
614 dmic_clock_control, SND_SOC_DAPM_POST_PMU),
615
616 SND_SOC_DAPM_SWITCH("DMIC1 Enable", SND_SOC_NOPM,
617 0, 0, &nau8824_adc_ch0_dmic),
618 SND_SOC_DAPM_SWITCH("DMIC2 Enable", SND_SOC_NOPM,
619 0, 0, &nau8824_adc_ch1_dmic),
620 SND_SOC_DAPM_SWITCH("DMIC3 Enable", SND_SOC_NOPM,
621 0, 0, &nau8824_adc_ch2_dmic),
622 SND_SOC_DAPM_SWITCH("DMIC4 Enable", SND_SOC_NOPM,
623 0, 0, &nau8824_adc_ch3_dmic),
624
625 SND_SOC_DAPM_MIXER("Left ADC", NAU8824_REG_POWER_UP_CONTROL,
626 12, 0, nau8824_adc_left_mixer,
627 ARRAY_SIZE(nau8824_adc_left_mixer)),
628 SND_SOC_DAPM_MIXER("Right ADC", NAU8824_REG_POWER_UP_CONTROL,
629 13, 0, nau8824_adc_right_mixer,
630 ARRAY_SIZE(nau8824_adc_right_mixer)),
631
632 SND_SOC_DAPM_ADC("ADCL", NULL, NAU8824_REG_ANALOG_ADC_2,
633 NAU8824_ADCL_EN_SFT, 0),
634 SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2,
635 NAU8824_ADCR_EN_SFT, 0),
636
637 SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
638 SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
639
640 SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC,
641 NAU8824_DACL_EN_SFT, 0),
642 SND_SOC_DAPM_SUPPLY("DACL Clock", NAU8824_REG_RDAC,
643 NAU8824_DACL_CLK_SFT, 0, NULL, 0),
644 SND_SOC_DAPM_DAC("DACR", NULL, NAU8824_REG_RDAC,
645 NAU8824_DACR_EN_SFT, 0),
646 SND_SOC_DAPM_SUPPLY("DACR Clock", NAU8824_REG_RDAC,
647 NAU8824_DACR_CLK_SFT, 0, NULL, 0),
648
649 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacl_mux),
650 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacr_mux),
651
652 SND_SOC_DAPM_PGA_S("Output DACL", 0, NAU8824_REG_CHARGE_PUMP_CONTROL,
653 8, 1, nau8824_output_dac_event,
654 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
655 SND_SOC_DAPM_PGA_S("Output DACR", 0, NAU8824_REG_CHARGE_PUMP_CONTROL,
656 9, 1, nau8824_output_dac_event,
657 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
658
659 SND_SOC_DAPM_PGA_S("ClassD", 0, NAU8824_REG_CLASSD_GAIN_1,
660 NAU8824_CLASSD_EN_SFT, 0, nau8824_spk_event,
661 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
662
663 SND_SOC_DAPM_MIXER("Left Headphone", NAU8824_REG_CLASSG,
664 NAU8824_CLASSG_LDAC_EN_SFT, 0, nau8824_hp_left_mixer,
665 ARRAY_SIZE(nau8824_hp_left_mixer)),
666 SND_SOC_DAPM_MIXER("Right Headphone", NAU8824_REG_CLASSG,
667 NAU8824_CLASSG_RDAC_EN_SFT, 0, nau8824_hp_right_mixer,
668 ARRAY_SIZE(nau8824_hp_right_mixer)),
669 SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8824_REG_CHARGE_PUMP_CONTROL,
670 NAU8824_CHARGE_PUMP_EN_SFT, 0, nau8824_pump_event,
671 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
672 SND_SOC_DAPM_PGA("Output Driver L",
673 NAU8824_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
674 SND_SOC_DAPM_PGA("Output Driver R",
675 NAU8824_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
676 SND_SOC_DAPM_PGA("Main Driver L",
677 NAU8824_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
678 SND_SOC_DAPM_PGA("Main Driver R",
679 NAU8824_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
680 SND_SOC_DAPM_PGA("HP Boost Driver", NAU8824_REG_BOOST,
681 NAU8824_HP_BOOST_DIS_SFT, 1, NULL, 0),
682 SND_SOC_DAPM_PGA("Class G", NAU8824_REG_CLASSG,
683 NAU8824_CLASSG_EN_SFT, 0, NULL, 0),
684
685 SND_SOC_DAPM_OUTPUT("SPKOUTL"),
686 SND_SOC_DAPM_OUTPUT("SPKOUTR"),
687 SND_SOC_DAPM_OUTPUT("HPOL"),
688 SND_SOC_DAPM_OUTPUT("HPOR"),
689};
690
691static const struct snd_soc_dapm_route nau8824_dapm_routes[] = {
692 {"DMIC1 Enable", "Switch", "DMIC1"},
693 {"DMIC2 Enable", "Switch", "DMIC2"},
694 {"DMIC3 Enable", "Switch", "DMIC3"},
695 {"DMIC4 Enable", "Switch", "DMIC4"},
696
697 {"DMIC1", NULL, "DMIC12 Power"},
698 {"DMIC2", NULL, "DMIC12 Power"},
699 {"DMIC3", NULL, "DMIC34 Power"},
700 {"DMIC4", NULL, "DMIC34 Power"},
701 {"DMIC12 Power", NULL, "DMIC Clock"},
702 {"DMIC34 Power", NULL, "DMIC Clock"},
703
704 {"Left ADC", "MIC Switch", "MIC1"},
705 {"Left ADC", "HSMIC Switch", "HSMIC1"},
706 {"Right ADC", "MIC Switch", "MIC2"},
707 {"Right ADC", "HSMIC Switch", "HSMIC2"},
708
709 {"ADCL", NULL, "Left ADC"},
710 {"ADCR", NULL, "Right ADC"},
711
712 {"AIFTX", NULL, "MICBIAS"},
713 {"AIFTX", NULL, "ADCL"},
714 {"AIFTX", NULL, "ADCR"},
715 {"AIFTX", NULL, "DMIC1 Enable"},
716 {"AIFTX", NULL, "DMIC2 Enable"},
717 {"AIFTX", NULL, "DMIC3 Enable"},
718 {"AIFTX", NULL, "DMIC4 Enable"},
719
720 {"AIFTX", NULL, "System Clock"},
721 {"AIFRX", NULL, "System Clock"},
722
723 {"DACL", NULL, "AIFRX"},
724 {"DACL", NULL, "DACL Clock"},
725 {"DACR", NULL, "AIFRX"},
726 {"DACR", NULL, "DACR Clock"},
727
728 {"DACL Mux", "DACL", "DACL"},
729 {"DACL Mux", "DACR", "DACR"},
730 {"DACR Mux", "DACL", "DACL"},
731 {"DACR Mux", "DACR", "DACR"},
732
733 {"Output DACL", NULL, "DACL Mux"},
734 {"Output DACR", NULL, "DACR Mux"},
735
736 {"ClassD", NULL, "Output DACL"},
737 {"ClassD", NULL, "Output DACR"},
738
739 {"Left Headphone", "DAC Left Switch", "Output DACL"},
740 {"Left Headphone", "DAC Right Switch", "Output DACR"},
741 {"Right Headphone", "DAC Left Switch", "Output DACL"},
742 {"Right Headphone", "DAC Right Switch", "Output DACR"},
743
744 {"Charge Pump", NULL, "Left Headphone"},
745 {"Charge Pump", NULL, "Right Headphone"},
746 {"Output Driver L", NULL, "Charge Pump"},
747 {"Output Driver R", NULL, "Charge Pump"},
748 {"Main Driver L", NULL, "Output Driver L"},
749 {"Main Driver R", NULL, "Output Driver R"},
750 {"Class G", NULL, "Main Driver L"},
751 {"Class G", NULL, "Main Driver R"},
752 {"HP Boost Driver", NULL, "Class G"},
753
754 {"SPKOUTL", NULL, "ClassD"},
755 {"SPKOUTR", NULL, "ClassD"},
756 {"HPOL", NULL, "HP Boost Driver"},
757 {"HPOR", NULL, "HP Boost Driver"},
758};
759
760static bool nau8824_is_jack_inserted(struct nau8824 *nau8824)
761{
762 struct snd_soc_jack *jack = nau8824->jack;
763 bool insert = FALSE;
764
765 if (nau8824->irq && jack)
766 insert = jack->status & SND_JACK_HEADPHONE;
767
768 return insert;
769}
770
771static void nau8824_int_status_clear_all(struct regmap *regmap)
772{
773 int active_irq, clear_irq, i;
774
775 /* Reset the intrruption status from rightmost bit if the corres-
776 * ponding irq event occurs.
777 */
778 regmap_read(regmap, NAU8824_REG_IRQ, &active_irq);
779 for (i = 0; i < NAU8824_REG_DATA_LEN; i++) {
780 clear_irq = (0x1 << i);
781 if (active_irq & clear_irq)
782 regmap_write(regmap,
783 NAU8824_REG_CLEAR_INT_REG, clear_irq);
784 }
785}
786
787static void nau8824_eject_jack(struct nau8824 *nau8824)
788{
789 struct snd_soc_dapm_context *dapm = nau8824->dapm;
790 struct regmap *regmap = nau8824->regmap;
791
792 /* Clear all interruption status */
793 nau8824_int_status_clear_all(regmap);
794
795 snd_soc_dapm_disable_pin(dapm, "SAR");
796 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
797 snd_soc_dapm_sync(dapm);
798
799 /* Enable the insertion interruption, disable the ejection
800 * interruption, and then bypass de-bounce circuit.
801 */
802 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING,
803 NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS |
804 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS,
805 NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS |
806 NAU8824_IRQ_EJECT_DIS);
807 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1,
808 NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN,
809 NAU8824_IRQ_INSERT_EN);
810 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
811 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
812
813 /* Close clock for jack type detection at manual mode */
814 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
815}
816
817static void nau8824_jdet_work(struct work_struct *work)
818{
819 struct nau8824 *nau8824 = container_of(
820 work, struct nau8824, jdet_work);
821 struct snd_soc_dapm_context *dapm = nau8824->dapm;
822 struct regmap *regmap = nau8824->regmap;
823 int adc_value, event = 0, event_mask = 0;
824
825 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
826 snd_soc_dapm_force_enable_pin(dapm, "SAR");
827 snd_soc_dapm_sync(dapm);
828
829 msleep(100);
830
831 regmap_read(regmap, NAU8824_REG_SAR_ADC_DATA_OUT, &adc_value);
832 adc_value = adc_value & NAU8824_SAR_ADC_DATA_MASK;
833 dev_dbg(nau8824->dev, "SAR ADC data 0x%02x\n", adc_value);
834 if (adc_value < HEADSET_SARADC_THD) {
835 event |= SND_JACK_HEADPHONE;
836
837 snd_soc_dapm_disable_pin(dapm, "SAR");
838 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
839 snd_soc_dapm_sync(dapm);
840 } else {
841 event |= SND_JACK_HEADSET;
842 }
843 event_mask |= SND_JACK_HEADSET;
844 snd_soc_jack_report(nau8824->jack, event, event_mask);
845
846 nau8824_sema_release(nau8824);
847}
848
849static void nau8824_setup_auto_irq(struct nau8824 *nau8824)
850{
851 struct regmap *regmap = nau8824->regmap;
852
853 /* Enable jack ejection, short key press and release interruption. */
854 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1,
855 NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN,
856 NAU8824_IRQ_EJECT_EN);
857 regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING,
858 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_KEY_RELEASE_DIS |
859 NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0);
860 /* Enable internal VCO needed for interruptions */
861 nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0);
862 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
863 NAU8824_JD_SLEEP_MODE, 0);
864}
865
866static int nau8824_button_decode(int value)
867{
868 int buttons = 0;
869
870 /* The chip supports up to 8 buttons, but ALSA defines
871 * only 6 buttons.
872 */
873 if (value & BIT(0))
874 buttons |= SND_JACK_BTN_0;
875 if (value & BIT(1))
876 buttons |= SND_JACK_BTN_1;
877 if (value & BIT(2))
878 buttons |= SND_JACK_BTN_2;
879 if (value & BIT(3))
880 buttons |= SND_JACK_BTN_3;
881 if (value & BIT(4))
882 buttons |= SND_JACK_BTN_4;
883 if (value & BIT(5))
884 buttons |= SND_JACK_BTN_5;
885
886 return buttons;
887}
888
889#define NAU8824_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
890 SND_JACK_BTN_2 | SND_JACK_BTN_3)
891
892static irqreturn_t nau8824_interrupt(int irq, void *data)
893{
894 struct nau8824 *nau8824 = (struct nau8824 *)data;
895 struct regmap *regmap = nau8824->regmap;
896 int active_irq, clear_irq = 0, event = 0, event_mask = 0;
897
898 if (regmap_read(regmap, NAU8824_REG_IRQ, &active_irq)) {
899 dev_err(nau8824->dev, "failed to read irq status\n");
900 return IRQ_NONE;
901 }
902 dev_dbg(nau8824->dev, "IRQ %x\n", active_irq);
903
904 if (active_irq & NAU8824_JACK_EJECTION_DETECTED) {
905 nau8824_eject_jack(nau8824);
906 event_mask |= SND_JACK_HEADSET;
907 clear_irq = NAU8824_JACK_EJECTION_DETECTED;
908 /* release semaphore held after resume,
909 * and cancel jack detection
910 */
911 nau8824_sema_release(nau8824);
912 cancel_work_sync(&nau8824->jdet_work);
913 } else if (active_irq & NAU8824_KEY_SHORT_PRESS_IRQ) {
914 int key_status, button_pressed;
915
916 regmap_read(regmap, NAU8824_REG_CLEAR_INT_REG,
917 &key_status);
918
919 /* lower 8 bits of the register are for pressed keys */
920 button_pressed = nau8824_button_decode(key_status);
921
922 event |= button_pressed;
923 dev_dbg(nau8824->dev, "button %x pressed\n", event);
924 event_mask |= NAU8824_BUTTONS;
925 clear_irq = NAU8824_KEY_SHORT_PRESS_IRQ;
926 } else if (active_irq & NAU8824_KEY_RELEASE_IRQ) {
927 event_mask = NAU8824_BUTTONS;
928 clear_irq = NAU8824_KEY_RELEASE_IRQ;
929 } else if (active_irq & NAU8824_JACK_INSERTION_DETECTED) {
930 /* Turn off insertion interruption at manual mode */
931 regmap_update_bits(regmap,
932 NAU8824_REG_INTERRUPT_SETTING,
933 NAU8824_IRQ_INSERT_DIS,
934 NAU8824_IRQ_INSERT_DIS);
935 regmap_update_bits(regmap,
936 NAU8824_REG_INTERRUPT_SETTING_1,
937 NAU8824_IRQ_INSERT_EN, 0);
938 /* detect microphone and jack type */
939 cancel_work_sync(&nau8824->jdet_work);
940 schedule_work(&nau8824->jdet_work);
941
942 /* Enable interruption for jack type detection at audo
943 * mode which can detect microphone and jack type.
944 */
945 nau8824_setup_auto_irq(nau8824);
946 }
947
948 if (!clear_irq)
949 clear_irq = active_irq;
950 /* clears the rightmost interruption */
951 regmap_write(regmap, NAU8824_REG_CLEAR_INT_REG, clear_irq);
952
953 if (event_mask)
954 snd_soc_jack_report(nau8824->jack, event, event_mask);
955
956 return IRQ_HANDLED;
957}
958
959static int nau8824_clock_check(struct nau8824 *nau8824,
960 int stream, int rate, int osr)
961{
962 int osrate;
963
964 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
965 if (osr >= ARRAY_SIZE(osr_dac_sel))
966 return -EINVAL;
967 osrate = osr_dac_sel[osr].osr;
968 } else {
969 if (osr >= ARRAY_SIZE(osr_adc_sel))
970 return -EINVAL;
971 osrate = osr_adc_sel[osr].osr;
972 }
973
974 if (!osrate || rate * osr > CLK_DA_AD_MAX) {
975 dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n");
976 return -EINVAL;
977 }
978
979 return 0;
980}
981
982static int nau8824_hw_params(struct snd_pcm_substream *substream,
983 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
984{
985 struct snd_soc_codec *codec = dai->codec;
986 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
987 unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
988
989 nau8824_sema_acquire(nau8824, HZ);
990
991 /* CLK_DAC or CLK_ADC = OSR * FS
992 * DAC or ADC clock frequency is defined as Over Sampling Rate (OSR)
993 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs
994 * values must be selected such that the maximum frequency is less
995 * than 6.144 MHz.
996 */
997 nau8824->fs = params_rate(params);
998 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
999 regmap_read(nau8824->regmap,
1000 NAU8824_REG_DAC_FILTER_CTRL_1, &osr);
1001 osr &= NAU8824_DAC_OVERSAMPLE_MASK;
1002 if (nau8824_clock_check(nau8824, substream->stream,
1003 nau8824->fs, osr))
1004 return -EINVAL;
1005 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1006 NAU8824_CLK_DAC_SRC_MASK,
1007 osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT);
1008 } else {
1009 regmap_read(nau8824->regmap,
1010 NAU8824_REG_ADC_FILTER_CTRL, &osr);
1011 osr &= NAU8824_ADC_SYNC_DOWN_MASK;
1012 if (nau8824_clock_check(nau8824, substream->stream,
1013 nau8824->fs, osr))
1014 return -EINVAL;
1015 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1016 NAU8824_CLK_ADC_SRC_MASK,
1017 osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT);
1018 }
1019
1020 /* make BCLK and LRC divde configuration if the codec as master. */
1021 regmap_read(nau8824->regmap,
1022 NAU8824_REG_PORT0_I2S_PCM_CTRL_2, &ctrl_val);
1023 if (ctrl_val & NAU8824_I2S_MS_MASTER) {
1024 /* get the bclk and fs ratio */
1025 bclk_fs = snd_soc_params_to_bclk(params) / nau8824->fs;
1026 if (bclk_fs <= 32)
1027 bclk_div = 0x3;
1028 else if (bclk_fs <= 64)
1029 bclk_div = 0x2;
1030 else if (bclk_fs <= 128)
1031 bclk_div = 0x1;
1032 else if (bclk_fs <= 256)
1033 bclk_div = 0;
1034 else
1035 return -EINVAL;
1036 regmap_update_bits(nau8824->regmap,
1037 NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
1038 NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK,
1039 (bclk_div << NAU8824_I2S_LRC_DIV_SFT) | bclk_div);
1040 }
1041
1042 switch (params_width(params)) {
1043 case 16:
1044 val_len |= NAU8824_I2S_DL_16;
1045 break;
1046 case 20:
1047 val_len |= NAU8824_I2S_DL_20;
1048 break;
1049 case 24:
1050 val_len |= NAU8824_I2S_DL_24;
1051 break;
1052 case 32:
1053 val_len |= NAU8824_I2S_DL_32;
1054 break;
1055 default:
1056 return -EINVAL;
1057 }
1058
1059 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
1060 NAU8824_I2S_DL_MASK, val_len);
1061
1062 nau8824_sema_release(nau8824);
1063
1064 return 0;
1065}
1066
1067static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1068{
1069 struct snd_soc_codec *codec = dai->codec;
1070 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1071 unsigned int ctrl1_val = 0, ctrl2_val = 0;
1072
1073 nau8824_sema_acquire(nau8824, HZ);
1074
1075 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1076 case SND_SOC_DAIFMT_CBM_CFM:
1077 ctrl2_val |= NAU8824_I2S_MS_MASTER;
1078 break;
1079 case SND_SOC_DAIFMT_CBS_CFS:
1080 break;
1081 default:
1082 return -EINVAL;
1083 }
1084
1085 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1086 case SND_SOC_DAIFMT_NB_NF:
1087 break;
1088 case SND_SOC_DAIFMT_IB_NF:
1089 ctrl1_val |= NAU8824_I2S_BP_INV;
1090 break;
1091 default:
1092 return -EINVAL;
1093 }
1094
1095 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1096 case SND_SOC_DAIFMT_I2S:
1097 ctrl1_val |= NAU8824_I2S_DF_I2S;
1098 break;
1099 case SND_SOC_DAIFMT_LEFT_J:
1100 ctrl1_val |= NAU8824_I2S_DF_LEFT;
1101 break;
1102 case SND_SOC_DAIFMT_RIGHT_J:
1103 ctrl1_val |= NAU8824_I2S_DF_RIGTH;
1104 break;
1105 case SND_SOC_DAIFMT_DSP_A:
1106 ctrl1_val |= NAU8824_I2S_DF_PCM_AB;
1107 break;
1108 case SND_SOC_DAIFMT_DSP_B:
1109 ctrl1_val |= NAU8824_I2S_DF_PCM_AB;
1110 ctrl1_val |= NAU8824_I2S_PCMB_EN;
1111 break;
1112 default:
1113 return -EINVAL;
1114 }
1115
1116 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
1117 NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
1118 NAU8824_I2S_PCMB_EN, ctrl1_val);
1119 regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
1120 NAU8824_I2S_MS_MASK, ctrl2_val);
1121
1122 nau8824_sema_release(nau8824);
1123
1124 return 0;
1125}
1126
1127/**
1128 * nau8824_calc_fll_param - Calculate FLL parameters.
1129 * @fll_in: external clock provided to codec.
1130 * @fs: sampling rate.
1131 * @fll_param: Pointer to structure of FLL parameters.
1132 *
1133 * Calculate FLL parameters to configure codec.
1134 *
1135 * Returns 0 for success or negative error code.
1136 */
1137static int nau8824_calc_fll_param(unsigned int fll_in,
1138 unsigned int fs, struct nau8824_fll *fll_param)
1139{
1140 u64 fvco, fvco_max;
1141 unsigned int fref, i, fvco_sel;
1142
1143 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
1144 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
1145 * FREF = freq_in / NAU8824_FLL_REF_DIV_MASK
1146 */
1147 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
1148 fref = fll_in / fll_pre_scalar[i].param;
1149 if (fref <= NAU_FREF_MAX)
1150 break;
1151 }
1152 if (i == ARRAY_SIZE(fll_pre_scalar))
1153 return -EINVAL;
1154 fll_param->clk_ref_div = fll_pre_scalar[i].val;
1155
1156 /* Choose the FLL ratio based on FREF */
1157 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
1158 if (fref >= fll_ratio[i].param)
1159 break;
1160 }
1161 if (i == ARRAY_SIZE(fll_ratio))
1162 return -EINVAL;
1163 fll_param->ratio = fll_ratio[i].val;
1164
1165 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
1166 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be
1167 * guaranteed across the full range of operation.
1168 * FDCO = freq_out * 2 * mclk_src_scaling
1169 */
1170 fvco_max = 0;
1171 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
1172 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
1173 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
1174 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
1175 fvco_max < fvco) {
1176 fvco_max = fvco;
1177 fvco_sel = i;
1178 }
1179 }
1180 if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)
1181 return -EINVAL;
1182 fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
1183
1184 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
1185 * input based on FDCO, FREF and FLL ratio.
1186 */
1187 fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
1188 fll_param->fll_int = (fvco >> 16) & 0x3FF;
1189 fll_param->fll_frac = fvco & 0xFFFF;
1190 return 0;
1191}
1192
1193static void nau8824_fll_apply(struct regmap *regmap,
1194 struct nau8824_fll *fll_param)
1195{
1196 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1197 NAU8824_CLK_SRC_MASK | NAU8824_CLK_MCLK_SRC_MASK,
1198 NAU8824_CLK_SRC_MCLK | fll_param->mclk_src);
1199 regmap_update_bits(regmap, NAU8824_REG_FLL1,
1200 NAU8824_FLL_RATIO_MASK, fll_param->ratio);
1201 /* FLL 16-bit fractional input */
1202 regmap_write(regmap, NAU8824_REG_FLL2, fll_param->fll_frac);
1203 /* FLL 10-bit integer input */
1204 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1205 NAU8824_FLL_INTEGER_MASK, fll_param->fll_int);
1206 /* FLL pre-scaler */
1207 regmap_update_bits(regmap, NAU8824_REG_FLL4,
1208 NAU8824_FLL_REF_DIV_MASK,
1209 fll_param->clk_ref_div << NAU8824_FLL_REF_DIV_SFT);
1210 /* select divided VCO input */
1211 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1212 NAU8824_FLL_CLK_SW_MASK, NAU8824_FLL_CLK_SW_REF);
1213 /* Disable free-running mode */
1214 regmap_update_bits(regmap,
1215 NAU8824_REG_FLL6, NAU8824_DCO_EN, 0);
1216 if (fll_param->fll_frac) {
1217 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1218 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1219 NAU8824_FLL_FTR_SW_MASK,
1220 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1221 NAU8824_FLL_FTR_SW_FILTER);
1222 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1223 NAU8824_SDM_EN, NAU8824_SDM_EN);
1224 } else {
1225 regmap_update_bits(regmap, NAU8824_REG_FLL5,
1226 NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN |
1227 NAU8824_FLL_FTR_SW_MASK, NAU8824_FLL_FTR_SW_ACCU);
1228 regmap_update_bits(regmap,
1229 NAU8824_REG_FLL6, NAU8824_SDM_EN, 0);
1230 }
1231}
1232
1233/* freq_out must be 256*Fs in order to achieve the best performance */
1234static int nau8824_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
1235 unsigned int freq_in, unsigned int freq_out)
1236{
1237 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1238 struct nau8824_fll fll_param;
1239 int ret, fs;
1240
1241 fs = freq_out / 256;
1242 ret = nau8824_calc_fll_param(freq_in, fs, &fll_param);
1243 if (ret < 0) {
1244 dev_err(nau8824->dev, "Unsupported input clock %d\n", freq_in);
1245 return ret;
1246 }
1247 dev_dbg(nau8824->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
1248 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
1249 fll_param.fll_int, fll_param.clk_ref_div);
1250
1251 nau8824_fll_apply(nau8824->regmap, &fll_param);
1252 mdelay(2);
1253 regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
1254 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO);
1255
1256 return 0;
1257}
1258
1259static int nau8824_config_sysclk(struct nau8824 *nau8824,
1260 int clk_id, unsigned int freq)
1261{
1262 struct regmap *regmap = nau8824->regmap;
1263
1264 switch (clk_id) {
1265 case NAU8824_CLK_DIS:
1266 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1267 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK);
1268 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1269 NAU8824_DCO_EN, 0);
1270 break;
1271
1272 case NAU8824_CLK_MCLK:
1273 nau8824_sema_acquire(nau8824, HZ);
1274 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1275 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK);
1276 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1277 NAU8824_DCO_EN, 0);
1278 nau8824_sema_release(nau8824);
1279 break;
1280
1281 case NAU8824_CLK_INTERNAL:
1282 regmap_update_bits(regmap, NAU8824_REG_FLL6,
1283 NAU8824_DCO_EN, NAU8824_DCO_EN);
1284 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1285 NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO);
1286 break;
1287
1288 case NAU8824_CLK_FLL_MCLK:
1289 nau8824_sema_acquire(nau8824, HZ);
1290 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1291 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_MCLK);
1292 nau8824_sema_release(nau8824);
1293 break;
1294
1295 case NAU8824_CLK_FLL_BLK:
1296 nau8824_sema_acquire(nau8824, HZ);
1297 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1298 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_BLK);
1299 nau8824_sema_release(nau8824);
1300 break;
1301
1302 case NAU8824_CLK_FLL_FS:
1303 nau8824_sema_acquire(nau8824, HZ);
1304 regmap_update_bits(regmap, NAU8824_REG_FLL3,
1305 NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_FS);
1306 nau8824_sema_release(nau8824);
1307 break;
1308
1309 default:
1310 dev_err(nau8824->dev, "Invalid clock id (%d)\n", clk_id);
1311 return -EINVAL;
1312 }
1313
1314 dev_dbg(nau8824->dev, "Sysclk is %dHz and clock id is %d\n", freq,
1315 clk_id);
1316
1317 return 0;
1318}
1319
1320static int nau8824_set_sysclk(struct snd_soc_codec *codec,
1321 int clk_id, int source, unsigned int freq, int dir)
1322{
1323 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1324
1325 return nau8824_config_sysclk(nau8824, clk_id, freq);
1326}
1327
1328static void nau8824_resume_setup(struct nau8824 *nau8824)
1329{
1330 nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0);
1331 if (nau8824->irq) {
1332 /* Clear all interruption status */
1333 nau8824_int_status_clear_all(nau8824->regmap);
1334 /* Enable jack detection at sleep mode, insertion detection,
1335 * and ejection detection.
1336 */
1337 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL,
1338 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
1339 regmap_update_bits(nau8824->regmap,
1340 NAU8824_REG_INTERRUPT_SETTING_1,
1341 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN,
1342 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN);
1343 regmap_update_bits(nau8824->regmap,
1344 NAU8824_REG_INTERRUPT_SETTING,
1345 NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS, 0);
1346 }
1347}
1348
1349static int nau8824_set_bias_level(struct snd_soc_codec *codec,
1350 enum snd_soc_bias_level level)
1351{
1352 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1353
1354 switch (level) {
1355 case SND_SOC_BIAS_ON:
1356 break;
1357
1358 case SND_SOC_BIAS_PREPARE:
1359 break;
1360
1361 case SND_SOC_BIAS_STANDBY:
1362 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1363 /* Setup codec configuration after resume */
1364 nau8824_resume_setup(nau8824);
1365 }
1366 break;
1367
1368 case SND_SOC_BIAS_OFF:
1369 regmap_update_bits(nau8824->regmap,
1370 NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff);
1371 regmap_update_bits(nau8824->regmap,
1372 NAU8824_REG_INTERRUPT_SETTING_1,
1373 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0);
1374 break;
1375 }
1376
1377 return 0;
1378}
1379
1380static int nau8824_codec_probe(struct snd_soc_codec *codec)
1381{
1382 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1383 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1384
1385 nau8824->dapm = dapm;
1386
1387 return 0;
1388}
1389
1390static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec)
1391{
1392 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1393
1394 if (nau8824->irq) {
1395 disable_irq(nau8824->irq);
1396 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1397 }
1398 regcache_cache_only(nau8824->regmap, true);
1399 regcache_mark_dirty(nau8824->regmap);
1400
1401 return 0;
1402}
1403
1404static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
1405{
1406 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1407
1408 regcache_cache_only(nau8824->regmap, false);
1409 regcache_sync(nau8824->regmap);
1410 if (nau8824->irq) {
1411 /* Hold semaphore to postpone playback happening
1412 * until jack detection done.
1413 */
1414 nau8824_sema_acquire(nau8824, 0);
1415 enable_irq(nau8824->irq);
1416 }
1417
1418 return 0;
1419}
1420
1421static struct snd_soc_codec_driver nau8824_codec_driver = {
1422 .probe = nau8824_codec_probe,
1423 .set_sysclk = nau8824_set_sysclk,
1424 .set_pll = nau8824_set_pll,
1425 .set_bias_level = nau8824_set_bias_level,
1426 .suspend = nau8824_suspend,
1427 .resume = nau8824_resume,
1428 .suspend_bias_off = true,
1429
1430 .component_driver = {
1431 .controls = nau8824_snd_controls,
1432 .num_controls = ARRAY_SIZE(nau8824_snd_controls),
1433 .dapm_widgets = nau8824_dapm_widgets,
1434 .num_dapm_widgets = ARRAY_SIZE(nau8824_dapm_widgets),
1435 .dapm_routes = nau8824_dapm_routes,
1436 .num_dapm_routes = ARRAY_SIZE(nau8824_dapm_routes),
1437 },
1438};
1439
1440static const struct snd_soc_dai_ops nau8824_dai_ops = {
1441 .hw_params = nau8824_hw_params,
1442 .set_fmt = nau8824_set_fmt,
1443};
1444
1445#define NAU8824_RATES SNDRV_PCM_RATE_8000_192000
1446#define NAU8824_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
1447 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
1448
1449static struct snd_soc_dai_driver nau8824_dai = {
1450 .name = NAU8824_CODEC_DAI,
1451 .playback = {
1452 .stream_name = "Playback",
1453 .channels_min = 1,
1454 .channels_max = 2,
1455 .rates = NAU8824_RATES,
1456 .formats = NAU8824_FORMATS,
1457 },
1458 .capture = {
1459 .stream_name = "Capture",
1460 .channels_min = 1,
1461 .channels_max = 2,
1462 .rates = NAU8824_RATES,
1463 .formats = NAU8824_FORMATS,
1464 },
1465 .ops = &nau8824_dai_ops,
1466};
1467
1468static const struct regmap_config nau8824_regmap_config = {
1469 .val_bits = NAU8824_REG_ADDR_LEN,
1470 .reg_bits = NAU8824_REG_DATA_LEN,
1471
1472 .max_register = NAU8824_REG_MAX,
1473 .readable_reg = nau8824_readable_reg,
1474 .writeable_reg = nau8824_writeable_reg,
1475 .volatile_reg = nau8824_volatile_reg,
1476
1477 .cache_type = REGCACHE_RBTREE,
1478 .reg_defaults = nau8824_reg_defaults,
1479 .num_reg_defaults = ARRAY_SIZE(nau8824_reg_defaults),
1480};
1481
1482/**
1483 * nau8824_enable_jack_detect - Specify a jack for event reporting
1484 *
1485 * @component: component to register the jack with
1486 * @jack: jack to use to report headset and button events on
1487 *
1488 * After this function has been called the headset insert/remove and button
1489 * events will be routed to the given jack. Jack can be null to stop
1490 * reporting.
1491 */
1492int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
1493 struct snd_soc_jack *jack)
1494{
1495 struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec);
1496 int ret;
1497
1498 nau8824->jack = jack;
1499 /* Initiate jack detection work queue */
1500 INIT_WORK(&nau8824->jdet_work, nau8824_jdet_work);
1501 ret = devm_request_threaded_irq(nau8824->dev, nau8824->irq, NULL,
1502 nau8824_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1503 "nau8824", nau8824);
1504 if (ret) {
1505 dev_err(nau8824->dev, "Cannot request irq %d (%d)\n",
1506 nau8824->irq, ret);
1507 }
1508
1509 return ret;
1510}
1511EXPORT_SYMBOL_GPL(nau8824_enable_jack_detect);
1512
1513static void nau8824_reset_chip(struct regmap *regmap)
1514{
1515 regmap_write(regmap, NAU8824_REG_RESET, 0x00);
1516 regmap_write(regmap, NAU8824_REG_RESET, 0x00);
1517}
1518
1519static void nau8824_setup_buttons(struct nau8824 *nau8824)
1520{
1521 struct regmap *regmap = nau8824->regmap;
1522
1523 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1524 NAU8824_SAR_TRACKING_GAIN_MASK,
1525 nau8824->sar_voltage << NAU8824_SAR_TRACKING_GAIN_SFT);
1526 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1527 NAU8824_SAR_COMPARE_TIME_MASK,
1528 nau8824->sar_compare_time << NAU8824_SAR_COMPARE_TIME_SFT);
1529 regmap_update_bits(regmap, NAU8824_REG_SAR_ADC,
1530 NAU8824_SAR_SAMPLING_TIME_MASK,
1531 nau8824->sar_sampling_time << NAU8824_SAR_SAMPLING_TIME_SFT);
1532
1533 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1534 NAU8824_LEVELS_NR_MASK,
1535 (nau8824->sar_threshold_num - 1) << NAU8824_LEVELS_NR_SFT);
1536 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1537 NAU8824_HYSTERESIS_MASK,
1538 nau8824->sar_hysteresis << NAU8824_HYSTERESIS_SFT);
1539 regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT,
1540 NAU8824_SHORTKEY_DEBOUNCE_MASK,
1541 nau8824->key_debounce << NAU8824_SHORTKEY_DEBOUNCE_SFT);
1542
1543 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_1,
1544 (nau8824->sar_threshold[0] << 8) | nau8824->sar_threshold[1]);
1545 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_2,
1546 (nau8824->sar_threshold[2] << 8) | nau8824->sar_threshold[3]);
1547 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_3,
1548 (nau8824->sar_threshold[4] << 8) | nau8824->sar_threshold[5]);
1549 regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_4,
1550 (nau8824->sar_threshold[6] << 8) | nau8824->sar_threshold[7]);
1551}
1552
1553static void nau8824_init_regs(struct nau8824 *nau8824)
1554{
1555 struct regmap *regmap = nau8824->regmap;
1556
1557 /* Enable Bias/VMID/VMID Tieoff */
1558 regmap_update_bits(regmap, NAU8824_REG_BIAS_ADJ,
1559 NAU8824_VMID | NAU8824_VMID_SEL_MASK, NAU8824_VMID |
1560 (nau8824->vref_impedance << NAU8824_VMID_SEL_SFT));
1561 regmap_update_bits(regmap, NAU8824_REG_BOOST,
1562 NAU8824_GLOBAL_BIAS_EN, NAU8824_GLOBAL_BIAS_EN);
1563 mdelay(2);
1564 regmap_update_bits(regmap, NAU8824_REG_MIC_BIAS,
1565 NAU8824_MICBIAS_VOLTAGE_MASK, nau8824->micbias_voltage);
1566 /* Disable Boost Driver, Automatic Short circuit protection enable */
1567 regmap_update_bits(regmap, NAU8824_REG_BOOST,
1568 NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS |
1569 NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN,
1570 NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS |
1571 NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN);
1572 /* Scaling for ADC and DAC clock */
1573 regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER,
1574 NAU8824_CLK_ADC_SRC_MASK | NAU8824_CLK_DAC_SRC_MASK,
1575 (0x1 << NAU8824_CLK_ADC_SRC_SFT) |
1576 (0x1 << NAU8824_CLK_DAC_SRC_SFT));
1577 regmap_update_bits(regmap, NAU8824_REG_DAC_MUTE_CTRL,
1578 NAU8824_DAC_ZC_EN, NAU8824_DAC_ZC_EN);
1579 regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL,
1580 NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN |
1581 NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN |
1582 NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN,
1583 NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN |
1584 NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN |
1585 NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN);
1586 regmap_update_bits(regmap, NAU8824_REG_CLK_GATING_ENA,
1587 NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN |
1588 NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN |
1589 NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN |
1590 NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN,
1591 NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN |
1592 NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN |
1593 NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN |
1594 NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN);
1595 /* Class G timer 64ms */
1596 regmap_update_bits(regmap, NAU8824_REG_CLASSG,
1597 NAU8824_CLASSG_TIMER_MASK,
1598 0x20 << NAU8824_CLASSG_TIMER_SFT);
1599 regmap_update_bits(regmap, NAU8824_REG_TRIM_SETTINGS,
1600 NAU8824_DRV_CURR_INC, NAU8824_DRV_CURR_INC);
1601 /* Disable DACR/L power */
1602 regmap_update_bits(regmap, NAU8824_REG_CHARGE_PUMP_CONTROL,
1603 NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN |
1604 NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL,
1605 NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN |
1606 NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL);
1607 /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input
1608 * signal to avoid any glitches due to power up transients in both
1609 * the analog and digital DAC circuit.
1610 */
1611 regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO,
1612 NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN);
1613 /* Config L/R channel */
1614 regmap_update_bits(regmap, NAU8824_REG_DAC_CH0_DGAIN_CTRL,
1615 NAU8824_DAC_CH0_SEL_MASK, NAU8824_DAC_CH0_SEL_I2S0);
1616 regmap_update_bits(regmap, NAU8824_REG_DAC_CH1_DGAIN_CTRL,
1617 NAU8824_DAC_CH1_SEL_MASK, NAU8824_DAC_CH1_SEL_I2S1);
1618 regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO,
1619 NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN,
1620 NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN);
1621 /* Default oversampling/decimations settings are unusable
1622 * (audible hiss). Set it to something better.
1623 */
1624 regmap_update_bits(regmap, NAU8824_REG_ADC_FILTER_CTRL,
1625 NAU8824_ADC_SYNC_DOWN_MASK, NAU8824_ADC_SYNC_DOWN_64);
1626 regmap_update_bits(regmap, NAU8824_REG_DAC_FILTER_CTRL_1,
1627 NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_MASK,
1628 NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_64);
1629 /* DAC clock delay 2ns, VREF */
1630 regmap_update_bits(regmap, NAU8824_REG_RDAC,
1631 NAU8824_RDAC_CLK_DELAY_MASK | NAU8824_RDAC_VREF_MASK,
1632 (0x2 << NAU8824_RDAC_CLK_DELAY_SFT) |
1633 (0x3 << NAU8824_RDAC_VREF_SFT));
1634 /* PGA input mode selection */
1635 regmap_update_bits(regmap, NAU8824_REG_FEPGA,
1636 NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN,
1637 NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN);
1638 /* Digital microphone control */
1639 regmap_update_bits(regmap, NAU8824_REG_ANALOG_CONTROL_1,
1640 NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST,
1641 NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST);
1642 regmap_update_bits(regmap, NAU8824_REG_JACK_DET_CTRL,
1643 NAU8824_JACK_LOGIC,
1644 /* jkdet_polarity - 1 is for active-low */
1645 nau8824->jkdet_polarity ? 0 : NAU8824_JACK_LOGIC);
1646 regmap_update_bits(regmap,
1647 NAU8824_REG_JACK_DET_CTRL, NAU8824_JACK_EJECT_DT_MASK,
1648 (nau8824->jack_eject_debounce << NAU8824_JACK_EJECT_DT_SFT));
1649 if (nau8824->sar_threshold_num)
1650 nau8824_setup_buttons(nau8824);
1651}
1652
1653static int nau8824_setup_irq(struct nau8824 *nau8824)
1654{
1655 /* Disable interruption before codec initiation done */
1656 regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL,
1657 NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE);
1658 regmap_update_bits(nau8824->regmap,
1659 NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff);
1660 regmap_update_bits(nau8824->regmap, NAU8824_REG_INTERRUPT_SETTING_1,
1661 NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0);
1662
1663 return 0;
1664}
1665
1666static void nau8824_print_device_properties(struct nau8824 *nau8824)
1667{
1668 struct device *dev = nau8824->dev;
1669 int i;
1670
1671 dev_dbg(dev, "jkdet-polarity: %d\n", nau8824->jkdet_polarity);
1672 dev_dbg(dev, "micbias-voltage: %d\n", nau8824->micbias_voltage);
1673 dev_dbg(dev, "vref-impedance: %d\n", nau8824->vref_impedance);
1674
1675 dev_dbg(dev, "sar-threshold-num: %d\n", nau8824->sar_threshold_num);
1676 for (i = 0; i < nau8824->sar_threshold_num; i++)
1677 dev_dbg(dev, "sar-threshold[%d]=%x\n", i,
1678 nau8824->sar_threshold[i]);
1679
1680 dev_dbg(dev, "sar-hysteresis: %d\n", nau8824->sar_hysteresis);
1681 dev_dbg(dev, "sar-voltage: %d\n", nau8824->sar_voltage);
1682 dev_dbg(dev, "sar-compare-time: %d\n", nau8824->sar_compare_time);
1683 dev_dbg(dev, "sar-sampling-time: %d\n", nau8824->sar_sampling_time);
1684 dev_dbg(dev, "short-key-debounce: %d\n", nau8824->key_debounce);
1685 dev_dbg(dev, "jack-eject-debounce: %d\n",
1686 nau8824->jack_eject_debounce);
1687}
1688
1689static int nau8824_read_device_properties(struct device *dev,
1690 struct nau8824 *nau8824) {
1691 int ret;
1692
1693 ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
1694 &nau8824->jkdet_polarity);
1695 if (ret)
1696 nau8824->jkdet_polarity = 1;
1697 ret = device_property_read_u32(dev, "nuvoton,micbias-voltage",
1698 &nau8824->micbias_voltage);
1699 if (ret)
1700 nau8824->micbias_voltage = 6;
1701 ret = device_property_read_u32(dev, "nuvoton,vref-impedance",
1702 &nau8824->vref_impedance);
1703 if (ret)
1704 nau8824->vref_impedance = 2;
1705 ret = device_property_read_u32(dev, "nuvoton,sar-threshold-num",
1706 &nau8824->sar_threshold_num);
1707 if (ret)
1708 nau8824->sar_threshold_num = 4;
1709 ret = device_property_read_u32_array(dev, "nuvoton,sar-threshold",
1710 nau8824->sar_threshold, nau8824->sar_threshold_num);
1711 if (ret) {
1712 nau8824->sar_threshold[0] = 0x0a;
1713 nau8824->sar_threshold[1] = 0x14;
1714 nau8824->sar_threshold[2] = 0x26;
1715 nau8824->sar_threshold[3] = 0x73;
1716 }
1717 ret = device_property_read_u32(dev, "nuvoton,sar-hysteresis",
1718 &nau8824->sar_hysteresis);
1719 if (ret)
1720 nau8824->sar_hysteresis = 0;
1721 ret = device_property_read_u32(dev, "nuvoton,sar-voltage",
1722 &nau8824->sar_voltage);
1723 if (ret)
1724 nau8824->sar_voltage = 6;
1725 ret = device_property_read_u32(dev, "nuvoton,sar-compare-time",
1726 &nau8824->sar_compare_time);
1727 if (ret)
1728 nau8824->sar_compare_time = 1;
1729 ret = device_property_read_u32(dev, "nuvoton,sar-sampling-time",
1730 &nau8824->sar_sampling_time);
1731 if (ret)
1732 nau8824->sar_sampling_time = 1;
1733 ret = device_property_read_u32(dev, "nuvoton,short-key-debounce",
1734 &nau8824->key_debounce);
1735 if (ret)
1736 nau8824->key_debounce = 0;
1737 ret = device_property_read_u32(dev, "nuvoton,jack-eject-debounce",
1738 &nau8824->jack_eject_debounce);
1739 if (ret)
1740 nau8824->jack_eject_debounce = 1;
1741
1742 return 0;
1743}
1744
1745static int nau8824_i2c_probe(struct i2c_client *i2c,
1746 const struct i2c_device_id *id)
1747{
1748 struct device *dev = &i2c->dev;
1749 struct nau8824 *nau8824 = dev_get_platdata(dev);
1750 int ret, value;
1751
1752 if (!nau8824) {
1753 nau8824 = devm_kzalloc(dev, sizeof(*nau8824), GFP_KERNEL);
1754 if (!nau8824)
1755 return -ENOMEM;
1756 ret = nau8824_read_device_properties(dev, nau8824);
1757 if (ret)
1758 return ret;
1759 }
1760 i2c_set_clientdata(i2c, nau8824);
1761
1762 nau8824->regmap = devm_regmap_init_i2c(i2c, &nau8824_regmap_config);
1763 if (IS_ERR(nau8824->regmap))
1764 return PTR_ERR(nau8824->regmap);
1765 nau8824->dev = dev;
1766 nau8824->irq = i2c->irq;
1767 sema_init(&nau8824->jd_sem, 1);
1768
1769 nau8824_print_device_properties(nau8824);
1770
1771 ret = regmap_read(nau8824->regmap, NAU8824_REG_I2C_DEVICE_ID, &value);
1772 if (ret < 0) {
1773 dev_err(dev, "Failed to read device id from the NAU8824: %d\n",
1774 ret);
1775 return ret;
1776 }
1777 nau8824_reset_chip(nau8824->regmap);
1778 nau8824_init_regs(nau8824);
1779
1780 if (i2c->irq)
1781 nau8824_setup_irq(nau8824);
1782
1783 return snd_soc_register_codec(dev,
1784 &nau8824_codec_driver, &nau8824_dai, 1);
1785}
1786
1787
1788static int nau8824_i2c_remove(struct i2c_client *client)
1789{
1790 snd_soc_unregister_codec(&client->dev);
1791 return 0;
1792}
1793
1794static const struct i2c_device_id nau8824_i2c_ids[] = {
1795 { "nau8824", 0 },
1796 { }
1797};
1798MODULE_DEVICE_TABLE(i2c, nau8824_i2c_ids);
1799
1800#ifdef CONFIG_OF
1801static const struct of_device_id nau8824_of_ids[] = {
1802 { .compatible = "nuvoton,nau8824", },
1803 {}
1804};
1805MODULE_DEVICE_TABLE(of, nau8824_of_ids);
1806#endif
1807
1808#ifdef CONFIG_ACPI
1809static const struct acpi_device_id nau8824_acpi_match[] = {
1810 { "10508824", 0 },
1811 {},
1812};
1813MODULE_DEVICE_TABLE(acpi, nau8824_acpi_match);
1814#endif
1815
1816static struct i2c_driver nau8824_i2c_driver = {
1817 .driver = {
1818 .name = "nau8824",
1819 .of_match_table = of_match_ptr(nau8824_of_ids),
1820 .acpi_match_table = ACPI_PTR(nau8824_acpi_match),
1821 },
1822 .probe = nau8824_i2c_probe,
1823 .remove = nau8824_i2c_remove,
1824 .id_table = nau8824_i2c_ids,
1825};
1826module_i2c_driver(nau8824_i2c_driver);
1827
1828
1829MODULE_DESCRIPTION("ASoC NAU88L24 driver");
1830MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");
1831MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/nau8824.h b/sound/soc/codecs/nau8824.h
new file mode 100644
index 000000000000..87ac9a382aed
--- /dev/null
+++ b/sound/soc/codecs/nau8824.h
@@ -0,0 +1,466 @@
1/*
2 * NAU88L24 ALSA SoC audio driver
3 *
4 * Copyright 2016 Nuvoton Technology Corp.
5 * Author: John Hsu <KCHSU0@nuvoton.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 __NAU8824_H__
13#define __NAU8824_H__
14
15#define NAU8824_REG_RESET 0x00
16#define NAU8824_REG_ENA_CTRL 0x01
17#define NAU8824_REG_CLK_GATING_ENA 0x02
18#define NAU8824_REG_CLK_DIVIDER 0x03
19#define NAU8824_REG_FLL1 0x04
20#define NAU8824_REG_FLL2 0x05
21#define NAU8824_REG_FLL3 0x06
22#define NAU8824_REG_FLL4 0x07
23#define NAU8824_REG_FLL5 0x08
24#define NAU8824_REG_FLL6 0x09
25#define NAU8824_REG_FLL_VCO_RSV 0x0A
26#define NAU8824_REG_JACK_DET_CTRL 0x0D
27#define NAU8824_REG_INTERRUPT_SETTING_1 0x0F
28#define NAU8824_REG_IRQ 0x10
29#define NAU8824_REG_CLEAR_INT_REG 0x11
30#define NAU8824_REG_INTERRUPT_SETTING 0x12
31#define NAU8824_REG_SAR_ADC 0x13
32#define NAU8824_REG_VDET_COEFFICIENT 0x14
33#define NAU8824_REG_VDET_THRESHOLD_1 0x15
34#define NAU8824_REG_VDET_THRESHOLD_2 0x16
35#define NAU8824_REG_VDET_THRESHOLD_3 0x17
36#define NAU8824_REG_VDET_THRESHOLD_4 0x18
37#define NAU8824_REG_GPIO_SEL 0x1A
38#define NAU8824_REG_PORT0_I2S_PCM_CTRL_1 0x1C
39#define NAU8824_REG_PORT0_I2S_PCM_CTRL_2 0x1D
40#define NAU8824_REG_PORT0_LEFT_TIME_SLOT 0x1E
41#define NAU8824_REG_PORT0_RIGHT_TIME_SLOT 0x1F
42#define NAU8824_REG_TDM_CTRL 0x20
43#define NAU8824_REG_ADC_HPF_FILTER 0x23
44#define NAU8824_REG_ADC_FILTER_CTRL 0x24
45#define NAU8824_REG_DAC_FILTER_CTRL_1 0x25
46#define NAU8824_REG_DAC_FILTER_CTRL_2 0x26
47#define NAU8824_REG_NOTCH_FILTER_1 0x27
48#define NAU8824_REG_NOTCH_FILTER_2 0x28
49#define NAU8824_REG_EQ1_LOW 0x29
50#define NAU8824_REG_EQ2_EQ3 0x2A
51#define NAU8824_REG_EQ4_EQ5 0x2B
52#define NAU8824_REG_ADC_CH0_DGAIN_CTRL 0x2D
53#define NAU8824_REG_ADC_CH1_DGAIN_CTRL 0x2E
54#define NAU8824_REG_ADC_CH2_DGAIN_CTRL 0x2F
55#define NAU8824_REG_ADC_CH3_DGAIN_CTRL 0x30
56#define NAU8824_REG_DAC_MUTE_CTRL 0x31
57#define NAU8824_REG_DAC_CH0_DGAIN_CTRL 0x32
58#define NAU8824_REG_DAC_CH1_DGAIN_CTRL 0x33
59#define NAU8824_REG_ADC_TO_DAC_ST 0x34
60#define NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 0x38
61#define NAU8824_REG_DRC_KNEE_IP34_ADC_CH01 0x39
62#define NAU8824_REG_DRC_SLOPE_ADC_CH01 0x3A
63#define NAU8824_REG_DRC_ATKDCY_ADC_CH01 0x3B
64#define NAU8824_REG_DRC_KNEE_IP12_ADC_CH23 0x3C
65#define NAU8824_REG_DRC_KNEE_IP34_ADC_CH23 0x3D
66#define NAU8824_REG_DRC_SLOPE_ADC_CH23 0x3E
67#define NAU8824_REG_DRC_ATKDCY_ADC_CH23 0x3F
68#define NAU8824_REG_DRC_GAINL_ADC0 0x40
69#define NAU8824_REG_DRC_GAINL_ADC1 0x41
70#define NAU8824_REG_DRC_GAINL_ADC2 0x42
71#define NAU8824_REG_DRC_GAINL_ADC3 0x43
72#define NAU8824_REG_DRC_KNEE_IP12_DAC 0x45
73#define NAU8824_REG_DRC_KNEE_IP34_DAC 0x46
74#define NAU8824_REG_DRC_SLOPE_DAC 0x47
75#define NAU8824_REG_DRC_ATKDCY_DAC 0x48
76#define NAU8824_REG_DRC_GAIN_DAC_CH0 0x49
77#define NAU8824_REG_DRC_GAIN_DAC_CH1 0x4A
78#define NAU8824_REG_MODE 0x4C
79#define NAU8824_REG_MODE1 0x4D
80#define NAU8824_REG_MODE2 0x4E
81#define NAU8824_REG_CLASSG 0x50
82#define NAU8824_REG_OTP_EFUSE 0x51
83#define NAU8824_REG_OTPDOUT_1 0x53
84#define NAU8824_REG_OTPDOUT_2 0x54
85#define NAU8824_REG_MISC_CTRL 0x55
86#define NAU8824_REG_I2C_TIMEOUT 0x56
87#define NAU8824_REG_TEST_MODE 0x57
88#define NAU8824_REG_I2C_DEVICE_ID 0x58
89#define NAU8824_REG_SAR_ADC_DATA_OUT 0x59
90#define NAU8824_REG_BIAS_ADJ 0x66
91#define NAU8824_REG_PGA_GAIN 0x67
92#define NAU8824_REG_TRIM_SETTINGS 0x68
93#define NAU8824_REG_ANALOG_CONTROL_1 0x69
94#define NAU8824_REG_ANALOG_CONTROL_2 0x6A
95#define NAU8824_REG_ENABLE_LO 0x6B
96#define NAU8824_REG_GAIN_LO 0x6C
97#define NAU8824_REG_CLASSD_GAIN_1 0x6D
98#define NAU8824_REG_CLASSD_GAIN_2 0x6E
99#define NAU8824_REG_ANALOG_ADC_1 0x71
100#define NAU8824_REG_ANALOG_ADC_2 0x72
101#define NAU8824_REG_RDAC 0x73
102#define NAU8824_REG_MIC_BIAS 0x74
103#define NAU8824_REG_HS_VOLUME_CONTROL 0x75
104#define NAU8824_REG_BOOST 0x76
105#define NAU8824_REG_FEPGA 0x77
106#define NAU8824_REG_FEPGA_II 0x78
107#define NAU8824_REG_FEPGA_SE 0x79
108#define NAU8824_REG_FEPGA_ATTENUATION 0x7A
109#define NAU8824_REG_ATT_PORT0 0x7B
110#define NAU8824_REG_ATT_PORT1 0x7C
111#define NAU8824_REG_POWER_UP_CONTROL 0x7F
112#define NAU8824_REG_CHARGE_PUMP_CONTROL 0x80
113#define NAU8824_REG_CHARGE_PUMP_INPUT 0x81
114#define NAU8824_REG_MAX NAU8824_REG_CHARGE_PUMP_INPUT
115/* 16-bit control register address, and 16-bits control register data */
116#define NAU8824_REG_ADDR_LEN 16
117#define NAU8824_REG_DATA_LEN 16
118
119
120/* ENA_CTRL (0x1) */
121#define NAU8824_DMIC_LCH_EDGE_CH23 (0x1 << 12)
122#define NAU8824_DMIC_LCH_EDGE_CH01 (0x1 << 11)
123#define NAU8824_JD_SLEEP_MODE (0x1 << 10)
124#define NAU8824_ADC_CH3_DMIC_SFT 9
125#define NAU8824_ADC_CH3_DMIC_EN (0x1 << NAU8824_ADC_CH3_DMIC_SFT)
126#define NAU8824_ADC_CH2_DMIC_SFT 8
127#define NAU8824_ADC_CH2_DMIC_EN (0x1 << NAU8824_ADC_CH2_DMIC_SFT)
128#define NAU8824_ADC_CH1_DMIC_SFT 7
129#define NAU8824_ADC_CH1_DMIC_EN (0x1 << NAU8824_ADC_CH1_DMIC_SFT)
130#define NAU8824_ADC_CH0_DMIC_SFT 6
131#define NAU8824_ADC_CH0_DMIC_EN (0x1 << NAU8824_ADC_CH0_DMIC_SFT)
132#define NAU8824_DAC_CH1_EN (0x1 << 5)
133#define NAU8824_DAC_CH0_EN (0x1 << 4)
134#define NAU8824_ADC_CH3_EN (0x1 << 3)
135#define NAU8824_ADC_CH2_EN (0x1 << 2)
136#define NAU8824_ADC_CH1_EN (0x1 << 1)
137#define NAU8824_ADC_CH0_EN 0x1
138
139/* CLK_GATING_ENA (0x02) */
140#define NAU8824_CLK_ADC_CH23_EN (0x1 << 15)
141#define NAU8824_CLK_ADC_CH01_EN (0x1 << 14)
142#define NAU8824_CLK_DAC_CH1_EN (0x1 << 13)
143#define NAU8824_CLK_DAC_CH0_EN (0x1 << 12)
144#define NAU8824_CLK_I2S_EN (0x1 << 7)
145#define NAU8824_CLK_GAIN_EN (0x1 << 5)
146#define NAU8824_CLK_SAR_EN (0x1 << 3)
147#define NAU8824_CLK_DMIC_CH23_EN (0x1 << 1)
148
149/* CLK_DIVIDER (0x3) */
150#define NAU8824_CLK_SRC_SFT 15
151#define NAU8824_CLK_SRC_MASK (1 << NAU8824_CLK_SRC_SFT)
152#define NAU8824_CLK_SRC_VCO (1 << NAU8824_CLK_SRC_SFT)
153#define NAU8824_CLK_SRC_MCLK (0 << NAU8824_CLK_SRC_SFT)
154#define NAU8824_CLK_MCLK_SRC_MASK (0xf << 0)
155#define NAU8824_CLK_DMIC_SRC_SFT 10
156#define NAU8824_CLK_DMIC_SRC_MASK (0x7 << NAU8824_CLK_DMIC_SRC_SFT)
157#define NAU8824_CLK_ADC_SRC_SFT 6
158#define NAU8824_CLK_ADC_SRC_MASK (0x3 << NAU8824_CLK_ADC_SRC_SFT)
159#define NAU8824_CLK_DAC_SRC_SFT 4
160#define NAU8824_CLK_DAC_SRC_MASK (0x3 << NAU8824_CLK_DAC_SRC_SFT)
161
162/* FLL1 (0x04) */
163#define NAU8824_FLL_RATIO_MASK (0x7f << 0)
164
165/* FLL3 (0x06) */
166#define NAU8824_FLL_INTEGER_MASK (0x3ff << 0)
167#define NAU8824_FLL_CLK_SRC_SFT 10
168#define NAU8824_FLL_CLK_SRC_MASK (0x3 << NAU8824_FLL_CLK_SRC_SFT)
169#define NAU8824_FLL_CLK_SRC_MCLK (0 << NAU8824_FLL_CLK_SRC_SFT)
170#define NAU8824_FLL_CLK_SRC_BLK (0x2 << NAU8824_FLL_CLK_SRC_SFT)
171#define NAU8824_FLL_CLK_SRC_FS (0x3 << NAU8824_FLL_CLK_SRC_SFT)
172
173/* FLL4 (0x07) */
174#define NAU8824_FLL_REF_DIV_SFT 10
175#define NAU8824_FLL_REF_DIV_MASK (0x3 << NAU8824_FLL_REF_DIV_SFT)
176
177/* FLL5 (0x08) */
178#define NAU8824_FLL_PDB_DAC_EN (0x1 << 15)
179#define NAU8824_FLL_LOOP_FTR_EN (0x1 << 14)
180#define NAU8824_FLL_CLK_SW_MASK (0x1 << 13)
181#define NAU8824_FLL_CLK_SW_N2 (0x1 << 13)
182#define NAU8824_FLL_CLK_SW_REF (0x0 << 13)
183#define NAU8824_FLL_FTR_SW_MASK (0x1 << 12)
184#define NAU8824_FLL_FTR_SW_ACCU (0x1 << 12)
185#define NAU8824_FLL_FTR_SW_FILTER (0x0 << 12)
186
187/* FLL6 (0x9) */
188#define NAU8824_DCO_EN (0x1 << 15)
189#define NAU8824_SDM_EN (0x1 << 14)
190
191/* IRQ (0x10) */
192#define NAU8824_SHORT_CIRCUIT_IRQ (0x1 << 7)
193#define NAU8824_IMPEDANCE_MEAS_IRQ (0x1 << 6)
194#define NAU8824_KEY_RELEASE_IRQ (0x1 << 5)
195#define NAU8824_KEY_LONG_PRESS_IRQ (0x1 << 4)
196#define NAU8824_KEY_SHORT_PRESS_IRQ (0x1 << 3)
197#define NAU8824_JACK_EJECTION_DETECTED (0x1 << 1)
198#define NAU8824_JACK_INSERTION_DETECTED 0x1
199
200/* JACK_DET_CTRL (0x0D) */
201#define NAU8824_JACK_EJECT_DT_SFT 2
202#define NAU8824_JACK_EJECT_DT_MASK (0x3 << NAU8824_JACK_EJECT_DT_SFT)
203#define NAU8824_JACK_LOGIC 0x1
204
205
206/* INTERRUPT_SETTING_1 (0x0F) */
207#define NAU8824_IRQ_EJECT_EN (0x1 << 9)
208#define NAU8824_IRQ_INSERT_EN (0x1 << 8)
209
210/* INTERRUPT_SETTING (0x12) */
211#define NAU8824_IRQ_KEY_RELEASE_DIS (0x1 << 5)
212#define NAU8824_IRQ_KEY_SHORT_PRESS_DIS (0x1 << 3)
213#define NAU8824_IRQ_EJECT_DIS (0x1 << 1)
214#define NAU8824_IRQ_INSERT_DIS 0x1
215
216/* SAR_ADC (0x13) */
217#define NAU8824_SAR_ADC_EN_SFT 12
218#define NAU8824_SAR_TRACKING_GAIN_SFT 8
219#define NAU8824_SAR_TRACKING_GAIN_MASK (0x7 << NAU8824_SAR_TRACKING_GAIN_SFT)
220#define NAU8824_SAR_COMPARE_TIME_SFT 2
221#define NAU8824_SAR_COMPARE_TIME_MASK (3 << 2)
222#define NAU8824_SAR_SAMPLING_TIME_SFT 0
223#define NAU8824_SAR_SAMPLING_TIME_MASK (3 << 0)
224
225/* VDET_COEFFICIENT (0x14) */
226#define NAU8824_SHORTKEY_DEBOUNCE_SFT 12
227#define NAU8824_SHORTKEY_DEBOUNCE_MASK (0x3 << NAU8824_SHORTKEY_DEBOUNCE_SFT)
228#define NAU8824_LEVELS_NR_SFT 8
229#define NAU8824_LEVELS_NR_MASK (0x7 << 8)
230#define NAU8824_HYSTERESIS_SFT 0
231#define NAU8824_HYSTERESIS_MASK 0xf
232
233/* PORT0_I2S_PCM_CTRL_1 (0x1C) */
234#define NAU8824_I2S_BP_SFT 7
235#define NAU8824_I2S_BP_MASK (1 << NAU8824_I2S_BP_SFT)
236#define NAU8824_I2S_BP_INV (1 << NAU8824_I2S_BP_SFT)
237#define NAU8824_I2S_PCMB_SFT 6
238#define NAU8824_I2S_PCMB_EN (1 << NAU8824_I2S_PCMB_SFT)
239#define NAU8824_I2S_DL_SFT 2
240#define NAU8824_I2S_DL_MASK (0x3 << NAU8824_I2S_DL_SFT)
241#define NAU8824_I2S_DL_16 (0 << NAU8824_I2S_DL_SFT)
242#define NAU8824_I2S_DL_20 (1 << NAU8824_I2S_DL_SFT)
243#define NAU8824_I2S_DL_24 (2 << NAU8824_I2S_DL_SFT)
244#define NAU8824_I2S_DL_32 (3 << NAU8824_I2S_DL_SFT)
245#define NAU8824_I2S_DF_MASK 0x3
246#define NAU8824_I2S_DF_RIGTH 0
247#define NAU8824_I2S_DF_LEFT 1
248#define NAU8824_I2S_DF_I2S 2
249#define NAU8824_I2S_DF_PCM_AB 3
250
251
252/* PORT0_I2S_PCM_CTRL_2 (0x1D) */
253#define NAU8824_I2S_LRC_DIV_SFT 12
254#define NAU8824_I2S_LRC_DIV_MASK (0x3 << NAU8824_I2S_LRC_DIV_SFT)
255#define NAU8824_I2S_MS_SFT 3
256#define NAU8824_I2S_MS_MASK (1 << NAU8824_I2S_MS_SFT)
257#define NAU8824_I2S_MS_MASTER (1 << NAU8824_I2S_MS_SFT)
258#define NAU8824_I2S_MS_SLAVE (0 << NAU8824_I2S_MS_SFT)
259#define NAU8824_I2S_BLK_DIV_MASK 0x7
260
261/* ADC_FILTER_CTRL (0x24) */
262#define NAU8824_ADC_SYNC_DOWN_MASK 0x3
263#define NAU8824_ADC_SYNC_DOWN_32 0
264#define NAU8824_ADC_SYNC_DOWN_64 1
265#define NAU8824_ADC_SYNC_DOWN_128 2
266#define NAU8824_ADC_SYNC_DOWN_256 3
267
268/* DAC_FILTER_CTRL_1 (0x25) */
269#define NAU8824_DAC_CICCLP_OFF (0x1 << 7)
270#define NAU8824_DAC_OVERSAMPLE_MASK 0x7
271#define NAU8824_DAC_OVERSAMPLE_64 0
272#define NAU8824_DAC_OVERSAMPLE_256 1
273#define NAU8824_DAC_OVERSAMPLE_128 2
274#define NAU8824_DAC_OVERSAMPLE_32 4
275
276/* DAC_MUTE_CTRL (0x31) */
277#define NAU8824_DAC_CH01_MIX 0x3
278#define NAU8824_DAC_ZC_EN (0x1 << 11)
279
280/* DAC_CH0_DGAIN_CTRL (0x32) */
281#define NAU8824_DAC_CH0_SEL_SFT 9
282#define NAU8824_DAC_CH0_SEL_MASK (0x1 << NAU8824_DAC_CH0_SEL_SFT)
283#define NAU8824_DAC_CH0_SEL_I2S0 (0x0 << NAU8824_DAC_CH0_SEL_SFT)
284#define NAU8824_DAC_CH0_SEL_I2S1 (0x1 << NAU8824_DAC_CH0_SEL_SFT)
285#define NAU8824_DAC_CH0_VOL_MASK 0x1ff
286
287/* DAC_CH1_DGAIN_CTRL (0x33) */
288#define NAU8824_DAC_CH1_SEL_SFT 9
289#define NAU8824_DAC_CH1_SEL_MASK (0x1 << NAU8824_DAC_CH1_SEL_SFT)
290#define NAU8824_DAC_CH1_SEL_I2S0 (0x0 << NAU8824_DAC_CH1_SEL_SFT)
291#define NAU8824_DAC_CH1_SEL_I2S1 (0x1 << NAU8824_DAC_CH1_SEL_SFT)
292#define NAU8824_DAC_CH1_VOL_MASK 0x1ff
293
294/* CLASSG (0x50) */
295#define NAU8824_CLASSG_TIMER_SFT 8
296#define NAU8824_CLASSG_TIMER_MASK (0x3f << NAU8824_CLASSG_TIMER_SFT)
297#define NAU8824_CLASSG_LDAC_EN_SFT 2
298#define NAU8824_CLASSG_RDAC_EN_SFT 1
299#define NAU8824_CLASSG_EN_SFT 0
300
301/* SAR_ADC_DATA_OUT (0x59) */
302#define NAU8824_SAR_ADC_DATA_MASK 0xff
303
304/* BIAS_ADJ (0x66) */
305#define NAU8824_VMID (1 << 6)
306#define NAU8824_VMID_SEL_SFT 4
307#define NAU8824_VMID_SEL_MASK (3 << NAU8824_VMID_SEL_SFT)
308#define NAU8824_DMIC2_EN_SFT 3
309#define NAU8824_DMIC1_EN_SFT 2
310
311/* TRIM_SETTINGS (0x68) */
312#define NAU8824_DRV_CURR_INC (1 << 15)
313
314/* ANALOG_CONTROL_1 (0x69) */
315#define NAU8824_DMIC_CLK_DRV_STRG (1 << 3)
316#define NAU8824_DMIC_CLK_SLEW_FAST (0x7)
317
318/* ANALOG_CONTROL_2 (0x6A) */
319#define NAU8824_CLASSD_CLAMP_DIS_SFT 3
320#define NAU8824_CLASSD_CLAMP_DIS (0x1 << NAU8824_CLASSD_CLAMP_DIS_SFT)
321
322/* ENABLE_LO (0x6B) */
323#define NAU8824_TEST_DAC_SFT 14
324#define NAU8824_TEST_DAC_EN (0x3 << NAU8824_TEST_DAC_SFT)
325#define NAU8824_DACL_HPR_EN_SFT 3
326#define NAU8824_DACL_HPR_EN (0x1 << NAU8824_DACL_HPR_EN_SFT)
327#define NAU8824_DACR_HPR_EN_SFT 2
328#define NAU8824_DACR_HPR_EN (0x1 << NAU8824_DACR_HPR_EN_SFT)
329#define NAU8824_DACR_HPL_EN_SFT 1
330#define NAU8824_DACR_HPL_EN (0x1 << NAU8824_DACR_HPL_EN_SFT)
331#define NAU8824_DACL_HPL_EN_SFT 0
332#define NAU8824_DACL_HPL_EN 0x1
333
334/* CLASSD_GAIN_1 (0x6D) */
335#define NAU8824_CLASSD_GAIN_1R_SFT 8
336#define NAU8824_CLASSD_GAIN_1R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT)
337#define NAU8824_CLASSD_EN_SFT 7
338#define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT)
339#define NAU8824_CLASSD_GAIN_1L_MASK 0x1f
340
341/* CLASSD_GAIN_2 (0x6E) */
342#define NAU8824_CLASSD_GAIN_2R_SFT 8
343#define NAU8824_CLASSD_GAIN_2R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT)
344#define NAU8824_CLASSD_EN_SFT 7
345#define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT)
346#define NAU8824_CLASSD_GAIN_2L_MASK 0x1f
347
348/* ANALOG_ADC_2 (0x72) */
349#define NAU8824_ADCR_EN_SFT 7
350#define NAU8824_ADCL_EN_SFT 6
351
352/* RDAC (0x73) */
353#define NAU8824_DACR_EN_SFT 13
354#define NAU8824_DACL_EN_SFT 12
355#define NAU8824_DACR_CLK_SFT 9
356#define NAU8824_DACL_CLK_SFT 8
357#define NAU8824_RDAC_CLK_DELAY_SFT 4
358#define NAU8824_RDAC_CLK_DELAY_MASK (0x7 << NAU8824_RDAC_CLK_DELAY_SFT)
359#define NAU8824_RDAC_VREF_SFT 2
360#define NAU8824_RDAC_VREF_MASK (0x3 << NAU8824_RDAC_VREF_SFT)
361
362/* MIC_BIAS (0x74) */
363#define NAU8824_MICBIAS_JKSLV (1 << 14)
364#define NAU8824_MICBIAS_JKR2 (1 << 12)
365#define NAU8824_MICBIAS_POWERUP_SFT 8
366#define NAU8824_MICBIAS_VOLTAGE_SFT 0
367#define NAU8824_MICBIAS_VOLTAGE_MASK 0x7
368
369/* BOOST (0x76) */
370#define NAU8824_PRECHARGE_DIS (0x1 << 13)
371#define NAU8824_GLOBAL_BIAS_EN (0x1 << 12)
372#define NAU8824_HP_BOOST_DIS_SFT 9
373#define NAU8824_HP_BOOST_DIS (0x1 << NAU8824_HP_BOOST_DIS_SFT)
374#define NAU8824_HP_BOOST_G_DIS_SFT 8
375#define NAU8824_HP_BOOST_G_DIS (0x1 << NAU8824_HP_BOOST_G_DIS_SFT)
376#define NAU8824_SHORT_SHUTDOWN_DIG_EN (1 << 7)
377#define NAU8824_SHORT_SHUTDOWN_EN (1 << 6)
378
379/* FEPGA (0x77) */
380#define NAU8824_FEPGA_MODER_SHORT_SFT 7
381#define NAU8824_FEPGA_MODER_SHORT_EN (0x1 << NAU8824_FEPGA_MODER_SHORT_SFT)
382#define NAU8824_FEPGA_MODER_MIC2_SFT 5
383#define NAU8824_FEPGA_MODER_MIC2_EN (0x1 << NAU8824_FEPGA_MODER_MIC2_SFT)
384#define NAU8824_FEPGA_MODER_HSMIC_SFT 4
385#define NAU8824_FEPGA_MODER_HSMIC_EN (0x1 << NAU8824_FEPGA_MODER_HSMIC_SFT)
386#define NAU8824_FEPGA_MODEL_SHORT_SFT 3
387#define NAU8824_FEPGA_MODEL_SHORT_EN (0x1 << NAU8824_FEPGA_MODEL_SHORT_SFT)
388#define NAU8824_FEPGA_MODEL_MIC1_SFT 1
389#define NAU8824_FEPGA_MODEL_MIC1_EN (0x1 << NAU8824_FEPGA_MODEL_MIC1_SFT)
390#define NAU8824_FEPGA_MODEL_HSMIC_SFT 0
391#define NAU8824_FEPGA_MODEL_HSMIC_EN (0x1 << NAU8824_FEPGA_MODEL_HSMIC_SFT)
392
393/* FEPGA_II (0x78) */
394#define NAU8824_FEPGA_GAINR_SFT 5
395#define NAU8824_FEPGA_GAINR_MASK (0x1f << NAU8824_FEPGA_GAINR_SFT)
396#define NAU8824_FEPGA_GAINL_SFT 0
397#define NAU8824_FEPGA_GAINL_MASK 0x1f
398
399/* CHARGE_PUMP_CONTROL (0x80) */
400#define NAU8824_JAMNODCLOW (0x1 << 15)
401#define NAU8824_SPKR_PULL_DOWN (0x1 << 13)
402#define NAU8824_SPKL_PULL_DOWN (0x1 << 12)
403#define NAU8824_POWER_DOWN_DACR (0x1 << 9)
404#define NAU8824_POWER_DOWN_DACL (0x1 << 8)
405#define NAU8824_CHARGE_PUMP_EN_SFT 5
406#define NAU8824_CHARGE_PUMP_EN (0x1 << NAU8824_CHARGE_PUMP_EN_SFT)
407
408
409#define NAU8824_CODEC_DAI "nau8824-hifi"
410
411/* System Clock Source */
412enum {
413 NAU8824_CLK_DIS,
414 NAU8824_CLK_MCLK,
415 NAU8824_CLK_INTERNAL,
416 NAU8824_CLK_FLL_MCLK,
417 NAU8824_CLK_FLL_BLK,
418 NAU8824_CLK_FLL_FS,
419};
420
421struct nau8824 {
422 struct device *dev;
423 struct regmap *regmap;
424 struct snd_soc_dapm_context *dapm;
425 struct snd_soc_jack *jack;
426 struct work_struct jdet_work;
427 struct semaphore jd_sem;
428 int fs;
429 int irq;
430 int micbias_voltage;
431 int vref_impedance;
432 int jkdet_polarity;
433 int sar_threshold_num;
434 int sar_threshold[8];
435 int sar_hysteresis;
436 int sar_voltage;
437 int sar_compare_time;
438 int sar_sampling_time;
439 int key_debounce;
440 int jack_eject_debounce;
441};
442
443struct nau8824_fll {
444 int mclk_src;
445 int ratio;
446 int fll_frac;
447 int fll_int;
448 int clk_ref_div;
449};
450
451struct nau8824_fll_attr {
452 unsigned int param;
453 unsigned int val;
454};
455
456struct nau8824_osr_attr {
457 unsigned int osr;
458 unsigned int clk_src;
459};
460
461
462int nau8824_enable_jack_detect(struct snd_soc_codec *codec,
463 struct snd_soc_jack *jack);
464
465#endif /* _NAU8824_H */
466
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index b281a46d769d..f91221b1ddf0 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -1084,13 +1084,28 @@ static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev)
1084 return 0; 1084 return 0;
1085} 1085}
1086 1086
1087static __maybe_unused int rt5514_i2c_resume(struct device *dev)
1088{
1089 struct rt5514_priv *rt5514 = dev_get_drvdata(dev);
1090 unsigned int val;
1091
1092 /*
1093 * Add a bogus read to avoid rt5514's confusion after s2r in case it
1094 * saw glitches on the i2c lines and thought the other side sent a
1095 * start bit.
1096 */
1097 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1098
1099 return 0;
1100}
1101
1087static int rt5514_i2c_probe(struct i2c_client *i2c, 1102static int rt5514_i2c_probe(struct i2c_client *i2c,
1088 const struct i2c_device_id *id) 1103 const struct i2c_device_id *id)
1089{ 1104{
1090 struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev); 1105 struct rt5514_platform_data *pdata = dev_get_platdata(&i2c->dev);
1091 struct rt5514_priv *rt5514; 1106 struct rt5514_priv *rt5514;
1092 int ret; 1107 int ret;
1093 unsigned int val; 1108 unsigned int val = ~0;
1094 1109
1095 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv), 1110 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv),
1096 GFP_KERNEL); 1111 GFP_KERNEL);
@@ -1120,8 +1135,16 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
1120 return ret; 1135 return ret;
1121 } 1136 }
1122 1137
1123 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val); 1138 /*
1124 if (val != RT5514_DEVICE_ID) { 1139 * The rt5514 can get confused if the i2c lines glitch together, as
1140 * can happen at bootup as regulators are turned off and on. If it's
1141 * in this glitched state the first i2c read will fail, so we'll give
1142 * it one change to retry.
1143 */
1144 ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1145 if (ret || val != RT5514_DEVICE_ID)
1146 ret = regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
1147 if (ret || val != RT5514_DEVICE_ID) {
1125 dev_err(&i2c->dev, 1148 dev_err(&i2c->dev,
1126 "Device with ID register %x is not rt5514\n", val); 1149 "Device with ID register %x is not rt5514\n", val);
1127 return -ENODEV; 1150 return -ENODEV;
@@ -1149,10 +1172,15 @@ static int rt5514_i2c_remove(struct i2c_client *i2c)
1149 return 0; 1172 return 0;
1150} 1173}
1151 1174
1152struct i2c_driver rt5514_i2c_driver = { 1175static const struct dev_pm_ops rt5514_i2_pm_ops = {
1176 SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume)
1177};
1178
1179static struct i2c_driver rt5514_i2c_driver = {
1153 .driver = { 1180 .driver = {
1154 .name = "rt5514", 1181 .name = "rt5514",
1155 .of_match_table = of_match_ptr(rt5514_of_match), 1182 .of_match_table = of_match_ptr(rt5514_of_match),
1183 .pm = &rt5514_i2_pm_ops,
1156 }, 1184 },
1157 .probe = rt5514_i2c_probe, 1185 .probe = rt5514_i2c_probe,
1158 .remove = rt5514_i2c_remove, 1186 .remove = rt5514_i2c_remove,
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index e149f3ce5401..87844a45886a 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3542,6 +3542,15 @@ static const struct i2c_device_id rt5645_i2c_id[] = {
3542}; 3542};
3543MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); 3543MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
3544 3544
3545#ifdef CONFIG_OF
3546static const struct of_device_id rt5645_of_match[] = {
3547 { .compatible = "realtek,rt5645", },
3548 { .compatible = "realtek,rt5650", },
3549 { }
3550};
3551MODULE_DEVICE_TABLE(of, rt5645_of_match);
3552#endif
3553
3545#ifdef CONFIG_ACPI 3554#ifdef CONFIG_ACPI
3546static const struct acpi_device_id rt5645_acpi_match[] = { 3555static const struct acpi_device_id rt5645_acpi_match[] = {
3547 { "10EC5645", 0 }, 3556 { "10EC5645", 0 },
@@ -3912,6 +3921,7 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
3912static struct i2c_driver rt5645_i2c_driver = { 3921static struct i2c_driver rt5645_i2c_driver = {
3913 .driver = { 3922 .driver = {
3914 .name = "rt5645", 3923 .name = "rt5645",
3924 .of_match_table = of_match_ptr(rt5645_of_match),
3915 .acpi_match_table = ACPI_PTR(rt5645_acpi_match), 3925 .acpi_match_table = ACPI_PTR(rt5645_acpi_match),
3916 }, 3926 },
3917 .probe = rt5645_i2c_probe, 3927 .probe = rt5645_i2c_probe,
diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c
index 476135ec5726..8cd22307f5b6 100644
--- a/sound/soc/codecs/rt5665.c
+++ b/sound/soc/codecs/rt5665.c
@@ -1139,7 +1139,8 @@ static void rt5665_enable_push_button_irq(struct snd_soc_codec *codec,
1139 bool enable) 1139 bool enable)
1140{ 1140{
1141 if (enable) { 1141 if (enable) {
1142 snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x000b); 1142 snd_soc_write(codec, RT5665_4BTN_IL_CMD_1, 0x0003);
1143 snd_soc_update_bits(codec, RT5665_SAR_IL_CMD_9, 0x1, 0x1);
1143 snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048); 1144 snd_soc_write(codec, RT5665_IL_CMD_1, 0x0048);
1144 snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2, 1145 snd_soc_update_bits(codec, RT5665_4BTN_IL_CMD_2,
1145 RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK, 1146 RT5665_4BTN_IL_MASK | RT5665_4BTN_IL_RST_MASK,
@@ -1192,10 +1193,13 @@ static int rt5665_headset_detect(struct snd_soc_codec *codec, int jack_insert)
1192 } 1193 }
1193 1194
1194 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, 1195 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
1195 0x180, 0x180); 1196 0x1a0, 0x120);
1196 regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424); 1197 regmap_write(rt5665->regmap, RT5665_EJD_CTRL_3, 0x3424);
1198 regmap_write(rt5665->regmap, RT5665_IL_CMD_1, 0x0048);
1197 regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291); 1199 regmap_write(rt5665->regmap, RT5665_SAR_IL_CMD_1, 0xa291);
1198 1200
1201 usleep_range(10000, 15000);
1202
1199 rt5665->sar_adc_value = snd_soc_read(rt5665->codec, 1203 rt5665->sar_adc_value = snd_soc_read(rt5665->codec,
1200 RT5665_SAR_IL_CMD_4) & 0x7ff; 1204 RT5665_SAR_IL_CMD_4) & 0x7ff;
1201 1205
@@ -1256,8 +1260,8 @@ static void rt5665_jd_check_handler(struct work_struct *work)
1256 } 1260 }
1257} 1261}
1258 1262
1259int rt5665_set_jack_detect(struct snd_soc_codec *codec, 1263static int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1260 struct snd_soc_jack *hs_jack) 1264 struct snd_soc_jack *hs_jack, void *data)
1261{ 1265{
1262 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 1266 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
1263 1267
@@ -1284,7 +1288,6 @@ int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1284 1288
1285 return 0; 1289 return 0;
1286} 1290}
1287EXPORT_SYMBOL_GPL(rt5665_set_jack_detect);
1288 1291
1289static void rt5665_jack_detect_handler(struct work_struct *work) 1292static void rt5665_jack_detect_handler(struct work_struct *work)
1290{ 1293{
@@ -2600,6 +2603,55 @@ static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
2600 return 0; 2603 return 0;
2601} 2604}
2602 2605
2606static int rt5665_i2s_pin_event(struct snd_soc_dapm_widget *w,
2607 struct snd_kcontrol *kcontrol, int event)
2608{
2609 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2610 unsigned int val1, val2, mask1, mask2 = 0;
2611
2612 switch (w->shift) {
2613 case RT5665_PWR_I2S2_1_BIT:
2614 mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
2615 RT5665_GP4_PIN_MASK | RT5665_GP5_PIN_MASK;
2616 val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
2617 RT5665_GP4_PIN_DACDAT2_1 | RT5665_GP5_PIN_ADCDAT2_1;
2618 break;
2619 case RT5665_PWR_I2S2_2_BIT:
2620 mask1 = RT5665_GP2_PIN_MASK | RT5665_GP3_PIN_MASK |
2621 RT5665_GP8_PIN_MASK;
2622 val1 = RT5665_GP2_PIN_BCLK2 | RT5665_GP3_PIN_LRCK2 |
2623 RT5665_GP8_PIN_DACDAT2_2;
2624 mask2 = RT5665_GP9_PIN_MASK;
2625 val2 = RT5665_GP9_PIN_ADCDAT2_2;
2626 break;
2627 case RT5665_PWR_I2S3_BIT:
2628 mask1 = RT5665_GP6_PIN_MASK | RT5665_GP7_PIN_MASK |
2629 RT5665_GP8_PIN_MASK;
2630 val1 = RT5665_GP6_PIN_BCLK3 | RT5665_GP7_PIN_LRCK3 |
2631 RT5665_GP8_PIN_DACDAT3;
2632 mask2 = RT5665_GP9_PIN_MASK;
2633 val2 = RT5665_GP9_PIN_ADCDAT3;
2634 break;
2635 }
2636 switch (event) {
2637 case SND_SOC_DAPM_PRE_PMU:
2638 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, val1);
2639 if (mask2)
2640 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
2641 mask2, val2);
2642 break;
2643 case SND_SOC_DAPM_POST_PMD:
2644 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_1, mask1, 0);
2645 if (mask2)
2646 snd_soc_update_bits(codec, RT5665_GPIO_CTRL_2,
2647 mask2, 0);
2648 break;
2649 default:
2650 return 0;
2651 }
2652
2653 return 0;
2654}
2603 2655
2604static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = { 2656static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
2605 SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0, 2657 SND_SOC_DAPM_SUPPLY("LDO2", RT5665_PWR_ANLG_3, RT5665_PWR_LDO2_BIT, 0,
@@ -2852,11 +2904,14 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
2852 SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT, 2904 SND_SOC_DAPM_SUPPLY("I2S1_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S1_2_BIT,
2853 0, NULL, 0), 2905 0, NULL, 0),
2854 SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT, 2906 SND_SOC_DAPM_SUPPLY("I2S2_1", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_1_BIT,
2855 0, NULL, 0), 2907 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2908 SND_SOC_DAPM_POST_PMD),
2856 SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT, 2909 SND_SOC_DAPM_SUPPLY("I2S2_2", RT5665_PWR_DIG_1, RT5665_PWR_I2S2_2_BIT,
2857 0, NULL, 0), 2910 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2911 SND_SOC_DAPM_POST_PMD),
2858 SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT, 2912 SND_SOC_DAPM_SUPPLY("I2S3", RT5665_PWR_DIG_1, RT5665_PWR_I2S3_BIT,
2859 0, NULL, 0), 2913 0, rt5665_i2s_pin_event, SND_SOC_DAPM_PRE_PMU |
2914 SND_SOC_DAPM_POST_PMD),
2860 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), 2915 SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
2861 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), 2916 SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2862 SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0), 2917 SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -3963,12 +4018,68 @@ static const struct snd_soc_dapm_route rt5665_dapm_routes[] = {
3963 {"PDMR", NULL, "PDM R Playback"}, 4018 {"PDMR", NULL, "PDM R Playback"},
3964}; 4019};
3965 4020
4021static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
4022 unsigned int rx_mask, int slots, int slot_width)
4023{
4024 struct snd_soc_codec *codec = dai->codec;
4025 unsigned int val = 0;
4026
4027 if (rx_mask || tx_mask)
4028 val |= RT5665_I2S1_MODE_TDM;
4029
4030 switch (slots) {
4031 case 4:
4032 val |= RT5665_TDM_IN_CH_4;
4033 val |= RT5665_TDM_OUT_CH_4;
4034 break;
4035 case 6:
4036 val |= RT5665_TDM_IN_CH_6;
4037 val |= RT5665_TDM_OUT_CH_6;
4038 break;
4039 case 8:
4040 val |= RT5665_TDM_IN_CH_8;
4041 val |= RT5665_TDM_OUT_CH_8;
4042 break;
4043 case 2:
4044 break;
4045 default:
4046 return -EINVAL;
4047 }
4048
4049 switch (slot_width) {
4050 case 20:
4051 val |= RT5665_TDM_IN_LEN_20;
4052 val |= RT5665_TDM_OUT_LEN_20;
4053 break;
4054 case 24:
4055 val |= RT5665_TDM_IN_LEN_24;
4056 val |= RT5665_TDM_OUT_LEN_24;
4057 break;
4058 case 32:
4059 val |= RT5665_TDM_IN_LEN_32;
4060 val |= RT5665_TDM_OUT_LEN_32;
4061 break;
4062 case 16:
4063 break;
4064 default:
4065 return -EINVAL;
4066 }
4067
4068 snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
4069 RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
4070 RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
4071 RT5665_TDM_OUT_LEN_MASK, val);
4072
4073 return 0;
4074}
4075
4076
3966static int rt5665_hw_params(struct snd_pcm_substream *substream, 4077static int rt5665_hw_params(struct snd_pcm_substream *substream,
3967 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 4078 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
3968{ 4079{
3969 struct snd_soc_codec *codec = dai->codec; 4080 struct snd_soc_codec *codec = dai->codec;
3970 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4081 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
3971 unsigned int val_len = 0, val_clk, mask_clk, val_bits = 0x0100; 4082 unsigned int val_len = 0, val_clk, reg_clk, mask_clk, val_bits = 0x0100;
3972 int pre_div, frame_size; 4083 int pre_div, frame_size;
3973 4084
3974 rt5665->lrck[dai->id] = params_rate(params); 4085 rt5665->lrck[dai->id] = params_rate(params);
@@ -4009,6 +4120,10 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4009 switch (dai->id) { 4120 switch (dai->id) {
4010 case RT5665_AIF1_1: 4121 case RT5665_AIF1_1:
4011 case RT5665_AIF1_2: 4122 case RT5665_AIF1_2:
4123 if (params_channels(params) > 2)
4124 rt5665_set_tdm_slot(dai, 0xf, 0xf,
4125 params_channels(params), params_width(params));
4126 reg_clk = RT5665_ADDA_CLK_1;
4012 mask_clk = RT5665_I2S_PD1_MASK; 4127 mask_clk = RT5665_I2S_PD1_MASK;
4013 val_clk = pre_div << RT5665_I2S_PD1_SFT; 4128 val_clk = pre_div << RT5665_I2S_PD1_SFT;
4014 snd_soc_update_bits(codec, RT5665_I2S1_SDP, 4129 snd_soc_update_bits(codec, RT5665_I2S1_SDP,
@@ -4016,12 +4131,14 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4016 break; 4131 break;
4017 case RT5665_AIF2_1: 4132 case RT5665_AIF2_1:
4018 case RT5665_AIF2_2: 4133 case RT5665_AIF2_2:
4134 reg_clk = RT5665_ADDA_CLK_2;
4019 mask_clk = RT5665_I2S_PD2_MASK; 4135 mask_clk = RT5665_I2S_PD2_MASK;
4020 val_clk = pre_div << RT5665_I2S_PD2_SFT; 4136 val_clk = pre_div << RT5665_I2S_PD2_SFT;
4021 snd_soc_update_bits(codec, RT5665_I2S2_SDP, 4137 snd_soc_update_bits(codec, RT5665_I2S2_SDP,
4022 RT5665_I2S_DL_MASK, val_len); 4138 RT5665_I2S_DL_MASK, val_len);
4023 break; 4139 break;
4024 case RT5665_AIF3: 4140 case RT5665_AIF3:
4141 reg_clk = RT5665_ADDA_CLK_2;
4025 mask_clk = RT5665_I2S_PD3_MASK; 4142 mask_clk = RT5665_I2S_PD3_MASK;
4026 val_clk = pre_div << RT5665_I2S_PD3_SFT; 4143 val_clk = pre_div << RT5665_I2S_PD3_SFT;
4027 snd_soc_update_bits(codec, RT5665_I2S3_SDP, 4144 snd_soc_update_bits(codec, RT5665_I2S3_SDP,
@@ -4032,7 +4149,7 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream,
4032 return -EINVAL; 4149 return -EINVAL;
4033 } 4150 }
4034 4151
4035 snd_soc_update_bits(codec, RT5665_ADDA_CLK_1, mask_clk, val_clk); 4152 snd_soc_update_bits(codec, reg_clk, mask_clk, val_clk);
4036 snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits); 4153 snd_soc_update_bits(codec, RT5665_STO1_DAC_SIL_DET, 0x3700, val_bits);
4037 4154
4038 switch (rt5665->lrck[dai->id]) { 4155 switch (rt5665->lrck[dai->id]) {
@@ -4125,10 +4242,9 @@ static int rt5665_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
4125 return 0; 4242 return 0;
4126} 4243}
4127 4244
4128static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai, 4245static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
4129 int clk_id, unsigned int freq, int dir) 4246 int source, unsigned int freq, int dir)
4130{ 4247{
4131 struct snd_soc_codec *codec = dai->codec;
4132 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4248 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
4133 unsigned int reg_val = 0; 4249 unsigned int reg_val = 0;
4134 4250
@@ -4154,20 +4270,20 @@ static int rt5665_set_dai_sysclk(struct snd_soc_dai *dai,
4154 rt5665->sysclk = freq; 4270 rt5665->sysclk = freq;
4155 rt5665->sysclk_src = clk_id; 4271 rt5665->sysclk_src = clk_id;
4156 4272
4157 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 4273 dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
4158 4274
4159 return 0; 4275 return 0;
4160} 4276}
4161 4277
4162static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source, 4278static int rt5665_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
4163 unsigned int freq_in, unsigned int freq_out) 4279 int source, unsigned int freq_in,
4280 unsigned int freq_out)
4164{ 4281{
4165 struct snd_soc_codec *codec = dai->codec;
4166 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); 4282 struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec);
4167 struct rl6231_pll_code pll_code; 4283 struct rl6231_pll_code pll_code;
4168 int ret; 4284 int ret;
4169 4285
4170 if (Source == rt5665->pll_src && freq_in == rt5665->pll_in && 4286 if (source == rt5665->pll_src && freq_in == rt5665->pll_in &&
4171 freq_out == rt5665->pll_out) 4287 freq_out == rt5665->pll_out)
4172 return 0; 4288 return 0;
4173 4289
@@ -4181,7 +4297,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4181 return 0; 4297 return 0;
4182 } 4298 }
4183 4299
4184 switch (Source) { 4300 switch (source) {
4185 case RT5665_PLL1_S_MCLK: 4301 case RT5665_PLL1_S_MCLK:
4186 snd_soc_update_bits(codec, RT5665_GLB_CLK, 4302 snd_soc_update_bits(codec, RT5665_GLB_CLK,
4187 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK); 4303 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_MCLK);
@@ -4199,7 +4315,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4199 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3); 4315 RT5665_PLL1_SRC_MASK, RT5665_PLL1_SRC_BCLK3);
4200 break; 4316 break;
4201 default: 4317 default:
4202 dev_err(codec->dev, "Unknown PLL Source %d\n", Source); 4318 dev_err(codec->dev, "Unknown PLL Source %d\n", source);
4203 return -EINVAL; 4319 return -EINVAL;
4204 } 4320 }
4205 4321
@@ -4221,62 +4337,7 @@ static int rt5665_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
4221 4337
4222 rt5665->pll_in = freq_in; 4338 rt5665->pll_in = freq_in;
4223 rt5665->pll_out = freq_out; 4339 rt5665->pll_out = freq_out;
4224 rt5665->pll_src = Source; 4340 rt5665->pll_src = source;
4225
4226 return 0;
4227}
4228
4229static int rt5665_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
4230 unsigned int rx_mask, int slots, int slot_width)
4231{
4232 struct snd_soc_codec *codec = dai->codec;
4233 unsigned int val = 0;
4234
4235 if (rx_mask || tx_mask)
4236 val |= RT5665_I2S1_MODE_TDM;
4237
4238 switch (slots) {
4239 case 4:
4240 val |= RT5665_TDM_IN_CH_4;
4241 val |= RT5665_TDM_OUT_CH_4;
4242 break;
4243 case 6:
4244 val |= RT5665_TDM_IN_CH_6;
4245 val |= RT5665_TDM_OUT_CH_6;
4246 break;
4247 case 8:
4248 val |= RT5665_TDM_IN_CH_8;
4249 val |= RT5665_TDM_OUT_CH_8;
4250 break;
4251 case 2:
4252 break;
4253 default:
4254 return -EINVAL;
4255 }
4256
4257 switch (slot_width) {
4258 case 20:
4259 val |= RT5665_TDM_IN_LEN_20;
4260 val |= RT5665_TDM_OUT_LEN_20;
4261 break;
4262 case 24:
4263 val |= RT5665_TDM_IN_LEN_24;
4264 val |= RT5665_TDM_OUT_LEN_24;
4265 break;
4266 case 32:
4267 val |= RT5665_TDM_IN_LEN_32;
4268 val |= RT5665_TDM_OUT_LEN_32;
4269 break;
4270 case 16:
4271 break;
4272 default:
4273 return -EINVAL;
4274 }
4275
4276 snd_soc_update_bits(codec, RT5665_TDM_CTRL_1,
4277 RT5665_I2S1_MODE_MASK | RT5665_TDM_IN_CH_MASK |
4278 RT5665_TDM_OUT_CH_MASK | RT5665_TDM_IN_LEN_MASK |
4279 RT5665_TDM_OUT_LEN_MASK, val);
4280 4341
4281 return 0; 4342 return 0;
4282} 4343}
@@ -4393,9 +4454,7 @@ static int rt5665_resume(struct snd_soc_codec *codec)
4393static const struct snd_soc_dai_ops rt5665_aif_dai_ops = { 4454static const struct snd_soc_dai_ops rt5665_aif_dai_ops = {
4394 .hw_params = rt5665_hw_params, 4455 .hw_params = rt5665_hw_params,
4395 .set_fmt = rt5665_set_dai_fmt, 4456 .set_fmt = rt5665_set_dai_fmt,
4396 .set_sysclk = rt5665_set_dai_sysclk,
4397 .set_tdm_slot = rt5665_set_tdm_slot, 4457 .set_tdm_slot = rt5665_set_tdm_slot,
4398 .set_pll = rt5665_set_dai_pll,
4399 .set_bclk_ratio = rt5665_set_bclk_ratio, 4458 .set_bclk_ratio = rt5665_set_bclk_ratio,
4400}; 4459};
4401 4460
@@ -4504,7 +4563,10 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5665 = {
4504 .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets), 4563 .num_dapm_widgets = ARRAY_SIZE(rt5665_dapm_widgets),
4505 .dapm_routes = rt5665_dapm_routes, 4564 .dapm_routes = rt5665_dapm_routes,
4506 .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes), 4565 .num_dapm_routes = ARRAY_SIZE(rt5665_dapm_routes),
4507 } 4566 },
4567 .set_sysclk = rt5665_set_codec_sysclk,
4568 .set_pll = rt5665_set_codec_pll,
4569 .set_jack = rt5665_set_jack_detect,
4508}; 4570};
4509 4571
4510 4572
@@ -4783,7 +4845,7 @@ static int rt5665_i2c_probe(struct i2c_client *i2c,
4783 4845
4784 regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002); 4846 regmap_write(rt5665->regmap, RT5665_HP_LOGIC_CTRL_2, 0x0002);
4785 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1, 4847 regmap_update_bits(rt5665->regmap, RT5665_EJD_CTRL_1,
4786 0xf000 | RT5665_VREF_POW_MASK, 0xd000 | RT5665_VREF_POW_REG); 4848 0xf000 | RT5665_VREF_POW_MASK, 0xe000 | RT5665_VREF_POW_REG);
4787 /* Work around for pow_pump */ 4849 /* Work around for pow_pump */
4788 regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET, 4850 regmap_update_bits(rt5665->regmap, RT5665_STO1_DAC_SIL_DET,
4789 RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS); 4851 RT5665_DEB_STO_DAC_MASK, RT5665_DEB_80_MS);
diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h
index a30f5e6d0628..1db5c6a62a8e 100644
--- a/sound/soc/codecs/rt5665.h
+++ b/sound/soc/codecs/rt5665.h
@@ -1984,7 +1984,5 @@ enum {
1984 1984
1985int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec, 1985int rt5665_sel_asrc_clk_src(struct snd_soc_codec *codec,
1986 unsigned int filter_mask, unsigned int clk_src); 1986 unsigned int filter_mask, unsigned int clk_src);
1987int rt5665_set_jack_detect(struct snd_soc_codec *codec,
1988 struct snd_soc_jack *hs_jack);
1989 1987
1990#endif /* __RT5665_H__ */ 1988#endif /* __RT5665_H__ */
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 17d20b99f041..e27c5a4a0a15 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -2835,6 +2835,27 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
2835 DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"), 2835 DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"),
2836 }, 2836 },
2837 }, 2837 },
2838 {
2839 .ident = "Lenovo Thinkpad Tablet 10",
2840 .matches = {
2841 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2842 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
2843 },
2844 },
2845 {
2846 .ident = "Lenovo Thinkpad Tablet 10",
2847 .matches = {
2848 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2849 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
2850 },
2851 },
2852 {
2853 .ident = "Lenovo Thinkpad Tablet 10",
2854 .matches = {
2855 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
2856 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
2857 },
2858 },
2838 {} 2859 {}
2839}; 2860};
2840 2861
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index abc802a5a479..65ac4518ad06 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -5035,6 +5035,12 @@ static const struct i2c_device_id rt5677_i2c_id[] = {
5035}; 5035};
5036MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); 5036MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
5037 5037
5038static const struct of_device_id rt5677_of_match[] = {
5039 { .compatible = "realtek,rt5677", },
5040 { }
5041};
5042MODULE_DEVICE_TABLE(of, rt5677_of_match);
5043
5038static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false }; 5044static const struct acpi_gpio_params plug_det_gpio = { RT5677_GPIO_PLUG_DET, 0, false };
5039static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false }; 5045static const struct acpi_gpio_params mic_present_gpio = { RT5677_GPIO_MIC_PRESENT_L, 0, false };
5040static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false }; 5046static const struct acpi_gpio_params headphone_enable_gpio = { RT5677_GPIO_HP_AMP_SHDN_L, 0, false };
@@ -5294,6 +5300,7 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
5294static struct i2c_driver rt5677_i2c_driver = { 5300static struct i2c_driver rt5677_i2c_driver = {
5295 .driver = { 5301 .driver = {
5296 .name = "rt5677", 5302 .name = "rt5677",
5303 .of_match_table = rt5677_of_match,
5297 }, 5304 },
5298 .probe = rt5677_i2c_probe, 5305 .probe = rt5677_i2c_probe,
5299 .remove = rt5677_i2c_remove, 5306 .remove = rt5677_i2c_remove,
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 1589325855bc..5a2702edeb77 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -99,6 +99,13 @@ enum sgtl5000_micbias_resistor {
99 SGTL5000_MICBIAS_8K = 8, 99 SGTL5000_MICBIAS_8K = 8,
100}; 100};
101 101
102enum {
103 I2S_LRCLK_STRENGTH_DISABLE,
104 I2S_LRCLK_STRENGTH_LOW,
105 I2S_LRCLK_STRENGTH_MEDIUM,
106 I2S_LRCLK_STRENGTH_HIGH,
107};
108
102/* sgtl5000 private structure in codec */ 109/* sgtl5000 private structure in codec */
103struct sgtl5000_priv { 110struct sgtl5000_priv {
104 int sysclk; /* sysclk rate */ 111 int sysclk; /* sysclk rate */
@@ -111,6 +118,7 @@ struct sgtl5000_priv {
111 int revision; 118 int revision;
112 u8 micbias_resistor; 119 u8 micbias_resistor;
113 u8 micbias_voltage; 120 u8 micbias_voltage;
121 u8 lrclk_strength;
114}; 122};
115 123
116/* 124/*
@@ -1089,6 +1097,7 @@ static int sgtl5000_enable_regulators(struct i2c_client *client)
1089static int sgtl5000_probe(struct snd_soc_codec *codec) 1097static int sgtl5000_probe(struct snd_soc_codec *codec)
1090{ 1098{
1091 int ret; 1099 int ret;
1100 u16 reg;
1092 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 1101 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1093 1102
1094 /* power up sgtl5000 */ 1103 /* power up sgtl5000 */
@@ -1118,7 +1127,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1118 SGTL5000_DAC_MUTE_RIGHT | 1127 SGTL5000_DAC_MUTE_RIGHT |
1119 SGTL5000_DAC_MUTE_LEFT); 1128 SGTL5000_DAC_MUTE_LEFT);
1120 1129
1121 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f); 1130 reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f);
1131 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, reg);
1122 1132
1123 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL, 1133 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1124 SGTL5000_HP_ZCD_EN | 1134 SGTL5000_HP_ZCD_EN |
@@ -1347,6 +1357,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1347 } 1357 }
1348 } 1358 }
1349 1359
1360 sgtl5000->lrclk_strength = I2S_LRCLK_STRENGTH_LOW;
1361 if (!of_property_read_u32(np, "lrclk-strength", &value)) {
1362 if (value > I2S_LRCLK_STRENGTH_HIGH)
1363 value = I2S_LRCLK_STRENGTH_LOW;
1364 sgtl5000->lrclk_strength = value;
1365 }
1366
1350 /* Ensure sgtl5000 will start with sane register values */ 1367 /* Ensure sgtl5000 will start with sane register values */
1351 sgtl5000_fill_defaults(client); 1368 sgtl5000_fill_defaults(client);
1352 1369
diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c
index 2bb5a11c9ba1..a622623e8558 100644
--- a/sound/soc/codecs/ssm4567.c
+++ b/sound/soc/codecs/ssm4567.c
@@ -485,6 +485,14 @@ static const struct i2c_device_id ssm4567_i2c_ids[] = {
485}; 485};
486MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids); 486MODULE_DEVICE_TABLE(i2c, ssm4567_i2c_ids);
487 487
488#ifdef CONFIG_OF
489static const struct of_device_id ssm4567_of_match[] = {
490 { .compatible = "adi,ssm4567", },
491 { }
492};
493MODULE_DEVICE_TABLE(of, ssm4567_of_match);
494#endif
495
488#ifdef CONFIG_ACPI 496#ifdef CONFIG_ACPI
489 497
490static const struct acpi_device_id ssm4567_acpi_match[] = { 498static const struct acpi_device_id ssm4567_acpi_match[] = {
@@ -498,6 +506,7 @@ MODULE_DEVICE_TABLE(acpi, ssm4567_acpi_match);
498static struct i2c_driver ssm4567_driver = { 506static struct i2c_driver ssm4567_driver = {
499 .driver = { 507 .driver = {
500 .name = "ssm4567", 508 .name = "ssm4567",
509 .of_match_table = of_match_ptr(ssm4567_of_match),
501 .acpi_match_table = ACPI_PTR(ssm4567_acpi_match), 510 .acpi_match_table = ACPI_PTR(ssm4567_acpi_match),
502 }, 511 },
503 .probe = ssm4567_i2c_probe, 512 .probe = ssm4567_i2c_probe,
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index d4b384e4b266..660734359bf3 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -375,9 +375,16 @@ static const struct i2c_device_id sta529_i2c_id[] = {
375}; 375};
376MODULE_DEVICE_TABLE(i2c, sta529_i2c_id); 376MODULE_DEVICE_TABLE(i2c, sta529_i2c_id);
377 377
378static const struct of_device_id sta529_of_match[] = {
379 { .compatible = "st,sta529", },
380 { }
381};
382MODULE_DEVICE_TABLE(of, sta529_of_match);
383
378static struct i2c_driver sta529_i2c_driver = { 384static struct i2c_driver sta529_i2c_driver = {
379 .driver = { 385 .driver = {
380 .name = "sta529", 386 .name = "sta529",
387 .of_match_table = sta529_of_match,
381 }, 388 },
382 .probe = sta529_i2c_probe, 389 .probe = sta529_i2c_probe,
383 .remove = sta529_i2c_remove, 390 .remove = sta529_i2c_remove,
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index baf455e8c2f7..8840f72f3c4a 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -611,7 +611,7 @@ probe_fail:
611 611
612 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies), 612 regulator_bulk_disable(ARRAY_SIZE(tas2552->supplies),
613 tas2552->supplies); 613 tas2552->supplies);
614 return -EIO; 614 return ret;
615} 615}
616 616
617static int tas2552_codec_remove(struct snd_soc_codec *codec) 617static int tas2552_codec_remove(struct snd_soc_codec *codec)
@@ -637,7 +637,7 @@ static int tas2552_suspend(struct snd_soc_codec *codec)
637 if (ret != 0) 637 if (ret != 0)
638 dev_err(codec->dev, "Failed to disable supplies: %d\n", 638 dev_err(codec->dev, "Failed to disable supplies: %d\n",
639 ret); 639 ret);
640 return 0; 640 return ret;
641} 641}
642 642
643static int tas2552_resume(struct snd_soc_codec *codec) 643static int tas2552_resume(struct snd_soc_codec *codec)
@@ -653,7 +653,7 @@ static int tas2552_resume(struct snd_soc_codec *codec)
653 ret); 653 ret);
654 } 654 }
655 655
656 return 0; 656 return ret;
657} 657}
658#else 658#else
659#define tas2552_suspend NULL 659#define tas2552_suspend NULL
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 410cae0f2060..628a8eeaab68 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -174,10 +174,9 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
174 {"ROUT", NULL, "Output Mixer"}, 174 {"ROUT", NULL, "Output Mixer"},
175 175
176 /* Inputs */ 176 /* Inputs */
177 {"Line Input", "NULL", "LLINEIN"}, 177 {"Line Input", NULL, "LLINEIN"},
178 {"Line Input", "NULL", "RLINEIN"}, 178 {"Line Input", NULL, "RLINEIN"},
179 179 {"Mic Input", NULL, "MICIN"},
180 {"Mic Input", "NULL", "MICIN"},
181 180
182 /* input mux */ 181 /* input mux */
183 {"Capture Source", "Line", "Line Input"}, 182 {"Capture Source", "Line", "Line Input"},
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 748036e851ea..2b6ad09e0886 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -606,6 +606,14 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
606 twl6040_headset_power_get_enum, 606 twl6040_headset_power_get_enum,
607 twl6040_headset_power_put_enum), 607 twl6040_headset_power_put_enum),
608 608
609 /* Left HS PDM data routed to Right HSDAC */
610 SOC_SINGLE("Headset Mono to Stereo Playback Switch",
611 TWL6040_REG_HSRCTL, 7, 1, 0),
612
613 /* Left HF PDM data routed to Right HFDAC */
614 SOC_SINGLE("Handsfree Mono to Stereo Playback Switch",
615 TWL6040_REG_HFRCTL, 5, 1, 0),
616
609 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum, 617 SOC_ENUM_EXT("PLL Selection", twl6040_power_mode_enum,
610 twl6040_pll_get_enum, twl6040_pll_put_enum), 618 twl6040_pll_get_enum, twl6040_pll_put_enum),
611}; 619};
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2918fdb95e58..61cdc79840e7 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -791,9 +791,16 @@ static const struct i2c_device_id uda1380_i2c_id[] = {
791}; 791};
792MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); 792MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
793 793
794static const struct of_device_id uda1380_of_match[] = {
795 { .compatible = "nxp,uda1380", },
796 { }
797};
798MODULE_DEVICE_TABLE(of, uda1380_of_match);
799
794static struct i2c_driver uda1380_i2c_driver = { 800static struct i2c_driver uda1380_i2c_driver = {
795 .driver = { 801 .driver = {
796 .name = "uda1380-codec", 802 .name = "uda1380-codec",
803 .of_match_table = uda1380_of_match,
797 }, 804 },
798 .probe = uda1380_i2c_probe, 805 .probe = uda1380_i2c_probe,
799 .remove = uda1380_i2c_remove, 806 .remove = uda1380_i2c_remove,
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 560575000cc5..138a84efdd54 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -2014,7 +2014,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2014 2014
2015 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val); 2015 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
2016 if (ret != 0) { 2016 if (ret != 0) {
2017 dev_err(wm5100->dev, "Failed to read micropone status: %d\n", 2017 dev_err(wm5100->dev, "Failed to read microphone status: %d\n",
2018 ret); 2018 ret);
2019 return; 2019 return;
2020 } 2020 }
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 6e887c2c42b1..237eeb9a8b97 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -24,6 +24,7 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/regulator/consumer.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <linux/irq.h> 29#include <linux/irq.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
@@ -115,10 +116,19 @@ static const struct reg_default wm8903_reg_defaults[] = {
115 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */ 116 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
116}; 117};
117 118
119#define WM8903_NUM_SUPPLIES 4
120static const char *wm8903_supply_names[WM8903_NUM_SUPPLIES] = {
121 "AVDD",
122 "CPVDD",
123 "DBVDD",
124 "DCVDD",
125};
126
118struct wm8903_priv { 127struct wm8903_priv {
119 struct wm8903_platform_data *pdata; 128 struct wm8903_platform_data *pdata;
120 struct device *dev; 129 struct device *dev;
121 struct regmap *regmap; 130 struct regmap *regmap;
131 struct regulator_bulk_data supplies[WM8903_NUM_SUPPLIES];
122 132
123 int sysclk; 133 int sysclk;
124 int irq; 134 int irq;
@@ -2030,6 +2040,23 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2030 2040
2031 pdata = wm8903->pdata; 2041 pdata = wm8903->pdata;
2032 2042
2043 for (i = 0; i < ARRAY_SIZE(wm8903->supplies); i++)
2044 wm8903->supplies[i].supply = wm8903_supply_names[i];
2045
2046 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8903->supplies),
2047 wm8903->supplies);
2048 if (ret != 0) {
2049 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2050 return ret;
2051 }
2052
2053 ret = regulator_bulk_enable(ARRAY_SIZE(wm8903->supplies),
2054 wm8903->supplies);
2055 if (ret != 0) {
2056 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2057 return ret;
2058 }
2059
2033 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); 2060 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
2034 if (ret != 0) { 2061 if (ret != 0) {
2035 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); 2062 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
@@ -2160,6 +2187,8 @@ static int wm8903_i2c_probe(struct i2c_client *i2c,
2160 2187
2161 return 0; 2188 return 0;
2162err: 2189err:
2190 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2191 wm8903->supplies);
2163 return ret; 2192 return ret;
2164} 2193}
2165 2194
@@ -2167,6 +2196,8 @@ static int wm8903_i2c_remove(struct i2c_client *client)
2167{ 2196{
2168 struct wm8903_priv *wm8903 = i2c_get_clientdata(client); 2197 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2169 2198
2199 regulator_bulk_disable(ARRAY_SIZE(wm8903->supplies),
2200 wm8903->supplies);
2170 if (client->irq) 2201 if (client->irq)
2171 free_irq(client->irq, wm8903); 2202 free_irq(client->irq, wm8903);
2172 wm8903_free_gpio(wm8903); 2203 wm8903_free_gpio(wm8903);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 3bf081a7e450..9ed455700954 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -604,12 +604,150 @@ static const int bclk_divs[] = {
604 120, 160, 220, 240, 320, 320, 320 604 120, 160, 220, 240, 320, 320, 320
605}; 605};
606 606
607/**
608 * wm8960_configure_sysclk - checks if there is a sysclk frequency available
609 * The sysclk must be chosen such that:
610 * - sysclk = MCLK / sysclk_divs
611 * - lrclk = sysclk / dac_divs
612 * - 10 * bclk = sysclk / bclk_divs
613 *
614 * If we cannot find an exact match for (sysclk, lrclk, bclk)
615 * triplet, we relax the bclk such that bclk is chosen as the
616 * closest available frequency greater than expected bclk.
617 *
618 * @wm8960_priv: wm8960 codec private data
619 * @mclk: MCLK used to derive sysclk
620 * @sysclk_idx: sysclk_divs index for found sysclk
621 * @dac_idx: dac_divs index for found lrclk
622 * @bclk_idx: bclk_divs index for found bclk
623 *
624 * Returns:
625 * -1, in case no sysclk frequency available found
626 * >=0, in case we could derive bclk and lrclk from sysclk using
627 * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
628 */
629static
630int wm8960_configure_sysclk(struct wm8960_priv *wm8960, int mclk,
631 int *sysclk_idx, int *dac_idx, int *bclk_idx)
632{
633 int sysclk, bclk, lrclk;
634 int i, j, k;
635 int diff, closest = mclk;
636
637 /* marker for no match */
638 *bclk_idx = -1;
639
640 bclk = wm8960->bclk;
641 lrclk = wm8960->lrclk;
642
643 /* check if the sysclk frequency is available. */
644 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
645 if (sysclk_divs[i] == -1)
646 continue;
647 sysclk = mclk / sysclk_divs[i];
648 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
649 if (sysclk != dac_divs[j] * lrclk)
650 continue;
651 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
652 diff = sysclk - bclk * bclk_divs[k] / 10;
653 if (diff == 0) {
654 *sysclk_idx = i;
655 *dac_idx = j;
656 *bclk_idx = k;
657 break;
658 }
659 if (diff > 0 && closest > diff) {
660 *sysclk_idx = i;
661 *dac_idx = j;
662 *bclk_idx = k;
663 closest = diff;
664 }
665 }
666 if (k != ARRAY_SIZE(bclk_divs))
667 break;
668 }
669 if (j != ARRAY_SIZE(dac_divs))
670 break;
671 }
672 return *bclk_idx;
673}
674
675/**
676 * wm8960_configure_pll - checks if there is a PLL out frequency available
677 * The PLL out frequency must be chosen such that:
678 * - sysclk = lrclk * dac_divs
679 * - freq_out = sysclk * sysclk_divs
680 * - 10 * sysclk = bclk * bclk_divs
681 *
682 * If we cannot find an exact match for (sysclk, lrclk, bclk)
683 * triplet, we relax the bclk such that bclk is chosen as the
684 * closest available frequency greater than expected bclk.
685 *
686 * @codec: codec structure
687 * @freq_in: input frequency used to derive freq out via PLL
688 * @sysclk_idx: sysclk_divs index for found sysclk
689 * @dac_idx: dac_divs index for found lrclk
690 * @bclk_idx: bclk_divs index for found bclk
691 *
692 * Returns:
693 * < 0, in case no PLL frequency out available was found
694 * >=0, in case we could derive bclk, lrclk, sysclk from PLL out using
695 * (@sysclk_idx, @dac_idx, @bclk_idx) dividers
696 */
697static
698int wm8960_configure_pll(struct snd_soc_codec *codec, int freq_in,
699 int *sysclk_idx, int *dac_idx, int *bclk_idx)
700{
701 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
702 int sysclk, bclk, lrclk, freq_out;
703 int diff, closest, best_freq_out;
704 int i, j, k;
705
706 bclk = wm8960->bclk;
707 lrclk = wm8960->lrclk;
708 closest = freq_in;
709
710 best_freq_out = -EINVAL;
711 *sysclk_idx = *dac_idx = *bclk_idx = -1;
712
713 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
714 if (sysclk_divs[i] == -1)
715 continue;
716 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
717 sysclk = lrclk * dac_divs[j];
718 freq_out = sysclk * sysclk_divs[i];
719
720 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) {
721 if (!is_pll_freq_available(freq_in, freq_out))
722 continue;
723
724 diff = sysclk - bclk * bclk_divs[k] / 10;
725 if (diff == 0) {
726 *sysclk_idx = i;
727 *dac_idx = j;
728 *bclk_idx = k;
729 return freq_out;
730 }
731 if (diff > 0 && closest > diff) {
732 *sysclk_idx = i;
733 *dac_idx = j;
734 *bclk_idx = k;
735 closest = diff;
736 best_freq_out = freq_out;
737 }
738 }
739 }
740 }
741
742 return best_freq_out;
743}
607static int wm8960_configure_clocking(struct snd_soc_codec *codec) 744static int wm8960_configure_clocking(struct snd_soc_codec *codec)
608{ 745{
609 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 746 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
610 int sysclk, bclk, lrclk, freq_out, freq_in; 747 int freq_out, freq_in;
611 u16 iface1 = snd_soc_read(codec, WM8960_IFACE1); 748 u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
612 int i, j, k; 749 int i, j, k;
750 int ret;
613 751
614 if (!(iface1 & (1<<6))) { 752 if (!(iface1 & (1<<6))) {
615 dev_dbg(codec->dev, 753 dev_dbg(codec->dev,
@@ -623,8 +761,6 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
623 } 761 }
624 762
625 freq_in = wm8960->freq_in; 763 freq_in = wm8960->freq_in;
626 bclk = wm8960->bclk;
627 lrclk = wm8960->lrclk;
628 /* 764 /*
629 * If it's sysclk auto mode, check if the MCLK can provide sysclk or 765 * If it's sysclk auto mode, check if the MCLK can provide sysclk or
630 * not. If MCLK can provide sysclk, using MCLK to provide sysclk 766 * not. If MCLK can provide sysclk, using MCLK to provide sysclk
@@ -643,60 +779,21 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
643 } 779 }
644 780
645 if (wm8960->clk_id != WM8960_SYSCLK_PLL) { 781 if (wm8960->clk_id != WM8960_SYSCLK_PLL) {
646 /* check if the sysclk frequency is available. */ 782 ret = wm8960_configure_sysclk(wm8960, freq_out, &i, &j, &k);
647 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { 783 if (ret >= 0) {
648 if (sysclk_divs[i] == -1)
649 continue;
650 sysclk = freq_out / sysclk_divs[i];
651 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
652 if (sysclk != dac_divs[j] * lrclk)
653 continue;
654 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k)
655 if (sysclk == bclk * bclk_divs[k] / 10)
656 break;
657 if (k != ARRAY_SIZE(bclk_divs))
658 break;
659 }
660 if (j != ARRAY_SIZE(dac_divs))
661 break;
662 }
663
664 if (i != ARRAY_SIZE(sysclk_divs)) {
665 goto configure_clock; 784 goto configure_clock;
666 } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { 785 } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
667 dev_err(codec->dev, "failed to configure clock\n"); 786 dev_err(codec->dev, "failed to configure clock\n");
668 return -EINVAL; 787 return -EINVAL;
669 } 788 }
670 } 789 }
671 /* get a available pll out frequency and set pll */
672 for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
673 if (sysclk_divs[i] == -1)
674 continue;
675 for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
676 sysclk = lrclk * dac_divs[j];
677 freq_out = sysclk * sysclk_divs[i];
678 790
679 for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) { 791 freq_out = wm8960_configure_pll(codec, freq_in, &i, &j, &k);
680 if (sysclk == bclk * bclk_divs[k] / 10 && 792 if (freq_out < 0) {
681 is_pll_freq_available(freq_in, freq_out)) { 793 dev_err(codec->dev, "failed to configure clock via PLL\n");
682 wm8960_set_pll(codec, 794 return freq_out;
683 freq_in, freq_out);
684 break;
685 } else {
686 continue;
687 }
688 }
689 if (k != ARRAY_SIZE(bclk_divs))
690 break;
691 }
692 if (j != ARRAY_SIZE(dac_divs))
693 break;
694 }
695
696 if (i == ARRAY_SIZE(sysclk_divs)) {
697 dev_err(codec->dev, "failed to configure clock\n");
698 return -EINVAL;
699 } 795 }
796 wm8960_set_pll(codec, freq_in, freq_out);
700 797
701configure_clock: 798configure_clock:
702 /* configure sysclk clock */ 799 /* configure sysclk clock */
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 90b2d418ef60..cf761e2d7546 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1071,9 +1071,16 @@ static const struct i2c_device_id wm8978_i2c_id[] = {
1071}; 1071};
1072MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id); 1072MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1073 1073
1074static const struct of_device_id wm8978_of_match[] = {
1075 { .compatible = "wlf,wm8978", },
1076 { }
1077};
1078MODULE_DEVICE_TABLE(of, wm8978_of_match);
1079
1074static struct i2c_driver wm8978_i2c_driver = { 1080static struct i2c_driver wm8978_i2c_driver = {
1075 .driver = { 1081 .driver = {
1076 .name = "wm8978", 1082 .name = "wm8978",
1083 .of_match_table = wm8978_of_match,
1077 }, 1084 },
1078 .probe = wm8978_i2c_probe, 1085 .probe = wm8978_i2c_probe,
1079 .remove = wm8978_i2c_remove, 1086 .remove = wm8978_i2c_remove,
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index bbdb72f73df1..20695b691aff 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -112,17 +112,22 @@
112#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 112#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */
113#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 113#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
114 114
115#define ADSP2_CONTROL 0x0 115#define ADSP2_CONTROL 0x0
116#define ADSP2_CLOCKING 0x1 116#define ADSP2_CLOCKING 0x1
117#define ADSP2_STATUS1 0x4 117#define ADSP2V2_CLOCKING 0x2
118#define ADSP2_WDMA_CONFIG_1 0x30 118#define ADSP2_STATUS1 0x4
119#define ADSP2_WDMA_CONFIG_2 0x31 119#define ADSP2_WDMA_CONFIG_1 0x30
120#define ADSP2_RDMA_CONFIG_1 0x34 120#define ADSP2_WDMA_CONFIG_2 0x31
121 121#define ADSP2V2_WDMA_CONFIG_2 0x32
122#define ADSP2_SCRATCH0 0x40 122#define ADSP2_RDMA_CONFIG_1 0x34
123#define ADSP2_SCRATCH1 0x41 123
124#define ADSP2_SCRATCH2 0x42 124#define ADSP2_SCRATCH0 0x40
125#define ADSP2_SCRATCH3 0x43 125#define ADSP2_SCRATCH1 0x41
126#define ADSP2_SCRATCH2 0x42
127#define ADSP2_SCRATCH3 0x43
128
129#define ADSP2V2_SCRATCH0_1 0x40
130#define ADSP2V2_SCRATCH2_3 0x42
126 131
127/* 132/*
128 * ADSP2 Control 133 * ADSP2 Control
@@ -153,6 +158,17 @@
153#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 158#define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
154 159
155/* 160/*
161 * ADSP2V2 clocking
162 */
163#define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */
164#define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */
165#define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
166
167#define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */
168#define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */
169#define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */
170
171/*
156 * ADSP2 Status 1 172 * ADSP2 Status 1
157 */ 173 */
158#define ADSP2_RAM_RDY 0x0001 174#define ADSP2_RAM_RDY 0x0001
@@ -160,6 +176,37 @@
160#define ADSP2_RAM_RDY_SHIFT 0 176#define ADSP2_RAM_RDY_SHIFT 0
161#define ADSP2_RAM_RDY_WIDTH 1 177#define ADSP2_RAM_RDY_WIDTH 1
162 178
179/*
180 * ADSP2 Lock support
181 */
182#define ADSP2_LOCK_CODE_0 0x5555
183#define ADSP2_LOCK_CODE_1 0xAAAA
184
185#define ADSP2_WATCHDOG 0x0A
186#define ADSP2_BUS_ERR_ADDR 0x52
187#define ADSP2_REGION_LOCK_STATUS 0x64
188#define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66
189#define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68
190#define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A
191#define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C
192#define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E
193#define ADSP2_LOCK_REGION_CTRL 0x7A
194#define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C
195
196#define ADSP2_REGION_LOCK_ERR_MASK 0x8000
197#define ADSP2_SLAVE_ERR_MASK 0x4000
198#define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000
199#define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002
200#define ADSP2_CTRL_ERR_EINT 0x0001
201
202#define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF
203#define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF
204#define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000
205#define ADSP2_PMEM_ERR_ADDR_SHIFT 16
206#define ADSP2_WDT_ENA_MASK 0xFFFFFFFD
207
208#define ADSP2_LOCK_REGION_SHIFT 16
209
163#define ADSP_MAX_STD_CTRL_SIZE 512 210#define ADSP_MAX_STD_CTRL_SIZE 512
164 211
165#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 212#define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100
@@ -683,6 +730,9 @@ static const struct soc_enum wm_adsp_fw_enum[] = {
683 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 730 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
684 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 731 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
685 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 732 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
733 SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
734 SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
735 SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
686}; 736};
687 737
688const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 738const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
@@ -694,6 +744,12 @@ const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
694 wm_adsp_fw_get, wm_adsp_fw_put), 744 wm_adsp_fw_get, wm_adsp_fw_put),
695 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 745 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
696 wm_adsp_fw_get, wm_adsp_fw_put), 746 wm_adsp_fw_get, wm_adsp_fw_put),
747 SOC_ENUM_EXT("DSP5 Firmware", wm_adsp_fw_enum[4],
748 wm_adsp_fw_get, wm_adsp_fw_put),
749 SOC_ENUM_EXT("DSP6 Firmware", wm_adsp_fw_enum[5],
750 wm_adsp_fw_get, wm_adsp_fw_put),
751 SOC_ENUM_EXT("DSP7 Firmware", wm_adsp_fw_enum[6],
752 wm_adsp_fw_get, wm_adsp_fw_put),
697}; 753};
698EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 754EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
699 755
@@ -750,6 +806,29 @@ static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
750 be16_to_cpu(scratch[3])); 806 be16_to_cpu(scratch[3]));
751} 807}
752 808
809static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
810{
811 u32 scratch[2];
812 int ret;
813
814 ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
815 scratch, sizeof(scratch));
816
817 if (ret) {
818 adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
819 return;
820 }
821
822 scratch[0] = be32_to_cpu(scratch[0]);
823 scratch[1] = be32_to_cpu(scratch[1]);
824
825 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
826 scratch[0] & 0xFFFF,
827 scratch[0] >> 16,
828 scratch[1] & 0xFFFF,
829 scratch[1] >> 16);
830}
831
753static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) 832static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext)
754{ 833{
755 return container_of(ext, struct wm_coeff_ctl, bytes_ext); 834 return container_of(ext, struct wm_coeff_ctl, bytes_ext);
@@ -2435,10 +2514,17 @@ static int wm_adsp2_ena(struct wm_adsp *dsp)
2435 unsigned int val; 2514 unsigned int val;
2436 int ret, count; 2515 int ret, count;
2437 2516
2438 ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, 2517 switch (dsp->rev) {
2439 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 2518 case 0:
2440 if (ret != 0) 2519 ret = regmap_update_bits_async(dsp->regmap,
2441 return ret; 2520 dsp->base + ADSP2_CONTROL,
2521 ADSP2_SYS_ENA, ADSP2_SYS_ENA);
2522 if (ret != 0)
2523 return ret;
2524 break;
2525 default:
2526 break;
2527 }
2442 2528
2443 /* Wait for the RAM to start, should be near instantaneous */ 2529 /* Wait for the RAM to start, should be near instantaneous */
2444 for (count = 0; count < 10; ++count) { 2530 for (count = 0; count < 10; ++count) {
@@ -2497,11 +2583,17 @@ static void wm_adsp2_boot_work(struct work_struct *work)
2497 if (ret != 0) 2583 if (ret != 0)
2498 goto err_ena; 2584 goto err_ena;
2499 2585
2500 /* Turn DSP back off until we are ready to run */ 2586 switch (dsp->rev) {
2501 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2587 case 0:
2502 ADSP2_SYS_ENA, 0); 2588 /* Turn DSP back off until we are ready to run */
2503 if (ret != 0) 2589 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2504 goto err_ena; 2590 ADSP2_SYS_ENA, 0);
2591 if (ret != 0)
2592 goto err_ena;
2593 break;
2594 default:
2595 break;
2596 }
2505 2597
2506 dsp->booted = true; 2598 dsp->booted = true;
2507 2599
@@ -2523,12 +2615,21 @@ static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
2523{ 2615{
2524 int ret; 2616 int ret;
2525 2617
2526 ret = regmap_update_bits_async(dsp->regmap, 2618 switch (dsp->rev) {
2527 dsp->base + ADSP2_CLOCKING, 2619 case 0:
2528 ADSP2_CLK_SEL_MASK, 2620 ret = regmap_update_bits_async(dsp->regmap,
2529 freq << ADSP2_CLK_SEL_SHIFT); 2621 dsp->base + ADSP2_CLOCKING,
2530 if (ret != 0) 2622 ADSP2_CLK_SEL_MASK,
2531 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2623 freq << ADSP2_CLK_SEL_SHIFT);
2624 if (ret) {
2625 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
2626 return;
2627 }
2628 break;
2629 default:
2630 /* clock is handled by parent codec driver */
2631 break;
2632 }
2532} 2633}
2533 2634
2534int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, 2635int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
@@ -2568,6 +2669,18 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
2568} 2669}
2569EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); 2670EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
2570 2671
2672static void wm_adsp_stop_watchdog(struct wm_adsp *dsp)
2673{
2674 switch (dsp->rev) {
2675 case 0:
2676 case 1:
2677 return;
2678 default:
2679 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG,
2680 ADSP2_WDT_ENA_MASK, 0);
2681 }
2682}
2683
2571int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2684int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2572 struct snd_kcontrol *kcontrol, int event, 2685 struct snd_kcontrol *kcontrol, int event,
2573 unsigned int freq) 2686 unsigned int freq)
@@ -2640,6 +2753,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2640 if (ret != 0) 2753 if (ret != 0)
2641 goto err; 2754 goto err;
2642 2755
2756 wm_adsp2_lock(dsp, dsp->lock_regions);
2757
2643 ret = regmap_update_bits(dsp->regmap, 2758 ret = regmap_update_bits(dsp->regmap,
2644 dsp->base + ADSP2_CONTROL, 2759 dsp->base + ADSP2_CONTROL,
2645 ADSP2_CORE_ENA | ADSP2_START, 2760 ADSP2_CORE_ENA | ADSP2_START,
@@ -2663,23 +2778,49 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
2663 /* Tell the firmware to cleanup */ 2778 /* Tell the firmware to cleanup */
2664 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); 2779 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN);
2665 2780
2781 wm_adsp_stop_watchdog(dsp);
2782
2666 /* Log firmware state, it can be useful for analysis */ 2783 /* Log firmware state, it can be useful for analysis */
2667 wm_adsp2_show_fw_status(dsp); 2784 switch (dsp->rev) {
2785 case 0:
2786 wm_adsp2_show_fw_status(dsp);
2787 break;
2788 default:
2789 wm_adsp2v2_show_fw_status(dsp);
2790 break;
2791 }
2668 2792
2669 mutex_lock(&dsp->pwr_lock); 2793 mutex_lock(&dsp->pwr_lock);
2670 2794
2671 dsp->running = false; 2795 dsp->running = false;
2672 2796
2673 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2797 regmap_update_bits(dsp->regmap,
2798 dsp->base + ADSP2_CONTROL,
2674 ADSP2_CORE_ENA | ADSP2_START, 0); 2799 ADSP2_CORE_ENA | ADSP2_START, 0);
2675 2800
2676 /* Make sure DMAs are quiesced */ 2801 /* Make sure DMAs are quiesced */
2677 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2802 switch (dsp->rev) {
2678 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2803 case 0:
2679 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 2804 regmap_write(dsp->regmap,
2680 2805 dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2681 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2806 regmap_write(dsp->regmap,
2682 ADSP2_SYS_ENA, 0); 2807 dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2808 regmap_write(dsp->regmap,
2809 dsp->base + ADSP2_WDMA_CONFIG_2, 0);
2810
2811 regmap_update_bits(dsp->regmap,
2812 dsp->base + ADSP2_CONTROL,
2813 ADSP2_SYS_ENA, 0);
2814 break;
2815 default:
2816 regmap_write(dsp->regmap,
2817 dsp->base + ADSP2_RDMA_CONFIG_1, 0);
2818 regmap_write(dsp->regmap,
2819 dsp->base + ADSP2_WDMA_CONFIG_1, 0);
2820 regmap_write(dsp->regmap,
2821 dsp->base + ADSP2V2_WDMA_CONFIG_2, 0);
2822 break;
2823 }
2683 2824
2684 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2825 if (wm_adsp_fw[dsp->fw].num_caps != 0)
2685 wm_adsp_buffer_free(dsp); 2826 wm_adsp_buffer_free(dsp);
@@ -2732,15 +2873,22 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2732{ 2873{
2733 int ret; 2874 int ret;
2734 2875
2735 /* 2876 switch (dsp->rev) {
2736 * Disable the DSP memory by default when in reset for a small 2877 case 0:
2737 * power saving. 2878 /*
2738 */ 2879 * Disable the DSP memory by default when in reset for a small
2739 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2880 * power saving.
2740 ADSP2_MEM_ENA, 0); 2881 */
2741 if (ret != 0) { 2882 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
2742 adsp_err(dsp, "Failed to clear memory retention: %d\n", ret); 2883 ADSP2_MEM_ENA, 0);
2743 return ret; 2884 if (ret) {
2885 adsp_err(dsp,
2886 "Failed to clear memory retention: %d\n", ret);
2887 return ret;
2888 }
2889 break;
2890 default:
2891 break;
2744 } 2892 }
2745 2893
2746 INIT_LIST_HEAD(&dsp->alg_regions); 2894 INIT_LIST_HEAD(&dsp->alg_regions);
@@ -3523,4 +3671,94 @@ int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf,
3523} 3671}
3524EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); 3672EXPORT_SYMBOL_GPL(wm_adsp_compr_copy);
3525 3673
3674int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions)
3675{
3676 struct regmap *regmap = dsp->regmap;
3677 unsigned int code0, code1, lock_reg;
3678
3679 if (!(lock_regions & WM_ADSP2_REGION_ALL))
3680 return 0;
3681
3682 lock_regions &= WM_ADSP2_REGION_ALL;
3683 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0;
3684
3685 while (lock_regions) {
3686 code0 = code1 = 0;
3687 if (lock_regions & BIT(0)) {
3688 code0 = ADSP2_LOCK_CODE_0;
3689 code1 = ADSP2_LOCK_CODE_1;
3690 }
3691 if (lock_regions & BIT(1)) {
3692 code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT;
3693 code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT;
3694 }
3695 regmap_write(regmap, lock_reg, code0);
3696 regmap_write(regmap, lock_reg, code1);
3697 lock_regions >>= 2;
3698 lock_reg += 2;
3699 }
3700
3701 return 0;
3702}
3703EXPORT_SYMBOL_GPL(wm_adsp2_lock);
3704
3705irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
3706{
3707 unsigned int val;
3708 struct regmap *regmap = dsp->regmap;
3709 int ret = 0;
3710
3711 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
3712 if (ret) {
3713 adsp_err(dsp,
3714 "Failed to read Region Lock Ctrl register: %d\n", ret);
3715 return IRQ_HANDLED;
3716 }
3717
3718 if (val & ADSP2_WDT_TIMEOUT_STS_MASK) {
3719 adsp_err(dsp, "watchdog timeout error\n");
3720 wm_adsp_stop_watchdog(dsp);
3721 }
3722
3723 if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) {
3724 if (val & ADSP2_SLAVE_ERR_MASK)
3725 adsp_err(dsp, "bus error: slave error\n");
3726 else
3727 adsp_err(dsp, "bus error: region lock error\n");
3728
3729 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val);
3730 if (ret) {
3731 adsp_err(dsp,
3732 "Failed to read Bus Err Addr register: %d\n",
3733 ret);
3734 return IRQ_HANDLED;
3735 }
3736
3737 adsp_err(dsp, "bus error address = 0x%x\n",
3738 val & ADSP2_BUS_ERR_ADDR_MASK);
3739
3740 ret = regmap_read(regmap,
3741 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR,
3742 &val);
3743 if (ret) {
3744 adsp_err(dsp,
3745 "Failed to read Pmem Xmem Err Addr register: %d\n",
3746 ret);
3747 return IRQ_HANDLED;
3748 }
3749
3750 adsp_err(dsp, "xmem error address = 0x%x\n",
3751 val & ADSP2_XMEM_ERR_ADDR_MASK);
3752 adsp_err(dsp, "pmem error address = 0x%x\n",
3753 (val & ADSP2_PMEM_ERR_ADDR_MASK) >>
3754 ADSP2_PMEM_ERR_ADDR_SHIFT);
3755 }
3756
3757 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
3758 ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT);
3759
3760 return IRQ_HANDLED;
3761}
3762EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
3763
3526MODULE_LICENSE("GPL v2"); 3764MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 3706b11053a3..41cc11c19b83 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -23,6 +23,23 @@
23#define WM_ADSP_COMPR_OK 0 23#define WM_ADSP_COMPR_OK 0
24#define WM_ADSP_COMPR_VOICE_TRIGGER 1 24#define WM_ADSP_COMPR_VOICE_TRIGGER 1
25 25
26#define WM_ADSP2_REGION_0 BIT(0)
27#define WM_ADSP2_REGION_1 BIT(1)
28#define WM_ADSP2_REGION_2 BIT(2)
29#define WM_ADSP2_REGION_3 BIT(3)
30#define WM_ADSP2_REGION_4 BIT(4)
31#define WM_ADSP2_REGION_5 BIT(5)
32#define WM_ADSP2_REGION_6 BIT(6)
33#define WM_ADSP2_REGION_7 BIT(7)
34#define WM_ADSP2_REGION_8 BIT(8)
35#define WM_ADSP2_REGION_9 BIT(9)
36#define WM_ADSP2_REGION_1_9 (WM_ADSP2_REGION_1 | \
37 WM_ADSP2_REGION_2 | WM_ADSP2_REGION_3 | \
38 WM_ADSP2_REGION_4 | WM_ADSP2_REGION_5 | \
39 WM_ADSP2_REGION_6 | WM_ADSP2_REGION_7 | \
40 WM_ADSP2_REGION_8 | WM_ADSP2_REGION_9)
41#define WM_ADSP2_REGION_ALL (WM_ADSP2_REGION_0 | WM_ADSP2_REGION_1_9)
42
26struct wm_adsp_region { 43struct wm_adsp_region {
27 int type; 44 int type;
28 unsigned int base; 45 unsigned int base;
@@ -40,6 +57,7 @@ struct wm_adsp_compr_buf;
40 57
41struct wm_adsp { 58struct wm_adsp {
42 const char *part; 59 const char *part;
60 int rev;
43 int num; 61 int num;
44 int type; 62 int type;
45 struct device *dev; 63 struct device *dev;
@@ -75,6 +93,8 @@ struct wm_adsp {
75 93
76 struct mutex pwr_lock; 94 struct mutex pwr_lock;
77 95
96 unsigned int lock_regions;
97
78#ifdef CONFIG_DEBUG_FS 98#ifdef CONFIG_DEBUG_FS
79 struct dentry *debugfs_root; 99 struct dentry *debugfs_root;
80 char *wmfw_file_name; 100 char *wmfw_file_name;
@@ -113,6 +133,10 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
113int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 133int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *kcontrol, int event, 134 struct snd_kcontrol *kcontrol, int event,
115 unsigned int freq); 135 unsigned int freq);
136
137int wm_adsp2_lock(struct wm_adsp *adsp, unsigned int regions);
138irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp);
139
116int wm_adsp2_event(struct snd_soc_dapm_widget *w, 140int wm_adsp2_event(struct snd_soc_dapm_widget *w,
117 struct snd_kcontrol *kcontrol, int event); 141 struct snd_kcontrol *kcontrol, int event);
118 142
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
index c297efe43861..c6fd95fa5ca6 100644
--- a/sound/soc/dwc/Kconfig
+++ b/sound/soc/dwc/Kconfig
@@ -8,10 +8,10 @@ config SND_DESIGNWARE_I2S
8 maximum of 8 channels each for play and record. 8 maximum of 8 channels each for play and record.
9 9
10config SND_DESIGNWARE_PCM 10config SND_DESIGNWARE_PCM
11 tristate "PCM PIO extension for I2S driver" 11 bool "PCM PIO extension for I2S driver"
12 depends on SND_DESIGNWARE_I2S 12 depends on SND_DESIGNWARE_I2S
13 help 13 help
14 Say Y, M or N if you want to add a custom ALSA extension that registers 14 Say Y or N if you want to add a custom ALSA extension that registers
15 a PCM and uses PIO to transfer data. 15 a PCM and uses PIO to transfer data.
16 16
17 This functionality is specially suited for I2S devices that don't have 17 This functionality is specially suited for I2S devices that don't have
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
index 38f1ca31c5fa..3e24c0ff95fb 100644
--- a/sound/soc/dwc/Makefile
+++ b/sound/soc/dwc/Makefile
@@ -1,5 +1,5 @@
1# SYNOPSYS Platform Support 1# SYNOPSYS Platform Support
2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o 2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
3ifdef CONFIG_SND_DESIGNWARE_PCM 3
4obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_pcm.o 4designware_i2s-y := dwc-i2s.o
5endif 5designware_i2s-$(CONFIG_SND_DESIGNWARE_PCM) += dwc-pcm.o
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/dwc-i2s.c
index 9c46e4112026..9c46e4112026 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/dwc-i2s.c
diff --git a/sound/soc/dwc/designware_pcm.c b/sound/soc/dwc/dwc-pcm.c
index 459ec861e6b6..406fd867117b 100644
--- a/sound/soc/dwc/designware_pcm.c
+++ b/sound/soc/dwc/dwc-pcm.c
@@ -129,13 +129,11 @@ void dw_pcm_push_tx(struct dw_i2s_dev *dev)
129{ 129{
130 dw_pcm_transfer(dev, true); 130 dw_pcm_transfer(dev, true);
131} 131}
132EXPORT_SYMBOL_GPL(dw_pcm_push_tx);
133 132
134void dw_pcm_pop_rx(struct dw_i2s_dev *dev) 133void dw_pcm_pop_rx(struct dw_i2s_dev *dev)
135{ 134{
136 dw_pcm_transfer(dev, false); 135 dw_pcm_transfer(dev, false);
137} 136}
138EXPORT_SYMBOL_GPL(dw_pcm_pop_rx);
139 137
140static int dw_pcm_open(struct snd_pcm_substream *substream) 138static int dw_pcm_open(struct snd_pcm_substream *substream)
141{ 139{
@@ -281,4 +279,3 @@ int dw_pcm_register(struct platform_device *pdev)
281{ 279{
282 return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform); 280 return devm_snd_soc_register_platform(&pdev->dev, &dw_pcm_platform);
283} 281}
284EXPORT_SYMBOL_GPL(dw_pcm_register);
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 883087f2b092..84ef6385736c 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -64,7 +64,7 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
64 return 0; 64 return 0;
65} 65}
66 66
67static struct snd_soc_ops eukrea_tlv320_snd_ops = { 67static const struct snd_soc_ops eukrea_tlv320_snd_ops = {
68 .hw_params = eukrea_tlv320_hw_params, 68 .hw_params = eukrea_tlv320_hw_params,
69}; 69};
70 70
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index dc30d780f874..282d841840b1 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -76,7 +76,7 @@ static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream)
76 pair->dma_chan[!dir], runtime->dma_addr, 76 pair->dma_chan[!dir], runtime->dma_addr,
77 snd_pcm_lib_buffer_bytes(substream), 77 snd_pcm_lib_buffer_bytes(substream),
78 snd_pcm_lib_period_bytes(substream), 78 snd_pcm_lib_period_bytes(substream),
79 dir == OUT ? DMA_TO_DEVICE : DMA_FROM_DEVICE, flags); 79 dir == OUT ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, flags);
80 if (!pair->desc[!dir]) { 80 if (!pair->desc[!dir]) {
81 dev_err(dev, "failed to prepare slave DMA for Front-End\n"); 81 dev_err(dev, "failed to prepare slave DMA for Front-End\n");
82 return -ENOMEM; 82 return -ENOMEM;
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 38bfd46f4ad8..809a069d490b 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -19,7 +19,6 @@
19#include "fsl_esai.h" 19#include "fsl_esai.h"
20#include "imx-pcm.h" 20#include "imx-pcm.h"
21 21
22#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
23#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ 22#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
24 SNDRV_PCM_FMTBIT_S16_LE | \ 23 SNDRV_PCM_FMTBIT_S16_LE | \
25 SNDRV_PCM_FMTBIT_S20_3LE | \ 24 SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -647,14 +646,14 @@ static struct snd_soc_dai_driver fsl_esai_dai = {
647 .stream_name = "CPU-Playback", 646 .stream_name = "CPU-Playback",
648 .channels_min = 1, 647 .channels_min = 1,
649 .channels_max = 12, 648 .channels_max = 12,
650 .rates = FSL_ESAI_RATES, 649 .rates = SNDRV_PCM_RATE_8000_192000,
651 .formats = FSL_ESAI_FORMATS, 650 .formats = FSL_ESAI_FORMATS,
652 }, 651 },
653 .capture = { 652 .capture = {
654 .stream_name = "CPU-Capture", 653 .stream_name = "CPU-Capture",
655 .channels_min = 1, 654 .channels_min = 1,
656 .channels_max = 8, 655 .channels_max = 8,
657 .rates = FSL_ESAI_RATES, 656 .rates = SNDRV_PCM_RATE_8000_192000,
658 .formats = FSL_ESAI_FORMATS, 657 .formats = FSL_ESAI_FORMATS,
659 }, 658 },
660 .ops = &fsl_esai_dai_ops, 659 .ops = &fsl_esai_dai_ops,
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fde08660b63b..173cb8496641 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/clk.h> 37#include <linux/clk.h>
38#include <linux/ctype.h>
38#include <linux/device.h> 39#include <linux/device.h>
39#include <linux/delay.h> 40#include <linux/delay.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
@@ -55,16 +56,6 @@
55#include "imx-pcm.h" 56#include "imx-pcm.h"
56 57
57/** 58/**
58 * FSLSSI_I2S_RATES: sample rates supported by the I2S
59 *
60 * This driver currently only supports the SSI running in I2S slave mode,
61 * which means the codec determines the sample rate. Therefore, we tell
62 * ALSA that we support all rates and let the codec driver decide what rates
63 * are really supported.
64 */
65#define FSLSSI_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
66
67/**
68 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI 59 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
69 * 60 *
70 * The SSI has a limitation in that the samples must be in the same byte 61 * The SSI has a limitation in that the samples must be in the same byte
@@ -1212,14 +1203,14 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = {
1212 .stream_name = "CPU-Playback", 1203 .stream_name = "CPU-Playback",
1213 .channels_min = 1, 1204 .channels_min = 1,
1214 .channels_max = 32, 1205 .channels_max = 32,
1215 .rates = FSLSSI_I2S_RATES, 1206 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1216 .formats = FSLSSI_I2S_FORMATS, 1207 .formats = FSLSSI_I2S_FORMATS,
1217 }, 1208 },
1218 .capture = { 1209 .capture = {
1219 .stream_name = "CPU-Capture", 1210 .stream_name = "CPU-Capture",
1220 .channels_min = 1, 1211 .channels_min = 1,
1221 .channels_max = 32, 1212 .channels_max = 32,
1222 .rates = FSLSSI_I2S_RATES, 1213 .rates = SNDRV_PCM_RATE_CONTINUOUS,
1223 .formats = FSLSSI_I2S_FORMATS, 1214 .formats = FSLSSI_I2S_FORMATS,
1224 }, 1215 },
1225 .ops = &fsl_ssi_dai_ops, 1216 .ops = &fsl_ssi_dai_ops,
@@ -1325,14 +1316,10 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
1325 */ 1316 */
1326static void make_lowercase(char *s) 1317static void make_lowercase(char *s)
1327{ 1318{
1328 char *p = s; 1319 if (!s)
1329 char c; 1320 return;
1330 1321 for (; *s; s++)
1331 while ((c = *p)) { 1322 *s = tolower(*s);
1332 if ((c >= 'A') && (c <= 'Z'))
1333 *p = c + ('a' - 'A');
1334 p++;
1335 }
1336} 1323}
1337 1324
1338static int fsl_ssi_imx_probe(struct platform_device *pdev, 1325static int fsl_ssi_imx_probe(struct platform_device *pdev,
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index bb0459018b45..9d19b808f634 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -48,7 +48,7 @@ static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream,
48 return snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16); 48 return snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16);
49} 49}
50 50
51static struct snd_soc_ops imx_mc13783_hifi_ops = { 51static const struct snd_soc_ops imx_mc13783_hifi_ops = {
52 .hw_params = imx_mc13783_hifi_hw_params, 52 .hw_params = imx_mc13783_hifi_hw_params,
53}; 53};
54 54
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index f3d3d1ffa84e..314814ddd2b0 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -33,48 +33,20 @@ static bool filter(struct dma_chan *chan, void *param)
33 return true; 33 return true;
34} 34}
35 35
36static const struct snd_pcm_hardware imx_pcm_hardware = {
37 .info = SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_BLOCK_TRANSFER |
39 SNDRV_PCM_INFO_MMAP |
40 SNDRV_PCM_INFO_MMAP_VALID |
41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME,
43 .buffer_bytes_max = IMX_DEFAULT_DMABUF_SIZE,
44 .period_bytes_min = 128,
45 .period_bytes_max = 65535, /* Limited by SDMA engine */
46 .periods_min = 2,
47 .periods_max = 255,
48 .fifo_size = 0,
49};
50
51static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = { 36static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
52 .pcm_hardware = &imx_pcm_hardware,
53 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, 37 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
54 .compat_filter_fn = filter, 38 .compat_filter_fn = filter,
55 .prealloc_buffer_size = IMX_DEFAULT_DMABUF_SIZE,
56}; 39};
57 40
58int imx_pcm_dma_init(struct platform_device *pdev, size_t size) 41int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
59{ 42{
60 struct snd_dmaengine_pcm_config *config; 43 struct snd_dmaengine_pcm_config *config;
61 struct snd_pcm_hardware *pcm_hardware;
62 44
63 config = devm_kzalloc(&pdev->dev, 45 config = devm_kzalloc(&pdev->dev,
64 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL); 46 sizeof(struct snd_dmaengine_pcm_config), GFP_KERNEL);
65 if (!config) 47 if (!config)
66 return -ENOMEM; 48 return -ENOMEM;
67 *config = imx_dmaengine_pcm_config; 49 *config = imx_dmaengine_pcm_config;
68 if (size)
69 config->prealloc_buffer_size = size;
70
71 pcm_hardware = devm_kzalloc(&pdev->dev,
72 sizeof(struct snd_pcm_hardware), GFP_KERNEL);
73 *pcm_hardware = imx_pcm_hardware;
74 if (size)
75 pcm_hardware->buffer_bytes_max = size;
76
77 config->pcm_hardware = pcm_hardware;
78 50
79 return devm_snd_dmaengine_pcm_register(&pdev->dev, 51 return devm_snd_dmaengine_pcm_register(&pdev->dev,
80 config, 52 config,
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index dac6688540dc..92410f7ca1fa 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -282,7 +282,7 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
282 return 0; 282 return 0;
283} 283}
284 284
285static int ssi_irq = 0; 285static int ssi_irq;
286 286
287static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) 287static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
288{ 288{
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 1b60958e2080..206b898e554c 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -33,14 +33,14 @@ struct imx_wm8962_data {
33 struct snd_soc_card card; 33 struct snd_soc_card card;
34 char codec_dai_name[DAI_NAME_SIZE]; 34 char codec_dai_name[DAI_NAME_SIZE];
35 char platform_name[DAI_NAME_SIZE]; 35 char platform_name[DAI_NAME_SIZE];
36 struct clk *codec_clk;
37 unsigned int clk_frequency; 36 unsigned int clk_frequency;
38}; 37};
39 38
40struct imx_priv { 39struct imx_priv {
41 struct platform_device *pdev; 40 struct platform_device *pdev;
41 int sample_rate;
42 snd_pcm_format_t sample_format;
42}; 43};
43static struct imx_priv card_priv;
44 44
45static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = { 45static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
46 SND_SOC_DAPM_HP("Headphone Jack", NULL), 46 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -49,14 +49,14 @@ static const struct snd_soc_dapm_widget imx_wm8962_dapm_widgets[] = {
49 SND_SOC_DAPM_MIC("DMIC", NULL), 49 SND_SOC_DAPM_MIC("DMIC", NULL),
50}; 50};
51 51
52static int sample_rate = 44100;
53static snd_pcm_format_t sample_format = SNDRV_PCM_FORMAT_S16_LE;
54
55static int imx_hifi_hw_params(struct snd_pcm_substream *substream, 52static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params) 53 struct snd_pcm_hw_params *params)
57{ 54{
58 sample_rate = params_rate(params); 55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 sample_format = params_format(params); 56 struct imx_priv *priv = snd_soc_card_get_drvdata(rtd->card);
57
58 priv->sample_rate = params_rate(params);
59 priv->sample_format = params_format(params);
60 60
61 return 0; 61 return 0;
62} 62}
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
71{ 71{
72 struct snd_soc_pcm_runtime *rtd; 72 struct snd_soc_pcm_runtime *rtd;
73 struct snd_soc_dai *codec_dai; 73 struct snd_soc_dai *codec_dai;
74 struct imx_priv *priv = &card_priv; 74 struct imx_priv *priv = snd_soc_card_get_drvdata(card);
75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 75 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
76 struct device *dev = &priv->pdev->dev; 76 struct device *dev = &priv->pdev->dev;
77 unsigned int pll_out; 77 unsigned int pll_out;
@@ -85,10 +85,10 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
85 switch (level) { 85 switch (level) {
86 case SND_SOC_BIAS_PREPARE: 86 case SND_SOC_BIAS_PREPARE:
87 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 87 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
88 if (sample_format == SNDRV_PCM_FORMAT_S24_LE) 88 if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
89 pll_out = sample_rate * 384; 89 pll_out = priv->sample_rate * 384;
90 else 90 else
91 pll_out = sample_rate * 256; 91 pll_out = priv->sample_rate * 256;
92 92
93 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, 93 ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL,
94 WM8962_FLL_MCLK, data->clk_frequency, 94 WM8962_FLL_MCLK, data->clk_frequency,
@@ -140,7 +140,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
140{ 140{
141 struct snd_soc_pcm_runtime *rtd; 141 struct snd_soc_pcm_runtime *rtd;
142 struct snd_soc_dai *codec_dai; 142 struct snd_soc_dai *codec_dai;
143 struct imx_priv *priv = &card_priv; 143 struct imx_priv *priv = snd_soc_card_get_drvdata(card);
144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card); 144 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
145 struct device *dev = &priv->pdev->dev; 145 struct device *dev = &priv->pdev->dev;
146 int ret; 146 int ret;
@@ -160,13 +160,20 @@ static int imx_wm8962_probe(struct platform_device *pdev)
160 struct device_node *np = pdev->dev.of_node; 160 struct device_node *np = pdev->dev.of_node;
161 struct device_node *ssi_np, *codec_np; 161 struct device_node *ssi_np, *codec_np;
162 struct platform_device *ssi_pdev; 162 struct platform_device *ssi_pdev;
163 struct imx_priv *priv = &card_priv;
164 struct i2c_client *codec_dev; 163 struct i2c_client *codec_dev;
165 struct imx_wm8962_data *data; 164 struct imx_wm8962_data *data;
165 struct imx_priv *priv;
166 struct clk *codec_clk;
166 int int_port, ext_port; 167 int int_port, ext_port;
167 int ret; 168 int ret;
168 169
170 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
171 if (!priv)
172 return -ENOMEM;
173
169 priv->pdev = pdev; 174 priv->pdev = pdev;
175 priv->sample_rate = 44100;
176 priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
170 177
171 ret = of_property_read_u32(np, "mux-int-port", &int_port); 178 ret = of_property_read_u32(np, "mux-int-port", &int_port);
172 if (ret) { 179 if (ret) {
@@ -231,19 +238,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
231 goto fail; 238 goto fail;
232 } 239 }
233 240
234 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL); 241 codec_clk = clk_get(&codec_dev->dev, NULL);
235 if (IS_ERR(data->codec_clk)) { 242 if (IS_ERR(codec_clk)) {
236 ret = PTR_ERR(data->codec_clk); 243 ret = PTR_ERR(codec_clk);
237 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret); 244 dev_err(&codec_dev->dev, "failed to get codec clk: %d\n", ret);
238 goto fail; 245 goto fail;
239 } 246 }
240 247
241 data->clk_frequency = clk_get_rate(data->codec_clk); 248 data->clk_frequency = clk_get_rate(codec_clk);
242 ret = clk_prepare_enable(data->codec_clk); 249 clk_put(codec_clk);
243 if (ret) {
244 dev_err(&codec_dev->dev, "failed to enable codec clk: %d\n", ret);
245 goto fail;
246 }
247 250
248 data->dai.name = "HiFi"; 251 data->dai.name = "HiFi";
249 data->dai.stream_name = "HiFi"; 252 data->dai.stream_name = "HiFi";
@@ -258,10 +261,10 @@ static int imx_wm8962_probe(struct platform_device *pdev)
258 data->card.dev = &pdev->dev; 261 data->card.dev = &pdev->dev;
259 ret = snd_soc_of_parse_card_name(&data->card, "model"); 262 ret = snd_soc_of_parse_card_name(&data->card, "model");
260 if (ret) 263 if (ret)
261 goto clk_fail; 264 goto fail;
262 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); 265 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
263 if (ret) 266 if (ret)
264 goto clk_fail; 267 goto fail;
265 data->card.num_links = 1; 268 data->card.num_links = 1;
266 data->card.owner = THIS_MODULE; 269 data->card.owner = THIS_MODULE;
267 data->card.dai_link = &data->dai; 270 data->card.dai_link = &data->dai;
@@ -277,16 +280,9 @@ static int imx_wm8962_probe(struct platform_device *pdev)
277 ret = devm_snd_soc_register_card(&pdev->dev, &data->card); 280 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
278 if (ret) { 281 if (ret) {
279 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 282 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
280 goto clk_fail; 283 goto fail;
281 } 284 }
282 285
283 of_node_put(ssi_np);
284 of_node_put(codec_np);
285
286 return 0;
287
288clk_fail:
289 clk_disable_unprepare(data->codec_clk);
290fail: 286fail:
291 of_node_put(ssi_np); 287 of_node_put(ssi_np);
292 of_node_put(codec_np); 288 of_node_put(codec_np);
@@ -294,17 +290,6 @@ fail:
294 return ret; 290 return ret;
295} 291}
296 292
297static int imx_wm8962_remove(struct platform_device *pdev)
298{
299 struct snd_soc_card *card = platform_get_drvdata(pdev);
300 struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
301
302 if (!IS_ERR(data->codec_clk))
303 clk_disable_unprepare(data->codec_clk);
304
305 return 0;
306}
307
308static const struct of_device_id imx_wm8962_dt_ids[] = { 293static const struct of_device_id imx_wm8962_dt_ids[] = {
309 { .compatible = "fsl,imx-audio-wm8962", }, 294 { .compatible = "fsl,imx-audio-wm8962", },
310 { /* sentinel */ } 295 { /* sentinel */ }
@@ -318,7 +303,6 @@ static struct platform_driver imx_wm8962_driver = {
318 .of_match_table = imx_wm8962_dt_ids, 303 .of_match_table = imx_wm8962_dt_ids,
319 }, 304 },
320 .probe = imx_wm8962_probe, 305 .probe = imx_wm8962_probe,
321 .remove = imx_wm8962_remove,
322}; 306};
323module_platform_driver(imx_wm8962_driver); 307module_platform_driver(imx_wm8962_driver);
324 308
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index ddf49f30b23f..a639b52c16f6 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -174,7 +174,7 @@ static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card)
174/** 174/**
175 * mpc8610_hpcd_ops: ASoC machine driver operations 175 * mpc8610_hpcd_ops: ASoC machine driver operations
176 */ 176 */
177static struct snd_soc_ops mpc8610_hpcd_ops = { 177static const struct snd_soc_ops mpc8610_hpcd_ops = {
178 .startup = mpc8610_hpcd_startup, 178 .startup = mpc8610_hpcd_startup,
179}; 179};
180 180
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index 198eeb3f3f7a..d7ec3d20065c 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -73,7 +73,7 @@ static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
73 return 0; 73 return 0;
74} 74}
75 75
76static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { 76static const struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
77 .hw_params = mx27vis_aic32x4_hw_params, 77 .hw_params = mx27vis_aic32x4_hw_params,
78}; 78};
79 79
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index a1f780ecadf5..41c623c55c16 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -184,7 +184,7 @@ static int p1022_ds_machine_remove(struct snd_soc_card *card)
184/** 184/**
185 * p1022_ds_ops: ASoC machine driver operations 185 * p1022_ds_ops: ASoC machine driver operations
186 */ 186 */
187static struct snd_soc_ops p1022_ds_ops = { 187static const struct snd_soc_ops p1022_ds_ops = {
188 .startup = p1022_ds_startup, 188 .startup = p1022_ds_startup,
189}; 189};
190 190
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index d4d88a8cb9c0..4afbdd610bfa 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -188,7 +188,7 @@ static int p1022_rdk_machine_remove(struct snd_soc_card *card)
188/** 188/**
189 * p1022_rdk_ops: ASoC machine driver operations 189 * p1022_rdk_ops: ASoC machine driver operations
190 */ 190 */
191static struct snd_soc_ops p1022_rdk_ops = { 191static const struct snd_soc_ops p1022_rdk_ops = {
192 .startup = p1022_rdk_startup, 192 .startup = p1022_rdk_startup,
193}; 193};
194 194
diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index ae403c29688f..66fb6c4614d2 100644
--- a/sound/soc/fsl/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
@@ -23,7 +23,7 @@
23 23
24static struct snd_soc_card imx_phycore; 24static struct snd_soc_card imx_phycore;
25 25
26static struct snd_soc_ops imx_phycore_hifi_ops = { 26static const struct snd_soc_ops imx_phycore_hifi_ops = {
27}; 27};
28 28
29static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { 29static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index b454972dce35..cdaf16367b47 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -139,7 +139,7 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
139 return 0; 139 return 0;
140} 140}
141 141
142static struct snd_soc_ops wm1133_ev1_ops = { 142static const struct snd_soc_ops wm1133_ev1_ops = {
143 .hw_params = wm1133_ev1_hw_params, 143 .hw_params = wm1133_ev1_hw_params,
144}; 144};
145 145
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 85b4f1806514..2c9dedab5184 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -40,9 +40,10 @@ struct simple_card_data {
40 struct snd_soc_dai_link *dai_link; 40 struct snd_soc_dai_link *dai_link;
41}; 41};
42 42
43#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) 43#define simple_priv_to_card(priv) (&(priv)->snd_card)
44#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
45#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) 44#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
45#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
46#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
46 47
47#define DAI "sound-dai" 48#define DAI "sound-dai"
48#define CELL "#sound-dai-cells" 49#define CELL "#sound-dai-cells"
@@ -323,6 +324,7 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
323{ 324{
324 struct device *dev = simple_priv_to_dev(priv); 325 struct device *dev = simple_priv_to_dev(priv);
325 struct device_node *aux_node; 326 struct device_node *aux_node;
327 struct snd_soc_card *card = simple_priv_to_card(priv);
326 int i, n, len; 328 int i, n, len;
327 329
328 if (!of_find_property(node, PREFIX "aux-devs", &len)) 330 if (!of_find_property(node, PREFIX "aux-devs", &len))
@@ -332,19 +334,19 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
332 if (n <= 0) 334 if (n <= 0)
333 return -EINVAL; 335 return -EINVAL;
334 336
335 priv->snd_card.aux_dev = devm_kzalloc(dev, 337 card->aux_dev = devm_kzalloc(dev,
336 n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL); 338 n * sizeof(*card->aux_dev), GFP_KERNEL);
337 if (!priv->snd_card.aux_dev) 339 if (!card->aux_dev)
338 return -ENOMEM; 340 return -ENOMEM;
339 341
340 for (i = 0; i < n; i++) { 342 for (i = 0; i < n; i++) {
341 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i); 343 aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
342 if (!aux_node) 344 if (!aux_node)
343 return -EINVAL; 345 return -EINVAL;
344 priv->snd_card.aux_dev[i].codec_of_node = aux_node; 346 card->aux_dev[i].codec_of_node = aux_node;
345 } 347 }
346 348
347 priv->snd_card.num_aux_devs = n; 349 card->num_aux_devs = n;
348 return 0; 350 return 0;
349} 351}
350 352
@@ -352,6 +354,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
352 struct simple_card_data *priv) 354 struct simple_card_data *priv)
353{ 355{
354 struct device *dev = simple_priv_to_dev(priv); 356 struct device *dev = simple_priv_to_dev(priv);
357 struct snd_soc_card *card = simple_priv_to_card(priv);
355 struct device_node *dai_link; 358 struct device_node *dai_link;
356 int ret; 359 int ret;
357 360
@@ -362,7 +365,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
362 365
363 /* The off-codec widgets */ 366 /* The off-codec widgets */
364 if (of_property_read_bool(node, PREFIX "widgets")) { 367 if (of_property_read_bool(node, PREFIX "widgets")) {
365 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, 368 ret = snd_soc_of_parse_audio_simple_widgets(card,
366 PREFIX "widgets"); 369 PREFIX "widgets");
367 if (ret) 370 if (ret)
368 goto card_parse_end; 371 goto card_parse_end;
@@ -370,7 +373,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
370 373
371 /* DAPM routes */ 374 /* DAPM routes */
372 if (of_property_read_bool(node, PREFIX "routing")) { 375 if (of_property_read_bool(node, PREFIX "routing")) {
373 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, 376 ret = snd_soc_of_parse_audio_routing(card,
374 PREFIX "routing"); 377 PREFIX "routing");
375 if (ret) 378 if (ret)
376 goto card_parse_end; 379 goto card_parse_end;
@@ -401,7 +404,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
401 goto card_parse_end; 404 goto card_parse_end;
402 } 405 }
403 406
404 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); 407 ret = asoc_simple_card_parse_card_name(card, PREFIX);
405 if (ret < 0) 408 if (ret < 0)
406 goto card_parse_end; 409 goto card_parse_end;
407 410
@@ -418,8 +421,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
418 struct simple_card_data *priv; 421 struct simple_card_data *priv;
419 struct snd_soc_dai_link *dai_link; 422 struct snd_soc_dai_link *dai_link;
420 struct simple_dai_props *dai_props; 423 struct simple_dai_props *dai_props;
421 struct device_node *np = pdev->dev.of_node;
422 struct device *dev = &pdev->dev; 424 struct device *dev = &pdev->dev;
425 struct device_node *np = dev->of_node;
426 struct snd_soc_card *card;
423 int num, ret; 427 int num, ret;
424 428
425 /* Get the number of DAI links */ 429 /* Get the number of DAI links */
@@ -442,10 +446,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
442 priv->dai_link = dai_link; 446 priv->dai_link = dai_link;
443 447
444 /* Init snd_soc_card */ 448 /* Init snd_soc_card */
445 priv->snd_card.owner = THIS_MODULE; 449 card = simple_priv_to_card(priv);
446 priv->snd_card.dev = dev; 450 card->owner = THIS_MODULE;
447 priv->snd_card.dai_link = priv->dai_link; 451 card->dev = dev;
448 priv->snd_card.num_links = num; 452 card->dai_link = priv->dai_link;
453 card->num_links = num;
449 454
450 if (np && of_device_is_available(np)) { 455 if (np && of_device_is_available(np)) {
451 456
@@ -474,7 +479,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
474 return -EINVAL; 479 return -EINVAL;
475 } 480 }
476 481
477 priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name; 482 card->name = (cinfo->card) ? cinfo->card : cinfo->name;
478 dai_link->name = cinfo->name; 483 dai_link->name = cinfo->name;
479 dai_link->stream_name = cinfo->name; 484 dai_link->stream_name = cinfo->name;
480 dai_link->platform_name = cinfo->platform; 485 dai_link->platform_name = cinfo->platform;
@@ -489,13 +494,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
489 sizeof(priv->dai_props->codec_dai)); 494 sizeof(priv->dai_props->codec_dai));
490 } 495 }
491 496
492 snd_soc_card_set_drvdata(&priv->snd_card, priv); 497 snd_soc_card_set_drvdata(card, priv);
493 498
494 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 499 ret = devm_snd_soc_register_card(dev, card);
495 if (ret >= 0) 500 if (ret >= 0)
496 return ret; 501 return ret;
497err: 502err:
498 asoc_simple_card_clean_reference(&priv->snd_card); 503 asoc_simple_card_clean_reference(card);
499 504
500 return ret; 505 return ret;
501} 506}
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index 308ff4c11a8d..dcbcab230d1b 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -31,9 +31,10 @@ struct simple_card_data {
31 u32 convert_channels; 31 u32 convert_channels;
32}; 32};
33 33
34#define simple_priv_to_dev(priv) ((priv)->snd_card.dev) 34#define simple_priv_to_card(priv) (&(priv)->snd_card)
35#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
36#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i)) 35#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
36#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
37#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
37 38
38#define DAI "sound-dai" 39#define DAI "sound-dai"
39#define CELL "#sound-dai-cells" 40#define CELL "#sound-dai-cells"
@@ -109,6 +110,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
109 struct device *dev = simple_priv_to_dev(priv); 110 struct device *dev = simple_priv_to_dev(priv);
110 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 111 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
111 struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx); 112 struct asoc_simple_dai *dai_props = simple_priv_to_props(priv, idx);
113 struct snd_soc_card *card = simple_priv_to_card(priv);
112 int ret; 114 int ret;
113 115
114 if (is_fe) { 116 if (is_fe) {
@@ -163,7 +165,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
163 if (ret < 0) 165 if (ret < 0)
164 return ret; 166 return ret;
165 167
166 snd_soc_of_parse_audio_prefix(&priv->snd_card, 168 snd_soc_of_parse_audio_prefix(card,
167 &priv->codec_conf, 169 &priv->codec_conf,
168 dai_link->codec_of_node, 170 dai_link->codec_of_node,
169 PREFIX "prefix"); 171 PREFIX "prefix");
@@ -201,6 +203,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
201{ 203{
202 struct device *dev = simple_priv_to_dev(priv); 204 struct device *dev = simple_priv_to_dev(priv);
203 struct device_node *np; 205 struct device_node *np;
206 struct snd_soc_card *card = simple_priv_to_card(priv);
204 unsigned int daifmt = 0; 207 unsigned int daifmt = 0;
205 bool is_fe; 208 bool is_fe;
206 int ret, i; 209 int ret, i;
@@ -208,7 +211,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
208 if (!node) 211 if (!node)
209 return -EINVAL; 212 return -EINVAL;
210 213
211 ret = snd_soc_of_parse_audio_routing(&priv->snd_card, PREFIX "routing"); 214 ret = snd_soc_of_parse_audio_routing(card, PREFIX "routing");
212 if (ret < 0) 215 if (ret < 0)
213 return ret; 216 return ret;
214 217
@@ -239,12 +242,12 @@ static int asoc_simple_card_parse_of(struct device_node *node,
239 i++; 242 i++;
240 } 243 }
241 244
242 ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); 245 ret = asoc_simple_card_parse_card_name(card, PREFIX);
243 if (ret < 0) 246 if (ret < 0)
244 return ret; 247 return ret;
245 248
246 dev_dbg(dev, "New card: %s\n", 249 dev_dbg(dev, "New card: %s\n",
247 priv->snd_card.name ? priv->snd_card.name : ""); 250 card->name ? card->name : "");
248 dev_dbg(dev, "convert_rate %d\n", priv->convert_rate); 251 dev_dbg(dev, "convert_rate %d\n", priv->convert_rate);
249 dev_dbg(dev, "convert_channels %d\n", priv->convert_channels); 252 dev_dbg(dev, "convert_channels %d\n", priv->convert_channels);
250 253
@@ -256,8 +259,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
256 struct simple_card_data *priv; 259 struct simple_card_data *priv;
257 struct snd_soc_dai_link *dai_link; 260 struct snd_soc_dai_link *dai_link;
258 struct asoc_simple_dai *dai_props; 261 struct asoc_simple_dai *dai_props;
262 struct snd_soc_card *card;
259 struct device *dev = &pdev->dev; 263 struct device *dev = &pdev->dev;
260 struct device_node *np = pdev->dev.of_node; 264 struct device_node *np = dev->of_node;
261 int num, ret; 265 int num, ret;
262 266
263 /* Allocate the private data */ 267 /* Allocate the private data */
@@ -276,12 +280,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
276 priv->dai_link = dai_link; 280 priv->dai_link = dai_link;
277 281
278 /* Init snd_soc_card */ 282 /* Init snd_soc_card */
279 priv->snd_card.owner = THIS_MODULE; 283 card = simple_priv_to_card(priv);
280 priv->snd_card.dev = dev; 284 card->owner = THIS_MODULE;
281 priv->snd_card.dai_link = priv->dai_link; 285 card->dev = dev;
282 priv->snd_card.num_links = num; 286 card->dai_link = priv->dai_link;
283 priv->snd_card.codec_conf = &priv->codec_conf; 287 card->num_links = num;
284 priv->snd_card.num_configs = 1; 288 card->codec_conf = &priv->codec_conf;
289 card->num_configs = 1;
285 290
286 ret = asoc_simple_card_parse_of(np, priv); 291 ret = asoc_simple_card_parse_of(np, priv);
287 if (ret < 0) { 292 if (ret < 0) {
@@ -290,13 +295,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
290 goto err; 295 goto err;
291 } 296 }
292 297
293 snd_soc_card_set_drvdata(&priv->snd_card, priv); 298 snd_soc_card_set_drvdata(card, priv);
294 299
295 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); 300 ret = devm_snd_soc_register_card(dev, card);
296 if (ret >= 0) 301 if (ret >= 0)
297 return ret; 302 return ret;
298err: 303err:
299 asoc_simple_card_clean_reference(&priv->snd_card); 304 asoc_simple_card_clean_reference(card);
300 305
301 return ret; 306 return ret;
302} 307}
diff --git a/sound/soc/hisilicon/Kconfig b/sound/soc/hisilicon/Kconfig
new file mode 100644
index 000000000000..4356d5a1d338
--- /dev/null
+++ b/sound/soc/hisilicon/Kconfig
@@ -0,0 +1,5 @@
1config SND_I2S_HI6210_I2S
2 tristate "Hisilicon I2S controller"
3 select SND_SOC_GENERIC_DMAENGINE_PCM
4 help
5 Hisilicon I2S
diff --git a/sound/soc/hisilicon/Makefile b/sound/soc/hisilicon/Makefile
new file mode 100644
index 000000000000..e8095e2af91a
--- /dev/null
+++ b/sound/soc/hisilicon/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SND_I2S_HI6210_I2S) += hi6210-i2s.o
diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c
new file mode 100644
index 000000000000..45163e5202f5
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.c
@@ -0,0 +1,618 @@
1/*
2 * linux/sound/soc/m8m/hi6210_i2s.c - I2S IP driver
3 *
4 * Copyright (C) 2015 Linaro, Ltd
5 * Author: Andy Green <andy.green@linaro.org>
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 as published by
9 * the Free Software Foundation, version 2 of the License.
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 * This driver only deals with S2 interface (BT)
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/jiffies.h>
25#include <linux/io.h>
26#include <linux/gpio.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/dmaengine_pcm.h>
31#include <sound/initval.h>
32#include <sound/soc.h>
33#include <linux/interrupt.h>
34#include <linux/reset.h>
35#include <linux/of_address.h>
36#include <linux/of_irq.h>
37#include <linux/mfd/syscon.h>
38#include <linux/reset-controller.h>
39#include <linux/clk.h>
40
41#include "hi6210-i2s.h"
42
43struct hi6210_i2s {
44 struct device *dev;
45 struct reset_control *rc;
46 struct clk *clk[8];
47 int clocks;
48 struct snd_soc_dai_driver dai;
49 void __iomem *base;
50 struct regmap *sysctrl;
51 phys_addr_t base_phys;
52 struct snd_dmaengine_dai_dma_data dma_data[2];
53 int clk_rate;
54 spinlock_t lock;
55 int rate;
56 int format;
57 u8 bits;
58 u8 channels;
59 u8 id;
60 u8 channel_length;
61 u8 use;
62 u32 master:1;
63 u32 status:1;
64};
65
66#define SC_PERIPH_CLKEN1 0x210
67#define SC_PERIPH_CLKDIS1 0x214
68
69#define SC_PERIPH_CLKEN3 0x230
70#define SC_PERIPH_CLKDIS3 0x234
71
72#define SC_PERIPH_CLKEN12 0x270
73#define SC_PERIPH_CLKDIS12 0x274
74
75#define SC_PERIPH_RSTEN1 0x310
76#define SC_PERIPH_RSTDIS1 0x314
77#define SC_PERIPH_RSTSTAT1 0x318
78
79#define SC_PERIPH_RSTEN2 0x320
80#define SC_PERIPH_RSTDIS2 0x324
81#define SC_PERIPH_RSTSTAT2 0x328
82
83#define SOC_PMCTRL_BBPPLLALIAS 0x48
84
85enum {
86 CLK_DACODEC,
87 CLK_I2S_BASE,
88};
89
90static inline void hi6210_write_reg(struct hi6210_i2s *i2s, int reg, u32 val)
91{
92 writel(val, i2s->base + reg);
93}
94
95static inline u32 hi6210_read_reg(struct hi6210_i2s *i2s, int reg)
96{
97 return readl(i2s->base + reg);
98}
99
100int hi6210_i2s_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *cpu_dai)
102{
103 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
104 int ret, n;
105 u32 val;
106
107 /* deassert reset on ABB */
108 regmap_read(i2s->sysctrl, SC_PERIPH_RSTSTAT2, &val);
109 if (val & BIT(4))
110 regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS2, BIT(4));
111
112 for (n = 0; n < i2s->clocks; n++) {
113 ret = clk_prepare_enable(i2s->clk[n]);
114 if (ret) {
115 while (n--)
116 clk_disable_unprepare(i2s->clk[n]);
117 return ret;
118 }
119 }
120
121 ret = clk_set_rate(i2s->clk[CLK_I2S_BASE], 49152000);
122 if (ret) {
123 dev_err(i2s->dev, "%s: setting 49.152MHz base rate failed %d\n",
124 __func__, ret);
125 return ret;
126 }
127
128 /* enable clock before frequency division */
129 regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN12, BIT(9));
130
131 /* enable codec working clock / == "codec bus clock" */
132 regmap_write(i2s->sysctrl, SC_PERIPH_CLKEN1, BIT(5));
133
134 /* deassert reset on codec / interface clock / working clock */
135 regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
136 regmap_write(i2s->sysctrl, SC_PERIPH_RSTDIS1, BIT(5));
137
138 /* not interested in i2s irqs */
139 val = hi6210_read_reg(i2s, HII2S_CODEC_IRQ_MASK);
140 val |= 0x3f;
141 hi6210_write_reg(i2s, HII2S_CODEC_IRQ_MASK, val);
142
143
144 /* reset the stereo downlink fifo */
145 val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
146 val |= (BIT(5) | BIT(4));
147 hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
148
149 val = hi6210_read_reg(i2s, HII2S_APB_AFIFO_CFG_1);
150 val &= ~(BIT(5) | BIT(4));
151 hi6210_write_reg(i2s, HII2S_APB_AFIFO_CFG_1, val);
152
153
154 val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
155 val &= ~(HII2S_SW_RST_N__ST_DL_WORDLEN_MASK <<
156 HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
157 val |= (HII2S_BITS_16 << HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT);
158 hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
159
160 val = hi6210_read_reg(i2s, HII2S_MISC_CFG);
161 /* mux 11/12 = APB not i2s */
162 val &= ~HII2S_MISC_CFG__ST_DL_TEST_SEL;
163 /* BT R ch 0 = mixer op of DACR ch */
164 val &= ~HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
165 val &= ~HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
166
167 val |= HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL;
168 /* BT L ch = 1 = mux 7 = "mixer output of DACL */
169 val |= HII2S_MISC_CFG__S2_DOUT_TEST_SEL;
170 hi6210_write_reg(i2s, HII2S_MISC_CFG, val);
171
172 val = hi6210_read_reg(i2s, HII2S_SW_RST_N);
173 val |= HII2S_SW_RST_N__SW_RST_N;
174 hi6210_write_reg(i2s, HII2S_SW_RST_N, val);
175
176 return 0;
177}
178void hi6210_i2s_shutdown(struct snd_pcm_substream *substream,
179 struct snd_soc_dai *cpu_dai)
180{
181 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
182 int n;
183
184 for (n = 0; n < i2s->clocks; n++)
185 clk_disable_unprepare(i2s->clk[n]);
186
187 regmap_write(i2s->sysctrl, SC_PERIPH_RSTEN1, BIT(5));
188}
189
190static void hi6210_i2s_txctrl(struct snd_soc_dai *cpu_dai, int on)
191{
192 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
193 u32 val;
194
195 spin_lock(&i2s->lock);
196 if (on) {
197 /* enable S2 TX */
198 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
199 val |= HII2S_I2S_CFG__S2_IF_TX_EN;
200 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
201 } else {
202 /* disable S2 TX */
203 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
204 val &= ~HII2S_I2S_CFG__S2_IF_TX_EN;
205 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
206 }
207 spin_unlock(&i2s->lock);
208}
209
210static void hi6210_i2s_rxctrl(struct snd_soc_dai *cpu_dai, int on)
211{
212 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
213 u32 val;
214
215 spin_lock(&i2s->lock);
216 if (on) {
217 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
218 val |= HII2S_I2S_CFG__S2_IF_RX_EN;
219 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
220 } else {
221 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
222 val &= ~HII2S_I2S_CFG__S2_IF_RX_EN;
223 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
224 }
225 spin_unlock(&i2s->lock);
226}
227
228static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
229{
230 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
231
232 /*
233 * We don't actually set the hardware until the hw_params
234 * call, but we need to validate the user input here.
235 */
236 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
237 case SND_SOC_DAIFMT_CBM_CFM:
238 case SND_SOC_DAIFMT_CBS_CFS:
239 break;
240 default:
241 return -EINVAL;
242 }
243
244 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
245 case SND_SOC_DAIFMT_I2S:
246 case SND_SOC_DAIFMT_LEFT_J:
247 case SND_SOC_DAIFMT_RIGHT_J:
248 break;
249 default:
250 return -EINVAL;
251 }
252
253 i2s->format = fmt;
254 i2s->master = (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) ==
255 SND_SOC_DAIFMT_CBS_CFS;
256
257 return 0;
258}
259
260static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream,
261 struct snd_pcm_hw_params *params,
262 struct snd_soc_dai *cpu_dai)
263{
264 struct hi6210_i2s *i2s = dev_get_drvdata(cpu_dai->dev);
265 u32 bits = 0, rate = 0, signed_data = 0, fmt = 0;
266 u32 val;
267 struct snd_dmaengine_dai_dma_data *dma_data;
268
269 switch (params_format(params)) {
270 case SNDRV_PCM_FORMAT_U16_LE:
271 signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
272 /* fallthru */
273 case SNDRV_PCM_FORMAT_S16_LE:
274 bits = HII2S_BITS_16;
275 break;
276 case SNDRV_PCM_FORMAT_U24_LE:
277 signed_data = HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
278 /* fallthru */
279 case SNDRV_PCM_FORMAT_S24_LE:
280 bits = HII2S_BITS_24;
281 break;
282 default:
283 dev_err(cpu_dai->dev, "Bad format\n");
284 return -EINVAL;
285 }
286
287
288 switch (params_rate(params)) {
289 case 8000:
290 rate = HII2S_FS_RATE_8KHZ;
291 break;
292 case 16000:
293 rate = HII2S_FS_RATE_16KHZ;
294 break;
295 case 32000:
296 rate = HII2S_FS_RATE_32KHZ;
297 break;
298 case 48000:
299 rate = HII2S_FS_RATE_48KHZ;
300 break;
301 case 96000:
302 rate = HII2S_FS_RATE_96KHZ;
303 break;
304 case 192000:
305 rate = HII2S_FS_RATE_192KHZ;
306 break;
307 default:
308 dev_err(cpu_dai->dev, "Bad rate: %d\n", params_rate(params));
309 return -EINVAL;
310 }
311
312 if (!(params_channels(params))) {
313 dev_err(cpu_dai->dev, "Bad channels\n");
314 return -EINVAL;
315 }
316
317 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
318
319 switch (bits) {
320 case HII2S_BITS_24:
321 i2s->bits = 32;
322 dma_data->addr_width = 3;
323 break;
324 default:
325 i2s->bits = 16;
326 dma_data->addr_width = 2;
327 break;
328 }
329 i2s->rate = params_rate(params);
330 i2s->channels = params_channels(params);
331 i2s->channel_length = i2s->channels * i2s->bits;
332
333 val = hi6210_read_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG);
334 val &= ~((HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK <<
335 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
336 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK <<
337 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
338 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK <<
339 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
340 (HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK <<
341 HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
342 val |= ((16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT) |
343 (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT) |
344 (16 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT) |
345 (30 << HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT));
346 hi6210_write_reg(i2s, HII2S_ST_DL_FIFO_TH_CFG, val);
347
348
349 val = hi6210_read_reg(i2s, HII2S_IF_CLK_EN_CFG);
350 val |= (BIT(19) | BIT(18) | BIT(17) |
351 HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN |
352 HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN |
353 HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN |
354 HII2S_IF_CLK_EN_CFG__ST_DL_R_EN |
355 HII2S_IF_CLK_EN_CFG__ST_DL_L_EN);
356 hi6210_write_reg(i2s, HII2S_IF_CLK_EN_CFG, val);
357
358
359 val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG);
360 val &= ~(HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN |
361 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN |
362 HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN |
363 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN |
364 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN |
365 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN);
366 val |= (HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN |
367 HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN);
368 hi6210_write_reg(i2s, HII2S_DIG_FILTER_CLK_EN_CFG, val);
369
370
371 val = hi6210_read_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG);
372 val &= ~(HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE |
373 HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE);
374 hi6210_write_reg(i2s, HII2S_DIG_FILTER_MODULE_CFG, val);
375
376 val = hi6210_read_reg(i2s, HII2S_MUX_TOP_MODULE_CFG);
377 val &= ~(HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE |
378 HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE |
379 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE |
380 HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE);
381 hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val);
382
383
384 switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) {
385 case SND_SOC_DAIFMT_CBM_CFM:
386 i2s->master = false;
387 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
388 val |= HII2S_I2S_CFG__S2_MST_SLV;
389 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 i2s->master = true;
393 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
394 val &= ~HII2S_I2S_CFG__S2_MST_SLV;
395 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
396 break;
397 default:
398 WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n");
399 return -EINVAL;
400 }
401
402 switch (i2s->format & SND_SOC_DAIFMT_FORMAT_MASK) {
403 case SND_SOC_DAIFMT_I2S:
404 fmt = HII2S_FORMAT_I2S;
405 break;
406 case SND_SOC_DAIFMT_LEFT_J:
407 fmt = HII2S_FORMAT_LEFT_JUST;
408 break;
409 case SND_SOC_DAIFMT_RIGHT_J:
410 fmt = HII2S_FORMAT_RIGHT_JUST;
411 break;
412 default:
413 WARN_ONCE(1, "Invalid i2s->fmt FORMAT_MASK. This shouldn't happen\n");
414 return -EINVAL;
415 }
416
417 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
418 val &= ~(HII2S_I2S_CFG__S2_FUNC_MODE_MASK <<
419 HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT);
420 val |= fmt << HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT;
421 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
422
423
424 val = hi6210_read_reg(i2s, HII2S_CLK_SEL);
425 val &= ~(HII2S_CLK_SEL__I2S_BT_FM_SEL | /* BT gets the I2S */
426 HII2S_CLK_SEL__EXT_12_288MHZ_SEL);
427 hi6210_write_reg(i2s, HII2S_CLK_SEL, val);
428
429 dma_data->maxburst = 2;
430
431 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
432 dma_data->addr = i2s->base_phys + HII2S_ST_DL_CHANNEL;
433 else
434 dma_data->addr = i2s->base_phys + HII2S_STEREO_UPLINK_CHANNEL;
435
436 switch (i2s->channels) {
437 case 1:
438 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
439 val |= HII2S_I2S_CFG__S2_FRAME_MODE;
440 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
441 break;
442 default:
443 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
444 val &= ~HII2S_I2S_CFG__S2_FRAME_MODE;
445 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
446 break;
447 }
448
449 /* clear loopback, set signed type and word length */
450 val = hi6210_read_reg(i2s, HII2S_I2S_CFG);
451 val &= ~HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT;
452 val &= ~(HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK <<
453 HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
454 val &= ~(HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK <<
455 HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT);
456 val |= signed_data;
457 val |= (bits << HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT);
458 hi6210_write_reg(i2s, HII2S_I2S_CFG, val);
459
460
461 if (!i2s->master)
462 return 0;
463
464 /* set DAC and related units to correct rate */
465 val = hi6210_read_reg(i2s, HII2S_FS_CFG);
466 val &= ~(HII2S_FS_CFG__FS_S2_MASK << HII2S_FS_CFG__FS_S2_SHIFT);
467 val &= ~(HII2S_FS_CFG__FS_DACLR_MASK << HII2S_FS_CFG__FS_DACLR_SHIFT);
468 val &= ~(HII2S_FS_CFG__FS_ST_DL_R_MASK <<
469 HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
470 val &= ~(HII2S_FS_CFG__FS_ST_DL_L_MASK <<
471 HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
472 val |= (rate << HII2S_FS_CFG__FS_S2_SHIFT);
473 val |= (rate << HII2S_FS_CFG__FS_DACLR_SHIFT);
474 val |= (rate << HII2S_FS_CFG__FS_ST_DL_R_SHIFT);
475 val |= (rate << HII2S_FS_CFG__FS_ST_DL_L_SHIFT);
476 hi6210_write_reg(i2s, HII2S_FS_CFG, val);
477
478 return 0;
479}
480
481static int hi6210_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
482 struct snd_soc_dai *cpu_dai)
483{
484 pr_debug("%s\n", __func__);
485 switch (cmd) {
486 case SNDRV_PCM_TRIGGER_START:
487 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
488 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
489 hi6210_i2s_rxctrl(cpu_dai, 1);
490 else
491 hi6210_i2s_txctrl(cpu_dai, 1);
492 break;
493 case SNDRV_PCM_TRIGGER_STOP:
494 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
495 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
496 hi6210_i2s_rxctrl(cpu_dai, 0);
497 else
498 hi6210_i2s_txctrl(cpu_dai, 0);
499 break;
500 default:
501 dev_err(cpu_dai->dev, "uknown cmd\n");
502 return -EINVAL;
503 }
504 return 0;
505}
506
507static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai)
508{
509 struct hi6210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
510
511 snd_soc_dai_init_dma_data(dai,
512 &i2s->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
513 &i2s->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
514
515 return 0;
516}
517
518
519static struct snd_soc_dai_ops hi6210_i2s_dai_ops = {
520 .trigger = hi6210_i2s_trigger,
521 .hw_params = hi6210_i2s_hw_params,
522 .set_fmt = hi6210_i2s_set_fmt,
523 .startup = hi6210_i2s_startup,
524 .shutdown = hi6210_i2s_shutdown,
525};
526
527struct snd_soc_dai_driver hi6210_i2s_dai_init = {
528 .probe = hi6210_i2s_dai_probe,
529 .playback = {
530 .channels_min = 2,
531 .channels_max = 2,
532 .formats = SNDRV_PCM_FMTBIT_S16_LE |
533 SNDRV_PCM_FMTBIT_U16_LE,
534 .rates = SNDRV_PCM_RATE_48000,
535 },
536 .capture = {
537 .channels_min = 2,
538 .channels_max = 2,
539 .formats = SNDRV_PCM_FMTBIT_S16_LE |
540 SNDRV_PCM_FMTBIT_U16_LE,
541 .rates = SNDRV_PCM_RATE_48000,
542 },
543 .ops = &hi6210_i2s_dai_ops,
544};
545
546static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = {
547 .name = "hi6210_i2s-i2s",
548};
549
550static int hi6210_i2s_probe(struct platform_device *pdev)
551{
552 struct device_node *node = pdev->dev.of_node;
553 struct device *dev = &pdev->dev;
554 struct hi6210_i2s *i2s;
555 struct resource *res;
556 int ret;
557
558 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
559 if (!i2s)
560 return -ENOMEM;
561
562 i2s->dev = dev;
563 spin_lock_init(&i2s->lock);
564
565 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
566 i2s->base = devm_ioremap_resource(dev, res);
567 if (IS_ERR(i2s->base))
568 return PTR_ERR(i2s->base);
569
570 i2s->base_phys = (phys_addr_t)res->start;
571 i2s->dai = hi6210_i2s_dai_init;
572
573 dev_set_drvdata(&pdev->dev, i2s);
574
575 i2s->sysctrl = syscon_regmap_lookup_by_phandle(node,
576 "hisilicon,sysctrl-syscon");
577 if (IS_ERR(i2s->sysctrl))
578 return PTR_ERR(i2s->sysctrl);
579
580 i2s->clk[CLK_DACODEC] = devm_clk_get(&pdev->dev, "dacodec");
581 if (IS_ERR_OR_NULL(i2s->clk[CLK_DACODEC]))
582 return PTR_ERR(i2s->clk[CLK_DACODEC]);
583 i2s->clocks++;
584
585 i2s->clk[CLK_I2S_BASE] = devm_clk_get(&pdev->dev, "i2s-base");
586 if (IS_ERR_OR_NULL(i2s->clk[CLK_I2S_BASE]))
587 return PTR_ERR(i2s->clk[CLK_I2S_BASE]);
588 i2s->clocks++;
589
590 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
591 if (ret)
592 return ret;
593
594 ret = devm_snd_soc_register_component(&pdev->dev, &hi6210_i2s_i2s_comp,
595 &i2s->dai, 1);
596 return ret;
597}
598
599static const struct of_device_id hi6210_i2s_dt_ids[] = {
600 { .compatible = "hisilicon,hi6210-i2s" },
601 { /* sentinel */ }
602};
603
604MODULE_DEVICE_TABLE(of, hi6210_i2s_dt_ids);
605
606static struct platform_driver hi6210_i2s_driver = {
607 .probe = hi6210_i2s_probe,
608 .driver = {
609 .name = "hi6210_i2s",
610 .of_match_table = hi6210_i2s_dt_ids,
611 },
612};
613
614module_platform_driver(hi6210_i2s_driver);
615
616MODULE_DESCRIPTION("Hisilicon HI6210 I2S driver");
617MODULE_AUTHOR("Andy Green <andy.green@linaro.org>");
618MODULE_LICENSE("GPL");
diff --git a/sound/soc/hisilicon/hi6210-i2s.h b/sound/soc/hisilicon/hi6210-i2s.h
new file mode 100644
index 000000000000..85cecc4939a0
--- /dev/null
+++ b/sound/soc/hisilicon/hi6210-i2s.h
@@ -0,0 +1,276 @@
1/*
2 * linux/sound/soc/hisilicon/hi6210-i2s.h
3 *
4 * Copyright (C) 2015 Linaro, Ltd
5 * Author: Andy Green <andy.green@linaro.org>
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 as published by
9 * the Free Software Foundation, version 2 of the License.
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 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Note at least on 6220, S2 == BT, S1 == Digital FM Radio IF
20 */
21
22#ifndef _HI6210_I2S_H
23#define _HI6210_I2S_H
24
25#define HII2S_SW_RST_N 0
26
27#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_SHIFT 28
28#define HII2S_SW_RST_N__STEREO_UPLINK_WORDLEN_MASK 3
29#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_SHIFT 26
30#define HII2S_SW_RST_N__THIRDMD_UPLINK_WORDLEN_MASK 3
31#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_SHIFT 24
32#define HII2S_SW_RST_N__VOICE_UPLINK_WORDLEN_MASK 3
33#define HII2S_SW_RST_N__ST_DL_WORDLEN_SHIFT 20
34#define HII2S_SW_RST_N__ST_DL_WORDLEN_MASK 3
35#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_SHIFT 18
36#define HII2S_SW_RST_N__THIRDMD_DLINK_WORDLEN_MASK 3
37#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_SHIFT 16
38#define HII2S_SW_RST_N__VOICE_DLINK_WORDLEN_MASK 3
39
40#define HII2S_SW_RST_N__SW_RST_N BIT(0)
41
42enum hi6210_bits {
43 HII2S_BITS_16,
44 HII2S_BITS_18,
45 HII2S_BITS_20,
46 HII2S_BITS_24,
47};
48
49
50#define HII2S_IF_CLK_EN_CFG 4
51
52#define HII2S_IF_CLK_EN_CFG__THIRDMD_UPLINK_EN BIT(25)
53#define HII2S_IF_CLK_EN_CFG__THIRDMD_DLINK_EN BIT(24)
54#define HII2S_IF_CLK_EN_CFG__S3_IF_CLK_EN BIT(20)
55#define HII2S_IF_CLK_EN_CFG__S2_IF_CLK_EN BIT(16)
56#define HII2S_IF_CLK_EN_CFG__S2_OL_MIXER_EN BIT(15)
57#define HII2S_IF_CLK_EN_CFG__S2_OL_SRC_EN BIT(14)
58#define HII2S_IF_CLK_EN_CFG__S2_IR_PGA_EN BIT(13)
59#define HII2S_IF_CLK_EN_CFG__S2_IL_PGA_EN BIT(12)
60#define HII2S_IF_CLK_EN_CFG__S1_IR_PGA_EN BIT(10)
61#define HII2S_IF_CLK_EN_CFG__S1_IL_PGA_EN BIT(9)
62#define HII2S_IF_CLK_EN_CFG__S1_IF_CLK_EN BIT(8)
63#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_SRC_EN BIT(7)
64#define HII2S_IF_CLK_EN_CFG__VOICE_DLINK_EN BIT(6)
65#define HII2S_IF_CLK_EN_CFG__ST_DL_R_EN BIT(5)
66#define HII2S_IF_CLK_EN_CFG__ST_DL_L_EN BIT(4)
67#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_R_EN BIT(3)
68#define HII2S_IF_CLK_EN_CFG__VOICE_UPLINK_L_EN BIT(2)
69#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_R_EN BIT(1)
70#define HII2S_IF_CLK_EN_CFG__STEREO_UPLINK_L_EN BIT(0)
71
72#define HII2S_DIG_FILTER_CLK_EN_CFG 8
73#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_SDM_EN BIT(30)
74#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_HBF2I_EN BIT(28)
75#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_MIXER_EN BIT(25)
76#define HII2S_DIG_FILTER_CLK_EN_CFG__DACR_AGC_EN BIT(24)
77#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_SDM_EN BIT(22)
78#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_HBF2I_EN BIT(20)
79#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_MIXER_EN BIT(17)
80#define HII2S_DIG_FILTER_CLK_EN_CFG__DACL_AGC_EN BIT(16)
81
82#define HII2S_FS_CFG 0xc
83
84#define HII2S_FS_CFG__FS_S2_SHIFT 28
85#define HII2S_FS_CFG__FS_S2_MASK 7
86#define HII2S_FS_CFG__FS_S1_SHIFT 24
87#define HII2S_FS_CFG__FS_S1_MASK 7
88#define HII2S_FS_CFG__FS_ADCLR_SHIFT 20
89#define HII2S_FS_CFG__FS_ADCLR_MASK 7
90#define HII2S_FS_CFG__FS_DACLR_SHIFT 16
91#define HII2S_FS_CFG__FS_DACLR_MASK 7
92#define HII2S_FS_CFG__FS_ST_DL_R_SHIFT 8
93#define HII2S_FS_CFG__FS_ST_DL_R_MASK 7
94#define HII2S_FS_CFG__FS_ST_DL_L_SHIFT 4
95#define HII2S_FS_CFG__FS_ST_DL_L_MASK 7
96#define HII2S_FS_CFG__FS_VOICE_DLINK_SHIFT 0
97#define HII2S_FS_CFG__FS_VOICE_DLINK_MASK 7
98
99enum hi6210_i2s_rates {
100 HII2S_FS_RATE_8KHZ = 0,
101 HII2S_FS_RATE_16KHZ = 1,
102 HII2S_FS_RATE_32KHZ = 2,
103 HII2S_FS_RATE_48KHZ = 4,
104 HII2S_FS_RATE_96KHZ = 5,
105 HII2S_FS_RATE_192KHZ = 6,
106};
107
108#define HII2S_I2S_CFG 0x10
109
110#define HII2S_I2S_CFG__S2_IF_TX_EN BIT(31)
111#define HII2S_I2S_CFG__S2_IF_RX_EN BIT(30)
112#define HII2S_I2S_CFG__S2_FRAME_MODE BIT(29)
113#define HII2S_I2S_CFG__S2_MST_SLV BIT(28)
114#define HII2S_I2S_CFG__S2_LRCK_MODE BIT(27)
115#define HII2S_I2S_CFG__S2_CHNNL_MODE BIT(26)
116#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_SHIFT 24
117#define HII2S_I2S_CFG__S2_CODEC_IO_WORDLENGTH_MASK 3
118#define HII2S_I2S_CFG__S2_DIRECT_LOOP_SHIFT 22
119#define HII2S_I2S_CFG__S2_DIRECT_LOOP_MASK 3
120#define HII2S_I2S_CFG__S2_TX_CLK_SEL BIT(21)
121#define HII2S_I2S_CFG__S2_RX_CLK_SEL BIT(20)
122#define HII2S_I2S_CFG__S2_CODEC_DATA_FORMAT BIT(19)
123#define HII2S_I2S_CFG__S2_FUNC_MODE_SHIFT 16
124#define HII2S_I2S_CFG__S2_FUNC_MODE_MASK 7
125#define HII2S_I2S_CFG__S1_IF_TX_EN BIT(15)
126#define HII2S_I2S_CFG__S1_IF_RX_EN BIT(14)
127#define HII2S_I2S_CFG__S1_FRAME_MODE BIT(13)
128#define HII2S_I2S_CFG__S1_MST_SLV BIT(12)
129#define HII2S_I2S_CFG__S1_LRCK_MODE BIT(11)
130#define HII2S_I2S_CFG__S1_CHNNL_MODE BIT(10)
131#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_SHIFT 8
132#define HII2S_I2S_CFG__S1_CODEC_IO_WORDLENGTH_MASK 3
133#define HII2S_I2S_CFG__S1_DIRECT_LOOP_SHIFT 6
134#define HII2S_I2S_CFG__S1_DIRECT_LOOP_MASK 3
135#define HII2S_I2S_CFG__S1_TX_CLK_SEL BIT(5)
136#define HII2S_I2S_CFG__S1_RX_CLK_SEL BIT(4)
137#define HII2S_I2S_CFG__S1_CODEC_DATA_FORMAT BIT(3)
138#define HII2S_I2S_CFG__S1_FUNC_MODE_SHIFT 0
139#define HII2S_I2S_CFG__S1_FUNC_MODE_MASK 7
140
141enum hi6210_i2s_formats {
142 HII2S_FORMAT_I2S,
143 HII2S_FORMAT_PCM_STD,
144 HII2S_FORMAT_PCM_USER,
145 HII2S_FORMAT_LEFT_JUST,
146 HII2S_FORMAT_RIGHT_JUST,
147};
148
149#define HII2S_DIG_FILTER_MODULE_CFG 0x14
150
151#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_SHIFT 28
152#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_GAIN_MASK 3
153#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN4_MUTE BIT(27)
154#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN3_MUTE BIT(26)
155#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN2_MUTE BIT(25)
156#define HII2S_DIG_FILTER_MODULE_CFG__DACR_MIXER_IN1_MUTE BIT(24)
157#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_SHIFT 20
158#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_GAIN_MASK 3
159#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN4_MUTE BIT(19)
160#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN3_MUTE BIT(18)
161#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN2_MUTE BIT(17)
162#define HII2S_DIG_FILTER_MODULE_CFG__DACL_MIXER_IN1_MUTE BIT(16)
163#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACR_SDM_DITHER BIT(9)
164#define HII2S_DIG_FILTER_MODULE_CFG__SW_DACL_SDM_DITHER BIT(8)
165#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_SHIFT 4
166#define HII2S_DIG_FILTER_MODULE_CFG__LM_CODEC_DAC2ADC_MASK 7
167#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_SHIFT 0
168#define HII2S_DIG_FILTER_MODULE_CFG__RM_CODEC_DAC2ADC_MASK 7
169
170enum hi6210_gains {
171 HII2S_GAIN_100PC,
172 HII2S_GAIN_50PC,
173 HII2S_GAIN_25PC,
174};
175
176#define HII2S_MUX_TOP_MODULE_CFG 0x18
177
178#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_SHIFT 14
179#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_GAIN_MASK 3
180#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN2_MUTE BIT(13)
181#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_MIXER_IN1_MUTE BIT(12)
182#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_SHIFT 10
183#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_GAIN_MASK 3
184#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN2_MUTE BIT(9)
185#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_MIXER_IN1_MUTE BIT(8)
186#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_RDY BIT(6)
187#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_SHIFT 4
188#define HII2S_MUX_TOP_MODULE_CFG__S2_OL_SRC_MODE_MASK 3
189#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_RDY BIT(3)
190#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_SHIFT 0
191#define HII2S_MUX_TOP_MODULE_CFG__VOICE_DLINK_SRC_MODE_MASK 7
192
193enum hi6210_s2_src_mode {
194 HII2S_S2_SRC_MODE_3,
195 HII2S_S2_SRC_MODE_12,
196 HII2S_S2_SRC_MODE_6,
197 HII2S_S2_SRC_MODE_2,
198};
199
200enum hi6210_voice_dlink_src_mode {
201 HII2S_VOICE_DL_SRC_MODE_12 = 1,
202 HII2S_VOICE_DL_SRC_MODE_6,
203 HII2S_VOICE_DL_SRC_MODE_2,
204 HII2S_VOICE_DL_SRC_MODE_3,
205};
206
207#define HII2S_ADC_PGA_CFG 0x1c
208#define HII2S_S1_INPUT_PGA_CFG 0x20
209#define HII2S_S2_INPUT_PGA_CFG 0x24
210#define HII2S_ST_DL_PGA_CFG 0x28
211#define HII2S_VOICE_SIDETONE_DLINK_PGA_CFG 0x2c
212#define HII2S_APB_AFIFO_CFG_1 0x30
213#define HII2S_APB_AFIFO_CFG_2 0x34
214#define HII2S_ST_DL_FIFO_TH_CFG 0x38
215
216#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_SHIFT 24
217#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AEMPTY_MASK 0x1f
218#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_SHIFT 16
219#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_R_AFULL_MASK 0x1f
220#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_SHIFT 8
221#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AEMPTY_MASK 0x1f
222#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_SHIFT 0
223#define HII2S_ST_DL_FIFO_TH_CFG__ST_DL_L_AFULL_MASK 0x1f
224
225#define HII2S_STEREO_UPLINK_FIFO_TH_CFG 0x3c
226#define HII2S_VOICE_UPLINK_FIFO_TH_CFG 0x40
227#define HII2S_CODEC_IRQ_MASK 0x44
228#define HII2S_CODEC_IRQ 0x48
229#define HII2S_DACL_AGC_CFG_1 0x4c
230#define HII2S_DACL_AGC_CFG_2 0x50
231#define HII2S_DACR_AGC_CFG_1 0x54
232#define HII2S_DACR_AGC_CFG_2 0x58
233#define HII2S_DMIC_SIF_CFG 0x5c
234#define HII2S_MISC_CFG 0x60
235
236#define HII2S_MISC_CFG__THIRDMD_DLINK_TEST_SEL BIT(17)
237#define HII2S_MISC_CFG__THIRDMD_DLINK_DIN_SEL BIT(16)
238#define HII2S_MISC_CFG__S3_DOUT_RIGHT_SEL BIT(14)
239#define HII2S_MISC_CFG__S3_DOUT_LEFT_SEL BIT(13)
240#define HII2S_MISC_CFG__S3_DIN_TEST_SEL BIT(12)
241#define HII2S_MISC_CFG__VOICE_DLINK_SRC_UP_DOUT_VLD_SEL BIT(8)
242#define HII2S_MISC_CFG__VOICE_DLINK_TEST_SEL BIT(7)
243#define HII2S_MISC_CFG__VOICE_DLINK_DIN_SEL BIT(6)
244#define HII2S_MISC_CFG__ST_DL_TEST_SEL BIT(4)
245#define HII2S_MISC_CFG__S2_DOUT_RIGHT_SEL BIT(3)
246#define HII2S_MISC_CFG__S2_DOUT_TEST_SEL BIT(2)
247#define HII2S_MISC_CFG__S1_DOUT_TEST_SEL BIT(1)
248#define HII2S_MISC_CFG__S2_DOUT_LEFT_SEL BIT(0)
249
250#define HII2S_S2_SRC_CFG 0x64
251#define HII2S_MEM_CFG 0x68
252#define HII2S_THIRDMD_PCM_PGA_CFG 0x6c
253#define HII2S_THIRD_MODEM_FIFO_TH 0x70
254#define HII2S_S3_ANTI_FREQ_JITTER_TX_INC_CNT 0x74
255#define HII2S_S3_ANTI_FREQ_JITTER_TX_DEC_CNT 0x78
256#define HII2S_S3_ANTI_FREQ_JITTER_RX_INC_CNT 0x7c
257#define HII2S_S3_ANTI_FREQ_JITTER_RX_DEC_CNT 0x80
258#define HII2S_ANTI_FREQ_JITTER_EN 0x84
259#define HII2S_CLK_SEL 0x88
260
261/* 0 = BT owns the i2s */
262#define HII2S_CLK_SEL__I2S_BT_FM_SEL BIT(0)
263/* 0 = internal source, 1 = ext */
264#define HII2S_CLK_SEL__EXT_12_288MHZ_SEL BIT(1)
265
266
267#define HII2S_THIRDMD_DLINK_CHANNEL 0xe8
268#define HII2S_THIRDMD_ULINK_CHANNEL 0xec
269#define HII2S_VOICE_DLINK_CHANNEL 0xf0
270
271/* shovel data in here for playback */
272#define HII2S_ST_DL_CHANNEL 0xf4
273#define HII2S_STEREO_UPLINK_CHANNEL 0xf8
274#define HII2S_VOICE_UPLINK_CHANNEL 0xfc
275
276#endif/* _HI6210_I2S_H */
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 526855ad479e..67968ef3bbda 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -202,6 +202,30 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
202 platforms with MAX98090 audio codec it also can support TI jack chip as aux device. 202 platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
203 If unsure select "N". 203 If unsure select "N".
204 204
205config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
206 tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
207 depends on X86_INTEL_LPSS && I2C && ACPI
208 select SND_SOC_DA7213
209 select SND_SST_ATOM_HIFI2_PLATFORM
210 select SND_SST_IPC_ACPI
211 select SND_SOC_INTEL_SST_MATCH if ACPI
212 help
213 This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
214 platforms with DA7212/7213 audio codec.
215 If unsure select "N".
216
217config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
218 tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
219 depends on X86_INTEL_LPSS && I2C && ACPI
220 select SND_SST_ATOM_HIFI2_PLATFORM
221 select SND_SST_IPC_ACPI
222 select SND_SOC_INTEL_SST_MATCH if ACPI
223 help
224 This adds support for ASoC machine driver for the MinnowBoard Max or
225 Up boards and provides access to I2S signals on the Low-Speed
226 connector
227 If unsure select "N".
228
205config SND_SOC_INTEL_SKYLAKE 229config SND_SOC_INTEL_SKYLAKE
206 tristate 230 tristate
207 select SND_HDA_EXT_CORE 231 select SND_HDA_EXT_CORE
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 747c0f393d2d..dd250b8b26f2 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -420,7 +420,21 @@ static const struct dmi_system_id byt_table[] = {
420 .callback = byt_thinkpad10_quirk_cb, 420 .callback = byt_thinkpad10_quirk_cb,
421 .matches = { 421 .matches = {
422 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 422 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
423 DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), 423 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
424 },
425 },
426 {
427 .callback = byt_thinkpad10_quirk_cb,
428 .matches = {
429 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
430 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
431 },
432 },
433 {
434 .callback = byt_thinkpad10_quirk_cb,
435 .matches = {
436 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
437 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
424 }, 438 },
425 }, 439 },
426 { } 440 { }
@@ -480,12 +494,23 @@ static struct sst_acpi_mach sst_acpi_bytcr[] = {
480 &byt_rvp_platform_data }, 494 &byt_rvp_platform_data },
481 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_0f28.bin", "bytcr_rt5651", NULL, 495 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_0f28.bin", "bytcr_rt5651", NULL,
482 &byt_rvp_platform_data }, 496 &byt_rvp_platform_data },
497 {"DLGS7212", "bytcht_da7213", "intel/fw_sst_0f28.bin", "bytcht_da7213", NULL,
498 &byt_rvp_platform_data },
499 {"DLGS7213", "bytcht_da7213", "intel/fw_sst_0f28.bin", "bytcht_da7213", NULL,
500 &byt_rvp_platform_data },
483 /* some Baytrail platforms rely on RT5645, use CHT machine driver */ 501 /* some Baytrail platforms rely on RT5645, use CHT machine driver */
484 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, 502 {"10EC5645", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL,
485 &byt_rvp_platform_data }, 503 &byt_rvp_platform_data },
486 {"10EC5648", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, 504 {"10EC5648", "cht-bsw-rt5645", "intel/fw_sst_0f28.bin", "cht-bsw", NULL,
487 &byt_rvp_platform_data }, 505 &byt_rvp_platform_data },
488 506#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
507 /*
508 * This is always last in the table so that it is selected only when
509 * enabled explicitly and there is no codec-related information in SSDT
510 */
511 {"80860F28", "bytcht_nocodec", "intel/fw_sst_0f28.bin", "bytcht_nocodec", NULL,
512 &byt_rvp_platform_data },
513#endif
489 {}, 514 {},
490}; 515};
491 516
@@ -504,6 +529,10 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
504 529
505 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, 530 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
506 &chv_platform_data }, 531 &chv_platform_data },
532 {"DLGS7212", "bytcht_da7213", "intel/fw_sst_22a8.bin", "bytcht_da7213", NULL,
533 &chv_platform_data },
534 {"DLGS7213", "bytcht_da7213", "intel/fw_sst_22a8.bin", "bytcht_da7213", NULL,
535 &chv_platform_data },
507 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */ 536 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
508 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", cht_quirk, 537 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", cht_quirk,
509 &chv_platform_data }, 538 &chv_platform_data },
@@ -512,6 +541,14 @@ static struct sst_acpi_mach sst_acpi_chv[] = {
512 /* some CHT-T platforms rely on RT5651, use Baytrail machine driver */ 541 /* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
513 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_22a8.bin", "bytcr_rt5651", NULL, 542 {"10EC5651", "bytcr_rt5651", "intel/fw_sst_22a8.bin", "bytcr_rt5651", NULL,
514 &chv_platform_data }, 543 &chv_platform_data },
544#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
545 /*
546 * This is always last in the table so that it is selected only when
547 * enabled explicitly and there is no codec-related information in SSDT
548 */
549 {"808622A8", "bytcht_nocodec", "intel/fw_sst_22a8.bin", "bytcht_nocodec", NULL,
550 &chv_platform_data },
551#endif
515 {}, 552 {},
516}; 553};
517 554
diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index 14c2d9d18180..20b01e02ed8f 100644
--- a/sound/soc/intel/atom/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -236,7 +236,9 @@ static void process_fw_init(struct intel_sst_drv *sst_drv_ctx,
236 retval = init->result; 236 retval = init->result;
237 goto ret; 237 goto ret;
238 } 238 }
239 dev_info(sst_drv_ctx->dev, "FW Version %02x.%02x.%02x.%02x\n", 239 if (memcmp(&sst_drv_ctx->fw_version, &init->fw_version,
240 sizeof(init->fw_version)))
241 dev_info(sst_drv_ctx->dev, "FW Version %02x.%02x.%02x.%02x\n",
240 init->fw_version.type, init->fw_version.major, 242 init->fw_version.type, init->fw_version.major,
241 init->fw_version.minor, init->fw_version.build); 243 init->fw_version.minor, init->fw_version.build);
242 dev_dbg(sst_drv_ctx->dev, "Build date %s Time %s\n", 244 dev_dbg(sst_drv_ctx->dev, "Build date %s Time %s\n",
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 5639f10774e6..56896e09445d 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -10,6 +10,8 @@ snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
10snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 10snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
11snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 11snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
12snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 12snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
13snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
14snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
13snd-soc-skl_rt286-objs := skl_rt286.o 15snd-soc-skl_rt286-objs := skl_rt286.o
14snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o 16snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
15snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o 17snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o
@@ -26,6 +28,8 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
26obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 28obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
27obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 29obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
28obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 30obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
31obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
32obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
29obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o 33obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
30obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o 34obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
31obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o 35obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c
index 53c6b4cbb1e1..14d9693c1641 100644
--- a/sound/soc/intel/boards/bdw-rt5677.c
+++ b/sound/soc/intel/boards/bdw-rt5677.c
@@ -193,13 +193,12 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
193 RT5677_CLK_SEL_I2S1_ASRC); 193 RT5677_CLK_SEL_I2S1_ASRC);
194 194
195 /* Request rt5677 GPIO for headphone amp control */ 195 /* Request rt5677 GPIO for headphone amp control */
196 bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev, 196 bdw_rt5677->gpio_hp_en = devm_gpiod_get(codec->dev, "headphone-enable",
197 "headphone-enable", 0, 0); 197 GPIOD_OUT_LOW);
198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) { 198 if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n"); 199 dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
200 return PTR_ERR(bdw_rt5677->gpio_hp_en); 200 return PTR_ERR(bdw_rt5677->gpio_hp_en);
201 } 201 }
202 gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);
203 202
204 /* Create and initialize headphone jack */ 203 /* Create and initialize headphone jack */
205 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack", 204 if (!snd_soc_card_jack_new(rtd->card, "Headphone Jack",
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index faf865bb1765..6dcbbcefc25b 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -269,9 +269,6 @@ static struct snd_soc_card broadwell_rt286 = {
269static int broadwell_audio_probe(struct platform_device *pdev) 269static int broadwell_audio_probe(struct platform_device *pdev)
270{ 270{
271 broadwell_rt286.dev = &pdev->dev; 271 broadwell_rt286.dev = &pdev->dev;
272
273 snd_soc_set_dmi_name(&broadwell_rt286, NULL);
274
275 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286); 272 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286);
276} 273}
277 274
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 2cda06cde4d1..3a8c4d954a91 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -55,6 +55,54 @@ enum {
55 BXT_DPCM_AUDIO_HDMI3_PB, 55 BXT_DPCM_AUDIO_HDMI3_PB,
56}; 56};
57 57
58static inline struct snd_soc_dai *bxt_get_codec_dai(struct snd_soc_card *card)
59{
60 struct snd_soc_pcm_runtime *rtd;
61
62 list_for_each_entry(rtd, &card->rtd_list, list) {
63
64 if (!strncmp(rtd->codec_dai->name, BXT_DIALOG_CODEC_DAI,
65 strlen(BXT_DIALOG_CODEC_DAI)))
66 return rtd->codec_dai;
67 }
68
69 return NULL;
70}
71
72static int platform_clock_control(struct snd_soc_dapm_widget *w,
73 struct snd_kcontrol *k, int event)
74{
75 int ret = 0;
76 struct snd_soc_dapm_context *dapm = w->dapm;
77 struct snd_soc_card *card = dapm->card;
78 struct snd_soc_dai *codec_dai;
79
80 codec_dai = bxt_get_codec_dai(card);
81 if (!codec_dai) {
82 dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
83 return -EIO;
84 }
85
86 if (SND_SOC_DAPM_EVENT_OFF(event)) {
87 ret = snd_soc_dai_set_pll(codec_dai, 0,
88 DA7219_SYSCLK_MCLK, 0, 0);
89 if (ret)
90 dev_err(card->dev, "failed to stop PLL: %d\n", ret);
91 } else if(SND_SOC_DAPM_EVENT_ON(event)) {
92 ret = snd_soc_dai_set_sysclk(codec_dai,
93 DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN);
94 if (ret)
95 dev_err(card->dev, "can't set codec sysclk configuration\n");
96
97 ret = snd_soc_dai_set_pll(codec_dai, 0,
98 DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
99 if (ret)
100 dev_err(card->dev, "failed to start PLL: %d\n", ret);
101 }
102
103 return ret;
104}
105
58static const struct snd_kcontrol_new broxton_controls[] = { 106static const struct snd_kcontrol_new broxton_controls[] = {
59 SOC_DAPM_PIN_SWITCH("Headphone Jack"), 107 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
60 SOC_DAPM_PIN_SWITCH("Headset Mic"), 108 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -69,6 +117,8 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = {
69 SND_SOC_DAPM_SPK("HDMI1", NULL), 117 SND_SOC_DAPM_SPK("HDMI1", NULL),
70 SND_SOC_DAPM_SPK("HDMI2", NULL), 118 SND_SOC_DAPM_SPK("HDMI2", NULL),
71 SND_SOC_DAPM_SPK("HDMI3", NULL), 119 SND_SOC_DAPM_SPK("HDMI3", NULL),
120 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
121 platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
72}; 122};
73 123
74static const struct snd_soc_dapm_route broxton_map[] = { 124static const struct snd_soc_dapm_route broxton_map[] = {
@@ -109,6 +159,9 @@ static const struct snd_soc_dapm_route broxton_map[] = {
109 /* DMIC */ 159 /* DMIC */
110 {"dmic01_hifi", NULL, "DMIC01 Rx"}, 160 {"dmic01_hifi", NULL, "DMIC01 Rx"},
111 {"DMIC01 Rx", NULL, "DMIC AIF"}, 161 {"DMIC01 Rx", NULL, "DMIC AIF"},
162
163 { "Headphone Jack", NULL, "Platform Clock" },
164 { "Headset Mic", NULL, "Platform Clock" },
112}; 165};
113 166
114static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, 167static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
@@ -243,49 +296,6 @@ static const struct snd_soc_ops broxton_da7219_fe_ops = {
243 .startup = bxt_fe_startup, 296 .startup = bxt_fe_startup,
244}; 297};
245 298
246static int broxton_da7219_hw_params(struct snd_pcm_substream *substream,
247 struct snd_pcm_hw_params *params)
248{
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250 struct snd_soc_dai *codec_dai = rtd->codec_dai;
251 int ret;
252
253 ret = snd_soc_dai_set_sysclk(codec_dai,
254 DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN);
255 if (ret < 0)
256 dev_err(codec_dai->dev, "can't set codec sysclk configuration\n");
257
258 ret = snd_soc_dai_set_pll(codec_dai, 0,
259 DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304);
260 if (ret < 0) {
261 dev_err(codec_dai->dev, "failed to start PLL: %d\n", ret);
262 return -EIO;
263 }
264
265 return ret;
266}
267
268static int broxton_da7219_hw_free(struct snd_pcm_substream *substream)
269{
270 struct snd_soc_pcm_runtime *rtd = substream->private_data;
271 struct snd_soc_dai *codec_dai = rtd->codec_dai;
272 int ret;
273
274 ret = snd_soc_dai_set_pll(codec_dai, 0,
275 DA7219_SYSCLK_MCLK, 0, 0);
276 if (ret < 0) {
277 dev_err(codec_dai->dev, "failed to stop PLL: %d\n", ret);
278 return -EIO;
279 }
280
281 return ret;
282}
283
284static const struct snd_soc_ops broxton_da7219_ops = {
285 .hw_params = broxton_da7219_hw_params,
286 .hw_free = broxton_da7219_hw_free,
287};
288
289static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, 299static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
290 struct snd_pcm_hw_params *params) 300 struct snd_pcm_hw_params *params)
291{ 301{
@@ -467,7 +477,6 @@ static struct snd_soc_dai_link broxton_dais[] = {
467 SND_SOC_DAIFMT_CBS_CFS, 477 SND_SOC_DAIFMT_CBS_CFS,
468 .ignore_pmdown_time = 1, 478 .ignore_pmdown_time = 1,
469 .be_hw_params_fixup = broxton_ssp_fixup, 479 .be_hw_params_fixup = broxton_ssp_fixup,
470 .ops = &broxton_da7219_ops,
471 .dpcm_playback = 1, 480 .dpcm_playback = 1,
472 .dpcm_capture = 1, 481 .dpcm_capture = 1,
473 }, 482 },
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index 176c080a9818..1a68d043c803 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -274,12 +274,15 @@ static int bxt_fe_startup(struct snd_pcm_substream *substream)
274 * on this platform for PCM device we support: 274 * on this platform for PCM device we support:
275 * 48Khz 275 * 48Khz
276 * stereo 276 * stereo
277 * 16-bit audio
277 */ 278 */
278 279
279 runtime->hw.channels_max = 2; 280 runtime->hw.channels_max = 2;
280 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 281 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
281 &constraints_channels); 282 &constraints_channels);
282 283
284 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
285 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
283 snd_pcm_hw_constraint_list(runtime, 0, 286 snd_pcm_hw_constraint_list(runtime, 0,
284 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); 287 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
285 288
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c
new file mode 100644
index 000000000000..18873e23f404
--- /dev/null
+++ b/sound/soc/intel/boards/bytcht_da7213.c
@@ -0,0 +1,283 @@
1/*
2 * bytcht-da7213.c - ASoc Machine driver for Intel Baytrail and
3 * Cherrytrail-based platforms, with Dialog DA7213 codec
4 *
5 * Copyright (C) 2017 Intel Corporation
6 * Author: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21
22#include <linux/module.h>
23#include <linux/acpi.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <asm/platform_sst_audio.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include "../../codecs/da7213.h"
31#include "../atom/sst-atom-controls.h"
32#include "../common/sst-acpi.h"
33
34static const struct snd_kcontrol_new controls[] = {
35 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
36 SOC_DAPM_PIN_SWITCH("Headset Mic"),
37 SOC_DAPM_PIN_SWITCH("Mic"),
38 SOC_DAPM_PIN_SWITCH("Aux In"),
39};
40
41static const struct snd_soc_dapm_widget dapm_widgets[] = {
42 SND_SOC_DAPM_HP("Headphone Jack", NULL),
43 SND_SOC_DAPM_MIC("Headset Mic", NULL),
44 SND_SOC_DAPM_MIC("Mic", NULL),
45 SND_SOC_DAPM_LINE("Aux In", NULL),
46};
47
48static const struct snd_soc_dapm_route audio_map[] = {
49 {"Headphone Jack", NULL, "HPL"},
50 {"Headphone Jack", NULL, "HPR"},
51
52 {"AUXL", NULL, "Aux In"},
53 {"AUXR", NULL, "Aux In"},
54
55 /* Assume Mic1 is linked to Headset and Mic2 to on-board mic */
56 {"MIC1", NULL, "Headset Mic"},
57 {"MIC2", NULL, "Mic"},
58
59 /* SOC-codec link */
60 {"ssp2 Tx", NULL, "codec_out0"},
61 {"ssp2 Tx", NULL, "codec_out1"},
62 {"codec_in0", NULL, "ssp2 Rx"},
63 {"codec_in1", NULL, "ssp2 Rx"},
64
65 {"Playback", NULL, "ssp2 Tx"},
66 {"ssp2 Rx", NULL, "Capture"},
67};
68
69static int codec_fixup(struct snd_soc_pcm_runtime *rtd,
70 struct snd_pcm_hw_params *params)
71{
72 int ret;
73 struct snd_interval *rate = hw_param_interval(params,
74 SNDRV_PCM_HW_PARAM_RATE);
75 struct snd_interval *channels = hw_param_interval(params,
76 SNDRV_PCM_HW_PARAM_CHANNELS);
77
78 /* The DSP will convert the FE rate to 48k, stereo, 24bits */
79 rate->min = rate->max = 48000;
80 channels->min = channels->max = 2;
81
82 /* set SSP2 to 24-bit */
83 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
84
85 /*
86 * Default mode for SSP configuration is TDM 4 slot, override config
87 * with explicit setting to I2S 2ch 24-bit. The word length is set with
88 * dai_set_tdm_slot() since there is no other API exposed
89 */
90 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
91 SND_SOC_DAIFMT_I2S |
92 SND_SOC_DAIFMT_NB_NF |
93 SND_SOC_DAIFMT_CBS_CFS);
94 if (ret < 0) {
95 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
96 return ret;
97 }
98
99 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
100 if (ret < 0) {
101 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
102 return ret;
103 }
104
105 return 0;
106}
107
108static int aif1_startup(struct snd_pcm_substream *substream)
109{
110 return snd_pcm_hw_constraint_single(substream->runtime,
111 SNDRV_PCM_HW_PARAM_RATE, 48000);
112}
113
114static int aif1_hw_params(struct snd_pcm_substream *substream,
115 struct snd_pcm_hw_params *params)
116{
117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
118 struct snd_soc_dai *codec_dai = rtd->codec_dai;
119 int ret;
120
121 ret = snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK,
122 19200000, SND_SOC_CLOCK_IN);
123 if (ret < 0)
124 dev_err(codec_dai->dev, "can't set codec sysclk configuration\n");
125
126 ret = snd_soc_dai_set_pll(codec_dai, 0,
127 DA7213_SYSCLK_PLL_SRM, 0, DA7213_PLL_FREQ_OUT_98304000);
128 if (ret < 0) {
129 dev_err(codec_dai->dev, "failed to start PLL: %d\n", ret);
130 return -EIO;
131 }
132
133 return ret;
134}
135
136static int aif1_hw_free(struct snd_pcm_substream *substream)
137{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct snd_soc_dai *codec_dai = rtd->codec_dai;
140 int ret;
141
142 ret = snd_soc_dai_set_pll(codec_dai, 0,
143 DA7213_SYSCLK_MCLK, 0, 0);
144 if (ret < 0) {
145 dev_err(codec_dai->dev, "failed to stop PLL: %d\n", ret);
146 return -EIO;
147 }
148
149 return ret;
150}
151
152static const struct snd_soc_ops aif1_ops = {
153 .startup = aif1_startup,
154};
155
156static const struct snd_soc_ops ssp2_ops = {
157 .hw_params = aif1_hw_params,
158 .hw_free = aif1_hw_free,
159
160};
161
162static struct snd_soc_dai_link dailink[] = {
163 [MERR_DPCM_AUDIO] = {
164 .name = "Audio Port",
165 .stream_name = "Audio",
166 .cpu_dai_name = "media-cpu-dai",
167 .codec_dai_name = "snd-soc-dummy-dai",
168 .codec_name = "snd-soc-dummy",
169 .platform_name = "sst-mfld-platform",
170 .nonatomic = true,
171 .dynamic = 1,
172 .dpcm_playback = 1,
173 .dpcm_capture = 1,
174 .ops = &aif1_ops,
175 },
176 [MERR_DPCM_DEEP_BUFFER] = {
177 .name = "Deep-Buffer Audio Port",
178 .stream_name = "Deep-Buffer Audio",
179 .cpu_dai_name = "deepbuffer-cpu-dai",
180 .codec_dai_name = "snd-soc-dummy-dai",
181 .codec_name = "snd-soc-dummy",
182 .platform_name = "sst-mfld-platform",
183 .nonatomic = true,
184 .dynamic = 1,
185 .dpcm_playback = 1,
186 .ops = &aif1_ops,
187 },
188 [MERR_DPCM_COMPR] = {
189 .name = "Compressed Port",
190 .stream_name = "Compress",
191 .cpu_dai_name = "compress-cpu-dai",
192 .codec_dai_name = "snd-soc-dummy-dai",
193 .codec_name = "snd-soc-dummy",
194 .platform_name = "sst-mfld-platform",
195 },
196 /* CODEC<->CODEC link */
197 /* back ends */
198 {
199 .name = "SSP2-Codec",
200 .id = 1,
201 .cpu_dai_name = "ssp2-port",
202 .platform_name = "sst-mfld-platform",
203 .no_pcm = 1,
204 .codec_dai_name = "da7213-hifi",
205 .codec_name = "i2c-DLGS7213:00",
206 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
207 | SND_SOC_DAIFMT_CBS_CFS,
208 .be_hw_params_fixup = codec_fixup,
209 .nonatomic = true,
210 .dpcm_playback = 1,
211 .dpcm_capture = 1,
212 .ops = &ssp2_ops,
213 },
214};
215
216/* SoC card */
217static struct snd_soc_card bytcht_da7213_card = {
218 .name = "bytcht-da7213",
219 .owner = THIS_MODULE,
220 .dai_link = dailink,
221 .num_links = ARRAY_SIZE(dailink),
222 .controls = controls,
223 .num_controls = ARRAY_SIZE(controls),
224 .dapm_widgets = dapm_widgets,
225 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
226 .dapm_routes = audio_map,
227 .num_dapm_routes = ARRAY_SIZE(audio_map),
228};
229
230static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
231
232static int bytcht_da7213_probe(struct platform_device *pdev)
233{
234 int ret_val = 0;
235 int i;
236 struct snd_soc_card *card;
237 struct sst_acpi_mach *mach;
238 const char *i2c_name = NULL;
239 int dai_index = 0;
240
241 mach = (&pdev->dev)->platform_data;
242 card = &bytcht_da7213_card;
243 card->dev = &pdev->dev;
244
245 /* fix index of codec dai */
246 dai_index = MERR_DPCM_COMPR + 1;
247 for (i = 0; i < ARRAY_SIZE(dailink); i++) {
248 if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) {
249 dai_index = i;
250 break;
251 }
252 }
253
254 /* fixup codec name based on HID */
255 i2c_name = sst_acpi_find_name_from_hid(mach->id);
256 if (i2c_name != NULL) {
257 snprintf(codec_name, sizeof(codec_name),
258 "%s%s", "i2c-", i2c_name);
259 dailink[dai_index].codec_name = codec_name;
260 }
261
262 ret_val = devm_snd_soc_register_card(&pdev->dev, card);
263 if (ret_val) {
264 dev_err(&pdev->dev,
265 "snd_soc_register_card failed %d\n", ret_val);
266 return ret_val;
267 }
268 platform_set_drvdata(pdev, card);
269 return ret_val;
270}
271
272static struct platform_driver bytcht_da7213_driver = {
273 .driver = {
274 .name = "bytcht_da7213",
275 },
276 .probe = bytcht_da7213_probe,
277};
278module_platform_driver(bytcht_da7213_driver);
279
280MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail+DA7213 Machine driver");
281MODULE_AUTHOR("Pierre-Louis Bossart");
282MODULE_LICENSE("GPL v2");
283MODULE_ALIAS("platform:bytcht_da7213");
diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c
new file mode 100644
index 000000000000..89853eeaaf9d
--- /dev/null
+++ b/sound/soc/intel/boards/bytcht_nocodec.c
@@ -0,0 +1,208 @@
1/*
2 * bytcht_nocodec.c - ASoc Machine driver for MinnowBoard Max and Up
3 * to make I2S signals observable on the Low-Speed connector. Audio codec
4 * is not managed by ASoC/DAPM
5 *
6 * Copyright (C) 2015-2017 Intel Corp
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21
22#include <linux/module.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include "../atom/sst-atom-controls.h"
27
28static const struct snd_soc_dapm_widget widgets[] = {
29 SND_SOC_DAPM_MIC("Mic", NULL),
30 SND_SOC_DAPM_SPK("Speaker", NULL),
31};
32
33static const struct snd_kcontrol_new controls[] = {
34 SOC_DAPM_PIN_SWITCH("Mic"),
35 SOC_DAPM_PIN_SWITCH("Speaker"),
36};
37
38static const struct snd_soc_dapm_route audio_map[] = {
39 {"ssp2 Tx", NULL, "codec_out0"},
40 {"ssp2 Tx", NULL, "codec_out1"},
41 {"codec_in0", NULL, "ssp2 Rx"},
42 {"codec_in1", NULL, "ssp2 Rx"},
43
44 {"ssp2 Rx", NULL, "Mic"},
45 {"Speaker", NULL, "ssp2 Tx"},
46};
47
48static int codec_fixup(struct snd_soc_pcm_runtime *rtd,
49 struct snd_pcm_hw_params *params)
50{
51 struct snd_interval *rate = hw_param_interval(params,
52 SNDRV_PCM_HW_PARAM_RATE);
53 struct snd_interval *channels = hw_param_interval(params,
54 SNDRV_PCM_HW_PARAM_CHANNELS);
55 int ret;
56
57 /* The DSP will convert the FE rate to 48k, stereo, 24bits */
58 rate->min = rate->max = 48000;
59 channels->min = channels->max = 2;
60
61 /* set SSP2 to 24-bit */
62 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
63
64 /*
65 * Default mode for SSP configuration is TDM 4 slot, override config
66 * with explicit setting to I2S 2ch 24-bit. The word length is set with
67 * dai_set_tdm_slot() since there is no other API exposed
68 */
69 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
70 SND_SOC_DAIFMT_I2S |
71 SND_SOC_DAIFMT_NB_NF |
72 SND_SOC_DAIFMT_CBS_CFS);
73
74 if (ret < 0) {
75 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
76 return ret;
77 }
78
79 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
80 if (ret < 0) {
81 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
82 return ret;
83 }
84
85 return 0;
86}
87
88static unsigned int rates_48000[] = {
89 48000,
90};
91
92static struct snd_pcm_hw_constraint_list constraints_48000 = {
93 .count = ARRAY_SIZE(rates_48000),
94 .list = rates_48000,
95};
96
97static int aif1_startup(struct snd_pcm_substream *substream)
98{
99 return snd_pcm_hw_constraint_list(substream->runtime, 0,
100 SNDRV_PCM_HW_PARAM_RATE,
101 &constraints_48000);
102}
103
104static struct snd_soc_ops aif1_ops = {
105 .startup = aif1_startup,
106};
107
108static struct snd_soc_dai_link dais[] = {
109 [MERR_DPCM_AUDIO] = {
110 .name = "Audio Port",
111 .stream_name = "Audio",
112 .cpu_dai_name = "media-cpu-dai",
113 .codec_dai_name = "snd-soc-dummy-dai",
114 .codec_name = "snd-soc-dummy",
115 .platform_name = "sst-mfld-platform",
116 .ignore_suspend = 1,
117 .nonatomic = true,
118 .dynamic = 1,
119 .dpcm_playback = 1,
120 .dpcm_capture = 1,
121 .ops = &aif1_ops,
122 },
123 [MERR_DPCM_DEEP_BUFFER] = {
124 .name = "Deep-Buffer Audio Port",
125 .stream_name = "Deep-Buffer Audio",
126 .cpu_dai_name = "deepbuffer-cpu-dai",
127 .codec_dai_name = "snd-soc-dummy-dai",
128 .codec_name = "snd-soc-dummy",
129 .platform_name = "sst-mfld-platform",
130 .ignore_suspend = 1,
131 .nonatomic = true,
132 .dynamic = 1,
133 .dpcm_playback = 1,
134 .ops = &aif1_ops,
135 },
136 [MERR_DPCM_COMPR] = {
137 .name = "Compressed Port",
138 .stream_name = "Compress",
139 .cpu_dai_name = "compress-cpu-dai",
140 .codec_dai_name = "snd-soc-dummy-dai",
141 .codec_name = "snd-soc-dummy",
142 .platform_name = "sst-mfld-platform",
143 },
144 /* CODEC<->CODEC link */
145 /* back ends */
146 {
147 .name = "SSP2-LowSpeed Connector",
148 .id = 1,
149 .cpu_dai_name = "ssp2-port",
150 .platform_name = "sst-mfld-platform",
151 .no_pcm = 1,
152 .codec_dai_name = "snd-soc-dummy-dai",
153 .codec_name = "snd-soc-dummy",
154 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
155 | SND_SOC_DAIFMT_CBS_CFS,
156 .be_hw_params_fixup = codec_fixup,
157 .ignore_suspend = 1,
158 .nonatomic = true,
159 .dpcm_playback = 1,
160 .dpcm_capture = 1,
161 },
162};
163
164/* SoC card */
165static struct snd_soc_card bytcht_nocodec_card = {
166 .name = "bytcht-nocodec",
167 .owner = THIS_MODULE,
168 .dai_link = dais,
169 .num_links = ARRAY_SIZE(dais),
170 .dapm_widgets = widgets,
171 .num_dapm_widgets = ARRAY_SIZE(widgets),
172 .dapm_routes = audio_map,
173 .num_dapm_routes = ARRAY_SIZE(audio_map),
174 .controls = controls,
175 .num_controls = ARRAY_SIZE(controls),
176 .fully_routed = true,
177};
178
179static int snd_bytcht_nocodec_mc_probe(struct platform_device *pdev)
180{
181 int ret_val = 0;
182
183 /* register the soc card */
184 bytcht_nocodec_card.dev = &pdev->dev;
185
186 ret_val = devm_snd_soc_register_card(&pdev->dev, &bytcht_nocodec_card);
187
188 if (ret_val) {
189 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
190 ret_val);
191 return ret_val;
192 }
193 platform_set_drvdata(pdev, &bytcht_nocodec_card);
194 return ret_val;
195}
196
197static struct platform_driver snd_bytcht_nocodec_mc_driver = {
198 .driver = {
199 .name = "bytcht_nocodec",
200 },
201 .probe = snd_bytcht_nocodec_mc_probe,
202};
203module_platform_driver(snd_bytcht_nocodec_mc_driver);
204
205MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail Nocodec Machine driver");
206MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>");
207MODULE_LICENSE("GPL v2");
208MODULE_ALIAS("platform:bytcht_nocodec");
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 9e2a3404a836..4a76b099a508 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/moduleparam.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/acpi.h> 24#include <linux/acpi.h>
24#include <linux/device.h> 25#include <linux/device.h>
@@ -56,35 +57,88 @@ enum {
56struct byt_rt5640_private { 57struct byt_rt5640_private {
57 struct clk *mclk; 58 struct clk *mclk;
58}; 59};
60static bool is_bytcr;
59 61
60static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; 62static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
63static unsigned int quirk_override;
64module_param_named(quirk, quirk_override, uint, 0444);
65MODULE_PARM_DESC(quirk, "Board-specific quirk override");
61 66
62static void log_quirks(struct device *dev) 67static void log_quirks(struct device *dev)
63{ 68{
64 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP) 69 int map;
65 dev_info(dev, "quirk DMIC1_MAP enabled"); 70 bool has_dmic = false;
66 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP) 71 bool has_mclk = false;
67 dev_info(dev, "quirk DMIC2_MAP enabled"); 72 bool has_ssp0 = false;
68 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP) 73 bool has_ssp0_aif1 = false;
69 dev_info(dev, "quirk IN1_MAP enabled"); 74 bool has_ssp0_aif2 = false;
70 if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP) 75 bool has_ssp2_aif2 = false;
71 dev_info(dev, "quirk IN3_MAP enabled"); 76
72 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) 77 map = BYT_RT5640_MAP(byt_rt5640_quirk);
73 dev_info(dev, "quirk DMIC enabled"); 78 switch (map) {
79 case BYT_RT5640_DMIC1_MAP:
80 dev_info(dev, "quirk DMIC1_MAP enabled\n");
81 has_dmic = true;
82 break;
83 case BYT_RT5640_DMIC2_MAP:
84 dev_info(dev, "quirk DMIC2_MAP enabled\n");
85 has_dmic = true;
86 break;
87 case BYT_RT5640_IN1_MAP:
88 dev_info(dev, "quirk IN1_MAP enabled\n");
89 break;
90 case BYT_RT5640_IN3_MAP:
91 dev_info(dev, "quirk IN3_MAP enabled\n");
92 break;
93 default:
94 dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
95 break;
96 }
97 if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
98 if (has_dmic)
99 dev_info(dev, "quirk DMIC enabled\n");
100 else
101 dev_err(dev, "quirk DMIC enabled but no DMIC input set, will be ignored\n");
102 }
74 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) 103 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
75 dev_info(dev, "quirk MONO_SPEAKER enabled"); 104 dev_info(dev, "quirk MONO_SPEAKER enabled\n");
76 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) 105 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
77 dev_info(dev, "quirk DIFF_MIC enabled"); 106 if (!has_dmic)
78 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) 107 dev_info(dev, "quirk DIFF_MIC enabled\n");
79 dev_info(dev, "quirk SSP2_AIF2 enabled"); 108 else
80 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) 109 dev_info(dev, "quirk DIFF_MIC enabled but DMIC input selected, will be ignored\n");
81 dev_info(dev, "quirk SSP0_AIF1 enabled"); 110 }
82 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) 111 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
83 dev_info(dev, "quirk SSP0_AIF2 enabled"); 112 dev_info(dev, "quirk SSP0_AIF1 enabled\n");
84 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) 113 has_ssp0 = true;
85 dev_info(dev, "quirk MCLK_EN enabled"); 114 has_ssp0_aif1 = true;
86 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) 115 }
87 dev_info(dev, "quirk MCLK_25MHZ enabled"); 116 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
117 dev_info(dev, "quirk SSP0_AIF2 enabled\n");
118 has_ssp0 = true;
119 has_ssp0_aif2 = true;
120 }
121 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
122 dev_info(dev, "quirk SSP2_AIF2 enabled\n");
123 has_ssp2_aif2 = true;
124 }
125 if (is_bytcr && !has_ssp0)
126 dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
127 if (has_ssp0_aif1 && has_ssp0_aif2)
128 dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
129 if (has_ssp0 && has_ssp2_aif2)
130 dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
131
132 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
133 dev_info(dev, "quirk MCLK_EN enabled\n");
134 has_mclk = true;
135 }
136 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
137 if (has_mclk)
138 dev_info(dev, "quirk MCLK_25MHZ enabled\n");
139 else
140 dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
141 }
88} 142}
89 143
90 144
@@ -128,7 +182,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
128 ret = clk_prepare_enable(priv->mclk); 182 ret = clk_prepare_enable(priv->mclk);
129 if (ret < 0) { 183 if (ret < 0) {
130 dev_err(card->dev, 184 dev_err(card->dev,
131 "could not configure MCLK state"); 185 "could not configure MCLK state\n");
132 return ret; 186 return ret;
133 } 187 }
134 } 188 }
@@ -710,8 +764,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
710 int i; 764 int i;
711 int dai_index; 765 int dai_index;
712 struct byt_rt5640_private *priv; 766 struct byt_rt5640_private *priv;
713 bool is_bytcr = false;
714 767
768 is_bytcr = false;
715 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); 769 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
716 if (!priv) 770 if (!priv)
717 return -ENOMEM; 771 return -ENOMEM;
@@ -806,6 +860,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
806 860
807 /* check quirks before creating card */ 861 /* check quirks before creating card */
808 dmi_check_system(byt_rt5640_quirk_table); 862 dmi_check_system(byt_rt5640_quirk_table);
863 if (quirk_override) {
864 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
865 (unsigned int)byt_rt5640_quirk, quirk_override);
866 byt_rt5640_quirk = quirk_override;
867 }
809 log_quirks(&pdev->dev); 868 log_quirks(&pdev->dev);
810 869
811 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || 870 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index a3459d1682a6..d33bdaf92c57 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -2000,10 +2000,8 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2000 u32 param_size, char *param) 2000 u32 param_size, char *param)
2001{ 2001{
2002 int ret; 2002 int ret;
2003 unsigned char *data = NULL;
2004 u32 header = 0; 2003 u32 header = 0;
2005 u32 payload_size = 0, transfer_parameter_size = 0; 2004 u32 payload_size = 0, transfer_parameter_size = 0;
2006 dma_addr_t dma_addr = 0;
2007 struct sst_hsw_transfer_parameter *parameter; 2005 struct sst_hsw_transfer_parameter *parameter;
2008 struct device *dev = hsw->dev; 2006 struct device *dev = hsw->dev;
2009 2007
@@ -2047,10 +2045,6 @@ int sst_hsw_module_set_param(struct sst_hsw *hsw,
2047 2045
2048 kfree(parameter); 2046 kfree(parameter);
2049 2047
2050 if (data)
2051 dma_free_coherent(hsw->dsp->dma_dev,
2052 param_size, (void *)data, dma_addr);
2053
2054 return ret; 2048 return ret;
2055} 2049}
2056 2050
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 15a063a403cc..f5e7dbb1ba39 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -25,7 +25,8 @@
25#include "skl-sst-ipc.h" 25#include "skl-sst-ipc.h"
26 26
27#define BXT_BASEFW_TIMEOUT 3000 27#define BXT_BASEFW_TIMEOUT 3000
28#define BXT_INIT_TIMEOUT 500 28#define BXT_INIT_TIMEOUT 300
29#define BXT_ROM_INIT_TIMEOUT 70
29#define BXT_IPC_PURGE_FW 0x01004000 30#define BXT_IPC_PURGE_FW 0x01004000
30 31
31#define BXT_ROM_INIT 0x5 32#define BXT_ROM_INIT 0x5
@@ -45,6 +46,8 @@
45/* Delay before scheduling D0i3 entry */ 46/* Delay before scheduling D0i3 entry */
46#define BXT_D0I3_DELAY 5000 47#define BXT_D0I3_DELAY 5000
47 48
49#define BXT_FW_ROM_INIT_RETRY 3
50
48static unsigned int bxt_get_errorcode(struct sst_dsp *ctx) 51static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
49{ 52{
50 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE); 53 return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
@@ -55,29 +58,15 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
55{ 58{
56 struct snd_dma_buffer dmab; 59 struct snd_dma_buffer dmab;
57 struct skl_sst *skl = ctx->thread_context; 60 struct skl_sst *skl = ctx->thread_context;
58 const struct firmware *fw = NULL;
59 struct firmware stripped_fw; 61 struct firmware stripped_fw;
60 int ret = 0, i, dma_id, stream_tag; 62 int ret = 0, i, dma_id, stream_tag;
61 63
62 /* library indices start from 1 to N. 0 represents base FW */ 64 /* library indices start from 1 to N. 0 represents base FW */
63 for (i = 1; i < lib_count; i++) { 65 for (i = 1; i < lib_count; i++) {
64 ret = request_firmware(&fw, linfo[i].name, ctx->dev); 66 ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
65 if (ret < 0) {
66 dev_err(ctx->dev, "Request lib %s failed:%d\n",
67 linfo[i].name, ret);
68 return ret;
69 }
70
71 if (skl->is_first_boot) {
72 ret = snd_skl_parse_uuids(ctx, fw,
73 BXT_ADSP_FW_BIN_HDR_OFFSET, i); 67 BXT_ADSP_FW_BIN_HDR_OFFSET, i);
74 if (ret < 0) 68 if (ret < 0)
75 goto load_library_failed; 69 goto load_library_failed;
76 }
77
78 stripped_fw.data = fw->data;
79 stripped_fw.size = fw->size;
80 skl_dsp_strip_extended_manifest(&stripped_fw);
81 70
82 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, 71 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
83 stripped_fw.size, &dmab); 72 stripped_fw.size, &dmab);
@@ -92,21 +81,19 @@ bxt_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
92 memcpy(dmab.area, stripped_fw.data, stripped_fw.size); 81 memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
93 82
94 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag); 83 ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
95 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i); 84 ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i, true);
96 if (ret < 0) 85 if (ret < 0)
97 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n", 86 dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
98 linfo[i].name, ret); 87 linfo[i].name, ret);
99 88
100 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag); 89 ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
101 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag); 90 ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
102 release_firmware(fw);
103 fw = NULL;
104 } 91 }
105 92
106 return ret; 93 return ret;
107 94
108load_library_failed: 95load_library_failed:
109 release_firmware(fw); 96 skl_release_library(linfo, lib_count);
110 return ret; 97 return ret;
111} 98}
112 99
@@ -156,7 +143,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
156 SKL_ADSP_REG_HIPCIE_DONE, 143 SKL_ADSP_REG_HIPCIE_DONE,
157 BXT_INIT_TIMEOUT, "HIPCIE Done"); 144 BXT_INIT_TIMEOUT, "HIPCIE Done");
158 if (ret < 0) { 145 if (ret < 0) {
159 dev_err(ctx->dev, "Timout for Purge Request%d\n", ret); 146 dev_err(ctx->dev, "Timeout for Purge Request%d\n", ret);
160 goto base_fw_load_failed; 147 goto base_fw_load_failed;
161 } 148 }
162 149
@@ -173,7 +160,7 @@ static int sst_bxt_prepare_fw(struct sst_dsp *ctx,
173 160
174 /* Step 7: Wait for ROM init */ 161 /* Step 7: Wait for ROM init */
175 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK, 162 ret = sst_dsp_register_poll(ctx, BXT_ADSP_FW_STATUS, SKL_FW_STS_MASK,
176 SKL_FW_INIT, BXT_INIT_TIMEOUT, "ROM Load"); 163 SKL_FW_INIT, BXT_ROM_INIT_TIMEOUT, "ROM Load");
177 if (ret < 0) { 164 if (ret < 0) {
178 dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret); 165 dev_err(ctx->dev, "Timeout for ROM init, ret:%d\n", ret);
179 goto base_fw_load_failed; 166 goto base_fw_load_failed;
@@ -206,18 +193,16 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
206{ 193{
207 struct firmware stripped_fw; 194 struct firmware stripped_fw;
208 struct skl_sst *skl = ctx->thread_context; 195 struct skl_sst *skl = ctx->thread_context;
209 int ret; 196 int ret, i;
210 197
211 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); 198 if (ctx->fw == NULL) {
212 if (ret < 0) { 199 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev);
213 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 200 if (ret < 0) {
214 goto sst_load_base_firmware_failed; 201 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
202 return ret;
203 }
215 } 204 }
216 205
217 /* check for extended manifest */
218 if (ctx->fw == NULL)
219 goto sst_load_base_firmware_failed;
220
221 /* prase uuids on first boot */ 206 /* prase uuids on first boot */
222 if (skl->is_first_boot) { 207 if (skl->is_first_boot) {
223 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0); 208 ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
@@ -229,18 +214,20 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
229 stripped_fw.size = ctx->fw->size; 214 stripped_fw.size = ctx->fw->size;
230 skl_dsp_strip_extended_manifest(&stripped_fw); 215 skl_dsp_strip_extended_manifest(&stripped_fw);
231 216
232 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 217
233 /* Retry Enabling core and ROM load. Retry seemed to help */ 218 for (i = 0; i < BXT_FW_ROM_INIT_RETRY; i++) {
234 if (ret < 0) {
235 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); 219 ret = sst_bxt_prepare_fw(ctx, stripped_fw.data, stripped_fw.size);
236 if (ret < 0) { 220 if (ret == 0)
237 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n", 221 break;
222 }
223
224 if (ret < 0) {
225 dev_err(ctx->dev, "Error code=0x%x: FW status=0x%x\n",
238 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE), 226 sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE),
239 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS)); 227 sst_dsp_shim_read(ctx, BXT_ADSP_FW_STATUS));
240 228
241 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret); 229 dev_err(ctx->dev, "Core En/ROM load fail:%d\n", ret);
242 goto sst_load_base_firmware_failed; 230 goto sst_load_base_firmware_failed;
243 }
244 } 231 }
245 232
246 ret = sst_transfer_fw_host_dma(ctx); 233 ret = sst_transfer_fw_host_dma(ctx);
@@ -265,8 +252,11 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
265 } 252 }
266 } 253 }
267 254
255 return ret;
256
268sst_load_base_firmware_failed: 257sst_load_base_firmware_failed:
269 release_firmware(ctx->fw); 258 release_firmware(ctx->fw);
259 ctx->fw = NULL;
270 return ret; 260 return ret;
271} 261}
272 262
@@ -428,6 +418,7 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
428 return ret; 418 return ret;
429 } 419 }
430 } 420 }
421 skl->cores.state[core_id] = SKL_DSP_RUNNING;
431 return ret; 422 return ret;
432 } 423 }
433 424
@@ -514,11 +505,22 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
514 505
515 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID, 506 ret = skl_ipc_set_dx(&skl->ipc, BXT_INSTANCE_ID,
516 BXT_BASE_FW_MODULE_ID, &dx); 507 BXT_BASE_FW_MODULE_ID, &dx);
517 if (ret < 0) 508 if (ret < 0) {
518 dev_err(ctx->dev, 509 dev_err(ctx->dev,
519 "Failed to set DSP to D3:core id = %d;Continue reset\n", 510 "Failed to set DSP to D3:core id = %d;Continue reset\n",
520 core_id); 511 core_id);
512 /*
513 * In case of D3 failure, re-download the firmware, so set
514 * fw_loaded to false.
515 */
516 skl->fw_loaded = false;
517 }
521 518
519 if (core_id == SKL_DSP_CORE0_ID) {
520 /* disable Interrupt */
521 skl_ipc_op_int_disable(ctx);
522 skl_ipc_int_disable(ctx);
523 }
522 ret = skl_dsp_disable_core(ctx, core_mask); 524 ret = skl_dsp_disable_core(ctx, core_mask);
523 if (ret < 0) { 525 if (ret < 0) {
524 dev_err(ctx->dev, "Failed to disable core %d\n", ret); 526 dev_err(ctx->dev, "Failed to disable core %d\n", ret);
@@ -560,23 +562,14 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
560 struct sst_dsp *sst; 562 struct sst_dsp *sst;
561 int ret; 563 int ret;
562 564
563 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); 565 ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
564 if (skl == NULL) 566 if (ret < 0) {
565 return -ENOMEM; 567 dev_err(dev, "%s: no device\n", __func__);
566 568 return ret;
567 skl->dev = dev;
568 skl_dev.thread_context = skl;
569 INIT_LIST_HEAD(&skl->uuid_list);
570
571 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
572 if (!skl->dsp) {
573 dev_err(skl->dev, "skl_dsp_ctx_init failed\n");
574 return -ENODEV;
575 } 569 }
576 570
571 skl = *dsp;
577 sst = skl->dsp; 572 sst = skl->dsp;
578 sst->fw_name = fw_name;
579 sst->dsp_ops = dsp_ops;
580 sst->fw_ops = bxt_fw_ops; 573 sst->fw_ops = bxt_fw_ops;
581 sst->addr.lpe = mmio_base; 574 sst->addr.lpe = mmio_base;
582 sst->addr.shim = mmio_base; 575 sst->addr.shim = mmio_base;
@@ -584,24 +577,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
584 sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 577 sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
585 SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 578 SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
586 579
587 INIT_LIST_HEAD(&sst->module_list);
588 ret = skl_ipc_init(dev, skl);
589 if (ret)
590 return ret;
591
592 /* set the D0i3 check */ 580 /* set the D0i3 check */
593 skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; 581 skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0;
594 582
595 skl->cores.count = 2; 583 skl->cores.count = 2;
596 skl->boot_complete = false; 584 skl->boot_complete = false;
597 init_waitqueue_head(&skl->boot_wait); 585 init_waitqueue_head(&skl->boot_wait);
598 skl->is_first_boot = true;
599 INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); 586 INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
600 skl->d0i3.state = SKL_DSP_D0I3_NONE; 587 skl->d0i3.state = SKL_DSP_D0I3_NONE;
601 588
602 if (dsp)
603 *dsp = skl;
604
605 return 0; 589 return 0;
606} 590}
607EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); 591EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
@@ -635,6 +619,10 @@ EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
635 619
636void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) 620void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
637{ 621{
622
623 skl_release_library(ctx->lib_info, ctx->lib_count);
624 if (ctx->dsp->fw)
625 release_firmware(ctx->dsp->fw);
638 skl_freeup_uuid_list(ctx); 626 skl_freeup_uuid_list(ctx);
639 skl_ipc_free(&ctx->ipc); 627 skl_ipc_free(&ctx->ipc);
640 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); 628 ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index e66870474f10..ab1adc0c9cc3 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -58,7 +58,7 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
58#define NOTIFICATION_MASK 0xf 58#define NOTIFICATION_MASK 0xf
59 59
60/* disable notfication for underruns/overruns from firmware module */ 60/* disable notfication for underruns/overruns from firmware module */
61static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) 61void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
62{ 62{
63 struct notification_mask mask; 63 struct notification_mask mask;
64 struct skl_ipc_large_config_msg msg = {0}; 64 struct skl_ipc_large_config_msg msg = {0};
@@ -209,7 +209,7 @@ static const struct skl_dsp_ops dsp_ops[] = {
209 { 209 {
210 .id = 0x9d71, 210 .id = 0x9d71,
211 .loader_ops = skl_get_loader_ops, 211 .loader_ops = skl_get_loader_ops,
212 .init = skl_sst_dsp_init, 212 .init = kbl_sst_dsp_init,
213 .init_fw = skl_sst_init_fw, 213 .init_fw = skl_sst_init_fw,
214 .cleanup = skl_sst_dsp_cleanup 214 .cleanup = skl_sst_dsp_cleanup
215 }, 215 },
@@ -274,6 +274,7 @@ int skl_init_dsp(struct skl *skl)
274 if (ret < 0) 274 if (ret < 0)
275 return ret; 275 return ret;
276 276
277 skl->skl_sst->dsp_ops = ops;
277 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 278 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
278 279
279 return ret; 280 return ret;
@@ -284,16 +285,11 @@ int skl_free_dsp(struct skl *skl)
284 struct hdac_ext_bus *ebus = &skl->ebus; 285 struct hdac_ext_bus *ebus = &skl->ebus;
285 struct hdac_bus *bus = ebus_to_hbus(ebus); 286 struct hdac_bus *bus = ebus_to_hbus(ebus);
286 struct skl_sst *ctx = skl->skl_sst; 287 struct skl_sst *ctx = skl->skl_sst;
287 const struct skl_dsp_ops *ops;
288 288
289 /* disable ppcap interrupt */ 289 /* disable ppcap interrupt */
290 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 290 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
291 291
292 ops = skl_get_dsp_ops(skl->pci->device); 292 ctx->dsp_ops->cleanup(bus->dev, ctx);
293 if (!ops)
294 return -EIO;
295
296 ops->cleanup(bus->dev, ctx);
297 293
298 if (ctx->dsp->addr.lpe) 294 if (ctx->dsp->addr.lpe)
299 iounmap(ctx->dsp->addr.lpe); 295 iounmap(ctx->dsp->addr.lpe);
@@ -866,7 +862,7 @@ static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
866 } 862 }
867 863
868 if (!found) 864 if (!found)
869 mcfg->m_state = SKL_MODULE_UNINIT; 865 mcfg->m_state = SKL_MODULE_INIT_DONE;
870 return; 866 return;
871} 867}
872 868
@@ -1098,7 +1094,7 @@ int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe)
1098 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1094 dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1099 1095
1100 /* If pipe is started, do stop the pipe in FW. */ 1096 /* If pipe is started, do stop the pipe in FW. */
1101 if (pipe->state > SKL_PIPE_STARTED) { 1097 if (pipe->state >= SKL_PIPE_STARTED) {
1102 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1098 ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED);
1103 if (ret < 0) { 1099 if (ret < 0) {
1104 dev_err(ctx->dev, "Failed to stop pipeline\n"); 1100 dev_err(ctx->dev, "Failed to stop pipeline\n");
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 7eb9c419dc7f..e3f06672fd6d 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -24,8 +24,6 @@
24static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45, 24static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45,
25 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53}; 25 0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53};
26 26
27#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS"
28
29struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) 27struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
30{ 28{
31 acpi_handle handle; 29 acpi_handle handle;
@@ -33,8 +31,9 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
33 struct nhlt_resource_desc *nhlt_ptr = NULL; 31 struct nhlt_resource_desc *nhlt_ptr = NULL;
34 struct nhlt_acpi_table *nhlt_table = NULL; 32 struct nhlt_acpi_table *nhlt_table = NULL;
35 33
36 if (ACPI_FAILURE(acpi_get_handle(NULL, DSDT_NHLT_PATH, &handle))) { 34 handle = ACPI_HANDLE(dev);
37 dev_err(dev, "Requested NHLT device not found\n"); 35 if (!handle) {
36 dev_err(dev, "Didn't find ACPI_HANDLE\n");
38 return NULL; 37 return NULL;
39 } 38 }
40 39
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index e12520e142ff..e91bbcffc856 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -21,6 +21,7 @@
21 21
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/delay.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
25#include <sound/soc.h> 26#include <sound/soc.h>
26#include "skl.h" 27#include "skl.h"
@@ -155,7 +156,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
155 snd_hdac_ext_stream_decouple(ebus, stream, true); 156 snd_hdac_ext_stream_decouple(ebus, stream, true);
156 157
157 format_val = snd_hdac_calc_stream_format(params->s_freq, 158 format_val = snd_hdac_calc_stream_format(params->s_freq,
158 params->ch, params->format, 32, 0); 159 params->ch, params->format, params->host_bps, 0);
159 160
160 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", 161 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
161 format_val, params->s_freq, params->ch, params->format); 162 format_val, params->s_freq, params->ch, params->format);
@@ -190,8 +191,8 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
190 191
191 stream = stream_to_hdac_ext_stream(hstream); 192 stream = stream_to_hdac_ext_stream(hstream);
192 snd_hdac_ext_stream_decouple(ebus, stream, true); 193 snd_hdac_ext_stream_decouple(ebus, stream, true);
193 format_val = snd_hdac_calc_stream_format(params->s_freq, 194 format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
194 params->ch, params->format, 24, 0); 195 params->format, params->link_bps, 0);
195 196
196 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", 197 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
197 format_val, params->s_freq, params->ch, params->format); 198 format_val, params->s_freq, params->ch, params->format);
@@ -262,23 +263,6 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
262 return 0; 263 return 0;
263} 264}
264 265
265static int skl_be_prepare(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai)
267{
268 struct skl *skl = get_skl_ctx(dai->dev);
269 struct skl_sst *ctx = skl->skl_sst;
270 struct skl_module_cfg *mconfig;
271
272 if (dai->playback_widget->power || dai->capture_widget->power)
273 return 0;
274
275 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
276 if (mconfig == NULL)
277 return -EINVAL;
278
279 return skl_dsp_set_dma_control(ctx, mconfig);
280}
281
282static int skl_pcm_prepare(struct snd_pcm_substream *substream, 266static int skl_pcm_prepare(struct snd_pcm_substream *substream,
283 struct snd_soc_dai *dai) 267 struct snd_soc_dai *dai)
284{ 268{
@@ -326,6 +310,11 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
326 p_params.host_dma_id = dma_id; 310 p_params.host_dma_id = dma_id;
327 p_params.stream = substream->stream; 311 p_params.stream = substream->stream;
328 p_params.format = params_format(params); 312 p_params.format = params_format(params);
313 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
314 p_params.host_bps = dai->driver->playback.sig_bits;
315 else
316 p_params.host_bps = dai->driver->capture.sig_bits;
317
329 318
330 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream); 319 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
331 if (m_cfg) 320 if (m_cfg)
@@ -564,6 +553,11 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
564 p_params.link_index = link->index; 553 p_params.link_index = link->index;
565 p_params.format = params_format(params); 554 p_params.format = params_format(params);
566 555
556 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
557 p_params.link_bps = codec_dai->driver->playback.sig_bits;
558 else
559 p_params.link_bps = codec_dai->driver->capture.sig_bits;
560
567 return skl_tplg_be_update_params(dai, &p_params); 561 return skl_tplg_be_update_params(dai, &p_params);
568} 562}
569 563
@@ -649,7 +643,6 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = {
649 643
650static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { 644static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
651 .hw_params = skl_be_hw_params, 645 .hw_params = skl_be_hw_params,
652 .prepare = skl_be_prepare,
653}; 646};
654 647
655static struct snd_soc_dai_ops skl_link_dai_ops = { 648static struct snd_soc_dai_ops skl_link_dai_ops = {
@@ -670,6 +663,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
670 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000, 663 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
671 .formats = SNDRV_PCM_FMTBIT_S16_LE | 664 .formats = SNDRV_PCM_FMTBIT_S16_LE |
672 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, 665 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
666 .sig_bits = 32,
673 }, 667 },
674 .capture = { 668 .capture = {
675 .stream_name = "System Capture", 669 .stream_name = "System Capture",
@@ -677,6 +671,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
677 .channels_max = HDA_STEREO, 671 .channels_max = HDA_STEREO,
678 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 672 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
679 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 673 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
674 .sig_bits = 32,
680 }, 675 },
681}, 676},
682{ 677{
@@ -688,6 +683,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
688 .channels_max = HDA_QUAD, 683 .channels_max = HDA_QUAD,
689 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 684 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
690 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 685 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
686 .sig_bits = 32,
691 }, 687 },
692}, 688},
693{ 689{
@@ -699,6 +695,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
699 .channels_max = HDA_STEREO, 695 .channels_max = HDA_STEREO,
700 .rates = SNDRV_PCM_RATE_48000, 696 .rates = SNDRV_PCM_RATE_48000,
701 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 697 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
698 .sig_bits = 32,
702 }, 699 },
703}, 700},
704{ 701{
@@ -710,6 +707,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
710 .channels_max = HDA_STEREO, 707 .channels_max = HDA_STEREO,
711 .rates = SNDRV_PCM_RATE_48000, 708 .rates = SNDRV_PCM_RATE_48000,
712 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 709 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
710 .sig_bits = 32,
713 }, 711 },
714}, 712},
715{ 713{
@@ -721,6 +719,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
721 .channels_max = HDA_QUAD, 719 .channels_max = HDA_QUAD,
722 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000, 720 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
723 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 721 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
722 .sig_bits = 32,
724 }, 723 },
725}, 724},
726{ 725{
@@ -736,6 +735,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
736 SNDRV_PCM_RATE_192000, 735 SNDRV_PCM_RATE_192000,
737 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 736 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
738 SNDRV_PCM_FMTBIT_S32_LE, 737 SNDRV_PCM_FMTBIT_S32_LE,
738 .sig_bits = 32,
739 }, 739 },
740}, 740},
741{ 741{
@@ -751,6 +751,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
751 SNDRV_PCM_RATE_192000, 751 SNDRV_PCM_RATE_192000,
752 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 752 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
753 SNDRV_PCM_FMTBIT_S32_LE, 753 SNDRV_PCM_FMTBIT_S32_LE,
754 .sig_bits = 32,
754 }, 755 },
755}, 756},
756{ 757{
@@ -766,6 +767,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
766 SNDRV_PCM_RATE_192000, 767 SNDRV_PCM_RATE_192000,
767 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | 768 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
768 SNDRV_PCM_FMTBIT_S32_LE, 769 SNDRV_PCM_FMTBIT_S32_LE,
770 .sig_bits = 32,
769 }, 771 },
770}, 772},
771 773
@@ -949,14 +951,12 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
949 951
950static int skl_platform_open(struct snd_pcm_substream *substream) 952static int skl_platform_open(struct snd_pcm_substream *substream)
951{ 953{
952 struct snd_pcm_runtime *runtime;
953 struct snd_soc_pcm_runtime *rtd = substream->private_data; 954 struct snd_soc_pcm_runtime *rtd = substream->private_data;
954 struct snd_soc_dai_link *dai_link = rtd->dai_link; 955 struct snd_soc_dai_link *dai_link = rtd->dai_link;
955 956
956 dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__, 957 dev_dbg(rtd->cpu_dai->dev, "In %s:%s\n", __func__,
957 dai_link->cpu_dai_name); 958 dai_link->cpu_dai_name);
958 959
959 runtime = substream->runtime;
960 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw); 960 snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw);
961 961
962 return 0; 962 return 0;
@@ -1062,13 +1062,31 @@ static snd_pcm_uframes_t skl_platform_pcm_pointer
1062 * HAD space reflects the actual data that is transferred. 1062 * HAD space reflects the actual data that is transferred.
1063 * Use the position buffer for capture, as DPIB write gets 1063 * Use the position buffer for capture, as DPIB write gets
1064 * completed earlier than the actual data written to the DDR. 1064 * completed earlier than the actual data written to the DDR.
1065 *
1066 * For capture stream following workaround is required to fix the
1067 * incorrect position reporting.
1068 *
1069 * 1. Wait for 20us before reading the DMA position in buffer once
1070 * the interrupt is generated for stream completion as update happens
1071 * on the HDA frame boundary i.e. 20.833uSec.
1072 * 2. Read DPIB register to flush the DMA position value. This dummy
1073 * read is required to flush DMA position value.
1074 * 3. Read the DMA Position-in-Buffer. This value now will be equal to
1075 * or greater than period boundary.
1065 */ 1076 */
1066 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1077
1078 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1067 pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE + 1079 pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1068 (AZX_REG_VS_SDXDPIB_XINTERVAL * 1080 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1069 hdac_stream(hstream)->index)); 1081 hdac_stream(hstream)->index));
1070 else 1082 } else {
1083 udelay(20);
1084 readl(ebus->bus.remap_addr +
1085 AZX_REG_VS_SDXDPIB_XBASE +
1086 (AZX_REG_VS_SDXDPIB_XINTERVAL *
1087 hdac_stream(hstream)->index));
1071 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream)); 1088 pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
1089 }
1072 1090
1073 if (pos >= hdac_stream(hstream)->bufsize) 1091 if (pos >= hdac_stream(hstream)->bufsize)
1074 pos = 0; 1092 pos = 0;
@@ -1165,7 +1183,7 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1165 snd_dma_pci_data(skl->pci), 1183 snd_dma_pci_data(skl->pci),
1166 size, MAX_PREALLOC_SIZE); 1184 size, MAX_PREALLOC_SIZE);
1167 if (retval) { 1185 if (retval) {
1168 dev_err(dai->dev, "dma buffer allocationf fail\n"); 1186 dev_err(dai->dev, "dma buffer allocation fail\n");
1169 return retval; 1187 return retval;
1170 } 1188 }
1171 } 1189 }
@@ -1173,29 +1191,52 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
1173 return retval; 1191 return retval;
1174} 1192}
1175 1193
1194static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig)
1195{
1196 struct skl_sst *ctx = skl->skl_sst;
1197 struct uuid_module *module;
1198 uuid_le *uuid_mod;
1199
1200 uuid_mod = (uuid_le *)mconfig->guid;
1201
1202 if (list_empty(&ctx->uuid_list)) {
1203 dev_err(ctx->dev, "Module list is empty\n");
1204 return -EIO;
1205 }
1206
1207 list_for_each_entry(module, &ctx->uuid_list, list) {
1208 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
1209 mconfig->id.module_id = module->id;
1210 mconfig->is_loadable = module->is_loadable;
1211 return 0;
1212 }
1213 }
1214
1215 return -EIO;
1216}
1217
1176static int skl_populate_modules(struct skl *skl) 1218static int skl_populate_modules(struct skl *skl)
1177{ 1219{
1178 struct skl_pipeline *p; 1220 struct skl_pipeline *p;
1179 struct skl_pipe_module *m; 1221 struct skl_pipe_module *m;
1180 struct snd_soc_dapm_widget *w; 1222 struct snd_soc_dapm_widget *w;
1181 struct skl_module_cfg *mconfig; 1223 struct skl_module_cfg *mconfig;
1182 int ret; 1224 int ret = 0;
1183 1225
1184 list_for_each_entry(p, &skl->ppl_list, node) { 1226 list_for_each_entry(p, &skl->ppl_list, node) {
1185 list_for_each_entry(m, &p->pipe->w_list, node) { 1227 list_for_each_entry(m, &p->pipe->w_list, node) {
1186
1187 w = m->w; 1228 w = m->w;
1188 mconfig = w->priv; 1229 mconfig = w->priv;
1189 1230
1190 ret = snd_skl_get_module_info(skl->skl_sst, mconfig); 1231 ret = skl_get_module_info(skl, mconfig);
1191 if (ret < 0) { 1232 if (ret < 0) {
1192 dev_err(skl->skl_sst->dev, 1233 dev_err(skl->skl_sst->dev,
1193 "query module info failed:%d\n", ret); 1234 "query module info failed\n");
1194 goto err; 1235 return ret;
1195 } 1236 }
1196 } 1237 }
1197 } 1238 }
1198err: 1239
1199 return ret; 1240 return ret;
1200} 1241}
1201 1242
@@ -1232,6 +1273,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
1232 } 1273 }
1233 skl_populate_modules(skl); 1274 skl_populate_modules(skl);
1234 skl->skl_sst->update_d0i3c = skl_update_d0i3c; 1275 skl->skl_sst->update_d0i3c = skl_update_d0i3c;
1276 skl_dsp_enable_notification(skl->skl_sst, false);
1235 } 1277 }
1236 pm_runtime_mark_last_busy(platform->dev); 1278 pm_runtime_mark_last_busy(platform->dev);
1237 pm_runtime_put_autosuspend(platform->dev); 1279 pm_runtime_put_autosuspend(platform->dev);
@@ -1256,6 +1298,7 @@ int skl_platform_register(struct device *dev)
1256 struct skl *skl = ebus_to_skl(ebus); 1298 struct skl *skl = ebus_to_skl(ebus);
1257 1299
1258 INIT_LIST_HEAD(&skl->ppl_list); 1300 INIT_LIST_HEAD(&skl->ppl_list);
1301 INIT_LIST_HEAD(&skl->bind_list);
1259 1302
1260 ret = snd_soc_register_platform(dev, &skl_platform_drv); 1303 ret = snd_soc_register_platform(dev, &skl_platform_drv);
1261 if (ret) { 1304 if (ret) {
@@ -1276,6 +1319,17 @@ int skl_platform_register(struct device *dev)
1276 1319
1277int skl_platform_unregister(struct device *dev) 1320int skl_platform_unregister(struct device *dev)
1278{ 1321{
1322 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
1323 struct skl *skl = ebus_to_skl(ebus);
1324 struct skl_module_deferred_bind *modules, *tmp;
1325
1326 if (!list_empty(&skl->bind_list)) {
1327 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
1328 list_del(&modules->node);
1329 kfree(modules);
1330 }
1331 }
1332
1279 snd_soc_unregister_component(dev); 1333 snd_soc_unregister_component(dev);
1280 snd_soc_unregister_platform(dev); 1334 snd_soc_unregister_platform(dev);
1281 return 0; 1335 return 0;
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c
index c9f6d87381db..d2b1d60fec02 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.c
+++ b/sound/soc/intel/skylake/skl-sst-cldma.c
@@ -164,7 +164,7 @@ static void skl_cldma_cleanup(struct sst_dsp *ctx)
164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl); 164 ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_bdl);
165} 165}
166 166
167static int skl_cldma_wait_interruptible(struct sst_dsp *ctx) 167int skl_cldma_wait_interruptible(struct sst_dsp *ctx)
168{ 168{
169 int ret = 0; 169 int ret = 0;
170 170
@@ -243,9 +243,14 @@ static void skl_cldma_fill_buffer(struct sst_dsp *ctx, unsigned int size,
243 * 2. Polling on fw register to identify if data left to transferred doesn't 243 * 2. Polling on fw register to identify if data left to transferred doesn't
244 * fill the ring buffer. Caller takes care of polling the required status 244 * fill the ring buffer. Caller takes care of polling the required status
245 * register to identify the transfer status. 245 * register to identify the transfer status.
246 * 3. if wait flag is set, waits for DBL interrupt to copy the next chunk till
247 * bytes_left is 0.
248 * if wait flag is not set, doesn't wait for BDL interrupt. after ccopying
249 * the first chunk return the no of bytes_left to be copied.
246 */ 250 */
247static int 251static int
248skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size) 252skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin,
253 u32 total_size, bool wait)
249{ 254{
250 int ret = 0; 255 int ret = 0;
251 bool start = true; 256 bool start = true;
@@ -272,13 +277,14 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
272 size = ctx->cl_dev.bufsize; 277 size = ctx->cl_dev.bufsize;
273 skl_cldma_fill_buffer(ctx, size, curr_pos, true, start); 278 skl_cldma_fill_buffer(ctx, size, curr_pos, true, start);
274 279
275 start = false; 280 if (wait) {
276 ret = skl_cldma_wait_interruptible(ctx); 281 start = false;
277 if (ret < 0) { 282 ret = skl_cldma_wait_interruptible(ctx);
278 skl_cldma_stop(ctx); 283 if (ret < 0) {
279 return ret; 284 skl_cldma_stop(ctx);
285 return ret;
286 }
280 } 287 }
281
282 } else { 288 } else {
283 skl_cldma_int_disable(ctx); 289 skl_cldma_int_disable(ctx);
284 290
@@ -298,9 +304,11 @@ skl_cldma_copy_to_buf(struct sst_dsp *ctx, const void *bin, u32 total_size)
298 } 304 }
299 bytes_left -= size; 305 bytes_left -= size;
300 curr_pos = curr_pos + size; 306 curr_pos = curr_pos + size;
307 if (!wait)
308 return bytes_left;
301 } 309 }
302 310
303 return ret; 311 return bytes_left;
304} 312}
305 313
306void skl_cldma_process_intr(struct sst_dsp *ctx) 314void skl_cldma_process_intr(struct sst_dsp *ctx)
diff --git a/sound/soc/intel/skylake/skl-sst-cldma.h b/sound/soc/intel/skylake/skl-sst-cldma.h
index 99e4c86b6358..5b730a1a0ae4 100644
--- a/sound/soc/intel/skylake/skl-sst-cldma.h
+++ b/sound/soc/intel/skylake/skl-sst-cldma.h
@@ -213,7 +213,7 @@ struct skl_cl_dev_ops {
213 void (*cl_trigger)(struct sst_dsp *ctx, bool enable); 213 void (*cl_trigger)(struct sst_dsp *ctx, bool enable);
214 void (*cl_cleanup_controller)(struct sst_dsp *ctx); 214 void (*cl_cleanup_controller)(struct sst_dsp *ctx);
215 int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx, 215 int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
216 const void *bin, u32 size); 216 const void *bin, u32 size, bool wait);
217 void (*cl_stop_dma)(struct sst_dsp *ctx); 217 void (*cl_stop_dma)(struct sst_dsp *ctx);
218}; 218};
219 219
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index c3deefab65d6..08332723c700 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -355,12 +355,13 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id)
355 ret = ctx->fw_ops.set_state_D0(ctx, core_id); 355 ret = ctx->fw_ops.set_state_D0(ctx, core_id);
356 if (ret < 0) { 356 if (ret < 0) {
357 dev_err(ctx->dev, "unable to get core%d\n", core_id); 357 dev_err(ctx->dev, "unable to get core%d\n", core_id);
358 return ret; 358 goto out;
359 } 359 }
360 } 360 }
361 361
362 skl->cores.usage_count[core_id]++; 362 skl->cores.usage_count[core_id]++;
363 363
364out:
364 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", 365 dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n",
365 core_id, skl->cores.state[core_id], 366 core_id, skl->cores.state[core_id],
366 skl->cores.usage_count[core_id]); 367 skl->cores.usage_count[core_id]);
@@ -379,7 +380,8 @@ int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id)
379 return -EINVAL; 380 return -EINVAL;
380 } 381 }
381 382
382 if (--skl->cores.usage_count[core_id] == 0) { 383 if ((--skl->cores.usage_count[core_id] == 0) &&
384 (skl->cores.state[core_id] != SKL_DSP_RESET)) {
383 ret = ctx->fw_ops.set_state_D3(ctx, core_id); 385 ret = ctx->fw_ops.set_state_D3(ctx, core_id);
384 if (ret < 0) { 386 if (ret < 0) {
385 dev_err(ctx->dev, "unable to put core %d: %d\n", 387 dev_err(ctx->dev, "unable to put core %d: %d\n",
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index 849410d0823e..eba20d37ba8c 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -17,13 +17,15 @@
17#define __SKL_SST_DSP_H__ 17#define __SKL_SST_DSP_H__
18 18
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/uuid.h>
21#include <linux/firmware.h>
20#include <sound/memalloc.h> 22#include <sound/memalloc.h>
21#include "skl-sst-cldma.h" 23#include "skl-sst-cldma.h"
22#include "skl-topology.h"
23 24
24struct sst_dsp; 25struct sst_dsp;
25struct skl_sst; 26struct skl_sst;
26struct sst_dsp_device; 27struct sst_dsp_device;
28struct skl_lib_info;
27 29
28/* Intel HD Audio General DSP Registers */ 30/* Intel HD Audio General DSP Registers */
29#define SKL_ADSP_GEN_BASE 0x0 31#define SKL_ADSP_GEN_BASE 0x0
@@ -144,7 +146,7 @@ struct skl_dsp_fw_ops {
144 int (*load_fw)(struct sst_dsp *ctx); 146 int (*load_fw)(struct sst_dsp *ctx);
145 /* FW module parser/loader */ 147 /* FW module parser/loader */
146 int (*load_library)(struct sst_dsp *ctx, 148 int (*load_library)(struct sst_dsp *ctx,
147 struct skl_lib_info *linfo, int count); 149 struct skl_lib_info *linfo, int lib_count);
148 int (*parse_fw)(struct sst_dsp *ctx); 150 int (*parse_fw)(struct sst_dsp *ctx);
149 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); 151 int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
150 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); 152 int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
@@ -172,6 +174,19 @@ struct skl_dsp_loader_ops {
172 int stream_tag); 174 int stream_tag);
173}; 175};
174 176
177#define MAX_INSTANCE_BUFF 2
178
179struct uuid_module {
180 uuid_le uuid;
181 int id;
182 int is_loadable;
183 int max_instance;
184 u64 pvt_id[MAX_INSTANCE_BUFF];
185 int *instance_id;
186
187 struct list_head list;
188};
189
175struct skl_load_module_info { 190struct skl_load_module_info {
176 u16 mod_id; 191 u16 mod_id;
177 const struct firmware *fw; 192 const struct firmware *fw;
@@ -186,6 +201,7 @@ struct skl_module_table {
186void skl_cldma_process_intr(struct sst_dsp *ctx); 201void skl_cldma_process_intr(struct sst_dsp *ctx);
187void skl_cldma_int_disable(struct sst_dsp *ctx); 202void skl_cldma_int_disable(struct sst_dsp *ctx);
188int skl_cldma_prepare(struct sst_dsp *ctx); 203int skl_cldma_prepare(struct sst_dsp *ctx);
204int skl_cldma_wait_interruptible(struct sst_dsp *ctx);
189 205
190void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); 206void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
191struct sst_dsp *skl_dsp_ctx_init(struct device *dev, 207struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
@@ -214,6 +230,9 @@ int skl_dsp_boot(struct sst_dsp *ctx);
214int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 230int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
215 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 231 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
216 struct skl_sst **dsp); 232 struct skl_sst **dsp);
233int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
234 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
235 struct skl_sst **dsp);
217int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 236int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
218 const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 237 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
219 struct skl_sst **dsp); 238 struct skl_sst **dsp);
@@ -222,17 +241,22 @@ int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
222void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 241void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
223void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); 242void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
224 243
225int snd_skl_get_module_info(struct skl_sst *ctx,
226 struct skl_module_cfg *mconfig);
227int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, 244int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
228 unsigned int offset, int index); 245 unsigned int offset, int index);
229int skl_get_pvt_id(struct skl_sst *ctx, 246int skl_get_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int instance_id);
230 struct skl_module_cfg *mconfig); 247int skl_put_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int *pvt_id);
231int skl_put_pvt_id(struct skl_sst *ctx,
232 struct skl_module_cfg *mconfig);
233int skl_get_pvt_instance_id_map(struct skl_sst *ctx, 248int skl_get_pvt_instance_id_map(struct skl_sst *ctx,
234 int module_id, int instance_id); 249 int module_id, int instance_id);
235void skl_freeup_uuid_list(struct skl_sst *ctx); 250void skl_freeup_uuid_list(struct skl_sst *ctx);
236 251
237int skl_dsp_strip_extended_manifest(struct firmware *fw); 252int skl_dsp_strip_extended_manifest(struct firmware *fw);
253void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable);
254int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
255 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
256 struct sst_dsp_device *skl_dev);
257int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
258 struct firmware *stripped_fw,
259 unsigned int hdr_offset, int index);
260void skl_release_library(struct skl_lib_info *linfo, int lib_count);
261
238#endif /*__SKL_SST_DSP_H__*/ 262#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 e1391dfbc9e9..58c525096a7c 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -34,6 +34,11 @@
34#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1) 34#define IPC_GLB_REPLY_STATUS_MASK ((0x1 << IPC_GLB_REPLY_STATUS_SHIFT) - 1)
35#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT) 35#define IPC_GLB_REPLY_STATUS(x) ((x) << IPC_GLB_REPLY_STATUS_SHIFT)
36 36
37#define IPC_GLB_REPLY_TYPE_SHIFT 29
38#define IPC_GLB_REPLY_TYPE_MASK 0x1F
39#define IPC_GLB_REPLY_TYPE(x) (((x) >> IPC_GLB_REPLY_TYPE_SHIFT) \
40 & IPC_GLB_RPLY_TYPE_MASK)
41
37#define IPC_TIMEOUT_MSECS 3000 42#define IPC_TIMEOUT_MSECS 3000
38 43
39#define IPC_EMPTY_LIST_SIZE 8 44#define IPC_EMPTY_LIST_SIZE 8
@@ -387,12 +392,27 @@ static int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
387 return 0; 392 return 0;
388} 393}
389 394
395static int skl_ipc_set_reply_error_code(u32 reply)
396{
397 switch (reply) {
398 case IPC_GLB_REPLY_OUT_OF_MEMORY:
399 return -ENOMEM;
400
401 case IPC_GLB_REPLY_BUSY:
402 return -EBUSY;
403
404 default:
405 return -EINVAL;
406 }
407}
408
390static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, 409static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
391 struct skl_ipc_header header) 410 struct skl_ipc_header header)
392{ 411{
393 struct ipc_message *msg; 412 struct ipc_message *msg;
394 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; 413 u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK;
395 u64 *ipc_header = (u64 *)(&header); 414 u64 *ipc_header = (u64 *)(&header);
415 struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc);
396 416
397 msg = skl_ipc_reply_get_msg(ipc, *ipc_header); 417 msg = skl_ipc_reply_get_msg(ipc, *ipc_header);
398 if (msg == NULL) { 418 if (msg == NULL) {
@@ -401,33 +421,39 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
401 } 421 }
402 422
403 /* first process the header */ 423 /* first process the header */
404 switch (reply) { 424 if (reply == IPC_GLB_REPLY_SUCCESS) {
405 case IPC_GLB_REPLY_SUCCESS:
406 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary); 425 dev_dbg(ipc->dev, "ipc FW reply %x: success\n", header.primary);
407 /* copy the rx data from the mailbox */ 426 /* copy the rx data from the mailbox */
408 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size); 427 sst_dsp_inbox_read(ipc->dsp, msg->rx_data, msg->rx_size);
409 break; 428 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
410 429 case IPC_GLB_LOAD_MULTIPLE_MODS:
411 case IPC_GLB_REPLY_OUT_OF_MEMORY: 430 case IPC_GLB_LOAD_LIBRARY:
412 dev_err(ipc->dev, "ipc fw reply: %x: no memory\n", header.primary); 431 skl->mod_load_complete = true;
413 msg->errno = -ENOMEM; 432 skl->mod_load_status = true;
414 break; 433 wake_up(&skl->mod_load_wait);
415 434 break;
416 case IPC_GLB_REPLY_BUSY:
417 dev_err(ipc->dev, "ipc fw reply: %x: Busy\n", header.primary);
418 msg->errno = -EBUSY;
419 break;
420 435
421 default: 436 default:
422 dev_err(ipc->dev, "Unknown ipc reply: 0x%x\n", reply); 437 break;
423 msg->errno = -EINVAL;
424 break;
425 }
426 438
427 if (reply != IPC_GLB_REPLY_SUCCESS) { 439 }
440 } else {
441 msg->errno = skl_ipc_set_reply_error_code(reply);
428 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply); 442 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
429 dev_err(ipc->dev, "FW Error Code: %u\n", 443 dev_err(ipc->dev, "FW Error Code: %u\n",
430 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp)); 444 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
445 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
446 case IPC_GLB_LOAD_MULTIPLE_MODS:
447 case IPC_GLB_LOAD_LIBRARY:
448 skl->mod_load_complete = true;
449 skl->mod_load_status = false;
450 wake_up(&skl->mod_load_wait);
451 break;
452
453 default:
454 break;
455
456 }
431 } 457 }
432 458
433 list_del(&msg->list); 459 list_del(&msg->list);
@@ -811,8 +837,8 @@ int skl_ipc_load_modules(struct sst_generic_ipc *ipc,
811 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS); 837 header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_MULTIPLE_MODS);
812 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt); 838 header.primary |= IPC_LOAD_MODULE_CNT(module_cnt);
813 839
814 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, data, 840 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, data,
815 (sizeof(u16) * module_cnt), NULL, 0); 841 (sizeof(u16) * module_cnt));
816 if (ret < 0) 842 if (ret < 0)
817 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret); 843 dev_err(ipc->dev, "ipc: load modules failed :%d\n", ret);
818 844
@@ -947,7 +973,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
947EXPORT_SYMBOL_GPL(skl_ipc_get_large_config); 973EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
948 974
949int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, 975int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
950 u8 dma_id, u8 table_id) 976 u8 dma_id, u8 table_id, bool wait)
951{ 977{
952 struct skl_ipc_header header = {0}; 978 struct skl_ipc_header header = {0};
953 u64 *ipc_header = (u64 *)(&header); 979 u64 *ipc_header = (u64 *)(&header);
@@ -959,7 +985,11 @@ int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
959 header.primary |= IPC_MOD_INSTANCE_ID(table_id); 985 header.primary |= IPC_MOD_INSTANCE_ID(table_id);
960 header.primary |= IPC_MOD_ID(dma_id); 986 header.primary |= IPC_MOD_ID(dma_id);
961 987
962 ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0); 988 if (wait)
989 ret = sst_ipc_tx_message_wait(ipc, *ipc_header,
990 NULL, 0, NULL, 0);
991 else
992 ret = sst_ipc_tx_message_nowait(ipc, *ipc_header, NULL, 0);
963 993
964 if (ret < 0) 994 if (ret < 0)
965 dev_err(ipc->dev, "ipc: load lib failed\n"); 995 dev_err(ipc->dev, "ipc: load lib failed\n");
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9660ace379ab..e057da2713c6 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -69,6 +69,14 @@ struct skl_d0i3_data {
69 struct delayed_work work; 69 struct delayed_work work;
70}; 70};
71 71
72#define SKL_LIB_NAME_LENGTH 128
73#define SKL_MAX_LIB 16
74
75struct skl_lib_info {
76 char name[SKL_LIB_NAME_LENGTH];
77 const struct firmware *fw;
78};
79
72struct skl_sst { 80struct skl_sst {
73 struct device *dev; 81 struct device *dev;
74 struct sst_dsp *dsp; 82 struct sst_dsp *dsp;
@@ -77,6 +85,11 @@ struct skl_sst {
77 wait_queue_head_t boot_wait; 85 wait_queue_head_t boot_wait;
78 bool boot_complete; 86 bool boot_complete;
79 87
88 /* module load */
89 wait_queue_head_t mod_load_wait;
90 bool mod_load_complete;
91 bool mod_load_status;
92
80 /* IPC messaging */ 93 /* IPC messaging */
81 struct sst_generic_ipc ipc; 94 struct sst_generic_ipc ipc;
82 95
@@ -105,6 +118,8 @@ struct skl_sst {
105 void (*update_d0i3c)(struct device *dev, bool enable); 118 void (*update_d0i3c)(struct device *dev, bool enable);
106 119
107 struct skl_d0i3_data d0i3; 120 struct skl_d0i3_data d0i3;
121
122 const struct skl_dsp_ops *dsp_ops;
108}; 123};
109 124
110struct skl_ipc_init_instance_msg { 125struct skl_ipc_init_instance_msg {
@@ -182,7 +197,7 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
182 struct skl_ipc_large_config_msg *msg, u32 *param); 197 struct skl_ipc_large_config_msg *msg, u32 *param);
183 198
184int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc, 199int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
185 u8 dma_id, u8 table_id); 200 u8 dma_id, u8 table_id, bool wait);
186 201
187int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc, 202int skl_ipc_set_d0ix(struct sst_generic_ipc *ipc,
188 struct skl_ipc_d0ix_msg *msg); 203 struct skl_ipc_d0ix_msg *msg);
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index ea162fbf68e5..81ee251881b4 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -94,19 +94,6 @@ struct adsp_fw_hdr {
94 u32 load_offset; 94 u32 load_offset;
95} __packed; 95} __packed;
96 96
97#define MAX_INSTANCE_BUFF 2
98
99struct uuid_module {
100 uuid_le uuid;
101 int id;
102 int is_loadable;
103 int max_instance;
104 u64 pvt_id[MAX_INSTANCE_BUFF];
105 int *instance_id;
106
107 struct list_head list;
108};
109
110struct skl_ext_manifest_hdr { 97struct skl_ext_manifest_hdr {
111 u32 id; 98 u32 id;
112 u32 len; 99 u32 len;
@@ -115,32 +102,6 @@ struct skl_ext_manifest_hdr {
115 u32 entries; 102 u32 entries;
116}; 103};
117 104
118int snd_skl_get_module_info(struct skl_sst *ctx,
119 struct skl_module_cfg *mconfig)
120{
121 struct uuid_module *module;
122 uuid_le *uuid_mod;
123
124 uuid_mod = (uuid_le *)mconfig->guid;
125
126 if (list_empty(&ctx->uuid_list)) {
127 dev_err(ctx->dev, "Module list is empty\n");
128 return -EINVAL;
129 }
130
131 list_for_each_entry(module, &ctx->uuid_list, list) {
132 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
133 mconfig->id.module_id = module->id;
134 mconfig->is_loadable = module->is_loadable;
135
136 return 0;
137 }
138 }
139
140 return -EINVAL;
141}
142EXPORT_SYMBOL_GPL(snd_skl_get_module_info);
143
144static int skl_get_pvtid_map(struct uuid_module *module, int instance_id) 105static int skl_get_pvtid_map(struct uuid_module *module, int instance_id)
145{ 106{
146 int pvt_id; 107 int pvt_id;
@@ -222,21 +183,18 @@ static inline int skl_pvtid_128(struct uuid_module *module)
222 * This generates a 128 bit private unique id for a module TYPE so that 183 * This generates a 128 bit private unique id for a module TYPE so that
223 * module instance is unique 184 * module instance is unique
224 */ 185 */
225int skl_get_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 186int skl_get_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int instance_id)
226{ 187{
227 struct uuid_module *module; 188 struct uuid_module *module;
228 uuid_le *uuid_mod;
229 int pvt_id; 189 int pvt_id;
230 190
231 uuid_mod = (uuid_le *)mconfig->guid;
232
233 list_for_each_entry(module, &ctx->uuid_list, list) { 191 list_for_each_entry(module, &ctx->uuid_list, list) {
234 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 192 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
235 193
236 pvt_id = skl_pvtid_128(module); 194 pvt_id = skl_pvtid_128(module);
237 if (pvt_id >= 0) { 195 if (pvt_id >= 0) {
238 module->instance_id[pvt_id] = 196 module->instance_id[pvt_id] = instance_id;
239 mconfig->id.instance_id; 197
240 return pvt_id; 198 return pvt_id;
241 } 199 }
242 } 200 }
@@ -254,23 +212,21 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
254 * 212 *
255 * This frees a 128 bit private unique id previously generated 213 * This frees a 128 bit private unique id previously generated
256 */ 214 */
257int skl_put_pvt_id(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 215int skl_put_pvt_id(struct skl_sst *ctx, uuid_le *uuid_mod, int *pvt_id)
258{ 216{
259 int i; 217 int i;
260 uuid_le *uuid_mod;
261 struct uuid_module *module; 218 struct uuid_module *module;
262 219
263 uuid_mod = (uuid_le *)mconfig->guid;
264 list_for_each_entry(module, &ctx->uuid_list, list) { 220 list_for_each_entry(module, &ctx->uuid_list, list) {
265 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { 221 if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
266 222
267 if (mconfig->id.pvt_id != 0) 223 if (*pvt_id != 0)
268 i = (mconfig->id.pvt_id) / 64; 224 i = (*pvt_id) / 64;
269 else 225 else
270 i = 0; 226 i = 0;
271 227
272 module->pvt_id[i] &= ~(1 << (mconfig->id.pvt_id)); 228 module->pvt_id[i] &= ~(1 << (*pvt_id));
273 mconfig->id.pvt_id = -1; 229 *pvt_id = -1;
274 return 0; 230 return 0;
275 } 231 }
276 } 232 }
@@ -405,3 +361,83 @@ int skl_dsp_strip_extended_manifest(struct firmware *fw)
405 361
406 return 0; 362 return 0;
407} 363}
364
365int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
366 struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
367 struct sst_dsp_device *skl_dev)
368{
369 struct skl_sst *skl;
370 struct sst_dsp *sst;
371 int ret;
372
373 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL);
374 if (skl == NULL)
375 return -ENOMEM;
376
377 skl->dev = dev;
378 skl_dev->thread_context = skl;
379 INIT_LIST_HEAD(&skl->uuid_list);
380 skl->dsp = skl_dsp_ctx_init(dev, skl_dev, irq);
381 if (!skl->dsp) {
382 dev_err(skl->dev, "%s: no device\n", __func__);
383 return -ENODEV;
384 }
385
386 sst = skl->dsp;
387 sst->fw_name = fw_name;
388 sst->dsp_ops = dsp_ops;
389 init_waitqueue_head(&skl->mod_load_wait);
390 INIT_LIST_HEAD(&sst->module_list);
391 ret = skl_ipc_init(dev, skl);
392 if (ret)
393 return ret;
394
395 skl->is_first_boot = true;
396 if (dsp)
397 *dsp = skl;
398
399 return ret;
400}
401
402int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo,
403 struct firmware *stripped_fw,
404 unsigned int hdr_offset, int index)
405{
406 int ret;
407 struct sst_dsp *dsp = skl->dsp;
408
409 if (linfo->fw == NULL) {
410 ret = request_firmware(&linfo->fw, linfo->name,
411 skl->dev);
412 if (ret < 0) {
413 dev_err(skl->dev, "Request lib %s failed:%d\n",
414 linfo->name, ret);
415 return ret;
416 }
417 }
418
419 if (skl->is_first_boot) {
420 ret = snd_skl_parse_uuids(dsp, linfo->fw, hdr_offset, index);
421 if (ret < 0)
422 return ret;
423 }
424
425 stripped_fw->data = linfo->fw->data;
426 stripped_fw->size = linfo->fw->size;
427 skl_dsp_strip_extended_manifest(stripped_fw);
428
429 return 0;
430}
431
432void skl_release_library(struct skl_lib_info *linfo, int lib_count)
433{
434 int i;
435
436 /* library indices start from 1 to N. 0 represents base FW */
437 for (i = 1; i < lib_count; i++) {
438 if (linfo[i].fw) {
439 release_firmware(linfo[i].fw);
440 linfo[i].fw = NULL;
441 }
442 }
443}
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index b30bd384c8d3..155e456b7a3a 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -52,7 +52,8 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
52{ 52{
53 int ret = 0; 53 int ret = 0;
54 54
55 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, basefw, base_fw_size); 55 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, basefw, base_fw_size,
56 true);
56 if (ret < 0) 57 if (ret < 0)
57 return ret; 58 return ret;
58 59
@@ -178,6 +179,18 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
178 dev_err(ctx->dev, "unable to load firmware\n"); 179 dev_err(ctx->dev, "unable to load firmware\n");
179 return ret; 180 return ret;
180 } 181 }
182
183 /* load libs as they are also lost on D3 */
184 if (skl->lib_count > 1) {
185 ret = ctx->fw_ops.load_library(ctx, skl->lib_info,
186 skl->lib_count);
187 if (ret < 0) {
188 dev_err(ctx->dev, "reload libs failed: %d\n",
189 ret);
190 return ret;
191 }
192
193 }
181 } 194 }
182 195
183 /* 196 /*
@@ -203,7 +216,7 @@ static int skl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
203 216
204 skl->cores.state[core_id] = SKL_DSP_RUNNING; 217 skl->cores.state[core_id] = SKL_DSP_RUNNING;
205 218
206 return ret; 219 return 0;
207} 220}
208 221
209static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) 222static int skl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id)
@@ -323,27 +336,85 @@ static struct skl_module_table *skl_module_get_from_id(
323 return NULL; 336 return NULL;
324} 337}
325 338
326static int skl_transfer_module(struct sst_dsp *ctx, 339static int skl_transfer_module(struct sst_dsp *ctx, const void *data,
327 struct skl_load_module_info *module) 340 u32 size, u16 mod_id, u8 table_id, bool is_module)
328{ 341{
329 int ret; 342 int ret, bytes_left, curr_pos;
330 struct skl_sst *skl = ctx->thread_context; 343 struct skl_sst *skl = ctx->thread_context;
344 skl->mod_load_complete = false;
331 345
332 ret = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, module->fw->data, 346 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx, data, size, false);
333 module->fw->size); 347 if (bytes_left < 0)
334 if (ret < 0) 348 return bytes_left;
335 return ret;
336 349
337 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, 350 /* check is_module flag to load module or library */
338 (void *)&module->mod_id); 351 if (is_module)
339 if (ret < 0) 352 ret = skl_ipc_load_modules(&skl->ipc, SKL_NUM_MODULES, &mod_id);
340 dev_err(ctx->dev, "Failed to Load module: %d\n", ret); 353 else
354 ret = skl_sst_ipc_load_library(&skl->ipc, 0, table_id, false);
355
356 if (ret < 0) {
357 dev_err(ctx->dev, "Failed to Load %s with err %d\n",
358 is_module ? "module" : "lib", ret);
359 goto out;
360 }
361
362 /*
363 * if bytes_left > 0 then wait for BDL complete interrupt and
364 * copy the next chunk till bytes_left is 0. if bytes_left is
365 * is zero, then wait for load module IPC reply
366 */
367 while (bytes_left > 0) {
368 curr_pos = size - bytes_left;
369
370 ret = skl_cldma_wait_interruptible(ctx);
371 if (ret < 0)
372 goto out;
373
374 bytes_left = ctx->cl_dev.ops.cl_copy_to_dmabuf(ctx,
375 data + curr_pos,
376 bytes_left, false);
377 }
341 378
379 ret = wait_event_timeout(skl->mod_load_wait, skl->mod_load_complete,
380 msecs_to_jiffies(SKL_IPC_BOOT_MSECS));
381 if (ret == 0 || !skl->mod_load_status) {
382 dev_err(ctx->dev, "Module Load failed\n");
383 ret = -EIO;
384 }
385
386out:
342 ctx->cl_dev.ops.cl_stop_dma(ctx); 387 ctx->cl_dev.ops.cl_stop_dma(ctx);
343 388
344 return ret; 389 return ret;
345} 390}
346 391
392static int
393kbl_load_library(struct sst_dsp *ctx, struct skl_lib_info *linfo, int lib_count)
394{
395 struct skl_sst *skl = ctx->thread_context;
396 struct firmware stripped_fw;
397 int ret, i;
398
399 /* library indices start from 1 to N. 0 represents base FW */
400 for (i = 1; i < lib_count; i++) {
401 ret = skl_prepare_lib_load(skl, &skl->lib_info[i], &stripped_fw,
402 SKL_ADSP_FW_BIN_HDR_OFFSET, i);
403 if (ret < 0)
404 goto load_library_failed;
405 ret = skl_transfer_module(ctx, stripped_fw.data,
406 stripped_fw.size, 0, i, false);
407 if (ret < 0)
408 goto load_library_failed;
409 }
410
411 return 0;
412
413load_library_failed:
414 skl_release_library(linfo, lib_count);
415 return ret;
416}
417
347static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid) 418static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
348{ 419{
349 struct skl_module_table *module_entry = NULL; 420 struct skl_module_table *module_entry = NULL;
@@ -365,7 +436,9 @@ static int skl_load_module(struct sst_dsp *ctx, u16 mod_id, u8 *guid)
365 } 436 }
366 437
367 if (!module_entry->usage_cnt) { 438 if (!module_entry->usage_cnt) {
368 ret = skl_transfer_module(ctx, module_entry->mod_info); 439 ret = skl_transfer_module(ctx, module_entry->mod_info->fw->data,
440 module_entry->mod_info->fw->size,
441 mod_id, 0, true);
369 if (ret < 0) { 442 if (ret < 0) {
370 dev_err(ctx->dev, "Failed to Load module\n"); 443 dev_err(ctx->dev, "Failed to Load module\n");
371 return ret; 444 return ret;
@@ -388,6 +461,11 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
388 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt); 461 dev_err(ctx->dev, "Module bad usage cnt!:%d\n", usage_cnt);
389 return -EIO; 462 return -EIO;
390 } 463 }
464
465 /* if module is used by others return, no need to unload */
466 if (usage_cnt > 0)
467 return 0;
468
391 ret = skl_ipc_unload_modules(&skl->ipc, 469 ret = skl_ipc_unload_modules(&skl->ipc,
392 SKL_NUM_MODULES, &mod_id); 470 SKL_NUM_MODULES, &mod_id);
393 if (ret < 0) { 471 if (ret < 0) {
@@ -434,6 +512,16 @@ static struct skl_dsp_fw_ops skl_fw_ops = {
434 .unload_mod = skl_unload_module, 512 .unload_mod = skl_unload_module,
435}; 513};
436 514
515static struct skl_dsp_fw_ops kbl_fw_ops = {
516 .set_state_D0 = skl_set_dsp_D0,
517 .set_state_D3 = skl_set_dsp_D3,
518 .load_fw = skl_load_base_firmware,
519 .get_fw_errcode = skl_get_errorcode,
520 .load_library = kbl_load_library,
521 .load_mod = skl_load_module,
522 .unload_mod = skl_unload_module,
523};
524
437static struct sst_ops skl_ops = { 525static struct sst_ops skl_ops = {
438 .irq_handler = skl_dsp_sst_interrupt, 526 .irq_handler = skl_dsp_sst_interrupt,
439 .write = sst_shim32_write, 527 .write = sst_shim32_write,
@@ -455,45 +543,47 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
455 struct sst_dsp *sst; 543 struct sst_dsp *sst;
456 int ret; 544 int ret;
457 545
458 skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); 546 ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &skl_dev);
459 if (skl == NULL) 547 if (ret < 0) {
460 return -ENOMEM; 548 dev_err(dev, "%s: no device\n", __func__);
461 549 return ret;
462 skl->dev = dev;
463 skl_dev.thread_context = skl;
464 INIT_LIST_HEAD(&skl->uuid_list);
465
466 skl->dsp = skl_dsp_ctx_init(dev, &skl_dev, irq);
467 if (!skl->dsp) {
468 dev_err(skl->dev, "%s: no device\n", __func__);
469 return -ENODEV;
470 } 550 }
471 551
552 skl = *dsp;
472 sst = skl->dsp; 553 sst = skl->dsp;
473
474 sst->fw_name = fw_name;
475 sst->addr.lpe = mmio_base; 554 sst->addr.lpe = mmio_base;
476 sst->addr.shim = mmio_base; 555 sst->addr.shim = mmio_base;
477 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), 556 sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ),
478 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); 557 SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ);
479 558
480 INIT_LIST_HEAD(&sst->module_list);
481 sst->dsp_ops = dsp_ops;
482 sst->fw_ops = skl_fw_ops; 559 sst->fw_ops = skl_fw_ops;
483 560
484 ret = skl_ipc_init(dev, skl); 561 skl->cores.count = 2;
485 if (ret) 562
563 return 0;
564}
565EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
566
567int kbl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
568 const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
569 struct skl_sst **dsp)
570{
571 struct sst_dsp *sst;
572 int ret;
573
574 ret = skl_sst_dsp_init(dev, mmio_base, irq, fw_name, dsp_ops, dsp);
575 if (ret < 0) {
576 dev_err(dev, "%s: Init failed %d\n", __func__, ret);
486 return ret; 577 return ret;
578 }
487 579
488 skl->cores.count = 2; 580 sst = (*dsp)->dsp;
489 skl->is_first_boot = true; 581 sst->fw_ops = kbl_fw_ops;
490 582
491 if (dsp) 583 return 0;
492 *dsp = skl;
493 584
494 return ret;
495} 585}
496EXPORT_SYMBOL_GPL(skl_sst_dsp_init); 586EXPORT_SYMBOL_GPL(kbl_sst_dsp_init);
497 587
498int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx) 588int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
499{ 589{
@@ -507,6 +597,15 @@ int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
507 } 597 }
508 598
509 skl_dsp_init_core_state(sst); 599 skl_dsp_init_core_state(sst);
600
601 if (ctx->lib_count > 1) {
602 ret = sst->fw_ops.load_library(sst, ctx->lib_info,
603 ctx->lib_count);
604 if (ret < 0) {
605 dev_err(dev, "Load Library failed : %x\n", ret);
606 return ret;
607 }
608 }
510 ctx->is_first_boot = false; 609 ctx->is_first_boot = false;
511 610
512 return 0; 611 return 0;
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 2dbfb1b24ef4..3a99712e44a8 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -299,8 +299,6 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
299{ 299{
300 int multiplier = 1; 300 int multiplier = 1;
301 struct skl_module_fmt *in_fmt, *out_fmt; 301 struct skl_module_fmt *in_fmt, *out_fmt;
302 int in_rate, out_rate;
303
304 302
305 /* Since fixups is applied to pin 0 only, ibs, obs needs 303 /* Since fixups is applied to pin 0 only, ibs, obs needs
306 * change for pin 0 only 304 * change for pin 0 only
@@ -311,22 +309,12 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
311 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) 309 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
312 multiplier = 5; 310 multiplier = 5;
313 311
314 if (in_fmt->s_freq % 1000) 312 mcfg->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) *
315 in_rate = (in_fmt->s_freq / 1000) + 1; 313 in_fmt->channels * (in_fmt->bit_depth >> 3) *
316 else
317 in_rate = (in_fmt->s_freq / 1000);
318
319 mcfg->ibs = in_rate * (mcfg->in_fmt->channels) *
320 (mcfg->in_fmt->bit_depth >> 3) *
321 multiplier; 314 multiplier;
322 315
323 if (mcfg->out_fmt->s_freq % 1000) 316 mcfg->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) *
324 out_rate = (mcfg->out_fmt->s_freq / 1000) + 1; 317 out_fmt->channels * (out_fmt->bit_depth >> 3) *
325 else
326 out_rate = (mcfg->out_fmt->s_freq / 1000);
327
328 mcfg->obs = out_rate * (mcfg->out_fmt->channels) *
329 (mcfg->out_fmt->bit_depth >> 3) *
330 multiplier; 318 multiplier;
331} 319}
332 320
@@ -551,6 +539,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
551 int ret = 0; 539 int ret = 0;
552 540
553 list_for_each_entry(w_module, &pipe->w_list, node) { 541 list_for_each_entry(w_module, &pipe->w_list, node) {
542 uuid_le *uuid_mod;
554 w = w_module->w; 543 w = w_module->w;
555 mconfig = w->priv; 544 mconfig = w->priv;
556 545
@@ -588,13 +577,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
588 * FE/BE params 577 * FE/BE params
589 */ 578 */
590 skl_tplg_update_module_params(w, ctx); 579 skl_tplg_update_module_params(w, ctx);
591 mconfig->id.pvt_id = skl_get_pvt_id(ctx, mconfig); 580 uuid_mod = (uuid_le *)mconfig->guid;
581 mconfig->id.pvt_id = skl_get_pvt_id(ctx, uuid_mod,
582 mconfig->id.instance_id);
592 if (mconfig->id.pvt_id < 0) 583 if (mconfig->id.pvt_id < 0)
593 return ret; 584 return ret;
594 skl_tplg_set_module_init_data(w); 585 skl_tplg_set_module_init_data(w);
595 ret = skl_init_module(ctx, mconfig); 586 ret = skl_init_module(ctx, mconfig);
596 if (ret < 0) { 587 if (ret < 0) {
597 skl_put_pvt_id(ctx, mconfig); 588 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
598 return ret; 589 return ret;
599 } 590 }
600 skl_tplg_alloc_pipe_mcps(skl, mconfig); 591 skl_tplg_alloc_pipe_mcps(skl, mconfig);
@@ -614,7 +605,9 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
614 struct skl_module_cfg *mconfig = NULL; 605 struct skl_module_cfg *mconfig = NULL;
615 606
616 list_for_each_entry(w_module, &pipe->w_list, node) { 607 list_for_each_entry(w_module, &pipe->w_list, node) {
608 uuid_le *uuid_mod;
617 mconfig = w_module->w->priv; 609 mconfig = w_module->w->priv;
610 uuid_mod = (uuid_le *)mconfig->guid;
618 611
619 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && 612 if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod &&
620 mconfig->m_state > SKL_MODULE_UNINIT) { 613 mconfig->m_state > SKL_MODULE_UNINIT) {
@@ -623,7 +616,7 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx,
623 if (ret < 0) 616 if (ret < 0)
624 return -EIO; 617 return -EIO;
625 } 618 }
626 skl_put_pvt_id(ctx, mconfig); 619 skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id);
627 } 620 }
628 621
629 /* no modules to unload in this path, so return */ 622 /* no modules to unload in this path, so return */
@@ -645,8 +638,9 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
645 struct skl_module_cfg *mconfig = w->priv; 638 struct skl_module_cfg *mconfig = w->priv;
646 struct skl_pipe_module *w_module; 639 struct skl_pipe_module *w_module;
647 struct skl_pipe *s_pipe = mconfig->pipe; 640 struct skl_pipe *s_pipe = mconfig->pipe;
648 struct skl_module_cfg *src_module = NULL, *dst_module; 641 struct skl_module_cfg *src_module = NULL, *dst_module, *module;
649 struct skl_sst *ctx = skl->skl_sst; 642 struct skl_sst *ctx = skl->skl_sst;
643 struct skl_module_deferred_bind *modules;
650 644
651 /* check resource available */ 645 /* check resource available */
652 if (!skl_is_pipe_mcps_avail(skl, mconfig)) 646 if (!skl_is_pipe_mcps_avail(skl, mconfig))
@@ -687,29 +681,48 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
687 src_module = dst_module; 681 src_module = dst_module;
688 } 682 }
689 683
684 /*
685 * When the destination module is initialized, check for these modules
686 * in deferred bind list. If found, bind them.
687 */
688 list_for_each_entry(w_module, &s_pipe->w_list, node) {
689 if (list_empty(&skl->bind_list))
690 break;
691
692 list_for_each_entry(modules, &skl->bind_list, node) {
693 module = w_module->w->priv;
694 if (modules->dst == module)
695 skl_bind_modules(ctx, modules->src,
696 modules->dst);
697 }
698 }
699
690 return 0; 700 return 0;
691} 701}
692 702
693static int skl_fill_sink_instance_id(struct skl_sst *ctx, 703static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
694 struct skl_algo_data *alg_data) 704 int size, struct skl_module_cfg *mcfg)
695{ 705{
696 struct skl_kpb_params *params = (struct skl_kpb_params *)alg_data->params;
697 struct skl_mod_inst_map *inst;
698 int i, pvt_id; 706 int i, pvt_id;
699 707
700 inst = params->map; 708 if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
709 struct skl_kpb_params *kpb_params =
710 (struct skl_kpb_params *)params;
711 struct skl_mod_inst_map *inst = kpb_params->map;
701 712
702 for (i = 0; i < params->num_modules; i++) { 713 for (i = 0; i < kpb_params->num_modules; i++) {
703 pvt_id = skl_get_pvt_instance_id_map(ctx, 714 pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
704 inst->mod_id, inst->inst_id); 715 inst->inst_id);
705 if (pvt_id < 0) 716 if (pvt_id < 0)
706 return -EINVAL; 717 return -EINVAL;
707 inst->inst_id = pvt_id; 718
708 inst++; 719 inst->inst_id = pvt_id;
720 inst++;
721 }
709 } 722 }
723
710 return 0; 724 return 0;
711} 725}
712
713/* 726/*
714 * Some modules require params to be set after the module is bound to 727 * Some modules require params to be set after the module is bound to
715 * all pins connected. 728 * all pins connected.
@@ -726,6 +739,7 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
726 struct soc_bytes_ext *sb; 739 struct soc_bytes_ext *sb;
727 struct skl_algo_data *bc; 740 struct skl_algo_data *bc;
728 struct skl_specific_cfg *sp_cfg; 741 struct skl_specific_cfg *sp_cfg;
742 u32 *params;
729 743
730 /* 744 /*
731 * check all out/in pins are in bind state. 745 * check all out/in pins are in bind state.
@@ -758,11 +772,18 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
758 bc = (struct skl_algo_data *)sb->dobj.private; 772 bc = (struct skl_algo_data *)sb->dobj.private;
759 773
760 if (bc->set_params == SKL_PARAM_BIND) { 774 if (bc->set_params == SKL_PARAM_BIND) {
761 if (mconfig->m_type == SKL_MODULE_TYPE_KPB) 775 params = kzalloc(bc->max, GFP_KERNEL);
762 skl_fill_sink_instance_id(ctx, bc); 776 if (!params)
763 ret = skl_set_module_params(ctx, 777 return -ENOMEM;
764 (u32 *)bc->params, bc->max, 778
765 bc->param_id, mconfig); 779 memcpy(params, bc->params, bc->max);
780 skl_fill_sink_instance_id(ctx, params, bc->max,
781 mconfig);
782
783 ret = skl_set_module_params(ctx, params,
784 bc->max, bc->param_id, mconfig);
785 kfree(params);
786
766 if (ret < 0) 787 if (ret < 0)
767 return ret; 788 return ret;
768 } 789 }
@@ -772,6 +793,44 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
772 return 0; 793 return 0;
773} 794}
774 795
796
797static int skl_tplg_module_add_deferred_bind(struct skl *skl,
798 struct skl_module_cfg *src, struct skl_module_cfg *dst)
799{
800 struct skl_module_deferred_bind *m_list, *modules;
801 int i;
802
803 /* only supported for module with static pin connection */
804 for (i = 0; i < dst->max_in_queue; i++) {
805 struct skl_module_pin *pin = &dst->m_in_pin[i];
806
807 if (pin->is_dynamic)
808 continue;
809
810 if ((pin->id.module_id == src->id.module_id) &&
811 (pin->id.instance_id == src->id.instance_id)) {
812
813 if (!list_empty(&skl->bind_list)) {
814 list_for_each_entry(modules, &skl->bind_list, node) {
815 if (modules->src == src && modules->dst == dst)
816 return 0;
817 }
818 }
819
820 m_list = kzalloc(sizeof(*m_list), GFP_KERNEL);
821 if (!m_list)
822 return -ENOMEM;
823
824 m_list->src = src;
825 m_list->dst = dst;
826
827 list_add(&m_list->node, &skl->bind_list);
828 }
829 }
830
831 return 0;
832}
833
775static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, 834static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
776 struct skl *skl, 835 struct skl *skl,
777 struct snd_soc_dapm_widget *src_w, 836 struct snd_soc_dapm_widget *src_w,
@@ -806,6 +865,28 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
806 sink = p->sink; 865 sink = p->sink;
807 sink_mconfig = sink->priv; 866 sink_mconfig = sink->priv;
808 867
868 /*
869 * Modules other than PGA leaf can be connected
870 * directly or via switch to a module in another
871 * pipeline. EX: reference path
872 * when the path is enabled, the dst module that needs
873 * to be bound may not be initialized. if the module is
874 * not initialized, add these modules in the deferred
875 * bind list and when the dst module is initialised,
876 * bind this module to the dst_module in deferred list.
877 */
878 if (((src_mconfig->m_state == SKL_MODULE_INIT_DONE)
879 && (sink_mconfig->m_state == SKL_MODULE_UNINIT))) {
880
881 ret = skl_tplg_module_add_deferred_bind(skl,
882 src_mconfig, sink_mconfig);
883
884 if (ret < 0)
885 return ret;
886
887 }
888
889
809 if (src_mconfig->m_state == SKL_MODULE_UNINIT || 890 if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
810 sink_mconfig->m_state == SKL_MODULE_UNINIT) 891 sink_mconfig->m_state == SKL_MODULE_UNINIT)
811 continue; 892 continue;
@@ -985,15 +1066,6 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
985 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; 1066 src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg;
986 if (!src_mconfig) 1067 if (!src_mconfig)
987 continue; 1068 continue;
988 /*
989 * If path_found == 1, that means pmd for source
990 * pipe has not occurred, source is connected to
991 * some other sink. so its responsibility of sink
992 * to unbind itself from source.
993 */
994 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
995 if (ret < 0)
996 return ret;
997 1069
998 ret = skl_unbind_modules(ctx, 1070 ret = skl_unbind_modules(ctx,
999 src_mconfig, sink_mconfig); 1071 src_mconfig, sink_mconfig);
@@ -1019,6 +1091,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1019 struct skl_module_cfg *src_module = NULL, *dst_module; 1091 struct skl_module_cfg *src_module = NULL, *dst_module;
1020 struct skl_sst *ctx = skl->skl_sst; 1092 struct skl_sst *ctx = skl->skl_sst;
1021 struct skl_pipe *s_pipe = mconfig->pipe; 1093 struct skl_pipe *s_pipe = mconfig->pipe;
1094 struct skl_module_deferred_bind *modules, *tmp;
1022 1095
1023 if (s_pipe->state == SKL_PIPE_INVALID) 1096 if (s_pipe->state == SKL_PIPE_INVALID)
1024 return -EINVAL; 1097 return -EINVAL;
@@ -1027,6 +1100,35 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1027 skl_tplg_free_pipe_mem(skl, mconfig); 1100 skl_tplg_free_pipe_mem(skl, mconfig);
1028 1101
1029 list_for_each_entry(w_module, &s_pipe->w_list, node) { 1102 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1103 if (list_empty(&skl->bind_list))
1104 break;
1105
1106 src_module = w_module->w->priv;
1107
1108 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) {
1109 /*
1110 * When the destination module is deleted, Unbind the
1111 * modules from deferred bind list.
1112 */
1113 if (modules->dst == src_module) {
1114 skl_unbind_modules(ctx, modules->src,
1115 modules->dst);
1116 }
1117
1118 /*
1119 * When the source module is deleted, remove this entry
1120 * from the deferred bind list.
1121 */
1122 if (modules->src == src_module) {
1123 list_del(&modules->node);
1124 modules->src = NULL;
1125 modules->dst = NULL;
1126 kfree(modules);
1127 }
1128 }
1129 }
1130
1131 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1030 dst_module = w_module->w->priv; 1132 dst_module = w_module->w->priv;
1031 1133
1032 if (mconfig->m_state >= SKL_MODULE_INIT_DONE) 1134 if (mconfig->m_state >= SKL_MODULE_INIT_DONE)
@@ -1042,6 +1144,11 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1042 1144
1043 skl_delete_pipe(ctx, mconfig->pipe); 1145 skl_delete_pipe(ctx, mconfig->pipe);
1044 1146
1147 list_for_each_entry(w_module, &s_pipe->w_list, node) {
1148 src_module = w_module->w->priv;
1149 src_module->m_state = SKL_MODULE_UNINIT;
1150 }
1151
1045 return skl_tplg_unload_pipe_modules(ctx, s_pipe); 1152 return skl_tplg_unload_pipe_modules(ctx, s_pipe);
1046} 1153}
1047 1154
@@ -1083,36 +1190,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
1083} 1190}
1084 1191
1085/* 1192/*
1086 * In modelling, we assume there will be ONLY one mixer in a pipeline. If
1087 * mixer is not required then it is treated as static mixer aka vmixer with
1088 * a hard path to source module
1089 * So we don't need to check if source is started or not as hard path puts
1090 * dependency on each other
1091 */
1092static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
1093 struct snd_kcontrol *k, int event)
1094{
1095 struct snd_soc_dapm_context *dapm = w->dapm;
1096 struct skl *skl = get_skl_ctx(dapm->dev);
1097
1098 switch (event) {
1099 case SND_SOC_DAPM_PRE_PMU:
1100 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
1101
1102 case SND_SOC_DAPM_POST_PMU:
1103 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
1104
1105 case SND_SOC_DAPM_PRE_PMD:
1106 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
1107
1108 case SND_SOC_DAPM_POST_PMD:
1109 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
1110 }
1111
1112 return 0;
1113}
1114
1115/*
1116 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a 1193 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
1117 * second one is required that is created as another pipe entity. 1194 * second one is required that is created as another pipe entity.
1118 * The mixer is responsible for pipe management and represent a pipeline 1195 * The mixer is responsible for pipe management and represent a pipeline
@@ -1252,10 +1329,12 @@ static void skl_tplg_fill_dma_id(struct skl_module_cfg *mcfg,
1252 case SKL_DEVICE_HDALINK: 1329 case SKL_DEVICE_HDALINK:
1253 pipe->p_params->link_dma_id = params->link_dma_id; 1330 pipe->p_params->link_dma_id = params->link_dma_id;
1254 pipe->p_params->link_index = params->link_index; 1331 pipe->p_params->link_index = params->link_index;
1332 pipe->p_params->link_bps = params->link_bps;
1255 break; 1333 break;
1256 1334
1257 case SKL_DEVICE_HDAHOST: 1335 case SKL_DEVICE_HDAHOST:
1258 pipe->p_params->host_dma_id = params->host_dma_id; 1336 pipe->p_params->host_dma_id = params->host_dma_id;
1337 pipe->p_params->host_bps = params->host_bps;
1259 break; 1338 break;
1260 1339
1261 default: 1340 default:
@@ -1578,7 +1657,7 @@ int skl_tplg_be_update_params(struct snd_soc_dai *dai,
1578 1657
1579static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = { 1658static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1580 {SKL_MIXER_EVENT, skl_tplg_mixer_event}, 1659 {SKL_MIXER_EVENT, skl_tplg_mixer_event},
1581 {SKL_VMIXER_EVENT, skl_tplg_vmixer_event}, 1660 {SKL_VMIXER_EVENT, skl_tplg_mixer_event},
1582 {SKL_PGA_EVENT, skl_tplg_pga_event}, 1661 {SKL_PGA_EVENT, skl_tplg_pga_event},
1583}; 1662};
1584 1663
@@ -1632,7 +1711,7 @@ static int skl_tplg_add_pipe(struct device *dev,
1632 list_for_each_entry(ppl, &skl->ppl_list, node) { 1711 list_for_each_entry(ppl, &skl->ppl_list, node) {
1633 if (ppl->pipe->ppl_id == tkn_elem->value) { 1712 if (ppl->pipe->ppl_id == tkn_elem->value) {
1634 mconfig->pipe = ppl->pipe; 1713 mconfig->pipe = ppl->pipe;
1635 return EEXIST; 1714 return -EEXIST;
1636 } 1715 }
1637 } 1716 }
1638 1717
@@ -1924,11 +2003,13 @@ static int skl_tplg_get_token(struct device *dev,
1924 ret = skl_tplg_add_pipe(dev, 2003 ret = skl_tplg_add_pipe(dev,
1925 mconfig, skl, tkn_elem); 2004 mconfig, skl, tkn_elem);
1926 2005
1927 if (ret < 0) 2006 if (ret < 0) {
2007 if (ret == -EEXIST) {
2008 is_pipe_exists = 1;
2009 break;
2010 }
1928 return is_pipe_exists; 2011 return is_pipe_exists;
1929 2012 }
1930 if (ret == EEXIST)
1931 is_pipe_exists = 1;
1932 2013
1933 break; 2014 break;
1934 2015
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index fefab0e99a3b..cc64d6bdb4f6 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -257,6 +257,8 @@ struct skl_pipe_params {
257 snd_pcm_format_t format; 257 snd_pcm_format_t format;
258 int link_index; 258 int link_index;
259 int stream; 259 int stream;
260 unsigned int host_bps;
261 unsigned int link_bps;
260}; 262};
261 263
262struct skl_pipe { 264struct skl_pipe {
@@ -334,17 +336,10 @@ struct skl_pipeline {
334 struct list_head node; 336 struct list_head node;
335}; 337};
336 338
337#define SKL_LIB_NAME_LENGTH 128 339struct skl_module_deferred_bind {
338#define SKL_MAX_LIB 16 340 struct skl_module_cfg *src;
339 341 struct skl_module_cfg *dst;
340struct skl_lib_info { 342 struct list_head node;
341 char name[SKL_LIB_NAME_LENGTH];
342 const struct firmware *fw;
343};
344
345struct skl_manifest {
346 u32 lib_count;
347 struct skl_lib_info lib[SKL_MAX_LIB];
348}; 343};
349 344
350static inline struct skl *get_skl_ctx(struct device *dev) 345static inline struct skl *get_skl_ctx(struct device *dev)
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 0c57d4eaae3a..6df3b317a476 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -512,7 +512,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr)
512 struct hdac_bus *bus = ebus_to_hbus(ebus); 512 struct hdac_bus *bus = ebus_to_hbus(ebus);
513 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | 513 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
514 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; 514 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
515 unsigned int res; 515 unsigned int res = -1;
516 516
517 mutex_lock(&bus->cmd_mutex); 517 mutex_lock(&bus->cmd_mutex);
518 snd_hdac_bus_send_cmd(bus, cmd); 518 snd_hdac_bus_send_cmd(bus, cmd);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 8e2878012d53..a454f6035f3e 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -56,6 +56,7 @@ struct skl {
56 56
57 struct skl_dsp_resource resource; 57 struct skl_dsp_resource resource;
58 struct list_head ppl_list; 58 struct list_head ppl_list;
59 struct list_head bind_list;
59 60
60 const char *fw_name; 61 const char *fw_name;
61 char tplg_name[64]; 62 char tplg_name[64];
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index d7013bde6f45..5c68797f36c4 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -22,6 +22,16 @@ config SND_SOC_MT2701_CS42448
22 Select Y if you have such device. 22 Select Y if you have such device.
23 If unsure select "N". 23 If unsure select "N".
24 24
25config SND_SOC_MT2701_WM8960
26 tristate "ASoc Audio driver for MT2701 with WM8960 codec"
27 depends on SND_SOC_MT2701 && I2C
28 select SND_SOC_WM8960
29 help
30 This adds ASoC driver for Mediatek MT2701 boards
31 with the WM8960 codecs.
32 Select Y if you have such device.
33 If unsure select "N".
34
25config SND_SOC_MT8173 35config SND_SOC_MT8173
26 tristate "ASoC support for Mediatek MT8173 chip" 36 tristate "ASoC support for Mediatek MT8173 chip"
27 depends on ARCH_MEDIATEK 37 depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/mt2701/Makefile b/sound/soc/mediatek/mt2701/Makefile
index 31c3d04d4942..c91deb6aca21 100644
--- a/sound/soc/mediatek/mt2701/Makefile
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
17 17
18# machine driver 18# machine driver
19obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o 19obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
20obj-$(CONFIG_SND_SOC_MT2701_WM8960) += mt2701-wm8960.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index c7fa3e663463..bc5d4db94de6 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -604,6 +604,22 @@ static struct snd_soc_dai_ops mt2701_btmrg_ops = {
604static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { 604static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
605 /* FE DAIs: memory intefaces to CPU */ 605 /* FE DAIs: memory intefaces to CPU */
606 { 606 {
607 .name = "PCMO0",
608 .id = MT2701_MEMIF_DL1,
609 .suspend = mtk_afe_dai_suspend,
610 .resume = mtk_afe_dai_resume,
611 .playback = {
612 .stream_name = "DL1",
613 .channels_min = 1,
614 .channels_max = 2,
615 .rates = SNDRV_PCM_RATE_8000_192000,
616 .formats = (SNDRV_PCM_FMTBIT_S16_LE
617 | SNDRV_PCM_FMTBIT_S24_LE
618 | SNDRV_PCM_FMTBIT_S32_LE)
619 },
620 .ops = &mt2701_single_memif_dai_ops,
621 },
622 {
607 .name = "PCM_multi", 623 .name = "PCM_multi",
608 .id = MT2701_MEMIF_DLM, 624 .id = MT2701_MEMIF_DLM,
609 .suspend = mtk_afe_dai_suspend, 625 .suspend = mtk_afe_dai_suspend,
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
index 1e7e8d43fd8a..aa5b31b121e3 100644
--- a/sound/soc/mediatek/mt2701/mt2701-cs42448.c
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -129,7 +129,7 @@ static int mt2701_cs42448_fe_ops_startup(struct snd_pcm_substream *substream)
129 return 0; 129 return 0;
130} 130}
131 131
132static struct snd_soc_ops mt2701_cs42448_48k_fe_ops = { 132static const struct snd_soc_ops mt2701_cs42448_48k_fe_ops = {
133 .startup = mt2701_cs42448_fe_ops_startup, 133 .startup = mt2701_cs42448_fe_ops_startup,
134}; 134};
135 135
diff --git a/sound/soc/mediatek/mt2701/mt2701-wm8960.c b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
new file mode 100644
index 000000000000..a08ce2323bdc
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-wm8960.c
@@ -0,0 +1,176 @@
1/*
2 * mt2701-wm8960.c -- MT2701 WM8960 ALSA SoC machine driver
3 *
4 * Copyright (c) 2017 MediaTek Inc.
5 * Author: Ryder Lee <ryder.lee@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <sound/soc.h>
19
20#include "mt2701-afe-common.h"
21
22static const struct snd_soc_dapm_widget mt2701_wm8960_widgets[] = {
23 SND_SOC_DAPM_HP("Headphone", NULL),
24 SND_SOC_DAPM_MIC("AMIC", NULL),
25};
26
27static const struct snd_kcontrol_new mt2701_wm8960_controls[] = {
28 SOC_DAPM_PIN_SWITCH("Headphone"),
29 SOC_DAPM_PIN_SWITCH("AMIC"),
30};
31
32static int mt2701_wm8960_be_ops_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params)
34{
35 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
38 unsigned int mclk_rate;
39 unsigned int rate = params_rate(params);
40 unsigned int div_mclk_over_bck = rate > 192000 ? 2 : 4;
41 unsigned int div_bck_over_lrck = 64;
42
43 mclk_rate = rate * div_bck_over_lrck * div_mclk_over_bck;
44
45 snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_rate, SND_SOC_CLOCK_OUT);
46 snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate, SND_SOC_CLOCK_IN);
47
48 return 0;
49}
50
51static struct snd_soc_ops mt2701_wm8960_be_ops = {
52 .hw_params = mt2701_wm8960_be_ops_hw_params
53};
54
55static struct snd_soc_dai_link mt2701_wm8960_dai_links[] = {
56 /* FE */
57 {
58 .name = "wm8960-playback",
59 .stream_name = "wm8960-playback",
60 .cpu_dai_name = "PCMO0",
61 .codec_name = "snd-soc-dummy",
62 .codec_dai_name = "snd-soc-dummy-dai",
63 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
64 SND_SOC_DPCM_TRIGGER_POST},
65 .dynamic = 1,
66 .dpcm_playback = 1,
67 },
68 {
69 .name = "wm8960-capture",
70 .stream_name = "wm8960-capture",
71 .cpu_dai_name = "PCM0",
72 .codec_name = "snd-soc-dummy",
73 .codec_dai_name = "snd-soc-dummy-dai",
74 .trigger = {SND_SOC_DPCM_TRIGGER_POST,
75 SND_SOC_DPCM_TRIGGER_POST},
76 .dynamic = 1,
77 .dpcm_capture = 1,
78 },
79 /* BE */
80 {
81 .name = "wm8960-codec",
82 .cpu_dai_name = "I2S0",
83 .no_pcm = 1,
84 .codec_dai_name = "wm8960-hifi",
85 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS
86 | SND_SOC_DAIFMT_GATED,
87 .ops = &mt2701_wm8960_be_ops,
88 .dpcm_playback = 1,
89 .dpcm_capture = 1,
90 },
91};
92
93static struct snd_soc_card mt2701_wm8960_card = {
94 .name = "mt2701-wm8960",
95 .owner = THIS_MODULE,
96 .dai_link = mt2701_wm8960_dai_links,
97 .num_links = ARRAY_SIZE(mt2701_wm8960_dai_links),
98 .controls = mt2701_wm8960_controls,
99 .num_controls = ARRAY_SIZE(mt2701_wm8960_controls),
100 .dapm_widgets = mt2701_wm8960_widgets,
101 .num_dapm_widgets = ARRAY_SIZE(mt2701_wm8960_widgets),
102};
103
104static int mt2701_wm8960_machine_probe(struct platform_device *pdev)
105{
106 struct snd_soc_card *card = &mt2701_wm8960_card;
107 struct device_node *platform_node, *codec_node;
108 int ret, i;
109
110 platform_node = of_parse_phandle(pdev->dev.of_node,
111 "mediatek,platform", 0);
112 if (!platform_node) {
113 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
114 return -EINVAL;
115 }
116 for (i = 0; i < card->num_links; i++) {
117 if (mt2701_wm8960_dai_links[i].platform_name)
118 continue;
119 mt2701_wm8960_dai_links[i].platform_of_node = platform_node;
120 }
121
122 card->dev = &pdev->dev;
123
124 codec_node = of_parse_phandle(pdev->dev.of_node,
125 "mediatek,audio-codec", 0);
126 if (!codec_node) {
127 dev_err(&pdev->dev,
128 "Property 'audio-codec' missing or invalid\n");
129 return -EINVAL;
130 }
131 for (i = 0; i < card->num_links; i++) {
132 if (mt2701_wm8960_dai_links[i].codec_name)
133 continue;
134 mt2701_wm8960_dai_links[i].codec_of_node = codec_node;
135 }
136
137 ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
138 if (ret) {
139 dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
140 return ret;
141 }
142
143 ret = devm_snd_soc_register_card(&pdev->dev, card);
144 if (ret)
145 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
146 __func__, ret);
147
148 return ret;
149}
150
151#ifdef CONFIG_OF
152static const struct of_device_id mt2701_wm8960_machine_dt_match[] = {
153 {.compatible = "mediatek,mt2701-wm8960-machine",},
154 {}
155};
156#endif
157
158static struct platform_driver mt2701_wm8960_machine = {
159 .driver = {
160 .name = "mt2701-wm8960",
161 .owner = THIS_MODULE,
162#ifdef CONFIG_OF
163 .of_match_table = mt2701_wm8960_machine_dt_match,
164#endif
165 },
166 .probe = mt2701_wm8960_machine_probe,
167};
168
169module_platform_driver(mt2701_wm8960_machine);
170
171/* Module information */
172MODULE_DESCRIPTION("MT2701 WM8960 ALSA SoC machine driver");
173MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
174MODULE_LICENSE("GPL v2");
175MODULE_ALIAS("mt2701 wm8960 soc card");
176
diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 46c8e6ae00b4..e0c2b23ec711 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -67,7 +67,7 @@ static int mt8173_max98090_hw_params(struct snd_pcm_substream *substream,
67 SND_SOC_CLOCK_IN); 67 SND_SOC_CLOCK_IN);
68} 68}
69 69
70static struct snd_soc_ops mt8173_max98090_ops = { 70static const struct snd_soc_ops mt8173_max98090_ops = {
71 .hw_params = mt8173_max98090_hw_params, 71 .hw_params = mt8173_max98090_hw_params,
72}; 72};
73 73
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 467f7049a288..5e383eb456a4 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -75,7 +75,7 @@ static int mt8173_rt5650_rt5514_hw_params(struct snd_pcm_substream *substream,
75 return 0; 75 return 0;
76} 76}
77 77
78static struct snd_soc_ops mt8173_rt5650_rt5514_ops = { 78static const struct snd_soc_ops mt8173_rt5650_rt5514_ops = {
79 .hw_params = mt8173_rt5650_rt5514_hw_params, 79 .hw_params = mt8173_rt5650_rt5514_hw_params,
80}; 80};
81 81
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 1b8b2a778845..fed1f15a39c2 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -79,7 +79,7 @@ static int mt8173_rt5650_rt5676_hw_params(struct snd_pcm_substream *substream,
79 return 0; 79 return 0;
80} 80}
81 81
82static struct snd_soc_ops mt8173_rt5650_rt5676_ops = { 82static const struct snd_soc_ops mt8173_rt5650_rt5676_ops = {
83 .hw_params = mt8173_rt5650_rt5676_hw_params, 83 .hw_params = mt8173_rt5650_rt5676_hw_params,
84}; 84};
85 85
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index ba65f4157a7e..a78470839b65 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -105,7 +105,7 @@ static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
105 return 0; 105 return 0;
106} 106}
107 107
108static struct snd_soc_ops mt8173_rt5650_ops = { 108static const struct snd_soc_ops mt8173_rt5650_ops = {
109 .hw_params = mt8173_rt5650_hw_params, 109 .hw_params = mt8173_rt5650_hw_params,
110}; 110};
111 111
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 25a33e9d417a..d5651026ec10 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -49,7 +49,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
49 return ret; 49 return ret;
50} 50}
51 51
52static struct snd_soc_ops am3517evm_ops = { 52static const struct snd_soc_ops am3517evm_ops = {
53 .hw_params = am3517evm_hw_params, 53 .hw_params = am3517evm_hw_params,
54}; 54};
55 55
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index fdecb7043174..71e5f31fa306 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -124,7 +124,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream,
124 return err; 124 return err;
125} 125}
126 126
127static struct snd_soc_ops n810_ops = { 127static const struct snd_soc_ops n810_ops = {
128 .startup = n810_startup, 128 .startup = n810_startup,
129 .hw_params = n810_hw_params, 129 .hw_params = n810_hw_params,
130 .shutdown = n810_shutdown, 130 .shutdown = n810_shutdown,
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 89fe95e877db..614b18d2f631 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -70,7 +70,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream,
70 return ret; 70 return ret;
71} 71}
72 72
73static struct snd_soc_ops omap_abe_ops = { 73static const struct snd_soc_ops omap_abe_ops = {
74 .hw_params = omap_abe_hw_params, 74 .hw_params = omap_abe_hw_params,
75}; 75};
76 76
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index 743131473056..a24b0dedabb9 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -73,7 +73,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
73 return snd_soc_runtime_set_dai_fmt(rtd, fmt); 73 return snd_soc_runtime_set_dai_fmt(rtd, fmt);
74} 74}
75 75
76static struct snd_soc_ops omap_twl4030_ops = { 76static const struct snd_soc_ops omap_twl4030_ops = {
77 .hw_params = omap_twl4030_hw_params, 77 .hw_params = omap_twl4030_hw_params,
78}; 78};
79 79
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 732e749a1f8e..4e3de712159c 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -184,7 +184,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
184 return 0; 184 return 0;
185} 185}
186 186
187static struct snd_soc_ops omap3pandora_ops = { 187static const struct snd_soc_ops omap3pandora_ops = {
188 .hw_params = omap3pandora_hw_params, 188 .hw_params = omap3pandora_hw_params,
189}; 189};
190 190
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index aa4053bf6710..e4096779ca05 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -68,7 +68,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
68 return err; 68 return err;
69} 69}
70 70
71static struct snd_soc_ops osk_ops = { 71static const struct snd_soc_ops osk_ops = {
72 .startup = osk_startup, 72 .startup = osk_startup,
73 .hw_params = osk_hw_params, 73 .hw_params = osk_hw_params,
74 .shutdown = osk_shutdown, 74 .shutdown = osk_shutdown,
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index a76845748a10..3aeb65feaea1 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -123,7 +123,7 @@ static int rx51_hw_params(struct snd_pcm_substream *substream,
123 SND_SOC_CLOCK_IN); 123 SND_SOC_CLOCK_IN);
124} 124}
125 125
126static struct snd_soc_ops rx51_ops = { 126static const struct snd_soc_ops rx51_ops = {
127 .startup = rx51_startup, 127 .startup = rx51_startup,
128 .hw_params = rx51_hw_params, 128 .hw_params = rx51_hw_params,
129}; 129};
@@ -433,10 +433,9 @@ static int rx51_soc_probe(struct platform_device *pdev)
433 } 433 }
434 434
435 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 435 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
436 if (pdata == NULL) { 436 if (pdata == NULL)
437 dev_err(card->dev, "failed to create private data\n");
438 return -ENOMEM; 437 return -ENOMEM;
439 } 438
440 snd_soc_card_set_drvdata(card, pdata); 439 snd_soc_card_set_drvdata(card, pdata);
441 440
442 pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, 441 pdata->tvout_selection_gpio = devm_gpiod_get(card->dev,
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index b6cb9950f05d..9a3f5b799720 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -74,7 +74,7 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
74} 74}
75 75
76/* machine stream operations */ 76/* machine stream operations */
77static struct snd_soc_ops brownstone_ops = { 77static const struct snd_soc_ops brownstone_ops = {
78 .hw_params = brownstone_wm8994_hw_params, 78 .hw_params = brownstone_wm8994_hw_params,
79}; 79};
80 80
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 311774e9ca46..054e0d65db9d 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -154,7 +154,7 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
154 return 0; 154 return 0;
155} 155}
156 156
157static struct snd_soc_ops corgi_ops = { 157static const struct snd_soc_ops corgi_ops = {
158 .startup = corgi_startup, 158 .startup = corgi_startup,
159 .hw_params = corgi_hw_params, 159 .hw_params = corgi_hw_params,
160 .shutdown = corgi_shutdown, 160 .shutdown = corgi_shutdown,
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index fdcd94adee7c..82bcbbb1841b 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -81,7 +81,7 @@ static struct snd_soc_dai_link e750_dai[] = {
81 .name = "AC97 Aux", 81 .name = "AC97 Aux",
82 .stream_name = "AC97 Aux", 82 .stream_name = "AC97 Aux",
83 .cpu_dai_name = "pxa2xx-ac97-aux", 83 .cpu_dai_name = "pxa2xx-ac97-aux",
84 .codec_dai_name ="wm9705-aux", 84 .codec_dai_name = "wm9705-aux",
85 .platform_name = "pxa-pcm-audio", 85 .platform_name = "pxa-pcm-audio",
86 .codec_name = "wm9705-codec", 86 .codec_name = "wm9705-codec",
87 }, 87 },
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 2df714f70ec0..1ed8aa2348f1 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -81,7 +81,7 @@ static struct snd_soc_dai_link e800_dai[] = {
81 .name = "AC97 Aux", 81 .name = "AC97 Aux",
82 .stream_name = "AC97 Aux", 82 .stream_name = "AC97 Aux",
83 .cpu_dai_name = "pxa2xx-ac97-aux", 83 .cpu_dai_name = "pxa2xx-ac97-aux",
84 .codec_dai_name ="wm9712-aux", 84 .codec_dai_name = "wm9712-aux",
85 .platform_name = "pxa-pcm-audio", 85 .platform_name = "pxa-pcm-audio",
86 .codec_name = "wm9712-codec", 86 .codec_name = "wm9712-codec",
87 }, 87 },
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index 6f2020f6c8d3..e046770ce70e 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -43,7 +43,7 @@ static struct snd_soc_dai_link em_x270_dai[] = {
43 .name = "AC97 Aux", 43 .name = "AC97 Aux",
44 .stream_name = "AC97 Aux", 44 .stream_name = "AC97 Aux",
45 .cpu_dai_name = "pxa2xx-ac97-aux", 45 .cpu_dai_name = "pxa2xx-ac97-aux",
46 .codec_dai_name ="wm9712-aux", 46 .codec_dai_name = "wm9712-aux",
47 .platform_name = "pxa-pcm-audio", 47 .platform_name = "pxa-pcm-audio",
48 .codec_name = "wm9712-codec", 48 .codec_name = "wm9712-codec",
49 }, 49 },
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 85483049b916..a9ac881c2e14 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -79,7 +79,7 @@ static int hx4700_hw_params(struct snd_pcm_substream *substream,
79 return 0; 79 return 0;
80} 80}
81 81
82static struct snd_soc_ops hx4700_ops = { 82static const struct snd_soc_ops hx4700_ops = {
83 .hw_params = hx4700_hw_params, 83 .hw_params = hx4700_hw_params,
84}; 84};
85 85
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 9d0e40771ef5..78475376f971 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -42,7 +42,7 @@ static int imote2_asoc_hw_params(struct snd_pcm_substream *substream,
42 return ret; 42 return ret;
43} 43}
44 44
45static struct snd_soc_ops imote2_asoc_ops = { 45static const struct snd_soc_ops imote2_asoc_ops = {
46 .hw_params = imote2_asoc_hw_params, 46 .hw_params = imote2_asoc_hw_params,
47}; 47};
48 48
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 2d4d4455fe87..2fc012b06c43 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -255,12 +255,12 @@ static int magician_capture_hw_params(struct snd_pcm_substream *substream,
255 return 0; 255 return 0;
256} 256}
257 257
258static struct snd_soc_ops magician_capture_ops = { 258static const struct snd_soc_ops magician_capture_ops = {
259 .startup = magician_startup, 259 .startup = magician_startup,
260 .hw_params = magician_capture_hw_params, 260 .hw_params = magician_capture_hw_params,
261}; 261};
262 262
263static struct snd_soc_ops magician_playback_ops = { 263static const struct snd_soc_ops magician_playback_ops = {
264 .startup = magician_startup, 264 .startup = magician_startup,
265 .hw_params = magician_playback_hw_params, 265 .hw_params = magician_playback_hw_params,
266}; 266};
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 8760a6687885..c4c6fbedc723 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -157,7 +157,7 @@ static struct snd_soc_dai_link mioa701_dai[] = {
157 .name = "AC97 Aux", 157 .name = "AC97 Aux",
158 .stream_name = "AC97 Aux", 158 .stream_name = "AC97 Aux",
159 .cpu_dai_name = "pxa2xx-ac97-aux", 159 .cpu_dai_name = "pxa2xx-ac97-aux",
160 .codec_dai_name ="wm9713-aux", 160 .codec_dai_name = "wm9713-aux",
161 .codec_name = "wm9713-codec", 161 .codec_name = "wm9713-codec",
162 .platform_name = "pxa-pcm-audio", 162 .platform_name = "pxa-pcm-audio",
163 .ops = &mioa701_ops, 163 .ops = &mioa701_ops,
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 96df9b2d8fc4..5b5f1a442891 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -166,7 +166,6 @@ static void mmp_pcm_free_dma_buffers(struct snd_pcm *pcm)
166 buf->area = NULL; 166 buf->area = NULL;
167 } 167 }
168 168
169 return;
170} 169}
171 170
172static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream, 171static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index ca8b23f8c525..9cc35012e6e5 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -119,7 +119,6 @@ static void mmp_sspa_shutdown(struct snd_pcm_substream *substream,
119 clk_disable(priv->sspa->clk); 119 clk_disable(priv->sspa->clk);
120 clk_disable(priv->sysclk); 120 clk_disable(priv->sysclk);
121 121
122 return;
123} 122}
124 123
125/* 124/*
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index a879aba0691f..b6693f32fc02 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -129,7 +129,7 @@ static int poodle_hw_params(struct snd_pcm_substream *substream,
129 return 0; 129 return 0;
130} 130}
131 131
132static struct snd_soc_ops poodle_ops = { 132static const struct snd_soc_ops poodle_ops = {
133 .startup = poodle_startup, 133 .startup = poodle_startup,
134 .hw_params = poodle_hw_params, 134 .hw_params = poodle_hw_params,
135 .shutdown = poodle_shutdown, 135 .shutdown = poodle_shutdown,
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3cad990dad2c..0291c7cb64eb 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -354,6 +354,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
354 if (ssp->type == PXA3xx_SSP) { 354 if (ssp->type == PXA3xx_SSP) {
355 u32 val; 355 u32 val;
356 u64 tmp = 19968; 356 u64 tmp = 19968;
357
357 tmp *= 1000000; 358 tmp *= 1000000;
358 do_div(tmp, freq_out); 359 do_div(tmp, freq_out);
359 val = tmp; 360 val = tmp;
@@ -590,13 +591,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
590 591
591 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) { 592 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
592 /* This is a special case where the bitclk is 64fs 593 /* This is a special case where the bitclk is 64fs
593 * and we're not dealing with 2*32 bits of audio 594 * and we're not dealing with 2*32 bits of audio
594 * samples. 595 * samples.
595 * 596 *
596 * The SSP values used for that are all found out by 597 * The SSP values used for that are all found out by
597 * trying and failing a lot; some of the registers 598 * trying and failing a lot; some of the registers
598 * needed for that mode are only available on PXA3xx. 599 * needed for that mode are only available on PXA3xx.
599 */ 600 */
600 if (ssp->type != PXA3xx_SSP) 601 if (ssp->type != PXA3xx_SSP)
601 return -EINVAL; 602 return -EINVAL;
602 603
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 2e2fb1838ec2..f49bf02e5ec2 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -140,9 +140,8 @@ static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
140{ 140{
141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
142 return -ENODEV; 142 return -ENODEV;
143 else 143 snd_soc_dai_set_dma_data(cpu_dai, substream,
144 snd_soc_dai_set_dma_data(cpu_dai, substream, 144 &pxa2xx_ac97_pcm_mic_mono_in);
145 &pxa2xx_ac97_pcm_mic_mono_in);
146 145
147 return 0; 146 return 0;
148} 147}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 0389cf7b4b1e..3fb60baf6eab 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -46,10 +46,10 @@
46#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ 46#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
47#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ 47#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
48#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ 48#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
49#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ 49#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
50#define SACR0_ENB (1 << 0) /* Enable I2S Link */ 50#define SACR0_ENB (1 << 0) /* Enable I2S Link */
51#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ 51#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
52#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ 52#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
53#define SACR1_DREC (1 << 3) /* Disable Recording Function */ 53#define SACR1_DREC (1 << 3) /* Disable Recording Function */
54#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ 54#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
55 55
@@ -60,7 +60,7 @@
60#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ 60#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
61#define SASR0_BSY (1 << 2) /* I2S Busy */ 61#define SASR0_BSY (1 << 2) /* I2S Busy */
62#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ 62#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
63#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ 63#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
64 64
65#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ 65#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
66#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ 66#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
@@ -119,7 +119,7 @@ static int pxa_i2s_wait(void)
119 int i; 119 int i;
120 120
121 /* flush the Rx FIFO */ 121 /* flush the Rx FIFO */
122 for(i = 0; i < 16; i++) 122 for (i = 0; i < 16; i++)
123 SADR; 123 SADR;
124 return 0; 124 return 0;
125} 125}
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 410d48b93031..b51d7a0755d5 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -85,7 +85,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
85} 85}
86 86
87static struct snd_soc_platform_driver pxa2xx_soc_platform = { 87static struct snd_soc_platform_driver pxa2xx_soc_platform = {
88 .ops = &pxa2xx_pcm_ops, 88 .ops = &pxa2xx_pcm_ops,
89 .pcm_new = pxa2xx_soc_pcm_new, 89 .pcm_new = pxa2xx_soc_pcm_new,
90 .pcm_free = pxa2xx_pcm_free_dma_buffers, 90 .pcm_free = pxa2xx_pcm_free_dma_buffers,
91}; 91};
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 552b763005ed..111a907c4eb9 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -132,7 +132,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct snd_soc_ops raumfeld_cs4270_ops = { 135static const struct snd_soc_ops raumfeld_cs4270_ops = {
136 .startup = raumfeld_cs4270_startup, 136 .startup = raumfeld_cs4270_startup,
137 .shutdown = raumfeld_cs4270_shutdown, 137 .shutdown = raumfeld_cs4270_shutdown,
138 .hw_params = raumfeld_cs4270_hw_params, 138 .hw_params = raumfeld_cs4270_hw_params,
@@ -228,14 +228,12 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
228 .codec_name = "spi0.0", \ 228 .codec_name = "spi0.0", \
229} 229}
230 230
231static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = 231static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = {
232{
233 DAI_LINK_CS4270, 232 DAI_LINK_CS4270,
234 DAI_LINK_AK4104, 233 DAI_LINK_AK4104,
235}; 234};
236 235
237static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = 236static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = {
238{
239 DAI_LINK_CS4270, 237 DAI_LINK_CS4270,
240}; 238};
241 239
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 07d77cddac60..1671da648e95 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -156,7 +156,7 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
156 return 0; 156 return 0;
157} 157}
158 158
159static struct snd_soc_ops spitz_ops = { 159static const struct snd_soc_ops spitz_ops = {
160 .startup = spitz_startup, 160 .startup = spitz_startup,
161 .hw_params = spitz_hw_params, 161 .hw_params = spitz_hw_params,
162}; 162};
@@ -230,8 +230,8 @@ static const struct snd_soc_dapm_route spitz_audio_map[] = {
230 {"Headset Jack", NULL, "ROUT1"}, 230 {"Headset Jack", NULL, "ROUT1"},
231 231
232 /* ext speaker connected to LOUT2, ROUT2 */ 232 /* ext speaker connected to LOUT2, ROUT2 */
233 {"Ext Spk", NULL , "ROUT2"}, 233 {"Ext Spk", NULL, "ROUT2"},
234 {"Ext Spk", NULL , "LOUT2"}, 234 {"Ext Spk", NULL, "LOUT2"},
235 235
236 /* mic is connected to input 1 - with bias */ 236 /* mic is connected to input 1 - with bias */
237 {"LINPUT1", NULL, "Mic Bias"}, 237 {"LINPUT1", NULL, "Mic Bias"},
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index e022b2a777f6..ae9c12e1ea2a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -85,7 +85,7 @@ static int tosa_startup(struct snd_pcm_substream *substream)
85 return 0; 85 return 0;
86} 86}
87 87
88static struct snd_soc_ops tosa_ops = { 88static const struct snd_soc_ops tosa_ops = {
89 .startup = tosa_startup, 89 .startup = tosa_startup,
90}; 90};
91 91
@@ -133,7 +133,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
133static int tosa_hp_event(struct snd_soc_dapm_widget *w, 133static int tosa_hp_event(struct snd_soc_dapm_widget *w,
134 struct snd_kcontrol *k, int event) 134 struct snd_kcontrol *k, int event)
135{ 135{
136 gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0); 136 gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
137 return 0; 137 return 0;
138} 138}
139 139
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 990b1aa6d7f6..5b0eccd2b4dd 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -119,8 +119,8 @@ static const struct snd_soc_dapm_route z2_audio_map[] = {
119 {"Headphone Jack", NULL, "ROUT1"}, 119 {"Headphone Jack", NULL, "ROUT1"},
120 120
121 /* ext speaker connected to LOUT2, ROUT2 */ 121 /* ext speaker connected to LOUT2, ROUT2 */
122 {"Ext Spk", NULL , "ROUT2"}, 122 {"Ext Spk", NULL, "ROUT2"},
123 {"Ext Spk", NULL , "LOUT2"}, 123 {"Ext Spk", NULL, "LOUT2"},
124 124
125 /* mic is connected to R input 2 - with bias */ 125 /* mic is connected to R input 2 - with bias */
126 {"RINPUT2", NULL, "Mic Bias"}, 126 {"RINPUT2", NULL, "Mic Bias"},
@@ -152,7 +152,7 @@ err:
152 return ret; 152 return ret;
153} 153}
154 154
155static struct snd_soc_ops z2_ops = { 155static const struct snd_soc_ops z2_ops = {
156 .hw_params = z2_hw_params, 156 .hw_params = z2_hw_params,
157}; 157};
158 158
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 6fbcdf02c88d..ba468e560dd2 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -132,7 +132,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct snd_soc_ops zylonite_voice_ops = { 135static const struct snd_soc_ops zylonite_voice_ops = {
136 .hw_params = zylonite_voice_hw_params, 136 .hw_params = zylonite_voice_hw_params,
137}; 137};
138 138
diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
index 8aed72be3224..8a74844d99e2 100644
--- a/sound/soc/qcom/lpass-apq8016.c
+++ b/sound/soc/qcom/lpass-apq8016.c
@@ -231,6 +231,18 @@ static struct lpass_variant apq8016_data = {
231 .wrdma_channels = 2, 231 .wrdma_channels = 2,
232 .dai_driver = apq8016_lpass_cpu_dai_driver, 232 .dai_driver = apq8016_lpass_cpu_dai_driver,
233 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver), 233 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
234 .dai_osr_clk_names = (const char *[]) {
235 "mi2s-osr-clk0",
236 "mi2s-osr-clk1",
237 "mi2s-osr-clk2",
238 "mi2s-osr-clk3",
239 },
240 .dai_bit_clk_names = (const char *[]) {
241 "mi2s-bit-clk0",
242 "mi2s-bit-clk1",
243 "mi2s-bit-clk2",
244 "mi2s-bit-clk3",
245 },
234 .init = apq8016_lpass_init, 246 .init = apq8016_lpass_init,
235 .exit = apq8016_lpass_exit, 247 .exit = apq8016_lpass_exit,
236 .alloc_dma_channel = apq8016_lpass_alloc_dma_channel, 248 .alloc_dma_channel = apq8016_lpass_alloc_dma_channel,
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 5202a584e0c6..292b103abada 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -429,7 +429,6 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
429 struct lpass_variant *variant; 429 struct lpass_variant *variant;
430 struct device *dev = &pdev->dev; 430 struct device *dev = &pdev->dev;
431 const struct of_device_id *match; 431 const struct of_device_id *match;
432 char clk_name[16];
433 int ret, i, dai_id; 432 int ret, i, dai_id;
434 433
435 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0); 434 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
@@ -477,31 +476,24 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
477 476
478 for (i = 0; i < variant->num_dai; i++) { 477 for (i = 0; i < variant->num_dai; i++) {
479 dai_id = variant->dai_driver[i].id; 478 dai_id = variant->dai_driver[i].id;
480 if (variant->num_dai > 1)
481 sprintf(clk_name, "mi2s-osr-clk%d", i);
482 else
483 sprintf(clk_name, "mi2s-osr-clk");
484
485 drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev, 479 drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev,
486 clk_name); 480 variant->dai_osr_clk_names[i]);
487 if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) { 481 if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {
488 dev_warn(&pdev->dev, 482 dev_warn(&pdev->dev,
489 "error getting optional mi2s-osr-clk: %ld\n", 483 "%s() error getting optional %s: %ld\n",
484 __func__,
485 variant->dai_osr_clk_names[i],
490 PTR_ERR(drvdata->mi2s_osr_clk[dai_id])); 486 PTR_ERR(drvdata->mi2s_osr_clk[dai_id]));
491 487
492 drvdata->mi2s_osr_clk[dai_id] = NULL; 488 drvdata->mi2s_osr_clk[dai_id] = NULL;
493 } 489 }
494 490
495 if (variant->num_dai > 1)
496 sprintf(clk_name, "mi2s-bit-clk%d", i);
497 else
498 sprintf(clk_name, "mi2s-bit-clk");
499
500 drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev, 491 drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev,
501 clk_name); 492 variant->dai_bit_clk_names[i]);
502 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { 493 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
503 dev_err(&pdev->dev, 494 dev_err(&pdev->dev,
504 "error getting mi2s-bit-clk: %ld\n", 495 "error getting %s: %ld\n",
496 variant->dai_bit_clk_names[i],
505 PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); 497 PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
506 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); 498 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
507 } 499 }
diff --git a/sound/soc/qcom/lpass-ipq806x.c b/sound/soc/qcom/lpass-ipq806x.c
index 608c1a92af8a..ca1e1f2d2787 100644
--- a/sound/soc/qcom/lpass-ipq806x.c
+++ b/sound/soc/qcom/lpass-ipq806x.c
@@ -92,6 +92,12 @@ static struct lpass_variant ipq806x_data = {
92 .wrdma_channels = 4, 92 .wrdma_channels = 4,
93 .dai_driver = &ipq806x_lpass_cpu_dai_driver, 93 .dai_driver = &ipq806x_lpass_cpu_dai_driver,
94 .num_dai = 1, 94 .num_dai = 1,
95 .dai_osr_clk_names = (const char *[]) {
96 "mi2s-osr-clk",
97 },
98 .dai_bit_clk_names = (const char *[]) {
99 "mi2s-bit-clk",
100 },
95 .alloc_dma_channel = ipq806x_lpass_alloc_dma_channel, 101 .alloc_dma_channel = ipq806x_lpass_alloc_dma_channel,
96 .free_dma_channel = ipq806x_lpass_free_dma_channel, 102 .free_dma_channel = ipq806x_lpass_free_dma_channel,
97}; 103};
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 9b031352ea3c..b848db2d6c3d 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -91,6 +91,8 @@ struct lpass_variant {
91 /* SOC specific dais */ 91 /* SOC specific dais */
92 struct snd_soc_dai_driver *dai_driver; 92 struct snd_soc_dai_driver *dai_driver;
93 int num_dai; 93 int num_dai;
94 const char * const *dai_osr_clk_names;
95 const char * const *dai_bit_clk_names;
94}; 96};
95 97
96/* register the platform driver from the CPU DAI driver */ 98/* register the platform driver from the CPU DAI driver */
diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c
index b60abf322ce1..dbc53e48c52c 100644
--- a/sound/soc/rockchip/rk3288_hdmi_analog.c
+++ b/sound/soc/rockchip/rk3288_hdmi_analog.c
@@ -93,6 +93,9 @@ static int rk_hw_params(struct snd_pcm_substream *substream,
93 case 96000: 93 case 96000:
94 mclk = 12288000; 94 mclk = 12288000;
95 break; 95 break;
96 case 192000:
97 mclk = 24576000;
98 break;
96 case 11025: 99 case 11025:
97 case 22050: 100 case 22050:
98 case 44100: 101 case 44100:
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index f1f1d7959a1b..0520f5afd7cc 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -185,6 +185,14 @@ config SND_SOC_SNOW
185 Say Y if you want to add audio support for various Snow 185 Say Y if you want to add audio support for various Snow
186 boards based on Exynos5 series of SoCs. 186 boards based on Exynos5 series of SoCs.
187 187
188config SND_SOC_ODROID
189 tristate "Audio support for Odroid XU3/XU4"
190 depends on SND_SOC_SAMSUNG && I2C
191 select SND_SOC_MAX98090
192 select SND_SAMSUNG_I2S
193 help
194 Say Y here to enable audio support for the Odroid XU3/XU4.
195
188config SND_SOC_ARNDALE_RT5631_ALC5631 196config SND_SOC_ARNDALE_RT5631_ALC5631
189 tristate "Audio support for RT5631(ALC5631) on Arndale Board" 197 tristate "Audio support for RT5631(ALC5631) on Arndale Board"
190 depends on I2C 198 depends on I2C
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index b5df5e2e3d94..b6c2ee358333 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -40,6 +40,7 @@ snd-soc-tobermory-objs := tobermory.o
40snd-soc-lowland-objs := lowland.o 40snd-soc-lowland-objs := lowland.o
41snd-soc-littlemill-objs := littlemill.o 41snd-soc-littlemill-objs := littlemill.o
42snd-soc-bells-objs := bells.o 42snd-soc-bells-objs := bells.o
43snd-soc-odroid-objs := odroid.o
43snd-soc-arndale-rt5631-objs := arndale_rt5631.o 44snd-soc-arndale-rt5631-objs := arndale_rt5631.o
44snd-soc-tm2-wm5110-objs := tm2_wm5110.o 45snd-soc-tm2-wm5110-objs := tm2_wm5110.o
45 46
@@ -62,5 +63,6 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
62obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o 63obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
63obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o 64obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
64obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o 65obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
66obj-$(CONFIG_SND_SOC_ODROID) += snd-soc-odroid.o
65obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o 67obj-$(CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631) += snd-soc-arndale-rt5631.o
66obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) += snd-soc-tm2-wm5110.o 68obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) += snd-soc-tm2-wm5110.o
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index 3dd246fa0059..34deba461ae1 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -446,7 +446,6 @@ static struct snd_soc_card bells_cards[] = {
446 }, 446 },
447}; 447};
448 448
449
450static int bells_probe(struct platform_device *pdev) 449static int bells_probe(struct platform_device *pdev)
451{ 450{
452 int ret; 451 int ret;
diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h
index 9170c311d66e..fe6914005494 100644
--- a/sound/soc/samsung/i2s-regs.h
+++ b/sound/soc/samsung/i2s-regs.h
@@ -160,5 +160,3 @@
160#define I2SSIZE_SHIFT (16) 160#define I2SSIZE_SHIFT (16)
161 161
162#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */ 162#endif /* __SND_SOC_SAMSUNG_I2S_REGS_H */
163
164
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 52a47ed292a4..af3ba4d4ccc5 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1242,7 +1242,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1242 i2s_dai_data = (struct samsung_i2s_dai_data *) 1242 i2s_dai_data = (struct samsung_i2s_dai_data *)
1243 platform_get_device_id(pdev)->driver_data; 1243 platform_get_device_id(pdev)->driver_data;
1244 1244
1245
1246 pri_dai = i2s_alloc_dai(pdev, false); 1245 pri_dai = i2s_alloc_dai(pdev, false);
1247 if (!pri_dai) { 1246 if (!pri_dai) {
1248 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); 1247 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c
new file mode 100644
index 000000000000..0c0b00e40646
--- /dev/null
+++ b/sound/soc/samsung/odroid.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2017 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
10#include <linux/of.h>
11#include <linux/of_device.h>
12#include <linux/module.h>
13#include <sound/soc.h>
14#include <sound/pcm_params.h>
15#include "i2s.h"
16#include "i2s-regs.h"
17
18struct odroid_priv {
19 struct snd_soc_card card;
20 struct snd_soc_dai_link dai_link;
21
22 struct clk *pll;
23 struct clk *rclk;
24};
25
26static int odroid_card_startup(struct snd_pcm_substream *substream)
27{
28 struct snd_pcm_runtime *runtime = substream->runtime;
29
30 snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
31 return 0;
32}
33
34static int odroid_card_hw_params(struct snd_pcm_substream *substream,
35 struct snd_pcm_hw_params *params)
36{
37 struct snd_soc_pcm_runtime *rtd = substream->private_data;
38 struct odroid_priv *priv = snd_soc_card_get_drvdata(rtd->card);
39 unsigned int pll_freq, rclk_freq;
40 int ret;
41
42 switch (params_rate(params)) {
43 case 32000:
44 case 64000:
45 pll_freq = 131072000U;
46 break;
47 case 44100:
48 case 88200:
49 case 176400:
50 pll_freq = 180633600U;
51 break;
52 case 48000:
53 case 96000:
54 case 192000:
55 pll_freq = 196608000U;
56 break;
57 default:
58 return -EINVAL;
59 }
60
61 ret = clk_set_rate(priv->pll, pll_freq + 1);
62 if (ret < 0)
63 return ret;
64
65 rclk_freq = params_rate(params) * 256 * 4;
66
67 ret = clk_set_rate(priv->rclk, rclk_freq);
68 if (ret < 0)
69 return ret;
70
71 if (rtd->num_codecs > 1) {
72 struct snd_soc_dai *codec_dai = rtd->codec_dais[1];
73
74 ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk_freq,
75 SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78 }
79
80 return 0;
81}
82
83static const struct snd_soc_ops odroid_card_ops = {
84 .startup = odroid_card_startup,
85 .hw_params = odroid_card_hw_params,
86};
87
88static void odroid_put_codec_of_nodes(struct snd_soc_dai_link *link)
89{
90 struct snd_soc_dai_link_component *component = link->codecs;
91 int i;
92
93 for (i = 0; i < link->num_codecs; i++, component++) {
94 if (!component->of_node)
95 break;
96 of_node_put(component->of_node);
97 }
98}
99
100static int odroid_audio_probe(struct platform_device *pdev)
101{
102 struct device *dev = &pdev->dev;
103 struct device_node *cpu, *codec;
104 struct odroid_priv *priv;
105 struct snd_soc_dai_link *link;
106 struct snd_soc_card *card;
107 int ret;
108
109 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
110 if (!priv)
111 return -ENOMEM;
112
113 card = &priv->card;
114 card->dev = dev;
115
116 card->owner = THIS_MODULE;
117 card->fully_routed = true;
118
119 snd_soc_card_set_drvdata(card, priv);
120
121 priv->pll = devm_clk_get(dev, "epll");
122 if (IS_ERR(priv->pll))
123 return PTR_ERR(priv->pll);
124
125 priv->rclk = devm_clk_get(dev, "i2s_rclk");
126 if (IS_ERR(priv->rclk))
127 return PTR_ERR(priv->rclk);
128
129 ret = snd_soc_of_parse_card_name(card, "model");
130 if (ret < 0)
131 return ret;
132
133 if (of_property_read_bool(dev->of_node, "samsung,audio-widgets")) {
134 ret = snd_soc_of_parse_audio_simple_widgets(card,
135 "samsung,audio-widgets");
136 if (ret < 0)
137 return ret;
138 }
139
140 if (of_property_read_bool(dev->of_node, "samsung,audio-routing")) {
141 ret = snd_soc_of_parse_audio_routing(card,
142 "samsung,audio-routing");
143 if (ret < 0)
144 return ret;
145 }
146
147 link = &priv->dai_link;
148
149 link->ops = &odroid_card_ops;
150 link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
151 SND_SOC_DAIFMT_CBS_CFS;
152
153 card->dai_link = &priv->dai_link;
154 card->num_links = 1;
155
156 cpu = of_get_child_by_name(dev->of_node, "cpu");
157 codec = of_get_child_by_name(dev->of_node, "codec");
158
159 link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
160 if (!link->cpu_of_node) {
161 dev_err(dev, "Failed parsing cpu/sound-dai property\n");
162 return -EINVAL;
163 }
164
165 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
166 if (ret < 0)
167 goto err_put_codec_n;
168
169 link->platform_of_node = link->cpu_of_node;
170
171 link->name = "Primary";
172 link->stream_name = link->name;
173
174 ret = devm_snd_soc_register_card(dev, card);
175 if (ret < 0) {
176 dev_err(dev, "snd_soc_register_card() failed: %d\n", ret);
177 goto err_put_i2s_n;
178 }
179
180 return 0;
181
182err_put_i2s_n:
183 of_node_put(link->cpu_of_node);
184err_put_codec_n:
185 odroid_put_codec_of_nodes(link);
186 return ret;
187}
188
189static int odroid_audio_remove(struct platform_device *pdev)
190{
191 struct odroid_priv *priv = platform_get_drvdata(pdev);
192
193 of_node_put(priv->dai_link.cpu_of_node);
194 odroid_put_codec_of_nodes(&priv->dai_link);
195
196 return 0;
197}
198
199static const struct of_device_id odroid_audio_of_match[] = {
200 { .compatible = "samsung,odroid-xu3-audio" },
201 { .compatible = "samsung,odroid-xu4-audio"},
202 { },
203};
204MODULE_DEVICE_TABLE(of, odroid_audio_of_match);
205
206static struct platform_driver odroid_audio_driver = {
207 .driver = {
208 .name = "odroid-audio",
209 .of_match_table = odroid_audio_of_match,
210 .pm = &snd_soc_pm_ops,
211 },
212 .probe = odroid_audio_probe,
213 .remove = odroid_audio_remove,
214};
215module_platform_driver(odroid_audio_driver);
216
217MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
218MODULE_DESCRIPTION("Odroid XU3/XU4 audio support");
219MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 644f186fd35c..8f42deaa184b 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -72,7 +72,6 @@ static inline void dbg_showcon(const char *fn, u32 con)
72} 72}
73#endif 73#endif
74 74
75
76/* Turn on or off the transmission path. */ 75/* Turn on or off the transmission path. */
77static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) 76static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on)
78{ 77{
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 85a33ac0a5c4..66203d107a11 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -43,6 +43,7 @@ struct rsnd_adg {
43}; 43};
44 44
45#define LRCLK_ASYNC (1 << 0) 45#define LRCLK_ASYNC (1 << 0)
46#define AUDIO_OUT_48 (1 << 1)
46#define adg_mode_flags(adg) (adg->flags) 47#define adg_mode_flags(adg) (adg->flags)
47 48
48#define for_each_rsnd_clk(pos, adg, i) \ 49#define for_each_rsnd_clk(pos, adg, i) \
@@ -364,7 +365,10 @@ found_clock:
364 365
365 rsnd_adg_set_ssi_clk(ssi_mod, data); 366 rsnd_adg_set_ssi_clk(ssi_mod, data);
366 367
367 if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) { 368 if (adg_mode_flags(adg) & LRCLK_ASYNC) {
369 if (adg_mode_flags(adg) & AUDIO_OUT_48)
370 ckr = 0x80000000;
371 } else {
368 if (0 == (rate % 8000)) 372 if (0 == (rate % 8000))
369 ckr = 0x80000000; 373 ckr = 0x80000000;
370 } 374 }
@@ -427,11 +431,14 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
427 struct clk *clk; 431 struct clk *clk;
428 struct device *dev = rsnd_priv_to_dev(priv); 432 struct device *dev = rsnd_priv_to_dev(priv);
429 struct device_node *np = dev->of_node; 433 struct device_node *np = dev->of_node;
434 struct property *prop;
430 u32 ckr, rbgx, rbga, rbgb; 435 u32 ckr, rbgx, rbga, rbgb;
431 u32 rate, req_rate = 0, div; 436 u32 rate, div;
437#define REQ_SIZE 2
438 u32 req_rate[REQ_SIZE] = {};
432 uint32_t count = 0; 439 uint32_t count = 0;
433 unsigned long req_48kHz_rate, req_441kHz_rate; 440 unsigned long req_48kHz_rate, req_441kHz_rate;
434 int i; 441 int i, req_size;
435 const char *parent_clk_name = NULL; 442 const char *parent_clk_name = NULL;
436 static const char * const clkout_name[] = { 443 static const char * const clkout_name[] = {
437 [CLKOUT] = "audio_clkout", 444 [CLKOUT] = "audio_clkout",
@@ -446,19 +453,32 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
446 [CLKI] = 0x2, 453 [CLKI] = 0x2,
447 }; 454 };
448 455
449 of_property_read_u32(np, "#clock-cells", &count); 456 ckr = 0;
457 rbga = 2; /* default 1/6 */
458 rbgb = 2; /* default 1/6 */
450 459
451 /* 460 /*
452 * ADG supports BRRA/BRRB output only 461 * ADG supports BRRA/BRRB output only
453 * this means all clkout0/1/2/3 will be same rate 462 * this means all clkout0/1/2/3 will be same rate
454 */ 463 */
455 of_property_read_u32(np, "clock-frequency", &req_rate); 464 prop = of_find_property(np, "clock-frequency", NULL);
465 if (!prop)
466 goto rsnd_adg_get_clkout_end;
467
468 req_size = prop->length / sizeof(u32);
469
470 of_property_read_u32_array(np, "clock-frequency", req_rate, req_size);
456 req_48kHz_rate = 0; 471 req_48kHz_rate = 0;
457 req_441kHz_rate = 0; 472 req_441kHz_rate = 0;
458 if (0 == (req_rate % 44100)) 473 for (i = 0; i < req_size; i++) {
459 req_441kHz_rate = req_rate; 474 if (0 == (req_rate[i] % 44100))
460 if (0 == (req_rate % 48000)) 475 req_441kHz_rate = req_rate[i];
461 req_48kHz_rate = req_rate; 476 if (0 == (req_rate[i] % 48000))
477 req_48kHz_rate = req_rate[i];
478 }
479
480 if (req_rate[0] % 48000 == 0)
481 adg->flags = AUDIO_OUT_48;
462 482
463 /* 483 /*
464 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC 484 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
@@ -469,9 +489,6 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
469 * rsnd_adg_ssi_clk_try_start() 489 * rsnd_adg_ssi_clk_try_start()
470 * rsnd_ssi_master_clk_start() 490 * rsnd_ssi_master_clk_start()
471 */ 491 */
472 ckr = 0;
473 rbga = 2; /* default 1/6 */
474 rbgb = 2; /* default 1/6 */
475 adg->rbga_rate_for_441khz = 0; 492 adg->rbga_rate_for_441khz = 0;
476 adg->rbgb_rate_for_48khz = 0; 493 adg->rbgb_rate_for_48khz = 0;
477 for_each_rsnd_clk(clk, adg, i) { 494 for_each_rsnd_clk(clk, adg, i) {
@@ -505,10 +522,8 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
505 rbgb = rbgx; 522 rbgb = rbgx;
506 adg->rbgb_rate_for_48khz = rate / div; 523 adg->rbgb_rate_for_48khz = rate / div;
507 ckr |= brg_table[i] << 16; 524 ckr |= brg_table[i] << 16;
508 if (req_48kHz_rate) { 525 if (req_48kHz_rate)
509 parent_clk_name = __clk_get_name(clk); 526 parent_clk_name = __clk_get_name(clk);
510 ckr |= 0x80000000;
511 }
512 } 527 }
513 } 528 }
514 } 529 }
@@ -518,12 +533,13 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
518 * this means all clkout0/1/2/3 will be * same rate 533 * this means all clkout0/1/2/3 will be * same rate
519 */ 534 */
520 535
536 of_property_read_u32(np, "#clock-cells", &count);
521 /* 537 /*
522 * for clkout 538 * for clkout
523 */ 539 */
524 if (!count) { 540 if (!count) {
525 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], 541 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
526 parent_clk_name, 0, req_rate); 542 parent_clk_name, 0, req_rate[0]);
527 if (!IS_ERR(clk)) { 543 if (!IS_ERR(clk)) {
528 adg->clkout[CLKOUT] = clk; 544 adg->clkout[CLKOUT] = clk;
529 of_clk_add_provider(np, of_clk_src_simple_get, clk); 545 of_clk_add_provider(np, of_clk_src_simple_get, clk);
@@ -536,19 +552,18 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
536 for (i = 0; i < CLKOUTMAX; i++) { 552 for (i = 0; i < CLKOUTMAX; i++) {
537 clk = clk_register_fixed_rate(dev, clkout_name[i], 553 clk = clk_register_fixed_rate(dev, clkout_name[i],
538 parent_clk_name, 0, 554 parent_clk_name, 0,
539 req_rate); 555 req_rate[0]);
540 if (!IS_ERR(clk)) { 556 adg->clkout[i] = ERR_PTR(-ENOENT);
541 adg->onecell.clks = adg->clkout; 557 if (!IS_ERR(clk))
542 adg->onecell.clk_num = CLKOUTMAX;
543
544 adg->clkout[i] = clk; 558 adg->clkout[i] = clk;
545
546 of_clk_add_provider(np, of_clk_src_onecell_get,
547 &adg->onecell);
548 }
549 } 559 }
560 adg->onecell.clks = adg->clkout;
561 adg->onecell.clk_num = CLKOUTMAX;
562 of_clk_add_provider(np, of_clk_src_onecell_get,
563 &adg->onecell);
550 } 564 }
551 565
566rsnd_adg_get_clkout_end:
552 adg->ckr = ckr; 567 adg->ckr = ckr;
553 adg->rbga = rbga; 568 adg->rbga = rbga;
554 adg->rbgb = rbgb; 569 adg->rbgb = rbgb;
@@ -564,6 +579,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
564 struct rsnd_adg *adg; 579 struct rsnd_adg *adg;
565 struct device *dev = rsnd_priv_to_dev(priv); 580 struct device *dev = rsnd_priv_to_dev(priv);
566 struct device_node *np = dev->of_node; 581 struct device_node *np = dev->of_node;
582 int ret;
567 583
568 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 584 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
569 if (!adg) { 585 if (!adg) {
@@ -571,8 +587,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
571 return -ENOMEM; 587 return -ENOMEM;
572 } 588 }
573 589
574 rsnd_mod_init(priv, &adg->mod, &adg_ops, 590 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
575 NULL, NULL, 0, 0); 591 NULL, NULL, 0, 0);
592 if (ret)
593 return ret;
576 594
577 rsnd_adg_get_clkin(priv, adg); 595 rsnd_adg_get_clkin(priv, adg);
578 rsnd_adg_get_clkout(priv, adg); 596 rsnd_adg_get_clkout(priv, adg);
@@ -589,5 +607,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
589 607
590void rsnd_adg_remove(struct rsnd_priv *priv) 608void rsnd_adg_remove(struct rsnd_priv *priv)
591{ 609{
610 struct device *dev = rsnd_priv_to_dev(priv);
611 struct device_node *np = dev->of_node;
612
613 of_clk_del_provider(np);
614
592 rsnd_adg_clk_disable(priv); 615 rsnd_adg_clk_disable(priv);
593} 616}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 47b370cb2d3b..1744015408c3 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -96,7 +96,7 @@
96#include <linux/pm_runtime.h> 96#include <linux/pm_runtime.h>
97#include "rsnd.h" 97#include "rsnd.h"
98 98
99#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_192000
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 of_device_id rsnd_of_match[] = { 102static const struct of_device_id rsnd_of_match[] = {
@@ -110,7 +110,6 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
110/* 110/*
111 * rsnd_mod functions 111 * rsnd_mod functions
112 */ 112 */
113#ifdef DEBUG
114void 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)
115{ 114{
116 if (mod->type != type) { 115 if (mod->type != type) {
@@ -121,7 +120,6 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
121 rsnd_mod_name(mod), rsnd_mod_id(mod)); 120 rsnd_mod_name(mod), rsnd_mod_id(mod));
122 } 121 }
123} 122}
124#endif
125 123
126char *rsnd_mod_name(struct rsnd_mod *mod) 124char *rsnd_mod_name(struct rsnd_mod *mod)
127{ 125{
@@ -674,12 +672,10 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
674 /* set clock inversion */ 672 /* set clock inversion */
675 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 673 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
676 case SND_SOC_DAIFMT_NB_IF: 674 case SND_SOC_DAIFMT_NB_IF:
677 rdai->bit_clk_inv = rdai->bit_clk_inv;
678 rdai->frm_clk_inv = !rdai->frm_clk_inv; 675 rdai->frm_clk_inv = !rdai->frm_clk_inv;
679 break; 676 break;
680 case SND_SOC_DAIFMT_IB_NF: 677 case SND_SOC_DAIFMT_IB_NF:
681 rdai->bit_clk_inv = !rdai->bit_clk_inv; 678 rdai->bit_clk_inv = !rdai->bit_clk_inv;
682 rdai->frm_clk_inv = rdai->frm_clk_inv;
683 break; 679 break;
684 case SND_SOC_DAIFMT_IB_IF: 680 case SND_SOC_DAIFMT_IB_IF:
685 rdai->bit_clk_inv = !rdai->bit_clk_inv; 681 rdai->bit_clk_inv = !rdai->bit_clk_inv;
@@ -1002,13 +998,30 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
1002 return change; 998 return change;
1003} 999}
1004 1000
1005static int __rsnd_kctrl_new(struct rsnd_mod *mod, 1001struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg)
1006 struct rsnd_dai_stream *io, 1002{
1007 struct snd_soc_pcm_runtime *rtd, 1003 cfg->cfg.val = cfg->val;
1008 const unsigned char *name, 1004
1009 struct rsnd_kctrl_cfg *cfg, 1005 return &cfg->cfg;
1010 void (*update)(struct rsnd_dai_stream *io, 1006}
1011 struct rsnd_mod *mod)) 1007
1008struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg)
1009{
1010 cfg->cfg.val = &cfg->val;
1011
1012 return &cfg->cfg;
1013}
1014
1015int rsnd_kctrl_new(struct rsnd_mod *mod,
1016 struct rsnd_dai_stream *io,
1017 struct snd_soc_pcm_runtime *rtd,
1018 const unsigned char *name,
1019 void (*update)(struct rsnd_dai_stream *io,
1020 struct rsnd_mod *mod),
1021 struct rsnd_kctrl_cfg *cfg,
1022 const char * const *texts,
1023 int size,
1024 u32 max)
1012{ 1025{
1013 struct snd_card *card = rtd->card->snd_card; 1026 struct snd_card *card = rtd->card->snd_card;
1014 struct snd_kcontrol *kctrl; 1027 struct snd_kcontrol *kctrl;
@@ -1023,6 +1036,9 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1023 }; 1036 };
1024 int ret; 1037 int ret;
1025 1038
1039 if (size > RSND_MAX_CHANNELS)
1040 return -EINVAL;
1041
1026 kctrl = snd_ctl_new1(&knew, mod); 1042 kctrl = snd_ctl_new1(&knew, mod);
1027 if (!kctrl) 1043 if (!kctrl)
1028 return -ENOMEM; 1044 return -ENOMEM;
@@ -1031,74 +1047,17 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
1031 if (ret < 0) 1047 if (ret < 0)
1032 return ret; 1048 return ret;
1033 1049
1034 cfg->update = update; 1050 cfg->texts = texts;
1035 cfg->card = card; 1051 cfg->max = max;
1036 cfg->kctrl = kctrl; 1052 cfg->size = size;
1037 cfg->io = io; 1053 cfg->update = update;
1054 cfg->card = card;
1055 cfg->kctrl = kctrl;
1056 cfg->io = io;
1038 1057
1039 return 0; 1058 return 0;
1040} 1059}
1041 1060
1042void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg)
1043{
1044 if (cfg->card && cfg->kctrl)
1045 snd_ctl_remove(cfg->card, cfg->kctrl);
1046
1047 cfg->card = NULL;
1048 cfg->kctrl = NULL;
1049}
1050
1051int rsnd_kctrl_new_m(struct rsnd_mod *mod,
1052 struct rsnd_dai_stream *io,
1053 struct snd_soc_pcm_runtime *rtd,
1054 const unsigned char *name,
1055 void (*update)(struct rsnd_dai_stream *io,
1056 struct rsnd_mod *mod),
1057 struct rsnd_kctrl_cfg_m *_cfg,
1058 int ch_size,
1059 u32 max)
1060{
1061 if (ch_size > RSND_MAX_CHANNELS)
1062 return -EINVAL;
1063
1064 _cfg->cfg.max = max;
1065 _cfg->cfg.size = ch_size;
1066 _cfg->cfg.val = _cfg->val;
1067 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1068}
1069
1070int rsnd_kctrl_new_s(struct rsnd_mod *mod,
1071 struct rsnd_dai_stream *io,
1072 struct snd_soc_pcm_runtime *rtd,
1073 const unsigned char *name,
1074 void (*update)(struct rsnd_dai_stream *io,
1075 struct rsnd_mod *mod),
1076 struct rsnd_kctrl_cfg_s *_cfg,
1077 u32 max)
1078{
1079 _cfg->cfg.max = max;
1080 _cfg->cfg.size = 1;
1081 _cfg->cfg.val = &_cfg->val;
1082 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1083}
1084
1085int rsnd_kctrl_new_e(struct rsnd_mod *mod,
1086 struct rsnd_dai_stream *io,
1087 struct snd_soc_pcm_runtime *rtd,
1088 const unsigned char *name,
1089 struct rsnd_kctrl_cfg_s *_cfg,
1090 void (*update)(struct rsnd_dai_stream *io,
1091 struct rsnd_mod *mod),
1092 const char * const *texts,
1093 u32 max)
1094{
1095 _cfg->cfg.max = max;
1096 _cfg->cfg.size = 1;
1097 _cfg->cfg.val = &_cfg->val;
1098 _cfg->cfg.texts = texts;
1099 return __rsnd_kctrl_new(mod, io, rtd, name, &_cfg->cfg, update);
1100}
1101
1102/* 1061/*
1103 * snd_soc_platform 1062 * snd_soc_platform
1104 */ 1063 */
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index cf8f59cdd8d7..463de8360985 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -218,21 +218,6 @@ static int rsnd_dvc_probe_(struct rsnd_mod *mod,
218 return rsnd_cmd_attach(io, rsnd_mod_id(mod)); 218 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
219} 219}
220 220
221static int rsnd_dvc_remove_(struct rsnd_mod *mod,
222 struct rsnd_dai_stream *io,
223 struct rsnd_priv *priv)
224{
225 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
226
227 rsnd_kctrl_remove(dvc->volume);
228 rsnd_kctrl_remove(dvc->mute);
229 rsnd_kctrl_remove(dvc->ren);
230 rsnd_kctrl_remove(dvc->rup);
231 rsnd_kctrl_remove(dvc->rdown);
232
233 return 0;
234}
235
236static int rsnd_dvc_init(struct rsnd_mod *mod, 221static int rsnd_dvc_init(struct rsnd_mod *mod,
237 struct rsnd_dai_stream *io, 222 struct rsnd_dai_stream *io,
238 struct rsnd_priv *priv) 223 struct rsnd_priv *priv)
@@ -300,18 +285,18 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
300 ret = rsnd_kctrl_new_e(mod, io, rtd, 285 ret = rsnd_kctrl_new_e(mod, io, rtd,
301 is_play ? 286 is_play ?
302 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", 287 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
303 &dvc->rup,
304 rsnd_dvc_volume_update, 288 rsnd_dvc_volume_update,
305 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 289 &dvc->rup,
290 dvc_ramp_rate);
306 if (ret < 0) 291 if (ret < 0)
307 return ret; 292 return ret;
308 293
309 ret = rsnd_kctrl_new_e(mod, io, rtd, 294 ret = rsnd_kctrl_new_e(mod, io, rtd,
310 is_play ? 295 is_play ?
311 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", 296 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
312 &dvc->rdown,
313 rsnd_dvc_volume_update, 297 rsnd_dvc_volume_update,
314 dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate)); 298 &dvc->rdown,
299 dvc_ramp_rate);
315 300
316 if (ret < 0) 301 if (ret < 0)
317 return ret; 302 return ret;
@@ -332,7 +317,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
332 .name = DVC_NAME, 317 .name = DVC_NAME,
333 .dma_req = rsnd_dvc_dma_req, 318 .dma_req = rsnd_dvc_dma_req,
334 .probe = rsnd_dvc_probe_, 319 .probe = rsnd_dvc_probe_,
335 .remove = rsnd_dvc_remove_,
336 .init = rsnd_dvc_init, 320 .init = rsnd_dvc_init,
337 .quit = rsnd_dvc_quit, 321 .quit = rsnd_dvc_quit,
338 .pcm_new = rsnd_dvc_pcm_new, 322 .pcm_new = rsnd_dvc_pcm_new,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 7410ec0174db..dbf4163427e8 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -611,35 +611,30 @@ struct rsnd_kctrl_cfg_s {
611 u32 val; 611 u32 val;
612}; 612};
613 613
614void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); 614struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg);
615#define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) 615struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg);
616 616int rsnd_kctrl_new(struct rsnd_mod *mod,
617int rsnd_kctrl_new_m(struct rsnd_mod *mod, 617 struct rsnd_dai_stream *io,
618 struct rsnd_dai_stream *io, 618 struct snd_soc_pcm_runtime *rtd,
619 struct snd_soc_pcm_runtime *rtd, 619 const unsigned char *name,
620 const unsigned char *name, 620 void (*update)(struct rsnd_dai_stream *io,
621 void (*update)(struct rsnd_dai_stream *io, 621 struct rsnd_mod *mod),
622 struct rsnd_mod *mod), 622 struct rsnd_kctrl_cfg *cfg,
623 struct rsnd_kctrl_cfg_m *_cfg, 623 const char * const *texts,
624 int ch_size, 624 int size,
625 u32 max); 625 u32 max);
626int rsnd_kctrl_new_s(struct rsnd_mod *mod, 626
627 struct rsnd_dai_stream *io, 627#define rsnd_kctrl_new_m(mod, io, rtd, name, update, cfg, size, max) \
628 struct snd_soc_pcm_runtime *rtd, 628 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_m(cfg), \
629 const unsigned char *name, 629 NULL, size, max)
630 void (*update)(struct rsnd_dai_stream *io, 630
631 struct rsnd_mod *mod), 631#define rsnd_kctrl_new_s(mod, io, rtd, name, update, cfg, max) \
632 struct rsnd_kctrl_cfg_s *_cfg, 632 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \
633 u32 max); 633 NULL, 1, max)
634int rsnd_kctrl_new_e(struct rsnd_mod *mod, 634
635 struct rsnd_dai_stream *io, 635#define rsnd_kctrl_new_e(mod, io, rtd, name, update, cfg, texts) \
636 struct snd_soc_pcm_runtime *rtd, 636 rsnd_kctrl_new(mod, io, rtd, name, update, rsnd_kctrl_init_s(cfg), \
637 const unsigned char *name, 637 texts, 1, ARRAY_SIZE(texts))
638 struct rsnd_kctrl_cfg_s *_cfg,
639 void (*update)(struct rsnd_dai_stream *io,
640 struct rsnd_mod *mod),
641 const char * const *texts,
642 u32 max);
643 638
644/* 639/*
645 * R-Car SSI 640 * R-Car SSI
@@ -732,8 +727,8 @@ void rsnd_cmd_remove(struct rsnd_priv *priv);
732int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); 727int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
733struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); 728struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id);
734 729
735#ifdef DEBUG
736void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 730void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
731#ifdef DEBUG
737#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) 732#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
738#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC) 733#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
739#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC) 734#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 42db48db09ba..20b5b2ec625e 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -167,6 +167,7 @@ static int rsnd_src_hw_params(struct rsnd_mod *mod,
167 * dpcm_fe_dai_hw_params() 167 * dpcm_fe_dai_hw_params()
168 * dpcm_be_dai_hw_params() 168 * dpcm_be_dai_hw_params()
169 */ 169 */
170 src->convert_rate = 0;
170 if (fe->dai_link->dynamic) { 171 if (fe->dai_link->dynamic) {
171 int stream = substream->stream; 172 int stream = substream->stream;
172 struct snd_soc_dpcm *dpcm; 173 struct snd_soc_dpcm *dpcm;
@@ -414,8 +415,6 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
414 415
415 rsnd_mod_power_off(mod); 416 rsnd_mod_power_off(mod);
416 417
417 src->convert_rate = 0;
418
419 /* reset sync convert_rate */ 418 /* reset sync convert_rate */
420 src->sync.val = 0; 419 src->sync.val = 0;
421 420
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 411bda2387ad..135c5669f796 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -228,6 +228,15 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
228 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { 228 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
229 229
230 /* 230 /*
231 * It will set SSIWSR.CONT here, but SSICR.CKDV = 000
232 * with it is not allowed. (SSIWSR.WS_MODE with
233 * SSICR.CKDV = 000 is not allowed either).
234 * Skip it. See SSICR.CKDV
235 */
236 if (j == 0)
237 continue;
238
239 /*
231 * this driver is assuming that 240 * this driver is assuming that
232 * system word is 32bit x chan 241 * system word is 32bit x chan
233 * see rsnd_ssi_init() 242 * see rsnd_ssi_init()
diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c
index 3f2cce03275c..be066de74aaa 100644
--- a/sound/soc/sirf/sirf-audio-port.c
+++ b/sound/soc/sirf/sirf-audio-port.c
@@ -19,6 +19,7 @@ struct sirf_audio_port {
19static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) 19static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
20{ 20{
21 struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); 21 struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai);
22
22 snd_soc_dai_init_dma_data(dai, &port->playback_dma_data, 23 snd_soc_dai_init_dma_data(dai, &port->playback_dma_data,
23 &port->capture_dma_data); 24 &port->capture_dma_data);
24 return 0; 25 return 0;
diff --git a/sound/soc/sirf/sirf-audio.c b/sound/soc/sirf/sirf-audio.c
index 94ea152e0362..f2bc50790f76 100644
--- a/sound/soc/sirf/sirf-audio.c
+++ b/sound/soc/sirf/sirf-audio.c
@@ -27,6 +27,7 @@ static int sirf_audio_hp_event(struct snd_soc_dapm_widget *w,
27 struct snd_soc_card *card = dapm->card; 27 struct snd_soc_card *card = dapm->card;
28 struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card); 28 struct sirf_audio_card *sirf_audio_card = snd_soc_card_get_drvdata(card);
29 int on = !SND_SOC_DAPM_EVENT_OFF(event); 29 int on = !SND_SOC_DAPM_EVENT_OFF(event);
30
30 if (gpio_is_valid(sirf_audio_card->gpio_hp_pa)) 31 if (gpio_is_valid(sirf_audio_card->gpio_hp_pa))
31 gpio_set_value(sirf_audio_card->gpio_hp_pa, on); 32 gpio_set_value(sirf_audio_card->gpio_hp_pa, on);
32 return 0; 33 return 0;
diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 45fc06c0e0e5..77e7dcf969d0 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -71,6 +71,7 @@ static void sirf_usp_rx_disable(struct sirf_usp *usp)
71static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai) 71static int sirf_usp_pcm_dai_probe(struct snd_soc_dai *dai)
72{ 72{
73 struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai); 73 struct sirf_usp *usp = snd_soc_dai_get_drvdata(dai);
74
74 snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data, 75 snd_soc_dai_init_dma_data(dai, &usp->playback_dma_data,
75 &usp->capture_dma_data); 76 &usp->capture_dma_data);
76 return 0; 77 return 0;
@@ -294,6 +295,7 @@ static struct snd_soc_dai_driver sirf_usp_pcm_dai = {
294static int sirf_usp_pcm_runtime_suspend(struct device *dev) 295static int sirf_usp_pcm_runtime_suspend(struct device *dev)
295{ 296{
296 struct sirf_usp *usp = dev_get_drvdata(dev); 297 struct sirf_usp *usp = dev_get_drvdata(dev);
298
297 clk_disable_unprepare(usp->clk); 299 clk_disable_unprepare(usp->clk);
298 return 0; 300 return 0;
299} 301}
@@ -302,6 +304,7 @@ static int sirf_usp_pcm_runtime_resume(struct device *dev)
302{ 304{
303 struct sirf_usp *usp = dev_get_drvdata(dev); 305 struct sirf_usp *usp = dev_get_drvdata(dev);
304 int ret; 306 int ret;
307
305 ret = clk_prepare_enable(usp->clk); 308 ret = clk_prepare_enable(usp->clk);
306 if (ret) { 309 if (ret) {
307 dev_err(dev, "clk_enable failed: %d\n", ret); 310 dev_err(dev, "clk_enable failed: %d\n", ret);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2722bb0c5573..525f2f397b4c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1776,7 +1776,6 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1776 } 1776 }
1777 1777
1778 component->init = aux_dev->init; 1778 component->init = aux_dev->init;
1779 component->auxiliary = 1;
1780 list_add(&component->card_aux_list, &card->aux_comp_list); 1779 list_add(&component->card_aux_list, &card->aux_comp_list);
1781 1780
1782 return 0; 1781 return 0;
@@ -1788,14 +1787,13 @@ err_defer:
1788 1787
1789static int soc_probe_aux_devices(struct snd_soc_card *card) 1788static int soc_probe_aux_devices(struct snd_soc_card *card)
1790{ 1789{
1791 struct snd_soc_component *comp, *tmp; 1790 struct snd_soc_component *comp;
1792 int order; 1791 int order;
1793 int ret; 1792 int ret;
1794 1793
1795 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1794 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1796 order++) { 1795 order++) {
1797 list_for_each_entry_safe(comp, tmp, &card->aux_comp_list, 1796 list_for_each_entry(comp, &card->aux_comp_list, card_aux_list) {
1798 card_aux_list) {
1799 if (comp->driver->probe_order == order) { 1797 if (comp->driver->probe_order == order) {
1800 ret = soc_probe_component(card, comp); 1798 ret = soc_probe_component(card, comp);
1801 if (ret < 0) { 1799 if (ret < 0) {
@@ -1804,7 +1802,6 @@ static int soc_probe_aux_devices(struct snd_soc_card *card)
1804 comp->name, ret); 1802 comp->name, ret);
1805 return ret; 1803 return ret;
1806 } 1804 }
1807 list_del(&comp->card_aux_list);
1808 } 1805 }
1809 } 1806 }
1810 } 1807 }
@@ -1820,14 +1817,12 @@ static void soc_remove_aux_devices(struct snd_soc_card *card)
1820 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1817 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1821 order++) { 1818 order++) {
1822 list_for_each_entry_safe(comp, _comp, 1819 list_for_each_entry_safe(comp, _comp,
1823 &card->component_dev_list, card_list) { 1820 &card->aux_comp_list, card_aux_list) {
1824
1825 if (!comp->auxiliary)
1826 continue;
1827 1821
1828 if (comp->driver->remove_order == order) { 1822 if (comp->driver->remove_order == order) {
1829 soc_remove_component(comp); 1823 soc_remove_component(comp);
1830 comp->auxiliary = 0; 1824 /* remove it from the card's aux_comp_list */
1825 list_del(&comp->card_aux_list);
1831 } 1826 }
1832 } 1827 }
1833 } 1828 }
@@ -1918,6 +1913,7 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
1918EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt); 1913EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
1919 1914
1920 1915
1916#ifdef CONFIG_DMI
1921/* Trim special characters, and replace '-' with '_' since '-' is used to 1917/* Trim special characters, and replace '-' with '_' since '-' is used to
1922 * separate different DMI fields in the card long name. Only number and 1918 * separate different DMI fields in the card long name. Only number and
1923 * alphabet characters and a few separator characters are kept. 1919 * alphabet characters and a few separator characters are kept.
@@ -2049,6 +2045,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
2049 return 0; 2045 return 0;
2050} 2046}
2051EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name); 2047EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
2048#endif /* CONFIG_DMI */
2052 2049
2053static int snd_soc_instantiate_card(struct snd_soc_card *card) 2050static int snd_soc_instantiate_card(struct snd_soc_card *card)
2054{ 2051{
@@ -2190,6 +2187,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
2190 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 2187 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
2191 card->num_of_dapm_routes); 2188 card->num_of_dapm_routes);
2192 2189
2190 /* try to set some sane longname if DMI is available */
2191 snd_soc_set_dmi_name(card, NULL);
2192
2193 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 2193 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
2194 "%s", card->name); 2194 "%s", card->name);
2195 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 2195 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -3139,7 +3139,7 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
3139 component->suspend = component->driver->suspend; 3139 component->suspend = component->driver->suspend;
3140 component->resume = component->driver->resume; 3140 component->resume = component->driver->resume;
3141 component->pcm_new = component->driver->pcm_new; 3141 component->pcm_new = component->driver->pcm_new;
3142 component->pcm_free= component->driver->pcm_free; 3142 component->pcm_free = component->driver->pcm_free;
3143 3143
3144 dapm = &component->dapm; 3144 dapm = &component->dapm;
3145 dapm->dev = dev; 3145 dapm->dev = dev;
@@ -3240,6 +3240,11 @@ static void snd_soc_component_cleanup(struct snd_soc_component *component)
3240 3240
3241static void snd_soc_component_del_unlocked(struct snd_soc_component *component) 3241static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
3242{ 3242{
3243 struct snd_soc_card *card = component->card;
3244
3245 if (card)
3246 snd_soc_unregister_card(card);
3247
3243 list_del(&component->list); 3248 list_del(&component->list);
3244} 3249}
3245 3250
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fbaa1bb41102..7daf21fee355 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -19,9 +19,28 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/suspend.h>
22#include <trace/events/asoc.h> 23#include <trace/events/asoc.h>
23 24
24/** 25/**
26 * snd_soc_codec_set_jack - configure codec jack.
27 * @codec: CODEC
28 * @jack: structure to use for the jack
29 * @data: can be used if codec driver need extra data for configuring jack
30 *
31 * Configures and enables jack detection function.
32 */
33int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
34 struct snd_soc_jack *jack, void *data)
35{
36 if (codec->driver->set_jack)
37 return codec->driver->set_jack(codec, jack, data);
38 else
39 return -EINVAL;
40}
41EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack);
42
43/**
25 * snd_soc_card_jack_new - Create a new jack 44 * snd_soc_card_jack_new - Create a new jack
26 * @card: ASoC card 45 * @card: ASoC card
27 * @id: an identifying string for this jack 46 * @id: an identifying string for this jack
@@ -293,6 +312,27 @@ static void gpio_work(struct work_struct *work)
293 snd_soc_jack_gpio_detect(gpio); 312 snd_soc_jack_gpio_detect(gpio);
294} 313}
295 314
315static int snd_soc_jack_pm_notifier(struct notifier_block *nb,
316 unsigned long action, void *data)
317{
318 struct snd_soc_jack_gpio *gpio =
319 container_of(nb, struct snd_soc_jack_gpio, pm_notifier);
320
321 switch (action) {
322 case PM_POST_SUSPEND:
323 case PM_POST_HIBERNATION:
324 case PM_POST_RESTORE:
325 /*
326 * Use workqueue so we do not have to care about running
327 * concurrently with work triggered by the interrupt handler.
328 */
329 queue_delayed_work(system_power_efficient_wq, &gpio->work, 0);
330 break;
331 }
332
333 return NOTIFY_DONE;
334}
335
296/** 336/**
297 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack 337 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
298 * 338 *
@@ -369,6 +409,13 @@ got_gpio:
369 i, ret); 409 i, ret);
370 } 410 }
371 411
412 /*
413 * Register PM notifier so we do not miss state transitions
414 * happening while system is asleep.
415 */
416 gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier;
417 register_pm_notifier(&gpios[i].pm_notifier);
418
372 /* Expose GPIO value over sysfs for diagnostic purposes */ 419 /* Expose GPIO value over sysfs for diagnostic purposes */
373 gpiod_export(gpios[i].desc, false); 420 gpiod_export(gpios[i].desc, false);
374 421
@@ -428,6 +475,7 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
428 475
429 for (i = 0; i < count; i++) { 476 for (i = 0; i < count; i++) {
430 gpiod_unexport(gpios[i].desc); 477 gpiod_unexport(gpios[i].desc);
478 unregister_pm_notifier(&gpios[i].pm_notifier);
431 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); 479 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
432 cancel_delayed_work_sync(&gpios[i].work); 480 cancel_delayed_work_sync(&gpios[i].work);
433 gpiod_put(gpios[i].desc); 481 gpiod_put(gpios[i].desc);
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 058bc99c6c34..002772e3ba2c 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -495,12 +495,13 @@ static void remove_widget(struct snd_soc_component *comp,
495 struct snd_kcontrol *kcontrol = w->kcontrols[i]; 495 struct snd_kcontrol *kcontrol = w->kcontrols[i];
496 struct soc_enum *se = 496 struct soc_enum *se =
497 (struct soc_enum *)kcontrol->private_value; 497 (struct soc_enum *)kcontrol->private_value;
498 int j;
498 499
499 snd_ctl_remove(card, kcontrol); 500 snd_ctl_remove(card, kcontrol);
500 501
501 kfree(se->dobj.control.dvalues); 502 kfree(se->dobj.control.dvalues);
502 for (i = 0; i < se->items; i++) 503 for (j = 0; j < se->items; j++)
503 kfree(se->dobj.control.dtexts[i]); 504 kfree(se->dobj.control.dtexts[j]);
504 505
505 kfree(se); 506 kfree(se);
506 } 507 }
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index d7e8dd46d2cc..d8b6936e544e 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -1074,7 +1074,7 @@ int uni_player_init(struct platform_device *pdev,
1074 player->clk = of_clk_get(pdev->dev.of_node, 0); 1074 player->clk = of_clk_get(pdev->dev.of_node, 0);
1075 if (IS_ERR(player->clk)) { 1075 if (IS_ERR(player->clk)) {
1076 dev_err(player->dev, "Failed to get clock\n"); 1076 dev_err(player->dev, "Failed to get clock\n");
1077 ret = PTR_ERR(player->clk); 1077 return PTR_ERR(player->clk);
1078 } 1078 }
1079 1079
1080 /* Select the frequency synthesizer clock */ 1080 /* Select the frequency synthesizer clock */
diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
new file mode 100644
index 000000000000..972970f0890a
--- /dev/null
+++ b/sound/soc/stm/Kconfig
@@ -0,0 +1,8 @@
1menuconfig SND_SOC_STM32
2 tristate "STMicroelectronics STM32 SOC audio support"
3 depends on ARCH_STM32 || COMPILE_TEST
4 depends on SND_SOC
5 select SND_SOC_GENERIC_DMAENGINE_PCM
6 select REGMAP_MMIO
7 help
8 Say Y if you want to enable ASoC-support for STM32
diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile
new file mode 100644
index 000000000000..e466a4759698
--- /dev/null
+++ b/sound/soc/stm/Makefile
@@ -0,0 +1,6 @@
1# SAI
2snd-soc-stm32-sai-sub-objs := stm32_sai_sub.o
3obj-$(CONFIG_SND_SOC_STM32) += snd-soc-stm32-sai-sub.o
4
5snd-soc-stm32-sai-objs := stm32_sai.o
6obj-$(CONFIG_SND_SOC_STM32) += snd-soc-stm32-sai.o
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
new file mode 100644
index 000000000000..2a27a26bf7a1
--- /dev/null
+++ b/sound/soc/stm/stm32_sai.c
@@ -0,0 +1,115 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19#include <linux/clk.h>
20#include <linux/delay.h>
21#include <linux/module.h>
22#include <linux/of_platform.h>
23#include <linux/reset.h>
24
25#include <sound/dmaengine_pcm.h>
26#include <sound/core.h>
27
28#include "stm32_sai.h"
29
30static const struct of_device_id stm32_sai_ids[] = {
31 { .compatible = "st,stm32f4-sai", .data = (void *)SAI_STM32F4 },
32 {}
33};
34
35static int stm32_sai_probe(struct platform_device *pdev)
36{
37 struct device_node *np = pdev->dev.of_node;
38 struct stm32_sai_data *sai;
39 struct reset_control *rst;
40 struct resource *res;
41 void __iomem *base;
42 const struct of_device_id *of_id;
43
44 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
45 if (!sai)
46 return -ENOMEM;
47
48 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
49 base = devm_ioremap_resource(&pdev->dev, res);
50 if (IS_ERR(base))
51 return PTR_ERR(base);
52
53 of_id = of_match_device(stm32_sai_ids, &pdev->dev);
54 if (of_id)
55 sai->version = (enum stm32_sai_version)of_id->data;
56 else
57 return -EINVAL;
58
59 sai->clk_x8k = devm_clk_get(&pdev->dev, "x8k");
60 if (IS_ERR(sai->clk_x8k)) {
61 dev_err(&pdev->dev, "missing x8k parent clock\n");
62 return PTR_ERR(sai->clk_x8k);
63 }
64
65 sai->clk_x11k = devm_clk_get(&pdev->dev, "x11k");
66 if (IS_ERR(sai->clk_x11k)) {
67 dev_err(&pdev->dev, "missing x11k parent clock\n");
68 return PTR_ERR(sai->clk_x11k);
69 }
70
71 /* init irqs */
72 sai->irq = platform_get_irq(pdev, 0);
73 if (sai->irq < 0) {
74 dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
75 return sai->irq;
76 }
77
78 /* reset */
79 rst = reset_control_get(&pdev->dev, NULL);
80 if (!IS_ERR(rst)) {
81 reset_control_assert(rst);
82 udelay(2);
83 reset_control_deassert(rst);
84 }
85
86 sai->pdev = pdev;
87 platform_set_drvdata(pdev, sai);
88
89 return of_platform_populate(np, NULL, NULL, &pdev->dev);
90}
91
92static int stm32_sai_remove(struct platform_device *pdev)
93{
94 of_platform_depopulate(&pdev->dev);
95
96 return 0;
97}
98
99MODULE_DEVICE_TABLE(of, stm32_sai_ids);
100
101static struct platform_driver stm32_sai_driver = {
102 .driver = {
103 .name = "st,stm32-sai",
104 .of_match_table = stm32_sai_ids,
105 },
106 .probe = stm32_sai_probe,
107 .remove = stm32_sai_remove,
108};
109
110module_platform_driver(stm32_sai_driver);
111
112MODULE_DESCRIPTION("STM32 Soc SAI Interface");
113MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>");
114MODULE_ALIAS("platform:st,stm32-sai");
115MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/stm/stm32_sai.h b/sound/soc/stm/stm32_sai.h
new file mode 100644
index 000000000000..a801fda5066f
--- /dev/null
+++ b/sound/soc/stm/stm32_sai.h
@@ -0,0 +1,200 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19/******************** SAI Register Map **************************************/
20
21/* common register */
22#define STM_SAI_GCR 0x00
23
24/* Sub-block A&B registers offsets, relative to A&B sub-block addresses */
25#define STM_SAI_CR1_REGX 0x00 /* A offset: 0x04. B offset: 0x24 */
26#define STM_SAI_CR2_REGX 0x04
27#define STM_SAI_FRCR_REGX 0x08
28#define STM_SAI_SLOTR_REGX 0x0C
29#define STM_SAI_IMR_REGX 0x10
30#define STM_SAI_SR_REGX 0x14
31#define STM_SAI_CLRFR_REGX 0x18
32#define STM_SAI_DR_REGX 0x1C
33
34/******************** Bit definition for SAI_GCR register *******************/
35#define SAI_GCR_SYNCIN_SHIFT 0
36#define SAI_GCR_SYNCIN_MASK GENMASK(1, SAI_GCR_SYNCIN_SHIFT)
37#define SAI_GCR_SYNCIN_SET(x) ((x) << SAI_GCR_SYNCIN_SHIFT)
38
39#define SAI_GCR_SYNCOUT_SHIFT 4
40#define SAI_GCR_SYNCOUT_MASK GENMASK(5, SAI_GCR_SYNCOUT_SHIFT)
41#define SAI_GCR_SYNCOUT_SET(x) ((x) << SAI_GCR_SYNCOUT_SHIFT)
42
43/******************* Bit definition for SAI_XCR1 register *******************/
44#define SAI_XCR1_RX_TX_SHIFT 0
45#define SAI_XCR1_RX_TX BIT(SAI_XCR1_RX_TX_SHIFT)
46#define SAI_XCR1_SLAVE_SHIFT 1
47#define SAI_XCR1_SLAVE BIT(SAI_XCR1_SLAVE_SHIFT)
48
49#define SAI_XCR1_PRTCFG_SHIFT 2
50#define SAI_XCR1_PRTCFG_MASK GENMASK(3, SAI_XCR1_PRTCFG_SHIFT)
51#define SAI_XCR1_PRTCFG_SET(x) ((x) << SAI_XCR1_PRTCFG_SHIFT)
52
53#define SAI_XCR1_DS_SHIFT 5
54#define SAI_XCR1_DS_MASK GENMASK(7, SAI_XCR1_DS_SHIFT)
55#define SAI_XCR1_DS_SET(x) ((x) << SAI_XCR1_DS_SHIFT)
56
57#define SAI_XCR1_LSBFIRST_SHIFT 8
58#define SAI_XCR1_LSBFIRST BIT(SAI_XCR1_LSBFIRST_SHIFT)
59#define SAI_XCR1_CKSTR_SHIFT 9
60#define SAI_XCR1_CKSTR BIT(SAI_XCR1_CKSTR_SHIFT)
61
62#define SAI_XCR1_SYNCEN_SHIFT 10
63#define SAI_XCR1_SYNCEN_MASK GENMASK(11, SAI_XCR1_SYNCEN_SHIFT)
64#define SAI_XCR1_SYNCEN_SET(x) ((x) << SAI_XCR1_SYNCEN_SHIFT)
65
66#define SAI_XCR1_MONO_SHIFT 12
67#define SAI_XCR1_MONO BIT(SAI_XCR1_MONO_SHIFT)
68#define SAI_XCR1_OUTDRIV_SHIFT 13
69#define SAI_XCR1_OUTDRIV BIT(SAI_XCR1_OUTDRIV_SHIFT)
70#define SAI_XCR1_SAIEN_SHIFT 16
71#define SAI_XCR1_SAIEN BIT(SAI_XCR1_SAIEN_SHIFT)
72#define SAI_XCR1_DMAEN_SHIFT 17
73#define SAI_XCR1_DMAEN BIT(SAI_XCR1_DMAEN_SHIFT)
74#define SAI_XCR1_NODIV_SHIFT 19
75#define SAI_XCR1_NODIV BIT(SAI_XCR1_NODIV_SHIFT)
76
77#define SAI_XCR1_MCKDIV_SHIFT 20
78#define SAI_XCR1_MCKDIV_WIDTH 4
79#define SAI_XCR1_MCKDIV_MASK GENMASK(24, SAI_XCR1_MCKDIV_SHIFT)
80#define SAI_XCR1_MCKDIV_SET(x) ((x) << SAI_XCR1_MCKDIV_SHIFT)
81#define SAI_XCR1_MCKDIV_MAX ((1 << SAI_XCR1_MCKDIV_WIDTH) - 1)
82
83#define SAI_XCR1_OSR_SHIFT 26
84#define SAI_XCR1_OSR BIT(SAI_XCR1_OSR_SHIFT)
85
86/******************* Bit definition for SAI_XCR2 register *******************/
87#define SAI_XCR2_FTH_SHIFT 0
88#define SAI_XCR2_FTH_MASK GENMASK(2, SAI_XCR2_FTH_SHIFT)
89#define SAI_XCR2_FTH_SET(x) ((x) << SAI_XCR2_FTH_SHIFT)
90
91#define SAI_XCR2_FFLUSH_SHIFT 3
92#define SAI_XCR2_FFLUSH BIT(SAI_XCR2_FFLUSH_SHIFT)
93#define SAI_XCR2_TRIS_SHIFT 4
94#define SAI_XCR2_TRIS BIT(SAI_XCR2_TRIS_SHIFT)
95#define SAI_XCR2_MUTE_SHIFT 5
96#define SAI_XCR2_MUTE BIT(SAI_XCR2_MUTE_SHIFT)
97#define SAI_XCR2_MUTEVAL_SHIFT 6
98#define SAI_XCR2_MUTEVAL BIT(SAI_XCR2_MUTEVAL_SHIFT)
99
100#define SAI_XCR2_MUTECNT_SHIFT 7
101#define SAI_XCR2_MUTECNT_MASK GENMASK(12, SAI_XCR2_MUTECNT_SHIFT)
102#define SAI_XCR2_MUTECNT_SET(x) ((x) << SAI_XCR2_MUTECNT_SHIFT)
103
104#define SAI_XCR2_CPL_SHIFT 13
105#define SAI_XCR2_CPL BIT(SAI_XCR2_CPL_SHIFT)
106
107#define SAI_XCR2_COMP_SHIFT 14
108#define SAI_XCR2_COMP_MASK GENMASK(15, SAI_XCR2_COMP_SHIFT)
109#define SAI_XCR2_COMP_SET(x) ((x) << SAI_XCR2_COMP_SHIFT)
110
111/****************** Bit definition for SAI_XFRCR register *******************/
112#define SAI_XFRCR_FRL_SHIFT 0
113#define SAI_XFRCR_FRL_MASK GENMASK(7, SAI_XFRCR_FRL_SHIFT)
114#define SAI_XFRCR_FRL_SET(x) ((x) << SAI_XFRCR_FRL_SHIFT)
115
116#define SAI_XFRCR_FSALL_SHIFT 8
117#define SAI_XFRCR_FSALL_MASK GENMASK(14, SAI_XFRCR_FSALL_SHIFT)
118#define SAI_XFRCR_FSALL_SET(x) ((x) << SAI_XFRCR_FSALL_SHIFT)
119
120#define SAI_XFRCR_FSDEF_SHIFT 16
121#define SAI_XFRCR_FSDEF BIT(SAI_XFRCR_FSDEF_SHIFT)
122#define SAI_XFRCR_FSPOL_SHIFT 17
123#define SAI_XFRCR_FSPOL BIT(SAI_XFRCR_FSPOL_SHIFT)
124#define SAI_XFRCR_FSOFF_SHIFT 18
125#define SAI_XFRCR_FSOFF BIT(SAI_XFRCR_FSOFF_SHIFT)
126
127/****************** Bit definition for SAI_XSLOTR register ******************/
128
129#define SAI_XSLOTR_FBOFF_SHIFT 0
130#define SAI_XSLOTR_FBOFF_MASK GENMASK(4, SAI_XSLOTR_FBOFF_SHIFT)
131#define SAI_XSLOTR_FBOFF_SET(x) ((x) << SAI_XSLOTR_FBOFF_SHIFT)
132
133#define SAI_XSLOTR_SLOTSZ_SHIFT 6
134#define SAI_XSLOTR_SLOTSZ_MASK GENMASK(7, SAI_XSLOTR_SLOTSZ_SHIFT)
135#define SAI_XSLOTR_SLOTSZ_SET(x) ((x) << SAI_XSLOTR_SLOTSZ_SHIFT)
136
137#define SAI_XSLOTR_NBSLOT_SHIFT 8
138#define SAI_XSLOTR_NBSLOT_MASK GENMASK(11, SAI_XSLOTR_NBSLOT_SHIFT)
139#define SAI_XSLOTR_NBSLOT_SET(x) ((x) << SAI_XSLOTR_NBSLOT_SHIFT)
140
141#define SAI_XSLOTR_SLOTEN_SHIFT 16
142#define SAI_XSLOTR_SLOTEN_WIDTH 16
143#define SAI_XSLOTR_SLOTEN_MASK GENMASK(31, SAI_XSLOTR_SLOTEN_SHIFT)
144#define SAI_XSLOTR_SLOTEN_SET(x) ((x) << SAI_XSLOTR_SLOTEN_SHIFT)
145
146/******************* Bit definition for SAI_XIMR register *******************/
147#define SAI_XIMR_OVRUDRIE BIT(0)
148#define SAI_XIMR_MUTEDETIE BIT(1)
149#define SAI_XIMR_WCKCFGIE BIT(2)
150#define SAI_XIMR_FREQIE BIT(3)
151#define SAI_XIMR_CNRDYIE BIT(4)
152#define SAI_XIMR_AFSDETIE BIT(5)
153#define SAI_XIMR_LFSDETIE BIT(6)
154
155#define SAI_XIMR_SHIFT 0
156#define SAI_XIMR_MASK GENMASK(6, SAI_XIMR_SHIFT)
157
158/******************** Bit definition for SAI_XSR register *******************/
159#define SAI_XSR_OVRUDR BIT(0)
160#define SAI_XSR_MUTEDET BIT(1)
161#define SAI_XSR_WCKCFG BIT(2)
162#define SAI_XSR_FREQ BIT(3)
163#define SAI_XSR_CNRDY BIT(4)
164#define SAI_XSR_AFSDET BIT(5)
165#define SAI_XSR_LFSDET BIT(6)
166
167#define SAI_XSR_SHIFT 0
168#define SAI_XSR_MASK GENMASK(6, SAI_XSR_SHIFT)
169
170/****************** Bit definition for SAI_XCLRFR register ******************/
171#define SAI_XCLRFR_COVRUDR BIT(0)
172#define SAI_XCLRFR_CMUTEDET BIT(1)
173#define SAI_XCLRFR_CWCKCFG BIT(2)
174#define SAI_XCLRFR_CFREQ BIT(3)
175#define SAI_XCLRFR_CCNRDY BIT(4)
176#define SAI_XCLRFR_CAFSDET BIT(5)
177#define SAI_XCLRFR_CLFSDET BIT(6)
178
179#define SAI_XCLRFR_SHIFT 0
180#define SAI_XCLRFR_MASK GENMASK(6, SAI_XCLRFR_SHIFT)
181
182enum stm32_sai_version {
183 SAI_STM32F4
184};
185
186/**
187 * struct stm32_sai_data - private data of SAI instance driver
188 * @pdev: device data pointer
189 * @clk_x8k: SAI parent clock for sampling frequencies multiple of 8kHz
190 * @clk_x11k: SAI parent clock for sampling frequencies multiple of 11kHz
191 * @version: SOC version
192 * @irq: SAI interrupt line
193 */
194struct stm32_sai_data {
195 struct platform_device *pdev;
196 struct clk *clk_x8k;
197 struct clk *clk_x11k;
198 int version;
199 int irq;
200};
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
new file mode 100644
index 000000000000..ae4706ca265b
--- /dev/null
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -0,0 +1,884 @@
1/*
2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
6 *
7 * License terms: GPL V2.0.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details.
17 */
18
19#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of_irq.h>
23#include <linux/of_platform.h>
24#include <linux/regmap.h>
25
26#include <sound/core.h>
27#include <sound/dmaengine_pcm.h>
28#include <sound/pcm_params.h>
29
30#include "stm32_sai.h"
31
32#define SAI_FREE_PROTOCOL 0x0
33
34#define SAI_SLOT_SIZE_AUTO 0x0
35#define SAI_SLOT_SIZE_16 0x1
36#define SAI_SLOT_SIZE_32 0x2
37
38#define SAI_DATASIZE_8 0x2
39#define SAI_DATASIZE_10 0x3
40#define SAI_DATASIZE_16 0x4
41#define SAI_DATASIZE_20 0x5
42#define SAI_DATASIZE_24 0x6
43#define SAI_DATASIZE_32 0x7
44
45#define STM_SAI_FIFO_SIZE 8
46#define STM_SAI_DAI_NAME_SIZE 15
47
48#define STM_SAI_IS_PLAYBACK(ip) ((ip)->dir == SNDRV_PCM_STREAM_PLAYBACK)
49#define STM_SAI_IS_CAPTURE(ip) ((ip)->dir == SNDRV_PCM_STREAM_CAPTURE)
50
51#define STM_SAI_A_ID 0x0
52#define STM_SAI_B_ID 0x1
53
54#define STM_SAI_BLOCK_NAME(x) (((x)->id == STM_SAI_A_ID) ? "A" : "B")
55
56/**
57 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
58 * @pdev: device data pointer
59 * @regmap: SAI register map pointer
60 * @dma_params: dma configuration data for rx or tx channel
61 * @cpu_dai_drv: DAI driver data pointer
62 * @cpu_dai: DAI runtime data pointer
63 * @substream: PCM substream data pointer
64 * @pdata: SAI block parent data pointer
65 * @sai_ck: kernel clock feeding the SAI clock generator
66 * @phys_addr: SAI registers physical base address
67 * @mclk_rate: SAI block master clock frequency (Hz). set at init
68 * @id: SAI sub block id corresponding to sub-block A or B
69 * @dir: SAI block direction (playback or capture). set at init
70 * @master: SAI block mode flag. (true=master, false=slave) set at init
71 * @fmt: SAI block format. relevant only for custom protocols. set at init
72 * @sync: SAI block synchronization mode. (none, internal or external)
73 * @fs_length: frame synchronization length. depends on protocol settings
74 * @slots: rx or tx slot number
75 * @slot_width: rx or tx slot width in bits
76 * @slot_mask: rx or tx active slots mask. set at init or at runtime
77 * @data_size: PCM data width. corresponds to PCM substream width.
78 */
79struct stm32_sai_sub_data {
80 struct platform_device *pdev;
81 struct regmap *regmap;
82 struct snd_dmaengine_dai_dma_data dma_params;
83 struct snd_soc_dai_driver *cpu_dai_drv;
84 struct snd_soc_dai *cpu_dai;
85 struct snd_pcm_substream *substream;
86 struct stm32_sai_data *pdata;
87 struct clk *sai_ck;
88 dma_addr_t phys_addr;
89 unsigned int mclk_rate;
90 unsigned int id;
91 int dir;
92 bool master;
93 int fmt;
94 int sync;
95 int fs_length;
96 int slots;
97 int slot_width;
98 int slot_mask;
99 int data_size;
100};
101
102enum stm32_sai_fifo_th {
103 STM_SAI_FIFO_TH_EMPTY,
104 STM_SAI_FIFO_TH_QUARTER,
105 STM_SAI_FIFO_TH_HALF,
106 STM_SAI_FIFO_TH_3_QUARTER,
107 STM_SAI_FIFO_TH_FULL,
108};
109
110static bool stm32_sai_sub_readable_reg(struct device *dev, unsigned int reg)
111{
112 switch (reg) {
113 case STM_SAI_CR1_REGX:
114 case STM_SAI_CR2_REGX:
115 case STM_SAI_FRCR_REGX:
116 case STM_SAI_SLOTR_REGX:
117 case STM_SAI_IMR_REGX:
118 case STM_SAI_SR_REGX:
119 case STM_SAI_CLRFR_REGX:
120 case STM_SAI_DR_REGX:
121 return true;
122 default:
123 return false;
124 }
125}
126
127static bool stm32_sai_sub_volatile_reg(struct device *dev, unsigned int reg)
128{
129 switch (reg) {
130 case STM_SAI_DR_REGX:
131 return true;
132 default:
133 return false;
134 }
135}
136
137static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
138{
139 switch (reg) {
140 case STM_SAI_CR1_REGX:
141 case STM_SAI_CR2_REGX:
142 case STM_SAI_FRCR_REGX:
143 case STM_SAI_SLOTR_REGX:
144 case STM_SAI_IMR_REGX:
145 case STM_SAI_SR_REGX:
146 case STM_SAI_CLRFR_REGX:
147 case STM_SAI_DR_REGX:
148 return true;
149 default:
150 return false;
151 }
152}
153
154static const struct regmap_config stm32_sai_sub_regmap_config = {
155 .reg_bits = 32,
156 .reg_stride = 4,
157 .val_bits = 32,
158 .max_register = STM_SAI_DR_REGX,
159 .readable_reg = stm32_sai_sub_readable_reg,
160 .volatile_reg = stm32_sai_sub_volatile_reg,
161 .writeable_reg = stm32_sai_sub_writeable_reg,
162 .fast_io = true,
163};
164
165static irqreturn_t stm32_sai_isr(int irq, void *devid)
166{
167 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
168 struct snd_pcm_substream *substream = sai->substream;
169 struct platform_device *pdev = sai->pdev;
170 unsigned int sr, imr, flags;
171 snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
172
173 regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr);
174 regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr);
175
176 flags = sr & imr;
177 if (!flags)
178 return IRQ_NONE;
179
180 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
181 SAI_XCLRFR_MASK);
182
183 if (flags & SAI_XIMR_OVRUDRIE) {
184 dev_err(&pdev->dev, "IT %s\n",
185 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
186 status = SNDRV_PCM_STATE_XRUN;
187 }
188
189 if (flags & SAI_XIMR_MUTEDETIE)
190 dev_dbg(&pdev->dev, "IT mute detected\n");
191
192 if (flags & SAI_XIMR_WCKCFGIE) {
193 dev_err(&pdev->dev, "IT wrong clock configuration\n");
194 status = SNDRV_PCM_STATE_DISCONNECTED;
195 }
196
197 if (flags & SAI_XIMR_CNRDYIE)
198 dev_warn(&pdev->dev, "IT Codec not ready\n");
199
200 if (flags & SAI_XIMR_AFSDETIE) {
201 dev_warn(&pdev->dev, "IT Anticipated frame synchro\n");
202 status = SNDRV_PCM_STATE_XRUN;
203 }
204
205 if (flags & SAI_XIMR_LFSDETIE) {
206 dev_warn(&pdev->dev, "IT Late frame synchro\n");
207 status = SNDRV_PCM_STATE_XRUN;
208 }
209
210 if (status != SNDRV_PCM_STATE_RUNNING) {
211 snd_pcm_stream_lock(substream);
212 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
213 snd_pcm_stream_unlock(substream);
214 }
215
216 return IRQ_HANDLED;
217}
218
219static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
220 int clk_id, unsigned int freq, int dir)
221{
222 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
223
224 if ((dir == SND_SOC_CLOCK_OUT) && sai->master) {
225 sai->mclk_rate = freq;
226 dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
227 }
228
229 return 0;
230}
231
232static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
233 u32 rx_mask, int slots, int slot_width)
234{
235 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
236 int slotr, slotr_mask, slot_size;
237
238 dev_dbg(cpu_dai->dev, "masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
239 tx_mask, rx_mask, slots, slot_width);
240
241 switch (slot_width) {
242 case 16:
243 slot_size = SAI_SLOT_SIZE_16;
244 break;
245 case 32:
246 slot_size = SAI_SLOT_SIZE_32;
247 break;
248 default:
249 slot_size = SAI_SLOT_SIZE_AUTO;
250 break;
251 }
252
253 slotr = SAI_XSLOTR_SLOTSZ_SET(slot_size) |
254 SAI_XSLOTR_NBSLOT_SET(slots - 1);
255 slotr_mask = SAI_XSLOTR_SLOTSZ_MASK | SAI_XSLOTR_NBSLOT_MASK;
256
257 /* tx/rx mask set in machine init, if slot number defined in DT */
258 if (STM_SAI_IS_PLAYBACK(sai)) {
259 sai->slot_mask = tx_mask;
260 slotr |= SAI_XSLOTR_SLOTEN_SET(tx_mask);
261 }
262
263 if (STM_SAI_IS_CAPTURE(sai)) {
264 sai->slot_mask = rx_mask;
265 slotr |= SAI_XSLOTR_SLOTEN_SET(rx_mask);
266 }
267
268 slotr_mask |= SAI_XSLOTR_SLOTEN_MASK;
269
270 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
271
272 sai->slot_width = slot_width;
273 sai->slots = slots;
274
275 return 0;
276}
277
278static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
279{
280 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
281 int cr1 = 0, frcr = 0;
282 int cr1_mask = 0, frcr_mask = 0;
283 int ret;
284
285 dev_dbg(cpu_dai->dev, "fmt %x\n", fmt);
286
287 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
288 /* SCK active high for all protocols */
289 case SND_SOC_DAIFMT_I2S:
290 cr1 |= SAI_XCR1_CKSTR;
291 frcr |= SAI_XFRCR_FSOFF | SAI_XFRCR_FSDEF;
292 break;
293 /* Left justified */
294 case SND_SOC_DAIFMT_MSB:
295 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
296 break;
297 /* Right justified */
298 case SND_SOC_DAIFMT_LSB:
299 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
300 break;
301 case SND_SOC_DAIFMT_DSP_A:
302 frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
303 break;
304 case SND_SOC_DAIFMT_DSP_B:
305 frcr |= SAI_XFRCR_FSPOL;
306 break;
307 default:
308 dev_err(cpu_dai->dev, "Unsupported protocol %#x\n",
309 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
310 return -EINVAL;
311 }
312
313 cr1_mask |= SAI_XCR1_PRTCFG_MASK | SAI_XCR1_CKSTR;
314 frcr_mask |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF |
315 SAI_XFRCR_FSDEF;
316
317 /* DAI clock strobing. Invert setting previously set */
318 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
319 case SND_SOC_DAIFMT_NB_NF:
320 break;
321 case SND_SOC_DAIFMT_IB_NF:
322 cr1 ^= SAI_XCR1_CKSTR;
323 break;
324 case SND_SOC_DAIFMT_NB_IF:
325 frcr ^= SAI_XFRCR_FSPOL;
326 break;
327 case SND_SOC_DAIFMT_IB_IF:
328 /* Invert fs & sck */
329 cr1 ^= SAI_XCR1_CKSTR;
330 frcr ^= SAI_XFRCR_FSPOL;
331 break;
332 default:
333 dev_err(cpu_dai->dev, "Unsupported strobing %#x\n",
334 fmt & SND_SOC_DAIFMT_INV_MASK);
335 return -EINVAL;
336 }
337 cr1_mask |= SAI_XCR1_CKSTR;
338 frcr_mask |= SAI_XFRCR_FSPOL;
339
340 regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
341
342 /* DAI clock master masks */
343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
344 case SND_SOC_DAIFMT_CBM_CFM:
345 /* codec is master */
346 cr1 |= SAI_XCR1_SLAVE;
347 sai->master = false;
348 break;
349 case SND_SOC_DAIFMT_CBS_CFS:
350 sai->master = true;
351 break;
352 default:
353 dev_err(cpu_dai->dev, "Unsupported mode %#x\n",
354 fmt & SND_SOC_DAIFMT_MASTER_MASK);
355 return -EINVAL;
356 }
357 cr1_mask |= SAI_XCR1_SLAVE;
358
359 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
360 if (ret < 0) {
361 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
362 return ret;
363 }
364
365 sai->fmt = fmt;
366
367 return 0;
368}
369
370static int stm32_sai_startup(struct snd_pcm_substream *substream,
371 struct snd_soc_dai *cpu_dai)
372{
373 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
374 int imr, cr2, ret;
375
376 sai->substream = substream;
377
378 ret = clk_prepare_enable(sai->sai_ck);
379 if (ret < 0) {
380 dev_err(cpu_dai->dev, "failed to enable clock: %d\n", ret);
381 return ret;
382 }
383
384 /* Enable ITs */
385 regmap_update_bits(sai->regmap, STM_SAI_SR_REGX,
386 SAI_XSR_MASK, (unsigned int)~SAI_XSR_MASK);
387
388 regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX,
389 SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
390
391 imr = SAI_XIMR_OVRUDRIE;
392 if (STM_SAI_IS_CAPTURE(sai)) {
393 regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2);
394 if (cr2 & SAI_XCR2_MUTECNT_MASK)
395 imr |= SAI_XIMR_MUTEDETIE;
396 }
397
398 if (sai->master)
399 imr |= SAI_XIMR_WCKCFGIE;
400 else
401 imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE;
402
403 regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
404 SAI_XIMR_MASK, imr);
405
406 return 0;
407}
408
409static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
410 struct snd_pcm_substream *substream,
411 struct snd_pcm_hw_params *params)
412{
413 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
414 int cr1, cr1_mask, ret;
415 int fth = STM_SAI_FIFO_TH_HALF;
416
417 /* FIFO config */
418 regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
419 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
420 SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));
421
422 /* Mode, data format and channel config */
423 cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
424 switch (params_format(params)) {
425 case SNDRV_PCM_FORMAT_S8:
426 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_8);
427 break;
428 case SNDRV_PCM_FORMAT_S16_LE:
429 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_16);
430 break;
431 case SNDRV_PCM_FORMAT_S32_LE:
432 cr1 |= SAI_XCR1_DS_SET(SAI_DATASIZE_32);
433 break;
434 default:
435 dev_err(cpu_dai->dev, "Data format not supported");
436 return -EINVAL;
437 }
438 cr1_mask = SAI_XCR1_DS_MASK | SAI_XCR1_PRTCFG_MASK;
439
440 cr1_mask |= SAI_XCR1_RX_TX;
441 if (STM_SAI_IS_CAPTURE(sai))
442 cr1 |= SAI_XCR1_RX_TX;
443
444 cr1_mask |= SAI_XCR1_MONO;
445 if ((sai->slots == 2) && (params_channels(params) == 1))
446 cr1 |= SAI_XCR1_MONO;
447
448 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
449 if (ret < 0) {
450 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
451 return ret;
452 }
453
454 /* DMA config */
455 sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
456 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
457
458 return 0;
459}
460
461static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai)
462{
463 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
464 int slotr, slot_sz;
465
466 regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr);
467
468 /*
469 * If SLOTSZ is set to auto in SLOTR, align slot width on data size
470 * By default slot width = data size, if not forced from DT
471 */
472 slot_sz = slotr & SAI_XSLOTR_SLOTSZ_MASK;
473 if (slot_sz == SAI_XSLOTR_SLOTSZ_SET(SAI_SLOT_SIZE_AUTO))
474 sai->slot_width = sai->data_size;
475
476 if (sai->slot_width < sai->data_size) {
477 dev_err(cpu_dai->dev,
478 "Data size %d larger than slot width\n",
479 sai->data_size);
480 return -EINVAL;
481 }
482
483 /* Slot number is set to 2, if not specified in DT */
484 if (!sai->slots)
485 sai->slots = 2;
486
487 /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/
488 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
489 SAI_XSLOTR_NBSLOT_MASK,
490 SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
491
492 /* Set default slots mask if not already set from DT */
493 if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) {
494 sai->slot_mask = (1 << sai->slots) - 1;
495 regmap_update_bits(sai->regmap,
496 STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
497 SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
498 }
499
500 dev_dbg(cpu_dai->dev, "slots %d, slot width %d\n",
501 sai->slots, sai->slot_width);
502
503 return 0;
504}
505
506static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai)
507{
508 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
509 int fs_active, offset, format;
510 int frcr, frcr_mask;
511
512 format = sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
513 sai->fs_length = sai->slot_width * sai->slots;
514
515 fs_active = sai->fs_length / 2;
516 if ((format == SND_SOC_DAIFMT_DSP_A) ||
517 (format == SND_SOC_DAIFMT_DSP_B))
518 fs_active = 1;
519
520 frcr = SAI_XFRCR_FRL_SET((sai->fs_length - 1));
521 frcr |= SAI_XFRCR_FSALL_SET((fs_active - 1));
522 frcr_mask = SAI_XFRCR_FRL_MASK | SAI_XFRCR_FSALL_MASK;
523
524 dev_dbg(cpu_dai->dev, "frame length %d, frame active %d\n",
525 sai->fs_length, fs_active);
526
527 regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
528
529 if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
530 offset = sai->slot_width - sai->data_size;
531
532 regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
533 SAI_XSLOTR_FBOFF_MASK,
534 SAI_XSLOTR_FBOFF_SET(offset));
535 }
536}
537
538static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
539 struct snd_pcm_hw_params *params)
540{
541 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
542 int cr1, mask, div = 0;
543 int sai_clk_rate, ret;
544
545 if (!sai->mclk_rate) {
546 dev_err(cpu_dai->dev, "Mclk rate is null\n");
547 return -EINVAL;
548 }
549
550 if (!(params_rate(params) % 11025))
551 clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
552 else
553 clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
554 sai_clk_rate = clk_get_rate(sai->sai_ck);
555
556 /*
557 * mclk_rate = 256 * fs
558 * MCKDIV = 0 if sai_ck < 3/2 * mclk_rate
559 * MCKDIV = sai_ck / (2 * mclk_rate) otherwise
560 */
561 if (2 * sai_clk_rate >= 3 * sai->mclk_rate)
562 div = DIV_ROUND_CLOSEST(sai_clk_rate, 2 * sai->mclk_rate);
563
564 if (div > SAI_XCR1_MCKDIV_MAX) {
565 dev_err(cpu_dai->dev, "Divider %d out of range\n", div);
566 return -EINVAL;
567 }
568 dev_dbg(cpu_dai->dev, "SAI clock %d, divider %d\n", sai_clk_rate, div);
569
570 mask = SAI_XCR1_MCKDIV_MASK;
571 cr1 = SAI_XCR1_MCKDIV_SET(div);
572 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1);
573 if (ret < 0) {
574 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
575 return ret;
576 }
577
578 return 0;
579}
580
581static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
582 struct snd_pcm_hw_params *params,
583 struct snd_soc_dai *cpu_dai)
584{
585 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
586 int ret;
587
588 sai->data_size = params_width(params);
589
590 ret = stm32_sai_set_slots(cpu_dai);
591 if (ret < 0)
592 return ret;
593 stm32_sai_set_frame(cpu_dai);
594
595 ret = stm32_sai_set_config(cpu_dai, substream, params);
596 if (ret)
597 return ret;
598
599 if (sai->master)
600 ret = stm32_sai_configure_clock(cpu_dai, params);
601
602 return ret;
603}
604
605static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
606 struct snd_soc_dai *cpu_dai)
607{
608 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
609 int ret;
610
611 switch (cmd) {
612 case SNDRV_PCM_TRIGGER_START:
613 case SNDRV_PCM_TRIGGER_RESUME:
614 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
615 dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n");
616
617 regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
618 SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
619
620 /* Enable SAI */
621 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
622 SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
623 if (ret < 0)
624 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
625 break;
626 case SNDRV_PCM_TRIGGER_SUSPEND:
627 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
628 case SNDRV_PCM_TRIGGER_STOP:
629 dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n");
630
631 regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
632 SAI_XCR1_DMAEN,
633 (unsigned int)~SAI_XCR1_DMAEN);
634
635 ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
636 SAI_XCR1_SAIEN,
637 (unsigned int)~SAI_XCR1_SAIEN);
638 if (ret < 0)
639 dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
640 break;
641 default:
642 return -EINVAL;
643 }
644
645 return ret;
646}
647
648static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
649 struct snd_soc_dai *cpu_dai)
650{
651 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
652
653 regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
654
655 clk_disable_unprepare(sai->sai_ck);
656 sai->substream = NULL;
657}
658
659static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
660{
661 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
662
663 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
664 sai->dma_params.maxburst = 1;
665 /* Buswidth will be set by framework at runtime */
666 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
667
668 if (STM_SAI_IS_PLAYBACK(sai))
669 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params, NULL);
670 else
671 snd_soc_dai_init_dma_data(cpu_dai, NULL, &sai->dma_params);
672
673 return 0;
674}
675
676static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
677 .set_sysclk = stm32_sai_set_sysclk,
678 .set_fmt = stm32_sai_set_dai_fmt,
679 .set_tdm_slot = stm32_sai_set_dai_tdm_slot,
680 .startup = stm32_sai_startup,
681 .hw_params = stm32_sai_hw_params,
682 .trigger = stm32_sai_trigger,
683 .shutdown = stm32_sai_shutdown,
684};
685
686static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
687 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
688 .buffer_bytes_max = 8 * PAGE_SIZE,
689 .period_bytes_min = 1024, /* 5ms at 48kHz */
690 .period_bytes_max = PAGE_SIZE,
691 .periods_min = 2,
692 .periods_max = 8,
693};
694
695static struct snd_soc_dai_driver stm32_sai_playback_dai[] = {
696{
697 .probe = stm32_sai_dai_probe,
698 .id = 1, /* avoid call to fmt_single_name() */
699 .playback = {
700 .channels_min = 1,
701 .channels_max = 2,
702 .rate_min = 8000,
703 .rate_max = 192000,
704 .rates = SNDRV_PCM_RATE_CONTINUOUS,
705 /* DMA does not support 24 bits transfers */
706 .formats =
707 SNDRV_PCM_FMTBIT_S8 |
708 SNDRV_PCM_FMTBIT_S16_LE |
709 SNDRV_PCM_FMTBIT_S32_LE,
710 },
711 .ops = &stm32_sai_pcm_dai_ops,
712 }
713};
714
715static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
716{
717 .probe = stm32_sai_dai_probe,
718 .id = 1, /* avoid call to fmt_single_name() */
719 .capture = {
720 .channels_min = 1,
721 .channels_max = 2,
722 .rate_min = 8000,
723 .rate_max = 192000,
724 .rates = SNDRV_PCM_RATE_CONTINUOUS,
725 /* DMA does not support 24 bits transfers */
726 .formats =
727 SNDRV_PCM_FMTBIT_S8 |
728 SNDRV_PCM_FMTBIT_S16_LE |
729 SNDRV_PCM_FMTBIT_S32_LE,
730 },
731 .ops = &stm32_sai_pcm_dai_ops,
732 }
733};
734
735static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
736 .pcm_hardware = &stm32_sai_pcm_hw,
737 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
738};
739
740static const struct snd_soc_component_driver stm32_component = {
741 .name = "stm32-sai",
742};
743
744static const struct of_device_id stm32_sai_sub_ids[] = {
745 { .compatible = "st,stm32-sai-sub-a",
746 .data = (void *)STM_SAI_A_ID},
747 { .compatible = "st,stm32-sai-sub-b",
748 .data = (void *)STM_SAI_B_ID},
749 {}
750};
751MODULE_DEVICE_TABLE(of, stm32_sai_sub_ids);
752
753static int stm32_sai_sub_parse_of(struct platform_device *pdev,
754 struct stm32_sai_sub_data *sai)
755{
756 struct device_node *np = pdev->dev.of_node;
757 struct resource *res;
758 void __iomem *base;
759
760 if (!np)
761 return -ENODEV;
762
763 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
764
765 dev_err(&pdev->dev, "res %pr\n", res);
766
767 base = devm_ioremap_resource(&pdev->dev, res);
768 if (IS_ERR(base))
769 return PTR_ERR(base);
770
771 sai->phys_addr = res->start;
772 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
773 &stm32_sai_sub_regmap_config);
774
775 /* Get direction property */
776 if (of_property_match_string(np, "dma-names", "tx") >= 0) {
777 sai->dir = SNDRV_PCM_STREAM_PLAYBACK;
778 } else if (of_property_match_string(np, "dma-names", "rx") >= 0) {
779 sai->dir = SNDRV_PCM_STREAM_CAPTURE;
780 } else {
781 dev_err(&pdev->dev, "Unsupported direction\n");
782 return -EINVAL;
783 }
784
785 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
786 if (IS_ERR(sai->sai_ck)) {
787 dev_err(&pdev->dev, "missing kernel clock sai_ck\n");
788 return PTR_ERR(sai->sai_ck);
789 }
790
791 return 0;
792}
793
794static int stm32_sai_sub_dais_init(struct platform_device *pdev,
795 struct stm32_sai_sub_data *sai)
796{
797 sai->cpu_dai_drv = devm_kzalloc(&pdev->dev,
798 sizeof(struct snd_soc_dai_driver),
799 GFP_KERNEL);
800 if (!sai->cpu_dai_drv)
801 return -ENOMEM;
802
803 sai->cpu_dai_drv->name = dev_name(&pdev->dev);
804 if (STM_SAI_IS_PLAYBACK(sai)) {
805 memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai,
806 sizeof(stm32_sai_playback_dai));
807 sai->cpu_dai_drv->playback.stream_name = sai->cpu_dai_drv->name;
808 } else {
809 memcpy(sai->cpu_dai_drv, &stm32_sai_capture_dai,
810 sizeof(stm32_sai_capture_dai));
811 sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name;
812 }
813
814 return 0;
815}
816
817static int stm32_sai_sub_probe(struct platform_device *pdev)
818{
819 struct stm32_sai_sub_data *sai;
820 const struct of_device_id *of_id;
821 int ret;
822
823 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
824 if (!sai)
825 return -ENOMEM;
826
827 of_id = of_match_device(stm32_sai_sub_ids, &pdev->dev);
828 if (!of_id)
829 return -EINVAL;
830 sai->id = (uintptr_t)of_id->data;
831
832 sai->pdev = pdev;
833 platform_set_drvdata(pdev, sai);
834
835 sai->pdata = dev_get_drvdata(pdev->dev.parent);
836 if (!sai->pdata) {
837 dev_err(&pdev->dev, "Parent device data not available\n");
838 return -EINVAL;
839 }
840
841 ret = stm32_sai_sub_parse_of(pdev, sai);
842 if (ret)
843 return ret;
844
845 ret = stm32_sai_sub_dais_init(pdev, sai);
846 if (ret)
847 return ret;
848
849 ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
850 IRQF_SHARED, dev_name(&pdev->dev), sai);
851 if (ret) {
852 dev_err(&pdev->dev, "irq request returned %d\n", ret);
853 return ret;
854 }
855
856 ret = devm_snd_soc_register_component(&pdev->dev, &stm32_component,
857 sai->cpu_dai_drv, 1);
858 if (ret)
859 return ret;
860
861 ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
862 &stm32_sai_pcm_config, 0);
863 if (ret) {
864 dev_err(&pdev->dev, "could not register pcm dma\n");
865 return ret;
866 }
867
868 return 0;
869}
870
871static struct platform_driver stm32_sai_sub_driver = {
872 .driver = {
873 .name = "st,stm32-sai-sub",
874 .of_match_table = stm32_sai_sub_ids,
875 },
876 .probe = stm32_sai_sub_probe,
877};
878
879module_platform_driver(stm32_sai_sub_driver);
880
881MODULE_DESCRIPTION("STM32 Soc SAI sub-block Interface");
882MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>");
883MODULE_ALIAS("platform:st,stm32-sai-sub");
884MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
index 72331332b72e..6c17c99c2c8d 100644
--- a/sound/soc/sunxi/sun8i-codec-analog.c
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -252,24 +252,15 @@ static const DECLARE_TLV_DB_RANGE(sun8i_codec_mic_gain_scale,
252); 252);
253 253
254static const struct snd_kcontrol_new sun8i_codec_common_controls[] = { 254static const struct snd_kcontrol_new sun8i_codec_common_controls[] = {
255 /* Mixer pre-gains */ 255 /* Mixer pre-gain */
256 SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
257 SUN8I_ADDA_LINEIN_GCTRL_LINEING,
258 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
259 SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL, 256 SOC_SINGLE_TLV("Mic1 Playback Volume", SUN8I_ADDA_MICIN_GCTRL,
260 SUN8I_ADDA_MICIN_GCTRL_MIC1G, 257 SUN8I_ADDA_MICIN_GCTRL_MIC1G,
261 0x7, 0, sun8i_codec_out_mixer_pregain_scale), 258 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
262 SOC_SINGLE_TLV("Mic2 Playback Volume",
263 SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
264 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
265 259
266 /* Microphone Amp boost gains */ 260 /* Microphone Amp boost gain */
267 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 261 SOC_SINGLE_TLV("Mic1 Boost Volume", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
268 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0, 262 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST, 0x7, 0,
269 sun8i_codec_mic_gain_scale), 263 sun8i_codec_mic_gain_scale),
270 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
271 SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
272 sun8i_codec_mic_gain_scale),
273 264
274 /* ADC */ 265 /* ADC */
275 SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN, 266 SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN8I_ADDA_ADC_AP_EN,
@@ -295,12 +286,8 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
295 * stream widgets at the card level. 286 * stream widgets at the card level.
296 */ 287 */
297 288
298 /* Line In */ 289 /* Microphone input */
299 SND_SOC_DAPM_INPUT("LINEIN"),
300
301 /* Microphone inputs */
302 SND_SOC_DAPM_INPUT("MIC1"), 290 SND_SOC_DAPM_INPUT("MIC1"),
303 SND_SOC_DAPM_INPUT("MIC2"),
304 291
305 /* Microphone Bias */ 292 /* Microphone Bias */
306 SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 293 SND_SOC_DAPM_SUPPLY("MBIAS", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
@@ -310,8 +297,6 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
310 /* Mic input path */ 297 /* Mic input path */
311 SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL, 298 SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN8I_ADDA_MIC1G_MICBIAS_CTRL,
312 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0), 299 SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN, 0, NULL, 0),
313 SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
314 SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
315 300
316 /* Mixers */ 301 /* Mixers */
317 SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC, 302 SND_SOC_DAPM_MIXER("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
@@ -335,35 +320,26 @@ static const struct snd_soc_dapm_widget sun8i_codec_common_widgets[] = {
335static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = { 320static const struct snd_soc_dapm_route sun8i_codec_common_routes[] = {
336 /* Microphone Routes */ 321 /* Microphone Routes */
337 { "Mic1 Amplifier", NULL, "MIC1"}, 322 { "Mic1 Amplifier", NULL, "MIC1"},
338 { "Mic2 Amplifier", NULL, "MIC2"},
339 323
340 /* Left Mixer Routes */ 324 /* Left Mixer Routes */
341 { "Left Mixer", "DAC Playback Switch", "Left DAC" }, 325 { "Left Mixer", "DAC Playback Switch", "Left DAC" },
342 { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, 326 { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
343 { "Left Mixer", "Line In Playback Switch", "LINEIN" },
344 { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 327 { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
345 { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
346 328
347 /* Right Mixer Routes */ 329 /* Right Mixer Routes */
348 { "Right Mixer", "DAC Playback Switch", "Right DAC" }, 330 { "Right Mixer", "DAC Playback Switch", "Right DAC" },
349 { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, 331 { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
350 { "Right Mixer", "Line In Playback Switch", "LINEIN" },
351 { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, 332 { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
352 { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
353 333
354 /* Left ADC Mixer Routes */ 334 /* Left ADC Mixer Routes */
355 { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, 335 { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
356 { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, 336 { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
357 { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
358 { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 337 { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
359 { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
360 338
361 /* Right ADC Mixer Routes */ 339 /* Right ADC Mixer Routes */
362 { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, 340 { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
363 { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, 341 { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
364 { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
365 { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, 342 { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
366 { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
367 343
368 /* ADC Routes */ 344 /* ADC Routes */
369 { "Left ADC", NULL, "Left ADC Mixer" }, 345 { "Left ADC", NULL, "Left ADC Mixer" },
@@ -498,6 +474,61 @@ static int sun8i_codec_add_hmic(struct snd_soc_component *cmpnt)
498 return ret; 474 return ret;
499} 475}
500 476
477/* line in specific controls, widgets and rines */
478static const struct snd_kcontrol_new sun8i_codec_linein_controls[] = {
479 /* Mixer pre-gain */
480 SOC_SINGLE_TLV("Line In Playback Volume", SUN8I_ADDA_LINEIN_GCTRL,
481 SUN8I_ADDA_LINEIN_GCTRL_LINEING,
482 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
483};
484
485static const struct snd_soc_dapm_widget sun8i_codec_linein_widgets[] = {
486 /* Line input */
487 SND_SOC_DAPM_INPUT("LINEIN"),
488};
489
490static const struct snd_soc_dapm_route sun8i_codec_linein_routes[] = {
491 { "Left Mixer", "Line In Playback Switch", "LINEIN" },
492
493 { "Right Mixer", "Line In Playback Switch", "LINEIN" },
494
495 { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
496
497 { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
498};
499
500static int sun8i_codec_add_linein(struct snd_soc_component *cmpnt)
501{
502 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
503 struct device *dev = cmpnt->dev;
504 int ret;
505
506 ret = snd_soc_add_component_controls(cmpnt,
507 sun8i_codec_linein_controls,
508 ARRAY_SIZE(sun8i_codec_linein_controls));
509 if (ret) {
510 dev_err(dev, "Failed to add Line In controls: %d\n", ret);
511 return ret;
512 }
513
514 ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_linein_widgets,
515 ARRAY_SIZE(sun8i_codec_linein_widgets));
516 if (ret) {
517 dev_err(dev, "Failed to add Line In DAPM widgets: %d\n", ret);
518 return ret;
519 }
520
521 ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_linein_routes,
522 ARRAY_SIZE(sun8i_codec_linein_routes));
523 if (ret) {
524 dev_err(dev, "Failed to add Line In DAPM routes: %d\n", ret);
525 return ret;
526 }
527
528 return 0;
529}
530
531
501/* line out specific controls, widgets and routes */ 532/* line out specific controls, widgets and routes */
502static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale, 533static const DECLARE_TLV_DB_RANGE(sun8i_codec_lineout_vol_scale,
503 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), 534 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
@@ -578,19 +609,90 @@ static int sun8i_codec_add_lineout(struct snd_soc_component *cmpnt)
578 return 0; 609 return 0;
579} 610}
580 611
612/* mic2 specific controls, widgets and routes */
613static const struct snd_kcontrol_new sun8i_codec_mic2_controls[] = {
614 /* Mixer pre-gain */
615 SOC_SINGLE_TLV("Mic2 Playback Volume",
616 SUN8I_ADDA_MICIN_GCTRL, SUN8I_ADDA_MICIN_GCTRL_MIC2G,
617 0x7, 0, sun8i_codec_out_mixer_pregain_scale),
618
619 /* Microphone Amp boost gain */
620 SOC_SINGLE_TLV("Mic2 Boost Volume", SUN8I_ADDA_MIC2G_CTRL,
621 SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST, 0x7, 0,
622 sun8i_codec_mic_gain_scale),
623};
624
625static const struct snd_soc_dapm_widget sun8i_codec_mic2_widgets[] = {
626 /* Microphone input */
627 SND_SOC_DAPM_INPUT("MIC2"),
628
629 /* Mic input path */
630 SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN8I_ADDA_MIC2G_CTRL,
631 SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN, 0, NULL, 0),
632};
633
634static const struct snd_soc_dapm_route sun8i_codec_mic2_routes[] = {
635 { "Mic2 Amplifier", NULL, "MIC2"},
636
637 { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
638
639 { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
640
641 { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
642
643 { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
644};
645
646static int sun8i_codec_add_mic2(struct snd_soc_component *cmpnt)
647{
648 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
649 struct device *dev = cmpnt->dev;
650 int ret;
651
652 ret = snd_soc_add_component_controls(cmpnt,
653 sun8i_codec_mic2_controls,
654 ARRAY_SIZE(sun8i_codec_mic2_controls));
655 if (ret) {
656 dev_err(dev, "Failed to add MIC2 controls: %d\n", ret);
657 return ret;
658 }
659
660 ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_mic2_widgets,
661 ARRAY_SIZE(sun8i_codec_mic2_widgets));
662 if (ret) {
663 dev_err(dev, "Failed to add MIC2 DAPM widgets: %d\n", ret);
664 return ret;
665 }
666
667 ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_mic2_routes,
668 ARRAY_SIZE(sun8i_codec_mic2_routes));
669 if (ret) {
670 dev_err(dev, "Failed to add MIC2 DAPM routes: %d\n", ret);
671 return ret;
672 }
673
674 return 0;
675}
676
581struct sun8i_codec_analog_quirks { 677struct sun8i_codec_analog_quirks {
582 bool has_headphone; 678 bool has_headphone;
583 bool has_hmic; 679 bool has_hmic;
680 bool has_linein;
584 bool has_lineout; 681 bool has_lineout;
682 bool has_mic2;
585}; 683};
586 684
587static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = { 685static const struct sun8i_codec_analog_quirks sun8i_a23_quirks = {
588 .has_headphone = true, 686 .has_headphone = true,
589 .has_hmic = true, 687 .has_hmic = true,
688 .has_linein = true,
689 .has_mic2 = true,
590}; 690};
591 691
592static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = { 692static const struct sun8i_codec_analog_quirks sun8i_h3_quirks = {
693 .has_linein = true,
593 .has_lineout = true, 694 .has_lineout = true,
695 .has_mic2 = true,
594}; 696};
595 697
596static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt) 698static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
@@ -620,12 +722,24 @@ static int sun8i_codec_analog_cmpnt_probe(struct snd_soc_component *cmpnt)
620 return ret; 722 return ret;
621 } 723 }
622 724
725 if (quirks->has_linein) {
726 ret = sun8i_codec_add_linein(cmpnt);
727 if (ret)
728 return ret;
729 }
730
623 if (quirks->has_lineout) { 731 if (quirks->has_lineout) {
624 ret = sun8i_codec_add_lineout(cmpnt); 732 ret = sun8i_codec_add_lineout(cmpnt);
625 if (ret) 733 if (ret)
626 return ret; 734 return ret;
627 } 735 }
628 736
737 if (quirks->has_mic2) {
738 ret = sun8i_codec_add_mic2(cmpnt);
739 if (ret)
740 return ret;
741 }
742
629 return 0; 743 return 0;
630} 744}
631 745
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 7527ba29a5a0..5723c3404f6b 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -290,12 +290,10 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
290 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0), 290 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
291 291
292 /* DAC Mixers */ 292 /* DAC Mixers */
293 SND_SOC_DAPM_MIXER("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0, 293 SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
294 sun8i_dac_mixer_controls, 294 sun8i_dac_mixer_controls),
295 ARRAY_SIZE(sun8i_dac_mixer_controls)), 295 SOC_MIXER_ARRAY("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
296 SND_SOC_DAPM_MIXER("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0, 296 sun8i_dac_mixer_controls),
297 sun8i_dac_mixer_controls,
298 ARRAY_SIZE(sun8i_dac_mixer_controls)),
299 297
300 /* Clocks */ 298 /* Clocks */
301 SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA, 299 SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index a68368edab9c..affad46bf188 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -318,7 +318,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
318 ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97), 318 ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97),
319 GFP_KERNEL); 319 GFP_KERNEL);
320 if (!ac97) { 320 if (!ac97) {
321 dev_err(&pdev->dev, "Can't allocate tegra20_ac97\n");
322 ret = -ENOMEM; 321 ret = -ENOMEM;
323 goto err; 322 goto err;
324 } 323 }
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index 89add13c31cf..4024e3abbeed 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -41,6 +41,7 @@ static inline void tegra20_das_write(u32 reg, u32 val)
41static inline u32 tegra20_das_read(u32 reg) 41static inline u32 tegra20_das_read(u32 reg)
42{ 42{
43 u32 val; 43 u32 val;
44
44 regmap_read(das->regmap, reg, &val); 45 regmap_read(das->regmap, reg, &val);
45 return val; 46 return val;
46} 47}
@@ -142,7 +143,6 @@ static int tegra20_das_probe(struct platform_device *pdev)
142 143
143 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL); 144 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL);
144 if (!das) { 145 if (!das) {
145 dev_err(&pdev->dev, "Can't allocate tegra20_das\n");
146 ret = -ENOMEM; 146 ret = -ENOMEM;
147 goto err; 147 goto err;
148 } 148 }
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 14106fa82bca..26253c2849e7 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -345,7 +345,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
345 345
346 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL); 346 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
347 if (!i2s) { 347 if (!i2s) {
348 dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
349 ret = -ENOMEM; 348 ret = -ENOMEM;
350 goto err; 349 goto err;
351 } 350 }
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index a0c3640572b9..767c0491e11a 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -271,10 +271,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
271 271
272 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif), 272 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
273 GFP_KERNEL); 273 GFP_KERNEL);
274 if (!spdif) { 274 if (!spdif)
275 dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
276 return -ENOMEM; 275 return -ENOMEM;
277 } 276
278 dev_set_drvdata(&pdev->dev, spdif); 277 dev_set_drvdata(&pdev->dev, spdif);
279 278
280 spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "spdif_out"); 279 spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "spdif_out");
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index fef3b9a21a66..8c10ae7982ba 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -41,6 +41,7 @@ static inline void tegra30_apbif_write(u32 reg, u32 val)
41static inline u32 tegra30_apbif_read(u32 reg) 41static inline u32 tegra30_apbif_read(u32 reg)
42{ 42{
43 u32 val; 43 u32 val;
44
44 regmap_read(ahub->regmap_apbif, reg, &val); 45 regmap_read(ahub->regmap_apbif, reg, &val);
45 return val; 46 return val;
46} 47}
@@ -560,10 +561,8 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
560 561
561 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), 562 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
562 GFP_KERNEL); 563 GFP_KERNEL);
563 if (!ahub) { 564 if (!ahub)
564 dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n");
565 return -ENOMEM; 565 return -ENOMEM;
566 }
567 dev_set_drvdata(&pdev->dev, ahub); 566 dev_set_drvdata(&pdev->dev, ahub);
568 567
569 ahub->soc_data = soc_data; 568 ahub->soc_data = soc_data;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 8e55583aa104..b2b279c96029 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -385,7 +385,6 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
385 385
386 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); 386 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
387 if (!i2s) { 387 if (!i2s) {
388 dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
389 ret = -ENOMEM; 388 ret = -ENOMEM;
390 goto err; 389 goto err;
391 } 390 }
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index eead6e7f205b..0509902512cc 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -169,10 +169,8 @@ static int tegra_alc5632_probe(struct platform_device *pdev)
169 169
170 alc5632 = devm_kzalloc(&pdev->dev, 170 alc5632 = devm_kzalloc(&pdev->dev,
171 sizeof(struct tegra_alc5632), GFP_KERNEL); 171 sizeof(struct tegra_alc5632), GFP_KERNEL);
172 if (!alc5632) { 172 if (!alc5632)
173 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
174 return -ENOMEM; 173 return -ENOMEM;
175 }
176 174
177 card->dev = &pdev->dev; 175 card->dev = &pdev->dev;
178 platform_set_drvdata(pdev, card); 176 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c
index a403db6d563e..c34a54d6e812 100644
--- a/sound/soc/tegra/tegra_max98090.c
+++ b/sound/soc/tegra/tegra_max98090.c
@@ -225,10 +225,8 @@ static int tegra_max98090_probe(struct platform_device *pdev)
225 225
226 machine = devm_kzalloc(&pdev->dev, 226 machine = devm_kzalloc(&pdev->dev,
227 sizeof(struct tegra_max98090), GFP_KERNEL); 227 sizeof(struct tegra_max98090), GFP_KERNEL);
228 if (!machine) { 228 if (!machine)
229 dev_err(&pdev->dev, "Can't allocate tegra_max98090\n");
230 return -ENOMEM; 229 return -ENOMEM;
231 }
232 230
233 card->dev = &pdev->dev; 231 card->dev = &pdev->dev;
234 platform_set_drvdata(pdev, card); 232 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 25b9fc03ba62..93a356802345 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -170,10 +170,8 @@ static int tegra_rt5640_probe(struct platform_device *pdev)
170 170
171 machine = devm_kzalloc(&pdev->dev, 171 machine = devm_kzalloc(&pdev->dev,
172 sizeof(struct tegra_rt5640), GFP_KERNEL); 172 sizeof(struct tegra_rt5640), GFP_KERNEL);
173 if (!machine) { 173 if (!machine)
174 dev_err(&pdev->dev, "Can't allocate tegra_rt5640\n");
175 return -ENOMEM; 174 return -ENOMEM;
176 }
177 175
178 card->dev = &pdev->dev; 176 card->dev = &pdev->dev;
179 platform_set_drvdata(pdev, card); 177 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c
index 4bbab098f50b..6dda01f69983 100644
--- a/sound/soc/tegra/tegra_sgtl5000.c
+++ b/sound/soc/tegra/tegra_sgtl5000.c
@@ -120,10 +120,8 @@ static int tegra_sgtl5000_driver_probe(struct platform_device *pdev)
120 120
121 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000), 121 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_sgtl5000),
122 GFP_KERNEL); 122 GFP_KERNEL);
123 if (!machine) { 123 if (!machine)
124 dev_err(&pdev->dev, "Can't allocate tegra_sgtl5000 struct\n");
125 return -ENOMEM; 124 return -ENOMEM;
126 }
127 125
128 card->dev = &pdev->dev; 126 card->dev = &pdev->dev;
129 platform_set_drvdata(pdev, card); 127 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index bdedd1028569..d0ab0026a4cd 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -128,10 +128,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev)
128 128
129 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753), 129 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753),
130 GFP_KERNEL); 130 GFP_KERNEL);
131 if (!machine) { 131 if (!machine)
132 dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
133 return -ENOMEM; 132 return -ENOMEM;
134 }
135 133
136 card->dev = &pdev->dev; 134 card->dev = &pdev->dev;
137 platform_set_drvdata(pdev, card); 135 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 2013e9c4bba0..dbfb49298ae8 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -248,10 +248,8 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev)
248 248
249 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), 249 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903),
250 GFP_KERNEL); 250 GFP_KERNEL);
251 if (!machine) { 251 if (!machine)
252 dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n");
253 return -ENOMEM; 252 return -ENOMEM;
254 }
255 253
256 card->dev = &pdev->dev; 254 card->dev = &pdev->dev;
257 platform_set_drvdata(pdev, card); 255 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 6492f8143ff1..c9cd22432627 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -77,10 +77,8 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev)
77 77
78 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712), 78 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
79 GFP_KERNEL); 79 GFP_KERNEL);
80 if (!machine) { 80 if (!machine)
81 dev_err(&pdev->dev, "Can't allocate tegra_wm9712 struct\n");
82 return -ENOMEM; 81 return -ENOMEM;
83 }
84 82
85 card->dev = &pdev->dev; 83 card->dev = &pdev->dev;
86 platform_set_drvdata(pdev, card); 84 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 870f84ab5005..c9dcad9bb931 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -123,10 +123,8 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev)
123 123
124 trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice), 124 trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice),
125 GFP_KERNEL); 125 GFP_KERNEL);
126 if (!trimslice) { 126 if (!trimslice)
127 dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n");
128 return -ENOMEM; 127 return -ENOMEM;
129 }
130 128
131 card->dev = &pdev->dev; 129 card->dev = &pdev->dev;
132 platform_set_drvdata(pdev, card); 130 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index a8f705bb60dc..7912bf09dc4d 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -206,7 +206,7 @@ static void txx9aclc_dma_tasklet(unsigned long data)
206static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 206static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
207{ 207{
208 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; 208 struct txx9aclc_dmadata *dmadata = substream->runtime->private_data;
209 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; 209 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
210 void __iomem *base = drvdata->base; 210 void __iomem *base = drvdata->base;
211 unsigned long flags; 211 unsigned long flags;
212 int ret = 0; 212 int ret = 0;
@@ -340,7 +340,7 @@ static bool filter(struct dma_chan *chan, void *param)
340static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, 340static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
341 struct txx9aclc_dmadata *dmadata) 341 struct txx9aclc_dmadata *dmadata)
342{ 342{
343 struct txx9aclc_plat_drvdata *drvdata =txx9aclc_drvdata; 343 struct txx9aclc_plat_drvdata *drvdata = txx9aclc_drvdata;
344 struct txx9dmac_slave *ds = &dmadata->dma_slave; 344 struct txx9dmac_slave *ds = &dmadata->dma_slave;
345 dma_cap_mask_t mask; 345 dma_cap_mask_t mask;
346 346
@@ -392,6 +392,7 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform)
392 for (i = 0; i < 2; i++) { 392 for (i = 0; i < 2; i++) {
393 struct txx9aclc_dmadata *dmadata = &dev->dmadata[i]; 393 struct txx9aclc_dmadata *dmadata = &dev->dmadata[i];
394 struct dma_chan *chan = dmadata->dma_chan; 394 struct dma_chan *chan = dmadata->dma_chan;
395
395 if (chan) { 396 if (chan) {
396 dmadata->frag_count = -1; 397 dmadata->frag_count = -1;
397 dmaengine_terminate_all(chan); 398 dmaengine_terminate_all(chan);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index ba9fc099cf67..b50f68a439ce 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -33,7 +33,6 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
33 .stream_name = "ab8500_0", 33 .stream_name = "ab8500_0",
34 .cpu_dai_name = "ux500-msp-i2s.1", 34 .cpu_dai_name = "ux500-msp-i2s.1",
35 .codec_dai_name = "ab8500-codec-dai.0", 35 .codec_dai_name = "ab8500-codec-dai.0",
36 .platform_name = "ux500-msp-i2s.1",
37 .codec_name = "ab8500-codec.0", 36 .codec_name = "ab8500-codec.0",
38 .init = mop500_ab8500_machine_init, 37 .init = mop500_ab8500_machine_init,
39 .ops = mop500_ab8500_ops, 38 .ops = mop500_ab8500_ops,
@@ -43,7 +42,6 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
43 .stream_name = "ab8500_1", 42 .stream_name = "ab8500_1",
44 .cpu_dai_name = "ux500-msp-i2s.3", 43 .cpu_dai_name = "ux500-msp-i2s.3",
45 .codec_dai_name = "ab8500-codec-dai.1", 44 .codec_dai_name = "ab8500-codec-dai.1",
46 .platform_name = "ux500-msp-i2s.3",
47 .codec_name = "ab8500-codec.0", 45 .codec_name = "ab8500-codec.0",
48 .init = NULL, 46 .init = NULL,
49 .ops = mop500_ab8500_ops, 47 .ops = mop500_ab8500_ops,
@@ -87,8 +85,6 @@ static int mop500_of_probe(struct platform_device *pdev,
87 for (i = 0; i < 2; i++) { 85 for (i = 0; i < 2; i++) {
88 mop500_dai_links[i].cpu_of_node = msp_np[i]; 86 mop500_dai_links[i].cpu_of_node = msp_np[i];
89 mop500_dai_links[i].cpu_dai_name = NULL; 87 mop500_dai_links[i].cpu_dai_name = NULL;
90 mop500_dai_links[i].platform_of_node = msp_np[i];
91 mop500_dai_links[i].platform_name = NULL;
92 mop500_dai_links[i].codec_of_node = codec_np; 88 mop500_dai_links[i].codec_of_node = codec_np;
93 mop500_dai_links[i].codec_name = NULL; 89 mop500_dai_links[i].codec_name = NULL;
94 } 90 }
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index b343efd9be5b..ec5152aa3f6e 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -133,6 +133,7 @@ static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
133 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); 133 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
134 134
135 u32 frame_length = MSP_FRAME_LEN_1; 135 u32 frame_length = MSP_FRAME_LEN_1;
136
136 prot_desc->frame_width = 0; 137 prot_desc->frame_width = 0;
137 138
138 switch (drvdata->slots) { 139 switch (drvdata->slots) {
@@ -482,7 +483,8 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
482 if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) && 483 if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) &&
483 (drvdata->msp->f_bitclk > 19200000)) { 484 (drvdata->msp->f_bitclk > 19200000)) {
484 /* If the bit-clock is higher than 19.2MHz, Vape should be 485 /* If the bit-clock is higher than 19.2MHz, Vape should be
485 * run in 100% OPP. Only when bit-clock is used (MSP master) */ 486 * run in 100% OPP. Only when bit-clock is used (MSP master)
487 */
486 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP, 488 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
487 "ux500-msp-i2s", 100); 489 "ux500-msp-i2s", 100);
488 drvdata->vape_opp_constraint = 1; 490 drvdata->vape_opp_constraint = 1;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 959d7b4edf56..bd5266aca0f1 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -604,7 +604,6 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
604 break; 604 break;
605 default: 605 default:
606 return -EINVAL; 606 return -EINVAL;
607 break;
608 } 607 }
609 608
610 return 0; 609 return 0;
diff --git a/sound/soc/zte/Kconfig b/sound/soc/zte/Kconfig
index 6d8a90d36315..75f67a5d23ea 100644
--- a/sound/soc/zte/Kconfig
+++ b/sound/soc/zte/Kconfig
@@ -15,3 +15,11 @@ config ZX_I2S
15 help 15 help
16 Say Y or M if you want to add support for codecs attached to the 16 Say Y or M if you want to add support for codecs attached to the
17 ZTE ZX I2S interface 17 ZTE ZX I2S interface
18
19config ZX_TDM
20 tristate "ZTE ZX TDM Driver Support"
21 depends on COMMON_CLK
22 select SND_SOC_GENERIC_DMAENGINE_PCM
23 help
24 Say Y or M if you want to add support for codecs attached to the
25 ZTE ZX TDM interface
diff --git a/sound/soc/zte/Makefile b/sound/soc/zte/Makefile
index 77768f5fd10c..1fc841acdfdd 100644
--- a/sound/soc/zte/Makefile
+++ b/sound/soc/zte/Makefile
@@ -1,2 +1,3 @@
1obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o 1obj-$(CONFIG_ZX_SPDIF) += zx-spdif.o
2obj-$(CONFIG_ZX_I2S) += zx-i2s.o 2obj-$(CONFIG_ZX_I2S) += zx-i2s.o
3obj-$(CONFIG_ZX_TDM) += zx-tdm.o
diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c
new file mode 100644
index 000000000000..bd632cc503b3
--- /dev/null
+++ b/sound/soc/zte/zx-tdm.c
@@ -0,0 +1,461 @@
1/*
2 * ZTE's TDM driver
3 *
4 * Copyright (C) 2017 ZTE Ltd
5 *
6 * Author: Baoyou Xie <baoyou.xie@linaro.org>
7 *
8 * License terms: GNU General Public License (GPL) version 2
9 */
10
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/mfd/syscon.h>
14#include <linux/module.h>
15#include <sound/dmaengine_pcm.h>
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18#include <sound/soc-dai.h>
19
20#define REG_TIMING_CTRL 0x04
21#define REG_TX_FIFO_CTRL 0x0C
22#define REG_RX_FIFO_CTRL 0x10
23#define REG_INT_EN 0x1C
24#define REG_INT_STATUS 0x20
25#define REG_DATABUF 0x24
26#define REG_TS_MASK0 0x44
27#define REG_PROCESS_CTRL 0x54
28
29#define FIFO_CTRL_TX_RST BIT(0)
30#define FIFO_CTRL_RX_RST BIT(0)
31#define DEAGULT_FIFO_THRES GENMASK(4, 2)
32
33#define FIFO_CTRL_TX_DMA_EN BIT(1)
34#define FIFO_CTRL_RX_DMA_EN BIT(1)
35
36#define TX_FIFO_RST_MASK BIT(0)
37#define RX_FIFO_RST_MASK BIT(0)
38
39#define FIFOCTRL_TX_FIFO_RST BIT(0)
40#define FIFOCTRL_RX_FIFO_RST BIT(0)
41
42#define TXTH_MASK GENMASK(5, 2)
43#define RXTH_MASK GENMASK(5, 2)
44
45#define FIFOCTRL_THRESHOLD(x) ((x) << 2)
46
47#define TIMING_MS_MASK BIT(1)
48/*
49 * 00: 8 clk cycles every timeslot
50 * 01: 16 clk cycles every timeslot
51 * 10: 32 clk cycles every timeslot
52 */
53#define TIMING_SYNC_WIDTH_MASK GENMASK(6, 5)
54#define TIMING_WIDTH_SHIFT 5
55#define TIMING_DEFAULT_WIDTH 0
56#define TIMING_TS_WIDTH(x) ((x) << TIMING_WIDTH_SHIFT)
57#define TIMING_WIDTH_FACTOR 8
58
59#define TIMING_MASTER_MODE BIT(21)
60#define TIMING_LSB_FIRST BIT(20)
61#define TIMING_TS_NUM(x) (((x) - 1) << 7)
62#define TIMING_CLK_SEL_MASK GENMASK(2, 0)
63#define TIMING_CLK_SEL_DEF BIT(2)
64
65#define PROCESS_TX_EN BIT(0)
66#define PROCESS_RX_EN BIT(1)
67#define PROCESS_TDM_EN BIT(2)
68#define PROCESS_DISABLE_ALL 0
69
70#define INT_DISABLE_ALL 0
71#define INT_STATUS_MASK GENMASK(6, 0)
72
73struct zx_tdm_info {
74 struct snd_dmaengine_dai_dma_data dma_playback;
75 struct snd_dmaengine_dai_dma_data dma_capture;
76 resource_size_t phy_addr;
77 void __iomem *regbase;
78 struct clk *dai_wclk;
79 struct clk *dai_pclk;
80 int master;
81 struct device *dev;
82};
83
84static inline u32 zx_tdm_readl(struct zx_tdm_info *tdm, u16 reg)
85{
86 return readl_relaxed(tdm->regbase + reg);
87}
88
89static inline void zx_tdm_writel(struct zx_tdm_info *tdm, u16 reg, u32 val)
90{
91 writel_relaxed(val, tdm->regbase + reg);
92}
93
94static void zx_tdm_tx_en(struct zx_tdm_info *tdm, bool on)
95{
96 unsigned long val;
97
98 val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
99 if (on)
100 val |= PROCESS_TX_EN | PROCESS_TDM_EN;
101 else
102 val &= ~(PROCESS_TX_EN | PROCESS_TDM_EN);
103 zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
104}
105
106static void zx_tdm_rx_en(struct zx_tdm_info *tdm, bool on)
107{
108 unsigned long val;
109
110 val = zx_tdm_readl(tdm, REG_PROCESS_CTRL);
111 if (on)
112 val |= PROCESS_RX_EN | PROCESS_TDM_EN;
113 else
114 val &= ~(PROCESS_RX_EN | PROCESS_TDM_EN);
115 zx_tdm_writel(tdm, REG_PROCESS_CTRL, val);
116}
117
118static void zx_tdm_tx_dma_en(struct zx_tdm_info *tdm, bool on)
119{
120 unsigned long val;
121
122 val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
123 val |= FIFO_CTRL_TX_RST | DEAGULT_FIFO_THRES;
124 if (on)
125 val |= FIFO_CTRL_TX_DMA_EN;
126 else
127 val &= ~FIFO_CTRL_TX_DMA_EN;
128 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
129}
130
131static void zx_tdm_rx_dma_en(struct zx_tdm_info *tdm, bool on)
132{
133 unsigned long val;
134
135 val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
136 val |= FIFO_CTRL_RX_RST | DEAGULT_FIFO_THRES;
137 if (on)
138 val |= FIFO_CTRL_RX_DMA_EN;
139 else
140 val &= ~FIFO_CTRL_RX_DMA_EN;
141 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
142}
143
144#define ZX_TDM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
145
146#define ZX_TDM_FMTBIT \
147 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_MU_LAW | \
148 SNDRV_PCM_FORMAT_A_LAW)
149
150static int zx_tdm_dai_probe(struct snd_soc_dai *dai)
151{
152 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
153
154 snd_soc_dai_set_drvdata(dai, zx_tdm);
155 zx_tdm->dma_playback.addr = zx_tdm->phy_addr + REG_DATABUF;
156 zx_tdm->dma_playback.maxburst = 16;
157 zx_tdm->dma_capture.addr = zx_tdm->phy_addr + REG_DATABUF;
158 zx_tdm->dma_capture.maxburst = 16;
159 snd_soc_dai_init_dma_data(dai, &zx_tdm->dma_playback,
160 &zx_tdm->dma_capture);
161 return 0;
162}
163
164static int zx_tdm_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
165{
166 struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(cpu_dai);
167 unsigned long val;
168
169 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
170 val &= ~(TIMING_SYNC_WIDTH_MASK | TIMING_MS_MASK);
171 val |= TIMING_DEFAULT_WIDTH << TIMING_WIDTH_SHIFT;
172
173 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
174 case SND_SOC_DAIFMT_CBM_CFM:
175 tdm->master = 1;
176 val |= TIMING_MASTER_MODE;
177 break;
178 case SND_SOC_DAIFMT_CBS_CFS:
179 tdm->master = 0;
180 val &= ~TIMING_MASTER_MODE;
181 break;
182 default:
183 dev_err(cpu_dai->dev, "Unknown master/slave format\n");
184 return -EINVAL;
185 }
186
187
188 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
189
190 return 0;
191}
192
193static int zx_tdm_hw_params(struct snd_pcm_substream *substream,
194 struct snd_pcm_hw_params *params,
195 struct snd_soc_dai *socdai)
196{
197 struct zx_tdm_info *tdm = snd_soc_dai_get_drvdata(socdai);
198 struct snd_dmaengine_dai_dma_data *dma_data;
199 unsigned int ts_width = TIMING_DEFAULT_WIDTH;
200 unsigned int ch_num = 32;
201 unsigned int mask = 0;
202 unsigned int ret = 0;
203 unsigned long val;
204
205 dma_data = snd_soc_dai_get_dma_data(socdai, substream);
206 dma_data->addr_width = ch_num >> 3;
207
208 switch (params_format(params)) {
209 case SNDRV_PCM_FORMAT_MU_LAW:
210 case SNDRV_PCM_FORMAT_A_LAW:
211 case SNDRV_PCM_FORMAT_S16_LE:
212 ts_width = 1;
213 break;
214 default:
215 ts_width = 0;
216 dev_err(socdai->dev, "Unknown data format\n");
217 return -EINVAL;
218 }
219
220 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
221 val |= TIMING_TS_WIDTH(ts_width) | TIMING_TS_NUM(1);
222 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
223 zx_tdm_writel(tdm, REG_TS_MASK0, mask);
224
225 if (tdm->master)
226 ret = clk_set_rate(tdm->dai_wclk,
227 params_rate(params) * TIMING_WIDTH_FACTOR * ch_num);
228
229 return ret;
230}
231
232static int zx_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
233 struct snd_soc_dai *dai)
234{
235 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
236 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
237 unsigned int val;
238 int ret = 0;
239
240 switch (cmd) {
241 case SNDRV_PCM_TRIGGER_START:
242 if (capture) {
243 val = zx_tdm_readl(zx_tdm, REG_RX_FIFO_CTRL);
244 val |= FIFOCTRL_RX_FIFO_RST;
245 zx_tdm_writel(zx_tdm, REG_RX_FIFO_CTRL, val);
246
247 zx_tdm_rx_dma_en(zx_tdm, true);
248 } else {
249 val = zx_tdm_readl(zx_tdm, REG_TX_FIFO_CTRL);
250 val |= FIFOCTRL_TX_FIFO_RST;
251 zx_tdm_writel(zx_tdm, REG_TX_FIFO_CTRL, val);
252
253 zx_tdm_tx_dma_en(zx_tdm, true);
254 }
255 break;
256 case SNDRV_PCM_TRIGGER_RESUME:
257 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
258 if (capture)
259 zx_tdm_rx_en(zx_tdm, true);
260 else
261 zx_tdm_tx_en(zx_tdm, true);
262 break;
263 case SNDRV_PCM_TRIGGER_STOP:
264 if (capture)
265 zx_tdm_rx_dma_en(zx_tdm, false);
266 else
267 zx_tdm_tx_dma_en(zx_tdm, false);
268 break;
269 case SNDRV_PCM_TRIGGER_SUSPEND:
270 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
271 if (capture)
272 zx_tdm_rx_en(zx_tdm, false);
273 else
274 zx_tdm_tx_en(zx_tdm, false);
275 break;
276 default:
277 ret = -EINVAL;
278 break;
279 }
280
281 return ret;
282}
283
284static int zx_tdm_startup(struct snd_pcm_substream *substream,
285 struct snd_soc_dai *dai)
286{
287 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
288 int ret;
289
290 ret = clk_prepare_enable(zx_tdm->dai_wclk);
291 if (ret)
292 return ret;
293
294 ret = clk_prepare_enable(zx_tdm->dai_pclk);
295 if (ret) {
296 clk_disable_unprepare(zx_tdm->dai_wclk);
297 return ret;
298 }
299
300 return 0;
301}
302
303static void zx_tdm_shutdown(struct snd_pcm_substream *substream,
304 struct snd_soc_dai *dai)
305{
306 struct zx_tdm_info *zx_tdm = dev_get_drvdata(dai->dev);
307
308 clk_disable_unprepare(zx_tdm->dai_pclk);
309 clk_disable_unprepare(zx_tdm->dai_wclk);
310}
311
312static struct snd_soc_dai_ops zx_tdm_dai_ops = {
313 .trigger = zx_tdm_trigger,
314 .hw_params = zx_tdm_hw_params,
315 .set_fmt = zx_tdm_set_fmt,
316 .startup = zx_tdm_startup,
317 .shutdown = zx_tdm_shutdown,
318};
319
320static const struct snd_soc_component_driver zx_tdm_component = {
321 .name = "zx-tdm",
322};
323
324static void zx_tdm_init_state(struct zx_tdm_info *tdm)
325{
326 unsigned int val;
327
328 zx_tdm_writel(tdm, REG_PROCESS_CTRL, PROCESS_DISABLE_ALL);
329
330 val = zx_tdm_readl(tdm, REG_TIMING_CTRL);
331 val |= TIMING_LSB_FIRST;
332 val &= ~TIMING_CLK_SEL_MASK;
333 val |= TIMING_CLK_SEL_DEF;
334 zx_tdm_writel(tdm, REG_TIMING_CTRL, val);
335
336 zx_tdm_writel(tdm, REG_INT_EN, INT_DISABLE_ALL);
337 /*
338 * write INT_STATUS register to clear it.
339 */
340 zx_tdm_writel(tdm, REG_INT_STATUS, INT_STATUS_MASK);
341 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, FIFOCTRL_RX_FIFO_RST);
342 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, FIFOCTRL_TX_FIFO_RST);
343
344 val = zx_tdm_readl(tdm, REG_RX_FIFO_CTRL);
345 val &= ~(RXTH_MASK | RX_FIFO_RST_MASK);
346 val |= FIFOCTRL_THRESHOLD(8);
347 zx_tdm_writel(tdm, REG_RX_FIFO_CTRL, val);
348
349 val = zx_tdm_readl(tdm, REG_TX_FIFO_CTRL);
350 val &= ~(TXTH_MASK | TX_FIFO_RST_MASK);
351 val |= FIFOCTRL_THRESHOLD(8);
352 zx_tdm_writel(tdm, REG_TX_FIFO_CTRL, val);
353}
354
355static struct snd_soc_dai_driver zx_tdm_dai = {
356 .name = "zx-tdm-dai",
357 .id = 0,
358 .probe = zx_tdm_dai_probe,
359 .playback = {
360 .channels_min = 1,
361 .channels_max = 4,
362 .rates = ZX_TDM_RATES,
363 .formats = ZX_TDM_FMTBIT,
364 },
365 .capture = {
366 .channels_min = 1,
367 .channels_max = 4,
368 .rates = ZX_TDM_RATES,
369 .formats = ZX_TDM_FMTBIT,
370 },
371 .ops = &zx_tdm_dai_ops,
372};
373
374static int zx_tdm_probe(struct platform_device *pdev)
375{
376 struct device *dev = &pdev->dev;
377 struct of_phandle_args out_args;
378 unsigned int dma_reg_offset;
379 struct zx_tdm_info *zx_tdm;
380 unsigned int dma_mask;
381 struct resource *res;
382 struct regmap *regmap_sysctrl;
383 int ret;
384
385 zx_tdm = devm_kzalloc(&pdev->dev, sizeof(*zx_tdm), GFP_KERNEL);
386 if (!zx_tdm)
387 return -ENOMEM;
388
389 zx_tdm->dev = dev;
390
391 zx_tdm->dai_wclk = devm_clk_get(&pdev->dev, "wclk");
392 if (IS_ERR(zx_tdm->dai_wclk)) {
393 dev_err(&pdev->dev, "Fail to get wclk\n");
394 return PTR_ERR(zx_tdm->dai_wclk);
395 }
396
397 zx_tdm->dai_pclk = devm_clk_get(&pdev->dev, "pclk");
398 if (IS_ERR(zx_tdm->dai_pclk)) {
399 dev_err(&pdev->dev, "Fail to get pclk\n");
400 return PTR_ERR(zx_tdm->dai_pclk);
401 }
402
403 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
404 zx_tdm->phy_addr = res->start;
405 zx_tdm->regbase = devm_ioremap_resource(&pdev->dev, res);
406 if (IS_ERR(zx_tdm->regbase))
407 return PTR_ERR(zx_tdm->regbase);
408
409 ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
410 "zte,tdm-dma-sysctrl", 2, 0, &out_args);
411 if (ret) {
412 dev_err(&pdev->dev, "Fail to get zte,tdm-dma-sysctrl\n");
413 return ret;
414 }
415
416 dma_reg_offset = out_args.args[0];
417 dma_mask = out_args.args[1];
418 regmap_sysctrl = syscon_node_to_regmap(out_args.np);
419 if (IS_ERR(regmap_sysctrl)) {
420 of_node_put(out_args.np);
421 return PTR_ERR(regmap_sysctrl);
422 }
423
424 regmap_update_bits(regmap_sysctrl, dma_reg_offset, dma_mask, dma_mask);
425 of_node_put(out_args.np);
426
427 zx_tdm_init_state(zx_tdm);
428 platform_set_drvdata(pdev, zx_tdm);
429
430 ret = devm_snd_soc_register_component(&pdev->dev, &zx_tdm_component,
431 &zx_tdm_dai, 1);
432 if (ret) {
433 dev_err(&pdev->dev, "Register DAI failed: %d\n", ret);
434 return ret;
435 }
436
437 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
438 if (ret)
439 dev_err(&pdev->dev, "Register platform PCM failed: %d\n", ret);
440
441 return ret;
442}
443
444static const struct of_device_id zx_tdm_dt_ids[] = {
445 { .compatible = "zte,zx296718-tdm", },
446 {}
447};
448MODULE_DEVICE_TABLE(of, zx_tdm_dt_ids);
449
450static struct platform_driver tdm_driver = {
451 .probe = zx_tdm_probe,
452 .driver = {
453 .name = "zx-tdm",
454 .of_match_table = zx_tdm_dt_ids,
455 },
456};
457module_platform_driver(tdm_driver);
458
459MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
460MODULE_DESCRIPTION("ZTE TDM DAI driver");
461MODULE_LICENSE("GPL v2");