aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/au1x/ac97c.c21
-rw-r--r--sound/soc/au1x/psc-ac97.c33
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c29
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c12
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c12
-rw-r--r--sound/soc/codecs/adau1701.c321
-rw-r--r--sound/soc/codecs/stac9766.c26
-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.h3
-rw-r--r--sound/soc/fsl/imx-ssi.c11
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c10
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c60
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c10
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.h3
-rw-r--r--sound/soc/samsung/ac97.c42
-rw-r--r--sound/soc/sh/hac.c8
-rw-r--r--sound/soc/soc-core.c17
-rw-r--r--sound/soc/tegra/tegra20_ac97.c67
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c17
23 files changed, 935 insertions, 285 deletions
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index 44b8dcecf571..d6f7694fcad4 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -179,13 +179,12 @@ static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)
179} 179}
180 180
181/* AC97 controller operations */ 181/* AC97 controller operations */
182struct snd_ac97_bus_ops soc_ac97_ops = { 182static struct snd_ac97_bus_ops ac97c_bus_ops = {
183 .read = au1xac97c_ac97_read, 183 .read = au1xac97c_ac97_read,
184 .write = au1xac97c_ac97_write, 184 .write = au1xac97c_ac97_write,
185 .reset = au1xac97c_ac97_cold_reset, 185 .reset = au1xac97c_ac97_cold_reset,
186 .warm_reset = au1xac97c_ac97_warm_reset, 186 .warm_reset = au1xac97c_ac97_warm_reset,
187}; 187};
188EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189 188
190static int alchemy_ac97c_startup(struct snd_pcm_substream *substream, 189static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
@@ -272,6 +271,10 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)
272 271
273 platform_set_drvdata(pdev, ctx); 272 platform_set_drvdata(pdev, ctx);
274 273
274 ret = snd_soc_set_ac97_ops(&ac97c_bus_ops);
275 if (ret)
276 return ret;
277
275 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component, 278 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
276 &au1xac97c_dai_driver, 1); 279 &au1xac97c_dai_driver, 1);
277 if (ret) 280 if (ret)
@@ -338,19 +341,7 @@ static struct platform_driver au1xac97c_driver = {
338 .remove = au1xac97c_drvremove, 341 .remove = au1xac97c_drvremove,
339}; 342};
340 343
341static int __init au1xac97c_load(void) 344module_platform_driver(&au1xac97c_driver);
342{
343 ac97c_workdata = NULL;
344 return platform_driver_register(&au1xac97c_driver);
345}
346
347static void __exit au1xac97c_unload(void)
348{
349 platform_driver_unregister(&au1xac97c_driver);
350}
351
352module_init(au1xac97c_load);
353module_exit(au1xac97c_unload);
354 345
355MODULE_LICENSE("GPL"); 346MODULE_LICENSE("GPL");
356MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver"); 347MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 8f1862aa7333..a822ab822bb7 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -201,13 +201,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
201} 201}
202 202
203/* AC97 controller operations */ 203/* AC97 controller operations */
204struct snd_ac97_bus_ops soc_ac97_ops = { 204static struct snd_ac97_bus_ops psc_ac97_ops = {
205 .read = au1xpsc_ac97_read, 205 .read = au1xpsc_ac97_read,
206 .write = au1xpsc_ac97_write, 206 .write = au1xpsc_ac97_write,
207 .reset = au1xpsc_ac97_cold_reset, 207 .reset = au1xpsc_ac97_cold_reset,
208 .warm_reset = au1xpsc_ac97_warm_reset, 208 .warm_reset = au1xpsc_ac97_warm_reset,
209}; 209};
210EXPORT_SYMBOL_GPL(soc_ac97_ops);
211 210
212static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, 211static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
213 struct snd_pcm_hw_params *params, 212 struct snd_pcm_hw_params *params,
@@ -383,15 +382,9 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
383 if (!iores) 382 if (!iores)
384 return -ENODEV; 383 return -ENODEV;
385 384
386 if (!devm_request_mem_region(&pdev->dev, iores->start, 385 wd->mmio = devm_ioremap_resource(&pdev->dev, iores);
387 resource_size(iores), 386 if (IS_ERR(wd->mmio))
388 pdev->name)) 387 return PTR_ERR(wd->mmio);
389 return -EBUSY;
390
391 wd->mmio = devm_ioremap(&pdev->dev, iores->start,
392 resource_size(iores));
393 if (!wd->mmio)
394 return -EBUSY;
395 388
396 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 389 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
397 if (!dmares) 390 if (!dmares)
@@ -423,6 +416,10 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
423 416
424 platform_set_drvdata(pdev, wd); 417 platform_set_drvdata(pdev, wd);
425 418
419 ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
420 if (ret)
421 return ret;
422
426 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, 423 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
427 &wd->dai_drv, 1); 424 &wd->dai_drv, 1);
428 if (ret) 425 if (ret)
@@ -503,19 +500,7 @@ static struct platform_driver au1xpsc_ac97_driver = {
503 .remove = au1xpsc_ac97_drvremove, 500 .remove = au1xpsc_ac97_drvremove,
504}; 501};
505 502
506static int __init au1xpsc_ac97_load(void) 503module_platform_driver(au1xpsc_ac97_driver);
507{
508 au1xpsc_ac97_workdata = NULL;
509 return platform_driver_register(&au1xpsc_ac97_driver);
510}
511
512static void __exit au1xpsc_ac97_unload(void)
513{
514 platform_driver_unregister(&au1xpsc_ac97_driver);
515}
516
517module_init(au1xpsc_ac97_load);
518module_exit(au1xpsc_ac97_unload);
519 504
520MODULE_LICENSE("GPL"); 505MODULE_LICENSE("GPL");
521MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 506MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 490217325975..c5af677ba49c 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -198,13 +198,12 @@ static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
198#endif 198#endif
199} 199}
200 200
201struct snd_ac97_bus_ops soc_ac97_ops = { 201static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
202 .read = bf5xx_ac97_read, 202 .read = bf5xx_ac97_read,
203 .write = bf5xx_ac97_write, 203 .write = bf5xx_ac97_write,
204 .warm_reset = bf5xx_ac97_warm_reset, 204 .warm_reset = bf5xx_ac97_warm_reset,
205 .reset = bf5xx_ac97_cold_reset, 205 .reset = bf5xx_ac97_cold_reset,
206}; 206};
207EXPORT_SYMBOL_GPL(soc_ac97_ops);
208 207
209#ifdef CONFIG_PM 208#ifdef CONFIG_PM
210static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) 209static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
@@ -293,13 +292,14 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
293 292
294#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 293#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
295 /* Request PB3 as reset pin */ 294 /* Request PB3 as reset pin */
296 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { 295 ret = devm_gpio_request_one(&pdev->dev,
297 pr_err("Failed to request GPIO_%d for reset\n", 296 CONFIG_SND_BF5XX_RESET_GPIO_NUM,
298 CONFIG_SND_BF5XX_RESET_GPIO_NUM); 297 GPIOF_OUT_INIT_HIGH, "SND_AD198x RESET") {
299 ret = -1; 298 dev_err(&pdev->dev,
299 "Failed to request GPIO_%d for reset: %d\n",
300 CONFIG_SND_BF5XX_RESET_GPIO_NUM, ret);
300 goto gpio_err; 301 goto gpio_err;
301 } 302 }
302 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
303#endif 303#endif
304 304
305 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame), 305 sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame),
@@ -335,6 +335,12 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
335 goto sport_config_err; 335 goto sport_config_err;
336 } 336 }
337 337
338 ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops);
339 if (ret != 0) {
340 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
341 goto sport_config_err;
342 }
343
338 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component, 344 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
339 &bfin_ac97_dai, 1); 345 &bfin_ac97_dai, 1);
340 if (ret) { 346 if (ret) {
@@ -349,10 +355,7 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
349sport_config_err: 355sport_config_err:
350 sport_done(sport_handle); 356 sport_done(sport_handle);
351sport_err: 357sport_err:
352#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 358 snd_soc_set_ac97_ops(NULL);
353 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
354gpio_err:
355#endif
356 359
357 return ret; 360 return ret;
358} 361}
@@ -363,9 +366,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)
363 366
364 snd_soc_unregister_component(&pdev->dev); 367 snd_soc_unregister_component(&pdev->dev);
365 sport_done(sport_handle); 368 sport_done(sport_handle);
366#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 369 snd_soc_set_ac97_ops(NULL);
367 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
368#endif
369 370
370 return 0; 371 return 0;
371} 372}
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index 7798fbd5e81d..4bc9490e2c84 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -237,13 +237,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
237 return IRQ_HANDLED; 237 return IRQ_HANDLED;
238} 238}
239 239
240struct snd_ac97_bus_ops soc_ac97_ops = { 240static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
241 .read = ep93xx_ac97_read, 241 .read = ep93xx_ac97_read,
242 .write = ep93xx_ac97_write, 242 .write = ep93xx_ac97_write,
243 .reset = ep93xx_ac97_cold_reset, 243 .reset = ep93xx_ac97_cold_reset,
244 .warm_reset = ep93xx_ac97_warm_reset, 244 .warm_reset = ep93xx_ac97_warm_reset,
245}; 245};
246EXPORT_SYMBOL_GPL(soc_ac97_ops);
247 246
248static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, 247static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
249 int cmd, struct snd_soc_dai *dai) 248 int cmd, struct snd_soc_dai *dai)
@@ -395,6 +394,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
395 ep93xx_ac97_info = info; 394 ep93xx_ac97_info = info;
396 platform_set_drvdata(pdev, info); 395 platform_set_drvdata(pdev, info);
397 396
397 ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
398 if (ret)
399 goto fail;
400
398 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, 401 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
399 &ep93xx_ac97_dai, 1); 402 &ep93xx_ac97_dai, 1);
400 if (ret) 403 if (ret)
@@ -405,7 +408,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
405fail: 408fail:
406 platform_set_drvdata(pdev, NULL); 409 platform_set_drvdata(pdev, NULL);
407 ep93xx_ac97_info = NULL; 410 ep93xx_ac97_info = NULL;
408 dev_set_drvdata(&pdev->dev, NULL); 411 snd_soc_set_ac97_ops(NULL);
409 return ret; 412 return ret;
410} 413}
411 414
@@ -420,7 +423,8 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
420 423
421 platform_set_drvdata(pdev, NULL); 424 platform_set_drvdata(pdev, NULL);
422 ep93xx_ac97_info = NULL; 425 ep93xx_ac97_info = NULL;
423 dev_set_drvdata(&pdev->dev, NULL); 426
427 snd_soc_set_ac97_ops(NULL);
424 428
425 return 0; 429 return 0;
426} 430}
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..d1124a5b3471 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) 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)
142{ 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;
175 211
176 ret = snd_soc_cache_read(codec, reg, &value); 212 send_buf[0] = reg >> 8;
177 if (ret) 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;
224
225 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
226 if (ret < 0)
178 return ret; 227 return ret;
228 else if (ret != ARRAY_SIZE(msgs))
229 return -EIO;
179 230
180 return value; 231 *value = 0;
232
233 for (i = 0; i < size; i++)
234 *value |= recv_buf[i] << (i * 8);
235
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,
@@ -221,7 +334,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec,
221 mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK; 334 mask |= ADAU1701_SEROCTL_MSB_DEALY_MASK;
222 } 335 }
223 336
224 snd_soc_update_bits(codec, ADAU1701_SEROCTL, mask, val); 337 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, mask, val);
225 338
226 return 0; 339 return 0;
227} 340}
@@ -249,7 +362,7 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
249 return -EINVAL; 362 return -EINVAL;
250 } 363 }
251 364
252 snd_soc_update_bits(codec, ADAU1701_SERICTL, 365 regmap_update_bits(adau1701->regmap, ADAU1701_SERICTL,
253 ADAU1701_SERICTL_MODE_MASK, val); 366 ADAU1701_SERICTL_MODE_MASK, val);
254 367
255 return 0; 368 return 0;
@@ -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:
@@ -276,7 +403,7 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
276 return -EINVAL; 403 return -EINVAL;
277 } 404 }
278 405
279 snd_soc_update_bits(codec, ADAU1701_DSPCTRL, 406 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL,
280 ADAU1701_DSPCTRL_SR_MASK, val); 407 ADAU1701_DSPCTRL_SR_MASK, val);
281 408
282 format = params_format(params); 409 format = params_format(params);
@@ -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;
@@ -363,6 +490,7 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
363 enum snd_soc_bias_level level) 490 enum snd_soc_bias_level level)
364{ 491{
365 unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD; 492 unsigned int mask = ADAU1701_AUXNPOW_VBPD | ADAU1701_AUXNPOW_VRPD;
493 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
366 494
367 switch (level) { 495 switch (level) {
368 case SND_SOC_BIAS_ON: 496 case SND_SOC_BIAS_ON:
@@ -371,11 +499,13 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
371 break; 499 break;
372 case SND_SOC_BIAS_STANDBY: 500 case SND_SOC_BIAS_STANDBY:
373 /* Enable VREF and VREF buffer */ 501 /* Enable VREF and VREF buffer */
374 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, 0x00); 502 regmap_update_bits(adau1701->regmap,
503 ADAU1701_AUXNPOW, mask, 0x00);
375 break; 504 break;
376 case SND_SOC_BIAS_OFF: 505 case SND_SOC_BIAS_OFF:
377 /* Disable VREF and VREF buffer */ 506 /* Disable VREF and VREF buffer */
378 snd_soc_update_bits(codec, ADAU1701_AUXNPOW, mask, mask); 507 regmap_update_bits(adau1701->regmap,
508 ADAU1701_AUXNPOW, mask, mask);
379 break; 509 break;
380 } 510 }
381 511
@@ -387,6 +517,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
387{ 517{
388 struct snd_soc_codec *codec = dai->codec; 518 struct snd_soc_codec *codec = dai->codec;
389 unsigned int mask = ADAU1701_DSPCTRL_DAM; 519 unsigned int mask = ADAU1701_DSPCTRL_DAM;
520 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
390 unsigned int val; 521 unsigned int val;
391 522
392 if (mute) 523 if (mute)
@@ -394,7 +525,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute)
394 else 525 else
395 val = mask; 526 val = mask;
396 527
397 snd_soc_update_bits(codec, ADAU1701_DSPCTRL, mask, val); 528 regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, mask, val);
398 529
399 return 0; 530 return 0;
400} 531}
@@ -403,6 +534,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
403 int source, unsigned int freq, int dir) 534 int source, unsigned int freq, int dir)
404{ 535{
405 unsigned int val; 536 unsigned int val;
537 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
406 538
407 switch (clk_id) { 539 switch (clk_id) {
408 case ADAU1701_CLK_SRC_OSC: 540 case ADAU1701_CLK_SRC_OSC:
@@ -415,7 +547,9 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
415 return -EINVAL; 547 return -EINVAL;
416 } 548 }
417 549
418 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val); 550 regmap_update_bits(adau1701->regmap, ADAU1701_OSCIPOW,
551 ADAU1701_OSCIPOW_OPD, val);
552 adau1701->sysclk = freq;
419 553
420 return 0; 554 return 0;
421} 555}
@@ -452,18 +586,45 @@ static struct snd_soc_dai_driver adau1701_dai = {
452 .symmetric_rates = 1, 586 .symmetric_rates = 1,
453}; 587};
454 588
589#ifdef CONFIG_OF
590static const struct of_device_id adau1701_dt_ids[] = {
591 { .compatible = "adi,adau1701", },
592 { }
593};
594MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
595#endif
596
455static int adau1701_probe(struct snd_soc_codec *codec) 597static int adau1701_probe(struct snd_soc_codec *codec)
456{ 598{
457 int ret; 599 int i, ret;
600 unsigned int val;
601 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
602
603 /*
604 * Let the pll_clkdiv variable default to something that won't happen
605 * at runtime. That way, we can postpone the firmware download from
606 * adau1701_reset() to a point in time when we know the correct PLL
607 * mode parameters.
608 */
609 adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
610
611 /* initalize with pre-configured pll mode settings */
612 ret = adau1701_reset(codec, adau1701->pll_clkdiv);
613 if (ret < 0)
614 return ret;
615
616 /* set up pin config */
617 val = 0;
618 for (i = 0; i < 6; i++)
619 val |= adau1701->pin_config[i] << (i * 4);
458 620
459 codec->control_data = to_i2c_client(codec->dev); 621 regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val);
460 622
461 ret = adau1701_load_firmware(codec); 623 val = 0;
462 if (ret) 624 for (i = 0; i < 6; i++)
463 dev_warn(codec->dev, "Failed to load firmware\n"); 625 val |= adau1701->pin_config[i + 6] << (i * 4);
464 626
465 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); 627 regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
466 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR);
467 628
468 return 0; 629 return 0;
469} 630}
@@ -473,9 +634,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
473 .set_bias_level = adau1701_set_bias_level, 634 .set_bias_level = adau1701_set_bias_level,
474 .idle_bias_off = true, 635 .idle_bias_off = true,
475 636
476 .reg_cache_size = ADAU1701_NUM_REGS,
477 .reg_word_size = sizeof(u16),
478
479 .controls = adau1701_controls, 637 .controls = adau1701_controls,
480 .num_controls = ARRAY_SIZE(adau1701_controls), 638 .num_controls = ARRAY_SIZE(adau1701_controls),
481 .dapm_widgets = adau1701_dapm_widgets, 639 .dapm_widgets = adau1701_dapm_widgets,
@@ -483,22 +641,86 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
483 .dapm_routes = adau1701_dapm_routes, 641 .dapm_routes = adau1701_dapm_routes,
484 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 642 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
485 643
486 .write = adau1701_write,
487 .read = adau1701_read,
488
489 .set_sysclk = adau1701_set_sysclk, 644 .set_sysclk = adau1701_set_sysclk,
490}; 645};
491 646
647static const struct regmap_config adau1701_regmap = {
648 .reg_bits = 16,
649 .val_bits = 32,
650 .max_register = ADAU1701_MAX_REGISTER,
651 .cache_type = REGCACHE_RBTREE,
652 .volatile_reg = adau1701_volatile_reg,
653 .reg_write = adau1701_reg_write,
654 .reg_read = adau1701_reg_read,
655};
656
492static int adau1701_i2c_probe(struct i2c_client *client, 657static int adau1701_i2c_probe(struct i2c_client *client,
493 const struct i2c_device_id *id) 658 const struct i2c_device_id *id)
494{ 659{
495 struct adau1701 *adau1701; 660 struct adau1701 *adau1701;
661 struct device *dev = &client->dev;
662 int gpio_nreset = -EINVAL;
663 int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
496 int ret; 664 int ret;
497 665
498 adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); 666 adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
499 if (!adau1701) 667 if (!adau1701)
500 return -ENOMEM; 668 return -ENOMEM;
501 669
670 adau1701->regmap = devm_regmap_init(dev, NULL, client,
671 &adau1701_regmap);
672 if (IS_ERR(adau1701->regmap))
673 return PTR_ERR(adau1701->regmap);
674
675 if (dev->of_node) {
676 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
677 if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
678 return gpio_nreset;
679
680 gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
681 "adi,pll-mode-gpios", 0);
682 if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
683 return gpio_pll_mode[0];
684
685 gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
686 "adi,pll-mode-gpios", 1);
687 if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
688 return gpio_pll_mode[1];
689
690 of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
691 &adau1701->pll_clkdiv);
692
693 of_property_read_u8_array(dev->of_node, "adi,pin-config",
694 adau1701->pin_config,
695 ARRAY_SIZE(adau1701->pin_config));
696 }
697
698 if (gpio_is_valid(gpio_nreset)) {
699 ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
700 "ADAU1701 Reset");
701 if (ret < 0)
702 return ret;
703 }
704
705 if (gpio_is_valid(gpio_pll_mode[0]) &&
706 gpio_is_valid(gpio_pll_mode[1])) {
707 ret = devm_gpio_request_one(dev, gpio_pll_mode[0],
708 GPIOF_OUT_INIT_LOW,
709 "ADAU1701 PLL mode 0");
710 if (ret < 0)
711 return ret;
712
713 ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
714 GPIOF_OUT_INIT_LOW,
715 "ADAU1701 PLL mode 1");
716 if (ret < 0)
717 return ret;
718 }
719
720 adau1701->gpio_nreset = gpio_nreset;
721 adau1701->gpio_pll_mode[0] = gpio_pll_mode[0];
722 adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
723
502 i2c_set_clientdata(client, adau1701); 724 i2c_set_clientdata(client, adau1701);
503 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, 725 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
504 &adau1701_dai, 1); 726 &adau1701_dai, 1);
@@ -521,6 +743,7 @@ static struct i2c_driver adau1701_i2c_driver = {
521 .driver = { 743 .driver = {
522 .name = "adau1701", 744 .name = "adau1701",
523 .owner = THIS_MODULE, 745 .owner = THIS_MODULE,
746 .of_match_table = of_match_ptr(adau1701_dt_ids),
524 }, 747 },
525 .probe = adau1701_i2c_probe, 748 .probe = adau1701_i2c_probe,
526 .remove = adau1701_i2c_remove, 749 .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/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 36533eac420e..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,6 +56,8 @@ 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) \
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index c6fa03e2114a..bd40849454a8 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -501,13 +501,12 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
501 imx_ssi_ac97_read(ac97, 0); 501 imx_ssi_ac97_read(ac97, 0);
502} 502}
503 503
504struct snd_ac97_bus_ops soc_ac97_ops = { 504static struct snd_ac97_bus_ops imx_ssi_ac97_ops = {
505 .read = imx_ssi_ac97_read, 505 .read = imx_ssi_ac97_read,
506 .write = imx_ssi_ac97_write, 506 .write = imx_ssi_ac97_write,
507 .reset = imx_ssi_ac97_reset, 507 .reset = imx_ssi_ac97_reset,
508 .warm_reset = imx_ssi_ac97_warm_reset 508 .warm_reset = imx_ssi_ac97_warm_reset
509}; 509};
510EXPORT_SYMBOL_GPL(soc_ac97_ops);
511 510
512static int imx_ssi_probe(struct platform_device *pdev) 511static int imx_ssi_probe(struct platform_device *pdev)
513{ 512{
@@ -583,6 +582,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
583 582
584 platform_set_drvdata(pdev, ssi); 583 platform_set_drvdata(pdev, ssi);
585 584
585 ret = snd_soc_set_ac97_ops(&imx_ssi_ac97_ops);
586 if (ret != 0) {
587 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
588 goto failed_register;
589 }
590
586 ret = snd_soc_register_component(&pdev->dev, &imx_component, 591 ret = snd_soc_register_component(&pdev->dev, &imx_component,
587 dai, 1); 592 dai, 1);
588 if (ret) { 593 if (ret) {
@@ -630,6 +635,7 @@ failed_register:
630 release_mem_region(res->start, resource_size(res)); 635 release_mem_region(res->start, resource_size(res));
631 clk_disable_unprepare(ssi->clk); 636 clk_disable_unprepare(ssi->clk);
632failed_clk: 637failed_clk:
638 snd_soc_set_ac97_ops(NULL);
633 639
634 return ret; 640 return ret;
635} 641}
@@ -649,6 +655,7 @@ static int imx_ssi_remove(struct platform_device *pdev)
649 655
650 release_mem_region(res->start, resource_size(res)); 656 release_mem_region(res->start, resource_size(res));
651 clk_disable_unprepare(ssi->clk); 657 clk_disable_unprepare(ssi->clk);
658 snd_soc_set_ac97_ops(NULL);
652 659
653 return 0; 660 return 0;
654} 661}
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 4141b35ef0bb..3ef7a0c92efa 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -131,13 +131,12 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
131 psc_ac97_warm_reset(ac97); 131 psc_ac97_warm_reset(ac97);
132} 132}
133 133
134struct snd_ac97_bus_ops soc_ac97_ops = { 134static struct snd_ac97_bus_ops psc_ac97_ops = {
135 .read = psc_ac97_read, 135 .read = psc_ac97_read,
136 .write = psc_ac97_write, 136 .write = psc_ac97_write,
137 .reset = psc_ac97_cold_reset, 137 .reset = psc_ac97_cold_reset,
138 .warm_reset = psc_ac97_warm_reset, 138 .warm_reset = psc_ac97_warm_reset,
139}; 139};
140EXPORT_SYMBOL_GPL(soc_ac97_ops);
141 140
142static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, 141static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params, 142 struct snd_pcm_hw_params *params,
@@ -290,6 +289,12 @@ static int psc_ac97_of_probe(struct platform_device *op)
290 if (rc != 0) 289 if (rc != 0)
291 return rc; 290 return rc;
292 291
292 rc = snd_soc_set_ac97_ops(&psc_ac97_ops);
293 if (rc != 0) {
294 dev_err(&op->dev, "Failed to set AC'97 ops: %d\n", ret);
295 return rc;
296 }
297
293 rc = snd_soc_register_component(&op->dev, &psc_ac97_component, 298 rc = snd_soc_register_component(&op->dev, &psc_ac97_component,
294 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); 299 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
295 if (rc != 0) { 300 if (rc != 0) {
@@ -318,6 +323,7 @@ static int psc_ac97_of_remove(struct platform_device *op)
318{ 323{
319 mpc5200_audio_dma_destroy(op); 324 mpc5200_audio_dma_destroy(op);
320 snd_soc_unregister_component(&op->dev); 325 snd_soc_unregister_component(&op->dev);
326 snd_soc_set_ac97_ops(NULL);
321 return 0; 327 return 0;
322} 328}
323 329
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index fe3285ceaf5b..f4c2417a8730 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -197,13 +197,12 @@ static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)
197} 197}
198 198
199/* AC97 controller operations */ 199/* AC97 controller operations */
200struct snd_ac97_bus_ops soc_ac97_ops = { 200static struct snd_ac97_bus_ops nuc900_ac97_ops = {
201 .read = nuc900_ac97_read, 201 .read = nuc900_ac97_read,
202 .write = nuc900_ac97_write, 202 .write = nuc900_ac97_write,
203 .reset = nuc900_ac97_cold_reset, 203 .reset = nuc900_ac97_cold_reset,
204 .warm_reset = nuc900_ac97_warm_reset, 204 .warm_reset = nuc900_ac97_warm_reset,
205} 205};
206EXPORT_SYMBOL_GPL(soc_ac97_ops);
207 206
208static int nuc900_ac97_trigger(struct snd_pcm_substream *substream, 207static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
209 int cmd, struct snd_soc_dai *dai) 208 int cmd, struct snd_soc_dai *dai)
@@ -326,64 +325,52 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
326 if (nuc900_ac97_data) 325 if (nuc900_ac97_data)
327 return -EBUSY; 326 return -EBUSY;
328 327
329 nuc900_audio = kzalloc(sizeof(struct nuc900_audio), GFP_KERNEL); 328 nuc900_audio = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_audio),
329 GFP_KERNEL);
330 if (!nuc900_audio) 330 if (!nuc900_audio)
331 return -ENOMEM; 331 return -ENOMEM;
332 332
333 spin_lock_init(&nuc900_audio->lock); 333 spin_lock_init(&nuc900_audio->lock);
334 334
335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336 if (!nuc900_audio->res) { 336 if (!nuc900_audio->res)
337 ret = -ENODEV; 337 return ret;
338 goto out0;
339 }
340
341 if (!request_mem_region(nuc900_audio->res->start,
342 resource_size(nuc900_audio->res), pdev->name)) {
343 ret = -EBUSY;
344 goto out0;
345 }
346 338
347 nuc900_audio->mmio = ioremap(nuc900_audio->res->start, 339 nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev,
348 resource_size(nuc900_audio->res)); 340 nuc900_audio->res);
349 if (!nuc900_audio->mmio) { 341 if (IS_ERR(nuc900_audio->mmio))
350 ret = -ENOMEM; 342 return PTR_ERR(nuc900_audio->mmio);
351 goto out1;
352 }
353 343
354 nuc900_audio->clk = clk_get(&pdev->dev, NULL); 344 nuc900_audio->clk = devm_clk_get(&pdev->dev, NULL);
355 if (IS_ERR(nuc900_audio->clk)) { 345 if (IS_ERR(nuc900_audio->clk)) {
356 ret = PTR_ERR(nuc900_audio->clk); 346 ret = PTR_ERR(nuc900_audio->clk);
357 goto out2; 347 goto out;
358 } 348 }
359 349
360 nuc900_audio->irq_num = platform_get_irq(pdev, 0); 350 nuc900_audio->irq_num = platform_get_irq(pdev, 0);
361 if (!nuc900_audio->irq_num) { 351 if (!nuc900_audio->irq_num) {
362 ret = -EBUSY; 352 ret = -EBUSY;
363 goto out3; 353 goto out;
364 } 354 }
365 355
366 nuc900_ac97_data = nuc900_audio; 356 nuc900_ac97_data = nuc900_audio;
367 357
358 ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops);
359 if (ret)
360 goto out;
361
368 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, 362 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
369 &nuc900_ac97_dai, 1); 363 &nuc900_ac97_dai, 1);
370 if (ret) 364 if (ret)
371 goto out3; 365 goto out;
372 366
373 /* enbale ac97 multifunction pin */ 367 /* enbale ac97 multifunction pin */
374 mfp_set_groupg(nuc900_audio->dev, NULL); 368 mfp_set_groupg(nuc900_audio->dev, NULL);
375 369
376 return 0; 370 return 0;
377 371
378out3: 372out:
379 clk_put(nuc900_audio->clk); 373 snd_soc_set_ac97_ops(NULL);
380out2:
381 iounmap(nuc900_audio->mmio);
382out1:
383 release_mem_region(nuc900_audio->res->start,
384 resource_size(nuc900_audio->res));
385out0:
386 kfree(nuc900_audio);
387 return ret; 374 return ret;
388} 375}
389 376
@@ -391,13 +378,8 @@ static int nuc900_ac97_drvremove(struct platform_device *pdev)
391{ 378{
392 snd_soc_unregister_component(&pdev->dev); 379 snd_soc_unregister_component(&pdev->dev);
393 380
394 clk_put(nuc900_ac97_data->clk);
395 iounmap(nuc900_ac97_data->mmio);
396 release_mem_region(nuc900_ac97_data->res->start,
397 resource_size(nuc900_ac97_data->res));
398
399 kfree(nuc900_ac97_data);
400 nuc900_ac97_data = NULL; 381 nuc900_ac97_data = NULL;
382 snd_soc_set_ac97_ops(NULL);
401 383
402 return 0; 384 return 0;
403} 385}
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 57ea8e6c5488..1475515712e6 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -41,13 +41,12 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)
41 pxa2xx_ac97_finish_reset(ac97); 41 pxa2xx_ac97_finish_reset(ac97);
42} 42}
43 43
44struct snd_ac97_bus_ops soc_ac97_ops = { 44static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
45 .read = pxa2xx_ac97_read, 45 .read = pxa2xx_ac97_read,
46 .write = pxa2xx_ac97_write, 46 .write = pxa2xx_ac97_write,
47 .warm_reset = pxa2xx_ac97_warm_reset, 47 .warm_reset = pxa2xx_ac97_warm_reset,
48 .reset = pxa2xx_ac97_cold_reset, 48 .reset = pxa2xx_ac97_cold_reset,
49}; 49};
50EXPORT_SYMBOL_GPL(soc_ac97_ops);
51 50
52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 51static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
53 .name = "AC97 PCM Stereo out", 52 .name = "AC97 PCM Stereo out",
@@ -239,11 +238,17 @@ static const struct snd_soc_component_driver pxa_ac97_component = {
239 238
240static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) 239static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
241{ 240{
241 int ret;
242
242 if (pdev->id != -1) { 243 if (pdev->id != -1) {
243 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n"); 244 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
244 return -ENXIO; 245 return -ENXIO;
245 } 246 }
246 247
248 ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
249 if (ret != 0)
250 return ret;
251
247 /* Punt most of the init to the SoC probe; we may need the machine 252 /* Punt most of the init to the SoC probe; we may need the machine
248 * driver to do interesting things with the clocking to get us up 253 * driver to do interesting things with the clocking to get us up
249 * and running. 254 * and running.
@@ -255,6 +260,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
255static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) 260static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
256{ 261{
257 snd_soc_unregister_component(&pdev->dev); 262 snd_soc_unregister_component(&pdev->dev);
263 snd_soc_set_ac97_ops(NULL);
258 return 0; 264 return 0;
259} 265}
260 266
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index eda891e6f31b..a49c21ba3842 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,7 +14,4 @@
14#define PXA2XX_DAI_AC97_AUX 1 14#define PXA2XX_DAI_AC97_AUX 1
15#define PXA2XX_DAI_AC97_MIC 2 15#define PXA2XX_DAI_AC97_MIC 2
16 16
17/* platform data */
18extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
19
20#endif 17#endif
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index cb88ead98917..2dd623fa3882 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -214,13 +214,12 @@ static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
214 return IRQ_HANDLED; 214 return IRQ_HANDLED;
215} 215}
216 216
217struct snd_ac97_bus_ops soc_ac97_ops = { 217static struct snd_ac97_bus_ops s3c_ac97_ops = {
218 .read = s3c_ac97_read, 218 .read = s3c_ac97_read,
219 .write = s3c_ac97_write, 219 .write = s3c_ac97_write,
220 .warm_reset = s3c_ac97_warm_reset, 220 .warm_reset = s3c_ac97_warm_reset,
221 .reset = s3c_ac97_cold_reset, 221 .reset = s3c_ac97_cold_reset,
222}; 222};
223EXPORT_SYMBOL_GPL(soc_ac97_ops);
224 223
225static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, 224static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
226 struct snd_pcm_hw_params *params, 225 struct snd_pcm_hw_params *params,
@@ -417,11 +416,9 @@ static int s3c_ac97_probe(struct platform_device *pdev)
417 return -ENXIO; 416 return -ENXIO;
418 } 417 }
419 418
420 if (!request_mem_region(mem_res->start, 419 s3c_ac97.regs = devm_ioremap_resource(&pdev->dev, mem_res);
421 resource_size(mem_res), "ac97")) { 420 if (IS_ERR(s3c_ac97.regs))
422 dev_err(&pdev->dev, "Unable to request register region\n"); 421 return PTR_ERR(s3c_ac97.regs);
423 return -EBUSY;
424 }
425 422
426 s3c_ac97_pcm_out.channel = dmatx_res->start; 423 s3c_ac97_pcm_out.channel = dmatx_res->start;
427 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; 424 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
@@ -433,14 +430,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
433 init_completion(&s3c_ac97.done); 430 init_completion(&s3c_ac97.done);
434 mutex_init(&s3c_ac97.lock); 431 mutex_init(&s3c_ac97.lock);
435 432
436 s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); 433 s3c_ac97.ac97_clk = devm_clk_get(&pdev->dev, "ac97");
437 if (s3c_ac97.regs == NULL) {
438 dev_err(&pdev->dev, "Unable to ioremap register region\n");
439 ret = -ENXIO;
440 goto err1;
441 }
442
443 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
444 if (IS_ERR(s3c_ac97.ac97_clk)) { 434 if (IS_ERR(s3c_ac97.ac97_clk)) {
445 dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); 435 dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
446 ret = -ENODEV; 436 ret = -ENODEV;
@@ -461,6 +451,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
461 goto err4; 451 goto err4;
462 } 452 }
463 453
454 ret = snd_soc_set_ac97_ops(&s3c_ac97_ops);
455 if (ret != 0) {
456 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
457 goto err4;
458 }
459
464 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, 460 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
465 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); 461 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
466 if (ret) 462 if (ret)
@@ -480,18 +476,14 @@ err5:
480err4: 476err4:
481err3: 477err3:
482 clk_disable_unprepare(s3c_ac97.ac97_clk); 478 clk_disable_unprepare(s3c_ac97.ac97_clk);
483 clk_put(s3c_ac97.ac97_clk);
484err2: 479err2:
485 iounmap(s3c_ac97.regs); 480 snd_soc_set_ac97_ops(NULL);
486err1:
487 release_mem_region(mem_res->start, resource_size(mem_res));
488
489 return ret; 481 return ret;
490} 482}
491 483
492static int s3c_ac97_remove(struct platform_device *pdev) 484static int s3c_ac97_remove(struct platform_device *pdev)
493{ 485{
494 struct resource *mem_res, *irq_res; 486 struct resource *irq_res;
495 487
496 asoc_dma_platform_unregister(&pdev->dev); 488 asoc_dma_platform_unregister(&pdev->dev);
497 snd_soc_unregister_component(&pdev->dev); 489 snd_soc_unregister_component(&pdev->dev);
@@ -501,13 +493,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
501 free_irq(irq_res->start, NULL); 493 free_irq(irq_res->start, NULL);
502 494
503 clk_disable_unprepare(s3c_ac97.ac97_clk); 495 clk_disable_unprepare(s3c_ac97.ac97_clk);
504 clk_put(s3c_ac97.ac97_clk); 496 snd_soc_set_ac97_ops(NULL);
505
506 iounmap(s3c_ac97.regs);
507
508 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
509 if (mem_res)
510 release_mem_region(mem_res->start, resource_size(mem_res));
511 497
512 return 0; 498 return 0;
513} 499}
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index af19f77b7bf0..0af2e4dfd139 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -227,13 +227,12 @@ static void hac_ac97_coldrst(struct snd_ac97 *ac97)
227 hac_ac97_warmrst(ac97); 227 hac_ac97_warmrst(ac97);
228} 228}
229 229
230struct snd_ac97_bus_ops soc_ac97_ops = { 230static struct snd_ac97_bus_ops hac_ac97_ops = {
231 .read = hac_ac97_read, 231 .read = hac_ac97_read,
232 .write = hac_ac97_write, 232 .write = hac_ac97_write,
233 .reset = hac_ac97_coldrst, 233 .reset = hac_ac97_coldrst,
234 .warm_reset = hac_ac97_warmrst, 234 .warm_reset = hac_ac97_warmrst,
235}; 235};
236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 236
238static int hac_hw_params(struct snd_pcm_substream *substream, 237static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, 238 struct snd_pcm_hw_params *params,
@@ -316,6 +315,10 @@ static const struct snd_soc_component_driver sh4_hac_component = {
316 315
317static int hac_soc_platform_probe(struct platform_device *pdev) 316static int hac_soc_platform_probe(struct platform_device *pdev)
318{ 317{
318 ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
319 if (ret != 0)
320 return ret;
321
319 return snd_soc_register_component(&pdev->dev, &sh4_hac_component, 322 return snd_soc_register_component(&pdev->dev, &sh4_hac_component,
320 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); 323 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
321} 324}
@@ -323,6 +326,7 @@ static int hac_soc_platform_probe(struct platform_device *pdev)
323static int hac_soc_platform_remove(struct platform_device *pdev) 326static int hac_soc_platform_remove(struct platform_device *pdev)
324{ 327{
325 snd_soc_unregister_component(&pdev->dev); 328 snd_soc_unregister_component(&pdev->dev);
329 snd_soc_set_ac97_ops(NULL);
326 return 0; 330 return 0;
327} 331}
328 332
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d56bbea6e75e..0a8a5f50b466 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2079,6 +2079,23 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2079} 2079}
2080EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 2080EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2081 2081
2082struct snd_ac97_bus_ops *soc_ac97_ops;
2083EXPORT_SYMBOL_GPL(soc_ac97_ops);
2084
2085int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
2086{
2087 if (ops == soc_ac97_ops)
2088 return 0;
2089
2090 if (soc_ac97_ops && ops)
2091 return -EBUSY;
2092
2093 soc_ac97_ops = ops;
2094
2095 return 0;
2096}
2097EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
2098
2082/** 2099/**
2083 * snd_soc_free_ac97_codec - free AC97 codec device 2100 * snd_soc_free_ac97_codec - free AC97 codec device
2084 * @codec: audio codec 2101 * @codec: audio codec
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 2f70ea7f6618..e58233f7df61 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -142,13 +142,12 @@ static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,
142 } while (!time_after(jiffies, timeout)); 142 } while (!time_after(jiffies, timeout));
143} 143}
144 144
145struct snd_ac97_bus_ops soc_ac97_ops = { 145static struct snd_ac97_bus_ops tegra20_ac97_ops = {
146 .read = tegra20_ac97_codec_read, 146 .read = tegra20_ac97_codec_read,
147 .write = tegra20_ac97_codec_write, 147 .write = tegra20_ac97_codec_write,
148 .reset = tegra20_ac97_codec_reset, 148 .reset = tegra20_ac97_codec_reset,
149 .warm_reset = tegra20_ac97_codec_warm_reset, 149 .warm_reset = tegra20_ac97_codec_warm_reset,
150}; 150};
151EXPORT_SYMBOL_GPL(soc_ac97_ops);
152 151
153static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97) 152static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
154{ 153{
@@ -313,7 +312,7 @@ static const struct regmap_config tegra20_ac97_regmap_config = {
313static int tegra20_ac97_platform_probe(struct platform_device *pdev) 312static int tegra20_ac97_platform_probe(struct platform_device *pdev)
314{ 313{
315 struct tegra20_ac97 *ac97; 314 struct tegra20_ac97 *ac97;
316 struct resource *mem, *memregion; 315 struct resource *mem;
317 u32 of_dma[2]; 316 u32 of_dma[2];
318 void __iomem *regs; 317 void __iomem *regs;
319 int ret = 0; 318 int ret = 0;
@@ -327,7 +326,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
327 } 326 }
328 dev_set_drvdata(&pdev->dev, ac97); 327 dev_set_drvdata(&pdev->dev, ac97);
329 328
330 ac97->clk_ac97 = clk_get(&pdev->dev, NULL); 329 ac97->clk_ac97 = devm_clk_get(&pdev->dev, NULL);
331 if (IS_ERR(ac97->clk_ac97)) { 330 if (IS_ERR(ac97->clk_ac97)) {
332 dev_err(&pdev->dev, "Can't retrieve ac97 clock\n"); 331 dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");
333 ret = PTR_ERR(ac97->clk_ac97); 332 ret = PTR_ERR(ac97->clk_ac97);
@@ -341,18 +340,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
341 goto err_clk_put; 340 goto err_clk_put;
342 } 341 }
343 342
344 memregion = devm_request_mem_region(&pdev->dev, mem->start, 343 regs = devm_ioremap_resource(&pdev->dev, mem);
345 resource_size(mem), DRV_NAME); 344 if (IS_ERR(regs)) {
346 if (!memregion) { 345 ret = PTR_ERR(regs);
347 dev_err(&pdev->dev, "Memory region already claimed\n");
348 ret = -EBUSY;
349 goto err_clk_put;
350 }
351
352 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
353 if (!regs) {
354 dev_err(&pdev->dev, "ioremap failed\n");
355 ret = -ENOMEM;
356 goto err_clk_put; 346 goto err_clk_put;
357 } 347 }
358 348
@@ -403,23 +393,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
403 ac97->capture_dma_data.maxburst = 4; 393 ac97->capture_dma_data.maxburst = 4;
404 ac97->capture_dma_data.slave_id = of_dma[0]; 394 ac97->capture_dma_data.slave_id = of_dma[0];
405 395
406 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
407 &tegra20_ac97_dai, 1);
408 if (ret) {
409 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
410 ret = -ENOMEM;
411 goto err_clk_put;
412 }
413
414 ret = tegra_pcm_platform_register(&pdev->dev);
415 if (ret) {
416 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
417 goto err_unregister_component;
418 }
419
420 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); 396 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
421 if (ret) 397 if (ret)
422 goto err_unregister_pcm; 398 goto err_clk_put;
423 399
424 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data); 400 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
425 if (ret) 401 if (ret)
@@ -431,20 +407,40 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
431 goto err_asoc_utils_fini; 407 goto err_asoc_utils_fini;
432 } 408 }
433 409
410 ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops);
411 if (ret) {
412 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
413 goto err_asoc_utils_fini;
414 }
415
416 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
417 &tegra20_ac97_dai, 1);
418 if (ret) {
419 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
420 ret = -ENOMEM;
421 goto err_asoc_utils_fini;
422 }
423
424 ret = tegra_pcm_platform_register(&pdev->dev);
425 if (ret) {
426 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
427 goto err_unregister_component;
428 }
429
434 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */ 430 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
435 workdata = ac97; 431 workdata = ac97;
436 432
437 return 0; 433 return 0;
438 434
439err_asoc_utils_fini:
440 tegra_asoc_utils_fini(&ac97->util_data);
441err_unregister_pcm: 435err_unregister_pcm:
442 tegra_pcm_platform_unregister(&pdev->dev); 436 tegra_pcm_platform_unregister(&pdev->dev);
443err_unregister_component: 437err_unregister_component:
444 snd_soc_unregister_component(&pdev->dev); 438 snd_soc_unregister_component(&pdev->dev);
439err_asoc_utils_fini:
440 tegra_asoc_utils_fini(&ac97->util_data);
445err_clk_put: 441err_clk_put:
446 clk_put(ac97->clk_ac97);
447err: 442err:
443 snd_soc_set_ac97_ops(NULL);
448 return ret; 444 return ret;
449} 445}
450 446
@@ -458,7 +454,8 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
458 tegra_asoc_utils_fini(&ac97->util_data); 454 tegra_asoc_utils_fini(&ac97->util_data);
459 455
460 clk_disable_unprepare(ac97->clk_ac97); 456 clk_disable_unprepare(ac97->clk_ac97);
461 clk_put(ac97->clk_ac97); 457
458 snd_soc_set_ac97_ops(NULL);
462 459
463 return 0; 460 return 0;
464} 461}
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 8a2840304d28..4bcce8a3cded 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -119,12 +119,11 @@ static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97)
119} 119}
120 120
121/* AC97 controller operations */ 121/* AC97 controller operations */
122struct snd_ac97_bus_ops soc_ac97_ops = { 122static struct snd_ac97_bus_ops txx9aclc_ac97_ops = {
123 .read = txx9aclc_ac97_read, 123 .read = txx9aclc_ac97_read,
124 .write = txx9aclc_ac97_write, 124 .write = txx9aclc_ac97_write,
125 .reset = txx9aclc_ac97_cold_reset, 125 .reset = txx9aclc_ac97_cold_reset,
126}; 126};
127EXPORT_SYMBOL_GPL(soc_ac97_ops);
128 127
129static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) 128static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)
130{ 129{
@@ -188,9 +187,9 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
188 if (!r) 187 if (!r)
189 return -EBUSY; 188 return -EBUSY;
190 189
191 if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), 190 drvdata->base = devm_ioremap_resource(&pdev->dev, r);
192 dev_name(&pdev->dev))) 191 if (IS_ERR(drvdata->base))
193 return -EBUSY; 192 return PTR_ERR(drvdata->base);
194 193
195 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 194 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
196 if (!drvdata) 195 if (!drvdata)
@@ -201,14 +200,15 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
201 r->start >= TXX9_DIRECTMAP_BASE && 200 r->start >= TXX9_DIRECTMAP_BASE &&
202 r->start < TXX9_DIRECTMAP_BASE + 0x400000) 201 r->start < TXX9_DIRECTMAP_BASE + 0x400000)
203 drvdata->physbase |= 0xf00000000ull; 202 drvdata->physbase |= 0xf00000000ull;
204 drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
205 if (!drvdata->base)
206 return -EBUSY;
207 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, 203 err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,
208 0, dev_name(&pdev->dev), drvdata); 204 0, dev_name(&pdev->dev), drvdata);
209 if (err < 0) 205 if (err < 0)
210 return err; 206 return err;
211 207
208 err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops);
209 if (err < 0)
210 return err;
211
212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, 212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,
213 &txx9aclc_ac97_dai, 1); 213 &txx9aclc_ac97_dai, 1);
214} 214}
@@ -216,6 +216,7 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) 216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
217{ 217{
218 snd_soc_unregister_component(&pdev->dev); 218 snd_soc_unregister_component(&pdev->dev);
219 snd_soc_set_ac97_ops(NULL);
219 return 0; 220 return 0;
220} 221}
221 222