aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-13 01:31:38 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-18 23:23:53 -0400
commitb306e84f9a15e465812d9b66f8d6ecadae806f4c (patch)
treee26bd1cf8b97a91c2752bb58629fd56082d3036b
parent35ecf7cd96a79d92c1b8433c950a827a2a723db9 (diff)
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)
187 } 187 }
188} 188}
189 189
190static int wm8961_reset(struct snd_soc_codec *codec)
191{
192 return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
193}
194
195/* 190/*
196 * The headphone output supports special anti-pop sequences giving 191 * The headphone output supports special anti-pop sequences giving
197 * silent power up and power down. 192 * silent power up and power down.
@@ -840,7 +835,6 @@ static struct snd_soc_dai_driver wm8961_dai = {
840 835
841static int wm8961_probe(struct snd_soc_codec *codec) 836static int wm8961_probe(struct snd_soc_codec *codec)
842{ 837{
843 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
844 struct snd_soc_dapm_context *dapm = &codec->dapm; 838 struct snd_soc_dapm_context *dapm = &codec->dapm;
845 int ret = 0; 839 int ret = 0;
846 u16 reg; 840 u16 reg;
@@ -851,27 +845,6 @@ static int wm8961_probe(struct snd_soc_codec *codec)
851 return ret; 845 return ret;
852 } 846 }
853 847
854 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
855 if (reg != 0x1801) {
856 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
857 return -EINVAL;
858 }
859
860 /* This isn't volatile - readback doesn't correspond to write */
861 regcache_cache_bypass(wm8961->regmap, true);
862 reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
863 regcache_cache_bypass(wm8961->regmap, false);
864 dev_info(codec->dev, "WM8961 family %d revision %c\n",
865 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
866 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
867 + 'A');
868
869 ret = wm8961_reset(codec);
870 if (ret < 0) {
871 dev_err(codec->dev, "Failed to issue reset\n");
872 return ret;
873 }
874
875 /* Enable class W */ 848 /* Enable class W */
876 reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B); 849 reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
877 reg |= WM8961_CP_DYN_PWR_MASK; 850 reg |= WM8961_CP_DYN_PWR_MASK;
@@ -968,6 +941,7 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
968 const struct i2c_device_id *id) 941 const struct i2c_device_id *id)
969{ 942{
970 struct wm8961_priv *wm8961; 943 struct wm8961_priv *wm8961;
944 unsigned int val;
971 int ret; 945 int ret;
972 946
973 wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), 947 wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
@@ -979,6 +953,38 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
979 if (IS_ERR(wm8961->regmap)) 953 if (IS_ERR(wm8961->regmap))
980 return PTR_ERR(wm8961->regmap); 954 return PTR_ERR(wm8961->regmap);
981 955
956 ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val);
957 if (ret != 0) {
958 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
959 return ret;
960 }
961
962 if (val != 0x1801) {
963 dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val);
964 return -EINVAL;
965 }
966
967 /* This isn't volatile - readback doesn't correspond to write */
968 regcache_cache_bypass(wm8961->regmap, true);
969 ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val);
970 regcache_cache_bypass(wm8961->regmap, false);
971
972 if (ret != 0) {
973 dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
974 return ret;
975 }
976
977 dev_info(&i2c->dev, "WM8961 family %d revision %c\n",
978 (val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
979 ((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
980 + 'A');
981
982 ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801);
983 if (ret != 0) {
984 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
985 return ret;
986 }
987
982 i2c_set_clientdata(i2c, wm8961); 988 i2c_set_clientdata(i2c, wm8961);
983 989
984 ret = snd_soc_register_codec(&i2c->dev, 990 ret = snd_soc_register_codec(&i2c->dev,