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 | ||