ASoC: rt5651: Add support for active-high jack detect
authorHans de Goede <hdegoede@redhat.com>
Tue, 5 Mar 2019 11:38:59 +0000 (12:38 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 18 Mar 2019 12:08:02 +0000 (12:08 +0000)
Some boards use a jack-receptacle with a switch which reports the
jack-inserted status as active-high, rather then the standard active-low
reporting most jacks use.

This commit adds support for it. This is activated by a boolean
"realtek,jack-detect-not-inverted" device-property. The not-inverted
in the device-property name, rather then active-high, was chosen to keep
the device-property naming consistent with the rt5640 codec driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Documentation/devicetree/bindings/sound/rt5651.txt
sound/soc/codecs/rt5651.c
sound/soc/codecs/rt5651.h

index a41199a5cd79b5225b2b732bacfef782d9286d54..56e736a1cba97414c8399d507c08d24d5c280742 100644 (file)
@@ -22,6 +22,11 @@ Optional properties:
   2: Use JD1_2 pin for jack-detect
   3: Use JD2 pin for jack-detect
 
+- realtek,jack-detect-not-inverted
+  bool. Normal jack-detect switches give an inverted (active-low) signal,
+  set this bool in the rare case you've a jack-detect switch which is not
+  inverted.
+
 - realtek,over-current-threshold-microamp
   u32, micbias over-current detection threshold in µA, valid values are
   600, 1500 and 2000µA.
index 29b2d60076b022f824032c0e9aed87b18bbc4148..cb8252ff31cb86f22e52c2cb297561f422b54503 100644 (file)
@@ -1645,7 +1645,10 @@ static bool rt5651_jack_inserted(struct snd_soc_component *component)
                break;
        }
 
-       return val == 0;
+       if (rt5651->jd_active_high)
+               return val != 0;
+       else
+               return val == 0;
 }
 
 /* Jack detect and button-press timings */
@@ -1868,20 +1871,47 @@ static void rt5651_enable_jack_detect(struct snd_soc_component *component,
        case RT5651_JD1_1:
                snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
                        RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_1);
-               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
-                       RT5651_JD1_1_IRQ_EN, RT5651_JD1_1_IRQ_EN);
+               /* active-low is normal, set inv flag for active-high */
+               if (rt5651->jd_active_high)
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV,
+                               RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV);
+               else
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD1_1_IRQ_EN | RT5651_JD1_1_INV,
+                               RT5651_JD1_1_IRQ_EN);
                break;
        case RT5651_JD1_2:
                snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
                        RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD1_2);
-               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
-                       RT5651_JD1_2_IRQ_EN, RT5651_JD1_2_IRQ_EN);
+               /* active-low is normal, set inv flag for active-high */
+               if (rt5651->jd_active_high)
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV,
+                               RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV);
+               else
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD1_2_IRQ_EN | RT5651_JD1_2_INV,
+                               RT5651_JD1_2_IRQ_EN);
                break;
        case RT5651_JD2:
                snd_soc_component_update_bits(component, RT5651_JD_CTRL2,
                        RT5651_JD_TRG_SEL_MASK, RT5651_JD_TRG_SEL_JD2);
-               snd_soc_component_update_bits(component, RT5651_IRQ_CTRL1,
-                       RT5651_JD2_IRQ_EN, RT5651_JD2_IRQ_EN);
+               /* active-low is normal, set inv flag for active-high */
+               if (rt5651->jd_active_high)
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD2_IRQ_EN | RT5651_JD2_INV,
+                               RT5651_JD2_IRQ_EN | RT5651_JD2_INV);
+               else
+                       snd_soc_component_update_bits(component,
+                               RT5651_IRQ_CTRL1,
+                               RT5651_JD2_IRQ_EN | RT5651_JD2_INV,
+                               RT5651_JD2_IRQ_EN);
                break;
        default:
                dev_err(component->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
@@ -1986,6 +2016,9 @@ static void rt5651_apply_properties(struct snd_soc_component *component)
                                     "realtek,jack-detect-source", &val) == 0)
                rt5651->jd_src = val;
 
+       if (device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted"))
+               rt5651->jd_active_high = true;
+
        /*
         * Testing on various boards has shown that good defaults for the OVCD
         * threshold and scale-factor are 2000µA and 0.75. For an effective
index 41fcb8b5eb4072ce0e62002976a26aaf95cf6592..05b0f6f8b95d387be136157643cd110e4866b3ba 100644 (file)
@@ -2083,6 +2083,7 @@ struct rt5651_priv {
        int release_count;
        int poll_count;
        unsigned int jd_src;
+       bool jd_active_high;
        unsigned int ovcd_th;
        unsigned int ovcd_sf;