ALSA: core: Expose sound card online/offline state
Expose sound card online/offline state to procfs so userspace application can poll and read sound card's state. Change-Id: Ie605ad57f4ce5abf62a216e790407029658ac3c9 Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org> Signed-off-by: Banajit Goswami <bgoswami@codeaurora.org> Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org> Signed-off-by: Meng Wang <mwang@codeaurora.org>
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
2b0715dd21
commit
473195fead
@@ -134,6 +134,9 @@ struct snd_card {
|
|||||||
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
|
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
|
||||||
bool registered; /* card_dev is registered? */
|
bool registered; /* card_dev is registered? */
|
||||||
wait_queue_head_t remove_sleep;
|
wait_queue_head_t remove_sleep;
|
||||||
|
int offline; /* if this sound card is offline */
|
||||||
|
unsigned long offline_change;
|
||||||
|
wait_queue_head_t offline_poll_wait;
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
unsigned int power_state; /* power state */
|
unsigned int power_state; /* power state */
|
||||||
@@ -253,6 +256,8 @@ int snd_component_add(struct snd_card *card, const char *component);
|
|||||||
int snd_card_file_add(struct snd_card *card, struct file *file);
|
int snd_card_file_add(struct snd_card *card, struct file *file);
|
||||||
int snd_card_file_remove(struct snd_card *card, struct file *file);
|
int snd_card_file_remove(struct snd_card *card, struct file *file);
|
||||||
#define snd_card_unref(card) put_device(&(card)->card_dev)
|
#define snd_card_unref(card) put_device(&(card)->card_dev)
|
||||||
|
void snd_card_change_online_state(struct snd_card *card, int online);
|
||||||
|
bool snd_card_is_online_state(struct snd_card *card);
|
||||||
|
|
||||||
#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
|
#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
|
||||||
|
|
||||||
|
|||||||
@@ -556,6 +556,8 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void snd_soc_card_change_online_state(struct snd_soc_card *soc_card,
|
||||||
|
int online);
|
||||||
#ifdef CONFIG_SND_SOC_AC97_BUS
|
#ifdef CONFIG_SND_SOC_AC97_BUS
|
||||||
struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
|
struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
|
||||||
struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
|
struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ static char *slots[SNDRV_CARDS];
|
|||||||
module_param_array(slots, charp, NULL, 0444);
|
module_param_array(slots, charp, NULL, 0444);
|
||||||
MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
|
MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
|
||||||
|
|
||||||
|
#define SND_CARD_STATE_MAX_LEN 16
|
||||||
|
|
||||||
/* return non-zero if the given index is reserved for the given
|
/* return non-zero if the given index is reserved for the given
|
||||||
* module via slots option
|
* module via slots option
|
||||||
*/
|
*/
|
||||||
@@ -107,9 +109,39 @@ static void snd_card_id_read(struct snd_info_entry *entry,
|
|||||||
snd_iprintf(buffer, "%s\n", entry->card->id);
|
snd_iprintf(buffer, "%s\n", entry->card->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t snd_card_state_read(struct snd_info_entry *entry,
|
||||||
|
void *file_private_data, struct file *file,
|
||||||
|
char __user *buf, size_t count, loff_t pos)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char buffer[SND_CARD_STATE_MAX_LEN];
|
||||||
|
|
||||||
|
/* make sure offline is updated prior to wake up */
|
||||||
|
rmb();
|
||||||
|
len = snprintf(buffer, sizeof(buffer), "%s\n",
|
||||||
|
entry->card->offline ? "OFFLINE" : "ONLINE");
|
||||||
|
return simple_read_from_buffer(buf, count, &pos, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int snd_card_state_poll(struct snd_info_entry *entry,
|
||||||
|
void *private_data, struct file *file,
|
||||||
|
poll_table *wait)
|
||||||
|
{
|
||||||
|
poll_wait(file, &entry->card->offline_poll_wait, wait);
|
||||||
|
if (xchg(&entry->card->offline_change, 0))
|
||||||
|
return POLLIN | POLLPRI | POLLRDNORM;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct snd_info_entry_ops snd_card_state_proc_ops = {
|
||||||
|
.read = snd_card_state_read,
|
||||||
|
.poll = snd_card_state_poll,
|
||||||
|
};
|
||||||
|
|
||||||
static int init_info_for_card(struct snd_card *card)
|
static int init_info_for_card(struct snd_card *card)
|
||||||
{
|
{
|
||||||
struct snd_info_entry *entry;
|
struct snd_info_entry *entry, *entry_state;
|
||||||
|
|
||||||
entry = snd_info_create_card_entry(card, "id", card->proc_root);
|
entry = snd_info_create_card_entry(card, "id", card->proc_root);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@@ -119,6 +151,17 @@ static int init_info_for_card(struct snd_card *card)
|
|||||||
entry->c.text.read = snd_card_id_read;
|
entry->c.text.read = snd_card_id_read;
|
||||||
card->proc_id = entry;
|
card->proc_id = entry;
|
||||||
|
|
||||||
|
entry_state = snd_info_create_card_entry(card, "state",
|
||||||
|
card->proc_root);
|
||||||
|
if (!entry_state) {
|
||||||
|
dev_dbg(card->dev, "unable to create card entry state\n");
|
||||||
|
card->proc_id = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
entry_state->size = SND_CARD_STATE_MAX_LEN;
|
||||||
|
entry_state->content = SNDRV_INFO_CONTENT_DATA;
|
||||||
|
entry_state->c.ops = &snd_card_state_proc_ops;
|
||||||
|
|
||||||
return snd_info_card_register(card);
|
return snd_info_card_register(card);
|
||||||
}
|
}
|
||||||
#else /* !CONFIG_SND_PROC_FS */
|
#else /* !CONFIG_SND_PROC_FS */
|
||||||
@@ -257,6 +300,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||||||
#endif
|
#endif
|
||||||
init_waitqueue_head(&card->remove_sleep);
|
init_waitqueue_head(&card->remove_sleep);
|
||||||
|
|
||||||
|
init_waitqueue_head(&card->offline_poll_wait);
|
||||||
device_initialize(&card->card_dev);
|
device_initialize(&card->card_dev);
|
||||||
card->card_dev.parent = parent;
|
card->card_dev.parent = parent;
|
||||||
card->card_dev.class = sound_class;
|
card->card_dev.class = sound_class;
|
||||||
@@ -1000,6 +1044,35 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_card_file_remove);
|
EXPORT_SYMBOL(snd_card_file_remove);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_card_change_online_state - mark card's online/offline state
|
||||||
|
* @card: Card to mark
|
||||||
|
* @online: whether online of offline
|
||||||
|
*
|
||||||
|
* Mutes the DAI DAC.
|
||||||
|
*/
|
||||||
|
void snd_card_change_online_state(struct snd_card *card, int online)
|
||||||
|
{
|
||||||
|
snd_printd("snd card %s state change %d -> %d\n",
|
||||||
|
card->shortname, !card->offline, online);
|
||||||
|
card->offline = !online;
|
||||||
|
/* make sure offline is updated prior to wake up */
|
||||||
|
wmb();
|
||||||
|
xchg(&card->offline_change, 1);
|
||||||
|
wake_up_interruptible(&card->offline_poll_wait);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_card_change_online_state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_card_is_online_state - return true if card is online state
|
||||||
|
* @card: Card to query
|
||||||
|
*/
|
||||||
|
bool snd_card_is_online_state(struct snd_card *card)
|
||||||
|
{
|
||||||
|
return !card->offline;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_card_is_online_state);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
/**
|
/**
|
||||||
* snd_power_wait - wait until the power-state is changed.
|
* snd_power_wait - wait until the power-state is changed.
|
||||||
|
|||||||
@@ -3271,6 +3271,17 @@ struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
|
EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_soc_card_change_online_state - Mark if soc card is online/offline
|
||||||
|
*
|
||||||
|
* @soc_card : soc_card to mark
|
||||||
|
*/
|
||||||
|
void snd_soc_card_change_online_state(struct snd_soc_card *soc_card, int online)
|
||||||
|
{
|
||||||
|
snd_card_change_online_state(soc_card->snd_card, online);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_soc_card_change_online_state);
|
||||||
|
|
||||||
/* Retrieve a card's name from device tree */
|
/* Retrieve a card's name from device tree */
|
||||||
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
|
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
|
||||||
const char *propname)
|
const char *propname)
|
||||||
|
|||||||
Reference in New Issue
Block a user