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 | ||