diff options
-rw-r--r-- | include/sound/soc.h | 6 | ||||
-rw-r--r-- | sound/soc/soc-jack.c | 38 |
2 files changed, 44 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index b8bac6ae6244..80dfac162723 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/notifier.h> | ||
18 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
19 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -261,6 +262,10 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, | |||
261 | void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); | 262 | void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask); |
262 | int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | 263 | int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, |
263 | struct snd_soc_jack_pin *pins); | 264 | struct snd_soc_jack_pin *pins); |
265 | void snd_soc_jack_notifier_register(struct snd_soc_jack *jack, | ||
266 | struct notifier_block *nb); | ||
267 | void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack, | ||
268 | struct notifier_block *nb); | ||
264 | #ifdef CONFIG_GPIOLIB | 269 | #ifdef CONFIG_GPIOLIB |
265 | int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | 270 | int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, |
266 | struct snd_soc_jack_gpio *gpios); | 271 | struct snd_soc_jack_gpio *gpios); |
@@ -364,6 +369,7 @@ struct snd_soc_jack { | |||
364 | struct snd_soc_card *card; | 369 | struct snd_soc_card *card; |
365 | struct list_head pins; | 370 | struct list_head pins; |
366 | int status; | 371 | int status; |
372 | struct blocking_notifier_head notifier; | ||
367 | }; | 373 | }; |
368 | 374 | ||
369 | /* SoC PCM stream information */ | 375 | /* SoC PCM stream information */ |
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 3c07a94c2e30..f8fd22cc70bc 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type, | |||
37 | { | 37 | { |
38 | jack->card = card; | 38 | jack->card = card; |
39 | INIT_LIST_HEAD(&jack->pins); | 39 | INIT_LIST_HEAD(&jack->pins); |
40 | BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); | ||
40 | 41 | ||
41 | return snd_jack_new(card->codec->card, id, type, &jack->jack); | 42 | return snd_jack_new(card->codec->card, id, type, &jack->jack); |
42 | } | 43 | } |
@@ -93,6 +94,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
93 | snd_soc_dapm_disable_pin(codec, pin->pin); | 94 | snd_soc_dapm_disable_pin(codec, pin->pin); |
94 | } | 95 | } |
95 | 96 | ||
97 | /* Report before the DAPM sync to help users updating micbias status */ | ||
98 | blocking_notifier_call_chain(&jack->notifier, status, NULL); | ||
99 | |||
96 | snd_soc_dapm_sync(codec); | 100 | snd_soc_dapm_sync(codec); |
97 | 101 | ||
98 | snd_jack_report(jack->jack, status); | 102 | snd_jack_report(jack->jack, status); |
@@ -143,6 +147,40 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | |||
143 | } | 147 | } |
144 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); | 148 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); |
145 | 149 | ||
150 | /** | ||
151 | * snd_soc_jack_notifier_register - Register a notifier for jack status | ||
152 | * | ||
153 | * @jack: ASoC jack | ||
154 | * @nb: Notifier block to register | ||
155 | * | ||
156 | * Register for notification of the current status of the jack. Note | ||
157 | * that it is not possible to report additional jack events in the | ||
158 | * callback from the notifier, this is intended to support | ||
159 | * applications such as enabling electrical detection only when a | ||
160 | * mechanical detection event has occurred. | ||
161 | */ | ||
162 | void snd_soc_jack_notifier_register(struct snd_soc_jack *jack, | ||
163 | struct notifier_block *nb) | ||
164 | { | ||
165 | blocking_notifier_chain_register(&jack->notifier, nb); | ||
166 | } | ||
167 | EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register); | ||
168 | |||
169 | /** | ||
170 | * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status | ||
171 | * | ||
172 | * @jack: ASoC jack | ||
173 | * @nb: Notifier block to unregister | ||
174 | * | ||
175 | * Stop notifying for status changes. | ||
176 | */ | ||
177 | void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack, | ||
178 | struct notifier_block *nb) | ||
179 | { | ||
180 | blocking_notifier_chain_unregister(&jack->notifier, nb); | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister); | ||
183 | |||
146 | #ifdef CONFIG_GPIOLIB | 184 | #ifdef CONFIG_GPIOLIB |
147 | /* gpio detect */ | 185 | /* gpio detect */ |
148 | static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) | 186 | static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) |