Unverified Commit 5f52d4dd authored by Mark Brown's avatar Mark Brown
Browse files

Merge series "ASoC: fsl-asoc-card: Support hp and mic detection" from Shengjiu...

Merge series "ASoC: fsl-asoc-card: Support hp and mic detection" from Shengjiu Wang <shengjiu.wang@nxp.com>:

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
parents bdd0c277 3b171194
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -69,6 +69,9 @@ Optional properties:
			        coexisting in order to support the old bindings
				of wm8962 and sgtl5000.

  - hp-det-gpio		: The GPIO that detect headphones are plugged in
  - mic-det-gpio	: The GPIO that detect microphones are plugged in

Optional unless SSI is selected as a CPU DAI:

  - mux-int-port	: The internal port of the i.MX audio muxer (AUDMUX)
+3 −3
Original line number Diff line number Diff line
@@ -12,9 +12,9 @@
#include <sound/soc.h>

#define asoc_simple_init_hp(card, sjack, prefix) \
	asoc_simple_init_jack(card, sjack, 1, prefix)
	asoc_simple_init_jack(card, sjack, 1, prefix, NULL)
#define asoc_simple_init_mic(card, sjack, prefix) \
	asoc_simple_init_jack(card, sjack, 0, prefix)
	asoc_simple_init_jack(card, sjack, 0, prefix, NULL)

struct asoc_simple_dai {
	const char *name;
@@ -131,7 +131,7 @@ int asoc_simple_parse_pin_switches(struct snd_soc_card *card,

int asoc_simple_init_jack(struct snd_soc_card *card,
			       struct asoc_simple_jack *sjack,
			       int is_hp, char *prefix);
			       int is_hp, char *prefix, char *pin);
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
			       struct link_info *li);

+1 −0
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD
	depends on OF && I2C
	# enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
	depends on SND_AC97_CODEC || SND_AC97_CODEC=n
	select SND_SIMPLE_CARD_UTILS
	select SND_SOC_IMX_AUDMUX
	select SND_SOC_IMX_PCM_DMA
	select SND_SOC_FSL_ESAI
+75 −2
Original line number Diff line number Diff line
@@ -15,6 +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 @@ 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 @@ struct cpu_priv {

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;
@@ -445,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
	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 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
	snd_soc_card_set_drvdata(&priv->card, priv);

	ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
	if (ret && ret != -EPROBE_DEFER)
	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);
+4 −3
Original line number Diff line number Diff line
@@ -540,7 +540,8 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);

int asoc_simple_init_jack(struct snd_soc_card *card,
			  struct asoc_simple_jack *sjack,
			  int is_hp, char *prefix)
			  int is_hp, char *prefix,
			  char *pin)
{
	struct device *dev = card->dev;
	enum of_gpio_flags flags;
@@ -557,12 +558,12 @@ int asoc_simple_init_jack(struct snd_soc_card *card,

	if (is_hp) {
		snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
		pin_name	= "Headphones";
		pin_name	= pin ? pin : "Headphones";
		gpio_name	= "Headphone detection";
		mask		= SND_JACK_HEADPHONE;
	} else {
		snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
		pin_name	= "Mic Jack";
		pin_name	= pin ? pin : "Mic Jack";
		gpio_name	= "Mic detection";
		mask		= SND_JACK_MICROPHONE;
	}