.. | .. |
---|
11 | 11 | #include <linux/module.h> |
---|
12 | 12 | #include <linux/pm_runtime.h> |
---|
13 | 13 | #include <linux/regmap.h> |
---|
| 14 | +#include <linux/regulator/consumer.h> |
---|
14 | 15 | #include <linux/slab.h> |
---|
15 | 16 | |
---|
16 | 17 | #include <sound/initval.h> |
---|
.. | .. |
---|
22 | 23 | |
---|
23 | 24 | #include "ak5558.h" |
---|
24 | 25 | |
---|
| 26 | +#define AK5558_NUM_SUPPLIES 2 |
---|
| 27 | +static const char *ak5558_supply_names[AK5558_NUM_SUPPLIES] = { |
---|
| 28 | + "DVDD", |
---|
| 29 | + "AVDD", |
---|
| 30 | +}; |
---|
| 31 | + |
---|
25 | 32 | /* AK5558 Codec Private Data */ |
---|
26 | 33 | struct ak5558_priv { |
---|
| 34 | + struct regulator_bulk_data supplies[AK5558_NUM_SUPPLIES]; |
---|
27 | 35 | struct snd_soc_component component; |
---|
28 | 36 | struct regmap *regmap; |
---|
29 | 37 | struct i2c_client *i2c; |
---|
.. | .. |
---|
130 | 138 | u8 bits; |
---|
131 | 139 | int pcm_width = max(params_physical_width(params), ak5558->slot_width); |
---|
132 | 140 | |
---|
133 | | - /* set master/slave audio interface */ |
---|
134 | | - bits = snd_soc_component_read32(component, AK5558_02_CONTROL1); |
---|
135 | | - bits &= ~AK5558_BITS; |
---|
136 | | - |
---|
137 | 141 | switch (pcm_width) { |
---|
138 | 142 | case 16: |
---|
139 | | - bits |= AK5558_DIF_24BIT_MODE; |
---|
| 143 | + bits = AK5558_DIF_24BIT_MODE; |
---|
140 | 144 | break; |
---|
141 | 145 | case 32: |
---|
142 | | - bits |= AK5558_DIF_32BIT_MODE; |
---|
| 146 | + bits = AK5558_DIF_32BIT_MODE; |
---|
143 | 147 | break; |
---|
144 | 148 | default: |
---|
145 | 149 | return -EINVAL; |
---|
.. | .. |
---|
168 | 172 | } |
---|
169 | 173 | |
---|
170 | 174 | /* set master/slave audio interface */ |
---|
171 | | - format = snd_soc_component_read32(component, AK5558_02_CONTROL1); |
---|
172 | | - format &= ~AK5558_DIF; |
---|
173 | | - |
---|
174 | 175 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
---|
175 | 176 | case SND_SOC_DAIFMT_I2S: |
---|
176 | | - format |= AK5558_DIF_I2S_MODE; |
---|
| 177 | + format = AK5558_DIF_I2S_MODE; |
---|
177 | 178 | break; |
---|
178 | 179 | case SND_SOC_DAIFMT_LEFT_J: |
---|
179 | | - format |= AK5558_DIF_MSB_MODE; |
---|
| 180 | + format = AK5558_DIF_MSB_MODE; |
---|
180 | 181 | break; |
---|
181 | 182 | case SND_SOC_DAIFMT_DSP_B: |
---|
182 | | - format |= AK5558_DIF_MSB_MODE; |
---|
| 183 | + format = AK5558_DIF_MSB_MODE; |
---|
183 | 184 | break; |
---|
184 | 185 | default: |
---|
185 | 186 | return -EINVAL; |
---|
.. | .. |
---|
246 | 247 | &ak5558_rate_constraints); |
---|
247 | 248 | } |
---|
248 | 249 | |
---|
249 | | -static struct snd_soc_dai_ops ak5558_dai_ops = { |
---|
| 250 | +static const struct snd_soc_dai_ops ak5558_dai_ops = { |
---|
250 | 251 | .startup = ak5558_startup, |
---|
251 | 252 | .hw_params = ak5558_hw_params, |
---|
252 | 253 | |
---|
.. | .. |
---|
306 | 307 | regcache_cache_only(ak5558->regmap, true); |
---|
307 | 308 | ak5558_power_off(ak5558); |
---|
308 | 309 | |
---|
| 310 | + regulator_bulk_disable(ARRAY_SIZE(ak5558->supplies), |
---|
| 311 | + ak5558->supplies); |
---|
309 | 312 | return 0; |
---|
310 | 313 | } |
---|
311 | 314 | |
---|
312 | 315 | static int __maybe_unused ak5558_runtime_resume(struct device *dev) |
---|
313 | 316 | { |
---|
314 | 317 | struct ak5558_priv *ak5558 = dev_get_drvdata(dev); |
---|
| 318 | + int ret; |
---|
| 319 | + |
---|
| 320 | + ret = regulator_bulk_enable(ARRAY_SIZE(ak5558->supplies), |
---|
| 321 | + ak5558->supplies); |
---|
| 322 | + if (ret != 0) { |
---|
| 323 | + dev_err(dev, "Failed to enable supplies: %d\n", ret); |
---|
| 324 | + return ret; |
---|
| 325 | + } |
---|
315 | 326 | |
---|
316 | 327 | ak5558_power_off(ak5558); |
---|
317 | 328 | ak5558_power_on(ak5558); |
---|
.. | .. |
---|
357 | 368 | { |
---|
358 | 369 | struct ak5558_priv *ak5558; |
---|
359 | 370 | int ret = 0; |
---|
| 371 | + int i; |
---|
360 | 372 | |
---|
361 | 373 | ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL); |
---|
362 | 374 | if (!ak5558) |
---|
.. | .. |
---|
374 | 386 | if (IS_ERR(ak5558->reset_gpiod)) |
---|
375 | 387 | return PTR_ERR(ak5558->reset_gpiod); |
---|
376 | 388 | |
---|
| 389 | + for (i = 0; i < ARRAY_SIZE(ak5558->supplies); i++) |
---|
| 390 | + ak5558->supplies[i].supply = ak5558_supply_names[i]; |
---|
| 391 | + |
---|
| 392 | + ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(ak5558->supplies), |
---|
| 393 | + ak5558->supplies); |
---|
| 394 | + if (ret != 0) { |
---|
| 395 | + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
---|
| 396 | + return ret; |
---|
| 397 | + } |
---|
| 398 | + |
---|
377 | 399 | ret = devm_snd_soc_register_component(&i2c->dev, |
---|
378 | 400 | &soc_codec_dev_ak5558, |
---|
379 | 401 | &ak5558_dai, 1); |
---|
.. | .. |
---|
381 | 403 | return ret; |
---|
382 | 404 | |
---|
383 | 405 | pm_runtime_enable(&i2c->dev); |
---|
| 406 | + regcache_cache_only(ak5558->regmap, true); |
---|
384 | 407 | |
---|
385 | 408 | return 0; |
---|
386 | 409 | } |
---|