aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h4
-rw-r--r--sound/soc/au1x/ac97c.c7
-rw-r--r--sound/soc/au1x/psc-ac97.c7
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c11
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c10
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c12
-rw-r--r--sound/soc/codecs/stac9766.c22
-rw-r--r--sound/soc/codecs/wm9705.c14
-rw-r--r--sound/soc/codecs/wm9712.c18
-rw-r--r--sound/soc/codecs/wm9713.c18
-rw-r--r--sound/soc/fsl/imx-ssi.c11
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c10
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c11
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c8
-rw-r--r--sound/soc/samsung/ac97.c12
-rw-r--r--sound/soc/sh/hac.c8
-rw-r--r--sound/soc/soc-core.c16
-rw-r--r--sound/soc/tegra/tegra20_ac97.c12
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c8
20 files changed, 154 insertions, 72 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 85c15226103b..6eabee7ec15a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -340,7 +340,7 @@ struct snd_soc_jack_gpio;
340 340
341typedef int (*hw_write_t)(void *,const char* ,int); 341typedef int (*hw_write_t)(void *,const char* ,int);
342 342
343extern struct snd_ac97_bus_ops soc_ac97_ops; 343extern struct snd_ac97_bus_ops *soc_ac97_ops;
344 344
345enum snd_soc_control_type { 345enum snd_soc_control_type {
346 SND_SOC_I2C = 1, 346 SND_SOC_I2C = 1,
@@ -467,6 +467,8 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
467 struct snd_ac97_bus_ops *ops, int num); 467 struct snd_ac97_bus_ops *ops, int num);
468void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 468void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
469 469
470int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
471
470/* 472/*
471 *Controls 473 *Controls
472 */ 474 */
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index a51dabe20cbb..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)
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a97ba1367b69..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,
@@ -417,6 +416,10 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
417 416
418 platform_set_drvdata(pdev, wd); 417 platform_set_drvdata(pdev, wd);
419 418
419 ret = snd_soc_set_ac97_ops(&psc_ac97_ops);
420 if (ret)
421 return ret;
422
420 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, 423 ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,
421 &wd->dai_drv, 1); 424 &wd->dai_drv, 1);
422 if (ret) 425 if (ret)
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 024e2dbe6c7f..c5af677ba49c 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -198,13 +198,12 @@ static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)
198#endif 198#endif
199} 199}
200 200
201struct snd_ac97_bus_ops soc_ac97_ops = { 201static struct snd_ac97_bus_ops bf5xx_ac97_ops = {
202 .read = bf5xx_ac97_read, 202 .read = bf5xx_ac97_read,
203 .write = bf5xx_ac97_write, 203 .write = bf5xx_ac97_write,
204 .warm_reset = bf5xx_ac97_warm_reset, 204 .warm_reset = bf5xx_ac97_warm_reset,
205 .reset = bf5xx_ac97_cold_reset, 205 .reset = bf5xx_ac97_cold_reset,
206}; 206};
207EXPORT_SYMBOL_GPL(soc_ac97_ops);
208 207
209#ifdef CONFIG_PM 208#ifdef CONFIG_PM
210static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) 209static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
@@ -336,6 +335,12 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
336 goto sport_config_err; 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 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component, 344 ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,
340 &bfin_ac97_dai, 1); 345 &bfin_ac97_dai, 1);
341 if (ret) { 346 if (ret) {
@@ -350,6 +355,7 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)
350sport_config_err: 355sport_config_err:
351 sport_done(sport_handle); 356 sport_done(sport_handle);
352sport_err: 357sport_err:
358 snd_soc_set_ac97_ops(NULL);
353 359
354 return ret; 360 return ret;
355} 361}
@@ -360,6 +366,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)
360 366
361 snd_soc_unregister_component(&pdev->dev); 367 snd_soc_unregister_component(&pdev->dev);
362 sport_done(sport_handle); 368 sport_done(sport_handle);
369 snd_soc_set_ac97_ops(NULL);
363 370
364 return 0; 371 return 0;
365} 372}
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index d49e0556e381..4bc9490e2c84 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -237,13 +237,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)
237 return IRQ_HANDLED; 237 return IRQ_HANDLED;
238} 238}
239 239
240struct snd_ac97_bus_ops soc_ac97_ops = { 240static struct snd_ac97_bus_ops ep93xx_ac97_ops = {
241 .read = ep93xx_ac97_read, 241 .read = ep93xx_ac97_read,
242 .write = ep93xx_ac97_write, 242 .write = ep93xx_ac97_write,
243 .reset = ep93xx_ac97_cold_reset, 243 .reset = ep93xx_ac97_cold_reset,
244 .warm_reset = ep93xx_ac97_warm_reset, 244 .warm_reset = ep93xx_ac97_warm_reset,
245}; 245};
246EXPORT_SYMBOL_GPL(soc_ac97_ops);
247 246
248static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, 247static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
249 int cmd, struct snd_soc_dai *dai) 248 int cmd, struct snd_soc_dai *dai)
@@ -395,6 +394,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
395 ep93xx_ac97_info = info; 394 ep93xx_ac97_info = info;
396 platform_set_drvdata(pdev, info); 395 platform_set_drvdata(pdev, info);
397 396
397 ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops);
398 if (ret)
399 goto fail;
400
398 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, 401 ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,
399 &ep93xx_ac97_dai, 1); 402 &ep93xx_ac97_dai, 1);
400 if (ret) 403 if (ret)
@@ -405,6 +408,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
405fail: 408fail:
406 platform_set_drvdata(pdev, NULL); 409 platform_set_drvdata(pdev, NULL);
407 ep93xx_ac97_info = NULL; 410 ep93xx_ac97_info = NULL;
411 snd_soc_set_ac97_ops(NULL);
408 return ret; 412 return ret;
409} 413}
410 414
@@ -420,6 +424,8 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)
420 platform_set_drvdata(pdev, NULL); 424 platform_set_drvdata(pdev, NULL);
421 ep93xx_ac97_info = NULL; 425 ep93xx_ac97_info = NULL;
422 426
427 snd_soc_set_ac97_ops(NULL);
428
423 return 0; 429 return 0;
424} 430}
425 431
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/stac9766.c b/sound/soc/codecs/stac9766.c
index cbc7ae322324..a5455c1aea42 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -143,14 +143,14 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
143 143
144 if (reg > AC97_STAC_PAGE0) { 144 if (reg > AC97_STAC_PAGE0) {
145 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 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 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 147 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
148 return 0; 148 return 0;
149 } 149 }
150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg)) 150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
151 return -EIO; 151 return -EIO;
152 152
153 soc_ac97_ops.write(codec->ac97, reg, val); 153 soc_ac97_ops->write(codec->ac97, reg, val);
154 cache[reg / 2] = val; 154 cache[reg / 2] = val;
155 return 0; 155 return 0;
156} 156}
@@ -162,7 +162,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
162 162
163 if (reg > AC97_STAC_PAGE0) { 163 if (reg > AC97_STAC_PAGE0) {
164 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 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 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 166 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
167 return val; 167 return val;
168 } 168 }
@@ -173,7 +173,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || 173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
174 reg == AC97_VENDOR_ID2) { 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 return val; 177 return val;
178 } 178 }
179 return cache[reg / 2]; 179 return cache[reg / 2];
@@ -240,15 +240,15 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
240 240
241static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) 241static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
242{ 242{
243 if (try_warm && soc_ac97_ops.warm_reset) { 243 if (try_warm && soc_ac97_ops->warm_reset) {
244 soc_ac97_ops.warm_reset(codec->ac97); 244 soc_ac97_ops->warm_reset(codec->ac97);
245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) 245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
246 return 1; 246 return 1;
247 } 247 }
248 248
249 soc_ac97_ops.reset(codec->ac97); 249 soc_ac97_ops->reset(codec->ac97);
250 if (soc_ac97_ops.warm_reset) 250 if (soc_ac97_ops->warm_reset)
251 soc_ac97_ops.warm_reset(codec->ac97); 251 soc_ac97_ops->warm_reset(codec->ac97);
252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) 252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
253 return -EIO; 253 return -EIO;
254 return 0; 254 return 0;
@@ -272,7 +272,7 @@ reset:
272 return -EIO; 272 return -EIO;
273 } 273 }
274 codec->ac97->bus->ops->warm_reset(codec->ac97); 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 if (id != 0x4c13) { 276 if (id != 0x4c13) {
277 stac9766_reset(codec, 0); 277 stac9766_reset(codec, 0);
278 reset++; 278 reset++;
@@ -336,7 +336,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
336{ 336{
337 int ret = 0; 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 if (ret < 0) 340 if (ret < 0)
341 goto codec_err; 341 goto codec_err;
342 342
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index a5fc61dbcd47..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,7 +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 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 340 ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);
341 if (ret < 0) { 341 if (ret < 0) {
342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 342 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
343 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/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index c6fa03e2114a..bd40849454a8 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -501,13 +501,12 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
501 imx_ssi_ac97_read(ac97, 0); 501 imx_ssi_ac97_read(ac97, 0);
502} 502}
503 503
504struct snd_ac97_bus_ops soc_ac97_ops = { 504static struct snd_ac97_bus_ops imx_ssi_ac97_ops = {
505 .read = imx_ssi_ac97_read, 505 .read = imx_ssi_ac97_read,
506 .write = imx_ssi_ac97_write, 506 .write = imx_ssi_ac97_write,
507 .reset = imx_ssi_ac97_reset, 507 .reset = imx_ssi_ac97_reset,
508 .warm_reset = imx_ssi_ac97_warm_reset 508 .warm_reset = imx_ssi_ac97_warm_reset
509}; 509};
510EXPORT_SYMBOL_GPL(soc_ac97_ops);
511 510
512static int imx_ssi_probe(struct platform_device *pdev) 511static int imx_ssi_probe(struct platform_device *pdev)
513{ 512{
@@ -583,6 +582,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
583 582
584 platform_set_drvdata(pdev, ssi); 583 platform_set_drvdata(pdev, ssi);
585 584
585 ret = snd_soc_set_ac97_ops(&imx_ssi_ac97_ops);
586 if (ret != 0) {
587 dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret);
588 goto failed_register;
589 }
590
586 ret = snd_soc_register_component(&pdev->dev, &imx_component, 591 ret = snd_soc_register_component(&pdev->dev, &imx_component,
587 dai, 1); 592 dai, 1);
588 if (ret) { 593 if (ret) {
@@ -630,6 +635,7 @@ failed_register:
630 release_mem_region(res->start, resource_size(res)); 635 release_mem_region(res->start, resource_size(res));
631 clk_disable_unprepare(ssi->clk); 636 clk_disable_unprepare(ssi->clk);
632failed_clk: 637failed_clk:
638 snd_soc_set_ac97_ops(NULL);
633 639
634 return ret; 640 return ret;
635} 641}
@@ -649,6 +655,7 @@ static int imx_ssi_remove(struct platform_device *pdev)
649 655
650 release_mem_region(res->start, resource_size(res)); 656 release_mem_region(res->start, resource_size(res));
651 clk_disable_unprepare(ssi->clk); 657 clk_disable_unprepare(ssi->clk);
658 snd_soc_set_ac97_ops(NULL);
652 659
653 return 0; 660 return 0;
654} 661}
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 4141b35ef0bb..3ef7a0c92efa 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -131,13 +131,12 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
131 psc_ac97_warm_reset(ac97); 131 psc_ac97_warm_reset(ac97);
132} 132}
133 133
134struct snd_ac97_bus_ops soc_ac97_ops = { 134static struct snd_ac97_bus_ops psc_ac97_ops = {
135 .read = psc_ac97_read, 135 .read = psc_ac97_read,
136 .write = psc_ac97_write, 136 .write = psc_ac97_write,
137 .reset = psc_ac97_cold_reset, 137 .reset = psc_ac97_cold_reset,
138 .warm_reset = psc_ac97_warm_reset, 138 .warm_reset = psc_ac97_warm_reset,
139}; 139};
140EXPORT_SYMBOL_GPL(soc_ac97_ops);
141 140
142static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, 141static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params, 142 struct snd_pcm_hw_params *params,
@@ -290,6 +289,12 @@ static int psc_ac97_of_probe(struct platform_device *op)
290 if (rc != 0) 289 if (rc != 0)
291 return rc; 290 return rc;
292 291
292 rc = snd_soc_set_ac97_ops(&psc_ac97_ops);
293 if (rc != 0) {
294 dev_err(&op->dev, "Failed to set AC'97 ops: %d\n", ret);
295 return rc;
296 }
297
293 rc = snd_soc_register_component(&op->dev, &psc_ac97_component, 298 rc = snd_soc_register_component(&op->dev, &psc_ac97_component,
294 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); 299 psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
295 if (rc != 0) { 300 if (rc != 0) {
@@ -318,6 +323,7 @@ static int psc_ac97_of_remove(struct platform_device *op)
318{ 323{
319 mpc5200_audio_dma_destroy(op); 324 mpc5200_audio_dma_destroy(op);
320 snd_soc_unregister_component(&op->dev); 325 snd_soc_unregister_component(&op->dev);
326 snd_soc_set_ac97_ops(NULL);
321 return 0; 327 return 0;
322} 328}
323 329
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index 8dea4c1fd997..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)
@@ -356,6 +355,10 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
356 355
357 nuc900_ac97_data = nuc900_audio; 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 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, 362 ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,
360 &nuc900_ac97_dai, 1); 363 &nuc900_ac97_dai, 1);
361 if (ret) 364 if (ret)
@@ -367,6 +370,7 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
367 return 0; 370 return 0;
368 371
369out: 372out:
373 snd_soc_set_ac97_ops(NULL);
370 return ret; 374 return ret;
371} 375}
372 376
@@ -375,6 +379,7 @@ static int nuc900_ac97_drvremove(struct platform_device *pdev)
375 snd_soc_unregister_component(&pdev->dev); 379 snd_soc_unregister_component(&pdev->dev);
376 380
377 nuc900_ac97_data = NULL; 381 nuc900_ac97_data = NULL;
382 snd_soc_set_ac97_ops(NULL);
378 383
379 return 0; 384 return 0;
380} 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 04d7fd461484..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,
@@ -452,6 +451,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)
452 goto err4; 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 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, 460 ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
456 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); 461 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
457 if (ret) 462 if (ret)
@@ -472,7 +477,7 @@ err4:
472err3: 477err3:
473 clk_disable_unprepare(s3c_ac97.ac97_clk); 478 clk_disable_unprepare(s3c_ac97.ac97_clk);
474err2: 479err2:
475 480 snd_soc_set_ac97_ops(NULL);
476 return ret; 481 return ret;
477} 482}
478 483
@@ -488,6 +493,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
488 free_irq(irq_res->start, NULL); 493 free_irq(irq_res->start, NULL);
489 494
490 clk_disable_unprepare(s3c_ac97.ac97_clk); 495 clk_disable_unprepare(s3c_ac97.ac97_clk);
496 snd_soc_set_ac97_ops(NULL);
491 497
492 return 0; 498 return 0;
493} 499}
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index af19f77b7bf0..0af2e4dfd139 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -227,13 +227,12 @@ static void hac_ac97_coldrst(struct snd_ac97 *ac97)
227 hac_ac97_warmrst(ac97); 227 hac_ac97_warmrst(ac97);
228} 228}
229 229
230struct snd_ac97_bus_ops soc_ac97_ops = { 230static struct snd_ac97_bus_ops hac_ac97_ops = {
231 .read = hac_ac97_read, 231 .read = hac_ac97_read,
232 .write = hac_ac97_write, 232 .write = hac_ac97_write,
233 .reset = hac_ac97_coldrst, 233 .reset = hac_ac97_coldrst,
234 .warm_reset = hac_ac97_warmrst, 234 .warm_reset = hac_ac97_warmrst,
235}; 235};
236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 236
238static int hac_hw_params(struct snd_pcm_substream *substream, 237static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params, 238 struct snd_pcm_hw_params *params,
@@ -316,6 +315,10 @@ static const struct snd_soc_component_driver sh4_hac_component = {
316 315
317static int hac_soc_platform_probe(struct platform_device *pdev) 316static int hac_soc_platform_probe(struct platform_device *pdev)
318{ 317{
318 ret = snd_soc_set_ac97_ops(&hac_ac97_ops);
319 if (ret != 0)
320 return ret;
321
319 return snd_soc_register_component(&pdev->dev, &sh4_hac_component, 322 return snd_soc_register_component(&pdev->dev, &sh4_hac_component,
320 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); 323 sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
321} 324}
@@ -323,6 +326,7 @@ static int hac_soc_platform_probe(struct platform_device *pdev)
323static int hac_soc_platform_remove(struct platform_device *pdev) 326static int hac_soc_platform_remove(struct platform_device *pdev)
324{ 327{
325 snd_soc_unregister_component(&pdev->dev); 328 snd_soc_unregister_component(&pdev->dev);
329 snd_soc_set_ac97_ops(NULL);
326 return 0; 330 return 0;
327} 331}
328 332
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d56bbea6e75e..562d72e04e6e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2079,6 +2079,22 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2079} 2079}
2080EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 2080EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2081 2081
2082struct snd_ac97_bus_ops *soc_ac97_ops;
2083
2084int 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}
2096EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
2097
2082/** 2098/**
2083 * snd_soc_free_ac97_codec - free AC97 codec device 2099 * snd_soc_free_ac97_codec - free AC97 codec device
2084 * @codec: audio codec 2100 * @codec: audio codec
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 48037f784a86..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{
@@ -409,6 +408,12 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
409 goto err_asoc_utils_fini; 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 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, 417 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
413 &tegra20_ac97_dai, 1); 418 &tegra20_ac97_dai, 1);
414 if (ret) { 419 if (ret) {
@@ -436,6 +441,7 @@ err_asoc_utils_fini:
436 tegra_asoc_utils_fini(&ac97->util_data); 441 tegra_asoc_utils_fini(&ac97->util_data);
437err_clk_put: 442err_clk_put:
438err: 443err:
444 snd_soc_set_ac97_ops(NULL);
439 return ret; 445 return ret;
440} 446}
441 447
@@ -450,6 +456,8 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)
450 456
451 clk_disable_unprepare(ac97->clk_ac97); 457 clk_disable_unprepare(ac97->clk_ac97);
452 458
459 snd_soc_set_ac97_ops(NULL);
460
453 return 0; 461 return 0;
454} 462}
455 463
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 8ee8d4220014..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{
@@ -206,6 +205,10 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
206 if (err < 0) 205 if (err < 0)
207 return err; 206 return err;
208 207
208 err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops);
209 if (err < 0)
210 return err;
211
209 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, 212 return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,
210 &txx9aclc_ac97_dai, 1); 213 &txx9aclc_ac97_dai, 1);
211} 214}
@@ -213,6 +216,7 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
213static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) 216static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
214{ 217{
215 snd_soc_unregister_component(&pdev->dev); 218 snd_soc_unregister_component(&pdev->dev);
219 snd_soc_set_ac97_ops(NULL);
216 return 0; 220 return 0;
217} 221}
218 222