[alsa-devel] [PATCH v2 17/32] ASoC: rt5651: Allow specifying over-current thresholds through device-properties

Hans de Goede hdegoede at redhat.com
Sun Feb 25 11:46:58 CET 2018


OVer-Current-Detection (OVCD) for the micbias current is used to detect if
an inserted jack is a headset or headphones (mic shorted to ground).

Some boards may need different values for the OVCD threshold because of a
resistor on the board in serial with or parallel to the jack mic contact.

This commit adds support for the sofar unset OVCD scale-factor register
values and adds support for specifying non-default values for both the
current threshold and the scale-factor through device-properties.

Cc: devicetree at vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 Documentation/devicetree/bindings/sound/rt5651.txt | 11 ++++++
 include/sound/rt5651.h                             | 11 ++++++
 sound/soc/codecs/rt5651.c                          | 42 +++++++++++++++++++++-
 sound/soc/codecs/rt5651.h                          | 10 ++++++
 4 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/rt5651.txt b/Documentation/devicetree/bindings/sound/rt5651.txt
index 1632c0cf6123..8cb7ee8e79cf 100644
--- a/Documentation/devicetree/bindings/sound/rt5651.txt
+++ b/Documentation/devicetree/bindings/sound/rt5651.txt
@@ -22,6 +22,17 @@ Optional properties:
   2: Use JD1_2 pin for jack-dectect
   3: Use JD2 pin for jack-dectect
 
+- realtek,over-current-threshold
+  u32, micbias over-current detection threshold in µA, valid values are
+  600, 1500 and 2000µA.
+
+- realtek,over-current-scale-factor
+  u32, micbias over-current detection scale-factor, valid values are:
+  0: Scale current by 0.5
+  1: Scale current by 0.75
+  2: Scale current by 1.0
+  3: Scale current by 1.5
+
 Pins on the device (for linking into audio routes) for RT5651:
 
   * DMIC L1
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h
index 725b36c329d0..6403b862fb9a 100644
--- a/include/sound/rt5651.h
+++ b/include/sound/rt5651.h
@@ -22,4 +22,15 @@ enum rt5651_jd_src {
 	RT5651_JD2,
 };
 
+/*
+ * Note these MUST match the values from the DT binding:
+ * Documentation/devicetree/bindings/sound/rt5651.txt
+ */
+enum rt5651_ovcd_sf {
+	RT5651_OVCD_SF_0P5,
+	RT5651_OVCD_SF_0P75,
+	RT5651_OVCD_SF_1P0,
+	RT5651_OVCD_SF_1P5,
+};
+
 #endif
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index dfdc8244d308..38d2e12fe701 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -1592,6 +1592,13 @@ static int rt5651_set_jack(struct snd_soc_component *component,
 			   struct snd_soc_jack *hp_jack, void *data)
 {
 	struct rt5651_priv *rt5651 = snd_soc_component_get_drvdata(component);
+	/*
+	 * 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
+	 * limit of 1500µA, this seems to be more reliable then 1500µA and 1.0.
+	 */
+	unsigned int ovcd_th = RT5651_MIC1_OVTH_2000UA;
+	unsigned int ovcd_sf = RT5651_MIC_OVCD_SF_0P75;
 	int ret;
 	u32 val;
 
@@ -1599,6 +1606,35 @@ static int rt5651_set_jack(struct snd_soc_component *component,
 				     "realtek,jack-detect-source", &val) == 0)
 		rt5651->jd_src = val;
 
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-threshold", &val) == 0) {
+		switch (val) {
+		case 600:
+			ovcd_th = RT5651_MIC1_OVTH_600UA;
+			break;
+		case 1500:
+			ovcd_th = RT5651_MIC1_OVTH_1500UA;
+			break;
+		case 2000:
+			ovcd_th = RT5651_MIC1_OVTH_2000UA;
+			break;
+		default:
+			dev_err(component->dev, "Invalid over-current-threshold value: %d\n",
+				val);
+			return -EINVAL;
+		}
+	}
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-scale-factor", &val) == 0) {
+		if (val > RT5651_OVCD_SF_1P5) {
+			dev_err(component->dev, "Invalid over-current-scale-factor value: %d\n",
+				val);
+			return -EINVAL;
+		}
+		ovcd_sf = val << RT5651_MIC_OVCD_SF_SFT;
+	}
+
 	if (!rt5651->irq)
 		return -EINVAL;
 
@@ -1637,13 +1673,17 @@ static int rt5651_set_jack(struct snd_soc_component *component,
 	snd_soc_component_update_bits(component, RT5651_PWR_ANLG2,
 		RT5651_PWR_JD_M, RT5651_PWR_JD_M);
 
+	/* Set OVCD threshold current and scale-factor */
+	snd_soc_component_write(component, RT5651_PR_BASE + RT5651_BIAS_CUR4,
+				0xa800 | ovcd_sf);
+
 	snd_soc_component_update_bits(component, RT5651_MICBIAS,
 				      RT5651_MIC1_OVCD_MASK |
 				      RT5651_MIC1_OVTH_MASK |
 				      RT5651_PWR_CLK12M_MASK |
 				      RT5651_PWR_MB_MASK,
 				      RT5651_MIC1_OVCD_EN |
-				      RT5651_MIC1_OVTH_600UA |
+				      ovcd_th |
 				      RT5651_PWR_MB_PU |
 				      RT5651_PWR_CLK12M_PU);
 
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 7d9d5fa09d6f..5fb25f7e2a8c 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -138,6 +138,7 @@
 /* Index of Codec Private Register definition */
 #define RT5651_BIAS_CUR1			0x12
 #define RT5651_BIAS_CUR3			0x14
+#define RT5651_BIAS_CUR4			0x15
 #define RT5651_CLSD_INT_REG1			0x1c
 #define RT5651_CHPUMP_INT_REG1			0x24
 #define RT5651_MAMP_INT_REG2			0x37
@@ -1966,6 +1967,15 @@
 #define RT5651_D_GATE_EN_SFT			0
 
 /* Codec Private Register definition */
+
+/* MIC Over current threshold scale factor (0x15) */
+#define RT5651_MIC_OVCD_SF_MASK			(0x3 << 8)
+#define RT5651_MIC_OVCD_SF_SFT			8
+#define RT5651_MIC_OVCD_SF_0P5			(0x0 << 8)
+#define RT5651_MIC_OVCD_SF_0P75			(0x1 << 8)
+#define RT5651_MIC_OVCD_SF_1P0			(0x2 << 8)
+#define RT5651_MIC_OVCD_SF_1P5			(0x3 << 8)
+
 /* 3D Speaker Control (0x63) */
 #define RT5651_3D_SPK_MASK			(0x1 << 15)
 #define RT5651_3D_SPK_SFT			15
-- 
2.14.3



More information about the Alsa-devel mailing list