ASoC: jz4752b: Capture fixes
[platform/kernel/linux-rpi.git] / sound / soc / codecs / wm8962.c
index 8104966..b4b4355 100644 (file)
@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
               4, 1, 0, inmix_tlv),
 };
 
+static int tp_event(struct snd_soc_dapm_widget *w,
+                   struct snd_kcontrol *kcontrol, int event)
+{
+       int ret, reg, val, mask;
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+       ret = pm_runtime_resume_and_get(component->dev);
+       if (ret < 0) {
+               dev_err(component->dev, "Failed to resume device: %d\n", ret);
+               return ret;
+       }
+
+       reg = WM8962_ADDITIONAL_CONTROL_4;
+
+       if (!strcmp(w->name, "TEMP_HP")) {
+               mask = WM8962_TEMP_ENA_HP_MASK;
+               val = WM8962_TEMP_ENA_HP;
+       } else if (!strcmp(w->name, "TEMP_SPK")) {
+               mask = WM8962_TEMP_ENA_SPK_MASK;
+               val = WM8962_TEMP_ENA_SPK;
+       } else {
+               pm_runtime_put(component->dev);
+               return -EINVAL;
+       }
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               val = 0;
+               fallthrough;
+       case SND_SOC_DAPM_POST_PMU:
+               ret = snd_soc_component_update_bits(component, reg, mask, val);
+               break;
+       default:
+               WARN(1, "Invalid event %d\n", event);
+               pm_runtime_put(component->dev);
+               return -EINVAL;
+       }
+
+       pm_runtime_put(component->dev);
+
+       return 0;
+}
+
 static int cp_event(struct snd_soc_dapm_widget *w,
                    struct snd_kcontrol *kcontrol, int event)
 {
@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
                      WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
                      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
                   inpgal, ARRAY_SIZE(inpgal)),
@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
        if (ret < 0)
                goto err_pm_runtime;
 
+       regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
+                           WM8962_TEMP_ENA_HP_MASK, 0);
+       regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
+                           WM8962_TEMP_ENA_SPK_MASK, 0);
+
        regcache_cache_only(wm8962->regmap, true);
 
        /* The drivers should power up as needed */