summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-13 09:31:38 +0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-19 07:23:53 +0400
commitb306e84f9a15e465812d9b66f8d6ecadae806f4c (patch)
treee26bd1cf8b97a91c2752bb58629fd56082d3036b
parent35ecf7cd96a79d92c1b8433c950a827a2a723db9 (diff)
downloadlinux-b306e84f9a15e465812d9b66f8d6ecadae806f4c.tar.xz
ASoC: wm8961: Move device identification and reset to I2C probe
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>
-rw-r--r--sound/soc/codecs/wm8961.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 4ea64d6e68e2..f387670d0d75 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -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.
@@ -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;
@@ -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;
@@ -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),
@@ -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,