summaryrefslogtreecommitdiff
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.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 53b810d23fea..dbff0c89be48 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[] = {
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,45 +242,41 @@ 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;
}
-static int stac9766_codec_suspend(struct snd_soc_codec *codec)
-{
- stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
- return 0;
-}
-
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;
/* give the codec an AC97 warm reset to start the link */
reset:
if (reset > 5) {
- printk(KERN_ERR "stac9766 failed to resume");
+ dev_err(codec->dev, "Failed to resume\n");
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++;
goto reset;
}
- stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
@@ -294,7 +292,6 @@ static const struct snd_soc_dai_ops stac9766_dai_ops_digital = {
static struct snd_soc_dai_driver stac9766_dai[] = {
{
.name = "stac9766-hifi-analog",
- .ac97_control = 1,
/* stream cababilities */
.playback = {
@@ -316,7 +313,6 @@ static struct snd_soc_dai_driver stac9766_dai[] = {
},
{
.name = "stac9766-hifi-IEC958",
- .ac97_control = 1,
/* stream cababilities */
.playback = {
@@ -334,46 +330,48 @@ 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, soc_ac97_ops, 0);
- 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 */
stac9766_reset(codec, 0);
ret = stac9766_reset(codec, 1);
if (ret < 0) {
- printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
+ dev_err(codec->dev, "Failed to reset: AC97 link error\n");
goto codec_err;
}
- stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
- ARRAY_SIZE(stac9766_snd_ac97_controls));
-
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;
}
static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
+ .controls = stac9766_snd_ac97_controls,
+ .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls),
.write = stac9766_ac97_write,
.read = stac9766_ac97_read,
.set_bias_level = stac9766_set_bias_level,
+ .suspend_bias_off = true,
.probe = stac9766_codec_probe,
.remove = stac9766_codec_remove,
- .suspend = stac9766_codec_suspend,
.resume = stac9766_codec_resume,
.reg_cache_size = ARRAY_SIZE(stac9766_reg),
.reg_word_size = sizeof(u16),