aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2014-11-10 16:41:53 -0500
committerMark Brown <broonie@kernel.org>2014-11-18 10:38:03 -0500
commit358a8bb5628420529e4f0b77068155ca8fa8973b (patch)
tree864f2cc85356c306157d6ce65d24be1914bbb21e
parentbc2632140435cc84f9817f1c362479b23dbdfebc (diff)
ASoC: ac97: Push snd_ac97 pointer to the driver level
Now that the ASoC core no longer needs a handle to the AC'97 device that is associated with a CODEC we can remove it from the snd_soc_codec struct and push it into the individual driver state structs like we do for other communication buses. Doing so creates a clean separation between the AC'97 bus support and the ASoC core. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc.h5
-rw-r--r--sound/soc/codecs/ac97.c17
-rw-r--r--sound/soc/codecs/ad1980.c27
-rw-r--r--sound/soc/codecs/stac9766.c38
-rw-r--r--sound/soc/codecs/wm9705.c31
-rw-r--r--sound/soc/codecs/wm9712.c32
-rw-r--r--sound/soc/codecs/wm9713.c31
-rw-r--r--sound/soc/soc-ac97.c40
8 files changed, 141 insertions, 80 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 206cc8d6eefa..9e513ae11749 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -499,8 +499,8 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
499 unsigned int mask, unsigned int value); 499 unsigned int mask, unsigned int value);
500 500
501#ifdef CONFIG_SND_SOC_AC97_BUS 501#ifdef CONFIG_SND_SOC_AC97_BUS
502int snd_soc_new_ac97_codec(struct snd_soc_codec *codec); 502struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec);
503void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 503void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
504 504
505int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops); 505int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops);
506int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, 506int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
@@ -797,7 +797,6 @@ struct snd_soc_codec {
797 struct list_head card_list; 797 struct list_head card_list;
798 798
799 /* runtime */ 799 /* runtime */
800 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
801 unsigned int cache_bypass:1; /* Suppress access to the cache */ 800 unsigned int cache_bypass:1; /* Suppress access to the cache */
802 unsigned int suspended:1; /* Codec is in suspend PM state */ 801 unsigned int suspended:1; /* Codec is in suspend PM state */
803 unsigned int cache_init:1; /* codec cache has been initialized */ 802 unsigned int cache_init:1; /* codec cache has been initialized */
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 5d90924e8b96..c6e5a313ebf4 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -37,10 +37,11 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
37 struct snd_soc_dai *dai) 37 struct snd_soc_dai *dai)
38{ 38{
39 struct snd_soc_codec *codec = dai->codec; 39 struct snd_soc_codec *codec = dai->codec;
40 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
40 41
41 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 42 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
42 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 43 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
43 return snd_ac97_set_rate(codec->ac97, reg, substream->runtime->rate); 44 return snd_ac97_set_rate(ac97, reg, substream->runtime->rate);
44} 45}
45 46
46#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 47#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -70,6 +71,7 @@ static struct snd_soc_dai_driver ac97_dai = {
70 71
71static int ac97_soc_probe(struct snd_soc_codec *codec) 72static int ac97_soc_probe(struct snd_soc_codec *codec)
72{ 73{
74 struct snd_ac97 *ac97;
73 struct snd_ac97_bus *ac97_bus; 75 struct snd_ac97_bus *ac97_bus;
74 struct snd_ac97_template ac97_template; 76 struct snd_ac97_template ac97_template;
75 int ret; 77 int ret;
@@ -81,24 +83,31 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
81 return ret; 83 return ret;
82 84
83 memset(&ac97_template, 0, sizeof(struct snd_ac97_template)); 85 memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
84 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97); 86 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
85 if (ret < 0) 87 if (ret < 0)
86 return ret; 88 return ret;
87 89
90 snd_soc_codec_set_drvdata(codec, ac97);
91
88 return 0; 92 return 0;
89} 93}
90 94
91#ifdef CONFIG_PM 95#ifdef CONFIG_PM
92static int ac97_soc_suspend(struct snd_soc_codec *codec) 96static int ac97_soc_suspend(struct snd_soc_codec *codec)
93{ 97{
94 snd_ac97_suspend(codec->ac97); 98 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
99
100 snd_ac97_suspend(ac97);
95 101
96 return 0; 102 return 0;
97} 103}
98 104
99static int ac97_soc_resume(struct snd_soc_codec *codec) 105static int ac97_soc_resume(struct snd_soc_codec *codec)
100{ 106{
101 snd_ac97_resume(codec->ac97); 107
108 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
109
110 snd_ac97_resume(ac97);
102 111
103 return 0; 112 return 0;
104} 113}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index c6cb101a5b8f..93bd47db6d0c 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -135,6 +135,7 @@ static const struct snd_soc_dapm_route ad1980_dapm_routes[] = {
135static unsigned int ac97_read(struct snd_soc_codec *codec, 135static unsigned int ac97_read(struct snd_soc_codec *codec,
136 unsigned int reg) 136 unsigned int reg)
137{ 137{
138 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
138 u16 *cache = codec->reg_cache; 139 u16 *cache = codec->reg_cache;
139 140
140 switch (reg) { 141 switch (reg) {
@@ -144,7 +145,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
144 case AC97_EXTENDED_STATUS: 145 case AC97_EXTENDED_STATUS:
145 case AC97_VENDOR_ID1: 146 case AC97_VENDOR_ID1:
146 case AC97_VENDOR_ID2: 147 case AC97_VENDOR_ID2:
147 return soc_ac97_ops->read(codec->ac97, reg); 148 return soc_ac97_ops->read(ac97, reg);
148 default: 149 default:
149 reg = reg >> 1; 150 reg = reg >> 1;
150 151
@@ -158,9 +159,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
158static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 159static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
159 unsigned int val) 160 unsigned int val)
160{ 161{
162 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
161 u16 *cache = codec->reg_cache; 163 u16 *cache = codec->reg_cache;
162 164
163 soc_ac97_ops->write(codec->ac97, reg, val); 165 soc_ac97_ops->write(ac97, reg, val);
164 reg = reg >> 1; 166 reg = reg >> 1;
165 if (reg < ARRAY_SIZE(ad1980_reg)) 167 if (reg < ARRAY_SIZE(ad1980_reg))
166 cache[reg] = val; 168 cache[reg] = val;
@@ -186,16 +188,17 @@ static struct snd_soc_dai_driver ad1980_dai = {
186 188
187static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) 189static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
188{ 190{
191 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
189 unsigned int retry_cnt = 0; 192 unsigned int retry_cnt = 0;
190 193
191 do { 194 do {
192 if (try_warm && soc_ac97_ops->warm_reset) { 195 if (try_warm && soc_ac97_ops->warm_reset) {
193 soc_ac97_ops->warm_reset(codec->ac97); 196 soc_ac97_ops->warm_reset(ac97);
194 if (ac97_read(codec, AC97_RESET) == 0x0090) 197 if (ac97_read(codec, AC97_RESET) == 0x0090)
195 return 1; 198 return 1;
196 } 199 }
197 200
198 soc_ac97_ops->reset(codec->ac97); 201 soc_ac97_ops->reset(ac97);
199 /* 202 /*
200 * Set bit 16slot in register 74h, then every slot will has only 203 * Set bit 16slot in register 74h, then every slot will has only
201 * 16 bits. This command is sent out in 20bit mode, in which 204 * 16 bits. This command is sent out in 20bit mode, in which
@@ -215,16 +218,20 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
215 218
216static int ad1980_soc_probe(struct snd_soc_codec *codec) 219static int ad1980_soc_probe(struct snd_soc_codec *codec)
217{ 220{
221 struct snd_ac97 *ac97;
218 int ret; 222 int ret;
219 u16 vendor_id2; 223 u16 vendor_id2;
220 u16 ext_status; 224 u16 ext_status;
221 225
222 ret = snd_soc_new_ac97_codec(codec); 226 ac97 = snd_soc_new_ac97_codec(codec);
223 if (ret < 0) { 227 if (IS_ERR(ac97)) {
224 dev_err(codec->dev, "Failed to register AC97 codec\n"); 228 ret = PTR_ERR(ac97);
229 dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
225 return ret; 230 return ret;
226 } 231 }
227 232
233 snd_soc_codec_set_drvdata(codec, ac97);
234
228 ret = ad1980_reset(codec, 0); 235 ret = ad1980_reset(codec, 0);
229 if (ret < 0) 236 if (ret < 0)
230 goto reset_err; 237 goto reset_err;
@@ -261,13 +268,15 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
261 return 0; 268 return 0;
262 269
263reset_err: 270reset_err:
264 snd_soc_free_ac97_codec(codec); 271 snd_soc_free_ac97_codec(ac97);
265 return ret; 272 return ret;
266} 273}
267 274
268static int ad1980_soc_remove(struct snd_soc_codec *codec) 275static int ad1980_soc_remove(struct snd_soc_codec *codec)
269{ 276{
270 snd_soc_free_ac97_codec(codec); 277 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
278
279 snd_soc_free_ac97_codec(ac97);
271 return 0; 280 return 0;
272} 281}
273 282
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index c0808061b08a..f37a79ec45e6 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -139,18 +139,19 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
139static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg, 139static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
140 unsigned int val) 140 unsigned int val)
141{ 141{
142 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
142 u16 *cache = codec->reg_cache; 143 u16 *cache = codec->reg_cache;
143 144
144 if (reg > AC97_STAC_PAGE0) { 145 if (reg > AC97_STAC_PAGE0) {
145 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 146 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
146 soc_ac97_ops->write(codec->ac97, reg, val); 147 soc_ac97_ops->write(ac97, reg, val);
147 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 148 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
148 return 0; 149 return 0;
149 } 150 }
150 if (reg / 2 >= ARRAY_SIZE(stac9766_reg)) 151 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
151 return -EIO; 152 return -EIO;
152 153
153 soc_ac97_ops->write(codec->ac97, reg, val); 154 soc_ac97_ops->write(ac97, reg, val);
154 cache[reg / 2] = val; 155 cache[reg / 2] = val;
155 return 0; 156 return 0;
156} 157}
@@ -158,11 +159,12 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
158static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, 159static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
159 unsigned int reg) 160 unsigned int reg)
160{ 161{
162 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
161 u16 val = 0, *cache = codec->reg_cache; 163 u16 val = 0, *cache = codec->reg_cache;
162 164
163 if (reg > AC97_STAC_PAGE0) { 165 if (reg > AC97_STAC_PAGE0) {
164 stac9766_ac97_write(codec, AC97_INT_PAGING, 0); 166 stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
165 val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0); 167 val = soc_ac97_ops->read(ac97, reg - AC97_STAC_PAGE0);
166 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
167 return val; 169 return val;
168 } 170 }
@@ -173,7 +175,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
173 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || 175 reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
174 reg == AC97_VENDOR_ID2) { 176 reg == AC97_VENDOR_ID2) {
175 177
176 val = soc_ac97_ops->read(codec->ac97, reg); 178 val = soc_ac97_ops->read(ac97, reg);
177 return val; 179 return val;
178 } 180 }
179 return cache[reg / 2]; 181 return cache[reg / 2];
@@ -240,15 +242,17 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
240 242
241static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) 243static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
242{ 244{
245 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
246
243 if (try_warm && soc_ac97_ops->warm_reset) { 247 if (try_warm && soc_ac97_ops->warm_reset) {
244 soc_ac97_ops->warm_reset(codec->ac97); 248 soc_ac97_ops->warm_reset(ac97);
245 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) 249 if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
246 return 1; 250 return 1;
247 } 251 }
248 252
249 soc_ac97_ops->reset(codec->ac97); 253 soc_ac97_ops->reset(ac97);
250 if (soc_ac97_ops->warm_reset) 254 if (soc_ac97_ops->warm_reset)
251 soc_ac97_ops->warm_reset(codec->ac97); 255 soc_ac97_ops->warm_reset(ac97);
252 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) 256 if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
253 return -EIO; 257 return -EIO;
254 return 0; 258 return 0;
@@ -262,6 +266,7 @@ static int stac9766_codec_suspend(struct snd_soc_codec *codec)
262 266
263static int stac9766_codec_resume(struct snd_soc_codec *codec) 267static int stac9766_codec_resume(struct snd_soc_codec *codec)
264{ 268{
269 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
265 u16 id, reset; 270 u16 id, reset;
266 271
267 reset = 0; 272 reset = 0;
@@ -271,8 +276,8 @@ reset:
271 printk(KERN_ERR "stac9766 failed to resume"); 276 printk(KERN_ERR "stac9766 failed to resume");
272 return -EIO; 277 return -EIO;
273 } 278 }
274 codec->ac97->bus->ops->warm_reset(codec->ac97); 279 ac97->bus->ops->warm_reset(ac97);
275 id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2); 280 id = soc_ac97_ops->read(ac97, AC97_VENDOR_ID2);
276 if (id != 0x4c13) { 281 if (id != 0x4c13) {
277 stac9766_reset(codec, 0); 282 stac9766_reset(codec, 0);
278 reset++; 283 reset++;
@@ -332,11 +337,14 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
332 337
333static int stac9766_codec_probe(struct snd_soc_codec *codec) 338static int stac9766_codec_probe(struct snd_soc_codec *codec)
334{ 339{
340 struct snd_ac97 *ac97;
335 int ret = 0; 341 int ret = 0;
336 342
337 ret = snd_soc_new_ac97_codec(codec); 343 ac97 = snd_soc_new_ac97_codec(codec);
338 if (ret < 0) 344 if (IS_ERR(ac97))
339 goto codec_err; 345 return PTR_ERR(ac97);
346
347 snd_soc_codec_set_drvdata(codec, ac97);
340 348
341 /* do a cold reset for the controller and then try 349 /* do a cold reset for the controller and then try
342 * a warm reset followed by an optional cold reset for codec */ 350 * a warm reset followed by an optional cold reset for codec */
@@ -355,13 +363,15 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
355 return 0; 363 return 0;
356 364
357codec_err: 365codec_err:
358 snd_soc_free_ac97_codec(codec); 366 snd_soc_free_ac97_codec(ac97);
359 return ret; 367 return ret;
360} 368}
361 369
362static int stac9766_codec_remove(struct snd_soc_codec *codec) 370static int stac9766_codec_remove(struct snd_soc_codec *codec)
363{ 371{
364 snd_soc_free_ac97_codec(codec); 372 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
373
374 snd_soc_free_ac97_codec(ac97);
365 return 0; 375 return 0;
366} 376}
367 377
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 5b5118ba1526..d3a800fa6f06 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -203,13 +203,14 @@ static const struct snd_soc_dapm_route wm9705_audio_map[] = {
203/* We use a register cache to enhance read performance. */ 203/* We use a register cache to enhance read performance. */
204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) 204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
205{ 205{
206 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
206 u16 *cache = codec->reg_cache; 207 u16 *cache = codec->reg_cache;
207 208
208 switch (reg) { 209 switch (reg) {
209 case AC97_RESET: 210 case AC97_RESET:
210 case AC97_VENDOR_ID1: 211 case AC97_VENDOR_ID1:
211 case AC97_VENDOR_ID2: 212 case AC97_VENDOR_ID2:
212 return soc_ac97_ops->read(codec->ac97, reg); 213 return soc_ac97_ops->read(ac97, reg);
213 default: 214 default:
214 reg = reg >> 1; 215 reg = reg >> 1;
215 216
@@ -223,9 +224,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
223static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 224static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
224 unsigned int val) 225 unsigned int val)
225{ 226{
227 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
226 u16 *cache = codec->reg_cache; 228 u16 *cache = codec->reg_cache;
227 229
228 soc_ac97_ops->write(codec->ac97, reg, val); 230 soc_ac97_ops->write(ac97, reg, val);
229 reg = reg >> 1; 231 reg = reg >> 1;
230 if (reg < (ARRAY_SIZE(wm9705_reg))) 232 if (reg < (ARRAY_SIZE(wm9705_reg)))
231 cache[reg] = val; 233 cache[reg] = val;
@@ -293,8 +295,10 @@ static struct snd_soc_dai_driver wm9705_dai[] = {
293 295
294static int wm9705_reset(struct snd_soc_codec *codec) 296static int wm9705_reset(struct snd_soc_codec *codec)
295{ 297{
298 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
299
296 if (soc_ac97_ops->reset) { 300 if (soc_ac97_ops->reset) {
297 soc_ac97_ops->reset(codec->ac97); 301 soc_ac97_ops->reset(ac97);
298 if (ac97_read(codec, 0) == wm9705_reg[0]) 302 if (ac97_read(codec, 0) == wm9705_reg[0])
299 return 0; /* Success */ 303 return 0; /* Success */
300 } 304 }
@@ -307,13 +311,16 @@ static int wm9705_reset(struct snd_soc_codec *codec)
307#ifdef CONFIG_PM 311#ifdef CONFIG_PM
308static int wm9705_soc_suspend(struct snd_soc_codec *codec) 312static int wm9705_soc_suspend(struct snd_soc_codec *codec)
309{ 313{
310 soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff); 314 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
315
316 soc_ac97_ops->write(ac97, AC97_POWERDOWN, 0xffff);
311 317
312 return 0; 318 return 0;
313} 319}
314 320
315static int wm9705_soc_resume(struct snd_soc_codec *codec) 321static int wm9705_soc_resume(struct snd_soc_codec *codec)
316{ 322{
323 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
317 int i, ret; 324 int i, ret;
318 u16 *cache = codec->reg_cache; 325 u16 *cache = codec->reg_cache;
319 326
@@ -322,7 +329,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
322 return ret; 329 return ret;
323 330
324 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { 331 for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
325 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); 332 soc_ac97_ops->write(ac97, i, cache[i>>1]);
326 } 333 }
327 334
328 return 0; 335 return 0;
@@ -334,14 +341,18 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
334 341
335static int wm9705_soc_probe(struct snd_soc_codec *codec) 342static int wm9705_soc_probe(struct snd_soc_codec *codec)
336{ 343{
344 struct snd_ac97 *ac97;
337 int ret = 0; 345 int ret = 0;
338 346
339 ret = snd_soc_new_ac97_codec(codec); 347 ac97 = snd_soc_new_ac97_codec(codec);
340 if (ret < 0) { 348 if (IS_ERR(ac97)) {
349 ret = PTR_ERR(ac97);
341 dev_err(codec->dev, "Failed to register AC97 codec\n"); 350 dev_err(codec->dev, "Failed to register AC97 codec\n");
342 return ret; 351 return ret;
343 } 352 }
344 353
354 snd_soc_codec_set_drvdata(codec, ac97);
355
345 ret = wm9705_reset(codec); 356 ret = wm9705_reset(codec);
346 if (ret) 357 if (ret)
347 goto reset_err; 358 goto reset_err;
@@ -349,13 +360,15 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
349 return 0; 360 return 0;
350 361
351reset_err: 362reset_err:
352 snd_soc_free_ac97_codec(codec); 363 snd_soc_free_ac97_codec(ac97);
353 return ret; 364 return ret;
354} 365}
355 366
356static int wm9705_soc_remove(struct snd_soc_codec *codec) 367static int wm9705_soc_remove(struct snd_soc_codec *codec)
357{ 368{
358 snd_soc_free_ac97_codec(codec); 369 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
370
371 snd_soc_free_ac97_codec(ac97);
359 return 0; 372 return 0;
360} 373}
361 374
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 9fa794baa5f8..52a211be5b47 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -24,6 +24,7 @@
24#include "wm9712.h" 24#include "wm9712.h"
25 25
26struct wm9712_priv { 26struct wm9712_priv {
27 struct snd_ac97 *ac97;
27 unsigned int hp_mixer[2]; 28 unsigned int hp_mixer[2];
28 struct mutex lock; 29 struct mutex lock;
29}; 30};
@@ -484,12 +485,13 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
484static unsigned int ac97_read(struct snd_soc_codec *codec, 485static unsigned int ac97_read(struct snd_soc_codec *codec,
485 unsigned int reg) 486 unsigned int reg)
486{ 487{
488 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
487 u16 *cache = codec->reg_cache; 489 u16 *cache = codec->reg_cache;
488 490
489 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 491 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
490 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 492 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
491 reg == AC97_REC_GAIN) 493 reg == AC97_REC_GAIN)
492 return soc_ac97_ops->read(codec->ac97, reg); 494 return soc_ac97_ops->read(wm9712->ac97, reg);
493 else { 495 else {
494 reg = reg >> 1; 496 reg = reg >> 1;
495 497
@@ -503,9 +505,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
503static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 505static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
504 unsigned int val) 506 unsigned int val)
505{ 507{
508 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
506 u16 *cache = codec->reg_cache; 509 u16 *cache = codec->reg_cache;
507 510
508 soc_ac97_ops->write(codec->ac97, reg, val); 511 soc_ac97_ops->write(wm9712->ac97, reg, val);
509 reg = reg >> 1; 512 reg = reg >> 1;
510 if (reg < (ARRAY_SIZE(wm9712_reg))) 513 if (reg < (ARRAY_SIZE(wm9712_reg)))
511 cache[reg] = val; 514 cache[reg] = val;
@@ -613,15 +616,17 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
613 616
614static int wm9712_reset(struct snd_soc_codec *codec, int try_warm) 617static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
615{ 618{
619 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
620
616 if (try_warm && soc_ac97_ops->warm_reset) { 621 if (try_warm && soc_ac97_ops->warm_reset) {
617 soc_ac97_ops->warm_reset(codec->ac97); 622 soc_ac97_ops->warm_reset(wm9712->ac97);
618 if (ac97_read(codec, 0) == wm9712_reg[0]) 623 if (ac97_read(codec, 0) == wm9712_reg[0])
619 return 1; 624 return 1;
620 } 625 }
621 626
622 soc_ac97_ops->reset(codec->ac97); 627 soc_ac97_ops->reset(wm9712->ac97);
623 if (soc_ac97_ops->warm_reset) 628 if (soc_ac97_ops->warm_reset)
624 soc_ac97_ops->warm_reset(codec->ac97); 629 soc_ac97_ops->warm_reset(wm9712->ac97);
625 if (ac97_read(codec, 0) != wm9712_reg[0]) 630 if (ac97_read(codec, 0) != wm9712_reg[0])
626 goto err; 631 goto err;
627 return 0; 632 return 0;
@@ -639,6 +644,7 @@ static int wm9712_soc_suspend(struct snd_soc_codec *codec)
639 644
640static int wm9712_soc_resume(struct snd_soc_codec *codec) 645static int wm9712_soc_resume(struct snd_soc_codec *codec)
641{ 646{
647 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
642 int i, ret; 648 int i, ret;
643 u16 *cache = codec->reg_cache; 649 u16 *cache = codec->reg_cache;
644 650
@@ -654,7 +660,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
654 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN || 660 if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||
655 (i > 0x58 && i != 0x5c)) 661 (i > 0x58 && i != 0x5c))
656 continue; 662 continue;
657 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); 663 soc_ac97_ops->write(wm9712->ac97, i, cache[i>>1]);
658 } 664 }
659 } 665 }
660 666
@@ -663,11 +669,13 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)
663 669
664static int wm9712_soc_probe(struct snd_soc_codec *codec) 670static int wm9712_soc_probe(struct snd_soc_codec *codec)
665{ 671{
672 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
666 int ret = 0; 673 int ret = 0;
667 674
668 ret = snd_soc_new_ac97_codec(codec); 675 wm9712->ac97 = snd_soc_new_ac97_codec(codec);
669 if (ret < 0) { 676 if (IS_ERR(wm9712->ac97)) {
670 dev_err(codec->dev, "Failed to register AC97 codec\n"); 677 ret = PTR_ERR(wm9712->ac97);
678 dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
671 return ret; 679 return ret;
672 } 680 }
673 681
@@ -683,13 +691,15 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
683 return 0; 691 return 0;
684 692
685reset_err: 693reset_err:
686 snd_soc_free_ac97_codec(codec); 694 snd_soc_free_ac97_codec(wm9712->ac97);
687 return ret; 695 return ret;
688} 696}
689 697
690static int wm9712_soc_remove(struct snd_soc_codec *codec) 698static int wm9712_soc_remove(struct snd_soc_codec *codec)
691{ 699{
692 snd_soc_free_ac97_codec(codec); 700 struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
701
702 snd_soc_free_ac97_codec(wm9712->ac97);
693 return 0; 703 return 0;
694} 704}
695 705
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index cd1b266d3af3..6c95d98b0eb1 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -30,6 +30,7 @@
30#include "wm9713.h" 30#include "wm9713.h"
31 31
32struct wm9713_priv { 32struct wm9713_priv {
33 struct snd_ac97 *ac97;
33 u32 pll_in; /* PLL input frequency */ 34 u32 pll_in; /* PLL input frequency */
34 unsigned int hp_mixer[2]; 35 unsigned int hp_mixer[2];
35 struct mutex lock; 36 struct mutex lock;
@@ -674,12 +675,13 @@ static const struct snd_soc_dapm_route wm9713_audio_map[] = {
674static unsigned int ac97_read(struct snd_soc_codec *codec, 675static unsigned int ac97_read(struct snd_soc_codec *codec,
675 unsigned int reg) 676 unsigned int reg)
676{ 677{
678 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
677 u16 *cache = codec->reg_cache; 679 u16 *cache = codec->reg_cache;
678 680
679 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 681 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
680 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 || 682 reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
681 reg == AC97_CD) 683 reg == AC97_CD)
682 return soc_ac97_ops->read(codec->ac97, reg); 684 return soc_ac97_ops->read(wm9713->ac97, reg);
683 else { 685 else {
684 reg = reg >> 1; 686 reg = reg >> 1;
685 687
@@ -693,8 +695,10 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,
693static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, 695static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
694 unsigned int val) 696 unsigned int val)
695{ 697{
698 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
699
696 u16 *cache = codec->reg_cache; 700 u16 *cache = codec->reg_cache;
697 soc_ac97_ops->write(codec->ac97, reg, val); 701 soc_ac97_ops->write(wm9713->ac97, reg, val);
698 reg = reg >> 1; 702 reg = reg >> 1;
699 if (reg < (ARRAY_SIZE(wm9713_reg))) 703 if (reg < (ARRAY_SIZE(wm9713_reg)))
700 cache[reg] = val; 704 cache[reg] = val;
@@ -1121,15 +1125,17 @@ static struct snd_soc_dai_driver wm9713_dai[] = {
1121 1125
1122int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1126int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1123{ 1127{
1128 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1129
1124 if (try_warm && soc_ac97_ops->warm_reset) { 1130 if (try_warm && soc_ac97_ops->warm_reset) {
1125 soc_ac97_ops->warm_reset(codec->ac97); 1131 soc_ac97_ops->warm_reset(wm9713->ac97);
1126 if (ac97_read(codec, 0) == wm9713_reg[0]) 1132 if (ac97_read(codec, 0) == wm9713_reg[0])
1127 return 1; 1133 return 1;
1128 } 1134 }
1129 1135
1130 soc_ac97_ops->reset(codec->ac97); 1136 soc_ac97_ops->reset(wm9713->ac97);
1131 if (soc_ac97_ops->warm_reset) 1137 if (soc_ac97_ops->warm_reset)
1132 soc_ac97_ops->warm_reset(codec->ac97); 1138 soc_ac97_ops->warm_reset(wm9713->ac97);
1133 if (ac97_read(codec, 0) != wm9713_reg[0]) { 1139 if (ac97_read(codec, 0) != wm9713_reg[0]) {
1134 dev_err(codec->dev, "Failed to reset: AC97 link error\n"); 1140 dev_err(codec->dev, "Failed to reset: AC97 link error\n");
1135 return -EIO; 1141 return -EIO;
@@ -1207,7 +1213,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1207 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID || 1213 if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
1208 i == AC97_EXTENDED_MSTATUS || i > 0x66) 1214 i == AC97_EXTENDED_MSTATUS || i > 0x66)
1209 continue; 1215 continue;
1210 soc_ac97_ops->write(codec->ac97, i, cache[i>>1]); 1216 soc_ac97_ops->write(wm9713->ac97, i, cache[i>>1]);
1211 } 1217 }
1212 } 1218 }
1213 1219
@@ -1216,11 +1222,12 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
1216 1222
1217static int wm9713_soc_probe(struct snd_soc_codec *codec) 1223static int wm9713_soc_probe(struct snd_soc_codec *codec)
1218{ 1224{
1225 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1219 int ret = 0, reg; 1226 int ret = 0, reg;
1220 1227
1221 ret = snd_soc_new_ac97_codec(codec); 1228 wm9713->ac97 = snd_soc_new_ac97_codec(codec);
1222 if (ret < 0) 1229 if (IS_ERR(wm9713->ac97))
1223 return ret; 1230 return PTR_ERR(wm9713->ac97);
1224 1231
1225 /* do a cold reset for the controller and then try 1232 /* do a cold reset for the controller and then try
1226 * a warm reset followed by an optional cold reset for codec */ 1233 * a warm reset followed by an optional cold reset for codec */
@@ -1238,13 +1245,15 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1238 return 0; 1245 return 0;
1239 1246
1240reset_err: 1247reset_err:
1241 snd_soc_free_ac97_codec(codec); 1248 snd_soc_free_ac97_codec(wm9713->ac97);
1242 return ret; 1249 return ret;
1243} 1250}
1244 1251
1245static int wm9713_soc_remove(struct snd_soc_codec *codec) 1252static int wm9713_soc_remove(struct snd_soc_codec *codec)
1246{ 1253{
1247 snd_soc_free_ac97_codec(codec); 1254 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1255
1256 snd_soc_free_ac97_codec(wm9713->ac97);
1248 return 0; 1257 return 0;
1249} 1258}
1250 1259
diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c
index 920d76c43827..2e10e9a38376 100644
--- a/sound/soc/soc-ac97.c
+++ b/sound/soc/soc-ac97.c
@@ -53,30 +53,33 @@ static void soc_ac97_device_release(struct device *dev)
53 * 53 *
54 * Initialises AC97 codec resources for use by ad-hoc devices only. 54 * Initialises AC97 codec resources for use by ad-hoc devices only.
55 */ 55 */
56int snd_soc_new_ac97_codec(struct snd_soc_codec *codec) 56struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec)
57{ 57{
58 struct snd_ac97 *ac97;
58 int ret; 59 int ret;
59 60
60 codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); 61 ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
61 if (codec->ac97 == NULL) 62 if (ac97 == NULL)
62 return -ENOMEM; 63 return ERR_PTR(-ENOMEM);
63 64
64 codec->ac97->bus = &soc_ac97_bus; 65 ac97->bus = &soc_ac97_bus;
65 codec->ac97->num = 0; 66 ac97->num = 0;
66 67
67 codec->ac97->dev.bus = &ac97_bus_type; 68 ac97->dev.bus = &ac97_bus_type;
68 codec->ac97->dev.parent = codec->component.card->dev; 69 ac97->dev.parent = codec->component.card->dev;
69 codec->ac97->dev.release = soc_ac97_device_release; 70 ac97->dev.release = soc_ac97_device_release;
70 71
71 dev_set_name(&codec->ac97->dev, "%d-%d:%s", 72 dev_set_name(&ac97->dev, "%d-%d:%s",
72 codec->component.card->snd_card->number, 0, 73 codec->component.card->snd_card->number, 0,
73 codec->component.name); 74 codec->component.name);
74 75
75 ret = device_register(&codec->ac97->dev); 76 ret = device_register(&ac97->dev);
76 if (ret) 77 if (ret) {
77 put_device(&codec->ac97->dev); 78 put_device(&ac97->dev);
79 return ERR_PTR(ret);
80 }
78 81
79 return ret; 82 return ac97;
80} 83}
81EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 84EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
82 85
@@ -86,12 +89,11 @@ EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
86 * 89 *
87 * Frees AC97 codec device resources. 90 * Frees AC97 codec device resources.
88 */ 91 */
89void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) 92void snd_soc_free_ac97_codec(struct snd_ac97 *ac97)
90{ 93{
91 device_del(&codec->ac97->dev); 94 device_del(&ac97->dev);
92 codec->ac97->bus = NULL; 95 ac97->bus = NULL;
93 put_device(&codec->ac97->dev); 96 put_device(&ac97->dev);
94 codec->ac97 = NULL;
95} 97}
96EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); 98EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
97 99