ALSA: asihpi - Add volume mute controls
authorEliot Blennerhassett <eblennerhassett@audioscience.com>
Fri, 22 Jul 2011 03:53:03 +0000 (15:53 +1200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 22 Jul 2011 05:54:20 +0000 (07:54 +0200)
Mute functionality was recently added to the DSP firmware

Signed-off-by: Eliot Blennerhassett <eblennerhassett@audioscience.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/asihpi/asihpi.c

index 3444bd7..f2b35e1 100644 (file)
@@ -1487,11 +1487,48 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
 
 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
 
+static int snd_asihpi_volume_mute_info(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+       uinfo->count = 1;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = 1;
+       return 0;
+}
+
+static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       u32 h_control = kcontrol->private_value;
+       u32 mute;
+
+       hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
+       ucontrol->value.integer.value[0] = mute ? 0 : 1;
+
+       return 0;
+}
+
+static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
+{
+       u32 h_control = kcontrol->private_value;
+       int change = 1;
+       /* HPI currently only supports all or none muting of multichannel volume
+       ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
+       */
+       int mute =  ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
+       hpi_handle_error(hpi_volume_set_mute(h_control, mute));
+       return change;
+}
+
 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
                                        struct hpi_control *hpi_ctl)
 {
        struct snd_card *card = asihpi->card;
        struct snd_kcontrol_new snd_control;
+       int err;
+       u32 mute;
 
        asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1501,7 +1538,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
        snd_control.put = snd_asihpi_volume_put;
        snd_control.tlv.p = db_scale_100;
 
-       return ctl_add(card, &snd_control, asihpi);
+       err = ctl_add(card, &snd_control, asihpi);
+       if (err)
+               return err;
+
+       if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
+               asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
+               snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+               snd_control.info = snd_asihpi_volume_mute_info;
+               snd_control.get = snd_asihpi_volume_mute_get;
+               snd_control.put = snd_asihpi_volume_mute_put;
+               err = ctl_add(card, &snd_control, asihpi);
+       }
+       return err;
 }
 
 /*------------------------------------------------------------