Commit b047e1cce8fe32475ab61846772943a5e4c0a908

Authored by Mark Brown
1 parent b49dff8cb6

ASoC: ac97: Support multi-platform AC'97

Currently we can only have a single platform built in with AC'97 support
due to the use of a global variable to provide the bus operations. Fix
this by making that variable a pointer and having the bus drivers set the
operations prior to registering.

This is not a particularly good or nice approach but it avoids blocking
multiplatform and a real fix involves fixing the fairly deep problems
with AC'97 support - we should be converting it to a real bus.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

Showing 20 changed files with 154 additions and 72 deletions Side-by-side Diff

... ... @@ -340,7 +340,7 @@
340 340  
341 341 typedef int (*hw_write_t)(void *,const char* ,int);
342 342  
343   -extern struct snd_ac97_bus_ops soc_ac97_ops;
  343 +extern struct snd_ac97_bus_ops *soc_ac97_ops;
344 344  
345 345 enum snd_soc_control_type {
346 346 SND_SOC_I2C = 1,
... ... @@ -466,6 +466,8 @@
466 466 int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
467 467 struct snd_ac97_bus_ops *ops, int num);
468 468 void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
  469 +
  470 +int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
469 471  
470 472 /*
471 473 *Controls
sound/soc/au1x/ac97c.c
... ... @@ -179,13 +179,12 @@
179 179 }
180 180  
181 181 /* AC97 controller operations */
182   -struct snd_ac97_bus_ops soc_ac97_ops = {
  182 +static struct snd_ac97_bus_ops ac97c_bus_ops = {
183 183 .read = au1xac97c_ac97_read,
184 184 .write = au1xac97c_ac97_write,
185 185 .reset = au1xac97c_ac97_cold_reset,
186 186 .warm_reset = au1xac97c_ac97_warm_reset,
187 187 };
188   -EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */
189 188  
190 189 static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,
191 190 struct snd_soc_dai *dai)
... ... @@ -271,6 +270,10 @@
271 270 WR(ctx, AC97_CONFIG, ctx->cfg);
272 271  
273 272 platform_set_drvdata(pdev, ctx);
  273 +
  274 + ret = snd_soc_set_ac97_ops(&ac97c_bus_ops);
  275 + if (ret)
  276 + return ret;
274 277  
275 278 ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,
276 279 &au1xac97c_dai_driver, 1);
sound/soc/au1x/psc-ac97.c
... ... @@ -201,13 +201,12 @@
201 201 }
202 202  
203 203 /* AC97 controller operations */
204   -struct snd_ac97_bus_ops soc_ac97_ops = {
  204 +static struct snd_ac97_bus_ops psc_ac97_ops = {
205 205 .read = au1xpsc_ac97_read,
206 206 .write = au1xpsc_ac97_write,
207 207 .reset = au1xpsc_ac97_cold_reset,
208 208 .warm_reset = au1xpsc_ac97_warm_reset,
209 209 };
210   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
211 210  
212 211 static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
213 212 struct snd_pcm_hw_params *params,
... ... @@ -416,6 +415,10 @@
416 415 wd->dai_drv.name = dev_name(&pdev->dev);
417 416  
418 417 platform_set_drvdata(pdev, wd);
  418 +
  419 + ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
  420 + if (ret)
  421 + return ret;
419 422  
420 423 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
421 424 &wd->dai_drv, 1);
sound/soc/blackfin/bf5xx-ac97.c
... ... @@ -198,13 +198,12 @@
198 198 #endif
199 199 }
200 200  
201   -struct snd_ac97_bus_ops soc_ac97_ops = {
  201 +static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
202 202 .read = bf5xx_ac97_read,
203 203 .write = bf5xx_ac97_write,
204 204 .warm_reset = bf5xx_ac97_warm_reset,
205 205 .reset = bf5xx_ac97_cold_reset,
206 206 };
207   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
208 207  
209 208 #ifdef CONFIG_PM
210 209 static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
... ... @@ -336,6 +335,12 @@
336 335 goto sport_config_err;
337 336 }
338 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 +
339 344 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
340 345 &bfin_ac97_dai, 1);
341 346 if (ret) {
... ... @@ -350,6 +355,7 @@
350 355 sport_config_err:
351 356 sport_done(sport_handle);
352 357 sport_err:
  358 + snd_soc_set_ac97_ops(NULL);
353 359  
354 360 return ret;
355 361 }
... ... @@ -360,6 +366,7 @@
360 366  
361 367 snd_soc_unregister_component(&pdev->dev);
362 368 sport_done(sport_handle);
  369 + snd_soc_set_ac97_ops(NULL);
363 370  
364 371 return 0;
365 372 }
sound/soc/cirrus/ep93xx-ac97.c
... ... @@ -237,13 +237,12 @@
237 237 return IRQ_HANDLED;
238 238 }
239 239  
240   -struct snd_ac97_bus_ops soc_ac97_ops = {
  240 +static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
241 241 .read = ep93xx_ac97_read,
242 242 .write = ep93xx_ac97_write,
243 243 .reset = ep93xx_ac97_cold_reset,
244 244 .warm_reset = ep93xx_ac97_warm_reset,
245 245 };
246   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
247 246  
248 247 static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
249 248 int cmd, struct snd_soc_dai *dai)
... ... @@ -395,6 +394,10 @@
395 394 ep93xx_ac97_info = info;
396 395 platform_set_drvdata(pdev, info);
397 396  
  397 + ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
  398 + if (ret)
  399 + goto fail;
  400 +
398 401 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
399 402 &ep93xx_ac97_dai, 1);
400 403 if (ret)
... ... @@ -405,6 +408,7 @@
405 408 fail:
406 409 platform_set_drvdata(pdev, NULL);
407 410 ep93xx_ac97_info = NULL;
  411 + snd_soc_set_ac97_ops(NULL);
408 412 return ret;
409 413 }
410 414  
... ... @@ -419,6 +423,8 @@
419 423  
420 424 platform_set_drvdata(pdev, NULL);
421 425 ep93xx_ac97_info = NULL;
  426 +
  427 + snd_soc_set_ac97_ops(NULL);
422 428  
423 429 return 0;
424 430 }
sound/soc/codecs/ac97.c
... ... @@ -62,13 +62,13 @@
62 62 static unsigned int ac97_read(struct snd_soc_codec *codec,
63 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  
68 68 static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
69 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 72 return 0;
73 73 }
74 74  
... ... @@ -79,7 +79,8 @@
79 79 int ret;
80 80  
81 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 84 if (ret < 0)
84 85 return ret;
85 86  
sound/soc/codecs/ad1980.c
... ... @@ -108,7 +108,7 @@
108 108 case AC97_EXTENDED_STATUS:
109 109 case AC97_VENDOR_ID1:
110 110 case AC97_VENDOR_ID2:
111   - return soc_ac97_ops.read(codec->ac97, reg);
  111 + return soc_ac97_ops->read(codec->ac97, reg);
112 112 default:
113 113 reg = reg >> 1;
114 114  
... ... @@ -124,7 +124,7 @@
124 124 {
125 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 128 reg = reg >> 1;
129 129 if (reg < ARRAY_SIZE(ad1980_reg))
130 130 cache[reg] = val;
131 131  
... ... @@ -154,13 +154,13 @@
154 154 u16 retry_cnt = 0;
155 155  
156 156 retry:
157   - if (try_warm && soc_ac97_ops.warm_reset) {
158   - soc_ac97_ops.warm_reset(codec->ac97);
  157 + if (try_warm && soc_ac97_ops->warm_reset) {
  158 + soc_ac97_ops->warm_reset(codec->ac97);
159 159 if (ac97_read(codec, AC97_RESET) == 0x0090)
160 160 return 1;
161 161 }
162 162  
163   - soc_ac97_ops.reset(codec->ac97);
  163 + soc_ac97_ops->reset(codec->ac97);
164 164 /* Set bit 16slot in register 74h, then every slot will has only 16
165 165 * bits. This command is sent out in 20bit mode, in which case the
166 166 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
... ... @@ -186,7 +186,7 @@
186 186  
187 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 190 if (ret < 0) {
191 191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
192 192 return ret;
sound/soc/codecs/stac9766.c
... ... @@ -143,14 +143,14 @@
143 143  
144 144 if (reg > AC97_STAC_PAGE0) {
145 145 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
146   - soc_ac97_ops.write(codec->ac97, reg, val);
  146 + soc_ac97_ops->write(codec->ac97, reg, val);
147 147 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
148 148 return 0;
149 149 }
150 150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
151 151 return -EIO;
152 152  
153   - soc_ac97_ops.write(codec->ac97, reg, val);
  153 + soc_ac97_ops->write(codec->ac97, reg, val);
154 154 cache[reg / 2] = val;
155 155 return 0;
156 156 }
... ... @@ -162,7 +162,7 @@
162 162  
163 163 if (reg > AC97_STAC_PAGE0) {
164 164 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
165   - val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0);
  165 + val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0);
166 166 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
167 167 return val;
168 168 }
... ... @@ -173,7 +173,7 @@
173 173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
174 174 reg == AC97_VENDOR_ID2) {
175 175  
176   - val = soc_ac97_ops.read(codec->ac97, reg);
  176 + val = soc_ac97_ops->read(codec->ac97, reg);
177 177 return val;
178 178 }
179 179 return cache[reg / 2];
180 180  
... ... @@ -240,15 +240,15 @@
240 240  
241 241 static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
242 242 {
243   - if (try_warm && soc_ac97_ops.warm_reset) {
244   - soc_ac97_ops.warm_reset(codec->ac97);
  243 + if (try_warm && soc_ac97_ops->warm_reset) {
  244 + soc_ac97_ops->warm_reset(codec->ac97);
245 245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
246 246 return 1;
247 247 }
248 248  
249   - soc_ac97_ops.reset(codec->ac97);
250   - if (soc_ac97_ops.warm_reset)
251   - soc_ac97_ops.warm_reset(codec->ac97);
  249 + soc_ac97_ops->reset(codec->ac97);
  250 + if (soc_ac97_ops->warm_reset)
  251 + soc_ac97_ops->warm_reset(codec->ac97);
252 252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
253 253 return -EIO;
254 254 return 0;
... ... @@ -272,7 +272,7 @@
272 272 return -EIO;
273 273 }
274 274 codec->ac97->bus->ops->warm_reset(codec->ac97);
275   - id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2);
  275 + id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2);
276 276 if (id != 0x4c13) {
277 277 stac9766_reset(codec, 0);
278 278 reset++;
... ... @@ -336,7 +336,7 @@
336 336 {
337 337 int ret = 0;
338 338  
339   - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
  339 + ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
340 340 if (ret < 0)
341 341 goto codec_err;
342 342  
sound/soc/codecs/wm9705.c
... ... @@ -209,7 +209,7 @@
209 209 case AC97_RESET:
210 210 case AC97_VENDOR_ID1:
211 211 case AC97_VENDOR_ID2:
212   - return soc_ac97_ops.read(codec->ac97, reg);
  212 + return soc_ac97_ops->read(codec->ac97, reg);
213 213 default:
214 214 reg = reg >> 1;
215 215  
... ... @@ -225,7 +225,7 @@
225 225 {
226 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 229 reg = reg >> 1;
230 230 if (reg < (ARRAY_SIZE(wm9705_reg)))
231 231 cache[reg] = val;
... ... @@ -294,8 +294,8 @@
294 294  
295 295 static int wm9705_reset(struct snd_soc_codec *codec)
296 296 {
297   - if (soc_ac97_ops.reset) {
298   - soc_ac97_ops.reset(codec->ac97);
  297 + if (soc_ac97_ops->reset) {
  298 + soc_ac97_ops->reset(codec->ac97);
299 299 if (ac97_read(codec, 0) == wm9705_reg[0])
300 300 return 0; /* Success */
301 301 }
... ... @@ -306,7 +306,7 @@
306 306 #ifdef CONFIG_PM
307 307 static 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 311 return 0;
312 312 }
... ... @@ -323,7 +323,7 @@
323 323 }
324 324  
325 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 329 return 0;
... ... @@ -337,7 +337,7 @@
337 337 {
338 338 int ret = 0;
339 339  
340   - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
  340 + ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
341 341 if (ret < 0) {
342 342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
343 343 return ret;
sound/soc/codecs/wm9712.c
... ... @@ -455,7 +455,7 @@
455 455 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
456 456 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
457 457 reg == AC97_REC_GAIN)
458   - return soc_ac97_ops.read(codec->ac97, reg);
  458 + return soc_ac97_ops->read(codec->ac97, reg);
459 459 else {
460 460 reg = reg >> 1;
461 461  
... ... @@ -472,7 +472,7 @@
472 472 u16 *cache = codec->reg_cache;
473 473  
474 474 if (reg < 0x7c)
475   - soc_ac97_ops.write(codec->ac97, reg, val);
  475 + soc_ac97_ops->write(codec->ac97, reg, val);
476 476 reg = reg >> 1;
477 477 if (reg < (ARRAY_SIZE(wm9712_reg)))
478 478 cache[reg] = val;
479 479  
... ... @@ -581,15 +581,15 @@
581 581  
582 582 static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
583 583 {
584   - if (try_warm && soc_ac97_ops.warm_reset) {
585   - soc_ac97_ops.warm_reset(codec->ac97);
  584 + if (try_warm && soc_ac97_ops->warm_reset) {
  585 + soc_ac97_ops->warm_reset(codec->ac97);
586 586 if (ac97_read(codec, 0) == wm9712_reg[0])
587 587 return 1;
588 588 }
589 589  
590   - soc_ac97_ops.reset(codec->ac97);
591   - if (soc_ac97_ops.warm_reset)
592   - soc_ac97_ops.warm_reset(codec->ac97);
  590 + soc_ac97_ops->reset(codec->ac97);
  591 + if (soc_ac97_ops->warm_reset)
  592 + soc_ac97_ops->warm_reset(codec->ac97);
593 593 if (ac97_read(codec, 0) != wm9712_reg[0])
594 594 goto err;
595 595 return 0;
... ... @@ -624,7 +624,7 @@
624 624 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
625 625 (i > 0x58 && i != 0x5c))
626 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 @@
635 635 {
636 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 639 if (ret < 0) {
640 640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
641 641 return ret;
sound/soc/codecs/wm9713.c
... ... @@ -652,7 +652,7 @@
652 652 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
653 653 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
654 654 reg == AC97_CD)
655   - return soc_ac97_ops.read(codec->ac97, reg);
  655 + return soc_ac97_ops->read(codec->ac97, reg);
656 656 else {
657 657 reg = reg >> 1;
658 658  
... ... @@ -668,7 +668,7 @@
668 668 {
669 669 u16 *cache = codec->reg_cache;
670 670 if (reg < 0x7c)
671   - soc_ac97_ops.write(codec->ac97, reg, val);
  671 + soc_ac97_ops->write(codec->ac97, reg, val);
672 672 reg = reg >> 1;
673 673 if (reg < (ARRAY_SIZE(wm9713_reg)))
674 674 cache[reg] = val;
675 675  
... ... @@ -1095,15 +1095,15 @@
1095 1095  
1096 1096 int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097 1097 {
1098   - if (try_warm && soc_ac97_ops.warm_reset) {
1099   - soc_ac97_ops.warm_reset(codec->ac97);
  1098 + if (try_warm && soc_ac97_ops->warm_reset) {
  1099 + soc_ac97_ops->warm_reset(codec->ac97);
1100 1100 if (ac97_read(codec, 0) == wm9713_reg[0])
1101 1101 return 1;
1102 1102 }
1103 1103  
1104   - soc_ac97_ops.reset(codec->ac97);
1105   - if (soc_ac97_ops.warm_reset)
1106   - soc_ac97_ops.warm_reset(codec->ac97);
  1104 + soc_ac97_ops->reset(codec->ac97);
  1105 + if (soc_ac97_ops->warm_reset)
  1106 + soc_ac97_ops->warm_reset(codec->ac97);
1107 1107 if (ac97_read(codec, 0) != wm9713_reg[0])
1108 1108 return -EIO;
1109 1109 return 0;
... ... @@ -1180,7 +1180,7 @@
1180 1180 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1181 1181 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1182 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 @@
1197 1197 return -ENOMEM;
1198 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 1201 if (ret < 0)
1202 1202 goto codec_err;
1203 1203  
sound/soc/fsl/imx-ssi.c
... ... @@ -501,13 +501,12 @@
501 501 imx_ssi_ac97_read(ac97, 0);
502 502 }
503 503  
504   -struct snd_ac97_bus_ops soc_ac97_ops = {
  504 +static struct snd_ac97_bus_ops imx_ssi_ac97_ops = {
505 505 .read = imx_ssi_ac97_read,
506 506 .write = imx_ssi_ac97_write,
507 507 .reset = imx_ssi_ac97_reset,
508 508 .warm_reset = imx_ssi_ac97_warm_reset
509 509 };
510   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
511 510  
512 511 static int imx_ssi_probe(struct platform_device *pdev)
513 512 {
... ... @@ -583,6 +582,12 @@
583 582  
584 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 591 ret = snd_soc_register_component(&pdev->dev, &imx_component,
587 592 dai, 1);
588 593 if (ret) {
... ... @@ -630,6 +635,7 @@
630 635 release_mem_region(res->start, resource_size(res));
631 636 clk_disable_unprepare(ssi->clk);
632 637 failed_clk:
  638 + snd_soc_set_ac97_ops(NULL);
633 639  
634 640 return ret;
635 641 }
... ... @@ -649,6 +655,7 @@
649 655  
650 656 release_mem_region(res->start, resource_size(res));
651 657 clk_disable_unprepare(ssi->clk);
  658 + snd_soc_set_ac97_ops(NULL);
652 659  
653 660 return 0;
654 661 }
sound/soc/fsl/mpc5200_psc_ac97.c
... ... @@ -131,13 +131,12 @@
131 131 psc_ac97_warm_reset(ac97);
132 132 }
133 133  
134   -struct snd_ac97_bus_ops soc_ac97_ops = {
  134 +static struct snd_ac97_bus_ops psc_ac97_ops = {
135 135 .read = psc_ac97_read,
136 136 .write = psc_ac97_write,
137 137 .reset = psc_ac97_cold_reset,
138 138 .warm_reset = psc_ac97_warm_reset,
139 139 };
140   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
141 140  
142 141 static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
143 142 struct snd_pcm_hw_params *params,
... ... @@ -290,6 +289,12 @@
290 289 if (rc != 0)
291 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 298 rc = snd_soc_register_component(&op->dev, &psc_ac97_component,
294 299 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
295 300 if (rc != 0) {
... ... @@ -318,6 +323,7 @@
318 323 {
319 324 mpc5200_audio_dma_destroy(op);
320 325 snd_soc_unregister_component(&op->dev);
  326 + snd_soc_set_ac97_ops(NULL);
321 327 return 0;
322 328 }
323 329  
sound/soc/nuc900/nuc900-ac97.c
... ... @@ -197,13 +197,12 @@
197 197 }
198 198  
199 199 /* AC97 controller operations */
200   -struct snd_ac97_bus_ops soc_ac97_ops = {
  200 +static struct snd_ac97_bus_ops nuc900_ac97_ops = {
201 201 .read = nuc900_ac97_read,
202 202 .write = nuc900_ac97_write,
203 203 .reset = nuc900_ac97_cold_reset,
204 204 .warm_reset = nuc900_ac97_warm_reset,
205   -}
206   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
  205 +};
207 206  
208 207 static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,
209 208 int cmd, struct snd_soc_dai *dai)
... ... @@ -356,6 +355,10 @@
356 355  
357 356 nuc900_ac97_data = nuc900_audio;
358 357  
  358 + ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops);
  359 + if (ret)
  360 + goto out;
  361 +
359 362 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
360 363 &nuc900_ac97_dai, 1);
361 364 if (ret)
... ... @@ -367,6 +370,7 @@
367 370 return 0;
368 371  
369 372 out:
  373 + snd_soc_set_ac97_ops(NULL);
370 374 return ret;
371 375 }
372 376  
... ... @@ -375,6 +379,7 @@
375 379 snd_soc_unregister_component(&pdev->dev);
376 380  
377 381 nuc900_ac97_data = NULL;
  382 + snd_soc_set_ac97_ops(NULL);
378 383  
379 384 return 0;
380 385 }
sound/soc/pxa/pxa2xx-ac97.c
... ... @@ -41,13 +41,12 @@
41 41 pxa2xx_ac97_finish_reset(ac97);
42 42 }
43 43  
44   -struct snd_ac97_bus_ops soc_ac97_ops = {
  44 +static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
45 45 .read = pxa2xx_ac97_read,
46 46 .write = pxa2xx_ac97_write,
47 47 .warm_reset = pxa2xx_ac97_warm_reset,
48 48 .reset = pxa2xx_ac97_cold_reset,
49 49 };
50   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
51 50  
52 51 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
53 52 .name = "AC97 PCM Stereo out",
... ... @@ -244,6 +243,10 @@
244 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 250 /* Punt most of the init to the SoC probe; we may need the machine
248 251 * driver to do interesting things with the clocking to get us up
249 252 * and running.
... ... @@ -255,6 +258,7 @@
255 258 static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
256 259 {
257 260 snd_soc_unregister_component(&pdev->dev);
  261 + snd_soc_set_ac97_ops(NULL);
258 262 return 0;
259 263 }
260 264  
sound/soc/samsung/ac97.c
... ... @@ -214,13 +214,12 @@
214 214 return IRQ_HANDLED;
215 215 }
216 216  
217   -struct snd_ac97_bus_ops soc_ac97_ops = {
  217 +static struct snd_ac97_bus_ops s3c_ac97_ops = {
218 218 .read = s3c_ac97_read,
219 219 .write = s3c_ac97_write,
220 220 .warm_reset = s3c_ac97_warm_reset,
221 221 .reset = s3c_ac97_cold_reset,
222 222 };
223   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
224 223  
225 224 static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
226 225 struct snd_pcm_hw_params *params,
... ... @@ -452,6 +451,12 @@
452 451 goto err4;
453 452 }
454 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 +
455 460 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
456 461 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
457 462 if (ret)
... ... @@ -472,7 +477,7 @@
472 477 err3:
473 478 clk_disable_unprepare(s3c_ac97.ac97_clk);
474 479 err2:
475   -
  480 + snd_soc_set_ac97_ops(NULL);
476 481 return ret;
477 482 }
478 483  
... ... @@ -488,6 +493,7 @@
488 493 free_irq(irq_res->start, NULL);
489 494  
490 495 clk_disable_unprepare(s3c_ac97.ac97_clk);
  496 + snd_soc_set_ac97_ops(NULL);
491 497  
492 498 return 0;
493 499 }
... ... @@ -227,13 +227,12 @@
227 227 hac_ac97_warmrst(ac97);
228 228 }
229 229  
230   -struct snd_ac97_bus_ops soc_ac97_ops = {
  230 +static struct snd_ac97_bus_ops hac_ac97_ops = {
231 231 .read = hac_ac97_read,
232 232 .write = hac_ac97_write,
233 233 .reset = hac_ac97_coldrst,
234 234 .warm_reset = hac_ac97_warmrst,
235 235 };
236   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 236  
238 237 static int hac_hw_params(struct snd_pcm_substream *substream,
239 238 struct snd_pcm_hw_params *params,
... ... @@ -316,6 +315,10 @@
316 315  
317 316 static 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 322 return snd_soc_register_component(&pdev->dev, &sh4_hac_component,
320 323 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
321 324 }
... ... @@ -323,6 +326,7 @@
323 326 static int hac_soc_platform_remove(struct platform_device *pdev)
324 327 {
325 328 snd_soc_unregister_component(&pdev->dev);
  329 + snd_soc_set_ac97_ops(NULL);
326 330 return 0;
327 331 }
328 332  
sound/soc/soc-core.c
... ... @@ -2079,6 +2079,22 @@
2079 2079 }
2080 2080 EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2081 2081  
  2082 +struct snd_ac97_bus_ops *soc_ac97_ops;
  2083 +
  2084 +int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
  2085 +{
  2086 + if (ops == soc_ac97_ops)
  2087 + return 0;
  2088 +
  2089 + if (soc_ac97_ops && ops)
  2090 + return -EBUSY;
  2091 +
  2092 + soc_ac97_ops = ops;
  2093 +
  2094 + return 0;
  2095 +}
  2096 +EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
  2097 +
2082 2098 /**
2083 2099 * snd_soc_free_ac97_codec - free AC97 codec device
2084 2100 * @codec: audio codec
sound/soc/tegra/tegra20_ac97.c
... ... @@ -142,13 +142,12 @@
142 142 } while (!time_after(jiffies, timeout));
143 143 }
144 144  
145   -struct snd_ac97_bus_ops soc_ac97_ops = {
  145 +static struct snd_ac97_bus_ops tegra20_ac97_ops = {
146 146 .read = tegra20_ac97_codec_read,
147 147 .write = tegra20_ac97_codec_write,
148 148 .reset = tegra20_ac97_codec_reset,
149 149 .warm_reset = tegra20_ac97_codec_warm_reset,
150 150 };
151   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
152 151  
153 152 static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)
154 153 {
... ... @@ -409,6 +408,12 @@
409 408 goto err_asoc_utils_fini;
410 409 }
411 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 +
412 417 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
413 418 &tegra20_ac97_dai, 1);
414 419 if (ret) {
... ... @@ -436,6 +441,7 @@
436 441 tegra_asoc_utils_fini(&ac97->util_data);
437 442 err_clk_put:
438 443 err:
  444 + snd_soc_set_ac97_ops(NULL);
439 445 return ret;
440 446 }
441 447  
... ... @@ -449,6 +455,8 @@
449 455 tegra_asoc_utils_fini(&ac97->util_data);
450 456  
451 457 clk_disable_unprepare(ac97->clk_ac97);
  458 +
  459 + snd_soc_set_ac97_ops(NULL);
452 460  
453 461 return 0;
454 462 }
sound/soc/txx9/txx9aclc-ac97.c
... ... @@ -119,12 +119,11 @@
119 119 }
120 120  
121 121 /* AC97 controller operations */
122   -struct snd_ac97_bus_ops soc_ac97_ops = {
  122 +static struct snd_ac97_bus_ops txx9aclc_ac97_ops = {
123 123 .read = txx9aclc_ac97_read,
124 124 .write = txx9aclc_ac97_write,
125 125 .reset = txx9aclc_ac97_cold_reset,
126 126 };
127   -EXPORT_SYMBOL_GPL(soc_ac97_ops);
128 127  
129 128 static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)
130 129 {
... ... @@ -206,6 +205,10 @@
206 205 if (err < 0)
207 206 return err;
208 207  
  208 + err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops);
  209 + if (err < 0)
  210 + return err;
  211 +
209 212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,
210 213 &txx9aclc_ac97_dai, 1);
211 214 }
... ... @@ -213,6 +216,7 @@
213 216 static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
214 217 {
215 218 snd_soc_unregister_component(&pdev->dev);
  219 + snd_soc_set_ac97_ops(NULL);
216 220 return 0;
217 221 }
218 222