diff options
| -rw-r--r-- | sound/soc/codecs/wm8993.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index e97b3f45b24b..bf022f68b84f 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
| @@ -923,10 +923,33 @@ static const struct snd_soc_dapm_route routes[] = { | |||
| 923 | { "Right Headphone Mux", "DAC", "DACR" }, | 923 | { "Right Headphone Mux", "DAC", "DACR" }, |
| 924 | }; | 924 | }; |
| 925 | 925 | ||
| 926 | static void wm8993_cache_restore(struct snd_soc_codec *codec) | ||
| 927 | { | ||
| 928 | u16 *cache = codec->reg_cache; | ||
| 929 | int i; | ||
| 930 | |||
| 931 | if (!codec->cache_sync) | ||
| 932 | return; | ||
| 933 | |||
| 934 | /* Reenable hardware writes */ | ||
| 935 | codec->cache_only = 0; | ||
| 936 | |||
| 937 | /* Restore the register settings */ | ||
| 938 | for (i = 1; i < WM8993_MAX_REGISTER; i++) { | ||
| 939 | if (cache[i] == wm8993_reg_defaults[i]) | ||
| 940 | continue; | ||
| 941 | snd_soc_write(codec, i, cache[i]); | ||
| 942 | } | ||
| 943 | |||
| 944 | /* We're in sync again */ | ||
| 945 | codec->cache_sync = 0; | ||
| 946 | } | ||
| 947 | |||
| 926 | static int wm8993_set_bias_level(struct snd_soc_codec *codec, | 948 | static int wm8993_set_bias_level(struct snd_soc_codec *codec, |
| 927 | enum snd_soc_bias_level level) | 949 | enum snd_soc_bias_level level) |
| 928 | { | 950 | { |
| 929 | struct wm8993_priv *wm8993 = codec->private_data; | 951 | struct wm8993_priv *wm8993 = codec->private_data; |
| 952 | int ret; | ||
| 930 | 953 | ||
| 931 | switch (level) { | 954 | switch (level) { |
| 932 | case SND_SOC_BIAS_ON: | 955 | case SND_SOC_BIAS_ON: |
| @@ -940,6 +963,13 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
| 940 | 963 | ||
| 941 | case SND_SOC_BIAS_STANDBY: | 964 | case SND_SOC_BIAS_STANDBY: |
| 942 | if (codec->bias_level == SND_SOC_BIAS_OFF) { | 965 | if (codec->bias_level == SND_SOC_BIAS_OFF) { |
| 966 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
| 967 | wm8993->supplies); | ||
| 968 | if (ret != 0) | ||
| 969 | return ret; | ||
| 970 | |||
| 971 | wm8993_cache_restore(codec); | ||
| 972 | |||
| 943 | /* Tune DC servo configuration */ | 973 | /* Tune DC servo configuration */ |
| 944 | snd_soc_write(codec, 0x44, 3); | 974 | snd_soc_write(codec, 0x44, 3); |
| 945 | snd_soc_write(codec, 0x56, 3); | 975 | snd_soc_write(codec, 0x56, 3); |
| @@ -992,6 +1022,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
| 992 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, | 1022 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, |
| 993 | WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, | 1023 | WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, |
| 994 | 0); | 1024 | 0); |
| 1025 | |||
| 1026 | #ifdef CONFIG_REGULATOR | ||
| 1027 | /* Post 2.6.34 we will be able to get a callback when | ||
| 1028 | * the regulators are disabled which we can use but | ||
| 1029 | * for now just assume that the power will be cut if | ||
| 1030 | * the regulator API is in use. | ||
| 1031 | */ | ||
| 1032 | codec->cache_sync = 1; | ||
| 1033 | #endif | ||
| 1034 | |||
| 1035 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), | ||
| 1036 | wm8993->supplies); | ||
| 995 | break; | 1037 | break; |
| 996 | } | 1038 | } |
| 997 | 1039 | ||
| @@ -1460,15 +1502,7 @@ static int wm8993_resume(struct platform_device *pdev) | |||
| 1460 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1502 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
| 1461 | struct snd_soc_codec *codec = socdev->card->codec; | 1503 | struct snd_soc_codec *codec = socdev->card->codec; |
| 1462 | struct wm8993_priv *wm8993 = codec->private_data; | 1504 | struct wm8993_priv *wm8993 = codec->private_data; |
| 1463 | u16 *cache = wm8993->reg_cache; | 1505 | int ret; |
| 1464 | int i, ret; | ||
| 1465 | |||
| 1466 | /* Restore the register settings */ | ||
| 1467 | for (i = 1; i < WM8993_MAX_REGISTER; i++) { | ||
| 1468 | if (cache[i] == wm8993_reg_defaults[i]) | ||
| 1469 | continue; | ||
| 1470 | snd_soc_write(codec, i, cache[i]); | ||
| 1471 | } | ||
| 1472 | 1506 | ||
| 1473 | wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1507 | wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1474 | 1508 | ||
| @@ -1584,6 +1618,8 @@ static int wm8993_i2c_probe(struct i2c_client *i2c, | |||
| 1584 | if (ret != 0) | 1618 | if (ret != 0) |
| 1585 | goto err_enable; | 1619 | goto err_enable; |
| 1586 | 1620 | ||
| 1621 | codec->cache_only = 1; | ||
| 1622 | |||
| 1587 | /* By default we're using the output mixers */ | 1623 | /* By default we're using the output mixers */ |
| 1588 | wm8993->class_w_users = 2; | 1624 | wm8993->class_w_users = 2; |
| 1589 | 1625 | ||
