aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-05 09:07:33 -0500
committerTakashi Iwai <tiwai@suse.de>2012-03-05 09:07:33 -0500
commit650d6e25cde82fda425995ba77ed4b0ad3be5b8d (patch)
tree44ed9829a0b1797d4eea907aa1ed68273f7e3692 /sound/soc
parent6b21ed851624a03f11ea9ed3f229f56419e03686 (diff)
parentad20ff920c1fd217578e2c637dd50c1878a21c06 (diff)
Merge tag 'asoc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into topic/asoc
This has been a very active release for ASoC, as well as the usual raft of bugfixes and driver updates there's quite a few framework enhancements. Most are either small or are laying the groundwork for user visible features (especially dynamic PCM), the most directly visible change is the dmaengine library. There's also a bunch of regmap API enhancements pulled into the tree so that either the framework or drivers can take advantage of the new features. Changes include: - Support for widgets not associated with a CODEC, an important part of the dynamic PCM framework. - A library factoring out the common code shared by dmaengine based DMA drivers contributed by Lars-Peter Clausen. This will save a lot of code and make it much easier to deploy enhancements to dmaengine. - Support for binary controls, used for providing runtime configuration of algorithm coefficients. - A new DAPM widget type for regulator supplies allowing drivers for devices that can power down unused supplies while active to do without any per-driver code. - DAPM widgets for DAIs, initially giving a speed boost for playback startup and shutdown and also the basis for CODEC<->CODEC DAI link support. - Support for specifying the number of significant bits on audio interfaces, useful for allowing applications to know how much effort to put into generating data for a larger sample format. - Conversion of the FSI driver used on some SH processors to DMAEngine. - New CODEC drivers for Maxim MAX9768 and Wolfson Microelectronics WM2200.
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig3
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c37
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c17
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c17
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c29
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c20
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c13
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1701.c16
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c13
-rw-r--r--sound/soc/codecs/Kconfig8
-rw-r--r--sound/soc/codecs/Makefile4
-rw-r--r--sound/soc/codecs/ad1836.c6
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/adau1373.c7
-rw-r--r--sound/soc/codecs/adau1701.c2
-rw-r--r--sound/soc/codecs/ak4104.c174
-rw-r--r--sound/soc/codecs/ak4535.c98
-rw-r--r--sound/soc/codecs/ak4535.h2
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c2
-rw-r--r--sound/soc/codecs/alc5623.c8
-rw-r--r--sound/soc/codecs/alc5632.c195
-rw-r--r--sound/soc/codecs/alc5632.h1
-rw-r--r--sound/soc/codecs/cq93vc.c2
-rw-r--r--sound/soc/codecs/cs4270.c4
-rw-r--r--sound/soc/codecs/cs4271.c2
-rw-r--r--sound/soc/codecs/cs42l73.c2
-rw-r--r--sound/soc/codecs/lm4857.c2
-rw-r--r--sound/soc/codecs/max9768.c247
-rw-r--r--sound/soc/codecs/max98088.c4
-rw-r--r--sound/soc/codecs/max98095.c6
-rw-r--r--sound/soc/codecs/max9877.c2
-rw-r--r--sound/soc/codecs/sn95031.c5
-rw-r--r--sound/soc/codecs/ssm2602.c2
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/tlv320aic26.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c66
-rw-r--r--sound/soc/codecs/tlv320aic3x.h9
-rw-r--r--sound/soc/codecs/tlv320dac33.c4
-rw-r--r--sound/soc/codecs/tpa6130a2.c4
-rw-r--r--sound/soc/codecs/twl4030.c35
-rw-r--r--sound/soc/codecs/twl6040.c2
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/wl1273.c2
-rw-r--r--sound/soc/codecs/wm2000.c31
-rw-r--r--sound/soc/codecs/wm2200.c2286
-rw-r--r--sound/soc/codecs/wm2200.h3674
-rw-r--r--sound/soc/codecs/wm5100.c306
-rw-r--r--sound/soc/codecs/wm8737.c2
-rw-r--r--sound/soc/codecs/wm8753.c15
-rw-r--r--sound/soc/codecs/wm8770.c5
-rw-r--r--sound/soc/codecs/wm8776.c8
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8904.c18
-rw-r--r--sound/soc/codecs/wm8940.c2
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c16
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c316
-rw-r--r--sound/soc/codecs/wm8988.c142
-rw-r--r--sound/soc/codecs/wm8990.c2
-rw-r--r--sound/soc/codecs/wm8991.c2
-rw-r--r--sound/soc/codecs/wm8993.c54
-rw-r--r--sound/soc/codecs/wm8993.h9
-rw-r--r--sound/soc/codecs/wm8994.c300
-rw-r--r--sound/soc/codecs/wm8994.h5
-rw-r--r--sound/soc/codecs/wm8995.c4
-rw-r--r--sound/soc/codecs/wm8996.c197
-rw-r--r--sound/soc/codecs/wm9081.c80
-rw-r--r--sound/soc/codecs/wm9090.c8
-rw-r--r--sound/soc/codecs/wm9705.c2
-rw-r--r--sound/soc/codecs/wm9712.c16
-rw-r--r--sound/soc/codecs/wm9713.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c166
-rw-r--r--sound/soc/codecs/wm_hubs.h12
-rw-r--r--sound/soc/fsl/mpc5200_dma.c1
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c16
-rw-r--r--sound/soc/fsl/p1022_ds.c4
-rw-r--r--sound/soc/imx/Kconfig6
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c221
-rw-r--r--sound/soc/imx/imx-ssi.c30
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c46
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c47
-rw-r--r--sound/soc/mid-x86/mfld_machine.c2
-rw-r--r--sound/soc/mxs/Kconfig2
-rw-r--r--sound/soc/mxs/mxs-pcm.c157
-rw-r--r--sound/soc/mxs/mxs-pcm.h16
-rw-r--r--sound/soc/mxs/mxs-saif.c56
-rw-r--r--sound/soc/omap/ams-delta.c2
-rw-r--r--sound/soc/omap/n810.c17
-rw-r--r--sound/soc/omap/omap-mcbsp.c8
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/rx51.c25
-rw-r--r--sound/soc/pxa/corgi.c14
-rw-r--r--sound/soc/pxa/magician.c2
-rw-r--r--sound/soc/pxa/poodle.c14
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c10
-rw-r--r--sound/soc/pxa/raumfeld.c2
-rw-r--r--sound/soc/pxa/spitz.c14
-rw-r--r--sound/soc/pxa/tosa.c2
-rw-r--r--sound/soc/samsung/ac97.c4
-rw-r--r--sound/soc/samsung/i2s.c14
-rw-r--r--sound/soc/samsung/i2s.h2
-rw-r--r--sound/soc/samsung/littlemill.c3
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c69
-rw-r--r--sound/soc/samsung/pcm.c4
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c6
-rw-r--r--sound/soc/samsung/smdk_wm8580.c4
-rw-r--r--sound/soc/samsung/smdk_wm9713.c4
-rw-r--r--sound/soc/sh/fsi.c918
-rw-r--r--sound/soc/soc-core.c357
-rw-r--r--sound/soc/soc-dapm.c366
-rw-r--r--sound/soc/soc-dmaengine-pcm.c287
-rw-r--r--sound/soc/soc-io.c6
-rw-r--r--sound/soc/soc-pcm.c68
-rw-r--r--sound/soc/tegra/tegra_alc5632.c130
119 files changed, 9357 insertions, 2380 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 35e662d270e6..91c985599d32 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -25,6 +25,9 @@ if SND_SOC
25config SND_SOC_AC97_BUS 25config SND_SOC_AC97_BUS
26 bool 26 bool
27 27
28config SND_SOC_DMAENGINE_PCM
29 bool
30
28# All the supported SoCs 31# All the supported SoCs
29source "sound/soc/atmel/Kconfig" 32source "sound/soc/atmel/Kconfig"
30source "sound/soc/au1x/Kconfig" 33source "sound/soc/au1x/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9ea8ac827adc..2feaf376e94b 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,6 +1,9 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-io.o 2snd-soc-core-objs += soc-pcm.o soc-io.o
3 3
4snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
5obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
6
4obj-$(CONFIG_SND_SOC) += snd-soc-core.o 7obj-$(CONFIG_SND_SOC) += snd-soc-core.o
5obj-$(CONFIG_SND_SOC) += codecs/ 8obj-$(CONFIG_SND_SOC) += codecs/
6obj-$(CONFIG_SND_SOC) += atmel/ 9obj-$(CONFIG_SND_SOC) += atmel/
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 4ca667d477f9..f65f08beac31 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -46,29 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
46{ 46{
47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 47 struct snd_soc_pcm_runtime *rtd = substream->private_data;
48 struct snd_soc_dai *codec_dai = rtd->codec_dai; 48 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 int err; 49 int err;
51 50
52 /* Set codec DAI configuration */
53 err = snd_soc_dai_set_fmt(codec_dai,
54 SND_SOC_DAIFMT_I2S|
55 SND_SOC_DAIFMT_NB_IF |
56 SND_SOC_DAIFMT_CBM_CFM);
57 if (err < 0) {
58 printk(KERN_ERR "can't set codec DAI configuration\n");
59 return err;
60 }
61
62 /* Set cpu DAI configuration */
63 err = snd_soc_dai_set_fmt(cpu_dai,
64 SND_SOC_DAIFMT_I2S |
65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) {
68 printk(KERN_ERR "can't set cpu DAI configuration\n");
69 return err;
70 }
71
72 /* Set the codec system clock for DAC and ADC */ 51 /* Set the codec system clock for DAC and ADC */
73 err = 52 err =
74 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); 53 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -91,7 +70,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
91 SND_SOC_DAPM_MIC("Mic Jack", NULL), 70 SND_SOC_DAPM_MIC("Mic Jack", NULL),
92}; 71};
93 72
94static const struct snd_soc_dapm_route audio_map[] = { 73static const struct snd_soc_dapm_route afeb9260_audio_map[] = {
95 {"Headphone Jack", NULL, "LHPOUT"}, 74 {"Headphone Jack", NULL, "LHPOUT"},
96 {"Headphone Jack", NULL, "RHPOUT"}, 75 {"Headphone Jack", NULL, "RHPOUT"},
97 76
@@ -106,13 +85,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
106 struct snd_soc_codec *codec = rtd->codec; 85 struct snd_soc_codec *codec = rtd->codec;
107 struct snd_soc_dapm_context *dapm = &codec->dapm; 86 struct snd_soc_dapm_context *dapm = &codec->dapm;
108 87
109 /* Add afeb9260 specific widgets */
110 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
111 ARRAY_SIZE(tlv320aic23_dapm_widgets));
112
113 /* Set up afeb9260 specific audio path audio_map */
114 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
115
116 snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); 88 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
117 snd_soc_dapm_enable_pin(dapm, "Line In"); 89 snd_soc_dapm_enable_pin(dapm, "Line In");
118 snd_soc_dapm_enable_pin(dapm, "Mic Jack"); 90 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
@@ -129,6 +101,8 @@ static struct snd_soc_dai_link afeb9260_dai = {
129 .platform_name = "atmel_pcm-audio", 101 .platform_name = "atmel_pcm-audio",
130 .codec_name = "tlv320aic23-codec.0-001a", 102 .codec_name = "tlv320aic23-codec.0-001a",
131 .init = afeb9260_tlv320aic23_init, 103 .init = afeb9260_tlv320aic23_init,
104 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
105 SND_SOC_DAIFMT_CBM_CFM,
132 .ops = &afeb9260_ops, 106 .ops = &afeb9260_ops,
133}; 107};
134 108
@@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = {
138 .owner = THIS_MODULE, 112 .owner = THIS_MODULE,
139 .dai_link = &afeb9260_dai, 113 .dai_link = &afeb9260_dai,
140 .num_links = 1, 114 .num_links = 1,
115
116 .dapm_widgets = tlv320aic23_dapm_widgets,
117 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
118 .dapm_routes = afeb9260_audio_map,
119 .num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map),
141}; 120};
142 121
143static struct platform_device *afeb9260_snd_device; 122static struct platform_device *afeb9260_snd_device;
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 60962ce6cd4d..d542d4063771 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -40,20 +40,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
40{ 40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
44 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; 43 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
45 int ret = 0; 44 int ret = 0;
46 /* set cpu DAI configuration */
47 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
48 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
49 if (ret < 0)
50 return ret;
51
52 /* set codec DAI configuration */
53 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
54 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
55 if (ret < 0)
56 return ret;
57 45
58 /* set cpu DAI channel mapping */ 46 /* set cpu DAI channel mapping */
59 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), 47 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
@@ -68,6 +56,9 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
68 .hw_params = bf5xx_ad1836_hw_params, 56 .hw_params = bf5xx_ad1836_hw_params,
69}; 57};
70 58
59#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
60 SND_SOC_DAIFMT_CBM_CFM)
61
71static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { 62static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
72 { 63 {
73 .name = "ad1836", 64 .name = "ad1836",
@@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
77 .platform_name = "bfin-tdm-pcm-audio", 68 .platform_name = "bfin-tdm-pcm-audio",
78 .codec_name = "spi0.4", 69 .codec_name = "spi0.4",
79 .ops = &bf5xx_ad1836_ops, 70 .ops = &bf5xx_ad1836_ops,
71 .dai_fmt = BF5XX_AD1836_DAIFMT,
80 }, 72 },
81 { 73 {
82 .name = "ad1836", 74 .name = "ad1836",
@@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
86 .platform_name = "bfin-tdm-pcm-audio", 78 .platform_name = "bfin-tdm-pcm-audio",
87 .codec_name = "spi0.4", 79 .codec_name = "spi0.4",
88 .ops = &bf5xx_ad1836_ops, 80 .ops = &bf5xx_ad1836_ops,
81 .dai_fmt = BF5XX_AD1836_DAIFMT,
89 }, 82 },
90}; 83};
91 84
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 2d8d82dbc159..0e55e9f2a514 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
60 break; 60 break;
61 } 61 }
62 62
63 /* set cpu DAI configuration */
64 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
65 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 /* set codec DAI configuration */
70 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
71 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
72 if (ret < 0)
73 return ret;
74
75 /* set the codec system clock for DAC and ADC */ 63 /* set the codec system clock for DAC and ADC */
76 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 64 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
77 SND_SOC_CLOCK_IN); 65 SND_SOC_CLOCK_IN);
@@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
92 return 0; 80 return 0;
93} 81}
94 82
83#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
84 SND_SOC_DAIFMT_CBM_CFM)
85
95static struct snd_soc_ops bf5xx_ad193x_ops = { 86static struct snd_soc_ops bf5xx_ad193x_ops = {
96 .hw_params = bf5xx_ad193x_hw_params, 87 .hw_params = bf5xx_ad193x_hw_params,
97}; 88};
@@ -105,6 +96,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
105 .platform_name = "bfin-tdm-pcm-audio", 96 .platform_name = "bfin-tdm-pcm-audio",
106 .codec_name = "spi0.5", 97 .codec_name = "spi0.5",
107 .ops = &bf5xx_ad193x_ops, 98 .ops = &bf5xx_ad193x_ops,
99 .dai_fmt = BF5XX_AD193X_DAIFMT,
108 }, 100 },
109 { 101 {
110 .name = "ad193x", 102 .name = "ad193x",
@@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
114 .platform_name = "bfin-tdm-pcm-audio", 106 .platform_name = "bfin-tdm-pcm-audio",
115 .codec_name = "spi0.5", 107 .codec_name = "spi0.5",
116 .ops = &bf5xx_ad193x_ops, 108 .ops = &bf5xx_ad193x_ops,
109 .dai_fmt = BF5XX_AD193X_DAIFMT,
117 }, 110 },
118}; 111};
119 112
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 8e49508596da..61cc91d4a028 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card)
145 return 0; 145 return 0;
146} 146}
147 147
148static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, 148#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
149 struct snd_pcm_hw_params *params) 149 SND_SOC_DAIFMT_CBM_CFM)
150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153 int ret = 0;
154
155 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
156 params_format(params));
157
158 /* set cpu DAI configuration */
159 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
160 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
161 if (ret < 0)
162 return ret;
163
164 return 0;
165}
166
167
168static struct snd_soc_ops bf5xx_ad73311_ops = {
169 .hw_params = bf5xx_ad73311_hw_params,
170};
171 150
172static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { 151static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
173 { 152 {
@@ -177,7 +156,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
177 .codec_dai_name = "ad73311-hifi", 156 .codec_dai_name = "ad73311-hifi",
178 .platform_name = "bfin-i2s-pcm-audio", 157 .platform_name = "bfin-i2s-pcm-audio",
179 .codec_name = "ad73311", 158 .codec_name = "ad73311",
180 .ops = &bf5xx_ad73311_ops, 159 .dai_fmt = BF5XX_AD7311_DAI_FMT,
181 }, 160 },
182 { 161 {
183 .name = "ad73311", 162 .name = "ad73311",
@@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
186 .codec_dai_name = "ad73311-hifi", 165 .codec_dai_name = "ad73311-hifi",
187 .platform_name = "bfin-i2s-pcm-audio", 166 .platform_name = "bfin-i2s-pcm-audio",
188 .codec_name = "ad73311", 167 .codec_name = "ad73311",
189 .ops = &bf5xx_ad73311_ops, 168 .dai_fmt = BF5XX_AD7311_DAI_FMT,
190 }, 169 },
191}; 170};
192 171
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 030303238042..df3ac73f8778 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -49,7 +49,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
49{ 49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *codec_dai = rtd->codec_dai; 51 struct snd_soc_dai *codec_dai = rtd->codec_dai;
52 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
53 unsigned int clk = 0; 52 unsigned int clk = 0;
54 int ret = 0; 53 int ret = 0;
55 54
@@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
75 break; 74 break;
76 } 75 }
77 76
78 /*
79 * CODEC is master for BCLK and LRC in this configuration.
80 */
81
82 /* set codec DAI configuration */
83 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
84 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
85 if (ret < 0)
86 return ret;
87 /* set cpu DAI configuration */
88 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
89 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
90 if (ret < 0)
91 return ret;
92
93 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk, 77 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
94 SND_SOC_CLOCK_IN); 78 SND_SOC_CLOCK_IN);
95 if (ret < 0) 79 if (ret < 0)
@@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
102 .hw_params = bf5xx_ssm2602_hw_params, 86 .hw_params = bf5xx_ssm2602_hw_params,
103}; 87};
104 88
89/* CODEC is master for BCLK and LRC in this configuration. */
90#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
91 SND_SOC_DAIFMT_CBM_CFM)
92
105static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { 93static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
106 { 94 {
107 .name = "ssm2602", 95 .name = "ssm2602",
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 26b271c62efa..f3adbdbdd5e1 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params) 67 struct snd_pcm_hw_params *params)
68{ 68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data; 69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
71 struct snd_soc_dai *codec_dai = rtd->codec_dai; 70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
72 int ret; 71 int ret;
73 int pll_rate; 72 int pll_rate;
74 73
75 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
76 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
77 if (ret)
78 return ret;
79
80 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
81 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
82 if (ret)
83 return ret;
84
85 switch (params_rate(params)) { 74 switch (params_rate(params)) {
86 case 48000: 75 case 48000:
87 case 8000: 76 case 8000:
@@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
143 .codec_name = "adau1373.0-001a", 132 .codec_name = "adau1373.0-001a",
144 .ops = &bfin_eval_adau1373_ops, 133 .ops = &bfin_eval_adau1373_ops,
145 .init = bfin_eval_adau1373_codec_init, 134 .init = bfin_eval_adau1373_codec_init,
135 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
136 SND_SOC_DAIFMT_CBM_CFM,
146}; 137};
147 138
148static struct snd_soc_card bfin_eval_adau1373 = { 139static struct snd_soc_card bfin_eval_adau1373 = {
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index c0064fa1dca6..b0531fc9d814 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params) 37 struct snd_pcm_hw_params *params)
38{ 38{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
41 struct snd_soc_dai *codec_dai = rtd->codec_dai; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
42 int ret; 41 int ret;
43 42
44 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
45 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
46 if (ret)
47 return ret;
48
49 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
50 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
51 if (ret)
52 return ret;
53
54 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000, 43 ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
55 SND_SOC_CLOCK_IN); 44 SND_SOC_CLOCK_IN);
56 45
@@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = {
61 .hw_params = bfin_eval_adau1701_hw_params, 50 .hw_params = bfin_eval_adau1701_hw_params,
62}; 51};
63 52
53#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
54 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
55
64static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { 56static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
65 { 57 {
66 .name = "adau1701", 58 .name = "adau1701",
@@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
70 .platform_name = "bfin-i2s-pcm-audio", 62 .platform_name = "bfin-i2s-pcm-audio",
71 .codec_name = "adau1701.0-0034", 63 .codec_name = "adau1701.0-0034",
72 .ops = &bfin_eval_adau1701_ops, 64 .ops = &bfin_eval_adau1701_ops,
65 .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
73 }, 66 },
74 { 67 {
75 .name = "adau1701", 68 .name = "adau1701",
@@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
79 .platform_name = "bfin-i2s-pcm-audio", 72 .platform_name = "bfin-i2s-pcm-audio",
80 .codec_name = "adau1701.0-0034", 73 .codec_name = "adau1701.0-0034",
81 .ops = &bfin_eval_adau1701_ops, 74 .ops = &bfin_eval_adau1701_ops,
75 .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
82 }, 76 },
83}; 77};
84 78
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 4ef079f95e2e..84b09987b7f3 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
34 struct snd_pcm_hw_params *params) 34 struct snd_pcm_hw_params *params)
35{ 35{
36 struct snd_soc_pcm_runtime *rtd = substream->private_data; 36 struct snd_soc_pcm_runtime *rtd = substream->private_data;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
38 struct snd_soc_dai *codec_dai = rtd->codec_dai; 37 struct snd_soc_dai *codec_dai = rtd->codec_dai;
39 int ret; 38 int ret;
40 39
41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
42 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
43 if (ret)
44 return ret;
45
46 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
47 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
48 if (ret)
49 return ret;
50
51 ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, 40 ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
52 27000000, params_rate(params) * 256); 41 27000000, params_rate(params) * 256);
53 if (ret) 42 if (ret)
@@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
88 .platform_name = "bfin-i2s-pcm-audio", 77 .platform_name = "bfin-i2s-pcm-audio",
89 .init = bfin_eval_adav80x_codec_init, 78 .init = bfin_eval_adav80x_codec_init,
90 .ops = &bfin_eval_adav80x_ops, 79 .ops = &bfin_eval_adav80x_ops,
80 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
81 SND_SOC_DAIFMT_CBM_CFM,
91 }, 82 },
92}; 83};
93 84
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 7c205e77d83a..6508e8b790bb 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS
40 select SND_SOC_MAX98088 if I2C 40 select SND_SOC_MAX98088 if I2C
41 select SND_SOC_MAX98095 if I2C 41 select SND_SOC_MAX98095 if I2C
42 select SND_SOC_MAX9850 if I2C 42 select SND_SOC_MAX9850 if I2C
43 select SND_SOC_MAX9768 if I2C
43 select SND_SOC_MAX9877 if I2C 44 select SND_SOC_MAX9877 if I2C
44 select SND_SOC_PCM3008 45 select SND_SOC_PCM3008
45 select SND_SOC_RT5631 if I2C 46 select SND_SOC_RT5631 if I2C
@@ -62,6 +63,7 @@ config SND_SOC_ALL_CODECS
62 select SND_SOC_WL1273 if MFD_WL1273_CORE 63 select SND_SOC_WL1273 if MFD_WL1273_CORE
63 select SND_SOC_WM1250_EV1 if I2C 64 select SND_SOC_WM1250_EV1 if I2C
64 select SND_SOC_WM2000 if I2C 65 select SND_SOC_WM2000 if I2C
66 select SND_SOC_WM2200 if I2C
65 select SND_SOC_WM5100 if I2C 67 select SND_SOC_WM5100 if I2C
66 select SND_SOC_WM8350 if MFD_WM8350 68 select SND_SOC_WM8350 if MFD_WM8350
67 select SND_SOC_WM8400 if MFD_WM8400 69 select SND_SOC_WM8400 if MFD_WM8400
@@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1
292config SND_SOC_WM2000 294config SND_SOC_WM2000
293 tristate 295 tristate
294 296
297config SND_SOC_WM2200
298 tristate
299
295config SND_SOC_WM5100 300config SND_SOC_WM5100
296 tristate 301 tristate
297 302
@@ -425,6 +430,9 @@ config SND_SOC_WM9713
425config SND_SOC_LM4857 430config SND_SOC_LM4857
426 tristate 431 tristate
427 432
433config SND_SOC_MAX9768
434 tristate
435
428config SND_SOC_MAX9877 436config SND_SOC_MAX9877
429 tristate 437 tristate
430 438
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index de8078178f86..6662eb0cdcc0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o
25snd-soc-jz4740-codec-objs := jz4740.o 25snd-soc-jz4740-codec-objs := jz4740.o
26snd-soc-l3-objs := l3.o 26snd-soc-l3-objs := l3.o
27snd-soc-lm4857-objs := lm4857.o 27snd-soc-lm4857-objs := lm4857.o
28snd-soc-max9768-objs := max9768.o
28snd-soc-max98088-objs := max98088.o 29snd-soc-max98088-objs := max98088.o
29snd-soc-max98095-objs := max98095.o 30snd-soc-max98095-objs := max98095.o
30snd-soc-max9850-objs := max9850.o 31snd-soc-max9850-objs := max9850.o
@@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o
51snd-soc-wl1273-objs := wl1273.o 52snd-soc-wl1273-objs := wl1273.o
52snd-soc-wm1250-ev1-objs := wm1250-ev1.o 53snd-soc-wm1250-ev1-objs := wm1250-ev1.o
53snd-soc-wm2000-objs := wm2000.o 54snd-soc-wm2000-objs := wm2000.o
55snd-soc-wm2200-objs := wm2200.o
54snd-soc-wm5100-objs := wm5100.o wm5100-tables.o 56snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
55snd-soc-wm8350-objs := wm8350.o 57snd-soc-wm8350-objs := wm8350.o
56snd-soc-wm8400-objs := wm8400.o 58snd-soc-wm8400-objs := wm8400.o
@@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
129obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 131obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
130obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 132obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
131obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 133obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
134obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
132obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 135obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
133obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 136obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
134obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 137obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
@@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
153obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o 156obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
154obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o 157obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
155obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 158obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
159obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
156obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o 160obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
157obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 161obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
158obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 162obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 982d201c2e86..12e3b4118557 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
277 if (ad1836->type == AD1836) { 277 if (ad1836->type == AD1836) {
278 /* left/right diff:PGA/MUX */ 278 /* left/right diff:PGA/MUX */
279 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); 279 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
280 ret = snd_soc_add_controls(codec, ad1836_controls, 280 ret = snd_soc_add_codec_controls(codec, ad1836_controls,
281 ARRAY_SIZE(ad1836_controls)); 281 ARRAY_SIZE(ad1836_controls));
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
285 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); 285 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
286 } 286 }
287 287
288 ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2); 288 ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
289 if (ret) 289 if (ret)
290 return ret; 290 return ret;
291 291
292 ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs); 292 ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
293 if (ret) 293 if (ret)
294 return ret; 294 return ret;
295 295
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 9bba7f849464..8c39dddd7d00 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
228 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); 228 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
229 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); 229 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
230 230
231 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 231 snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls,
232 ARRAY_SIZE(ad1980_snd_ac97_controls)); 232 ARRAY_SIZE(ad1980_snd_ac97_controls));
233 233
234 return 0; 234 return 0;
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 971ba4529171..44f59064d8de 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1244 return ret; 1244 return ret;
1245 } 1245 }
1246 1246
1247 codec->dapm.idle_bias_off = true;
1248
1249 if (pdata) { 1247 if (pdata) {
1250 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) 1248 if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
1251 return -EINVAL; 1249 return -EINVAL;
@@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1259 pdata->drc_setting[i]); 1257 pdata->drc_setting[i]);
1260 } 1258 }
1261 1259
1262 snd_soc_add_controls(codec, adau1373_drc_controls, 1260 snd_soc_add_codec_controls(codec, adau1373_drc_controls,
1263 pdata->num_drc); 1261 pdata->num_drc);
1264 1262
1265 val = 0; 1263 val = 0;
@@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1284 } 1282 }
1285 1283
1286 if (!lineout_differential) { 1284 if (!lineout_differential) {
1287 snd_soc_add_controls(codec, adau1373_lineout2_controls, 1285 snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
1288 ARRAY_SIZE(adau1373_lineout2_controls)); 1286 ARRAY_SIZE(adau1373_lineout2_controls));
1289 } 1287 }
1290 1288
@@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
1340 .suspend = adau1373_suspend, 1338 .suspend = adau1373_suspend,
1341 .resume = adau1373_resume, 1339 .resume = adau1373_resume,
1342 .set_bias_level = adau1373_set_bias_level, 1340 .set_bias_level = adau1373_set_bias_level,
1341 .idle_bias_off = true,
1343 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), 1342 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1344 .reg_cache_default = adau1373_default_regs, 1343 .reg_cache_default = adau1373_default_regs,
1345 .reg_word_size = sizeof(uint8_t), 1344 .reg_word_size = sizeof(uint8_t),
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 6b325ea03869..78e9ce48bb99 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
457{ 457{
458 int ret; 458 int ret;
459 459
460 codec->dapm.idle_bias_off = 1;
461 codec->control_data = to_i2c_client(codec->dev); 460 codec->control_data = to_i2c_client(codec->dev);
462 461
463 ret = adau1701_load_firmware(codec); 462 ret = adau1701_load_firmware(codec);
@@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
473static struct snd_soc_codec_driver adau1701_codec_drv = { 472static struct snd_soc_codec_driver adau1701_codec_drv = {
474 .probe = adau1701_probe, 473 .probe = adau1701_probe,
475 .set_bias_level = adau1701_set_bias_level, 474 .set_bias_level = adau1701_set_bias_level,
475 .idle_bias_off = true,
476 476
477 .reg_cache_size = ADAU1701_NUM_REGS, 477 .reg_cache_size = ADAU1701_NUM_REGS,
478 .reg_word_size = sizeof(u16), 478 .reg_word_size = sizeof(u16),
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index d27b5e4cce99..ceb96ecf5588 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -46,75 +46,15 @@
46#define DRV_NAME "ak4104-codec" 46#define DRV_NAME "ak4104-codec"
47 47
48struct ak4104_private { 48struct ak4104_private {
49 enum snd_soc_control_type control_type; 49 struct regmap *regmap;
50 void *control_data;
51}; 50};
52 51
53static int ak4104_fill_cache(struct snd_soc_codec *codec)
54{
55 int i;
56 u8 *reg_cache = codec->reg_cache;
57 struct spi_device *spi = codec->control_data;
58
59 for (i = 0; i < codec->driver->reg_cache_size; i++) {
60 int ret = spi_w8r8(spi, i | AK4104_READ);
61 if (ret < 0) {
62 dev_err(&spi->dev, "SPI write failure\n");
63 return ret;
64 }
65
66 reg_cache[i] = ret;
67 }
68
69 return 0;
70}
71
72static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg)
74{
75 u8 *reg_cache = codec->reg_cache;
76
77 if (reg >= codec->driver->reg_cache_size)
78 return -EINVAL;
79
80 return reg_cache[reg];
81}
82
83static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
84 unsigned int value)
85{
86 u8 *cache = codec->reg_cache;
87 struct spi_device *spi = codec->control_data;
88
89 if (reg >= codec->driver->reg_cache_size)
90 return -EINVAL;
91
92 /* only write to the hardware if value has changed */
93 if (cache[reg] != value) {
94 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
95
96 if (spi_write(spi, tmp, sizeof(tmp))) {
97 dev_err(&spi->dev, "SPI write failed\n");
98 return -EIO;
99 }
100
101 cache[reg] = value;
102 }
103
104 return 0;
105}
106
107static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, 52static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
108 unsigned int format) 53 unsigned int format)
109{ 54{
110 struct snd_soc_codec *codec = codec_dai->codec; 55 struct snd_soc_codec *codec = codec_dai->codec;
111 int val = 0; 56 int val = 0;
112 57 int ret;
113 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
114 if (val < 0)
115 return val;
116
117 val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1);
118 58
119 /* set DAI format */ 59 /* set DAI format */
120 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 60 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -135,7 +75,13 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
135 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) 75 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
136 return -EINVAL; 76 return -EINVAL;
137 77
138 return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 78 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
79 AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,
80 val);
81 if (ret < 0)
82 return ret;
83
84 return 0;
139} 85}
140 86
141static int ak4104_hw_params(struct snd_pcm_substream *substream, 87static int ak4104_hw_params(struct snd_pcm_substream *substream,
@@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
148 94
149 /* set the IEC958 bits: consumer mode, no copyright bit */ 95 /* set the IEC958 bits: consumer mode, no copyright bit */
150 val |= IEC958_AES0_CON_NOT_COPYRIGHT; 96 val |= IEC958_AES0_CON_NOT_COPYRIGHT;
151 ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); 97 snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val);
152 98
153 val = 0; 99 val = 0;
154 100
@@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
167 return -EINVAL; 113 return -EINVAL;
168 } 114 }
169 115
170 return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); 116 return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val);
171} 117}
172 118
173static const struct snd_soc_dai_ops ak4101_dai_ops = { 119static const struct snd_soc_dai_ops ak4101_dai_ops = {
@@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = {
192static int ak4104_probe(struct snd_soc_codec *codec) 138static int ak4104_probe(struct snd_soc_codec *codec)
193{ 139{
194 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); 140 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
195 int ret, val; 141 int ret;
196
197 codec->control_data = ak4104->control_data;
198 142
199 /* read all regs and fill the cache */ 143 codec->control_data = ak4104->regmap;
200 ret = ak4104_fill_cache(codec); 144 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
201 if (ret < 0) { 145 if (ret != 0)
202 dev_err(codec->dev, "failed to fill register cache\n");
203 return ret; 146 return ret;
204 }
205
206 /* read the 'reserved' register - according to the datasheet, it
207 * should contain 0x5b. Not a good way to verify the presence of
208 * the device, but there is no hardware ID register. */
209 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
210 AK4104_RESERVED_VAL)
211 return -ENODEV;
212 147
213 /* set power-up and non-reset bits */ 148 /* set power-up and non-reset bits */
214 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); 149 ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
215 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; 150 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
216 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 151 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
217 if (ret < 0) 152 if (ret < 0)
218 return ret; 153 return ret;
219 154
220 /* enable transmitter */ 155 /* enable transmitter */
221 val = ak4104_read_reg_cache(codec, AK4104_REG_TX); 156 ret = snd_soc_update_bits(codec, AK4104_REG_TX,
222 val |= AK4104_TX_TXE; 157 AK4104_TX_TXE, AK4104_TX_TXE);
223 ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
224 if (ret < 0) 158 if (ret < 0)
225 return ret; 159 return ret;
226 160
227 dev_info(codec->dev, "SPI device initialized\n");
228 return 0; 161 return 0;
229} 162}
230 163
231static int ak4104_remove(struct snd_soc_codec *codec) 164static int ak4104_remove(struct snd_soc_codec *codec)
232{ 165{
233 int val, ret; 166 snd_soc_update_bits(codec, AK4104_REG_CONTROL1,
234 167 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
235 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
236 if (val < 0)
237 return val;
238
239 /* clear power-up and non-reset bits */
240 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
241 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
242 168
243 return ret; 169 return 0;
244} 170}
245 171
246static struct snd_soc_codec_driver soc_codec_device_ak4104 = { 172static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe, 173 .probe = ak4104_probe,
248 .remove = ak4104_remove, 174 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS, 175};
250 .reg_word_size = sizeof(u8), 176
177static const struct regmap_config ak4104_regmap = {
178 .reg_bits = 8,
179 .val_bits = 8,
180
181 .max_register = AK4104_NUM_REGS - 1,
182 .read_flag_mask = AK4104_READ,
183 .write_flag_mask = AK4104_WRITE,
184
185 .cache_type = REGCACHE_RBTREE,
251}; 186};
252 187
253static int ak4104_spi_probe(struct spi_device *spi) 188static int ak4104_spi_probe(struct spi_device *spi)
254{ 189{
255 struct ak4104_private *ak4104; 190 struct ak4104_private *ak4104;
191 unsigned int val;
256 int ret; 192 int ret;
257 193
258 spi->bits_per_word = 8; 194 spi->bits_per_word = 8;
@@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi)
266 if (ak4104 == NULL) 202 if (ak4104 == NULL)
267 return -ENOMEM; 203 return -ENOMEM;
268 204
269 ak4104->control_data = spi; 205 ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
270 ak4104->control_type = SND_SOC_SPI; 206 if (IS_ERR(ak4104->regmap)) {
207 ret = PTR_ERR(ak4104->regmap);
208 return ret;
209 }
210
211 /* read the 'reserved' register - according to the datasheet, it
212 * should contain 0x5b. Not a good way to verify the presence of
213 * the device, but there is no hardware ID register. */
214 ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);
215 if (ret != 0)
216 goto err;
217 if (val != AK4104_RESERVED_VAL) {
218 ret = -ENODEV;
219 goto err;
220 }
221
271 spi_set_drvdata(spi, ak4104); 222 spi_set_drvdata(spi, ak4104);
272 223
273 ret = snd_soc_register_codec(&spi->dev, 224 ret = snd_soc_register_codec(&spi->dev,
274 &soc_codec_device_ak4104, &ak4104_dai, 1); 225 &soc_codec_device_ak4104, &ak4104_dai, 1);
226 if (ret != 0)
227 goto err;
228
229 return 0;
230
231err:
232 regmap_exit(ak4104->regmap);
275 return ret; 233 return ret;
276} 234}
277 235
278static int __devexit ak4104_spi_remove(struct spi_device *spi) 236static int __devexit ak4104_spi_remove(struct spi_device *spi)
279{ 237{
238 struct ak4104_private *ak4101 = spi_get_drvdata(spi);
239 regmap_exit(ak4101->regmap);
280 snd_soc_unregister_codec(&spi->dev); 240 snd_soc_unregister_codec(&spi->dev);
281 return 0; 241 return 0;
282} 242}
@@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = {
290 .remove = __devexit_p(ak4104_spi_remove), 250 .remove = __devexit_p(ak4104_spi_remove),
291}; 251};
292 252
293static int __init ak4104_init(void) 253module_spi_driver(ak4104_spi_driver);
294{
295 return spi_register_driver(&ak4104_spi_driver);
296}
297module_init(ak4104_init);
298
299static void __exit ak4104_exit(void)
300{
301 spi_unregister_driver(&ak4104_spi_driver);
302}
303module_exit(ak4104_exit);
304 254
305MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 255MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
306MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); 256MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 9e809e05d066..838ae8b22b50 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -27,24 +28,43 @@
27 28
28#include "ak4535.h" 29#include "ak4535.h"
29 30
30#define AK4535_VERSION "0.3"
31
32/* codec private data */ 31/* codec private data */
33struct ak4535_priv { 32struct ak4535_priv {
33 struct regmap *regmap;
34 unsigned int sysclk; 34 unsigned int sysclk;
35 enum snd_soc_control_type control_type;
36}; 35};
37 36
38/* 37/*
39 * ak4535 register cache 38 * ak4535 register cache
40 */ 39 */
41static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { 40static const struct reg_default ak4535_reg_defaults[] = {
42 0x00, 0x80, 0x00, 0x03, 41 { 0, 0x00 },
43 0x02, 0x00, 0x11, 0x01, 42 { 1, 0x80 },
44 0x00, 0x40, 0x36, 0x10, 43 { 2, 0x00 },
45 0x00, 0x00, 0x57, 0x00, 44 { 3, 0x03 },
45 { 4, 0x02 },
46 { 5, 0x00 },
47 { 6, 0x11 },
48 { 7, 0x01 },
49 { 8, 0x00 },
50 { 9, 0x40 },
51 { 10, 0x36 },
52 { 11, 0x10 },
53 { 12, 0x00 },
54 { 13, 0x00 },
55 { 14, 0x57 },
46}; 56};
47 57
58static bool ak4535_volatile(struct device *dev, unsigned int reg)
59{
60 switch (reg) {
61 case AK4535_STATUS:
62 return true;
63 default:
64 return false;
65 }
66}
67
48static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; 68static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
49static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; 69static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
50static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; 70static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
372 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 392 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
373 int ret; 393 int ret;
374 394
375 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); 395 codec->control_data = ak4535->regmap;
376 396 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
377 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
378 if (ret < 0) { 397 if (ret < 0) {
379 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 398 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
380 return ret; 399 return ret;
@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
382 /* power on device */ 401 /* power on device */
383 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 402 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
384 403
385 snd_soc_add_controls(codec, ak4535_snd_controls, 404 snd_soc_add_codec_controls(codec, ak4535_snd_controls,
386 ARRAY_SIZE(ak4535_snd_controls)); 405 ARRAY_SIZE(ak4535_snd_controls));
387 return 0; 406 return 0;
388} 407}
@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
394 return 0; 413 return 0;
395} 414}
396 415
416static const struct regmap_config ak4535_regmap = {
417 .reg_bits = 8,
418 .val_bits = 8,
419
420 .max_register = AK4535_STATUS,
421 .volatile_reg = ak4535_volatile,
422
423 .cache_type = REGCACHE_RBTREE,
424 .reg_defaults = ak4535_reg_defaults,
425 .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
426};
427
397static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { 428static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
398 .probe = ak4535_probe, 429 .probe = ak4535_probe,
399 .remove = ak4535_remove, 430 .remove = ak4535_remove,
400 .suspend = ak4535_suspend, 431 .suspend = ak4535_suspend,
401 .resume = ak4535_resume, 432 .resume = ak4535_resume,
402 .set_bias_level = ak4535_set_bias_level, 433 .set_bias_level = ak4535_set_bias_level,
403 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
404 .reg_word_size = sizeof(u8),
405 .reg_cache_default = ak4535_reg,
406 .dapm_widgets = ak4535_dapm_widgets, 434 .dapm_widgets = ak4535_dapm_widgets,
407 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), 435 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
408 .dapm_routes = ak4535_audio_map, 436 .dapm_routes = ak4535_audio_map,
409 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), 437 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
410}; 438};
411 439
412#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
413static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, 440static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
414 const struct i2c_device_id *id) 441 const struct i2c_device_id *id)
415{ 442{
@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
421 if (ak4535 == NULL) 448 if (ak4535 == NULL)
422 return -ENOMEM; 449 return -ENOMEM;
423 450
451 ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
452 if (IS_ERR(ak4535->regmap)) {
453 ret = PTR_ERR(ak4535->regmap);
454 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
455 return ret;
456 }
457
424 i2c_set_clientdata(i2c, ak4535); 458 i2c_set_clientdata(i2c, ak4535);
425 ak4535->control_type = SND_SOC_I2C;
426 459
427 ret = snd_soc_register_codec(&i2c->dev, 460 ret = snd_soc_register_codec(&i2c->dev,
428 &soc_codec_dev_ak4535, &ak4535_dai, 1); 461 &soc_codec_dev_ak4535, &ak4535_dai, 1);
462 if (ret != 0)
463 regmap_exit(ak4535->regmap);
464
429 return ret; 465 return ret;
430} 466}
431 467
432static __devexit int ak4535_i2c_remove(struct i2c_client *client) 468static __devexit int ak4535_i2c_remove(struct i2c_client *client)
433{ 469{
470 struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
471
434 snd_soc_unregister_codec(&client->dev); 472 snd_soc_unregister_codec(&client->dev);
473 regmap_exit(ak4535->regmap);
435 return 0; 474 return 0;
436} 475}
437 476
@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
443 482
444static struct i2c_driver ak4535_i2c_driver = { 483static struct i2c_driver ak4535_i2c_driver = {
445 .driver = { 484 .driver = {
446 .name = "ak4535-codec", 485 .name = "ak4535",
447 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
448 }, 487 },
449 .probe = ak4535_i2c_probe, 488 .probe = ak4535_i2c_probe,
450 .remove = __devexit_p(ak4535_i2c_remove), 489 .remove = __devexit_p(ak4535_i2c_remove),
451 .id_table = ak4535_i2c_id, 490 .id_table = ak4535_i2c_id,
452}; 491};
453#endif
454 492
455static int __init ak4535_modinit(void) 493module_i2c_driver(ak4535_i2c_driver);
456{
457 int ret = 0;
458#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
459 ret = i2c_add_driver(&ak4535_i2c_driver);
460 if (ret != 0) {
461 printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
462 ret);
463 }
464#endif
465 return ret;
466}
467module_init(ak4535_modinit);
468
469static void __exit ak4535_exit(void)
470{
471#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
472 i2c_del_driver(&ak4535_i2c_driver);
473#endif
474}
475module_exit(ak4535_exit);
476 494
477MODULE_DESCRIPTION("Soc AK4535 driver"); 495MODULE_DESCRIPTION("Soc AK4535 driver");
478MODULE_AUTHOR("Richard Purdie"); 496MODULE_AUTHOR("Richard Purdie");
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index 0431e5f634a2..402de1d274bf 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -34,6 +34,4 @@
34#define AK4535_VOL 0xe 34#define AK4535_VOL 0xe
35#define AK4535_STATUS 0xf 35#define AK4535_STATUS 0xf
36 36
37#define AK4535_CACHEREGNUM 0x10
38
39#endif 37#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 5ef70b5d27e4..16bd1e7d2384 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -476,7 +476,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
476 return ret; 476 return ret;
477 } 477 }
478 478
479 snd_soc_add_controls(codec, ak4642_snd_controls, 479 snd_soc_add_codec_controls(codec, ak4642_snd_controls,
480 ARRAY_SIZE(ak4642_snd_controls)); 480 ARRAY_SIZE(ak4642_snd_controls));
481 481
482 ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 482 ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index a53b152e6a07..5fb7c2a80e6d 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec)
628 return ret; 628 return ret;
629 } 629 }
630 630
631 snd_soc_add_controls(codec, ak4671_snd_controls, 631 snd_soc_add_codec_controls(codec, ak4671_snd_controls,
632 ARRAY_SIZE(ak4671_snd_controls)); 632 ARRAY_SIZE(ak4671_snd_controls));
633 633
634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 634 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 08f24198c8da..d47b62ddb210 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec)
925 925
926 switch (alc5623->id) { 926 switch (alc5623->id) {
927 case 0x21: 927 case 0x21:
928 snd_soc_add_controls(codec, alc5621_vol_snd_controls, 928 snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
929 ARRAY_SIZE(alc5621_vol_snd_controls)); 929 ARRAY_SIZE(alc5621_vol_snd_controls));
930 break; 930 break;
931 case 0x22: 931 case 0x22:
932 snd_soc_add_controls(codec, alc5622_vol_snd_controls, 932 snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
933 ARRAY_SIZE(alc5622_vol_snd_controls)); 933 ARRAY_SIZE(alc5622_vol_snd_controls));
934 break; 934 break;
935 case 0x23: 935 case 0x23:
936 snd_soc_add_controls(codec, alc5623_vol_snd_controls, 936 snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
937 ARRAY_SIZE(alc5623_vol_snd_controls)); 937 ARRAY_SIZE(alc5623_vol_snd_controls));
938 break; 938 break;
939 default: 939 default:
940 return -EINVAL; 940 return -EINVAL;
941 } 941 }
942 942
943 snd_soc_add_controls(codec, alc5623_snd_controls, 943 snd_soc_add_codec_controls(codec, alc5623_snd_controls,
944 ARRAY_SIZE(alc5623_snd_controls)); 944 ARRAY_SIZE(alc5623_snd_controls));
945 945
946 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, 946 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index af9c27ae02f0..e2111e0ccad7 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
145/* -16.5db min scale, 1.5db steps, no mute */ 145/* -16.5db min scale, 1.5db steps, no mute */
146static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); 146static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
147static const unsigned int boost_tlv[] = { 147static const unsigned int boost_tlv[] = {
148 TLV_DB_RANGE_HEAD(3), 148 TLV_DB_RANGE_HEAD(2),
149 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 149 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
150 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 150 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
151 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
152}; 151};
153/* 0db min scale, 6 db steps, no mute */ 152/* 0db min scale, 6 db steps, no mute */
154static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); 153static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
155/* 0db min scalem 0.75db steps, no mute */ 154/* 0db min scalem 0.75db steps, no mute */
156static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); 155static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
157 156
158static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { 157static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
159 /* left starts at bit 8, right at bit 0 */ 158 /* left starts at bit 8, right at bit 0 */
@@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = {
176 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), 175 ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
177 SOC_SINGLE_TLV("Voice DAC Playback Volume", 176 SOC_SINGLE_TLV("Voice DAC Playback Volume",
178 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), 177 ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
179 SOC_SINGLE_TLV("Phone Capture Volume", 178 SOC_SINGLE("Voice DAC Playback Switch",
179 ALC5632_VOICE_DAC_VOL, 12, 1, 1),
180 SOC_SINGLE_TLV("Phone Playback Volume",
180 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), 181 ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
181 SOC_DOUBLE_TLV("LineIn Capture Volume", 182 SOC_DOUBLE_TLV("LineIn Playback Volume",
182 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), 183 ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
183 SOC_DOUBLE_TLV("Master Playback Volume", 184 SOC_DOUBLE_TLV("Master Playback Volume",
184 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), 185 ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
185 SOC_DOUBLE("Master Playback Switch", 186 SOC_DOUBLE("Master Playback Switch",
186 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), 187 ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
187 SOC_SINGLE_TLV("Mic1 Capture Volume", 188 SOC_SINGLE_TLV("Mic1 Playback Volume",
188 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), 189 ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
189 SOC_SINGLE_TLV("Mic2 Capture Volume", 190 SOC_SINGLE_TLV("Mic2 Playback Volume",
190 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), 191 ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
191 SOC_DOUBLE_TLV("Rec Capture Volume", 192 SOC_DOUBLE_TLV("Rec Capture Volume",
192 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), 193 ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
193 SOC_SINGLE_TLV("Mic 1 Boost Volume", 194 SOC_SINGLE_TLV("Mic 1 Boost Volume",
194 ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), 195 ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
195 SOC_SINGLE_TLV("Mic 2 Boost Volume", 196 SOC_SINGLE_TLV("Mic 2 Boost Volume",
196 ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), 197 ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
197 SOC_SINGLE_TLV("Digital Boost Volume", 198 SOC_SINGLE_TLV("DMIC Boost Capture Volume",
198 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), 199 ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
200 SOC_SINGLE("DMIC En Capture Switch",
201 ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
202 SOC_SINGLE("DMIC PreFilter Capture Switch",
203 ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
199}; 204};
200 205
201/* 206/*
@@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
244 249
245/* Left Record Mixer */ 250/* Left Record Mixer */
246static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { 251static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
247SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), 252SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
248SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), 253SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
249SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), 254SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
250SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), 255SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
251SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), 256SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
252SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), 257SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
253SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), 258SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
254}; 259};
255 260
256/* Right Record Mixer */ 261/* Right Record Mixer */
257static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { 262static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
258SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), 263SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
259SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), 264SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
260SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), 265SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
261SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), 266SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
262SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), 267SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
263SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), 268SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
264SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), 269SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
265}; 270};
266 271
267static const char *alc5632_spk_n_sour_sel[] = { 272/* Dmic Mixer */
273static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
274SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
275};
276static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
277SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
278};
279
280static const char * const alc5632_spk_n_sour_sel[] = {
268 "RN/-R", "RP/+R", "LN/-R", "Mute"}; 281 "RN/-R", "RP/+R", "LN/-R", "Mute"};
269static const char *alc5632_hpl_out_input_sel[] = { 282static const char * const alc5632_hpl_out_input_sel[] = {
270 "Vmid", "HP Left Mix"}; 283 "Vmid", "HP Left Mix"};
271static const char *alc5632_hpr_out_input_sel[] = { 284static const char * const alc5632_hpr_out_input_sel[] = {
272 "Vmid", "HP Right Mix"}; 285 "Vmid", "HP Right Mix"};
273static const char *alc5632_spkout_input_sel[] = { 286static const char * const alc5632_spkout_input_sel[] = {
274 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 287 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
275static const char *alc5632_aux_out_input_sel[] = { 288static const char * const alc5632_aux_out_input_sel[] = {
276 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; 289 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
290static const char * const alc5632_adcr_func_sel[] = {
291 "Stereo ADC", "Voice ADC"};
292static const char * const alc5632_i2s_out_sel[] = {
293 "ADC LR", "Voice Stereo Digital"};
277 294
278/* auxout output mux */ 295/* auxout output mux */
279static const struct soc_enum alc5632_aux_out_input_enum = 296static const struct soc_enum alc5632_aux_out_input_enum =
@@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum =
312static const struct snd_kcontrol_new alc5632_amp_mux_controls = 329static const struct snd_kcontrol_new alc5632_amp_mux_controls =
313 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); 330 SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
314 331
332/* ADC output select */
333static const struct soc_enum alc5632_adcr_func_enum =
334 SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
335static const struct snd_kcontrol_new alc5632_adcr_func_controls =
336 SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
337
338/* I2S out select */
339static const struct soc_enum alc5632_i2s_out_enum =
340 SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
341static const struct snd_kcontrol_new alc5632_i2s_out_controls =
342 SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
315 343
316static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { 344static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
317/* Muxes */ 345/* Muxes */
@@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
325 &alc5632_hpr_out_mux_controls), 353 &alc5632_hpr_out_mux_controls),
326SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, 354SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
327 &alc5632_spkoutn_mux_controls), 355 &alc5632_spkoutn_mux_controls),
356SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
357 &alc5632_adcr_func_controls),
358SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
359 &alc5632_i2s_out_controls),
328 360
329/* output mixers */ 361/* output mixers */
330SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, 362SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
@@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
343SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, 375SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
344 &alc5632_speaker_mixer_controls[0], 376 &alc5632_speaker_mixer_controls[0],
345 ARRAY_SIZE(alc5632_speaker_mixer_controls)), 377 ARRAY_SIZE(alc5632_speaker_mixer_controls)),
378SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
379 &alc5632_dmicl_mixer_controls[0],
380 ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
381SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
382 &alc5632_dmicr_mixer_controls[0],
383 ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
346 384
347/* input mixers */ 385/* input mixers */
348SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, 386SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
@@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
352 &alc5632_captureR_mixer_controls[0], 390 &alc5632_captureR_mixer_controls[0],
353 ARRAY_SIZE(alc5632_captureR_mixer_controls)), 391 ARRAY_SIZE(alc5632_captureR_mixer_controls)),
354 392
355SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", 393SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
356 ALC5632_PWR_MANAG_ADD2, 9, 0), 394SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
357SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", 395SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
358 ALC5632_PWR_MANAG_ADD2, 8, 0), 396SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
397SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
398SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
399
400SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
401SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
402SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
403SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
404SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
405
359SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), 406SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
360SND_SOC_DAPM_MIXER("DAC Right Channel", 407SND_SOC_DAPM_MIXER("DAC Right Channel",
361 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), 408 ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
362SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), 409SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
363SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 410SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
364SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), 411SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
365SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", 412SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
366 ALC5632_PWR_MANAG_ADD2, 7, 0), 413SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
367SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", 414
368 ALC5632_PWR_MANAG_ADD2, 6, 0),
369SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), 415SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
370SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), 416SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
371SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), 417SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
@@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"),
393SND_SOC_DAPM_OUTPUT("HPR"), 439SND_SOC_DAPM_OUTPUT("HPR"),
394SND_SOC_DAPM_OUTPUT("SPKOUT"), 440SND_SOC_DAPM_OUTPUT("SPKOUT"),
395SND_SOC_DAPM_OUTPUT("SPKOUTN"), 441SND_SOC_DAPM_OUTPUT("SPKOUTN"),
442
396SND_SOC_DAPM_INPUT("LINEINL"), 443SND_SOC_DAPM_INPUT("LINEINL"),
397SND_SOC_DAPM_INPUT("LINEINR"), 444SND_SOC_DAPM_INPUT("LINEINR"),
398SND_SOC_DAPM_INPUT("PHONEP"), 445SND_SOC_DAPM_INPUT("PHONEP"),
399SND_SOC_DAPM_INPUT("PHONEN"), 446SND_SOC_DAPM_INPUT("PHONEN"),
447SND_SOC_DAPM_INPUT("DMICDAT"),
400SND_SOC_DAPM_INPUT("MIC1"), 448SND_SOC_DAPM_INPUT("MIC1"),
401SND_SOC_DAPM_INPUT("MIC2"), 449SND_SOC_DAPM_INPUT("MIC2"),
402SND_SOC_DAPM_VMID("Vmid"), 450SND_SOC_DAPM_VMID("Vmid"),
@@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"),
404 452
405 453
406static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { 454static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
455 /* Playback streams */
456 {"Left DAC", NULL, "AIFRXL"},
457 {"Right DAC", NULL, "AIFRXR"},
458
407 /* virtual mixer - mixes left & right channels */ 459 /* virtual mixer - mixes left & right channels */
408 {"I2S Mix", NULL, "Left DAC"}, 460 {"I2S Mix", NULL, "Left DAC"},
409 {"I2S Mix", NULL, "Right DAC"}, 461 {"I2S Mix", NULL, "Right DAC"},
@@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
426 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, 478 {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"},
427 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, 479 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
428 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, 480 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
429 481 {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"},
430 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, 482 {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"},
431 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, 483 {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"},
484 {"HPOut Mix", NULL, "HP Mix"},
485 {"HPOut Mix", NULL, "HPR Mix"},
486 {"HPOut Mix", NULL, "HPL Mix"},
432 487
433 /* speaker mixer */ 488 /* speaker mixer */
434 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, 489 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
@@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
436 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, 491 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
437 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, 492 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
438 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, 493 {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"},
439 494 {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"},
440
441 495
442 /* mono mixer */ 496 /* mono mixer */
443 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, 497 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
444 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, 498 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
445 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, 499 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
446 {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"},
447 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, 500 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
448 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, 501 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
449 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, 502 {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"},
503 {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"},
450 504
451 /* Left record mixer */ 505 /* Left record mixer */
452 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, 506 {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
453 {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, 507 {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
454 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 508 {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
455 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 509 {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
456 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, 510 {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
457 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 511 {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
458 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 512 {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
459 513
460 /*Right record mixer */ 514 /*Right record mixer */
461 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, 515 {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
462 {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, 516 {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
463 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, 517 {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
464 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, 518 {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
465 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, 519 {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
466 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, 520 {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
467 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, 521 {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
468 522
469 /* headphone left mux */ 523 /* headphone left mux */
470 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, 524 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
@@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
504 558
505 /* left ADC */ 559 /* left ADC */
506 {"Left ADC", NULL, "Left Capture Mix"}, 560 {"Left ADC", NULL, "Left Capture Mix"},
561 {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
562 {"Left ADC", NULL, "DMICL Mix"},
563 {"ADCLR", NULL, "Left ADC"},
507 564
508 /* right ADC */ 565 /* right ADC */
509 {"Right ADC", NULL, "Right Capture Mix"}, 566 {"Right ADC", NULL, "Right Capture Mix"},
510 567 {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
568 {"Right ADC", NULL, "DMICR Mix"},
569 {"ADCR Mux", "Stereo ADC", "Right ADC"},
570 {"ADCR Mux", "Voice ADC", "Right ADC"},
571 {"ADCLR", NULL, "ADCR Mux"},
572 {"VAIFTX", NULL, "ADCR Mux"},
573
574 /* Digital I2S out */
575 {"I2SOut Mux", "ADC LR", "ADCLR"},
576 {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
577 {"AIFTXL", NULL, "I2SOut Mux"},
578 {"AIFTXR", NULL, "I2SOut Mux"},
579
580 /* Voice Mix */
581 {"Voice DAC", NULL, "VAIFRX"},
582 {"Voice Mix", NULL, "Voice DAC"},
583
584 /* Speaker Output */
511 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, 585 {"SpeakerOut N Mux", "RN/-R", "Left Speaker"},
512 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, 586 {"SpeakerOut N Mux", "RP/+R", "Left Speaker"},
513 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, 587 {"SpeakerOut N Mux", "LN/-R", "Left Speaker"},
@@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
714 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); 788 struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
715 789
716 switch (freq) { 790 switch (freq) {
791 case 4096000:
717 case 8192000: 792 case 8192000:
718 case 11289600: 793 case 11289600:
719 case 12288000: 794 case 12288000:
@@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
994 1069
995 switch (alc5632->id) { 1070 switch (alc5632->id) {
996 case 0x5c: 1071 case 0x5c:
997 snd_soc_add_controls(codec, alc5632_vol_snd_controls, 1072 snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
998 ARRAY_SIZE(alc5632_vol_snd_controls)); 1073 ARRAY_SIZE(alc5632_vol_snd_controls));
999 break; 1074 break;
1000 default: 1075 default:
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
index 357651ec074e..1b5bda594ea3 100644
--- a/sound/soc/codecs/alc5632.h
+++ b/sound/soc/codecs/alc5632.h
@@ -51,6 +51,7 @@
51#define ALC5632_ADC_REC_MONOMIX (1 << 0) 51#define ALC5632_ADC_REC_MONOMIX (1 << 0)
52 52
53#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ 53#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */
54#define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */
54/* ALC5632_OUTPUT_MIXER_CTRL : */ 55/* ALC5632_OUTPUT_MIXER_CTRL : */
55/* same remark as for reg 2 line vs speaker */ 56/* same remark as for reg 2 line vs speaker */
56#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ 57#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 06d2ea18a54c..064cd6a93516 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -157,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
157 codec->control_data = davinci_vc; 157 codec->control_data = davinci_vc;
158 158
159 /* Set controls */ 159 /* Set controls */
160 snd_soc_add_controls(codec, cq93vc_snd_controls, 160 snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
161 ARRAY_SIZE(cq93vc_snd_controls)); 161 ARRAY_SIZE(cq93vc_snd_controls));
162 162
163 /* Off, with power on */ 163 /* Off, with power on */
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 055536645da9..1d672f528662 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
521 } 521 }
522 522
523 /* Add the non-DAPM controls */ 523 /* Add the non-DAPM controls */
524 ret = snd_soc_add_controls(codec, cs4270_snd_controls, 524 ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
525 ARRAY_SIZE(cs4270_snd_controls)); 525 ARRAY_SIZE(cs4270_snd_controls));
526 if (ret < 0) { 526 if (ret < 0) {
527 dev_err(codec->dev, "failed to add controls\n"); 527 dev_err(codec->dev, "failed to add controls\n");
@@ -715,7 +715,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
715 */ 715 */
716static struct i2c_driver cs4270_i2c_driver = { 716static struct i2c_driver cs4270_i2c_driver = {
717 .driver = { 717 .driver = {
718 .name = "cs4270-codec", 718 .name = "cs4270",
719 .owner = THIS_MODULE, 719 .owner = THIS_MODULE,
720 }, 720 },
721 .id_table = cs4270_id, 721 .id_table = cs4270_id,
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index f6fe846b6a6c..bf7141280a74 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
513 /* Power-up sequence requires 85 uS */ 513 /* Power-up sequence requires 85 uS */
514 udelay(85); 514 udelay(85);
515 515
516 return snd_soc_add_controls(codec, cs4271_snd_controls, 516 return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
517 ARRAY_SIZE(cs4271_snd_controls)); 517 ARRAY_SIZE(cs4271_snd_controls));
518} 518}
519 519
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 9d38db8f1919..78979b3e0e95 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
1113 priv->config[id].mmcc &= 0xC0; 1113 priv->config[id].mmcc &= 0xC0;
1114 priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; 1114 priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc;
1115 priv->config[id].spc &= 0xFC; 1115 priv->config[id].spc &= 0xFC;
1116 priv->config[id].spc &= MCK_SCLK_64FS; 1116 priv->config[id].spc |= MCK_SCLK_MCLK;
1117 } else { 1117 } else {
1118 /* CS42L73 Slave */ 1118 /* CS42L73 Slave */
1119 priv->config[id].spc &= 0xFC; 1119 priv->config[id].spc &= 0xFC;
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 319039240e0f..ba4fafb93e56 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec)
179 179
180 codec->control_data = lm4857->i2c; 180 codec->control_data = lm4857->i2c;
181 181
182 ret = snd_soc_add_controls(codec, lm4857_controls, 182 ret = snd_soc_add_codec_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls)); 183 ARRAY_SIZE(lm4857_controls));
184 if (ret) 184 if (ret)
185 return ret; 185 return ret;
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
new file mode 100644
index 000000000000..17b3ec2d05cb
--- /dev/null
+++ b/sound/soc/codecs/max9768.c
@@ -0,0 +1,247 @@
1/*
2 * MAX9768 AMP driver
3 *
4 * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/i2c.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/regmap.h>
17
18#include <sound/core.h>
19#include <sound/soc.h>
20#include <sound/tlv.h>
21#include <sound/max9768.h>
22
23/* "Registers" */
24#define MAX9768_VOL 0
25#define MAX9768_CTRL 3
26
27/* Commands */
28#define MAX9768_CTRL_PWM 0x15
29#define MAX9768_CTRL_FILTERLESS 0x16
30
31struct max9768 {
32 struct regmap *regmap;
33 int mute_gpio;
34 int shdn_gpio;
35 u32 flags;
36};
37
38static struct reg_default max9768_default_regs[] = {
39 { 0, 0 },
40 { 3, MAX9768_CTRL_FILTERLESS},
41};
42
43static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
44 struct snd_ctl_elem_value *ucontrol)
45{
46 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
47 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
48 int val = gpio_get_value_cansleep(max9768->mute_gpio);
49
50 ucontrol->value.integer.value[0] = !val;
51
52 return 0;
53}
54
55static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
56 struct snd_ctl_elem_value *ucontrol)
57{
58 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
59 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
60
61 gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
62
63 return 0;
64}
65
66static const unsigned int volume_tlv[] = {
67 TLV_DB_RANGE_HEAD(43),
68 0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
69 1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
70 2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
71 3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
72 4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
73 5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
74 6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
75 7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
76 8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
77 9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
78 10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
79 11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
80 12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
81 13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
82 14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
83 15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
84 18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
85 19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
86 20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
87 21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
88 22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
89 23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
90 24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
91 25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
92 26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
93 27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
94 28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
95 31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
96 32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
97 35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
98 38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
99 40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
100 41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
101 42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
102 43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
103 44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
104 45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
105 46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
106 47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
107 51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
108 58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
109 59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
110 63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
111};
112
113static const struct snd_kcontrol_new max9768_volume[] = {
114 SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
115};
116
117static const struct snd_kcontrol_new max9768_mute[] = {
118 SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
119};
120
121static int max9768_probe(struct snd_soc_codec *codec)
122{
123 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
124 int ret;
125
126 codec->control_data = max9768->regmap;
127 ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
128 if (ret)
129 return ret;
130
131 if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
132 ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
133 if (ret)
134 return ret;
135 }
136
137 if (gpio_is_valid(max9768->mute_gpio)) {
138 ret = snd_soc_add_codec_controls(codec, max9768_mute,
139 ARRAY_SIZE(max9768_mute));
140 if (ret)
141 return ret;
142 }
143
144 return 0;
145}
146
147static struct snd_soc_codec_driver max9768_codec_driver = {
148 .probe = max9768_probe,
149 .controls = max9768_volume,
150 .num_controls = ARRAY_SIZE(max9768_volume),
151};
152
153static const struct regmap_config max9768_i2c_regmap_config = {
154 .reg_bits = 2,
155 .val_bits = 6,
156 .max_register = 3,
157 .reg_defaults = max9768_default_regs,
158 .num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
159 .cache_type = REGCACHE_RBTREE,
160};
161
162static int __devinit max9768_i2c_probe(struct i2c_client *client,
163 const struct i2c_device_id *id)
164{
165 struct max9768 *max9768;
166 struct max9768_pdata *pdata = client->dev.platform_data;
167 int err;
168
169 max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
170 if (!max9768)
171 return -ENOMEM;
172
173 if (pdata) {
174 /* Mute on powerup to avoid clicks */
175 err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
176 max9768->mute_gpio = err ?: pdata->mute_gpio;
177
178 /* Activate chip by releasing shutdown, enables I2C */
179 err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
180 max9768->shdn_gpio = err ?: pdata->shdn_gpio;
181
182 max9768->flags = pdata->flags;
183 } else {
184 max9768->shdn_gpio = -EINVAL;
185 max9768->mute_gpio = -EINVAL;
186 }
187
188 i2c_set_clientdata(client, max9768);
189
190 max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
191 if (IS_ERR(max9768->regmap)) {
192 err = PTR_ERR(max9768->regmap);
193 goto err_gpio_free;
194 }
195
196 err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
197 if (err)
198 goto err_regmap_free;
199
200 return 0;
201
202 err_regmap_free:
203 regmap_exit(max9768->regmap);
204 err_gpio_free:
205 if (gpio_is_valid(max9768->shdn_gpio))
206 gpio_free(max9768->shdn_gpio);
207 if (gpio_is_valid(max9768->mute_gpio))
208 gpio_free(max9768->mute_gpio);
209
210 return err;
211}
212
213static int __devexit max9768_i2c_remove(struct i2c_client *client)
214{
215 struct max9768 *max9768 = i2c_get_clientdata(client);
216
217 snd_soc_unregister_codec(&client->dev);
218 regmap_exit(max9768->regmap);
219
220 if (gpio_is_valid(max9768->shdn_gpio))
221 gpio_free(max9768->shdn_gpio);
222 if (gpio_is_valid(max9768->mute_gpio))
223 gpio_free(max9768->mute_gpio);
224
225 return 0;
226}
227
228static const struct i2c_device_id max9768_i2c_id[] = {
229 { "max9768", 0 },
230 { }
231};
232MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
233
234static struct i2c_driver max9768_i2c_driver = {
235 .driver = {
236 .name = "max9768",
237 .owner = THIS_MODULE,
238 },
239 .probe = max9768_i2c_probe,
240 .remove = __devexit_p(max9768_i2c_remove),
241 .id_table = max9768_i2c_id,
242};
243module_i2c_driver(max9768_i2c_driver);
244
245MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
246MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
247MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 006efcfe6dda..af7324b79dd0 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1908 max98088->eq_enum.texts = max98088->eq_texts; 1908 max98088->eq_enum.texts = max98088->eq_texts;
1909 max98088->eq_enum.max = max98088->eq_textcnt; 1909 max98088->eq_enum.max = max98088->eq_textcnt;
1910 1910
1911 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 1911 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1912 if (ret != 0) 1912 if (ret != 0)
1913 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1913 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1914} 1914}
@@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
2030 2030
2031 max98088_handle_pdata(codec); 2031 max98088_handle_pdata(codec);
2032 2032
2033 snd_soc_add_controls(codec, max98088_snd_controls, 2033 snd_soc_add_codec_controls(codec, max98088_snd_controls,
2034 ARRAY_SIZE(max98088_snd_controls)); 2034 ARRAY_SIZE(max98088_snd_controls));
2035 2035
2036err_access: 2036err_access:
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index fcfa7497d7b7..0bb511a0388d 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
1284 1284
1285static int max98095_add_widgets(struct snd_soc_codec *codec) 1285static int max98095_add_widgets(struct snd_soc_codec *codec)
1286{ 1286{
1287 snd_soc_add_controls(codec, max98095_snd_controls, 1287 snd_soc_add_codec_controls(codec, max98095_snd_controls,
1288 ARRAY_SIZE(max98095_snd_controls)); 1288 ARRAY_SIZE(max98095_snd_controls));
1289 1289
1290 return 0; 1290 return 0;
@@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1984 max98095->eq_enum.texts = max98095->eq_texts; 1984 max98095->eq_enum.texts = max98095->eq_texts;
1985 max98095->eq_enum.max = max98095->eq_textcnt; 1985 max98095->eq_enum.max = max98095->eq_textcnt;
1986 1986
1987 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 1987 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
1988 if (ret != 0) 1988 if (ret != 0)
1989 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); 1989 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1990} 1990}
@@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2139 max98095->bq_enum.texts = max98095->bq_texts; 2139 max98095->bq_enum.texts = max98095->bq_texts;
2140 max98095->bq_enum.max = max98095->bq_textcnt; 2140 max98095->bq_enum.max = max98095->bq_textcnt;
2141 2141
2142 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 2142 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
2143 if (ret != 0) 2143 if (ret != 0)
2144 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); 2144 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
2145} 2145}
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index dcf6f2a1600a..3a2ba3d8fd6d 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = {
253/* This function is called from ASoC machine driver */ 253/* This function is called from ASoC machine driver */
254int max9877_add_controls(struct snd_soc_codec *codec) 254int max9877_add_controls(struct snd_soc_codec *codec)
255{ 255{
256 return snd_soc_add_controls(codec, max9877_controls, 256 return snd_soc_add_codec_controls(codec, max9877_controls,
257 ARRAY_SIZE(max9877_controls)); 257 ARRAY_SIZE(max9877_controls));
258} 258}
259EXPORT_SYMBOL_GPL(max9877_add_controls); 259EXPORT_SYMBOL_GPL(max9877_add_controls);
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index f99baa0b8c39..50dbdb9357ea 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
827{ 827{
828 pr_debug("codec_probe called\n"); 828 pr_debug("codec_probe called\n");
829 829
830 codec->dapm.idle_bias_off = 1;
831
832 /* PCM interface config 830 /* PCM interface config
833 * This sets the pcm rx slot conguration to max 6 slots 831 * This sets the pcm rx slot conguration to max 6 slots
834 * for max 4 dais (2 stereo and 2 mono) 832 * for max 4 dais (2 stereo and 2 mono)
@@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
871 snd_soc_write(codec, SN95031_SSR2, 0x10); 869 snd_soc_write(codec, SN95031_SSR2, 0x10);
872 snd_soc_write(codec, SN95031_SSR3, 0x40); 870 snd_soc_write(codec, SN95031_SSR3, 0x40);
873 871
874 snd_soc_add_controls(codec, sn95031_snd_controls, 872 snd_soc_add_codec_controls(codec, sn95031_snd_controls,
875 ARRAY_SIZE(sn95031_snd_controls)); 873 ARRAY_SIZE(sn95031_snd_controls));
876 874
877 return 0; 875 return 0;
@@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = {
891 .read = sn95031_read, 889 .read = sn95031_read,
892 .write = sn95031_write, 890 .write = sn95031_write,
893 .set_bias_level = sn95031_set_vaud_bias, 891 .set_bias_level = sn95031_set_vaud_bias,
892 .idle_bias_off = true,
894 .dapm_widgets = sn95031_dapm_widgets, 893 .dapm_widgets = sn95031_dapm_widgets,
895 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), 894 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
896 .dapm_routes = sn95031_audio_map, 895 .dapm_routes = sn95031_audio_map,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 333dd98af39c..de2b20544ceb 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
548 snd_soc_update_bits(codec, SSM2602_ROUT1V, 548 snd_soc_update_bits(codec, SSM2602_ROUT1V,
549 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); 549 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
550 550
551 ret = snd_soc_add_controls(codec, ssm2602_snd_controls, 551 ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
552 ARRAY_SIZE(ssm2602_snd_controls)); 552 ARRAY_SIZE(ssm2602_snd_controls));
553 if (ret) 553 if (ret)
554 return ret; 554 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index cc0566c22ec1..982e437799a8 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
355 355
356 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 356 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
357 357
358 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 358 snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
359 ARRAY_SIZE(stac9766_snd_ac97_controls)); 359 ARRAY_SIZE(stac9766_snd_ac97_controls));
360 360
361 return 0; 361 return 0;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index dfa41a96599b..16d55f91a653 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
593 593
594 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); 594 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
595 595
596 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 596 snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
597 ARRAY_SIZE(tlv320aic23_snd_controls)); 597 ARRAY_SIZE(tlv320aic23_snd_controls));
598 598
599 return 0; 599 return 0;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index a038daec682b..802064b5030d 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
389 389
390 /* register controls */ 390 /* register controls */
391 dev_dbg(codec->dev, "Registering controls\n"); 391 dev_dbg(codec->dev, "Registering controls\n");
392 err = snd_soc_add_controls(codec, aic26_snd_controls, 392 err = snd_soc_add_codec_controls(codec, aic26_snd_controls,
393 ARRAY_SIZE(aic26_snd_controls)); 393 ARRAY_SIZE(aic26_snd_controls));
394 WARN_ON(err < 0); 394 WARN_ON(err < 0);
395 395
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 372b0b83bd9f..b0a73d37ed52 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
671 } 671 }
672 672
673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
674 snd_soc_add_controls(codec, aic32x4_snd_controls, 674 snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
675 ARRAY_SIZE(aic32x4_snd_controls)); 675 ARRAY_SIZE(aic32x4_snd_controls));
676 aic32x4_add_widgets(codec); 676 aic32x4_add_widgets(codec);
677 677
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 492f22f8a4d7..8d20f6ec20f3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
121 0x00, 0x00, 0x02, /* 100 */ 121 0x00, 0x00, 0x02, /* 100 */
122}; 122};
123 123
124/*
125 * read from the aic3x register space. Only use for this function is if
126 * wanting to read volatile bits from those registers that has both read-only
127 * and read/write bits. All other cases should use snd_soc_read.
128 */
129static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
130 u8 *value)
131{
132 u8 *cache = codec->reg_cache;
133
134 if (codec->cache_only)
135 return -EINVAL;
136 if (reg >= AIC3X_CACHEREGNUM)
137 return -1;
138
139 codec->cache_bypass = 1;
140 *value = snd_soc_read(codec, reg);
141 codec->cache_bypass = 0;
142
143 cache[reg] = *value;
144
145 return 0;
146}
147
148#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 124#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
149{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 125{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
150 .info = snd_soc_info_volsw, \ 126 .info = snd_soc_info_volsw, \
@@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1185 return 0; 1161 return 0;
1186} 1162}
1187 1163
1188void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1189{
1190 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1191 u8 bit = gpio ? 3: 0;
1192 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1193 snd_soc_write(codec, reg, val | (!!state << bit));
1194}
1195EXPORT_SYMBOL_GPL(aic3x_set_gpio);
1196
1197int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
1198{
1199 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1200 u8 val = 0, bit = gpio ? 2 : 1;
1201
1202 aic3x_read(codec, reg, &val);
1203 return (val >> bit) & 1;
1204}
1205EXPORT_SYMBOL_GPL(aic3x_get_gpio);
1206
1207void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, 1164void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1208 int headset_debounce, int button_debounce) 1165 int headset_debounce, int button_debounce)
1209{ 1166{
@@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1221 1178
1222 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); 1179 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1223} 1180}
1224EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1225
1226int aic3x_headset_detected(struct snd_soc_codec *codec)
1227{
1228 u8 val = 0;
1229 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1230 return (val >> 4) & 1;
1231}
1232EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1233
1234int aic3x_button_pressed(struct snd_soc_codec *codec)
1235{
1236 u8 val = 0;
1237 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1238 return (val >> 5) & 1;
1239}
1240EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1241 1181
1242#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1182#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1243#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1183#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1377 1317
1378 INIT_LIST_HEAD(&aic3x->list); 1318 INIT_LIST_HEAD(&aic3x->list);
1379 aic3x->codec = codec; 1319 aic3x->codec = codec;
1380 codec->dapm.idle_bias_off = 1;
1381 1320
1382 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); 1321 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1383 if (ret != 0) { 1322 if (ret != 0) {
@@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1426 (aic3x->setup->gpio_func[1] & 0xf) << 4); 1365 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1427 } 1366 }
1428 1367
1429 snd_soc_add_controls(codec, aic3x_snd_controls, 1368 snd_soc_add_codec_controls(codec, aic3x_snd_controls,
1430 ARRAY_SIZE(aic3x_snd_controls)); 1369 ARRAY_SIZE(aic3x_snd_controls));
1431 if (aic3x->model == AIC3X_MODEL_3007) 1370 if (aic3x->model == AIC3X_MODEL_3007)
1432 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1371 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1433 1372
1434 aic3x_add_widgets(codec); 1373 aic3x_add_widgets(codec);
1435 list_add(&aic3x->list, &reset_list); 1374 list_add(&aic3x->list, &reset_list);
@@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1471 1410
1472static struct snd_soc_codec_driver soc_codec_dev_aic3x = { 1411static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1473 .set_bias_level = aic3x_set_bias_level, 1412 .set_bias_level = aic3x_set_bias_level,
1413 .idle_bias_off = true,
1474 .reg_cache_size = ARRAY_SIZE(aic3x_reg), 1414 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1475 .reg_word_size = sizeof(u8), 1415 .reg_word_size = sizeof(u8),
1476 .reg_cache_default = aic3x_reg, 1416 .reg_cache_default = aic3x_reg,
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 06a19784b162..6f097fb60683 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -212,9 +212,6 @@
212/* Default input volume */ 212/* Default input volume */
213#define DEFAULT_GAIN 0x20 213#define DEFAULT_GAIN 0x20
214 214
215void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
216int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
217
218/* headset detection / button API */ 215/* headset detection / button API */
219 216
220/* The AIC3x supports detection of stereo headsets (GND + left + right signal) 217/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
@@ -252,10 +249,4 @@ enum {
252#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 249#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
253#define AIC3X_BUTTON_DEBOUNCE_MASK 3 250#define AIC3X_BUTTON_DEBOUNCE_MASK 3
254 251
255/* see the enums above for valid parameters to this function */
256void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
257 int headset_debounce, int button_debounce);
258int aic3x_headset_detected(struct snd_soc_codec *codec);
259int aic3x_button_pressed(struct snd_soc_codec *codec);
260
261#endif /* _AIC3X_H */ 252#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index c06c3e4b9127..4587ddd0fbf8 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1395,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1395 1395
1396 codec->control_data = dac33->control_data; 1396 codec->control_data = dac33->control_data;
1397 codec->hw_write = (hw_write_t) i2c_master_send; 1397 codec->hw_write = (hw_write_t) i2c_master_send;
1398 codec->dapm.idle_bias_off = 1;
1399 dac33->codec = codec; 1398 dac33->codec = codec;
1400 1399
1401 /* Read the tlv320dac33 ID registers */ 1400 /* Read the tlv320dac33 ID registers */
@@ -1438,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1438 1437
1439 /* Only add the FIFO controls, if we have valid IRQ number */ 1438 /* Only add the FIFO controls, if we have valid IRQ number */
1440 if (dac33->irq >= 0) 1439 if (dac33->irq >= 0)
1441 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1440 snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
1442 ARRAY_SIZE(dac33_mode_snd_controls)); 1441 ARRAY_SIZE(dac33_mode_snd_controls));
1443 1442
1444err_power: 1443err_power:
@@ -1476,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1476 .read = dac33_read_reg_cache, 1475 .read = dac33_read_reg_cache,
1477 .write = dac33_write_locked, 1476 .write = dac33_write_locked,
1478 .set_bias_level = dac33_set_bias_level, 1477 .set_bias_level = dac33_set_bias_level,
1478 .idle_bias_off = true,
1479 .reg_cache_size = ARRAY_SIZE(dac33_reg), 1479 .reg_cache_size = ARRAY_SIZE(dac33_reg),
1480 .reg_word_size = sizeof(u8), 1480 .reg_word_size = sizeof(u8),
1481 .reg_cache_default = dac33_reg, 1481 .reg_cache_default = dac33_reg,
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 363b99dad8e9..6fe4aa3ac544 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
351 data = i2c_get_clientdata(tpa6130a2_client); 351 data = i2c_get_clientdata(tpa6130a2_client);
352 352
353 if (data->id == TPA6140A2) 353 if (data->id == TPA6140A2)
354 return snd_soc_add_controls(codec, tpa6140a2_controls, 354 return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
355 ARRAY_SIZE(tpa6140a2_controls)); 355 ARRAY_SIZE(tpa6140a2_controls));
356 else 356 else
357 return snd_soc_add_controls(codec, tpa6130a2_controls, 357 return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
358 ARRAY_SIZE(tpa6130a2_controls)); 358 ARRAY_SIZE(tpa6130a2_controls));
359} 359}
360EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 360EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index a193f5fa4b3a..170cf9a8fc79 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
1002 unsigned short mask, bitmask; 1002 unsigned short mask, bitmask;
1003 1003
1004 if (twl4030->configured) { 1004 if (twl4030->configured) {
1005 printk(KERN_ERR "twl4030 operation mode cannot be " 1005 dev_err(codec->dev,
1006 "changed on-the-fly\n"); 1006 "operation mode cannot be changed on-the-fly\n");
1007 return -EBUSY; 1007 return -EBUSY;
1008 } 1008 }
1009 1009
@@ -1800,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1800 mode |= TWL4030_APLL_RATE_96000; 1800 mode |= TWL4030_APLL_RATE_96000;
1801 break; 1801 break;
1802 default: 1802 default:
1803 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", 1803 dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
1804 params_rate(params)); 1804 params_rate(params));
1805 return -EINVAL; 1805 return -EINVAL;
1806 } 1806 }
@@ -1817,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1817 format |= TWL4030_DATA_WIDTH_32S_24W; 1817 format |= TWL4030_DATA_WIDTH_32S_24W;
1818 break; 1818 break;
1819 default: 1819 default:
1820 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n", 1820 dev_err(codec->dev, "%s: unknown format %d\n", __func__,
1821 params_format(params)); 1821 params_format(params));
1822 return -EINVAL; 1822 return -EINVAL;
1823 } 1823 }
@@ -1867,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1867 case 38400000: 1867 case 38400000:
1868 break; 1868 break;
1869 default: 1869 default:
1870 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq); 1870 dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
1871 return -EINVAL; 1871 return -EINVAL;
1872 } 1872 }
1873 1873
1874 if ((freq / 1000) != twl4030->sysclk) { 1874 if ((freq / 1000) != twl4030->sysclk) {
1875 dev_err(codec->dev, 1875 dev_err(codec->dev,
1876 "Mismatch in APLL mclk: %u (configured: %u)\n", 1876 "Mismatch in HFCLKIN: %u (configured: %u)\n",
1877 freq, twl4030->sysclk * 1000); 1877 freq, twl4030->sysclk * 1000);
1878 return -EINVAL; 1878 return -EINVAL;
1879 } 1879 }
@@ -1983,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1983 * not available. 1983 * not available.
1984 */ 1984 */
1985 if (twl4030->sysclk != 26000) { 1985 if (twl4030->sysclk != 26000) {
1986 dev_err(codec->dev, "The board is configured for %u Hz, while" 1986 dev_err(codec->dev,
1987 "the Voice interface needs 26MHz APLL mclk\n", 1987 "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
1988 twl4030->sysclk * 1000); 1988 __func__, twl4030->sysclk);
1989 return -EINVAL; 1989 return -EINVAL;
1990 } 1990 }
1991 1991
@@ -1996,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1996 & TWL4030_OPT_MODE; 1996 & TWL4030_OPT_MODE;
1997 1997
1998 if (mode != TWL4030_OPTION_2) { 1998 if (mode != TWL4030_OPTION_2) {
1999 printk(KERN_ERR "TWL4030 voice startup: " 1999 dev_err(codec->dev, "%s: the codec mode is not option2\n",
2000 "the codec mode is not option2\n"); 2000 __func__);
2001 return -EINVAL; 2001 return -EINVAL;
2002 } 2002 }
2003 2003
@@ -2038,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2038 mode |= TWL4030_SEL_16K; 2038 mode |= TWL4030_SEL_16K;
2039 break; 2039 break;
2040 default: 2040 default:
2041 printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", 2041 dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
2042 params_rate(params)); 2042 params_rate(params));
2043 return -EINVAL; 2043 return -EINVAL;
2044 } 2044 }
@@ -2067,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
2067 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2067 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2068 2068
2069 if (freq != 26000000) { 2069 if (freq != 26000000) {
2070 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" 2070 dev_err(codec->dev,
2071 "interface needs 26MHz APLL mclk\n", freq); 2071 "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
2072 __func__, freq / 1000);
2072 return -EINVAL; 2073 return -EINVAL;
2073 } 2074 }
2074 if ((freq / 1000) != twl4030->sysclk) { 2075 if ((freq / 1000) != twl4030->sysclk) {
2075 dev_err(codec->dev, 2076 dev_err(codec->dev,
2076 "Mismatch in APLL mclk: %u (configured: %u)\n", 2077 "Mismatch in HFCLKIN: %u (configured: %u)\n",
2077 freq, twl4030->sysclk * 1000); 2078 freq, twl4030->sysclk * 1000);
2078 return -EINVAL; 2079 return -EINVAL;
2079 } 2080 }
@@ -2221,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2221 2222
2222 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2223 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2223 if (twl4030 == NULL) { 2224 if (twl4030 == NULL) {
2224 printk("Can not allocate memroy\n"); 2225 dev_err(codec->dev, "Can not allocate memory\n");
2225 return -ENOMEM; 2226 return -ENOMEM;
2226 } 2227 }
2227 snd_soc_codec_set_drvdata(codec, twl4030); 2228 snd_soc_codec_set_drvdata(codec, twl4030);
2228 /* Set the defaults, and power up the codec */ 2229 /* Set the defaults, and power up the codec */
2229 twl4030->sysclk = twl4030_audio_get_mclk() / 1000; 2230 twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
2230 codec->dapm.idle_bias_off = 1;
2231 2231
2232 twl4030_init_chip(codec); 2232 twl4030_init_chip(codec);
2233 2233
@@ -2253,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2253 .read = twl4030_read_reg_cache, 2253 .read = twl4030_read_reg_cache,
2254 .write = twl4030_write, 2254 .write = twl4030_write,
2255 .set_bias_level = twl4030_set_bias_level, 2255 .set_bias_level = twl4030_set_bias_level,
2256 .idle_bias_off = true,
2256 .reg_cache_size = sizeof(twl4030_reg), 2257 .reg_cache_size = sizeof(twl4030_reg),
2257 .reg_word_size = sizeof(u8), 2258 .reg_word_size = sizeof(u8),
2258 .reg_cache_default = twl4030_reg, 2259 .reg_cache_default = twl4030_reg,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 1a64edf671a2..2d8c6b825e57 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1540,7 +1540,6 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1540 1540
1541 priv->codec = codec; 1541 priv->codec = codec;
1542 codec->control_data = dev_get_drvdata(codec->dev->parent); 1542 codec->control_data = dev_get_drvdata(codec->dev->parent);
1543 codec->ignore_pmdown_time = 1;
1544 1543
1545 if (pdata && pdata->hs_left_step && pdata->hs_right_step) { 1544 if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
1546 priv->hs_left_step = pdata->hs_left_step; 1545 priv->hs_left_step = pdata->hs_left_step;
@@ -1626,6 +1625,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1626 .reg_cache_size = ARRAY_SIZE(twl6040_reg), 1625 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1627 .reg_word_size = sizeof(u8), 1626 .reg_word_size = sizeof(u8),
1628 .reg_cache_default = twl6040_reg, 1627 .reg_cache_default = twl6040_reg,
1628 .ignore_pmdown_time = true,
1629 1629
1630 .controls = twl6040_snd_controls, 1630 .controls = twl6040_snd_controls,
1631 .num_controls = ARRAY_SIZE(twl6040_snd_controls), 1631 .num_controls = ARRAY_SIZE(twl6040_snd_controls),
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 8f4f469d6411..797b0dde2c68 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -531,15 +531,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
531 switch (pd->model) { 531 switch (pd->model) {
532 case UDA134X_UDA1340: 532 case UDA134X_UDA1340:
533 case UDA134X_UDA1344: 533 case UDA134X_UDA1344:
534 ret = snd_soc_add_controls(codec, uda1340_snd_controls, 534 ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
535 ARRAY_SIZE(uda1340_snd_controls)); 535 ARRAY_SIZE(uda1340_snd_controls));
536 break; 536 break;
537 case UDA134X_UDA1341: 537 case UDA134X_UDA1341:
538 ret = snd_soc_add_controls(codec, uda1341_snd_controls, 538 ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
539 ARRAY_SIZE(uda1341_snd_controls)); 539 ARRAY_SIZE(uda1341_snd_controls));
540 break; 540 break;
541 case UDA134X_UDA1345: 541 case UDA134X_UDA1345:
542 ret = snd_soc_add_controls(codec, uda1345_snd_controls, 542 ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
543 ARRAY_SIZE(uda1345_snd_controls)); 543 ARRAY_SIZE(uda1345_snd_controls));
544 break; 544 break;
545 default: 545 default:
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 44aacf927ba9..3d868dc40092 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -464,7 +464,7 @@ static int wl1273_probe(struct snd_soc_codec *codec)
464 464
465 snd_soc_codec_set_drvdata(codec, wl1273); 465 snd_soc_codec_set_drvdata(codec, wl1273);
466 466
467 r = snd_soc_add_controls(codec, wl1273_controls, 467 r = snd_soc_add_codec_controls(codec, wl1273_controls,
468 ARRAY_SIZE(wl1273_controls)); 468 ARRAY_SIZE(wl1273_controls));
469 if (r) 469 if (r)
470 kfree(wl1273); 470 kfree(wl1273);
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index c2880907fced..a75c3766aede 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
733 struct wm2000_priv *wm2000; 733 struct wm2000_priv *wm2000;
734 struct wm2000_platform_data *pdata; 734 struct wm2000_platform_data *pdata;
735 const char *filename; 735 const char *filename;
736 const struct firmware *fw; 736 const struct firmware *fw = NULL;
737 int reg, ret; 737 int ret;
738 int reg;
738 u16 id; 739 u16 id;
739 740
740 wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), 741 wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv),
@@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
751 ret = PTR_ERR(wm2000->regmap); 752 ret = PTR_ERR(wm2000->regmap);
752 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 753 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
753 ret); 754 ret);
754 goto err; 755 goto out;
755 } 756 }
756 757
757 /* Verify that this is a WM2000 */ 758 /* Verify that this is a WM2000 */
@@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
763 if (id != 0x2000) { 764 if (id != 0x2000) {
764 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); 765 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
765 ret = -ENODEV; 766 ret = -ENODEV;
766 goto err_regmap; 767 goto out_regmap_exit;
767 } 768 }
768 769
769 reg = wm2000_read(i2c, WM2000_REG_REVISON); 770 reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
782 ret = request_firmware(&fw, filename, &i2c->dev); 783 ret = request_firmware(&fw, filename, &i2c->dev);
783 if (ret != 0) { 784 if (ret != 0) {
784 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); 785 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
785 goto err_regmap; 786 goto out_regmap_exit;
786 } 787 }
787 788
788 /* Pre-cook the concatenation of the register address onto the image */ 789 /* Pre-cook the concatenation of the register address onto the image */
@@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
793 if (wm2000->anc_download == NULL) { 794 if (wm2000->anc_download == NULL) {
794 dev_err(&i2c->dev, "Out of memory\n"); 795 dev_err(&i2c->dev, "Out of memory\n");
795 ret = -ENOMEM; 796 ret = -ENOMEM;
796 goto err_fw; 797 goto out_regmap_exit;
797 } 798 }
798 799
799 wm2000->anc_download[0] = 0x80; 800 wm2000->anc_download[0] = 0x80;
800 wm2000->anc_download[1] = 0x00; 801 wm2000->anc_download[1] = 0x00;
801 memcpy(wm2000->anc_download + 2, fw->data, fw->size); 802 memcpy(wm2000->anc_download + 2, fw->data, fw->size);
802 803
803 release_firmware(fw);
804
805 wm2000->anc_eng_ena = 1; 804 wm2000->anc_eng_ena = 1;
806 wm2000->anc_active = 1; 805 wm2000->anc_active = 1;
807 wm2000->spk_ena = 1; 806 wm2000->spk_ena = 1;
@@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
809 808
810 wm2000_reset(wm2000); 809 wm2000_reset(wm2000);
811 810
812 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, 811 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
813 NULL, 0); 812 if (!ret)
814 if (ret != 0) 813 goto out;
815 goto err_fw;
816 814
817 return 0; 815out_regmap_exit:
818
819err_fw:
820 release_firmware(fw);
821err_regmap:
822 regmap_exit(wm2000->regmap); 816 regmap_exit(wm2000->regmap);
823err: 817out:
818 release_firmware(fw);
824 return ret; 819 return ret;
825} 820}
826 821
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
new file mode 100644
index 000000000000..acbdc5fde923
--- /dev/null
+++ b/sound/soc/codecs/wm2200.c
@@ -0,0 +1,2286 @@
1/*
2 * wm2200.c -- WM2200 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
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/gcd.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/pm_runtime.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/jack.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <sound/wm2200.h>
33
34#include "wm2200.h"
35
36/* The code assumes DCVDD is generated internally */
37#define WM2200_NUM_CORE_SUPPLIES 2
38static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
39 "DBVDD",
40 "LDOVDD",
41};
42
43struct wm2200_fll {
44 int fref;
45 int fout;
46 int src;
47 struct completion lock;
48};
49
50/* codec private data */
51struct wm2200_priv {
52 struct regmap *regmap;
53 struct device *dev;
54 struct snd_soc_codec *codec;
55 struct wm2200_pdata pdata;
56 struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
57
58 struct completion fll_lock;
59 int fll_fout;
60 int fll_fref;
61 int fll_src;
62
63 int rev;
64 int sysclk;
65};
66
67static struct reg_default wm2200_reg_defaults[] = {
68 { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */
69 { 0x0102, 0x0000 }, /* R258 - Clocking 3 */
70 { 0x0103, 0x0011 }, /* R259 - Clocking 4 */
71 { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */
72 { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */
73 { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */
74 { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */
75 { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */
76 { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */
77 { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */
78 { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */
79 { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */
80 { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */
81 { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */
82 { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */
83 { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */
84 { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */
85 { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */
86 { 0x0301, 0x0000 }, /* R769 - Input Enables */
87 { 0x0302, 0x2240 }, /* R770 - IN1L Control */
88 { 0x0303, 0x0040 }, /* R771 - IN1R Control */
89 { 0x0304, 0x2240 }, /* R772 - IN2L Control */
90 { 0x0305, 0x0040 }, /* R773 - IN2R Control */
91 { 0x0306, 0x2240 }, /* R774 - IN3L Control */
92 { 0x0307, 0x0040 }, /* R775 - IN3R Control */
93 { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */
94 { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */
95 { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */
96 { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */
97 { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */
98 { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */
99 { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */
100 { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */
101 { 0x0400, 0x0000 }, /* R1024 - Output Enables */
102 { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */
103 { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */
104 { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */
105 { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */
106 { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */
107 { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */
108 { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */
109 { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */
110 { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */
111 { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */
112 { 0x0417, 0x0069 }, /* R1047 - PDM 1 */
113 { 0x0418, 0x0000 }, /* R1048 - PDM 2 */
114 { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */
115 { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */
116 { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */
117 { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */
118 { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */
119 { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */
120 { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */
121 { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */
122 { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */
123 { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */
124 { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */
125 { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */
126 { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */
127 { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */
128 { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */
129 { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */
130 { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */
131 { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */
132 { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */
133 { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */
134 { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */
135 { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */
136 { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */
137 { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */
138 { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */
139 { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */
140 { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */
141 { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */
142 { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */
143 { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */
144 { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */
145 { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */
146 { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */
147 { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */
148 { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */
149 { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */
150 { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */
151 { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */
152 { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */
153 { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */
154 { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */
155 { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */
156 { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */
157 { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */
158 { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */
159 { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */
160 { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */
161 { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */
162 { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */
163 { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */
164 { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */
165 { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */
166 { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */
167 { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */
168 { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */
169 { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */
170 { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */
171 { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */
172 { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */
173 { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */
174 { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */
175 { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */
176 { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */
177 { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */
178 { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */
179 { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */
180 { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */
181 { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */
182 { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */
183 { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */
184 { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */
185 { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */
186 { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */
187 { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */
188 { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */
189 { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */
190 { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */
191 { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */
192 { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */
193 { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */
194 { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */
195 { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */
196 { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */
197 { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */
198 { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */
199 { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */
200 { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */
201 { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */
202 { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */
203 { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */
204 { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */
205 { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */
206 { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */
207 { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */
208 { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */
209 { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */
210 { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */
211 { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */
212 { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */
213 { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */
214 { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */
215 { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */
216 { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */
217 { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */
218 { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */
219 { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */
220 { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */
221 { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */
222 { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */
223 { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */
224 { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */
225 { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */
226 { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */
227 { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */
228 { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */
229 { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */
230 { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */
231 { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */
232 { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */
233 { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */
234 { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */
235 { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */
236 { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */
237 { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */
238 { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */
239 { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */
240 { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */
241 { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */
242 { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */
243 { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */
244 { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */
245 { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */
246 { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */
247 { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */
248 { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */
249 { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */
250 { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */
251 { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */
252 { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */
253 { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */
254 { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */
255 { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */
256 { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */
257 { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */
258 { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */
259 { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */
260 { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */
261 { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */
262 { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */
263 { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */
264 { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */
265 { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */
266 { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */
267 { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */
268 { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */
269 { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */
270 { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */
271 { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */
272 { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */
273 { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */
274 { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */
275 { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */
276 { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */
277 { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */
278 { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */
279 { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */
280 { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */
281 { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */
282 { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */
283 { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */
284 { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */
285 { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */
286 { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */
287 { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */
288 { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */
289 { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */
290 { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */
291 { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */
292 { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */
293 { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */
294 { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */
295 { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */
296 { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */
297 { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */
298 { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */
299 { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */
300 { 0x0900, 0x0000 }, /* R2304 - EQL_1 */
301 { 0x0901, 0x0000 }, /* R2305 - EQL_2 */
302 { 0x0902, 0x0000 }, /* R2306 - EQL_3 */
303 { 0x0903, 0x0000 }, /* R2307 - EQL_4 */
304 { 0x0904, 0x0000 }, /* R2308 - EQL_5 */
305 { 0x0905, 0x0000 }, /* R2309 - EQL_6 */
306 { 0x0906, 0x0000 }, /* R2310 - EQL_7 */
307 { 0x0907, 0x0000 }, /* R2311 - EQL_8 */
308 { 0x0908, 0x0000 }, /* R2312 - EQL_9 */
309 { 0x0909, 0x0000 }, /* R2313 - EQL_10 */
310 { 0x090A, 0x0000 }, /* R2314 - EQL_11 */
311 { 0x090B, 0x0000 }, /* R2315 - EQL_12 */
312 { 0x090C, 0x0000 }, /* R2316 - EQL_13 */
313 { 0x090D, 0x0000 }, /* R2317 - EQL_14 */
314 { 0x090E, 0x0000 }, /* R2318 - EQL_15 */
315 { 0x090F, 0x0000 }, /* R2319 - EQL_16 */
316 { 0x0910, 0x0000 }, /* R2320 - EQL_17 */
317 { 0x0911, 0x0000 }, /* R2321 - EQL_18 */
318 { 0x0912, 0x0000 }, /* R2322 - EQL_19 */
319 { 0x0913, 0x0000 }, /* R2323 - EQL_20 */
320 { 0x0916, 0x0000 }, /* R2326 - EQR_1 */
321 { 0x0917, 0x0000 }, /* R2327 - EQR_2 */
322 { 0x0918, 0x0000 }, /* R2328 - EQR_3 */
323 { 0x0919, 0x0000 }, /* R2329 - EQR_4 */
324 { 0x091A, 0x0000 }, /* R2330 - EQR_5 */
325 { 0x091B, 0x0000 }, /* R2331 - EQR_6 */
326 { 0x091C, 0x0000 }, /* R2332 - EQR_7 */
327 { 0x091D, 0x0000 }, /* R2333 - EQR_8 */
328 { 0x091E, 0x0000 }, /* R2334 - EQR_9 */
329 { 0x091F, 0x0000 }, /* R2335 - EQR_10 */
330 { 0x0920, 0x0000 }, /* R2336 - EQR_11 */
331 { 0x0921, 0x0000 }, /* R2337 - EQR_12 */
332 { 0x0922, 0x0000 }, /* R2338 - EQR_13 */
333 { 0x0923, 0x0000 }, /* R2339 - EQR_14 */
334 { 0x0924, 0x0000 }, /* R2340 - EQR_15 */
335 { 0x0925, 0x0000 }, /* R2341 - EQR_16 */
336 { 0x0926, 0x0000 }, /* R2342 - EQR_17 */
337 { 0x0927, 0x0000 }, /* R2343 - EQR_18 */
338 { 0x0928, 0x0000 }, /* R2344 - EQR_19 */
339 { 0x0929, 0x0000 }, /* R2345 - EQR_20 */
340 { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */
341 { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */
342 { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */
343 { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */
344 { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */
345 { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */
346 { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */
347 { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */
348 { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */
349 { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */
350 { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */
351 { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */
352 { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */
353 { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */
354 { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */
355 { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */
356 { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */
357 { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */
358 { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */
359 { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */
360 { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */
361 { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */
362 { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */
363 { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */
364 { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */
365 { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */
366 { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */
367 { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */
368 { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */
369 { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */
370 { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */
371 { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */
372 { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */
373 { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */
374 { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */
375 { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */
376 { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */
377 { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */
378 { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */
379 { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */
380 { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */
381 { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */
382 { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */
383 { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */
384 { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */
385 { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */
386 { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */
387 { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */
388 { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */
389 { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */
390 { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */
391 { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */
392 { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */
393 { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */
394 { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */
395 { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */
396 { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */
397 { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */
398 { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */
399 { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */
400 { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */
401 { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */
402 { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */
403 { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */
404 { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */
405 { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */
406};
407
408static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
409{
410 switch (reg) {
411 case WM2200_SOFTWARE_RESET:
412 case WM2200_DEVICE_REVISION:
413 case WM2200_ADPS1_IRQ0:
414 case WM2200_ADPS1_IRQ1:
415 case WM2200_INTERRUPT_STATUS_1:
416 case WM2200_INTERRUPT_STATUS_2:
417 case WM2200_INTERRUPT_RAW_STATUS_2:
418 return true;
419 default:
420 return false;
421 }
422}
423
424static bool wm2200_readable_register(struct device *dev, unsigned int reg)
425{
426 switch (reg) {
427 case WM2200_SOFTWARE_RESET:
428 case WM2200_DEVICE_REVISION:
429 case WM2200_TONE_GENERATOR_1:
430 case WM2200_CLOCKING_3:
431 case WM2200_CLOCKING_4:
432 case WM2200_FLL_CONTROL_1:
433 case WM2200_FLL_CONTROL_2:
434 case WM2200_FLL_CONTROL_3:
435 case WM2200_FLL_CONTROL_4:
436 case WM2200_FLL_CONTROL_6:
437 case WM2200_FLL_CONTROL_7:
438 case WM2200_FLL_EFS_1:
439 case WM2200_FLL_EFS_2:
440 case WM2200_MIC_CHARGE_PUMP_1:
441 case WM2200_MIC_CHARGE_PUMP_2:
442 case WM2200_DM_CHARGE_PUMP_1:
443 case WM2200_MIC_BIAS_CTRL_1:
444 case WM2200_MIC_BIAS_CTRL_2:
445 case WM2200_EAR_PIECE_CTRL_1:
446 case WM2200_EAR_PIECE_CTRL_2:
447 case WM2200_INPUT_ENABLES:
448 case WM2200_IN1L_CONTROL:
449 case WM2200_IN1R_CONTROL:
450 case WM2200_IN2L_CONTROL:
451 case WM2200_IN2R_CONTROL:
452 case WM2200_IN3L_CONTROL:
453 case WM2200_IN3R_CONTROL:
454 case WM2200_RXANC_SRC:
455 case WM2200_INPUT_VOLUME_RAMP:
456 case WM2200_ADC_DIGITAL_VOLUME_1L:
457 case WM2200_ADC_DIGITAL_VOLUME_1R:
458 case WM2200_ADC_DIGITAL_VOLUME_2L:
459 case WM2200_ADC_DIGITAL_VOLUME_2R:
460 case WM2200_ADC_DIGITAL_VOLUME_3L:
461 case WM2200_ADC_DIGITAL_VOLUME_3R:
462 case WM2200_OUTPUT_ENABLES:
463 case WM2200_DAC_VOLUME_LIMIT_1L:
464 case WM2200_DAC_VOLUME_LIMIT_1R:
465 case WM2200_DAC_VOLUME_LIMIT_2L:
466 case WM2200_DAC_VOLUME_LIMIT_2R:
467 case WM2200_DAC_AEC_CONTROL_1:
468 case WM2200_OUTPUT_VOLUME_RAMP:
469 case WM2200_DAC_DIGITAL_VOLUME_1L:
470 case WM2200_DAC_DIGITAL_VOLUME_1R:
471 case WM2200_DAC_DIGITAL_VOLUME_2L:
472 case WM2200_DAC_DIGITAL_VOLUME_2R:
473 case WM2200_PDM_1:
474 case WM2200_PDM_2:
475 case WM2200_AUDIO_IF_1_1:
476 case WM2200_AUDIO_IF_1_2:
477 case WM2200_AUDIO_IF_1_3:
478 case WM2200_AUDIO_IF_1_4:
479 case WM2200_AUDIO_IF_1_5:
480 case WM2200_AUDIO_IF_1_6:
481 case WM2200_AUDIO_IF_1_7:
482 case WM2200_AUDIO_IF_1_8:
483 case WM2200_AUDIO_IF_1_9:
484 case WM2200_AUDIO_IF_1_10:
485 case WM2200_AUDIO_IF_1_11:
486 case WM2200_AUDIO_IF_1_12:
487 case WM2200_AUDIO_IF_1_13:
488 case WM2200_AUDIO_IF_1_14:
489 case WM2200_AUDIO_IF_1_15:
490 case WM2200_AUDIO_IF_1_16:
491 case WM2200_AUDIO_IF_1_17:
492 case WM2200_AUDIO_IF_1_18:
493 case WM2200_AUDIO_IF_1_19:
494 case WM2200_AUDIO_IF_1_20:
495 case WM2200_AUDIO_IF_1_21:
496 case WM2200_AUDIO_IF_1_22:
497 case WM2200_OUT1LMIX_INPUT_1_SOURCE:
498 case WM2200_OUT1LMIX_INPUT_1_VOLUME:
499 case WM2200_OUT1LMIX_INPUT_2_SOURCE:
500 case WM2200_OUT1LMIX_INPUT_2_VOLUME:
501 case WM2200_OUT1LMIX_INPUT_3_SOURCE:
502 case WM2200_OUT1LMIX_INPUT_3_VOLUME:
503 case WM2200_OUT1LMIX_INPUT_4_SOURCE:
504 case WM2200_OUT1LMIX_INPUT_4_VOLUME:
505 case WM2200_OUT1RMIX_INPUT_1_SOURCE:
506 case WM2200_OUT1RMIX_INPUT_1_VOLUME:
507 case WM2200_OUT1RMIX_INPUT_2_SOURCE:
508 case WM2200_OUT1RMIX_INPUT_2_VOLUME:
509 case WM2200_OUT1RMIX_INPUT_3_SOURCE:
510 case WM2200_OUT1RMIX_INPUT_3_VOLUME:
511 case WM2200_OUT1RMIX_INPUT_4_SOURCE:
512 case WM2200_OUT1RMIX_INPUT_4_VOLUME:
513 case WM2200_OUT2LMIX_INPUT_1_SOURCE:
514 case WM2200_OUT2LMIX_INPUT_1_VOLUME:
515 case WM2200_OUT2LMIX_INPUT_2_SOURCE:
516 case WM2200_OUT2LMIX_INPUT_2_VOLUME:
517 case WM2200_OUT2LMIX_INPUT_3_SOURCE:
518 case WM2200_OUT2LMIX_INPUT_3_VOLUME:
519 case WM2200_OUT2LMIX_INPUT_4_SOURCE:
520 case WM2200_OUT2LMIX_INPUT_4_VOLUME:
521 case WM2200_OUT2RMIX_INPUT_1_SOURCE:
522 case WM2200_OUT2RMIX_INPUT_1_VOLUME:
523 case WM2200_OUT2RMIX_INPUT_2_SOURCE:
524 case WM2200_OUT2RMIX_INPUT_2_VOLUME:
525 case WM2200_OUT2RMIX_INPUT_3_SOURCE:
526 case WM2200_OUT2RMIX_INPUT_3_VOLUME:
527 case WM2200_OUT2RMIX_INPUT_4_SOURCE:
528 case WM2200_OUT2RMIX_INPUT_4_VOLUME:
529 case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
530 case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
531 case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
532 case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
533 case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
534 case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
535 case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
536 case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
537 case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
538 case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
539 case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
540 case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
541 case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
542 case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
543 case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
544 case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
545 case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
546 case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
547 case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
548 case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
549 case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
550 case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
551 case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
552 case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
553 case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
554 case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
555 case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
556 case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
557 case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
558 case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
559 case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
560 case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
561 case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
562 case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
563 case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
564 case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
565 case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
566 case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
567 case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
568 case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
569 case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
570 case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
571 case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
572 case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
573 case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
574 case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
575 case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
576 case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
577 case WM2200_EQLMIX_INPUT_1_SOURCE:
578 case WM2200_EQLMIX_INPUT_1_VOLUME:
579 case WM2200_EQLMIX_INPUT_2_SOURCE:
580 case WM2200_EQLMIX_INPUT_2_VOLUME:
581 case WM2200_EQLMIX_INPUT_3_SOURCE:
582 case WM2200_EQLMIX_INPUT_3_VOLUME:
583 case WM2200_EQLMIX_INPUT_4_SOURCE:
584 case WM2200_EQLMIX_INPUT_4_VOLUME:
585 case WM2200_EQRMIX_INPUT_1_SOURCE:
586 case WM2200_EQRMIX_INPUT_1_VOLUME:
587 case WM2200_EQRMIX_INPUT_2_SOURCE:
588 case WM2200_EQRMIX_INPUT_2_VOLUME:
589 case WM2200_EQRMIX_INPUT_3_SOURCE:
590 case WM2200_EQRMIX_INPUT_3_VOLUME:
591 case WM2200_EQRMIX_INPUT_4_SOURCE:
592 case WM2200_EQRMIX_INPUT_4_VOLUME:
593 case WM2200_LHPF1MIX_INPUT_1_SOURCE:
594 case WM2200_LHPF1MIX_INPUT_1_VOLUME:
595 case WM2200_LHPF1MIX_INPUT_2_SOURCE:
596 case WM2200_LHPF1MIX_INPUT_2_VOLUME:
597 case WM2200_LHPF1MIX_INPUT_3_SOURCE:
598 case WM2200_LHPF1MIX_INPUT_3_VOLUME:
599 case WM2200_LHPF1MIX_INPUT_4_SOURCE:
600 case WM2200_LHPF1MIX_INPUT_4_VOLUME:
601 case WM2200_LHPF2MIX_INPUT_1_SOURCE:
602 case WM2200_LHPF2MIX_INPUT_1_VOLUME:
603 case WM2200_LHPF2MIX_INPUT_2_SOURCE:
604 case WM2200_LHPF2MIX_INPUT_2_VOLUME:
605 case WM2200_LHPF2MIX_INPUT_3_SOURCE:
606 case WM2200_LHPF2MIX_INPUT_3_VOLUME:
607 case WM2200_LHPF2MIX_INPUT_4_SOURCE:
608 case WM2200_LHPF2MIX_INPUT_4_VOLUME:
609 case WM2200_DSP1LMIX_INPUT_1_SOURCE:
610 case WM2200_DSP1LMIX_INPUT_1_VOLUME:
611 case WM2200_DSP1LMIX_INPUT_2_SOURCE:
612 case WM2200_DSP1LMIX_INPUT_2_VOLUME:
613 case WM2200_DSP1LMIX_INPUT_3_SOURCE:
614 case WM2200_DSP1LMIX_INPUT_3_VOLUME:
615 case WM2200_DSP1LMIX_INPUT_4_SOURCE:
616 case WM2200_DSP1LMIX_INPUT_4_VOLUME:
617 case WM2200_DSP1RMIX_INPUT_1_SOURCE:
618 case WM2200_DSP1RMIX_INPUT_1_VOLUME:
619 case WM2200_DSP1RMIX_INPUT_2_SOURCE:
620 case WM2200_DSP1RMIX_INPUT_2_VOLUME:
621 case WM2200_DSP1RMIX_INPUT_3_SOURCE:
622 case WM2200_DSP1RMIX_INPUT_3_VOLUME:
623 case WM2200_DSP1RMIX_INPUT_4_SOURCE:
624 case WM2200_DSP1RMIX_INPUT_4_VOLUME:
625 case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
626 case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
627 case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
628 case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
629 case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
630 case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
631 case WM2200_DSP2LMIX_INPUT_1_SOURCE:
632 case WM2200_DSP2LMIX_INPUT_1_VOLUME:
633 case WM2200_DSP2LMIX_INPUT_2_SOURCE:
634 case WM2200_DSP2LMIX_INPUT_2_VOLUME:
635 case WM2200_DSP2LMIX_INPUT_3_SOURCE:
636 case WM2200_DSP2LMIX_INPUT_3_VOLUME:
637 case WM2200_DSP2LMIX_INPUT_4_SOURCE:
638 case WM2200_DSP2LMIX_INPUT_4_VOLUME:
639 case WM2200_DSP2RMIX_INPUT_1_SOURCE:
640 case WM2200_DSP2RMIX_INPUT_1_VOLUME:
641 case WM2200_DSP2RMIX_INPUT_2_SOURCE:
642 case WM2200_DSP2RMIX_INPUT_2_VOLUME:
643 case WM2200_DSP2RMIX_INPUT_3_SOURCE:
644 case WM2200_DSP2RMIX_INPUT_3_VOLUME:
645 case WM2200_DSP2RMIX_INPUT_4_SOURCE:
646 case WM2200_DSP2RMIX_INPUT_4_VOLUME:
647 case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
648 case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
649 case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
650 case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
651 case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
652 case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
653 case WM2200_GPIO_CTRL_1:
654 case WM2200_GPIO_CTRL_2:
655 case WM2200_GPIO_CTRL_3:
656 case WM2200_GPIO_CTRL_4:
657 case WM2200_ADPS1_IRQ0:
658 case WM2200_ADPS1_IRQ1:
659 case WM2200_MISC_PAD_CTRL_1:
660 case WM2200_INTERRUPT_STATUS_1:
661 case WM2200_INTERRUPT_STATUS_1_MASK:
662 case WM2200_INTERRUPT_STATUS_2:
663 case WM2200_INTERRUPT_RAW_STATUS_2:
664 case WM2200_INTERRUPT_STATUS_2_MASK:
665 case WM2200_INTERRUPT_CONTROL:
666 case WM2200_EQL_1:
667 case WM2200_EQL_2:
668 case WM2200_EQL_3:
669 case WM2200_EQL_4:
670 case WM2200_EQL_5:
671 case WM2200_EQL_6:
672 case WM2200_EQL_7:
673 case WM2200_EQL_8:
674 case WM2200_EQL_9:
675 case WM2200_EQL_10:
676 case WM2200_EQL_11:
677 case WM2200_EQL_12:
678 case WM2200_EQL_13:
679 case WM2200_EQL_14:
680 case WM2200_EQL_15:
681 case WM2200_EQL_16:
682 case WM2200_EQL_17:
683 case WM2200_EQL_18:
684 case WM2200_EQL_19:
685 case WM2200_EQL_20:
686 case WM2200_EQR_1:
687 case WM2200_EQR_2:
688 case WM2200_EQR_3:
689 case WM2200_EQR_4:
690 case WM2200_EQR_5:
691 case WM2200_EQR_6:
692 case WM2200_EQR_7:
693 case WM2200_EQR_8:
694 case WM2200_EQR_9:
695 case WM2200_EQR_10:
696 case WM2200_EQR_11:
697 case WM2200_EQR_12:
698 case WM2200_EQR_13:
699 case WM2200_EQR_14:
700 case WM2200_EQR_15:
701 case WM2200_EQR_16:
702 case WM2200_EQR_17:
703 case WM2200_EQR_18:
704 case WM2200_EQR_19:
705 case WM2200_EQR_20:
706 case WM2200_HPLPF1_1:
707 case WM2200_HPLPF1_2:
708 case WM2200_HPLPF2_1:
709 case WM2200_HPLPF2_2:
710 case WM2200_DSP1_CONTROL_1:
711 case WM2200_DSP1_CONTROL_2:
712 case WM2200_DSP1_CONTROL_3:
713 case WM2200_DSP1_CONTROL_4:
714 case WM2200_DSP1_CONTROL_5:
715 case WM2200_DSP1_CONTROL_6:
716 case WM2200_DSP1_CONTROL_7:
717 case WM2200_DSP1_CONTROL_8:
718 case WM2200_DSP1_CONTROL_9:
719 case WM2200_DSP1_CONTROL_10:
720 case WM2200_DSP1_CONTROL_11:
721 case WM2200_DSP1_CONTROL_12:
722 case WM2200_DSP1_CONTROL_13:
723 case WM2200_DSP1_CONTROL_14:
724 case WM2200_DSP1_CONTROL_15:
725 case WM2200_DSP1_CONTROL_16:
726 case WM2200_DSP1_CONTROL_17:
727 case WM2200_DSP1_CONTROL_18:
728 case WM2200_DSP1_CONTROL_19:
729 case WM2200_DSP1_CONTROL_20:
730 case WM2200_DSP1_CONTROL_21:
731 case WM2200_DSP1_CONTROL_22:
732 case WM2200_DSP1_CONTROL_23:
733 case WM2200_DSP1_CONTROL_24:
734 case WM2200_DSP1_CONTROL_25:
735 case WM2200_DSP1_CONTROL_26:
736 case WM2200_DSP1_CONTROL_27:
737 case WM2200_DSP1_CONTROL_28:
738 case WM2200_DSP1_CONTROL_29:
739 case WM2200_DSP1_CONTROL_30:
740 case WM2200_DSP1_CONTROL_31:
741 case WM2200_DSP2_CONTROL_1:
742 case WM2200_DSP2_CONTROL_2:
743 case WM2200_DSP2_CONTROL_3:
744 case WM2200_DSP2_CONTROL_4:
745 case WM2200_DSP2_CONTROL_5:
746 case WM2200_DSP2_CONTROL_6:
747 case WM2200_DSP2_CONTROL_7:
748 case WM2200_DSP2_CONTROL_8:
749 case WM2200_DSP2_CONTROL_9:
750 case WM2200_DSP2_CONTROL_10:
751 case WM2200_DSP2_CONTROL_11:
752 case WM2200_DSP2_CONTROL_12:
753 case WM2200_DSP2_CONTROL_13:
754 case WM2200_DSP2_CONTROL_14:
755 case WM2200_DSP2_CONTROL_15:
756 case WM2200_DSP2_CONTROL_16:
757 case WM2200_DSP2_CONTROL_17:
758 case WM2200_DSP2_CONTROL_18:
759 case WM2200_DSP2_CONTROL_19:
760 case WM2200_DSP2_CONTROL_20:
761 case WM2200_DSP2_CONTROL_21:
762 case WM2200_DSP2_CONTROL_22:
763 case WM2200_DSP2_CONTROL_23:
764 case WM2200_DSP2_CONTROL_24:
765 case WM2200_DSP2_CONTROL_25:
766 case WM2200_DSP2_CONTROL_26:
767 case WM2200_DSP2_CONTROL_27:
768 case WM2200_DSP2_CONTROL_28:
769 case WM2200_DSP2_CONTROL_29:
770 case WM2200_DSP2_CONTROL_30:
771 case WM2200_DSP2_CONTROL_31:
772 return true;
773 default:
774 return false;
775 }
776}
777
778static const struct reg_default wm2200_reva_patch[] = {
779 { 0x07, 0x0003 },
780 { 0x102, 0x0200 },
781 { 0x203, 0x0084 },
782 { 0x201, 0x83FF },
783 { 0x20C, 0x0062 },
784 { 0x20D, 0x0062 },
785 { 0x207, 0x2002 },
786 { 0x208, 0x20C0 },
787 { 0x21D, 0x01C0 },
788 { 0x50A, 0x0001 },
789 { 0x50B, 0x0002 },
790 { 0x50C, 0x0003 },
791 { 0x50D, 0x0004 },
792 { 0x50E, 0x0005 },
793 { 0x510, 0x0001 },
794 { 0x511, 0x0002 },
795 { 0x512, 0x0003 },
796 { 0x513, 0x0004 },
797 { 0x514, 0x0005 },
798 { 0x515, 0x0000 },
799 { 0x201, 0x8084 },
800 { 0x202, 0xBBDE },
801 { 0x203, 0x00EC },
802 { 0x500, 0x8000 },
803 { 0x507, 0x1820 },
804 { 0x508, 0x1820 },
805 { 0x505, 0x0300 },
806 { 0x506, 0x0300 },
807 { 0x302, 0x2280 },
808 { 0x303, 0x0080 },
809 { 0x304, 0x2280 },
810 { 0x305, 0x0080 },
811 { 0x306, 0x2280 },
812 { 0x307, 0x0080 },
813 { 0x401, 0x0080 },
814 { 0x402, 0x0080 },
815 { 0x417, 0x3069 },
816 { 0x900, 0x6318 },
817 { 0x901, 0x6300 },
818 { 0x902, 0x0FC8 },
819 { 0x903, 0x03FE },
820 { 0x904, 0x00E0 },
821 { 0x905, 0x1EC4 },
822 { 0x906, 0xF136 },
823 { 0x907, 0x0409 },
824 { 0x908, 0x04CC },
825 { 0x909, 0x1C9B },
826 { 0x90A, 0xF337 },
827 { 0x90B, 0x040B },
828 { 0x90C, 0x0CBB },
829 { 0x90D, 0x16F8 },
830 { 0x90E, 0xF7D9 },
831 { 0x90F, 0x040A },
832 { 0x910, 0x1F14 },
833 { 0x911, 0x058C },
834 { 0x912, 0x0563 },
835 { 0x913, 0x4000 },
836 { 0x916, 0x6318 },
837 { 0x917, 0x6300 },
838 { 0x918, 0x0FC8 },
839 { 0x919, 0x03FE },
840 { 0x91A, 0x00E0 },
841 { 0x91B, 0x1EC4 },
842 { 0x91C, 0xF136 },
843 { 0x91D, 0x0409 },
844 { 0x91E, 0x04CC },
845 { 0x91F, 0x1C9B },
846 { 0x920, 0xF337 },
847 { 0x921, 0x040B },
848 { 0x922, 0x0CBB },
849 { 0x923, 0x16F8 },
850 { 0x924, 0xF7D9 },
851 { 0x925, 0x040A },
852 { 0x926, 0x1F14 },
853 { 0x927, 0x058C },
854 { 0x928, 0x0563 },
855 { 0x929, 0x4000 },
856 { 0x709, 0x2000 },
857 { 0x207, 0x200E },
858 { 0x208, 0x20D4 },
859 { 0x20A, 0x0080 },
860 { 0x07, 0x0000 },
861};
862
863static int wm2200_reset(struct wm2200_priv *wm2200)
864{
865 if (wm2200->pdata.reset) {
866 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
867 gpio_set_value_cansleep(wm2200->pdata.reset, 1);
868
869 return 0;
870 } else {
871 return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
872 0x2200);
873 }
874}
875
876static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
877static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
878static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
879
880static const char *wm2200_mixer_texts[] = {
881 "None",
882 "Tone Generator",
883 "AEC loopback",
884 "IN1L",
885 "IN1R",
886 "IN2L",
887 "IN2R",
888 "IN3L",
889 "IN3R",
890 "AIF1RX1",
891 "AIF1RX2",
892 "AIF1RX3",
893 "AIF1RX4",
894 "AIF1RX5",
895 "AIF1RX6",
896 "EQL",
897 "EQR",
898 "LHPF1",
899 "LHPF2",
900 "LHPF3",
901 "LHPF4",
902 "DSP1.1",
903 "DSP1.2",
904 "DSP1.3",
905 "DSP1.4",
906 "DSP1.5",
907 "DSP1.6",
908 "DSP2.1",
909 "DSP2.2",
910 "DSP2.3",
911 "DSP2.4",
912 "DSP2.5",
913 "DSP2.6",
914};
915
916static int wm2200_mixer_values[] = {
917 0x00,
918 0x04, /* Tone */
919 0x08, /* AEC */
920 0x10, /* Input */
921 0x11,
922 0x12,
923 0x13,
924 0x14,
925 0x15,
926 0x20, /* AIF */
927 0x21,
928 0x22,
929 0x23,
930 0x24,
931 0x25,
932 0x50, /* EQ */
933 0x51,
934 0x52,
935 0x60, /* LHPF1 */
936 0x61, /* LHPF2 */
937 0x68, /* DSP1 */
938 0x69,
939 0x6a,
940 0x6b,
941 0x6c,
942 0x6d,
943 0x70, /* DSP2 */
944 0x71,
945 0x72,
946 0x73,
947 0x74,
948 0x75,
949};
950
951#define WM2200_MIXER_CONTROLS(name, base) \
952 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
953 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
954 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
955 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
956 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
957 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
958 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
959 WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
960
961#define WM2200_MUX_ENUM_DECL(name, reg) \
962 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
963 wm2200_mixer_texts, wm2200_mixer_values)
964
965#define WM2200_MUX_CTL_DECL(name) \
966 const struct snd_kcontrol_new name##_mux = \
967 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
968
969#define WM2200_MIXER_ENUMS(name, base_reg) \
970 static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
971 static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
972 static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
973 static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
974 static WM2200_MUX_CTL_DECL(name##_in1); \
975 static WM2200_MUX_CTL_DECL(name##_in2); \
976 static WM2200_MUX_CTL_DECL(name##_in3); \
977 static WM2200_MUX_CTL_DECL(name##_in4)
978
979static const struct snd_kcontrol_new wm2200_snd_controls[] = {
980SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
981 WM2200_IN1_OSR_SHIFT, 1, 0),
982SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
983 WM2200_IN2_OSR_SHIFT, 1, 0),
984SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
985 WM2200_IN3_OSR_SHIFT, 1, 0),
986
987SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
988 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
989SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
990 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
991SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
992 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
993
994SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
995 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
996SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
997 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
998SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
999 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1000
1001SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
1002 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
1003 0xbf, 0, digital_tlv),
1004SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
1005 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
1006 0xbf, 0, digital_tlv),
1007SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1008 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1009 0xbf, 0, digital_tlv),
1010
1011SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1012 WM2200_OUT1_OSR_SHIFT, 1, 0),
1013SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1014 WM2200_OUT2_OSR_SHIFT, 1, 0),
1015
1016SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1017 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
1018SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
1019 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
1020 digital_tlv),
1021SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
1022 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
1023 0x46, 0, out_tlv),
1024
1025SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1026 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
1027SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1028 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
1029 digital_tlv),
1030SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1031 WM2200_SPK1R_MUTE_SHIFT, 1, 0),
1032};
1033
1034WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
1035WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
1036WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
1037WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
1038
1039WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
1040WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
1041WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
1042WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
1043WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
1044WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
1045
1046WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
1047WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
1048
1049WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
1050WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
1051WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
1052WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
1053
1054WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
1055WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
1056
1057#define WM2200_MUX(name, ctrl) \
1058 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
1059
1060#define WM2200_MIXER_WIDGETS(name, name_str) \
1061 WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
1062 WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
1063 WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
1064 WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
1065 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
1066
1067#define WM2200_MIXER_INPUT_ROUTES(name) \
1068 { name, "Tone Generator", "Tone Generator" }, \
1069 { name, "IN1L", "IN1L PGA" }, \
1070 { name, "IN1R", "IN1R PGA" }, \
1071 { name, "IN2L", "IN2L PGA" }, \
1072 { name, "IN2R", "IN2R PGA" }, \
1073 { name, "IN3L", "IN3L PGA" }, \
1074 { name, "IN3R", "IN3R PGA" }, \
1075 { name, "DSP1.1", "DSP1" }, \
1076 { name, "DSP1.2", "DSP1" }, \
1077 { name, "DSP1.3", "DSP1" }, \
1078 { name, "DSP1.4", "DSP1" }, \
1079 { name, "DSP1.5", "DSP1" }, \
1080 { name, "DSP1.6", "DSP1" }, \
1081 { name, "DSP2.1", "DSP2" }, \
1082 { name, "DSP2.2", "DSP2" }, \
1083 { name, "DSP2.3", "DSP2" }, \
1084 { name, "DSP2.4", "DSP2" }, \
1085 { name, "DSP2.5", "DSP2" }, \
1086 { name, "DSP2.6", "DSP2" }, \
1087 { name, "AIF1RX1", "AIF1RX1" }, \
1088 { name, "AIF1RX2", "AIF1RX2" }, \
1089 { name, "AIF1RX3", "AIF1RX3" }, \
1090 { name, "AIF1RX4", "AIF1RX4" }, \
1091 { name, "AIF1RX5", "AIF1RX5" }, \
1092 { name, "AIF1RX6", "AIF1RX6" }, \
1093 { name, "EQL", "EQL" }, \
1094 { name, "EQR", "EQR" }, \
1095 { name, "LHPF1", "LHPF1" }, \
1096 { name, "LHPF2", "LHPF2" }
1097
1098#define WM2200_MIXER_ROUTES(widget, name) \
1099 { widget, NULL, name " Mixer" }, \
1100 { name " Mixer", NULL, name " Input 1" }, \
1101 { name " Mixer", NULL, name " Input 2" }, \
1102 { name " Mixer", NULL, name " Input 3" }, \
1103 { name " Mixer", NULL, name " Input 4" }, \
1104 WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
1105 WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
1106 WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
1107 WM2200_MIXER_INPUT_ROUTES(name " Input 4")
1108
1109static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
1110SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
1111 NULL, 0),
1112SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
1113 NULL, 0),
1114SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
1115 NULL, 0),
1116SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
1117 0, NULL, 0),
1118SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
1119 0, NULL, 0),
1120SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
1121SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
1122
1123SND_SOC_DAPM_INPUT("IN1L"),
1124SND_SOC_DAPM_INPUT("IN1R"),
1125SND_SOC_DAPM_INPUT("IN2L"),
1126SND_SOC_DAPM_INPUT("IN2R"),
1127SND_SOC_DAPM_INPUT("IN3L"),
1128SND_SOC_DAPM_INPUT("IN3R"),
1129
1130SND_SOC_DAPM_SIGGEN("TONE"),
1131SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
1132 WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
1133
1134SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
1135 NULL, 0),
1136SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
1137 NULL, 0),
1138SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
1139 NULL, 0),
1140SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
1141 NULL, 0),
1142SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
1143 NULL, 0),
1144SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
1145 NULL, 0),
1146
1147SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
1148 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
1149SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
1150 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
1151SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
1152 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
1153SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
1154 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
1155SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
1156 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
1157SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
1158 WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
1159
1160SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
1161SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
1162
1163SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
1164 NULL, 0),
1165SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
1166 NULL, 0),
1167
1168SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
1169SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0),
1170
1171SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
1172 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
1173SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
1174 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
1175SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
1176 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
1177SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
1178 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
1179SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
1180 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
1181SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
1182 WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
1183
1184SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
1185 WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
1186SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
1187 WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
1188
1189SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1190 WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
1191SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1192 WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
1193SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1194 WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
1195
1196SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1197 WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
1198SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1199 WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
1200SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1201 WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
1202
1203SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1204 WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
1205SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1206 WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
1207SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1208 WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
1209
1210SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1211 WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
1212SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1213 WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
1214SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1215 WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
1216
1217SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
1218 0, NULL, 0),
1219SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
1220 0, NULL, 0),
1221
1222SND_SOC_DAPM_OUTPUT("EPOUTLN"),
1223SND_SOC_DAPM_OUTPUT("EPOUTLP"),
1224SND_SOC_DAPM_OUTPUT("EPOUTRN"),
1225SND_SOC_DAPM_OUTPUT("EPOUTRP"),
1226SND_SOC_DAPM_OUTPUT("SPK"),
1227
1228WM2200_MIXER_WIDGETS(EQL, "EQL"),
1229WM2200_MIXER_WIDGETS(EQR, "EQR"),
1230
1231WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
1232WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
1233
1234WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"),
1235WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"),
1236WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"),
1237WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"),
1238
1239WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1240WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1241WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1242WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1243WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1244WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1245
1246WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
1247WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
1248WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
1249WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
1250};
1251
1252static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
1253 /* Everything needs SYSCLK but only hook up things on the edge
1254 * of the chip */
1255 { "IN1L", NULL, "SYSCLK" },
1256 { "IN1R", NULL, "SYSCLK" },
1257 { "IN2L", NULL, "SYSCLK" },
1258 { "IN2R", NULL, "SYSCLK" },
1259 { "IN3L", NULL, "SYSCLK" },
1260 { "IN3R", NULL, "SYSCLK" },
1261 { "OUT1L", NULL, "SYSCLK" },
1262 { "OUT1R", NULL, "SYSCLK" },
1263 { "OUT2L", NULL, "SYSCLK" },
1264 { "OUT2R", NULL, "SYSCLK" },
1265 { "AIF1RX1", NULL, "SYSCLK" },
1266 { "AIF1RX2", NULL, "SYSCLK" },
1267 { "AIF1RX3", NULL, "SYSCLK" },
1268 { "AIF1RX4", NULL, "SYSCLK" },
1269 { "AIF1RX5", NULL, "SYSCLK" },
1270 { "AIF1RX6", NULL, "SYSCLK" },
1271 { "AIF1TX1", NULL, "SYSCLK" },
1272 { "AIF1TX2", NULL, "SYSCLK" },
1273 { "AIF1TX3", NULL, "SYSCLK" },
1274 { "AIF1TX4", NULL, "SYSCLK" },
1275 { "AIF1TX5", NULL, "SYSCLK" },
1276 { "AIF1TX6", NULL, "SYSCLK" },
1277
1278 { "IN1L", NULL, "AVDD" },
1279 { "IN1R", NULL, "AVDD" },
1280 { "IN2L", NULL, "AVDD" },
1281 { "IN2R", NULL, "AVDD" },
1282 { "IN3L", NULL, "AVDD" },
1283 { "IN3R", NULL, "AVDD" },
1284 { "OUT1L", NULL, "AVDD" },
1285 { "OUT1R", NULL, "AVDD" },
1286
1287 { "IN1L PGA", NULL, "IN1L" },
1288 { "IN1R PGA", NULL, "IN1R" },
1289 { "IN2L PGA", NULL, "IN2L" },
1290 { "IN2R PGA", NULL, "IN2R" },
1291 { "IN3L PGA", NULL, "IN3L" },
1292 { "IN3R PGA", NULL, "IN3R" },
1293
1294 { "Tone Generator", NULL, "TONE" },
1295
1296 { "CP2", NULL, "CPVDD" },
1297 { "MICBIAS1", NULL, "CP2" },
1298 { "MICBIAS2", NULL, "CP2" },
1299
1300 { "CP1", NULL, "CPVDD" },
1301 { "EPD_LN", NULL, "CP1" },
1302 { "EPD_LP", NULL, "CP1" },
1303 { "EPD_RN", NULL, "CP1" },
1304 { "EPD_RP", NULL, "CP1" },
1305
1306 { "EPD_LP", NULL, "OUT1L" },
1307 { "EPD_OUTP_LP", NULL, "EPD_LP" },
1308 { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
1309 { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
1310
1311 { "EPD_LN", NULL, "OUT1L" },
1312 { "EPD_OUTP_LN", NULL, "EPD_LN" },
1313 { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
1314 { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
1315
1316 { "EPD_RP", NULL, "OUT1R" },
1317 { "EPD_OUTP_RP", NULL, "EPD_RP" },
1318 { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
1319 { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
1320
1321 { "EPD_RN", NULL, "OUT1R" },
1322 { "EPD_OUTP_RN", NULL, "EPD_RN" },
1323 { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
1324 { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
1325
1326 { "SPK", NULL, "OUT2L" },
1327 { "SPK", NULL, "OUT2R" },
1328
1329 WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
1330 WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
1331 WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
1332 WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
1333
1334 WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
1335 WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
1336 WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
1337 WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
1338
1339 WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1340 WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1341 WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1342 WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1343 WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1344 WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1345
1346 WM2200_MIXER_ROUTES("EQL", "EQL"),
1347 WM2200_MIXER_ROUTES("EQR", "EQR"),
1348
1349 WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
1350 WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
1351};
1352
1353static int wm2200_probe(struct snd_soc_codec *codec)
1354{
1355 struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
1356 int ret;
1357
1358 wm2200->codec = codec;
1359 codec->control_data = wm2200->regmap;
1360 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1361
1362 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1363 if (ret != 0) {
1364 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1365 return ret;
1366 }
1367
1368 return ret;
1369}
1370
1371static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1372{
1373 struct snd_soc_codec *codec = dai->codec;
1374 int lrclk, bclk, fmt_val;
1375
1376 lrclk = 0;
1377 bclk = 0;
1378
1379 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1380 case SND_SOC_DAIFMT_DSP_A:
1381 fmt_val = 0;
1382 break;
1383 case SND_SOC_DAIFMT_DSP_B:
1384 fmt_val = 1;
1385 break;
1386 case SND_SOC_DAIFMT_I2S:
1387 fmt_val = 2;
1388 break;
1389 case SND_SOC_DAIFMT_LEFT_J:
1390 fmt_val = 3;
1391 break;
1392 default:
1393 dev_err(codec->dev, "Unsupported DAI format %d\n",
1394 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1395 return -EINVAL;
1396 }
1397
1398 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1399 case SND_SOC_DAIFMT_CBS_CFS:
1400 break;
1401 case SND_SOC_DAIFMT_CBS_CFM:
1402 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1403 break;
1404 case SND_SOC_DAIFMT_CBM_CFS:
1405 bclk |= WM2200_AIF1_BCLK_MSTR;
1406 break;
1407 case SND_SOC_DAIFMT_CBM_CFM:
1408 lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1409 bclk |= WM2200_AIF1_BCLK_MSTR;
1410 break;
1411 default:
1412 dev_err(codec->dev, "Unsupported master mode %d\n",
1413 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1414 return -EINVAL;
1415 }
1416
1417 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1418 case SND_SOC_DAIFMT_NB_NF:
1419 break;
1420 case SND_SOC_DAIFMT_IB_IF:
1421 bclk |= WM2200_AIF1_BCLK_INV;
1422 lrclk |= WM2200_AIF1TX_LRCLK_INV;
1423 break;
1424 case SND_SOC_DAIFMT_IB_NF:
1425 bclk |= WM2200_AIF1_BCLK_INV;
1426 break;
1427 case SND_SOC_DAIFMT_NB_IF:
1428 lrclk |= WM2200_AIF1TX_LRCLK_INV;
1429 break;
1430 default:
1431 return -EINVAL;
1432 }
1433
1434 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
1435 WM2200_AIF1_BCLK_INV, bclk);
1436 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1437 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1438 lrclk);
1439 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
1440 WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1441 lrclk);
1442 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
1443 WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
1444
1445 return 0;
1446}
1447
1448static int wm2200_sr_code[] = {
1449 0,
1450 12000,
1451 24000,
1452 48000,
1453 96000,
1454 192000,
1455 384000,
1456 768000,
1457 0,
1458 11025,
1459 22050,
1460 44100,
1461 88200,
1462 176400,
1463 352800,
1464 705600,
1465 4000,
1466 8000,
1467 16000,
1468 32000,
1469 64000,
1470 128000,
1471 256000,
1472 512000,
1473};
1474
1475#define WM2200_NUM_BCLK_RATES 12
1476
1477static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
1478 6144000,
1479 3072000,
1480 2048000,
1481 1536000,
1482 768000,
1483 512000,
1484 384000,
1485 256000,
1486 192000,
1487 128000,
1488 96000,
1489 64000,
1490};
1491
1492static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
1493 5644800,
1494 2882400,
1495 1881600,
1496 1411200,
1497 705600,
1498 470400,
1499 352800,
1500 176400,
1501 117600,
1502 88200,
1503 58800,
1504};
1505
1506static int wm2200_hw_params(struct snd_pcm_substream *substream,
1507 struct snd_pcm_hw_params *params,
1508 struct snd_soc_dai *dai)
1509{
1510 struct snd_soc_codec *codec = dai->codec;
1511 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1512 int i, bclk, lrclk, wl, fl, sr_code;
1513 int *bclk_rates;
1514
1515 /* Data sizes if not using TDM */
1516 wl = snd_pcm_format_width(params_format(params));
1517 if (wl < 0)
1518 return wl;
1519 fl = snd_soc_params_to_frame_size(params);
1520 if (fl < 0)
1521 return fl;
1522
1523 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1524 wl, fl);
1525
1526 /* Target BCLK rate */
1527 bclk = snd_soc_params_to_bclk(params);
1528 if (bclk < 0)
1529 return bclk;
1530
1531 if (!wm2200->sysclk) {
1532 dev_err(codec->dev, "SYSCLK has no rate set\n");
1533 return -EINVAL;
1534 }
1535
1536 for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
1537 if (wm2200_sr_code[i] == params_rate(params))
1538 break;
1539 if (i == ARRAY_SIZE(wm2200_sr_code)) {
1540 dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
1541 params_rate(params));
1542 return -EINVAL;
1543 }
1544 sr_code = i;
1545
1546 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
1547 bclk, wm2200->sysclk);
1548
1549 if (wm2200->sysclk % 4000)
1550 bclk_rates = wm2200_bclk_rates_cd;
1551 else
1552 bclk_rates = wm2200_bclk_rates_dat;
1553
1554 for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
1555 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1556 break;
1557 if (i == WM2200_NUM_BCLK_RATES) {
1558 dev_err(codec->dev,
1559 "No valid BCLK for %dHz found from %dHz SYSCLK\n",
1560 bclk, wm2200->sysclk);
1561 return -EINVAL;
1562 }
1563
1564 bclk = i;
1565 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1566 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
1567 WM2200_AIF1_BCLK_DIV_MASK, bclk);
1568
1569 lrclk = bclk_rates[bclk] / params_rate(params);
1570 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1571 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1572 dai->symmetric_rates)
1573 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
1574 WM2200_AIF1RX_BCPF_MASK, lrclk);
1575 else
1576 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
1577 WM2200_AIF1TX_BCPF_MASK, lrclk);
1578
1579 i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
1580 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1581 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
1582 WM2200_AIF1RX_WL_MASK |
1583 WM2200_AIF1RX_SLOT_LEN_MASK, i);
1584 else
1585 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
1586 WM2200_AIF1TX_WL_MASK |
1587 WM2200_AIF1TX_SLOT_LEN_MASK, i);
1588
1589 snd_soc_update_bits(codec, WM2200_CLOCKING_4,
1590 WM2200_SAMPLE_RATE_1_MASK, sr_code);
1591
1592 return 0;
1593}
1594
1595static const struct snd_soc_dai_ops wm2200_dai_ops = {
1596 .set_fmt = wm2200_set_fmt,
1597 .hw_params = wm2200_hw_params,
1598};
1599
1600static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1601 int source, unsigned int freq, int dir)
1602{
1603 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1604 int fval;
1605
1606 switch (clk_id) {
1607 case WM2200_CLK_SYSCLK:
1608 break;
1609
1610 default:
1611 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1612 return -EINVAL;
1613 }
1614
1615 switch (source) {
1616 case WM2200_CLKSRC_MCLK1:
1617 case WM2200_CLKSRC_MCLK2:
1618 case WM2200_CLKSRC_FLL:
1619 case WM2200_CLKSRC_BCLK1:
1620 break;
1621 default:
1622 dev_err(codec->dev, "Invalid source %d\n", source);
1623 return -EINVAL;
1624 }
1625
1626 switch (freq) {
1627 case 22579200:
1628 case 24576000:
1629 fval = 2;
1630 break;
1631 default:
1632 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1633 return -EINVAL;
1634 }
1635
1636 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1637 * match.
1638 */
1639
1640 snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
1641 WM2200_SYSCLK_SRC_MASK,
1642 fval << WM2200_SYSCLK_FREQ_SHIFT | source);
1643
1644 wm2200->sysclk = freq;
1645
1646 return 0;
1647}
1648
1649struct _fll_div {
1650 u16 fll_fratio;
1651 u16 fll_outdiv;
1652 u16 fll_refclk_div;
1653 u16 n;
1654 u16 theta;
1655 u16 lambda;
1656};
1657
1658static struct {
1659 unsigned int min;
1660 unsigned int max;
1661 u16 fll_fratio;
1662 int ratio;
1663} fll_fratios[] = {
1664 { 0, 64000, 4, 16 },
1665 { 64000, 128000, 3, 8 },
1666 { 128000, 256000, 2, 4 },
1667 { 256000, 1000000, 1, 2 },
1668 { 1000000, 13500000, 0, 1 },
1669};
1670
1671static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1672 unsigned int Fout)
1673{
1674 unsigned int target;
1675 unsigned int div;
1676 unsigned int fratio, gcd_fll;
1677 int i;
1678
1679 /* Fref must be <=13.5MHz */
1680 div = 1;
1681 fll_div->fll_refclk_div = 0;
1682 while ((Fref / div) > 13500000) {
1683 div *= 2;
1684 fll_div->fll_refclk_div++;
1685
1686 if (div > 8) {
1687 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1688 Fref);
1689 return -EINVAL;
1690 }
1691 }
1692
1693 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1694
1695 /* Apply the division for our remaining calculations */
1696 Fref /= div;
1697
1698 /* Fvco should be 90-100MHz; don't check the upper bound */
1699 div = 2;
1700 while (Fout * div < 90000000) {
1701 div++;
1702 if (div > 64) {
1703 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1704 Fout);
1705 return -EINVAL;
1706 }
1707 }
1708 target = Fout * div;
1709 fll_div->fll_outdiv = div - 1;
1710
1711 pr_debug("FLL Fvco=%dHz\n", target);
1712
1713 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1714 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1715 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1716 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1717 fratio = fll_fratios[i].ratio;
1718 break;
1719 }
1720 }
1721 if (i == ARRAY_SIZE(fll_fratios)) {
1722 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1723 return -EINVAL;
1724 }
1725
1726 fll_div->n = target / (fratio * Fref);
1727
1728 if (target % Fref == 0) {
1729 fll_div->theta = 0;
1730 fll_div->lambda = 0;
1731 } else {
1732 gcd_fll = gcd(target, fratio * Fref);
1733
1734 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1735 / gcd_fll;
1736 fll_div->lambda = (fratio * Fref) / gcd_fll;
1737 }
1738
1739 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1740 fll_div->n, fll_div->theta, fll_div->lambda);
1741 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1742 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1743 fll_div->fll_refclk_div);
1744
1745 return 0;
1746}
1747
1748static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1749 unsigned int Fref, unsigned int Fout)
1750{
1751 struct i2c_client *i2c = to_i2c_client(codec->dev);
1752 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1753 struct _fll_div factors;
1754 int ret, i, timeout;
1755
1756 if (!Fout) {
1757 dev_dbg(codec->dev, "FLL disabled");
1758
1759 if (wm2200->fll_fout)
1760 pm_runtime_put(codec->dev);
1761
1762 wm2200->fll_fout = 0;
1763 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1764 WM2200_FLL_ENA, 0);
1765 return 0;
1766 }
1767
1768 switch (source) {
1769 case WM2200_FLL_SRC_MCLK1:
1770 case WM2200_FLL_SRC_MCLK2:
1771 case WM2200_FLL_SRC_BCLK:
1772 break;
1773 default:
1774 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1775 return -EINVAL;
1776 }
1777
1778 ret = fll_factors(&factors, Fref, Fout);
1779 if (ret < 0)
1780 return ret;
1781
1782 /* Disable the FLL while we reconfigure */
1783 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
1784
1785 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
1786 WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
1787 (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
1788 factors.fll_fratio);
1789 if (factors.theta) {
1790 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1791 WM2200_FLL_FRACN_ENA,
1792 WM2200_FLL_FRACN_ENA);
1793 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1794 WM2200_FLL_EFS_ENA,
1795 WM2200_FLL_EFS_ENA);
1796 } else {
1797 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1798 WM2200_FLL_FRACN_ENA, 0);
1799 snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1800 WM2200_FLL_EFS_ENA, 0);
1801 }
1802
1803 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
1804 factors.theta);
1805 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
1806 factors.n);
1807 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
1808 WM2200_FLL_CLK_REF_DIV_MASK |
1809 WM2200_FLL_CLK_REF_SRC_MASK,
1810 (factors.fll_refclk_div
1811 << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
1812 snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
1813 WM2200_FLL_LAMBDA_MASK, factors.lambda);
1814
1815 /* Clear any pending completions */
1816 try_wait_for_completion(&wm2200->fll_lock);
1817
1818 pm_runtime_get_sync(codec->dev);
1819
1820 snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1821 WM2200_FLL_ENA, WM2200_FLL_ENA);
1822
1823 if (i2c->irq)
1824 timeout = 2;
1825 else
1826 timeout = 50;
1827
1828 snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
1829 WM2200_SYSCLK_ENA);
1830
1831 /* Poll for the lock; will use the interrupt to exit quickly */
1832 for (i = 0; i < timeout; i++) {
1833 if (i2c->irq) {
1834 ret = wait_for_completion_timeout(&wm2200->fll_lock,
1835 msecs_to_jiffies(25));
1836 if (ret > 0)
1837 break;
1838 } else {
1839 msleep(1);
1840 }
1841
1842 ret = snd_soc_read(codec,
1843 WM2200_INTERRUPT_RAW_STATUS_2);
1844 if (ret < 0) {
1845 dev_err(codec->dev,
1846 "Failed to read FLL status: %d\n",
1847 ret);
1848 continue;
1849 }
1850 if (ret & WM2200_FLL_LOCK_STS)
1851 break;
1852 }
1853 if (i == timeout) {
1854 dev_err(codec->dev, "FLL lock timed out\n");
1855 pm_runtime_put(codec->dev);
1856 return -ETIMEDOUT;
1857 }
1858
1859 wm2200->fll_src = source;
1860 wm2200->fll_fref = Fref;
1861 wm2200->fll_fout = Fout;
1862
1863 dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
1864
1865 return 0;
1866}
1867
1868static int wm2200_dai_probe(struct snd_soc_dai *dai)
1869{
1870 struct snd_soc_codec *codec = dai->codec;
1871 unsigned int val = 0;
1872 int ret;
1873
1874 ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
1875 if (ret >= 0) {
1876 if ((ret & WM2200_GP1_FN_MASK) != 0) {
1877 dai->symmetric_rates = true;
1878 val = WM2200_AIF1TX_LRCLK_SRC;
1879 }
1880 } else {
1881 dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
1882 }
1883
1884 snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1885 WM2200_AIF1TX_LRCLK_SRC, val);
1886
1887 return 0;
1888}
1889
1890#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
1891
1892#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1893 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1894
1895static struct snd_soc_dai_driver wm2200_dai = {
1896 .name = "wm2200",
1897 .probe = wm2200_dai_probe,
1898 .playback = {
1899 .stream_name = "Playback",
1900 .channels_min = 2,
1901 .channels_max = 2,
1902 .rates = WM2200_RATES,
1903 .formats = WM2200_FORMATS,
1904 },
1905 .capture = {
1906 .stream_name = "Capture",
1907 .channels_min = 2,
1908 .channels_max = 2,
1909 .rates = WM2200_RATES,
1910 .formats = WM2200_FORMATS,
1911 },
1912 .ops = &wm2200_dai_ops,
1913};
1914
1915static struct snd_soc_codec_driver soc_codec_wm2200 = {
1916 .probe = wm2200_probe,
1917
1918 .idle_bias_off = true,
1919 .ignore_pmdown_time = true,
1920 .set_sysclk = wm2200_set_sysclk,
1921 .set_pll = wm2200_set_fll,
1922
1923 .controls = wm2200_snd_controls,
1924 .num_controls = ARRAY_SIZE(wm2200_snd_controls),
1925 .dapm_widgets = wm2200_dapm_widgets,
1926 .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
1927 .dapm_routes = wm2200_dapm_routes,
1928 .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
1929};
1930
1931static irqreturn_t wm2200_irq(int irq, void *data)
1932{
1933 struct wm2200_priv *wm2200 = data;
1934 unsigned int val, mask;
1935 int ret;
1936
1937 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
1938 if (ret != 0) {
1939 dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
1940 return IRQ_NONE;
1941 }
1942
1943 ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
1944 &mask);
1945 if (ret != 0) {
1946 dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
1947 mask = 0;
1948 }
1949
1950 val &= ~mask;
1951
1952 if (val & WM2200_FLL_LOCK_EINT) {
1953 dev_dbg(wm2200->dev, "FLL locked\n");
1954 complete(&wm2200->fll_lock);
1955 }
1956
1957 if (val) {
1958 regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
1959
1960 return IRQ_HANDLED;
1961 } else {
1962 return IRQ_NONE;
1963 }
1964}
1965
1966static const struct regmap_config wm2200_regmap = {
1967 .reg_bits = 16,
1968 .val_bits = 16,
1969
1970 .max_register = WM2200_MAX_REGISTER,
1971 .reg_defaults = wm2200_reg_defaults,
1972 .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
1973 .volatile_reg = wm2200_volatile_register,
1974 .readable_reg = wm2200_readable_register,
1975 .cache_type = REGCACHE_RBTREE,
1976};
1977
1978static const unsigned int wm2200_dig_vu[] = {
1979 WM2200_DAC_DIGITAL_VOLUME_1L,
1980 WM2200_DAC_DIGITAL_VOLUME_1R,
1981 WM2200_DAC_DIGITAL_VOLUME_2L,
1982 WM2200_DAC_DIGITAL_VOLUME_2R,
1983 WM2200_ADC_DIGITAL_VOLUME_1L,
1984 WM2200_ADC_DIGITAL_VOLUME_1R,
1985 WM2200_ADC_DIGITAL_VOLUME_2L,
1986 WM2200_ADC_DIGITAL_VOLUME_2R,
1987 WM2200_ADC_DIGITAL_VOLUME_3L,
1988 WM2200_ADC_DIGITAL_VOLUME_3R,
1989};
1990
1991static const unsigned int wm2200_mic_ctrl_reg[] = {
1992 WM2200_IN1L_CONTROL,
1993 WM2200_IN2L_CONTROL,
1994 WM2200_IN3L_CONTROL,
1995};
1996
1997static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
1998 const struct i2c_device_id *id)
1999{
2000 struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
2001 struct wm2200_priv *wm2200;
2002 unsigned int reg;
2003 int ret, i;
2004
2005 wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2006 GFP_KERNEL);
2007 if (wm2200 == NULL)
2008 return -ENOMEM;
2009
2010 wm2200->dev = &i2c->dev;
2011 init_completion(&wm2200->fll_lock);
2012
2013 wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
2014 if (IS_ERR(wm2200->regmap)) {
2015 ret = PTR_ERR(wm2200->regmap);
2016 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2017 ret);
2018 goto err;
2019 }
2020
2021 if (pdata)
2022 wm2200->pdata = *pdata;
2023
2024 i2c_set_clientdata(i2c, wm2200);
2025
2026 for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
2027 wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
2028
2029 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies),
2030 wm2200->core_supplies);
2031 if (ret != 0) {
2032 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2033 ret);
2034 goto err_regmap;
2035 }
2036
2037 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2038 wm2200->core_supplies);
2039 if (ret != 0) {
2040 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2041 ret);
2042 goto err_core;
2043 }
2044
2045 if (wm2200->pdata.ldo_ena) {
2046 ret = gpio_request_one(wm2200->pdata.ldo_ena,
2047 GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
2048 if (ret < 0) {
2049 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2050 wm2200->pdata.ldo_ena, ret);
2051 goto err_enable;
2052 }
2053 msleep(2);
2054 }
2055
2056 if (wm2200->pdata.reset) {
2057 ret = gpio_request_one(wm2200->pdata.reset,
2058 GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
2059 if (ret < 0) {
2060 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2061 wm2200->pdata.reset, ret);
2062 goto err_ldo;
2063 }
2064 }
2065
2066 ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
2067 if (ret < 0) {
2068 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2069 goto err_reset;
2070 }
2071 switch (reg) {
2072 case 0x2200:
2073 break;
2074
2075 default:
2076 dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
2077 ret = -EINVAL;
2078 goto err_reset;
2079 }
2080
2081 ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
2082 if (ret < 0) {
2083 dev_err(&i2c->dev, "Failed to read revision register\n");
2084 goto err_reset;
2085 }
2086
2087 wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
2088
2089 dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
2090
2091 switch (wm2200->rev) {
2092 case 0:
2093 ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
2094 ARRAY_SIZE(wm2200_reva_patch));
2095 if (ret != 0) {
2096 dev_err(&i2c->dev, "Failed to register patch: %d\n",
2097 ret);
2098 }
2099 break;
2100 default:
2101 break;
2102 }
2103
2104 ret = wm2200_reset(wm2200);
2105 if (ret < 0) {
2106 dev_err(&i2c->dev, "Failed to issue reset\n");
2107 goto err_reset;
2108 }
2109
2110 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
2111 if (!wm2200->pdata.gpio_defaults[i])
2112 continue;
2113
2114 regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
2115 wm2200->pdata.gpio_defaults[i]);
2116 }
2117
2118 for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
2119 regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
2120 WM2200_OUT_VU, WM2200_OUT_VU);
2121
2122 /* Assign slots 1-6 to channels 1-6 for both TX and RX */
2123 for (i = 0; i < 6; i++) {
2124 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
2125 regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2126 }
2127
2128 for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2129 regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2130 WM2200_IN1_MODE_MASK |
2131 WM2200_IN1_DMIC_SUP_MASK,
2132 (wm2200->pdata.in_mode[i] <<
2133 WM2200_IN1_MODE_SHIFT) |
2134 (wm2200->pdata.dmic_sup[i] <<
2135 WM2200_IN1_DMIC_SUP_SHIFT));
2136 }
2137
2138 if (i2c->irq) {
2139 ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
2140 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
2141 "wm2200", wm2200);
2142 if (ret == 0)
2143 regmap_update_bits(wm2200->regmap,
2144 WM2200_INTERRUPT_STATUS_2_MASK,
2145 WM2200_FLL_LOCK_EINT, 0);
2146 else
2147 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2148 i2c->irq, ret);
2149 }
2150
2151 pm_runtime_set_active(&i2c->dev);
2152 pm_runtime_enable(&i2c->dev);
2153 pm_request_idle(&i2c->dev);
2154
2155 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
2156 &wm2200_dai, 1);
2157 if (ret != 0) {
2158 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
2159 goto err_pm_runtime;
2160 }
2161
2162 return 0;
2163
2164err_pm_runtime:
2165 pm_runtime_disable(&i2c->dev);
2166err_reset:
2167 if (wm2200->pdata.reset) {
2168 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2169 gpio_free(wm2200->pdata.reset);
2170 }
2171err_ldo:
2172 if (wm2200->pdata.ldo_ena) {
2173 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2174 gpio_free(wm2200->pdata.ldo_ena);
2175 }
2176err_enable:
2177 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2178 wm2200->core_supplies);
2179err_core:
2180 regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2181 wm2200->core_supplies);
2182err_regmap:
2183 regmap_exit(wm2200->regmap);
2184err:
2185 return ret;
2186}
2187
2188static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
2189{
2190 struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
2191
2192 snd_soc_unregister_codec(&i2c->dev);
2193 if (i2c->irq)
2194 free_irq(i2c->irq, wm2200);
2195 if (wm2200->pdata.reset) {
2196 gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2197 gpio_free(wm2200->pdata.reset);
2198 }
2199 if (wm2200->pdata.ldo_ena) {
2200 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2201 gpio_free(wm2200->pdata.ldo_ena);
2202 }
2203 regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2204 wm2200->core_supplies);
2205 regmap_exit(wm2200->regmap);
2206
2207 return 0;
2208}
2209
2210#ifdef CONFIG_PM_RUNTIME
2211static int wm2200_runtime_suspend(struct device *dev)
2212{
2213 struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2214
2215 regcache_cache_only(wm2200->regmap, true);
2216 regcache_mark_dirty(wm2200->regmap);
2217 if (wm2200->pdata.ldo_ena)
2218 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2219 regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2220 wm2200->core_supplies);
2221
2222 return 0;
2223}
2224
2225static int wm2200_runtime_resume(struct device *dev)
2226{
2227 struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2228 int ret;
2229
2230 ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2231 wm2200->core_supplies);
2232 if (ret != 0) {
2233 dev_err(dev, "Failed to enable supplies: %d\n",
2234 ret);
2235 return ret;
2236 }
2237
2238 if (wm2200->pdata.ldo_ena) {
2239 gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
2240 msleep(2);
2241 }
2242
2243 regcache_cache_only(wm2200->regmap, false);
2244 regcache_sync(wm2200->regmap);
2245
2246 return 0;
2247}
2248#endif
2249
2250static struct dev_pm_ops wm2200_pm = {
2251 SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
2252 NULL)
2253};
2254
2255static const struct i2c_device_id wm2200_i2c_id[] = {
2256 { "wm2200", 0 },
2257 { }
2258};
2259MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
2260
2261static struct i2c_driver wm2200_i2c_driver = {
2262 .driver = {
2263 .name = "wm2200",
2264 .owner = THIS_MODULE,
2265 .pm = &wm2200_pm,
2266 },
2267 .probe = wm2200_i2c_probe,
2268 .remove = __devexit_p(wm2200_i2c_remove),
2269 .id_table = wm2200_i2c_id,
2270};
2271
2272static int __init wm2200_modinit(void)
2273{
2274 return i2c_add_driver(&wm2200_i2c_driver);
2275}
2276module_init(wm2200_modinit);
2277
2278static void __exit wm2200_exit(void)
2279{
2280 i2c_del_driver(&wm2200_i2c_driver);
2281}
2282module_exit(wm2200_exit);
2283
2284MODULE_DESCRIPTION("ASoC WM2200 driver");
2285MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2286MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2200.h b/sound/soc/codecs/wm2200.h
new file mode 100644
index 000000000000..5d719d6b4a8d
--- /dev/null
+++ b/sound/soc/codecs/wm2200.h
@@ -0,0 +1,3674 @@
1/*
2 * wm2200.h - WM2200 audio codec interface
3 *
4 * Copyright 2012 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM2200_H
14#define _WM2200_H
15
16#define WM2200_CLK_SYSCLK 1
17
18#define WM2200_CLKSRC_MCLK1 0
19#define WM2200_CLKSRC_MCLK2 1
20#define WM2200_CLKSRC_FLL 4
21#define WM2200_CLKSRC_BCLK1 8
22
23#define WM2200_FLL_SRC_MCLK1 0
24#define WM2200_FLL_SRC_MCLK2 1
25#define WM2200_FLL_SRC_BCLK 2
26
27/*
28 * Register values.
29 */
30#define WM2200_SOFTWARE_RESET 0x00
31#define WM2200_DEVICE_REVISION 0x01
32#define WM2200_TONE_GENERATOR_1 0x0B
33#define WM2200_CLOCKING_3 0x102
34#define WM2200_CLOCKING_4 0x103
35#define WM2200_FLL_CONTROL_1 0x111
36#define WM2200_FLL_CONTROL_2 0x112
37#define WM2200_FLL_CONTROL_3 0x113
38#define WM2200_FLL_CONTROL_4 0x114
39#define WM2200_FLL_CONTROL_6 0x116
40#define WM2200_FLL_CONTROL_7 0x117
41#define WM2200_FLL_EFS_1 0x119
42#define WM2200_FLL_EFS_2 0x11A
43#define WM2200_MIC_CHARGE_PUMP_1 0x200
44#define WM2200_MIC_CHARGE_PUMP_2 0x201
45#define WM2200_DM_CHARGE_PUMP_1 0x202
46#define WM2200_MIC_BIAS_CTRL_1 0x20C
47#define WM2200_MIC_BIAS_CTRL_2 0x20D
48#define WM2200_EAR_PIECE_CTRL_1 0x20F
49#define WM2200_EAR_PIECE_CTRL_2 0x210
50#define WM2200_INPUT_ENABLES 0x301
51#define WM2200_IN1L_CONTROL 0x302
52#define WM2200_IN1R_CONTROL 0x303
53#define WM2200_IN2L_CONTROL 0x304
54#define WM2200_IN2R_CONTROL 0x305
55#define WM2200_IN3L_CONTROL 0x306
56#define WM2200_IN3R_CONTROL 0x307
57#define WM2200_RXANC_SRC 0x30A
58#define WM2200_INPUT_VOLUME_RAMP 0x30B
59#define WM2200_ADC_DIGITAL_VOLUME_1L 0x30C
60#define WM2200_ADC_DIGITAL_VOLUME_1R 0x30D
61#define WM2200_ADC_DIGITAL_VOLUME_2L 0x30E
62#define WM2200_ADC_DIGITAL_VOLUME_2R 0x30F
63#define WM2200_ADC_DIGITAL_VOLUME_3L 0x310
64#define WM2200_ADC_DIGITAL_VOLUME_3R 0x311
65#define WM2200_OUTPUT_ENABLES 0x400
66#define WM2200_DAC_VOLUME_LIMIT_1L 0x401
67#define WM2200_DAC_VOLUME_LIMIT_1R 0x402
68#define WM2200_DAC_VOLUME_LIMIT_2L 0x403
69#define WM2200_DAC_VOLUME_LIMIT_2R 0x404
70#define WM2200_DAC_AEC_CONTROL_1 0x409
71#define WM2200_OUTPUT_VOLUME_RAMP 0x40A
72#define WM2200_DAC_DIGITAL_VOLUME_1L 0x40B
73#define WM2200_DAC_DIGITAL_VOLUME_1R 0x40C
74#define WM2200_DAC_DIGITAL_VOLUME_2L 0x40D
75#define WM2200_DAC_DIGITAL_VOLUME_2R 0x40E
76#define WM2200_PDM_1 0x417
77#define WM2200_PDM_2 0x418
78#define WM2200_AUDIO_IF_1_1 0x500
79#define WM2200_AUDIO_IF_1_2 0x501
80#define WM2200_AUDIO_IF_1_3 0x502
81#define WM2200_AUDIO_IF_1_4 0x503
82#define WM2200_AUDIO_IF_1_5 0x504
83#define WM2200_AUDIO_IF_1_6 0x505
84#define WM2200_AUDIO_IF_1_7 0x506
85#define WM2200_AUDIO_IF_1_8 0x507
86#define WM2200_AUDIO_IF_1_9 0x508
87#define WM2200_AUDIO_IF_1_10 0x509
88#define WM2200_AUDIO_IF_1_11 0x50A
89#define WM2200_AUDIO_IF_1_12 0x50B
90#define WM2200_AUDIO_IF_1_13 0x50C
91#define WM2200_AUDIO_IF_1_14 0x50D
92#define WM2200_AUDIO_IF_1_15 0x50E
93#define WM2200_AUDIO_IF_1_16 0x50F
94#define WM2200_AUDIO_IF_1_17 0x510
95#define WM2200_AUDIO_IF_1_18 0x511
96#define WM2200_AUDIO_IF_1_19 0x512
97#define WM2200_AUDIO_IF_1_20 0x513
98#define WM2200_AUDIO_IF_1_21 0x514
99#define WM2200_AUDIO_IF_1_22 0x515
100#define WM2200_OUT1LMIX_INPUT_1_SOURCE 0x600
101#define WM2200_OUT1LMIX_INPUT_1_VOLUME 0x601
102#define WM2200_OUT1LMIX_INPUT_2_SOURCE 0x602
103#define WM2200_OUT1LMIX_INPUT_2_VOLUME 0x603
104#define WM2200_OUT1LMIX_INPUT_3_SOURCE 0x604
105#define WM2200_OUT1LMIX_INPUT_3_VOLUME 0x605
106#define WM2200_OUT1LMIX_INPUT_4_SOURCE 0x606
107#define WM2200_OUT1LMIX_INPUT_4_VOLUME 0x607
108#define WM2200_OUT1RMIX_INPUT_1_SOURCE 0x608
109#define WM2200_OUT1RMIX_INPUT_1_VOLUME 0x609
110#define WM2200_OUT1RMIX_INPUT_2_SOURCE 0x60A
111#define WM2200_OUT1RMIX_INPUT_2_VOLUME 0x60B
112#define WM2200_OUT1RMIX_INPUT_3_SOURCE 0x60C
113#define WM2200_OUT1RMIX_INPUT_3_VOLUME 0x60D
114#define WM2200_OUT1RMIX_INPUT_4_SOURCE 0x60E
115#define WM2200_OUT1RMIX_INPUT_4_VOLUME 0x60F
116#define WM2200_OUT2LMIX_INPUT_1_SOURCE 0x610
117#define WM2200_OUT2LMIX_INPUT_1_VOLUME 0x611
118#define WM2200_OUT2LMIX_INPUT_2_SOURCE 0x612
119#define WM2200_OUT2LMIX_INPUT_2_VOLUME 0x613
120#define WM2200_OUT2LMIX_INPUT_3_SOURCE 0x614
121#define WM2200_OUT2LMIX_INPUT_3_VOLUME 0x615
122#define WM2200_OUT2LMIX_INPUT_4_SOURCE 0x616
123#define WM2200_OUT2LMIX_INPUT_4_VOLUME 0x617
124#define WM2200_OUT2RMIX_INPUT_1_SOURCE 0x618
125#define WM2200_OUT2RMIX_INPUT_1_VOLUME 0x619
126#define WM2200_OUT2RMIX_INPUT_2_SOURCE 0x61A
127#define WM2200_OUT2RMIX_INPUT_2_VOLUME 0x61B
128#define WM2200_OUT2RMIX_INPUT_3_SOURCE 0x61C
129#define WM2200_OUT2RMIX_INPUT_3_VOLUME 0x61D
130#define WM2200_OUT2RMIX_INPUT_4_SOURCE 0x61E
131#define WM2200_OUT2RMIX_INPUT_4_VOLUME 0x61F
132#define WM2200_AIF1TX1MIX_INPUT_1_SOURCE 0x620
133#define WM2200_AIF1TX1MIX_INPUT_1_VOLUME 0x621
134#define WM2200_AIF1TX1MIX_INPUT_2_SOURCE 0x622
135#define WM2200_AIF1TX1MIX_INPUT_2_VOLUME 0x623
136#define WM2200_AIF1TX1MIX_INPUT_3_SOURCE 0x624
137#define WM2200_AIF1TX1MIX_INPUT_3_VOLUME 0x625
138#define WM2200_AIF1TX1MIX_INPUT_4_SOURCE 0x626
139#define WM2200_AIF1TX1MIX_INPUT_4_VOLUME 0x627
140#define WM2200_AIF1TX2MIX_INPUT_1_SOURCE 0x628
141#define WM2200_AIF1TX2MIX_INPUT_1_VOLUME 0x629
142#define WM2200_AIF1TX2MIX_INPUT_2_SOURCE 0x62A
143#define WM2200_AIF1TX2MIX_INPUT_2_VOLUME 0x62B
144#define WM2200_AIF1TX2MIX_INPUT_3_SOURCE 0x62C
145#define WM2200_AIF1TX2MIX_INPUT_3_VOLUME 0x62D
146#define WM2200_AIF1TX2MIX_INPUT_4_SOURCE 0x62E
147#define WM2200_AIF1TX2MIX_INPUT_4_VOLUME 0x62F
148#define WM2200_AIF1TX3MIX_INPUT_1_SOURCE 0x630
149#define WM2200_AIF1TX3MIX_INPUT_1_VOLUME 0x631
150#define WM2200_AIF1TX3MIX_INPUT_2_SOURCE 0x632
151#define WM2200_AIF1TX3MIX_INPUT_2_VOLUME 0x633
152#define WM2200_AIF1TX3MIX_INPUT_3_SOURCE 0x634
153#define WM2200_AIF1TX3MIX_INPUT_3_VOLUME 0x635
154#define WM2200_AIF1TX3MIX_INPUT_4_SOURCE 0x636
155#define WM2200_AIF1TX3MIX_INPUT_4_VOLUME 0x637
156#define WM2200_AIF1TX4MIX_INPUT_1_SOURCE 0x638
157#define WM2200_AIF1TX4MIX_INPUT_1_VOLUME 0x639
158#define WM2200_AIF1TX4MIX_INPUT_2_SOURCE 0x63A
159#define WM2200_AIF1TX4MIX_INPUT_2_VOLUME 0x63B
160#define WM2200_AIF1TX4MIX_INPUT_3_SOURCE 0x63C
161#define WM2200_AIF1TX4MIX_INPUT_3_VOLUME 0x63D
162#define WM2200_AIF1TX4MIX_INPUT_4_SOURCE 0x63E
163#define WM2200_AIF1TX4MIX_INPUT_4_VOLUME 0x63F
164#define WM2200_AIF1TX5MIX_INPUT_1_SOURCE 0x640
165#define WM2200_AIF1TX5MIX_INPUT_1_VOLUME 0x641
166#define WM2200_AIF1TX5MIX_INPUT_2_SOURCE 0x642
167#define WM2200_AIF1TX5MIX_INPUT_2_VOLUME 0x643
168#define WM2200_AIF1TX5MIX_INPUT_3_SOURCE 0x644
169#define WM2200_AIF1TX5MIX_INPUT_3_VOLUME 0x645
170#define WM2200_AIF1TX5MIX_INPUT_4_SOURCE 0x646
171#define WM2200_AIF1TX5MIX_INPUT_4_VOLUME 0x647
172#define WM2200_AIF1TX6MIX_INPUT_1_SOURCE 0x648
173#define WM2200_AIF1TX6MIX_INPUT_1_VOLUME 0x649
174#define WM2200_AIF1TX6MIX_INPUT_2_SOURCE 0x64A
175#define WM2200_AIF1TX6MIX_INPUT_2_VOLUME 0x64B
176#define WM2200_AIF1TX6MIX_INPUT_3_SOURCE 0x64C
177#define WM2200_AIF1TX6MIX_INPUT_3_VOLUME 0x64D
178#define WM2200_AIF1TX6MIX_INPUT_4_SOURCE 0x64E
179#define WM2200_AIF1TX6MIX_INPUT_4_VOLUME 0x64F
180#define WM2200_EQLMIX_INPUT_1_SOURCE 0x650
181#define WM2200_EQLMIX_INPUT_1_VOLUME 0x651
182#define WM2200_EQLMIX_INPUT_2_SOURCE 0x652
183#define WM2200_EQLMIX_INPUT_2_VOLUME 0x653
184#define WM2200_EQLMIX_INPUT_3_SOURCE 0x654
185#define WM2200_EQLMIX_INPUT_3_VOLUME 0x655
186#define WM2200_EQLMIX_INPUT_4_SOURCE 0x656
187#define WM2200_EQLMIX_INPUT_4_VOLUME 0x657
188#define WM2200_EQRMIX_INPUT_1_SOURCE 0x658
189#define WM2200_EQRMIX_INPUT_1_VOLUME 0x659
190#define WM2200_EQRMIX_INPUT_2_SOURCE 0x65A
191#define WM2200_EQRMIX_INPUT_2_VOLUME 0x65B
192#define WM2200_EQRMIX_INPUT_3_SOURCE 0x65C
193#define WM2200_EQRMIX_INPUT_3_VOLUME 0x65D
194#define WM2200_EQRMIX_INPUT_4_SOURCE 0x65E
195#define WM2200_EQRMIX_INPUT_4_VOLUME 0x65F
196#define WM2200_LHPF1MIX_INPUT_1_SOURCE 0x660
197#define WM2200_LHPF1MIX_INPUT_1_VOLUME 0x661
198#define WM2200_LHPF1MIX_INPUT_2_SOURCE 0x662
199#define WM2200_LHPF1MIX_INPUT_2_VOLUME 0x663
200#define WM2200_LHPF1MIX_INPUT_3_SOURCE 0x664
201#define WM2200_LHPF1MIX_INPUT_3_VOLUME 0x665
202#define WM2200_LHPF1MIX_INPUT_4_SOURCE 0x666
203#define WM2200_LHPF1MIX_INPUT_4_VOLUME 0x667
204#define WM2200_LHPF2MIX_INPUT_1_SOURCE 0x668
205#define WM2200_LHPF2MIX_INPUT_1_VOLUME 0x669
206#define WM2200_LHPF2MIX_INPUT_2_SOURCE 0x66A
207#define WM2200_LHPF2MIX_INPUT_2_VOLUME 0x66B
208#define WM2200_LHPF2MIX_INPUT_3_SOURCE 0x66C
209#define WM2200_LHPF2MIX_INPUT_3_VOLUME 0x66D
210#define WM2200_LHPF2MIX_INPUT_4_SOURCE 0x66E
211#define WM2200_LHPF2MIX_INPUT_4_VOLUME 0x66F
212#define WM2200_DSP1LMIX_INPUT_1_SOURCE 0x670
213#define WM2200_DSP1LMIX_INPUT_1_VOLUME 0x671
214#define WM2200_DSP1LMIX_INPUT_2_SOURCE 0x672
215#define WM2200_DSP1LMIX_INPUT_2_VOLUME 0x673
216#define WM2200_DSP1LMIX_INPUT_3_SOURCE 0x674
217#define WM2200_DSP1LMIX_INPUT_3_VOLUME 0x675
218#define WM2200_DSP1LMIX_INPUT_4_SOURCE 0x676
219#define WM2200_DSP1LMIX_INPUT_4_VOLUME 0x677
220#define WM2200_DSP1RMIX_INPUT_1_SOURCE 0x678
221#define WM2200_DSP1RMIX_INPUT_1_VOLUME 0x679
222#define WM2200_DSP1RMIX_INPUT_2_SOURCE 0x67A
223#define WM2200_DSP1RMIX_INPUT_2_VOLUME 0x67B
224#define WM2200_DSP1RMIX_INPUT_3_SOURCE 0x67C
225#define WM2200_DSP1RMIX_INPUT_3_VOLUME 0x67D
226#define WM2200_DSP1RMIX_INPUT_4_SOURCE 0x67E
227#define WM2200_DSP1RMIX_INPUT_4_VOLUME 0x67F
228#define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE 0x680
229#define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE 0x681
230#define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE 0x682
231#define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE 0x683
232#define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE 0x684
233#define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE 0x685
234#define WM2200_DSP2LMIX_INPUT_1_SOURCE 0x686
235#define WM2200_DSP2LMIX_INPUT_1_VOLUME 0x687
236#define WM2200_DSP2LMIX_INPUT_2_SOURCE 0x688
237#define WM2200_DSP2LMIX_INPUT_2_VOLUME 0x689
238#define WM2200_DSP2LMIX_INPUT_3_SOURCE 0x68A
239#define WM2200_DSP2LMIX_INPUT_3_VOLUME 0x68B
240#define WM2200_DSP2LMIX_INPUT_4_SOURCE 0x68C
241#define WM2200_DSP2LMIX_INPUT_4_VOLUME 0x68D
242#define WM2200_DSP2RMIX_INPUT_1_SOURCE 0x68E
243#define WM2200_DSP2RMIX_INPUT_1_VOLUME 0x68F
244#define WM2200_DSP2RMIX_INPUT_2_SOURCE 0x690
245#define WM2200_DSP2RMIX_INPUT_2_VOLUME 0x691
246#define WM2200_DSP2RMIX_INPUT_3_SOURCE 0x692
247#define WM2200_DSP2RMIX_INPUT_3_VOLUME 0x693
248#define WM2200_DSP2RMIX_INPUT_4_SOURCE 0x694
249#define WM2200_DSP2RMIX_INPUT_4_VOLUME 0x695
250#define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE 0x696
251#define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE 0x697
252#define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE 0x698
253#define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE 0x699
254#define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE 0x69A
255#define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE 0x69B
256#define WM2200_GPIO_CTRL_1 0x700
257#define WM2200_GPIO_CTRL_2 0x701
258#define WM2200_GPIO_CTRL_3 0x702
259#define WM2200_GPIO_CTRL_4 0x703
260#define WM2200_ADPS1_IRQ0 0x707
261#define WM2200_ADPS1_IRQ1 0x708
262#define WM2200_MISC_PAD_CTRL_1 0x709
263#define WM2200_INTERRUPT_STATUS_1 0x800
264#define WM2200_INTERRUPT_STATUS_1_MASK 0x801
265#define WM2200_INTERRUPT_STATUS_2 0x802
266#define WM2200_INTERRUPT_RAW_STATUS_2 0x803
267#define WM2200_INTERRUPT_STATUS_2_MASK 0x804
268#define WM2200_INTERRUPT_CONTROL 0x808
269#define WM2200_EQL_1 0x900
270#define WM2200_EQL_2 0x901
271#define WM2200_EQL_3 0x902
272#define WM2200_EQL_4 0x903
273#define WM2200_EQL_5 0x904
274#define WM2200_EQL_6 0x905
275#define WM2200_EQL_7 0x906
276#define WM2200_EQL_8 0x907
277#define WM2200_EQL_9 0x908
278#define WM2200_EQL_10 0x909
279#define WM2200_EQL_11 0x90A
280#define WM2200_EQL_12 0x90B
281#define WM2200_EQL_13 0x90C
282#define WM2200_EQL_14 0x90D
283#define WM2200_EQL_15 0x90E
284#define WM2200_EQL_16 0x90F
285#define WM2200_EQL_17 0x910
286#define WM2200_EQL_18 0x911
287#define WM2200_EQL_19 0x912
288#define WM2200_EQL_20 0x913
289#define WM2200_EQR_1 0x916
290#define WM2200_EQR_2 0x917
291#define WM2200_EQR_3 0x918
292#define WM2200_EQR_4 0x919
293#define WM2200_EQR_5 0x91A
294#define WM2200_EQR_6 0x91B
295#define WM2200_EQR_7 0x91C
296#define WM2200_EQR_8 0x91D
297#define WM2200_EQR_9 0x91E
298#define WM2200_EQR_10 0x91F
299#define WM2200_EQR_11 0x920
300#define WM2200_EQR_12 0x921
301#define WM2200_EQR_13 0x922
302#define WM2200_EQR_14 0x923
303#define WM2200_EQR_15 0x924
304#define WM2200_EQR_16 0x925
305#define WM2200_EQR_17 0x926
306#define WM2200_EQR_18 0x927
307#define WM2200_EQR_19 0x928
308#define WM2200_EQR_20 0x929
309#define WM2200_HPLPF1_1 0x93E
310#define WM2200_HPLPF1_2 0x93F
311#define WM2200_HPLPF2_1 0x942
312#define WM2200_HPLPF2_2 0x943
313#define WM2200_DSP1_CONTROL_1 0xA00
314#define WM2200_DSP1_CONTROL_2 0xA02
315#define WM2200_DSP1_CONTROL_3 0xA03
316#define WM2200_DSP1_CONTROL_4 0xA04
317#define WM2200_DSP1_CONTROL_5 0xA06
318#define WM2200_DSP1_CONTROL_6 0xA07
319#define WM2200_DSP1_CONTROL_7 0xA08
320#define WM2200_DSP1_CONTROL_8 0xA09
321#define WM2200_DSP1_CONTROL_9 0xA0A
322#define WM2200_DSP1_CONTROL_10 0xA0B
323#define WM2200_DSP1_CONTROL_11 0xA0C
324#define WM2200_DSP1_CONTROL_12 0xA0D
325#define WM2200_DSP1_CONTROL_13 0xA0F
326#define WM2200_DSP1_CONTROL_14 0xA10
327#define WM2200_DSP1_CONTROL_15 0xA11
328#define WM2200_DSP1_CONTROL_16 0xA12
329#define WM2200_DSP1_CONTROL_17 0xA13
330#define WM2200_DSP1_CONTROL_18 0xA14
331#define WM2200_DSP1_CONTROL_19 0xA16
332#define WM2200_DSP1_CONTROL_20 0xA17
333#define WM2200_DSP1_CONTROL_21 0xA18
334#define WM2200_DSP1_CONTROL_22 0xA1A
335#define WM2200_DSP1_CONTROL_23 0xA1B
336#define WM2200_DSP1_CONTROL_24 0xA1C
337#define WM2200_DSP1_CONTROL_25 0xA1E
338#define WM2200_DSP1_CONTROL_26 0xA20
339#define WM2200_DSP1_CONTROL_27 0xA21
340#define WM2200_DSP1_CONTROL_28 0xA22
341#define WM2200_DSP1_CONTROL_29 0xA23
342#define WM2200_DSP1_CONTROL_30 0xA24
343#define WM2200_DSP1_CONTROL_31 0xA26
344#define WM2200_DSP2_CONTROL_1 0xB00
345#define WM2200_DSP2_CONTROL_2 0xB02
346#define WM2200_DSP2_CONTROL_3 0xB03
347#define WM2200_DSP2_CONTROL_4 0xB04
348#define WM2200_DSP2_CONTROL_5 0xB06
349#define WM2200_DSP2_CONTROL_6 0xB07
350#define WM2200_DSP2_CONTROL_7 0xB08
351#define WM2200_DSP2_CONTROL_8 0xB09
352#define WM2200_DSP2_CONTROL_9 0xB0A
353#define WM2200_DSP2_CONTROL_10 0xB0B
354#define WM2200_DSP2_CONTROL_11 0xB0C
355#define WM2200_DSP2_CONTROL_12 0xB0D
356#define WM2200_DSP2_CONTROL_13 0xB0F
357#define WM2200_DSP2_CONTROL_14 0xB10
358#define WM2200_DSP2_CONTROL_15 0xB11
359#define WM2200_DSP2_CONTROL_16 0xB12
360#define WM2200_DSP2_CONTROL_17 0xB13
361#define WM2200_DSP2_CONTROL_18 0xB14
362#define WM2200_DSP2_CONTROL_19 0xB16
363#define WM2200_DSP2_CONTROL_20 0xB17
364#define WM2200_DSP2_CONTROL_21 0xB18
365#define WM2200_DSP2_CONTROL_22 0xB1A
366#define WM2200_DSP2_CONTROL_23 0xB1B
367#define WM2200_DSP2_CONTROL_24 0xB1C
368#define WM2200_DSP2_CONTROL_25 0xB1E
369#define WM2200_DSP2_CONTROL_26 0xB20
370#define WM2200_DSP2_CONTROL_27 0xB21
371#define WM2200_DSP2_CONTROL_28 0xB22
372#define WM2200_DSP2_CONTROL_29 0xB23
373#define WM2200_DSP2_CONTROL_30 0xB24
374#define WM2200_DSP2_CONTROL_31 0xB26
375#define WM2200_ANC_CTRL1 0xD00
376#define WM2200_ANC_CTRL2 0xD01
377#define WM2200_ANC_CTRL3 0xD02
378#define WM2200_ANC_CTRL7 0xD08
379#define WM2200_ANC_CTRL8 0xD09
380#define WM2200_ANC_CTRL9 0xD0A
381#define WM2200_ANC_CTRL10 0xD0B
382#define WM2200_ANC_CTRL11 0xD0C
383#define WM2200_ANC_CTRL12 0xD0D
384#define WM2200_ANC_CTRL13 0xD0E
385#define WM2200_ANC_CTRL14 0xD0F
386#define WM2200_ANC_CTRL15 0xD10
387#define WM2200_ANC_CTRL16 0xD11
388#define WM2200_ANC_CTRL17 0xD12
389#define WM2200_ANC_CTRL18 0xD15
390#define WM2200_ANC_CTRL19 0xD16
391#define WM2200_ANC_CTRL20 0xD17
392#define WM2200_ANC_CTRL21 0xD18
393#define WM2200_ANC_CTRL22 0xD19
394#define WM2200_ANC_CTRL23 0xD1A
395#define WM2200_ANC_CTRL24 0xD1B
396#define WM2200_ANC_CTRL25 0xD1C
397#define WM2200_ANC_CTRL26 0xD1D
398#define WM2200_ANC_CTRL27 0xD1E
399#define WM2200_ANC_CTRL28 0xD1F
400#define WM2200_ANC_CTRL29 0xD20
401#define WM2200_ANC_CTRL30 0xD21
402#define WM2200_ANC_CTRL31 0xD23
403#define WM2200_ANC_CTRL32 0xD24
404#define WM2200_ANC_CTRL33 0xD25
405#define WM2200_ANC_CTRL34 0xD27
406#define WM2200_ANC_CTRL35 0xD28
407#define WM2200_ANC_CTRL36 0xD29
408#define WM2200_ANC_CTRL37 0xD2A
409#define WM2200_ANC_CTRL38 0xD2B
410#define WM2200_ANC_CTRL39 0xD2C
411#define WM2200_ANC_CTRL40 0xD2D
412#define WM2200_ANC_CTRL41 0xD2E
413#define WM2200_ANC_CTRL42 0xD2F
414#define WM2200_ANC_CTRL43 0xD30
415#define WM2200_ANC_CTRL44 0xD31
416#define WM2200_ANC_CTRL45 0xD32
417#define WM2200_ANC_CTRL46 0xD33
418#define WM2200_ANC_CTRL47 0xD34
419#define WM2200_ANC_CTRL48 0xD35
420#define WM2200_ANC_CTRL49 0xD36
421#define WM2200_ANC_CTRL50 0xD37
422#define WM2200_ANC_CTRL51 0xD38
423#define WM2200_ANC_CTRL52 0xD39
424#define WM2200_ANC_CTRL53 0xD3A
425#define WM2200_ANC_CTRL54 0xD3B
426#define WM2200_ANC_CTRL55 0xD3C
427#define WM2200_ANC_CTRL56 0xD3D
428#define WM2200_ANC_CTRL57 0xD3E
429#define WM2200_ANC_CTRL58 0xD3F
430#define WM2200_ANC_CTRL59 0xD40
431#define WM2200_ANC_CTRL60 0xD41
432#define WM2200_ANC_CTRL61 0xD42
433#define WM2200_ANC_CTRL62 0xD43
434#define WM2200_ANC_CTRL63 0xD44
435#define WM2200_ANC_CTRL64 0xD45
436#define WM2200_ANC_CTRL65 0xD46
437#define WM2200_ANC_CTRL66 0xD47
438#define WM2200_ANC_CTRL67 0xD48
439#define WM2200_ANC_CTRL68 0xD49
440#define WM2200_ANC_CTRL69 0xD4A
441#define WM2200_ANC_CTRL70 0xD4B
442#define WM2200_ANC_CTRL71 0xD4C
443#define WM2200_ANC_CTRL72 0xD4D
444#define WM2200_ANC_CTRL73 0xD4E
445#define WM2200_ANC_CTRL74 0xD4F
446#define WM2200_ANC_CTRL75 0xD50
447#define WM2200_ANC_CTRL76 0xD51
448#define WM2200_ANC_CTRL77 0xD52
449#define WM2200_ANC_CTRL78 0xD53
450#define WM2200_ANC_CTRL79 0xD54
451#define WM2200_ANC_CTRL80 0xD55
452#define WM2200_ANC_CTRL81 0xD56
453#define WM2200_ANC_CTRL82 0xD57
454#define WM2200_ANC_CTRL83 0xD58
455#define WM2200_ANC_CTRL84 0xD5B
456#define WM2200_ANC_CTRL85 0xD5C
457#define WM2200_ANC_CTRL86 0xD5F
458#define WM2200_ANC_CTRL87 0xD60
459#define WM2200_ANC_CTRL88 0xD61
460#define WM2200_ANC_CTRL89 0xD62
461#define WM2200_ANC_CTRL90 0xD63
462#define WM2200_ANC_CTRL91 0xD64
463#define WM2200_ANC_CTRL92 0xD65
464#define WM2200_ANC_CTRL93 0xD66
465#define WM2200_ANC_CTRL94 0xD67
466#define WM2200_ANC_CTRL95 0xD68
467#define WM2200_ANC_CTRL96 0xD69
468#define WM2200_DSP1_DM_0 0x3000
469#define WM2200_DSP1_DM_1 0x3001
470#define WM2200_DSP1_DM_2 0x3002
471#define WM2200_DSP1_DM_3 0x3003
472#define WM2200_DSP1_DM_2044 0x37FC
473#define WM2200_DSP1_DM_2045 0x37FD
474#define WM2200_DSP1_DM_2046 0x37FE
475#define WM2200_DSP1_DM_2047 0x37FF
476#define WM2200_DSP1_PM_0 0x3800
477#define WM2200_DSP1_PM_1 0x3801
478#define WM2200_DSP1_PM_2 0x3802
479#define WM2200_DSP1_PM_3 0x3803
480#define WM2200_DSP1_PM_4 0x3804
481#define WM2200_DSP1_PM_5 0x3805
482#define WM2200_DSP1_PM_762 0x3AFA
483#define WM2200_DSP1_PM_763 0x3AFB
484#define WM2200_DSP1_PM_764 0x3AFC
485#define WM2200_DSP1_PM_765 0x3AFD
486#define WM2200_DSP1_PM_766 0x3AFE
487#define WM2200_DSP1_PM_767 0x3AFF
488#define WM2200_DSP1_ZM_0 0x3C00
489#define WM2200_DSP1_ZM_1 0x3C01
490#define WM2200_DSP1_ZM_2 0x3C02
491#define WM2200_DSP1_ZM_3 0x3C03
492#define WM2200_DSP1_ZM_1020 0x3FFC
493#define WM2200_DSP1_ZM_1021 0x3FFD
494#define WM2200_DSP1_ZM_1022 0x3FFE
495#define WM2200_DSP1_ZM_1023 0x3FFF
496#define WM2200_DSP2_DM_0 0x4000
497#define WM2200_DSP2_DM_1 0x4001
498#define WM2200_DSP2_DM_2 0x4002
499#define WM2200_DSP2_DM_3 0x4003
500#define WM2200_DSP2_DM_2044 0x47FC
501#define WM2200_DSP2_DM_2045 0x47FD
502#define WM2200_DSP2_DM_2046 0x47FE
503#define WM2200_DSP2_DM_2047 0x47FF
504#define WM2200_DSP2_PM_0 0x4800
505#define WM2200_DSP2_PM_1 0x4801
506#define WM2200_DSP2_PM_2 0x4802
507#define WM2200_DSP2_PM_3 0x4803
508#define WM2200_DSP2_PM_4 0x4804
509#define WM2200_DSP2_PM_5 0x4805
510#define WM2200_DSP2_PM_762 0x4AFA
511#define WM2200_DSP2_PM_763 0x4AFB
512#define WM2200_DSP2_PM_764 0x4AFC
513#define WM2200_DSP2_PM_765 0x4AFD
514#define WM2200_DSP2_PM_766 0x4AFE
515#define WM2200_DSP2_PM_767 0x4AFF
516#define WM2200_DSP2_ZM_0 0x4C00
517#define WM2200_DSP2_ZM_1 0x4C01
518#define WM2200_DSP2_ZM_2 0x4C02
519#define WM2200_DSP2_ZM_3 0x4C03
520#define WM2200_DSP2_ZM_1020 0x4FFC
521#define WM2200_DSP2_ZM_1021 0x4FFD
522#define WM2200_DSP2_ZM_1022 0x4FFE
523#define WM2200_DSP2_ZM_1023 0x4FFF
524
525#define WM2200_REGISTER_COUNT 494
526#define WM2200_MAX_REGISTER 0x4FFF
527
528/*
529 * Field Definitions.
530 */
531
532/*
533 * R0 (0x00) - software reset
534 */
535#define WM2200_SW_RESET_CHIP_ID1_MASK 0xFFFF /* SW_RESET_CHIP_ID1 - [15:0] */
536#define WM2200_SW_RESET_CHIP_ID1_SHIFT 0 /* SW_RESET_CHIP_ID1 - [15:0] */
537#define WM2200_SW_RESET_CHIP_ID1_WIDTH 16 /* SW_RESET_CHIP_ID1 - [15:0] */
538
539/*
540 * R1 (0x01) - Device Revision
541 */
542#define WM2200_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */
543#define WM2200_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */
544#define WM2200_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */
545
546/*
547 * R11 (0x0B) - Tone Generator 1
548 */
549#define WM2200_TONE_ENA 0x0001 /* TONE_ENA */
550#define WM2200_TONE_ENA_MASK 0x0001 /* TONE_ENA */
551#define WM2200_TONE_ENA_SHIFT 0 /* TONE_ENA */
552#define WM2200_TONE_ENA_WIDTH 1 /* TONE_ENA */
553
554/*
555 * R258 (0x102) - Clocking 3
556 */
557#define WM2200_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */
558#define WM2200_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */
559#define WM2200_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */
560#define WM2200_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */
561#define WM2200_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */
562#define WM2200_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */
563#define WM2200_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
564#define WM2200_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */
565#define WM2200_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */
566#define WM2200_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */
567
568/*
569 * R259 (0x103) - Clocking 4
570 */
571#define WM2200_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */
572#define WM2200_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */
573#define WM2200_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */
574
575/*
576 * R273 (0x111) - FLL Control 1
577 */
578#define WM2200_FLL_ENA 0x0001 /* FLL_ENA */
579#define WM2200_FLL_ENA_MASK 0x0001 /* FLL_ENA */
580#define WM2200_FLL_ENA_SHIFT 0 /* FLL_ENA */
581#define WM2200_FLL_ENA_WIDTH 1 /* FLL_ENA */
582
583/*
584 * R274 (0x112) - FLL Control 2
585 */
586#define WM2200_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
587#define WM2200_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
588#define WM2200_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
589#define WM2200_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
590#define WM2200_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
591#define WM2200_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
592
593/*
594 * R275 (0x113) - FLL Control 3
595 */
596#define WM2200_FLL_FRACN_ENA 0x0001 /* FLL_FRACN_ENA */
597#define WM2200_FLL_FRACN_ENA_MASK 0x0001 /* FLL_FRACN_ENA */
598#define WM2200_FLL_FRACN_ENA_SHIFT 0 /* FLL_FRACN_ENA */
599#define WM2200_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
600
601/*
602 * R276 (0x114) - FLL Control 4
603 */
604#define WM2200_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
605#define WM2200_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
606#define WM2200_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
607
608/*
609 * R278 (0x116) - FLL Control 6
610 */
611#define WM2200_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
612#define WM2200_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
613#define WM2200_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
614
615/*
616 * R279 (0x117) - FLL Control 7
617 */
618#define WM2200_FLL_CLK_REF_DIV_MASK 0x0030 /* FLL_CLK_REF_DIV - [5:4] */
619#define WM2200_FLL_CLK_REF_DIV_SHIFT 4 /* FLL_CLK_REF_DIV - [5:4] */
620#define WM2200_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [5:4] */
621#define WM2200_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
622#define WM2200_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
623#define WM2200_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
624
625/*
626 * R281 (0x119) - FLL EFS 1
627 */
628#define WM2200_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
629#define WM2200_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
630#define WM2200_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
631
632/*
633 * R282 (0x11A) - FLL EFS 2
634 */
635#define WM2200_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
636#define WM2200_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
637#define WM2200_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
638#define WM2200_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
639
640/*
641 * R512 (0x200) - Mic Charge Pump 1
642 */
643#define WM2200_CPMIC_BYPASS_MODE 0x0020 /* CPMIC_BYPASS_MODE */
644#define WM2200_CPMIC_BYPASS_MODE_MASK 0x0020 /* CPMIC_BYPASS_MODE */
645#define WM2200_CPMIC_BYPASS_MODE_SHIFT 5 /* CPMIC_BYPASS_MODE */
646#define WM2200_CPMIC_BYPASS_MODE_WIDTH 1 /* CPMIC_BYPASS_MODE */
647#define WM2200_CPMIC_ENA 0x0001 /* CPMIC_ENA */
648#define WM2200_CPMIC_ENA_MASK 0x0001 /* CPMIC_ENA */
649#define WM2200_CPMIC_ENA_SHIFT 0 /* CPMIC_ENA */
650#define WM2200_CPMIC_ENA_WIDTH 1 /* CPMIC_ENA */
651
652/*
653 * R513 (0x201) - Mic Charge Pump 2
654 */
655#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK 0xF800 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
656#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT 11 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
657#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH 5 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
658
659/*
660 * R514 (0x202) - DM Charge Pump 1
661 */
662#define WM2200_CPDM_ENA 0x0001 /* CPDM_ENA */
663#define WM2200_CPDM_ENA_MASK 0x0001 /* CPDM_ENA */
664#define WM2200_CPDM_ENA_SHIFT 0 /* CPDM_ENA */
665#define WM2200_CPDM_ENA_WIDTH 1 /* CPDM_ENA */
666
667/*
668 * R524 (0x20C) - Mic Bias Ctrl 1
669 */
670#define WM2200_MICB1_DISCH 0x0040 /* MICB1_DISCH */
671#define WM2200_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */
672#define WM2200_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */
673#define WM2200_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
674#define WM2200_MICB1_RATE 0x0020 /* MICB1_RATE */
675#define WM2200_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
676#define WM2200_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
677#define WM2200_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
678#define WM2200_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */
679#define WM2200_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */
680#define WM2200_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */
681#define WM2200_MICB1_MODE 0x0002 /* MICB1_MODE */
682#define WM2200_MICB1_MODE_MASK 0x0002 /* MICB1_MODE */
683#define WM2200_MICB1_MODE_SHIFT 1 /* MICB1_MODE */
684#define WM2200_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
685#define WM2200_MICB1_ENA 0x0001 /* MICB1_ENA */
686#define WM2200_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */
687#define WM2200_MICB1_ENA_SHIFT 0 /* MICB1_ENA */
688#define WM2200_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
689
690/*
691 * R525 (0x20D) - Mic Bias Ctrl 2
692 */
693#define WM2200_MICB2_DISCH 0x0040 /* MICB2_DISCH */
694#define WM2200_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */
695#define WM2200_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */
696#define WM2200_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
697#define WM2200_MICB2_RATE 0x0020 /* MICB2_RATE */
698#define WM2200_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
699#define WM2200_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
700#define WM2200_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
701#define WM2200_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */
702#define WM2200_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */
703#define WM2200_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */
704#define WM2200_MICB2_MODE 0x0002 /* MICB2_MODE */
705#define WM2200_MICB2_MODE_MASK 0x0002 /* MICB2_MODE */
706#define WM2200_MICB2_MODE_SHIFT 1 /* MICB2_MODE */
707#define WM2200_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
708#define WM2200_MICB2_ENA 0x0001 /* MICB2_ENA */
709#define WM2200_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */
710#define WM2200_MICB2_ENA_SHIFT 0 /* MICB2_ENA */
711#define WM2200_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
712
713/*
714 * R527 (0x20F) - Ear Piece Ctrl 1
715 */
716#define WM2200_EPD_LP_ENA 0x4000 /* EPD_LP_ENA */
717#define WM2200_EPD_LP_ENA_MASK 0x4000 /* EPD_LP_ENA */
718#define WM2200_EPD_LP_ENA_SHIFT 14 /* EPD_LP_ENA */
719#define WM2200_EPD_LP_ENA_WIDTH 1 /* EPD_LP_ENA */
720#define WM2200_EPD_OUTP_LP_ENA 0x2000 /* EPD_OUTP_LP_ENA */
721#define WM2200_EPD_OUTP_LP_ENA_MASK 0x2000 /* EPD_OUTP_LP_ENA */
722#define WM2200_EPD_OUTP_LP_ENA_SHIFT 13 /* EPD_OUTP_LP_ENA */
723#define WM2200_EPD_OUTP_LP_ENA_WIDTH 1 /* EPD_OUTP_LP_ENA */
724#define WM2200_EPD_RMV_SHRT_LP 0x1000 /* EPD_RMV_SHRT_LP */
725#define WM2200_EPD_RMV_SHRT_LP_MASK 0x1000 /* EPD_RMV_SHRT_LP */
726#define WM2200_EPD_RMV_SHRT_LP_SHIFT 12 /* EPD_RMV_SHRT_LP */
727#define WM2200_EPD_RMV_SHRT_LP_WIDTH 1 /* EPD_RMV_SHRT_LP */
728#define WM2200_EPD_LN_ENA 0x0800 /* EPD_LN_ENA */
729#define WM2200_EPD_LN_ENA_MASK 0x0800 /* EPD_LN_ENA */
730#define WM2200_EPD_LN_ENA_SHIFT 11 /* EPD_LN_ENA */
731#define WM2200_EPD_LN_ENA_WIDTH 1 /* EPD_LN_ENA */
732#define WM2200_EPD_OUTP_LN_ENA 0x0400 /* EPD_OUTP_LN_ENA */
733#define WM2200_EPD_OUTP_LN_ENA_MASK 0x0400 /* EPD_OUTP_LN_ENA */
734#define WM2200_EPD_OUTP_LN_ENA_SHIFT 10 /* EPD_OUTP_LN_ENA */
735#define WM2200_EPD_OUTP_LN_ENA_WIDTH 1 /* EPD_OUTP_LN_ENA */
736#define WM2200_EPD_RMV_SHRT_LN 0x0200 /* EPD_RMV_SHRT_LN */
737#define WM2200_EPD_RMV_SHRT_LN_MASK 0x0200 /* EPD_RMV_SHRT_LN */
738#define WM2200_EPD_RMV_SHRT_LN_SHIFT 9 /* EPD_RMV_SHRT_LN */
739#define WM2200_EPD_RMV_SHRT_LN_WIDTH 1 /* EPD_RMV_SHRT_LN */
740
741/*
742 * R528 (0x210) - Ear Piece Ctrl 2
743 */
744#define WM2200_EPD_RP_ENA 0x4000 /* EPD_RP_ENA */
745#define WM2200_EPD_RP_ENA_MASK 0x4000 /* EPD_RP_ENA */
746#define WM2200_EPD_RP_ENA_SHIFT 14 /* EPD_RP_ENA */
747#define WM2200_EPD_RP_ENA_WIDTH 1 /* EPD_RP_ENA */
748#define WM2200_EPD_OUTP_RP_ENA 0x2000 /* EPD_OUTP_RP_ENA */
749#define WM2200_EPD_OUTP_RP_ENA_MASK 0x2000 /* EPD_OUTP_RP_ENA */
750#define WM2200_EPD_OUTP_RP_ENA_SHIFT 13 /* EPD_OUTP_RP_ENA */
751#define WM2200_EPD_OUTP_RP_ENA_WIDTH 1 /* EPD_OUTP_RP_ENA */
752#define WM2200_EPD_RMV_SHRT_RP 0x1000 /* EPD_RMV_SHRT_RP */
753#define WM2200_EPD_RMV_SHRT_RP_MASK 0x1000 /* EPD_RMV_SHRT_RP */
754#define WM2200_EPD_RMV_SHRT_RP_SHIFT 12 /* EPD_RMV_SHRT_RP */
755#define WM2200_EPD_RMV_SHRT_RP_WIDTH 1 /* EPD_RMV_SHRT_RP */
756#define WM2200_EPD_RN_ENA 0x0800 /* EPD_RN_ENA */
757#define WM2200_EPD_RN_ENA_MASK 0x0800 /* EPD_RN_ENA */
758#define WM2200_EPD_RN_ENA_SHIFT 11 /* EPD_RN_ENA */
759#define WM2200_EPD_RN_ENA_WIDTH 1 /* EPD_RN_ENA */
760#define WM2200_EPD_OUTP_RN_ENA 0x0400 /* EPD_OUTP_RN_ENA */
761#define WM2200_EPD_OUTP_RN_ENA_MASK 0x0400 /* EPD_OUTP_RN_ENA */
762#define WM2200_EPD_OUTP_RN_ENA_SHIFT 10 /* EPD_OUTP_RN_ENA */
763#define WM2200_EPD_OUTP_RN_ENA_WIDTH 1 /* EPD_OUTP_RN_ENA */
764#define WM2200_EPD_RMV_SHRT_RN 0x0200 /* EPD_RMV_SHRT_RN */
765#define WM2200_EPD_RMV_SHRT_RN_MASK 0x0200 /* EPD_RMV_SHRT_RN */
766#define WM2200_EPD_RMV_SHRT_RN_SHIFT 9 /* EPD_RMV_SHRT_RN */
767#define WM2200_EPD_RMV_SHRT_RN_WIDTH 1 /* EPD_RMV_SHRT_RN */
768
769/*
770 * R769 (0x301) - Input Enables
771 */
772#define WM2200_IN3L_ENA 0x0020 /* IN3L_ENA */
773#define WM2200_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */
774#define WM2200_IN3L_ENA_SHIFT 5 /* IN3L_ENA */
775#define WM2200_IN3L_ENA_WIDTH 1 /* IN3L_ENA */
776#define WM2200_IN3R_ENA 0x0010 /* IN3R_ENA */
777#define WM2200_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */
778#define WM2200_IN3R_ENA_SHIFT 4 /* IN3R_ENA */
779#define WM2200_IN3R_ENA_WIDTH 1 /* IN3R_ENA */
780#define WM2200_IN2L_ENA 0x0008 /* IN2L_ENA */
781#define WM2200_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */
782#define WM2200_IN2L_ENA_SHIFT 3 /* IN2L_ENA */
783#define WM2200_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
784#define WM2200_IN2R_ENA 0x0004 /* IN2R_ENA */
785#define WM2200_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */
786#define WM2200_IN2R_ENA_SHIFT 2 /* IN2R_ENA */
787#define WM2200_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
788#define WM2200_IN1L_ENA 0x0002 /* IN1L_ENA */
789#define WM2200_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */
790#define WM2200_IN1L_ENA_SHIFT 1 /* IN1L_ENA */
791#define WM2200_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
792#define WM2200_IN1R_ENA 0x0001 /* IN1R_ENA */
793#define WM2200_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */
794#define WM2200_IN1R_ENA_SHIFT 0 /* IN1R_ENA */
795#define WM2200_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
796
797/*
798 * R770 (0x302) - IN1L Control
799 */
800#define WM2200_IN1_OSR 0x2000 /* IN1_OSR */
801#define WM2200_IN1_OSR_MASK 0x2000 /* IN1_OSR */
802#define WM2200_IN1_OSR_SHIFT 13 /* IN1_OSR */
803#define WM2200_IN1_OSR_WIDTH 1 /* IN1_OSR */
804#define WM2200_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
805#define WM2200_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
806#define WM2200_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
807#define WM2200_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */
808#define WM2200_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */
809#define WM2200_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */
810#define WM2200_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
811#define WM2200_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
812#define WM2200_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
813
814/*
815 * R771 (0x303) - IN1R Control
816 */
817#define WM2200_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
818#define WM2200_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
819#define WM2200_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
820
821/*
822 * R772 (0x304) - IN2L Control
823 */
824#define WM2200_IN2_OSR 0x2000 /* IN2_OSR */
825#define WM2200_IN2_OSR_MASK 0x2000 /* IN2_OSR */
826#define WM2200_IN2_OSR_SHIFT 13 /* IN2_OSR */
827#define WM2200_IN2_OSR_WIDTH 1 /* IN2_OSR */
828#define WM2200_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
829#define WM2200_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
830#define WM2200_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
831#define WM2200_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */
832#define WM2200_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */
833#define WM2200_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */
834#define WM2200_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
835#define WM2200_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
836#define WM2200_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
837
838/*
839 * R773 (0x305) - IN2R Control
840 */
841#define WM2200_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
842#define WM2200_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
843#define WM2200_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
844
845/*
846 * R774 (0x306) - IN3L Control
847 */
848#define WM2200_IN3_OSR 0x2000 /* IN3_OSR */
849#define WM2200_IN3_OSR_MASK 0x2000 /* IN3_OSR */
850#define WM2200_IN3_OSR_SHIFT 13 /* IN3_OSR */
851#define WM2200_IN3_OSR_WIDTH 1 /* IN3_OSR */
852#define WM2200_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
853#define WM2200_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
854#define WM2200_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
855#define WM2200_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */
856#define WM2200_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */
857#define WM2200_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */
858#define WM2200_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
859#define WM2200_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
860#define WM2200_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
861
862/*
863 * R775 (0x307) - IN3R Control
864 */
865#define WM2200_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
866#define WM2200_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
867#define WM2200_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
868
869/*
870 * R778 (0x30A) - RXANC_SRC
871 */
872#define WM2200_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */
873#define WM2200_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */
874#define WM2200_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */
875
876/*
877 * R779 (0x30B) - Input Volume Ramp
878 */
879#define WM2200_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */
880#define WM2200_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */
881#define WM2200_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */
882#define WM2200_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */
883#define WM2200_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
884#define WM2200_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
885
886/*
887 * R780 (0x30C) - ADC Digital Volume 1L
888 */
889#define WM2200_IN_VU 0x0200 /* IN_VU */
890#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
891#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
892#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
893#define WM2200_IN1L_MUTE 0x0100 /* IN1L_MUTE */
894#define WM2200_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */
895#define WM2200_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */
896#define WM2200_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
897#define WM2200_IN1L_DIG_VOL_MASK 0x00FF /* IN1L_DIG_VOL - [7:0] */
898#define WM2200_IN1L_DIG_VOL_SHIFT 0 /* IN1L_DIG_VOL - [7:0] */
899#define WM2200_IN1L_DIG_VOL_WIDTH 8 /* IN1L_DIG_VOL - [7:0] */
900
901/*
902 * R781 (0x30D) - ADC Digital Volume 1R
903 */
904#define WM2200_IN_VU 0x0200 /* IN_VU */
905#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
906#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
907#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
908#define WM2200_IN1R_MUTE 0x0100 /* IN1R_MUTE */
909#define WM2200_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */
910#define WM2200_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */
911#define WM2200_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
912#define WM2200_IN1R_DIG_VOL_MASK 0x00FF /* IN1R_DIG_VOL - [7:0] */
913#define WM2200_IN1R_DIG_VOL_SHIFT 0 /* IN1R_DIG_VOL - [7:0] */
914#define WM2200_IN1R_DIG_VOL_WIDTH 8 /* IN1R_DIG_VOL - [7:0] */
915
916/*
917 * R782 (0x30E) - ADC Digital Volume 2L
918 */
919#define WM2200_IN_VU 0x0200 /* IN_VU */
920#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
921#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
922#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
923#define WM2200_IN2L_MUTE 0x0100 /* IN2L_MUTE */
924#define WM2200_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */
925#define WM2200_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */
926#define WM2200_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
927#define WM2200_IN2L_DIG_VOL_MASK 0x00FF /* IN2L_DIG_VOL - [7:0] */
928#define WM2200_IN2L_DIG_VOL_SHIFT 0 /* IN2L_DIG_VOL - [7:0] */
929#define WM2200_IN2L_DIG_VOL_WIDTH 8 /* IN2L_DIG_VOL - [7:0] */
930
931/*
932 * R783 (0x30F) - ADC Digital Volume 2R
933 */
934#define WM2200_IN_VU 0x0200 /* IN_VU */
935#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
936#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
937#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
938#define WM2200_IN2R_MUTE 0x0100 /* IN2R_MUTE */
939#define WM2200_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */
940#define WM2200_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */
941#define WM2200_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
942#define WM2200_IN2R_DIG_VOL_MASK 0x00FF /* IN2R_DIG_VOL - [7:0] */
943#define WM2200_IN2R_DIG_VOL_SHIFT 0 /* IN2R_DIG_VOL - [7:0] */
944#define WM2200_IN2R_DIG_VOL_WIDTH 8 /* IN2R_DIG_VOL - [7:0] */
945
946/*
947 * R784 (0x310) - ADC Digital Volume 3L
948 */
949#define WM2200_IN_VU 0x0200 /* IN_VU */
950#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
951#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
952#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
953#define WM2200_IN3L_MUTE 0x0100 /* IN3L_MUTE */
954#define WM2200_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */
955#define WM2200_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */
956#define WM2200_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */
957#define WM2200_IN3L_DIG_VOL_MASK 0x00FF /* IN3L_DIG_VOL - [7:0] */
958#define WM2200_IN3L_DIG_VOL_SHIFT 0 /* IN3L_DIG_VOL - [7:0] */
959#define WM2200_IN3L_DIG_VOL_WIDTH 8 /* IN3L_DIG_VOL - [7:0] */
960
961/*
962 * R785 (0x311) - ADC Digital Volume 3R
963 */
964#define WM2200_IN_VU 0x0200 /* IN_VU */
965#define WM2200_IN_VU_MASK 0x0200 /* IN_VU */
966#define WM2200_IN_VU_SHIFT 9 /* IN_VU */
967#define WM2200_IN_VU_WIDTH 1 /* IN_VU */
968#define WM2200_IN3R_MUTE 0x0100 /* IN3R_MUTE */
969#define WM2200_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */
970#define WM2200_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */
971#define WM2200_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */
972#define WM2200_IN3R_DIG_VOL_MASK 0x00FF /* IN3R_DIG_VOL - [7:0] */
973#define WM2200_IN3R_DIG_VOL_SHIFT 0 /* IN3R_DIG_VOL - [7:0] */
974#define WM2200_IN3R_DIG_VOL_WIDTH 8 /* IN3R_DIG_VOL - [7:0] */
975
976/*
977 * R1024 (0x400) - Output Enables
978 */
979#define WM2200_OUT2L_ENA 0x0008 /* OUT2L_ENA */
980#define WM2200_OUT2L_ENA_MASK 0x0008 /* OUT2L_ENA */
981#define WM2200_OUT2L_ENA_SHIFT 3 /* OUT2L_ENA */
982#define WM2200_OUT2L_ENA_WIDTH 1 /* OUT2L_ENA */
983#define WM2200_OUT2R_ENA 0x0004 /* OUT2R_ENA */
984#define WM2200_OUT2R_ENA_MASK 0x0004 /* OUT2R_ENA */
985#define WM2200_OUT2R_ENA_SHIFT 2 /* OUT2R_ENA */
986#define WM2200_OUT2R_ENA_WIDTH 1 /* OUT2R_ENA */
987#define WM2200_OUT1L_ENA 0x0002 /* OUT1L_ENA */
988#define WM2200_OUT1L_ENA_MASK 0x0002 /* OUT1L_ENA */
989#define WM2200_OUT1L_ENA_SHIFT 1 /* OUT1L_ENA */
990#define WM2200_OUT1L_ENA_WIDTH 1 /* OUT1L_ENA */
991#define WM2200_OUT1R_ENA 0x0001 /* OUT1R_ENA */
992#define WM2200_OUT1R_ENA_MASK 0x0001 /* OUT1R_ENA */
993#define WM2200_OUT1R_ENA_SHIFT 0 /* OUT1R_ENA */
994#define WM2200_OUT1R_ENA_WIDTH 1 /* OUT1R_ENA */
995
996/*
997 * R1025 (0x401) - DAC Volume Limit 1L
998 */
999#define WM2200_OUT1_OSR 0x2000 /* OUT1_OSR */
1000#define WM2200_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */
1001#define WM2200_OUT1_OSR_SHIFT 13 /* OUT1_OSR */
1002#define WM2200_OUT1_OSR_WIDTH 1 /* OUT1_OSR */
1003#define WM2200_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */
1004#define WM2200_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */
1005#define WM2200_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */
1006#define WM2200_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */
1007#define WM2200_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */
1008#define WM2200_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */
1009#define WM2200_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */
1010
1011/*
1012 * R1026 (0x402) - DAC Volume Limit 1R
1013 */
1014#define WM2200_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */
1015#define WM2200_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */
1016#define WM2200_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */
1017#define WM2200_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */
1018#define WM2200_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */
1019#define WM2200_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */
1020#define WM2200_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */
1021
1022/*
1023 * R1027 (0x403) - DAC Volume Limit 2L
1024 */
1025#define WM2200_OUT2_OSR 0x2000 /* OUT2_OSR */
1026#define WM2200_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */
1027#define WM2200_OUT2_OSR_SHIFT 13 /* OUT2_OSR */
1028#define WM2200_OUT2_OSR_WIDTH 1 /* OUT2_OSR */
1029#define WM2200_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */
1030#define WM2200_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */
1031#define WM2200_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */
1032#define WM2200_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */
1033
1034/*
1035 * R1028 (0x404) - DAC Volume Limit 2R
1036 */
1037#define WM2200_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */
1038#define WM2200_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */
1039#define WM2200_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */
1040#define WM2200_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */
1041
1042/*
1043 * R1033 (0x409) - DAC AEC Control 1
1044 */
1045#define WM2200_AEC_LOOPBACK_ENA 0x0004 /* AEC_LOOPBACK_ENA */
1046#define WM2200_AEC_LOOPBACK_ENA_MASK 0x0004 /* AEC_LOOPBACK_ENA */
1047#define WM2200_AEC_LOOPBACK_ENA_SHIFT 2 /* AEC_LOOPBACK_ENA */
1048#define WM2200_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */
1049#define WM2200_AEC_LOOPBACK_SRC_MASK 0x0003 /* AEC_LOOPBACK_SRC - [1:0] */
1050#define WM2200_AEC_LOOPBACK_SRC_SHIFT 0 /* AEC_LOOPBACK_SRC - [1:0] */
1051#define WM2200_AEC_LOOPBACK_SRC_WIDTH 2 /* AEC_LOOPBACK_SRC - [1:0] */
1052
1053/*
1054 * R1034 (0x40A) - Output Volume Ramp
1055 */
1056#define WM2200_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */
1057#define WM2200_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */
1058#define WM2200_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */
1059#define WM2200_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */
1060#define WM2200_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */
1061#define WM2200_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */
1062
1063/*
1064 * R1035 (0x40B) - DAC Digital Volume 1L
1065 */
1066#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1067#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1068#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1069#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1070#define WM2200_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */
1071#define WM2200_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */
1072#define WM2200_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */
1073#define WM2200_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */
1074#define WM2200_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */
1075#define WM2200_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */
1076#define WM2200_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */
1077
1078/*
1079 * R1036 (0x40C) - DAC Digital Volume 1R
1080 */
1081#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1082#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1083#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1084#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1085#define WM2200_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */
1086#define WM2200_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */
1087#define WM2200_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */
1088#define WM2200_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */
1089#define WM2200_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */
1090#define WM2200_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */
1091#define WM2200_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */
1092
1093/*
1094 * R1037 (0x40D) - DAC Digital Volume 2L
1095 */
1096#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1097#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1098#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1099#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1100#define WM2200_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */
1101#define WM2200_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */
1102#define WM2200_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */
1103#define WM2200_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */
1104#define WM2200_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */
1105#define WM2200_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */
1106#define WM2200_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */
1107
1108/*
1109 * R1038 (0x40E) - DAC Digital Volume 2R
1110 */
1111#define WM2200_OUT_VU 0x0200 /* OUT_VU */
1112#define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */
1113#define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */
1114#define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */
1115#define WM2200_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */
1116#define WM2200_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */
1117#define WM2200_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */
1118#define WM2200_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */
1119#define WM2200_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */
1120#define WM2200_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */
1121#define WM2200_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */
1122
1123/*
1124 * R1047 (0x417) - PDM 1
1125 */
1126#define WM2200_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */
1127#define WM2200_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */
1128#define WM2200_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */
1129#define WM2200_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
1130#define WM2200_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */
1131#define WM2200_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */
1132#define WM2200_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */
1133#define WM2200_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
1134#define WM2200_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */
1135#define WM2200_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */
1136#define WM2200_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */
1137#define WM2200_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */
1138#define WM2200_SPK1_MUTE_SEQL_MASK 0x00FF /* SPK1_MUTE_SEQL - [7:0] */
1139#define WM2200_SPK1_MUTE_SEQL_SHIFT 0 /* SPK1_MUTE_SEQL - [7:0] */
1140#define WM2200_SPK1_MUTE_SEQL_WIDTH 8 /* SPK1_MUTE_SEQL - [7:0] */
1141
1142/*
1143 * R1048 (0x418) - PDM 2
1144 */
1145#define WM2200_SPK1_FMT 0x0001 /* SPK1_FMT */
1146#define WM2200_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */
1147#define WM2200_SPK1_FMT_SHIFT 0 /* SPK1_FMT */
1148#define WM2200_SPK1_FMT_WIDTH 1 /* SPK1_FMT */
1149
1150/*
1151 * R1280 (0x500) - Audio IF 1_1
1152 */
1153#define WM2200_AIF1_BCLK_INV 0x0040 /* AIF1_BCLK_INV */
1154#define WM2200_AIF1_BCLK_INV_MASK 0x0040 /* AIF1_BCLK_INV */
1155#define WM2200_AIF1_BCLK_INV_SHIFT 6 /* AIF1_BCLK_INV */
1156#define WM2200_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1157#define WM2200_AIF1_BCLK_FRC 0x0020 /* AIF1_BCLK_FRC */
1158#define WM2200_AIF1_BCLK_FRC_MASK 0x0020 /* AIF1_BCLK_FRC */
1159#define WM2200_AIF1_BCLK_FRC_SHIFT 5 /* AIF1_BCLK_FRC */
1160#define WM2200_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1161#define WM2200_AIF1_BCLK_MSTR 0x0010 /* AIF1_BCLK_MSTR */
1162#define WM2200_AIF1_BCLK_MSTR_MASK 0x0010 /* AIF1_BCLK_MSTR */
1163#define WM2200_AIF1_BCLK_MSTR_SHIFT 4 /* AIF1_BCLK_MSTR */
1164#define WM2200_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1165#define WM2200_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1166#define WM2200_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1167#define WM2200_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1168
1169/*
1170 * R1281 (0x501) - Audio IF 1_2
1171 */
1172#define WM2200_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */
1173#define WM2200_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */
1174#define WM2200_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */
1175#define WM2200_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1176#define WM2200_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */
1177#define WM2200_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */
1178#define WM2200_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */
1179#define WM2200_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */
1180#define WM2200_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1181#define WM2200_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1182#define WM2200_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1183#define WM2200_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1184#define WM2200_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1185#define WM2200_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1186#define WM2200_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1187#define WM2200_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1188#define WM2200_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1189#define WM2200_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1190#define WM2200_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1191#define WM2200_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1192
1193/*
1194 * R1282 (0x502) - Audio IF 1_3
1195 */
1196#define WM2200_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1197#define WM2200_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1198#define WM2200_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1199#define WM2200_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1200#define WM2200_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1201#define WM2200_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1202#define WM2200_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1203#define WM2200_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1204#define WM2200_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1205#define WM2200_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1206#define WM2200_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1207#define WM2200_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1208
1209/*
1210 * R1283 (0x503) - Audio IF 1_4
1211 */
1212#define WM2200_AIF1_TRI 0x0040 /* AIF1_TRI */
1213#define WM2200_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */
1214#define WM2200_AIF1_TRI_SHIFT 6 /* AIF1_TRI */
1215#define WM2200_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1216
1217/*
1218 * R1284 (0x504) - Audio IF 1_5
1219 */
1220#define WM2200_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */
1221#define WM2200_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */
1222#define WM2200_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */
1223
1224/*
1225 * R1285 (0x505) - Audio IF 1_6
1226 */
1227#define WM2200_AIF1TX_BCPF_MASK 0x07FF /* AIF1TX_BCPF - [10:0] */
1228#define WM2200_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [10:0] */
1229#define WM2200_AIF1TX_BCPF_WIDTH 11 /* AIF1TX_BCPF - [10:0] */
1230
1231/*
1232 * R1286 (0x506) - Audio IF 1_7
1233 */
1234#define WM2200_AIF1RX_BCPF_MASK 0x07FF /* AIF1RX_BCPF - [10:0] */
1235#define WM2200_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [10:0] */
1236#define WM2200_AIF1RX_BCPF_WIDTH 11 /* AIF1RX_BCPF - [10:0] */
1237
1238/*
1239 * R1287 (0x507) - Audio IF 1_8
1240 */
1241#define WM2200_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */
1242#define WM2200_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */
1243#define WM2200_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */
1244#define WM2200_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1245#define WM2200_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1246#define WM2200_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1247
1248/*
1249 * R1288 (0x508) - Audio IF 1_9
1250 */
1251#define WM2200_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */
1252#define WM2200_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */
1253#define WM2200_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */
1254#define WM2200_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1255#define WM2200_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1256#define WM2200_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1257
1258/*
1259 * R1289 (0x509) - Audio IF 1_10
1260 */
1261#define WM2200_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */
1262#define WM2200_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */
1263#define WM2200_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */
1264
1265/*
1266 * R1290 (0x50A) - Audio IF 1_11
1267 */
1268#define WM2200_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */
1269#define WM2200_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */
1270#define WM2200_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */
1271
1272/*
1273 * R1291 (0x50B) - Audio IF 1_12
1274 */
1275#define WM2200_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */
1276#define WM2200_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */
1277#define WM2200_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */
1278
1279/*
1280 * R1292 (0x50C) - Audio IF 1_13
1281 */
1282#define WM2200_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */
1283#define WM2200_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */
1284#define WM2200_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */
1285
1286/*
1287 * R1293 (0x50D) - Audio IF 1_14
1288 */
1289#define WM2200_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */
1290#define WM2200_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */
1291#define WM2200_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */
1292
1293/*
1294 * R1294 (0x50E) - Audio IF 1_15
1295 */
1296#define WM2200_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */
1297#define WM2200_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */
1298#define WM2200_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */
1299
1300/*
1301 * R1295 (0x50F) - Audio IF 1_16
1302 */
1303#define WM2200_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */
1304#define WM2200_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */
1305#define WM2200_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */
1306
1307/*
1308 * R1296 (0x510) - Audio IF 1_17
1309 */
1310#define WM2200_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */
1311#define WM2200_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */
1312#define WM2200_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */
1313
1314/*
1315 * R1297 (0x511) - Audio IF 1_18
1316 */
1317#define WM2200_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */
1318#define WM2200_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */
1319#define WM2200_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */
1320
1321/*
1322 * R1298 (0x512) - Audio IF 1_19
1323 */
1324#define WM2200_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */
1325#define WM2200_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */
1326#define WM2200_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */
1327
1328/*
1329 * R1299 (0x513) - Audio IF 1_20
1330 */
1331#define WM2200_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */
1332#define WM2200_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */
1333#define WM2200_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */
1334
1335/*
1336 * R1300 (0x514) - Audio IF 1_21
1337 */
1338#define WM2200_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */
1339#define WM2200_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */
1340#define WM2200_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */
1341
1342/*
1343 * R1301 (0x515) - Audio IF 1_22
1344 */
1345#define WM2200_AIF1RX6_ENA 0x0800 /* AIF1RX6_ENA */
1346#define WM2200_AIF1RX6_ENA_MASK 0x0800 /* AIF1RX6_ENA */
1347#define WM2200_AIF1RX6_ENA_SHIFT 11 /* AIF1RX6_ENA */
1348#define WM2200_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */
1349#define WM2200_AIF1RX5_ENA 0x0400 /* AIF1RX5_ENA */
1350#define WM2200_AIF1RX5_ENA_MASK 0x0400 /* AIF1RX5_ENA */
1351#define WM2200_AIF1RX5_ENA_SHIFT 10 /* AIF1RX5_ENA */
1352#define WM2200_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */
1353#define WM2200_AIF1RX4_ENA 0x0200 /* AIF1RX4_ENA */
1354#define WM2200_AIF1RX4_ENA_MASK 0x0200 /* AIF1RX4_ENA */
1355#define WM2200_AIF1RX4_ENA_SHIFT 9 /* AIF1RX4_ENA */
1356#define WM2200_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */
1357#define WM2200_AIF1RX3_ENA 0x0100 /* AIF1RX3_ENA */
1358#define WM2200_AIF1RX3_ENA_MASK 0x0100 /* AIF1RX3_ENA */
1359#define WM2200_AIF1RX3_ENA_SHIFT 8 /* AIF1RX3_ENA */
1360#define WM2200_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */
1361#define WM2200_AIF1RX2_ENA 0x0080 /* AIF1RX2_ENA */
1362#define WM2200_AIF1RX2_ENA_MASK 0x0080 /* AIF1RX2_ENA */
1363#define WM2200_AIF1RX2_ENA_SHIFT 7 /* AIF1RX2_ENA */
1364#define WM2200_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */
1365#define WM2200_AIF1RX1_ENA 0x0040 /* AIF1RX1_ENA */
1366#define WM2200_AIF1RX1_ENA_MASK 0x0040 /* AIF1RX1_ENA */
1367#define WM2200_AIF1RX1_ENA_SHIFT 6 /* AIF1RX1_ENA */
1368#define WM2200_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */
1369#define WM2200_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */
1370#define WM2200_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */
1371#define WM2200_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */
1372#define WM2200_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */
1373#define WM2200_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */
1374#define WM2200_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */
1375#define WM2200_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */
1376#define WM2200_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */
1377#define WM2200_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */
1378#define WM2200_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */
1379#define WM2200_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */
1380#define WM2200_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */
1381#define WM2200_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */
1382#define WM2200_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */
1383#define WM2200_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */
1384#define WM2200_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */
1385#define WM2200_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */
1386#define WM2200_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */
1387#define WM2200_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */
1388#define WM2200_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */
1389#define WM2200_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */
1390#define WM2200_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */
1391#define WM2200_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */
1392#define WM2200_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */
1393
1394/*
1395 * R1536 (0x600) - OUT1LMIX Input 1 Source
1396 */
1397#define WM2200_OUT1LMIX_SRC1_MASK 0x007F /* OUT1LMIX_SRC1 - [6:0] */
1398#define WM2200_OUT1LMIX_SRC1_SHIFT 0 /* OUT1LMIX_SRC1 - [6:0] */
1399#define WM2200_OUT1LMIX_SRC1_WIDTH 7 /* OUT1LMIX_SRC1 - [6:0] */
1400
1401/*
1402 * R1537 (0x601) - OUT1LMIX Input 1 Volume
1403 */
1404#define WM2200_OUT1LMIX_VOL1_MASK 0x00FE /* OUT1LMIX_VOL1 - [7:1] */
1405#define WM2200_OUT1LMIX_VOL1_SHIFT 1 /* OUT1LMIX_VOL1 - [7:1] */
1406#define WM2200_OUT1LMIX_VOL1_WIDTH 7 /* OUT1LMIX_VOL1 - [7:1] */
1407
1408/*
1409 * R1538 (0x602) - OUT1LMIX Input 2 Source
1410 */
1411#define WM2200_OUT1LMIX_SRC2_MASK 0x007F /* OUT1LMIX_SRC2 - [6:0] */
1412#define WM2200_OUT1LMIX_SRC2_SHIFT 0 /* OUT1LMIX_SRC2 - [6:0] */
1413#define WM2200_OUT1LMIX_SRC2_WIDTH 7 /* OUT1LMIX_SRC2 - [6:0] */
1414
1415/*
1416 * R1539 (0x603) - OUT1LMIX Input 2 Volume
1417 */
1418#define WM2200_OUT1LMIX_VOL2_MASK 0x00FE /* OUT1LMIX_VOL2 - [7:1] */
1419#define WM2200_OUT1LMIX_VOL2_SHIFT 1 /* OUT1LMIX_VOL2 - [7:1] */
1420#define WM2200_OUT1LMIX_VOL2_WIDTH 7 /* OUT1LMIX_VOL2 - [7:1] */
1421
1422/*
1423 * R1540 (0x604) - OUT1LMIX Input 3 Source
1424 */
1425#define WM2200_OUT1LMIX_SRC3_MASK 0x007F /* OUT1LMIX_SRC3 - [6:0] */
1426#define WM2200_OUT1LMIX_SRC3_SHIFT 0 /* OUT1LMIX_SRC3 - [6:0] */
1427#define WM2200_OUT1LMIX_SRC3_WIDTH 7 /* OUT1LMIX_SRC3 - [6:0] */
1428
1429/*
1430 * R1541 (0x605) - OUT1LMIX Input 3 Volume
1431 */
1432#define WM2200_OUT1LMIX_VOL3_MASK 0x00FE /* OUT1LMIX_VOL3 - [7:1] */
1433#define WM2200_OUT1LMIX_VOL3_SHIFT 1 /* OUT1LMIX_VOL3 - [7:1] */
1434#define WM2200_OUT1LMIX_VOL3_WIDTH 7 /* OUT1LMIX_VOL3 - [7:1] */
1435
1436/*
1437 * R1542 (0x606) - OUT1LMIX Input 4 Source
1438 */
1439#define WM2200_OUT1LMIX_SRC4_MASK 0x007F /* OUT1LMIX_SRC4 - [6:0] */
1440#define WM2200_OUT1LMIX_SRC4_SHIFT 0 /* OUT1LMIX_SRC4 - [6:0] */
1441#define WM2200_OUT1LMIX_SRC4_WIDTH 7 /* OUT1LMIX_SRC4 - [6:0] */
1442
1443/*
1444 * R1543 (0x607) - OUT1LMIX Input 4 Volume
1445 */
1446#define WM2200_OUT1LMIX_VOL4_MASK 0x00FE /* OUT1LMIX_VOL4 - [7:1] */
1447#define WM2200_OUT1LMIX_VOL4_SHIFT 1 /* OUT1LMIX_VOL4 - [7:1] */
1448#define WM2200_OUT1LMIX_VOL4_WIDTH 7 /* OUT1LMIX_VOL4 - [7:1] */
1449
1450/*
1451 * R1544 (0x608) - OUT1RMIX Input 1 Source
1452 */
1453#define WM2200_OUT1RMIX_SRC1_MASK 0x007F /* OUT1RMIX_SRC1 - [6:0] */
1454#define WM2200_OUT1RMIX_SRC1_SHIFT 0 /* OUT1RMIX_SRC1 - [6:0] */
1455#define WM2200_OUT1RMIX_SRC1_WIDTH 7 /* OUT1RMIX_SRC1 - [6:0] */
1456
1457/*
1458 * R1545 (0x609) - OUT1RMIX Input 1 Volume
1459 */
1460#define WM2200_OUT1RMIX_VOL1_MASK 0x00FE /* OUT1RMIX_VOL1 - [7:1] */
1461#define WM2200_OUT1RMIX_VOL1_SHIFT 1 /* OUT1RMIX_VOL1 - [7:1] */
1462#define WM2200_OUT1RMIX_VOL1_WIDTH 7 /* OUT1RMIX_VOL1 - [7:1] */
1463
1464/*
1465 * R1546 (0x60A) - OUT1RMIX Input 2 Source
1466 */
1467#define WM2200_OUT1RMIX_SRC2_MASK 0x007F /* OUT1RMIX_SRC2 - [6:0] */
1468#define WM2200_OUT1RMIX_SRC2_SHIFT 0 /* OUT1RMIX_SRC2 - [6:0] */
1469#define WM2200_OUT1RMIX_SRC2_WIDTH 7 /* OUT1RMIX_SRC2 - [6:0] */
1470
1471/*
1472 * R1547 (0x60B) - OUT1RMIX Input 2 Volume
1473 */
1474#define WM2200_OUT1RMIX_VOL2_MASK 0x00FE /* OUT1RMIX_VOL2 - [7:1] */
1475#define WM2200_OUT1RMIX_VOL2_SHIFT 1 /* OUT1RMIX_VOL2 - [7:1] */
1476#define WM2200_OUT1RMIX_VOL2_WIDTH 7 /* OUT1RMIX_VOL2 - [7:1] */
1477
1478/*
1479 * R1548 (0x60C) - OUT1RMIX Input 3 Source
1480 */
1481#define WM2200_OUT1RMIX_SRC3_MASK 0x007F /* OUT1RMIX_SRC3 - [6:0] */
1482#define WM2200_OUT1RMIX_SRC3_SHIFT 0 /* OUT1RMIX_SRC3 - [6:0] */
1483#define WM2200_OUT1RMIX_SRC3_WIDTH 7 /* OUT1RMIX_SRC3 - [6:0] */
1484
1485/*
1486 * R1549 (0x60D) - OUT1RMIX Input 3 Volume
1487 */
1488#define WM2200_OUT1RMIX_VOL3_MASK 0x00FE /* OUT1RMIX_VOL3 - [7:1] */
1489#define WM2200_OUT1RMIX_VOL3_SHIFT 1 /* OUT1RMIX_VOL3 - [7:1] */
1490#define WM2200_OUT1RMIX_VOL3_WIDTH 7 /* OUT1RMIX_VOL3 - [7:1] */
1491
1492/*
1493 * R1550 (0x60E) - OUT1RMIX Input 4 Source
1494 */
1495#define WM2200_OUT1RMIX_SRC4_MASK 0x007F /* OUT1RMIX_SRC4 - [6:0] */
1496#define WM2200_OUT1RMIX_SRC4_SHIFT 0 /* OUT1RMIX_SRC4 - [6:0] */
1497#define WM2200_OUT1RMIX_SRC4_WIDTH 7 /* OUT1RMIX_SRC4 - [6:0] */
1498
1499/*
1500 * R1551 (0x60F) - OUT1RMIX Input 4 Volume
1501 */
1502#define WM2200_OUT1RMIX_VOL4_MASK 0x00FE /* OUT1RMIX_VOL4 - [7:1] */
1503#define WM2200_OUT1RMIX_VOL4_SHIFT 1 /* OUT1RMIX_VOL4 - [7:1] */
1504#define WM2200_OUT1RMIX_VOL4_WIDTH 7 /* OUT1RMIX_VOL4 - [7:1] */
1505
1506/*
1507 * R1552 (0x610) - OUT2LMIX Input 1 Source
1508 */
1509#define WM2200_OUT2LMIX_SRC1_MASK 0x007F /* OUT2LMIX_SRC1 - [6:0] */
1510#define WM2200_OUT2LMIX_SRC1_SHIFT 0 /* OUT2LMIX_SRC1 - [6:0] */
1511#define WM2200_OUT2LMIX_SRC1_WIDTH 7 /* OUT2LMIX_SRC1 - [6:0] */
1512
1513/*
1514 * R1553 (0x611) - OUT2LMIX Input 1 Volume
1515 */
1516#define WM2200_OUT2LMIX_VOL1_MASK 0x00FE /* OUT2LMIX_VOL1 - [7:1] */
1517#define WM2200_OUT2LMIX_VOL1_SHIFT 1 /* OUT2LMIX_VOL1 - [7:1] */
1518#define WM2200_OUT2LMIX_VOL1_WIDTH 7 /* OUT2LMIX_VOL1 - [7:1] */
1519
1520/*
1521 * R1554 (0x612) - OUT2LMIX Input 2 Source
1522 */
1523#define WM2200_OUT2LMIX_SRC2_MASK 0x007F /* OUT2LMIX_SRC2 - [6:0] */
1524#define WM2200_OUT2LMIX_SRC2_SHIFT 0 /* OUT2LMIX_SRC2 - [6:0] */
1525#define WM2200_OUT2LMIX_SRC2_WIDTH 7 /* OUT2LMIX_SRC2 - [6:0] */
1526
1527/*
1528 * R1555 (0x613) - OUT2LMIX Input 2 Volume
1529 */
1530#define WM2200_OUT2LMIX_VOL2_MASK 0x00FE /* OUT2LMIX_VOL2 - [7:1] */
1531#define WM2200_OUT2LMIX_VOL2_SHIFT 1 /* OUT2LMIX_VOL2 - [7:1] */
1532#define WM2200_OUT2LMIX_VOL2_WIDTH 7 /* OUT2LMIX_VOL2 - [7:1] */
1533
1534/*
1535 * R1556 (0x614) - OUT2LMIX Input 3 Source
1536 */
1537#define WM2200_OUT2LMIX_SRC3_MASK 0x007F /* OUT2LMIX_SRC3 - [6:0] */
1538#define WM2200_OUT2LMIX_SRC3_SHIFT 0 /* OUT2LMIX_SRC3 - [6:0] */
1539#define WM2200_OUT2LMIX_SRC3_WIDTH 7 /* OUT2LMIX_SRC3 - [6:0] */
1540
1541/*
1542 * R1557 (0x615) - OUT2LMIX Input 3 Volume
1543 */
1544#define WM2200_OUT2LMIX_VOL3_MASK 0x00FE /* OUT2LMIX_VOL3 - [7:1] */
1545#define WM2200_OUT2LMIX_VOL3_SHIFT 1 /* OUT2LMIX_VOL3 - [7:1] */
1546#define WM2200_OUT2LMIX_VOL3_WIDTH 7 /* OUT2LMIX_VOL3 - [7:1] */
1547
1548/*
1549 * R1558 (0x616) - OUT2LMIX Input 4 Source
1550 */
1551#define WM2200_OUT2LMIX_SRC4_MASK 0x007F /* OUT2LMIX_SRC4 - [6:0] */
1552#define WM2200_OUT2LMIX_SRC4_SHIFT 0 /* OUT2LMIX_SRC4 - [6:0] */
1553#define WM2200_OUT2LMIX_SRC4_WIDTH 7 /* OUT2LMIX_SRC4 - [6:0] */
1554
1555/*
1556 * R1559 (0x617) - OUT2LMIX Input 4 Volume
1557 */
1558#define WM2200_OUT2LMIX_VOL4_MASK 0x00FE /* OUT2LMIX_VOL4 - [7:1] */
1559#define WM2200_OUT2LMIX_VOL4_SHIFT 1 /* OUT2LMIX_VOL4 - [7:1] */
1560#define WM2200_OUT2LMIX_VOL4_WIDTH 7 /* OUT2LMIX_VOL4 - [7:1] */
1561
1562/*
1563 * R1560 (0x618) - OUT2RMIX Input 1 Source
1564 */
1565#define WM2200_OUT2RMIX_SRC1_MASK 0x007F /* OUT2RMIX_SRC1 - [6:0] */
1566#define WM2200_OUT2RMIX_SRC1_SHIFT 0 /* OUT2RMIX_SRC1 - [6:0] */
1567#define WM2200_OUT2RMIX_SRC1_WIDTH 7 /* OUT2RMIX_SRC1 - [6:0] */
1568
1569/*
1570 * R1561 (0x619) - OUT2RMIX Input 1 Volume
1571 */
1572#define WM2200_OUT2RMIX_VOL1_MASK 0x00FE /* OUT2RMIX_VOL1 - [7:1] */
1573#define WM2200_OUT2RMIX_VOL1_SHIFT 1 /* OUT2RMIX_VOL1 - [7:1] */
1574#define WM2200_OUT2RMIX_VOL1_WIDTH 7 /* OUT2RMIX_VOL1 - [7:1] */
1575
1576/*
1577 * R1562 (0x61A) - OUT2RMIX Input 2 Source
1578 */
1579#define WM2200_OUT2RMIX_SRC2_MASK 0x007F /* OUT2RMIX_SRC2 - [6:0] */
1580#define WM2200_OUT2RMIX_SRC2_SHIFT 0 /* OUT2RMIX_SRC2 - [6:0] */
1581#define WM2200_OUT2RMIX_SRC2_WIDTH 7 /* OUT2RMIX_SRC2 - [6:0] */
1582
1583/*
1584 * R1563 (0x61B) - OUT2RMIX Input 2 Volume
1585 */
1586#define WM2200_OUT2RMIX_VOL2_MASK 0x00FE /* OUT2RMIX_VOL2 - [7:1] */
1587#define WM2200_OUT2RMIX_VOL2_SHIFT 1 /* OUT2RMIX_VOL2 - [7:1] */
1588#define WM2200_OUT2RMIX_VOL2_WIDTH 7 /* OUT2RMIX_VOL2 - [7:1] */
1589
1590/*
1591 * R1564 (0x61C) - OUT2RMIX Input 3 Source
1592 */
1593#define WM2200_OUT2RMIX_SRC3_MASK 0x007F /* OUT2RMIX_SRC3 - [6:0] */
1594#define WM2200_OUT2RMIX_SRC3_SHIFT 0 /* OUT2RMIX_SRC3 - [6:0] */
1595#define WM2200_OUT2RMIX_SRC3_WIDTH 7 /* OUT2RMIX_SRC3 - [6:0] */
1596
1597/*
1598 * R1565 (0x61D) - OUT2RMIX Input 3 Volume
1599 */
1600#define WM2200_OUT2RMIX_VOL3_MASK 0x00FE /* OUT2RMIX_VOL3 - [7:1] */
1601#define WM2200_OUT2RMIX_VOL3_SHIFT 1 /* OUT2RMIX_VOL3 - [7:1] */
1602#define WM2200_OUT2RMIX_VOL3_WIDTH 7 /* OUT2RMIX_VOL3 - [7:1] */
1603
1604/*
1605 * R1566 (0x61E) - OUT2RMIX Input 4 Source
1606 */
1607#define WM2200_OUT2RMIX_SRC4_MASK 0x007F /* OUT2RMIX_SRC4 - [6:0] */
1608#define WM2200_OUT2RMIX_SRC4_SHIFT 0 /* OUT2RMIX_SRC4 - [6:0] */
1609#define WM2200_OUT2RMIX_SRC4_WIDTH 7 /* OUT2RMIX_SRC4 - [6:0] */
1610
1611/*
1612 * R1567 (0x61F) - OUT2RMIX Input 4 Volume
1613 */
1614#define WM2200_OUT2RMIX_VOL4_MASK 0x00FE /* OUT2RMIX_VOL4 - [7:1] */
1615#define WM2200_OUT2RMIX_VOL4_SHIFT 1 /* OUT2RMIX_VOL4 - [7:1] */
1616#define WM2200_OUT2RMIX_VOL4_WIDTH 7 /* OUT2RMIX_VOL4 - [7:1] */
1617
1618/*
1619 * R1568 (0x620) - AIF1TX1MIX Input 1 Source
1620 */
1621#define WM2200_AIF1TX1MIX_SRC1_MASK 0x007F /* AIF1TX1MIX_SRC1 - [6:0] */
1622#define WM2200_AIF1TX1MIX_SRC1_SHIFT 0 /* AIF1TX1MIX_SRC1 - [6:0] */
1623#define WM2200_AIF1TX1MIX_SRC1_WIDTH 7 /* AIF1TX1MIX_SRC1 - [6:0] */
1624
1625/*
1626 * R1569 (0x621) - AIF1TX1MIX Input 1 Volume
1627 */
1628#define WM2200_AIF1TX1MIX_VOL1_MASK 0x00FE /* AIF1TX1MIX_VOL1 - [7:1] */
1629#define WM2200_AIF1TX1MIX_VOL1_SHIFT 1 /* AIF1TX1MIX_VOL1 - [7:1] */
1630#define WM2200_AIF1TX1MIX_VOL1_WIDTH 7 /* AIF1TX1MIX_VOL1 - [7:1] */
1631
1632/*
1633 * R1570 (0x622) - AIF1TX1MIX Input 2 Source
1634 */
1635#define WM2200_AIF1TX1MIX_SRC2_MASK 0x007F /* AIF1TX1MIX_SRC2 - [6:0] */
1636#define WM2200_AIF1TX1MIX_SRC2_SHIFT 0 /* AIF1TX1MIX_SRC2 - [6:0] */
1637#define WM2200_AIF1TX1MIX_SRC2_WIDTH 7 /* AIF1TX1MIX_SRC2 - [6:0] */
1638
1639/*
1640 * R1571 (0x623) - AIF1TX1MIX Input 2 Volume
1641 */
1642#define WM2200_AIF1TX1MIX_VOL2_MASK 0x00FE /* AIF1TX1MIX_VOL2 - [7:1] */
1643#define WM2200_AIF1TX1MIX_VOL2_SHIFT 1 /* AIF1TX1MIX_VOL2 - [7:1] */
1644#define WM2200_AIF1TX1MIX_VOL2_WIDTH 7 /* AIF1TX1MIX_VOL2 - [7:1] */
1645
1646/*
1647 * R1572 (0x624) - AIF1TX1MIX Input 3 Source
1648 */
1649#define WM2200_AIF1TX1MIX_SRC3_MASK 0x007F /* AIF1TX1MIX_SRC3 - [6:0] */
1650#define WM2200_AIF1TX1MIX_SRC3_SHIFT 0 /* AIF1TX1MIX_SRC3 - [6:0] */
1651#define WM2200_AIF1TX1MIX_SRC3_WIDTH 7 /* AIF1TX1MIX_SRC3 - [6:0] */
1652
1653/*
1654 * R1573 (0x625) - AIF1TX1MIX Input 3 Volume
1655 */
1656#define WM2200_AIF1TX1MIX_VOL3_MASK 0x00FE /* AIF1TX1MIX_VOL3 - [7:1] */
1657#define WM2200_AIF1TX1MIX_VOL3_SHIFT 1 /* AIF1TX1MIX_VOL3 - [7:1] */
1658#define WM2200_AIF1TX1MIX_VOL3_WIDTH 7 /* AIF1TX1MIX_VOL3 - [7:1] */
1659
1660/*
1661 * R1574 (0x626) - AIF1TX1MIX Input 4 Source
1662 */
1663#define WM2200_AIF1TX1MIX_SRC4_MASK 0x007F /* AIF1TX1MIX_SRC4 - [6:0] */
1664#define WM2200_AIF1TX1MIX_SRC4_SHIFT 0 /* AIF1TX1MIX_SRC4 - [6:0] */
1665#define WM2200_AIF1TX1MIX_SRC4_WIDTH 7 /* AIF1TX1MIX_SRC4 - [6:0] */
1666
1667/*
1668 * R1575 (0x627) - AIF1TX1MIX Input 4 Volume
1669 */
1670#define WM2200_AIF1TX1MIX_VOL4_MASK 0x00FE /* AIF1TX1MIX_VOL4 - [7:1] */
1671#define WM2200_AIF1TX1MIX_VOL4_SHIFT 1 /* AIF1TX1MIX_VOL4 - [7:1] */
1672#define WM2200_AIF1TX1MIX_VOL4_WIDTH 7 /* AIF1TX1MIX_VOL4 - [7:1] */
1673
1674/*
1675 * R1576 (0x628) - AIF1TX2MIX Input 1 Source
1676 */
1677#define WM2200_AIF1TX2MIX_SRC1_MASK 0x007F /* AIF1TX2MIX_SRC1 - [6:0] */
1678#define WM2200_AIF1TX2MIX_SRC1_SHIFT 0 /* AIF1TX2MIX_SRC1 - [6:0] */
1679#define WM2200_AIF1TX2MIX_SRC1_WIDTH 7 /* AIF1TX2MIX_SRC1 - [6:0] */
1680
1681/*
1682 * R1577 (0x629) - AIF1TX2MIX Input 1 Volume
1683 */
1684#define WM2200_AIF1TX2MIX_VOL1_MASK 0x00FE /* AIF1TX2MIX_VOL1 - [7:1] */
1685#define WM2200_AIF1TX2MIX_VOL1_SHIFT 1 /* AIF1TX2MIX_VOL1 - [7:1] */
1686#define WM2200_AIF1TX2MIX_VOL1_WIDTH 7 /* AIF1TX2MIX_VOL1 - [7:1] */
1687
1688/*
1689 * R1578 (0x62A) - AIF1TX2MIX Input 2 Source
1690 */
1691#define WM2200_AIF1TX2MIX_SRC2_MASK 0x007F /* AIF1TX2MIX_SRC2 - [6:0] */
1692#define WM2200_AIF1TX2MIX_SRC2_SHIFT 0 /* AIF1TX2MIX_SRC2 - [6:0] */
1693#define WM2200_AIF1TX2MIX_SRC2_WIDTH 7 /* AIF1TX2MIX_SRC2 - [6:0] */
1694
1695/*
1696 * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume
1697 */
1698#define WM2200_AIF1TX2MIX_VOL2_MASK 0x00FE /* AIF1TX2MIX_VOL2 - [7:1] */
1699#define WM2200_AIF1TX2MIX_VOL2_SHIFT 1 /* AIF1TX2MIX_VOL2 - [7:1] */
1700#define WM2200_AIF1TX2MIX_VOL2_WIDTH 7 /* AIF1TX2MIX_VOL2 - [7:1] */
1701
1702/*
1703 * R1580 (0x62C) - AIF1TX2MIX Input 3 Source
1704 */
1705#define WM2200_AIF1TX2MIX_SRC3_MASK 0x007F /* AIF1TX2MIX_SRC3 - [6:0] */
1706#define WM2200_AIF1TX2MIX_SRC3_SHIFT 0 /* AIF1TX2MIX_SRC3 - [6:0] */
1707#define WM2200_AIF1TX2MIX_SRC3_WIDTH 7 /* AIF1TX2MIX_SRC3 - [6:0] */
1708
1709/*
1710 * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume
1711 */
1712#define WM2200_AIF1TX2MIX_VOL3_MASK 0x00FE /* AIF1TX2MIX_VOL3 - [7:1] */
1713#define WM2200_AIF1TX2MIX_VOL3_SHIFT 1 /* AIF1TX2MIX_VOL3 - [7:1] */
1714#define WM2200_AIF1TX2MIX_VOL3_WIDTH 7 /* AIF1TX2MIX_VOL3 - [7:1] */
1715
1716/*
1717 * R1582 (0x62E) - AIF1TX2MIX Input 4 Source
1718 */
1719#define WM2200_AIF1TX2MIX_SRC4_MASK 0x007F /* AIF1TX2MIX_SRC4 - [6:0] */
1720#define WM2200_AIF1TX2MIX_SRC4_SHIFT 0 /* AIF1TX2MIX_SRC4 - [6:0] */
1721#define WM2200_AIF1TX2MIX_SRC4_WIDTH 7 /* AIF1TX2MIX_SRC4 - [6:0] */
1722
1723/*
1724 * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume
1725 */
1726#define WM2200_AIF1TX2MIX_VOL4_MASK 0x00FE /* AIF1TX2MIX_VOL4 - [7:1] */
1727#define WM2200_AIF1TX2MIX_VOL4_SHIFT 1 /* AIF1TX2MIX_VOL4 - [7:1] */
1728#define WM2200_AIF1TX2MIX_VOL4_WIDTH 7 /* AIF1TX2MIX_VOL4 - [7:1] */
1729
1730/*
1731 * R1584 (0x630) - AIF1TX3MIX Input 1 Source
1732 */
1733#define WM2200_AIF1TX3MIX_SRC1_MASK 0x007F /* AIF1TX3MIX_SRC1 - [6:0] */
1734#define WM2200_AIF1TX3MIX_SRC1_SHIFT 0 /* AIF1TX3MIX_SRC1 - [6:0] */
1735#define WM2200_AIF1TX3MIX_SRC1_WIDTH 7 /* AIF1TX3MIX_SRC1 - [6:0] */
1736
1737/*
1738 * R1585 (0x631) - AIF1TX3MIX Input 1 Volume
1739 */
1740#define WM2200_AIF1TX3MIX_VOL1_MASK 0x00FE /* AIF1TX3MIX_VOL1 - [7:1] */
1741#define WM2200_AIF1TX3MIX_VOL1_SHIFT 1 /* AIF1TX3MIX_VOL1 - [7:1] */
1742#define WM2200_AIF1TX3MIX_VOL1_WIDTH 7 /* AIF1TX3MIX_VOL1 - [7:1] */
1743
1744/*
1745 * R1586 (0x632) - AIF1TX3MIX Input 2 Source
1746 */
1747#define WM2200_AIF1TX3MIX_SRC2_MASK 0x007F /* AIF1TX3MIX_SRC2 - [6:0] */
1748#define WM2200_AIF1TX3MIX_SRC2_SHIFT 0 /* AIF1TX3MIX_SRC2 - [6:0] */
1749#define WM2200_AIF1TX3MIX_SRC2_WIDTH 7 /* AIF1TX3MIX_SRC2 - [6:0] */
1750
1751/*
1752 * R1587 (0x633) - AIF1TX3MIX Input 2 Volume
1753 */
1754#define WM2200_AIF1TX3MIX_VOL2_MASK 0x00FE /* AIF1TX3MIX_VOL2 - [7:1] */
1755#define WM2200_AIF1TX3MIX_VOL2_SHIFT 1 /* AIF1TX3MIX_VOL2 - [7:1] */
1756#define WM2200_AIF1TX3MIX_VOL2_WIDTH 7 /* AIF1TX3MIX_VOL2 - [7:1] */
1757
1758/*
1759 * R1588 (0x634) - AIF1TX3MIX Input 3 Source
1760 */
1761#define WM2200_AIF1TX3MIX_SRC3_MASK 0x007F /* AIF1TX3MIX_SRC3 - [6:0] */
1762#define WM2200_AIF1TX3MIX_SRC3_SHIFT 0 /* AIF1TX3MIX_SRC3 - [6:0] */
1763#define WM2200_AIF1TX3MIX_SRC3_WIDTH 7 /* AIF1TX3MIX_SRC3 - [6:0] */
1764
1765/*
1766 * R1589 (0x635) - AIF1TX3MIX Input 3 Volume
1767 */
1768#define WM2200_AIF1TX3MIX_VOL3_MASK 0x00FE /* AIF1TX3MIX_VOL3 - [7:1] */
1769#define WM2200_AIF1TX3MIX_VOL3_SHIFT 1 /* AIF1TX3MIX_VOL3 - [7:1] */
1770#define WM2200_AIF1TX3MIX_VOL3_WIDTH 7 /* AIF1TX3MIX_VOL3 - [7:1] */
1771
1772/*
1773 * R1590 (0x636) - AIF1TX3MIX Input 4 Source
1774 */
1775#define WM2200_AIF1TX3MIX_SRC4_MASK 0x007F /* AIF1TX3MIX_SRC4 - [6:0] */
1776#define WM2200_AIF1TX3MIX_SRC4_SHIFT 0 /* AIF1TX3MIX_SRC4 - [6:0] */
1777#define WM2200_AIF1TX3MIX_SRC4_WIDTH 7 /* AIF1TX3MIX_SRC4 - [6:0] */
1778
1779/*
1780 * R1591 (0x637) - AIF1TX3MIX Input 4 Volume
1781 */
1782#define WM2200_AIF1TX3MIX_VOL4_MASK 0x00FE /* AIF1TX3MIX_VOL4 - [7:1] */
1783#define WM2200_AIF1TX3MIX_VOL4_SHIFT 1 /* AIF1TX3MIX_VOL4 - [7:1] */
1784#define WM2200_AIF1TX3MIX_VOL4_WIDTH 7 /* AIF1TX3MIX_VOL4 - [7:1] */
1785
1786/*
1787 * R1592 (0x638) - AIF1TX4MIX Input 1 Source
1788 */
1789#define WM2200_AIF1TX4MIX_SRC1_MASK 0x007F /* AIF1TX4MIX_SRC1 - [6:0] */
1790#define WM2200_AIF1TX4MIX_SRC1_SHIFT 0 /* AIF1TX4MIX_SRC1 - [6:0] */
1791#define WM2200_AIF1TX4MIX_SRC1_WIDTH 7 /* AIF1TX4MIX_SRC1 - [6:0] */
1792
1793/*
1794 * R1593 (0x639) - AIF1TX4MIX Input 1 Volume
1795 */
1796#define WM2200_AIF1TX4MIX_VOL1_MASK 0x00FE /* AIF1TX4MIX_VOL1 - [7:1] */
1797#define WM2200_AIF1TX4MIX_VOL1_SHIFT 1 /* AIF1TX4MIX_VOL1 - [7:1] */
1798#define WM2200_AIF1TX4MIX_VOL1_WIDTH 7 /* AIF1TX4MIX_VOL1 - [7:1] */
1799
1800/*
1801 * R1594 (0x63A) - AIF1TX4MIX Input 2 Source
1802 */
1803#define WM2200_AIF1TX4MIX_SRC2_MASK 0x007F /* AIF1TX4MIX_SRC2 - [6:0] */
1804#define WM2200_AIF1TX4MIX_SRC2_SHIFT 0 /* AIF1TX4MIX_SRC2 - [6:0] */
1805#define WM2200_AIF1TX4MIX_SRC2_WIDTH 7 /* AIF1TX4MIX_SRC2 - [6:0] */
1806
1807/*
1808 * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume
1809 */
1810#define WM2200_AIF1TX4MIX_VOL2_MASK 0x00FE /* AIF1TX4MIX_VOL2 - [7:1] */
1811#define WM2200_AIF1TX4MIX_VOL2_SHIFT 1 /* AIF1TX4MIX_VOL2 - [7:1] */
1812#define WM2200_AIF1TX4MIX_VOL2_WIDTH 7 /* AIF1TX4MIX_VOL2 - [7:1] */
1813
1814/*
1815 * R1596 (0x63C) - AIF1TX4MIX Input 3 Source
1816 */
1817#define WM2200_AIF1TX4MIX_SRC3_MASK 0x007F /* AIF1TX4MIX_SRC3 - [6:0] */
1818#define WM2200_AIF1TX4MIX_SRC3_SHIFT 0 /* AIF1TX4MIX_SRC3 - [6:0] */
1819#define WM2200_AIF1TX4MIX_SRC3_WIDTH 7 /* AIF1TX4MIX_SRC3 - [6:0] */
1820
1821/*
1822 * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume
1823 */
1824#define WM2200_AIF1TX4MIX_VOL3_MASK 0x00FE /* AIF1TX4MIX_VOL3 - [7:1] */
1825#define WM2200_AIF1TX4MIX_VOL3_SHIFT 1 /* AIF1TX4MIX_VOL3 - [7:1] */
1826#define WM2200_AIF1TX4MIX_VOL3_WIDTH 7 /* AIF1TX4MIX_VOL3 - [7:1] */
1827
1828/*
1829 * R1598 (0x63E) - AIF1TX4MIX Input 4 Source
1830 */
1831#define WM2200_AIF1TX4MIX_SRC4_MASK 0x007F /* AIF1TX4MIX_SRC4 - [6:0] */
1832#define WM2200_AIF1TX4MIX_SRC4_SHIFT 0 /* AIF1TX4MIX_SRC4 - [6:0] */
1833#define WM2200_AIF1TX4MIX_SRC4_WIDTH 7 /* AIF1TX4MIX_SRC4 - [6:0] */
1834
1835/*
1836 * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume
1837 */
1838#define WM2200_AIF1TX4MIX_VOL4_MASK 0x00FE /* AIF1TX4MIX_VOL4 - [7:1] */
1839#define WM2200_AIF1TX4MIX_VOL4_SHIFT 1 /* AIF1TX4MIX_VOL4 - [7:1] */
1840#define WM2200_AIF1TX4MIX_VOL4_WIDTH 7 /* AIF1TX4MIX_VOL4 - [7:1] */
1841
1842/*
1843 * R1600 (0x640) - AIF1TX5MIX Input 1 Source
1844 */
1845#define WM2200_AIF1TX5MIX_SRC1_MASK 0x007F /* AIF1TX5MIX_SRC1 - [6:0] */
1846#define WM2200_AIF1TX5MIX_SRC1_SHIFT 0 /* AIF1TX5MIX_SRC1 - [6:0] */
1847#define WM2200_AIF1TX5MIX_SRC1_WIDTH 7 /* AIF1TX5MIX_SRC1 - [6:0] */
1848
1849/*
1850 * R1601 (0x641) - AIF1TX5MIX Input 1 Volume
1851 */
1852#define WM2200_AIF1TX5MIX_VOL1_MASK 0x00FE /* AIF1TX5MIX_VOL1 - [7:1] */
1853#define WM2200_AIF1TX5MIX_VOL1_SHIFT 1 /* AIF1TX5MIX_VOL1 - [7:1] */
1854#define WM2200_AIF1TX5MIX_VOL1_WIDTH 7 /* AIF1TX5MIX_VOL1 - [7:1] */
1855
1856/*
1857 * R1602 (0x642) - AIF1TX5MIX Input 2 Source
1858 */
1859#define WM2200_AIF1TX5MIX_SRC2_MASK 0x007F /* AIF1TX5MIX_SRC2 - [6:0] */
1860#define WM2200_AIF1TX5MIX_SRC2_SHIFT 0 /* AIF1TX5MIX_SRC2 - [6:0] */
1861#define WM2200_AIF1TX5MIX_SRC2_WIDTH 7 /* AIF1TX5MIX_SRC2 - [6:0] */
1862
1863/*
1864 * R1603 (0x643) - AIF1TX5MIX Input 2 Volume
1865 */
1866#define WM2200_AIF1TX5MIX_VOL2_MASK 0x00FE /* AIF1TX5MIX_VOL2 - [7:1] */
1867#define WM2200_AIF1TX5MIX_VOL2_SHIFT 1 /* AIF1TX5MIX_VOL2 - [7:1] */
1868#define WM2200_AIF1TX5MIX_VOL2_WIDTH 7 /* AIF1TX5MIX_VOL2 - [7:1] */
1869
1870/*
1871 * R1604 (0x644) - AIF1TX5MIX Input 3 Source
1872 */
1873#define WM2200_AIF1TX5MIX_SRC3_MASK 0x007F /* AIF1TX5MIX_SRC3 - [6:0] */
1874#define WM2200_AIF1TX5MIX_SRC3_SHIFT 0 /* AIF1TX5MIX_SRC3 - [6:0] */
1875#define WM2200_AIF1TX5MIX_SRC3_WIDTH 7 /* AIF1TX5MIX_SRC3 - [6:0] */
1876
1877/*
1878 * R1605 (0x645) - AIF1TX5MIX Input 3 Volume
1879 */
1880#define WM2200_AIF1TX5MIX_VOL3_MASK 0x00FE /* AIF1TX5MIX_VOL3 - [7:1] */
1881#define WM2200_AIF1TX5MIX_VOL3_SHIFT 1 /* AIF1TX5MIX_VOL3 - [7:1] */
1882#define WM2200_AIF1TX5MIX_VOL3_WIDTH 7 /* AIF1TX5MIX_VOL3 - [7:1] */
1883
1884/*
1885 * R1606 (0x646) - AIF1TX5MIX Input 4 Source
1886 */
1887#define WM2200_AIF1TX5MIX_SRC4_MASK 0x007F /* AIF1TX5MIX_SRC4 - [6:0] */
1888#define WM2200_AIF1TX5MIX_SRC4_SHIFT 0 /* AIF1TX5MIX_SRC4 - [6:0] */
1889#define WM2200_AIF1TX5MIX_SRC4_WIDTH 7 /* AIF1TX5MIX_SRC4 - [6:0] */
1890
1891/*
1892 * R1607 (0x647) - AIF1TX5MIX Input 4 Volume
1893 */
1894#define WM2200_AIF1TX5MIX_VOL4_MASK 0x00FE /* AIF1TX5MIX_VOL4 - [7:1] */
1895#define WM2200_AIF1TX5MIX_VOL4_SHIFT 1 /* AIF1TX5MIX_VOL4 - [7:1] */
1896#define WM2200_AIF1TX5MIX_VOL4_WIDTH 7 /* AIF1TX5MIX_VOL4 - [7:1] */
1897
1898/*
1899 * R1608 (0x648) - AIF1TX6MIX Input 1 Source
1900 */
1901#define WM2200_AIF1TX6MIX_SRC1_MASK 0x007F /* AIF1TX6MIX_SRC1 - [6:0] */
1902#define WM2200_AIF1TX6MIX_SRC1_SHIFT 0 /* AIF1TX6MIX_SRC1 - [6:0] */
1903#define WM2200_AIF1TX6MIX_SRC1_WIDTH 7 /* AIF1TX6MIX_SRC1 - [6:0] */
1904
1905/*
1906 * R1609 (0x649) - AIF1TX6MIX Input 1 Volume
1907 */
1908#define WM2200_AIF1TX6MIX_VOL1_MASK 0x00FE /* AIF1TX6MIX_VOL1 - [7:1] */
1909#define WM2200_AIF1TX6MIX_VOL1_SHIFT 1 /* AIF1TX6MIX_VOL1 - [7:1] */
1910#define WM2200_AIF1TX6MIX_VOL1_WIDTH 7 /* AIF1TX6MIX_VOL1 - [7:1] */
1911
1912/*
1913 * R1610 (0x64A) - AIF1TX6MIX Input 2 Source
1914 */
1915#define WM2200_AIF1TX6MIX_SRC2_MASK 0x007F /* AIF1TX6MIX_SRC2 - [6:0] */
1916#define WM2200_AIF1TX6MIX_SRC2_SHIFT 0 /* AIF1TX6MIX_SRC2 - [6:0] */
1917#define WM2200_AIF1TX6MIX_SRC2_WIDTH 7 /* AIF1TX6MIX_SRC2 - [6:0] */
1918
1919/*
1920 * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume
1921 */
1922#define WM2200_AIF1TX6MIX_VOL2_MASK 0x00FE /* AIF1TX6MIX_VOL2 - [7:1] */
1923#define WM2200_AIF1TX6MIX_VOL2_SHIFT 1 /* AIF1TX6MIX_VOL2 - [7:1] */
1924#define WM2200_AIF1TX6MIX_VOL2_WIDTH 7 /* AIF1TX6MIX_VOL2 - [7:1] */
1925
1926/*
1927 * R1612 (0x64C) - AIF1TX6MIX Input 3 Source
1928 */
1929#define WM2200_AIF1TX6MIX_SRC3_MASK 0x007F /* AIF1TX6MIX_SRC3 - [6:0] */
1930#define WM2200_AIF1TX6MIX_SRC3_SHIFT 0 /* AIF1TX6MIX_SRC3 - [6:0] */
1931#define WM2200_AIF1TX6MIX_SRC3_WIDTH 7 /* AIF1TX6MIX_SRC3 - [6:0] */
1932
1933/*
1934 * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume
1935 */
1936#define WM2200_AIF1TX6MIX_VOL3_MASK 0x00FE /* AIF1TX6MIX_VOL3 - [7:1] */
1937#define WM2200_AIF1TX6MIX_VOL3_SHIFT 1 /* AIF1TX6MIX_VOL3 - [7:1] */
1938#define WM2200_AIF1TX6MIX_VOL3_WIDTH 7 /* AIF1TX6MIX_VOL3 - [7:1] */
1939
1940/*
1941 * R1614 (0x64E) - AIF1TX6MIX Input 4 Source
1942 */
1943#define WM2200_AIF1TX6MIX_SRC4_MASK 0x007F /* AIF1TX6MIX_SRC4 - [6:0] */
1944#define WM2200_AIF1TX6MIX_SRC4_SHIFT 0 /* AIF1TX6MIX_SRC4 - [6:0] */
1945#define WM2200_AIF1TX6MIX_SRC4_WIDTH 7 /* AIF1TX6MIX_SRC4 - [6:0] */
1946
1947/*
1948 * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume
1949 */
1950#define WM2200_AIF1TX6MIX_VOL4_MASK 0x00FE /* AIF1TX6MIX_VOL4 - [7:1] */
1951#define WM2200_AIF1TX6MIX_VOL4_SHIFT 1 /* AIF1TX6MIX_VOL4 - [7:1] */
1952#define WM2200_AIF1TX6MIX_VOL4_WIDTH 7 /* AIF1TX6MIX_VOL4 - [7:1] */
1953
1954/*
1955 * R1616 (0x650) - EQLMIX Input 1 Source
1956 */
1957#define WM2200_EQLMIX_SRC1_MASK 0x007F /* EQLMIX_SRC1 - [6:0] */
1958#define WM2200_EQLMIX_SRC1_SHIFT 0 /* EQLMIX_SRC1 - [6:0] */
1959#define WM2200_EQLMIX_SRC1_WIDTH 7 /* EQLMIX_SRC1 - [6:0] */
1960
1961/*
1962 * R1617 (0x651) - EQLMIX Input 1 Volume
1963 */
1964#define WM2200_EQLMIX_VOL1_MASK 0x00FE /* EQLMIX_VOL1 - [7:1] */
1965#define WM2200_EQLMIX_VOL1_SHIFT 1 /* EQLMIX_VOL1 - [7:1] */
1966#define WM2200_EQLMIX_VOL1_WIDTH 7 /* EQLMIX_VOL1 - [7:1] */
1967
1968/*
1969 * R1618 (0x652) - EQLMIX Input 2 Source
1970 */
1971#define WM2200_EQLMIX_SRC2_MASK 0x007F /* EQLMIX_SRC2 - [6:0] */
1972#define WM2200_EQLMIX_SRC2_SHIFT 0 /* EQLMIX_SRC2 - [6:0] */
1973#define WM2200_EQLMIX_SRC2_WIDTH 7 /* EQLMIX_SRC2 - [6:0] */
1974
1975/*
1976 * R1619 (0x653) - EQLMIX Input 2 Volume
1977 */
1978#define WM2200_EQLMIX_VOL2_MASK 0x00FE /* EQLMIX_VOL2 - [7:1] */
1979#define WM2200_EQLMIX_VOL2_SHIFT 1 /* EQLMIX_VOL2 - [7:1] */
1980#define WM2200_EQLMIX_VOL2_WIDTH 7 /* EQLMIX_VOL2 - [7:1] */
1981
1982/*
1983 * R1620 (0x654) - EQLMIX Input 3 Source
1984 */
1985#define WM2200_EQLMIX_SRC3_MASK 0x007F /* EQLMIX_SRC3 - [6:0] */
1986#define WM2200_EQLMIX_SRC3_SHIFT 0 /* EQLMIX_SRC3 - [6:0] */
1987#define WM2200_EQLMIX_SRC3_WIDTH 7 /* EQLMIX_SRC3 - [6:0] */
1988
1989/*
1990 * R1621 (0x655) - EQLMIX Input 3 Volume
1991 */
1992#define WM2200_EQLMIX_VOL3_MASK 0x00FE /* EQLMIX_VOL3 - [7:1] */
1993#define WM2200_EQLMIX_VOL3_SHIFT 1 /* EQLMIX_VOL3 - [7:1] */
1994#define WM2200_EQLMIX_VOL3_WIDTH 7 /* EQLMIX_VOL3 - [7:1] */
1995
1996/*
1997 * R1622 (0x656) - EQLMIX Input 4 Source
1998 */
1999#define WM2200_EQLMIX_SRC4_MASK 0x007F /* EQLMIX_SRC4 - [6:0] */
2000#define WM2200_EQLMIX_SRC4_SHIFT 0 /* EQLMIX_SRC4 - [6:0] */
2001#define WM2200_EQLMIX_SRC4_WIDTH 7 /* EQLMIX_SRC4 - [6:0] */
2002
2003/*
2004 * R1623 (0x657) - EQLMIX Input 4 Volume
2005 */
2006#define WM2200_EQLMIX_VOL4_MASK 0x00FE /* EQLMIX_VOL4 - [7:1] */
2007#define WM2200_EQLMIX_VOL4_SHIFT 1 /* EQLMIX_VOL4 - [7:1] */
2008#define WM2200_EQLMIX_VOL4_WIDTH 7 /* EQLMIX_VOL4 - [7:1] */
2009
2010/*
2011 * R1624 (0x658) - EQRMIX Input 1 Source
2012 */
2013#define WM2200_EQRMIX_SRC1_MASK 0x007F /* EQRMIX_SRC1 - [6:0] */
2014#define WM2200_EQRMIX_SRC1_SHIFT 0 /* EQRMIX_SRC1 - [6:0] */
2015#define WM2200_EQRMIX_SRC1_WIDTH 7 /* EQRMIX_SRC1 - [6:0] */
2016
2017/*
2018 * R1625 (0x659) - EQRMIX Input 1 Volume
2019 */
2020#define WM2200_EQRMIX_VOL1_MASK 0x00FE /* EQRMIX_VOL1 - [7:1] */
2021#define WM2200_EQRMIX_VOL1_SHIFT 1 /* EQRMIX_VOL1 - [7:1] */
2022#define WM2200_EQRMIX_VOL1_WIDTH 7 /* EQRMIX_VOL1 - [7:1] */
2023
2024/*
2025 * R1626 (0x65A) - EQRMIX Input 2 Source
2026 */
2027#define WM2200_EQRMIX_SRC2_MASK 0x007F /* EQRMIX_SRC2 - [6:0] */
2028#define WM2200_EQRMIX_SRC2_SHIFT 0 /* EQRMIX_SRC2 - [6:0] */
2029#define WM2200_EQRMIX_SRC2_WIDTH 7 /* EQRMIX_SRC2 - [6:0] */
2030
2031/*
2032 * R1627 (0x65B) - EQRMIX Input 2 Volume
2033 */
2034#define WM2200_EQRMIX_VOL2_MASK 0x00FE /* EQRMIX_VOL2 - [7:1] */
2035#define WM2200_EQRMIX_VOL2_SHIFT 1 /* EQRMIX_VOL2 - [7:1] */
2036#define WM2200_EQRMIX_VOL2_WIDTH 7 /* EQRMIX_VOL2 - [7:1] */
2037
2038/*
2039 * R1628 (0x65C) - EQRMIX Input 3 Source
2040 */
2041#define WM2200_EQRMIX_SRC3_MASK 0x007F /* EQRMIX_SRC3 - [6:0] */
2042#define WM2200_EQRMIX_SRC3_SHIFT 0 /* EQRMIX_SRC3 - [6:0] */
2043#define WM2200_EQRMIX_SRC3_WIDTH 7 /* EQRMIX_SRC3 - [6:0] */
2044
2045/*
2046 * R1629 (0x65D) - EQRMIX Input 3 Volume
2047 */
2048#define WM2200_EQRMIX_VOL3_MASK 0x00FE /* EQRMIX_VOL3 - [7:1] */
2049#define WM2200_EQRMIX_VOL3_SHIFT 1 /* EQRMIX_VOL3 - [7:1] */
2050#define WM2200_EQRMIX_VOL3_WIDTH 7 /* EQRMIX_VOL3 - [7:1] */
2051
2052/*
2053 * R1630 (0x65E) - EQRMIX Input 4 Source
2054 */
2055#define WM2200_EQRMIX_SRC4_MASK 0x007F /* EQRMIX_SRC4 - [6:0] */
2056#define WM2200_EQRMIX_SRC4_SHIFT 0 /* EQRMIX_SRC4 - [6:0] */
2057#define WM2200_EQRMIX_SRC4_WIDTH 7 /* EQRMIX_SRC4 - [6:0] */
2058
2059/*
2060 * R1631 (0x65F) - EQRMIX Input 4 Volume
2061 */
2062#define WM2200_EQRMIX_VOL4_MASK 0x00FE /* EQRMIX_VOL4 - [7:1] */
2063#define WM2200_EQRMIX_VOL4_SHIFT 1 /* EQRMIX_VOL4 - [7:1] */
2064#define WM2200_EQRMIX_VOL4_WIDTH 7 /* EQRMIX_VOL4 - [7:1] */
2065
2066/*
2067 * R1632 (0x660) - LHPF1MIX Input 1 Source
2068 */
2069#define WM2200_LHPF1MIX_SRC1_MASK 0x007F /* LHPF1MIX_SRC1 - [6:0] */
2070#define WM2200_LHPF1MIX_SRC1_SHIFT 0 /* LHPF1MIX_SRC1 - [6:0] */
2071#define WM2200_LHPF1MIX_SRC1_WIDTH 7 /* LHPF1MIX_SRC1 - [6:0] */
2072
2073/*
2074 * R1633 (0x661) - LHPF1MIX Input 1 Volume
2075 */
2076#define WM2200_LHPF1MIX_VOL1_MASK 0x00FE /* LHPF1MIX_VOL1 - [7:1] */
2077#define WM2200_LHPF1MIX_VOL1_SHIFT 1 /* LHPF1MIX_VOL1 - [7:1] */
2078#define WM2200_LHPF1MIX_VOL1_WIDTH 7 /* LHPF1MIX_VOL1 - [7:1] */
2079
2080/*
2081 * R1634 (0x662) - LHPF1MIX Input 2 Source
2082 */
2083#define WM2200_LHPF1MIX_SRC2_MASK 0x007F /* LHPF1MIX_SRC2 - [6:0] */
2084#define WM2200_LHPF1MIX_SRC2_SHIFT 0 /* LHPF1MIX_SRC2 - [6:0] */
2085#define WM2200_LHPF1MIX_SRC2_WIDTH 7 /* LHPF1MIX_SRC2 - [6:0] */
2086
2087/*
2088 * R1635 (0x663) - LHPF1MIX Input 2 Volume
2089 */
2090#define WM2200_LHPF1MIX_VOL2_MASK 0x00FE /* LHPF1MIX_VOL2 - [7:1] */
2091#define WM2200_LHPF1MIX_VOL2_SHIFT 1 /* LHPF1MIX_VOL2 - [7:1] */
2092#define WM2200_LHPF1MIX_VOL2_WIDTH 7 /* LHPF1MIX_VOL2 - [7:1] */
2093
2094/*
2095 * R1636 (0x664) - LHPF1MIX Input 3 Source
2096 */
2097#define WM2200_LHPF1MIX_SRC3_MASK 0x007F /* LHPF1MIX_SRC3 - [6:0] */
2098#define WM2200_LHPF1MIX_SRC3_SHIFT 0 /* LHPF1MIX_SRC3 - [6:0] */
2099#define WM2200_LHPF1MIX_SRC3_WIDTH 7 /* LHPF1MIX_SRC3 - [6:0] */
2100
2101/*
2102 * R1637 (0x665) - LHPF1MIX Input 3 Volume
2103 */
2104#define WM2200_LHPF1MIX_VOL3_MASK 0x00FE /* LHPF1MIX_VOL3 - [7:1] */
2105#define WM2200_LHPF1MIX_VOL3_SHIFT 1 /* LHPF1MIX_VOL3 - [7:1] */
2106#define WM2200_LHPF1MIX_VOL3_WIDTH 7 /* LHPF1MIX_VOL3 - [7:1] */
2107
2108/*
2109 * R1638 (0x666) - LHPF1MIX Input 4 Source
2110 */
2111#define WM2200_LHPF1MIX_SRC4_MASK 0x007F /* LHPF1MIX_SRC4 - [6:0] */
2112#define WM2200_LHPF1MIX_SRC4_SHIFT 0 /* LHPF1MIX_SRC4 - [6:0] */
2113#define WM2200_LHPF1MIX_SRC4_WIDTH 7 /* LHPF1MIX_SRC4 - [6:0] */
2114
2115/*
2116 * R1639 (0x667) - LHPF1MIX Input 4 Volume
2117 */
2118#define WM2200_LHPF1MIX_VOL4_MASK 0x00FE /* LHPF1MIX_VOL4 - [7:1] */
2119#define WM2200_LHPF1MIX_VOL4_SHIFT 1 /* LHPF1MIX_VOL4 - [7:1] */
2120#define WM2200_LHPF1MIX_VOL4_WIDTH 7 /* LHPF1MIX_VOL4 - [7:1] */
2121
2122/*
2123 * R1640 (0x668) - LHPF2MIX Input 1 Source
2124 */
2125#define WM2200_LHPF2MIX_SRC1_MASK 0x007F /* LHPF2MIX_SRC1 - [6:0] */
2126#define WM2200_LHPF2MIX_SRC1_SHIFT 0 /* LHPF2MIX_SRC1 - [6:0] */
2127#define WM2200_LHPF2MIX_SRC1_WIDTH 7 /* LHPF2MIX_SRC1 - [6:0] */
2128
2129/*
2130 * R1641 (0x669) - LHPF2MIX Input 1 Volume
2131 */
2132#define WM2200_LHPF2MIX_VOL1_MASK 0x00FE /* LHPF2MIX_VOL1 - [7:1] */
2133#define WM2200_LHPF2MIX_VOL1_SHIFT 1 /* LHPF2MIX_VOL1 - [7:1] */
2134#define WM2200_LHPF2MIX_VOL1_WIDTH 7 /* LHPF2MIX_VOL1 - [7:1] */
2135
2136/*
2137 * R1642 (0x66A) - LHPF2MIX Input 2 Source
2138 */
2139#define WM2200_LHPF2MIX_SRC2_MASK 0x007F /* LHPF2MIX_SRC2 - [6:0] */
2140#define WM2200_LHPF2MIX_SRC2_SHIFT 0 /* LHPF2MIX_SRC2 - [6:0] */
2141#define WM2200_LHPF2MIX_SRC2_WIDTH 7 /* LHPF2MIX_SRC2 - [6:0] */
2142
2143/*
2144 * R1643 (0x66B) - LHPF2MIX Input 2 Volume
2145 */
2146#define WM2200_LHPF2MIX_VOL2_MASK 0x00FE /* LHPF2MIX_VOL2 - [7:1] */
2147#define WM2200_LHPF2MIX_VOL2_SHIFT 1 /* LHPF2MIX_VOL2 - [7:1] */
2148#define WM2200_LHPF2MIX_VOL2_WIDTH 7 /* LHPF2MIX_VOL2 - [7:1] */
2149
2150/*
2151 * R1644 (0x66C) - LHPF2MIX Input 3 Source
2152 */
2153#define WM2200_LHPF2MIX_SRC3_MASK 0x007F /* LHPF2MIX_SRC3 - [6:0] */
2154#define WM2200_LHPF2MIX_SRC3_SHIFT 0 /* LHPF2MIX_SRC3 - [6:0] */
2155#define WM2200_LHPF2MIX_SRC3_WIDTH 7 /* LHPF2MIX_SRC3 - [6:0] */
2156
2157/*
2158 * R1645 (0x66D) - LHPF2MIX Input 3 Volume
2159 */
2160#define WM2200_LHPF2MIX_VOL3_MASK 0x00FE /* LHPF2MIX_VOL3 - [7:1] */
2161#define WM2200_LHPF2MIX_VOL3_SHIFT 1 /* LHPF2MIX_VOL3 - [7:1] */
2162#define WM2200_LHPF2MIX_VOL3_WIDTH 7 /* LHPF2MIX_VOL3 - [7:1] */
2163
2164/*
2165 * R1646 (0x66E) - LHPF2MIX Input 4 Source
2166 */
2167#define WM2200_LHPF2MIX_SRC4_MASK 0x007F /* LHPF2MIX_SRC4 - [6:0] */
2168#define WM2200_LHPF2MIX_SRC4_SHIFT 0 /* LHPF2MIX_SRC4 - [6:0] */
2169#define WM2200_LHPF2MIX_SRC4_WIDTH 7 /* LHPF2MIX_SRC4 - [6:0] */
2170
2171/*
2172 * R1647 (0x66F) - LHPF2MIX Input 4 Volume
2173 */
2174#define WM2200_LHPF2MIX_VOL4_MASK 0x00FE /* LHPF2MIX_VOL4 - [7:1] */
2175#define WM2200_LHPF2MIX_VOL4_SHIFT 1 /* LHPF2MIX_VOL4 - [7:1] */
2176#define WM2200_LHPF2MIX_VOL4_WIDTH 7 /* LHPF2MIX_VOL4 - [7:1] */
2177
2178/*
2179 * R1648 (0x670) - DSP1LMIX Input 1 Source
2180 */
2181#define WM2200_DSP1LMIX_SRC1_MASK 0x007F /* DSP1LMIX_SRC1 - [6:0] */
2182#define WM2200_DSP1LMIX_SRC1_SHIFT 0 /* DSP1LMIX_SRC1 - [6:0] */
2183#define WM2200_DSP1LMIX_SRC1_WIDTH 7 /* DSP1LMIX_SRC1 - [6:0] */
2184
2185/*
2186 * R1649 (0x671) - DSP1LMIX Input 1 Volume
2187 */
2188#define WM2200_DSP1LMIX_VOL1_MASK 0x00FE /* DSP1LMIX_VOL1 - [7:1] */
2189#define WM2200_DSP1LMIX_VOL1_SHIFT 1 /* DSP1LMIX_VOL1 - [7:1] */
2190#define WM2200_DSP1LMIX_VOL1_WIDTH 7 /* DSP1LMIX_VOL1 - [7:1] */
2191
2192/*
2193 * R1650 (0x672) - DSP1LMIX Input 2 Source
2194 */
2195#define WM2200_DSP1LMIX_SRC2_MASK 0x007F /* DSP1LMIX_SRC2 - [6:0] */
2196#define WM2200_DSP1LMIX_SRC2_SHIFT 0 /* DSP1LMIX_SRC2 - [6:0] */
2197#define WM2200_DSP1LMIX_SRC2_WIDTH 7 /* DSP1LMIX_SRC2 - [6:0] */
2198
2199/*
2200 * R1651 (0x673) - DSP1LMIX Input 2 Volume
2201 */
2202#define WM2200_DSP1LMIX_VOL2_MASK 0x00FE /* DSP1LMIX_VOL2 - [7:1] */
2203#define WM2200_DSP1LMIX_VOL2_SHIFT 1 /* DSP1LMIX_VOL2 - [7:1] */
2204#define WM2200_DSP1LMIX_VOL2_WIDTH 7 /* DSP1LMIX_VOL2 - [7:1] */
2205
2206/*
2207 * R1652 (0x674) - DSP1LMIX Input 3 Source
2208 */
2209#define WM2200_DSP1LMIX_SRC3_MASK 0x007F /* DSP1LMIX_SRC3 - [6:0] */
2210#define WM2200_DSP1LMIX_SRC3_SHIFT 0 /* DSP1LMIX_SRC3 - [6:0] */
2211#define WM2200_DSP1LMIX_SRC3_WIDTH 7 /* DSP1LMIX_SRC3 - [6:0] */
2212
2213/*
2214 * R1653 (0x675) - DSP1LMIX Input 3 Volume
2215 */
2216#define WM2200_DSP1LMIX_VOL3_MASK 0x00FE /* DSP1LMIX_VOL3 - [7:1] */
2217#define WM2200_DSP1LMIX_VOL3_SHIFT 1 /* DSP1LMIX_VOL3 - [7:1] */
2218#define WM2200_DSP1LMIX_VOL3_WIDTH 7 /* DSP1LMIX_VOL3 - [7:1] */
2219
2220/*
2221 * R1654 (0x676) - DSP1LMIX Input 4 Source
2222 */
2223#define WM2200_DSP1LMIX_SRC4_MASK 0x007F /* DSP1LMIX_SRC4 - [6:0] */
2224#define WM2200_DSP1LMIX_SRC4_SHIFT 0 /* DSP1LMIX_SRC4 - [6:0] */
2225#define WM2200_DSP1LMIX_SRC4_WIDTH 7 /* DSP1LMIX_SRC4 - [6:0] */
2226
2227/*
2228 * R1655 (0x677) - DSP1LMIX Input 4 Volume
2229 */
2230#define WM2200_DSP1LMIX_VOL4_MASK 0x00FE /* DSP1LMIX_VOL4 - [7:1] */
2231#define WM2200_DSP1LMIX_VOL4_SHIFT 1 /* DSP1LMIX_VOL4 - [7:1] */
2232#define WM2200_DSP1LMIX_VOL4_WIDTH 7 /* DSP1LMIX_VOL4 - [7:1] */
2233
2234/*
2235 * R1656 (0x678) - DSP1RMIX Input 1 Source
2236 */
2237#define WM2200_DSP1RMIX_SRC1_MASK 0x007F /* DSP1RMIX_SRC1 - [6:0] */
2238#define WM2200_DSP1RMIX_SRC1_SHIFT 0 /* DSP1RMIX_SRC1 - [6:0] */
2239#define WM2200_DSP1RMIX_SRC1_WIDTH 7 /* DSP1RMIX_SRC1 - [6:0] */
2240
2241/*
2242 * R1657 (0x679) - DSP1RMIX Input 1 Volume
2243 */
2244#define WM2200_DSP1RMIX_VOL1_MASK 0x00FE /* DSP1RMIX_VOL1 - [7:1] */
2245#define WM2200_DSP1RMIX_VOL1_SHIFT 1 /* DSP1RMIX_VOL1 - [7:1] */
2246#define WM2200_DSP1RMIX_VOL1_WIDTH 7 /* DSP1RMIX_VOL1 - [7:1] */
2247
2248/*
2249 * R1658 (0x67A) - DSP1RMIX Input 2 Source
2250 */
2251#define WM2200_DSP1RMIX_SRC2_MASK 0x007F /* DSP1RMIX_SRC2 - [6:0] */
2252#define WM2200_DSP1RMIX_SRC2_SHIFT 0 /* DSP1RMIX_SRC2 - [6:0] */
2253#define WM2200_DSP1RMIX_SRC2_WIDTH 7 /* DSP1RMIX_SRC2 - [6:0] */
2254
2255/*
2256 * R1659 (0x67B) - DSP1RMIX Input 2 Volume
2257 */
2258#define WM2200_DSP1RMIX_VOL2_MASK 0x00FE /* DSP1RMIX_VOL2 - [7:1] */
2259#define WM2200_DSP1RMIX_VOL2_SHIFT 1 /* DSP1RMIX_VOL2 - [7:1] */
2260#define WM2200_DSP1RMIX_VOL2_WIDTH 7 /* DSP1RMIX_VOL2 - [7:1] */
2261
2262/*
2263 * R1660 (0x67C) - DSP1RMIX Input 3 Source
2264 */
2265#define WM2200_DSP1RMIX_SRC3_MASK 0x007F /* DSP1RMIX_SRC3 - [6:0] */
2266#define WM2200_DSP1RMIX_SRC3_SHIFT 0 /* DSP1RMIX_SRC3 - [6:0] */
2267#define WM2200_DSP1RMIX_SRC3_WIDTH 7 /* DSP1RMIX_SRC3 - [6:0] */
2268
2269/*
2270 * R1661 (0x67D) - DSP1RMIX Input 3 Volume
2271 */
2272#define WM2200_DSP1RMIX_VOL3_MASK 0x00FE /* DSP1RMIX_VOL3 - [7:1] */
2273#define WM2200_DSP1RMIX_VOL3_SHIFT 1 /* DSP1RMIX_VOL3 - [7:1] */
2274#define WM2200_DSP1RMIX_VOL3_WIDTH 7 /* DSP1RMIX_VOL3 - [7:1] */
2275
2276/*
2277 * R1662 (0x67E) - DSP1RMIX Input 4 Source
2278 */
2279#define WM2200_DSP1RMIX_SRC4_MASK 0x007F /* DSP1RMIX_SRC4 - [6:0] */
2280#define WM2200_DSP1RMIX_SRC4_SHIFT 0 /* DSP1RMIX_SRC4 - [6:0] */
2281#define WM2200_DSP1RMIX_SRC4_WIDTH 7 /* DSP1RMIX_SRC4 - [6:0] */
2282
2283/*
2284 * R1663 (0x67F) - DSP1RMIX Input 4 Volume
2285 */
2286#define WM2200_DSP1RMIX_VOL4_MASK 0x00FE /* DSP1RMIX_VOL4 - [7:1] */
2287#define WM2200_DSP1RMIX_VOL4_SHIFT 1 /* DSP1RMIX_VOL4 - [7:1] */
2288#define WM2200_DSP1RMIX_VOL4_WIDTH 7 /* DSP1RMIX_VOL4 - [7:1] */
2289
2290/*
2291 * R1664 (0x680) - DSP1AUX1MIX Input 1 Source
2292 */
2293#define WM2200_DSP1AUX1MIX_SRC1_MASK 0x007F /* DSP1AUX1MIX_SRC1 - [6:0] */
2294#define WM2200_DSP1AUX1MIX_SRC1_SHIFT 0 /* DSP1AUX1MIX_SRC1 - [6:0] */
2295#define WM2200_DSP1AUX1MIX_SRC1_WIDTH 7 /* DSP1AUX1MIX_SRC1 - [6:0] */
2296
2297/*
2298 * R1665 (0x681) - DSP1AUX2MIX Input 1 Source
2299 */
2300#define WM2200_DSP1AUX2MIX_SRC1_MASK 0x007F /* DSP1AUX2MIX_SRC1 - [6:0] */
2301#define WM2200_DSP1AUX2MIX_SRC1_SHIFT 0 /* DSP1AUX2MIX_SRC1 - [6:0] */
2302#define WM2200_DSP1AUX2MIX_SRC1_WIDTH 7 /* DSP1AUX2MIX_SRC1 - [6:0] */
2303
2304/*
2305 * R1666 (0x682) - DSP1AUX3MIX Input 1 Source
2306 */
2307#define WM2200_DSP1AUX3MIX_SRC1_MASK 0x007F /* DSP1AUX3MIX_SRC1 - [6:0] */
2308#define WM2200_DSP1AUX3MIX_SRC1_SHIFT 0 /* DSP1AUX3MIX_SRC1 - [6:0] */
2309#define WM2200_DSP1AUX3MIX_SRC1_WIDTH 7 /* DSP1AUX3MIX_SRC1 - [6:0] */
2310
2311/*
2312 * R1667 (0x683) - DSP1AUX4MIX Input 1 Source
2313 */
2314#define WM2200_DSP1AUX4MIX_SRC1_MASK 0x007F /* DSP1AUX4MIX_SRC1 - [6:0] */
2315#define WM2200_DSP1AUX4MIX_SRC1_SHIFT 0 /* DSP1AUX4MIX_SRC1 - [6:0] */
2316#define WM2200_DSP1AUX4MIX_SRC1_WIDTH 7 /* DSP1AUX4MIX_SRC1 - [6:0] */
2317
2318/*
2319 * R1668 (0x684) - DSP1AUX5MIX Input 1 Source
2320 */
2321#define WM2200_DSP1AUX5MIX_SRC1_MASK 0x007F /* DSP1AUX5MIX_SRC1 - [6:0] */
2322#define WM2200_DSP1AUX5MIX_SRC1_SHIFT 0 /* DSP1AUX5MIX_SRC1 - [6:0] */
2323#define WM2200_DSP1AUX5MIX_SRC1_WIDTH 7 /* DSP1AUX5MIX_SRC1 - [6:0] */
2324
2325/*
2326 * R1669 (0x685) - DSP1AUX6MIX Input 1 Source
2327 */
2328#define WM2200_DSP1AUX6MIX_SRC1_MASK 0x007F /* DSP1AUX6MIX_SRC1 - [6:0] */
2329#define WM2200_DSP1AUX6MIX_SRC1_SHIFT 0 /* DSP1AUX6MIX_SRC1 - [6:0] */
2330#define WM2200_DSP1AUX6MIX_SRC1_WIDTH 7 /* DSP1AUX6MIX_SRC1 - [6:0] */
2331
2332/*
2333 * R1670 (0x686) - DSP2LMIX Input 1 Source
2334 */
2335#define WM2200_DSP2LMIX_SRC1_MASK 0x007F /* DSP2LMIX_SRC1 - [6:0] */
2336#define WM2200_DSP2LMIX_SRC1_SHIFT 0 /* DSP2LMIX_SRC1 - [6:0] */
2337#define WM2200_DSP2LMIX_SRC1_WIDTH 7 /* DSP2LMIX_SRC1 - [6:0] */
2338
2339/*
2340 * R1671 (0x687) - DSP2LMIX Input 1 Volume
2341 */
2342#define WM2200_DSP2LMIX_VOL1_MASK 0x00FE /* DSP2LMIX_VOL1 - [7:1] */
2343#define WM2200_DSP2LMIX_VOL1_SHIFT 1 /* DSP2LMIX_VOL1 - [7:1] */
2344#define WM2200_DSP2LMIX_VOL1_WIDTH 7 /* DSP2LMIX_VOL1 - [7:1] */
2345
2346/*
2347 * R1672 (0x688) - DSP2LMIX Input 2 Source
2348 */
2349#define WM2200_DSP2LMIX_SRC2_MASK 0x007F /* DSP2LMIX_SRC2 - [6:0] */
2350#define WM2200_DSP2LMIX_SRC2_SHIFT 0 /* DSP2LMIX_SRC2 - [6:0] */
2351#define WM2200_DSP2LMIX_SRC2_WIDTH 7 /* DSP2LMIX_SRC2 - [6:0] */
2352
2353/*
2354 * R1673 (0x689) - DSP2LMIX Input 2 Volume
2355 */
2356#define WM2200_DSP2LMIX_VOL2_MASK 0x00FE /* DSP2LMIX_VOL2 - [7:1] */
2357#define WM2200_DSP2LMIX_VOL2_SHIFT 1 /* DSP2LMIX_VOL2 - [7:1] */
2358#define WM2200_DSP2LMIX_VOL2_WIDTH 7 /* DSP2LMIX_VOL2 - [7:1] */
2359
2360/*
2361 * R1674 (0x68A) - DSP2LMIX Input 3 Source
2362 */
2363#define WM2200_DSP2LMIX_SRC3_MASK 0x007F /* DSP2LMIX_SRC3 - [6:0] */
2364#define WM2200_DSP2LMIX_SRC3_SHIFT 0 /* DSP2LMIX_SRC3 - [6:0] */
2365#define WM2200_DSP2LMIX_SRC3_WIDTH 7 /* DSP2LMIX_SRC3 - [6:0] */
2366
2367/*
2368 * R1675 (0x68B) - DSP2LMIX Input 3 Volume
2369 */
2370#define WM2200_DSP2LMIX_VOL3_MASK 0x00FE /* DSP2LMIX_VOL3 - [7:1] */
2371#define WM2200_DSP2LMIX_VOL3_SHIFT 1 /* DSP2LMIX_VOL3 - [7:1] */
2372#define WM2200_DSP2LMIX_VOL3_WIDTH 7 /* DSP2LMIX_VOL3 - [7:1] */
2373
2374/*
2375 * R1676 (0x68C) - DSP2LMIX Input 4 Source
2376 */
2377#define WM2200_DSP2LMIX_SRC4_MASK 0x007F /* DSP2LMIX_SRC4 - [6:0] */
2378#define WM2200_DSP2LMIX_SRC4_SHIFT 0 /* DSP2LMIX_SRC4 - [6:0] */
2379#define WM2200_DSP2LMIX_SRC4_WIDTH 7 /* DSP2LMIX_SRC4 - [6:0] */
2380
2381/*
2382 * R1677 (0x68D) - DSP2LMIX Input 4 Volume
2383 */
2384#define WM2200_DSP2LMIX_VOL4_MASK 0x00FE /* DSP2LMIX_VOL4 - [7:1] */
2385#define WM2200_DSP2LMIX_VOL4_SHIFT 1 /* DSP2LMIX_VOL4 - [7:1] */
2386#define WM2200_DSP2LMIX_VOL4_WIDTH 7 /* DSP2LMIX_VOL4 - [7:1] */
2387
2388/*
2389 * R1678 (0x68E) - DSP2RMIX Input 1 Source
2390 */
2391#define WM2200_DSP2RMIX_SRC1_MASK 0x007F /* DSP2RMIX_SRC1 - [6:0] */
2392#define WM2200_DSP2RMIX_SRC1_SHIFT 0 /* DSP2RMIX_SRC1 - [6:0] */
2393#define WM2200_DSP2RMIX_SRC1_WIDTH 7 /* DSP2RMIX_SRC1 - [6:0] */
2394
2395/*
2396 * R1679 (0x68F) - DSP2RMIX Input 1 Volume
2397 */
2398#define WM2200_DSP2RMIX_VOL1_MASK 0x00FE /* DSP2RMIX_VOL1 - [7:1] */
2399#define WM2200_DSP2RMIX_VOL1_SHIFT 1 /* DSP2RMIX_VOL1 - [7:1] */
2400#define WM2200_DSP2RMIX_VOL1_WIDTH 7 /* DSP2RMIX_VOL1 - [7:1] */
2401
2402/*
2403 * R1680 (0x690) - DSP2RMIX Input 2 Source
2404 */
2405#define WM2200_DSP2RMIX_SRC2_MASK 0x007F /* DSP2RMIX_SRC2 - [6:0] */
2406#define WM2200_DSP2RMIX_SRC2_SHIFT 0 /* DSP2RMIX_SRC2 - [6:0] */
2407#define WM2200_DSP2RMIX_SRC2_WIDTH 7 /* DSP2RMIX_SRC2 - [6:0] */
2408
2409/*
2410 * R1681 (0x691) - DSP2RMIX Input 2 Volume
2411 */
2412#define WM2200_DSP2RMIX_VOL2_MASK 0x00FE /* DSP2RMIX_VOL2 - [7:1] */
2413#define WM2200_DSP2RMIX_VOL2_SHIFT 1 /* DSP2RMIX_VOL2 - [7:1] */
2414#define WM2200_DSP2RMIX_VOL2_WIDTH 7 /* DSP2RMIX_VOL2 - [7:1] */
2415
2416/*
2417 * R1682 (0x692) - DSP2RMIX Input 3 Source
2418 */
2419#define WM2200_DSP2RMIX_SRC3_MASK 0x007F /* DSP2RMIX_SRC3 - [6:0] */
2420#define WM2200_DSP2RMIX_SRC3_SHIFT 0 /* DSP2RMIX_SRC3 - [6:0] */
2421#define WM2200_DSP2RMIX_SRC3_WIDTH 7 /* DSP2RMIX_SRC3 - [6:0] */
2422
2423/*
2424 * R1683 (0x693) - DSP2RMIX Input 3 Volume
2425 */
2426#define WM2200_DSP2RMIX_VOL3_MASK 0x00FE /* DSP2RMIX_VOL3 - [7:1] */
2427#define WM2200_DSP2RMIX_VOL3_SHIFT 1 /* DSP2RMIX_VOL3 - [7:1] */
2428#define WM2200_DSP2RMIX_VOL3_WIDTH 7 /* DSP2RMIX_VOL3 - [7:1] */
2429
2430/*
2431 * R1684 (0x694) - DSP2RMIX Input 4 Source
2432 */
2433#define WM2200_DSP2RMIX_SRC4_MASK 0x007F /* DSP2RMIX_SRC4 - [6:0] */
2434#define WM2200_DSP2RMIX_SRC4_SHIFT 0 /* DSP2RMIX_SRC4 - [6:0] */
2435#define WM2200_DSP2RMIX_SRC4_WIDTH 7 /* DSP2RMIX_SRC4 - [6:0] */
2436
2437/*
2438 * R1685 (0x695) - DSP2RMIX Input 4 Volume
2439 */
2440#define WM2200_DSP2RMIX_VOL4_MASK 0x00FE /* DSP2RMIX_VOL4 - [7:1] */
2441#define WM2200_DSP2RMIX_VOL4_SHIFT 1 /* DSP2RMIX_VOL4 - [7:1] */
2442#define WM2200_DSP2RMIX_VOL4_WIDTH 7 /* DSP2RMIX_VOL4 - [7:1] */
2443
2444/*
2445 * R1686 (0x696) - DSP2AUX1MIX Input 1 Source
2446 */
2447#define WM2200_DSP2AUX1MIX_SRC1_MASK 0x007F /* DSP2AUX1MIX_SRC1 - [6:0] */
2448#define WM2200_DSP2AUX1MIX_SRC1_SHIFT 0 /* DSP2AUX1MIX_SRC1 - [6:0] */
2449#define WM2200_DSP2AUX1MIX_SRC1_WIDTH 7 /* DSP2AUX1MIX_SRC1 - [6:0] */
2450
2451/*
2452 * R1687 (0x697) - DSP2AUX2MIX Input 1 Source
2453 */
2454#define WM2200_DSP2AUX2MIX_SRC1_MASK 0x007F /* DSP2AUX2MIX_SRC1 - [6:0] */
2455#define WM2200_DSP2AUX2MIX_SRC1_SHIFT 0 /* DSP2AUX2MIX_SRC1 - [6:0] */
2456#define WM2200_DSP2AUX2MIX_SRC1_WIDTH 7 /* DSP2AUX2MIX_SRC1 - [6:0] */
2457
2458/*
2459 * R1688 (0x698) - DSP2AUX3MIX Input 1 Source
2460 */
2461#define WM2200_DSP2AUX3MIX_SRC1_MASK 0x007F /* DSP2AUX3MIX_SRC1 - [6:0] */
2462#define WM2200_DSP2AUX3MIX_SRC1_SHIFT 0 /* DSP2AUX3MIX_SRC1 - [6:0] */
2463#define WM2200_DSP2AUX3MIX_SRC1_WIDTH 7 /* DSP2AUX3MIX_SRC1 - [6:0] */
2464
2465/*
2466 * R1689 (0x699) - DSP2AUX4MIX Input 1 Source
2467 */
2468#define WM2200_DSP2AUX4MIX_SRC1_MASK 0x007F /* DSP2AUX4MIX_SRC1 - [6:0] */
2469#define WM2200_DSP2AUX4MIX_SRC1_SHIFT 0 /* DSP2AUX4MIX_SRC1 - [6:0] */
2470#define WM2200_DSP2AUX4MIX_SRC1_WIDTH 7 /* DSP2AUX4MIX_SRC1 - [6:0] */
2471
2472/*
2473 * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source
2474 */
2475#define WM2200_DSP2AUX5MIX_SRC1_MASK 0x007F /* DSP2AUX5MIX_SRC1 - [6:0] */
2476#define WM2200_DSP2AUX5MIX_SRC1_SHIFT 0 /* DSP2AUX5MIX_SRC1 - [6:0] */
2477#define WM2200_DSP2AUX5MIX_SRC1_WIDTH 7 /* DSP2AUX5MIX_SRC1 - [6:0] */
2478
2479/*
2480 * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source
2481 */
2482#define WM2200_DSP2AUX6MIX_SRC1_MASK 0x007F /* DSP2AUX6MIX_SRC1 - [6:0] */
2483#define WM2200_DSP2AUX6MIX_SRC1_SHIFT 0 /* DSP2AUX6MIX_SRC1 - [6:0] */
2484#define WM2200_DSP2AUX6MIX_SRC1_WIDTH 7 /* DSP2AUX6MIX_SRC1 - [6:0] */
2485
2486/*
2487 * R1792 (0x700) - GPIO CTRL 1
2488 */
2489#define WM2200_GP1_DIR 0x8000 /* GP1_DIR */
2490#define WM2200_GP1_DIR_MASK 0x8000 /* GP1_DIR */
2491#define WM2200_GP1_DIR_SHIFT 15 /* GP1_DIR */
2492#define WM2200_GP1_DIR_WIDTH 1 /* GP1_DIR */
2493#define WM2200_GP1_PU 0x4000 /* GP1_PU */
2494#define WM2200_GP1_PU_MASK 0x4000 /* GP1_PU */
2495#define WM2200_GP1_PU_SHIFT 14 /* GP1_PU */
2496#define WM2200_GP1_PU_WIDTH 1 /* GP1_PU */
2497#define WM2200_GP1_PD 0x2000 /* GP1_PD */
2498#define WM2200_GP1_PD_MASK 0x2000 /* GP1_PD */
2499#define WM2200_GP1_PD_SHIFT 13 /* GP1_PD */
2500#define WM2200_GP1_PD_WIDTH 1 /* GP1_PD */
2501#define WM2200_GP1_POL 0x0400 /* GP1_POL */
2502#define WM2200_GP1_POL_MASK 0x0400 /* GP1_POL */
2503#define WM2200_GP1_POL_SHIFT 10 /* GP1_POL */
2504#define WM2200_GP1_POL_WIDTH 1 /* GP1_POL */
2505#define WM2200_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
2506#define WM2200_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
2507#define WM2200_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
2508#define WM2200_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
2509#define WM2200_GP1_DB 0x0100 /* GP1_DB */
2510#define WM2200_GP1_DB_MASK 0x0100 /* GP1_DB */
2511#define WM2200_GP1_DB_SHIFT 8 /* GP1_DB */
2512#define WM2200_GP1_DB_WIDTH 1 /* GP1_DB */
2513#define WM2200_GP1_LVL 0x0040 /* GP1_LVL */
2514#define WM2200_GP1_LVL_MASK 0x0040 /* GP1_LVL */
2515#define WM2200_GP1_LVL_SHIFT 6 /* GP1_LVL */
2516#define WM2200_GP1_LVL_WIDTH 1 /* GP1_LVL */
2517#define WM2200_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */
2518#define WM2200_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */
2519#define WM2200_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */
2520
2521/*
2522 * R1793 (0x701) - GPIO CTRL 2
2523 */
2524#define WM2200_GP2_DIR 0x8000 /* GP2_DIR */
2525#define WM2200_GP2_DIR_MASK 0x8000 /* GP2_DIR */
2526#define WM2200_GP2_DIR_SHIFT 15 /* GP2_DIR */
2527#define WM2200_GP2_DIR_WIDTH 1 /* GP2_DIR */
2528#define WM2200_GP2_PU 0x4000 /* GP2_PU */
2529#define WM2200_GP2_PU_MASK 0x4000 /* GP2_PU */
2530#define WM2200_GP2_PU_SHIFT 14 /* GP2_PU */
2531#define WM2200_GP2_PU_WIDTH 1 /* GP2_PU */
2532#define WM2200_GP2_PD 0x2000 /* GP2_PD */
2533#define WM2200_GP2_PD_MASK 0x2000 /* GP2_PD */
2534#define WM2200_GP2_PD_SHIFT 13 /* GP2_PD */
2535#define WM2200_GP2_PD_WIDTH 1 /* GP2_PD */
2536#define WM2200_GP2_POL 0x0400 /* GP2_POL */
2537#define WM2200_GP2_POL_MASK 0x0400 /* GP2_POL */
2538#define WM2200_GP2_POL_SHIFT 10 /* GP2_POL */
2539#define WM2200_GP2_POL_WIDTH 1 /* GP2_POL */
2540#define WM2200_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
2541#define WM2200_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
2542#define WM2200_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
2543#define WM2200_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
2544#define WM2200_GP2_DB 0x0100 /* GP2_DB */
2545#define WM2200_GP2_DB_MASK 0x0100 /* GP2_DB */
2546#define WM2200_GP2_DB_SHIFT 8 /* GP2_DB */
2547#define WM2200_GP2_DB_WIDTH 1 /* GP2_DB */
2548#define WM2200_GP2_LVL 0x0040 /* GP2_LVL */
2549#define WM2200_GP2_LVL_MASK 0x0040 /* GP2_LVL */
2550#define WM2200_GP2_LVL_SHIFT 6 /* GP2_LVL */
2551#define WM2200_GP2_LVL_WIDTH 1 /* GP2_LVL */
2552#define WM2200_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */
2553#define WM2200_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */
2554#define WM2200_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */
2555
2556/*
2557 * R1794 (0x702) - GPIO CTRL 3
2558 */
2559#define WM2200_GP3_DIR 0x8000 /* GP3_DIR */
2560#define WM2200_GP3_DIR_MASK 0x8000 /* GP3_DIR */
2561#define WM2200_GP3_DIR_SHIFT 15 /* GP3_DIR */
2562#define WM2200_GP3_DIR_WIDTH 1 /* GP3_DIR */
2563#define WM2200_GP3_PU 0x4000 /* GP3_PU */
2564#define WM2200_GP3_PU_MASK 0x4000 /* GP3_PU */
2565#define WM2200_GP3_PU_SHIFT 14 /* GP3_PU */
2566#define WM2200_GP3_PU_WIDTH 1 /* GP3_PU */
2567#define WM2200_GP3_PD 0x2000 /* GP3_PD */
2568#define WM2200_GP3_PD_MASK 0x2000 /* GP3_PD */
2569#define WM2200_GP3_PD_SHIFT 13 /* GP3_PD */
2570#define WM2200_GP3_PD_WIDTH 1 /* GP3_PD */
2571#define WM2200_GP3_POL 0x0400 /* GP3_POL */
2572#define WM2200_GP3_POL_MASK 0x0400 /* GP3_POL */
2573#define WM2200_GP3_POL_SHIFT 10 /* GP3_POL */
2574#define WM2200_GP3_POL_WIDTH 1 /* GP3_POL */
2575#define WM2200_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
2576#define WM2200_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
2577#define WM2200_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
2578#define WM2200_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
2579#define WM2200_GP3_DB 0x0100 /* GP3_DB */
2580#define WM2200_GP3_DB_MASK 0x0100 /* GP3_DB */
2581#define WM2200_GP3_DB_SHIFT 8 /* GP3_DB */
2582#define WM2200_GP3_DB_WIDTH 1 /* GP3_DB */
2583#define WM2200_GP3_LVL 0x0040 /* GP3_LVL */
2584#define WM2200_GP3_LVL_MASK 0x0040 /* GP3_LVL */
2585#define WM2200_GP3_LVL_SHIFT 6 /* GP3_LVL */
2586#define WM2200_GP3_LVL_WIDTH 1 /* GP3_LVL */
2587#define WM2200_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */
2588#define WM2200_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */
2589#define WM2200_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */
2590
2591/*
2592 * R1795 (0x703) - GPIO CTRL 4
2593 */
2594#define WM2200_GP4_DIR 0x8000 /* GP4_DIR */
2595#define WM2200_GP4_DIR_MASK 0x8000 /* GP4_DIR */
2596#define WM2200_GP4_DIR_SHIFT 15 /* GP4_DIR */
2597#define WM2200_GP4_DIR_WIDTH 1 /* GP4_DIR */
2598#define WM2200_GP4_PU 0x4000 /* GP4_PU */
2599#define WM2200_GP4_PU_MASK 0x4000 /* GP4_PU */
2600#define WM2200_GP4_PU_SHIFT 14 /* GP4_PU */
2601#define WM2200_GP4_PU_WIDTH 1 /* GP4_PU */
2602#define WM2200_GP4_PD 0x2000 /* GP4_PD */
2603#define WM2200_GP4_PD_MASK 0x2000 /* GP4_PD */
2604#define WM2200_GP4_PD_SHIFT 13 /* GP4_PD */
2605#define WM2200_GP4_PD_WIDTH 1 /* GP4_PD */
2606#define WM2200_GP4_POL 0x0400 /* GP4_POL */
2607#define WM2200_GP4_POL_MASK 0x0400 /* GP4_POL */
2608#define WM2200_GP4_POL_SHIFT 10 /* GP4_POL */
2609#define WM2200_GP4_POL_WIDTH 1 /* GP4_POL */
2610#define WM2200_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
2611#define WM2200_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
2612#define WM2200_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
2613#define WM2200_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
2614#define WM2200_GP4_DB 0x0100 /* GP4_DB */
2615#define WM2200_GP4_DB_MASK 0x0100 /* GP4_DB */
2616#define WM2200_GP4_DB_SHIFT 8 /* GP4_DB */
2617#define WM2200_GP4_DB_WIDTH 1 /* GP4_DB */
2618#define WM2200_GP4_LVL 0x0040 /* GP4_LVL */
2619#define WM2200_GP4_LVL_MASK 0x0040 /* GP4_LVL */
2620#define WM2200_GP4_LVL_SHIFT 6 /* GP4_LVL */
2621#define WM2200_GP4_LVL_WIDTH 1 /* GP4_LVL */
2622#define WM2200_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */
2623#define WM2200_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */
2624#define WM2200_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */
2625
2626/*
2627 * R1799 (0x707) - ADPS1 IRQ0
2628 */
2629#define WM2200_DSP_IRQ1 0x0002 /* DSP_IRQ1 */
2630#define WM2200_DSP_IRQ1_MASK 0x0002 /* DSP_IRQ1 */
2631#define WM2200_DSP_IRQ1_SHIFT 1 /* DSP_IRQ1 */
2632#define WM2200_DSP_IRQ1_WIDTH 1 /* DSP_IRQ1 */
2633#define WM2200_DSP_IRQ0 0x0001 /* DSP_IRQ0 */
2634#define WM2200_DSP_IRQ0_MASK 0x0001 /* DSP_IRQ0 */
2635#define WM2200_DSP_IRQ0_SHIFT 0 /* DSP_IRQ0 */
2636#define WM2200_DSP_IRQ0_WIDTH 1 /* DSP_IRQ0 */
2637
2638/*
2639 * R1800 (0x708) - ADPS1 IRQ1
2640 */
2641#define WM2200_DSP_IRQ3 0x0002 /* DSP_IRQ3 */
2642#define WM2200_DSP_IRQ3_MASK 0x0002 /* DSP_IRQ3 */
2643#define WM2200_DSP_IRQ3_SHIFT 1 /* DSP_IRQ3 */
2644#define WM2200_DSP_IRQ3_WIDTH 1 /* DSP_IRQ3 */
2645#define WM2200_DSP_IRQ2 0x0001 /* DSP_IRQ2 */
2646#define WM2200_DSP_IRQ2_MASK 0x0001 /* DSP_IRQ2 */
2647#define WM2200_DSP_IRQ2_SHIFT 0 /* DSP_IRQ2 */
2648#define WM2200_DSP_IRQ2_WIDTH 1 /* DSP_IRQ2 */
2649
2650/*
2651 * R1801 (0x709) - Misc Pad Ctrl 1
2652 */
2653#define WM2200_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */
2654#define WM2200_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */
2655#define WM2200_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */
2656#define WM2200_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
2657#define WM2200_MCLK2_PD 0x2000 /* MCLK2_PD */
2658#define WM2200_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */
2659#define WM2200_MCLK2_PD_SHIFT 13 /* MCLK2_PD */
2660#define WM2200_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
2661#define WM2200_MCLK1_PD 0x1000 /* MCLK1_PD */
2662#define WM2200_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */
2663#define WM2200_MCLK1_PD_SHIFT 12 /* MCLK1_PD */
2664#define WM2200_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
2665#define WM2200_DACLRCLK1_PU 0x0400 /* DACLRCLK1_PU */
2666#define WM2200_DACLRCLK1_PU_MASK 0x0400 /* DACLRCLK1_PU */
2667#define WM2200_DACLRCLK1_PU_SHIFT 10 /* DACLRCLK1_PU */
2668#define WM2200_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
2669#define WM2200_DACLRCLK1_PD 0x0200 /* DACLRCLK1_PD */
2670#define WM2200_DACLRCLK1_PD_MASK 0x0200 /* DACLRCLK1_PD */
2671#define WM2200_DACLRCLK1_PD_SHIFT 9 /* DACLRCLK1_PD */
2672#define WM2200_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
2673#define WM2200_BCLK1_PU 0x0100 /* BCLK1_PU */
2674#define WM2200_BCLK1_PU_MASK 0x0100 /* BCLK1_PU */
2675#define WM2200_BCLK1_PU_SHIFT 8 /* BCLK1_PU */
2676#define WM2200_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
2677#define WM2200_BCLK1_PD 0x0080 /* BCLK1_PD */
2678#define WM2200_BCLK1_PD_MASK 0x0080 /* BCLK1_PD */
2679#define WM2200_BCLK1_PD_SHIFT 7 /* BCLK1_PD */
2680#define WM2200_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
2681#define WM2200_DACDAT1_PU 0x0040 /* DACDAT1_PU */
2682#define WM2200_DACDAT1_PU_MASK 0x0040 /* DACDAT1_PU */
2683#define WM2200_DACDAT1_PU_SHIFT 6 /* DACDAT1_PU */
2684#define WM2200_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
2685#define WM2200_DACDAT1_PD 0x0020 /* DACDAT1_PD */
2686#define WM2200_DACDAT1_PD_MASK 0x0020 /* DACDAT1_PD */
2687#define WM2200_DACDAT1_PD_SHIFT 5 /* DACDAT1_PD */
2688#define WM2200_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
2689#define WM2200_DMICDAT3_PD 0x0010 /* DMICDAT3_PD */
2690#define WM2200_DMICDAT3_PD_MASK 0x0010 /* DMICDAT3_PD */
2691#define WM2200_DMICDAT3_PD_SHIFT 4 /* DMICDAT3_PD */
2692#define WM2200_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
2693#define WM2200_DMICDAT2_PD 0x0008 /* DMICDAT2_PD */
2694#define WM2200_DMICDAT2_PD_MASK 0x0008 /* DMICDAT2_PD */
2695#define WM2200_DMICDAT2_PD_SHIFT 3 /* DMICDAT2_PD */
2696#define WM2200_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
2697#define WM2200_DMICDAT1_PD 0x0004 /* DMICDAT1_PD */
2698#define WM2200_DMICDAT1_PD_MASK 0x0004 /* DMICDAT1_PD */
2699#define WM2200_DMICDAT1_PD_SHIFT 2 /* DMICDAT1_PD */
2700#define WM2200_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
2701#define WM2200_RSTB_PU 0x0002 /* RSTB_PU */
2702#define WM2200_RSTB_PU_MASK 0x0002 /* RSTB_PU */
2703#define WM2200_RSTB_PU_SHIFT 1 /* RSTB_PU */
2704#define WM2200_RSTB_PU_WIDTH 1 /* RSTB_PU */
2705#define WM2200_ADDR_PD 0x0001 /* ADDR_PD */
2706#define WM2200_ADDR_PD_MASK 0x0001 /* ADDR_PD */
2707#define WM2200_ADDR_PD_SHIFT 0 /* ADDR_PD */
2708#define WM2200_ADDR_PD_WIDTH 1 /* ADDR_PD */
2709
2710/*
2711 * R2048 (0x800) - Interrupt Status 1
2712 */
2713#define WM2200_DSP_IRQ0_EINT 0x0080 /* DSP_IRQ0_EINT */
2714#define WM2200_DSP_IRQ0_EINT_MASK 0x0080 /* DSP_IRQ0_EINT */
2715#define WM2200_DSP_IRQ0_EINT_SHIFT 7 /* DSP_IRQ0_EINT */
2716#define WM2200_DSP_IRQ0_EINT_WIDTH 1 /* DSP_IRQ0_EINT */
2717#define WM2200_DSP_IRQ1_EINT 0x0040 /* DSP_IRQ1_EINT */
2718#define WM2200_DSP_IRQ1_EINT_MASK 0x0040 /* DSP_IRQ1_EINT */
2719#define WM2200_DSP_IRQ1_EINT_SHIFT 6 /* DSP_IRQ1_EINT */
2720#define WM2200_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */
2721#define WM2200_DSP_IRQ2_EINT 0x0020 /* DSP_IRQ2_EINT */
2722#define WM2200_DSP_IRQ2_EINT_MASK 0x0020 /* DSP_IRQ2_EINT */
2723#define WM2200_DSP_IRQ2_EINT_SHIFT 5 /* DSP_IRQ2_EINT */
2724#define WM2200_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */
2725#define WM2200_DSP_IRQ3_EINT 0x0010 /* DSP_IRQ3_EINT */
2726#define WM2200_DSP_IRQ3_EINT_MASK 0x0010 /* DSP_IRQ3_EINT */
2727#define WM2200_DSP_IRQ3_EINT_SHIFT 4 /* DSP_IRQ3_EINT */
2728#define WM2200_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */
2729#define WM2200_GP4_EINT 0x0008 /* GP4_EINT */
2730#define WM2200_GP4_EINT_MASK 0x0008 /* GP4_EINT */
2731#define WM2200_GP4_EINT_SHIFT 3 /* GP4_EINT */
2732#define WM2200_GP4_EINT_WIDTH 1 /* GP4_EINT */
2733#define WM2200_GP3_EINT 0x0004 /* GP3_EINT */
2734#define WM2200_GP3_EINT_MASK 0x0004 /* GP3_EINT */
2735#define WM2200_GP3_EINT_SHIFT 2 /* GP3_EINT */
2736#define WM2200_GP3_EINT_WIDTH 1 /* GP3_EINT */
2737#define WM2200_GP2_EINT 0x0002 /* GP2_EINT */
2738#define WM2200_GP2_EINT_MASK 0x0002 /* GP2_EINT */
2739#define WM2200_GP2_EINT_SHIFT 1 /* GP2_EINT */
2740#define WM2200_GP2_EINT_WIDTH 1 /* GP2_EINT */
2741#define WM2200_GP1_EINT 0x0001 /* GP1_EINT */
2742#define WM2200_GP1_EINT_MASK 0x0001 /* GP1_EINT */
2743#define WM2200_GP1_EINT_SHIFT 0 /* GP1_EINT */
2744#define WM2200_GP1_EINT_WIDTH 1 /* GP1_EINT */
2745
2746/*
2747 * R2049 (0x801) - Interrupt Status 1 Mask
2748 */
2749#define WM2200_IM_DSP_IRQ0_EINT 0x0080 /* IM_DSP_IRQ0_EINT */
2750#define WM2200_IM_DSP_IRQ0_EINT_MASK 0x0080 /* IM_DSP_IRQ0_EINT */
2751#define WM2200_IM_DSP_IRQ0_EINT_SHIFT 7 /* IM_DSP_IRQ0_EINT */
2752#define WM2200_IM_DSP_IRQ0_EINT_WIDTH 1 /* IM_DSP_IRQ0_EINT */
2753#define WM2200_IM_DSP_IRQ1_EINT 0x0040 /* IM_DSP_IRQ1_EINT */
2754#define WM2200_IM_DSP_IRQ1_EINT_MASK 0x0040 /* IM_DSP_IRQ1_EINT */
2755#define WM2200_IM_DSP_IRQ1_EINT_SHIFT 6 /* IM_DSP_IRQ1_EINT */
2756#define WM2200_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */
2757#define WM2200_IM_DSP_IRQ2_EINT 0x0020 /* IM_DSP_IRQ2_EINT */
2758#define WM2200_IM_DSP_IRQ2_EINT_MASK 0x0020 /* IM_DSP_IRQ2_EINT */
2759#define WM2200_IM_DSP_IRQ2_EINT_SHIFT 5 /* IM_DSP_IRQ2_EINT */
2760#define WM2200_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */
2761#define WM2200_IM_DSP_IRQ3_EINT 0x0010 /* IM_DSP_IRQ3_EINT */
2762#define WM2200_IM_DSP_IRQ3_EINT_MASK 0x0010 /* IM_DSP_IRQ3_EINT */
2763#define WM2200_IM_DSP_IRQ3_EINT_SHIFT 4 /* IM_DSP_IRQ3_EINT */
2764#define WM2200_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */
2765#define WM2200_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
2766#define WM2200_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
2767#define WM2200_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
2768#define WM2200_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
2769#define WM2200_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
2770#define WM2200_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
2771#define WM2200_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
2772#define WM2200_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
2773#define WM2200_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
2774#define WM2200_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
2775#define WM2200_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
2776#define WM2200_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
2777#define WM2200_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
2778#define WM2200_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
2779#define WM2200_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
2780#define WM2200_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
2781
2782/*
2783 * R2050 (0x802) - Interrupt Status 2
2784 */
2785#define WM2200_WSEQ_BUSY_EINT 0x0100 /* WSEQ_BUSY_EINT */
2786#define WM2200_WSEQ_BUSY_EINT_MASK 0x0100 /* WSEQ_BUSY_EINT */
2787#define WM2200_WSEQ_BUSY_EINT_SHIFT 8 /* WSEQ_BUSY_EINT */
2788#define WM2200_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */
2789#define WM2200_FLL_LOCK_EINT 0x0002 /* FLL_LOCK_EINT */
2790#define WM2200_FLL_LOCK_EINT_MASK 0x0002 /* FLL_LOCK_EINT */
2791#define WM2200_FLL_LOCK_EINT_SHIFT 1 /* FLL_LOCK_EINT */
2792#define WM2200_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
2793#define WM2200_CLKGEN_EINT 0x0001 /* CLKGEN_EINT */
2794#define WM2200_CLKGEN_EINT_MASK 0x0001 /* CLKGEN_EINT */
2795#define WM2200_CLKGEN_EINT_SHIFT 0 /* CLKGEN_EINT */
2796#define WM2200_CLKGEN_EINT_WIDTH 1 /* CLKGEN_EINT */
2797
2798/*
2799 * R2051 (0x803) - Interrupt Raw Status 2
2800 */
2801#define WM2200_WSEQ_BUSY_STS 0x0100 /* WSEQ_BUSY_STS */
2802#define WM2200_WSEQ_BUSY_STS_MASK 0x0100 /* WSEQ_BUSY_STS */
2803#define WM2200_WSEQ_BUSY_STS_SHIFT 8 /* WSEQ_BUSY_STS */
2804#define WM2200_WSEQ_BUSY_STS_WIDTH 1 /* WSEQ_BUSY_STS */
2805#define WM2200_FLL_LOCK_STS 0x0002 /* FLL_LOCK_STS */
2806#define WM2200_FLL_LOCK_STS_MASK 0x0002 /* FLL_LOCK_STS */
2807#define WM2200_FLL_LOCK_STS_SHIFT 1 /* FLL_LOCK_STS */
2808#define WM2200_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
2809#define WM2200_CLKGEN_STS 0x0001 /* CLKGEN_STS */
2810#define WM2200_CLKGEN_STS_MASK 0x0001 /* CLKGEN_STS */
2811#define WM2200_CLKGEN_STS_SHIFT 0 /* CLKGEN_STS */
2812#define WM2200_CLKGEN_STS_WIDTH 1 /* CLKGEN_STS */
2813
2814/*
2815 * R2052 (0x804) - Interrupt Status 2 Mask
2816 */
2817#define WM2200_IM_WSEQ_BUSY_EINT 0x0100 /* IM_WSEQ_BUSY_EINT */
2818#define WM2200_IM_WSEQ_BUSY_EINT_MASK 0x0100 /* IM_WSEQ_BUSY_EINT */
2819#define WM2200_IM_WSEQ_BUSY_EINT_SHIFT 8 /* IM_WSEQ_BUSY_EINT */
2820#define WM2200_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */
2821#define WM2200_IM_FLL_LOCK_EINT 0x0002 /* IM_FLL_LOCK_EINT */
2822#define WM2200_IM_FLL_LOCK_EINT_MASK 0x0002 /* IM_FLL_LOCK_EINT */
2823#define WM2200_IM_FLL_LOCK_EINT_SHIFT 1 /* IM_FLL_LOCK_EINT */
2824#define WM2200_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
2825#define WM2200_IM_CLKGEN_EINT 0x0001 /* IM_CLKGEN_EINT */
2826#define WM2200_IM_CLKGEN_EINT_MASK 0x0001 /* IM_CLKGEN_EINT */
2827#define WM2200_IM_CLKGEN_EINT_SHIFT 0 /* IM_CLKGEN_EINT */
2828#define WM2200_IM_CLKGEN_EINT_WIDTH 1 /* IM_CLKGEN_EINT */
2829
2830/*
2831 * R2056 (0x808) - Interrupt Control
2832 */
2833#define WM2200_IM_IRQ 0x0001 /* IM_IRQ */
2834#define WM2200_IM_IRQ_MASK 0x0001 /* IM_IRQ */
2835#define WM2200_IM_IRQ_SHIFT 0 /* IM_IRQ */
2836#define WM2200_IM_IRQ_WIDTH 1 /* IM_IRQ */
2837
2838/*
2839 * R2304 (0x900) - EQL_1
2840 */
2841#define WM2200_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */
2842#define WM2200_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */
2843#define WM2200_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */
2844#define WM2200_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */
2845#define WM2200_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */
2846#define WM2200_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */
2847#define WM2200_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */
2848#define WM2200_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */
2849#define WM2200_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */
2850#define WM2200_EQL_ENA 0x0001 /* EQL_ENA */
2851#define WM2200_EQL_ENA_MASK 0x0001 /* EQL_ENA */
2852#define WM2200_EQL_ENA_SHIFT 0 /* EQL_ENA */
2853#define WM2200_EQL_ENA_WIDTH 1 /* EQL_ENA */
2854
2855/*
2856 * R2305 (0x901) - EQL_2
2857 */
2858#define WM2200_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */
2859#define WM2200_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */
2860#define WM2200_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */
2861#define WM2200_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */
2862#define WM2200_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */
2863#define WM2200_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */
2864
2865/*
2866 * R2306 (0x902) - EQL_3
2867 */
2868#define WM2200_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */
2869#define WM2200_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */
2870#define WM2200_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */
2871
2872/*
2873 * R2307 (0x903) - EQL_4
2874 */
2875#define WM2200_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */
2876#define WM2200_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */
2877#define WM2200_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */
2878
2879/*
2880 * R2308 (0x904) - EQL_5
2881 */
2882#define WM2200_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */
2883#define WM2200_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */
2884#define WM2200_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */
2885
2886/*
2887 * R2309 (0x905) - EQL_6
2888 */
2889#define WM2200_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */
2890#define WM2200_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */
2891#define WM2200_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */
2892
2893/*
2894 * R2310 (0x906) - EQL_7
2895 */
2896#define WM2200_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */
2897#define WM2200_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */
2898#define WM2200_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */
2899
2900/*
2901 * R2311 (0x907) - EQL_8
2902 */
2903#define WM2200_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */
2904#define WM2200_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */
2905#define WM2200_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */
2906
2907/*
2908 * R2312 (0x908) - EQL_9
2909 */
2910#define WM2200_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */
2911#define WM2200_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */
2912#define WM2200_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */
2913
2914/*
2915 * R2313 (0x909) - EQL_10
2916 */
2917#define WM2200_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */
2918#define WM2200_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */
2919#define WM2200_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */
2920
2921/*
2922 * R2314 (0x90A) - EQL_11
2923 */
2924#define WM2200_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */
2925#define WM2200_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */
2926#define WM2200_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */
2927
2928/*
2929 * R2315 (0x90B) - EQL_12
2930 */
2931#define WM2200_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */
2932#define WM2200_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */
2933#define WM2200_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */
2934
2935/*
2936 * R2316 (0x90C) - EQL_13
2937 */
2938#define WM2200_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */
2939#define WM2200_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */
2940#define WM2200_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */
2941
2942/*
2943 * R2317 (0x90D) - EQL_14
2944 */
2945#define WM2200_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */
2946#define WM2200_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */
2947#define WM2200_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */
2948
2949/*
2950 * R2318 (0x90E) - EQL_15
2951 */
2952#define WM2200_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */
2953#define WM2200_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */
2954#define WM2200_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */
2955
2956/*
2957 * R2319 (0x90F) - EQL_16
2958 */
2959#define WM2200_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */
2960#define WM2200_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */
2961#define WM2200_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */
2962
2963/*
2964 * R2320 (0x910) - EQL_17
2965 */
2966#define WM2200_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */
2967#define WM2200_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */
2968#define WM2200_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */
2969
2970/*
2971 * R2321 (0x911) - EQL_18
2972 */
2973#define WM2200_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */
2974#define WM2200_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */
2975#define WM2200_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */
2976
2977/*
2978 * R2322 (0x912) - EQL_19
2979 */
2980#define WM2200_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */
2981#define WM2200_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */
2982#define WM2200_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */
2983
2984/*
2985 * R2323 (0x913) - EQL_20
2986 */
2987#define WM2200_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */
2988#define WM2200_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */
2989#define WM2200_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */
2990
2991/*
2992 * R2326 (0x916) - EQR_1
2993 */
2994#define WM2200_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */
2995#define WM2200_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */
2996#define WM2200_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */
2997#define WM2200_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */
2998#define WM2200_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */
2999#define WM2200_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */
3000#define WM2200_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */
3001#define WM2200_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */
3002#define WM2200_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */
3003#define WM2200_EQR_ENA 0x0001 /* EQR_ENA */
3004#define WM2200_EQR_ENA_MASK 0x0001 /* EQR_ENA */
3005#define WM2200_EQR_ENA_SHIFT 0 /* EQR_ENA */
3006#define WM2200_EQR_ENA_WIDTH 1 /* EQR_ENA */
3007
3008/*
3009 * R2327 (0x917) - EQR_2
3010 */
3011#define WM2200_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */
3012#define WM2200_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */
3013#define WM2200_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */
3014#define WM2200_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */
3015#define WM2200_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */
3016#define WM2200_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */
3017
3018/*
3019 * R2328 (0x918) - EQR_3
3020 */
3021#define WM2200_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */
3022#define WM2200_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */
3023#define WM2200_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */
3024
3025/*
3026 * R2329 (0x919) - EQR_4
3027 */
3028#define WM2200_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */
3029#define WM2200_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */
3030#define WM2200_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */
3031
3032/*
3033 * R2330 (0x91A) - EQR_5
3034 */
3035#define WM2200_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */
3036#define WM2200_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */
3037#define WM2200_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */
3038
3039/*
3040 * R2331 (0x91B) - EQR_6
3041 */
3042#define WM2200_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */
3043#define WM2200_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */
3044#define WM2200_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */
3045
3046/*
3047 * R2332 (0x91C) - EQR_7
3048 */
3049#define WM2200_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */
3050#define WM2200_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */
3051#define WM2200_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */
3052
3053/*
3054 * R2333 (0x91D) - EQR_8
3055 */
3056#define WM2200_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */
3057#define WM2200_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */
3058#define WM2200_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */
3059
3060/*
3061 * R2334 (0x91E) - EQR_9
3062 */
3063#define WM2200_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */
3064#define WM2200_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */
3065#define WM2200_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */
3066
3067/*
3068 * R2335 (0x91F) - EQR_10
3069 */
3070#define WM2200_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */
3071#define WM2200_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */
3072#define WM2200_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */
3073
3074/*
3075 * R2336 (0x920) - EQR_11
3076 */
3077#define WM2200_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */
3078#define WM2200_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */
3079#define WM2200_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */
3080
3081/*
3082 * R2337 (0x921) - EQR_12
3083 */
3084#define WM2200_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */
3085#define WM2200_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */
3086#define WM2200_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */
3087
3088/*
3089 * R2338 (0x922) - EQR_13
3090 */
3091#define WM2200_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */
3092#define WM2200_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */
3093#define WM2200_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */
3094
3095/*
3096 * R2339 (0x923) - EQR_14
3097 */
3098#define WM2200_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */
3099#define WM2200_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */
3100#define WM2200_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */
3101
3102/*
3103 * R2340 (0x924) - EQR_15
3104 */
3105#define WM2200_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */
3106#define WM2200_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */
3107#define WM2200_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */
3108
3109/*
3110 * R2341 (0x925) - EQR_16
3111 */
3112#define WM2200_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */
3113#define WM2200_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */
3114#define WM2200_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */
3115
3116/*
3117 * R2342 (0x926) - EQR_17
3118 */
3119#define WM2200_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */
3120#define WM2200_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */
3121#define WM2200_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */
3122
3123/*
3124 * R2343 (0x927) - EQR_18
3125 */
3126#define WM2200_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */
3127#define WM2200_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */
3128#define WM2200_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */
3129
3130/*
3131 * R2344 (0x928) - EQR_19
3132 */
3133#define WM2200_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */
3134#define WM2200_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */
3135#define WM2200_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */
3136
3137/*
3138 * R2345 (0x929) - EQR_20
3139 */
3140#define WM2200_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */
3141#define WM2200_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */
3142#define WM2200_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */
3143
3144/*
3145 * R2366 (0x93E) - HPLPF1_1
3146 */
3147#define WM2200_LHPF1_MODE 0x0002 /* LHPF1_MODE */
3148#define WM2200_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */
3149#define WM2200_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */
3150#define WM2200_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */
3151#define WM2200_LHPF1_ENA 0x0001 /* LHPF1_ENA */
3152#define WM2200_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */
3153#define WM2200_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */
3154#define WM2200_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */
3155
3156/*
3157 * R2367 (0x93F) - HPLPF1_2
3158 */
3159#define WM2200_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */
3160#define WM2200_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */
3161#define WM2200_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */
3162
3163/*
3164 * R2370 (0x942) - HPLPF2_1
3165 */
3166#define WM2200_LHPF2_MODE 0x0002 /* LHPF2_MODE */
3167#define WM2200_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */
3168#define WM2200_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */
3169#define WM2200_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */
3170#define WM2200_LHPF2_ENA 0x0001 /* LHPF2_ENA */
3171#define WM2200_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */
3172#define WM2200_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */
3173#define WM2200_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */
3174
3175/*
3176 * R2371 (0x943) - HPLPF2_2
3177 */
3178#define WM2200_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */
3179#define WM2200_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */
3180#define WM2200_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */
3181
3182/*
3183 * R2560 (0xA00) - DSP1 Control 1
3184 */
3185#define WM2200_DSP1_RW_SEQUENCE_ENA 0x0001 /* DSP1_RW_SEQUENCE_ENA */
3186#define WM2200_DSP1_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP1_RW_SEQUENCE_ENA */
3187#define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT 0 /* DSP1_RW_SEQUENCE_ENA */
3188#define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH 1 /* DSP1_RW_SEQUENCE_ENA */
3189
3190/*
3191 * R2562 (0xA02) - DSP1 Control 2
3192 */
3193#define WM2200_DSP1_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_PM - [15:8] */
3194#define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT 8 /* DSP1_PAGE_BASE_PM - [15:8] */
3195#define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH 8 /* DSP1_PAGE_BASE_PM - [15:8] */
3196
3197/*
3198 * R2563 (0xA03) - DSP1 Control 3
3199 */
3200#define WM2200_DSP1_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_DM - [15:8] */
3201#define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT 8 /* DSP1_PAGE_BASE_DM - [15:8] */
3202#define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH 8 /* DSP1_PAGE_BASE_DM - [15:8] */
3203
3204/*
3205 * R2564 (0xA04) - DSP1 Control 4
3206 */
3207#define WM2200_DSP1_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_ZM - [15:8] */
3208#define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
3209#define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH 8 /* DSP1_PAGE_BASE_ZM - [15:8] */
3210
3211/*
3212 * R2566 (0xA06) - DSP1 Control 5
3213 */
3214#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3215#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3216#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3217
3218/*
3219 * R2567 (0xA07) - DSP1 Control 6
3220 */
3221#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3222#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3223#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3224
3225/*
3226 * R2568 (0xA08) - DSP1 Control 7
3227 */
3228#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3229#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3230#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3231
3232/*
3233 * R2569 (0xA09) - DSP1 Control 8
3234 */
3235#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3236#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3237#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3238
3239/*
3240 * R2570 (0xA0A) - DSP1 Control 9
3241 */
3242#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3243#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3244#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3245
3246/*
3247 * R2571 (0xA0B) - DSP1 Control 10
3248 */
3249#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3250#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3251#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3252
3253/*
3254 * R2572 (0xA0C) - DSP1 Control 11
3255 */
3256#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3257#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3258#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3259
3260/*
3261 * R2573 (0xA0D) - DSP1 Control 12
3262 */
3263#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3264#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3265#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3266
3267/*
3268 * R2575 (0xA0F) - DSP1 Control 13
3269 */
3270#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3271#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3272#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3273
3274/*
3275 * R2576 (0xA10) - DSP1 Control 14
3276 */
3277#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3278#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3279#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3280
3281/*
3282 * R2577 (0xA11) - DSP1 Control 15
3283 */
3284#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3285#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3286#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3287
3288/*
3289 * R2578 (0xA12) - DSP1 Control 16
3290 */
3291#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3292#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3293#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3294
3295/*
3296 * R2579 (0xA13) - DSP1 Control 17
3297 */
3298#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3299#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3300#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3301
3302/*
3303 * R2580 (0xA14) - DSP1 Control 18
3304 */
3305#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3306#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3307#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3308
3309/*
3310 * R2582 (0xA16) - DSP1 Control 19
3311 */
3312#define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3313#define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3314#define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
3315
3316/*
3317 * R2583 (0xA17) - DSP1 Control 20
3318 */
3319#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3320#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3321#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
3322
3323/*
3324 * R2584 (0xA18) - DSP1 Control 21
3325 */
3326#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3327#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3328#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
3329
3330/*
3331 * R2586 (0xA1A) - DSP1 Control 22
3332 */
3333#define WM2200_DSP1_DM_SIZE_MASK 0xFFFF /* DSP1_DM_SIZE - [15:0] */
3334#define WM2200_DSP1_DM_SIZE_SHIFT 0 /* DSP1_DM_SIZE - [15:0] */
3335#define WM2200_DSP1_DM_SIZE_WIDTH 16 /* DSP1_DM_SIZE - [15:0] */
3336
3337/*
3338 * R2587 (0xA1B) - DSP1 Control 23
3339 */
3340#define WM2200_DSP1_PM_SIZE_MASK 0xFFFF /* DSP1_PM_SIZE - [15:0] */
3341#define WM2200_DSP1_PM_SIZE_SHIFT 0 /* DSP1_PM_SIZE - [15:0] */
3342#define WM2200_DSP1_PM_SIZE_WIDTH 16 /* DSP1_PM_SIZE - [15:0] */
3343
3344/*
3345 * R2588 (0xA1C) - DSP1 Control 24
3346 */
3347#define WM2200_DSP1_ZM_SIZE_MASK 0xFFFF /* DSP1_ZM_SIZE - [15:0] */
3348#define WM2200_DSP1_ZM_SIZE_SHIFT 0 /* DSP1_ZM_SIZE - [15:0] */
3349#define WM2200_DSP1_ZM_SIZE_WIDTH 16 /* DSP1_ZM_SIZE - [15:0] */
3350
3351/*
3352 * R2590 (0xA1E) - DSP1 Control 25
3353 */
3354#define WM2200_DSP1_PING_FULL 0x8000 /* DSP1_PING_FULL */
3355#define WM2200_DSP1_PING_FULL_MASK 0x8000 /* DSP1_PING_FULL */
3356#define WM2200_DSP1_PING_FULL_SHIFT 15 /* DSP1_PING_FULL */
3357#define WM2200_DSP1_PING_FULL_WIDTH 1 /* DSP1_PING_FULL */
3358#define WM2200_DSP1_PONG_FULL 0x4000 /* DSP1_PONG_FULL */
3359#define WM2200_DSP1_PONG_FULL_MASK 0x4000 /* DSP1_PONG_FULL */
3360#define WM2200_DSP1_PONG_FULL_SHIFT 14 /* DSP1_PONG_FULL */
3361#define WM2200_DSP1_PONG_FULL_WIDTH 1 /* DSP1_PONG_FULL */
3362#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3363#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3364#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
3365
3366/*
3367 * R2592 (0xA20) - DSP1 Control 26
3368 */
3369#define WM2200_DSP1_SCRATCH_0_MASK 0xFFFF /* DSP1_SCRATCH_0 - [15:0] */
3370#define WM2200_DSP1_SCRATCH_0_SHIFT 0 /* DSP1_SCRATCH_0 - [15:0] */
3371#define WM2200_DSP1_SCRATCH_0_WIDTH 16 /* DSP1_SCRATCH_0 - [15:0] */
3372
3373/*
3374 * R2593 (0xA21) - DSP1 Control 27
3375 */
3376#define WM2200_DSP1_SCRATCH_1_MASK 0xFFFF /* DSP1_SCRATCH_1 - [15:0] */
3377#define WM2200_DSP1_SCRATCH_1_SHIFT 0 /* DSP1_SCRATCH_1 - [15:0] */
3378#define WM2200_DSP1_SCRATCH_1_WIDTH 16 /* DSP1_SCRATCH_1 - [15:0] */
3379
3380/*
3381 * R2594 (0xA22) - DSP1 Control 28
3382 */
3383#define WM2200_DSP1_SCRATCH_2_MASK 0xFFFF /* DSP1_SCRATCH_2 - [15:0] */
3384#define WM2200_DSP1_SCRATCH_2_SHIFT 0 /* DSP1_SCRATCH_2 - [15:0] */
3385#define WM2200_DSP1_SCRATCH_2_WIDTH 16 /* DSP1_SCRATCH_2 - [15:0] */
3386
3387/*
3388 * R2595 (0xA23) - DSP1 Control 29
3389 */
3390#define WM2200_DSP1_SCRATCH_3_MASK 0xFFFF /* DSP1_SCRATCH_3 - [15:0] */
3391#define WM2200_DSP1_SCRATCH_3_SHIFT 0 /* DSP1_SCRATCH_3 - [15:0] */
3392#define WM2200_DSP1_SCRATCH_3_WIDTH 16 /* DSP1_SCRATCH_3 - [15:0] */
3393
3394/*
3395 * R2596 (0xA24) - DSP1 Control 30
3396 */
3397#define WM2200_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */
3398#define WM2200_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */
3399#define WM2200_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */
3400#define WM2200_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */
3401#define WM2200_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */
3402#define WM2200_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */
3403#define WM2200_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */
3404#define WM2200_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */
3405#define WM2200_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */
3406#define WM2200_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */
3407#define WM2200_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */
3408#define WM2200_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */
3409#define WM2200_DSP1_START 0x0001 /* DSP1_START */
3410#define WM2200_DSP1_START_MASK 0x0001 /* DSP1_START */
3411#define WM2200_DSP1_START_SHIFT 0 /* DSP1_START */
3412#define WM2200_DSP1_START_WIDTH 1 /* DSP1_START */
3413
3414/*
3415 * R2598 (0xA26) - DSP1 Control 31
3416 */
3417#define WM2200_DSP1_CLK_RATE_MASK 0x0018 /* DSP1_CLK_RATE - [4:3] */
3418#define WM2200_DSP1_CLK_RATE_SHIFT 3 /* DSP1_CLK_RATE - [4:3] */
3419#define WM2200_DSP1_CLK_RATE_WIDTH 2 /* DSP1_CLK_RATE - [4:3] */
3420#define WM2200_DSP1_CLK_AVAIL 0x0004 /* DSP1_CLK_AVAIL */
3421#define WM2200_DSP1_CLK_AVAIL_MASK 0x0004 /* DSP1_CLK_AVAIL */
3422#define WM2200_DSP1_CLK_AVAIL_SHIFT 2 /* DSP1_CLK_AVAIL */
3423#define WM2200_DSP1_CLK_AVAIL_WIDTH 1 /* DSP1_CLK_AVAIL */
3424#define WM2200_DSP1_CLK_REQ_MASK 0x0003 /* DSP1_CLK_REQ - [1:0] */
3425#define WM2200_DSP1_CLK_REQ_SHIFT 0 /* DSP1_CLK_REQ - [1:0] */
3426#define WM2200_DSP1_CLK_REQ_WIDTH 2 /* DSP1_CLK_REQ - [1:0] */
3427
3428/*
3429 * R2816 (0xB00) - DSP2 Control 1
3430 */
3431#define WM2200_DSP2_RW_SEQUENCE_ENA 0x0001 /* DSP2_RW_SEQUENCE_ENA */
3432#define WM2200_DSP2_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP2_RW_SEQUENCE_ENA */
3433#define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT 0 /* DSP2_RW_SEQUENCE_ENA */
3434#define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH 1 /* DSP2_RW_SEQUENCE_ENA */
3435
3436/*
3437 * R2818 (0xB02) - DSP2 Control 2
3438 */
3439#define WM2200_DSP2_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_PM - [15:8] */
3440#define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT 8 /* DSP2_PAGE_BASE_PM - [15:8] */
3441#define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH 8 /* DSP2_PAGE_BASE_PM - [15:8] */
3442
3443/*
3444 * R2819 (0xB03) - DSP2 Control 3
3445 */
3446#define WM2200_DSP2_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_DM - [15:8] */
3447#define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT 8 /* DSP2_PAGE_BASE_DM - [15:8] */
3448#define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH 8 /* DSP2_PAGE_BASE_DM - [15:8] */
3449
3450/*
3451 * R2820 (0xB04) - DSP2 Control 4
3452 */
3453#define WM2200_DSP2_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_ZM - [15:8] */
3454#define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
3455#define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH 8 /* DSP2_PAGE_BASE_ZM - [15:8] */
3456
3457/*
3458 * R2822 (0xB06) - DSP2 Control 5
3459 */
3460#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3461#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3462#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
3463
3464/*
3465 * R2823 (0xB07) - DSP2 Control 6
3466 */
3467#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3468#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3469#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
3470
3471/*
3472 * R2824 (0xB08) - DSP2 Control 7
3473 */
3474#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3475#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3476#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
3477
3478/*
3479 * R2825 (0xB09) - DSP2 Control 8
3480 */
3481#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3482#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3483#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
3484
3485/*
3486 * R2826 (0xB0A) - DSP2 Control 9
3487 */
3488#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3489#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3490#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
3491
3492/*
3493 * R2827 (0xB0B) - DSP2 Control 10
3494 */
3495#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3496#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3497#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
3498
3499/*
3500 * R2828 (0xB0C) - DSP2 Control 11
3501 */
3502#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3503#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3504#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
3505
3506/*
3507 * R2829 (0xB0D) - DSP2 Control 12
3508 */
3509#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3510#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3511#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
3512
3513/*
3514 * R2831 (0xB0F) - DSP2 Control 13
3515 */
3516#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3517#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3518#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
3519
3520/*
3521 * R2832 (0xB10) - DSP2 Control 14
3522 */
3523#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3524#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3525#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
3526
3527/*
3528 * R2833 (0xB11) - DSP2 Control 15
3529 */
3530#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3531#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3532#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
3533
3534/*
3535 * R2834 (0xB12) - DSP2 Control 16
3536 */
3537#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3538#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3539#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
3540
3541/*
3542 * R2835 (0xB13) - DSP2 Control 17
3543 */
3544#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3545#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3546#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
3547
3548/*
3549 * R2836 (0xB14) - DSP2 Control 18
3550 */
3551#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3552#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3553#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
3554
3555/*
3556 * R2838 (0xB16) - DSP2 Control 19
3557 */
3558#define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3559#define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3560#define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
3561
3562/*
3563 * R2839 (0xB17) - DSP2 Control 20
3564 */
3565#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3566#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3567#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
3568
3569/*
3570 * R2840 (0xB18) - DSP2 Control 21
3571 */
3572#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3573#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3574#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
3575
3576/*
3577 * R2842 (0xB1A) - DSP2 Control 22
3578 */
3579#define WM2200_DSP2_DM_SIZE_MASK 0xFFFF /* DSP2_DM_SIZE - [15:0] */
3580#define WM2200_DSP2_DM_SIZE_SHIFT 0 /* DSP2_DM_SIZE - [15:0] */
3581#define WM2200_DSP2_DM_SIZE_WIDTH 16 /* DSP2_DM_SIZE - [15:0] */
3582
3583/*
3584 * R2843 (0xB1B) - DSP2 Control 23
3585 */
3586#define WM2200_DSP2_PM_SIZE_MASK 0xFFFF /* DSP2_PM_SIZE - [15:0] */
3587#define WM2200_DSP2_PM_SIZE_SHIFT 0 /* DSP2_PM_SIZE - [15:0] */
3588#define WM2200_DSP2_PM_SIZE_WIDTH 16 /* DSP2_PM_SIZE - [15:0] */
3589
3590/*
3591 * R2844 (0xB1C) - DSP2 Control 24
3592 */
3593#define WM2200_DSP2_ZM_SIZE_MASK 0xFFFF /* DSP2_ZM_SIZE - [15:0] */
3594#define WM2200_DSP2_ZM_SIZE_SHIFT 0 /* DSP2_ZM_SIZE - [15:0] */
3595#define WM2200_DSP2_ZM_SIZE_WIDTH 16 /* DSP2_ZM_SIZE - [15:0] */
3596
3597/*
3598 * R2846 (0xB1E) - DSP2 Control 25
3599 */
3600#define WM2200_DSP2_PING_FULL 0x8000 /* DSP2_PING_FULL */
3601#define WM2200_DSP2_PING_FULL_MASK 0x8000 /* DSP2_PING_FULL */
3602#define WM2200_DSP2_PING_FULL_SHIFT 15 /* DSP2_PING_FULL */
3603#define WM2200_DSP2_PING_FULL_WIDTH 1 /* DSP2_PING_FULL */
3604#define WM2200_DSP2_PONG_FULL 0x4000 /* DSP2_PONG_FULL */
3605#define WM2200_DSP2_PONG_FULL_MASK 0x4000 /* DSP2_PONG_FULL */
3606#define WM2200_DSP2_PONG_FULL_SHIFT 14 /* DSP2_PONG_FULL */
3607#define WM2200_DSP2_PONG_FULL_WIDTH 1 /* DSP2_PONG_FULL */
3608#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3609#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3610#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
3611
3612/*
3613 * R2848 (0xB20) - DSP2 Control 26
3614 */
3615#define WM2200_DSP2_SCRATCH_0_MASK 0xFFFF /* DSP2_SCRATCH_0 - [15:0] */
3616#define WM2200_DSP2_SCRATCH_0_SHIFT 0 /* DSP2_SCRATCH_0 - [15:0] */
3617#define WM2200_DSP2_SCRATCH_0_WIDTH 16 /* DSP2_SCRATCH_0 - [15:0] */
3618
3619/*
3620 * R2849 (0xB21) - DSP2 Control 27
3621 */
3622#define WM2200_DSP2_SCRATCH_1_MASK 0xFFFF /* DSP2_SCRATCH_1 - [15:0] */
3623#define WM2200_DSP2_SCRATCH_1_SHIFT 0 /* DSP2_SCRATCH_1 - [15:0] */
3624#define WM2200_DSP2_SCRATCH_1_WIDTH 16 /* DSP2_SCRATCH_1 - [15:0] */
3625
3626/*
3627 * R2850 (0xB22) - DSP2 Control 28
3628 */
3629#define WM2200_DSP2_SCRATCH_2_MASK 0xFFFF /* DSP2_SCRATCH_2 - [15:0] */
3630#define WM2200_DSP2_SCRATCH_2_SHIFT 0 /* DSP2_SCRATCH_2 - [15:0] */
3631#define WM2200_DSP2_SCRATCH_2_WIDTH 16 /* DSP2_SCRATCH_2 - [15:0] */
3632
3633/*
3634 * R2851 (0xB23) - DSP2 Control 29
3635 */
3636#define WM2200_DSP2_SCRATCH_3_MASK 0xFFFF /* DSP2_SCRATCH_3 - [15:0] */
3637#define WM2200_DSP2_SCRATCH_3_SHIFT 0 /* DSP2_SCRATCH_3 - [15:0] */
3638#define WM2200_DSP2_SCRATCH_3_WIDTH 16 /* DSP2_SCRATCH_3 - [15:0] */
3639
3640/*
3641 * R2852 (0xB24) - DSP2 Control 30
3642 */
3643#define WM2200_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */
3644#define WM2200_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */
3645#define WM2200_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */
3646#define WM2200_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */
3647#define WM2200_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */
3648#define WM2200_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */
3649#define WM2200_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */
3650#define WM2200_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */
3651#define WM2200_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */
3652#define WM2200_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */
3653#define WM2200_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */
3654#define WM2200_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */
3655#define WM2200_DSP2_START 0x0001 /* DSP2_START */
3656#define WM2200_DSP2_START_MASK 0x0001 /* DSP2_START */
3657#define WM2200_DSP2_START_SHIFT 0 /* DSP2_START */
3658#define WM2200_DSP2_START_WIDTH 1 /* DSP2_START */
3659
3660/*
3661 * R2854 (0xB26) - DSP2 Control 31
3662 */
3663#define WM2200_DSP2_CLK_RATE_MASK 0x0018 /* DSP2_CLK_RATE - [4:3] */
3664#define WM2200_DSP2_CLK_RATE_SHIFT 3 /* DSP2_CLK_RATE - [4:3] */
3665#define WM2200_DSP2_CLK_RATE_WIDTH 2 /* DSP2_CLK_RATE - [4:3] */
3666#define WM2200_DSP2_CLK_AVAIL 0x0004 /* DSP2_CLK_AVAIL */
3667#define WM2200_DSP2_CLK_AVAIL_MASK 0x0004 /* DSP2_CLK_AVAIL */
3668#define WM2200_DSP2_CLK_AVAIL_SHIFT 2 /* DSP2_CLK_AVAIL */
3669#define WM2200_DSP2_CLK_AVAIL_WIDTH 1 /* DSP2_CLK_AVAIL */
3670#define WM2200_DSP2_CLK_REQ_MASK 0x0003 /* DSP2_CLK_REQ - [1:0] */
3671#define WM2200_DSP2_CLK_REQ_SHIFT 0 /* DSP2_CLK_REQ - [1:0] */
3672#define WM2200_DSP2_CLK_REQ_WIDTH 2 /* DSP2_CLK_REQ - [1:0] */
3673
3674#endif
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 714256e609c1..b9c185ce64e4 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -18,6 +18,7 @@
18#include <linux/gcd.h> 18#include <linux/gcd.h>
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/pm_runtime.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/regulator/fixed.h> 23#include <linux/regulator/fixed.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
@@ -55,9 +56,6 @@ struct wm5100_priv {
55 struct snd_soc_codec *codec; 56 struct snd_soc_codec *codec;
56 57
57 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; 58 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
58 struct regulator *cpvdd;
59 struct regulator *dbvdd2;
60 struct regulator *dbvdd3;
61 59
62 int rev; 60 int rev;
63 61
@@ -74,6 +72,7 @@ struct wm5100_priv {
74 bool jack_detecting; 72 bool jack_detecting;
75 bool jack_mic; 73 bool jack_mic;
76 int jack_mode; 74 int jack_mode;
75 int jack_flips;
77 76
78 struct wm5100_fll fll[2]; 77 struct wm5100_fll fll[2];
79 78
@@ -710,6 +709,8 @@ WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
710 709
711WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), 710WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
712WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), 711WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
712SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5,
713 WM5100_DRCL_ENA | WM5100_DRCR_ENA),
713 714
714WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), 715WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
715WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), 716WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
@@ -777,85 +778,6 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
777 return 0; 778 return 0;
778} 779}
779 780
780static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
781 struct snd_kcontrol *kcontrol,
782 int event)
783{
784 struct snd_soc_codec *codec = w->codec;
785 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
786 int ret;
787
788 switch (event) {
789 case SND_SOC_DAPM_PRE_PMU:
790 ret = regulator_enable(wm5100->cpvdd);
791 if (ret != 0) {
792 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
793 ret);
794 return ret;
795 }
796 return ret;
797
798 case SND_SOC_DAPM_POST_PMD:
799 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
800 if (ret != 0) {
801 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
802 ret);
803 return ret;
804 }
805 return ret;
806
807 default:
808 BUG();
809 return 0;
810 }
811}
812
813static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
814 struct snd_kcontrol *kcontrol,
815 int event)
816{
817 struct snd_soc_codec *codec = w->codec;
818 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
819 struct regulator *regulator;
820 int ret;
821
822 switch (w->shift) {
823 case 2:
824 regulator = wm5100->dbvdd2;
825 break;
826 case 3:
827 regulator = wm5100->dbvdd3;
828 break;
829 default:
830 BUG();
831 return 0;
832 }
833
834 switch (event) {
835 case SND_SOC_DAPM_PRE_PMU:
836 ret = regulator_enable(regulator);
837 if (ret != 0) {
838 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
839 w->shift, ret);
840 return ret;
841 }
842 return ret;
843
844 case SND_SOC_DAPM_POST_PMD:
845 ret = regulator_disable(regulator);
846 if (ret != 0) {
847 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
848 w->shift, ret);
849 return ret;
850 }
851 return ret;
852
853 default:
854 BUG();
855 return 0;
856 }
857}
858
859static void wm5100_log_status3(struct wm5100_priv *wm5100, int val) 781static void wm5100_log_status3(struct wm5100_priv *wm5100, int val)
860{ 782{
861 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) 783 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
@@ -926,18 +848,16 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
926SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, 848SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
927 0, NULL, 0), 849 0, NULL, 0),
928 850
851SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
852SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
853SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
854
929SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, 855SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
930 wm5100_cp_ev, 856 NULL, 0),
931 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
932SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, 857SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
933 NULL, 0), 858 NULL, 0),
934SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, 859SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
935 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev, 860 WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0),
936 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
937SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
938 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
939SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
940 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
941 861
942SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, 862SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
943 0, NULL, 0), 863 0, NULL, 0),
@@ -1148,6 +1068,9 @@ SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1148}; 1068};
1149 1069
1150static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { 1070static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1071 { "CP1", NULL, "CPVDD" },
1072 { "CP2 Active", NULL, "CPVDD" },
1073
1151 { "IN1L", NULL, "SYSCLK" }, 1074 { "IN1L", NULL, "SYSCLK" },
1152 { "IN1R", NULL, "SYSCLK" }, 1075 { "IN1R", NULL, "SYSCLK" },
1153 { "IN2L", NULL, "SYSCLK" }, 1076 { "IN2L", NULL, "SYSCLK" },
@@ -1342,54 +1265,6 @@ static const __devinitdata struct reg_default wm5100_reva_patches[] = {
1342 { WM5100_AUDIO_IF_3_19, 1 }, 1265 { WM5100_AUDIO_IF_3_19, 1 },
1343}; 1266};
1344 1267
1345static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1346 enum snd_soc_bias_level level)
1347{
1348 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1349 int ret;
1350
1351 switch (level) {
1352 case SND_SOC_BIAS_ON:
1353 break;
1354
1355 case SND_SOC_BIAS_PREPARE:
1356 break;
1357
1358 case SND_SOC_BIAS_STANDBY:
1359 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1360 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1361 wm5100->core_supplies);
1362 if (ret != 0) {
1363 dev_err(codec->dev,
1364 "Failed to enable supplies: %d\n",
1365 ret);
1366 return ret;
1367 }
1368
1369 if (wm5100->pdata.ldo_ena) {
1370 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1371 1);
1372 msleep(2);
1373 }
1374
1375 regcache_cache_only(wm5100->regmap, false);
1376 regcache_sync(wm5100->regmap);
1377 }
1378 break;
1379
1380 case SND_SOC_BIAS_OFF:
1381 regcache_cache_only(wm5100->regmap, true);
1382 if (wm5100->pdata.ldo_ena)
1383 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1384 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1385 wm5100->core_supplies);
1386 break;
1387 }
1388 codec->dapm.bias_level = level;
1389
1390 return 0;
1391}
1392
1393static int wm5100_dai_to_base(struct snd_soc_dai *dai) 1268static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1394{ 1269{
1395 switch (dai->id) { 1270 switch (dai->id) {
@@ -1917,6 +1792,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1917 1792
1918 if (!Fout) { 1793 if (!Fout) {
1919 dev_dbg(codec->dev, "FLL%d disabled", fll_id); 1794 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1795 if (fll->fout)
1796 pm_runtime_put(codec->dev);
1920 fll->fout = 0; 1797 fll->fout = 0;
1921 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); 1798 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1922 return 0; 1799 return 0;
@@ -1961,6 +1838,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1961 /* Clear any pending completions */ 1838 /* Clear any pending completions */
1962 try_wait_for_completion(&fll->lock); 1839 try_wait_for_completion(&fll->lock);
1963 1840
1841 pm_runtime_get_sync(codec->dev);
1842
1964 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); 1843 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1965 1844
1966 if (i2c->irq) 1845 if (i2c->irq)
@@ -1995,6 +1874,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1995 } 1874 }
1996 if (i == timeout) { 1875 if (i == timeout) {
1997 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); 1876 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
1877 pm_runtime_put(codec->dev);
1998 return -ETIMEDOUT; 1878 return -ETIMEDOUT;
1999 } 1879 }
2000 1880
@@ -2119,6 +1999,19 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
2119 wm5100->jack_mode); 1999 wm5100->jack_mode);
2120} 2000}
2121 2001
2002static void wm5100_report_headphone(struct wm5100_priv *wm5100)
2003{
2004 dev_dbg(wm5100->dev, "Headphone detected\n");
2005 wm5100->jack_detecting = false;
2006 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2007 SND_JACK_HEADPHONE);
2008
2009 /* Increase the detection rate a bit for responsiveness. */
2010 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2011 WM5100_ACCDET_RATE_MASK,
2012 7 << WM5100_ACCDET_RATE_SHIFT);
2013}
2014
2122static void wm5100_micd_irq(struct wm5100_priv *wm5100) 2015static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2123{ 2016{
2124 unsigned int val; 2017 unsigned int val;
@@ -2143,6 +2036,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2143 dev_dbg(wm5100->dev, "Jack removal detected\n"); 2036 dev_dbg(wm5100->dev, "Jack removal detected\n");
2144 wm5100->jack_mic = false; 2037 wm5100->jack_mic = false;
2145 wm5100->jack_detecting = true; 2038 wm5100->jack_detecting = true;
2039 wm5100->jack_flips = 0;
2146 snd_soc_jack_report(wm5100->jack, 0, 2040 snd_soc_jack_report(wm5100->jack, 0,
2147 SND_JACK_LINEOUT | SND_JACK_HEADSET | 2041 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2148 SND_JACK_BTN_0); 2042 SND_JACK_BTN_0);
@@ -2161,6 +2055,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2161 if (wm5100->jack_detecting) { 2055 if (wm5100->jack_detecting) {
2162 dev_dbg(wm5100->dev, "Microphone detected\n"); 2056 dev_dbg(wm5100->dev, "Microphone detected\n");
2163 wm5100->jack_mic = true; 2057 wm5100->jack_mic = true;
2058 wm5100->jack_detecting = false;
2164 snd_soc_jack_report(wm5100->jack, 2059 snd_soc_jack_report(wm5100->jack,
2165 SND_JACK_HEADSET, 2060 SND_JACK_HEADSET,
2166 SND_JACK_HEADSET | SND_JACK_BTN_0); 2061 SND_JACK_HEADSET | SND_JACK_BTN_0);
@@ -2181,10 +2076,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2181 /* If we detected a lower impedence during initial startup 2076 /* If we detected a lower impedence during initial startup
2182 * then we probably have the wrong polarity, flip it. Don't 2077 * then we probably have the wrong polarity, flip it. Don't
2183 * do this for the lowest impedences to speed up detection of 2078 * do this for the lowest impedences to speed up detection of
2184 * plain headphones. 2079 * plain headphones and give up if neither polarity looks
2080 * sensible.
2185 */ 2081 */
2186 if (wm5100->jack_detecting && (val & 0x3f8)) { 2082 if (wm5100->jack_detecting && (val & 0x3f8)) {
2187 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); 2083 wm5100->jack_flips++;
2084
2085 if (wm5100->jack_flips > 1)
2086 wm5100_report_headphone(wm5100);
2087 else
2088 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
2188 2089
2189 return; 2090 return;
2190 } 2091 }
@@ -2198,16 +2099,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2198 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, 2099 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2199 SND_JACK_BTN_0); 2100 SND_JACK_BTN_0);
2200 } else if (wm5100->jack_detecting) { 2101 } else if (wm5100->jack_detecting) {
2201 dev_dbg(wm5100->dev, "Headphone detected\n"); 2102 wm5100_report_headphone(wm5100);
2202 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2203 SND_JACK_HEADPHONE);
2204
2205 /* Increase the detection rate a bit for
2206 * responsiveness.
2207 */
2208 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2209 WM5100_ACCDET_RATE_MASK,
2210 7 << WM5100_ACCDET_RATE_SHIFT);
2211 } 2103 }
2212 } 2104 }
2213} 2105}
@@ -2219,6 +2111,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2219 if (jack) { 2111 if (jack) {
2220 wm5100->jack = jack; 2112 wm5100->jack = jack;
2221 wm5100->jack_detecting = true; 2113 wm5100->jack_detecting = true;
2114 wm5100->jack_flips = 0;
2222 2115
2223 wm5100_set_detect_mode(wm5100, 0); 2116 wm5100_set_detect_mode(wm5100, 0);
2224 2117
@@ -2458,9 +2351,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2458 return ret; 2351 return ret;
2459 } 2352 }
2460 2353
2461 regcache_cache_only(wm5100->regmap, true);
2462
2463
2464 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) 2354 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2465 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, 2355 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2466 WM5100_OUT_VU); 2356 WM5100_OUT_VU);
@@ -2486,14 +2376,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
2486 } 2376 }
2487 } 2377 }
2488 2378
2489 /* We'll get woken up again when the system has something useful
2490 * for us to do.
2491 */
2492 if (wm5100->pdata.ldo_ena)
2493 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2494 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2495 wm5100->core_supplies);
2496
2497 return 0; 2379 return 0;
2498 2380
2499err_gpio: 2381err_gpio:
@@ -2525,7 +2407,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2525 2407
2526 .set_sysclk = wm5100_set_sysclk, 2408 .set_sysclk = wm5100_set_sysclk,
2527 .set_pll = wm5100_set_fll, 2409 .set_pll = wm5100_set_fll,
2528 .set_bias_level = wm5100_set_bias_level,
2529 .idle_bias_off = 1, 2410 .idle_bias_off = 1,
2530 .reg_cache_size = WM5100_MAX_REGISTER, 2411 .reg_cache_size = WM5100_MAX_REGISTER,
2531 .volatile_register = wm5100_soc_volatile, 2412 .volatile_register = wm5100_soc_volatile,
@@ -2551,6 +2432,13 @@ static const struct regmap_config wm5100_regmap = {
2551 .cache_type = REGCACHE_RBTREE, 2432 .cache_type = REGCACHE_RBTREE,
2552}; 2433};
2553 2434
2435static const unsigned int wm5100_mic_ctrl_reg[] = {
2436 WM5100_IN1L_CONTROL,
2437 WM5100_IN2L_CONTROL,
2438 WM5100_IN3L_CONTROL,
2439 WM5100_IN4L_CONTROL,
2440};
2441
2554static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, 2442static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2555 const struct i2c_device_id *id) 2443 const struct i2c_device_id *id)
2556{ 2444{
@@ -2585,41 +2473,21 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2585 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) 2473 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2586 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; 2474 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2587 2475
2588 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), 2476 ret = devm_regulator_bulk_get(&i2c->dev,
2589 wm5100->core_supplies); 2477 ARRAY_SIZE(wm5100->core_supplies),
2478 wm5100->core_supplies);
2590 if (ret != 0) { 2479 if (ret != 0) {
2591 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", 2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2592 ret); 2481 ret);
2593 goto err_regmap; 2482 goto err_regmap;
2594 } 2483 }
2595 2484
2596 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2597 if (IS_ERR(wm5100->cpvdd)) {
2598 ret = PTR_ERR(wm5100->cpvdd);
2599 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2600 goto err_core;
2601 }
2602
2603 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2604 if (IS_ERR(wm5100->dbvdd2)) {
2605 ret = PTR_ERR(wm5100->dbvdd2);
2606 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2607 goto err_cpvdd;
2608 }
2609
2610 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2611 if (IS_ERR(wm5100->dbvdd3)) {
2612 ret = PTR_ERR(wm5100->dbvdd3);
2613 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2614 goto err_dbvdd2;
2615 }
2616
2617 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), 2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2618 wm5100->core_supplies); 2486 wm5100->core_supplies);
2619 if (ret != 0) { 2487 if (ret != 0) {
2620 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", 2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2621 ret); 2489 ret);
2622 goto err_dbvdd3; 2490 goto err_regmap;
2623 } 2491 }
2624 2492
2625 if (wm5100->pdata.ldo_ena) { 2493 if (wm5100->pdata.ldo_ena) {
@@ -2701,7 +2569,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2701 } 2569 }
2702 2570
2703 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { 2571 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2704 regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, 2572 regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i],
2705 WM5100_IN1_MODE_MASK | 2573 WM5100_IN1_MODE_MASK |
2706 WM5100_IN1_DMIC_SUP_MASK, 2574 WM5100_IN1_DMIC_SUP_MASK,
2707 (wm5100->pdata.in_mode[i] << 2575 (wm5100->pdata.in_mode[i] <<
@@ -2762,6 +2630,10 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2762 } 2630 }
2763 } 2631 }
2764 2632
2633 pm_runtime_set_active(&i2c->dev);
2634 pm_runtime_enable(&i2c->dev);
2635 pm_request_idle(&i2c->dev);
2636
2765 ret = snd_soc_register_codec(&i2c->dev, 2637 ret = snd_soc_register_codec(&i2c->dev,
2766 &soc_codec_dev_wm5100, wm5100_dai, 2638 &soc_codec_dev_wm5100, wm5100_dai,
2767 ARRAY_SIZE(wm5100_dai)); 2639 ARRAY_SIZE(wm5100_dai));
@@ -2788,15 +2660,6 @@ err_ldo:
2788err_enable: 2660err_enable:
2789 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2790 wm5100->core_supplies); 2662 wm5100->core_supplies);
2791err_dbvdd3:
2792 regulator_put(wm5100->dbvdd3);
2793err_dbvdd2:
2794 regulator_put(wm5100->dbvdd2);
2795err_cpvdd:
2796 regulator_put(wm5100->cpvdd);
2797err_core:
2798 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2799 wm5100->core_supplies);
2800err_regmap: 2663err_regmap:
2801 regmap_exit(wm5100->regmap); 2664 regmap_exit(wm5100->regmap);
2802err: 2665err:
@@ -2819,16 +2682,56 @@ static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
2819 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2682 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2820 gpio_free(wm5100->pdata.ldo_ena); 2683 gpio_free(wm5100->pdata.ldo_ena);
2821 } 2684 }
2822 regulator_put(wm5100->dbvdd3);
2823 regulator_put(wm5100->dbvdd2);
2824 regulator_put(wm5100->cpvdd);
2825 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2826 wm5100->core_supplies);
2827 regmap_exit(wm5100->regmap); 2685 regmap_exit(wm5100->regmap);
2828 2686
2829 return 0; 2687 return 0;
2830} 2688}
2831 2689
2690#ifdef CONFIG_PM_RUNTIME
2691static int wm5100_runtime_suspend(struct device *dev)
2692{
2693 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2694
2695 regcache_cache_only(wm5100->regmap, true);
2696 regcache_mark_dirty(wm5100->regmap);
2697 if (wm5100->pdata.ldo_ena)
2698 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2699 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2700 wm5100->core_supplies);
2701
2702 return 0;
2703}
2704
2705static int wm5100_runtime_resume(struct device *dev)
2706{
2707 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2708 int ret;
2709
2710 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2711 wm5100->core_supplies);
2712 if (ret != 0) {
2713 dev_err(dev, "Failed to enable supplies: %d\n",
2714 ret);
2715 return ret;
2716 }
2717
2718 if (wm5100->pdata.ldo_ena) {
2719 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
2720 msleep(2);
2721 }
2722
2723 regcache_cache_only(wm5100->regmap, false);
2724 regcache_sync(wm5100->regmap);
2725
2726 return 0;
2727}
2728#endif
2729
2730static struct dev_pm_ops wm5100_pm = {
2731 SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume,
2732 NULL)
2733};
2734
2832static const struct i2c_device_id wm5100_i2c_id[] = { 2735static const struct i2c_device_id wm5100_i2c_id[] = {
2833 { "wm5100", 0 }, 2736 { "wm5100", 0 },
2834 { } 2737 { }
@@ -2839,6 +2742,7 @@ static struct i2c_driver wm5100_i2c_driver = {
2839 .driver = { 2742 .driver = {
2840 .name = "wm5100", 2743 .name = "wm5100",
2841 .owner = THIS_MODULE, 2744 .owner = THIS_MODULE,
2745 .pm = &wm5100_pm,
2842 }, 2746 },
2843 .probe = wm5100_i2c_probe, 2747 .probe = wm5100_i2c_probe,
2844 .remove = __devexit_p(wm5100_i2c_remove), 2748 .remove = __devexit_p(wm5100_i2c_remove),
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index ff95e62c56b9..4fe9d191e277 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -599,7 +599,7 @@ static int wm8737_probe(struct snd_soc_codec *codec)
599 /* Bias level configuration will have done an extra enable */ 599 /* Bias level configuration will have done an extra enable */
600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
601 601
602 snd_soc_add_controls(codec, wm8737_snd_controls, 602 snd_soc_add_codec_controls(codec, wm8737_snd_controls,
603 ARRAY_SIZE(wm8737_snd_controls)); 603 ARRAY_SIZE(wm8737_snd_controls));
604 wm8737_add_widgets(codec); 604 wm8737_add_widgets(codec);
605 605
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 21ed75de41f3..e27e7b62b365 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1557,7 +1557,8 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
1557 struct wm8753_priv *wm8753; 1557 struct wm8753_priv *wm8753;
1558 int ret; 1558 int ret;
1559 1559
1560 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1560 wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv),
1561 GFP_KERNEL);
1561 if (wm8753 == NULL) 1562 if (wm8753 == NULL)
1562 return -ENOMEM; 1563 return -ENOMEM;
1563 1564
@@ -1577,10 +1578,12 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
1577 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); 1578 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
1578 goto err_regmap; 1579 goto err_regmap;
1579 } 1580 }
1581
1582 return 0;
1583
1580err_regmap: 1584err_regmap:
1581 regmap_exit(wm8753->regmap); 1585 regmap_exit(wm8753->regmap);
1582err: 1586err:
1583 kfree(wm8753);
1584 return ret; 1587 return ret;
1585} 1588}
1586 1589
@@ -1612,7 +1615,8 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1612 struct wm8753_priv *wm8753; 1615 struct wm8753_priv *wm8753;
1613 int ret; 1616 int ret;
1614 1617
1615 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1618 wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv),
1619 GFP_KERNEL);
1616 if (wm8753 == NULL) 1620 if (wm8753 == NULL)
1617 return -ENOMEM; 1621 return -ENOMEM;
1618 1622
@@ -1632,10 +1636,12 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1632 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); 1636 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1633 goto err_regmap; 1637 goto err_regmap;
1634 } 1638 }
1639
1640 return 0;
1641
1635err_regmap: 1642err_regmap:
1636 regmap_exit(wm8753->regmap); 1643 regmap_exit(wm8753->regmap);
1637err: 1644err:
1638 kfree(wm8753);
1639 return ret; 1645 return ret;
1640} 1646}
1641 1647
@@ -1645,7 +1651,6 @@ static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1645 1651
1646 snd_soc_unregister_codec(&client->dev); 1652 snd_soc_unregister_codec(&client->dev);
1647 regmap_exit(wm8753->regmap); 1653 regmap_exit(wm8753->regmap);
1648 kfree(wm8753);
1649 return 0; 1654 return 0;
1650} 1655}
1651 1656
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19374a9e5ba6..a5127b4ff9e1 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -580,8 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec)
580 wm8770 = snd_soc_codec_get_drvdata(codec); 580 wm8770 = snd_soc_codec_get_drvdata(codec);
581 wm8770->codec = codec; 581 wm8770->codec = codec;
582 582
583 codec->dapm.idle_bias_off = 1;
584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); 583 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
586 if (ret < 0) { 584 if (ret < 0) {
587 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 585 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -643,7 +641,7 @@ static int wm8770_probe(struct snd_soc_codec *codec)
643 /* mute all DACs */ 641 /* mute all DACs */
644 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); 642 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
645 643
646 snd_soc_add_controls(codec, wm8770_snd_controls, 644 snd_soc_add_codec_controls(codec, wm8770_snd_controls,
647 ARRAY_SIZE(wm8770_snd_controls)); 645 ARRAY_SIZE(wm8770_snd_controls));
648 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, 646 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
649 ARRAY_SIZE(wm8770_dapm_widgets)); 647 ARRAY_SIZE(wm8770_dapm_widgets));
@@ -679,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
679 .suspend = wm8770_suspend, 677 .suspend = wm8770_suspend,
680 .resume = wm8770_resume, 678 .resume = wm8770_resume,
681 .set_bias_level = wm8770_set_bias_level, 679 .set_bias_level = wm8770_set_bias_level,
680 .idle_bias_off = true,
682 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), 681 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
683 .reg_word_size = sizeof (u16), 682 .reg_word_size = sizeof (u16),
684 .reg_cache_default = wm8770_reg_defs 683 .reg_cache_default = wm8770_reg_defs
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 33e97d1d8f46..a19db5a0a17a 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -30,6 +30,11 @@
30 30
31#include "wm8776.h" 31#include "wm8776.h"
32 32
33enum wm8776_chip_type {
34 WM8775 = 1,
35 WM8776,
36};
37
33/* codec private data */ 38/* codec private data */
34struct wm8776_priv { 39struct wm8776_priv {
35 enum snd_soc_control_type control_type; 40 enum snd_soc_control_type control_type;
@@ -512,7 +517,8 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
512} 517}
513 518
514static const struct i2c_device_id wm8776_i2c_id[] = { 519static const struct i2c_device_id wm8776_i2c_id[] = {
515 { "wm8776", 0 }, 520 { "wm8775", WM8775 },
521 { "wm8776", WM8776 },
516 { } 522 { }
517}; 523};
518MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); 524MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 8abe3757a979..7ee8dcf1fe32 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -549,7 +549,6 @@ static int wm8804_probe(struct snd_soc_codec *codec)
549 549
550 wm8804 = snd_soc_codec_get_drvdata(codec); 550 wm8804 = snd_soc_codec_get_drvdata(codec);
551 551
552 codec->dapm.idle_bias_off = 1;
553 codec->control_data = wm8804->regmap; 552 codec->control_data = wm8804->regmap;
554 553
555 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 554 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
@@ -678,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
678 .suspend = wm8804_suspend, 677 .suspend = wm8804_suspend,
679 .resume = wm8804_resume, 678 .resume = wm8804_resume,
680 .set_bias_level = wm8804_set_bias_level, 679 .set_bias_level = wm8804_set_bias_level,
680 .idle_bias_off = true,
681 681
682 .controls = wm8804_snd_controls, 682 .controls = wm8804_snd_controls,
683 .num_controls = ARRAY_SIZE(wm8804_snd_controls), 683 .num_controls = ARRAY_SIZE(wm8804_snd_controls),
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 14afc1193343..65d525d74c54 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1176,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1176 1176
1177 switch (wm8904->devtype) { 1177 switch (wm8904->devtype) {
1178 case WM8904: 1178 case WM8904:
1179 snd_soc_add_controls(codec, wm8904_adc_snd_controls, 1179 snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
1180 ARRAY_SIZE(wm8904_adc_snd_controls)); 1180 ARRAY_SIZE(wm8904_adc_snd_controls));
1181 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1181 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1182 ARRAY_SIZE(wm8904_dac_snd_controls)); 1182 ARRAY_SIZE(wm8904_dac_snd_controls));
1183 snd_soc_add_controls(codec, wm8904_snd_controls, 1183 snd_soc_add_codec_controls(codec, wm8904_snd_controls,
1184 ARRAY_SIZE(wm8904_snd_controls)); 1184 ARRAY_SIZE(wm8904_snd_controls));
1185 1185
1186 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, 1186 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
@@ -1201,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1201 break; 1201 break;
1202 1202
1203 case WM8912: 1203 case WM8912:
1204 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1204 snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
1205 ARRAY_SIZE(wm8904_dac_snd_controls)); 1205 ARRAY_SIZE(wm8904_dac_snd_controls));
1206 1206
1207 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, 1207 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
@@ -2020,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2020 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2020 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2021 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2021 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2022 2022
2023 ret = snd_soc_add_controls(codec, &control, 1); 2023 ret = snd_soc_add_codec_controls(codec, &control, 1);
2024 if (ret != 0) 2024 if (ret != 0)
2025 dev_err(codec->dev, 2025 dev_err(codec->dev,
2026 "Failed to add ReTune Mobile control: %d\n", ret); 2026 "Failed to add ReTune Mobile control: %d\n", ret);
@@ -2033,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2033 int ret, i; 2033 int ret, i;
2034 2034
2035 if (!pdata) { 2035 if (!pdata) {
2036 snd_soc_add_controls(codec, wm8904_eq_controls, 2036 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2037 ARRAY_SIZE(wm8904_eq_controls)); 2037 ARRAY_SIZE(wm8904_eq_controls));
2038 return; 2038 return;
2039 } 2039 }
@@ -2061,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2061 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2061 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2062 wm8904->drc_enum.texts = wm8904->drc_texts; 2062 wm8904->drc_enum.texts = wm8904->drc_texts;
2063 2063
2064 ret = snd_soc_add_controls(codec, &control, 1); 2064 ret = snd_soc_add_codec_controls(codec, &control, 1);
2065 if (ret != 0) 2065 if (ret != 0)
2066 dev_err(codec->dev, 2066 dev_err(codec->dev,
2067 "Failed to add DRC mode control: %d\n", ret); 2067 "Failed to add DRC mode control: %d\n", ret);
@@ -2075,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2075 if (pdata->num_retune_mobile_cfgs) 2075 if (pdata->num_retune_mobile_cfgs)
2076 wm8904_handle_retune_mobile_pdata(codec); 2076 wm8904_handle_retune_mobile_pdata(codec);
2077 else 2077 else
2078 snd_soc_add_controls(codec, wm8904_eq_controls, 2078 snd_soc_add_codec_controls(codec, wm8904_eq_controls,
2079 ARRAY_SIZE(wm8904_eq_controls)); 2079 ARRAY_SIZE(wm8904_eq_controls));
2080} 2080}
2081 2081
@@ -2088,7 +2088,6 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2088 int ret, i; 2088 int ret, i;
2089 2089
2090 codec->cache_sync = 1; 2090 codec->cache_sync = 1;
2091 codec->dapm.idle_bias_off = 1;
2092 codec->control_data = wm8904->regmap; 2091 codec->control_data = wm8904->regmap;
2093 2092
2094 switch (wm8904->devtype) { 2093 switch (wm8904->devtype) {
@@ -2237,6 +2236,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2237 .suspend = wm8904_suspend, 2236 .suspend = wm8904_suspend,
2238 .resume = wm8904_resume, 2237 .resume = wm8904_resume,
2239 .set_bias_level = wm8904_set_bias_level, 2238 .set_bias_level = wm8904_set_bias_level,
2239 .idle_bias_off = true,
2240}; 2240};
2241 2241
2242static const struct regmap_config wm8904_regmap = { 2242static const struct regmap_config wm8904_regmap = {
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index ae1933ed3e07..d2883affea3b 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -717,7 +717,7 @@ static int wm8940_probe(struct snd_soc_codec *codec)
717 return ret; 717 return ret;
718 } 718 }
719 719
720 ret = snd_soc_add_controls(codec, wm8940_snd_controls, 720 ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
721 ARRAY_SIZE(wm8940_snd_controls)); 721 ARRAY_SIZE(wm8940_snd_controls));
722 if (ret) 722 if (ret)
723 return ret; 723 return ret;
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 8d4ea43d40a3..1332692ef81b 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
55 return 0; 55 return 0;
56 56
57 if (fw->size < 32) { 57 if (fw->size < 32) {
58 dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", 58 dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n",
59 name, fw->size); 59 name, fw->size);
60 goto err; 60 goto err;
61 } 61 }
@@ -920,11 +920,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
920 920
921 wm8994->dsp_active = -1; 921 wm8994->dsp_active = -1;
922 922
923 snd_soc_add_controls(codec, wm8958_mbc_snd_controls, 923 snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls,
924 ARRAY_SIZE(wm8958_mbc_snd_controls)); 924 ARRAY_SIZE(wm8958_mbc_snd_controls));
925 snd_soc_add_controls(codec, wm8958_vss_snd_controls, 925 snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls,
926 ARRAY_SIZE(wm8958_vss_snd_controls)); 926 ARRAY_SIZE(wm8958_vss_snd_controls));
927 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, 927 snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls,
928 ARRAY_SIZE(wm8958_enh_eq_snd_controls)); 928 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
929 929
930 930
@@ -958,7 +958,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs; 958 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
959 wm8994->mbc_enum.texts = wm8994->mbc_texts; 959 wm8994->mbc_enum.texts = wm8994->mbc_texts;
960 960
961 ret = snd_soc_add_controls(wm8994->codec, control, 1); 961 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
962 if (ret != 0) 962 if (ret != 0)
963 dev_err(wm8994->codec->dev, 963 dev_err(wm8994->codec->dev,
964 "Failed to add MBC mode controls: %d\n", ret); 964 "Failed to add MBC mode controls: %d\n", ret);
@@ -986,7 +986,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
986 wm8994->vss_enum.max = pdata->num_vss_cfgs; 986 wm8994->vss_enum.max = pdata->num_vss_cfgs;
987 wm8994->vss_enum.texts = wm8994->vss_texts; 987 wm8994->vss_enum.texts = wm8994->vss_texts;
988 988
989 ret = snd_soc_add_controls(wm8994->codec, control, 1); 989 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
990 if (ret != 0) 990 if (ret != 0)
991 dev_err(wm8994->codec->dev, 991 dev_err(wm8994->codec->dev,
992 "Failed to add VSS mode controls: %d\n", ret); 992 "Failed to add VSS mode controls: %d\n", ret);
@@ -1015,7 +1015,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1015 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; 1015 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1016 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; 1016 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1017 1017
1018 ret = snd_soc_add_controls(wm8994->codec, control, 1); 1018 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
1019 if (ret != 0) 1019 if (ret != 0)
1020 dev_err(wm8994->codec->dev, 1020 dev_err(wm8994->codec->dev,
1021 "Failed to add VSS HPFmode controls: %d\n", 1021 "Failed to add VSS HPFmode controls: %d\n",
@@ -1045,7 +1045,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
1045 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; 1045 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1046 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; 1046 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1047 1047
1048 ret = snd_soc_add_controls(wm8994->codec, control, 1); 1048 ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
1049 if (ret != 0) 1049 if (ret != 0)
1050 dev_err(wm8994->codec->dev, 1050 dev_err(wm8994->codec->dev,
1051 "Failed to add enhanced EQ controls: %d\n", 1051 "Failed to add enhanced EQ controls: %d\n",
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e5caae32e541..840d72086d04 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -940,7 +940,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
940 snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); 940 snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
941 snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); 941 snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
942 942
943 snd_soc_add_controls(codec, wm8960_snd_controls, 943 snd_soc_add_codec_controls(codec, wm8960_snd_controls,
944 ARRAY_SIZE(wm8960_snd_controls)); 944 ARRAY_SIZE(wm8960_snd_controls));
945 wm8960_add_widgets(codec); 945 wm8960_add_widgets(codec);
946 946
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 4f20c72a0f1d..05ea7c274093 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,7 +1022,7 @@ static int wm8961_probe(struct snd_soc_codec *codec)
1022 1022
1023 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1023 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1024 1024
1025 snd_soc_add_controls(codec, wm8961_snd_controls, 1025 snd_soc_add_codec_controls(codec, wm8961_snd_controls,
1026 ARRAY_SIZE(wm8961_snd_controls)); 1026 ARRAY_SIZE(wm8961_snd_controls));
1027 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, 1027 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
1028 ARRAY_SIZE(wm8961_dapm_widgets)); 1028 ARRAY_SIZE(wm8961_dapm_widgets));
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index cc4049e9174b..445d2090661c 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -20,6 +20,7 @@
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/pm_runtime.h>
23#include <linux/regmap.h> 24#include <linux/regmap.h>
24#include <linux/regulator/consumer.h> 25#include <linux/regulator/consumer.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
@@ -96,7 +97,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \
96 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ 97 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
97 disable_nb[n]); \ 98 disable_nb[n]); \
98 if (event & REGULATOR_EVENT_DISABLE) { \ 99 if (event & REGULATOR_EVENT_DISABLE) { \
99 regcache_cache_only(wm8962->regmap, true); \ 100 regcache_mark_dirty(wm8962->regmap); \
100 } \ 101 } \
101 return 0; \ 102 return 0; \
102} 103}
@@ -207,8 +208,6 @@ static struct reg_default wm8962_reg[] = {
207 { 126, 0x000D }, /* R126 - Analogue Clocking3 */ 208 { 126, 0x000D }, /* R126 - Analogue Clocking3 */
208 { 127, 0x0000 }, /* R127 - PLL Software Reset */ 209 { 127, 0x0000 }, /* R127 - PLL Software Reset */
209 210
210 { 129, 0x0000 }, /* R129 - PLL2 */
211
212 { 131, 0x0000 }, /* R131 - PLL 4 */ 211 { 131, 0x0000 }, /* R131 - PLL 4 */
213 212
214 { 136, 0x0067 }, /* R136 - PLL 9 */ 213 { 136, 0x0067 }, /* R136 - PLL 9 */
@@ -1832,65 +1831,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
1832 4, 1, 0, inmix_tlv), 1831 4, 1, 0, inmix_tlv),
1833}; 1832};
1834 1833
1835static int sysclk_event(struct snd_soc_dapm_widget *w,
1836 struct snd_kcontrol *kcontrol, int event)
1837{
1838 struct snd_soc_codec *codec = w->codec;
1839 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1840 unsigned long timeout;
1841 int src;
1842 int fll;
1843
1844 /* Ignore attempts to run the event during startup */
1845 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1846 return 0;
1847
1848 src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
1849
1850 switch (src) {
1851 case 0: /* MCLK */
1852 fll = 0;
1853 break;
1854 case 0x200: /* FLL */
1855 fll = 1;
1856 break;
1857 default:
1858 dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
1859 return -EINVAL;
1860 }
1861
1862 switch (event) {
1863 case SND_SOC_DAPM_PRE_PMU:
1864 if (fll) {
1865 try_wait_for_completion(&wm8962->fll_lock);
1866
1867 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1868 WM8962_FLL_ENA, WM8962_FLL_ENA);
1869
1870 timeout = msecs_to_jiffies(5);
1871 timeout = wait_for_completion_timeout(&wm8962->fll_lock,
1872 timeout);
1873
1874 if (wm8962->irq && timeout == 0)
1875 dev_err(codec->dev,
1876 "Timed out starting FLL\n");
1877 }
1878 break;
1879
1880 case SND_SOC_DAPM_POST_PMD:
1881 if (fll)
1882 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1883 WM8962_FLL_ENA, 0);
1884 break;
1885
1886 default:
1887 BUG();
1888 return -EINVAL;
1889 }
1890
1891 return 0;
1892}
1893
1894static int cp_event(struct snd_soc_dapm_widget *w, 1834static int cp_event(struct snd_soc_dapm_widget *w,
1895 struct snd_kcontrol *kcontrol, int event) 1835 struct snd_kcontrol *kcontrol, int event)
1896{ 1836{
@@ -2176,8 +2116,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"),
2176SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), 2116SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
2177 2117
2178SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), 2118SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2179SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, 2119SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0),
2180 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2181SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, 2120SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2182 SND_SOC_DAPM_POST_PMU), 2121 SND_SOC_DAPM_POST_PMU),
2183SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), 2122SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
@@ -2291,9 +2230,11 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = {
2291 2230
2292 { "STL", "Left", "ADCL" }, 2231 { "STL", "Left", "ADCL" },
2293 { "STL", "Right", "ADCR" }, 2232 { "STL", "Right", "ADCR" },
2233 { "STL", NULL, "Class G" },
2294 2234
2295 { "STR", "Left", "ADCL" }, 2235 { "STR", "Left", "ADCL" },
2296 { "STR", "Right", "ADCR" }, 2236 { "STR", "Right", "ADCR" },
2237 { "STR", NULL, "Class G" },
2297 2238
2298 { "DACL", NULL, "SYSCLK" }, 2239 { "DACL", NULL, "SYSCLK" },
2299 { "DACL", NULL, "TOCLK" }, 2240 { "DACL", NULL, "TOCLK" },
@@ -2405,13 +2346,13 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2405 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 2346 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
2406 struct snd_soc_dapm_context *dapm = &codec->dapm; 2347 struct snd_soc_dapm_context *dapm = &codec->dapm;
2407 2348
2408 snd_soc_add_controls(codec, wm8962_snd_controls, 2349 snd_soc_add_codec_controls(codec, wm8962_snd_controls,
2409 ARRAY_SIZE(wm8962_snd_controls)); 2350 ARRAY_SIZE(wm8962_snd_controls));
2410 if (pdata && pdata->spk_mono) 2351 if (pdata && pdata->spk_mono)
2411 snd_soc_add_controls(codec, wm8962_spk_mono_controls, 2352 snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
2412 ARRAY_SIZE(wm8962_spk_mono_controls)); 2353 ARRAY_SIZE(wm8962_spk_mono_controls));
2413 else 2354 else
2414 snd_soc_add_controls(codec, wm8962_spk_stereo_controls, 2355 snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls,
2415 ARRAY_SIZE(wm8962_spk_stereo_controls)); 2356 ARRAY_SIZE(wm8962_spk_stereo_controls));
2416 2357
2417 2358
@@ -2445,7 +2386,7 @@ static const int bclk_divs[] = {
2445}; 2386};
2446 2387
2447static const int sysclk_rates[] = { 2388static const int sysclk_rates[] = {
2448 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 2389 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144
2449}; 2390};
2450 2391
2451static void wm8962_configure_bclk(struct snd_soc_codec *codec) 2392static void wm8962_configure_bclk(struct snd_soc_codec *codec)
@@ -2479,6 +2420,8 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2479 return; 2420 return;
2480 } 2421 }
2481 2422
2423 dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
2424
2482 snd_soc_update_bits(codec, WM8962_CLOCKING_4, 2425 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2483 WM8962_SYSCLK_RATE_MASK, clocking4); 2426 WM8962_SYSCLK_RATE_MASK, clocking4);
2484 2427
@@ -2537,9 +2480,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2537static int wm8962_set_bias_level(struct snd_soc_codec *codec, 2480static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2538 enum snd_soc_bias_level level) 2481 enum snd_soc_bias_level level)
2539{ 2482{
2540 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2541 int ret;
2542
2543 if (level == codec->dapm.bias_level) 2483 if (level == codec->dapm.bias_level)
2544 return 0; 2484 return 0;
2545 2485
@@ -2556,51 +2496,15 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2556 break; 2496 break;
2557 2497
2558 case SND_SOC_BIAS_STANDBY: 2498 case SND_SOC_BIAS_STANDBY:
2559 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2560 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
2561 wm8962->supplies);
2562 if (ret != 0) {
2563 dev_err(codec->dev,
2564 "Failed to enable supplies: %d\n",
2565 ret);
2566 return ret;
2567 }
2568
2569 regcache_cache_only(wm8962->regmap, false);
2570 regcache_sync(wm8962->regmap);
2571
2572 snd_soc_update_bits(codec, WM8962_ANTI_POP,
2573 WM8962_STARTUP_BIAS_ENA |
2574 WM8962_VMID_BUF_ENA,
2575 WM8962_STARTUP_BIAS_ENA |
2576 WM8962_VMID_BUF_ENA);
2577
2578 /* Bias enable at 2*50k for ramp */
2579 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2580 WM8962_VMID_SEL_MASK |
2581 WM8962_BIAS_ENA,
2582 WM8962_BIAS_ENA | 0x180);
2583
2584 msleep(5);
2585 }
2586
2587 /* VMID 2*250k */ 2499 /* VMID 2*250k */
2588 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, 2500 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2589 WM8962_VMID_SEL_MASK, 0x100); 2501 WM8962_VMID_SEL_MASK, 0x100);
2590 break; 2502 break;
2591 2503
2592 case SND_SOC_BIAS_OFF: 2504 case SND_SOC_BIAS_OFF:
2593 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2594 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
2595
2596 snd_soc_update_bits(codec, WM8962_ANTI_POP,
2597 WM8962_STARTUP_BIAS_ENA |
2598 WM8962_VMID_BUF_ENA, 0);
2599
2600 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
2601 wm8962->supplies);
2602 break; 2505 break;
2603 } 2506 }
2507
2604 codec->dapm.bias_level = level; 2508 codec->dapm.bias_level = level;
2605 return 0; 2509 return 0;
2606} 2510}
@@ -2634,6 +2538,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2634 int adctl3 = 0; 2538 int adctl3 = 0;
2635 2539
2636 wm8962->bclk = snd_soc_params_to_bclk(params); 2540 wm8962->bclk = snd_soc_params_to_bclk(params);
2541 if (params_channels(params) == 1)
2542 wm8962->bclk *= 2;
2543
2637 wm8962->lrclk = params_rate(params); 2544 wm8962->lrclk = params_rate(params);
2638 2545
2639 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { 2546 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
@@ -2654,13 +2561,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2654 case SNDRV_PCM_FORMAT_S16_LE: 2561 case SNDRV_PCM_FORMAT_S16_LE:
2655 break; 2562 break;
2656 case SNDRV_PCM_FORMAT_S20_3LE: 2563 case SNDRV_PCM_FORMAT_S20_3LE:
2657 aif0 |= 0x40; 2564 aif0 |= 0x4;
2658 break; 2565 break;
2659 case SNDRV_PCM_FORMAT_S24_LE: 2566 case SNDRV_PCM_FORMAT_S24_LE:
2660 aif0 |= 0x80; 2567 aif0 |= 0x8;
2661 break; 2568 break;
2662 case SNDRV_PCM_FORMAT_S32_LE: 2569 case SNDRV_PCM_FORMAT_S32_LE:
2663 aif0 |= 0xc0; 2570 aif0 |= 0xc;
2664 break; 2571 break;
2665 default: 2572 default:
2666 return -EINVAL; 2573 return -EINVAL;
@@ -2672,7 +2579,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2672 WM8962_SAMPLE_RATE_INT_MODE | 2579 WM8962_SAMPLE_RATE_INT_MODE |
2673 WM8962_SAMPLE_RATE_MASK, adctl3); 2580 WM8962_SAMPLE_RATE_MASK, adctl3);
2674 2581
2675 wm8962_configure_bclk(codec); 2582 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
2583 wm8962_configure_bclk(codec);
2676 2584
2677 return 0; 2585 return 0;
2678} 2586}
@@ -2702,6 +2610,8 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2702 2610
2703 wm8962->sysclk_rate = freq; 2611 wm8962->sysclk_rate = freq;
2704 2612
2613 wm8962_configure_bclk(codec);
2614
2705 return 0; 2615 return 0;
2706} 2616}
2707 2617
@@ -2880,8 +2790,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2880 struct _fll_div fll_div; 2790 struct _fll_div fll_div;
2881 unsigned long timeout; 2791 unsigned long timeout;
2882 int ret; 2792 int ret;
2883 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; 2793 int fll1 = 0;
2884 int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
2885 2794
2886 /* Any change? */ 2795 /* Any change? */
2887 if (source == wm8962->fll_src && Fref == wm8962->fll_fref && 2796 if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -2897,6 +2806,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2897 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2806 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2898 WM8962_FLL_ENA, 0); 2807 WM8962_FLL_ENA, 0);
2899 2808
2809 pm_runtime_put(codec->dev);
2810
2900 return 0; 2811 return 0;
2901 } 2812 }
2902 2813
@@ -2904,6 +2815,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2904 if (ret != 0) 2815 if (ret != 0)
2905 return ret; 2816 return ret;
2906 2817
2818 /* Parameters good, disable so we can reprogram */
2819 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
2820
2907 switch (fll_id) { 2821 switch (fll_id) {
2908 case WM8962_FLL_MCLK: 2822 case WM8962_FLL_MCLK:
2909 case WM8962_FLL_BCLK: 2823 case WM8962_FLL_BCLK:
@@ -2942,12 +2856,11 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2942 2856
2943 try_wait_for_completion(&wm8962->fll_lock); 2857 try_wait_for_completion(&wm8962->fll_lock);
2944 2858
2945 if (sysclk) 2859 pm_runtime_get_sync(codec->dev);
2946 fll1 |= WM8962_FLL_ENA;
2947 2860
2948 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, 2861 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2949 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | 2862 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
2950 WM8962_FLL_ENA, fll1); 2863 WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
2951 2864
2952 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); 2865 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2953 2866
@@ -3008,14 +2921,14 @@ static struct snd_soc_dai_driver wm8962_dai = {
3008 .name = "wm8962", 2921 .name = "wm8962",
3009 .playback = { 2922 .playback = {
3010 .stream_name = "Playback", 2923 .stream_name = "Playback",
3011 .channels_min = 2, 2924 .channels_min = 1,
3012 .channels_max = 2, 2925 .channels_max = 2,
3013 .rates = WM8962_RATES, 2926 .rates = WM8962_RATES,
3014 .formats = WM8962_FORMATS, 2927 .formats = WM8962_FORMATS,
3015 }, 2928 },
3016 .capture = { 2929 .capture = {
3017 .stream_name = "Capture", 2930 .stream_name = "Capture",
3018 .channels_min = 2, 2931 .channels_min = 1,
3019 .channels_max = 2, 2932 .channels_max = 2,
3020 .rates = WM8962_RATES, 2933 .rates = WM8962_RATES,
3021 .formats = WM8962_FORMATS, 2934 .formats = WM8962_FORMATS,
@@ -3056,54 +2969,73 @@ static void wm8962_mic_work(struct work_struct *work)
3056 2969
3057static irqreturn_t wm8962_irq(int irq, void *data) 2970static irqreturn_t wm8962_irq(int irq, void *data)
3058{ 2971{
3059 struct snd_soc_codec *codec = data; 2972 struct device *dev = data;
3060 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2973 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3061 int mask; 2974 unsigned int mask;
3062 int active; 2975 unsigned int active;
3063 int reg; 2976 int reg, ret;
3064 2977
3065 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); 2978 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK,
2979 &mask);
2980 if (ret != 0) {
2981 dev_err(dev, "Failed to read interrupt mask: %d\n",
2982 ret);
2983 return IRQ_NONE;
2984 }
2985
2986 ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active);
2987 if (ret != 0) {
2988 dev_err(dev, "Failed to read interrupt: %d\n", ret);
2989 return IRQ_NONE;
2990 }
3066 2991
3067 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3068 active &= ~mask; 2992 active &= ~mask;
3069 2993
3070 if (!active) 2994 if (!active)
3071 return IRQ_NONE; 2995 return IRQ_NONE;
3072 2996
3073 /* Acknowledge the interrupts */ 2997 /* Acknowledge the interrupts */
3074 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); 2998 ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active);
2999 if (ret != 0)
3000 dev_warn(dev, "Failed to ack interrupt: %d\n", ret);
3075 3001
3076 if (active & WM8962_FLL_LOCK_EINT) { 3002 if (active & WM8962_FLL_LOCK_EINT) {
3077 dev_dbg(codec->dev, "FLL locked\n"); 3003 dev_dbg(dev, "FLL locked\n");
3078 complete(&wm8962->fll_lock); 3004 complete(&wm8962->fll_lock);
3079 } 3005 }
3080 3006
3081 if (active & WM8962_FIFOS_ERR_EINT) 3007 if (active & WM8962_FIFOS_ERR_EINT)
3082 dev_err(codec->dev, "FIFO error\n"); 3008 dev_err(dev, "FIFO error\n");
3083 3009
3084 if (active & WM8962_TEMP_SHUT_EINT) { 3010 if (active & WM8962_TEMP_SHUT_EINT) {
3085 dev_crit(codec->dev, "Thermal shutdown\n"); 3011 dev_crit(dev, "Thermal shutdown\n");
3086 3012
3087 reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); 3013 ret = regmap_read(wm8962->regmap,
3014 WM8962_THERMAL_SHUTDOWN_STATUS, &reg);
3015 if (ret != 0) {
3016 dev_warn(dev, "Failed to read thermal status: %d\n",
3017 ret);
3018 reg = 0;
3019 }
3088 3020
3089 if (reg & WM8962_TEMP_ERR_HP) 3021 if (reg & WM8962_TEMP_ERR_HP)
3090 dev_crit(codec->dev, "Headphone thermal error\n"); 3022 dev_crit(dev, "Headphone thermal error\n");
3091 if (reg & WM8962_TEMP_WARN_HP) 3023 if (reg & WM8962_TEMP_WARN_HP)
3092 dev_crit(codec->dev, "Headphone thermal warning\n"); 3024 dev_crit(dev, "Headphone thermal warning\n");
3093 if (reg & WM8962_TEMP_ERR_SPK) 3025 if (reg & WM8962_TEMP_ERR_SPK)
3094 dev_crit(codec->dev, "Speaker thermal error\n"); 3026 dev_crit(dev, "Speaker thermal error\n");
3095 if (reg & WM8962_TEMP_WARN_SPK) 3027 if (reg & WM8962_TEMP_WARN_SPK)
3096 dev_crit(codec->dev, "Speaker thermal warning\n"); 3028 dev_crit(dev, "Speaker thermal warning\n");
3097 } 3029 }
3098 3030
3099 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3031 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3100 dev_dbg(codec->dev, "Microphone event detected\n"); 3032 dev_dbg(dev, "Microphone event detected\n");
3101 3033
3102#ifndef CONFIG_SND_SOC_WM8962_MODULE 3034#ifndef CONFIG_SND_SOC_WM8962_MODULE
3103 trace_snd_soc_jack_irq(dev_name(codec->dev)); 3035 trace_snd_soc_jack_irq(dev_name(dev));
3104#endif 3036#endif
3105 3037
3106 pm_wakeup_event(codec->dev, 300); 3038 pm_wakeup_event(dev, 300);
3107 3039
3108 schedule_delayed_work(&wm8962->mic_work, 3040 schedule_delayed_work(&wm8962->mic_work,
3109 msecs_to_jiffies(250)); 3041 msecs_to_jiffies(250));
@@ -3584,7 +3516,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3584 3516
3585 ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, 3517 ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq,
3586 trigger | IRQF_ONESHOT, 3518 trigger | IRQF_ONESHOT,
3587 "wm8962", codec); 3519 "wm8962", codec->dev);
3588 if (ret != 0) { 3520 if (ret != 0) {
3589 dev_err(codec->dev, "Failed to request IRQ %d: %d\n", 3521 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
3590 wm8962->irq, ret); 3522 wm8962->irq, ret);
@@ -3622,20 +3554,19 @@ static int wm8962_remove(struct snd_soc_codec *codec)
3622 return 0; 3554 return 0;
3623} 3555}
3624 3556
3625static int wm8962_soc_volatile(struct snd_soc_codec *codec,
3626 unsigned int reg)
3627{
3628 return true;
3629}
3630
3631
3632static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { 3557static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
3633 .probe = wm8962_probe, 3558 .probe = wm8962_probe,
3634 .remove = wm8962_remove, 3559 .remove = wm8962_remove,
3635 .set_bias_level = wm8962_set_bias_level, 3560 .set_bias_level = wm8962_set_bias_level,
3636 .set_pll = wm8962_set_fll, 3561 .set_pll = wm8962_set_fll,
3637 .reg_cache_size = WM8962_MAX_REGISTER, 3562 .idle_bias_off = true,
3638 .volatile_register = wm8962_soc_volatile, 3563};
3564
3565/* Improve power consumption for IN4 DC measurement mode */
3566static const struct reg_default wm8962_dc_measure[] = {
3567 { 0xfd, 0x1 },
3568 { 0xcc, 0x40 },
3569 { 0xfd, 0 },
3639}; 3570};
3640 3571
3641static const struct regmap_config wm8962_regmap = { 3572static const struct regmap_config wm8962_regmap = {
@@ -3653,6 +3584,7 @@ static const struct regmap_config wm8962_regmap = {
3653static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, 3584static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
3654 const struct i2c_device_id *id) 3585 const struct i2c_device_id *id)
3655{ 3586{
3587 struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev);
3656 struct wm8962_priv *wm8962; 3588 struct wm8962_priv *wm8962;
3657 unsigned int reg; 3589 unsigned int reg;
3658 int ret, i; 3590 int ret, i;
@@ -3706,7 +3638,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
3706 } 3638 }
3707 if (reg != 0x6243) { 3639 if (reg != 0x6243) {
3708 dev_err(&i2c->dev, 3640 dev_err(&i2c->dev,
3709 "Device is not a WM8962, ID %x != 0x6243\n", ret); 3641 "Device is not a WM8962, ID %x != 0x6243\n", reg);
3710 ret = -EINVAL; 3642 ret = -EINVAL;
3711 goto err_regmap; 3643 goto err_regmap;
3712 } 3644 }
@@ -3731,7 +3663,19 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
3731 goto err_regmap; 3663 goto err_regmap;
3732 } 3664 }
3733 3665
3734 regcache_cache_only(wm8962->regmap, true); 3666 if (pdata && pdata->in4_dc_measure) {
3667 ret = regmap_register_patch(wm8962->regmap,
3668 wm8962_dc_measure,
3669 ARRAY_SIZE(wm8962_dc_measure));
3670 if (ret != 0)
3671 dev_err(&i2c->dev,
3672 "Failed to configure for DC mesurement: %d\n",
3673 ret);
3674 }
3675
3676 pm_runtime_set_active(&i2c->dev);
3677 pm_runtime_enable(&i2c->dev);
3678 pm_request_idle(&i2c->dev);
3735 3679
3736 ret = snd_soc_register_codec(&i2c->dev, 3680 ret = snd_soc_register_codec(&i2c->dev,
3737 &soc_codec_dev_wm8962, &wm8962_dai, 1); 3681 &soc_codec_dev_wm8962, &wm8962_dai, 1);
@@ -3763,6 +3707,65 @@ static __devexit int wm8962_i2c_remove(struct i2c_client *client)
3763 return 0; 3707 return 0;
3764} 3708}
3765 3709
3710#ifdef CONFIG_PM_RUNTIME
3711static int wm8962_runtime_resume(struct device *dev)
3712{
3713 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3714 int ret;
3715
3716 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3717 wm8962->supplies);
3718 if (ret != 0) {
3719 dev_err(dev,
3720 "Failed to enable supplies: %d\n", ret);
3721 return ret;
3722 }
3723
3724 regcache_cache_only(wm8962->regmap, false);
3725 regcache_sync(wm8962->regmap);
3726
3727 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
3728 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
3729 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
3730
3731 /* Bias enable at 2*50k for ramp */
3732 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3733 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
3734 WM8962_BIAS_ENA | 0x180);
3735
3736 msleep(5);
3737
3738 /* VMID back to 2x250k for standby */
3739 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3740 WM8962_VMID_SEL_MASK, 0x100);
3741
3742 return 0;
3743}
3744
3745static int wm8962_runtime_suspend(struct device *dev)
3746{
3747 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3748
3749 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3750 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
3751
3752 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
3753 WM8962_STARTUP_BIAS_ENA |
3754 WM8962_VMID_BUF_ENA, 0);
3755
3756 regcache_cache_only(wm8962->regmap, true);
3757
3758 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
3759 wm8962->supplies);
3760
3761 return 0;
3762}
3763#endif
3764
3765static struct dev_pm_ops wm8962_pm = {
3766 SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
3767};
3768
3766static const struct i2c_device_id wm8962_i2c_id[] = { 3769static const struct i2c_device_id wm8962_i2c_id[] = {
3767 { "wm8962", 0 }, 3770 { "wm8962", 0 },
3768 { } 3771 { }
@@ -3773,23 +3776,14 @@ static struct i2c_driver wm8962_i2c_driver = {
3773 .driver = { 3776 .driver = {
3774 .name = "wm8962", 3777 .name = "wm8962",
3775 .owner = THIS_MODULE, 3778 .owner = THIS_MODULE,
3779 .pm = &wm8962_pm,
3776 }, 3780 },
3777 .probe = wm8962_i2c_probe, 3781 .probe = wm8962_i2c_probe,
3778 .remove = __devexit_p(wm8962_i2c_remove), 3782 .remove = __devexit_p(wm8962_i2c_remove),
3779 .id_table = wm8962_i2c_id, 3783 .id_table = wm8962_i2c_id,
3780}; 3784};
3781 3785
3782static int __init wm8962_modinit(void) 3786module_i2c_driver(wm8962_i2c_driver);
3783{
3784 return i2c_add_driver(&wm8962_i2c_driver);
3785}
3786module_init(wm8962_modinit);
3787
3788static void __exit wm8962_exit(void)
3789{
3790 i2c_del_driver(&wm8962_i2c_driver);
3791}
3792module_exit(wm8962_exit);
3793 3787
3794MODULE_DESCRIPTION("ASoC WM8962 driver"); 3788MODULE_DESCRIPTION("ASoC WM8962 driver");
3795MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3789MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 4ef9d4cb7d7c..6cdf6a2bc283 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -33,24 +33,89 @@
33 * We can't read the WM8988 register space when we 33 * We can't read the WM8988 register space when we
34 * are using 2 wire for device control, so we cache them instead. 34 * are using 2 wire for device control, so we cache them instead.
35 */ 35 */
36static const u16 wm8988_reg[] = { 36static const struct reg_default wm8988_reg_defaults[] = {
37 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 37 { 0, 0x0097 },
38 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 38 { 1, 0x0097 },
39 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 39 { 2, 0x0079 },
40 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 40 { 3, 0x0079 },
41 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 41 { 5, 0x0008 },
42 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 42 { 7, 0x000a },
43 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 43 { 8, 0x0000 },
44 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 44 { 10, 0x00ff },
45 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 45 { 11, 0x00ff },
46 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 46 { 12, 0x000f },
47 0x0079, 0x0079, 0x0079, /* 40 */ 47 { 13, 0x000f },
48 { 16, 0x0000 },
49 { 17, 0x007b },
50 { 18, 0x0000 },
51 { 19, 0x0032 },
52 { 20, 0x0000 },
53 { 21, 0x00c3 },
54 { 22, 0x00c3 },
55 { 23, 0x00c0 },
56 { 24, 0x0000 },
57 { 25, 0x0000 },
58 { 26, 0x0000 },
59 { 27, 0x0000 },
60 { 31, 0x0000 },
61 { 32, 0x0000 },
62 { 33, 0x0000 },
63 { 34, 0x0050 },
64 { 35, 0x0050 },
65 { 36, 0x0050 },
66 { 37, 0x0050 },
67 { 40, 0x0079 },
68 { 41, 0x0079 },
69 { 42, 0x0079 },
48}; 70};
49 71
72static bool wm8988_writeable(struct device *dev, unsigned int reg)
73{
74 switch (reg) {
75 case WM8988_LINVOL:
76 case WM8988_RINVOL:
77 case WM8988_LOUT1V:
78 case WM8988_ROUT1V:
79 case WM8988_ADCDAC:
80 case WM8988_IFACE:
81 case WM8988_SRATE:
82 case WM8988_LDAC:
83 case WM8988_RDAC:
84 case WM8988_BASS:
85 case WM8988_TREBLE:
86 case WM8988_RESET:
87 case WM8988_3D:
88 case WM8988_ALC1:
89 case WM8988_ALC2:
90 case WM8988_ALC3:
91 case WM8988_NGATE:
92 case WM8988_LADC:
93 case WM8988_RADC:
94 case WM8988_ADCTL1:
95 case WM8988_ADCTL2:
96 case WM8988_PWR1:
97 case WM8988_PWR2:
98 case WM8988_ADCTL3:
99 case WM8988_ADCIN:
100 case WM8988_LADCIN:
101 case WM8988_RADCIN:
102 case WM8988_LOUTM1:
103 case WM8988_LOUTM2:
104 case WM8988_ROUTM1:
105 case WM8988_ROUTM2:
106 case WM8988_LOUT2V:
107 case WM8988_ROUT2V:
108 case WM8988_LPPB:
109 return true;
110 default:
111 return false;
112 }
113}
114
50/* codec private data */ 115/* codec private data */
51struct wm8988_priv { 116struct wm8988_priv {
117 struct regmap *regmap;
52 unsigned int sysclk; 118 unsigned int sysclk;
53 enum snd_soc_control_type control_type;
54 struct snd_pcm_hw_constraint_list *sysclk_constraints; 119 struct snd_pcm_hw_constraint_list *sysclk_constraints;
55}; 120};
56 121
@@ -661,6 +726,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
661static int wm8988_set_bias_level(struct snd_soc_codec *codec, 726static int wm8988_set_bias_level(struct snd_soc_codec *codec,
662 enum snd_soc_bias_level level) 727 enum snd_soc_bias_level level)
663{ 728{
729 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
664 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; 730 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
665 731
666 switch (level) { 732 switch (level) {
@@ -674,7 +740,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
674 740
675 case SND_SOC_BIAS_STANDBY: 741 case SND_SOC_BIAS_STANDBY:
676 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 742 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
677 snd_soc_cache_sync(codec); 743 regcache_sync(wm8988->regmap);
678 744
679 /* VREF, VMID=2x5k */ 745 /* VREF, VMID=2x5k */
680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 746 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = {
730 796
731static int wm8988_suspend(struct snd_soc_codec *codec) 797static int wm8988_suspend(struct snd_soc_codec *codec)
732{ 798{
799 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
800
733 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 801 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
802 regcache_mark_dirty(wm8988->regmap);
734 return 0; 803 return 0;
735} 804}
736 805
@@ -745,7 +814,8 @@ static int wm8988_probe(struct snd_soc_codec *codec)
745 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 814 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
746 int ret = 0; 815 int ret = 0;
747 816
748 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); 817 codec->control_data = wm8988->regmap;
818 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
749 if (ret < 0) { 819 if (ret < 0) {
750 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 820 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
751 return ret; 821 return ret;
@@ -781,9 +851,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
781 .suspend = wm8988_suspend, 851 .suspend = wm8988_suspend,
782 .resume = wm8988_resume, 852 .resume = wm8988_resume,
783 .set_bias_level = wm8988_set_bias_level, 853 .set_bias_level = wm8988_set_bias_level,
784 .reg_cache_size = ARRAY_SIZE(wm8988_reg),
785 .reg_word_size = sizeof(u16),
786 .reg_cache_default = wm8988_reg,
787 854
788 .controls = wm8988_snd_controls, 855 .controls = wm8988_snd_controls,
789 .num_controls = ARRAY_SIZE(wm8988_snd_controls), 856 .num_controls = ARRAY_SIZE(wm8988_snd_controls),
@@ -793,6 +860,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
793 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), 860 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
794}; 861};
795 862
863static struct regmap_config wm8988_regmap = {
864 .reg_bits = 7,
865 .val_bits = 9,
866
867 .max_register = WM8988_LPPB,
868 .writeable_reg = wm8988_writeable,
869
870 .cache_type = REGCACHE_RBTREE,
871 .reg_defaults = wm8988_reg_defaults,
872 .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
873};
874
796#if defined(CONFIG_SPI_MASTER) 875#if defined(CONFIG_SPI_MASTER)
797static int __devinit wm8988_spi_probe(struct spi_device *spi) 876static int __devinit wm8988_spi_probe(struct spi_device *spi)
798{ 877{
@@ -804,18 +883,28 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
804 if (wm8988 == NULL) 883 if (wm8988 == NULL)
805 return -ENOMEM; 884 return -ENOMEM;
806 885
807 wm8988->control_type = SND_SOC_SPI; 886 wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
887 if (IS_ERR(wm8988->regmap)) {
888 ret = PTR_ERR(wm8988->regmap);
889 dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
890 return ret;
891 }
892
808 spi_set_drvdata(spi, wm8988); 893 spi_set_drvdata(spi, wm8988);
809 894
810 ret = snd_soc_register_codec(&spi->dev, 895 ret = snd_soc_register_codec(&spi->dev,
811 &soc_codec_dev_wm8988, &wm8988_dai, 1); 896 &soc_codec_dev_wm8988, &wm8988_dai, 1);
897 if (ret != 0)
898 regmap_exit(wm8988->regmap);
812 899
813 return ret; 900 return ret;
814} 901}
815 902
816static int __devexit wm8988_spi_remove(struct spi_device *spi) 903static int __devexit wm8988_spi_remove(struct spi_device *spi)
817{ 904{
905 struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
818 snd_soc_unregister_codec(&spi->dev); 906 snd_soc_unregister_codec(&spi->dev);
907 regmap_exit(wm8988->regmap);
819 return 0; 908 return 0;
820} 909}
821 910
@@ -842,16 +931,27 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
842 return -ENOMEM; 931 return -ENOMEM;
843 932
844 i2c_set_clientdata(i2c, wm8988); 933 i2c_set_clientdata(i2c, wm8988);
845 wm8988->control_type = SND_SOC_I2C; 934
935 wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
936 if (IS_ERR(wm8988->regmap)) {
937 ret = PTR_ERR(wm8988->regmap);
938 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
939 return ret;
940 }
846 941
847 ret = snd_soc_register_codec(&i2c->dev, 942 ret = snd_soc_register_codec(&i2c->dev,
848 &soc_codec_dev_wm8988, &wm8988_dai, 1); 943 &soc_codec_dev_wm8988, &wm8988_dai, 1);
944 if (ret != 0)
945 regmap_exit(wm8988->regmap);
946
849 return ret; 947 return ret;
850} 948}
851 949
852static __devexit int wm8988_i2c_remove(struct i2c_client *client) 950static __devexit int wm8988_i2c_remove(struct i2c_client *client)
853{ 951{
952 struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
854 snd_soc_unregister_codec(&client->dev); 953 snd_soc_unregister_codec(&client->dev);
954 regmap_exit(wm8988->regmap);
855 return 0; 955 return 0;
856} 956}
857 957
@@ -863,7 +963,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
863 963
864static struct i2c_driver wm8988_i2c_driver = { 964static struct i2c_driver wm8988_i2c_driver = {
865 .driver = { 965 .driver = {
866 .name = "wm8988-codec", 966 .name = "wm8988",
867 .owner = THIS_MODULE, 967 .owner = THIS_MODULE,
868 }, 968 },
869 .probe = wm8988_i2c_probe, 969 .probe = wm8988_i2c_probe,
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index e538edaae1f0..9d242351e6e8 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1356,7 +1356,7 @@ static int wm8990_probe(struct snd_soc_codec *codec)
1356 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1356 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1357 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1357 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1358 1358
1359 snd_soc_add_controls(codec, wm8990_snd_controls, 1359 snd_soc_add_codec_controls(codec, wm8990_snd_controls,
1360 ARRAY_SIZE(wm8990_snd_controls)); 1360 ARRAY_SIZE(wm8990_snd_controls));
1361 wm8990_add_widgets(codec); 1361 wm8990_add_widgets(codec);
1362 1362
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 7ee40da8dbb5..9ac31ba9b82e 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1297,7 +1297,7 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1297 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1297 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1298 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1298 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1299 1299
1300 snd_soc_add_controls(codec, wm8991_snd_controls, 1300 snd_soc_add_codec_controls(codec, wm8991_snd_controls,
1301 ARRAY_SIZE(wm8991_snd_controls)); 1301 ARRAY_SIZE(wm8991_snd_controls));
1302 1302
1303 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, 1303 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index dd687c3a84f9..d256a9340644 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -61,8 +61,9 @@ static struct reg_default wm8993_reg_defaults[] = {
61 { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ 61 { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */
62 { 19, 0x0010 }, /* R19 - GPIO1 */ 62 { 19, 0x0010 }, /* R19 - GPIO1 */
63 { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */ 63 { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */
64 { 21, 0x8000 }, /* R22 - GPIOCTRL 2 */ 64 { 21, 0x0000 }, /* R21 - Inputs Clamp */
65 { 22, 0x0800 }, /* R23 - GPIO_POL */ 65 { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */
66 { 23, 0x0800 }, /* R23 - GPIO_POL */
66 { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ 67 { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
67 { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ 68 { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
68 { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ 69 { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
@@ -1057,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1057 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1058 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1058 int ret; 1059 int ret;
1059 1060
1061 wm_hubs_set_bias_level(codec, level);
1062
1060 switch (level) { 1063 switch (level) {
1061 case SND_SOC_BIAS_ON: 1064 case SND_SOC_BIAS_ON:
1062 case SND_SOC_BIAS_PREPARE: 1065 case SND_SOC_BIAS_PREPARE:
@@ -1077,10 +1080,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1077 regcache_cache_only(wm8993->regmap, false); 1080 regcache_cache_only(wm8993->regmap, false);
1078 regcache_sync(wm8993->regmap); 1081 regcache_sync(wm8993->regmap);
1079 1082
1080 /* Tune DC servo configuration */ 1083 wm_hubs_vmid_ena(codec);
1081 snd_soc_write(codec, 0x44, 3);
1082 snd_soc_write(codec, 0x56, 3);
1083 snd_soc_write(codec, 0x44, 0);
1084 1084
1085 /* Bring up VMID with fast soft start */ 1085 /* Bring up VMID with fast soft start */
1086 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 1086 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
@@ -1609,13 +1609,13 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1609 if (ret != 0) 1609 if (ret != 0)
1610 return ret; 1610 return ret;
1611 1611
1612 snd_soc_add_controls(codec, wm8993_snd_controls, 1612 snd_soc_add_codec_controls(codec, wm8993_snd_controls,
1613 ARRAY_SIZE(wm8993_snd_controls)); 1613 ARRAY_SIZE(wm8993_snd_controls));
1614 if (wm8993->pdata.num_retune_configs != 0) { 1614 if (wm8993->pdata.num_retune_configs != 0) {
1615 dev_dbg(codec->dev, "Using ReTune Mobile\n"); 1615 dev_dbg(codec->dev, "Using ReTune Mobile\n");
1616 } else { 1616 } else {
1617 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); 1617 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
1618 snd_soc_add_controls(codec, wm8993_eq_controls, 1618 snd_soc_add_codec_controls(codec, wm8993_eq_controls,
1619 ARRAY_SIZE(wm8993_eq_controls)); 1619 ARRAY_SIZE(wm8993_eq_controls));
1620 } 1620 }
1621 1621
@@ -1627,6 +1627,12 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1627 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1627 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1628 wm8993->pdata.lineout2_diff); 1628 wm8993->pdata.lineout2_diff);
1629 1629
1630 /* If the line outputs are differential then we aren't presenting
1631 * VMID as an output and can disable it.
1632 */
1633 if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff)
1634 codec->dapm.idle_bias_off = 1;
1635
1630 return 0; 1636 return 0;
1631 1637
1632} 1638}
@@ -1691,6 +1697,13 @@ static int wm8993_resume(struct snd_soc_codec *codec)
1691#define wm8993_resume NULL 1697#define wm8993_resume NULL
1692#endif 1698#endif
1693 1699
1700/* Tune DC servo configuration */
1701static struct reg_default wm8993_regmap_patch[] = {
1702 { 0x44, 3 },
1703 { 0x56, 3 },
1704 { 0x44, 0 },
1705};
1706
1694static const struct regmap_config wm8993_regmap = { 1707static const struct regmap_config wm8993_regmap = {
1695 .reg_bits = 8, 1708 .reg_bits = 8,
1696 .val_bits = 16, 1709 .val_bits = 16,
@@ -1769,6 +1782,12 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
1769 if (ret != 0) 1782 if (ret != 0)
1770 goto err_enable; 1783 goto err_enable;
1771 1784
1785 ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch,
1786 ARRAY_SIZE(wm8993_regmap_patch));
1787 if (ret != 0)
1788 dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n",
1789 ret);
1790
1772 if (i2c->irq) { 1791 if (i2c->irq) {
1773 /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ 1792 /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */
1774 ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, 1793 ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1,
@@ -1840,24 +1859,7 @@ static struct i2c_driver wm8993_i2c_driver = {
1840 .id_table = wm8993_i2c_id, 1859 .id_table = wm8993_i2c_id,
1841}; 1860};
1842 1861
1843static int __init wm8993_modinit(void) 1862module_i2c_driver(wm8993_i2c_driver);
1844{
1845 int ret = 0;
1846 ret = i2c_add_driver(&wm8993_i2c_driver);
1847 if (ret != 0) {
1848 pr_err("WM8993: Unable to register I2C driver: %d\n",
1849 ret);
1850 }
1851 return ret;
1852}
1853module_init(wm8993_modinit);
1854
1855static void __exit wm8993_exit(void)
1856{
1857 i2c_del_driver(&wm8993_i2c_driver);
1858}
1859module_exit(wm8993_exit);
1860
1861 1863
1862MODULE_DESCRIPTION("ASoC WM8993 driver"); 1864MODULE_DESCRIPTION("ASoC WM8993 driver");
1863MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1865MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 2184617b9611..4478b40c86e3 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -31,6 +31,7 @@
31#define WM8993_GPIO_CTRL_1 0x12 31#define WM8993_GPIO_CTRL_1 0x12
32#define WM8993_GPIO1 0x13 32#define WM8993_GPIO1 0x13
33#define WM8993_IRQ_DEBOUNCE 0x14 33#define WM8993_IRQ_DEBOUNCE 0x14
34#define WM8993_INPUTS_CLAMP_REG 0x15
34#define WM8993_GPIOCTRL_2 0x16 35#define WM8993_GPIOCTRL_2 0x16
35#define WM8993_GPIO_POL 0x17 36#define WM8993_GPIO_POL 0x17
36#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18 37#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18
@@ -656,6 +657,14 @@
656#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */ 657#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */
657 658
658/* 659/*
660 * R21 (0x15) - Inputs Clamp
661 */
662#define WM8993_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
663#define WM8993_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
664#define WM8993_INPUTS_CLAMP_SHIFT 7 /* INPUTS_CLAMP */
665#define WM8993_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
666
667/*
659 * R22 (0x16) - GPIOCTRL 2 668 * R22 (0x16) - GPIOCTRL 2
660 */ 669 */
661#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */ 670#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b047bfada709..2417ef9316ed 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -685,15 +685,37 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0,
685static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) 685static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
686{ 686{
687 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 687 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
688 u16 old = snd_soc_read(codec, WM8994_ANTIPOP_2)
689 & WM1811_JACKDET_MODE_MASK;
690
691 if (!wm8994->jackdet || !wm8994->jack_cb)
692 return;
688 693
689 if (wm8994->active_refcount) 694 if (wm8994->active_refcount)
690 mode = WM1811_JACKDET_MODE_AUDIO; 695 mode = WM1811_JACKDET_MODE_AUDIO;
691 696
697 if (mode == old)
698 return;
699
692 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 700 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
693 WM1811_JACKDET_MODE_MASK, mode); 701 WM1811_JACKDET_MODE_MASK, mode);
694 702
695 if (mode == WM1811_JACKDET_MODE_MIC) 703 switch (mode) {
696 msleep(2); 704 case WM1811_JACKDET_MODE_MIC:
705 case WM1811_JACKDET_MODE_AUDIO:
706 switch (old) {
707 case WM1811_JACKDET_MODE_MIC:
708 case WM1811_JACKDET_MODE_AUDIO:
709 break;
710 default:
711 msleep(2);
712 break;
713 }
714
715 default:
716 break;
717 }
718
697} 719}
698 720
699static void active_reference(struct snd_soc_codec *codec) 721static void active_reference(struct snd_soc_codec *codec)
@@ -707,15 +729,8 @@ static void active_reference(struct snd_soc_codec *codec)
707 dev_dbg(codec->dev, "Active refcount incremented, now %d\n", 729 dev_dbg(codec->dev, "Active refcount incremented, now %d\n",
708 wm8994->active_refcount); 730 wm8994->active_refcount);
709 731
710 if (wm8994->active_refcount == 1) { 732 /* If we're using jack detection go into audio mode */
711 /* If we're using jack detection go into audio mode */ 733 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO);
712 if (wm8994->jackdet && wm8994->jack_cb) {
713 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
714 WM1811_JACKDET_MODE_MASK,
715 WM1811_JACKDET_MODE_AUDIO);
716 msleep(2);
717 }
718 }
719 734
720 mutex_unlock(&wm8994->accdet_lock); 735 mutex_unlock(&wm8994->accdet_lock);
721} 736}
@@ -734,16 +749,12 @@ static void active_dereference(struct snd_soc_codec *codec)
734 749
735 if (wm8994->active_refcount == 0) { 750 if (wm8994->active_refcount == 0) {
736 /* Go into appropriate detection only mode */ 751 /* Go into appropriate detection only mode */
737 if (wm8994->jackdet && wm8994->jack_cb) { 752 if (wm8994->jack_mic || wm8994->mic_detecting)
738 if (wm8994->jack_mic || wm8994->mic_detecting) 753 mode = WM1811_JACKDET_MODE_MIC;
739 mode = WM1811_JACKDET_MODE_MIC; 754 else
740 else 755 mode = WM1811_JACKDET_MODE_JACK;
741 mode = WM1811_JACKDET_MODE_JACK;
742 756
743 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 757 wm1811_jackdet_set_mode(codec, mode);
744 WM1811_JACKDET_MODE_MASK,
745 mode);
746 }
747 } 758 }
748 759
749 mutex_unlock(&wm8994->accdet_lock); 760 mutex_unlock(&wm8994->accdet_lock);
@@ -770,20 +781,33 @@ static void vmid_reference(struct snd_soc_codec *codec)
770{ 781{
771 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 782 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
772 783
784 pm_runtime_get_sync(codec->dev);
785
773 wm8994->vmid_refcount++; 786 wm8994->vmid_refcount++;
774 787
775 dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", 788 dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n",
776 wm8994->vmid_refcount); 789 wm8994->vmid_refcount);
777 790
778 if (wm8994->vmid_refcount == 1) { 791 if (wm8994->vmid_refcount == 1) {
792 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
793 WM8994_LINEOUT_VMID_BUF_ENA |
794 WM8994_LINEOUT1_DISCH |
795 WM8994_LINEOUT2_DISCH,
796 WM8994_LINEOUT_VMID_BUF_ENA);
797
798 wm_hubs_vmid_ena(codec);
799
779 /* Startup bias, VMID ramp & buffer */ 800 /* Startup bias, VMID ramp & buffer */
780 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 801 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
802 WM8994_BIAS_SRC |
803 WM8994_VMID_DISCH |
781 WM8994_STARTUP_BIAS_ENA | 804 WM8994_STARTUP_BIAS_ENA |
782 WM8994_VMID_BUF_ENA | 805 WM8994_VMID_BUF_ENA |
783 WM8994_VMID_RAMP_MASK, 806 WM8994_VMID_RAMP_MASK,
807 WM8994_BIAS_SRC |
784 WM8994_STARTUP_BIAS_ENA | 808 WM8994_STARTUP_BIAS_ENA |
785 WM8994_VMID_BUF_ENA | 809 WM8994_VMID_BUF_ENA |
786 (0x11 << WM8994_VMID_RAMP_SHIFT)); 810 (0x2 << WM8994_VMID_RAMP_SHIFT));
787 811
788 /* Main bias enable, VMID=2x40k */ 812 /* Main bias enable, VMID=2x40k */
789 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, 813 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
@@ -791,7 +815,11 @@ static void vmid_reference(struct snd_soc_codec *codec)
791 WM8994_VMID_SEL_MASK, 815 WM8994_VMID_SEL_MASK,
792 WM8994_BIAS_ENA | 0x2); 816 WM8994_BIAS_ENA | 0x2);
793 817
794 msleep(20); 818 msleep(50);
819
820 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
821 WM8994_VMID_RAMP_MASK | WM8994_BIAS_SRC,
822 0);
795 } 823 }
796} 824}
797 825
@@ -821,6 +849,10 @@ static void vmid_dereference(struct snd_soc_codec *codec)
821 WM8994_BIAS_ENA | 849 WM8994_BIAS_ENA |
822 WM8994_VMID_SEL_MASK, 0); 850 WM8994_VMID_SEL_MASK, 0);
823 851
852 /* Discharge VMID */
853 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
854 WM8994_VMID_DISCH, WM8994_VMID_DISCH);
855
824 /* Discharge line */ 856 /* Discharge line */
825 snd_soc_update_bits(codec, WM8994_ANTIPOP_1, 857 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
826 WM8994_LINEOUT1_DISCH | 858 WM8994_LINEOUT1_DISCH |
@@ -837,6 +869,8 @@ static void vmid_dereference(struct snd_soc_codec *codec)
837 WM8994_VMID_BUF_ENA | 869 WM8994_VMID_BUF_ENA |
838 WM8994_VMID_RAMP_MASK, 0); 870 WM8994_VMID_RAMP_MASK, 0);
839 } 871 }
872
873 pm_runtime_put(codec->dev);
840} 874}
841 875
842static int vmid_event(struct snd_soc_dapm_widget *w, 876static int vmid_event(struct snd_soc_dapm_widget *w,
@@ -1450,17 +1484,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1450 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, 1484 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
1451 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1485 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1452 1486
1453SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1487SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1454SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 1488SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1455SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 1489SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1456SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 1490SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1457 1491
1458SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1492SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
1459SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), 1493SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
1460SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1494SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
1461 1495
1462SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1496SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1463SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1497SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
1464 1498
1465SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), 1499SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
1466 1500
@@ -1575,6 +1609,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1575 1609
1576 { "TOCLK", NULL, "CLK_SYS" }, 1610 { "TOCLK", NULL, "CLK_SYS" },
1577 1611
1612 { "AIF1DACDAT", NULL, "AIF1 Playback" },
1613 { "AIF2DACDAT", NULL, "AIF2 Playback" },
1614 { "AIF3DACDAT", NULL, "AIF3 Playback" },
1615
1616 { "AIF1 Capture", NULL, "AIF1ADCDAT" },
1617 { "AIF2 Capture", NULL, "AIF2ADCDAT" },
1618 { "AIF3 Capture", NULL, "AIF3ADCDAT" },
1619
1578 /* AIF1 outputs */ 1620 /* AIF1 outputs */
1579 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, 1621 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
1580 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, 1622 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
@@ -1887,7 +1929,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
1887 WM8994_FLL1_OUTDIV_MASK | 1929 WM8994_FLL1_OUTDIV_MASK |
1888 WM8994_FLL1_FRATIO_MASK, reg); 1930 WM8994_FLL1_FRATIO_MASK, reg);
1889 1931
1890 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); 1932 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset,
1933 WM8994_FLL1_K_MASK, fll.k);
1891 1934
1892 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, 1935 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
1893 WM8994_FLL1_N_MASK, 1936 WM8994_FLL1_N_MASK,
@@ -2065,6 +2108,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2065 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2108 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2066 struct wm8994 *control = wm8994->wm8994; 2109 struct wm8994 *control = wm8994->wm8994;
2067 2110
2111 wm_hubs_set_bias_level(codec, level);
2112
2068 switch (level) { 2113 switch (level) {
2069 case SND_SOC_BIAS_ON: 2114 case SND_SOC_BIAS_ON:
2070 break; 2115 break;
@@ -2159,6 +2204,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2159 wm8994->cur_fw = NULL; 2204 wm8994->cur_fw = NULL;
2160 break; 2205 break;
2161 } 2206 }
2207
2162 codec->dapm.bias_level = level; 2208 codec->dapm.bias_level = level;
2163 2209
2164 return 0; 2210 return 0;
@@ -2759,13 +2805,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
2759 codec->cache_only = 0; 2805 codec->cache_only = 0;
2760 } 2806 }
2761 2807
2762 /* Restore the registers */
2763 ret = snd_soc_cache_sync(codec);
2764 if (ret != 0)
2765 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
2766
2767 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2768
2769 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2808 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2770 if (!wm8994->fll_suspend[i].out) 2809 if (!wm8994->fll_suspend[i].out)
2771 continue; 2810 continue;
@@ -2867,7 +2906,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
2867 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 2906 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
2868 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 2907 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
2869 2908
2870 ret = snd_soc_add_controls(wm8994->codec, controls, 2909 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2871 ARRAY_SIZE(controls)); 2910 ARRAY_SIZE(controls));
2872 if (ret != 0) 2911 if (ret != 0)
2873 dev_err(wm8994->codec->dev, 2912 dev_err(wm8994->codec->dev,
@@ -2920,7 +2959,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2920 wm8994->drc_enum.max = pdata->num_drc_cfgs; 2959 wm8994->drc_enum.max = pdata->num_drc_cfgs;
2921 wm8994->drc_enum.texts = wm8994->drc_texts; 2960 wm8994->drc_enum.texts = wm8994->drc_texts;
2922 2961
2923 ret = snd_soc_add_controls(wm8994->codec, controls, 2962 ret = snd_soc_add_codec_controls(wm8994->codec, controls,
2924 ARRAY_SIZE(controls)); 2963 ARRAY_SIZE(controls));
2925 if (ret != 0) 2964 if (ret != 0)
2926 dev_err(wm8994->codec->dev, 2965 dev_err(wm8994->codec->dev,
@@ -2936,7 +2975,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2936 if (pdata->num_retune_mobile_cfgs) 2975 if (pdata->num_retune_mobile_cfgs)
2937 wm8994_handle_retune_mobile_pdata(wm8994); 2976 wm8994_handle_retune_mobile_pdata(wm8994);
2938 else 2977 else
2939 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, 2978 snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
2940 ARRAY_SIZE(wm8994_eq_controls)); 2979 ARRAY_SIZE(wm8994_eq_controls));
2941 2980
2942 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { 2981 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -2953,8 +2992,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2953 * @codec: WM8994 codec 2992 * @codec: WM8994 codec
2954 * @jack: jack to report detection events on 2993 * @jack: jack to report detection events on
2955 * @micbias: microphone bias to detect on 2994 * @micbias: microphone bias to detect on
2956 * @det: value to report for presence detection
2957 * @shrt: value to report for short detection
2958 * 2995 *
2959 * Enable microphone detection via IRQ on the WM8994. If GPIOs are 2996 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
2960 * being used to bring out signals to the processor then only platform 2997 * being used to bring out signals to the processor then only platform
@@ -2965,43 +3002,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
2965 * and micbias2_lvl platform data members. 3002 * and micbias2_lvl platform data members.
2966 */ 3003 */
2967int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 3004int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2968 int micbias, int det, int shrt) 3005 int micbias)
2969{ 3006{
2970 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3007 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2971 struct wm8994_micdet *micdet; 3008 struct wm8994_micdet *micdet;
2972 struct wm8994 *control = wm8994->wm8994; 3009 struct wm8994 *control = wm8994->wm8994;
2973 int reg; 3010 int reg, ret;
2974 3011
2975 if (control->type != WM8994) 3012 if (control->type != WM8994) {
3013 dev_warn(codec->dev, "Not a WM8994\n");
2976 return -EINVAL; 3014 return -EINVAL;
3015 }
2977 3016
2978 switch (micbias) { 3017 switch (micbias) {
2979 case 1: 3018 case 1:
2980 micdet = &wm8994->micdet[0]; 3019 micdet = &wm8994->micdet[0];
3020 if (jack)
3021 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3022 "MICBIAS1");
3023 else
3024 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3025 "MICBIAS1");
2981 break; 3026 break;
2982 case 2: 3027 case 2:
2983 micdet = &wm8994->micdet[1]; 3028 micdet = &wm8994->micdet[1];
3029 if (jack)
3030 ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
3031 "MICBIAS1");
3032 else
3033 ret = snd_soc_dapm_disable_pin(&codec->dapm,
3034 "MICBIAS1");
2984 break; 3035 break;
2985 default: 3036 default:
3037 dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
2986 return -EINVAL; 3038 return -EINVAL;
2987 } 3039 }
3040
3041 if (ret != 0)
3042 dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
3043 micbias, ret);
2988 3044
2989 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", 3045 dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
2990 micbias, det, shrt); 3046 micbias, jack);
2991 3047
2992 /* Store the configuration */ 3048 /* Store the configuration */
2993 micdet->jack = jack; 3049 micdet->jack = jack;
2994 micdet->det = det; 3050 micdet->detecting = true;
2995 micdet->shrt = shrt;
2996 3051
2997 /* If either of the jacks is set up then enable detection */ 3052 /* If either of the jacks is set up then enable detection */
2998 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) 3053 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2999 reg = WM8994_MICD_ENA; 3054 reg = WM8994_MICD_ENA;
3000 else 3055 else
3001 reg = 0; 3056 reg = 0;
3002 3057
3003 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); 3058 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3004 3059
3060 snd_soc_dapm_sync(&codec->dapm);
3061
3005 return 0; 3062 return 0;
3006} 3063}
3007EXPORT_SYMBOL_GPL(wm8994_mic_detect); 3064EXPORT_SYMBOL_GPL(wm8994_mic_detect);
@@ -3027,20 +3084,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3027 dev_dbg(codec->dev, "Microphone status: %x\n", reg); 3084 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3028 3085
3029 report = 0; 3086 report = 0;
3030 if (reg & WM8994_MIC1_DET_STS) 3087 if (reg & WM8994_MIC1_DET_STS) {
3031 report |= priv->micdet[0].det; 3088 if (priv->micdet[0].detecting)
3032 if (reg & WM8994_MIC1_SHRT_STS) 3089 report = SND_JACK_HEADSET;
3033 report |= priv->micdet[0].shrt; 3090 }
3091 if (reg & WM8994_MIC1_SHRT_STS) {
3092 if (priv->micdet[0].detecting)
3093 report = SND_JACK_HEADPHONE;
3094 else
3095 report |= SND_JACK_BTN_0;
3096 }
3097 if (report)
3098 priv->micdet[0].detecting = false;
3099 else
3100 priv->micdet[0].detecting = true;
3101
3034 snd_soc_jack_report(priv->micdet[0].jack, report, 3102 snd_soc_jack_report(priv->micdet[0].jack, report,
3035 priv->micdet[0].det | priv->micdet[0].shrt); 3103 SND_JACK_HEADSET | SND_JACK_BTN_0);
3036 3104
3037 report = 0; 3105 report = 0;
3038 if (reg & WM8994_MIC2_DET_STS) 3106 if (reg & WM8994_MIC2_DET_STS) {
3039 report |= priv->micdet[1].det; 3107 if (priv->micdet[1].detecting)
3040 if (reg & WM8994_MIC2_SHRT_STS) 3108 report = SND_JACK_HEADSET;
3041 report |= priv->micdet[1].shrt; 3109 }
3110 if (reg & WM8994_MIC2_SHRT_STS) {
3111 if (priv->micdet[1].detecting)
3112 report = SND_JACK_HEADPHONE;
3113 else
3114 report |= SND_JACK_BTN_0;
3115 }
3116 if (report)
3117 priv->micdet[1].detecting = false;
3118 else
3119 priv->micdet[1].detecting = true;
3120
3042 snd_soc_jack_report(priv->micdet[1].jack, report, 3121 snd_soc_jack_report(priv->micdet[1].jack, report,
3043 priv->micdet[1].det | priv->micdet[1].shrt); 3122 SND_JACK_HEADSET | SND_JACK_BTN_0);
3044 3123
3045 return IRQ_HANDLED; 3124 return IRQ_HANDLED;
3046} 3125}
@@ -3089,7 +3168,7 @@ static void wm8958_default_micdet(u16 status, void *data)
3089 } 3168 }
3090 3169
3091 3170
3092 if (wm8994->mic_detecting && status & 0x4) { 3171 if (wm8994->mic_detecting && status & 0xfc) {
3093 dev_dbg(codec->dev, "Detected headphone\n"); 3172 dev_dbg(codec->dev, "Detected headphone\n");
3094 wm8994->mic_detecting = false; 3173 wm8994->mic_detecting = false;
3095 3174
@@ -3103,6 +3182,14 @@ static void wm8958_default_micdet(u16 status, void *data)
3103 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3182 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3104 WM8958_MICD_ENA, 0); 3183 WM8958_MICD_ENA, 0);
3105 3184
3185 if (wm8994->pdata->jd_ext_cap) {
3186 mutex_lock(&codec->mutex);
3187 snd_soc_dapm_disable_pin(&codec->dapm,
3188 "MICBIAS2");
3189 snd_soc_dapm_sync(&codec->dapm);
3190 mutex_unlock(&codec->mutex);
3191 }
3192
3106 wm1811_jackdet_set_mode(codec, 3193 wm1811_jackdet_set_mode(codec,
3107 WM1811_JACKDET_MODE_JACK); 3194 WM1811_JACKDET_MODE_JACK);
3108 } 3195 }
@@ -3157,21 +3244,52 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3157 snd_soc_jack_report(wm8994->micdet[0].jack, 3244 snd_soc_jack_report(wm8994->micdet[0].jack,
3158 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); 3245 SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
3159 3246
3247 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3248 WM8958_MICB2_DISCH, 0);
3249
3250 /* Disable debounce while inserted */
3251 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3252 WM1811_JACKDET_DB, 0);
3253
3160 /* 3254 /*
3161 * Start off measument of microphone impedence to find 3255 * Start off measument of microphone impedence to find
3162 * out what's actually there. 3256 * out what's actually there.
3163 */ 3257 */
3164 wm8994->mic_detecting = true; 3258 wm8994->mic_detecting = true;
3165 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); 3259 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
3260
3166 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3261 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3167 WM8958_MICD_ENA, WM8958_MICD_ENA); 3262 WM8958_MICD_ENA, WM8958_MICD_ENA);
3263
3264 /* If required for an external cap force MICBIAS on */
3265 if (wm8994->pdata->jd_ext_cap) {
3266 mutex_lock(&codec->mutex);
3267 snd_soc_dapm_force_enable_pin(&codec->dapm,
3268 "MICBIAS2");
3269 snd_soc_dapm_sync(&codec->dapm);
3270 mutex_unlock(&codec->mutex);
3271 }
3168 } else { 3272 } else {
3169 dev_dbg(codec->dev, "Jack not detected\n"); 3273 dev_dbg(codec->dev, "Jack not detected\n");
3170 3274
3275 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3276 WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
3277
3278 if (wm8994->pdata->jd_ext_cap) {
3279 mutex_lock(&codec->mutex);
3280 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3281 snd_soc_dapm_sync(&codec->dapm);
3282 mutex_unlock(&codec->mutex);
3283 }
3284
3171 snd_soc_jack_report(wm8994->micdet[0].jack, 0, 3285 snd_soc_jack_report(wm8994->micdet[0].jack, 0,
3172 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3286 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3173 wm8994->btn_mask); 3287 wm8994->btn_mask);
3174 3288
3289 /* Enable debounce while removed */
3290 snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
3291 WM1811_JACKDET_DB, WM1811_JACKDET_DB);
3292
3175 wm8994->mic_detecting = false; 3293 wm8994->mic_detecting = false;
3176 wm8994->jack_mic = false; 3294 wm8994->jack_mic = false;
3177 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3295 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
@@ -3223,6 +3341,7 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3223 } 3341 }
3224 3342
3225 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); 3343 snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
3344 snd_soc_dapm_sync(&codec->dapm);
3226 3345
3227 wm8994->micdet[0].jack = jack; 3346 wm8994->micdet[0].jack = jack;
3228 wm8994->jack_cb = cb; 3347 wm8994->jack_cb = cb;
@@ -3253,6 +3372,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3253 * otherwise jump straight to microphone detection. 3372 * otherwise jump straight to microphone detection.
3254 */ 3373 */
3255 if (wm8994->jackdet) { 3374 if (wm8994->jackdet) {
3375 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3376 WM8958_MICB2_DISCH,
3377 WM8958_MICB2_DISCH);
3256 snd_soc_update_bits(codec, WM8994_LDO_1, 3378 snd_soc_update_bits(codec, WM8994_LDO_1,
3257 WM8994_LDO1_DISCH, 0); 3379 WM8994_LDO1_DISCH, 0);
3258 wm1811_jackdet_set_mode(codec, 3380 wm1811_jackdet_set_mode(codec,
@@ -3265,7 +3387,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3265 } else { 3387 } else {
3266 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 3388 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3267 WM8958_MICD_ENA, 0); 3389 WM8958_MICD_ENA, 0);
3390 wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE);
3268 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); 3391 snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS");
3392 snd_soc_dapm_sync(&codec->dapm);
3269 } 3393 }
3270 3394
3271 return 0; 3395 return 0;
@@ -3363,23 +3487,16 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data)
3363static int wm8994_codec_probe(struct snd_soc_codec *codec) 3487static int wm8994_codec_probe(struct snd_soc_codec *codec)
3364{ 3488{
3365 struct wm8994 *control = dev_get_drvdata(codec->dev->parent); 3489 struct wm8994 *control = dev_get_drvdata(codec->dev->parent);
3366 struct wm8994_priv *wm8994; 3490 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3367 struct snd_soc_dapm_context *dapm = &codec->dapm; 3491 struct snd_soc_dapm_context *dapm = &codec->dapm;
3368 unsigned int reg; 3492 unsigned int reg;
3369 int ret, i; 3493 int ret, i;
3370 3494
3495 wm8994->codec = codec;
3371 codec->control_data = control->regmap; 3496 codec->control_data = control->regmap;
3372 3497
3373 wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv),
3374 GFP_KERNEL);
3375 if (wm8994 == NULL)
3376 return -ENOMEM;
3377 snd_soc_codec_set_drvdata(codec, wm8994);
3378
3379 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 3498 snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
3380 3499
3381 wm8994->wm8994 = dev_get_drvdata(codec->dev->parent);
3382 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3383 wm8994->codec = codec; 3500 wm8994->codec = codec;
3384 3501
3385 mutex_init(&wm8994->accdet_lock); 3502 mutex_init(&wm8994->accdet_lock);
@@ -3394,12 +3511,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3394 WM8994_IRQ_MIC1_DET; 3511 WM8994_IRQ_MIC1_DET;
3395 3512
3396 pm_runtime_enable(codec->dev); 3513 pm_runtime_enable(codec->dev);
3397 pm_runtime_resume(codec->dev); 3514 pm_runtime_idle(codec->dev);
3515
3516 /* By default use idle_bias_off, will override for WM8994 */
3517 codec->dapm.idle_bias_off = 1;
3398 3518
3399 /* Set revision-specific configuration */ 3519 /* Set revision-specific configuration */
3400 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 3520 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3401 switch (control->type) { 3521 switch (control->type) {
3402 case WM8994: 3522 case WM8994:
3523 /* Single ended line outputs should have VMID on. */
3524 if (!wm8994->pdata->lineout1_diff ||
3525 !wm8994->pdata->lineout2_diff)
3526 codec->dapm.idle_bias_off = 0;
3527
3403 switch (wm8994->revision) { 3528 switch (wm8994->revision) {
3404 case 2: 3529 case 2:
3405 case 3: 3530 case 3:
@@ -3417,11 +3542,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3417 3542
3418 case WM8958: 3543 case WM8958:
3419 wm8994->hubs.dcs_readback_mode = 1; 3544 wm8994->hubs.dcs_readback_mode = 1;
3545 wm8994->hubs.hp_startup_mode = 1;
3420 break; 3546 break;
3421 3547
3422 case WM1811: 3548 case WM1811:
3423 wm8994->hubs.dcs_readback_mode = 2; 3549 wm8994->hubs.dcs_readback_mode = 2;
3424 wm8994->hubs.no_series_update = 1; 3550 wm8994->hubs.no_series_update = 1;
3551 wm8994->hubs.hp_startup_mode = 1;
3552 wm8994->hubs.no_cache_class_w = true;
3425 3553
3426 switch (wm8994->revision) { 3554 switch (wm8994->revision) {
3427 case 0: 3555 case 0:
@@ -3538,6 +3666,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3538 wm8994->fll_locked_irq = false; 3666 wm8994->fll_locked_irq = false;
3539 } 3667 }
3540 3668
3669 /* Make sure we can read from the GPIOs if they're inputs */
3670 pm_runtime_get_sync(codec->dev);
3671
3541 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3672 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3542 * configured on init - if a system wants to do this dynamically 3673 * configured on init - if a system wants to do this dynamically
3543 * at runtime we can deal with that then. 3674 * at runtime we can deal with that then.
@@ -3566,7 +3697,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3566 wm8994->lrclk_shared[1] = 0; 3697 wm8994->lrclk_shared[1] = 0;
3567 } 3698 }
3568 3699
3569 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3700 pm_runtime_put(codec->dev);
3570 3701
3571 /* Latch volume updates (right only; we always do left then right). */ 3702 /* Latch volume updates (right only; we always do left then right). */
3572 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, 3703 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
@@ -3644,7 +3775,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3644 wm8994_handle_pdata(wm8994); 3775 wm8994_handle_pdata(wm8994);
3645 3776
3646 wm_hubs_add_analogue_controls(codec); 3777 wm_hubs_add_analogue_controls(codec);
3647 snd_soc_add_controls(codec, wm8994_snd_controls, 3778 snd_soc_add_codec_controls(codec, wm8994_snd_controls,
3648 ARRAY_SIZE(wm8994_snd_controls)); 3779 ARRAY_SIZE(wm8994_snd_controls));
3649 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, 3780 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
3650 ARRAY_SIZE(wm8994_dapm_widgets)); 3781 ARRAY_SIZE(wm8994_dapm_widgets));
@@ -3670,7 +3801,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3670 } 3801 }
3671 break; 3802 break;
3672 case WM8958: 3803 case WM8958:
3673 snd_soc_add_controls(codec, wm8958_snd_controls, 3804 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3674 ARRAY_SIZE(wm8958_snd_controls)); 3805 ARRAY_SIZE(wm8958_snd_controls));
3675 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3806 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3676 ARRAY_SIZE(wm8958_dapm_widgets)); 3807 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3692,7 +3823,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3692 break; 3823 break;
3693 3824
3694 case WM1811: 3825 case WM1811:
3695 snd_soc_add_controls(codec, wm8958_snd_controls, 3826 snd_soc_add_codec_controls(codec, wm8958_snd_controls,
3696 ARRAY_SIZE(wm8958_snd_controls)); 3827 ARRAY_SIZE(wm8958_snd_controls));
3697 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, 3828 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3698 ARRAY_SIZE(wm8958_dapm_widgets)); 3829 ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3821,24 +3952,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
3821 return 0; 3952 return 0;
3822} 3953}
3823 3954
3824static int wm8994_soc_volatile(struct snd_soc_codec *codec,
3825 unsigned int reg)
3826{
3827 return true;
3828}
3829
3830static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { 3955static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
3831 .probe = wm8994_codec_probe, 3956 .probe = wm8994_codec_probe,
3832 .remove = wm8994_codec_remove, 3957 .remove = wm8994_codec_remove,
3833 .suspend = wm8994_suspend, 3958 .suspend = wm8994_suspend,
3834 .resume = wm8994_resume, 3959 .resume = wm8994_resume,
3835 .set_bias_level = wm8994_set_bias_level, 3960 .set_bias_level = wm8994_set_bias_level,
3836 .reg_cache_size = WM8994_MAX_REGISTER,
3837 .volatile_register = wm8994_soc_volatile,
3838}; 3961};
3839 3962
3840static int __devinit wm8994_probe(struct platform_device *pdev) 3963static int __devinit wm8994_probe(struct platform_device *pdev)
3841{ 3964{
3965 struct wm8994_priv *wm8994;
3966
3967 wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv),
3968 GFP_KERNEL);
3969 if (wm8994 == NULL)
3970 return -ENOMEM;
3971 platform_set_drvdata(pdev, wm8994);
3972
3973 wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
3974 wm8994->pdata = dev_get_platdata(pdev->dev.parent);
3975
3842 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, 3976 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
3843 wm8994_dai, ARRAY_SIZE(wm8994_dai)); 3977 wm8994_dai, ARRAY_SIZE(wm8994_dai));
3844} 3978}
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index c3a42474ab19..f996d14766d9 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -35,7 +35,7 @@
35typedef void (*wm8958_micdet_cb)(u16 status, void *data); 35typedef void (*wm8958_micdet_cb)(u16 status, void *data);
36 36
37int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 37int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
38 int micbias, int det, int shrt); 38 int micbias);
39int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 39int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
40 wm8958_micdet_cb cb, void *cb_data); 40 wm8958_micdet_cb cb, void *cb_data);
41 41
@@ -46,8 +46,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec);
46 46
47struct wm8994_micdet { 47struct wm8994_micdet {
48 struct snd_soc_jack *jack; 48 struct snd_soc_jack *jack;
49 int det; 49 bool detecting;
50 int shrt;
51}; 50};
52 51
53/* codec private data */ 52/* codec private data */
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index c8aada597d70..28c89b094c6e 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2047,7 +2047,6 @@ static int wm8995_probe(struct snd_soc_codec *codec)
2047 int i; 2047 int i;
2048 int ret; 2048 int ret;
2049 2049
2050 codec->dapm.idle_bias_off = 1;
2051 wm8995 = snd_soc_codec_get_drvdata(codec); 2050 wm8995 = snd_soc_codec_get_drvdata(codec);
2052 wm8995->codec = codec; 2051 wm8995->codec = codec;
2053 2052
@@ -2137,7 +2136,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
2137 2136
2138 wm8995_update_class_w(codec); 2137 wm8995_update_class_w(codec);
2139 2138
2140 snd_soc_add_controls(codec, wm8995_snd_controls, 2139 snd_soc_add_codec_controls(codec, wm8995_snd_controls,
2141 ARRAY_SIZE(wm8995_snd_controls)); 2140 ARRAY_SIZE(wm8995_snd_controls));
2142 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, 2141 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
2143 ARRAY_SIZE(wm8995_dapm_widgets)); 2142 ARRAY_SIZE(wm8995_dapm_widgets));
@@ -2241,6 +2240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
2241 .suspend = wm8995_suspend, 2240 .suspend = wm8995_suspend,
2242 .resume = wm8995_resume, 2241 .resume = wm8995_resume,
2243 .set_bias_level = wm8995_set_bias_level, 2242 .set_bias_level = wm8995_set_bias_level,
2243 .idle_bias_off = true,
2244}; 2244};
2245 2245
2246static struct regmap_config wm8995_regmap = { 2246static struct regmap_config wm8995_regmap = {
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 8e8f8d1fef91..9376b19941b6 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -73,7 +73,6 @@ struct wm8996_priv {
73 73
74 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; 74 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
75 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; 75 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
76 struct regulator *cpvdd;
77 int bg_ena; 76 int bg_ena;
78 77
79 struct wm8996_pdata pdata; 78 struct wm8996_pdata pdata;
@@ -90,6 +89,7 @@ struct wm8996_priv {
90 struct snd_soc_jack *jack; 89 struct snd_soc_jack *jack;
91 bool detecting; 90 bool detecting;
92 bool jack_mic; 91 bool jack_mic;
92 int jack_flips;
93 wm8996_polarity_fn polarity_cb; 93 wm8996_polarity_fn polarity_cb;
94 94
95#ifdef CONFIG_GPIOLIB 95#ifdef CONFIG_GPIOLIB
@@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
108 struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ 108 struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
109 disable_nb[n]); \ 109 disable_nb[n]); \
110 if (event & REGULATOR_EVENT_DISABLE) { \ 110 if (event & REGULATOR_EVENT_DISABLE) { \
111 regcache_cache_only(wm8996->regmap, true); \ 111 regcache_mark_dirty(wm8996->regmap); \
112 } \ 112 } \
113 return 0; \ 113 return 0; \
114} 114}
@@ -716,10 +716,16 @@ SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
716SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), 716SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
717SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), 717SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
718SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), 718SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
719SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5,
720 WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA |
721 WM8996_DSP1TXR_DRC_ENA),
719 722
720SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), 723SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
721SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), 724SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
722SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), 725SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
726SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5,
727 WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA |
728 WM8996_DSP2TXR_DRC_ENA),
723}; 729};
724 730
725static const struct snd_kcontrol_new wm8996_eq_controls[] = { 731static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -792,29 +798,18 @@ static int bg_event(struct snd_soc_dapm_widget *w,
792static int cp_event(struct snd_soc_dapm_widget *w, 798static int cp_event(struct snd_soc_dapm_widget *w,
793 struct snd_kcontrol *kcontrol, int event) 799 struct snd_kcontrol *kcontrol, int event)
794{ 800{
795 struct snd_soc_codec *codec = w->codec;
796 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
797 int ret = 0; 801 int ret = 0;
798 802
799 switch (event) { 803 switch (event) {
800 case SND_SOC_DAPM_PRE_PMU:
801 ret = regulator_enable(wm8996->cpvdd);
802 if (ret != 0)
803 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
804 ret);
805 break;
806 case SND_SOC_DAPM_POST_PMU: 804 case SND_SOC_DAPM_POST_PMU:
807 msleep(5); 805 msleep(5);
808 break; 806 break;
809 case SND_SOC_DAPM_POST_PMD:
810 regulator_disable_deferred(wm8996->cpvdd, 20);
811 break;
812 default: 807 default:
813 BUG(); 808 BUG();
814 ret = -EINVAL; 809 ret = -EINVAL;
815 } 810 }
816 811
817 return ret; 812 return 0;
818} 813}
819 814
820static int rmv_short_event(struct snd_soc_dapm_widget *w, 815static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -1116,11 +1111,12 @@ SND_SOC_DAPM_INPUT("IN2RP"),
1116SND_SOC_DAPM_INPUT("DMIC1DAT"), 1111SND_SOC_DAPM_INPUT("DMIC1DAT"),
1117SND_SOC_DAPM_INPUT("DMIC2DAT"), 1112SND_SOC_DAPM_INPUT("DMIC2DAT"),
1118 1113
1114SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
1119SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), 1115SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
1120SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), 1116SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
1121SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), 1117SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
1122SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, 1118SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
1123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1119 SND_SOC_DAPM_POST_PMU),
1124SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, 1120SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
1125 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1121 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1126SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), 1122SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
@@ -1179,41 +1175,25 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),
1179SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), 1175SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),
1180SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), 1176SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),
1181 1177
1182SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, 1178SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0),
1183 WM8996_POWER_MANAGEMENT_4, 9, 0), 1179SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0),
1184SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1, 1180
1185 WM8996_POWER_MANAGEMENT_4, 8, 0), 1181SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0),
1186 1182SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0),
1187SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, 1183
1188 WM8996_POWER_MANAGEMENT_6, 9, 0), 1184SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0),
1189SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1, 1185SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0),
1190 WM8996_POWER_MANAGEMENT_6, 8, 0), 1186SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0),
1191 1187SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0),
1192SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, 1188SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0),
1193 WM8996_POWER_MANAGEMENT_4, 5, 0), 1189SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0),
1194SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, 1190
1195 WM8996_POWER_MANAGEMENT_4, 4, 0), 1191SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0),
1196SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, 1192SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0),
1197 WM8996_POWER_MANAGEMENT_4, 3, 0), 1193SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0),
1198SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, 1194SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0),
1199 WM8996_POWER_MANAGEMENT_4, 2, 0), 1195SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0),
1200SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, 1196SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0),
1201 WM8996_POWER_MANAGEMENT_4, 1, 0),
1202SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1203 WM8996_POWER_MANAGEMENT_4, 0, 0),
1204
1205SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1206 WM8996_POWER_MANAGEMENT_6, 5, 0),
1207SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1208 WM8996_POWER_MANAGEMENT_6, 4, 0),
1209SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1210 WM8996_POWER_MANAGEMENT_6, 3, 0),
1211SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1212 WM8996_POWER_MANAGEMENT_6, 2, 0),
1213SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1214 WM8996_POWER_MANAGEMENT_6, 1, 0),
1215SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1216 WM8996_POWER_MANAGEMENT_6, 0, 0),
1217 1197
1218/* We route as stereo pairs so define some dummy widgets to squash 1198/* We route as stereo pairs so define some dummy widgets to squash
1219 * things down for now. RXA = 0,1, RXB = 2,3 and so on */ 1199 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
@@ -1279,6 +1259,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1279 { "AIFCLK", NULL, "SYSCLK" }, 1259 { "AIFCLK", NULL, "SYSCLK" },
1280 { "SYSDSPCLK", NULL, "SYSCLK" }, 1260 { "SYSDSPCLK", NULL, "SYSCLK" },
1281 { "Charge Pump", NULL, "SYSCLK" }, 1261 { "Charge Pump", NULL, "SYSCLK" },
1262 { "Charge Pump", NULL, "CPVDD" },
1282 1263
1283 { "MICB1", NULL, "LDO2" }, 1264 { "MICB1", NULL, "LDO2" },
1284 { "MICB1", NULL, "MICB1 Audio" }, 1265 { "MICB1", NULL, "MICB1 Audio" },
@@ -1287,6 +1268,26 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
1287 { "MICB2", NULL, "MICB2 Audio" }, 1268 { "MICB2", NULL, "MICB2 Audio" },
1288 { "MICB2", NULL, "Bandgap" }, 1269 { "MICB2", NULL, "Bandgap" },
1289 1270
1271 { "AIF1RX0", NULL, "AIF1 Playback" },
1272 { "AIF1RX1", NULL, "AIF1 Playback" },
1273 { "AIF1RX2", NULL, "AIF1 Playback" },
1274 { "AIF1RX3", NULL, "AIF1 Playback" },
1275 { "AIF1RX4", NULL, "AIF1 Playback" },
1276 { "AIF1RX5", NULL, "AIF1 Playback" },
1277
1278 { "AIF2RX0", NULL, "AIF2 Playback" },
1279 { "AIF2RX1", NULL, "AIF2 Playback" },
1280
1281 { "AIF1 Capture", NULL, "AIF1TX0" },
1282 { "AIF1 Capture", NULL, "AIF1TX1" },
1283 { "AIF1 Capture", NULL, "AIF1TX2" },
1284 { "AIF1 Capture", NULL, "AIF1TX3" },
1285 { "AIF1 Capture", NULL, "AIF1TX4" },
1286 { "AIF1 Capture", NULL, "AIF1TX5" },
1287
1288 { "AIF2 Capture", NULL, "AIF2TX0" },
1289 { "AIF2 Capture", NULL, "AIF2TX1" },
1290
1290 { "IN1L PGA", NULL, "IN2LN" }, 1291 { "IN1L PGA", NULL, "IN2LN" },
1291 { "IN1L PGA", NULL, "IN2LP" }, 1292 { "IN1L PGA", NULL, "IN2LP" },
1292 { "IN1L PGA", NULL, "IN1LN" }, 1293 { "IN1L PGA", NULL, "IN1LN" },
@@ -1719,6 +1720,7 @@ static int wm8996_reset(struct wm8996_priv *wm8996)
1719{ 1720{
1720 if (wm8996->pdata.ldo_ena > 0) { 1721 if (wm8996->pdata.ldo_ena > 0) {
1721 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 1722 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1723 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
1722 return 0; 1724 return 0;
1723 } else { 1725 } else {
1724 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, 1726 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
@@ -2437,6 +2439,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2437 wm8996->jack = jack; 2439 wm8996->jack = jack;
2438 wm8996->detecting = true; 2440 wm8996->detecting = true;
2439 wm8996->polarity_cb = polarity_cb; 2441 wm8996->polarity_cb = polarity_cb;
2442 wm8996->jack_flips = 0;
2440 2443
2441 if (wm8996->polarity_cb) 2444 if (wm8996->polarity_cb)
2442 wm8996->polarity_cb(codec, 0); 2445 wm8996->polarity_cb(codec, 0);
@@ -2552,6 +2555,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec)
2552 WM8996_HP_POLL, WM8996_HP_POLL); 2555 WM8996_HP_POLL, WM8996_HP_POLL);
2553} 2556}
2554 2557
2558static void wm8996_report_headphone(struct snd_soc_codec *codec)
2559{
2560 dev_dbg(codec->dev, "Headphone detected\n");
2561 wm8996_hpdet_start(codec);
2562
2563 /* Increase the detection rate a bit for responsiveness. */
2564 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2565 WM8996_MICD_RATE_MASK |
2566 WM8996_MICD_BIAS_STARTTIME_MASK,
2567 7 << WM8996_MICD_RATE_SHIFT |
2568 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
2569}
2570
2555static void wm8996_micd(struct snd_soc_codec *codec) 2571static void wm8996_micd(struct snd_soc_codec *codec)
2556{ 2572{
2557 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2573 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2571,6 +2587,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2571 dev_dbg(codec->dev, "Jack removal detected\n"); 2587 dev_dbg(codec->dev, "Jack removal detected\n");
2572 wm8996->jack_mic = false; 2588 wm8996->jack_mic = false;
2573 wm8996->detecting = true; 2589 wm8996->detecting = true;
2590 wm8996->jack_flips = 0;
2574 snd_soc_jack_report(wm8996->jack, 0, 2591 snd_soc_jack_report(wm8996->jack, 0,
2575 SND_JACK_LINEOUT | SND_JACK_HEADSET | 2592 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2576 SND_JACK_BTN_0); 2593 SND_JACK_BTN_0);
@@ -2611,9 +2628,17 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2611 /* If we detected a lower impedence during initial startup 2628 /* If we detected a lower impedence during initial startup
2612 * then we probably have the wrong polarity, flip it. Don't 2629 * then we probably have the wrong polarity, flip it. Don't
2613 * do this for the lowest impedences to speed up detection of 2630 * do this for the lowest impedences to speed up detection of
2614 * plain headphones. 2631 * plain headphones. If both polarities report a low
2632 * impedence then give up and report headphones.
2615 */ 2633 */
2616 if (wm8996->detecting && (val & 0x3f0)) { 2634 if (wm8996->detecting && (val & 0x3f0)) {
2635 wm8996->jack_flips++;
2636
2637 if (wm8996->jack_flips > 1) {
2638 wm8996_report_headphone(codec);
2639 return;
2640 }
2641
2617 reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); 2642 reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
2618 reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | 2643 reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
2619 WM8996_MICD_BIAS_SRC; 2644 WM8996_MICD_BIAS_SRC;
@@ -2640,17 +2665,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
2640 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, 2665 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
2641 SND_JACK_BTN_0); 2666 SND_JACK_BTN_0);
2642 } else if (wm8996->detecting) { 2667 } else if (wm8996->detecting) {
2643 dev_dbg(codec->dev, "Headphone detected\n"); 2668 wm8996_report_headphone(codec);
2644 wm8996_hpdet_start(codec);
2645
2646 /* Increase the detection rate a bit for
2647 * responsiveness.
2648 */
2649 snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
2650 WM8996_MICD_RATE_MASK |
2651 WM8996_MICD_BIAS_STARTTIME_MASK,
2652 7 << WM8996_MICD_RATE_SHIFT |
2653 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
2654 } 2669 }
2655 } 2670 }
2656} 2671}
@@ -2767,7 +2782,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
2767 wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; 2782 wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts;
2768 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; 2783 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
2769 2784
2770 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); 2785 ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
2771 if (ret != 0) 2786 if (ret != 0)
2772 dev_err(codec->dev, 2787 dev_err(codec->dev,
2773 "Failed to add ReTune Mobile controls: %d\n", ret); 2788 "Failed to add ReTune Mobile controls: %d\n", ret);
@@ -2790,7 +2805,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2790 int ret; 2805 int ret;
2791 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2806 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2792 struct i2c_client *i2c = to_i2c_client(codec->dev); 2807 struct i2c_client *i2c = to_i2c_client(codec->dev);
2793 struct snd_soc_dapm_context *dapm = &codec->dapm;
2794 int i, irq_flags; 2808 int i, irq_flags;
2795 2809
2796 wm8996->codec = codec; 2810 wm8996->codec = codec;
@@ -2798,8 +2812,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2798 init_completion(&wm8996->dcs_done); 2812 init_completion(&wm8996->dcs_done);
2799 init_completion(&wm8996->fll_lock); 2813 init_completion(&wm8996->fll_lock);
2800 2814
2801 dapm->idle_bias_off = true;
2802
2803 codec->control_data = wm8996->regmap; 2815 codec->control_data = wm8996->regmap;
2804 2816
2805 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); 2817 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
@@ -2965,7 +2977,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2965 if (wm8996->pdata.num_retune_mobile_cfgs) 2977 if (wm8996->pdata.num_retune_mobile_cfgs)
2966 wm8996_retune_mobile_pdata(codec); 2978 wm8996_retune_mobile_pdata(codec);
2967 else 2979 else
2968 snd_soc_add_controls(codec, wm8996_eq_controls, 2980 snd_soc_add_codec_controls(codec, wm8996_eq_controls,
2969 ARRAY_SIZE(wm8996_eq_controls)); 2981 ARRAY_SIZE(wm8996_eq_controls));
2970 2982
2971 /* If the TX LRCLK pins are not in LRCLK mode configure the 2983 /* If the TX LRCLK pins are not in LRCLK mode configure the
@@ -3037,22 +3049,16 @@ static int wm8996_remove(struct snd_soc_codec *codec)
3037 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3049 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3038 regulator_unregister_notifier(wm8996->supplies[i].consumer, 3050 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3039 &wm8996->disable_nb[i]); 3051 &wm8996->disable_nb[i]);
3040 regulator_put(wm8996->cpvdd);
3041 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3052 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3042 3053
3043 return 0; 3054 return 0;
3044} 3055}
3045 3056
3046static int wm8996_soc_volatile_register(struct snd_soc_codec *codec,
3047 unsigned int reg)
3048{
3049 return true;
3050}
3051
3052static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { 3057static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
3053 .probe = wm8996_probe, 3058 .probe = wm8996_probe,
3054 .remove = wm8996_remove, 3059 .remove = wm8996_remove,
3055 .set_bias_level = wm8996_set_bias_level, 3060 .set_bias_level = wm8996_set_bias_level,
3061 .idle_bias_off = true,
3056 .seq_notifier = wm8996_seq_notifier, 3062 .seq_notifier = wm8996_seq_notifier,
3057 .controls = wm8996_snd_controls, 3063 .controls = wm8996_snd_controls,
3058 .num_controls = ARRAY_SIZE(wm8996_snd_controls), 3064 .num_controls = ARRAY_SIZE(wm8996_snd_controls),
@@ -3061,8 +3067,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
3061 .dapm_routes = wm8996_dapm_routes, 3067 .dapm_routes = wm8996_dapm_routes,
3062 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), 3068 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),
3063 .set_pll = wm8996_set_fll, 3069 .set_pll = wm8996_set_fll,
3064 .reg_cache_size = WM8996_MAX_REGISTER,
3065 .volatile_register = wm8996_soc_volatile_register,
3066}; 3070};
3067 3071
3068#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 3072#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -3152,25 +3156,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3152 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) 3156 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3153 wm8996->supplies[i].supply = wm8996_supply_names[i]; 3157 wm8996->supplies[i].supply = wm8996_supply_names[i];
3154 3158
3155 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), 3159 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
3156 wm8996->supplies); 3160 wm8996->supplies);
3157 if (ret != 0) { 3161 if (ret != 0) {
3158 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); 3162 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
3159 goto err_gpio; 3163 goto err_gpio;
3160 } 3164 }
3161 3165
3162 wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
3163 if (IS_ERR(wm8996->cpvdd)) {
3164 ret = PTR_ERR(wm8996->cpvdd);
3165 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
3166 goto err_get;
3167 }
3168
3169 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), 3166 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3170 wm8996->supplies); 3167 wm8996->supplies);
3171 if (ret != 0) { 3168 if (ret != 0) {
3172 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 3169 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
3173 goto err_cpvdd; 3170 goto err_gpio;
3174 } 3171 }
3175 3172
3176 if (wm8996->pdata.ldo_ena > 0) { 3173 if (wm8996->pdata.ldo_ena > 0) {
@@ -3191,7 +3188,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3191 goto err_regmap; 3188 goto err_regmap;
3192 } 3189 }
3193 if (reg != 0x8915) { 3190 if (reg != 0x8915) {
3194 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); 3191 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);
3195 ret = -EINVAL; 3192 ret = -EINVAL;
3196 goto err_regmap; 3193 goto err_regmap;
3197 } 3194 }
@@ -3232,10 +3229,6 @@ err_enable:
3232 if (wm8996->pdata.ldo_ena > 0) 3229 if (wm8996->pdata.ldo_ena > 0)
3233 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3230 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3234 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 3231 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3235err_cpvdd:
3236 regulator_put(wm8996->cpvdd);
3237err_get:
3238 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3239err_gpio: 3232err_gpio:
3240 if (wm8996->pdata.ldo_ena > 0) 3233 if (wm8996->pdata.ldo_ena > 0)
3241 gpio_free(wm8996->pdata.ldo_ena); 3234 gpio_free(wm8996->pdata.ldo_ena);
@@ -3250,8 +3243,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3250 3243
3251 snd_soc_unregister_codec(&client->dev); 3244 snd_soc_unregister_codec(&client->dev);
3252 wm8996_free_gpio(wm8996); 3245 wm8996_free_gpio(wm8996);
3253 regulator_put(wm8996->cpvdd);
3254 regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3255 regmap_exit(wm8996->regmap); 3246 regmap_exit(wm8996->regmap);
3256 if (wm8996->pdata.ldo_ena > 0) { 3247 if (wm8996->pdata.ldo_ena > 0) {
3257 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3248 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3276,25 +3267,7 @@ static struct i2c_driver wm8996_i2c_driver = {
3276 .id_table = wm8996_i2c_id, 3267 .id_table = wm8996_i2c_id,
3277}; 3268};
3278 3269
3279static int __init wm8996_modinit(void) 3270module_i2c_driver(wm8996_i2c_driver);
3280{
3281 int ret;
3282
3283 ret = i2c_add_driver(&wm8996_i2c_driver);
3284 if (ret != 0) {
3285 printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n",
3286 ret);
3287 }
3288
3289 return ret;
3290}
3291module_init(wm8996_modinit);
3292
3293static void __exit wm8996_exit(void)
3294{
3295 i2c_del_driver(&wm8996_i2c_driver);
3296}
3297module_exit(wm8996_exit);
3298 3271
3299MODULE_DESCRIPTION("ASoC WM8996 driver"); 3272MODULE_DESCRIPTION("ASoC WM8996 driver");
3300MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3273MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a6bab392700e..076c126ed9b1 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
824static int wm9081_set_bias_level(struct snd_soc_codec *codec, 824static int wm9081_set_bias_level(struct snd_soc_codec *codec,
825 enum snd_soc_bias_level level) 825 enum snd_soc_bias_level level)
826{ 826{
827 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
828
827 switch (level) { 829 switch (level) {
828 case SND_SOC_BIAS_ON: 830 case SND_SOC_BIAS_ON:
829 break; 831 break;
@@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
841 case SND_SOC_BIAS_STANDBY: 843 case SND_SOC_BIAS_STANDBY:
842 /* Initial cold start */ 844 /* Initial cold start */
843 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 845 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
846 regcache_cache_only(wm9081->regmap, false);
847 regcache_sync(wm9081->regmap);
848
844 /* Disable LINEOUT discharge */ 849 /* Disable LINEOUT discharge */
845 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, 850 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
846 WM9081_LINEOUT_DISCH, 0); 851 WM9081_LINEOUT_DISCH, 0);
@@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
892 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, 897 snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
893 WM9081_LINEOUT_DISCH, 898 WM9081_LINEOUT_DISCH,
894 WM9081_LINEOUT_DISCH); 899 WM9081_LINEOUT_DISCH);
900
901 regcache_cache_only(wm9081->regmap, true);
895 break; 902 break;
896 } 903 }
897 904
@@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1258{ 1265{
1259 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1266 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1260 int ret; 1267 int ret;
1261 u16 reg;
1262 1268
1263 codec->control_data = wm9081->regmap; 1269 codec->control_data = wm9081->regmap;
1264 1270
@@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1268 return ret; 1274 return ret;
1269 } 1275 }
1270 1276
1271 reg = 0;
1272 if (wm9081->pdata.irq_high)
1273 reg |= WM9081_IRQ_POL;
1274 if (!wm9081->pdata.irq_cmos)
1275 reg |= WM9081_IRQ_OP_CTRL;
1276 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1277 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1278
1279 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1280
1281 /* Enable zero cross by default */ 1277 /* Enable zero cross by default */
1282 snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, 1278 snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
1283 WM9081_LINEOUTZC, WM9081_LINEOUTZC); 1279 WM9081_LINEOUTZC, WM9081_LINEOUTZC);
@@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1287 if (!wm9081->pdata.num_retune_configs) { 1283 if (!wm9081->pdata.num_retune_configs) {
1288 dev_dbg(codec->dev, 1284 dev_dbg(codec->dev,
1289 "No ReTune Mobile data, using normal EQ\n"); 1285 "No ReTune Mobile data, using normal EQ\n");
1290 snd_soc_add_controls(codec, wm9081_eq_controls, 1286 snd_soc_add_codec_controls(codec, wm9081_eq_controls,
1291 ARRAY_SIZE(wm9081_eq_controls)); 1287 ARRAY_SIZE(wm9081_eq_controls));
1292 } 1288 }
1293 1289
@@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec)
1300 return 0; 1296 return 0;
1301} 1297}
1302 1298
1303#ifdef CONFIG_PM
1304static int wm9081_suspend(struct snd_soc_codec *codec)
1305{
1306 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1307
1308 return 0;
1309}
1310
1311static int wm9081_resume(struct snd_soc_codec *codec)
1312{
1313 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1314
1315 regcache_sync(wm9081->regmap);
1316
1317 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1318
1319 return 0;
1320}
1321#else
1322#define wm9081_suspend NULL
1323#define wm9081_resume NULL
1324#endif
1325
1326static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { 1299static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1327 .probe = wm9081_probe, 1300 .probe = wm9081_probe,
1328 .remove = wm9081_remove, 1301 .remove = wm9081_remove,
1329 .suspend = wm9081_suspend,
1330 .resume = wm9081_resume,
1331 1302
1332 .set_sysclk = wm9081_set_sysclk, 1303 .set_sysclk = wm9081_set_sysclk,
1333 .set_bias_level = wm9081_set_bias_level, 1304 .set_bias_level = wm9081_set_bias_level,
1334 1305
1306 .idle_bias_off = true,
1307
1335 .controls = wm9081_snd_controls, 1308 .controls = wm9081_snd_controls,
1336 .num_controls = ARRAY_SIZE(wm9081_snd_controls), 1309 .num_controls = ARRAY_SIZE(wm9081_snd_controls),
1337 .dapm_widgets = wm9081_dapm_widgets, 1310 .dapm_widgets = wm9081_dapm_widgets,
@@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1395 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), 1368 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1396 sizeof(wm9081->pdata)); 1369 sizeof(wm9081->pdata));
1397 1370
1371 reg = 0;
1372 if (wm9081->pdata.irq_high)
1373 reg |= WM9081_IRQ_POL;
1374 if (!wm9081->pdata.irq_cmos)
1375 reg |= WM9081_IRQ_OP_CTRL;
1376 regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL,
1377 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1378
1379 regcache_cache_only(wm9081->regmap, true);
1380
1398 ret = snd_soc_register_codec(&i2c->dev, 1381 ret = snd_soc_register_codec(&i2c->dev,
1399 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1382 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1400 if (ret < 0) 1383 if (ret < 0)
@@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = {
1435}; 1418};
1436#endif 1419#endif
1437 1420
1438static int __init wm9081_modinit(void) 1421module_i2c_driver(wm9081_i2c_driver);
1439{
1440 int ret = 0;
1441#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1442 ret = i2c_add_driver(&wm9081_i2c_driver);
1443 if (ret != 0) {
1444 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
1445 ret);
1446 }
1447#endif
1448 return ret;
1449}
1450module_init(wm9081_modinit);
1451
1452static void __exit wm9081_exit(void)
1453{
1454#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1455 i2c_del_driver(&wm9081_i2c_driver);
1456#endif
1457}
1458module_exit(wm9081_exit);
1459
1460 1422
1461MODULE_DESCRIPTION("ASoC WM9081 driver"); 1423MODULE_DESCRIPTION("ASoC WM9081 driver");
1462MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1424MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index a2b9208a08f0..4b263b6edf13 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -433,7 +433,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
433 433
434 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 434 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
435 435
436 snd_soc_add_controls(codec, wm9090_controls, 436 snd_soc_add_codec_controls(codec, wm9090_controls,
437 ARRAY_SIZE(wm9090_controls)); 437 ARRAY_SIZE(wm9090_controls));
438 438
439 if (wm9090->pdata.lin1_diff) { 439 if (wm9090->pdata.lin1_diff) {
@@ -442,7 +442,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
442 } else { 442 } else {
443 snd_soc_dapm_add_routes(dapm, audio_map_in1_se, 443 snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
444 ARRAY_SIZE(audio_map_in1_se)); 444 ARRAY_SIZE(audio_map_in1_se));
445 snd_soc_add_controls(codec, wm9090_in1_se_controls, 445 snd_soc_add_codec_controls(codec, wm9090_in1_se_controls,
446 ARRAY_SIZE(wm9090_in1_se_controls)); 446 ARRAY_SIZE(wm9090_in1_se_controls));
447 } 447 }
448 448
@@ -452,7 +452,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
452 } else { 452 } else {
453 snd_soc_dapm_add_routes(dapm, audio_map_in2_se, 453 snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
454 ARRAY_SIZE(audio_map_in2_se)); 454 ARRAY_SIZE(audio_map_in2_se));
455 snd_soc_add_controls(codec, wm9090_in2_se_controls, 455 snd_soc_add_codec_controls(codec, wm9090_in2_se_controls,
456 ARRAY_SIZE(wm9090_in2_se_controls)); 456 ARRAY_SIZE(wm9090_in2_se_controls));
457 } 457 }
458 458
@@ -639,7 +639,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
639 if (ret < 0) 639 if (ret < 0)
640 goto err; 640 goto err;
641 if (reg != 0x9093) { 641 if (reg != 0x9093) {
642 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret); 642 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
643 ret = -ENODEV; 643 ret = -ENODEV;
644 goto err; 644 goto err;
645 } 645 }
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 40c92ead85a3..cacc6a86b46f 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -351,7 +351,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
351 if (ret) 351 if (ret)
352 goto reset_err; 352 goto reset_err;
353 353
354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls,
355 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
356 356
357 return 0; 357 return 0;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index b7b31f84c10b..b342ae50bcd6 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,10 +20,9 @@
20#include <sound/ac97_codec.h> 20#include <sound/ac97_codec.h>
21#include <sound/initval.h> 21#include <sound/initval.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/tlv.h>
23#include "wm9712.h" 24#include "wm9712.h"
24 25
25#define WM9712_VERSION "0.4"
26
27static unsigned int ac97_read(struct snd_soc_codec *codec, 26static unsigned int ac97_read(struct snd_soc_codec *codec,
28 unsigned int reg); 27 unsigned int reg);
29static int ac97_write(struct snd_soc_codec *codec, 28static int ac97_write(struct snd_soc_codec *codec,
@@ -71,6 +70,9 @@ static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer",
71static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; 70static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"};
72static const char *wm9712_diff_sel[] = {"Mic", "Line"}; 71static const char *wm9712_diff_sel[] = {"Mic", "Line"};
73 72
73static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
74static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0);
75
74static const struct soc_enum wm9712_enum[] = { 76static const struct soc_enum wm9712_enum[] = {
75SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), 77SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select),
76SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), 78SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux),
@@ -149,9 +151,9 @@ SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
149SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), 151SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
150SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 152SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
151 153
152SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 154SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
153SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 155SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
154SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), 156SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv),
155}; 157};
156 158
157/* We have to create a fake left and right HP mixers because 159/* We have to create a fake left and right HP mixers because
@@ -619,8 +621,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
619{ 621{
620 int ret = 0; 622 int ret = 0;
621 623
622 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
623
624 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 624 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
625 if (ret < 0) { 625 if (ret < 0) {
626 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 626 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
@@ -637,7 +637,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
637 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); 637 ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
638 638
639 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 639 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
640 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 640 snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls,
641 ARRAY_SIZE(wm9712_snd_ac97_controls)); 641 ARRAY_SIZE(wm9712_snd_ac97_controls));
642 642
643 return 0; 643 return 0;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2b8479bfcd93..2d22cc70d536 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1216,7 +1216,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1216 reg = ac97_read(codec, AC97_CD) & 0x7fff; 1216 reg = ac97_read(codec, AC97_CD) & 0x7fff;
1217 ac97_write(codec, AC97_CD, reg); 1217 ac97_write(codec, AC97_CD, reg);
1218 1218
1219 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1219 snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls,
1220 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1220 ARRAY_SIZE(wm9713_snd_ac97_controls));
1221 1221
1222 return 0; 1222 return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 2a61094075f8..c08d1c2f346f 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -172,7 +172,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
172 break; 172 break;
173 default: 173 default:
174 WARN(1, "Unknown DCS readback method\n"); 174 WARN(1, "Unknown DCS readback method\n");
175 break; 175 return;
176 } 176 }
177 177
178 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); 178 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
@@ -207,7 +207,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
207 207
208 /* Save the callibrated offset if we're in class W mode and 208 /* Save the callibrated offset if we're in class W mode and
209 * therefore don't have any analogue signal mixed in. */ 209 * therefore don't have any analogue signal mixed in. */
210 if (hubs->class_w) 210 if (hubs->class_w && !hubs->no_cache_class_w)
211 hubs->class_w_dcs = dcs_cfg; 211 hubs->class_w_dcs = dcs_cfg;
212} 212}
213 213
@@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
500 return 0; 500 return 0;
501} 501}
502 502
503static int lineout_event(struct snd_soc_dapm_widget *w,
504 struct snd_kcontrol *control, int event)
505{
506 struct snd_soc_codec *codec = w->codec;
507 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
508 bool *flag;
509
510 switch (w->shift) {
511 case WM8993_LINEOUT1N_ENA_SHIFT:
512 flag = &hubs->lineout1n_ena;
513 break;
514 case WM8993_LINEOUT1P_ENA_SHIFT:
515 flag = &hubs->lineout1p_ena;
516 break;
517 case WM8993_LINEOUT2N_ENA_SHIFT:
518 flag = &hubs->lineout2n_ena;
519 break;
520 case WM8993_LINEOUT2P_ENA_SHIFT:
521 flag = &hubs->lineout2p_ena;
522 break;
523 default:
524 WARN(1, "Unknown line output");
525 return -EINVAL;
526 }
527
528 *flag = SND_SOC_DAPM_EVENT_ON(event);
529
530 return 0;
531}
532
503static const struct snd_kcontrol_new in1l_pga[] = { 533static const struct snd_kcontrol_new in1l_pga[] = {
504SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), 534SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
505SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), 535SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
@@ -586,14 +616,14 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
586}; 616};
587 617
588static const struct snd_kcontrol_new line2_mix[] = { 618static const struct snd_kcontrol_new line2_mix[] = {
589SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0), 619SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0),
590SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0), 620SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0),
591SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), 621SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
592}; 622};
593 623
594static const struct snd_kcontrol_new line2n_mix[] = { 624static const struct snd_kcontrol_new line2n_mix[] = {
595SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), 625SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
596SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), 626SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
597}; 627};
598 628
599static const struct snd_kcontrol_new line2p_mix[] = { 629static const struct snd_kcontrol_new line2p_mix[] = {
@@ -613,6 +643,8 @@ SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
613SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), 643SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
614SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), 644SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
615 645
646SND_SOC_DAPM_SUPPLY("LINEOUT_VMID_BUF", WM8993_ANTIPOP1, 7, 0, NULL, 0),
647
616SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, 648SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
617 in1l_pga, ARRAY_SIZE(in1l_pga)), 649 in1l_pga, ARRAY_SIZE(in1l_pga)),
618SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0, 650SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
@@ -638,9 +670,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
638 670
639SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, 671SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
640 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 672 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
641SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 673SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
642 NULL, 0, 674 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
643 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
644 675
645SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 676SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
646 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), 677 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
@@ -654,10 +685,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
654 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), 685 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
655 686
656SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), 687SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
657SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, 688SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
658 NULL, 0), 689 NULL, 0),
659SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, 690SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
660 NULL, 0), 691 NULL, 0),
661 692
662SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, 693SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
663 line1_mix, ARRAY_SIZE(line1_mix)), 694 line1_mix, ARRAY_SIZE(line1_mix)),
@@ -673,14 +704,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
673SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, 704SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
674 line2p_mix, ARRAY_SIZE(line2p_mix)), 705 line2p_mix, ARRAY_SIZE(line2p_mix)),
675 706
676SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, 707SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
677 NULL, 0), 708 NULL, 0, lineout_event,
678SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, 709 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
679 NULL, 0), 710SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
680SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, 711 NULL, 0, lineout_event,
681 NULL, 0), 712 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
682SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, 713SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
683 NULL, 0), 714 NULL, 0, lineout_event,
715 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
716SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
717 NULL, 0, lineout_event,
718 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
684 719
685SND_SOC_DAPM_OUTPUT("SPKOUTLP"), 720SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
686SND_SOC_DAPM_OUTPUT("SPKOUTLN"), 721SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
@@ -834,9 +869,11 @@ static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
834}; 869};
835 870
836static const struct snd_soc_dapm_route lineout1_se_routes[] = { 871static const struct snd_soc_dapm_route lineout1_se_routes[] = {
872 { "LINEOUT1N Mixer", NULL, "LINEOUT_VMID_BUF" },
837 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" }, 873 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
838 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" }, 874 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
839 875
876 { "LINEOUT1P Mixer", NULL, "LINEOUT_VMID_BUF" },
840 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" }, 877 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
841 878
842 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, 879 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
@@ -844,8 +881,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
844}; 881};
845 882
846static const struct snd_soc_dapm_route lineout2_diff_routes[] = { 883static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
847 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, 884 { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" },
848 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, 885 { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" },
849 { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, 886 { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
850 887
851 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, 888 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
@@ -853,9 +890,11 @@ static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
853}; 890};
854 891
855static const struct snd_soc_dapm_route lineout2_se_routes[] = { 892static const struct snd_soc_dapm_route lineout2_se_routes[] = {
893 { "LINEOUT2N Mixer", NULL, "LINEOUT_VMID_BUF" },
856 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" }, 894 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
857 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" }, 895 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
858 896
897 { "LINEOUT2P Mixer", NULL, "LINEOUT_VMID_BUF" },
859 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" }, 898 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
860 899
861 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, 900 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
@@ -895,7 +934,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
895 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 934 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
896 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 935 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
897 936
898 snd_soc_add_controls(codec, analogue_snd_controls, 937 snd_soc_add_codec_controls(codec, analogue_snd_controls,
899 ARRAY_SIZE(analogue_snd_controls)); 938 ARRAY_SIZE(analogue_snd_controls));
900 939
901 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, 940 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
@@ -943,6 +982,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
943 int jd_scthr, int jd_thr, int micbias1_lvl, 982 int jd_scthr, int jd_thr, int micbias1_lvl,
944 int micbias2_lvl) 983 int micbias2_lvl)
945{ 984{
985 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
986
987 hubs->lineout1_se = !lineout1_diff;
988 hubs->lineout2_se = !lineout2_diff;
989
946 if (!lineout1_diff) 990 if (!lineout1_diff)
947 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 991 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
948 WM8993_LINEOUT1_MODE, 992 WM8993_LINEOUT1_MODE,
@@ -952,12 +996,6 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
952 WM8993_LINEOUT2_MODE, 996 WM8993_LINEOUT2_MODE,
953 WM8993_LINEOUT2_MODE); 997 WM8993_LINEOUT2_MODE);
954 998
955 /* If the line outputs are differential then we aren't presenting
956 * VMID as an output and can disable it.
957 */
958 if (lineout1_diff && lineout2_diff)
959 codec->dapm.idle_bias_off = 1;
960
961 if (lineout1fb) 999 if (lineout1fb)
962 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 1000 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
963 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); 1001 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
@@ -978,6 +1016,74 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
978} 1016}
979EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); 1017EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
980 1018
1019void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
1020{
1021 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1022 int val = 0;
1023
1024 if (hubs->lineout1_se)
1025 val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
1026
1027 if (hubs->lineout2_se)
1028 val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
1029
1030 /* Enable the line outputs while we power up */
1031 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
1032}
1033EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
1034
1035void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
1036 enum snd_soc_bias_level level)
1037{
1038 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
1039 int val;
1040
1041 switch (level) {
1042 case SND_SOC_BIAS_STANDBY:
1043 /* Clamp the inputs to VMID while we ramp to charge caps */
1044 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1045 WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
1046 break;
1047
1048 case SND_SOC_BIAS_ON:
1049 /* Turn off any unneded single ended outputs */
1050 val = 0;
1051
1052 if (hubs->lineout1_se && hubs->lineout1n_ena)
1053 val |= WM8993_LINEOUT1N_ENA;
1054
1055 if (hubs->lineout1_se && hubs->lineout1p_ena)
1056 val |= WM8993_LINEOUT1P_ENA;
1057
1058 if (hubs->lineout2_se && hubs->lineout2n_ena)
1059 val |= WM8993_LINEOUT2N_ENA;
1060
1061 if (hubs->lineout2_se && hubs->lineout2p_ena)
1062 val |= WM8993_LINEOUT2P_ENA;
1063
1064 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
1065 WM8993_LINEOUT1N_ENA |
1066 WM8993_LINEOUT1P_ENA |
1067 WM8993_LINEOUT2N_ENA |
1068 WM8993_LINEOUT2P_ENA,
1069 val);
1070
1071 if (!hubs->lineout1n_ena && !hubs->lineout1p_ena &&
1072 !hubs->lineout2n_ena && !hubs->lineout2p_ena)
1073 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1074 WM8993_LINEOUT_VMID_BUF_ENA, 0);
1075
1076 /* Remove the input clamps */
1077 snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
1078 WM8993_INPUTS_CLAMP, 0);
1079 break;
1080
1081 default:
1082 break;
1083 }
1084}
1085EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
1086
981MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 1087MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
982MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1088MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
983MODULE_LICENSE("GPL"); 1089MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index c674c7a502a6..5705276f4943 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -30,9 +30,18 @@ struct wm_hubs_data {
30 int series_startup; 30 int series_startup;
31 int no_series_update; 31 int no_series_update;
32 32
33 bool no_cache_class_w;
33 bool class_w; 34 bool class_w;
34 u16 class_w_dcs; 35 u16 class_w_dcs;
35 36
37 bool lineout1_se;
38 bool lineout1n_ena;
39 bool lineout1p_ena;
40
41 bool lineout2_se;
42 bool lineout2n_ena;
43 bool lineout2p_ena;
44
36 bool dcs_done_irq; 45 bool dcs_done_irq;
37 struct completion dcs_done; 46 struct completion dcs_done;
38}; 47};
@@ -46,5 +55,8 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
46 int micbias1_lvl, int micbias2_lvl); 55 int micbias1_lvl, int micbias2_lvl);
47 56
48extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); 57extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
58extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
59extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
60 enum snd_soc_bias_level level);
49 61
50#endif 62#endif
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 33adbf1e40d6..9a3f7c5ab687 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of_device.h> 10#include <linux/of_device.h>
11#include <linux/dma-mapping.h>
11#include <linux/slab.h> 12#include <linux/slab.h>
12#include <linux/of_platform.h> 13#include <linux/of_platform.h>
13 14
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 0ea4a5a96e06..fcf9302f59b4 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -245,7 +245,7 @@ static int get_parent_cell_index(struct device_node *np)
245 * 'struct device' It's ugly and hackish, but it works. 245 * 'struct device' It's ugly and hackish, but it works.
246 * 246 *
247 * The dev_name for such devices include the bus number and I2C address. For 247 * The dev_name for such devices include the bus number and I2C address. For
248 * example, "cs4270-codec.0-004f". 248 * example, "cs4270.0-004f".
249 */ 249 */
250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) 250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
251{ 251{
@@ -267,13 +267,13 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
267 if (!i2c) 267 if (!i2c)
268 return -ENODEV; 268 return -ENODEV;
269 269
270 snprintf(buf, len, "%s-codec.%u-%04x", temp, i2c->adapter->nr, addr); 270 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
271 271
272 return 0; 272 return 0;
273} 273}
274 274
275static int get_dma_channel(struct device_node *ssi_np, 275static int get_dma_channel(struct device_node *ssi_np,
276 const char *compatible, 276 const char *name,
277 struct snd_soc_dai_link *dai, 277 struct snd_soc_dai_link *dai,
278 unsigned int *dma_channel_id, 278 unsigned int *dma_channel_id,
279 unsigned int *dma_id) 279 unsigned int *dma_id)
@@ -283,7 +283,7 @@ static int get_dma_channel(struct device_node *ssi_np,
283 const u32 *iprop; 283 const u32 *iprop;
284 int ret; 284 int ret;
285 285
286 dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, 286 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
287 "fsl,ssi-dma-channel"); 287 "fsl,ssi-dma-channel");
288 if (!dma_channel_np) 288 if (!dma_channel_np)
289 return -EINVAL; 289 return -EINVAL;
@@ -336,12 +336,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
336 const char *sprop; 336 const char *sprop;
337 const u32 *iprop; 337 const u32 *iprop;
338 338
339 /* We are only interested in SSIs with a codec phandle in them, 339 /* Find the codec node for this SSI. */
340 * so let's make sure this SSI has one. The MPC8610 HPCD only 340 codec_np = of_parse_phandle(np, "codec-handle", 0);
341 * knows about the CS4270 codec, so reject anything else.
342 */
343 codec_np = get_node_by_phandle_name(np, "codec-handle",
344 "cirrus,cs4270");
345 if (!codec_np) { 341 if (!codec_np) {
346 dev_err(dev, "invalid codec node\n"); 342 dev_err(dev, "invalid codec node\n");
347 return -EINVAL; 343 return -EINVAL;
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index a5d4e80a9cf4..d32ec4646d25 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -276,7 +276,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
276} 276}
277 277
278static int get_dma_channel(struct device_node *ssi_np, 278static int get_dma_channel(struct device_node *ssi_np,
279 const char *compatible, 279 const char *name,
280 struct snd_soc_dai_link *dai, 280 struct snd_soc_dai_link *dai,
281 unsigned int *dma_channel_id, 281 unsigned int *dma_channel_id,
282 unsigned int *dma_id) 282 unsigned int *dma_id)
@@ -286,7 +286,7 @@ static int get_dma_channel(struct device_node *ssi_np,
286 const u32 *iprop; 286 const u32 *iprop;
287 int ret; 287 int ret;
288 288
289 dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, 289 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
290 "fsl,ssi-dma-channel"); 290 "fsl,ssi-dma-channel");
291 if (!dma_channel_np) 291 if (!dma_channel_np)
292 return -EINVAL; 292 return -EINVAL;
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 738391757f2c..aa4294bf49b2 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,9 +1,6 @@
1menuconfig SND_IMX_SOC 1menuconfig SND_IMX_SOC
2 tristate "SoC Audio for Freescale i.MX CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MXC 3 depends on ARCH_MXC
4 select SND_PCM
5 select FIQ
6 select SND_SOC_AC97_BUS
7 help 4 help
8 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
9 the i.MX SSI interface. 6 the i.MX SSI interface.
@@ -12,9 +9,11 @@ menuconfig SND_IMX_SOC
12if SND_IMX_SOC 9if SND_IMX_SOC
13 10
14config SND_MXC_SOC_FIQ 11config SND_MXC_SOC_FIQ
12 select FIQ
15 tristate 13 tristate
16 14
17config SND_MXC_SOC_MX2 15config SND_MXC_SOC_MX2
16 select SND_SOC_DMAENGINE_PCM
18 tristate 17 tristate
19 18
20config SND_MXC_SOC_WM1133_EV1 19config SND_MXC_SOC_WM1133_EV1
@@ -38,6 +37,7 @@ config SND_SOC_MX27VIS_AIC32X4
38config SND_SOC_PHYCORE_AC97 37config SND_SOC_PHYCORE_AC97
39 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" 38 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
40 depends on MACH_PCM043 || MACH_PCA100 39 depends on MACH_PCM043 || MACH_PCA100
40 select SND_SOC_AC97_BUS
41 select SND_SOC_WM9712 41 select SND_SOC_WM9712
42 select SND_MXC_SOC_FIQ 42 select SND_MXC_SOC_FIQ
43 help 43 help
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 5780c9b9d569..471e2218c971 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -27,212 +27,54 @@
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/dmaengine_pcm.h>
30 31
31#include <mach/dma.h> 32#include <mach/dma.h>
32 33
33#include "imx-ssi.h" 34#include "imx-ssi.h"
34 35
35struct imx_pcm_runtime_data {
36 int period_bytes;
37 int periods;
38 int dma;
39 unsigned long offset;
40 unsigned long size;
41 void *buf;
42 int period_time;
43 struct dma_async_tx_descriptor *desc;
44 struct dma_chan *dma_chan;
45 struct imx_dma_data dma_data;
46};
47
48static void audio_dma_irq(void *data)
49{
50 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
51 struct snd_pcm_runtime *runtime = substream->runtime;
52 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
53
54 iprtd->offset += iprtd->period_bytes;
55 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
56
57 snd_pcm_period_elapsed(substream);
58}
59
60static bool filter(struct dma_chan *chan, void *param) 36static bool filter(struct dma_chan *chan, void *param)
61{ 37{
62 struct imx_pcm_runtime_data *iprtd = param;
63
64 if (!imx_dma_is_general_purpose(chan)) 38 if (!imx_dma_is_general_purpose(chan))
65 return false; 39 return false;
66 40
67 chan->private = &iprtd->dma_data; 41 chan->private = param;
68 42
69 return true; 43 return true;
70} 44}
71 45
72static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, 46static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params) 47 struct snd_pcm_hw_params *params)
74{ 48{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data; 49 struct snd_soc_pcm_runtime *rtd = substream->private_data;
50 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
76 struct imx_pcm_dma_params *dma_params; 51 struct imx_pcm_dma_params *dma_params;
77 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
79 struct dma_slave_config slave_config; 52 struct dma_slave_config slave_config;
80 dma_cap_mask_t mask;
81 enum dma_slave_buswidth buswidth;
82 int ret; 53 int ret;
83 54
84 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 55 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
85 56
86 iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; 57 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
87 iprtd->dma_data.priority = DMA_PRIO_HIGH; 58 if (ret)
88 iprtd->dma_data.dma_request = dma_params->dma; 59 return ret;
89
90 /* Try to grab a DMA channel */
91 if (!iprtd->dma_chan) {
92 dma_cap_zero(mask);
93 dma_cap_set(DMA_SLAVE, mask);
94 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
95 if (!iprtd->dma_chan)
96 return -EINVAL;
97 }
98
99 switch (params_format(params)) {
100 case SNDRV_PCM_FORMAT_S16_LE:
101 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
102 break;
103 case SNDRV_PCM_FORMAT_S20_3LE:
104 case SNDRV_PCM_FORMAT_S24_LE:
105 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
106 break;
107 default:
108 return 0;
109 }
110 60
111 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 61 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
112 slave_config.direction = DMA_MEM_TO_DEV;
113 slave_config.dst_addr = dma_params->dma_addr; 62 slave_config.dst_addr = dma_params->dma_addr;
114 slave_config.dst_addr_width = buswidth;
115 slave_config.dst_maxburst = dma_params->burstsize; 63 slave_config.dst_maxburst = dma_params->burstsize;
116 } else { 64 } else {
117 slave_config.direction = DMA_DEV_TO_MEM;
118 slave_config.src_addr = dma_params->dma_addr; 65 slave_config.src_addr = dma_params->dma_addr;
119 slave_config.src_addr_width = buswidth;
120 slave_config.src_maxburst = dma_params->burstsize; 66 slave_config.src_maxburst = dma_params->burstsize;
121 } 67 }
122 68
123 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); 69 ret = dmaengine_slave_config(chan, &slave_config);
124 if (ret) 70 if (ret)
125 return ret; 71 return ret;
126 72
127 return 0;
128}
129
130static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
131 struct snd_pcm_hw_params *params)
132{
133 struct snd_soc_pcm_runtime *rtd = substream->private_data;
134 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
136 unsigned long dma_addr;
137 struct dma_chan *chan;
138 struct imx_pcm_dma_params *dma_params;
139 int ret;
140
141 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
142 ret = imx_ssi_dma_alloc(substream, params);
143 if (ret)
144 return ret;
145 chan = iprtd->dma_chan;
146
147 iprtd->size = params_buffer_bytes(params);
148 iprtd->periods = params_periods(params);
149 iprtd->period_bytes = params_period_bytes(params);
150 iprtd->offset = 0;
151 iprtd->period_time = HZ / (params_rate(params) /
152 params_period_size(params));
153
154 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 73 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
155 74
156 dma_addr = runtime->dma_addr;
157
158 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
159
160 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
161 iprtd->period_bytes * iprtd->periods,
162 iprtd->period_bytes,
163 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
164 DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
165 if (!iprtd->desc) {
166 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
167 return -EINVAL;
168 }
169
170 iprtd->desc->callback = audio_dma_irq;
171 iprtd->desc->callback_param = substream;
172
173 return 0;
174}
175
176static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
177{
178 struct snd_pcm_runtime *runtime = substream->runtime;
179 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
180
181 if (iprtd->dma_chan) {
182 dma_release_channel(iprtd->dma_chan);
183 iprtd->dma_chan = NULL;
184 }
185
186 return 0;
187}
188
189static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
190{
191 struct snd_soc_pcm_runtime *rtd = substream->private_data;
192 struct imx_pcm_dma_params *dma_params;
193
194 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
195
196 return 0; 75 return 0;
197} 76}
198 77
199static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
203
204 switch (cmd) {
205 case SNDRV_PCM_TRIGGER_START:
206 case SNDRV_PCM_TRIGGER_RESUME:
207 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
208 dmaengine_submit(iprtd->desc);
209
210 break;
211
212 case SNDRV_PCM_TRIGGER_STOP:
213 case SNDRV_PCM_TRIGGER_SUSPEND:
214 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
215 dmaengine_terminate_all(iprtd->dma_chan);
216
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 return 0;
223}
224
225static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
226{
227 struct snd_pcm_runtime *runtime = substream->runtime;
228 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
229
230 pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
231 bytes_to_frames(substream->runtime, iprtd->offset));
232
233 return bytes_to_frames(substream->runtime, iprtd->offset);
234}
235
236static struct snd_pcm_hardware snd_imx_hardware = { 78static struct snd_pcm_hardware snd_imx_hardware = {
237 .info = SNDRV_PCM_INFO_INTERLEAVED | 79 .info = SNDRV_PCM_INFO_INTERLEAVED |
238 SNDRV_PCM_INFO_BLOCK_TRANSFER | 80 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -254,33 +96,37 @@ static struct snd_pcm_hardware snd_imx_hardware = {
254 96
255static int snd_imx_open(struct snd_pcm_substream *substream) 97static int snd_imx_open(struct snd_pcm_substream *substream)
256{ 98{
257 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
258 struct imx_pcm_runtime_data *iprtd; 100 struct imx_pcm_dma_params *dma_params;
101 struct imx_dma_data *dma_data;
259 int ret; 102 int ret;
260 103
261 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 104 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
262 if (iprtd == NULL)
263 return -ENOMEM;
264 runtime->private_data = iprtd;
265 105
266 ret = snd_pcm_hw_constraint_integer(substream->runtime, 106 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
267 SNDRV_PCM_HW_PARAM_PERIODS); 107
268 if (ret < 0) { 108 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
269 kfree(iprtd); 109 dma_data->peripheral_type = IMX_DMATYPE_SSI;
270 return ret; 110 dma_data->priority = DMA_PRIO_HIGH;
111 dma_data->dma_request = dma_params->dma;
112
113 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
114 if (ret) {
115 kfree(dma_data);
116 return 0;
271 } 117 }
272 118
273 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 119 snd_dmaengine_pcm_set_data(substream, dma_data);
274 120
275 return 0; 121 return 0;
276} 122}
277 123
278static int snd_imx_close(struct snd_pcm_substream *substream) 124static int snd_imx_close(struct snd_pcm_substream *substream)
279{ 125{
280 struct snd_pcm_runtime *runtime = substream->runtime; 126 struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
281 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
282 127
283 kfree(iprtd); 128 snd_dmaengine_pcm_close(substream);
129 kfree(dma_data);
284 130
285 return 0; 131 return 0;
286} 132}
@@ -290,10 +136,8 @@ static struct snd_pcm_ops imx_pcm_ops = {
290 .close = snd_imx_close, 136 .close = snd_imx_close,
291 .ioctl = snd_pcm_lib_ioctl, 137 .ioctl = snd_pcm_lib_ioctl,
292 .hw_params = snd_imx_pcm_hw_params, 138 .hw_params = snd_imx_pcm_hw_params,
293 .hw_free = snd_imx_pcm_hw_free, 139 .trigger = snd_dmaengine_pcm_trigger,
294 .prepare = snd_imx_pcm_prepare, 140 .pointer = snd_dmaengine_pcm_pointer,
295 .trigger = snd_imx_pcm_trigger,
296 .pointer = snd_imx_pcm_pointer,
297 .mmap = snd_imx_pcm_mmap, 141 .mmap = snd_imx_pcm_mmap,
298}; 142};
299 143
@@ -305,11 +149,6 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = {
305 149
306static int __devinit imx_soc_platform_probe(struct platform_device *pdev) 150static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
307{ 151{
308 struct imx_ssi *ssi = platform_get_drvdata(pdev);
309
310 ssi->dma_params_tx.burstsize = 6;
311 ssi->dma_params_rx.burstsize = 4;
312
313 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); 152 return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
314} 153}
315 154
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 01d1f749cf02..25c623115a9f 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -233,6 +233,23 @@ static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
233 return 0; 233 return 0;
234} 234}
235 235
236static int imx_ssi_startup(struct snd_pcm_substream *substream,
237 struct snd_soc_dai *cpu_dai)
238{
239 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
240 struct imx_pcm_dma_params *dma_data;
241
242 /* Tx/Rx config */
243 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
244 dma_data = &ssi->dma_params_tx;
245 else
246 dma_data = &ssi->dma_params_rx;
247
248 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
249
250 return 0;
251}
252
236/* 253/*
237 * Should only be called when port is inactive (i.e. SSIEN = 0), 254 * Should only be called when port is inactive (i.e. SSIEN = 0),
238 * although can be called multiple times by upper layers. 255 * although can be called multiple times by upper layers.
@@ -242,23 +259,17 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_dai *cpu_dai) 259 struct snd_soc_dai *cpu_dai)
243{ 260{
244 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); 261 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
245 struct imx_pcm_dma_params *dma_data;
246 u32 reg, sccr; 262 u32 reg, sccr;
247 263
248 /* Tx/Rx config */ 264 /* Tx/Rx config */
249 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 265 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
250 reg = SSI_STCCR; 266 reg = SSI_STCCR;
251 dma_data = &ssi->dma_params_tx; 267 else
252 } else {
253 reg = SSI_SRCCR; 268 reg = SSI_SRCCR;
254 dma_data = &ssi->dma_params_rx;
255 }
256 269
257 if (ssi->flags & IMX_SSI_SYN) 270 if (ssi->flags & IMX_SSI_SYN)
258 reg = SSI_STCCR; 271 reg = SSI_STCCR;
259 272
260 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
261
262 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; 273 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
263 274
264 /* DAI data (word) size */ 275 /* DAI data (word) size */
@@ -343,6 +354,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
343} 354}
344 355
345static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { 356static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
357 .startup = imx_ssi_startup,
346 .hw_params = imx_ssi_hw_params, 358 .hw_params = imx_ssi_hw_params,
347 .set_fmt = imx_ssi_set_dai_fmt, 359 .set_fmt = imx_ssi_set_dai_fmt,
348 .set_clkdiv = imx_ssi_set_dai_clkdiv, 360 .set_clkdiv = imx_ssi_set_dai_clkdiv,
@@ -656,7 +668,7 @@ static int imx_ssi_probe(struct platform_device *pdev)
656 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 668 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
657 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 669 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
658 670
659 ssi->dma_params_tx.burstsize = 4; 671 ssi->dma_params_tx.burstsize = 6;
660 ssi->dma_params_rx.burstsize = 4; 672 ssi->dma_params_rx.burstsize = 4;
661 673
662 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 674 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 55d2ed3df30d..80bd59c33be4 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -71,41 +71,41 @@ static struct snd_soc_card openrd_client = {
71 .num_links = ARRAY_SIZE(openrd_client_dai), 71 .num_links = ARRAY_SIZE(openrd_client_dai),
72}; 72};
73 73
74static struct platform_device *openrd_client_snd_device; 74static int __devinit openrd_probe(struct platform_device *pdev)
75
76static int __init openrd_client_init(void)
77{ 75{
76 struct snd_soc_card *card = &openrd_client;
78 int ret; 77 int ret;
79 78
80 if (!machine_is_openrd_client() && !machine_is_openrd_ultimate()) 79 card->dev = &pdev->dev;
81 return 0;
82
83 openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
84 if (!openrd_client_snd_device)
85 return -ENOMEM;
86
87 platform_set_drvdata(openrd_client_snd_device,
88 &openrd_client);
89
90 ret = platform_device_add(openrd_client_snd_device);
91 if (ret) {
92 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
93 platform_device_put(openrd_client_snd_device);
94 }
95 80
81 ret = snd_soc_register_card(card);
82 if (ret)
83 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
84 ret);
96 return ret; 85 return ret;
97} 86}
98 87
99static void __exit openrd_client_exit(void) 88static int __devexit openrd_remove(struct platform_device *pdev)
100{ 89{
101 platform_device_unregister(openrd_client_snd_device); 90 struct snd_soc_card *card = platform_get_drvdata(pdev);
91
92 snd_soc_unregister_card(card);
93 return 0;
102} 94}
103 95
104module_init(openrd_client_init); 96static struct platform_driver openrd_driver = {
105module_exit(openrd_client_exit); 97 .driver = {
98 .name = "openrd-client-audio",
99 .owner = THIS_MODULE,
100 },
101 .probe = openrd_probe,
102 .remove = __devexit_p(openrd_remove),
103};
104
105module_platform_driver(openrd_driver);
106 106
107/* Module information */ 107/* Module information */
108MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 108MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
109MODULE_DESCRIPTION("ALSA SoC OpenRD Client"); 109MODULE_DESCRIPTION("ALSA SoC OpenRD Client");
110MODULE_LICENSE("GPL"); 110MODULE_LICENSE("GPL");
111MODULE_ALIAS("platform:soc-audio"); 111MODULE_ALIAS("platform:openrd-client-audio");
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index b47cc4e9b746..f8983635f7ef 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -80,7 +80,6 @@ static struct snd_soc_dai_link t5325_dai[] = {
80}, 80},
81}; 81};
82 82
83
84static struct snd_soc_card t5325 = { 83static struct snd_soc_card t5325 = {
85 .name = "t5325", 84 .name = "t5325",
86 .owner = THIS_MODULE, 85 .owner = THIS_MODULE,
@@ -93,38 +92,40 @@ static struct snd_soc_card t5325 = {
93 .num_dapm_routes = ARRAY_SIZE(t5325_route), 92 .num_dapm_routes = ARRAY_SIZE(t5325_route),
94}; 93};
95 94
96static struct platform_device *t5325_snd_device; 95static int __devinit t5325_probe(struct platform_device *pdev)
97
98static int __init t5325_init(void)
99{ 96{
97 struct snd_soc_card *card = &t5325;
100 int ret; 98 int ret;
101 99
102 if (!machine_is_t5325()) 100 card->dev = &pdev->dev;
103 return 0;
104
105 t5325_snd_device = platform_device_alloc("soc-audio", -1);
106 if (!t5325_snd_device)
107 return -ENOMEM;
108
109 platform_set_drvdata(t5325_snd_device,
110 &t5325);
111
112 ret = platform_device_add(t5325_snd_device);
113 if (ret) {
114 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
115 platform_device_put(t5325_snd_device);
116 }
117 101
102 ret = snd_soc_register_card(card);
103 if (ret)
104 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
105 ret);
118 return ret; 106 return ret;
119} 107}
120module_init(t5325_init);
121 108
122static void __exit t5325_exit(void) 109static int __devexit t5325_remove(struct platform_device *pdev)
123{ 110{
124 platform_device_unregister(t5325_snd_device); 111 struct snd_soc_card *card = platform_get_drvdata(pdev);
112
113 snd_soc_unregister_card(card);
114 return 0;
125} 115}
126module_exit(t5325_exit); 116
117static struct platform_driver t5325_driver = {
118 .driver = {
119 .name = "t5325-audio",
120 .owner = THIS_MODULE,
121 },
122 .probe = t5325_probe,
123 .remove = __devexit_p(t5325_remove),
124};
125
126module_platform_driver(t5325_driver);
127 127
128MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 128MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
129MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); 129MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
130MODULE_LICENSE("GPL"); 130MODULE_LICENSE("GPL");
131MODULE_ALIAS("platform:t5325-audio");
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 6f77eef0f131..2937e54da49e 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -235,7 +235,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
235 snd_soc_dapm_enable_pin(dapm, "Headphones"); 235 snd_soc_dapm_enable_pin(dapm, "Headphones");
236 snd_soc_dapm_enable_pin(dapm, "Mic"); 236 snd_soc_dapm_enable_pin(dapm, "Mic");
237 237
238 ret_val = snd_soc_add_controls(codec, mfld_snd_controls, 238 ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
239 ARRAY_SIZE(mfld_snd_controls)); 239 ARRAY_SIZE(mfld_snd_controls));
240 if (ret_val) { 240 if (ret_val) {
241 pr_err("soc_add_controls failed %d", ret_val); 241 pr_err("soc_add_controls failed %d", ret_val);
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index e4ba8d5f25fa..99a997f19bb9 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -1,7 +1,7 @@
1menuconfig SND_MXS_SOC 1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs" 2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS 3 depends on ARCH_MXS
4 select SND_PCM 4 select SND_SOC_DMAENGINE_PCM
5 help 5 help
6 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
7 the MXS SAIF interface. 7 the MXS SAIF interface.
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 105f42a394df..6ca1f46d84a4 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -34,10 +34,16 @@
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
36#include <sound/soc.h> 36#include <sound/soc.h>
37#include <sound/dmaengine_pcm.h>
37 38
38#include <mach/dma.h> 39#include <mach/dma.h>
39#include "mxs-pcm.h" 40#include "mxs-pcm.h"
40 41
42struct mxs_pcm_dma_data {
43 struct mxs_dma_data dma_data;
44 struct mxs_pcm_dma_params *dma_params;
45};
46
41static struct snd_pcm_hardware snd_mxs_hardware = { 47static struct snd_pcm_hardware snd_mxs_hardware = {
42 .info = SNDRV_PCM_INFO_MMAP | 48 .info = SNDRV_PCM_INFO_MMAP |
43 SNDRV_PCM_INFO_MMAP_VALID | 49 SNDRV_PCM_INFO_MMAP_VALID |
@@ -58,21 +64,10 @@ static struct snd_pcm_hardware snd_mxs_hardware = {
58 64
59}; 65};
60 66
61static void audio_dma_irq(void *data)
62{
63 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
64 struct snd_pcm_runtime *runtime = substream->runtime;
65 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
66
67 iprtd->offset += iprtd->period_bytes;
68 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
69 snd_pcm_period_elapsed(substream);
70}
71
72static bool filter(struct dma_chan *chan, void *param) 67static bool filter(struct dma_chan *chan, void *param)
73{ 68{
74 struct mxs_pcm_runtime_data *iprtd = param; 69 struct mxs_pcm_dma_data *pcm_dma_data = param;
75 struct mxs_pcm_dma_params *dma_params = iprtd->dma_params; 70 struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
76 71
77 if (!mxs_dma_is_apbx(chan)) 72 if (!mxs_dma_is_apbx(chan))
78 return false; 73 return false;
@@ -80,150 +75,51 @@ static bool filter(struct dma_chan *chan, void *param)
80 if (chan->chan_id != dma_params->chan_num) 75 if (chan->chan_id != dma_params->chan_num)
81 return false; 76 return false;
82 77
83 chan->private = &iprtd->dma_data; 78 chan->private = &pcm_dma_data->dma_data;
84 79
85 return true; 80 return true;
86} 81}
87 82
88static int mxs_dma_alloc(struct snd_pcm_substream *substream,
89 struct snd_pcm_hw_params *params)
90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data;
92 struct snd_pcm_runtime *runtime = substream->runtime;
93 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
94 dma_cap_mask_t mask;
95
96 iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
97
98 dma_cap_zero(mask);
99 dma_cap_set(DMA_SLAVE, mask);
100 iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
101 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
102 if (!iprtd->dma_chan)
103 return -EINVAL;
104
105 return 0;
106}
107
108static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, 83static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params) 84 struct snd_pcm_hw_params *params)
110{ 85{
111 struct snd_pcm_runtime *runtime = substream->runtime;
112 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
113 unsigned long dma_addr;
114 struct dma_chan *chan;
115 int ret;
116
117 ret = mxs_dma_alloc(substream, params);
118 if (ret)
119 return ret;
120 chan = iprtd->dma_chan;
121
122 iprtd->size = params_buffer_bytes(params);
123 iprtd->periods = params_periods(params);
124 iprtd->period_bytes = params_period_bytes(params);
125 iprtd->offset = 0;
126 iprtd->period_time = HZ / (params_rate(params) /
127 params_period_size(params));
128
129 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 86 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
130 87
131 dma_addr = runtime->dma_addr;
132
133 iprtd->buf = substream->dma_buffer.area;
134
135 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
136 iprtd->period_bytes * iprtd->periods,
137 iprtd->period_bytes,
138 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
139 DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
140 if (!iprtd->desc) {
141 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
142 return -EINVAL;
143 }
144
145 iprtd->desc->callback = audio_dma_irq;
146 iprtd->desc->callback_param = substream;
147
148 return 0;
149}
150
151static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
152{
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
155
156 if (iprtd->dma_chan) {
157 dma_release_channel(iprtd->dma_chan);
158 iprtd->dma_chan = NULL;
159 }
160
161 return 0;
162}
163
164static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165{
166 struct snd_pcm_runtime *runtime = substream->runtime;
167 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
168
169 switch (cmd) {
170 case SNDRV_PCM_TRIGGER_START:
171 case SNDRV_PCM_TRIGGER_RESUME:
172 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
173 dmaengine_submit(iprtd->desc);
174
175 break;
176 case SNDRV_PCM_TRIGGER_STOP:
177 case SNDRV_PCM_TRIGGER_SUSPEND:
178 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179 dmaengine_terminate_all(iprtd->dma_chan);
180
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 return 0; 88 return 0;
187} 89}
188 90
189static snd_pcm_uframes_t snd_mxs_pcm_pointer(
190 struct snd_pcm_substream *substream)
191{
192 struct snd_pcm_runtime *runtime = substream->runtime;
193 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
194
195 return bytes_to_frames(substream->runtime, iprtd->offset);
196}
197
198static int snd_mxs_open(struct snd_pcm_substream *substream) 91static int snd_mxs_open(struct snd_pcm_substream *substream)
199{ 92{
200 struct snd_pcm_runtime *runtime = substream->runtime; 93 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201 struct mxs_pcm_runtime_data *iprtd; 94 struct mxs_pcm_dma_data *pcm_dma_data;
202 int ret; 95 int ret;
203 96
204 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); 97 pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
205 if (iprtd == NULL) 98 if (pcm_dma_data == NULL)
206 return -ENOMEM; 99 return -ENOMEM;
207 runtime->private_data = iprtd;
208 100
209 ret = snd_pcm_hw_constraint_integer(substream->runtime, 101 pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
210 SNDRV_PCM_HW_PARAM_PERIODS); 102 pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
211 if (ret < 0) { 103
212 kfree(iprtd); 104 ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
105 if (ret) {
106 kfree(pcm_dma_data);
213 return ret; 107 return ret;
214 } 108 }
215 109
216 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); 110 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
217 111
112 snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
113
218 return 0; 114 return 0;
219} 115}
220 116
221static int snd_mxs_close(struct snd_pcm_substream *substream) 117static int snd_mxs_close(struct snd_pcm_substream *substream)
222{ 118{
223 struct snd_pcm_runtime *runtime = substream->runtime; 119 struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
224 struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
225 120
226 kfree(iprtd); 121 snd_dmaengine_pcm_close(substream);
122 kfree(pcm_dma_data);
227 123
228 return 0; 124 return 0;
229} 125}
@@ -244,9 +140,8 @@ static struct snd_pcm_ops mxs_pcm_ops = {
244 .close = snd_mxs_close, 140 .close = snd_mxs_close,
245 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
246 .hw_params = snd_mxs_pcm_hw_params, 142 .hw_params = snd_mxs_pcm_hw_params,
247 .hw_free = snd_mxs_pcm_hw_free, 143 .trigger = snd_dmaengine_pcm_trigger,
248 .trigger = snd_mxs_pcm_trigger, 144 .pointer = snd_dmaengine_pcm_pointer,
249 .pointer = snd_mxs_pcm_pointer,
250 .mmap = snd_mxs_pcm_mmap, 145 .mmap = snd_mxs_pcm_mmap,
251}; 146};
252 147
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index f55ac4f7a76a..5f01a9124b3d 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,25 +19,9 @@
19#ifndef _MXS_PCM_H 19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H 20#define _MXS_PCM_H
21 21
22#include <mach/dma.h>
23
24struct mxs_pcm_dma_params { 22struct mxs_pcm_dma_params {
25 int chan_irq; 23 int chan_irq;
26 int chan_num; 24 int chan_num;
27}; 25};
28 26
29struct mxs_pcm_runtime_data {
30 int period_bytes;
31 int periods;
32 int dma;
33 unsigned long offset;
34 unsigned long size;
35 void *buf;
36 int period_time;
37 struct dma_async_tx_descriptor *desc;
38 struct dma_chan *dma_chan;
39 struct mxs_dma_data dma_data;
40 struct mxs_pcm_dma_params *dma_params;
41};
42
43#endif 27#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index dccfb37a9626..12be05b16880 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -124,6 +124,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
124 * 124 *
125 * If MCLK is not used, we just set saif clk to 512*fs. 125 * If MCLK is not used, we just set saif clk to 512*fs.
126 */ 126 */
127 clk_prepare_enable(master_saif->clk);
128
127 if (master_saif->mclk_in_use) { 129 if (master_saif->mclk_in_use) {
128 if (mclk % 32 == 0) { 130 if (mclk % 32 == 0) {
129 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; 131 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
@@ -133,6 +135,7 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
133 ret = clk_set_rate(master_saif->clk, 384 * rate); 135 ret = clk_set_rate(master_saif->clk, 384 * rate);
134 } else { 136 } else {
135 /* SAIF MCLK should be either 32x or 48x */ 137 /* SAIF MCLK should be either 32x or 48x */
138 clk_disable_unprepare(master_saif->clk);
136 return -EINVAL; 139 return -EINVAL;
137 } 140 }
138 } else { 141 } else {
@@ -140,6 +143,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif,
140 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; 143 scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE;
141 } 144 }
142 145
146 clk_disable_unprepare(master_saif->clk);
147
143 if (ret) 148 if (ret)
144 return ret; 149 return ret;
145 150
@@ -625,7 +630,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
625 if (pdev->id >= ARRAY_SIZE(mxs_saif)) 630 if (pdev->id >= ARRAY_SIZE(mxs_saif))
626 return -EINVAL; 631 return -EINVAL;
627 632
628 saif = kzalloc(sizeof(*saif), GFP_KERNEL); 633 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
629 if (!saif) 634 if (!saif)
630 return -ENOMEM; 635 return -ENOMEM;
631 636
@@ -650,29 +655,16 @@ static int mxs_saif_probe(struct platform_device *pdev)
650 ret = PTR_ERR(saif->clk); 655 ret = PTR_ERR(saif->clk);
651 dev_err(&pdev->dev, "Cannot get the clock: %d\n", 656 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
652 ret); 657 ret);
653 goto failed_clk; 658 return ret;
654 } 659 }
655 660
656 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 661 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
657 if (!iores) {
658 ret = -ENODEV;
659 dev_err(&pdev->dev, "failed to get io resource: %d\n",
660 ret);
661 goto failed_get_resource;
662 }
663
664 if (!request_mem_region(iores->start, resource_size(iores),
665 "mxs-saif")) {
666 dev_err(&pdev->dev, "request_mem_region failed\n");
667 ret = -EBUSY;
668 goto failed_get_resource;
669 }
670 662
671 saif->base = ioremap(iores->start, resource_size(iores)); 663 saif->base = devm_request_and_ioremap(&pdev->dev, iores);
672 if (!saif->base) { 664 if (!saif->base) {
673 dev_err(&pdev->dev, "ioremap failed\n"); 665 dev_err(&pdev->dev, "ioremap failed\n");
674 ret = -ENODEV; 666 ret = -ENODEV;
675 goto failed_ioremap; 667 goto failed_get_resource;
676 } 668 }
677 669
678 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 670 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -680,7 +672,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
680 ret = -ENODEV; 672 ret = -ENODEV;
681 dev_err(&pdev->dev, "failed to get dma resource: %d\n", 673 dev_err(&pdev->dev, "failed to get dma resource: %d\n",
682 ret); 674 ret);
683 goto failed_ioremap; 675 goto failed_get_resource;
684 } 676 }
685 saif->dma_param.chan_num = dmares->start; 677 saif->dma_param.chan_num = dmares->start;
686 678
@@ -689,14 +681,15 @@ static int mxs_saif_probe(struct platform_device *pdev)
689 ret = saif->irq; 681 ret = saif->irq;
690 dev_err(&pdev->dev, "failed to get irq resource: %d\n", 682 dev_err(&pdev->dev, "failed to get irq resource: %d\n",
691 ret); 683 ret);
692 goto failed_get_irq1; 684 goto failed_get_resource;
693 } 685 }
694 686
695 saif->dev = &pdev->dev; 687 saif->dev = &pdev->dev;
696 ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif); 688 ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
689 "mxs-saif", saif);
697 if (ret) { 690 if (ret) {
698 dev_err(&pdev->dev, "failed to request irq\n"); 691 dev_err(&pdev->dev, "failed to request irq\n");
699 goto failed_get_irq1; 692 goto failed_get_resource;
700 } 693 }
701 694
702 saif->dma_param.chan_irq = platform_get_irq(pdev, 1); 695 saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -704,7 +697,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
704 ret = saif->dma_param.chan_irq; 697 ret = saif->dma_param.chan_irq;
705 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", 698 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
706 ret); 699 ret);
707 goto failed_get_irq2; 700 goto failed_get_resource;
708 } 701 }
709 702
710 platform_set_drvdata(pdev, saif); 703 platform_set_drvdata(pdev, saif);
@@ -712,7 +705,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
712 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); 705 ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
713 if (ret) { 706 if (ret) {
714 dev_err(&pdev->dev, "register DAI failed\n"); 707 dev_err(&pdev->dev, "register DAI failed\n");
715 goto failed_register; 708 goto failed_get_resource;
716 } 709 }
717 710
718 saif->soc_platform_pdev = platform_device_alloc( 711 saif->soc_platform_pdev = platform_device_alloc(
@@ -735,36 +728,19 @@ failed_pdev_add:
735 platform_device_put(saif->soc_platform_pdev); 728 platform_device_put(saif->soc_platform_pdev);
736failed_pdev_alloc: 729failed_pdev_alloc:
737 snd_soc_unregister_dai(&pdev->dev); 730 snd_soc_unregister_dai(&pdev->dev);
738failed_register:
739failed_get_irq2:
740 free_irq(saif->irq, saif);
741failed_get_irq1:
742 iounmap(saif->base);
743failed_ioremap:
744 release_mem_region(iores->start, resource_size(iores));
745failed_get_resource: 731failed_get_resource:
746 clk_put(saif->clk); 732 clk_put(saif->clk);
747failed_clk:
748 kfree(saif);
749 733
750 return ret; 734 return ret;
751} 735}
752 736
753static int __devexit mxs_saif_remove(struct platform_device *pdev) 737static int __devexit mxs_saif_remove(struct platform_device *pdev)
754{ 738{
755 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
756 struct mxs_saif *saif = platform_get_drvdata(pdev); 739 struct mxs_saif *saif = platform_get_drvdata(pdev);
757 740
758 platform_device_unregister(saif->soc_platform_pdev); 741 platform_device_unregister(saif->soc_platform_pdev);
759
760 snd_soc_unregister_dai(&pdev->dev); 742 snd_soc_unregister_dai(&pdev->dev);
761
762 iounmap(saif->base);
763 release_mem_region(res->start, resource_size(res));
764 free_irq(saif->irq, saif);
765
766 clk_put(saif->clk); 743 clk_put(saif->clk);
767 kfree(saif);
768 744
769 return 0; 745 return 0;
770} 746}
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index a67f4370bc9f..78563bbbbf01 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -570,7 +570,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
570 snd_soc_dapm_disable_pin(dapm, "AGCOUT"); 570 snd_soc_dapm_disable_pin(dapm, "AGCOUT");
571 571
572 /* Add virtual switch */ 572 /* Add virtual switch */
573 ret = snd_soc_add_controls(codec, ams_delta_audio_controls, 573 ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls,
574 ARRAY_SIZE(ams_delta_audio_controls)); 574 ARRAY_SIZE(ams_delta_audio_controls));
575 if (ret) 575 if (ret)
576 dev_warn(card->dev, 576 dev_warn(card->dev,
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 597be412f1e4..c292bf0fd19c 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -55,9 +55,8 @@ static int n810_spk_func;
55static int n810_jack_func; 55static int n810_jack_func;
56static int n810_dmic_func; 56static int n810_dmic_func;
57 57
58static void n810_ext_control(struct snd_soc_codec *codec) 58static void n810_ext_control(struct snd_soc_dapm_context *dapm)
59{ 59{
60 struct snd_soc_dapm_context *dapm = &codec->dapm;
61 int hp = 0, line1l = 0; 60 int hp = 0, line1l = 0;
62 61
63 switch (n810_jack_func) { 62 switch (n810_jack_func) {
@@ -102,7 +101,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
102 snd_pcm_hw_constraint_minmax(runtime, 101 snd_pcm_hw_constraint_minmax(runtime,
103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 102 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
104 103
105 n810_ext_control(codec); 104 n810_ext_control(&codec->dapm);
106 return clk_enable(sys_clkout2); 105 return clk_enable(sys_clkout2);
107} 106}
108 107
@@ -142,13 +141,13 @@ static int n810_get_spk(struct snd_kcontrol *kcontrol,
142static int n810_set_spk(struct snd_kcontrol *kcontrol, 141static int n810_set_spk(struct snd_kcontrol *kcontrol,
143 struct snd_ctl_elem_value *ucontrol) 142 struct snd_ctl_elem_value *ucontrol)
144{ 143{
145 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 144 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
146 145
147 if (n810_spk_func == ucontrol->value.integer.value[0]) 146 if (n810_spk_func == ucontrol->value.integer.value[0])
148 return 0; 147 return 0;
149 148
150 n810_spk_func = ucontrol->value.integer.value[0]; 149 n810_spk_func = ucontrol->value.integer.value[0];
151 n810_ext_control(codec); 150 n810_ext_control(&card->dapm);
152 151
153 return 1; 152 return 1;
154} 153}
@@ -164,13 +163,13 @@ static int n810_get_jack(struct snd_kcontrol *kcontrol,
164static int n810_set_jack(struct snd_kcontrol *kcontrol, 163static int n810_set_jack(struct snd_kcontrol *kcontrol,
165 struct snd_ctl_elem_value *ucontrol) 164 struct snd_ctl_elem_value *ucontrol)
166{ 165{
167 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 166 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
168 167
169 if (n810_jack_func == ucontrol->value.integer.value[0]) 168 if (n810_jack_func == ucontrol->value.integer.value[0])
170 return 0; 169 return 0;
171 170
172 n810_jack_func = ucontrol->value.integer.value[0]; 171 n810_jack_func = ucontrol->value.integer.value[0];
173 n810_ext_control(codec); 172 n810_ext_control(&card->dapm);
174 173
175 return 1; 174 return 1;
176} 175}
@@ -186,13 +185,13 @@ static int n810_get_input(struct snd_kcontrol *kcontrol,
186static int n810_set_input(struct snd_kcontrol *kcontrol, 185static int n810_set_input(struct snd_kcontrol *kcontrol,
187 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
188{ 187{
189 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
190 189
191 if (n810_dmic_func == ucontrol->value.integer.value[0]) 190 if (n810_dmic_func == ucontrol->value.integer.value[0])
192 return 0; 191 return 0;
193 192
194 n810_dmic_func = ucontrol->value.integer.value[0]; 193 n810_dmic_func = ucontrol->value.integer.value[0];
195 n810_ext_control(codec); 194 n810_ext_control(&card->dapm);
196 195
197 return 1; 196 return 1;
198} 197}
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 017371913ec3..1287b870f221 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -744,17 +744,17 @@ static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
744 omap_mcbsp3_set_st_ch1_volume), 744 omap_mcbsp3_set_st_ch1_volume),
745}; 745};
746 746
747int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id) 747int omap_mcbsp_st_add_controls(struct snd_soc_dai *dai)
748{ 748{
749 if (!cpu_is_omap34xx()) 749 if (!cpu_is_omap34xx())
750 return -ENODEV; 750 return -ENODEV;
751 751
752 switch (mcbsp_id) { 752 switch (dai->id) {
753 case 1: /* McBSP 2 */ 753 case 1: /* McBSP 2 */
754 return snd_soc_add_controls(codec, omap_mcbsp2_st_controls, 754 return snd_soc_add_dai_controls(dai, omap_mcbsp2_st_controls,
755 ARRAY_SIZE(omap_mcbsp2_st_controls)); 755 ARRAY_SIZE(omap_mcbsp2_st_controls));
756 case 2: /* McBSP 3 */ 756 case 2: /* McBSP 3 */
757 return snd_soc_add_controls(codec, omap_mcbsp3_st_controls, 757 return snd_soc_add_dai_controls(dai, omap_mcbsp3_st_controls,
758 ARRAY_SIZE(omap_mcbsp3_st_controls)); 758 ARRAY_SIZE(omap_mcbsp3_st_controls));
759 default: 759 default:
760 break; 760 break;
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 65cde9d3807b..476fe2add703 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -59,6 +59,6 @@ enum omap_mcbsp_div {
59#define NUM_LINKS 5 59#define NUM_LINKS 5
60#endif 60#endif
61 61
62int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id); 62int omap_mcbsp_st_add_controls(struct snd_soc_dai *dai);
63 63
64#endif 64#endif
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index fada6ef43eea..58936c730a87 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -59,9 +59,8 @@ static int rx51_spk_func;
59static int rx51_dmic_func; 59static int rx51_dmic_func;
60static int rx51_jack_func; 60static int rx51_jack_func;
61 61
62static void rx51_ext_control(struct snd_soc_codec *codec) 62static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
63{ 63{
64 struct snd_soc_dapm_context *dapm = &codec->dapm;
65 int hp = 0, hs = 0, tvout = 0; 64 int hp = 0, hs = 0, tvout = 0;
66 65
67 switch (rx51_jack_func) { 66 switch (rx51_jack_func) {
@@ -102,11 +101,11 @@ static int rx51_startup(struct snd_pcm_substream *substream)
102{ 101{
103 struct snd_pcm_runtime *runtime = substream->runtime; 102 struct snd_pcm_runtime *runtime = substream->runtime;
104 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
105 struct snd_soc_codec *codec = rtd->codec; 104 struct snd_soc_card *card = rtd->card;
106 105
107 snd_pcm_hw_constraint_minmax(runtime, 106 snd_pcm_hw_constraint_minmax(runtime,
108 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 107 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
109 rx51_ext_control(codec); 108 rx51_ext_control(&card->dapm);
110 109
111 return 0; 110 return 0;
112} 111}
@@ -138,13 +137,13 @@ static int rx51_get_spk(struct snd_kcontrol *kcontrol,
138static int rx51_set_spk(struct snd_kcontrol *kcontrol, 137static int rx51_set_spk(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 138 struct snd_ctl_elem_value *ucontrol)
140{ 139{
141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 140 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
142 141
143 if (rx51_spk_func == ucontrol->value.integer.value[0]) 142 if (rx51_spk_func == ucontrol->value.integer.value[0])
144 return 0; 143 return 0;
145 144
146 rx51_spk_func = ucontrol->value.integer.value[0]; 145 rx51_spk_func = ucontrol->value.integer.value[0];
147 rx51_ext_control(codec); 146 rx51_ext_control(&card->dapm);
148 147
149 return 1; 148 return 1;
150} 149}
@@ -184,13 +183,13 @@ static int rx51_get_input(struct snd_kcontrol *kcontrol,
184static int rx51_set_input(struct snd_kcontrol *kcontrol, 183static int rx51_set_input(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol) 184 struct snd_ctl_elem_value *ucontrol)
186{ 185{
187 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 186 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
188 187
189 if (rx51_dmic_func == ucontrol->value.integer.value[0]) 188 if (rx51_dmic_func == ucontrol->value.integer.value[0])
190 return 0; 189 return 0;
191 190
192 rx51_dmic_func = ucontrol->value.integer.value[0]; 191 rx51_dmic_func = ucontrol->value.integer.value[0];
193 rx51_ext_control(codec); 192 rx51_ext_control(&card->dapm);
194 193
195 return 1; 194 return 1;
196} 195}
@@ -206,13 +205,13 @@ static int rx51_get_jack(struct snd_kcontrol *kcontrol,
206static int rx51_set_jack(struct snd_kcontrol *kcontrol, 205static int rx51_set_jack(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 206 struct snd_ctl_elem_value *ucontrol)
208{ 207{
209 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 208 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
210 209
211 if (rx51_jack_func == ucontrol->value.integer.value[0]) 210 if (rx51_jack_func == ucontrol->value.integer.value[0])
212 return 0; 211 return 0;
213 212
214 rx51_jack_func = ucontrol->value.integer.value[0]; 213 rx51_jack_func = ucontrol->value.integer.value[0];
215 rx51_ext_control(codec); 214 rx51_ext_control(&card->dapm);
216 215
217 return 1; 216 return 1;
218} 217}
@@ -297,7 +296,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
297 snd_soc_dapm_nc_pin(dapm, "LINE1R"); 296 snd_soc_dapm_nc_pin(dapm, "LINE1R");
298 297
299 /* Add RX-51 specific controls */ 298 /* Add RX-51 specific controls */
300 err = snd_soc_add_controls(codec, aic34_rx51_controls, 299 err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
301 ARRAY_SIZE(aic34_rx51_controls)); 300 ARRAY_SIZE(aic34_rx51_controls));
302 if (err < 0) 301 if (err < 0)
303 return err; 302 return err;
@@ -314,7 +313,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
314 return err; 313 return err;
315 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); 314 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
316 315
317 err = omap_mcbsp_st_add_controls(codec, 1); 316 err = omap_mcbsp_st_add_controls(rtd->cpu_dai);
318 if (err < 0) 317 if (err < 0)
319 return err; 318 return err;
320 319
@@ -335,7 +334,7 @@ static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
335{ 334{
336 int err; 335 int err;
337 336
338 err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb, 337 err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
339 ARRAY_SIZE(aic34_rx51_controlsb)); 338 ARRAY_SIZE(aic34_rx51_controlsb));
340 if (err < 0) 339 if (err < 0)
341 return err; 340 return err;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index bc21944851c4..863367ad89ce 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -45,10 +45,8 @@
45static int corgi_jack_func; 45static int corgi_jack_func;
46static int corgi_spk_func; 46static int corgi_spk_func;
47 47
48static void corgi_ext_control(struct snd_soc_codec *codec) 48static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
49{ 49{
50 struct snd_soc_dapm_context *dapm = &codec->dapm;
51
52 /* set up jack connection */ 50 /* set up jack connection */
53 switch (corgi_jack_func) { 51 switch (corgi_jack_func) {
54 case CORGI_HP: 52 case CORGI_HP:
@@ -104,7 +102,7 @@ static int corgi_startup(struct snd_pcm_substream *substream)
104 mutex_lock(&codec->mutex); 102 mutex_lock(&codec->mutex);
105 103
106 /* check the jack status at stream startup */ 104 /* check the jack status at stream startup */
107 corgi_ext_control(codec); 105 corgi_ext_control(&codec->dapm);
108 106
109 mutex_unlock(&codec->mutex); 107 mutex_unlock(&codec->mutex);
110 108
@@ -173,13 +171,13 @@ static int corgi_get_jack(struct snd_kcontrol *kcontrol,
173static int corgi_set_jack(struct snd_kcontrol *kcontrol, 171static int corgi_set_jack(struct snd_kcontrol *kcontrol,
174 struct snd_ctl_elem_value *ucontrol) 172 struct snd_ctl_elem_value *ucontrol)
175{ 173{
176 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 174 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
177 175
178 if (corgi_jack_func == ucontrol->value.integer.value[0]) 176 if (corgi_jack_func == ucontrol->value.integer.value[0])
179 return 0; 177 return 0;
180 178
181 corgi_jack_func = ucontrol->value.integer.value[0]; 179 corgi_jack_func = ucontrol->value.integer.value[0];
182 corgi_ext_control(codec); 180 corgi_ext_control(&card->dapm);
183 return 1; 181 return 1;
184} 182}
185 183
@@ -193,13 +191,13 @@ static int corgi_get_spk(struct snd_kcontrol *kcontrol,
193static int corgi_set_spk(struct snd_kcontrol *kcontrol, 191static int corgi_set_spk(struct snd_kcontrol *kcontrol,
194 struct snd_ctl_elem_value *ucontrol) 192 struct snd_ctl_elem_value *ucontrol)
195{ 193{
196 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 194 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
197 195
198 if (corgi_spk_func == ucontrol->value.integer.value[0]) 196 if (corgi_spk_func == ucontrol->value.integer.value[0])
199 return 0; 197 return 0;
200 198
201 corgi_spk_func = ucontrol->value.integer.value[0]; 199 corgi_spk_func = ucontrol->value.integer.value[0];
202 corgi_ext_control(codec); 200 corgi_ext_control(&card->dapm);
203 return 1; 201 return 1;
204} 202}
205 203
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 3f7a8ecb9720..aace19e0fe2c 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -411,7 +411,7 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
411 snd_soc_dapm_nc_pin(dapm, "VINR"); 411 snd_soc_dapm_nc_pin(dapm, "VINR");
412 412
413 /* Add magician specific controls */ 413 /* Add magician specific controls */
414 err = snd_soc_add_controls(codec, uda1380_magician_controls, 414 err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
415 ARRAY_SIZE(uda1380_magician_controls)); 415 ARRAY_SIZE(uda1380_magician_controls));
416 if (err < 0) 416 if (err < 0)
417 return err; 417 return err;
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index fd0ed10c6fe7..d2cc81735036 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -43,10 +43,8 @@
43static int poodle_jack_func; 43static int poodle_jack_func;
44static int poodle_spk_func; 44static int poodle_spk_func;
45 45
46static void poodle_ext_control(struct snd_soc_codec *codec) 46static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
47{ 47{
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
50 /* set up jack connection */ 48 /* set up jack connection */
51 if (poodle_jack_func == POODLE_HP) { 49 if (poodle_jack_func == POODLE_HP) {
52 /* set = unmute headphone */ 50 /* set = unmute headphone */
@@ -81,7 +79,7 @@ static int poodle_startup(struct snd_pcm_substream *substream)
81 mutex_lock(&codec->mutex); 79 mutex_lock(&codec->mutex);
82 80
83 /* check the jack status at stream startup */ 81 /* check the jack status at stream startup */
84 poodle_ext_control(codec); 82 poodle_ext_control(&codec->dapm);
85 83
86 mutex_unlock(&codec->mutex); 84 mutex_unlock(&codec->mutex);
87 85
@@ -152,13 +150,13 @@ static int poodle_get_jack(struct snd_kcontrol *kcontrol,
152static int poodle_set_jack(struct snd_kcontrol *kcontrol, 150static int poodle_set_jack(struct snd_kcontrol *kcontrol,
153 struct snd_ctl_elem_value *ucontrol) 151 struct snd_ctl_elem_value *ucontrol)
154{ 152{
155 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 153 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
156 154
157 if (poodle_jack_func == ucontrol->value.integer.value[0]) 155 if (poodle_jack_func == ucontrol->value.integer.value[0])
158 return 0; 156 return 0;
159 157
160 poodle_jack_func = ucontrol->value.integer.value[0]; 158 poodle_jack_func = ucontrol->value.integer.value[0];
161 poodle_ext_control(codec); 159 poodle_ext_control(&card->dapm);
162 return 1; 160 return 1;
163} 161}
164 162
@@ -172,13 +170,13 @@ static int poodle_get_spk(struct snd_kcontrol *kcontrol,
172static int poodle_set_spk(struct snd_kcontrol *kcontrol, 170static int poodle_set_spk(struct snd_kcontrol *kcontrol,
173 struct snd_ctl_elem_value *ucontrol) 171 struct snd_ctl_elem_value *ucontrol)
174{ 172{
175 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 173 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
176 174
177 if (poodle_spk_func == ucontrol->value.integer.value[0]) 175 if (poodle_spk_func == ucontrol->value.integer.value[0])
178 return 0; 176 return 0;
179 177
180 poodle_spk_func = ucontrol->value.integer.value[0]; 178 poodle_spk_func = ucontrol->value.integer.value[0];
181 poodle_ext_control(codec); 179 poodle_ext_control(&card->dapm);
182 return 1; 180 return 1;
183} 181}
184 182
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 837ff341fd6d..4800d5fe568d 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -103,7 +103,7 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
103#define pxa2xx_ac97_resume NULL 103#define pxa2xx_ac97_resume NULL
104#endif 104#endif
105 105
106static int pxa2xx_ac97_probe(struct snd_soc_dai *dai) 106static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai)
107{ 107{
108 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); 108 return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
109} 109}
@@ -179,7 +179,7 @@ static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
179 * There is only 1 physical AC97 interface for pxa2xx, but it 179 * There is only 1 physical AC97 interface for pxa2xx, but it
180 * has extra fifo's that can be used for aux DACs and ADCs. 180 * has extra fifo's that can be used for aux DACs and ADCs.
181 */ 181 */
182static struct snd_soc_dai_driver pxa_ac97_dai[] = { 182static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = {
183{ 183{
184 .name = "pxa2xx-ac97", 184 .name = "pxa2xx-ac97",
185 .ac97_control = 1, 185 .ac97_control = 1,
@@ -244,13 +244,13 @@ static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
244 * driver to do interesting things with the clocking to get us up 244 * driver to do interesting things with the clocking to get us up
245 * and running. 245 * and running.
246 */ 246 */
247 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai, 247 return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver,
248 ARRAY_SIZE(pxa_ac97_dai)); 248 ARRAY_SIZE(pxa_ac97_dai_driver));
249} 249}
250 250
251static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) 251static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
252{ 252{
253 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai)); 253 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver));
254 return 0; 254 return 0;
255} 255}
256 256
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index ba1545188ec6..083706595495 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -232,7 +232,7 @@ static struct snd_soc_ops raumfeld_ak4104_ops = {
232 .cpu_dai_name = "pxa-ssp-dai.0", \ 232 .cpu_dai_name = "pxa-ssp-dai.0", \
233 .platform_name = "pxa-pcm-audio", \ 233 .platform_name = "pxa-pcm-audio", \
234 .codec_dai_name = "cs4270-hifi", \ 234 .codec_dai_name = "cs4270-hifi", \
235 .codec_name = "cs4270-codec.0-0048", \ 235 .codec_name = "cs4270.0-0048", \
236 .ops = &raumfeld_cs4270_ops, \ 236 .ops = &raumfeld_cs4270_ops, \
237} 237}
238 238
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 90c5245c4742..fc052d8247ff 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -44,10 +44,8 @@ static int spitz_jack_func;
44static int spitz_spk_func; 44static int spitz_spk_func;
45static int spitz_mic_gpio; 45static int spitz_mic_gpio;
46 46
47static void spitz_ext_control(struct snd_soc_codec *codec) 47static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
48{ 48{
49 struct snd_soc_dapm_context *dapm = &codec->dapm;
50
51 if (spitz_spk_func == SPITZ_SPK_ON) 49 if (spitz_spk_func == SPITZ_SPK_ON)
52 snd_soc_dapm_enable_pin(dapm, "Ext Spk"); 50 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
53 else 51 else
@@ -113,7 +111,7 @@ static int spitz_startup(struct snd_pcm_substream *substream)
113 mutex_lock(&codec->mutex); 111 mutex_lock(&codec->mutex);
114 112
115 /* check the jack status at stream startup */ 113 /* check the jack status at stream startup */
116 spitz_ext_control(codec); 114 spitz_ext_control(&codec->dapm);
117 115
118 mutex_unlock(&codec->mutex); 116 mutex_unlock(&codec->mutex);
119 117
@@ -173,13 +171,13 @@ static int spitz_get_jack(struct snd_kcontrol *kcontrol,
173static int spitz_set_jack(struct snd_kcontrol *kcontrol, 171static int spitz_set_jack(struct snd_kcontrol *kcontrol,
174 struct snd_ctl_elem_value *ucontrol) 172 struct snd_ctl_elem_value *ucontrol)
175{ 173{
176 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 174 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
177 175
178 if (spitz_jack_func == ucontrol->value.integer.value[0]) 176 if (spitz_jack_func == ucontrol->value.integer.value[0])
179 return 0; 177 return 0;
180 178
181 spitz_jack_func = ucontrol->value.integer.value[0]; 179 spitz_jack_func = ucontrol->value.integer.value[0];
182 spitz_ext_control(codec); 180 spitz_ext_control(&card->dapm);
183 return 1; 181 return 1;
184} 182}
185 183
@@ -193,13 +191,13 @@ static int spitz_get_spk(struct snd_kcontrol *kcontrol,
193static int spitz_set_spk(struct snd_kcontrol *kcontrol, 191static int spitz_set_spk(struct snd_kcontrol *kcontrol,
194 struct snd_ctl_elem_value *ucontrol) 192 struct snd_ctl_elem_value *ucontrol)
195{ 193{
196 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 194 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
197 195
198 if (spitz_spk_func == ucontrol->value.integer.value[0]) 196 if (spitz_spk_func == ucontrol->value.integer.value[0])
199 return 0; 197 return 0;
200 198
201 spitz_spk_func = ucontrol->value.integer.value[0]; 199 spitz_spk_func = ucontrol->value.integer.value[0];
202 spitz_ext_control(codec); 200 spitz_ext_control(&card->dapm);
203 return 1; 201 return 1;
204} 202}
205 203
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 564ef08a89f2..2aec63f3706a 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -197,7 +197,7 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
197 snd_soc_dapm_nc_pin(dapm, "MONOOUT"); 197 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
198 198
199 /* add tosa specific controls */ 199 /* add tosa specific controls */
200 err = snd_soc_add_controls(codec, tosa_controls, 200 err = snd_soc_add_codec_controls(codec, tosa_controls,
201 ARRAY_SIZE(tosa_controls)); 201 ARRAY_SIZE(tosa_controls));
202 if (err < 0) 202 if (err < 0)
203 return err; 203 return err;
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 7b9bf93e3701..3d04c1fa6781 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -4,7 +4,7 @@
4 * Evolved from s3c2443-ac97.c 4 * Evolved from s3c2443-ac97.c
5 * 5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd 6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com> 7 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
8 * Credits: Graeme Gregory, Sean Choi 8 * Credits: Graeme Gregory, Sean Choi
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -511,7 +511,7 @@ static struct platform_driver s3c_ac97_driver = {
511 511
512module_platform_driver(s3c_ac97_driver); 512module_platform_driver(s3c_ac97_driver);
513 513
514MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 514MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
515MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); 515MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
516MODULE_LICENSE("GPL"); 516MODULE_LICENSE("GPL");
517MODULE_ALIAS("platform:samsung-ac97"); 517MODULE_ALIAS("platform:samsung-ac97");
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 87a874dc7a35..6553b19c70c7 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver 3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 * 4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd. 5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.com> 6 * Jaswinder Singh <jassisinghbrar@gmail.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
@@ -761,15 +761,13 @@ static int i2s_trigger(struct snd_pcm_substream *substream,
761 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 761 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
762 local_irq_save(flags); 762 local_irq_save(flags);
763 763
764 if (capture) 764 if (capture) {
765 i2s_rxctrl(i2s, 0); 765 i2s_rxctrl(i2s, 0);
766 else
767 i2s_txctrl(i2s, 0);
768
769 if (capture)
770 i2s_fifo(i2s, FIC_RXFLUSH); 766 i2s_fifo(i2s, FIC_RXFLUSH);
771 else 767 } else {
768 i2s_txctrl(i2s, 0);
772 i2s_fifo(i2s, FIC_TXFLUSH); 769 i2s_fifo(i2s, FIC_TXFLUSH);
770 }
773 771
774 local_irq_restore(flags); 772 local_irq_restore(flags);
775 break; 773 break;
@@ -1143,7 +1141,7 @@ static struct platform_driver samsung_i2s_driver = {
1143module_platform_driver(samsung_i2s_driver); 1141module_platform_driver(samsung_i2s_driver);
1144 1142
1145/* Module information */ 1143/* Module information */
1146MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 1144MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
1147MODULE_DESCRIPTION("Samsung I2S Interface"); 1145MODULE_DESCRIPTION("Samsung I2S Interface");
1148MODULE_ALIAS("platform:samsung-i2s"); 1146MODULE_ALIAS("platform:samsung-i2s");
1149MODULE_LICENSE("GPL"); 1147MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
index 8e15f6a616d1..d420a7ca56ca 100644
--- a/sound/soc/samsung/i2s.h
+++ b/sound/soc/samsung/i2s.h
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver 3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 * 4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd. 5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.com> 6 * Jaswinder Singh <jassisinghbrar@gmail.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 9dd818bde06f..e7416851bf7d 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -189,6 +189,9 @@ static int littlemill_late_probe(struct snd_soc_card *card)
189 /* This will check device compatibility itself */ 189 /* This will check device compatibility itself */
190 wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); 190 wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
191 191
192 /* As will this */
193 wm8994_mic_detect(codec, &littlemill_headset, 1);
194
192 return 0; 195 return 0;
193} 196}
194 197
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 7ac0ba2025c3..24bdb321269a 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -230,8 +230,6 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
230 230
231/* GTA02 specific routes and controls */ 231/* GTA02 specific routes and controls */
232 232
233#ifdef CONFIG_MACH_NEO1973_GTA02
234
235static int gta02_speaker_enabled; 233static int gta02_speaker_enabled;
236 234
237static int lm4853_set_spk(struct snd_kcontrol *kcontrol, 235static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
@@ -298,7 +296,7 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
298 if (ret) 296 if (ret)
299 return ret; 297 return ret;
300 298
301 ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls, 299 ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls,
302 ARRAY_SIZE(neo1973_gta02_wm8753_controls)); 300 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
303 if (ret) 301 if (ret)
304 return ret; 302 return ret;
@@ -311,10 +309,6 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
311 return 0; 309 return 0;
312} 310}
313 311
314#else
315static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; }
316#endif
317
318static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 312static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
319{ 313{
320 struct snd_soc_codec *codec = rtd->codec; 314 struct snd_soc_codec *codec = rtd->codec;
@@ -322,10 +316,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
322 int ret; 316 int ret;
323 317
324 /* set up NC codec pins */ 318 /* set up NC codec pins */
325 if (machine_is_neo1973_gta01()) {
326 snd_soc_dapm_nc_pin(dapm, "LOUT2");
327 snd_soc_dapm_nc_pin(dapm, "ROUT2");
328 }
329 snd_soc_dapm_nc_pin(dapm, "OUT3"); 319 snd_soc_dapm_nc_pin(dapm, "OUT3");
330 snd_soc_dapm_nc_pin(dapm, "OUT4"); 320 snd_soc_dapm_nc_pin(dapm, "OUT4");
331 snd_soc_dapm_nc_pin(dapm, "LINE1"); 321 snd_soc_dapm_nc_pin(dapm, "LINE1");
@@ -338,7 +328,7 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
338 return ret; 328 return ret;
339 329
340 /* add neo1973 specific controls */ 330 /* add neo1973 specific controls */
341 ret = snd_soc_add_controls(codec, neo1973_wm8753_controls, 331 ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls,
342 ARRAY_SIZE(neo1973_wm8753_controls)); 332 ARRAY_SIZE(neo1973_wm8753_controls));
343 if (ret) 333 if (ret)
344 return ret; 334 return ret;
@@ -370,50 +360,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
370 return 0; 360 return 0;
371} 361}
372 362
373/* GTA01 specific controls */
374
375#ifdef CONFIG_MACH_NEO1973_GTA01
376
377static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = {
378 {"Amp IN", NULL, "ROUT1"},
379 {"Amp IN", NULL, "LOUT1"},
380
381 {"Handset Spk", NULL, "Amp EP"},
382 {"Stereo Out", NULL, "Amp LS"},
383 {"Headphone", NULL, "Amp HP"},
384};
385
386static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = {
387 SND_SOC_DAPM_SPK("Handset Spk", NULL),
388 SND_SOC_DAPM_SPK("Stereo Out", NULL),
389 SND_SOC_DAPM_HP("Headphone", NULL),
390};
391
392static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm)
393{
394 int ret;
395
396 ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets,
397 ARRAY_SIZE(neo1973_lm4857_dapm_widgets));
398 if (ret)
399 return ret;
400
401 ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes,
402 ARRAY_SIZE(neo1973_lm4857_routes));
403 if (ret)
404 return ret;
405
406 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
407 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
408 snd_soc_dapm_ignore_suspend(dapm, "Headphone");
409
410 return 0;
411}
412
413#else
414static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; };
415#endif
416
417static struct snd_soc_dai_link neo1973_dai[] = { 363static struct snd_soc_dai_link neo1973_dai[] = {
418{ /* Hifi Playback - for similatious use with voice below */ 364{ /* Hifi Playback - for similatious use with voice below */
419 .name = "WM8753", 365 .name = "WM8753",
@@ -440,11 +386,6 @@ static struct snd_soc_aux_dev neo1973_aux_devs[] = {
440 .name = "dfbmcs320", 386 .name = "dfbmcs320",
441 .codec_name = "dfbmcs320.0", 387 .codec_name = "dfbmcs320.0",
442 }, 388 },
443 {
444 .name = "lm4857",
445 .codec_name = "lm4857.0-007c",
446 .init = neo1973_lm4857_init,
447 },
448}; 389};
449 390
450static struct snd_soc_codec_conf neo1973_codec_conf[] = { 391static struct snd_soc_codec_conf neo1973_codec_conf[] = {
@@ -454,14 +395,10 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = {
454 }, 395 },
455}; 396};
456 397
457#ifdef CONFIG_MACH_NEO1973_GTA02
458static const struct gpio neo1973_gta02_gpios[] = { 398static const struct gpio neo1973_gta02_gpios[] = {
459 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, 399 { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
460 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, 400 { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
461}; 401};
462#else
463static const struct gpio neo1973_gta02_gpios[] = {};
464#endif
465 402
466static struct snd_soc_card neo1973 = { 403static struct snd_soc_card neo1973 = {
467 .name = "neo1973", 404 .name = "neo1973",
@@ -480,7 +417,7 @@ static int __init neo1973_init(void)
480{ 417{
481 int ret; 418 int ret;
482 419
483 if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) 420 if (!machine_is_neo1973_gta02())
484 return -ENODEV; 421 return -ENODEV;
485 422
486 if (machine_is_neo1973_gta02()) { 423 if (machine_is_neo1973_gta02()) {
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 56780206c000..b7b2a1f91425 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -3,7 +3,7 @@
3 * ALSA SoC Audio Layer - S3C PCM-Controller driver 3 * ALSA SoC Audio Layer - S3C PCM-Controller driver
4 * 4 *
5 * Copyright (c) 2009 Samsung Electronics Co. Ltd 5 * Copyright (c) 2009 Samsung Electronics Co. Ltd
6 * Author: Jaswinder Singh <jassi.brar@samsung.com> 6 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
7 * based upon I2S drivers by Ben Dooks. 7 * based upon I2S drivers by Ben Dooks.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
@@ -639,7 +639,7 @@ static struct platform_driver s3c_pcm_driver = {
639module_platform_driver(s3c_pcm_driver); 639module_platform_driver(s3c_pcm_driver);
640 640
641/* Module information */ 641/* Module information */
642MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 642MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>");
643MODULE_DESCRIPTION("S3C PCM Controller Driver"); 643MODULE_DESCRIPTION("S3C PCM Controller Driver");
644MODULE_LICENSE("GPL"); 644MODULE_LICENSE("GPL");
645MODULE_ALIAS("platform:samsung-pcm"); 645MODULE_ALIAS("platform:samsung-pcm");
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index a253bcc1646a..656d5afe4ca9 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -134,18 +134,18 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = {
134 134
135void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) 135void simtec_audio_init(struct snd_soc_pcm_runtime *rtd)
136{ 136{
137 struct snd_soc_codec *codec = rtd->codec; 137 struct snd_soc_card *card = rtd->card;
138 138
139 if (pdata->amp_gpio > 0) { 139 if (pdata->amp_gpio > 0) {
140 pr_debug("%s: adding amp routes\n", __func__); 140 pr_debug("%s: adding amp routes\n", __func__);
141 141
142 snd_soc_add_controls(codec, amp_unmute_controls, 142 snd_soc_add_card_controls(card, amp_unmute_controls,
143 ARRAY_SIZE(amp_unmute_controls)); 143 ARRAY_SIZE(amp_unmute_controls));
144 } 144 }
145 145
146 if (pdata->amp_gain[0] > 0) { 146 if (pdata->amp_gain[0] > 0) {
147 pr_debug("%s: adding amp controls\n", __func__); 147 pr_debug("%s: adding amp controls\n", __func__);
148 snd_soc_add_controls(codec, amp_gain_controls, 148 snd_soc_add_card_controls(card, amp_gain_controls,
149 ARRAY_SIZE(amp_gain_controls)); 149 ARRAY_SIZE(amp_gain_controls));
150 } 150 }
151} 151}
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index bff8758e7f20..ade2809cf393 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -2,7 +2,7 @@
2 * smdk_wm8580.c 2 * smdk_wm8580.c
3 * 3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd 4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com> 5 * Author: Jaswinder Singh <jassisinghbrar@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -253,6 +253,6 @@ static void __exit smdk_audio_exit(void)
253} 253}
254module_exit(smdk_audio_exit); 254module_exit(smdk_audio_exit);
255 255
256MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); 256MODULE_AUTHOR("Jaswinder Singh, jassisinghbrar@gmail.com");
257MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); 257MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
258MODULE_LICENSE("GPL"); 258MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 8e26a730fcdc..55b2ca7f3290 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -2,7 +2,7 @@
2 * smdk_wm9713.c -- SoC audio for SMDK 2 * smdk_wm9713.c -- SoC audio for SMDK
3 * 3 *
4 * Copyright 2010 Samsung Electronics Co. Ltd. 4 * Copyright 2010 Samsung Electronics Co. Ltd.
5 * Author: Jaswinder Singh Brar <jassi.brar@samsung.com> 5 * Author: Jaswinder Singh Brar <jassisinghbrar@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
@@ -103,6 +103,6 @@ module_init(smdk_init);
103module_exit(smdk_exit); 103module_exit(smdk_exit);
104 104
105/* Module information */ 105/* Module information */
106MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); 106MODULE_AUTHOR("Jaswinder Singh Brar, jassisinghbrar@gmail.com");
107MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); 107MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
108MODULE_LICENSE("GPL"); 108MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index db6c89a28bda..378cc5b056d7 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -13,8 +13,11 @@
13 */ 13 */
14 14
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/dma-mapping.h>
16#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
17#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/scatterlist.h>
20#include <linux/sh_dma.h>
18#include <linux/slab.h> 21#include <linux/slab.h>
19#include <linux/module.h> 22#include <linux/module.h>
20#include <sound/soc.h> 23#include <sound/soc.h>
@@ -53,6 +56,7 @@
53 56
54/* DO_FMT */ 57/* DO_FMT */
55/* DI_FMT */ 58/* DI_FMT */
59#define CR_BWS_MASK (0x3 << 20) /* FSI2 */
56#define CR_BWS_24 (0x0 << 20) /* FSI2 */ 60#define CR_BWS_24 (0x0 << 20) /* FSI2 */
57#define CR_BWS_16 (0x1 << 20) /* FSI2 */ 61#define CR_BWS_16 (0x1 << 20) /* FSI2 */
58#define CR_BWS_20 (0x2 << 20) /* FSI2 */ 62#define CR_BWS_20 (0x2 << 20) /* FSI2 */
@@ -68,6 +72,15 @@
68#define CR_TDM (0x4 << 4) 72#define CR_TDM (0x4 << 4)
69#define CR_TDM_D (0x5 << 4) 73#define CR_TDM_D (0x5 << 4)
70 74
75/* OUT_DMAC */
76/* IN_DMAC */
77#define VDMD_MASK (0x3 << 4)
78#define VDMD_FRONT (0x0 << 4) /* Package in front */
79#define VDMD_BACK (0x1 << 4) /* Package in back */
80#define VDMD_STREAM (0x2 << 4) /* Stream mode(16bit * 2) */
81
82#define DMA_ON (0x1 << 0)
83
71/* DOFF_CTL */ 84/* DOFF_CTL */
72/* DIFF_CTL */ 85/* DIFF_CTL */
73#define IRQ_HALF 0x00100000 86#define IRQ_HALF 0x00100000
@@ -116,7 +129,7 @@
116 129
117#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 130#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
118 131
119typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable); 132typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
120 133
121/* 134/*
122 * FSI driver use below type name for variable 135 * FSI driver use below type name for variable
@@ -159,22 +172,41 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
159 * struct 172 * struct
160 */ 173 */
161 174
175struct fsi_stream_handler;
162struct fsi_stream { 176struct fsi_stream {
163 struct snd_pcm_substream *substream;
164 177
178 /*
179 * these are initialized by fsi_stream_init()
180 */
181 struct snd_pcm_substream *substream;
165 int fifo_sample_capa; /* sample capacity of FSI FIFO */ 182 int fifo_sample_capa; /* sample capacity of FSI FIFO */
166 int buff_sample_capa; /* sample capacity of ALSA buffer */ 183 int buff_sample_capa; /* sample capacity of ALSA buffer */
167 int buff_sample_pos; /* sample position of ALSA buffer */ 184 int buff_sample_pos; /* sample position of ALSA buffer */
168 int period_samples; /* sample number / 1 period */ 185 int period_samples; /* sample number / 1 period */
169 int period_pos; /* current period position */ 186 int period_pos; /* current period position */
170 187 int sample_width; /* sample width */
171 int uerr_num; 188 int uerr_num;
172 int oerr_num; 189 int oerr_num;
190
191 /*
192 * thse are initialized by fsi_handler_init()
193 */
194 struct fsi_stream_handler *handler;
195 struct fsi_priv *priv;
196
197 /*
198 * these are for DMAEngine
199 */
200 struct dma_chan *chan;
201 struct sh_dmae_slave slave; /* see fsi_handler_init() */
202 struct tasklet_struct tasklet;
203 dma_addr_t dma;
173}; 204};
174 205
175struct fsi_priv { 206struct fsi_priv {
176 void __iomem *base; 207 void __iomem *base;
177 struct fsi_master *master; 208 struct fsi_master *master;
209 struct sh_fsi_port_info *info;
178 210
179 struct fsi_stream playback; 211 struct fsi_stream playback;
180 struct fsi_stream capture; 212 struct fsi_stream capture;
@@ -189,6 +221,20 @@ struct fsi_priv {
189 long rate; 221 long rate;
190}; 222};
191 223
224struct fsi_stream_handler {
225 int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
226 int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
227 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
228 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
229 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
230 void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
231 int enable);
232};
233#define fsi_stream_handler_call(io, func, args...) \
234 (!(io) ? -ENODEV : \
235 !((io)->handler->func) ? 0 : \
236 (io)->handler->func(args))
237
192struct fsi_core { 238struct fsi_core {
193 int ver; 239 int ver;
194 240
@@ -205,10 +251,11 @@ struct fsi_master {
205 struct fsi_priv fsia; 251 struct fsi_priv fsia;
206 struct fsi_priv fsib; 252 struct fsi_priv fsib;
207 struct fsi_core *core; 253 struct fsi_core *core;
208 struct sh_fsi_platform_info *info;
209 spinlock_t lock; 254 spinlock_t lock;
210}; 255};
211 256
257static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
258
212/* 259/*
213 * basic read write function 260 * basic read write function
214 */ 261 */
@@ -295,6 +342,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi)
295 return fsi->spdif; 342 return fsi->spdif;
296} 343}
297 344
345static int fsi_is_play(struct snd_pcm_substream *substream)
346{
347 return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
348}
349
298static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) 350static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
299{ 351{
300 struct snd_soc_pcm_runtime *rtd = substream->private_data; 352 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -317,44 +369,25 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
317 return fsi_get_priv_frm_dai(fsi_get_dai(substream)); 369 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
318} 370}
319 371
320static set_rate_func fsi_get_info_set_rate(struct fsi_master *master) 372static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
321{ 373{
322 if (!master->info) 374 if (!fsi->info)
323 return NULL; 375 return NULL;
324 376
325 return master->info->set_rate; 377 return fsi->info->set_rate;
326} 378}
327 379
328static u32 fsi_get_info_flags(struct fsi_priv *fsi) 380static u32 fsi_get_info_flags(struct fsi_priv *fsi)
329{ 381{
330 int is_porta = fsi_is_port_a(fsi); 382 if (!fsi->info)
331 struct fsi_master *master = fsi_get_master(fsi);
332
333 if (!master->info)
334 return 0; 383 return 0;
335 384
336 return is_porta ? master->info->porta_flags : 385 return fsi->info->flags;
337 master->info->portb_flags;
338}
339
340static inline int fsi_stream_is_play(int stream)
341{
342 return stream == SNDRV_PCM_STREAM_PLAYBACK;
343} 386}
344 387
345static inline int fsi_is_play(struct snd_pcm_substream *substream) 388static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
346{
347 return fsi_stream_is_play(substream->stream);
348}
349
350static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
351 int is_play)
352{
353 return is_play ? &fsi->playback : &fsi->capture;
354}
355
356static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
357{ 389{
390 int is_play = fsi_stream_is_play(fsi, io);
358 int is_porta = fsi_is_port_a(fsi); 391 int is_porta = fsi_is_port_a(fsi);
359 u32 shift; 392 u32 shift;
360 393
@@ -376,26 +409,81 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
376 return samples / fsi->chan_num; 409 return samples / fsi->chan_num;
377} 410}
378 411
412static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
413 struct fsi_stream *io)
414{
415 int is_play = fsi_stream_is_play(fsi, io);
416 u32 status;
417 int frames;
418
419 status = is_play ?
420 fsi_reg_read(fsi, DOFF_ST) :
421 fsi_reg_read(fsi, DIFF_ST);
422
423 frames = 0x1ff & (status >> 8);
424
425 return fsi_frame2sample(fsi, frames);
426}
427
428static void fsi_count_fifo_err(struct fsi_priv *fsi)
429{
430 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
431 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
432
433 if (ostatus & ERR_OVER)
434 fsi->playback.oerr_num++;
435
436 if (ostatus & ERR_UNDER)
437 fsi->playback.uerr_num++;
438
439 if (istatus & ERR_OVER)
440 fsi->capture.oerr_num++;
441
442 if (istatus & ERR_UNDER)
443 fsi->capture.uerr_num++;
444
445 fsi_reg_write(fsi, DOFF_ST, 0);
446 fsi_reg_write(fsi, DIFF_ST, 0);
447}
448
449/*
450 * fsi_stream_xx() function
451 */
452static inline int fsi_stream_is_play(struct fsi_priv *fsi,
453 struct fsi_stream *io)
454{
455 return &fsi->playback == io;
456}
457
458static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
459 struct snd_pcm_substream *substream)
460{
461 return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
462}
463
379static int fsi_stream_is_working(struct fsi_priv *fsi, 464static int fsi_stream_is_working(struct fsi_priv *fsi,
380 int is_play) 465 struct fsi_stream *io)
381{ 466{
382 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
383 struct fsi_master *master = fsi_get_master(fsi); 467 struct fsi_master *master = fsi_get_master(fsi);
384 unsigned long flags; 468 unsigned long flags;
385 int ret; 469 int ret;
386 470
387 spin_lock_irqsave(&master->lock, flags); 471 spin_lock_irqsave(&master->lock, flags);
388 ret = !!io->substream; 472 ret = !!(io->substream && io->substream->runtime);
389 spin_unlock_irqrestore(&master->lock, flags); 473 spin_unlock_irqrestore(&master->lock, flags);
390 474
391 return ret; 475 return ret;
392} 476}
393 477
394static void fsi_stream_push(struct fsi_priv *fsi, 478static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
395 int is_play, 479{
480 return io->priv;
481}
482
483static void fsi_stream_init(struct fsi_priv *fsi,
484 struct fsi_stream *io,
396 struct snd_pcm_substream *substream) 485 struct snd_pcm_substream *substream)
397{ 486{
398 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
399 struct snd_pcm_runtime *runtime = substream->runtime; 487 struct snd_pcm_runtime *runtime = substream->runtime;
400 struct fsi_master *master = fsi_get_master(fsi); 488 struct fsi_master *master = fsi_get_master(fsi);
401 unsigned long flags; 489 unsigned long flags;
@@ -406,14 +494,15 @@ static void fsi_stream_push(struct fsi_priv *fsi,
406 io->buff_sample_pos = 0; 494 io->buff_sample_pos = 0;
407 io->period_samples = fsi_frame2sample(fsi, runtime->period_size); 495 io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
408 io->period_pos = 0; 496 io->period_pos = 0;
497 io->sample_width = samples_to_bytes(runtime, 1);
409 io->oerr_num = -1; /* ignore 1st err */ 498 io->oerr_num = -1; /* ignore 1st err */
410 io->uerr_num = -1; /* ignore 1st err */ 499 io->uerr_num = -1; /* ignore 1st err */
500 fsi_stream_handler_call(io, init, fsi, io);
411 spin_unlock_irqrestore(&master->lock, flags); 501 spin_unlock_irqrestore(&master->lock, flags);
412} 502}
413 503
414static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) 504static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
415{ 505{
416 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
417 struct snd_soc_dai *dai = fsi_get_dai(io->substream); 506 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
418 struct fsi_master *master = fsi_get_master(fsi); 507 struct fsi_master *master = fsi_get_master(fsi);
419 unsigned long flags; 508 unsigned long flags;
@@ -426,127 +515,87 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
426 if (io->uerr_num > 0) 515 if (io->uerr_num > 0)
427 dev_err(dai->dev, "under_run = %d\n", io->uerr_num); 516 dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
428 517
518 fsi_stream_handler_call(io, quit, fsi, io);
429 io->substream = NULL; 519 io->substream = NULL;
430 io->buff_sample_capa = 0; 520 io->buff_sample_capa = 0;
431 io->buff_sample_pos = 0; 521 io->buff_sample_pos = 0;
432 io->period_samples = 0; 522 io->period_samples = 0;
433 io->period_pos = 0; 523 io->period_pos = 0;
524 io->sample_width = 0;
434 io->oerr_num = 0; 525 io->oerr_num = 0;
435 io->uerr_num = 0; 526 io->uerr_num = 0;
436 spin_unlock_irqrestore(&master->lock, flags); 527 spin_unlock_irqrestore(&master->lock, flags);
437} 528}
438 529
439static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play) 530static int fsi_stream_transfer(struct fsi_stream *io)
440{ 531{
441 u32 status; 532 struct fsi_priv *fsi = fsi_stream_to_priv(io);
442 int frames; 533 if (!fsi)
534 return -EIO;
443 535
444 status = is_play ? 536 return fsi_stream_handler_call(io, transfer, fsi, io);
445 fsi_reg_read(fsi, DOFF_ST) :
446 fsi_reg_read(fsi, DIFF_ST);
447
448 frames = 0x1ff & (status >> 8);
449
450 return fsi_frame2sample(fsi, frames);
451} 537}
452 538
453static void fsi_count_fifo_err(struct fsi_priv *fsi) 539#define fsi_stream_start(fsi, io)\
454{ 540 fsi_stream_handler_call(io, start_stop, fsi, io, 1)
455 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
456 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
457 541
458 if (ostatus & ERR_OVER) 542#define fsi_stream_stop(fsi, io)\
459 fsi->playback.oerr_num++; 543 fsi_stream_handler_call(io, start_stop, fsi, io, 0)
460
461 if (ostatus & ERR_UNDER)
462 fsi->playback.uerr_num++;
463
464 if (istatus & ERR_OVER)
465 fsi->capture.oerr_num++;
466
467 if (istatus & ERR_UNDER)
468 fsi->capture.uerr_num++;
469 544
470 fsi_reg_write(fsi, DOFF_ST, 0); 545static int fsi_stream_probe(struct fsi_priv *fsi)
471 fsi_reg_write(fsi, DIFF_ST, 0);
472}
473
474/*
475 * dma function
476 */
477
478static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
479{ 546{
480 int is_play = fsi_stream_is_play(stream); 547 struct fsi_stream *io;
481 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 548 int ret1, ret2;
482 struct snd_pcm_runtime *runtime = io->substream->runtime;
483 549
484 return runtime->dma_area + 550 io = &fsi->playback;
485 samples_to_bytes(runtime, io->buff_sample_pos); 551 ret1 = fsi_stream_handler_call(io, probe, fsi, io);
486}
487 552
488static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) 553 io = &fsi->capture;
489{ 554 ret2 = fsi_stream_handler_call(io, probe, fsi, io);
490 u16 *start;
491 int i;
492 555
493 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK); 556 if (ret1 < 0)
557 return ret1;
558 if (ret2 < 0)
559 return ret2;
494 560
495 for (i = 0; i < num; i++) 561 return 0;
496 fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
497}
498
499static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
500{
501 u16 *start;
502 int i;
503
504 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
505
506
507 for (i = 0; i < num; i++)
508 *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
509} 562}
510 563
511static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num) 564static int fsi_stream_remove(struct fsi_priv *fsi)
512{ 565{
513 u32 *start; 566 struct fsi_stream *io;
514 int i; 567 int ret1, ret2;
515
516 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
517 568
569 io = &fsi->playback;
570 ret1 = fsi_stream_handler_call(io, remove, fsi, io);
518 571
519 for (i = 0; i < num; i++) 572 io = &fsi->capture;
520 fsi_reg_write(fsi, DODT, *(start + i)); 573 ret2 = fsi_stream_handler_call(io, remove, fsi, io);
521}
522
523static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num)
524{
525 u32 *start;
526 int i;
527 574
528 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE); 575 if (ret1 < 0)
576 return ret1;
577 if (ret2 < 0)
578 return ret2;
529 579
530 for (i = 0; i < num; i++) 580 return 0;
531 *(start + i) = fsi_reg_read(fsi, DIDT);
532} 581}
533 582
534/* 583/*
535 * irq function 584 * irq function
536 */ 585 */
537 586
538static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 587static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io)
539{ 588{
540 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 589 u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
541 struct fsi_master *master = fsi_get_master(fsi); 590 struct fsi_master *master = fsi_get_master(fsi);
542 591
543 fsi_core_mask_set(master, imsk, data, data); 592 fsi_core_mask_set(master, imsk, data, data);
544 fsi_core_mask_set(master, iemsk, data, data); 593 fsi_core_mask_set(master, iemsk, data, data);
545} 594}
546 595
547static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 596static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io)
548{ 597{
549 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 598 u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
550 struct fsi_master *master = fsi_get_master(fsi); 599 struct fsi_master *master = fsi_get_master(fsi);
551 600
552 fsi_core_mask_set(master, imsk, data, 0); 601 fsi_core_mask_set(master, imsk, data, 0);
@@ -563,8 +612,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
563 u32 data = 0; 612 u32 data = 0;
564 struct fsi_master *master = fsi_get_master(fsi); 613 struct fsi_master *master = fsi_get_master(fsi);
565 614
566 data |= AB_IO(1, fsi_get_port_shift(fsi, 0)); 615 data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
567 data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); 616 data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
568 617
569 /* clear interrupt factor */ 618 /* clear interrupt factor */
570 fsi_core_mask_set(master, int_st, data, 0); 619 fsi_core_mask_set(master, int_st, data, 0);
@@ -600,11 +649,14 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
600 long rate, int enable) 649 long rate, int enable)
601{ 650{
602 struct fsi_master *master = fsi_get_master(fsi); 651 struct fsi_master *master = fsi_get_master(fsi);
603 set_rate_func set_rate = fsi_get_info_set_rate(master); 652 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
604 int fsi_ver = master->core->ver; 653 int fsi_ver = master->core->ver;
605 int ret; 654 int ret;
606 655
607 ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable); 656 if (!set_rate)
657 return 0;
658
659 ret = set_rate(dev, rate, enable);
608 if (ret < 0) /* error */ 660 if (ret < 0) /* error */
609 return ret; 661 return ret;
610 662
@@ -671,96 +723,64 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
671 return ret; 723 return ret;
672} 724}
673 725
674#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) 726/*
675#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) 727 * pio data transfer handler
676static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) 728 */
729static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
677{ 730{
678 struct fsi_master *master = fsi_get_master(fsi); 731 u16 *buf = (u16 *)_buf;
679 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; 732 int i;
680 733
681 if (enable) 734 for (i = 0; i < samples; i++)
682 fsi_irq_enable(fsi, is_play); 735 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
683 else 736}
684 fsi_irq_disable(fsi, is_play);
685 737
686 if (fsi_is_clk_master(fsi)) 738static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
687 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 739{
740 u16 *buf = (u16 *)_buf;
741 int i;
742
743 for (i = 0; i < samples; i++)
744 *(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
688} 745}
689 746
690/* 747static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples)
691 * ctrl function
692 */
693static void fsi_fifo_init(struct fsi_priv *fsi,
694 int is_play,
695 struct device *dev)
696{ 748{
697 struct fsi_master *master = fsi_get_master(fsi); 749 u32 *buf = (u32 *)_buf;
698 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 750 int i;
699 u32 shift, i;
700 int frame_capa;
701 751
702 /* get on-chip RAM capacity */ 752 for (i = 0; i < samples; i++)
703 shift = fsi_master_read(master, FIFO_SZ); 753 fsi_reg_write(fsi, DODT, *(buf + i));
704 shift >>= fsi_get_port_shift(fsi, is_play); 754}
705 shift &= FIFO_SZ_MASK;
706 frame_capa = 256 << shift;
707 dev_dbg(dev, "fifo = %d words\n", frame_capa);
708 755
709 /* 756static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples)
710 * The maximum number of sample data varies depending 757{
711 * on the number of channels selected for the format. 758 u32 *buf = (u32 *)_buf;
712 * 759 int i;
713 * FIFOs are used in 4-channel units in 3-channel mode
714 * and in 8-channel units in 5- to 7-channel mode
715 * meaning that more FIFOs than the required size of DPRAM
716 * are used.
717 *
718 * ex) if 256 words of DP-RAM is connected
719 * 1 channel: 256 (256 x 1 = 256)
720 * 2 channels: 128 (128 x 2 = 256)
721 * 3 channels: 64 ( 64 x 3 = 192)
722 * 4 channels: 64 ( 64 x 4 = 256)
723 * 5 channels: 32 ( 32 x 5 = 160)
724 * 6 channels: 32 ( 32 x 6 = 192)
725 * 7 channels: 32 ( 32 x 7 = 224)
726 * 8 channels: 32 ( 32 x 8 = 256)
727 */
728 for (i = 1; i < fsi->chan_num; i <<= 1)
729 frame_capa >>= 1;
730 dev_dbg(dev, "%d channel %d store\n",
731 fsi->chan_num, frame_capa);
732 760
733 io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa); 761 for (i = 0; i < samples; i++)
762 *(buf + i) = fsi_reg_read(fsi, DIDT);
763}
734 764
735 /* 765static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
736 * set interrupt generation factor 766{
737 * clear FIFO 767 struct snd_pcm_runtime *runtime = io->substream->runtime;
738 */ 768
739 if (is_play) { 769 return runtime->dma_area +
740 fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); 770 samples_to_bytes(runtime, io->buff_sample_pos);
741 fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
742 } else {
743 fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
744 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
745 }
746} 771}
747 772
748static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) 773static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
774 void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
775 void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
776 int samples)
749{ 777{
750 struct snd_pcm_runtime *runtime; 778 struct snd_pcm_runtime *runtime;
751 struct snd_pcm_substream *substream = NULL; 779 struct snd_pcm_substream *substream;
752 int is_play = fsi_stream_is_play(stream); 780 u8 *buf;
753 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
754 int sample_residues;
755 int sample_width;
756 int samples;
757 int samples_max;
758 int over_period; 781 int over_period;
759 void (*fn)(struct fsi_priv *fsi, int size);
760 782
761 if (!fsi || 783 if (!fsi_stream_is_working(fsi, io))
762 !io->substream ||
763 !io->substream->runtime)
764 return -EINVAL; 784 return -EINVAL;
765 785
766 over_period = 0; 786 over_period = 0;
@@ -780,60 +800,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
780 io->buff_sample_pos = 0; 800 io->buff_sample_pos = 0;
781 } 801 }
782 802
783 /* get 1 sample data width */ 803 buf = fsi_pio_get_area(fsi, io);
784 sample_width = samples_to_bytes(runtime, 1);
785
786 /* get number of residue samples */
787 sample_residues = io->buff_sample_capa - io->buff_sample_pos;
788 804
789 if (is_play) { 805 switch (io->sample_width) {
790 /* 806 case 2:
791 * for play-back 807 run16(fsi, buf, samples);
792 * 808 break;
793 * samples_max : number of FSI fifo free samples space 809 case 4:
794 * samples : number of ALSA residue samples 810 run32(fsi, buf, samples);
795 */ 811 break;
796 samples_max = io->fifo_sample_capa; 812 default:
797 samples_max -= fsi_get_current_fifo_samples(fsi, is_play); 813 return -EINVAL;
798
799 samples = sample_residues;
800
801 switch (sample_width) {
802 case 2:
803 fn = fsi_dma_soft_push16;
804 break;
805 case 4:
806 fn = fsi_dma_soft_push32;
807 break;
808 default:
809 return -EINVAL;
810 }
811 } else {
812 /*
813 * for capture
814 *
815 * samples_max : number of ALSA free samples space
816 * samples : number of samples in FSI fifo
817 */
818 samples_max = sample_residues;
819 samples = fsi_get_current_fifo_samples(fsi, is_play);
820
821 switch (sample_width) {
822 case 2:
823 fn = fsi_dma_soft_pop16;
824 break;
825 case 4:
826 fn = fsi_dma_soft_pop32;
827 break;
828 default:
829 return -EINVAL;
830 }
831 } 814 }
832 815
833 samples = min(samples, samples_max);
834
835 fn(fsi, samples);
836
837 /* update buff_sample_pos */ 816 /* update buff_sample_pos */
838 io->buff_sample_pos += samples; 817 io->buff_sample_pos += samples;
839 818
@@ -843,16 +822,66 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
843 return 0; 822 return 0;
844} 823}
845 824
846static int fsi_data_pop(struct fsi_priv *fsi) 825static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
826{
827 int sample_residues; /* samples in FSI fifo */
828 int sample_space; /* ALSA free samples space */
829 int samples;
830
831 sample_residues = fsi_get_current_fifo_samples(fsi, io);
832 sample_space = io->buff_sample_capa - io->buff_sample_pos;
833
834 samples = min(sample_residues, sample_space);
835
836 return fsi_pio_transfer(fsi, io,
837 fsi_pio_pop16,
838 fsi_pio_pop32,
839 samples);
840}
841
842static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
847{ 843{
848 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE); 844 int sample_residues; /* ALSA residue samples */
845 int sample_space; /* FSI fifo free samples space */
846 int samples;
847
848 sample_residues = io->buff_sample_capa - io->buff_sample_pos;
849 sample_space = io->fifo_sample_capa -
850 fsi_get_current_fifo_samples(fsi, io);
851
852 samples = min(sample_residues, sample_space);
853
854 return fsi_pio_transfer(fsi, io,
855 fsi_pio_push16,
856 fsi_pio_push32,
857 samples);
849} 858}
850 859
851static int fsi_data_push(struct fsi_priv *fsi) 860static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
861 int enable)
852{ 862{
853 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK); 863 struct fsi_master *master = fsi_get_master(fsi);
864 u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
865
866 if (enable)
867 fsi_irq_enable(fsi, io);
868 else
869 fsi_irq_disable(fsi, io);
870
871 if (fsi_is_clk_master(fsi))
872 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
854} 873}
855 874
875static struct fsi_stream_handler fsi_pio_push_handler = {
876 .transfer = fsi_pio_push,
877 .start_stop = fsi_pio_start_stop,
878};
879
880static struct fsi_stream_handler fsi_pio_pop_handler = {
881 .transfer = fsi_pio_pop,
882 .start_stop = fsi_pio_start_stop,
883};
884
856static irqreturn_t fsi_interrupt(int irq, void *data) 885static irqreturn_t fsi_interrupt(int irq, void *data)
857{ 886{
858 struct fsi_master *master = data; 887 struct fsi_master *master = data;
@@ -863,13 +892,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
863 fsi_master_mask_set(master, SOFT_RST, IR, IR); 892 fsi_master_mask_set(master, SOFT_RST, IR, IR);
864 893
865 if (int_st & AB_IO(1, AO_SHIFT)) 894 if (int_st & AB_IO(1, AO_SHIFT))
866 fsi_data_push(&master->fsia); 895 fsi_stream_transfer(&master->fsia.playback);
867 if (int_st & AB_IO(1, BO_SHIFT)) 896 if (int_st & AB_IO(1, BO_SHIFT))
868 fsi_data_push(&master->fsib); 897 fsi_stream_transfer(&master->fsib.playback);
869 if (int_st & AB_IO(1, AI_SHIFT)) 898 if (int_st & AB_IO(1, AI_SHIFT))
870 fsi_data_pop(&master->fsia); 899 fsi_stream_transfer(&master->fsia.capture);
871 if (int_st & AB_IO(1, BI_SHIFT)) 900 if (int_st & AB_IO(1, BI_SHIFT))
872 fsi_data_pop(&master->fsib); 901 fsi_stream_transfer(&master->fsib.capture);
873 902
874 fsi_count_fifo_err(&master->fsia); 903 fsi_count_fifo_err(&master->fsia);
875 fsi_count_fifo_err(&master->fsib); 904 fsi_count_fifo_err(&master->fsib);
@@ -881,11 +910,271 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
881} 910}
882 911
883/* 912/*
913 * dma data transfer handler
914 */
915static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
916{
917 struct snd_pcm_runtime *runtime = io->substream->runtime;
918 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
919 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
920 DMA_TO_DEVICE : DMA_FROM_DEVICE;
921
922 io->dma = dma_map_single(dai->dev, runtime->dma_area,
923 snd_pcm_lib_buffer_bytes(io->substream), dir);
924 return 0;
925}
926
927static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
928{
929 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
930 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
931 DMA_TO_DEVICE : DMA_FROM_DEVICE;
932
933 dma_unmap_single(dai->dev, io->dma,
934 snd_pcm_lib_buffer_bytes(io->substream), dir);
935 return 0;
936}
937
938static void fsi_dma_complete(void *data)
939{
940 struct fsi_stream *io = (struct fsi_stream *)data;
941 struct fsi_priv *fsi = fsi_stream_to_priv(io);
942 struct snd_pcm_runtime *runtime = io->substream->runtime;
943 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
944 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
945 DMA_TO_DEVICE : DMA_FROM_DEVICE;
946
947 dma_sync_single_for_cpu(dai->dev, io->dma,
948 samples_to_bytes(runtime, io->period_samples), dir);
949
950 io->buff_sample_pos += io->period_samples;
951 io->period_pos++;
952
953 if (io->period_pos >= runtime->periods) {
954 io->period_pos = 0;
955 io->buff_sample_pos = 0;
956 }
957
958 fsi_count_fifo_err(fsi);
959 fsi_stream_transfer(io);
960
961 snd_pcm_period_elapsed(io->substream);
962}
963
964static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
965{
966 struct snd_pcm_runtime *runtime = io->substream->runtime;
967
968 return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
969}
970
971static void fsi_dma_do_tasklet(unsigned long data)
972{
973 struct fsi_stream *io = (struct fsi_stream *)data;
974 struct fsi_priv *fsi = fsi_stream_to_priv(io);
975 struct dma_chan *chan;
976 struct snd_soc_dai *dai;
977 struct dma_async_tx_descriptor *desc;
978 struct scatterlist sg;
979 struct snd_pcm_runtime *runtime;
980 enum dma_data_direction dir;
981 dma_cookie_t cookie;
982 int is_play = fsi_stream_is_play(fsi, io);
983 int len;
984 dma_addr_t buf;
985
986 if (!fsi_stream_is_working(fsi, io))
987 return;
988
989 dai = fsi_get_dai(io->substream);
990 chan = io->chan;
991 runtime = io->substream->runtime;
992 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
993 len = samples_to_bytes(runtime, io->period_samples);
994 buf = fsi_dma_get_area(io);
995
996 dma_sync_single_for_device(dai->dev, io->dma, len, dir);
997
998 sg_init_table(&sg, 1);
999 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
1000 len , offset_in_page(buf));
1001 sg_dma_address(&sg) = buf;
1002 sg_dma_len(&sg) = len;
1003
1004 desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
1005 DMA_PREP_INTERRUPT |
1006 DMA_CTRL_ACK);
1007 if (!desc) {
1008 dev_err(dai->dev, "device_prep_slave_sg() fail\n");
1009 return;
1010 }
1011
1012 desc->callback = fsi_dma_complete;
1013 desc->callback_param = io;
1014
1015 cookie = desc->tx_submit(desc);
1016 if (cookie < 0) {
1017 dev_err(dai->dev, "tx_submit() fail\n");
1018 return;
1019 }
1020
1021 dma_async_issue_pending(chan);
1022
1023 /*
1024 * FIXME
1025 *
1026 * In DMAEngine case, codec and FSI cannot be started simultaneously
1027 * since FSI is using tasklet.
1028 * Therefore, in capture case, probably FSI FIFO will have got
1029 * overflow error in this point.
1030 * in that case, DMA cannot start transfer until error was cleared.
1031 */
1032 if (!is_play) {
1033 if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) {
1034 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
1035 fsi_reg_write(fsi, DIFF_ST, 0);
1036 }
1037 }
1038}
1039
1040static bool fsi_dma_filter(struct dma_chan *chan, void *param)
1041{
1042 struct sh_dmae_slave *slave = param;
1043
1044 chan->private = slave;
1045
1046 return true;
1047}
1048
1049static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
1050{
1051 tasklet_schedule(&io->tasklet);
1052
1053 return 0;
1054}
1055
1056static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1057 int start)
1058{
1059 u32 bws;
1060 u32 dma;
1061
1062 switch (io->sample_width * start) {
1063 case 2:
1064 bws = CR_BWS_16;
1065 dma = VDMD_STREAM | DMA_ON;
1066 break;
1067 case 4:
1068 bws = CR_BWS_24;
1069 dma = VDMD_BACK | DMA_ON;
1070 break;
1071 default:
1072 bws = 0;
1073 dma = 0;
1074 }
1075
1076 fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
1077 fsi_reg_write(fsi, OUT_DMAC, dma);
1078}
1079
1080static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
1081{
1082 dma_cap_mask_t mask;
1083
1084 dma_cap_zero(mask);
1085 dma_cap_set(DMA_SLAVE, mask);
1086
1087 io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
1088 if (!io->chan)
1089 return -EIO;
1090
1091 tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
1092
1093 return 0;
1094}
1095
1096static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io)
1097{
1098 tasklet_kill(&io->tasklet);
1099
1100 fsi_stream_stop(fsi, io);
1101
1102 if (io->chan)
1103 dma_release_channel(io->chan);
1104
1105 io->chan = NULL;
1106 return 0;
1107}
1108
1109static struct fsi_stream_handler fsi_dma_push_handler = {
1110 .init = fsi_dma_init,
1111 .quit = fsi_dma_quit,
1112 .probe = fsi_dma_probe,
1113 .transfer = fsi_dma_transfer,
1114 .remove = fsi_dma_remove,
1115 .start_stop = fsi_dma_push_start_stop,
1116};
1117
1118/*
884 * dai ops 1119 * dai ops
885 */ 1120 */
1121static void fsi_fifo_init(struct fsi_priv *fsi,
1122 struct fsi_stream *io,
1123 struct device *dev)
1124{
1125 struct fsi_master *master = fsi_get_master(fsi);
1126 int is_play = fsi_stream_is_play(fsi, io);
1127 u32 shift, i;
1128 int frame_capa;
1129
1130 /* get on-chip RAM capacity */
1131 shift = fsi_master_read(master, FIFO_SZ);
1132 shift >>= fsi_get_port_shift(fsi, io);
1133 shift &= FIFO_SZ_MASK;
1134 frame_capa = 256 << shift;
1135 dev_dbg(dev, "fifo = %d words\n", frame_capa);
1136
1137 /*
1138 * The maximum number of sample data varies depending
1139 * on the number of channels selected for the format.
1140 *
1141 * FIFOs are used in 4-channel units in 3-channel mode
1142 * and in 8-channel units in 5- to 7-channel mode
1143 * meaning that more FIFOs than the required size of DPRAM
1144 * are used.
1145 *
1146 * ex) if 256 words of DP-RAM is connected
1147 * 1 channel: 256 (256 x 1 = 256)
1148 * 2 channels: 128 (128 x 2 = 256)
1149 * 3 channels: 64 ( 64 x 3 = 192)
1150 * 4 channels: 64 ( 64 x 4 = 256)
1151 * 5 channels: 32 ( 32 x 5 = 160)
1152 * 6 channels: 32 ( 32 x 6 = 192)
1153 * 7 channels: 32 ( 32 x 7 = 224)
1154 * 8 channels: 32 ( 32 x 8 = 256)
1155 */
1156 for (i = 1; i < fsi->chan_num; i <<= 1)
1157 frame_capa >>= 1;
1158 dev_dbg(dev, "%d channel %d store\n",
1159 fsi->chan_num, frame_capa);
1160
1161 io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
1162
1163 /*
1164 * set interrupt generation factor
1165 * clear FIFO
1166 */
1167 if (is_play) {
1168 fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
1169 fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
1170 } else {
1171 fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
1172 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
1173 }
1174}
886 1175
887static int fsi_hw_startup(struct fsi_priv *fsi, 1176static int fsi_hw_startup(struct fsi_priv *fsi,
888 int is_play, 1177 struct fsi_stream *io,
889 struct device *dev) 1178 struct device *dev)
890{ 1179{
891 struct fsi_master *master = fsi_get_master(fsi); 1180 struct fsi_master *master = fsi_get_master(fsi);
@@ -934,17 +1223,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
934 } 1223 }
935 1224
936 /* irq clear */ 1225 /* irq clear */
937 fsi_irq_disable(fsi, is_play); 1226 fsi_irq_disable(fsi, io);
938 fsi_irq_clear_status(fsi); 1227 fsi_irq_clear_status(fsi);
939 1228
940 /* fifo init */ 1229 /* fifo init */
941 fsi_fifo_init(fsi, is_play, dev); 1230 fsi_fifo_init(fsi, io, dev);
942 1231
943 return 0; 1232 return 0;
944} 1233}
945 1234
946static void fsi_hw_shutdown(struct fsi_priv *fsi, 1235static void fsi_hw_shutdown(struct fsi_priv *fsi,
947 int is_play,
948 struct device *dev) 1236 struct device *dev)
949{ 1237{
950 if (fsi_is_clk_master(fsi)) 1238 if (fsi_is_clk_master(fsi))
@@ -955,18 +1243,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
955 struct snd_soc_dai *dai) 1243 struct snd_soc_dai *dai)
956{ 1244{
957 struct fsi_priv *fsi = fsi_get_priv(substream); 1245 struct fsi_priv *fsi = fsi_get_priv(substream);
958 int is_play = fsi_is_play(substream);
959 1246
960 return fsi_hw_startup(fsi, is_play, dai->dev); 1247 return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
961} 1248}
962 1249
963static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 1250static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
964 struct snd_soc_dai *dai) 1251 struct snd_soc_dai *dai)
965{ 1252{
966 struct fsi_priv *fsi = fsi_get_priv(substream); 1253 struct fsi_priv *fsi = fsi_get_priv(substream);
967 int is_play = fsi_is_play(substream);
968 1254
969 fsi_hw_shutdown(fsi, is_play, dai->dev); 1255 fsi_hw_shutdown(fsi, dai->dev);
970 fsi->rate = 0; 1256 fsi->rate = 0;
971} 1257}
972 1258
@@ -974,18 +1260,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
974 struct snd_soc_dai *dai) 1260 struct snd_soc_dai *dai)
975{ 1261{
976 struct fsi_priv *fsi = fsi_get_priv(substream); 1262 struct fsi_priv *fsi = fsi_get_priv(substream);
977 int is_play = fsi_is_play(substream); 1263 struct fsi_stream *io = fsi_stream_get(fsi, substream);
978 int ret = 0; 1264 int ret = 0;
979 1265
980 switch (cmd) { 1266 switch (cmd) {
981 case SNDRV_PCM_TRIGGER_START: 1267 case SNDRV_PCM_TRIGGER_START:
982 fsi_stream_push(fsi, is_play, substream); 1268 fsi_stream_init(fsi, io, substream);
983 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 1269 ret = fsi_stream_transfer(io);
984 fsi_port_start(fsi, is_play); 1270 if (0 == ret)
1271 fsi_stream_start(fsi, io);
985 break; 1272 break;
986 case SNDRV_PCM_TRIGGER_STOP: 1273 case SNDRV_PCM_TRIGGER_STOP:
987 fsi_port_stop(fsi, is_play); 1274 fsi_stream_stop(fsi, io);
988 fsi_stream_pop(fsi, is_play); 1275 fsi_stream_quit(fsi, io);
989 break; 1276 break;
990 } 1277 }
991 1278
@@ -1036,8 +1323,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
1036static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1323static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1037{ 1324{
1038 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); 1325 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
1039 struct fsi_master *master = fsi_get_master(fsi); 1326 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
1040 set_rate_func set_rate = fsi_get_info_set_rate(master);
1041 u32 flags = fsi_get_info_flags(fsi); 1327 u32 flags = fsi_get_info_flags(fsi);
1042 int ret; 1328 int ret;
1043 1329
@@ -1151,13 +1437,9 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
1151static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 1437static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
1152{ 1438{
1153 struct fsi_priv *fsi = fsi_get_priv(substream); 1439 struct fsi_priv *fsi = fsi_get_priv(substream);
1154 struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); 1440 struct fsi_stream *io = fsi_stream_get(fsi, substream);
1155 int samples_pos = io->buff_sample_pos - 1;
1156
1157 if (samples_pos < 0)
1158 samples_pos = 0;
1159 1441
1160 return fsi_sample2frame(fsi, samples_pos); 1442 return fsi_sample2frame(fsi, io->buff_sample_pos);
1161} 1443}
1162 1444
1163static struct snd_pcm_ops fsi_pcm_ops = { 1445static struct snd_pcm_ops fsi_pcm_ops = {
@@ -1243,11 +1525,24 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
1243/* 1525/*
1244 * platform function 1526 * platform function
1245 */ 1527 */
1528static void fsi_handler_init(struct fsi_priv *fsi)
1529{
1530 fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */
1531 fsi->playback.priv = fsi;
1532 fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
1533 fsi->capture.priv = fsi;
1534
1535 if (fsi->info->tx_id) {
1536 fsi->playback.slave.slave_id = fsi->info->tx_id;
1537 fsi->playback.handler = &fsi_dma_push_handler;
1538 }
1539}
1246 1540
1247static int fsi_probe(struct platform_device *pdev) 1541static int fsi_probe(struct platform_device *pdev)
1248{ 1542{
1249 struct fsi_master *master; 1543 struct fsi_master *master;
1250 const struct platform_device_id *id_entry; 1544 const struct platform_device_id *id_entry;
1545 struct sh_fsi_platform_info *info = pdev->dev.platform_data;
1251 struct resource *res; 1546 struct resource *res;
1252 unsigned int irq; 1547 unsigned int irq;
1253 int ret; 1548 int ret;
@@ -1282,17 +1577,30 @@ static int fsi_probe(struct platform_device *pdev)
1282 1577
1283 /* master setting */ 1578 /* master setting */
1284 master->irq = irq; 1579 master->irq = irq;
1285 master->info = pdev->dev.platform_data;
1286 master->core = (struct fsi_core *)id_entry->driver_data; 1580 master->core = (struct fsi_core *)id_entry->driver_data;
1287 spin_lock_init(&master->lock); 1581 spin_lock_init(&master->lock);
1288 1582
1289 /* FSI A setting */ 1583 /* FSI A setting */
1290 master->fsia.base = master->base; 1584 master->fsia.base = master->base;
1291 master->fsia.master = master; 1585 master->fsia.master = master;
1586 master->fsia.info = &info->port_a;
1587 fsi_handler_init(&master->fsia);
1588 ret = fsi_stream_probe(&master->fsia);
1589 if (ret < 0) {
1590 dev_err(&pdev->dev, "FSIA stream probe failed\n");
1591 goto exit_iounmap;
1592 }
1292 1593
1293 /* FSI B setting */ 1594 /* FSI B setting */
1294 master->fsib.base = master->base + 0x40; 1595 master->fsib.base = master->base + 0x40;
1295 master->fsib.master = master; 1596 master->fsib.master = master;
1597 master->fsib.info = &info->port_b;
1598 fsi_handler_init(&master->fsib);
1599 ret = fsi_stream_probe(&master->fsib);
1600 if (ret < 0) {
1601 dev_err(&pdev->dev, "FSIB stream probe failed\n");
1602 goto exit_fsia;
1603 }
1296 1604
1297 pm_runtime_enable(&pdev->dev); 1605 pm_runtime_enable(&pdev->dev);
1298 dev_set_drvdata(&pdev->dev, master); 1606 dev_set_drvdata(&pdev->dev, master);
@@ -1301,7 +1609,7 @@ static int fsi_probe(struct platform_device *pdev)
1301 id_entry->name, master); 1609 id_entry->name, master);
1302 if (ret) { 1610 if (ret) {
1303 dev_err(&pdev->dev, "irq request err\n"); 1611 dev_err(&pdev->dev, "irq request err\n");
1304 goto exit_iounmap; 1612 goto exit_fsib;
1305 } 1613 }
1306 1614
1307 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); 1615 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
@@ -1323,6 +1631,10 @@ exit_snd_soc:
1323 snd_soc_unregister_platform(&pdev->dev); 1631 snd_soc_unregister_platform(&pdev->dev);
1324exit_free_irq: 1632exit_free_irq:
1325 free_irq(irq, master); 1633 free_irq(irq, master);
1634exit_fsib:
1635 fsi_stream_remove(&master->fsib);
1636exit_fsia:
1637 fsi_stream_remove(&master->fsia);
1326exit_iounmap: 1638exit_iounmap:
1327 iounmap(master->base); 1639 iounmap(master->base);
1328 pm_runtime_disable(&pdev->dev); 1640 pm_runtime_disable(&pdev->dev);
@@ -1345,6 +1657,9 @@ static int fsi_remove(struct platform_device *pdev)
1345 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); 1657 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
1346 snd_soc_unregister_platform(&pdev->dev); 1658 snd_soc_unregister_platform(&pdev->dev);
1347 1659
1660 fsi_stream_remove(&master->fsia);
1661 fsi_stream_remove(&master->fsib);
1662
1348 iounmap(master->base); 1663 iounmap(master->base);
1349 kfree(master); 1664 kfree(master);
1350 1665
@@ -1352,30 +1667,29 @@ static int fsi_remove(struct platform_device *pdev)
1352} 1667}
1353 1668
1354static void __fsi_suspend(struct fsi_priv *fsi, 1669static void __fsi_suspend(struct fsi_priv *fsi,
1355 int is_play, 1670 struct fsi_stream *io,
1356 struct device *dev) 1671 struct device *dev)
1357{ 1672{
1358 if (!fsi_stream_is_working(fsi, is_play)) 1673 if (!fsi_stream_is_working(fsi, io))
1359 return; 1674 return;
1360 1675
1361 fsi_port_stop(fsi, is_play); 1676 fsi_stream_stop(fsi, io);
1362 fsi_hw_shutdown(fsi, is_play, dev); 1677 fsi_hw_shutdown(fsi, dev);
1363} 1678}
1364 1679
1365static void __fsi_resume(struct fsi_priv *fsi, 1680static void __fsi_resume(struct fsi_priv *fsi,
1366 int is_play, 1681 struct fsi_stream *io,
1367 struct device *dev) 1682 struct device *dev)
1368{ 1683{
1369 if (!fsi_stream_is_working(fsi, is_play)) 1684 if (!fsi_stream_is_working(fsi, io))
1370 return; 1685 return;
1371 1686
1372 fsi_hw_startup(fsi, is_play, dev); 1687 fsi_hw_startup(fsi, io, dev);
1373 1688
1374 if (fsi_is_clk_master(fsi) && fsi->rate) 1689 if (fsi_is_clk_master(fsi) && fsi->rate)
1375 fsi_set_master_clk(dev, fsi, fsi->rate, 1); 1690 fsi_set_master_clk(dev, fsi, fsi->rate, 1);
1376 1691
1377 fsi_port_start(fsi, is_play); 1692 fsi_stream_start(fsi, io);
1378
1379} 1693}
1380 1694
1381static int fsi_suspend(struct device *dev) 1695static int fsi_suspend(struct device *dev)
@@ -1384,11 +1698,11 @@ static int fsi_suspend(struct device *dev)
1384 struct fsi_priv *fsia = &master->fsia; 1698 struct fsi_priv *fsia = &master->fsia;
1385 struct fsi_priv *fsib = &master->fsib; 1699 struct fsi_priv *fsib = &master->fsib;
1386 1700
1387 __fsi_suspend(fsia, 1, dev); 1701 __fsi_suspend(fsia, &fsia->playback, dev);
1388 __fsi_suspend(fsia, 0, dev); 1702 __fsi_suspend(fsia, &fsia->capture, dev);
1389 1703
1390 __fsi_suspend(fsib, 1, dev); 1704 __fsi_suspend(fsib, &fsib->playback, dev);
1391 __fsi_suspend(fsib, 0, dev); 1705 __fsi_suspend(fsib, &fsib->capture, dev);
1392 1706
1393 return 0; 1707 return 0;
1394} 1708}
@@ -1399,32 +1713,18 @@ static int fsi_resume(struct device *dev)
1399 struct fsi_priv *fsia = &master->fsia; 1713 struct fsi_priv *fsia = &master->fsia;
1400 struct fsi_priv *fsib = &master->fsib; 1714 struct fsi_priv *fsib = &master->fsib;
1401 1715
1402 __fsi_resume(fsia, 1, dev); 1716 __fsi_resume(fsia, &fsia->playback, dev);
1403 __fsi_resume(fsia, 0, dev); 1717 __fsi_resume(fsia, &fsia->capture, dev);
1404 1718
1405 __fsi_resume(fsib, 1, dev); 1719 __fsi_resume(fsib, &fsib->playback, dev);
1406 __fsi_resume(fsib, 0, dev); 1720 __fsi_resume(fsib, &fsib->capture, dev);
1407 1721
1408 return 0; 1722 return 0;
1409} 1723}
1410 1724
1411static int fsi_runtime_nop(struct device *dev)
1412{
1413 /* Runtime PM callback shared between ->runtime_suspend()
1414 * and ->runtime_resume(). Simply returns success.
1415 *
1416 * This driver re-initializes all registers after
1417 * pm_runtime_get_sync() anyway so there is no need
1418 * to save and restore registers here.
1419 */
1420 return 0;
1421}
1422
1423static struct dev_pm_ops fsi_pm_ops = { 1725static struct dev_pm_ops fsi_pm_ops = {
1424 .suspend = fsi_suspend, 1726 .suspend = fsi_suspend,
1425 .resume = fsi_resume, 1727 .resume = fsi_resume,
1426 .runtime_suspend = fsi_runtime_nop,
1427 .runtime_resume = fsi_runtime_nop,
1428}; 1728};
1429 1729
1430static struct fsi_core fsi1_core = { 1730static struct fsi_core fsi1_core = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 35a1e639d7f9..7978f6c01ef7 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -277,8 +277,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
277 codec->debugfs_codec_root = debugfs_create_dir(codec->name, 277 codec->debugfs_codec_root = debugfs_create_dir(codec->name,
278 debugfs_card_root); 278 debugfs_card_root);
279 if (!codec->debugfs_codec_root) { 279 if (!codec->debugfs_codec_root) {
280 printk(KERN_WARNING 280 dev_warn(codec->dev, "Failed to create codec debugfs directory\n");
281 "ASoC: Failed to create codec debugfs directory\n");
282 return; 281 return;
283 } 282 }
284 283
@@ -291,8 +290,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
291 codec->debugfs_codec_root, 290 codec->debugfs_codec_root,
292 codec, &codec_reg_fops); 291 codec, &codec_reg_fops);
293 if (!codec->debugfs_reg) 292 if (!codec->debugfs_reg)
294 printk(KERN_WARNING 293 dev_warn(codec->dev, "Failed to create codec register debugfs file\n");
295 "ASoC: Failed to create codec register debugfs file\n");
296 294
297 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); 295 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
298} 296}
@@ -302,6 +300,27 @@ static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
302 debugfs_remove_recursive(codec->debugfs_codec_root); 300 debugfs_remove_recursive(codec->debugfs_codec_root);
303} 301}
304 302
303static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
304{
305 struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
306
307 platform->debugfs_platform_root = debugfs_create_dir(platform->name,
308 debugfs_card_root);
309 if (!platform->debugfs_platform_root) {
310 dev_warn(platform->dev,
311 "Failed to create platform debugfs directory\n");
312 return;
313 }
314
315 snd_soc_dapm_debugfs_init(&platform->dapm,
316 platform->debugfs_platform_root);
317}
318
319static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
320{
321 debugfs_remove_recursive(platform->debugfs_platform_root);
322}
323
305static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, 324static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
306 size_t count, loff_t *ppos) 325 size_t count, loff_t *ppos)
307{ 326{
@@ -435,6 +454,14 @@ static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
435{ 454{
436} 455}
437 456
457static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform)
458{
459}
460
461static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
462{
463}
464
438static inline void soc_init_card_debugfs(struct snd_soc_card *card) 465static inline void soc_init_card_debugfs(struct snd_soc_card *card)
439{ 466{
440} 467}
@@ -546,18 +573,20 @@ int snd_soc_suspend(struct device *dev)
546 } 573 }
547 574
548 for (i = 0; i < card->num_rtd; i++) { 575 for (i = 0; i < card->num_rtd; i++) {
549 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; 576 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
550 577
551 if (card->rtd[i].dai_link->ignore_suspend) 578 if (card->rtd[i].dai_link->ignore_suspend)
552 continue; 579 continue;
553 580
554 if (driver->playback.stream_name != NULL) 581 snd_soc_dapm_stream_event(&card->rtd[i],
555 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, 582 SNDRV_PCM_STREAM_PLAYBACK,
556 SND_SOC_DAPM_STREAM_SUSPEND); 583 codec_dai,
584 SND_SOC_DAPM_STREAM_SUSPEND);
557 585
558 if (driver->capture.stream_name != NULL) 586 snd_soc_dapm_stream_event(&card->rtd[i],
559 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, 587 SNDRV_PCM_STREAM_CAPTURE,
560 SND_SOC_DAPM_STREAM_SUSPEND); 588 codec_dai,
589 SND_SOC_DAPM_STREAM_SUSPEND);
561 } 590 }
562 591
563 /* suspend all CODECs */ 592 /* suspend all CODECs */
@@ -567,6 +596,17 @@ int snd_soc_suspend(struct device *dev)
567 if (!codec->suspended && codec->driver->suspend) { 596 if (!codec->suspended && codec->driver->suspend) {
568 switch (codec->dapm.bias_level) { 597 switch (codec->dapm.bias_level) {
569 case SND_SOC_BIAS_STANDBY: 598 case SND_SOC_BIAS_STANDBY:
599 /*
600 * If the CODEC is capable of idle
601 * bias off then being in STANDBY
602 * means it's doing something,
603 * otherwise fall through.
604 */
605 if (codec->dapm.idle_bias_off) {
606 dev_dbg(codec->dev,
607 "idle_bias_off CODEC on over suspend\n");
608 break;
609 }
570 case SND_SOC_BIAS_OFF: 610 case SND_SOC_BIAS_OFF:
571 codec->driver->suspend(codec); 611 codec->driver->suspend(codec);
572 codec->suspended = 1; 612 codec->suspended = 1;
@@ -649,18 +689,18 @@ static void soc_resume_deferred(struct work_struct *work)
649 } 689 }
650 690
651 for (i = 0; i < card->num_rtd; i++) { 691 for (i = 0; i < card->num_rtd; i++) {
652 struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; 692 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
653 693
654 if (card->rtd[i].dai_link->ignore_suspend) 694 if (card->rtd[i].dai_link->ignore_suspend)
655 continue; 695 continue;
656 696
657 if (driver->playback.stream_name != NULL) 697 snd_soc_dapm_stream_event(&card->rtd[i],
658 snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, 698 SNDRV_PCM_STREAM_PLAYBACK, codec_dai,
659 SND_SOC_DAPM_STREAM_RESUME); 699 SND_SOC_DAPM_STREAM_RESUME);
660 700
661 if (driver->capture.stream_name != NULL) 701 snd_soc_dapm_stream_event(&card->rtd[i],
662 snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, 702 SNDRV_PCM_STREAM_CAPTURE, codec_dai,
663 SND_SOC_DAPM_STREAM_RESUME); 703 SND_SOC_DAPM_STREAM_RESUME);
664 } 704 }
665 705
666 /* unmute any active DACs */ 706 /* unmute any active DACs */
@@ -893,7 +933,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
893 if (codec_dai->driver->remove) { 933 if (codec_dai->driver->remove) {
894 err = codec_dai->driver->remove(codec_dai); 934 err = codec_dai->driver->remove(codec_dai);
895 if (err < 0) 935 if (err < 0)
896 printk(KERN_ERR "asoc: failed to remove %s\n", codec_dai->name); 936 pr_err("asoc: failed to remove %s: %d\n",
937 codec_dai->name, err);
897 } 938 }
898 codec_dai->probed = 0; 939 codec_dai->probed = 0;
899 list_del(&codec_dai->card_list); 940 list_del(&codec_dai->card_list);
@@ -905,12 +946,14 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
905 if (platform->driver->remove) { 946 if (platform->driver->remove) {
906 err = platform->driver->remove(platform); 947 err = platform->driver->remove(platform);
907 if (err < 0) 948 if (err < 0)
908 printk(KERN_ERR "asoc: failed to remove %s\n", platform->name); 949 pr_err("asoc: failed to remove %s: %d\n",
950 platform->name, err);
909 } 951 }
910 952
911 /* Make sure all DAPM widgets are freed */ 953 /* Make sure all DAPM widgets are freed */
912 snd_soc_dapm_free(&platform->dapm); 954 snd_soc_dapm_free(&platform->dapm);
913 955
956 soc_cleanup_platform_debugfs(platform);
914 platform->probed = 0; 957 platform->probed = 0;
915 list_del(&platform->card_list); 958 list_del(&platform->card_list);
916 module_put(platform->dev->driver->owner); 959 module_put(platform->dev->driver->owner);
@@ -927,7 +970,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
927 if (cpu_dai->driver->remove) { 970 if (cpu_dai->driver->remove) {
928 err = cpu_dai->driver->remove(cpu_dai); 971 err = cpu_dai->driver->remove(cpu_dai);
929 if (err < 0) 972 if (err < 0)
930 printk(KERN_ERR "asoc: failed to remove %s\n", cpu_dai->name); 973 pr_err("asoc: failed to remove %s: %d\n",
974 cpu_dai->name, err);
931 } 975 }
932 cpu_dai->probed = 0; 976 cpu_dai->probed = 0;
933 list_del(&cpu_dai->card_list); 977 list_del(&cpu_dai->card_list);
@@ -969,6 +1013,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
969{ 1013{
970 int ret = 0; 1014 int ret = 0;
971 const struct snd_soc_codec_driver *driver = codec->driver; 1015 const struct snd_soc_codec_driver *driver = codec->driver;
1016 struct snd_soc_dai *dai;
972 1017
973 codec->card = card; 1018 codec->card = card;
974 codec->dapm.card = card; 1019 codec->dapm.card = card;
@@ -983,6 +1028,14 @@ static int soc_probe_codec(struct snd_soc_card *card,
983 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, 1028 snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
984 driver->num_dapm_widgets); 1029 driver->num_dapm_widgets);
985 1030
1031 /* Create DAPM widgets for each DAI stream */
1032 list_for_each_entry(dai, &dai_list, list) {
1033 if (dai->dev != codec->dev)
1034 continue;
1035
1036 snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1037 }
1038
986 codec->dapm.idle_bias_off = driver->idle_bias_off; 1039 codec->dapm.idle_bias_off = driver->idle_bias_off;
987 1040
988 if (driver->probe) { 1041 if (driver->probe) {
@@ -996,7 +1049,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
996 } 1049 }
997 1050
998 if (driver->controls) 1051 if (driver->controls)
999 snd_soc_add_controls(codec, driver->controls, 1052 snd_soc_add_codec_controls(codec, driver->controls,
1000 driver->num_controls); 1053 driver->num_controls);
1001 if (driver->dapm_routes) 1054 if (driver->dapm_routes)
1002 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1055 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
@@ -1028,6 +1081,8 @@ static int soc_probe_platform(struct snd_soc_card *card,
1028 if (!try_module_get(platform->dev->driver->owner)) 1081 if (!try_module_get(platform->dev->driver->owner))
1029 return -ENODEV; 1082 return -ENODEV;
1030 1083
1084 soc_init_platform_debugfs(platform);
1085
1031 if (driver->dapm_widgets) 1086 if (driver->dapm_widgets)
1032 snd_soc_dapm_new_controls(&platform->dapm, 1087 snd_soc_dapm_new_controls(&platform->dapm,
1033 driver->dapm_widgets, driver->num_dapm_widgets); 1088 driver->dapm_widgets, driver->num_dapm_widgets);
@@ -1057,6 +1112,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1057 return 0; 1112 return 0;
1058 1113
1059err_probe: 1114err_probe:
1115 soc_cleanup_platform_debugfs(platform);
1060 module_put(platform->dev->driver->owner); 1116 module_put(platform->dev->driver->owner);
1061 1117
1062 return ret; 1118 return ret;
@@ -1172,8 +1228,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1172 if (cpu_dai->driver->probe) { 1228 if (cpu_dai->driver->probe) {
1173 ret = cpu_dai->driver->probe(cpu_dai); 1229 ret = cpu_dai->driver->probe(cpu_dai);
1174 if (ret < 0) { 1230 if (ret < 0) {
1175 printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", 1231 pr_err("asoc: failed to probe CPU DAI %s: %d\n",
1176 cpu_dai->name); 1232 cpu_dai->name, ret);
1177 module_put(cpu_dai->dev->driver->owner); 1233 module_put(cpu_dai->dev->driver->owner);
1178 return ret; 1234 return ret;
1179 } 1235 }
@@ -1204,8 +1260,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1204 if (codec_dai->driver->probe) { 1260 if (codec_dai->driver->probe) {
1205 ret = codec_dai->driver->probe(codec_dai); 1261 ret = codec_dai->driver->probe(codec_dai);
1206 if (ret < 0) { 1262 if (ret < 0) {
1207 printk(KERN_ERR "asoc: failed to probe CODEC DAI %s\n", 1263 pr_err("asoc: failed to probe CODEC DAI %s: %d\n",
1208 codec_dai->name); 1264 codec_dai->name, ret);
1209 return ret; 1265 return ret;
1210 } 1266 }
1211 } 1267 }
@@ -1225,12 +1281,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1225 1281
1226 ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); 1282 ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
1227 if (ret < 0) 1283 if (ret < 0)
1228 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); 1284 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
1229 1285
1230 /* create the pcm */ 1286 /* create the pcm */
1231 ret = soc_new_pcm(rtd, num); 1287 ret = soc_new_pcm(rtd, num);
1232 if (ret < 0) { 1288 if (ret < 0) {
1233 printk(KERN_ERR "asoc: can't create pcm %s\n", dai_link->stream_name); 1289 pr_err("asoc: can't create pcm %s :%d\n",
1290 dai_link->stream_name, ret);
1234 return ret; 1291 return ret;
1235 } 1292 }
1236 1293
@@ -1263,7 +1320,7 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
1263 1320
1264 ret = soc_ac97_dev_register(rtd->codec); 1321 ret = soc_ac97_dev_register(rtd->codec);
1265 if (ret < 0) { 1322 if (ret < 0) {
1266 printk(KERN_ERR "asoc: AC97 device register failed\n"); 1323 pr_err("asoc: AC97 device register failed:%d\n", ret);
1267 return ret; 1324 return ret;
1268 } 1325 }
1269 1326
@@ -1403,8 +1460,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1403 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1460 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1404 card->owner, 0, &card->snd_card); 1461 card->owner, 0, &card->snd_card);
1405 if (ret < 0) { 1462 if (ret < 0) {
1406 printk(KERN_ERR "asoc: can't create sound card for card %s\n", 1463 pr_err("asoc: can't create sound card for card %s: %d\n",
1407 card->name); 1464 card->name, ret);
1408 mutex_unlock(&card->mutex); 1465 mutex_unlock(&card->mutex);
1409 return; 1466 return;
1410 } 1467 }
@@ -1457,13 +1514,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1457 } 1514 }
1458 } 1515 }
1459 1516
1460 /* We should have a non-codec control add function but we don't */ 1517 snd_soc_dapm_link_dai_widgets(card);
1518
1461 if (card->controls) 1519 if (card->controls)
1462 snd_soc_add_controls(list_first_entry(&card->codec_dev_list, 1520 snd_soc_add_card_controls(card, card->controls, card->num_controls);
1463 struct snd_soc_codec,
1464 card_list),
1465 card->controls,
1466 card->num_controls);
1467 1521
1468 if (card->dapm_routes) 1522 if (card->dapm_routes)
1469 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1523 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
@@ -1527,7 +1581,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1527 1581
1528 ret = snd_card_register(card->snd_card); 1582 ret = snd_card_register(card->snd_card);
1529 if (ret < 0) { 1583 if (ret < 0) {
1530 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1584 pr_err("asoc: failed to register soundcard for %s: %d\n",
1585 card->name, ret);
1531 goto probe_aux_dev_err; 1586 goto probe_aux_dev_err;
1532 } 1587 }
1533 1588
@@ -1536,7 +1591,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1536 for (i = 0; i < card->num_rtd; i++) { 1591 for (i = 0; i < card->num_rtd; i++) {
1537 ret = soc_register_ac97_dai_link(&card->rtd[i]); 1592 ret = soc_register_ac97_dai_link(&card->rtd[i]);
1538 if (ret < 0) { 1593 if (ret < 0) {
1539 printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); 1594 pr_err("asoc: failed to register AC97 %s: %d\n",
1595 card->name, ret);
1540 while (--i >= 0) 1596 while (--i >= 0)
1541 soc_unregister_ac97_dai_link(card->rtd[i].codec); 1597 soc_unregister_ac97_dai_link(card->rtd[i].codec);
1542 goto probe_aux_dev_err; 1598 goto probe_aux_dev_err;
@@ -1589,6 +1645,10 @@ static int soc_probe(struct platform_device *pdev)
1589 if (!card) 1645 if (!card)
1590 return -EINVAL; 1646 return -EINVAL;
1591 1647
1648 dev_warn(&pdev->dev,
1649 "ASoC machine %s should use snd_soc_register_card()\n",
1650 card->name);
1651
1592 /* Bodge while we unpick instantiation */ 1652 /* Bodge while we unpick instantiation */
1593 card->dev = &pdev->dev; 1653 card->dev = &pdev->dev;
1594 1654
@@ -1665,7 +1725,10 @@ EXPORT_SYMBOL_GPL(snd_soc_poweroff);
1665const struct dev_pm_ops snd_soc_pm_ops = { 1725const struct dev_pm_ops snd_soc_pm_ops = {
1666 .suspend = snd_soc_suspend, 1726 .suspend = snd_soc_suspend,
1667 .resume = snd_soc_resume, 1727 .resume = snd_soc_resume,
1728 .freeze = snd_soc_suspend,
1729 .thaw = snd_soc_resume,
1668 .poweroff = snd_soc_poweroff, 1730 .poweroff = snd_soc_poweroff,
1731 .restore = snd_soc_resume,
1669}; 1732};
1670EXPORT_SYMBOL_GPL(snd_soc_pm_ops); 1733EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
1671 1734
@@ -1981,7 +2044,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
1981 * Returns 0 for success, else error. 2044 * Returns 0 for success, else error.
1982 */ 2045 */
1983struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, 2046struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
1984 void *data, char *long_name, 2047 void *data, const char *long_name,
1985 const char *prefix) 2048 const char *prefix)
1986{ 2049{
1987 struct snd_kcontrol_new template; 2050 struct snd_kcontrol_new template;
@@ -2016,9 +2079,28 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2016} 2079}
2017EXPORT_SYMBOL_GPL(snd_soc_cnew); 2080EXPORT_SYMBOL_GPL(snd_soc_cnew);
2018 2081
2082static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
2083 const struct snd_kcontrol_new *controls, int num_controls,
2084 const char *prefix, void *data)
2085{
2086 int err, i;
2087
2088 for (i = 0; i < num_controls; i++) {
2089 const struct snd_kcontrol_new *control = &controls[i];
2090 err = snd_ctl_add(card, snd_soc_cnew(control, data,
2091 control->name, prefix));
2092 if (err < 0) {
2093 dev_err(dev, "Failed to add %s: %d\n", control->name, err);
2094 return err;
2095 }
2096 }
2097
2098 return 0;
2099}
2100
2019/** 2101/**
2020 * snd_soc_add_controls - add an array of controls to a codec. 2102 * snd_soc_add_codec_controls - add an array of controls to a codec.
2021 * Convienience function to add a list of controls. Many codecs were 2103 * Convenience function to add a list of controls. Many codecs were
2022 * duplicating this code. 2104 * duplicating this code.
2023 * 2105 *
2024 * @codec: codec to add controls to 2106 * @codec: codec to add controls to
@@ -2027,31 +2109,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew);
2027 * 2109 *
2028 * Return 0 for success, else error. 2110 * Return 0 for success, else error.
2029 */ 2111 */
2030int snd_soc_add_controls(struct snd_soc_codec *codec, 2112int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
2031 const struct snd_kcontrol_new *controls, int num_controls) 2113 const struct snd_kcontrol_new *controls, int num_controls)
2032{ 2114{
2033 struct snd_card *card = codec->card->snd_card; 2115 struct snd_card *card = codec->card->snd_card;
2034 int err, i;
2035 2116
2036 for (i = 0; i < num_controls; i++) { 2117 return snd_soc_add_controls(card, codec->dev, controls, num_controls,
2037 const struct snd_kcontrol_new *control = &controls[i]; 2118 codec->name_prefix, codec);
2038 err = snd_ctl_add(card, snd_soc_cnew(control, codec,
2039 control->name,
2040 codec->name_prefix));
2041 if (err < 0) {
2042 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2043 codec->name, control->name, err);
2044 return err;
2045 }
2046 }
2047
2048 return 0;
2049} 2119}
2050EXPORT_SYMBOL_GPL(snd_soc_add_controls); 2120EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
2051 2121
2052/** 2122/**
2053 * snd_soc_add_platform_controls - add an array of controls to a platform. 2123 * snd_soc_add_platform_controls - add an array of controls to a platform.
2054 * Convienience function to add a list of controls. 2124 * Convenience function to add a list of controls.
2055 * 2125 *
2056 * @platform: platform to add controls to 2126 * @platform: platform to add controls to
2057 * @controls: array of controls to add 2127 * @controls: array of controls to add
@@ -2063,23 +2133,53 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
2063 const struct snd_kcontrol_new *controls, int num_controls) 2133 const struct snd_kcontrol_new *controls, int num_controls)
2064{ 2134{
2065 struct snd_card *card = platform->card->snd_card; 2135 struct snd_card *card = platform->card->snd_card;
2066 int err, i;
2067 2136
2068 for (i = 0; i < num_controls; i++) { 2137 return snd_soc_add_controls(card, platform->dev, controls, num_controls,
2069 const struct snd_kcontrol_new *control = &controls[i]; 2138 NULL, platform);
2070 err = snd_ctl_add(card, snd_soc_cnew(control, platform,
2071 control->name, NULL));
2072 if (err < 0) {
2073 dev_err(platform->dev, "Failed to add %s %d\n",control->name, err);
2074 return err;
2075 }
2076 }
2077
2078 return 0;
2079} 2139}
2080EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); 2140EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
2081 2141
2082/** 2142/**
2143 * snd_soc_add_card_controls - add an array of controls to a SoC card.
2144 * Convenience function to add a list of controls.
2145 *
2146 * @soc_card: SoC card to add controls to
2147 * @controls: array of controls to add
2148 * @num_controls: number of elements in the array
2149 *
2150 * Return 0 for success, else error.
2151 */
2152int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
2153 const struct snd_kcontrol_new *controls, int num_controls)
2154{
2155 struct snd_card *card = soc_card->snd_card;
2156
2157 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
2158 NULL, soc_card);
2159}
2160EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
2161
2162/**
2163 * snd_soc_add_dai_controls - add an array of controls to a DAI.
2164 * Convienience function to add a list of controls.
2165 *
2166 * @dai: DAI to add controls to
2167 * @controls: array of controls to add
2168 * @num_controls: number of elements in the array
2169 *
2170 * Return 0 for success, else error.
2171 */
2172int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
2173 const struct snd_kcontrol_new *controls, int num_controls)
2174{
2175 struct snd_card *card = dai->card->snd_card;
2176
2177 return snd_soc_add_controls(card, dai->dev, controls, num_controls,
2178 NULL, dai);
2179}
2180EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
2181
2182/**
2083 * snd_soc_info_enum_double - enumerated double mixer info callback 2183 * snd_soc_info_enum_double - enumerated double mixer info callback
2084 * @kcontrol: mixer control 2184 * @kcontrol: mixer control
2085 * @uinfo: control element information 2185 * @uinfo: control element information
@@ -2645,6 +2745,115 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2645} 2745}
2646EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); 2746EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2647 2747
2748int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2749 struct snd_ctl_elem_info *uinfo)
2750{
2751 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2752 struct soc_bytes *params = (void *)kcontrol->private_value;
2753
2754 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
2755 uinfo->count = params->num_regs * codec->val_bytes;
2756
2757 return 0;
2758}
2759EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
2760
2761int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
2762 struct snd_ctl_elem_value *ucontrol)
2763{
2764 struct soc_bytes *params = (void *)kcontrol->private_value;
2765 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2766 int ret;
2767
2768 if (codec->using_regmap)
2769 ret = regmap_raw_read(codec->control_data, params->base,
2770 ucontrol->value.bytes.data,
2771 params->num_regs * codec->val_bytes);
2772 else
2773 ret = -EINVAL;
2774
2775 /* Hide any masked bytes to ensure consistent data reporting */
2776 if (ret == 0 && params->mask) {
2777 switch (codec->val_bytes) {
2778 case 1:
2779 ucontrol->value.bytes.data[0] &= ~params->mask;
2780 break;
2781 case 2:
2782 ((u16 *)(&ucontrol->value.bytes.data))[0]
2783 &= ~params->mask;
2784 break;
2785 case 4:
2786 ((u32 *)(&ucontrol->value.bytes.data))[0]
2787 &= ~params->mask;
2788 break;
2789 default:
2790 return -EINVAL;
2791 }
2792 }
2793
2794 return ret;
2795}
2796EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
2797
2798int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
2799 struct snd_ctl_elem_value *ucontrol)
2800{
2801 struct soc_bytes *params = (void *)kcontrol->private_value;
2802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2803 int ret, len;
2804 unsigned int val;
2805 void *data;
2806
2807 if (!codec->using_regmap)
2808 return -EINVAL;
2809
2810 data = ucontrol->value.bytes.data;
2811 len = params->num_regs * codec->val_bytes;
2812
2813 /*
2814 * If we've got a mask then we need to preserve the register
2815 * bits. We shouldn't modify the incoming data so take a
2816 * copy.
2817 */
2818 if (params->mask) {
2819 ret = regmap_read(codec->control_data, params->base, &val);
2820 if (ret != 0)
2821 return ret;
2822
2823 val &= params->mask;
2824
2825 data = kmemdup(data, len, GFP_KERNEL);
2826 if (!data)
2827 return -ENOMEM;
2828
2829 switch (codec->val_bytes) {
2830 case 1:
2831 ((u8 *)data)[0] &= ~params->mask;
2832 ((u8 *)data)[0] |= val;
2833 break;
2834 case 2:
2835 ((u16 *)data)[0] &= cpu_to_be16(~params->mask);
2836 ((u16 *)data)[0] |= cpu_to_be16(val);
2837 break;
2838 case 4:
2839 ((u32 *)data)[0] &= cpu_to_be32(~params->mask);
2840 ((u32 *)data)[0] |= cpu_to_be32(val);
2841 break;
2842 default:
2843 return -EINVAL;
2844 }
2845 }
2846
2847 ret = regmap_raw_write(codec->control_data, params->base,
2848 data, len);
2849
2850 if (params->mask)
2851 kfree(data);
2852
2853 return ret;
2854}
2855EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
2856
2648/** 2857/**
2649 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2858 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2650 * @dai: DAI 2859 * @dai: DAI
@@ -2998,7 +3207,7 @@ static inline char *fmt_multiple_name(struct device *dev,
2998 struct snd_soc_dai_driver *dai_drv) 3207 struct snd_soc_dai_driver *dai_drv)
2999{ 3208{
3000 if (dai_drv->name == NULL) { 3209 if (dai_drv->name == NULL) {
3001 printk(KERN_ERR "asoc: error - multiple DAI %s registered with no name\n", 3210 pr_err("asoc: error - multiple DAI %s registered with no name\n",
3002 dev_name(dev)); 3211 dev_name(dev));
3003 return NULL; 3212 return NULL;
3004 } 3213 }
@@ -3281,6 +3490,7 @@ int snd_soc_register_codec(struct device *dev,
3281 codec->volatile_register = codec_drv->volatile_register; 3490 codec->volatile_register = codec_drv->volatile_register;
3282 codec->readable_register = codec_drv->readable_register; 3491 codec->readable_register = codec_drv->readable_register;
3283 codec->writable_register = codec_drv->writable_register; 3492 codec->writable_register = codec_drv->writable_register;
3493 codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time;
3284 codec->dapm.bias_level = SND_SOC_BIAS_OFF; 3494 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3285 codec->dapm.dev = dev; 3495 codec->dapm.dev = dev;
3286 codec->dapm.codec = codec; 3496 codec->dapm.codec = codec;
@@ -3469,8 +3679,7 @@ static int __init snd_soc_init(void)
3469#ifdef CONFIG_DEBUG_FS 3679#ifdef CONFIG_DEBUG_FS
3470 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); 3680 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3471 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { 3681 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3472 printk(KERN_WARNING 3682 pr_warn("ASoC: Failed to create debugfs directory\n");
3473 "ASoC: Failed to create debugfs directory\n");
3474 snd_soc_debugfs_root = NULL; 3683 snd_soc_debugfs_root = NULL;
3475 } 3684 }
3476 3685
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 31a06b2b4442..c9b088dab1cf 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -14,19 +14,13 @@
14 * dynamic configuration of codec internal audio paths and active 14 * dynamic configuration of codec internal audio paths and active
15 * DACs/ADCs. 15 * DACs/ADCs.
16 * o Platform power domain - can support external components i.e. amps and 16 * o Platform power domain - can support external components i.e. amps and
17 * mic/meadphone insertion events. 17 * mic/headphone insertion events.
18 * o Automatic Mic Bias support 18 * o Automatic Mic Bias support
19 * o Jack insertion power event initiation - e.g. hp insertion will enable 19 * o Jack insertion power event initiation - e.g. hp insertion will enable
20 * sinks, dacs, etc 20 * sinks, dacs, etc
21 * o Delayed powerdown of audio susbsystem to reduce pops between a quick 21 * o Delayed power down of audio subsystem to reduce pops between a quick
22 * device reopen. 22 * device reopen.
23 * 23 *
24 * Todo:
25 * o DAPM power change sequencing - allow for configurable per
26 * codec sequences.
27 * o Support for analogue bias optimisation.
28 * o Support for reduced codec oversampling rates.
29 * o Support for reduced codec bias currents.
30 */ 24 */
31 25
32#include <linux/module.h> 26#include <linux/module.h>
@@ -40,6 +34,7 @@
40#include <linux/jiffies.h> 34#include <linux/jiffies.h>
41#include <linux/debugfs.h> 35#include <linux/debugfs.h>
42#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/regulator/consumer.h>
43#include <linux/slab.h> 38#include <linux/slab.h>
44#include <sound/core.h> 39#include <sound/core.h>
45#include <sound/pcm.h> 40#include <sound/pcm.h>
@@ -55,7 +50,9 @@
55static int dapm_up_seq[] = { 50static int dapm_up_seq[] = {
56 [snd_soc_dapm_pre] = 0, 51 [snd_soc_dapm_pre] = 0,
57 [snd_soc_dapm_supply] = 1, 52 [snd_soc_dapm_supply] = 1,
53 [snd_soc_dapm_regulator_supply] = 1,
58 [snd_soc_dapm_micbias] = 2, 54 [snd_soc_dapm_micbias] = 2,
55 [snd_soc_dapm_dai] = 3,
59 [snd_soc_dapm_aif_in] = 3, 56 [snd_soc_dapm_aif_in] = 3,
60 [snd_soc_dapm_aif_out] = 3, 57 [snd_soc_dapm_aif_out] = 3,
61 [snd_soc_dapm_mic] = 4, 58 [snd_soc_dapm_mic] = 4,
@@ -90,6 +87,8 @@ static int dapm_down_seq[] = {
90 [snd_soc_dapm_value_mux] = 9, 87 [snd_soc_dapm_value_mux] = 9,
91 [snd_soc_dapm_aif_in] = 10, 88 [snd_soc_dapm_aif_in] = 10,
92 [snd_soc_dapm_aif_out] = 10, 89 [snd_soc_dapm_aif_out] = 10,
90 [snd_soc_dapm_dai] = 10,
91 [snd_soc_dapm_regulator_supply] = 11,
93 [snd_soc_dapm_supply] = 11, 92 [snd_soc_dapm_supply] = 11,
94 [snd_soc_dapm_post] = 12, 93 [snd_soc_dapm_post] = 12,
95}; 94};
@@ -172,6 +171,19 @@ static inline struct snd_soc_card *dapm_get_soc_card(
172 return NULL; 171 return NULL;
173} 172}
174 173
174static void dapm_reset(struct snd_soc_card *card)
175{
176 struct snd_soc_dapm_widget *w;
177
178 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
179
180 list_for_each_entry(w, &card->widgets, list) {
181 w->power_checked = false;
182 w->inputs = -1;
183 w->outputs = -1;
184 }
185}
186
175static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) 187static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
176{ 188{
177 if (w->codec) 189 if (w->codec)
@@ -352,8 +364,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
352 case snd_soc_dapm_micbias: 364 case snd_soc_dapm_micbias:
353 case snd_soc_dapm_vmid: 365 case snd_soc_dapm_vmid:
354 case snd_soc_dapm_supply: 366 case snd_soc_dapm_supply:
367 case snd_soc_dapm_regulator_supply:
355 case snd_soc_dapm_aif_in: 368 case snd_soc_dapm_aif_in:
356 case snd_soc_dapm_aif_out: 369 case snd_soc_dapm_aif_out:
370 case snd_soc_dapm_dai:
357 case snd_soc_dapm_hp: 371 case snd_soc_dapm_hp:
358 case snd_soc_dapm_mic: 372 case snd_soc_dapm_mic:
359 case snd_soc_dapm_spk: 373 case snd_soc_dapm_spk:
@@ -511,17 +525,17 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
511 * for widgets so cut the prefix off 525 * for widgets so cut the prefix off
512 * the front of the widget name. 526 * the front of the widget name.
513 */ 527 */
514 snprintf(path->long_name, name_len, "%s %s", 528 snprintf((char *)path->long_name, name_len,
515 w->name + prefix_len, 529 "%s %s", w->name + prefix_len,
516 w->kcontrol_news[i].name); 530 w->kcontrol_news[i].name);
517 break; 531 break;
518 case snd_soc_dapm_mixer_named_ctl: 532 case snd_soc_dapm_mixer_named_ctl:
519 snprintf(path->long_name, name_len, "%s", 533 snprintf((char *)path->long_name, name_len,
520 w->kcontrol_news[i].name); 534 "%s", w->kcontrol_news[i].name);
521 break; 535 break;
522 } 536 }
523 537
524 path->long_name[name_len - 1] = '\0'; 538 ((char *)path->long_name)[name_len - 1] = '\0';
525 539
526 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], 540 path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
527 wlist, path->long_name, 541 wlist, path->long_name,
@@ -555,7 +569,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
555 struct snd_soc_dapm_widget_list *wlist; 569 struct snd_soc_dapm_widget_list *wlist;
556 int shared, wlistentries; 570 int shared, wlistentries;
557 size_t wlistsize; 571 size_t wlistsize;
558 char *name; 572 const char *name;
559 573
560 if (w->num_kcontrols != 1) { 574 if (w->num_kcontrols != 1) {
561 dev_err(dapm->dev, 575 dev_err(dapm->dev,
@@ -680,12 +694,18 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
680 694
681 DAPM_UPDATE_STAT(widget, path_checks); 695 DAPM_UPDATE_STAT(widget, path_checks);
682 696
683 if (widget->id == snd_soc_dapm_supply) 697 switch (widget->id) {
698 case snd_soc_dapm_supply:
699 case snd_soc_dapm_regulator_supply:
684 return 0; 700 return 0;
701 default:
702 break;
703 }
685 704
686 switch (widget->id) { 705 switch (widget->id) {
687 case snd_soc_dapm_adc: 706 case snd_soc_dapm_adc:
688 case snd_soc_dapm_aif_out: 707 case snd_soc_dapm_aif_out:
708 case snd_soc_dapm_dai:
689 if (widget->active) { 709 if (widget->active) {
690 widget->outputs = snd_soc_dapm_suspend_check(widget); 710 widget->outputs = snd_soc_dapm_suspend_check(widget);
691 return widget->outputs; 711 return widget->outputs;
@@ -745,13 +765,19 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
745 765
746 DAPM_UPDATE_STAT(widget, path_checks); 766 DAPM_UPDATE_STAT(widget, path_checks);
747 767
748 if (widget->id == snd_soc_dapm_supply) 768 switch (widget->id) {
769 case snd_soc_dapm_supply:
770 case snd_soc_dapm_regulator_supply:
749 return 0; 771 return 0;
772 default:
773 break;
774 }
750 775
751 /* active stream ? */ 776 /* active stream ? */
752 switch (widget->id) { 777 switch (widget->id) {
753 case snd_soc_dapm_dac: 778 case snd_soc_dapm_dac:
754 case snd_soc_dapm_aif_in: 779 case snd_soc_dapm_aif_in:
780 case snd_soc_dapm_dai:
755 if (widget->active) { 781 if (widget->active) {
756 widget->inputs = snd_soc_dapm_suspend_check(widget); 782 widget->inputs = snd_soc_dapm_suspend_check(widget);
757 return widget->inputs; 783 return widget->inputs;
@@ -828,6 +854,19 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
828} 854}
829EXPORT_SYMBOL_GPL(dapm_reg_event); 855EXPORT_SYMBOL_GPL(dapm_reg_event);
830 856
857/*
858 * Handler for regulator supply widget.
859 */
860int dapm_regulator_event(struct snd_soc_dapm_widget *w,
861 struct snd_kcontrol *kcontrol, int event)
862{
863 if (SND_SOC_DAPM_EVENT_ON(event))
864 return regulator_enable(w->priv);
865 else
866 return regulator_disable_deferred(w->priv, w->shift);
867}
868EXPORT_SYMBOL_GPL(dapm_regulator_event);
869
831static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) 870static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
832{ 871{
833 if (w->power_checked) 872 if (w->power_checked)
@@ -858,6 +897,13 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
858 return out != 0 && in != 0; 897 return out != 0 && in != 0;
859} 898}
860 899
900static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
901{
902 DAPM_UPDATE_STAT(w, power_checks);
903
904 return w->active;
905}
906
861/* Check to see if an ADC has power */ 907/* Check to see if an ADC has power */
862static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) 908static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
863{ 909{
@@ -1258,7 +1304,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1258 dev_err(d->dev, "Failed to turn off bias: %d\n", ret); 1304 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1259 1305
1260 if (d->dev) 1306 if (d->dev)
1261 pm_runtime_put_sync(d->dev); 1307 pm_runtime_put(d->dev);
1262 } 1308 }
1263 1309
1264 /* If we just powered up then move to active bias */ 1310 /* If we just powered up then move to active bias */
@@ -1308,6 +1354,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1308 } 1354 }
1309 switch (w->id) { 1355 switch (w->id) {
1310 case snd_soc_dapm_supply: 1356 case snd_soc_dapm_supply:
1357 case snd_soc_dapm_regulator_supply:
1311 /* Supplies can't affect their outputs, only their inputs */ 1358 /* Supplies can't affect their outputs, only their inputs */
1312 break; 1359 break;
1313 default: 1360 default:
@@ -1380,13 +1427,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1380 } 1427 }
1381 } 1428 }
1382 1429
1383 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 1430 dapm_reset(card);
1384
1385 list_for_each_entry(w, &card->widgets, list) {
1386 w->power_checked = false;
1387 w->inputs = -1;
1388 w->outputs = -1;
1389 }
1390 1431
1391 /* Check which widgets we need to power and store them in 1432 /* Check which widgets we need to power and store them in
1392 * lists indicating if they should be powered up or down. We 1433 * lists indicating if they should be powered up or down. We
@@ -1407,10 +1448,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1407 /* Supplies and micbiases only bring the 1448 /* Supplies and micbiases only bring the
1408 * context up to STANDBY as unless something 1449 * context up to STANDBY as unless something
1409 * else is active and passing audio they 1450 * else is active and passing audio they
1410 * generally don't require full power. 1451 * generally don't require full power. Signal
1452 * generators are virtual pins and have no
1453 * power impact themselves.
1411 */ 1454 */
1412 switch (w->id) { 1455 switch (w->id) {
1456 case snd_soc_dapm_siggen:
1457 break;
1413 case snd_soc_dapm_supply: 1458 case snd_soc_dapm_supply:
1459 case snd_soc_dapm_regulator_supply:
1414 case snd_soc_dapm_micbias: 1460 case snd_soc_dapm_micbias:
1415 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1461 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1416 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1462 d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1482,6 +1528,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1482 &async_domain); 1528 &async_domain);
1483 async_synchronize_full_domain(&async_domain); 1529 async_synchronize_full_domain(&async_domain);
1484 1530
1531 /* do we need to notify any clients that DAPM event is complete */
1532 list_for_each_entry(d, &card->dapm_list, list) {
1533 if (d->stream_event)
1534 d->stream_event(d, event);
1535 }
1536
1485 pop_dbg(dapm->dev, card->pop_time, 1537 pop_dbg(dapm->dev, card->pop_time,
1486 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1538 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
1487 pop_wait(card->pop_time); 1539 pop_wait(card->pop_time);
@@ -1666,9 +1718,8 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1666#endif 1718#endif
1667 1719
1668/* test and update the power status of a mux widget */ 1720/* test and update the power status of a mux widget */
1669static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1721int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1670 struct snd_kcontrol *kcontrol, int change, 1722 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1671 int mux, struct soc_enum *e)
1672{ 1723{
1673 struct snd_soc_dapm_path *path; 1724 struct snd_soc_dapm_path *path;
1674 int found = 0; 1725 int found = 0;
@@ -1678,9 +1729,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1678 widget->id != snd_soc_dapm_value_mux) 1729 widget->id != snd_soc_dapm_value_mux)
1679 return -ENODEV; 1730 return -ENODEV;
1680 1731
1681 if (!change)
1682 return 0;
1683
1684 /* find dapm widget path assoc with kcontrol */ 1732 /* find dapm widget path assoc with kcontrol */
1685 list_for_each_entry(path, &widget->dapm->card->paths, list) { 1733 list_for_each_entry(path, &widget->dapm->card->paths, list) {
1686 if (path->kcontrol != kcontrol) 1734 if (path->kcontrol != kcontrol)
@@ -1709,9 +1757,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1709 1757
1710 return 0; 1758 return 0;
1711} 1759}
1760EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
1712 1761
1713/* test and update the power status of a mixer or switch widget */ 1762/* test and update the power status of a mixer or switch widget */
1714static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1763int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1715 struct snd_kcontrol *kcontrol, int connect) 1764 struct snd_kcontrol *kcontrol, int connect)
1716{ 1765{
1717 struct snd_soc_dapm_path *path; 1766 struct snd_soc_dapm_path *path;
@@ -1740,6 +1789,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1740 1789
1741 return 0; 1790 return 0;
1742} 1791}
1792EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
1743 1793
1744/* show dapm widget status in sys fs */ 1794/* show dapm widget status in sys fs */
1745static ssize_t dapm_widget_show(struct device *dev, 1795static ssize_t dapm_widget_show(struct device *dev,
@@ -1769,6 +1819,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1769 case snd_soc_dapm_mixer: 1819 case snd_soc_dapm_mixer:
1770 case snd_soc_dapm_mixer_named_ctl: 1820 case snd_soc_dapm_mixer_named_ctl:
1771 case snd_soc_dapm_supply: 1821 case snd_soc_dapm_supply:
1822 case snd_soc_dapm_regulator_supply:
1772 if (w->name) 1823 if (w->name)
1773 count += sprintf(buf + count, "%s: %s\n", 1824 count += sprintf(buf + count, "%s: %s\n",
1774 w->name, w->power ? "On":"Off"); 1825 w->name, w->power ? "On":"Off");
@@ -1876,10 +1927,12 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1876 return -EINVAL; 1927 return -EINVAL;
1877 } 1928 }
1878 1929
1930 if (w->connected != status)
1931 dapm_mark_dirty(w, "pin configuration");
1932
1879 w->connected = status; 1933 w->connected = status;
1880 if (status == 0) 1934 if (status == 0)
1881 w->force = 0; 1935 w->force = 0;
1882 dapm_mark_dirty(w, "pin configuration");
1883 1936
1884 return 0; 1937 return 0;
1885} 1938}
@@ -2007,8 +2060,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2007 case snd_soc_dapm_pre: 2060 case snd_soc_dapm_pre:
2008 case snd_soc_dapm_post: 2061 case snd_soc_dapm_post:
2009 case snd_soc_dapm_supply: 2062 case snd_soc_dapm_supply:
2063 case snd_soc_dapm_regulator_supply:
2010 case snd_soc_dapm_aif_in: 2064 case snd_soc_dapm_aif_in:
2011 case snd_soc_dapm_aif_out: 2065 case snd_soc_dapm_aif_out:
2066 case snd_soc_dapm_dai:
2012 list_add(&path->list, &dapm->card->paths); 2067 list_add(&path->list, &dapm->card->paths);
2013 list_add(&path->list_sink, &wsink->sources); 2068 list_add(&path->list_sink, &wsink->sources);
2014 list_add(&path->list_source, &wsource->sinks); 2069 list_add(&path->list_source, &wsource->sinks);
@@ -2322,7 +2377,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2322 update.val = val; 2377 update.val = val;
2323 widget->dapm->update = &update; 2378 widget->dapm->update = &update;
2324 2379
2325 dapm_mixer_update_power(widget, kcontrol, connect); 2380 snd_soc_dapm_mixer_update_power(widget, kcontrol, connect);
2326 2381
2327 widget->dapm->update = NULL; 2382 widget->dapm->update = NULL;
2328 } 2383 }
@@ -2413,7 +2468,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2413 update.val = val; 2468 update.val = val;
2414 widget->dapm->update = &update; 2469 widget->dapm->update = &update;
2415 2470
2416 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2471 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2417 2472
2418 widget->dapm->update = NULL; 2473 widget->dapm->update = NULL;
2419 } 2474 }
@@ -2474,8 +2529,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2474 2529
2475 widget->value = ucontrol->value.enumerated.item[0]; 2530 widget->value = ucontrol->value.enumerated.item[0];
2476 2531
2477 dapm_mux_update_power(widget, kcontrol, change, 2532 snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
2478 widget->value, e);
2479 } 2533 }
2480 } 2534 }
2481 2535
@@ -2578,7 +2632,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2578 update.val = val; 2632 update.val = val;
2579 widget->dapm->update = &update; 2633 widget->dapm->update = &update;
2580 2634
2581 dapm_mux_update_power(widget, kcontrol, change, mux, e); 2635 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2582 2636
2583 widget->dapm->update = NULL; 2637 widget->dapm->update = NULL;
2584 } 2638 }
@@ -2618,15 +2672,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
2618int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 2672int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2619 struct snd_ctl_elem_value *ucontrol) 2673 struct snd_ctl_elem_value *ucontrol)
2620{ 2674{
2621 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2675 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2622 const char *pin = (const char *)kcontrol->private_value; 2676 const char *pin = (const char *)kcontrol->private_value;
2623 2677
2624 mutex_lock(&codec->mutex); 2678 mutex_lock(&card->mutex);
2625 2679
2626 ucontrol->value.integer.value[0] = 2680 ucontrol->value.integer.value[0] =
2627 snd_soc_dapm_get_pin_status(&codec->dapm, pin); 2681 snd_soc_dapm_get_pin_status(&card->dapm, pin);
2628 2682
2629 mutex_unlock(&codec->mutex); 2683 mutex_unlock(&card->mutex);
2630 2684
2631 return 0; 2685 return 0;
2632} 2686}
@@ -2641,41 +2695,48 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
2641int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 2695int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2642 struct snd_ctl_elem_value *ucontrol) 2696 struct snd_ctl_elem_value *ucontrol)
2643{ 2697{
2644 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2698 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2645 const char *pin = (const char *)kcontrol->private_value; 2699 const char *pin = (const char *)kcontrol->private_value;
2646 2700
2647 mutex_lock(&codec->mutex); 2701 mutex_lock(&card->mutex);
2648 2702
2649 if (ucontrol->value.integer.value[0]) 2703 if (ucontrol->value.integer.value[0])
2650 snd_soc_dapm_enable_pin(&codec->dapm, pin); 2704 snd_soc_dapm_enable_pin(&card->dapm, pin);
2651 else 2705 else
2652 snd_soc_dapm_disable_pin(&codec->dapm, pin); 2706 snd_soc_dapm_disable_pin(&card->dapm, pin);
2653 2707
2654 snd_soc_dapm_sync(&codec->dapm); 2708 snd_soc_dapm_sync(&card->dapm);
2655 2709
2656 mutex_unlock(&codec->mutex); 2710 mutex_unlock(&card->mutex);
2657 2711
2658 return 0; 2712 return 0;
2659} 2713}
2660EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 2714EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
2661 2715
2662/** 2716static struct snd_soc_dapm_widget *
2663 * snd_soc_dapm_new_control - create new dapm control 2717snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2664 * @dapm: DAPM context 2718 const struct snd_soc_dapm_widget *widget)
2665 * @widget: widget template
2666 *
2667 * Creates a new dapm control based upon the template.
2668 *
2669 * Returns 0 for success else error.
2670 */
2671int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2672 const struct snd_soc_dapm_widget *widget)
2673{ 2719{
2674 struct snd_soc_dapm_widget *w; 2720 struct snd_soc_dapm_widget *w;
2675 size_t name_len; 2721 size_t name_len;
2722 int ret;
2676 2723
2677 if ((w = dapm_cnew_widget(widget)) == NULL) 2724 if ((w = dapm_cnew_widget(widget)) == NULL)
2678 return -ENOMEM; 2725 return NULL;
2726
2727 switch (w->id) {
2728 case snd_soc_dapm_regulator_supply:
2729 w->priv = devm_regulator_get(dapm->dev, w->name);
2730 if (IS_ERR(w->priv)) {
2731 ret = PTR_ERR(w->priv);
2732 dev_err(dapm->dev, "Failed to request %s: %d\n",
2733 w->name, ret);
2734 return NULL;
2735 }
2736 break;
2737 default:
2738 break;
2739 }
2679 2740
2680 name_len = strlen(widget->name) + 1; 2741 name_len = strlen(widget->name) + 1;
2681 if (dapm->codec && dapm->codec->name_prefix) 2742 if (dapm->codec && dapm->codec->name_prefix)
@@ -2683,13 +2744,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2683 w->name = kmalloc(name_len, GFP_KERNEL); 2744 w->name = kmalloc(name_len, GFP_KERNEL);
2684 if (w->name == NULL) { 2745 if (w->name == NULL) {
2685 kfree(w); 2746 kfree(w);
2686 return -ENOMEM; 2747 return NULL;
2687 } 2748 }
2688 if (dapm->codec && dapm->codec->name_prefix) 2749 if (dapm->codec && dapm->codec->name_prefix)
2689 snprintf(w->name, name_len, "%s %s", 2750 snprintf((char *)w->name, name_len, "%s %s",
2690 dapm->codec->name_prefix, widget->name); 2751 dapm->codec->name_prefix, widget->name);
2691 else 2752 else
2692 snprintf(w->name, name_len, "%s", widget->name); 2753 snprintf((char *)w->name, name_len, "%s", widget->name);
2693 2754
2694 switch (w->id) { 2755 switch (w->id) {
2695 case snd_soc_dapm_switch: 2756 case snd_soc_dapm_switch:
@@ -2722,8 +2783,12 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2722 w->power_check = dapm_generic_check_power; 2783 w->power_check = dapm_generic_check_power;
2723 break; 2784 break;
2724 case snd_soc_dapm_supply: 2785 case snd_soc_dapm_supply:
2786 case snd_soc_dapm_regulator_supply:
2725 w->power_check = dapm_supply_check_power; 2787 w->power_check = dapm_supply_check_power;
2726 break; 2788 break;
2789 case snd_soc_dapm_dai:
2790 w->power_check = dapm_dai_check_power;
2791 break;
2727 default: 2792 default:
2728 w->power_check = dapm_always_on_check_power; 2793 w->power_check = dapm_always_on_check_power;
2729 break; 2794 break;
@@ -2741,9 +2806,8 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2741 2806
2742 /* machine layer set ups unconnected pins and insertions */ 2807 /* machine layer set ups unconnected pins and insertions */
2743 w->connected = 1; 2808 w->connected = 1;
2744 return 0; 2809 return w;
2745} 2810}
2746EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
2747 2811
2748/** 2812/**
2749 * snd_soc_dapm_new_controls - create new dapm controls 2813 * snd_soc_dapm_new_controls - create new dapm controls
@@ -2759,15 +2823,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2759 const struct snd_soc_dapm_widget *widget, 2823 const struct snd_soc_dapm_widget *widget,
2760 int num) 2824 int num)
2761{ 2825{
2762 int i, ret; 2826 struct snd_soc_dapm_widget *w;
2827 int i;
2763 2828
2764 for (i = 0; i < num; i++) { 2829 for (i = 0; i < num; i++) {
2765 ret = snd_soc_dapm_new_control(dapm, widget); 2830 w = snd_soc_dapm_new_control(dapm, widget);
2766 if (ret < 0) { 2831 if (!w) {
2767 dev_err(dapm->dev, 2832 dev_err(dapm->dev,
2768 "ASoC: Failed to create DAPM control %s: %d\n", 2833 "ASoC: Failed to create DAPM control %s\n",
2769 widget->name, ret); 2834 widget->name);
2770 return ret; 2835 return -ENOMEM;
2771 } 2836 }
2772 widget++; 2837 widget++;
2773 } 2838 }
@@ -2775,40 +2840,140 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2775} 2840}
2776EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2841EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
2777 2842
2778static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, 2843int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
2779 const char *stream, int event) 2844 struct snd_soc_dai *dai)
2780{ 2845{
2846 struct snd_soc_dapm_widget template;
2781 struct snd_soc_dapm_widget *w; 2847 struct snd_soc_dapm_widget *w;
2782 2848
2783 list_for_each_entry(w, &dapm->card->widgets, list) 2849 WARN_ON(dapm->dev != dai->dev);
2784 { 2850
2785 if (!w->sname || w->dapm != dapm) 2851 memset(&template, 0, sizeof(template));
2852 template.reg = SND_SOC_NOPM;
2853
2854 if (dai->driver->playback.stream_name) {
2855 template.id = snd_soc_dapm_dai;
2856 template.name = dai->driver->playback.stream_name;
2857 template.sname = dai->driver->playback.stream_name;
2858
2859 dev_dbg(dai->dev, "adding %s widget\n",
2860 template.name);
2861
2862 w = snd_soc_dapm_new_control(dapm, &template);
2863 if (!w) {
2864 dev_err(dapm->dev, "Failed to create %s widget\n",
2865 dai->driver->playback.stream_name);
2866 }
2867
2868 w->priv = dai;
2869 dai->playback_widget = w;
2870 }
2871
2872 if (dai->driver->capture.stream_name) {
2873 template.id = snd_soc_dapm_dai;
2874 template.name = dai->driver->capture.stream_name;
2875 template.sname = dai->driver->capture.stream_name;
2876
2877 dev_dbg(dai->dev, "adding %s widget\n",
2878 template.name);
2879
2880 w = snd_soc_dapm_new_control(dapm, &template);
2881 if (!w) {
2882 dev_err(dapm->dev, "Failed to create %s widget\n",
2883 dai->driver->capture.stream_name);
2884 }
2885
2886 w->priv = dai;
2887 dai->capture_widget = w;
2888 }
2889
2890 return 0;
2891}
2892
2893int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
2894{
2895 struct snd_soc_dapm_widget *dai_w, *w;
2896 struct snd_soc_dai *dai;
2897 struct snd_soc_dapm_route r;
2898
2899 memset(&r, 0, sizeof(r));
2900
2901 /* For each DAI widget... */
2902 list_for_each_entry(dai_w, &card->widgets, list) {
2903 if (dai_w->id != snd_soc_dapm_dai)
2786 continue; 2904 continue;
2787 dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", 2905
2788 w->name, w->sname, stream, event); 2906 dai = dai_w->priv;
2789 if (strstr(w->sname, stream)) { 2907
2790 dapm_mark_dirty(w, "stream event"); 2908 /* ...find all widgets with the same stream and link them */
2791 switch(event) { 2909 list_for_each_entry(w, &card->widgets, list) {
2792 case SND_SOC_DAPM_STREAM_START: 2910 if (w->dapm != dai_w->dapm)
2793 w->active = 1; 2911 continue;
2794 break; 2912
2795 case SND_SOC_DAPM_STREAM_STOP: 2913 if (w->id == snd_soc_dapm_dai)
2796 w->active = 0; 2914 continue;
2797 break; 2915
2798 case SND_SOC_DAPM_STREAM_SUSPEND: 2916 if (!w->sname)
2799 case SND_SOC_DAPM_STREAM_RESUME: 2917 continue;
2800 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2918
2801 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2919 if (dai->driver->playback.stream_name &&
2802 break; 2920 strstr(w->sname,
2921 dai->driver->playback.stream_name)) {
2922 r.source = dai->playback_widget->name;
2923 r.sink = w->name;
2924 dev_dbg(dai->dev, "%s -> %s\n",
2925 r.source, r.sink);
2926
2927 snd_soc_dapm_add_route(w->dapm, &r);
2928 }
2929
2930 if (dai->driver->capture.stream_name &&
2931 strstr(w->sname,
2932 dai->driver->capture.stream_name)) {
2933 r.source = w->name;
2934 r.sink = dai->capture_widget->name;
2935 dev_dbg(dai->dev, "%s -> %s\n",
2936 r.source, r.sink);
2937
2938 snd_soc_dapm_add_route(w->dapm, &r);
2803 } 2939 }
2804 } 2940 }
2805 } 2941 }
2806 2942
2807 dapm_power_widgets(dapm, event); 2943 return 0;
2944}
2945
2946static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2947 int stream, struct snd_soc_dai *dai,
2948 int event)
2949{
2950 struct snd_soc_dapm_widget *w;
2951
2952 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2953 w = dai->playback_widget;
2954 else
2955 w = dai->capture_widget;
2808 2956
2809 /* do we need to notify any clients that DAPM stream is complete */ 2957 if (!w)
2810 if (dapm->stream_event) 2958 return;
2811 dapm->stream_event(dapm, event); 2959
2960 dapm_mark_dirty(w, "stream event");
2961
2962 switch (event) {
2963 case SND_SOC_DAPM_STREAM_START:
2964 w->active = 1;
2965 break;
2966 case SND_SOC_DAPM_STREAM_STOP:
2967 w->active = 0;
2968 break;
2969 case SND_SOC_DAPM_STREAM_SUSPEND:
2970 case SND_SOC_DAPM_STREAM_RESUME:
2971 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2972 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2973 break;
2974 }
2975
2976 dapm_power_widgets(dapm, event);
2812} 2977}
2813 2978
2814/** 2979/**
@@ -2822,16 +2987,13 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2822 * 2987 *
2823 * Returns 0 for success else error. 2988 * Returns 0 for success else error.
2824 */ 2989 */
2825int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, 2990int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2826 const char *stream, int event) 2991 struct snd_soc_dai *dai, int event)
2827{ 2992{
2828 struct snd_soc_codec *codec = rtd->codec; 2993 struct snd_soc_codec *codec = rtd->codec;
2829 2994
2830 if (stream == NULL)
2831 return 0;
2832
2833 mutex_lock(&codec->mutex); 2995 mutex_lock(&codec->mutex);
2834 soc_dapm_stream_event(&codec->dapm, stream, event); 2996 soc_dapm_stream_event(&codec->dapm, stream, dai, event);
2835 mutex_unlock(&codec->mutex); 2997 mutex_unlock(&codec->mutex);
2836 return 0; 2998 return 0;
2837} 2999}
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
new file mode 100644
index 000000000000..0526cf82b54f
--- /dev/null
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -0,0 +1,287 @@
1/*
2 * Copyright (C) 2012, Analog Devices Inc.
3 * Author: Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * Based on:
6 * imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
7 * mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc.
8 * ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
9 * Copyright (C) 2006 Applied Data Systems
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 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/dmaengine.h>
24#include <linux/slab.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <sound/dmaengine_pcm.h>
30
31struct dmaengine_pcm_runtime_data {
32 struct dma_chan *dma_chan;
33
34 unsigned int pos;
35
36 void *data;
37};
38
39static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
40 const struct snd_pcm_substream *substream)
41{
42 return substream->runtime->private_data;
43}
44
45/**
46 * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
47 * @substream: PCM substream
48 * @data: Data to set
49 */
50void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
51{
52 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
53
54 prtd->data = data;
55}
56EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
57
58/**
59 * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
60 * @substream: PCM substream
61 *
62 * Returns the data previously set with snd_dmaengine_pcm_set_data
63 */
64void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
65{
66 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
67
68 return prtd->data;
69}
70EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
71
72struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
73{
74 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
75
76 return prtd->dma_chan;
77}
78EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_chan);
79
80/**
81 * snd_hwparams_to_dma_slave_config - Convert hw_params to dma_slave_config
82 * @substream: PCM substream
83 * @params: hw_params
84 * @slave_config: DMA slave config
85 *
86 * This function can be used to initialize a dma_slave_config from a substream
87 * and hw_params in a dmaengine based PCM driver implementation.
88 */
89int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
90 const struct snd_pcm_hw_params *params,
91 struct dma_slave_config *slave_config)
92{
93 enum dma_slave_buswidth buswidth;
94
95 switch (params_format(params)) {
96 case SNDRV_PCM_FORMAT_S8:
97 buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
98 break;
99 case SNDRV_PCM_FORMAT_S16_LE:
100 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
101 break;
102 case SNDRV_PCM_FORMAT_S18_3LE:
103 case SNDRV_PCM_FORMAT_S20_3LE:
104 case SNDRV_PCM_FORMAT_S24_LE:
105 case SNDRV_PCM_FORMAT_S32_LE:
106 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
107 break;
108 default:
109 return -EINVAL;
110 }
111
112 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
113 slave_config->direction = DMA_MEM_TO_DEV;
114 slave_config->dst_addr_width = buswidth;
115 } else {
116 slave_config->direction = DMA_DEV_TO_MEM;
117 slave_config->src_addr_width = buswidth;
118 }
119
120 return 0;
121}
122EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
123
124static void dmaengine_pcm_dma_complete(void *arg)
125{
126 struct snd_pcm_substream *substream = arg;
127 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
128
129 prtd->pos += snd_pcm_lib_period_bytes(substream);
130 if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
131 prtd->pos = 0;
132
133 snd_pcm_period_elapsed(substream);
134}
135
136static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
137{
138 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
139 struct dma_chan *chan = prtd->dma_chan;
140 struct dma_async_tx_descriptor *desc;
141 enum dma_transfer_direction direction;
142
143 direction = snd_pcm_substream_to_dma_direction(substream);
144
145 desc = chan->device->device_prep_dma_cyclic(chan,
146 substream->runtime->dma_addr,
147 snd_pcm_lib_buffer_bytes(substream),
148 snd_pcm_lib_period_bytes(substream), direction);
149
150 if (!desc)
151 return -ENOMEM;
152
153 desc->callback = dmaengine_pcm_dma_complete;
154 desc->callback_param = substream;
155 dmaengine_submit(desc);
156
157 return 0;
158}
159
160/**
161 * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation
162 * @substream: PCM substream
163 * @cmd: Trigger command
164 *
165 * Returns 0 on success, a negative error code otherwise.
166 *
167 * This function can be used as the PCM trigger callback for dmaengine based PCM
168 * driver implementations.
169 */
170int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
171{
172 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
173 int ret;
174
175 switch (cmd) {
176 case SNDRV_PCM_TRIGGER_START:
177 ret = dmaengine_pcm_prepare_and_submit(substream);
178 if (ret)
179 return ret;
180 dma_async_issue_pending(prtd->dma_chan);
181 break;
182 case SNDRV_PCM_TRIGGER_RESUME:
183 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
184 dmaengine_resume(prtd->dma_chan);
185 break;
186 case SNDRV_PCM_TRIGGER_SUSPEND:
187 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
188 dmaengine_pause(prtd->dma_chan);
189 break;
190 case SNDRV_PCM_TRIGGER_STOP:
191 dmaengine_terminate_all(prtd->dma_chan);
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 return 0;
198}
199EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
200
201/**
202 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
203 * @substream: PCM substream
204 *
205 * This function can be used as the PCM pointer callback for dmaengine based PCM
206 * driver implementations.
207 */
208snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
209{
210 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
211 return bytes_to_frames(substream->runtime, prtd->pos);
212}
213EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
214
215static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd,
216 dma_filter_fn filter_fn, void *filter_data)
217{
218 dma_cap_mask_t mask;
219
220 dma_cap_zero(mask);
221 dma_cap_set(DMA_SLAVE, mask);
222 dma_cap_set(DMA_CYCLIC, mask);
223 prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data);
224
225 if (!prtd->dma_chan)
226 return -ENXIO;
227
228 return 0;
229}
230
231/**
232 * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream
233 * @substream: PCM substream
234 * @filter_fn: Filter function used to request the DMA channel
235 * @filter_data: Data passed to the DMA filter function
236 *
237 * Returns 0 on success, a negative error code otherwise.
238 *
239 * This function will request a DMA channel using the passed filter function and
240 * data. The function should usually be called from the pcm open callback.
241 *
242 * Note that this function will use private_data field of the substream's
243 * runtime. So it is not availabe to your pcm driver implementation. If you need
244 * to keep additional data attached to a substream use
245 * snd_dmaeinge_pcm_{set,get}_data.
246 */
247int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
248 dma_filter_fn filter_fn, void *filter_data)
249{
250 struct dmaengine_pcm_runtime_data *prtd;
251 int ret;
252
253 ret = snd_pcm_hw_constraint_integer(substream->runtime,
254 SNDRV_PCM_HW_PARAM_PERIODS);
255 if (ret < 0)
256 return ret;
257
258 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
259 if (!prtd)
260 return -ENOMEM;
261
262 ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data);
263 if (ret < 0) {
264 kfree(prtd);
265 return ret;
266 }
267
268 substream->runtime->private_data = prtd;
269
270 return 0;
271}
272EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open);
273
274/**
275 * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream
276 * @substream: PCM substream
277 */
278int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
279{
280 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
281
282 dma_release_channel(prtd->dma_chan);
283 kfree(prtd);
284
285 return 0;
286}
287EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 39ba5070ff92..4d8dc6a27d4d 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -114,6 +114,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
114 enum snd_soc_control_type control) 114 enum snd_soc_control_type control)
115{ 115{
116 struct regmap_config config; 116 struct regmap_config config;
117 int ret;
117 118
118 memset(&config, 0, sizeof(config)); 119 memset(&config, 0, sizeof(config));
119 codec->write = hw_write; 120 codec->write = hw_write;
@@ -141,6 +142,11 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
141 case SND_SOC_REGMAP: 142 case SND_SOC_REGMAP:
142 /* Device has made its own regmap arrangements */ 143 /* Device has made its own regmap arrangements */
143 codec->using_regmap = true; 144 codec->using_regmap = true;
145
146 ret = regmap_get_val_bytes(codec->control_data);
147 /* Errors are legitimate for non-integer byte multiples */
148 if (ret > 0)
149 codec->val_bytes = ret;
144 break; 150 break;
145 151
146 default: 152 default:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 326890148a26..0ad8dcacd2f3 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -68,7 +68,7 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
68 * like the DAC/ADC resolution to use but there isn't right now. 68 * like the DAC/ADC resolution to use but there isn't right now.
69 */ 69 */
70static int sample_sizes[] = { 70static int sample_sizes[] = {
71 8, 16, 24, 32, 71 24, 32,
72}; 72};
73 73
74static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, 74static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
@@ -123,8 +123,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
123 if (cpu_dai->driver->ops->startup) { 123 if (cpu_dai->driver->ops->startup) {
124 ret = cpu_dai->driver->ops->startup(substream, cpu_dai); 124 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
125 if (ret < 0) { 125 if (ret < 0) {
126 printk(KERN_ERR "asoc: can't open interface %s\n", 126 dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
127 cpu_dai->name); 127 cpu_dai->name, ret);
128 goto out; 128 goto out;
129 } 129 }
130 } 130 }
@@ -132,7 +132,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
132 if (platform->driver->ops && platform->driver->ops->open) { 132 if (platform->driver->ops && platform->driver->ops->open) {
133 ret = platform->driver->ops->open(substream); 133 ret = platform->driver->ops->open(substream);
134 if (ret < 0) { 134 if (ret < 0) {
135 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); 135 dev_err(platform->dev, "can't open platform %s: %d\n",
136 platform->name, ret);
136 goto platform_err; 137 goto platform_err;
137 } 138 }
138 } 139 }
@@ -140,8 +141,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
140 if (codec_dai->driver->ops->startup) { 141 if (codec_dai->driver->ops->startup) {
141 ret = codec_dai->driver->ops->startup(substream, codec_dai); 142 ret = codec_dai->driver->ops->startup(substream, codec_dai);
142 if (ret < 0) { 143 if (ret < 0) {
143 printk(KERN_ERR "asoc: can't open codec %s\n", 144 dev_err(codec_dai->dev, "can't open codec %s: %d\n",
144 codec_dai->name); 145 codec_dai->name, ret);
145 goto codec_dai_err; 146 goto codec_dai_err;
146 } 147 }
147 } 148 }
@@ -149,7 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
149 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { 150 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
150 ret = rtd->dai_link->ops->startup(substream); 151 ret = rtd->dai_link->ops->startup(substream);
151 if (ret < 0) { 152 if (ret < 0) {
152 printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name); 153 pr_err("asoc: %s startup failed: %d\n",
154 rtd->dai_link->name, ret);
153 goto machine_err; 155 goto machine_err;
154 } 156 }
155 } 157 }
@@ -305,9 +307,8 @@ static void close_delayed_work(struct work_struct *work)
305 /* are we waiting on this codec DAI stream */ 307 /* are we waiting on this codec DAI stream */
306 if (codec_dai->pop_wait == 1) { 308 if (codec_dai->pop_wait == 1) {
307 codec_dai->pop_wait = 0; 309 codec_dai->pop_wait = 0;
308 snd_soc_dapm_stream_event(rtd, 310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
309 codec_dai->driver->playback.stream_name, 311 codec_dai, SND_SOC_DAPM_STREAM_STOP);
310 SND_SOC_DAPM_STREAM_STOP);
311 } 312 }
312 313
313 mutex_unlock(&rtd->pcm_mutex); 314 mutex_unlock(&rtd->pcm_mutex);
@@ -367,12 +368,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
367 cpu_dai->runtime = NULL; 368 cpu_dai->runtime = NULL;
368 369
369 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
370 if (codec->ignore_pmdown_time || 371 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
371 rtd->dai_link->ignore_pmdown_time) { 372 rtd->dai_link->ignore_pmdown_time) {
372 /* powered down playback stream now */ 373 /* powered down playback stream now */
373 snd_soc_dapm_stream_event(rtd, 374 snd_soc_dapm_stream_event(rtd,
374 codec_dai->driver->playback.stream_name, 375 SNDRV_PCM_STREAM_PLAYBACK,
375 SND_SOC_DAPM_STREAM_STOP); 376 codec_dai,
377 SND_SOC_DAPM_STREAM_STOP);
376 } else { 378 } else {
377 /* start delayed pop wq here for playback streams */ 379 /* start delayed pop wq here for playback streams */
378 codec_dai->pop_wait = 1; 380 codec_dai->pop_wait = 1;
@@ -381,9 +383,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
381 } 383 }
382 } else { 384 } else {
383 /* capture streams can be powered down now */ 385 /* capture streams can be powered down now */
384 snd_soc_dapm_stream_event(rtd, 386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
385 codec_dai->driver->capture.stream_name, 387 codec_dai, SND_SOC_DAPM_STREAM_STOP);
386 SND_SOC_DAPM_STREAM_STOP);
387 } 388 }
388 389
389 mutex_unlock(&rtd->pcm_mutex); 390 mutex_unlock(&rtd->pcm_mutex);
@@ -413,7 +414,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
413 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { 414 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
414 ret = rtd->dai_link->ops->prepare(substream); 415 ret = rtd->dai_link->ops->prepare(substream);
415 if (ret < 0) { 416 if (ret < 0) {
416 printk(KERN_ERR "asoc: machine prepare error\n"); 417 pr_err("asoc: machine prepare error: %d\n", ret);
417 goto out; 418 goto out;
418 } 419 }
419 } 420 }
@@ -421,7 +422,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
421 if (platform->driver->ops && platform->driver->ops->prepare) { 422 if (platform->driver->ops && platform->driver->ops->prepare) {
422 ret = platform->driver->ops->prepare(substream); 423 ret = platform->driver->ops->prepare(substream);
423 if (ret < 0) { 424 if (ret < 0) {
424 printk(KERN_ERR "asoc: platform prepare error\n"); 425 dev_err(platform->dev, "platform prepare error: %d\n",
426 ret);
425 goto out; 427 goto out;
426 } 428 }
427 } 429 }
@@ -429,7 +431,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
429 if (codec_dai->driver->ops->prepare) { 431 if (codec_dai->driver->ops->prepare) {
430 ret = codec_dai->driver->ops->prepare(substream, codec_dai); 432 ret = codec_dai->driver->ops->prepare(substream, codec_dai);
431 if (ret < 0) { 433 if (ret < 0) {
432 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 434 dev_err(codec_dai->dev, "DAI prepare error: %d\n",
435 ret);
433 goto out; 436 goto out;
434 } 437 }
435 } 438 }
@@ -437,7 +440,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
437 if (cpu_dai->driver->ops->prepare) { 440 if (cpu_dai->driver->ops->prepare) {
438 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); 441 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
439 if (ret < 0) { 442 if (ret < 0) {
440 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 443 dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
444 ret);
441 goto out; 445 goto out;
442 } 446 }
443 } 447 }
@@ -449,14 +453,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
449 cancel_delayed_work(&rtd->delayed_work); 453 cancel_delayed_work(&rtd->delayed_work);
450 } 454 }
451 455
452 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai,
453 snd_soc_dapm_stream_event(rtd, 457 SND_SOC_DAPM_STREAM_START);
454 codec_dai->driver->playback.stream_name,
455 SND_SOC_DAPM_STREAM_START);
456 else
457 snd_soc_dapm_stream_event(rtd,
458 codec_dai->driver->capture.stream_name,
459 SND_SOC_DAPM_STREAM_START);
460 458
461 snd_soc_dai_digital_mute(codec_dai, 0); 459 snd_soc_dai_digital_mute(codec_dai, 0);
462 460
@@ -484,7 +482,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
484 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { 482 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
485 ret = rtd->dai_link->ops->hw_params(substream, params); 483 ret = rtd->dai_link->ops->hw_params(substream, params);
486 if (ret < 0) { 484 if (ret < 0) {
487 printk(KERN_ERR "asoc: machine hw_params failed\n"); 485 pr_err("asoc: machine hw_params failed: %d\n", ret);
488 goto out; 486 goto out;
489 } 487 }
490 } 488 }
@@ -492,8 +490,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
492 if (codec_dai->driver->ops->hw_params) { 490 if (codec_dai->driver->ops->hw_params) {
493 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); 491 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
494 if (ret < 0) { 492 if (ret < 0) {
495 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 493 dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
496 codec_dai->name); 494 codec_dai->name, ret);
497 goto codec_err; 495 goto codec_err;
498 } 496 }
499 } 497 }
@@ -501,8 +499,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
501 if (cpu_dai->driver->ops->hw_params) { 499 if (cpu_dai->driver->ops->hw_params) {
502 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); 500 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
503 if (ret < 0) { 501 if (ret < 0) {
504 printk(KERN_ERR "asoc: interface %s hw params failed\n", 502 dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
505 cpu_dai->name); 503 cpu_dai->name, ret);
506 goto interface_err; 504 goto interface_err;
507 } 505 }
508 } 506 }
@@ -510,8 +508,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
510 if (platform->driver->ops && platform->driver->ops->hw_params) { 508 if (platform->driver->ops && platform->driver->ops->hw_params) {
511 ret = platform->driver->ops->hw_params(substream, params); 509 ret = platform->driver->ops->hw_params(substream, params);
512 if (ret < 0) { 510 if (ret < 0) {
513 printk(KERN_ERR "asoc: platform %s hw params failed\n", 511 dev_err(platform->dev, "%s hw params failed: %d\n",
514 platform->name); 512 platform->name, ret);
515 goto platform_err; 513 goto platform_err;
516 } 514 }
517 } 515 }
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 4a0e805c4edd..2a27725cc9b1 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -18,6 +18,7 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/of_gpio.h>
21 22
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/jack.h> 24#include <sound/jack.h>
@@ -34,8 +35,13 @@
34 35
35#define DRV_NAME "tegra-alc5632" 36#define DRV_NAME "tegra-alc5632"
36 37
38#define GPIO_HP_DET BIT(0)
39
37struct tegra_alc5632 { 40struct tegra_alc5632 {
38 struct tegra_asoc_utils_data util_data; 41 struct tegra_asoc_utils_data util_data;
42 struct platform_device *pcm_dev;
43 int gpio_requested;
44 int gpio_hp_det;
39}; 45};
40 46
41static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, 47static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
@@ -85,24 +91,18 @@ static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = {
85 }, 91 },
86}; 92};
87 93
94static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
95 .name = "Headset detection",
96 .report = SND_JACK_HEADSET,
97 .debounce_time = 150,
98 .invert = 1,
99};
100
88static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { 101static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
89 SND_SOC_DAPM_SPK("Int Spk", NULL), 102 SND_SOC_DAPM_SPK("Int Spk", NULL),
90 SND_SOC_DAPM_HP("Headset Stereophone", NULL), 103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
91 SND_SOC_DAPM_MIC("Headset Mic", NULL), 104 SND_SOC_DAPM_MIC("Headset Mic", NULL),
92}; 105 SND_SOC_DAPM_MIC("Digital Mic", NULL),
93
94static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = {
95 /* Internal Speaker */
96 {"Int Spk", NULL, "SPKOUT"},
97 {"Int Spk", NULL, "SPKOUTN"},
98
99 /* Headset Mic */
100 {"MIC1", NULL, "MICBIAS1"},
101 {"MICBIAS1", NULL, "Headset Mic"},
102
103 /* Headset Stereophone */
104 {"Headset Stereophone", NULL, "HPR"},
105 {"Headset Stereophone", NULL, "HPL"},
106}; 106};
107 107
108static const struct snd_kcontrol_new tegra_alc5632_controls[] = { 108static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
@@ -113,6 +113,9 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
113{ 113{
114 struct snd_soc_codec *codec = rtd->codec; 114 struct snd_soc_codec *codec = rtd->codec;
115 struct snd_soc_dapm_context *dapm = &codec->dapm; 115 struct snd_soc_dapm_context *dapm = &codec->dapm;
116 struct device_node *np = codec->card->dev->of_node;
117 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
118 int ret;
116 119
117 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 120 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
118 &tegra_alc5632_hs_jack); 121 &tegra_alc5632_hs_jack);
@@ -120,6 +123,16 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
120 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 123 ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
121 tegra_alc5632_hs_jack_pins); 124 tegra_alc5632_hs_jack_pins);
122 125
126 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
127
128 if (gpio_is_valid(machine->gpio_hp_det)) {
129 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
130 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
131 1,
132 &tegra_alc5632_hp_jack_gpio);
133 machine->gpio_requested |= GPIO_HP_DET;
134 }
135
123 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 136 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
124 137
125 return 0; 138 return 0;
@@ -128,9 +141,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
128static struct snd_soc_dai_link tegra_alc5632_dai = { 141static struct snd_soc_dai_link tegra_alc5632_dai = {
129 .name = "ALC5632", 142 .name = "ALC5632",
130 .stream_name = "ALC5632 PCM", 143 .stream_name = "ALC5632 PCM",
131 .codec_name = "alc5632.0-001e",
132 .platform_name = "tegra-pcm-audio", 144 .platform_name = "tegra-pcm-audio",
133 .cpu_dai_name = "tegra-i2s.0",
134 .codec_dai_name = "alc5632-hifi", 145 .codec_dai_name = "alc5632-hifi",
135 .init = tegra_alc5632_asoc_init, 146 .init = tegra_alc5632_asoc_init,
136 .ops = &tegra_alc5632_asoc_ops, 147 .ops = &tegra_alc5632_asoc_ops,
@@ -148,8 +159,6 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
148 .num_controls = ARRAY_SIZE(tegra_alc5632_controls), 159 .num_controls = ARRAY_SIZE(tegra_alc5632_controls),
149 .dapm_widgets = tegra_alc5632_dapm_widgets, 160 .dapm_widgets = tegra_alc5632_dapm_widgets,
150 .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets), 161 .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets),
151 .dapm_routes = tegra_alc5632_audio_map,
152 .num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map),
153 .fully_routed = true, 162 .fully_routed = true,
154}; 163};
155 164
@@ -163,45 +172,111 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
163 sizeof(struct tegra_alc5632), GFP_KERNEL); 172 sizeof(struct tegra_alc5632), GFP_KERNEL);
164 if (!alc5632) { 173 if (!alc5632) {
165 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); 174 dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
166 return -ENOMEM; 175 ret = -ENOMEM;
176 goto err;
167 } 177 }
168 178
169 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
170 if (ret)
171 return ret;
172
173 card->dev = &pdev->dev; 179 card->dev = &pdev->dev;
174 platform_set_drvdata(pdev, card); 180 platform_set_drvdata(pdev, card);
175 snd_soc_card_set_drvdata(card, alc5632); 181 snd_soc_card_set_drvdata(card, alc5632);
176 182
183 alc5632->pcm_dev = ERR_PTR(-EINVAL);
184
185 if (!(pdev->dev.of_node)) {
186 dev_err(&pdev->dev, "Must be instantiated using device tree\n");
187 ret = -EINVAL;
188 goto err;
189 }
190
191 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
192 if (ret)
193 goto err;
194
195 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
196 if (ret)
197 goto err;
198
199 tegra_alc5632_dai.codec_of_node = of_parse_phandle(
200 pdev->dev.of_node, "nvidia,audio-codec", 0);
201
202 if (!tegra_alc5632_dai.codec_of_node) {
203 dev_err(&pdev->dev,
204 "Property 'nvidia,audio-codec' missing or invalid\n");
205 ret = -EINVAL;
206 goto err;
207 }
208
209 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle(
210 pdev->dev.of_node, "nvidia,i2s-controller", 0);
211 if (!tegra_alc5632_dai.cpu_dai_of_node) {
212 dev_err(&pdev->dev,
213 "Property 'nvidia,i2s-controller' missing or invalid\n");
214 ret = -EINVAL;
215 goto err;
216 }
217
218 alc5632->pcm_dev = platform_device_register_simple(
219 "tegra-pcm-audio", -1, NULL, 0);
220 if (IS_ERR(alc5632->pcm_dev)) {
221 dev_err(&pdev->dev,
222 "Can't instantiate tegra-pcm-audio\n");
223 ret = PTR_ERR(alc5632->pcm_dev);
224 goto err;
225 }
226
227 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
228 if (ret)
229 goto err_unregister;
230
177 ret = snd_soc_register_card(card); 231 ret = snd_soc_register_card(card);
178 if (ret) { 232 if (ret) {
179 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 233 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
180 ret); 234 ret);
181 tegra_asoc_utils_fini(&alc5632->util_data); 235 goto err_fini_utils;
182 return ret;
183 } 236 }
184 237
185 return 0; 238 return 0;
239
240err_fini_utils:
241 tegra_asoc_utils_fini(&alc5632->util_data);
242err_unregister:
243 if (!IS_ERR(alc5632->pcm_dev))
244 platform_device_unregister(alc5632->pcm_dev);
245err:
246 return ret;
186} 247}
187 248
188static int __devexit tegra_alc5632_remove(struct platform_device *pdev) 249static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
189{ 250{
190 struct snd_soc_card *card = platform_get_drvdata(pdev); 251 struct snd_soc_card *card = platform_get_drvdata(pdev);
191 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 252 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
253
254 if (machine->gpio_requested & GPIO_HP_DET)
255 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack,
256 1,
257 &tegra_alc5632_hp_jack_gpio);
258 machine->gpio_requested = 0;
192 259
193 snd_soc_unregister_card(card); 260 snd_soc_unregister_card(card);
194 261
195 tegra_asoc_utils_fini(&alc5632->util_data); 262 tegra_asoc_utils_fini(&machine->util_data);
263 if (!IS_ERR(machine->pcm_dev))
264 platform_device_unregister(machine->pcm_dev);
196 265
197 return 0; 266 return 0;
198} 267}
199 268
269static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = {
270 { .compatible = "nvidia,tegra-audio-alc5632", },
271 {},
272};
273
200static struct platform_driver tegra_alc5632_driver = { 274static struct platform_driver tegra_alc5632_driver = {
201 .driver = { 275 .driver = {
202 .name = DRV_NAME, 276 .name = DRV_NAME,
203 .owner = THIS_MODULE, 277 .owner = THIS_MODULE,
204 .pm = &snd_soc_pm_ops, 278 .pm = &snd_soc_pm_ops,
279 .of_match_table = tegra_alc5632_of_match,
205 }, 280 },
206 .probe = tegra_alc5632_probe, 281 .probe = tegra_alc5632_probe,
207 .remove = __devexit_p(tegra_alc5632_remove), 282 .remove = __devexit_p(tegra_alc5632_remove),
@@ -212,3 +287,4 @@ MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
212MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); 287MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver");
213MODULE_LICENSE("GPL"); 288MODULE_LICENSE("GPL");
214MODULE_ALIAS("platform:" DRV_NAME); 289MODULE_ALIAS("platform:" DRV_NAME);
290MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match);