[alsa-devel] [GIT PULL] dummy: allow disabling mixer controls

Takashi Iwai tiwai at suse.de
Sun Oct 21 10:22:07 CEST 2012


At Sun, 21 Oct 2012 15:24:56 +0800,
Raymond Yau wrote:
> 
> 2012-10-21 上午6:11 於 "Clemens Ladisch" <clemens at ladisch.de> 寫道:
> >
> > The following changes since commit
> a0d271cbfed1dd50278c6b06bead3d00ba0a88f9:
> >
> >   Linux 3.6 (2012-09-30 16:47:46 -0700)
> >
> > are available in the git repository at:
> >   git://git.alsa-project.org/alsa-kprivate.git dummy-ctl-inactive
> >
> > ----------------------------------------------------------------
> > Quite a few mixer applications do not handle deactivated controls
> > correctly.  This patch adds such controls to snd-dummy to make
> > crash^H^H^H^H^Htesting these apps easier.
> > ----------------------------------------------------------------
> 
> what is the meaning of deactivated control ?
> 
> amixer still can change the value of the deactivated cd volume control if
> write access is no disabled

If so, that should be checked rather in the core code...


Takashi

> > Clemens Ladisch (1):
> >       ALSA: dummy: allow disabling mixer controls
> >
> >  sound/drivers/dummy.c |   73
> +++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 files changed, 71 insertions(+), 2 deletions(-)
> >
> > diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
> > index 54bb664..4f522cf 100644
> > --- a/sound/drivers/dummy.c
> > +++ b/sound/drivers/dummy.c
> > @@ -134,6 +134,9 @@ struct snd_dummy {
> >         spinlock_t mixer_lock;
> >         int mixer_volume[MIXER_ADDR_LAST+1][2];
> >         int capture_source[MIXER_ADDR_LAST+1][2];
> > +       int iobox;
> > +       struct snd_kcontrol *cd_volume_ctl;
> > +       struct snd_kcontrol *cd_switch_ctl;
> >         const struct dummy_timer_ops *timer_ops;
> >  };
> >
> > @@ -817,6 +820,57 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol
> *kcontrol, struct snd_ctl_el
> >         return change;
> >  }
> >
> > +static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol,
> > +                               struct snd_ctl_elem_info *info)
> > +{
> > +       const char *const names[] = { "None", "CD Player" };
> > +
> > +       return snd_ctl_enum_info(info, 1, 2, names);
> > +}
> > +
> > +static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol,
> > +                              struct snd_ctl_elem_value *value)
> > +{
> > +       struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
> > +
> > +       value->value.enumerated.item[0] = dummy->iobox;
> > +       return 0;
> > +}
> > +
> > +static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
> > +                              struct snd_ctl_elem_value *value)
> > +{
> > +       struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
> > +       int changed;
> > +
> > +       if (value->value.enumerated.item[0] > 1)
> > +               return -EINVAL;
> > +
> > +       changed = value->value.enumerated.item[0] != dummy->iobox;
> > +       if (changed) {
> > +               dummy->iobox = value->value.enumerated.item[0];
> > +
> > +               if (dummy->iobox) {
> > +                       dummy->cd_volume_ctl->vd[0].access &=
> > +                               ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
> > +                       dummy->cd_switch_ctl->vd[0].access &=
> > +                               ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
> > +               } else {
> > +                       dummy->cd_volume_ctl->vd[0].access |=
> > +                               SNDRV_CTL_ELEM_ACCESS_INACTIVE;
> > +                       dummy->cd_switch_ctl->vd[0].access |=
> > +                               SNDRV_CTL_ELEM_ACCESS_INACTIVE;
> > +               }
> > +
> > +               snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
> > +                              &dummy->cd_volume_ctl->id);
> > +               snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
> > +                              &dummy->cd_switch_ctl->id);
> > +       }
> > +
> > +       return changed;
> > +}
> > +
> >  static struct snd_kcontrol_new snd_dummy_controls[] = {
> >  DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
> >  DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
> > @@ -827,22 +881,37 @@ DUMMY_CAPSRC("Line Capture Switch", 0,
> MIXER_ADDR_LINE),
> >  DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
> >  DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
> >  DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
> > -DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
> > +DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD),
> > +{
> > +       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> > +       .name  = "External I/O Box",
> > +       .info  = snd_dummy_iobox_info,
> > +       .get   = snd_dummy_iobox_get,
> > +       .put   = snd_dummy_iobox_put,
> > +},
> >  };
> >
> >  static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
> >  {
> >         struct snd_card *card = dummy->card;
> > +       struct snd_kcontrol *kcontrol;
> >         unsigned int idx;
> >         int err;
> >
> >         spin_lock_init(&dummy->mixer_lock);
> >         strcpy(card->mixername, "Dummy Mixer");
> > +       dummy->iobox = 1;
> >
> >         for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
> > -               err = snd_ctl_add(card,
> snd_ctl_new1(&snd_dummy_controls[idx], dummy));
> > +               kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy);
> > +               err = snd_ctl_add(card, kcontrol);
> >                 if (err < 0)
> >                         return err;
> > +               if (!strcmp(kcontrol->id.name, "CD Volume"))
> > +                       dummy->cd_volume_ctl = kcontrol;
> > +               else if (!strcmp(kcontrol->id.name, "CD Capture Switch"))
> > +                       dummy->cd_switch_ctl = kcontrol;
> > +
> >         }
> >         return 0;
> >  }


More information about the Alsa-devel mailing list