|
@@ -139,18 +139,19 @@ static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = {
|
|
|
static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
|
|
|
unsigned int val)
|
|
|
{
|
|
|
+ struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
|
|
|
u16 *cache = codec->reg_cache;
|
|
|
|
|
|
if (reg > AC97_STAC_PAGE0) {
|
|
|
stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
|
|
|
- soc_ac97_ops->write(codec->ac97, reg, val);
|
|
|
+ soc_ac97_ops->write(ac97, reg, val);
|
|
|
stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
|
|
|
return 0;
|
|
|
}
|
|
|
if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
|
|
|
return -EIO;
|
|
|
|
|
|
- soc_ac97_ops->write(codec->ac97, reg, val);
|
|
|
+ soc_ac97_ops->write(ac97, reg, val);
|
|
|
cache[reg / 2] = val;
|
|
|
return 0;
|
|
|
}
|
|
@@ -158,11 +159,12 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
|
|
|
static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
|
|
|
unsigned int reg)
|
|
|
{
|
|
|
+ struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
|
|
|
u16 val = 0, *cache = codec->reg_cache;
|
|
|
|
|
|
if (reg > AC97_STAC_PAGE0) {
|
|
|
stac9766_ac97_write(codec, AC97_INT_PAGING, 0);
|
|
|
- val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0);
|
|
|
+ val = soc_ac97_ops->read(ac97, reg - AC97_STAC_PAGE0);
|
|
|
stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
|
|
|
return val;
|
|
|
}
|
|
@@ -173,7 +175,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
|
|
|
reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||
|
|
|
reg == AC97_VENDOR_ID2) {
|
|
|
|
|
|
- val = soc_ac97_ops->read(codec->ac97, reg);
|
|
|
+ val = soc_ac97_ops->read(ac97, reg);
|
|
|
return val;
|
|
|
}
|
|
|
return cache[reg / 2];
|
|
@@ -240,15 +242,17 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
|
|
|
|
|
|
static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
|
|
|
{
|
|
|
+ struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
|
|
|
+
|
|
|
if (try_warm && soc_ac97_ops->warm_reset) {
|
|
|
- soc_ac97_ops->warm_reset(codec->ac97);
|
|
|
+ soc_ac97_ops->warm_reset(ac97);
|
|
|
if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- soc_ac97_ops->reset(codec->ac97);
|
|
|
+ soc_ac97_ops->reset(ac97);
|
|
|
if (soc_ac97_ops->warm_reset)
|
|
|
- soc_ac97_ops->warm_reset(codec->ac97);
|
|
|
+ soc_ac97_ops->warm_reset(ac97);
|
|
|
if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])
|
|
|
return -EIO;
|
|
|
return 0;
|
|
@@ -262,6 +266,7 @@ static int stac9766_codec_suspend(struct snd_soc_codec *codec)
|
|
|
|
|
|
static int stac9766_codec_resume(struct snd_soc_codec *codec)
|
|
|
{
|
|
|
+ struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
|
|
|
u16 id, reset;
|
|
|
|
|
|
reset = 0;
|
|
@@ -271,8 +276,8 @@ reset:
|
|
|
printk(KERN_ERR "stac9766 failed to resume");
|
|
|
return -EIO;
|
|
|
}
|
|
|
- codec->ac97->bus->ops->warm_reset(codec->ac97);
|
|
|
- id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2);
|
|
|
+ ac97->bus->ops->warm_reset(ac97);
|
|
|
+ id = soc_ac97_ops->read(ac97, AC97_VENDOR_ID2);
|
|
|
if (id != 0x4c13) {
|
|
|
stac9766_reset(codec, 0);
|
|
|
reset++;
|
|
@@ -332,11 +337,14 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
|
|
|
|
|
|
static int stac9766_codec_probe(struct snd_soc_codec *codec)
|
|
|
{
|
|
|
+ struct snd_ac97 *ac97;
|
|
|
int ret = 0;
|
|
|
|
|
|
- ret = snd_soc_new_ac97_codec(codec);
|
|
|
- if (ret < 0)
|
|
|
- goto codec_err;
|
|
|
+ ac97 = snd_soc_new_ac97_codec(codec);
|
|
|
+ if (IS_ERR(ac97))
|
|
|
+ return PTR_ERR(ac97);
|
|
|
+
|
|
|
+ snd_soc_codec_set_drvdata(codec, ac97);
|
|
|
|
|
|
/* do a cold reset for the controller and then try
|
|
|
* 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)
|
|
|
return 0;
|
|
|
|
|
|
codec_err:
|
|
|
- snd_soc_free_ac97_codec(codec);
|
|
|
+ snd_soc_free_ac97_codec(ac97);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static int stac9766_codec_remove(struct snd_soc_codec *codec)
|
|
|
{
|
|
|
- snd_soc_free_ac97_codec(codec);
|
|
|
+ struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
|
|
|
+
|
|
|
+ snd_soc_free_ac97_codec(ac97);
|
|
|
return 0;
|
|
|
}
|
|
|
|