diff options
| author | Dylan Reid <dgreid@chromium.org> | 2014-10-01 17:25:20 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2014-10-02 11:53:40 -0400 |
| commit | 3fe240326cc395c66eda0518b1945ea505afd1fc (patch) | |
| tree | 96acd1e5ba508d7fb1ea99bbe762d0af4c4442fc | |
| parent | 04a0b8ef6b27c2b6280dcbfcdd418b7d851f8491 (diff) | |
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>
| -rw-r--r-- | Documentation/devicetree/bindings/sound/simple-card.txt | 4 | ||||
| -rw-r--r-- | sound/soc/generic/simple-card.c | 73 |
2 files changed, 77 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index c2e9841dfce4..72d94b7aa5f5 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
| @@ -17,6 +17,10 @@ Optional properties: | |||
| 17 | source. | 17 | source. |
| 18 | - simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec | 18 | - simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec |
| 19 | mclk. | 19 | mclk. |
| 20 | - simple-audio-card,hp_det_gpio : Reference to GPIO that signals when | ||
| 21 | headphones are attached. | ||
| 22 | - simple-audio-card,mic_det_gpio : Reference to GPIO that signals when | ||
| 23 | a microphone is attached. | ||
| 20 | 24 | ||
| 21 | Optional subnodes: | 25 | Optional subnodes: |
| 22 | 26 | ||
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 @@ | |||
| 10 | */ | 10 | */ |
| 11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <linux/gpio.h> | ||
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/of_gpio.h> | ||
| 15 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 16 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 19 | #include <sound/jack.h> | ||
| 17 | #include <sound/simple_card.h> | 20 | #include <sound/simple_card.h> |
| 18 | #include <sound/soc-dai.h> | 21 | #include <sound/soc-dai.h> |
| 19 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
| @@ -25,6 +28,8 @@ struct simple_card_data { | |||
| 25 | struct asoc_simple_dai codec_dai; | 28 | struct asoc_simple_dai codec_dai; |
| 26 | } *dai_props; | 29 | } *dai_props; |
| 27 | unsigned int mclk_fs; | 30 | unsigned int mclk_fs; |
| 31 | int gpio_hp_det; | ||
| 32 | int gpio_mic_det; | ||
| 28 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ | 33 | struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ |
| 29 | }; | 34 | }; |
| 30 | 35 | ||
| @@ -54,6 +59,32 @@ static struct snd_soc_ops asoc_simple_card_ops = { | |||
| 54 | .hw_params = asoc_simple_card_hw_params, | 59 | .hw_params = asoc_simple_card_hw_params, |
| 55 | }; | 60 | }; |
| 56 | 61 | ||
| 62 | static struct snd_soc_jack simple_card_hp_jack; | ||
| 63 | static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = { | ||
| 64 | { | ||
| 65 | .pin = "Headphones", | ||
| 66 | .mask = SND_JACK_HEADPHONE, | ||
| 67 | }, | ||
| 68 | }; | ||
| 69 | static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = { | ||
| 70 | .name = "Headphone detection", | ||
| 71 | .report = SND_JACK_HEADPHONE, | ||
| 72 | .debounce_time = 150, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct snd_soc_jack simple_card_mic_jack; | ||
| 76 | static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = { | ||
| 77 | { | ||
| 78 | .pin = "Mic Jack", | ||
| 79 | .mask = SND_JACK_MICROPHONE, | ||
| 80 | }, | ||
| 81 | }; | ||
| 82 | static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = { | ||
| 83 | .name = "Mic detection", | ||
| 84 | .report = SND_JACK_MICROPHONE, | ||
| 85 | .debounce_time = 150, | ||
| 86 | }; | ||
| 87 | |||
| 57 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, | 88 | static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, |
| 58 | struct asoc_simple_dai *set) | 89 | struct asoc_simple_dai *set) |
| 59 | { | 90 | { |
| @@ -109,6 +140,28 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
| 109 | if (ret < 0) | 140 | if (ret < 0) |
| 110 | return ret; | 141 | return ret; |
| 111 | 142 | ||
| 143 | if (gpio_is_valid(priv->gpio_hp_det)) { | ||
| 144 | snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE, | ||
| 145 | &simple_card_hp_jack); | ||
| 146 | snd_soc_jack_add_pins(&simple_card_hp_jack, | ||
| 147 | ARRAY_SIZE(simple_card_hp_jack_pins), | ||
| 148 | simple_card_hp_jack_pins); | ||
| 149 | |||
| 150 | simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; | ||
| 151 | snd_soc_jack_add_gpios(&simple_card_hp_jack, 1, | ||
| 152 | &simple_card_hp_jack_gpio); | ||
| 153 | } | ||
| 154 | |||
| 155 | if (gpio_is_valid(priv->gpio_mic_det)) { | ||
| 156 | snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE, | ||
| 157 | &simple_card_mic_jack); | ||
| 158 | snd_soc_jack_add_pins(&simple_card_mic_jack, | ||
| 159 | ARRAY_SIZE(simple_card_mic_jack_pins), | ||
| 160 | simple_card_mic_jack_pins); | ||
| 161 | simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; | ||
| 162 | snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, | ||
| 163 | &simple_card_mic_jack_gpio); | ||
| 164 | } | ||
| 112 | return 0; | 165 | return 0; |
| 113 | } | 166 | } |
| 114 | 167 | ||
| @@ -383,6 +436,16 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
| 383 | return ret; | 436 | return ret; |
| 384 | } | 437 | } |
| 385 | 438 | ||
| 439 | priv->gpio_hp_det = of_get_named_gpio(node, | ||
| 440 | "simple-audio-card,hp-det-gpio", 0); | ||
| 441 | if (priv->gpio_hp_det == -EPROBE_DEFER) | ||
| 442 | return -EPROBE_DEFER; | ||
| 443 | |||
| 444 | priv->gpio_mic_det = of_get_named_gpio(node, | ||
| 445 | "simple-audio-card,mic-det-gpio", 0); | ||
| 446 | if (priv->gpio_mic_det == -EPROBE_DEFER) | ||
| 447 | return -EPROBE_DEFER; | ||
| 448 | |||
| 386 | if (!priv->snd_card.name) | 449 | if (!priv->snd_card.name) |
| 387 | priv->snd_card.name = priv->snd_card.dai_link->name; | 450 | priv->snd_card.name = priv->snd_card.dai_link->name; |
| 388 | 451 | ||
| @@ -502,6 +565,16 @@ err: | |||
| 502 | 565 | ||
| 503 | static int asoc_simple_card_remove(struct platform_device *pdev) | 566 | static int asoc_simple_card_remove(struct platform_device *pdev) |
| 504 | { | 567 | { |
| 568 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 569 | struct simple_card_data *priv = snd_soc_card_get_drvdata(card); | ||
| 570 | |||
| 571 | if (gpio_is_valid(priv->gpio_hp_det)) | ||
| 572 | snd_soc_jack_free_gpios(&simple_card_hp_jack, 1, | ||
| 573 | &simple_card_hp_jack_gpio); | ||
| 574 | if (gpio_is_valid(priv->gpio_mic_det)) | ||
| 575 | snd_soc_jack_free_gpios(&simple_card_mic_jack, 1, | ||
| 576 | &simple_card_mic_jack_gpio); | ||
| 577 | |||
| 505 | return asoc_simple_card_unref(pdev); | 578 | return asoc_simple_card_unref(pdev); |
| 506 | } | 579 | } |
| 507 | 580 | ||
