aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-22 02:43:19 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-22 02:43:19 -0400
commit13b137ef0367237909bb2dc38babfb8305154676 (patch)
treea5d756fcc6603da970ef8c5e263244c6166a2fba /sound/soc/codecs
parente8fd86efaa09445ca1afc1aea08d4666c966ed03 (diff)
parent440085598672c0e3fde8a48495f61fea418b06d1 (diff)
Merge branch 'topic/asoc' into for-linus
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad1836.c313
-rw-r--r--sound/soc/codecs/ad1836.h44
-rw-r--r--sound/soc/codecs/adau1701.c549
-rw-r--r--sound/soc/codecs/adau1701.h17
-rw-r--r--sound/soc/codecs/adav80x.c951
-rw-r--r--sound/soc/codecs/adav80x.h35
-rw-r--r--sound/soc/codecs/ak4641.c2
-rw-r--r--sound/soc/codecs/cs4270.c5
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/codecs/max98095.c10
-rw-r--r--sound/soc/codecs/sta32x.c917
-rw-r--r--sound/soc/codecs/sta32x.h210
-rw-r--r--sound/soc/codecs/tlv320aic3x.c34
-rw-r--r--sound/soc/codecs/twl6040.c4
-rw-r--r--sound/soc/codecs/wm8782.c80
-rw-r--r--sound/soc/codecs/wm8900.c1
-rw-r--r--sound/soc/codecs/wm8904.c1
-rw-r--r--sound/soc/codecs/wm8915.c156
-rw-r--r--sound/soc/codecs/wm8940.c7
-rw-r--r--sound/soc/codecs/wm8962.c132
-rw-r--r--sound/soc/codecs/wm8983.c1203
-rw-r--r--sound/soc/codecs/wm8983.h1029
-rw-r--r--sound/soc/codecs/wm8993.c3
-rw-r--r--sound/soc/codecs/wm8994.c157
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm9081.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c54
-rw-r--r--sound/soc/codecs/wm_hubs.h10
30 files changed, 5643 insertions, 320 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 98175a096df2..36a030f1d1f5 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311 19 select SND_SOC_AD73311
20 select SND_SOC_ADAV80X
20 select SND_SOC_ADS117X 21 select SND_SOC_ADS117X
21 select SND_SOC_AK4104 if SPI_MASTER 22 select SND_SOC_AK4104 if SPI_MASTER
22 select SND_SOC_AK4535 if I2C 23 select SND_SOC_AK4535 if I2C
@@ -42,6 +43,7 @@ config SND_SOC_ALL_CODECS
42 select SND_SOC_SN95031 if INTEL_SCU_IPC 43 select SND_SOC_SN95031 if INTEL_SCU_IPC
43 select SND_SOC_SPDIF 44 select SND_SOC_SPDIF
44 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI 45 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
46 select SND_SOC_STA32X if I2C
45 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 47 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
46 select SND_SOC_TLV320AIC23 if I2C 48 select SND_SOC_TLV320AIC23 if I2C
47 select SND_SOC_TLV320AIC26 if SPI_MASTER 49 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -71,6 +73,7 @@ config SND_SOC_ALL_CODECS
71 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 73 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
72 select SND_SOC_WM8770 if SPI_MASTER 74 select SND_SOC_WM8770 if SPI_MASTER
73 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 75 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
76 select SND_SOC_WM8782
74 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI 77 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
75 select SND_SOC_WM8900 if I2C 78 select SND_SOC_WM8900 if I2C
76 select SND_SOC_WM8903 if I2C 79 select SND_SOC_WM8903 if I2C
@@ -84,6 +87,7 @@ config SND_SOC_ALL_CODECS
84 select SND_SOC_WM8971 if I2C 87 select SND_SOC_WM8971 if I2C
85 select SND_SOC_WM8974 if I2C 88 select SND_SOC_WM8974 if I2C
86 select SND_SOC_WM8978 if I2C 89 select SND_SOC_WM8978 if I2C
90 select SND_SOC_WM8983 if SND_SOC_I2C_AND_SPI
87 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI 91 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
88 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 92 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
89 select SND_SOC_WM8990 if I2C 93 select SND_SOC_WM8990 if I2C
@@ -130,7 +134,14 @@ config SND_SOC_AD1980
130 134
131config SND_SOC_AD73311 135config SND_SOC_AD73311
132 tristate 136 tristate
133 137
138config SND_SOC_ADAU1701
139 select SIGMA
140 tristate
141
142config SND_SOC_ADAV80X
143 tristate
144
134config SND_SOC_ADS117X 145config SND_SOC_ADS117X
135 tristate 146 tristate
136 147
@@ -216,6 +227,9 @@ config SND_SOC_SPDIF
216config SND_SOC_SSM2602 227config SND_SOC_SSM2602
217 tristate 228 tristate
218 229
230config SND_SOC_STA32X
231 tristate
232
219config SND_SOC_STAC9766 233config SND_SOC_STAC9766
220 tristate 234 tristate
221 235
@@ -299,6 +313,9 @@ config SND_SOC_WM8770
299config SND_SOC_WM8776 313config SND_SOC_WM8776
300 tristate 314 tristate
301 315
316config SND_SOC_WM8782
317 tristate
318
302config SND_SOC_WM8804 319config SND_SOC_WM8804
303 tristate 320 tristate
304 321
@@ -338,6 +355,9 @@ config SND_SOC_WM8974
338config SND_SOC_WM8978 355config SND_SOC_WM8978
339 tristate 356 tristate
340 357
358config SND_SOC_WM8983
359 tristate
360
341config SND_SOC_WM8985 361config SND_SOC_WM8985
342 tristate 362 tristate
343 363
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fd8558406ef0..da9990fb8569 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -4,6 +4,8 @@ snd-soc-ad1836-objs := ad1836.o
4snd-soc-ad193x-objs := ad193x.o 4snd-soc-ad193x-objs := ad193x.o
5snd-soc-ad1980-objs := ad1980.o 5snd-soc-ad1980-objs := ad1980.o
6snd-soc-ad73311-objs := ad73311.o 6snd-soc-ad73311-objs := ad73311.o
7snd-soc-adau1701-objs := adau1701.o
8snd-soc-adav80x-objs := adav80x.o
7snd-soc-ads117x-objs := ads117x.o 9snd-soc-ads117x-objs := ads117x.o
8snd-soc-ak4104-objs := ak4104.o 10snd-soc-ak4104-objs := ak4104.o
9snd-soc-ak4535-objs := ak4535.o 11snd-soc-ak4535-objs := ak4535.o
@@ -28,6 +30,7 @@ snd-soc-alc5623-objs := alc5623.o
28snd-soc-sn95031-objs := sn95031.o 30snd-soc-sn95031-objs := sn95031.o
29snd-soc-spdif-objs := spdif_transciever.o 31snd-soc-spdif-objs := spdif_transciever.o
30snd-soc-ssm2602-objs := ssm2602.o 32snd-soc-ssm2602-objs := ssm2602.o
33snd-soc-sta32x-objs := sta32x.o
31snd-soc-stac9766-objs := stac9766.o 34snd-soc-stac9766-objs := stac9766.o
32snd-soc-tlv320aic23-objs := tlv320aic23.o 35snd-soc-tlv320aic23-objs := tlv320aic23.o
33snd-soc-tlv320aic26-objs := tlv320aic26.o 36snd-soc-tlv320aic26-objs := tlv320aic26.o
@@ -55,6 +58,7 @@ snd-soc-wm8750-objs := wm8750.o
55snd-soc-wm8753-objs := wm8753.o 58snd-soc-wm8753-objs := wm8753.o
56snd-soc-wm8770-objs := wm8770.o 59snd-soc-wm8770-objs := wm8770.o
57snd-soc-wm8776-objs := wm8776.o 60snd-soc-wm8776-objs := wm8776.o
61snd-soc-wm8782-objs := wm8782.o
58snd-soc-wm8804-objs := wm8804.o 62snd-soc-wm8804-objs := wm8804.o
59snd-soc-wm8900-objs := wm8900.o 63snd-soc-wm8900-objs := wm8900.o
60snd-soc-wm8903-objs := wm8903.o 64snd-soc-wm8903-objs := wm8903.o
@@ -68,6 +72,7 @@ snd-soc-wm8962-objs := wm8962.o
68snd-soc-wm8971-objs := wm8971.o 72snd-soc-wm8971-objs := wm8971.o
69snd-soc-wm8974-objs := wm8974.o 73snd-soc-wm8974-objs := wm8974.o
70snd-soc-wm8978-objs := wm8978.o 74snd-soc-wm8978-objs := wm8978.o
75snd-soc-wm8983-objs := wm8983.o
71snd-soc-wm8985-objs := wm8985.o 76snd-soc-wm8985-objs := wm8985.o
72snd-soc-wm8988-objs := wm8988.o 77snd-soc-wm8988-objs := wm8988.o
73snd-soc-wm8990-objs := wm8990.o 78snd-soc-wm8990-objs := wm8990.o
@@ -95,6 +100,8 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
95obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 100obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
96obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 101obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
97obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 102obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
103obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
104obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
98obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 105obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
99obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 106obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
100obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 107obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
@@ -120,6 +127,7 @@ obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
120obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 127obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
121obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 128obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
122obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 129obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
130obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
123obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 131obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
124obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 132obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
125obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 133obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
@@ -147,6 +155,7 @@ obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
147obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 155obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
148obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o 156obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
149obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 157obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
158obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o
150obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o 159obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
151obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 160obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
152obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 161obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
@@ -160,6 +169,7 @@ obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o
160obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 169obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
161obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 170obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
162obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o 171obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
172obj-$(CONFIG_SND_SOC_WM8983) += snd-soc-wm8983.o
163obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o 173obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
164obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 174obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
165obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 175obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 754c496412bd..4e5c5726366b 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -1,19 +1,10 @@
1/* 1 /*
2 * File: sound/soc/codecs/ad1836.c 2 * Audio Codec driver supporting:
3 * Author: Barry Song <Barry.Song@analog.com> 3 * AD1835A, AD1836, AD1837A, AD1838A, AD1839A
4 *
5 * Created: Aug 04 2009
6 * Description: Driver for AD1836 sound chip
7 *
8 * Modified:
9 * Copyright 2009 Analog Devices Inc.
10 * 4 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 5 * Copyright 2009-2011 Analog Devices Inc.
12 * 6 *
13 * This program is free software; you can redistribute it and/or modify 7 * Licensed under the GPL-2 or later.
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 */ 8 */
18 9
19#include <linux/init.h> 10#include <linux/init.h>
@@ -30,10 +21,15 @@
30#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
31#include "ad1836.h" 22#include "ad1836.h"
32 23
24enum ad1836_type {
25 AD1835,
26 AD1836,
27 AD1838,
28};
29
33/* codec private data */ 30/* codec private data */
34struct ad1836_priv { 31struct ad1836_priv {
35 enum snd_soc_control_type control_type; 32 enum ad1836_type type;
36 void *control_data;
37}; 33};
38 34
39/* 35/*
@@ -44,29 +40,60 @@ static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
44static const struct soc_enum ad1836_deemp_enum = 40static const struct soc_enum ad1836_deemp_enum =
45 SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp); 41 SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
46 42
47static const struct snd_kcontrol_new ad1836_snd_controls[] = { 43#define AD1836_DAC_VOLUME(x) \
48 /* DAC volume control */ 44 SOC_DOUBLE_R("DAC" #x " Playback Volume", AD1836_DAC_L_VOL(x), \
49 SOC_DOUBLE_R("DAC1 Volume", AD1836_DAC_L1_VOL, 45 AD1836_DAC_R_VOL(x), 0, 0x3FF, 0)
50 AD1836_DAC_R1_VOL, 0, 0x3FF, 0), 46
51 SOC_DOUBLE_R("DAC2 Volume", AD1836_DAC_L2_VOL, 47#define AD1836_DAC_SWITCH(x) \
52 AD1836_DAC_R2_VOL, 0, 0x3FF, 0), 48 SOC_DOUBLE("DAC" #x " Playback Switch", AD1836_DAC_CTRL2, \
53 SOC_DOUBLE_R("DAC3 Volume", AD1836_DAC_L3_VOL, 49 AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
54 AD1836_DAC_R3_VOL, 0, 0x3FF, 0), 50
55 51#define AD1836_ADC_SWITCH(x) \
56 /* ADC switch control */ 52 SOC_DOUBLE("ADC" #x " Capture Switch", AD1836_ADC_CTRL2, \
57 SOC_DOUBLE("ADC1 Switch", AD1836_ADC_CTRL2, AD1836_ADCL1_MUTE, 53 AD1836_MUTE_LEFT(x), AD1836_MUTE_RIGHT(x), 1, 1)
58 AD1836_ADCR1_MUTE, 1, 1), 54
59 SOC_DOUBLE("ADC2 Switch", AD1836_ADC_CTRL2, AD1836_ADCL2_MUTE, 55static const struct snd_kcontrol_new ad183x_dac_controls[] = {
60 AD1836_ADCR2_MUTE, 1, 1), 56 AD1836_DAC_VOLUME(1),
61 57 AD1836_DAC_SWITCH(1),
62 /* DAC switch control */ 58 AD1836_DAC_VOLUME(2),
63 SOC_DOUBLE("DAC1 Switch", AD1836_DAC_CTRL2, AD1836_DACL1_MUTE, 59 AD1836_DAC_SWITCH(2),
64 AD1836_DACR1_MUTE, 1, 1), 60 AD1836_DAC_VOLUME(3),
65 SOC_DOUBLE("DAC2 Switch", AD1836_DAC_CTRL2, AD1836_DACL2_MUTE, 61 AD1836_DAC_SWITCH(3),
66 AD1836_DACR2_MUTE, 1, 1), 62 AD1836_DAC_VOLUME(4),
67 SOC_DOUBLE("DAC3 Switch", AD1836_DAC_CTRL2, AD1836_DACL3_MUTE, 63 AD1836_DAC_SWITCH(4),
68 AD1836_DACR3_MUTE, 1, 1), 64};
65
66static const struct snd_soc_dapm_widget ad183x_dac_dapm_widgets[] = {
67 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
68 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
69 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
70 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
71};
72
73static const struct snd_soc_dapm_route ad183x_dac_routes[] = {
74 { "DAC1OUT", NULL, "DAC" },
75 { "DAC2OUT", NULL, "DAC" },
76 { "DAC3OUT", NULL, "DAC" },
77 { "DAC4OUT", NULL, "DAC" },
78};
79
80static const struct snd_kcontrol_new ad183x_adc_controls[] = {
81 AD1836_ADC_SWITCH(1),
82 AD1836_ADC_SWITCH(2),
83 AD1836_ADC_SWITCH(3),
84};
85
86static const struct snd_soc_dapm_widget ad183x_adc_dapm_widgets[] = {
87 SND_SOC_DAPM_INPUT("ADC1IN"),
88 SND_SOC_DAPM_INPUT("ADC2IN"),
89};
90
91static const struct snd_soc_dapm_route ad183x_adc_routes[] = {
92 { "ADC", NULL, "ADC1IN" },
93 { "ADC", NULL, "ADC2IN" },
94};
69 95
96static const struct snd_kcontrol_new ad183x_controls[] = {
70 /* ADC high-pass filter */ 97 /* ADC high-pass filter */
71 SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1, 98 SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
72 AD1836_ADC_HIGHPASS_FILTER, 1, 0), 99 AD1836_ADC_HIGHPASS_FILTER, 1, 0),
@@ -75,27 +102,24 @@ static const struct snd_kcontrol_new ad1836_snd_controls[] = {
75 SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum), 102 SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
76}; 103};
77 104
78static const struct snd_soc_dapm_widget ad1836_dapm_widgets[] = { 105static const struct snd_soc_dapm_widget ad183x_dapm_widgets[] = {
79 SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1, 106 SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
80 AD1836_DAC_POWERDOWN, 1), 107 AD1836_DAC_POWERDOWN, 1),
81 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 108 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
82 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1, 109 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
83 AD1836_ADC_POWERDOWN, 1, NULL, 0), 110 AD1836_ADC_POWERDOWN, 1, NULL, 0),
84 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
85 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
86 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
87 SND_SOC_DAPM_INPUT("ADC1IN"),
88 SND_SOC_DAPM_INPUT("ADC2IN"),
89}; 111};
90 112
91static const struct snd_soc_dapm_route audio_paths[] = { 113static const struct snd_soc_dapm_route ad183x_dapm_routes[] = {
92 { "DAC", NULL, "ADC_PWR" }, 114 { "DAC", NULL, "ADC_PWR" },
93 { "ADC", NULL, "ADC_PWR" }, 115 { "ADC", NULL, "ADC_PWR" },
94 { "DAC1OUT", "DAC1 Switch", "DAC" }, 116};
95 { "DAC2OUT", "DAC2 Switch", "DAC" }, 117
96 { "DAC3OUT", "DAC3 Switch", "DAC" }, 118static const DECLARE_TLV_DB_SCALE(ad1836_in_tlv, 0, 300, 0);
97 { "ADC", "ADC1 Switch", "ADC1IN" }, 119
98 { "ADC", "ADC2 Switch", "ADC2IN" }, 120static const struct snd_kcontrol_new ad1836_controls[] = {
121 SOC_DOUBLE_TLV("ADC2 Capture Volume", AD1836_ADC_CTRL1, 3, 0, 4, 0,
122 ad1836_in_tlv),
99}; 123};
100 124
101/* 125/*
@@ -165,64 +189,69 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
165 return 0; 189 return 0;
166} 190}
167 191
192static struct snd_soc_dai_ops ad1836_dai_ops = {
193 .hw_params = ad1836_hw_params,
194 .set_fmt = ad1836_set_dai_fmt,
195};
196
197#define AD183X_DAI(_name, num_dacs, num_adcs) \
198{ \
199 .name = _name "-hifi", \
200 .playback = { \
201 .stream_name = "Playback", \
202 .channels_min = 2, \
203 .channels_max = (num_dacs) * 2, \
204 .rates = SNDRV_PCM_RATE_48000, \
205 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
206 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
207 }, \
208 .capture = { \
209 .stream_name = "Capture", \
210 .channels_min = 2, \
211 .channels_max = (num_adcs) * 2, \
212 .rates = SNDRV_PCM_RATE_48000, \
213 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | \
214 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, \
215 }, \
216 .ops = &ad1836_dai_ops, \
217}
218
219static struct snd_soc_dai_driver ad183x_dais[] = {
220 [AD1835] = AD183X_DAI("ad1835", 4, 1),
221 [AD1836] = AD183X_DAI("ad1836", 3, 2),
222 [AD1838] = AD183X_DAI("ad1838", 3, 1),
223};
224
168#ifdef CONFIG_PM 225#ifdef CONFIG_PM
169static int ad1836_soc_suspend(struct snd_soc_codec *codec, 226static int ad1836_suspend(struct snd_soc_codec *codec, pm_message_t state)
170 pm_message_t state)
171{ 227{
172 /* reset clock control mode */ 228 /* reset clock control mode */
173 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 229 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
174 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; 230 AD1836_ADC_SERFMT_MASK, 0);
175
176 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
177} 231}
178 232
179static int ad1836_soc_resume(struct snd_soc_codec *codec) 233static int ad1836_resume(struct snd_soc_codec *codec)
180{ 234{
181 /* restore clock control mode */ 235 /* restore clock control mode */
182 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 236 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
183 adc_ctrl2 |= AD1836_ADC_AUX; 237 AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
184
185 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
186} 238}
187#else 239#else
188#define ad1836_soc_suspend NULL 240#define ad1836_suspend NULL
189#define ad1836_soc_resume NULL 241#define ad1836_resume NULL
190#endif 242#endif
191 243
192static struct snd_soc_dai_ops ad1836_dai_ops = {
193 .hw_params = ad1836_hw_params,
194 .set_fmt = ad1836_set_dai_fmt,
195};
196
197/* codec DAI instance */
198static struct snd_soc_dai_driver ad1836_dai = {
199 .name = "ad1836-hifi",
200 .playback = {
201 .stream_name = "Playback",
202 .channels_min = 2,
203 .channels_max = 6,
204 .rates = SNDRV_PCM_RATE_48000,
205 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
206 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
207 },
208 .capture = {
209 .stream_name = "Capture",
210 .channels_min = 2,
211 .channels_max = 4,
212 .rates = SNDRV_PCM_RATE_48000,
213 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
214 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
215 },
216 .ops = &ad1836_dai_ops,
217};
218
219static int ad1836_probe(struct snd_soc_codec *codec) 244static int ad1836_probe(struct snd_soc_codec *codec)
220{ 245{
221 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); 246 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
222 struct snd_soc_dapm_context *dapm = &codec->dapm; 247 struct snd_soc_dapm_context *dapm = &codec->dapm;
248 int num_dacs, num_adcs;
223 int ret = 0; 249 int ret = 0;
250 int i;
251
252 num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
253 num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
224 254
225 codec->control_data = ad1836->control_data;
226 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); 255 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
227 if (ret < 0) { 256 if (ret < 0) {
228 dev_err(codec->dev, "failed to set cache I/O: %d\n", 257 dev_err(codec->dev, "failed to set cache I/O: %d\n",
@@ -239,21 +268,46 @@ static int ad1836_probe(struct snd_soc_codec *codec)
239 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); 268 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
240 /* unmute adc channles, adc aux mode */ 269 /* unmute adc channles, adc aux mode */
241 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); 270 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
242 /* left/right diff:PGA/MUX */
243 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
244 /* volume */ 271 /* volume */
245 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF); 272 for (i = 1; i <= num_dacs; ++i) {
246 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF); 273 snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF);
247 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF); 274 snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF);
248 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF); 275 }
249 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); 276
250 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); 277 if (ad1836->type == AD1836) {
251 278 /* left/right diff:PGA/MUX */
252 snd_soc_add_controls(codec, ad1836_snd_controls, 279 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
253 ARRAY_SIZE(ad1836_snd_controls)); 280 ret = snd_soc_add_controls(codec, ad1836_controls,
254 snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets, 281 ARRAY_SIZE(ad1836_controls));
255 ARRAY_SIZE(ad1836_dapm_widgets)); 282 if (ret)
256 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); 283 return ret;
284 } else {
285 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
286 }
287
288 ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2);
289 if (ret)
290 return ret;
291
292 ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs);
293 if (ret)
294 return ret;
295
296 ret = snd_soc_dapm_new_controls(dapm, ad183x_dac_dapm_widgets, num_dacs);
297 if (ret)
298 return ret;
299
300 ret = snd_soc_dapm_new_controls(dapm, ad183x_adc_dapm_widgets, num_adcs);
301 if (ret)
302 return ret;
303
304 ret = snd_soc_dapm_add_routes(dapm, ad183x_dac_routes, num_dacs);
305 if (ret)
306 return ret;
307
308 ret = snd_soc_dapm_add_routes(dapm, ad183x_adc_routes, num_adcs);
309 if (ret)
310 return ret;
257 311
258 return ret; 312 return ret;
259} 313}
@@ -262,19 +316,24 @@ static int ad1836_probe(struct snd_soc_codec *codec)
262static int ad1836_remove(struct snd_soc_codec *codec) 316static int ad1836_remove(struct snd_soc_codec *codec)
263{ 317{
264 /* reset clock control mode */ 318 /* reset clock control mode */
265 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 319 return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
266 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; 320 AD1836_ADC_SERFMT_MASK, 0);
267
268 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
269} 321}
270 322
271static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { 323static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
272 .probe = ad1836_probe, 324 .probe = ad1836_probe,
273 .remove = ad1836_remove, 325 .remove = ad1836_remove,
274 .suspend = ad1836_soc_suspend, 326 .suspend = ad1836_suspend,
275 .resume = ad1836_soc_resume, 327 .resume = ad1836_resume,
276 .reg_cache_size = AD1836_NUM_REGS, 328 .reg_cache_size = AD1836_NUM_REGS,
277 .reg_word_size = sizeof(u16), 329 .reg_word_size = sizeof(u16),
330
331 .controls = ad183x_controls,
332 .num_controls = ARRAY_SIZE(ad183x_controls),
333 .dapm_widgets = ad183x_dapm_widgets,
334 .num_dapm_widgets = ARRAY_SIZE(ad183x_dapm_widgets),
335 .dapm_routes = ad183x_dapm_routes,
336 .num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
278}; 337};
279 338
280static int __devinit ad1836_spi_probe(struct spi_device *spi) 339static int __devinit ad1836_spi_probe(struct spi_device *spi)
@@ -286,12 +345,12 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi)
286 if (ad1836 == NULL) 345 if (ad1836 == NULL)
287 return -ENOMEM; 346 return -ENOMEM;
288 347
348 ad1836->type = spi_get_device_id(spi)->driver_data;
349
289 spi_set_drvdata(spi, ad1836); 350 spi_set_drvdata(spi, ad1836);
290 ad1836->control_data = spi;
291 ad1836->control_type = SND_SOC_SPI;
292 351
293 ret = snd_soc_register_codec(&spi->dev, 352 ret = snd_soc_register_codec(&spi->dev,
294 &soc_codec_dev_ad1836, &ad1836_dai, 1); 353 &soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1);
295 if (ret < 0) 354 if (ret < 0)
296 kfree(ad1836); 355 kfree(ad1836);
297 return ret; 356 return ret;
@@ -303,27 +362,29 @@ static int __devexit ad1836_spi_remove(struct spi_device *spi)
303 kfree(spi_get_drvdata(spi)); 362 kfree(spi_get_drvdata(spi));
304 return 0; 363 return 0;
305} 364}
365static const struct spi_device_id ad1836_ids[] = {
366 { "ad1835", AD1835 },
367 { "ad1836", AD1836 },
368 { "ad1837", AD1835 },
369 { "ad1838", AD1838 },
370 { "ad1839", AD1838 },
371 { },
372};
373MODULE_DEVICE_TABLE(spi, ad1836_ids);
306 374
307static struct spi_driver ad1836_spi_driver = { 375static struct spi_driver ad1836_spi_driver = {
308 .driver = { 376 .driver = {
309 .name = "ad1836-codec", 377 .name = "ad1836",
310 .owner = THIS_MODULE, 378 .owner = THIS_MODULE,
311 }, 379 },
312 .probe = ad1836_spi_probe, 380 .probe = ad1836_spi_probe,
313 .remove = __devexit_p(ad1836_spi_remove), 381 .remove = __devexit_p(ad1836_spi_remove),
382 .id_table = ad1836_ids,
314}; 383};
315 384
316static int __init ad1836_init(void) 385static int __init ad1836_init(void)
317{ 386{
318 int ret; 387 return spi_register_driver(&ad1836_spi_driver);
319
320 ret = spi_register_driver(&ad1836_spi_driver);
321 if (ret != 0) {
322 printk(KERN_ERR "Failed to register ad1836 SPI driver: %d\n",
323 ret);
324 }
325
326 return ret;
327} 388}
328module_init(ad1836_init); 389module_init(ad1836_init);
329 390
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 9d6a3f8f8aaf..444747f0db26 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -1,19 +1,10 @@
1/* 1/*
2 * File: sound/soc/codecs/ad1836.h 2 * Audio Codec driver supporting:
3 * Based on: 3 * AD1835A, AD1836, AD1837A, AD1838A, AD1839A
4 * Author: Barry Song <Barry.Song@analog.com>
5 * 4 *
6 * Created: Aug 04, 2009 5 * Copyright 2009-2011 Analog Devices Inc.
7 * Description: definitions for AD1836 registers
8 * 6 *
9 * Modified: 7 * Licensed under the GPL-2 or later.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 */ 8 */
18 9
19#ifndef __AD1836_H__ 10#ifndef __AD1836_H__
@@ -21,39 +12,30 @@
21 12
22#define AD1836_DAC_CTRL1 0 13#define AD1836_DAC_CTRL1 0
23#define AD1836_DAC_POWERDOWN 2 14#define AD1836_DAC_POWERDOWN 2
24#define AD1836_DAC_SERFMT_MASK 0xE0 15#define AD1836_DAC_SERFMT_MASK 0xE0
25#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5) 16#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
26#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5) 17#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
27#define AD1836_DAC_WORD_LEN_MASK 0x18 18#define AD1836_DAC_WORD_LEN_MASK 0x18
28#define AD1836_DAC_WORD_LEN_OFFSET 3 19#define AD1836_DAC_WORD_LEN_OFFSET 3
29 20
30#define AD1836_DAC_CTRL2 1 21#define AD1836_DAC_CTRL2 1
31#define AD1836_DACL1_MUTE 0
32#define AD1836_DACR1_MUTE 1
33#define AD1836_DACL2_MUTE 2
34#define AD1836_DACR2_MUTE 3
35#define AD1836_DACL3_MUTE 4
36#define AD1836_DACR3_MUTE 5
37 22
38#define AD1836_DAC_L1_VOL 2 23/* These macros are one-based. So AD183X_MUTE_LEFT(1) will return the mute bit
39#define AD1836_DAC_R1_VOL 3 24 * for the first ADC/DAC */
40#define AD1836_DAC_L2_VOL 4 25#define AD1836_MUTE_LEFT(x) (((x) * 2) - 2)
41#define AD1836_DAC_R2_VOL 5 26#define AD1836_MUTE_RIGHT(x) (((x) * 2) - 1)
42#define AD1836_DAC_L3_VOL 6 27
43#define AD1836_DAC_R3_VOL 7 28#define AD1836_DAC_L_VOL(x) ((x) * 2)
29#define AD1836_DAC_R_VOL(x) (1 + ((x) * 2))
44 30
45#define AD1836_ADC_CTRL1 12 31#define AD1836_ADC_CTRL1 12
46#define AD1836_ADC_POWERDOWN 7 32#define AD1836_ADC_POWERDOWN 7
47#define AD1836_ADC_HIGHPASS_FILTER 8 33#define AD1836_ADC_HIGHPASS_FILTER 8
48 34
49#define AD1836_ADC_CTRL2 13 35#define AD1836_ADC_CTRL2 13
50#define AD1836_ADCL1_MUTE 0
51#define AD1836_ADCR1_MUTE 1
52#define AD1836_ADCL2_MUTE 2
53#define AD1836_ADCR2_MUTE 3
54#define AD1836_ADC_WORD_LEN_MASK 0x30 36#define AD1836_ADC_WORD_LEN_MASK 0x30
55#define AD1836_ADC_WORD_OFFSET 5 37#define AD1836_ADC_WORD_OFFSET 5
56#define AD1836_ADC_SERFMT_MASK (7 << 6) 38#define AD1836_ADC_SERFMT_MASK (7 << 6)
57#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 39#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
58#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 40#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
59#define AD1836_ADC_AUX (0x6 << 6) 41#define AD1836_ADC_AUX (0x6 << 6)
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
new file mode 100644
index 000000000000..2758d5fc60d6
--- /dev/null
+++ b/sound/soc/codecs/adau1701.c
@@ -0,0 +1,549 @@
1/*
2 * Driver for ADAU1701 SigmaDSP processor
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 * based on an inital version by Cliff Cai <cliff.cai@analog.com>
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/i2c.h>
14#include <linux/delay.h>
15#include <linux/sigma.h>
16#include <linux/slab.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21
22#include "adau1701.h"
23
24#define ADAU1701_DSPCTRL 0x1c
25#define ADAU1701_SEROCTL 0x1e
26#define ADAU1701_SERICTL 0x1f
27
28#define ADAU1701_AUXNPOW 0x22
29
30#define ADAU1701_OSCIPOW 0x26
31#define ADAU1701_DACSET 0x27
32
33#define ADAU1701_NUM_REGS 0x28
34
35#define ADAU1701_DSPCTRL_CR (1 << 2)
36#define ADAU1701_DSPCTRL_DAM (1 << 3)
37#define ADAU1701_DSPCTRL_ADM (1 << 4)
38#define ADAU1701_DSPCTRL_SR_48 0x00
39#define ADAU1701_DSPCTRL_SR_96 0x01
40#define ADAU1701_DSPCTRL_SR_192 0x02
41#define ADAU1701_DSPCTRL_SR_MASK 0x03
42
43#define ADAU1701_SEROCTL_INV_LRCLK 0x2000
44#define ADAU1701_SEROCTL_INV_BCLK 0x1000
45#define ADAU1701_SEROCTL_MASTER 0x0800
46
47#define ADAU1701_SEROCTL_OBF16 0x0000
48#define ADAU1701_SEROCTL_OBF8 0x0200
49#define ADAU1701_SEROCTL_OBF4 0x0400
50#define ADAU1701_SEROCTL_OBF2 0x0600
51#define ADAU1701_SEROCTL_OBF_MASK 0x0600
52
53#define ADAU1701_SEROCTL_OLF1024 0x0000
54#define ADAU1701_SEROCTL_OLF512 0x0080
55#define ADAU1701_SEROCTL_OLF256 0x0100
56#define ADAU1701_SEROCTL_OLF_MASK 0x0180
57
58#define ADAU1701_SEROCTL_MSB_DEALY1 0x0000
59#define ADAU1701_SEROCTL_MSB_DEALY0 0x0004
60#define ADAU1701_SEROCTL_MSB_DEALY8 0x0008
61#define ADAU1701_SEROCTL_MSB_DEALY12 0x000c
62#define ADAU1701_SEROCTL_MSB_DEALY16 0x0010
63#define ADAU1701_SEROCTL_MSB_DEALY_MASK 0x001c
64
65#define ADAU1701_SEROCTL_WORD_LEN_24 0x0000
66#define ADAU1701_SEROCTL_WORD_LEN_20 0x0001
67#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010
68#define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003
69
70#define ADAU1701_AUXNPOW_VBPD 0x40
71#define ADAU1701_AUXNPOW_VRPD 0x20
72
73#define ADAU1701_SERICTL_I2S 0
74#define ADAU1701_SERICTL_LEFTJ 1
75#define ADAU1701_SERICTL_TDM 2
76#define ADAU1701_SERICTL_RIGHTJ_24 3
77#define ADAU1701_SERICTL_RIGHTJ_20 4
78#define ADAU1701_SERICTL_RIGHTJ_18 5
79#define ADAU1701_SERICTL_RIGHTJ_16 6
80#define ADAU1701_SERICTL_MODE_MASK 7
81#define ADAU1701_SERICTL_INV_BCLK BIT(3)
82#define ADAU1701_SERICTL_INV_LRCLK BIT(4)
83
84#define ADAU1701_OSCIPOW_OPD 0x04
85#define ADAU1701_DACSET_DACINIT 1
86
87#define ADAU1701_FIRMWARE "adau1701.bin"
88
89struct adau1701 {
90 unsigned int dai_fmt;
91};
92
93static const struct snd_kcontrol_new adau1701_controls[] = {
94 SOC_SINGLE("Master Capture Switch", ADAU1701_DSPCTRL, 4, 1, 0),
95};
96
97static const struct snd_soc_dapm_widget adau1701_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC0", "Playback", ADAU1701_AUXNPOW, 3, 1),
99 SND_SOC_DAPM_DAC("DAC1", "Playback", ADAU1701_AUXNPOW, 2, 1),
100 SND_SOC_DAPM_DAC("DAC2", "Playback", ADAU1701_AUXNPOW, 1, 1),
101 SND_SOC_DAPM_DAC("DAC3", "Playback", ADAU1701_AUXNPOW, 0, 1),
102 SND_SOC_DAPM_ADC("ADC", "Capture", ADAU1701_AUXNPOW, 7, 1),
103
104 SND_SOC_DAPM_OUTPUT("OUT0"),
105 SND_SOC_DAPM_OUTPUT("OUT1"),
106 SND_SOC_DAPM_OUTPUT("OUT2"),
107 SND_SOC_DAPM_OUTPUT("OUT3"),
108 SND_SOC_DAPM_INPUT("IN0"),
109 SND_SOC_DAPM_INPUT("IN1"),
110};
111
112static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
113 { "OUT0", NULL, "DAC0" },
114 { "OUT1", NULL, "DAC1" },
115 { "OUT2", NULL, "DAC2" },
116 { "OUT3", NULL, "DAC3" },
117
118 { "ADC", NULL, "IN0" },
119 { "ADC", NULL, "IN1" },
120};
121
122static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
123 unsigned int reg)
124{
125 switch (reg) {
126 case ADAU1701_DSPCTRL:
127 case ADAU1701_SEROCTL:
128 case ADAU1701_AUXNPOW:
129 case ADAU1701_OSCIPOW:
130 case ADAU1701_DACSET:
131 return 2;
132 case ADAU1701_SERICTL:
133 return 1;
134 }
135
136 dev_err(codec->dev, "Unsupported register address: %d\n", reg);
137 return 0;
138}
139
140static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
141 unsigned int value)
142{
143 unsigned int i;
144 unsigned int size;
145 uint8_t buf[4];
146 int ret;
147
148 size = adau1701_register_size(codec, reg);
149 if (size == 0)
150 return -EINVAL;
151
152 snd_soc_cache_write(codec, reg, value);
153
154 buf[0] = 0x08;
155 buf[1] = reg;
156
157 for (i = size + 1; i >= 2; --i) {
158 buf[i] = value;
159 value >>= 8;
160 }
161
162 ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2);
163 if (ret == size + 2)
164 return 0;
165 else if (ret < 0)
166 return ret;
167 else
168 return -EIO;
169}
170
171static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg)
172{
173 unsigned int value;
174 unsigned int ret;
175
176 ret = snd_soc_cache_read(codec, reg, &value);
177 if (ret)
178 return ret;
179
180 return value;
181}
182
183static int adau1701_load_firmware(struct snd_soc_codec *codec)
184{
185 return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE);
186}
187
188static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
189 snd_pcm_format_t format)
190{
191 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
192 unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK;
193 unsigned int val;
194
195 switch (format) {
196 case SNDRV_PCM_FORMAT_S16_LE:
197 val = ADAU1701_SEROCTL_WORD_LEN_16;
198 break;
199 case SNDRV_PCM_FORMAT_S20_3LE:
200 val = ADAU1701_SEROCTL_WORD_LEN_20;
201 break;
202 case SNDRV_PCM_FORMAT_S24_LE:
203 val = ADAU1701_SEROCTL_WORD_LEN_24;
204 break;
205 default:
206 return -EINVAL;
207 }
208
209 if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) {
210 switch (format) {
211 case SNDRV_PCM_FORMAT_S16_LE:
212 val |= ADAU1701_SEROCTL_MSB_DEALY16;
213 break;
214 case SNDRV_PCM_FORMAT_S20_3LE:
215 val |= ADAU1701_SEROCTL_MSB_DEALY12;
216 break;
217 case SNDRV_PCM_FORMAT_S24_LE:
218 val |= ADAU1701_SEROCTL_MSB_DEALY8;
219 break;
220 }
221 mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK;
222 }
223
224 snd_soc_update_bits(codec, ADAU1701_SEROCTL, mask, val);
225
226 return 0;
227}
228
229static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
230 snd_pcm_format_t format)
231{
232 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
233 unsigned int val;
234
235 if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
236 return 0;
237
238 switch (format) {
239 case SNDRV_PCM_FORMAT_S16_LE:
240 val = ADAU1701_SERICTL_RIGHTJ_16;
241 break;
242 case SNDRV_PCM_FORMAT_S20_3LE:
243 val = ADAU1701_SERICTL_RIGHTJ_20;
244 break;
245 case SNDRV_PCM_FORMAT_S24_LE:
246 val = ADAU1701_SERICTL_RIGHTJ_24;
247 break;
248 default:
249 return -EINVAL;
250 }
251
252 snd_soc_update_bits(codec, ADAU1701_SERICTL,
253 ADAU1701_SERICTL_MODE_MASK, val);
254
255 return 0;
256}
257
258static int adau1701_hw_params(struct snd_pcm_substream *substream,
259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
260{
261 struct snd_soc_pcm_runtime *rtd = substream->private_data;
262 struct snd_soc_codec *codec = rtd->codec;
263 snd_pcm_format_t format;
264 unsigned int val;
265
266 switch (params_rate(params)) {
267 case 192000:
268 val = ADAU1701_DSPCTRL_SR_192;
269 break;
270 case 96000:
271 val = ADAU1701_DSPCTRL_SR_96;
272 break;
273 case 48000:
274 val = ADAU1701_DSPCTRL_SR_48;
275 break;
276 default:
277 return -EINVAL;
278 }
279
280 snd_soc_update_bits(codec, ADAU1701_DSPCTRL,
281 ADAU1701_DSPCTRL_SR_MASK, val);
282
283 format = params_format(params);
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
285 return adau1701_set_playback_pcm_format(codec, format);
286 else
287 return adau1701_set_capture_pcm_format(codec, format);
288}
289
290static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
291 unsigned int fmt)
292{
293 struct snd_soc_codec *codec = codec_dai->codec;
294 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
295 unsigned int serictl = 0x00, seroctl = 0x00;
296 bool invert_lrclk;
297
298 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
299 case SND_SOC_DAIFMT_CBM_CFM:
300 /* master, 64-bits per sample, 1 frame per sample */
301 seroctl |= ADAU1701_SEROCTL_MASTER | ADAU1701_SEROCTL_OBF16
302 | ADAU1701_SEROCTL_OLF1024;
303 break;
304 case SND_SOC_DAIFMT_CBS_CFS:
305 break;
306 default:
307 return -EINVAL;
308 }
309
310 /* clock inversion */
311 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
312 case SND_SOC_DAIFMT_NB_NF:
313 invert_lrclk = false;
314 break;
315 case SND_SOC_DAIFMT_NB_IF:
316 invert_lrclk = true;
317 break;
318 case SND_SOC_DAIFMT_IB_NF:
319 invert_lrclk = false;
320 serictl |= ADAU1701_SERICTL_INV_BCLK;
321 seroctl |= ADAU1701_SEROCTL_INV_BCLK;
322 break;
323 case SND_SOC_DAIFMT_IB_IF:
324 invert_lrclk = true;
325 serictl |= ADAU1701_SERICTL_INV_BCLK;
326 seroctl |= ADAU1701_SEROCTL_INV_BCLK;
327 break;
328 default:
329 return -EINVAL;
330 }
331
332 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
333 case SND_SOC_DAIFMT_I2S:
334 break;
335 case SND_SOC_DAIFMT_LEFT_J:
336 serictl |= ADAU1701_SERICTL_LEFTJ;
337 seroctl |= ADAU1701_SEROCTL_MSB_DEALY0;
338 invert_lrclk = !invert_lrclk;
339 break;
340 case SND_SOC_DAIFMT_RIGHT_J:
341 serictl |= ADAU1701_SERICTL_RIGHTJ_24;
342 seroctl |= ADAU1701_SEROCTL_MSB_DEALY8;
343 invert_lrclk = !invert_lrclk;
344 break;
345 default:
346 return -EINVAL;
347 }
348
349 if (invert_lrclk) {
350 seroctl |= ADAU1701_SEROCTL_INV_LRCLK;
351 serictl |= ADAU1701_SERICTL_INV_LRCLK;
352 }
353
354 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
355
356 snd_soc_write(codec, ADAU1701_SERICTL, serictl);
357 snd_soc_update_bits(codec, ADAU1701_SEROCTL,
358 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
359
360 return 0;
361}
362
363static int adau1701_set_bias_level(struct snd_soc_codec *codec,
364 enum snd_soc_bias_level level)
365{
366 unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
367
368 switch (level) {
369 case SND_SOC_BIAS_ON:
370 break;
371 case SND_SOC_BIAS_PREPARE:
372 break;
373 case SND_SOC_BIAS_STANDBY:
374 /* Enable VREF and VREF buffer */
375 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, 0x00);
376 break;
377 case SND_SOC_BIAS_OFF:
378 /* Disable VREF and VREF buffer */
379 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, mask);
380 break;
381 }
382
383 codec->dapm.bias_level = level;
384 return 0;
385}
386
387static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
388{
389 struct snd_soc_codec *codec = dai->codec;
390 unsigned int mask = ADAU1701_DSPCTRL_DAM;
391 unsigned int val;
392
393 if (mute)
394 val = 0;
395 else
396 val = mask;
397
398 snd_soc_update_bits(codec, ADAU1701_DSPCTRL, mask, val);
399
400 return 0;
401}
402
403static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
404 unsigned int freq, int dir)
405{
406 unsigned int val;
407
408 switch (clk_id) {
409 case ADAU1701_CLK_SRC_OSC:
410 val = 0x0;
411 break;
412 case ADAU1701_CLK_SRC_MCLK:
413 val = ADAU1701_OSCIPOW_OPD;
414 break;
415 default:
416 return -EINVAL;
417 }
418
419 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val);
420
421 return 0;
422}
423
424#define ADAU1701_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
425 SNDRV_PCM_RATE_192000)
426
427#define ADAU1701_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
428 SNDRV_PCM_FMTBIT_S24_LE)
429
430static const struct snd_soc_dai_ops adau1701_dai_ops = {
431 .set_fmt = adau1701_set_dai_fmt,
432 .hw_params = adau1701_hw_params,
433 .digital_mute = adau1701_digital_mute,
434};
435
436static struct snd_soc_dai_driver adau1701_dai = {
437 .name = "adau1701",
438 .playback = {
439 .stream_name = "Playback",
440 .channels_min = 2,
441 .channels_max = 8,
442 .rates = ADAU1701_RATES,
443 .formats = ADAU1701_FORMATS,
444 },
445 .capture = {
446 .stream_name = "Capture",
447 .channels_min = 2,
448 .channels_max = 8,
449 .rates = ADAU1701_RATES,
450 .formats = ADAU1701_FORMATS,
451 },
452 .ops = &adau1701_dai_ops,
453 .symmetric_rates = 1,
454};
455
456static int adau1701_probe(struct snd_soc_codec *codec)
457{
458 int ret;
459
460 codec->dapm.idle_bias_off = 1;
461
462 ret = adau1701_load_firmware(codec);
463 if (ret)
464 dev_warn(codec->dev, "Failed to load firmware\n");
465
466 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
467 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
468
469 return 0;
470}
471
472static struct snd_soc_codec_driver adau1701_codec_drv = {
473 .probe = adau1701_probe,
474 .set_bias_level = adau1701_set_bias_level,
475
476 .reg_cache_size = ADAU1701_NUM_REGS,
477 .reg_word_size = sizeof(u16),
478
479 .controls = adau1701_controls,
480 .num_controls = ARRAY_SIZE(adau1701_controls),
481 .dapm_widgets = adau1701_dapm_widgets,
482 .num_dapm_widgets = ARRAY_SIZE(adau1701_dapm_widgets),
483 .dapm_routes = adau1701_dapm_routes,
484 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
485
486 .write = adau1701_write,
487 .read = adau1701_read,
488
489 .set_sysclk = adau1701_set_sysclk,
490};
491
492static __devinit int adau1701_i2c_probe(struct i2c_client *client,
493 const struct i2c_device_id *id)
494{
495 struct adau1701 *adau1701;
496 int ret;
497
498 adau1701 = kzalloc(sizeof(*adau1701), GFP_KERNEL);
499 if (!adau1701)
500 return -ENOMEM;
501
502 i2c_set_clientdata(client, adau1701);
503 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
504 &adau1701_dai, 1);
505 if (ret < 0)
506 kfree(adau1701);
507
508 return ret;
509}
510
511static __devexit int adau1701_i2c_remove(struct i2c_client *client)
512{
513 snd_soc_unregister_codec(&client->dev);
514 kfree(i2c_get_clientdata(client));
515 return 0;
516}
517
518static const struct i2c_device_id adau1701_i2c_id[] = {
519 { "adau1701", 0 },
520 { }
521};
522MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
523
524static struct i2c_driver adau1701_i2c_driver = {
525 .driver = {
526 .name = "adau1701",
527 .owner = THIS_MODULE,
528 },
529 .probe = adau1701_i2c_probe,
530 .remove = __devexit_p(adau1701_i2c_remove),
531 .id_table = adau1701_i2c_id,
532};
533
534static int __init adau1701_init(void)
535{
536 return i2c_add_driver(&adau1701_i2c_driver);
537}
538module_init(adau1701_init);
539
540static void __exit adau1701_exit(void)
541{
542 i2c_del_driver(&adau1701_i2c_driver);
543}
544module_exit(adau1701_exit);
545
546MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
547MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
548MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
549MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adau1701.h b/sound/soc/codecs/adau1701.h
new file mode 100644
index 000000000000..8d0949a2aec9
--- /dev/null
+++ b/sound/soc/codecs/adau1701.h
@@ -0,0 +1,17 @@
1/*
2 * header file for ADAU1701 SigmaDSP processor
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#ifndef _ADAU1701_H
10#define _ADAU1701_H
11
12enum adau1701_clk_src {
13 ADAU1701_CLK_SRC_OSC,
14 ADAU1701_CLK_SRC_MCLK,
15};
16
17#endif
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
new file mode 100644
index 000000000000..300c04b70e71
--- /dev/null
+++ b/sound/soc/codecs/adav80x.c
@@ -0,0 +1,951 @@
1/*
2 * ADAV80X Audio Codec driver supporting ADAV801, ADAV803
3 *
4 * Copyright 2011 Analog Devices Inc.
5 * Author: Yi Li <yi.li@analog.com>
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 *
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/i2c.h>
15#include <linux/spi/spi.h>
16#include <linux/slab.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include <sound/soc.h>
22
23#include "adav80x.h"
24
25#define ADAV80X_PLAYBACK_CTRL 0x04
26#define ADAV80X_AUX_IN_CTRL 0x05
27#define ADAV80X_REC_CTRL 0x06
28#define ADAV80X_AUX_OUT_CTRL 0x07
29#define ADAV80X_DPATH_CTRL1 0x62
30#define ADAV80X_DPATH_CTRL2 0x63
31#define ADAV80X_DAC_CTRL1 0x64
32#define ADAV80X_DAC_CTRL2 0x65
33#define ADAV80X_DAC_CTRL3 0x66
34#define ADAV80X_DAC_L_VOL 0x68
35#define ADAV80X_DAC_R_VOL 0x69
36#define ADAV80X_PGA_L_VOL 0x6c
37#define ADAV80X_PGA_R_VOL 0x6d
38#define ADAV80X_ADC_CTRL1 0x6e
39#define ADAV80X_ADC_CTRL2 0x6f
40#define ADAV80X_ADC_L_VOL 0x70
41#define ADAV80X_ADC_R_VOL 0x71
42#define ADAV80X_PLL_CTRL1 0x74
43#define ADAV80X_PLL_CTRL2 0x75
44#define ADAV80X_ICLK_CTRL1 0x76
45#define ADAV80X_ICLK_CTRL2 0x77
46#define ADAV80X_PLL_CLK_SRC 0x78
47#define ADAV80X_PLL_OUTE 0x7a
48
49#define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll) 0x00
50#define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll) (0x40 << (pll))
51#define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll) (0x40 << (pll))
52
53#define ADAV80X_ICLK_CTRL1_DAC_SRC(src) ((src) << 5)
54#define ADAV80X_ICLK_CTRL1_ADC_SRC(src) ((src) << 2)
55#define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src) (src)
56#define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src) ((src) << 3)
57
58#define ADAV80X_PLL_CTRL1_PLLDIV 0x10
59#define ADAV80X_PLL_CTRL1_PLLPD(pll) (0x04 << (pll))
60#define ADAV80X_PLL_CTRL1_XTLPD 0x02
61
62#define ADAV80X_PLL_CTRL2_FIELD(pll, x) ((x) << ((pll) * 4))
63
64#define ADAV80X_PLL_CTRL2_FS_48(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x00)
65#define ADAV80X_PLL_CTRL2_FS_32(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x08)
66#define ADAV80X_PLL_CTRL2_FS_44(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0c)
67
68#define ADAV80X_PLL_CTRL2_SEL(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x02)
69#define ADAV80X_PLL_CTRL2_DOUB(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x01)
70#define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0f)
71
72#define ADAV80X_ADC_CTRL1_MODULATOR_MASK 0x80
73#define ADAV80X_ADC_CTRL1_MODULATOR_128FS 0x00
74#define ADAV80X_ADC_CTRL1_MODULATOR_64FS 0x80
75
76#define ADAV80X_DAC_CTRL1_PD 0x80
77
78#define ADAV80X_DAC_CTRL2_DIV1 0x00
79#define ADAV80X_DAC_CTRL2_DIV1_5 0x10
80#define ADAV80X_DAC_CTRL2_DIV2 0x20
81#define ADAV80X_DAC_CTRL2_DIV3 0x30
82#define ADAV80X_DAC_CTRL2_DIV_MASK 0x30
83
84#define ADAV80X_DAC_CTRL2_INTERPOL_256FS 0x00
85#define ADAV80X_DAC_CTRL2_INTERPOL_128FS 0x40
86#define ADAV80X_DAC_CTRL2_INTERPOL_64FS 0x80
87#define ADAV80X_DAC_CTRL2_INTERPOL_MASK 0xc0
88
89#define ADAV80X_DAC_CTRL2_DEEMPH_NONE 0x00
90#define ADAV80X_DAC_CTRL2_DEEMPH_44 0x01
91#define ADAV80X_DAC_CTRL2_DEEMPH_32 0x02
92#define ADAV80X_DAC_CTRL2_DEEMPH_48 0x03
93#define ADAV80X_DAC_CTRL2_DEEMPH_MASK 0x01
94
95#define ADAV80X_CAPTURE_MODE_MASTER 0x20
96#define ADAV80X_CAPTURE_WORD_LEN24 0x00
97#define ADAV80X_CAPTURE_WORD_LEN20 0x04
98#define ADAV80X_CAPTRUE_WORD_LEN18 0x08
99#define ADAV80X_CAPTURE_WORD_LEN16 0x0c
100#define ADAV80X_CAPTURE_WORD_LEN_MASK 0x0c
101
102#define ADAV80X_CAPTURE_MODE_LEFT_J 0x00
103#define ADAV80X_CAPTURE_MODE_I2S 0x01
104#define ADAV80X_CAPTURE_MODE_RIGHT_J 0x03
105#define ADAV80X_CAPTURE_MODE_MASK 0x03
106
107#define ADAV80X_PLAYBACK_MODE_MASTER 0x10
108#define ADAV80X_PLAYBACK_MODE_LEFT_J 0x00
109#define ADAV80X_PLAYBACK_MODE_I2S 0x01
110#define ADAV80X_PLAYBACK_MODE_RIGHT_J_24 0x04
111#define ADAV80X_PLAYBACK_MODE_RIGHT_J_20 0x05
112#define ADAV80X_PLAYBACK_MODE_RIGHT_J_18 0x06
113#define ADAV80X_PLAYBACK_MODE_RIGHT_J_16 0x07
114#define ADAV80X_PLAYBACK_MODE_MASK 0x07
115
116#define ADAV80X_PLL_OUTE_SYSCLKPD(x) BIT(2 - (x))
117
118static u8 adav80x_default_regs[] = {
119 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x01, 0x80, 0x26, 0x00, 0x00,
120 0x02, 0x40, 0x20, 0x00, 0x09, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x92, 0xb1, 0x37,
122 0x48, 0xd2, 0xfb, 0xca, 0xd2, 0x15, 0xe8, 0x29, 0xb9, 0x6a, 0xda, 0x2b,
123 0xb7, 0xc0, 0x11, 0x65, 0x5c, 0xf6, 0xff, 0x8d, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00,
126 0x00, 0xe8, 0x46, 0xe1, 0x5b, 0xd3, 0x43, 0x77, 0x93, 0xa7, 0x44, 0xee,
127 0x32, 0x12, 0xc0, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x3f,
128 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x52, 0x00,
130};
131
132struct adav80x {
133 enum snd_soc_control_type control_type;
134
135 enum adav80x_clk_src clk_src;
136 unsigned int sysclk;
137 enum adav80x_pll_src pll_src;
138
139 unsigned int dai_fmt[2];
140 unsigned int rate;
141 bool deemph;
142 bool sysclk_pd[3];
143};
144
145static const char *adav80x_mux_text[] = {
146 "ADC",
147 "Playback",
148 "Aux Playback",
149};
150
151static const unsigned int adav80x_mux_values[] = {
152 0, 2, 3,
153};
154
155#define ADAV80X_MUX_ENUM_DECL(name, reg, shift) \
156 SOC_VALUE_ENUM_DOUBLE_DECL(name, reg, shift, 7, \
157 ARRAY_SIZE(adav80x_mux_text), adav80x_mux_text, \
158 adav80x_mux_values)
159
160static ADAV80X_MUX_ENUM_DECL(adav80x_aux_capture_enum, ADAV80X_DPATH_CTRL1, 0);
161static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3);
162static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3);
163
164static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl =
165 SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum);
166static const struct snd_kcontrol_new adav80x_capture_mux_ctrl =
167 SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum);
168static const struct snd_kcontrol_new adav80x_dac_mux_ctrl =
169 SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum);
170
171#define ADAV80X_MUX(name, ctrl) \
172 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
173
174static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {
175 SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1),
176 SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_ADC_CTRL1, 5, 1),
177
178 SND_SOC_DAPM_PGA("Right PGA", ADAV80X_ADC_CTRL1, 0, 1, NULL, 0),
179 SND_SOC_DAPM_PGA("Left PGA", ADAV80X_ADC_CTRL1, 1, 1, NULL, 0),
180
181 SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
182 SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
183
184 SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux Capture", 0, SND_SOC_NOPM, 0, 0),
185 SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux Playback", 0, SND_SOC_NOPM, 0, 0),
186
187 ADAV80X_MUX("Aux Capture Select", &adav80x_aux_capture_mux_ctrl),
188 ADAV80X_MUX("Capture Select", &adav80x_capture_mux_ctrl),
189 ADAV80X_MUX("DAC Select", &adav80x_dac_mux_ctrl),
190
191 SND_SOC_DAPM_INPUT("VINR"),
192 SND_SOC_DAPM_INPUT("VINL"),
193 SND_SOC_DAPM_OUTPUT("VOUTR"),
194 SND_SOC_DAPM_OUTPUT("VOUTL"),
195
196 SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0),
197 SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PLL_CTRL1, 2, 1, NULL, 0),
198 SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PLL_CTRL1, 3, 1, NULL, 0),
199 SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL_CTRL1, 1, 1, NULL, 0),
200};
201
202static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,
203 struct snd_soc_dapm_widget *sink)
204{
205 struct snd_soc_codec *codec = source->codec;
206 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
207 const char *clk;
208
209 switch (adav80x->clk_src) {
210 case ADAV80X_CLK_PLL1:
211 clk = "PLL1";
212 break;
213 case ADAV80X_CLK_PLL2:
214 clk = "PLL2";
215 break;
216 case ADAV80X_CLK_XTAL:
217 clk = "OSC";
218 break;
219 default:
220 return 0;
221 }
222
223 return strcmp(source->name, clk) == 0;
224}
225
226static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,
227 struct snd_soc_dapm_widget *sink)
228{
229 struct snd_soc_codec *codec = source->codec;
230 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
231
232 return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;
233}
234
235
236static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {
237 { "DAC Select", "ADC", "ADC" },
238 { "DAC Select", "Playback", "AIFIN" },
239 { "DAC Select", "Aux Playback", "AIFAUXIN" },
240 { "DAC", NULL, "DAC Select" },
241
242 { "Capture Select", "ADC", "ADC" },
243 { "Capture Select", "Playback", "AIFIN" },
244 { "Capture Select", "Aux Playback", "AIFAUXIN" },
245 { "AIFOUT", NULL, "Capture Select" },
246
247 { "Aux Capture Select", "ADC", "ADC" },
248 { "Aux Capture Select", "Playback", "AIFIN" },
249 { "Aux Capture Select", "Aux Playback", "AIFAUXIN" },
250 { "AIFAUXOUT", NULL, "Aux Capture Select" },
251
252 { "VOUTR", NULL, "DAC" },
253 { "VOUTL", NULL, "DAC" },
254
255 { "Left PGA", NULL, "VINL" },
256 { "Right PGA", NULL, "VINR" },
257 { "ADC", NULL, "Left PGA" },
258 { "ADC", NULL, "Right PGA" },
259
260 { "SYSCLK", NULL, "PLL1", adav80x_dapm_sysclk_check },
261 { "SYSCLK", NULL, "PLL2", adav80x_dapm_sysclk_check },
262 { "SYSCLK", NULL, "OSC", adav80x_dapm_sysclk_check },
263 { "PLL1", NULL, "OSC", adav80x_dapm_pll_check },
264 { "PLL2", NULL, "OSC", adav80x_dapm_pll_check },
265
266 { "ADC", NULL, "SYSCLK" },
267 { "DAC", NULL, "SYSCLK" },
268 { "AIFOUT", NULL, "SYSCLK" },
269 { "AIFAUXOUT", NULL, "SYSCLK" },
270 { "AIFIN", NULL, "SYSCLK" },
271 { "AIFAUXIN", NULL, "SYSCLK" },
272};
273
274static int adav80x_set_deemph(struct snd_soc_codec *codec)
275{
276 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
277 unsigned int val;
278
279 if (adav80x->deemph) {
280 switch (adav80x->rate) {
281 case 32000:
282 val = ADAV80X_DAC_CTRL2_DEEMPH_32;
283 break;
284 case 44100:
285 val = ADAV80X_DAC_CTRL2_DEEMPH_44;
286 break;
287 case 48000:
288 case 64000:
289 case 88200:
290 case 96000:
291 val = ADAV80X_DAC_CTRL2_DEEMPH_48;
292 break;
293 default:
294 val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
295 break;
296 }
297 } else {
298 val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;
299 }
300
301 return snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2,
302 ADAV80X_DAC_CTRL2_DEEMPH_MASK, val);
303}
304
305static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol)
307{
308 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
309 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
310 unsigned int deemph = ucontrol->value.enumerated.item[0];
311
312 if (deemph > 1)
313 return -EINVAL;
314
315 adav80x->deemph = deemph;
316
317 return adav80x_set_deemph(codec);
318}
319
320static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,
321 struct snd_ctl_elem_value *ucontrol)
322{
323 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
324 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
325
326 ucontrol->value.enumerated.item[0] = adav80x->deemph;
327 return 0;
328};
329
330static const DECLARE_TLV_DB_SCALE(adav80x_inpga_tlv, 0, 50, 0);
331static const DECLARE_TLV_DB_MINMAX(adav80x_digital_tlv, -9563, 0);
332
333static const struct snd_kcontrol_new adav80x_controls[] = {
334 SOC_DOUBLE_R_TLV("Master Playback Volume", ADAV80X_DAC_L_VOL,
335 ADAV80X_DAC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
336 SOC_DOUBLE_R_TLV("Master Capture Volume", ADAV80X_ADC_L_VOL,
337 ADAV80X_ADC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),
338
339 SOC_DOUBLE_R_TLV("PGA Capture Volume", ADAV80X_PGA_L_VOL,
340 ADAV80X_PGA_R_VOL, 0, 0x30, 0, adav80x_inpga_tlv),
341
342 SOC_DOUBLE("Master Playback Switch", ADAV80X_DAC_CTRL1, 0, 1, 1, 0),
343 SOC_DOUBLE("Master Capture Switch", ADAV80X_ADC_CTRL1, 2, 3, 1, 1),
344
345 SOC_SINGLE("ADC High Pass Filter Switch", ADAV80X_ADC_CTRL1, 6, 1, 0),
346
347 SOC_SINGLE_BOOL_EXT("Playback De-emphasis Switch", 0,
348 adav80x_get_deemph, adav80x_put_deemph),
349};
350
351static unsigned int adav80x_port_ctrl_regs[2][2] = {
352 { ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_CTRL, },
353 { ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN_CTRL },
354};
355
356static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
357{
358 struct snd_soc_codec *codec = dai->codec;
359 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
360 unsigned int capture = 0x00;
361 unsigned int playback = 0x00;
362
363 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
364 case SND_SOC_DAIFMT_CBM_CFM:
365 capture |= ADAV80X_CAPTURE_MODE_MASTER;
366 playback |= ADAV80X_PLAYBACK_MODE_MASTER;
367 case SND_SOC_DAIFMT_CBS_CFS:
368 break;
369 default:
370 return -EINVAL;
371 }
372
373 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
374 case SND_SOC_DAIFMT_I2S:
375 capture |= ADAV80X_CAPTURE_MODE_I2S;
376 playback |= ADAV80X_PLAYBACK_MODE_I2S;
377 break;
378 case SND_SOC_DAIFMT_LEFT_J:
379 capture |= ADAV80X_CAPTURE_MODE_LEFT_J;
380 playback |= ADAV80X_PLAYBACK_MODE_LEFT_J;
381 break;
382 case SND_SOC_DAIFMT_RIGHT_J:
383 capture |= ADAV80X_CAPTURE_MODE_RIGHT_J;
384 playback |= ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
385 break;
386 default:
387 return -EINVAL;
388 }
389
390 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
391 case SND_SOC_DAIFMT_NB_NF:
392 break;
393 default:
394 return -EINVAL;
395 }
396
397 snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0],
398 ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER,
399 capture);
400 snd_soc_write(codec, adav80x_port_ctrl_regs[dai->id][1], playback);
401
402 adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
403
404 return 0;
405}
406
407static int adav80x_set_adc_clock(struct snd_soc_codec *codec,
408 unsigned int sample_rate)
409{
410 unsigned int val;
411
412 if (sample_rate <= 48000)
413 val = ADAV80X_ADC_CTRL1_MODULATOR_128FS;
414 else
415 val = ADAV80X_ADC_CTRL1_MODULATOR_64FS;
416
417 snd_soc_update_bits(codec, ADAV80X_ADC_CTRL1,
418 ADAV80X_ADC_CTRL1_MODULATOR_MASK, val);
419
420 return 0;
421}
422
423static int adav80x_set_dac_clock(struct snd_soc_codec *codec,
424 unsigned int sample_rate)
425{
426 unsigned int val;
427
428 if (sample_rate <= 48000)
429 val = ADAV80X_DAC_CTRL2_DIV1 | ADAV80X_DAC_CTRL2_INTERPOL_256FS;
430 else
431 val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS;
432
433 snd_soc_update_bits(codec, ADAV80X_DAC_CTRL2,
434 ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK,
435 val);
436
437 return 0;
438}
439
440static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec,
441 struct snd_soc_dai *dai, snd_pcm_format_t format)
442{
443 unsigned int val;
444
445 switch (format) {
446 case SNDRV_PCM_FORMAT_S16_LE:
447 val = ADAV80X_CAPTURE_WORD_LEN16;
448 break;
449 case SNDRV_PCM_FORMAT_S18_3LE:
450 val = ADAV80X_CAPTRUE_WORD_LEN18;
451 break;
452 case SNDRV_PCM_FORMAT_S20_3LE:
453 val = ADAV80X_CAPTURE_WORD_LEN20;
454 break;
455 case SNDRV_PCM_FORMAT_S24_LE:
456 val = ADAV80X_CAPTURE_WORD_LEN24;
457 break;
458 default:
459 return -EINVAL;
460 }
461
462 snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][0],
463 ADAV80X_CAPTURE_WORD_LEN_MASK, val);
464
465 return 0;
466}
467
468static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec,
469 struct snd_soc_dai *dai, snd_pcm_format_t format)
470{
471 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
472 unsigned int val;
473
474 if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)
475 return 0;
476
477 switch (format) {
478 case SNDRV_PCM_FORMAT_S16_LE:
479 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;
480 break;
481 case SNDRV_PCM_FORMAT_S18_3LE:
482 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;
483 break;
484 case SNDRV_PCM_FORMAT_S20_3LE:
485 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;
486 break;
487 case SNDRV_PCM_FORMAT_S24_LE:
488 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;
489 break;
490 default:
491 return -EINVAL;
492 }
493
494 snd_soc_update_bits(codec, adav80x_port_ctrl_regs[dai->id][1],
495 ADAV80X_PLAYBACK_MODE_MASK, val);
496
497 return 0;
498}
499
500static int adav80x_hw_params(struct snd_pcm_substream *substream,
501 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
502{
503 struct snd_soc_codec *codec = dai->codec;
504 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
505 unsigned int rate = params_rate(params);
506
507 if (rate * 256 != adav80x->sysclk)
508 return -EINVAL;
509
510 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
511 adav80x_set_playback_pcm_format(codec, dai,
512 params_format(params));
513 adav80x_set_dac_clock(codec, rate);
514 } else {
515 adav80x_set_capture_pcm_format(codec, dai,
516 params_format(params));
517 adav80x_set_adc_clock(codec, rate);
518 }
519 adav80x->rate = rate;
520 adav80x_set_deemph(codec);
521
522 return 0;
523}
524
525static int adav80x_set_sysclk(struct snd_soc_codec *codec,
526 int clk_id, unsigned int freq, int dir)
527{
528 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
529
530 if (dir == SND_SOC_CLOCK_IN) {
531 switch (clk_id) {
532 case ADAV80X_CLK_XIN:
533 case ADAV80X_CLK_XTAL:
534 case ADAV80X_CLK_MCLKI:
535 case ADAV80X_CLK_PLL1:
536 case ADAV80X_CLK_PLL2:
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 adav80x->sysclk = freq;
543
544 if (adav80x->clk_src != clk_id) {
545 unsigned int iclk_ctrl1, iclk_ctrl2;
546
547 adav80x->clk_src = clk_id;
548 if (clk_id == ADAV80X_CLK_XTAL)
549 clk_id = ADAV80X_CLK_XIN;
550
551 iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |
552 ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |
553 ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);
554 iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);
555
556 snd_soc_write(codec, ADAV80X_ICLK_CTRL1, iclk_ctrl1);
557 snd_soc_write(codec, ADAV80X_ICLK_CTRL2, iclk_ctrl2);
558
559 snd_soc_dapm_sync(&codec->dapm);
560 }
561 } else {
562 unsigned int mask;
563
564 switch (clk_id) {
565 case ADAV80X_CLK_SYSCLK1:
566 case ADAV80X_CLK_SYSCLK2:
567 case ADAV80X_CLK_SYSCLK3:
568 break;
569 default:
570 return -EINVAL;
571 }
572
573 clk_id -= ADAV80X_CLK_SYSCLK1;
574 mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);
575
576 if (freq == 0) {
577 snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, mask);
578 adav80x->sysclk_pd[clk_id] = true;
579 } else {
580 snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, 0);
581 adav80x->sysclk_pd[clk_id] = false;
582 }
583
584 if (adav80x->sysclk_pd[0])
585 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
586 else
587 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
588
589 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
590 snd_soc_dapm_disable_pin(&codec->dapm, "PLL2");
591 else
592 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
593
594 snd_soc_dapm_sync(&codec->dapm);
595 }
596
597 return 0;
598}
599
600static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
601 int source, unsigned int freq_in, unsigned int freq_out)
602{
603 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
604 unsigned int pll_ctrl1 = 0;
605 unsigned int pll_ctrl2 = 0;
606 unsigned int pll_src;
607
608 switch (source) {
609 case ADAV80X_PLL_SRC_XTAL:
610 case ADAV80X_PLL_SRC_XIN:
611 case ADAV80X_PLL_SRC_MCLKI:
612 break;
613 default:
614 return -EINVAL;
615 }
616
617 if (!freq_out)
618 return 0;
619
620 switch (freq_in) {
621 case 27000000:
622 break;
623 case 54000000:
624 if (source == ADAV80X_PLL_SRC_XIN) {
625 pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;
626 break;
627 }
628 default:
629 return -EINVAL;
630 }
631
632 if (freq_out > 12288000) {
633 pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);
634 freq_out /= 2;
635 }
636
637 /* freq_out = sample_rate * 256 */
638 switch (freq_out) {
639 case 8192000:
640 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);
641 break;
642 case 11289600:
643 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);
644 break;
645 case 12288000:
646 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);
647 break;
648 default:
649 return -EINVAL;
650 }
651
652 snd_soc_update_bits(codec, ADAV80X_PLL_CTRL1, ADAV80X_PLL_CTRL1_PLLDIV,
653 pll_ctrl1);
654 snd_soc_update_bits(codec, ADAV80X_PLL_CTRL2,
655 ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);
656
657 if (source != adav80x->pll_src) {
658 if (source == ADAV80X_PLL_SRC_MCLKI)
659 pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);
660 else
661 pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);
662
663 snd_soc_update_bits(codec, ADAV80X_PLL_CLK_SRC,
664 ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);
665
666 adav80x->pll_src = source;
667
668 snd_soc_dapm_sync(&codec->dapm);
669 }
670
671 return 0;
672}
673
674static int adav80x_set_bias_level(struct snd_soc_codec *codec,
675 enum snd_soc_bias_level level)
676{
677 unsigned int mask = ADAV80X_DAC_CTRL1_PD;
678
679 switch (level) {
680 case SND_SOC_BIAS_ON:
681 break;
682 case SND_SOC_BIAS_PREPARE:
683 break;
684 case SND_SOC_BIAS_STANDBY:
685 snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, 0x00);
686 break;
687 case SND_SOC_BIAS_OFF:
688 snd_soc_update_bits(codec, ADAV80X_DAC_CTRL1, mask, mask);
689 break;
690 }
691
692 codec->dapm.bias_level = level;
693 return 0;
694}
695
696/* Enforce the same sample rate on all audio interfaces */
697static int adav80x_dai_startup(struct snd_pcm_substream *substream,
698 struct snd_soc_dai *dai)
699{
700 struct snd_soc_codec *codec = dai->codec;
701 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
702
703 if (!codec->active || !adav80x->rate)
704 return 0;
705
706 return snd_pcm_hw_constraint_minmax(substream->runtime,
707 SNDRV_PCM_HW_PARAM_RATE, adav80x->rate, adav80x->rate);
708}
709
710static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
711 struct snd_soc_dai *dai)
712{
713 struct snd_soc_codec *codec = dai->codec;
714 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
715
716 if (!codec->active)
717 adav80x->rate = 0;
718}
719
720static const struct snd_soc_dai_ops adav80x_dai_ops = {
721 .set_fmt = adav80x_set_dai_fmt,
722 .hw_params = adav80x_hw_params,
723 .startup = adav80x_dai_startup,
724 .shutdown = adav80x_dai_shutdown,
725};
726
727#define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
728 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | \
729 SNDRV_PCM_RATE_96000)
730
731#define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
732
733#define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \
734 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
735
736static struct snd_soc_dai_driver adav80x_dais[] = {
737 {
738 .name = "adav80x-hifi",
739 .id = 0,
740 .playback = {
741 .stream_name = "HiFi Playback",
742 .channels_min = 2,
743 .channels_max = 2,
744 .rates = ADAV80X_PLAYBACK_RATES,
745 .formats = ADAV80X_FORMATS,
746 },
747 .capture = {
748 .stream_name = "HiFi Capture",
749 .channels_min = 2,
750 .channels_max = 2,
751 .rates = ADAV80X_CAPTURE_RATES,
752 .formats = ADAV80X_FORMATS,
753 },
754 .ops = &adav80x_dai_ops,
755 },
756 {
757 .name = "adav80x-aux",
758 .id = 1,
759 .playback = {
760 .stream_name = "Aux Playback",
761 .channels_min = 2,
762 .channels_max = 2,
763 .rates = ADAV80X_PLAYBACK_RATES,
764 .formats = ADAV80X_FORMATS,
765 },
766 .capture = {
767 .stream_name = "Aux Capture",
768 .channels_min = 2,
769 .channels_max = 2,
770 .rates = ADAV80X_CAPTURE_RATES,
771 .formats = ADAV80X_FORMATS,
772 },
773 .ops = &adav80x_dai_ops,
774 },
775};
776
777static int adav80x_probe(struct snd_soc_codec *codec)
778{
779 int ret;
780 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
781
782 ret = snd_soc_codec_set_cache_io(codec, 7, 9, adav80x->control_type);
783 if (ret) {
784 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
785 return ret;
786 }
787
788 /* Force PLLs on for SYSCLK output */
789 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
790 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
791
792 /* Power down S/PDIF receiver, since it is currently not supported */
793 snd_soc_write(codec, ADAV80X_PLL_OUTE, 0x20);
794 /* Disable DAC zero flag */
795 snd_soc_write(codec, ADAV80X_DAC_CTRL3, 0x6);
796
797 return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
798}
799
800static int adav80x_suspend(struct snd_soc_codec *codec, pm_message_t state)
801{
802 return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
803}
804
805static int adav80x_resume(struct snd_soc_codec *codec)
806{
807 adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
808 codec->cache_sync = 1;
809 snd_soc_cache_sync(codec);
810
811 return 0;
812}
813
814static int adav80x_remove(struct snd_soc_codec *codec)
815{
816 return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
817}
818
819static struct snd_soc_codec_driver adav80x_codec_driver = {
820 .probe = adav80x_probe,
821 .remove = adav80x_remove,
822 .suspend = adav80x_suspend,
823 .resume = adav80x_resume,
824 .set_bias_level = adav80x_set_bias_level,
825
826 .set_pll = adav80x_set_pll,
827 .set_sysclk = adav80x_set_sysclk,
828
829 .reg_word_size = sizeof(u8),
830 .reg_cache_size = ARRAY_SIZE(adav80x_default_regs),
831 .reg_cache_default = adav80x_default_regs,
832
833 .controls = adav80x_controls,
834 .num_controls = ARRAY_SIZE(adav80x_controls),
835 .dapm_widgets = adav80x_dapm_widgets,
836 .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),
837 .dapm_routes = adav80x_dapm_routes,
838 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
839};
840
841static int __devinit adav80x_bus_probe(struct device *dev,
842 enum snd_soc_control_type control_type)
843{
844 struct adav80x *adav80x;
845 int ret;
846
847 adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL);
848 if (!adav80x)
849 return -ENOMEM;
850
851 dev_set_drvdata(dev, adav80x);
852 adav80x->control_type = control_type;
853
854 ret = snd_soc_register_codec(dev, &adav80x_codec_driver,
855 adav80x_dais, ARRAY_SIZE(adav80x_dais));
856 if (ret)
857 kfree(adav80x);
858
859 return ret;
860}
861
862static int __devexit adav80x_bus_remove(struct device *dev)
863{
864 snd_soc_unregister_codec(dev);
865 kfree(dev_get_drvdata(dev));
866 return 0;
867}
868
869#if defined(CONFIG_SPI_MASTER)
870static int __devinit adav80x_spi_probe(struct spi_device *spi)
871{
872 return adav80x_bus_probe(&spi->dev, SND_SOC_SPI);
873}
874
875static int __devexit adav80x_spi_remove(struct spi_device *spi)
876{
877 return adav80x_bus_remove(&spi->dev);
878}
879
880static struct spi_driver adav80x_spi_driver = {
881 .driver = {
882 .name = "adav801",
883 .owner = THIS_MODULE,
884 },
885 .probe = adav80x_spi_probe,
886 .remove = __devexit_p(adav80x_spi_remove),
887};
888#endif
889
890#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
891static const struct i2c_device_id adav80x_id[] = {
892 { "adav803", 0 },
893 { }
894};
895MODULE_DEVICE_TABLE(i2c, adav80x_id);
896
897static int __devinit adav80x_i2c_probe(struct i2c_client *client,
898 const struct i2c_device_id *id)
899{
900 return adav80x_bus_probe(&client->dev, SND_SOC_I2C);
901}
902
903static int __devexit adav80x_i2c_remove(struct i2c_client *client)
904{
905 return adav80x_bus_remove(&client->dev);
906}
907
908static struct i2c_driver adav80x_i2c_driver = {
909 .driver = {
910 .name = "adav803",
911 .owner = THIS_MODULE,
912 },
913 .probe = adav80x_i2c_probe,
914 .remove = __devexit_p(adav80x_i2c_remove),
915 .id_table = adav80x_id,
916};
917#endif
918
919static int __init adav80x_init(void)
920{
921 int ret = 0;
922
923#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
924 ret = i2c_add_driver(&adav80x_i2c_driver);
925 if (ret)
926 return ret;
927#endif
928
929#if defined(CONFIG_SPI_MASTER)
930 ret = spi_register_driver(&adav80x_spi_driver);
931#endif
932
933 return ret;
934}
935module_init(adav80x_init);
936
937static void __exit adav80x_exit(void)
938{
939#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
940 i2c_del_driver(&adav80x_i2c_driver);
941#endif
942#if defined(CONFIG_SPI_MASTER)
943 spi_unregister_driver(&adav80x_spi_driver);
944#endif
945}
946module_exit(adav80x_exit);
947
948MODULE_DESCRIPTION("ASoC ADAV80x driver");
949MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
950MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");
951MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/adav80x.h b/sound/soc/codecs/adav80x.h
new file mode 100644
index 000000000000..adb0fc76d4e3
--- /dev/null
+++ b/sound/soc/codecs/adav80x.h
@@ -0,0 +1,35 @@
1/*
2 * header file for ADAV80X parts
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#ifndef _ADAV80X_H
10#define _ADAV80X_H
11
12enum adav80x_pll_src {
13 ADAV80X_PLL_SRC_XIN,
14 ADAV80X_PLL_SRC_XTAL,
15 ADAV80X_PLL_SRC_MCLKI,
16};
17
18enum adav80x_pll {
19 ADAV80X_PLL1 = 0,
20 ADAV80X_PLL2 = 1,
21};
22
23enum adav80x_clk_src {
24 ADAV80X_CLK_XIN = 0,
25 ADAV80X_CLK_MCLKI = 1,
26 ADAV80X_CLK_PLL1 = 2,
27 ADAV80X_CLK_PLL2 = 3,
28 ADAV80X_CLK_XTAL = 6,
29
30 ADAV80X_CLK_SYSCLK1 = 6,
31 ADAV80X_CLK_SYSCLK2 = 7,
32 ADAV80X_CLK_SYSCLK3 = 8,
33};
34
35#endif
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index ed96f247c2da..7a64e58cddc4 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -457,7 +457,7 @@ static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
457 .set_sysclk = ak4641_set_dai_sysclk, 457 .set_sysclk = ak4641_set_dai_sysclk,
458}; 458};
459 459
460struct snd_soc_dai_driver ak4641_dai[] = { 460static struct snd_soc_dai_driver ak4641_dai[] = {
461{ 461{
462 .name = "ak4641-hifi", 462 .name = "ak4641-hifi",
463 .id = 1, 463 .id = 1,
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 0206a17d7283..6cc8678f49f3 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -636,10 +636,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
636#endif /* CONFIG_PM */ 636#endif /* CONFIG_PM */
637 637
638/* 638/*
639 * ASoC codec device structure 639 * ASoC codec driver structure
640 *
641 * Assign this variable to the codec_dev field of the machine driver's
642 * snd_soc_device structure.
643 */ 640 */
644static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { 641static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
645 .probe = cs4270_probe, 642 .probe = cs4270_probe,
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 4173b67c94d1..ac65a2d36408 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1397,8 +1397,6 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
1397 if (freq == max98088->sysclk) 1397 if (freq == max98088->sysclk)
1398 return 0; 1398 return 0;
1399 1399
1400 max98088->sysclk = freq; /* remember current sysclk */
1401
1402 /* Setup clocks for slave mode, and using the PLL 1400 /* Setup clocks for slave mode, and using the PLL
1403 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) 1401 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1404 * 0x02 (when master clk is 20MHz to 30MHz).. 1402 * 0x02 (when master clk is 20MHz to 30MHz)..
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index e1d282d477da..668434d44303 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1517,8 +1517,6 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
1517 if (freq == max98095->sysclk) 1517 if (freq == max98095->sysclk)
1518 return 0; 1518 return 0;
1519 1519
1520 max98095->sysclk = freq; /* remember current sysclk */
1521
1522 /* Setup clocks for slave mode, and using the PLL 1520 /* Setup clocks for slave mode, and using the PLL
1523 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) 1521 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1524 * 0x02 (when master clk is 20MHz to 40MHz).. 1522 * 0x02 (when master clk is 20MHz to 40MHz)..
@@ -2261,11 +2259,11 @@ static int max98095_probe(struct snd_soc_codec *codec)
2261 2259
2262 ret = snd_soc_read(codec, M98095_0FF_REV_ID); 2260 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2263 if (ret < 0) { 2261 if (ret < 0) {
2264 dev_err(codec->dev, "Failed to read device revision: %d\n", 2262 dev_err(codec->dev, "Failure reading hardware revision: %d\n",
2265 ret); 2263 ret);
2266 goto err_access; 2264 goto err_access;
2267 } 2265 }
2268 dev_info(codec->dev, "revision %c\n", ret + 'A'); 2266 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
2269 2267
2270 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV); 2268 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
2271 2269
@@ -2342,8 +2340,8 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
2342 max98095->control_data = i2c; 2340 max98095->control_data = i2c;
2343 max98095->pdata = i2c->dev.platform_data; 2341 max98095->pdata = i2c->dev.platform_data;
2344 2342
2345 ret = snd_soc_register_codec(&i2c->dev, 2343 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095,
2346 &soc_codec_dev_max98095, &max98095_dai[0], 3); 2344 max98095_dai, ARRAY_SIZE(max98095_dai));
2347 if (ret < 0) 2345 if (ret < 0)
2348 kfree(max98095); 2346 kfree(max98095);
2349 return ret; 2347 return ret;
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
new file mode 100644
index 000000000000..409d89d1f34c
--- /dev/null
+++ b/sound/soc/codecs/sta32x.c
@@ -0,0 +1,917 @@
1/*
2 * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
3 *
4 * Copyright: 2011 Raumfeld GmbH
5 * Author: Johannes Stezenbach <js@sig21.net>
6 *
7 * based on code from:
8 * Wolfson Microelectronics PLC.
9 * Mark Brown <broonie@opensource.wolfsonmicro.com>
10 * Freescale Semiconductor, Inc.
11 * Timur Tabi <timur@freescale.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <linux/regulator/consumer.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38#include "sta32x.h"
39
40#define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
41 SNDRV_PCM_RATE_44100 | \
42 SNDRV_PCM_RATE_48000 | \
43 SNDRV_PCM_RATE_88200 | \
44 SNDRV_PCM_RATE_96000 | \
45 SNDRV_PCM_RATE_176400 | \
46 SNDRV_PCM_RATE_192000)
47
48#define STA32X_FORMATS \
49 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
50 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
51 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
52 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
54 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
55
56/* Power-up register defaults */
57static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = {
58 0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60,
59 0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69,
60 0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
62 0xc0, 0xf3, 0x33, 0x00, 0x0c,
63};
64
65/* regulator power supply names */
66static const char *sta32x_supply_names[] = {
67 "Vdda", /* analog supply, 3.3VV */
68 "Vdd3", /* digital supply, 3.3V */
69 "Vcc" /* power amp spply, 10V - 36V */
70};
71
72/* codec private data */
73struct sta32x_priv {
74 struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
75 struct snd_soc_codec *codec;
76
77 unsigned int mclk;
78 unsigned int format;
79};
80
81static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
82static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);
83static const DECLARE_TLV_DB_SCALE(tone_tlv, -120, 200, 0);
84
85static const char *sta32x_drc_ac[] = {
86 "Anti-Clipping", "Dynamic Range Compression" };
87static const char *sta32x_auto_eq_mode[] = {
88 "User", "Preset", "Loudness" };
89static const char *sta32x_auto_gc_mode[] = {
90 "User", "AC no clipping", "AC limited clipping (10%)",
91 "DRC nighttime listening mode" };
92static const char *sta32x_auto_xo_mode[] = {
93 "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", "200Hz",
94 "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", "340Hz", "360Hz" };
95static const char *sta32x_preset_eq_mode[] = {
96 "Flat", "Rock", "Soft Rock", "Jazz", "Classical", "Dance", "Pop", "Soft",
97 "Hard", "Party", "Vocal", "Hip-Hop", "Dialog", "Bass-boost #1",
98 "Bass-boost #2", "Bass-boost #3", "Loudness 1", "Loudness 2",
99 "Loudness 3", "Loudness 4", "Loudness 5", "Loudness 6", "Loudness 7",
100 "Loudness 8", "Loudness 9", "Loudness 10", "Loudness 11", "Loudness 12",
101 "Loudness 13", "Loudness 14", "Loudness 15", "Loudness 16" };
102static const char *sta32x_limiter_select[] = {
103 "Limiter Disabled", "Limiter #1", "Limiter #2" };
104static const char *sta32x_limiter_attack_rate[] = {
105 "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024",
106 "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752",
107 "0.0645", "0.0564", "0.0501", "0.0451" };
108static const char *sta32x_limiter_release_rate[] = {
109 "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",
110 "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",
111 "0.0134", "0.0117", "0.0110", "0.0104" };
112
113static const unsigned int sta32x_limiter_ac_attack_tlv[] = {
114 TLV_DB_RANGE_HEAD(2),
115 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
116 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),
117};
118
119static const unsigned int sta32x_limiter_ac_release_tlv[] = {
120 TLV_DB_RANGE_HEAD(5),
121 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
122 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
123 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
124 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
125 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
126};
127
128static const unsigned int sta32x_limiter_drc_attack_tlv[] = {
129 TLV_DB_RANGE_HEAD(3),
130 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
131 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
132 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
133};
134
135static const unsigned int sta32x_limiter_drc_release_tlv[] = {
136 TLV_DB_RANGE_HEAD(5),
137 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
138 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
139 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
140 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
141 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
142};
143
144static const struct soc_enum sta32x_drc_ac_enum =
145 SOC_ENUM_SINGLE(STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
146 2, sta32x_drc_ac);
147static const struct soc_enum sta32x_auto_eq_enum =
148 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT,
149 3, sta32x_auto_eq_mode);
150static const struct soc_enum sta32x_auto_gc_enum =
151 SOC_ENUM_SINGLE(STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT,
152 4, sta32x_auto_gc_mode);
153static const struct soc_enum sta32x_auto_xo_enum =
154 SOC_ENUM_SINGLE(STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT,
155 16, sta32x_auto_xo_mode);
156static const struct soc_enum sta32x_preset_eq_enum =
157 SOC_ENUM_SINGLE(STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT,
158 32, sta32x_preset_eq_mode);
159static const struct soc_enum sta32x_limiter_ch1_enum =
160 SOC_ENUM_SINGLE(STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT,
161 3, sta32x_limiter_select);
162static const struct soc_enum sta32x_limiter_ch2_enum =
163 SOC_ENUM_SINGLE(STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT,
164 3, sta32x_limiter_select);
165static const struct soc_enum sta32x_limiter_ch3_enum =
166 SOC_ENUM_SINGLE(STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT,
167 3, sta32x_limiter_select);
168static const struct soc_enum sta32x_limiter1_attack_rate_enum =
169 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxA_SHIFT,
170 16, sta32x_limiter_attack_rate);
171static const struct soc_enum sta32x_limiter2_attack_rate_enum =
172 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxA_SHIFT,
173 16, sta32x_limiter_attack_rate);
174static const struct soc_enum sta32x_limiter1_release_rate_enum =
175 SOC_ENUM_SINGLE(STA32X_L1AR, STA32X_LxR_SHIFT,
176 16, sta32x_limiter_release_rate);
177static const struct soc_enum sta32x_limiter2_release_rate_enum =
178 SOC_ENUM_SINGLE(STA32X_L2AR, STA32X_LxR_SHIFT,
179 16, sta32x_limiter_release_rate);
180
181/* byte array controls for setting biquad, mixer, scaling coefficients;
182 * for biquads all five coefficients need to be set in one go,
183 * mixer and pre/postscale coefs can be set individually;
184 * each coef is 24bit, the bytes are ordered in the same way
185 * as given in the STA32x data sheet (big endian; b1, b2, a1, a2, b0)
186 */
187
188static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_info *uinfo)
190{
191 int numcoef = kcontrol->private_value >> 16;
192 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
193 uinfo->count = 3 * numcoef;
194 return 0;
195}
196
197static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
198 struct snd_ctl_elem_value *ucontrol)
199{
200 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
201 int numcoef = kcontrol->private_value >> 16;
202 int index = kcontrol->private_value & 0xffff;
203 unsigned int cfud;
204 int i;
205
206 /* preserve reserved bits in STA32X_CFUD */
207 cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
208 /* chip documentation does not say if the bits are self clearing,
209 * so do it explicitly */
210 snd_soc_write(codec, STA32X_CFUD, cfud);
211
212 snd_soc_write(codec, STA32X_CFADDR2, index);
213 if (numcoef == 1)
214 snd_soc_write(codec, STA32X_CFUD, cfud | 0x04);
215 else if (numcoef == 5)
216 snd_soc_write(codec, STA32X_CFUD, cfud | 0x08);
217 else
218 return -EINVAL;
219 for (i = 0; i < 3 * numcoef; i++)
220 ucontrol->value.bytes.data[i] =
221 snd_soc_read(codec, STA32X_B1CF1 + i);
222
223 return 0;
224}
225
226static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol)
228{
229 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
230 int numcoef = kcontrol->private_value >> 16;
231 int index = kcontrol->private_value & 0xffff;
232 unsigned int cfud;
233 int i;
234
235 /* preserve reserved bits in STA32X_CFUD */
236 cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
237 /* chip documentation does not say if the bits are self clearing,
238 * so do it explicitly */
239 snd_soc_write(codec, STA32X_CFUD, cfud);
240
241 snd_soc_write(codec, STA32X_CFADDR2, index);
242 for (i = 0; i < 3 * numcoef; i++)
243 snd_soc_write(codec, STA32X_B1CF1 + i,
244 ucontrol->value.bytes.data[i]);
245 if (numcoef == 1)
246 snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
247 else if (numcoef == 5)
248 snd_soc_write(codec, STA32X_CFUD, cfud | 0x02);
249 else
250 return -EINVAL;
251
252 return 0;
253}
254
255#define SINGLE_COEF(xname, index) \
256{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
257 .info = sta32x_coefficient_info, \
258 .get = sta32x_coefficient_get,\
259 .put = sta32x_coefficient_put, \
260 .private_value = index | (1 << 16) }
261
262#define BIQUAD_COEFS(xname, index) \
263{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
264 .info = sta32x_coefficient_info, \
265 .get = sta32x_coefficient_get,\
266 .put = sta32x_coefficient_put, \
267 .private_value = index | (5 << 16) }
268
269static const struct snd_kcontrol_new sta32x_snd_controls[] = {
270SOC_SINGLE_TLV("Master Volume", STA32X_MVOL, 0, 0xff, 1, mvol_tlv),
271SOC_SINGLE("Master Switch", STA32X_MMUTE, 0, 1, 1),
272SOC_SINGLE("Ch1 Switch", STA32X_MMUTE, 1, 1, 1),
273SOC_SINGLE("Ch2 Switch", STA32X_MMUTE, 2, 1, 1),
274SOC_SINGLE("Ch3 Switch", STA32X_MMUTE, 3, 1, 1),
275SOC_SINGLE_TLV("Ch1 Volume", STA32X_C1VOL, 0, 0xff, 1, chvol_tlv),
276SOC_SINGLE_TLV("Ch2 Volume", STA32X_C2VOL, 0, 0xff, 1, chvol_tlv),
277SOC_SINGLE_TLV("Ch3 Volume", STA32X_C3VOL, 0, 0xff, 1, chvol_tlv),
278SOC_SINGLE("De-emphasis Filter Switch", STA32X_CONFD, STA32X_CONFD_DEMP_SHIFT, 1, 0),
279SOC_ENUM("Compressor/Limiter Switch", sta32x_drc_ac_enum),
280SOC_SINGLE("Miami Mode Switch", STA32X_CONFD, STA32X_CONFD_MME_SHIFT, 1, 0),
281SOC_SINGLE("Zero Cross Switch", STA32X_CONFE, STA32X_CONFE_ZCE_SHIFT, 1, 0),
282SOC_SINGLE("Soft Ramp Switch", STA32X_CONFE, STA32X_CONFE_SVE_SHIFT, 1, 0),
283SOC_SINGLE("Auto-Mute Switch", STA32X_CONFF, STA32X_CONFF_IDE_SHIFT, 1, 0),
284SOC_ENUM("Automode EQ", sta32x_auto_eq_enum),
285SOC_ENUM("Automode GC", sta32x_auto_gc_enum),
286SOC_ENUM("Automode XO", sta32x_auto_xo_enum),
287SOC_ENUM("Preset EQ", sta32x_preset_eq_enum),
288SOC_SINGLE("Ch1 Tone Control Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
289SOC_SINGLE("Ch2 Tone Control Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_TCB_SHIFT, 1, 0),
290SOC_SINGLE("Ch1 EQ Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
291SOC_SINGLE("Ch2 EQ Bypass Switch", STA32X_C2CFG, STA32X_CxCFG_EQBP_SHIFT, 1, 0),
292SOC_SINGLE("Ch1 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
293SOC_SINGLE("Ch2 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
294SOC_SINGLE("Ch3 Master Volume Bypass Switch", STA32X_C1CFG, STA32X_CxCFG_VBP_SHIFT, 1, 0),
295SOC_ENUM("Ch1 Limiter Select", sta32x_limiter_ch1_enum),
296SOC_ENUM("Ch2 Limiter Select", sta32x_limiter_ch2_enum),
297SOC_ENUM("Ch3 Limiter Select", sta32x_limiter_ch3_enum),
298SOC_SINGLE_TLV("Bass Tone Control", STA32X_TONE, STA32X_TONE_BTC_SHIFT, 15, 0, tone_tlv),
299SOC_SINGLE_TLV("Treble Tone Control", STA32X_TONE, STA32X_TONE_TTC_SHIFT, 15, 0, tone_tlv),
300SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),
301SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),
302SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
303SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
304
305/* depending on mode, the attack/release thresholds have
306 * two different enum definitions; provide both
307 */
308SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
309 16, 0, sta32x_limiter_ac_attack_tlv),
310SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
311 16, 0, sta32x_limiter_ac_attack_tlv),
312SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
313 16, 0, sta32x_limiter_ac_release_tlv),
314SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
315 16, 0, sta32x_limiter_ac_release_tlv),
316SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxA_SHIFT,
317 16, 0, sta32x_limiter_drc_attack_tlv),
318SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxA_SHIFT,
319 16, 0, sta32x_limiter_drc_attack_tlv),
320SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", STA32X_L1ATRT, STA32X_LxR_SHIFT,
321 16, 0, sta32x_limiter_drc_release_tlv),
322SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", STA32X_L2ATRT, STA32X_LxR_SHIFT,
323 16, 0, sta32x_limiter_drc_release_tlv),
324
325BIQUAD_COEFS("Ch1 - Biquad 1", 0),
326BIQUAD_COEFS("Ch1 - Biquad 2", 5),
327BIQUAD_COEFS("Ch1 - Biquad 3", 10),
328BIQUAD_COEFS("Ch1 - Biquad 4", 15),
329BIQUAD_COEFS("Ch2 - Biquad 1", 20),
330BIQUAD_COEFS("Ch2 - Biquad 2", 25),
331BIQUAD_COEFS("Ch2 - Biquad 3", 30),
332BIQUAD_COEFS("Ch2 - Biquad 4", 35),
333BIQUAD_COEFS("High-pass", 40),
334BIQUAD_COEFS("Low-pass", 45),
335SINGLE_COEF("Ch1 - Prescale", 50),
336SINGLE_COEF("Ch2 - Prescale", 51),
337SINGLE_COEF("Ch1 - Postscale", 52),
338SINGLE_COEF("Ch2 - Postscale", 53),
339SINGLE_COEF("Ch3 - Postscale", 54),
340SINGLE_COEF("Thermal warning - Postscale", 55),
341SINGLE_COEF("Ch1 - Mix 1", 56),
342SINGLE_COEF("Ch1 - Mix 2", 57),
343SINGLE_COEF("Ch2 - Mix 1", 58),
344SINGLE_COEF("Ch2 - Mix 2", 59),
345SINGLE_COEF("Ch3 - Mix 1", 60),
346SINGLE_COEF("Ch3 - Mix 2", 61),
347};
348
349static const struct snd_soc_dapm_widget sta32x_dapm_widgets[] = {
350SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
351SND_SOC_DAPM_OUTPUT("LEFT"),
352SND_SOC_DAPM_OUTPUT("RIGHT"),
353SND_SOC_DAPM_OUTPUT("SUB"),
354};
355
356static const struct snd_soc_dapm_route sta32x_dapm_routes[] = {
357 { "LEFT", NULL, "DAC" },
358 { "RIGHT", NULL, "DAC" },
359 { "SUB", NULL, "DAC" },
360};
361
362/* MCLK interpolation ratio per fs */
363static struct {
364 int fs;
365 int ir;
366} interpolation_ratios[] = {
367 { 32000, 0 },
368 { 44100, 0 },
369 { 48000, 0 },
370 { 88200, 1 },
371 { 96000, 1 },
372 { 176400, 2 },
373 { 192000, 2 },
374};
375
376/* MCLK to fs clock ratios */
377static struct {
378 int ratio;
379 int mcs;
380} mclk_ratios[3][7] = {
381 { { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 },
382 { 128, 4 }, { 576, 5 }, { 0, 0 } },
383 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
384 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
385};
386
387
388/**
389 * sta32x_set_dai_sysclk - configure MCLK
390 * @codec_dai: the codec DAI
391 * @clk_id: the clock ID (ignored)
392 * @freq: the MCLK input frequency
393 * @dir: the clock direction (ignored)
394 *
395 * The value of MCLK is used to determine which sample rates are supported
396 * by the STA32X, based on the mclk_ratios table.
397 *
398 * This function must be called by the machine driver's 'startup' function,
399 * otherwise the list of supported sample rates will not be available in
400 * time for ALSA.
401 *
402 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
403 * theoretically possible sample rates to be enabled. Call it again with a
404 * proper value set one the external clock is set (most probably you would do
405 * that from a machine's driver 'hw_param' hook.
406 */
407static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
408 int clk_id, unsigned int freq, int dir)
409{
410 struct snd_soc_codec *codec = codec_dai->codec;
411 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
412 int i, j, ir, fs;
413 unsigned int rates = 0;
414 unsigned int rate_min = -1;
415 unsigned int rate_max = 0;
416
417 pr_debug("mclk=%u\n", freq);
418 sta32x->mclk = freq;
419
420 if (sta32x->mclk) {
421 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
422 ir = interpolation_ratios[i].ir;
423 fs = interpolation_ratios[i].fs;
424 for (j = 0; mclk_ratios[ir][j].ratio; j++) {
425 if (mclk_ratios[ir][j].ratio * fs == freq) {
426 rates |= snd_pcm_rate_to_rate_bit(fs);
427 if (fs < rate_min)
428 rate_min = fs;
429 if (fs > rate_max)
430 rate_max = fs;
431 }
432 }
433 }
434 /* FIXME: soc should support a rate list */
435 rates &= ~SNDRV_PCM_RATE_KNOT;
436
437 if (!rates) {
438 dev_err(codec->dev, "could not find a valid sample rate\n");
439 return -EINVAL;
440 }
441 } else {
442 /* enable all possible rates */
443 rates = STA32X_RATES;
444 rate_min = 32000;
445 rate_max = 192000;
446 }
447
448 codec_dai->driver->playback.rates = rates;
449 codec_dai->driver->playback.rate_min = rate_min;
450 codec_dai->driver->playback.rate_max = rate_max;
451 return 0;
452}
453
454/**
455 * sta32x_set_dai_fmt - configure the codec for the selected audio format
456 * @codec_dai: the codec DAI
457 * @fmt: a SND_SOC_DAIFMT_x value indicating the data format
458 *
459 * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
460 * codec accordingly.
461 */
462static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
463 unsigned int fmt)
464{
465 struct snd_soc_codec *codec = codec_dai->codec;
466 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
467 u8 confb = snd_soc_read(codec, STA32X_CONFB);
468
469 pr_debug("\n");
470 confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM);
471
472 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
473 case SND_SOC_DAIFMT_CBS_CFS:
474 break;
475 default:
476 return -EINVAL;
477 }
478
479 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
480 case SND_SOC_DAIFMT_I2S:
481 case SND_SOC_DAIFMT_RIGHT_J:
482 case SND_SOC_DAIFMT_LEFT_J:
483 sta32x->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
484 break;
485 default:
486 return -EINVAL;
487 }
488
489 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
490 case SND_SOC_DAIFMT_NB_NF:
491 confb |= STA32X_CONFB_C2IM;
492 break;
493 case SND_SOC_DAIFMT_NB_IF:
494 confb |= STA32X_CONFB_C1IM;
495 break;
496 default:
497 return -EINVAL;
498 }
499
500 snd_soc_write(codec, STA32X_CONFB, confb);
501 return 0;
502}
503
504/**
505 * sta32x_hw_params - program the STA32X with the given hardware parameters.
506 * @substream: the audio stream
507 * @params: the hardware parameters to set
508 * @dai: the SOC DAI (ignored)
509 *
510 * This function programs the hardware with the values provided.
511 * Specifically, the sample rate and the data format.
512 */
513static int sta32x_hw_params(struct snd_pcm_substream *substream,
514 struct snd_pcm_hw_params *params,
515 struct snd_soc_dai *dai)
516{
517 struct snd_soc_pcm_runtime *rtd = substream->private_data;
518 struct snd_soc_codec *codec = rtd->codec;
519 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
520 unsigned int rate;
521 int i, mcs = -1, ir = -1;
522 u8 confa, confb;
523
524 rate = params_rate(params);
525 pr_debug("rate: %u\n", rate);
526 for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
527 if (interpolation_ratios[i].fs == rate)
528 ir = interpolation_ratios[i].ir;
529 if (ir < 0)
530 return -EINVAL;
531 for (i = 0; mclk_ratios[ir][i].ratio; i++)
532 if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk)
533 mcs = mclk_ratios[ir][i].mcs;
534 if (mcs < 0)
535 return -EINVAL;
536
537 confa = snd_soc_read(codec, STA32X_CONFA);
538 confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
539 confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);
540
541 confb = snd_soc_read(codec, STA32X_CONFB);
542 confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
543 switch (params_format(params)) {
544 case SNDRV_PCM_FORMAT_S24_LE:
545 case SNDRV_PCM_FORMAT_S24_BE:
546 case SNDRV_PCM_FORMAT_S24_3LE:
547 case SNDRV_PCM_FORMAT_S24_3BE:
548 pr_debug("24bit\n");
549 /* fall through */
550 case SNDRV_PCM_FORMAT_S32_LE:
551 case SNDRV_PCM_FORMAT_S32_BE:
552 pr_debug("24bit or 32bit\n");
553 switch (sta32x->format) {
554 case SND_SOC_DAIFMT_I2S:
555 confb |= 0x0;
556 break;
557 case SND_SOC_DAIFMT_LEFT_J:
558 confb |= 0x1;
559 break;
560 case SND_SOC_DAIFMT_RIGHT_J:
561 confb |= 0x2;
562 break;
563 }
564
565 break;
566 case SNDRV_PCM_FORMAT_S20_3LE:
567 case SNDRV_PCM_FORMAT_S20_3BE:
568 pr_debug("20bit\n");
569 switch (sta32x->format) {
570 case SND_SOC_DAIFMT_I2S:
571 confb |= 0x4;
572 break;
573 case SND_SOC_DAIFMT_LEFT_J:
574 confb |= 0x5;
575 break;
576 case SND_SOC_DAIFMT_RIGHT_J:
577 confb |= 0x6;
578 break;
579 }
580
581 break;
582 case SNDRV_PCM_FORMAT_S18_3LE:
583 case SNDRV_PCM_FORMAT_S18_3BE:
584 pr_debug("18bit\n");
585 switch (sta32x->format) {
586 case SND_SOC_DAIFMT_I2S:
587 confb |= 0x8;
588 break;
589 case SND_SOC_DAIFMT_LEFT_J:
590 confb |= 0x9;
591 break;
592 case SND_SOC_DAIFMT_RIGHT_J:
593 confb |= 0xa;
594 break;
595 }
596
597 break;
598 case SNDRV_PCM_FORMAT_S16_LE:
599 case SNDRV_PCM_FORMAT_S16_BE:
600 pr_debug("16bit\n");
601 switch (sta32x->format) {
602 case SND_SOC_DAIFMT_I2S:
603 confb |= 0x0;
604 break;
605 case SND_SOC_DAIFMT_LEFT_J:
606 confb |= 0xd;
607 break;
608 case SND_SOC_DAIFMT_RIGHT_J:
609 confb |= 0xe;
610 break;
611 }
612
613 break;
614 default:
615 return -EINVAL;
616 }
617
618 snd_soc_write(codec, STA32X_CONFA, confa);
619 snd_soc_write(codec, STA32X_CONFB, confb);
620 return 0;
621}
622
623/**
624 * sta32x_set_bias_level - DAPM callback
625 * @codec: the codec device
626 * @level: DAPM power level
627 *
628 * This is called by ALSA to put the codec into low power mode
629 * or to wake it up. If the codec is powered off completely
630 * all registers must be restored after power on.
631 */
632static int sta32x_set_bias_level(struct snd_soc_codec *codec,
633 enum snd_soc_bias_level level)
634{
635 int ret;
636 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
637
638 pr_debug("level = %d\n", level);
639 switch (level) {
640 case SND_SOC_BIAS_ON:
641 break;
642
643 case SND_SOC_BIAS_PREPARE:
644 /* Full power on */
645 snd_soc_update_bits(codec, STA32X_CONFF,
646 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
647 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
648 break;
649
650 case SND_SOC_BIAS_STANDBY:
651 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
652 ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
653 sta32x->supplies);
654 if (ret != 0) {
655 dev_err(codec->dev,
656 "Failed to enable supplies: %d\n", ret);
657 return ret;
658 }
659
660 snd_soc_cache_sync(codec);
661 }
662
663 /* Power up to mute */
664 /* FIXME */
665 snd_soc_update_bits(codec, STA32X_CONFF,
666 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
667 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
668
669 break;
670
671 case SND_SOC_BIAS_OFF:
672 /* The chip runs through the power down sequence for us. */
673 snd_soc_update_bits(codec, STA32X_CONFF,
674 STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
675 STA32X_CONFF_PWDN);
676 msleep(300);
677
678 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
679 sta32x->supplies);
680 break;
681 }
682 codec->dapm.bias_level = level;
683 return 0;
684}
685
686static struct snd_soc_dai_ops sta32x_dai_ops = {
687 .hw_params = sta32x_hw_params,
688 .set_sysclk = sta32x_set_dai_sysclk,
689 .set_fmt = sta32x_set_dai_fmt,
690};
691
692static struct snd_soc_dai_driver sta32x_dai = {
693 .name = "STA32X",
694 .playback = {
695 .stream_name = "Playback",
696 .channels_min = 2,
697 .channels_max = 2,
698 .rates = STA32X_RATES,
699 .formats = STA32X_FORMATS,
700 },
701 .ops = &sta32x_dai_ops,
702};
703
704#ifdef CONFIG_PM
705static int sta32x_suspend(struct snd_soc_codec *codec, pm_message_t state)
706{
707 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
708 return 0;
709}
710
711static int sta32x_resume(struct snd_soc_codec *codec)
712{
713 sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
714 return 0;
715}
716#else
717#define sta32x_suspend NULL
718#define sta32x_resume NULL
719#endif
720
721static int sta32x_probe(struct snd_soc_codec *codec)
722{
723 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
724 int i, ret = 0;
725
726 sta32x->codec = codec;
727
728 /* regulators */
729 for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
730 sta32x->supplies[i].supply = sta32x_supply_names[i];
731
732 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies),
733 sta32x->supplies);
734 if (ret != 0) {
735 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
736 goto err;
737 }
738
739 ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
740 sta32x->supplies);
741 if (ret != 0) {
742 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
743 goto err_get;
744 }
745
746 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
747 * then do the I2C transactions itself.
748 */
749 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
750 if (ret < 0) {
751 dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
752 return ret;
753 }
754
755 /* read reg reset values into cache */
756 for (i = 0; i < STA32X_REGISTER_COUNT; i++)
757 snd_soc_cache_write(codec, i, sta32x_regs[i]);
758
759 /* preserve reset values of reserved register bits */
760 snd_soc_cache_write(codec, STA32X_CONFC,
761 codec->hw_read(codec, STA32X_CONFC));
762 snd_soc_cache_write(codec, STA32X_CONFE,
763 codec->hw_read(codec, STA32X_CONFE));
764 snd_soc_cache_write(codec, STA32X_CONFF,
765 codec->hw_read(codec, STA32X_CONFF));
766 snd_soc_cache_write(codec, STA32X_MMUTE,
767 codec->hw_read(codec, STA32X_MMUTE));
768 snd_soc_cache_write(codec, STA32X_AUTO1,
769 codec->hw_read(codec, STA32X_AUTO1));
770 snd_soc_cache_write(codec, STA32X_AUTO3,
771 codec->hw_read(codec, STA32X_AUTO3));
772 snd_soc_cache_write(codec, STA32X_C3CFG,
773 codec->hw_read(codec, STA32X_C3CFG));
774
775 /* FIXME enable thermal warning adjustment and recovery */
776 snd_soc_update_bits(codec, STA32X_CONFA,
777 STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, 0);
778
779 /* FIXME select 2.1 mode */
780 snd_soc_update_bits(codec, STA32X_CONFF,
781 STA32X_CONFF_OCFG_MASK,
782 1 << STA32X_CONFF_OCFG_SHIFT);
783
784 /* FIXME channel to output mapping */
785 snd_soc_update_bits(codec, STA32X_C1CFG,
786 STA32X_CxCFG_OM_MASK,
787 0 << STA32X_CxCFG_OM_SHIFT);
788 snd_soc_update_bits(codec, STA32X_C2CFG,
789 STA32X_CxCFG_OM_MASK,
790 1 << STA32X_CxCFG_OM_SHIFT);
791 snd_soc_update_bits(codec, STA32X_C3CFG,
792 STA32X_CxCFG_OM_MASK,
793 2 << STA32X_CxCFG_OM_SHIFT);
794
795 sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
796 /* Bias level configuration will have done an extra enable */
797 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
798
799 return 0;
800
801err_get:
802 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
803err:
804 return ret;
805}
806
807static int sta32x_remove(struct snd_soc_codec *codec)
808{
809 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
810
811 regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
812 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
813
814 return 0;
815}
816
817static int sta32x_reg_is_volatile(struct snd_soc_codec *codec,
818 unsigned int reg)
819{
820 switch (reg) {
821 case STA32X_CONFA ... STA32X_L2ATRT:
822 case STA32X_MPCC1 ... STA32X_FDRC2:
823 return 0;
824 }
825 return 1;
826}
827
828static const struct snd_soc_codec_driver sta32x_codec = {
829 .probe = sta32x_probe,
830 .remove = sta32x_remove,
831 .suspend = sta32x_suspend,
832 .resume = sta32x_resume,
833 .reg_cache_size = STA32X_REGISTER_COUNT,
834 .reg_word_size = sizeof(u8),
835 .volatile_register = sta32x_reg_is_volatile,
836 .set_bias_level = sta32x_set_bias_level,
837 .controls = sta32x_snd_controls,
838 .num_controls = ARRAY_SIZE(sta32x_snd_controls),
839 .dapm_widgets = sta32x_dapm_widgets,
840 .num_dapm_widgets = ARRAY_SIZE(sta32x_dapm_widgets),
841 .dapm_routes = sta32x_dapm_routes,
842 .num_dapm_routes = ARRAY_SIZE(sta32x_dapm_routes),
843};
844
845static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
846 const struct i2c_device_id *id)
847{
848 struct sta32x_priv *sta32x;
849 int ret;
850
851 sta32x = kzalloc(sizeof(struct sta32x_priv), GFP_KERNEL);
852 if (!sta32x)
853 return -ENOMEM;
854
855 i2c_set_clientdata(i2c, sta32x);
856
857 ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
858 if (ret != 0) {
859 dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
860 return ret;
861 }
862
863 return 0;
864}
865
866static __devexit int sta32x_i2c_remove(struct i2c_client *client)
867{
868 struct sta32x_priv *sta32x = i2c_get_clientdata(client);
869 struct snd_soc_codec *codec = sta32x->codec;
870
871 if (codec)
872 sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
873
874 regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
875
876 if (codec) {
877 snd_soc_unregister_codec(&client->dev);
878 snd_soc_codec_set_drvdata(codec, NULL);
879 }
880
881 kfree(sta32x);
882 return 0;
883}
884
885static const struct i2c_device_id sta32x_i2c_id[] = {
886 { "sta326", 0 },
887 { "sta328", 0 },
888 { "sta329", 0 },
889 { }
890};
891MODULE_DEVICE_TABLE(i2c, sta32x_i2c_id);
892
893static struct i2c_driver sta32x_i2c_driver = {
894 .driver = {
895 .name = "sta32x",
896 .owner = THIS_MODULE,
897 },
898 .probe = sta32x_i2c_probe,
899 .remove = __devexit_p(sta32x_i2c_remove),
900 .id_table = sta32x_i2c_id,
901};
902
903static int __init sta32x_init(void)
904{
905 return i2c_add_driver(&sta32x_i2c_driver);
906}
907module_init(sta32x_init);
908
909static void __exit sta32x_exit(void)
910{
911 i2c_del_driver(&sta32x_i2c_driver);
912}
913module_exit(sta32x_exit);
914
915MODULE_DESCRIPTION("ASoC STA32X driver");
916MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
917MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sta32x.h b/sound/soc/codecs/sta32x.h
new file mode 100644
index 000000000000..b97ee5a75667
--- /dev/null
+++ b/sound/soc/codecs/sta32x.h
@@ -0,0 +1,210 @@
1/*
2 * Codec driver for ST STA32x 2.1-channel high-efficiency digital audio system
3 *
4 * Copyright: 2011 Raumfeld GmbH
5 * Author: Johannes Stezenbach <js@sig21.net>
6 *
7 * based on code from:
8 * Wolfson Microelectronics PLC.
9 * Mark Brown <broonie@opensource.wolfsonmicro.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#ifndef _ASOC_STA_32X_H
17#define _ASOC_STA_32X_H
18
19/* STA326 register addresses */
20
21#define STA32X_REGISTER_COUNT 0x2d
22
23#define STA32X_CONFA 0x00
24#define STA32X_CONFB 0x01
25#define STA32X_CONFC 0x02
26#define STA32X_CONFD 0x03
27#define STA32X_CONFE 0x04
28#define STA32X_CONFF 0x05
29#define STA32X_MMUTE 0x06
30#define STA32X_MVOL 0x07
31#define STA32X_C1VOL 0x08
32#define STA32X_C2VOL 0x09
33#define STA32X_C3VOL 0x0a
34#define STA32X_AUTO1 0x0b
35#define STA32X_AUTO2 0x0c
36#define STA32X_AUTO3 0x0d
37#define STA32X_C1CFG 0x0e
38#define STA32X_C2CFG 0x0f
39#define STA32X_C3CFG 0x10
40#define STA32X_TONE 0x11
41#define STA32X_L1AR 0x12
42#define STA32X_L1ATRT 0x13
43#define STA32X_L2AR 0x14
44#define STA32X_L2ATRT 0x15
45#define STA32X_CFADDR2 0x16
46#define STA32X_B1CF1 0x17
47#define STA32X_B1CF2 0x18
48#define STA32X_B1CF3 0x19
49#define STA32X_B2CF1 0x1a
50#define STA32X_B2CF2 0x1b
51#define STA32X_B2CF3 0x1c
52#define STA32X_A1CF1 0x1d
53#define STA32X_A1CF2 0x1e
54#define STA32X_A1CF3 0x1f
55#define STA32X_A2CF1 0x20
56#define STA32X_A2CF2 0x21
57#define STA32X_A2CF3 0x22
58#define STA32X_B0CF1 0x23
59#define STA32X_B0CF2 0x24
60#define STA32X_B0CF3 0x25
61#define STA32X_CFUD 0x26
62#define STA32X_MPCC1 0x27
63#define STA32X_MPCC2 0x28
64/* Reserved 0x29 */
65/* Reserved 0x2a */
66#define STA32X_Reserved 0x2a
67#define STA32X_FDRC1 0x2b
68#define STA32X_FDRC2 0x2c
69/* Reserved 0x2d */
70
71
72/* STA326 register field definitions */
73
74/* 0x00 CONFA */
75#define STA32X_CONFA_MCS_MASK 0x03
76#define STA32X_CONFA_MCS_SHIFT 0
77#define STA32X_CONFA_IR_MASK 0x18
78#define STA32X_CONFA_IR_SHIFT 3
79#define STA32X_CONFA_TWRB 0x20
80#define STA32X_CONFA_TWAB 0x40
81#define STA32X_CONFA_FDRB 0x80
82
83/* 0x01 CONFB */
84#define STA32X_CONFB_SAI_MASK 0x0f
85#define STA32X_CONFB_SAI_SHIFT 0
86#define STA32X_CONFB_SAIFB 0x10
87#define STA32X_CONFB_DSCKE 0x20
88#define STA32X_CONFB_C1IM 0x40
89#define STA32X_CONFB_C2IM 0x80
90
91/* 0x02 CONFC */
92#define STA32X_CONFC_OM_MASK 0x03
93#define STA32X_CONFC_OM_SHIFT 0
94#define STA32X_CONFC_CSZ_MASK 0x7c
95#define STA32X_CONFC_CSZ_SHIFT 2
96
97/* 0x03 CONFD */
98#define STA32X_CONFD_HPB 0x01
99#define STA32X_CONFD_HPB_SHIFT 0
100#define STA32X_CONFD_DEMP 0x02
101#define STA32X_CONFD_DEMP_SHIFT 1
102#define STA32X_CONFD_DSPB 0x04
103#define STA32X_CONFD_DSPB_SHIFT 2
104#define STA32X_CONFD_PSL 0x08
105#define STA32X_CONFD_PSL_SHIFT 3
106#define STA32X_CONFD_BQL 0x10
107#define STA32X_CONFD_BQL_SHIFT 4
108#define STA32X_CONFD_DRC 0x20
109#define STA32X_CONFD_DRC_SHIFT 5
110#define STA32X_CONFD_ZDE 0x40
111#define STA32X_CONFD_ZDE_SHIFT 6
112#define STA32X_CONFD_MME 0x80
113#define STA32X_CONFD_MME_SHIFT 7
114
115/* 0x04 CONFE */
116#define STA32X_CONFE_MPCV 0x01
117#define STA32X_CONFE_MPCV_SHIFT 0
118#define STA32X_CONFE_MPC 0x02
119#define STA32X_CONFE_MPC_SHIFT 1
120#define STA32X_CONFE_AME 0x08
121#define STA32X_CONFE_AME_SHIFT 3
122#define STA32X_CONFE_PWMS 0x10
123#define STA32X_CONFE_PWMS_SHIFT 4
124#define STA32X_CONFE_ZCE 0x40
125#define STA32X_CONFE_ZCE_SHIFT 6
126#define STA32X_CONFE_SVE 0x80
127#define STA32X_CONFE_SVE_SHIFT 7
128
129/* 0x05 CONFF */
130#define STA32X_CONFF_OCFG_MASK 0x03
131#define STA32X_CONFF_OCFG_SHIFT 0
132#define STA32X_CONFF_IDE 0x04
133#define STA32X_CONFF_IDE_SHIFT 3
134#define STA32X_CONFF_BCLE 0x08
135#define STA32X_CONFF_ECLE 0x20
136#define STA32X_CONFF_PWDN 0x40
137#define STA32X_CONFF_EAPD 0x80
138
139/* 0x06 MMUTE */
140#define STA32X_MMUTE_MMUTE 0x01
141
142/* 0x0b AUTO1 */
143#define STA32X_AUTO1_AMEQ_MASK 0x03
144#define STA32X_AUTO1_AMEQ_SHIFT 0
145#define STA32X_AUTO1_AMV_MASK 0xc0
146#define STA32X_AUTO1_AMV_SHIFT 2
147#define STA32X_AUTO1_AMGC_MASK 0x30
148#define STA32X_AUTO1_AMGC_SHIFT 4
149#define STA32X_AUTO1_AMPS 0x80
150
151/* 0x0c AUTO2 */
152#define STA32X_AUTO2_AMAME 0x01
153#define STA32X_AUTO2_AMAM_MASK 0x0e
154#define STA32X_AUTO2_AMAM_SHIFT 1
155#define STA32X_AUTO2_XO_MASK 0xf0
156#define STA32X_AUTO2_XO_SHIFT 4
157
158/* 0x0d AUTO3 */
159#define STA32X_AUTO3_PEQ_MASK 0x1f
160#define STA32X_AUTO3_PEQ_SHIFT 0
161
162/* 0x0e 0x0f 0x10 CxCFG */
163#define STA32X_CxCFG_TCB 0x01 /* only C1 and C2 */
164#define STA32X_CxCFG_TCB_SHIFT 0
165#define STA32X_CxCFG_EQBP 0x02 /* only C1 and C2 */
166#define STA32X_CxCFG_EQBP_SHIFT 1
167#define STA32X_CxCFG_VBP 0x03
168#define STA32X_CxCFG_VBP_SHIFT 2
169#define STA32X_CxCFG_BO 0x04
170#define STA32X_CxCFG_LS_MASK 0x30
171#define STA32X_CxCFG_LS_SHIFT 4
172#define STA32X_CxCFG_OM_MASK 0xc0
173#define STA32X_CxCFG_OM_SHIFT 6
174
175/* 0x11 TONE */
176#define STA32X_TONE_BTC_SHIFT 0
177#define STA32X_TONE_TTC_SHIFT 4
178
179/* 0x12 0x13 0x14 0x15 limiter attack/release */
180#define STA32X_LxA_SHIFT 0
181#define STA32X_LxR_SHIFT 4
182
183/* 0x26 CFUD */
184#define STA32X_CFUD_W1 0x01
185#define STA32X_CFUD_WA 0x02
186#define STA32X_CFUD_R1 0x04
187#define STA32X_CFUD_RA 0x08
188
189
190/* biquad filter coefficient table offsets */
191#define STA32X_C1_BQ_BASE 0
192#define STA32X_C2_BQ_BASE 20
193#define STA32X_CH_BQ_NUM 4
194#define STA32X_BQ_NUM_COEF 5
195#define STA32X_XO_HP_BQ_BASE 40
196#define STA32X_XO_LP_BQ_BASE 45
197#define STA32X_C1_PRESCALE 50
198#define STA32X_C2_PRESCALE 51
199#define STA32X_C1_POSTSCALE 52
200#define STA32X_C2_POSTSCALE 53
201#define STA32X_C3_POSTSCALE 54
202#define STA32X_TW_POSTSCALE 55
203#define STA32X_C1_MIX1 56
204#define STA32X_C1_MIX2 57
205#define STA32X_C2_MIX1 58
206#define STA32X_C2_MIX2 59
207#define STA32X_C3_MIX1 60
208#define STA32X_C3_MIX2 61
209
210#endif /* _ASOC_STA_32X_H */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 789453d44ec5..0963c4c7a83f 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -226,11 +226,13 @@ static const char *aic3x_adc_hpf[] =
226#define RDAC_ENUM 1 226#define RDAC_ENUM 1
227#define LHPCOM_ENUM 2 227#define LHPCOM_ENUM 2
228#define RHPCOM_ENUM 3 228#define RHPCOM_ENUM 3
229#define LINE1L_ENUM 4 229#define LINE1L_2_L_ENUM 4
230#define LINE1R_ENUM 5 230#define LINE1L_2_R_ENUM 5
231#define LINE2L_ENUM 6 231#define LINE1R_2_L_ENUM 6
232#define LINE2R_ENUM 7 232#define LINE1R_2_R_ENUM 7
233#define ADC_HPF_ENUM 8 233#define LINE2L_ENUM 8
234#define LINE2R_ENUM 9
235#define ADC_HPF_ENUM 10
234 236
235static const struct soc_enum aic3x_enum[] = { 237static const struct soc_enum aic3x_enum[] = {
236 SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux), 238 SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux),
@@ -238,6 +240,8 @@ static const struct soc_enum aic3x_enum[] = {
238 SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux), 240 SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux),
239 SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux), 241 SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux),
240 SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), 242 SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
243 SOC_ENUM_SINGLE(LINE1L_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
244 SOC_ENUM_SINGLE(LINE1R_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
241 SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), 245 SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
242 SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux), 246 SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
243 SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux), 247 SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
@@ -490,12 +494,16 @@ static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
490}; 494};
491 495
492/* Left Line1 Mux */ 496/* Left Line1 Mux */
493static const struct snd_kcontrol_new aic3x_left_line1_mux_controls = 497static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =
494SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_ENUM]); 498SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_L_ENUM]);
499static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls =
500SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_R_ENUM]);
495 501
496/* Right Line1 Mux */ 502/* Right Line1 Mux */
497static const struct snd_kcontrol_new aic3x_right_line1_mux_controls = 503static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls =
498SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_ENUM]); 504SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_R_ENUM]);
505static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls =
506SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_L_ENUM]);
499 507
500/* Left Line2 Mux */ 508/* Left Line2 Mux */
501static const struct snd_kcontrol_new aic3x_left_line2_mux_controls = 509static const struct snd_kcontrol_new aic3x_left_line2_mux_controls =
@@ -535,9 +543,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
535 &aic3x_left_pga_mixer_controls[0], 543 &aic3x_left_pga_mixer_controls[0],
536 ARRAY_SIZE(aic3x_left_pga_mixer_controls)), 544 ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
537 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, 545 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
538 &aic3x_left_line1_mux_controls), 546 &aic3x_left_line1l_mux_controls),
539 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0, 547 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
540 &aic3x_left_line1_mux_controls), 548 &aic3x_left_line1r_mux_controls),
541 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, 549 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
542 &aic3x_left_line2_mux_controls), 550 &aic3x_left_line2_mux_controls),
543 551
@@ -548,9 +556,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
548 &aic3x_right_pga_mixer_controls[0], 556 &aic3x_right_pga_mixer_controls[0],
549 ARRAY_SIZE(aic3x_right_pga_mixer_controls)), 557 ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
550 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0, 558 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
551 &aic3x_right_line1_mux_controls), 559 &aic3x_right_line1l_mux_controls),
552 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, 560 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
553 &aic3x_right_line1_mux_controls), 561 &aic3x_right_line1r_mux_controls),
554 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, 562 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
555 &aic3x_right_line2_mux_controls), 563 &aic3x_right_line2_mux_controls),
556 564
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 4c336636d4f5..cd63bba623df 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -954,9 +954,9 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
954 954
955/* 955/*
956 * MICGAIN volume control: 956 * MICGAIN volume control:
957 * from -6 to 30 dB in 6 dB steps 957 * from 6 to 30 dB in 6 dB steps
958 */ 958 */
959static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0); 959static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
960 960
961/* 961/*
962 * AFMGAIN volume control: 962 * AFMGAIN volume control:
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
new file mode 100644
index 000000000000..a2a09f85ea99
--- /dev/null
+++ b/sound/soc/codecs/wm8782.c
@@ -0,0 +1,80 @@
1/*
2 * sound/soc/codecs/wm8782.c
3 * simple, strap-pin configured 24bit 2ch ADC
4 *
5 * Copyright: 2011 Raumfeld GmbH
6 * Author: Johannes Stezenbach <js@sig21.net>
7 *
8 * based on ad73311.c
9 * Copyright: Analog Device Inc.
10 * Author: Cliff Cai <cliff.cai@analog.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/ac97_codec.h>
26#include <sound/initval.h>
27#include <sound/soc.h>
28
29static struct snd_soc_dai_driver wm8782_dai = {
30 .name = "wm8782",
31 .capture = {
32 .stream_name = "Capture",
33 .channels_min = 2,
34 .channels_max = 2,
35 /* For configurations with FSAMPEN=0 */
36 .rates = SNDRV_PCM_RATE_8000_48000,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S20_3LE |
39 SNDRV_PCM_FMTBIT_S24_LE,
40 },
41};
42
43static struct snd_soc_codec_driver soc_codec_dev_wm8782;
44
45static __devinit int wm8782_probe(struct platform_device *pdev)
46{
47 return snd_soc_register_codec(&pdev->dev,
48 &soc_codec_dev_wm8782, &wm8782_dai, 1);
49}
50
51static int __devexit wm8782_remove(struct platform_device *pdev)
52{
53 snd_soc_unregister_codec(&pdev->dev);
54 return 0;
55}
56
57static struct platform_driver wm8782_codec_driver = {
58 .driver = {
59 .name = "wm8782",
60 .owner = THIS_MODULE,
61 },
62 .probe = wm8782_probe,
63 .remove = wm8782_remove,
64};
65
66static int __init wm8782_init(void)
67{
68 return platform_driver_register(&wm8782_codec_driver);
69}
70module_init(wm8782_init);
71
72static void __exit wm8782_exit(void)
73{
74 platform_driver_unregister(&wm8782_codec_driver);
75}
76module_exit(wm8782_exit);
77
78MODULE_DESCRIPTION("ASoC WM8782 driver");
79MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
80MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 449ea09a193d..082040eda8a2 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -1167,6 +1167,7 @@ static int wm8900_resume(struct snd_soc_codec *codec)
1167 ret = wm8900_set_fll(codec, 0, fll_in, fll_out); 1167 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1168 if (ret != 0) { 1168 if (ret != 0) {
1169 dev_err(codec->dev, "Failed to restart FLL\n"); 1169 dev_err(codec->dev, "Failed to restart FLL\n");
1170 kfree(cache);
1170 return ret; 1171 return ret;
1171 } 1172 }
1172 } 1173 }
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 9b3bba4df5b3..b085575d4aa5 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2560,6 +2560,7 @@ static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2560static const struct i2c_device_id wm8904_i2c_id[] = { 2560static const struct i2c_device_id wm8904_i2c_id[] = {
2561 { "wm8904", WM8904 }, 2561 { "wm8904", WM8904 },
2562 { "wm8912", WM8912 }, 2562 { "wm8912", WM8912 },
2563 { "wm8918", WM8904 }, /* Actually a subset, updates to follow */
2563 { } 2564 { }
2564}; 2565};
2565MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); 2566MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
index e2ab4fac2819..423baa9be241 100644
--- a/sound/soc/codecs/wm8915.c
+++ b/sound/soc/codecs/wm8915.c
@@ -41,14 +41,12 @@
41#define HPOUT2L 4 41#define HPOUT2L 4
42#define HPOUT2R 8 42#define HPOUT2R 8
43 43
44#define WM8915_NUM_SUPPLIES 6 44#define WM8915_NUM_SUPPLIES 4
45static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = { 45static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
46 "DCVDD",
47 "DBVDD", 46 "DBVDD",
48 "AVDD1", 47 "AVDD1",
49 "AVDD2", 48 "AVDD2",
50 "CPVDD", 49 "CPVDD",
51 "MICVDD",
52}; 50};
53 51
54struct wm8915_priv { 52struct wm8915_priv {
@@ -57,6 +55,7 @@ struct wm8915_priv {
57 int ldo1ena; 55 int ldo1ena;
58 56
59 int sysclk; 57 int sysclk;
58 int sysclk_src;
60 59
61 int fll_src; 60 int fll_src;
62 int fll_fref; 61 int fll_fref;
@@ -76,6 +75,7 @@ struct wm8915_priv {
76 struct wm8915_pdata pdata; 75 struct wm8915_pdata pdata;
77 76
78 int rx_rate[WM8915_AIFS]; 77 int rx_rate[WM8915_AIFS];
78 int bclk_rate[WM8915_AIFS];
79 79
80 /* Platform dependant ReTune mobile configuration */ 80 /* Platform dependant ReTune mobile configuration */
81 int num_retune_mobile_texts; 81 int num_retune_mobile_texts;
@@ -113,8 +113,6 @@ WM8915_REGULATOR_EVENT(0)
113WM8915_REGULATOR_EVENT(1) 113WM8915_REGULATOR_EVENT(1)
114WM8915_REGULATOR_EVENT(2) 114WM8915_REGULATOR_EVENT(2)
115WM8915_REGULATOR_EVENT(3) 115WM8915_REGULATOR_EVENT(3)
116WM8915_REGULATOR_EVENT(4)
117WM8915_REGULATOR_EVENT(5)
118 116
119static const u16 wm8915_reg[WM8915_MAX_REGISTER] = { 117static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
120 [WM8915_SOFTWARE_RESET] = 0x8915, 118 [WM8915_SOFTWARE_RESET] = 0x8915,
@@ -1565,6 +1563,50 @@ static int wm8915_reset(struct snd_soc_codec *codec)
1565 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915); 1563 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
1566} 1564}
1567 1565
1566static const int bclk_divs[] = {
1567 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1568};
1569
1570static void wm8915_update_bclk(struct snd_soc_codec *codec)
1571{
1572 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1573 int aif, best, cur_val, bclk_rate, bclk_reg, i;
1574
1575 /* Don't bother if we're in a low frequency idle mode that
1576 * can't support audio.
1577 */
1578 if (wm8915->sysclk < 64000)
1579 return;
1580
1581 for (aif = 0; aif < WM8915_AIFS; aif++) {
1582 switch (aif) {
1583 case 0:
1584 bclk_reg = WM8915_AIF1_BCLK;
1585 break;
1586 case 1:
1587 bclk_reg = WM8915_AIF2_BCLK;
1588 break;
1589 }
1590
1591 bclk_rate = wm8915->bclk_rate[aif];
1592
1593 /* Pick a divisor for BCLK as close as we can get to ideal */
1594 best = 0;
1595 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1596 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1597 if (cur_val < 0) /* BCLK table is sorted */
1598 break;
1599 best = i;
1600 }
1601 bclk_rate = wm8915->sysclk / bclk_divs[best];
1602 dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1603 bclk_divs[best], bclk_rate);
1604
1605 snd_soc_update_bits(codec, bclk_reg,
1606 WM8915_AIF1_BCLK_DIV_MASK, best);
1607 }
1608}
1609
1568static int wm8915_set_bias_level(struct snd_soc_codec *codec, 1610static int wm8915_set_bias_level(struct snd_soc_codec *codec,
1569 enum snd_soc_bias_level level) 1611 enum snd_soc_bias_level level)
1570{ 1612{
@@ -1717,10 +1759,6 @@ static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1717 return 0; 1759 return 0;
1718} 1760}
1719 1761
1720static const int bclk_divs[] = {
1721 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1722};
1723
1724static const int dsp_divs[] = { 1762static const int dsp_divs[] = {
1725 48000, 32000, 16000, 8000 1763 48000, 32000, 16000, 8000
1726}; 1764};
@@ -1731,17 +1769,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1731{ 1769{
1732 struct snd_soc_codec *codec = dai->codec; 1770 struct snd_soc_codec *codec = dai->codec;
1733 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); 1771 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1734 int bits, i, bclk_rate, best, cur_val; 1772 int bits, i, bclk_rate;
1735 int aifdata = 0; 1773 int aifdata = 0;
1736 int bclk = 0;
1737 int lrclk = 0; 1774 int lrclk = 0;
1738 int dsp = 0; 1775 int dsp = 0;
1739 int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift; 1776 int aifdata_reg, lrclk_reg, dsp_shift;
1740
1741 if (!wm8915->sysclk) {
1742 dev_err(codec->dev, "SYSCLK not configured\n");
1743 return -EINVAL;
1744 }
1745 1777
1746 switch (dai->id) { 1778 switch (dai->id) {
1747 case 0: 1779 case 0:
@@ -1753,7 +1785,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1753 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1; 1785 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
1754 lrclk_reg = WM8915_AIF1_TX_LRCLK_1; 1786 lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
1755 } 1787 }
1756 bclk_reg = WM8915_AIF1_BCLK;
1757 dsp_shift = 0; 1788 dsp_shift = 0;
1758 break; 1789 break;
1759 case 1: 1790 case 1:
@@ -1765,7 +1796,6 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1765 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1; 1796 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
1766 lrclk_reg = WM8915_AIF2_TX_LRCLK_1; 1797 lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
1767 } 1798 }
1768 bclk_reg = WM8915_AIF2_BCLK;
1769 dsp_shift = WM8915_DSP2_DIV_SHIFT; 1799 dsp_shift = WM8915_DSP2_DIV_SHIFT;
1770 break; 1800 break;
1771 default: 1801 default:
@@ -1779,6 +1809,9 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1779 return bclk_rate; 1809 return bclk_rate;
1780 } 1810 }
1781 1811
1812 wm8915->bclk_rate[dai->id] = bclk_rate;
1813 wm8915->rx_rate[dai->id] = params_rate(params);
1814
1782 /* Needs looking at for TDM */ 1815 /* Needs looking at for TDM */
1783 bits = snd_pcm_format_width(params_format(params)); 1816 bits = snd_pcm_format_width(params_format(params));
1784 if (bits < 0) 1817 if (bits < 0)
@@ -1796,18 +1829,7 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1796 } 1829 }
1797 dsp |= i << dsp_shift; 1830 dsp |= i << dsp_shift;
1798 1831
1799 /* Pick a divisor for BCLK as close as we can get to ideal */ 1832 wm8915_update_bclk(codec);
1800 best = 0;
1801 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1802 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1803 if (cur_val < 0) /* BCLK table is sorted */
1804 break;
1805 best = i;
1806 }
1807 bclk_rate = wm8915->sysclk / bclk_divs[best];
1808 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1809 bclk_divs[best], bclk_rate);
1810 bclk |= best;
1811 1833
1812 lrclk = bclk_rate / params_rate(params); 1834 lrclk = bclk_rate / params_rate(params);
1813 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", 1835 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
@@ -1817,14 +1839,11 @@ static int wm8915_hw_params(struct snd_pcm_substream *substream,
1817 WM8915_AIF1TX_WL_MASK | 1839 WM8915_AIF1TX_WL_MASK |
1818 WM8915_AIF1TX_SLOT_LEN_MASK, 1840 WM8915_AIF1TX_SLOT_LEN_MASK,
1819 aifdata); 1841 aifdata);
1820 snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
1821 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK, 1842 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
1822 lrclk); 1843 lrclk);
1823 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2, 1844 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
1824 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp); 1845 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
1825 1846
1826 wm8915->rx_rate[dai->id] = params_rate(params);
1827
1828 return 0; 1847 return 0;
1829} 1848}
1830 1849
@@ -1838,6 +1857,9 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1838 int src; 1857 int src;
1839 int old; 1858 int old;
1840 1859
1860 if (freq == wm8915->sysclk && clk_id == wm8915->sysclk_src)
1861 return 0;
1862
1841 /* Disable SYSCLK while we reconfigure */ 1863 /* Disable SYSCLK while we reconfigure */
1842 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA; 1864 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA;
1843 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, 1865 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
@@ -1882,6 +1904,8 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1882 return -EINVAL; 1904 return -EINVAL;
1883 } 1905 }
1884 1906
1907 wm8915_update_bclk(codec);
1908
1885 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, 1909 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1886 WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK, 1910 WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
1887 src << WM8915_SYSCLK_SRC_SHIFT | ratediv); 1911 src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
@@ -1889,6 +1913,8 @@ static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1889 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, 1913 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1890 WM8915_SYSCLK_ENA, old); 1914 WM8915_SYSCLK_ENA, old);
1891 1915
1916 wm8915->sysclk_src = clk_id;
1917
1892 return 0; 1918 return 0;
1893} 1919}
1894 1920
@@ -2007,6 +2033,7 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2007 unsigned int Fref, unsigned int Fout) 2033 unsigned int Fref, unsigned int Fout)
2008{ 2034{
2009 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); 2035 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2036 struct i2c_client *i2c = to_i2c_client(codec->dev);
2010 struct _fll_div fll_div; 2037 struct _fll_div fll_div;
2011 unsigned long timeout; 2038 unsigned long timeout;
2012 int ret, reg; 2039 int ret, reg;
@@ -2093,7 +2120,18 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2093 else 2120 else
2094 timeout = msecs_to_jiffies(2); 2121 timeout = msecs_to_jiffies(2);
2095 2122
2096 wait_for_completion_timeout(&wm8915->fll_lock, timeout); 2123 /* Allow substantially longer if we've actually got the IRQ */
2124 if (i2c->irq)
2125 timeout *= 1000;
2126
2127 ret = wait_for_completion_timeout(&wm8915->fll_lock, timeout);
2128
2129 if (ret == 0 && i2c->irq) {
2130 dev_err(codec->dev, "Timed out waiting for FLL\n");
2131 ret = -ETIMEDOUT;
2132 } else {
2133 ret = 0;
2134 }
2097 2135
2098 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2136 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2099 2137
@@ -2101,7 +2139,7 @@ static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2101 wm8915->fll_fout = Fout; 2139 wm8915->fll_fout = Fout;
2102 wm8915->fll_src = source; 2140 wm8915->fll_src = source;
2103 2141
2104 return 0; 2142 return ret;
2105} 2143}
2106 2144
2107#ifdef CONFIG_GPIOLIB 2145#ifdef CONFIG_GPIOLIB
@@ -2293,6 +2331,12 @@ static void wm8915_micd(struct snd_soc_codec *codec)
2293 SND_JACK_HEADSET | SND_JACK_BTN_0); 2331 SND_JACK_HEADSET | SND_JACK_BTN_0);
2294 wm8915->jack_mic = true; 2332 wm8915->jack_mic = true;
2295 wm8915->detecting = false; 2333 wm8915->detecting = false;
2334
2335 /* Increase poll rate to give better responsiveness
2336 * for buttons */
2337 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2338 WM8915_MICD_RATE_MASK,
2339 5 << WM8915_MICD_RATE_SHIFT);
2296 } 2340 }
2297 2341
2298 /* If we detected a lower impedence during initial startup 2342 /* If we detected a lower impedence during initial startup
@@ -2333,15 +2377,17 @@ static void wm8915_micd(struct snd_soc_codec *codec)
2333 SND_JACK_HEADPHONE, 2377 SND_JACK_HEADPHONE,
2334 SND_JACK_HEADSET | 2378 SND_JACK_HEADSET |
2335 SND_JACK_BTN_0); 2379 SND_JACK_BTN_0);
2380
2381 /* Increase the detection rate a bit for
2382 * responsiveness.
2383 */
2384 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2385 WM8915_MICD_RATE_MASK,
2386 7 << WM8915_MICD_RATE_SHIFT);
2387
2336 wm8915->detecting = false; 2388 wm8915->detecting = false;
2337 } 2389 }
2338 } 2390 }
2339
2340 /* Increase poll rate to give better responsiveness for buttons */
2341 if (!wm8915->detecting)
2342 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2343 WM8915_MICD_RATE_MASK,
2344 5 << WM8915_MICD_RATE_SHIFT);
2345} 2391}
2346 2392
2347static irqreturn_t wm8915_irq(int irq, void *data) 2393static irqreturn_t wm8915_irq(int irq, void *data)
@@ -2383,6 +2429,20 @@ static irqreturn_t wm8915_irq(int irq, void *data)
2383 } 2429 }
2384} 2430}
2385 2431
2432static irqreturn_t wm8915_edge_irq(int irq, void *data)
2433{
2434 irqreturn_t ret = IRQ_NONE;
2435 irqreturn_t val;
2436
2437 do {
2438 val = wm8915_irq(irq, data);
2439 if (val != IRQ_NONE)
2440 ret = val;
2441 } while (val != IRQ_NONE);
2442
2443 return ret;
2444}
2445
2386static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec) 2446static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
2387{ 2447{
2388 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); 2448 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
@@ -2482,8 +2542,6 @@ static int wm8915_probe(struct snd_soc_codec *codec)
2482 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1; 2542 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
2483 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2; 2543 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
2484 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3; 2544 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
2485 wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
2486 wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
2487 2545
2488 /* This should really be moved into the regulator core */ 2546 /* This should really be moved into the regulator core */
2489 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) { 2547 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
@@ -2709,8 +2767,14 @@ static int wm8915_probe(struct snd_soc_codec *codec)
2709 2767
2710 irq_flags |= IRQF_ONESHOT; 2768 irq_flags |= IRQF_ONESHOT;
2711 2769
2712 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq, 2770 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2713 irq_flags, "wm8915", codec); 2771 ret = request_threaded_irq(i2c->irq, NULL,
2772 wm8915_edge_irq,
2773 irq_flags, "wm8915", codec);
2774 else
2775 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
2776 irq_flags, "wm8915", codec);
2777
2714 if (ret == 0) { 2778 if (ret == 0) {
2715 /* Unmask the interrupt */ 2779 /* Unmask the interrupt */
2716 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL, 2780 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 25580e3ee7c4..056daa0010f9 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -297,8 +297,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
297 if (ret) 297 if (ret)
298 goto error_ret; 298 goto error_ret;
299 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 299 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
300 if (ret)
301 goto error_ret;
302 300
303error_ret: 301error_ret:
304 return ret; 302 return ret;
@@ -683,8 +681,6 @@ static int wm8940_resume(struct snd_soc_codec *codec)
683 } 681 }
684 } 682 }
685 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 683 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
686 if (ret)
687 goto error_ret;
688 684
689error_ret: 685error_ret:
690 return ret; 686 return ret;
@@ -730,9 +726,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
730 if (ret) 726 if (ret)
731 return ret; 727 return ret;
732 ret = wm8940_add_widgets(codec); 728 ret = wm8940_add_widgets(codec);
733 if (ret)
734 return ret;
735
736 return ret; 729 return ret;
737} 730}
738 731
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 5e05eed96c38..8499c563a9b5 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -78,6 +78,8 @@ struct wm8962_priv {
78#ifdef CONFIG_GPIOLIB 78#ifdef CONFIG_GPIOLIB
79 struct gpio_chip gpio_chip; 79 struct gpio_chip gpio_chip;
80#endif 80#endif
81
82 int irq;
81}; 83};
82 84
83/* We can't use the same notifier block for more than one supply and 85/* We can't use the same notifier block for more than one supply and
@@ -1982,6 +1984,7 @@ static const unsigned int classd_tlv[] = {
1982 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 1984 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
1983 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), 1985 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
1984}; 1986};
1987static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1985 1988
1986/* The VU bits for the headphones are in a different register to the mute 1989/* The VU bits for the headphones are in a different register to the mute
1987 * bits and only take effect on the PGA if it is actually powered. 1990 * bits and only take effect on the PGA if it is actually powered.
@@ -2119,6 +2122,18 @@ SOC_SINGLE_TLV("HPMIXR MIXINR Volume", WM8962_HEADPHONE_MIXER_4,
2119 2122
2120SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0, 2123SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0,
2121 classd_tlv), 2124 classd_tlv),
2125
2126SOC_SINGLE("EQ Switch", WM8962_EQ1, WM8962_EQ_ENA_SHIFT, 1, 0),
2127SOC_DOUBLE_R_TLV("EQ1 Volume", WM8962_EQ2, WM8962_EQ22,
2128 WM8962_EQL_B1_GAIN_SHIFT, 31, 0, eq_tlv),
2129SOC_DOUBLE_R_TLV("EQ2 Volume", WM8962_EQ2, WM8962_EQ22,
2130 WM8962_EQL_B2_GAIN_SHIFT, 31, 0, eq_tlv),
2131SOC_DOUBLE_R_TLV("EQ3 Volume", WM8962_EQ2, WM8962_EQ22,
2132 WM8962_EQL_B3_GAIN_SHIFT, 31, 0, eq_tlv),
2133SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
2134 WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv),
2135SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
2136 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
2122}; 2137};
2123 2138
2124static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 2139static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2184,6 +2199,8 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
2184 struct snd_kcontrol *kcontrol, int event) 2199 struct snd_kcontrol *kcontrol, int event)
2185{ 2200{
2186 struct snd_soc_codec *codec = w->codec; 2201 struct snd_soc_codec *codec = w->codec;
2202 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2203 unsigned long timeout;
2187 int src; 2204 int src;
2188 int fll; 2205 int fll;
2189 2206
@@ -2203,9 +2220,19 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
2203 2220
2204 switch (event) { 2221 switch (event) {
2205 case SND_SOC_DAPM_PRE_PMU: 2222 case SND_SOC_DAPM_PRE_PMU:
2206 if (fll) 2223 if (fll) {
2207 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2224 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2208 WM8962_FLL_ENA, WM8962_FLL_ENA); 2225 WM8962_FLL_ENA, WM8962_FLL_ENA);
2226 if (wm8962->irq) {
2227 timeout = msecs_to_jiffies(5);
2228 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
2229 timeout);
2230
2231 if (timeout == 0)
2232 dev_err(codec->dev,
2233 "Timed out starting FLL\n");
2234 }
2235 }
2209 break; 2236 break;
2210 2237
2211 case SND_SOC_DAPM_POST_PMD: 2238 case SND_SOC_DAPM_POST_PMD:
@@ -2763,18 +2790,44 @@ static const int bclk_divs[] = {
2763 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32 2790 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
2764}; 2791};
2765 2792
2793static const int sysclk_rates[] = {
2794 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
2795};
2796
2766static void wm8962_configure_bclk(struct snd_soc_codec *codec) 2797static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2767{ 2798{
2768 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2799 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2769 int dspclk, i; 2800 int dspclk, i;
2770 int clocking2 = 0; 2801 int clocking2 = 0;
2802 int clocking4 = 0;
2771 int aif2 = 0; 2803 int aif2 = 0;
2772 2804
2773 if (!wm8962->bclk) { 2805 if (!wm8962->sysclk_rate) {
2774 dev_dbg(codec->dev, "No BCLK rate configured\n"); 2806 dev_dbg(codec->dev, "No SYSCLK configured\n");
2807 return;
2808 }
2809
2810 if (!wm8962->bclk || !wm8962->lrclk) {
2811 dev_dbg(codec->dev, "No audio clocks configured\n");
2775 return; 2812 return;
2776 } 2813 }
2777 2814
2815 for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
2816 if (sysclk_rates[i] == wm8962->sysclk_rate / wm8962->lrclk) {
2817 clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
2818 break;
2819 }
2820 }
2821
2822 if (i == ARRAY_SIZE(sysclk_rates)) {
2823 dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
2824 wm8962->sysclk_rate / wm8962->lrclk);
2825 return;
2826 }
2827
2828 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2829 WM8962_SYSCLK_RATE_MASK, clocking4);
2830
2778 dspclk = snd_soc_read(codec, WM8962_CLOCKING1); 2831 dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
2779 if (dspclk < 0) { 2832 if (dspclk < 0) {
2780 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk); 2833 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
@@ -2844,6 +2897,8 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2844 /* VMID 2*50k */ 2897 /* VMID 2*50k */
2845 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, 2898 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2846 WM8962_VMID_SEL_MASK, 0x80); 2899 WM8962_VMID_SEL_MASK, 0x80);
2900
2901 wm8962_configure_bclk(codec);
2847 break; 2902 break;
2848 2903
2849 case SND_SOC_BIAS_STANDBY: 2904 case SND_SOC_BIAS_STANDBY:
@@ -2876,8 +2931,6 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2876 snd_soc_update_bits(codec, WM8962_CLOCKING2, 2931 snd_soc_update_bits(codec, WM8962_CLOCKING2,
2877 WM8962_CLKREG_OVD, 2932 WM8962_CLKREG_OVD,
2878 WM8962_CLKREG_OVD); 2933 WM8962_CLKREG_OVD);
2879
2880 wm8962_configure_bclk(codec);
2881 } 2934 }
2882 2935
2883 /* VMID 2*250k */ 2936 /* VMID 2*250k */
@@ -2918,10 +2971,6 @@ static const struct {
2918 { 96000, 6 }, 2971 { 96000, 6 },
2919}; 2972};
2920 2973
2921static const int sysclk_rates[] = {
2922 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
2923};
2924
2925static int wm8962_hw_params(struct snd_pcm_substream *substream, 2974static int wm8962_hw_params(struct snd_pcm_substream *substream,
2926 struct snd_pcm_hw_params *params, 2975 struct snd_pcm_hw_params *params,
2927 struct snd_soc_dai *dai) 2976 struct snd_soc_dai *dai)
@@ -2929,41 +2978,27 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2929 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2978 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2930 struct snd_soc_codec *codec = rtd->codec; 2979 struct snd_soc_codec *codec = rtd->codec;
2931 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2980 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2932 int rate = params_rate(params);
2933 int i; 2981 int i;
2934 int aif0 = 0; 2982 int aif0 = 0;
2935 int adctl3 = 0; 2983 int adctl3 = 0;
2936 int clocking4 = 0;
2937 2984
2938 wm8962->bclk = snd_soc_params_to_bclk(params); 2985 wm8962->bclk = snd_soc_params_to_bclk(params);
2939 wm8962->lrclk = params_rate(params); 2986 wm8962->lrclk = params_rate(params);
2940 2987
2941 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { 2988 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
2942 if (sr_vals[i].rate == rate) { 2989 if (sr_vals[i].rate == wm8962->lrclk) {
2943 adctl3 |= sr_vals[i].reg; 2990 adctl3 |= sr_vals[i].reg;
2944 break; 2991 break;
2945 } 2992 }
2946 } 2993 }
2947 if (i == ARRAY_SIZE(sr_vals)) { 2994 if (i == ARRAY_SIZE(sr_vals)) {
2948 dev_err(codec->dev, "Unsupported rate %dHz\n", rate); 2995 dev_err(codec->dev, "Unsupported rate %dHz\n", wm8962->lrclk);
2949 return -EINVAL; 2996 return -EINVAL;
2950 } 2997 }
2951 2998
2952 if (rate % 8000 == 0) 2999 if (wm8962->lrclk % 8000 == 0)
2953 adctl3 |= WM8962_SAMPLE_RATE_INT_MODE; 3000 adctl3 |= WM8962_SAMPLE_RATE_INT_MODE;
2954 3001
2955 for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
2956 if (sysclk_rates[i] == wm8962->sysclk_rate / rate) {
2957 clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
2958 break;
2959 }
2960 }
2961 if (i == ARRAY_SIZE(sysclk_rates)) {
2962 dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
2963 wm8962->sysclk_rate / rate);
2964 return -EINVAL;
2965 }
2966
2967 switch (params_format(params)) { 3002 switch (params_format(params)) {
2968 case SNDRV_PCM_FORMAT_S16_LE: 3003 case SNDRV_PCM_FORMAT_S16_LE:
2969 break; 3004 break;
@@ -2985,8 +3020,6 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2985 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3, 3020 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
2986 WM8962_SAMPLE_RATE_INT_MODE | 3021 WM8962_SAMPLE_RATE_INT_MODE |
2987 WM8962_SAMPLE_RATE_MASK, adctl3); 3022 WM8962_SAMPLE_RATE_MASK, adctl3);
2988 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2989 WM8962_SYSCLK_RATE_MASK, clocking4);
2990 3023
2991 wm8962_configure_bclk(codec); 3024 wm8962_configure_bclk(codec);
2992 3025
@@ -3261,16 +3294,31 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3261 3294
3262 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 3295 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
3263 3296
3264 /* This should be a massive overestimate */ 3297 ret = 0;
3265 timeout = msecs_to_jiffies(1); 3298
3299 if (fll1 & WM8962_FLL_ENA) {
3300 /* This should be a massive overestimate but go even
3301 * higher if we'll error out
3302 */
3303 if (wm8962->irq)
3304 timeout = msecs_to_jiffies(5);
3305 else
3306 timeout = msecs_to_jiffies(1);
3307
3308 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
3309 timeout);
3266 3310
3267 wait_for_completion_timeout(&wm8962->fll_lock, timeout); 3311 if (timeout == 0 && wm8962->irq) {
3312 dev_err(codec->dev, "FLL lock timed out");
3313 ret = -ETIMEDOUT;
3314 }
3315 }
3268 3316
3269 wm8962->fll_fref = Fref; 3317 wm8962->fll_fref = Fref;
3270 wm8962->fll_fout = Fout; 3318 wm8962->fll_fout = Fout;
3271 wm8962->fll_src = source; 3319 wm8962->fll_src = source;
3272 3320
3273 return 0; 3321 return ret;
3274} 3322}
3275 3323
3276static int wm8962_mute(struct snd_soc_dai *dai, int mute) 3324static int wm8962_mute(struct snd_soc_dai *dai, int mute)
@@ -3731,8 +3779,6 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3731 int ret; 3779 int ret;
3732 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3780 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3733 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 3781 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
3734 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
3735 dev);
3736 u16 *reg_cache = codec->reg_cache; 3782 u16 *reg_cache = codec->reg_cache;
3737 int i, trigger, irq_pol; 3783 int i, trigger, irq_pol;
3738 bool dmicclk, dmicdat; 3784 bool dmicclk, dmicdat;
@@ -3871,6 +3917,9 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3871 snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME, 3917 snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
3872 WM8962_HPOUT_VU, WM8962_HPOUT_VU); 3918 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3873 3919
3920 /* Stereo control for EQ */
3921 snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0);
3922
3874 wm8962_add_widgets(codec); 3923 wm8962_add_widgets(codec);
3875 3924
3876 /* Save boards having to disable DMIC when not in use */ 3925 /* Save boards having to disable DMIC when not in use */
@@ -3899,7 +3948,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3899 wm8962_init_beep(codec); 3948 wm8962_init_beep(codec);
3900 wm8962_init_gpio(codec); 3949 wm8962_init_gpio(codec);
3901 3950
3902 if (i2c->irq) { 3951 if (wm8962->irq) {
3903 if (pdata && pdata->irq_active_low) { 3952 if (pdata && pdata->irq_active_low) {
3904 trigger = IRQF_TRIGGER_LOW; 3953 trigger = IRQF_TRIGGER_LOW;
3905 irq_pol = WM8962_IRQ_POL; 3954 irq_pol = WM8962_IRQ_POL;
@@ -3911,12 +3960,13 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3911 snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL, 3960 snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL,
3912 WM8962_IRQ_POL, irq_pol); 3961 WM8962_IRQ_POL, irq_pol);
3913 3962
3914 ret = request_threaded_irq(i2c->irq, NULL, wm8962_irq, 3963 ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
3915 trigger | IRQF_ONESHOT, 3964 trigger | IRQF_ONESHOT,
3916 "wm8962", codec); 3965 "wm8962", codec);
3917 if (ret != 0) { 3966 if (ret != 0) {
3918 dev_err(codec->dev, "Failed to request IRQ %d: %d\n", 3967 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
3919 i2c->irq, ret); 3968 wm8962->irq, ret);
3969 wm8962->irq = 0;
3920 /* Non-fatal */ 3970 /* Non-fatal */
3921 } else { 3971 } else {
3922 /* Enable some IRQs by default */ 3972 /* Enable some IRQs by default */
@@ -3941,12 +3991,10 @@ err:
3941static int wm8962_remove(struct snd_soc_codec *codec) 3991static int wm8962_remove(struct snd_soc_codec *codec)
3942{ 3992{
3943 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 3993 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3944 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
3945 dev);
3946 int i; 3994 int i;
3947 3995
3948 if (i2c->irq) 3996 if (wm8962->irq)
3949 free_irq(i2c->irq, codec); 3997 free_irq(wm8962->irq, codec);
3950 3998
3951 cancel_delayed_work_sync(&wm8962->mic_work); 3999 cancel_delayed_work_sync(&wm8962->mic_work);
3952 4000
@@ -3986,6 +4034,8 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
3986 4034
3987 i2c_set_clientdata(i2c, wm8962); 4035 i2c_set_clientdata(i2c, wm8962);
3988 4036
4037 wm8962->irq = i2c->irq;
4038
3989 ret = snd_soc_register_codec(&i2c->dev, 4039 ret = snd_soc_register_codec(&i2c->dev,
3990 &soc_codec_dev_wm8962, &wm8962_dai, 1); 4040 &soc_codec_dev_wm8962, &wm8962_dai, 1);
3991 if (ret < 0) 4041 if (ret < 0)
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
new file mode 100644
index 000000000000..17f04ec2b940
--- /dev/null
+++ b/sound/soc/codecs/wm8983.c
@@ -0,0 +1,1203 @@
1/*
2 * wm8983.c -- WM8983 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/spi/spi.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/initval.h>
26#include <sound/tlv.h>
27
28#include "wm8983.h"
29
30static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = {
31 [0x00] = 0x0000, /* R0 - Software Reset */
32 [0x01] = 0x0000, /* R1 - Power management 1 */
33 [0x02] = 0x0000, /* R2 - Power management 2 */
34 [0x03] = 0x0000, /* R3 - Power management 3 */
35 [0x04] = 0x0050, /* R4 - Audio Interface */
36 [0x05] = 0x0000, /* R5 - Companding control */
37 [0x06] = 0x0140, /* R6 - Clock Gen control */
38 [0x07] = 0x0000, /* R7 - Additional control */
39 [0x08] = 0x0000, /* R8 - GPIO Control */
40 [0x09] = 0x0000, /* R9 - Jack Detect Control 1 */
41 [0x0A] = 0x0000, /* R10 - DAC Control */
42 [0x0B] = 0x00FF, /* R11 - Left DAC digital Vol */
43 [0x0C] = 0x00FF, /* R12 - Right DAC digital vol */
44 [0x0D] = 0x0000, /* R13 - Jack Detect Control 2 */
45 [0x0E] = 0x0100, /* R14 - ADC Control */
46 [0x0F] = 0x00FF, /* R15 - Left ADC Digital Vol */
47 [0x10] = 0x00FF, /* R16 - Right ADC Digital Vol */
48 [0x12] = 0x012C, /* R18 - EQ1 - low shelf */
49 [0x13] = 0x002C, /* R19 - EQ2 - peak 1 */
50 [0x14] = 0x002C, /* R20 - EQ3 - peak 2 */
51 [0x15] = 0x002C, /* R21 - EQ4 - peak 3 */
52 [0x16] = 0x002C, /* R22 - EQ5 - high shelf */
53 [0x18] = 0x0032, /* R24 - DAC Limiter 1 */
54 [0x19] = 0x0000, /* R25 - DAC Limiter 2 */
55 [0x1B] = 0x0000, /* R27 - Notch Filter 1 */
56 [0x1C] = 0x0000, /* R28 - Notch Filter 2 */
57 [0x1D] = 0x0000, /* R29 - Notch Filter 3 */
58 [0x1E] = 0x0000, /* R30 - Notch Filter 4 */
59 [0x20] = 0x0038, /* R32 - ALC control 1 */
60 [0x21] = 0x000B, /* R33 - ALC control 2 */
61 [0x22] = 0x0032, /* R34 - ALC control 3 */
62 [0x23] = 0x0000, /* R35 - Noise Gate */
63 [0x24] = 0x0008, /* R36 - PLL N */
64 [0x25] = 0x000C, /* R37 - PLL K 1 */
65 [0x26] = 0x0093, /* R38 - PLL K 2 */
66 [0x27] = 0x00E9, /* R39 - PLL K 3 */
67 [0x29] = 0x0000, /* R41 - 3D control */
68 [0x2A] = 0x0000, /* R42 - OUT4 to ADC */
69 [0x2B] = 0x0000, /* R43 - Beep control */
70 [0x2C] = 0x0033, /* R44 - Input ctrl */
71 [0x2D] = 0x0010, /* R45 - Left INP PGA gain ctrl */
72 [0x2E] = 0x0010, /* R46 - Right INP PGA gain ctrl */
73 [0x2F] = 0x0100, /* R47 - Left ADC BOOST ctrl */
74 [0x30] = 0x0100, /* R48 - Right ADC BOOST ctrl */
75 [0x31] = 0x0002, /* R49 - Output ctrl */
76 [0x32] = 0x0001, /* R50 - Left mixer ctrl */
77 [0x33] = 0x0001, /* R51 - Right mixer ctrl */
78 [0x34] = 0x0039, /* R52 - LOUT1 (HP) volume ctrl */
79 [0x35] = 0x0039, /* R53 - ROUT1 (HP) volume ctrl */
80 [0x36] = 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */
81 [0x37] = 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */
82 [0x38] = 0x0001, /* R56 - OUT3 mixer ctrl */
83 [0x39] = 0x0001, /* R57 - OUT4 (MONO) mix ctrl */
84 [0x3D] = 0x0000 /* R61 - BIAS CTRL */
85};
86
87static const struct wm8983_reg_access {
88 u16 read; /* Mask of readable bits */
89 u16 write; /* Mask of writable bits */
90} wm8983_access_masks[WM8983_MAX_REGISTER + 1] = {
91 [0x00] = { 0x0000, 0x01FF }, /* R0 - Software Reset */
92 [0x01] = { 0x0000, 0x01FF }, /* R1 - Power management 1 */
93 [0x02] = { 0x0000, 0x01FF }, /* R2 - Power management 2 */
94 [0x03] = { 0x0000, 0x01EF }, /* R3 - Power management 3 */
95 [0x04] = { 0x0000, 0x01FF }, /* R4 - Audio Interface */
96 [0x05] = { 0x0000, 0x003F }, /* R5 - Companding control */
97 [0x06] = { 0x0000, 0x01FD }, /* R6 - Clock Gen control */
98 [0x07] = { 0x0000, 0x000F }, /* R7 - Additional control */
99 [0x08] = { 0x0000, 0x003F }, /* R8 - GPIO Control */
100 [0x09] = { 0x0000, 0x0070 }, /* R9 - Jack Detect Control 1 */
101 [0x0A] = { 0x0000, 0x004F }, /* R10 - DAC Control */
102 [0x0B] = { 0x0000, 0x01FF }, /* R11 - Left DAC digital Vol */
103 [0x0C] = { 0x0000, 0x01FF }, /* R12 - Right DAC digital vol */
104 [0x0D] = { 0x0000, 0x00FF }, /* R13 - Jack Detect Control 2 */
105 [0x0E] = { 0x0000, 0x01FB }, /* R14 - ADC Control */
106 [0x0F] = { 0x0000, 0x01FF }, /* R15 - Left ADC Digital Vol */
107 [0x10] = { 0x0000, 0x01FF }, /* R16 - Right ADC Digital Vol */
108 [0x12] = { 0x0000, 0x017F }, /* R18 - EQ1 - low shelf */
109 [0x13] = { 0x0000, 0x017F }, /* R19 - EQ2 - peak 1 */
110 [0x14] = { 0x0000, 0x017F }, /* R20 - EQ3 - peak 2 */
111 [0x15] = { 0x0000, 0x017F }, /* R21 - EQ4 - peak 3 */
112 [0x16] = { 0x0000, 0x007F }, /* R22 - EQ5 - high shelf */
113 [0x18] = { 0x0000, 0x01FF }, /* R24 - DAC Limiter 1 */
114 [0x19] = { 0x0000, 0x007F }, /* R25 - DAC Limiter 2 */
115 [0x1B] = { 0x0000, 0x01FF }, /* R27 - Notch Filter 1 */
116 [0x1C] = { 0x0000, 0x017F }, /* R28 - Notch Filter 2 */
117 [0x1D] = { 0x0000, 0x017F }, /* R29 - Notch Filter 3 */
118 [0x1E] = { 0x0000, 0x017F }, /* R30 - Notch Filter 4 */
119 [0x20] = { 0x0000, 0x01BF }, /* R32 - ALC control 1 */
120 [0x21] = { 0x0000, 0x00FF }, /* R33 - ALC control 2 */
121 [0x22] = { 0x0000, 0x01FF }, /* R34 - ALC control 3 */
122 [0x23] = { 0x0000, 0x000F }, /* R35 - Noise Gate */
123 [0x24] = { 0x0000, 0x001F }, /* R36 - PLL N */
124 [0x25] = { 0x0000, 0x003F }, /* R37 - PLL K 1 */
125 [0x26] = { 0x0000, 0x01FF }, /* R38 - PLL K 2 */
126 [0x27] = { 0x0000, 0x01FF }, /* R39 - PLL K 3 */
127 [0x29] = { 0x0000, 0x000F }, /* R41 - 3D control */
128 [0x2A] = { 0x0000, 0x01E7 }, /* R42 - OUT4 to ADC */
129 [0x2B] = { 0x0000, 0x01BF }, /* R43 - Beep control */
130 [0x2C] = { 0x0000, 0x0177 }, /* R44 - Input ctrl */
131 [0x2D] = { 0x0000, 0x01FF }, /* R45 - Left INP PGA gain ctrl */
132 [0x2E] = { 0x0000, 0x01FF }, /* R46 - Right INP PGA gain ctrl */
133 [0x2F] = { 0x0000, 0x0177 }, /* R47 - Left ADC BOOST ctrl */
134 [0x30] = { 0x0000, 0x0177 }, /* R48 - Right ADC BOOST ctrl */
135 [0x31] = { 0x0000, 0x007F }, /* R49 - Output ctrl */
136 [0x32] = { 0x0000, 0x01FF }, /* R50 - Left mixer ctrl */
137 [0x33] = { 0x0000, 0x01FF }, /* R51 - Right mixer ctrl */
138 [0x34] = { 0x0000, 0x01FF }, /* R52 - LOUT1 (HP) volume ctrl */
139 [0x35] = { 0x0000, 0x01FF }, /* R53 - ROUT1 (HP) volume ctrl */
140 [0x36] = { 0x0000, 0x01FF }, /* R54 - LOUT2 (SPK) volume ctrl */
141 [0x37] = { 0x0000, 0x01FF }, /* R55 - ROUT2 (SPK) volume ctrl */
142 [0x38] = { 0x0000, 0x004F }, /* R56 - OUT3 mixer ctrl */
143 [0x39] = { 0x0000, 0x00FF }, /* R57 - OUT4 (MONO) mix ctrl */
144 [0x3D] = { 0x0000, 0x0100 } /* R61 - BIAS CTRL */
145};
146
147/* vol/gain update regs */
148static const int vol_update_regs[] = {
149 WM8983_LEFT_DAC_DIGITAL_VOL,
150 WM8983_RIGHT_DAC_DIGITAL_VOL,
151 WM8983_LEFT_ADC_DIGITAL_VOL,
152 WM8983_RIGHT_ADC_DIGITAL_VOL,
153 WM8983_LOUT1_HP_VOLUME_CTRL,
154 WM8983_ROUT1_HP_VOLUME_CTRL,
155 WM8983_LOUT2_SPK_VOLUME_CTRL,
156 WM8983_ROUT2_SPK_VOLUME_CTRL,
157 WM8983_LEFT_INP_PGA_GAIN_CTRL,
158 WM8983_RIGHT_INP_PGA_GAIN_CTRL
159};
160
161struct wm8983_priv {
162 enum snd_soc_control_type control_type;
163 u32 sysclk;
164 u32 bclk;
165};
166
167static const struct {
168 int div;
169 int ratio;
170} fs_ratios[] = {
171 { 10, 128 },
172 { 15, 192 },
173 { 20, 256 },
174 { 30, 384 },
175 { 40, 512 },
176 { 60, 768 },
177 { 80, 1024 },
178 { 120, 1536 }
179};
180
181static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };
182
183static const int bclk_divs[] = {
184 1, 2, 4, 8, 16, 32
185};
186
187static int eqmode_get(struct snd_kcontrol *kcontrol,
188 struct snd_ctl_elem_value *ucontrol);
189static int eqmode_put(struct snd_kcontrol *kcontrol,
190 struct snd_ctl_elem_value *ucontrol);
191
192static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
193static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1);
194static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
195static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0);
196static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0);
197static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0);
198static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0);
199static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0);
200static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0);
201static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);
202static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
203static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0);
204static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
205static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
206
207static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
208static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8983_ALC_CONTROL_1, 7,
209 alc_sel_text);
210
211static const char *alc_mode_text[] = { "ALC", "Limiter" };
212static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8983_ALC_CONTROL_3, 8,
213 alc_mode_text);
214
215static const char *filter_mode_text[] = { "Audio", "Application" };
216static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8983_ADC_CONTROL, 7,
217 filter_mode_text);
218
219static const char *eq_bw_text[] = { "Narrow", "Wide" };
220static const char *eqmode_text[] = { "Capture", "Playback" };
221static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
222
223static const char *eq1_cutoff_text[] = {
224 "80Hz", "105Hz", "135Hz", "175Hz"
225};
226static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8983_EQ1_LOW_SHELF, 5,
227 eq1_cutoff_text);
228static const char *eq2_cutoff_text[] = {
229 "230Hz", "300Hz", "385Hz", "500Hz"
230};
231static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8983_EQ2_PEAK_1, 8, eq_bw_text);
232static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8983_EQ2_PEAK_1, 5,
233 eq2_cutoff_text);
234static const char *eq3_cutoff_text[] = {
235 "650Hz", "850Hz", "1.1kHz", "1.4kHz"
236};
237static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8983_EQ3_PEAK_2, 8, eq_bw_text);
238static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8983_EQ3_PEAK_2, 5,
239 eq3_cutoff_text);
240static const char *eq4_cutoff_text[] = {
241 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
242};
243static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8983_EQ4_PEAK_3, 8, eq_bw_text);
244static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8983_EQ4_PEAK_3, 5,
245 eq4_cutoff_text);
246static const char *eq5_cutoff_text[] = {
247 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
248};
249static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,
250 eq5_cutoff_text);
251
252static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
253static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
254
255static const char *depth_3d_text[] = {
256 "Off",
257 "6.67%",
258 "13.3%",
259 "20%",
260 "26.7%",
261 "33.3%",
262 "40%",
263 "46.6%",
264 "53.3%",
265 "60%",
266 "66.7%",
267 "73.3%",
268 "80%",
269 "86.7%",
270 "93.3%",
271 "100%"
272};
273static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8983_3D_CONTROL, 0,
274 depth_3d_text);
275
276static const struct snd_kcontrol_new wm8983_snd_controls[] = {
277 SOC_SINGLE("Digital Loopback Switch", WM8983_COMPANDING_CONTROL,
278 0, 1, 0),
279
280 SOC_ENUM("ALC Capture Function", alc_sel),
281 SOC_SINGLE_TLV("ALC Capture Max Volume", WM8983_ALC_CONTROL_1,
282 3, 7, 0, alc_max_tlv),
283 SOC_SINGLE_TLV("ALC Capture Min Volume", WM8983_ALC_CONTROL_1,
284 0, 7, 0, alc_min_tlv),
285 SOC_SINGLE_TLV("ALC Capture Target Volume", WM8983_ALC_CONTROL_2,
286 0, 15, 0, alc_tar_tlv),
287 SOC_SINGLE("ALC Capture Attack", WM8983_ALC_CONTROL_3, 0, 10, 0),
288 SOC_SINGLE("ALC Capture Hold", WM8983_ALC_CONTROL_2, 4, 10, 0),
289 SOC_SINGLE("ALC Capture Decay", WM8983_ALC_CONTROL_3, 4, 10, 0),
290 SOC_ENUM("ALC Mode", alc_mode),
291 SOC_SINGLE("ALC Capture NG Switch", WM8983_NOISE_GATE,
292 3, 1, 0),
293 SOC_SINGLE("ALC Capture NG Threshold", WM8983_NOISE_GATE,
294 0, 7, 1),
295
296 SOC_DOUBLE_R_TLV("Capture Volume", WM8983_LEFT_ADC_DIGITAL_VOL,
297 WM8983_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv),
298 SOC_DOUBLE_R("Capture PGA ZC Switch", WM8983_LEFT_INP_PGA_GAIN_CTRL,
299 WM8983_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0),
300 SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8983_LEFT_INP_PGA_GAIN_CTRL,
301 WM8983_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv),
302
303 SOC_DOUBLE_R_TLV("Capture PGA Boost Volume",
304 WM8983_LEFT_ADC_BOOST_CTRL, WM8983_RIGHT_ADC_BOOST_CTRL,
305 8, 1, 0, pga_boost_tlv),
306
307 SOC_DOUBLE("ADC Inversion Switch", WM8983_ADC_CONTROL, 0, 1, 1, 0),
308 SOC_SINGLE("ADC 128x Oversampling Switch", WM8983_ADC_CONTROL, 8, 1, 0),
309
310 SOC_DOUBLE_R_TLV("Playback Volume", WM8983_LEFT_DAC_DIGITAL_VOL,
311 WM8983_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv),
312
313 SOC_SINGLE("DAC Playback Limiter Switch", WM8983_DAC_LIMITER_1, 8, 1, 0),
314 SOC_SINGLE("DAC Playback Limiter Decay", WM8983_DAC_LIMITER_1, 4, 10, 0),
315 SOC_SINGLE("DAC Playback Limiter Attack", WM8983_DAC_LIMITER_1, 0, 11, 0),
316 SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8983_DAC_LIMITER_2,
317 4, 7, 1, lim_thresh_tlv),
318 SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8983_DAC_LIMITER_2,
319 0, 12, 0, lim_boost_tlv),
320 SOC_DOUBLE("DAC Inversion Switch", WM8983_DAC_CONTROL, 0, 1, 1, 0),
321 SOC_SINGLE("DAC Auto Mute Switch", WM8983_DAC_CONTROL, 2, 1, 0),
322 SOC_SINGLE("DAC 128x Oversampling Switch", WM8983_DAC_CONTROL, 3, 1, 0),
323
324 SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8983_LOUT1_HP_VOLUME_CTRL,
325 WM8983_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv),
326 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8983_LOUT1_HP_VOLUME_CTRL,
327 WM8983_ROUT1_HP_VOLUME_CTRL, 7, 1, 0),
328 SOC_DOUBLE_R("Headphone Switch", WM8983_LOUT1_HP_VOLUME_CTRL,
329 WM8983_ROUT1_HP_VOLUME_CTRL, 6, 1, 1),
330
331 SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8983_LOUT2_SPK_VOLUME_CTRL,
332 WM8983_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv),
333 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,
334 WM8983_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0),
335 SOC_DOUBLE_R("Speaker Switch", WM8983_LOUT2_SPK_VOLUME_CTRL,
336 WM8983_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1),
337
338 SOC_SINGLE("OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
339 6, 1, 1),
340
341 SOC_SINGLE("OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
342 6, 1, 1),
343
344 SOC_SINGLE("High Pass Filter Switch", WM8983_ADC_CONTROL, 8, 1, 0),
345 SOC_ENUM("High Pass Filter Mode", filter_mode),
346 SOC_SINGLE("High Pass Filter Cutoff", WM8983_ADC_CONTROL, 4, 7, 0),
347
348 SOC_DOUBLE_R_TLV("Aux Bypass Volume",
349 WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 6, 7, 0,
350 aux_tlv),
351
352 SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
353 WM8983_LEFT_MIXER_CTRL, WM8983_RIGHT_MIXER_CTRL, 2, 7, 0,
354 bypass_tlv),
355
356 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
357 SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
358 SOC_SINGLE_TLV("EQ1 Volume", WM8983_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
359 SOC_ENUM("EQ2 Bandwith", eq2_bw),
360 SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
361 SOC_SINGLE_TLV("EQ2 Volume", WM8983_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
362 SOC_ENUM("EQ3 Bandwith", eq3_bw),
363 SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
364 SOC_SINGLE_TLV("EQ3 Volume", WM8983_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
365 SOC_ENUM("EQ4 Bandwith", eq4_bw),
366 SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
367 SOC_SINGLE_TLV("EQ4 Volume", WM8983_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
368 SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
369 SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
370
371 SOC_ENUM("3D Depth", depth_3d),
372
373 SOC_ENUM("Speaker Mode", speaker_mode)
374};
375
376static const struct snd_kcontrol_new left_out_mixer[] = {
377 SOC_DAPM_SINGLE("Line Switch", WM8983_LEFT_MIXER_CTRL, 1, 1, 0),
378 SOC_DAPM_SINGLE("Aux Switch", WM8983_LEFT_MIXER_CTRL, 5, 1, 0),
379 SOC_DAPM_SINGLE("PCM Switch", WM8983_LEFT_MIXER_CTRL, 0, 1, 0),
380};
381
382static const struct snd_kcontrol_new right_out_mixer[] = {
383 SOC_DAPM_SINGLE("Line Switch", WM8983_RIGHT_MIXER_CTRL, 1, 1, 0),
384 SOC_DAPM_SINGLE("Aux Switch", WM8983_RIGHT_MIXER_CTRL, 5, 1, 0),
385 SOC_DAPM_SINGLE("PCM Switch", WM8983_RIGHT_MIXER_CTRL, 0, 1, 0),
386};
387
388static const struct snd_kcontrol_new left_input_mixer[] = {
389 SOC_DAPM_SINGLE("L2 Switch", WM8983_INPUT_CTRL, 2, 1, 0),
390 SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 1, 1, 0),
391 SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 0, 1, 0),
392};
393
394static const struct snd_kcontrol_new right_input_mixer[] = {
395 SOC_DAPM_SINGLE("R2 Switch", WM8983_INPUT_CTRL, 6, 1, 0),
396 SOC_DAPM_SINGLE("MicN Switch", WM8983_INPUT_CTRL, 5, 1, 0),
397 SOC_DAPM_SINGLE("MicP Switch", WM8983_INPUT_CTRL, 4, 1, 0),
398};
399
400static const struct snd_kcontrol_new left_boost_mixer[] = {
401 SOC_DAPM_SINGLE_TLV("L2 Volume", WM8983_LEFT_ADC_BOOST_CTRL,
402 4, 7, 0, boost_tlv),
403 SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8983_LEFT_ADC_BOOST_CTRL,
404 0, 7, 0, boost_tlv)
405};
406
407static const struct snd_kcontrol_new out3_mixer[] = {
408 SOC_DAPM_SINGLE("LMIX2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
409 1, 1, 0),
410 SOC_DAPM_SINGLE("LDAC2OUT3 Switch", WM8983_OUT3_MIXER_CTRL,
411 0, 1, 0),
412};
413
414static const struct snd_kcontrol_new out4_mixer[] = {
415 SOC_DAPM_SINGLE("LMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
416 4, 1, 0),
417 SOC_DAPM_SINGLE("RMIX2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
418 1, 1, 0),
419 SOC_DAPM_SINGLE("LDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
420 3, 1, 0),
421 SOC_DAPM_SINGLE("RDAC2OUT4 Switch", WM8983_OUT4_MONO_MIX_CTRL,
422 0, 1, 0),
423};
424
425static const struct snd_kcontrol_new right_boost_mixer[] = {
426 SOC_DAPM_SINGLE_TLV("R2 Volume", WM8983_RIGHT_ADC_BOOST_CTRL,
427 4, 7, 0, boost_tlv),
428 SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8983_RIGHT_ADC_BOOST_CTRL,
429 0, 7, 0, boost_tlv)
430};
431
432static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = {
433 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8983_POWER_MANAGEMENT_3,
434 0, 0),
435 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8983_POWER_MANAGEMENT_3,
436 1, 0),
437 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8983_POWER_MANAGEMENT_2,
438 0, 0),
439 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8983_POWER_MANAGEMENT_2,
440 1, 0),
441
442 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8983_POWER_MANAGEMENT_3,
443 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
444 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8983_POWER_MANAGEMENT_3,
445 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
446
447 SND_SOC_DAPM_MIXER("Left Input Mixer", WM8983_POWER_MANAGEMENT_2,
448 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
449 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8983_POWER_MANAGEMENT_2,
450 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
451
452 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8983_POWER_MANAGEMENT_2,
453 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
454 SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8983_POWER_MANAGEMENT_2,
455 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
456
457 SND_SOC_DAPM_MIXER("OUT3 Mixer", WM8983_POWER_MANAGEMENT_1,
458 6, 0, out3_mixer, ARRAY_SIZE(out3_mixer)),
459
460 SND_SOC_DAPM_MIXER("OUT4 Mixer", WM8983_POWER_MANAGEMENT_1,
461 7, 0, out4_mixer, ARRAY_SIZE(out4_mixer)),
462
463 SND_SOC_DAPM_PGA("Left Capture PGA", WM8983_LEFT_INP_PGA_GAIN_CTRL,
464 6, 1, NULL, 0),
465 SND_SOC_DAPM_PGA("Right Capture PGA", WM8983_RIGHT_INP_PGA_GAIN_CTRL,
466 6, 1, NULL, 0),
467
468 SND_SOC_DAPM_PGA("Left Headphone Out", WM8983_POWER_MANAGEMENT_2,
469 7, 0, NULL, 0),
470 SND_SOC_DAPM_PGA("Right Headphone Out", WM8983_POWER_MANAGEMENT_2,
471 8, 0, NULL, 0),
472
473 SND_SOC_DAPM_PGA("Left Speaker Out", WM8983_POWER_MANAGEMENT_3,
474 5, 0, NULL, 0),
475 SND_SOC_DAPM_PGA("Right Speaker Out", WM8983_POWER_MANAGEMENT_3,
476 6, 0, NULL, 0),
477
478 SND_SOC_DAPM_PGA("OUT3 Out", WM8983_POWER_MANAGEMENT_3,
479 7, 0, NULL, 0),
480
481 SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3,
482 8, 0, NULL, 0),
483
484 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0),
485
486 SND_SOC_DAPM_INPUT("LIN"),
487 SND_SOC_DAPM_INPUT("LIP"),
488 SND_SOC_DAPM_INPUT("RIN"),
489 SND_SOC_DAPM_INPUT("RIP"),
490 SND_SOC_DAPM_INPUT("AUXL"),
491 SND_SOC_DAPM_INPUT("AUXR"),
492 SND_SOC_DAPM_INPUT("L2"),
493 SND_SOC_DAPM_INPUT("R2"),
494 SND_SOC_DAPM_OUTPUT("HPL"),
495 SND_SOC_DAPM_OUTPUT("HPR"),
496 SND_SOC_DAPM_OUTPUT("SPKL"),
497 SND_SOC_DAPM_OUTPUT("SPKR"),
498 SND_SOC_DAPM_OUTPUT("OUT3"),
499 SND_SOC_DAPM_OUTPUT("OUT4")
500};
501
502static const struct snd_soc_dapm_route wm8983_audio_map[] = {
503 { "OUT3 Mixer", "LMIX2OUT3 Switch", "Left Output Mixer" },
504 { "OUT3 Mixer", "LDAC2OUT3 Switch", "Left DAC" },
505
506 { "OUT3 Out", NULL, "OUT3 Mixer" },
507 { "OUT3", NULL, "OUT3 Out" },
508
509 { "OUT4 Mixer", "LMIX2OUT4 Switch", "Left Output Mixer" },
510 { "OUT4 Mixer", "RMIX2OUT4 Switch", "Right Output Mixer" },
511 { "OUT4 Mixer", "LDAC2OUT4 Switch", "Left DAC" },
512 { "OUT4 Mixer", "RDAC2OUT4 Switch", "Right DAC" },
513
514 { "OUT4 Out", NULL, "OUT4 Mixer" },
515 { "OUT4", NULL, "OUT4 Out" },
516
517 { "Right Output Mixer", "PCM Switch", "Right DAC" },
518 { "Right Output Mixer", "Aux Switch", "AUXR" },
519 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
520
521 { "Left Output Mixer", "PCM Switch", "Left DAC" },
522 { "Left Output Mixer", "Aux Switch", "AUXL" },
523 { "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
524
525 { "Right Headphone Out", NULL, "Right Output Mixer" },
526 { "HPR", NULL, "Right Headphone Out" },
527
528 { "Left Headphone Out", NULL, "Left Output Mixer" },
529 { "HPL", NULL, "Left Headphone Out" },
530
531 { "Right Speaker Out", NULL, "Right Output Mixer" },
532 { "SPKR", NULL, "Right Speaker Out" },
533
534 { "Left Speaker Out", NULL, "Left Output Mixer" },
535 { "SPKL", NULL, "Left Speaker Out" },
536
537 { "Right ADC", NULL, "Right Boost Mixer" },
538
539 { "Right Boost Mixer", "AUXR Volume", "AUXR" },
540 { "Right Boost Mixer", NULL, "Right Capture PGA" },
541 { "Right Boost Mixer", "R2 Volume", "R2" },
542
543 { "Left ADC", NULL, "Left Boost Mixer" },
544
545 { "Left Boost Mixer", "AUXL Volume", "AUXL" },
546 { "Left Boost Mixer", NULL, "Left Capture PGA" },
547 { "Left Boost Mixer", "L2 Volume", "L2" },
548
549 { "Right Capture PGA", NULL, "Right Input Mixer" },
550 { "Left Capture PGA", NULL, "Left Input Mixer" },
551
552 { "Right Input Mixer", "R2 Switch", "R2" },
553 { "Right Input Mixer", "MicN Switch", "RIN" },
554 { "Right Input Mixer", "MicP Switch", "RIP" },
555
556 { "Left Input Mixer", "L2 Switch", "L2" },
557 { "Left Input Mixer", "MicN Switch", "LIN" },
558 { "Left Input Mixer", "MicP Switch", "LIP" },
559};
560
561static int eqmode_get(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563{
564 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
565 unsigned int reg;
566
567 reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
568 if (reg & WM8983_EQ3DMODE)
569 ucontrol->value.integer.value[0] = 1;
570 else
571 ucontrol->value.integer.value[0] = 0;
572
573 return 0;
574}
575
576static int eqmode_put(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
580 unsigned int regpwr2, regpwr3;
581 unsigned int reg_eq;
582
583 if (ucontrol->value.integer.value[0] != 0
584 && ucontrol->value.integer.value[0] != 1)
585 return -EINVAL;
586
587 reg_eq = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF);
588 switch ((reg_eq & WM8983_EQ3DMODE) >> WM8983_EQ3DMODE_SHIFT) {
589 case 0:
590 if (!ucontrol->value.integer.value[0])
591 return 0;
592 break;
593 case 1:
594 if (ucontrol->value.integer.value[0])
595 return 0;
596 break;
597 }
598
599 regpwr2 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_2);
600 regpwr3 = snd_soc_read(codec, WM8983_POWER_MANAGEMENT_3);
601 /* disable the DACs and ADCs */
602 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_2,
603 WM8983_ADCENR_MASK | WM8983_ADCENL_MASK, 0);
604 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_3,
605 WM8983_DACENR_MASK | WM8983_DACENL_MASK, 0);
606 /* set the desired eqmode */
607 snd_soc_update_bits(codec, WM8983_EQ1_LOW_SHELF,
608 WM8983_EQ3DMODE_MASK,
609 ucontrol->value.integer.value[0]
610 << WM8983_EQ3DMODE_SHIFT);
611 /* restore DAC/ADC configuration */
612 snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, regpwr2);
613 snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, regpwr3);
614 return 0;
615}
616
617static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg)
618{
619 if (reg > WM8983_MAX_REGISTER)
620 return 0;
621
622 return wm8983_access_masks[reg].read != 0;
623}
624
625static int wm8983_dac_mute(struct snd_soc_dai *dai, int mute)
626{
627 struct snd_soc_codec *codec = dai->codec;
628
629 return snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
630 WM8983_SOFTMUTE_MASK,
631 !!mute << WM8983_SOFTMUTE_SHIFT);
632}
633
634static int wm8983_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
635{
636 struct snd_soc_codec *codec = dai->codec;
637 u16 format, master, bcp, lrp;
638
639 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
640 case SND_SOC_DAIFMT_I2S:
641 format = 0x2;
642 break;
643 case SND_SOC_DAIFMT_RIGHT_J:
644 format = 0x0;
645 break;
646 case SND_SOC_DAIFMT_LEFT_J:
647 format = 0x1;
648 break;
649 case SND_SOC_DAIFMT_DSP_A:
650 case SND_SOC_DAIFMT_DSP_B:
651 format = 0x3;
652 break;
653 default:
654 dev_err(dai->dev, "Unknown dai format\n");
655 return -EINVAL;
656 }
657
658 snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
659 WM8983_FMT_MASK, format << WM8983_FMT_SHIFT);
660
661 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
662 case SND_SOC_DAIFMT_CBM_CFM:
663 master = 1;
664 break;
665 case SND_SOC_DAIFMT_CBS_CFS:
666 master = 0;
667 break;
668 default:
669 dev_err(dai->dev, "Unknown master/slave configuration\n");
670 return -EINVAL;
671 }
672
673 snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
674 WM8983_MS_MASK, master << WM8983_MS_SHIFT);
675
676 /* FIXME: We don't currently support DSP A/B modes */
677 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
678 case SND_SOC_DAIFMT_DSP_A:
679 case SND_SOC_DAIFMT_DSP_B:
680 dev_err(dai->dev, "DSP A/B modes are not supported\n");
681 return -EINVAL;
682 default:
683 break;
684 }
685
686 bcp = lrp = 0;
687 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
688 case SND_SOC_DAIFMT_NB_NF:
689 break;
690 case SND_SOC_DAIFMT_IB_IF:
691 bcp = lrp = 1;
692 break;
693 case SND_SOC_DAIFMT_IB_NF:
694 bcp = 1;
695 break;
696 case SND_SOC_DAIFMT_NB_IF:
697 lrp = 1;
698 break;
699 default:
700 dev_err(dai->dev, "Unknown polarity configuration\n");
701 return -EINVAL;
702 }
703
704 snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
705 WM8983_LRCP_MASK, lrp << WM8983_LRCP_SHIFT);
706 snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
707 WM8983_BCP_MASK, bcp << WM8983_BCP_SHIFT);
708 return 0;
709}
710
711static int wm8983_hw_params(struct snd_pcm_substream *substream,
712 struct snd_pcm_hw_params *params,
713 struct snd_soc_dai *dai)
714{
715 int i;
716 struct snd_soc_codec *codec = dai->codec;
717 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
718 u16 blen, srate_idx;
719 u32 tmp;
720 int srate_best;
721 int ret;
722
723 ret = snd_soc_params_to_bclk(params);
724 if (ret < 0) {
725 dev_err(codec->dev, "Failed to convert params to bclk: %d\n", ret);
726 return ret;
727 }
728
729 wm8983->bclk = ret;
730
731 switch (params_format(params)) {
732 case SNDRV_PCM_FORMAT_S16_LE:
733 blen = 0x0;
734 break;
735 case SNDRV_PCM_FORMAT_S20_3LE:
736 blen = 0x1;
737 break;
738 case SNDRV_PCM_FORMAT_S24_LE:
739 blen = 0x2;
740 break;
741 case SNDRV_PCM_FORMAT_S32_LE:
742 blen = 0x3;
743 break;
744 default:
745 dev_err(dai->dev, "Unsupported word length %u\n",
746 params_format(params));
747 return -EINVAL;
748 }
749
750 snd_soc_update_bits(codec, WM8983_AUDIO_INTERFACE,
751 WM8983_WL_MASK, blen << WM8983_WL_SHIFT);
752
753 /*
754 * match to the nearest possible sample rate and rely
755 * on the array index to configure the SR register
756 */
757 srate_idx = 0;
758 srate_best = abs(srates[0] - params_rate(params));
759 for (i = 1; i < ARRAY_SIZE(srates); ++i) {
760 if (abs(srates[i] - params_rate(params)) >= srate_best)
761 continue;
762 srate_idx = i;
763 srate_best = abs(srates[i] - params_rate(params));
764 }
765
766 dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
767 snd_soc_update_bits(codec, WM8983_ADDITIONAL_CONTROL,
768 WM8983_SR_MASK, srate_idx << WM8983_SR_SHIFT);
769
770 dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8983->bclk);
771 dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8983->sysclk);
772
773 for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) {
774 if (wm8983->sysclk / params_rate(params)
775 == fs_ratios[i].ratio)
776 break;
777 }
778
779 if (i == ARRAY_SIZE(fs_ratios)) {
780 dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n",
781 wm8983->sysclk, params_rate(params));
782 return -EINVAL;
783 }
784
785 dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
786 snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
787 WM8983_MCLKDIV_MASK, i << WM8983_MCLKDIV_SHIFT);
788
789 /* select the appropriate bclk divider */
790 tmp = (wm8983->sysclk / fs_ratios[i].div) * 10;
791 for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) {
792 if (wm8983->bclk == tmp / bclk_divs[i])
793 break;
794 }
795
796 if (i == ARRAY_SIZE(bclk_divs)) {
797 dev_err(dai->dev, "No matching BCLK divider found\n");
798 return -EINVAL;
799 }
800
801 dev_dbg(dai->dev, "BCLK div = %d\n", i);
802 snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
803 WM8983_BCLKDIV_MASK, i << WM8983_BCLKDIV_SHIFT);
804
805 return 0;
806}
807
808struct pll_div {
809 u32 div2:1;
810 u32 n:4;
811 u32 k:24;
812};
813
814#define FIXED_PLL_SIZE ((1ULL << 24) * 10)
815static int pll_factors(struct pll_div *pll_div, unsigned int target,
816 unsigned int source)
817{
818 u64 Kpart;
819 unsigned long int K, Ndiv, Nmod;
820
821 pll_div->div2 = 0;
822 Ndiv = target / source;
823 if (Ndiv < 6) {
824 source >>= 1;
825 pll_div->div2 = 1;
826 Ndiv = target / source;
827 }
828
829 if (Ndiv < 6 || Ndiv > 12) {
830 printk(KERN_ERR "%s: WM8983 N value is not within"
831 " the recommended range: %lu\n", __func__, Ndiv);
832 return -EINVAL;
833 }
834 pll_div->n = Ndiv;
835
836 Nmod = target % source;
837 Kpart = FIXED_PLL_SIZE * (u64)Nmod;
838
839 do_div(Kpart, source);
840
841 K = Kpart & 0xffffffff;
842 if ((K % 10) >= 5)
843 K += 5;
844 K /= 10;
845 pll_div->k = K;
846 return 0;
847}
848
849static int wm8983_set_pll(struct snd_soc_dai *dai, int pll_id,
850 int source, unsigned int freq_in,
851 unsigned int freq_out)
852{
853 int ret;
854 struct snd_soc_codec *codec;
855 struct pll_div pll_div;
856
857 codec = dai->codec;
858 if (freq_in && freq_out) {
859 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
860 if (ret)
861 return ret;
862 }
863
864 /* disable the PLL before re-programming it */
865 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
866 WM8983_PLLEN_MASK, 0);
867
868 if (!freq_in || !freq_out)
869 return 0;
870
871 /* set PLLN and PRESCALE */
872 snd_soc_write(codec, WM8983_PLL_N,
873 (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
874 | pll_div.n);
875 /* set PLLK */
876 snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
877 snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
878 snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
879 /* enable the PLL */
880 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
881 WM8983_PLLEN_MASK, WM8983_PLLEN);
882 return 0;
883}
884
885static int wm8983_set_sysclk(struct snd_soc_dai *dai,
886 int clk_id, unsigned int freq, int dir)
887{
888 struct snd_soc_codec *codec = dai->codec;
889 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
890
891 switch (clk_id) {
892 case WM8983_CLKSRC_MCLK:
893 snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
894 WM8983_CLKSEL_MASK, 0);
895 break;
896 case WM8983_CLKSRC_PLL:
897 snd_soc_update_bits(codec, WM8983_CLOCK_GEN_CONTROL,
898 WM8983_CLKSEL_MASK, WM8983_CLKSEL);
899 break;
900 default:
901 dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
902 return -EINVAL;
903 }
904
905 wm8983->sysclk = freq;
906 return 0;
907}
908
909static int wm8983_set_bias_level(struct snd_soc_codec *codec,
910 enum snd_soc_bias_level level)
911{
912 int ret;
913
914 switch (level) {
915 case SND_SOC_BIAS_ON:
916 case SND_SOC_BIAS_PREPARE:
917 /* VMID at 100k */
918 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
919 WM8983_VMIDSEL_MASK,
920 1 << WM8983_VMIDSEL_SHIFT);
921 break;
922 case SND_SOC_BIAS_STANDBY:
923 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
924 ret = snd_soc_cache_sync(codec);
925 if (ret < 0) {
926 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
927 return ret;
928 }
929 /* enable anti-pop features */
930 snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
931 WM8983_POBCTRL_MASK | WM8983_DELEN_MASK,
932 WM8983_POBCTRL | WM8983_DELEN);
933 /* enable thermal shutdown */
934 snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
935 WM8983_TSDEN_MASK, WM8983_TSDEN);
936 /* enable BIASEN */
937 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
938 WM8983_BIASEN_MASK, WM8983_BIASEN);
939 /* VMID at 100k */
940 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
941 WM8983_VMIDSEL_MASK,
942 1 << WM8983_VMIDSEL_SHIFT);
943 msleep(250);
944 /* disable anti-pop features */
945 snd_soc_update_bits(codec, WM8983_OUT4_TO_ADC,
946 WM8983_POBCTRL_MASK |
947 WM8983_DELEN_MASK, 0);
948 }
949
950 /* VMID at 500k */
951 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
952 WM8983_VMIDSEL_MASK,
953 2 << WM8983_VMIDSEL_SHIFT);
954 break;
955 case SND_SOC_BIAS_OFF:
956 /* disable thermal shutdown */
957 snd_soc_update_bits(codec, WM8983_OUTPUT_CTRL,
958 WM8983_TSDEN_MASK, 0);
959 /* disable VMIDSEL and BIASEN */
960 snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
961 WM8983_VMIDSEL_MASK | WM8983_BIASEN_MASK,
962 0);
963 /* wait for VMID to discharge */
964 msleep(100);
965 snd_soc_write(codec, WM8983_POWER_MANAGEMENT_1, 0);
966 snd_soc_write(codec, WM8983_POWER_MANAGEMENT_2, 0);
967 snd_soc_write(codec, WM8983_POWER_MANAGEMENT_3, 0);
968 break;
969 }
970
971 codec->dapm.bias_level = level;
972 return 0;
973}
974
975#ifdef CONFIG_PM
976static int wm8983_suspend(struct snd_soc_codec *codec, pm_message_t state)
977{
978 wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF);
979 return 0;
980}
981
982static int wm8983_resume(struct snd_soc_codec *codec)
983{
984 wm8983_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
985 return 0;
986}
987#else
988#define wm8983_suspend NULL
989#define wm8983_resume NULL
990#endif
991
992static int wm8983_remove(struct snd_soc_codec *codec)
993{
994 wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF);
995 return 0;
996}
997
998static int wm8983_probe(struct snd_soc_codec *codec)
999{
1000 int ret;
1001 struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
1002 int i;
1003
1004 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type);
1005 if (ret < 0) {
1006 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1007 return ret;
1008 }
1009
1010 ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0x8983);
1011 if (ret < 0) {
1012 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1013 return ret;
1014 }
1015
1016 /* set the vol/gain update bits */
1017 for (i = 0; i < ARRAY_SIZE(vol_update_regs); ++i)
1018 snd_soc_update_bits(codec, vol_update_regs[i],
1019 0x100, 0x100);
1020
1021 /* mute all outputs and set PGAs to minimum gain */
1022 for (i = WM8983_LOUT1_HP_VOLUME_CTRL;
1023 i <= WM8983_OUT4_MONO_MIX_CTRL; ++i)
1024 snd_soc_update_bits(codec, i, 0x40, 0x40);
1025
1026 /* enable soft mute */
1027 snd_soc_update_bits(codec, WM8983_DAC_CONTROL,
1028 WM8983_SOFTMUTE_MASK,
1029 WM8983_SOFTMUTE);
1030
1031 /* enable BIASCUT */
1032 snd_soc_update_bits(codec, WM8983_BIAS_CTRL,
1033 WM8983_BIASCUT, WM8983_BIASCUT);
1034 return 0;
1035}
1036
1037static struct snd_soc_dai_ops wm8983_dai_ops = {
1038 .digital_mute = wm8983_dac_mute,
1039 .hw_params = wm8983_hw_params,
1040 .set_fmt = wm8983_set_fmt,
1041 .set_sysclk = wm8983_set_sysclk,
1042 .set_pll = wm8983_set_pll
1043};
1044
1045#define WM8983_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1046 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1047
1048static struct snd_soc_dai_driver wm8983_dai = {
1049 .name = "wm8983-hifi",
1050 .playback = {
1051 .stream_name = "Playback",
1052 .channels_min = 2,
1053 .channels_max = 2,
1054 .rates = SNDRV_PCM_RATE_8000_48000,
1055 .formats = WM8983_FORMATS,
1056 },
1057 .capture = {
1058 .stream_name = "Capture",
1059 .channels_min = 2,
1060 .channels_max = 2,
1061 .rates = SNDRV_PCM_RATE_8000_48000,
1062 .formats = WM8983_FORMATS,
1063 },
1064 .ops = &wm8983_dai_ops,
1065 .symmetric_rates = 1
1066};
1067
1068static struct snd_soc_codec_driver soc_codec_dev_wm8983 = {
1069 .probe = wm8983_probe,
1070 .remove = wm8983_remove,
1071 .suspend = wm8983_suspend,
1072 .resume = wm8983_resume,
1073 .set_bias_level = wm8983_set_bias_level,
1074 .reg_cache_size = ARRAY_SIZE(wm8983_reg_defs),
1075 .reg_word_size = sizeof(u16),
1076 .reg_cache_default = wm8983_reg_defs,
1077 .controls = wm8983_snd_controls,
1078 .num_controls = ARRAY_SIZE(wm8983_snd_controls),
1079 .dapm_widgets = wm8983_dapm_widgets,
1080 .num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
1081 .dapm_routes = wm8983_audio_map,
1082 .num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
1083 .readable_register = wm8983_readable
1084};
1085
1086#if defined(CONFIG_SPI_MASTER)
1087static int __devinit wm8983_spi_probe(struct spi_device *spi)
1088{
1089 struct wm8983_priv *wm8983;
1090 int ret;
1091
1092 wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
1093 if (!wm8983)
1094 return -ENOMEM;
1095
1096 wm8983->control_type = SND_SOC_SPI;
1097 spi_set_drvdata(spi, wm8983);
1098
1099 ret = snd_soc_register_codec(&spi->dev,
1100 &soc_codec_dev_wm8983, &wm8983_dai, 1);
1101 if (ret < 0)
1102 kfree(wm8983);
1103 return ret;
1104}
1105
1106static int __devexit wm8983_spi_remove(struct spi_device *spi)
1107{
1108 snd_soc_unregister_codec(&spi->dev);
1109 kfree(spi_get_drvdata(spi));
1110 return 0;
1111}
1112
1113static struct spi_driver wm8983_spi_driver = {
1114 .driver = {
1115 .name = "wm8983",
1116 .owner = THIS_MODULE,
1117 },
1118 .probe = wm8983_spi_probe,
1119 .remove = __devexit_p(wm8983_spi_remove)
1120};
1121#endif
1122
1123#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1124static __devinit int wm8983_i2c_probe(struct i2c_client *i2c,
1125 const struct i2c_device_id *id)
1126{
1127 struct wm8983_priv *wm8983;
1128 int ret;
1129
1130 wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
1131 if (!wm8983)
1132 return -ENOMEM;
1133
1134 wm8983->control_type = SND_SOC_I2C;
1135 i2c_set_clientdata(i2c, wm8983);
1136
1137 ret = snd_soc_register_codec(&i2c->dev,
1138 &soc_codec_dev_wm8983, &wm8983_dai, 1);
1139 if (ret < 0)
1140 kfree(wm8983);
1141 return ret;
1142}
1143
1144static __devexit int wm8983_i2c_remove(struct i2c_client *client)
1145{
1146 snd_soc_unregister_codec(&client->dev);
1147 kfree(i2c_get_clientdata(client));
1148 return 0;
1149}
1150
1151static const struct i2c_device_id wm8983_i2c_id[] = {
1152 { "wm8983", 0 },
1153 { }
1154};
1155MODULE_DEVICE_TABLE(i2c, wm8983_i2c_id);
1156
1157static struct i2c_driver wm8983_i2c_driver = {
1158 .driver = {
1159 .name = "wm8983",
1160 .owner = THIS_MODULE,
1161 },
1162 .probe = wm8983_i2c_probe,
1163 .remove = __devexit_p(wm8983_i2c_remove),
1164 .id_table = wm8983_i2c_id
1165};
1166#endif
1167
1168static int __init wm8983_modinit(void)
1169{
1170 int ret = 0;
1171
1172#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1173 ret = i2c_add_driver(&wm8983_i2c_driver);
1174 if (ret) {
1175 printk(KERN_ERR "Failed to register wm8983 I2C driver: %d\n",
1176 ret);
1177 }
1178#endif
1179#if defined(CONFIG_SPI_MASTER)
1180 ret = spi_register_driver(&wm8983_spi_driver);
1181 if (ret != 0) {
1182 printk(KERN_ERR "Failed to register wm8983 SPI driver: %d\n",
1183 ret);
1184 }
1185#endif
1186 return ret;
1187}
1188module_init(wm8983_modinit);
1189
1190static void __exit wm8983_exit(void)
1191{
1192#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1193 i2c_del_driver(&wm8983_i2c_driver);
1194#endif
1195#if defined(CONFIG_SPI_MASTER)
1196 spi_unregister_driver(&wm8983_spi_driver);
1197#endif
1198}
1199module_exit(wm8983_exit);
1200
1201MODULE_DESCRIPTION("ASoC WM8983 driver");
1202MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
1203MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8983.h b/sound/soc/codecs/wm8983.h
new file mode 100644
index 000000000000..71ee619c2742
--- /dev/null
+++ b/sound/soc/codecs/wm8983.h
@@ -0,0 +1,1029 @@
1/*
2 * wm8983.h -- WM8983 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8983_H
14#define _WM8983_H
15
16/*
17 * Register values.
18 */
19#define WM8983_SOFTWARE_RESET 0x00
20#define WM8983_POWER_MANAGEMENT_1 0x01
21#define WM8983_POWER_MANAGEMENT_2 0x02
22#define WM8983_POWER_MANAGEMENT_3 0x03
23#define WM8983_AUDIO_INTERFACE 0x04
24#define WM8983_COMPANDING_CONTROL 0x05
25#define WM8983_CLOCK_GEN_CONTROL 0x06
26#define WM8983_ADDITIONAL_CONTROL 0x07
27#define WM8983_GPIO_CONTROL 0x08
28#define WM8983_JACK_DETECT_CONTROL_1 0x09
29#define WM8983_DAC_CONTROL 0x0A
30#define WM8983_LEFT_DAC_DIGITAL_VOL 0x0B
31#define WM8983_RIGHT_DAC_DIGITAL_VOL 0x0C
32#define WM8983_JACK_DETECT_CONTROL_2 0x0D
33#define WM8983_ADC_CONTROL 0x0E
34#define WM8983_LEFT_ADC_DIGITAL_VOL 0x0F
35#define WM8983_RIGHT_ADC_DIGITAL_VOL 0x10
36#define WM8983_EQ1_LOW_SHELF 0x12
37#define WM8983_EQ2_PEAK_1 0x13
38#define WM8983_EQ3_PEAK_2 0x14
39#define WM8983_EQ4_PEAK_3 0x15
40#define WM8983_EQ5_HIGH_SHELF 0x16
41#define WM8983_DAC_LIMITER_1 0x18
42#define WM8983_DAC_LIMITER_2 0x19
43#define WM8983_NOTCH_FILTER_1 0x1B
44#define WM8983_NOTCH_FILTER_2 0x1C
45#define WM8983_NOTCH_FILTER_3 0x1D
46#define WM8983_NOTCH_FILTER_4 0x1E
47#define WM8983_ALC_CONTROL_1 0x20
48#define WM8983_ALC_CONTROL_2 0x21
49#define WM8983_ALC_CONTROL_3 0x22
50#define WM8983_NOISE_GATE 0x23
51#define WM8983_PLL_N 0x24
52#define WM8983_PLL_K_1 0x25
53#define WM8983_PLL_K_2 0x26
54#define WM8983_PLL_K_3 0x27
55#define WM8983_3D_CONTROL 0x29
56#define WM8983_OUT4_TO_ADC 0x2A
57#define WM8983_BEEP_CONTROL 0x2B
58#define WM8983_INPUT_CTRL 0x2C
59#define WM8983_LEFT_INP_PGA_GAIN_CTRL 0x2D
60#define WM8983_RIGHT_INP_PGA_GAIN_CTRL 0x2E
61#define WM8983_LEFT_ADC_BOOST_CTRL 0x2F
62#define WM8983_RIGHT_ADC_BOOST_CTRL 0x30
63#define WM8983_OUTPUT_CTRL 0x31
64#define WM8983_LEFT_MIXER_CTRL 0x32
65#define WM8983_RIGHT_MIXER_CTRL 0x33
66#define WM8983_LOUT1_HP_VOLUME_CTRL 0x34
67#define WM8983_ROUT1_HP_VOLUME_CTRL 0x35
68#define WM8983_LOUT2_SPK_VOLUME_CTRL 0x36
69#define WM8983_ROUT2_SPK_VOLUME_CTRL 0x37
70#define WM8983_OUT3_MIXER_CTRL 0x38
71#define WM8983_OUT4_MONO_MIX_CTRL 0x39
72#define WM8983_BIAS_CTRL 0x3D
73
74#define WM8983_REGISTER_COUNT 59
75#define WM8983_MAX_REGISTER 0x3F
76
77/*
78 * Field Definitions.
79 */
80
81/*
82 * R0 (0x00) - Software Reset
83 */
84#define WM8983_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */
85#define WM8983_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */
86#define WM8983_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */
87
88/*
89 * R1 (0x01) - Power management 1
90 */
91#define WM8983_BUFDCOPEN 0x0100 /* BUFDCOPEN */
92#define WM8983_BUFDCOPEN_MASK 0x0100 /* BUFDCOPEN */
93#define WM8983_BUFDCOPEN_SHIFT 8 /* BUFDCOPEN */
94#define WM8983_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
95#define WM8983_OUT4MIXEN 0x0080 /* OUT4MIXEN */
96#define WM8983_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */
97#define WM8983_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */
98#define WM8983_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */
99#define WM8983_OUT3MIXEN 0x0040 /* OUT3MIXEN */
100#define WM8983_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */
101#define WM8983_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */
102#define WM8983_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */
103#define WM8983_PLLEN 0x0020 /* PLLEN */
104#define WM8983_PLLEN_MASK 0x0020 /* PLLEN */
105#define WM8983_PLLEN_SHIFT 5 /* PLLEN */
106#define WM8983_PLLEN_WIDTH 1 /* PLLEN */
107#define WM8983_MICBEN 0x0010 /* MICBEN */
108#define WM8983_MICBEN_MASK 0x0010 /* MICBEN */
109#define WM8983_MICBEN_SHIFT 4 /* MICBEN */
110#define WM8983_MICBEN_WIDTH 1 /* MICBEN */
111#define WM8983_BIASEN 0x0008 /* BIASEN */
112#define WM8983_BIASEN_MASK 0x0008 /* BIASEN */
113#define WM8983_BIASEN_SHIFT 3 /* BIASEN */
114#define WM8983_BIASEN_WIDTH 1 /* BIASEN */
115#define WM8983_BUFIOEN 0x0004 /* BUFIOEN */
116#define WM8983_BUFIOEN_MASK 0x0004 /* BUFIOEN */
117#define WM8983_BUFIOEN_SHIFT 2 /* BUFIOEN */
118#define WM8983_BUFIOEN_WIDTH 1 /* BUFIOEN */
119#define WM8983_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */
120#define WM8983_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */
121#define WM8983_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */
122
123/*
124 * R2 (0x02) - Power management 2
125 */
126#define WM8983_ROUT1EN 0x0100 /* ROUT1EN */
127#define WM8983_ROUT1EN_MASK 0x0100 /* ROUT1EN */
128#define WM8983_ROUT1EN_SHIFT 8 /* ROUT1EN */
129#define WM8983_ROUT1EN_WIDTH 1 /* ROUT1EN */
130#define WM8983_LOUT1EN 0x0080 /* LOUT1EN */
131#define WM8983_LOUT1EN_MASK 0x0080 /* LOUT1EN */
132#define WM8983_LOUT1EN_SHIFT 7 /* LOUT1EN */
133#define WM8983_LOUT1EN_WIDTH 1 /* LOUT1EN */
134#define WM8983_SLEEP 0x0040 /* SLEEP */
135#define WM8983_SLEEP_MASK 0x0040 /* SLEEP */
136#define WM8983_SLEEP_SHIFT 6 /* SLEEP */
137#define WM8983_SLEEP_WIDTH 1 /* SLEEP */
138#define WM8983_BOOSTENR 0x0020 /* BOOSTENR */
139#define WM8983_BOOSTENR_MASK 0x0020 /* BOOSTENR */
140#define WM8983_BOOSTENR_SHIFT 5 /* BOOSTENR */
141#define WM8983_BOOSTENR_WIDTH 1 /* BOOSTENR */
142#define WM8983_BOOSTENL 0x0010 /* BOOSTENL */
143#define WM8983_BOOSTENL_MASK 0x0010 /* BOOSTENL */
144#define WM8983_BOOSTENL_SHIFT 4 /* BOOSTENL */
145#define WM8983_BOOSTENL_WIDTH 1 /* BOOSTENL */
146#define WM8983_INPGAENR 0x0008 /* INPGAENR */
147#define WM8983_INPGAENR_MASK 0x0008 /* INPGAENR */
148#define WM8983_INPGAENR_SHIFT 3 /* INPGAENR */
149#define WM8983_INPGAENR_WIDTH 1 /* INPGAENR */
150#define WM8983_INPPGAENL 0x0004 /* INPPGAENL */
151#define WM8983_INPPGAENL_MASK 0x0004 /* INPPGAENL */
152#define WM8983_INPPGAENL_SHIFT 2 /* INPPGAENL */
153#define WM8983_INPPGAENL_WIDTH 1 /* INPPGAENL */
154#define WM8983_ADCENR 0x0002 /* ADCENR */
155#define WM8983_ADCENR_MASK 0x0002 /* ADCENR */
156#define WM8983_ADCENR_SHIFT 1 /* ADCENR */
157#define WM8983_ADCENR_WIDTH 1 /* ADCENR */
158#define WM8983_ADCENL 0x0001 /* ADCENL */
159#define WM8983_ADCENL_MASK 0x0001 /* ADCENL */
160#define WM8983_ADCENL_SHIFT 0 /* ADCENL */
161#define WM8983_ADCENL_WIDTH 1 /* ADCENL */
162
163/*
164 * R3 (0x03) - Power management 3
165 */
166#define WM8983_OUT4EN 0x0100 /* OUT4EN */
167#define WM8983_OUT4EN_MASK 0x0100 /* OUT4EN */
168#define WM8983_OUT4EN_SHIFT 8 /* OUT4EN */
169#define WM8983_OUT4EN_WIDTH 1 /* OUT4EN */
170#define WM8983_OUT3EN 0x0080 /* OUT3EN */
171#define WM8983_OUT3EN_MASK 0x0080 /* OUT3EN */
172#define WM8983_OUT3EN_SHIFT 7 /* OUT3EN */
173#define WM8983_OUT3EN_WIDTH 1 /* OUT3EN */
174#define WM8983_LOUT2EN 0x0040 /* LOUT2EN */
175#define WM8983_LOUT2EN_MASK 0x0040 /* LOUT2EN */
176#define WM8983_LOUT2EN_SHIFT 6 /* LOUT2EN */
177#define WM8983_LOUT2EN_WIDTH 1 /* LOUT2EN */
178#define WM8983_ROUT2EN 0x0020 /* ROUT2EN */
179#define WM8983_ROUT2EN_MASK 0x0020 /* ROUT2EN */
180#define WM8983_ROUT2EN_SHIFT 5 /* ROUT2EN */
181#define WM8983_ROUT2EN_WIDTH 1 /* ROUT2EN */
182#define WM8983_RMIXEN 0x0008 /* RMIXEN */
183#define WM8983_RMIXEN_MASK 0x0008 /* RMIXEN */
184#define WM8983_RMIXEN_SHIFT 3 /* RMIXEN */
185#define WM8983_RMIXEN_WIDTH 1 /* RMIXEN */
186#define WM8983_LMIXEN 0x0004 /* LMIXEN */
187#define WM8983_LMIXEN_MASK 0x0004 /* LMIXEN */
188#define WM8983_LMIXEN_SHIFT 2 /* LMIXEN */
189#define WM8983_LMIXEN_WIDTH 1 /* LMIXEN */
190#define WM8983_DACENR 0x0002 /* DACENR */
191#define WM8983_DACENR_MASK 0x0002 /* DACENR */
192#define WM8983_DACENR_SHIFT 1 /* DACENR */
193#define WM8983_DACENR_WIDTH 1 /* DACENR */
194#define WM8983_DACENL 0x0001 /* DACENL */
195#define WM8983_DACENL_MASK 0x0001 /* DACENL */
196#define WM8983_DACENL_SHIFT 0 /* DACENL */
197#define WM8983_DACENL_WIDTH 1 /* DACENL */
198
199/*
200 * R4 (0x04) - Audio Interface
201 */
202#define WM8983_BCP 0x0100 /* BCP */
203#define WM8983_BCP_MASK 0x0100 /* BCP */
204#define WM8983_BCP_SHIFT 8 /* BCP */
205#define WM8983_BCP_WIDTH 1 /* BCP */
206#define WM8983_LRCP 0x0080 /* LRCP */
207#define WM8983_LRCP_MASK 0x0080 /* LRCP */
208#define WM8983_LRCP_SHIFT 7 /* LRCP */
209#define WM8983_LRCP_WIDTH 1 /* LRCP */
210#define WM8983_WL_MASK 0x0060 /* WL - [6:5] */
211#define WM8983_WL_SHIFT 5 /* WL - [6:5] */
212#define WM8983_WL_WIDTH 2 /* WL - [6:5] */
213#define WM8983_FMT_MASK 0x0018 /* FMT - [4:3] */
214#define WM8983_FMT_SHIFT 3 /* FMT - [4:3] */
215#define WM8983_FMT_WIDTH 2 /* FMT - [4:3] */
216#define WM8983_DLRSWAP 0x0004 /* DLRSWAP */
217#define WM8983_DLRSWAP_MASK 0x0004 /* DLRSWAP */
218#define WM8983_DLRSWAP_SHIFT 2 /* DLRSWAP */
219#define WM8983_DLRSWAP_WIDTH 1 /* DLRSWAP */
220#define WM8983_ALRSWAP 0x0002 /* ALRSWAP */
221#define WM8983_ALRSWAP_MASK 0x0002 /* ALRSWAP */
222#define WM8983_ALRSWAP_SHIFT 1 /* ALRSWAP */
223#define WM8983_ALRSWAP_WIDTH 1 /* ALRSWAP */
224#define WM8983_MONO 0x0001 /* MONO */
225#define WM8983_MONO_MASK 0x0001 /* MONO */
226#define WM8983_MONO_SHIFT 0 /* MONO */
227#define WM8983_MONO_WIDTH 1 /* MONO */
228
229/*
230 * R5 (0x05) - Companding control
231 */
232#define WM8983_WL8 0x0020 /* WL8 */
233#define WM8983_WL8_MASK 0x0020 /* WL8 */
234#define WM8983_WL8_SHIFT 5 /* WL8 */
235#define WM8983_WL8_WIDTH 1 /* WL8 */
236#define WM8983_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */
237#define WM8983_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */
238#define WM8983_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */
239#define WM8983_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */
240#define WM8983_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */
241#define WM8983_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */
242#define WM8983_LOOPBACK 0x0001 /* LOOPBACK */
243#define WM8983_LOOPBACK_MASK 0x0001 /* LOOPBACK */
244#define WM8983_LOOPBACK_SHIFT 0 /* LOOPBACK */
245#define WM8983_LOOPBACK_WIDTH 1 /* LOOPBACK */
246
247/*
248 * R6 (0x06) - Clock Gen control
249 */
250#define WM8983_CLKSEL 0x0100 /* CLKSEL */
251#define WM8983_CLKSEL_MASK 0x0100 /* CLKSEL */
252#define WM8983_CLKSEL_SHIFT 8 /* CLKSEL */
253#define WM8983_CLKSEL_WIDTH 1 /* CLKSEL */
254#define WM8983_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */
255#define WM8983_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */
256#define WM8983_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */
257#define WM8983_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */
258#define WM8983_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */
259#define WM8983_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */
260#define WM8983_MS 0x0001 /* MS */
261#define WM8983_MS_MASK 0x0001 /* MS */
262#define WM8983_MS_SHIFT 0 /* MS */
263#define WM8983_MS_WIDTH 1 /* MS */
264
265/*
266 * R7 (0x07) - Additional control
267 */
268#define WM8983_SR_MASK 0x000E /* SR - [3:1] */
269#define WM8983_SR_SHIFT 1 /* SR - [3:1] */
270#define WM8983_SR_WIDTH 3 /* SR - [3:1] */
271#define WM8983_SLOWCLKEN 0x0001 /* SLOWCLKEN */
272#define WM8983_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */
273#define WM8983_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */
274#define WM8983_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */
275
276/*
277 * R8 (0x08) - GPIO Control
278 */
279#define WM8983_OPCLKDIV_MASK 0x0030 /* OPCLKDIV - [5:4] */
280#define WM8983_OPCLKDIV_SHIFT 4 /* OPCLKDIV - [5:4] */
281#define WM8983_OPCLKDIV_WIDTH 2 /* OPCLKDIV - [5:4] */
282#define WM8983_GPIO1POL 0x0008 /* GPIO1POL */
283#define WM8983_GPIO1POL_MASK 0x0008 /* GPIO1POL */
284#define WM8983_GPIO1POL_SHIFT 3 /* GPIO1POL */
285#define WM8983_GPIO1POL_WIDTH 1 /* GPIO1POL */
286#define WM8983_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */
287#define WM8983_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */
288#define WM8983_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */
289
290/*
291 * R9 (0x09) - Jack Detect Control 1
292 */
293#define WM8983_JD_VMID1 0x0100 /* JD_VMID1 */
294#define WM8983_JD_VMID1_MASK 0x0100 /* JD_VMID1 */
295#define WM8983_JD_VMID1_SHIFT 8 /* JD_VMID1 */
296#define WM8983_JD_VMID1_WIDTH 1 /* JD_VMID1 */
297#define WM8983_JD_VMID0 0x0080 /* JD_VMID0 */
298#define WM8983_JD_VMID0_MASK 0x0080 /* JD_VMID0 */
299#define WM8983_JD_VMID0_SHIFT 7 /* JD_VMID0 */
300#define WM8983_JD_VMID0_WIDTH 1 /* JD_VMID0 */
301#define WM8983_JD_EN 0x0040 /* JD_EN */
302#define WM8983_JD_EN_MASK 0x0040 /* JD_EN */
303#define WM8983_JD_EN_SHIFT 6 /* JD_EN */
304#define WM8983_JD_EN_WIDTH 1 /* JD_EN */
305#define WM8983_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */
306#define WM8983_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */
307#define WM8983_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */
308
309/*
310 * R10 (0x0A) - DAC Control
311 */
312#define WM8983_SOFTMUTE 0x0040 /* SOFTMUTE */
313#define WM8983_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */
314#define WM8983_SOFTMUTE_SHIFT 6 /* SOFTMUTE */
315#define WM8983_SOFTMUTE_WIDTH 1 /* SOFTMUTE */
316#define WM8983_DACOSR128 0x0008 /* DACOSR128 */
317#define WM8983_DACOSR128_MASK 0x0008 /* DACOSR128 */
318#define WM8983_DACOSR128_SHIFT 3 /* DACOSR128 */
319#define WM8983_DACOSR128_WIDTH 1 /* DACOSR128 */
320#define WM8983_AMUTE 0x0004 /* AMUTE */
321#define WM8983_AMUTE_MASK 0x0004 /* AMUTE */
322#define WM8983_AMUTE_SHIFT 2 /* AMUTE */
323#define WM8983_AMUTE_WIDTH 1 /* AMUTE */
324#define WM8983_DACRPOL 0x0002 /* DACRPOL */
325#define WM8983_DACRPOL_MASK 0x0002 /* DACRPOL */
326#define WM8983_DACRPOL_SHIFT 1 /* DACRPOL */
327#define WM8983_DACRPOL_WIDTH 1 /* DACRPOL */
328#define WM8983_DACLPOL 0x0001 /* DACLPOL */
329#define WM8983_DACLPOL_MASK 0x0001 /* DACLPOL */
330#define WM8983_DACLPOL_SHIFT 0 /* DACLPOL */
331#define WM8983_DACLPOL_WIDTH 1 /* DACLPOL */
332
333/*
334 * R11 (0x0B) - Left DAC digital Vol
335 */
336#define WM8983_DACVU 0x0100 /* DACVU */
337#define WM8983_DACVU_MASK 0x0100 /* DACVU */
338#define WM8983_DACVU_SHIFT 8 /* DACVU */
339#define WM8983_DACVU_WIDTH 1 /* DACVU */
340#define WM8983_DACLVOL_MASK 0x00FF /* DACLVOL - [7:0] */
341#define WM8983_DACLVOL_SHIFT 0 /* DACLVOL - [7:0] */
342#define WM8983_DACLVOL_WIDTH 8 /* DACLVOL - [7:0] */
343
344/*
345 * R12 (0x0C) - Right DAC digital vol
346 */
347#define WM8983_DACVU 0x0100 /* DACVU */
348#define WM8983_DACVU_MASK 0x0100 /* DACVU */
349#define WM8983_DACVU_SHIFT 8 /* DACVU */
350#define WM8983_DACVU_WIDTH 1 /* DACVU */
351#define WM8983_DACRVOL_MASK 0x00FF /* DACRVOL - [7:0] */
352#define WM8983_DACRVOL_SHIFT 0 /* DACRVOL - [7:0] */
353#define WM8983_DACRVOL_WIDTH 8 /* DACRVOL - [7:0] */
354
355/*
356 * R13 (0x0D) - Jack Detect Control 2
357 */
358#define WM8983_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */
359#define WM8983_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */
360#define WM8983_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */
361#define WM8983_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */
362#define WM8983_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */
363#define WM8983_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */
364
365/*
366 * R14 (0x0E) - ADC Control
367 */
368#define WM8983_HPFEN 0x0100 /* HPFEN */
369#define WM8983_HPFEN_MASK 0x0100 /* HPFEN */
370#define WM8983_HPFEN_SHIFT 8 /* HPFEN */
371#define WM8983_HPFEN_WIDTH 1 /* HPFEN */
372#define WM8983_HPFAPP 0x0080 /* HPFAPP */
373#define WM8983_HPFAPP_MASK 0x0080 /* HPFAPP */
374#define WM8983_HPFAPP_SHIFT 7 /* HPFAPP */
375#define WM8983_HPFAPP_WIDTH 1 /* HPFAPP */
376#define WM8983_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */
377#define WM8983_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */
378#define WM8983_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */
379#define WM8983_ADCOSR128 0x0008 /* ADCOSR128 */
380#define WM8983_ADCOSR128_MASK 0x0008 /* ADCOSR128 */
381#define WM8983_ADCOSR128_SHIFT 3 /* ADCOSR128 */
382#define WM8983_ADCOSR128_WIDTH 1 /* ADCOSR128 */
383#define WM8983_ADCRPOL 0x0002 /* ADCRPOL */
384#define WM8983_ADCRPOL_MASK 0x0002 /* ADCRPOL */
385#define WM8983_ADCRPOL_SHIFT 1 /* ADCRPOL */
386#define WM8983_ADCRPOL_WIDTH 1 /* ADCRPOL */
387#define WM8983_ADCLPOL 0x0001 /* ADCLPOL */
388#define WM8983_ADCLPOL_MASK 0x0001 /* ADCLPOL */
389#define WM8983_ADCLPOL_SHIFT 0 /* ADCLPOL */
390#define WM8983_ADCLPOL_WIDTH 1 /* ADCLPOL */
391
392/*
393 * R15 (0x0F) - Left ADC Digital Vol
394 */
395#define WM8983_ADCVU 0x0100 /* ADCVU */
396#define WM8983_ADCVU_MASK 0x0100 /* ADCVU */
397#define WM8983_ADCVU_SHIFT 8 /* ADCVU */
398#define WM8983_ADCVU_WIDTH 1 /* ADCVU */
399#define WM8983_ADCLVOL_MASK 0x00FF /* ADCLVOL - [7:0] */
400#define WM8983_ADCLVOL_SHIFT 0 /* ADCLVOL - [7:0] */
401#define WM8983_ADCLVOL_WIDTH 8 /* ADCLVOL - [7:0] */
402
403/*
404 * R16 (0x10) - Right ADC Digital Vol
405 */
406#define WM8983_ADCVU 0x0100 /* ADCVU */
407#define WM8983_ADCVU_MASK 0x0100 /* ADCVU */
408#define WM8983_ADCVU_SHIFT 8 /* ADCVU */
409#define WM8983_ADCVU_WIDTH 1 /* ADCVU */
410#define WM8983_ADCRVOL_MASK 0x00FF /* ADCRVOL - [7:0] */
411#define WM8983_ADCRVOL_SHIFT 0 /* ADCRVOL - [7:0] */
412#define WM8983_ADCRVOL_WIDTH 8 /* ADCRVOL - [7:0] */
413
414/*
415 * R18 (0x12) - EQ1 - low shelf
416 */
417#define WM8983_EQ3DMODE 0x0100 /* EQ3DMODE */
418#define WM8983_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */
419#define WM8983_EQ3DMODE_SHIFT 8 /* EQ3DMODE */
420#define WM8983_EQ3DMODE_WIDTH 1 /* EQ3DMODE */
421#define WM8983_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */
422#define WM8983_EQ1C_SHIFT 5 /* EQ1C - [6:5] */
423#define WM8983_EQ1C_WIDTH 2 /* EQ1C - [6:5] */
424#define WM8983_EQ1G_MASK 0x001F /* EQ1G - [4:0] */
425#define WM8983_EQ1G_SHIFT 0 /* EQ1G - [4:0] */
426#define WM8983_EQ1G_WIDTH 5 /* EQ1G - [4:0] */
427
428/*
429 * R19 (0x13) - EQ2 - peak 1
430 */
431#define WM8983_EQ2BW 0x0100 /* EQ2BW */
432#define WM8983_EQ2BW_MASK 0x0100 /* EQ2BW */
433#define WM8983_EQ2BW_SHIFT 8 /* EQ2BW */
434#define WM8983_EQ2BW_WIDTH 1 /* EQ2BW */
435#define WM8983_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */
436#define WM8983_EQ2C_SHIFT 5 /* EQ2C - [6:5] */
437#define WM8983_EQ2C_WIDTH 2 /* EQ2C - [6:5] */
438#define WM8983_EQ2G_MASK 0x001F /* EQ2G - [4:0] */
439#define WM8983_EQ2G_SHIFT 0 /* EQ2G - [4:0] */
440#define WM8983_EQ2G_WIDTH 5 /* EQ2G - [4:0] */
441
442/*
443 * R20 (0x14) - EQ3 - peak 2
444 */
445#define WM8983_EQ3BW 0x0100 /* EQ3BW */
446#define WM8983_EQ3BW_MASK 0x0100 /* EQ3BW */
447#define WM8983_EQ3BW_SHIFT 8 /* EQ3BW */
448#define WM8983_EQ3BW_WIDTH 1 /* EQ3BW */
449#define WM8983_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */
450#define WM8983_EQ3C_SHIFT 5 /* EQ3C - [6:5] */
451#define WM8983_EQ3C_WIDTH 2 /* EQ3C - [6:5] */
452#define WM8983_EQ3G_MASK 0x001F /* EQ3G - [4:0] */
453#define WM8983_EQ3G_SHIFT 0 /* EQ3G - [4:0] */
454#define WM8983_EQ3G_WIDTH 5 /* EQ3G - [4:0] */
455
456/*
457 * R21 (0x15) - EQ4 - peak 3
458 */
459#define WM8983_EQ4BW 0x0100 /* EQ4BW */
460#define WM8983_EQ4BW_MASK 0x0100 /* EQ4BW */
461#define WM8983_EQ4BW_SHIFT 8 /* EQ4BW */
462#define WM8983_EQ4BW_WIDTH 1 /* EQ4BW */
463#define WM8983_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */
464#define WM8983_EQ4C_SHIFT 5 /* EQ4C - [6:5] */
465#define WM8983_EQ4C_WIDTH 2 /* EQ4C - [6:5] */
466#define WM8983_EQ4G_MASK 0x001F /* EQ4G - [4:0] */
467#define WM8983_EQ4G_SHIFT 0 /* EQ4G - [4:0] */
468#define WM8983_EQ4G_WIDTH 5 /* EQ4G - [4:0] */
469
470/*
471 * R22 (0x16) - EQ5 - high shelf
472 */
473#define WM8983_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */
474#define WM8983_EQ5C_SHIFT 5 /* EQ5C - [6:5] */
475#define WM8983_EQ5C_WIDTH 2 /* EQ5C - [6:5] */
476#define WM8983_EQ5G_MASK 0x001F /* EQ5G - [4:0] */
477#define WM8983_EQ5G_SHIFT 0 /* EQ5G - [4:0] */
478#define WM8983_EQ5G_WIDTH 5 /* EQ5G - [4:0] */
479
480/*
481 * R24 (0x18) - DAC Limiter 1
482 */
483#define WM8983_LIMEN 0x0100 /* LIMEN */
484#define WM8983_LIMEN_MASK 0x0100 /* LIMEN */
485#define WM8983_LIMEN_SHIFT 8 /* LIMEN */
486#define WM8983_LIMEN_WIDTH 1 /* LIMEN */
487#define WM8983_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */
488#define WM8983_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */
489#define WM8983_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */
490#define WM8983_LIMATK_MASK 0x000F /* LIMATK - [3:0] */
491#define WM8983_LIMATK_SHIFT 0 /* LIMATK - [3:0] */
492#define WM8983_LIMATK_WIDTH 4 /* LIMATK - [3:0] */
493
494/*
495 * R25 (0x19) - DAC Limiter 2
496 */
497#define WM8983_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */
498#define WM8983_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */
499#define WM8983_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */
500#define WM8983_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */
501#define WM8983_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */
502#define WM8983_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */
503
504/*
505 * R27 (0x1B) - Notch Filter 1
506 */
507#define WM8983_NFU 0x0100 /* NFU */
508#define WM8983_NFU_MASK 0x0100 /* NFU */
509#define WM8983_NFU_SHIFT 8 /* NFU */
510#define WM8983_NFU_WIDTH 1 /* NFU */
511#define WM8983_NFEN 0x0080 /* NFEN */
512#define WM8983_NFEN_MASK 0x0080 /* NFEN */
513#define WM8983_NFEN_SHIFT 7 /* NFEN */
514#define WM8983_NFEN_WIDTH 1 /* NFEN */
515#define WM8983_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */
516#define WM8983_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */
517#define WM8983_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */
518
519/*
520 * R28 (0x1C) - Notch Filter 2
521 */
522#define WM8983_NFU 0x0100 /* NFU */
523#define WM8983_NFU_MASK 0x0100 /* NFU */
524#define WM8983_NFU_SHIFT 8 /* NFU */
525#define WM8983_NFU_WIDTH 1 /* NFU */
526#define WM8983_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */
527#define WM8983_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */
528#define WM8983_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */
529
530/*
531 * R29 (0x1D) - Notch Filter 3
532 */
533#define WM8983_NFU 0x0100 /* NFU */
534#define WM8983_NFU_MASK 0x0100 /* NFU */
535#define WM8983_NFU_SHIFT 8 /* NFU */
536#define WM8983_NFU_WIDTH 1 /* NFU */
537#define WM8983_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */
538#define WM8983_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */
539#define WM8983_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */
540
541/*
542 * R30 (0x1E) - Notch Filter 4
543 */
544#define WM8983_NFU 0x0100 /* NFU */
545#define WM8983_NFU_MASK 0x0100 /* NFU */
546#define WM8983_NFU_SHIFT 8 /* NFU */
547#define WM8983_NFU_WIDTH 1 /* NFU */
548#define WM8983_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */
549#define WM8983_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */
550#define WM8983_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */
551
552/*
553 * R32 (0x20) - ALC control 1
554 */
555#define WM8983_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
556#define WM8983_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
557#define WM8983_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
558#define WM8983_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */
559#define WM8983_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */
560#define WM8983_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */
561#define WM8983_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */
562#define WM8983_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */
563#define WM8983_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */
564
565/*
566 * R33 (0x21) - ALC control 2
567 */
568#define WM8983_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */
569#define WM8983_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */
570#define WM8983_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */
571#define WM8983_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */
572#define WM8983_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */
573#define WM8983_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */
574
575/*
576 * R34 (0x22) - ALC control 3
577 */
578#define WM8983_ALCMODE 0x0100 /* ALCMODE */
579#define WM8983_ALCMODE_MASK 0x0100 /* ALCMODE */
580#define WM8983_ALCMODE_SHIFT 8 /* ALCMODE */
581#define WM8983_ALCMODE_WIDTH 1 /* ALCMODE */
582#define WM8983_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */
583#define WM8983_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */
584#define WM8983_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */
585#define WM8983_ALCATK_MASK 0x000F /* ALCATK - [3:0] */
586#define WM8983_ALCATK_SHIFT 0 /* ALCATK - [3:0] */
587#define WM8983_ALCATK_WIDTH 4 /* ALCATK - [3:0] */
588
589/*
590 * R35 (0x23) - Noise Gate
591 */
592#define WM8983_NGEN 0x0008 /* NGEN */
593#define WM8983_NGEN_MASK 0x0008 /* NGEN */
594#define WM8983_NGEN_SHIFT 3 /* NGEN */
595#define WM8983_NGEN_WIDTH 1 /* NGEN */
596#define WM8983_NGTH_MASK 0x0007 /* NGTH - [2:0] */
597#define WM8983_NGTH_SHIFT 0 /* NGTH - [2:0] */
598#define WM8983_NGTH_WIDTH 3 /* NGTH - [2:0] */
599
600/*
601 * R36 (0x24) - PLL N
602 */
603#define WM8983_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */
604#define WM8983_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */
605#define WM8983_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */
606#define WM8983_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */
607#define WM8983_PLLN_MASK 0x000F /* PLLN - [3:0] */
608#define WM8983_PLLN_SHIFT 0 /* PLLN - [3:0] */
609#define WM8983_PLLN_WIDTH 4 /* PLLN - [3:0] */
610
611/*
612 * R37 (0x25) - PLL K 1
613 */
614#define WM8983_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */
615#define WM8983_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */
616#define WM8983_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */
617
618/*
619 * R38 (0x26) - PLL K 2
620 */
621#define WM8983_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */
622#define WM8983_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */
623#define WM8983_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */
624
625/*
626 * R39 (0x27) - PLL K 3
627 */
628#define WM8983_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */
629#define WM8983_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */
630#define WM8983_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */
631
632/*
633 * R41 (0x29) - 3D control
634 */
635#define WM8983_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */
636#define WM8983_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */
637#define WM8983_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */
638
639/*
640 * R42 (0x2A) - OUT4 to ADC
641 */
642#define WM8983_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */
643#define WM8983_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */
644#define WM8983_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */
645#define WM8983_OUT4_2LNR 0x0020 /* OUT4_2LNR */
646#define WM8983_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */
647#define WM8983_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */
648#define WM8983_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */
649#define WM8983_POBCTRL 0x0004 /* POBCTRL */
650#define WM8983_POBCTRL_MASK 0x0004 /* POBCTRL */
651#define WM8983_POBCTRL_SHIFT 2 /* POBCTRL */
652#define WM8983_POBCTRL_WIDTH 1 /* POBCTRL */
653#define WM8983_DELEN 0x0002 /* DELEN */
654#define WM8983_DELEN_MASK 0x0002 /* DELEN */
655#define WM8983_DELEN_SHIFT 1 /* DELEN */
656#define WM8983_DELEN_WIDTH 1 /* DELEN */
657#define WM8983_OUT1DEL 0x0001 /* OUT1DEL */
658#define WM8983_OUT1DEL_MASK 0x0001 /* OUT1DEL */
659#define WM8983_OUT1DEL_SHIFT 0 /* OUT1DEL */
660#define WM8983_OUT1DEL_WIDTH 1 /* OUT1DEL */
661
662/*
663 * R43 (0x2B) - Beep control
664 */
665#define WM8983_BYPL2RMIX 0x0100 /* BYPL2RMIX */
666#define WM8983_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */
667#define WM8983_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */
668#define WM8983_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */
669#define WM8983_BYPR2LMIX 0x0080 /* BYPR2LMIX */
670#define WM8983_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */
671#define WM8983_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */
672#define WM8983_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */
673#define WM8983_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */
674#define WM8983_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */
675#define WM8983_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */
676#define WM8983_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */
677#define WM8983_INVROUT2 0x0010 /* INVROUT2 */
678#define WM8983_INVROUT2_MASK 0x0010 /* INVROUT2 */
679#define WM8983_INVROUT2_SHIFT 4 /* INVROUT2 */
680#define WM8983_INVROUT2_WIDTH 1 /* INVROUT2 */
681#define WM8983_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */
682#define WM8983_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */
683#define WM8983_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */
684#define WM8983_BEEPEN 0x0001 /* BEEPEN */
685#define WM8983_BEEPEN_MASK 0x0001 /* BEEPEN */
686#define WM8983_BEEPEN_SHIFT 0 /* BEEPEN */
687#define WM8983_BEEPEN_WIDTH 1 /* BEEPEN */
688
689/*
690 * R44 (0x2C) - Input ctrl
691 */
692#define WM8983_MBVSEL 0x0100 /* MBVSEL */
693#define WM8983_MBVSEL_MASK 0x0100 /* MBVSEL */
694#define WM8983_MBVSEL_SHIFT 8 /* MBVSEL */
695#define WM8983_MBVSEL_WIDTH 1 /* MBVSEL */
696#define WM8983_R2_2INPPGA 0x0040 /* R2_2INPPGA */
697#define WM8983_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */
698#define WM8983_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */
699#define WM8983_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */
700#define WM8983_RIN2INPPGA 0x0020 /* RIN2INPPGA */
701#define WM8983_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */
702#define WM8983_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */
703#define WM8983_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */
704#define WM8983_RIP2INPPGA 0x0010 /* RIP2INPPGA */
705#define WM8983_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */
706#define WM8983_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */
707#define WM8983_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */
708#define WM8983_L2_2INPPGA 0x0004 /* L2_2INPPGA */
709#define WM8983_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */
710#define WM8983_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */
711#define WM8983_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */
712#define WM8983_LIN2INPPGA 0x0002 /* LIN2INPPGA */
713#define WM8983_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */
714#define WM8983_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */
715#define WM8983_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */
716#define WM8983_LIP2INPPGA 0x0001 /* LIP2INPPGA */
717#define WM8983_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */
718#define WM8983_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */
719#define WM8983_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */
720
721/*
722 * R45 (0x2D) - Left INP PGA gain ctrl
723 */
724#define WM8983_INPGAVU 0x0100 /* INPGAVU */
725#define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */
726#define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */
727#define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */
728#define WM8983_INPPGAZCL 0x0080 /* INPPGAZCL */
729#define WM8983_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */
730#define WM8983_INPPGAZCL_SHIFT 7 /* INPPGAZCL */
731#define WM8983_INPPGAZCL_WIDTH 1 /* INPPGAZCL */
732#define WM8983_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */
733#define WM8983_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */
734#define WM8983_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */
735#define WM8983_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */
736#define WM8983_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */
737#define WM8983_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */
738#define WM8983_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */
739
740/*
741 * R46 (0x2E) - Right INP PGA gain ctrl
742 */
743#define WM8983_INPGAVU 0x0100 /* INPGAVU */
744#define WM8983_INPGAVU_MASK 0x0100 /* INPGAVU */
745#define WM8983_INPGAVU_SHIFT 8 /* INPGAVU */
746#define WM8983_INPGAVU_WIDTH 1 /* INPGAVU */
747#define WM8983_INPPGAZCR 0x0080 /* INPPGAZCR */
748#define WM8983_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */
749#define WM8983_INPPGAZCR_SHIFT 7 /* INPPGAZCR */
750#define WM8983_INPPGAZCR_WIDTH 1 /* INPPGAZCR */
751#define WM8983_INPPGAMUTER 0x0040 /* INPPGAMUTER */
752#define WM8983_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */
753#define WM8983_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */
754#define WM8983_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */
755#define WM8983_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */
756#define WM8983_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */
757#define WM8983_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */
758
759/*
760 * R47 (0x2F) - Left ADC BOOST ctrl
761 */
762#define WM8983_PGABOOSTL 0x0100 /* PGABOOSTL */
763#define WM8983_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */
764#define WM8983_PGABOOSTL_SHIFT 8 /* PGABOOSTL */
765#define WM8983_PGABOOSTL_WIDTH 1 /* PGABOOSTL */
766#define WM8983_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */
767#define WM8983_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */
768#define WM8983_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */
769#define WM8983_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */
770#define WM8983_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */
771#define WM8983_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */
772
773/*
774 * R48 (0x30) - Right ADC BOOST ctrl
775 */
776#define WM8983_PGABOOSTR 0x0100 /* PGABOOSTR */
777#define WM8983_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */
778#define WM8983_PGABOOSTR_SHIFT 8 /* PGABOOSTR */
779#define WM8983_PGABOOSTR_WIDTH 1 /* PGABOOSTR */
780#define WM8983_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */
781#define WM8983_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */
782#define WM8983_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */
783#define WM8983_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */
784#define WM8983_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */
785#define WM8983_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */
786
787/*
788 * R49 (0x31) - Output ctrl
789 */
790#define WM8983_DACL2RMIX 0x0040 /* DACL2RMIX */
791#define WM8983_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */
792#define WM8983_DACL2RMIX_SHIFT 6 /* DACL2RMIX */
793#define WM8983_DACL2RMIX_WIDTH 1 /* DACL2RMIX */
794#define WM8983_DACR2LMIX 0x0020 /* DACR2LMIX */
795#define WM8983_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */
796#define WM8983_DACR2LMIX_SHIFT 5 /* DACR2LMIX */
797#define WM8983_DACR2LMIX_WIDTH 1 /* DACR2LMIX */
798#define WM8983_OUT4BOOST 0x0010 /* OUT4BOOST */
799#define WM8983_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */
800#define WM8983_OUT4BOOST_SHIFT 4 /* OUT4BOOST */
801#define WM8983_OUT4BOOST_WIDTH 1 /* OUT4BOOST */
802#define WM8983_OUT3BOOST 0x0008 /* OUT3BOOST */
803#define WM8983_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */
804#define WM8983_OUT3BOOST_SHIFT 3 /* OUT3BOOST */
805#define WM8983_OUT3BOOST_WIDTH 1 /* OUT3BOOST */
806#define WM8983_SPKBOOST 0x0004 /* SPKBOOST */
807#define WM8983_SPKBOOST_MASK 0x0004 /* SPKBOOST */
808#define WM8983_SPKBOOST_SHIFT 2 /* SPKBOOST */
809#define WM8983_SPKBOOST_WIDTH 1 /* SPKBOOST */
810#define WM8983_TSDEN 0x0002 /* TSDEN */
811#define WM8983_TSDEN_MASK 0x0002 /* TSDEN */
812#define WM8983_TSDEN_SHIFT 1 /* TSDEN */
813#define WM8983_TSDEN_WIDTH 1 /* TSDEN */
814#define WM8983_VROI 0x0001 /* VROI */
815#define WM8983_VROI_MASK 0x0001 /* VROI */
816#define WM8983_VROI_SHIFT 0 /* VROI */
817#define WM8983_VROI_WIDTH 1 /* VROI */
818
819/*
820 * R50 (0x32) - Left mixer ctrl
821 */
822#define WM8983_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */
823#define WM8983_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */
824#define WM8983_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */
825#define WM8983_AUXL2LMIX 0x0020 /* AUXL2LMIX */
826#define WM8983_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */
827#define WM8983_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */
828#define WM8983_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */
829#define WM8983_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */
830#define WM8983_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */
831#define WM8983_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */
832#define WM8983_BYPL2LMIX 0x0002 /* BYPL2LMIX */
833#define WM8983_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */
834#define WM8983_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */
835#define WM8983_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */
836#define WM8983_DACL2LMIX 0x0001 /* DACL2LMIX */
837#define WM8983_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */
838#define WM8983_DACL2LMIX_SHIFT 0 /* DACL2LMIX */
839#define WM8983_DACL2LMIX_WIDTH 1 /* DACL2LMIX */
840
841/*
842 * R51 (0x33) - Right mixer ctrl
843 */
844#define WM8983_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */
845#define WM8983_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */
846#define WM8983_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */
847#define WM8983_AUXR2RMIX 0x0020 /* AUXR2RMIX */
848#define WM8983_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */
849#define WM8983_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */
850#define WM8983_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */
851#define WM8983_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */
852#define WM8983_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */
853#define WM8983_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */
854#define WM8983_BYPR2RMIX 0x0002 /* BYPR2RMIX */
855#define WM8983_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */
856#define WM8983_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */
857#define WM8983_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */
858#define WM8983_DACR2RMIX 0x0001 /* DACR2RMIX */
859#define WM8983_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */
860#define WM8983_DACR2RMIX_SHIFT 0 /* DACR2RMIX */
861#define WM8983_DACR2RMIX_WIDTH 1 /* DACR2RMIX */
862
863/*
864 * R52 (0x34) - LOUT1 (HP) volume ctrl
865 */
866#define WM8983_OUT1VU 0x0100 /* OUT1VU */
867#define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */
868#define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */
869#define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */
870#define WM8983_LOUT1ZC 0x0080 /* LOUT1ZC */
871#define WM8983_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */
872#define WM8983_LOUT1ZC_SHIFT 7 /* LOUT1ZC */
873#define WM8983_LOUT1ZC_WIDTH 1 /* LOUT1ZC */
874#define WM8983_LOUT1MUTE 0x0040 /* LOUT1MUTE */
875#define WM8983_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */
876#define WM8983_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */
877#define WM8983_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */
878#define WM8983_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */
879#define WM8983_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */
880#define WM8983_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */
881
882/*
883 * R53 (0x35) - ROUT1 (HP) volume ctrl
884 */
885#define WM8983_OUT1VU 0x0100 /* OUT1VU */
886#define WM8983_OUT1VU_MASK 0x0100 /* OUT1VU */
887#define WM8983_OUT1VU_SHIFT 8 /* OUT1VU */
888#define WM8983_OUT1VU_WIDTH 1 /* OUT1VU */
889#define WM8983_ROUT1ZC 0x0080 /* ROUT1ZC */
890#define WM8983_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */
891#define WM8983_ROUT1ZC_SHIFT 7 /* ROUT1ZC */
892#define WM8983_ROUT1ZC_WIDTH 1 /* ROUT1ZC */
893#define WM8983_ROUT1MUTE 0x0040 /* ROUT1MUTE */
894#define WM8983_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */
895#define WM8983_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */
896#define WM8983_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */
897#define WM8983_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */
898#define WM8983_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */
899#define WM8983_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */
900
901/*
902 * R54 (0x36) - LOUT2 (SPK) volume ctrl
903 */
904#define WM8983_OUT2VU 0x0100 /* OUT2VU */
905#define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */
906#define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */
907#define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */
908#define WM8983_LOUT2ZC 0x0080 /* LOUT2ZC */
909#define WM8983_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */
910#define WM8983_LOUT2ZC_SHIFT 7 /* LOUT2ZC */
911#define WM8983_LOUT2ZC_WIDTH 1 /* LOUT2ZC */
912#define WM8983_LOUT2MUTE 0x0040 /* LOUT2MUTE */
913#define WM8983_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */
914#define WM8983_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */
915#define WM8983_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */
916#define WM8983_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */
917#define WM8983_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */
918#define WM8983_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */
919
920/*
921 * R55 (0x37) - ROUT2 (SPK) volume ctrl
922 */
923#define WM8983_OUT2VU 0x0100 /* OUT2VU */
924#define WM8983_OUT2VU_MASK 0x0100 /* OUT2VU */
925#define WM8983_OUT2VU_SHIFT 8 /* OUT2VU */
926#define WM8983_OUT2VU_WIDTH 1 /* OUT2VU */
927#define WM8983_ROUT2ZC 0x0080 /* ROUT2ZC */
928#define WM8983_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */
929#define WM8983_ROUT2ZC_SHIFT 7 /* ROUT2ZC */
930#define WM8983_ROUT2ZC_WIDTH 1 /* ROUT2ZC */
931#define WM8983_ROUT2MUTE 0x0040 /* ROUT2MUTE */
932#define WM8983_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */
933#define WM8983_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */
934#define WM8983_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */
935#define WM8983_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */
936#define WM8983_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */
937#define WM8983_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */
938
939/*
940 * R56 (0x38) - OUT3 mixer ctrl
941 */
942#define WM8983_OUT3MUTE 0x0040 /* OUT3MUTE */
943#define WM8983_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */
944#define WM8983_OUT3MUTE_SHIFT 6 /* OUT3MUTE */
945#define WM8983_OUT3MUTE_WIDTH 1 /* OUT3MUTE */
946#define WM8983_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */
947#define WM8983_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */
948#define WM8983_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */
949#define WM8983_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */
950#define WM8983_BYPL2OUT3 0x0004 /* BYPL2OUT3 */
951#define WM8983_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */
952#define WM8983_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */
953#define WM8983_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */
954#define WM8983_LMIX2OUT3 0x0002 /* LMIX2OUT3 */
955#define WM8983_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */
956#define WM8983_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */
957#define WM8983_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */
958#define WM8983_LDAC2OUT3 0x0001 /* LDAC2OUT3 */
959#define WM8983_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */
960#define WM8983_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */
961#define WM8983_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */
962
963/*
964 * R57 (0x39) - OUT4 (MONO) mix ctrl
965 */
966#define WM8983_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */
967#define WM8983_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */
968#define WM8983_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */
969#define WM8983_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */
970#define WM8983_OUT4MUTE 0x0040 /* OUT4MUTE */
971#define WM8983_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */
972#define WM8983_OUT4MUTE_SHIFT 6 /* OUT4MUTE */
973#define WM8983_OUT4MUTE_WIDTH 1 /* OUT4MUTE */
974#define WM8983_OUT4ATTN 0x0020 /* OUT4ATTN */
975#define WM8983_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */
976#define WM8983_OUT4ATTN_SHIFT 5 /* OUT4ATTN */
977#define WM8983_OUT4ATTN_WIDTH 1 /* OUT4ATTN */
978#define WM8983_LMIX2OUT4 0x0010 /* LMIX2OUT4 */
979#define WM8983_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */
980#define WM8983_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */
981#define WM8983_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */
982#define WM8983_LDAC2OUT4 0x0008 /* LDAC2OUT4 */
983#define WM8983_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */
984#define WM8983_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */
985#define WM8983_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */
986#define WM8983_BYPR2OUT4 0x0004 /* BYPR2OUT4 */
987#define WM8983_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */
988#define WM8983_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */
989#define WM8983_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */
990#define WM8983_RMIX2OUT4 0x0002 /* RMIX2OUT4 */
991#define WM8983_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */
992#define WM8983_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */
993#define WM8983_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */
994#define WM8983_RDAC2OUT4 0x0001 /* RDAC2OUT4 */
995#define WM8983_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */
996#define WM8983_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */
997#define WM8983_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */
998
999/*
1000 * R61 (0x3D) - BIAS CTRL
1001 */
1002#define WM8983_BIASCUT 0x0100 /* BIASCUT */
1003#define WM8983_BIASCUT_MASK 0x0100 /* BIASCUT */
1004#define WM8983_BIASCUT_SHIFT 8 /* BIASCUT */
1005#define WM8983_BIASCUT_WIDTH 1 /* BIASCUT */
1006#define WM8983_HALFIPBIAS 0x0080 /* HALFIPBIAS */
1007#define WM8983_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */
1008#define WM8983_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */
1009#define WM8983_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */
1010#define WM8983_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */
1011#define WM8983_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */
1012#define WM8983_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */
1013#define WM8983_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */
1014#define WM8983_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */
1015#define WM8983_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */
1016#define WM8983_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */
1017#define WM8983_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */
1018#define WM8983_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */
1019#define WM8983_HALFOPBIAS 0x0001 /* HALFOPBIAS */
1020#define WM8983_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */
1021#define WM8983_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */
1022#define WM8983_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */
1023
1024enum clk_src {
1025 WM8983_CLKSRC_MCLK,
1026 WM8983_CLKSRC_PLL
1027};
1028
1029#endif /* _WM8983_H */
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 9e5ff789b805..6e85b8869af7 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -876,7 +876,7 @@ SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
876 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), 876 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
877SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0, 877SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0,
878 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 878 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
879 879SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
880}; 880};
881 881
882static const struct snd_soc_dapm_route routes[] = { 882static const struct snd_soc_dapm_route routes[] = {
@@ -1434,6 +1434,7 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1434 1434
1435 wm8993->hubs_data.hp_startup_mode = 1; 1435 wm8993->hubs_data.hp_startup_mode = 1;
1436 wm8993->hubs_data.dcs_codes = -2; 1436 wm8993->hubs_data.dcs_codes = -2;
1437 wm8993->hubs_data.series_startup = 1;
1437 1438
1438 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1439 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1439 if (ret != 0) { 1440 if (ret != 0) {
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index c2fc0356c2a4..09e680ae88b2 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -195,10 +195,6 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
195 aif + 1, rate); 195 aif + 1, rate);
196 } 196 }
197 197
198 if (rate && rate < 3000000)
199 dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
200 aif + 1, rate);
201
202 wm8994->aifclk[aif] = rate; 198 wm8994->aifclk[aif] = rate;
203 199
204 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, 200 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
@@ -1146,13 +1142,33 @@ SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1146 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1142 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1147SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, 1143SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1148 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1144 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1145SND_SOC_DAPM_PGA_E("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0,
1146 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1147
1148SND_SOC_DAPM_MIXER_E("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1149 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer),
1150 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1151SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1152 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer),
1153 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1154SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux,
1155 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1156SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux,
1157 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1149 1158
1150SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) 1159SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
1151}; 1160};
1152 1161
1153static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { 1162static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
1154SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), 1163SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1155SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0) 1164SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
1165SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
1166SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1167 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
1168SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1169 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
1170SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1171SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1156}; 1172};
1157 1173
1158static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { 1174static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
@@ -1190,7 +1206,6 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"),
1190SND_SOC_DAPM_INPUT("DMIC2DAT"), 1206SND_SOC_DAPM_INPUT("DMIC2DAT"),
1191SND_SOC_DAPM_INPUT("Clock"), 1207SND_SOC_DAPM_INPUT("Clock"),
1192 1208
1193SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
1194SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, 1209SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1195 SND_SOC_DAPM_PRE_PMU), 1210 SND_SOC_DAPM_PRE_PMU),
1196 1211
@@ -1283,14 +1298,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
1283SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), 1298SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
1284SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), 1299SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
1285 1300
1286SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1287SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1288
1289SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1290 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
1291SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1292 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
1293
1294SND_SOC_DAPM_POST("Debug log", post_ev), 1301SND_SOC_DAPM_POST("Debug log", post_ev),
1295}; 1302};
1296 1303
@@ -1509,8 +1516,10 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1509 { "AIF2DACDAT", NULL, "AIF1DACDAT" }, 1516 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
1510 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, 1517 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
1511 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, 1518 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
1512 { "MICBIAS", NULL, "CLK_SYS" }, 1519 { "MICBIAS1", NULL, "CLK_SYS" },
1513 { "MICBIAS", NULL, "MICBIAS Supply" }, 1520 { "MICBIAS1", NULL, "MICBIAS Supply" },
1521 { "MICBIAS2", NULL, "CLK_SYS" },
1522 { "MICBIAS2", NULL, "MICBIAS Supply" },
1514}; 1523};
1515 1524
1516static const struct snd_soc_dapm_route wm8994_intercon[] = { 1525static const struct snd_soc_dapm_route wm8994_intercon[] = {
@@ -1623,6 +1632,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1623 int reg_offset, ret; 1632 int reg_offset, ret;
1624 struct fll_div fll; 1633 struct fll_div fll;
1625 u16 reg, aif1, aif2; 1634 u16 reg, aif1, aif2;
1635 unsigned long timeout;
1626 1636
1627 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) 1637 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
1628 & WM8994_AIF1CLK_ENA; 1638 & WM8994_AIF1CLK_ENA;
@@ -1704,6 +1714,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1704 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | 1714 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
1705 (src - 1)); 1715 (src - 1));
1706 1716
1717 /* Clear any pending completion from a previous failure */
1718 try_wait_for_completion(&wm8994->fll_locked[id]);
1719
1707 /* Enable (with fractional mode if required) */ 1720 /* Enable (with fractional mode if required) */
1708 if (freq_out) { 1721 if (freq_out) {
1709 if (fll.k) 1722 if (fll.k)
@@ -1714,7 +1727,15 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1714 WM8994_FLL1_ENA | WM8994_FLL1_FRAC, 1727 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
1715 reg); 1728 reg);
1716 1729
1717 msleep(5); 1730 if (wm8994->fll_locked_irq) {
1731 timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
1732 msecs_to_jiffies(10));
1733 if (timeout == 0)
1734 dev_warn(codec->dev,
1735 "Timed out waiting for FLL lock\n");
1736 } else {
1737 msleep(5);
1738 }
1718 } 1739 }
1719 1740
1720 wm8994->fll[id].in = freq_in; 1741 wm8994->fll[id].in = freq_in;
@@ -1732,6 +1753,14 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1732 return 0; 1753 return 0;
1733} 1754}
1734 1755
1756static irqreturn_t wm8994_fll_locked_irq(int irq, void *data)
1757{
1758 struct completion *completion = data;
1759
1760 complete(completion);
1761
1762 return IRQ_HANDLED;
1763}
1735 1764
1736static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; 1765static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
1737 1766
@@ -2271,6 +2300,33 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2271 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2300 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2272} 2301}
2273 2302
2303static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2304 struct snd_soc_dai *dai)
2305{
2306 struct snd_soc_codec *codec = dai->codec;
2307 int rate_reg = 0;
2308
2309 switch (dai->id) {
2310 case 1:
2311 rate_reg = WM8994_AIF1_RATE;
2312 break;
2313 case 2:
2314 rate_reg = WM8994_AIF1_RATE;
2315 break;
2316 default:
2317 break;
2318 }
2319
2320 /* If the DAI is idle then configure the divider tree for the
2321 * lowest output rate to save a little power if the clock is
2322 * still active (eg, because it is system clock).
2323 */
2324 if (rate_reg && !dai->playback_active && !dai->capture_active)
2325 snd_soc_update_bits(codec, rate_reg,
2326 WM8994_AIF1_SR_MASK |
2327 WM8994_AIF1CLK_RATE_MASK, 0x9);
2328}
2329
2274static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2330static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
2275{ 2331{
2276 struct snd_soc_codec *codec = codec_dai->codec; 2332 struct snd_soc_codec *codec = codec_dai->codec;
@@ -2337,6 +2393,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
2337 .set_sysclk = wm8994_set_dai_sysclk, 2393 .set_sysclk = wm8994_set_dai_sysclk,
2338 .set_fmt = wm8994_set_dai_fmt, 2394 .set_fmt = wm8994_set_dai_fmt,
2339 .hw_params = wm8994_hw_params, 2395 .hw_params = wm8994_hw_params,
2396 .shutdown = wm8994_aif_shutdown,
2340 .digital_mute = wm8994_aif_mute, 2397 .digital_mute = wm8994_aif_mute,
2341 .set_pll = wm8994_set_fll, 2398 .set_pll = wm8994_set_fll,
2342 .set_tristate = wm8994_set_tristate, 2399 .set_tristate = wm8994_set_tristate,
@@ -2346,6 +2403,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
2346 .set_sysclk = wm8994_set_dai_sysclk, 2403 .set_sysclk = wm8994_set_dai_sysclk,
2347 .set_fmt = wm8994_set_dai_fmt, 2404 .set_fmt = wm8994_set_dai_fmt,
2348 .hw_params = wm8994_hw_params, 2405 .hw_params = wm8994_hw_params,
2406 .shutdown = wm8994_aif_shutdown,
2349 .digital_mute = wm8994_aif_mute, 2407 .digital_mute = wm8994_aif_mute,
2350 .set_pll = wm8994_set_fll, 2408 .set_pll = wm8994_set_fll,
2351 .set_tristate = wm8994_set_tristate, 2409 .set_tristate = wm8994_set_tristate,
@@ -2763,7 +2821,7 @@ static void wm8958_default_micdet(u16 status, void *data)
2763 report = SND_JACK_MICROPHONE; 2821 report = SND_JACK_MICROPHONE;
2764 2822
2765 /* Everything else is buttons; just assign slots */ 2823 /* Everything else is buttons; just assign slots */
2766 if (status & 0x1c0) 2824 if (status & 0x1c)
2767 report |= SND_JACK_BTN_0; 2825 report |= SND_JACK_BTN_0;
2768 2826
2769done: 2827done:
@@ -2849,6 +2907,15 @@ out:
2849 return IRQ_HANDLED; 2907 return IRQ_HANDLED;
2850} 2908}
2851 2909
2910static irqreturn_t wm8994_fifo_error(int irq, void *data)
2911{
2912 struct snd_soc_codec *codec = data;
2913
2914 dev_err(codec->dev, "FIFO error\n");
2915
2916 return IRQ_HANDLED;
2917}
2918
2852static int wm8994_codec_probe(struct snd_soc_codec *codec) 2919static int wm8994_codec_probe(struct snd_soc_codec *codec)
2853{ 2920{
2854 struct wm8994 *control; 2921 struct wm8994 *control;
@@ -2867,6 +2934,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2867 wm8994->pdata = dev_get_platdata(codec->dev->parent); 2934 wm8994->pdata = dev_get_platdata(codec->dev->parent);
2868 wm8994->codec = codec; 2935 wm8994->codec = codec;
2869 2936
2937 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
2938 init_completion(&wm8994->fll_locked[i]);
2939
2870 if (wm8994->pdata && wm8994->pdata->micdet_irq) 2940 if (wm8994->pdata && wm8994->pdata->micdet_irq)
2871 wm8994->micdet_irq = wm8994->pdata->micdet_irq; 2941 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
2872 else if (wm8994->pdata && wm8994->pdata->irq_base) 2942 else if (wm8994->pdata && wm8994->pdata->irq_base)
@@ -2905,6 +2975,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2905 wm8994->hubs.dcs_codes = -5; 2975 wm8994->hubs.dcs_codes = -5;
2906 wm8994->hubs.hp_startup_mode = 1; 2976 wm8994->hubs.hp_startup_mode = 1;
2907 wm8994->hubs.dcs_readback_mode = 1; 2977 wm8994->hubs.dcs_readback_mode = 1;
2978 wm8994->hubs.series_startup = 1;
2908 break; 2979 break;
2909 default: 2980 default:
2910 wm8994->hubs.dcs_readback_mode = 1; 2981 wm8994->hubs.dcs_readback_mode = 1;
@@ -2919,6 +2990,15 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2919 break; 2990 break;
2920 } 2991 }
2921 2992
2993 wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR,
2994 wm8994_fifo_error, "FIFO error", codec);
2995
2996 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
2997 wm_hubs_dcs_done, "DC servo done",
2998 &wm8994->hubs);
2999 if (ret == 0)
3000 wm8994->hubs.dcs_done_irq = true;
3001
2922 switch (control->type) { 3002 switch (control->type) {
2923 case WM8994: 3003 case WM8994:
2924 if (wm8994->micdet_irq) { 3004 if (wm8994->micdet_irq) {
@@ -2975,6 +3055,16 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2975 } 3055 }
2976 } 3056 }
2977 3057
3058 wm8994->fll_locked_irq = true;
3059 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) {
3060 ret = wm8994_request_irq(codec->control_data,
3061 WM8994_IRQ_FLL1_LOCK + i,
3062 wm8994_fll_locked_irq, "FLL lock",
3063 &wm8994->fll_locked[i]);
3064 if (ret != 0)
3065 wm8994->fll_locked_irq = false;
3066 }
3067
2978 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3068 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
2979 * configured on init - if a system wants to do this dynamically 3069 * configured on init - if a system wants to do this dynamically
2980 * at runtime we can deal with that then. 3070 * at runtime we can deal with that then.
@@ -3050,10 +3140,18 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3050 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT, 3140 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3051 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT); 3141 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3052 3142
3053 /* Unconditionally enable AIF1 ADC TDM mode; it only affects 3143 /* Unconditionally enable AIF1 ADC TDM mode on chips which can
3054 * behaviour on idle TDM clock cycles. */ 3144 * use this; it only affects behaviour on idle TDM clock
3055 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1, 3145 * cycles. */
3056 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM); 3146 switch (control->type) {
3147 case WM8994:
3148 case WM8958:
3149 snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
3150 WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
3151 break;
3152 default:
3153 break;
3154 }
3057 3155
3058 wm8994_update_class_w(codec); 3156 wm8994_update_class_w(codec);
3059 3157
@@ -3152,6 +3250,12 @@ err_irq:
3152 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3250 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
3153 if (wm8994->micdet_irq) 3251 if (wm8994->micdet_irq)
3154 free_irq(wm8994->micdet_irq, wm8994); 3252 free_irq(wm8994->micdet_irq, wm8994);
3253 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3254 wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
3255 &wm8994->fll_locked[i]);
3256 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3257 &wm8994->hubs);
3258 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3155err: 3259err:
3156 kfree(wm8994); 3260 kfree(wm8994);
3157 return ret; 3261 return ret;
@@ -3161,11 +3265,20 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3161{ 3265{
3162 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3266 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3163 struct wm8994 *control = codec->control_data; 3267 struct wm8994 *control = codec->control_data;
3268 int i;
3164 3269
3165 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 3270 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3166 3271
3167 pm_runtime_disable(codec->dev); 3272 pm_runtime_disable(codec->dev);
3168 3273
3274 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3275 wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i,
3276 &wm8994->fll_locked[i]);
3277
3278 wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE,
3279 &wm8994->hubs);
3280 wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec);
3281
3169 switch (control->type) { 3282 switch (control->type) {
3170 case WM8994: 3283 case WM8994:
3171 if (wm8994->micdet_irq) 3284 if (wm8994->micdet_irq)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0a1db04b73bd..1ab2266039f7 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -11,6 +11,7 @@
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h> 13#include <linux/firmware.h>
14#include <linux/completion.h>
14 15
15#include "wm_hubs.h" 16#include "wm_hubs.h"
16 17
@@ -79,6 +80,8 @@ struct wm8994_priv {
79 int mclk[2]; 80 int mclk[2];
80 int aifclk[2]; 81 int aifclk[2];
81 struct wm8994_fll_config fll[2], fll_suspend[2]; 82 struct wm8994_fll_config fll[2], fll_suspend[2];
83 struct completion fll_locked[2];
84 bool fll_locked_irq;
82 85
83 int dac_rates[2]; 86 int dac_rates[2];
84 int lrclk_shared[2]; 87 int lrclk_shared[2];
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 91c6b39de50c..a4691321f9b3 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -727,7 +727,7 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
728 728
729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0), 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0), 730SND_SOC_DAPM_OUT_DRV("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
731 731
732SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
733SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 9e370d14ad88..4cc2d567f22f 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -63,8 +63,10 @@ static const struct soc_enum speaker_mode =
63 63
64static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) 64static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
65{ 65{
66 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
66 unsigned int reg; 67 unsigned int reg;
67 int count = 0; 68 int count = 0;
69 int timeout;
68 unsigned int val; 70 unsigned int val;
69 71
70 val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1; 72 val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
@@ -74,18 +76,39 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
74 76
75 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 77 dev_dbg(codec->dev, "Waiting for DC servo...\n");
76 78
79 if (hubs->dcs_done_irq)
80 timeout = 4;
81 else
82 timeout = 400;
83
77 do { 84 do {
78 count++; 85 count++;
79 msleep(1); 86
87 if (hubs->dcs_done_irq)
88 wait_for_completion_timeout(&hubs->dcs_done,
89 msecs_to_jiffies(250));
90 else
91 msleep(1);
92
80 reg = snd_soc_read(codec, WM8993_DC_SERVO_0); 93 reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
81 dev_dbg(codec->dev, "DC servo: %x\n", reg); 94 dev_dbg(codec->dev, "DC servo: %x\n", reg);
82 } while (reg & op && count < 400); 95 } while (reg & op && count < timeout);
83 96
84 if (reg & op) 97 if (reg & op)
85 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n", 98 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
86 op); 99 op);
87} 100}
88 101
102irqreturn_t wm_hubs_dcs_done(int irq, void *data)
103{
104 struct wm_hubs_data *hubs = data;
105
106 complete(&hubs->dcs_done);
107
108 return IRQ_HANDLED;
109}
110EXPORT_SYMBOL_GPL(wm_hubs_dcs_done);
111
89/* 112/*
90 * Startup calibration of the DC servo 113 * Startup calibration of the DC servo
91 */ 114 */
@@ -107,8 +130,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
107 return; 130 return;
108 } 131 }
109 132
110 /* Devices not using a DCS code correction have startup mode */ 133 if (hubs->series_startup) {
111 if (hubs->dcs_codes) {
112 /* Set for 32 series updates */ 134 /* Set for 32 series updates */
113 snd_soc_update_bits(codec, WM8993_DC_SERVO_1, 135 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
114 WM8993_DCS_SERIES_NO_01_MASK, 136 WM8993_DCS_SERIES_NO_01_MASK,
@@ -134,9 +156,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
134 break; 156 break;
135 case 1: 157 case 1:
136 reg = snd_soc_read(codec, WM8993_DC_SERVO_3); 158 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
137 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) 159 reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
138 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; 160 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
139 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; 161 reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
140 break; 162 break;
141 default: 163 default:
142 WARN(1, "Unknown DCS readback method\n"); 164 WARN(1, "Unknown DCS readback method\n");
@@ -150,13 +172,13 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
150 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 172 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
151 hubs->dcs_codes); 173 hubs->dcs_codes);
152 174
153 /* HPOUT1L */ 175 /* HPOUT1R */
154 offset = reg_l; 176 offset = reg_r;
155 offset += hubs->dcs_codes; 177 offset += hubs->dcs_codes;
156 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 178 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
157 179
158 /* HPOUT1R */ 180 /* HPOUT1L */
159 offset = reg_r; 181 offset = reg_l;
160 offset += hubs->dcs_codes; 182 offset += hubs->dcs_codes;
161 dcs_cfg |= (u8)offset; 183 dcs_cfg |= (u8)offset;
162 184
@@ -168,8 +190,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
168 WM8993_DCS_TRIG_DAC_WR_0 | 190 WM8993_DCS_TRIG_DAC_WR_0 |
169 WM8993_DCS_TRIG_DAC_WR_1); 191 WM8993_DCS_TRIG_DAC_WR_1);
170 } else { 192 } else {
171 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT; 193 dcs_cfg = reg_r << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
172 dcs_cfg |= reg_r; 194 dcs_cfg |= reg_l;
173 } 195 }
174 196
175 /* Save the callibrated offset if we're in class W mode and 197 /* Save the callibrated offset if we're in class W mode and
@@ -195,7 +217,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
195 217
196 /* If we're applying an offset correction then updating the 218 /* If we're applying an offset correction then updating the
197 * callibration would be likely to introduce further offsets. */ 219 * callibration would be likely to introduce further offsets. */
198 if (hubs->dcs_codes) 220 if (hubs->dcs_codes || hubs->no_series_update)
199 return ret; 221 return ret;
200 222
201 /* Only need to do this if the outputs are active */ 223 /* Only need to do this if the outputs are active */
@@ -599,9 +621,6 @@ SND_SOC_DAPM_MIXER("IN2L PGA", WM8993_POWER_MANAGEMENT_2, 7, 0,
599SND_SOC_DAPM_MIXER("IN2R PGA", WM8993_POWER_MANAGEMENT_2, 5, 0, 621SND_SOC_DAPM_MIXER("IN2R PGA", WM8993_POWER_MANAGEMENT_2, 5, 0,
600 in2r_pga, ARRAY_SIZE(in2r_pga)), 622 in2r_pga, ARRAY_SIZE(in2r_pga)),
601 623
602/* Dummy widgets to represent differential paths */
603SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
604
605SND_SOC_DAPM_MIXER("MIXINL", WM8993_POWER_MANAGEMENT_2, 9, 0, 624SND_SOC_DAPM_MIXER("MIXINL", WM8993_POWER_MANAGEMENT_2, 9, 0,
606 mixinl, ARRAY_SIZE(mixinl)), 625 mixinl, ARRAY_SIZE(mixinl)),
607SND_SOC_DAPM_MIXER("MIXINR", WM8993_POWER_MANAGEMENT_2, 8, 0, 626SND_SOC_DAPM_MIXER("MIXINR", WM8993_POWER_MANAGEMENT_2, 8, 0,
@@ -867,8 +886,11 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
867int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, 886int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
868 int lineout1_diff, int lineout2_diff) 887 int lineout1_diff, int lineout2_diff)
869{ 888{
889 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
870 struct snd_soc_dapm_context *dapm = &codec->dapm; 890 struct snd_soc_dapm_context *dapm = &codec->dapm;
871 891
892 init_completion(&hubs->dcs_done);
893
872 snd_soc_dapm_add_routes(dapm, analogue_routes, 894 snd_soc_dapm_add_routes(dapm, analogue_routes,
873 ARRAY_SIZE(analogue_routes)); 895 ARRAY_SIZE(analogue_routes));
874 896
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index f8a5e976b5e6..676b1252ab91 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -14,6 +14,9 @@
14#ifndef _WM_HUBS_H 14#ifndef _WM_HUBS_H
15#define _WM_HUBS_H 15#define _WM_HUBS_H
16 16
17#include <linux/completion.h>
18#include <linux/interrupt.h>
19
17struct snd_soc_codec; 20struct snd_soc_codec;
18 21
19extern const unsigned int wm_hubs_spkmix_tlv[]; 22extern const unsigned int wm_hubs_spkmix_tlv[];
@@ -23,9 +26,14 @@ struct wm_hubs_data {
23 int dcs_codes; 26 int dcs_codes;
24 int dcs_readback_mode; 27 int dcs_readback_mode;
25 int hp_startup_mode; 28 int hp_startup_mode;
29 int series_startup;
30 int no_series_update;
26 31
27 bool class_w; 32 bool class_w;
28 u16 class_w_dcs; 33 u16 class_w_dcs;
34
35 bool dcs_done_irq;
36 struct completion dcs_done;
29}; 37};
30 38
31extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 39extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
@@ -36,4 +44,6 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
36 int jd_scthr, int jd_thr, 44 int jd_scthr, int jd_thr,
37 int micbias1_lvl, int micbias2_lvl); 45 int micbias1_lvl, int micbias2_lvl);
38 46
47extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
48
39#endif 49#endif