pmaports/device/testing/linux-postmarketos-exynos5/0010-ASoC-samsung-snow-add-jack-detection.patch

165 lines
4.5 KiB
Diff
Raw Normal View History

From a60b595873e36af9ff321808f409051906a7c6d5 Mon Sep 17 00:00:00 2001
From: Anton Bambura <jenneron@protonmail.com>
Date: Sat, 5 Feb 2022 03:19:07 +0200
Subject: [PATCH 10/33] ASoC: samsung: snow: add jack detection
Add jack detection support with two GPIOs:
- samsung,hp-det;
- samsung,mic-det.
Signed-off-by: Anton Bambura <jenneron@protonmail.com>
---
sound/soc/samsung/snow.c | 94 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c
index 02372109c251..e0232dd2afdb 100644
--- a/sound/soc/samsung/snow.c
+++ b/sound/soc/samsung/snow.c
@@ -3,10 +3,12 @@
// ASoC machine driver for Snow boards
#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <sound/jack.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -22,6 +24,37 @@ SND_SOC_DAILINK_DEFS(links,
struct snow_priv {
struct snd_soc_dai_link dai_link;
struct clk *clk_i2s_bus;
+ struct gpio_desc *gpiod_hp_det;
+ struct gpio_desc *gpiod_mic_det;
+};
+
+static struct snd_soc_jack snow_hp_jack;
+
+static struct snd_soc_jack_pin snow_hp_jack_pins[] = {
+ { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
+};
+
+static struct snd_soc_jack_gpio snow_hp_jack_gpio = {
+ .name = "Headphones detection",
+ .report = SND_JACK_HEADPHONE,
+ .debounce_time = 150,
+};
+
+static struct snd_soc_jack snow_mic_jack;
+
+static struct snd_soc_jack_pin snow_mic_jack_pins[] = {
+ { .pin = "Mic Jack", .mask = SND_JACK_MICROPHONE },
+};
+
+static struct snd_soc_jack_gpio snow_mic_jack_gpio = {
+ .name = "Microphone detection",
+ .report = SND_JACK_MICROPHONE,
+ .debounce_time = 150,
+};
+
+static const struct snd_soc_dapm_widget snow_dapm_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
};
static int snow_card_hw_params(struct snd_pcm_substream *substream,
@@ -105,9 +138,56 @@ static int snow_late_probe(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
struct snd_soc_dai *codec_dai;
+ struct snow_priv *priv = snd_soc_card_get_drvdata(card);
+ const char *jack_name;
+ int err;
rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
+ if (priv->gpiod_hp_det) {
+ jack_name = "Headphones";
+
+ err = snd_soc_card_jack_new(card, jack_name,
+ SND_JACK_HEADPHONE,
+ &snow_hp_jack,
+ snow_hp_jack_pins,
+ ARRAY_SIZE(snow_hp_jack_pins));
+ if (err) {
+ dev_err(rtd->dev,
+ "Headphones Jack creation failed: %d\n", err);
+ return err;
+ }
+
+ snow_hp_jack_gpio.desc = priv->gpiod_hp_det;
+
+ err = snd_soc_jack_add_gpios(&snow_hp_jack, 1,
+ &snow_hp_jack_gpio);
+ if (err)
+ dev_err(rtd->dev, "Headphones GPIOs not added: %d\n", err);
+ }
+
+ if (priv->gpiod_mic_det) {
+ jack_name = "Microphone";
+
+ err = snd_soc_card_jack_new(card, jack_name,
+ SND_JACK_MICROPHONE,
+ &snow_mic_jack,
+ snow_mic_jack_pins,
+ ARRAY_SIZE(snow_mic_jack_pins));
+ if (err) {
+ dev_err(rtd->dev,
+ "Microphone Jack creation failed: %d\n", err);
+ return err;
+ }
+
+ snow_mic_jack_gpio.desc = priv->gpiod_mic_det;
+
+ err = snd_soc_jack_add_gpios(&snow_mic_jack, 1,
+ &snow_mic_jack_gpio);
+ if (err)
+ dev_err(rtd->dev, "Microphone GPIOs not added: %d\n", err);
+ }
+
/* In the multi-codec case codec_dais 0 is MAX98095 and 1 is HDMI. */
codec_dai = asoc_rtd_to_codec(rtd, 0);
@@ -129,6 +209,7 @@ static int snow_probe(struct platform_device *pdev)
struct device_node *cpu, *codec;
struct snd_soc_dai_link *link;
struct snow_priv *priv;
+ struct gpio_desc *gpiod;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -137,6 +218,16 @@ static int snow_probe(struct platform_device *pdev)
link = &priv->dai_link;
+ gpiod = devm_gpiod_get_optional(dev, "samsung,hp-det", GPIOD_IN);
+ priv->gpiod_hp_det = gpiod;
+ if (IS_ERR(gpiod))
+ return PTR_ERR(gpiod);
+
+ gpiod = devm_gpiod_get_optional(dev, "samsung,mic-det", GPIOD_IN);
+ priv->gpiod_mic_det = gpiod;
+ if (IS_ERR(gpiod))
+ return PTR_ERR(gpiod);
+
link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS;
@@ -154,6 +245,9 @@ static int snow_probe(struct platform_device *pdev)
card->num_links = 1;
card->dev = dev;
+ card->dapm_widgets = snow_dapm_widgets;
+ card->num_dapm_widgets = ARRAY_SIZE(snow_dapm_widgets);
+
/* Try new DT bindings with HDMI support first. */
cpu = of_get_child_by_name(dev->of_node, "cpu");
--
2.38.0