aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8731.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r--sound/soc/codecs/wm8731.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e7c6bf163185..0ab9b6355297 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -225,7 +225,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_device *socdev = rtd->socdev; 226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec; 227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = codec->private_data; 228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 230 int i = get_coeff(wm8731->sysclk, params_rate(params));
231 u16 srate = (coeff_div[i].sr << 2) | 231 u16 srate = (coeff_div[i].sr << 2) |
@@ -292,7 +292,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
292 int clk_id, unsigned int freq, int dir) 292 int clk_id, unsigned int freq, int dir)
293{ 293{
294 struct snd_soc_codec *codec = codec_dai->codec; 294 struct snd_soc_codec *codec = codec_dai->codec;
295 struct wm8731_priv *wm8731 = codec->private_data; 295 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
296 296
297 switch (freq) { 297 switch (freq) {
298 case 11289600: 298 case 11289600:
@@ -369,6 +369,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
369static int wm8731_set_bias_level(struct snd_soc_codec *codec, 369static int wm8731_set_bias_level(struct snd_soc_codec *codec,
370 enum snd_soc_bias_level level) 370 enum snd_soc_bias_level level)
371{ 371{
372 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
373 int i, ret;
374 u8 data[2];
375 u16 *cache = codec->reg_cache;
372 u16 reg; 376 u16 reg;
373 377
374 switch (level) { 378 switch (level) {
@@ -377,6 +381,24 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
377 case SND_SOC_BIAS_PREPARE: 381 case SND_SOC_BIAS_PREPARE:
378 break; 382 break;
379 case SND_SOC_BIAS_STANDBY: 383 case SND_SOC_BIAS_STANDBY:
384 if (codec->bias_level == SND_SOC_BIAS_OFF) {
385 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
386 wm8731->supplies);
387 if (ret != 0)
388 return ret;
389
390 /* Sync reg_cache with the hardware */
391 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
392 if (cache[i] == wm8731_reg[i])
393 continue;
394
395 data[0] = (i << 1) | ((cache[i] >> 8)
396 & 0x0001);
397 data[1] = cache[i] & 0x00ff;
398 codec->hw_write(codec->control_data, data, 2);
399 }
400 }
401
380 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 402 /* Clear PWROFF, gate CLKOUT, everything else as-is */
381 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; 403 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
382 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 404 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
@@ -384,17 +406,15 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
384 case SND_SOC_BIAS_OFF: 406 case SND_SOC_BIAS_OFF:
385 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 407 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
386 snd_soc_write(codec, WM8731_PWR, 0xffff); 408 snd_soc_write(codec, WM8731_PWR, 0xffff);
409 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
410 wm8731->supplies);
387 break; 411 break;
388 } 412 }
389 codec->bias_level = level; 413 codec->bias_level = level;
390 return 0; 414 return 0;
391} 415}
392 416
393#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 417#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
394 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
395 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
396 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
397 SNDRV_PCM_RATE_96000)
398 418
399#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 419#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
400 SNDRV_PCM_FMTBIT_S24_LE) 420 SNDRV_PCM_FMTBIT_S24_LE)
@@ -432,12 +452,9 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
432{ 452{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 454 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
436 455
437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 457
440 wm8731->supplies);
441 return 0; 458 return 0;
442} 459}
443 460
@@ -445,27 +462,8 @@ static int wm8731_resume(struct platform_device *pdev)
445{ 462{
446 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
447 struct snd_soc_codec *codec = socdev->card->codec; 464 struct snd_soc_codec *codec = socdev->card->codec;
448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
450 u8 data[2];
451 u16 *cache = codec->reg_cache;
452 465
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
458 /* Sync reg_cache with the hardware */
459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
460 if (cache[i] == wm8731_reg[i])
461 continue;
462
463 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
464 data[1] = cache[i] & 0x00ff;
465 codec->hw_write(codec->control_data, data, 2);
466 }
467 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
468 wm8731_set_bias_level(codec, codec->suspend_bias_level);
469 467
470 return 0; 468 return 0;
471} 469}
@@ -540,7 +538,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
540 INIT_LIST_HEAD(&codec->dapm_widgets); 538 INIT_LIST_HEAD(&codec->dapm_widgets);
541 INIT_LIST_HEAD(&codec->dapm_paths); 539 INIT_LIST_HEAD(&codec->dapm_paths);
542 540
543 codec->private_data = wm8731; 541 snd_soc_codec_set_drvdata(codec, wm8731);
544 codec->name = "WM8731"; 542 codec->name = "WM8731";
545 codec->owner = THIS_MODULE; 543 codec->owner = THIS_MODULE;
546 codec->bias_level = SND_SOC_BIAS_OFF; 544 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -609,6 +607,9 @@ static int wm8731_register(struct wm8731_priv *wm8731,
609 goto err_codec; 607 goto err_codec;
610 } 608 }
611 609
610 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612
612 return 0; 613 return 0;
613 614
614err_codec: 615err_codec:
@@ -627,7 +628,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
627 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
628 snd_soc_unregister_dai(&wm8731_dai); 629 snd_soc_unregister_dai(&wm8731_dai);
629 snd_soc_unregister_codec(&wm8731->codec); 630 snd_soc_unregister_codec(&wm8731->codec);
630 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 632 kfree(wm8731);
633 wm8731_codec = NULL; 633 wm8731_codec = NULL;
@@ -708,7 +708,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 708
709static struct i2c_driver wm8731_i2c_driver = { 709static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 710 .driver = {
711 .name = "WM8731 I2C Codec", 711 .name = "wm8731",
712 .owner = THIS_MODULE, 712 .owner = THIS_MODULE,
713 }, 713 },
714 .probe = wm8731_i2c_probe, 714 .probe = wm8731_i2c_probe,