linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/2] Make headphone work on Huawei Matebook D15
@ 2022-04-03  8:59 Mauro Carvalho Chehab
  2022-04-03  8:59 ` [PATCH RFC 1/2] ASoC: Intel: sof_es8336: support a separate gpio to control headphone Mauro Carvalho Chehab
  2022-04-03  8:59 ` [PATCH RFC 2/2] ASoC: Intel: sof_es8336: Huawei Matebook D15 uses a headphone gpio Mauro Carvalho Chehab
  0 siblings, 2 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2022-04-03  8:59 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Mauro Carvalho Chehab, Hans de Goede, Péter Ujfalusi,
	Bard Liao, Cezary Rojewski, Jaroslav Kysela, Jie Yang,
	Liam Girdwood, Mark Brown, Takashi Iwai, alsa-devel,
	linux-kernel

The headphone output at Huawei Matebook D15 is controlled by a separate
GPIO than the speaker. So, the es8336 boards logic need to handle two events:
one for the speaker switch and another one for the headphone.

Please notice that this is my first real incursion at SOC/SOF. While this is working
fine, I'm still struggling with some troubles with pipewire, which I believe are
due to UCM support, as, sometimes when pavucontrol starts, the playback stucks.
Also, sometimes the mixers won't change when jack plug/unplug is detected.

So, more debug is needed, and probably the UCM will also need to be closer to
the definitions that are used at ucm2/codecs/es8316/, as es8336 is a variant of
it.

Anyway, let me submit this as as RFC, in order to get some feedback if this is
going at the right way to support the headphone switch event.

Mauro Carvalho Chehab (2):
  ASoC: Intel: sof_es8336: support a separate gpio to control headphone
  ASoC: Intel: sof_es8336: Huawei Matebook D15 uses a headphone gpio

 sound/soc/intel/boards/sof_es8336.c | 84 ++++++++++++++++++++++-------
 1 file changed, 65 insertions(+), 19 deletions(-)

-- 
2.35.1



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

* [PATCH RFC 1/2] ASoC: Intel: sof_es8336: support a separate gpio to control headphone
  2022-04-03  8:59 [PATCH RFC 0/2] Make headphone work on Huawei Matebook D15 Mauro Carvalho Chehab
@ 2022-04-03  8:59 ` Mauro Carvalho Chehab
  2022-04-03  8:59 ` [PATCH RFC 2/2] ASoC: Intel: sof_es8336: Huawei Matebook D15 uses a headphone gpio Mauro Carvalho Chehab
  1 sibling, 0 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2022-04-03  8:59 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Mauro Carvalho Chehab, Hans de Goede, Péter Ujfalusi,
	Bard Liao, Cezary Rojewski, Jaroslav Kysela, Jie Yang,
	Liam Girdwood, Mark Brown, Takashi Iwai, alsa-devel,
	linux-kernel, Mauro Carvalho Chehab

From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

Some devices may use both gpio0 and gpio1 to independently switch
the speaker and the headphone.

Add support for that.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
---

See [PATCH RFC 0/2] at: https://lore.kernel.org/all/cover.1648975926.git.mchehab@kernel.org/

 sound/soc/intel/boards/sof_es8336.c | 76 +++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 19 deletions(-)

diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index 5e0529aa4f1d..96920d3eed8a 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -30,6 +30,7 @@
 #define SOF_ES8336_TGL_GPIO_QUIRK		BIT(4)
 #define SOF_ES8336_ENABLE_DMIC			BIT(5)
 #define SOF_ES8336_JD_INVERTED			BIT(6)
+#define SOF_ES8336_HEADPHONE_GPIO		BIT(7)
 
 static unsigned long quirk;
 
@@ -39,10 +40,9 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
 
 struct sof_es8336_private {
 	struct device *codec_dev;
-	struct gpio_desc *gpio_pa;
+	struct gpio_desc *gpio_pa, *gpio_pa_headphone;
 	struct snd_soc_jack jack;
 	struct list_head hdmi_pcm_list;
-	bool speaker_en;
 };
 
 struct sof_hdmi_pcm {
@@ -51,15 +51,28 @@ struct sof_hdmi_pcm {
 	int device;
 };
 
-static const struct acpi_gpio_params pa_enable_gpio = { 0, 0, true };
+static const struct acpi_gpio_params pa_enable_gpio0 = { 0, 0, true };
+static const struct acpi_gpio_params pa_enable_gpio1 = { 1, 0, true };
+
 static const struct acpi_gpio_mapping acpi_es8336_gpios[] = {
-	{ "pa-enable-gpios", &pa_enable_gpio, 1 },
+	{ "pa-enable-gpios", &pa_enable_gpio0, 1 },
 	{ }
 };
 
-static const struct acpi_gpio_params quirk_pa_enable_gpio = { 1, 0, true };
 static const struct acpi_gpio_mapping quirk_acpi_es8336_gpios[] = {
-	{ "pa-enable-gpios", &quirk_pa_enable_gpio, 1 },
+	{ "pa-enable-gpios", &pa_enable_gpio1, 1 },
+	{ }
+};
+
+static const struct acpi_gpio_mapping quirk_acpi_headphone_es8336_gpios[] = {
+	{ "pa-enable-gpios", &pa_enable_gpio0, 1 },
+	{ "pa-enable-headphone-gpios", &pa_enable_gpio1, 1 },
+	{ }
+};
+
+static const struct acpi_gpio_mapping quirk_tgl_acpi_headphone_es8336_gpios[] = {
+	{ "pa-enable-gpios", &pa_enable_gpio1, 1 },
+	{ "pa-enable-headphone-gpios", &pa_enable_gpio0, 1 },
 	{ }
 };
 
@@ -71,6 +84,8 @@ static void log_quirks(struct device *dev)
 	dev_info(dev, "quirk SSP%ld\n",  SOF_ES8336_SSP_CODEC(quirk));
 	if (quirk & SOF_ES8336_ENABLE_DMIC)
 		dev_info(dev, "quirk DMIC enabled\n");
+	if (quirk & SOF_ES8336_HEADPHONE_GPIO)
+		dev_info(dev, "quirk headphone GPIO enabled\n");
 	if (quirk & SOF_ES8336_TGL_GPIO_QUIRK)
 		dev_info(dev, "quirk TGL GPIO enabled\n");
 	if (quirk & SOF_ES8336_JD_INVERTED)
@@ -84,24 +99,35 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
 	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
 
 	if (SND_SOC_DAPM_EVENT_ON(event))
-		priv->speaker_en = false;
-	else
-		priv->speaker_en = true;
+		msleep(70);
 
-	gpiod_set_value_cansleep(priv->gpio_pa, priv->speaker_en);
+	gpiod_set_value_cansleep(priv->gpio_pa, !SND_SOC_DAPM_EVENT_ON(event));
+
+	return 0;
+}
+
+static int sof_es8316_headphone_power_event(struct snd_soc_dapm_widget *w,
+					  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = w->dapm->card;
+	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+
+	if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
+		return 0;
+
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		msleep(70);
+
+	gpiod_set_value_cansleep(priv->gpio_pa_headphone, SND_SOC_DAPM_EVENT_ON(event));
 
 	return 0;
 }
 
 static const struct snd_soc_dapm_widget sof_es8316_widgets[] = {
-	SND_SOC_DAPM_SPK("Speaker", NULL),
-	SND_SOC_DAPM_HP("Headphone", NULL),
+	SND_SOC_DAPM_SPK("Speaker", sof_es8316_speaker_power_event),
+	SND_SOC_DAPM_HP("Headphone", sof_es8316_headphone_power_event),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
 	SND_SOC_DAPM_MIC("Internal Mic", NULL),
-
-	SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
-			    sof_es8316_speaker_power_event,
-			    SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 };
 
 static const struct snd_soc_dapm_widget dmic_widgets[] = {
@@ -114,11 +140,10 @@ static const struct snd_soc_dapm_route sof_es8316_audio_map[] = {
 
 	/*
 	 * There is no separate speaker output instead the speakers are muxed to
-	 * the HP outputs. The mux is controlled by the "Speaker Power" supply.
+	 * the HP outputs. The mux is controlled Speaker and/or headphone switch.
 	 */
 	{"Speaker", NULL, "HPOL"},
 	{"Speaker", NULL, "HPOR"},
-	{"Speaker", NULL, "Speaker Power"},
 };
 
 static const struct snd_soc_dapm_route sof_es8316_intmic_in1_map[] = {
@@ -233,8 +258,14 @@ static int sof_es8336_quirk_cb(const struct dmi_system_id *id)
 {
 	quirk = (unsigned long)id->driver_data;
 
-	if (quirk & SOF_ES8336_TGL_GPIO_QUIRK)
+	if (quirk & SOF_ES8336_HEADPHONE_GPIO) {
+		if (quirk & SOF_ES8336_TGL_GPIO_QUIRK)
+			gpio_mapping = quirk_tgl_acpi_headphone_es8336_gpios;
+		else
+			gpio_mapping = quirk_acpi_headphone_es8336_gpios;
+	} else if (quirk & SOF_ES8336_TGL_GPIO_QUIRK) {
 		gpio_mapping = quirk_acpi_es8336_gpios;
+	}
 
 	return 1;
 }
@@ -592,6 +623,13 @@ static int sof_es8336_probe(struct platform_device *pdev)
 		goto err_put_codec;
 	}
 
+	priv->gpio_pa_headphone = gpiod_get_optional(codec_dev, "pa-enable-headphone", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->gpio_pa_headphone)) {
+		ret = dev_err_probe(dev, PTR_ERR(priv->gpio_pa_headphone),
+				    "could not get pa-enable-headphone GPIO\n");
+		goto err_put_codec;
+	}
+
 	INIT_LIST_HEAD(&priv->hdmi_pcm_list);
 
 	snd_soc_card_set_drvdata(card, priv);
-- 
2.35.1


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

* [PATCH RFC 2/2] ASoC: Intel: sof_es8336: Huawei Matebook D15 uses a headphone gpio
  2022-04-03  8:59 [PATCH RFC 0/2] Make headphone work on Huawei Matebook D15 Mauro Carvalho Chehab
  2022-04-03  8:59 ` [PATCH RFC 1/2] ASoC: Intel: sof_es8336: support a separate gpio to control headphone Mauro Carvalho Chehab
@ 2022-04-03  8:59 ` Mauro Carvalho Chehab
  1 sibling, 0 replies; 3+ messages in thread
From: Mauro Carvalho Chehab @ 2022-04-03  8:59 UTC (permalink / raw)
  To: Pierre-Louis Bossart
  Cc: Mauro Carvalho Chehab, Hans de Goede, Péter Ujfalusi,
	Bard Liao, Cezary Rojewski, Jaroslav Kysela, Jie Yang,
	Liam Girdwood, Mark Brown, Takashi Iwai, alsa-devel,
	linux-kernel, Mauro Carvalho Chehab

From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

Based on experimental tests, Huawei Matebook D15 actually uses
both gpio0 and gpio1: the first one controls the speaker, while
the other one controls the headphone.

Add a quirk for that.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
---

See [PATCH RFC 0/2] at: https://lore.kernel.org/all/cover.1648975926.git.mchehab@kernel.org/

 sound/soc/intel/boards/sof_es8336.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index 96920d3eed8a..fd47aba1bd5d 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -290,6 +290,14 @@ static const struct dmi_system_id sof_es8336_quirk_table[] = {
 		},
 		.driver_data = (void *)(SOF_ES8336_TGL_GPIO_QUIRK)
 	},
+	{
+		.callback = sof_es8336_quirk_cb,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"),
+			DMI_MATCH(DMI_BOARD_NAME, "BOHB-WAX9-PCB-B2"),
+		},
+		.driver_data = (void *)(SOF_ES8336_HEADPHONE_GPIO)
+	},
 	{}
 };
 
-- 
2.35.1


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

end of thread, other threads:[~2022-04-03  8:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-03  8:59 [PATCH RFC 0/2] Make headphone work on Huawei Matebook D15 Mauro Carvalho Chehab
2022-04-03  8:59 ` [PATCH RFC 1/2] ASoC: Intel: sof_es8336: support a separate gpio to control headphone Mauro Carvalho Chehab
2022-04-03  8:59 ` [PATCH RFC 2/2] ASoC: Intel: sof_es8336: Huawei Matebook D15 uses a headphone gpio Mauro Carvalho Chehab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).