Merge series "ASoC: fsl-asoc-card: Support hp and mic detection" from Shengjiu Wang...
authorMark Brown <broonie@kernel.org>
Thu, 16 Jul 2020 22:51:52 +0000 (23:51 +0100)
committerMark Brown <broonie@kernel.org>
Thu, 16 Jul 2020 22:51:52 +0000 (23:51 +0100)
Support hp and mic detection.
Add a parameter for asoc_simple_init_jack.

Shengjiu Wang (3):
  ASoC: simple-card-utils: Support configure pin_name for
    asoc_simple_init_jack
  ASoC: bindings: fsl-asoc-card: Support hp-det-gpio and mic-det-gpio
  ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

changes in v2:
- Add more comments in third commit
- Add Acked-by Nicolin.

 .../bindings/sound/fsl-asoc-card.txt          |  3 +
 include/sound/simple_card_utils.h             |  6 +-
 sound/soc/fsl/Kconfig                         |  1 +
 sound/soc/fsl/fsl-asoc-card.c                 | 77 ++++++++++++++++++-
 sound/soc/generic/simple-card-utils.c         |  7 +-
 5 files changed, 86 insertions(+), 8 deletions(-)

--
2.27.0

1  2 
sound/soc/fsl/fsl-asoc-card.c

@@@ -15,6 -15,8 +15,8 @@@
  #endif
  #include <sound/pcm_params.h>
  #include <sound/soc.h>
+ #include <sound/jack.h>
+ #include <sound/simple_card_utils.h>
  
  #include "fsl_esai.h"
  #include "fsl_sai.h"
@@@ -65,6 -67,8 +67,8 @@@ struct cpu_priv 
  /**
   * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data
   * @dai_link: DAI link structure including normal one and DPCM link
+  * @hp_jack: Headphone Jack structure
+  * @mic_jack: Microphone Jack structure
   * @pdev: platform device pointer
   * @codec_priv: CODEC private data
   * @cpu_priv: CPU private data
@@@ -79,6 -83,8 +83,8 @@@
  
  struct fsl_asoc_card_priv {
        struct snd_soc_dai_link dai_link[3];
+       struct asoc_simple_jack hp_jack;
+       struct asoc_simple_jack mic_jack;
        struct platform_device *pdev;
        struct codec_priv codec_priv;
        struct cpu_priv cpu_priv;
@@@ -92,7 -98,7 +98,7 @@@
  };
  
  /*
 - * This dapm route map exits for DPCM link only.
 + * This dapm route map exists for DPCM link only.
   * The other routes shall go through Device Tree.
   *
   * Note: keep all ASRC routes in the second half
@@@ -445,6 -451,44 +451,44 @@@ static int fsl_asoc_card_audmux_init(st
        return 0;
  }
  
+ static int hp_jack_event(struct notifier_block *nb, unsigned long event,
+                        void *data)
+ {
+       struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+       struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+       if (event & SND_JACK_HEADPHONE)
+               /* Disable speaker if headphone is plugged in */
+               snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+       else
+               snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+       return 0;
+ }
+ static struct notifier_block hp_jack_nb = {
+       .notifier_call = hp_jack_event,
+ };
+ static int mic_jack_event(struct notifier_block *nb, unsigned long event,
+                         void *data)
+ {
+       struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+       struct snd_soc_dapm_context *dapm = &jack->card->dapm;
+       if (event & SND_JACK_MICROPHONE)
+               /* Disable dmic if microphone is plugged in */
+               snd_soc_dapm_disable_pin(dapm, "DMIC");
+       else
+               snd_soc_dapm_enable_pin(dapm, "DMIC");
+       return 0;
+ }
+ static struct notifier_block mic_jack_nb = {
+       .notifier_call = mic_jack_event,
+ };
  static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
  {
        struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
@@@ -745,8 -789,37 +789,37 @@@ static int fsl_asoc_card_probe(struct p
        snd_soc_card_set_drvdata(&priv->card, priv);
  
        ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
-       if (ret && ret != -EPROBE_DEFER)
-               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+       if (ret) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+               goto asrc_fail;
+       }
+       /*
+        * Properties "hp-det-gpio" and "mic-det-gpio" are optional, and
+        * asoc_simple_init_jack uses these properties for creating
+        * Headphone Jack and Microphone Jack.
+        *
+        * The notifier is initialized in snd_soc_card_jack_new(), then
+        * snd_soc_jack_notifier_register can be called.
+        */
+       if (of_property_read_bool(np, "hp-det-gpio")) {
+               ret = asoc_simple_init_jack(&priv->card, &priv->hp_jack,
+                                           1, NULL, "Headphone Jack");
+               if (ret)
+                       goto asrc_fail;
+               snd_soc_jack_notifier_register(&priv->hp_jack.jack, &hp_jack_nb);
+       }
+       if (of_property_read_bool(np, "mic-det-gpio")) {
+               ret = asoc_simple_init_jack(&priv->card, &priv->mic_jack,
+                                           0, NULL, "Mic Jack");
+               if (ret)
+                       goto asrc_fail;
+               snd_soc_jack_notifier_register(&priv->mic_jack.jack, &mic_jack_nb);
+       }
  
  asrc_fail:
        of_node_put(asrc_np);