At Fri, 29 Aug 2008 14:16:52 +0100, Liam Girdwood wrote: > > On Fri, 2008-08-29 at 15:01 +0200, Takashi Iwai wrote: > > At Fri, 29 Aug 2008 14:54:42 +0200, > > Harald Radke wrote: > > > > > > Hi there! > > > > > > Please be patient with me, I am quite inexperienced with alsa programming, so > > > this might be a dumb question: > > > > > > We have a WM8750 working in our PDA, the codec is working so far but I want to > > > remove some of the control since they aren't needed. > > > > > > Instead of copying the wm8750.c file and adjusting it, I want to write another > > > module which basically get rid of those controls, something like: > > > > > > [...] > > > > > > static const char* unused_controls[] = {"AAAA", "BBBB,"CCCC"}; > > > > > > struct snd_kcontrol *ctl; > > > > > > list_for_each_entry(ctl, &card->controls, list) > > > > You can't use list_for_each_entry() together with removal. > > Use list_for_each_entry_safe() for such a purpose. > > > > But... > > > > > for(i=0; i < ARRAY_SIZE(unused_controls); i++) > > > if (!strcmp(unused_controls[i],ctl->id.name)) { > > > down_write(&card->controls_rwsem); > > > snd_ctl_remove(card,ctl); > > > up_write(&card->controls_rwsem); > > > break; > > > } > > > > It'd be easier like the following: > > > > for (i = 0; i < ARRAY_SIZE(unused_controls); i++) { > > struct snd_ctl_elem_id id; > > memset(&id, 0, sizeof(id)); > > strcpy(id.name, unused_controls[i]); > > id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; > > snd_ctl_remove_id(card, &id); > > } > > I'd prefer an addition to our API to handle this more _common_ case > rather than just removing controls. > > Something where we can mark controls as "disabled" so alsamixer and > friends wont render/get them. This would also allow scenario code to > disable relevant mixers and then re-enable when required. Something like below? Takashi diff --git a/sound/core/control.c b/sound/core/control.c index 3c5e746..c6f7062 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -410,6 +410,52 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) EXPORT_SYMBOL(snd_ctl_remove_id); /** + * snd_ctl_activate_id - activate/inactivate the control of the given id + * @card: the card instance + * @id: the control id to activate/inactivate + * @active: non-zero to activate + * + * Finds the control instance with the given id, and activate or + * inactivate the control together with notification, if changed. + * + * Returns 0 if unchanged, 1 if changed, or a negative error code on failure. + */ +int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, + int active) +{ + struct snd_kcontrol *kctl; + struct snd_kcontrol_volatile *vd; + unsigned int index_offset; + int ret; + + down_write(&card->controls_rwsem); + kctl = snd_ctl_find_id(card, id); + if (kctl == NULL) { + up_write(&card->controls_rwsem); + return -ENOENT; + } + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; + ret = 0; + if (active) { + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) + goto unlock; + vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + } else { + if (vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) + goto unlock; + vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + } + ret = 1; + unlock: + up_write(&card->controls_rwsem); + if (ret) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id); + return ret; +} +EXPORT_SYMBOL(snd_ctl_activate_id); + +/** * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it * @file: active control handle * @id: the control id to remove _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel