Asoc:Apply cirrus' patch to fix hp detect issue
authoryaozm1 <yaozm1@lenovo.com>
Thu, 21 Mar 2019 05:55:59 +0000 (13:55 +0800)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:57 +0000 (20:23 +0300)
From: Charles Keepax <ckeepax@opensource.cirrus.com>
Date: Tue, 19 Mar 2019 17:29:02 +0000
Subject: [PATCH] ASoC: madera: Force EP demux over to headphones to run HPDET

The EP demux needs to be set to the headphones for the HPDET to run the
correct value.

Change-Id: I7bcc0cdca28b2a1b3144ee03f3af84056ddcaba4
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: yaozm1 <yaozm1@mt.com>
Change-Id: I24c057510dfff3b531cd75e3c8aafa255727e87e
Reviewed-on: https://gerrit.mot.com/1324759
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..e4b999b096fe31b7feb98350377b6730c3e25109 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 |
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..669c55189e27b86334f6e945bd986086732c776a 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);