diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-06-08 23:41:58 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-06-25 04:53:52 -0400 |
commit | 03862cf62ea36d6cf3d94eee84b89578cbcf0213 (patch) | |
tree | a5fdf88e310b3117f33777e3675ba49ea66c1e51 /sound/soc | |
parent | fd88759a42dc10f8230b3933a1ceb40bd88fccea (diff) |
ASoC: wm8904: Move regulator acquisition and device identification to I2C
It's more idiomatic to have the resource allocation at this level.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/wm8904.c | 112 |
1 files changed, 51 insertions, 61 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index ecab871573b1..b178232c990c 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -314,11 +314,6 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg) | |||
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
317 | static int wm8904_reset(struct snd_soc_codec *codec) | ||
318 | { | ||
319 | return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0); | ||
320 | } | ||
321 | |||
322 | static int wm8904_configure_clocking(struct snd_soc_codec *codec) | 317 | static int wm8904_configure_clocking(struct snd_soc_codec *codec) |
323 | { | 318 | { |
324 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 319 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
@@ -2082,52 +2077,6 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2082 | return ret; | 2077 | return ret; |
2083 | } | 2078 | } |
2084 | 2079 | ||
2085 | for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) | ||
2086 | wm8904->supplies[i].supply = wm8904_supply_names[i]; | ||
2087 | |||
2088 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies), | ||
2089 | wm8904->supplies); | ||
2090 | if (ret != 0) { | ||
2091 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
2092 | return ret; | ||
2093 | } | ||
2094 | |||
2095 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), | ||
2096 | wm8904->supplies); | ||
2097 | if (ret != 0) { | ||
2098 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
2099 | goto err_get; | ||
2100 | } | ||
2101 | |||
2102 | ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID); | ||
2103 | if (ret < 0) { | ||
2104 | dev_err(codec->dev, "Failed to read ID register\n"); | ||
2105 | goto err_enable; | ||
2106 | } | ||
2107 | if (ret != 0x8904) { | ||
2108 | dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); | ||
2109 | ret = -EINVAL; | ||
2110 | goto err_enable; | ||
2111 | } | ||
2112 | |||
2113 | ret = snd_soc_read(codec, WM8904_REVISION); | ||
2114 | if (ret < 0) { | ||
2115 | dev_err(codec->dev, "Failed to read device revision: %d\n", | ||
2116 | ret); | ||
2117 | goto err_enable; | ||
2118 | } | ||
2119 | dev_info(codec->dev, "revision %c\n", ret + 'A'); | ||
2120 | |||
2121 | ret = wm8904_reset(codec); | ||
2122 | if (ret < 0) { | ||
2123 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
2124 | goto err_enable; | ||
2125 | } | ||
2126 | |||
2127 | /* Can leave the device powered off until we need it */ | ||
2128 | regcache_cache_only(wm8904->regmap, true); | ||
2129 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2130 | |||
2131 | /* Change some default settings - latch VU and enable ZC */ | 2080 | /* Change some default settings - latch VU and enable ZC */ |
2132 | snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, | 2081 | snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, |
2133 | WM8904_ADC_VU, WM8904_ADC_VU); | 2082 | WM8904_ADC_VU, WM8904_ADC_VU); |
@@ -2187,19 +2136,12 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2187 | wm8904_add_widgets(codec); | 2136 | wm8904_add_widgets(codec); |
2188 | 2137 | ||
2189 | return 0; | 2138 | return 0; |
2190 | |||
2191 | err_enable: | ||
2192 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2193 | err_get: | ||
2194 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2195 | return ret; | ||
2196 | } | 2139 | } |
2197 | 2140 | ||
2198 | static int wm8904_remove(struct snd_soc_codec *codec) | 2141 | static int wm8904_remove(struct snd_soc_codec *codec) |
2199 | { | 2142 | { |
2200 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 2143 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2201 | 2144 | ||
2202 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2203 | kfree(wm8904->retune_mobile_texts); | 2145 | kfree(wm8904->retune_mobile_texts); |
2204 | kfree(wm8904->drc_texts); | 2146 | kfree(wm8904->drc_texts); |
2205 | 2147 | ||
@@ -2230,7 +2172,8 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | |||
2230 | const struct i2c_device_id *id) | 2172 | const struct i2c_device_id *id) |
2231 | { | 2173 | { |
2232 | struct wm8904_priv *wm8904; | 2174 | struct wm8904_priv *wm8904; |
2233 | int ret; | 2175 | unsigned int val; |
2176 | int ret, i; | ||
2234 | 2177 | ||
2235 | wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), | 2178 | wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), |
2236 | GFP_KERNEL); | 2179 | GFP_KERNEL); |
@@ -2249,14 +2192,61 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | |||
2249 | i2c_set_clientdata(i2c, wm8904); | 2192 | i2c_set_clientdata(i2c, wm8904); |
2250 | wm8904->pdata = i2c->dev.platform_data; | 2193 | wm8904->pdata = i2c->dev.platform_data; |
2251 | 2194 | ||
2195 | for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) | ||
2196 | wm8904->supplies[i].supply = wm8904_supply_names[i]; | ||
2197 | |||
2198 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8904->supplies), | ||
2199 | wm8904->supplies); | ||
2200 | if (ret != 0) { | ||
2201 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
2202 | return ret; | ||
2203 | } | ||
2204 | |||
2205 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), | ||
2206 | wm8904->supplies); | ||
2207 | if (ret != 0) { | ||
2208 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
2209 | return ret; | ||
2210 | } | ||
2211 | |||
2212 | ret = regmap_read(wm8904->regmap, WM8904_SW_RESET_AND_ID, &val); | ||
2213 | if (ret < 0) { | ||
2214 | dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); | ||
2215 | goto err_enable; | ||
2216 | } | ||
2217 | if (val != 0x8904) { | ||
2218 | dev_err(&i2c->dev, "Device is not a WM8904, ID is %x\n", val); | ||
2219 | ret = -EINVAL; | ||
2220 | goto err_enable; | ||
2221 | } | ||
2222 | |||
2223 | ret = regmap_read(wm8904->regmap, WM8904_REVISION, &val); | ||
2224 | if (ret < 0) { | ||
2225 | dev_err(&i2c->dev, "Failed to read device revision: %d\n", | ||
2226 | ret); | ||
2227 | goto err_enable; | ||
2228 | } | ||
2229 | dev_info(&i2c->dev, "revision %c\n", val + 'A'); | ||
2230 | |||
2231 | ret = regmap_write(wm8904->regmap, WM8904_SW_RESET_AND_ID, 0); | ||
2232 | if (ret < 0) { | ||
2233 | dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); | ||
2234 | goto err_enable; | ||
2235 | } | ||
2236 | |||
2237 | /* Can leave the device powered off until we need it */ | ||
2238 | regcache_cache_only(wm8904->regmap, true); | ||
2239 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2240 | |||
2252 | ret = snd_soc_register_codec(&i2c->dev, | 2241 | ret = snd_soc_register_codec(&i2c->dev, |
2253 | &soc_codec_dev_wm8904, &wm8904_dai, 1); | 2242 | &soc_codec_dev_wm8904, &wm8904_dai, 1); |
2254 | if (ret != 0) | 2243 | if (ret != 0) |
2255 | goto err; | 2244 | return ret; |
2256 | 2245 | ||
2257 | return 0; | 2246 | return 0; |
2258 | 2247 | ||
2259 | err: | 2248 | err_enable: |
2249 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | ||
2260 | return ret; | 2250 | return ret; |
2261 | } | 2251 | } |
2262 | 2252 | ||