alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control
@ 2011-03-16 10:58 Dimitris Papastamos
  2011-03-16 10:58 ` [PATCH 2/2 v3] ASoC: soc-core: Add helper function to handle dynamic update of controls Dimitris Papastamos
  2011-03-16 11:45 ` [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Clemens Ladisch
  0 siblings, 2 replies; 3+ messages in thread
From: Dimitris Papastamos @ 2011-03-16 10:58 UTC (permalink / raw)
  To: Mark Brown, lrg, Jaroslav Kysela, Takashi Iwai, Clemens Ladisch
  Cc: alsa-devel, patches, lrg

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 allow ALSA Mixer to update the
controls dynamically.

Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
---
 Hi,

 Any potentially locking related issues have been fixed now.
 Any comments on whether it would be advisable to use the same `numid' when
 I update an existing control?

 Thanks,
 Dimitris

 include/sound/control.h |    1 +
 sound/core/control.c    |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/include/sound/control.h b/include/sound/control.h
index e67db28..2a2fd82 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, bool 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..1d2b524 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -368,6 +368,71 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
 EXPORT_SYMBOL(snd_ctl_add);
 
 /**
+ * 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 given control.  If the given control does not exist
+ * and the add_on_update flag is set, the control is added.  If the
+ * control exists, it is destroyed first.
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ *
+ * It frees automatically the control which cannot be added or updated.
+ */
+int snd_ctl_update(struct snd_card *card, struct snd_kcontrol *kcontrol,
+		   bool add_on_update)
+{
+	struct snd_ctl_elem_id id;
+	unsigned int idx;
+	struct snd_kcontrol *old;
+	int ret;
+
+	if (!kcontrol)
+		return -EINVAL;
+	if (snd_BUG_ON(!card || !kcontrol->info)) {
+		ret = -EINVAL;
+		goto error;
+	}
+	id = kcontrol->id;
+	down_write(&card->controls_rwsem);
+	old = snd_ctl_find_id(card, &id);
+	if (!old) {
+		if (add_on_update)
+			goto add;
+		up_write(&card->controls_rwsem);
+		ret = -EINVAL;
+		goto error;
+	}
+	ret = snd_ctl_remove(card, old);
+	if (ret < 0) {
+		up_write(&card->controls_rwsem);
+		goto error;
+	}
+add:
+	if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
+		up_write(&card->controls_rwsem);
+		ret = -ENOMEM;
+		goto error;
+	}
+	list_add_tail(&kcontrol->list, &card->controls);
+	card->controls_count += kcontrol->count;
+	kcontrol->id.numid = card->last_numid + 1;
+	card->last_numid += kcontrol->count;
+	up_write(&card->controls_rwsem);
+	for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
+		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
+	return 0;
+
+error:
+	snd_ctl_free_one(kcontrol);
+	return ret;
+}
+
+EXPORT_SYMBOL(snd_ctl_update);
+
+/**
  * snd_ctl_remove - remove the control from the card and release it
  * @card: the card instance
  * @kcontrol: the control instance to remove
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2 v3] ASoC: soc-core: Add helper function to handle dynamic update of controls
  2011-03-16 10:58 [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Dimitris Papastamos
@ 2011-03-16 10:58 ` Dimitris Papastamos
  2011-03-16 11:45 ` [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Clemens Ladisch
  1 sibling, 0 replies; 3+ messages in thread
From: Dimitris Papastamos @ 2011-03-16 10:58 UTC (permalink / raw)
  To: Mark Brown, lrg, Jaroslav Kysela, Takashi Iwai, Clemens Ladisch
  Cc: alsa-devel, patches, lrg

This function can be used to update or add controls at runtime.  It will
always try to add a given control if it does not already exist.

Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
---
 include/sound/soc.h  |    2 ++
 sound/soc/soc-core.c |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index bfa4836..509c1ea 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -344,6 +344,8 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
 				  const char *prefix);
 int snd_soc_add_controls(struct snd_soc_codec *codec,
 	const struct snd_kcontrol_new *controls, int num_controls);
+int snd_soc_update_controls(struct snd_soc_codec *codec,
+	const struct snd_kcontrol_new *controls, int num_controls);
 int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_info *uinfo);
 int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 17efacd..7ce2a07 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2420,6 +2420,39 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
 EXPORT_SYMBOL_GPL(snd_soc_add_controls);
 
 /**
+ * snd_soc_update_controls - update an array of controls
+ * Convienience function to update a list of controls.
+ *
+ * @codec: codec to update controls of
+ * @controls: array of controls to update
+ * @num_controls: number of elements in the array
+ *
+ * Return 0 for success, else error.
+ */
+int snd_soc_update_controls(struct snd_soc_codec *codec,
+	const struct snd_kcontrol_new *controls, int num_controls)
+{
+	struct snd_card *card = codec->card->snd_card;
+	int err, i;
+
+	for (i = 0; i < num_controls; i++) {
+		const struct snd_kcontrol_new *control = &controls[i];
+		/* always add on update if not already added */
+		err = snd_ctl_update(card, snd_soc_cnew(control, codec,
+							control->name,
+							codec->name_prefix), true);
+		if (err < 0) {
+			dev_err(codec->dev, "%s: Failed to update %s: %d\n",
+				codec->name, control->name, err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_update_controls);
+
+/**
  * snd_soc_info_enum_double - enumerated double mixer info callback
  * @kcontrol: mixer control
  * @uinfo: control element information
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control
  2011-03-16 10:58 [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Dimitris Papastamos
  2011-03-16 10:58 ` [PATCH 2/2 v3] ASoC: soc-core: Add helper function to handle dynamic update of controls Dimitris Papastamos
@ 2011-03-16 11:45 ` Clemens Ladisch
  1 sibling, 0 replies; 3+ messages in thread
From: Clemens Ladisch @ 2011-03-16 11:45 UTC (permalink / raw)
  To: Dimitris Papastamos
  Cc: alsa-devel, Mark Brown, Takashi Iwai, patches, lrg, lrg

Dimitris Papastamos wrote:
> Any comments on whether it would be advisable to use the same `numid' when
> I update an existing control?

"Update" sounds like it would change some properties of the existing
control.  However, what this function does is to entirely replace the
old control(s) with new one(s) (and this is also how the userspace
notifications look), so I think assigning a new ID is appropriate here,
if you call it snd_ctl_replace().  :)


Regards,
Clemens

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-03-16 11:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-16 10:58 [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Dimitris Papastamos
2011-03-16 10:58 ` [PATCH 2/2 v3] ASoC: soc-core: Add helper function to handle dynamic update of controls Dimitris Papastamos
2011-03-16 11:45 ` [PATCH 1/2 v3] ALSA: Add snd_ctl_update() to dynamically update a control Clemens Ladisch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).