Audio:Re-apply Cirrus' patch for hp detect
authoryaozm1 <yaozm1@lenovo.com>
Sat, 23 Mar 2019 06:56:17 +0000 (14:56 +0800)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:31:58 +0000 (17:31 +0800)
Force EP demux over to headphones to run HPDET
Add invert logic clamp.
Set clamp Defenderault value to true.

Change-Id: Ib4202e2d226e5585506acdf114c3056b60ab8d2b
Signed-off-by: yaozm1 <yaozm1@mt.com>
Reviewed-on: https://gerrit.mot.com/1326172
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key

drivers/extcon/extcon-madera.c
include/linux/mfd/madera/core.h
sound/soc/codecs/madera.c

index 0d4420ac0f9aed60063a9783eb28c5d9fb9b1210..ccd7db6205553b384124d1908d6db365d03e4058 100755 (executable)
@@ -769,9 +769,7 @@ static void madera_jds_timeout_work(struct work_struct *work)
 static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
 {
        struct madera *madera = info->madera;
-       unsigned int mask = 0, val = 0;
-       unsigned int edre_reg = 0, edre_val = 0;
-       unsigned int ep_sel = 0;
+       unsigned int mask = 0, ep_mask = 0, val = 0;
        int ret;
 
        snd_soc_dapm_mutex_lock(madera->dapm);
@@ -779,38 +777,14 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
        switch (madera->type) {
        case CS47L15:
        case CS47L35:
-       case CS47L92:
-       case CS47L93:
-               /*
-                * check whether audio is routed to EPOUT, do not disable OUT1
-                * in that case
-                */
-               regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
-               ep_sel &= MADERA_EP_SEL_MASK;
-               break;
-       default:
-               break;
-       };
-
-       switch (madera->type) {
-       case CS47L35:
+               ep_mask = MADERA_EP_SEL_MASK;
                break;
        case CS47L85:
        case WM1840:
-               edre_reg = MADERA_EDRE_MANUAL;
-               mask = MADERA_HP1L_SHRTO | MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
-               if (clamp) {
-                       val = MADERA_HP1L_SHRTO;
-                       edre_val = MADERA_EDRE_OUT1L_MANUAL |
-                                  MADERA_EDRE_OUT1R_MANUAL;
-               } else {
-                       val = MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
-                       edre_val = 0;
-               }
                break;
        default:
                mask = MADERA_HPD_OVD_ENA_SEL_MASK;
-               if (clamp)
+               if (!clamp)
                        val = MADERA_HPD_OVD_ENA_SEL_MASK;
                else
                        val = 0;
@@ -819,13 +793,14 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
 
        madera->out_clamp[0] = clamp;
 
-       /* Keep the HP output stages disabled while doing the clamp */
-       if (clamp && !ep_sel) {
+       /* Keep the HP output stages disabled while disabling the clamp */
+       if (!clamp) {
                ret = regmap_update_bits(madera->regmap,
                                         MADERA_OUTPUT_ENABLES_1,
-                                        (MADERA_OUT1L_ENA |
+                                        ep_mask |
+                                        ((MADERA_OUT1L_ENA |
                                          MADERA_OUT1R_ENA) <<
-                                        (2 * (info->pdata->output - 1)),
+                                        (2 * (info->pdata->output - 1))),
                                         0);
                if (ret)
                        dev_warn(info->dev,
@@ -833,33 +808,13 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
                                 ret);
        }
 
-       if (edre_reg && !ep_sel) {
-               ret = regmap_update_bits(madera->regmap, edre_reg,
-                                        MADERA_EDRE_OUT1L_MANUAL_MASK |
-                                        MADERA_EDRE_OUT1R_MANUAL_MASK,
-                                        edre_val);
-               if (ret)
-                       dev_warn(info->dev,
-                                "Failed to set EDRE Manual: %d\n", ret);
-       }
-
-       dev_warn(info->dev, "%s clamp mask=0x%x val=0x%x\n",
+       dev_dbg(info->dev, "%s clamp mask=0x%x val=0x%x\n",
                clamp ? "Setting" : "Clearing", mask, val);
 
        switch (madera->type) {
        case CS47L35:
-               break;
        case CS47L85:
        case WM1840:
-               ret = regmap_update_bits(madera->regmap,
-                                        MADERA_HP_CTRL_1L, mask, val);
-               if (ret)
-                       dev_warn(info->dev, "Failed to do clamp: %d\n", ret);
-
-               ret = regmap_update_bits(madera->regmap,
-                                        MADERA_HP_CTRL_1R, mask, val);
-               if (ret)
-                       dev_warn(info->dev, "Failed to do clamp: %d\n", ret);
                break;
        default:
                ret = regmap_update_bits(madera->regmap,
@@ -871,12 +826,22 @@ static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
                break;
        }
 
-       /* Restore the desired state while not doing the clamp */
-       if (!clamp) {
+       /* Restore the desired state when restoring the clamp */
+       if (clamp) {
+               if (ep_mask) {
+                       ret = regmap_update_bits(madera->regmap,
+                                                MADERA_OUTPUT_ENABLES_1,
+                                                ep_mask, madera->ep_sel);
+                       if (ret)
+                               dev_warn(info->dev,
+                                        "Failed to restore output demux: %d\n",
+                                        ret);
+               }
+
                madera->out_shorted[0] = (madera->hp_impedance_x100[0] <=
                                          info->hpdet_short_x100);
 
-               if (!madera->out_shorted[0] && !ep_sel) {
+               if (!madera->out_shorted[0]) {
                        ret = regmap_update_bits(madera->regmap,
                                                 MADERA_OUTPUT_ENABLES_1,
                                                 (MADERA_OUT1L_ENA |
@@ -1684,7 +1649,7 @@ int madera_hpdet_start(struct madera_extcon *info)
        case CS47L35:
        case CS47L85:
        case WM1840:
-               madera_extcon_hp_clamp(info, true);
+               madera_extcon_hp_clamp(info, false);
                ret = regmap_update_bits(madera->regmap,
                                         MADERA_ACCESSORY_DETECT_MODE_1,
                                         MADERA_ACCDET_MODE_MASK,
@@ -1735,7 +1700,7 @@ int madera_hpdet_start(struct madera_extcon *info)
                                "Failed to set HPDET sense: %d\n", ret);
                        goto err;
                }
-               madera_extcon_hp_clamp(info, true);
+               madera_extcon_hp_clamp(info, false);
                madera_hpdet_start_micd(info);
                break;
        }
@@ -1750,7 +1715,7 @@ int madera_hpdet_start(struct madera_extcon *info)
        return 0;
 
 err:
-       madera_extcon_hp_clamp(info, false);
+       madera_extcon_hp_clamp(info, true);
 
        pm_runtime_put_autosuspend(info->dev);
 
@@ -1848,7 +1813,7 @@ void madera_hpdet_stop(struct madera_extcon *info)
                break;
        }
 
-       madera_extcon_hp_clamp(info, false);
+       madera_extcon_hp_clamp(info, true);
 
        pm_runtime_mark_last_busy(info->dev);
        pm_runtime_put_autosuspend(info->dev);
@@ -3286,6 +3251,9 @@ static int madera_extcon_probe(struct platform_device *pdev)
 
        madera_extcon_set_micd_clamp_mode(info);
 
+        /*Since Invert the calmp was set, the calmp need to set true as init in case EPOUT will be mute */
+       madera->out_clamp[0]=true;
+
        if ((info->num_micd_modes > 2) && !info->micd_pol_gpio)
                dev_warn(info->dev, "Have >1 mic_configs but no pol_gpio\n");
 
index 090440ff0b5eb85b7d9712929b3b28cace9ebfbd..a08db0bd1d7950f4ba395141fc0aa67e06c481a2 100755 (executable)
@@ -164,6 +164,7 @@ struct madera {
        unsigned int out_clamp[MADERA_MAX_OUTPUT];
        unsigned int out_shorted[MADERA_MAX_OUTPUT];
        unsigned int hp_ena;
+       unsigned int ep_sel;
        unsigned int hp_impedance_x100[MADERA_MAX_ACCESSORY];
 
        struct snd_soc_dapm_context *dapm;
index 59a4bf329ce53911bb74b8d77bb015beb5e54937..994621fe27c8b7581c4ec844f3c677f4b1a716f5 100755 (executable)
@@ -522,20 +522,21 @@ int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
                snd_soc_dapm_kcontrol_dapm(kcontrol);
        struct madera *madera = dev_get_drvdata(codec->dev->parent);
        struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-       unsigned int ep_sel, mux, change;
-       int ret, demux_change_ret;
+       unsigned int mux, change;
+       int ret, demux_change_ret = 0;
        bool out_mono, restore_out = true;
 
        if (ucontrol->value.enumerated.item[0] > e->items - 1)
                return -EINVAL;
 
        mux = ucontrol->value.enumerated.item[0];
-       ep_sel = mux << MADERA_EP_SEL_SHIFT;
 
        snd_soc_dapm_mutex_lock(dapm);
 
+       madera->ep_sel = mux << MADERA_EP_SEL_SHIFT;
+
        change = snd_soc_test_bits(codec, MADERA_OUTPUT_ENABLES_1,
-                                  MADERA_EP_SEL_MASK, ep_sel);
+                                  MADERA_EP_SEL_MASK, madera->ep_sel);
        if (!change)
                goto end;
 
@@ -550,23 +551,25 @@ int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
        usleep_range(2000, 3000); /* wait for wseq to complete */
 
        /*
-        * if HP detection clamp is applied while switching to HPOUT
-        * OUT1 should remain disabled and EDRE should be set to manual
+        * if HPDET has disabled the clamp while switching to HPOUT
+        * OUT1 should remain disabled
         */
-       if (!ep_sel &&
-           (madera->out_clamp[0] || madera->out_shorted[0]))
+       if (!madera->ep_sel &&
+           (!madera->out_clamp[0] || madera->out_shorted[0]))
                restore_out = false;
 
        /* change demux setting */
-       demux_change_ret = regmap_update_bits(madera->regmap,
-                                             MADERA_OUTPUT_ENABLES_1,
-                                             MADERA_EP_SEL_MASK, ep_sel);
+       if (madera->out_clamp[0])
+               demux_change_ret = regmap_update_bits(madera->regmap,
+                                                     MADERA_OUTPUT_ENABLES_1,
+                                                     MADERA_EP_SEL_MASK,
+                                                     madera->ep_sel);
        if (demux_change_ret) {
                dev_err(madera->dev, "Failed to set OUT1 demux: %d\n",
                        demux_change_ret);
        } else {
                /* apply correct setting for mono mode */
-               if (!ep_sel && !madera->pdata.codec.out_mono[0])
+               if (!madera->ep_sel && !madera->pdata.codec.out_mono[0])
                        out_mono = false; /* stereo HP */
                else
                        out_mono = true; /* EP or mono HP */
@@ -605,11 +608,14 @@ int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
-       unsigned int val;
-       val = snd_soc_read(codec, MADERA_OUTPUT_ENABLES_1);
-       val &= MADERA_EP_SEL_MASK;
-       val >>= MADERA_EP_SEL_SHIFT;
-       ucontrol->value.enumerated.item[0] = val;
+       struct snd_soc_dapm_context *dapm =
+               snd_soc_dapm_kcontrol_dapm(kcontrol);
+       struct madera *madera = dev_get_drvdata(codec->dev->parent);
+
+       snd_soc_dapm_mutex_lock(dapm);
+       ucontrol->value.enumerated.item[0] = madera->ep_sel >> MADERA_EP_SEL_SHIFT;
+       snd_soc_dapm_mutex_unlock(dapm);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(madera_out1_demux_get);
@@ -2742,9 +2748,9 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w,
        regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
        ep_sel &= MADERA_EP_SEL_MASK;
 
-       /* Force off if HPDET clamp is active for this output */
+       /* Force off if HPDET disabled the clamp for this output */
        if (!ep_sel &&
-           (madera->out_clamp[out_num] || madera->out_shorted[out_num]))
+           (!madera->out_clamp[out_num] || madera->out_shorted[out_num]))
                val = 0;
 
        regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);