]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating
authorDerek Fang <derek.fang@realtek.com>
Mon, 8 Apr 2024 09:10:56 +0000 (17:10 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 16 Jun 2024 11:32:00 +0000 (13:32 +0200)
[ Upstream commit 103abab975087e1f01b76fcb54c91dbb65dbc249 ]

The codec leaves tie combo jack's sleeve/ring2 to floating status
default. It would cause electric noise while connecting the active
speaker jack during boot or shutdown.
This patch requests a gpio to control the additional jack circuit
to tie the contacts to the ground or floating.

Signed-off-by: Derek Fang <derek.fang@realtek.com>
Link: https://msgid.link/r/20240408091057.14165-1-derek.fang@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/codecs/rt5645.c

index 5db63ef33f1a236e8f2d7ec85887c1115da7a63b..ac403827a2290ab5e3a5e2cddb5d1213932a82fc 100644 (file)
@@ -414,6 +414,7 @@ struct rt5645_priv {
        struct regmap *regmap;
        struct i2c_client *i2c;
        struct gpio_desc *gpiod_hp_det;
+       struct gpio_desc *gpiod_cbj_sleeve;
        struct snd_soc_jack *hp_jack;
        struct snd_soc_jack *mic_jack;
        struct snd_soc_jack *btn_jack;
@@ -3169,6 +3170,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
                        RT5645_CBJ_MN_JD, 0);
 
+               if (rt5645->gpiod_cbj_sleeve)
+                       gpiod_set_value(rt5645->gpiod_cbj_sleeve, 1);
+
                msleep(600);
                regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
                val &= 0x7;
@@ -3185,6 +3189,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                        snd_soc_dapm_sync(dapm);
                        rt5645->jack_type = SND_JACK_HEADPHONE;
+                       if (rt5645->gpiod_cbj_sleeve)
+                               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
                }
                if (rt5645->pdata.level_trigger_irq)
                        regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
@@ -3210,6 +3216,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                if (rt5645->pdata.level_trigger_irq)
                        regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
                                RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
+
+               if (rt5645->gpiod_cbj_sleeve)
+                       gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
        }
 
        return rt5645->jack_type;
@@ -3882,6 +3891,16 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
                        return ret;
        }
 
+       rt5645->gpiod_cbj_sleeve = devm_gpiod_get_optional(&i2c->dev, "cbj-sleeve",
+                                                          GPIOD_OUT_LOW);
+
+       if (IS_ERR(rt5645->gpiod_cbj_sleeve)) {
+               ret = PTR_ERR(rt5645->gpiod_cbj_sleeve);
+               dev_info(&i2c->dev, "failed to initialize gpiod, ret=%d\n", ret);
+               if (ret != -ENOENT)
+                       return ret;
+       }
+
        for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
                rt5645->supplies[i].supply = rt5645_supply_names[i];
 
@@ -4125,6 +4144,9 @@ static int rt5645_i2c_remove(struct i2c_client *i2c)
        cancel_delayed_work_sync(&rt5645->jack_detect_work);
        cancel_delayed_work_sync(&rt5645->rcclock_work);
 
+       if (rt5645->gpiod_cbj_sleeve)
+               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
+
        regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
 
        return 0;
@@ -4142,6 +4164,9 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
                0);
        msleep(20);
        regmap_write(rt5645->regmap, RT5645_RESET, 0);
+
+       if (rt5645->gpiod_cbj_sleeve)
+               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
 }
 
 static struct i2c_driver rt5645_i2c_driver = {