ASoC: qcom: sm8250: Add Jack support
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Wed, 6 Oct 2021 17:27:45 +0000 (18:27 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 18 Oct 2021 20:11:50 +0000 (21:11 +0100)
WCD938X on SM8250 MTP is connected via TX macro which has MBHC support,
So add this jack support in the soundcard driver too.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20211006172745.22103-3-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/qcom/sm8250.c

index 9f2f0598a222e24a47abe535d9ce853e810bb6a5..b2ca2579810b06138fc2b7d8deddb60920924e58 100644 (file)
@@ -8,6 +8,8 @@
 #include <sound/soc-dapm.h>
 #include <sound/pcm.h>
 #include <linux/soundwire/sdw.h>
+#include <sound/jack.h>
+#include <linux/input-event-codes.h>
 #include "qdsp6/q6afe.h"
 #include "common.h"
 
@@ -18,8 +20,66 @@ struct sm8250_snd_data {
        bool stream_prepared[AFE_PORT_MAX];
        struct snd_soc_card *card;
        struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
+       struct snd_soc_jack jack;
+       bool jack_setup;
 };
 
+static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd)
+{
+       struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+       struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+       struct snd_soc_card *card = rtd->card;
+       int rval, i;
+
+       if (!data->jack_setup) {
+               struct snd_jack *jack;
+
+               rval = snd_soc_card_jack_new(card, "Headset Jack",
+                                            SND_JACK_HEADSET | SND_JACK_LINEOUT |
+                                            SND_JACK_MECHANICAL |
+                                            SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+                                            SND_JACK_BTN_2 | SND_JACK_BTN_3 |
+                                            SND_JACK_BTN_4 | SND_JACK_BTN_5,
+                                            &data->jack, NULL, 0);
+
+               if (rval < 0) {
+                       dev_err(card->dev, "Unable to add Headphone Jack\n");
+                       return rval;
+               }
+
+               jack = data->jack.jack;
+
+               snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA);
+               snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+               snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+               snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+               data->jack_setup = true;
+       }
+
+       switch (cpu_dai->id) {
+       case TX_CODEC_DMA_TX_0:
+       case TX_CODEC_DMA_TX_1:
+       case TX_CODEC_DMA_TX_2:
+       case TX_CODEC_DMA_TX_3:
+               for_each_rtd_codec_dais(rtd, i, codec_dai) {
+                       rval = snd_soc_component_set_jack(codec_dai->component,
+                                                         &data->jack, NULL);
+                       if (rval != 0 && rval != -ENOTSUPP) {
+                               dev_warn(card->dev, "Failed to set jack: %d\n", rval);
+                               return rval;
+                       }
+               }
+
+               break;
+       default:
+               break;
+       }
+
+
+       return 0;
+}
+
 static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
                                     struct snd_pcm_hw_params *params)
 {
@@ -192,6 +252,7 @@ static void sm8250_add_be_ops(struct snd_soc_card *card)
 
        for_each_card_prelinks(card, i, link) {
                if (link->no_pcm == 1) {
+                       link->init = sm8250_snd_init;
                        link->be_hw_params_fixup = sm8250_be_hw_params_fixup;
                        link->ops = &sm8250_be_ops;
                }