aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9081.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r--sound/soc/codecs/wm9081.c80
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[] = {
824static int wm9081_set_bias_level(struct snd_soc_codec *codec, 824static 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
1304static 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
1311static 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
1326static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { 1299static 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
1438static int __init wm9081_modinit(void) 1421module_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}
1450module_init(wm9081_modinit);
1451
1452static 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}
1458module_exit(wm9081_exit);
1459
1460 1422
1461MODULE_DESCRIPTION("ASoC WM9081 driver"); 1423MODULE_DESCRIPTION("ASoC WM9081 driver");
1462MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1424MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");