diff options
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
| -rw-r--r-- | sound/soc/codecs/wm8731.c | 66 |
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, | |||
| 369 | static int wm8731_set_bias_level(struct snd_soc_codec *codec, | 369 | static 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 | ||
| 614 | err_codec: | 615 | err_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 | ||
| 709 | static struct i2c_driver wm8731_i2c_driver = { | 709 | static 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, |
