Skip to content

Commit

Permalink
ASoC: Add a notifier for jack status changes
Browse files Browse the repository at this point in the history
Some systems provide both mechanical and electrical detection of jack
status changes. On such systems power savings can be achieved by only
enabling the electrical detection methods when physical insertion has
been detected.

Begin supporting such systems by providing a notifier for jack status
changes which can be used to trigger any reconfiguration.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
  • Loading branch information
Mark Brown committed Mar 22, 2010
1 parent c96907f commit d5021ec
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/notifier.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -261,6 +262,10 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_pin *pins);
void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
struct notifier_block *nb);
void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
struct notifier_block *nb);
#ifdef CONFIG_GPIOLIB
int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_gpio *gpios);
Expand Down Expand Up @@ -364,6 +369,7 @@ struct snd_soc_jack {
struct snd_soc_card *card;
struct list_head pins;
int status;
struct blocking_notifier_head notifier;
};

/* SoC PCM stream information */
Expand Down
38 changes: 38 additions & 0 deletions sound/soc/soc-jack.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
{
jack->card = card;
INIT_LIST_HEAD(&jack->pins);
BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);

return snd_jack_new(card->codec->card, id, type, &jack->jack);
}
Expand Down Expand Up @@ -93,6 +94,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
snd_soc_dapm_disable_pin(codec, pin->pin);
}

/* Report before the DAPM sync to help users updating micbias status */
blocking_notifier_call_chain(&jack->notifier, status, NULL);

snd_soc_dapm_sync(codec);

snd_jack_report(jack->jack, status);
Expand Down Expand Up @@ -143,6 +147,40 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
}
EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);

/**
* snd_soc_jack_notifier_register - Register a notifier for jack status
*
* @jack: ASoC jack
* @nb: Notifier block to register
*
* Register for notification of the current status of the jack. Note
* that it is not possible to report additional jack events in the
* callback from the notifier, this is intended to support
* applications such as enabling electrical detection only when a
* mechanical detection event has occurred.
*/
void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
struct notifier_block *nb)
{
blocking_notifier_chain_register(&jack->notifier, nb);
}
EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register);

/**
* snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
*
* @jack: ASoC jack
* @nb: Notifier block to unregister
*
* Stop notifying for status changes.
*/
void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
struct notifier_block *nb)
{
blocking_notifier_chain_unregister(&jack->notifier, nb);
}
EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);

#ifdef CONFIG_GPIOLIB
/* gpio detect */
static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
Expand Down

0 comments on commit d5021ec

Please sign in to comment.