All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support
@ 2018-05-08 15:35 Hans de Goede
  2018-05-08 15:35 ` [PATCH 01/19] ASoC: rt5640: Remove is_sys_clk_from_pll, it has ordering issues Hans de Goede
                   ` (19 more replies)
  0 siblings, 20 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Hi All,

This series has been long in the making, but it is finally ready now.
This series adds jack-detect support for rt5640 using devices.

This is modelled after the recent rt5651 codec- and bytcr-rt5651 machine-
driver jack-detect changes (which were actually based on a WIP version of
this series).

As discussed on the list already unfortunately there are no really good
defaults which work everywhere, so patch 18 adds quirks for 10 devices,
I've decided to do this in one go rather then split this into 10 patches.

Patch 19 makes the bytcr-rt5640 set a longname based on the speaker and
input-map quirks, so that userspace can pick a correct UCM profile based
on the longname with working jack-detect based input / output switching.
I've matching patches adding UCM profiles for this to alsa-lib here:
https://github.com/jwrdegoede/alsa-lib/commits/master
I'm waiting with submitting those upstream until patch 19 is accepted
for merging.

Regards,

Hans

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 01/19] ASoC: rt5640: Remove is_sys_clk_from_pll, it has ordering issues
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-08 15:35 ` [PATCH 02/19] ASoC: rt5640: Add devicetree-bindings for dmic, jack-detect Hans de Goede
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

is_sys_clk_from_pll() is used as a snd_soc_dapm_route.connected callback,
checking RT5640_GBL_CLK to determine if the sys-clk is PLL1 and thus the
PWR_PLL bit in reg PWR_ANLG2 must be set.

RT5640_GBL_CLK is changed by rt5640_set_dai_sysclk(), which gets called by
the pre_pmu / post_pmd functions of the "Platform Clock" dapm-supply.

This creates an ordering issue, during a dapm transition first all
connected() callbacks are called to build a list of supplies to enable
and then the complete list is walked to enable the supplies. Since the
connected() check happens before enabling any supplies,
is_sys_clk_from_pll() ends up deciding if the PWR_PLL bit should be set
based on the state the "Platform Clock" supply had *before* the transition.
This sometimes results in PWR_PLL being off, even though *after* the
transition PLL1 is configured as sys-clk.

This commit removes is_sys_clk_from_pll() instead simply setting / clearing
PWR_PLL in rt5640_set_dai_sysclk() based on the selected sys-clk, which
fixes this and as a bonus results in a nice cleanup.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/codecs/rt5640.c | 29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 05567426f211..140bad07429e 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -476,20 +476,6 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
 	return idx;
 }
 
-static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
-			 struct snd_soc_dapm_widget *sink)
-{
-	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
-	unsigned int val;
-
-	val = snd_soc_component_read32(component, RT5640_GLB_CLK);
-	val &= RT5640_SCLK_SRC_MASK;
-	if (val == RT5640_SCLK_SRC_PLL1)
-		return 1;
-	else
-		return 0;
-}
-
 static int is_using_asrc(struct snd_soc_dapm_widget *source,
 			 struct snd_soc_dapm_widget *sink)
 {
@@ -1071,9 +1057,6 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
 }
 
 static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
-	SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
-			RT5640_PWR_PLL_BIT, 0, NULL, 0),
-
 	/* ASRC */
 	SND_SOC_DAPM_SUPPLY_S("Stereo Filter ASRC", 1, RT5640_ASRC_1,
 			 15, 0, NULL, 0),
@@ -1427,22 +1410,18 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
 	{"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"},
 	{"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"},
 	{"Stereo ADC MIXL", NULL, "Stereo Filter"},
-	{"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
 
 	{"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"},
 	{"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"},
 	{"Stereo ADC MIXR", NULL, "Stereo Filter"},
-	{"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll},
 
 	{"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"},
 	{"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"},
 	{"Mono ADC MIXL", NULL, "Mono Left Filter"},
-	{"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll},
 
 	{"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"},
 	{"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"},
 	{"Mono ADC MIXR", NULL, "Mono Right Filter"},
-	{"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll},
 
 	{"IF2 ADC L", NULL, "Mono ADC MIXL"},
 	{"IF2 ADC R", NULL, "Mono ADC MIXR"},
@@ -1512,10 +1491,8 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
 	{"DIG MIXR", "DAC R1 Switch", "DAC MIXR"},
 
 	{"DAC L1", NULL, "Stereo DAC MIXL"},
-	{"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
 	{"DAC L1", NULL, "DAC L1 Power"},
 	{"DAC R1", NULL, "Stereo DAC MIXR"},
-	{"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
 	{"DAC R1", NULL, "DAC R1 Power"},
 
 	{"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
@@ -1622,10 +1599,8 @@ static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = {
 	{"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"},
 
 	{"DAC L2", NULL, "Mono DAC MIXL"},
-	{"DAC L2", NULL, "PLL1", is_sys_clk_from_pll},
 	{"DAC L2", NULL, "DAC L2 Power"},
 	{"DAC R2", NULL, "Mono DAC MIXR"},
-	{"DAC R2", NULL, "PLL1", is_sys_clk_from_pll},
 	{"DAC R2", NULL, "DAC R2 Power"},
 
 	{"SPK MIXL", "DAC L2 Switch", "DAC L2"},
@@ -1861,6 +1836,7 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 	struct snd_soc_component *component = dai->component;
 	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 	unsigned int reg_val = 0;
+	unsigned int pll_bit = 0;
 
 	if (freq == rt5640->sysclk && clk_id == rt5640->sysclk_src)
 		return 0;
@@ -1871,6 +1847,7 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 		break;
 	case RT5640_SCLK_S_PLL1:
 		reg_val |= RT5640_SCLK_SRC_PLL1;
+		pll_bit |= RT5640_PWR_PLL;
 		break;
 	case RT5640_SCLK_S_RCCLK:
 		reg_val |= RT5640_SCLK_SRC_RCCLK;
@@ -1879,6 +1856,8 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
 		dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
 		return -EINVAL;
 	}
+	snd_soc_component_update_bits(component, RT5640_PWR_ANLG2,
+		RT5640_PWR_PLL, pll_bit);
 	snd_soc_component_update_bits(component, RT5640_GLB_CLK,
 		RT5640_SCLK_SRC_MASK, reg_val);
 	rt5640->sysclk = freq;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 02/19] ASoC: rt5640: Add devicetree-bindings for dmic, jack-detect
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
  2018-05-08 15:35 ` [PATCH 01/19] ASoC: rt5640: Remove is_sys_clk_from_pll, it has ordering issues Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-08 15:35 ` [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data Hans de Goede
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Add devicetree-bindings for the dmic, jack-detect source and overcurrent-
detect threshold settings.

The dmic bindings mirror the existing bindings for the rt5645.
The jd-src and ovcd bindings mirror the existing bindings for the rt5651.

Cc devicetree@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../devicetree/bindings/sound/rt5640.txt      | 35 +++++++++++++++++++
 include/dt-bindings/sound/rt5640.h            | 25 +++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 include/dt-bindings/sound/rt5640.h

diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt
index 57fe64643050..e40e4893eed8 100644
--- a/Documentation/devicetree/bindings/sound/rt5640.txt
+++ b/Documentation/devicetree/bindings/sound/rt5640.txt
@@ -22,6 +22,41 @@ Optional properties:
 
 - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
 
+- realtek,dmic1-data-pin
+  0: dmic1 is not used
+  1: using IN1P pin as dmic1 data pin
+  2: using GPIO3 pin as dmic1 data pin
+
+- realtek,dmic2-data-pin
+  0: dmic2 is not used
+  1: using IN1N pin as dmic2 data pin
+  2: using GPIO4 pin as dmic2 data pin
+
+- realtek,jack-detect-source
+  u32. Valid values:
+  0: jack-detect is not used
+  1: Use GPIO1 for jack-detect
+  2: Use JD1_IN4P for jack-detect
+  3: Use JD2_IN4N for jack-detect
+  4: Use GPIO2 for jack-detect
+  5: Use GPIO3 for jack-detect
+  6: Use GPIO4 for jack-detect
+
+- realtek,jack-detect-not-inverted
+  bool. Normal jack-detect switches give an inverted signal, set this bool
+  in the rare case you've a jack-detect switch which is not inverted.
+
+- realtek,over-current-threshold-microamp
+  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 RT5639/RT5640:
 
   * DMIC1
diff --git a/include/dt-bindings/sound/rt5640.h b/include/dt-bindings/sound/rt5640.h
new file mode 100644
index 000000000000..154c9b4414f2
--- /dev/null
+++ b/include/dt-bindings/sound/rt5640.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_RT5640_H
+#define __DT_RT5640_H
+
+#define RT5640_DMIC1_DATA_PIN_NONE	0
+#define RT5640_DMIC1_DATA_PIN_IN1P	1
+#define RT5640_DMIC1_DATA_PIN_GPIO3	2
+
+#define RT5640_DMIC2_DATA_PIN_NONE	0
+#define RT5640_DMIC2_DATA_PIN_IN1N	1
+#define RT5640_DMIC2_DATA_PIN_GPIO4	2
+
+#define RT5640_JD_SRC_GPIO1		1
+#define RT5640_JD_SRC_JD1_IN4P		2
+#define RT5640_JD_SRC_JD2_IN4N		3
+#define RT5640_JD_SRC_GPIO2		4
+#define RT5640_JD_SRC_GPIO3		5
+#define RT5640_JD_SRC_GPIO4		6
+
+#define RT5640_OVCD_SF_0P5		0
+#define RT5640_OVCD_SF_0P75		1
+#define RT5640_OVCD_SF_1P0		2
+#define RT5640_OVCD_SF_1P5		3
+
+#endif /* __DT_RT5640_H */
-- 
2.17.0

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
  2018-05-08 15:35 ` [PATCH 01/19] ASoC: rt5640: Remove is_sys_clk_from_pll, it has ordering issues Hans de Goede
  2018-05-08 15:35 ` [PATCH 02/19] ASoC: rt5640: Add devicetree-bindings for dmic, jack-detect Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:16   ` Mark Brown
  2018-05-11  2:52   ` Applied "ASoC: rt5640: Remove unused rt5640_platform_data" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 04/19] ASoC: rt5640: Move checking of device-properties to component probe callback Hans de Goede
                   ` (16 subsequent siblings)
  19 siblings, 2 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

There are no in tree users of platform-data for the rt5640 codec driver,
so lets remove support for it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/sound/rt5640.h    | 27 --------------------
 sound/soc/codecs/rt5640.c | 53 ++++++++++++---------------------------
 sound/soc/codecs/rt5640.h |  3 +--
 3 files changed, 17 insertions(+), 66 deletions(-)
 delete mode 100644 include/sound/rt5640.h

diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
deleted file mode 100644
index e3c84b92ff70..000000000000
--- a/include/sound/rt5640.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/sound/rt5640.h -- Platform data for RT5640
- *
- * Copyright 2011 Realtek Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_RT5640_H
-#define __LINUX_SND_RT5640_H
-
-struct rt5640_platform_data {
-	/* IN1 & IN2 & IN3 can optionally be differential */
-	bool in1_diff;
-	bool in2_diff;
-	bool in3_diff;
-
-	bool dmic_en;
-	bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
-	bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
-
-	int ldo1_en; /* GPIO for LDO1_EN */
-};
-
-#endif
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 140bad07429e..616f0a69b850 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2138,10 +2138,6 @@ static int rt5640_probe(struct snd_soc_component *component)
 		return -ENODEV;
 	}
 
-	if (rt5640->pdata.dmic_en)
-		rt5640_dmic_enable(component, rt5640->pdata.dmic1_data_pin,
-					  rt5640->pdata.dmic2_data_pin);
-
 	return 0;
 }
 
@@ -2159,8 +2155,8 @@ static int rt5640_suspend(struct snd_soc_component *component)
 	rt5640_reset(component);
 	regcache_cache_only(rt5640->regmap, true);
 	regcache_mark_dirty(rt5640->regmap);
-	if (gpio_is_valid(rt5640->pdata.ldo1_en))
-		gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 0);
+	if (gpio_is_valid(rt5640->ldo1_en))
+		gpio_set_value_cansleep(rt5640->ldo1_en, 0);
 
 	return 0;
 }
@@ -2169,8 +2165,8 @@ static int rt5640_resume(struct snd_soc_component *component)
 {
 	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
-	if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
-		gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 1);
+	if (gpio_is_valid(rt5640->ldo1_en)) {
+		gpio_set_value_cansleep(rt5640->ldo1_en, 1);
 		msleep(400);
 	}
 
@@ -2302,22 +2298,16 @@ MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
 
 static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
 {
-	rt5640->pdata.in1_diff = of_property_read_bool(np,
-					"realtek,in1-differential");
-	rt5640->pdata.in2_diff = of_property_read_bool(np,
-					"realtek,in2-differential");
-
-	rt5640->pdata.ldo1_en = of_get_named_gpio(np,
-					"realtek,ldo1-en-gpios", 0);
+	rt5640->ldo1_en = of_get_named_gpio(np, "realtek,ldo1-en-gpios", 0);
 	/*
 	 * LDO1_EN is optional (it may be statically tied on the board).
 	 * -ENOENT means that the property doesn't exist, i.e. there is no
 	 * GPIO, so is not an error. Any other error code means the property
 	 * exists, but could not be parsed.
 	 */
-	if (!gpio_is_valid(rt5640->pdata.ldo1_en) &&
-			(rt5640->pdata.ldo1_en != -ENOENT))
-		return rt5640->pdata.ldo1_en;
+	if (!gpio_is_valid(rt5640->ldo1_en) &&
+			(rt5640->ldo1_en != -ENOENT))
+		return rt5640->ldo1_en;
 
 	return 0;
 }
@@ -2325,7 +2315,6 @@ static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
 static int rt5640_i2c_probe(struct i2c_client *i2c,
 		    const struct i2c_device_id *id)
 {
-	struct rt5640_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct rt5640_priv *rt5640;
 	int ret;
 	unsigned int val;
@@ -2337,22 +2326,12 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 	i2c_set_clientdata(i2c, rt5640);
 
-	if (pdata) {
-		rt5640->pdata = *pdata;
-		/*
-		 * Translate zero'd out (default) pdata value to an invalid
-		 * GPIO ID. This makes the pdata and DT paths consistent in
-		 * terms of the value left in this field when no GPIO is
-		 * specified, but means we can't actually use GPIO 0.
-		 */
-		if (!rt5640->pdata.ldo1_en)
-			rt5640->pdata.ldo1_en = -EINVAL;
-	} else if (i2c->dev.of_node) {
+	if (i2c->dev.of_node) {
 		ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
 		if (ret)
 			return ret;
 	} else
-		rt5640->pdata.ldo1_en = -EINVAL;
+		rt5640->ldo1_en = -EINVAL;
 
 	rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
 	if (IS_ERR(rt5640->regmap)) {
@@ -2362,13 +2341,13 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
-		ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en,
+	if (gpio_is_valid(rt5640->ldo1_en)) {
+		ret = devm_gpio_request_one(&i2c->dev, rt5640->ldo1_en,
 					    GPIOF_OUT_INIT_HIGH,
 					    "RT5640 LDO1_EN");
 		if (ret < 0) {
 			dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n",
-				rt5640->pdata.ldo1_en, ret);
+				rt5640->ldo1_en, ret);
 			return ret;
 		}
 		msleep(400);
@@ -2391,15 +2370,15 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 	regmap_update_bits(rt5640->regmap, RT5640_DUMMY1,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
-	if (rt5640->pdata.in1_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in1-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
 					RT5640_IN_DF1, RT5640_IN_DF1);
 
-	if (rt5640->pdata.in2_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in2-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
 					RT5640_IN_DF2, RT5640_IN_DF2);
 
-	if (rt5640->pdata.in3_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in3-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
 					RT5640_IN_DF2, RT5640_IN_DF2);
 
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c473e8ae2eda..2db6586f5ab4 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -13,7 +13,6 @@
 #define _RT5640_H
 
 #include <linux/clk.h>
-#include <sound/rt5640.h>
 
 /* Info */
 #define RT5640_RESET				0x00
@@ -2103,10 +2102,10 @@ enum {
 
 struct rt5640_priv {
 	struct snd_soc_component *component;
-	struct rt5640_platform_data pdata;
 	struct regmap *regmap;
 	struct clk *mclk;
 
+	int ldo1_en; /* GPIO for LDO1_EN */
 	int sysclk;
 	int sysclk_src;
 	int lrck[RT5640_AIFS];
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 04/19] ASoC: rt5640: Move checking of device-properties to component probe callback
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (2 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:51   ` Applied "ASoC: rt5640: Move checking of device-properties to component probe callback" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 05/19] ASoC: rt5640: Allow specifying dmic data pins through device-properties Hans de Goede
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

On some platforms the platform code may need to add device-properties,
rather then relying only on properties set by the firmware.

This commit moves the parsing of the device-properties from the i2c-driver
probe() function, which may be called at any time, to the component-driver
probe() function, which gets called after the platform code calls
snd_soc_register_card().

This allows the platform code to attach extra device-properties before
the device-properties are parsed.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/codecs/rt5640.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 616f0a69b850..265a0786851d 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2138,6 +2138,25 @@ static int rt5640_probe(struct snd_soc_component *component)
 		return -ENODEV;
 	}
 
+	/*
+	 * Note on some platforms the platform code may need to add device-props
+	 * rather then relying only on properties set by the firmware.
+	 * Therefor the property parsing MUST be done here, rather then from
+	 * rt5640_i2c_probe(), so that the platform-code can attach extra
+	 * properties before calling snd_soc_register_card().
+	 */
+	if (device_property_read_bool(component->dev, "realtek,in1-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
+					      RT5640_IN_DF1, RT5640_IN_DF1);
+
+	if (device_property_read_bool(component->dev, "realtek,in2-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN3_IN4,
+					      RT5640_IN_DF2, RT5640_IN_DF2);
+
+	if (device_property_read_bool(component->dev, "realtek,in3-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
+					      RT5640_IN_DF2, RT5640_IN_DF2);
+
 	return 0;
 }
 
@@ -2370,18 +2389,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 	regmap_update_bits(rt5640->regmap, RT5640_DUMMY1,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
-	if (device_property_read_bool(&i2c->dev, "realtek,in1-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
-					RT5640_IN_DF1, RT5640_IN_DF1);
-
-	if (device_property_read_bool(&i2c->dev, "realtek,in2-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
-					RT5640_IN_DF2, RT5640_IN_DF2);
-
-	if (device_property_read_bool(&i2c->dev, "realtek,in3-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
-					RT5640_IN_DF2, RT5640_IN_DF2);
-
 	rt5640->hp_mute = 1;
 
 	return devm_snd_soc_register_component(&i2c->dev,
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 05/19] ASoC: rt5640: Allow specifying dmic data pins through device-properties
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (3 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 04/19] ASoC: rt5640: Move checking of device-properties to component probe callback Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:51   ` Applied "ASoC: rt5640: Allow specifying dmic data pins through device-properties" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 06/19] ASoC: rt5640: Add jack-detect support Hans de Goede
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Allow specifying dmic data pins through device-properties / dt. This will
allow us to stop exporting rt5640_dmic_enable() once all callers of it have
been converted to setting device-properties for this instead.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/codecs/rt5640.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 265a0786851d..d7c7b207f3cc 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2097,6 +2097,10 @@ static int rt5640_probe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+	u32 dmic1_data_pin = 0;
+	u32 dmic2_data_pin = 0;
+	bool dmic_en = false;
+	u32 val;
 
 	/* Check if MCLK provided */
 	rt5640->mclk = devm_clk_get(component->dev, "mclk");
@@ -2157,6 +2161,21 @@ static int rt5640_probe(struct snd_soc_component *component)
 		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
 					      RT5640_IN_DF2, RT5640_IN_DF2);
 
+	if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin",
+				     &val) == 0 && val) {
+		dmic1_data_pin = val - 1;
+		dmic_en = true;
+	}
+
+	if (device_property_read_u32(component->dev, "realtek,dmic2-data-pin",
+				     &val) == 0 && val) {
+		dmic2_data_pin = val - 1;
+		dmic_en = true;
+	}
+
+	if (dmic_en)
+		rt5640_dmic_enable(component, dmic1_data_pin, dmic2_data_pin);
+
 	return 0;
 }
 
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 06/19] ASoC: rt5640: Add jack-detect support
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (4 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 05/19] ASoC: rt5640: Allow specifying dmic data pins through device-properties Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:50   ` Applied "ASoC: rt5640: Add jack-detect support" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 07/19] ASoC: rt5640: Add button press support Hans de Goede
                   ` (13 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Add jack-detect support, loosely based on earlier work on this by:

Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Francisco mendez <francisco.mendez@intel.com>

Note getting the OVCD to work reliable was sort of finicky, so there are
quite a few comments on this to hopefully avoid people breaking it in the
future.

This (and the follow-up button press support) has been tested on the
following devices:

Acer Iconia Tab 8 W1-810
Asus T100CHI
Asus T100TA
Asus T200TA
Axxo WT1011
Chuwi Vi8
Dell Venue 8 Pro 5830
HP Pavilion X2 10-n000nd
HP Stream 7
I.T. Works TW891
Lamina I8270
MSI S100
Peaq C1010
Pipo W4
PoV MobiiTAB-P800W (v2.0)
Toshiba Click Mini L9W-B

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=196377
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/codecs/rt5640.c | 286 ++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rt5640.h |  36 ++++-
 2 files changed, 318 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index d7c7b207f3cc..8e306f509601 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -24,6 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/acpi.h>
 #include <sound/core.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -2093,6 +2094,224 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
 }
 EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
 
+static void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS1");
+	/* OVCD is unreliable when used with RCCLK as sysclk-source */
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS1");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "LDO2");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5640_clear_micbias1_ovcd(struct snd_soc_component *component)
+{
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_MB1_OC_STATUS, 0);
+}
+
+static bool rt5640_micbias1_ovcd(struct snd_soc_component *component)
+{
+	int val;
+
+	val = snd_soc_component_read32(component, RT5640_IRQ_CTRL2);
+	dev_dbg(component->dev, "irq ctrl2 %#04x\n", val);
+
+	return (val & RT5640_MB1_OC_STATUS);
+}
+
+static bool rt5640_jack_inserted(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+	int val;
+
+	val = snd_soc_component_read32(component, RT5640_INT_IRQ_ST);
+	dev_dbg(component->dev, "irq status %#04x\n", val);
+
+	if (rt5640->jd_inverted)
+		return !(val & RT5640_JD_STATUS);
+	else
+		return (val & RT5640_JD_STATUS);
+}
+
+/* Jack detect timings */
+#define JACK_SETTLE_TIME	100 /* milli seconds */
+#define JACK_DETECT_COUNT	5
+#define JACK_DETECT_MAXCOUNT	20  /* Aprox. 2 seconds worth of tries */
+
+static int rt5640_detect_headset(struct snd_soc_component *component)
+{
+	int i, headset_count = 0, headphone_count = 0;
+
+	/*
+	 * We get the insertion event before the jack is fully inserted at which
+	 * point the second ring on a TRRS connector may short the 2nd ring and
+	 * sleeve contacts, also the overcurrent detection is not entirely
+	 * reliable. So we try several times with a wait in between until we
+	 * detect the same type JACK_DETECT_COUNT times in a row.
+	 */
+	for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) {
+		/* Clear any previous over-current status flag */
+		rt5640_clear_micbias1_ovcd(component);
+
+		msleep(JACK_SETTLE_TIME);
+
+		/* Check the jack is still connected before checking ovcd */
+		if (!rt5640_jack_inserted(component))
+			return 0;
+
+		if (rt5640_micbias1_ovcd(component)) {
+			/*
+			 * Over current detected, there is a short between the
+			 * 2nd ring contact and the ground, so a TRS connector
+			 * without a mic contact and thus plain headphones.
+			 */
+			dev_dbg(component->dev, "jack mic-gnd shorted\n");
+			headset_count = 0;
+			headphone_count++;
+			if (headphone_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADPHONE;
+		} else {
+			dev_dbg(component->dev, "jack mic-gnd open\n");
+			headphone_count = 0;
+			headset_count++;
+			if (headset_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADSET;
+		}
+	}
+
+	dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
+	return SND_JACK_HEADPHONE;
+}
+
+static void rt5640_jack_work(struct work_struct *work)
+{
+	struct rt5640_priv *rt5640 =
+		container_of(work, struct rt5640_priv, jack_work);
+	struct snd_soc_component *component = rt5640->component;
+	int status;
+
+	if (!rt5640_jack_inserted(component)) {
+		/* Jack removed, or spurious IRQ? */
+		if (rt5640->jack->status & SND_JACK_HEADPHONE) {
+			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_HEADSET);
+			dev_dbg(component->dev, "jack unplugged\n");
+		}
+	} else if (!(rt5640->jack->status & SND_JACK_HEADPHONE)) {
+		/* Jack inserted */
+		rt5640_enable_micbias1_for_ovcd(component);
+		status = rt5640_detect_headset(component);
+		rt5640_disable_micbias1_for_ovcd(component);
+
+		dev_dbg(component->dev, "detect status %#02x\n", status);
+		snd_soc_jack_report(rt5640->jack, status, SND_JACK_HEADSET);
+	}
+}
+
+static irqreturn_t rt5640_irq(int irq, void *data)
+{
+	struct rt5640_priv *rt5640 = data;
+
+	if (rt5640->jack)
+		queue_work(system_long_wq, &rt5640->jack_work);
+
+	return IRQ_HANDLED;
+}
+
+static void rt5640_cancel_work(void *data)
+{
+	struct rt5640_priv *rt5640 = data;
+
+	cancel_work_sync(&rt5640->jack_work);
+}
+
+static void rt5640_enable_jack_detect(struct snd_soc_component *component,
+				      struct snd_soc_jack *jack)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	/* Select JD-source */
+	snd_soc_component_update_bits(component, RT5640_JD_CTRL,
+		RT5640_JD_MASK, rt5640->jd_src);
+
+	/* Selecting GPIO01 as an interrupt */
+	snd_soc_component_update_bits(component, RT5640_GPIO_CTRL1,
+		RT5640_GP1_PIN_MASK, RT5640_GP1_PIN_IRQ);
+
+	/* Set GPIO1 output */
+	snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3,
+		RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT);
+
+	/* Enabling jd2 in general control 1 */
+	snd_soc_component_write(component, RT5640_DUMMY1, 0x3f41);
+
+	/* Enabling jd2 in general control 2 */
+	snd_soc_component_write(component, RT5640_DUMMY2, 0x4001);
+
+	snd_soc_component_write(component, RT5640_PR_BASE + RT5640_BIAS_CUR4,
+		0xa800 | rt5640->ovcd_sf);
+
+	snd_soc_component_update_bits(component, RT5640_MICBIAS,
+		RT5640_MIC1_OVTH_MASK | RT5640_MIC1_OVCD_MASK,
+		rt5640->ovcd_th | RT5640_MIC1_OVCD_EN);
+
+	/*
+	 * The over-current-detect is only reliable in detecting the absence
+	 * of over-current, when the mic-contact in the jack is short-circuited,
+	 * the hardware periodically retries if it can apply the bias-current
+	 * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
+	 * 10% of the time, as we poll the ovcd status bit we might hit that
+	 * 10%, so we enable sticky mode and when checking OVCD we clear the
+	 * status, msleep() a bit and then check to get a reliable reading.
+	 */
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
+
+	snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+				RT5640_IRQ_JD_NOR);
+
+	rt5640->jack = jack;
+	enable_irq(rt5640->irq);
+	/* sync initial jack state */
+	queue_work(system_long_wq, &rt5640->jack_work);
+}
+
+static void rt5640_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	disable_irq(rt5640->irq);
+	rt5640_cancel_work(rt5640);
+
+	rt5640->jack = NULL;
+}
+
+static int rt5640_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *jack, void *data)
+{
+	if (jack)
+		rt5640_enable_jack_detect(component, jack);
+	else
+		rt5640_disable_jack_detect(component);
+
+	return 0;
+}
+
 static int rt5640_probe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
@@ -2176,6 +2395,53 @@ static int rt5640_probe(struct snd_soc_component *component)
 	if (dmic_en)
 		rt5640_dmic_enable(component, dmic1_data_pin, dmic2_data_pin);
 
+	if (device_property_read_u32(component->dev,
+				     "realtek,jack-detect-source", &val) == 0) {
+		if (val <= RT5640_JD_SRC_GPIO4)
+			rt5640->jd_src = val << RT5640_JD_SFT;
+		else
+			dev_warn(component->dev, "Warning: Invalid jack-detect-source value: %d, leaving jack-detect disabled\n",
+				 val);
+	}
+
+	if (!device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted"))
+		rt5640->jd_inverted = true;
+
+	/*
+	 * 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.
+	 */
+	rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
+	rt5640->ovcd_sf = RT5640_MIC_OVCD_SF_0P75;
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-threshold-microamp", &val) == 0) {
+		switch (val) {
+		case 600:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_600UA;
+			break;
+		case 1500:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_1500UA;
+			break;
+		case 2000:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
+			break;
+		default:
+			dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n",
+				 val);
+		}
+	}
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-scale-factor", &val) == 0) {
+		if (val <= RT5640_OVCD_SF_1P5)
+			rt5640->ovcd_sf = val << RT5640_MIC_OVCD_SF_SFT;
+		else
+			dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n",
+				 val);
+	}
+
 	return 0;
 }
 
@@ -2276,6 +2542,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt5640 = {
 	.suspend		= rt5640_suspend,
 	.resume			= rt5640_resume,
 	.set_bias_level		= rt5640_set_bias_level,
+	.set_jack		= rt5640_set_jack,
 	.controls		= rt5640_snd_controls,
 	.num_controls		= ARRAY_SIZE(rt5640_snd_controls),
 	.dapm_widgets		= rt5640_dapm_widgets,
@@ -2409,6 +2676,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
 	rt5640->hp_mute = 1;
+	rt5640->irq = i2c->irq;
+	INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
+
+	/* Make sure work is stopped on probe-error / remove */
+	ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
+	if (ret)
+		return ret;
+
+	ret = devm_request_irq(&i2c->dev, rt5640->irq, rt5640_irq,
+			       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
+			       | IRQF_ONESHOT, "rt5640", rt5640);
+	if (ret == 0) {
+		/* Gets re-enabled by rt5640_set_jack() */
+		disable_irq(rt5640->irq);
+	} else {
+		dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n",
+			 rt5640->irq, ret);
+		rt5640->irq = -ENXIO;
+	}
 
 	return devm_snd_soc_register_component(&i2c->dev,
 				      &soc_component_dev_rt5640,
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 2db6586f5ab4..9d08471734b3 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -13,6 +13,8 @@
 #define _RT5640_H
 
 #include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <dt-bindings/sound/rt5640.h>
 
 /* Info */
 #define RT5640_RESET				0x00
@@ -145,6 +147,7 @@
 
 
 /* Index of Codec Private Register definition */
+#define RT5640_BIAS_CUR4			0x15
 #define RT5640_CHPUMP_INT_REG1			0x24
 #define RT5640_MAMP_INT_REG2			0x37
 #define RT5640_3D_SPK				0x63
@@ -1606,10 +1609,17 @@
 #define RT5640_MB2_OC_P_SFT			6
 #define RT5640_MB2_OC_P_NOR			(0x0 << 6)
 #define RT5640_MB2_OC_P_INV			(0x1 << 6)
-#define RT5640_MB1_OC_CLR			(0x1 << 3)
-#define RT5640_MB1_OC_CLR_SFT			3
-#define RT5640_MB2_OC_CLR			(0x1 << 2)
-#define RT5640_MB2_OC_CLR_SFT			2
+#define RT5640_MB1_OC_STATUS			(0x1 << 3)
+#define RT5640_MB1_OC_STATUS_SFT		3
+#define RT5640_MB2_OC_STATUS			(0x1 << 2)
+#define RT5640_MB2_OC_STATUS_SFT		2
+
+/* GPIO and Internal Status (0xbf) */
+#define RT5640_GPIO1_STATUS			(0x1 << 8)
+#define RT5640_GPIO2_STATUS			(0x1 << 7)
+#define RT5640_JD_STATUS			(0x1 << 4)
+#define RT5640_OVT_STATUS			(0x1 << 3)
+#define RT5640_CLS_D_OVCD_STATUS		(0x1 << 0)
 
 /* GPIO Control 1 (0xc0) */
 #define RT5640_GP1_PIN_MASK			(0x1 << 15)
@@ -1977,6 +1987,15 @@
 #define RT5640_MCLK_DET				(0x1 << 11)
 
 /* Codec Private Register definition */
+
+/* MIC Over current threshold scale factor (0x15) */
+#define RT5640_MIC_OVCD_SF_MASK			(0x3 << 8)
+#define RT5640_MIC_OVCD_SF_SFT			8
+#define RT5640_MIC_OVCD_SF_0P5			(0x0 << 8)
+#define RT5640_MIC_OVCD_SF_0P75			(0x1 << 8)
+#define RT5640_MIC_OVCD_SF_1P0			(0x2 << 8)
+#define RT5640_MIC_OVCD_SF_1P5			(0x3 << 8)
+
 /* 3D Speaker Control (0x63) */
 #define RT5640_3D_SPK_MASK			(0x1 << 15)
 #define RT5640_3D_SPK_SFT			15
@@ -2106,6 +2125,7 @@ struct rt5640_priv {
 	struct clk *mclk;
 
 	int ldo1_en; /* GPIO for LDO1_EN */
+	int irq;
 	int sysclk;
 	int sysclk_src;
 	int lrck[RT5640_AIFS];
@@ -2118,6 +2138,14 @@ struct rt5640_priv {
 
 	bool hp_mute;
 	bool asrc_en;
+
+	/* Jack detect data */
+	struct work_struct jack_work;
+	struct snd_soc_jack *jack;
+	unsigned int jd_src;
+	bool jd_inverted;
+	unsigned int ovcd_th;
+	unsigned int ovcd_sf;
 };
 
 int rt5640_dmic_enable(struct snd_soc_component *component,
-- 
2.17.0

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 07/19] ASoC: rt5640: Add button press support
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (5 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 06/19] ASoC: rt5640: Add jack-detect support Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:50   ` Applied "ASoC: rt5640: Add button press support" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 08/19] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it Hans de Goede
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Enable button press detection for headsets by using the ovcd IRQ to get
notified of button presses.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/codecs/rt5640.c | 157 ++++++++++++++++++++++++++++++++++++--
 sound/soc/codecs/rt5640.h |   9 ++-
 2 files changed, 159 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 8e306f509601..8bf8d360c25f 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2119,6 +2119,24 @@ static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component
 	snd_soc_dapm_mutex_unlock(dapm);
 }
 
+static void rt5640_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_NOR);
+	rt5640->ovcd_irq_enabled = true;
+}
+
+static void rt5640_disable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_BP);
+	rt5640->ovcd_irq_enabled = false;
+}
+
 static void rt5640_clear_micbias1_ovcd(struct snd_soc_component *component)
 {
 	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
@@ -2149,10 +2167,80 @@ static bool rt5640_jack_inserted(struct snd_soc_component *component)
 		return (val & RT5640_JD_STATUS);
 }
 
-/* Jack detect timings */
+/* Jack detect and button-press timings */
 #define JACK_SETTLE_TIME	100 /* milli seconds */
 #define JACK_DETECT_COUNT	5
 #define JACK_DETECT_MAXCOUNT	20  /* Aprox. 2 seconds worth of tries */
+#define JACK_UNPLUG_TIME	80  /* milli seconds */
+#define BP_POLL_TIME		10  /* milli seconds */
+#define BP_POLL_MAXCOUNT	200 /* assume something is wrong after this */
+#define BP_THRESHOLD		3
+
+static void rt5640_start_button_press_work(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	rt5640->poll_count = 0;
+	rt5640->press_count = 0;
+	rt5640->release_count = 0;
+	rt5640->pressed = false;
+	rt5640->press_reported = false;
+	rt5640_clear_micbias1_ovcd(component);
+	schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
+
+static void rt5640_button_press_work(struct work_struct *work)
+{
+	struct rt5640_priv *rt5640 =
+		container_of(work, struct rt5640_priv, bp_work.work);
+	struct snd_soc_component *component = rt5640->component;
+
+	/* Check the jack was not removed underneath us */
+	if (!rt5640_jack_inserted(component))
+		return;
+
+	if (rt5640_micbias1_ovcd(component)) {
+		rt5640->release_count = 0;
+		rt5640->press_count++;
+		/* Remember till after JACK_UNPLUG_TIME wait */
+		if (rt5640->press_count >= BP_THRESHOLD)
+			rt5640->pressed = true;
+		rt5640_clear_micbias1_ovcd(component);
+	} else {
+		rt5640->press_count = 0;
+		rt5640->release_count++;
+	}
+
+	/*
+	 * The pins get temporarily shorted on jack unplug, so we poll for
+	 * at least JACK_UNPLUG_TIME milli-seconds before reporting a press.
+	 */
+	rt5640->poll_count++;
+	if (rt5640->poll_count < (JACK_UNPLUG_TIME / BP_POLL_TIME)) {
+		schedule_delayed_work(&rt5640->bp_work,
+				      msecs_to_jiffies(BP_POLL_TIME));
+		return;
+	}
+
+	if (rt5640->pressed && !rt5640->press_reported) {
+		dev_dbg(component->dev, "headset button press\n");
+		snd_soc_jack_report(rt5640->jack, SND_JACK_BTN_0,
+				    SND_JACK_BTN_0);
+		rt5640->press_reported = true;
+	}
+
+	if (rt5640->release_count >= BP_THRESHOLD) {
+		if (rt5640->press_reported) {
+			dev_dbg(component->dev, "headset button release\n");
+			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+		}
+		/* Re-enable OVCD IRQ to detect next press */
+		rt5640_enable_micbias1_ovcd_irq(component);
+		return; /* Stop polling */
+	}
+
+	schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
 
 static int rt5640_detect_headset(struct snd_soc_component *component)
 {
@@ -2209,17 +2297,51 @@ static void rt5640_jack_work(struct work_struct *work)
 	if (!rt5640_jack_inserted(component)) {
 		/* Jack removed, or spurious IRQ? */
 		if (rt5640->jack->status & SND_JACK_HEADPHONE) {
-			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_HEADSET);
+			if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+				cancel_delayed_work_sync(&rt5640->bp_work);
+				rt5640_disable_micbias1_ovcd_irq(component);
+				rt5640_disable_micbias1_for_ovcd(component);
+			}
+			snd_soc_jack_report(rt5640->jack, 0,
+					    SND_JACK_HEADSET | SND_JACK_BTN_0);
 			dev_dbg(component->dev, "jack unplugged\n");
 		}
 	} else if (!(rt5640->jack->status & SND_JACK_HEADPHONE)) {
 		/* Jack inserted */
+		WARN_ON(rt5640->ovcd_irq_enabled);
 		rt5640_enable_micbias1_for_ovcd(component);
 		status = rt5640_detect_headset(component);
-		rt5640_disable_micbias1_for_ovcd(component);
-
+		if (status == SND_JACK_HEADSET) {
+			/* Enable ovcd IRQ for button press detect. */
+			rt5640_enable_micbias1_ovcd_irq(component);
+		} else {
+			/* No more need for overcurrent detect. */
+			rt5640_disable_micbias1_for_ovcd(component);
+		}
 		dev_dbg(component->dev, "detect status %#02x\n", status);
 		snd_soc_jack_report(rt5640->jack, status, SND_JACK_HEADSET);
+	} else if (rt5640->ovcd_irq_enabled && rt5640_micbias1_ovcd(component)) {
+		dev_dbg(component->dev, "OVCD IRQ\n");
+
+		/*
+		 * The ovcd IRQ keeps firing while the button is pressed, so
+		 * we disable it and start polling the button until released.
+		 *
+		 * The disable will make the IRQ pin 0 again and since we get
+		 * IRQs on both edges (so as to detect both jack plugin and
+		 * unplug) this means we will immediately get another IRQ.
+		 * The ovcd_irq_enabled check above makes the 2ND IRQ a NOP.
+		 */
+		rt5640_disable_micbias1_ovcd_irq(component);
+		rt5640_start_button_press_work(component);
+
+		/*
+		 * If the jack-detect IRQ flag goes high (unplug) after our
+		 * above rt5640_jack_inserted() check and before we have
+		 * disabled the OVCD IRQ, the IRQ pin will stay high and as
+		 * we react to edges, we miss the unplug event -> recheck.
+		 */
+		queue_work(system_long_wq, &rt5640->jack_work);
 	}
 }
 
@@ -2238,6 +2360,7 @@ static void rt5640_cancel_work(void *data)
 	struct rt5640_priv *rt5640 = data;
 
 	cancel_work_sync(&rt5640->jack_work);
+	cancel_delayed_work_sync(&rt5640->bp_work);
 }
 
 static void rt5640_enable_jack_detect(struct snd_soc_component *component,
@@ -2282,10 +2405,25 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
 	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
 		RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
 
-	snd_soc_component_write(component, RT5640_IRQ_CTRL1,
-				RT5640_IRQ_JD_NOR);
+	/*
+	 * All IRQs get or-ed together, so we need the jack IRQ to report 0
+	 * when a jack is inserted so that the OVCD IRQ then toggles the IRQ
+	 * pin 0/1 instead of it being stuck to 1. So we invert the JD polarity
+	 * on systems where the hardware does not already do this.
+	 */
+	if (rt5640->jd_inverted)
+		snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+					RT5640_IRQ_JD_NOR);
+	else
+		snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+					RT5640_IRQ_JD_NOR | RT5640_JD_P_INV);
 
 	rt5640->jack = jack;
+	if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+		rt5640_enable_micbias1_for_ovcd(component);
+		rt5640_enable_micbias1_ovcd_irq(component);
+	}
+
 	enable_irq(rt5640->irq);
 	/* sync initial jack state */
 	queue_work(system_long_wq, &rt5640->jack_work);
@@ -2298,6 +2436,12 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
 	disable_irq(rt5640->irq);
 	rt5640_cancel_work(rt5640);
 
+	if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+		rt5640_disable_micbias1_ovcd_irq(component);
+		rt5640_disable_micbias1_for_ovcd(component);
+		snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+	}
+
 	rt5640->jack = NULL;
 }
 
@@ -2677,6 +2821,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 
 	rt5640->hp_mute = 1;
 	rt5640->irq = i2c->irq;
+	INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work);
 	INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
 
 	/* Make sure work is stopped on probe-error / remove */
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 9d08471734b3..e29e3e7d61b0 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -2139,7 +2139,14 @@ struct rt5640_priv {
 	bool hp_mute;
 	bool asrc_en;
 
-	/* Jack detect data */
+	/* Jack and button detect data */
+	bool ovcd_irq_enabled;
+	bool pressed;
+	bool press_reported;
+	int press_count;
+	int release_count;
+	int poll_count;
+	struct delayed_work bp_work;
 	struct work_struct jack_work;
 	struct snd_soc_jack *jack;
 	unsigned int jd_src;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 08/19] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (6 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 07/19] ASoC: rt5640: Add button press support Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:48   ` Applied "ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 09/19] ASoC: Intel: bytcr_rt5640: Use device-property for differential mics Hans de Goede
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

When platform_clock_control() first selects PLL1 as sysclk the PLL_CTRL
registers have not been setup yet and we effectively have an invalid clock
configuration until byt_rt5640_aif1_hw_params() gets called.

Add a new byt_rt5640_prepare_and_enable_pll1() helper and use that from
both platform_clock_control() and byt_rt5640_aif1_hw_params() to fix this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 100 +++++++++++++-------------
 1 file changed, 49 insertions(+), 51 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 84ce98ebd00e..0f587d394b06 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -141,6 +141,52 @@ static void log_quirks(struct device *dev)
 	}
 }
 
+static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
+					      int rate)
+{
+	int ret;
+
+	/* Configure the PLL before selecting it */
+	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
+		/* use bitclock as PLL input */
+		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+		    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+			/* 2x16 bit slots on SSP0 */
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_BCLK1,
+						  rate * 32, rate * 512);
+		} else {
+			/* 2x15 bit slots on SSP2 */
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_BCLK1,
+						  rate * 50, rate * 512);
+		}
+	} else {
+		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_MCLK,
+						  25000000, rate * 512);
+		} else {
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_MCLK,
+						  19200000, rate * 512);
+		}
+	}
+
+	if (ret < 0) {
+		dev_err(codec_dai->codec->dev, "can't set pll: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
+				     rate * 512, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		dev_err(codec_dai->codec->dev, "can't set clock %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
 
 #define BYT_CODEC_DAI1	"rt5640-aif1"
 #define BYT_CODEC_DAI2	"rt5640-aif2"
@@ -173,9 +219,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
 				return ret;
 			}
 		}
-		ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-					     48000 * 512,
-					     SND_SOC_CLOCK_IN);
+		ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
 	} else {
 		/*
 		 * Set codec clock source to internal clock before
@@ -299,55 +343,9 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 					struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-				     params_rate(params) * 512,
-				     SND_SOC_CLOCK_IN);
-
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
-		return ret;
-	}
+	struct snd_soc_dai *dai = rtd->codec_dai;
 
-	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
-		/* use bitclock as PLL input */
-		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
-			(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
-			/* 2x16 bit slots on SSP0 */
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_BCLK1,
-						params_rate(params) * 32,
-						params_rate(params) * 512);
-		} else {
-			/* 2x15 bit slots on SSP2 */
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_BCLK1,
-						params_rate(params) * 50,
-						params_rate(params) * 512);
-		}
-	} else {
-		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_MCLK,
-						25000000,
-						params_rate(params) * 512);
-		} else {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_MCLK,
-						19200000,
-						params_rate(params) * 512);
-		}
-	}
-
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 }
 
 static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 09/19] ASoC: Intel: bytcr_rt5640: Use device-property for differential mics
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (7 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 08/19] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:48   ` Applied "ASoC: Intel: bytcr_rt5640: Use device-property for differential mics" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic Hans de Goede
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Set the "realtek,in1-differential" or "realtek,in3-differential"
device-property when the BYT_RT5640_DIFF_MIC quirk is set instead of
directly poking the codec registers.

This also fixes the BYT_RT5640_DIFF_MIC quirk not working when
combined with BYT_RT5640_IN3_MAP.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 48 ++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 0f587d394b06..81d0d07449a8 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -17,6 +17,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -54,6 +55,9 @@ enum {
 #define BYT_RT5640_MCLK_EN	BIT(22)
 #define BYT_RT5640_MCLK_25MHZ	BIT(23)
 
+/* in-diff + terminating empty entry */
+#define MAX_NO_PROPS 2
+
 struct byt_rt5640_private {
 	struct clk *mclk;
 };
@@ -438,6 +442,39 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{}
 };
 
+/*
+ * Note this MUST be called before snd_soc_register_card(), so that the props
+ * are in place before the codec component driver's probe function parses them.
+ */
+static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
+{
+	struct property_entry props[MAX_NO_PROPS] = {};
+	struct device *i2c_dev;
+	int ret, cnt = 0;
+
+	i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
+	if (!i2c_dev)
+		return -EPROBE_DEFER;
+
+	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
+	case BYT_RT5640_IN1_MAP:
+		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+			props[cnt++] =
+				PROPERTY_ENTRY_BOOL("realtek,in1-differential");
+		break;
+	case BYT_RT5640_IN3_MAP:
+		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+			props[cnt++] =
+				PROPERTY_ENTRY_BOOL("realtek,in3-differential");
+		break;
+	}
+
+	ret = device_add_properties(i2c_dev, props);
+	put_device(i2c_dev);
+
+	return ret;
+}
+
 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
@@ -519,11 +556,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 	if (ret)
 		return ret;
 
-	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
-		snd_soc_component_update_bits(component,  RT5640_IN1_IN2, RT5640_IN_DF1,
-				    RT5640_IN_DF1);
-	}
-
 	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
 		ret = rt5640_dmic_enable(component, 0, 0);
 		if (ret)
@@ -837,6 +869,12 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 			 (unsigned int)byt_rt5640_quirk, quirk_override);
 		byt_rt5640_quirk = quirk_override;
 	}
+
+	/* Must be called before register_card, also see declaration comment. */
+	ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
+	if (ret_val)
+		return ret_val;
+
 	log_quirks(&pdev->dev);
 
 	if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (8 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 09/19] ASoC: Intel: bytcr_rt5640: Use device-property for differential mics Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-11  2:25   ` Mark Brown
  2018-05-08 15:35 ` [PATCH 11/19] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk Hans de Goede
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Use device-properties for setting up the dmic, based on the
BYT_RT5640_MAP() value, instead of using the codec specific
rt5640_dmic_enable() function for this.  This also removes the need
for the BYT_RT5640_DMIC_EN quirk, which was always set together with
a MAP() quirk of DMIC1_MAP or DMIC2_MAP.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 42 +++++++++------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 81d0d07449a8..8b8716575910 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -34,6 +34,7 @@
 #include <sound/soc.h>
 #include <sound/jack.h>
 #include <sound/soc-acpi.h>
+#include <dt-bindings/sound/rt5640.h>
 #include "../../codecs/rt5640.h"
 #include "../atom/sst-atom-controls.h"
 #include "../common/sst-dsp.h"
@@ -46,7 +47,6 @@ enum {
 };
 
 #define BYT_RT5640_MAP(quirk)	((quirk) &  GENMASK(7, 0))
-#define BYT_RT5640_DMIC_EN	BIT(16)
 #define BYT_RT5640_MONO_SPEAKER BIT(17)
 #define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
 #define BYT_RT5640_SSP2_AIF2    BIT(19) /* default is using AIF1  */
@@ -55,7 +55,7 @@ enum {
 #define BYT_RT5640_MCLK_EN	BIT(22)
 #define BYT_RT5640_MCLK_25MHZ	BIT(23)
 
-/* in-diff + terminating empty entry */
+/* in-diff or dmic-pin + terminating empty entry */
 #define MAX_NO_PROPS 2
 
 struct byt_rt5640_private {
@@ -71,7 +71,6 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 static void log_quirks(struct device *dev)
 {
 	int map;
-	bool has_dmic = false;
 	bool has_mclk = false;
 	bool has_ssp0 = false;
 	bool has_ssp0_aif1 = false;
@@ -82,11 +81,9 @@ static void log_quirks(struct device *dev)
 	switch (map) {
 	case BYT_RT5640_DMIC1_MAP:
 		dev_info(dev, "quirk DMIC1_MAP enabled\n");
-		has_dmic = true;
 		break;
 	case BYT_RT5640_DMIC2_MAP:
 		dev_info(dev, "quirk DMIC2_MAP enabled\n");
-		has_dmic = true;
 		break;
 	case BYT_RT5640_IN1_MAP:
 		dev_info(dev, "quirk IN1_MAP enabled\n");
@@ -98,20 +95,10 @@ static void log_quirks(struct device *dev)
 		dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
 		break;
 	}
-	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-		if (has_dmic)
-			dev_info(dev, "quirk DMIC enabled\n");
-		else
-			dev_err(dev, "quirk DMIC enabled but no DMIC input set, will be ignored\n");
-	}
 	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
 		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
-	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
-		if (!has_dmic)
-			dev_info(dev, "quirk DIFF_MIC enabled\n");
-		else
-			dev_info(dev, "quirk DIFF_MIC enabled but DMIC input selected, will be ignored\n");
-	}
+	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+		dev_info(dev, "quirk DIFF_MIC enabled\n");
 	if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
 		dev_info(dev, "quirk SSP0_AIF1 enabled\n");
 		has_ssp0 = true;
@@ -387,7 +374,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 		},
 		.driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
-					BYT_RT5640_DMIC_EN |
 					BYT_RT5640_MCLK_EN),
 	},
 	{
@@ -405,8 +391,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
 		},
-		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
-					BYT_RT5640_DMIC_EN),
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
 	},
 	{
 		.callback = byt_rt5640_quirk_cb,
@@ -457,6 +442,14 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
 		return -EPROBE_DEFER;
 
 	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
+	case BYT_RT5640_DMIC1_MAP:
+		props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
+						  RT5640_DMIC1_DATA_PIN_IN1P);
+		break;
+	case BYT_RT5640_DMIC2_MAP:
+		props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
+						  RT5640_DMIC2_DATA_PIN_IN1N);
+		break;
 	case BYT_RT5640_IN1_MAP:
 		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
 			props[cnt++] =
@@ -556,12 +549,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 	if (ret)
 		return ret;
 
-	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
-		ret = rt5640_dmic_enable(component, 0, 0);
-		if (ret)
-			return ret;
-	}
-
 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
 		/*
 		 * The firmware might enable the clock at
@@ -858,8 +845,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		byt_rt5640_quirk |= BYT_RT5640_IN1_MAP;
 		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
 	} else {
-		byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP |
-				BYT_RT5640_DMIC_EN);
+		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
 	}
 
 	/* check quirks before creating card */
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11/19] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (9 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 12/19] ASoC: Intel: bytcr_rt5640: Enable jack detection Hans de Goede
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

This fixes the following 3 issues:

1) The sys_vendor match should be for "Dell Inc." not "DellInc.",
   without this fixed the quirk never gets applied
2) DMIC1 is used not DMIC2, this was not a problem sofar because for
   regular BYT boards (rather then BYTCR) we default to DMIC1 and because
   of 1. the quirk was not being applied
3) The Dell Venue 8 5830 Pro only has a single speaker

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 8b8716575910..ac9ba5aa2dc3 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -370,10 +370,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
-			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 		},
-		.driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_MONO_SPEAKER |
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 12/19] ASoC: Intel: bytcr_rt5640: Enable jack detection
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (10 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 11/19] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Enable jack detection" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 13/19] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3 Hans de Goede
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Add code to support setting jack-detect parameters through quirks and
extend the existing DMI quirk table entries for the Asus T100TA and the
Dell Venue 8 Pro 5830 to enable jack detection.

Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 164 +++++++++++++++++++++++---
 1 file changed, 148 insertions(+), 16 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index ac9ba5aa2dc3..6be4e8972010 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
+#include <linux/input.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
 #include <asm/platform_sst_audio.h>
@@ -46,19 +47,46 @@ enum {
 	BYT_RT5640_IN3_MAP,
 };
 
-#define BYT_RT5640_MAP(quirk)	((quirk) &  GENMASK(7, 0))
-#define BYT_RT5640_MONO_SPEAKER BIT(17)
-#define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
-#define BYT_RT5640_SSP2_AIF2    BIT(19) /* default is using AIF1  */
-#define BYT_RT5640_SSP0_AIF1    BIT(20)
-#define BYT_RT5640_SSP0_AIF2    BIT(21)
-#define BYT_RT5640_MCLK_EN	BIT(22)
-#define BYT_RT5640_MCLK_25MHZ	BIT(23)
+enum {
+	BYT_RT5640_JD_SRC_GPIO1		= (RT5640_JD_SRC_GPIO1 << 4),
+	BYT_RT5640_JD_SRC_JD1_IN4P	= (RT5640_JD_SRC_JD1_IN4P << 4),
+	BYT_RT5640_JD_SRC_JD2_IN4N	= (RT5640_JD_SRC_JD2_IN4N << 4),
+	BYT_RT5640_JD_SRC_GPIO2		= (RT5640_JD_SRC_GPIO2 << 4),
+	BYT_RT5640_JD_SRC_GPIO3		= (RT5640_JD_SRC_GPIO3 << 4),
+	BYT_RT5640_JD_SRC_GPIO4		= (RT5640_JD_SRC_GPIO4 << 4),
+};
+
+enum {
+	BYT_RT5640_OVCD_TH_600UA	= (6 << 8),
+	BYT_RT5640_OVCD_TH_1500UA	= (15 << 8),
+	BYT_RT5640_OVCD_TH_2000UA	= (20 << 8),
+};
+
+enum {
+	BYT_RT5640_OVCD_SF_0P5		= (RT5640_OVCD_SF_0P5 << 13),
+	BYT_RT5640_OVCD_SF_0P75		= (RT5640_OVCD_SF_0P75 << 13),
+	BYT_RT5640_OVCD_SF_1P0		= (RT5640_OVCD_SF_1P0 << 13),
+	BYT_RT5640_OVCD_SF_1P5		= (RT5640_OVCD_SF_1P5 << 13),
+};
 
-/* in-diff or dmic-pin + terminating empty entry */
-#define MAX_NO_PROPS 2
+#define BYT_RT5640_MAP(quirk)		((quirk) &  GENMASK(3, 0))
+#define BYT_RT5640_JDSRC(quirk)		(((quirk) & GENMASK(7, 4)) >> 4)
+#define BYT_RT5640_OVCD_TH(quirk)	(((quirk) & GENMASK(12, 8)) >> 8)
+#define BYT_RT5640_OVCD_SF(quirk)	(((quirk) & GENMASK(14, 13)) >> 13)
+#define BYT_RT5640_JD_NOT_INV		BIT(16)
+#define BYT_RT5640_MONO_SPEAKER		BIT(17)
+#define BYT_RT5640_DIFF_MIC		BIT(18) /* default is single-ended */
+#define BYT_RT5640_SSP2_AIF2		BIT(19) /* default is using AIF1  */
+#define BYT_RT5640_SSP0_AIF1		BIT(20)
+#define BYT_RT5640_SSP0_AIF2		BIT(21)
+#define BYT_RT5640_MCLK_EN		BIT(22)
+#define BYT_RT5640_MCLK_25MHZ		BIT(23)
+
+/* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
+#define MAX_NO_PROPS 6
 
 struct byt_rt5640_private {
+	struct snd_soc_jack jack;
 	struct clk *mclk;
 };
 static bool is_bytcr;
@@ -95,6 +123,16 @@ static void log_quirks(struct device *dev)
 		dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
 		break;
 	}
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
+			 BYT_RT5640_JDSRC(byt_rt5640_quirk));
+		dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
+			 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
+		dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
+			 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
+	}
+	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
+		dev_info(dev, "quirk JD_NOT_INV enabled\n");
 	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
 		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
@@ -330,6 +368,17 @@ static const struct snd_kcontrol_new byt_rt5640_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Speaker"),
 };
 
+static struct snd_soc_jack_pin rt5640_pins[] = {
+	{
+		.pin	= "Headphone",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Mic",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
 static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 					struct snd_pcm_hw_params *params)
 {
@@ -353,6 +402,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
 		},
 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
 					BYT_RT5640_MCLK_EN),
 	},
 	{
@@ -374,6 +426,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 		},
 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
 					BYT_RT5640_MONO_SPEAKER |
 					BYT_RT5640_MCLK_EN),
 	},
@@ -463,6 +518,23 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
 		break;
 	}
 
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,jack-detect-source",
+				    BYT_RT5640_JDSRC(byt_rt5640_quirk));
+
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,over-current-threshold-microamp",
+				    BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
+
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,over-current-scale-factor",
+				    BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
+	}
+
+	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
+		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
+
 	ret = device_add_properties(i2c_dev, props);
 	put_device(i2c_dev);
 
@@ -480,6 +552,11 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	/* Start with RC clk for jack-detect (we disable MCLK below) */
+	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
+			RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
+
 	rt5640_sel_asrc_clk_src(component,
 				RT5640_DA_STEREO_FILTER |
 				RT5640_DA_MONO_L_FILTER	|
@@ -570,11 +647,27 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 		else
 			ret = clk_set_rate(priv->mclk, 19200000);
 
-		if (ret)
+		if (ret) {
 			dev_err(card->dev, "unable to set MCLK rate\n");
+			return ret;
+		}
 	}
 
-	return ret;
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		ret = snd_soc_card_jack_new(card, "Headset",
+					    SND_JACK_HEADSET | SND_JACK_BTN_0,
+					    &priv->jack, rt5640_pins,
+					    ARRAY_SIZE(rt5640_pins));
+		if (ret) {
+			dev_err(card->dev, "Jack creation failed %d\n", ret);
+			return ret;
+		}
+		snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
+				 KEY_PLAYPAUSE);
+		snd_soc_component_set_jack(component, &priv->jack, NULL);
+	}
+
+	return 0;
 }
 
 static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
@@ -715,6 +808,47 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
 };
 
 /* SoC card */
+static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
+static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
+static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+
+static int byt_rt5640_suspend(struct snd_soc_card *card)
+{
+	struct snd_soc_component *component;
+
+	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
+		return 0;
+
+	list_for_each_entry(component, &card->component_dev_list, card_list) {
+		if (!strcmp(component->name, byt_rt5640_codec_name)) {
+			dev_dbg(component->dev, "disabling jack detect before suspend\n");
+			snd_soc_component_set_jack(component, NULL, NULL);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int byt_rt5640_resume(struct snd_soc_card *card)
+{
+	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+	struct snd_soc_component *component;
+
+	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
+		return 0;
+
+	list_for_each_entry(component, &card->component_dev_list, card_list) {
+		if (!strcmp(component->name, byt_rt5640_codec_name)) {
+			dev_dbg(component->dev, "re-enabling jack detect after resume\n");
+			snd_soc_component_set_jack(component, &priv->jack, NULL);
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static struct snd_soc_card byt_rt5640_card = {
 	.name = "bytcr-rt5640",
 	.owner = THIS_MODULE,
@@ -725,12 +859,10 @@ static struct snd_soc_card byt_rt5640_card = {
 	.dapm_routes = byt_rt5640_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
 	.fully_routed = true,
+	.suspend_pre = byt_rt5640_suspend,
+	.resume_post = byt_rt5640_resume,
 };
 
-static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
-static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
-static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
-
 static bool is_valleyview(void)
 {
 	static const struct x86_cpu_id cpu_ids[] = {
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 13/19] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (11 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 12/19] ASoC: Intel: bytcr_rt5640: Enable jack detection Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3" to the asoc tree Mark Brown
  2018-05-08 15:35 ` [PATCH 14/19] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults Hans de Goede
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Out of the 11 BYTCR devices which I have access to for testing,
7 use IN3 for the internal mic and only 1 uses IN1 for the internal mic,
the other 3 use DMIC1.

So IN3 clearly is a better default, using IN3 as default avoids the need
to add DMI quirks for some of these devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 6be4e8972010..bc0b85ec0b16 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -975,7 +975,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 
 		/* change defaults for Baytrail-CR capture */
-		byt_rt5640_quirk |= BYT_RT5640_IN1_MAP;
+		byt_rt5640_quirk |= BYT_RT5640_IN3_MAP;
 		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
 	} else {
 		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 14/19] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (12 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 13/19] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3 Hans de Goede
@ 2018-05-08 15:35 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults" to the asoc tree Mark Brown
  2018-05-08 15:36 ` [PATCH 15/19] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings Hans de Goede
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:35 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Currently we've 2 places with BYTCR defaults: 1. The generic catch-all
DMI_SYS_VENDOR=="Insyde" DMI quirk which selects SSP0-AIF1 for generic
Insyde BYTCR tablets without the ACPI channel package; and 2. the
defaults in the if (is_bytcr) {} code block.

Currently these are not identical, both select IN3 as the internal mic
output, but the "Insyde" DMI quirk leaves out the DIFF_MIC quirk. The
DIFF_MIC quirk should be enabled by default, because enabling diff. input
helps a lot for devices with a differential mic, where as it is a nop on
devices with a normal mic.

This commit adds the DIFF_MIC quirk to the "Insyde" DMI quirk path, by
adding a new BYTCR_INPUT_DEFAULTS define and using that in both code paths
which set BYTCR defaults.

Having a single place where the BYTCR input defaults are defined also
allows defining jack-detect defaults in a single place in a follow-up
commit.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index bc0b85ec0b16..0ec3aac62a07 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -82,6 +82,10 @@ enum {
 #define BYT_RT5640_MCLK_EN		BIT(22)
 #define BYT_RT5640_MCLK_25MHZ		BIT(23)
 
+#define BYTCR_INPUT_DEFAULTS				\
+	(BYT_RT5640_IN3_MAP |				\
+	 BYT_RT5640_DIFF_MIC)
+
 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
 #define MAX_NO_PROPS 6
 
@@ -475,7 +479,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 		},
-		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 					BYT_RT5640_MCLK_EN |
 					BYT_RT5640_SSP0_AIF1),
 
@@ -975,8 +979,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 
 		/* change defaults for Baytrail-CR capture */
-		byt_rt5640_quirk |= BYT_RT5640_IN3_MAP;
-		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
+		byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
 	} else {
 		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
 	}
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 15/19] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (13 preceding siblings ...)
  2018-05-08 15:35 ` [PATCH 14/19] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults Hans de Goede
@ 2018-05-08 15:36 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Add default jack-detect settings" to the asoc tree Mark Brown
  2018-05-08 15:36 ` [PATCH 16/19] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically Hans de Goede
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Out of the 11 BYTCR devices which I have access to for testing, 6 use
JD1IN4P for jack-detect, 2 use JD1IN4P non-inverted and the other 3 use
JD2IN4N, the ones not using JD1IN4P are all also special in other ways and
need a DMI quirk regardless.

All 5 BYT (non CR) devices which I have access to use JD2IN4N.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 0ec3aac62a07..d600a7cc9ca7 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -84,6 +84,9 @@ enum {
 
 #define BYTCR_INPUT_DEFAULTS				\
 	(BYT_RT5640_IN3_MAP |				\
+	 BYT_RT5640_JD_SRC_JD1_IN4P |			\
+	 BYT_RT5640_OVCD_TH_2000UA |			\
+	 BYT_RT5640_OVCD_SF_0P75 |			\
 	 BYT_RT5640_DIFF_MIC)
 
 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
@@ -981,7 +984,10 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		/* change defaults for Baytrail-CR capture */
 		byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
 	} else {
-		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
+		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
+				    BYT_RT5640_JD_SRC_JD2_IN4N |
+				    BYT_RT5640_OVCD_TH_2000UA |
+				    BYT_RT5640_OVCD_SF_0P75;
 	}
 
 	/* check quirks before creating card */
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 16/19] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (14 preceding siblings ...)
  2018-05-08 15:36 ` [PATCH 15/19] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings Hans de Goede
@ 2018-05-08 15:36 ` Hans de Goede
  2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically" to the asoc tree Mark Brown
  2018-05-08 15:36 ` [PATCH 17/19] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling Hans de Goede
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

As we add more quirks it is useful to have some sort of order in the
quirk list, sort it alphabetically.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 41 ++++++++++++++-------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index d600a7cc9ca7..07df097e3f48 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -401,7 +401,19 @@ static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
 	return 1;
 }
 
+/* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+	{
+		.callback = byt_rt5640_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+		},
+		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+						 BYT_RT5640_MCLK_EN |
+						 BYT_RT5640_SSP0_AIF1),
+
+	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -426,6 +438,14 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_SSP0_AIF2 |
 					BYT_RT5640_MCLK_EN),
 	},
+	{
+		.callback = byt_rt5640_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
+	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -448,14 +468,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
 					BYT_RT5640_MCLK_EN),
 	},
-	{
-		.callback = byt_rt5640_quirk_cb,
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
-		},
-		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
-	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -466,18 +478,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN |
 					BYT_RT5640_SSP0_AIF1),
 	},
-	{
-		.callback = byt_rt5640_quirk_cb,
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
-		},
-		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
-						 BYT_RT5640_MCLK_EN |
-						 BYT_RT5640_SSP0_AIF1),
-
-	},
-	{
+	{	/* Catch-all for generic Insyde tablets, must be last */
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 17/19] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (15 preceding siblings ...)
  2018-05-08 15:36 ` [PATCH 16/19] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically Hans de Goede
@ 2018-05-08 15:36 ` Hans de Goede
  2018-05-17 16:38   ` Applied "ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling" to the asoc tree Mark Brown
  2018-05-08 15:36 ` [PATCH 18/19] ASoC: Intel: bytcr_rt5640: Add quirks for various devices Hans de Goede
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Use dmi_first_match() instead of dmi_check_system() + callbacks, this
avoid the need to initialize dmi_system_id.callback for each
byt_rt5640_quirk_table entry.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 07df097e3f48..fcea409f3a92 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -395,16 +395,9 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 	return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 }
 
-static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
-{
-	byt_rt5640_quirk = (unsigned long)id->driver_data;
-	return 1;
-}
-
 /* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
@@ -415,7 +408,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
@@ -427,7 +419,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
@@ -439,7 +430,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
@@ -447,7 +437,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
@@ -460,7 +449,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
@@ -469,7 +457,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
 			DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
@@ -479,7 +466,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_SSP0_AIF1),
 	},
 	{	/* Catch-all for generic Insyde tablets, must be last */
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 		},
@@ -890,6 +876,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
+	const struct dmi_system_id *dmi_id;
 	struct byt_rt5640_private *priv;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
@@ -992,7 +979,9 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 	}
 
 	/* check quirks before creating card */
-	dmi_check_system(byt_rt5640_quirk_table);
+	dmi_id = dmi_first_match(byt_rt5640_quirk_table);
+	if (dmi_id)
+		byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
 	if (quirk_override) {
 		dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
 			 (unsigned int)byt_rt5640_quirk, quirk_override);
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 18/19] ASoC: Intel: bytcr_rt5640: Add quirks for various devices
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (16 preceding siblings ...)
  2018-05-08 15:36 ` [PATCH 17/19] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling Hans de Goede
@ 2018-05-08 15:36 ` Hans de Goede
  2018-05-08 15:36 ` [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks Hans de Goede
  2018-05-08 18:42 ` [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Pierre-Louis Bossart
  19 siblings, 0 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Even with our recently tweaked defaults, quite a few bytcr_rt5640 devices
still need quirks to be fully functional. This commits adds quirks where
necessary for the 16 bytcr_rt5640 devices I have access to.

The quirks are added for the following reasons:

1) Devices with only one speaker need the mono quirk to avoid driving an
unused and potentially short-circuited output. 8 of my sample of 16 devs
are mono, 4 of these would work with the defaults if it were not for their
mono speaker.

2) Devices using a different input for the internal mic then the default,
this is the case for 6 of my sample of 16 devices.

3) BYTCR devices without an ACPI channel map, which do not work with the
default of SSP0-AIF2, this is the case for 2 of my sample of 16 devices.

4) Devices which need non-default jack-detect settings, this is the case
for 6 of my sample of 16 devices.

This commit add quirks for the following devices:

Acer Iconia Tab 8 W1-810
Chuwi Vi8
HP Pavilion X2 10-n000nd
HP Stream 7
I.T. Works TW891
Lamina I8270
MSI S100
Pipo W4
PoV-mobii-800w
Toshiba Click Mini L9W-B

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 124 ++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index fcea409f3a92..cfc520200214 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -397,6 +397,18 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 
 /* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+	{	/* Acer Iconia Tab 8 W1-810 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD1_IN4P |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -429,6 +441,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_SSP0_AIF2 |
 					BYT_RT5640_MCLK_EN),
 	},
+	{	/* Chuwi Vi8 (CWI506) */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
+			/* The above are too generic, also match BIOS info */
+			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
+		},
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
@@ -456,6 +480,94 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
 					BYT_RT5640_MCLK_EN),
 	},
+	{	/* HP Pavilion x2 10-n000nd */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_1500UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* HP Stream 7 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
+		},
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_JD_NOT_INV |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* I.T.Works TW891 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
+		},
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* Lamina I8270 / T701BR.SE */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
+		},
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_JD_NOT_INV |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* MSI S100 tablet */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
+		},
+		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_DIFF_MIC |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* Pipo W4 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+			/* The above are too generic, also match BIOS info */
+			DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
+		},
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
+	{	/* Point of View Mobii TAB-P800W (V2.1) */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+			/* The above are too generic, also match BIOS info */
+			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
+			DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
+		},
+		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_MONO_SPEAKER |
+					BYT_RT5640_DIFF_MIC |
+					BYT_RT5640_SSP0_AIF2 |
+					BYT_RT5640_MCLK_EN),
+	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
@@ -465,6 +577,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN |
 					BYT_RT5640_SSP0_AIF1),
 	},
+	{	/* Toshiba Satellite Click Mini L9W-B */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_1500UA |
+					BYT_RT5640_OVCD_SF_0P75 |
+					BYT_RT5640_SSP0_AIF1 |
+					BYT_RT5640_MCLK_EN),
+	},
 	{	/* Catch-all for generic Insyde tablets, must be last */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (17 preceding siblings ...)
  2018-05-08 15:36 ` [PATCH 18/19] ASoC: Intel: bytcr_rt5640: Add quirks for various devices Hans de Goede
@ 2018-05-08 15:36 ` Hans de Goede
  2018-05-08 18:35   ` Pierre-Louis Bossart
  2018-05-17 16:38   ` Applied "ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks" to the asoc tree Mark Brown
  2018-05-08 18:42 ` [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Pierre-Louis Bossart
  19 siblings, 2 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-08 15:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou, Pierre-Louis Bossart
  Cc: Hans de Goede, alsa-devel, Takashi Iwai

Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
long_name, making it impossible for userspace to have a correct UCM
profile which only uses inputs / outputs which are actually hooked up
on the device.

Our quirks already specify which input the internal mic is connected to
and if a single (mono) speaker is used or if the device has stereo
speakers.

This commit sets a long_name based on the quirks so that userspace can
have UCM profiles doing the right thing based on the long_name.

Note that if we ever encounter the need for a special UCM profile for
some device we can add a quirk to set a specific long_name for the
device,

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index cfc520200214..9a1204dcdbc6 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
 static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
 static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
 static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
 
 static int byt_rt5640_suspend(struct snd_soc_card *card)
 {
@@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
+	const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
 	const struct dmi_system_id *dmi_id;
 	struct byt_rt5640_private *priv;
 	struct snd_soc_acpi_mach *mach;
@@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 	}
 
+	snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
+		 "bytcr-rt5640-%s-spk-%s-mic",
+		 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
+			"mono" : "stereo",
+		 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
+	byt_rt5640_card.long_name = byt_rt5640_long_name;
+
 	ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
 
 	if (ret_val) {
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-08 15:36 ` [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks Hans de Goede
@ 2018-05-08 18:35   ` Pierre-Louis Bossart
  2018-05-10 10:27     ` Hans de Goede
  2018-05-17 16:38   ` Applied "ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks" to the asoc tree Mark Brown
  1 sibling, 1 reply; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-08 18:35 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

On 5/8/18 10:36 AM, Hans de Goede wrote:
> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
> long_name, making it impossible for userspace to have a correct UCM
> profile which only uses inputs / outputs which are actually hooked up
> on the device.
> 
> Our quirks already specify which input the internal mic is connected to
> and if a single (mono) speaker is used or if the device has stereo
> speakers.
> 
> This commit sets a long_name based on the quirks so that userspace can
> have UCM profiles doing the right thing based on the long_name.

Isn't this going to be complicated to manage for UCM? Just with this 
patch alone, you'd need 8 UCM files to cover all the combinations. 16 if 
you add the 'sof-' prefix.

seems like UCM should become more 'dynamic' and get quirk information 
somehow (sysfs?) to enable/disable endpoints rather than rely on name 
encoding to select the right profile?

> 
> Note that if we ever encounter the need for a special UCM profile for
> some device we can add a quirk to set a specific long_name for the
> device,
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
> index cfc520200214..9a1204dcdbc6 100644
> --- a/sound/soc/intel/boards/bytcr_rt5640.c
> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>   static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
> +static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
>   
>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>   {
> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
>   
>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>   {
> +	const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
>   	const struct dmi_system_id *dmi_id;
>   	struct byt_rt5640_private *priv;
>   	struct snd_soc_acpi_mach *mach;
> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>   		}
>   	}
>   
> +	snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
> +		 "bytcr-rt5640-%s-spk-%s-mic",
> +		 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
> +			"mono" : "stereo",
> +		 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
> +	byt_rt5640_card.long_name = byt_rt5640_long_name;
> +
>   	ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
>   
>   	if (ret_val) {
> 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support
  2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
                   ` (18 preceding siblings ...)
  2018-05-08 15:36 ` [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks Hans de Goede
@ 2018-05-08 18:42 ` Pierre-Louis Bossart
  19 siblings, 0 replies; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-08 18:42 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

On 5/8/18 10:35 AM, Hans de Goede wrote:
> Hi All,
> 
> This series has been long in the making, but it is finally ready now.
> This series adds jack-detect support for rt5640 using devices.
> 
> This is modelled after the recent rt5651 codec- and bytcr-rt5651 machine-
> driver jack-detect changes (which were actually based on a WIP version of
> this series).
> 
> As discussed on the list already unfortunately there are no really good
> defaults which work everywhere, so patch 18 adds quirks for 10 devices,
> I've decided to do this in one go rather then split this into 10 patches.

Impressive work, thanks!

patches 8..18
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>


> Patch 19 makes the bytcr-rt5640 set a longname based on the speaker and
> input-map quirks, so that userspace can pick a correct UCM profile based
> on the longname with working jack-detect based input / output switching.
> I've matching patches adding UCM profiles for this to alsa-lib here:
> https://github.com/jwrdegoede/alsa-lib/commits/master
> I'm waiting with submitting those upstream until patch 19 is accepted
> for merging.

That last patch is a bit controversial. I am not sure this is the right 
direction to add a new profile for every combination of quirks. At the 
very least, we should have a mechanism to include basic parts (and I 
think UCM already has a concept of include). Or better one UCM file that 
combines all possible combinations and disables some parts based on 
quirk information fetched during initialization.

> 
> Regards,
> 
> Hans
> 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-08 18:35   ` Pierre-Louis Bossart
@ 2018-05-10 10:27     ` Hans de Goede
  2018-05-10 15:00       ` Pierre-Louis Bossart
  0 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-10 10:27 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

Hi,

On 08-05-18 20:35, Pierre-Louis Bossart wrote:
> On 5/8/18 10:36 AM, Hans de Goede wrote:
>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>> long_name, making it impossible for userspace to have a correct UCM
>> profile which only uses inputs / outputs which are actually hooked up
>> on the device.
>>
>> Our quirks already specify which input the internal mic is connected to
>> and if a single (mono) speaker is used or if the device has stereo
>> speakers.
>>
>> This commit sets a long_name based on the quirks so that userspace can
>> have UCM profiles doing the right thing based on the long_name.
> 
> Isn't this going to be complicated to manage for UCM? Just with this patch alone, you'd need 8 UCM files to cover all the combinations. 16 if you add the 'sof-' prefix.
> 
> seems like UCM should become more 'dynamic' and get quirk information somehow (sysfs?) to enable/disable endpoints rather than rely on name encoding to select the right profile?

I agree that this is not ideal, but this is an improvement from the
current state where we would need 1 UCM profile per board
(assuming valid DMI data and thus a proper long-name being set),
6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
to manage then 1 profile per board. So as said I believe this is
a step in the right direction.

And looking at the foreseeable future I simply don't see any of us
having the time to implement an ideal solution for this. I would
really like for end users to be able to run the latest upstream
kernel + alsa-lib and have things just work, before this hardware
becomes obsolete. I know that no-one having time to work on reworking
UCM to make it more dynamic is not the best of arguments but it
is something to take into consideration.

Thinking more about this on the alsa-lib / UCM profile side we
could have something like this:

/usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:

SectionUseCase."HiFi" {
         File "../bytcr-rt5640/Generic.conf"
	File "../bytcr-rt5640/MonoSpeaker.conf"
	File "../bytcr-rt5640/In1Mic.conf"
         Comment "Play HiFi quality Music"
}

SectionDefaults [
         cdev "hw:bytcrrt5640"
]

The only problem I can see with that is that the "ConflictingDevice"
sections for the various inputs / outputs then would refer to not
present SectionDevice sections. I have not tested this suggestion yet,
but I'm willing to write an alsa-lib patch to ignore non present
ConflictingDevice references, to make my suggestion work.

I think doing things this way, thus avoiding the need to copy and
paste a whole lot of UCM code for the 6 profiles it will not be
a problem to maintain 6 profiles, as we're really just maintaining
6 config snippets such as the above example and only one complete
profile.

Would the solution I outlined above be acceptable to you?

Regards,

Hans





>> Note that if we ever encounter the need for a special UCM profile for
>> some device we can add a quirk to set a specific long_name for the
>> device,
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
>> index cfc520200214..9a1204dcdbc6 100644
>> --- a/sound/soc/intel/boards/bytcr_rt5640.c
>> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
>> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
>>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>>   static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
>>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
>> +static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
>>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>>   {
>> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
>>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>   {
>> +    const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
>>       const struct dmi_system_id *dmi_id;
>>       struct byt_rt5640_private *priv;
>>       struct snd_soc_acpi_mach *mach;
>> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>           }
>>       }
>> +    snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
>> +         "bytcr-rt5640-%s-spk-%s-mic",
>> +         (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
>> +            "mono" : "stereo",
>> +         map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
>> +    byt_rt5640_card.long_name = byt_rt5640_long_name;
>> +
>>       ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
>>       if (ret_val) {
>>
> 
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 10:27     ` Hans de Goede
@ 2018-05-10 15:00       ` Pierre-Louis Bossart
  2018-05-10 15:48         ` Hans de Goede
  0 siblings, 1 reply; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-10 15:00 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

On 5/10/18 5:27 AM, Hans de Goede wrote:
> Hi,
> 
> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>> long_name, making it impossible for userspace to have a correct UCM
>>> profile which only uses inputs / outputs which are actually hooked up
>>> on the device.
>>>
>>> Our quirks already specify which input the internal mic is connected to
>>> and if a single (mono) speaker is used or if the device has stereo
>>> speakers.
>>>
>>> This commit sets a long_name based on the quirks so that userspace can
>>> have UCM profiles doing the right thing based on the long_name.
>>
>> Isn't this going to be complicated to manage for UCM? Just with this 
>> patch alone, you'd need 8 UCM files to cover all the combinations. 16 
>> if you add the 'sof-' prefix.
>>
>> seems like UCM should become more 'dynamic' and get quirk information 
>> somehow (sysfs?) to enable/disable endpoints rather than rely on name 
>> encoding to select the right profile?
> 
> I agree that this is not ideal, but this is an improvement from the
> current state where we would need 1 UCM profile per board
> (assuming valid DMI data and thus a proper long-name being set),
> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
> to manage then 1 profile per board. So as said I believe this is
> a step in the right direction.
> 
> And looking at the foreseeable future I simply don't see any of us
> having the time to implement an ideal solution for this. I would
> really like for end users to be able to run the latest upstream
> kernel + alsa-lib and have things just work, before this hardware
> becomes obsolete. I know that no-one having time to work on reworking
> UCM to make it more dynamic is not the best of arguments but it
> is something to take into consideration.
> 
> Thinking more about this on the alsa-lib / UCM profile side we
> could have something like this:
> 
> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
> 
> 
> SectionUseCase."HiFi" {
>          File "../bytcr-rt5640/Generic.conf"
>      File "../bytcr-rt5640/MonoSpeaker.conf"
>      File "../bytcr-rt5640/In1Mic.conf"
>          Comment "Play HiFi quality Music"
> }
> 
> SectionDefaults [
>          cdev "hw:bytcrrt5640"
> ]
> 
> The only problem I can see with that is that the "ConflictingDevice"
> sections for the various inputs / outputs then would refer to not
> present SectionDevice sections. I have not tested this suggestion yet,
> but I'm willing to write an alsa-lib patch to ignore non present
> ConflictingDevice references, to make my suggestion work.
> 
> I think doing things this way, thus avoiding the need to copy and
> paste a whole lot of UCM code for the 6 profiles it will not be
> a problem to maintain 6 profiles, as we're really just maintaining
> 6 config snippets such as the above example and only one complete
> profile.
> 
> Would the solution I outlined above be acceptable to you?

The includes and disabling conflicting devices that aren't present make 
sense. I have another issue though: for SOF integration I already 
prepared a set of files, which are mostly identical to the regular ones 
except that the platform-side mixer controls are removed (or different) 
and the name of the card/device is different (sof- prefix). See on github.

I was nearly ready to submit all those files to the new repository, I 
wasn't aware of your work so now need to figure out how to reuse all 
this once we upstream SOF (any time now if I look at Liam's patches).

> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> 
>>> Note that if we ever encounter the need for a special UCM profile for
>>> some device we can add a quirk to set a specific long_name for the
>>> device,
>>>
>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>> ---
>>>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>>>   1 file changed, 9 insertions(+)
>>>
>>> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c 
>>> b/sound/soc/intel/boards/bytcr_rt5640.c
>>> index cfc520200214..9a1204dcdbc6 100644
>>> --- a/sound/soc/intel/boards/bytcr_rt5640.c
>>> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
>>> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
>>>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>>>   static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
>>>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
>>> +static char byt_rt5640_long_name[40]; /* = 
>>> "bytcr-rt5640-*-spk-*-mic" */
>>>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>>>   {
>>> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to 
>>> require 64 bit integers */
>>>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>   {
>>> +    const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
>>>       const struct dmi_system_id *dmi_id;
>>>       struct byt_rt5640_private *priv;
>>>       struct snd_soc_acpi_mach *mach;
>>> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct 
>>> platform_device *pdev)
>>>           }
>>>       }
>>> +    snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
>>> +         "bytcr-rt5640-%s-spk-%s-mic",
>>> +         (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
>>> +            "mono" : "stereo",
>>> +         map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
>>> +    byt_rt5640_card.long_name = byt_rt5640_long_name;
>>> +
>>>       ret_val = devm_snd_soc_register_card(&pdev->dev, 
>>> &byt_rt5640_card);
>>>       if (ret_val) {
>>>
>>

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 15:00       ` Pierre-Louis Bossart
@ 2018-05-10 15:48         ` Hans de Goede
  2018-05-10 17:46           ` Pierre-Louis Bossart
  2018-05-18 15:55           ` Hans de Goede
  0 siblings, 2 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-10 15:48 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

Hi,

On 10-05-18 17:00, Pierre-Louis Bossart wrote:
> On 5/10/18 5:27 AM, Hans de Goede wrote:
>> Hi,
>>
>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>>> long_name, making it impossible for userspace to have a correct UCM
>>>> profile which only uses inputs / outputs which are actually hooked up
>>>> on the device.
>>>>
>>>> Our quirks already specify which input the internal mic is connected to
>>>> and if a single (mono) speaker is used or if the device has stereo
>>>> speakers.
>>>>
>>>> This commit sets a long_name based on the quirks so that userspace can
>>>> have UCM profiles doing the right thing based on the long_name.
>>>
>>> Isn't this going to be complicated to manage for UCM? Just with this patch alone, you'd need 8 UCM files to cover all the combinations. 16 if you add the 'sof-' prefix.
>>>
>>> seems like UCM should become more 'dynamic' and get quirk information somehow (sysfs?) to enable/disable endpoints rather than rely on name encoding to select the right profile?
>>
>> I agree that this is not ideal, but this is an improvement from the
>> current state where we would need 1 UCM profile per board
>> (assuming valid DMI data and thus a proper long-name being set),
>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>> to manage then 1 profile per board. So as said I believe this is
>> a step in the right direction.
>>
>> And looking at the foreseeable future I simply don't see any of us
>> having the time to implement an ideal solution for this. I would
>> really like for end users to be able to run the latest upstream
>> kernel + alsa-lib and have things just work, before this hardware
>> becomes obsolete. I know that no-one having time to work on reworking
>> UCM to make it more dynamic is not the best of arguments but it
>> is something to take into consideration.
>>
>> Thinking more about this on the alsa-lib / UCM profile side we
>> could have something like this:
>>
>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:
>>
>> SectionUseCase."HiFi" {
>>          File "../bytcr-rt5640/Generic.conf"
>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>      File "../bytcr-rt5640/In1Mic.conf"
>>          Comment "Play HiFi quality Music"
>> }
>>
>> SectionDefaults [
>>          cdev "hw:bytcrrt5640"
>> ]
>>
>> The only problem I can see with that is that the "ConflictingDevice"
>> sections for the various inputs / outputs then would refer to not
>> present SectionDevice sections. I have not tested this suggestion yet,
>> but I'm willing to write an alsa-lib patch to ignore non present
>> ConflictingDevice references, to make my suggestion work.
>>
>> I think doing things this way, thus avoiding the need to copy and
>> paste a whole lot of UCM code for the 6 profiles it will not be
>> a problem to maintain 6 profiles, as we're really just maintaining
>> 6 config snippets such as the above example and only one complete
>> profile.
>>
>> Would the solution I outlined above be acceptable to you?
> 
> The includes and disabling conflicting devices that aren't present make sense. I have another issue though: for SOF integration I already prepared a set of files, which are mostly identical to the regular ones except that the platform-side mixer controls are removed (or different) and the name of the card/device is different (sof- prefix). See on github.

Hmm, it might make sense to split the includes in platform and codec includes, so
to pick my example again we would get:

/usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:

SectionUseCase."HiFi" {
     SectionVerb {
          EnableSequence [
              cdev "hw:bytcrrt5640"

              File "../bytcr-rt5640/EnableSeq.conf" # This contains the platform mixer settings
              File "../rt5640/EnableSeq.conf"
          ]

          DisableSequence [
          ]

          Value {
              PlaybackPCM "hw:bytcrrt5640"
              CapturePCM "hw:bytcrrt5640"
          }
       }

       File "../rt5640/Headset.conf"
       File "../rt5640/MonoSpeaker.conf"
       File "../rt5640/In1Mic.conf"
       Comment "Play HiFi quality Music"
}

SectionDefaults [
       cdev "hw:bytcrrt5640"
]

And then for sof you would just need to
offer a sof-rt5640/EnableSeq.conf, or
maybe even leave it out completely.

And we might also be able to merge the platform
enable sequences into a generic:

bytcr/EnableSeq.conf

I think that will at least fly for bytcr-rt5640 and
butcr-rt5651, leading us being able to remove more
duplicated UCM config.

How does this sound?

Regards,

Hans





> 
> I was nearly ready to submit all those files to the new repository, I wasn't aware of your work so now need to figure out how to reuse all this once we upstream SOF (any time now if I look at Liam's patches).
> 
>>
>> Regards,
>>
>> Hans
>>
>>
>>
>>
>>
>>>> Note that if we ever encounter the need for a special UCM profile for
>>>> some device we can add a quirk to set a specific long_name for the
>>>> device,
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>> ---
>>>>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>>>>   1 file changed, 9 insertions(+)
>>>>
>>>> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
>>>> index cfc520200214..9a1204dcdbc6 100644
>>>> --- a/sound/soc/intel/boards/bytcr_rt5640.c
>>>> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
>>>> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
>>>>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>>>>   static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
>>>>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
>>>> +static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
>>>>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>>>>   {
>>>> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
>>>>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>>   {
>>>> +    const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
>>>>       const struct dmi_system_id *dmi_id;
>>>>       struct byt_rt5640_private *priv;
>>>>       struct snd_soc_acpi_mach *mach;
>>>> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>>           }
>>>>       }
>>>> +    snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
>>>> +         "bytcr-rt5640-%s-spk-%s-mic",
>>>> +         (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
>>>> +            "mono" : "stereo",
>>>> +         map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
>>>> +    byt_rt5640_card.long_name = byt_rt5640_long_name;
>>>> +
>>>>       ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
>>>>       if (ret_val) {
>>>>
>>>
> 
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 15:48         ` Hans de Goede
@ 2018-05-10 17:46           ` Pierre-Louis Bossart
  2018-05-10 18:01             ` Hans de Goede
  2018-05-18 15:55           ` Hans de Goede
  1 sibling, 1 reply; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-10 17:46 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

On 5/10/18 10:48 AM, Hans de Goede wrote:
> Hi,
> 
> On 10-05-18 17:00, Pierre-Louis Bossart wrote:
>> On 5/10/18 5:27 AM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>>>> long_name, making it impossible for userspace to have a correct UCM
>>>>> profile which only uses inputs / outputs which are actually hooked up
>>>>> on the device.
>>>>>
>>>>> Our quirks already specify which input the internal mic is 
>>>>> connected to
>>>>> and if a single (mono) speaker is used or if the device has stereo
>>>>> speakers.
>>>>>
>>>>> This commit sets a long_name based on the quirks so that userspace can
>>>>> have UCM profiles doing the right thing based on the long_name.
>>>>
>>>> Isn't this going to be complicated to manage for UCM? Just with this 
>>>> patch alone, you'd need 8 UCM files to cover all the combinations. 
>>>> 16 if you add the 'sof-' prefix.
>>>>
>>>> seems like UCM should become more 'dynamic' and get quirk 
>>>> information somehow (sysfs?) to enable/disable endpoints rather than 
>>>> rely on name encoding to select the right profile?
>>>
>>> I agree that this is not ideal, but this is an improvement from the
>>> current state where we would need 1 UCM profile per board
>>> (assuming valid DMI data and thus a proper long-name being set),
>>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>>> to manage then 1 profile per board. So as said I believe this is
>>> a step in the right direction.
>>>
>>> And looking at the foreseeable future I simply don't see any of us
>>> having the time to implement an ideal solution for this. I would
>>> really like for end users to be able to run the latest upstream
>>> kernel + alsa-lib and have things just work, before this hardware
>>> becomes obsolete. I know that no-one having time to work on reworking
>>> UCM to make it more dynamic is not the best of arguments but it
>>> is something to take into consideration.
>>>
>>> Thinking more about this on the alsa-lib / UCM profile side we
>>> could have something like this:
>>>
>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
>>>
>>>
>>> SectionUseCase."HiFi" {
>>>          File "../bytcr-rt5640/Generic.conf"
>>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>>      File "../bytcr-rt5640/In1Mic.conf"
>>>          Comment "Play HiFi quality Music"
>>> }
>>>
>>> SectionDefaults [
>>>          cdev "hw:bytcrrt5640"
>>> ]
>>>
>>> The only problem I can see with that is that the "ConflictingDevice"
>>> sections for the various inputs / outputs then would refer to not
>>> present SectionDevice sections. I have not tested this suggestion yet,
>>> but I'm willing to write an alsa-lib patch to ignore non present
>>> ConflictingDevice references, to make my suggestion work.
>>>
>>> I think doing things this way, thus avoiding the need to copy and
>>> paste a whole lot of UCM code for the 6 profiles it will not be
>>> a problem to maintain 6 profiles, as we're really just maintaining
>>> 6 config snippets such as the above example and only one complete
>>> profile.
>>>
>>> Would the solution I outlined above be acceptable to you?
>>
>> The includes and disabling conflicting devices that aren't present 
>> make sense. I have another issue though: for SOF integration I already 
>> prepared a set of files, which are mostly identical to the regular 
>> ones except that the platform-side mixer controls are removed (or 
>> different) and the name of the card/device is different (sof- prefix). 
>> See on github.
> 
> Hmm, it might make sense to split the includes in platform and codec 
> includes, so
> to pick my example again we would get:
> 
> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
> 
> 
> SectionUseCase."HiFi" {
>      SectionVerb {
>           EnableSequence [
>               cdev "hw:bytcrrt5640"
> 
>               File "../bytcr-rt5640/EnableSeq.conf" # This contains the 
> platform mixer settings
>               File "../rt5640/EnableSeq.conf"
>           ]
> 
>           DisableSequence [
>           ]
> 
>           Value {
>               PlaybackPCM "hw:bytcrrt5640"
>               CapturePCM "hw:bytcrrt5640"
>           }
>        }
> 
>        File "../rt5640/Headset.conf"
>        File "../rt5640/MonoSpeaker.conf"
>        File "../rt5640/In1Mic.conf"
>        Comment "Play HiFi quality Music"
> }
> 
> SectionDefaults [
>        cdev "hw:bytcrrt5640"
> ]
> 
> And then for sof you would just need to
> offer a sof-rt5640/EnableSeq.conf, or
> maybe even leave it out completely.
> 
> And we might also be able to merge the platform
> enable sequences into a generic:
> 
> bytcr/EnableSeq.conf
> 
> I think that will at least fly for bytcr-rt5640 and
> butcr-rt5651, leading us being able to remove more
> duplicated UCM config.
> 
> How does this sound?

splitting platform and codec sides is a good idea (and something that 
was done by removing all platform mixer settings from the HiFi files)

the problem remains that we have all these cdev strings that are 
hard-codec with a card name. Same when the match happens based on a DMI 
string, how would I know which of the platform settings to apply without 
querying what the platform driver is?

> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> 
>>
>> I was nearly ready to submit all those files to the new repository, I 
>> wasn't aware of your work so now need to figure out how to reuse all 
>> this once we upstream SOF (any time now if I look at Liam's patches).
>>
>>>
>>> Regards,
>>>
>>> Hans
>>>
>>>
>>>
>>>
>>>
>>>>> Note that if we ever encounter the need for a special UCM profile for
>>>>> some device we can add a quirk to set a specific long_name for the
>>>>> device,
>>>>>
>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>> ---
>>>>>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>>>>>   1 file changed, 9 insertions(+)
>>>>>
>>>>> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c 
>>>>> b/sound/soc/intel/boards/bytcr_rt5640.c
>>>>> index cfc520200214..9a1204dcdbc6 100644
>>>>> --- a/sound/soc/intel/boards/bytcr_rt5640.c
>>>>> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
>>>>> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link 
>>>>> byt_rt5640_dais[] = {
>>>>>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>>>>>   static char byt_rt5640_codec_aif_name[12]; /*  = 
>>>>> "rt5640-aif[1|2]" */
>>>>>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
>>>>> +static char byt_rt5640_long_name[40]; /* = 
>>>>> "bytcr-rt5640-*-spk-*-mic" */
>>>>>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>>>>>   {
>>>>> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems 
>>>>> to require 64 bit integers */
>>>>>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>>>   {
>>>>> +    const char * const map_name[] = { "dmic1", "dmic2", "in1", 
>>>>> "in3" };
>>>>>       const struct dmi_system_id *dmi_id;
>>>>>       struct byt_rt5640_private *priv;
>>>>>       struct snd_soc_acpi_mach *mach;
>>>>> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct 
>>>>> platform_device *pdev)
>>>>>           }
>>>>>       }
>>>>> +    snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
>>>>> +         "bytcr-rt5640-%s-spk-%s-mic",
>>>>> +         (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
>>>>> +            "mono" : "stereo",
>>>>> +         map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
>>>>> +    byt_rt5640_card.long_name = byt_rt5640_long_name;
>>>>> +
>>>>>       ret_val = devm_snd_soc_register_card(&pdev->dev, 
>>>>> &byt_rt5640_card);
>>>>>       if (ret_val) {
>>>>>
>>>>
>>

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 17:46           ` Pierre-Louis Bossart
@ 2018-05-10 18:01             ` Hans de Goede
  2018-05-12 21:21               ` Pierre-Louis Bossart
  0 siblings, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-10 18:01 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

Hi,

On 10-05-18 19:46, Pierre-Louis Bossart wrote:
> On 5/10/18 10:48 AM, Hans de Goede wrote:
>> Hi,
>>
>> On 10-05-18 17:00, Pierre-Louis Bossart wrote:
>>> On 5/10/18 5:27 AM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>>>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>>>>> long_name, making it impossible for userspace to have a correct UCM
>>>>>> profile which only uses inputs / outputs which are actually hooked up
>>>>>> on the device.
>>>>>>
>>>>>> Our quirks already specify which input the internal mic is connected to
>>>>>> and if a single (mono) speaker is used or if the device has stereo
>>>>>> speakers.
>>>>>>
>>>>>> This commit sets a long_name based on the quirks so that userspace can
>>>>>> have UCM profiles doing the right thing based on the long_name.
>>>>>
>>>>> Isn't this going to be complicated to manage for UCM? Just with this patch alone, you'd need 8 UCM files to cover all the combinations. 16 if you add the 'sof-' prefix.
>>>>>
>>>>> seems like UCM should become more 'dynamic' and get quirk information somehow (sysfs?) to enable/disable endpoints rather than rely on name encoding to select the right profile?
>>>>
>>>> I agree that this is not ideal, but this is an improvement from the
>>>> current state where we would need 1 UCM profile per board
>>>> (assuming valid DMI data and thus a proper long-name being set),
>>>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>>>> to manage then 1 profile per board. So as said I believe this is
>>>> a step in the right direction.
>>>>
>>>> And looking at the foreseeable future I simply don't see any of us
>>>> having the time to implement an ideal solution for this. I would
>>>> really like for end users to be able to run the latest upstream
>>>> kernel + alsa-lib and have things just work, before this hardware
>>>> becomes obsolete. I know that no-one having time to work on reworking
>>>> UCM to make it more dynamic is not the best of arguments but it
>>>> is something to take into consideration.
>>>>
>>>> Thinking more about this on the alsa-lib / UCM profile side we
>>>> could have something like this:
>>>>
>>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:
>>>>
>>>> SectionUseCase."HiFi" {
>>>>          File "../bytcr-rt5640/Generic.conf"
>>>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>>>      File "../bytcr-rt5640/In1Mic.conf"
>>>>          Comment "Play HiFi quality Music"
>>>> }
>>>>
>>>> SectionDefaults [
>>>>          cdev "hw:bytcrrt5640"
>>>> ]
>>>>
>>>> The only problem I can see with that is that the "ConflictingDevice"
>>>> sections for the various inputs / outputs then would refer to not
>>>> present SectionDevice sections. I have not tested this suggestion yet,
>>>> but I'm willing to write an alsa-lib patch to ignore non present
>>>> ConflictingDevice references, to make my suggestion work.
>>>>
>>>> I think doing things this way, thus avoiding the need to copy and
>>>> paste a whole lot of UCM code for the 6 profiles it will not be
>>>> a problem to maintain 6 profiles, as we're really just maintaining
>>>> 6 config snippets such as the above example and only one complete
>>>> profile.
>>>>
>>>> Would the solution I outlined above be acceptable to you?
>>>
>>> The includes and disabling conflicting devices that aren't present make sense. I have another issue though: for SOF integration I already prepared a set of files, which are mostly identical to the regular ones except that the platform-side mixer controls are removed (or different) and the name of the card/device is different (sof- prefix). See on github.
>>
>> Hmm, it might make sense to split the includes in platform and codec includes, so
>> to pick my example again we would get:
>>
>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:
>>
>> SectionUseCase."HiFi" {
>>      SectionVerb {
>>           EnableSequence [
>>               cdev "hw:bytcrrt5640"
>>
>>               File "../bytcr-rt5640/EnableSeq.conf" # This contains the platform mixer settings
>>               File "../rt5640/EnableSeq.conf"
>>           ]
>>
>>           DisableSequence [
>>           ]
>>
>>           Value {
>>               PlaybackPCM "hw:bytcrrt5640"
>>               CapturePCM "hw:bytcrrt5640"
>>           }
>>        }
>>
>>        File "../rt5640/Headset.conf"
>>        File "../rt5640/MonoSpeaker.conf"
>>        File "../rt5640/In1Mic.conf"
>>        Comment "Play HiFi quality Music"
>> }
>>
>> SectionDefaults [
>>        cdev "hw:bytcrrt5640"
>> ]
>>
>> And then for sof you would just need to
>> offer a sof-rt5640/EnableSeq.conf, or
>> maybe even leave it out completely.
>>
>> And we might also be able to merge the platform
>> enable sequences into a generic:
>>
>> bytcr/EnableSeq.conf
>>
>> I think that will at least fly for bytcr-rt5640 and
>> butcr-rt5651, leading us being able to remove more
>> duplicated UCM config.
>>
>> How does this sound?
> 
> splitting platform and codec sides is a good idea (and something that was done by removing all platform mixer settings from the HiFi files)
> 
> the problem remains that we have all these cdev strings that are hard-codec with a card name. Same when the match happens based on a DMI string, how would I know which of the platform settings to apply without querying what the platform driver is?

Well the DMI string would uniquely identify a certain model device,
when we write the UCM file we should know what the platform + codec
for that device is and we can simply hardcode them, like in
my example above.

But maybe I'm misunderstanding you?

Regards,

Hans




>>>>>> ---
>>>>>>   sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
>>>>>>   1 file changed, 9 insertions(+)
>>>>>>
>>>>>> diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
>>>>>> index cfc520200214..9a1204dcdbc6 100644
>>>>>> --- a/sound/soc/intel/boards/bytcr_rt5640.c
>>>>>> +++ b/sound/soc/intel/boards/bytcr_rt5640.c
>>>>>> @@ -929,6 +929,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
>>>>>>   static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
>>>>>>   static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
>>>>>>   static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
>>>>>> +static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
>>>>>>   static int byt_rt5640_suspend(struct snd_soc_card *card)
>>>>>>   {
>>>>>> @@ -1000,6 +1001,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
>>>>>>   static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>>>>   {
>>>>>> +    const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
>>>>>>       const struct dmi_system_id *dmi_id;
>>>>>>       struct byt_rt5640_private *priv;
>>>>>>       struct snd_soc_acpi_mach *mach;
>>>>>> @@ -1163,6 +1165,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
>>>>>>           }
>>>>>>       }
>>>>>> +    snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
>>>>>> +         "bytcr-rt5640-%s-spk-%s-mic",
>>>>>> +         (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
>>>>>> +            "mono" : "stereo",
>>>>>> +         map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
>>>>>> +    byt_rt5640_card.long_name = byt_rt5640_long_name;
>>>>>> +
>>>>>>       ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
>>>>>>       if (ret_val) {
>>>>>>
>>>>>
>>>
> 
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data
  2018-05-08 15:35 ` [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data Hans de Goede
@ 2018-05-11  2:16   ` Mark Brown
  2018-05-11  2:52   ` Applied "ASoC: rt5640: Remove unused rt5640_platform_data" to the asoc tree Mark Brown
  1 sibling, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:16 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, Pierre-Louis Bossart, alsa-devel, Liam Girdwood,
	Takashi Iwai, Bard Liao


[-- Attachment #1.1: Type: text/plain, Size: 356 bytes --]

On Tue, May 08, 2018 at 05:35:48PM +0200, Hans de Goede wrote:

> There are no in tree users of platform-data for the rt5640 codec driver,
> so lets remove support for it.

Like we went through last time this is not a strong reason for removing
support for platform data, it's not a positive reason for removing
things when not everything uses DT or ACPI.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic
  2018-05-08 15:35 ` [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic Hans de Goede
@ 2018-05-11  2:25   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:25 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, Pierre-Louis Bossart, alsa-devel, Liam Girdwood,
	Takashi Iwai, Bard Liao


[-- Attachment #1.1: Type: text/plain, Size: 438 bytes --]

On Tue, May 08, 2018 at 05:35:55PM +0200, Hans de Goede wrote:
> Use device-properties for setting up the dmic, based on the
> BYT_RT5640_MAP() value, instead of using the codec specific
> rt5640_dmic_enable() function for this.  This also removes the need
> for the BYT_RT5640_DMIC_EN quirk, which was always set together with
> a MAP() quirk of DMIC1_MAP or DMIC2_MAP.

This doesn't apply against current code, please check and resend.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Use device-property for differential mics" to the asoc tree
  2018-05-08 15:35 ` [PATCH 09/19] ASoC: Intel: bytcr_rt5640: Use device-property for differential mics Hans de Goede
@ 2018-05-11  2:48   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Use device-property for differential mics

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 6a7c05e55c0a3d6d4f092d734cd8fee798cf044b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:54 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Use device-property for
 differential mics

Set the "realtek,in1-differential" or "realtek,in3-differential"
device-property when the BYT_RT5640_DIFF_MIC quirk is set instead of
directly poking the codec registers.

This also fixes the BYT_RT5640_DIFF_MIC quirk not working when
combined with BYT_RT5640_IN3_MAP.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 48 ++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index c540dfdf045d..404aa7355912 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -17,6 +17,7 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -54,6 +55,9 @@ enum {
 #define BYT_RT5640_MCLK_EN	BIT(22)
 #define BYT_RT5640_MCLK_25MHZ	BIT(23)
 
+/* in-diff + terminating empty entry */
+#define MAX_NO_PROPS 2
+
 struct byt_rt5640_private {
 	struct clk *mclk;
 };
@@ -438,6 +442,39 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{}
 };
 
+/*
+ * Note this MUST be called before snd_soc_register_card(), so that the props
+ * are in place before the codec component driver's probe function parses them.
+ */
+static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
+{
+	struct property_entry props[MAX_NO_PROPS] = {};
+	struct device *i2c_dev;
+	int ret, cnt = 0;
+
+	i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
+	if (!i2c_dev)
+		return -EPROBE_DEFER;
+
+	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
+	case BYT_RT5640_IN1_MAP:
+		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+			props[cnt++] =
+				PROPERTY_ENTRY_BOOL("realtek,in1-differential");
+		break;
+	case BYT_RT5640_IN3_MAP:
+		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
+			props[cnt++] =
+				PROPERTY_ENTRY_BOOL("realtek,in3-differential");
+		break;
+	}
+
+	ret = device_add_properties(i2c_dev, props);
+	put_device(i2c_dev);
+
+	return ret;
+}
+
 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
@@ -519,11 +556,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 	if (ret)
 		return ret;
 
-	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
-		snd_soc_component_update_bits(component,  RT5640_IN1_IN2, RT5640_IN_DF1,
-				    RT5640_IN_DF1);
-	}
-
 	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
 		ret = rt5640_dmic_enable(component, 0, 0);
 		if (ret)
@@ -841,6 +873,12 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 			 (unsigned int)byt_rt5640_quirk, quirk_override);
 		byt_rt5640_quirk = quirk_override;
 	}
+
+	/* Must be called before register_card, also see declaration comment. */
+	ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
+	if (ret_val)
+		return ret_val;
+
 	log_quirks(&pdev->dev);
 
 	if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it" to the asoc tree
  2018-05-08 15:35 ` [PATCH 08/19] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it Hans de Goede
@ 2018-05-11  2:48   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From bcd9a325f0b0f407c4559779a94e802977c67274 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:53 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it

When platform_clock_control() first selects PLL1 as sysclk the PLL_CTRL
registers have not been setup yet and we effectively have an invalid clock
configuration until byt_rt5640_aif1_hw_params() gets called.

Add a new byt_rt5640_prepare_and_enable_pll1() helper and use that from
both platform_clock_control() and byt_rt5640_aif1_hw_params() to fix this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 100 +++++++++++++-------------
 1 file changed, 49 insertions(+), 51 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index ad5fcd5a1762..c540dfdf045d 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -141,6 +141,52 @@ static void log_quirks(struct device *dev)
 	}
 }
 
+static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
+					      int rate)
+{
+	int ret;
+
+	/* Configure the PLL before selecting it */
+	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
+		/* use bitclock as PLL input */
+		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+		    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+			/* 2x16 bit slots on SSP0 */
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_BCLK1,
+						  rate * 32, rate * 512);
+		} else {
+			/* 2x15 bit slots on SSP2 */
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_BCLK1,
+						  rate * 50, rate * 512);
+		}
+	} else {
+		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_MCLK,
+						  25000000, rate * 512);
+		} else {
+			ret = snd_soc_dai_set_pll(codec_dai, 0,
+						  RT5640_PLL1_S_MCLK,
+						  19200000, rate * 512);
+		}
+	}
+
+	if (ret < 0) {
+		dev_err(codec_dai->codec->dev, "can't set pll: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
+				     rate * 512, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		dev_err(codec_dai->codec->dev, "can't set clock %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
 
 #define BYT_CODEC_DAI1	"rt5640-aif1"
 #define BYT_CODEC_DAI2	"rt5640-aif2"
@@ -173,9 +219,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
 				return ret;
 			}
 		}
-		ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-					     48000 * 512,
-					     SND_SOC_CLOCK_IN);
+		ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
 	} else {
 		/*
 		 * Set codec clock source to internal clock before
@@ -299,55 +343,9 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 					struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-				     params_rate(params) * 512,
-				     SND_SOC_CLOCK_IN);
-
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
-		return ret;
-	}
+	struct snd_soc_dai *dai = rtd->codec_dai;
 
-	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
-		/* use bitclock as PLL input */
-		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
-			(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
-			/* 2x16 bit slots on SSP0 */
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_BCLK1,
-						params_rate(params) * 32,
-						params_rate(params) * 512);
-		} else {
-			/* 2x15 bit slots on SSP2 */
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_BCLK1,
-						params_rate(params) * 50,
-						params_rate(params) * 512);
-		}
-	} else {
-		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_MCLK,
-						25000000,
-						params_rate(params) * 512);
-		} else {
-			ret = snd_soc_dai_set_pll(codec_dai, 0,
-						RT5640_PLL1_S_MCLK,
-						19200000,
-						params_rate(params) * 512);
-		}
-	}
-
-	if (ret < 0) {
-		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
-		return ret;
-	}
-
-	return 0;
+	return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 }
 
 static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: rt5640: Add button press support" to the asoc tree
  2018-05-08 15:35 ` [PATCH 07/19] ASoC: rt5640: Add button press support Hans de Goede
@ 2018-05-11  2:50   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

The patch

   ASoC: rt5640: Add button press support

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From b16188a20f62b4d2f2bc7ede2ca3b15253184352 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:52 +0200
Subject: [PATCH] ASoC: rt5640: Add button press support

Enable button press detection for headsets by using the ovcd IRQ to get
notified of button presses.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/rt5640.c | 157 ++++++++++++++++++++++++++++++++++++--
 sound/soc/codecs/rt5640.h |   9 ++-
 2 files changed, 159 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 8e306f509601..8bf8d360c25f 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2119,6 +2119,24 @@ static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component
 	snd_soc_dapm_mutex_unlock(dapm);
 }
 
+static void rt5640_enable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_NOR);
+	rt5640->ovcd_irq_enabled = true;
+}
+
+static void rt5640_disable_micbias1_ovcd_irq(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_IRQ_MB1_OC_MASK, RT5640_IRQ_MB1_OC_BP);
+	rt5640->ovcd_irq_enabled = false;
+}
+
 static void rt5640_clear_micbias1_ovcd(struct snd_soc_component *component)
 {
 	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
@@ -2149,10 +2167,80 @@ static bool rt5640_jack_inserted(struct snd_soc_component *component)
 		return (val & RT5640_JD_STATUS);
 }
 
-/* Jack detect timings */
+/* Jack detect and button-press timings */
 #define JACK_SETTLE_TIME	100 /* milli seconds */
 #define JACK_DETECT_COUNT	5
 #define JACK_DETECT_MAXCOUNT	20  /* Aprox. 2 seconds worth of tries */
+#define JACK_UNPLUG_TIME	80  /* milli seconds */
+#define BP_POLL_TIME		10  /* milli seconds */
+#define BP_POLL_MAXCOUNT	200 /* assume something is wrong after this */
+#define BP_THRESHOLD		3
+
+static void rt5640_start_button_press_work(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	rt5640->poll_count = 0;
+	rt5640->press_count = 0;
+	rt5640->release_count = 0;
+	rt5640->pressed = false;
+	rt5640->press_reported = false;
+	rt5640_clear_micbias1_ovcd(component);
+	schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
+
+static void rt5640_button_press_work(struct work_struct *work)
+{
+	struct rt5640_priv *rt5640 =
+		container_of(work, struct rt5640_priv, bp_work.work);
+	struct snd_soc_component *component = rt5640->component;
+
+	/* Check the jack was not removed underneath us */
+	if (!rt5640_jack_inserted(component))
+		return;
+
+	if (rt5640_micbias1_ovcd(component)) {
+		rt5640->release_count = 0;
+		rt5640->press_count++;
+		/* Remember till after JACK_UNPLUG_TIME wait */
+		if (rt5640->press_count >= BP_THRESHOLD)
+			rt5640->pressed = true;
+		rt5640_clear_micbias1_ovcd(component);
+	} else {
+		rt5640->press_count = 0;
+		rt5640->release_count++;
+	}
+
+	/*
+	 * The pins get temporarily shorted on jack unplug, so we poll for
+	 * at least JACK_UNPLUG_TIME milli-seconds before reporting a press.
+	 */
+	rt5640->poll_count++;
+	if (rt5640->poll_count < (JACK_UNPLUG_TIME / BP_POLL_TIME)) {
+		schedule_delayed_work(&rt5640->bp_work,
+				      msecs_to_jiffies(BP_POLL_TIME));
+		return;
+	}
+
+	if (rt5640->pressed && !rt5640->press_reported) {
+		dev_dbg(component->dev, "headset button press\n");
+		snd_soc_jack_report(rt5640->jack, SND_JACK_BTN_0,
+				    SND_JACK_BTN_0);
+		rt5640->press_reported = true;
+	}
+
+	if (rt5640->release_count >= BP_THRESHOLD) {
+		if (rt5640->press_reported) {
+			dev_dbg(component->dev, "headset button release\n");
+			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+		}
+		/* Re-enable OVCD IRQ to detect next press */
+		rt5640_enable_micbias1_ovcd_irq(component);
+		return; /* Stop polling */
+	}
+
+	schedule_delayed_work(&rt5640->bp_work, msecs_to_jiffies(BP_POLL_TIME));
+}
 
 static int rt5640_detect_headset(struct snd_soc_component *component)
 {
@@ -2209,17 +2297,51 @@ static void rt5640_jack_work(struct work_struct *work)
 	if (!rt5640_jack_inserted(component)) {
 		/* Jack removed, or spurious IRQ? */
 		if (rt5640->jack->status & SND_JACK_HEADPHONE) {
-			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_HEADSET);
+			if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+				cancel_delayed_work_sync(&rt5640->bp_work);
+				rt5640_disable_micbias1_ovcd_irq(component);
+				rt5640_disable_micbias1_for_ovcd(component);
+			}
+			snd_soc_jack_report(rt5640->jack, 0,
+					    SND_JACK_HEADSET | SND_JACK_BTN_0);
 			dev_dbg(component->dev, "jack unplugged\n");
 		}
 	} else if (!(rt5640->jack->status & SND_JACK_HEADPHONE)) {
 		/* Jack inserted */
+		WARN_ON(rt5640->ovcd_irq_enabled);
 		rt5640_enable_micbias1_for_ovcd(component);
 		status = rt5640_detect_headset(component);
-		rt5640_disable_micbias1_for_ovcd(component);
-
+		if (status == SND_JACK_HEADSET) {
+			/* Enable ovcd IRQ for button press detect. */
+			rt5640_enable_micbias1_ovcd_irq(component);
+		} else {
+			/* No more need for overcurrent detect. */
+			rt5640_disable_micbias1_for_ovcd(component);
+		}
 		dev_dbg(component->dev, "detect status %#02x\n", status);
 		snd_soc_jack_report(rt5640->jack, status, SND_JACK_HEADSET);
+	} else if (rt5640->ovcd_irq_enabled && rt5640_micbias1_ovcd(component)) {
+		dev_dbg(component->dev, "OVCD IRQ\n");
+
+		/*
+		 * The ovcd IRQ keeps firing while the button is pressed, so
+		 * we disable it and start polling the button until released.
+		 *
+		 * The disable will make the IRQ pin 0 again and since we get
+		 * IRQs on both edges (so as to detect both jack plugin and
+		 * unplug) this means we will immediately get another IRQ.
+		 * The ovcd_irq_enabled check above makes the 2ND IRQ a NOP.
+		 */
+		rt5640_disable_micbias1_ovcd_irq(component);
+		rt5640_start_button_press_work(component);
+
+		/*
+		 * If the jack-detect IRQ flag goes high (unplug) after our
+		 * above rt5640_jack_inserted() check and before we have
+		 * disabled the OVCD IRQ, the IRQ pin will stay high and as
+		 * we react to edges, we miss the unplug event -> recheck.
+		 */
+		queue_work(system_long_wq, &rt5640->jack_work);
 	}
 }
 
@@ -2238,6 +2360,7 @@ static void rt5640_cancel_work(void *data)
 	struct rt5640_priv *rt5640 = data;
 
 	cancel_work_sync(&rt5640->jack_work);
+	cancel_delayed_work_sync(&rt5640->bp_work);
 }
 
 static void rt5640_enable_jack_detect(struct snd_soc_component *component,
@@ -2282,10 +2405,25 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
 	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
 		RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
 
-	snd_soc_component_write(component, RT5640_IRQ_CTRL1,
-				RT5640_IRQ_JD_NOR);
+	/*
+	 * All IRQs get or-ed together, so we need the jack IRQ to report 0
+	 * when a jack is inserted so that the OVCD IRQ then toggles the IRQ
+	 * pin 0/1 instead of it being stuck to 1. So we invert the JD polarity
+	 * on systems where the hardware does not already do this.
+	 */
+	if (rt5640->jd_inverted)
+		snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+					RT5640_IRQ_JD_NOR);
+	else
+		snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+					RT5640_IRQ_JD_NOR | RT5640_JD_P_INV);
 
 	rt5640->jack = jack;
+	if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+		rt5640_enable_micbias1_for_ovcd(component);
+		rt5640_enable_micbias1_ovcd_irq(component);
+	}
+
 	enable_irq(rt5640->irq);
 	/* sync initial jack state */
 	queue_work(system_long_wq, &rt5640->jack_work);
@@ -2298,6 +2436,12 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
 	disable_irq(rt5640->irq);
 	rt5640_cancel_work(rt5640);
 
+	if (rt5640->jack->status & SND_JACK_MICROPHONE) {
+		rt5640_disable_micbias1_ovcd_irq(component);
+		rt5640_disable_micbias1_for_ovcd(component);
+		snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
+	}
+
 	rt5640->jack = NULL;
 }
 
@@ -2677,6 +2821,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 
 	rt5640->hp_mute = 1;
 	rt5640->irq = i2c->irq;
+	INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work);
 	INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
 
 	/* Make sure work is stopped on probe-error / remove */
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 9d08471734b3..e29e3e7d61b0 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -2139,7 +2139,14 @@ struct rt5640_priv {
 	bool hp_mute;
 	bool asrc_en;
 
-	/* Jack detect data */
+	/* Jack and button detect data */
+	bool ovcd_irq_enabled;
+	bool pressed;
+	bool press_reported;
+	int press_count;
+	int release_count;
+	int poll_count;
+	struct delayed_work bp_work;
 	struct work_struct jack_work;
 	struct snd_soc_jack *jack;
 	unsigned int jd_src;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: rt5640: Add jack-detect support" to the asoc tree
  2018-05-08 15:35 ` [PATCH 06/19] ASoC: rt5640: Add jack-detect support Hans de Goede
@ 2018-05-11  2:50   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

[-- Attachment #1: Type: text/plain, Size: 15152 bytes --]

The patch

   ASoC: rt5640: Add jack-detect support

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 8210804bcf40b837f8560c99efb315c0bbfc8c7b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:51 +0200
Subject: [PATCH] ASoC: rt5640: Add jack-detect support

Add jack-detect support, loosely based on earlier work on this by:

Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Francisco mendez <francisco.mendez@intel.com>

Note getting the OVCD to work reliable was sort of finicky, so there are
quite a few comments on this to hopefully avoid people breaking it in the
future.

This (and the follow-up button press support) has been tested on the
following devices:

Acer Iconia Tab 8 W1-810
Asus T100CHI
Asus T100TA
Asus T200TA
Axxo WT1011
Chuwi Vi8
Dell Venue 8 Pro 5830
HP Pavilion X2 10-n000nd
HP Stream 7
I.T. Works TW891
Lamina I8270
MSI S100
Peaq C1010
Pipo W4
PoV MobiiTAB-P800W (v2.0)
Toshiba Click Mini L9W-B

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=196377
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/rt5640.c | 286 ++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rt5640.h |  36 ++++-
 2 files changed, 318 insertions(+), 4 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index d7c7b207f3cc..8e306f509601 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -24,6 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/acpi.h>
 #include <sound/core.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -2093,6 +2094,224 @@ int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
 }
 EXPORT_SYMBOL_GPL(rt5640_sel_asrc_clk_src);
 
+static void rt5640_enable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "MICBIAS1");
+	/* OVCD is unreliable when used with RCCLK as sysclk-source */
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5640_disable_micbias1_for_ovcd(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+	snd_soc_dapm_mutex_lock(dapm);
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Platform Clock");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "MICBIAS1");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "LDO2");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static void rt5640_clear_micbias1_ovcd(struct snd_soc_component *component)
+{
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_MB1_OC_STATUS, 0);
+}
+
+static bool rt5640_micbias1_ovcd(struct snd_soc_component *component)
+{
+	int val;
+
+	val = snd_soc_component_read32(component, RT5640_IRQ_CTRL2);
+	dev_dbg(component->dev, "irq ctrl2 %#04x\n", val);
+
+	return (val & RT5640_MB1_OC_STATUS);
+}
+
+static bool rt5640_jack_inserted(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+	int val;
+
+	val = snd_soc_component_read32(component, RT5640_INT_IRQ_ST);
+	dev_dbg(component->dev, "irq status %#04x\n", val);
+
+	if (rt5640->jd_inverted)
+		return !(val & RT5640_JD_STATUS);
+	else
+		return (val & RT5640_JD_STATUS);
+}
+
+/* Jack detect timings */
+#define JACK_SETTLE_TIME	100 /* milli seconds */
+#define JACK_DETECT_COUNT	5
+#define JACK_DETECT_MAXCOUNT	20  /* Aprox. 2 seconds worth of tries */
+
+static int rt5640_detect_headset(struct snd_soc_component *component)
+{
+	int i, headset_count = 0, headphone_count = 0;
+
+	/*
+	 * We get the insertion event before the jack is fully inserted at which
+	 * point the second ring on a TRRS connector may short the 2nd ring and
+	 * sleeve contacts, also the overcurrent detection is not entirely
+	 * reliable. So we try several times with a wait in between until we
+	 * detect the same type JACK_DETECT_COUNT times in a row.
+	 */
+	for (i = 0; i < JACK_DETECT_MAXCOUNT; i++) {
+		/* Clear any previous over-current status flag */
+		rt5640_clear_micbias1_ovcd(component);
+
+		msleep(JACK_SETTLE_TIME);
+
+		/* Check the jack is still connected before checking ovcd */
+		if (!rt5640_jack_inserted(component))
+			return 0;
+
+		if (rt5640_micbias1_ovcd(component)) {
+			/*
+			 * Over current detected, there is a short between the
+			 * 2nd ring contact and the ground, so a TRS connector
+			 * without a mic contact and thus plain headphones.
+			 */
+			dev_dbg(component->dev, "jack mic-gnd shorted\n");
+			headset_count = 0;
+			headphone_count++;
+			if (headphone_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADPHONE;
+		} else {
+			dev_dbg(component->dev, "jack mic-gnd open\n");
+			headphone_count = 0;
+			headset_count++;
+			if (headset_count == JACK_DETECT_COUNT)
+				return SND_JACK_HEADSET;
+		}
+	}
+
+	dev_err(component->dev, "Error detecting headset vs headphones, bad contact?, assuming headphones\n");
+	return SND_JACK_HEADPHONE;
+}
+
+static void rt5640_jack_work(struct work_struct *work)
+{
+	struct rt5640_priv *rt5640 =
+		container_of(work, struct rt5640_priv, jack_work);
+	struct snd_soc_component *component = rt5640->component;
+	int status;
+
+	if (!rt5640_jack_inserted(component)) {
+		/* Jack removed, or spurious IRQ? */
+		if (rt5640->jack->status & SND_JACK_HEADPHONE) {
+			snd_soc_jack_report(rt5640->jack, 0, SND_JACK_HEADSET);
+			dev_dbg(component->dev, "jack unplugged\n");
+		}
+	} else if (!(rt5640->jack->status & SND_JACK_HEADPHONE)) {
+		/* Jack inserted */
+		rt5640_enable_micbias1_for_ovcd(component);
+		status = rt5640_detect_headset(component);
+		rt5640_disable_micbias1_for_ovcd(component);
+
+		dev_dbg(component->dev, "detect status %#02x\n", status);
+		snd_soc_jack_report(rt5640->jack, status, SND_JACK_HEADSET);
+	}
+}
+
+static irqreturn_t rt5640_irq(int irq, void *data)
+{
+	struct rt5640_priv *rt5640 = data;
+
+	if (rt5640->jack)
+		queue_work(system_long_wq, &rt5640->jack_work);
+
+	return IRQ_HANDLED;
+}
+
+static void rt5640_cancel_work(void *data)
+{
+	struct rt5640_priv *rt5640 = data;
+
+	cancel_work_sync(&rt5640->jack_work);
+}
+
+static void rt5640_enable_jack_detect(struct snd_soc_component *component,
+				      struct snd_soc_jack *jack)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	/* Select JD-source */
+	snd_soc_component_update_bits(component, RT5640_JD_CTRL,
+		RT5640_JD_MASK, rt5640->jd_src);
+
+	/* Selecting GPIO01 as an interrupt */
+	snd_soc_component_update_bits(component, RT5640_GPIO_CTRL1,
+		RT5640_GP1_PIN_MASK, RT5640_GP1_PIN_IRQ);
+
+	/* Set GPIO1 output */
+	snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3,
+		RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT);
+
+	/* Enabling jd2 in general control 1 */
+	snd_soc_component_write(component, RT5640_DUMMY1, 0x3f41);
+
+	/* Enabling jd2 in general control 2 */
+	snd_soc_component_write(component, RT5640_DUMMY2, 0x4001);
+
+	snd_soc_component_write(component, RT5640_PR_BASE + RT5640_BIAS_CUR4,
+		0xa800 | rt5640->ovcd_sf);
+
+	snd_soc_component_update_bits(component, RT5640_MICBIAS,
+		RT5640_MIC1_OVTH_MASK | RT5640_MIC1_OVCD_MASK,
+		rt5640->ovcd_th | RT5640_MIC1_OVCD_EN);
+
+	/*
+	 * The over-current-detect is only reliable in detecting the absence
+	 * of over-current, when the mic-contact in the jack is short-circuited,
+	 * the hardware periodically retries if it can apply the bias-current
+	 * leading to the ovcd status flip-flopping 1-0-1 with it being 0 about
+	 * 10% of the time, as we poll the ovcd status bit we might hit that
+	 * 10%, so we enable sticky mode and when checking OVCD we clear the
+	 * status, msleep() a bit and then check to get a reliable reading.
+	 */
+	snd_soc_component_update_bits(component, RT5640_IRQ_CTRL2,
+		RT5640_MB1_OC_STKY_MASK, RT5640_MB1_OC_STKY_EN);
+
+	snd_soc_component_write(component, RT5640_IRQ_CTRL1,
+				RT5640_IRQ_JD_NOR);
+
+	rt5640->jack = jack;
+	enable_irq(rt5640->irq);
+	/* sync initial jack state */
+	queue_work(system_long_wq, &rt5640->jack_work);
+}
+
+static void rt5640_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+
+	disable_irq(rt5640->irq);
+	rt5640_cancel_work(rt5640);
+
+	rt5640->jack = NULL;
+}
+
+static int rt5640_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *jack, void *data)
+{
+	if (jack)
+		rt5640_enable_jack_detect(component, jack);
+	else
+		rt5640_disable_jack_detect(component);
+
+	return 0;
+}
+
 static int rt5640_probe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
@@ -2176,6 +2395,53 @@ static int rt5640_probe(struct snd_soc_component *component)
 	if (dmic_en)
 		rt5640_dmic_enable(component, dmic1_data_pin, dmic2_data_pin);
 
+	if (device_property_read_u32(component->dev,
+				     "realtek,jack-detect-source", &val) == 0) {
+		if (val <= RT5640_JD_SRC_GPIO4)
+			rt5640->jd_src = val << RT5640_JD_SFT;
+		else
+			dev_warn(component->dev, "Warning: Invalid jack-detect-source value: %d, leaving jack-detect disabled\n",
+				 val);
+	}
+
+	if (!device_property_read_bool(component->dev, "realtek,jack-detect-not-inverted"))
+		rt5640->jd_inverted = true;
+
+	/*
+	 * 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.
+	 */
+	rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
+	rt5640->ovcd_sf = RT5640_MIC_OVCD_SF_0P75;
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-threshold-microamp", &val) == 0) {
+		switch (val) {
+		case 600:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_600UA;
+			break;
+		case 1500:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_1500UA;
+			break;
+		case 2000:
+			rt5640->ovcd_th = RT5640_MIC1_OVTH_2000UA;
+			break;
+		default:
+			dev_warn(component->dev, "Warning: Invalid over-current-threshold-microamp value: %d, defaulting to 2000uA\n",
+				 val);
+		}
+	}
+
+	if (device_property_read_u32(component->dev,
+			"realtek,over-current-scale-factor", &val) == 0) {
+		if (val <= RT5640_OVCD_SF_1P5)
+			rt5640->ovcd_sf = val << RT5640_MIC_OVCD_SF_SFT;
+		else
+			dev_warn(component->dev, "Warning: Invalid over-current-scale-factor value: %d, defaulting to 0.75\n",
+				 val);
+	}
+
 	return 0;
 }
 
@@ -2276,6 +2542,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt5640 = {
 	.suspend		= rt5640_suspend,
 	.resume			= rt5640_resume,
 	.set_bias_level		= rt5640_set_bias_level,
+	.set_jack		= rt5640_set_jack,
 	.controls		= rt5640_snd_controls,
 	.num_controls		= ARRAY_SIZE(rt5640_snd_controls),
 	.dapm_widgets		= rt5640_dapm_widgets,
@@ -2409,6 +2676,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
 	rt5640->hp_mute = 1;
+	rt5640->irq = i2c->irq;
+	INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
+
+	/* Make sure work is stopped on probe-error / remove */
+	ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
+	if (ret)
+		return ret;
+
+	ret = devm_request_irq(&i2c->dev, rt5640->irq, rt5640_irq,
+			       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
+			       | IRQF_ONESHOT, "rt5640", rt5640);
+	if (ret == 0) {
+		/* Gets re-enabled by rt5640_set_jack() */
+		disable_irq(rt5640->irq);
+	} else {
+		dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n",
+			 rt5640->irq, ret);
+		rt5640->irq = -ENXIO;
+	}
 
 	return devm_snd_soc_register_component(&i2c->dev,
 				      &soc_component_dev_rt5640,
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index 2db6586f5ab4..9d08471734b3 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -13,6 +13,8 @@
 #define _RT5640_H
 
 #include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <dt-bindings/sound/rt5640.h>
 
 /* Info */
 #define RT5640_RESET				0x00
@@ -145,6 +147,7 @@
 
 
 /* Index of Codec Private Register definition */
+#define RT5640_BIAS_CUR4			0x15
 #define RT5640_CHPUMP_INT_REG1			0x24
 #define RT5640_MAMP_INT_REG2			0x37
 #define RT5640_3D_SPK				0x63
@@ -1606,10 +1609,17 @@
 #define RT5640_MB2_OC_P_SFT			6
 #define RT5640_MB2_OC_P_NOR			(0x0 << 6)
 #define RT5640_MB2_OC_P_INV			(0x1 << 6)
-#define RT5640_MB1_OC_CLR			(0x1 << 3)
-#define RT5640_MB1_OC_CLR_SFT			3
-#define RT5640_MB2_OC_CLR			(0x1 << 2)
-#define RT5640_MB2_OC_CLR_SFT			2
+#define RT5640_MB1_OC_STATUS			(0x1 << 3)
+#define RT5640_MB1_OC_STATUS_SFT		3
+#define RT5640_MB2_OC_STATUS			(0x1 << 2)
+#define RT5640_MB2_OC_STATUS_SFT		2
+
+/* GPIO and Internal Status (0xbf) */
+#define RT5640_GPIO1_STATUS			(0x1 << 8)
+#define RT5640_GPIO2_STATUS			(0x1 << 7)
+#define RT5640_JD_STATUS			(0x1 << 4)
+#define RT5640_OVT_STATUS			(0x1 << 3)
+#define RT5640_CLS_D_OVCD_STATUS		(0x1 << 0)
 
 /* GPIO Control 1 (0xc0) */
 #define RT5640_GP1_PIN_MASK			(0x1 << 15)
@@ -1977,6 +1987,15 @@
 #define RT5640_MCLK_DET				(0x1 << 11)
 
 /* Codec Private Register definition */
+
+/* MIC Over current threshold scale factor (0x15) */
+#define RT5640_MIC_OVCD_SF_MASK			(0x3 << 8)
+#define RT5640_MIC_OVCD_SF_SFT			8
+#define RT5640_MIC_OVCD_SF_0P5			(0x0 << 8)
+#define RT5640_MIC_OVCD_SF_0P75			(0x1 << 8)
+#define RT5640_MIC_OVCD_SF_1P0			(0x2 << 8)
+#define RT5640_MIC_OVCD_SF_1P5			(0x3 << 8)
+
 /* 3D Speaker Control (0x63) */
 #define RT5640_3D_SPK_MASK			(0x1 << 15)
 #define RT5640_3D_SPK_SFT			15
@@ -2106,6 +2125,7 @@ struct rt5640_priv {
 	struct clk *mclk;
 
 	int ldo1_en; /* GPIO for LDO1_EN */
+	int irq;
 	int sysclk;
 	int sysclk_src;
 	int lrck[RT5640_AIFS];
@@ -2118,6 +2138,14 @@ struct rt5640_priv {
 
 	bool hp_mute;
 	bool asrc_en;
+
+	/* Jack detect data */
+	struct work_struct jack_work;
+	struct snd_soc_jack *jack;
+	unsigned int jd_src;
+	bool jd_inverted;
+	unsigned int ovcd_th;
+	unsigned int ovcd_sf;
 };
 
 int rt5640_dmic_enable(struct snd_soc_component *component,
-- 
2.17.0


[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: rt5640: Allow specifying dmic data pins through device-properties" to the asoc tree
  2018-05-08 15:35 ` [PATCH 05/19] ASoC: rt5640: Allow specifying dmic data pins through device-properties Hans de Goede
@ 2018-05-11  2:51   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:51 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

The patch

   ASoC: rt5640: Allow specifying dmic data pins through device-properties

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From fb509fa962243e20bddcc5cab74c4a2153c01ff6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:50 +0200
Subject: [PATCH] ASoC: rt5640: Allow specifying dmic data pins through
 device-properties

Allow specifying dmic data pins through device-properties / dt. This will
allow us to stop exporting rt5640_dmic_enable() once all callers of it have
been converted to setting device-properties for this instead.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/rt5640.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 265a0786851d..d7c7b207f3cc 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2097,6 +2097,10 @@ static int rt5640_probe(struct snd_soc_component *component)
 {
 	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+	u32 dmic1_data_pin = 0;
+	u32 dmic2_data_pin = 0;
+	bool dmic_en = false;
+	u32 val;
 
 	/* Check if MCLK provided */
 	rt5640->mclk = devm_clk_get(component->dev, "mclk");
@@ -2157,6 +2161,21 @@ static int rt5640_probe(struct snd_soc_component *component)
 		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
 					      RT5640_IN_DF2, RT5640_IN_DF2);
 
+	if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin",
+				     &val) == 0 && val) {
+		dmic1_data_pin = val - 1;
+		dmic_en = true;
+	}
+
+	if (device_property_read_u32(component->dev, "realtek,dmic2-data-pin",
+				     &val) == 0 && val) {
+		dmic2_data_pin = val - 1;
+		dmic_en = true;
+	}
+
+	if (dmic_en)
+		rt5640_dmic_enable(component, dmic1_data_pin, dmic2_data_pin);
+
 	return 0;
 }
 
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: rt5640: Move checking of device-properties to component probe callback" to the asoc tree
  2018-05-08 15:35 ` [PATCH 04/19] ASoC: rt5640: Move checking of device-properties to component probe callback Hans de Goede
@ 2018-05-11  2:51   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:51 UTC (permalink / raw)
  To: Hans de Goede; +Cc: alsa-devel, Mark Brown

The patch

   ASoC: rt5640: Move checking of device-properties to component probe callback

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 988a5e0162ce75a4440c9181ad6d900473e428ae Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:49 +0200
Subject: [PATCH] ASoC: rt5640: Move checking of device-properties to component
 probe callback

On some platforms the platform code may need to add device-properties,
rather then relying only on properties set by the firmware.

This commit moves the parsing of the device-properties from the i2c-driver
probe() function, which may be called at any time, to the component-driver
probe() function, which gets called after the platform code calls
snd_soc_register_card().

This allows the platform code to attach extra device-properties before
the device-properties are parsed.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/rt5640.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 616f0a69b850..265a0786851d 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2138,6 +2138,25 @@ static int rt5640_probe(struct snd_soc_component *component)
 		return -ENODEV;
 	}
 
+	/*
+	 * Note on some platforms the platform code may need to add device-props
+	 * rather then relying only on properties set by the firmware.
+	 * Therefor the property parsing MUST be done here, rather then from
+	 * rt5640_i2c_probe(), so that the platform-code can attach extra
+	 * properties before calling snd_soc_register_card().
+	 */
+	if (device_property_read_bool(component->dev, "realtek,in1-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
+					      RT5640_IN_DF1, RT5640_IN_DF1);
+
+	if (device_property_read_bool(component->dev, "realtek,in2-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN3_IN4,
+					      RT5640_IN_DF2, RT5640_IN_DF2);
+
+	if (device_property_read_bool(component->dev, "realtek,in3-differential"))
+		snd_soc_component_update_bits(component, RT5640_IN1_IN2,
+					      RT5640_IN_DF2, RT5640_IN_DF2);
+
 	return 0;
 }
 
@@ -2370,18 +2389,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 	regmap_update_bits(rt5640->regmap, RT5640_DUMMY1,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
-	if (device_property_read_bool(&i2c->dev, "realtek,in1-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
-					RT5640_IN_DF1, RT5640_IN_DF1);
-
-	if (device_property_read_bool(&i2c->dev, "realtek,in2-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
-					RT5640_IN_DF2, RT5640_IN_DF2);
-
-	if (device_property_read_bool(&i2c->dev, "realtek,in3-differential"))
-		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
-					RT5640_IN_DF2, RT5640_IN_DF2);
-
 	rt5640->hp_mute = 1;
 
 	return devm_snd_soc_register_component(&i2c->dev,
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: rt5640: Remove unused rt5640_platform_data" to the asoc tree
  2018-05-08 15:35 ` [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data Hans de Goede
  2018-05-11  2:16   ` Mark Brown
@ 2018-05-11  2:52   ` Mark Brown
  1 sibling, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-11  2:52 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Liam Girdwood,
	Pierre-Louis Bossart, Mark Brown, Bard Liao

The patch

   ASoC: rt5640: Remove unused rt5640_platform_data

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 8e3ebf5e8f0a6da53795d940763cc34f5073c4c3 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Tue, 8 May 2018 17:35:48 +0200
Subject: [PATCH] ASoC: rt5640: Remove unused rt5640_platform_data

There are no in tree users of platform-data for the rt5640 codec driver,
so lets remove support for it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 include/sound/rt5640.h    | 27 --------------------
 sound/soc/codecs/rt5640.c | 53 ++++++++++++---------------------------
 sound/soc/codecs/rt5640.h |  3 +--
 3 files changed, 17 insertions(+), 66 deletions(-)
 delete mode 100644 include/sound/rt5640.h

diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
deleted file mode 100644
index e3c84b92ff70..000000000000
--- a/include/sound/rt5640.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/sound/rt5640.h -- Platform data for RT5640
- *
- * Copyright 2011 Realtek Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_RT5640_H
-#define __LINUX_SND_RT5640_H
-
-struct rt5640_platform_data {
-	/* IN1 & IN2 & IN3 can optionally be differential */
-	bool in1_diff;
-	bool in2_diff;
-	bool in3_diff;
-
-	bool dmic_en;
-	bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
-	bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
-
-	int ldo1_en; /* GPIO for LDO1_EN */
-};
-
-#endif
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 140bad07429e..616f0a69b850 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2138,10 +2138,6 @@ static int rt5640_probe(struct snd_soc_component *component)
 		return -ENODEV;
 	}
 
-	if (rt5640->pdata.dmic_en)
-		rt5640_dmic_enable(component, rt5640->pdata.dmic1_data_pin,
-					  rt5640->pdata.dmic2_data_pin);
-
 	return 0;
 }
 
@@ -2159,8 +2155,8 @@ static int rt5640_suspend(struct snd_soc_component *component)
 	rt5640_reset(component);
 	regcache_cache_only(rt5640->regmap, true);
 	regcache_mark_dirty(rt5640->regmap);
-	if (gpio_is_valid(rt5640->pdata.ldo1_en))
-		gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 0);
+	if (gpio_is_valid(rt5640->ldo1_en))
+		gpio_set_value_cansleep(rt5640->ldo1_en, 0);
 
 	return 0;
 }
@@ -2169,8 +2165,8 @@ static int rt5640_resume(struct snd_soc_component *component)
 {
 	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
-	if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
-		gpio_set_value_cansleep(rt5640->pdata.ldo1_en, 1);
+	if (gpio_is_valid(rt5640->ldo1_en)) {
+		gpio_set_value_cansleep(rt5640->ldo1_en, 1);
 		msleep(400);
 	}
 
@@ -2302,22 +2298,16 @@ MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
 
 static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
 {
-	rt5640->pdata.in1_diff = of_property_read_bool(np,
-					"realtek,in1-differential");
-	rt5640->pdata.in2_diff = of_property_read_bool(np,
-					"realtek,in2-differential");
-
-	rt5640->pdata.ldo1_en = of_get_named_gpio(np,
-					"realtek,ldo1-en-gpios", 0);
+	rt5640->ldo1_en = of_get_named_gpio(np, "realtek,ldo1-en-gpios", 0);
 	/*
 	 * LDO1_EN is optional (it may be statically tied on the board).
 	 * -ENOENT means that the property doesn't exist, i.e. there is no
 	 * GPIO, so is not an error. Any other error code means the property
 	 * exists, but could not be parsed.
 	 */
-	if (!gpio_is_valid(rt5640->pdata.ldo1_en) &&
-			(rt5640->pdata.ldo1_en != -ENOENT))
-		return rt5640->pdata.ldo1_en;
+	if (!gpio_is_valid(rt5640->ldo1_en) &&
+			(rt5640->ldo1_en != -ENOENT))
+		return rt5640->ldo1_en;
 
 	return 0;
 }
@@ -2325,7 +2315,6 @@ static int rt5640_parse_dt(struct rt5640_priv *rt5640, struct device_node *np)
 static int rt5640_i2c_probe(struct i2c_client *i2c,
 		    const struct i2c_device_id *id)
 {
-	struct rt5640_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct rt5640_priv *rt5640;
 	int ret;
 	unsigned int val;
@@ -2337,22 +2326,12 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 	i2c_set_clientdata(i2c, rt5640);
 
-	if (pdata) {
-		rt5640->pdata = *pdata;
-		/*
-		 * Translate zero'd out (default) pdata value to an invalid
-		 * GPIO ID. This makes the pdata and DT paths consistent in
-		 * terms of the value left in this field when no GPIO is
-		 * specified, but means we can't actually use GPIO 0.
-		 */
-		if (!rt5640->pdata.ldo1_en)
-			rt5640->pdata.ldo1_en = -EINVAL;
-	} else if (i2c->dev.of_node) {
+	if (i2c->dev.of_node) {
 		ret = rt5640_parse_dt(rt5640, i2c->dev.of_node);
 		if (ret)
 			return ret;
 	} else
-		rt5640->pdata.ldo1_en = -EINVAL;
+		rt5640->ldo1_en = -EINVAL;
 
 	rt5640->regmap = devm_regmap_init_i2c(i2c, &rt5640_regmap);
 	if (IS_ERR(rt5640->regmap)) {
@@ -2362,13 +2341,13 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	if (gpio_is_valid(rt5640->pdata.ldo1_en)) {
-		ret = devm_gpio_request_one(&i2c->dev, rt5640->pdata.ldo1_en,
+	if (gpio_is_valid(rt5640->ldo1_en)) {
+		ret = devm_gpio_request_one(&i2c->dev, rt5640->ldo1_en,
 					    GPIOF_OUT_INIT_HIGH,
 					    "RT5640 LDO1_EN");
 		if (ret < 0) {
 			dev_err(&i2c->dev, "Failed to request LDO1_EN %d: %d\n",
-				rt5640->pdata.ldo1_en, ret);
+				rt5640->ldo1_en, ret);
 			return ret;
 		}
 		msleep(400);
@@ -2391,15 +2370,15 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
 	regmap_update_bits(rt5640->regmap, RT5640_DUMMY1,
 				RT5640_MCLK_DET, RT5640_MCLK_DET);
 
-	if (rt5640->pdata.in1_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in1-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
 					RT5640_IN_DF1, RT5640_IN_DF1);
 
-	if (rt5640->pdata.in2_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in2-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
 					RT5640_IN_DF2, RT5640_IN_DF2);
 
-	if (rt5640->pdata.in3_diff)
+	if (device_property_read_bool(&i2c->dev, "realtek,in3-differential"))
 		regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
 					RT5640_IN_DF2, RT5640_IN_DF2);
 
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c473e8ae2eda..2db6586f5ab4 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -13,7 +13,6 @@
 #define _RT5640_H
 
 #include <linux/clk.h>
-#include <sound/rt5640.h>
 
 /* Info */
 #define RT5640_RESET				0x00
@@ -2103,10 +2102,10 @@ enum {
 
 struct rt5640_priv {
 	struct snd_soc_component *component;
-	struct rt5640_platform_data pdata;
 	struct regmap *regmap;
 	struct clk *mclk;
 
+	int ldo1_en; /* GPIO for LDO1_EN */
 	int sysclk;
 	int sysclk_src;
 	int lrck[RT5640_AIFS];
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 18:01             ` Hans de Goede
@ 2018-05-12 21:21               ` Pierre-Louis Bossart
  2018-05-13  7:11                 ` Takashi Iwai
  0 siblings, 1 reply; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-12 21:21 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai



On 05/10/2018 01:01 PM, Hans de Goede wrote:
> Hi,
>
> On 10-05-18 19:46, Pierre-Louis Bossart wrote:
>> On 5/10/18 10:48 AM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 10-05-18 17:00, Pierre-Louis Bossart wrote:
>>>> On 5/10/18 5:27 AM, Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>>>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap 
>>>>>>> devices with
>>>>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to 
>>>>>>> set a
>>>>>>> long_name, making it impossible for userspace to have a correct UCM
>>>>>>> profile which only uses inputs / outputs which are actually 
>>>>>>> hooked up
>>>>>>> on the device.
>>>>>>>
>>>>>>> Our quirks already specify which input the internal mic is 
>>>>>>> connected to
>>>>>>> and if a single (mono) speaker is used or if the device has stereo
>>>>>>> speakers.
>>>>>>>
>>>>>>> This commit sets a long_name based on the quirks so that 
>>>>>>> userspace can
>>>>>>> have UCM profiles doing the right thing based on the long_name.
>>>>>>
>>>>>> Isn't this going to be complicated to manage for UCM? Just with 
>>>>>> this patch alone, you'd need 8 UCM files to cover all the 
>>>>>> combinations. 16 if you add the 'sof-' prefix.
>>>>>>
>>>>>> seems like UCM should become more 'dynamic' and get quirk 
>>>>>> information somehow (sysfs?) to enable/disable endpoints rather 
>>>>>> than rely on name encoding to select the right profile?
>>>>>
>>>>> I agree that this is not ideal, but this is an improvement from the
>>>>> current state where we would need 1 UCM profile per board
>>>>> (assuming valid DMI data and thus a proper long-name being set),
>>>>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>>>>> to manage then 1 profile per board. So as said I believe this is
>>>>> a step in the right direction.
>>>>>
>>>>> And looking at the foreseeable future I simply don't see any of us
>>>>> having the time to implement an ideal solution for this. I would
>>>>> really like for end users to be able to run the latest upstream
>>>>> kernel + alsa-lib and have things just work, before this hardware
>>>>> becomes obsolete. I know that no-one having time to work on reworking
>>>>> UCM to make it more dynamic is not the best of arguments but it
>>>>> is something to take into consideration.
>>>>>
>>>>> Thinking more about this on the alsa-lib / UCM profile side we
>>>>> could have something like this:
>>>>>
>>>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
>>>>>
>>>>>
>>>>> SectionUseCase."HiFi" {
>>>>>          File "../bytcr-rt5640/Generic.conf"
>>>>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>>>>      File "../bytcr-rt5640/In1Mic.conf"
>>>>>          Comment "Play HiFi quality Music"
>>>>> }
>>>>>
>>>>> SectionDefaults [
>>>>>          cdev "hw:bytcrrt5640"
>>>>> ]
>>>>>
>>>>> The only problem I can see with that is that the "ConflictingDevice"
>>>>> sections for the various inputs / outputs then would refer to not
>>>>> present SectionDevice sections. I have not tested this suggestion 
>>>>> yet,
>>>>> but I'm willing to write an alsa-lib patch to ignore non present
>>>>> ConflictingDevice references, to make my suggestion work.
>>>>>
>>>>> I think doing things this way, thus avoiding the need to copy and
>>>>> paste a whole lot of UCM code for the 6 profiles it will not be
>>>>> a problem to maintain 6 profiles, as we're really just maintaining
>>>>> 6 config snippets such as the above example and only one complete
>>>>> profile.
>>>>>
>>>>> Would the solution I outlined above be acceptable to you?
>>>>
>>>> The includes and disabling conflicting devices that aren't present 
>>>> make sense. I have another issue though: for SOF integration I 
>>>> already prepared a set of files, which are mostly identical to the 
>>>> regular ones except that the platform-side mixer controls are 
>>>> removed (or different) and the name of the card/device is different 
>>>> (sof- prefix). See on github.
>>>
>>> Hmm, it might make sense to split the includes in platform and codec 
>>> includes, so
>>> to pick my example again we would get:
>>>
>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
>>>
>>>
>>> SectionUseCase."HiFi" {
>>>      SectionVerb {
>>>           EnableSequence [
>>>               cdev "hw:bytcrrt5640"
>>>
>>>               File "../bytcr-rt5640/EnableSeq.conf" # This contains 
>>> the platform mixer settings
>>>               File "../rt5640/EnableSeq.conf"
>>>           ]
>>>
>>>           DisableSequence [
>>>           ]
>>>
>>>           Value {
>>>               PlaybackPCM "hw:bytcrrt5640"
>>>               CapturePCM "hw:bytcrrt5640"
>>>           }
>>>        }
>>>
>>>        File "../rt5640/Headset.conf"
>>>        File "../rt5640/MonoSpeaker.conf"
>>>        File "../rt5640/In1Mic.conf"
>>>        Comment "Play HiFi quality Music"
>>> }
>>>
>>> SectionDefaults [
>>>        cdev "hw:bytcrrt5640"
>>> ]
>>>
>>> And then for sof you would just need to
>>> offer a sof-rt5640/EnableSeq.conf, or
>>> maybe even leave it out completely.
>>>
>>> And we might also be able to merge the platform
>>> enable sequences into a generic:
>>>
>>> bytcr/EnableSeq.conf
>>>
>>> I think that will at least fly for bytcr-rt5640 and
>>> butcr-rt5651, leading us being able to remove more
>>> duplicated UCM config.
>>>
>>> How does this sound?
>>
>> splitting platform and codec sides is a good idea (and something that 
>> was done by removing all platform mixer settings from the HiFi files)
>>
>> the problem remains that we have all these cdev strings that are 
>> hard-codec with a card name. Same when the match happens based on a 
>> DMI string, how would I know which of the platform settings to apply 
>> without querying what the platform driver is?
>
> Well the DMI string would uniquely identify a certain model device,
> when we write the UCM file we should know what the platform + codec
> for that device is and we can simply hardcode them, like in
> my example above.
>
> But maybe I'm misunderstanding you?

For the same DMI device, you could either enable the existing intel/sst 
or SOF drivers. How would we handle UCM configs then? The DMI name would 
need to be augmented with a prefix, or we use *something* to add the 
references to SOF in the platform include and ALSA device string.

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-12 21:21               ` Pierre-Louis Bossart
@ 2018-05-13  7:11                 ` Takashi Iwai
  2018-05-13  7:28                   ` Hans de Goede
  0 siblings, 1 reply; 49+ messages in thread
From: Takashi Iwai @ 2018-05-13  7:11 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Oder Chiou, alsa-devel, Liam Girdwood, Hans de Goede, Mark Brown,
	Bard Liao

On Sat, 12 May 2018 23:21:58 +0200,
Pierre-Louis Bossart wrote:
> 
> >>
> >> splitting platform and codec sides is a good idea (and something
> >> that was done by removing all platform mixer settings from the HiFi
> >> files)
> >>
> >> the problem remains that we have all these cdev strings that are
> >> hard-codec with a card name. Same when the match happens based on a
> >> DMI string, how would I know which of the platform settings to
> >> apply without querying what the platform driver is?
> >
> > Well the DMI string would uniquely identify a certain model device,
> > when we write the UCM file we should know what the platform + codec
> > for that device is and we can simply hardcode them, like in
> > my example above.
> >
> > But maybe I'm misunderstanding you?
> 
> For the same DMI device, you could either enable the existing
> intel/sst or SOF drivers. How would we handle UCM configs then? The
> DMI name would need to be augmented with a prefix, or we use
> *something* to add the references to SOF in the platform include and
> ALSA device string.

You've already added the flavor suffix to snd_soc_set_dmi_name(), so
they'll be unique, no?


Takashi

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-13  7:11                 ` Takashi Iwai
@ 2018-05-13  7:28                   ` Hans de Goede
  0 siblings, 0 replies; 49+ messages in thread
From: Hans de Goede @ 2018-05-13  7:28 UTC (permalink / raw)
  To: Takashi Iwai, Pierre-Louis Bossart
  Cc: Oder Chiou, Bard Liao, alsa-devel, Mark Brown, Liam Girdwood

Hi,

On 05/13/2018 09:11 AM, Takashi Iwai wrote:
> On Sat, 12 May 2018 23:21:58 +0200,
> Pierre-Louis Bossart wrote:
>>
>>>>
>>>> splitting platform and codec sides is a good idea (and something
>>>> that was done by removing all platform mixer settings from the HiFi
>>>> files)
>>>>
>>>> the problem remains that we have all these cdev strings that are
>>>> hard-codec with a card name. Same when the match happens based on a
>>>> DMI string, how would I know which of the platform settings to
>>>> apply without querying what the platform driver is?
>>>
>>> Well the DMI string would uniquely identify a certain model device,
>>> when we write the UCM file we should know what the platform + codec
>>> for that device is and we can simply hardcode them, like in
>>> my example above.
>>>
>>> But maybe I'm misunderstanding you?
>>
>> For the same DMI device, you could either enable the existing
>> intel/sst or SOF drivers. How would we handle UCM configs then? The
>> DMI name would need to be augmented with a prefix, or we use
>> *something* to add the references to SOF in the platform include and
>> ALSA device string.
> 
> You've already added the flavor suffix to snd_soc_set_dmi_name(), so
> they'll be unique, no?

Yes I was going to suggest doing something like that, but if we
already have that even better.

Note that the patch setting the longname based on the quirks
overrides (pre-empts really) snd_soc_set_dmi_name() and does
include  bytcr_rt5640 prefix, so this patch should make sure
that there is no name conflict between the sof and bytcr
machine drivers UCM profiles.

As mentioned in the commit message this pre-emption means we
loose the ability to have an UCM profile optimized for a
specific device, but we can work around this if necessary
with a flag which sets to not do set the quirk based
long-name on some models (if the need ever arises for this).

Regards,

Hans

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks" to the asoc tree
  2018-05-08 15:36 ` [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks Hans de Goede
  2018-05-08 18:35   ` Pierre-Louis Bossart
@ 2018-05-17 16:38   ` Mark Brown
  1 sibling, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:38 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 063422ca2a9de238401c3848c1b3641c07b6316c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:35 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks

Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
long_name, making it impossible for userspace to have a correct UCM
profile which only uses inputs / outputs which are actually hooked up
on the device.

Our quirks already specify which input the internal mic is connected to
and if a single (mono) speaker is used or if the device has stereo
speakers.

This commit sets a long_name based on the quirks so that userspace can
have UCM profiles doing the right thing based on the long_name.

Note that if we ever encounter the need for a special UCM profile for
some device we can add a quirk to set a specific long_name for the
device,

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 686d00405493..b0eec0a9b7b9 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -950,6 +950,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
 static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
 static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
 static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
 
 static int byt_rt5640_suspend(struct snd_soc_card *card)
 {
@@ -1021,6 +1022,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
+	const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
 	const struct dmi_system_id *dmi_id;
 	struct byt_rt5640_private *priv;
 	struct snd_soc_acpi_mach *mach;
@@ -1184,6 +1186,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 	}
 
+	snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
+		 "bytcr-rt5640-%s-spk-%s-mic",
+		 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
+			"mono" : "stereo",
+		 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
+	byt_rt5640_card.long_name = byt_rt5640_long_name;
+
 	ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
 
 	if (ret_val) {
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling" to the asoc tree
  2018-05-08 15:36 ` [PATCH 17/19] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling Hans de Goede
@ 2018-05-17 16:38   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:38 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 6d1bfcc5e7d196416c2ac2d5aead05c0d7acffb0 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:33 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI
 quirk handling

Use dmi_first_match() instead of dmi_check_system() + callbacks, this
avoid the need to initialize dmi_system_id.callback for each
byt_rt5640_quirk_table entry.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 965721663749..0f80deaf7fce 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -395,16 +395,9 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 	return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 }
 
-static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
-{
-	byt_rt5640_quirk = (unsigned long)id->driver_data;
-	return 1;
-}
-
 /* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
@@ -415,7 +408,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
@@ -427,7 +419,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
@@ -439,7 +430,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
@@ -447,7 +437,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
@@ -460,7 +449,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
@@ -469,7 +457,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
 			DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
@@ -479,7 +466,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_SSP0_AIF1),
 	},
 	{	/* Catch-all for generic Insyde tablets, must be last */
-		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 		},
@@ -894,6 +880,7 @@ struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
 
 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 {
+	const struct dmi_system_id *dmi_id;
 	struct byt_rt5640_private *priv;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
@@ -996,7 +983,9 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 	}
 
 	/* check quirks before creating card */
-	dmi_check_system(byt_rt5640_quirk_table);
+	dmi_id = dmi_first_match(byt_rt5640_quirk_table);
+	if (dmi_id)
+		byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
 	if (quirk_override) {
 		dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
 			 (unsigned int)byt_rt5640_quirk, quirk_override);
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically" to the asoc tree
  2018-05-08 15:36 ` [PATCH 16/19] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 3c0d01160899576af068ce293f5688b3f0bcce3c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:32 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically

As we add more quirks it is useful to have some sort of order in the
quirk list, sort it alphabetically.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 41 ++++++++++++++-------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index b00f21ed4357..965721663749 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -401,7 +401,19 @@ static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
 	return 1;
 }
 
+/* Please keep this list alphabetically sorted */
 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+	{
+		.callback = byt_rt5640_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+		},
+		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+						 BYT_RT5640_MCLK_EN |
+						 BYT_RT5640_SSP0_AIF1),
+
+	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -426,6 +438,14 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_SSP0_AIF2 |
 					BYT_RT5640_MCLK_EN),
 	},
+	{
+		.callback = byt_rt5640_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
+		},
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
+	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -448,14 +468,6 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
 					BYT_RT5640_MCLK_EN),
 	},
-	{
-		.callback = byt_rt5640_quirk_cb,
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
-		},
-		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
-	},
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
@@ -466,18 +478,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 					BYT_RT5640_MCLK_EN |
 					BYT_RT5640_SSP0_AIF1),
 	},
-	{
-		.callback = byt_rt5640_quirk_cb,
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
-		},
-		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
-						 BYT_RT5640_MCLK_EN |
-						 BYT_RT5640_SSP0_AIF1),
-
-	},
-	{
+	{	/* Catch-all for generic Insyde tablets, must be last */
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Add default jack-detect settings" to the asoc tree
  2018-05-08 15:36 ` [PATCH 15/19] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Add default jack-detect settings

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 56ff44094501787e5901669d6e880ca2065206fe Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:31 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings

Out of the 11 BYTCR devices which I have access to for testing, 6 use
JD1IN4P for jack-detect, 2 use JD1IN4P non-inverted and the other 3 use
JD2IN4N, the ones not using JD1IN4P are all also special in other ways and
need a DMI quirk regardless.

All 5 BYT (non CR) devices which I have access to use JD2IN4N.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 355c241470b5..b00f21ed4357 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -84,6 +84,9 @@ enum {
 
 #define BYTCR_INPUT_DEFAULTS				\
 	(BYT_RT5640_IN3_MAP |				\
+	 BYT_RT5640_JD_SRC_JD1_IN4P |			\
+	 BYT_RT5640_OVCD_TH_2000UA |			\
+	 BYT_RT5640_OVCD_SF_0P75 |			\
 	 BYT_RT5640_DIFF_MIC)
 
 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
@@ -985,7 +988,10 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		/* change defaults for Baytrail-CR capture */
 		byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
 	} else {
-		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
+		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
+				    BYT_RT5640_JD_SRC_JD2_IN4N |
+				    BYT_RT5640_OVCD_TH_2000UA |
+				    BYT_RT5640_OVCD_SF_0P75;
 	}
 
 	/* check quirks before creating card */
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults" to the asoc tree
  2018-05-08 15:35 ` [PATCH 14/19] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 96a388feb29474729a24703db99db72b283f977a Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:30 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults

Currently we've 2 places with BYTCR defaults: 1. The generic catch-all
DMI_SYS_VENDOR=="Insyde" DMI quirk which selects SSP0-AIF1 for generic
Insyde BYTCR tablets without the ACPI channel package; and 2. the
defaults in the if (is_bytcr) {} code block.

Currently these are not identical, both select IN3 as the internal mic
output, but the "Insyde" DMI quirk leaves out the DIFF_MIC quirk. The
DIFF_MIC quirk should be enabled by default, because enabling diff. input
helps a lot for devices with a differential mic, where as it is a nop on
devices with a normal mic.

This commit adds the DIFF_MIC quirk to the "Insyde" DMI quirk path, by
adding a new BYTCR_INPUT_DEFAULTS define and using that in both code paths
which set BYTCR defaults.

Having a single place where the BYTCR input defaults are defined also
allows defining jack-detect defaults in a single place in a follow-up
commit.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 09cdfd57e383..355c241470b5 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -82,6 +82,10 @@ enum {
 #define BYT_RT5640_MCLK_EN		BIT(22)
 #define BYT_RT5640_MCLK_25MHZ		BIT(23)
 
+#define BYTCR_INPUT_DEFAULTS				\
+	(BYT_RT5640_IN3_MAP |				\
+	 BYT_RT5640_DIFF_MIC)
+
 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
 #define MAX_NO_PROPS 6
 
@@ -475,7 +479,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
 		},
-		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
+		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
 					BYT_RT5640_MCLK_EN |
 					BYT_RT5640_SSP0_AIF1),
 
@@ -979,8 +983,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 
 		/* change defaults for Baytrail-CR capture */
-		byt_rt5640_quirk |= BYT_RT5640_IN3_MAP;
-		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
+		byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
 	} else {
 		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
 	}
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3" to the asoc tree
  2018-05-08 15:35 ` [PATCH 13/19] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3 Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 737c14641a411b2a6bea61203c4aecb62de35d72 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:29 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3

Out of the 11 BYTCR devices which I have access to for testing,
7 use IN3 for the internal mic and only 1 uses IN1 for the internal mic,
the other 3 use DMIC1.

So IN3 clearly is a better default, using IN3 as default avoids the need
to add DMI quirks for some of these devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 3cdaf87480ef..09cdfd57e383 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -979,7 +979,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
 		}
 
 		/* change defaults for Baytrail-CR capture */
-		byt_rt5640_quirk |= BYT_RT5640_IN1_MAP;
+		byt_rt5640_quirk |= BYT_RT5640_IN3_MAP;
 		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
 	} else {
 		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Enable jack detection" to the asoc tree
  2018-05-08 15:35 ` [PATCH 12/19] ASoC: Intel: bytcr_rt5640: Enable jack detection Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Enable jack detection

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 7732310839f61658162967cb43e044311196edf2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:28 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Enable jack detection

Add code to support setting jack-detect parameters through quirks and
extend the existing DMI quirk table entries for the Asus T100TA and the
Dell Venue 8 Pro 5830 to enable jack detection.

Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 164 +++++++++++++++++++++++---
 1 file changed, 148 insertions(+), 16 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index d0706ea3b04f..3cdaf87480ef 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -26,6 +26,7 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dmi.h>
+#include <linux/input.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
 #include <asm/platform_sst_audio.h>
@@ -46,19 +47,46 @@ enum {
 	BYT_RT5640_IN3_MAP,
 };
 
-#define BYT_RT5640_MAP(quirk)	((quirk) &  GENMASK(7, 0))
-#define BYT_RT5640_MONO_SPEAKER BIT(17)
-#define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
-#define BYT_RT5640_SSP2_AIF2    BIT(19) /* default is using AIF1  */
-#define BYT_RT5640_SSP0_AIF1    BIT(20)
-#define BYT_RT5640_SSP0_AIF2    BIT(21)
-#define BYT_RT5640_MCLK_EN	BIT(22)
-#define BYT_RT5640_MCLK_25MHZ	BIT(23)
+enum {
+	BYT_RT5640_JD_SRC_GPIO1		= (RT5640_JD_SRC_GPIO1 << 4),
+	BYT_RT5640_JD_SRC_JD1_IN4P	= (RT5640_JD_SRC_JD1_IN4P << 4),
+	BYT_RT5640_JD_SRC_JD2_IN4N	= (RT5640_JD_SRC_JD2_IN4N << 4),
+	BYT_RT5640_JD_SRC_GPIO2		= (RT5640_JD_SRC_GPIO2 << 4),
+	BYT_RT5640_JD_SRC_GPIO3		= (RT5640_JD_SRC_GPIO3 << 4),
+	BYT_RT5640_JD_SRC_GPIO4		= (RT5640_JD_SRC_GPIO4 << 4),
+};
+
+enum {
+	BYT_RT5640_OVCD_TH_600UA	= (6 << 8),
+	BYT_RT5640_OVCD_TH_1500UA	= (15 << 8),
+	BYT_RT5640_OVCD_TH_2000UA	= (20 << 8),
+};
+
+enum {
+	BYT_RT5640_OVCD_SF_0P5		= (RT5640_OVCD_SF_0P5 << 13),
+	BYT_RT5640_OVCD_SF_0P75		= (RT5640_OVCD_SF_0P75 << 13),
+	BYT_RT5640_OVCD_SF_1P0		= (RT5640_OVCD_SF_1P0 << 13),
+	BYT_RT5640_OVCD_SF_1P5		= (RT5640_OVCD_SF_1P5 << 13),
+};
 
-/* in-diff or dmic-pin + terminating empty entry */
-#define MAX_NO_PROPS 2
+#define BYT_RT5640_MAP(quirk)		((quirk) &  GENMASK(3, 0))
+#define BYT_RT5640_JDSRC(quirk)		(((quirk) & GENMASK(7, 4)) >> 4)
+#define BYT_RT5640_OVCD_TH(quirk)	(((quirk) & GENMASK(12, 8)) >> 8)
+#define BYT_RT5640_OVCD_SF(quirk)	(((quirk) & GENMASK(14, 13)) >> 13)
+#define BYT_RT5640_JD_NOT_INV		BIT(16)
+#define BYT_RT5640_MONO_SPEAKER		BIT(17)
+#define BYT_RT5640_DIFF_MIC		BIT(18) /* default is single-ended */
+#define BYT_RT5640_SSP2_AIF2		BIT(19) /* default is using AIF1  */
+#define BYT_RT5640_SSP0_AIF1		BIT(20)
+#define BYT_RT5640_SSP0_AIF2		BIT(21)
+#define BYT_RT5640_MCLK_EN		BIT(22)
+#define BYT_RT5640_MCLK_25MHZ		BIT(23)
+
+/* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
+#define MAX_NO_PROPS 6
 
 struct byt_rt5640_private {
+	struct snd_soc_jack jack;
 	struct clk *mclk;
 };
 static bool is_bytcr;
@@ -95,6 +123,16 @@ static void log_quirks(struct device *dev)
 		dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
 		break;
 	}
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
+			 BYT_RT5640_JDSRC(byt_rt5640_quirk));
+		dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
+			 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
+		dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
+			 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
+	}
+	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
+		dev_info(dev, "quirk JD_NOT_INV enabled\n");
 	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
 		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
@@ -330,6 +368,17 @@ static const struct snd_kcontrol_new byt_rt5640_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Speaker"),
 };
 
+static struct snd_soc_jack_pin rt5640_pins[] = {
+	{
+		.pin	= "Headphone",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Mic",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
 static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
 					struct snd_pcm_hw_params *params)
 {
@@ -353,6 +402,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
 		},
 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
 					BYT_RT5640_MCLK_EN),
 	},
 	{
@@ -374,6 +426,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 		},
 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_JD_SRC_JD2_IN4N |
+					BYT_RT5640_OVCD_TH_2000UA |
+					BYT_RT5640_OVCD_SF_0P75 |
 					BYT_RT5640_MONO_SPEAKER |
 					BYT_RT5640_MCLK_EN),
 	},
@@ -463,6 +518,23 @@ static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
 		break;
 	}
 
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,jack-detect-source",
+				    BYT_RT5640_JDSRC(byt_rt5640_quirk));
+
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,over-current-threshold-microamp",
+				    BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
+
+		props[cnt++] = PROPERTY_ENTRY_U32(
+				    "realtek,over-current-scale-factor",
+				    BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
+	}
+
+	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
+		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
+
 	ret = device_add_properties(i2c_dev, props);
 	put_device(i2c_dev);
 
@@ -480,6 +552,11 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	/* Start with RC clk for jack-detect (we disable MCLK below) */
+	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
+		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
+			RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
+
 	rt5640_sel_asrc_clk_src(component,
 				RT5640_DA_STEREO_FILTER |
 				RT5640_DA_MONO_L_FILTER	|
@@ -573,11 +650,27 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
 		else
 			ret = clk_set_rate(priv->mclk, 19200000);
 
-		if (ret)
+		if (ret) {
 			dev_err(card->dev, "unable to set MCLK rate\n");
+			return ret;
+		}
 	}
 
-	return ret;
+	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
+		ret = snd_soc_card_jack_new(card, "Headset",
+					    SND_JACK_HEADSET | SND_JACK_BTN_0,
+					    &priv->jack, rt5640_pins,
+					    ARRAY_SIZE(rt5640_pins));
+		if (ret) {
+			dev_err(card->dev, "Jack creation failed %d\n", ret);
+			return ret;
+		}
+		snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
+				 KEY_PLAYPAUSE);
+		snd_soc_component_set_jack(component, &priv->jack, NULL);
+	}
+
+	return 0;
 }
 
 static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
@@ -719,6 +812,47 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
 };
 
 /* SoC card */
+static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
+static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
+static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
+
+static int byt_rt5640_suspend(struct snd_soc_card *card)
+{
+	struct snd_soc_component *component;
+
+	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
+		return 0;
+
+	list_for_each_entry(component, &card->component_dev_list, card_list) {
+		if (!strcmp(component->name, byt_rt5640_codec_name)) {
+			dev_dbg(component->dev, "disabling jack detect before suspend\n");
+			snd_soc_component_set_jack(component, NULL, NULL);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int byt_rt5640_resume(struct snd_soc_card *card)
+{
+	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
+	struct snd_soc_component *component;
+
+	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
+		return 0;
+
+	list_for_each_entry(component, &card->component_dev_list, card_list) {
+		if (!strcmp(component->name, byt_rt5640_codec_name)) {
+			dev_dbg(component->dev, "re-enabling jack detect after resume\n");
+			snd_soc_component_set_jack(component, &priv->jack, NULL);
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static struct snd_soc_card byt_rt5640_card = {
 	.name = "bytcr-rt5640",
 	.owner = THIS_MODULE,
@@ -729,12 +863,10 @@ static struct snd_soc_card byt_rt5640_card = {
 	.dapm_routes = byt_rt5640_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
 	.fully_routed = true,
+	.suspend_pre = byt_rt5640_suspend,
+	.resume_post = byt_rt5640_resume,
 };
 
-static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
-static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
-static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
-
 static bool is_valleyview(void)
 {
 	static const struct x86_cpu_id cpu_ids[] = {
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Applied "ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk" to the asoc tree
  2018-05-08 15:35 ` [PATCH 11/19] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk Hans de Goede
@ 2018-05-17 16:39   ` Mark Brown
  0 siblings, 0 replies; 49+ messages in thread
From: Mark Brown @ 2018-05-17 16:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Oder Chiou, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Liam Girdwood, Mark Brown, Bard Liao

The patch

   ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 6748fb7e77ebff6a216243076cf162c1c700e9d6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Sun, 13 May 2018 09:24:27 +0200
Subject: [PATCH] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk

This fixes the following 3 issues:

1) The sys_vendor match should be for "Dell Inc." not "DellInc.",
   without this fixed the quirk never gets applied
2) DMIC1 is used not DMIC2, this was not a problem sofar because for
   regular BYT boards (rather then BYTCR) we default to DMIC1 and because
   of 1. the quirk was not being applied
3) The Dell Venue 8 5830 Pro only has a single speaker

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/intel/boards/bytcr_rt5640.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index cc607cfeda56..d0706ea3b04f 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -370,10 +370,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
 	{
 		.callback = byt_rt5640_quirk_cb,
 		.matches = {
-			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
 		},
-		.driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
+		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
+					BYT_RT5640_MONO_SPEAKER |
 					BYT_RT5640_MCLK_EN),
 	},
 	{
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-10 15:48         ` Hans de Goede
  2018-05-10 17:46           ` Pierre-Louis Bossart
@ 2018-05-18 15:55           ` Hans de Goede
  2018-05-18 16:21             ` Pierre-Louis Bossart
  1 sibling, 1 reply; 49+ messages in thread
From: Hans de Goede @ 2018-05-18 15:55 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

Hi Pierre-Louis,

On 10-05-18 17:48, Hans de Goede wrote:
> Hi,
> 
> On 10-05-18 17:00, Pierre-Louis Bossart wrote:
>> On 5/10/18 5:27 AM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices with
>>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>>>> long_name, making it impossible for userspace to have a correct UCM
>>>>> profile which only uses inputs / outputs which are actually hooked up
>>>>> on the device.
>>>>>
>>>>> Our quirks already specify which input the internal mic is connected to
>>>>> and if a single (mono) speaker is used or if the device has stereo
>>>>> speakers.
>>>>>
>>>>> This commit sets a long_name based on the quirks so that userspace can
>>>>> have UCM profiles doing the right thing based on the long_name.
>>>>
>>>> Isn't this going to be complicated to manage for UCM? Just with this patch alone, you'd need 8 UCM files to cover all the combinations. 16 if you add the 'sof-' prefix.
>>>>
>>>> seems like UCM should become more 'dynamic' and get quirk information somehow (sysfs?) to enable/disable endpoints rather than rely on name encoding to select the right profile?
>>>
>>> I agree that this is not ideal, but this is an improvement from the
>>> current state where we would need 1 UCM profile per board
>>> (assuming valid DMI data and thus a proper long-name being set),
>>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>>> to manage then 1 profile per board. So as said I believe this is
>>> a step in the right direction.
>>>
>>> And looking at the foreseeable future I simply don't see any of us
>>> having the time to implement an ideal solution for this. I would
>>> really like for end users to be able to run the latest upstream
>>> kernel + alsa-lib and have things just work, before this hardware
>>> becomes obsolete. I know that no-one having time to work on reworking
>>> UCM to make it more dynamic is not the best of arguments but it
>>> is something to take into consideration.
>>>
>>> Thinking more about this on the alsa-lib / UCM profile side we
>>> could have something like this:
>>>
>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:
>>>
>>> SectionUseCase."HiFi" {
>>>          File "../bytcr-rt5640/Generic.conf"
>>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>>      File "../bytcr-rt5640/In1Mic.conf"
>>>          Comment "Play HiFi quality Music"
>>> }
>>>
>>> SectionDefaults [
>>>          cdev "hw:bytcrrt5640"
>>> ]
>>>
>>> The only problem I can see with that is that the "ConflictingDevice"
>>> sections for the various inputs / outputs then would refer to not
>>> present SectionDevice sections. I have not tested this suggestion yet,
>>> but I'm willing to write an alsa-lib patch to ignore non present
>>> ConflictingDevice references, to make my suggestion work.
>>>
>>> I think doing things this way, thus avoiding the need to copy and
>>> paste a whole lot of UCM code for the 6 profiles it will not be
>>> a problem to maintain 6 profiles, as we're really just maintaining
>>> 6 config snippets such as the above example and only one complete
>>> profile.
>>>
>>> Would the solution I outlined above be acceptable to you?
>>
>> The includes and disabling conflicting devices that aren't present make sense. I have another issue though: for SOF integration I already prepared a set of files, which are mostly identical to the regular ones except that the platform-side mixer controls are removed (or different) and the name of the card/device is different (sof- prefix). See on github.
> 
> Hmm, it might make sense to split the includes in platform and codec includes, so
> to pick my example again we would get:
> 
> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf:
> 
> SectionUseCase."HiFi" {
>      SectionVerb {
>           EnableSequence [
>               cdev "hw:bytcrrt5640"
> 
>               File "../bytcr-rt5640/EnableSeq.conf" # This contains the platform mixer settings
>               File "../rt5640/EnableSeq.conf"
>           ]
> 
>           DisableSequence [
>           ]
> 
>           Value {
>               PlaybackPCM "hw:bytcrrt5640"
>               CapturePCM "hw:bytcrrt5640"
>           }
>        }
> 
>        File "../rt5640/Headset.conf"
>        File "../rt5640/MonoSpeaker.conf"
>        File "../rt5640/In1Mic.conf"
>        Comment "Play HiFi quality Music"
> }
> 
> SectionDefaults [
>        cdev "hw:bytcrrt5640"
> ]
> 
> And then for sof you would just need to
> offer a sof-rt5640/EnableSeq.conf, or
> maybe even leave it out completely.
> 
> And we might also be able to merge the platform
> enable sequences into a generic:
> 
> bytcr/EnableSeq.conf
> 
> I think that will at least fly for bytcr-rt5640 and
> butcr-rt5651, leading us being able to remove more
> duplicated UCM config. >
> How does this sound?

I've implemented the above scheme, see:
https://github.com/jwrdegoede/alsa-lib/commits/master

This seems to work well (I still need to test a
bit more, but so far the generic and one long-name
based profile work fine) and Mark has merged the
"ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks"
patch in his for-next branch, so I plan to submit
the matching alsa-lib patches from my github for
upstream alsa-lib inclusion soon.

Regards,

Hans
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks
  2018-05-18 15:55           ` Hans de Goede
@ 2018-05-18 16:21             ` Pierre-Louis Bossart
  0 siblings, 0 replies; 49+ messages in thread
From: Pierre-Louis Bossart @ 2018-05-18 16:21 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown, Bard Liao, Oder Chiou
  Cc: alsa-devel, Takashi Iwai

On 5/18/18 10:55 AM, Hans de Goede wrote:
> Hi Pierre-Louis,
> 
> On 10-05-18 17:48, Hans de Goede wrote:
>> Hi,
>>
>> On 10-05-18 17:00, Pierre-Louis Bossart wrote:
>>> On 5/10/18 5:27 AM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 08-05-18 20:35, Pierre-Louis Bossart wrote:
>>>>> On 5/8/18 10:36 AM, Hans de Goede wrote:
>>>>>> Many X86 devices using a BYT SoC + RT5640 codec are cheap devices 
>>>>>> with
>>>>>> generic DMI strings, causing snd_soc_set_dmi_name() to fail to set a
>>>>>> long_name, making it impossible for userspace to have a correct UCM
>>>>>> profile which only uses inputs / outputs which are actually hooked up
>>>>>> on the device.
>>>>>>
>>>>>> Our quirks already specify which input the internal mic is 
>>>>>> connected to
>>>>>> and if a single (mono) speaker is used or if the device has stereo
>>>>>> speakers.
>>>>>>
>>>>>> This commit sets a long_name based on the quirks so that userspace 
>>>>>> can
>>>>>> have UCM profiles doing the right thing based on the long_name.
>>>>>
>>>>> Isn't this going to be complicated to manage for UCM? Just with 
>>>>> this patch alone, you'd need 8 UCM files to cover all the 
>>>>> combinations. 16 if you add the 'sof-' prefix.
>>>>>
>>>>> seems like UCM should become more 'dynamic' and get quirk 
>>>>> information somehow (sysfs?) to enable/disable endpoints rather 
>>>>> than rely on name encoding to select the right profile?
>>>>
>>>> I agree that this is not ideal, but this is an improvement from the
>>>> current state where we would need 1 UCM profile per board
>>>> (assuming valid DMI data and thus a proper long-name being set),
>>>> 6 profiles (dmic2 is not used anywhere sofar) is a whole lot easier
>>>> to manage then 1 profile per board. So as said I believe this is
>>>> a step in the right direction.
>>>>
>>>> And looking at the foreseeable future I simply don't see any of us
>>>> having the time to implement an ideal solution for this. I would
>>>> really like for end users to be able to run the latest upstream
>>>> kernel + alsa-lib and have things just work, before this hardware
>>>> becomes obsolete. I know that no-one having time to work on reworking
>>>> UCM to make it more dynamic is not the best of arguments but it
>>>> is something to take into consideration.
>>>>
>>>> Thinking more about this on the alsa-lib / UCM profile side we
>>>> could have something like this:
>>>>
>>>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
>>>>
>>>>
>>>> SectionUseCase."HiFi" {
>>>>          File "../bytcr-rt5640/Generic.conf"
>>>>      File "../bytcr-rt5640/MonoSpeaker.conf"
>>>>      File "../bytcr-rt5640/In1Mic.conf"
>>>>          Comment "Play HiFi quality Music"
>>>> }
>>>>
>>>> SectionDefaults [
>>>>          cdev "hw:bytcrrt5640"
>>>> ]
>>>>
>>>> The only problem I can see with that is that the "ConflictingDevice"
>>>> sections for the various inputs / outputs then would refer to not
>>>> present SectionDevice sections. I have not tested this suggestion yet,
>>>> but I'm willing to write an alsa-lib patch to ignore non present
>>>> ConflictingDevice references, to make my suggestion work.
>>>>
>>>> I think doing things this way, thus avoiding the need to copy and
>>>> paste a whole lot of UCM code for the 6 profiles it will not be
>>>> a problem to maintain 6 profiles, as we're really just maintaining
>>>> 6 config snippets such as the above example and only one complete
>>>> profile.
>>>>
>>>> Would the solution I outlined above be acceptable to you?
>>>
>>> The includes and disabling conflicting devices that aren't present 
>>> make sense. I have another issue though: for SOF integration I 
>>> already prepared a set of files, which are mostly identical to the 
>>> regular ones except that the platform-side mixer controls are removed 
>>> (or different) and the name of the card/device is different (sof- 
>>> prefix). See on github.
>>
>> Hmm, it might make sense to split the includes in platform and codec 
>> includes, so
>> to pick my example again we would get:
>>
>> /usr/share/alsa/ucm/bytcr-rt5640-mono-spk-in1-mic/bytcr-rt5640-mono-spk-in1-mic.conf: 
>>
>>
>> SectionUseCase."HiFi" {
>>      SectionVerb {
>>           EnableSequence [
>>               cdev "hw:bytcrrt5640"
>>
>>               File "../bytcr-rt5640/EnableSeq.conf" # This contains 
>> the platform mixer settings
>>               File "../rt5640/EnableSeq.conf"
>>           ]
>>
>>           DisableSequence [
>>           ]
>>
>>           Value {
>>               PlaybackPCM "hw:bytcrrt5640"
>>               CapturePCM "hw:bytcrrt5640"
>>           }
>>        }
>>
>>        File "../rt5640/Headset.conf"
>>        File "../rt5640/MonoSpeaker.conf"
>>        File "../rt5640/In1Mic.conf"
>>        Comment "Play HiFi quality Music"
>> }
>>
>> SectionDefaults [
>>        cdev "hw:bytcrrt5640"
>> ]
>>
>> And then for sof you would just need to
>> offer a sof-rt5640/EnableSeq.conf, or
>> maybe even leave it out completely.
>>
>> And we might also be able to merge the platform
>> enable sequences into a generic:
>>
>> bytcr/EnableSeq.conf
>>
>> I think that will at least fly for bytcr-rt5640 and
>> butcr-rt5651, leading us being able to remove more
>> duplicated UCM config. >
>> How does this sound?
> 
> I've implemented the above scheme, see:
> https://github.com/jwrdegoede/alsa-lib/commits/master
> 
> This seems to work well (I still need to test a
> bit more, but so far the generic and one long-name
> based profile work fine) and Mark has merged the
> "ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks"
> patch in his for-next branch, so I plan to submit
> the matching alsa-lib patches from my github for
> upstream alsa-lib inclusion soon.

This looks pretty good, thanks!

The part that is still problematic is the cdev "hw:bytcrrt5640" that is 
pretty much everywhere. I don't know if it's useful to be repeated in 
all files. If there was a way to assign it at a higher level or to 
override it when SOF is present it'd solve most of the issues I see.

Please go ahead and submit these patches, I am not going to have 
iso-functionality for rt5640 and 51 in the next weeks with SOF - I don't 
have a clean way to deal with SSP0/SSP2 automatic configuration at the 
firmware level for now, so don't want to stop your work because I have 
something on the back burner.

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2018-05-18 16:21 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-08 15:35 [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Hans de Goede
2018-05-08 15:35 ` [PATCH 01/19] ASoC: rt5640: Remove is_sys_clk_from_pll, it has ordering issues Hans de Goede
2018-05-08 15:35 ` [PATCH 02/19] ASoC: rt5640: Add devicetree-bindings for dmic, jack-detect Hans de Goede
2018-05-08 15:35 ` [PATCH 03/19] ASoC: rt5640: Remove unused rt5640_platform_data Hans de Goede
2018-05-11  2:16   ` Mark Brown
2018-05-11  2:52   ` Applied "ASoC: rt5640: Remove unused rt5640_platform_data" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 04/19] ASoC: rt5640: Move checking of device-properties to component probe callback Hans de Goede
2018-05-11  2:51   ` Applied "ASoC: rt5640: Move checking of device-properties to component probe callback" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 05/19] ASoC: rt5640: Allow specifying dmic data pins through device-properties Hans de Goede
2018-05-11  2:51   ` Applied "ASoC: rt5640: Allow specifying dmic data pins through device-properties" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 06/19] ASoC: rt5640: Add jack-detect support Hans de Goede
2018-05-11  2:50   ` Applied "ASoC: rt5640: Add jack-detect support" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 07/19] ASoC: rt5640: Add button press support Hans de Goede
2018-05-11  2:50   ` Applied "ASoC: rt5640: Add button press support" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 08/19] ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it Hans de Goede
2018-05-11  2:48   ` Applied "ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 09/19] ASoC: Intel: bytcr_rt5640: Use device-property for differential mics Hans de Goede
2018-05-11  2:48   ` Applied "ASoC: Intel: bytcr_rt5640: Use device-property for differential mics" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 10/19] ASoC: Intel: bytcr_rt5640: Use device properties for setting up dmic Hans de Goede
2018-05-11  2:25   ` Mark Brown
2018-05-08 15:35 ` [PATCH 11/19] ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Fix Dell Venue 8 5830 Pro quirk" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 12/19] ASoC: Intel: bytcr_rt5640: Enable jack detection Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Enable jack detection" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 13/19] ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3 Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Change BYTCR default input to IN3" to the asoc tree Mark Brown
2018-05-08 15:35 ` [PATCH 14/19] ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Unify BYTCR input defaults" to the asoc tree Mark Brown
2018-05-08 15:36 ` [PATCH 15/19] ASoC: Intel: bytcr_rt5640: Add default jack-detect settings Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Add default jack-detect settings" to the asoc tree Mark Brown
2018-05-08 15:36 ` [PATCH 16/19] ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically Hans de Goede
2018-05-17 16:39   ` Applied "ASoC: Intel: bytcr_rt5640: Sort DMI quirk list alphabetically" to the asoc tree Mark Brown
2018-05-08 15:36 ` [PATCH 17/19] ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling Hans de Goede
2018-05-17 16:38   ` Applied "ASoC: Intel: bytcr_rt5640: Use dmi_first_match() for DMI quirk handling" to the asoc tree Mark Brown
2018-05-08 15:36 ` [PATCH 18/19] ASoC: Intel: bytcr_rt5640: Add quirks for various devices Hans de Goede
2018-05-08 15:36 ` [PATCH 19/19] ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks Hans de Goede
2018-05-08 18:35   ` Pierre-Louis Bossart
2018-05-10 10:27     ` Hans de Goede
2018-05-10 15:00       ` Pierre-Louis Bossart
2018-05-10 15:48         ` Hans de Goede
2018-05-10 17:46           ` Pierre-Louis Bossart
2018-05-10 18:01             ` Hans de Goede
2018-05-12 21:21               ` Pierre-Louis Bossart
2018-05-13  7:11                 ` Takashi Iwai
2018-05-13  7:28                   ` Hans de Goede
2018-05-18 15:55           ` Hans de Goede
2018-05-18 16:21             ` Pierre-Louis Bossart
2018-05-17 16:38   ` Applied "ASoC: Intel: bytcr_rt5640: Set card long_name based on quirks" to the asoc tree Mark Brown
2018-05-08 18:42 ` [PATCH 00/19] ASoC: rt5640: Add jack-detect and button-press support Pierre-Louis Bossart

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.