aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-06-28 07:36:22 -0400
committerTakashi Iwai <tiwai@suse.de>2013-06-28 07:36:22 -0400
commitaccaf69da1d1e64bd77ac0caad77e4cfc3b654c7 (patch)
tree0402e4fad9cecd428c8c3c228a08f9e31eb63470 /sound
parent975cc02a904ae385721f1bdb65eb1bcf707dfaf1 (diff)
parent27516080b21cbcb936440d2a3171867860b9a881 (diff)
Merge tag 'asoc-v3.11-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: More updates for v3.11 Some more fixes and enhancements, and also a bunch of refectoring for AC'97 support which enables more than one AC'97 controller driver to be built in.
Diffstat (limited to 'sound')
-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/88pm860x-codec.c6
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c12
-rw-r--r--sound/soc/codecs/adau1701.c277
-rw-r--r--sound/soc/codecs/stac9766.c26
-rw-r--r--sound/soc/codecs/tas5086.c330
-rw-r--r--sound/soc/codecs/tlv320aic3x.c6
-rw-r--r--sound/soc/codecs/twl6040.c109
-rw-r--r--sound/soc/codecs/wm8400.c9
-rw-r--r--sound/soc/codecs/wm8903.c6
-rw-r--r--sound/soc/codecs/wm8904.c9
-rw-r--r--sound/soc/codecs/wm8990.c11
-rw-r--r--sound/soc/codecs/wm8991.h9
-rw-r--r--sound/soc/codecs/wm8994.c12
-rw-r--r--sound/soc/codecs/wm8995.h7
-rw-r--r--sound/soc/codecs/wm9705.c16
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c18
-rw-r--r--sound/soc/codecs/wm_adsp.h10
-rw-r--r--sound/soc/codecs/wm_hubs.c6
-rw-r--r--sound/soc/fsl/imx-ssi.c11
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c10
-rw-r--r--sound/soc/mid-x86/mfld_machine.c31
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c60
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c8
-rw-r--r--sound/soc/samsung/ac97.c42
-rw-r--r--sound/soc/sh/hac.c8
-rw-r--r--sound/soc/soc-core.c16
-rw-r--r--sound/soc/tegra/tegra20_ac97.c66
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c17
34 files changed, 895 insertions, 373 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 c66bef826ac5..efb1daecd0dd 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 3f4f88877c84..ac73c607410a 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)
@@ -389,6 +388,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
389 ep93xx_ac97_info = info; 388 ep93xx_ac97_info = info;
390 platform_set_drvdata(pdev, info); 389 platform_set_drvdata(pdev, info);
391 390
391 ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
392 if (ret)
393 goto fail;
394
392 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, 395 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
393 &ep93xx_ac97_dai, 1); 396 &ep93xx_ac97_dai, 1);
394 if (ret) 397 if (ret)
@@ -398,7 +401,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
398 401
399fail: 402fail:
400 ep93xx_ac97_info = NULL; 403 ep93xx_ac97_info = NULL;
401 dev_set_drvdata(&pdev->dev, NULL); 404 snd_soc_set_ac97_ops(NULL);
402 return ret; 405 return ret;
403} 406}
404 407
@@ -412,7 +415,8 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
412 ep93xx_ac97_write_reg(info, AC97GCR, 0); 415 ep93xx_ac97_write_reg(info, AC97GCR, 0);
413 416
414 ep93xx_ac97_info = NULL; 417 ep93xx_ac97_info = NULL;
415 dev_set_drvdata(&pdev->dev, NULL); 418
419 snd_soc_set_ac97_ops(NULL);
416 420
417 return 0; 421 return 0;
418} 422}
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 1382f3f3f4bf..8af04343cc1a 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -120,10 +120,8 @@
120 * before DAC & PGA in DAPM power-off sequence. 120 * before DAC & PGA in DAPM power-off sequence.
121 */ 121 */
122#define PM860X_DAPM_OUTPUT(wname, wevent) \ 122#define PM860X_DAPM_OUTPUT(wname, wevent) \
123{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 123 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, 0, 0, NULL, 0, wevent, \
124 .shift = 0, .invert = 0, .kcontrol_news = NULL, \ 124 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD)
125 .num_kcontrols = 0, .event = wevent, \
126 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
127 125
128struct pm860x_det { 126struct pm860x_det {
129 struct snd_soc_jack *hp_jack; 127 struct snd_soc_jack *hp_jack;
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index ef2ae32ffc66..ec7351803c24 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -62,13 +62,13 @@ static struct snd_soc_dai_driver ac97_dai = {
62static unsigned int ac97_read(struct snd_soc_codec *codec, 62static unsigned int ac97_read(struct snd_soc_codec *codec,
63 unsigned int reg) 63 unsigned int reg)
64{ 64{
65 return soc_ac97_ops.read(codec->ac97, reg); 65 return soc_ac97_ops->read(codec->ac97, reg);
66} 66}
67 67
68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 68static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
69 unsigned int val) 69 unsigned int val)
70{ 70{
71 soc_ac97_ops.write(codec->ac97, reg, val); 71 soc_ac97_ops->write(codec->ac97, reg, val);
72 return 0; 72 return 0;
73} 73}
74 74
@@ -79,7 +79,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
79 int ret; 79 int ret;
80 80
81 /* add codec as bus device for standard ac97 */ 81 /* add codec as bus device for standard ac97 */
82 ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus); 82 ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL,
83 &ac97_bus);
83 if (ret < 0) 84 if (ret < 0)
84 return ret; 85 return ret;
85 86
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index f385342947d3..89fcf7d6e7b8 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -108,7 +108,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
108 case AC97_EXTENDED_STATUS: 108 case AC97_EXTENDED_STATUS:
109 case AC97_VENDOR_ID1: 109 case AC97_VENDOR_ID1:
110 case AC97_VENDOR_ID2: 110 case AC97_VENDOR_ID2:
111 return soc_ac97_ops.read(codec->ac97, reg); 111 return soc_ac97_ops->read(codec->ac97, reg);
112 default: 112 default:
113 reg = reg >> 1; 113 reg = reg >> 1;
114 114
@@ -124,7 +124,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
124{ 124{
125 u16 *cache = codec->reg_cache; 125 u16 *cache = codec->reg_cache;
126 126
127 soc_ac97_ops.write(codec->ac97, reg, val); 127 soc_ac97_ops->write(codec->ac97, reg, val);
128 reg = reg >> 1; 128 reg = reg >> 1;
129 if (reg < ARRAY_SIZE(ad1980_reg)) 129 if (reg < ARRAY_SIZE(ad1980_reg))
130 cache[reg] = val; 130 cache[reg] = val;
@@ -154,13 +154,13 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
154 u16 retry_cnt = 0; 154 u16 retry_cnt = 0;
155 155
156retry: 156retry:
157 if (try_warm && soc_ac97_ops.warm_reset) { 157 if (try_warm && soc_ac97_ops->warm_reset) {
158 soc_ac97_ops.warm_reset(codec->ac97); 158 soc_ac97_ops->warm_reset(codec->ac97);
159 if (ac97_read(codec, AC97_RESET) == 0x0090) 159 if (ac97_read(codec, AC97_RESET) == 0x0090)
160 return 1; 160 return 1;
161 } 161 }
162 162
163 soc_ac97_ops.reset(codec->ac97); 163 soc_ac97_ops->reset(codec->ac97);
164 /* Set bit 16slot in register 74h, then every slot will has only 16 164 /* Set bit 16slot in register 74h, then every slot will has only 16
165 * bits. This command is sent out in 20bit mode, in which case the 165 * bits. This command is sent out in 20bit mode, in which case the
166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/ 166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
@@ -186,7 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
186 186
187 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 187 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
188 188
189 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 189 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
190 if (ret < 0) { 190 if (ret < 0) {
191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
192 return ret; 192 return ret;
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index b6b1a773bd37..0e250f118c0e 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -16,6 +16,7 @@
16#include <linux/of.h> 16#include <linux/of.h>
17#include <linux/of_gpio.h> 17#include <linux/of_gpio.h>
18#include <linux/of_device.h> 18#include <linux/of_device.h>
19#include <linux/regmap.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -24,16 +25,19 @@
24#include "sigmadsp.h" 25#include "sigmadsp.h"
25#include "adau1701.h" 26#include "adau1701.h"
26 27
27#define ADAU1701_DSPCTRL 0x1c 28#define ADAU1701_DSPCTRL 0x081c
28#define ADAU1701_SEROCTL 0x1e 29#define ADAU1701_SEROCTL 0x081e
29#define ADAU1701_SERICTL 0x1f 30#define ADAU1701_SERICTL 0x081f
30 31
31#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
32 36
33#define ADAU1701_OSCIPOW 0x26 37#define ADAU1701_OSCIPOW 0x0826
34#define ADAU1701_DACSET 0x27 38#define ADAU1701_DACSET 0x0827
35 39
36#define ADAU1701_NUM_REGS 0x28 40#define ADAU1701_MAX_REGISTER 0x0828
37 41
38#define ADAU1701_DSPCTRL_CR (1 << 2) 42#define ADAU1701_DSPCTRL_CR (1 << 2)
39#define ADAU1701_DSPCTRL_DAM (1 << 3) 43#define ADAU1701_DSPCTRL_DAM (1 << 3)
@@ -87,11 +91,18 @@
87#define ADAU1701_OSCIPOW_OPD 0x04 91#define ADAU1701_OSCIPOW_OPD 0x04
88#define ADAU1701_DACSET_DACINIT 1 92#define ADAU1701_DACSET_DACINIT 1
89 93
94#define ADAU1707_CLKDIV_UNSET (-1UL)
95
90#define ADAU1701_FIRMWARE "adau1701.bin" 96#define ADAU1701_FIRMWARE "adau1701.bin"
91 97
92struct adau1701 { 98struct adau1701 {
93 int gpio_nreset; 99 int gpio_nreset;
100 int gpio_pll_mode[2];
94 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];
95}; 106};
96 107
97static const struct snd_kcontrol_new adau1701_controls[] = { 108static const struct snd_kcontrol_new adau1701_controls[] = {
@@ -123,10 +134,13 @@ static const struct snd_soc_dapm_route adau1701_dapm_routes[] = {
123 { "ADC", NULL, "IN1" }, 134 { "ADC", NULL, "IN1" },
124}; 135};
125 136
126static unsigned int adau1701_register_size(struct snd_soc_codec *codec, 137static unsigned int adau1701_register_size(struct device *dev,
127 unsigned int reg) 138 unsigned int reg)
128{ 139{
129 switch (reg) { 140 switch (reg) {
141 case ADAU1701_PINCONF_0:
142 case ADAU1701_PINCONF_1:
143 return 3;
130 case ADAU1701_DSPCTRL: 144 case ADAU1701_DSPCTRL:
131 case ADAU1701_SEROCTL: 145 case ADAU1701_SEROCTL:
132 case ADAU1701_AUXNPOW: 146 case ADAU1701_AUXNPOW:
@@ -137,33 +151,42 @@ static unsigned int adau1701_register_size(struct snd_soc_codec *codec,
137 return 1; 151 return 1;
138 } 152 }
139 153
140 dev_err(codec->dev, "Unsupported register address: %d\n", reg); 154 dev_err(dev, "Unsupported register address: %d\n", reg);
141 return 0; 155 return 0;
142} 156}
143 157
144static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg, 158static bool adau1701_volatile_reg(struct device *dev, unsigned int reg)
145 unsigned int value)
146{ 159{
160 switch (reg) {
161 case ADAU1701_DACSET:
162 return true;
163 default:
164 return false;
165 }
166}
167
168static int adau1701_reg_write(void *context, unsigned int reg,
169 unsigned int value)
170{
171 struct i2c_client *client = context;
147 unsigned int i; 172 unsigned int i;
148 unsigned int size; 173 unsigned int size;
149 uint8_t buf[4]; 174 uint8_t buf[5];
150 int ret; 175 int ret;
151 176
152 size = adau1701_register_size(codec, reg); 177 size = adau1701_register_size(&client->dev, reg);
153 if (size == 0) 178 if (size == 0)
154 return -EINVAL; 179 return -EINVAL;
155 180
156 snd_soc_cache_write(codec, reg, value); 181 buf[0] = reg >> 8;
157 182 buf[1] = reg & 0xff;
158 buf[0] = 0x08;
159 buf[1] = reg;
160 183
161 for (i = size + 1; i >= 2; --i) { 184 for (i = size + 1; i >= 2; --i) {
162 buf[i] = value; 185 buf[i] = value;
163 value >>= 8; 186 value >>= 8;
164 } 187 }
165 188
166 ret = i2c_master_send(to_i2c_client(codec->dev), buf, size + 2); 189 ret = i2c_master_send(client, buf, size + 2);
167 if (ret == size + 2) 190 if (ret == size + 2)
168 return 0; 191 return 0;
169 else if (ret < 0) 192 else if (ret < 0)
@@ -172,47 +195,105 @@ static int adau1701_write(struct snd_soc_codec *codec, unsigned int reg,
172 return -EIO; 195 return -EIO;
173} 196}
174 197
175static 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)
176{ 200{
177 unsigned int value; 201 int ret;
178 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];
179 207
180 ret = snd_soc_cache_read(codec, reg, &value); 208 size = adau1701_register_size(&client->dev, reg);
181 if (ret) 209 if (size == 0)
182 return ret; 210 return -EINVAL;
183 211
184 return value; 212 send_buf[0] = reg >> 8;
185} 213 send_buf[1] = reg & 0xff;
186 214
187static void adau1701_reset(struct snd_soc_codec *codec) 215 msgs[0].addr = client->addr;
188{ 216 msgs[0].len = sizeof(send_buf);
189 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); 217 msgs[0].buf = send_buf;
218 msgs[0].flags = 0;
190 219
191 if (!gpio_is_valid(adau1701->gpio_nreset)) 220 msgs[1].addr = client->addr;
192 return; 221 msgs[1].len = size;
222 msgs[1].buf = recv_buf;
223 msgs[1].flags = I2C_M_RD;
193 224
194 gpio_set_value(adau1701->gpio_nreset, 0); 225 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
195 /* minimum reset time is 20ns */ 226 if (ret < 0)
196 udelay(1); 227 return ret;
197 gpio_set_value(adau1701->gpio_nreset, 1); 228 else if (ret != ARRAY_SIZE(msgs))
198 /* power-up time may be as long as 85ms */ 229 return -EIO;
199 mdelay(85); 230
231 *value = 0;
232
233 for (i = 0; i < size; i++)
234 *value |= recv_buf[i] << (i * 8);
235
236 return 0;
200} 237}
201 238
202static int adau1701_init(struct snd_soc_codec *codec) 239static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
203{ 240{
204 int ret; 241 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
205 struct i2c_client *client = to_i2c_client(codec->dev); 242 struct i2c_client *client = to_i2c_client(codec->dev);
243 int ret;
206 244
207 adau1701_reset(codec); 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 }
208 268
209 ret = process_sigma_firmware(client, ADAU1701_FIRMWARE); 269 adau1701->pll_clkdiv = clkdiv;
210 if (ret) { 270
211 dev_warn(codec->dev, "Failed to load firmware\n"); 271 if (gpio_is_valid(adau1701->gpio_nreset)) {
212 return ret; 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);
213 } 278 }
214 279
215 snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); 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);
216 297
217 return 0; 298 return 0;
218} 299}
@@ -291,8 +372,22 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 372 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
292{ 373{
293 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);
294 snd_pcm_format_t format; 377 snd_pcm_format_t format;
295 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 }
296 391
297 switch (params_rate(params)) { 392 switch (params_rate(params)) {
298 case 192000: 393 case 192000:
@@ -384,8 +479,8 @@ static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai,
384 479
385 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 480 adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
386 481
387 snd_soc_write(codec, ADAU1701_SERICTL, serictl); 482 regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl);
388 snd_soc_update_bits(codec, ADAU1701_SEROCTL, 483 regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL,
389 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); 484 ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl);
390 485
391 return 0; 486 return 0;
@@ -435,6 +530,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
435 int source, unsigned int freq, int dir) 530 int source, unsigned int freq, int dir)
436{ 531{
437 unsigned int val; 532 unsigned int val;
533 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
438 534
439 switch (clk_id) { 535 switch (clk_id) {
440 case ADAU1701_CLK_SRC_OSC: 536 case ADAU1701_CLK_SRC_OSC:
@@ -448,6 +544,7 @@ static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id,
448 } 544 }
449 545
450 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val); 546 snd_soc_update_bits(codec, ADAU1701_OSCIPOW, ADAU1701_OSCIPOW_OPD, val);
547 adau1701->sysclk = freq;
451 548
452 return 0; 549 return 0;
453} 550}
@@ -494,15 +591,37 @@ MODULE_DEVICE_TABLE(of, adau1701_dt_ids);
494 591
495static int adau1701_probe(struct snd_soc_codec *codec) 592static int adau1701_probe(struct snd_soc_codec *codec)
496{ 593{
497 int ret; 594 int i, ret;
595 unsigned int val;
596 struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
498 597
499 codec->control_data = to_i2c_client(codec->dev); 598 codec->control_data = to_i2c_client(codec->dev);
500 599
501 ret = adau1701_init(codec); 600 /*
502 if (ret) 601 * Let the pll_clkdiv variable default to something that won't happen
602 * at runtime. That way, we can postpone the firmware download from
603 * adau1701_reset() to a point in time when we know the correct PLL
604 * mode parameters.
605 */
606 adau1701->pll_clkdiv = ADAU1707_CLKDIV_UNSET;
607
608 /* initalize with pre-configured pll mode settings */
609 ret = adau1701_reset(codec, adau1701->pll_clkdiv);
610 if (ret < 0)
503 return ret; 611 return ret;
504 612
505 snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); 613 /* set up pin config */
614 val = 0;
615 for (i = 0; i < 6; i++)
616 val |= adau1701->pin_config[i] << (i * 4);
617
618 regmap_write(adau1701->regmap, ADAU1701_PINCONF_0, val);
619
620 val = 0;
621 for (i = 0; i < 6; i++)
622 val |= adau1701->pin_config[i + 6] << (i * 4);
623
624 regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
506 625
507 return 0; 626 return 0;
508} 627}
@@ -512,9 +631,6 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
512 .set_bias_level = adau1701_set_bias_level, 631 .set_bias_level = adau1701_set_bias_level,
513 .idle_bias_off = true, 632 .idle_bias_off = true,
514 633
515 .reg_cache_size = ADAU1701_NUM_REGS,
516 .reg_word_size = sizeof(u16),
517
518 .controls = adau1701_controls, 634 .controls = adau1701_controls,
519 .num_controls = ARRAY_SIZE(adau1701_controls), 635 .num_controls = ARRAY_SIZE(adau1701_controls),
520 .dapm_widgets = adau1701_dapm_widgets, 636 .dapm_widgets = adau1701_dapm_widgets,
@@ -522,28 +638,58 @@ static struct snd_soc_codec_driver adau1701_codec_drv = {
522 .dapm_routes = adau1701_dapm_routes, 638 .dapm_routes = adau1701_dapm_routes,
523 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes), 639 .num_dapm_routes = ARRAY_SIZE(adau1701_dapm_routes),
524 640
525 .write = adau1701_write,
526 .read = adau1701_read,
527
528 .set_sysclk = adau1701_set_sysclk, 641 .set_sysclk = adau1701_set_sysclk,
529}; 642};
530 643
644static const struct regmap_config adau1701_regmap = {
645 .reg_bits = 16,
646 .val_bits = 32,
647 .max_register = ADAU1701_MAX_REGISTER,
648 .cache_type = REGCACHE_RBTREE,
649 .volatile_reg = adau1701_volatile_reg,
650 .reg_write = adau1701_reg_write,
651 .reg_read = adau1701_reg_read,
652};
653
531static int adau1701_i2c_probe(struct i2c_client *client, 654static int adau1701_i2c_probe(struct i2c_client *client,
532 const struct i2c_device_id *id) 655 const struct i2c_device_id *id)
533{ 656{
534 struct adau1701 *adau1701; 657 struct adau1701 *adau1701;
535 struct device *dev = &client->dev; 658 struct device *dev = &client->dev;
536 int gpio_nreset = -EINVAL; 659 int gpio_nreset = -EINVAL;
660 int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
537 int ret; 661 int ret;
538 662
539 adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); 663 adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
540 if (!adau1701) 664 if (!adau1701)
541 return -ENOMEM; 665 return -ENOMEM;
542 666
667 adau1701->regmap = devm_regmap_init(dev, NULL, client,
668 &adau1701_regmap);
669 if (IS_ERR(adau1701->regmap))
670 return PTR_ERR(adau1701->regmap);
671
543 if (dev->of_node) { 672 if (dev->of_node) {
544 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); 673 gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
545 if (gpio_nreset < 0 && gpio_nreset != -ENOENT) 674 if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
546 return gpio_nreset; 675 return gpio_nreset;
676
677 gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
678 "adi,pll-mode-gpios", 0);
679 if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
680 return gpio_pll_mode[0];
681
682 gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
683 "adi,pll-mode-gpios", 1);
684 if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
685 return gpio_pll_mode[1];
686
687 of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
688 &adau1701->pll_clkdiv);
689
690 of_property_read_u8_array(dev->of_node, "adi,pin-config",
691 adau1701->pin_config,
692 ARRAY_SIZE(adau1701->pin_config));
547 } 693 }
548 694
549 if (gpio_is_valid(gpio_nreset)) { 695 if (gpio_is_valid(gpio_nreset)) {
@@ -553,7 +699,24 @@ static int adau1701_i2c_probe(struct i2c_client *client,
553 return ret; 699 return ret;
554 } 700 }
555 701
702 if (gpio_is_valid(gpio_pll_mode[0]) &&
703 gpio_is_valid(gpio_pll_mode[1])) {
704 ret = devm_gpio_request_one(dev, gpio_pll_mode[0],
705 GPIOF_OUT_INIT_LOW,
706 "ADAU1701 PLL mode 0");
707 if (ret < 0)
708 return ret;
709
710 ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
711 GPIOF_OUT_INIT_LOW,
712 "ADAU1701 PLL mode 1");
713 if (ret < 0)
714 return ret;
715 }
716
556 adau1701->gpio_nreset = gpio_nreset; 717 adau1701->gpio_nreset = gpio_nreset;
718 adau1701->gpio_pll_mode[0] = gpio_pll_mode[0];
719 adau1701->gpio_pll_mode[1] = gpio_pll_mode[1];
557 720
558 i2c_set_clientdata(client, adau1701); 721 i2c_set_clientdata(client, adau1701);
559 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, 722 ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
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/tas5086.c b/sound/soc/codecs/tas5086.c
index d447c4aa1d5e..6d31d88f7204 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -83,6 +83,14 @@
83#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ 83#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */
84#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ 84#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */
85#define TAS5086_BKNDERR 0x1c 85#define TAS5086_BKNDERR 0x1c
86#define TAS5086_INPUT_MUX 0x20
87#define TAS5086_PWM_OUTPUT_MUX 0x25
88
89#define TAS5086_MAX_REGISTER TAS5086_PWM_OUTPUT_MUX
90
91#define TAS5086_PWM_START_MIDZ_FOR_START_1 (1 << 7)
92#define TAS5086_PWM_START_MIDZ_FOR_START_2 (1 << 6)
93#define TAS5086_PWM_START_CHANNEL_MASK (0x3f)
86 94
87/* 95/*
88 * Default TAS5086 power-up configuration 96 * Default TAS5086 power-up configuration
@@ -119,9 +127,30 @@ static const struct reg_default tas5086_reg_defaults[] = {
119 { 0x1c, 0x05 }, 127 { 0x1c, 0x05 },
120}; 128};
121 129
130static int tas5086_register_size(struct device *dev, unsigned int reg)
131{
132 switch (reg) {
133 case TAS5086_CLOCK_CONTROL ... TAS5086_BKNDERR:
134 return 1;
135 case TAS5086_INPUT_MUX:
136 case TAS5086_PWM_OUTPUT_MUX:
137 return 4;
138 }
139
140 dev_err(dev, "Unsupported register address: %d\n", reg);
141 return 0;
142}
143
122static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) 144static bool tas5086_accessible_reg(struct device *dev, unsigned int reg)
123{ 145{
124 return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); 146 switch (reg) {
147 case 0x0f:
148 case 0x11 ... 0x17:
149 case 0x1d ... 0x1f:
150 return false;
151 default:
152 return true;
153 }
125} 154}
126 155
127static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) 156static bool tas5086_volatile_reg(struct device *dev, unsigned int reg)
@@ -140,6 +169,76 @@ static bool tas5086_writeable_reg(struct device *dev, unsigned int reg)
140 return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); 169 return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID);
141} 170}
142 171
172static int tas5086_reg_write(void *context, unsigned int reg,
173 unsigned int value)
174{
175 struct i2c_client *client = context;
176 unsigned int i, size;
177 uint8_t buf[5];
178 int ret;
179
180 size = tas5086_register_size(&client->dev, reg);
181 if (size == 0)
182 return -EINVAL;
183
184 buf[0] = reg;
185
186 for (i = size; i >= 1; --i) {
187 buf[i] = value;
188 value >>= 8;
189 }
190
191 ret = i2c_master_send(client, buf, size + 1);
192 if (ret == size + 1)
193 return 0;
194 else if (ret < 0)
195 return ret;
196 else
197 return -EIO;
198}
199
200static int tas5086_reg_read(void *context, unsigned int reg,
201 unsigned int *value)
202{
203 struct i2c_client *client = context;
204 uint8_t send_buf, recv_buf[4];
205 struct i2c_msg msgs[2];
206 unsigned int size;
207 unsigned int i;
208 int ret;
209
210 size = tas5086_register_size(&client->dev, reg);
211 if (size == 0)
212 return -EINVAL;
213
214 send_buf = reg;
215
216 msgs[0].addr = client->addr;
217 msgs[0].len = sizeof(send_buf);
218 msgs[0].buf = &send_buf;
219 msgs[0].flags = 0;
220
221 msgs[1].addr = client->addr;
222 msgs[1].len = size;
223 msgs[1].buf = recv_buf;
224 msgs[1].flags = I2C_M_RD;
225
226 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
227 if (ret < 0)
228 return ret;
229 else if (ret != ARRAY_SIZE(msgs))
230 return -EIO;
231
232 *value = 0;
233
234 for (i = 0; i < size; i++) {
235 *value <<= 8;
236 *value |= recv_buf[i];
237 }
238
239 return 0;
240}
241
143struct tas5086_private { 242struct tas5086_private {
144 struct regmap *regmap; 243 struct regmap *regmap;
145 unsigned int mclk, sclk; 244 unsigned int mclk, sclk;
@@ -376,6 +475,202 @@ static const struct snd_kcontrol_new tas5086_controls[] = {
376 tas5086_get_deemph, tas5086_put_deemph), 475 tas5086_get_deemph, tas5086_put_deemph),
377}; 476};
378 477
478/* Input mux controls */
479static const char *tas5086_dapm_sdin_texts[] =
480{
481 "SDIN1-L", "SDIN1-R", "SDIN2-L", "SDIN2-R",
482 "SDIN3-L", "SDIN3-R", "Ground (0)", "nc"
483};
484
485static const struct soc_enum tas5086_dapm_input_mux_enum[] = {
486 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 20, 8, tas5086_dapm_sdin_texts),
487 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 16, 8, tas5086_dapm_sdin_texts),
488 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 12, 8, tas5086_dapm_sdin_texts),
489 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 8, 8, tas5086_dapm_sdin_texts),
490 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 4, 8, tas5086_dapm_sdin_texts),
491 SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 0, 8, tas5086_dapm_sdin_texts),
492};
493
494static const struct snd_kcontrol_new tas5086_dapm_input_mux_controls[] = {
495 SOC_DAPM_ENUM("Channel 1 input", tas5086_dapm_input_mux_enum[0]),
496 SOC_DAPM_ENUM("Channel 2 input", tas5086_dapm_input_mux_enum[1]),
497 SOC_DAPM_ENUM("Channel 3 input", tas5086_dapm_input_mux_enum[2]),
498 SOC_DAPM_ENUM("Channel 4 input", tas5086_dapm_input_mux_enum[3]),
499 SOC_DAPM_ENUM("Channel 5 input", tas5086_dapm_input_mux_enum[4]),
500 SOC_DAPM_ENUM("Channel 6 input", tas5086_dapm_input_mux_enum[5]),
501};
502
503/* Output mux controls */
504static const char *tas5086_dapm_channel_texts[] =
505 { "Channel 1 Mux", "Channel 2 Mux", "Channel 3 Mux",
506 "Channel 4 Mux", "Channel 5 Mux", "Channel 6 Mux" };
507
508static const struct soc_enum tas5086_dapm_output_mux_enum[] = {
509 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 20, 6, tas5086_dapm_channel_texts),
510 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 16, 6, tas5086_dapm_channel_texts),
511 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 12, 6, tas5086_dapm_channel_texts),
512 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 8, 6, tas5086_dapm_channel_texts),
513 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 4, 6, tas5086_dapm_channel_texts),
514 SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 0, 6, tas5086_dapm_channel_texts),
515};
516
517static const struct snd_kcontrol_new tas5086_dapm_output_mux_controls[] = {
518 SOC_DAPM_ENUM("PWM1 Output", tas5086_dapm_output_mux_enum[0]),
519 SOC_DAPM_ENUM("PWM2 Output", tas5086_dapm_output_mux_enum[1]),
520 SOC_DAPM_ENUM("PWM3 Output", tas5086_dapm_output_mux_enum[2]),
521 SOC_DAPM_ENUM("PWM4 Output", tas5086_dapm_output_mux_enum[3]),
522 SOC_DAPM_ENUM("PWM5 Output", tas5086_dapm_output_mux_enum[4]),
523 SOC_DAPM_ENUM("PWM6 Output", tas5086_dapm_output_mux_enum[5]),
524};
525
526static const struct snd_soc_dapm_widget tas5086_dapm_widgets[] = {
527 SND_SOC_DAPM_INPUT("SDIN1-L"),
528 SND_SOC_DAPM_INPUT("SDIN1-R"),
529 SND_SOC_DAPM_INPUT("SDIN2-L"),
530 SND_SOC_DAPM_INPUT("SDIN2-R"),
531 SND_SOC_DAPM_INPUT("SDIN3-L"),
532 SND_SOC_DAPM_INPUT("SDIN3-R"),
533 SND_SOC_DAPM_INPUT("SDIN4-L"),
534 SND_SOC_DAPM_INPUT("SDIN4-R"),
535
536 SND_SOC_DAPM_OUTPUT("PWM1"),
537 SND_SOC_DAPM_OUTPUT("PWM2"),
538 SND_SOC_DAPM_OUTPUT("PWM3"),
539 SND_SOC_DAPM_OUTPUT("PWM4"),
540 SND_SOC_DAPM_OUTPUT("PWM5"),
541 SND_SOC_DAPM_OUTPUT("PWM6"),
542
543 SND_SOC_DAPM_MUX("Channel 1 Mux", SND_SOC_NOPM, 0, 0,
544 &tas5086_dapm_input_mux_controls[0]),
545 SND_SOC_DAPM_MUX("Channel 2 Mux", SND_SOC_NOPM, 0, 0,
546 &tas5086_dapm_input_mux_controls[1]),
547 SND_SOC_DAPM_MUX("Channel 3 Mux", SND_SOC_NOPM, 0, 0,
548 &tas5086_dapm_input_mux_controls[2]),
549 SND_SOC_DAPM_MUX("Channel 4 Mux", SND_SOC_NOPM, 0, 0,
550 &tas5086_dapm_input_mux_controls[3]),
551 SND_SOC_DAPM_MUX("Channel 5 Mux", SND_SOC_NOPM, 0, 0,
552 &tas5086_dapm_input_mux_controls[4]),
553 SND_SOC_DAPM_MUX("Channel 6 Mux", SND_SOC_NOPM, 0, 0,
554 &tas5086_dapm_input_mux_controls[5]),
555
556 SND_SOC_DAPM_MUX("PWM1 Mux", SND_SOC_NOPM, 0, 0,
557 &tas5086_dapm_output_mux_controls[0]),
558 SND_SOC_DAPM_MUX("PWM2 Mux", SND_SOC_NOPM, 0, 0,
559 &tas5086_dapm_output_mux_controls[1]),
560 SND_SOC_DAPM_MUX("PWM3 Mux", SND_SOC_NOPM, 0, 0,
561 &tas5086_dapm_output_mux_controls[2]),
562 SND_SOC_DAPM_MUX("PWM4 Mux", SND_SOC_NOPM, 0, 0,
563 &tas5086_dapm_output_mux_controls[3]),
564 SND_SOC_DAPM_MUX("PWM5 Mux", SND_SOC_NOPM, 0, 0,
565 &tas5086_dapm_output_mux_controls[4]),
566 SND_SOC_DAPM_MUX("PWM6 Mux", SND_SOC_NOPM, 0, 0,
567 &tas5086_dapm_output_mux_controls[5]),
568};
569
570static const struct snd_soc_dapm_route tas5086_dapm_routes[] = {
571 /* SDIN inputs -> channel muxes */
572 { "Channel 1 Mux", "SDIN1-L", "SDIN1-L" },
573 { "Channel 1 Mux", "SDIN1-R", "SDIN1-R" },
574 { "Channel 1 Mux", "SDIN2-L", "SDIN2-L" },
575 { "Channel 1 Mux", "SDIN2-R", "SDIN2-R" },
576 { "Channel 1 Mux", "SDIN3-L", "SDIN3-L" },
577 { "Channel 1 Mux", "SDIN3-R", "SDIN3-R" },
578
579 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
580 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
581 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
582 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
583 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
584 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
585
586 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
587 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
588 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
589 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
590 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
591 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
592
593 { "Channel 3 Mux", "SDIN1-L", "SDIN1-L" },
594 { "Channel 3 Mux", "SDIN1-R", "SDIN1-R" },
595 { "Channel 3 Mux", "SDIN2-L", "SDIN2-L" },
596 { "Channel 3 Mux", "SDIN2-R", "SDIN2-R" },
597 { "Channel 3 Mux", "SDIN3-L", "SDIN3-L" },
598 { "Channel 3 Mux", "SDIN3-R", "SDIN3-R" },
599
600 { "Channel 4 Mux", "SDIN1-L", "SDIN1-L" },
601 { "Channel 4 Mux", "SDIN1-R", "SDIN1-R" },
602 { "Channel 4 Mux", "SDIN2-L", "SDIN2-L" },
603 { "Channel 4 Mux", "SDIN2-R", "SDIN2-R" },
604 { "Channel 4 Mux", "SDIN3-L", "SDIN3-L" },
605 { "Channel 4 Mux", "SDIN3-R", "SDIN3-R" },
606
607 { "Channel 5 Mux", "SDIN1-L", "SDIN1-L" },
608 { "Channel 5 Mux", "SDIN1-R", "SDIN1-R" },
609 { "Channel 5 Mux", "SDIN2-L", "SDIN2-L" },
610 { "Channel 5 Mux", "SDIN2-R", "SDIN2-R" },
611 { "Channel 5 Mux", "SDIN3-L", "SDIN3-L" },
612 { "Channel 5 Mux", "SDIN3-R", "SDIN3-R" },
613
614 { "Channel 6 Mux", "SDIN1-L", "SDIN1-L" },
615 { "Channel 6 Mux", "SDIN1-R", "SDIN1-R" },
616 { "Channel 6 Mux", "SDIN2-L", "SDIN2-L" },
617 { "Channel 6 Mux", "SDIN2-R", "SDIN2-R" },
618 { "Channel 6 Mux", "SDIN3-L", "SDIN3-L" },
619 { "Channel 6 Mux", "SDIN3-R", "SDIN3-R" },
620
621 /* Channel muxes -> PWM muxes */
622 { "PWM1 Mux", "Channel 1 Mux", "Channel 1 Mux" },
623 { "PWM2 Mux", "Channel 1 Mux", "Channel 1 Mux" },
624 { "PWM3 Mux", "Channel 1 Mux", "Channel 1 Mux" },
625 { "PWM4 Mux", "Channel 1 Mux", "Channel 1 Mux" },
626 { "PWM5 Mux", "Channel 1 Mux", "Channel 1 Mux" },
627 { "PWM6 Mux", "Channel 1 Mux", "Channel 1 Mux" },
628
629 { "PWM1 Mux", "Channel 2 Mux", "Channel 2 Mux" },
630 { "PWM2 Mux", "Channel 2 Mux", "Channel 2 Mux" },
631 { "PWM3 Mux", "Channel 2 Mux", "Channel 2 Mux" },
632 { "PWM4 Mux", "Channel 2 Mux", "Channel 2 Mux" },
633 { "PWM5 Mux", "Channel 2 Mux", "Channel 2 Mux" },
634 { "PWM6 Mux", "Channel 2 Mux", "Channel 2 Mux" },
635
636 { "PWM1 Mux", "Channel 3 Mux", "Channel 3 Mux" },
637 { "PWM2 Mux", "Channel 3 Mux", "Channel 3 Mux" },
638 { "PWM3 Mux", "Channel 3 Mux", "Channel 3 Mux" },
639 { "PWM4 Mux", "Channel 3 Mux", "Channel 3 Mux" },
640 { "PWM5 Mux", "Channel 3 Mux", "Channel 3 Mux" },
641 { "PWM6 Mux", "Channel 3 Mux", "Channel 3 Mux" },
642
643 { "PWM1 Mux", "Channel 4 Mux", "Channel 4 Mux" },
644 { "PWM2 Mux", "Channel 4 Mux", "Channel 4 Mux" },
645 { "PWM3 Mux", "Channel 4 Mux", "Channel 4 Mux" },
646 { "PWM4 Mux", "Channel 4 Mux", "Channel 4 Mux" },
647 { "PWM5 Mux", "Channel 4 Mux", "Channel 4 Mux" },
648 { "PWM6 Mux", "Channel 4 Mux", "Channel 4 Mux" },
649
650 { "PWM1 Mux", "Channel 5 Mux", "Channel 5 Mux" },
651 { "PWM2 Mux", "Channel 5 Mux", "Channel 5 Mux" },
652 { "PWM3 Mux", "Channel 5 Mux", "Channel 5 Mux" },
653 { "PWM4 Mux", "Channel 5 Mux", "Channel 5 Mux" },
654 { "PWM5 Mux", "Channel 5 Mux", "Channel 5 Mux" },
655 { "PWM6 Mux", "Channel 5 Mux", "Channel 5 Mux" },
656
657 { "PWM1 Mux", "Channel 6 Mux", "Channel 6 Mux" },
658 { "PWM2 Mux", "Channel 6 Mux", "Channel 6 Mux" },
659 { "PWM3 Mux", "Channel 6 Mux", "Channel 6 Mux" },
660 { "PWM4 Mux", "Channel 6 Mux", "Channel 6 Mux" },
661 { "PWM5 Mux", "Channel 6 Mux", "Channel 6 Mux" },
662 { "PWM6 Mux", "Channel 6 Mux", "Channel 6 Mux" },
663
664 /* The PWM muxes are directly connected to the PWM outputs */
665 { "PWM1", NULL, "PWM1 Mux" },
666 { "PWM2", NULL, "PWM2 Mux" },
667 { "PWM3", NULL, "PWM3 Mux" },
668 { "PWM4", NULL, "PWM4 Mux" },
669 { "PWM5", NULL, "PWM5 Mux" },
670 { "PWM6", NULL, "PWM6 Mux" },
671
672};
673
379static const struct snd_soc_dai_ops tas5086_dai_ops = { 674static const struct snd_soc_dai_ops tas5086_dai_ops = {
380 .hw_params = tas5086_hw_params, 675 .hw_params = tas5086_hw_params,
381 .set_sysclk = tas5086_set_dai_sysclk, 676 .set_sysclk = tas5086_set_dai_sysclk,
@@ -426,13 +721,34 @@ static int tas5086_probe(struct snd_soc_codec *codec)
426{ 721{
427 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); 722 struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
428 int charge_period = 1300000; /* hardware default is 1300 ms */ 723 int charge_period = 1300000; /* hardware default is 1300 ms */
724 u8 pwm_start_mid_z = 0;
429 int i, ret; 725 int i, ret;
430 726
431 if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { 727 if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) {
432 struct device_node *of_node = codec->dev->of_node; 728 struct device_node *of_node = codec->dev->of_node;
433 of_property_read_u32(of_node, "ti,charge-period", &charge_period); 729 of_property_read_u32(of_node, "ti,charge-period", &charge_period);
730
731 for (i = 0; i < 6; i++) {
732 char name[25];
733
734 snprintf(name, sizeof(name),
735 "ti,mid-z-channel-%d", i + 1);
736
737 if (of_get_property(of_node, name, NULL) != NULL)
738 pwm_start_mid_z |= 1 << i;
739 }
434 } 740 }
435 741
742 /*
743 * If any of the channels is configured to start in Mid-Z mode,
744 * configure 'part 1' of the PWM starts to use Mid-Z, and tell
745 * all configured mid-z channels to start start under 'part 1'.
746 */
747 if (pwm_start_mid_z)
748 regmap_write(priv->regmap, TAS5086_PWM_START,
749 TAS5086_PWM_START_MIDZ_FOR_START_1 |
750 pwm_start_mid_z);
751
436 /* lookup and set split-capacitor charge period */ 752 /* lookup and set split-capacitor charge period */
437 if (charge_period == 0) { 753 if (charge_period == 0) {
438 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); 754 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0);
@@ -490,6 +806,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
490 .resume = tas5086_soc_resume, 806 .resume = tas5086_soc_resume,
491 .controls = tas5086_controls, 807 .controls = tas5086_controls,
492 .num_controls = ARRAY_SIZE(tas5086_controls), 808 .num_controls = ARRAY_SIZE(tas5086_controls),
809 .dapm_widgets = tas5086_dapm_widgets,
810 .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets),
811 .dapm_routes = tas5086_dapm_routes,
812 .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes),
493}; 813};
494 814
495static const struct i2c_device_id tas5086_i2c_id[] = { 815static const struct i2c_device_id tas5086_i2c_id[] = {
@@ -500,14 +820,16 @@ MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id);
500 820
501static const struct regmap_config tas5086_regmap = { 821static const struct regmap_config tas5086_regmap = {
502 .reg_bits = 8, 822 .reg_bits = 8,
503 .val_bits = 8, 823 .val_bits = 32,
504 .max_register = ARRAY_SIZE(tas5086_reg_defaults), 824 .max_register = TAS5086_MAX_REGISTER,
505 .reg_defaults = tas5086_reg_defaults, 825 .reg_defaults = tas5086_reg_defaults,
506 .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), 826 .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults),
507 .cache_type = REGCACHE_RBTREE, 827 .cache_type = REGCACHE_RBTREE,
508 .volatile_reg = tas5086_volatile_reg, 828 .volatile_reg = tas5086_volatile_reg,
509 .writeable_reg = tas5086_writeable_reg, 829 .writeable_reg = tas5086_writeable_reg,
510 .readable_reg = tas5086_accessible_reg, 830 .readable_reg = tas5086_accessible_reg,
831 .reg_read = tas5086_reg_read,
832 .reg_write = tas5086_reg_write,
511}; 833};
512 834
513static int tas5086_i2c_probe(struct i2c_client *i2c, 835static int tas5086_i2c_probe(struct i2c_client *i2c,
@@ -522,7 +844,7 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
522 if (!priv) 844 if (!priv)
523 return -ENOMEM; 845 return -ENOMEM;
524 846
525 priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); 847 priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap);
526 if (IS_ERR(priv->regmap)) { 848 if (IS_ERR(priv->regmap)) {
527 ret = PTR_ERR(priv->regmap); 849 ret = PTR_ERR(priv->regmap);
528 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); 850 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 1514bf845e4b..e5b926883131 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -128,10 +128,8 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
128}; 128};
129 129
130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
131{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 131 SOC_SINGLE_EXT(xname, reg, shift, mask, invert, \
132 .info = snd_soc_info_volsw, \ 132 snd_soc_dapm_get_volsw, snd_soc_dapm_put_volsw_aic3x)
133 .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw_aic3x, \
134 .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) }
135 133
136/* 134/*
137 * All input lines are connected when !0xf and disconnected with 0xf bit field, 135 * All input lines are connected when !0xf and disconnected with 0xf bit field,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 9b9a6e587610..44621ddc332d 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -38,6 +38,14 @@
38 38
39#include "twl6040.h" 39#include "twl6040.h"
40 40
41enum twl6040_dai_id {
42 TWL6040_DAI_LEGACY = 0,
43 TWL6040_DAI_UL,
44 TWL6040_DAI_DL1,
45 TWL6040_DAI_DL2,
46 TWL6040_DAI_VIB,
47};
48
41#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000 49#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
42#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 50#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
43 51
@@ -67,6 +75,8 @@ struct twl6040_data {
67 int pll_power_mode; 75 int pll_power_mode;
68 int hs_power_mode; 76 int hs_power_mode;
69 int hs_power_mode_locked; 77 int hs_power_mode_locked;
78 bool dl1_unmuted;
79 bool dl2_unmuted;
70 unsigned int clk_in; 80 unsigned int clk_in;
71 unsigned int sysclk; 81 unsigned int sysclk;
72 struct twl6040_jack_data hs_jack; 82 struct twl6040_jack_data hs_jack;
@@ -220,6 +230,25 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
220 return value; 230 return value;
221} 231}
222 232
233static bool twl6040_is_path_unmuted(struct snd_soc_codec *codec,
234 unsigned int reg)
235{
236 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
237
238 switch (reg) {
239 case TWL6040_REG_HSLCTL:
240 case TWL6040_REG_HSRCTL:
241 case TWL6040_REG_EARCTL:
242 /* DL1 path */
243 return priv->dl1_unmuted;
244 case TWL6040_REG_HFLCTL:
245 case TWL6040_REG_HFRCTL:
246 return priv->dl2_unmuted;
247 default:
248 return 1;
249 };
250}
251
223/* 252/*
224 * write to the twl6040 register space 253 * write to the twl6040 register space
225 */ 254 */
@@ -232,7 +261,8 @@ static int twl6040_write(struct snd_soc_codec *codec,
232 return -EIO; 261 return -EIO;
233 262
234 twl6040_write_reg_cache(codec, reg, value); 263 twl6040_write_reg_cache(codec, reg, value);
235 if (likely(reg < TWL6040_REG_SW_SHADOW)) 264 if (likely(reg < TWL6040_REG_SW_SHADOW) &&
265 twl6040_is_path_unmuted(codec, reg))
236 return twl6040_reg_write(twl6040, reg, value); 266 return twl6040_reg_write(twl6040, reg, value);
237 else 267 else
238 return 0; 268 return 0;
@@ -1026,16 +1056,84 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1026 return 0; 1056 return 0;
1027} 1057}
1028 1058
1059static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id,
1060 int mute)
1061{
1062 struct twl6040 *twl6040 = codec->control_data;
1063 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1064 int hslctl, hsrctl, earctl;
1065 int hflctl, hfrctl;
1066
1067 switch (id) {
1068 case TWL6040_DAI_DL1:
1069 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
1070 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
1071 earctl = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL);
1072
1073 if (mute) {
1074 /* Power down drivers and DACs */
1075 earctl &= ~0x01;
1076 hslctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1077 hsrctl &= ~(TWL6040_HSDRVENA | TWL6040_HSDACENA);
1078
1079 }
1080
1081 twl6040_reg_write(twl6040, TWL6040_REG_EARCTL, earctl);
1082 twl6040_reg_write(twl6040, TWL6040_REG_HSLCTL, hslctl);
1083 twl6040_reg_write(twl6040, TWL6040_REG_HSRCTL, hsrctl);
1084 priv->dl1_unmuted = !mute;
1085 break;
1086 case TWL6040_DAI_DL2:
1087 hflctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFLCTL);
1088 hfrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFRCTL);
1089
1090 if (mute) {
1091 /* Power down drivers and DACs */
1092 hflctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1093 TWL6040_HFDRVENA);
1094 hfrctl &= ~(TWL6040_HFDACENA | TWL6040_HFPGAENA |
1095 TWL6040_HFDRVENA);
1096 }
1097
1098 twl6040_reg_write(twl6040, TWL6040_REG_HFLCTL, hflctl);
1099 twl6040_reg_write(twl6040, TWL6040_REG_HFRCTL, hfrctl);
1100 priv->dl2_unmuted = !mute;
1101 break;
1102 default:
1103 break;
1104 };
1105}
1106
1107static int twl6040_digital_mute(struct snd_soc_dai *dai, int mute)
1108{
1109 switch (dai->id) {
1110 case TWL6040_DAI_LEGACY:
1111 twl6040_mute_path(dai->codec, TWL6040_DAI_DL1, mute);
1112 twl6040_mute_path(dai->codec, TWL6040_DAI_DL2, mute);
1113 break;
1114 case TWL6040_DAI_DL1:
1115 case TWL6040_DAI_DL2:
1116 twl6040_mute_path(dai->codec, dai->id, mute);
1117 break;
1118 default:
1119 break;
1120 }
1121
1122 return 0;
1123}
1124
1029static const struct snd_soc_dai_ops twl6040_dai_ops = { 1125static const struct snd_soc_dai_ops twl6040_dai_ops = {
1030 .startup = twl6040_startup, 1126 .startup = twl6040_startup,
1031 .hw_params = twl6040_hw_params, 1127 .hw_params = twl6040_hw_params,
1032 .prepare = twl6040_prepare, 1128 .prepare = twl6040_prepare,
1033 .set_sysclk = twl6040_set_dai_sysclk, 1129 .set_sysclk = twl6040_set_dai_sysclk,
1130 .digital_mute = twl6040_digital_mute,
1034}; 1131};
1035 1132
1036static struct snd_soc_dai_driver twl6040_dai[] = { 1133static struct snd_soc_dai_driver twl6040_dai[] = {
1037{ 1134{
1038 .name = "twl6040-legacy", 1135 .name = "twl6040-legacy",
1136 .id = TWL6040_DAI_LEGACY,
1039 .playback = { 1137 .playback = {
1040 .stream_name = "Legacy Playback", 1138 .stream_name = "Legacy Playback",
1041 .channels_min = 1, 1139 .channels_min = 1,
@@ -1054,6 +1152,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1054}, 1152},
1055{ 1153{
1056 .name = "twl6040-ul", 1154 .name = "twl6040-ul",
1155 .id = TWL6040_DAI_UL,
1057 .capture = { 1156 .capture = {
1058 .stream_name = "Capture", 1157 .stream_name = "Capture",
1059 .channels_min = 1, 1158 .channels_min = 1,
@@ -1065,6 +1164,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1065}, 1164},
1066{ 1165{
1067 .name = "twl6040-dl1", 1166 .name = "twl6040-dl1",
1167 .id = TWL6040_DAI_DL1,
1068 .playback = { 1168 .playback = {
1069 .stream_name = "Headset Playback", 1169 .stream_name = "Headset Playback",
1070 .channels_min = 1, 1170 .channels_min = 1,
@@ -1076,6 +1176,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1076}, 1176},
1077{ 1177{
1078 .name = "twl6040-dl2", 1178 .name = "twl6040-dl2",
1179 .id = TWL6040_DAI_DL2,
1079 .playback = { 1180 .playback = {
1080 .stream_name = "Handsfree Playback", 1181 .stream_name = "Handsfree Playback",
1081 .channels_min = 1, 1182 .channels_min = 1,
@@ -1087,6 +1188,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = {
1087}, 1188},
1088{ 1189{
1089 .name = "twl6040-vib", 1190 .name = "twl6040-vib",
1191 .id = TWL6040_DAI_VIB,
1090 .playback = { 1192 .playback = {
1091 .stream_name = "Vibra Playback", 1193 .stream_name = "Vibra Playback",
1092 .channels_min = 1, 1194 .channels_min = 1,
@@ -1143,7 +1245,7 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1143 1245
1144 mutex_init(&priv->mutex); 1246 mutex_init(&priv->mutex);
1145 1247
1146 ret = devm_request_threaded_irq(codec->dev, priv->plug_irq, NULL, 1248 ret = request_threaded_irq(priv->plug_irq, NULL,
1147 twl6040_audio_handler, IRQF_NO_SUSPEND, 1249 twl6040_audio_handler, IRQF_NO_SUSPEND,
1148 "twl6040_irq_plug", codec); 1250 "twl6040_irq_plug", codec);
1149 if (ret) { 1251 if (ret) {
@@ -1159,6 +1261,9 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1159 1261
1160static int twl6040_remove(struct snd_soc_codec *codec) 1262static int twl6040_remove(struct snd_soc_codec *codec)
1161{ 1263{
1264 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1265
1266 free_irq(priv->plug_irq, codec);
1162 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1267 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1163 1268
1164 return 0; 1269 return 0;
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index af6d227e67be..d2a092850283 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -143,13 +143,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
143} 143}
144 144
145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
146{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 146 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
147 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 147 snd_soc_get_volsw, wm8400_outpga_put_volsw_vu, tlv_array)
148 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
149 .tlv.p = (tlv_array), \
150 .info = snd_soc_info_volsw, \
151 .get = snd_soc_get_volsw, .put = wm8400_outpga_put_volsw_vu, \
152 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
153 148
154 149
155static const char *wm8400_digital_sidetone[] = 150static const char *wm8400_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 9d88437cdcd1..fa24cedee687 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -403,10 +403,8 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
403} 403}
404 404
405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \ 405#define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \
406{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 406 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
407 .info = snd_soc_info_volsw, \ 407 snd_soc_dapm_get_volsw, wm8903_class_w_put)
408 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \
409 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
410 408
411 409
412static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; 410static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 3ff195c541db..4c9fb142cb2d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -603,13 +603,8 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
603 603
604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), 604SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
605SOC_ENUM("High Pass Filter Mode", hpf_mode), 605SOC_ENUM("High Pass Filter Mode", hpf_mode),
606 606SOC_SINGLE_EXT("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0,
607{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 607 snd_soc_get_volsw, wm8904_adc_osr_put),
608 .name = "ADC 128x OSR Switch",
609 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
610 .put = wm8904_adc_osr_put,
611 .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
612},
613}; 608};
614 609
615static const char *drc_path_text[] = { 610static const char *drc_path_text[] = {
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 837978e16e9d..253c88bb7a4c 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -151,14 +151,9 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
151} 151}
152 152
153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 153#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
154 tlv_array) {\ 154 tlv_array) \
155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 155 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
156 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 156 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
157 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
158 .tlv.p = (tlv_array), \
159 .info = snd_soc_info_volsw, \
160 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
161 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
162 157
163 158
164static const char *wm8990_digital_sidetone[] = 159static const char *wm8990_digital_sidetone[] =
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
index 8a942efd18a5..07707d8d7e20 100644
--- a/sound/soc/codecs/wm8991.h
+++ b/sound/soc/codecs/wm8991.h
@@ -822,12 +822,7 @@
822 822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \ 824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 825 SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 826 snd_soc_get_volsw, wm899x_outpga_put_volsw_vu, tlv_array)
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832 827
833#endif /* _WM8991_H */ 828#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 25580b5a853f..1d4b1ec66e36 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -290,10 +290,8 @@ static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
290static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0); 290static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0);
291 291
292#define WM8994_DRC_SWITCH(xname, reg, shift) \ 292#define WM8994_DRC_SWITCH(xname, reg, shift) \
293{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 293 SOC_SINGLE_EXT(xname, reg, shift, 1, 0, \
294 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 294 snd_soc_get_volsw, wm8994_put_drc_sw)
295 .put = wm8994_put_drc_sw, \
296 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
297 295
298static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, 296static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
299 struct snd_ctl_elem_value *ucontrol) 297 struct snd_ctl_elem_value *ucontrol)
@@ -1433,10 +1431,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1433}; 1431};
1434 1432
1435#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 1433#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
1436{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 1434 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
1437 .info = snd_soc_info_volsw, \ 1435 snd_soc_get_volsw, wm8994_put_class_w)
1438 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
1439 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
1440 1436
1441static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1437static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1442 struct snd_ctl_elem_value *ucontrol) 1438 struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
index 5642121c4977..508ad27fe2bb 100644
--- a/sound/soc/codecs/wm8995.h
+++ b/sound/soc/codecs/wm8995.h
@@ -4237,11 +4237,8 @@
4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ 4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
4238 4238
4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
4240{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 4240 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
4241 .info = snd_soc_info_volsw, \ 4241 snd_soc_dapm_get_volsw, wm8995_put_class_w)
4242 .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
4243 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
4244}
4245 4242
4246struct wm8995_reg_access { 4243struct wm8995_reg_access {
4247 u16 read; 4244 u16 read;
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 05b1f346695b..70ce6793c5bd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -209,7 +209,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
209 case AC97_RESET: 209 case AC97_RESET:
210 case AC97_VENDOR_ID1: 210 case AC97_VENDOR_ID1:
211 case AC97_VENDOR_ID2: 211 case AC97_VENDOR_ID2:
212 return soc_ac97_ops.read(codec->ac97, reg); 212 return soc_ac97_ops->read(codec->ac97, reg);
213 default: 213 default:
214 reg = reg >> 1; 214 reg = reg >> 1;
215 215
@@ -225,7 +225,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
225{ 225{
226 u16 *cache = codec->reg_cache; 226 u16 *cache = codec->reg_cache;
227 227
228 soc_ac97_ops.write(codec->ac97, reg, val); 228 soc_ac97_ops->write(codec->ac97, reg, val);
229 reg = reg >> 1; 229 reg = reg >> 1;
230 if (reg < (ARRAY_SIZE(wm9705_reg))) 230 if (reg < (ARRAY_SIZE(wm9705_reg)))
231 cache[reg] = val; 231 cache[reg] = val;
@@ -294,8 +294,8 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
294 294
295static int wm9705_reset(struct snd_soc_codec *codec) 295static int wm9705_reset(struct snd_soc_codec *codec)
296{ 296{
297 if (soc_ac97_ops.reset) { 297 if (soc_ac97_ops->reset) {
298 soc_ac97_ops.reset(codec->ac97); 298 soc_ac97_ops->reset(codec->ac97);
299 if (ac97_read(codec, 0) == wm9705_reg[0]) 299 if (ac97_read(codec, 0) == wm9705_reg[0])
300 return 0; /* Success */ 300 return 0; /* Success */
301 } 301 }
@@ -306,7 +306,7 @@ static int wm9705_reset(struct snd_soc_codec *codec)
306#ifdef CONFIG_PM 306#ifdef CONFIG_PM
307static int wm9705_soc_suspend(struct snd_soc_codec *codec) 307static int wm9705_soc_suspend(struct snd_soc_codec *codec)
308{ 308{
309 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); 309 soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff);
310 310
311 return 0; 311 return 0;
312} 312}
@@ -323,7 +323,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
323 } 323 }
324 324
325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { 325 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
326 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 326 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
327 } 327 }
328 328
329 return 0; 329 return 0;
@@ -337,9 +337,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
337{ 337{
338 int ret = 0; 338 int ret = 0;
339 339
340 printk(KERN_INFO "WM9705 SoC Audio Codec\n"); 340 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
341
342 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
343 if (ret < 0) { 341 if (ret < 0) {
344 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
345 return ret; 343 return ret;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 8e9a6a3eeb1a..c5eb746087b4 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -455,7 +455,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
457 reg == AC97_REC_GAIN) 457 reg == AC97_REC_GAIN)
458 return soc_ac97_ops.read(codec->ac97, reg); 458 return soc_ac97_ops->read(codec->ac97, reg);
459 else { 459 else {
460 reg = reg >> 1; 460 reg = reg >> 1;
461 461
@@ -472,7 +472,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
472 u16 *cache = codec->reg_cache; 472 u16 *cache = codec->reg_cache;
473 473
474 if (reg < 0x7c) 474 if (reg < 0x7c)
475 soc_ac97_ops.write(codec->ac97, reg, val); 475 soc_ac97_ops->write(codec->ac97, reg, val);
476 reg = reg >> 1; 476 reg = reg >> 1;
477 if (reg < (ARRAY_SIZE(wm9712_reg))) 477 if (reg < (ARRAY_SIZE(wm9712_reg)))
478 cache[reg] = val; 478 cache[reg] = val;
@@ -581,15 +581,15 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
581 581
582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) 582static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
583{ 583{
584 if (try_warm && soc_ac97_ops.warm_reset) { 584 if (try_warm && soc_ac97_ops->warm_reset) {
585 soc_ac97_ops.warm_reset(codec->ac97); 585 soc_ac97_ops->warm_reset(codec->ac97);
586 if (ac97_read(codec, 0) == wm9712_reg[0]) 586 if (ac97_read(codec, 0) == wm9712_reg[0])
587 return 1; 587 return 1;
588 } 588 }
589 589
590 soc_ac97_ops.reset(codec->ac97); 590 soc_ac97_ops->reset(codec->ac97);
591 if (soc_ac97_ops.warm_reset) 591 if (soc_ac97_ops->warm_reset)
592 soc_ac97_ops.warm_reset(codec->ac97); 592 soc_ac97_ops->warm_reset(codec->ac97);
593 if (ac97_read(codec, 0) != wm9712_reg[0]) 593 if (ac97_read(codec, 0) != wm9712_reg[0])
594 goto err; 594 goto err;
595 return 0; 595 return 0;
@@ -624,7 +624,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || 624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
625 (i > 0x58 && i != 0x5c)) 625 (i > 0x58 && i != 0x5c))
626 continue; 626 continue;
627 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 627 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
628 } 628 }
629 } 629 }
630 630
@@ -635,7 +635,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
635{ 635{
636 int ret = 0; 636 int ret = 0;
637 637
638 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 638 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
639 if (ret < 0) { 639 if (ret < 0) {
640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
641 return ret; 641 return ret;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index f7afa68d8c7f..a53e175c015a 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -652,7 +652,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
654 reg == AC97_CD) 654 reg == AC97_CD)
655 return soc_ac97_ops.read(codec->ac97, reg); 655 return soc_ac97_ops->read(codec->ac97, reg);
656 else { 656 else {
657 reg = reg >> 1; 657 reg = reg >> 1;
658 658
@@ -668,7 +668,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
668{ 668{
669 u16 *cache = codec->reg_cache; 669 u16 *cache = codec->reg_cache;
670 if (reg < 0x7c) 670 if (reg < 0x7c)
671 soc_ac97_ops.write(codec->ac97, reg, val); 671 soc_ac97_ops->write(codec->ac97, reg, val);
672 reg = reg >> 1; 672 reg = reg >> 1;
673 if (reg < (ARRAY_SIZE(wm9713_reg))) 673 if (reg < (ARRAY_SIZE(wm9713_reg)))
674 cache[reg] = val; 674 cache[reg] = val;
@@ -1095,15 +1095,15 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1095 1095
1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097{ 1097{
1098 if (try_warm && soc_ac97_ops.warm_reset) { 1098 if (try_warm && soc_ac97_ops->warm_reset) {
1099 soc_ac97_ops.warm_reset(codec->ac97); 1099 soc_ac97_ops->warm_reset(codec->ac97);
1100 if (ac97_read(codec, 0) == wm9713_reg[0]) 1100 if (ac97_read(codec, 0) == wm9713_reg[0])
1101 return 1; 1101 return 1;
1102 } 1102 }
1103 1103
1104 soc_ac97_ops.reset(codec->ac97); 1104 soc_ac97_ops->reset(codec->ac97);
1105 if (soc_ac97_ops.warm_reset) 1105 if (soc_ac97_ops->warm_reset)
1106 soc_ac97_ops.warm_reset(codec->ac97); 1106 soc_ac97_ops->warm_reset(codec->ac97);
1107 if (ac97_read(codec, 0) != wm9713_reg[0]) 1107 if (ac97_read(codec, 0) != wm9713_reg[0])
1108 return -EIO; 1108 return -EIO;
1109 return 0; 1109 return 0;
@@ -1180,7 +1180,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1181 i == AC97_EXTENDED_MSTATUS || i > 0x66) 1181 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1182 continue; 1182 continue;
1183 soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); 1183 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);
1184 } 1184 }
1185 } 1185 }
1186 1186
@@ -1197,7 +1197,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1197 return -ENOMEM; 1197 return -ENOMEM;
1198 snd_soc_codec_set_drvdata(codec, wm9713); 1198 snd_soc_codec_set_drvdata(codec, wm9713);
1199 1199
1200 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1200 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
1201 if (ret < 0) 1201 if (ret < 0)
1202 goto codec_err; 1202 goto codec_err;
1203 1203
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 6e890b916592..9f922c82536c 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -61,14 +61,12 @@ struct wm_adsp {
61}; 61};
62 62
63#define WM_ADSP1(wname, num) \ 63#define WM_ADSP1(wname, num) \
64 { .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 64 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
65 .shift = num, .event = wm_adsp1_event, \ 65 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
66 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
67 66
68#define WM_ADSP2(wname, num) \ 67#define WM_ADSP2(wname, num) \
69{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \ 68 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
70 .shift = num, .event = wm_adsp2_event, \ 69 wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
71 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
72 70
73extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; 71extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
74extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; 72extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index f5d81b948759..2d9e099415a5 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -693,10 +693,8 @@ void wm_hubs_update_class_w(struct snd_soc_codec *codec)
693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w); 693EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
694 694
695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \ 695#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \
696{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 696 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
697 .info = snd_soc_info_volsw, \ 697 snd_soc_dapm_get_volsw, class_w_put_volsw)
698 .get = snd_soc_dapm_get_volsw, .put = class_w_put_volsw, \
699 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
700 698
701static int class_w_put_volsw(struct snd_kcontrol *kcontrol, 699static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
702 struct snd_ctl_elem_value *ucontrol) 700 struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index a8362be3cd18..51be3772cba9 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) {
@@ -608,6 +613,7 @@ failed_register:
608 release_mem_region(res->start, resource_size(res)); 613 release_mem_region(res->start, resource_size(res));
609 clk_disable_unprepare(ssi->clk); 614 clk_disable_unprepare(ssi->clk);
610failed_clk: 615failed_clk:
616 snd_soc_set_ac97_ops(NULL);
611 617
612 return ret; 618 return ret;
613} 619}
@@ -627,6 +633,7 @@ static int imx_ssi_remove(struct platform_device *pdev)
627 633
628 release_mem_region(res->start, resource_size(res)); 634 release_mem_region(res->start, resource_size(res));
629 clk_disable_unprepare(ssi->clk); 635 clk_disable_unprepare(ssi->clk);
636 snd_soc_set_ac97_ops(NULL);
630 637
631 return 0; 638 return 0;
632} 639}
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/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 78d582519891..ee363845759e 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -371,7 +371,7 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
371 371
372 /* audio interrupt base of SRAM location where 372 /* audio interrupt base of SRAM location where
373 * interrupts are stored by System FW */ 373 * interrupts are stored by System FW */
374 mc_drv_ctx = kzalloc(sizeof(*mc_drv_ctx), GFP_ATOMIC); 374 mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC);
375 if (!mc_drv_ctx) { 375 if (!mc_drv_ctx) {
376 pr_err("allocation failed\n"); 376 pr_err("allocation failed\n");
377 return -ENOMEM; 377 return -ENOMEM;
@@ -381,50 +381,39 @@ static int snd_mfld_mc_probe(struct platform_device *pdev)
381 pdev, IORESOURCE_MEM, "IRQ_BASE"); 381 pdev, IORESOURCE_MEM, "IRQ_BASE");
382 if (!irq_mem) { 382 if (!irq_mem) {
383 pr_err("no mem resource given\n"); 383 pr_err("no mem resource given\n");
384 ret_val = -ENODEV; 384 return -ENODEV;
385 goto unalloc;
386 } 385 }
387 mc_drv_ctx->int_base = ioremap_nocache(irq_mem->start, 386 mc_drv_ctx->int_base = devm_ioremap_nocache(&pdev->dev, irq_mem->start,
388 resource_size(irq_mem)); 387 resource_size(irq_mem));
389 if (!mc_drv_ctx->int_base) { 388 if (!mc_drv_ctx->int_base) {
390 pr_err("Mapping of cache failed\n"); 389 pr_err("Mapping of cache failed\n");
391 ret_val = -ENOMEM; 390 return -ENOMEM;
392 goto unalloc;
393 } 391 }
394 /* register for interrupt */ 392 /* register for interrupt */
395 ret_val = request_threaded_irq(irq, snd_mfld_jack_intr_handler, 393 ret_val = devm_request_threaded_irq(&pdev->dev, irq,
394 snd_mfld_jack_intr_handler,
396 snd_mfld_jack_detection, 395 snd_mfld_jack_detection,
397 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx); 396 IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
398 if (ret_val) { 397 if (ret_val) {
399 pr_err("cannot register IRQ\n"); 398 pr_err("cannot register IRQ\n");
400 goto unalloc; 399 return ret_val;
401 } 400 }
402 /* register the soc card */ 401 /* register the soc card */
403 snd_soc_card_mfld.dev = &pdev->dev; 402 snd_soc_card_mfld.dev = &pdev->dev;
404 ret_val = snd_soc_register_card(&snd_soc_card_mfld); 403 ret_val = snd_soc_register_card(&snd_soc_card_mfld);
405 if (ret_val) { 404 if (ret_val) {
406 pr_debug("snd_soc_register_card failed %d\n", ret_val); 405 pr_debug("snd_soc_register_card failed %d\n", ret_val);
407 goto freeirq; 406 return ret_val;
408 } 407 }
409 platform_set_drvdata(pdev, mc_drv_ctx); 408 platform_set_drvdata(pdev, mc_drv_ctx);
410 pr_debug("successfully exited probe\n"); 409 pr_debug("successfully exited probe\n");
411 return ret_val; 410 return 0;
412
413freeirq:
414 free_irq(irq, mc_drv_ctx);
415unalloc:
416 kfree(mc_drv_ctx);
417 return ret_val;
418} 411}
419 412
420static int snd_mfld_mc_remove(struct platform_device *pdev) 413static int snd_mfld_mc_remove(struct platform_device *pdev)
421{ 414{
422 struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
423
424 pr_debug("snd_mfld_mc_remove called\n"); 415 pr_debug("snd_mfld_mc_remove called\n");
425 free_irq(platform_get_irq(pdev, 0), mc_drv_ctx);
426 snd_soc_unregister_card(&snd_soc_card_mfld); 416 snd_soc_unregister_card(&snd_soc_card_mfld);
427 kfree(mc_drv_ctx);
428 return 0; 417 return 0;
429} 418}
430 419
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..a3c22ba25f08 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",
@@ -244,6 +243,10 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
244 return -ENXIO; 243 return -ENXIO;
245 } 244 }
246 245
246 ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops);
247 if (ret != 0)
248 return ret;
249
247 /* Punt most of the init to the SoC probe; we may need the machine 250 /* 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 251 * driver to do interesting things with the clocking to get us up
249 * and running. 252 * and running.
@@ -255,6 +258,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
255static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) 258static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
256{ 259{
257 snd_soc_unregister_component(&pdev->dev); 260 snd_soc_unregister_component(&pdev->dev);
261 snd_soc_set_ac97_ops(NULL);
258 return 0; 262 return 0;
259} 263}
260 264
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 4489c5b7b53a..309e5c91167b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2080,6 +2080,22 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2080} 2080}
2081EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 2081EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2082 2082
2083struct snd_ac97_bus_ops *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
2083/** 2099/**
2084 * snd_soc_free_ac97_codec - free AC97 codec device 2100 * snd_soc_free_ac97_codec - free AC97 codec device
2085 * @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..f52eab6d2231 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{
@@ -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,10 @@ 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"); 346 dev_err(&pdev->dev, "ioremap failed: %d\n", ret);
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; 347 goto err_clk_put;
357 } 348 }
358 349
@@ -403,23 +394,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
403 ac97->capture_dma_data.maxburst = 4; 394 ac97->capture_dma_data.maxburst = 4;
404 ac97->capture_dma_data.slave_id = of_dma[0]; 395 ac97->capture_dma_data.slave_id = of_dma[0];
405 396
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); 397 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
421 if (ret) 398 if (ret)
422 goto err_unregister_pcm; 399 goto err_clk_put;
423 400
424 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data); 401 ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);
425 if (ret) 402 if (ret)
@@ -431,20 +408,40 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
431 goto err_asoc_utils_fini; 408 goto err_asoc_utils_fini;
432 } 409 }
433 410
411 ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops);
412 if (ret) {
413 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
414 goto err_asoc_utils_fini;
415 }
416
417 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
418 &tegra20_ac97_dai, 1);
419 if (ret) {
420 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
421 ret = -ENOMEM;
422 goto err_asoc_utils_fini;
423 }
424
425 ret = tegra_pcm_platform_register(&pdev->dev);
426 if (ret) {
427 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
428 goto err_unregister_component;
429 }
430
434 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */ 431 /* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */
435 workdata = ac97; 432 workdata = ac97;
436 433
437 return 0; 434 return 0;
438 435
439err_asoc_utils_fini:
440 tegra_asoc_utils_fini(&ac97->util_data);
441err_unregister_pcm: 436err_unregister_pcm:
442 tegra_pcm_platform_unregister(&pdev->dev); 437 tegra_pcm_platform_unregister(&pdev->dev);
443err_unregister_component: 438err_unregister_component:
444 snd_soc_unregister_component(&pdev->dev); 439 snd_soc_unregister_component(&pdev->dev);
440err_asoc_utils_fini:
441 tegra_asoc_utils_fini(&ac97->util_data);
445err_clk_put: 442err_clk_put:
446 clk_put(ac97->clk_ac97);
447err: 443err:
444 snd_soc_set_ac97_ops(NULL);
448 return ret; 445 return ret;
449} 446}
450 447
@@ -458,7 +455,8 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
458 tegra_asoc_utils_fini(&ac97->util_data); 455 tegra_asoc_utils_fini(&ac97->util_data);
459 456
460 clk_disable_unprepare(ac97->clk_ac97); 457 clk_disable_unprepare(ac97->clk_ac97);
461 clk_put(ac97->clk_ac97); 458
459 snd_soc_set_ac97_ops(NULL);
462 460
463 return 0; 461 return 0;
464} 462}
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