aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/atmel/Kconfig6
-rw-r--r--sound/soc/atmel/atmel-pcm-pdc.c4
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel-pcm.h6
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c14
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c6
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c7
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c6
-rw-r--r--sound/soc/codecs/Kconfig9
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ab8500-codec.c2
-rw-r--r--sound/soc/codecs/ak4642.c33
-rw-r--r--sound/soc/codecs/arizona.c269
-rw-r--r--sound/soc/codecs/arizona.h8
-rw-r--r--sound/soc/codecs/cs4271.c34
-rw-r--r--sound/soc/codecs/cs42l52.c4
-rw-r--r--sound/soc/codecs/da7213.c1599
-rw-r--r--sound/soc/codecs/da7213.h523
-rw-r--r--sound/soc/codecs/jz4740.c6
-rwxr-xr-x[-rw-r--r--]sound/soc/codecs/max98090.c2685
-rwxr-xr-xsound/soc/codecs/max98090.h1549
-rw-r--r--sound/soc/codecs/tlv320aic3x.c87
-rw-r--r--sound/soc/codecs/tlv320aic3x.h4
-rw-r--r--sound/soc/codecs/tlv320dac33.c16
-rw-r--r--sound/soc/codecs/twl4030.c85
-rw-r--r--sound/soc/codecs/twl6040.c62
-rw-r--r--sound/soc/codecs/wm2000.c66
-rw-r--r--sound/soc/codecs/wm2000.h3
-rw-r--r--sound/soc/codecs/wm2200.c65
-rw-r--r--sound/soc/codecs/wm5100.c13
-rw-r--r--sound/soc/codecs/wm5102.c166
-rw-r--r--sound/soc/codecs/wm5110.c101
-rw-r--r--sound/soc/codecs/wm8350.c10
-rw-r--r--sound/soc/codecs/wm8804.c3
-rw-r--r--sound/soc/codecs/wm8962.c37
-rw-r--r--sound/soc/codecs/wm8974.c6
-rw-r--r--sound/soc/codecs/wm8978.c6
-rw-r--r--sound/soc/codecs/wm8983.c47
-rw-r--r--sound/soc/codecs/wm8985.c49
-rw-r--r--sound/soc/codecs/wm8994.c10
-rw-r--r--sound/soc/codecs/wm_adsp.c527
-rw-r--r--sound/soc/codecs/wm_adsp.h18
-rw-r--r--sound/soc/codecs/wmfw.h15
-rw-r--r--sound/soc/davinci/davinci-evm.c6
-rw-r--r--sound/soc/davinci/davinci-mcasp.c2
-rw-r--r--sound/soc/dwc/designware_i2s.c4
-rw-r--r--sound/soc/fsl/imx-audmux.c8
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c21
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c22
-rw-r--r--sound/soc/fsl/imx-pcm.c32
-rw-r--r--sound/soc/fsl/imx-pcm.h18
-rw-r--r--sound/soc/fsl/imx-ssi.c7
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
-rw-r--r--sound/soc/generic/simple-card.c63
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c8
-rw-r--r--sound/soc/mxs/mxs-saif.c57
-rw-r--r--sound/soc/omap/Kconfig19
-rw-r--r--sound/soc/omap/Makefile4
-rw-r--r--sound/soc/omap/n810.c4
-rw-r--r--sound/soc/omap/omap-hdmi.c2
-rw-r--r--sound/soc/omap/omap-mcpdm.c4
-rw-r--r--sound/soc/omap/omap-pcm.c14
-rw-r--r--sound/soc/omap/omap-twl4030.c204
-rw-r--r--sound/soc/omap/omap3pandora.c8
-rw-r--r--sound/soc/omap/rx51.c8
-rw-r--r--sound/soc/omap/sdp3430.c278
-rw-r--r--sound/soc/omap/zoom2.c207
-rw-r--r--sound/soc/pxa/mmp-sspa.c6
-rw-r--r--sound/soc/pxa/palm27x.c38
-rw-r--r--sound/soc/samsung/Kconfig6
-rw-r--r--sound/soc/samsung/dma.c3
-rw-r--r--sound/soc/samsung/dma.h1
-rw-r--r--sound/soc/samsung/h1940_uda1380.c13
-rw-r--r--sound/soc/samsung/i2s.c267
-rw-r--r--sound/soc/samsung/i2s.h7
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c8
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c2
-rw-r--r--sound/soc/samsung/smdk_wm8580.c7
-rw-r--r--sound/soc/samsung/smdk_wm8994.c30
-rw-r--r--sound/soc/sh/fsi.c242
-rw-r--r--sound/soc/soc-compress.c123
-rw-r--r--sound/soc/soc-core.c135
-rw-r--r--sound/soc/soc-dapm.c18
-rw-r--r--sound/soc/soc-pcm.c19
-rw-r--r--sound/soc/tegra/Kconfig19
-rw-r--r--sound/soc/tegra/Makefile4
-rw-r--r--sound/soc/tegra/tegra20_ac97.c480
-rw-r--r--sound/soc/tegra/tegra20_ac97.h95
-rw-r--r--sound/soc/tegra/tegra20_das.c13
-rw-r--r--sound/soc/tegra/tegra30_ahub.c20
-rw-r--r--sound/soc/tegra/tegra30_i2s.c4
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c53
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h1
-rw-r--r--sound/soc/tegra/tegra_wm9712.c176
-rw-r--r--sound/soc/ux500/mop500.c2
95 files changed, 9142 insertions, 1824 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index d1b691bf8e2d..3fdd87fa18a9 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -1,6 +1,6 @@
1config SND_ATMEL_SOC 1config SND_ATMEL_SOC
2 tristate "SoC Audio for the Atmel System-on-Chip" 2 tristate "SoC Audio for the Atmel System-on-Chip"
3 depends on ARCH_AT91 3 depends on HAS_IOMEM
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the ATMEL SSC interface. You will also need 6 the ATMEL SSC interface. You will also need
@@ -24,7 +24,7 @@ config SND_ATMEL_SOC_SSC
24 24
25config SND_AT91_SOC_SAM9G20_WM8731 25config SND_AT91_SOC_SAM9G20_WM8731
26 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 26 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
27 depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS 27 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS
28 select SND_ATMEL_SOC_PDC 28 select SND_ATMEL_SOC_PDC
29 select SND_ATMEL_SOC_SSC 29 select SND_ATMEL_SOC_SSC
30 select SND_SOC_WM8731 30 select SND_SOC_WM8731
@@ -34,7 +34,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
34 34
35config SND_AT91_SOC_AFEB9260 35config SND_AT91_SOC_AFEB9260
36 tristate "SoC Audio support for AFEB9260 board" 36 tristate "SoC Audio support for AFEB9260 board"
37 depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC 37 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
38 select SND_ATMEL_SOC_PDC 38 select SND_ATMEL_SOC_PDC
39 select SND_ATMEL_SOC_SSC 39 select SND_ATMEL_SOC_SSC
40 select SND_SOC_TLV320AIC23 40 select SND_SOC_TLV320AIC23
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index 6a293c713a38..054ea4d9326a 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -159,7 +159,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
159 159
160 pr_debug("atmel-pcm: " 160 pr_debug("atmel-pcm: "
161 "hw_params: DMA for %s initialized " 161 "hw_params: DMA for %s initialized "
162 "(dma_bytes=%u, period_size=%u)\n", 162 "(dma_bytes=%zu, period_size=%zu)\n",
163 prtd->params->name, 163 prtd->params->name,
164 runtime->dma_bytes, 164 runtime->dma_bytes,
165 prtd->period_size); 165 prtd->period_size);
@@ -201,7 +201,7 @@ static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
201 int ret = 0; 201 int ret = 0;
202 202
203 pr_debug("atmel-pcm:buffer_size = %ld," 203 pr_debug("atmel-pcm:buffer_size = %ld,"
204 "dma_area = %p, dma_bytes = %u\n", 204 "dma_area = %p, dma_bytes = %zu\n",
205 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes); 205 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
206 206
207 switch (cmd) { 207 switch (cmd) {
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index e99f1811300a..3109db7b9017 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -49,7 +49,7 @@ static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
49 buf->private_data = NULL; 49 buf->private_data = NULL;
50 buf->area = dma_alloc_coherent(pcm->card->dev, size, 50 buf->area = dma_alloc_coherent(pcm->card->dev, size,
51 &buf->addr, GFP_KERNEL); 51 &buf->addr, GFP_KERNEL);
52 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n", 52 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
53 (void *)buf->area, (void *)buf->addr, size); 53 (void *)buf->area, (void *)buf->addr, size);
54 54
55 if (!buf->area) 55 if (!buf->area)
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index bb45d20e7250..12ae814eff21 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -88,7 +88,8 @@ void atmel_pcm_free(struct snd_pcm *pcm);
88int atmel_pcm_mmap(struct snd_pcm_substream *substream, 88int atmel_pcm_mmap(struct snd_pcm_substream *substream,
89 struct vm_area_struct *vma); 89 struct vm_area_struct *vma);
90 90
91#ifdef CONFIG_SND_ATMEL_SOC_PDC 91#if defined(CONFIG_SND_ATMEL_SOC_PDC) || \
92 defined(CONFIG_SND_ATMEL_SOC_PDC_MODULE)
92int atmel_pcm_pdc_platform_register(struct device *dev); 93int atmel_pcm_pdc_platform_register(struct device *dev);
93void atmel_pcm_pdc_platform_unregister(struct device *dev); 94void atmel_pcm_pdc_platform_unregister(struct device *dev);
94#else 95#else
@@ -101,7 +102,8 @@ static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
101} 102}
102#endif 103#endif
103 104
104#ifdef CONFIG_SND_ATMEL_SOC_DMA 105#if defined(CONFIG_SND_ATMEL_SOC_DMA) || \
106 defined(CONFIG_SND_ATMEL_SOC_DMA_MODULE)
105int atmel_pcm_dma_platform_register(struct device *dev); 107int atmel_pcm_dma_platform_register(struct device *dev);
106void atmel_pcm_dma_platform_unregister(struct device *dev); 108void atmel_pcm_dma_platform_unregister(struct device *dev);
107#else 109#else
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 1c7663422054..e13580d6c476 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -42,8 +42,6 @@
42#include <sound/initval.h> 42#include <sound/initval.h>
43#include <sound/soc.h> 43#include <sound/soc.h>
44 44
45#include <mach/hardware.h>
46
47#include "atmel-pcm.h" 45#include "atmel-pcm.h"
48#include "atmel_ssc_dai.h" 46#include "atmel_ssc_dai.h"
49 47
@@ -679,15 +677,6 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
679# define atmel_ssc_resume NULL 677# define atmel_ssc_resume NULL
680#endif /* CONFIG_PM */ 678#endif /* CONFIG_PM */
681 679
682static int atmel_ssc_probe(struct snd_soc_dai *dai)
683{
684 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
685
686 snd_soc_dai_set_drvdata(dai, ssc_p);
687
688 return 0;
689}
690
691#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000) 680#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
692 681
693#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 682#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
@@ -703,7 +692,6 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
703}; 692};
704 693
705static struct snd_soc_dai_driver atmel_ssc_dai = { 694static struct snd_soc_dai_driver atmel_ssc_dai = {
706 .probe = atmel_ssc_probe,
707 .suspend = atmel_ssc_suspend, 695 .suspend = atmel_ssc_suspend,
708 .resume = atmel_ssc_resume, 696 .resume = atmel_ssc_resume,
709 .playback = { 697 .playback = {
@@ -790,8 +778,8 @@ void atmel_ssc_put_audio(int ssc_id)
790{ 778{
791 struct ssc_device *ssc = ssc_info[ssc_id].ssc; 779 struct ssc_device *ssc = ssc_info[ssc_id].ssc;
792 780
793 ssc_free(ssc);
794 asoc_ssc_exit(&ssc->pdev->dev); 781 asoc_ssc_exit(&ssc->pdev->dev);
782 ssc_free(ssc);
795} 783}
796EXPORT_SYMBOL_GPL(atmel_ssc_put_audio); 784EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
797 785
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index da976291da9e..2d6fbd0125b9 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -305,10 +305,10 @@ static int at91sam9g20ek_audio_remove(struct platform_device *pdev)
305{ 305{
306 struct snd_soc_card *card = platform_get_drvdata(pdev); 306 struct snd_soc_card *card = platform_get_drvdata(pdev);
307 307
308 atmel_ssc_put_audio(0); 308 clk_disable(mclk);
309 snd_soc_unregister_card(card);
310 clk_put(mclk);
311 mclk = NULL; 309 mclk = NULL;
310 snd_soc_unregister_card(card);
311 atmel_ssc_put_audio(0);
312 312
313 return 0; 313 return 0;
314} 314}
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index f3f50e6fd6eb..1738d28fb04f 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/err.h>
14#include <linux/io.h> 15#include <linux/io.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/module.h> 17#include <linux/module.h>
@@ -367,9 +368,9 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
367 if (!res) 368 if (!res)
368 return -ENODEV; 369 return -ENODEV;
369 370
370 info->regs = devm_request_and_ioremap(&pdev->dev, res); 371 info->regs = devm_ioremap_resource(&pdev->dev, res);
371 if (!info->regs) 372 if (IS_ERR(info->regs))
372 return -ENXIO; 373 return PTR_ERR(info->regs);
373 374
374 irq = platform_get_irq(pdev, 0); 375 irq = platform_get_irq(pdev, 0);
375 if (!irq) 376 if (!irq)
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 3365d4e843b7..323ed69b7975 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -380,9 +380,9 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
380 if (!res) 380 if (!res)
381 return -ENODEV; 381 return -ENODEV;
382 382
383 info->regs = devm_request_and_ioremap(&pdev->dev, res); 383 info->regs = devm_ioremap_resource(&pdev->dev, res);
384 if (!info->regs) 384 if (IS_ERR(info->regs))
385 return -ENXIO; 385 return PTR_ERR(info->regs);
386 386
387 info->mclk = clk_get(&pdev->dev, "mclk"); 387 info->mclk = clk_get(&pdev->dev, "mclk");
388 if (IS_ERR(info->mclk)) { 388 if (IS_ERR(info->mclk)) {
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3a847828932a..45b72561c615 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -34,8 +34,9 @@ config SND_SOC_ALL_CODECS
34 select SND_SOC_CS42L73 if I2C 34 select SND_SOC_CS42L73 if I2C
35 select SND_SOC_CS4270 if I2C 35 select SND_SOC_CS4270 if I2C
36 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 36 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_CX20442 37 select SND_SOC_CX20442 if TTY
38 select SND_SOC_DA7210 if I2C 38 select SND_SOC_DA7210 if I2C
39 select SND_SOC_DA7213 if I2C
39 select SND_SOC_DA732X if I2C 40 select SND_SOC_DA732X if I2C
40 select SND_SOC_DA9055 if I2C 41 select SND_SOC_DA9055 if I2C
41 select SND_SOC_DFBMCS320 42 select SND_SOC_DFBMCS320
@@ -98,7 +99,7 @@ config SND_SOC_ALL_CODECS
98 select SND_SOC_WM8782 99 select SND_SOC_WM8782
99 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI 100 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
100 select SND_SOC_WM8900 if I2C 101 select SND_SOC_WM8900 if I2C
101 select SND_SOC_WM8903 if I2C 102 select SND_SOC_WM8903 if I2C && GENERIC_HARDIRQS
102 select SND_SOC_WM8904 if I2C 103 select SND_SOC_WM8904 if I2C
103 select SND_SOC_WM8940 if I2C 104 select SND_SOC_WM8940 if I2C
104 select SND_SOC_WM8955 if I2C 105 select SND_SOC_WM8955 if I2C
@@ -236,6 +237,7 @@ config SND_SOC_CS4271
236 237
237config SND_SOC_CX20442 238config SND_SOC_CX20442
238 tristate 239 tristate
240 depends on TTY
239 241
240config SND_SOC_JZ4740_CODEC 242config SND_SOC_JZ4740_CODEC
241 select REGMAP_MMIO 243 select REGMAP_MMIO
@@ -247,6 +249,9 @@ config SND_SOC_L3
247config SND_SOC_DA7210 249config SND_SOC_DA7210
248 tristate 250 tristate
249 251
252config SND_SOC_DA7213
253 tristate
254
250config SND_SOC_DA732X 255config SND_SOC_DA732X
251 tristate 256 tristate
252 257
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f6e8e36cceb7..6a3b3c3b8b41 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -23,6 +23,7 @@ snd-soc-cs4270-objs := cs4270.o
23snd-soc-cs4271-objs := cs4271.o 23snd-soc-cs4271-objs := cs4271.o
24snd-soc-cx20442-objs := cx20442.o 24snd-soc-cx20442-objs := cx20442.o
25snd-soc-da7210-objs := da7210.o 25snd-soc-da7210-objs := da7210.o
26snd-soc-da7213-objs := da7213.o
26snd-soc-da732x-objs := da732x.o 27snd-soc-da732x-objs := da732x.o
27snd-soc-da9055-objs := da9055.o 28snd-soc-da9055-objs := da9055.o
28snd-soc-dfbmcs320-objs := dfbmcs320.o 29snd-soc-dfbmcs320-objs := dfbmcs320.o
@@ -147,6 +148,7 @@ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
147obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 148obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
148obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 149obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
149obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 150obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
151obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
150obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 152obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
151obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 153obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
152obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 154obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 6c12ac206ee9..a153b168129b 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2147,7 +2147,7 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2147 status = ab8500_codec_set_dai_clock_gate(codec, fmt); 2147 status = ab8500_codec_set_dai_clock_gate(codec, fmt);
2148 if (status) { 2148 if (status) {
2149 dev_err(dai->codec->dev, 2149 dev_err(dai->codec->dev,
2150 "%s: ERRROR: Failed to set clock gate (%d).\n", 2150 "%s: ERROR: Failed to set clock gate (%d).\n",
2151 __func__, status); 2151 __func__, status);
2152 return status; 2152 return status;
2153 } 2153 }
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 1f0cdab03294..2d0378709702 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/of_device.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <sound/soc.h> 31#include <sound/soc.h>
31#include <sound/initval.h> 32#include <sound/initval.h>
@@ -513,12 +514,31 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
513}; 514};
514 515
515#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 516#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
517static struct of_device_id ak4642_of_match[];
516static int ak4642_i2c_probe(struct i2c_client *i2c, 518static int ak4642_i2c_probe(struct i2c_client *i2c,
517 const struct i2c_device_id *id) 519 const struct i2c_device_id *id)
518{ 520{
521 struct device_node *np = i2c->dev.of_node;
522 const struct snd_soc_codec_driver *driver;
523
524 driver = NULL;
525 if (np) {
526 const struct of_device_id *of_id;
527
528 of_id = of_match_device(ak4642_of_match, &i2c->dev);
529 if (of_id)
530 driver = of_id->data;
531 } else {
532 driver = (struct snd_soc_codec_driver *)id->driver_data;
533 }
534
535 if (!driver) {
536 dev_err(&i2c->dev, "no driver\n");
537 return -EINVAL;
538 }
539
519 return snd_soc_register_codec(&i2c->dev, 540 return snd_soc_register_codec(&i2c->dev,
520 (struct snd_soc_codec_driver *)id->driver_data, 541 driver, &ak4642_dai, 1);
521 &ak4642_dai, 1);
522} 542}
523 543
524static int ak4642_i2c_remove(struct i2c_client *client) 544static int ak4642_i2c_remove(struct i2c_client *client)
@@ -527,6 +547,14 @@ static int ak4642_i2c_remove(struct i2c_client *client)
527 return 0; 547 return 0;
528} 548}
529 549
550static struct of_device_id ak4642_of_match[] = {
551 { .compatible = "asahi-kasei,ak4642", .data = &soc_codec_dev_ak4642},
552 { .compatible = "asahi-kasei,ak4643", .data = &soc_codec_dev_ak4642},
553 { .compatible = "asahi-kasei,ak4648", .data = &soc_codec_dev_ak4648},
554 {},
555};
556MODULE_DEVICE_TABLE(of, ak4642_of_match);
557
530static const struct i2c_device_id ak4642_i2c_id[] = { 558static const struct i2c_device_id ak4642_i2c_id[] = {
531 { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 }, 559 { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
532 { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 }, 560 { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
@@ -539,6 +567,7 @@ static struct i2c_driver ak4642_i2c_driver = {
539 .driver = { 567 .driver = {
540 .name = "ak4642-codec", 568 .name = "ak4642-codec",
541 .owner = THIS_MODULE, 569 .owner = THIS_MODULE,
570 .of_match_table = ak4642_of_match,
542 }, 571 },
543 .probe = ak4642_i2c_probe, 572 .probe = ak4642_i2c_probe,
544 .remove = ak4642_i2c_remove, 573 .remove = ak4642_i2c_remove,
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 1d8bb5917594..ac948a671ea6 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -56,14 +56,14 @@
56#define arizona_fll_warn(_fll, fmt, ...) \ 56#define arizona_fll_warn(_fll, fmt, ...) \
57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58#define arizona_fll_dbg(_fll, fmt, ...) \ 58#define arizona_fll_dbg(_fll, fmt, ...) \
59 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__) 59 dev_dbg(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60 60
61#define arizona_aif_err(_dai, fmt, ...) \ 61#define arizona_aif_err(_dai, fmt, ...) \
62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
63#define arizona_aif_warn(_dai, fmt, ...) \ 63#define arizona_aif_warn(_dai, fmt, ...) \
64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65#define arizona_aif_dbg(_dai, fmt, ...) \ 65#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) 66 dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67 67
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None", 69 "None",
@@ -141,6 +141,30 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
141 "ASRC1R", 141 "ASRC1R",
142 "ASRC2L", 142 "ASRC2L",
143 "ASRC2R", 143 "ASRC2R",
144 "ISRC1INT1",
145 "ISRC1INT2",
146 "ISRC1INT3",
147 "ISRC1INT4",
148 "ISRC1DEC1",
149 "ISRC1DEC2",
150 "ISRC1DEC3",
151 "ISRC1DEC4",
152 "ISRC2INT1",
153 "ISRC2INT2",
154 "ISRC2INT3",
155 "ISRC2INT4",
156 "ISRC2DEC1",
157 "ISRC2DEC2",
158 "ISRC2DEC3",
159 "ISRC2DEC4",
160 "ISRC3INT1",
161 "ISRC3INT2",
162 "ISRC3INT3",
163 "ISRC3INT4",
164 "ISRC3DEC1",
165 "ISRC3DEC2",
166 "ISRC3DEC3",
167 "ISRC3DEC4",
144}; 168};
145EXPORT_SYMBOL_GPL(arizona_mixer_texts); 169EXPORT_SYMBOL_GPL(arizona_mixer_texts);
146 170
@@ -220,6 +244,30 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
220 0x91, 244 0x91,
221 0x92, 245 0x92,
222 0x93, 246 0x93,
247 0xa0, /* ISRC1INT1 */
248 0xa1,
249 0xa2,
250 0xa3,
251 0xa4, /* ISRC1DEC1 */
252 0xa5,
253 0xa6,
254 0xa7,
255 0xa8, /* ISRC2DEC1 */
256 0xa9,
257 0xaa,
258 0xab,
259 0xac, /* ISRC2INT1 */
260 0xad,
261 0xae,
262 0xaf,
263 0xb0, /* ISRC3DEC1 */
264 0xb1,
265 0xb2,
266 0xb3,
267 0xb4, /* ISRC3INT1 */
268 0xb5,
269 0xb6,
270 0xb7,
223}; 271};
224EXPORT_SYMBOL_GPL(arizona_mixer_values); 272EXPORT_SYMBOL_GPL(arizona_mixer_values);
225 273
@@ -275,9 +323,35 @@ const struct soc_enum arizona_lhpf4_mode =
275 arizona_lhpf_mode_text); 323 arizona_lhpf_mode_text);
276EXPORT_SYMBOL_GPL(arizona_lhpf4_mode); 324EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
277 325
326static const char *arizona_ng_hold_text[] = {
327 "30ms", "120ms", "250ms", "500ms",
328};
329
330const struct soc_enum arizona_ng_hold =
331 SOC_ENUM_SINGLE(ARIZONA_NOISE_GATE_CONTROL, ARIZONA_NGATE_HOLD_SHIFT,
332 4, arizona_ng_hold_text);
333EXPORT_SYMBOL_GPL(arizona_ng_hold);
334
278int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 335int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
279 int event) 336 int event)
280{ 337{
338 unsigned int reg;
339
340 if (w->shift % 2)
341 reg = ARIZONA_ADC_DIGITAL_VOLUME_1L + ((w->shift / 2) * 8);
342 else
343 reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
344
345 switch (event) {
346 case SND_SOC_DAPM_POST_PMU:
347 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
348 break;
349 case SND_SOC_DAPM_PRE_PMD:
350 snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE,
351 ARIZONA_IN1L_MUTE);
352 break;
353 }
354
281 return 0; 355 return 0;
282} 356}
283EXPORT_SYMBOL_GPL(arizona_in_ev); 357EXPORT_SYMBOL_GPL(arizona_in_ev);
@@ -417,6 +491,10 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
417 case 147456000: 491 case 147456000:
418 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; 492 val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
419 break; 493 break;
494 case 0:
495 dev_dbg(arizona->dev, "%s cleared\n", name);
496 *clk = freq;
497 return 0;
420 default: 498 default:
421 return -EINVAL; 499 return -EINVAL;
422 } 500 }
@@ -635,6 +713,9 @@ static int arizona_startup(struct snd_pcm_substream *substream,
635 return 0; 713 return 0;
636 } 714 }
637 715
716 if (base_rate == 0)
717 return 0;
718
638 if (base_rate % 8000) 719 if (base_rate % 8000)
639 constraint = &arizona_44k1_constraint; 720 constraint = &arizona_44k1_constraint;
640 else 721 else
@@ -645,25 +726,81 @@ static int arizona_startup(struct snd_pcm_substream *substream,
645 constraint); 726 constraint);
646} 727}
647 728
729static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params,
731 struct snd_soc_dai *dai)
732{
733 struct snd_soc_codec *codec = dai->codec;
734 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
735 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
736 int base = dai->driver->base;
737 int i, sr_val;
738
739 /*
740 * We will need to be more flexible than this in future,
741 * currently we use a single sample rate for SYSCLK.
742 */
743 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
744 if (arizona_sr_vals[i] == params_rate(params))
745 break;
746 if (i == ARRAY_SIZE(arizona_sr_vals)) {
747 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
748 params_rate(params));
749 return -EINVAL;
750 }
751 sr_val = i;
752
753 switch (dai_priv->clk) {
754 case ARIZONA_CLK_SYSCLK:
755 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
756 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
757 if (base)
758 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
759 ARIZONA_AIF1_RATE_MASK, 0);
760 break;
761 case ARIZONA_CLK_ASYNCCLK:
762 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
763 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
764 if (base)
765 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
766 ARIZONA_AIF1_RATE_MASK,
767 8 << ARIZONA_AIF1_RATE_SHIFT);
768 break;
769 default:
770 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
771 return -EINVAL;
772 }
773
774 return 0;
775}
776
648static int arizona_hw_params(struct snd_pcm_substream *substream, 777static int arizona_hw_params(struct snd_pcm_substream *substream,
649 struct snd_pcm_hw_params *params, 778 struct snd_pcm_hw_params *params,
650 struct snd_soc_dai *dai) 779 struct snd_soc_dai *dai)
651{ 780{
652 struct snd_soc_codec *codec = dai->codec; 781 struct snd_soc_codec *codec = dai->codec;
653 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 782 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
654 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; 783 struct arizona *arizona = priv->arizona;
655 int base = dai->driver->base; 784 int base = dai->driver->base;
656 const int *rates; 785 const int *rates;
657 int i; 786 int i, ret;
658 int bclk, lrclk, wl, frame, sr_val; 787 int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
788 int bclk, lrclk, wl, frame, bclk_target;
659 789
660 if (params_rate(params) % 8000) 790 if (params_rate(params) % 8000)
661 rates = &arizona_44k1_bclk_rates[0]; 791 rates = &arizona_44k1_bclk_rates[0];
662 else 792 else
663 rates = &arizona_48k_bclk_rates[0]; 793 rates = &arizona_48k_bclk_rates[0];
664 794
795 bclk_target = snd_soc_params_to_bclk(params);
796 if (chan_limit && chan_limit < params_channels(params)) {
797 arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
798 bclk_target /= params_channels(params);
799 bclk_target *= chan_limit;
800 }
801
665 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { 802 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
666 if (rates[i] >= snd_soc_params_to_bclk(params) && 803 if (rates[i] >= bclk_target &&
667 rates[i] % params_rate(params) == 0) { 804 rates[i] % params_rate(params) == 0) {
668 bclk = i; 805 bclk = i;
669 break; 806 break;
@@ -675,17 +812,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
675 return -EINVAL; 812 return -EINVAL;
676 } 813 }
677 814
678 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++) 815 lrclk = rates[bclk] / params_rate(params);
679 if (arizona_sr_vals[i] == params_rate(params))
680 break;
681 if (i == ARRAY_SIZE(arizona_sr_vals)) {
682 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
683 params_rate(params));
684 return -EINVAL;
685 }
686 sr_val = i;
687
688 lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
689 816
690 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", 817 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
691 rates[bclk], rates[bclk] / lrclk); 818 rates[bclk], rates[bclk] / lrclk);
@@ -693,28 +820,9 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
693 wl = snd_pcm_format_width(params_format(params)); 820 wl = snd_pcm_format_width(params_format(params));
694 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl; 821 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
695 822
696 /* 823 ret = arizona_hw_params_rate(substream, params, dai);
697 * We will need to be more flexible than this in future, 824 if (ret != 0)
698 * currently we use a single sample rate for SYSCLK. 825 return ret;
699 */
700 switch (dai_priv->clk) {
701 case ARIZONA_CLK_SYSCLK:
702 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
703 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
704 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
705 ARIZONA_AIF1_RATE_MASK, 0);
706 break;
707 case ARIZONA_CLK_ASYNCCLK:
708 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
709 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
710 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
711 ARIZONA_AIF1_RATE_MASK,
712 8 << ARIZONA_AIF1_RATE_SHIFT);
713 break;
714 default:
715 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
716 return -EINVAL;
717 }
718 826
719 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, 827 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
720 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); 828 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
@@ -789,11 +897,27 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
789 return snd_soc_dapm_sync(&codec->dapm); 897 return snd_soc_dapm_sync(&codec->dapm);
790} 898}
791 899
900static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
901{
902 struct snd_soc_codec *codec = dai->codec;
903 int base = dai->driver->base;
904 unsigned int reg;
905
906 if (tristate)
907 reg = ARIZONA_AIF1_TRI;
908 else
909 reg = 0;
910
911 return snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
912 ARIZONA_AIF1_TRI, reg);
913}
914
792const struct snd_soc_dai_ops arizona_dai_ops = { 915const struct snd_soc_dai_ops arizona_dai_ops = {
793 .startup = arizona_startup, 916 .startup = arizona_startup,
794 .set_fmt = arizona_set_fmt, 917 .set_fmt = arizona_set_fmt,
795 .hw_params = arizona_hw_params, 918 .hw_params = arizona_hw_params,
796 .set_sysclk = arizona_dai_set_sysclk, 919 .set_sysclk = arizona_dai_set_sysclk,
920 .set_tristate = arizona_set_tristate,
797}; 921};
798EXPORT_SYMBOL_GPL(arizona_dai_ops); 922EXPORT_SYMBOL_GPL(arizona_dai_ops);
799 923
@@ -807,17 +931,6 @@ int arizona_init_dai(struct arizona_priv *priv, int id)
807} 931}
808EXPORT_SYMBOL_GPL(arizona_init_dai); 932EXPORT_SYMBOL_GPL(arizona_init_dai);
809 933
810static irqreturn_t arizona_fll_lock(int irq, void *data)
811{
812 struct arizona_fll *fll = data;
813
814 arizona_fll_dbg(fll, "Lock status changed\n");
815
816 complete(&fll->lock);
817
818 return IRQ_HANDLED;
819}
820
821static irqreturn_t arizona_fll_clock_ok(int irq, void *data) 934static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
822{ 935{
823 struct arizona_fll *fll = data; 936 struct arizona_fll *fll = data;
@@ -910,7 +1023,7 @@ static int arizona_calc_fll(struct arizona_fll *fll,
910 1023
911 cfg->n = target / (ratio * Fref); 1024 cfg->n = target / (ratio * Fref);
912 1025
913 if (target % Fref) { 1026 if (target % (ratio * Fref)) {
914 gcd_fll = gcd(target, ratio * Fref); 1027 gcd_fll = gcd(target, ratio * Fref);
915 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll); 1028 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
916 1029
@@ -922,6 +1035,15 @@ static int arizona_calc_fll(struct arizona_fll *fll,
922 cfg->lambda = 0; 1035 cfg->lambda = 0;
923 } 1036 }
924 1037
1038 /* Round down to 16bit range with cost of accuracy lost.
1039 * Denominator must be bigger than numerator so we only
1040 * take care of it.
1041 */
1042 while (cfg->lambda >= (1 << 16)) {
1043 cfg->theta >>= 1;
1044 cfg->lambda >>= 1;
1045 }
1046
925 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n", 1047 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
926 cfg->n, cfg->theta, cfg->lambda); 1048 cfg->n, cfg->theta, cfg->lambda);
927 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", 1049 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
@@ -1057,7 +1179,6 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1057{ 1179{
1058 int ret; 1180 int ret;
1059 1181
1060 init_completion(&fll->lock);
1061 init_completion(&fll->ok); 1182 init_completion(&fll->ok);
1062 1183
1063 fll->id = id; 1184 fll->id = id;
@@ -1068,13 +1189,6 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1068 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), 1189 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
1069 "FLL%d clock OK", id); 1190 "FLL%d clock OK", id);
1070 1191
1071 ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
1072 arizona_fll_lock, fll);
1073 if (ret != 0) {
1074 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
1075 id, ret);
1076 }
1077
1078 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name, 1192 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
1079 arizona_fll_clock_ok, fll); 1193 arizona_fll_clock_ok, fll);
1080 if (ret != 0) { 1194 if (ret != 0) {
@@ -1082,10 +1196,47 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
1082 id, ret); 1196 id, ret);
1083 } 1197 }
1084 1198
1199 regmap_update_bits(arizona->regmap, fll->base + 1,
1200 ARIZONA_FLL1_FREERUN, 0);
1201
1085 return 0; 1202 return 0;
1086} 1203}
1087EXPORT_SYMBOL_GPL(arizona_init_fll); 1204EXPORT_SYMBOL_GPL(arizona_init_fll);
1088 1205
1206/**
1207 * arizona_set_output_mode - Set the mode of the specified output
1208 *
1209 * @codec: Device to configure
1210 * @output: Output number
1211 * @diff: True to set the output to differential mode
1212 *
1213 * Some systems use external analogue switches to connect more
1214 * analogue devices to the CODEC than are supported by the device. In
1215 * some systems this requires changing the switched output from single
1216 * ended to differential mode dynamically at runtime, an operation
1217 * supported using this function.
1218 *
1219 * Most systems have a single static configuration and should use
1220 * platform data instead.
1221 */
1222int arizona_set_output_mode(struct snd_soc_codec *codec, int output, bool diff)
1223{
1224 unsigned int reg, val;
1225
1226 if (output < 1 || output > 6)
1227 return -EINVAL;
1228
1229 reg = ARIZONA_OUTPUT_PATH_CONFIG_1L + (output - 1) * 8;
1230
1231 if (diff)
1232 val = ARIZONA_OUT1_MONO;
1233 else
1234 val = 0;
1235
1236 return snd_soc_update_bits(codec, reg, ARIZONA_OUT1_MONO, val);
1237}
1238EXPORT_SYMBOL_GPL(arizona_set_output_mode);
1239
1089MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support"); 1240MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
1090MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1241MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1091MODULE_LICENSE("GPL"); 1242MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 4deebeb07177..116372c91f5d 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -66,7 +66,7 @@ struct arizona_priv {
66 struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; 66 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
67}; 67};
68 68
69#define ARIZONA_NUM_MIXER_INPUTS 75 69#define ARIZONA_NUM_MIXER_INPUTS 99
70 70
71extern const unsigned int arizona_mixer_tlv[]; 71extern const unsigned int arizona_mixer_tlv[];
72extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; 72extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
@@ -176,6 +176,8 @@ extern const struct soc_enum arizona_lhpf2_mode;
176extern const struct soc_enum arizona_lhpf3_mode; 176extern const struct soc_enum arizona_lhpf3_mode;
177extern const struct soc_enum arizona_lhpf4_mode; 177extern const struct soc_enum arizona_lhpf4_mode;
178 178
179extern const struct soc_enum arizona_ng_hold;
180
179extern int arizona_in_ev(struct snd_soc_dapm_widget *w, 181extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
180 struct snd_kcontrol *kcontrol, 182 struct snd_kcontrol *kcontrol,
181 int event); 183 int event);
@@ -195,7 +197,6 @@ struct arizona_fll {
195 int id; 197 int id;
196 unsigned int base; 198 unsigned int base;
197 unsigned int vco_mult; 199 unsigned int vco_mult;
198 struct completion lock;
199 struct completion ok; 200 struct completion ok;
200 unsigned int fref; 201 unsigned int fref;
201 unsigned int fout; 202 unsigned int fout;
@@ -211,4 +212,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source,
211 212
212extern int arizona_init_dai(struct arizona_priv *priv, int dai); 213extern int arizona_init_dai(struct arizona_priv *priv, int dai);
213 214
215int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
216 bool diff);
217
214#endif 218#endif
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index ac8742a1f25a..2415a4118dbd 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -167,6 +167,8 @@ struct cs4271_private {
167 int gpio_nreset; 167 int gpio_nreset;
168 /* GPIO that disable serial bus, if any */ 168 /* GPIO that disable serial bus, if any */
169 int gpio_disable; 169 int gpio_disable;
170 /* enable soft reset workaround */
171 bool enable_soft_reset;
170}; 172};
171 173
172/* 174/*
@@ -325,6 +327,33 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
325 int i, ret; 327 int i, ret;
326 unsigned int ratio, val; 328 unsigned int ratio, val;
327 329
330 if (cs4271->enable_soft_reset) {
331 /*
332 * Put the codec in soft reset and back again in case it's not
333 * currently streaming data. This way of bringing the codec in
334 * sync to the current clocks is not explicitly documented in
335 * the data sheet, but it seems to work fine, and in contrast
336 * to a read hardware reset, we don't have to sync back all
337 * registers every time.
338 */
339
340 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
341 !dai->capture_active) ||
342 (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
343 !dai->playback_active)) {
344 ret = snd_soc_update_bits(codec, CS4271_MODE2,
345 CS4271_MODE2_PDN,
346 CS4271_MODE2_PDN);
347 if (ret < 0)
348 return ret;
349
350 ret = snd_soc_update_bits(codec, CS4271_MODE2,
351 CS4271_MODE2_PDN, 0);
352 if (ret < 0)
353 return ret;
354 }
355 }
356
328 cs4271->rate = params_rate(params); 357 cs4271->rate = params_rate(params);
329 358
330 /* Configure DAC */ 359 /* Configure DAC */
@@ -484,6 +513,10 @@ static int cs4271_probe(struct snd_soc_codec *codec)
484 if (of_get_property(codec->dev->of_node, 513 if (of_get_property(codec->dev->of_node,
485 "cirrus,amutec-eq-bmutec", NULL)) 514 "cirrus,amutec-eq-bmutec", NULL))
486 amutec_eq_bmutec = true; 515 amutec_eq_bmutec = true;
516
517 if (of_get_property(codec->dev->of_node,
518 "cirrus,enable-soft-reset", NULL))
519 cs4271->enable_soft_reset = true;
487 } 520 }
488#endif 521#endif
489 522
@@ -492,6 +525,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
492 gpio_nreset = cs4271plat->gpio_nreset; 525 gpio_nreset = cs4271plat->gpio_nreset;
493 526
494 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec; 527 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
528 cs4271->enable_soft_reset = cs4271plat->enable_soft_reset;
495 } 529 }
496 530
497 if (gpio_nreset >= 0) 531 if (gpio_nreset >= 0)
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 9811a5478c87..0f6f481cec09 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -1038,7 +1038,7 @@ static void cs42l52_init_beep(struct snd_soc_codec *codec)
1038 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); 1038 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1039 int ret; 1039 int ret;
1040 1040
1041 cs42l52->beep = input_allocate_device(); 1041 cs42l52->beep = devm_input_allocate_device(codec->dev);
1042 if (!cs42l52->beep) { 1042 if (!cs42l52->beep) {
1043 dev_err(codec->dev, "Failed to allocate beep device\n"); 1043 dev_err(codec->dev, "Failed to allocate beep device\n");
1044 return; 1044 return;
@@ -1059,7 +1059,6 @@ static void cs42l52_init_beep(struct snd_soc_codec *codec)
1059 1059
1060 ret = input_register_device(cs42l52->beep); 1060 ret = input_register_device(cs42l52->beep);
1061 if (ret != 0) { 1061 if (ret != 0) {
1062 input_free_device(cs42l52->beep);
1063 cs42l52->beep = NULL; 1062 cs42l52->beep = NULL;
1064 dev_err(codec->dev, "Failed to register beep device\n"); 1063 dev_err(codec->dev, "Failed to register beep device\n");
1065 } 1064 }
@@ -1076,7 +1075,6 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec)
1076 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); 1075 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1077 1076
1078 device_remove_file(codec->dev, &dev_attr_beep); 1077 device_remove_file(codec->dev, &dev_attr_beep);
1079 input_unregister_device(cs42l52->beep);
1080 cancel_work_sync(&cs42l52->beep_work); 1078 cancel_work_sync(&cs42l52->beep_work);
1081 cs42l52->beep = NULL; 1079 cs42l52->beep = NULL;
1082 1080
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
new file mode 100644
index 000000000000..41230ad1c3e0
--- /dev/null
+++ b/sound/soc/codecs/da7213.c
@@ -0,0 +1,1599 @@
1/*
2 * DA7213 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2013 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 * Based on DA9055 ALSA SoC codec driver.
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 as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/delay.h>
16#include <linux/i2c.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/module.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25
26#include <sound/da7213.h>
27#include "da7213.h"
28
29
30/* Gain and Volume */
31static const unsigned int aux_vol_tlv[] = {
32 TLV_DB_RANGE_HEAD(2),
33 /* -54dB */
34 0x0, 0x11, TLV_DB_SCALE_ITEM(-5400, 0, 0),
35 /* -52.5dB to 15dB */
36 0x12, 0x3f, TLV_DB_SCALE_ITEM(-5250, 150, 0)
37};
38
39static const unsigned int digital_gain_tlv[] = {
40 TLV_DB_RANGE_HEAD(2),
41 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
42 /* -78dB to 12dB */
43 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0)
44};
45
46static const unsigned int alc_analog_gain_tlv[] = {
47 TLV_DB_RANGE_HEAD(2),
48 0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
49 /* 0dB to 36dB */
50 0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0)
51};
52
53static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
54static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0);
55static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
56static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
57static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);
58static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);
59static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);
60
61/* ADC and DAC voice mode (8kHz) high pass cutoff value */
62static const char * const da7213_voice_hpf_corner_txt[] = {
63 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
64};
65
66static const struct soc_enum da7213_dac_voice_hpf_corner =
67 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
68 DA7213_VOICE_HPF_CORNER_MAX,
69 da7213_voice_hpf_corner_txt);
70
71static const struct soc_enum da7213_adc_voice_hpf_corner =
72 SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
73 DA7213_VOICE_HPF_CORNER_MAX,
74 da7213_voice_hpf_corner_txt);
75
76/* ADC and DAC high pass filter cutoff value */
77static const char * const da7213_audio_hpf_corner_txt[] = {
78 "Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
79};
80
81static const struct soc_enum da7213_dac_audio_hpf_corner =
82 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
83 DA7213_AUDIO_HPF_CORNER_MAX,
84 da7213_audio_hpf_corner_txt);
85
86static const struct soc_enum da7213_adc_audio_hpf_corner =
87 SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
88 DA7213_AUDIO_HPF_CORNER_MAX,
89 da7213_audio_hpf_corner_txt);
90
91/* Gain ramping rate value */
92static const char * const da7213_gain_ramp_rate_txt[] = {
93 "nominal rate * 8", "nominal rate * 16", "nominal rate / 16",
94 "nominal rate / 32"
95};
96
97static const struct soc_enum da7213_gain_ramp_rate =
98 SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT,
99 DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt);
100
101/* DAC noise gate setup time value */
102static const char * const da7213_dac_ng_setup_time_txt[] = {
103 "256 samples", "512 samples", "1024 samples", "2048 samples"
104};
105
106static const struct soc_enum da7213_dac_ng_setup_time =
107 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
108 DA7213_DAC_NG_SETUP_TIME_SHIFT,
109 DA7213_DAC_NG_SETUP_TIME_MAX,
110 da7213_dac_ng_setup_time_txt);
111
112/* DAC noise gate rampup rate value */
113static const char * const da7213_dac_ng_rampup_txt[] = {
114 "0.02 ms/dB", "0.16 ms/dB"
115};
116
117static const struct soc_enum da7213_dac_ng_rampup_rate =
118 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
119 DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
120 DA7213_DAC_NG_RAMP_RATE_MAX,
121 da7213_dac_ng_rampup_txt);
122
123/* DAC noise gate rampdown rate value */
124static const char * const da7213_dac_ng_rampdown_txt[] = {
125 "0.64 ms/dB", "20.48 ms/dB"
126};
127
128static const struct soc_enum da7213_dac_ng_rampdown_rate =
129 SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
130 DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
131 DA7213_DAC_NG_RAMP_RATE_MAX,
132 da7213_dac_ng_rampdown_txt);
133
134/* DAC soft mute rate value */
135static const char * const da7213_dac_soft_mute_rate_txt[] = {
136 "1", "2", "4", "8", "16", "32", "64"
137};
138
139static const struct soc_enum da7213_dac_soft_mute_rate =
140 SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT,
141 DA7213_DAC_SOFTMUTE_RATE_MAX,
142 da7213_dac_soft_mute_rate_txt);
143
144/* ALC Attack Rate select */
145static const char * const da7213_alc_attack_rate_txt[] = {
146 "44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs",
147 "5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
148};
149
150static const struct soc_enum da7213_alc_attack_rate =
151 SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT,
152 DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt);
153
154/* ALC Release Rate select */
155static const char * const da7213_alc_release_rate_txt[] = {
156 "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs",
157 "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
158};
159
160static const struct soc_enum da7213_alc_release_rate =
161 SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT,
162 DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt);
163
164/* ALC Hold Time select */
165static const char * const da7213_alc_hold_time_txt[] = {
166 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
167 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
168 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
169};
170
171static const struct soc_enum da7213_alc_hold_time =
172 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT,
173 DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt);
174
175/* ALC Input Signal Tracking rate select */
176static const char * const da7213_alc_integ_rate_txt[] = {
177 "1/4", "1/16", "1/256", "1/65536"
178};
179
180static const struct soc_enum da7213_alc_integ_attack_rate =
181 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT,
182 DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
183
184static const struct soc_enum da7213_alc_integ_release_rate =
185 SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT,
186 DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
187
188
189/*
190 * Control Functions
191 */
192
193static int da7213_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
194{
195 int mid_data, top_data;
196 int sum = 0;
197 u8 iteration;
198
199 for (iteration = 0; iteration < DA7213_ALC_AVG_ITERATIONS;
200 iteration++) {
201 /* Select the left or right channel and capture data */
202 snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL, reg_val);
203
204 /* Select middle 8 bits for read back from data register */
205 snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
206 reg_val | DA7213_ALC_DATA_MIDDLE);
207 mid_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
208
209 /* Select top 8 bits for read back from data register */
210 snd_soc_write(codec, DA7213_ALC_CIC_OP_LVL_CTRL,
211 reg_val | DA7213_ALC_DATA_TOP);
212 top_data = snd_soc_read(codec, DA7213_ALC_CIC_OP_LVL_DATA);
213
214 sum += ((mid_data << 8) | (top_data << 16));
215 }
216
217 return sum / DA7213_ALC_AVG_ITERATIONS;
218}
219
220static void da7213_alc_calib_man(struct snd_soc_codec *codec)
221{
222 u8 reg_val;
223 int avg_left_data, avg_right_data, offset_l, offset_r;
224
225 /* Calculate average for Left and Right data */
226 /* Left Data */
227 avg_left_data = da7213_get_alc_data(codec,
228 DA7213_ALC_CIC_OP_CHANNEL_LEFT);
229 /* Right Data */
230 avg_right_data = da7213_get_alc_data(codec,
231 DA7213_ALC_CIC_OP_CHANNEL_RIGHT);
232
233 /* Calculate DC offset */
234 offset_l = -avg_left_data;
235 offset_r = -avg_right_data;
236
237 reg_val = (offset_l & DA7213_ALC_OFFSET_15_8) >> 8;
238 snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_L, reg_val);
239 reg_val = (offset_l & DA7213_ALC_OFFSET_19_16) >> 16;
240 snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_L, reg_val);
241
242 reg_val = (offset_r & DA7213_ALC_OFFSET_15_8) >> 8;
243 snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_M_R, reg_val);
244 reg_val = (offset_r & DA7213_ALC_OFFSET_19_16) >> 16;
245 snd_soc_write(codec, DA7213_ALC_OFFSET_MAN_U_R, reg_val);
246
247 /* Enable analog/digital gain mode & offset cancellation */
248 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
249 DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
250 DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
251}
252
253static void da7213_alc_calib_auto(struct snd_soc_codec *codec)
254{
255 u8 alc_ctrl1;
256
257 /* Begin auto calibration and wait for completion */
258 snd_soc_update_bits(codec, DA7213_ALC_CTRL1, DA7213_ALC_AUTO_CALIB_EN,
259 DA7213_ALC_AUTO_CALIB_EN);
260 do {
261 alc_ctrl1 = snd_soc_read(codec, DA7213_ALC_CTRL1);
262 } while (alc_ctrl1 & DA7213_ALC_AUTO_CALIB_EN);
263
264 /* If auto calibration fails, fall back to digital gain only mode */
265 if (alc_ctrl1 & DA7213_ALC_CALIB_OVERFLOW) {
266 dev_warn(codec->dev,
267 "ALC auto calibration failed with overflow\n");
268 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
269 DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
270 0);
271 } else {
272 /* Enable analog/digital gain mode & offset cancellation */
273 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
274 DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE,
275 DA7213_ALC_OFFSET_EN | DA7213_ALC_SYNC_MODE);
276 }
277
278}
279
280static void da7213_alc_calib(struct snd_soc_codec *codec)
281{
282 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
283 u8 adc_l_ctrl, adc_r_ctrl;
284 u8 mixin_l_sel, mixin_r_sel;
285 u8 mic_1_ctrl, mic_2_ctrl;
286
287 /* Save current values from ADC control registers */
288 adc_l_ctrl = snd_soc_read(codec, DA7213_ADC_L_CTRL);
289 adc_r_ctrl = snd_soc_read(codec, DA7213_ADC_R_CTRL);
290
291 /* Save current values from MIXIN_L/R_SELECT registers */
292 mixin_l_sel = snd_soc_read(codec, DA7213_MIXIN_L_SELECT);
293 mixin_r_sel = snd_soc_read(codec, DA7213_MIXIN_R_SELECT);
294
295 /* Save current values from MIC control registers */
296 mic_1_ctrl = snd_soc_read(codec, DA7213_MIC_1_CTRL);
297 mic_2_ctrl = snd_soc_read(codec, DA7213_MIC_2_CTRL);
298
299 /* Enable ADC Left and Right */
300 snd_soc_update_bits(codec, DA7213_ADC_L_CTRL, DA7213_ADC_EN,
301 DA7213_ADC_EN);
302 snd_soc_update_bits(codec, DA7213_ADC_R_CTRL, DA7213_ADC_EN,
303 DA7213_ADC_EN);
304
305 /* Enable MIC paths */
306 snd_soc_update_bits(codec, DA7213_MIXIN_L_SELECT,
307 DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
308 DA7213_MIXIN_L_MIX_SELECT_MIC_2,
309 DA7213_MIXIN_L_MIX_SELECT_MIC_1 |
310 DA7213_MIXIN_L_MIX_SELECT_MIC_2);
311 snd_soc_update_bits(codec, DA7213_MIXIN_R_SELECT,
312 DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
313 DA7213_MIXIN_R_MIX_SELECT_MIC_1,
314 DA7213_MIXIN_R_MIX_SELECT_MIC_2 |
315 DA7213_MIXIN_R_MIX_SELECT_MIC_1);
316
317 /* Mute MIC PGAs */
318 snd_soc_update_bits(codec, DA7213_MIC_1_CTRL, DA7213_MUTE_EN,
319 DA7213_MUTE_EN);
320 snd_soc_update_bits(codec, DA7213_MIC_2_CTRL, DA7213_MUTE_EN,
321 DA7213_MUTE_EN);
322
323 /* Perform calibration */
324 if (da7213->alc_calib_auto)
325 da7213_alc_calib_auto(codec);
326 else
327 da7213_alc_calib_man(codec);
328
329 /* Restore MIXIN_L/R_SELECT registers to their original states */
330 snd_soc_write(codec, DA7213_MIXIN_L_SELECT, mixin_l_sel);
331 snd_soc_write(codec, DA7213_MIXIN_R_SELECT, mixin_r_sel);
332
333 /* Restore ADC control registers to their original states */
334 snd_soc_write(codec, DA7213_ADC_L_CTRL, adc_l_ctrl);
335 snd_soc_write(codec, DA7213_ADC_R_CTRL, adc_r_ctrl);
336
337 /* Restore original values of MIC control registers */
338 snd_soc_write(codec, DA7213_MIC_1_CTRL, mic_1_ctrl);
339 snd_soc_write(codec, DA7213_MIC_2_CTRL, mic_2_ctrl);
340}
341
342static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol,
343 struct snd_ctl_elem_value *ucontrol)
344{
345 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
346 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
347 int ret;
348
349 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
350
351 /* If ALC in operation, make sure calibrated offsets are updated */
352 if ((!ret) && (da7213->alc_en))
353 da7213_alc_calib(codec);
354
355 return ret;
356}
357
358static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
360{
361 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
362 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
363
364 /* Force ALC offset calibration if enabling ALC */
365 if (ucontrol->value.integer.value[0] ||
366 ucontrol->value.integer.value[1]) {
367 if (!da7213->alc_en) {
368 da7213_alc_calib(codec);
369 da7213->alc_en = true;
370 }
371 } else {
372 da7213->alc_en = false;
373 }
374
375 return snd_soc_put_volsw(kcontrol, ucontrol);
376}
377
378
379/*
380 * KControls
381 */
382
383static const struct snd_kcontrol_new da7213_snd_controls[] = {
384
385 /* Volume controls */
386 SOC_SINGLE_TLV("Mic 1 Volume", DA7213_MIC_1_GAIN,
387 DA7213_MIC_AMP_GAIN_SHIFT, DA7213_MIC_AMP_GAIN_MAX,
388 DA7213_NO_INVERT, mic_vol_tlv),
389 SOC_SINGLE_TLV("Mic 2 Volume", DA7213_MIC_2_GAIN,
390 DA7213_MIC_AMP_GAIN_SHIFT, DA7213_MIC_AMP_GAIN_MAX,
391 DA7213_NO_INVERT, mic_vol_tlv),
392 SOC_DOUBLE_R_TLV("Aux Volume", DA7213_AUX_L_GAIN, DA7213_AUX_R_GAIN,
393 DA7213_AUX_AMP_GAIN_SHIFT, DA7213_AUX_AMP_GAIN_MAX,
394 DA7213_NO_INVERT, aux_vol_tlv),
395 SOC_DOUBLE_R_EXT_TLV("Mixin PGA Volume", DA7213_MIXIN_L_GAIN,
396 DA7213_MIXIN_R_GAIN, DA7213_MIXIN_AMP_GAIN_SHIFT,
397 DA7213_MIXIN_AMP_GAIN_MAX, DA7213_NO_INVERT,
398 snd_soc_get_volsw_2r, da7213_put_mixin_gain,
399 mixin_gain_tlv),
400 SOC_DOUBLE_R_TLV("ADC Volume", DA7213_ADC_L_GAIN, DA7213_ADC_R_GAIN,
401 DA7213_ADC_AMP_GAIN_SHIFT, DA7213_ADC_AMP_GAIN_MAX,
402 DA7213_NO_INVERT, digital_gain_tlv),
403 SOC_DOUBLE_R_TLV("DAC Volume", DA7213_DAC_L_GAIN, DA7213_DAC_R_GAIN,
404 DA7213_DAC_AMP_GAIN_SHIFT, DA7213_DAC_AMP_GAIN_MAX,
405 DA7213_NO_INVERT, digital_gain_tlv),
406 SOC_DOUBLE_R_TLV("Headphone Volume", DA7213_HP_L_GAIN, DA7213_HP_R_GAIN,
407 DA7213_HP_AMP_GAIN_SHIFT, DA7213_HP_AMP_GAIN_MAX,
408 DA7213_NO_INVERT, hp_vol_tlv),
409 SOC_SINGLE_TLV("Lineout Volume", DA7213_LINE_GAIN,
410 DA7213_LINE_AMP_GAIN_SHIFT, DA7213_LINE_AMP_GAIN_MAX,
411 DA7213_NO_INVERT, lineout_vol_tlv),
412
413 /* DAC Equalizer controls */
414 SOC_SINGLE("DAC EQ Switch", DA7213_DAC_FILTERS4, DA7213_DAC_EQ_EN_SHIFT,
415 DA7213_DAC_EQ_EN_MAX, DA7213_NO_INVERT),
416 SOC_SINGLE_TLV("DAC EQ1 Volume", DA7213_DAC_FILTERS2,
417 DA7213_DAC_EQ_BAND1_SHIFT, DA7213_DAC_EQ_BAND_MAX,
418 DA7213_NO_INVERT, eq_gain_tlv),
419 SOC_SINGLE_TLV("DAC EQ2 Volume", DA7213_DAC_FILTERS2,
420 DA7213_DAC_EQ_BAND2_SHIFT, DA7213_DAC_EQ_BAND_MAX,
421 DA7213_NO_INVERT, eq_gain_tlv),
422 SOC_SINGLE_TLV("DAC EQ3 Volume", DA7213_DAC_FILTERS3,
423 DA7213_DAC_EQ_BAND3_SHIFT, DA7213_DAC_EQ_BAND_MAX,
424 DA7213_NO_INVERT, eq_gain_tlv),
425 SOC_SINGLE_TLV("DAC EQ4 Volume", DA7213_DAC_FILTERS3,
426 DA7213_DAC_EQ_BAND4_SHIFT, DA7213_DAC_EQ_BAND_MAX,
427 DA7213_NO_INVERT, eq_gain_tlv),
428 SOC_SINGLE_TLV("DAC EQ5 Volume", DA7213_DAC_FILTERS4,
429 DA7213_DAC_EQ_BAND5_SHIFT, DA7213_DAC_EQ_BAND_MAX,
430 DA7213_NO_INVERT, eq_gain_tlv),
431
432 /* High Pass Filter and Voice Mode controls */
433 SOC_SINGLE("ADC HPF Switch", DA7213_ADC_FILTERS1, DA7213_HPF_EN_SHIFT,
434 DA7213_HPF_EN_MAX, DA7213_NO_INVERT),
435 SOC_ENUM("ADC HPF Cutoff", da7213_adc_audio_hpf_corner),
436 SOC_SINGLE("ADC Voice Mode Switch", DA7213_ADC_FILTERS1,
437 DA7213_VOICE_EN_SHIFT, DA7213_VOICE_EN_MAX,
438 DA7213_NO_INVERT),
439 SOC_ENUM("ADC Voice Cutoff", da7213_adc_voice_hpf_corner),
440
441 SOC_SINGLE("DAC HPF Switch", DA7213_DAC_FILTERS1, DA7213_HPF_EN_SHIFT,
442 DA7213_HPF_EN_MAX, DA7213_NO_INVERT),
443 SOC_ENUM("DAC HPF Cutoff", da7213_dac_audio_hpf_corner),
444 SOC_SINGLE("DAC Voice Mode Switch", DA7213_DAC_FILTERS1,
445 DA7213_VOICE_EN_SHIFT, DA7213_VOICE_EN_MAX,
446 DA7213_NO_INVERT),
447 SOC_ENUM("DAC Voice Cutoff", da7213_dac_voice_hpf_corner),
448
449 /* Mute controls */
450 SOC_SINGLE("Mic 1 Switch", DA7213_MIC_1_CTRL, DA7213_MUTE_EN_SHIFT,
451 DA7213_MUTE_EN_MAX, DA7213_INVERT),
452 SOC_SINGLE("Mic 2 Switch", DA7213_MIC_2_CTRL, DA7213_MUTE_EN_SHIFT,
453 DA7213_MUTE_EN_MAX, DA7213_INVERT),
454 SOC_DOUBLE_R("Aux Switch", DA7213_AUX_L_CTRL, DA7213_AUX_R_CTRL,
455 DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
456 SOC_DOUBLE_R("Mixin PGA Switch", DA7213_MIXIN_L_CTRL,
457 DA7213_MIXIN_R_CTRL, DA7213_MUTE_EN_SHIFT,
458 DA7213_MUTE_EN_MAX, DA7213_INVERT),
459 SOC_DOUBLE_R("ADC Switch", DA7213_ADC_L_CTRL, DA7213_ADC_R_CTRL,
460 DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
461 SOC_DOUBLE_R("Headphone Switch", DA7213_HP_L_CTRL, DA7213_HP_R_CTRL,
462 DA7213_MUTE_EN_SHIFT, DA7213_MUTE_EN_MAX, DA7213_INVERT),
463 SOC_SINGLE("Lineout Switch", DA7213_LINE_CTRL, DA7213_MUTE_EN_SHIFT,
464 DA7213_MUTE_EN_MAX, DA7213_INVERT),
465 SOC_SINGLE("DAC Soft Mute Switch", DA7213_DAC_FILTERS5,
466 DA7213_DAC_SOFTMUTE_EN_SHIFT, DA7213_DAC_SOFTMUTE_EN_MAX,
467 DA7213_NO_INVERT),
468 SOC_ENUM("DAC Soft Mute Rate", da7213_dac_soft_mute_rate),
469
470 /* Zero Cross controls */
471 SOC_DOUBLE_R("Aux ZC Switch", DA7213_AUX_L_CTRL, DA7213_AUX_R_CTRL,
472 DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX, DA7213_NO_INVERT),
473 SOC_DOUBLE_R("Mixin PGA ZC Switch", DA7213_MIXIN_L_CTRL,
474 DA7213_MIXIN_R_CTRL, DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX,
475 DA7213_NO_INVERT),
476 SOC_DOUBLE_R("Headphone ZC Switch", DA7213_HP_L_CTRL, DA7213_HP_R_CTRL,
477 DA7213_ZC_EN_SHIFT, DA7213_ZC_EN_MAX, DA7213_NO_INVERT),
478
479 /* Gain Ramping controls */
480 SOC_DOUBLE_R("Aux Gain Ramping Switch", DA7213_AUX_L_CTRL,
481 DA7213_AUX_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
482 DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
483 SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA7213_MIXIN_L_CTRL,
484 DA7213_MIXIN_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
485 DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
486 SOC_DOUBLE_R("ADC Gain Ramping Switch", DA7213_ADC_L_CTRL,
487 DA7213_ADC_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
488 DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
489 SOC_DOUBLE_R("DAC Gain Ramping Switch", DA7213_DAC_L_CTRL,
490 DA7213_DAC_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
491 DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
492 SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA7213_HP_L_CTRL,
493 DA7213_HP_R_CTRL, DA7213_GAIN_RAMP_EN_SHIFT,
494 DA7213_GAIN_RAMP_EN_MAX, DA7213_NO_INVERT),
495 SOC_SINGLE("Lineout Gain Ramping Switch", DA7213_LINE_CTRL,
496 DA7213_GAIN_RAMP_EN_SHIFT, DA7213_GAIN_RAMP_EN_MAX,
497 DA7213_NO_INVERT),
498 SOC_ENUM("Gain Ramping Rate", da7213_gain_ramp_rate),
499
500 /* DAC Noise Gate controls */
501 SOC_SINGLE("DAC NG Switch", DA7213_DAC_NG_CTRL, DA7213_DAC_NG_EN_SHIFT,
502 DA7213_DAC_NG_EN_MAX, DA7213_NO_INVERT),
503 SOC_ENUM("DAC NG Setup Time", da7213_dac_ng_setup_time),
504 SOC_ENUM("DAC NG Rampup Rate", da7213_dac_ng_rampup_rate),
505 SOC_ENUM("DAC NG Rampdown Rate", da7213_dac_ng_rampdown_rate),
506 SOC_SINGLE("DAC NG OFF Threshold", DA7213_DAC_NG_OFF_THRESHOLD,
507 DA7213_DAC_NG_THRESHOLD_SHIFT, DA7213_DAC_NG_THRESHOLD_MAX,
508 DA7213_NO_INVERT),
509 SOC_SINGLE("DAC NG ON Threshold", DA7213_DAC_NG_ON_THRESHOLD,
510 DA7213_DAC_NG_THRESHOLD_SHIFT, DA7213_DAC_NG_THRESHOLD_MAX,
511 DA7213_NO_INVERT),
512
513 /* DAC Routing & Inversion */
514 SOC_DOUBLE("DAC Mono Switch", DA7213_DIG_ROUTING_DAC,
515 DA7213_DAC_L_MONO_SHIFT, DA7213_DAC_R_MONO_SHIFT,
516 DA7213_DAC_MONO_MAX, DA7213_NO_INVERT),
517 SOC_DOUBLE("DAC Invert Switch", DA7213_DIG_CTRL, DA7213_DAC_L_INV_SHIFT,
518 DA7213_DAC_R_INV_SHIFT, DA7213_DAC_INV_MAX,
519 DA7213_NO_INVERT),
520
521 /* DMIC controls */
522 SOC_DOUBLE_R("DMIC Switch", DA7213_MIXIN_L_SELECT,
523 DA7213_MIXIN_R_SELECT, DA7213_DMIC_EN_SHIFT,
524 DA7213_DMIC_EN_MAX, DA7213_NO_INVERT),
525
526 /* ALC Controls */
527 SOC_DOUBLE_EXT("ALC Switch", DA7213_ALC_CTRL1, DA7213_ALC_L_EN_SHIFT,
528 DA7213_ALC_R_EN_SHIFT, DA7213_ALC_EN_MAX,
529 DA7213_NO_INVERT, snd_soc_get_volsw, da7213_put_alc_sw),
530 SOC_ENUM("ALC Attack Rate", da7213_alc_attack_rate),
531 SOC_ENUM("ALC Release Rate", da7213_alc_release_rate),
532 SOC_ENUM("ALC Hold Time", da7213_alc_hold_time),
533 /*
534 * Rate at which input signal envelope is tracked as the signal gets
535 * larger
536 */
537 SOC_ENUM("ALC Integ Attack Rate", da7213_alc_integ_attack_rate),
538 /*
539 * Rate at which input signal envelope is tracked as the signal gets
540 * smaller
541 */
542 SOC_ENUM("ALC Integ Release Rate", da7213_alc_integ_release_rate),
543 SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA7213_ALC_NOISE,
544 DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
545 DA7213_INVERT, alc_threshold_tlv),
546 SOC_SINGLE_TLV("ALC Min Threshold Volume", DA7213_ALC_TARGET_MIN,
547 DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
548 DA7213_INVERT, alc_threshold_tlv),
549 SOC_SINGLE_TLV("ALC Max Threshold Volume", DA7213_ALC_TARGET_MAX,
550 DA7213_ALC_THRESHOLD_SHIFT, DA7213_ALC_THRESHOLD_MAX,
551 DA7213_INVERT, alc_threshold_tlv),
552 SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA7213_ALC_GAIN_LIMITS,
553 DA7213_ALC_ATTEN_MAX_SHIFT,
554 DA7213_ALC_ATTEN_GAIN_MAX_MAX, DA7213_NO_INVERT,
555 alc_gain_tlv),
556 SOC_SINGLE_TLV("ALC Max Gain Volume", DA7213_ALC_GAIN_LIMITS,
557 DA7213_ALC_GAIN_MAX_SHIFT, DA7213_ALC_ATTEN_GAIN_MAX_MAX,
558 DA7213_NO_INVERT, alc_gain_tlv),
559 SOC_SINGLE_TLV("ALC Min Analog Gain Volume", DA7213_ALC_ANA_GAIN_LIMITS,
560 DA7213_ALC_ANA_GAIN_MIN_SHIFT, DA7213_ALC_ANA_GAIN_MAX,
561 DA7213_NO_INVERT, alc_analog_gain_tlv),
562 SOC_SINGLE_TLV("ALC Max Analog Gain Volume", DA7213_ALC_ANA_GAIN_LIMITS,
563 DA7213_ALC_ANA_GAIN_MAX_SHIFT, DA7213_ALC_ANA_GAIN_MAX,
564 DA7213_NO_INVERT, alc_analog_gain_tlv),
565 SOC_SINGLE("ALC Anticlip Mode Switch", DA7213_ALC_ANTICLIP_CTRL,
566 DA7213_ALC_ANTICLIP_EN_SHIFT, DA7213_ALC_ANTICLIP_EN_MAX,
567 DA7213_NO_INVERT),
568 SOC_SINGLE("ALC Anticlip Level", DA7213_ALC_ANTICLIP_LEVEL,
569 DA7213_ALC_ANTICLIP_LEVEL_SHIFT,
570 DA7213_ALC_ANTICLIP_LEVEL_MAX, DA7213_NO_INVERT),
571};
572
573
574/*
575 * DAPM
576 */
577
578/*
579 * Enums
580 */
581
582/* MIC PGA source select */
583static const char * const da7213_mic_amp_in_sel_txt[] = {
584 "Differential", "MIC_P", "MIC_N"
585};
586
587static const struct soc_enum da7213_mic_1_amp_in_sel =
588 SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
589 DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
590static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux =
591 SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel);
592
593static const struct soc_enum da7213_mic_2_amp_in_sel =
594 SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
595 DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
596static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux =
597 SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel);
598
599/* DAI routing select */
600static const char * const da7213_dai_src_txt[] = {
601 "ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right"
602};
603
604static const struct soc_enum da7213_dai_l_src =
605 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT,
606 DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
607static const struct snd_kcontrol_new da7213_dai_l_src_mux =
608 SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
609
610static const struct soc_enum da7213_dai_r_src =
611 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT,
612 DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
613static const struct snd_kcontrol_new da7213_dai_r_src_mux =
614 SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src);
615
616/* DAC routing select */
617static const char * const da7213_dac_src_txt[] = {
618 "ADC Output Left", "ADC Output Right", "DAI Input Left",
619 "DAI Input Right"
620};
621
622static const struct soc_enum da7213_dac_l_src =
623 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT,
624 DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
625static const struct snd_kcontrol_new da7213_dac_l_src_mux =
626 SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
627
628static const struct soc_enum da7213_dac_r_src =
629 SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT,
630 DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
631static const struct snd_kcontrol_new da7213_dac_r_src_mux =
632 SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src);
633
634/*
635 * Mixer Controls
636 */
637
638/* Mixin Left */
639static const struct snd_kcontrol_new da7213_dapm_mixinl_controls[] = {
640 SOC_DAPM_SINGLE("Aux Left Switch", DA7213_MIXIN_L_SELECT,
641 DA7213_MIXIN_L_MIX_SELECT_AUX_L_SHIFT,
642 DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
643 SOC_DAPM_SINGLE("Mic 1 Switch", DA7213_MIXIN_L_SELECT,
644 DA7213_MIXIN_L_MIX_SELECT_MIC_1_SHIFT,
645 DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
646 SOC_DAPM_SINGLE("Mic 2 Switch", DA7213_MIXIN_L_SELECT,
647 DA7213_MIXIN_L_MIX_SELECT_MIC_2_SHIFT,
648 DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
649 SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXIN_L_SELECT,
650 DA7213_MIXIN_L_MIX_SELECT_MIXIN_R_SHIFT,
651 DA7213_MIXIN_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
652};
653
654/* Mixin Right */
655static const struct snd_kcontrol_new da7213_dapm_mixinr_controls[] = {
656 SOC_DAPM_SINGLE("Aux Right Switch", DA7213_MIXIN_R_SELECT,
657 DA7213_MIXIN_R_MIX_SELECT_AUX_R_SHIFT,
658 DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
659 SOC_DAPM_SINGLE("Mic 2 Switch", DA7213_MIXIN_R_SELECT,
660 DA7213_MIXIN_R_MIX_SELECT_MIC_2_SHIFT,
661 DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
662 SOC_DAPM_SINGLE("Mic 1 Switch", DA7213_MIXIN_R_SELECT,
663 DA7213_MIXIN_R_MIX_SELECT_MIC_1_SHIFT,
664 DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
665 SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXIN_R_SELECT,
666 DA7213_MIXIN_R_MIX_SELECT_MIXIN_L_SHIFT,
667 DA7213_MIXIN_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
668};
669
670/* Mixout Left */
671static const struct snd_kcontrol_new da7213_dapm_mixoutl_controls[] = {
672 SOC_DAPM_SINGLE("Aux Left Switch", DA7213_MIXOUT_L_SELECT,
673 DA7213_MIXOUT_L_MIX_SELECT_AUX_L_SHIFT,
674 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
675 SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXOUT_L_SELECT,
676 DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_SHIFT,
677 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
678 SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXOUT_L_SELECT,
679 DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_SHIFT,
680 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
681 SOC_DAPM_SINGLE("DAC Left Switch", DA7213_MIXOUT_L_SELECT,
682 DA7213_MIXOUT_L_MIX_SELECT_DAC_L_SHIFT,
683 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
684 SOC_DAPM_SINGLE("Aux Left Invert Switch", DA7213_MIXOUT_L_SELECT,
685 DA7213_MIXOUT_L_MIX_SELECT_AUX_L_INVERTED_SHIFT,
686 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
687 SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA7213_MIXOUT_L_SELECT,
688 DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_INVERTED_SHIFT,
689 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
690 SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA7213_MIXOUT_L_SELECT,
691 DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_INVERTED_SHIFT,
692 DA7213_MIXOUT_L_MIX_SELECT_MAX, DA7213_NO_INVERT),
693};
694
695/* Mixout Right */
696static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
697 SOC_DAPM_SINGLE("Aux Right Switch", DA7213_MIXOUT_R_SELECT,
698 DA7213_MIXOUT_R_MIX_SELECT_AUX_R_SHIFT,
699 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
700 SOC_DAPM_SINGLE("Mixin Right Switch", DA7213_MIXOUT_R_SELECT,
701 DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_SHIFT,
702 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
703 SOC_DAPM_SINGLE("Mixin Left Switch", DA7213_MIXOUT_R_SELECT,
704 DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_SHIFT,
705 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
706 SOC_DAPM_SINGLE("DAC Right Switch", DA7213_MIXOUT_R_SELECT,
707 DA7213_MIXOUT_R_MIX_SELECT_DAC_R_SHIFT,
708 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
709 SOC_DAPM_SINGLE("Aux Right Invert Switch", DA7213_MIXOUT_R_SELECT,
710 DA7213_MIXOUT_R_MIX_SELECT_AUX_R_INVERTED_SHIFT,
711 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
712 SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA7213_MIXOUT_R_SELECT,
713 DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_INVERTED_SHIFT,
714 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
715 SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA7213_MIXOUT_R_SELECT,
716 DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_INVERTED_SHIFT,
717 DA7213_MIXOUT_R_MIX_SELECT_MAX, DA7213_NO_INVERT),
718};
719
720
721/*
722 * DAPM widgets
723 */
724
725static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
726 /*
727 * Input & Output
728 */
729
730 /* Use a supply here as this controls both input & output DAIs */
731 SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT,
732 DA7213_NO_INVERT, NULL, 0),
733
734 /*
735 * Input
736 */
737
738 /* Input Lines */
739 SND_SOC_DAPM_INPUT("MIC1"),
740 SND_SOC_DAPM_INPUT("MIC2"),
741 SND_SOC_DAPM_INPUT("AUXL"),
742 SND_SOC_DAPM_INPUT("AUXR"),
743
744 /* MUXs for Mic PGA source selection */
745 SND_SOC_DAPM_MUX("Mic 1 Amp Source MUX", SND_SOC_NOPM, 0, 0,
746 &da7213_mic_1_amp_in_sel_mux),
747 SND_SOC_DAPM_MUX("Mic 2 Amp Source MUX", SND_SOC_NOPM, 0, 0,
748 &da7213_mic_2_amp_in_sel_mux),
749
750 /* Input PGAs */
751 SND_SOC_DAPM_PGA("Mic 1 PGA", DA7213_MIC_1_CTRL, DA7213_AMP_EN_SHIFT,
752 DA7213_NO_INVERT, NULL, 0),
753 SND_SOC_DAPM_PGA("Mic 2 PGA", DA7213_MIC_2_CTRL, DA7213_AMP_EN_SHIFT,
754 DA7213_NO_INVERT, NULL, 0),
755 SND_SOC_DAPM_PGA("Aux Left PGA", DA7213_AUX_L_CTRL, DA7213_AMP_EN_SHIFT,
756 DA7213_NO_INVERT, NULL, 0),
757 SND_SOC_DAPM_PGA("Aux Right PGA", DA7213_AUX_R_CTRL,
758 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
759 SND_SOC_DAPM_PGA("Mixin Left PGA", DA7213_MIXIN_L_CTRL,
760 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
761 SND_SOC_DAPM_PGA("Mixin Right PGA", DA7213_MIXIN_R_CTRL,
762 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
763
764 /* Mic Biases */
765 SND_SOC_DAPM_SUPPLY("Mic Bias 1", DA7213_MICBIAS_CTRL,
766 DA7213_MICBIAS1_EN_SHIFT, DA7213_NO_INVERT,
767 NULL, 0),
768 SND_SOC_DAPM_SUPPLY("Mic Bias 2", DA7213_MICBIAS_CTRL,
769 DA7213_MICBIAS2_EN_SHIFT, DA7213_NO_INVERT,
770 NULL, 0),
771
772 /* Input Mixers */
773 SND_SOC_DAPM_MIXER("Mixin Left", SND_SOC_NOPM, 0, 0,
774 &da7213_dapm_mixinl_controls[0],
775 ARRAY_SIZE(da7213_dapm_mixinl_controls)),
776 SND_SOC_DAPM_MIXER("Mixin Right", SND_SOC_NOPM, 0, 0,
777 &da7213_dapm_mixinr_controls[0],
778 ARRAY_SIZE(da7213_dapm_mixinr_controls)),
779
780 /* ADCs */
781 SND_SOC_DAPM_ADC("ADC Left", NULL, DA7213_ADC_L_CTRL,
782 DA7213_ADC_EN_SHIFT, DA7213_NO_INVERT),
783 SND_SOC_DAPM_ADC("ADC Right", NULL, DA7213_ADC_R_CTRL,
784 DA7213_ADC_EN_SHIFT, DA7213_NO_INVERT),
785
786 /* DAI */
787 SND_SOC_DAPM_MUX("DAI Left Source MUX", SND_SOC_NOPM, 0, 0,
788 &da7213_dai_l_src_mux),
789 SND_SOC_DAPM_MUX("DAI Right Source MUX", SND_SOC_NOPM, 0, 0,
790 &da7213_dai_r_src_mux),
791 SND_SOC_DAPM_AIF_OUT("DAIOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
792 SND_SOC_DAPM_AIF_OUT("DAIOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
793
794 /*
795 * Output
796 */
797
798 /* DAI */
799 SND_SOC_DAPM_AIF_IN("DAIINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
800 SND_SOC_DAPM_AIF_IN("DAIINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
801 SND_SOC_DAPM_MUX("DAC Left Source MUX", SND_SOC_NOPM, 0, 0,
802 &da7213_dac_l_src_mux),
803 SND_SOC_DAPM_MUX("DAC Right Source MUX", SND_SOC_NOPM, 0, 0,
804 &da7213_dac_r_src_mux),
805
806 /* DACs */
807 SND_SOC_DAPM_DAC("DAC Left", NULL, DA7213_DAC_L_CTRL,
808 DA7213_DAC_EN_SHIFT, DA7213_NO_INVERT),
809 SND_SOC_DAPM_DAC("DAC Right", NULL, DA7213_DAC_R_CTRL,
810 DA7213_DAC_EN_SHIFT, DA7213_NO_INVERT),
811
812 /* Output Mixers */
813 SND_SOC_DAPM_MIXER("Mixout Left", SND_SOC_NOPM, 0, 0,
814 &da7213_dapm_mixoutl_controls[0],
815 ARRAY_SIZE(da7213_dapm_mixoutl_controls)),
816 SND_SOC_DAPM_MIXER("Mixout Right", SND_SOC_NOPM, 0, 0,
817 &da7213_dapm_mixoutr_controls[0],
818 ARRAY_SIZE(da7213_dapm_mixoutr_controls)),
819
820 /* Output PGAs */
821 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7213_MIXOUT_L_CTRL,
822 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
823 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7213_MIXOUT_R_CTRL,
824 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
825 SND_SOC_DAPM_PGA("Lineout PGA", DA7213_LINE_CTRL, DA7213_AMP_EN_SHIFT,
826 DA7213_NO_INVERT, NULL, 0),
827 SND_SOC_DAPM_PGA("Headphone Left PGA", DA7213_HP_L_CTRL,
828 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
829 SND_SOC_DAPM_PGA("Headphone Right PGA", DA7213_HP_R_CTRL,
830 DA7213_AMP_EN_SHIFT, DA7213_NO_INVERT, NULL, 0),
831
832 /* Charge Pump */
833 SND_SOC_DAPM_SUPPLY("Charge Pump", DA7213_CP_CTRL, DA7213_CP_EN_SHIFT,
834 DA7213_NO_INVERT, NULL, 0),
835
836 /* Output Lines */
837 SND_SOC_DAPM_OUTPUT("HPL"),
838 SND_SOC_DAPM_OUTPUT("HPR"),
839 SND_SOC_DAPM_OUTPUT("LINE"),
840};
841
842
843/*
844 * DAPM audio route definition
845 */
846
847static const struct snd_soc_dapm_route da7213_audio_map[] = {
848 /* Dest Connecting Widget source */
849
850 /* Input path */
851 {"MIC1", NULL, "Mic Bias 1"},
852 {"MIC2", NULL, "Mic Bias 2"},
853
854 {"Mic 1 Amp Source MUX", "Differential", "MIC1"},
855 {"Mic 1 Amp Source MUX", "MIC_P", "MIC1"},
856 {"Mic 1 Amp Source MUX", "MIC_N", "MIC1"},
857
858 {"Mic 2 Amp Source MUX", "Differential", "MIC2"},
859 {"Mic 2 Amp Source MUX", "MIC_P", "MIC2"},
860 {"Mic 2 Amp Source MUX", "MIC_N", "MIC2"},
861
862 {"Mic 1 PGA", NULL, "Mic 1 Amp Source MUX"},
863 {"Mic 2 PGA", NULL, "Mic 2 Amp Source MUX"},
864
865 {"Aux Left PGA", NULL, "AUXL"},
866 {"Aux Right PGA", NULL, "AUXR"},
867
868 {"Mixin Left", "Aux Left Switch", "Aux Left PGA"},
869 {"Mixin Left", "Mic 1 Switch", "Mic 1 PGA"},
870 {"Mixin Left", "Mic 2 Switch", "Mic 2 PGA"},
871 {"Mixin Left", "Mixin Right Switch", "Mixin Right PGA"},
872
873 {"Mixin Right", "Aux Right Switch", "Aux Right PGA"},
874 {"Mixin Right", "Mic 2 Switch", "Mic 2 PGA"},
875 {"Mixin Right", "Mic 1 Switch", "Mic 1 PGA"},
876 {"Mixin Right", "Mixin Left Switch", "Mixin Left PGA"},
877
878 {"Mixin Left PGA", NULL, "Mixin Left"},
879 {"ADC Left", NULL, "Mixin Left PGA"},
880
881 {"Mixin Right PGA", NULL, "Mixin Right"},
882 {"ADC Right", NULL, "Mixin Right PGA"},
883
884 {"DAI Left Source MUX", "ADC Left", "ADC Left"},
885 {"DAI Left Source MUX", "ADC Right", "ADC Right"},
886 {"DAI Left Source MUX", "DAI Input Left", "DAIINL"},
887 {"DAI Left Source MUX", "DAI Input Right", "DAIINR"},
888
889 {"DAI Right Source MUX", "ADC Left", "ADC Left"},
890 {"DAI Right Source MUX", "ADC Right", "ADC Right"},
891 {"DAI Right Source MUX", "DAI Input Left", "DAIINL"},
892 {"DAI Right Source MUX", "DAI Input Right", "DAIINR"},
893
894 {"DAIOUTL", NULL, "DAI Left Source MUX"},
895 {"DAIOUTR", NULL, "DAI Right Source MUX"},
896
897 {"DAIOUTL", NULL, "DAI"},
898 {"DAIOUTR", NULL, "DAI"},
899
900 /* Output path */
901 {"DAIINL", NULL, "DAI"},
902 {"DAIINR", NULL, "DAI"},
903
904 {"DAC Left Source MUX", "ADC Output Left", "ADC Left"},
905 {"DAC Left Source MUX", "ADC Output Right", "ADC Right"},
906 {"DAC Left Source MUX", "DAI Input Left", "DAIINL"},
907 {"DAC Left Source MUX", "DAI Input Right", "DAIINR"},
908
909 {"DAC Right Source MUX", "ADC Output Left", "ADC Left"},
910 {"DAC Right Source MUX", "ADC Output Right", "ADC Right"},
911 {"DAC Right Source MUX", "DAI Input Left", "DAIINL"},
912 {"DAC Right Source MUX", "DAI Input Right", "DAIINR"},
913
914 {"DAC Left", NULL, "DAC Left Source MUX"},
915 {"DAC Right", NULL, "DAC Right Source MUX"},
916
917 {"Mixout Left", "Aux Left Switch", "Aux Left PGA"},
918 {"Mixout Left", "Mixin Left Switch", "Mixin Left PGA"},
919 {"Mixout Left", "Mixin Right Switch", "Mixin Right PGA"},
920 {"Mixout Left", "DAC Left Switch", "DAC Left"},
921 {"Mixout Left", "Aux Left Invert Switch", "Aux Left PGA"},
922 {"Mixout Left", "Mixin Left Invert Switch", "Mixin Left PGA"},
923 {"Mixout Left", "Mixin Right Invert Switch", "Mixin Right PGA"},
924
925 {"Mixout Right", "Aux Right Switch", "Aux Right PGA"},
926 {"Mixout Right", "Mixin Right Switch", "Mixin Right PGA"},
927 {"Mixout Right", "Mixin Left Switch", "Mixin Left PGA"},
928 {"Mixout Right", "DAC Right Switch", "DAC Right"},
929 {"Mixout Right", "Aux Right Invert Switch", "Aux Right PGA"},
930 {"Mixout Right", "Mixin Right Invert Switch", "Mixin Right PGA"},
931 {"Mixout Right", "Mixin Left Invert Switch", "Mixin Left PGA"},
932
933 {"Mixout Left PGA", NULL, "Mixout Left"},
934 {"Mixout Right PGA", NULL, "Mixout Right"},
935
936 {"Headphone Left PGA", NULL, "Mixout Left PGA"},
937 {"Headphone Left PGA", NULL, "Charge Pump"},
938 {"HPL", NULL, "Headphone Left PGA"},
939
940 {"Headphone Right PGA", NULL, "Mixout Right PGA"},
941 {"Headphone Right PGA", NULL, "Charge Pump"},
942 {"HPR", NULL, "Headphone Right PGA"},
943
944 {"Lineout PGA", NULL, "Mixout Right PGA"},
945 {"LINE", NULL, "Lineout PGA"},
946};
947
948static struct reg_default da7213_reg_defaults[] = {
949 { DA7213_DIG_ROUTING_DAI, 0x10 },
950 { DA7213_SR, 0x0A },
951 { DA7213_REFERENCES, 0x80 },
952 { DA7213_PLL_FRAC_TOP, 0x00 },
953 { DA7213_PLL_FRAC_BOT, 0x00 },
954 { DA7213_PLL_INTEGER, 0x20 },
955 { DA7213_PLL_CTRL, 0x0C },
956 { DA7213_DAI_CLK_MODE, 0x01 },
957 { DA7213_DAI_CTRL, 0x08 },
958 { DA7213_DIG_ROUTING_DAC, 0x32 },
959 { DA7213_AUX_L_GAIN, 0x35 },
960 { DA7213_AUX_R_GAIN, 0x35 },
961 { DA7213_MIXIN_L_SELECT, 0x00 },
962 { DA7213_MIXIN_R_SELECT, 0x00 },
963 { DA7213_MIXIN_L_GAIN, 0x03 },
964 { DA7213_MIXIN_R_GAIN, 0x03 },
965 { DA7213_ADC_L_GAIN, 0x6F },
966 { DA7213_ADC_R_GAIN, 0x6F },
967 { DA7213_ADC_FILTERS1, 0x80 },
968 { DA7213_MIC_1_GAIN, 0x01 },
969 { DA7213_MIC_2_GAIN, 0x01 },
970 { DA7213_DAC_FILTERS5, 0x00 },
971 { DA7213_DAC_FILTERS2, 0x88 },
972 { DA7213_DAC_FILTERS3, 0x88 },
973 { DA7213_DAC_FILTERS4, 0x08 },
974 { DA7213_DAC_FILTERS1, 0x80 },
975 { DA7213_DAC_L_GAIN, 0x6F },
976 { DA7213_DAC_R_GAIN, 0x6F },
977 { DA7213_CP_CTRL, 0x61 },
978 { DA7213_HP_L_GAIN, 0x39 },
979 { DA7213_HP_R_GAIN, 0x39 },
980 { DA7213_LINE_GAIN, 0x30 },
981 { DA7213_MIXOUT_L_SELECT, 0x00 },
982 { DA7213_MIXOUT_R_SELECT, 0x00 },
983 { DA7213_SYSTEM_MODES_INPUT, 0x00 },
984 { DA7213_SYSTEM_MODES_OUTPUT, 0x00 },
985 { DA7213_AUX_L_CTRL, 0x44 },
986 { DA7213_AUX_R_CTRL, 0x44 },
987 { DA7213_MICBIAS_CTRL, 0x11 },
988 { DA7213_MIC_1_CTRL, 0x40 },
989 { DA7213_MIC_2_CTRL, 0x40 },
990 { DA7213_MIXIN_L_CTRL, 0x40 },
991 { DA7213_MIXIN_R_CTRL, 0x40 },
992 { DA7213_ADC_L_CTRL, 0x40 },
993 { DA7213_ADC_R_CTRL, 0x40 },
994 { DA7213_DAC_L_CTRL, 0x48 },
995 { DA7213_DAC_R_CTRL, 0x40 },
996 { DA7213_HP_L_CTRL, 0x41 },
997 { DA7213_HP_R_CTRL, 0x40 },
998 { DA7213_LINE_CTRL, 0x40 },
999 { DA7213_MIXOUT_L_CTRL, 0x10 },
1000 { DA7213_MIXOUT_R_CTRL, 0x10 },
1001 { DA7213_LDO_CTRL, 0x00 },
1002 { DA7213_IO_CTRL, 0x00 },
1003 { DA7213_GAIN_RAMP_CTRL, 0x00},
1004 { DA7213_MIC_CONFIG, 0x00 },
1005 { DA7213_PC_COUNT, 0x00 },
1006 { DA7213_CP_VOL_THRESHOLD1, 0x32 },
1007 { DA7213_CP_DELAY, 0x95 },
1008 { DA7213_CP_DETECTOR, 0x00 },
1009 { DA7213_DAI_OFFSET, 0x00 },
1010 { DA7213_DIG_CTRL, 0x00 },
1011 { DA7213_ALC_CTRL2, 0x00 },
1012 { DA7213_ALC_CTRL3, 0x00 },
1013 { DA7213_ALC_NOISE, 0x3F },
1014 { DA7213_ALC_TARGET_MIN, 0x3F },
1015 { DA7213_ALC_TARGET_MAX, 0x00 },
1016 { DA7213_ALC_GAIN_LIMITS, 0xFF },
1017 { DA7213_ALC_ANA_GAIN_LIMITS, 0x71 },
1018 { DA7213_ALC_ANTICLIP_CTRL, 0x00 },
1019 { DA7213_ALC_ANTICLIP_LEVEL, 0x00 },
1020 { DA7213_ALC_OFFSET_MAN_M_L, 0x00 },
1021 { DA7213_ALC_OFFSET_MAN_U_L, 0x00 },
1022 { DA7213_ALC_OFFSET_MAN_M_R, 0x00 },
1023 { DA7213_ALC_OFFSET_MAN_U_R, 0x00 },
1024 { DA7213_ALC_CIC_OP_LVL_CTRL, 0x00 },
1025 { DA7213_DAC_NG_SETUP_TIME, 0x00 },
1026 { DA7213_DAC_NG_OFF_THRESHOLD, 0x00 },
1027 { DA7213_DAC_NG_ON_THRESHOLD, 0x00 },
1028 { DA7213_DAC_NG_CTRL, 0x00 },
1029};
1030
1031static bool da7213_volatile_register(struct device *dev, unsigned int reg)
1032{
1033 switch (reg) {
1034 case DA7213_STATUS1:
1035 case DA7213_PLL_STATUS:
1036 case DA7213_AUX_L_GAIN_STATUS:
1037 case DA7213_AUX_R_GAIN_STATUS:
1038 case DA7213_MIC_1_GAIN_STATUS:
1039 case DA7213_MIC_2_GAIN_STATUS:
1040 case DA7213_MIXIN_L_GAIN_STATUS:
1041 case DA7213_MIXIN_R_GAIN_STATUS:
1042 case DA7213_ADC_L_GAIN_STATUS:
1043 case DA7213_ADC_R_GAIN_STATUS:
1044 case DA7213_DAC_L_GAIN_STATUS:
1045 case DA7213_DAC_R_GAIN_STATUS:
1046 case DA7213_HP_L_GAIN_STATUS:
1047 case DA7213_HP_R_GAIN_STATUS:
1048 case DA7213_LINE_GAIN_STATUS:
1049 case DA7213_ALC_CTRL1:
1050 case DA7213_ALC_OFFSET_AUTO_M_L:
1051 case DA7213_ALC_OFFSET_AUTO_U_L:
1052 case DA7213_ALC_OFFSET_AUTO_M_R:
1053 case DA7213_ALC_OFFSET_AUTO_U_R:
1054 case DA7213_ALC_CIC_OP_LVL_DATA:
1055 return 1;
1056 default:
1057 return 0;
1058 }
1059}
1060
1061static int da7213_hw_params(struct snd_pcm_substream *substream,
1062 struct snd_pcm_hw_params *params,
1063 struct snd_soc_dai *dai)
1064{
1065 struct snd_soc_codec *codec = dai->codec;
1066 u8 dai_ctrl = 0;
1067 u8 fs;
1068
1069 /* Set DAI format */
1070 switch (params_format(params)) {
1071 case SNDRV_PCM_FORMAT_S16_LE:
1072 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE;
1073 break;
1074 case SNDRV_PCM_FORMAT_S20_3LE:
1075 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE;
1076 break;
1077 case SNDRV_PCM_FORMAT_S24_LE:
1078 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE;
1079 break;
1080 case SNDRV_PCM_FORMAT_S32_LE:
1081 dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE;
1082 break;
1083 default:
1084 return -EINVAL;
1085 }
1086
1087 /* Set sampling rate */
1088 switch (params_rate(params)) {
1089 case 8000:
1090 fs = DA7213_SR_8000;
1091 break;
1092 case 11025:
1093 fs = DA7213_SR_11025;
1094 break;
1095 case 12000:
1096 fs = DA7213_SR_12000;
1097 break;
1098 case 16000:
1099 fs = DA7213_SR_16000;
1100 break;
1101 case 22050:
1102 fs = DA7213_SR_22050;
1103 break;
1104 case 32000:
1105 fs = DA7213_SR_32000;
1106 break;
1107 case 44100:
1108 fs = DA7213_SR_44100;
1109 break;
1110 case 48000:
1111 fs = DA7213_SR_48000;
1112 break;
1113 case 88200:
1114 fs = DA7213_SR_88200;
1115 break;
1116 case 96000:
1117 fs = DA7213_SR_96000;
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122
1123 snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_WORD_LENGTH_MASK,
1124 dai_ctrl);
1125 snd_soc_write(codec, DA7213_SR, fs);
1126
1127 return 0;
1128}
1129
1130static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1131{
1132 struct snd_soc_codec *codec = codec_dai->codec;
1133 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1134 u8 dai_clk_mode = 0, dai_ctrl = 0;
1135
1136 /* Set master/slave mode */
1137 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1138 case SND_SOC_DAIFMT_CBM_CFM:
1139 dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE;
1140 da7213->master = true;
1141 break;
1142 case SND_SOC_DAIFMT_CBS_CFS:
1143 dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE;
1144 da7213->master = false;
1145 break;
1146 default:
1147 return -EINVAL;
1148 }
1149
1150 /* Set clock normal/inverted */
1151 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1152 case SND_SOC_DAIFMT_NB_NF:
1153 break;
1154 case SND_SOC_DAIFMT_NB_IF:
1155 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV;
1156 break;
1157 case SND_SOC_DAIFMT_IB_NF:
1158 dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
1159 break;
1160 case SND_SOC_DAIFMT_IB_IF:
1161 dai_clk_mode |= DA7213_DAI_WCLK_POL_INV | DA7213_DAI_CLK_POL_INV;
1162 break;
1163 default:
1164 return -EINVAL;
1165 }
1166
1167 /* Only I2S is supported */
1168 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1169 case SND_SOC_DAIFMT_I2S:
1170 dai_ctrl |= DA7213_DAI_FORMAT_I2S_MODE;
1171 break;
1172 case SND_SOC_DAIFMT_LEFT_J:
1173 dai_ctrl |= DA7213_DAI_FORMAT_LEFT_J;
1174 break;
1175 case SND_SOC_DAIFMT_RIGHT_J:
1176 dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
1177 break;
1178 default:
1179 return -EINVAL;
1180 }
1181
1182 /* By default only 32 BCLK per WCLK is supported */
1183 dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_32;
1184
1185 snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
1186 snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
1187 dai_ctrl);
1188
1189 return 0;
1190}
1191
1192static int da7213_mute(struct snd_soc_dai *dai, int mute)
1193{
1194 struct snd_soc_codec *codec = dai->codec;
1195
1196 if (mute) {
1197 snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
1198 DA7213_MUTE_EN, DA7213_MUTE_EN);
1199 snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
1200 DA7213_MUTE_EN, DA7213_MUTE_EN);
1201 } else {
1202 snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
1203 DA7213_MUTE_EN, 0);
1204 snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
1205 DA7213_MUTE_EN, 0);
1206 }
1207
1208 return 0;
1209}
1210
1211#define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1212 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1213
1214static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1215 int clk_id, unsigned int freq, int dir)
1216{
1217 struct snd_soc_codec *codec = codec_dai->codec;
1218 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1219
1220 switch (clk_id) {
1221 case DA7213_CLKSRC_MCLK:
1222 if ((freq == 32768) ||
1223 ((freq >= 5000000) && (freq <= 54000000))) {
1224 da7213->mclk_rate = freq;
1225 return 0;
1226 } else {
1227 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1228 freq);
1229 return -EINVAL;
1230 }
1231 break;
1232 default:
1233 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1234 return -EINVAL;
1235 }
1236}
1237
1238/* Supported PLL input frequencies are 5MHz - 54MHz. */
1239static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1240 int source, unsigned int fref, unsigned int fout)
1241{
1242 struct snd_soc_codec *codec = codec_dai->codec;
1243 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1244
1245 u8 pll_ctrl, indiv_bits, indiv;
1246 u8 pll_frac_top, pll_frac_bot, pll_integer;
1247 u32 freq_ref;
1248 u64 frac_div;
1249
1250 /* Reset PLL configuration */
1251 snd_soc_write(codec, DA7213_PLL_CTRL, 0);
1252
1253 pll_ctrl = 0;
1254
1255 /* Workout input divider based on MCLK rate */
1256 if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) {
1257 /* 32KHz PLL Mode */
1258 indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
1259 indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
1260 freq_ref = 3750000;
1261 pll_ctrl |= DA7213_PLL_32K_MODE;
1262 } else {
1263 /* 5 - 54MHz MCLK */
1264 if (da7213->mclk_rate < 5000000) {
1265 goto pll_err;
1266 } else if (da7213->mclk_rate <= 10000000) {
1267 indiv_bits = DA7213_PLL_INDIV_5_10_MHZ;
1268 indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL;
1269 } else if (da7213->mclk_rate <= 20000000) {
1270 indiv_bits = DA7213_PLL_INDIV_10_20_MHZ;
1271 indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL;
1272 } else if (da7213->mclk_rate <= 40000000) {
1273 indiv_bits = DA7213_PLL_INDIV_20_40_MHZ;
1274 indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL;
1275 } else if (da7213->mclk_rate <= 54000000) {
1276 indiv_bits = DA7213_PLL_INDIV_40_54_MHZ;
1277 indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL;
1278 } else {
1279 goto pll_err;
1280 }
1281 freq_ref = (da7213->mclk_rate / indiv);
1282 }
1283
1284 pll_ctrl |= indiv_bits;
1285
1286 /* PLL Bypass mode */
1287 if (source == DA7213_SYSCLK_MCLK) {
1288 snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
1289 return 0;
1290 }
1291
1292 /*
1293 * If Codec is slave and SRM enabled,
1294 * freq_out is (98304000 + 90316800)/2 = 94310400
1295 */
1296 if (!da7213->master && da7213->srm_en) {
1297 fout = DA7213_PLL_FREQ_OUT_94310400;
1298 pll_ctrl |= DA7213_PLL_SRM_EN;
1299 }
1300
1301 /* Enable MCLK squarer if required */
1302 if (da7213->mclk_squarer_en)
1303 pll_ctrl |= DA7213_PLL_MCLK_SQR_EN;
1304
1305 /* Calculate dividers for PLL */
1306 pll_integer = fout / freq_ref;
1307 frac_div = (u64)(fout % freq_ref) * 8192ULL;
1308 do_div(frac_div, freq_ref);
1309 pll_frac_top = (frac_div >> DA7213_BYTE_SHIFT) & DA7213_BYTE_MASK;
1310 pll_frac_bot = (frac_div) & DA7213_BYTE_MASK;
1311
1312 /* Write PLL dividers */
1313 snd_soc_write(codec, DA7213_PLL_FRAC_TOP, pll_frac_top);
1314 snd_soc_write(codec, DA7213_PLL_FRAC_BOT, pll_frac_bot);
1315 snd_soc_write(codec, DA7213_PLL_INTEGER, pll_integer);
1316
1317 /* Enable PLL */
1318 pll_ctrl |= DA7213_PLL_EN;
1319 snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
1320
1321 return 0;
1322
1323pll_err:
1324 dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n",
1325 da7213->mclk_rate);
1326 return -EINVAL;
1327}
1328
1329/* DAI operations */
1330static const struct snd_soc_dai_ops da7213_dai_ops = {
1331 .hw_params = da7213_hw_params,
1332 .set_fmt = da7213_set_dai_fmt,
1333 .set_sysclk = da7213_set_dai_sysclk,
1334 .set_pll = da7213_set_dai_pll,
1335 .digital_mute = da7213_mute,
1336};
1337
1338static struct snd_soc_dai_driver da7213_dai = {
1339 .name = "da7213-hifi",
1340 /* Playback Capabilities */
1341 .playback = {
1342 .stream_name = "Playback",
1343 .channels_min = 1,
1344 .channels_max = 2,
1345 .rates = SNDRV_PCM_RATE_8000_96000,
1346 .formats = DA7213_FORMATS,
1347 },
1348 /* Capture Capabilities */
1349 .capture = {
1350 .stream_name = "Capture",
1351 .channels_min = 1,
1352 .channels_max = 2,
1353 .rates = SNDRV_PCM_RATE_8000_96000,
1354 .formats = DA7213_FORMATS,
1355 },
1356 .ops = &da7213_dai_ops,
1357 .symmetric_rates = 1,
1358};
1359
1360static int da7213_set_bias_level(struct snd_soc_codec *codec,
1361 enum snd_soc_bias_level level)
1362{
1363 switch (level) {
1364 case SND_SOC_BIAS_ON:
1365 case SND_SOC_BIAS_PREPARE:
1366 break;
1367 case SND_SOC_BIAS_STANDBY:
1368 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1369 /* Enable VMID reference & master bias */
1370 snd_soc_update_bits(codec, DA7213_REFERENCES,
1371 DA7213_VMID_EN | DA7213_BIAS_EN,
1372 DA7213_VMID_EN | DA7213_BIAS_EN);
1373 }
1374 break;
1375 case SND_SOC_BIAS_OFF:
1376 /* Disable VMID reference & master bias */
1377 snd_soc_update_bits(codec, DA7213_REFERENCES,
1378 DA7213_VMID_EN | DA7213_BIAS_EN, 0);
1379 break;
1380 }
1381 codec->dapm.bias_level = level;
1382 return 0;
1383}
1384
1385static int da7213_probe(struct snd_soc_codec *codec)
1386{
1387 int ret;
1388 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1389 struct da7213_platform_data *pdata = da7213->pdata;
1390
1391 codec->control_data = da7213->regmap;
1392 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1393 if (ret < 0) {
1394 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1395 return ret;
1396 }
1397
1398 /* Default to using ALC auto offset calibration mode. */
1399 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
1400 DA7213_ALC_CALIB_MODE_MAN, 0);
1401 da7213->alc_calib_auto = true;
1402
1403 /* Default to using SRM for slave mode */
1404 da7213->srm_en = true;
1405
1406 /* Enable all Gain Ramps */
1407 snd_soc_update_bits(codec, DA7213_AUX_L_CTRL,
1408 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1409 snd_soc_update_bits(codec, DA7213_AUX_R_CTRL,
1410 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1411 snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
1412 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1413 snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
1414 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1415 snd_soc_update_bits(codec, DA7213_ADC_L_CTRL,
1416 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1417 snd_soc_update_bits(codec, DA7213_ADC_R_CTRL,
1418 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1419 snd_soc_update_bits(codec, DA7213_DAC_L_CTRL,
1420 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1421 snd_soc_update_bits(codec, DA7213_DAC_R_CTRL,
1422 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1423 snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
1424 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1425 snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
1426 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1427 snd_soc_update_bits(codec, DA7213_LINE_CTRL,
1428 DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN);
1429
1430 /*
1431 * There are two separate control bits for input and output mixers as
1432 * well as headphone and line outs.
1433 * One to enable corresponding amplifier and other to enable its
1434 * output. As amplifier bits are related to power control, they are
1435 * being managed by DAPM while other (non power related) bits are
1436 * enabled here
1437 */
1438 snd_soc_update_bits(codec, DA7213_MIXIN_L_CTRL,
1439 DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
1440 snd_soc_update_bits(codec, DA7213_MIXIN_R_CTRL,
1441 DA7213_MIXIN_MIX_EN, DA7213_MIXIN_MIX_EN);
1442
1443 snd_soc_update_bits(codec, DA7213_MIXOUT_L_CTRL,
1444 DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
1445 snd_soc_update_bits(codec, DA7213_MIXOUT_R_CTRL,
1446 DA7213_MIXOUT_MIX_EN, DA7213_MIXOUT_MIX_EN);
1447
1448 snd_soc_update_bits(codec, DA7213_HP_L_CTRL,
1449 DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
1450 snd_soc_update_bits(codec, DA7213_HP_R_CTRL,
1451 DA7213_HP_AMP_OE, DA7213_HP_AMP_OE);
1452
1453 snd_soc_update_bits(codec, DA7213_LINE_CTRL,
1454 DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
1455
1456 /* Set platform data values */
1457 if (da7213->pdata) {
1458 u8 micbias_lvl = 0, dmic_cfg = 0;
1459
1460 /* Set Mic Bias voltages */
1461 switch (pdata->micbias1_lvl) {
1462 case DA7213_MICBIAS_1_6V:
1463 case DA7213_MICBIAS_2_2V:
1464 case DA7213_MICBIAS_2_5V:
1465 case DA7213_MICBIAS_3_0V:
1466 micbias_lvl |= (pdata->micbias1_lvl <<
1467 DA7213_MICBIAS1_LEVEL_SHIFT);
1468 break;
1469 }
1470 switch (pdata->micbias2_lvl) {
1471 case DA7213_MICBIAS_1_6V:
1472 case DA7213_MICBIAS_2_2V:
1473 case DA7213_MICBIAS_2_5V:
1474 case DA7213_MICBIAS_3_0V:
1475 micbias_lvl |= (pdata->micbias2_lvl <<
1476 DA7213_MICBIAS2_LEVEL_SHIFT);
1477 break;
1478 }
1479 snd_soc_update_bits(codec, DA7213_MICBIAS_CTRL,
1480 DA7213_MICBIAS1_LEVEL_MASK |
1481 DA7213_MICBIAS2_LEVEL_MASK, micbias_lvl);
1482
1483 /* Set DMIC configuration */
1484 switch (pdata->dmic_data_sel) {
1485 case DA7213_DMIC_DATA_LFALL_RRISE:
1486 case DA7213_DMIC_DATA_LRISE_RFALL:
1487 dmic_cfg |= (pdata->dmic_data_sel <<
1488 DA7213_DMIC_DATA_SEL_SHIFT);
1489 break;
1490 }
1491 switch (pdata->dmic_data_sel) {
1492 case DA7213_DMIC_SAMPLE_ON_CLKEDGE:
1493 case DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE:
1494 dmic_cfg |= (pdata->dmic_data_sel <<
1495 DA7213_DMIC_SAMPLEPHASE_SHIFT);
1496 break;
1497 }
1498 switch (pdata->dmic_data_sel) {
1499 case DA7213_DMIC_CLK_3_0MHZ:
1500 case DA7213_DMIC_CLK_1_5MHZ:
1501 dmic_cfg |= (pdata->dmic_data_sel <<
1502 DA7213_DMIC_CLK_RATE_SHIFT);
1503 break;
1504 }
1505 snd_soc_update_bits(codec, DA7213_MIC_CONFIG,
1506 DA7213_DMIC_DATA_SEL_MASK |
1507 DA7213_DMIC_SAMPLEPHASE_MASK |
1508 DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
1509
1510 /* Set MCLK squaring */
1511 da7213->mclk_squarer_en = pdata->mclk_squaring;
1512 }
1513 return 0;
1514}
1515
1516static struct snd_soc_codec_driver soc_codec_dev_da7213 = {
1517 .probe = da7213_probe,
1518 .set_bias_level = da7213_set_bias_level,
1519
1520 .controls = da7213_snd_controls,
1521 .num_controls = ARRAY_SIZE(da7213_snd_controls),
1522
1523 .dapm_widgets = da7213_dapm_widgets,
1524 .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
1525 .dapm_routes = da7213_audio_map,
1526 .num_dapm_routes = ARRAY_SIZE(da7213_audio_map),
1527};
1528
1529static const struct regmap_config da7213_regmap_config = {
1530 .reg_bits = 8,
1531 .val_bits = 8,
1532
1533 .reg_defaults = da7213_reg_defaults,
1534 .num_reg_defaults = ARRAY_SIZE(da7213_reg_defaults),
1535 .volatile_reg = da7213_volatile_register,
1536 .cache_type = REGCACHE_RBTREE,
1537};
1538
1539static int da7213_i2c_probe(struct i2c_client *i2c,
1540 const struct i2c_device_id *id)
1541{
1542 struct da7213_priv *da7213;
1543 struct da7213_platform_data *pdata = dev_get_platdata(&i2c->dev);
1544 int ret;
1545
1546 da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv),
1547 GFP_KERNEL);
1548 if (!da7213)
1549 return -ENOMEM;
1550
1551 if (pdata)
1552 da7213->pdata = pdata;
1553
1554 i2c_set_clientdata(i2c, da7213);
1555
1556 da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
1557 if (IS_ERR(da7213->regmap)) {
1558 ret = PTR_ERR(da7213->regmap);
1559 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1560 return ret;
1561 }
1562
1563 ret = snd_soc_register_codec(&i2c->dev,
1564 &soc_codec_dev_da7213, &da7213_dai, 1);
1565 if (ret < 0) {
1566 dev_err(&i2c->dev, "Failed to register da7213 codec: %d\n",
1567 ret);
1568 }
1569 return ret;
1570}
1571
1572static int da7213_remove(struct i2c_client *client)
1573{
1574 snd_soc_unregister_codec(&client->dev);
1575 return 0;
1576}
1577
1578static const struct i2c_device_id da7213_i2c_id[] = {
1579 { "da7213", 0 },
1580 { }
1581};
1582MODULE_DEVICE_TABLE(i2c, da7213_i2c_id);
1583
1584/* I2C codec control layer */
1585static struct i2c_driver da7213_i2c_driver = {
1586 .driver = {
1587 .name = "da7213",
1588 .owner = THIS_MODULE,
1589 },
1590 .probe = da7213_i2c_probe,
1591 .remove = da7213_remove,
1592 .id_table = da7213_i2c_id,
1593};
1594
1595module_i2c_driver(da7213_i2c_driver);
1596
1597MODULE_DESCRIPTION("ASoC DA7213 Codec driver");
1598MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
1599MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
new file mode 100644
index 000000000000..9cb9ddd01282
--- /dev/null
+++ b/sound/soc/codecs/da7213.h
@@ -0,0 +1,523 @@
1/*
2 * da7213.h - DA7213 ASoC Codec Driver
3 *
4 * Copyright (c) 2013 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _DA7213_H
14#define _DA7213_H
15
16#include <linux/regmap.h>
17#include <sound/da7213.h>
18
19/*
20 * Registers
21 */
22
23/* Status Registers */
24#define DA7213_STATUS1 0x02
25#define DA7213_PLL_STATUS 0x03
26#define DA7213_AUX_L_GAIN_STATUS 0x04
27#define DA7213_AUX_R_GAIN_STATUS 0x05
28#define DA7213_MIC_1_GAIN_STATUS 0x06
29#define DA7213_MIC_2_GAIN_STATUS 0x07
30#define DA7213_MIXIN_L_GAIN_STATUS 0x08
31#define DA7213_MIXIN_R_GAIN_STATUS 0x09
32#define DA7213_ADC_L_GAIN_STATUS 0x0A
33#define DA7213_ADC_R_GAIN_STATUS 0x0B
34#define DA7213_DAC_L_GAIN_STATUS 0x0C
35#define DA7213_DAC_R_GAIN_STATUS 0x0D
36#define DA7213_HP_L_GAIN_STATUS 0x0E
37#define DA7213_HP_R_GAIN_STATUS 0x0F
38#define DA7213_LINE_GAIN_STATUS 0x10
39
40/* System Initialisation Registers */
41#define DA7213_DIG_ROUTING_DAI 0x21
42#define DA7213_SR 0x22
43#define DA7213_REFERENCES 0x23
44#define DA7213_PLL_FRAC_TOP 0x24
45#define DA7213_PLL_FRAC_BOT 0x25
46#define DA7213_PLL_INTEGER 0x26
47#define DA7213_PLL_CTRL 0x27
48#define DA7213_DAI_CLK_MODE 0x28
49#define DA7213_DAI_CTRL 0x29
50#define DA7213_DIG_ROUTING_DAC 0x2A
51#define DA7213_ALC_CTRL1 0x2B
52
53/* Input - Gain, Select and Filter Registers */
54#define DA7213_AUX_L_GAIN 0x30
55#define DA7213_AUX_R_GAIN 0x31
56#define DA7213_MIXIN_L_SELECT 0x32
57#define DA7213_MIXIN_R_SELECT 0x33
58#define DA7213_MIXIN_L_GAIN 0x34
59#define DA7213_MIXIN_R_GAIN 0x35
60#define DA7213_ADC_L_GAIN 0x36
61#define DA7213_ADC_R_GAIN 0x37
62#define DA7213_ADC_FILTERS1 0x38
63#define DA7213_MIC_1_GAIN 0x39
64#define DA7213_MIC_2_GAIN 0x3A
65
66/* Output - Gain, Select and Filter Registers */
67#define DA7213_DAC_FILTERS5 0x40
68#define DA7213_DAC_FILTERS2 0x41
69#define DA7213_DAC_FILTERS3 0x42
70#define DA7213_DAC_FILTERS4 0x43
71#define DA7213_DAC_FILTERS1 0x44
72#define DA7213_DAC_L_GAIN 0x45
73#define DA7213_DAC_R_GAIN 0x46
74#define DA7213_CP_CTRL 0x47
75#define DA7213_HP_L_GAIN 0x48
76#define DA7213_HP_R_GAIN 0x49
77#define DA7213_LINE_GAIN 0x4A
78#define DA7213_MIXOUT_L_SELECT 0x4B
79#define DA7213_MIXOUT_R_SELECT 0x4C
80
81/* System Controller Registers */
82#define DA7213_SYSTEM_MODES_INPUT 0x50
83#define DA7213_SYSTEM_MODES_OUTPUT 0x51
84
85/* Control Registers */
86#define DA7213_AUX_L_CTRL 0x60
87#define DA7213_AUX_R_CTRL 0x61
88#define DA7213_MICBIAS_CTRL 0x62
89#define DA7213_MIC_1_CTRL 0x63
90#define DA7213_MIC_2_CTRL 0x64
91#define DA7213_MIXIN_L_CTRL 0x65
92#define DA7213_MIXIN_R_CTRL 0x66
93#define DA7213_ADC_L_CTRL 0x67
94#define DA7213_ADC_R_CTRL 0x68
95#define DA7213_DAC_L_CTRL 0x69
96#define DA7213_DAC_R_CTRL 0x6A
97#define DA7213_HP_L_CTRL 0x6B
98#define DA7213_HP_R_CTRL 0x6C
99#define DA7213_LINE_CTRL 0x6D
100#define DA7213_MIXOUT_L_CTRL 0x6E
101#define DA7213_MIXOUT_R_CTRL 0x6F
102
103/* Configuration Registers */
104#define DA7213_LDO_CTRL 0x90
105#define DA7213_IO_CTRL 0x91
106#define DA7213_GAIN_RAMP_CTRL 0x92
107#define DA7213_MIC_CONFIG 0x93
108#define DA7213_PC_COUNT 0x94
109#define DA7213_CP_VOL_THRESHOLD1 0x95
110#define DA7213_CP_DELAY 0x96
111#define DA7213_CP_DETECTOR 0x97
112#define DA7213_DAI_OFFSET 0x98
113#define DA7213_DIG_CTRL 0x99
114#define DA7213_ALC_CTRL2 0x9A
115#define DA7213_ALC_CTRL3 0x9B
116#define DA7213_ALC_NOISE 0x9C
117#define DA7213_ALC_TARGET_MIN 0x9D
118#define DA7213_ALC_TARGET_MAX 0x9E
119#define DA7213_ALC_GAIN_LIMITS 0x9F
120#define DA7213_ALC_ANA_GAIN_LIMITS 0xA0
121#define DA7213_ALC_ANTICLIP_CTRL 0xA1
122#define DA7213_ALC_ANTICLIP_LEVEL 0xA2
123
124#define DA7213_ALC_OFFSET_AUTO_M_L 0xA3
125#define DA7213_ALC_OFFSET_AUTO_U_L 0xA4
126#define DA7213_ALC_OFFSET_MAN_M_L 0xA6
127#define DA7213_ALC_OFFSET_MAN_U_L 0xA7
128#define DA7213_ALC_OFFSET_AUTO_M_R 0xA8
129#define DA7213_ALC_OFFSET_AUTO_U_R 0xA9
130#define DA7213_ALC_OFFSET_MAN_M_R 0xAB
131#define DA7213_ALC_OFFSET_MAN_U_R 0xAC
132#define DA7213_ALC_CIC_OP_LVL_CTRL 0xAD
133#define DA7213_ALC_CIC_OP_LVL_DATA 0xAE
134#define DA7213_DAC_NG_SETUP_TIME 0xAF
135#define DA7213_DAC_NG_OFF_THRESHOLD 0xB0
136#define DA7213_DAC_NG_ON_THRESHOLD 0xB1
137#define DA7213_DAC_NG_CTRL 0xB2
138
139
140/*
141 * Bit fields
142 */
143
144/* DA7213_SR = 0x22 */
145#define DA7213_SR_8000 (0x1 << 0)
146#define DA7213_SR_11025 (0x2 << 0)
147#define DA7213_SR_12000 (0x3 << 0)
148#define DA7213_SR_16000 (0x5 << 0)
149#define DA7213_SR_22050 (0x6 << 0)
150#define DA7213_SR_24000 (0x7 << 0)
151#define DA7213_SR_32000 (0x9 << 0)
152#define DA7213_SR_44100 (0xA << 0)
153#define DA7213_SR_48000 (0xB << 0)
154#define DA7213_SR_88200 (0xE << 0)
155#define DA7213_SR_96000 (0xF << 0)
156
157/* DA7213_REFERENCES = 0x23 */
158#define DA7213_BIAS_EN (0x1 << 3)
159#define DA7213_VMID_EN (0x1 << 7)
160
161/* DA7213_PLL_CTRL = 0x27 */
162#define DA7213_PLL_INDIV_5_10_MHZ (0x0 << 2)
163#define DA7213_PLL_INDIV_10_20_MHZ (0x1 << 2)
164#define DA7213_PLL_INDIV_20_40_MHZ (0x2 << 2)
165#define DA7213_PLL_INDIV_40_54_MHZ (0x3 << 2)
166#define DA7213_PLL_INDIV_MASK (0x3 << 2)
167#define DA7213_PLL_MCLK_SQR_EN (0x1 << 4)
168#define DA7213_PLL_32K_MODE (0x1 << 5)
169#define DA7213_PLL_SRM_EN (0x1 << 6)
170#define DA7213_PLL_EN (0x1 << 7)
171
172/* DA7213_DAI_CLK_MODE = 0x28 */
173#define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
174#define DA7213_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
175#define DA7213_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
176#define DA7213_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
177#define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
178#define DA7213_DAI_CLK_POL_INV (0x1 << 2)
179#define DA7213_DAI_WCLK_POL_INV (0x1 << 3)
180#define DA7213_DAI_CLK_EN_SLAVE_MODE (0x0 << 7)
181#define DA7213_DAI_CLK_EN_MASTER_MODE (0x1 << 7)
182#define DA7213_DAI_CLK_EN_MASK (0x1 << 7)
183
184/* DA7213_DAI_CTRL = 0x29 */
185#define DA7213_DAI_FORMAT_I2S_MODE (0x0 << 0)
186#define DA7213_DAI_FORMAT_LEFT_J (0x1 << 0)
187#define DA7213_DAI_FORMAT_RIGHT_J (0x2 << 0)
188#define DA7213_DAI_FORMAT_MASK (0x3 << 0)
189#define DA7213_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
190#define DA7213_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
191#define DA7213_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
192#define DA7213_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
193#define DA7213_DAI_WORD_LENGTH_MASK (0x3 << 2)
194#define DA7213_DAI_EN_SHIFT 7
195
196/* DA7213_DIG_ROUTING_DAI = 0x21 */
197#define DA7213_DAI_L_SRC_SHIFT 0
198#define DA7213_DAI_R_SRC_SHIFT 4
199#define DA7213_DAI_SRC_MAX 4
200
201/* DA7213_DIG_ROUTING_DAC = 0x2A */
202#define DA7213_DAC_L_SRC_SHIFT 0
203#define DA7213_DAC_L_MONO_SHIFT 3
204#define DA7213_DAC_R_SRC_SHIFT 4
205#define DA7213_DAC_R_MONO_SHIFT 7
206#define DA7213_DAC_SRC_MAX 4
207#define DA7213_DAC_MONO_MAX 0x1
208
209/* DA7213_ALC_CTRL1 = 0x2B */
210#define DA7213_ALC_OFFSET_EN_SHIFT 0
211#define DA7213_ALC_OFFSET_EN_MAX 0x1
212#define DA7213_ALC_OFFSET_EN (0x1 << 0)
213#define DA7213_ALC_SYNC_MODE (0x1 << 1)
214#define DA7213_ALC_CALIB_MODE_MAN (0x1 << 2)
215#define DA7213_ALC_L_EN_SHIFT 3
216#define DA7213_ALC_AUTO_CALIB_EN (0x1 << 4)
217#define DA7213_ALC_CALIB_OVERFLOW (0x1 << 5)
218#define DA7213_ALC_R_EN_SHIFT 7
219#define DA7213_ALC_EN_MAX 0x1
220
221/* DA7213_AUX_L/R_GAIN = 0x30/0x31 */
222#define DA7213_AUX_AMP_GAIN_SHIFT 0
223#define DA7213_AUX_AMP_GAIN_MAX 0x3F
224
225/* DA7213_MIXIN_L/R_SELECT = 0x32/0x33 */
226#define DA7213_DMIC_EN_SHIFT 7
227#define DA7213_DMIC_EN_MAX 0x1
228
229/* DA7213_MIXIN_L_SELECT = 0x32 */
230#define DA7213_MIXIN_L_MIX_SELECT_AUX_L_SHIFT 0
231#define DA7213_MIXIN_L_MIX_SELECT_MIC_1_SHIFT 1
232#define DA7213_MIXIN_L_MIX_SELECT_MIC_1 (0x1 << 1)
233#define DA7213_MIXIN_L_MIX_SELECT_MIC_2_SHIFT 2
234#define DA7213_MIXIN_L_MIX_SELECT_MIC_2 (0x1 << 2)
235#define DA7213_MIXIN_L_MIX_SELECT_MIXIN_R_SHIFT 3
236#define DA7213_MIXIN_L_MIX_SELECT_MAX 0x1
237
238/* DA7213_MIXIN_R_SELECT = 0x33 */
239#define DA7213_MIXIN_R_MIX_SELECT_AUX_R_SHIFT 0
240#define DA7213_MIXIN_R_MIX_SELECT_MIC_2_SHIFT 1
241#define DA7213_MIXIN_R_MIX_SELECT_MIC_2 (0x1 << 1)
242#define DA7213_MIXIN_R_MIX_SELECT_MIC_1_SHIFT 2
243#define DA7213_MIXIN_R_MIX_SELECT_MIC_1 (0x1 << 2)
244#define DA7213_MIXIN_R_MIX_SELECT_MIXIN_L_SHIFT 3
245#define DA7213_MIXIN_R_MIX_SELECT_MAX 0x1
246#define DA7213_MIC_BIAS_OUTPUT_SELECT_2 (0x1 << 6)
247
248/* DA7213_MIXIN_L/R_GAIN = 0x34/0x35 */
249#define DA7213_MIXIN_AMP_GAIN_SHIFT 0
250#define DA7213_MIXIN_AMP_GAIN_MAX 0xF
251
252/* DA7213_ADC_L/R_GAIN = 0x36/0x37 */
253#define DA7213_ADC_AMP_GAIN_SHIFT 0
254#define DA7213_ADC_AMP_GAIN_MAX 0x7F
255
256/* DA7213_ADC/DAC_FILTERS1 = 0x38/0x44 */
257#define DA7213_VOICE_HPF_CORNER_SHIFT 0
258#define DA7213_VOICE_HPF_CORNER_MAX 8
259#define DA7213_VOICE_EN_SHIFT 3
260#define DA7213_VOICE_EN_MAX 0x1
261#define DA7213_AUDIO_HPF_CORNER_SHIFT 4
262#define DA7213_AUDIO_HPF_CORNER_MAX 4
263#define DA7213_HPF_EN_SHIFT 7
264#define DA7213_HPF_EN_MAX 0x1
265
266/* DA7213_MIC_1/2_GAIN = 0x39/0x3A */
267#define DA7213_MIC_AMP_GAIN_SHIFT 0
268#define DA7213_MIC_AMP_GAIN_MAX 0x7
269
270/* DA7213_DAC_FILTERS5 = 0x40 */
271#define DA7213_DAC_SOFTMUTE_EN_SHIFT 7
272#define DA7213_DAC_SOFTMUTE_EN_MAX 0x1
273#define DA7213_DAC_SOFTMUTE_RATE_SHIFT 4
274#define DA7213_DAC_SOFTMUTE_RATE_MAX 7
275
276/* DA7213_DAC_FILTERS2/3/4 = 0x41/0x42/0x43 */
277#define DA7213_DAC_EQ_BAND_MAX 0xF
278
279/* DA7213_DAC_FILTERS2 = 0x41 */
280#define DA7213_DAC_EQ_BAND1_SHIFT 0
281#define DA7213_DAC_EQ_BAND2_SHIFT 4
282
283/* DA7213_DAC_FILTERS2 = 0x42 */
284#define DA7213_DAC_EQ_BAND3_SHIFT 0
285#define DA7213_DAC_EQ_BAND4_SHIFT 4
286
287/* DA7213_DAC_FILTERS4 = 0x43 */
288#define DA7213_DAC_EQ_BAND5_SHIFT 0
289#define DA7213_DAC_EQ_EN_SHIFT 7
290#define DA7213_DAC_EQ_EN_MAX 0x1
291
292/* DA7213_DAC_L/R_GAIN = 0x45/0x46 */
293#define DA7213_DAC_AMP_GAIN_SHIFT 0
294#define DA7213_DAC_AMP_GAIN_MAX 0x7F
295
296/* DA7213_HP_L/R_GAIN = 0x45/0x46 */
297#define DA7213_HP_AMP_GAIN_SHIFT 0
298#define DA7213_HP_AMP_GAIN_MAX 0x3F
299
300/* DA7213_CP_CTRL = 0x47 */
301#define DA7213_CP_EN_SHIFT 7
302
303/* DA7213_LINE_GAIN = 0x4A */
304#define DA7213_LINE_AMP_GAIN_SHIFT 0
305#define DA7213_LINE_AMP_GAIN_MAX 0x3F
306
307/* DA7213_MIXOUT_L_SELECT = 0x4B */
308#define DA7213_MIXOUT_L_MIX_SELECT_AUX_L_SHIFT 0
309#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_SHIFT 1
310#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_SHIFT 2
311#define DA7213_MIXOUT_L_MIX_SELECT_DAC_L_SHIFT 3
312#define DA7213_MIXOUT_L_MIX_SELECT_AUX_L_INVERTED_SHIFT 4
313#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_L_INVERTED_SHIFT 5
314#define DA7213_MIXOUT_L_MIX_SELECT_MIXIN_R_INVERTED_SHIFT 6
315#define DA7213_MIXOUT_L_MIX_SELECT_MAX 0x1
316
317/* DA7213_MIXOUT_R_SELECT = 0x4C */
318#define DA7213_MIXOUT_R_MIX_SELECT_AUX_R_SHIFT 0
319#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_SHIFT 1
320#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_SHIFT 2
321#define DA7213_MIXOUT_R_MIX_SELECT_DAC_R_SHIFT 3
322#define DA7213_MIXOUT_R_MIX_SELECT_AUX_R_INVERTED_SHIFT 4
323#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_R_INVERTED_SHIFT 5
324#define DA7213_MIXOUT_R_MIX_SELECT_MIXIN_L_INVERTED_SHIFT 6
325#define DA7213_MIXOUT_R_MIX_SELECT_MAX 0x1
326
327/*
328 * DA7213_AUX_L/R_CTRL = 0x60/0x61,
329 * DA7213_MIC_1/2_CTRL = 0x63/0x64,
330 * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
331 * DA7213_ADC_L/R_CTRL = 0x65/0x66,
332 * DA7213_DAC_L/R_CTRL = 0x69/0x6A,
333 * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
334 * DA7213_LINE_CTRL = 0x6D
335 */
336#define DA7213_MUTE_EN_SHIFT 6
337#define DA7213_MUTE_EN_MAX 0x1
338#define DA7213_MUTE_EN (0x1 << 6)
339
340/*
341 * DA7213_AUX_L/R_CTRL = 0x60/0x61,
342 * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
343 * DA7213_ADC_L/R_CTRL = 0x65/0x66,
344 * DA7213_DAC_L/R_CTRL = 0x69/0x6A,
345 * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
346 * DA7213_LINE_CTRL = 0x6D
347 */
348#define DA7213_GAIN_RAMP_EN_SHIFT 5
349#define DA7213_GAIN_RAMP_EN_MAX 0x1
350#define DA7213_GAIN_RAMP_EN (0x1 << 5)
351
352/*
353 * DA7213_AUX_L/R_CTRL = 0x60/0x61,
354 * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
355 * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
356 * DA7213_LINE_CTRL = 0x6D
357 */
358#define DA7213_ZC_EN_SHIFT 4
359#define DA7213_ZC_EN_MAX 0x1
360
361/*
362 * DA7213_AUX_L/R_CTRL = 0x60/0x61,
363 * DA7213_MIC_1/2_CTRL = 0x63/0x64,
364 * DA7213_MIXIN_L/R_CTRL = 0x65/0x66,
365 * DA7213_HP_L/R_CTRL = 0x6B/0x6C,
366 * DA7213_MIXOUT_L/R_CTRL = 0x6E/0x6F,
367 * DA7213_LINE_CTRL = 0x6D
368 */
369#define DA7213_AMP_EN_SHIFT 7
370
371/* DA7213_MIC_1/2_CTRL = 0x63/0x64 */
372#define DA7213_MIC_AMP_IN_SEL_SHIFT 2
373#define DA7213_MIC_AMP_IN_SEL_MAX 3
374
375/* DA7213_MICBIAS_CTRL = 0x62 */
376#define DA7213_MICBIAS1_LEVEL_SHIFT 0
377#define DA7213_MICBIAS1_LEVEL_MASK (0x3 << 0)
378#define DA7213_MICBIAS1_EN_SHIFT 3
379#define DA7213_MICBIAS2_LEVEL_SHIFT 4
380#define DA7213_MICBIAS2_LEVEL_MASK (0x3 << 4)
381#define DA7213_MICBIAS2_EN_SHIFT 7
382
383/* DA7213_MIXIN_L/R_CTRL = 0x65/0x66 */
384#define DA7213_MIXIN_MIX_EN (0x1 << 3)
385
386/* DA7213_ADC_L/R_CTRL = 0x67/0x68 */
387#define DA7213_ADC_EN_SHIFT 7
388#define DA7213_ADC_EN (0x1 << 7)
389
390/* DA7213_DAC_L/R_CTRL = 0x69/0x6A*/
391#define DA7213_DAC_EN_SHIFT 7
392
393/* DA7213_HP_L/R_CTRL = 0x6B/0x6C */
394#define DA7213_HP_AMP_OE (0x1 << 3)
395
396/* DA7213_LINE_CTRL = 0x6D */
397#define DA7213_LINE_AMP_OE (0x1 << 3)
398
399/* DA7213_MIXOUT_L/R_CTRL = 0x6E/0x6F */
400#define DA7213_MIXOUT_MIX_EN (0x1 << 3)
401
402/* DA7213_GAIN_RAMP_CTRL = 0x92 */
403#define DA7213_GAIN_RAMP_RATE_SHIFT 0
404#define DA7213_GAIN_RAMP_RATE_MAX 4
405
406/* DA7213_MIC_CONFIG = 0x93 */
407#define DA7213_DMIC_DATA_SEL_SHIFT 0
408#define DA7213_DMIC_DATA_SEL_MASK (0x1 << 0)
409#define DA7213_DMIC_SAMPLEPHASE_SHIFT 1
410#define DA7213_DMIC_SAMPLEPHASE_MASK (0x1 << 1)
411#define DA7213_DMIC_CLK_RATE_SHIFT 2
412#define DA7213_DMIC_CLK_RATE_MASK (0x1 << 2)
413
414/* DA7213_DIG_CTRL = 0x99 */
415#define DA7213_DAC_L_INV_SHIFT 3
416#define DA7213_DAC_R_INV_SHIFT 7
417#define DA7213_DAC_INV_MAX 0x1
418
419/* DA7213_ALC_CTRL2 = 0x9A */
420#define DA7213_ALC_ATTACK_SHIFT 0
421#define DA7213_ALC_ATTACK_MAX 13
422#define DA7213_ALC_RELEASE_SHIFT 4
423#define DA7213_ALC_RELEASE_MAX 11
424
425/* DA7213_ALC_CTRL3 = 0x9B */
426#define DA7213_ALC_HOLD_SHIFT 0
427#define DA7213_ALC_HOLD_MAX 16
428#define DA7213_ALC_INTEG_ATTACK_SHIFT 4
429#define DA7213_ALC_INTEG_RELEASE_SHIFT 6
430#define DA7213_ALC_INTEG_MAX 4
431
432/*
433 * DA7213_ALC_NOISE = 0x9C,
434 * DA7213_ALC_TARGET_MIN/MAX = 0x9D/0x9E
435 */
436#define DA7213_ALC_THRESHOLD_SHIFT 0
437#define DA7213_ALC_THRESHOLD_MAX 0x3F
438
439/* DA7213_ALC_GAIN_LIMITS = 0x9F */
440#define DA7213_ALC_ATTEN_MAX_SHIFT 0
441#define DA7213_ALC_GAIN_MAX_SHIFT 4
442#define DA7213_ALC_ATTEN_GAIN_MAX_MAX 0xF
443
444/* DA7213_ALC_ANA_GAIN_LIMITS = 0xA0 */
445#define DA7213_ALC_ANA_GAIN_MIN_SHIFT 0
446#define DA7213_ALC_ANA_GAIN_MAX_SHIFT 4
447#define DA7213_ALC_ANA_GAIN_MAX 0x7
448
449/* DA7213_ALC_ANTICLIP_CTRL = 0xA1 */
450#define DA7213_ALC_ANTICLIP_EN_SHIFT 7
451#define DA7213_ALC_ANTICLIP_EN_MAX 0x1
452
453/* DA7213_ALC_ANTICLIP_LEVEL = 0xA2 */
454#define DA7213_ALC_ANTICLIP_LEVEL_SHIFT 0
455#define DA7213_ALC_ANTICLIP_LEVEL_MAX 0x7F
456
457/* DA7213_ALC_CIC_OP_LVL_CTRL = 0xAD */
458#define DA7213_ALC_DATA_MIDDLE (0x2 << 0)
459#define DA7213_ALC_DATA_TOP (0x3 << 0)
460#define DA7213_ALC_CIC_OP_CHANNEL_LEFT (0x0 << 7)
461#define DA7213_ALC_CIC_OP_CHANNEL_RIGHT (0x1 << 7)
462
463/* DA7213_DAC_NG_SETUP_TIME = 0xAF */
464#define DA7213_DAC_NG_SETUP_TIME_SHIFT 0
465#define DA7213_DAC_NG_SETUP_TIME_MAX 4
466#define DA7213_DAC_NG_RAMPUP_RATE_SHIFT 2
467#define DA7213_DAC_NG_RAMPDN_RATE_SHIFT 3
468#define DA7213_DAC_NG_RAMP_RATE_MAX 2
469
470/* DA7213_DAC_NG_OFF/ON_THRESH = 0xB0/0xB1 */
471#define DA7213_DAC_NG_THRESHOLD_SHIFT 0
472#define DA7213_DAC_NG_THRESHOLD_MAX 0x7
473
474/* DA7213_DAC_NG_CTRL = 0xB2 */
475#define DA7213_DAC_NG_EN_SHIFT 7
476#define DA7213_DAC_NG_EN_MAX 0x1
477
478
479/*
480 * General defines
481 */
482
483/* Register inversion */
484#define DA7213_NO_INVERT 0
485#define DA7213_INVERT 1
486
487/* Byte related defines */
488#define DA7213_BYTE_SHIFT 8
489#define DA7213_BYTE_MASK 0xFF
490
491/* ALC related */
492#define DA7213_ALC_OFFSET_15_8 0x00FF00
493#define DA7213_ALC_OFFSET_19_16 0x0F0000
494#define DA7213_ALC_AVG_ITERATIONS 5
495
496/* PLL related */
497#define DA7213_SYSCLK_MCLK 0
498#define DA7213_SYSCLK_PLL 1
499#define DA7213_PLL_FREQ_OUT_90316800 90316800
500#define DA7213_PLL_FREQ_OUT_98304000 98304000
501#define DA7213_PLL_FREQ_OUT_94310400 94310400
502#define DA7213_PLL_INDIV_5_10_MHZ_VAL 2
503#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4
504#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
505#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
506
507enum clk_src {
508 DA7213_CLKSRC_MCLK
509};
510
511/* Codec private data */
512struct da7213_priv {
513 struct regmap *regmap;
514 unsigned int mclk_rate;
515 bool master;
516 bool mclk_squarer_en;
517 bool srm_en;
518 bool alc_calib_auto;
519 bool alc_en;
520 struct da7213_platform_data *pdata;
521};
522
523#endif /* _DA7213_H */
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index d991529e1aff..5f607b35b68b 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -361,9 +361,9 @@ static int jz4740_codec_probe(struct platform_device *pdev)
361 return -ENOMEM; 361 return -ENOMEM;
362 362
363 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 363 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
364 base = devm_request_and_ioremap(&pdev->dev, mem); 364 base = devm_ioremap_resource(&pdev->dev, mem);
365 if (!base) 365 if (IS_ERR(base))
366 return -EBUSY; 366 return PTR_ERR(base);
367 367
368 jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base, 368 jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
369 &jz4740_codec_regmap_config); 369 &jz4740_codec_regmap_config);
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index c9772ca3da4f..fc176044994d 100644..100755
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -1,562 +1,2381 @@
1/* 1/*
2 * max98090.c -- MAX98090 ALSA SoC Audio driver 2 * max98090.c -- MAX98090 ALSA SoC Audio driver
3 * based on Rev0p8 datasheet
4 * 3 *
5 * Copyright (C) 2012 Renesas Solutions Corp. 4 * Copyright 2011-2012 Maxim Integrated Products
6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7 *
8 * Based on
9 *
10 * max98095.c
11 * Copyright 2011 Maxim Integrated Products
12 *
13 * https://github.com/hardkernel/linux/commit/\
14 * 3417d7166b17113b3b33b0a337c74d1c7cc313df#sound/soc/codecs/max98090.c
15 * Copyright 2011 Maxim Integrated Products
16 * 5 *
17 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
20 */ 9 */
21 10
11#include <linux/delay.h>
22#include <linux/i2c.h> 12#include <linux/i2c.h>
23#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pm.h>
15#include <linux/pm_runtime.h>
24#include <linux/regmap.h> 16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <sound/jack.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
25#include <sound/soc.h> 21#include <sound/soc.h>
26#include <sound/tlv.h> 22#include <sound/tlv.h>
23#include <sound/max98090.h>
24#include "max98090.h"
25
26#include <linux/version.h>
27
28#define DEBUG
29#define EXTMIC_METHOD
30#define EXTMIC_METHOD_TEST
31
32/* Allows for sparsely populated register maps */
33static struct reg_default max98090_reg[] = {
34 { 0x00, 0x00 }, /* 00 Software Reset */
35 { 0x03, 0x04 }, /* 03 Interrupt Masks */
36 { 0x04, 0x00 }, /* 04 System Clock Quick */
37 { 0x05, 0x00 }, /* 05 Sample Rate Quick */
38 { 0x06, 0x00 }, /* 06 DAI Interface Quick */
39 { 0x07, 0x00 }, /* 07 DAC Path Quick */
40 { 0x08, 0x00 }, /* 08 Mic/Direct to ADC Quick */
41 { 0x09, 0x00 }, /* 09 Line to ADC Quick */
42 { 0x0A, 0x00 }, /* 0A Analog Mic Loop Quick */
43 { 0x0B, 0x00 }, /* 0B Analog Line Loop Quick */
44 { 0x0C, 0x00 }, /* 0C Reserved */
45 { 0x0D, 0x00 }, /* 0D Input Config */
46 { 0x0E, 0x1B }, /* 0E Line Input Level */
47 { 0x0F, 0x00 }, /* 0F Line Config */
48
49 { 0x10, 0x14 }, /* 10 Mic1 Input Level */
50 { 0x11, 0x14 }, /* 11 Mic2 Input Level */
51 { 0x12, 0x00 }, /* 12 Mic Bias Voltage */
52 { 0x13, 0x00 }, /* 13 Digital Mic Config */
53 { 0x14, 0x00 }, /* 14 Digital Mic Mode */
54 { 0x15, 0x00 }, /* 15 Left ADC Mixer */
55 { 0x16, 0x00 }, /* 16 Right ADC Mixer */
56 { 0x17, 0x03 }, /* 17 Left ADC Level */
57 { 0x18, 0x03 }, /* 18 Right ADC Level */
58 { 0x19, 0x00 }, /* 19 ADC Biquad Level */
59 { 0x1A, 0x00 }, /* 1A ADC Sidetone */
60 { 0x1B, 0x00 }, /* 1B System Clock */
61 { 0x1C, 0x00 }, /* 1C Clock Mode */
62 { 0x1D, 0x00 }, /* 1D Any Clock 1 */
63 { 0x1E, 0x00 }, /* 1E Any Clock 2 */
64 { 0x1F, 0x00 }, /* 1F Any Clock 3 */
65
66 { 0x20, 0x00 }, /* 20 Any Clock 4 */
67 { 0x21, 0x00 }, /* 21 Master Mode */
68 { 0x22, 0x00 }, /* 22 Interface Format */
69 { 0x23, 0x00 }, /* 23 TDM Format 1*/
70 { 0x24, 0x00 }, /* 24 TDM Format 2*/
71 { 0x25, 0x00 }, /* 25 I/O Configuration */
72 { 0x26, 0x80 }, /* 26 Filter Config */
73 { 0x27, 0x00 }, /* 27 DAI Playback Level */
74 { 0x28, 0x00 }, /* 28 EQ Playback Level */
75 { 0x29, 0x00 }, /* 29 Left HP Mixer */
76 { 0x2A, 0x00 }, /* 2A Right HP Mixer */
77 { 0x2B, 0x00 }, /* 2B HP Control */
78 { 0x2C, 0x1A }, /* 2C Left HP Volume */
79 { 0x2D, 0x1A }, /* 2D Right HP Volume */
80 { 0x2E, 0x00 }, /* 2E Left Spk Mixer */
81 { 0x2F, 0x00 }, /* 2F Right Spk Mixer */
82
83 { 0x30, 0x00 }, /* 30 Spk Control */
84 { 0x31, 0x2C }, /* 31 Left Spk Volume */
85 { 0x32, 0x2C }, /* 32 Right Spk Volume */
86 { 0x33, 0x00 }, /* 33 ALC Timing */
87 { 0x34, 0x00 }, /* 34 ALC Compressor */
88 { 0x35, 0x00 }, /* 35 ALC Expander */
89 { 0x36, 0x00 }, /* 36 ALC Gain */
90 { 0x37, 0x00 }, /* 37 Rcv/Line OutL Mixer */
91 { 0x38, 0x00 }, /* 38 Rcv/Line OutL Control */
92 { 0x39, 0x15 }, /* 39 Rcv/Line OutL Volume */
93 { 0x3A, 0x00 }, /* 3A Line OutR Mixer */
94 { 0x3B, 0x00 }, /* 3B Line OutR Control */
95 { 0x3C, 0x15 }, /* 3C Line OutR Volume */
96 { 0x3D, 0x00 }, /* 3D Jack Detect */
97 { 0x3E, 0x00 }, /* 3E Input Enable */
98 { 0x3F, 0x00 }, /* 3F Output Enable */
99
100 { 0x40, 0x00 }, /* 40 Level Control */
101 { 0x41, 0x00 }, /* 41 DSP Filter Enable */
102 { 0x42, 0x00 }, /* 42 Bias Control */
103 { 0x43, 0x00 }, /* 43 DAC Control */
104 { 0x44, 0x06 }, /* 44 ADC Control */
105 { 0x45, 0x00 }, /* 45 Device Shutdown */
106 { 0x46, 0x00 }, /* 46 Equalizer Band 1 Coefficient B0 */
107 { 0x47, 0x00 }, /* 47 Equalizer Band 1 Coefficient B0 */
108 { 0x48, 0x00 }, /* 48 Equalizer Band 1 Coefficient B0 */
109 { 0x49, 0x00 }, /* 49 Equalizer Band 1 Coefficient B1 */
110 { 0x4A, 0x00 }, /* 4A Equalizer Band 1 Coefficient B1 */
111 { 0x4B, 0x00 }, /* 4B Equalizer Band 1 Coefficient B1 */
112 { 0x4C, 0x00 }, /* 4C Equalizer Band 1 Coefficient B2 */
113 { 0x4D, 0x00 }, /* 4D Equalizer Band 1 Coefficient B2 */
114 { 0x4E, 0x00 }, /* 4E Equalizer Band 1 Coefficient B2 */
115 { 0x4F, 0x00 }, /* 4F Equalizer Band 1 Coefficient A1 */
116
117 { 0x50, 0x00 }, /* 50 Equalizer Band 1 Coefficient A1 */
118 { 0x51, 0x00 }, /* 51 Equalizer Band 1 Coefficient A1 */
119 { 0x52, 0x00 }, /* 52 Equalizer Band 1 Coefficient A2 */
120 { 0x53, 0x00 }, /* 53 Equalizer Band 1 Coefficient A2 */
121 { 0x54, 0x00 }, /* 54 Equalizer Band 1 Coefficient A2 */
122 { 0x55, 0x00 }, /* 55 Equalizer Band 2 Coefficient B0 */
123 { 0x56, 0x00 }, /* 56 Equalizer Band 2 Coefficient B0 */
124 { 0x57, 0x00 }, /* 57 Equalizer Band 2 Coefficient B0 */
125 { 0x58, 0x00 }, /* 58 Equalizer Band 2 Coefficient B1 */
126 { 0x59, 0x00 }, /* 59 Equalizer Band 2 Coefficient B1 */
127 { 0x5A, 0x00 }, /* 5A Equalizer Band 2 Coefficient B1 */
128 { 0x5B, 0x00 }, /* 5B Equalizer Band 2 Coefficient B2 */
129 { 0x5C, 0x00 }, /* 5C Equalizer Band 2 Coefficient B2 */
130 { 0x5D, 0x00 }, /* 5D Equalizer Band 2 Coefficient B2 */
131 { 0x5E, 0x00 }, /* 5E Equalizer Band 2 Coefficient A1 */
132 { 0x5F, 0x00 }, /* 5F Equalizer Band 2 Coefficient A1 */
133
134 { 0x60, 0x00 }, /* 60 Equalizer Band 2 Coefficient A1 */
135 { 0x61, 0x00 }, /* 61 Equalizer Band 2 Coefficient A2 */
136 { 0x62, 0x00 }, /* 62 Equalizer Band 2 Coefficient A2 */
137 { 0x63, 0x00 }, /* 63 Equalizer Band 2 Coefficient A2 */
138 { 0x64, 0x00 }, /* 64 Equalizer Band 3 Coefficient B0 */
139 { 0x65, 0x00 }, /* 65 Equalizer Band 3 Coefficient B0 */
140 { 0x66, 0x00 }, /* 66 Equalizer Band 3 Coefficient B0 */
141 { 0x67, 0x00 }, /* 67 Equalizer Band 3 Coefficient B1 */
142 { 0x68, 0x00 }, /* 68 Equalizer Band 3 Coefficient B1 */
143 { 0x69, 0x00 }, /* 69 Equalizer Band 3 Coefficient B1 */
144 { 0x6A, 0x00 }, /* 6A Equalizer Band 3 Coefficient B2 */
145 { 0x6B, 0x00 }, /* 6B Equalizer Band 3 Coefficient B2 */
146 { 0x6C, 0x00 }, /* 6C Equalizer Band 3 Coefficient B2 */
147 { 0x6D, 0x00 }, /* 6D Equalizer Band 3 Coefficient A1 */
148 { 0x6E, 0x00 }, /* 6E Equalizer Band 3 Coefficient A1 */
149 { 0x6F, 0x00 }, /* 6F Equalizer Band 3 Coefficient A1 */
150
151 { 0x70, 0x00 }, /* 70 Equalizer Band 3 Coefficient A2 */
152 { 0x71, 0x00 }, /* 71 Equalizer Band 3 Coefficient A2 */
153 { 0x72, 0x00 }, /* 72 Equalizer Band 3 Coefficient A2 */
154 { 0x73, 0x00 }, /* 73 Equalizer Band 4 Coefficient B0 */
155 { 0x74, 0x00 }, /* 74 Equalizer Band 4 Coefficient B0 */
156 { 0x75, 0x00 }, /* 75 Equalizer Band 4 Coefficient B0 */
157 { 0x76, 0x00 }, /* 76 Equalizer Band 4 Coefficient B1 */
158 { 0x77, 0x00 }, /* 77 Equalizer Band 4 Coefficient B1 */
159 { 0x78, 0x00 }, /* 78 Equalizer Band 4 Coefficient B1 */
160 { 0x79, 0x00 }, /* 79 Equalizer Band 4 Coefficient B2 */
161 { 0x7A, 0x00 }, /* 7A Equalizer Band 4 Coefficient B2 */
162 { 0x7B, 0x00 }, /* 7B Equalizer Band 4 Coefficient B2 */
163 { 0x7C, 0x00 }, /* 7C Equalizer Band 4 Coefficient A1 */
164 { 0x7D, 0x00 }, /* 7D Equalizer Band 4 Coefficient A1 */
165 { 0x7E, 0x00 }, /* 7E Equalizer Band 4 Coefficient A1 */
166 { 0x7F, 0x00 }, /* 7F Equalizer Band 4 Coefficient A2 */
167
168 { 0x80, 0x00 }, /* 80 Equalizer Band 4 Coefficient A2 */
169 { 0x81, 0x00 }, /* 81 Equalizer Band 4 Coefficient A2 */
170 { 0x82, 0x00 }, /* 82 Equalizer Band 5 Coefficient B0 */
171 { 0x83, 0x00 }, /* 83 Equalizer Band 5 Coefficient B0 */
172 { 0x84, 0x00 }, /* 84 Equalizer Band 5 Coefficient B0 */
173 { 0x85, 0x00 }, /* 85 Equalizer Band 5 Coefficient B1 */
174 { 0x86, 0x00 }, /* 86 Equalizer Band 5 Coefficient B1 */
175 { 0x87, 0x00 }, /* 87 Equalizer Band 5 Coefficient B1 */
176 { 0x88, 0x00 }, /* 88 Equalizer Band 5 Coefficient B2 */
177 { 0x89, 0x00 }, /* 89 Equalizer Band 5 Coefficient B2 */
178 { 0x8A, 0x00 }, /* 8A Equalizer Band 5 Coefficient B2 */
179 { 0x8B, 0x00 }, /* 8B Equalizer Band 5 Coefficient A1 */
180 { 0x8C, 0x00 }, /* 8C Equalizer Band 5 Coefficient A1 */
181 { 0x8D, 0x00 }, /* 8D Equalizer Band 5 Coefficient A1 */
182 { 0x8E, 0x00 }, /* 8E Equalizer Band 5 Coefficient A2 */
183 { 0x8F, 0x00 }, /* 8F Equalizer Band 5 Coefficient A2 */
184
185 { 0x90, 0x00 }, /* 90 Equalizer Band 5 Coefficient A2 */
186 { 0x91, 0x00 }, /* 91 Equalizer Band 6 Coefficient B0 */
187 { 0x92, 0x00 }, /* 92 Equalizer Band 6 Coefficient B0 */
188 { 0x93, 0x00 }, /* 93 Equalizer Band 6 Coefficient B0 */
189 { 0x94, 0x00 }, /* 94 Equalizer Band 6 Coefficient B1 */
190 { 0x95, 0x00 }, /* 95 Equalizer Band 6 Coefficient B1 */
191 { 0x96, 0x00 }, /* 96 Equalizer Band 6 Coefficient B1 */
192 { 0x97, 0x00 }, /* 97 Equalizer Band 6 Coefficient B2 */
193 { 0x98, 0x00 }, /* 98 Equalizer Band 6 Coefficient B2 */
194 { 0x99, 0x00 }, /* 99 Equalizer Band 6 Coefficient B2 */
195 { 0x9A, 0x00 }, /* 9A Equalizer Band 6 Coefficient A1 */
196 { 0x9B, 0x00 }, /* 9B Equalizer Band 6 Coefficient A1 */
197 { 0x9C, 0x00 }, /* 9C Equalizer Band 6 Coefficient A1 */
198 { 0x9D, 0x00 }, /* 9D Equalizer Band 6 Coefficient A2 */
199 { 0x9E, 0x00 }, /* 9E Equalizer Band 6 Coefficient A2 */
200 { 0x9F, 0x00 }, /* 9F Equalizer Band 6 Coefficient A2 */
201
202 { 0xA0, 0x00 }, /* A0 Equalizer Band 7 Coefficient B0 */
203 { 0xA1, 0x00 }, /* A1 Equalizer Band 7 Coefficient B0 */
204 { 0xA2, 0x00 }, /* A2 Equalizer Band 7 Coefficient B0 */
205 { 0xA3, 0x00 }, /* A3 Equalizer Band 7 Coefficient B1 */
206 { 0xA4, 0x00 }, /* A4 Equalizer Band 7 Coefficient B1 */
207 { 0xA5, 0x00 }, /* A5 Equalizer Band 7 Coefficient B1 */
208 { 0xA6, 0x00 }, /* A6 Equalizer Band 7 Coefficient B2 */
209 { 0xA7, 0x00 }, /* A7 Equalizer Band 7 Coefficient B2 */
210 { 0xA8, 0x00 }, /* A8 Equalizer Band 7 Coefficient B2 */
211 { 0xA9, 0x00 }, /* A9 Equalizer Band 7 Coefficient A1 */
212 { 0xAA, 0x00 }, /* AA Equalizer Band 7 Coefficient A1 */
213 { 0xAB, 0x00 }, /* AB Equalizer Band 7 Coefficient A1 */
214 { 0xAC, 0x00 }, /* AC Equalizer Band 7 Coefficient A2 */
215 { 0xAD, 0x00 }, /* AD Equalizer Band 7 Coefficient A2 */
216 { 0xAE, 0x00 }, /* AE Equalizer Band 7 Coefficient A2 */
217 { 0xAF, 0x00 }, /* AF ADC Biquad Coefficient B0 */
218
219 { 0xB0, 0x00 }, /* B0 ADC Biquad Coefficient B0 */
220 { 0xB1, 0x00 }, /* B1 ADC Biquad Coefficient B0 */
221 { 0xB2, 0x00 }, /* B2 ADC Biquad Coefficient B1 */
222 { 0xB3, 0x00 }, /* B3 ADC Biquad Coefficient B1 */
223 { 0xB4, 0x00 }, /* B4 ADC Biquad Coefficient B1 */
224 { 0xB5, 0x00 }, /* B5 ADC Biquad Coefficient B2 */
225 { 0xB6, 0x00 }, /* B6 ADC Biquad Coefficient B2 */
226 { 0xB7, 0x00 }, /* B7 ADC Biquad Coefficient B2 */
227 { 0xB8, 0x00 }, /* B8 ADC Biquad Coefficient A1 */
228 { 0xB9, 0x00 }, /* B9 ADC Biquad Coefficient A1 */
229 { 0xBA, 0x00 }, /* BA ADC Biquad Coefficient A1 */
230 { 0xBB, 0x00 }, /* BB ADC Biquad Coefficient A2 */
231 { 0xBC, 0x00 }, /* BC ADC Biquad Coefficient A2 */
232 { 0xBD, 0x00 }, /* BD ADC Biquad Coefficient A2 */
233 { 0xBE, 0x00 }, /* BE Digital Mic 3 Volume */
234 { 0xBF, 0x00 }, /* BF Digital Mic 4 Volume */
235
236 { 0xC0, 0x00 }, /* C0 Digital Mic 34 Biquad Pre Atten */
237 { 0xC1, 0x00 }, /* C1 Record TDM Slot */
238 { 0xC2, 0x00 }, /* C2 Sample Rate */
239 { 0xC3, 0x00 }, /* C3 Digital Mic 34 Biquad Coefficient C3 */
240 { 0xC4, 0x00 }, /* C4 Digital Mic 34 Biquad Coefficient C4 */
241 { 0xC5, 0x00 }, /* C5 Digital Mic 34 Biquad Coefficient C5 */
242 { 0xC6, 0x00 }, /* C6 Digital Mic 34 Biquad Coefficient C6 */
243 { 0xC7, 0x00 }, /* C7 Digital Mic 34 Biquad Coefficient C7 */
244 { 0xC8, 0x00 }, /* C8 Digital Mic 34 Biquad Coefficient C8 */
245 { 0xC9, 0x00 }, /* C9 Digital Mic 34 Biquad Coefficient C9 */
246 { 0xCA, 0x00 }, /* CA Digital Mic 34 Biquad Coefficient CA */
247 { 0xCB, 0x00 }, /* CB Digital Mic 34 Biquad Coefficient CB */
248 { 0xCC, 0x00 }, /* CC Digital Mic 34 Biquad Coefficient CC */
249 { 0xCD, 0x00 }, /* CD Digital Mic 34 Biquad Coefficient CD */
250 { 0xCE, 0x00 }, /* CE Digital Mic 34 Biquad Coefficient CE */
251 { 0xCF, 0x00 }, /* CF Digital Mic 34 Biquad Coefficient CF */
252
253 { 0xD0, 0x00 }, /* D0 Digital Mic 34 Biquad Coefficient D0 */
254 { 0xD1, 0x00 }, /* D1 Digital Mic 34 Biquad Coefficient D1 */
255};
27 256
28/* 257static bool max98090_volatile_register(struct device *dev, unsigned int reg)
29 * 258{
30 * MAX98090 Registers Definition 259 switch (reg) {
31 * 260 case M98090_REG_DEVICE_STATUS:
32 */ 261 case M98090_REG_JACK_STATUS:
262 case M98090_REG_REVISION_ID:
263 return true;
264 default:
265 return false;
266 }
267}
33 268
34/* RESET / STATUS / INTERRUPT REGISTERS */ 269static bool max98090_readable_register(struct device *dev, unsigned int reg)
35#define MAX98090_0x00_SW_RESET 0x00 270{
36#define MAX98090_0x01_INT_STS 0x01 271 switch (reg) {
37#define MAX98090_0x02_JACK_STS 0x02 272 case M98090_REG_DEVICE_STATUS:
38#define MAX98090_0x03_INT_MASK 0x03 273 case M98090_REG_JACK_STATUS:
39 274 case M98090_REG_INTERRUPT_S:
40/* QUICK SETUP REGISTERS */ 275 case M98090_REG_RESERVED:
41#define MAX98090_0x04_SYS_CLK 0x04 276 case M98090_REG_LINE_INPUT_CONFIG:
42#define MAX98090_0x05_SAMPLE_RATE 0x05 277 case M98090_REG_LINE_INPUT_LEVEL:
43#define MAX98090_0x06_DAI_IF 0x06 278 case M98090_REG_INPUT_MODE:
44#define MAX98090_0x07_DAC_PATH 0x07 279 case M98090_REG_MIC1_INPUT_LEVEL:
45#define MAX98090_0x08_MIC_TO_ADC 0x08 280 case M98090_REG_MIC2_INPUT_LEVEL:
46#define MAX98090_0x09_LINE_TO_ADC 0x09 281 case M98090_REG_MIC_BIAS_VOLTAGE:
47#define MAX98090_0x0A_ANALOG_MIC_LOOP 0x0A 282 case M98090_REG_DIGITAL_MIC_ENABLE:
48#define MAX98090_0x0B_ANALOG_LINE_LOOP 0x0B 283 case M98090_REG_DIGITAL_MIC_CONFIG:
49 284 case M98090_REG_LEFT_ADC_MIXER:
50/* ANALOG INPUT CONFIGURATION REGISTERS */ 285 case M98090_REG_RIGHT_ADC_MIXER:
51#define MAX98090_0x0D_INPUT_CONFIG 0x0D 286 case M98090_REG_LEFT_ADC_LEVEL:
52#define MAX98090_0x0E_LINE_IN_LVL 0x0E 287 case M98090_REG_RIGHT_ADC_LEVEL:
53#define MAX98090_0x0F_LINI_IN_CFG 0x0F 288 case M98090_REG_ADC_BIQUAD_LEVEL:
54#define MAX98090_0x10_MIC1_IN_LVL 0x10 289 case M98090_REG_ADC_SIDETONE:
55#define MAX98090_0x11_MIC2_IN_LVL 0x11 290 case M98090_REG_SYSTEM_CLOCK:
56 291 case M98090_REG_CLOCK_MODE:
57/* MICROPHONE CONFIGURATION REGISTERS */ 292 case M98090_REG_CLOCK_RATIO_NI_MSB:
58#define MAX98090_0x12_MIC_BIAS_VOL 0x12 293 case M98090_REG_CLOCK_RATIO_NI_LSB:
59#define MAX98090_0x13_DIGITAL_MIC_CFG 0x13 294 case M98090_REG_CLOCK_RATIO_MI_MSB:
60#define MAX98090_0x14_DIGITAL_MIC_MODE 0x14 295 case M98090_REG_CLOCK_RATIO_MI_LSB:
61 296 case M98090_REG_MASTER_MODE:
62/* ADC PATH AND CONFIGURATION REGISTERS */ 297 case M98090_REG_INTERFACE_FORMAT:
63#define MAX98090_0x15_L_ADC_MIX 0x15 298 case M98090_REG_TDM_CONTROL:
64#define MAX98090_0x16_R_ADC_MIX 0x16 299 case M98090_REG_TDM_FORMAT:
65#define MAX98090_0x17_L_ADC_LVL 0x17 300 case M98090_REG_IO_CONFIGURATION:
66#define MAX98090_0x18_R_ADC_LVL 0x18 301 case M98090_REG_FILTER_CONFIG:
67#define MAX98090_0x19_ADC_BIQUAD_LVL 0x19 302 case M98090_REG_DAI_PLAYBACK_LEVEL:
68#define MAX98090_0x1A_ADC_SIDETONE 0x1A 303 case M98090_REG_DAI_PLAYBACK_LEVEL_EQ:
69 304 case M98090_REG_LEFT_HP_MIXER:
70/* CLOCK CONFIGURATION REGISTERS */ 305 case M98090_REG_RIGHT_HP_MIXER:
71#define MAX98090_0x1B_SYS_CLK 0x1B 306 case M98090_REG_HP_CONTROL:
72#define MAX98090_0x1C_CLK_MODE 0x1C 307 case M98090_REG_LEFT_HP_VOLUME:
73#define MAX98090_0x1D_ANY_CLK1 0x1D 308 case M98090_REG_RIGHT_HP_VOLUME:
74#define MAX98090_0x1E_ANY_CLK2 0x1E 309 case M98090_REG_LEFT_SPK_MIXER:
75#define MAX98090_0x1F_ANY_CLK3 0x1F 310 case M98090_REG_RIGHT_SPK_MIXER:
76#define MAX98090_0x20_ANY_CLK4 0x20 311 case M98090_REG_SPK_CONTROL:
77#define MAX98090_0x21_MASTER_MODE 0x21 312 case M98090_REG_LEFT_SPK_VOLUME:
78 313 case M98090_REG_RIGHT_SPK_VOLUME:
79/* INTERFACE CONTROL REGISTERS */ 314 case M98090_REG_DRC_TIMING:
80#define MAX98090_0x22_DAI_IF_FMT 0x22 315 case M98090_REG_DRC_COMPRESSOR:
81#define MAX98090_0x23_DAI_TDM_FMT1 0x23 316 case M98090_REG_DRC_EXPANDER:
82#define MAX98090_0x24_DAI_TDM_FMT2 0x24 317 case M98090_REG_DRC_GAIN:
83#define MAX98090_0x25_DAI_IO_CFG 0x25 318 case M98090_REG_RCV_LOUTL_MIXER:
84#define MAX98090_0x26_FILTER_CFG 0x26 319 case M98090_REG_RCV_LOUTL_CONTROL:
85#define MAX98090_0x27_DAI_PLAYBACK_LVL 0x27 320 case M98090_REG_RCV_LOUTL_VOLUME:
86#define MAX98090_0x28_EQ_PLAYBACK_LVL 0x28 321 case M98090_REG_LOUTR_MIXER:
87 322 case M98090_REG_LOUTR_CONTROL:
88/* HEADPHONE CONTROL REGISTERS */ 323 case M98090_REG_LOUTR_VOLUME:
89#define MAX98090_0x29_L_HP_MIX 0x29 324 case M98090_REG_JACK_DETECT:
90#define MAX98090_0x2A_R_HP_MIX 0x2A 325 case M98090_REG_INPUT_ENABLE:
91#define MAX98090_0x2B_HP_CTR 0x2B 326 case M98090_REG_OUTPUT_ENABLE:
92#define MAX98090_0x2C_L_HP_VOL 0x2C 327 case M98090_REG_LEVEL_CONTROL:
93#define MAX98090_0x2D_R_HP_VOL 0x2D 328 case M98090_REG_DSP_FILTER_ENABLE:
94 329 case M98090_REG_BIAS_CONTROL:
95/* SPEAKER CONFIGURATION REGISTERS */ 330 case M98090_REG_DAC_CONTROL:
96#define MAX98090_0x2E_L_SPK_MIX 0x2E 331 case M98090_REG_ADC_CONTROL:
97#define MAX98090_0x2F_R_SPK_MIX 0x2F 332 case M98090_REG_DEVICE_SHUTDOWN:
98#define MAX98090_0x30_SPK_CTR 0x30 333 case M98090_REG_EQUALIZER_BASE ... M98090_REG_EQUALIZER_BASE + 0x68:
99#define MAX98090_0x31_L_SPK_VOL 0x31 334 case M98090_REG_RECORD_BIQUAD_BASE ... M98090_REG_RECORD_BIQUAD_BASE + 0x0E:
100#define MAX98090_0x32_R_SPK_VOL 0x32 335 case M98090_REG_DMIC3_VOLUME:
101 336 case M98090_REG_DMIC4_VOLUME:
102/* ALC CONFIGURATION REGISTERS */ 337 case M98090_REG_DMIC34_BQ_PREATTEN:
103#define MAX98090_0x33_ALC_TIMING 0x33 338 case M98090_REG_RECORD_TDM_SLOT:
104#define MAX98090_0x34_ALC_COMPRESSOR 0x34 339 case M98090_REG_SAMPLE_RATE:
105#define MAX98090_0x35_ALC_EXPANDER 0x35 340 case M98090_REG_DMIC34_BIQUAD_BASE ... M98090_REG_DMIC34_BIQUAD_BASE + 0x0E:
106#define MAX98090_0x36_ALC_GAIN 0x36 341 return true;
107 342 default:
108/* RECEIVER AND LINE_OUTPUT REGISTERS */ 343 return false;
109#define MAX98090_0x37_RCV_LOUT_L_MIX 0x37 344 }
110#define MAX98090_0x38_RCV_LOUT_L_CNTL 0x38 345}
111#define MAX98090_0x39_RCV_LOUT_L_VOL 0x39
112#define MAX98090_0x3A_LOUT_R_MIX 0x3A
113#define MAX98090_0x3B_LOUT_R_CNTL 0x3B
114#define MAX98090_0x3C_LOUT_R_VOL 0x3C
115
116/* JACK DETECT AND ENABLE REGISTERS */
117#define MAX98090_0x3D_JACK_DETECT 0x3D
118#define MAX98090_0x3E_IN_ENABLE 0x3E
119#define MAX98090_0x3F_OUT_ENABLE 0x3F
120#define MAX98090_0x40_LVL_CTR 0x40
121#define MAX98090_0x41_DSP_FILTER_ENABLE 0x41
122
123/* BIAS AND POWER MODE CONFIGURATION REGISTERS */
124#define MAX98090_0x42_BIAS_CTR 0x42
125#define MAX98090_0x43_DAC_CTR 0x43
126#define MAX98090_0x44_ADC_CTR 0x44
127#define MAX98090_0x45_DEV_SHUTDOWN 0x45
128
129/* REVISION ID REGISTER */
130#define MAX98090_0xFF_REV_ID 0xFF
131
132#define MAX98090_REG_MAX_CACHED 0x45
133#define MAX98090_REG_END 0xFF
134 346
135/* 347static int max98090_reset(struct max98090_priv *max98090)
136 * 348{
137 * MAX98090 Registers Bit Fields 349 int ret;
138 *
139 */
140 350
141/* MAX98090_0x06_DAI_IF */ 351 /* Reset the codec by writing to this write-only reset register */
142#define MAX98090_DAI_IF_MASK 0x3F 352 ret = regmap_write(max98090->regmap, M98090_REG_SOFTWARE_RESET,
143#define MAX98090_RJ_M (1 << 5) 353 M98090_SWRESET_MASK);
144#define MAX98090_RJ_S (1 << 4) 354 if (ret < 0) {
145#define MAX98090_LJ_M (1 << 3) 355 dev_err(max98090->codec->dev,
146#define MAX98090_LJ_S (1 << 2) 356 "Failed to reset codec: %d\n", ret);
147#define MAX98090_I2S_M (1 << 1) 357 return ret;
148#define MAX98090_I2S_S (1 << 0) 358 }
149 359
150/* MAX98090_0x45_DEV_SHUTDOWN */ 360 msleep(20);
151#define MAX98090_SHDNRUN (1 << 7) 361 return ret;
152 362}
153/* codec private data */ 363
154struct max98090_priv { 364static const unsigned int max98090_micboost_tlv[] = {
155 struct regmap *regmap; 365 TLV_DB_RANGE_HEAD(2),
156}; 366 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
157 367 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
158static const struct reg_default max98090_reg_defaults[] = { 368};
159 /* RESET / STATUS / INTERRUPT REGISTERS */ 369
160 {MAX98090_0x00_SW_RESET, 0x00}, 370static const DECLARE_TLV_DB_SCALE(max98090_mic_tlv, 0, 100, 0);
161 {MAX98090_0x01_INT_STS, 0x00}, 371
162 {MAX98090_0x02_JACK_STS, 0x00}, 372static const DECLARE_TLV_DB_SCALE(max98090_line_single_ended_tlv,
163 {MAX98090_0x03_INT_MASK, 0x04}, 373 -600, 600, 0);
164 374
165 /* QUICK SETUP REGISTERS */ 375static const unsigned int max98090_line_tlv[] = {
166 {MAX98090_0x04_SYS_CLK, 0x00}, 376 TLV_DB_RANGE_HEAD(2),
167 {MAX98090_0x05_SAMPLE_RATE, 0x00}, 377 0, 3, TLV_DB_SCALE_ITEM(-600, 300, 0),
168 {MAX98090_0x06_DAI_IF, 0x00}, 378 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
169 {MAX98090_0x07_DAC_PATH, 0x00}, 379};
170 {MAX98090_0x08_MIC_TO_ADC, 0x00}, 380
171 {MAX98090_0x09_LINE_TO_ADC, 0x00}, 381static const DECLARE_TLV_DB_SCALE(max98090_avg_tlv, 0, 600, 0);
172 {MAX98090_0x0A_ANALOG_MIC_LOOP, 0x00}, 382static const DECLARE_TLV_DB_SCALE(max98090_av_tlv, -1200, 100, 0);
173 {MAX98090_0x0B_ANALOG_LINE_LOOP, 0x00}, 383
174 384static const DECLARE_TLV_DB_SCALE(max98090_dvg_tlv, 0, 600, 0);
175 /* ANALOG INPUT CONFIGURATION REGISTERS */ 385static const DECLARE_TLV_DB_SCALE(max98090_dv_tlv, -1500, 100, 0);
176 {MAX98090_0x0D_INPUT_CONFIG, 0x00}, 386
177 {MAX98090_0x0E_LINE_IN_LVL, 0x1B}, 387static const DECLARE_TLV_DB_SCALE(max98090_sidetone_tlv, -6050, 200, 0);
178 {MAX98090_0x0F_LINI_IN_CFG, 0x00}, 388
179 {MAX98090_0x10_MIC1_IN_LVL, 0x11}, 389static const DECLARE_TLV_DB_SCALE(max98090_alc_tlv, -1500, 100, 0);
180 {MAX98090_0x11_MIC2_IN_LVL, 0x11}, 390static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0);
181 391static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0);
182 /* MICROPHONE CONFIGURATION REGISTERS */ 392static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0);
183 {MAX98090_0x12_MIC_BIAS_VOL, 0x00}, 393
184 {MAX98090_0x13_DIGITAL_MIC_CFG, 0x00}, 394static const unsigned int max98090_mixout_tlv[] = {
185 {MAX98090_0x14_DIGITAL_MIC_MODE, 0x00}, 395 TLV_DB_RANGE_HEAD(2),
186 396 0, 1, TLV_DB_SCALE_ITEM(-1200, 250, 0),
187 /* ADC PATH AND CONFIGURATION REGISTERS */ 397 2, 3, TLV_DB_SCALE_ITEM(-600, 600, 0),
188 {MAX98090_0x15_L_ADC_MIX, 0x00},
189 {MAX98090_0x16_R_ADC_MIX, 0x00},
190 {MAX98090_0x17_L_ADC_LVL, 0x03},
191 {MAX98090_0x18_R_ADC_LVL, 0x03},
192 {MAX98090_0x19_ADC_BIQUAD_LVL, 0x00},
193 {MAX98090_0x1A_ADC_SIDETONE, 0x00},
194
195 /* CLOCK CONFIGURATION REGISTERS */
196 {MAX98090_0x1B_SYS_CLK, 0x00},
197 {MAX98090_0x1C_CLK_MODE, 0x00},
198 {MAX98090_0x1D_ANY_CLK1, 0x00},
199 {MAX98090_0x1E_ANY_CLK2, 0x00},
200 {MAX98090_0x1F_ANY_CLK3, 0x00},
201 {MAX98090_0x20_ANY_CLK4, 0x00},
202 {MAX98090_0x21_MASTER_MODE, 0x00},
203
204 /* INTERFACE CONTROL REGISTERS */
205 {MAX98090_0x22_DAI_IF_FMT, 0x00},
206 {MAX98090_0x23_DAI_TDM_FMT1, 0x00},
207 {MAX98090_0x24_DAI_TDM_FMT2, 0x00},
208 {MAX98090_0x25_DAI_IO_CFG, 0x00},
209 {MAX98090_0x26_FILTER_CFG, 0x80},
210 {MAX98090_0x27_DAI_PLAYBACK_LVL, 0x00},
211 {MAX98090_0x28_EQ_PLAYBACK_LVL, 0x00},
212
213 /* HEADPHONE CONTROL REGISTERS */
214 {MAX98090_0x29_L_HP_MIX, 0x00},
215 {MAX98090_0x2A_R_HP_MIX, 0x00},
216 {MAX98090_0x2B_HP_CTR, 0x00},
217 {MAX98090_0x2C_L_HP_VOL, 0x1A},
218 {MAX98090_0x2D_R_HP_VOL, 0x1A},
219
220 /* SPEAKER CONFIGURATION REGISTERS */
221 {MAX98090_0x2E_L_SPK_MIX, 0x00},
222 {MAX98090_0x2F_R_SPK_MIX, 0x00},
223 {MAX98090_0x30_SPK_CTR, 0x00},
224 {MAX98090_0x31_L_SPK_VOL, 0x2C},
225 {MAX98090_0x32_R_SPK_VOL, 0x2C},
226
227 /* ALC CONFIGURATION REGISTERS */
228 {MAX98090_0x33_ALC_TIMING, 0x00},
229 {MAX98090_0x34_ALC_COMPRESSOR, 0x00},
230 {MAX98090_0x35_ALC_EXPANDER, 0x00},
231 {MAX98090_0x36_ALC_GAIN, 0x00},
232
233 /* RECEIVER AND LINE_OUTPUT REGISTERS */
234 {MAX98090_0x37_RCV_LOUT_L_MIX, 0x00},
235 {MAX98090_0x38_RCV_LOUT_L_CNTL, 0x00},
236 {MAX98090_0x39_RCV_LOUT_L_VOL, 0x15},
237 {MAX98090_0x3A_LOUT_R_MIX, 0x00},
238 {MAX98090_0x3B_LOUT_R_CNTL, 0x00},
239 {MAX98090_0x3C_LOUT_R_VOL, 0x15},
240
241 /* JACK DETECT AND ENABLE REGISTERS */
242 {MAX98090_0x3D_JACK_DETECT, 0x00},
243 {MAX98090_0x3E_IN_ENABLE, 0x00},
244 {MAX98090_0x3F_OUT_ENABLE, 0x00},
245 {MAX98090_0x40_LVL_CTR, 0x00},
246 {MAX98090_0x41_DSP_FILTER_ENABLE, 0x00},
247
248 /* BIAS AND POWER MODE CONFIGURATION REGISTERS */
249 {MAX98090_0x42_BIAS_CTR, 0x00},
250 {MAX98090_0x43_DAC_CTR, 0x00},
251 {MAX98090_0x44_ADC_CTR, 0x06},
252 {MAX98090_0x45_DEV_SHUTDOWN, 0x00},
253}; 398};
254 399
255static const unsigned int max98090_hp_tlv[] = { 400static const unsigned int max98090_hp_tlv[] = {
256 TLV_DB_RANGE_HEAD(5), 401 TLV_DB_RANGE_HEAD(5),
257 0x0, 0x6, TLV_DB_SCALE_ITEM(-6700, 400, 0), 402 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
258 0x7, 0xE, TLV_DB_SCALE_ITEM(-4000, 300, 0), 403 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
259 0xF, 0x15, TLV_DB_SCALE_ITEM(-1700, 200, 0), 404 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
260 0x16, 0x1B, TLV_DB_SCALE_ITEM(-400, 100, 0), 405 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
261 0x1C, 0x1F, TLV_DB_SCALE_ITEM(150, 50, 0), 406 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
262}; 407};
263 408
264static struct snd_kcontrol_new max98090_snd_controls[] = { 409static const unsigned int max98090_spk_tlv[] = {
265 SOC_DOUBLE_R_TLV("Headphone Volume", MAX98090_0x2C_L_HP_VOL, 410 TLV_DB_RANGE_HEAD(5),
266 MAX98090_0x2D_R_HP_VOL, 0, 31, 0, max98090_hp_tlv), 411 0, 4, TLV_DB_SCALE_ITEM(-4800, 400, 0),
412 5, 10, TLV_DB_SCALE_ITEM(-2900, 300, 0),
413 11, 14, TLV_DB_SCALE_ITEM(-1200, 200, 0),
414 15, 29, TLV_DB_SCALE_ITEM(-500, 100, 0),
415 30, 39, TLV_DB_SCALE_ITEM(950, 50, 0),
267}; 416};
268 417
269/* Left HeadPhone Mixer Switch */ 418static const unsigned int max98090_rcv_lout_tlv[] = {
270static struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = { 419 TLV_DB_RANGE_HEAD(5),
271 SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x29_L_HP_MIX, 1, 1, 0), 420 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
272 SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x29_L_HP_MIX, 0, 1, 0), 421 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
422 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
423 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
424 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
273}; 425};
274 426
275/* Right HeadPhone Mixer Switch */ 427static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol,
276static struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = { 428 struct snd_ctl_elem_value *ucontrol)
277 SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x2A_R_HP_MIX, 1, 1, 0), 429{
278 SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x2A_R_HP_MIX, 0, 1, 0), 430 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
431 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
432 struct soc_mixer_control *mc =
433 (struct soc_mixer_control *)kcontrol->private_value;
434 unsigned int mask = (1 << fls(mc->max)) - 1;
435 unsigned int val = snd_soc_read(codec, mc->reg);
436 unsigned int *select;
437
438 switch (mc->reg) {
439 case M98090_REG_MIC1_INPUT_LEVEL:
440 select = &(max98090->pa1en);
441 break;
442 case M98090_REG_MIC2_INPUT_LEVEL:
443 select = &(max98090->pa2en);
444 break;
445 case M98090_REG_ADC_SIDETONE:
446 select = &(max98090->sidetone);
447 break;
448 default:
449 return -EINVAL;
450 }
451
452 val = (val >> mc->shift) & mask;
453
454 if (val >= 1) {
455 /* If on, return the volume */
456 val = val - 1;
457 *select = val;
458 } else {
459 /* If off, return last stored value */
460 val = *select;
461 }
462
463 ucontrol->value.integer.value[0] = val;
464 return 0;
465}
466
467static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
468 struct snd_ctl_elem_value *ucontrol)
469{
470 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
471 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
472 struct soc_mixer_control *mc =
473 (struct soc_mixer_control *)kcontrol->private_value;
474 unsigned int mask = (1 << fls(mc->max)) - 1;
475 unsigned int sel = ucontrol->value.integer.value[0];
476 unsigned int val = snd_soc_read(codec, mc->reg);
477 unsigned int *select;
478
479 switch (mc->reg) {
480 case M98090_REG_MIC1_INPUT_LEVEL:
481 select = &(max98090->pa1en);
482 break;
483 case M98090_REG_MIC2_INPUT_LEVEL:
484 select = &(max98090->pa2en);
485 break;
486 case M98090_REG_ADC_SIDETONE:
487 select = &(max98090->sidetone);
488 break;
489 default:
490 return -EINVAL;
491 }
492
493 val = (val >> mc->shift) & mask;
494
495 *select = sel;
496
497 /* Setting a volume is only valid if it is already On */
498 if (val >= 1) {
499 sel = sel + 1;
500 } else {
501 /* Write what was already there */
502 sel = val;
503 }
504
505 snd_soc_update_bits(codec, mc->reg,
506 mask << mc->shift,
507 sel << mc->shift);
508
509 return 0;
510}
511
512static const char * max98090_perf_pwr_text[] =
513 { "High Performance", "Low Power" };
514static const char * max98090_pwr_perf_text[] =
515 { "Low Power", "High Performance" };
516
517static const struct soc_enum max98090_vcmbandgap_enum =
518 SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT,
519 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
520
521static const char * max98090_osr128_text[] = { "64*fs", "128*fs" };
522
523static const struct soc_enum max98090_osr128_enum =
524 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT,
525 ARRAY_SIZE(max98090_osr128_text), max98090_osr128_text);
526
527static const char *max98090_mode_text[] = { "Voice", "Music" };
528
529static const struct soc_enum max98090_mode_enum =
530 SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG, M98090_MODE_SHIFT,
531 ARRAY_SIZE(max98090_mode_text), max98090_mode_text);
532
533static const struct soc_enum max98090_filter_dmic34mode_enum =
534 SOC_ENUM_SINGLE(M98090_REG_FILTER_CONFIG,
535 M98090_FLT_DMIC34MODE_SHIFT,
536 ARRAY_SIZE(max98090_mode_text), max98090_mode_text);
537
538static const char * max98090_drcatk_text[] =
539 { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" };
540
541static const struct soc_enum max98090_drcatk_enum =
542 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT,
543 ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text);
544
545static const char * max98090_drcrls_text[] =
546 { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" };
547
548static const struct soc_enum max98090_drcrls_enum =
549 SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT,
550 ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text);
551
552static const char * max98090_alccmp_text[] =
553 { "1:1", "1:1.5", "1:2", "1:4", "1:INF" };
554
555static const struct soc_enum max98090_alccmp_enum =
556 SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT,
557 ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text);
558
559static const char * max98090_drcexp_text[] = { "1:1", "2:1", "3:1" };
560
561static const struct soc_enum max98090_drcexp_enum =
562 SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT,
563 ARRAY_SIZE(max98090_drcexp_text), max98090_drcexp_text);
564
565static const struct soc_enum max98090_dac_perfmode_enum =
566 SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_PERFMODE_SHIFT,
567 ARRAY_SIZE(max98090_perf_pwr_text), max98090_perf_pwr_text);
568
569static const struct soc_enum max98090_dachp_enum =
570 SOC_ENUM_SINGLE(M98090_REG_DAC_CONTROL, M98090_DACHP_SHIFT,
571 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
572
573static const struct soc_enum max98090_adchp_enum =
574 SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_ADCHP_SHIFT,
575 ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text);
576
577static const struct snd_kcontrol_new max98090_snd_controls[] = {
578 SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum),
579
580 SOC_SINGLE("DMIC MIC Comp Filter Config", M98090_REG_DIGITAL_MIC_CONFIG,
581 M98090_DMIC_COMP_SHIFT, M98090_DMIC_COMP_NUM - 1, 0),
582
583 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
584 M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT,
585 M98090_MIC_PA1EN_NUM - 1, 0, max98090_get_enab_tlv,
586 max98090_put_enab_tlv, max98090_micboost_tlv),
587
588 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
589 M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT,
590 M98090_MIC_PA2EN_NUM - 1, 0, max98090_get_enab_tlv,
591 max98090_put_enab_tlv, max98090_micboost_tlv),
592
593 SOC_SINGLE_TLV("MIC1 Volume", M98090_REG_MIC1_INPUT_LEVEL,
594 M98090_MIC_PGAM1_SHIFT, M98090_MIC_PGAM1_NUM - 1, 1,
595 max98090_mic_tlv),
596
597 SOC_SINGLE_TLV("MIC2 Volume", M98090_REG_MIC2_INPUT_LEVEL,
598 M98090_MIC_PGAM2_SHIFT, M98090_MIC_PGAM2_NUM - 1, 1,
599 max98090_mic_tlv),
600
601 SOC_SINGLE_RANGE_TLV("LINEA Single Ended Volume",
602 M98090_REG_LINE_INPUT_LEVEL, M98090_MIXG135_SHIFT, 0,
603 M98090_MIXG135_NUM - 1, 1, max98090_line_single_ended_tlv),
604
605 SOC_SINGLE_RANGE_TLV("LINEB Single Ended Volume",
606 M98090_REG_LINE_INPUT_LEVEL, M98090_MIXG246_SHIFT, 0,
607 M98090_MIXG246_NUM - 1, 1, max98090_line_single_ended_tlv),
608
609 SOC_SINGLE_RANGE_TLV("LINEA Volume", M98090_REG_LINE_INPUT_LEVEL,
610 M98090_LINAPGA_SHIFT, 0, M98090_LINAPGA_NUM - 1, 1,
611 max98090_line_tlv),
612
613 SOC_SINGLE_RANGE_TLV("LINEB Volume", M98090_REG_LINE_INPUT_LEVEL,
614 M98090_LINBPGA_SHIFT, 0, M98090_LINBPGA_NUM - 1, 1,
615 max98090_line_tlv),
616
617 SOC_SINGLE("LINEA Ext Resistor Gain Mode", M98090_REG_INPUT_MODE,
618 M98090_EXTBUFA_SHIFT, M98090_EXTBUFA_NUM - 1, 0),
619 SOC_SINGLE("LINEB Ext Resistor Gain Mode", M98090_REG_INPUT_MODE,
620 M98090_EXTBUFB_SHIFT, M98090_EXTBUFB_NUM - 1, 0),
621
622 SOC_SINGLE_TLV("ADCL Boost Volume", M98090_REG_LEFT_ADC_LEVEL,
623 M98090_AVLG_SHIFT, M98090_AVLG_NUM - 1, 0,
624 max98090_avg_tlv),
625 SOC_SINGLE_TLV("ADCR Boost Volume", M98090_REG_RIGHT_ADC_LEVEL,
626 M98090_AVRG_SHIFT, M98090_AVLG_NUM - 1, 0,
627 max98090_avg_tlv),
628
629 SOC_SINGLE_TLV("ADCL Volume", M98090_REG_LEFT_ADC_LEVEL,
630 M98090_AVL_SHIFT, M98090_AVL_NUM - 1, 1,
631 max98090_av_tlv),
632 SOC_SINGLE_TLV("ADCR Volume", M98090_REG_RIGHT_ADC_LEVEL,
633 M98090_AVR_SHIFT, M98090_AVR_NUM - 1, 1,
634 max98090_av_tlv),
635
636 SOC_ENUM("ADC Oversampling Rate", max98090_osr128_enum),
637 SOC_SINGLE("ADC Quantizer Dither", M98090_REG_ADC_CONTROL,
638 M98090_ADCDITHER_SHIFT, M98090_ADCDITHER_NUM - 1, 0),
639 SOC_ENUM("ADC High Performance Mode", max98090_adchp_enum),
640
641 SOC_SINGLE("DAC Mono Mode", M98090_REG_IO_CONFIGURATION,
642 M98090_DMONO_SHIFT, M98090_DMONO_NUM - 1, 0),
643 SOC_SINGLE("SDIN Mode", M98090_REG_IO_CONFIGURATION,
644 M98090_SDIEN_SHIFT, M98090_SDIEN_NUM - 1, 0),
645 SOC_SINGLE("SDOUT Mode", M98090_REG_IO_CONFIGURATION,
646 M98090_SDOEN_SHIFT, M98090_SDOEN_NUM - 1, 0),
647 SOC_SINGLE("SDOUT Hi-Z Mode", M98090_REG_IO_CONFIGURATION,
648 M98090_HIZOFF_SHIFT, M98090_HIZOFF_NUM - 1, 1),
649 SOC_ENUM("Filter Mode", max98090_mode_enum),
650 SOC_SINGLE("Record Path DC Blocking", M98090_REG_FILTER_CONFIG,
651 M98090_AHPF_SHIFT, M98090_AHPF_NUM - 1, 0),
652 SOC_SINGLE("Playback Path DC Blocking", M98090_REG_FILTER_CONFIG,
653 M98090_DHPF_SHIFT, M98090_DHPF_NUM - 1, 0),
654 SOC_SINGLE_TLV("Digital BQ Volume", M98090_REG_ADC_BIQUAD_LEVEL,
655 M98090_AVBQ_SHIFT, M98090_AVBQ_NUM - 1, 1, max98090_dv_tlv),
656 SOC_SINGLE_EXT_TLV("Digital Sidetone Volume",
657 M98090_REG_ADC_SIDETONE, M98090_DVST_SHIFT,
658 M98090_DVST_NUM - 1, 1, max98090_get_enab_tlv,
659 max98090_put_enab_tlv, max98090_micboost_tlv),
660 SOC_SINGLE_TLV("Digital Coarse Volume", M98090_REG_DAI_PLAYBACK_LEVEL,
661 M98090_DVG_SHIFT, M98090_DVG_NUM - 1, 0,
662 max98090_dvg_tlv),
663 SOC_SINGLE_TLV("Digital Volume", M98090_REG_DAI_PLAYBACK_LEVEL,
664 M98090_DV_SHIFT, M98090_DV_NUM - 1, 1,
665 max98090_dv_tlv),
666 SND_SOC_BYTES("EQ Coefficients", M98090_REG_EQUALIZER_BASE, 105),
667 SOC_SINGLE("Digital EQ 3 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
668 M98090_EQ3BANDEN_SHIFT, M98090_EQ3BANDEN_NUM - 1, 0),
669 SOC_SINGLE("Digital EQ 5 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
670 M98090_EQ5BANDEN_SHIFT, M98090_EQ5BANDEN_NUM - 1, 0),
671 SOC_SINGLE("Digital EQ 7 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
672 M98090_EQ7BANDEN_SHIFT, M98090_EQ7BANDEN_NUM - 1, 0),
673 SOC_SINGLE("Digital EQ Clipping Detection", M98090_REG_DAI_PLAYBACK_LEVEL_EQ,
674 M98090_EQCLPN_SHIFT, M98090_EQCLPN_NUM - 1,
675 1),
676 SOC_SINGLE_TLV("Digital EQ Volume", M98090_REG_DAI_PLAYBACK_LEVEL_EQ,
677 M98090_DVEQ_SHIFT, M98090_DVEQ_NUM - 1, 1,
678 max98090_dv_tlv),
679
680 SOC_SINGLE("ALC Enable", M98090_REG_DRC_TIMING,
681 M98090_DRCEN_SHIFT, M98090_DRCEN_NUM - 1, 0),
682 SOC_ENUM("ALC Attack Time", max98090_drcatk_enum),
683 SOC_ENUM("ALC Release Time", max98090_drcrls_enum),
684 SOC_SINGLE_TLV("ALC Make Up Volume", M98090_REG_DRC_GAIN,
685 M98090_DRCG_SHIFT, M98090_DRCG_NUM - 1, 0,
686 max98090_alcmakeup_tlv),
687 SOC_ENUM("ALC Compression Ratio", max98090_alccmp_enum),
688 SOC_ENUM("ALC Expansion Ratio", max98090_drcexp_enum),
689 SOC_SINGLE_TLV("ALC Compression Threshold Volume",
690 M98090_REG_DRC_COMPRESSOR, M98090_DRCTHC_SHIFT,
691 M98090_DRCTHC_NUM - 1, 1, max98090_alccomp_tlv),
692 SOC_SINGLE_TLV("ALC Expansion Threshold Volume",
693 M98090_REG_DRC_EXPANDER, M98090_DRCTHE_SHIFT,
694 M98090_DRCTHE_NUM - 1, 1, max98090_drcexp_tlv),
695
696 SOC_ENUM("DAC HP Playback Performance Mode",
697 max98090_dac_perfmode_enum),
698 SOC_ENUM("DAC High Performance Mode", max98090_dachp_enum),
699
700 SOC_SINGLE_TLV("Headphone Left Mixer Volume",
701 M98090_REG_HP_CONTROL, M98090_MIXHPLG_SHIFT,
702 M98090_MIXHPLG_NUM - 1, 1, max98090_mixout_tlv),
703 SOC_SINGLE_TLV("Headphone Right Mixer Volume",
704 M98090_REG_HP_CONTROL, M98090_MIXHPRG_SHIFT,
705 M98090_MIXHPRG_NUM - 1, 1, max98090_mixout_tlv),
706
707 SOC_SINGLE_TLV("Speaker Left Mixer Volume",
708 M98090_REG_SPK_CONTROL, M98090_MIXSPLG_SHIFT,
709 M98090_MIXSPLG_NUM - 1, 1, max98090_mixout_tlv),
710 SOC_SINGLE_TLV("Speaker Right Mixer Volume",
711 M98090_REG_SPK_CONTROL, M98090_MIXSPRG_SHIFT,
712 M98090_MIXSPRG_NUM - 1, 1, max98090_mixout_tlv),
713
714 SOC_SINGLE_TLV("Receiver Left Mixer Volume",
715 M98090_REG_RCV_LOUTL_CONTROL, M98090_MIXRCVLG_SHIFT,
716 M98090_MIXRCVLG_NUM - 1, 1, max98090_mixout_tlv),
717 SOC_SINGLE_TLV("Receiver Right Mixer Volume",
718 M98090_REG_LOUTR_CONTROL, M98090_MIXRCVRG_SHIFT,
719 M98090_MIXRCVRG_NUM - 1, 1, max98090_mixout_tlv),
720
721 SOC_DOUBLE_R_TLV("Headphone Volume", M98090_REG_LEFT_HP_VOLUME,
722 M98090_REG_RIGHT_HP_VOLUME, M98090_HPVOLL_SHIFT,
723 M98090_HPVOLL_NUM - 1, 0, max98090_hp_tlv),
724
725 SOC_DOUBLE_R_RANGE_TLV("Speaker Volume",
726 M98090_REG_LEFT_SPK_VOLUME, M98090_REG_RIGHT_SPK_VOLUME,
727 M98090_SPVOLL_SHIFT, 24, M98090_SPVOLL_NUM - 1 + 24,
728 0, max98090_spk_tlv),
729
730 SOC_DOUBLE_R_TLV("Receiver Volume", M98090_REG_RCV_LOUTL_VOLUME,
731 M98090_REG_LOUTR_VOLUME, M98090_RCVLVOL_SHIFT,
732 M98090_RCVLVOL_NUM - 1, 0, max98090_rcv_lout_tlv),
733
734 SOC_SINGLE("Headphone Left Switch", M98090_REG_LEFT_HP_VOLUME,
735 M98090_HPLM_SHIFT, 1, 1),
736 SOC_SINGLE("Headphone Right Switch", M98090_REG_RIGHT_HP_VOLUME,
737 M98090_HPRM_SHIFT, 1, 1),
738
739 SOC_SINGLE("Speaker Left Switch", M98090_REG_LEFT_SPK_VOLUME,
740 M98090_SPLM_SHIFT, 1, 1),
741 SOC_SINGLE("Speaker Right Switch", M98090_REG_RIGHT_SPK_VOLUME,
742 M98090_SPRM_SHIFT, 1, 1),
743
744 SOC_SINGLE("Receiver Left Switch", M98090_REG_RCV_LOUTL_VOLUME,
745 M98090_RCVLM_SHIFT, 1, 1),
746 SOC_SINGLE("Receiver Right Switch", M98090_REG_LOUTR_VOLUME,
747 M98090_RCVRM_SHIFT, 1, 1),
748
749 SOC_SINGLE("Zero-Crossing Detection", M98090_REG_LEVEL_CONTROL,
750 M98090_ZDENN_SHIFT, M98090_ZDENN_NUM - 1, 1),
751 SOC_SINGLE("Enhanced Vol Smoothing", M98090_REG_LEVEL_CONTROL,
752 M98090_VS2ENN_SHIFT, M98090_VS2ENN_NUM - 1, 1),
753 SOC_SINGLE("Volume Adjustment Smoothing", M98090_REG_LEVEL_CONTROL,
754 M98090_VSENN_SHIFT, M98090_VSENN_NUM - 1, 1),
755
756 SND_SOC_BYTES("Biquad Coefficients", M98090_REG_RECORD_BIQUAD_BASE, 15),
757 SOC_SINGLE("Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
758 M98090_ADCBQEN_SHIFT, M98090_ADCBQEN_NUM - 1, 0),
279}; 759};
280 760
281static struct snd_soc_dapm_widget max98090_dapm_widgets[] = { 761static const struct snd_kcontrol_new max98091_snd_controls[] = {
282 /* Output */ 762
763 SOC_SINGLE("DMIC34 Zeropad", M98090_REG_SAMPLE_RATE,
764 M98090_DMIC34_ZEROPAD_SHIFT,
765 M98090_DMIC34_ZEROPAD_NUM - 1, 0),
766
767 SOC_ENUM("Filter DMIC34 Mode", max98090_filter_dmic34mode_enum),
768 SOC_SINGLE("DMIC34 DC Blocking", M98090_REG_FILTER_CONFIG,
769 M98090_FLT_DMIC34HPF_SHIFT,
770 M98090_FLT_DMIC34HPF_NUM - 1, 0),
771
772 SOC_SINGLE_TLV("DMIC3 Boost Volume", M98090_REG_DMIC3_VOLUME,
773 M98090_DMIC_AV3G_SHIFT, M98090_DMIC_AV3G_NUM - 1, 0,
774 max98090_avg_tlv),
775 SOC_SINGLE_TLV("DMIC4 Boost Volume", M98090_REG_DMIC4_VOLUME,
776 M98090_DMIC_AV4G_SHIFT, M98090_DMIC_AV4G_NUM - 1, 0,
777 max98090_avg_tlv),
778
779 SOC_SINGLE_TLV("DMIC3 Volume", M98090_REG_DMIC3_VOLUME,
780 M98090_DMIC_AV3_SHIFT, M98090_DMIC_AV3_NUM - 1, 1,
781 max98090_av_tlv),
782 SOC_SINGLE_TLV("DMIC4 Volume", M98090_REG_DMIC4_VOLUME,
783 M98090_DMIC_AV4_SHIFT, M98090_DMIC_AV4_NUM - 1, 1,
784 max98090_av_tlv),
785
786 SND_SOC_BYTES("DMIC34 Biquad Coefficients",
787 M98090_REG_DMIC34_BIQUAD_BASE, 15),
788 SOC_SINGLE("DMIC34 Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
789 M98090_DMIC34BQEN_SHIFT, M98090_DMIC34BQEN_NUM - 1, 0),
790
791 SOC_SINGLE_TLV("DMIC34 BQ PreAttenuation Volume",
792 M98090_REG_DMIC34_BQ_PREATTEN, M98090_AV34BQ_SHIFT,
793 M98090_AV34BQ_NUM - 1, 1, max98090_dv_tlv),
794};
795
796static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
797 struct snd_kcontrol *kcontrol, int event)
798{
799 struct snd_soc_codec *codec = w->codec;
800 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
801
802 unsigned int val = snd_soc_read(codec, w->reg);
803
804 if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
805 val = (val & M98090_MIC_PA1EN_MASK) >> M98090_MIC_PA1EN_SHIFT;
806 else
807 val = (val & M98090_MIC_PA2EN_MASK) >> M98090_MIC_PA2EN_SHIFT;
808
809
810 if (val >= 1) {
811 if (w->reg == M98090_REG_MIC1_INPUT_LEVEL) {
812 max98090->pa1en = val - 1; /* Update for volatile */
813 } else {
814 max98090->pa2en = val - 1; /* Update for volatile */
815 }
816 }
817
818 switch (event) {
819 case SND_SOC_DAPM_POST_PMU:
820 /* If turning on, set to most recently selected volume */
821 if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
822 val = max98090->pa1en + 1;
823 else
824 val = max98090->pa2en + 1;
825 break;
826 case SND_SOC_DAPM_POST_PMD:
827 /* If turning off, turn off */
828 val = 0;
829 break;
830 default:
831 return -EINVAL;
832 }
833
834 if (w->reg == M98090_REG_MIC1_INPUT_LEVEL)
835 snd_soc_update_bits(codec, w->reg, M98090_MIC_PA1EN_MASK,
836 val << M98090_MIC_PA1EN_SHIFT);
837 else
838 snd_soc_update_bits(codec, w->reg, M98090_MIC_PA2EN_MASK,
839 val << M98090_MIC_PA2EN_SHIFT);
840
841 return 0;
842}
843
844static const char *mic1_mux_text[] = { "IN12", "IN56" };
845
846static const struct soc_enum mic1_mux_enum =
847 SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC1_SHIFT,
848 ARRAY_SIZE(mic1_mux_text), mic1_mux_text);
849
850static const struct snd_kcontrol_new max98090_mic1_mux =
851 SOC_DAPM_ENUM("MIC1 Mux", mic1_mux_enum);
852
853static const char *mic2_mux_text[] = { "IN34", "IN56" };
854
855static const struct soc_enum mic2_mux_enum =
856 SOC_ENUM_SINGLE(M98090_REG_INPUT_MODE, M98090_EXTMIC2_SHIFT,
857 ARRAY_SIZE(mic2_mux_text), mic2_mux_text);
858
859static const struct snd_kcontrol_new max98090_mic2_mux =
860 SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum);
861
862static const char * max98090_micpre_text[] = { "Off", "On" };
863
864static const struct soc_enum max98090_pa1en_enum =
865 SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT,
866 ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text);
867
868static const struct soc_enum max98090_pa2en_enum =
869 SOC_ENUM_SINGLE(M98090_REG_MIC2_INPUT_LEVEL, M98090_MIC_PA2EN_SHIFT,
870 ARRAY_SIZE(max98090_micpre_text), max98090_micpre_text);
871
872/* LINEA mixer switch */
873static const struct snd_kcontrol_new max98090_linea_mixer_controls[] = {
874 SOC_DAPM_SINGLE("IN1 Switch", M98090_REG_LINE_INPUT_CONFIG,
875 M98090_IN1SEEN_SHIFT, 1, 0),
876 SOC_DAPM_SINGLE("IN3 Switch", M98090_REG_LINE_INPUT_CONFIG,
877 M98090_IN3SEEN_SHIFT, 1, 0),
878 SOC_DAPM_SINGLE("IN5 Switch", M98090_REG_LINE_INPUT_CONFIG,
879 M98090_IN5SEEN_SHIFT, 1, 0),
880 SOC_DAPM_SINGLE("IN34 Switch", M98090_REG_LINE_INPUT_CONFIG,
881 M98090_IN34DIFF_SHIFT, 1, 0),
882};
883
884/* LINEB mixer switch */
885static const struct snd_kcontrol_new max98090_lineb_mixer_controls[] = {
886 SOC_DAPM_SINGLE("IN2 Switch", M98090_REG_LINE_INPUT_CONFIG,
887 M98090_IN2SEEN_SHIFT, 1, 0),
888 SOC_DAPM_SINGLE("IN4 Switch", M98090_REG_LINE_INPUT_CONFIG,
889 M98090_IN4SEEN_SHIFT, 1, 0),
890 SOC_DAPM_SINGLE("IN6 Switch", M98090_REG_LINE_INPUT_CONFIG,
891 M98090_IN6SEEN_SHIFT, 1, 0),
892 SOC_DAPM_SINGLE("IN56 Switch", M98090_REG_LINE_INPUT_CONFIG,
893 M98090_IN56DIFF_SHIFT, 1, 0),
894};
895
896/* Left ADC mixer switch */
897static const struct snd_kcontrol_new max98090_left_adc_mixer_controls[] = {
898 SOC_DAPM_SINGLE("IN12 Switch", M98090_REG_LEFT_ADC_MIXER,
899 M98090_MIXADL_IN12DIFF_SHIFT, 1, 0),
900 SOC_DAPM_SINGLE("IN34 Switch", M98090_REG_LEFT_ADC_MIXER,
901 M98090_MIXADL_IN34DIFF_SHIFT, 1, 0),
902 SOC_DAPM_SINGLE("IN56 Switch", M98090_REG_LEFT_ADC_MIXER,
903 M98090_MIXADL_IN65DIFF_SHIFT, 1, 0),
904 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_LEFT_ADC_MIXER,
905 M98090_MIXADL_LINEA_SHIFT, 1, 0),
906 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_LEFT_ADC_MIXER,
907 M98090_MIXADL_LINEB_SHIFT, 1, 0),
908 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_LEFT_ADC_MIXER,
909 M98090_MIXADL_MIC1_SHIFT, 1, 0),
910 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_LEFT_ADC_MIXER,
911 M98090_MIXADL_MIC2_SHIFT, 1, 0),
912};
913
914/* Right ADC mixer switch */
915static const struct snd_kcontrol_new max98090_right_adc_mixer_controls[] = {
916 SOC_DAPM_SINGLE("IN12 Switch", M98090_REG_RIGHT_ADC_MIXER,
917 M98090_MIXADR_IN12DIFF_SHIFT, 1, 0),
918 SOC_DAPM_SINGLE("IN34 Switch", M98090_REG_RIGHT_ADC_MIXER,
919 M98090_MIXADR_IN34DIFF_SHIFT, 1, 0),
920 SOC_DAPM_SINGLE("IN56 Switch", M98090_REG_RIGHT_ADC_MIXER,
921 M98090_MIXADR_IN65DIFF_SHIFT, 1, 0),
922 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_RIGHT_ADC_MIXER,
923 M98090_MIXADR_LINEA_SHIFT, 1, 0),
924 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_RIGHT_ADC_MIXER,
925 M98090_MIXADR_LINEB_SHIFT, 1, 0),
926 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_RIGHT_ADC_MIXER,
927 M98090_MIXADR_MIC1_SHIFT, 1, 0),
928 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_RIGHT_ADC_MIXER,
929 M98090_MIXADR_MIC2_SHIFT, 1, 0),
930};
931
932static const char *lten_mux_text[] = { "Normal", "Loopthrough" };
933
934static const struct soc_enum ltenl_mux_enum =
935 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT,
936 ARRAY_SIZE(lten_mux_text), lten_mux_text);
937
938static const struct soc_enum ltenr_mux_enum =
939 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LTEN_SHIFT,
940 ARRAY_SIZE(lten_mux_text), lten_mux_text);
941
942static const struct snd_kcontrol_new max98090_ltenl_mux =
943 SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum);
944
945static const struct snd_kcontrol_new max98090_ltenr_mux =
946 SOC_DAPM_ENUM("LTENR Mux", ltenr_mux_enum);
947
948static const char *lben_mux_text[] = { "Normal", "Loopback" };
949
950static const struct soc_enum lbenl_mux_enum =
951 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT,
952 ARRAY_SIZE(lben_mux_text), lben_mux_text);
953
954static const struct soc_enum lbenr_mux_enum =
955 SOC_ENUM_SINGLE(M98090_REG_IO_CONFIGURATION, M98090_LBEN_SHIFT,
956 ARRAY_SIZE(lben_mux_text), lben_mux_text);
957
958static const struct snd_kcontrol_new max98090_lbenl_mux =
959 SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum);
960
961static const struct snd_kcontrol_new max98090_lbenr_mux =
962 SOC_DAPM_ENUM("LBENR Mux", lbenr_mux_enum);
963
964static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" };
965
966static const char *stenr_mux_text[] = { "Normal", "Sidetone Right" };
967
968static const struct soc_enum stenl_mux_enum =
969 SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSL_SHIFT,
970 ARRAY_SIZE(stenl_mux_text), stenl_mux_text);
971
972static const struct soc_enum stenr_mux_enum =
973 SOC_ENUM_SINGLE(M98090_REG_ADC_SIDETONE, M98090_DSTSR_SHIFT,
974 ARRAY_SIZE(stenr_mux_text), stenr_mux_text);
975
976static const struct snd_kcontrol_new max98090_stenl_mux =
977 SOC_DAPM_ENUM("STENL Mux", stenl_mux_enum);
978
979static const struct snd_kcontrol_new max98090_stenr_mux =
980 SOC_DAPM_ENUM("STENR Mux", stenr_mux_enum);
981
982/* Left speaker mixer switch */
983static const struct
984 snd_kcontrol_new max98090_left_speaker_mixer_controls[] = {
985 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_LEFT_SPK_MIXER,
986 M98090_MIXSPL_DACL_SHIFT, 1, 0),
987 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_LEFT_SPK_MIXER,
988 M98090_MIXSPL_DACR_SHIFT, 1, 0),
989 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_LEFT_SPK_MIXER,
990 M98090_MIXSPL_LINEA_SHIFT, 1, 0),
991 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_LEFT_SPK_MIXER,
992 M98090_MIXSPL_LINEB_SHIFT, 1, 0),
993 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_LEFT_SPK_MIXER,
994 M98090_MIXSPL_MIC1_SHIFT, 1, 0),
995 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_LEFT_SPK_MIXER,
996 M98090_MIXSPL_MIC2_SHIFT, 1, 0),
997};
998
999/* Right speaker mixer switch */
1000static const struct
1001 snd_kcontrol_new max98090_right_speaker_mixer_controls[] = {
1002 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_RIGHT_SPK_MIXER,
1003 M98090_MIXSPR_DACL_SHIFT, 1, 0),
1004 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_RIGHT_SPK_MIXER,
1005 M98090_MIXSPR_DACR_SHIFT, 1, 0),
1006 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_RIGHT_SPK_MIXER,
1007 M98090_MIXSPR_LINEA_SHIFT, 1, 0),
1008 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_RIGHT_SPK_MIXER,
1009 M98090_MIXSPR_LINEB_SHIFT, 1, 0),
1010 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_RIGHT_SPK_MIXER,
1011 M98090_MIXSPR_MIC1_SHIFT, 1, 0),
1012 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_RIGHT_SPK_MIXER,
1013 M98090_MIXSPR_MIC2_SHIFT, 1, 0),
1014};
1015
1016/* Left headphone mixer switch */
1017static const struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = {
1018 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_LEFT_HP_MIXER,
1019 M98090_MIXHPL_DACL_SHIFT, 1, 0),
1020 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_LEFT_HP_MIXER,
1021 M98090_MIXHPL_DACR_SHIFT, 1, 0),
1022 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_LEFT_HP_MIXER,
1023 M98090_MIXHPL_LINEA_SHIFT, 1, 0),
1024 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_LEFT_HP_MIXER,
1025 M98090_MIXHPL_LINEB_SHIFT, 1, 0),
1026 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_LEFT_HP_MIXER,
1027 M98090_MIXHPL_MIC1_SHIFT, 1, 0),
1028 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_LEFT_HP_MIXER,
1029 M98090_MIXHPL_MIC2_SHIFT, 1, 0),
1030};
1031
1032/* Right headphone mixer switch */
1033static const struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = {
1034 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_RIGHT_HP_MIXER,
1035 M98090_MIXHPR_DACL_SHIFT, 1, 0),
1036 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_RIGHT_HP_MIXER,
1037 M98090_MIXHPR_DACR_SHIFT, 1, 0),
1038 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_RIGHT_HP_MIXER,
1039 M98090_MIXHPR_LINEA_SHIFT, 1, 0),
1040 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_RIGHT_HP_MIXER,
1041 M98090_MIXHPR_LINEB_SHIFT, 1, 0),
1042 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_RIGHT_HP_MIXER,
1043 M98090_MIXHPR_MIC1_SHIFT, 1, 0),
1044 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_RIGHT_HP_MIXER,
1045 M98090_MIXHPR_MIC2_SHIFT, 1, 0),
1046};
1047
1048/* Left receiver mixer switch */
1049static const struct snd_kcontrol_new max98090_left_rcv_mixer_controls[] = {
1050 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_RCV_LOUTL_MIXER,
1051 M98090_MIXRCVL_DACL_SHIFT, 1, 0),
1052 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_RCV_LOUTL_MIXER,
1053 M98090_MIXRCVL_DACR_SHIFT, 1, 0),
1054 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_RCV_LOUTL_MIXER,
1055 M98090_MIXRCVL_LINEA_SHIFT, 1, 0),
1056 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_RCV_LOUTL_MIXER,
1057 M98090_MIXRCVL_LINEB_SHIFT, 1, 0),
1058 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_RCV_LOUTL_MIXER,
1059 M98090_MIXRCVL_MIC1_SHIFT, 1, 0),
1060 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_RCV_LOUTL_MIXER,
1061 M98090_MIXRCVL_MIC2_SHIFT, 1, 0),
1062};
1063
1064/* Right receiver mixer switch */
1065static const struct snd_kcontrol_new max98090_right_rcv_mixer_controls[] = {
1066 SOC_DAPM_SINGLE("Left DAC Switch", M98090_REG_LOUTR_MIXER,
1067 M98090_MIXRCVR_DACL_SHIFT, 1, 0),
1068 SOC_DAPM_SINGLE("Right DAC Switch", M98090_REG_LOUTR_MIXER,
1069 M98090_MIXRCVR_DACR_SHIFT, 1, 0),
1070 SOC_DAPM_SINGLE("LINEA Switch", M98090_REG_LOUTR_MIXER,
1071 M98090_MIXRCVR_LINEA_SHIFT, 1, 0),
1072 SOC_DAPM_SINGLE("LINEB Switch", M98090_REG_LOUTR_MIXER,
1073 M98090_MIXRCVR_LINEB_SHIFT, 1, 0),
1074 SOC_DAPM_SINGLE("MIC1 Switch", M98090_REG_LOUTR_MIXER,
1075 M98090_MIXRCVR_MIC1_SHIFT, 1, 0),
1076 SOC_DAPM_SINGLE("MIC2 Switch", M98090_REG_LOUTR_MIXER,
1077 M98090_MIXRCVR_MIC2_SHIFT, 1, 0),
1078};
1079
1080static const char *linmod_mux_text[] = { "Left Only", "Left and Right" };
1081
1082static const struct soc_enum linmod_mux_enum =
1083 SOC_ENUM_SINGLE(M98090_REG_LOUTR_MIXER, M98090_LINMOD_SHIFT,
1084 ARRAY_SIZE(linmod_mux_text), linmod_mux_text);
1085
1086static const struct snd_kcontrol_new max98090_linmod_mux =
1087 SOC_DAPM_ENUM("LINMOD Mux", linmod_mux_enum);
1088
1089static const char *mixhpsel_mux_text[] = { "DAC Only", "HP Mixer" };
1090
1091/*
1092 * This is a mux as it selects the HP output, but to DAPM it is a Mixer enable
1093 */
1094static const struct soc_enum mixhplsel_mux_enum =
1095 SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPLSEL_SHIFT,
1096 ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text);
1097
1098static const struct snd_kcontrol_new max98090_mixhplsel_mux =
1099 SOC_DAPM_ENUM("MIXHPLSEL Mux", mixhplsel_mux_enum);
1100
1101static const struct soc_enum mixhprsel_mux_enum =
1102 SOC_ENUM_SINGLE(M98090_REG_HP_CONTROL, M98090_MIXHPRSEL_SHIFT,
1103 ARRAY_SIZE(mixhpsel_mux_text), mixhpsel_mux_text);
1104
1105static const struct snd_kcontrol_new max98090_mixhprsel_mux =
1106 SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum);
1107
1108static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
1109
1110 SND_SOC_DAPM_INPUT("MIC1"),
1111 SND_SOC_DAPM_INPUT("MIC2"),
1112 SND_SOC_DAPM_INPUT("DMICL"),
1113 SND_SOC_DAPM_INPUT("DMICR"),
1114 SND_SOC_DAPM_INPUT("IN1"),
1115 SND_SOC_DAPM_INPUT("IN2"),
1116 SND_SOC_DAPM_INPUT("IN3"),
1117 SND_SOC_DAPM_INPUT("IN4"),
1118 SND_SOC_DAPM_INPUT("IN5"),
1119 SND_SOC_DAPM_INPUT("IN6"),
1120 SND_SOC_DAPM_INPUT("IN12"),
1121 SND_SOC_DAPM_INPUT("IN34"),
1122 SND_SOC_DAPM_INPUT("IN56"),
1123
1124 SND_SOC_DAPM_SUPPLY("MICBIAS", M98090_REG_INPUT_ENABLE,
1125 M98090_MBEN_SHIFT, 0, NULL, 0),
1126 SND_SOC_DAPM_SUPPLY("SHDN", M98090_REG_DEVICE_SHUTDOWN,
1127 M98090_SHDNN_SHIFT, 0, NULL, 0),
1128 SND_SOC_DAPM_SUPPLY("SDIEN", M98090_REG_IO_CONFIGURATION,
1129 M98090_SDIEN_SHIFT, 0, NULL, 0),
1130 SND_SOC_DAPM_SUPPLY("SDOEN", M98090_REG_IO_CONFIGURATION,
1131 M98090_SDOEN_SHIFT, 0, NULL, 0),
1132 SND_SOC_DAPM_SUPPLY("DMICL_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
1133 M98090_DIGMICL_SHIFT, 0, NULL, 0),
1134 SND_SOC_DAPM_SUPPLY("DMICR_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
1135 M98090_DIGMICR_SHIFT, 0, NULL, 0),
1136 SND_SOC_DAPM_SUPPLY("AHPF", M98090_REG_FILTER_CONFIG,
1137 M98090_AHPF_SHIFT, 0, NULL, 0),
1138
1139/*
1140 * Note: Sysclk and misc power supplies are taken care of by SHDN
1141 */
1142
1143 SND_SOC_DAPM_MUX("MIC1 Mux", SND_SOC_NOPM,
1144 0, 0, &max98090_mic1_mux),
1145
1146 SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM,
1147 0, 0, &max98090_mic2_mux),
1148
1149 SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL,
1150 M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event,
1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1152
1153 SND_SOC_DAPM_PGA_E("MIC2 Input", M98090_REG_MIC2_INPUT_LEVEL,
1154 M98090_MIC_PA2EN_SHIFT, 0, NULL, 0, max98090_micinput_event,
1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1156
1157 SND_SOC_DAPM_MIXER("LINEA Mixer", SND_SOC_NOPM, 0, 0,
1158 &max98090_linea_mixer_controls[0],
1159 ARRAY_SIZE(max98090_linea_mixer_controls)),
1160
1161 SND_SOC_DAPM_MIXER("LINEB Mixer", SND_SOC_NOPM, 0, 0,
1162 &max98090_lineb_mixer_controls[0],
1163 ARRAY_SIZE(max98090_lineb_mixer_controls)),
1164
1165 SND_SOC_DAPM_PGA("LINEA Input", M98090_REG_INPUT_ENABLE,
1166 M98090_LINEAEN_SHIFT, 0, NULL, 0),
1167 SND_SOC_DAPM_PGA("LINEB Input", M98090_REG_INPUT_ENABLE,
1168 M98090_LINEBEN_SHIFT, 0, NULL, 0),
1169
1170 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1171 &max98090_left_adc_mixer_controls[0],
1172 ARRAY_SIZE(max98090_left_adc_mixer_controls)),
1173
1174 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1175 &max98090_right_adc_mixer_controls[0],
1176 ARRAY_SIZE(max98090_right_adc_mixer_controls)),
1177
1178 SND_SOC_DAPM_ADC("ADCL", NULL, M98090_REG_INPUT_ENABLE,
1179 M98090_ADLEN_SHIFT, 0),
1180 SND_SOC_DAPM_ADC("ADCR", NULL, M98090_REG_INPUT_ENABLE,
1181 M98090_ADREN_SHIFT, 0),
1182
1183 SND_SOC_DAPM_AIF_OUT("AIFOUTL", "HiFi Capture", 0,
1184 SND_SOC_NOPM, 0, 0),
1185 SND_SOC_DAPM_AIF_OUT("AIFOUTR", "HiFi Capture", 1,
1186 SND_SOC_NOPM, 0, 0),
1187
1188 SND_SOC_DAPM_MUX("LBENL Mux", SND_SOC_NOPM,
1189 0, 0, &max98090_lbenl_mux),
1190
1191 SND_SOC_DAPM_MUX("LBENR Mux", SND_SOC_NOPM,
1192 0, 0, &max98090_lbenr_mux),
1193
1194 SND_SOC_DAPM_MUX("LTENL Mux", SND_SOC_NOPM,
1195 0, 0, &max98090_ltenl_mux),
1196
1197 SND_SOC_DAPM_MUX("LTENR Mux", SND_SOC_NOPM,
1198 0, 0, &max98090_ltenr_mux),
1199
1200 SND_SOC_DAPM_MUX("STENL Mux", SND_SOC_NOPM,
1201 0, 0, &max98090_stenl_mux),
1202
1203 SND_SOC_DAPM_MUX("STENR Mux", SND_SOC_NOPM,
1204 0, 0, &max98090_stenr_mux),
1205
1206 SND_SOC_DAPM_AIF_IN("AIFINL", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
1207 SND_SOC_DAPM_AIF_IN("AIFINR", "HiFi Playback", 1, SND_SOC_NOPM, 0, 0),
1208
1209 SND_SOC_DAPM_DAC("DACL", NULL, M98090_REG_OUTPUT_ENABLE,
1210 M98090_DALEN_SHIFT, 0),
1211 SND_SOC_DAPM_DAC("DACR", NULL, M98090_REG_OUTPUT_ENABLE,
1212 M98090_DAREN_SHIFT, 0),
1213
1214 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
1215 &max98090_left_hp_mixer_controls[0],
1216 ARRAY_SIZE(max98090_left_hp_mixer_controls)),
1217
1218 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
1219 &max98090_right_hp_mixer_controls[0],
1220 ARRAY_SIZE(max98090_right_hp_mixer_controls)),
1221
1222 SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
1223 &max98090_left_speaker_mixer_controls[0],
1224 ARRAY_SIZE(max98090_left_speaker_mixer_controls)),
1225
1226 SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
1227 &max98090_right_speaker_mixer_controls[0],
1228 ARRAY_SIZE(max98090_right_speaker_mixer_controls)),
1229
1230 SND_SOC_DAPM_MIXER("Left Receiver Mixer", SND_SOC_NOPM, 0, 0,
1231 &max98090_left_rcv_mixer_controls[0],
1232 ARRAY_SIZE(max98090_left_rcv_mixer_controls)),
1233
1234 SND_SOC_DAPM_MIXER("Right Receiver Mixer", SND_SOC_NOPM, 0, 0,
1235 &max98090_right_rcv_mixer_controls[0],
1236 ARRAY_SIZE(max98090_right_rcv_mixer_controls)),
1237
1238 SND_SOC_DAPM_MUX("LINMOD Mux", M98090_REG_LOUTR_MIXER,
1239 M98090_LINMOD_SHIFT, 0, &max98090_linmod_mux),
1240
1241 SND_SOC_DAPM_MUX("MIXHPLSEL Mux", M98090_REG_HP_CONTROL,
1242 M98090_MIXHPLSEL_SHIFT, 0, &max98090_mixhplsel_mux),
1243
1244 SND_SOC_DAPM_MUX("MIXHPRSEL Mux", M98090_REG_HP_CONTROL,
1245 M98090_MIXHPRSEL_SHIFT, 0, &max98090_mixhprsel_mux),
1246
1247 SND_SOC_DAPM_PGA("HP Left Out", M98090_REG_OUTPUT_ENABLE,
1248 M98090_HPLEN_SHIFT, 0, NULL, 0),
1249 SND_SOC_DAPM_PGA("HP Right Out", M98090_REG_OUTPUT_ENABLE,
1250 M98090_HPREN_SHIFT, 0, NULL, 0),
1251
1252 SND_SOC_DAPM_PGA("SPK Left Out", M98090_REG_OUTPUT_ENABLE,
1253 M98090_SPLEN_SHIFT, 0, NULL, 0),
1254 SND_SOC_DAPM_PGA("SPK Right Out", M98090_REG_OUTPUT_ENABLE,
1255 M98090_SPREN_SHIFT, 0, NULL, 0),
1256
1257 SND_SOC_DAPM_PGA("RCV Left Out", M98090_REG_OUTPUT_ENABLE,
1258 M98090_RCVLEN_SHIFT, 0, NULL, 0),
1259 SND_SOC_DAPM_PGA("RCV Right Out", M98090_REG_OUTPUT_ENABLE,
1260 M98090_RCVREN_SHIFT, 0, NULL, 0),
1261
283 SND_SOC_DAPM_OUTPUT("HPL"), 1262 SND_SOC_DAPM_OUTPUT("HPL"),
284 SND_SOC_DAPM_OUTPUT("HPR"), 1263 SND_SOC_DAPM_OUTPUT("HPR"),
1264 SND_SOC_DAPM_OUTPUT("SPKL"),
1265 SND_SOC_DAPM_OUTPUT("SPKR"),
1266 SND_SOC_DAPM_OUTPUT("RCVL"),
1267 SND_SOC_DAPM_OUTPUT("RCVR"),
1268};
1269
1270static const struct snd_soc_dapm_widget max98091_dapm_widgets[] = {
285 1271
286 /* PGA */ 1272 SND_SOC_DAPM_INPUT("DMIC3"),
287 SND_SOC_DAPM_PGA("HPL Out", MAX98090_0x3F_OUT_ENABLE, 7, 0, NULL, 0), 1273 SND_SOC_DAPM_INPUT("DMIC4"),
288 SND_SOC_DAPM_PGA("HPR Out", MAX98090_0x3F_OUT_ENABLE, 6, 0, NULL, 0),
289 1274
290 /* Mixer */ 1275 SND_SOC_DAPM_SUPPLY("DMIC3_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
291 SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0, 1276 M98090_DIGMIC3_SHIFT, 0, NULL, 0),
292 max98090_left_hp_mixer_controls, 1277 SND_SOC_DAPM_SUPPLY("DMIC4_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
293 ARRAY_SIZE(max98090_left_hp_mixer_controls)), 1278 M98090_DIGMIC4_SHIFT, 0, NULL, 0),
1279};
294 1280
295 SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0, 1281static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
296 max98090_right_hp_mixer_controls, 1282
297 ARRAY_SIZE(max98090_right_hp_mixer_controls)), 1283 {"MIC1 Input", NULL, "MIC1"},
1284 {"MIC2 Input", NULL, "MIC2"},
1285
1286 {"DMICL", NULL, "DMICL_ENA"},
1287 {"DMICR", NULL, "DMICR_ENA"},
1288 {"DMICL", NULL, "AHPF"},
1289 {"DMICR", NULL, "AHPF"},
1290
1291 /* MIC1 input mux */
1292 {"MIC1 Mux", "IN12", "IN12"},
1293 {"MIC1 Mux", "IN56", "IN56"},
1294
1295 /* MIC2 input mux */
1296 {"MIC2 Mux", "IN34", "IN34"},
1297 {"MIC2 Mux", "IN56", "IN56"},
1298
1299 {"MIC1 Input", NULL, "MIC1 Mux"},
1300 {"MIC2 Input", NULL, "MIC2 Mux"},
1301
1302 /* Left ADC input mixer */
1303 {"Left ADC Mixer", "IN12 Switch", "IN12"},
1304 {"Left ADC Mixer", "IN34 Switch", "IN34"},
1305 {"Left ADC Mixer", "IN56 Switch", "IN56"},
1306 {"Left ADC Mixer", "LINEA Switch", "LINEA Input"},
1307 {"Left ADC Mixer", "LINEB Switch", "LINEB Input"},
1308 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1309 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1310
1311 /* Right ADC input mixer */
1312 {"Right ADC Mixer", "IN12 Switch", "IN12"},
1313 {"Right ADC Mixer", "IN34 Switch", "IN34"},
1314 {"Right ADC Mixer", "IN56 Switch", "IN56"},
1315 {"Right ADC Mixer", "LINEA Switch", "LINEA Input"},
1316 {"Right ADC Mixer", "LINEB Switch", "LINEB Input"},
1317 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1318 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1319
1320 /* Line A input mixer */
1321 {"LINEA Mixer", "IN1 Switch", "IN1"},
1322 {"LINEA Mixer", "IN3 Switch", "IN3"},
1323 {"LINEA Mixer", "IN5 Switch", "IN5"},
1324 {"LINEA Mixer", "IN34 Switch", "IN34"},
1325
1326 /* Line B input mixer */
1327 {"LINEB Mixer", "IN2 Switch", "IN2"},
1328 {"LINEB Mixer", "IN4 Switch", "IN4"},
1329 {"LINEB Mixer", "IN6 Switch", "IN6"},
1330 {"LINEB Mixer", "IN56 Switch", "IN56"},
1331
1332 {"LINEA Input", NULL, "LINEA Mixer"},
1333 {"LINEB Input", NULL, "LINEB Mixer"},
1334
1335 /* Inputs */
1336 {"ADCL", NULL, "Left ADC Mixer"},
1337 {"ADCR", NULL, "Right ADC Mixer"},
1338 {"ADCL", NULL, "SHDN"},
1339 {"ADCR", NULL, "SHDN"},
1340
1341 {"LBENL Mux", "Normal", "ADCL"},
1342 {"LBENL Mux", "Normal", "DMICL"},
1343 {"LBENL Mux", "Loopback", "LTENL Mux"},
1344 {"LBENR Mux", "Normal", "ADCR"},
1345 {"LBENR Mux", "Normal", "DMICR"},
1346 {"LBENR Mux", "Loopback", "LTENR Mux"},
1347
1348 {"AIFOUTL", NULL, "LBENL Mux"},
1349 {"AIFOUTR", NULL, "LBENR Mux"},
1350 {"AIFOUTL", NULL, "SHDN"},
1351 {"AIFOUTR", NULL, "SHDN"},
1352 {"AIFOUTL", NULL, "SDOEN"},
1353 {"AIFOUTR", NULL, "SDOEN"},
1354
1355 {"LTENL Mux", "Normal", "AIFINL"},
1356 {"LTENL Mux", "Loopthrough", "LBENL Mux"},
1357 {"LTENR Mux", "Normal", "AIFINR"},
1358 {"LTENR Mux", "Loopthrough", "LBENR Mux"},
1359
1360 {"DACL", NULL, "LTENL Mux"},
1361 {"DACR", NULL, "LTENR Mux"},
1362
1363 {"STENL Mux", "Sidetone Left", "ADCL"},
1364 {"STENL Mux", "Sidetone Left", "DMICL"},
1365 {"STENR Mux", "Sidetone Right", "ADCR"},
1366 {"STENR Mux", "Sidetone Right", "DMICR"},
1367 {"DACL", "NULL", "STENL Mux"},
1368 {"DACR", "NULL", "STENL Mux"},
1369
1370 {"AIFINL", NULL, "SHDN"},
1371 {"AIFINR", NULL, "SHDN"},
1372 {"AIFINL", NULL, "SDIEN"},
1373 {"AIFINR", NULL, "SDIEN"},
1374 {"DACL", NULL, "SHDN"},
1375 {"DACR", NULL, "SHDN"},
1376
1377 /* Left headphone output mixer */
1378 {"Left Headphone Mixer", "Left DAC Switch", "DACL"},
1379 {"Left Headphone Mixer", "Right DAC Switch", "DACR"},
1380 {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1381 {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1382 {"Left Headphone Mixer", "LINEA Switch", "LINEA Input"},
1383 {"Left Headphone Mixer", "LINEB Switch", "LINEB Input"},
1384
1385 /* Right headphone output mixer */
1386 {"Right Headphone Mixer", "Left DAC Switch", "DACL"},
1387 {"Right Headphone Mixer", "Right DAC Switch", "DACR"},
1388 {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1389 {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1390 {"Right Headphone Mixer", "LINEA Switch", "LINEA Input"},
1391 {"Right Headphone Mixer", "LINEB Switch", "LINEB Input"},
1392
1393 /* Left speaker output mixer */
1394 {"Left Speaker Mixer", "Left DAC Switch", "DACL"},
1395 {"Left Speaker Mixer", "Right DAC Switch", "DACR"},
1396 {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1397 {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1398 {"Left Speaker Mixer", "LINEA Switch", "LINEA Input"},
1399 {"Left Speaker Mixer", "LINEB Switch", "LINEB Input"},
1400
1401 /* Right speaker output mixer */
1402 {"Right Speaker Mixer", "Left DAC Switch", "DACL"},
1403 {"Right Speaker Mixer", "Right DAC Switch", "DACR"},
1404 {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1405 {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1406 {"Right Speaker Mixer", "LINEA Switch", "LINEA Input"},
1407 {"Right Speaker Mixer", "LINEB Switch", "LINEB Input"},
1408
1409 /* Left Receiver output mixer */
1410 {"Left Receiver Mixer", "Left DAC Switch", "DACL"},
1411 {"Left Receiver Mixer", "Right DAC Switch", "DACR"},
1412 {"Left Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1413 {"Left Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1414 {"Left Receiver Mixer", "LINEA Switch", "LINEA Input"},
1415 {"Left Receiver Mixer", "LINEB Switch", "LINEB Input"},
1416
1417 /* Right Receiver output mixer */
1418 {"Right Receiver Mixer", "Left DAC Switch", "DACL"},
1419 {"Right Receiver Mixer", "Right DAC Switch", "DACR"},
1420 {"Right Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1421 {"Right Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1422 {"Right Receiver Mixer", "LINEA Switch", "LINEA Input"},
1423 {"Right Receiver Mixer", "LINEB Switch", "LINEB Input"},
1424
1425 {"MIXHPLSEL Mux", "HP Mixer", "Left Headphone Mixer"},
1426
1427 /*
1428 * Disable this for lowest power if bypassing
1429 * the DAC with an analog signal
1430 */
1431 {"HP Left Out", NULL, "DACL"},
1432 {"HP Left Out", NULL, "MIXHPLSEL Mux"},
1433
1434 {"MIXHPRSEL Mux", "HP Mixer", "Right Headphone Mixer"},
1435
1436 /*
1437 * Disable this for lowest power if bypassing
1438 * the DAC with an analog signal
1439 */
1440 {"HP Right Out", NULL, "DACR"},
1441 {"HP Right Out", NULL, "MIXHPRSEL Mux"},
1442
1443 {"SPK Left Out", NULL, "Left Speaker Mixer"},
1444 {"SPK Right Out", NULL, "Right Speaker Mixer"},
1445 {"RCV Left Out", NULL, "Left Receiver Mixer"},
1446
1447 {"LINMOD Mux", "Left and Right", "Right Receiver Mixer"},
1448 {"LINMOD Mux", "Left Only", "Left Receiver Mixer"},
1449 {"RCV Right Out", NULL, "LINMOD Mux"},
1450
1451 {"HPL", NULL, "HP Left Out"},
1452 {"HPR", NULL, "HP Right Out"},
1453 {"SPKL", NULL, "SPK Left Out"},
1454 {"SPKR", NULL, "SPK Right Out"},
1455 {"RCVL", NULL, "RCV Left Out"},
1456 {"RCVR", NULL, "RCV Right Out"},
298 1457
299 /* DAC */
300 SND_SOC_DAPM_DAC("DACL", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 0, 0),
301 SND_SOC_DAPM_DAC("DACR", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 1, 0),
302}; 1458};
303 1459
304static struct snd_soc_dapm_route max98090_audio_map[] = { 1460static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
305 /* Output */ 1461
306 {"HPL", NULL, "HPL Out"}, 1462 /* DMIC inputs */
307 {"HPR", NULL, "HPR Out"}, 1463 {"DMIC3", NULL, "DMIC3_ENA"},
1464 {"DMIC4", NULL, "DMIC4_ENA"},
1465 {"DMIC3", NULL, "AHPF"},
1466 {"DMIC4", NULL, "AHPF"},
1467
1468};
1469
1470static int max98090_add_widgets(struct snd_soc_codec *codec)
1471{
1472 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
1473 struct snd_soc_dapm_context *dapm = &codec->dapm;
1474
1475 snd_soc_add_codec_controls(codec, max98090_snd_controls,
1476 ARRAY_SIZE(max98090_snd_controls));
308 1477
309 /* PGA */ 1478 if (max98090->devtype == MAX98091) {
310 {"HPL Out", NULL, "HPL Mixer"}, 1479 snd_soc_add_codec_controls(codec, max98091_snd_controls,
311 {"HPR Out", NULL, "HPR Mixer"}, 1480 ARRAY_SIZE(max98091_snd_controls));
1481 }
1482
1483 snd_soc_dapm_new_controls(dapm, max98090_dapm_widgets,
1484 ARRAY_SIZE(max98090_dapm_widgets));
1485
1486 snd_soc_dapm_add_routes(dapm, max98090_dapm_routes,
1487 ARRAY_SIZE(max98090_dapm_routes));
1488
1489 if (max98090->devtype == MAX98091) {
1490 snd_soc_dapm_new_controls(dapm, max98091_dapm_widgets,
1491 ARRAY_SIZE(max98091_dapm_widgets));
1492
1493 snd_soc_dapm_add_routes(dapm, max98091_dapm_routes,
1494 ARRAY_SIZE(max98091_dapm_routes));
1495
1496 }
312 1497
313 /* Mixer*/ 1498 return 0;
314 {"HPL Mixer", "DACR Switch", "DACR"}, 1499}
315 {"HPL Mixer", "DACL Switch", "DACL"}, 1500
1501static const int pclk_rates[] = {
1502 12000000, 12000000, 13000000, 13000000,
1503 16000000, 16000000, 19200000, 19200000
1504};
1505
1506static const int lrclk_rates[] = {
1507 8000, 16000, 8000, 16000,
1508 8000, 16000, 8000, 16000
1509};
316 1510
317 {"HPR Mixer", "DACR Switch", "DACR"}, 1511static const int user_pclk_rates[] = {
318 {"HPR Mixer", "DACL Switch", "DACL"}, 1512 13000000, 13000000
319}; 1513};
320 1514
321static bool max98090_volatile(struct device *dev, unsigned int reg) 1515static const int user_lrclk_rates[] = {
1516 44100, 48000
1517};
1518
1519static const unsigned long long ni_value[] = {
1520 3528, 768
1521};
1522
1523static const unsigned long long mi_value[] = {
1524 8125, 1625
1525};
1526
1527static void max98090_configure_bclk(struct snd_soc_codec *codec)
322{ 1528{
323 if ((reg == MAX98090_0x01_INT_STS) || 1529 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
324 (reg == MAX98090_0x02_JACK_STS) || 1530 unsigned long long ni;
325 (reg > MAX98090_REG_MAX_CACHED)) 1531 int i;
326 return true; 1532
1533 if (!max98090->sysclk) {
1534 dev_err(codec->dev, "No SYSCLK configured\n");
1535 return;
1536 }
1537
1538 if (!max98090->bclk || !max98090->lrclk) {
1539 dev_err(codec->dev, "No audio clocks configured\n");
1540 return;
1541 }
1542
1543 /* Skip configuration when operating as slave */
1544 if (!(snd_soc_read(codec, M98090_REG_MASTER_MODE) &
1545 M98090_MAS_MASK)) {
1546 return;
1547 }
327 1548
328 return false; 1549 /* Check for supported PCLK to LRCLK ratios */
1550 for (i = 0; i < ARRAY_SIZE(pclk_rates); i++) {
1551 if ((pclk_rates[i] == max98090->sysclk) &&
1552 (lrclk_rates[i] == max98090->lrclk)) {
1553 dev_dbg(codec->dev,
1554 "Found supported PCLK to LRCLK rates 0x%x\n",
1555 i + 0x8);
1556
1557 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1558 M98090_FREQ_MASK,
1559 (i + 0x8) << M98090_FREQ_SHIFT);
1560 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1561 M98090_USE_M1_MASK, 0);
1562 return;
1563 }
1564 }
1565
1566 /* Check for user calculated MI and NI ratios */
1567 for (i = 0; i < ARRAY_SIZE(user_pclk_rates); i++) {
1568 if ((user_pclk_rates[i] == max98090->sysclk) &&
1569 (user_lrclk_rates[i] == max98090->lrclk)) {
1570 dev_dbg(codec->dev,
1571 "Found user supported PCLK to LRCLK rates\n");
1572 dev_dbg(codec->dev, "i %d ni %lld mi %lld\n",
1573 i, ni_value[i], mi_value[i]);
1574
1575 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1576 M98090_FREQ_MASK, 0);
1577 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1578 M98090_USE_M1_MASK,
1579 1 << M98090_USE_M1_SHIFT);
1580
1581 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
1582 (ni_value[i] >> 8) & 0x7F);
1583 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB,
1584 ni_value[i] & 0xFF);
1585 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_MSB,
1586 (mi_value[i] >> 8) & 0x7F);
1587 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_MI_LSB,
1588 mi_value[i] & 0xFF);
1589
1590 return;
1591 }
1592 }
1593
1594 /*
1595 * Calculate based on MI = 65536 (not as good as either method above)
1596 */
1597 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1598 M98090_FREQ_MASK, 0);
1599 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1600 M98090_USE_M1_MASK, 0);
1601
1602 /*
1603 * Configure NI when operating as master
1604 * Note: There is a small, but significant audio quality improvement
1605 * by calculating ni and mi.
1606 */
1607 ni = 65536ULL * (max98090->lrclk < 50000 ? 96ULL : 48ULL)
1608 * (unsigned long long int)max98090->lrclk;
1609 do_div(ni, (unsigned long long int)max98090->sysclk);
1610 dev_info(codec->dev, "No better method found\n");
1611 dev_info(codec->dev, "Calculating ni %lld with mi 65536\n", ni);
1612 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_MSB,
1613 (ni >> 8) & 0x7F);
1614 snd_soc_write(codec, M98090_REG_CLOCK_RATIO_NI_LSB, ni & 0xFF);
329} 1615}
330 1616
331static int max98090_dai_hw_params(struct snd_pcm_substream *substream, 1617static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
332 struct snd_pcm_hw_params *params, 1618 unsigned int fmt)
333 struct snd_soc_dai *dai)
334{ 1619{
335 struct snd_soc_codec *codec = dai->codec; 1620 struct snd_soc_codec *codec = codec_dai->codec;
336 unsigned int val; 1621 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
1622 struct max98090_cdata *cdata;
1623 u8 regval;
1624
1625 max98090->dai_fmt = fmt;
1626 cdata = &max98090->dai[0];
1627
1628 if (fmt != cdata->fmt) {
1629 cdata->fmt = fmt;
1630
1631 regval = 0;
1632 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1633 case SND_SOC_DAIFMT_CBS_CFS:
1634 /* Set to slave mode PLL - MAS mode off */
1635 snd_soc_write(codec,
1636 M98090_REG_CLOCK_RATIO_NI_MSB, 0x00);
1637 snd_soc_write(codec,
1638 M98090_REG_CLOCK_RATIO_NI_LSB, 0x00);
1639 snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE,
1640 M98090_USE_M1_MASK, 0);
1641 break;
1642 case SND_SOC_DAIFMT_CBM_CFM:
1643 /* Set to master mode */
1644 if (max98090->tdm_slots == 4) {
1645 /* TDM */
1646 regval |= M98090_MAS_MASK |
1647 M98090_BSEL_64;
1648 } else if (max98090->tdm_slots == 3) {
1649 /* TDM */
1650 regval |= M98090_MAS_MASK |
1651 M98090_BSEL_48;
1652 } else {
1653 /* Few TDM slots, or No TDM */
1654 regval |= M98090_MAS_MASK |
1655 M98090_BSEL_32;
1656 }
1657 break;
1658 case SND_SOC_DAIFMT_CBS_CFM:
1659 case SND_SOC_DAIFMT_CBM_CFS:
1660 default:
1661 dev_err(codec->dev, "DAI clock mode unsupported");
1662 return -EINVAL;
1663 }
1664 snd_soc_write(codec, M98090_REG_MASTER_MODE, regval);
1665
1666 regval = 0;
1667 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1668 case SND_SOC_DAIFMT_I2S:
1669 regval |= M98090_DLY_MASK;
1670 break;
1671 case SND_SOC_DAIFMT_LEFT_J:
1672 break;
1673 case SND_SOC_DAIFMT_RIGHT_J:
1674 regval |= M98090_RJ_MASK;
1675 break;
1676 case SND_SOC_DAIFMT_DSP_A:
1677 /* Not supported mode */
1678 default:
1679 dev_err(codec->dev, "DAI format unsupported");
1680 return -EINVAL;
1681 }
1682
1683 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1684 case SND_SOC_DAIFMT_NB_NF:
1685 break;
1686 case SND_SOC_DAIFMT_NB_IF:
1687 regval |= M98090_WCI_MASK;
1688 break;
1689 case SND_SOC_DAIFMT_IB_NF:
1690 regval |= M98090_BCI_MASK;
1691 break;
1692 case SND_SOC_DAIFMT_IB_IF:
1693 regval |= M98090_BCI_MASK|M98090_WCI_MASK;
1694 break;
1695 default:
1696 dev_err(codec->dev, "DAI invert mode unsupported");
1697 return -EINVAL;
1698 }
1699
1700 /*
1701 * This accommodates an inverted logic in the MAX98090 chip
1702 * for Bit Clock Invert (BCI). The inverted logic is only
1703 * seen for the case of TDM mode. The remaining cases have
1704 * normal logic.
1705 */
1706 if (max98090->tdm_slots > 1) {
1707 regval ^= M98090_BCI_MASK;
1708 }
1709
1710 snd_soc_write(codec,
1711 M98090_REG_INTERFACE_FORMAT, regval);
1712 }
337 1713
338 switch (params_rate(params)) { 1714 return 0;
339 case 96000: 1715}
340 val = 1 << 5; 1716
341 break; 1717static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
342 case 32000: 1718 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
343 val = 1 << 4; 1719{
344 break; 1720 struct snd_soc_codec *codec = codec_dai->codec;
345 case 48000: 1721 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
346 val = 1 << 3; 1722 struct max98090_cdata *cdata;
1723 cdata = &max98090->dai[0];
1724
1725 if (slots < 0 || slots > 4)
1726 return -EINVAL;
1727
1728 max98090->tdm_slots = slots;
1729 max98090->tdm_width = slot_width;
1730
1731 if (max98090->tdm_slots > 1) {
1732 /* SLOTL SLOTR SLOTDLY */
1733 snd_soc_write(codec, M98090_REG_TDM_FORMAT,
1734 0 << M98090_TDM_SLOTL_SHIFT |
1735 1 << M98090_TDM_SLOTR_SHIFT |
1736 0 << M98090_TDM_SLOTDLY_SHIFT);
1737
1738 /* FSW TDM */
1739 snd_soc_update_bits(codec, M98090_REG_TDM_CONTROL,
1740 M98090_TDM_MASK,
1741 M98090_TDM_MASK);
1742 }
1743
1744 /*
1745 * Normally advisable to set TDM first, but this permits either order
1746 */
1747 cdata->fmt = 0;
1748 max98090_dai_set_fmt(codec_dai, max98090->dai_fmt);
1749
1750 return 0;
1751}
1752
1753static int max98090_set_bias_level(struct snd_soc_codec *codec,
1754 enum snd_soc_bias_level level)
1755{
1756 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
1757 int ret;
1758
1759 switch (level) {
1760 case SND_SOC_BIAS_ON:
1761 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1762 ret = regcache_sync(max98090->regmap);
1763
1764 if (ret != 0) {
1765 dev_err(codec->dev,
1766 "Failed to sync cache: %d\n", ret);
1767 return ret;
1768 }
1769 }
1770
1771 if (max98090->jack_state == M98090_JACK_STATE_HEADSET) {
1772 /*
1773 * Set to normal bias level.
1774 */
1775 snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
1776 M98090_MBVSEL_MASK, M98090_MBVSEL_2V8);
1777 }
347 break; 1778 break;
348 case 44100: 1779
349 val = 1 << 2; 1780 case SND_SOC_BIAS_PREPARE:
350 break; 1781 break;
351 case 16000: 1782
352 val = 1 << 1; 1783 case SND_SOC_BIAS_STANDBY:
1784 case SND_SOC_BIAS_OFF:
1785 /* Set internal pull-up to lowest power mode */
1786 snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
1787 M98090_JDWK_MASK, M98090_JDWK_MASK);
1788 regcache_mark_dirty(max98090->regmap);
353 break; 1789 break;
354 case 8000: 1790 }
355 val = 1 << 0; 1791 codec->dapm.bias_level = level;
1792 return 0;
1793}
1794
1795static const int comp_pclk_rates[] = {
1796 11289600, 12288000, 12000000, 13000000, 19200000
1797};
1798
1799static const int dmic_micclk[] = {
1800 2, 2, 2, 2, 4, 2
1801};
1802
1803static const int comp_lrclk_rates[] = {
1804 8000, 16000, 32000, 44100, 48000, 96000
1805};
1806
1807static const int dmic_comp[6][6] = {
1808 {7, 8, 3, 3, 3, 3},
1809 {7, 8, 3, 3, 3, 3},
1810 {7, 8, 3, 3, 3, 3},
1811 {7, 8, 3, 1, 1, 1},
1812 {7, 8, 3, 1, 2, 2},
1813 {7, 8, 3, 3, 3, 3}
1814};
1815
1816static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
1817 struct snd_pcm_hw_params *params,
1818 struct snd_soc_dai *dai)
1819{
1820 struct snd_soc_codec *codec = dai->codec;
1821 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
1822 struct max98090_cdata *cdata;
1823 int i, j;
1824
1825 cdata = &max98090->dai[0];
1826 max98090->bclk = snd_soc_params_to_bclk(params);
1827 if (params_channels(params) == 1)
1828 max98090->bclk *= 2;
1829
1830 max98090->lrclk = params_rate(params);
1831
1832 switch (params_format(params)) {
1833 case SNDRV_PCM_FORMAT_S16_LE:
1834 snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT,
1835 M98090_WS_MASK, 0);
356 break; 1836 break;
357 default: 1837 default:
358 dev_err(codec->dev, "unsupported rate\n");
359 return -EINVAL; 1838 return -EINVAL;
360 } 1839 }
361 snd_soc_update_bits(codec, MAX98090_0x05_SAMPLE_RATE, 0x03F, val); 1840
1841 max98090_configure_bclk(codec);
1842
1843 cdata->rate = max98090->lrclk;
1844
1845 /* Update filter mode */
1846 if (max98090->lrclk < 24000)
1847 snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
1848 M98090_MODE_MASK, 0);
1849 else
1850 snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
1851 M98090_MODE_MASK, M98090_MODE_MASK);
1852
1853 /* Update sample rate mode */
1854 if (max98090->lrclk < 50000)
1855 snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
1856 M98090_DHF_MASK, 0);
1857 else
1858 snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
1859 M98090_DHF_MASK, M98090_DHF_MASK);
1860
1861 /* Check for supported PCLK to LRCLK ratios */
1862 for (j = 0; j < ARRAY_SIZE(comp_pclk_rates); j++) {
1863 if (comp_pclk_rates[j] == max98090->sysclk) {
1864 break;
1865 }
1866 }
1867
1868 for (i = 0; i < ARRAY_SIZE(comp_lrclk_rates) - 1; i++) {
1869 if (max98090->lrclk <= (comp_lrclk_rates[i] +
1870 comp_lrclk_rates[i + 1]) / 2) {
1871 break;
1872 }
1873 }
1874
1875 snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_ENABLE,
1876 M98090_MICCLK_MASK,
1877 dmic_micclk[j] << M98090_MICCLK_SHIFT);
1878
1879 snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_CONFIG,
1880 M98090_DMIC_COMP_MASK,
1881 dmic_comp[j][i] << M98090_DMIC_COMP_SHIFT);
362 1882
363 return 0; 1883 return 0;
364} 1884}
365 1885
1886/*
1887 * PLL / Sysclk
1888 */
366static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, 1889static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
367 int clk_id, unsigned int freq, int dir) 1890 int clk_id, unsigned int freq, int dir)
368{ 1891{
369 struct snd_soc_codec *codec = dai->codec; 1892 struct snd_soc_codec *codec = dai->codec;
370 unsigned int val; 1893 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
371 1894
372 snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, 1895 /* Requested clock frequency is already setup */
373 MAX98090_SHDNRUN, 0); 1896 if (freq == max98090->sysclk)
374 1897 return 0;
375 switch (freq) { 1898
376 case 26000000: 1899 /* Setup clocks for slave mode, and using the PLL
377 val = 1 << 7; 1900 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
378 break; 1901 * 0x02 (when master clk is 20MHz to 40MHz)..
379 case 19200000: 1902 * 0x03 (when master clk is 40MHz to 60MHz)..
380 val = 1 << 6; 1903 */
381 break; 1904 if ((freq >= 10000000) && (freq < 20000000)) {
382 case 13000000: 1905 snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
383 val = 1 << 5; 1906 M98090_PSCLK_DIV1);
384 break; 1907 } else if ((freq >= 20000000) && (freq < 40000000)) {
385 case 12288000: 1908 snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
386 val = 1 << 4; 1909 M98090_PSCLK_DIV2);
387 break; 1910 } else if ((freq >= 40000000) && (freq < 60000000)) {
388 case 12000000: 1911 snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
389 val = 1 << 3; 1912 M98090_PSCLK_DIV4);
390 break; 1913 } else {
391 case 11289600:
392 val = 1 << 2;
393 break;
394 default:
395 dev_err(codec->dev, "Invalid master clock frequency\n"); 1914 dev_err(codec->dev, "Invalid master clock frequency\n");
396 return -EINVAL; 1915 return -EINVAL;
397 } 1916 }
398 snd_soc_update_bits(codec, MAX98090_0x04_SYS_CLK, 0xFD, val);
399 1917
400 snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, 1918 max98090->sysclk = freq;
401 MAX98090_SHDNRUN, MAX98090_SHDNRUN);
402 1919
403 dev_dbg(dai->dev, "sysclk is %uHz\n", freq); 1920 max98090_configure_bclk(codec);
404 1921
405 return 0; 1922 return 0;
406} 1923}
407 1924
408static int max98090_dai_set_fmt(struct snd_soc_dai *dai, 1925static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
409 unsigned int fmt)
410{ 1926{
411 struct snd_soc_codec *codec = dai->codec; 1927 struct snd_soc_codec *codec = codec_dai->codec;
412 int is_master; 1928 int regval;
413 u8 val;
414 1929
415 /* master/slave mode */ 1930 regval = mute ? M98090_DVM_MASK : 0;
416 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1931 snd_soc_update_bits(codec, M98090_REG_DAI_PLAYBACK_LEVEL,
417 case SND_SOC_DAIFMT_CBM_CFM: 1932 M98090_DVM_MASK, regval);
418 is_master = 1; 1933
419 break; 1934 return 0;
420 case SND_SOC_DAIFMT_CBS_CFS: 1935}
421 is_master = 0; 1936
422 break; 1937static void max98090_jack_work(struct work_struct *work)
423 default: 1938{
424 dev_err(codec->dev, "unsupported clock\n"); 1939 struct max98090_priv *max98090 = container_of(work,
425 return -EINVAL; 1940 struct max98090_priv,
1941 jack_work.work);
1942 struct snd_soc_codec *codec = max98090->codec;
1943 struct snd_soc_dapm_context *dapm = &codec->dapm;
1944 int status = 0;
1945 int reg;
1946
1947 /* Read a second time */
1948 if (max98090->jack_state == M98090_JACK_STATE_NO_HEADSET) {
1949
1950 /* Strong pull up allows mic detection */
1951 snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
1952 M98090_JDWK_MASK, 0);
1953
1954 msleep(50);
1955
1956 reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
1957
1958 /* Weak pull up allows only insertion detection */
1959 snd_soc_update_bits(codec, M98090_REG_JACK_DETECT,
1960 M98090_JDWK_MASK, M98090_JDWK_MASK);
1961 } else {
1962 reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
426 } 1963 }
427 1964
428 /* format */ 1965 reg = snd_soc_read(codec, M98090_REG_JACK_STATUS);
429 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1966
430 case SND_SOC_DAIFMT_I2S: 1967 switch (reg & (M98090_LSNS_MASK | M98090_JKSNS_MASK)) {
431 val = (is_master) ? MAX98090_I2S_M : MAX98090_I2S_S; 1968 case M98090_LSNS_MASK | M98090_JKSNS_MASK:
432 break; 1969 dev_dbg(codec->dev, "No Headset Detected\n");
433 case SND_SOC_DAIFMT_RIGHT_J: 1970
434 val = (is_master) ? MAX98090_RJ_M : MAX98090_RJ_S; 1971 max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
435 break; 1972
436 case SND_SOC_DAIFMT_LEFT_J: 1973 status |= 0;
437 val = (is_master) ? MAX98090_LJ_M : MAX98090_LJ_S; 1974
438 break; 1975 break;
439 default: 1976
440 dev_err(codec->dev, "unsupported format\n"); 1977 case 0:
441 return -EINVAL; 1978 if (max98090->jack_state ==
1979 M98090_JACK_STATE_HEADSET) {
1980
1981 dev_dbg(codec->dev,
1982 "Headset Button Down Detected\n");
1983
1984 /*
1985 * max98090_headset_button_event(codec)
1986 * could be defined, then called here.
1987 */
1988
1989 status |= SND_JACK_HEADSET;
1990 status |= SND_JACK_BTN_0;
1991
1992 break;
1993 }
1994
1995 /* Line is reported as Headphone */
1996 /* Nokia Headset is reported as Headphone */
1997 /* Mono Headphone is reported as Headphone */
1998 dev_dbg(codec->dev, "Headphone Detected\n");
1999
2000 max98090->jack_state = M98090_JACK_STATE_HEADPHONE;
2001
2002 status |= SND_JACK_HEADPHONE;
2003
2004 break;
2005
2006 case M98090_JKSNS_MASK:
2007 dev_dbg(codec->dev, "Headset Detected\n");
2008
2009 max98090->jack_state = M98090_JACK_STATE_HEADSET;
2010
2011 status |= SND_JACK_HEADSET;
2012
2013 break;
2014
2015 default:
2016 dev_dbg(codec->dev, "Unrecognized Jack Status\n");
2017 break;
2018 }
2019
2020 snd_soc_jack_report(max98090->jack, status,
2021 SND_JACK_HEADSET | SND_JACK_BTN_0);
2022
2023 snd_soc_dapm_sync(dapm);
2024}
2025
2026static irqreturn_t max98090_interrupt(int irq, void *data)
2027{
2028 struct snd_soc_codec *codec = data;
2029 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
2030 int ret;
2031 unsigned int mask;
2032 unsigned int active;
2033
2034 dev_dbg(codec->dev, "***** max98090_interrupt *****\n");
2035
2036 ret = regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask);
2037
2038 if (ret != 0) {
2039 dev_err(codec->dev,
2040 "failed to read M98090_REG_INTERRUPT_S: %d\n",
2041 ret);
2042 return IRQ_NONE;
2043 }
2044
2045 ret = regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &active);
2046
2047 if (ret != 0) {
2048 dev_err(codec->dev,
2049 "failed to read M98090_REG_DEVICE_STATUS: %d\n",
2050 ret);
2051 return IRQ_NONE;
2052 }
2053
2054 dev_dbg(codec->dev, "active=0x%02x mask=0x%02x -> active=0x%02x\n",
2055 active, mask, active & mask);
2056
2057 active &= mask;
2058
2059 if (!active)
2060 return IRQ_NONE;
2061
2062 if (active & M98090_CLD_MASK) {
2063 dev_err(codec->dev, "M98090_CLD_MASK\n");
2064 }
2065
2066 if (active & M98090_SLD_MASK) {
2067 dev_dbg(codec->dev, "M98090_SLD_MASK\n");
442 } 2068 }
443 snd_soc_update_bits(codec, MAX98090_0x06_DAI_IF, 2069
444 MAX98090_DAI_IF_MASK, val); 2070 if (active & M98090_ULK_MASK) {
2071 dev_err(codec->dev, "M98090_ULK_MASK\n");
2072 }
2073
2074 if (active & M98090_JDET_MASK) {
2075 dev_dbg(codec->dev, "M98090_JDET_MASK\n");
2076
2077 pm_wakeup_event(codec->dev, 100);
2078
2079 schedule_delayed_work(&max98090->jack_work,
2080 msecs_to_jiffies(100));
2081 }
2082
2083 if (active & M98090_DRCACT_MASK) {
2084 dev_dbg(codec->dev, "M98090_DRCACT_MASK\n");
2085 }
2086
2087 if (active & M98090_DRCCLP_MASK) {
2088 dev_err(codec->dev, "M98090_DRCCLP_MASK\n");
2089 }
2090
2091 return IRQ_HANDLED;
2092}
2093
2094/**
2095 * max98090_mic_detect - Enable microphone detection via the MAX98090 IRQ
2096 *
2097 * @codec: MAX98090 codec
2098 * @jack: jack to report detection events on
2099 *
2100 * Enable microphone detection via IRQ on the MAX98090. If GPIOs are
2101 * being used to bring out signals to the processor then only platform
2102 * data configuration is needed for MAX98090 and processor GPIOs should
2103 * be configured using snd_soc_jack_add_gpios() instead.
2104 *
2105 * If no jack is supplied detection will be disabled.
2106 */
2107int max98090_mic_detect(struct snd_soc_codec *codec,
2108 struct snd_soc_jack *jack)
2109{
2110 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
2111
2112 dev_dbg(codec->dev, "max98090_mic_detect\n");
2113
2114 max98090->jack = jack;
2115 if (jack) {
2116 snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
2117 M98090_IJDET_MASK,
2118 1 << M98090_IJDET_SHIFT);
2119 } else {
2120 snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S,
2121 M98090_IJDET_MASK,
2122 0);
2123 }
2124
2125 /* Send an initial empty report */
2126 snd_soc_jack_report(max98090->jack, 0,
2127 SND_JACK_HEADSET | SND_JACK_BTN_0);
2128
2129 schedule_delayed_work(&max98090->jack_work,
2130 msecs_to_jiffies(100));
445 2131
446 return 0; 2132 return 0;
447} 2133}
2134EXPORT_SYMBOL_GPL(max98090_mic_detect);
448 2135
449#define MAX98090_RATES SNDRV_PCM_RATE_8000_96000 2136#define MAX98090_RATES SNDRV_PCM_RATE_8000_96000
450#define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 2137#define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
451 2138
452static struct snd_soc_dai_ops max98090_dai_ops = { 2139static struct snd_soc_dai_ops max98090_dai_ops = {
453 .set_sysclk = max98090_dai_set_sysclk, 2140 .set_sysclk = max98090_dai_set_sysclk,
454 .set_fmt = max98090_dai_set_fmt, 2141 .set_fmt = max98090_dai_set_fmt,
455 .hw_params = max98090_dai_hw_params, 2142 .set_tdm_slot = max98090_set_tdm_slot,
2143 .hw_params = max98090_dai_hw_params,
2144 .digital_mute = max98090_dai_digital_mute,
456}; 2145};
457 2146
458static struct snd_soc_dai_driver max98090_dai = { 2147static struct snd_soc_dai_driver max98090_dai[] = {
459 .name = "max98090-Hifi", 2148{
2149 .name = "HiFi",
460 .playback = { 2150 .playback = {
461 .stream_name = "Playback", 2151 .stream_name = "HiFi Playback",
462 .channels_min = 1, 2152 .channels_min = 2,
463 .channels_max = 2, 2153 .channels_max = 2,
464 .rates = MAX98090_RATES, 2154 .rates = MAX98090_RATES,
465 .formats = MAX98090_FORMATS, 2155 .formats = MAX98090_FORMATS,
2156 },
2157 .capture = {
2158 .stream_name = "HiFi Capture",
2159 .channels_min = 1,
2160 .channels_max = 2,
2161 .rates = MAX98090_RATES,
2162 .formats = MAX98090_FORMATS,
466 }, 2163 },
467 .ops = &max98090_dai_ops, 2164 .ops = &max98090_dai_ops,
2165}
468}; 2166};
469 2167
2168static void max98090_handle_pdata(struct snd_soc_codec *codec)
2169{
2170 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
2171 struct max98090_pdata *pdata = max98090->pdata;
2172
2173 if (!pdata) {
2174 dev_err(codec->dev, "No platform data\n");
2175 return;
2176 }
2177
2178}
2179
470static int max98090_probe(struct snd_soc_codec *codec) 2180static int max98090_probe(struct snd_soc_codec *codec)
471{ 2181{
472 struct max98090_priv *priv = snd_soc_codec_get_drvdata(codec); 2182 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
473 struct device *dev = codec->dev; 2183 struct max98090_cdata *cdata;
474 int ret; 2184 int ret = 0;
2185
2186 dev_dbg(codec->dev, "max98090_probe\n");
2187
2188 max98090->codec = codec;
2189
2190 codec->control_data = max98090->regmap;
475 2191
476 codec->control_data = priv->regmap;
477 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 2192 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
478 if (ret < 0) { 2193 if (ret != 0) {
479 dev_err(dev, "Failed to set cache I/O: %d\n", ret); 2194 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
480 return ret; 2195 return ret;
481 } 2196 }
482 2197
483 /* Device active */ 2198 /* Reset the codec, the DSP core, and disable all interrupts */
484 snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN, 2199 max98090_reset(max98090);
485 MAX98090_SHDNRUN, MAX98090_SHDNRUN);
486 2200
487 return 0; 2201 /* Initialize private data */
2202
2203 max98090->sysclk = (unsigned)-1;
2204
2205 cdata = &max98090->dai[0];
2206 cdata->rate = (unsigned)-1;
2207 cdata->fmt = (unsigned)-1;
2208
2209 max98090->lin_state = 0;
2210 max98090->pa1en = 0;
2211 max98090->pa2en = 0;
2212 max98090->extmic_mux = 0;
2213
2214 ret = snd_soc_read(codec, M98090_REG_REVISION_ID);
2215 if (ret < 0) {
2216 dev_err(codec->dev, "Failed to read device revision: %d\n",
2217 ret);
2218 goto err_access;
2219 }
2220
2221 if ((ret >= M98090_REVA) && (ret <= M98090_REVA + 0x0f)) {
2222 max98090->devtype = MAX98090;
2223 dev_info(codec->dev, "MAX98090 REVID=0x%02x\n", ret);
2224 } else if ((ret >= M98091_REVA) && (ret <= M98091_REVA + 0x0f)) {
2225 max98090->devtype = MAX98091;
2226 dev_info(codec->dev, "MAX98091 REVID=0x%02x\n", ret);
2227 } else {
2228 max98090->devtype = MAX98090;
2229 dev_err(codec->dev, "Unrecognized revision 0x%02x\n", ret);
2230 }
2231
2232 max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
2233
2234 INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work);
2235
2236 /* Enable jack detection */
2237 snd_soc_write(codec, M98090_REG_JACK_DETECT,
2238 M98090_JDETEN_MASK | M98090_JDEB_25MS);
2239
2240 /* Register for interrupts */
2241 dev_dbg(codec->dev, "irq = %d\n", max98090->irq);
2242
2243 ret = request_threaded_irq(max98090->irq, NULL,
2244 max98090_interrupt, IRQF_TRIGGER_FALLING,
2245 "max98090_interrupt", codec);
2246 if (ret < 0) {
2247 dev_err(codec->dev, "request_irq failed: %d\n",
2248 ret);
2249 }
2250
2251 /*
2252 * Clear any old interrupts.
2253 * An old interrupt ocurring prior to installing the ISR
2254 * can keep a new interrupt from generating a trigger.
2255 */
2256 snd_soc_read(codec, M98090_REG_DEVICE_STATUS);
2257
2258 /* High Performance is default */
2259 snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
2260 M98090_DACHP_MASK,
2261 1 << M98090_DACHP_SHIFT);
2262 snd_soc_update_bits(codec, M98090_REG_DAC_CONTROL,
2263 M98090_PERFMODE_MASK,
2264 0 << M98090_PERFMODE_SHIFT);
2265 snd_soc_update_bits(codec, M98090_REG_ADC_CONTROL,
2266 M98090_ADCHP_MASK,
2267 1 << M98090_ADCHP_SHIFT);
2268
2269 /* Turn on VCM bandgap reference */
2270 snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
2271 M98090_VCM_MODE_MASK);
2272
2273 max98090_handle_pdata(codec);
2274
2275 max98090_add_widgets(codec);
2276
2277err_access:
2278 return ret;
488} 2279}
489 2280
490static int max98090_remove(struct snd_soc_codec *codec) 2281static int max98090_remove(struct snd_soc_codec *codec)
491{ 2282{
2283 struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
2284
2285 cancel_delayed_work_sync(&max98090->jack_work);
2286
492 return 0; 2287 return 0;
493} 2288}
494 2289
495static struct snd_soc_codec_driver soc_codec_dev_max98090 = { 2290static struct snd_soc_codec_driver soc_codec_dev_max98090 = {
496 .probe = max98090_probe, 2291 .probe = max98090_probe,
497 .remove = max98090_remove, 2292 .remove = max98090_remove,
498 .controls = max98090_snd_controls, 2293 .set_bias_level = max98090_set_bias_level,
499 .num_controls = ARRAY_SIZE(max98090_snd_controls),
500 .dapm_widgets = max98090_dapm_widgets,
501 .num_dapm_widgets = ARRAY_SIZE(max98090_dapm_widgets),
502 .dapm_routes = max98090_audio_map,
503 .num_dapm_routes = ARRAY_SIZE(max98090_audio_map),
504}; 2294};
505 2295
506static const struct regmap_config max98090_regmap = { 2296static const struct regmap_config max98090_regmap = {
507 .reg_bits = 8, 2297 .reg_bits = 8,
508 .val_bits = 8, 2298 .val_bits = 8,
509 .max_register = MAX98090_REG_END, 2299
510 .volatile_reg = max98090_volatile, 2300 .max_register = MAX98090_MAX_REGISTER,
511 .cache_type = REGCACHE_RBTREE, 2301 .reg_defaults = max98090_reg,
512 .reg_defaults = max98090_reg_defaults, 2302 .num_reg_defaults = ARRAY_SIZE(max98090_reg),
513 .num_reg_defaults = ARRAY_SIZE(max98090_reg_defaults), 2303 .volatile_reg = max98090_volatile_register,
2304 .readable_reg = max98090_readable_register,
2305 .cache_type = REGCACHE_RBTREE,
514}; 2306};
515 2307
516static int max98090_i2c_probe(struct i2c_client *i2c, 2308static int max98090_i2c_probe(struct i2c_client *i2c,
517 const struct i2c_device_id *id) 2309 const struct i2c_device_id *id)
518{ 2310{
519 struct max98090_priv *priv; 2311 struct max98090_priv *max98090;
520 struct device *dev = &i2c->dev;
521 unsigned int val;
522 int ret; 2312 int ret;
523 2313
524 priv = devm_kzalloc(dev, sizeof(struct max98090_priv), 2314 pr_debug("max98090_i2c_probe\n");
525 GFP_KERNEL);
526 if (!priv)
527 return -ENOMEM;
528
529 priv->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap);
530 if (IS_ERR(priv->regmap)) {
531 ret = PTR_ERR(priv->regmap);
532 dev_err(dev, "Failed to init regmap: %d\n", ret);
533 return ret;
534 }
535 2315
536 i2c_set_clientdata(i2c, priv); 2316 max98090 = devm_kzalloc(&i2c->dev, sizeof(struct max98090_priv),
2317 GFP_KERNEL);
2318 if (max98090 == NULL)
2319 return -ENOMEM;
537 2320
538 ret = regmap_read(priv->regmap, MAX98090_0xFF_REV_ID, &val); 2321 max98090->devtype = id->driver_data;
539 if (ret < 0) { 2322 i2c_set_clientdata(i2c, max98090);
540 dev_err(dev, "Failed to read device revision: %d\n", ret); 2323 max98090->control_data = i2c;
541 return ret; 2324 max98090->pdata = i2c->dev.platform_data;
2325 max98090->irq = i2c->irq;
2326
2327 max98090->regmap = regmap_init_i2c(i2c, &max98090_regmap);
2328 if (IS_ERR(max98090->regmap)) {
2329 ret = PTR_ERR(max98090->regmap);
2330 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
2331 goto err_enable;
542 } 2332 }
543 dev_info(dev, "revision 0x%02x\n", val);
544 2333
545 ret = snd_soc_register_codec(dev, 2334 ret = snd_soc_register_codec(&i2c->dev,
546 &soc_codec_dev_max98090, 2335 &soc_codec_dev_max98090, max98090_dai,
547 &max98090_dai, 1); 2336 ARRAY_SIZE(max98090_dai));
2337 if (ret < 0)
2338 regmap_exit(max98090->regmap);
548 2339
2340err_enable:
549 return ret; 2341 return ret;
550} 2342}
551 2343
552static int max98090_i2c_remove(struct i2c_client *client) 2344static int max98090_i2c_remove(struct i2c_client *client)
553{ 2345{
2346 struct max98090_priv *max98090 = dev_get_drvdata(&client->dev);
554 snd_soc_unregister_codec(&client->dev); 2347 snd_soc_unregister_codec(&client->dev);
2348 regmap_exit(max98090->regmap);
2349 return 0;
2350}
2351
2352static int max98090_runtime_resume(struct device *dev)
2353{
2354 struct max98090_priv *max98090 = dev_get_drvdata(dev);
2355
2356 regcache_cache_only(max98090->regmap, false);
2357
2358 regcache_sync(max98090->regmap);
2359
555 return 0; 2360 return 0;
556} 2361}
557 2362
2363static int max98090_runtime_suspend(struct device *dev)
2364{
2365 struct max98090_priv *max98090 = dev_get_drvdata(dev);
2366
2367 regcache_cache_only(max98090->regmap, true);
2368
2369 return 0;
2370}
2371
2372static struct dev_pm_ops max98090_pm = {
2373 SET_RUNTIME_PM_OPS(max98090_runtime_suspend,
2374 max98090_runtime_resume, NULL)
2375};
2376
558static const struct i2c_device_id max98090_i2c_id[] = { 2377static const struct i2c_device_id max98090_i2c_id[] = {
559 { "max98090", 0 }, 2378 { "max98090", MAX98090 },
560 { } 2379 { }
561}; 2380};
562MODULE_DEVICE_TABLE(i2c, max98090_i2c_id); 2381MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
@@ -565,13 +2384,15 @@ static struct i2c_driver max98090_i2c_driver = {
565 .driver = { 2384 .driver = {
566 .name = "max98090", 2385 .name = "max98090",
567 .owner = THIS_MODULE, 2386 .owner = THIS_MODULE,
2387 .pm = &max98090_pm,
568 }, 2388 },
569 .probe = max98090_i2c_probe, 2389 .probe = max98090_i2c_probe,
570 .remove = max98090_i2c_remove, 2390 .remove = max98090_i2c_remove,
571 .id_table = max98090_i2c_id, 2391 .id_table = max98090_i2c_id,
572}; 2392};
2393
573module_i2c_driver(max98090_i2c_driver); 2394module_i2c_driver(max98090_i2c_driver);
574 2395
575MODULE_DESCRIPTION("ALSA SoC MAX98090 driver"); 2396MODULE_DESCRIPTION("ALSA SoC MAX98090 driver");
576MODULE_AUTHOR("Peter Hsiang, Kuninori Morimoto"); 2397MODULE_AUTHOR("Peter Hsiang, Jesse Marroqin, Jerry Wong");
577MODULE_LICENSE("GPL"); 2398MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h
new file mode 100755
index 000000000000..7e103f249053
--- /dev/null
+++ b/sound/soc/codecs/max98090.h
@@ -0,0 +1,1549 @@
1/*
2 * max98090.h -- MAX98090 ALSA SoC Audio driver
3 *
4 * Copyright 2011-2012 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98090_H
12#define _MAX98090_H
13
14#include <linux/version.h>
15
16/* One can override the Linux version here with an explicit version number */
17#define M98090_LINUX_VERSION LINUX_VERSION_CODE
18
19/*
20 * MAX98090 Register Definitions
21 */
22
23#define M98090_REG_SOFTWARE_RESET 0x00
24#define M98090_REG_DEVICE_STATUS 0x01
25#define M98090_REG_JACK_STATUS 0x02
26#define M98090_REG_INTERRUPT_S 0x03
27#define M98090_REG_QUICK_SYSTEM_CLOCK 0x04
28#define M98090_REG_QUICK_SAMPLE_RATE 0x05
29#define M98090_REG_DAI_INTERFACE 0x06
30#define M98090_REG_DAC_PATH 0x07
31#define M98090_REG_MIC_DIRECT_TO_ADC 0x08
32#define M98090_REG_LINE_TO_ADC 0x09
33#define M98090_REG_ANALOG_MIC_LOOP 0x0A
34#define M98090_REG_ANALOG_LINE_LOOP 0x0B
35#define M98090_REG_RESERVED 0x0C
36#define M98090_REG_LINE_INPUT_CONFIG 0x0D
37#define M98090_REG_LINE_INPUT_LEVEL 0x0E
38#define M98090_REG_INPUT_MODE 0x0F
39#define M98090_REG_MIC1_INPUT_LEVEL 0x10
40#define M98090_REG_MIC2_INPUT_LEVEL 0x11
41#define M98090_REG_MIC_BIAS_VOLTAGE 0x12
42#define M98090_REG_DIGITAL_MIC_ENABLE 0x13
43#define M98090_REG_DIGITAL_MIC_CONFIG 0x14
44#define M98090_REG_LEFT_ADC_MIXER 0x15
45#define M98090_REG_RIGHT_ADC_MIXER 0x16
46#define M98090_REG_LEFT_ADC_LEVEL 0x17
47#define M98090_REG_RIGHT_ADC_LEVEL 0x18
48#define M98090_REG_ADC_BIQUAD_LEVEL 0x19
49#define M98090_REG_ADC_SIDETONE 0x1A
50#define M98090_REG_SYSTEM_CLOCK 0x1B
51#define M98090_REG_CLOCK_MODE 0x1C
52#define M98090_REG_CLOCK_RATIO_NI_MSB 0x1D
53#define M98090_REG_CLOCK_RATIO_NI_LSB 0x1E
54#define M98090_REG_CLOCK_RATIO_MI_MSB 0x1F
55#define M98090_REG_CLOCK_RATIO_MI_LSB 0x20
56#define M98090_REG_MASTER_MODE 0x21
57#define M98090_REG_INTERFACE_FORMAT 0x22
58#define M98090_REG_TDM_CONTROL 0x23
59#define M98090_REG_TDM_FORMAT 0x24
60#define M98090_REG_IO_CONFIGURATION 0x25
61#define M98090_REG_FILTER_CONFIG 0x26
62#define M98090_REG_DAI_PLAYBACK_LEVEL 0x27
63#define M98090_REG_DAI_PLAYBACK_LEVEL_EQ 0x28
64#define M98090_REG_LEFT_HP_MIXER 0x29
65#define M98090_REG_RIGHT_HP_MIXER 0x2A
66#define M98090_REG_HP_CONTROL 0x2B
67#define M98090_REG_LEFT_HP_VOLUME 0x2C
68#define M98090_REG_RIGHT_HP_VOLUME 0x2D
69#define M98090_REG_LEFT_SPK_MIXER 0x2E
70#define M98090_REG_RIGHT_SPK_MIXER 0x2F
71#define M98090_REG_SPK_CONTROL 0x30
72#define M98090_REG_LEFT_SPK_VOLUME 0x31
73#define M98090_REG_RIGHT_SPK_VOLUME 0x32
74#define M98090_REG_DRC_TIMING 0x33
75#define M98090_REG_DRC_COMPRESSOR 0x34
76#define M98090_REG_DRC_EXPANDER 0x35
77#define M98090_REG_DRC_GAIN 0x36
78#define M98090_REG_RCV_LOUTL_MIXER 0x37
79#define M98090_REG_RCV_LOUTL_CONTROL 0x38
80#define M98090_REG_RCV_LOUTL_VOLUME 0x39
81#define M98090_REG_LOUTR_MIXER 0x3A
82#define M98090_REG_LOUTR_CONTROL 0x3B
83#define M98090_REG_LOUTR_VOLUME 0x3C
84#define M98090_REG_JACK_DETECT 0x3D
85#define M98090_REG_INPUT_ENABLE 0x3E
86#define M98090_REG_OUTPUT_ENABLE 0x3F
87#define M98090_REG_LEVEL_CONTROL 0x40
88#define M98090_REG_DSP_FILTER_ENABLE 0x41
89#define M98090_REG_BIAS_CONTROL 0x42
90#define M98090_REG_DAC_CONTROL 0x43
91#define M98090_REG_ADC_CONTROL 0x44
92#define M98090_REG_DEVICE_SHUTDOWN 0x45
93#define M98090_REG_EQUALIZER_BASE 0x46
94#define M98090_REG_RECORD_BIQUAD_BASE 0xAF
95#define M98090_REG_DMIC3_VOLUME 0xBE
96#define M98090_REG_DMIC4_VOLUME 0xBF
97#define M98090_REG_DMIC34_BQ_PREATTEN 0xC0
98#define M98090_REG_RECORD_TDM_SLOT 0xC1
99#define M98090_REG_SAMPLE_RATE 0xC2
100#define M98090_REG_DMIC34_BIQUAD_BASE 0xC3
101#define M98090_REG_REVISION_ID 0xFF
102
103#define M98090_REG_CNT (0xFF+1)
104#define MAX98090_MAX_REGISTER 0xFF
105
106/* MAX98090 Register Bit Fields */
107
108/*
109 * M98090_REG_SOFTWARE_RESET
110 */
111#define M98090_SWRESET_MASK (1<<7)
112#define M98090_SWRESET_SHIFT 7
113#define M98090_SWRESET_WIDTH 1
114
115/*
116 * M98090_REG_DEVICE_STATUS
117 */
118#define M98090_CLD_MASK (1<<7)
119#define M98090_CLD_SHIFT 7
120#define M98090_CLD_WIDTH 1
121#define M98090_SLD_MASK (1<<6)
122#define M98090_SLD_SHIFT 6
123#define M98090_SLD_WIDTH 1
124#define M98090_ULK_MASK (1<<5)
125#define M98090_ULK_SHIFT 5
126#define M98090_ULK_WIDTH 1
127#define M98090_JDET_MASK (1<<2)
128#define M98090_JDET_SHIFT 2
129#define M98090_JDET_WIDTH 1
130#define M98090_DRCACT_MASK (1<<1)
131#define M98090_DRCACT_SHIFT 1
132#define M98090_DRCACT_WIDTH 1
133#define M98090_DRCCLP_MASK (1<<0)
134#define M98090_DRCCLP_SHIFT 0
135#define M98090_DRCCLP_WIDTH 1
136
137/*
138 * M98090_REG_JACK_STATUS
139 */
140#define M98090_LSNS_MASK (1<<2)
141#define M98090_LSNS_SHIFT 2
142#define M98090_LSNS_WIDTH 1
143#define M98090_JKSNS_MASK (1<<1)
144#define M98090_JKSNS_SHIFT 1
145#define M98090_JKSNS_WIDTH 1
146
147/*
148 * M98090_REG_INTERRUPT_S
149 */
150#define M98090_ICLD_MASK (1<<7)
151#define M98090_ICLD_SHIFT 7
152#define M98090_ICLD_WIDTH 1
153#define M98090_ISLD_MASK (1<<6)
154#define M98090_ISLD_SHIFT 6
155#define M98090_ISLD_WIDTH 1
156#define M98090_IULK_MASK (1<<5)
157#define M98090_IULK_SHIFT 5
158#define M98090_IULK_WIDTH 1
159#define M98090_IJDET_MASK (1<<2)
160#define M98090_IJDET_SHIFT 2
161#define M98090_IJDET_WIDTH 1
162#define M98090_IDRCACT_MASK (1<<1)
163#define M98090_IDRCACT_SHIFT 1
164#define M98090_IDRCACT_WIDTH 1
165#define M98090_IDRCCLP_MASK (1<<0)
166#define M98090_IDRCCLP_SHIFT 0
167#define M98090_IDRCCLP_WIDTH 1
168
169/*
170 * M98090_REG_QUICK_SYSTEM_CLOCK
171 */
172#define M98090_26M_MASK (1<<7)
173#define M98090_26M_SHIFT 7
174#define M98090_26M_WIDTH 1
175#define M98090_19P2M_MASK (1<<6)
176#define M98090_19P2M_SHIFT 6
177#define M98090_19P2M_WIDTH 1
178#define M98090_13M_MASK (1<<5)
179#define M98090_13M_SHIFT 5
180#define M98090_13M_WIDTH 1
181#define M98090_12P288M_MASK (1<<4)
182#define M98090_12P288M_SHIFT 4
183#define M98090_12P288M_WIDTH 1
184#define M98090_12M_MASK (1<<3)
185#define M98090_12M_SHIFT 3
186#define M98090_12M_WIDTH 1
187#define M98090_11P2896M_MASK (1<<2)
188#define M98090_11P2896M_SHIFT 2
189#define M98090_11P2896M_WIDTH 1
190#define M98090_256FS_MASK (1<<0)
191#define M98090_256FS_SHIFT 0
192#define M98090_256FS_WIDTH 1
193#define M98090_CLK_ALL_SHIFT 0
194#define M98090_CLK_ALL_WIDTH 8
195#define M98090_CLK_ALL_NUM (1<<M98090_CLK_ALL_WIDTH)
196
197/*
198 * M98090_REG_QUICK_SAMPLE_RATE
199 */
200#define M98090_SR_96K_MASK (1<<5)
201#define M98090_SR_96K_SHIFT 5
202#define M98090_SR_96K_WIDTH 1
203#define M98090_SR_32K_MASK (1<<4)
204#define M98090_SR_32K_SHIFT 4
205#define M98090_SR_32K_WIDTH 1
206#define M98090_SR_48K_MASK (1<<3)
207#define M98090_SR_48K_SHIFT 3
208#define M98090_SR_48K_WIDTH 1
209#define M98090_SR_44K1_MASK (1<<2)
210#define M98090_SR_44K1_SHIFT 2
211#define M98090_SR_44K1_WIDTH 1
212#define M98090_SR_16K_MASK (1<<1)
213#define M98090_SR_16K_SHIFT 1
214#define M98090_SR_16K_WIDTH 1
215#define M98090_SR_8K_MASK (1<<0)
216#define M98090_SR_8K_SHIFT 0
217#define M98090_SR_8K_WIDTH 1
218#define M98090_SR_MASK 0x3F
219#define M98090_SR_ALL_SHIFT 0
220#define M98090_SR_ALL_WIDTH 8
221#define M98090_SR_ALL_NUM (1<<M98090_SR_ALL_WIDTH)
222
223/*
224 * M98090_REG_DAI_INTERFACE
225 */
226#define M98090_RJ_M_MASK (1<<5)
227#define M98090_RJ_M_SHIFT 5
228#define M98090_RJ_M_WIDTH 1
229#define M98090_RJ_S_MASK (1<<4)
230#define M98090_RJ_S_SHIFT 4
231#define M98090_RJ_S_WIDTH 1
232#define M98090_LJ_M_MASK (1<<3)
233#define M98090_LJ_M_SHIFT 3
234#define M98090_LJ_M_WIDTH 1
235#define M98090_LJ_S_MASK (1<<2)
236#define M98090_LJ_S_SHIFT 2
237#define M98090_LJ_S_WIDTH 1
238#define M98090_I2S_M_MASK (1<<1)
239#define M98090_I2S_M_SHIFT 1
240#define M98090_I2S_M_WIDTH 1
241#define M98090_I2S_S_MASK (1<<0)
242#define M98090_I2S_S_SHIFT 0
243#define M98090_I2S_S_WIDTH 1
244#define M98090_DAI_ALL_SHIFT 0
245#define M98090_DAI_ALL_WIDTH 8
246#define M98090_DAI_ALL_NUM (1<<M98090_DAI_ALL_WIDTH)
247
248/*
249 * M98090_REG_DAC_PATH
250 */
251#define M98090_DIG2_HP_MASK (1<<7)
252#define M98090_DIG2_HP_SHIFT 7
253#define M98090_DIG2_HP_WIDTH 1
254#define M98090_DIG2_EAR_MASK (1<<6)
255#define M98090_DIG2_EAR_SHIFT 6
256#define M98090_DIG2_EAR_WIDTH 1
257#define M98090_DIG2_SPK_MASK (1<<5)
258#define M98090_DIG2_SPK_SHIFT 5
259#define M98090_DIG2_SPK_WIDTH 1
260#define M98090_DIG2_LOUT_MASK (1<<4)
261#define M98090_DIG2_LOUT_SHIFT 4
262#define M98090_DIG2_LOUT_WIDTH 1
263#define M98090_DIG2_ALL_SHIFT 0
264#define M98090_DIG2_ALL_WIDTH 8
265#define M98090_DIG2_ALL_NUM (1<<M98090_DIG2_ALL_WIDTH)
266
267/*
268 * M98090_REG_MIC_DIRECT_TO_ADC
269 */
270#define M98090_IN12_MIC1_MASK (1<<7)
271#define M98090_IN12_MIC1_SHIFT 7
272#define M98090_IN12_MIC1_WIDTH 1
273#define M98090_IN34_MIC2_MASK (1<<6)
274#define M98090_IN34_MIC2_SHIFT 6
275#define M98090_IN34_MIC2_WIDTH 1
276#define M98090_IN56_MIC1_MASK (1<<5)
277#define M98090_IN56_MIC1_SHIFT 5
278#define M98090_IN56_MIC1_WIDTH 1
279#define M98090_IN56_MIC2_MASK (1<<4)
280#define M98090_IN56_MIC2_SHIFT 4
281#define M98090_IN56_MIC2_WIDTH 1
282#define M98090_IN12_DADC_MASK (1<<3)
283#define M98090_IN12_DADC_SHIFT 3
284#define M98090_IN12_DADC_WIDTH 1
285#define M98090_IN34_DADC_MASK (1<<2)
286#define M98090_IN34_DADC_SHIFT 2
287#define M98090_IN34_DADC_WIDTH 1
288#define M98090_IN56_DADC_MASK (1<<1)
289#define M98090_IN56_DADC_SHIFT 1
290#define M98090_IN56_DADC_WIDTH 1
291#define M98090_MIC_ALL_SHIFT 0
292#define M98090_MIC_ALL_WIDTH 8
293#define M98090_MIC_ALL_NUM (1<<M98090_MIC_ALL_WIDTH)
294
295/*
296 * M98090_REG_LINE_TO_ADC
297 */
298#define M98090_IN12S_AB_MASK (1<<7)
299#define M98090_IN12S_AB_SHIFT 7
300#define M98090_IN12S_AB_WIDTH 1
301#define M98090_IN34S_AB_MASK (1<<6)
302#define M98090_IN34S_AB_SHIFT 6
303#define M98090_IN34S_AB_WIDTH 1
304#define M98090_IN56S_AB_MASK (1<<5)
305#define M98090_IN56S_AB_SHIFT 5
306#define M98090_IN56S_AB_WIDTH 1
307#define M98090_IN34D_A_MASK (1<<4)
308#define M98090_IN34D_A_SHIFT 4
309#define M98090_IN34D_A_WIDTH 1
310#define M98090_IN56D_B_MASK (1<<3)
311#define M98090_IN56D_B_SHIFT 3
312#define M98090_IN56D_B_WIDTH 1
313#define M98090_LINE_ALL_SHIFT 0
314#define M98090_LINE_ALL_WIDTH 8
315#define M98090_LINE_ALL_NUM (1<<M98090_LINE_ALL_WIDTH)
316
317/*
318 * M98090_REG_ANALOG_MIC_LOOP
319 */
320#define M98090_IN12_M1HPL_MASK (1<<7)
321#define M98090_IN12_M1HPL_SHIFT 7
322#define M98090_IN12_M1HPL_WIDTH 1
323#define M98090_IN12_M1SPKL_MASK (1<<6)
324#define M98090_IN12_M1SPKL_SHIFT 6
325#define M98090_IN12_M1SPKL_WIDTH 1
326#define M98090_IN12_M1EAR_MASK (1<<5)
327#define M98090_IN12_M1EAR_SHIFT 5
328#define M98090_IN12_M1EAR_WIDTH 1
329#define M98090_IN12_M1LOUTL_MASK (1<<4)
330#define M98090_IN12_M1LOUTL_SHIFT 4
331#define M98090_IN12_M1LOUTL_WIDTH 1
332#define M98090_IN34_M2HPR_MASK (1<<3)
333#define M98090_IN34_M2HPR_SHIFT 3
334#define M98090_IN34_M2HPR_WIDTH 1
335#define M98090_IN34_M2SPKR_MASK (1<<2)
336#define M98090_IN34_M2SPKR_SHIFT 2
337#define M98090_IN34_M2SPKR_WIDTH 1
338#define M98090_IN34_M2EAR_MASK (1<<1)
339#define M98090_IN34_M2EAR_SHIFT 1
340#define M98090_IN34_M2EAR_WIDTH 1
341#define M98090_IN34_M2LOUTR_MASK (1<<0)
342#define M98090_IN34_M2LOUTR_SHIFT 0
343#define M98090_IN34_M2LOUTR_WIDTH 1
344#define M98090_AMIC_ALL_SHIFT 0
345#define M98090_AMIC_ALL_WIDTH 8
346#define M98090_AMIC_ALL_NUM (1<<M98090_AMIC_ALL_WIDTH)
347
348/*
349 * M98090_REG_ANALOG_LINE_LOOP
350 */
351#define M98090_IN12S_ABHP_MASK (1<<7)
352#define M98090_IN12S_ABHP_SHIFT 7
353#define M98090_IN12S_ABHP_WIDTH 1
354#define M98090_IN34D_ASPKL_MASK (1<<6)
355#define M98090_IN34D_ASPKL_SHIFT 6
356#define M98090_IN34D_ASPKL_WIDTH 1
357#define M98090_IN34D_AEAR_MASK (1<<5)
358#define M98090_IN34D_AEAR_SHIFT 5
359#define M98090_IN34D_AEAR_WIDTH 1
360#define M98090_IN12S_ABLOUT_MASK (1<<4)
361#define M98090_IN12S_ABLOUT_SHIFT 4
362#define M98090_IN12S_ABLOUT_WIDTH 1
363#define M98090_IN34S_ABHP_MASK (1<<3)
364#define M98090_IN34S_ABHP_SHIFT 3
365#define M98090_IN34S_ABHP_WIDTH 1
366#define M98090_IN56D_BSPKR_MASK (1<<2)
367#define M98090_IN56D_BSPKR_SHIFT 2
368#define M98090_IN56D_BSPKR_WIDTH 1
369#define M98090_IN56D_BEAR_MASK (1<<1)
370#define M98090_IN56D_BEAR_SHIFT 1
371#define M98090_IN56D_BEAR_WIDTH 1
372#define M98090_IN34S_ABLOUT_MASK (1<<0)
373#define M98090_IN34S_ABLOUT_SHIFT 0
374#define M98090_IN34S_ABLOUT_WIDTH 1
375#define M98090_ALIN_ALL_SHIFT 0
376#define M98090_ALIN_ALL_WIDTH 8
377#define M98090_ALIN_ALL_NUM (1<<M98090_ALIN_ALL_WIDTH)
378
379/*
380 * M98090_REG_RESERVED
381 */
382
383/*
384 * M98090_REG_LINE_INPUT_CONFIG
385 */
386#define M98090_IN34DIFF_MASK (1<<7)
387#define M98090_IN34DIFF_SHIFT 7
388#define M98090_IN34DIFF_WIDTH 1
389#define M98090_IN56DIFF_MASK (1<<6)
390#define M98090_IN56DIFF_SHIFT 6
391#define M98090_IN56DIFF_WIDTH 1
392#define M98090_IN1SEEN_MASK (1<<5)
393#define M98090_IN1SEEN_SHIFT 5
394#define M98090_IN1SEEN_WIDTH 1
395#define M98090_IN2SEEN_MASK (1<<4)
396#define M98090_IN2SEEN_SHIFT 4
397#define M98090_IN2SEEN_WIDTH 1
398#define M98090_IN3SEEN_MASK (1<<3)
399#define M98090_IN3SEEN_SHIFT 3
400#define M98090_IN3SEEN_WIDTH 1
401#define M98090_IN4SEEN_MASK (1<<2)
402#define M98090_IN4SEEN_SHIFT 2
403#define M98090_IN4SEEN_WIDTH 1
404#define M98090_IN5SEEN_MASK (1<<1)
405#define M98090_IN5SEEN_SHIFT 1
406#define M98090_IN5SEEN_WIDTH 1
407#define M98090_IN6SEEN_MASK (1<<0)
408#define M98090_IN6SEEN_SHIFT 0
409#define M98090_IN6SEEN_WIDTH 1
410
411/*
412 * M98090_REG_LINE_INPUT_LEVEL
413 */
414#define M98090_MIXG135_MASK (1<<7)
415#define M98090_MIXG135_SHIFT 7
416#define M98090_MIXG135_WIDTH 1
417#define M98090_MIXG135_NUM (1<<M98090_MIXG135_WIDTH)
418#define M98090_MIXG246_MASK (1<<6)
419#define M98090_MIXG246_SHIFT 6
420#define M98090_MIXG246_WIDTH 1
421#define M98090_MIXG246_NUM (1<<M98090_MIXG246_WIDTH)
422#define M98090_LINAPGA_MASK (7<<3)
423#define M98090_LINAPGA_SHIFT 3
424#define M98090_LINAPGA_WIDTH 3
425#define M98090_LINAPGA_NUM 6
426#define M98090_LINBPGA_MASK (7<<0)
427#define M98090_LINBPGA_SHIFT 0
428#define M98090_LINBPGA_WIDTH 3
429#define M98090_LINBPGA_NUM 6
430
431/*
432 * M98090_REG_INPUT_MODE
433 */
434#define M98090_EXTBUFA_MASK (1<<7)
435#define M98090_EXTBUFA_SHIFT 7
436#define M98090_EXTBUFA_WIDTH 1
437#define M98090_EXTBUFA_NUM (1<<M98090_EXTBUFA_WIDTH)
438#define M98090_EXTBUFB_MASK (1<<6)
439#define M98090_EXTBUFB_SHIFT 6
440#define M98090_EXTBUFB_WIDTH 1
441#define M98090_EXTBUFB_NUM (1<<M98090_EXTBUFB_WIDTH)
442#define M98090_EXTMIC_MASK (3<<0)
443#define M98090_EXTMIC_SHIFT 0
444#define M98090_EXTMIC1_SHIFT 0
445#define M98090_EXTMIC2_SHIFT 1
446#define M98090_EXTMIC_WIDTH 2
447#define M98090_EXTMIC_NONE (0<<0)
448#define M98090_EXTMIC_MIC1 (1<<0)
449#define M98090_EXTMIC_MIC2 (2<<0)
450
451/*
452 * M98090_REG_MIC1_INPUT_LEVEL
453 */
454#define M98090_MIC_PA1EN_MASK (3<<5)
455#define M98090_MIC_PA1EN_SHIFT 5
456#define M98090_MIC_PA1EN_WIDTH 2
457#define M98090_MIC_PA1EN_NUM 3
458#define M98090_MIC_PGAM1_MASK (31<<0)
459#define M98090_MIC_PGAM1_SHIFT 0
460#define M98090_MIC_PGAM1_WIDTH 5
461#define M98090_MIC_PGAM1_NUM 21
462
463/*
464 * M98090_REG_MIC2_INPUT_LEVEL
465 */
466#define M98090_MIC_PA2EN_MASK (3<<5)
467#define M98090_MIC_PA2EN_SHIFT 5
468#define M98090_MIC_PA2EN_WIDTH 2
469#define M98090_MIC_PA2EN_NUM 3
470#define M98090_MIC_PGAM2_MASK (31<<0)
471#define M98090_MIC_PGAM2_SHIFT 0
472#define M98090_MIC_PGAM2_WIDTH 5
473#define M98090_MIC_PGAM2_NUM 21
474
475/*
476 * M98090_REG_MIC_BIAS_VOLTAGE
477 */
478#define M98090_MBVSEL_MASK (3<<0)
479#define M98090_MBVSEL_SHIFT 0
480#define M98090_MBVSEL_WIDTH 2
481#define M98090_MBVSEL_2V8 (3<<0)
482#define M98090_MBVSEL_2V55 (2<<0)
483#define M98090_MBVSEL_2V4 (1<<0)
484#define M98090_MBVSEL_2V2 (0<<0)
485
486/*
487 * M98090_REG_DIGITAL_MIC_ENABLE
488 */
489#define M98090_MICCLK_MASK (7<<4)
490#define M98090_MICCLK_SHIFT 4
491#define M98090_MICCLK_WIDTH 3
492#define M98090_DIGMIC4_MASK (1<<3)
493#define M98090_DIGMIC4_SHIFT 3
494#define M98090_DIGMIC4_WIDTH 1
495#define M98090_DIGMIC4_NUM (1<<M98090_DIGMIC4_WIDTH)
496#define M98090_DIGMIC3_MASK (1<<2)
497#define M98090_DIGMIC3_SHIFT 2
498#define M98090_DIGMIC3_WIDTH 1
499#define M98090_DIGMIC3_NUM (1<<M98090_DIGMIC3_WIDTH)
500#define M98090_DIGMICR_MASK (1<<1)
501#define M98090_DIGMICR_SHIFT 1
502#define M98090_DIGMICR_WIDTH 1
503#define M98090_DIGMICR_NUM (1<<M98090_DIGMICR_WIDTH)
504#define M98090_DIGMICL_MASK (1<<0)
505#define M98090_DIGMICL_SHIFT 0
506#define M98090_DIGMICL_WIDTH 1
507#define M98090_DIGMICL_NUM (1<<M98090_DIGMICL_WIDTH)
508
509/*
510 * M98090_REG_DIGITAL_MIC_CONFIG
511 */
512#define M98090_DMIC_COMP_MASK (15<<4)
513#define M98090_DMIC_COMP_SHIFT 4
514#define M98090_DMIC_COMP_WIDTH 4
515#define M98090_DMIC_COMP_NUM (1<<M98090_DMIC_COMP_WIDTH)
516#define M98090_DMIC_FREQ_MASK (3<<0)
517#define M98090_DMIC_FREQ_SHIFT 0
518#define M98090_DMIC_FREQ_WIDTH 2
519
520/*
521 * M98090_REG_LEFT_ADC_MIXER
522 */
523#define M98090_MIXADL_MIC2_MASK (1<<6)
524#define M98090_MIXADL_MIC2_SHIFT 6
525#define M98090_MIXADL_MIC2_WIDTH 1
526#define M98090_MIXADL_MIC1_MASK (1<<5)
527#define M98090_MIXADL_MIC1_SHIFT 5
528#define M98090_MIXADL_MIC1_WIDTH 1
529#define M98090_MIXADL_LINEB_MASK (1<<4)
530#define M98090_MIXADL_LINEB_SHIFT 4
531#define M98090_MIXADL_LINEB_WIDTH 1
532#define M98090_MIXADL_LINEA_MASK (1<<3)
533#define M98090_MIXADL_LINEA_SHIFT 3
534#define M98090_MIXADL_LINEA_WIDTH 1
535#define M98090_MIXADL_IN65DIFF_MASK (1<<2)
536#define M98090_MIXADL_IN65DIFF_SHIFT 2
537#define M98090_MIXADL_IN65DIFF_WIDTH 1
538#define M98090_MIXADL_IN34DIFF_MASK (1<<1)
539#define M98090_MIXADL_IN34DIFF_SHIFT 1
540#define M98090_MIXADL_IN34DIFF_WIDTH 1
541#define M98090_MIXADL_IN12DIFF_MASK (1<<0)
542#define M98090_MIXADL_IN12DIFF_SHIFT 0
543#define M98090_MIXADL_IN12DIFF_WIDTH 1
544#define M98090_MIXADL_MASK (255<<0)
545#define M98090_MIXADL_SHIFT 0
546#define M98090_MIXADL_WIDTH 8
547
548/*
549 * M98090_REG_RIGHT_ADC_MIXER
550 */
551#define M98090_MIXADR_MIC2_MASK (1<<6)
552#define M98090_MIXADR_MIC2_SHIFT 6
553#define M98090_MIXADR_MIC2_WIDTH 1
554#define M98090_MIXADR_MIC1_MASK (1<<5)
555#define M98090_MIXADR_MIC1_SHIFT 5
556#define M98090_MIXADR_MIC1_WIDTH 1
557#define M98090_MIXADR_LINEB_MASK (1<<4)
558#define M98090_MIXADR_LINEB_SHIFT 4
559#define M98090_MIXADR_LINEB_WIDTH 1
560#define M98090_MIXADR_LINEA_MASK (1<<3)
561#define M98090_MIXADR_LINEA_SHIFT 3
562#define M98090_MIXADR_LINEA_WIDTH 1
563#define M98090_MIXADR_IN65DIFF_MASK (1<<2)
564#define M98090_MIXADR_IN65DIFF_SHIFT 2
565#define M98090_MIXADR_IN65DIFF_WIDTH 1
566#define M98090_MIXADR_IN34DIFF_MASK (1<<1)
567#define M98090_MIXADR_IN34DIFF_SHIFT 1
568#define M98090_MIXADR_IN34DIFF_WIDTH 1
569#define M98090_MIXADR_IN12DIFF_MASK (1<<0)
570#define M98090_MIXADR_IN12DIFF_SHIFT 0
571#define M98090_MIXADR_IN12DIFF_WIDTH 1
572#define M98090_MIXADR_MASK (255<<0)
573#define M98090_MIXADR_SHIFT 0
574#define M98090_MIXADR_WIDTH 8
575
576/*
577 * M98090_REG_LEFT_ADC_LEVEL
578 */
579#define M98090_AVLG_MASK (7<<4)
580#define M98090_AVLG_SHIFT 4
581#define M98090_AVLG_WIDTH 3
582#define M98090_AVLG_NUM (1<<M98090_AVLG_WIDTH)
583#define M98090_AVL_MASK (15<<0)
584#define M98090_AVL_SHIFT 0
585#define M98090_AVL_WIDTH 4
586#define M98090_AVL_NUM (1<<M98090_AVL_WIDTH)
587
588/*
589 * M98090_REG_RIGHT_ADC_LEVEL
590 */
591#define M98090_AVRG_MASK (7<<4)
592#define M98090_AVRG_SHIFT 4
593#define M98090_AVRG_WIDTH 3
594#define M98090_AVRG_NUM (1<<M98090_AVRG_WIDTH)
595#define M98090_AVR_MASK (15<<0)
596#define M98090_AVR_SHIFT 0
597#define M98090_AVR_WIDTH 4
598#define M98090_AVR_NUM (1<<M98090_AVR_WIDTH)
599
600/*
601 * M98090_REG_ADC_BIQUAD_LEVEL
602 */
603#define M98090_AVBQ_MASK (15<<0)
604#define M98090_AVBQ_SHIFT 0
605#define M98090_AVBQ_WIDTH 4
606#define M98090_AVBQ_NUM (1<<M98090_AVBQ_WIDTH)
607
608/*
609 * M98090_REG_ADC_SIDETONE
610 */
611#define M98090_DSTSR_MASK (1<<7)
612#define M98090_DSTSR_SHIFT 7
613#define M98090_DSTSR_WIDTH 1
614#define M98090_DSTSL_MASK (1<<6)
615#define M98090_DSTSL_SHIFT 6
616#define M98090_DSTSL_WIDTH 1
617#define M98090_DVST_MASK (31<<0)
618#define M98090_DVST_SHIFT 0
619#define M98090_DVST_WIDTH 5
620#define M98090_DVST_NUM 31
621
622/*
623 * M98090_REG_SYSTEM_CLOCK
624 */
625#define M98090_PSCLK_MASK (3<<4)
626#define M98090_PSCLK_SHIFT 4
627#define M98090_PSCLK_WIDTH 2
628#define M98090_PSCLK_DISABLED (0<<4)
629#define M98090_PSCLK_DIV1 (1<<4)
630#define M98090_PSCLK_DIV2 (2<<4)
631#define M98090_PSCLK_DIV4 (3<<4)
632
633/*
634 * M98090_REG_CLOCK_MODE
635 */
636#define M98090_FREQ_MASK (15<<4)
637#define M98090_FREQ_SHIFT 4
638#define M98090_FREQ_WIDTH 4
639#define M98090_USE_M1_MASK (1<<0)
640#define M98090_USE_M1_SHIFT 0
641#define M98090_USE_M1_WIDTH 1
642#define M98090_USE_M1_NUM (1<<M98090_USE_M1_WIDTH)
643
644/*
645 * M98090_REG_CLOCK_RATIO_NI_MSB
646 */
647#define M98090_NI_HI_MASK (127<<0)
648#define M98090_NI_HI_SHIFT 0
649#define M98090_NI_HI_WIDTH 7
650#define M98090_NI_HI_NUM (1<<M98090_NI_HI_WIDTH)
651
652/*
653 * M98090_REG_CLOCK_RATIO_NI_LSB
654 */
655#define M98090_NI_LO_MASK (255<<0)
656#define M98090_NI_LO_SHIFT 0
657#define M98090_NI_LO_WIDTH 8
658#define M98090_NI_LO_NUM (1<<M98090_NI_LO_WIDTH)
659
660/*
661 * M98090_REG_CLOCK_RATIO_MI_MSB
662 */
663#define M98090_MI_HI_MASK (255<<0)
664#define M98090_MI_HI_SHIFT 0
665#define M98090_MI_HI_WIDTH 8
666#define M98090_MI_HI_NUM (1<<M98090_MI_HI_WIDTH)
667
668/*
669 * M98090_REG_CLOCK_RATIO_MI_LSB
670 */
671#define M98090_MI_LO_MASK (255<<0)
672#define M98090_MI_LO_SHIFT 0
673#define M98090_MI_LO_WIDTH 8
674#define M98090_MI_LO_NUM (1<<M98090_MI_LO_WIDTH)
675
676/*
677 * M98090_REG_MASTER_MODE
678 */
679#define M98090_MAS_MASK (1<<7)
680#define M98090_MAS_SHIFT 7
681#define M98090_MAS_WIDTH 1
682#define M98090_BSEL_MASK (1<<0)
683#define M98090_BSEL_SHIFT 0
684#define M98090_BSEL_WIDTH 1
685#define M98090_BSEL_32 (1<<0)
686#define M98090_BSEL_48 (2<<0)
687#define M98090_BSEL_64 (3<<0)
688
689/*
690 * M98090_REG_INTERFACE_FORMAT
691 */
692#define M98090_RJ_MASK (1<<5)
693#define M98090_RJ_SHIFT 5
694#define M98090_RJ_WIDTH 1
695#define M98090_WCI_MASK (1<<4)
696#define M98090_WCI_SHIFT 4
697#define M98090_WCI_WIDTH 1
698#define M98090_BCI_MASK (1<<3)
699#define M98090_BCI_SHIFT 3
700#define M98090_BCI_WIDTH 1
701#define M98090_DLY_MASK (1<<2)
702#define M98090_DLY_SHIFT 2
703#define M98090_DLY_WIDTH 1
704#define M98090_WS_MASK (3<<0)
705#define M98090_WS_SHIFT 0
706#define M98090_WS_WIDTH 2
707#define M98090_WS_NUM (1<<M98090_WS_WIDTH)
708
709/*
710 * M98090_REG_TDM_CONTROL
711 */
712#define M98090_FSW_MASK (1<<1)
713#define M98090_FSW_SHIFT 1
714#define M98090_FSW_WIDTH 1
715#define M98090_TDM_MASK (1<<0)
716#define M98090_TDM_SHIFT 0
717#define M98090_TDM_WIDTH 1
718#define M98090_TDM_NUM (1<<M98090_TDM_WIDTH)
719
720/*
721 * M98090_REG_TDM_FORMAT
722 */
723#define M98090_TDM_SLOTL_MASK (3<<6)
724#define M98090_TDM_SLOTL_SHIFT 6
725#define M98090_TDM_SLOTL_WIDTH 2
726#define M98090_TDM_SLOTL_NUM (1<<M98090_TDM_SLOTL_WIDTH)
727#define M98090_TDM_SLOTR_MASK (3<<4)
728#define M98090_TDM_SLOTR_SHIFT 4
729#define M98090_TDM_SLOTR_WIDTH 2
730#define M98090_TDM_SLOTR_NUM (1<<M98090_TDM_SLOTR_WIDTH)
731#define M98090_TDM_SLOTDLY_MASK (15<<0)
732#define M98090_TDM_SLOTDLY_SHIFT 0
733#define M98090_TDM_SLOTDLY_WIDTH 4
734#define M98090_TDM_SLOTDLY_NUM (1<<M98090_TDM_SLOTDLY_WIDTH)
735
736/*
737 * M98090_REG_IO_CONFIGURATION
738 */
739#define M98090_LTEN_MASK (1<<5)
740#define M98090_LTEN_SHIFT 5
741#define M98090_LTEN_WIDTH 1
742#define M98090_LTEN_NUM (1<<M98090_LTEN_WIDTH)
743#define M98090_LBEN_MASK (1<<4)
744#define M98090_LBEN_SHIFT 4
745#define M98090_LBEN_WIDTH 1
746#define M98090_LBEN_NUM (1<<M98090_LBEN_WIDTH)
747#define M98090_DMONO_MASK (1<<3)
748#define M98090_DMONO_SHIFT 3
749#define M98090_DMONO_WIDTH 1
750#define M98090_DMONO_NUM (1<<M98090_DMONO_WIDTH)
751#define M98090_HIZOFF_MASK (1<<2)
752#define M98090_HIZOFF_SHIFT 2
753#define M98090_HIZOFF_WIDTH 1
754#define M98090_HIZOFF_NUM (1<<M98090_HIZOFF_WIDTH)
755#define M98090_SDOEN_MASK (1<<1)
756#define M98090_SDOEN_SHIFT 1
757#define M98090_SDOEN_WIDTH 1
758#define M98090_SDOEN_NUM (1<<M98090_SDOEN_WIDTH)
759#define M98090_SDIEN_MASK (1<<0)
760#define M98090_SDIEN_SHIFT 0
761#define M98090_SDIEN_WIDTH 1
762#define M98090_SDIEN_NUM (1<<M98090_SDIEN_WIDTH)
763
764/*
765 * M98090_REG_FILTER_CONFIG
766 */
767#define M98090_MODE_MASK (1<<7)
768#define M98090_MODE_SHIFT 7
769#define M98090_MODE_WIDTH 1
770#define M98090_AHPF_MASK (1<<6)
771#define M98090_AHPF_SHIFT 6
772#define M98090_AHPF_WIDTH 1
773#define M98090_AHPF_NUM (1<<M98090_AHPF_WIDTH)
774#define M98090_DHPF_MASK (1<<5)
775#define M98090_DHPF_SHIFT 5
776#define M98090_DHPF_WIDTH 1
777#define M98090_DHPF_NUM (1<<M98090_DHPF_WIDTH)
778#define M98090_DHF_MASK (1<<4)
779#define M98090_DHF_SHIFT 4
780#define M98090_DHF_WIDTH 1
781#define M98090_FLT_DMIC34MODE_MASK (1<<3)
782#define M98090_FLT_DMIC34MODE_SHIFT 3
783#define M98090_FLT_DMIC34MODE_WIDTH 1
784#define M98090_FLT_DMIC34HPF_MASK (1<<2)
785#define M98090_FLT_DMIC34HPF_SHIFT 2
786#define M98090_FLT_DMIC34HPF_WIDTH 1
787#define M98090_FLT_DMIC34HPF_NUM (1<<M98090_FLT_DMIC34HPF_WIDTH)
788
789/*
790 * M98090_REG_DAI_PLAYBACK_LEVEL
791 */
792#define M98090_DVM_MASK (1<<7)
793#define M98090_DVM_SHIFT 7
794#define M98090_DVM_WIDTH 1
795#define M98090_DVG_MASK (3<<4)
796#define M98090_DVG_SHIFT 4
797#define M98090_DVG_WIDTH 2
798#define M98090_DVG_NUM (1<<M98090_DVG_WIDTH)
799#define M98090_DV_MASK (15<<0)
800#define M98090_DV_SHIFT 0
801#define M98090_DV_WIDTH 4
802#define M98090_DV_NUM (1<<M98090_DV_WIDTH)
803
804/*
805 * M98090_REG_DAI_PLAYBACK_LEVEL_EQ
806 */
807#define M98090_EQCLPN_MASK (1<<4)
808#define M98090_EQCLPN_SHIFT 4
809#define M98090_EQCLPN_WIDTH 1
810#define M98090_EQCLPN_NUM (1<<M98090_EQCLPN_WIDTH)
811#define M98090_DVEQ_MASK (15<<0)
812#define M98090_DVEQ_SHIFT 0
813#define M98090_DVEQ_WIDTH 4
814#define M98090_DVEQ_NUM (1<<M98090_DVEQ_WIDTH)
815
816/*
817 * M98090_REG_LEFT_HP_MIXER
818 */
819#define M98090_MIXHPL_MIC2_MASK (1<<5)
820#define M98090_MIXHPL_MIC2_SHIFT 5
821#define M98090_MIXHPL_MIC2_WIDTH 1
822#define M98090_MIXHPL_MIC1_MASK (1<<4)
823#define M98090_MIXHPL_MIC1_SHIFT 4
824#define M98090_MIXHPL_MIC1_WIDTH 1
825#define M98090_MIXHPL_LINEB_MASK (1<<3)
826#define M98090_MIXHPL_LINEB_SHIFT 3
827#define M98090_MIXHPL_LINEB_WIDTH 1
828#define M98090_MIXHPL_LINEA_MASK (1<<2)
829#define M98090_MIXHPL_LINEA_SHIFT 2
830#define M98090_MIXHPL_LINEA_WIDTH 1
831#define M98090_MIXHPL_DACR_MASK (1<<1)
832#define M98090_MIXHPL_DACR_SHIFT 1
833#define M98090_MIXHPL_DACR_WIDTH 1
834#define M98090_MIXHPL_DACL_MASK (1<<0)
835#define M98090_MIXHPL_DACL_SHIFT 0
836#define M98090_MIXHPL_DACL_WIDTH 1
837#define M98090_MIXHPL_MASK (63<<0)
838#define M98090_MIXHPL_SHIFT 0
839#define M98090_MIXHPL_WIDTH 6
840
841/*
842 * M98090_REG_RIGHT_HP_MIXER
843 */
844#define M98090_MIXHPR_MIC2_MASK (1<<5)
845#define M98090_MIXHPR_MIC2_SHIFT 5
846#define M98090_MIXHPR_MIC2_WIDTH 1
847#define M98090_MIXHPR_MIC1_MASK (1<<4)
848#define M98090_MIXHPR_MIC1_SHIFT 4
849#define M98090_MIXHPR_MIC1_WIDTH 1
850#define M98090_MIXHPR_LINEB_MASK (1<<3)
851#define M98090_MIXHPR_LINEB_SHIFT 3
852#define M98090_MIXHPR_LINEB_WIDTH 1
853#define M98090_MIXHPR_LINEA_MASK (1<<2)
854#define M98090_MIXHPR_LINEA_SHIFT 2
855#define M98090_MIXHPR_LINEA_WIDTH 1
856#define M98090_MIXHPR_DACR_MASK (1<<1)
857#define M98090_MIXHPR_DACR_SHIFT 1
858#define M98090_MIXHPR_DACR_WIDTH 1
859#define M98090_MIXHPR_DACL_MASK (1<<0)
860#define M98090_MIXHPR_DACL_SHIFT 0
861#define M98090_MIXHPR_DACL_WIDTH 1
862#define M98090_MIXHPR_MASK (63<<0)
863#define M98090_MIXHPR_SHIFT 0
864#define M98090_MIXHPR_WIDTH 6
865
866/*
867 * M98090_REG_HP_CONTROL
868 */
869#define M98090_MIXHPRSEL_MASK (1<<5)
870#define M98090_MIXHPRSEL_SHIFT 5
871#define M98090_MIXHPRSEL_WIDTH 1
872#define M98090_MIXHPLSEL_MASK (1<<4)
873#define M98090_MIXHPLSEL_SHIFT 4
874#define M98090_MIXHPLSEL_WIDTH 1
875#define M98090_MIXHPRG_MASK (3<<2)
876#define M98090_MIXHPRG_SHIFT 2
877#define M98090_MIXHPRG_WIDTH 2
878#define M98090_MIXHPRG_NUM (1<<M98090_MIXHPRG_WIDTH)
879#define M98090_MIXHPLG_MASK (3<<0)
880#define M98090_MIXHPLG_SHIFT 0
881#define M98090_MIXHPLG_WIDTH 2
882#define M98090_MIXHPLG_NUM (1<<M98090_MIXHPLG_WIDTH)
883
884/*
885 * M98090_REG_LEFT_HP_VOLUME
886 */
887#define M98090_HPLM_MASK (1<<7)
888#define M98090_HPLM_SHIFT 7
889#define M98090_HPLM_WIDTH 1
890#define M98090_HPVOLL_MASK (31<<0)
891#define M98090_HPVOLL_SHIFT 0
892#define M98090_HPVOLL_WIDTH 5
893#define M98090_HPVOLL_NUM (1<<M98090_HPVOLL_WIDTH)
894
895/*
896 * M98090_REG_RIGHT_HP_VOLUME
897 */
898#define M98090_HPRM_MASK (1<<7)
899#define M98090_HPRM_SHIFT 7
900#define M98090_HPRM_WIDTH 1
901#define M98090_HPVOLR_MASK (31<<0)
902#define M98090_HPVOLR_SHIFT 0
903#define M98090_HPVOLR_WIDTH 5
904#define M98090_HPVOLR_NUM (1<<M98090_HPVOLR_WIDTH)
905
906/*
907 * M98090_REG_LEFT_SPK_MIXER
908 */
909#define M98090_MIXSPL_MIC2_MASK (1<<5)
910#define M98090_MIXSPL_MIC2_SHIFT 5
911#define M98090_MIXSPL_MIC2_WIDTH 1
912#define M98090_MIXSPL_MIC1_MASK (1<<4)
913#define M98090_MIXSPL_MIC1_SHIFT 4
914#define M98090_MIXSPL_MIC1_WIDTH 1
915#define M98090_MIXSPL_LINEB_MASK (1<<3)
916#define M98090_MIXSPL_LINEB_SHIFT 3
917#define M98090_MIXSPL_LINEB_WIDTH 1
918#define M98090_MIXSPL_LINEA_MASK (1<<2)
919#define M98090_MIXSPL_LINEA_SHIFT 2
920#define M98090_MIXSPL_LINEA_WIDTH 1
921#define M98090_MIXSPL_DACR_MASK (1<<1)
922#define M98090_MIXSPL_DACR_SHIFT 1
923#define M98090_MIXSPL_DACR_WIDTH 1
924#define M98090_MIXSPL_DACL_MASK (1<<0)
925#define M98090_MIXSPL_DACL_SHIFT 0
926#define M98090_MIXSPL_DACL_WIDTH 1
927#define M98090_MIXSPL_MASK (63<<0)
928#define M98090_MIXSPL_SHIFT 0
929#define M98090_MIXSPL_WIDTH 6
930#define M98090_MIXSPR_DACR_MASK (1<<1)
931#define M98090_MIXSPR_DACR_SHIFT 1
932#define M98090_MIXSPR_DACR_WIDTH 1
933
934
935/*
936 * M98090_REG_RIGHT_SPK_MIXER
937 */
938#define M98090_SPK_SLAVE_MASK (1<<6)
939#define M98090_SPK_SLAVE_SHIFT 6
940#define M98090_SPK_SLAVE_WIDTH 1
941#define M98090_MIXSPR_MIC2_MASK (1<<5)
942#define M98090_MIXSPR_MIC2_SHIFT 5
943#define M98090_MIXSPR_MIC2_WIDTH 1
944#define M98090_MIXSPR_MIC1_MASK (1<<4)
945#define M98090_MIXSPR_MIC1_SHIFT 4
946#define M98090_MIXSPR_MIC1_WIDTH 1
947#define M98090_MIXSPR_LINEB_MASK (1<<3)
948#define M98090_MIXSPR_LINEB_SHIFT 3
949#define M98090_MIXSPR_LINEB_WIDTH 1
950#define M98090_MIXSPR_LINEA_MASK (1<<2)
951#define M98090_MIXSPR_LINEA_SHIFT 2
952#define M98090_MIXSPR_LINEA_WIDTH 1
953#define M98090_MIXSPR_DACR_MASK (1<<1)
954#define M98090_MIXSPR_DACR_SHIFT 1
955#define M98090_MIXSPR_DACR_WIDTH 1
956#define M98090_MIXSPR_DACL_MASK (1<<0)
957#define M98090_MIXSPR_DACL_SHIFT 0
958#define M98090_MIXSPR_DACL_WIDTH 1
959#define M98090_MIXSPR_MASK (63<<0)
960#define M98090_MIXSPR_SHIFT 0
961#define M98090_MIXSPR_WIDTH 6
962
963/*
964 * M98090_REG_SPK_CONTROL
965 */
966#define M98090_MIXSPRG_MASK (3<<2)
967#define M98090_MIXSPRG_SHIFT 2
968#define M98090_MIXSPRG_WIDTH 2
969#define M98090_MIXSPRG_NUM (1<<M98090_MIXSPRG_WIDTH)
970#define M98090_MIXSPLG_MASK (3<<0)
971#define M98090_MIXSPLG_SHIFT 0
972#define M98090_MIXSPLG_WIDTH 2
973#define M98090_MIXSPLG_NUM (1<<M98090_MIXSPLG_WIDTH)
974
975/*
976 * M98090_REG_LEFT_SPK_VOLUME
977 */
978#define M98090_SPLM_MASK (1<<7)
979#define M98090_SPLM_SHIFT 7
980#define M98090_SPLM_WIDTH 1
981#define M98090_SPVOLL_MASK (63<<0)
982#define M98090_SPVOLL_SHIFT 0
983#define M98090_SPVOLL_WIDTH 6
984#define M98090_SPVOLL_NUM 40
985
986/*
987 * M98090_REG_RIGHT_SPK_VOLUME
988 */
989#define M98090_SPRM_MASK (1<<7)
990#define M98090_SPRM_SHIFT 7
991#define M98090_SPRM_WIDTH 1
992#define M98090_SPVOLR_MASK (63<<0)
993#define M98090_SPVOLR_SHIFT 0
994#define M98090_SPVOLR_WIDTH 6
995#define M98090_SPVOLR_NUM 40
996
997/*
998 * M98090_REG_DRC_TIMING
999 */
1000#define M98090_DRCEN_MASK (1<<7)
1001#define M98090_DRCEN_SHIFT 7
1002#define M98090_DRCEN_WIDTH 1
1003#define M98090_DRCEN_NUM (1<<M98090_DRCEN_WIDTH)
1004#define M98090_DRCRLS_MASK (7<<4)
1005#define M98090_DRCRLS_SHIFT 4
1006#define M98090_DRCRLS_WIDTH 3
1007#define M98090_DRCATK_MASK (7<<0)
1008#define M98090_DRCATK_SHIFT 0
1009#define M98090_DRCATK_WIDTH 3
1010
1011/*
1012 * M98090_REG_DRC_COMPRESSOR
1013 */
1014#define M98090_DRCCMP_MASK (7<<5)
1015#define M98090_DRCCMP_SHIFT 5
1016#define M98090_DRCCMP_WIDTH 3
1017#define M98090_DRCTHC_MASK (31<<0)
1018#define M98090_DRCTHC_SHIFT 0
1019#define M98090_DRCTHC_WIDTH 5
1020#define M98090_DRCTHC_NUM (1<<M98090_DRCTHC_WIDTH)
1021
1022/*
1023 * M98090_REG_DRC_EXPANDER
1024 */
1025#define M98090_DRCEXP_MASK (7<<5)
1026#define M98090_DRCEXP_SHIFT 5
1027#define M98090_DRCEXP_WIDTH 3
1028#define M98090_DRCTHE_MASK (31<<0)
1029#define M98090_DRCTHE_SHIFT 0
1030#define M98090_DRCTHE_WIDTH 5
1031#define M98090_DRCTHE_NUM (1<<M98090_DRCTHE_WIDTH)
1032
1033/*
1034 * M98090_REG_DRC_GAIN
1035 */
1036#define M98090_DRCG_MASK (31<<0)
1037#define M98090_DRCG_SHIFT 0
1038#define M98090_DRCG_WIDTH 5
1039#define M98090_DRCG_NUM 13
1040
1041/*
1042 * M98090_REG_RCV_LOUTL_MIXER
1043 */
1044#define M98090_MIXRCVL_MIC2_MASK (1<<5)
1045#define M98090_MIXRCVL_MIC2_SHIFT 5
1046#define M98090_MIXRCVL_MIC2_WIDTH 1
1047#define M98090_MIXRCVL_MIC1_MASK (1<<4)
1048#define M98090_MIXRCVL_MIC1_SHIFT 4
1049#define M98090_MIXRCVL_MIC1_WIDTH 1
1050#define M98090_MIXRCVL_LINEB_MASK (1<<3)
1051#define M98090_MIXRCVL_LINEB_SHIFT 3
1052#define M98090_MIXRCVL_LINEB_WIDTH 1
1053#define M98090_MIXRCVL_LINEA_MASK (1<<2)
1054#define M98090_MIXRCVL_LINEA_SHIFT 2
1055#define M98090_MIXRCVL_LINEA_WIDTH 1
1056#define M98090_MIXRCVL_DACR_MASK (1<<1)
1057#define M98090_MIXRCVL_DACR_SHIFT 1
1058#define M98090_MIXRCVL_DACR_WIDTH 1
1059#define M98090_MIXRCVL_DACL_MASK (1<<0)
1060#define M98090_MIXRCVL_DACL_SHIFT 0
1061#define M98090_MIXRCVL_DACL_WIDTH 1
1062#define M98090_MIXRCVL_MASK (63<<0)
1063#define M98090_MIXRCVL_SHIFT 0
1064#define M98090_MIXRCVL_WIDTH 6
1065
1066/*
1067 * M98090_REG_RCV_LOUTL_CONTROL
1068 */
1069#define M98090_MIXRCVLG_MASK (3<<0)
1070#define M98090_MIXRCVLG_SHIFT 0
1071#define M98090_MIXRCVLG_WIDTH 2
1072#define M98090_MIXRCVLG_NUM (1<<M98090_MIXRCVLG_WIDTH)
1073
1074/*
1075 * M98090_REG_RCV_LOUTL_VOLUME
1076 */
1077#define M98090_RCVLM_MASK (1<<7)
1078#define M98090_RCVLM_SHIFT 7
1079#define M98090_RCVLM_WIDTH 1
1080#define M98090_RCVLVOL_MASK (31<<0)
1081#define M98090_RCVLVOL_SHIFT 0
1082#define M98090_RCVLVOL_WIDTH 5
1083#define M98090_RCVLVOL_NUM (1<<M98090_RCVLVOL_WIDTH)
1084
1085/*
1086 * M98090_REG_LOUTR_MIXER
1087 */
1088#define M98090_LINMOD_MASK (1<<7)
1089#define M98090_LINMOD_SHIFT 7
1090#define M98090_LINMOD_WIDTH 1
1091#define M98090_MIXRCVR_MIC2_MASK (1<<5)
1092#define M98090_MIXRCVR_MIC2_SHIFT 5
1093#define M98090_MIXRCVR_MIC2_WIDTH 1
1094#define M98090_MIXRCVR_MIC1_MASK (1<<4)
1095#define M98090_MIXRCVR_MIC1_SHIFT 4
1096#define M98090_MIXRCVR_MIC1_WIDTH 1
1097#define M98090_MIXRCVR_LINEB_MASK (1<<3)
1098#define M98090_MIXRCVR_LINEB_SHIFT 3
1099#define M98090_MIXRCVR_LINEB_WIDTH 1
1100#define M98090_MIXRCVR_LINEA_MASK (1<<2)
1101#define M98090_MIXRCVR_LINEA_SHIFT 2
1102#define M98090_MIXRCVR_LINEA_WIDTH 1
1103#define M98090_MIXRCVR_DACR_MASK (1<<1)
1104#define M98090_MIXRCVR_DACR_SHIFT 1
1105#define M98090_MIXRCVR_DACR_WIDTH 1
1106#define M98090_MIXRCVR_DACL_MASK (1<<0)
1107#define M98090_MIXRCVR_DACL_SHIFT 0
1108#define M98090_MIXRCVR_DACL_WIDTH 1
1109#define M98090_MIXRCVR_MASK (63<<0)
1110#define M98090_MIXRCVR_SHIFT 0
1111#define M98090_MIXRCVR_WIDTH 6
1112
1113/*
1114 * M98090_REG_LOUTR_CONTROL
1115 */
1116#define M98090_MIXRCVRG_MASK (3<<0)
1117#define M98090_MIXRCVRG_SHIFT 0
1118#define M98090_MIXRCVRG_WIDTH 2
1119#define M98090_MIXRCVRG_NUM (1<<M98090_MIXRCVRG_WIDTH)
1120
1121/*
1122 * M98090_REG_LOUTR_VOLUME
1123 */
1124#define M98090_RCVRM_MASK (1<<7)
1125#define M98090_RCVRM_SHIFT 7
1126#define M98090_RCVRM_WIDTH 1
1127#define M98090_RCVRVOL_MASK (31<<0)
1128#define M98090_RCVRVOL_SHIFT 0
1129#define M98090_RCVRVOL_WIDTH 5
1130#define M98090_RCVRVOL_NUM (1<<M98090_RCVRVOL_WIDTH)
1131
1132/*
1133 * M98090_REG_JACK_DETECT
1134 */
1135#define M98090_JDETEN_MASK (1<<7)
1136#define M98090_JDETEN_SHIFT 7
1137#define M98090_JDETEN_WIDTH 1
1138#define M98090_JDWK_MASK (1<<6)
1139#define M98090_JDWK_SHIFT 6
1140#define M98090_JDWK_WIDTH 1
1141#define M98090_JDEB_MASK (3<<0)
1142#define M98090_JDEB_SHIFT 0
1143#define M98090_JDEB_WIDTH 2
1144#define M98090_JDEB_25MS (0<<0)
1145#define M98090_JDEB_50MS (1<<0)
1146#define M98090_JDEB_100MS (2<<0)
1147#define M98090_JDEB_200MS (3<<0)
1148
1149/*
1150 * M98090_REG_INPUT_ENABLE
1151 */
1152#define M98090_MBEN_MASK (1<<4)
1153#define M98090_MBEN_SHIFT 4
1154#define M98090_MBEN_WIDTH 1
1155#define M98090_LINEAEN_MASK (1<<3)
1156#define M98090_LINEAEN_SHIFT 3
1157#define M98090_LINEAEN_WIDTH 1
1158#define M98090_LINEBEN_MASK (1<<2)
1159#define M98090_LINEBEN_SHIFT 2
1160#define M98090_LINEBEN_WIDTH 1
1161#define M98090_ADREN_MASK (1<<1)
1162#define M98090_ADREN_SHIFT 1
1163#define M98090_ADREN_WIDTH 1
1164#define M98090_ADLEN_MASK (1<<0)
1165#define M98090_ADLEN_SHIFT 0
1166#define M98090_ADLEN_WIDTH 1
1167
1168/*
1169 * M98090_REG_OUTPUT_ENABLE
1170 */
1171#define M98090_HPREN_MASK (1<<7)
1172#define M98090_HPREN_SHIFT 7
1173#define M98090_HPREN_WIDTH 1
1174#define M98090_HPLEN_MASK (1<<6)
1175#define M98090_HPLEN_SHIFT 6
1176#define M98090_HPLEN_WIDTH 1
1177#define M98090_SPREN_MASK (1<<5)
1178#define M98090_SPREN_SHIFT 5
1179#define M98090_SPREN_WIDTH 1
1180#define M98090_SPLEN_MASK (1<<4)
1181#define M98090_SPLEN_SHIFT 4
1182#define M98090_SPLEN_WIDTH 1
1183#define M98090_RCVLEN_MASK (1<<3)
1184#define M98090_RCVLEN_SHIFT 3
1185#define M98090_RCVLEN_WIDTH 1
1186#define M98090_RCVREN_MASK (1<<2)
1187#define M98090_RCVREN_SHIFT 2
1188#define M98090_RCVREN_WIDTH 1
1189#define M98090_DAREN_MASK (1<<1)
1190#define M98090_DAREN_SHIFT 1
1191#define M98090_DAREN_WIDTH 1
1192#define M98090_DALEN_MASK (1<<0)
1193#define M98090_DALEN_SHIFT 0
1194#define M98090_DALEN_WIDTH 1
1195
1196/*
1197 * M98090_REG_LEVEL_CONTROL
1198 */
1199#define M98090_ZDENN_MASK (1<<2)
1200#define M98090_ZDENN_SHIFT 2
1201#define M98090_ZDENN_WIDTH 1
1202#define M98090_ZDENN_NUM (1<<M98090_ZDENN_WIDTH)
1203#define M98090_VS2ENN_MASK (1<<1)
1204#define M98090_VS2ENN_SHIFT 1
1205#define M98090_VS2ENN_WIDTH 1
1206#define M98090_VS2ENN_NUM (1<<M98090_VS2ENN_WIDTH)
1207#define M98090_VSENN_MASK (1<<0)
1208#define M98090_VSENN_SHIFT 0
1209#define M98090_VSENN_WIDTH 1
1210#define M98090_VSENN_NUM (1<<M98090_VSENN_WIDTH)
1211
1212/*
1213 * M98090_REG_DSP_FILTER_ENABLE
1214 */
1215#define M98090_DMIC34BQEN_MASK (1<<4)
1216#define M98090_DMIC34BQEN_SHIFT 4
1217#define M98090_DMIC34BQEN_WIDTH 1
1218#define M98090_DMIC34BQEN_NUM (1<<M98090_DMIC34BQEN_WIDTH)
1219#define M98090_ADCBQEN_MASK (1<<3)
1220#define M98090_ADCBQEN_SHIFT 3
1221#define M98090_ADCBQEN_WIDTH 1
1222#define M98090_ADCBQEN_NUM (1<<M98090_ADCBQEN_WIDTH)
1223#define M98090_EQ3BANDEN_MASK (1<<2)
1224#define M98090_EQ3BANDEN_SHIFT 2
1225#define M98090_EQ3BANDEN_WIDTH 1
1226#define M98090_EQ3BANDEN_NUM (1<<M98090_EQ3BANDEN_WIDTH)
1227#define M98090_EQ5BANDEN_MASK (1<<1)
1228#define M98090_EQ5BANDEN_SHIFT 1
1229#define M98090_EQ5BANDEN_WIDTH 1
1230#define M98090_EQ5BANDEN_NUM (1<<M98090_EQ5BANDEN_WIDTH)
1231#define M98090_EQ7BANDEN_MASK (1<<0)
1232#define M98090_EQ7BANDEN_SHIFT 0
1233#define M98090_EQ7BANDEN_WIDTH 1
1234#define M98090_EQ7BANDEN_NUM (1<<M98090_EQ7BANDEN_WIDTH)
1235
1236/*
1237 * M98090_REG_BIAS_CONTROL
1238 */
1239#define M98090_VCM_MODE_MASK (1<<0)
1240#define M98090_VCM_MODE_SHIFT 0
1241#define M98090_VCM_MODE_WIDTH 1
1242#define M98090_VCM_MODE_NUM (1<<M98090_VCM_MODE_WIDTH)
1243
1244/*
1245 * M98090_REG_DAC_CONTROL
1246 */
1247#define M98090_PERFMODE_MASK (1<<1)
1248#define M98090_PERFMODE_SHIFT 1
1249#define M98090_PERFMODE_WIDTH 1
1250#define M98090_PERFMODE_NUM (1<<M98090_PERFMODE_WIDTH)
1251#define M98090_DACHP_MASK (1<<0)
1252#define M98090_DACHP_SHIFT 0
1253#define M98090_DACHP_WIDTH 1
1254#define M98090_DACHP_NUM (1<<M98090_DACHP_WIDTH)
1255
1256/*
1257 * M98090_REG_ADC_CONTROL
1258 */
1259#define M98090_OSR128_MASK (1<<2)
1260#define M98090_OSR128_SHIFT 2
1261#define M98090_OSR128_WIDTH 1
1262#define M98090_ADCDITHER_MASK (1<<1)
1263#define M98090_ADCDITHER_SHIFT 1
1264#define M98090_ADCDITHER_WIDTH 1
1265#define M98090_ADCDITHER_NUM (1<<M98090_ADCDITHER_WIDTH)
1266#define M98090_ADCHP_MASK (1<<0)
1267#define M98090_ADCHP_SHIFT 0
1268#define M98090_ADCHP_WIDTH 1
1269#define M98090_ADCHP_NUM (1<<M98090_ADCHP_WIDTH)
1270
1271/*
1272 * M98090_REG_DEVICE_SHUTDOWN
1273 */
1274#define M98090_SHDNN_MASK (1<<7)
1275#define M98090_SHDNN_SHIFT 7
1276#define M98090_SHDNN_WIDTH 1
1277
1278/*
1279 * M98090_REG_EQUALIZER_BASE
1280 */
1281#define M98090_B0_1_HI_MASK (255<<0)
1282#define M98090_B0_1_HI_SHIFT 0
1283#define M98090_B0_1_HI_WIDTH 8
1284#define M98090_B0_1_MID_MASK (255<<0)
1285#define M98090_B0_1_MID_SHIFT 0
1286#define M98090_B0_1_MID_WIDTH 8
1287#define M98090_B0_1_LO_MASK (255<<0)
1288#define M98090_B0_1_LO_SHIFT 0
1289#define M98090_B0_1_LO_WIDTH 8
1290#define M98090_B1_1_HI_MASK (255<<0)
1291#define M98090_B1_1_HI_SHIFT 0
1292#define M98090_B1_1_HI_WIDTH 8
1293#define M98090_B1_1_MID_MASK (255<<0)
1294#define M98090_B1_1_MID_SHIFT 0
1295#define M98090_B1_1_MID_WIDTH 8
1296#define M98090_B1_1_LO_MASK (255<<0)
1297#define M98090_B1_1_LO_SHIFT 0
1298#define M98090_B1_1_LO_WIDTH 8
1299#define M98090_B2_1_HI_MASK (255<<0)
1300#define M98090_B2_1_HI_SHIFT 0
1301#define M98090_B2_1_HI_WIDTH 8
1302#define M98090_B2_1_MID_MASK (255<<0)
1303#define M98090_B2_1_MID_SHIFT 0
1304#define M98090_B2_1_MID_WIDTH 8
1305#define M98090_B2_1_LO_MASK (255<<0)
1306#define M98090_B2_1_LO_SHIFT 0
1307#define M98090_B2_1_LO_WIDTH 8
1308#define M98090_A1_1_HI_MASK (255<<0)
1309#define M98090_A1_1_HI_SHIFT 0
1310#define M98090_A1_1_HI_WIDTH 8
1311#define M98090_A1_1_MID_MASK (255<<0)
1312#define M98090_A1_1_MID_SHIFT 0
1313#define M98090_A1_1_MID_WIDTH 8
1314#define M98090_A1_1_LO_MASK (255<<0)
1315#define M98090_A1_1_LO_SHIFT 0
1316#define M98090_A1_1_LO_WIDTH 8
1317#define M98090_A2_1_HI_MASK (255<<0)
1318#define M98090_A2_1_HI_SHIFT 0
1319#define M98090_A2_1_HI_WIDTH 8
1320#define M98090_A2_1_MID_MASK (255<<0)
1321#define M98090_A2_1_MID_SHIFT 0
1322#define M98090_A2_1_MID_WIDTH 8
1323#define M98090_A2_1_LO_MASK (255<<0)
1324#define M98090_A2_1_LO_SHIFT 0
1325#define M98090_A2_1_LO_WIDTH 8
1326
1327#define M98090_COEFS_PER_BAND 5
1328#define M98090_COEFS_BLK_SZ (M98090_COEFS_PER_BAND * 3)
1329#define M98090_COEFS_MAX_SZ (M98090_COEFS_BLK_SZ * 7)
1330
1331/*
1332 * M98090_REG_RECORD_BIQUAD_BASE
1333 */
1334#define M98090_REC_B0_HI_MASK (255<<0)
1335#define M98090_REC_B0_HI_SHIFT 0
1336#define M98090_REC_B0_HI_WIDTH 8
1337#define M98090_REC_B0_MID_MASK (255<<0)
1338#define M98090_REC_B0_MID_SHIFT 0
1339#define M98090_REC_B0_MID_WIDTH 8
1340#define M98090_REC_B0_LO_MASK (255<<0)
1341#define M98090_REC_B0_LO_SHIFT 0
1342#define M98090_REC_B0_LO_WIDTH 8
1343#define M98090_REC_B1_HI_MASK (255<<0)
1344#define M98090_REC_B1_HI_SHIFT 0
1345#define M98090_REC_B1_HI_WIDTH 8
1346#define M98090_REC_B1_MID_MASK (255<<0)
1347#define M98090_REC_B1_MID_SHIFT 0
1348#define M98090_REC_B1_MID_WIDTH 8
1349#define M98090_REC_B1_LO_MASK (255<<0)
1350#define M98090_REC_B1_LO_SHIFT 0
1351#define M98090_REC_B1_LO_WIDTH 8
1352#define M98090_REC_B2_HI_MASK (255<<0)
1353#define M98090_REC_B2_HI_SHIFT 0
1354#define M98090_REC_B2_HI_WIDTH 8
1355#define M98090_REC_B2_MID_MASK (255<<0)
1356#define M98090_REC_B2_MID_SHIFT 0
1357#define M98090_REC_B2_MID_WIDTH 8
1358#define M98090_REC_B2_LO_MASK (255<<0)
1359#define M98090_REC_B2_LO_SHIFT 0
1360#define M98090_REC_B2_LO_WIDTH 8
1361#define M98090_REC_A1_HI_MASK (255<<0)
1362#define M98090_REC_A1_HI_SHIFT 0
1363#define M98090_REC_A1_HI_WIDTH 8
1364#define M98090_REC_A1_MID_MASK (255<<0)
1365#define M98090_REC_A1_MID_SHIFT 0
1366#define M98090_REC_A1_MID_WIDTH 8
1367#define M98090_REC_A1_LO_MASK (255<<0)
1368#define M98090_REC_A1_LO_SHIFT 0
1369#define M98090_REC_A1_LO_WIDTH 8
1370#define M98090_REC_A2_HI_MASK (255<<0)
1371#define M98090_REC_A2_HI_SHIFT 0
1372#define M98090_REC_A2_HI_WIDTH 8
1373#define M98090_REC_A2_MID_MASK (255<<0)
1374#define M98090_REC_A2_MID_SHIFT 0
1375#define M98090_REC_A2_MID_WIDTH 8
1376#define M98090_REC_A2_LO_MASK (255<<0)
1377#define M98090_REC_A2_LO_SHIFT 0
1378#define M98090_REC_A2_LO_WIDTH 8
1379
1380/*
1381 * M98090_REG_DMIC3_VOLUME
1382 */
1383#define M98090_DMIC_AV3G_MASK (7<<4)
1384#define M98090_DMIC_AV3G_SHIFT 4
1385#define M98090_DMIC_AV3G_WIDTH 3
1386#define M98090_DMIC_AV3G_NUM (1<<M98090_DMIC_AV3G_WIDTH)
1387#define M98090_DMIC_AV3_MASK (15<<0)
1388#define M98090_DMIC_AV3_SHIFT 0
1389#define M98090_DMIC_AV3_WIDTH 4
1390#define M98090_DMIC_AV3_NUM (1<<M98090_DMIC_AV3_WIDTH)
1391
1392/*
1393 * M98090_REG_DMIC4_VOLUME
1394 */
1395#define M98090_DMIC_AV4G_MASK (7<<4)
1396#define M98090_DMIC_AV4G_SHIFT 4
1397#define M98090_DMIC_AV4G_WIDTH 3
1398#define M98090_DMIC_AV4G_NUM (1<<M98090_DMIC_AV4G_WIDTH)
1399#define M98090_DMIC_AV4_MASK (15<<0)
1400#define M98090_DMIC_AV4_SHIFT 0
1401#define M98090_DMIC_AV4_WIDTH 4
1402#define M98090_DMIC_AV4_NUM (1<<M98090_DMIC_AV4_WIDTH)
1403
1404/*
1405 * M98090_REG_DMIC34_BQ_PREATTEN
1406 */
1407#define M98090_AV34BQ_MASK (15<<0)
1408#define M98090_AV34BQ_SHIFT 0
1409#define M98090_AV34BQ_WIDTH 4
1410#define M98090_AV34BQ_NUM (1<<M98090_AV34BQ_WIDTH)
1411
1412/*
1413 * M98090_REG_RECORD_TDM_SLOT
1414 */
1415#define M98090_TDM_SLOTADCL_MASK (3<<6)
1416#define M98090_TDM_SLOTADCL_SHIFT 6
1417#define M98090_TDM_SLOTADCL_WIDTH 2
1418#define M98090_TDM_SLOTADCL_NUM (1<<M98090_TDM_SLOTADCL_WIDTH)
1419#define M98090_TDM_SLOTADCR_MASK (3<<4)
1420#define M98090_TDM_SLOTADCR_SHIFT 4
1421#define M98090_TDM_SLOTADCR_WIDTH 2
1422#define M98090_TDM_SLOTADCR_NUM (1<<M98090_TDM_SLOTADCR_WIDTH)
1423#define M98090_TDM_SLOTDMIC3_MASK (3<<2)
1424#define M98090_TDM_SLOTDMIC3_SHIFT 2
1425#define M98090_TDM_SLOTDMIC3_WIDTH 2
1426#define M98090_TDM_SLOTDMIC3_NUM (1<<M98090_TDM_SLOTDMIC3_WIDTH)
1427#define M98090_TDM_SLOTDMIC4_MASK (3<<0)
1428#define M98090_TDM_SLOTDMIC4_SHIFT 0
1429#define M98090_TDM_SLOTDMIC4_WIDTH 2
1430#define M98090_TDM_SLOTDMIC4_NUM (1<<M98090_TDM_SLOTDMIC4_WIDTH)
1431
1432/*
1433 * M98090_REG_SAMPLE_RATE
1434 */
1435#define M98090_DMIC34_ZEROPAD_MASK (1<<4)
1436#define M98090_DMIC34_ZEROPAD_SHIFT 4
1437#define M98090_DMIC34_ZEROPAD_WIDTH 1
1438#define M98090_DMIC34_ZEROPAD_NUM (1<<M98090_DIGMIC4_WIDTH)
1439#define M98090_DMIC34_SRDIV_MASK (7<<0)
1440#define M98090_DMIC34_SRDIV_SHIFT 0
1441#define M98090_DMIC34_SRDIV_WIDTH 3
1442
1443/*
1444 * M98090_REG_DMIC34_BIQUAD_BASE
1445 */
1446#define M98090_DMIC34_B0_HI_MASK (255<<0)
1447#define M98090_DMIC34_B0_HI_SHIFT 0
1448#define M98090_DMIC34_B0_HI_WIDTH 8
1449#define M98090_DMIC34_B0_MID_MASK (255<<0)
1450#define M98090_DMIC34_B0_MID_SHIFT 0
1451#define M98090_DMIC34_B0_MID_WIDTH 8
1452#define M98090_DMIC34_B0_LO_MASK (255<<0)
1453#define M98090_DMIC34_B0_LO_SHIFT 0
1454#define M98090_DMIC34_B0_LO_WIDTH 8
1455#define M98090_DMIC34_B1_HI_MASK (255<<0)
1456#define M98090_DMIC34_B1_HI_SHIFT 0
1457#define M98090_DMIC34_B1_HI_WIDTH 8
1458#define M98090_DMIC34_B1_MID_MASK (255<<0)
1459#define M98090_DMIC34_B1_MID_SHIFT 0
1460#define M98090_DMIC34_B1_MID_WIDTH 8
1461#define M98090_DMIC34_B1_LO_MASK (255<<0)
1462#define M98090_DMIC34_B1_LO_SHIFT 0
1463#define M98090_DMIC34_B1_LO_WIDTH 8
1464#define M98090_DMIC34_B2_HI_MASK (255<<0)
1465#define M98090_DMIC34_B2_HI_SHIFT 0
1466#define M98090_DMIC34_B2_HI_WIDTH 8
1467#define M98090_DMIC34_B2_MID_MASK (255<<0)
1468#define M98090_DMIC34_B2_MID_SHIFT 0
1469#define M98090_DMIC34_B2_MID_WIDTH 8
1470#define M98090_DMIC34_B2_LO_MASK (255<<0)
1471#define M98090_DMIC34_B2_LO_SHIFT 0
1472#define M98090_DMIC34_B2_LO_WIDTH 8
1473#define M98090_DMIC34_A1_HI_MASK (255<<0)
1474#define M98090_DMIC34_A1_HI_SHIFT 0
1475#define M98090_DMIC34_A1_HI_WIDTH 8
1476#define M98090_DMIC34_A1_MID_MASK (255<<0)
1477#define M98090_DMIC34_A1_MID_SHIFT 0
1478#define M98090_DMIC34_A1_MID_WIDTH 8
1479#define M98090_DMIC34_A1_LO_MASK (255<<0)
1480#define M98090_DMIC34_A1_LO_SHIFT 0
1481#define M98090_DMIC34_A1_LO_WIDTH 8
1482#define M98090_DMIC34_A2_HI_MASK (255<<0)
1483#define M98090_DMIC34_A2_HI_SHIFT 0
1484#define M98090_DMIC34_A2_HI_WIDTH 8
1485#define M98090_DMIC34_A2_MID_MASK (255<<0)
1486#define M98090_DMIC34_A2_MID_SHIFT 0
1487#define M98090_DMIC34_A2_MID_WIDTH 8
1488#define M98090_DMIC34_A2_LO_MASK (255<<0)
1489#define M98090_DMIC34_A2_LO_SHIFT 0
1490#define M98090_DMIC34_A2_LO_WIDTH 8
1491
1492#define M98090_JACK_STATE_NO_HEADSET 0
1493#define M98090_JACK_STATE_NO_HEADSET_2 1
1494#define M98090_JACK_STATE_HEADPHONE 2
1495#define M98090_JACK_STATE_HEADSET 3
1496
1497/*
1498 * M98090_REG_REVISION_ID
1499 */
1500#define M98090_REVID_MASK (255<<0)
1501#define M98090_REVID_SHIFT 0
1502#define M98090_REVID_WIDTH 8
1503#define M98090_REVID_NUM (1<<M98090_REVID_WIDTH)
1504
1505#define M98090_BYTE1(w) ((w >> 8) & 0xff)
1506#define M98090_BYTE0(w) (w & 0xff)
1507
1508/* Silicon revision number */
1509#define M98090_REVA 0x40
1510#define M98091_REVA 0x50
1511
1512enum max98090_type {
1513 MAX98090,
1514 MAX98091,
1515};
1516
1517struct max98090_cdata {
1518 unsigned int rate;
1519 unsigned int fmt;
1520};
1521
1522struct max98090_priv {
1523 struct regmap *regmap;
1524 struct snd_soc_codec *codec;
1525 enum max98090_type devtype;
1526 void *control_data;
1527 struct max98090_pdata *pdata;
1528 unsigned int sysclk;
1529 unsigned int bclk;
1530 unsigned int lrclk;
1531 struct max98090_cdata dai[1];
1532 int irq;
1533 int jack_state;
1534 struct delayed_work jack_work;
1535 struct snd_soc_jack *jack;
1536 unsigned int dai_fmt;
1537 int tdm_slots;
1538 int tdm_width;
1539 u8 lin_state;
1540 unsigned int pa1en;
1541 unsigned int pa2en;
1542 unsigned int extmic_mux;
1543 unsigned int sidetone;
1544};
1545
1546int max98090_mic_detect(struct snd_soc_codec *codec,
1547 struct snd_soc_jack *jack);
1548
1549#endif
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5708a973a776..65d09d60b7c6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -85,6 +85,9 @@ struct aic3x_priv {
85#define AIC3X_MODEL_33 1 85#define AIC3X_MODEL_33 1
86#define AIC3X_MODEL_3007 2 86#define AIC3X_MODEL_3007 2
87 u16 model; 87 u16 model;
88
89 /* Selects the micbias voltage */
90 enum aic3x_micbias_voltage micbias_vg;
88}; 91};
89 92
90/* 93/*
@@ -195,6 +198,37 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
195 return ret; 198 return ret;
196} 199}
197 200
201/*
202 * mic bias power on/off share the same register bits with
203 * output voltage of mic bias. when power on mic bias, we
204 * need reclaim it to voltage value.
205 * 0x0 = Powered off
206 * 0x1 = MICBIAS output is powered to 2.0V,
207 * 0x2 = MICBIAS output is powered to 2.5V
208 * 0x3 = MICBIAS output is connected to AVDD
209 */
210static int mic_bias_event(struct snd_soc_dapm_widget *w,
211 struct snd_kcontrol *kcontrol, int event)
212{
213 struct snd_soc_codec *codec = w->codec;
214 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
215
216 switch (event) {
217 case SND_SOC_DAPM_POST_PMU:
218 /* change mic bias voltage to user defined */
219 snd_soc_update_bits(codec, MICBIAS_CTRL,
220 MICBIAS_LEVEL_MASK,
221 aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT);
222 break;
223
224 case SND_SOC_DAPM_PRE_PMD:
225 snd_soc_update_bits(codec, MICBIAS_CTRL,
226 MICBIAS_LEVEL_MASK, 0);
227 break;
228 }
229 return 0;
230}
231
198static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; 232static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" };
199static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; 233static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" };
200static const char *aic3x_left_hpcom_mux[] = 234static const char *aic3x_left_hpcom_mux[] =
@@ -596,12 +630,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
596 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), 630 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
597 631
598 /* Mic Bias */ 632 /* Mic Bias */
599 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V", 633 SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0,
600 MICBIAS_CTRL, 6, 3, 1, 0), 634 mic_bias_event,
601 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V", 635 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
602 MICBIAS_CTRL, 6, 3, 2, 0),
603 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
604 MICBIAS_CTRL, 6, 3, 3, 0),
605 636
606 /* Output mixers */ 637 /* Output mixers */
607 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, 638 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
@@ -1210,13 +1241,13 @@ static struct snd_soc_dai_driver aic3x_dai = {
1210 .name = "tlv320aic3x-hifi", 1241 .name = "tlv320aic3x-hifi",
1211 .playback = { 1242 .playback = {
1212 .stream_name = "Playback", 1243 .stream_name = "Playback",
1213 .channels_min = 1, 1244 .channels_min = 2,
1214 .channels_max = 2, 1245 .channels_max = 2,
1215 .rates = AIC3X_RATES, 1246 .rates = AIC3X_RATES,
1216 .formats = AIC3X_FORMATS,}, 1247 .formats = AIC3X_FORMATS,},
1217 .capture = { 1248 .capture = {
1218 .stream_name = "Capture", 1249 .stream_name = "Capture",
1219 .channels_min = 1, 1250 .channels_min = 2,
1220 .channels_max = 2, 1251 .channels_max = 2,
1221 .rates = AIC3X_RATES, 1252 .rates = AIC3X_RATES,
1222 .formats = AIC3X_FORMATS,}, 1253 .formats = AIC3X_FORMATS,},
@@ -1386,6 +1417,24 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1386 if (aic3x->model == AIC3X_MODEL_3007) 1417 if (aic3x->model == AIC3X_MODEL_3007)
1387 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1418 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1388 1419
1420 /* set mic bias voltage */
1421 switch (aic3x->micbias_vg) {
1422 case AIC3X_MICBIAS_2_0V:
1423 case AIC3X_MICBIAS_2_5V:
1424 case AIC3X_MICBIAS_AVDDV:
1425 snd_soc_update_bits(codec, MICBIAS_CTRL,
1426 MICBIAS_LEVEL_MASK,
1427 (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT);
1428 break;
1429 case AIC3X_MICBIAS_OFF:
1430 /*
1431 * noting to do. target won't enter here. This is just to avoid
1432 * compile time warning "warning: enumeration value
1433 * 'AIC3X_MICBIAS_OFF' not handled in switch"
1434 */
1435 break;
1436 }
1437
1389 aic3x_add_widgets(codec); 1438 aic3x_add_widgets(codec);
1390 list_add(&aic3x->list, &reset_list); 1439 list_add(&aic3x->list, &reset_list);
1391 1440
@@ -1461,6 +1510,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1461 struct aic3x_setup_data *ai3x_setup; 1510 struct aic3x_setup_data *ai3x_setup;
1462 struct device_node *np = i2c->dev.of_node; 1511 struct device_node *np = i2c->dev.of_node;
1463 int ret; 1512 int ret;
1513 u32 value;
1464 1514
1465 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); 1515 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
1466 if (aic3x == NULL) { 1516 if (aic3x == NULL) {
@@ -1474,6 +1524,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1474 if (pdata) { 1524 if (pdata) {
1475 aic3x->gpio_reset = pdata->gpio_reset; 1525 aic3x->gpio_reset = pdata->gpio_reset;
1476 aic3x->setup = pdata->setup; 1526 aic3x->setup = pdata->setup;
1527 aic3x->micbias_vg = pdata->micbias_vg;
1477 } else if (np) { 1528 } else if (np) {
1478 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup), 1529 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
1479 GFP_KERNEL); 1530 GFP_KERNEL);
@@ -1493,6 +1544,26 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1493 aic3x->setup = ai3x_setup; 1544 aic3x->setup = ai3x_setup;
1494 } 1545 }
1495 1546
1547 if (!of_property_read_u32(np, "ai3x-micbias-vg", &value)) {
1548 switch (value) {
1549 case 1 :
1550 aic3x->micbias_vg = AIC3X_MICBIAS_2_0V;
1551 break;
1552 case 2 :
1553 aic3x->micbias_vg = AIC3X_MICBIAS_2_5V;
1554 break;
1555 case 3 :
1556 aic3x->micbias_vg = AIC3X_MICBIAS_AVDDV;
1557 break;
1558 default :
1559 aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
1560 dev_err(&i2c->dev, "Unsuitable MicBias voltage "
1561 "found in DT\n");
1562 }
1563 } else {
1564 aic3x->micbias_vg = AIC3X_MICBIAS_OFF;
1565 }
1566
1496 } else { 1567 } else {
1497 aic3x->gpio_reset = -1; 1568 aic3x->gpio_reset = -1;
1498 } 1569 }
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 6db3c41b0163..e521ac3ddde8 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -238,6 +238,10 @@
238/* Default input volume */ 238/* Default input volume */
239#define DEFAULT_GAIN 0x20 239#define DEFAULT_GAIN 0x20
240 240
241/* MICBIAS Control Register */
242#define MICBIAS_LEVEL_SHIFT (6)
243#define MICBIAS_LEVEL_MASK (3 << 6)
244
241/* headset detection / button API */ 245/* headset detection / button API */
242 246
243/* The AIC3x supports detection of stereo headsets (GND + left + right signal) 247/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 782b0cded2e6..4f358393d6d6 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1452,20 +1452,6 @@ static int dac33_soc_remove(struct snd_soc_codec *codec)
1452 return 0; 1452 return 0;
1453} 1453}
1454 1454
1455static int dac33_soc_suspend(struct snd_soc_codec *codec)
1456{
1457 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1458
1459 return 0;
1460}
1461
1462static int dac33_soc_resume(struct snd_soc_codec *codec)
1463{
1464 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1465
1466 return 0;
1467}
1468
1469static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { 1455static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1470 .read = dac33_read_reg_cache, 1456 .read = dac33_read_reg_cache,
1471 .write = dac33_write_locked, 1457 .write = dac33_write_locked,
@@ -1476,8 +1462,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1476 .reg_cache_default = dac33_reg, 1462 .reg_cache_default = dac33_reg,
1477 .probe = dac33_soc_probe, 1463 .probe = dac33_soc_probe,
1478 .remove = dac33_soc_remove, 1464 .remove = dac33_soc_remove,
1479 .suspend = dac33_soc_suspend,
1480 .resume = dac33_soc_resume,
1481 1465
1482 .controls = dac33_snd_controls, 1466 .controls = dac33_snd_controls,
1483 .num_controls = ARRAY_SIZE(dac33_snd_controls), 1467 .num_controls = ARRAY_SIZE(dac33_snd_controls),
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 63b280b06035..8e6e5b016021 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -41,6 +41,11 @@
41/* Register descriptions are here */ 41/* Register descriptions are here */
42#include <linux/mfd/twl4030-audio.h> 42#include <linux/mfd/twl4030-audio.h>
43 43
44/* TWL4030 PMBR1 Register */
45#define TWL4030_PMBR1_REG 0x0D
46/* TWL4030 PMBR1 Register GPIO6 mux bits */
47#define TWL4030_GPIO6_PWM0_MUTE(value) ((value & 0x03) << 2)
48
44/* Shadow register used by the audio driver */ 49/* Shadow register used by the audio driver */
45#define TWL4030_REG_SW_SHADOW 0x4A 50#define TWL4030_REG_SW_SHADOW 0x4A
46#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 51#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
@@ -348,19 +353,32 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
348 353
349 pdata = twl4030_get_pdata(codec); 354 pdata = twl4030_get_pdata(codec);
350 355
351 if (pdata && pdata->hs_extmute && 356 if (pdata && pdata->hs_extmute) {
352 gpio_is_valid(pdata->hs_extmute_gpio)) { 357 if (gpio_is_valid(pdata->hs_extmute_gpio)) {
353 int ret; 358 int ret;
354 359
355 if (!pdata->hs_extmute_gpio) 360 if (!pdata->hs_extmute_gpio)
356 dev_warn(codec->dev, 361 dev_warn(codec->dev,
357 "Extmute GPIO is 0 is this correct?\n"); 362 "Extmute GPIO is 0 is this correct?\n");
358 363
359 ret = gpio_request_one(pdata->hs_extmute_gpio, 364 ret = gpio_request_one(pdata->hs_extmute_gpio,
360 GPIOF_OUT_INIT_LOW, "hs_extmute"); 365 GPIOF_OUT_INIT_LOW,
361 if (ret) { 366 "hs_extmute");
362 dev_err(codec->dev, "Failed to get hs_extmute GPIO\n"); 367 if (ret) {
363 pdata->hs_extmute_gpio = -1; 368 dev_err(codec->dev,
369 "Failed to get hs_extmute GPIO\n");
370 pdata->hs_extmute_gpio = -1;
371 }
372 } else {
373 u8 pin_mux;
374
375 /* Set TWL4030 GPIO6 as EXTMUTE signal */
376 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
377 TWL4030_PMBR1_REG);
378 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
379 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
380 twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
381 TWL4030_PMBR1_REG);
364 } 382 }
365 } 383 }
366 384
@@ -1306,6 +1324,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1306 SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0), 1324 SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
1307 SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0), 1325 SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),
1308 1326
1327 SND_SOC_DAPM_AIF_IN("VAIFIN", "Voice Playback", 0,
1328 TWL4030_REG_VOICE_IF, 6, 0),
1329
1309 /* Analog bypasses */ 1330 /* Analog bypasses */
1310 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1331 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1311 &twl4030_dapm_abypassr1_control), 1332 &twl4030_dapm_abypassr1_control),
@@ -1438,6 +1459,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1438 SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0), 1459 SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
1439 SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0), 1460 SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),
1440 1461
1462 SND_SOC_DAPM_AIF_OUT("VAIFOUT", "Voice Capture", 0,
1463 TWL4030_REG_VOICE_IF, 5, 0),
1464
1441 /* Analog/Digital mic path selection. 1465 /* Analog/Digital mic path selection.
1442 TX1 Left/Right: either analog Left/Right or Digimic0 1466 TX1 Left/Right: either analog Left/Right or Digimic0
1443 TX2 Left/Right: either analog Left/Right or Digimic1 */ 1467 TX2 Left/Right: either analog Left/Right or Digimic1 */
@@ -1473,10 +1497,15 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1473 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0, 1497 SND_SOC_DAPM_SUPPLY("micbias2 select", TWL4030_REG_MICBIAS_CTL, 6, 0,
1474 NULL, 0), 1498 NULL, 0),
1475 1499
1476 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0), 1500 /* Microphone bias */
1477 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0), 1501 SND_SOC_DAPM_SUPPLY("Mic Bias 1",
1478 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0), 1502 TWL4030_REG_MICBIAS_CTL, 0, 0, NULL, 0),
1503 SND_SOC_DAPM_SUPPLY("Mic Bias 2",
1504 TWL4030_REG_MICBIAS_CTL, 1, 0, NULL, 0),
1505 SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
1506 TWL4030_REG_MICBIAS_CTL, 2, 0, NULL, 0),
1479 1507
1508 SND_SOC_DAPM_SUPPLY("VIF Enable", TWL4030_REG_VOICE_IF, 0, 0, NULL, 0),
1480}; 1509};
1481 1510
1482static const struct snd_soc_dapm_route intercon[] = { 1511static const struct snd_soc_dapm_route intercon[] = {
@@ -1485,17 +1514,16 @@ static const struct snd_soc_dapm_route intercon[] = {
1485 {"DAC Left1", NULL, "HiFi Playback"}, 1514 {"DAC Left1", NULL, "HiFi Playback"},
1486 {"DAC Right2", NULL, "HiFi Playback"}, 1515 {"DAC Right2", NULL, "HiFi Playback"},
1487 {"DAC Left2", NULL, "HiFi Playback"}, 1516 {"DAC Left2", NULL, "HiFi Playback"},
1488 {"DAC Voice", NULL, "Voice Playback"}, 1517 {"DAC Voice", NULL, "VAIFIN"},
1489 1518
1490 /* ADC -> Stream mapping */ 1519 /* ADC -> Stream mapping */
1491 {"HiFi Capture", NULL, "ADC Virtual Left1"}, 1520 {"HiFi Capture", NULL, "ADC Virtual Left1"},
1492 {"HiFi Capture", NULL, "ADC Virtual Right1"}, 1521 {"HiFi Capture", NULL, "ADC Virtual Right1"},
1493 {"HiFi Capture", NULL, "ADC Virtual Left2"}, 1522 {"HiFi Capture", NULL, "ADC Virtual Left2"},
1494 {"HiFi Capture", NULL, "ADC Virtual Right2"}, 1523 {"HiFi Capture", NULL, "ADC Virtual Right2"},
1495 {"Voice Capture", NULL, "ADC Virtual Left1"}, 1524 {"VAIFOUT", NULL, "ADC Virtual Left2"},
1496 {"Voice Capture", NULL, "ADC Virtual Right1"}, 1525 {"VAIFOUT", NULL, "ADC Virtual Right2"},
1497 {"Voice Capture", NULL, "ADC Virtual Left2"}, 1526 {"VAIFOUT", NULL, "VIF Enable"},
1498 {"Voice Capture", NULL, "ADC Virtual Right2"},
1499 1527
1500 {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, 1528 {"Digital L1 Playback Mixer", NULL, "DAC Left1"},
1501 {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, 1529 {"Digital R1 Playback Mixer", NULL, "DAC Right1"},
@@ -1510,6 +1538,7 @@ static const struct snd_soc_dapm_route intercon[] = {
1510 {"DAC Right1", NULL, "AIF Enable"}, 1538 {"DAC Right1", NULL, "AIF Enable"},
1511 {"DAC Left2", NULL, "AIF Enable"}, 1539 {"DAC Left2", NULL, "AIF Enable"},
1512 {"DAC Right1", NULL, "AIF Enable"}, 1540 {"DAC Right1", NULL, "AIF Enable"},
1541 {"DAC Voice", NULL, "VIF Enable"},
1513 1542
1514 {"Digital R2 Playback Mixer", NULL, "AIF Enable"}, 1543 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1515 {"Digital L2 Playback Mixer", NULL, "AIF Enable"}, 1544 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
@@ -2267,18 +2296,6 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
2267}, 2296},
2268}; 2297};
2269 2298
2270static int twl4030_soc_suspend(struct snd_soc_codec *codec)
2271{
2272 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2273 return 0;
2274}
2275
2276static int twl4030_soc_resume(struct snd_soc_codec *codec)
2277{
2278 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2279 return 0;
2280}
2281
2282static int twl4030_soc_probe(struct snd_soc_codec *codec) 2299static int twl4030_soc_probe(struct snd_soc_codec *codec)
2283{ 2300{
2284 struct twl4030_priv *twl4030; 2301 struct twl4030_priv *twl4030;
@@ -2316,8 +2333,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
2316static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { 2333static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2317 .probe = twl4030_soc_probe, 2334 .probe = twl4030_soc_probe,
2318 .remove = twl4030_soc_remove, 2335 .remove = twl4030_soc_remove,
2319 .suspend = twl4030_soc_suspend,
2320 .resume = twl4030_soc_resume,
2321 .read = twl4030_read_reg_cache, 2336 .read = twl4030_read_reg_cache,
2322 .write = twl4030_write, 2337 .write = twl4030_write,
2323 .set_bias_level = twl4030_set_bias_level, 2338 .set_bias_level = twl4030_set_bias_level,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 3fc3fc64dd8b..9b9a6e587610 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -69,13 +69,8 @@ struct twl6040_data {
69 int hs_power_mode_locked; 69 int hs_power_mode_locked;
70 unsigned int clk_in; 70 unsigned int clk_in;
71 unsigned int sysclk; 71 unsigned int sysclk;
72 u16 hs_left_step;
73 u16 hs_right_step;
74 u16 hf_left_step;
75 u16 hf_right_step;
76 struct twl6040_jack_data hs_jack; 72 struct twl6040_jack_data hs_jack;
77 struct snd_soc_codec *codec; 73 struct snd_soc_codec *codec;
78 struct workqueue_struct *workqueue;
79 struct mutex mutex; 74 struct mutex mutex;
80}; 75};
81 76
@@ -404,8 +399,7 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
404 struct snd_soc_codec *codec = data; 399 struct snd_soc_codec *codec = data;
405 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 400 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
406 401
407 queue_delayed_work(priv->workqueue, &priv->hs_jack.work, 402 schedule_delayed_work(&priv->hs_jack.work, msecs_to_jiffies(200));
408 msecs_to_jiffies(200));
409 403
410 return IRQ_HANDLED; 404 return IRQ_HANDLED;
411} 405}
@@ -1115,7 +1109,6 @@ static int twl6040_suspend(struct snd_soc_codec *codec)
1115static int twl6040_resume(struct snd_soc_codec *codec) 1109static int twl6040_resume(struct snd_soc_codec *codec)
1116{ 1110{
1117 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1111 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1118 twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
1119 1112
1120 return 0; 1113 return 0;
1121} 1114}
@@ -1127,83 +1120,46 @@ static int twl6040_resume(struct snd_soc_codec *codec)
1127static int twl6040_probe(struct snd_soc_codec *codec) 1120static int twl6040_probe(struct snd_soc_codec *codec)
1128{ 1121{
1129 struct twl6040_data *priv; 1122 struct twl6040_data *priv;
1130 struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
1131 struct platform_device *pdev = container_of(codec->dev, 1123 struct platform_device *pdev = container_of(codec->dev,
1132 struct platform_device, dev); 1124 struct platform_device, dev);
1133 int ret = 0; 1125 int ret = 0;
1134 1126
1135 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1127 priv = devm_kzalloc(codec->dev, sizeof(*priv), GFP_KERNEL);
1136 if (priv == NULL) 1128 if (priv == NULL)
1137 return -ENOMEM; 1129 return -ENOMEM;
1130
1138 snd_soc_codec_set_drvdata(codec, priv); 1131 snd_soc_codec_set_drvdata(codec, priv);
1139 1132
1140 priv->codec = codec; 1133 priv->codec = codec;
1141 codec->control_data = dev_get_drvdata(codec->dev->parent); 1134 codec->control_data = dev_get_drvdata(codec->dev->parent);
1142 1135
1143 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1144 priv->hs_left_step = pdata->hs_left_step;
1145 priv->hs_right_step = pdata->hs_right_step;
1146 } else {
1147 priv->hs_left_step = 1;
1148 priv->hs_right_step = 1;
1149 }
1150
1151 if (pdata && pdata->hf_left_step && pdata->hf_right_step) {
1152 priv->hf_left_step = pdata->hf_left_step;
1153 priv->hf_right_step = pdata->hf_right_step;
1154 } else {
1155 priv->hf_left_step = 1;
1156 priv->hf_right_step = 1;
1157 }
1158
1159 priv->plug_irq = platform_get_irq(pdev, 0); 1136 priv->plug_irq = platform_get_irq(pdev, 0);
1160 if (priv->plug_irq < 0) { 1137 if (priv->plug_irq < 0) {
1161 dev_err(codec->dev, "invalid irq\n"); 1138 dev_err(codec->dev, "invalid irq\n");
1162 ret = -EINVAL; 1139 return -EINVAL;
1163 goto work_err;
1164 }
1165
1166 priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0);
1167 if (!priv->workqueue) {
1168 ret = -ENOMEM;
1169 goto work_err;
1170 } 1140 }
1171 1141
1172 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1142 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1173 1143
1174 mutex_init(&priv->mutex); 1144 mutex_init(&priv->mutex);
1175 1145
1176 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, 1146 ret = devm_request_threaded_irq(codec->dev, priv->plug_irq, NULL,
1177 0, "twl6040_irq_plug", codec); 1147 twl6040_audio_handler, IRQF_NO_SUSPEND,
1148 "twl6040_irq_plug", codec);
1178 if (ret) { 1149 if (ret) {
1179 dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret); 1150 dev_err(codec->dev, "PLUG IRQ request failed: %d\n", ret);
1180 goto plugirq_err; 1151 return ret;
1181 } 1152 }
1182 1153
1183 twl6040_init_chip(codec); 1154 twl6040_init_chip(codec);
1184 1155
1185 /* power on device */ 1156 /* power on device */
1186 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1157 return twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1187 if (!ret)
1188 return 0;
1189
1190 /* Error path */
1191 free_irq(priv->plug_irq, codec);
1192plugirq_err:
1193 destroy_workqueue(priv->workqueue);
1194work_err:
1195 kfree(priv);
1196 return ret;
1197} 1158}
1198 1159
1199static int twl6040_remove(struct snd_soc_codec *codec) 1160static int twl6040_remove(struct snd_soc_codec *codec)
1200{ 1161{
1201 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1202
1203 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1162 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1204 free_irq(priv->plug_irq, codec);
1205 destroy_workqueue(priv->workqueue);
1206 kfree(priv);
1207 1163
1208 return 0; 1164 return 0;
1209} 1165}
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 12bcae63a7f0..f2ac38b61a1b 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <linux/clk.h>
29#include <linux/delay.h> 30#include <linux/delay.h>
30#include <linux/pm.h> 31#include <linux/pm.h>
31#include <linux/i2c.h> 32#include <linux/i2c.h>
@@ -62,6 +63,7 @@ enum wm2000_anc_mode {
62struct wm2000_priv { 63struct wm2000_priv {
63 struct i2c_client *i2c; 64 struct i2c_client *i2c;
64 struct regmap *regmap; 65 struct regmap *regmap;
66 struct clk *mclk;
65 67
66 struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; 68 struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];
67 69
@@ -71,11 +73,12 @@ struct wm2000_priv {
71 unsigned int anc_eng_ena:1; 73 unsigned int anc_eng_ena:1;
72 unsigned int spk_ena:1; 74 unsigned int spk_ena:1;
73 75
74 unsigned int mclk_div:1;
75 unsigned int speech_clarity:1; 76 unsigned int speech_clarity:1;
76 77
77 int anc_download_size; 78 int anc_download_size;
78 char *anc_download; 79 char *anc_download;
80
81 struct mutex lock;
79}; 82};
80 83
81static int wm2000_write(struct i2c_client *i2c, unsigned int reg, 84static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
@@ -131,6 +134,7 @@ static int wm2000_poll_bit(struct i2c_client *i2c,
131static int wm2000_power_up(struct i2c_client *i2c, int analogue) 134static int wm2000_power_up(struct i2c_client *i2c, int analogue)
132{ 135{
133 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 136 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
137 unsigned long rate;
134 int ret; 138 int ret;
135 139
136 BUG_ON(wm2000->anc_mode != ANC_OFF); 140 BUG_ON(wm2000->anc_mode != ANC_OFF);
@@ -143,7 +147,8 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
143 return ret; 147 return ret;
144 } 148 }
145 149
146 if (!wm2000->mclk_div) { 150 rate = clk_get_rate(wm2000->mclk);
151 if (rate <= 13500000) {
147 dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); 152 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
148 wm2000_write(i2c, WM2000_REG_SYS_CTL2, 153 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
149 WM2000_MCLK_DIV2_ENA_CLR); 154 WM2000_MCLK_DIV2_ENA_CLR);
@@ -550,6 +555,15 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
550 return -EINVAL; 555 return -EINVAL;
551 } 556 }
552 557
558 /* Maintain clock while active */
559 if (anc_transitions[i].source == ANC_OFF) {
560 ret = clk_prepare_enable(wm2000->mclk);
561 if (ret != 0) {
562 dev_err(&i2c->dev, "Failed to enable MCLK: %d\n", ret);
563 return ret;
564 }
565 }
566
553 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) { 567 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
554 if (!anc_transitions[i].step[j]) 568 if (!anc_transitions[i].step[j])
555 break; 569 break;
@@ -559,7 +573,10 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
559 return ret; 573 return ret;
560 } 574 }
561 575
562 return 0; 576 if (anc_transitions[i].dest == ANC_OFF)
577 clk_disable_unprepare(wm2000->mclk);
578
579 return ret;
563} 580}
564 581
565static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) 582static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
@@ -599,13 +616,20 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
599 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 616 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
600 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 617 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
601 int anc_active = ucontrol->value.enumerated.item[0]; 618 int anc_active = ucontrol->value.enumerated.item[0];
619 int ret;
602 620
603 if (anc_active > 1) 621 if (anc_active > 1)
604 return -EINVAL; 622 return -EINVAL;
605 623
624 mutex_lock(&wm2000->lock);
625
606 wm2000->anc_active = anc_active; 626 wm2000->anc_active = anc_active;
607 627
608 return wm2000_anc_set_mode(wm2000); 628 ret = wm2000_anc_set_mode(wm2000);
629
630 mutex_unlock(&wm2000->lock);
631
632 return ret;
609} 633}
610 634
611static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, 635static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
@@ -625,16 +649,24 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
625 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 649 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
626 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 650 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
627 int val = ucontrol->value.enumerated.item[0]; 651 int val = ucontrol->value.enumerated.item[0];
652 int ret;
628 653
629 if (val > 1) 654 if (val > 1)
630 return -EINVAL; 655 return -EINVAL;
631 656
657 mutex_lock(&wm2000->lock);
658
632 wm2000->spk_ena = val; 659 wm2000->spk_ena = val;
633 660
634 return wm2000_anc_set_mode(wm2000); 661 ret = wm2000_anc_set_mode(wm2000);
662
663 mutex_unlock(&wm2000->lock);
664
665 return ret;
635} 666}
636 667
637static const struct snd_kcontrol_new wm2000_controls[] = { 668static const struct snd_kcontrol_new wm2000_controls[] = {
669 SOC_SINGLE("ANC Volume", WM2000_REG_ANC_GAIN_CTRL, 0, 255, 0),
638 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0, 670 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
639 wm2000_anc_mode_get, 671 wm2000_anc_mode_get,
640 wm2000_anc_mode_put), 672 wm2000_anc_mode_put),
@@ -648,6 +680,9 @@ static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
648{ 680{
649 struct snd_soc_codec *codec = w->codec; 681 struct snd_soc_codec *codec = w->codec;
650 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 682 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
683 int ret;
684
685 mutex_lock(&wm2000->lock);
651 686
652 if (SND_SOC_DAPM_EVENT_ON(event)) 687 if (SND_SOC_DAPM_EVENT_ON(event))
653 wm2000->anc_eng_ena = 1; 688 wm2000->anc_eng_ena = 1;
@@ -655,7 +690,11 @@ static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
655 if (SND_SOC_DAPM_EVENT_OFF(event)) 690 if (SND_SOC_DAPM_EVENT_OFF(event))
656 wm2000->anc_eng_ena = 0; 691 wm2000->anc_eng_ena = 0;
657 692
658 return wm2000_anc_set_mode(wm2000); 693 ret = wm2000_anc_set_mode(wm2000);
694
695 mutex_unlock(&wm2000->lock);
696
697 return ret;
659} 698}
660 699
661static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = { 700static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
@@ -702,6 +741,9 @@ static bool wm2000_readable_reg(struct device *dev, unsigned int reg)
702{ 741{
703 switch (reg) { 742 switch (reg) {
704 case WM2000_REG_SYS_START: 743 case WM2000_REG_SYS_START:
744 case WM2000_REG_ANC_GAIN_CTRL:
745 case WM2000_REG_MSE_TH1:
746 case WM2000_REG_MSE_TH2:
705 case WM2000_REG_SPEECH_CLARITY: 747 case WM2000_REG_SPEECH_CLARITY:
706 case WM2000_REG_SYS_WATCHDOG: 748 case WM2000_REG_SYS_WATCHDOG:
707 case WM2000_REG_ANA_VMID_PD_TIME: 749 case WM2000_REG_ANA_VMID_PD_TIME:
@@ -737,6 +779,8 @@ static int wm2000_probe(struct snd_soc_codec *codec)
737{ 779{
738 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 780 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
739 781
782 snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_REGMAP);
783
740 /* This will trigger a transition to standby mode by default */ 784 /* This will trigger a transition to standby mode by default */
741 wm2000_anc_set_mode(wm2000); 785 wm2000_anc_set_mode(wm2000);
742 786
@@ -782,6 +826,8 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
782 return -ENOMEM; 826 return -ENOMEM;
783 } 827 }
784 828
829 mutex_init(&wm2000->lock);
830
785 dev_set_drvdata(&i2c->dev, wm2000); 831 dev_set_drvdata(&i2c->dev, wm2000);
786 832
787 wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap); 833 wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap);
@@ -823,10 +869,16 @@ static int wm2000_i2c_probe(struct i2c_client *i2c,
823 reg = wm2000_read(i2c, WM2000_REG_REVISON); 869 reg = wm2000_read(i2c, WM2000_REG_REVISON);
824 dev_info(&i2c->dev, "revision %c\n", reg + 'A'); 870 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
825 871
872 wm2000->mclk = devm_clk_get(&i2c->dev, "MCLK");
873 if (IS_ERR(wm2000->mclk)) {
874 ret = PTR_ERR(wm2000->mclk);
875 dev_err(&i2c->dev, "Failed to get MCLK: %d\n", ret);
876 goto err_supplies;
877 }
878
826 filename = "wm2000_anc.bin"; 879 filename = "wm2000_anc.bin";
827 pdata = dev_get_platdata(&i2c->dev); 880 pdata = dev_get_platdata(&i2c->dev);
828 if (pdata) { 881 if (pdata) {
829 wm2000->mclk_div = pdata->mclkdiv2;
830 wm2000->speech_clarity = !pdata->speech_enh_disable; 882 wm2000->speech_clarity = !pdata->speech_enh_disable;
831 883
832 if (pdata->download_file) 884 if (pdata->download_file)
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
index abcd82a93995..fb812cd9e77d 100644
--- a/sound/soc/codecs/wm2000.h
+++ b/sound/soc/codecs/wm2000.h
@@ -10,6 +10,9 @@
10#define _WM2000_H 10#define _WM2000_H
11 11
12#define WM2000_REG_SYS_START 0x8000 12#define WM2000_REG_SYS_START 0x8000
13#define WM2000_REG_ANC_GAIN_CTRL 0x8fa2
14#define WM2000_REG_MSE_TH2 0x8fdf
15#define WM2000_REG_MSE_TH1 0x8fe0
13#define WM2000_REG_SPEECH_CLARITY 0x8fef 16#define WM2000_REG_SPEECH_CLARITY 0x8fef
14#define WM2000_REG_SYS_WATCHDOG 0x8ff6 17#define WM2000_REG_SYS_WATCHDOG 0x8ff6
15#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7 18#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index e6cefe1ac677..ddc98f02ecbd 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1019,8 +1019,6 @@ static const char *wm2200_mixer_texts[] = {
1019 "EQR", 1019 "EQR",
1020 "LHPF1", 1020 "LHPF1",
1021 "LHPF2", 1021 "LHPF2",
1022 "LHPF3",
1023 "LHPF4",
1024 "DSP1.1", 1022 "DSP1.1",
1025 "DSP1.2", 1023 "DSP1.2",
1026 "DSP1.3", 1024 "DSP1.3",
@@ -1053,7 +1051,6 @@ static int wm2200_mixer_values[] = {
1053 0x25, 1051 0x25,
1054 0x50, /* EQ */ 1052 0x50, /* EQ */
1055 0x51, 1053 0x51,
1056 0x52,
1057 0x60, /* LHPF1 */ 1054 0x60, /* LHPF1 */
1058 0x61, /* LHPF2 */ 1055 0x61, /* LHPF2 */
1059 0x68, /* DSP1 */ 1056 0x68, /* DSP1 */
@@ -1112,6 +1109,16 @@ static int wm2200_mixer_values[] = {
1112 static WM2200_MUX_CTL_DECL(name##_aux5); \ 1109 static WM2200_MUX_CTL_DECL(name##_aux5); \
1113 static WM2200_MUX_CTL_DECL(name##_aux6); 1110 static WM2200_MUX_CTL_DECL(name##_aux6);
1114 1111
1112static const char *wm2200_rxanc_input_sel_texts[] = {
1113 "None", "IN1", "IN2", "IN3",
1114};
1115
1116static const struct soc_enum wm2200_rxanc_input_sel =
1117 SOC_ENUM_SINGLE(WM2200_RXANC_SRC,
1118 WM2200_IN_RXANC_SEL_SHIFT,
1119 ARRAY_SIZE(wm2200_rxanc_input_sel_texts),
1120 wm2200_rxanc_input_sel_texts);
1121
1115static const struct snd_kcontrol_new wm2200_snd_controls[] = { 1122static const struct snd_kcontrol_new wm2200_snd_controls[] = {
1116SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, 1123SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
1117 WM2200_IN1_OSR_SHIFT, 1, 0), 1124 WM2200_IN1_OSR_SHIFT, 1, 0),
@@ -1129,9 +1136,9 @@ SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
1129 1136
1130SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, 1137SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
1131 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1), 1138 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
1132SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, 1139SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_2L,
1133 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1), 1140 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
1134SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, 1141SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_3L,
1135 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1), 1142 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1136 1143
1137SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L, 1144SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
@@ -1144,6 +1151,12 @@ SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1144 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT, 1151 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1145 0xbf, 0, digital_tlv), 1152 0xbf, 0, digital_tlv),
1146 1153
1154SND_SOC_BYTES_MASK("EQL Coefficients", WM2200_EQL_1, 20, WM2200_EQL_ENA),
1155SND_SOC_BYTES_MASK("EQR Coefficients", WM2200_EQR_1, 20, WM2200_EQR_ENA),
1156
1157SND_SOC_BYTES("LHPF1 Coefficeints", WM2200_HPLPF1_2, 1),
1158SND_SOC_BYTES("LHPF2 Coefficeints", WM2200_HPLPF2_2, 1),
1159
1147SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L, 1160SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1148 WM2200_OUT1_OSR_SHIFT, 1, 0), 1161 WM2200_OUT1_OSR_SHIFT, 1, 0),
1149SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L, 1162SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
@@ -1165,6 +1178,7 @@ SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1165 digital_tlv), 1178 digital_tlv),
1166SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT, 1179SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1167 WM2200_SPK1R_MUTE_SHIFT, 1, 1), 1180 WM2200_SPK1R_MUTE_SHIFT, 1, 1),
1181SOC_ENUM("RxANC Src", wm2200_rxanc_input_sel),
1168}; 1182};
1169 1183
1170WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE); 1184WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
@@ -1551,6 +1565,10 @@ static int wm2200_probe(struct snd_soc_codec *codec)
1551 return ret; 1565 return ret;
1552 } 1566 }
1553 1567
1568 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2);
1569 if (ret != 0)
1570 return ret;
1571
1554 return ret; 1572 return ret;
1555} 1573}
1556 1574
@@ -2185,6 +2203,7 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
2185 struct wm2200_priv *wm2200; 2203 struct wm2200_priv *wm2200;
2186 unsigned int reg; 2204 unsigned int reg;
2187 int ret, i; 2205 int ret, i;
2206 int val;
2188 2207
2189 wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv), 2208 wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2190 GFP_KERNEL); 2209 GFP_KERNEL);
@@ -2208,6 +2227,9 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
2208 wm2200->dsp[i].num = i + 1; 2227 wm2200->dsp[i].num = i + 1;
2209 wm2200->dsp[i].dev = &i2c->dev; 2228 wm2200->dsp[i].dev = &i2c->dev;
2210 wm2200->dsp[i].regmap = wm2200->regmap; 2229 wm2200->dsp[i].regmap = wm2200->regmap;
2230 wm2200->dsp[i].sysclk_reg = WM2200_CLOCKING_3;
2231 wm2200->dsp[i].sysclk_mask = WM2200_SYSCLK_FREQ_MASK;
2232 wm2200->dsp[i].sysclk_shift = WM2200_SYSCLK_FREQ_SHIFT;
2211 } 2233 }
2212 2234
2213 wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1; 2235 wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1;
@@ -2218,6 +2240,9 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
2218 wm2200->dsp[1].mem = wm2200_dsp2_regions; 2240 wm2200->dsp[1].mem = wm2200_dsp2_regions;
2219 wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions); 2241 wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions);
2220 2242
2243 for (i = 0; i < ARRAY_SIZE(wm2200->dsp); i++)
2244 wm_adsp1_init(&wm2200->dsp[i]);
2245
2221 if (pdata) 2246 if (pdata)
2222 wm2200->pdata = *pdata; 2247 wm2200->pdata = *pdata;
2223 2248
@@ -2329,6 +2354,36 @@ static int wm2200_i2c_probe(struct i2c_client *i2c,
2329 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i); 2354 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2330 } 2355 }
2331 2356
2357 for (i = 0; i < WM2200_MAX_MICBIAS; i++) {
2358 if (!wm2200->pdata.micbias[i].mb_lvl &&
2359 !wm2200->pdata.micbias[i].bypass)
2360 continue;
2361
2362 /* Apply default for bypass mode */
2363 if (!wm2200->pdata.micbias[i].mb_lvl)
2364 wm2200->pdata.micbias[i].mb_lvl
2365 = WM2200_MBIAS_LVL_1V5;
2366
2367 val = (wm2200->pdata.micbias[i].mb_lvl -1)
2368 << WM2200_MICB1_LVL_SHIFT;
2369
2370 if (wm2200->pdata.micbias[i].discharge)
2371 val |= WM2200_MICB1_DISCH;
2372
2373 if (wm2200->pdata.micbias[i].fast_start)
2374 val |= WM2200_MICB1_RATE;
2375
2376 if (wm2200->pdata.micbias[i].bypass)
2377 val |= WM2200_MICB1_MODE;
2378
2379 regmap_update_bits(wm2200->regmap,
2380 WM2200_MIC_BIAS_CTRL_1 + i,
2381 WM2200_MICB1_LVL_MASK |
2382 WM2200_MICB1_DISCH |
2383 WM2200_MICB1_MODE |
2384 WM2200_MICB1_RATE, val);
2385 }
2386
2332 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) { 2387 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2333 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i], 2388 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2334 WM2200_IN1_MODE_MASK | 2389 WM2200_IN1_MODE_MASK |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 54397a508073..ac1745d030d6 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -563,6 +563,19 @@ SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
563SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L, 563SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
564 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1), 564 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
565 565
566SND_SOC_BYTES_MASK("EQ1 Coefficients", WM5100_EQ1_1, 20, WM5100_EQ1_ENA),
567SND_SOC_BYTES_MASK("EQ2 Coefficients", WM5100_EQ2_1, 20, WM5100_EQ2_ENA),
568SND_SOC_BYTES_MASK("EQ3 Coefficients", WM5100_EQ3_1, 20, WM5100_EQ3_ENA),
569SND_SOC_BYTES_MASK("EQ4 Coefficients", WM5100_EQ4_1, 20, WM5100_EQ4_ENA),
570
571SND_SOC_BYTES_MASK("DRC Coefficients", WM5100_DRC1_CTRL1, 5,
572 WM5100_DRCL_ENA | WM5100_DRCR_ENA),
573
574SND_SOC_BYTES("LHPF1 Coefficeints", WM5100_HPLPF1_2, 1),
575SND_SOC_BYTES("LHPF2 Coefficeints", WM5100_HPLPF2_2, 1),
576SND_SOC_BYTES("LHPF3 Coefficeints", WM5100_HPLPF3_2, 1),
577SND_SOC_BYTES("LHPF4 Coefficeints", WM5100_HPLPF4_2, 1),
578
566SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L, 579SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
567 WM5100_OUT1_OSR_SHIFT, 1, 0), 580 WM5100_OUT1_OSR_SHIFT, 1, 0),
568SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L, 581SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 7a9048dad1cd..b8d461db369f 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -45,6 +45,7 @@ static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
45static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 45static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
46static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 46static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
47static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); 47static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
48static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
48 49
49static const struct wm_adsp_region wm5102_dsp1_regions[] = { 50static const struct wm_adsp_region wm5102_dsp1_regions[] = {
50 { .type = WMFW_ADSP2_PM, .base = 0x100000 }, 51 { .type = WMFW_ADSP2_PM, .base = 0x100000 },
@@ -603,6 +604,17 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
603 return 0; 604 return 0;
604} 605}
605 606
607#define WM5102_NG_SRC(name, base) \
608 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
609 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
610 SOC_SINGLE(name " NG HPOUT2L Switch", base, 2, 1, 0), \
611 SOC_SINGLE(name " NG HPOUT2R Switch", base, 3, 1, 0), \
612 SOC_SINGLE(name " NG EPOUT Switch", base, 4, 1, 0), \
613 SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \
614 SOC_SINGLE(name " NG SPKOUTR Switch", base, 7, 1, 0), \
615 SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
616 SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0)
617
606static const struct snd_kcontrol_new wm5102_snd_controls[] = { 618static const struct snd_kcontrol_new wm5102_snd_controls[] = {
607SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, 619SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
608 ARIZONA_IN1_OSR_SHIFT, 1, 0), 620 ARIZONA_IN1_OSR_SHIFT, 1, 0),
@@ -611,32 +623,31 @@ SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
611SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL, 623SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
612 ARIZONA_IN3_OSR_SHIFT, 1, 0), 624 ARIZONA_IN3_OSR_SHIFT, 1, 0),
613 625
614SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL, 626SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
615 ARIZONA_IN1R_CONTROL, 627 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
616 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 628SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
617SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL, 629 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
618 ARIZONA_IN2R_CONTROL, 630SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
619 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 631 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
620SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL, 632SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
621 ARIZONA_IN3R_CONTROL, 633 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
622 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 634SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
623 635 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
624SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L, 636SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
625 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1), 637 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
626SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L, 638
627 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1), 639SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
628SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L, 640 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
629 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1), 641SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
630 642 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
631SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L, 643SOC_SINGLE_TLV("IN2L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
632 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT, 644 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
633 0xbf, 0, digital_tlv), 645SOC_SINGLE_TLV("IN2R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2R,
634SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L, 646 ARIZONA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
635 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT, 647SOC_SINGLE_TLV("IN3L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
636 0xbf, 0, digital_tlv), 648 ARIZONA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
637SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, 649SOC_SINGLE_TLV("IN3R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3R,
638 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, 650 ARIZONA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
639 0xbf, 0, digital_tlv),
640 651
641SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), 652SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
642SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), 653SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
@@ -774,6 +785,22 @@ SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
774SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, 785SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
775 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1), 786 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
776 787
788SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
789 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
790SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
791 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
792SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
793
794WM5102_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L),
795WM5102_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R),
796WM5102_NG_SRC("HPOUT2L", ARIZONA_NOISE_GATE_SELECT_2L),
797WM5102_NG_SRC("HPOUT2R", ARIZONA_NOISE_GATE_SELECT_2R),
798WM5102_NG_SRC("EPOUT", ARIZONA_NOISE_GATE_SELECT_3L),
799WM5102_NG_SRC("SPKOUTL", ARIZONA_NOISE_GATE_SELECT_4L),
800WM5102_NG_SRC("SPKOUTR", ARIZONA_NOISE_GATE_SELECT_4R),
801WM5102_NG_SRC("SPKDAT1L", ARIZONA_NOISE_GATE_SELECT_5L),
802WM5102_NG_SRC("SPKDAT1R", ARIZONA_NOISE_GATE_SELECT_5R),
803
777ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), 804ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
778ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), 805ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
779ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), 806ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
@@ -880,6 +907,18 @@ ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
880ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); 907ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
881ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); 908ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
882 909
910ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
911ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
912
913ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
914ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
915
916ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
917ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
918
919ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
920ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
921
883ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); 922ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE);
884ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); 923ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
885 924
@@ -896,8 +935,7 @@ static const unsigned int wm5102_aec_loopback_values[] = {
896 935
897static const struct soc_enum wm5102_aec_loopback = 936static const struct soc_enum wm5102_aec_loopback =
898 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, 937 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
899 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 938 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
900 ARIZONA_AEC_LOOPBACK_SRC_MASK,
901 ARRAY_SIZE(wm5102_aec_loopback_texts), 939 ARRAY_SIZE(wm5102_aec_loopback_texts),
902 wm5102_aec_loopback_texts, 940 wm5102_aec_loopback_texts,
903 wm5102_aec_loopback_values); 941 wm5102_aec_loopback_values);
@@ -1003,6 +1041,26 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
1003SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0, 1041SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
1004 NULL, 0), 1042 NULL, 0),
1005 1043
1044SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
1045 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
1046SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
1047 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
1048
1049SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
1050 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
1051SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
1052 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
1053
1054SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
1055 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
1056SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
1057 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
1058
1059SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
1060 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
1061SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
1062 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
1063
1006SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0, 1064SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
1007 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), 1065 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
1008SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0, 1066SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
@@ -1139,6 +1197,18 @@ ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
1139ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), 1197ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
1140ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), 1198ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
1141 1199
1200ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
1201ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
1202
1203ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
1204ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
1205
1206ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
1207ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
1208
1209ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
1210ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
1211
1142WM_ADSP2("DSP1", 0), 1212WM_ADSP2("DSP1", 0),
1143 1213
1144SND_SOC_DAPM_OUTPUT("HPOUT1L"), 1214SND_SOC_DAPM_OUTPUT("HPOUT1L"),
@@ -1153,6 +1223,8 @@ SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
1153SND_SOC_DAPM_OUTPUT("SPKOUTRP"), 1223SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
1154SND_SOC_DAPM_OUTPUT("SPKDAT1L"), 1224SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
1155SND_SOC_DAPM_OUTPUT("SPKDAT1R"), 1225SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1226
1227SND_SOC_DAPM_OUTPUT("MICSUPP"),
1156}; 1228};
1157 1229
1158#define ARIZONA_MIXER_INPUT_ROUTES(name) \ 1230#define ARIZONA_MIXER_INPUT_ROUTES(name) \
@@ -1194,6 +1266,14 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
1194 { name, "ASRC1R", "ASRC1R" }, \ 1266 { name, "ASRC1R", "ASRC1R" }, \
1195 { name, "ASRC2L", "ASRC2L" }, \ 1267 { name, "ASRC2L", "ASRC2L" }, \
1196 { name, "ASRC2R", "ASRC2R" }, \ 1268 { name, "ASRC2R", "ASRC2R" }, \
1269 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
1270 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
1271 { name, "ISRC1INT1", "ISRC1INT1" }, \
1272 { name, "ISRC1INT2", "ISRC1INT2" }, \
1273 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
1274 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
1275 { name, "ISRC2INT1", "ISRC2INT1" }, \
1276 { name, "ISRC2INT2", "ISRC2INT2" }, \
1197 { name, "DSP1.1", "DSP1" }, \ 1277 { name, "DSP1.1", "DSP1" }, \
1198 { name, "DSP1.2", "DSP1" }, \ 1278 { name, "DSP1.2", "DSP1" }, \
1199 { name, "DSP1.3", "DSP1" }, \ 1279 { name, "DSP1.3", "DSP1" }, \
@@ -1290,6 +1370,18 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1290 { "ASRC2L", NULL, "ASRC2L Input" }, 1370 { "ASRC2L", NULL, "ASRC2L Input" },
1291 { "ASRC2R", NULL, "ASRC2R Input" }, 1371 { "ASRC2R", NULL, "ASRC2R Input" },
1292 1372
1373 { "ISRC1DEC1", NULL, "ISRC1DEC1 Input" },
1374 { "ISRC1DEC2", NULL, "ISRC1DEC2 Input" },
1375
1376 { "ISRC1INT1", NULL, "ISRC1INT1 Input" },
1377 { "ISRC1INT2", NULL, "ISRC1INT2 Input" },
1378
1379 { "ISRC2DEC1", NULL, "ISRC2DEC1 Input" },
1380 { "ISRC2DEC2", NULL, "ISRC2DEC2 Input" },
1381
1382 { "ISRC2INT1", NULL, "ISRC2INT1 Input" },
1383 { "ISRC2INT2", NULL, "ISRC2INT2 Input" },
1384
1293 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), 1385 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1294 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), 1386 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1295 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), 1387 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
@@ -1337,6 +1429,18 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1337 ARIZONA_MUX_ROUTES("ASRC2L"), 1429 ARIZONA_MUX_ROUTES("ASRC2L"),
1338 ARIZONA_MUX_ROUTES("ASRC2R"), 1430 ARIZONA_MUX_ROUTES("ASRC2R"),
1339 1431
1432 ARIZONA_MUX_ROUTES("ISRC1INT1"),
1433 ARIZONA_MUX_ROUTES("ISRC1INT2"),
1434
1435 ARIZONA_MUX_ROUTES("ISRC1DEC1"),
1436 ARIZONA_MUX_ROUTES("ISRC1DEC2"),
1437
1438 ARIZONA_MUX_ROUTES("ISRC2INT1"),
1439 ARIZONA_MUX_ROUTES("ISRC2INT2"),
1440
1441 ARIZONA_MUX_ROUTES("ISRC2DEC1"),
1442 ARIZONA_MUX_ROUTES("ISRC2DEC2"),
1443
1340 ARIZONA_DSP_ROUTES("DSP1"), 1444 ARIZONA_DSP_ROUTES("DSP1"),
1341 1445
1342 { "AEC Loopback", "HPOUT1L", "OUT1L" }, 1446 { "AEC Loopback", "HPOUT1L", "OUT1L" },
@@ -1365,6 +1469,8 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1365 { "AEC Loopback", "SPKDAT1R", "OUT5R" }, 1469 { "AEC Loopback", "SPKDAT1R", "OUT5R" },
1366 { "SPKDAT1L", NULL, "OUT5L" }, 1470 { "SPKDAT1L", NULL, "OUT5L" },
1367 { "SPKDAT1R", NULL, "OUT5R" }, 1471 { "SPKDAT1R", NULL, "OUT5R" },
1472
1473 { "MICSUPP", NULL, "SYSCLK" },
1368}; 1474};
1369 1475
1370static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 1476static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
@@ -1464,6 +1570,10 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1464 if (ret != 0) 1570 if (ret != 0)
1465 return ret; 1571 return ret;
1466 1572
1573 ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1);
1574 if (ret != 0)
1575 return ret;
1576
1467 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1577 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1468 1578
1469 priv->core.arizona->dapm = &codec->dapm; 1579 priv->core.arizona->dapm = &codec->dapm;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index ae80c8c28536..cd17b477781d 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -41,6 +41,21 @@ static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); 43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
45
46#define WM5110_NG_SRC(name, base) \
47 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
48 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
49 SOC_SINGLE(name " NG HPOUT2L Switch", base, 2, 1, 0), \
50 SOC_SINGLE(name " NG HPOUT2R Switch", base, 3, 1, 0), \
51 SOC_SINGLE(name " NG HPOUT3L Switch", base, 4, 1, 0), \
52 SOC_SINGLE(name " NG HPOUT3R Switch", base, 5, 1, 0), \
53 SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \
54 SOC_SINGLE(name " NG SPKOUTR Switch", base, 7, 1, 0), \
55 SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
56 SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0), \
57 SOC_SINGLE(name " NG SPKDAT2L Switch", base, 10, 1, 0), \
58 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0)
44 59
45static const struct snd_kcontrol_new wm5110_snd_controls[] = { 60static const struct snd_kcontrol_new wm5110_snd_controls[] = {
46SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, 61SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
@@ -52,37 +67,35 @@ SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
52SOC_SINGLE("IN4 High Performance Switch", ARIZONA_IN4L_CONTROL, 67SOC_SINGLE("IN4 High Performance Switch", ARIZONA_IN4L_CONTROL,
53 ARIZONA_IN4_OSR_SHIFT, 1, 0), 68 ARIZONA_IN4_OSR_SHIFT, 1, 0),
54 69
55SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL, 70SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
56 ARIZONA_IN1R_CONTROL, 71 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
57 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 72SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
58SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL, 73 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
59 ARIZONA_IN2R_CONTROL, 74SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
60 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 75 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
61SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL, 76SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
62 ARIZONA_IN3R_CONTROL, 77 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
63 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 78SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
64 79 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
65SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L, 80SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
66 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1), 81 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
67SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L, 82
68 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1), 83SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
69SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L, 84 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
70 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1), 85SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
71SOC_DOUBLE_R("IN4 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_4L, 86 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
72 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_MUTE_SHIFT, 1, 1), 87SOC_SINGLE_TLV("IN2L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
73 88 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
74SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L, 89SOC_SINGLE_TLV("IN2R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2R,
75 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT, 90 ARIZONA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
76 0xbf, 0, digital_tlv), 91SOC_SINGLE_TLV("IN3L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
77SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L, 92 ARIZONA_IN3L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
78 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT, 93SOC_SINGLE_TLV("IN3R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3R,
79 0xbf, 0, digital_tlv), 94 ARIZONA_IN3R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
80SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L, 95SOC_SINGLE_TLV("IN4L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L,
81 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT, 96 ARIZONA_IN4L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
82 0xbf, 0, digital_tlv), 97SOC_SINGLE_TLV("IN4R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4R,
83SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L, 98 ARIZONA_IN4R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
84 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT,
85 0xbf, 0, digital_tlv),
86 99
87SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp), 100SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
88SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp), 101SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
@@ -263,6 +276,25 @@ SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
263SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), 276SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
264SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), 277SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
265 278
279SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
280 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
281SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
282 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
283SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
284
285WM5110_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L),
286WM5110_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R),
287WM5110_NG_SRC("HPOUT2L", ARIZONA_NOISE_GATE_SELECT_2L),
288WM5110_NG_SRC("HPOUT2R", ARIZONA_NOISE_GATE_SELECT_2R),
289WM5110_NG_SRC("HPOUT3L", ARIZONA_NOISE_GATE_SELECT_3L),
290WM5110_NG_SRC("HPOUT3R", ARIZONA_NOISE_GATE_SELECT_3R),
291WM5110_NG_SRC("SPKOUTL", ARIZONA_NOISE_GATE_SELECT_4L),
292WM5110_NG_SRC("SPKOUTR", ARIZONA_NOISE_GATE_SELECT_4R),
293WM5110_NG_SRC("SPKDAT1L", ARIZONA_NOISE_GATE_SELECT_5L),
294WM5110_NG_SRC("SPKDAT1R", ARIZONA_NOISE_GATE_SELECT_5R),
295WM5110_NG_SRC("SPKDAT2L", ARIZONA_NOISE_GATE_SELECT_6L),
296WM5110_NG_SRC("SPKDAT2R", ARIZONA_NOISE_GATE_SELECT_6R),
297
266ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE), 298ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
267ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE), 299ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
268ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE), 300ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
@@ -344,8 +376,7 @@ static const unsigned int wm5110_aec_loopback_values[] = {
344 376
345static const struct soc_enum wm5110_aec_loopback = 377static const struct soc_enum wm5110_aec_loopback =
346 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, 378 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
347 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 379 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
348 ARIZONA_AEC_LOOPBACK_SRC_MASK,
349 ARRAY_SIZE(wm5110_aec_loopback_texts), 380 ARRAY_SIZE(wm5110_aec_loopback_texts),
350 wm5110_aec_loopback_texts, 381 wm5110_aec_loopback_texts,
351 wm5110_aec_loopback_values); 382 wm5110_aec_loopback_values);
@@ -625,6 +656,8 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
625SND_SOC_DAPM_OUTPUT("SPKDAT1R"), 656SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
626SND_SOC_DAPM_OUTPUT("SPKDAT2L"), 657SND_SOC_DAPM_OUTPUT("SPKDAT2L"),
627SND_SOC_DAPM_OUTPUT("SPKDAT2R"), 658SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
659
660SND_SOC_DAPM_OUTPUT("MICSUPP"),
628}; 661};
629 662
630#define ARIZONA_MIXER_INPUT_ROUTES(name) \ 663#define ARIZONA_MIXER_INPUT_ROUTES(name) \
@@ -833,6 +866,8 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
833 866
834 { "SPKDAT2L", NULL, "OUT6L" }, 867 { "SPKDAT2L", NULL, "OUT6L" },
835 { "SPKDAT2R", NULL, "OUT6R" }, 868 { "SPKDAT2R", NULL, "OUT6R" },
869
870 { "MICSUPP", NULL, "SYSCLK" },
836}; 871};
837 872
838static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 873static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index fb92fb47d636..ec0efc1443ba 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -283,18 +283,16 @@ static int pga_event(struct snd_soc_dapm_widget *w,
283 out->ramp = WM8350_RAMP_UP; 283 out->ramp = WM8350_RAMP_UP;
284 out->active = 1; 284 out->active = 1;
285 285
286 if (!delayed_work_pending(&codec->dapm.delayed_work)) 286 schedule_delayed_work(&codec->dapm.delayed_work,
287 schedule_delayed_work(&codec->dapm.delayed_work, 287 msecs_to_jiffies(1));
288 msecs_to_jiffies(1));
289 break; 288 break;
290 289
291 case SND_SOC_DAPM_PRE_PMD: 290 case SND_SOC_DAPM_PRE_PMD:
292 out->ramp = WM8350_RAMP_DOWN; 291 out->ramp = WM8350_RAMP_DOWN;
293 out->active = 0; 292 out->active = 0;
294 293
295 if (!delayed_work_pending(&codec->dapm.delayed_work)) 294 schedule_delayed_work(&codec->dapm.delayed_work,
296 schedule_delayed_work(&codec->dapm.delayed_work, 295 msecs_to_jiffies(1));
297 msecs_to_jiffies(1));
298 break; 296 break;
299 } 297 }
300 298
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index d321a875b029..1704b1e119cb 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -395,9 +395,6 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
395 /* power down the PLL before reprogramming it */ 395 /* power down the PLL before reprogramming it */
396 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); 396 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1);
397 397
398 if (!freq_in || !freq_out)
399 return 0;
400
401 /* set PLLN and PRESCALE */ 398 /* set PLLN and PRESCALE */
402 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, 399 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
403 pll_div.n | (pll_div.prescale << 4)); 400 pll_div.n | (pll_div.prescale << 4));
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index bd4b0db4cdaa..e9710280e5e1 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2873,22 +2873,20 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2873 2873
2874 ret = 0; 2874 ret = 0;
2875 2875
2876 if (fll1 & WM8962_FLL_ENA) { 2876 /* This should be a massive overestimate but go even
2877 /* This should be a massive overestimate but go even 2877 * higher if we'll error out
2878 * higher if we'll error out 2878 */
2879 */ 2879 if (wm8962->irq)
2880 if (wm8962->irq) 2880 timeout = msecs_to_jiffies(5);
2881 timeout = msecs_to_jiffies(5); 2881 else
2882 else 2882 timeout = msecs_to_jiffies(1);
2883 timeout = msecs_to_jiffies(1);
2884 2883
2885 timeout = wait_for_completion_timeout(&wm8962->fll_lock, 2884 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
2886 timeout); 2885 timeout);
2887 2886
2888 if (timeout == 0 && wm8962->irq) { 2887 if (timeout == 0 && wm8962->irq) {
2889 dev_err(codec->dev, "FLL lock timed out"); 2888 dev_err(codec->dev, "FLL lock timed out");
2890 ret = -ETIMEDOUT; 2889 ret = -ETIMEDOUT;
2891 }
2892 } 2890 }
2893 2891
2894 wm8962->fll_fref = Fref; 2892 wm8962->fll_fref = Fref;
@@ -3189,7 +3187,7 @@ static void wm8962_init_beep(struct snd_soc_codec *codec)
3189 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3187 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3190 int ret; 3188 int ret;
3191 3189
3192 wm8962->beep = input_allocate_device(); 3190 wm8962->beep = devm_input_allocate_device(codec->dev);
3193 if (!wm8962->beep) { 3191 if (!wm8962->beep) {
3194 dev_err(codec->dev, "Failed to allocate beep device\n"); 3192 dev_err(codec->dev, "Failed to allocate beep device\n");
3195 return; 3193 return;
@@ -3210,7 +3208,6 @@ static void wm8962_init_beep(struct snd_soc_codec *codec)
3210 3208
3211 ret = input_register_device(wm8962->beep); 3209 ret = input_register_device(wm8962->beep);
3212 if (ret != 0) { 3210 if (ret != 0) {
3213 input_free_device(wm8962->beep);
3214 wm8962->beep = NULL; 3211 wm8962->beep = NULL;
3215 dev_err(codec->dev, "Failed to register beep device\n"); 3212 dev_err(codec->dev, "Failed to register beep device\n");
3216 } 3213 }
@@ -3227,7 +3224,6 @@ static void wm8962_free_beep(struct snd_soc_codec *codec)
3227 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3224 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3228 3225
3229 device_remove_file(codec->dev, &dev_attr_beep); 3226 device_remove_file(codec->dev, &dev_attr_beep);
3230 input_unregister_device(wm8962->beep);
3231 cancel_work_sync(&wm8962->beep_work); 3227 cancel_work_sync(&wm8962->beep_work);
3232 wm8962->beep = NULL; 3228 wm8962->beep = NULL;
3233 3229
@@ -3758,10 +3754,17 @@ static const struct i2c_device_id wm8962_i2c_id[] = {
3758}; 3754};
3759MODULE_DEVICE_TABLE(i2c, wm8962_i2c_id); 3755MODULE_DEVICE_TABLE(i2c, wm8962_i2c_id);
3760 3756
3757static const struct of_device_id wm8962_of_match[] = {
3758 { .compatible = "wlf,wm8962", },
3759 { }
3760};
3761MODULE_DEVICE_TABLE(of, wm8962_of_match);
3762
3761static struct i2c_driver wm8962_i2c_driver = { 3763static struct i2c_driver wm8962_i2c_driver = {
3762 .driver = { 3764 .driver = {
3763 .name = "wm8962", 3765 .name = "wm8962",
3764 .owner = THIS_MODULE, 3766 .owner = THIS_MODULE,
3767 .of_match_table = wm8962_of_match,
3765 .pm = &wm8962_pm, 3768 .pm = &wm8962_pm,
3766 }, 3769 },
3767 .probe = wm8962_i2c_probe, 3770 .probe = wm8962_i2c_probe,
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index ea58b73e86b2..b47c252ef901 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -113,15 +113,15 @@ SOC_ENUM("Equaliser Function", wm8974_enum[3]),
113SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]), 113SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
114SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1, 0, 24, 1, eq_tlv), 114SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1, 0, 24, 1, eq_tlv),
115 115
116SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]), 116SOC_ENUM("Equaliser EQ2 Bandwidth", wm8974_enum[5]),
117SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]), 117SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
118SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2, 0, 24, 1, eq_tlv), 118SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2, 0, 24, 1, eq_tlv),
119 119
120SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]), 120SOC_ENUM("Equaliser EQ3 Bandwidth", wm8974_enum[7]),
121SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]), 121SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
122SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3, 0, 24, 1, eq_tlv), 122SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3, 0, 24, 1, eq_tlv),
123 123
124SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]), 124SOC_ENUM("Equaliser EQ4 Bandwidth", wm8974_enum[9]),
125SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]), 125SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
126SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv), 126SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv),
127 127
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index f347af3a67c2..029f31c8e703 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -166,15 +166,15 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
166 SOC_ENUM("EQ1 Cut Off", eq1), 166 SOC_ENUM("EQ1 Cut Off", eq1),
167 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv), 167 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
168 168
169 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw), 169 SOC_ENUM("Equaliser EQ2 Bandwidth", eq2bw),
170 SOC_ENUM("EQ2 Cut Off", eq2), 170 SOC_ENUM("EQ2 Cut Off", eq2),
171 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv), 171 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
172 172
173 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw), 173 SOC_ENUM("Equaliser EQ3 Bandwidth", eq3bw),
174 SOC_ENUM("EQ3 Cut Off", eq3), 174 SOC_ENUM("EQ3 Cut Off", eq3),
175 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv), 175 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
176 176
177 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw), 177 SOC_ENUM("Equaliser EQ4 Bandwidth", eq4bw),
178 SOC_ENUM("EQ4 Cut Off", eq4), 178 SOC_ENUM("EQ4 Cut Off", eq4),
179 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv), 179 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
180 180
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 9fe1e041da49..aa41ba0dfff4 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -353,13 +353,13 @@ static const struct snd_kcontrol_new wm8983_snd_controls[] = {
353 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put), 353 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
354 SOC_ENUM("EQ1 Cutoff", eq1_cutoff), 354 SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
355 SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv), 355 SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
356 SOC_ENUM("EQ2 Bandwith", eq2_bw), 356 SOC_ENUM("EQ2 Bandwidth", eq2_bw),
357 SOC_ENUM("EQ2 Cutoff", eq2_cutoff), 357 SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
358 SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv), 358 SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
359 SOC_ENUM("EQ3 Bandwith", eq3_bw), 359 SOC_ENUM("EQ3 Bandwidth", eq3_bw),
360 SOC_ENUM("EQ3 Cutoff", eq3_cutoff), 360 SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
361 SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv), 361 SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
362 SOC_ENUM("EQ4 Bandwith", eq4_bw), 362 SOC_ENUM("EQ4 Bandwidth", eq4_bw),
363 SOC_ENUM("EQ4 Cutoff", eq4_cutoff), 363 SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
364 SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv), 364 SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
365 SOC_ENUM("EQ5 Cutoff", eq5_cutoff), 365 SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
@@ -851,30 +851,33 @@ static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
851 struct pll_div pll_div; 851 struct pll_div pll_div;
852 852
853 codec = dai->codec; 853 codec = dai->codec;
854 if (freq_in && freq_out) { 854 if (!freq_in || !freq_out) {
855 /* disable the PLL */
856 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
857 WM8983_PLLEN_MASK, 0);
858 return 0;
859 } else {
855 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in); 860 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
856 if (ret) 861 if (ret)
857 return ret; 862 return ret;
858 }
859
860 /* disable the PLL before re-programming it */
861 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
862 WM8983_PLLEN_MASK, 0);
863 863
864 if (!freq_in || !freq_out) 864 /* disable the PLL before re-programming it */
865 return 0; 865 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
866 WM8983_PLLEN_MASK, 0);
867
868 /* set PLLN and PRESCALE */
869 snd_soc_write(codec, WM8983_PLL_N,
870 (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
871 | pll_div.n);
872 /* set PLLK */
873 snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
874 snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
875 snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
876 /* enable the PLL */
877 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
878 WM8983_PLLEN_MASK, WM8983_PLLEN);
879 }
866 880
867 /* set PLLN and PRESCALE */
868 snd_soc_write(codec, WM8983_PLL_N,
869 (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
870 | pll_div.n);
871 /* set PLLK */
872 snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
873 snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
874 snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
875 /* enable the PLL */
876 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
877 WM8983_PLLEN_MASK, WM8983_PLLEN);
878 return 0; 881 return 0;
879} 882}
880 883
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index ab3782657ac8..18f2babe1090 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -371,13 +371,13 @@ static const struct snd_kcontrol_new wm8985_snd_controls[] = {
371 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put), 371 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
372 SOC_ENUM("EQ1 Cutoff", eq1_cutoff), 372 SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
373 SOC_SINGLE_TLV("EQ1 Volume", WM8985_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv), 373 SOC_SINGLE_TLV("EQ1 Volume", WM8985_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
374 SOC_ENUM("EQ2 Bandwith", eq2_bw), 374 SOC_ENUM("EQ2 Bandwidth", eq2_bw),
375 SOC_ENUM("EQ2 Cutoff", eq2_cutoff), 375 SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
376 SOC_SINGLE_TLV("EQ2 Volume", WM8985_EQ2_PEAK_1, 0, 24, 1, eq_tlv), 376 SOC_SINGLE_TLV("EQ2 Volume", WM8985_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
377 SOC_ENUM("EQ3 Bandwith", eq3_bw), 377 SOC_ENUM("EQ3 Bandwidth", eq3_bw),
378 SOC_ENUM("EQ3 Cutoff", eq3_cutoff), 378 SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
379 SOC_SINGLE_TLV("EQ3 Volume", WM8985_EQ3_PEAK_2, 0, 24, 1, eq_tlv), 379 SOC_SINGLE_TLV("EQ3 Volume", WM8985_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
380 SOC_ENUM("EQ4 Bandwith", eq4_bw), 380 SOC_ENUM("EQ4 Bandwidth", eq4_bw),
381 SOC_ENUM("EQ4 Cutoff", eq4_cutoff), 381 SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
382 SOC_SINGLE_TLV("EQ4 Volume", WM8985_EQ4_PEAK_3, 0, 24, 1, eq_tlv), 382 SOC_SINGLE_TLV("EQ4 Volume", WM8985_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
383 SOC_ENUM("EQ5 Cutoff", eq5_cutoff), 383 SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
@@ -830,33 +830,30 @@ static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
830 struct pll_div pll_div; 830 struct pll_div pll_div;
831 831
832 codec = dai->codec; 832 codec = dai->codec;
833 if (freq_in && freq_out) { 833 if (!freq_in || !freq_out) {
834 /* disable the PLL */
835 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
836 WM8985_PLLEN_MASK, 0);
837 } else {
834 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in); 838 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
835 if (ret) 839 if (ret)
836 return ret; 840 return ret;
837 }
838 841
839 /* disable the PLL before reprogramming it */ 842 /* set PLLN and PRESCALE */
840 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1, 843 snd_soc_write(codec, WM8985_PLL_N,
841 WM8985_PLLEN_MASK, 0); 844 (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
842 845 | pll_div.n);
843 if (!freq_in || !freq_out) 846 /* set PLLK */
844 return 0; 847 snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
845 848 snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
846 /* set PLLN and PRESCALE */ 849 snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
847 snd_soc_write(codec, WM8985_PLL_N, 850 /* set the source of the clock to be the PLL */
848 (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT) 851 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
849 | pll_div.n); 852 WM8985_CLKSEL_MASK, WM8985_CLKSEL);
850 /* set PLLK */ 853 /* enable the PLL */
851 snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff); 854 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
852 snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff); 855 WM8985_PLLEN_MASK, WM8985_PLLEN);
853 snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18)); 856 }
854 /* set the source of the clock to be the PLL */
855 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
856 WM8985_CLKSEL_MASK, WM8985_CLKSEL);
857 /* enable the PLL */
858 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
859 WM8985_PLLEN_MASK, WM8985_PLLEN);
860 return 0; 857 return 0;
861} 858}
862 859
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 3b269fa226bd..c9bd445c4976 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3737,7 +3737,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3737{ 3737{
3738 struct wm8994_priv *wm8994 = data; 3738 struct wm8994_priv *wm8994 = data;
3739 struct snd_soc_codec *codec = wm8994->hubs.codec; 3739 struct snd_soc_codec *codec = wm8994->hubs.codec;
3740 int reg, count; 3740 int reg, count, ret;
3741 3741
3742 /* 3742 /*
3743 * Jack detection may have detected a removal simulataneously 3743 * Jack detection may have detected a removal simulataneously
@@ -3783,11 +3783,11 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3783 3783
3784 /* Avoid a transient report when the accessory is being removed */ 3784 /* Avoid a transient report when the accessory is being removed */
3785 if (wm8994->jackdet) { 3785 if (wm8994->jackdet) {
3786 reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); 3786 ret = snd_soc_read(codec, WM1811_JACKDET_CTRL);
3787 if (reg < 0) { 3787 if (ret < 0) {
3788 dev_err(codec->dev, "Failed to read jack status: %d\n", 3788 dev_err(codec->dev, "Failed to read jack status: %d\n",
3789 reg); 3789 ret);
3790 } else if (!(reg & WM1811_JACKDET_LVL)) { 3790 } else if (!(ret & WM1811_JACKDET_LVL)) {
3791 dev_dbg(codec->dev, "Ignoring removed jack\n"); 3791 dev_dbg(codec->dev, "Ignoring removed jack\n");
3792 return IRQ_HANDLED; 3792 return IRQ_HANDLED;
3793 } 3793 }
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 7b198c38f3ef..f3f7e75f8628 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/firmware.h> 17#include <linux/firmware.h>
18#include <linux/list.h>
18#include <linux/pm.h> 19#include <linux/pm.h>
19#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
20#include <linux/regmap.h> 21#include <linux/regmap.h>
@@ -103,9 +104,19 @@
103#define ADSP1_START_SHIFT 0 /* DSP1_START */ 104#define ADSP1_START_SHIFT 0 /* DSP1_START */
104#define ADSP1_START_WIDTH 1 /* DSP1_START */ 105#define ADSP1_START_WIDTH 1 /* DSP1_START */
105 106
106#define ADSP2_CONTROL 0 107/*
107#define ADSP2_CLOCKING 1 108 * ADSP1 Control 31
108#define ADSP2_STATUS1 4 109 */
110#define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */
111#define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */
112#define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */
113
114#define ADSP2_CONTROL 0x0
115#define ADSP2_CLOCKING 0x1
116#define ADSP2_STATUS1 0x4
117#define ADSP2_WDMA_CONFIG_1 0x30
118#define ADSP2_WDMA_CONFIG_2 0x31
119#define ADSP2_RDMA_CONFIG_1 0x34
109 120
110/* 121/*
111 * ADSP2 Control 122 * ADSP2 Control
@@ -143,6 +154,109 @@
143#define ADSP2_RAM_RDY_SHIFT 0 154#define ADSP2_RAM_RDY_SHIFT 0
144#define ADSP2_RAM_RDY_WIDTH 1 155#define ADSP2_RAM_RDY_WIDTH 1
145 156
157struct wm_adsp_buf {
158 struct list_head list;
159 void *buf;
160};
161
162static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len,
163 struct list_head *list)
164{
165 struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
166
167 if (buf == NULL)
168 return NULL;
169
170 buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA);
171 if (!buf->buf) {
172 kfree(buf);
173 return NULL;
174 }
175
176 if (list)
177 list_add_tail(&buf->list, list);
178
179 return buf;
180}
181
182static void wm_adsp_buf_free(struct list_head *list)
183{
184 while (!list_empty(list)) {
185 struct wm_adsp_buf *buf = list_first_entry(list,
186 struct wm_adsp_buf,
187 list);
188 list_del(&buf->list);
189 kfree(buf->buf);
190 kfree(buf);
191 }
192}
193
194#define WM_ADSP_NUM_FW 4
195
196static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
197 "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC"
198};
199
200static struct {
201 const char *file;
202} wm_adsp_fw[WM_ADSP_NUM_FW] = {
203 { .file = "mbc-vss" },
204 { .file = "tx" },
205 { .file = "tx-spk" },
206 { .file = "rx-anc" },
207};
208
209static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
210 struct snd_ctl_elem_value *ucontrol)
211{
212 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
213 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
214 struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
215
216 ucontrol->value.integer.value[0] = adsp[e->shift_l].fw;
217
218 return 0;
219}
220
221static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
222 struct snd_ctl_elem_value *ucontrol)
223{
224 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
225 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
226 struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
227
228 if (ucontrol->value.integer.value[0] == adsp[e->shift_l].fw)
229 return 0;
230
231 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW)
232 return -EINVAL;
233
234 if (adsp[e->shift_l].running)
235 return -EBUSY;
236
237 adsp[e->shift_l].fw = ucontrol->value.integer.value[0];
238
239 return 0;
240}
241
242static const struct soc_enum wm_adsp_fw_enum[] = {
243 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
244 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
245 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
246 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
247};
248
249const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
250 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
251 wm_adsp_fw_get, wm_adsp_fw_put),
252 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
253 wm_adsp_fw_get, wm_adsp_fw_put),
254 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
255 wm_adsp_fw_get, wm_adsp_fw_put),
256 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
257 wm_adsp_fw_get, wm_adsp_fw_put),
258};
259EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
146 260
147static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 261static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
148 int type) 262 int type)
@@ -156,8 +270,29 @@ static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
156 return NULL; 270 return NULL;
157} 271}
158 272
273static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
274 unsigned int offset)
275{
276 switch (region->type) {
277 case WMFW_ADSP1_PM:
278 return region->base + (offset * 3);
279 case WMFW_ADSP1_DM:
280 return region->base + (offset * 2);
281 case WMFW_ADSP2_XM:
282 return region->base + (offset * 2);
283 case WMFW_ADSP2_YM:
284 return region->base + (offset * 2);
285 case WMFW_ADSP1_ZM:
286 return region->base + (offset * 2);
287 default:
288 WARN_ON(NULL != "Unknown memory region type");
289 return offset;
290 }
291}
292
159static int wm_adsp_load(struct wm_adsp *dsp) 293static int wm_adsp_load(struct wm_adsp *dsp)
160{ 294{
295 LIST_HEAD(buf_list);
161 const struct firmware *firmware; 296 const struct firmware *firmware;
162 struct regmap *regmap = dsp->regmap; 297 struct regmap *regmap = dsp->regmap;
163 unsigned int pos = 0; 298 unsigned int pos = 0;
@@ -169,7 +304,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
169 const struct wm_adsp_region *mem; 304 const struct wm_adsp_region *mem;
170 const char *region_name; 305 const char *region_name;
171 char *file, *text; 306 char *file, *text;
172 void *buf; 307 struct wm_adsp_buf *buf;
173 unsigned int reg; 308 unsigned int reg;
174 int regions = 0; 309 int regions = 0;
175 int ret, offset, type, sizes; 310 int ret, offset, type, sizes;
@@ -178,7 +313,8 @@ static int wm_adsp_load(struct wm_adsp *dsp)
178 if (file == NULL) 313 if (file == NULL)
179 return -ENOMEM; 314 return -ENOMEM;
180 315
181 snprintf(file, PAGE_SIZE, "%s-dsp%d.wmfw", dsp->part, dsp->num); 316 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num,
317 wm_adsp_fw[dsp->fw].file);
182 file[PAGE_SIZE - 1] = '\0'; 318 file[PAGE_SIZE - 1] = '\0';
183 319
184 ret = request_firmware(&firmware, file, dsp->dev); 320 ret = request_firmware(&firmware, file, dsp->dev);
@@ -283,27 +419,27 @@ static int wm_adsp_load(struct wm_adsp *dsp)
283 case WMFW_ADSP1_PM: 419 case WMFW_ADSP1_PM:
284 BUG_ON(!mem); 420 BUG_ON(!mem);
285 region_name = "PM"; 421 region_name = "PM";
286 reg = mem->base + (offset * 3); 422 reg = wm_adsp_region_to_reg(mem, offset);
287 break; 423 break;
288 case WMFW_ADSP1_DM: 424 case WMFW_ADSP1_DM:
289 BUG_ON(!mem); 425 BUG_ON(!mem);
290 region_name = "DM"; 426 region_name = "DM";
291 reg = mem->base + (offset * 2); 427 reg = wm_adsp_region_to_reg(mem, offset);
292 break; 428 break;
293 case WMFW_ADSP2_XM: 429 case WMFW_ADSP2_XM:
294 BUG_ON(!mem); 430 BUG_ON(!mem);
295 region_name = "XM"; 431 region_name = "XM";
296 reg = mem->base + (offset * 2); 432 reg = wm_adsp_region_to_reg(mem, offset);
297 break; 433 break;
298 case WMFW_ADSP2_YM: 434 case WMFW_ADSP2_YM:
299 BUG_ON(!mem); 435 BUG_ON(!mem);
300 region_name = "YM"; 436 region_name = "YM";
301 reg = mem->base + (offset * 2); 437 reg = wm_adsp_region_to_reg(mem, offset);
302 break; 438 break;
303 case WMFW_ADSP1_ZM: 439 case WMFW_ADSP1_ZM:
304 BUG_ON(!mem); 440 BUG_ON(!mem);
305 region_name = "ZM"; 441 region_name = "ZM";
306 reg = mem->base + (offset * 2); 442 reg = wm_adsp_region_to_reg(mem, offset);
307 break; 443 break;
308 default: 444 default:
309 adsp_warn(dsp, 445 adsp_warn(dsp,
@@ -323,18 +459,16 @@ static int wm_adsp_load(struct wm_adsp *dsp)
323 } 459 }
324 460
325 if (reg) { 461 if (reg) {
326 buf = kmemdup(region->data, le32_to_cpu(region->len), 462 buf = wm_adsp_buf_alloc(region->data,
327 GFP_KERNEL); 463 le32_to_cpu(region->len),
464 &buf_list);
328 if (!buf) { 465 if (!buf) {
329 adsp_err(dsp, "Out of memory\n"); 466 adsp_err(dsp, "Out of memory\n");
330 return -ENOMEM; 467 return -ENOMEM;
331 } 468 }
332 469
333 ret = regmap_raw_write(regmap, reg, buf, 470 ret = regmap_raw_write_async(regmap, reg, buf->buf,
334 le32_to_cpu(region->len)); 471 le32_to_cpu(region->len));
335
336 kfree(buf);
337
338 if (ret != 0) { 472 if (ret != 0) {
339 adsp_err(dsp, 473 adsp_err(dsp,
340 "%s.%d: Failed to write %d bytes at %d in %s: %d\n", 474 "%s.%d: Failed to write %d bytes at %d in %s: %d\n",
@@ -348,12 +482,20 @@ static int wm_adsp_load(struct wm_adsp *dsp)
348 pos += le32_to_cpu(region->len) + sizeof(*region); 482 pos += le32_to_cpu(region->len) + sizeof(*region);
349 regions++; 483 regions++;
350 } 484 }
351 485
486 ret = regmap_async_complete(regmap);
487 if (ret != 0) {
488 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
489 goto out_fw;
490 }
491
352 if (pos > firmware->size) 492 if (pos > firmware->size)
353 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 493 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
354 file, regions, pos - firmware->size); 494 file, regions, pos - firmware->size);
355 495
356out_fw: 496out_fw:
497 regmap_async_complete(regmap);
498 wm_adsp_buf_free(&buf_list);
357 release_firmware(firmware); 499 release_firmware(firmware);
358out: 500out:
359 kfree(file); 501 kfree(file);
@@ -361,22 +503,222 @@ out:
361 return ret; 503 return ret;
362} 504}
363 505
506static int wm_adsp_setup_algs(struct wm_adsp *dsp)
507{
508 struct regmap *regmap = dsp->regmap;
509 struct wmfw_adsp1_id_hdr adsp1_id;
510 struct wmfw_adsp2_id_hdr adsp2_id;
511 struct wmfw_adsp1_alg_hdr *adsp1_alg;
512 struct wmfw_adsp2_alg_hdr *adsp2_alg;
513 void *alg, *buf;
514 struct wm_adsp_alg_region *region;
515 const struct wm_adsp_region *mem;
516 unsigned int pos, term;
517 size_t algs, buf_size;
518 __be32 val;
519 int i, ret;
520
521 switch (dsp->type) {
522 case WMFW_ADSP1:
523 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM);
524 break;
525 case WMFW_ADSP2:
526 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
527 break;
528 default:
529 mem = NULL;
530 break;
531 }
532
533 if (mem == NULL) {
534 BUG_ON(mem != NULL);
535 return -EINVAL;
536 }
537
538 switch (dsp->type) {
539 case WMFW_ADSP1:
540 ret = regmap_raw_read(regmap, mem->base, &adsp1_id,
541 sizeof(adsp1_id));
542 if (ret != 0) {
543 adsp_err(dsp, "Failed to read algorithm info: %d\n",
544 ret);
545 return ret;
546 }
547
548 buf = &adsp1_id;
549 buf_size = sizeof(adsp1_id);
550
551 algs = be32_to_cpu(adsp1_id.algs);
552 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
553 be32_to_cpu(adsp1_id.fw.id),
554 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16,
555 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8,
556 be32_to_cpu(adsp1_id.fw.ver) & 0xff,
557 algs);
558
559 pos = sizeof(adsp1_id) / 2;
560 term = pos + ((sizeof(*adsp1_alg) * algs) / 2);
561 break;
562
563 case WMFW_ADSP2:
564 ret = regmap_raw_read(regmap, mem->base, &adsp2_id,
565 sizeof(adsp2_id));
566 if (ret != 0) {
567 adsp_err(dsp, "Failed to read algorithm info: %d\n",
568 ret);
569 return ret;
570 }
571
572 buf = &adsp2_id;
573 buf_size = sizeof(adsp2_id);
574
575 algs = be32_to_cpu(adsp2_id.algs);
576 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
577 be32_to_cpu(adsp2_id.fw.id),
578 (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16,
579 (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8,
580 be32_to_cpu(adsp2_id.fw.ver) & 0xff,
581 algs);
582
583 pos = sizeof(adsp2_id) / 2;
584 term = pos + ((sizeof(*adsp2_alg) * algs) / 2);
585 break;
586
587 default:
588 BUG_ON(NULL == "Unknown DSP type");
589 return -EINVAL;
590 }
591
592 if (algs == 0) {
593 adsp_err(dsp, "No algorithms\n");
594 return -EINVAL;
595 }
596
597 if (algs > 1024) {
598 adsp_err(dsp, "Algorithm count %zx excessive\n", algs);
599 print_hex_dump_bytes(dev_name(dsp->dev), DUMP_PREFIX_OFFSET,
600 buf, buf_size);
601 return -EINVAL;
602 }
603
604 /* Read the terminator first to validate the length */
605 ret = regmap_raw_read(regmap, mem->base + term, &val, sizeof(val));
606 if (ret != 0) {
607 adsp_err(dsp, "Failed to read algorithm list end: %d\n",
608 ret);
609 return ret;
610 }
611
612 if (be32_to_cpu(val) != 0xbedead)
613 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n",
614 term, be32_to_cpu(val));
615
616 alg = kzalloc((term - pos) * 2, GFP_KERNEL | GFP_DMA);
617 if (!alg)
618 return -ENOMEM;
619
620 ret = regmap_raw_read(regmap, mem->base + pos, alg, (term - pos) * 2);
621 if (ret != 0) {
622 adsp_err(dsp, "Failed to read algorithm list: %d\n",
623 ret);
624 goto out;
625 }
626
627 adsp1_alg = alg;
628 adsp2_alg = alg;
629
630 for (i = 0; i < algs; i++) {
631 switch (dsp->type) {
632 case WMFW_ADSP1:
633 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n",
634 i, be32_to_cpu(adsp1_alg[i].alg.id),
635 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16,
636 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8,
637 be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff,
638 be32_to_cpu(adsp1_alg[i].dm),
639 be32_to_cpu(adsp1_alg[i].zm));
640
641 region = kzalloc(sizeof(*region), GFP_KERNEL);
642 if (!region)
643 return -ENOMEM;
644 region->type = WMFW_ADSP1_DM;
645 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
646 region->base = be32_to_cpu(adsp1_alg[i].dm);
647 list_add_tail(&region->list, &dsp->alg_regions);
648
649 region = kzalloc(sizeof(*region), GFP_KERNEL);
650 if (!region)
651 return -ENOMEM;
652 region->type = WMFW_ADSP1_ZM;
653 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
654 region->base = be32_to_cpu(adsp1_alg[i].zm);
655 list_add_tail(&region->list, &dsp->alg_regions);
656 break;
657
658 case WMFW_ADSP2:
659 adsp_info(dsp,
660 "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
661 i, be32_to_cpu(adsp2_alg[i].alg.id),
662 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
663 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
664 be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
665 be32_to_cpu(adsp2_alg[i].xm),
666 be32_to_cpu(adsp2_alg[i].ym),
667 be32_to_cpu(adsp2_alg[i].zm));
668
669 region = kzalloc(sizeof(*region), GFP_KERNEL);
670 if (!region)
671 return -ENOMEM;
672 region->type = WMFW_ADSP2_XM;
673 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
674 region->base = be32_to_cpu(adsp2_alg[i].xm);
675 list_add_tail(&region->list, &dsp->alg_regions);
676
677 region = kzalloc(sizeof(*region), GFP_KERNEL);
678 if (!region)
679 return -ENOMEM;
680 region->type = WMFW_ADSP2_YM;
681 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
682 region->base = be32_to_cpu(adsp2_alg[i].ym);
683 list_add_tail(&region->list, &dsp->alg_regions);
684
685 region = kzalloc(sizeof(*region), GFP_KERNEL);
686 if (!region)
687 return -ENOMEM;
688 region->type = WMFW_ADSP2_ZM;
689 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
690 region->base = be32_to_cpu(adsp2_alg[i].zm);
691 list_add_tail(&region->list, &dsp->alg_regions);
692 break;
693 }
694 }
695
696out:
697 kfree(alg);
698 return ret;
699}
700
364static int wm_adsp_load_coeff(struct wm_adsp *dsp) 701static int wm_adsp_load_coeff(struct wm_adsp *dsp)
365{ 702{
703 LIST_HEAD(buf_list);
366 struct regmap *regmap = dsp->regmap; 704 struct regmap *regmap = dsp->regmap;
367 struct wmfw_coeff_hdr *hdr; 705 struct wmfw_coeff_hdr *hdr;
368 struct wmfw_coeff_item *blk; 706 struct wmfw_coeff_item *blk;
369 const struct firmware *firmware; 707 const struct firmware *firmware;
708 const struct wm_adsp_region *mem;
709 struct wm_adsp_alg_region *alg_region;
370 const char *region_name; 710 const char *region_name;
371 int ret, pos, blocks, type, offset, reg; 711 int ret, pos, blocks, type, offset, reg;
372 char *file; 712 char *file;
373 void *buf; 713 struct wm_adsp_buf *buf;
714 int tmp;
374 715
375 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 716 file = kzalloc(PAGE_SIZE, GFP_KERNEL);
376 if (file == NULL) 717 if (file == NULL)
377 return -ENOMEM; 718 return -ENOMEM;
378 719
379 snprintf(file, PAGE_SIZE, "%s-dsp%d.bin", dsp->part, dsp->num); 720 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num,
721 wm_adsp_fw[dsp->fw].file);
380 file[PAGE_SIZE - 1] = '\0'; 722 file[PAGE_SIZE - 1] = '\0';
381 723
382 ret = request_firmware(&firmware, file, dsp->dev); 724 ret = request_firmware(&firmware, file, dsp->dev);
@@ -396,7 +738,17 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
396 hdr = (void*)&firmware->data[0]; 738 hdr = (void*)&firmware->data[0];
397 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 739 if (memcmp(hdr->magic, "WMDR", 4) != 0) {
398 adsp_err(dsp, "%s: invalid magic\n", file); 740 adsp_err(dsp, "%s: invalid magic\n", file);
399 return -EINVAL; 741 goto out_fw;
742 }
743
744 switch (be32_to_cpu(hdr->rev) & 0xff) {
745 case 1:
746 break;
747 default:
748 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
749 file, be32_to_cpu(hdr->rev) & 0xff);
750 ret = -EINVAL;
751 goto out_fw;
400 } 752 }
401 753
402 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, 754 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
@@ -411,8 +763,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
411 pos - firmware->size > sizeof(*blk)) { 763 pos - firmware->size > sizeof(*blk)) {
412 blk = (void*)(&firmware->data[pos]); 764 blk = (void*)(&firmware->data[pos]);
413 765
414 type = be32_to_cpu(blk->type) & 0xff; 766 type = le16_to_cpu(blk->type);
415 offset = le32_to_cpu(blk->offset) & 0xffffff; 767 offset = le16_to_cpu(blk->offset);
416 768
417 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", 769 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
418 file, blocks, le32_to_cpu(blk->id), 770 file, blocks, le32_to_cpu(blk->id),
@@ -425,52 +777,105 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
425 reg = 0; 777 reg = 0;
426 region_name = "Unknown"; 778 region_name = "Unknown";
427 switch (type) { 779 switch (type) {
428 case WMFW_NAME_TEXT: 780 case (WMFW_NAME_TEXT << 8):
429 case WMFW_INFO_TEXT: 781 case (WMFW_INFO_TEXT << 8):
430 break; 782 break;
431 case WMFW_ABSOLUTE: 783 case (WMFW_ABSOLUTE << 8):
432 region_name = "register"; 784 region_name = "register";
433 reg = offset; 785 reg = offset;
434 break; 786 break;
787
788 case WMFW_ADSP1_DM:
789 case WMFW_ADSP1_ZM:
790 case WMFW_ADSP2_XM:
791 case WMFW_ADSP2_YM:
792 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n",
793 file, blocks, le32_to_cpu(blk->len),
794 type, le32_to_cpu(blk->id));
795
796 mem = wm_adsp_find_region(dsp, type);
797 if (!mem) {
798 adsp_err(dsp, "No base for region %x\n", type);
799 break;
800 }
801
802 reg = 0;
803 list_for_each_entry(alg_region,
804 &dsp->alg_regions, list) {
805 if (le32_to_cpu(blk->id) == alg_region->alg &&
806 type == alg_region->type) {
807 reg = alg_region->base;
808 reg = wm_adsp_region_to_reg(mem,
809 reg);
810 reg += offset;
811 }
812 }
813
814 if (reg == 0)
815 adsp_err(dsp, "No %x for algorithm %x\n",
816 type, le32_to_cpu(blk->id));
817 break;
818
435 default: 819 default:
436 adsp_err(dsp, "Unknown region type %x\n", type); 820 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n",
821 file, blocks, type, pos);
437 break; 822 break;
438 } 823 }
439 824
440 if (reg) { 825 if (reg) {
441 buf = kmemdup(blk->data, le32_to_cpu(blk->len), 826 buf = wm_adsp_buf_alloc(blk->data,
442 GFP_KERNEL); 827 le32_to_cpu(blk->len),
828 &buf_list);
443 if (!buf) { 829 if (!buf) {
444 adsp_err(dsp, "Out of memory\n"); 830 adsp_err(dsp, "Out of memory\n");
445 return -ENOMEM; 831 return -ENOMEM;
446 } 832 }
447 833
448 ret = regmap_raw_write(regmap, reg, blk->data, 834 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
449 le32_to_cpu(blk->len)); 835 file, blocks, le32_to_cpu(blk->len),
836 reg);
837 ret = regmap_raw_write_async(regmap, reg, buf->buf,
838 le32_to_cpu(blk->len));
450 if (ret != 0) { 839 if (ret != 0) {
451 adsp_err(dsp, 840 adsp_err(dsp,
452 "%s.%d: Failed to write to %x in %s\n", 841 "%s.%d: Failed to write to %x in %s\n",
453 file, blocks, reg, region_name); 842 file, blocks, reg, region_name);
454 } 843 }
455
456 kfree(buf);
457 } 844 }
458 845
459 pos += le32_to_cpu(blk->len) + sizeof(*blk); 846 tmp = le32_to_cpu(blk->len) % 4;
847 if (tmp)
848 pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk);
849 else
850 pos += le32_to_cpu(blk->len) + sizeof(*blk);
851
460 blocks++; 852 blocks++;
461 } 853 }
462 854
855 ret = regmap_async_complete(regmap);
856 if (ret != 0)
857 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
858
463 if (pos > firmware->size) 859 if (pos > firmware->size)
464 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 860 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
465 file, blocks, pos - firmware->size); 861 file, blocks, pos - firmware->size);
466 862
467out_fw: 863out_fw:
468 release_firmware(firmware); 864 release_firmware(firmware);
865 wm_adsp_buf_free(&buf_list);
469out: 866out:
470 kfree(file); 867 kfree(file);
471 return 0; 868 return 0;
472} 869}
473 870
871int wm_adsp1_init(struct wm_adsp *adsp)
872{
873 INIT_LIST_HEAD(&adsp->alg_regions);
874
875 return 0;
876}
877EXPORT_SYMBOL_GPL(wm_adsp1_init);
878
474int wm_adsp1_event(struct snd_soc_dapm_widget *w, 879int wm_adsp1_event(struct snd_soc_dapm_widget *w,
475 struct snd_kcontrol *kcontrol, 880 struct snd_kcontrol *kcontrol,
476 int event) 881 int event)
@@ -479,16 +884,46 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
479 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 884 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
480 struct wm_adsp *dsp = &dsps[w->shift]; 885 struct wm_adsp *dsp = &dsps[w->shift];
481 int ret; 886 int ret;
887 int val;
482 888
483 switch (event) { 889 switch (event) {
484 case SND_SOC_DAPM_POST_PMU: 890 case SND_SOC_DAPM_POST_PMU:
485 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 891 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
486 ADSP1_SYS_ENA, ADSP1_SYS_ENA); 892 ADSP1_SYS_ENA, ADSP1_SYS_ENA);
487 893
894 /*
895 * For simplicity set the DSP clock rate to be the
896 * SYSCLK rate rather than making it configurable.
897 */
898 if(dsp->sysclk_reg) {
899 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
900 if (ret != 0) {
901 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
902 ret);
903 return ret;
904 }
905
906 val = (val & dsp->sysclk_mask)
907 >> dsp->sysclk_shift;
908
909 ret = regmap_update_bits(dsp->regmap,
910 dsp->base + ADSP1_CONTROL_31,
911 ADSP1_CLK_SEL_MASK, val);
912 if (ret != 0) {
913 adsp_err(dsp, "Failed to set clock rate: %d\n",
914 ret);
915 return ret;
916 }
917 }
918
488 ret = wm_adsp_load(dsp); 919 ret = wm_adsp_load(dsp);
489 if (ret != 0) 920 if (ret != 0)
490 goto err; 921 goto err;
491 922
923 ret = wm_adsp_setup_algs(dsp);
924 if (ret != 0)
925 goto err;
926
492 ret = wm_adsp_load_coeff(dsp); 927 ret = wm_adsp_load_coeff(dsp);
493 if (ret != 0) 928 if (ret != 0)
494 goto err; 929 goto err;
@@ -560,6 +995,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
560 struct snd_soc_codec *codec = w->codec; 995 struct snd_soc_codec *codec = w->codec;
561 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 996 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
562 struct wm_adsp *dsp = &dsps[w->shift]; 997 struct wm_adsp *dsp = &dsps[w->shift];
998 struct wm_adsp_alg_region *alg_region;
563 unsigned int val; 999 unsigned int val;
564 int ret; 1000 int ret;
565 1001
@@ -625,6 +1061,10 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
625 if (ret != 0) 1061 if (ret != 0)
626 goto err; 1062 goto err;
627 1063
1064 ret = wm_adsp_setup_algs(dsp);
1065 if (ret != 0)
1066 goto err;
1067
628 ret = wm_adsp_load_coeff(dsp); 1068 ret = wm_adsp_load_coeff(dsp);
629 if (ret != 0) 1069 if (ret != 0)
630 goto err; 1070 goto err;
@@ -635,13 +1075,22 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
635 ADSP2_CORE_ENA | ADSP2_START); 1075 ADSP2_CORE_ENA | ADSP2_START);
636 if (ret != 0) 1076 if (ret != 0)
637 goto err; 1077 goto err;
1078
1079 dsp->running = true;
638 break; 1080 break;
639 1081
640 case SND_SOC_DAPM_PRE_PMD: 1082 case SND_SOC_DAPM_PRE_PMD:
1083 dsp->running = false;
1084
641 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1085 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
642 ADSP2_SYS_ENA | ADSP2_CORE_ENA | 1086 ADSP2_SYS_ENA | ADSP2_CORE_ENA |
643 ADSP2_START, 0); 1087 ADSP2_START, 0);
644 1088
1089 /* Make sure DMAs are quiesced */
1090 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
1091 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
1092 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
1093
645 if (dsp->dvfs) { 1094 if (dsp->dvfs) {
646 ret = regulator_set_voltage(dsp->dvfs, 1200000, 1095 ret = regulator_set_voltage(dsp->dvfs, 1200000,
647 1800000); 1096 1800000);
@@ -656,6 +1105,14 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
656 "Failed to enable supply: %d\n", 1105 "Failed to enable supply: %d\n",
657 ret); 1106 ret);
658 } 1107 }
1108
1109 while (!list_empty(&dsp->alg_regions)) {
1110 alg_region = list_first_entry(&dsp->alg_regions,
1111 struct wm_adsp_alg_region,
1112 list);
1113 list_del(&alg_region->list);
1114 kfree(alg_region);
1115 }
659 break; 1116 break;
660 1117
661 default: 1118 default:
@@ -685,6 +1142,8 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
685 return ret; 1142 return ret;
686 } 1143 }
687 1144
1145 INIT_LIST_HEAD(&adsp->alg_regions);
1146
688 if (dvfs) { 1147 if (dvfs) {
689 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1148 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
690 if (IS_ERR(adsp->dvfs)) { 1149 if (IS_ERR(adsp->dvfs)) {
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index ffd29a4609e2..cb8871a3ec00 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -25,6 +25,13 @@ struct wm_adsp_region {
25 unsigned int base; 25 unsigned int base;
26}; 26};
27 27
28struct wm_adsp_alg_region {
29 struct list_head list;
30 unsigned int alg;
31 int type;
32 unsigned int base;
33};
34
28struct wm_adsp { 35struct wm_adsp {
29 const char *part; 36 const char *part;
30 int num; 37 int num;
@@ -33,10 +40,18 @@ struct wm_adsp {
33 struct regmap *regmap; 40 struct regmap *regmap;
34 41
35 int base; 42 int base;
43 int sysclk_reg;
44 int sysclk_mask;
45 int sysclk_shift;
46
47 struct list_head alg_regions;
36 48
37 const struct wm_adsp_region *mem; 49 const struct wm_adsp_region *mem;
38 int num_mems; 50 int num_mems;
39 51
52 int fw;
53 bool running;
54
40 struct regulator *dvfs; 55 struct regulator *dvfs;
41}; 56};
42 57
@@ -50,6 +65,9 @@ struct wm_adsp {
50 .shift = num, .event = wm_adsp2_event, \ 65 .shift = num, .event = wm_adsp2_event, \
51 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } 66 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
52 67
68extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
69
70int wm_adsp1_init(struct wm_adsp *adsp);
53int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); 71int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
54int wm_adsp1_event(struct snd_soc_dapm_widget *w, 72int wm_adsp1_event(struct snd_soc_dapm_widget *w,
55 struct snd_kcontrol *kcontrol, int event); 73 struct snd_kcontrol *kcontrol, int event);
diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h
index 5632ded67fdd..ef163360a745 100644
--- a/sound/soc/codecs/wmfw.h
+++ b/sound/soc/codecs/wmfw.h
@@ -93,15 +93,20 @@ struct wmfw_adsp2_alg_hdr {
93struct wmfw_coeff_hdr { 93struct wmfw_coeff_hdr {
94 u8 magic[4]; 94 u8 magic[4];
95 __le32 len; 95 __le32 len;
96 __le32 ver; 96 union {
97 __be32 rev;
98 __le32 ver;
99 };
100 union {
101 __be32 core;
102 __le32 core_ver;
103 };
97 u8 data[]; 104 u8 data[];
98} __packed; 105} __packed;
99 106
100struct wmfw_coeff_item { 107struct wmfw_coeff_item {
101 union { 108 __le16 offset;
102 __be32 type; 109 __le16 type;
103 __le32 offset;
104 };
105 __le32 id; 110 __le32 id;
106 __le32 ver; 111 __le32 ver;
107 __le32 sr; 112 __le32 sr;
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index d55e6477bff0..484b22c5df5d 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -116,9 +116,9 @@ static const struct snd_soc_dapm_route audio_map[] = {
116 {"Line Out", NULL, "RLOUT"}, 116 {"Line Out", NULL, "RLOUT"},
117 117
118 /* Mic connected to (MIC3L | MIC3R) */ 118 /* Mic connected to (MIC3L | MIC3R) */
119 {"MIC3L", NULL, "Mic Bias 2V"}, 119 {"MIC3L", NULL, "Mic Bias"},
120 {"MIC3R", NULL, "Mic Bias 2V"}, 120 {"MIC3R", NULL, "Mic Bias"},
121 {"Mic Bias 2V", NULL, "Mic Jack"}, 121 {"Mic Bias", NULL, "Mic Jack"},
122 122
123 /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */ 123 /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */
124 {"LINE1L", NULL, "Line In"}, 124 {"LINE1L", NULL, "Line In"},
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 55e2bf652bef..9321e5c9d8c1 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -626,7 +626,7 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,
626 int word_length) 626 int word_length)
627{ 627{
628 u32 fmt; 628 u32 fmt;
629 u32 rotate = (32 - word_length) / 4; 629 u32 rotate = (word_length / 4) & 0x7;
630 u32 mask = (1ULL << word_length) - 1; 630 u32 mask = (1ULL << word_length) - 1;
631 631
632 /* 632 /*
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 1aa51300c564..deb30d59965e 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -210,15 +210,19 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
210 switch (config->chan_nr) { 210 switch (config->chan_nr) {
211 case EIGHT_CHANNEL_SUPPORT: 211 case EIGHT_CHANNEL_SUPPORT:
212 ch_reg = 3; 212 ch_reg = 3;
213 break;
213 case SIX_CHANNEL_SUPPORT: 214 case SIX_CHANNEL_SUPPORT:
214 ch_reg = 2; 215 ch_reg = 2;
216 break;
215 case FOUR_CHANNEL_SUPPORT: 217 case FOUR_CHANNEL_SUPPORT:
216 ch_reg = 1; 218 ch_reg = 1;
219 break;
217 case TWO_CHANNEL_SUPPORT: 220 case TWO_CHANNEL_SUPPORT:
218 ch_reg = 0; 221 ch_reg = 0;
219 break; 222 break;
220 default: 223 default:
221 dev_err(dev->dev, "channel not supported\n"); 224 dev_err(dev->dev, "channel not supported\n");
225 return -EINVAL;
222 } 226 }
223 227
224 i2s_disable_channels(dev, substream->stream); 228 i2s_disable_channels(dev, substream->stream);
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 251f4d981e0c..3f333e5b4673 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -176,7 +176,7 @@ static inline void audmux_debugfs_remove(void)
176} 176}
177#endif 177#endif
178 178
179enum imx_audmux_type { 179static enum imx_audmux_type {
180 IMX21_AUDMUX, 180 IMX21_AUDMUX,
181 IMX31_AUDMUX, 181 IMX31_AUDMUX,
182} audmux_type; 182} audmux_type;
@@ -252,9 +252,9 @@ static int imx_audmux_probe(struct platform_device *pdev)
252 of_match_device(imx_audmux_dt_ids, &pdev->dev); 252 of_match_device(imx_audmux_dt_ids, &pdev->dev);
253 253
254 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 254 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
255 audmux_base = devm_request_and_ioremap(&pdev->dev, res); 255 audmux_base = devm_ioremap_resource(&pdev->dev, res);
256 if (!audmux_base) 256 if (IS_ERR(audmux_base))
257 return -EADDRNOTAVAIL; 257 return PTR_ERR(audmux_base);
258 258
259 pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 259 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
260 if (IS_ERR(pinctrl)) { 260 if (IS_ERR(pinctrl)) {
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index bf363d8d044a..500f8ce55d78 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -154,26 +154,7 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
154 .pcm_free = imx_pcm_free, 154 .pcm_free = imx_pcm_free,
155}; 155};
156 156
157static int imx_soc_platform_probe(struct platform_device *pdev) 157int imx_pcm_dma_init(struct platform_device *pdev)
158{ 158{
159 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); 159 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
160} 160}
161
162static int imx_soc_platform_remove(struct platform_device *pdev)
163{
164 snd_soc_unregister_platform(&pdev->dev);
165 return 0;
166}
167
168static struct platform_driver imx_pcm_driver = {
169 .driver = {
170 .name = "imx-pcm-audio",
171 .owner = THIS_MODULE,
172 },
173 .probe = imx_soc_platform_probe,
174 .remove = imx_soc_platform_remove,
175};
176
177module_platform_driver(imx_pcm_driver);
178MODULE_LICENSE("GPL");
179MODULE_ALIAS("platform:imx-pcm-audio");
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 5ec362ae4d01..920f945cb2f4 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -281,7 +281,7 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = {
281 .pcm_free = imx_pcm_fiq_free, 281 .pcm_free = imx_pcm_fiq_free,
282}; 282};
283 283
284static int imx_soc_platform_probe(struct platform_device *pdev) 284int imx_pcm_fiq_init(struct platform_device *pdev)
285{ 285{
286 struct imx_ssi *ssi = platform_get_drvdata(pdev); 286 struct imx_ssi *ssi = platform_get_drvdata(pdev);
287 int ret; 287 int ret;
@@ -314,23 +314,3 @@ failed_register:
314 314
315 return ret; 315 return ret;
316} 316}
317
318static int imx_soc_platform_remove(struct platform_device *pdev)
319{
320 snd_soc_unregister_platform(&pdev->dev);
321 return 0;
322}
323
324static struct platform_driver imx_pcm_driver = {
325 .driver = {
326 .name = "imx-fiq-pcm-audio",
327 .owner = THIS_MODULE,
328 },
329
330 .probe = imx_soc_platform_probe,
331 .remove = imx_soc_platform_remove,
332};
333
334module_platform_driver(imx_pcm_driver);
335
336MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
index d5cd9eff3b48..0d0625bfcb65 100644
--- a/sound/soc/fsl/imx-pcm.c
+++ b/sound/soc/fsl/imx-pcm.c
@@ -104,6 +104,38 @@ void imx_pcm_free(struct snd_pcm *pcm)
104} 104}
105EXPORT_SYMBOL_GPL(imx_pcm_free); 105EXPORT_SYMBOL_GPL(imx_pcm_free);
106 106
107static int imx_pcm_probe(struct platform_device *pdev)
108{
109 if (strcmp(pdev->id_entry->name, "imx-fiq-pcm-audio") == 0)
110 return imx_pcm_fiq_init(pdev);
111
112 return imx_pcm_dma_init(pdev);
113}
114
115static int imx_pcm_remove(struct platform_device *pdev)
116{
117 snd_soc_unregister_platform(&pdev->dev);
118 return 0;
119}
120
121static struct platform_device_id imx_pcm_devtype[] = {
122 { .name = "imx-pcm-audio", },
123 { .name = "imx-fiq-pcm-audio", },
124 { /* sentinel */ }
125};
126MODULE_DEVICE_TABLE(platform, imx_pcm_devtype);
127
128static struct platform_driver imx_pcm_driver = {
129 .driver = {
130 .name = "imx-pcm",
131 .owner = THIS_MODULE,
132 },
133 .id_table = imx_pcm_devtype,
134 .probe = imx_pcm_probe,
135 .remove = imx_pcm_remove,
136};
137module_platform_driver(imx_pcm_driver);
138
107MODULE_DESCRIPTION("Freescale i.MX PCM driver"); 139MODULE_DESCRIPTION("Freescale i.MX PCM driver");
108MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); 140MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
109MODULE_LICENSE("GPL"); 141MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 83c0ed7d55c9..5ae13a13a353 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -30,4 +30,22 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
30int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); 30int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
31void imx_pcm_free(struct snd_pcm *pcm); 31void imx_pcm_free(struct snd_pcm *pcm);
32 32
33#ifdef CONFIG_SND_SOC_IMX_PCM_DMA
34int imx_pcm_dma_init(struct platform_device *pdev);
35#else
36static inline int imx_pcm_dma_init(struct platform_device *pdev)
37{
38 return -ENODEV;
39}
40#endif
41
42#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ
43int imx_pcm_fiq_init(struct platform_device *pdev);
44#else
45static inline int imx_pcm_fiq_init(struct platform_device *pdev)
46{
47 return -ENODEV;
48}
49#endif
50
33#endif /* _IMX_PCM_H */ 51#endif /* _IMX_PCM_H */
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 3b480423747f..55464a5b0706 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -550,10 +550,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
550 goto failed_get_resource; 550 goto failed_get_resource;
551 } 551 }
552 552
553 ssi->base = devm_request_and_ioremap(&pdev->dev, res); 553 ssi->base = devm_ioremap_resource(&pdev->dev, res);
554 if (!ssi->base) { 554 if (IS_ERR(ssi->base)) {
555 dev_err(&pdev->dev, "ioremap failed\n"); 555 ret = PTR_ERR(ssi->base);
556 ret = -ENODEV;
557 goto failed_register; 556 goto failed_register;
558 } 557 }
559 558
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 9997c039bb24..2a847ca494b5 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -14,8 +14,8 @@
14 14
15#include <sound/soc.h> 15#include <sound/soc.h>
16 16
17#include <sysdev/bestcomm/bestcomm.h> 17#include <linux/fsl/bestcomm/bestcomm.h>
18#include <sysdev/bestcomm/gen_bd.h> 18#include <linux/fsl/bestcomm/gen_bd.h>
19#include <asm/mpc52xx_psc.h> 19#include <asm/mpc52xx_psc.h>
20 20
21#include "mpc5200_dma.h" 21#include "mpc5200_dma.h"
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index b4b4cab30232..6cf8355a8542 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -16,33 +16,38 @@
16#define asoc_simple_get_card_info(p) \ 16#define asoc_simple_get_card_info(p) \
17 container_of(p->dai_link, struct asoc_simple_card_info, snd_link) 17 container_of(p->dai_link, struct asoc_simple_card_info, snd_link)
18 18
19static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
20 struct asoc_simple_dai *set,
21 unsigned int daifmt)
22{
23 int ret = 0;
24
25 daifmt |= set->fmt;
26
27 if (!ret && daifmt)
28 ret = snd_soc_dai_set_fmt(dai, daifmt);
29
30 if (!ret && set->sysclk)
31 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
32
33 return ret;
34}
35
19static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 36static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
20{ 37{
21 struct asoc_simple_card_info *cinfo = asoc_simple_get_card_info(rtd); 38 struct asoc_simple_card_info *info = asoc_simple_get_card_info(rtd);
22 struct asoc_simple_dai_init_info *iinfo = cinfo->init;
23 struct snd_soc_dai *codec = rtd->codec_dai; 39 struct snd_soc_dai *codec = rtd->codec_dai;
24 struct snd_soc_dai *cpu = rtd->cpu_dai; 40 struct snd_soc_dai *cpu = rtd->cpu_dai;
25 unsigned int cpu_daifmt = iinfo->fmt | iinfo->cpu_daifmt; 41 unsigned int daifmt = info->daifmt;
26 unsigned int codec_daifmt = iinfo->fmt | iinfo->codec_daifmt;
27 int ret; 42 int ret;
28 43
29 if (codec_daifmt) { 44 ret = __asoc_simple_card_dai_init(codec, &info->codec_dai, daifmt);
30 ret = snd_soc_dai_set_fmt(codec, codec_daifmt); 45 if (ret < 0)
31 if (ret < 0) 46 return ret;
32 return ret;
33 }
34
35 if (iinfo->sysclk) {
36 ret = snd_soc_dai_set_sysclk(codec, 0, iinfo->sysclk, 0);
37 if (ret < 0)
38 return ret;
39 }
40 47
41 if (cpu_daifmt) { 48 ret = __asoc_simple_card_dai_init(cpu, &info->cpu_dai, daifmt);
42 ret = snd_soc_dai_set_fmt(cpu, cpu_daifmt); 49 if (ret < 0)
43 if (ret < 0) 50 return ret;
44 return ret;
45 }
46 51
47 return 0; 52 return 0;
48} 53}
@@ -50,19 +55,20 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
50static int asoc_simple_card_probe(struct platform_device *pdev) 55static int asoc_simple_card_probe(struct platform_device *pdev)
51{ 56{
52 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; 57 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data;
58 struct device *dev = &pdev->dev;
53 59
54 if (!cinfo) { 60 if (!cinfo) {
55 dev_err(&pdev->dev, "no info for asoc-simple-card\n"); 61 dev_err(dev, "no info for asoc-simple-card\n");
56 return -EINVAL; 62 return -EINVAL;
57 } 63 }
58 64
59 if (!cinfo->name || 65 if (!cinfo->name ||
60 !cinfo->card || 66 !cinfo->card ||
61 !cinfo->cpu_dai ||
62 !cinfo->codec || 67 !cinfo->codec ||
63 !cinfo->platform || 68 !cinfo->platform ||
64 !cinfo->codec_dai) { 69 !cinfo->cpu_dai.name ||
65 dev_err(&pdev->dev, "insufficient asoc_simple_card_info settings\n"); 70 !cinfo->codec_dai.name) {
71 dev_err(dev, "insufficient asoc_simple_card_info settings\n");
66 return -EINVAL; 72 return -EINVAL;
67 } 73 }
68 74
@@ -71,14 +77,11 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
71 */ 77 */
72 cinfo->snd_link.name = cinfo->name; 78 cinfo->snd_link.name = cinfo->name;
73 cinfo->snd_link.stream_name = cinfo->name; 79 cinfo->snd_link.stream_name = cinfo->name;
74 cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai; 80 cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai.name;
75 cinfo->snd_link.platform_name = cinfo->platform; 81 cinfo->snd_link.platform_name = cinfo->platform;
76 cinfo->snd_link.codec_name = cinfo->codec; 82 cinfo->snd_link.codec_name = cinfo->codec;
77 cinfo->snd_link.codec_dai_name = cinfo->codec_dai; 83 cinfo->snd_link.codec_dai_name = cinfo->codec_dai.name;
78 84 cinfo->snd_link.init = asoc_simple_card_dai_init;
79 /* enable snd_link.init if cinfo has settings */
80 if (cinfo->init)
81 cinfo->snd_link.init = asoc_simple_card_dai_init;
82 85
83 /* 86 /*
84 * init snd_soc_card 87 * init snd_soc_card
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 282d8b1163ba..c74c89065493 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -472,11 +472,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
472 return -ENXIO; 472 return -ENXIO;
473 } 473 }
474 474
475 priv->io = devm_request_and_ioremap(&pdev->dev, mem); 475 priv->io = devm_ioremap_resource(&pdev->dev, mem);
476 if (!priv->io) { 476 if (IS_ERR(priv->io))
477 dev_err(&pdev->dev, "devm_request_and_ioremap failed\n"); 477 return PTR_ERR(priv->io);
478 return -ENOMEM;
479 }
480 478
481 priv->irq = platform_get_irq(pdev, 0); 479 priv->irq = platform_get_irq(pdev, 0);
482 if (priv->irq <= 0) { 480 if (priv->irq <= 0) {
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 365d9d27a321..3a2aa1d19b93 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -32,7 +32,6 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/saif.h>
36#include <asm/mach-types.h> 35#include <asm/mach-types.h>
37#include <mach/hardware.h> 36#include <mach/hardware.h>
38#include <mach/mxs.h> 37#include <mach/mxs.h>
@@ -662,46 +661,40 @@ static int mxs_saif_probe(struct platform_device *pdev)
662 struct device_node *np = pdev->dev.of_node; 661 struct device_node *np = pdev->dev.of_node;
663 struct resource *iores, *dmares; 662 struct resource *iores, *dmares;
664 struct mxs_saif *saif; 663 struct mxs_saif *saif;
665 struct mxs_saif_platform_data *pdata;
666 struct pinctrl *pinctrl; 664 struct pinctrl *pinctrl;
667 int ret = 0; 665 int ret = 0;
666 struct device_node *master;
668 667
669 668 if (!np)
670 if (!np && pdev->id >= ARRAY_SIZE(mxs_saif))
671 return -EINVAL; 669 return -EINVAL;
672 670
673 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL); 671 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
674 if (!saif) 672 if (!saif)
675 return -ENOMEM; 673 return -ENOMEM;
676 674
677 if (np) { 675 ret = of_alias_get_id(np, "saif");
678 struct device_node *master; 676 if (ret < 0)
679 saif->id = of_alias_get_id(np, "saif"); 677 return ret;
680 if (saif->id < 0) 678 else
681 return saif->id; 679 saif->id = ret;
682 /* 680
683 * If there is no "fsl,saif-master" phandle, it's a saif 681 /*
684 * master. Otherwise, it's a slave and its phandle points 682 * If there is no "fsl,saif-master" phandle, it's a saif
685 * to the master. 683 * master. Otherwise, it's a slave and its phandle points
686 */ 684 * to the master.
687 master = of_parse_phandle(np, "fsl,saif-master", 0); 685 */
688 if (!master) { 686 master = of_parse_phandle(np, "fsl,saif-master", 0);
689 saif->master_id = saif->id; 687 if (!master) {
690 } else { 688 saif->master_id = saif->id;
691 saif->master_id = of_alias_get_id(master, "saif");
692 if (saif->master_id < 0)
693 return saif->master_id;
694 }
695 } else { 689 } else {
696 saif->id = pdev->id; 690 ret = of_alias_get_id(master, "saif");
697 pdata = pdev->dev.platform_data; 691 if (ret < 0)
698 if (pdata && !pdata->master_mode) 692 return ret;
699 saif->master_id = pdata->master_id;
700 else 693 else
701 saif->master_id = saif->id; 694 saif->master_id = ret;
702 } 695 }
703 696
704 if (saif->master_id < 0 || saif->master_id >= ARRAY_SIZE(mxs_saif)) { 697 if (saif->master_id >= ARRAY_SIZE(mxs_saif)) {
705 dev_err(&pdev->dev, "get wrong master id\n"); 698 dev_err(&pdev->dev, "get wrong master id\n");
706 return -EINVAL; 699 return -EINVAL;
707 } 700 }
@@ -724,11 +717,9 @@ static int mxs_saif_probe(struct platform_device *pdev)
724 717
725 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 718 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
726 719
727 saif->base = devm_request_and_ioremap(&pdev->dev, iores); 720 saif->base = devm_ioremap_resource(&pdev->dev, iores);
728 if (!saif->base) { 721 if (IS_ERR(saif->base))
729 dev_err(&pdev->dev, "ioremap failed\n"); 722 return PTR_ERR(saif->base);
730 return -ENODEV;
731 }
732 723
733 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 724 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
734 if (!dmares) { 725 if (!dmares) {
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 7048137f9a33..60259f2f3f2c 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -70,15 +70,6 @@ config SND_OMAP_SOC_AM3517EVM
70 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517 70 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
71 EVM. 71 EVM.
72 72
73config SND_OMAP_SOC_SDP3430
74 tristate "SoC Audio support for Texas Instruments SDP3430"
75 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
76 select SND_OMAP_SOC_MCBSP
77 select SND_SOC_TWL4030
78 help
79 Say Y if you want to add support for SoC audio on Texas Instruments
80 SDP3430.
81
82config SND_OMAP_SOC_OMAP_TWL4030 73config SND_OMAP_SOC_OMAP_TWL4030
83 tristate "SoC Audio support for TI SoC based boards with twl4030 codec" 74 tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
84 depends on TWL4030_CORE && SND_OMAP_SOC 75 depends on TWL4030_CORE && SND_OMAP_SOC
@@ -91,6 +82,8 @@ config SND_OMAP_SOC_OMAP_TWL4030
91 - Gumstix Overo or CompuLab CM-T35/CM-T3730 82 - Gumstix Overo or CompuLab CM-T35/CM-T3730
92 - IGEP v2 83 - IGEP v2
93 - OMAP3EVM 84 - OMAP3EVM
85 - SDP3430
86 - Zoom2
94 87
95config SND_OMAP_SOC_OMAP_ABE_TWL6040 88config SND_OMAP_SOC_OMAP_ABE_TWL6040
96 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 89 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
@@ -123,11 +116,3 @@ config SND_OMAP_SOC_OMAP3_PANDORA
123 select SND_SOC_TWL4030 116 select SND_SOC_TWL4030
124 help 117 help
125 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 118 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
126
127config SND_OMAP_SOC_ZOOM2
128 tristate "SoC Audio support for Zoom2"
129 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
130 select SND_OMAP_SOC_MCBSP
131 select SND_SOC_TWL4030
132 help
133 Say Y if you want to add support for Soc audio on Zoom2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 19637e55ea48..2b225945359b 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -17,11 +17,9 @@ snd-soc-rx51-objs := rx51.o
17snd-soc-ams-delta-objs := ams-delta.o 17snd-soc-ams-delta-objs := ams-delta.o
18snd-soc-osk5912-objs := osk5912.o 18snd-soc-osk5912-objs := osk5912.o
19snd-soc-am3517evm-objs := am3517evm.o 19snd-soc-am3517evm-objs := am3517evm.o
20snd-soc-sdp3430-objs := sdp3430.o
21snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o 20snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
22snd-soc-omap-twl4030-objs := omap-twl4030.o 21snd-soc-omap-twl4030-objs := omap-twl4030.o
23snd-soc-omap3pandora-objs := omap3pandora.o 22snd-soc-omap3pandora-objs := omap3pandora.o
24snd-soc-zoom2-objs := zoom2.o
25snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o 23snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o
26 24
27obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 25obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
@@ -30,9 +28,7 @@ obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
30obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 28obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
31obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o 29obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
32obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 30obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
33obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
34obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o 31obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
35obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o 32obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
36obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 33obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
37obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
38obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o 34obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 230b8c144848..ee7cd53aa3ee 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -230,8 +230,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
230 {"Ext Spk", NULL, "LLOUT"}, 230 {"Ext Spk", NULL, "LLOUT"},
231 {"Ext Spk", NULL, "RLOUT"}, 231 {"Ext Spk", NULL, "RLOUT"},
232 232
233 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 233 {"DMic Rate 64", NULL, "Mic Bias"},
234 {"Mic Bias 2V", NULL, "DMic"}, 234 {"Mic Bias", NULL, "DMic"},
235}; 235};
236 236
237static const char *spk_function[] = {"Off", "On"}; 237static const char *spk_function[] = {"Off", "On"};
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index 7ea24819d570..32fa840c493e 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -110,6 +110,8 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
110 /* 110 /*
111 * fill the IEC-60958 channel status word 111 * fill the IEC-60958 channel status word
112 */ 112 */
113 /* initialize the word bytes */
114 memset(iec->status, 0, sizeof(iec->status));
113 115
114 /* specify IEC-60958-3 (commercial use) */ 116 /* specify IEC-60958-3 (commercial use) */
115 iec->status[0] &= ~IEC958_AES0_PROFESSIONAL; 117 iec->status[0] &= ~IEC958_AES0_PROFESSIONAL;
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 2fe8be209452..5ca11bdac21e 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -449,10 +449,6 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
449 omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA; 449 omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA;
450 omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA; 450 omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA;
451 451
452 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
453 if (res == NULL)
454 return -ENOMEM;
455
456 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); 452 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
457 if (!res) 453 if (!res)
458 return -ENODEV; 454 return -ENODEV;
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 47bdbd415ad8..c722c2ef9665 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -174,23 +174,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
174 174
175static int omap_pcm_open(struct snd_pcm_substream *substream) 175static int omap_pcm_open(struct snd_pcm_substream *substream)
176{ 176{
177 struct snd_pcm_runtime *runtime = substream->runtime;
178 struct snd_soc_pcm_runtime *rtd = substream->private_data; 177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct omap_pcm_dma_data *dma_data; 178 struct omap_pcm_dma_data *dma_data;
180 int ret;
181 179
182 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); 180 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
183 181
184 /* Ensure that buffer size is a multiple of period size */
185 ret = snd_pcm_hw_constraint_integer(runtime,
186 SNDRV_PCM_HW_PARAM_PERIODS);
187 if (ret < 0)
188 return ret;
189
190 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 182 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
191 ret = snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, 183
192 &dma_data->dma_req); 184 return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
193 return ret; 185 &dma_data->dma_req);
194} 186}
195 187
196static int omap_pcm_close(struct snd_pcm_substream *substream) 188static int omap_pcm_close(struct snd_pcm_substream *substream)
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index 4541d28b5314..fd98509d0f49 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -11,6 +11,8 @@
11 * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>) 11 * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>)
12 * overo (Author: Steve Sakoman <steve@sakoman.com>) 12 * overo (Author: Steve Sakoman <steve@sakoman.com>)
13 * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>) 13 * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>)
14 * zoom2 (Author: Misael Lopez Cruz <misael.lopez@ti.com>)
15 * sdp3430 (Author: Misael Lopez Cruz <misael.lopez@ti.com>)
14 * 16 *
15 * This program is free software; you can redistribute it and/or 17 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License 18 * modify it under the terms of the GNU General Public License
@@ -32,14 +34,22 @@
32#include <linux/platform_data/omap-twl4030.h> 34#include <linux/platform_data/omap-twl4030.h>
33#include <linux/module.h> 35#include <linux/module.h>
34#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/gpio.h>
38#include <linux/of_gpio.h>
35 39
36#include <sound/core.h> 40#include <sound/core.h>
37#include <sound/pcm.h> 41#include <sound/pcm.h>
38#include <sound/soc.h> 42#include <sound/soc.h>
43#include <sound/jack.h>
39 44
40#include "omap-mcbsp.h" 45#include "omap-mcbsp.h"
41#include "omap-pcm.h" 46#include "omap-pcm.h"
42 47
48struct omap_twl4030 {
49 int jack_detect; /* board can detect jack events */
50 struct snd_soc_jack hs_jack;
51};
52
43static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, 53static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
44 struct snd_pcm_hw_params *params) 54 struct snd_pcm_hw_params *params)
45{ 55{
@@ -87,17 +97,164 @@ static struct snd_soc_ops omap_twl4030_ops = {
87 .hw_params = omap_twl4030_hw_params, 97 .hw_params = omap_twl4030_hw_params,
88}; 98};
89 99
100static const struct snd_soc_dapm_widget dapm_widgets[] = {
101 SND_SOC_DAPM_SPK("Earpiece Spk", NULL),
102 SND_SOC_DAPM_SPK("Handsfree Spk", NULL),
103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
104 SND_SOC_DAPM_SPK("Ext Spk", NULL),
105 SND_SOC_DAPM_SPK("Carkit Spk", NULL),
106
107 SND_SOC_DAPM_MIC("Main Mic", NULL),
108 SND_SOC_DAPM_MIC("Sub Mic", NULL),
109 SND_SOC_DAPM_MIC("Headset Mic", NULL),
110 SND_SOC_DAPM_MIC("Carkit Mic", NULL),
111 SND_SOC_DAPM_MIC("Digital0 Mic", NULL),
112 SND_SOC_DAPM_MIC("Digital1 Mic", NULL),
113 SND_SOC_DAPM_LINE("Line In", NULL),
114};
115
116static const struct snd_soc_dapm_route audio_map[] = {
117 /* Headset Stereophone: HSOL, HSOR */
118 {"Headset Stereophone", NULL, "HSOL"},
119 {"Headset Stereophone", NULL, "HSOR"},
120 /* External Speakers: HFL, HFR */
121 {"Handsfree Spk", NULL, "HFL"},
122 {"Handsfree Spk", NULL, "HFR"},
123 /* External Speakers: PredrivL, PredrivR */
124 {"Ext Spk", NULL, "PREDRIVEL"},
125 {"Ext Spk", NULL, "PREDRIVER"},
126 /* Carkit speakers: CARKITL, CARKITR */
127 {"Carkit Spk", NULL, "CARKITL"},
128 {"Carkit Spk", NULL, "CARKITR"},
129 /* Earpiece */
130 {"Earpiece Spk", NULL, "EARPIECE"},
131
132 /* External Mics: MAINMIC, SUBMIC with bias */
133 {"MAINMIC", NULL, "Main Mic"},
134 {"Main Mic", NULL, "Mic Bias 1"},
135 {"SUBMIC", NULL, "Sub Mic"},
136 {"Sub Mic", NULL, "Mic Bias 2"},
137 /* Headset Mic: HSMIC with bias */
138 {"HSMIC", NULL, "Headset Mic"},
139 {"Headset Mic", NULL, "Headset Mic Bias"},
140 /* Digital Mics: DIGIMIC0, DIGIMIC1 with bias */
141 {"DIGIMIC0", NULL, "Digital0 Mic"},
142 {"Digital0 Mic", NULL, "Mic Bias 1"},
143 {"DIGIMIC1", NULL, "Digital1 Mic"},
144 {"Digital1 Mic", NULL, "Mic Bias 2"},
145 /* Carkit In: CARKITMIC */
146 {"CARKITMIC", NULL, "Carkit Mic"},
147 /* Aux In: AUXL, AUXR */
148 {"AUXL", NULL, "Line In"},
149 {"AUXR", NULL, "Line In"},
150};
151
152/* Headset jack detection DAPM pins */
153static struct snd_soc_jack_pin hs_jack_pins[] = {
154 {
155 .pin = "Headset Mic",
156 .mask = SND_JACK_MICROPHONE,
157 },
158 {
159 .pin = "Headset Stereophone",
160 .mask = SND_JACK_HEADPHONE,
161 },
162};
163
164/* Headset jack detection gpios */
165static struct snd_soc_jack_gpio hs_jack_gpios[] = {
166 {
167 .name = "hsdet-gpio",
168 .report = SND_JACK_HEADSET,
169 .debounce_time = 200,
170 },
171};
172
173static inline void twl4030_disconnect_pin(struct snd_soc_dapm_context *dapm,
174 int connected, char *pin)
175{
176 if (!connected)
177 snd_soc_dapm_disable_pin(dapm, pin);
178}
179
180static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd)
181{
182 struct snd_soc_codec *codec = rtd->codec;
183 struct snd_soc_card *card = codec->card;
184 struct snd_soc_dapm_context *dapm = &codec->dapm;
185 struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev);
186 struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card);
187 int ret = 0;
188
189 /* Headset jack detection only if it is supported */
190 if (priv->jack_detect > 0) {
191 hs_jack_gpios[0].gpio = priv->jack_detect;
192
193 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
194 &priv->hs_jack);
195 if (ret)
196 return ret;
197
198 ret = snd_soc_jack_add_pins(&priv->hs_jack,
199 ARRAY_SIZE(hs_jack_pins),
200 hs_jack_pins);
201 if (ret)
202 return ret;
203
204 ret = snd_soc_jack_add_gpios(&priv->hs_jack,
205 ARRAY_SIZE(hs_jack_gpios),
206 hs_jack_gpios);
207 if (ret)
208 return ret;
209 }
210
211 /*
212 * NULL pdata means we booted with DT. In this case the routing is
213 * provided and the card is fully routed, no need to mark pins.
214 */
215 if (!pdata || !pdata->custom_routing)
216 return ret;
217
218 /* Disable not connected paths if not used */
219 twl4030_disconnect_pin(dapm, pdata->has_ear, "Earpiece Spk");
220 twl4030_disconnect_pin(dapm, pdata->has_hf, "Handsfree Spk");
221 twl4030_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
222 twl4030_disconnect_pin(dapm, pdata->has_predriv, "Ext Spk");
223 twl4030_disconnect_pin(dapm, pdata->has_carkit, "Carkit Spk");
224
225 twl4030_disconnect_pin(dapm, pdata->has_mainmic, "Main Mic");
226 twl4030_disconnect_pin(dapm, pdata->has_submic, "Sub Mic");
227 twl4030_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
228 twl4030_disconnect_pin(dapm, pdata->has_carkitmic, "Carkit Mic");
229 twl4030_disconnect_pin(dapm, pdata->has_digimic0, "Digital0 Mic");
230 twl4030_disconnect_pin(dapm, pdata->has_digimic1, "Digital1 Mic");
231 twl4030_disconnect_pin(dapm, pdata->has_linein, "Line In");
232
233 return ret;
234}
235
90/* Digital audio interface glue - connects codec <--> CPU */ 236/* Digital audio interface glue - connects codec <--> CPU */
91static struct snd_soc_dai_link omap_twl4030_dai_links[] = { 237static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
92 { 238 {
93 .name = "TWL4030", 239 .name = "TWL4030 HiFi",
94 .stream_name = "TWL4030", 240 .stream_name = "TWL4030 HiFi",
95 .cpu_dai_name = "omap-mcbsp.2", 241 .cpu_dai_name = "omap-mcbsp.2",
96 .codec_dai_name = "twl4030-hifi", 242 .codec_dai_name = "twl4030-hifi",
97 .platform_name = "omap-pcm-audio", 243 .platform_name = "omap-pcm-audio",
98 .codec_name = "twl4030-codec", 244 .codec_name = "twl4030-codec",
245 .init = omap_twl4030_init,
99 .ops = &omap_twl4030_ops, 246 .ops = &omap_twl4030_ops,
100 }, 247 },
248 {
249 .name = "TWL4030 Voice",
250 .stream_name = "TWL4030 Voice",
251 .cpu_dai_name = "omap-mcbsp.3",
252 .codec_dai_name = "twl4030-voice",
253 .platform_name = "omap-pcm-audio",
254 .codec_name = "twl4030-codec",
255 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
256 SND_SOC_DAIFMT_CBM_CFM,
257 },
101}; 258};
102 259
103/* Audio machine driver */ 260/* Audio machine driver */
@@ -105,6 +262,11 @@ static struct snd_soc_card omap_twl4030_card = {
105 .owner = THIS_MODULE, 262 .owner = THIS_MODULE,
106 .dai_link = omap_twl4030_dai_links, 263 .dai_link = omap_twl4030_dai_links,
107 .num_links = ARRAY_SIZE(omap_twl4030_dai_links), 264 .num_links = ARRAY_SIZE(omap_twl4030_dai_links),
265
266 .dapm_widgets = dapm_widgets,
267 .num_dapm_widgets = ARRAY_SIZE(dapm_widgets),
268 .dapm_routes = audio_map,
269 .num_dapm_routes = ARRAY_SIZE(audio_map),
108}; 270};
109 271
110static int omap_twl4030_probe(struct platform_device *pdev) 272static int omap_twl4030_probe(struct platform_device *pdev)
@@ -112,12 +274,18 @@ static int omap_twl4030_probe(struct platform_device *pdev)
112 struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev); 274 struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
113 struct device_node *node = pdev->dev.of_node; 275 struct device_node *node = pdev->dev.of_node;
114 struct snd_soc_card *card = &omap_twl4030_card; 276 struct snd_soc_card *card = &omap_twl4030_card;
277 struct omap_twl4030 *priv;
115 int ret = 0; 278 int ret = 0;
116 279
117 card->dev = &pdev->dev; 280 card->dev = &pdev->dev;
118 281
282 priv = devm_kzalloc(&pdev->dev, sizeof(struct omap_twl4030), GFP_KERNEL);
283 if (priv == NULL)
284 return -ENOMEM;
285
119 if (node) { 286 if (node) {
120 struct device_node *dai_node; 287 struct device_node *dai_node;
288 struct property *prop;
121 289
122 if (snd_soc_of_parse_card_name(card, "ti,model")) { 290 if (snd_soc_of_parse_card_name(card, "ti,model")) {
123 dev_err(&pdev->dev, "Card name is not provided\n"); 291 dev_err(&pdev->dev, "Card name is not provided\n");
@@ -132,6 +300,27 @@ static int omap_twl4030_probe(struct platform_device *pdev)
132 omap_twl4030_dai_links[0].cpu_dai_name = NULL; 300 omap_twl4030_dai_links[0].cpu_dai_name = NULL;
133 omap_twl4030_dai_links[0].cpu_of_node = dai_node; 301 omap_twl4030_dai_links[0].cpu_of_node = dai_node;
134 302
303 dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0);
304 if (!dai_node) {
305 card->num_links = 1;
306 } else {
307 omap_twl4030_dai_links[1].cpu_dai_name = NULL;
308 omap_twl4030_dai_links[1].cpu_of_node = dai_node;
309 }
310
311 priv->jack_detect = of_get_named_gpio(node,
312 "ti,jack-det-gpio", 0);
313
314 /* Optional: audio routing can be provided */
315 prop = of_find_property(node, "ti,audio-routing", NULL);
316 if (prop) {
317 ret = snd_soc_of_parse_audio_routing(card,
318 "ti,audio-routing");
319 if (ret)
320 return ret;
321
322 card->fully_routed = 1;
323 }
135 } else if (pdata) { 324 } else if (pdata) {
136 if (pdata->card_name) { 325 if (pdata->card_name) {
137 card->name = pdata->card_name; 326 card->name = pdata->card_name;
@@ -139,11 +328,17 @@ static int omap_twl4030_probe(struct platform_device *pdev)
139 dev_err(&pdev->dev, "Card name is not provided\n"); 328 dev_err(&pdev->dev, "Card name is not provided\n");
140 return -ENODEV; 329 return -ENODEV;
141 } 330 }
331
332 if (!pdata->voice_connected)
333 card->num_links = 1;
334
335 priv->jack_detect = pdata->jack_detect;
142 } else { 336 } else {
143 dev_err(&pdev->dev, "Missing pdata\n"); 337 dev_err(&pdev->dev, "Missing pdata\n");
144 return -ENODEV; 338 return -ENODEV;
145 } 339 }
146 340
341 snd_soc_card_set_drvdata(card, priv);
147 ret = snd_soc_register_card(card); 342 ret = snd_soc_register_card(card);
148 if (ret) { 343 if (ret) {
149 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 344 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
@@ -157,7 +352,12 @@ static int omap_twl4030_probe(struct platform_device *pdev)
157static int omap_twl4030_remove(struct platform_device *pdev) 352static int omap_twl4030_remove(struct platform_device *pdev)
158{ 353{
159 struct snd_soc_card *card = platform_get_drvdata(pdev); 354 struct snd_soc_card *card = platform_get_drvdata(pdev);
355 struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card);
160 356
357 if (priv->jack_detect > 0)
358 snd_soc_jack_free_gpios(&priv->hs_jack,
359 ARRAY_SIZE(hs_jack_gpios),
360 hs_jack_gpios);
161 snd_soc_unregister_card(card); 361 snd_soc_unregister_card(card);
162 362
163 return 0; 363 return 0;
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 43d950a79ff9..805512f2555a 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -144,11 +144,11 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
144 {"AUXL", NULL, "Line In"}, 144 {"AUXL", NULL, "Line In"},
145 {"AUXR", NULL, "Line In"}, 145 {"AUXR", NULL, "Line In"},
146 146
147 {"MAINMIC", NULL, "Mic Bias 1"}, 147 {"MAINMIC", NULL, "Mic (internal)"},
148 {"Mic Bias 1", NULL, "Mic (internal)"}, 148 {"Mic (internal)", NULL, "Mic Bias 1"},
149 149
150 {"SUBMIC", NULL, "Mic Bias 2"}, 150 {"SUBMIC", NULL, "Mic (external)"},
151 {"Mic Bias 2", NULL, "Mic (external)"}, 151 {"Mic (external)", NULL, "Mic Bias 2"},
152}; 152};
153 153
154static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) 154static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index d921ddbe3ecb..3cd525748975 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -248,16 +248,16 @@ static const struct snd_soc_dapm_route audio_map[] = {
248 {"FM Transmitter", NULL, "LLOUT"}, 248 {"FM Transmitter", NULL, "LLOUT"},
249 {"FM Transmitter", NULL, "RLOUT"}, 249 {"FM Transmitter", NULL, "RLOUT"},
250 250
251 {"DMic Rate 64", NULL, "Mic Bias 2V"}, 251 {"DMic Rate 64", NULL, "Mic Bias"},
252 {"Mic Bias 2V", NULL, "DMic"}, 252 {"Mic Bias", NULL, "DMic"},
253}; 253};
254 254
255static const struct snd_soc_dapm_route audio_mapb[] = { 255static const struct snd_soc_dapm_route audio_mapb[] = {
256 {"b LINE2R", NULL, "MONO_LOUT"}, 256 {"b LINE2R", NULL, "MONO_LOUT"},
257 {"Earphone", NULL, "b HPLOUT"}, 257 {"Earphone", NULL, "b HPLOUT"},
258 258
259 {"LINE1L", NULL, "b Mic Bias 2.5V"}, 259 {"LINE1L", NULL, "b Mic Bias"},
260 {"b Mic Bias 2.5V", NULL, "HS Mic"} 260 {"b Mic Bias", NULL, "HS Mic"}
261}; 261};
262 262
263static const char *spk_function[] = {"Off", "On"}; 263static const char *spk_function[] = {"Off", "On"};
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
deleted file mode 100644
index b462a2c9385f..000000000000
--- a/sound/soc/omap/sdp3430.c
+++ /dev/null
@@ -1,278 +0,0 @@
1/*
2 * sdp3430.c -- SoC audio for TI OMAP3430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * Based on:
7 * Author: Steve Sakoman <steve@sakoman.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/clk.h>
26#include <linux/platform_device.h>
27#include <linux/i2c/twl.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/soc.h>
31#include <sound/jack.h>
32
33#include <asm/mach-types.h>
34#include <linux/platform_data/gpio-omap.h>
35#include <linux/platform_data/asoc-ti-mcbsp.h>
36
37/* Register descriptions for twl4030 codec part */
38#include <linux/mfd/twl4030-audio.h>
39#include <linux/module.h>
40
41#include "omap-mcbsp.h"
42#include "omap-pcm.h"
43
44/* TWL4030 PMBR1 Register */
45#define TWL4030_INTBR_PMBR1 0x0D
46/* TWL4030 PMBR1 Register GPIO6 mux bit */
47#define TWL4030_GPIO6_PWM0_MUTE(value) (value << 2)
48
49static struct snd_soc_card snd_soc_sdp3430;
50
51static int sdp3430_hw_params(struct snd_pcm_substream *substream,
52 struct snd_pcm_hw_params *params)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->codec_dai;
56 int ret;
57
58 /* Set the codec system clock for DAC and ADC */
59 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
60 SND_SOC_CLOCK_IN);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set codec system clock\n");
63 return ret;
64 }
65
66 return 0;
67}
68
69static struct snd_soc_ops sdp3430_ops = {
70 .hw_params = sdp3430_hw_params,
71};
72
73/* Headset jack */
74static struct snd_soc_jack hs_jack;
75
76/* Headset jack detection DAPM pins */
77static struct snd_soc_jack_pin hs_jack_pins[] = {
78 {
79 .pin = "Headset Mic",
80 .mask = SND_JACK_MICROPHONE,
81 },
82 {
83 .pin = "Headset Stereophone",
84 .mask = SND_JACK_HEADPHONE,
85 },
86};
87
88/* Headset jack detection gpios */
89static struct snd_soc_jack_gpio hs_jack_gpios[] = {
90 {
91 .gpio = (OMAP_MAX_GPIO_LINES + 2),
92 .name = "hsdet-gpio",
93 .report = SND_JACK_HEADSET,
94 .debounce_time = 200,
95 },
96};
97
98/* SDP3430 machine DAPM */
99static const struct snd_soc_dapm_widget sdp3430_twl4030_dapm_widgets[] = {
100 SND_SOC_DAPM_MIC("Ext Mic", NULL),
101 SND_SOC_DAPM_SPK("Ext Spk", NULL),
102 SND_SOC_DAPM_MIC("Headset Mic", NULL),
103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
104};
105
106static const struct snd_soc_dapm_route audio_map[] = {
107 /* External Mics: MAINMIC, SUBMIC with bias*/
108 {"MAINMIC", NULL, "Mic Bias 1"},
109 {"SUBMIC", NULL, "Mic Bias 2"},
110 {"Mic Bias 1", NULL, "Ext Mic"},
111 {"Mic Bias 2", NULL, "Ext Mic"},
112
113 /* External Speakers: HFL, HFR */
114 {"Ext Spk", NULL, "HFL"},
115 {"Ext Spk", NULL, "HFR"},
116
117 /* Headset Mic: HSMIC with bias */
118 {"HSMIC", NULL, "Headset Mic Bias"},
119 {"Headset Mic Bias", NULL, "Headset Mic"},
120
121 /* Headset Stereophone (Headphone): HSOL, HSOR */
122 {"Headset Stereophone", NULL, "HSOL"},
123 {"Headset Stereophone", NULL, "HSOR"},
124};
125
126static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
127{
128 struct snd_soc_codec *codec = rtd->codec;
129 struct snd_soc_dapm_context *dapm = &codec->dapm;
130 int ret;
131
132 /* SDP3430 connected pins */
133 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
134 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
135 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
136 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
137
138 /* TWL4030 not connected pins */
139 snd_soc_dapm_nc_pin(dapm, "AUXL");
140 snd_soc_dapm_nc_pin(dapm, "AUXR");
141 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
142 snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
143 snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
144
145 snd_soc_dapm_nc_pin(dapm, "OUTL");
146 snd_soc_dapm_nc_pin(dapm, "OUTR");
147 snd_soc_dapm_nc_pin(dapm, "EARPIECE");
148 snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
149 snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
150 snd_soc_dapm_nc_pin(dapm, "CARKITL");
151 snd_soc_dapm_nc_pin(dapm, "CARKITR");
152
153 /* Headset jack detection */
154 ret = snd_soc_jack_new(codec, "Headset Jack",
155 SND_JACK_HEADSET, &hs_jack);
156 if (ret)
157 return ret;
158
159 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
160 hs_jack_pins);
161 if (ret)
162 return ret;
163
164 ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
165 hs_jack_gpios);
166
167 return ret;
168}
169
170static int sdp3430_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
171{
172 struct snd_soc_codec *codec = rtd->codec;
173 unsigned short reg;
174
175 /* Enable voice interface */
176 reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
177 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
178 codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
179
180 return 0;
181}
182
183
184/* Digital audio interface glue - connects codec <--> CPU */
185static struct snd_soc_dai_link sdp3430_dai[] = {
186 {
187 .name = "TWL4030 I2S",
188 .stream_name = "TWL4030 Audio",
189 .cpu_dai_name = "omap-mcbsp.2",
190 .codec_dai_name = "twl4030-hifi",
191 .platform_name = "omap-pcm-audio",
192 .codec_name = "twl4030-codec",
193 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
194 SND_SOC_DAIFMT_CBM_CFM,
195 .init = sdp3430_twl4030_init,
196 .ops = &sdp3430_ops,
197 },
198 {
199 .name = "TWL4030 PCM",
200 .stream_name = "TWL4030 Voice",
201 .cpu_dai_name = "omap-mcbsp.3",
202 .codec_dai_name = "twl4030-voice",
203 .platform_name = "omap-pcm-audio",
204 .codec_name = "twl4030-codec",
205 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
206 SND_SOC_DAIFMT_CBM_CFM,
207 .init = sdp3430_twl4030_voice_init,
208 .ops = &sdp3430_ops,
209 },
210};
211
212/* Audio machine driver */
213static struct snd_soc_card snd_soc_sdp3430 = {
214 .name = "SDP3430",
215 .owner = THIS_MODULE,
216 .dai_link = sdp3430_dai,
217 .num_links = ARRAY_SIZE(sdp3430_dai),
218
219 .dapm_widgets = sdp3430_twl4030_dapm_widgets,
220 .num_dapm_widgets = ARRAY_SIZE(sdp3430_twl4030_dapm_widgets),
221 .dapm_routes = audio_map,
222 .num_dapm_routes = ARRAY_SIZE(audio_map),
223};
224
225static struct platform_device *sdp3430_snd_device;
226
227static int __init sdp3430_soc_init(void)
228{
229 int ret;
230 u8 pin_mux;
231
232 if (!machine_is_omap_3430sdp())
233 return -ENODEV;
234 printk(KERN_INFO "SDP3430 SoC init\n");
235
236 sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
237 if (!sdp3430_snd_device) {
238 printk(KERN_ERR "Platform device allocation failed\n");
239 return -ENOMEM;
240 }
241
242 platform_set_drvdata(sdp3430_snd_device, &snd_soc_sdp3430);
243
244 /* Set TWL4030 GPIO6 as EXTMUTE signal */
245 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
246 TWL4030_INTBR_PMBR1);
247 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
248 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
249 twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
250 TWL4030_INTBR_PMBR1);
251
252 ret = platform_device_add(sdp3430_snd_device);
253 if (ret)
254 goto err1;
255
256 return 0;
257
258err1:
259 printk(KERN_ERR "Unable to add platform device\n");
260 platform_device_put(sdp3430_snd_device);
261
262 return ret;
263}
264module_init(sdp3430_soc_init);
265
266static void __exit sdp3430_soc_exit(void)
267{
268 snd_soc_jack_free_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
269 hs_jack_gpios);
270
271 platform_device_unregister(sdp3430_snd_device);
272}
273module_exit(sdp3430_soc_exit);
274
275MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
276MODULE_DESCRIPTION("ALSA SoC SDP3430");
277MODULE_LICENSE("GPL");
278
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
deleted file mode 100644
index 771bff27ac3e..000000000000
--- a/sound/soc/omap/zoom2.c
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * zoom2.c -- SoC audio for Zoom2
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/gpio.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/soc.h>
28
29#include <asm/mach-types.h>
30#include <linux/platform_data/asoc-ti-mcbsp.h>
31#include <linux/platform_data/gpio-omap.h>
32
33/* Register descriptions for twl4030 codec part */
34#include <linux/mfd/twl4030-audio.h>
35#include <linux/module.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39
40static int zoom2_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->codec_dai;
45 int ret;
46
47 /* Set the codec system clock for DAC and ADC */
48 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
49 SND_SOC_CLOCK_IN);
50 if (ret < 0) {
51 printk(KERN_ERR "can't set codec system clock\n");
52 return ret;
53 }
54
55 return 0;
56}
57
58static struct snd_soc_ops zoom2_ops = {
59 .hw_params = zoom2_hw_params,
60};
61
62/* Zoom2 machine DAPM */
63static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = {
64 SND_SOC_DAPM_MIC("Ext Mic", NULL),
65 SND_SOC_DAPM_SPK("Ext Spk", NULL),
66 SND_SOC_DAPM_MIC("Headset Mic", NULL),
67 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
68 SND_SOC_DAPM_LINE("Aux In", NULL),
69};
70
71static const struct snd_soc_dapm_route audio_map[] = {
72 /* External Mics: MAINMIC, SUBMIC with bias*/
73 {"MAINMIC", NULL, "Mic Bias 1"},
74 {"SUBMIC", NULL, "Mic Bias 2"},
75 {"Mic Bias 1", NULL, "Ext Mic"},
76 {"Mic Bias 2", NULL, "Ext Mic"},
77
78 /* External Speakers: HFL, HFR */
79 {"Ext Spk", NULL, "HFL"},
80 {"Ext Spk", NULL, "HFR"},
81
82 /* Headset Stereophone: HSOL, HSOR */
83 {"Headset Stereophone", NULL, "HSOL"},
84 {"Headset Stereophone", NULL, "HSOR"},
85
86 /* Headset Mic: HSMIC with bias */
87 {"HSMIC", NULL, "Headset Mic Bias"},
88 {"Headset Mic Bias", NULL, "Headset Mic"},
89
90 /* Aux In: AUXL, AUXR */
91 {"Aux In", NULL, "AUXL"},
92 {"Aux In", NULL, "AUXR"},
93};
94
95static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
96{
97 struct snd_soc_codec *codec = rtd->codec;
98 struct snd_soc_dapm_context *dapm = &codec->dapm;
99
100 /* TWL4030 not connected pins */
101 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
102 snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
103 snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
104 snd_soc_dapm_nc_pin(dapm, "EARPIECE");
105 snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
106 snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
107 snd_soc_dapm_nc_pin(dapm, "CARKITL");
108 snd_soc_dapm_nc_pin(dapm, "CARKITR");
109
110 return 0;
111}
112
113static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd)
114{
115 struct snd_soc_codec *codec = rtd->codec;
116 unsigned short reg;
117
118 /* Enable voice interface */
119 reg = codec->driver->read(codec, TWL4030_REG_VOICE_IF);
120 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
121 codec->driver->write(codec, TWL4030_REG_VOICE_IF, reg);
122
123 return 0;
124}
125
126/* Digital audio interface glue - connects codec <--> CPU */
127static struct snd_soc_dai_link zoom2_dai[] = {
128 {
129 .name = "TWL4030 I2S",
130 .stream_name = "TWL4030 Audio",
131 .cpu_dai_name = "omap-mcbsp.2",
132 .codec_dai_name = "twl4030-hifi",
133 .platform_name = "omap-pcm-audio",
134 .codec_name = "twl4030-codec",
135 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
136 SND_SOC_DAIFMT_CBM_CFM,
137 .init = zoom2_twl4030_init,
138 .ops = &zoom2_ops,
139 },
140 {
141 .name = "TWL4030 PCM",
142 .stream_name = "TWL4030 Voice",
143 .cpu_dai_name = "omap-mcbsp.3",
144 .codec_dai_name = "twl4030-voice",
145 .platform_name = "omap-pcm-audio",
146 .codec_name = "twl4030-codec",
147 .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF |
148 SND_SOC_DAIFMT_CBM_CFM,
149 .init = zoom2_twl4030_voice_init,
150 .ops = &zoom2_ops,
151 },
152};
153
154/* Audio machine driver */
155static struct snd_soc_card snd_soc_zoom2 = {
156 .name = "Zoom2",
157 .owner = THIS_MODULE,
158 .dai_link = zoom2_dai,
159 .num_links = ARRAY_SIZE(zoom2_dai),
160
161 .dapm_widgets = zoom2_twl4030_dapm_widgets,
162 .num_dapm_widgets = ARRAY_SIZE(zoom2_twl4030_dapm_widgets),
163 .dapm_routes = audio_map,
164 .num_dapm_routes = ARRAY_SIZE(audio_map),
165};
166
167static struct platform_device *zoom2_snd_device;
168
169static int __init zoom2_soc_init(void)
170{
171 int ret;
172
173 if (!machine_is_omap_zoom2())
174 return -ENODEV;
175 printk(KERN_INFO "Zoom2 SoC init\n");
176
177 zoom2_snd_device = platform_device_alloc("soc-audio", -1);
178 if (!zoom2_snd_device) {
179 printk(KERN_ERR "Platform device allocation failed\n");
180 return -ENOMEM;
181 }
182
183 platform_set_drvdata(zoom2_snd_device, &snd_soc_zoom2);
184 ret = platform_device_add(zoom2_snd_device);
185 if (ret)
186 goto err1;
187
188 return 0;
189
190err1:
191 printk(KERN_ERR "Unable to add platform device\n");
192 platform_device_put(zoom2_snd_device);
193
194 return ret;
195}
196module_init(zoom2_soc_init);
197
198static void __exit zoom2_soc_exit(void)
199{
200 platform_device_unregister(zoom2_snd_device);
201}
202module_exit(zoom2_soc_exit);
203
204MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
205MODULE_DESCRIPTION("ALSA SoC Zoom2");
206MODULE_LICENSE("GPL");
207
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 41c3a09b53ea..9140c4abafbc 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -429,9 +429,9 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
429 if (res == NULL) 429 if (res == NULL)
430 return -ENOMEM; 430 return -ENOMEM;
431 431
432 priv->sspa->mmio_base = devm_request_and_ioremap(&pdev->dev, res); 432 priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res);
433 if (priv->sspa->mmio_base == NULL) 433 if (IS_ERR(priv->sspa->mmio_base))
434 return -ENODEV; 434 return PTR_ERR(priv->sspa->mmio_base);
435 435
436 priv->sspa->clk = devm_clk_get(&pdev->dev, NULL); 436 priv->sspa->clk = devm_clk_get(&pdev->dev, NULL);
437 if (IS_ERR(priv->sspa->clk)) 437 if (IS_ERR(priv->sspa->clk))
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 2074e2daf9c6..e1ffcdd9a649 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -79,17 +79,6 @@ static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
79 struct snd_soc_dapm_context *dapm = &codec->dapm; 79 struct snd_soc_dapm_context *dapm = &codec->dapm;
80 int err; 80 int err;
81 81
82 /* add palm27x specific widgets */
83 err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
84 ARRAY_SIZE(palm27x_dapm_widgets));
85 if (err)
86 return err;
87
88 /* set up palm27x specific audio path audio_map */
89 err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
90 if (err)
91 return err;
92
93 /* connected pins */ 82 /* connected pins */
94 if (machine_is_palmld()) 83 if (machine_is_palmld())
95 snd_soc_dapm_enable_pin(dapm, "MIC1"); 84 snd_soc_dapm_enable_pin(dapm, "MIC1");
@@ -149,10 +138,12 @@ static struct snd_soc_card palm27x_asoc = {
149 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
150 .dai_link = palm27x_dai, 139 .dai_link = palm27x_dai,
151 .num_links = ARRAY_SIZE(palm27x_dai), 140 .num_links = ARRAY_SIZE(palm27x_dai),
141 .dapm_widgets = palm27x_dapm_widgets,
142 .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets),
143 .dapm_routes = audio_map,
144 .num_dapm_routes = ARRAY_SIZE(audio_map)
152}; 145};
153 146
154static struct platform_device *palm27x_snd_device;
155
156static int palm27x_asoc_probe(struct platform_device *pdev) 147static int palm27x_asoc_probe(struct platform_device *pdev)
157{ 148{
158 int ret; 149 int ret;
@@ -169,27 +160,18 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
169 hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *) 160 hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *)
170 (pdev->dev.platform_data))->jack_gpio; 161 (pdev->dev.platform_data))->jack_gpio;
171 162
172 palm27x_snd_device = platform_device_alloc("soc-audio", -1); 163 palm27x_asoc.dev = &pdev->dev;
173 if (!palm27x_snd_device)
174 return -ENOMEM;
175
176 platform_set_drvdata(palm27x_snd_device, &palm27x_asoc);
177 ret = platform_device_add(palm27x_snd_device);
178
179 if (ret != 0)
180 goto put_device;
181
182 return 0;
183
184put_device:
185 platform_device_put(palm27x_snd_device);
186 164
165 ret = snd_soc_register_card(&palm27x_asoc);
166 if (ret)
167 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
168 ret);
187 return ret; 169 return ret;
188} 170}
189 171
190static int palm27x_asoc_remove(struct platform_device *pdev) 172static int palm27x_asoc_remove(struct platform_device *pdev)
191{ 173{
192 platform_device_unregister(palm27x_snd_device); 174 snd_soc_unregister_card(&palm27x_asoc);
193 return 0; 175 return 0;
194} 176}
195 177
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 3c7c3a59ed39..90e7e6653233 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -63,7 +63,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8580
63 63
64config SND_SOC_SAMSUNG_SMDK_WM8994 64config SND_SOC_SAMSUNG_SMDK_WM8994
65 tristate "SoC I2S Audio support for WM8994 on SMDK" 65 tristate "SoC I2S Audio support for WM8994 on SMDK"
66 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212) 66 depends on SND_SOC_SAMSUNG
67 depends on I2C=y && GENERIC_HARDIRQS 67 depends on I2C=y && GENERIC_HARDIRQS
68 select MFD_WM8994 68 select MFD_WM8994
69 select SND_SOC_WM8994 69 select SND_SOC_WM8994
@@ -162,7 +162,7 @@ config SND_SOC_GONI_AQUILA_WM8994
162 162
163config SND_SOC_SAMSUNG_SMDK_SPDIF 163config SND_SOC_SAMSUNG_SMDK_SPDIF
164 tristate "SoC S/PDIF Audio support for SMDK" 164 tristate "SoC S/PDIF Audio support for SMDK"
165 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212) 165 depends on SND_SOC_SAMSUNG
166 select SND_SAMSUNG_SPDIF 166 select SND_SAMSUNG_SPDIF
167 help 167 help
168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 168 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
@@ -177,7 +177,7 @@ config SND_SOC_SMDK_WM8580_PCM
177 177
178config SND_SOC_SMDK_WM8994_PCM 178config SND_SOC_SMDK_WM8994_PCM
179 tristate "SoC PCM Audio support for WM8994 on SMDK" 179 tristate "SoC PCM Audio support for WM8994 on SMDK"
180 depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212) 180 depends on SND_SOC_SAMSUNG
181 depends on I2C=y && GENERIC_HARDIRQS 181 depends on I2C=y && GENERIC_HARDIRQS
182 select MFD_WM8994 182 select MFD_WM8994
183 select SND_SOC_WM8994 183 select SND_SOC_WM8994
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index db87628d7630..21b79262010e 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -174,7 +174,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
174 config.width = prtd->params->dma_size; 174 config.width = prtd->params->dma_size;
175 config.fifo = prtd->params->dma_addr; 175 config.fifo = prtd->params->dma_addr;
176 prtd->params->ch = prtd->params->ops->request( 176 prtd->params->ch = prtd->params->ops->request(
177 prtd->params->channel, &req); 177 prtd->params->channel, &req, rtd->cpu_dai->dev,
178 prtd->params->ch_name);
178 prtd->params->ops->config(prtd->params->ch, &config); 179 prtd->params->ops->config(prtd->params->ch, &config);
179 } 180 }
180 181
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 73d8c7c8a1e8..189a7a6d5020 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -19,6 +19,7 @@ struct s3c_dma_params {
19 int dma_size; /* Size of the DMA transfer */ 19 int dma_size; /* Size of the DMA transfer */
20 unsigned ch; 20 unsigned ch;
21 struct samsung_dma_ops *ops; 21 struct samsung_dma_ops *ops;
22 char *ch_name;
22}; 23};
23 24
24int asoc_dma_platform_register(struct device *dev); 25int asoc_dma_platform_register(struct device *dev);
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 3870e9678b5d..15a3817aa5c8 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -21,7 +21,6 @@
21#include <sound/jack.h> 21#include <sound/jack.h>
22 22
23#include <plat/regs-iis.h> 23#include <plat/regs-iis.h>
24#include <mach/h1940-latch.h>
25#include <asm/mach-types.h> 24#include <asm/mach-types.h>
26 25
27#include "s3c24xx-i2s.h" 26#include "s3c24xx-i2s.h"
@@ -147,9 +146,9 @@ static int h1940_spk_power(struct snd_soc_dapm_widget *w,
147 struct snd_kcontrol *kcontrol, int event) 146 struct snd_kcontrol *kcontrol, int event)
148{ 147{
149 if (SND_SOC_DAPM_EVENT_ON(event)) 148 if (SND_SOC_DAPM_EVENT_ON(event))
150 gpio_set_value(H1940_LATCH_AUDIO_POWER, 1); 149 gpio_set_value(S3C_GPIO_END + 9, 1);
151 else 150 else
152 gpio_set_value(H1940_LATCH_AUDIO_POWER, 0); 151 gpio_set_value(S3C_GPIO_END + 9, 0);
153 152
154 return 0; 153 return 0;
155} 154}
@@ -233,11 +232,11 @@ static int __init h1940_init(void)
233 return -ENODEV; 232 return -ENODEV;
234 233
235 /* configure some gpios */ 234 /* configure some gpios */
236 ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power"); 235 ret = gpio_request(S3C_GPIO_END + 9, "speaker-power");
237 if (ret) 236 if (ret)
238 goto err_out; 237 goto err_out;
239 238
240 ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0); 239 ret = gpio_direction_output(S3C_GPIO_END + 9, 0);
241 if (ret) 240 if (ret)
242 goto err_gpio; 241 goto err_gpio;
243 242
@@ -258,7 +257,7 @@ static int __init h1940_init(void)
258err_plat: 257err_plat:
259 platform_device_put(s3c24xx_snd_device); 258 platform_device_put(s3c24xx_snd_device);
260err_gpio: 259err_gpio:
261 gpio_free(H1940_LATCH_AUDIO_POWER); 260 gpio_free(S3C_GPIO_END + 9);
262 261
263err_out: 262err_out:
264 return ret; 263 return ret;
@@ -269,7 +268,7 @@ static void __exit h1940_exit(void)
269 platform_device_unregister(s3c24xx_snd_device); 268 platform_device_unregister(s3c24xx_snd_device);
270 snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), 269 snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
271 hp_jack_gpios); 270 hp_jack_gpios);
272 gpio_free(H1940_LATCH_AUDIO_POWER); 271 gpio_free(S3C_GPIO_END + 9);
273} 272}
274 273
275module_init(h1940_init); 274module_init(h1940_init);
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d2d124f1dd1b..d7231e336a7c 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -15,11 +15,15 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_gpio.h>
18#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
19 21
20#include <sound/soc.h> 22#include <sound/soc.h>
21#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
22 24
25#include <mach/dma.h>
26
23#include <linux/platform_data/asoc-s3c.h> 27#include <linux/platform_data/asoc-s3c.h>
24 28
25#include "dma.h" 29#include "dma.h"
@@ -29,6 +33,15 @@
29 33
30#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 34#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
31 35
36enum samsung_dai_type {
37 TYPE_PRI,
38 TYPE_SEC,
39};
40
41struct samsung_i2s_dai_data {
42 int dai_type;
43};
44
32struct i2s_dai { 45struct i2s_dai {
33 /* Platform device for this DAI */ 46 /* Platform device for this DAI */
34 struct platform_device *pdev; 47 struct platform_device *pdev;
@@ -66,6 +79,7 @@ struct i2s_dai {
66 u32 suspend_i2smod; 79 u32 suspend_i2smod;
67 u32 suspend_i2scon; 80 u32 suspend_i2scon;
68 u32 suspend_i2spsr; 81 u32 suspend_i2spsr;
82 unsigned long gpios[7]; /* i2s gpio line numbers */
69}; 83};
70 84
71/* Lock for cross i/f checks */ 85/* Lock for cross i/f checks */
@@ -651,6 +665,9 @@ static int i2s_startup(struct snd_pcm_substream *substream,
651 /* Enforce set_sysclk in Master mode */ 665 /* Enforce set_sysclk in Master mode */
652 i2s->rclk_srcrate = 0; 666 i2s->rclk_srcrate = 0;
653 667
668 if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
669 writel(CON_RSTCLR, i2s->addr + I2SCON);
670
654 spin_unlock_irqrestore(&lock, flags); 671 spin_unlock_irqrestore(&lock, flags);
655 672
656 return 0; 673 return 0;
@@ -981,8 +998,7 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
981 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; 998 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
982 } else { /* Create a new platform_device for Secondary */ 999 } else { /* Create a new platform_device for Secondary */
983 i2s->pdev = platform_device_register_resndata(NULL, 1000 i2s->pdev = platform_device_register_resndata(NULL,
984 pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, 1001 "samsung-i2s-sec", -1, NULL, 0, NULL, 0);
985 NULL, 0, NULL, 0);
986 if (IS_ERR(i2s->pdev)) 1002 if (IS_ERR(i2s->pdev))
987 return NULL; 1003 return NULL;
988 } 1004 }
@@ -993,18 +1009,103 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
993 return i2s; 1009 return i2s;
994} 1010}
995 1011
1012#ifdef CONFIG_OF
1013static int samsung_i2s_parse_dt_gpio(struct i2s_dai *i2s)
1014{
1015 struct device *dev = &i2s->pdev->dev;
1016 int index, gpio, ret;
1017
1018 for (index = 0; index < 7; index++) {
1019 gpio = of_get_gpio(dev->of_node, index);
1020 if (!gpio_is_valid(gpio)) {
1021 dev_err(dev, "invalid gpio[%d]: %d\n", index, gpio);
1022 goto free_gpio;
1023 }
1024
1025 ret = gpio_request(gpio, dev_name(dev));
1026 if (ret) {
1027 dev_err(dev, "gpio [%d] request failed\n", gpio);
1028 goto free_gpio;
1029 }
1030 i2s->gpios[index] = gpio;
1031 }
1032 return 0;
1033
1034free_gpio:
1035 while (--index >= 0)
1036 gpio_free(i2s->gpios[index]);
1037 return -EINVAL;
1038}
1039
1040static void samsung_i2s_dt_gpio_free(struct i2s_dai *i2s)
1041{
1042 unsigned int index;
1043 for (index = 0; index < 7; index++)
1044 gpio_free(i2s->gpios[index]);
1045}
1046#else
1047static int samsung_i2s_parse_dt_gpio(struct i2s_dai *dai)
1048{
1049 return -EINVAL;
1050}
1051
1052static void samsung_i2s_dt_gpio_free(struct i2s_dai *dai)
1053{
1054}
1055
1056#endif
1057
1058static const struct of_device_id exynos_i2s_match[];
1059
1060static inline int samsung_i2s_get_driver_data(struct platform_device *pdev)
1061{
1062#ifdef CONFIG_OF
1063 struct samsung_i2s_dai_data *data;
1064 if (pdev->dev.of_node) {
1065 const struct of_device_id *match;
1066 match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
1067 data = (struct samsung_i2s_dai_data *) match->data;
1068 return data->dai_type;
1069 } else
1070#endif
1071 return platform_get_device_id(pdev)->driver_data;
1072}
1073
1074#ifdef CONFIG_PM_RUNTIME
1075static int i2s_runtime_suspend(struct device *dev)
1076{
1077 struct i2s_dai *i2s = dev_get_drvdata(dev);
1078
1079 clk_disable_unprepare(i2s->clk);
1080
1081 return 0;
1082}
1083
1084static int i2s_runtime_resume(struct device *dev)
1085{
1086 struct i2s_dai *i2s = dev_get_drvdata(dev);
1087
1088 clk_prepare_enable(i2s->clk);
1089
1090 return 0;
1091}
1092#endif /* CONFIG_PM_RUNTIME */
1093
996static int samsung_i2s_probe(struct platform_device *pdev) 1094static int samsung_i2s_probe(struct platform_device *pdev)
997{ 1095{
998 u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
999 struct i2s_dai *pri_dai, *sec_dai = NULL; 1096 struct i2s_dai *pri_dai, *sec_dai = NULL;
1000 struct s3c_audio_pdata *i2s_pdata; 1097 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1001 struct samsung_i2s *i2s_cfg; 1098 struct samsung_i2s *i2s_cfg = NULL;
1002 struct resource *res; 1099 struct resource *res;
1003 u32 regs_base, quirks; 1100 u32 regs_base, quirks = 0, idma_addr = 0;
1101 struct device_node *np = pdev->dev.of_node;
1102 enum samsung_dai_type samsung_dai_type;
1004 int ret = 0; 1103 int ret = 0;
1005 1104
1006 /* Call during Seconday interface registration */ 1105 /* Call during Seconday interface registration */
1007 if (pdev->id >= SAMSUNG_I2S_SECOFF) { 1106 samsung_dai_type = samsung_i2s_get_driver_data(pdev);
1107
1108 if (samsung_dai_type == TYPE_SEC) {
1008 sec_dai = dev_get_drvdata(&pdev->dev); 1109 sec_dai = dev_get_drvdata(&pdev->dev);
1009 snd_soc_register_dai(&sec_dai->pdev->dev, 1110 snd_soc_register_dai(&sec_dai->pdev->dev,
1010 &sec_dai->i2s_dai_drv); 1111 &sec_dai->i2s_dai_drv);
@@ -1012,31 +1113,60 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1012 return 0; 1113 return 0;
1013 } 1114 }
1014 1115
1015 i2s_pdata = pdev->dev.platform_data; 1116 pri_dai = i2s_alloc_dai(pdev, false);
1016 if (i2s_pdata == NULL) { 1117 if (!pri_dai) {
1017 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); 1118 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1018 return -EINVAL; 1119 return -ENOMEM;
1019 } 1120 }
1020 1121
1021 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1122 if (!np) {
1022 if (!res) { 1123 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1023 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); 1124 if (!res) {
1024 return -ENXIO; 1125 dev_err(&pdev->dev,
1025 } 1126 "Unable to get I2S-TX dma resource\n");
1026 dma_pl_chan = res->start; 1127 return -ENXIO;
1128 }
1129 pri_dai->dma_playback.channel = res->start;
1027 1130
1028 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1131 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1029 if (!res) { 1132 if (!res) {
1030 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); 1133 dev_err(&pdev->dev,
1031 return -ENXIO; 1134 "Unable to get I2S-RX dma resource\n");
1032 } 1135 return -ENXIO;
1033 dma_cp_chan = res->start; 1136 }
1137 pri_dai->dma_capture.channel = res->start;
1034 1138
1035 res = platform_get_resource(pdev, IORESOURCE_DMA, 2); 1139 if (i2s_pdata == NULL) {
1036 if (res) 1140 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1037 dma_pl_sec_chan = res->start; 1141 return -EINVAL;
1038 else 1142 }
1039 dma_pl_sec_chan = 0; 1143
1144 if (&i2s_pdata->type)
1145 i2s_cfg = &i2s_pdata->type.i2s;
1146
1147 if (i2s_cfg) {
1148 quirks = i2s_cfg->quirks;
1149 idma_addr = i2s_cfg->idma_addr;
1150 }
1151 } else {
1152 if (of_find_property(np, "samsung,supports-6ch", NULL))
1153 quirks |= QUIRK_PRI_6CHAN;
1154
1155 if (of_find_property(np, "samsung,supports-secdai", NULL))
1156 quirks |= QUIRK_SEC_DAI;
1157
1158 if (of_find_property(np, "samsung,supports-rstclr", NULL))
1159 quirks |= QUIRK_NEED_RSTCLR;
1160
1161 if (of_property_read_u32(np, "samsung,idma-addr",
1162 &idma_addr)) {
1163 if (quirks & QUIRK_SEC_DAI) {
1164 dev_err(&pdev->dev, "idma address is not"\
1165 "specified");
1166 return -EINVAL;
1167 }
1168 }
1169 }
1040 1170
1041 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1171 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1042 if (!res) { 1172 if (!res) {
@@ -1051,24 +1181,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1051 } 1181 }
1052 regs_base = res->start; 1182 regs_base = res->start;
1053 1183
1054 i2s_cfg = &i2s_pdata->type.i2s;
1055 quirks = i2s_cfg->quirks;
1056
1057 pri_dai = i2s_alloc_dai(pdev, false);
1058 if (!pri_dai) {
1059 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1060 ret = -ENOMEM;
1061 goto err;
1062 }
1063
1064 pri_dai->dma_playback.dma_addr = regs_base + I2STXD; 1184 pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1065 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; 1185 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1066 pri_dai->dma_playback.client = 1186 pri_dai->dma_playback.client =
1067 (struct s3c2410_dma_client *)&pri_dai->dma_playback; 1187 (struct s3c2410_dma_client *)&pri_dai->dma_playback;
1188 pri_dai->dma_playback.ch_name = "tx";
1068 pri_dai->dma_capture.client = 1189 pri_dai->dma_capture.client =
1069 (struct s3c2410_dma_client *)&pri_dai->dma_capture; 1190 (struct s3c2410_dma_client *)&pri_dai->dma_capture;
1070 pri_dai->dma_playback.channel = dma_pl_chan; 1191 pri_dai->dma_capture.ch_name = "rx";
1071 pri_dai->dma_capture.channel = dma_cp_chan;
1072 pri_dai->dma_playback.dma_size = 4; 1192 pri_dai->dma_playback.dma_size = 4;
1073 pri_dai->dma_capture.dma_size = 4; 1193 pri_dai->dma_capture.dma_size = 4;
1074 pri_dai->base = regs_base; 1194 pri_dai->base = regs_base;
@@ -1087,20 +1207,34 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1087 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; 1207 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
1088 sec_dai->dma_playback.client = 1208 sec_dai->dma_playback.client =
1089 (struct s3c2410_dma_client *)&sec_dai->dma_playback; 1209 (struct s3c2410_dma_client *)&sec_dai->dma_playback;
1090 /* Use iDMA always if SysDMA not provided */ 1210 sec_dai->dma_playback.ch_name = "tx-sec";
1091 sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; 1211
1212 if (!np) {
1213 res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
1214 if (res)
1215 sec_dai->dma_playback.channel = res->start;
1216 }
1217
1092 sec_dai->dma_playback.dma_size = 4; 1218 sec_dai->dma_playback.dma_size = 4;
1093 sec_dai->base = regs_base; 1219 sec_dai->base = regs_base;
1094 sec_dai->quirks = quirks; 1220 sec_dai->quirks = quirks;
1095 sec_dai->idma_playback.dma_addr = i2s_cfg->idma_addr; 1221 sec_dai->idma_playback.dma_addr = idma_addr;
1096 sec_dai->pri_dai = pri_dai; 1222 sec_dai->pri_dai = pri_dai;
1097 pri_dai->sec_dai = sec_dai; 1223 pri_dai->sec_dai = sec_dai;
1098 } 1224 }
1099 1225
1100 if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { 1226 if (np) {
1101 dev_err(&pdev->dev, "Unable to configure gpio\n"); 1227 if (samsung_i2s_parse_dt_gpio(pri_dai)) {
1102 ret = -EINVAL; 1228 dev_err(&pdev->dev, "Unable to configure gpio\n");
1103 goto err; 1229 ret = -EINVAL;
1230 goto err;
1231 }
1232 } else {
1233 if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1234 dev_err(&pdev->dev, "Unable to configure gpio\n");
1235 ret = -EINVAL;
1236 goto err;
1237 }
1104 } 1238 }
1105 1239
1106 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); 1240 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
@@ -1120,10 +1254,14 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1120{ 1254{
1121 struct i2s_dai *i2s, *other; 1255 struct i2s_dai *i2s, *other;
1122 struct resource *res; 1256 struct resource *res;
1257 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1123 1258
1124 i2s = dev_get_drvdata(&pdev->dev); 1259 i2s = dev_get_drvdata(&pdev->dev);
1125 other = i2s->pri_dai ? : i2s->sec_dai; 1260 other = i2s->pri_dai ? : i2s->sec_dai;
1126 1261
1262 if (!i2s_pdata->cfg_gpio && pdev->dev.of_node)
1263 samsung_i2s_dt_gpio_free(i2s->pri_dai);
1264
1127 if (other) { 1265 if (other) {
1128 other->pri_dai = NULL; 1266 other->pri_dai = NULL;
1129 other->sec_dai = NULL; 1267 other->sec_dai = NULL;
@@ -1143,12 +1281,47 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1143 return 0; 1281 return 0;
1144} 1282}
1145 1283
1284static struct platform_device_id samsung_i2s_driver_ids[] = {
1285 {
1286 .name = "samsung-i2s",
1287 .driver_data = TYPE_PRI,
1288 }, {
1289 .name = "samsung-i2s-sec",
1290 .driver_data = TYPE_SEC,
1291 },
1292 {},
1293};
1294MODULE_DEVICE_TABLE(platform, samsung-i2s-driver-ids);
1295
1296#ifdef CONFIG_OF
1297static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = {
1298 [TYPE_PRI] = { TYPE_PRI },
1299 [TYPE_SEC] = { TYPE_SEC },
1300};
1301
1302static const struct of_device_id exynos_i2s_match[] = {
1303 { .compatible = "samsung,i2s-v5",
1304 .data = &samsung_i2s_dai_data_array[TYPE_PRI],
1305 },
1306 {},
1307};
1308MODULE_DEVICE_TABLE(of, exynos_i2s_match);
1309#endif
1310
1311static const struct dev_pm_ops samsung_i2s_pm = {
1312 SET_RUNTIME_PM_OPS(i2s_runtime_suspend,
1313 i2s_runtime_resume, NULL)
1314};
1315
1146static struct platform_driver samsung_i2s_driver = { 1316static struct platform_driver samsung_i2s_driver = {
1147 .probe = samsung_i2s_probe, 1317 .probe = samsung_i2s_probe,
1148 .remove = samsung_i2s_remove, 1318 .remove = samsung_i2s_remove,
1319 .id_table = samsung_i2s_driver_ids,
1149 .driver = { 1320 .driver = {
1150 .name = "samsung-i2s", 1321 .name = "samsung-i2s",
1151 .owner = THIS_MODULE, 1322 .owner = THIS_MODULE,
1323 .of_match_table = of_match_ptr(exynos_i2s_match),
1324 .pm = &samsung_i2s_pm,
1152 }, 1325 },
1153}; 1326};
1154 1327
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
index d420a7ca56ca..7966afc934db 100644
--- a/sound/soc/samsung/i2s.h
+++ b/sound/soc/samsung/i2s.h
@@ -13,13 +13,6 @@
13#ifndef __SND_SOC_SAMSUNG_I2S_H 13#ifndef __SND_SOC_SAMSUNG_I2S_H
14#define __SND_SOC_SAMSUNG_I2S_H 14#define __SND_SOC_SAMSUNG_I2S_H
15 15
16/*
17 * Maximum number of I2S blocks that any SoC can have.
18 * The secondary interface of a CPU dai(if there exists any),
19 * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
20 */
21#define SAMSUNG_I2S_SECOFF 4
22
23#define SAMSUNG_I2S_DIV_BCLK 1 16#define SAMSUNG_I2S_DIV_BCLK 1
24 17
25#define SAMSUNG_I2S_RCLKSRC_0 0 18#define SAMSUNG_I2S_RCLKSRC_0 0
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index c7e965f80d2e..a301d8cfaa34 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -237,7 +237,7 @@ static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
237{ 237{
238 gta02_speaker_enabled = ucontrol->value.integer.value[0]; 238 gta02_speaker_enabled = ucontrol->value.integer.value[0];
239 239
240 gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled); 240 gpio_set_value(S3C2410_GPJ(2), !gta02_speaker_enabled);
241 241
242 return 0; 242 return 0;
243} 243}
@@ -252,7 +252,7 @@ static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
252static int lm4853_event(struct snd_soc_dapm_widget *w, 252static int lm4853_event(struct snd_soc_dapm_widget *w,
253 struct snd_kcontrol *k, int event) 253 struct snd_kcontrol *k, int event)
254{ 254{
255 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); 255 gpio_set_value(S3C2410_GPJ(1), SND_SOC_DAPM_EVENT_OFF(event));
256 256
257 return 0; 257 return 0;
258} 258}
@@ -396,8 +396,8 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = {
396}; 396};
397 397
398static const struct gpio neo1973_gta02_gpios[] = { 398static const struct gpio neo1973_gta02_gpios[] = {
399 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, 399 { S3C2410_GPJ(2), GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
400 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, 400 { S3C2410_GPJ(1), GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
401}; 401};
402 402
403static struct snd_soc_card neo1973 = { 403static struct snd_soc_card neo1973 = {
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index ee10e8704e97..13f6dd1ceb00 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -469,7 +469,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
469{ 469{
470 int ret = 0; 470 int ret = 0;
471 471
472 ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); 472 ret = snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai);
473 if (ret) { 473 if (ret) {
474 pr_err("failed to register the dai\n"); 474 pr_err("failed to register the dai\n");
475 return ret; 475 return ret;
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 7e2b710763be..7a16b32ed673 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -193,9 +193,9 @@ static struct snd_soc_dai_link smdk_dai[] = {
193 [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ 193 [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
194 .name = "Sec_FIFO TX", 194 .name = "Sec_FIFO TX",
195 .stream_name = "Playback", 195 .stream_name = "Playback",
196 .cpu_dai_name = "samsung-i2s.x", 196 .cpu_dai_name = "samsung-i2s-sec",
197 .codec_dai_name = "wm8580-hifi-playback", 197 .codec_dai_name = "wm8580-hifi-playback",
198 .platform_name = "samsung-i2s.x", 198 .platform_name = "samsung-i2s-sec",
199 .codec_name = "wm8580.0-001b", 199 .codec_name = "wm8580.0-001b",
200 .ops = &smdk_ops, 200 .ops = &smdk_ops,
201 }, 201 },
@@ -223,9 +223,6 @@ static int __init smdk_audio_init(void)
223 if (machine_is_smdkc100() 223 if (machine_is_smdkc100()
224 || machine_is_smdkv210() || machine_is_smdkc110()) { 224 || machine_is_smdkv210() || machine_is_smdkc110()) {
225 smdk.num_links = 3; 225 smdk.num_links = 3;
226 /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
227 str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
228 str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
229 } else if (machine_is_smdk6410()) { 226 } else if (machine_is_smdk6410()) {
230 str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; 227 str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
231 str[strlen(str) - 1] = '2'; 228 str[strlen(str) - 1] = '2';
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index b0d0ab8bff5a..581ea4a06fc6 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -10,6 +10,7 @@
10#include "../codecs/wm8994.h" 10#include "../codecs/wm8994.h"
11#include <sound/pcm_params.h> 11#include <sound/pcm_params.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h>
13 14
14 /* 15 /*
15 * Default CFG switch settings to use this driver: 16 * Default CFG switch settings to use this driver:
@@ -134,9 +135,9 @@ static struct snd_soc_dai_link smdk_dai[] = {
134 }, { /* Sec_Fifo Playback i/f */ 135 }, { /* Sec_Fifo Playback i/f */
135 .name = "Sec_FIFO TX", 136 .name = "Sec_FIFO TX",
136 .stream_name = "Sec_Dai", 137 .stream_name = "Sec_Dai",
137 .cpu_dai_name = "samsung-i2s.4", 138 .cpu_dai_name = "samsung-i2s-sec",
138 .codec_dai_name = "wm8994-aif1", 139 .codec_dai_name = "wm8994-aif1",
139 .platform_name = "samsung-i2s.4", 140 .platform_name = "samsung-i2s-sec",
140 .codec_name = "wm8994-codec", 141 .codec_name = "wm8994-codec",
141 .ops = &smdk_ops, 142 .ops = &smdk_ops,
142 }, 143 },
@@ -153,9 +154,25 @@ static struct snd_soc_card smdk = {
153static int smdk_audio_probe(struct platform_device *pdev) 154static int smdk_audio_probe(struct platform_device *pdev)
154{ 155{
155 int ret; 156 int ret;
157 struct device_node *np = pdev->dev.of_node;
156 struct snd_soc_card *card = &smdk; 158 struct snd_soc_card *card = &smdk;
157 159
158 card->dev = &pdev->dev; 160 card->dev = &pdev->dev;
161
162 if (np) {
163 smdk_dai[0].cpu_dai_name = NULL;
164 smdk_dai[0].cpu_of_node = of_parse_phandle(np,
165 "samsung,i2s-controller", 0);
166 if (!smdk_dai[0].cpu_of_node) {
167 dev_err(&pdev->dev,
168 "Property 'samsung,i2s-controller' missing or invalid\n");
169 ret = -EINVAL;
170 }
171
172 smdk_dai[0].platform_name = NULL;
173 smdk_dai[0].platform_of_node = smdk_dai[0].cpu_of_node;
174 }
175
159 ret = snd_soc_register_card(card); 176 ret = snd_soc_register_card(card);
160 177
161 if (ret) 178 if (ret)
@@ -173,10 +190,19 @@ static int smdk_audio_remove(struct platform_device *pdev)
173 return 0; 190 return 0;
174} 191}
175 192
193#ifdef CONFIG_OF
194static const struct of_device_id samsung_wm8994_of_match[] = {
195 { .compatible = "samsung,smdk-wm8994", },
196 {},
197};
198MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);
199#endif /* CONFIG_OF */
200
176static struct platform_driver smdk_audio_driver = { 201static struct platform_driver smdk_audio_driver = {
177 .driver = { 202 .driver = {
178 .name = "smdk-audio", 203 .name = "smdk-audio",
179 .owner = THIS_MODULE, 204 .owner = THIS_MODULE,
205 .of_match_table = of_match_ptr(samsung_wm8994_of_match),
180 }, 206 },
181 .probe = smdk_audio_probe, 207 .probe = smdk_audio_probe,
182 .remove = smdk_audio_remove, 208 .remove = smdk_audio_remove,
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index a606d0f93d1c..c724026a246f 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -16,6 +16,8 @@
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
19#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
20#include <linux/sh_dma.h> 22#include <linux/sh_dma.h>
21#include <linux/slab.h> 23#include <linux/slab.h>
@@ -131,8 +133,6 @@
131 133
132#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 134#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
133 135
134typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
135
136/* 136/*
137 * bus options 137 * bus options
138 * 138 *
@@ -244,8 +244,7 @@ struct fsi_clk {
244 struct clk *ick; 244 struct clk *ick;
245 struct clk *div; 245 struct clk *div;
246 int (*set_rate)(struct device *dev, 246 int (*set_rate)(struct device *dev,
247 struct fsi_priv *fsi, 247 struct fsi_priv *fsi);
248 unsigned long rate);
249 248
250 unsigned long rate; 249 unsigned long rate;
251 unsigned int count; 250 unsigned int count;
@@ -254,7 +253,6 @@ struct fsi_clk {
254struct fsi_priv { 253struct fsi_priv {
255 void __iomem *base; 254 void __iomem *base;
256 struct fsi_master *master; 255 struct fsi_master *master;
257 struct sh_fsi_port_info *info;
258 256
259 struct fsi_stream playback; 257 struct fsi_stream playback;
260 struct fsi_stream capture; 258 struct fsi_stream capture;
@@ -270,8 +268,6 @@ struct fsi_priv {
270 int enable_stream:1; 268 int enable_stream:1;
271 int bit_clk_inv:1; 269 int bit_clk_inv:1;
272 int lr_clk_inv:1; 270 int lr_clk_inv:1;
273
274 long rate;
275}; 271};
276 272
277struct fsi_stream_handler { 273struct fsi_stream_handler {
@@ -303,7 +299,7 @@ struct fsi_master {
303 int irq; 299 int irq;
304 struct fsi_priv fsia; 300 struct fsi_priv fsia;
305 struct fsi_priv fsib; 301 struct fsi_priv fsib;
306 struct fsi_core *core; 302 const struct fsi_core *core;
307 spinlock_t lock; 303 spinlock_t lock;
308}; 304};
309 305
@@ -431,22 +427,6 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
431 return fsi_get_priv_frm_dai(fsi_get_dai(substream)); 427 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
432} 428}
433 429
434static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
435{
436 if (!fsi->info)
437 return NULL;
438
439 return fsi->info->set_rate;
440}
441
442static u32 fsi_get_info_flags(struct fsi_priv *fsi)
443{
444 if (!fsi->info)
445 return 0;
446
447 return fsi->info->flags;
448}
449
450static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io) 430static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
451{ 431{
452 int is_play = fsi_stream_is_play(fsi, io); 432 int is_play = fsi_stream_is_play(fsi, io);
@@ -757,8 +737,7 @@ static int fsi_clk_init(struct device *dev,
757 int ick, 737 int ick,
758 int div, 738 int div,
759 int (*set_rate)(struct device *dev, 739 int (*set_rate)(struct device *dev,
760 struct fsi_priv *fsi, 740 struct fsi_priv *fsi))
761 unsigned long rate))
762{ 741{
763 struct fsi_clk *clock = &fsi->clock; 742 struct fsi_clk *clock = &fsi->clock;
764 int is_porta = fsi_is_port_a(fsi); 743 int is_porta = fsi_is_port_a(fsi);
@@ -829,8 +808,7 @@ static int fsi_clk_is_valid(struct fsi_priv *fsi)
829} 808}
830 809
831static int fsi_clk_enable(struct device *dev, 810static int fsi_clk_enable(struct device *dev,
832 struct fsi_priv *fsi, 811 struct fsi_priv *fsi)
833 unsigned long rate)
834{ 812{
835 struct fsi_clk *clock = &fsi->clock; 813 struct fsi_clk *clock = &fsi->clock;
836 int ret = -EINVAL; 814 int ret = -EINVAL;
@@ -839,7 +817,7 @@ static int fsi_clk_enable(struct device *dev,
839 return ret; 817 return ret;
840 818
841 if (0 == clock->count) { 819 if (0 == clock->count) {
842 ret = clock->set_rate(dev, fsi, rate); 820 ret = clock->set_rate(dev, fsi);
843 if (ret < 0) { 821 if (ret < 0) {
844 fsi_clk_invalid(fsi); 822 fsi_clk_invalid(fsi);
845 return ret; 823 return ret;
@@ -946,11 +924,11 @@ static int fsi_clk_set_ackbpf(struct device *dev,
946} 924}
947 925
948static int fsi_clk_set_rate_external(struct device *dev, 926static int fsi_clk_set_rate_external(struct device *dev,
949 struct fsi_priv *fsi, 927 struct fsi_priv *fsi)
950 unsigned long rate)
951{ 928{
952 struct clk *xck = fsi->clock.xck; 929 struct clk *xck = fsi->clock.xck;
953 struct clk *ick = fsi->clock.ick; 930 struct clk *ick = fsi->clock.ick;
931 unsigned long rate = fsi->clock.rate;
954 unsigned long xrate; 932 unsigned long xrate;
955 int ackmd, bpfmd; 933 int ackmd, bpfmd;
956 int ret = 0; 934 int ret = 0;
@@ -978,11 +956,11 @@ static int fsi_clk_set_rate_external(struct device *dev,
978} 956}
979 957
980static int fsi_clk_set_rate_cpg(struct device *dev, 958static int fsi_clk_set_rate_cpg(struct device *dev,
981 struct fsi_priv *fsi, 959 struct fsi_priv *fsi)
982 unsigned long rate)
983{ 960{
984 struct clk *ick = fsi->clock.ick; 961 struct clk *ick = fsi->clock.ick;
985 struct clk *div = fsi->clock.div; 962 struct clk *div = fsi->clock.div;
963 unsigned long rate = fsi->clock.rate;
986 unsigned long target = 0; /* 12288000 or 11289600 */ 964 unsigned long target = 0; /* 12288000 or 11289600 */
987 unsigned long actual, cout; 965 unsigned long actual, cout;
988 unsigned long diff, min; 966 unsigned long diff, min;
@@ -1063,85 +1041,6 @@ static int fsi_clk_set_rate_cpg(struct device *dev,
1063 return ret; 1041 return ret;
1064} 1042}
1065 1043
1066static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
1067 long rate, int enable)
1068{
1069 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
1070 int ret;
1071
1072 /*
1073 * CAUTION
1074 *
1075 * set_rate will be deleted
1076 */
1077 if (!set_rate) {
1078 if (enable)
1079 return fsi_clk_enable(dev, fsi, rate);
1080 else
1081 return fsi_clk_disable(dev, fsi);
1082 }
1083
1084 ret = set_rate(dev, rate, enable);
1085 if (ret < 0) /* error */
1086 return ret;
1087
1088 if (!enable)
1089 return 0;
1090
1091 if (ret > 0) {
1092 u32 data = 0;
1093
1094 switch (ret & SH_FSI_ACKMD_MASK) {
1095 default:
1096 /* FALL THROUGH */
1097 case SH_FSI_ACKMD_512:
1098 data |= (0x0 << 12);
1099 break;
1100 case SH_FSI_ACKMD_256:
1101 data |= (0x1 << 12);
1102 break;
1103 case SH_FSI_ACKMD_128:
1104 data |= (0x2 << 12);
1105 break;
1106 case SH_FSI_ACKMD_64:
1107 data |= (0x3 << 12);
1108 break;
1109 case SH_FSI_ACKMD_32:
1110 data |= (0x4 << 12);
1111 break;
1112 }
1113
1114 switch (ret & SH_FSI_BPFMD_MASK) {
1115 default:
1116 /* FALL THROUGH */
1117 case SH_FSI_BPFMD_32:
1118 data |= (0x0 << 8);
1119 break;
1120 case SH_FSI_BPFMD_64:
1121 data |= (0x1 << 8);
1122 break;
1123 case SH_FSI_BPFMD_128:
1124 data |= (0x2 << 8);
1125 break;
1126 case SH_FSI_BPFMD_256:
1127 data |= (0x3 << 8);
1128 break;
1129 case SH_FSI_BPFMD_512:
1130 data |= (0x4 << 8);
1131 break;
1132 case SH_FSI_BPFMD_16:
1133 data |= (0x7 << 8);
1134 break;
1135 }
1136
1137 fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
1138 udelay(10);
1139 ret = 0;
1140 }
1141
1142 return ret;
1143}
1144
1145/* 1044/*
1146 * pio data transfer handler 1045 * pio data transfer handler
1147 */ 1046 */
@@ -1637,7 +1536,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1637 struct fsi_stream *io, 1536 struct fsi_stream *io,
1638 struct device *dev) 1537 struct device *dev)
1639{ 1538{
1640 u32 flags = fsi_get_info_flags(fsi);
1641 u32 data = 0; 1539 u32 data = 0;
1642 1540
1643 /* clock setting */ 1541 /* clock setting */
@@ -1654,19 +1552,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1654 data |= (1 << 4); 1552 data |= (1 << 4);
1655 if (fsi_is_clk_master(fsi)) 1553 if (fsi_is_clk_master(fsi))
1656 data <<= 8; 1554 data <<= 8;
1657 /* FIXME
1658 *
1659 * SH_FSI_xxx_INV style will be removed
1660 */
1661 if (SH_FSI_LRM_INV & flags)
1662 data |= 1 << 12;
1663 if (SH_FSI_BRM_INV & flags)
1664 data |= 1 << 8;
1665 if (SH_FSI_LRS_INV & flags)
1666 data |= 1 << 4;
1667 if (SH_FSI_BRS_INV & flags)
1668 data |= 1 << 0;
1669
1670 fsi_reg_write(fsi, CKG2, data); 1555 fsi_reg_write(fsi, CKG2, data);
1671 1556
1672 /* spdif ? */ 1557 /* spdif ? */
@@ -1698,7 +1583,7 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1698 1583
1699 /* start master clock */ 1584 /* start master clock */
1700 if (fsi_is_clk_master(fsi)) 1585 if (fsi_is_clk_master(fsi))
1701 return fsi_set_master_clk(dev, fsi, fsi->rate, 1); 1586 return fsi_clk_enable(dev, fsi);
1702 1587
1703 return 0; 1588 return 0;
1704} 1589}
@@ -1708,7 +1593,7 @@ static int fsi_hw_shutdown(struct fsi_priv *fsi,
1708{ 1593{
1709 /* stop master clock */ 1594 /* stop master clock */
1710 if (fsi_is_clk_master(fsi)) 1595 if (fsi_is_clk_master(fsi))
1711 return fsi_set_master_clk(dev, fsi, fsi->rate, 0); 1596 return fsi_clk_disable(dev, fsi);
1712 1597
1713 return 0; 1598 return 0;
1714} 1599}
@@ -1719,7 +1604,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
1719 struct fsi_priv *fsi = fsi_get_priv(substream); 1604 struct fsi_priv *fsi = fsi_get_priv(substream);
1720 1605
1721 fsi_clk_invalid(fsi); 1606 fsi_clk_invalid(fsi);
1722 fsi->rate = 0;
1723 1607
1724 return 0; 1608 return 0;
1725} 1609}
@@ -1730,7 +1614,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
1730 struct fsi_priv *fsi = fsi_get_priv(substream); 1614 struct fsi_priv *fsi = fsi_get_priv(substream);
1731 1615
1732 fsi_clk_invalid(fsi); 1616 fsi_clk_invalid(fsi);
1733 fsi->rate = 0;
1734} 1617}
1735 1618
1736static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 1619static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -1795,7 +1678,6 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
1795static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1678static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1796{ 1679{
1797 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 1680 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
1798 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
1799 int ret; 1681 int ret;
1800 1682
1801 /* set master/slave audio interface */ 1683 /* set master/slave audio interface */
@@ -1831,14 +1713,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1831 } 1713 }
1832 1714
1833 if (fsi_is_clk_master(fsi)) { 1715 if (fsi_is_clk_master(fsi)) {
1834 /*
1835 * CAUTION
1836 *
1837 * set_rate will be deleted
1838 */
1839 if (set_rate)
1840 dev_warn(dai->dev, "set_rate will be removed soon\n");
1841
1842 if (fsi->clk_cpg) 1716 if (fsi->clk_cpg)
1843 fsi_clk_init(dai->dev, fsi, 0, 1, 1, 1717 fsi_clk_init(dai->dev, fsi, 0, 1, 1,
1844 fsi_clk_set_rate_cpg); 1718 fsi_clk_set_rate_cpg);
@@ -1862,10 +1736,8 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
1862{ 1736{
1863 struct fsi_priv *fsi = fsi_get_priv(substream); 1737 struct fsi_priv *fsi = fsi_get_priv(substream);
1864 1738
1865 if (fsi_is_clk_master(fsi)) { 1739 if (fsi_is_clk_master(fsi))
1866 fsi->rate = params_rate(params); 1740 fsi_clk_valid(fsi, params_rate(params));
1867 fsi_clk_valid(fsi, fsi->rate);
1868 }
1869 1741
1870 return 0; 1742 return 0;
1871} 1743}
@@ -2017,6 +1889,33 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
2017/* 1889/*
2018 * platform function 1890 * platform function
2019 */ 1891 */
1892static void fsi_of_parse(char *name,
1893 struct device_node *np,
1894 struct sh_fsi_port_info *info,
1895 struct device *dev)
1896{
1897 int i;
1898 char prop[128];
1899 unsigned long flags = 0;
1900 struct {
1901 char *name;
1902 unsigned int val;
1903 } of_parse_property[] = {
1904 { "spdif-connection", SH_FSI_FMT_SPDIF },
1905 { "stream-mode-support", SH_FSI_ENABLE_STREAM_MODE },
1906 { "use-internal-clock", SH_FSI_CLK_CPG },
1907 };
1908
1909 for (i = 0; i < ARRAY_SIZE(of_parse_property); i++) {
1910 sprintf(prop, "%s,%s", name, of_parse_property[i].name);
1911 if (of_get_property(np, prop, NULL))
1912 flags |= of_parse_property[i].val;
1913 }
1914 info->flags = flags;
1915
1916 dev_dbg(dev, "%s flags : %lx\n", name, info->flags);
1917}
1918
2020static void fsi_port_info_init(struct fsi_priv *fsi, 1919static void fsi_port_info_init(struct fsi_priv *fsi,
2021 struct sh_fsi_port_info *info) 1920 struct sh_fsi_port_info *info)
2022{ 1921{
@@ -2044,23 +1943,40 @@ static void fsi_handler_init(struct fsi_priv *fsi,
2044 } 1943 }
2045} 1944}
2046 1945
1946static struct of_device_id fsi_of_match[];
2047static int fsi_probe(struct platform_device *pdev) 1947static int fsi_probe(struct platform_device *pdev)
2048{ 1948{
2049 struct fsi_master *master; 1949 struct fsi_master *master;
2050 const struct platform_device_id *id_entry; 1950 struct device_node *np = pdev->dev.of_node;
2051 struct sh_fsi_platform_info *info = pdev->dev.platform_data; 1951 struct sh_fsi_platform_info info;
2052 struct sh_fsi_port_info nul_info, *pinfo; 1952 const struct fsi_core *core;
2053 struct fsi_priv *fsi; 1953 struct fsi_priv *fsi;
2054 struct resource *res; 1954 struct resource *res;
2055 unsigned int irq; 1955 unsigned int irq;
2056 int ret; 1956 int ret;
2057 1957
2058 nul_info.flags = 0; 1958 memset(&info, 0, sizeof(info));
2059 nul_info.tx_id = 0; 1959
2060 nul_info.rx_id = 0; 1960 core = NULL;
1961 if (np) {
1962 const struct of_device_id *of_id;
2061 1963
2062 id_entry = pdev->id_entry; 1964 of_id = of_match_device(fsi_of_match, &pdev->dev);
2063 if (!id_entry) { 1965 if (of_id) {
1966 core = of_id->data;
1967 fsi_of_parse("fsia", np, &info.port_a, &pdev->dev);
1968 fsi_of_parse("fsib", np, &info.port_b, &pdev->dev);
1969 }
1970 } else {
1971 const struct platform_device_id *id_entry = pdev->id_entry;
1972 if (id_entry)
1973 core = (struct fsi_core *)id_entry->driver_data;
1974
1975 if (pdev->dev.platform_data)
1976 memcpy(&info, pdev->dev.platform_data, sizeof(info));
1977 }
1978
1979 if (!core) {
2064 dev_err(&pdev->dev, "unknown fsi device\n"); 1980 dev_err(&pdev->dev, "unknown fsi device\n");
2065 return -ENODEV; 1981 return -ENODEV;
2066 } 1982 }
@@ -2087,17 +2003,15 @@ static int fsi_probe(struct platform_device *pdev)
2087 2003
2088 /* master setting */ 2004 /* master setting */
2089 master->irq = irq; 2005 master->irq = irq;
2090 master->core = (struct fsi_core *)id_entry->driver_data; 2006 master->core = core;
2091 spin_lock_init(&master->lock); 2007 spin_lock_init(&master->lock);
2092 2008
2093 /* FSI A setting */ 2009 /* FSI A setting */
2094 pinfo = (info) ? &info->port_a : &nul_info;
2095 fsi = &master->fsia; 2010 fsi = &master->fsia;
2096 fsi->base = master->base; 2011 fsi->base = master->base;
2097 fsi->master = master; 2012 fsi->master = master;
2098 fsi->info = pinfo; 2013 fsi_port_info_init(fsi, &info.port_a);
2099 fsi_port_info_init(fsi, pinfo); 2014 fsi_handler_init(fsi, &info.port_a);
2100 fsi_handler_init(fsi, pinfo);
2101 ret = fsi_stream_probe(fsi, &pdev->dev); 2015 ret = fsi_stream_probe(fsi, &pdev->dev);
2102 if (ret < 0) { 2016 if (ret < 0) {
2103 dev_err(&pdev->dev, "FSIA stream probe failed\n"); 2017 dev_err(&pdev->dev, "FSIA stream probe failed\n");
@@ -2105,13 +2019,11 @@ static int fsi_probe(struct platform_device *pdev)
2105 } 2019 }
2106 2020
2107 /* FSI B setting */ 2021 /* FSI B setting */
2108 pinfo = (info) ? &info->port_b : &nul_info;
2109 fsi = &master->fsib; 2022 fsi = &master->fsib;
2110 fsi->base = master->base + 0x40; 2023 fsi->base = master->base + 0x40;
2111 fsi->master = master; 2024 fsi->master = master;
2112 fsi->info = pinfo; 2025 fsi_port_info_init(fsi, &info.port_b);
2113 fsi_port_info_init(fsi, pinfo); 2026 fsi_handler_init(fsi, &info.port_b);
2114 fsi_handler_init(fsi, pinfo);
2115 ret = fsi_stream_probe(fsi, &pdev->dev); 2027 ret = fsi_stream_probe(fsi, &pdev->dev);
2116 if (ret < 0) { 2028 if (ret < 0) {
2117 dev_err(&pdev->dev, "FSIB stream probe failed\n"); 2029 dev_err(&pdev->dev, "FSIB stream probe failed\n");
@@ -2122,7 +2034,7 @@ static int fsi_probe(struct platform_device *pdev)
2122 dev_set_drvdata(&pdev->dev, master); 2034 dev_set_drvdata(&pdev->dev, master);
2123 2035
2124 ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, 2036 ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0,
2125 id_entry->name, master); 2037 dev_name(&pdev->dev), master);
2126 if (ret) { 2038 if (ret) {
2127 dev_err(&pdev->dev, "irq request err\n"); 2039 dev_err(&pdev->dev, "irq request err\n");
2128 goto exit_fsib; 2040 goto exit_fsib;
@@ -2248,6 +2160,13 @@ static struct fsi_core fsi2_core = {
2248 .b_mclk = B_MST_CTLR, 2160 .b_mclk = B_MST_CTLR,
2249}; 2161};
2250 2162
2163static struct of_device_id fsi_of_match[] = {
2164 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
2165 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
2166 {},
2167};
2168MODULE_DEVICE_TABLE(of, fsi_of_match);
2169
2251static struct platform_device_id fsi_id_table[] = { 2170static struct platform_device_id fsi_id_table[] = {
2252 { "sh_fsi", (kernel_ulong_t)&fsi1_core }, 2171 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
2253 { "sh_fsi2", (kernel_ulong_t)&fsi2_core }, 2172 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
@@ -2259,6 +2178,7 @@ static struct platform_driver fsi_driver = {
2259 .driver = { 2178 .driver = {
2260 .name = "fsi-pcm-audio", 2179 .name = "fsi-pcm-audio",
2261 .pm = &fsi_pm_ops, 2180 .pm = &fsi_pm_ops,
2181 .of_match_table = fsi_of_match,
2262 }, 2182 },
2263 .probe = fsi_probe, 2183 .probe = fsi_probe,
2264 .remove = fsi_remove, 2184 .remove = fsi_remove,
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 5fbfb06e8083..b5b3db71e253 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -33,6 +33,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
33 struct snd_soc_dai *codec_dai = rtd->codec_dai; 33 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 int ret = 0; 34 int ret = 0;
35 35
36 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
37
36 if (platform->driver->compr_ops && platform->driver->compr_ops->open) { 38 if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
37 ret = platform->driver->compr_ops->open(cstream); 39 ret = platform->driver->compr_ops->open(cstream);
38 if (ret < 0) { 40 if (ret < 0) {
@@ -61,15 +63,46 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
61 codec_dai->active++; 63 codec_dai->active++;
62 rtd->codec->active++; 64 rtd->codec->active++;
63 65
66 mutex_unlock(&rtd->pcm_mutex);
67
64 return 0; 68 return 0;
65 69
66machine_err: 70machine_err:
67 if (platform->driver->compr_ops && platform->driver->compr_ops->free) 71 if (platform->driver->compr_ops && platform->driver->compr_ops->free)
68 platform->driver->compr_ops->free(cstream); 72 platform->driver->compr_ops->free(cstream);
69out: 73out:
74 mutex_unlock(&rtd->pcm_mutex);
70 return ret; 75 return ret;
71} 76}
72 77
78/*
79 * Power down the audio subsystem pmdown_time msecs after close is called.
80 * This is to ensure there are no pops or clicks in between any music tracks
81 * due to DAPM power cycling.
82 */
83static void close_delayed_work(struct work_struct *work)
84{
85 struct snd_soc_pcm_runtime *rtd =
86 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
87 struct snd_soc_dai *codec_dai = rtd->codec_dai;
88
89 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
90
91 dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
92 codec_dai->driver->playback.stream_name,
93 codec_dai->playback_active ? "active" : "inactive",
94 rtd->pop_wait ? "yes" : "no");
95
96 /* are we waiting on this codec DAI stream */
97 if (rtd->pop_wait == 1) {
98 rtd->pop_wait = 0;
99 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
100 SND_SOC_DAPM_STREAM_STOP);
101 }
102
103 mutex_unlock(&rtd->pcm_mutex);
104}
105
73static int soc_compr_free(struct snd_compr_stream *cstream) 106static int soc_compr_free(struct snd_compr_stream *cstream)
74{ 107{
75 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 108 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
@@ -78,6 +111,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
78 struct snd_soc_dai *codec_dai = rtd->codec_dai; 111 struct snd_soc_dai *codec_dai = rtd->codec_dai;
79 struct snd_soc_codec *codec = rtd->codec; 112 struct snd_soc_codec *codec = rtd->codec;
80 113
114 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
115
81 if (cstream->direction == SND_COMPRESS_PLAYBACK) { 116 if (cstream->direction == SND_COMPRESS_PLAYBACK) {
82 cpu_dai->playback_active--; 117 cpu_dai->playback_active--;
83 codec_dai->playback_active--; 118 codec_dai->playback_active--;
@@ -86,7 +121,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
86 codec_dai->capture_active--; 121 codec_dai->capture_active--;
87 } 122 }
88 123
89 snd_soc_dai_digital_mute(codec_dai, 1); 124 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
90 125
91 cpu_dai->active--; 126 cpu_dai->active--;
92 codec_dai->active--; 127 codec_dai->active--;
@@ -112,10 +147,11 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
112 snd_soc_dapm_stream_event(rtd, 147 snd_soc_dapm_stream_event(rtd,
113 SNDRV_PCM_STREAM_PLAYBACK, 148 SNDRV_PCM_STREAM_PLAYBACK,
114 SND_SOC_DAPM_STREAM_STOP); 149 SND_SOC_DAPM_STREAM_STOP);
115 } else 150 } else {
116 rtd->pop_wait = 1; 151 rtd->pop_wait = 1;
117 schedule_delayed_work(&rtd->delayed_work, 152 schedule_delayed_work(&rtd->delayed_work,
118 msecs_to_jiffies(rtd->pmdown_time)); 153 msecs_to_jiffies(rtd->pmdown_time));
154 }
119 } else { 155 } else {
120 /* capture streams can be powered down now */ 156 /* capture streams can be powered down now */
121 snd_soc_dapm_stream_event(rtd, 157 snd_soc_dapm_stream_event(rtd,
@@ -123,6 +159,7 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
123 SND_SOC_DAPM_STREAM_STOP); 159 SND_SOC_DAPM_STREAM_STOP);
124 } 160 }
125 161
162 mutex_unlock(&rtd->pcm_mutex);
126 return 0; 163 return 0;
127} 164}
128 165
@@ -134,17 +171,25 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
134 struct snd_soc_dai *codec_dai = rtd->codec_dai; 171 struct snd_soc_dai *codec_dai = rtd->codec_dai;
135 int ret = 0; 172 int ret = 0;
136 173
174 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
175
137 if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) { 176 if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
138 ret = platform->driver->compr_ops->trigger(cstream, cmd); 177 ret = platform->driver->compr_ops->trigger(cstream, cmd);
139 if (ret < 0) 178 if (ret < 0)
140 return ret; 179 goto out;
141 } 180 }
142 181
143 if (cmd == SNDRV_PCM_TRIGGER_START) 182 switch (cmd) {
144 snd_soc_dai_digital_mute(codec_dai, 0); 183 case SNDRV_PCM_TRIGGER_START:
145 else if (cmd == SNDRV_PCM_TRIGGER_STOP) 184 snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
146 snd_soc_dai_digital_mute(codec_dai, 1); 185 break;
186 case SNDRV_PCM_TRIGGER_STOP:
187 snd_soc_dai_digital_mute(codec_dai, 1, cstream->direction);
188 break;
189 }
147 190
191out:
192 mutex_unlock(&rtd->pcm_mutex);
148 return ret; 193 return ret;
149} 194}
150 195
@@ -155,6 +200,8 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
155 struct snd_soc_platform *platform = rtd->platform; 200 struct snd_soc_platform *platform = rtd->platform;
156 int ret = 0; 201 int ret = 0;
157 202
203 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
204
158 /* first we call set_params for the platform driver 205 /* first we call set_params for the platform driver
159 * this should configure the soc side 206 * this should configure the soc side
160 * if the machine has compressed ops then we call that as well 207 * if the machine has compressed ops then we call that as well
@@ -164,18 +211,20 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
164 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { 211 if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
165 ret = platform->driver->compr_ops->set_params(cstream, params); 212 ret = platform->driver->compr_ops->set_params(cstream, params);
166 if (ret < 0) 213 if (ret < 0)
167 return ret; 214 goto out;
168 } 215 }
169 216
170 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) { 217 if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
171 ret = rtd->dai_link->compr_ops->set_params(cstream); 218 ret = rtd->dai_link->compr_ops->set_params(cstream);
172 if (ret < 0) 219 if (ret < 0)
173 return ret; 220 goto out;
174 } 221 }
175 222
176 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 223 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
177 SND_SOC_DAPM_STREAM_START); 224 SND_SOC_DAPM_STREAM_START);
178 225
226out:
227 mutex_unlock(&rtd->pcm_mutex);
179 return ret; 228 return ret;
180} 229}
181 230
@@ -186,9 +235,12 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
186 struct snd_soc_platform *platform = rtd->platform; 235 struct snd_soc_platform *platform = rtd->platform;
187 int ret = 0; 236 int ret = 0;
188 237
238 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
239
189 if (platform->driver->compr_ops && platform->driver->compr_ops->get_params) 240 if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
190 ret = platform->driver->compr_ops->get_params(cstream, params); 241 ret = platform->driver->compr_ops->get_params(cstream, params);
191 242
243 mutex_unlock(&rtd->pcm_mutex);
192 return ret; 244 return ret;
193} 245}
194 246
@@ -199,9 +251,12 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
199 struct snd_soc_platform *platform = rtd->platform; 251 struct snd_soc_platform *platform = rtd->platform;
200 int ret = 0; 252 int ret = 0;
201 253
254 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
255
202 if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps) 256 if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
203 ret = platform->driver->compr_ops->get_caps(cstream, caps); 257 ret = platform->driver->compr_ops->get_caps(cstream, caps);
204 258
259 mutex_unlock(&rtd->pcm_mutex);
205 return ret; 260 return ret;
206} 261}
207 262
@@ -212,9 +267,12 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
212 struct snd_soc_platform *platform = rtd->platform; 267 struct snd_soc_platform *platform = rtd->platform;
213 int ret = 0; 268 int ret = 0;
214 269
270 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
271
215 if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) 272 if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
216 ret = platform->driver->compr_ops->get_codec_caps(cstream, codec); 273 ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
217 274
275 mutex_unlock(&rtd->pcm_mutex);
218 return ret; 276 return ret;
219} 277}
220 278
@@ -224,9 +282,12 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
224 struct snd_soc_platform *platform = rtd->platform; 282 struct snd_soc_platform *platform = rtd->platform;
225 int ret = 0; 283 int ret = 0;
226 284
285 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
286
227 if (platform->driver->compr_ops && platform->driver->compr_ops->ack) 287 if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
228 ret = platform->driver->compr_ops->ack(cstream, bytes); 288 ret = platform->driver->compr_ops->ack(cstream, bytes);
229 289
290 mutex_unlock(&rtd->pcm_mutex);
230 return ret; 291 return ret;
231} 292}
232 293
@@ -236,12 +297,31 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
236 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 297 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
237 struct snd_soc_platform *platform = rtd->platform; 298 struct snd_soc_platform *platform = rtd->platform;
238 299
300 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
301
239 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer) 302 if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
240 platform->driver->compr_ops->pointer(cstream, tstamp); 303 platform->driver->compr_ops->pointer(cstream, tstamp);
241 304
305 mutex_unlock(&rtd->pcm_mutex);
242 return 0; 306 return 0;
243} 307}
244 308
309static int soc_compr_copy(struct snd_compr_stream *cstream,
310 const char __user *buf, size_t count)
311{
312 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
313 struct snd_soc_platform *platform = rtd->platform;
314 int ret = 0;
315
316 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
317
318 if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
319 ret = platform->driver->compr_ops->copy(cstream, buf, count);
320
321 mutex_unlock(&rtd->pcm_mutex);
322 return ret;
323}
324
245/* ASoC Compress operations */ 325/* ASoC Compress operations */
246static struct snd_compr_ops soc_compr_ops = { 326static struct snd_compr_ops soc_compr_ops = {
247 .open = soc_compr_open, 327 .open = soc_compr_open,
@@ -259,6 +339,7 @@ static struct snd_compr_ops soc_compr_ops = {
259int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 339int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
260{ 340{
261 struct snd_soc_codec *codec = rtd->codec; 341 struct snd_soc_codec *codec = rtd->codec;
342 struct snd_soc_platform *platform = rtd->platform;
262 struct snd_soc_dai *codec_dai = rtd->codec_dai; 343 struct snd_soc_dai *codec_dai = rtd->codec_dai;
263 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 344 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
264 struct snd_compr *compr; 345 struct snd_compr *compr;
@@ -275,20 +356,38 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
275 return -ENOMEM; 356 return -ENOMEM;
276 } 357 }
277 358
278 compr->ops = &soc_compr_ops; 359 compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
360 GFP_KERNEL);
361 if (compr->ops == NULL) {
362 dev_err(rtd->card->dev, "Cannot allocate compressed ops\n");
363 ret = -ENOMEM;
364 goto compr_err;
365 }
366 memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
367
368 /* Add copy callback for not memory mapped DSPs */
369 if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
370 compr->ops->copy = soc_compr_copy;
371
279 mutex_init(&compr->lock); 372 mutex_init(&compr->lock);
280 ret = snd_compress_new(rtd->card->snd_card, num, direction, compr); 373 ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
281 if (ret < 0) { 374 if (ret < 0) {
282 pr_err("compress asoc: can't create compress for codec %s\n", 375 pr_err("compress asoc: can't create compress for codec %s\n",
283 codec->name); 376 codec->name);
284 kfree(compr); 377 goto compr_err;
285 return ret;
286 } 378 }
287 379
380 /* DAPM dai link stream work */
381 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
382
288 rtd->compr = compr; 383 rtd->compr = compr;
289 compr->private_data = rtd; 384 compr->private_data = rtd;
290 385
291 printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name, 386 printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
292 cpu_dai->name); 387 cpu_dai->name);
293 return ret; 388 return ret;
389
390compr_err:
391 kfree(compr);
392 return ret;
294} 393}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4c6526c0db03..b7e84a7cd9ee 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1107,6 +1107,10 @@ static int soc_probe_codec(struct snd_soc_card *card,
1107 "ASoC: failed to probe CODEC %d\n", ret); 1107 "ASoC: failed to probe CODEC %d\n", ret);
1108 goto err_probe; 1108 goto err_probe;
1109 } 1109 }
1110 WARN(codec->dapm.idle_bias_off &&
1111 codec->dapm.bias_level != SND_SOC_BIAS_OFF,
1112 "codec %s can not start from non-off bias"
1113 " with idle_bias_off==1\n", codec->name);
1110 } 1114 }
1111 1115
1112 /* If the driver didn't set I/O up try regmap */ 1116 /* If the driver didn't set I/O up try regmap */
@@ -3122,9 +3126,12 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3122 if (!codec->using_regmap) 3126 if (!codec->using_regmap)
3123 return -EINVAL; 3127 return -EINVAL;
3124 3128
3125 data = ucontrol->value.bytes.data;
3126 len = params->num_regs * codec->val_bytes; 3129 len = params->num_regs * codec->val_bytes;
3127 3130
3131 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA);
3132 if (!data)
3133 return -ENOMEM;
3134
3128 /* 3135 /*
3129 * If we've got a mask then we need to preserve the register 3136 * If we've got a mask then we need to preserve the register
3130 * bits. We shouldn't modify the incoming data so take a 3137 * bits. We shouldn't modify the incoming data so take a
@@ -3137,10 +3144,6 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3137 3144
3138 val &= params->mask; 3145 val &= params->mask;
3139 3146
3140 data = kmemdup(data, len, GFP_KERNEL);
3141 if (!data)
3142 return -ENOMEM;
3143
3144 switch (codec->val_bytes) { 3147 switch (codec->val_bytes) {
3145 case 1: 3148 case 1:
3146 ((u8 *)data)[0] &= ~params->mask; 3149 ((u8 *)data)[0] &= ~params->mask;
@@ -3162,8 +3165,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
3162 ret = regmap_raw_write(codec->control_data, params->base, 3165 ret = regmap_raw_write(codec->control_data, params->base,
3163 data, len); 3166 data, len);
3164 3167
3165 if (params->mask) 3168 kfree(data);
3166 kfree(data);
3167 3169
3168 return ret; 3170 return ret;
3169} 3171}
@@ -3540,12 +3542,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
3540 * snd_soc_dai_digital_mute - configure DAI system or master clock. 3542 * snd_soc_dai_digital_mute - configure DAI system or master clock.
3541 * @dai: DAI 3543 * @dai: DAI
3542 * @mute: mute enable 3544 * @mute: mute enable
3545 * @direction: stream to mute
3543 * 3546 *
3544 * Mutes the DAI DAC. 3547 * Mutes the DAI DAC.
3545 */ 3548 */
3546int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 3549int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
3550 int direction)
3547{ 3551{
3548 if (dai->driver && dai->driver->ops->digital_mute) 3552 if (!dai->driver)
3553 return -ENOTSUPP;
3554
3555 if (dai->driver->ops->mute_stream)
3556 return dai->driver->ops->mute_stream(dai, mute, direction);
3557 else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
3558 dai->driver->ops->digital_mute)
3549 return dai->driver->ops->digital_mute(dai, mute); 3559 return dai->driver->ops->digital_mute(dai, mute);
3550 else 3560 else
3551 return -ENOTSUPP; 3561 return -ENOTSUPP;
@@ -4208,6 +4218,113 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4208} 4218}
4209EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); 4219EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
4210 4220
4221unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
4222 const char *prefix)
4223{
4224 int ret, i;
4225 char prop[128];
4226 unsigned int format = 0;
4227 int bit, frame;
4228 const char *str;
4229 struct {
4230 char *name;
4231 unsigned int val;
4232 } of_fmt_table[] = {
4233 { "i2s", SND_SOC_DAIFMT_I2S },
4234 { "right_j", SND_SOC_DAIFMT_RIGHT_J },
4235 { "left_j", SND_SOC_DAIFMT_LEFT_J },
4236 { "dsp_a", SND_SOC_DAIFMT_DSP_A },
4237 { "dsp_b", SND_SOC_DAIFMT_DSP_B },
4238 { "ac97", SND_SOC_DAIFMT_AC97 },
4239 { "pdm", SND_SOC_DAIFMT_PDM},
4240 { "msb", SND_SOC_DAIFMT_MSB },
4241 { "lsb", SND_SOC_DAIFMT_LSB },
4242 };
4243
4244 if (!prefix)
4245 prefix = "";
4246
4247 /*
4248 * check "[prefix]format = xxx"
4249 * SND_SOC_DAIFMT_FORMAT_MASK area
4250 */
4251 snprintf(prop, sizeof(prop), "%sformat", prefix);
4252 ret = of_property_read_string(np, prop, &str);
4253 if (ret == 0) {
4254 for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
4255 if (strcmp(str, of_fmt_table[i].name) == 0) {
4256 format |= of_fmt_table[i].val;
4257 break;
4258 }
4259 }
4260 }
4261
4262 /*
4263 * check "[prefix]continuous-clock"
4264 * SND_SOC_DAIFMT_CLOCK_MASK area
4265 */
4266 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);
4267 if (of_get_property(np, prop, NULL))
4268 format |= SND_SOC_DAIFMT_CONT;
4269 else
4270 format |= SND_SOC_DAIFMT_GATED;
4271
4272 /*
4273 * check "[prefix]bitclock-inversion"
4274 * check "[prefix]frame-inversion"
4275 * SND_SOC_DAIFMT_INV_MASK area
4276 */
4277 snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
4278 bit = !!of_get_property(np, prop, NULL);
4279
4280 snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
4281 frame = !!of_get_property(np, prop, NULL);
4282
4283 switch ((bit << 4) + frame) {
4284 case 0x11:
4285 format |= SND_SOC_DAIFMT_IB_IF;
4286 break;
4287 case 0x10:
4288 format |= SND_SOC_DAIFMT_IB_NF;
4289 break;
4290 case 0x01:
4291 format |= SND_SOC_DAIFMT_NB_IF;
4292 break;
4293 default:
4294 /* SND_SOC_DAIFMT_NB_NF is default */
4295 break;
4296 }
4297
4298 /*
4299 * check "[prefix]bitclock-master"
4300 * check "[prefix]frame-master"
4301 * SND_SOC_DAIFMT_MASTER_MASK area
4302 */
4303 snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
4304 bit = !!of_get_property(np, prop, NULL);
4305
4306 snprintf(prop, sizeof(prop), "%sframe-master", prefix);
4307 frame = !!of_get_property(np, prop, NULL);
4308
4309 switch ((bit << 4) + frame) {
4310 case 0x11:
4311 format |= SND_SOC_DAIFMT_CBM_CFM;
4312 break;
4313 case 0x10:
4314 format |= SND_SOC_DAIFMT_CBM_CFS;
4315 break;
4316 case 0x01:
4317 format |= SND_SOC_DAIFMT_CBS_CFM;
4318 break;
4319 default:
4320 format |= SND_SOC_DAIFMT_CBS_CFS;
4321 break;
4322 }
4323
4324 return format;
4325}
4326EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
4327
4211static int __init snd_soc_init(void) 4328static int __init snd_soc_init(void)
4212{ 4329{
4213#ifdef CONFIG_DEBUG_FS 4330#ifdef CONFIG_DEBUG_FS
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1e36bc81e5af..1d6a9b3ceb27 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1023,7 +1023,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1023 1023
1024 if (SND_SOC_DAPM_EVENT_ON(event)) { 1024 if (SND_SOC_DAPM_EVENT_ON(event)) {
1025 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { 1025 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
1026 ret = regulator_allow_bypass(w->regulator, true); 1026 ret = regulator_allow_bypass(w->regulator, false);
1027 if (ret != 0) 1027 if (ret != 0)
1028 dev_warn(w->dapm->dev, 1028 dev_warn(w->dapm->dev,
1029 "ASoC: Failed to bypass %s: %d\n", 1029 "ASoC: Failed to bypass %s: %d\n",
@@ -1033,7 +1033,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1033 return regulator_enable(w->regulator); 1033 return regulator_enable(w->regulator);
1034 } else { 1034 } else {
1035 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { 1035 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
1036 ret = regulator_allow_bypass(w->regulator, false); 1036 ret = regulator_allow_bypass(w->regulator, true);
1037 if (ret != 0) 1037 if (ret != 0)
1038 dev_warn(w->dapm->dev, 1038 dev_warn(w->dapm->dev,
1039 "ASoC: Failed to unbypass %s: %d\n", 1039 "ASoC: Failed to unbypass %s: %d\n",
@@ -3039,6 +3039,14 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3039 w->name, ret); 3039 w->name, ret);
3040 return NULL; 3040 return NULL;
3041 } 3041 }
3042
3043 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
3044 ret = regulator_allow_bypass(w->regulator, true);
3045 if (ret != 0)
3046 dev_warn(w->dapm->dev,
3047 "ASoC: Failed to unbypass %s: %d\n",
3048 w->name, ret);
3049 }
3042 break; 3050 break;
3043 case snd_soc_dapm_clock_supply: 3051 case snd_soc_dapm_clock_supply:
3044#ifdef CONFIG_CLKDEV_LOOKUP 3052#ifdef CONFIG_CLKDEV_LOOKUP
@@ -3247,14 +3255,16 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3247 break; 3255 break;
3248 3256
3249 case SND_SOC_DAPM_POST_PMU: 3257 case SND_SOC_DAPM_POST_PMU:
3250 ret = snd_soc_dai_digital_mute(sink, 0); 3258 ret = snd_soc_dai_digital_mute(sink, 0,
3259 SNDRV_PCM_STREAM_PLAYBACK);
3251 if (ret != 0 && ret != -ENOTSUPP) 3260 if (ret != 0 && ret != -ENOTSUPP)
3252 dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret); 3261 dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret);
3253 ret = 0; 3262 ret = 0;
3254 break; 3263 break;
3255 3264
3256 case SND_SOC_DAPM_PRE_PMD: 3265 case SND_SOC_DAPM_PRE_PMD:
3257 ret = snd_soc_dai_digital_mute(sink, 1); 3266 ret = snd_soc_dai_digital_mute(sink, 1,
3267 SNDRV_PCM_STREAM_PLAYBACK);
3258 if (ret != 0 && ret != -ENOTSUPP) 3268 if (ret != 0 && ret != -ENOTSUPP)
3259 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); 3269 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
3260 ret = 0; 3270 ret = 0;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index cf191e6aebbe..73bb8eefa491 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -383,8 +383,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
383 /* Muting the DAC suppresses artifacts caused during digital 383 /* Muting the DAC suppresses artifacts caused during digital
384 * shutdown, for example from stopping clocks. 384 * shutdown, for example from stopping clocks.
385 */ 385 */
386 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 386 snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
387 snd_soc_dai_digital_mute(codec_dai, 1);
388 387
389 if (cpu_dai->driver->ops->shutdown) 388 if (cpu_dai->driver->ops->shutdown)
390 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 389 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
@@ -488,7 +487,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
488 snd_soc_dapm_stream_event(rtd, substream->stream, 487 snd_soc_dapm_stream_event(rtd, substream->stream,
489 SND_SOC_DAPM_STREAM_START); 488 SND_SOC_DAPM_STREAM_START);
490 489
491 snd_soc_dai_digital_mute(codec_dai, 0); 490 snd_soc_dai_digital_mute(codec_dai, 0, substream->stream);
492 491
493out: 492out:
494 mutex_unlock(&rtd->pcm_mutex); 493 mutex_unlock(&rtd->pcm_mutex);
@@ -586,7 +585,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
586 585
587 /* apply codec digital mute */ 586 /* apply codec digital mute */
588 if (!codec->active) 587 if (!codec->active)
589 snd_soc_dai_digital_mute(codec_dai, 1); 588 snd_soc_dai_digital_mute(codec_dai, 1, substream->stream);
590 589
591 /* free any machine hw params */ 590 /* free any machine hw params */
592 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 591 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
@@ -1729,20 +1728,16 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
1729 1728
1730 /* startup must always be called for new BEs */ 1729 /* startup must always be called for new BEs */
1731 ret = dpcm_be_dai_startup(fe, stream); 1730 ret = dpcm_be_dai_startup(fe, stream);
1732 if (ret < 0) { 1731 if (ret < 0)
1733 goto disconnect; 1732 goto disconnect;
1734 return ret;
1735 }
1736 1733
1737 /* keep going if FE state is > open */ 1734 /* keep going if FE state is > open */
1738 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_OPEN) 1735 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_OPEN)
1739 return 0; 1736 return 0;
1740 1737
1741 ret = dpcm_be_dai_hw_params(fe, stream); 1738 ret = dpcm_be_dai_hw_params(fe, stream);
1742 if (ret < 0) { 1739 if (ret < 0)
1743 goto close; 1740 goto close;
1744 return ret;
1745 }
1746 1741
1747 /* keep going if FE state is > hw_params */ 1742 /* keep going if FE state is > hw_params */
1748 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_PARAMS) 1743 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_PARAMS)
@@ -1750,10 +1745,8 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
1750 1745
1751 1746
1752 ret = dpcm_be_dai_prepare(fe, stream); 1747 ret = dpcm_be_dai_prepare(fe, stream);
1753 if (ret < 0) { 1748 if (ret < 0)
1754 goto hw_free; 1749 goto hw_free;
1755 return ret;
1756 }
1757 1750
1758 /* run the stream event for each BE */ 1751 /* run the stream event for each BE */
1759 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP); 1752 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 19e5fe7cc403..dbc27ce1d4de 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -6,6 +6,16 @@ config SND_SOC_TEGRA
6 help 6 help
7 Say Y or M here if you want support for SoC audio on Tegra. 7 Say Y or M here if you want support for SoC audio on Tegra.
8 8
9config SND_SOC_TEGRA20_AC97
10 tristate
11 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
12 select SND_SOC_AC97_BUS
13 select SND_SOC_TEGRA20_DAS
14 help
15 Say Y or M if you want to add support for codecs attached to the
16 Tegra20 AC97 interface. You will also need to select the individual
17 machine drivers to support below.
18
9config SND_SOC_TEGRA20_DAS 19config SND_SOC_TEGRA20_DAS
10 tristate 20 tristate
11 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC 21 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
@@ -70,6 +80,15 @@ config SND_SOC_TEGRA_WM8903
70 boards using the WM8093 codec. Currently, the supported boards are 80 boards using the WM8093 codec. Currently, the supported boards are
71 Harmony, Ventana, Seaboard, Kaen, and Aebl. 81 Harmony, Ventana, Seaboard, Kaen, and Aebl.
72 82
83config SND_SOC_TEGRA_WM9712
84 tristate "SoC Audio support for Tegra boards using a WM9712 codec"
85 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
86 select SND_SOC_TEGRA20_AC97
87 select SND_SOC_WM9712
88 help
89 Say Y or M here if you want to add support for SoC audio on Tegra
90 boards using the WM9712 (or compatible) codec.
91
73config SND_SOC_TEGRA_TRIMSLICE 92config SND_SOC_TEGRA_TRIMSLICE
74 tristate "SoC Audio support for TrimSlice board" 93 tristate "SoC Audio support for TrimSlice board"
75 depends on SND_SOC_TEGRA && I2C 94 depends on SND_SOC_TEGRA && I2C
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 391e78a34c06..416a14bde41b 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,6 +1,7 @@
1# Tegra platform Support 1# Tegra platform Support
2snd-soc-tegra-pcm-objs := tegra_pcm.o 2snd-soc-tegra-pcm-objs := tegra_pcm.o
3snd-soc-tegra-utils-objs += tegra_asoc_utils.o 3snd-soc-tegra-utils-objs += tegra_asoc_utils.o
4snd-soc-tegra20-ac97-objs := tegra20_ac97.o
4snd-soc-tegra20-das-objs := tegra20_das.o 5snd-soc-tegra20-das-objs := tegra20_das.o
5snd-soc-tegra20-i2s-objs := tegra20_i2s.o 6snd-soc-tegra20-i2s-objs := tegra20_i2s.o
6snd-soc-tegra20-spdif-objs := tegra20_spdif.o 7snd-soc-tegra20-spdif-objs := tegra20_spdif.o
@@ -9,6 +10,7 @@ snd-soc-tegra30-i2s-objs := tegra30_i2s.o
9 10
10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o 11obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
11obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o 12obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
13obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
12obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o 14obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o
13obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o 15obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o
14obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o 16obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o
@@ -18,10 +20,12 @@ obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
18# Tegra machine Support 20# Tegra machine Support
19snd-soc-tegra-wm8753-objs := tegra_wm8753.o 21snd-soc-tegra-wm8753-objs := tegra_wm8753.o
20snd-soc-tegra-wm8903-objs := tegra_wm8903.o 22snd-soc-tegra-wm8903-objs := tegra_wm8903.o
23snd-soc-tegra-wm9712-objs := tegra_wm9712.o
21snd-soc-tegra-trimslice-objs := trimslice.o 24snd-soc-tegra-trimslice-objs := trimslice.o
22snd-soc-tegra-alc5632-objs := tegra_alc5632.o 25snd-soc-tegra-alc5632-objs := tegra_alc5632.o
23 26
24obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o 27obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
25obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o 28obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
29obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o
26obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o 30obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
27obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o 31obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
new file mode 100644
index 000000000000..336dcdd3e8a4
--- /dev/null
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -0,0 +1,480 @@
1/*
2 * tegra20_ac97.c - Tegra20 AC97 platform driver
3 *
4 * Copyright (c) 2012 Lucas Stach <dev@lynxeye.de>
5 *
6 * Partly based on code copyright/by:
7 *
8 * Copyright (c) 2011,2012 Toradex Inc.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
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#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/gpio.h>
25#include <linux/io.h>
26#include <linux/jiffies.h>
27#include <linux/module.h>
28#include <linux/of.h>
29#include <linux/of_gpio.h>
30#include <linux/platform_device.h>
31#include <linux/pm_runtime.h>
32#include <linux/regmap.h>
33#include <linux/slab.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/soc.h>
38
39#include "tegra_asoc_utils.h"
40#include "tegra20_ac97.h"
41
42#define DRV_NAME "tegra20-ac97"
43
44static struct tegra20_ac97 *workdata;
45
46static void tegra20_ac97_codec_reset(struct snd_ac97 *ac97)
47{
48 u32 readback;
49 unsigned long timeout;
50
51 /* reset line is not driven by DAC pad group, have to toggle GPIO */
52 gpio_set_value(workdata->reset_gpio, 0);
53 udelay(2);
54
55 gpio_set_value(workdata->reset_gpio, 1);
56 udelay(2);
57
58 timeout = jiffies + msecs_to_jiffies(100);
59
60 do {
61 regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
62 if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
63 break;
64 usleep_range(1000, 2000);
65 } while (!time_after(jiffies, timeout));
66}
67
68static void tegra20_ac97_codec_warm_reset(struct snd_ac97 *ac97)
69{
70 u32 readback;
71 unsigned long timeout;
72
73 /*
74 * although sync line is driven by the DAC pad group warm reset using
75 * the controller cmd is not working, have to toggle sync line
76 * manually.
77 */
78 gpio_request(workdata->sync_gpio, "codec-sync");
79
80 gpio_direction_output(workdata->sync_gpio, 1);
81
82 udelay(2);
83 gpio_set_value(workdata->sync_gpio, 0);
84 udelay(2);
85 gpio_free(workdata->sync_gpio);
86
87 timeout = jiffies + msecs_to_jiffies(100);
88
89 do {
90 regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
91 if (readback & TEGRA20_AC97_STATUS1_CODEC1_RDY)
92 break;
93 usleep_range(1000, 2000);
94 } while (!time_after(jiffies, timeout));
95}
96
97static unsigned short tegra20_ac97_codec_read(struct snd_ac97 *ac97_snd,
98 unsigned short reg)
99{
100 u32 readback;
101 unsigned long timeout;
102
103 regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
104 (((reg | 0x80) << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
105 TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
106 TEGRA20_AC97_CMD_BUSY);
107
108 timeout = jiffies + msecs_to_jiffies(100);
109
110 do {
111 regmap_read(workdata->regmap, TEGRA20_AC97_STATUS1, &readback);
112 if (readback & TEGRA20_AC97_STATUS1_STA_VALID1)
113 break;
114 usleep_range(1000, 2000);
115 } while (!time_after(jiffies, timeout));
116
117 return ((readback & TEGRA20_AC97_STATUS1_STA_DATA1_MASK) >>
118 TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT);
119}
120
121static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,
122 unsigned short reg, unsigned short val)
123{
124 u32 readback;
125 unsigned long timeout;
126
127 regmap_write(workdata->regmap, TEGRA20_AC97_CMD,
128 ((reg << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT) &
129 TEGRA20_AC97_CMD_CMD_ADDR_MASK) |
130 ((val << TEGRA20_AC97_CMD_CMD_DATA_SHIFT) &
131 TEGRA20_AC97_CMD_CMD_DATA_MASK) |
132 TEGRA20_AC97_CMD_BUSY);
133
134 timeout = jiffies + msecs_to_jiffies(100);
135
136 do {
137 regmap_read(workdata->regmap, TEGRA20_AC97_CMD, &readback);
138 if (!(readback & TEGRA20_AC97_CMD_BUSY))
139 break;
140 usleep_range(1000, 2000);
141 } while (!time_after(jiffies, timeout));
142}
143
144struct snd_ac97_bus_ops soc_ac97_ops = {
145 .read = tegra20_ac97_codec_read,
146 .write = tegra20_ac97_codec_write,
147 .reset = tegra20_ac97_codec_reset,
148 .warm_reset = tegra20_ac97_codec_warm_reset,
149};
150EXPORT_SYMBOL_GPL(soc_ac97_ops);
151
152static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
153{
154 regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
155 TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN,
156 TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN);
157
158 regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
159 TEGRA20_AC97_CTRL_PCM_DAC_EN |
160 TEGRA20_AC97_CTRL_STM_EN,
161 TEGRA20_AC97_CTRL_PCM_DAC_EN |
162 TEGRA20_AC97_CTRL_STM_EN);
163}
164
165static inline void tegra20_ac97_stop_playback(struct tegra20_ac97 *ac97)
166{
167 regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
168 TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN, 0);
169
170 regmap_update_bits(ac97->regmap, TEGRA20_AC97_CTRL,
171 TEGRA20_AC97_CTRL_PCM_DAC_EN, 0);
172}
173
174static inline void tegra20_ac97_start_capture(struct tegra20_ac97 *ac97)
175{
176 regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
177 TEGRA20_AC97_FIFO_SCR_REC_FULL_EN,
178 TEGRA20_AC97_FIFO_SCR_REC_FULL_EN);
179}
180
181static inline void tegra20_ac97_stop_capture(struct tegra20_ac97 *ac97)
182{
183 regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR,
184 TEGRA20_AC97_FIFO_SCR_REC_FULL_EN, 0);
185}
186
187static int tegra20_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
188 struct snd_soc_dai *dai)
189{
190 struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);
191
192 switch (cmd) {
193 case SNDRV_PCM_TRIGGER_START:
194 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
195 case SNDRV_PCM_TRIGGER_RESUME:
196 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
197 tegra20_ac97_start_playback(ac97);
198 else
199 tegra20_ac97_start_capture(ac97);
200 break;
201 case SNDRV_PCM_TRIGGER_STOP:
202 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
203 case SNDRV_PCM_TRIGGER_SUSPEND:
204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
205 tegra20_ac97_stop_playback(ac97);
206 else
207 tegra20_ac97_stop_capture(ac97);
208 break;
209 default:
210 return -EINVAL;
211 }
212
213 return 0;
214}
215
216static const struct snd_soc_dai_ops tegra20_ac97_dai_ops = {
217 .trigger = tegra20_ac97_trigger,
218};
219
220static int tegra20_ac97_probe(struct snd_soc_dai *dai)
221{
222 struct tegra20_ac97 *ac97 = snd_soc_dai_get_drvdata(dai);
223
224 dai->capture_dma_data = &ac97->capture_dma_data;
225 dai->playback_dma_data = &ac97->playback_dma_data;
226
227 return 0;
228}
229
230static struct snd_soc_dai_driver tegra20_ac97_dai = {
231 .name = "tegra-ac97-pcm",
232 .ac97_control = 1,
233 .probe = tegra20_ac97_probe,
234 .playback = {
235 .stream_name = "PCM Playback",
236 .channels_min = 2,
237 .channels_max = 2,
238 .rates = SNDRV_PCM_RATE_8000_48000,
239 .formats = SNDRV_PCM_FMTBIT_S16_LE,
240 },
241 .capture = {
242 .stream_name = "PCM Capture",
243 .channels_min = 2,
244 .channels_max = 2,
245 .rates = SNDRV_PCM_RATE_8000_48000,
246 .formats = SNDRV_PCM_FMTBIT_S16_LE,
247 },
248 .ops = &tegra20_ac97_dai_ops,
249};
250
251static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg)
252{
253 switch (reg) {
254 case TEGRA20_AC97_CTRL:
255 case TEGRA20_AC97_CMD:
256 case TEGRA20_AC97_STATUS1:
257 case TEGRA20_AC97_FIFO1_SCR:
258 case TEGRA20_AC97_FIFO_TX1:
259 case TEGRA20_AC97_FIFO_RX1:
260 return true;
261 default:
262 break;
263 }
264
265 return false;
266}
267
268static bool tegra20_ac97_volatile_reg(struct device *dev, unsigned int reg)
269{
270 switch (reg) {
271 case TEGRA20_AC97_STATUS1:
272 case TEGRA20_AC97_FIFO1_SCR:
273 case TEGRA20_AC97_FIFO_TX1:
274 case TEGRA20_AC97_FIFO_RX1:
275 return true;
276 default:
277 break;
278 }
279
280 return false;
281}
282
283static bool tegra20_ac97_precious_reg(struct device *dev, unsigned int reg)
284{
285 switch (reg) {
286 case TEGRA20_AC97_FIFO_TX1:
287 case TEGRA20_AC97_FIFO_RX1:
288 return true;
289 default:
290 break;
291 }
292
293 return false;
294}
295
296static const struct regmap_config tegra20_ac97_regmap_config = {
297 .reg_bits = 32,
298 .reg_stride = 4,
299 .val_bits = 32,
300 .max_register = TEGRA20_AC97_FIFO_RX1,
301 .writeable_reg = tegra20_ac97_wr_rd_reg,
302 .readable_reg = tegra20_ac97_wr_rd_reg,
303 .volatile_reg = tegra20_ac97_volatile_reg,
304 .precious_reg = tegra20_ac97_precious_reg,
305 .cache_type = REGCACHE_RBTREE,
306};
307
308static int tegra20_ac97_platform_probe(struct platform_device *pdev)
309{
310 struct tegra20_ac97 *ac97;
311 struct resource *mem, *memregion;
312 u32 of_dma[2];
313 void __iomem *regs;
314 int ret = 0;
315
316 ac97 = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_ac97),
317 GFP_KERNEL);
318 if (!ac97) {
319 dev_err(&pdev->dev, "Can't allocate tegra20_ac97\n");
320 ret = -ENOMEM;
321 goto err;
322 }
323 dev_set_drvdata(&pdev->dev, ac97);
324
325 ac97->clk_ac97 = clk_get(&pdev->dev, NULL);
326 if (IS_ERR(ac97->clk_ac97)) {
327 dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");
328 ret = PTR_ERR(ac97->clk_ac97);
329 goto err;
330 }
331
332 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
333 if (!mem) {
334 dev_err(&pdev->dev, "No memory resource\n");
335 ret = -ENODEV;
336 goto err_clk_put;
337 }
338
339 memregion = devm_request_mem_region(&pdev->dev, mem->start,
340 resource_size(mem), DRV_NAME);
341 if (!memregion) {
342 dev_err(&pdev->dev, "Memory region already claimed\n");
343 ret = -EBUSY;
344 goto err_clk_put;
345 }
346
347 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
348 if (!regs) {
349 dev_err(&pdev->dev, "ioremap failed\n");
350 ret = -ENOMEM;
351 goto err_clk_put;
352 }
353
354 ac97->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
355 &tegra20_ac97_regmap_config);
356 if (IS_ERR(ac97->regmap)) {
357 dev_err(&pdev->dev, "regmap init failed\n");
358 ret = PTR_ERR(ac97->regmap);
359 goto err_clk_put;
360 }
361
362 if (of_property_read_u32_array(pdev->dev.of_node,
363 "nvidia,dma-request-selector",
364 of_dma, 2) < 0) {
365 dev_err(&pdev->dev, "No DMA resource\n");
366 ret = -ENODEV;
367 goto err_clk_put;
368 }
369
370 ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
371 "nvidia,codec-reset-gpio", 0);
372 if (gpio_is_valid(ac97->reset_gpio)) {
373 ret = devm_gpio_request_one(&pdev->dev, ac97->reset_gpio,
374 GPIOF_OUT_INIT_HIGH, "codec-reset");
375 if (ret) {
376 dev_err(&pdev->dev, "could not get codec-reset GPIO\n");
377 goto err_clk_put;
378 }
379 } else {
380 dev_err(&pdev->dev, "no codec-reset GPIO supplied\n");
381 goto err_clk_put;
382 }
383
384 ac97->sync_gpio = of_get_named_gpio(pdev->dev.of_node,
385 "nvidia,codec-sync-gpio", 0);
386 if (!gpio_is_valid(ac97->sync_gpio)) {
387 dev_err(&pdev->dev, "no codec-sync GPIO supplied\n");
388 goto err_clk_put;
389 }
390
391 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
392 ac97->capture_dma_data.wrap = 4;
393 ac97->capture_dma_data.width = 32;
394 ac97->capture_dma_data.req_sel = of_dma[1];
395
396 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
397 ac97->playback_dma_data.wrap = 4;
398 ac97->playback_dma_data.width = 32;
399 ac97->playback_dma_data.req_sel = of_dma[1];
400
401 ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1);
402 if (ret) {
403 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
404 ret = -ENOMEM;
405 goto err_clk_put;
406 }
407
408 ret = tegra_pcm_platform_register(&pdev->dev);
409 if (ret) {
410 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
411 goto err_unregister_dai;
412 }
413
414 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
415 if (ret)
416 goto err_unregister_pcm;
417
418 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
419 if (ret)
420 goto err_asoc_utils_fini;
421
422 ret = clk_prepare_enable(ac97->clk_ac97);
423 if (ret) {
424 dev_err(&pdev->dev, "clk_enable failed: %d\n", ret);
425 goto err_asoc_utils_fini;
426 }
427
428 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
429 workdata = ac97;
430
431 return 0;
432
433err_asoc_utils_fini:
434 tegra_asoc_utils_fini(&ac97->util_data);
435err_unregister_pcm:
436 tegra_pcm_platform_unregister(&pdev->dev);
437err_unregister_dai:
438 snd_soc_unregister_dai(&pdev->dev);
439err_clk_put:
440 clk_put(ac97->clk_ac97);
441err:
442 return ret;
443}
444
445static int tegra20_ac97_platform_remove(struct platform_device *pdev)
446{
447 struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev);
448
449 tegra_pcm_platform_unregister(&pdev->dev);
450 snd_soc_unregister_dai(&pdev->dev);
451
452 tegra_asoc_utils_fini(&ac97->util_data);
453
454 clk_disable_unprepare(ac97->clk_ac97);
455 clk_put(ac97->clk_ac97);
456
457 return 0;
458}
459
460static const struct of_device_id tegra20_ac97_of_match[] = {
461 { .compatible = "nvidia,tegra20-ac97", },
462 {},
463};
464
465static struct platform_driver tegra20_ac97_driver = {
466 .driver = {
467 .name = DRV_NAME,
468 .owner = THIS_MODULE,
469 .of_match_table = tegra20_ac97_of_match,
470 },
471 .probe = tegra20_ac97_platform_probe,
472 .remove = tegra20_ac97_platform_remove,
473};
474module_platform_driver(tegra20_ac97_driver);
475
476MODULE_AUTHOR("Lucas Stach");
477MODULE_DESCRIPTION("Tegra20 AC97 ASoC driver");
478MODULE_LICENSE("GPL v2");
479MODULE_ALIAS("platform:" DRV_NAME);
480MODULE_DEVICE_TABLE(of, tegra20_ac97_of_match);
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
new file mode 100644
index 000000000000..dddc6828004e
--- /dev/null
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -0,0 +1,95 @@
1/*
2 * tegra20_ac97.h - Definitions for the Tegra20 AC97 controller driver
3 *
4 * Copyright (c) 2012 Lucas Stach <dev@lynxeye.de>
5 *
6 * Partly based on code copyright/by:
7 *
8 * Copyright (c) 2011,2012 Toradex Inc.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
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#ifndef __TEGRA20_AC97_H__
22#define __TEGRA20_AC97_H__
23
24#include "tegra_pcm.h"
25
26#define TEGRA20_AC97_CTRL 0x00
27#define TEGRA20_AC97_CMD 0x04
28#define TEGRA20_AC97_STATUS1 0x08
29/* ... */
30#define TEGRA20_AC97_FIFO1_SCR 0x1c
31/* ... */
32#define TEGRA20_AC97_FIFO_TX1 0x40
33#define TEGRA20_AC97_FIFO_RX1 0x80
34
35/* TEGRA20_AC97_CTRL */
36#define TEGRA20_AC97_CTRL_STM2_EN (1 << 16)
37#define TEGRA20_AC97_CTRL_DOUBLE_SAMPLING_EN (1 << 11)
38#define TEGRA20_AC97_CTRL_IO_CNTRL_EN (1 << 10)
39#define TEGRA20_AC97_CTRL_HSET_DAC_EN (1 << 9)
40#define TEGRA20_AC97_CTRL_LINE2_DAC_EN (1 << 8)
41#define TEGRA20_AC97_CTRL_PCM_LFE_EN (1 << 7)
42#define TEGRA20_AC97_CTRL_PCM_SUR_EN (1 << 6)
43#define TEGRA20_AC97_CTRL_PCM_CEN_DAC_EN (1 << 5)
44#define TEGRA20_AC97_CTRL_LINE1_DAC_EN (1 << 4)
45#define TEGRA20_AC97_CTRL_PCM_DAC_EN (1 << 3)
46#define TEGRA20_AC97_CTRL_COLD_RESET (1 << 2)
47#define TEGRA20_AC97_CTRL_WARM_RESET (1 << 1)
48#define TEGRA20_AC97_CTRL_STM_EN (1 << 0)
49
50/* TEGRA20_AC97_CMD */
51#define TEGRA20_AC97_CMD_CMD_ADDR_SHIFT 24
52#define TEGRA20_AC97_CMD_CMD_ADDR_MASK (0xff << TEGRA20_AC97_CMD_CMD_ADDR_SHIFT)
53#define TEGRA20_AC97_CMD_CMD_DATA_SHIFT 8
54#define TEGRA20_AC97_CMD_CMD_DATA_MASK (0xffff << TEGRA20_AC97_CMD_CMD_DATA_SHIFT)
55#define TEGRA20_AC97_CMD_CMD_ID_SHIFT 2
56#define TEGRA20_AC97_CMD_CMD_ID_MASK (0x3 << TEGRA20_AC97_CMD_CMD_ID_SHIFT)
57#define TEGRA20_AC97_CMD_BUSY (1 << 0)
58
59/* TEGRA20_AC97_STATUS1 */
60#define TEGRA20_AC97_STATUS1_STA_ADDR1_SHIFT 24
61#define TEGRA20_AC97_STATUS1_STA_ADDR1_MASK (0xff << TEGRA20_AC97_STATUS1_STA_ADDR1_SHIFT)
62#define TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT 8
63#define TEGRA20_AC97_STATUS1_STA_DATA1_MASK (0xffff << TEGRA20_AC97_STATUS1_STA_DATA1_SHIFT)
64#define TEGRA20_AC97_STATUS1_STA_VALID1 (1 << 2)
65#define TEGRA20_AC97_STATUS1_STANDBY1 (1 << 1)
66#define TEGRA20_AC97_STATUS1_CODEC1_RDY (1 << 0)
67
68/* TEGRA20_AC97_FIFO1_SCR */
69#define TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_SHIFT 27
70#define TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_MASK (0x1f << TEGRA20_AC97_FIFO_SCR_REC_MT_CNT_SHIFT)
71#define TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_SHIFT 22
72#define TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_MASK (0x1f << TEGRA20_AC97_FIFO_SCR_PB_MT_CNT_SHIFT)
73#define TEGRA20_AC97_FIFO_SCR_REC_OVERRUN_INT_STA (1 << 19)
74#define TEGRA20_AC97_FIFO_SCR_PB_UNDERRUN_INT_STA (1 << 18)
75#define TEGRA20_AC97_FIFO_SCR_REC_FORCE_MT (1 << 17)
76#define TEGRA20_AC97_FIFO_SCR_PB_FORCE_MT (1 << 16)
77#define TEGRA20_AC97_FIFO_SCR_REC_FULL_EN (1 << 15)
78#define TEGRA20_AC97_FIFO_SCR_REC_3QRT_FULL_EN (1 << 14)
79#define TEGRA20_AC97_FIFO_SCR_REC_QRT_FULL_EN (1 << 13)
80#define TEGRA20_AC97_FIFO_SCR_REC_EMPTY_EN (1 << 12)
81#define TEGRA20_AC97_FIFO_SCR_PB_NOT_FULL_EN (1 << 11)
82#define TEGRA20_AC97_FIFO_SCR_PB_QRT_MT_EN (1 << 10)
83#define TEGRA20_AC97_FIFO_SCR_PB_3QRT_MT_EN (1 << 9)
84#define TEGRA20_AC97_FIFO_SCR_PB_EMPTY_MT_EN (1 << 8)
85
86struct tegra20_ac97 {
87 struct clk *clk_ac97;
88 struct tegra_pcm_dma_params capture_dma_data;
89 struct tegra_pcm_dma_params playback_dma_data;
90 struct regmap *regmap;
91 int reset_gpio;
92 int sync_gpio;
93 struct tegra_asoc_utils_data util_data;
94};
95#endif /* __TEGRA20_AC97_H__ */
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index 654318483877..e72392927bd2 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -191,6 +191,19 @@ static int tegra20_das_probe(struct platform_device *pdev)
191 goto err; 191 goto err;
192 } 192 }
193 193
194 ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_3,
195 TEGRA20_DAS_DAP_SEL_DAC3);
196 if (ret) {
197 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
198 goto err;
199 }
200 ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_3,
201 TEGRA20_DAS_DAC_SEL_DAP3);
202 if (ret) {
203 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
204 goto err;
205 }
206
194 platform_set_drvdata(pdev, das); 207 platform_set_drvdata(pdev, das);
195 208
196 return 0; 209 return 0;
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index f354dc390a0b..e5cfb4ac41ba 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -25,7 +25,7 @@
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <mach/clk.h> 28#include <linux/clk/tegra.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include "tegra30_ahub.h" 30#include "tegra30_ahub.h"
31 31
@@ -299,15 +299,6 @@ static const char * const configlink_clocks[] = {
299 "spdif_in", 299 "spdif_in",
300}; 300};
301 301
302struct of_dev_auxdata ahub_auxdata[] = {
303 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL),
304 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL),
305 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
306 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL),
307 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL),
308 {}
309};
310
311#define LAST_REG(name) \ 302#define LAST_REG(name) \
312 (TEGRA30_AHUB_##name + \ 303 (TEGRA30_AHUB_##name + \
313 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4) 304 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4)
@@ -451,7 +442,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
451 * Ensure that here. 442 * Ensure that here.
452 */ 443 */
453 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { 444 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
454 clk = clk_get_sys(NULL, configlink_clocks[i]); 445 clk = clk_get(&pdev->dev, configlink_clocks[i]);
455 if (IS_ERR(clk)) { 446 if (IS_ERR(clk)) {
456 dev_err(&pdev->dev, "Can't get clock %s\n", 447 dev_err(&pdev->dev, "Can't get clock %s\n",
457 configlink_clocks[i]); 448 configlink_clocks[i]);
@@ -569,8 +560,7 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
569 goto err_pm_disable; 560 goto err_pm_disable;
570 } 561 }
571 562
572 of_platform_populate(pdev->dev.of_node, NULL, ahub_auxdata, 563 of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
573 &pdev->dev);
574 564
575 return 0; 565 return 0;
576 566
@@ -580,7 +570,7 @@ err_clk_put_apbif:
580 clk_put(ahub->clk_apbif); 570 clk_put(ahub->clk_apbif);
581err_clk_put_d_audio: 571err_clk_put_d_audio:
582 clk_put(ahub->clk_d_audio); 572 clk_put(ahub->clk_d_audio);
583 ahub = 0; 573 ahub = NULL;
584err: 574err:
585 return ret; 575 return ret;
586} 576}
@@ -597,7 +587,7 @@ static int tegra30_ahub_remove(struct platform_device *pdev)
597 clk_put(ahub->clk_apbif); 587 clk_put(ahub->clk_apbif);
598 clk_put(ahub->clk_d_audio); 588 clk_put(ahub->clk_d_audio);
599 589
600 ahub = 0; 590 ahub = NULL;
601 591
602 return 0; 592 return 0;
603} 593}
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 27e91dd0b91c..f4e1ce82750a 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -71,7 +71,7 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
71 return 0; 71 return 0;
72} 72}
73 73
74int tegra30_i2s_startup(struct snd_pcm_substream *substream, 74static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
75 struct snd_soc_dai *dai) 75 struct snd_soc_dai *dai)
76{ 76{
77 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 77 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
@@ -98,7 +98,7 @@ int tegra30_i2s_startup(struct snd_pcm_substream *substream,
98 return ret; 98 return ret;
99} 99}
100 100
101void tegra30_i2s_shutdown(struct snd_pcm_substream *substream, 101static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
102 struct snd_soc_dai *dai) 102 struct snd_soc_dai *dai)
103{ 103{
104 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 104 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 6872c77a1196..ba419f86384d 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -112,6 +112,59 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
112} 112}
113EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate); 113EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
114 114
115int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data)
116{
117 const int pll_rate = 73728000;
118 const int ac97_rate = 24576000;
119 int err;
120
121 clk_disable_unprepare(data->clk_cdev1);
122 clk_disable_unprepare(data->clk_pll_a_out0);
123 clk_disable_unprepare(data->clk_pll_a);
124
125 /*
126 * AC97 rate is fixed at 24.576MHz and is used for both the host
127 * controller and the external codec
128 */
129 err = clk_set_rate(data->clk_pll_a, pll_rate);
130 if (err) {
131 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
132 return err;
133 }
134
135 err = clk_set_rate(data->clk_pll_a_out0, ac97_rate);
136 if (err) {
137 dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
138 return err;
139 }
140
141 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
142
143 err = clk_prepare_enable(data->clk_pll_a);
144 if (err) {
145 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
146 return err;
147 }
148
149 err = clk_prepare_enable(data->clk_pll_a_out0);
150 if (err) {
151 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
152 return err;
153 }
154
155 err = clk_prepare_enable(data->clk_cdev1);
156 if (err) {
157 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
158 return err;
159 }
160
161 data->set_baseclock = pll_rate;
162 data->set_mclk = ac97_rate;
163
164 return 0;
165}
166EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_ac97_rate);
167
115int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, 168int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
116 struct device *dev) 169 struct device *dev)
117{ 170{
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 44db1dbb8f21..974c9f8830f9 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -43,6 +43,7 @@ struct tegra_asoc_utils_data {
43 43
44int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, 44int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
45 int mclk); 45 int mclk);
46int tegra_asoc_utils_set_ac97_rate(struct tegra_asoc_utils_data *data);
46int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, 47int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
47 struct device *dev); 48 struct device *dev);
48void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 49void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
new file mode 100644
index 000000000000..68d42403d9b5
--- /dev/null
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -0,0 +1,176 @@
1/*
2 * tegra20_wm9712.c - Tegra machine ASoC driver for boards using WM9712 codec.
3 *
4 * Copyright 2012 Lucas Stach <dev@lynxeye.de>
5 *
6 * Partly based on code copyright/by:
7 * Copyright 2011,2012 Toradex Inc.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/gpio.h>
24#include <linux/of_gpio.h>
25
26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31
32#define DRV_NAME "tegra-snd-wm9712"
33
34struct tegra_wm9712 {
35 struct platform_device *codec;
36};
37
38static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
39 SND_SOC_DAPM_HP("Headphone", NULL),
40 SND_SOC_DAPM_LINE("LineIn", NULL),
41 SND_SOC_DAPM_MIC("Mic", NULL),
42};
43
44static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
45{
46 struct snd_soc_dai *codec_dai = rtd->codec_dai;
47 struct snd_soc_codec *codec = codec_dai->codec;
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
50 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
51
52 return snd_soc_dapm_sync(dapm);
53}
54
55static struct snd_soc_dai_link tegra_wm9712_dai = {
56 .name = "AC97 HiFi",
57 .stream_name = "AC97 HiFi",
58 .cpu_dai_name = "tegra-ac97-pcm",
59 .codec_dai_name = "wm9712-hifi",
60 .codec_name = "wm9712-codec",
61 .init = tegra_wm9712_init,
62};
63
64static struct snd_soc_card snd_soc_tegra_wm9712 = {
65 .name = "tegra-wm9712",
66 .owner = THIS_MODULE,
67 .dai_link = &tegra_wm9712_dai,
68 .num_links = 1,
69
70 .dapm_widgets = tegra_wm9712_dapm_widgets,
71 .num_dapm_widgets = ARRAY_SIZE(tegra_wm9712_dapm_widgets),
72 .fully_routed = true,
73};
74
75static int tegra_wm9712_driver_probe(struct platform_device *pdev)
76{
77 struct device_node *np = pdev->dev.of_node;
78 struct snd_soc_card *card = &snd_soc_tegra_wm9712;
79 struct tegra_wm9712 *machine;
80 int ret;
81
82 if (!pdev->dev.of_node) {
83 dev_err(&pdev->dev, "No platform data supplied\n");
84 return -EINVAL;
85 }
86
87 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
88 GFP_KERNEL);
89 if (!machine) {
90 dev_err(&pdev->dev, "Can't allocate tegra_wm9712 struct\n");
91 return -ENOMEM;
92 }
93
94 card->dev = &pdev->dev;
95 platform_set_drvdata(pdev, card);
96 snd_soc_card_set_drvdata(card, machine);
97
98 machine->codec = platform_device_alloc("wm9712-codec", -1);
99 if (!machine->codec) {
100 dev_err(&pdev->dev, "Can't allocate wm9712 platform device\n");
101 return -ENOMEM;
102 }
103
104 ret = platform_device_add(machine->codec);
105 if (ret)
106 goto codec_put;
107
108 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
109 if (ret)
110 goto codec_unregister;
111
112 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
113 if (ret)
114 goto codec_unregister;
115
116 tegra_wm9712_dai.cpu_of_node = of_parse_phandle(np,
117 "nvidia,ac97-controller", 0);
118 if (!tegra_wm9712_dai.cpu_of_node) {
119 dev_err(&pdev->dev,
120 "Property 'nvidia,ac97-controller' missing or invalid\n");
121 ret = -EINVAL;
122 goto codec_unregister;
123 }
124
125 tegra_wm9712_dai.platform_of_node = tegra_wm9712_dai.cpu_of_node;
126
127 ret = snd_soc_register_card(card);
128 if (ret) {
129 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
130 ret);
131 goto codec_unregister;
132 }
133
134 return 0;
135
136codec_unregister:
137 platform_device_del(machine->codec);
138codec_put:
139 platform_device_put(machine->codec);
140 return ret;
141}
142
143static int tegra_wm9712_driver_remove(struct platform_device *pdev)
144{
145 struct snd_soc_card *card = platform_get_drvdata(pdev);
146 struct tegra_wm9712 *machine = snd_soc_card_get_drvdata(card);
147
148 snd_soc_unregister_card(card);
149
150 platform_device_unregister(machine->codec);
151
152 return 0;
153}
154
155static const struct of_device_id tegra_wm9712_of_match[] = {
156 { .compatible = "nvidia,tegra-audio-wm9712", },
157 {},
158};
159
160static struct platform_driver tegra_wm9712_driver = {
161 .driver = {
162 .name = DRV_NAME,
163 .owner = THIS_MODULE,
164 .pm = &snd_soc_pm_ops,
165 .of_match_table = tegra_wm9712_of_match,
166 },
167 .probe = tegra_wm9712_driver_probe,
168 .remove = tegra_wm9712_driver_remove,
169};
170module_platform_driver(tegra_wm9712_driver);
171
172MODULE_AUTHOR("Lucas Stach");
173MODULE_DESCRIPTION("Tegra+WM9712 machine ASoC driver");
174MODULE_LICENSE("GPL v2");
175MODULE_ALIAS("platform:" DRV_NAME);
176MODULE_DEVICE_TABLE(of, tegra_wm9712_of_match);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index ae6990738783..204b899c2311 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -24,7 +24,7 @@
24#include "ux500_pcm.h" 24#include "ux500_pcm.h"
25#include "ux500_msp_dai.h" 25#include "ux500_msp_dai.h"
26 26
27#include <mop500_ab8500.h> 27#include "mop500_ab8500.h"
28 28
29/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */ 29/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
30struct snd_soc_dai_link mop500_dai_links[] = { 30struct snd_soc_dai_link mop500_dai_links[] = {