Commit 5f52d4dd authored by Mark Brown's avatar Mark Brown

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
...@@ -69,6 +69,9 @@ Optional properties: ...@@ -69,6 +69,9 @@ Optional properties:
coexisting in order to support the old bindings coexisting in order to support the old bindings
of wm8962 and sgtl5000. 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: Optional unless SSI is selected as a CPU DAI:
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
#include <sound/soc.h> #include <sound/soc.h>
#define asoc_simple_init_hp(card, sjack, prefix) \ #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) \ #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 { struct asoc_simple_dai {
const char *name; const char *name;
...@@ -131,7 +131,7 @@ int asoc_simple_parse_pin_switches(struct snd_soc_card *card, ...@@ -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, int asoc_simple_init_jack(struct snd_soc_card *card,
struct asoc_simple_jack *sjack, 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, int asoc_simple_init_priv(struct asoc_simple_priv *priv,
struct link_info *li); struct link_info *li);
......
...@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD ...@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD
depends on OF && I2C depends on OF && I2C
# enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m: # enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
depends on SND_AC97_CODEC || SND_AC97_CODEC=n depends on SND_AC97_CODEC || SND_AC97_CODEC=n
select SND_SIMPLE_CARD_UTILS
select SND_SOC_IMX_AUDMUX select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_PCM_DMA select SND_SOC_IMX_PCM_DMA
select SND_SOC_FSL_ESAI select SND_SOC_FSL_ESAI
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#endif #endif
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/jack.h>
#include <sound/simple_card_utils.h>
#include "fsl_esai.h" #include "fsl_esai.h"
#include "fsl_sai.h" #include "fsl_sai.h"
...@@ -65,6 +67,8 @@ struct cpu_priv { ...@@ -65,6 +67,8 @@ struct cpu_priv {
/** /**
* struct fsl_asoc_card_priv - Freescale Generic ASOC card private data * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data
* @dai_link: DAI link structure including normal one and DPCM link * @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 * @pdev: platform device pointer
* @codec_priv: CODEC private data * @codec_priv: CODEC private data
* @cpu_priv: CPU private data * @cpu_priv: CPU private data
...@@ -79,6 +83,8 @@ struct cpu_priv { ...@@ -79,6 +83,8 @@ struct cpu_priv {
struct fsl_asoc_card_priv { struct fsl_asoc_card_priv {
struct snd_soc_dai_link dai_link[3]; 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 platform_device *pdev;
struct codec_priv codec_priv; struct codec_priv codec_priv;
struct cpu_priv cpu_priv; struct cpu_priv cpu_priv;
...@@ -445,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node *np, ...@@ -445,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
return 0; 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) static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
{ {
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(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) ...@@ -745,8 +789,37 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(&priv->card, priv); snd_soc_card_set_drvdata(&priv->card, priv);
ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
if (ret && ret != -EPROBE_DEFER) if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 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: asrc_fail:
of_node_put(asrc_np); of_node_put(asrc_np);
......
...@@ -540,7 +540,8 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches); ...@@ -540,7 +540,8 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
int asoc_simple_init_jack(struct snd_soc_card *card, int asoc_simple_init_jack(struct snd_soc_card *card,
struct asoc_simple_jack *sjack, struct asoc_simple_jack *sjack,
int is_hp, char *prefix) int is_hp, char *prefix,
char *pin)
{ {
struct device *dev = card->dev; struct device *dev = card->dev;
enum of_gpio_flags flags; enum of_gpio_flags flags;
...@@ -557,12 +558,12 @@ int asoc_simple_init_jack(struct snd_soc_card *card, ...@@ -557,12 +558,12 @@ int asoc_simple_init_jack(struct snd_soc_card *card,
if (is_hp) { if (is_hp) {
snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix); snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
pin_name = "Headphones"; pin_name = pin ? pin : "Headphones";
gpio_name = "Headphone detection"; gpio_name = "Headphone detection";
mask = SND_JACK_HEADPHONE; mask = SND_JACK_HEADPHONE;
} else { } else {
snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix); snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
pin_name = "Mic Jack"; pin_name = pin ? pin : "Mic Jack";
gpio_name = "Mic detection"; gpio_name = "Mic detection";
mask = SND_JACK_MICROPHONE; mask = SND_JACK_MICROPHONE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment