diff options
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r-- | sound/soc/codecs/wm9081.c | 80 |
1 files changed, 21 insertions, 59 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index a6bab392700e..076c126ed9b1 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { | |||
824 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, | 824 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, |
825 | enum snd_soc_bias_level level) | 825 | enum snd_soc_bias_level level) |
826 | { | 826 | { |
827 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | ||
828 | |||
827 | switch (level) { | 829 | switch (level) { |
828 | case SND_SOC_BIAS_ON: | 830 | case SND_SOC_BIAS_ON: |
829 | break; | 831 | break; |
@@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
841 | case SND_SOC_BIAS_STANDBY: | 843 | case SND_SOC_BIAS_STANDBY: |
842 | /* Initial cold start */ | 844 | /* Initial cold start */ |
843 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 845 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
846 | regcache_cache_only(wm9081->regmap, false); | ||
847 | regcache_sync(wm9081->regmap); | ||
848 | |||
844 | /* Disable LINEOUT discharge */ | 849 | /* Disable LINEOUT discharge */ |
845 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, | 850 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
846 | WM9081_LINEOUT_DISCH, 0); | 851 | WM9081_LINEOUT_DISCH, 0); |
@@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
892 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, | 897 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
893 | WM9081_LINEOUT_DISCH, | 898 | WM9081_LINEOUT_DISCH, |
894 | WM9081_LINEOUT_DISCH); | 899 | WM9081_LINEOUT_DISCH); |
900 | |||
901 | regcache_cache_only(wm9081->regmap, true); | ||
895 | break; | 902 | break; |
896 | } | 903 | } |
897 | 904 | ||
@@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1258 | { | 1265 | { |
1259 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | 1266 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
1260 | int ret; | 1267 | int ret; |
1261 | u16 reg; | ||
1262 | 1268 | ||
1263 | codec->control_data = wm9081->regmap; | 1269 | codec->control_data = wm9081->regmap; |
1264 | 1270 | ||
@@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1268 | return ret; | 1274 | return ret; |
1269 | } | 1275 | } |
1270 | 1276 | ||
1271 | reg = 0; | ||
1272 | if (wm9081->pdata.irq_high) | ||
1273 | reg |= WM9081_IRQ_POL; | ||
1274 | if (!wm9081->pdata.irq_cmos) | ||
1275 | reg |= WM9081_IRQ_OP_CTRL; | ||
1276 | snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL, | ||
1277 | WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); | ||
1278 | |||
1279 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1280 | |||
1281 | /* Enable zero cross by default */ | 1277 | /* Enable zero cross by default */ |
1282 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, | 1278 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, |
1283 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); | 1279 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); |
@@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1287 | if (!wm9081->pdata.num_retune_configs) { | 1283 | if (!wm9081->pdata.num_retune_configs) { |
1288 | dev_dbg(codec->dev, | 1284 | dev_dbg(codec->dev, |
1289 | "No ReTune Mobile data, using normal EQ\n"); | 1285 | "No ReTune Mobile data, using normal EQ\n"); |
1290 | snd_soc_add_controls(codec, wm9081_eq_controls, | 1286 | snd_soc_add_codec_controls(codec, wm9081_eq_controls, |
1291 | ARRAY_SIZE(wm9081_eq_controls)); | 1287 | ARRAY_SIZE(wm9081_eq_controls)); |
1292 | } | 1288 | } |
1293 | 1289 | ||
@@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec) | |||
1300 | return 0; | 1296 | return 0; |
1301 | } | 1297 | } |
1302 | 1298 | ||
1303 | #ifdef CONFIG_PM | ||
1304 | static int wm9081_suspend(struct snd_soc_codec *codec) | ||
1305 | { | ||
1306 | wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1307 | |||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | static int wm9081_resume(struct snd_soc_codec *codec) | ||
1312 | { | ||
1313 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | ||
1314 | |||
1315 | regcache_sync(wm9081->regmap); | ||
1316 | |||
1317 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | #else | ||
1322 | #define wm9081_suspend NULL | ||
1323 | #define wm9081_resume NULL | ||
1324 | #endif | ||
1325 | |||
1326 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | 1299 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { |
1327 | .probe = wm9081_probe, | 1300 | .probe = wm9081_probe, |
1328 | .remove = wm9081_remove, | 1301 | .remove = wm9081_remove, |
1329 | .suspend = wm9081_suspend, | ||
1330 | .resume = wm9081_resume, | ||
1331 | 1302 | ||
1332 | .set_sysclk = wm9081_set_sysclk, | 1303 | .set_sysclk = wm9081_set_sysclk, |
1333 | .set_bias_level = wm9081_set_bias_level, | 1304 | .set_bias_level = wm9081_set_bias_level, |
1334 | 1305 | ||
1306 | .idle_bias_off = true, | ||
1307 | |||
1335 | .controls = wm9081_snd_controls, | 1308 | .controls = wm9081_snd_controls, |
1336 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1309 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1337 | .dapm_widgets = wm9081_dapm_widgets, | 1310 | .dapm_widgets = wm9081_dapm_widgets, |
@@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1395 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), | 1368 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
1396 | sizeof(wm9081->pdata)); | 1369 | sizeof(wm9081->pdata)); |
1397 | 1370 | ||
1371 | reg = 0; | ||
1372 | if (wm9081->pdata.irq_high) | ||
1373 | reg |= WM9081_IRQ_POL; | ||
1374 | if (!wm9081->pdata.irq_cmos) | ||
1375 | reg |= WM9081_IRQ_OP_CTRL; | ||
1376 | regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL, | ||
1377 | WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); | ||
1378 | |||
1379 | regcache_cache_only(wm9081->regmap, true); | ||
1380 | |||
1398 | ret = snd_soc_register_codec(&i2c->dev, | 1381 | ret = snd_soc_register_codec(&i2c->dev, |
1399 | &soc_codec_dev_wm9081, &wm9081_dai, 1); | 1382 | &soc_codec_dev_wm9081, &wm9081_dai, 1); |
1400 | if (ret < 0) | 1383 | if (ret < 0) |
@@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = { | |||
1435 | }; | 1418 | }; |
1436 | #endif | 1419 | #endif |
1437 | 1420 | ||
1438 | static int __init wm9081_modinit(void) | 1421 | module_i2c_driver(wm9081_i2c_driver); |
1439 | { | ||
1440 | int ret = 0; | ||
1441 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1442 | ret = i2c_add_driver(&wm9081_i2c_driver); | ||
1443 | if (ret != 0) { | ||
1444 | printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", | ||
1445 | ret); | ||
1446 | } | ||
1447 | #endif | ||
1448 | return ret; | ||
1449 | } | ||
1450 | module_init(wm9081_modinit); | ||
1451 | |||
1452 | static void __exit wm9081_exit(void) | ||
1453 | { | ||
1454 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1455 | i2c_del_driver(&wm9081_i2c_driver); | ||
1456 | #endif | ||
1457 | } | ||
1458 | module_exit(wm9081_exit); | ||
1459 | |||
1460 | 1422 | ||
1461 | MODULE_DESCRIPTION("ASoC WM9081 driver"); | 1423 | MODULE_DESCRIPTION("ASoC WM9081 driver"); |
1462 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1424 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |