diff options
author | Leon Romanovsky <leon@leon.nu> | 2012-02-02 15:13:37 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-02-02 17:27:52 -0500 |
commit | d559f1e5ad2d839f0a2192526c857cd0b24bf420 (patch) | |
tree | c6dcda95d3efcfd7478469fd5f11c139d61eb347 /sound/soc/tegra/tegra_alc5632.c | |
parent | 25bfe662e8c42f84851f79ed6ada5ef96a2ff329 (diff) |
ASoC: Tegra+ALC5632: Enable headset autodetection on PAZ00 board.
This patch is adding device tree support of headset autodetection on PAZ00 board.
Signed-off-by: Leon Romanovsky <leon@leon.nu>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra/tegra_alc5632.c')
-rw-r--r-- | sound/soc/tegra/tegra_alc5632.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index c0ba1e420192..17941392fd70 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/of_gpio.h> | ||
21 | 22 | ||
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/jack.h> | 24 | #include <sound/jack.h> |
@@ -34,9 +35,13 @@ | |||
34 | 35 | ||
35 | #define DRV_NAME "tegra-alc5632" | 36 | #define DRV_NAME "tegra-alc5632" |
36 | 37 | ||
38 | #define GPIO_HP_DET BIT(0) | ||
39 | |||
37 | struct tegra_alc5632 { | 40 | struct tegra_alc5632 { |
38 | struct tegra_asoc_utils_data util_data; | 41 | struct tegra_asoc_utils_data util_data; |
39 | struct platform_device *pcm_dev; | 42 | struct platform_device *pcm_dev; |
43 | int gpio_requested; | ||
44 | int gpio_hp_det; | ||
40 | }; | 45 | }; |
41 | 46 | ||
42 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, | 47 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, |
@@ -86,6 +91,13 @@ static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = { | |||
86 | }, | 91 | }, |
87 | }; | 92 | }; |
88 | 93 | ||
94 | static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = { | ||
95 | .name = "Headset detection", | ||
96 | .report = SND_JACK_HEADSET, | ||
97 | .debounce_time = 150, | ||
98 | .invert = 1, | ||
99 | }; | ||
100 | |||
89 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { | 101 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { |
90 | SND_SOC_DAPM_SPK("Int Spk", NULL), | 102 | SND_SOC_DAPM_SPK("Int Spk", NULL), |
91 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | 103 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), |
@@ -114,6 +126,9 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
114 | { | 126 | { |
115 | struct snd_soc_codec *codec = rtd->codec; | 127 | struct snd_soc_codec *codec = rtd->codec; |
116 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 128 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
129 | struct device_node *np = codec->card->dev->of_node; | ||
130 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); | ||
131 | int ret; | ||
117 | 132 | ||
118 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, | 133 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, |
119 | &tegra_alc5632_hs_jack); | 134 | &tegra_alc5632_hs_jack); |
@@ -121,6 +136,16 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
121 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), | 136 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), |
122 | tegra_alc5632_hs_jack_pins); | 137 | tegra_alc5632_hs_jack_pins); |
123 | 138 | ||
139 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | ||
140 | |||
141 | if (gpio_is_valid(machine->gpio_hp_det)) { | ||
142 | tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; | ||
143 | snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, | ||
144 | 1, | ||
145 | &tegra_alc5632_hp_jack_gpio); | ||
146 | machine->gpio_requested |= GPIO_HP_DET; | ||
147 | } | ||
148 | |||
124 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | 149 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); |
125 | 150 | ||
126 | return 0; | 151 | return 0; |
@@ -239,13 +264,19 @@ err: | |||
239 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | 264 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) |
240 | { | 265 | { |
241 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 266 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
242 | struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); | 267 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); |
268 | |||
269 | if (machine->gpio_requested & GPIO_HP_DET) | ||
270 | snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, | ||
271 | 1, | ||
272 | &tegra_alc5632_hp_jack_gpio); | ||
273 | machine->gpio_requested = 0; | ||
243 | 274 | ||
244 | snd_soc_unregister_card(card); | 275 | snd_soc_unregister_card(card); |
245 | 276 | ||
246 | tegra_asoc_utils_fini(&alc5632->util_data); | 277 | tegra_asoc_utils_fini(&machine->util_data); |
247 | if (!IS_ERR(alc5632->pcm_dev)) | 278 | if (!IS_ERR(machine->pcm_dev)) |
248 | platform_device_unregister(alc5632->pcm_dev); | 279 | platform_device_unregister(machine->pcm_dev); |
249 | 280 | ||
250 | return 0; | 281 | return 0; |
251 | } | 282 | } |