Blob Blame History Raw
From 8f5df7e07f68efe5ee5da4b95f6596138e3ff736 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 11 Apr 2017 15:51:02 +0200
Subject: [PATCH] ASoC: intel: Add headset jack support to cht-cx2072x
References: bsc#1068546
Patch-mainline: Submitted, alsa-devel ML

This patch adds plumbing up the jack detection via the standard gpio.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 sound/soc/intel/boards/cht_cx2072x.c |   64 +++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

--- a/sound/soc/intel/boards/cht_cx2072x.c
+++ b/sound/soc/intel/boards/cht_cx2072x.c
@@ -70,10 +70,49 @@ static int cht_aif1_hw_params(struct snd
 	return 0;
 }
 
+static struct snd_soc_jack cht_cx_headset;
+
+/* Headset jack detection DAPM pins */
+static struct snd_soc_jack_pin cht_cx_headset_pins[] = {
+	{
+		.pin = "Headset Mic",
+		.mask = SND_JACK_MICROPHONE,
+	},
+	{
+		.pin = "Headphone",
+		.mask = SND_JACK_HEADPHONE,
+	},
+};
+
+static const struct acpi_gpio_params headset_gpios = { 0, 0, false };
+
+static const struct acpi_gpio_mapping acpi_cht_cx2072x_gpios[] = {
+	{ "headset-gpios", &headset_gpios, 1 },
+	{},
+};
+
+static int cht_cx_jack_status_check(void *data)
+{
+	return cx2072x_get_jack_state(data);
+}
+
+static struct snd_soc_jack_gpio cht_cx_gpio = {
+	.name = "headset",
+	.report = SND_JACK_HEADSET | SND_JACK_BTN_0,
+	.debounce_time = 150,
+	.wake = true,
+	.jack_status_check = cht_cx_jack_status_check,
+};
+
 static int cht_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret;
 	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_codec *codec = rtd->codec;
+
+	if (devm_acpi_dev_add_driver_gpios(codec->dev,
+					   acpi_cht_cx2072x_gpios))
+		dev_warn(rtd->dev, "Unable to add GPIO mapping table\n");
 
 	card->dapm.idle_bias_off = true;
 
@@ -85,6 +124,24 @@ static int cht_codec_init(struct snd_soc
 		return ret;
 	}
 
+	ret = snd_soc_card_jack_new(card, "Headset",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0,
+				    &cht_cx_headset,
+				    cht_cx_headset_pins,
+				    ARRAY_SIZE(cht_cx_headset_pins));
+	if (ret)
+		return ret;
+
+	cht_cx_gpio.gpiod_dev = codec->dev;
+	cht_cx_gpio.data = codec;
+	ret = snd_soc_jack_add_gpios(&cht_cx_headset, 1, &cht_cx_gpio);
+	if (ret) {
+		dev_err(rtd->dev, "Adding jack GPIO failed\n");
+		return ret;
+	}
+
+	cx2072x_enable_detect(codec);
+
 	return ret;
 }
 
@@ -259,11 +316,18 @@ static int snd_cht_mc_probe(struct platf
 	return devm_snd_soc_register_card(&pdev->dev, &chtcx2072x_card);
 }
 
+static int snd_cht_mc_remove(struct platform_device *pdev)
+{
+	snd_soc_jack_free_gpios(&cht_cx_headset, 1, &cht_cx_gpio);
+	return 0;
+}
+
 static struct platform_driver snd_cht_mc_driver = {
 	.driver = {
 		.name = "cht-cx2072x",
 	},
 	.probe = snd_cht_mc_probe,
+	.remove = snd_cht_mc_remove,
 };
 module_platform_driver(snd_cht_mc_driver);