[alsa-devel] [PATCH 1/2] ALSA: Add snd_ctl_update() to dynamically update a control
Dimitris Papastamos
dp at opensource.wolfsonmicro.com
Tue Mar 15 13:21:41 CET 2011
Add a function to dynamically update a given control. If the
control does not already exist, a third parameter is used to determine
whether to actually add that control. This is useful in cases where
downloadable firmware at runtime can add or update existing controls.
A separate patch needs to be made to make ALSA Mixer cope with this.
Signed-off-by: Dimitris Papastamos <dp at opensource.wolfsonmicro.com>
---
include/sound/control.h | 1 +
sound/core/control.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/include/sound/control.h b/include/sound/control.h
index e67db28..12e4de7 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -113,6 +113,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, v
void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+int snd_ctl_update(struct snd_card * card, struct snd_kcontrol * kcontrol, int add_on_update);
int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
diff --git a/sound/core/control.c b/sound/core/control.c
index db51e4e..db23745 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -397,6 +397,50 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
EXPORT_SYMBOL(snd_ctl_remove);
/**
+ * snd_ctl_update - update the control instance of the card
+ * @card: the card instance
+ * @kcontrol: the control instance to update
+ * @add_on_update: add the control if not already added
+ *
+ * Updates the control instance created via snd_ctl_new() or
+ * snd_ctl_new1() of the given card.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ *
+ */
+int snd_ctl_update(struct snd_card *card, struct snd_kcontrol *kcontrol,
+ int add_on_update)
+{
+ struct snd_ctl_elem_id id;
+ struct snd_kcontrol *old;
+ int ret;
+
+ if (!kcontrol)
+ return -EINVAL;
+ if (snd_BUG_ON(!card || !kcontrol->info))
+ return -EINVAL;
+ id = kcontrol->id;
+ down_write(&card->controls_rwsem);
+ old = snd_ctl_find_id(card, &id);
+ if (!old) {
+ up_write(&card->controls_rwsem);
+ if (add_on_update)
+ return snd_ctl_add(card, kcontrol);
+ return -EINVAL;
+ }
+ ret = snd_ctl_remove(card, old);
+ if (ret < 0)
+ return ret;
+ up_write(&card->controls_rwsem);
+ ret = snd_ctl_add(card, kcontrol);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+EXPORT_SYMBOL(snd_ctl_update);
+
+/**
* snd_ctl_remove_id - remove the control of the given id and release it
* @card: the card instance
* @id: the control id to remove
--
1.7.4.1
More information about the Alsa-devel
mailing list