aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/88pm860x-codec.c6
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c12
-rw-r--r--sound/soc/codecs/adau1701.c302
-rw-r--r--sound/soc/codecs/stac9766.c26
-rw-r--r--sound/soc/codecs/tlv320aic3x.c6
-rw-r--r--sound/soc/codecs/wm8400.c9
-rw-r--r--sound/soc/codecs/wm8903.c6
-rw-r--r--sound/soc/codecs/wm8904.c9
-rw-r--r--sound/soc/codecs/wm8990.c11
-rw-r--r--sound/soc/codecs/wm8991.h9
-rw-r--r--sound/soc/codecs/wm8994.c12
-rw-r--r--sound/soc/codecs/wm8995.h7
-rw-r--r--sound/soc/codecs/wm9705.c16
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c18
-rw-r--r--sound/soc/codecs/wm_adsp.c459
-rw-r--r--sound/soc/codecs/wm_adsp.h13
-rw-r--r--sound/soc/codecs/wm_hubs.c6
19 files changed, 789 insertions, 163 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 60159c07448d..e2bd3dd02c0e 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -120,10 +120,8 @@
120 * before DAC & PGA in DAPM power-off sequence. 120 * before DAC & PGA in DAPM power-off sequence.
121 */ 121 */
122#define PM860X_DAPM_OUTPUT(wname, wevent) \ 122#define PM860X_DAPM_OUTPUT(wname, wevent) \
123{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 123 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, 0, 0, NULL, 0, wevent, \
124 .shift = 0, .invert = 0, .kcontrol_news = NULL, \ 124 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD)
125 .num_kcontrols = 0, .event = wevent, \
126 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
127 125
128struct pm860x_det { 126struct pm860x_det {
129 struct snd_soc_jack *hp_jack; 127 struct snd_soc_jack *hp_jack;
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index ef2ae32ffc66..ec7351803c24 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -62,13 +62,13 @@ static struct snd_soc_dai_driver ac97_dai = {
62static unsigned int ac97_read(struct snd_soc_codec *codec, 62static unsigned int ac97_read(struct snd_soc_codec *codec,
63 unsigned int reg) 63 unsigned int reg)
64{ 64{
65 return soc_ac97_ops.read(codec->ac97, reg); 65 return soc_ac97_ops->read(codec->ac97, reg);
66} 66}
67 67
68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
69 unsigned int val) 69 unsigned int val)
70{ 70{
71 soc_ac97_ops.write(codec->ac97, reg, val); 71 soc_ac97_ops->write(codec->ac97, reg, val);
72 return 0; 72 return 0;
73} 73}
74 74
@@ -79,7 +79,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
79 int ret; 79 int ret;
80 80
81 /* add codec as bus device for standard ac97 */ 81 /* add codec as bus device for standard ac97 */
82 ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus); 82 ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL,
83 &ac97_bus);
83 if (ret < 0) 84 if (ret < 0)
84 return ret; 85 return ret;
85 86
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index f385342947d3..89fcf7d6e7b8 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -108,7 +108,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
108 case AC97_EXTENDED_STATUS: 108 case AC97_EXTENDED_STATUS:
109 case AC97_VENDOR_ID1: 109 case AC97_VENDOR_ID1:
110 case AC97_VENDOR_ID2: 110 case AC97_VENDOR_ID2:
111 return soc_ac97_ops.read(codec->ac97, reg); 111 return soc_ac97_ops->read(codec->ac97, reg);
112 default: 112 default:
113 reg = reg >> 1; 113 reg = reg >> 1;
114 114
@@ -124,7 +124,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
124{ 124{
125 u16 *cache = codec->reg_cache; 125 u16 *cache = codec->reg_cache;
126 126
127 soc_ac97_ops.write(codec->ac97, reg, val); 127 soc_ac97_ops->write(codec->ac97, reg, val);
128 reg = reg >> 1; 128 reg = reg >> 1;
129 if (reg < ARRAY_SIZE(ad1980_reg)) 129 if (reg < ARRAY_SIZE(ad1980_reg))
130 cache[reg] = val; 130 cache[reg] = val;
@@ -154,13 +154,13 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
154 u16 retry_cnt = 0; 154 u16 retry_cnt = 0;
155 155
156retry: 156retry:
157 if (try_warm && soc_ac97_ops.warm_reset) { 157 if (try_warm && soc_ac97_ops->warm_reset) {
158 soc_ac97_ops.warm_reset(codec->ac97); 158 soc_ac97_ops->warm_reset(codec->ac97);
159 if (ac97_read(codec, AC97_RESET) == 0x0090) 159 if (ac97_read(codec, AC97_RESET) == 0x0090)
160 return 1; 160 return 1;
161 } 161 }
162 162
163 soc_ac97_ops.reset(codec->ac97); 163 soc_ac97_ops->reset(codec->ac97);
164 /* Set bit 16slot in register 74h, then every slot will has only 16 164 /* Set bit 16slot in register 74h, then every slot will has only 16
165 * bits. This command is sent out in 20bit mode, in which case the 165 * bits. This command is sent out in 20bit mode, in which case the
166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/ 166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
@@ -186,7 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
186 186
187 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 187 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
188 188
189 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 189 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
190 if (ret < 0) { 190 if (ret < 0) {
191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
192 return ret; 192 return ret;
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index dafdbe87edeb..0e250f118c0e 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -13,6 +13,10 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/of.h>
17#include <linux/of_gpio.h>
18#include <linux/of_device.h>
19#include <linux/regmap.h>
16#include <sound/core.h> 20#include <sound/core.h>
17#include <sound/pcm.h> 21#include <sound/pcm.h>
18#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -21,16 +25,19 @@
21#include "sigmadsp.h" 25#include "sigmadsp.h"
22#include "adau1701.h" 26#include "adau1701.h"
23 27
24#define ADAU1701_DSPCTRL 0x1c 28#define ADAU1701_DSPCTRL 0x081c
25#define ADAU1701_SEROCTL 0x1e 29#define ADAU1701_SEROCTL 0x081e
26#define ADAU1701_SERICTL 0x1f 30#define ADAU1701_SERICTL 0x081f
27 31
28#define ADAU1701_AUXNPOW 0x22 32#define ADAU1701_AUXNPOW 0x0822
33#define ADAU1701_PINCONF_0 0x0820
34#define ADAU1701_PINCONF_1 0x0821
35#define ADAU1701_AUXNPOW 0x0822
29 36
30#define ADAU1701_OSCIPOW 0x26 37#define ADAU1701_OSCIPOW 0x0826
31#define ADAU1701_DACSET 0x27 38#define ADAU1701_DACSET 0x0827
32 39
33#define ADAU1701_NUM_REGS 0x28 40#define ADAU1701_MAX_REGISTER 0x0828
34 41
35#define ADAU1701_DSPCTRL_CR (1 << 2) 42#define ADAU1701_DSPCTRL_CR (1 << 2)
36#define ADAU1701_DSPCTRL_DAM (1 << 3) 43#define ADAU1701_DSPCTRL_DAM (1 << 3)
@@ -84,10 +91,18 @@
84#define ADAU1701_OSCIPOW_OPD 0x04 91#define ADAU1701_OSCIPOW_OPD 0x04
85#define ADAU1701_DACSET_DACINIT 1 92#define ADAU1701_DACSET_DACINIT 1
86 93
94#define ADAU1707_CLKDIV_UNSET (-1UL)
95
87#define ADAU1701_FIRMWARE "adau1701.bin" 96#define ADAU1701_FIRMWARE "adau1701.bin"
88 97
89struct adau1701 { 98struct adau1701 {
99 int gpio_nreset;
100 int gpio_pll_mode[2];
90 unsigned int dai_fmt; 101 unsigned int dai_fmt;
102 unsigned int pll_clkdiv;
103 unsigned int sysclk;
104 struct regmap *regmap;
105 u8 pin_config[12];
91}; 106};
92 107
93static const struct snd_kcontrol_new adau1701_controls[] = { 108static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -119,10 +134,13 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
119 { "ADC", NULL, "IN1" }, 134 { "ADC", NULL, "IN1" },
120}; 135};
121 136
122static unsigned int adau1701_register_size(struct snd_soc_codec *codec, 137static unsigned int adau1701_register_size(struct device *dev,
123 unsigned int reg) 138 unsigned int reg)
124{ 139{
125 switch (reg) { 140 switch (reg) {
141 case ADAU1701_PINCONF_0:
142 case ADAU1701_PINCONF_1:
143 return 3;
126 case ADAU1701_DSPCTRL: 144 case ADAU1701_DSPCTRL:
127 case ADAU1701_SEROCTL: 145 case ADAU1701_SEROCTL:
128 case ADAU1701_AUXNPOW: 146 case ADAU1701_AUXNPOW:
@@ -133,33 +151,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
133 return 1; 151 return 1;
134 } 152 }
135 153
136 dev_err(codec->dev, "Unsupported register address: %d\n", reg); 154 dev_err(dev, "Unsupported register address: %d\n", reg);
137 return 0; 155 return 0;
138} 156}
139 157
140static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, 158static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
141 unsigned int value)
142{ 159{
160 switch (reg) {
161 case ADAU1701_DACSET:
162 return true;
163 default:
164 return false;
165 }
166}
167
168static int adau1701_reg_write(void *context, unsigned int reg,
169 unsigned int value)
170{
171 struct i2c_client *client = context;
143 unsigned int i; 172 unsigned int i;
144 unsigned int size; 173 unsigned int size;
145 uint8_t buf[4]; 174 uint8_t buf[5];
146 int ret; 175 int ret;
147 176
148 size = adau1701_register_size(codec, reg); 177 size = adau1701_register_size(&client->dev, reg);
149 if (size == 0) 178 if (size == 0)
150 return -EINVAL; 179 return -EINVAL;
151 180
152 snd_soc_cache_write(codec, reg, value); 181 buf[0] = reg >> 8;
153 182 buf[1] = reg & 0xff;
154 buf[0] = 0x08;
155 buf[1] = reg;
156 183
157 for (i = size + 1; i >= 2; --i) { 184 for (i = size + 1; i >= 2; --i) {
158 buf[i] = value; 185 buf[i] = value;
159 value >>= 8; 186 value >>= 8;
160 } 187 }
161 188
162 ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2); 189 ret = i2c_master_send(client, buf, size + 2);
163 if (ret == size + 2) 190 if (ret == size + 2)
164 return 0; 191 return 0;
165 else if (ret < 0) 192 else if (ret < 0)
@@ -168,21 +195,107 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
168 return -EIO; 195 return -EIO;
169} 196}
170 197
171static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg) 198static int adau1701_reg_read(void *context, unsigned int reg,
199 unsigned int *value)
172{ 200{
173 unsigned int value; 201 int ret;
174 unsigned int ret; 202 unsigned int i;
203 unsigned int size;
204 uint8_t send_buf[2], recv_buf[3];
205 struct i2c_client *client = context;
206 struct i2c_msg msgs[2];
207
208 size = adau1701_register_size(&client->dev, reg);
209 if (size == 0)
210 return -EINVAL;
211
212 send_buf[0] = reg >> 8;
213 send_buf[1] = reg & 0xff;
214
215 msgs[0].addr = client->addr;
216 msgs[0].len = sizeof(send_buf);
217 msgs[0].buf = send_buf;
218 msgs[0].flags = 0;
219
220 msgs[1].addr = client->addr;
221 msgs[1].len = size;
222 msgs[1].buf = recv_buf;
223 msgs[1].flags = I2C_M_RD;
175 224
176 ret = snd_soc_cache_read(codec, reg, &value); 225 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
177 if (ret) 226 if (ret < 0)
178 return ret; 227 return ret;
228 else if (ret != ARRAY_SIZE(msgs))
229 return -EIO;
230
231 *value = 0;
232
233 for (i = 0; i < size; i++)
234 *value |= recv_buf[i] << (i * 8);
179 235
180 return value; 236 return 0;
181} 237}
182 238
183static int adau1701_load_firmware(struct snd_soc_codec *codec) 239static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
184{ 240{
185 return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE); 241 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
242 struct i2c_client *client = to_i2c_client(codec->dev);
243 int ret;
244
245 if (clkdiv != ADAU1707_CLKDIV_UNSET &&
246 gpio_is_valid(adau1701->gpio_pll_mode[0]) &&
247 gpio_is_valid(adau1701->gpio_pll_mode[1])) {
248 switch (clkdiv) {
249 case 64:
250 gpio_set_value(adau1701->gpio_pll_mode[0], 0);
251 gpio_set_value(adau1701->gpio_pll_mode[1], 0);
252 break;
253 case 256:
254 gpio_set_value(adau1701->gpio_pll_mode[0], 0);
255 gpio_set_value(adau1701->gpio_pll_mode[1], 1);
256 break;
257 case 384:
258 gpio_set_value(adau1701->gpio_pll_mode[0], 1);
259 gpio_set_value(adau1701->gpio_pll_mode[1], 0);
260 break;
261 case 0: /* fallback */
262 case 512:
263 gpio_set_value(adau1701->gpio_pll_mode[0], 1);
264 gpio_set_value(adau1701->gpio_pll_mode[1], 1);
265 break;
266 }
267 }
268
269 adau1701->pll_clkdiv = clkdiv;
270
271 if (gpio_is_valid(adau1701->gpio_nreset)) {
272 gpio_set_value(adau1701->gpio_nreset, 0);
273 /* minimum reset time is 20ns */
274 udelay(1);
275 gpio_set_value(adau1701->gpio_nreset, 1);
276 /* power-up time may be as long as 85ms */
277 mdelay(85);
278 }
279
280 /*
281 * Postpone the firmware download to a point in time when we
282 * know the correct PLL setup
283 */
284 if (clkdiv != ADAU1707_CLKDIV_UNSET) {
285 ret = process_sigma_firmware(client, ADAU1701_FIRMWARE);
286 if (ret) {
287 dev_warn(codec->dev, "Failed to load firmware\n");
288 return ret;
289 }
290 }
291
292 regmap_write(adau1701->regmap, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT);
293 regmap_write(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
294
295 regcache_mark_dirty(adau1701->regmap);
296 regcache_sync(adau1701->regmap);
297
298 return 0;
186} 299}
187 300
188static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, 301static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
@@ -259,8 +372,22 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 372 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
260{ 373{
261 struct snd_soc_codec *codec = dai->codec; 374 struct snd_soc_codec *codec = dai->codec;
375 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
376 unsigned int clkdiv = adau1701->sysclk / params_rate(params);
262 snd_pcm_format_t format; 377 snd_pcm_format_t format;
263 unsigned int val; 378 unsigned int val;
379 int ret;
380
381 /*
382 * If the mclk/lrclk ratio changes, the chip needs updated PLL
383 * mode GPIO settings, and a full reset cycle, including a new
384 * firmware upload.
385 */
386 if (clkdiv != adau1701->pll_clkdiv) {
387 ret = adau1701_reset(codec, clkdiv);
388 if (ret < 0)
389 return ret;
390 }
264 391
265 switch (params_rate(params)) { 392 switch (params_rate(params)) {
266 case 192000: 393 case 192000:
@@ -352,8 +479,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
352 479
353 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 480 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
354 481
355 snd_soc_write(codec, ADAU1701_SERICTL, serictl); 482 regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
356 snd_soc_update_bits(codec, ADAU1701_SEROCTL, 483 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
357 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); 484 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
358 485
359 return 0; 486 return 0;
@@ -403,6 +530,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
403 int source, unsigned int freq, int dir) 530 int source, unsigned int freq, int dir)
404{ 531{
405 unsigned int val; 532 unsigned int val;
533 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
406 534
407 switch (clk_id) { 535 switch (clk_id) {
408 case ADAU1701_CLK_SRC_OSC: 536 case ADAU1701_CLK_SRC_OSC:
@@ -416,6 +544,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
416 } 544 }
417 545
418 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val); 546 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val);
547 adau1701->sysclk = freq;
419 548
420 return 0; 549 return 0;
421} 550}
@@ -452,18 +581,47 @@ static struct snd_soc_dai_driver adau1701_dai = {
452 .symmetric_rates = 1, 581 .symmetric_rates = 1,
453}; 582};
454 583
584#ifdef CONFIG_OF
585static const struct of_device_id adau1701_dt_ids[] = {
586 { .compatible = "adi,adau1701", },
587 { }
588};
589MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
590#endif
591
455static int adau1701_probe(struct snd_soc_codec *codec) 592static int adau1701_probe(struct snd_soc_codec *codec)
456{ 593{
457 int ret; 594 int i, ret;
595 unsigned int val;
596 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
458 597
459 codec->control_data = to_i2c_client(codec->dev); 598 codec->control_data = to_i2c_client(codec->dev);
460 599
461 ret = adau1701_load_firmware(codec); 600 /*
462 if (ret) 601 * Let the pll_clkdiv variable default to something that won't happen
463 dev_warn(codec->dev, "Failed to load firmware\n"); 602 * at runtime. That way, we can postpone the firmware download from
603 * adau1701_reset() to a point in time when we know the correct PLL
604 * mode parameters.
605 */
606 adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
607
608 /* initalize with pre-configured pll mode settings */
609 ret = adau1701_reset(codec, adau1701->pll_clkdiv);
610 if (ret < 0)
611 return ret;
612
613 /* set up pin config */
614 val = 0;
615 for (i = 0; i < 6; i++)
616 val |= adau1701->pin_config[i] << (i * 4);
464 617
465 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); 618 regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val);
466 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); 619
620 val = 0;
621 for (i = 0; i < 6; i++)
622 val |= adau1701->pin_config[i + 6] << (i * 4);
623
624 regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
467 625
468 return 0; 626 return 0;
469} 627}
@@ -473,9 +631,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
473 .set_bias_level = adau1701_set_bias_level, 631 .set_bias_level = adau1701_set_bias_level,
474 .idle_bias_off = true, 632 .idle_bias_off = true,
475 633
476 .reg_cache_size = ADAU1701_NUM_REGS,
477 .reg_word_size = sizeof(u16),
478
479 .controls = adau1701_controls, 634 .controls = adau1701_controls,
480 .num_controls = ARRAY_SIZE(adau1701_controls), 635 .num_controls = ARRAY_SIZE(adau1701_controls),
481 .dapm_widgets = adau1701_dapm_widgets, 636 .dapm_widgets = adau1701_dapm_widgets,
@@ -483,22 +638,86 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
483 .dapm_routes = adau1701_dapm_routes, 638 .dapm_routes = adau1701_dapm_routes,
484 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 639 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
485 640
486 .write = adau1701_write,
487 .read = adau1701_read,
488
489 .set_sysclk = adau1701_set_sysclk, 641 .set_sysclk = adau1701_set_sysclk,
490}; 642};
491 643
644static const struct regmap_config adau1701_regmap = {
645 .reg_bits = 16,
646 .val_bits = 32,
647 .max_register = ADAU1701_MAX_REGISTER,
648 .cache_type = REGCACHE_RBTREE,
649 .volatile_reg = adau1701_volatile_reg,
650 .reg_write = adau1701_reg_write,
651 .reg_read = adau1701_reg_read,
652};
653
492static int adau1701_i2c_probe(struct i2c_client *client, 654static int adau1701_i2c_probe(struct i2c_client *client,
493 const struct i2c_device_id *id) 655 const struct i2c_device_id *id)
494{ 656{
495 struct adau1701 *adau1701; 657 struct adau1701 *adau1701;
658 struct device *dev = &client->dev;
659 int gpio_nreset = -EINVAL;
660 int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
496 int ret; 661 int ret;
497 662
498 adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); 663 adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
499 if (!adau1701) 664 if (!adau1701)
500 return -ENOMEM; 665 return -ENOMEM;
501 666
667 adau1701->regmap = devm_regmap_init(dev, NULL, client,
668 &adau1701_regmap);
669 if (IS_ERR(adau1701->regmap))
670 return PTR_ERR(adau1701->regmap);
671
672 if (dev->of_node) {
673 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
674 if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
675 return gpio_nreset;
676
677 gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
678 "adi,pll-mode-gpios", 0);
679 if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
680 return gpio_pll_mode[0];
681
682 gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
683 "adi,pll-mode-gpios", 1);
684 if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
685 return gpio_pll_mode[1];
686
687 of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
688 &adau1701->pll_clkdiv);
689
690 of_property_read_u8_array(dev->of_node, "adi,pin-config",
691 adau1701->pin_config,
692 ARRAY_SIZE(adau1701->pin_config));
693 }
694
695 if (gpio_is_valid(gpio_nreset)) {
696 ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
697 "ADAU1701 Reset");
698 if (ret < 0)
699 return ret;
700 }
701
702 if (gpio_is_valid(gpio_pll_mode[0]) &&
703 gpio_is_valid(gpio_pll_mode[1])) {
704 ret = devm_gpio_request_one(dev, gpio_pll_mode[0],
705 GPIOF_OUT_INIT_LOW,
706 "ADAU1701 PLL mode 0");
707 if (ret < 0)
708 return ret;
709
710 ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
711 GPIOF_OUT_INIT_LOW,
712 "ADAU1701 PLL mode 1");
713 if (ret < 0)
714 return ret;
715 }
716
717 adau1701->gpio_nreset = gpio_nreset;
718 adau1701->gpio_pll_mode[0] = gpio_pll_mode[0];
719 adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
720
502 i2c_set_clientdata(client, adau1701); 721 i2c_set_clientdata(client, adau1701);
503 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, 722 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
504 &adau1701_dai, 1); 723 &adau1701_dai, 1);
@@ -521,6 +740,7 @@ static struct i2c_driver adau1701_i2c_driver = {
521 .driver = { 740 .driver = {
522 .name = "adau1701", 741 .name = "adau1701",
523 .owner = THIS_MODULE, 742 .owner = THIS_MODULE,
743 .of_match_table = of_match_ptr(adau1701_dt_ids),
524 }, 744 },
525 .probe = adau1701_i2c_probe, 745 .probe = adau1701_i2c_probe,
526 .remove = adau1701_i2c_remove, 746 .remove = adau1701_i2c_remove,
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 2eda85ba79ac..a5455c1aea42 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -28,8 +28,6 @@
28 28
29#include "stac9766.h" 29#include "stac9766.h"
30 30
31#define STAC9766_VERSION "0.10"
32
33/* 31/*
34 * STAC9766 register cache 32 * STAC9766 register cache
35 */ 33 */
@@ -145,14 +143,14 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
145 143
146 if (reg > AC97_STAC_PAGE0) { 144 if (reg > AC97_STAC_PAGE0) {
147 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 145 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
148 soc_ac97_ops.write(codec->ac97, reg, val); 146 soc_ac97_ops->write(codec->ac97, reg, val);
149 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 147 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
150 return 0; 148 return 0;
151 } 149 }
152 if (reg / 2 >= ARRAY_SIZE(stac9766_reg)) 150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
153 return -EIO; 151 return -EIO;
154 152
155 soc_ac97_ops.write(codec->ac97, reg, val); 153 soc_ac97_ops->write(codec->ac97, reg, val);
156 cache[reg / 2] = val; 154 cache[reg / 2] = val;
157 return 0; 155 return 0;
158} 156}
@@ -164,7 +162,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
164 162
165 if (reg > AC97_STAC_PAGE0) { 163 if (reg > AC97_STAC_PAGE0) {
166 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 164 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
167 val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0); 165 val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0);
168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 166 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
169 return val; 167 return val;
170 } 168 }
@@ -175,7 +173,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
175 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || 173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
176 reg == AC97_VENDOR_ID2) { 174 reg == AC97_VENDOR_ID2) {
177 175
178 val = soc_ac97_ops.read(codec->ac97, reg); 176 val = soc_ac97_ops->read(codec->ac97, reg);
179 return val; 177 return val;
180 } 178 }
181 return cache[reg / 2]; 179 return cache[reg / 2];
@@ -242,15 +240,15 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
242 240
243static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) 241static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
244{ 242{
245 if (try_warm && soc_ac97_ops.warm_reset) { 243 if (try_warm && soc_ac97_ops->warm_reset) {
246 soc_ac97_ops.warm_reset(codec->ac97); 244 soc_ac97_ops->warm_reset(codec->ac97);
247 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) 245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
248 return 1; 246 return 1;
249 } 247 }
250 248
251 soc_ac97_ops.reset(codec->ac97); 249 soc_ac97_ops->reset(codec->ac97);
252 if (soc_ac97_ops.warm_reset) 250 if (soc_ac97_ops->warm_reset)
253 soc_ac97_ops.warm_reset(codec->ac97); 251 soc_ac97_ops->warm_reset(codec->ac97);
254 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) 252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
255 return -EIO; 253 return -EIO;
256 return 0; 254 return 0;
@@ -274,7 +272,7 @@ reset:
274 return -EIO; 272 return -EIO;
275 } 273 }
276 codec->ac97->bus->ops->warm_reset(codec->ac97); 274 codec->ac97->bus->ops->warm_reset(codec->ac97);
277 id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2); 275 id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2);
278 if (id != 0x4c13) { 276 if (id != 0x4c13) {
279 stac9766_reset(codec, 0); 277 stac9766_reset(codec, 0);
280 reset++; 278 reset++;
@@ -338,9 +336,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
338{ 336{
339 int ret = 0; 337 int ret = 0;
340 338
341 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); 339 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
342
343 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
344 if (ret < 0) 340 if (ret < 0)
345 goto codec_err; 341 goto codec_err;
346 342
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 1514bf845e4b..e5b926883131 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -128,10 +128,8 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
128}; 128};
129 129
130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
131{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 131 SOC_SINGLE_EXT(xname, reg, shift, mask, invert, \
132 .info = snd_soc_info_volsw, \ 132 snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw_aic3x)
133 .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw_aic3x, \
134 .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) }
135 133
136/* 134/*
137 * All input lines are connected when !0xf and disconnected with 0xf bit field, 135 * All input lines are connected when !0xf and disconnected with 0xf bit field,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index af6d227e67be..d2a092850283 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -143,13 +143,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
143} 143}
144 144
145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
146{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 146 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
147 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 147 snd_soc_get_volsw, wm8400_outpga_put_volsw_vu, tlv_array)
148 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
149 .tlv.p = (tlv_array), \
150 .info = snd_soc_info_volsw, \
151 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
152 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
153 148
154 149
155static const char *wm8400_digital_sidetone[] = 150static const char *wm8400_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 9d88437cdcd1..fa24cedee687 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -403,10 +403,8 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
403} 403}
404 404
405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \ 405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
406{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 406 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
407 .info = snd_soc_info_volsw, \ 407 snd_soc_dapm_get_volsw, wm8903_class_w_put)
408 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
409 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
410 408
411 409
412static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; 410static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 3ff195c541db..4c9fb142cb2d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -603,13 +603,8 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
603 603
604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
605SOC_ENUM("High Pass Filter Mode", hpf_mode), 605SOC_ENUM("High Pass Filter Mode", hpf_mode),
606 606SOC_SINGLE_EXT("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0,
607{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 607 snd_soc_get_volsw, wm8904_adc_osr_put),
608 .name = "ADC 128x OSR Switch",
609 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
610 .put = wm8904_adc_osr_put,
611 .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
612},
613}; 608};
614 609
615static const char *drc_path_text[] = { 610static const char *drc_path_text[] = {
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 837978e16e9d..253c88bb7a4c 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -151,14 +151,9 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
151} 151}
152 152
153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
154 tlv_array) {\ 154 tlv_array) \
155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 155 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
156 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 156 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
157 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
158 .tlv.p = (tlv_array), \
159 .info = snd_soc_info_volsw, \
160 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
161 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
162 157
163 158
164static const char *wm8990_digital_sidetone[] = 159static const char *wm8990_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
index 8a942efd18a5..07707d8d7e20 100644
--- a/sound/soc/codecs/wm8991.h
+++ b/sound/soc/codecs/wm8991.h
@@ -822,12 +822,7 @@
822 822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \ 824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 825 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 826 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832 827
833#endif /* _WM8991_H */ 828#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 29e95f93d482..9e13edd81292 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -289,10 +289,8 @@ static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
289static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0); 289static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
290 290
291#define WM8994_DRC_SWITCH(xname, reg, shift) \ 291#define WM8994_DRC_SWITCH(xname, reg, shift) \
292{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 292 SOC_SINGLE_EXT(xname, reg, shift, 1, 0, \
293 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 293 snd_soc_get_volsw, wm8994_put_drc_sw)
294 .put = wm8994_put_drc_sw, \
295 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
296 294
297static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, 295static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_value *ucontrol) 296 struct snd_ctl_elem_value *ucontrol)
@@ -1432,10 +1430,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1432}; 1430};
1433 1431
1434#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 1432#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
1435{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1433 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
1436 .info = snd_soc_info_volsw, \ 1434 snd_soc_get_volsw, wm8994_put_class_w)
1437 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
1438 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
1439 1435
1440static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1436static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1441 struct snd_ctl_elem_value *ucontrol) 1437 struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
index 5642121c4977..508ad27fe2bb 100644
--- a/sound/soc/codecs/wm8995.h
+++ b/sound/soc/codecs/wm8995.h
@@ -4237,11 +4237,8 @@
4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ 4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
4238 4238
4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
4240{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 4240 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
4241 .info = snd_soc_info_volsw, \ 4241 snd_soc_dapm_get_volsw, wm8995_put_class_w)
4242 .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
4243 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
4244}
4245 4242
4246struct wm8995_reg_access { 4243struct wm8995_reg_access {
4247 u16 read; 4244 u16 read;
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 05b1f346695b..70ce6793c5bd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -209,7 +209,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
209 case AC97_RESET: 209 case AC97_RESET:
210 case AC97_VENDOR_ID1: 210 case AC97_VENDOR_ID1:
211 case AC97_VENDOR_ID2: 211 case AC97_VENDOR_ID2:
212 return soc_ac97_ops.read(codec->ac97, reg); 212 return soc_ac97_ops->read(codec->ac97, reg);
213 default: 213 default:
214 reg = reg >> 1; 214 reg = reg >> 1;
215 215
@@ -225,7 +225,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
225{ 225{
226 u16 *cache = codec->reg_cache; 226 u16 *cache = codec->reg_cache;
227 227
228 soc_ac97_ops.write(codec->ac97, reg, val); 228 soc_ac97_ops->write(codec->ac97, reg, val);
229 reg = reg >> 1; 229 reg = reg >> 1;
230 if (reg < (ARRAY_SIZE(wm9705_reg))) 230 if (reg < (ARRAY_SIZE(wm9705_reg)))
231 cache[reg] = val; 231 cache[reg] = val;
@@ -294,8 +294,8 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
294 294
295static int wm9705_reset(struct snd_soc_codec *codec) 295static int wm9705_reset(struct snd_soc_codec *codec)
296{ 296{
297 if (soc_ac97_ops.reset) { 297 if (soc_ac97_ops->reset) {
298 soc_ac97_ops.reset(codec->ac97); 298 soc_ac97_ops->reset(codec->ac97);
299 if (ac97_read(codec, 0) == wm9705_reg[0]) 299 if (ac97_read(codec, 0) == wm9705_reg[0])
300 return 0; /* Success */ 300 return 0; /* Success */
301 } 301 }
@@ -306,7 +306,7 @@ static int wm9705_reset(struct snd_soc_codec *codec)
306#ifdef CONFIG_PM 306#ifdef CONFIG_PM
307static int wm9705_soc_suspend(struct snd_soc_codec *codec) 307static int wm9705_soc_suspend(struct snd_soc_codec *codec)
308{ 308{
309 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); 309 soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff);
310 310
311 return 0; 311 return 0;
312} 312}
@@ -323,7 +323,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
323 } 323 }
324 324
325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { 325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
326 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 326 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
327 } 327 }
328 328
329 return 0; 329 return 0;
@@ -337,9 +337,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
337{ 337{
338 int ret = 0; 338 int ret = 0;
339 339
340 printk(KERN_INFO "WM9705 SoC Audio Codec\n"); 340 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
341
342 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
343 if (ret < 0) { 341 if (ret < 0) {
344 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
345 return ret; 343 return ret;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 8e9a6a3eeb1a..c5eb746087b4 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -455,7 +455,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
457 reg == AC97_REC_GAIN) 457 reg == AC97_REC_GAIN)
458 return soc_ac97_ops.read(codec->ac97, reg); 458 return soc_ac97_ops->read(codec->ac97, reg);
459 else { 459 else {
460 reg = reg >> 1; 460 reg = reg >> 1;
461 461
@@ -472,7 +472,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
472 u16 *cache = codec->reg_cache; 472 u16 *cache = codec->reg_cache;
473 473
474 if (reg < 0x7c) 474 if (reg < 0x7c)
475 soc_ac97_ops.write(codec->ac97, reg, val); 475 soc_ac97_ops->write(codec->ac97, reg, val);
476 reg = reg >> 1; 476 reg = reg >> 1;
477 if (reg < (ARRAY_SIZE(wm9712_reg))) 477 if (reg < (ARRAY_SIZE(wm9712_reg)))
478 cache[reg] = val; 478 cache[reg] = val;
@@ -581,15 +581,15 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
581 581
582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) 582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
583{ 583{
584 if (try_warm && soc_ac97_ops.warm_reset) { 584 if (try_warm && soc_ac97_ops->warm_reset) {
585 soc_ac97_ops.warm_reset(codec->ac97); 585 soc_ac97_ops->warm_reset(codec->ac97);
586 if (ac97_read(codec, 0) == wm9712_reg[0]) 586 if (ac97_read(codec, 0) == wm9712_reg[0])
587 return 1; 587 return 1;
588 } 588 }
589 589
590 soc_ac97_ops.reset(codec->ac97); 590 soc_ac97_ops->reset(codec->ac97);
591 if (soc_ac97_ops.warm_reset) 591 if (soc_ac97_ops->warm_reset)
592 soc_ac97_ops.warm_reset(codec->ac97); 592 soc_ac97_ops->warm_reset(codec->ac97);
593 if (ac97_read(codec, 0) != wm9712_reg[0]) 593 if (ac97_read(codec, 0) != wm9712_reg[0])
594 goto err; 594 goto err;
595 return 0; 595 return 0;
@@ -624,7 +624,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || 624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
625 (i > 0x58 && i != 0x5c)) 625 (i > 0x58 && i != 0x5c))
626 continue; 626 continue;
627 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 627 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
628 } 628 }
629 } 629 }
630 630
@@ -635,7 +635,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
635{ 635{
636 int ret = 0; 636 int ret = 0;
637 637
638 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 638 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
639 if (ret < 0) { 639 if (ret < 0) {
640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
641 return ret; 641 return ret;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index f7afa68d8c7f..a53e175c015a 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -652,7 +652,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
654 reg == AC97_CD) 654 reg == AC97_CD)
655 return soc_ac97_ops.read(codec->ac97, reg); 655 return soc_ac97_ops->read(codec->ac97, reg);
656 else { 656 else {
657 reg = reg >> 1; 657 reg = reg >> 1;
658 658
@@ -668,7 +668,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
668{ 668{
669 u16 *cache = codec->reg_cache; 669 u16 *cache = codec->reg_cache;
670 if (reg < 0x7c) 670 if (reg < 0x7c)
671 soc_ac97_ops.write(codec->ac97, reg, val); 671 soc_ac97_ops->write(codec->ac97, reg, val);
672 reg = reg >> 1; 672 reg = reg >> 1;
673 if (reg < (ARRAY_SIZE(wm9713_reg))) 673 if (reg < (ARRAY_SIZE(wm9713_reg)))
674 cache[reg] = val; 674 cache[reg] = val;
@@ -1095,15 +1095,15 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1095 1095
1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097{ 1097{
1098 if (try_warm && soc_ac97_ops.warm_reset) { 1098 if (try_warm && soc_ac97_ops->warm_reset) {
1099 soc_ac97_ops.warm_reset(codec->ac97); 1099 soc_ac97_ops->warm_reset(codec->ac97);
1100 if (ac97_read(codec, 0) == wm9713_reg[0]) 1100 if (ac97_read(codec, 0) == wm9713_reg[0])
1101 return 1; 1101 return 1;
1102 } 1102 }
1103 1103
1104 soc_ac97_ops.reset(codec->ac97); 1104 soc_ac97_ops->reset(codec->ac97);
1105 if (soc_ac97_ops.warm_reset) 1105 if (soc_ac97_ops->warm_reset)
1106 soc_ac97_ops.warm_reset(codec->ac97); 1106 soc_ac97_ops->warm_reset(codec->ac97);
1107 if (ac97_read(codec, 0) != wm9713_reg[0]) 1107 if (ac97_read(codec, 0) != wm9713_reg[0])
1108 return -EIO; 1108 return -EIO;
1109 return 0; 1109 return 0;
@@ -1180,7 +1180,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1181 i == AC97_EXTENDED_MSTATUS || i > 0x66) 1181 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1182 continue; 1182 continue;
1183 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 1183 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
1184 } 1184 }
1185 } 1185 }
1186 1186
@@ -1197,7 +1197,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1197 return -ENOMEM; 1197 return -ENOMEM;
1198 snd_soc_codec_set_drvdata(codec, wm9713); 1198 snd_soc_codec_set_drvdata(codec, wm9713);
1199 1199
1200 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1200 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
1201 if (ret < 0) 1201 if (ret < 0)
1202 goto codec_err; 1202 goto codec_err;
1203 1203
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 3470b649c0b2..ddba3fea39eb 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -21,6 +21,7 @@
21#include <linux/regmap.h> 21#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/workqueue.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
@@ -215,6 +216,36 @@ static struct {
215 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 216 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" },
216}; 217};
217 218
219struct wm_coeff_ctl_ops {
220 int (*xget)(struct snd_kcontrol *kcontrol,
221 struct snd_ctl_elem_value *ucontrol);
222 int (*xput)(struct snd_kcontrol *kcontrol,
223 struct snd_ctl_elem_value *ucontrol);
224 int (*xinfo)(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_info *uinfo);
226};
227
228struct wm_coeff {
229 struct device *dev;
230 struct list_head ctl_list;
231 struct regmap *regmap;
232};
233
234struct wm_coeff_ctl {
235 const char *name;
236 struct snd_card *card;
237 struct wm_adsp_alg_region region;
238 struct wm_coeff_ctl_ops ops;
239 struct wm_adsp *adsp;
240 void *private;
241 unsigned int enabled:1;
242 struct list_head list;
243 void *cache;
244 size_t len;
245 unsigned int set:1;
246 struct snd_kcontrol *kcontrol;
247};
248
218static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 249static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_value *ucontrol) 250 struct snd_ctl_elem_value *ucontrol)
220{ 251{
@@ -334,6 +365,181 @@ static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
334 } 365 }
335} 366}
336 367
368static int wm_coeff_info(struct snd_kcontrol *kcontrol,
369 struct snd_ctl_elem_info *uinfo)
370{
371 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
372
373 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
374 uinfo->count = ctl->len;
375 return 0;
376}
377
378static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
379 const void *buf, size_t len)
380{
381 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
382 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
383 struct wm_adsp_alg_region *region = &ctl->region;
384 const struct wm_adsp_region *mem;
385 struct wm_adsp *adsp = ctl->adsp;
386 void *scratch;
387 int ret;
388 unsigned int reg;
389
390 mem = wm_adsp_find_region(adsp, region->type);
391 if (!mem) {
392 adsp_err(adsp, "No base for region %x\n",
393 region->type);
394 return -EINVAL;
395 }
396
397 reg = ctl->region.base;
398 reg = wm_adsp_region_to_reg(mem, reg);
399
400 scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);
401 if (!scratch)
402 return -ENOMEM;
403
404 ret = regmap_raw_write(wm_coeff->regmap, reg, scratch,
405 ctl->len);
406 if (ret) {
407 adsp_err(adsp, "Failed to write %zu bytes to %x\n",
408 ctl->len, reg);
409 kfree(scratch);
410 return ret;
411 }
412
413 kfree(scratch);
414
415 return 0;
416}
417
418static int wm_coeff_put(struct snd_kcontrol *kcontrol,
419 struct snd_ctl_elem_value *ucontrol)
420{
421 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
422 char *p = ucontrol->value.bytes.data;
423
424 memcpy(ctl->cache, p, ctl->len);
425
426 if (!ctl->enabled) {
427 ctl->set = 1;
428 return 0;
429 }
430
431 return wm_coeff_write_control(kcontrol, p, ctl->len);
432}
433
434static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
435 void *buf, size_t len)
436{
437 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
438 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
439 struct wm_adsp_alg_region *region = &ctl->region;
440 const struct wm_adsp_region *mem;
441 struct wm_adsp *adsp = ctl->adsp;
442 void *scratch;
443 int ret;
444 unsigned int reg;
445
446 mem = wm_adsp_find_region(adsp, region->type);
447 if (!mem) {
448 adsp_err(adsp, "No base for region %x\n",
449 region->type);
450 return -EINVAL;
451 }
452
453 reg = ctl->region.base;
454 reg = wm_adsp_region_to_reg(mem, reg);
455
456 scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);
457 if (!scratch)
458 return -ENOMEM;
459
460 ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len);
461 if (ret) {
462 adsp_err(adsp, "Failed to read %zu bytes from %x\n",
463 ctl->len, reg);
464 kfree(scratch);
465 return ret;
466 }
467
468 memcpy(buf, scratch, ctl->len);
469 kfree(scratch);
470
471 return 0;
472}
473
474static int wm_coeff_get(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_value *ucontrol)
476{
477 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
478 char *p = ucontrol->value.bytes.data;
479
480 memcpy(p, ctl->cache, ctl->len);
481 return 0;
482}
483
484static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff,
485 struct wm_coeff_ctl *ctl,
486 const struct snd_kcontrol_new *kctl)
487{
488 int ret;
489 struct snd_kcontrol *kcontrol;
490
491 kcontrol = snd_ctl_new1(kctl, wm_coeff);
492 ret = snd_ctl_add(ctl->card, kcontrol);
493 if (ret < 0) {
494 dev_err(wm_coeff->dev, "Failed to add %s: %d\n",
495 kctl->name, ret);
496 return ret;
497 }
498 ctl->kcontrol = kcontrol;
499 return 0;
500}
501
502struct wmfw_ctl_work {
503 struct wm_coeff *wm_coeff;
504 struct wm_coeff_ctl *ctl;
505 struct work_struct work;
506};
507
508static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
509 struct wm_coeff_ctl *ctl)
510{
511 struct snd_kcontrol_new *kcontrol;
512 int ret;
513
514 if (!wm_coeff || !ctl || !ctl->name || !ctl->card)
515 return -EINVAL;
516
517 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
518 if (!kcontrol)
519 return -ENOMEM;
520 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
521
522 kcontrol->name = ctl->name;
523 kcontrol->info = wm_coeff_info;
524 kcontrol->get = wm_coeff_get;
525 kcontrol->put = wm_coeff_put;
526 kcontrol->private_value = (unsigned long)ctl;
527
528 ret = wm_coeff_add_kcontrol(wm_coeff,
529 ctl, kcontrol);
530 if (ret < 0)
531 goto err_kcontrol;
532
533 kfree(kcontrol);
534
535 list_add(&ctl->list, &wm_coeff->ctl_list);
536 return 0;
537
538err_kcontrol:
539 kfree(kcontrol);
540 return ret;
541}
542
337static int wm_adsp_load(struct wm_adsp *dsp) 543static int wm_adsp_load(struct wm_adsp *dsp)
338{ 544{
339 LIST_HEAD(buf_list); 545 LIST_HEAD(buf_list);
@@ -547,7 +753,157 @@ out:
547 return ret; 753 return ret;
548} 754}
549 755
550static int wm_adsp_setup_algs(struct wm_adsp *dsp) 756static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
757{
758 struct wm_coeff_ctl *ctl;
759 int ret;
760
761 list_for_each_entry(ctl, &wm_coeff->ctl_list,
762 list) {
763 if (!ctl->enabled || ctl->set)
764 continue;
765 ret = wm_coeff_read_control(ctl->kcontrol,
766 ctl->cache,
767 ctl->len);
768 if (ret < 0)
769 return ret;
770 }
771
772 return 0;
773}
774
775static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff)
776{
777 struct wm_coeff_ctl *ctl;
778 int ret;
779
780 list_for_each_entry(ctl, &wm_coeff->ctl_list,
781 list) {
782 if (!ctl->enabled)
783 continue;
784 if (ctl->set) {
785 ret = wm_coeff_write_control(ctl->kcontrol,
786 ctl->cache,
787 ctl->len);
788 if (ret < 0)
789 return ret;
790 }
791 }
792
793 return 0;
794}
795
796static void wm_adsp_ctl_work(struct work_struct *work)
797{
798 struct wmfw_ctl_work *ctl_work = container_of(work,
799 struct wmfw_ctl_work,
800 work);
801
802 wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl);
803 kfree(ctl_work);
804}
805
806static int wm_adsp_create_control(struct snd_soc_codec *codec,
807 const struct wm_adsp_alg_region *region)
808
809{
810 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
811 struct wm_coeff_ctl *ctl;
812 struct wmfw_ctl_work *ctl_work;
813 char *name;
814 char *region_name;
815 int ret;
816
817 name = kmalloc(PAGE_SIZE, GFP_KERNEL);
818 if (!name)
819 return -ENOMEM;
820
821 switch (region->type) {
822 case WMFW_ADSP1_PM:
823 region_name = "PM";
824 break;
825 case WMFW_ADSP1_DM:
826 region_name = "DM";
827 break;
828 case WMFW_ADSP2_XM:
829 region_name = "XM";
830 break;
831 case WMFW_ADSP2_YM:
832 region_name = "YM";
833 break;
834 case WMFW_ADSP1_ZM:
835 region_name = "ZM";
836 break;
837 default:
838 ret = -EINVAL;
839 goto err_name;
840 }
841
842 snprintf(name, PAGE_SIZE, "DSP%d %s %x",
843 dsp->num, region_name, region->alg);
844
845 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
846 list) {
847 if (!strcmp(ctl->name, name)) {
848 if (!ctl->enabled)
849 ctl->enabled = 1;
850 goto found;
851 }
852 }
853
854 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
855 if (!ctl) {
856 ret = -ENOMEM;
857 goto err_name;
858 }
859 ctl->region = *region;
860 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL);
861 if (!ctl->name) {
862 ret = -ENOMEM;
863 goto err_ctl;
864 }
865 ctl->enabled = 1;
866 ctl->set = 0;
867 ctl->ops.xget = wm_coeff_get;
868 ctl->ops.xput = wm_coeff_put;
869 ctl->card = codec->card->snd_card;
870 ctl->adsp = dsp;
871
872 ctl->len = region->len;
873 ctl->cache = kzalloc(ctl->len, GFP_KERNEL);
874 if (!ctl->cache) {
875 ret = -ENOMEM;
876 goto err_ctl_name;
877 }
878
879 ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL);
880 if (!ctl_work) {
881 ret = -ENOMEM;
882 goto err_ctl_cache;
883 }
884
885 ctl_work->wm_coeff = dsp->wm_coeff;
886 ctl_work->ctl = ctl;
887 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
888 schedule_work(&ctl_work->work);
889
890found:
891 kfree(name);
892
893 return 0;
894
895err_ctl_cache:
896 kfree(ctl->cache);
897err_ctl_name:
898 kfree(ctl->name);
899err_ctl:
900 kfree(ctl);
901err_name:
902 kfree(name);
903 return ret;
904}
905
906static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
551{ 907{
552 struct regmap *regmap = dsp->regmap; 908 struct regmap *regmap = dsp->regmap;
553 struct wmfw_adsp1_id_hdr adsp1_id; 909 struct wmfw_adsp1_id_hdr adsp1_id;
@@ -730,7 +1086,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
730 region->type = WMFW_ADSP1_DM; 1086 region->type = WMFW_ADSP1_DM;
731 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1087 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
732 region->base = be32_to_cpu(adsp1_alg[i].dm); 1088 region->base = be32_to_cpu(adsp1_alg[i].dm);
1089 region->len = 0;
733 list_add_tail(&region->list, &dsp->alg_regions); 1090 list_add_tail(&region->list, &dsp->alg_regions);
1091 if (i + 1 < algs) {
1092 region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
1093 region->len -= be32_to_cpu(adsp1_alg[i].dm);
1094 wm_adsp_create_control(codec, region);
1095 } else {
1096 adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1097 be32_to_cpu(adsp1_alg[i].alg.id));
1098 }
734 1099
735 region = kzalloc(sizeof(*region), GFP_KERNEL); 1100 region = kzalloc(sizeof(*region), GFP_KERNEL);
736 if (!region) 1101 if (!region)
@@ -738,7 +1103,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
738 region->type = WMFW_ADSP1_ZM; 1103 region->type = WMFW_ADSP1_ZM;
739 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1104 region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
740 region->base = be32_to_cpu(adsp1_alg[i].zm); 1105 region->base = be32_to_cpu(adsp1_alg[i].zm);
1106 region->len = 0;
741 list_add_tail(&region->list, &dsp->alg_regions); 1107 list_add_tail(&region->list, &dsp->alg_regions);
1108 if (i + 1 < algs) {
1109 region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
1110 region->len -= be32_to_cpu(adsp1_alg[i].zm);
1111 wm_adsp_create_control(codec, region);
1112 } else {
1113 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1114 be32_to_cpu(adsp1_alg[i].alg.id));
1115 }
742 break; 1116 break;
743 1117
744 case WMFW_ADSP2: 1118 case WMFW_ADSP2:
@@ -758,7 +1132,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
758 region->type = WMFW_ADSP2_XM; 1132 region->type = WMFW_ADSP2_XM;
759 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1133 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
760 region->base = be32_to_cpu(adsp2_alg[i].xm); 1134 region->base = be32_to_cpu(adsp2_alg[i].xm);
1135 region->len = 0;
761 list_add_tail(&region->list, &dsp->alg_regions); 1136 list_add_tail(&region->list, &dsp->alg_regions);
1137 if (i + 1 < algs) {
1138 region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
1139 region->len -= be32_to_cpu(adsp2_alg[i].xm);
1140 wm_adsp_create_control(codec, region);
1141 } else {
1142 adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1143 be32_to_cpu(adsp2_alg[i].alg.id));
1144 }
762 1145
763 region = kzalloc(sizeof(*region), GFP_KERNEL); 1146 region = kzalloc(sizeof(*region), GFP_KERNEL);
764 if (!region) 1147 if (!region)
@@ -766,7 +1149,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
766 region->type = WMFW_ADSP2_YM; 1149 region->type = WMFW_ADSP2_YM;
767 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1150 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
768 region->base = be32_to_cpu(adsp2_alg[i].ym); 1151 region->base = be32_to_cpu(adsp2_alg[i].ym);
1152 region->len = 0;
769 list_add_tail(&region->list, &dsp->alg_regions); 1153 list_add_tail(&region->list, &dsp->alg_regions);
1154 if (i + 1 < algs) {
1155 region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
1156 region->len -= be32_to_cpu(adsp2_alg[i].ym);
1157 wm_adsp_create_control(codec, region);
1158 } else {
1159 adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1160 be32_to_cpu(adsp2_alg[i].alg.id));
1161 }
770 1162
771 region = kzalloc(sizeof(*region), GFP_KERNEL); 1163 region = kzalloc(sizeof(*region), GFP_KERNEL);
772 if (!region) 1164 if (!region)
@@ -774,7 +1166,16 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp)
774 region->type = WMFW_ADSP2_ZM; 1166 region->type = WMFW_ADSP2_ZM;
775 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1167 region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
776 region->base = be32_to_cpu(adsp2_alg[i].zm); 1168 region->base = be32_to_cpu(adsp2_alg[i].zm);
1169 region->len = 0;
777 list_add_tail(&region->list, &dsp->alg_regions); 1170 list_add_tail(&region->list, &dsp->alg_regions);
1171 if (i + 1 < algs) {
1172 region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
1173 region->len -= be32_to_cpu(adsp2_alg[i].zm);
1174 wm_adsp_create_control(codec, region);
1175 } else {
1176 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1177 be32_to_cpu(adsp2_alg[i].alg.id));
1178 }
778 break; 1179 break;
779 } 1180 }
780 } 1181 }
@@ -986,6 +1387,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
986 struct snd_soc_codec *codec = w->codec; 1387 struct snd_soc_codec *codec = w->codec;
987 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1388 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
988 struct wm_adsp *dsp = &dsps[w->shift]; 1389 struct wm_adsp *dsp = &dsps[w->shift];
1390 struct wm_coeff_ctl *ctl;
989 int ret; 1391 int ret;
990 int val; 1392 int val;
991 1393
@@ -1023,7 +1425,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1023 if (ret != 0) 1425 if (ret != 0)
1024 goto err; 1426 goto err;
1025 1427
1026 ret = wm_adsp_setup_algs(dsp); 1428 ret = wm_adsp_setup_algs(dsp, codec);
1027 if (ret != 0) 1429 if (ret != 0)
1028 goto err; 1430 goto err;
1029 1431
@@ -1031,6 +1433,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1031 if (ret != 0) 1433 if (ret != 0)
1032 goto err; 1434 goto err;
1033 1435
1436 /* Initialize caches for enabled and unset controls */
1437 ret = wm_coeff_init_control_caches(dsp->wm_coeff);
1438 if (ret != 0)
1439 goto err;
1440
1441 /* Sync set controls */
1442 ret = wm_coeff_sync_controls(dsp->wm_coeff);
1443 if (ret != 0)
1444 goto err;
1445
1034 /* Start the core running */ 1446 /* Start the core running */
1035 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1447 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1036 ADSP1_CORE_ENA | ADSP1_START, 1448 ADSP1_CORE_ENA | ADSP1_START,
@@ -1047,6 +1459,11 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1047 1459
1048 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1460 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1049 ADSP1_SYS_ENA, 0); 1461 ADSP1_SYS_ENA, 0);
1462
1463 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
1464 list) {
1465 ctl->enabled = 0;
1466 }
1050 break; 1467 break;
1051 1468
1052 default: 1469 default:
@@ -1099,6 +1516,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1099 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1516 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
1100 struct wm_adsp *dsp = &dsps[w->shift]; 1517 struct wm_adsp *dsp = &dsps[w->shift];
1101 struct wm_adsp_alg_region *alg_region; 1518 struct wm_adsp_alg_region *alg_region;
1519 struct wm_coeff_ctl *ctl;
1102 unsigned int val; 1520 unsigned int val;
1103 int ret; 1521 int ret;
1104 1522
@@ -1164,7 +1582,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1164 if (ret != 0) 1582 if (ret != 0)
1165 goto err; 1583 goto err;
1166 1584
1167 ret = wm_adsp_setup_algs(dsp); 1585 ret = wm_adsp_setup_algs(dsp, codec);
1168 if (ret != 0) 1586 if (ret != 0)
1169 goto err; 1587 goto err;
1170 1588
@@ -1172,6 +1590,16 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1172 if (ret != 0) 1590 if (ret != 0)
1173 goto err; 1591 goto err;
1174 1592
1593 /* Initialize caches for enabled and unset controls */
1594 ret = wm_coeff_init_control_caches(dsp->wm_coeff);
1595 if (ret != 0)
1596 goto err;
1597
1598 /* Sync set controls */
1599 ret = wm_coeff_sync_controls(dsp->wm_coeff);
1600 if (ret != 0)
1601 goto err;
1602
1175 ret = regmap_update_bits(dsp->regmap, 1603 ret = regmap_update_bits(dsp->regmap,
1176 dsp->base + ADSP2_CONTROL, 1604 dsp->base + ADSP2_CONTROL,
1177 ADSP2_CORE_ENA | ADSP2_START, 1605 ADSP2_CORE_ENA | ADSP2_START,
@@ -1209,6 +1637,11 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1209 ret); 1637 ret);
1210 } 1638 }
1211 1639
1640 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list,
1641 list) {
1642 ctl->enabled = 0;
1643 }
1644
1212 while (!list_empty(&dsp->alg_regions)) { 1645 while (!list_empty(&dsp->alg_regions)) {
1213 alg_region = list_first_entry(&dsp->alg_regions, 1646 alg_region = list_first_entry(&dsp->alg_regions,
1214 struct wm_adsp_alg_region, 1647 struct wm_adsp_alg_region,
@@ -1247,36 +1680,48 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1247 1680
1248 INIT_LIST_HEAD(&adsp->alg_regions); 1681 INIT_LIST_HEAD(&adsp->alg_regions);
1249 1682
1683 adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff),
1684 GFP_KERNEL);
1685 if (!adsp->wm_coeff)
1686 return -ENOMEM;
1687 adsp->wm_coeff->regmap = adsp->regmap;
1688 adsp->wm_coeff->dev = adsp->dev;
1689 INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list);
1690
1250 if (dvfs) { 1691 if (dvfs) {
1251 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1692 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1252 if (IS_ERR(adsp->dvfs)) { 1693 if (IS_ERR(adsp->dvfs)) {
1253 ret = PTR_ERR(adsp->dvfs); 1694 ret = PTR_ERR(adsp->dvfs);
1254 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1695 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1255 return ret; 1696 goto out_coeff;
1256 } 1697 }
1257 1698
1258 ret = regulator_enable(adsp->dvfs); 1699 ret = regulator_enable(adsp->dvfs);
1259 if (ret != 0) { 1700 if (ret != 0) {
1260 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1701 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1261 ret); 1702 ret);
1262 return ret; 1703 goto out_coeff;
1263 } 1704 }
1264 1705
1265 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1706 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1266 if (ret != 0) { 1707 if (ret != 0) {
1267 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1708 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1268 ret); 1709 ret);
1269 return ret; 1710 goto out_coeff;
1270 } 1711 }
1271 1712
1272 ret = regulator_disable(adsp->dvfs); 1713 ret = regulator_disable(adsp->dvfs);
1273 if (ret != 0) { 1714 if (ret != 0) {
1274 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1715 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1275 ret); 1716 ret);
1276 return ret; 1717 goto out_coeff;
1277 } 1718 }
1278 } 1719 }
1279 1720
1280 return 0; 1721 return 0;
1722
1723out_coeff:
1724 kfree(adsp->wm_coeff);
1725 return ret;
1281} 1726}
1282EXPORT_SYMBOL_GPL(wm_adsp2_init); 1727EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index fea514627526..9f922c82536c 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -30,6 +30,7 @@ struct wm_adsp_alg_region {
30 unsigned int alg; 30 unsigned int alg;
31 int type; 31 int type;
32 unsigned int base; 32 unsigned int base;
33 size_t len;
33}; 34};
34 35
35struct wm_adsp { 36struct wm_adsp {
@@ -55,17 +56,17 @@ struct wm_adsp {
55 bool running; 56 bool running;
56 57
57 struct regulator *dvfs; 58 struct regulator *dvfs;
59
60 struct wm_coeff *wm_coeff;
58}; 61};
59 62
60#define WM_ADSP1(wname, num) \ 63#define WM_ADSP1(wname, num) \
61 { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 64 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
62 .shift = num, .event = wm_adsp1_event, \ 65 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
63 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
64 66
65#define WM_ADSP2(wname, num) \ 67#define WM_ADSP2(wname, num) \
66{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 68 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
67 .shift = num, .event = wm_adsp2_event, \ 69 wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
69 70
70extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; 71extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
71extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; 72extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index f5d81b948759..2d9e099415a5 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -693,10 +693,8 @@ void wm_hubs_update_class_w(struct snd_soc_codec *codec)
693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); 693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
694 694
695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \ 695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \
696{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 696 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
697 .info = snd_soc_info_volsw, \ 697 snd_soc_dapm_get_volsw, class_w_put_volsw)
698 .get = snd_soc_dapm_get_volsw, .put = class_w_put_volsw, \
699 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
700 698
701static int class_w_put_volsw(struct snd_kcontrol *kcontrol, 699static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol) 700 struct snd_ctl_elem_value *ucontrol)