Unverified Commit 103abab9 authored by Derek Fang's avatar Derek Fang Committed by Mark Brown
Browse files

ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating



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: default avatarDerek Fang <derek.fang@realtek.com>

Link: https://msgid.link/r/20240408091057.14165-1-derek.fang@realtek.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4b9a474c
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -444,6 +444,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;
@@ -3186,6 +3187,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;
@@ -3202,6 +3206,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,
@@ -3229,6 +3235,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;
@@ -4012,6 +4021,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];

@@ -4259,6 +4278,9 @@ static void 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);
}

@@ -4274,6 +4296,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 int __maybe_unused rt5645_sys_suspend(struct device *dev)