ASoC: rt5677: move jack-detect init to i2c probe
authorFletcher Woodruff <fletcherw@chromium.org>
Fri, 14 Jun 2019 19:48:52 +0000 (13:48 -0600)
committerMark Brown <broonie@kernel.org>
Mon, 17 Jun 2019 15:12:45 +0000 (16:12 +0100)
This patch moves the code to select the gpios for jack detection
from rt5677_probe to rt5677_init_irq (called from rt5677_i2c_probe).

It also sets some registers to fix bugs related to jack detection, and
adds some constants and comments to make it easier to understand what
certain register settings are controlling.

Signed-off-by: Ben Zhang <benzh@chromium.org>
Signed-off-by: Fletcher Woodruff <fletcherw@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt5677.c
sound/soc/codecs/rt5677.h

index fe000f30b9ad5f9fad6d142940e6842ea554cc49..87a92ba0d040b71569f6d6150de4abe484e57d3b 100644 (file)
@@ -4716,37 +4716,13 @@ static int rt5677_probe(struct snd_soc_component *component)
 
        snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
 
-       regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
+       regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
+                       ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020);
        regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
 
        for (i = 0; i < RT5677_GPIO_NUM; i++)
                rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);
 
-       if (rt5677->irq_data) {
-               regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, 0x8000,
-                       0x8000);
-               regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x0018,
-                       0x0008);
-
-               if (rt5677->pdata.jd1_gpio)
-                       regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
-                               RT5677_SEL_GPIO_JD1_MASK,
-                               rt5677->pdata.jd1_gpio <<
-                               RT5677_SEL_GPIO_JD1_SFT);
-
-               if (rt5677->pdata.jd2_gpio)
-                       regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
-                               RT5677_SEL_GPIO_JD2_MASK,
-                               rt5677->pdata.jd2_gpio <<
-                               RT5677_SEL_GPIO_JD2_SFT);
-
-               if (rt5677->pdata.jd3_gpio)
-                       regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
-                               RT5677_SEL_GPIO_JD3_MASK,
-                               rt5677->pdata.jd3_gpio <<
-                               RT5677_SEL_GPIO_JD3_SFT);
-       }
-
        mutex_init(&rt5677->dsp_cmd_lock);
        mutex_init(&rt5677->dsp_pri_lock);
 
@@ -5096,6 +5072,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)
 {
        int ret;
        struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
+       unsigned int jd_mask = 0, jd_val = 0;
 
        if (!rt5677->pdata.jd1_gpio &&
                !rt5677->pdata.jd2_gpio &&
@@ -5107,6 +5084,37 @@ static int rt5677_init_irq(struct i2c_client *i2c)
                return -EINVAL;
        }
 
+       /*
+        * Select RC as the debounce clock so that GPIO works even when
+        * MCLK is gated which happens when there is no audio stream
+        * (SND_SOC_BIAS_OFF).
+        */
+       regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
+                       RT5677_IRQ_DEBOUNCE_SEL_MASK,
+                       RT5677_IRQ_DEBOUNCE_SEL_RC);
+
+       /* Enable auto power on RC when GPIO states are changed */
+       regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL1, 0xff, 0xff);
+
+       /* Select and enable jack detection sources per platform data */
+       if (rt5677->pdata.jd1_gpio) {
+               jd_mask |= RT5677_SEL_GPIO_JD1_MASK;
+               jd_val  |= rt5677->pdata.jd1_gpio << RT5677_SEL_GPIO_JD1_SFT;
+       }
+       if (rt5677->pdata.jd2_gpio) {
+               jd_mask |= RT5677_SEL_GPIO_JD2_MASK;
+               jd_val  |= rt5677->pdata.jd2_gpio << RT5677_SEL_GPIO_JD2_SFT;
+       }
+       if (rt5677->pdata.jd3_gpio) {
+               jd_mask |= RT5677_SEL_GPIO_JD3_MASK;
+               jd_val  |= rt5677->pdata.jd3_gpio << RT5677_SEL_GPIO_JD3_SFT;
+       }
+       regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, jd_mask, jd_val);
+
+       /* Set GPIO1 pin to be IRQ output */
+       regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
+                       RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
+
        ret = regmap_add_irq_chip(rt5677->regmap, i2c->irq,
                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
                &rt5677_irq_chip, &rt5677->irq_data);
index 076e5161d8da30640dd89c3d629db4ea25426612..c26edd387e340b898fe1a4df1106c0d4df2867f2 100644 (file)
 #define RT5677_GPIO6_P_NOR                     (0x0 << 0)
 #define RT5677_GPIO6_P_INV                     (0x1 << 0)
 
+/* General Control (0xfa) */
+#define RT5677_IRQ_DEBOUNCE_SEL_MASK           (0x3 << 3)
+#define RT5677_IRQ_DEBOUNCE_SEL_MCLK           (0x0 << 3)
+#define RT5677_IRQ_DEBOUNCE_SEL_RC             (0x1 << 3)
+#define RT5677_IRQ_DEBOUNCE_SEL_SLIM           (0x2 << 3)
+
 /* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */
 #define RT5677_DSP_IB_01_H                     (0x1 << 15)
 #define RT5677_DSP_IB_01_H_SFT                 15