diff options
author | Dylan Reid <dgreid@chromium.org> | 2014-10-01 14:25:20 -0700 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-02 16:53:40 +0100 |
commit | 3fe240326cc395c66eda0518b1945ea505afd1fc (patch) | |
tree | 96acd1e5ba508d7fb1ea99bbe762d0af4c4442fc /sound/soc | |
parent | 04a0b8ef6b27c2b6280dcbfcdd418b7d851f8491 (diff) | |
download | linux-3fe240326cc395c66eda0518b1945ea505afd1fc.tar.bz2 |
ASoC: simple-card: Add mic and hp detect gpios.
Allow Headphone and Microphone jack detect gpios to be specified in
device tree. This will allow a few systems including rk3288_max98090
to use simple-card instead of having their own board file.
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/generic/simple-card.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 709ce67849c8..fcb431fe20b4 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -10,10 +10,13 @@ */ #include <linux/clk.h> #include <linux/device.h> +#include <linux/gpio.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/string.h> +#include <sound/jack.h> #include <sound/simple_card.h> #include <sound/soc-dai.h> #include <sound/soc.h> @@ -25,6 +28,8 @@ struct simple_card_data { struct asoc_simple_dai codec_dai; } *dai_props; unsigned int mclk_fs; + int gpio_hp_det; + int gpio_mic_det; struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ }; @@ -54,6 +59,32 @@ static struct snd_soc_ops asoc_simple_card_ops = { .hw_params = asoc_simple_card_hw_params, }; +static struct snd_soc_jack simple_card_hp_jack; +static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = { + { + .pin = "Headphones", + .mask = SND_JACK_HEADPHONE, + }, +}; +static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = { + .name = "Headphone detection", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, +}; + +static struct snd_soc_jack simple_card_mic_jack; +static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = { + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, +}; +static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = { + .name = "Mic detection", + .report = SND_JACK_MICROPHONE, + .debounce_time = 150, +}; + static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, struct asoc_simple_dai *set) { @@ -109,6 +140,28 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) if (ret < 0) return ret; + if (gpio_is_valid(priv->gpio_hp_det)) { + snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE, + &simple_card_hp_jack); + snd_soc_jack_add_pins(&simple_card_hp_jack, + ARRAY_SIZE(simple_card_hp_jack_pins), + simple_card_hp_jack_pins); + + simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; + snd_soc_jack_add_gpios(&simple_card_hp_jack, 1, + &simple_card_hp_jack_gpio); + } + + if (gpio_is_valid(priv->gpio_mic_det)) { + snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE, + &simple_card_mic_jack); + snd_soc_jack_add_pins(&simple_card_mic_jack, + ARRAY_SIZE(simple_card_mic_jack_pins), + simple_card_mic_jack_pins); + simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; + snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, + &simple_card_mic_jack_gpio); + } return 0; } @@ -383,6 +436,16 @@ static int asoc_simple_card_parse_of(struct device_node *node, return ret; } + priv->gpio_hp_det = of_get_named_gpio(node, + "simple-audio-card,hp-det-gpio", 0); + if (priv->gpio_hp_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + + priv->gpio_mic_det = of_get_named_gpio(node, + "simple-audio-card,mic-det-gpio", 0); + if (priv->gpio_mic_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!priv->snd_card.name) priv->snd_card.name = priv->snd_card.dai_link->name; @@ -502,6 +565,16 @@ err: static int asoc_simple_card_remove(struct platform_device *pdev) { + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct simple_card_data *priv = snd_soc_card_get_drvdata(card); + + if (gpio_is_valid(priv->gpio_hp_det)) + snd_soc_jack_free_gpios(&simple_card_hp_jack, 1, + &simple_card_hp_jack_gpio); + if (gpio_is_valid(priv->gpio_mic_det)) + snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, + &simple_card_mic_jack_gpio); + return asoc_simple_card_unref(pdev); } |