Instead of returning an error when a control is already present, the index field is incremented and a warning message is printed. This allows drivers to instanciate same control without device and sub device number management ( MIXER type controls).
Change-Id: Ifcc60dca9d1cf4c3a424bb9653296678aa7953cb Signed-off-by: Arnaud Pouliquen arnaud.pouliquen@st.com --- sound/core/control.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/sound/core/control.c b/sound/core/control.c index fb096cb..014e3f4 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -365,6 +365,7 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) struct snd_ctl_elem_id id; unsigned int idx; unsigned int count; + struct snd_kcontrol *elem_set; int err = -EINVAL;
if (! kcontrol) @@ -376,17 +377,24 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) goto error;
down_write(&card->controls_rwsem); - if (snd_ctl_find_id(card, &id)) { - up_write(&card->controls_rwsem); - dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n", - id.iface, - id.device, - id.subdevice, - id.name, - id.index); - err = -EBUSY; - goto error; + while (elem_set = snd_ctl_find_id(card, &id)) { + id.index++; + if (id.index > UINT_MAX - kcontrol->count) { + up_write(&card->controls_rwsem); + dev_err(card->dev, "no more free index for control %i:%i:%i:%s\n", + id.iface, id.device, id.subdevice, id.name); + err = -ENOSPC; + goto error; + } + } + if (kcontrol->id.index != id.index) { + dev_warn(card->dev, "control %i:%i:%i:%s:%i is already present\n", + id.iface, id.device, id.subdevice, id.name, id.index); + dev_warn(card->dev, "control index updated from %i to %i\n", + kcontrol->id.index, id.index); + kcontrol->id.index = id.index; } + if (snd_ctl_find_hole(card, kcontrol->count) < 0) { up_write(&card->controls_rwsem); err = -ENOMEM;