diff options
Diffstat (limited to 'sound/soc/codecs/stac9766.c')
-rw-r--r-- | sound/soc/codecs/stac9766.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 53b810d23fea..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[] = { | |||
139 | static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg, | 139 | static 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, | |||
158 | static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, | 159 | static 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 | ||
241 | static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) | 243 | static 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 | ||
263 | static int stac9766_codec_resume(struct snd_soc_codec *codec) | 267 | static 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++; |
@@ -294,7 +299,6 @@ static const struct snd_soc_dai_ops stac9766_dai_ops_digital = { | |||
294 | static struct snd_soc_dai_driver stac9766_dai[] = { | 299 | static struct snd_soc_dai_driver stac9766_dai[] = { |
295 | { | 300 | { |
296 | .name = "stac9766-hifi-analog", | 301 | .name = "stac9766-hifi-analog", |
297 | .ac97_control = 1, | ||
298 | 302 | ||
299 | /* stream cababilities */ | 303 | /* stream cababilities */ |
300 | .playback = { | 304 | .playback = { |
@@ -316,7 +320,6 @@ static struct snd_soc_dai_driver stac9766_dai[] = { | |||
316 | }, | 320 | }, |
317 | { | 321 | { |
318 | .name = "stac9766-hifi-IEC958", | 322 | .name = "stac9766-hifi-IEC958", |
319 | .ac97_control = 1, | ||
320 | 323 | ||
321 | /* stream cababilities */ | 324 | /* stream cababilities */ |
322 | .playback = { | 325 | .playback = { |
@@ -334,11 +337,14 @@ static struct snd_soc_dai_driver stac9766_dai[] = { | |||
334 | 337 | ||
335 | static int stac9766_codec_probe(struct snd_soc_codec *codec) | 338 | static int stac9766_codec_probe(struct snd_soc_codec *codec) |
336 | { | 339 | { |
340 | struct snd_ac97 *ac97; | ||
337 | int ret = 0; | 341 | int ret = 0; |
338 | 342 | ||
339 | ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0); | 343 | ac97 = snd_soc_new_ac97_codec(codec); |
340 | if (ret < 0) | 344 | if (IS_ERR(ac97)) |
341 | goto codec_err; | 345 | return PTR_ERR(ac97); |
346 | |||
347 | snd_soc_codec_set_drvdata(codec, ac97); | ||
342 | 348 | ||
343 | /* do a cold reset for the controller and then try | 349 | /* do a cold reset for the controller and then try |
344 | * a warm reset followed by an optional cold reset for codec */ | 350 | * a warm reset followed by an optional cold reset for codec */ |
@@ -357,13 +363,15 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) | |||
357 | return 0; | 363 | return 0; |
358 | 364 | ||
359 | codec_err: | 365 | codec_err: |
360 | snd_soc_free_ac97_codec(codec); | 366 | snd_soc_free_ac97_codec(ac97); |
361 | return ret; | 367 | return ret; |
362 | } | 368 | } |
363 | 369 | ||
364 | static int stac9766_codec_remove(struct snd_soc_codec *codec) | 370 | static int stac9766_codec_remove(struct snd_soc_codec *codec) |
365 | { | 371 | { |
366 | 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); | ||
367 | return 0; | 375 | return 0; |
368 | } | 376 | } |
369 | 377 | ||