Skip to content

Commit

Permalink
ASoC: wm8961: Move device identification and reset to I2C probe
Browse files Browse the repository at this point in the history
This is more idiomatic as it means we verify that the device is there
prior to trying to do the card probe.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Sep 19, 2012
1 parent 35ecf7c commit b306e84
Showing 1 changed file with 33 additions and 27 deletions.
60 changes: 33 additions & 27 deletions sound/soc/codecs/wm8961.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,6 @@ static bool wm8961_readable(struct device *dev, unsigned int reg)
}
}

static int wm8961_reset(struct snd_soc_codec *codec)
{
return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
}

/*
* The headphone output supports special anti-pop sequences giving
* silent power up and power down.
Expand Down Expand Up @@ -840,7 +835,6 @@ static struct snd_soc_dai_driver wm8961_dai = {

static int wm8961_probe(struct snd_soc_codec *codec)
{
struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret = 0;
u16 reg;
Expand All @@ -851,27 +845,6 @@ static int wm8961_probe(struct snd_soc_codec *codec)
return ret;
}

reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
if (reg != 0x1801) {
dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
return -EINVAL;
}

/* This isn't volatile - readback doesn't correspond to write */
regcache_cache_bypass(wm8961->regmap, true);
reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
regcache_cache_bypass(wm8961->regmap, false);
dev_info(codec->dev, "WM8961 family %d revision %c\n",
(reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
+ 'A');

ret = wm8961_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
return ret;
}

/* Enable class W */
reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
reg |= WM8961_CP_DYN_PWR_MASK;
Expand Down Expand Up @@ -968,6 +941,7 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8961_priv *wm8961;
unsigned int val;
int ret;

wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
Expand All @@ -979,6 +953,38 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
if (IS_ERR(wm8961->regmap))
return PTR_ERR(wm8961->regmap);

ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
return ret;
}

if (val != 0x1801) {
dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val);
return -EINVAL;
}

/* This isn't volatile - readback doesn't correspond to write */
regcache_cache_bypass(wm8961->regmap, true);
ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val);
regcache_cache_bypass(wm8961->regmap, false);

if (ret != 0) {
dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
return ret;
}

dev_info(&i2c->dev, "WM8961 family %d revision %c\n",
(val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
+ 'A');

ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
return ret;
}

i2c_set_clientdata(i2c, wm8961);

ret = snd_soc_register_codec(&i2c->dev,
Expand Down

0 comments on commit b306e84

Please sign in to comment.