All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements
@ 2019-01-03 13:45 Hans de Goede
  2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
                   ` (10 more replies)
  0 siblings, 11 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Hi All,

Here is a patch series which makes all the sound out and inputs on the
1 BYT + ES8316 and 2 CHT + ES8316 devices which I have fully work.

As usual this was an interesting journey, with things like needing a GPIO
to enable the speaker and the mono speaker on this devices being connected
between the left and right outputs of the HP amplifier of the ES8316.

Daniel and other Endless people I believe that Endless has at least one
CHT devices with an ES8316, it could be good if someone from Endless can
test your device with this series, combined with the ALSA ucm patches which
I will also Cc you on.

Note that I've chosen to make the mono speaker setup the defaults since
because of its differential setup it does not work very well when setup
for stereo speakers. So you may need to pass a quirk parameter and submit
a DMI based quirk upstream to get stereo instead of mono on your device
(you will get audio on both speakers, but it will be a mono mix output
on both speakers).

Regards,

Hans

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

* [PATCH 01/10] ASoC: es8316: Add jack-detect support
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:09   ` Applied "ASoC: es8316: Add jack-detect support" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control Hans de Goede
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Adding jack-detect support may seem weird for a codec with only
a single output, but it is necessary. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects
the speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail
devices and one Bay Trail CR device), use an analog mux to disconnect
the speakers, driven by a GPIO. In order to enable/disable the speakers
at the right time, we need jack-detect.

The same goes for the microphone where we must correctly set the mux
for the single ADC to either the internal or the headset microphone.

All devices I have support the es8316's builtin jack-detect functionality.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index e97d12d578b0..26413851e434 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -15,12 +15,14 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
 #include <linux/regmap.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
+#include <sound/jack.h>
 #include "es8316.h"
 
 /* In slave mode at single speed, the codec is documented as accepting 5
@@ -33,6 +35,11 @@ static const unsigned int supported_mclk_lrck_ratios[] = {
 };
 
 struct es8316_priv {
+	struct mutex lock;
+	struct regmap *regmap;
+	struct snd_soc_component *component;
+	struct snd_soc_jack *jack;
+	int irq;
 	unsigned int sysclk;
 	unsigned int allowed_rates[NR_SUPPORTED_MCLK_LRCK_RATIOS];
 	struct snd_pcm_hw_constraint_list sysclk_constraints;
@@ -529,8 +536,162 @@ static struct snd_soc_dai_driver es8316_dai = {
 	.symmetric_rates = 1,
 };
 
+static void es8316_enable_micbias_for_mic_gnd_short_detect(
+	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, "Bias");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Mic Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	msleep(20);
+}
+
+static void es8316_disable_micbias_for_mic_gnd_short_detect(
+	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, "Mic Bias");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static irqreturn_t es8316_irq(int irq, void *data)
+{
+	struct es8316_priv *es8316 = data;
+	struct snd_soc_component *comp = es8316->component;
+	unsigned int flags;
+
+	mutex_lock(&es8316->lock);
+
+	regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+	if (flags == 0x00)
+		goto out; /* Powered-down / reset */
+
+	/* Catch spurious IRQ before set_jack is called */
+	if (!es8316->jack)
+		goto out;
+
+	dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+	if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+		/* Jack removed, or spurious IRQ? */
+		if (es8316->jack->status & SND_JACK_MICROPHONE)
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+
+		if (es8316->jack->status & SND_JACK_HEADPHONE) {
+			snd_soc_jack_report(es8316->jack, 0,
+					    SND_JACK_HEADSET | SND_JACK_BTN_0);
+			dev_dbg(comp->dev, "jack unplugged\n");
+		}
+	} else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
+		/* Jack inserted, determine type */
+		es8316_enable_micbias_for_mic_gnd_short_detect(comp);
+		regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+		dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+		if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+			/* Jack unplugged underneath us */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		} else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, headset */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADSET,
+					    SND_JACK_HEADSET);
+			/* Keep mic-gnd-short detection on for button press */
+		} else {
+			/* Shorted, headphones */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADPHONE,
+					    SND_JACK_HEADSET);
+			/* No longer need mic-gnd-short detection */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		}
+	} else if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		/* Interrupt while jack inserted, report button state */
+		if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, button release */
+			snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+		} else {
+			/* Short, button press */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_BTN_0,
+					    SND_JACK_BTN_0);
+		}
+	}
+
+out:
+	mutex_unlock(&es8316->lock);
+	return IRQ_HANDLED;
+}
+
+static void es8316_enable_jack_detect(struct snd_soc_component *component,
+				      struct snd_soc_jack *jack)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	mutex_lock(&es8316->lock);
+
+	es8316->jack = jack;
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE)
+		es8316_enable_micbias_for_mic_gnd_short_detect(component);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT,
+				      ES8316_GPIO_ENABLE_INTERRUPT);
+
+	mutex_unlock(&es8316->lock);
+
+	/* Enable irq and sync initial jack state */
+	enable_irq(es8316->irq);
+	es8316_irq(es8316->irq, es8316);
+}
+
+static void es8316_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	disable_irq(es8316->irq);
+
+	mutex_lock(&es8316->lock);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT, 0);
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		es8316_disable_micbias_for_mic_gnd_short_detect(component);
+		snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+	}
+
+	es8316->jack = NULL;
+
+	mutex_unlock(&es8316->lock);
+}
+
+static int es8316_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *jack, void *data)
+{
+	if (jack)
+		es8316_enable_jack_detect(component, jack);
+	else
+		es8316_disable_jack_detect(component);
+
+	return 0;
+}
+
 static int es8316_probe(struct snd_soc_component *component)
 {
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	es8316->component = component;
+
 	/* Reset codec and enable current state machine */
 	snd_soc_component_write(component, ES8316_RESET, 0x3f);
 	usleep_range(5000, 5500);
@@ -555,6 +716,7 @@ static int es8316_probe(struct snd_soc_component *component)
 
 static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.probe			= es8316_probe,
+	.set_jack		= es8316_set_jack,
 	.controls		= es8316_snd_controls,
 	.num_controls		= ARRAY_SIZE(es8316_snd_controls),
 	.dapm_widgets		= es8316_dapm_widgets,
@@ -566,18 +728,29 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.non_legacy_dai_naming	= 1,
 };
 
+static const struct regmap_range es8316_volatile_ranges[] = {
+	regmap_reg_range(ES8316_GPIO_FLAG, ES8316_GPIO_FLAG),
+};
+
+static const struct regmap_access_table es8316_volatile_table = {
+	.yes_ranges	= es8316_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(es8316_volatile_ranges),
+};
+
 static const struct regmap_config es8316_regmap = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = 0x53,
+	.volatile_table	= &es8316_volatile_table,
 	.cache_type = REGCACHE_RBTREE,
 };
 
 static int es8316_i2c_probe(struct i2c_client *i2c_client,
 			    const struct i2c_device_id *id)
 {
+	struct device *dev = &i2c_client->dev;
 	struct es8316_priv *es8316;
-	struct regmap *regmap;
+	int ret;
 
 	es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
 			      GFP_KERNEL);
@@ -586,9 +759,23 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client,
 
 	i2c_set_clientdata(i2c_client, es8316);
 
-	regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
-	if (IS_ERR(regmap))
-		return PTR_ERR(regmap);
+	es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
+	if (IS_ERR(es8316->regmap))
+		return PTR_ERR(es8316->regmap);
+
+	es8316->irq = i2c_client->irq;
+	mutex_init(&es8316->lock);
+
+	ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
+					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					"es8316", es8316);
+	if (ret == 0) {
+		/* Gets re-enabled by es8316_set_jack() */
+		disable_irq(es8316->irq);
+	} else {
+		dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
+		es8316->irq = -ENXIO;
+	}
 
 	return devm_snd_soc_register_component(&i2c_client->dev,
 				      &soc_component_dev_es8316,
diff --git a/sound/soc/codecs/es8316.h b/sound/soc/codecs/es8316.h
index 6bcdd63ea459..439a0130cbb7 100644
--- a/sound/soc/codecs/es8316.h
+++ b/sound/soc/codecs/es8316.h
@@ -126,4 +126,11 @@
 #define ES8316_SERDATA2_LEN_16		0x0c
 #define ES8316_SERDATA2_LEN_32		0x10
 
+/* ES8316_GPIO_DEBOUNCE	*/
+#define ES8316_GPIO_ENABLE_INTERRUPT		0x02
+
+/* ES8316_GPIO_FLAG */
+#define ES8316_GPIO_FLAG_GM_NOT_SHORTED		0x02
+#define ES8316_GPIO_FLAG_HP_NOT_INSERTED	0x04
+
 #endif
-- 
2.20.1

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

* [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
  2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:09   ` Applied "ASoC: es8316: Add DAC mono mix switch mixer control" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically Hans de Goede
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Export the DAC functionality to mix left + right together and then output
the same (mixed) signal on both outputs.

Various (x86) tablets with an ES8316 codec use a single speaker
connected between the headhpone LOUT and ROUT pins, expecting the output
to be in a mono differential mode. Presumably this is done to use the
power of both the left and right outputs to allow the speaker to be
louder.

The ES8316 codec does not have a differential output mode, but we can
emulate this by making both channels output the same through the mono mix
switch, combined with setting the Playback Polarity control to "R Invert",
which applias a 180 degrees phase inversion to the right channel.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index 26413851e434..98464ba1046c 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -101,6 +101,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = {
 	SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2, 6, 1, 0),
 	SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2, 7, 1, 0),
 	SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3, 0, 7, 0),
+	SOC_SINGLE("DAC Mono Mix Switch", ES8316_DAC_SET3, 3, 1, 0),
 
 	SOC_ENUM("Capture Polarity", adcpol),
 	SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA, 0, 1, 0),
-- 
2.20.1

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

* [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
  2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
  2019-01-03 13:45 ` [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Sort includes alphabetically" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring Hans de Goede
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

For lack of a better (non-random) way of sorting includes more and more
files in the kernel are moving over to sorting the includes alphabetically.

Move the bytcht_es8316 driver over to this sorting before we add a
bunch of more includes.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index adc26dfc7d65..5d8ecc100766 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,13 +19,13 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/clk.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/device.h>
 #include <linux/slab.h>
 #include <asm/platform_sst_audio.h>
-#include <linux/clk.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
-- 
2.20.1

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

* [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (2 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Minor refactoring" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR) Hans de Goede
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Some minor refactoring:
1) Group the code setting the card dev and prive pointers together with
   registering the card
2) Properly put the comment about registering the card at the place where
   we actually register the card and add a new comment for getting the clk
3) Add a struct device *dev helper variable (this will be used more in
   follow up commits)
4) Reword error message to have the same "foo failed: %d" wording as others

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 5d8ecc100766..e29f00560b00 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -237,17 +237,18 @@ static char codec_name[SND_ACPI_I2C_ID_LEN];
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
+	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	mach = (&pdev->dev)->platform_data;
+	mach = dev->platform_data;
 	/* fix index of codec dai */
 	for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
 		if (!strcmp(byt_cht_es8316_dais[i].codec_name,
@@ -265,26 +266,25 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
-	/* register the soc card */
-	byt_cht_es8316_card.dev = &pdev->dev;
-	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
-
-	priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+	/* get the clock */
+	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
 		ret = PTR_ERR(priv->mclk);
-		dev_err(&pdev->dev,
-			"Failed to get MCLK from pmc_plt_clk_3: %d\n",
-			ret);
+		dev_err(dev, "clk_get pmc_plt_clk_3 failed: %d\n", ret);
 		return ret;
 	}
 
-	ret = devm_snd_soc_register_card(&pdev->dev, &byt_cht_es8316_card);
+	/* register the soc card */
+	byt_cht_es8316_card.dev = dev;
+	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
-		dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
+		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
 	platform_set_drvdata(pdev, &byt_cht_es8316_card);
-	return ret;
+	return 0;
 }
 
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
-- 
2.20.1

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

* [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (3 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support Hans de Goede
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Add support for having the codec connected to SSP0 instead of SSP2. This
is controlled through a new quirk parameter, similar to how this is done
in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Bay Trail CR (cost reduced) SoCs do not have an SSP2, so we default to SSP0
there.

Note the SPP0 quirk gets BIT(16) because bits 0-15 are reserved for non
boolean quirks like the input-map added in a later commit in this series.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index e29f00560b00..3358d82499a3 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -37,6 +39,20 @@ struct byt_cht_es8316_private {
 	struct clk *mclk;
 };
 
+#define BYT_CHT_ES8316_SSP0			BIT(16)
+
+static int quirk;
+
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
+static void log_quirks(struct device *dev)
+{
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		dev_info(dev, "quirk SSP0 enabled");
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
 
@@ -55,7 +71,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
+	{"Playback", NULL, "ssp0 Tx"},
+	{"ssp0 Tx", NULL, "modem_out"},
+	{"modem_in", NULL, "ssp0 Rx"},
+	{"ssp0 Rx", NULL, "Capture"},
+};
 
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 	{"Playback", NULL, "ssp2 Tx"},
 	{"ssp2 Tx", NULL, "codec_out0"},
 	{"ssp2 Tx", NULL, "codec_out1"},
@@ -74,10 +99,23 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	const struct snd_soc_dapm_route *custom_map;
+	int num_routes;
 	int ret;
 
 	card->dapm.idle_bias_off = true;
 
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		custom_map = byt_cht_es8316_ssp0_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
+	} else {
+		custom_map = byt_cht_es8316_ssp2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map);
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	/*
 	 * The firmware might enable the clock at boot (this information
 	 * may or may not be reflected in the enable clock register).
@@ -123,14 +161,21 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 			SNDRV_PCM_HW_PARAM_RATE);
 	struct snd_interval *channels = hw_param_interval(params,
 						SNDRV_PCM_HW_PARAM_CHANNELS);
-	int ret;
+	int ret, bits;
 
 	/* The DSP will covert the FE rate to 48k, stereo */
 	rate->min = rate->max = 48000;
 	channels->min = channels->max = 2;
 
-	/* set SSP2 to 24-bit */
-	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		/* set SSP0 to 16-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+		bits = 16;
+	} else {
+		/* set SSP2 to 24-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+		bits = 24;
+	}
 
 	/*
 	 * Default mode for SSP configuration is TDM 4 slot, override config
@@ -147,7 +192,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 		return ret;
 	}
 
-	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
 	if (ret < 0) {
 		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 		return ret;
@@ -232,6 +277,11 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.fully_routed = true,
 };
 
+static const struct x86_cpu_id baytrail_cpu_ids[] = {
+	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
+	{}
+};
+
 static char codec_name[SND_ACPI_I2C_ID_LEN];
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
@@ -266,6 +316,24 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
+	/* Check for BYTCR or other platform and setup quirks */
+	if (x86_match_cpu(baytrail_cpu_ids) &&
+	    mach->mach_params.acpi_ipc_irq_index == 0) {
+		/* On BYTCR default to SSP0 */
+		quirk = BYT_CHT_ES8316_SSP0;
+	} else {
+		quirk = 0;
+	}
+	if (quirk_override != -1) {
+		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
+			 quirk_override);
+		quirk = quirk_override;
+	}
+	log_quirks(dev);
+
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		byt_cht_es8316_dais[dai_index].cpu_dai_name = "ssp0-port";
+
 	/* get the clock */
 	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
-- 
2.20.1

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

* [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (4 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR) Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add jack-detect support" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support Hans de Goede
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Hookup the jack-detect support added to the codec driver.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 3358d82499a3..905dd6904710 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -22,12 +22,14 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -37,6 +39,7 @@
 
 struct byt_cht_es8316_private {
 	struct clk *mclk;
+	struct snd_soc_jack jack;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -55,6 +58,7 @@ static void log_quirks(struct device *dev)
 
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
 	/*
 	 * The codec supports two analog microphone inputs. I have only
@@ -68,6 +72,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"MIC1", NULL, "Microphone 1"},
 	{"MIC2", NULL, "Microphone 2"},
+	{"MIC1", NULL, "Headset Mic"},
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
@@ -91,12 +96,25 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Headphone"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
 	SOC_DAPM_PIN_SWITCH("Microphone 2"),
 };
 
+static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+	{
+		.pin	= "Headphone",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Mic",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
 static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
+	struct snd_soc_component *codec = runtime->codec_dai->component;
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
 	const struct snd_soc_dapm_route *custom_map;
@@ -143,6 +161,18 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
+	ret = snd_soc_card_jack_new(card, "Headset",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0,
+				    &priv->jack, byt_cht_es8316_jack_pins,
+				    ARRAY_SIZE(byt_cht_es8316_jack_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(codec, &priv->jack, NULL);
+
 	return 0;
 }
 
@@ -263,6 +293,39 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 
 /* SoC card */
+static char codec_name[SND_ACPI_I2C_ID_LEN];
+
+static int byt_cht_es8316_suspend(struct snd_soc_card *card)
+{
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_resume(struct snd_soc_card *card)
+{
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_card = {
 	.name = "bytcht-es8316",
 	.owner = THIS_MODULE,
@@ -275,6 +338,8 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.controls = byt_cht_es8316_controls,
 	.num_controls = ARRAY_SIZE(byt_cht_es8316_controls),
 	.fully_routed = true,
+	.suspend_pre = byt_cht_es8316_suspend,
+	.resume_post = byt_cht_es8316_resume,
 };
 
 static const struct x86_cpu_id baytrail_cpu_ids[] = {
@@ -282,8 +347,6 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
-static char codec_name[SND_ACPI_I2C_ID_LEN];
-
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
-- 
2.20.1

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

* [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (5 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add external speaker mux support" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support Hans de Goede
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

The ES8316 only has a single (amplified) output. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects the
speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail devices and
one Bay Trail CR device), use an analog mux to disconnect the speakers,
driven by a GPIO.

This commit adds support for this, modelling this as a separate speaker
widget / dapm pin-switch which sets the mux to drive the speakers when
selected.

The intend is for userspace to use the recently added jack-detect support
and then automatically select either the Headphone or Speaker output based
on that.

Note this commit includes a workaround for an ACPI table bug which is
present on 2 of the 3 devices I have, see the added comment in the code.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 905dd6904710..8e504fca4624 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,8 +19,11 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/module.h>
@@ -40,6 +43,8 @@
 struct byt_cht_es8316_private {
 	struct clk *mclk;
 	struct snd_soc_jack jack;
+	struct gpio_desc *speaker_en_gpio;
+	bool speaker_en;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -56,7 +61,24 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk SSP0 enabled");
 }
 
+static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = w->dapm->card;
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		priv->speaker_en = true;
+	else
+		priv->speaker_en = false;
+
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
+	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
@@ -67,6 +89,10 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	 */
 	SND_SOC_DAPM_MIC("Microphone 1", NULL),
 	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+
+	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
+			    byt_cht_es8316_speaker_power_event,
+			    SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
@@ -76,6 +102,14 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+
+	/*
+	 * There is no separate speaker output instead the speakers are muxed to
+	 * the HP outputs. The mux is controlled by the "Speaker Power" supply.
+	 */
+	{"Speaker", NULL, "HPOL"},
+	{"Speaker", NULL, "HPOR"},
+	{"Speaker", NULL, "Speaker Power"},
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
@@ -95,6 +129,7 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 };
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
@@ -323,6 +358,25 @@ static int byt_cht_es8316_resume(struct snd_soc_card *card)
 		}
 	}
 
+	/*
+	 * Some Cherry Trail boards with an ES8316 codec have a bug in their
+	 * ACPI tables where the MSSL1680 touchscreen's _PS0 and _PS3 methods
+	 * wrongly also set the speaker-enable GPIO to 1/0. Testing has shown
+	 * that this really is a bug and the GPIO has no influence on the
+	 * touchscreen at all.
+	 *
+	 * The silead.c touchscreen driver does not support runtime suspend, so
+	 * the GPIO can only be changed underneath us during a system suspend.
+	 * This resume() function runs from a pm complete() callback, and thus
+	 * is guaranteed to run after the touchscreen driver/ACPI-subsys has
+	 * brought the touchscreen back up again (and thus changed the GPIO).
+	 *
+	 * So to work around this we pass GPIOD_FLAGS_BIT_NONEXCLUSIVE when
+	 * requesting the GPIO and we set its value here to undo any changes
+	 * done by the touchscreen's broken _PS0 ACPI method.
+	 */
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
 	return 0;
 }
 
@@ -347,12 +401,20 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
+static const struct acpi_gpio_params first_gpio = { 0, 0, false };
+
+static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
+	{ "speaker-enable-gpios", &first_gpio, 1 },
+	{ },
+};
+
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
+	struct device *codec_dev;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
@@ -405,12 +467,39 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* get speaker enable GPIO */
+	codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
+	if (!codec_dev)
+		return -EPROBE_DEFER;
+
+	devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
+	priv->speaker_en_gpio =
+		gpiod_get_index(codec_dev, "speaker-enable", 0,
+				/* see comment in byt_cht_es8316_resume */
+				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+	put_device(codec_dev);
+
+	if (IS_ERR(priv->speaker_en_gpio)) {
+		ret = PTR_ERR(priv->speaker_en_gpio);
+		switch (ret) {
+		case -ENOENT:
+			priv->speaker_en_gpio = NULL;
+			break;
+		default:
+			dev_err(dev, "get speaker GPIO failed: %d\n", ret);
+			/* fall through */
+		case -EPROBE_DEFER:
+			return ret;
+		}
+	}
+
 	/* register the soc card */
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
 	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
+		gpiod_put(priv->speaker_en_gpio);
 		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
@@ -418,11 +507,20 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+{
+	struct byt_cht_es8316_private *priv = platform_get_drvdata(pdev);
+
+	gpiod_put(priv->speaker_en_gpio);
+	return 0;
+}
+
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
 	.driver = {
 		.name = "bytcht_es8316",
 	},
 	.probe = snd_byt_cht_es8316_mc_probe,
+	.remove = snd_byt_cht_es8316_mc_remove,
 };
 
 module_platform_driver(snd_byt_cht_es8316_mc_driver);
-- 
2.20.1

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

* [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (6 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add input-map support" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks Hans de Goede
                   ` (2 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

After adding jack-detect support we have 3 microphone input switches:
"Microphone 1", "Microphone 2" and "Headset Mic". But the ES8316 has only
2 microphone inputs.

In the app-note explaining how to use the codec and on the 3 boards I
have one input is used for an internal microphone and one for the headset
microphone. On the 2 CHT boards I have the internal mic is on on MIC1 and
the headset mic is on MIC2, on the BYTCR board I have it is the other way
around.

This commit replaces the 2 "Microphone 1" and "Microphone 2" input switches
with a single "Internal Mic" switch and adds support for selecting either
possible input mapping.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 8e504fca4624..941a66f94660 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -47,6 +47,12 @@ struct byt_cht_es8316_private {
 	bool speaker_en;
 };
 
+enum {
+	BYT_CHT_ES8316_INTMIC_IN1_MAP,
+	BYT_CHT_ES8316_INTMIC_IN2_MAP,
+};
+
+#define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
 
 static int quirk;
@@ -57,6 +63,10 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 
 static void log_quirks(struct device *dev)
 {
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP)
+		dev_info(dev, "quirk IN1_MAP enabled");
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP)
+		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
 }
@@ -81,14 +91,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
-	/*
-	 * The codec supports two analog microphone inputs. I have only
-	 * tested MIC1. A DMIC route could also potentially be added
-	 * if such functionality is found on another platform.
-	 */
-	SND_SOC_DAPM_MIC("Microphone 1", NULL),
-	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+	SND_SOC_DAPM_MIC("Internal Mic", NULL),
 
 	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
 			    byt_cht_es8316_speaker_power_event,
@@ -96,10 +99,6 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
-	{"MIC1", NULL, "Microphone 1"},
-	{"MIC2", NULL, "Microphone 2"},
-	{"MIC1", NULL, "Headset Mic"},
-
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
 
@@ -112,6 +111,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"Speaker", NULL, "Speaker Power"},
 };
 
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in1_map[] = {
+	{"MIC1", NULL, "Internal Mic"},
+	{"MIC2", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in2_map[] = {
+	{"MIC2", NULL, "Internal Mic"},
+	{"MIC1", NULL, "Headset Mic"},
+};
+
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
 	{"Playback", NULL, "ssp0 Tx"},
 	{"ssp0 Tx", NULL, "modem_out"},
@@ -132,8 +141,7 @@ static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
-	SOC_DAPM_PIN_SWITCH("Microphone 1"),
-	SOC_DAPM_PIN_SWITCH("Microphone 2"),
+	SOC_DAPM_PIN_SWITCH("Internal Mic"),
 };
 
 static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
@@ -158,6 +166,21 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	switch (BYT_CHT_ES8316_MAP(quirk)) {
+	case BYT_CHT_ES8316_INTMIC_IN1_MAP:
+	default:
+		custom_map = byt_cht_es8316_intmic_in1_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in1_map);
+		break;
+	case BYT_CHT_ES8316_INTMIC_IN2_MAP:
+		custom_map = byt_cht_es8316_intmic_in2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in2_map);
+		break;
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	if (quirk & BYT_CHT_ES8316_SSP0) {
 		custom_map = byt_cht_es8316_ssp0_map;
 		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
@@ -444,10 +467,11 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0 */
-		quirk = BYT_CHT_ES8316_SSP0;
+		/* On BYTCR default to SSP0, internal-mic-in2-map */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
 	} else {
-		quirk = 0;
+		/* Others default to internal-mic-in1-map */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
-- 
2.20.1

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

* [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (7 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Set card long_name based on quirks" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
  2019-01-03 17:05 ` [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Pierre-Louis Bossart
  10 siblings, 2 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Depending on the input-map and on if 1 or 2 speakers are connected,
userspace needs to use a different UCM profile.

Since we already deal with quirks in the kernel driver and set the
input-map from the kernel, add a quirk for devices with a single / mono
speaker and set the card's long_name based on the input and speaker
quirks, so that userspace can use the long_name to pick the right UCM
profile.

This change, including how the long_name is build-up mirrors how we do
this in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Note since all devices I have access to use a mono speaker setup I've
chosen to default the speaker setting to mono.

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

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 941a66f94660..cdf2061e7613 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -54,6 +54,7 @@ enum {
 
 #define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
+#define BYT_CHT_ES8316_MONO_SPEAKER		BIT(17)
 
 static int quirk;
 
@@ -69,6 +70,8 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
+	if (quirk & BYT_CHT_ES8316_MONO_SPEAKER)
+		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 }
 
 static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
@@ -352,6 +355,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 /* SoC card */
 static char codec_name[SND_ACPI_I2C_ID_LEN];
+static char long_name[50]; /* = "bytcht-es8316-*-spk-*-mic" */
 
 static int byt_cht_es8316_suspend(struct snd_soc_card *card)
 {
@@ -433,6 +437,7 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
+	const char * const mic_name[] = { "in1", "in2" };
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
@@ -467,11 +472,13 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0, internal-mic-in2-map */
-		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
+		/* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	} else {
-		/* Others default to internal-mic-in1-map */
-		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
+		/* Others default to internal-mic-in1-map, mono-speaker */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
@@ -518,6 +525,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	}
 
 	/* register the soc card */
+	snprintf(long_name, sizeof(long_name), "bytcht-es8316-%s-spk-%s-mic",
+		 (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo",
+		 mic_name[BYT_CHT_ES8316_MAP(quirk)]);
+	byt_cht_es8316_card.long_name = long_name;
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
-- 
2.20.1

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

* [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (8 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks Hans de Goede
@ 2019-01-03 13:45 ` Hans de Goede
  2019-01-03 16:43   ` Pierre-Louis Bossart
                     ` (2 more replies)
  2019-01-03 17:05 ` [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Pierre-Louis Bossart
  10 siblings, 3 replies; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 13:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: Hans de Goede, alsa-devel, linux, Daniel Drake

Some BYTCR devices use an ES8316 codec, add an ACPI match table entry
for this.

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

diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
index 027dc27262b7..96f9c553fe6c 100644
--- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
@@ -185,6 +185,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
 		.sof_tplg_filename = "intel/sof-byt-da7213.tplg",
 		.asoc_plat_name = "sst-mfld-platform",
 	},
+	{
+		.id = "ESSX8316",
+		.drv_name = "bytcht_es8316",
+		.fw_filename = "intel/fw_sst_0f28.bin",
+		.board = "bytcht_es8316",
+		.sof_fw_filename = "intel/sof-byt.ri",
+		.sof_tplg_filename = "intel/sof-byt-es8316.tplg",
+		.asoc_plat_name = "sst-mfld-platform",
+	},
 	/* some Baytrail platforms rely on RT5645, use CHT machine driver */
 	{
 		.id = "10EC5645",
-- 
2.20.1

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

* Re: [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform
  2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
@ 2019-01-03 16:43   ` Pierre-Louis Bossart
  2019-01-03 16:45     ` Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform" to the asoc tree Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2 siblings, 1 reply; 35+ messages in thread
From: Pierre-Louis Bossart @ 2019-01-03 16:43 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown; +Cc: alsa-devel, linux, Daniel Drake


On 1/3/19 7:45 AM, Hans de Goede wrote:
> Some BYTCR devices use an ES8316 codec, add an ACPI match table entry
> for this.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>   sound/soc/intel/common/soc-acpi-intel-byt-match.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
>
> diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
> index 027dc27262b7..96f9c553fe6c 100644
> --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c
> +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
> @@ -185,6 +185,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
>   		.sof_tplg_filename = "intel/sof-byt-da7213.tplg",
>   		.asoc_plat_name = "sst-mfld-platform",
>   	},
> +	{
> +		.id = "ESSX8316",
> +		.drv_name = "bytcht_es8316",
> +		.fw_filename = "intel/fw_sst_0f28.bin",
> +		.board = "bytcht_es8316",

Coming from the holiday break I saw this .board field and couldn't 
recall why we needed it. None of the more recent boards set this field. 
Is this legacy stuff that isn't used by anyone?


> +		.sof_fw_filename = "intel/sof-byt.ri",
> +		.sof_tplg_filename = "intel/sof-byt-es8316.tplg",
> +		.asoc_plat_name = "sst-mfld-platform",
> +	},
>   	/* some Baytrail platforms rely on RT5645, use CHT machine driver */
>   	{
>   		.id = "10EC5645",

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

* Re: [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform
  2019-01-03 16:43   ` Pierre-Louis Bossart
@ 2019-01-03 16:45     ` Hans de Goede
  2019-01-03 17:04       ` Pierre-Louis Bossart
  0 siblings, 1 reply; 35+ messages in thread
From: Hans de Goede @ 2019-01-03 16:45 UTC (permalink / raw)
  To: Pierre-Louis Bossart, Liam Girdwood, Mark Brown
  Cc: alsa-devel, linux, Daniel Drake

Hi,

On 03-01-19 17:43, Pierre-Louis Bossart wrote:
> 
> On 1/3/19 7:45 AM, Hans de Goede wrote:
>> Some BYTCR devices use an ES8316 codec, add an ACPI match table entry
>> for this.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   sound/soc/intel/common/soc-acpi-intel-byt-match.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
>> index 027dc27262b7..96f9c553fe6c 100644
>> --- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c
>> +++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
>> @@ -185,6 +185,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
>>           .sof_tplg_filename = "intel/sof-byt-da7213.tplg",
>>           .asoc_plat_name = "sst-mfld-platform",
>>       },
>> +    {
>> +        .id = "ESSX8316",
>> +        .drv_name = "bytcht_es8316",
>> +        .fw_filename = "intel/fw_sst_0f28.bin",
>> +        .board = "bytcht_es8316",
> 
> Coming from the holiday break I saw this .board field and couldn't recall why we needed it. None of the more recent boards set this field. Is this legacy stuff that isn't used by anyone?

I would expect you to know that better then I do :)  I just copied this from the
other entries.

If you want to submit a patch removing the .board entries I'm all for it.

Regards,

Hans



> 
> 
>> +        .sof_fw_filename = "intel/sof-byt.ri",
>> +        .sof_tplg_filename = "intel/sof-byt-es8316.tplg",
>> +        .asoc_plat_name = "sst-mfld-platform",
>> +    },
>>       /* some Baytrail platforms rely on RT5645, use CHT machine driver */
>>       {
>>           .id = "10EC5645",
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

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

* Re: [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform
  2019-01-03 16:45     ` Hans de Goede
@ 2019-01-03 17:04       ` Pierre-Louis Bossart
  0 siblings, 0 replies; 35+ messages in thread
From: Pierre-Louis Bossart @ 2019-01-03 17:04 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown; +Cc: alsa-devel, linux, Daniel Drake


>>>       },
>>> +    {
>>> +        .id = "ESSX8316",
>>> +        .drv_name = "bytcht_es8316",
>>> +        .fw_filename = "intel/fw_sst_0f28.bin",
>>> +        .board = "bytcht_es8316",
>>
>> Coming from the holiday break I saw this .board field and couldn't 
>> recall why we needed it. None of the more recent boards set this 
>> field. Is this legacy stuff that isn't used by anyone?
>
> I would expect you to know that better then I do :)  I just copied 
> this from the
> other entries.

I don't, it's at least 5 years old....

The initial tables in atom/sst/sst_acpi.c had this (April 2015).

+static struct sst_machines sst_acpi_bytcr[] = {
+    {"10EC5640", "T100", "bytt100_rt5640", NULL, "intel/fw_sst_0f28.bin",
+                        &byt_rvp_platform_data },
+    {},
+};

then it became

+static struct sst_acpi_mach sst_acpi_bytcr[] = {
+    {"10EC5640", "bytt100_rt5640", "intel/fw_sst_0f28.bin", "T100", NULL,

then

  static struct sst_acpi_mach sst_acpi_bytcr[] = {
-    {"10EC5640", "bytt100_rt5640", "intel/fw_sst_0f28.bin", "T100", NULL,
+    {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", 
"bytcr_rt5640", NULL,
                          &byt_rvp_platform_data },

and then

+    {
+        .id = "10EC5640",
+        .drv_name = "bytcr_rt5640",
+        .fw_filename = "intel/fw_sst_0f28.bin",
+        .board = "bytcr_rt5640",
+        .machine_quirk = byt_quirk,
+        .pdata = &byt_rvp_platform_data,
+    },

we only use the drv_name to select the machine driver.

Keyon, Liam, do you have any memories of why this board field was needed 
in the first place?

>
> If you want to submit a patch removing the .board entries I'm all for it.

I was planning to remove the new_mach_data already so this is the second 
strike on this soc_acpi_machine structure...

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

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

* Re: [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements
  2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
                   ` (9 preceding siblings ...)
  2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
@ 2019-01-03 17:05 ` Pierre-Louis Bossart
  10 siblings, 0 replies; 35+ messages in thread
From: Pierre-Louis Bossart @ 2019-01-03 17:05 UTC (permalink / raw)
  To: Hans de Goede, Liam Girdwood, Mark Brown; +Cc: alsa-devel, linux, Daniel Drake


On 1/3/19 7:45 AM, Hans de Goede wrote:
> Hi All,
>
> Here is a patch series which makes all the sound out and inputs on the
> 1 BYT + ES8316 and 2 CHT + ES8316 devices which I have fully work.
>
Patches for the Intel parts (3..10)

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

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

* Applied "ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform" to the asoc tree
  2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
  2019-01-03 16:43   ` Pierre-Louis Bossart
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  2 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform

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 5198baf8817d7e6e0fe2f3e74ea2ead714b74d9c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:35 +0100
Subject: [PATCH] ASoC: Intel: Add ACPI match table entry for ES8316 codec on
 BYTCR platform

Some BYTCR devices use an ES8316 codec, add an ACPI match table entry
for this.

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/common/soc-acpi-intel-byt-match.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
index 097dc06377ba..47a90909b956 100644
--- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
@@ -154,6 +154,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
 		.sof_tplg_filename = "intel/sof-byt-da7213.tplg",
 		.asoc_plat_name = "sst-mfld-platform",
 	},
+	{
+		.id = "ESSX8316",
+		.drv_name = "bytcht_es8316",
+		.fw_filename = "intel/fw_sst_0f28.bin",
+		.board = "bytcht_es8316",
+		.sof_fw_filename = "intel/sof-byt.ri",
+		.sof_tplg_filename = "intel/sof-byt-es8316.tplg",
+		.asoc_plat_name = "sst-mfld-platform",
+	},
 	/* some Baytrail platforms rely on RT5645, use CHT machine driver */
 	{
 		.id = "10EC5645",
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Set card long_name based on quirks" to the asoc tree
  2019-01-03 13:45 ` [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: 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 249d2fc9e55c324dda968252ea3ad0ac21c72b8f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:34 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Set card long_name based on
 quirks

Depending on the input-map and on if 1 or 2 speakers are connected,
userspace needs to use a different UCM profile.

Since we already deal with quirks in the kernel driver and set the
input-map from the kernel, add a quirk for devices with a single / mono
speaker and set the card's long_name based on the input and speaker
quirks, so that userspace can use the long_name to pick the right UCM
profile.

This change, including how the long_name is build-up mirrors how we do
this in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Note since all devices I have access to use a mono speaker setup I've
chosen to default the speaker setting to mono.

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/bytcht_es8316.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 941a66f94660..cdf2061e7613 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -54,6 +54,7 @@ enum {
 
 #define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
+#define BYT_CHT_ES8316_MONO_SPEAKER		BIT(17)
 
 static int quirk;
 
@@ -69,6 +70,8 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
+	if (quirk & BYT_CHT_ES8316_MONO_SPEAKER)
+		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 }
 
 static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
@@ -352,6 +355,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 /* SoC card */
 static char codec_name[SND_ACPI_I2C_ID_LEN];
+static char long_name[50]; /* = "bytcht-es8316-*-spk-*-mic" */
 
 static int byt_cht_es8316_suspend(struct snd_soc_card *card)
 {
@@ -433,6 +437,7 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
+	const char * const mic_name[] = { "in1", "in2" };
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
@@ -467,11 +472,13 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0, internal-mic-in2-map */
-		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
+		/* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	} else {
-		/* Others default to internal-mic-in1-map */
-		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
+		/* Others default to internal-mic-in1-map, mono-speaker */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
@@ -518,6 +525,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	}
 
 	/* register the soc card */
+	snprintf(long_name, sizeof(long_name), "bytcht-es8316-%s-spk-%s-mic",
+		 (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo",
+		 mic_name[BYT_CHT_ES8316_MAP(quirk)]);
+	byt_cht_es8316_card.long_name = long_name;
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add input-map support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add input-map 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 730501a91d94b652275e049e101ed44cdbfdf31b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:33 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add input-map support

After adding jack-detect support we have 3 microphone input switches:
"Microphone 1", "Microphone 2" and "Headset Mic". But the ES8316 has only
2 microphone inputs.

In the app-note explaining how to use the codec and on the 3 boards I
have one input is used for an internal microphone and one for the headset
microphone. On the 2 CHT boards I have the internal mic is on on MIC1 and
the headset mic is on MIC2, on the BYTCR board I have it is the other way
around.

This commit replaces the 2 "Microphone 1" and "Microphone 2" input switches
with a single "Internal Mic" switch and adds support for selecting either
possible input mapping.

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/bytcht_es8316.c | 58 ++++++++++++++++++--------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 8e504fca4624..941a66f94660 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -47,6 +47,12 @@ struct byt_cht_es8316_private {
 	bool speaker_en;
 };
 
+enum {
+	BYT_CHT_ES8316_INTMIC_IN1_MAP,
+	BYT_CHT_ES8316_INTMIC_IN2_MAP,
+};
+
+#define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
 
 static int quirk;
@@ -57,6 +63,10 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 
 static void log_quirks(struct device *dev)
 {
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP)
+		dev_info(dev, "quirk IN1_MAP enabled");
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP)
+		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
 }
@@ -81,14 +91,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
-	/*
-	 * The codec supports two analog microphone inputs. I have only
-	 * tested MIC1. A DMIC route could also potentially be added
-	 * if such functionality is found on another platform.
-	 */
-	SND_SOC_DAPM_MIC("Microphone 1", NULL),
-	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+	SND_SOC_DAPM_MIC("Internal Mic", NULL),
 
 	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
 			    byt_cht_es8316_speaker_power_event,
@@ -96,10 +99,6 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
-	{"MIC1", NULL, "Microphone 1"},
-	{"MIC2", NULL, "Microphone 2"},
-	{"MIC1", NULL, "Headset Mic"},
-
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
 
@@ -112,6 +111,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"Speaker", NULL, "Speaker Power"},
 };
 
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in1_map[] = {
+	{"MIC1", NULL, "Internal Mic"},
+	{"MIC2", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in2_map[] = {
+	{"MIC2", NULL, "Internal Mic"},
+	{"MIC1", NULL, "Headset Mic"},
+};
+
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
 	{"Playback", NULL, "ssp0 Tx"},
 	{"ssp0 Tx", NULL, "modem_out"},
@@ -132,8 +141,7 @@ static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
-	SOC_DAPM_PIN_SWITCH("Microphone 1"),
-	SOC_DAPM_PIN_SWITCH("Microphone 2"),
+	SOC_DAPM_PIN_SWITCH("Internal Mic"),
 };
 
 static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
@@ -158,6 +166,21 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	switch (BYT_CHT_ES8316_MAP(quirk)) {
+	case BYT_CHT_ES8316_INTMIC_IN1_MAP:
+	default:
+		custom_map = byt_cht_es8316_intmic_in1_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in1_map);
+		break;
+	case BYT_CHT_ES8316_INTMIC_IN2_MAP:
+		custom_map = byt_cht_es8316_intmic_in2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in2_map);
+		break;
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	if (quirk & BYT_CHT_ES8316_SSP0) {
 		custom_map = byt_cht_es8316_ssp0_map;
 		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
@@ -444,10 +467,11 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0 */
-		quirk = BYT_CHT_ES8316_SSP0;
+		/* On BYTCR default to SSP0, internal-mic-in2-map */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
 	} else {
-		quirk = 0;
+		/* Others default to internal-mic-in1-map */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add external speaker mux support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add external speaker mux 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 0d3e91da0750835cfd5c16487ffb3cdd752ea53a Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:32 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add external speaker mux support

The ES8316 only has a single (amplified) output. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects the
speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail devices and
one Bay Trail CR device), use an analog mux to disconnect the speakers,
driven by a GPIO.

This commit adds support for this, modelling this as a separate speaker
widget / dapm pin-switch which sets the mux to drive the speakers when
selected.

The intend is for userspace to use the recently added jack-detect support
and then automatically select either the Headphone or Speaker output based
on that.

Note this commit includes a workaround for an ACPI table bug which is
present on 2 of the 3 devices I have, see the added comment in the code.

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/bytcht_es8316.c | 98 ++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 905dd6904710..8e504fca4624 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,8 +19,11 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/module.h>
@@ -40,6 +43,8 @@
 struct byt_cht_es8316_private {
 	struct clk *mclk;
 	struct snd_soc_jack jack;
+	struct gpio_desc *speaker_en_gpio;
+	bool speaker_en;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -56,7 +61,24 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk SSP0 enabled");
 }
 
+static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = w->dapm->card;
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		priv->speaker_en = true;
+	else
+		priv->speaker_en = false;
+
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
+	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
@@ -67,6 +89,10 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	 */
 	SND_SOC_DAPM_MIC("Microphone 1", NULL),
 	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+
+	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
+			    byt_cht_es8316_speaker_power_event,
+			    SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
@@ -76,6 +102,14 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+
+	/*
+	 * There is no separate speaker output instead the speakers are muxed to
+	 * the HP outputs. The mux is controlled by the "Speaker Power" supply.
+	 */
+	{"Speaker", NULL, "HPOL"},
+	{"Speaker", NULL, "HPOR"},
+	{"Speaker", NULL, "Speaker Power"},
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
@@ -95,6 +129,7 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 };
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
@@ -323,6 +358,25 @@ static int byt_cht_es8316_resume(struct snd_soc_card *card)
 		}
 	}
 
+	/*
+	 * Some Cherry Trail boards with an ES8316 codec have a bug in their
+	 * ACPI tables where the MSSL1680 touchscreen's _PS0 and _PS3 methods
+	 * wrongly also set the speaker-enable GPIO to 1/0. Testing has shown
+	 * that this really is a bug and the GPIO has no influence on the
+	 * touchscreen at all.
+	 *
+	 * The silead.c touchscreen driver does not support runtime suspend, so
+	 * the GPIO can only be changed underneath us during a system suspend.
+	 * This resume() function runs from a pm complete() callback, and thus
+	 * is guaranteed to run after the touchscreen driver/ACPI-subsys has
+	 * brought the touchscreen back up again (and thus changed the GPIO).
+	 *
+	 * So to work around this we pass GPIOD_FLAGS_BIT_NONEXCLUSIVE when
+	 * requesting the GPIO and we set its value here to undo any changes
+	 * done by the touchscreen's broken _PS0 ACPI method.
+	 */
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
 	return 0;
 }
 
@@ -347,12 +401,20 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
+static const struct acpi_gpio_params first_gpio = { 0, 0, false };
+
+static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
+	{ "speaker-enable-gpios", &first_gpio, 1 },
+	{ },
+};
+
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
+	struct device *codec_dev;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
@@ -405,12 +467,39 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* get speaker enable GPIO */
+	codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
+	if (!codec_dev)
+		return -EPROBE_DEFER;
+
+	devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
+	priv->speaker_en_gpio =
+		gpiod_get_index(codec_dev, "speaker-enable", 0,
+				/* see comment in byt_cht_es8316_resume */
+				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+	put_device(codec_dev);
+
+	if (IS_ERR(priv->speaker_en_gpio)) {
+		ret = PTR_ERR(priv->speaker_en_gpio);
+		switch (ret) {
+		case -ENOENT:
+			priv->speaker_en_gpio = NULL;
+			break;
+		default:
+			dev_err(dev, "get speaker GPIO failed: %d\n", ret);
+			/* fall through */
+		case -EPROBE_DEFER:
+			return ret;
+		}
+	}
+
 	/* register the soc card */
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
 	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
+		gpiod_put(priv->speaker_en_gpio);
 		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
@@ -418,11 +507,20 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+{
+	struct byt_cht_es8316_private *priv = platform_get_drvdata(pdev);
+
+	gpiod_put(priv->speaker_en_gpio);
+	return 0;
+}
+
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
 	.driver = {
 		.name = "bytcht_es8316",
 	},
 	.probe = snd_byt_cht_es8316_mc_probe,
+	.remove = snd_byt_cht_es8316_mc_remove,
 };
 
 module_platform_driver(snd_byt_cht_es8316_mc_driver);
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add jack-detect support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: 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 4bf538b42933253296daf86aab7ede56b5fb97bf Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:31 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add jack-detect support

Hookup the jack-detect support added to the codec driver.

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/bytcht_es8316.c | 67 +++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 3358d82499a3..905dd6904710 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -22,12 +22,14 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -37,6 +39,7 @@
 
 struct byt_cht_es8316_private {
 	struct clk *mclk;
+	struct snd_soc_jack jack;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -55,6 +58,7 @@ static void log_quirks(struct device *dev)
 
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
 	/*
 	 * The codec supports two analog microphone inputs. I have only
@@ -68,6 +72,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"MIC1", NULL, "Microphone 1"},
 	{"MIC2", NULL, "Microphone 2"},
+	{"MIC1", NULL, "Headset Mic"},
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
@@ -91,12 +96,25 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Headphone"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
 	SOC_DAPM_PIN_SWITCH("Microphone 2"),
 };
 
+static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+	{
+		.pin	= "Headphone",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Mic",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
 static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
+	struct snd_soc_component *codec = runtime->codec_dai->component;
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
 	const struct snd_soc_dapm_route *custom_map;
@@ -143,6 +161,18 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
+	ret = snd_soc_card_jack_new(card, "Headset",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0,
+				    &priv->jack, byt_cht_es8316_jack_pins,
+				    ARRAY_SIZE(byt_cht_es8316_jack_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(codec, &priv->jack, NULL);
+
 	return 0;
 }
 
@@ -263,6 +293,39 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 
 /* SoC card */
+static char codec_name[SND_ACPI_I2C_ID_LEN];
+
+static int byt_cht_es8316_suspend(struct snd_soc_card *card)
+{
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_resume(struct snd_soc_card *card)
+{
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_card = {
 	.name = "bytcht-es8316",
 	.owner = THIS_MODULE,
@@ -275,6 +338,8 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.controls = byt_cht_es8316_controls,
 	.num_controls = ARRAY_SIZE(byt_cht_es8316_controls),
 	.fully_routed = true,
+	.suspend_pre = byt_cht_es8316_suspend,
+	.resume_post = byt_cht_es8316_resume,
 };
 
 static const struct x86_cpu_id baytrail_cpu_ids[] = {
@@ -282,8 +347,6 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
-static char codec_name[SND_ACPI_I2C_ID_LEN];
-
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)" to the asoc tree
  2019-01-03 13:45 ` [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR) Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)

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 349e13862c9975c613aac9dc7fa953e70cff9d06 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:30 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)

Add support for having the codec connected to SSP0 instead of SSP2. This
is controlled through a new quirk parameter, similar to how this is done
in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Bay Trail CR (cost reduced) SoCs do not have an SSP2, so we default to SSP0
there.

Note the SPP0 quirk gets BIT(16) because bits 0-15 are reserved for non
boolean quirks like the input-map added in a later commit in this series.

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/bytcht_es8316.c | 76 ++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index e29f00560b00..3358d82499a3 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -37,6 +39,20 @@ struct byt_cht_es8316_private {
 	struct clk *mclk;
 };
 
+#define BYT_CHT_ES8316_SSP0			BIT(16)
+
+static int quirk;
+
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
+static void log_quirks(struct device *dev)
+{
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		dev_info(dev, "quirk SSP0 enabled");
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
 
@@ -55,7 +71,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
+	{"Playback", NULL, "ssp0 Tx"},
+	{"ssp0 Tx", NULL, "modem_out"},
+	{"modem_in", NULL, "ssp0 Rx"},
+	{"ssp0 Rx", NULL, "Capture"},
+};
 
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 	{"Playback", NULL, "ssp2 Tx"},
 	{"ssp2 Tx", NULL, "codec_out0"},
 	{"ssp2 Tx", NULL, "codec_out1"},
@@ -74,10 +99,23 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	const struct snd_soc_dapm_route *custom_map;
+	int num_routes;
 	int ret;
 
 	card->dapm.idle_bias_off = true;
 
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		custom_map = byt_cht_es8316_ssp0_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
+	} else {
+		custom_map = byt_cht_es8316_ssp2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map);
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	/*
 	 * The firmware might enable the clock at boot (this information
 	 * may or may not be reflected in the enable clock register).
@@ -123,14 +161,21 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 			SNDRV_PCM_HW_PARAM_RATE);
 	struct snd_interval *channels = hw_param_interval(params,
 						SNDRV_PCM_HW_PARAM_CHANNELS);
-	int ret;
+	int ret, bits;
 
 	/* The DSP will covert the FE rate to 48k, stereo */
 	rate->min = rate->max = 48000;
 	channels->min = channels->max = 2;
 
-	/* set SSP2 to 24-bit */
-	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		/* set SSP0 to 16-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+		bits = 16;
+	} else {
+		/* set SSP2 to 24-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+		bits = 24;
+	}
 
 	/*
 	 * Default mode for SSP configuration is TDM 4 slot, override config
@@ -147,7 +192,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 		return ret;
 	}
 
-	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
 	if (ret < 0) {
 		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 		return ret;
@@ -232,6 +277,11 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.fully_routed = true,
 };
 
+static const struct x86_cpu_id baytrail_cpu_ids[] = {
+	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
+	{}
+};
+
 static char codec_name[SND_ACPI_I2C_ID_LEN];
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
@@ -266,6 +316,24 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
+	/* Check for BYTCR or other platform and setup quirks */
+	if (x86_match_cpu(baytrail_cpu_ids) &&
+	    mach->mach_params.acpi_ipc_irq_index == 0) {
+		/* On BYTCR default to SSP0 */
+		quirk = BYT_CHT_ES8316_SSP0;
+	} else {
+		quirk = 0;
+	}
+	if (quirk_override != -1) {
+		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
+			 quirk_override);
+		quirk = quirk_override;
+	}
+	log_quirks(dev);
+
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		byt_cht_es8316_dais[dai_index].cpu_dai_name = "ssp0-port";
+
 	/* get the clock */
 	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Minor refactoring" to the asoc tree
  2019-01-03 13:45 ` [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Minor refactoring

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 86909c8f77c5eda17a9b5dc954849e25df1ffe0f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:29 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Minor refactoring

Some minor refactoring:
1) Group the code setting the card dev and prive pointers together with
   registering the card
2) Properly put the comment about registering the card at the place where
   we actually register the card and add a new comment for getting the clk
3) Add a struct device *dev helper variable (this will be used more in
   follow up commits)
4) Reword error message to have the same "foo failed: %d" wording as others

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/bytcht_es8316.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 5d8ecc100766..e29f00560b00 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -237,17 +237,18 @@ static char codec_name[SND_ACPI_I2C_ID_LEN];
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
+	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	mach = (&pdev->dev)->platform_data;
+	mach = dev->platform_data;
 	/* fix index of codec dai */
 	for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
 		if (!strcmp(byt_cht_es8316_dais[i].codec_name,
@@ -265,26 +266,25 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
-	/* register the soc card */
-	byt_cht_es8316_card.dev = &pdev->dev;
-	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
-
-	priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+	/* get the clock */
+	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
 		ret = PTR_ERR(priv->mclk);
-		dev_err(&pdev->dev,
-			"Failed to get MCLK from pmc_plt_clk_3: %d\n",
-			ret);
+		dev_err(dev, "clk_get pmc_plt_clk_3 failed: %d\n", ret);
 		return ret;
 	}
 
-	ret = devm_snd_soc_register_card(&pdev->dev, &byt_cht_es8316_card);
+	/* register the soc card */
+	byt_cht_es8316_card.dev = dev;
+	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
-		dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
+		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
 	platform_set_drvdata(pdev, &byt_cht_es8316_card);
-	return ret;
+	return 0;
 }
 
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Sort includes alphabetically" to the asoc tree
  2019-01-03 13:45 ` [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically Hans de Goede
@ 2019-01-04 17:08   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:08 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Sort includes 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 6ca382c4363d6c636200ccdd9ac95f44b1a498ea Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:28 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Sort includes alphabetically

For lack of a better (non-random) way of sorting includes more and more
files in the kernel are moving over to sorting the includes alphabetically.

Move the bytcht_es8316 driver over to this sorting before we add a
bunch of more includes.

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/bytcht_es8316.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index adc26dfc7d65..5d8ecc100766 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,13 +19,13 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/clk.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/device.h>
 #include <linux/slab.h>
 #include <asm/platform_sst_audio.h>
-#include <linux/clk.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
-- 
2.20.1

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

* Applied "ASoC: es8316: Add DAC mono mix switch mixer control" to the asoc tree
  2019-01-03 13:45 ` [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control Hans de Goede
@ 2019-01-04 17:09   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: es8316: Add DAC mono mix switch mixer control

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 24b53f17a3f24967b8b523243f9f7fc361427119 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:27 +0100
Subject: [PATCH] ASoC: es8316: Add DAC mono mix switch mixer control

Export the DAC functionality to mix left + right together and then output
the same (mixed) signal on both outputs.

Various (x86) tablets with an ES8316 codec use a single speaker
connected between the headhpone LOUT and ROUT pins, expecting the output
to be in a mono differential mode. Presumably this is done to use the
power of both the left and right outputs to allow the speaker to be
louder.

The ES8316 codec does not have a differential output mode, but we can
emulate this by making both channels output the same through the mono mix
switch, combined with setting the Playback Polarity control to "R Invert",
which applias a 180 degrees phase inversion to the right channel.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index 26413851e434..98464ba1046c 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -101,6 +101,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = {
 	SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2, 6, 1, 0),
 	SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2, 7, 1, 0),
 	SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3, 0, 7, 0),
+	SOC_SINGLE("DAC Mono Mix Switch", ES8316_DAC_SET3, 3, 1, 0),
 
 	SOC_ENUM("Capture Polarity", adcpol),
 	SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA, 0, 1, 0),
-- 
2.20.1

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

* Applied "ASoC: es8316: Add jack-detect support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
@ 2019-01-04 17:09   ` Mark Brown
  2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-04 17:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: es8316: 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 822257661031faa437336058d8a32bf1844ad9c6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:26 +0100
Subject: [PATCH] ASoC: es8316: Add jack-detect support

Adding jack-detect support may seem weird for a codec with only
a single output, but it is necessary. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects
the speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail
devices and one Bay Trail CR device), use an analog mux to disconnect
the speakers, driven by a GPIO. In order to enable/disable the speakers
at the right time, we need jack-detect.

The same goes for the microphone where we must correctly set the mux
for the single ADC to either the internal or the headset microphone.

All devices I have support the es8316's builtin jack-detect functionality.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index e97d12d578b0..26413851e434 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -15,12 +15,14 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
 #include <linux/regmap.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
+#include <sound/jack.h>
 #include "es8316.h"
 
 /* In slave mode at single speed, the codec is documented as accepting 5
@@ -33,6 +35,11 @@ static const unsigned int supported_mclk_lrck_ratios[] = {
 };
 
 struct es8316_priv {
+	struct mutex lock;
+	struct regmap *regmap;
+	struct snd_soc_component *component;
+	struct snd_soc_jack *jack;
+	int irq;
 	unsigned int sysclk;
 	unsigned int allowed_rates[NR_SUPPORTED_MCLK_LRCK_RATIOS];
 	struct snd_pcm_hw_constraint_list sysclk_constraints;
@@ -529,8 +536,162 @@ static struct snd_soc_dai_driver es8316_dai = {
 	.symmetric_rates = 1,
 };
 
+static void es8316_enable_micbias_for_mic_gnd_short_detect(
+	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, "Bias");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Mic Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	msleep(20);
+}
+
+static void es8316_disable_micbias_for_mic_gnd_short_detect(
+	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, "Mic Bias");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static irqreturn_t es8316_irq(int irq, void *data)
+{
+	struct es8316_priv *es8316 = data;
+	struct snd_soc_component *comp = es8316->component;
+	unsigned int flags;
+
+	mutex_lock(&es8316->lock);
+
+	regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+	if (flags == 0x00)
+		goto out; /* Powered-down / reset */
+
+	/* Catch spurious IRQ before set_jack is called */
+	if (!es8316->jack)
+		goto out;
+
+	dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+	if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+		/* Jack removed, or spurious IRQ? */
+		if (es8316->jack->status & SND_JACK_MICROPHONE)
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+
+		if (es8316->jack->status & SND_JACK_HEADPHONE) {
+			snd_soc_jack_report(es8316->jack, 0,
+					    SND_JACK_HEADSET | SND_JACK_BTN_0);
+			dev_dbg(comp->dev, "jack unplugged\n");
+		}
+	} else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
+		/* Jack inserted, determine type */
+		es8316_enable_micbias_for_mic_gnd_short_detect(comp);
+		regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+		dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+		if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+			/* Jack unplugged underneath us */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		} else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, headset */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADSET,
+					    SND_JACK_HEADSET);
+			/* Keep mic-gnd-short detection on for button press */
+		} else {
+			/* Shorted, headphones */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADPHONE,
+					    SND_JACK_HEADSET);
+			/* No longer need mic-gnd-short detection */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		}
+	} else if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		/* Interrupt while jack inserted, report button state */
+		if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, button release */
+			snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+		} else {
+			/* Short, button press */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_BTN_0,
+					    SND_JACK_BTN_0);
+		}
+	}
+
+out:
+	mutex_unlock(&es8316->lock);
+	return IRQ_HANDLED;
+}
+
+static void es8316_enable_jack_detect(struct snd_soc_component *component,
+				      struct snd_soc_jack *jack)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	mutex_lock(&es8316->lock);
+
+	es8316->jack = jack;
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE)
+		es8316_enable_micbias_for_mic_gnd_short_detect(component);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT,
+				      ES8316_GPIO_ENABLE_INTERRUPT);
+
+	mutex_unlock(&es8316->lock);
+
+	/* Enable irq and sync initial jack state */
+	enable_irq(es8316->irq);
+	es8316_irq(es8316->irq, es8316);
+}
+
+static void es8316_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	disable_irq(es8316->irq);
+
+	mutex_lock(&es8316->lock);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT, 0);
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		es8316_disable_micbias_for_mic_gnd_short_detect(component);
+		snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+	}
+
+	es8316->jack = NULL;
+
+	mutex_unlock(&es8316->lock);
+}
+
+static int es8316_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *jack, void *data)
+{
+	if (jack)
+		es8316_enable_jack_detect(component, jack);
+	else
+		es8316_disable_jack_detect(component);
+
+	return 0;
+}
+
 static int es8316_probe(struct snd_soc_component *component)
 {
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	es8316->component = component;
+
 	/* Reset codec and enable current state machine */
 	snd_soc_component_write(component, ES8316_RESET, 0x3f);
 	usleep_range(5000, 5500);
@@ -555,6 +716,7 @@ static int es8316_probe(struct snd_soc_component *component)
 
 static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.probe			= es8316_probe,
+	.set_jack		= es8316_set_jack,
 	.controls		= es8316_snd_controls,
 	.num_controls		= ARRAY_SIZE(es8316_snd_controls),
 	.dapm_widgets		= es8316_dapm_widgets,
@@ -566,18 +728,29 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.non_legacy_dai_naming	= 1,
 };
 
+static const struct regmap_range es8316_volatile_ranges[] = {
+	regmap_reg_range(ES8316_GPIO_FLAG, ES8316_GPIO_FLAG),
+};
+
+static const struct regmap_access_table es8316_volatile_table = {
+	.yes_ranges	= es8316_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(es8316_volatile_ranges),
+};
+
 static const struct regmap_config es8316_regmap = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = 0x53,
+	.volatile_table	= &es8316_volatile_table,
 	.cache_type = REGCACHE_RBTREE,
 };
 
 static int es8316_i2c_probe(struct i2c_client *i2c_client,
 			    const struct i2c_device_id *id)
 {
+	struct device *dev = &i2c_client->dev;
 	struct es8316_priv *es8316;
-	struct regmap *regmap;
+	int ret;
 
 	es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
 			      GFP_KERNEL);
@@ -586,9 +759,23 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client,
 
 	i2c_set_clientdata(i2c_client, es8316);
 
-	regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
-	if (IS_ERR(regmap))
-		return PTR_ERR(regmap);
+	es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
+	if (IS_ERR(es8316->regmap))
+		return PTR_ERR(es8316->regmap);
+
+	es8316->irq = i2c_client->irq;
+	mutex_init(&es8316->lock);
+
+	ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
+					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					"es8316", es8316);
+	if (ret == 0) {
+		/* Gets re-enabled by es8316_set_jack() */
+		disable_irq(es8316->irq);
+	} else {
+		dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
+		es8316->irq = -ENXIO;
+	}
 
 	return devm_snd_soc_register_component(&i2c_client->dev,
 				      &soc_component_dev_es8316,
diff --git a/sound/soc/codecs/es8316.h b/sound/soc/codecs/es8316.h
index 6bcdd63ea459..439a0130cbb7 100644
--- a/sound/soc/codecs/es8316.h
+++ b/sound/soc/codecs/es8316.h
@@ -126,4 +126,11 @@
 #define ES8316_SERDATA2_LEN_16		0x0c
 #define ES8316_SERDATA2_LEN_32		0x10
 
+/* ES8316_GPIO_DEBOUNCE	*/
+#define ES8316_GPIO_ENABLE_INTERRUPT		0x02
+
+/* ES8316_GPIO_FLAG */
+#define ES8316_GPIO_FLAG_GM_NOT_SHORTED		0x02
+#define ES8316_GPIO_FLAG_HP_NOT_INSERTED	0x04
+
 #endif
-- 
2.20.1

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

* Applied "ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform" to the asoc tree
  2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
  2019-01-03 16:43   ` Pierre-Louis Bossart
  2019-01-04 17:08   ` Applied "ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  2 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform

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 5198baf8817d7e6e0fe2f3e74ea2ead714b74d9c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:35 +0100
Subject: [PATCH] ASoC: Intel: Add ACPI match table entry for ES8316 codec on
 BYTCR platform

Some BYTCR devices use an ES8316 codec, add an ACPI match table entry
for this.

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/common/soc-acpi-intel-byt-match.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/sound/soc/intel/common/soc-acpi-intel-byt-match.c b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
index 097dc06377ba..47a90909b956 100644
--- a/sound/soc/intel/common/soc-acpi-intel-byt-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-byt-match.c
@@ -154,6 +154,15 @@ struct snd_soc_acpi_mach  snd_soc_acpi_intel_baytrail_machines[] = {
 		.sof_tplg_filename = "intel/sof-byt-da7213.tplg",
 		.asoc_plat_name = "sst-mfld-platform",
 	},
+	{
+		.id = "ESSX8316",
+		.drv_name = "bytcht_es8316",
+		.fw_filename = "intel/fw_sst_0f28.bin",
+		.board = "bytcht_es8316",
+		.sof_fw_filename = "intel/sof-byt.ri",
+		.sof_tplg_filename = "intel/sof-byt-es8316.tplg",
+		.asoc_plat_name = "sst-mfld-platform",
+	},
 	/* some Baytrail platforms rely on RT5645, use CHT machine driver */
 	{
 		.id = "10EC5645",
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Set card long_name based on quirks" to the asoc tree
  2019-01-03 13:45 ` [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Set card long_name based on quirks" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: 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 249d2fc9e55c324dda968252ea3ad0ac21c72b8f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:34 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Set card long_name based on
 quirks

Depending on the input-map and on if 1 or 2 speakers are connected,
userspace needs to use a different UCM profile.

Since we already deal with quirks in the kernel driver and set the
input-map from the kernel, add a quirk for devices with a single / mono
speaker and set the card's long_name based on the input and speaker
quirks, so that userspace can use the long_name to pick the right UCM
profile.

This change, including how the long_name is build-up mirrors how we do
this in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Note since all devices I have access to use a mono speaker setup I've
chosen to default the speaker setting to mono.

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/bytcht_es8316.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 941a66f94660..cdf2061e7613 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -54,6 +54,7 @@ enum {
 
 #define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
+#define BYT_CHT_ES8316_MONO_SPEAKER		BIT(17)
 
 static int quirk;
 
@@ -69,6 +70,8 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
+	if (quirk & BYT_CHT_ES8316_MONO_SPEAKER)
+		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
 }
 
 static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
@@ -352,6 +355,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 /* SoC card */
 static char codec_name[SND_ACPI_I2C_ID_LEN];
+static char long_name[50]; /* = "bytcht-es8316-*-spk-*-mic" */
 
 static int byt_cht_es8316_suspend(struct snd_soc_card *card)
 {
@@ -433,6 +437,7 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
+	const char * const mic_name[] = { "in1", "in2" };
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
@@ -467,11 +472,13 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0, internal-mic-in2-map */
-		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
+		/* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	} else {
-		/* Others default to internal-mic-in1-map */
-		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
+		/* Others default to internal-mic-in1-map, mono-speaker */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP |
+			BYT_CHT_ES8316_MONO_SPEAKER;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
@@ -518,6 +525,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	}
 
 	/* register the soc card */
+	snprintf(long_name, sizeof(long_name), "bytcht-es8316-%s-spk-%s-mic",
+		 (quirk & BYT_CHT_ES8316_MONO_SPEAKER) ? "mono" : "stereo",
+		 mic_name[BYT_CHT_ES8316_MAP(quirk)]);
+	byt_cht_es8316_card.long_name = long_name;
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add input-map support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add input-map support" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add input-map 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 730501a91d94b652275e049e101ed44cdbfdf31b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:33 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add input-map support

After adding jack-detect support we have 3 microphone input switches:
"Microphone 1", "Microphone 2" and "Headset Mic". But the ES8316 has only
2 microphone inputs.

In the app-note explaining how to use the codec and on the 3 boards I
have one input is used for an internal microphone and one for the headset
microphone. On the 2 CHT boards I have the internal mic is on on MIC1 and
the headset mic is on MIC2, on the BYTCR board I have it is the other way
around.

This commit replaces the 2 "Microphone 1" and "Microphone 2" input switches
with a single "Internal Mic" switch and adds support for selecting either
possible input mapping.

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/bytcht_es8316.c | 58 ++++++++++++++++++--------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 8e504fca4624..941a66f94660 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -47,6 +47,12 @@ struct byt_cht_es8316_private {
 	bool speaker_en;
 };
 
+enum {
+	BYT_CHT_ES8316_INTMIC_IN1_MAP,
+	BYT_CHT_ES8316_INTMIC_IN2_MAP,
+};
+
+#define BYT_CHT_ES8316_MAP(quirk)		((quirk) & GENMASK(3, 0))
 #define BYT_CHT_ES8316_SSP0			BIT(16)
 
 static int quirk;
@@ -57,6 +63,10 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 
 static void log_quirks(struct device *dev)
 {
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN1_MAP)
+		dev_info(dev, "quirk IN1_MAP enabled");
+	if (BYT_CHT_ES8316_MAP(quirk) == BYT_CHT_ES8316_INTMIC_IN2_MAP)
+		dev_info(dev, "quirk IN2_MAP enabled");
 	if (quirk & BYT_CHT_ES8316_SSP0)
 		dev_info(dev, "quirk SSP0 enabled");
 }
@@ -81,14 +91,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
-
-	/*
-	 * The codec supports two analog microphone inputs. I have only
-	 * tested MIC1. A DMIC route could also potentially be added
-	 * if such functionality is found on another platform.
-	 */
-	SND_SOC_DAPM_MIC("Microphone 1", NULL),
-	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+	SND_SOC_DAPM_MIC("Internal Mic", NULL),
 
 	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
 			    byt_cht_es8316_speaker_power_event,
@@ -96,10 +99,6 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
-	{"MIC1", NULL, "Microphone 1"},
-	{"MIC2", NULL, "Microphone 2"},
-	{"MIC1", NULL, "Headset Mic"},
-
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
 
@@ -112,6 +111,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"Speaker", NULL, "Speaker Power"},
 };
 
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in1_map[] = {
+	{"MIC1", NULL, "Internal Mic"},
+	{"MIC2", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_intmic_in2_map[] = {
+	{"MIC2", NULL, "Internal Mic"},
+	{"MIC1", NULL, "Headset Mic"},
+};
+
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
 	{"Playback", NULL, "ssp0 Tx"},
 	{"ssp0 Tx", NULL, "modem_out"},
@@ -132,8 +141,7 @@ static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
-	SOC_DAPM_PIN_SWITCH("Microphone 1"),
-	SOC_DAPM_PIN_SWITCH("Microphone 2"),
+	SOC_DAPM_PIN_SWITCH("Internal Mic"),
 };
 
 static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
@@ -158,6 +166,21 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 
 	card->dapm.idle_bias_off = true;
 
+	switch (BYT_CHT_ES8316_MAP(quirk)) {
+	case BYT_CHT_ES8316_INTMIC_IN1_MAP:
+	default:
+		custom_map = byt_cht_es8316_intmic_in1_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in1_map);
+		break;
+	case BYT_CHT_ES8316_INTMIC_IN2_MAP:
+		custom_map = byt_cht_es8316_intmic_in2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_intmic_in2_map);
+		break;
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	if (quirk & BYT_CHT_ES8316_SSP0) {
 		custom_map = byt_cht_es8316_ssp0_map;
 		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
@@ -444,10 +467,11 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	/* Check for BYTCR or other platform and setup quirks */
 	if (x86_match_cpu(baytrail_cpu_ids) &&
 	    mach->mach_params.acpi_ipc_irq_index == 0) {
-		/* On BYTCR default to SSP0 */
-		quirk = BYT_CHT_ES8316_SSP0;
+		/* On BYTCR default to SSP0, internal-mic-in2-map */
+		quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP;
 	} else {
-		quirk = 0;
+		/* Others default to internal-mic-in1-map */
+		quirk = BYT_CHT_ES8316_INTMIC_IN1_MAP;
 	}
 	if (quirk_override != -1) {
 		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add external speaker mux support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add external speaker mux support" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add external speaker mux 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 0d3e91da0750835cfd5c16487ffb3cdd752ea53a Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:32 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add external speaker mux support

The ES8316 only has a single (amplified) output. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects the
speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail devices and
one Bay Trail CR device), use an analog mux to disconnect the speakers,
driven by a GPIO.

This commit adds support for this, modelling this as a separate speaker
widget / dapm pin-switch which sets the mux to drive the speakers when
selected.

The intend is for userspace to use the recently added jack-detect support
and then automatically select either the Headphone or Speaker output based
on that.

Note this commit includes a workaround for an ACPI table bug which is
present on 2 of the 3 devices I have, see the added comment in the code.

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/bytcht_es8316.c | 98 ++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 905dd6904710..8e504fca4624 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,8 +19,11 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/module.h>
@@ -40,6 +43,8 @@
 struct byt_cht_es8316_private {
 	struct clk *mclk;
 	struct snd_soc_jack jack;
+	struct gpio_desc *speaker_en_gpio;
+	bool speaker_en;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -56,7 +61,24 @@ static void log_quirks(struct device *dev)
 		dev_info(dev, "quirk SSP0 enabled");
 }
 
+static int byt_cht_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = w->dapm->card;
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		priv->speaker_en = true;
+	else
+		priv->speaker_en = false;
+
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
+	SND_SOC_DAPM_SPK("Speaker", NULL),
 	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
@@ -67,6 +89,10 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	 */
 	SND_SOC_DAPM_MIC("Microphone 1", NULL),
 	SND_SOC_DAPM_MIC("Microphone 2", NULL),
+
+	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
+			    byt_cht_es8316_speaker_power_event,
+			    SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
@@ -76,6 +102,14 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+
+	/*
+	 * There is no separate speaker output instead the speakers are muxed to
+	 * the HP outputs. The mux is controlled by the "Speaker Power" supply.
+	 */
+	{"Speaker", NULL, "HPOL"},
+	{"Speaker", NULL, "HPOR"},
+	{"Speaker", NULL, "Speaker Power"},
 };
 
 static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
@@ -95,6 +129,7 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 };
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speaker"),
 	SOC_DAPM_PIN_SWITCH("Headphone"),
 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
@@ -323,6 +358,25 @@ static int byt_cht_es8316_resume(struct snd_soc_card *card)
 		}
 	}
 
+	/*
+	 * Some Cherry Trail boards with an ES8316 codec have a bug in their
+	 * ACPI tables where the MSSL1680 touchscreen's _PS0 and _PS3 methods
+	 * wrongly also set the speaker-enable GPIO to 1/0. Testing has shown
+	 * that this really is a bug and the GPIO has no influence on the
+	 * touchscreen at all.
+	 *
+	 * The silead.c touchscreen driver does not support runtime suspend, so
+	 * the GPIO can only be changed underneath us during a system suspend.
+	 * This resume() function runs from a pm complete() callback, and thus
+	 * is guaranteed to run after the touchscreen driver/ACPI-subsys has
+	 * brought the touchscreen back up again (and thus changed the GPIO).
+	 *
+	 * So to work around this we pass GPIOD_FLAGS_BIT_NONEXCLUSIVE when
+	 * requesting the GPIO and we set its value here to undo any changes
+	 * done by the touchscreen's broken _PS0 ACPI method.
+	 */
+	gpiod_set_value_cansleep(priv->speaker_en_gpio, priv->speaker_en);
+
 	return 0;
 }
 
@@ -347,12 +401,20 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
+static const struct acpi_gpio_params first_gpio = { 0, 0, false };
+
+static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
+	{ "speaker-enable-gpios", &first_gpio, 1 },
+	{ },
+};
+
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
 	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
+	struct device *codec_dev;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
@@ -405,12 +467,39 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/* get speaker enable GPIO */
+	codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL, codec_name);
+	if (!codec_dev)
+		return -EPROBE_DEFER;
+
+	devm_acpi_dev_add_driver_gpios(codec_dev, byt_cht_es8316_gpios);
+	priv->speaker_en_gpio =
+		gpiod_get_index(codec_dev, "speaker-enable", 0,
+				/* see comment in byt_cht_es8316_resume */
+				GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+	put_device(codec_dev);
+
+	if (IS_ERR(priv->speaker_en_gpio)) {
+		ret = PTR_ERR(priv->speaker_en_gpio);
+		switch (ret) {
+		case -ENOENT:
+			priv->speaker_en_gpio = NULL;
+			break;
+		default:
+			dev_err(dev, "get speaker GPIO failed: %d\n", ret);
+			/* fall through */
+		case -EPROBE_DEFER:
+			return ret;
+		}
+	}
+
 	/* register the soc card */
 	byt_cht_es8316_card.dev = dev;
 	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
 
 	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
+		gpiod_put(priv->speaker_en_gpio);
 		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
@@ -418,11 +507,20 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int snd_byt_cht_es8316_mc_remove(struct platform_device *pdev)
+{
+	struct byt_cht_es8316_private *priv = platform_get_drvdata(pdev);
+
+	gpiod_put(priv->speaker_en_gpio);
+	return 0;
+}
+
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
 	.driver = {
 		.name = "bytcht_es8316",
 	},
 	.probe = snd_byt_cht_es8316_mc_probe,
+	.remove = snd_byt_cht_es8316_mc_remove,
 };
 
 module_platform_driver(snd_byt_cht_es8316_mc_driver);
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add jack-detect support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add jack-detect support" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: 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 4bf538b42933253296daf86aab7ede56b5fb97bf Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:31 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add jack-detect support

Hookup the jack-detect support added to the codec driver.

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/bytcht_es8316.c | 67 +++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 3358d82499a3..905dd6904710 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -22,12 +22,14 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -37,6 +39,7 @@
 
 struct byt_cht_es8316_private {
 	struct clk *mclk;
+	struct snd_soc_jack jack;
 };
 
 #define BYT_CHT_ES8316_SSP0			BIT(16)
@@ -55,6 +58,7 @@ static void log_quirks(struct device *dev)
 
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 
 	/*
 	 * The codec supports two analog microphone inputs. I have only
@@ -68,6 +72,7 @@ static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 	{"MIC1", NULL, "Microphone 1"},
 	{"MIC2", NULL, "Microphone 2"},
+	{"MIC1", NULL, "Headset Mic"},
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
@@ -91,12 +96,25 @@ static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 
 static const struct snd_kcontrol_new byt_cht_es8316_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Headphone"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
 	SOC_DAPM_PIN_SWITCH("Microphone 1"),
 	SOC_DAPM_PIN_SWITCH("Microphone 2"),
 };
 
+static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = {
+	{
+		.pin	= "Headphone",
+		.mask	= SND_JACK_HEADPHONE,
+	},
+	{
+		.pin	= "Headset Mic",
+		.mask	= SND_JACK_MICROPHONE,
+	},
+};
+
 static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
+	struct snd_soc_component *codec = runtime->codec_dai->component;
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
 	const struct snd_soc_dapm_route *custom_map;
@@ -143,6 +161,18 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 		return ret;
 	}
 
+	ret = snd_soc_card_jack_new(card, "Headset",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0,
+				    &priv->jack, byt_cht_es8316_jack_pins,
+				    ARRAY_SIZE(byt_cht_es8316_jack_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(codec, &priv->jack, NULL);
+
 	return 0;
 }
 
@@ -263,6 +293,39 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
 
 
 /* SoC card */
+static char codec_name[SND_ACPI_I2C_ID_LEN];
+
+static int byt_cht_es8316_suspend(struct snd_soc_card *card)
+{
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_resume(struct snd_soc_card *card)
+{
+	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	struct snd_soc_component *component;
+
+	for_each_card_components(card, component) {
+		if (!strcmp(component->name, 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_cht_es8316_card = {
 	.name = "bytcht-es8316",
 	.owner = THIS_MODULE,
@@ -275,6 +338,8 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.controls = byt_cht_es8316_controls,
 	.num_controls = ARRAY_SIZE(byt_cht_es8316_controls),
 	.fully_routed = true,
+	.suspend_pre = byt_cht_es8316_suspend,
+	.resume_post = byt_cht_es8316_resume,
 };
 
 static const struct x86_cpu_id baytrail_cpu_ids[] = {
@@ -282,8 +347,6 @@ static const struct x86_cpu_id baytrail_cpu_ids[] = {
 	{}
 };
 
-static char codec_name[SND_ACPI_I2C_ID_LEN];
-
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)" to the asoc tree
  2019-01-03 13:45 ` [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR) Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)

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 349e13862c9975c613aac9dc7fa953e70cff9d06 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:30 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)

Add support for having the codec connected to SSP0 instead of SSP2. This
is controlled through a new quirk parameter, similar to how this is done
in the bytcr_rt5640 and bytcr_rt5651 machine drivers.

Bay Trail CR (cost reduced) SoCs do not have an SSP2, so we default to SSP0
there.

Note the SPP0 quirk gets BIT(16) because bits 0-15 are reserved for non
boolean quirks like the input-map added in a later commit in this series.

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/bytcht_es8316.c | 76 ++++++++++++++++++++++++--
 1 file changed, 72 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index e29f00560b00..3358d82499a3 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
 #include <asm/platform_sst_audio.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -37,6 +39,20 @@ struct byt_cht_es8316_private {
 	struct clk *mclk;
 };
 
+#define BYT_CHT_ES8316_SSP0			BIT(16)
+
+static int quirk;
+
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
+static void log_quirks(struct device *dev)
+{
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		dev_info(dev, "quirk SSP0 enabled");
+}
+
 static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone", NULL),
 
@@ -55,7 +71,16 @@ static const struct snd_soc_dapm_route byt_cht_es8316_audio_map[] = {
 
 	{"Headphone", NULL, "HPOL"},
 	{"Headphone", NULL, "HPOR"},
+};
+
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp0_map[] = {
+	{"Playback", NULL, "ssp0 Tx"},
+	{"ssp0 Tx", NULL, "modem_out"},
+	{"modem_in", NULL, "ssp0 Rx"},
+	{"ssp0 Rx", NULL, "Capture"},
+};
 
+static const struct snd_soc_dapm_route byt_cht_es8316_ssp2_map[] = {
 	{"Playback", NULL, "ssp2 Tx"},
 	{"ssp2 Tx", NULL, "codec_out0"},
 	{"ssp2 Tx", NULL, "codec_out1"},
@@ -74,10 +99,23 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime)
 {
 	struct snd_soc_card *card = runtime->card;
 	struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card);
+	const struct snd_soc_dapm_route *custom_map;
+	int num_routes;
 	int ret;
 
 	card->dapm.idle_bias_off = true;
 
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		custom_map = byt_cht_es8316_ssp0_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp0_map);
+	} else {
+		custom_map = byt_cht_es8316_ssp2_map;
+		num_routes = ARRAY_SIZE(byt_cht_es8316_ssp2_map);
+	}
+	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
+	if (ret)
+		return ret;
+
 	/*
 	 * The firmware might enable the clock at boot (this information
 	 * may or may not be reflected in the enable clock register).
@@ -123,14 +161,21 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 			SNDRV_PCM_HW_PARAM_RATE);
 	struct snd_interval *channels = hw_param_interval(params,
 						SNDRV_PCM_HW_PARAM_CHANNELS);
-	int ret;
+	int ret, bits;
 
 	/* The DSP will covert the FE rate to 48k, stereo */
 	rate->min = rate->max = 48000;
 	channels->min = channels->max = 2;
 
-	/* set SSP2 to 24-bit */
-	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+	if (quirk & BYT_CHT_ES8316_SSP0) {
+		/* set SSP0 to 16-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
+		bits = 16;
+	} else {
+		/* set SSP2 to 24-bit */
+		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+		bits = 24;
+	}
 
 	/*
 	 * Default mode for SSP configuration is TDM 4 slot, override config
@@ -147,7 +192,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd,
 		return ret;
 	}
 
-	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
+	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
 	if (ret < 0) {
 		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
 		return ret;
@@ -232,6 +277,11 @@ static struct snd_soc_card byt_cht_es8316_card = {
 	.fully_routed = true,
 };
 
+static const struct x86_cpu_id baytrail_cpu_ids[] = {
+	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
+	{}
+};
+
 static char codec_name[SND_ACPI_I2C_ID_LEN];
 
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
@@ -266,6 +316,24 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
+	/* Check for BYTCR or other platform and setup quirks */
+	if (x86_match_cpu(baytrail_cpu_ids) &&
+	    mach->mach_params.acpi_ipc_irq_index == 0) {
+		/* On BYTCR default to SSP0 */
+		quirk = BYT_CHT_ES8316_SSP0;
+	} else {
+		quirk = 0;
+	}
+	if (quirk_override != -1) {
+		dev_info(dev, "Overriding quirk 0x%x => 0x%x\n", quirk,
+			 quirk_override);
+		quirk = quirk_override;
+	}
+	log_quirks(dev);
+
+	if (quirk & BYT_CHT_ES8316_SSP0)
+		byt_cht_es8316_dais[dai_index].cpu_dai_name = "ssp0-port";
+
 	/* get the clock */
 	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Minor refactoring" to the asoc tree
  2019-01-03 13:45 ` [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Minor refactoring" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Minor refactoring

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 86909c8f77c5eda17a9b5dc954849e25df1ffe0f Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:29 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Minor refactoring

Some minor refactoring:
1) Group the code setting the card dev and prive pointers together with
   registering the card
2) Properly put the comment about registering the card at the place where
   we actually register the card and add a new comment for getting the clk
3) Add a struct device *dev helper variable (this will be used more in
   follow up commits)
4) Reword error message to have the same "foo failed: %d" wording as others

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/bytcht_es8316.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 5d8ecc100766..e29f00560b00 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -237,17 +237,18 @@ static char codec_name[SND_ACPI_I2C_ID_LEN];
 static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 {
 	struct byt_cht_es8316_private *priv;
+	struct device *dev = &pdev->dev;
 	struct snd_soc_acpi_mach *mach;
 	const char *i2c_name = NULL;
 	int dai_index = 0;
 	int i;
 	int ret = 0;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	mach = (&pdev->dev)->platform_data;
+	mach = dev->platform_data;
 	/* fix index of codec dai */
 	for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
 		if (!strcmp(byt_cht_es8316_dais[i].codec_name,
@@ -265,26 +266,25 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
 		byt_cht_es8316_dais[dai_index].codec_name = codec_name;
 	}
 
-	/* register the soc card */
-	byt_cht_es8316_card.dev = &pdev->dev;
-	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
-
-	priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
+	/* get the clock */
+	priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
 	if (IS_ERR(priv->mclk)) {
 		ret = PTR_ERR(priv->mclk);
-		dev_err(&pdev->dev,
-			"Failed to get MCLK from pmc_plt_clk_3: %d\n",
-			ret);
+		dev_err(dev, "clk_get pmc_plt_clk_3 failed: %d\n", ret);
 		return ret;
 	}
 
-	ret = devm_snd_soc_register_card(&pdev->dev, &byt_cht_es8316_card);
+	/* register the soc card */
+	byt_cht_es8316_card.dev = dev;
+	snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
+
+	ret = devm_snd_soc_register_card(dev, &byt_cht_es8316_card);
 	if (ret) {
-		dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
+		dev_err(dev, "snd_soc_register_card failed: %d\n", ret);
 		return ret;
 	}
 	platform_set_drvdata(pdev, &byt_cht_es8316_card);
-	return ret;
+	return 0;
 }
 
 static struct platform_driver snd_byt_cht_es8316_mc_driver = {
-- 
2.20.1

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

* Applied "ASoC: Intel: bytcht_es8316: Sort includes alphabetically" to the asoc tree
  2019-01-03 13:45 ` [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically Hans de Goede
  2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Sort includes alphabetically" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: Intel: bytcht_es8316: Sort includes 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 6ca382c4363d6c636200ccdd9ac95f44b1a498ea Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:28 +0100
Subject: [PATCH] ASoC: Intel: bytcht_es8316: Sort includes alphabetically

For lack of a better (non-random) way of sorting includes more and more
files in the kernel are moving over to sorting the includes alphabetically.

Move the bytcht_es8316 driver over to this sorting before we add a
bunch of more includes.

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/bytcht_es8316.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index adc26dfc7d65..5d8ecc100766 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -19,13 +19,13 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+#include <linux/clk.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/device.h>
 #include <linux/slab.h>
 #include <asm/platform_sst_audio.h>
-#include <linux/clk.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
-- 
2.20.1

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

* Applied "ASoC: es8316: Add DAC mono mix switch mixer control" to the asoc tree
  2019-01-03 13:45 ` [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control Hans de Goede
  2019-01-04 17:09   ` Applied "ASoC: es8316: Add DAC mono mix switch mixer control" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: es8316: Add DAC mono mix switch mixer control

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 24b53f17a3f24967b8b523243f9f7fc361427119 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:27 +0100
Subject: [PATCH] ASoC: es8316: Add DAC mono mix switch mixer control

Export the DAC functionality to mix left + right together and then output
the same (mixed) signal on both outputs.

Various (x86) tablets with an ES8316 codec use a single speaker
connected between the headhpone LOUT and ROUT pins, expecting the output
to be in a mono differential mode. Presumably this is done to use the
power of both the left and right outputs to allow the speaker to be
louder.

The ES8316 codec does not have a differential output mode, but we can
emulate this by making both channels output the same through the mono mix
switch, combined with setting the Playback Polarity control to "R Invert",
which applias a 180 degrees phase inversion to the right channel.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index 26413851e434..98464ba1046c 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -101,6 +101,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = {
 	SOC_SINGLE("DAC Notch Filter Switch", ES8316_DAC_SET2, 6, 1, 0),
 	SOC_SINGLE("DAC Double Fs Switch", ES8316_DAC_SET2, 7, 1, 0),
 	SOC_SINGLE("DAC Stereo Enhancement", ES8316_DAC_SET3, 0, 7, 0),
+	SOC_SINGLE("DAC Mono Mix Switch", ES8316_DAC_SET3, 3, 1, 0),
 
 	SOC_ENUM("Capture Polarity", adcpol),
 	SOC_SINGLE("Mic Boost Switch", ES8316_ADC_D2SEPGA, 0, 1, 0),
-- 
2.20.1

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

* Applied "ASoC: es8316: Add jack-detect support" to the asoc tree
  2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
  2019-01-04 17:09   ` Applied "ASoC: es8316: Add jack-detect support" to the asoc tree Mark Brown
@ 2019-01-07 12:30   ` Mark Brown
  1 sibling, 0 replies; 35+ messages in thread
From: Mark Brown @ 2019-01-07 12:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: alsa-devel, Pierre-Louis Bossart, Daniel Drake, Liam Girdwood,
	Mark Brown, linux

The patch

   ASoC: es8316: 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 822257661031faa437336058d8a32bf1844ad9c6 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 3 Jan 2019 14:45:26 +0100
Subject: [PATCH] ASoC: es8316: Add jack-detect support

Adding jack-detect support may seem weird for a codec with only
a single output, but it is necessary. The ES8316 appnote showing
the intended usage uses a jack-receptacle which physically disconnects
the speakers from the output when a jack is plugged in.

But all 3 devices using the es8316 which I have (2 Cherry Trail
devices and one Bay Trail CR device), use an analog mux to disconnect
the speakers, driven by a GPIO. In order to enable/disable the speakers
at the right time, we need jack-detect.

The same goes for the microphone where we must correctly set the mux
for the single ADC to either the internal or the headset microphone.

All devices I have support the es8316's builtin jack-detect functionality.

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

diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index e97d12d578b0..26413851e434 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -15,12 +15,14 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
 #include <linux/regmap.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
+#include <sound/jack.h>
 #include "es8316.h"
 
 /* In slave mode at single speed, the codec is documented as accepting 5
@@ -33,6 +35,11 @@ static const unsigned int supported_mclk_lrck_ratios[] = {
 };
 
 struct es8316_priv {
+	struct mutex lock;
+	struct regmap *regmap;
+	struct snd_soc_component *component;
+	struct snd_soc_jack *jack;
+	int irq;
 	unsigned int sysclk;
 	unsigned int allowed_rates[NR_SUPPORTED_MCLK_LRCK_RATIOS];
 	struct snd_pcm_hw_constraint_list sysclk_constraints;
@@ -529,8 +536,162 @@ static struct snd_soc_dai_driver es8316_dai = {
 	.symmetric_rates = 1,
 };
 
+static void es8316_enable_micbias_for_mic_gnd_short_detect(
+	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, "Bias");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_force_enable_pin_unlocked(dapm, "Mic Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+
+	msleep(20);
+}
+
+static void es8316_disable_micbias_for_mic_gnd_short_detect(
+	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, "Mic Bias");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Analog power");
+	snd_soc_dapm_disable_pin_unlocked(dapm, "Bias");
+	snd_soc_dapm_sync_unlocked(dapm);
+	snd_soc_dapm_mutex_unlock(dapm);
+}
+
+static irqreturn_t es8316_irq(int irq, void *data)
+{
+	struct es8316_priv *es8316 = data;
+	struct snd_soc_component *comp = es8316->component;
+	unsigned int flags;
+
+	mutex_lock(&es8316->lock);
+
+	regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+	if (flags == 0x00)
+		goto out; /* Powered-down / reset */
+
+	/* Catch spurious IRQ before set_jack is called */
+	if (!es8316->jack)
+		goto out;
+
+	dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+	if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+		/* Jack removed, or spurious IRQ? */
+		if (es8316->jack->status & SND_JACK_MICROPHONE)
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+
+		if (es8316->jack->status & SND_JACK_HEADPHONE) {
+			snd_soc_jack_report(es8316->jack, 0,
+					    SND_JACK_HEADSET | SND_JACK_BTN_0);
+			dev_dbg(comp->dev, "jack unplugged\n");
+		}
+	} else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
+		/* Jack inserted, determine type */
+		es8316_enable_micbias_for_mic_gnd_short_detect(comp);
+		regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
+		dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
+		if (flags & ES8316_GPIO_FLAG_HP_NOT_INSERTED) {
+			/* Jack unplugged underneath us */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		} else if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, headset */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADSET,
+					    SND_JACK_HEADSET);
+			/* Keep mic-gnd-short detection on for button press */
+		} else {
+			/* Shorted, headphones */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_HEADPHONE,
+					    SND_JACK_HEADSET);
+			/* No longer need mic-gnd-short detection */
+			es8316_disable_micbias_for_mic_gnd_short_detect(comp);
+		}
+	} else if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		/* Interrupt while jack inserted, report button state */
+		if (flags & ES8316_GPIO_FLAG_GM_NOT_SHORTED) {
+			/* Open, button release */
+			snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+		} else {
+			/* Short, button press */
+			snd_soc_jack_report(es8316->jack,
+					    SND_JACK_BTN_0,
+					    SND_JACK_BTN_0);
+		}
+	}
+
+out:
+	mutex_unlock(&es8316->lock);
+	return IRQ_HANDLED;
+}
+
+static void es8316_enable_jack_detect(struct snd_soc_component *component,
+				      struct snd_soc_jack *jack)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	mutex_lock(&es8316->lock);
+
+	es8316->jack = jack;
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE)
+		es8316_enable_micbias_for_mic_gnd_short_detect(component);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT,
+				      ES8316_GPIO_ENABLE_INTERRUPT);
+
+	mutex_unlock(&es8316->lock);
+
+	/* Enable irq and sync initial jack state */
+	enable_irq(es8316->irq);
+	es8316_irq(es8316->irq, es8316);
+}
+
+static void es8316_disable_jack_detect(struct snd_soc_component *component)
+{
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	disable_irq(es8316->irq);
+
+	mutex_lock(&es8316->lock);
+
+	snd_soc_component_update_bits(component, ES8316_GPIO_DEBOUNCE,
+				      ES8316_GPIO_ENABLE_INTERRUPT, 0);
+
+	if (es8316->jack->status & SND_JACK_MICROPHONE) {
+		es8316_disable_micbias_for_mic_gnd_short_detect(component);
+		snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
+	}
+
+	es8316->jack = NULL;
+
+	mutex_unlock(&es8316->lock);
+}
+
+static int es8316_set_jack(struct snd_soc_component *component,
+			   struct snd_soc_jack *jack, void *data)
+{
+	if (jack)
+		es8316_enable_jack_detect(component, jack);
+	else
+		es8316_disable_jack_detect(component);
+
+	return 0;
+}
+
 static int es8316_probe(struct snd_soc_component *component)
 {
+	struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
+
+	es8316->component = component;
+
 	/* Reset codec and enable current state machine */
 	snd_soc_component_write(component, ES8316_RESET, 0x3f);
 	usleep_range(5000, 5500);
@@ -555,6 +716,7 @@ static int es8316_probe(struct snd_soc_component *component)
 
 static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.probe			= es8316_probe,
+	.set_jack		= es8316_set_jack,
 	.controls		= es8316_snd_controls,
 	.num_controls		= ARRAY_SIZE(es8316_snd_controls),
 	.dapm_widgets		= es8316_dapm_widgets,
@@ -566,18 +728,29 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = {
 	.non_legacy_dai_naming	= 1,
 };
 
+static const struct regmap_range es8316_volatile_ranges[] = {
+	regmap_reg_range(ES8316_GPIO_FLAG, ES8316_GPIO_FLAG),
+};
+
+static const struct regmap_access_table es8316_volatile_table = {
+	.yes_ranges	= es8316_volatile_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(es8316_volatile_ranges),
+};
+
 static const struct regmap_config es8316_regmap = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = 0x53,
+	.volatile_table	= &es8316_volatile_table,
 	.cache_type = REGCACHE_RBTREE,
 };
 
 static int es8316_i2c_probe(struct i2c_client *i2c_client,
 			    const struct i2c_device_id *id)
 {
+	struct device *dev = &i2c_client->dev;
 	struct es8316_priv *es8316;
-	struct regmap *regmap;
+	int ret;
 
 	es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
 			      GFP_KERNEL);
@@ -586,9 +759,23 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client,
 
 	i2c_set_clientdata(i2c_client, es8316);
 
-	regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
-	if (IS_ERR(regmap))
-		return PTR_ERR(regmap);
+	es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
+	if (IS_ERR(es8316->regmap))
+		return PTR_ERR(es8316->regmap);
+
+	es8316->irq = i2c_client->irq;
+	mutex_init(&es8316->lock);
+
+	ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
+					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					"es8316", es8316);
+	if (ret == 0) {
+		/* Gets re-enabled by es8316_set_jack() */
+		disable_irq(es8316->irq);
+	} else {
+		dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
+		es8316->irq = -ENXIO;
+	}
 
 	return devm_snd_soc_register_component(&i2c_client->dev,
 				      &soc_component_dev_es8316,
diff --git a/sound/soc/codecs/es8316.h b/sound/soc/codecs/es8316.h
index 6bcdd63ea459..439a0130cbb7 100644
--- a/sound/soc/codecs/es8316.h
+++ b/sound/soc/codecs/es8316.h
@@ -126,4 +126,11 @@
 #define ES8316_SERDATA2_LEN_16		0x0c
 #define ES8316_SERDATA2_LEN_32		0x10
 
+/* ES8316_GPIO_DEBOUNCE	*/
+#define ES8316_GPIO_ENABLE_INTERRUPT		0x02
+
+/* ES8316_GPIO_FLAG */
+#define ES8316_GPIO_FLAG_GM_NOT_SHORTED		0x02
+#define ES8316_GPIO_FLAG_HP_NOT_INSERTED	0x04
+
 #endif
-- 
2.20.1

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

end of thread, other threads:[~2019-01-07 12:30 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-03 13:45 [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements Hans de Goede
2019-01-03 13:45 ` [PATCH 01/10] ASoC: es8316: Add jack-detect support Hans de Goede
2019-01-04 17:09   ` Applied "ASoC: es8316: Add jack-detect support" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 02/10] ASoC: es8316: Add DAC mono mix switch mixer control Hans de Goede
2019-01-04 17:09   ` Applied "ASoC: es8316: Add DAC mono mix switch mixer control" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 03/10] ASoC: Intel: bytcht_es8316: Sort includes alphabetically Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Sort includes alphabetically" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 04/10] ASoC: Intel: bytcht_es8316: Minor refactoring Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Minor refactoring" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 05/10] ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR) Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add support for SSP0 (BYTCR)" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 06/10] ASoC: Intel: bytcht_es8316: Add jack-detect support Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add jack-detect support" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 07/10] ASoC: Intel: bytcht_es8316: Add external speaker mux support Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add external speaker mux support" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 08/10] ASoC: Intel: bytcht_es8316: Add input-map support Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Add input-map support" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 09/10] ASoC: Intel: bytcht_es8316: Set card long_name based on quirks Hans de Goede
2019-01-04 17:08   ` Applied "ASoC: Intel: bytcht_es8316: Set card long_name based on quirks" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 13:45 ` [PATCH 10/10] ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform Hans de Goede
2019-01-03 16:43   ` Pierre-Louis Bossart
2019-01-03 16:45     ` Hans de Goede
2019-01-03 17:04       ` Pierre-Louis Bossart
2019-01-04 17:08   ` Applied "ASoC: Intel: Add ACPI match table entry for ES8316 codec on BYTCR platform" to the asoc tree Mark Brown
2019-01-07 12:30   ` Mark Brown
2019-01-03 17:05 ` [PATCH 00/10] ASoC: bytcht-es8316 fixes and improvements 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.