[Artful][PATCH 3/3] UBUNTU: SAUCE: ASoC: rt5670: Add support for Wyse 3040

Wen-chien Jesse Sung jesse.sung at canonical.com
Mon Oct 16 11:27:00 UTC 2017


BugLink: https://launchpad.net/bugs/1723916

The rt5760 on Wyse 3040 requires some extra code to work.
This commit uses PCI ID to identify Wyse 3040 and does things
specific to the platform when there's a match. There should
be no impact to other systems using rt5670.

Based on a patch from realtek.

Signed-off-by: Wen-chien Jesse Sung <jesse.sung at canonical.com>
---
 sound/soc/codecs/rt5670.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 sound/soc/codecs/rt5670.h |  2 ++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 054b613..1b3dc29 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -20,6 +20,7 @@
 #include <linux/acpi.h>
 #include <linux/spi/spi.h>
 #include <linux/dmi.h>
+#include <linux/pci.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -426,7 +427,10 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
 			RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
 			RT5670_CBJ_MN_JD);
-		snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
+		if (unlikely(rt5670->is_wyse3040))
+			snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0034);
+		else
+			snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
 		snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
 			RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
 		snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
@@ -1466,6 +1470,10 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
 			RT5670_L_MUTE | RT5670_R_MUTE, 0);
 		msleep(80);
 		regmap_write(rt5670->regmap, RT5670_DEPOP_M1, 0x8019);
+		if (rt5670->is_wyse3040)
+			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+					   RT5670_GP2_PF_MASK | RT5670_GP2_OUT_MASK,
+					   RT5670_GP2_PF_OUT | RT5670_GP2_OUT_HI);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
@@ -1500,11 +1508,16 @@ static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST1_P, RT5670_PWR_BST1_P);
+		if (rt5670->is_wyse3040)
+			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+					   RT5670_GP2_PF_MASK | RT5670_GP2_OUT_MASK,
+					   RT5670_GP2_PF_OUT | RT5670_GP2_OUT_HI);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
@@ -1523,11 +1536,16 @@ static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
 		snd_soc_update_bits(codec, RT5670_PWR_ANLG2,
 				    RT5670_PWR_BST2_P, RT5670_PWR_BST2_P);
+		if (rt5670->is_wyse3040)
+			regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+					   RT5670_GP2_PF_MASK | RT5670_GP2_OUT_MASK,
+					   RT5670_GP2_PF_OUT | RT5670_GP2_OUT_HI);
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
@@ -2550,6 +2568,7 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 			unsigned int rx_mask, int slots, int slot_width)
 {
 	struct snd_soc_codec *codec = dai->codec;
+	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 	unsigned int val = 0;
 
 	if (rx_mask || tx_mask)
@@ -2589,6 +2608,9 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
 	snd_soc_update_bits(codec, RT5670_TDM_CTRL_1, 0x7c00, val);
 
+	if (rt5670->is_wyse3040 && (rt5670->v_id >= 5))
+		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x0800, 0x0800);
+
 	return 0;
 }
 
@@ -2675,6 +2697,8 @@ static int rt5670_probe(struct snd_soc_codec *codec)
 			"The driver is for RT5670 RT5671 or RT5672 only\n");
 		return -ENODEV;
 	}
+	if (rt5670->is_wyse3040)
+		rt5670->v_id = snd_soc_read(codec, RT5670_VENDOR_ID) & 0xff;
 	rt5670->codec = codec;
 
 	return 0;
@@ -2694,6 +2718,10 @@ static int rt5670_suspend(struct snd_soc_codec *codec)
 {
 	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 
+	if (rt5670->is_wyse3040)
+		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+				   RT5670_GP2_PF_MASK | RT5670_GP2_OUT_MASK,
+				   RT5670_GP2_PF_OUT | RT5670_GP2_OUT_LO);
 	regcache_cache_only(rt5670->regmap, true);
 	regcache_mark_dirty(rt5670->regmap);
 	return 0;
@@ -2866,6 +2894,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 	struct rt5670_priv *rt5670;
 	int ret;
 	unsigned int val;
+	struct pci_dev *pdev_host;
 
 	rt5670 = devm_kzalloc(&i2c->dev,
 				sizeof(struct rt5670_priv),
@@ -2890,6 +2919,13 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 		rt5670->pdata.jd_mode = 2;
 	}
 
+	pdev_host = pci_get_subsys(0x8086, 0x2280, 0x1028, 0x07c1, NULL);
+	if (pdev_host) {
+		rt5670->is_wyse3040 = true;
+		rt5670->pdata.dmic_en = false;
+		pci_dev_put(pdev_host);
+	}
+
 	rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
 	if (IS_ERR(rt5670->regmap)) {
 		ret = PTR_ERR(rt5670->regmap);
@@ -2913,6 +2949,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 
 	regmap_write(rt5670->regmap, RT5670_RESET, 0);
 
+	if (rt5670->is_wyse3040)
+		regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+				   RT5670_GP2_PF_MASK | RT5670_GP2_OUT_MASK,
+				   RT5670_GP2_PF_OUT | RT5670_GP2_OUT_LO);
+
 	regmap_read(rt5670->regmap, RT5670_VENDOR_ID, &val);
 	if (val >= 4)
 		regmap_write(rt5670->regmap, RT5670_GPIO_CTRL3, 0x0980);
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 5ba485c..26b6f1a 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1997,6 +1997,8 @@ struct rt5670_priv {
 	int lrck[RT5670_AIFS];
 	int bclk[RT5670_AIFS];
 	int master[RT5670_AIFS];
+	int v_id;
+	bool is_wyse3040;
 
 	int pll_src;
 	int pll_in;
-- 
2.7.4





More information about the kernel-team mailing list