aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/stac9766.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/stac9766.c')
-rw-r--r--sound/soc/codecs/stac9766.c40
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[] = {
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++;
@@ -294,7 +299,6 @@ static const struct snd_soc_dai_ops stac9766_dai_ops_digital = {
294static struct snd_soc_dai_driver stac9766_dai[] = { 299static 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
335static int stac9766_codec_probe(struct snd_soc_codec *codec) 338static 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
359codec_err: 365codec_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
364static int stac9766_codec_remove(struct snd_soc_codec *codec) 370static 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