ASoC: rt5640: Fix the issue of the abnormal JD2 status
authorOder Chiou <oder_chiou@realtek.com>
Mon, 12 Sep 2022 07:29:31 +0000 (15:29 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 12 Sep 2022 09:50:42 +0000 (10:50 +0100)
The patch fixes the issue of the abnormal JD2 status.

Signed-off-by: Oder Chiou <oder_chiou@realtek.com>
Reported-by: Sameer Pujar <spujar@nvidia.com>
Link: https://lore.kernel.org/r/20220912072931.1856-1-oder_chiou@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt5640.h

index 5a84432..0f8e6dd 100644 (file)
@@ -2494,7 +2494,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
 
        /* Select JD-source */
        snd_soc_component_update_bits(component, RT5640_JD_CTRL,
-               RT5640_JD_MASK, rt5640->jd_src);
+               RT5640_JD_MASK, rt5640->jd_src << RT5640_JD_SFT);
 
        /* Selecting GPIO01 as an interrupt */
        snd_soc_component_update_bits(component, RT5640_GPIO_CTRL1,
@@ -2504,12 +2504,8 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
        snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3,
                RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT);
 
-       /* Enabling jd2 in general control 1 */
        snd_soc_component_write(component, RT5640_DUMMY1, 0x3f41);
 
-       /* Enabling jd2 in general control 2 */
-       snd_soc_component_write(component, RT5640_DUMMY2, 0x4001);
-
        rt5640_set_ovcd_params(component);
 
        /*
@@ -2518,12 +2514,25 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
         * pin 0/1 instead of it being stuck to 1. So we invert the JD polarity
         * on systems where the hardware does not already do this.
         */
-       if (rt5640->jd_inverted)
-               snd_soc_component_write(component, RT5640_IRQ_CTRL1,
-                                       RT5640_IRQ_JD_NOR);
-       else
-               snd_soc_component_write(component, RT5640_IRQ_CTRL1,
-                                       RT5640_IRQ_JD_NOR | RT5640_JD_P_INV);
+       if (rt5640->jd_inverted) {
+               if (rt5640->jd_src == RT5640_JD_SRC_JD1_IN4P)
+                       snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+                               RT5640_IRQ_JD_NOR);
+               else if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
+                       snd_soc_component_update_bits(component, RT5640_DUMMY2,
+                               RT5640_IRQ_JD2_MASK | RT5640_JD2_MASK,
+                               RT5640_IRQ_JD2_NOR | RT5640_JD2_EN);
+       } else {
+               if (rt5640->jd_src == RT5640_JD_SRC_JD1_IN4P)
+                       snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+                               RT5640_IRQ_JD_NOR | RT5640_JD_P_INV);
+               else if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
+                       snd_soc_component_update_bits(component, RT5640_DUMMY2,
+                               RT5640_IRQ_JD2_MASK | RT5640_JD2_P_MASK |
+                               RT5640_JD2_MASK,
+                               RT5640_IRQ_JD2_NOR | RT5640_JD2_P_INV |
+                               RT5640_JD2_EN);
+       }
 
        rt5640->jack = jack;
        if (rt5640->jack->status & SND_JACK_MICROPHONE) {
@@ -2725,10 +2734,8 @@ static int rt5640_probe(struct snd_soc_component *component)
 
        if (device_property_read_u32(component->dev,
                                     "realtek,jack-detect-source", &val) == 0) {
-               if (val <= RT5640_JD_SRC_GPIO4)
-                       rt5640->jd_src = val << RT5640_JD_SFT;
-               else if (val == RT5640_JD_SRC_HDA_HEADER)
-                       rt5640->jd_src = RT5640_JD_SRC_HDA_HEADER;
+               if (val <= RT5640_JD_SRC_HDA_HEADER)
+                       rt5640->jd_src = val;
                else
                        dev_warn(component->dev, "Warning: Invalid jack-detect-source value: %d, leaving jack-detect disabled\n",
                                 val);
@@ -2809,12 +2816,31 @@ static int rt5640_resume(struct snd_soc_component *component)
        regcache_sync(rt5640->regmap);
 
        if (rt5640->jack) {
-               if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)
+               if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) {
                        snd_soc_component_update_bits(component,
                                RT5640_DUMMY2, 0x1100, 0x1100);
-               else
-                       snd_soc_component_write(component, RT5640_DUMMY2,
-                               0x4001);
+               } else {
+                       if (rt5640->jd_inverted) {
+                               if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
+                                       snd_soc_component_update_bits(
+                                               component, RT5640_DUMMY2,
+                                               RT5640_IRQ_JD2_MASK |
+                                               RT5640_JD2_MASK,
+                                               RT5640_IRQ_JD2_NOR |
+                                               RT5640_JD2_EN);
+
+                       } else {
+                               if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
+                                       snd_soc_component_update_bits(
+                                               component, RT5640_DUMMY2,
+                                               RT5640_IRQ_JD2_MASK |
+                                               RT5640_JD2_P_MASK |
+                                               RT5640_JD2_MASK,
+                                               RT5640_IRQ_JD2_NOR |
+                                               RT5640_JD2_P_INV |
+                                               RT5640_JD2_EN);
+                       }
+               }
 
                queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
        }
index 505c935..f58b88e 100644 (file)
 #define RT5640_M_MONO_ADC_R_SFT                        12
 #define RT5640_MCLK_DET                                (0x1 << 11)
 
+/* General Control 1 (0xfb) */
+#define RT5640_IRQ_JD2_MASK                    (0x1 << 12)
+#define RT5640_IRQ_JD2_SFT                     12
+#define RT5640_IRQ_JD2_BP                      (0x0 << 12)
+#define RT5640_IRQ_JD2_NOR                     (0x1 << 12)
+#define RT5640_JD2_P_MASK                      (0x1 << 10)
+#define RT5640_JD2_P_SFT                       10
+#define RT5640_JD2_P_NOR                       (0x0 << 10)
+#define RT5640_JD2_P_INV                       (0x1 << 10)
+#define RT5640_JD2_MASK                                (0x1 << 8)
+#define RT5640_JD2_SFT                         8
+#define RT5640_JD2_DIS                         (0x0 << 8)
+#define RT5640_JD2_EN                          (0x1 << 8)
+
 /* Codec Private Register definition */
 
 /* MIC Over current threshold scale factor (0x15) */