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
This commit is contained in:
Коммит
5f52d4dda5
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче