Merge branch 'topic/usb-audio' into for-linus
[pandora-kernel.git] / sound / usb / usbmixer.c
index df89691..ab5a3ac 100644 (file)
@@ -86,6 +86,7 @@ struct usb_mixer_interface {
        u8 rc_buffer[6];
 
        u8 audigy2nx_leds[3];
+       u8 xonar_u1_status;
 };
 
 
@@ -2042,6 +2043,58 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
        }
 }
 
+static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
+
+       ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
+       return 0;
+}
+
+static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
+                                  struct snd_ctl_elem_value *ucontrol)
+{
+       struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
+       u8 old_status, new_status;
+       int err, changed;
+
+       old_status = mixer->xonar_u1_status;
+       if (ucontrol->value.integer.value[0])
+               new_status = old_status | 0x02;
+       else
+               new_status = old_status & ~0x02;
+       changed = new_status != old_status;
+       err = snd_usb_ctl_msg(mixer->chip->dev,
+                             usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
+                             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+                             50, 0, &new_status, 1, 100);
+       if (err < 0)
+               return err;
+       mixer->xonar_u1_status = new_status;
+       return changed;
+}
+
+static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
+       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+       .name = "Digital Playback Switch",
+       .info = snd_ctl_boolean_mono_info,
+       .get = snd_xonar_u1_switch_get,
+       .put = snd_xonar_u1_switch_put,
+};
+
+static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
+{
+       int err;
+
+       err = snd_ctl_add(mixer->chip->card,
+                         snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
+       if (err < 0)
+               return err;
+       mixer->xonar_u1_status = 0x05;
+       return 0;
+}
+
 int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
                         int ignore_error)
 {
@@ -2084,6 +2137,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
                                              snd_audigy2nx_proc_read);
        }
 
+       if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
+           mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
+               err = snd_xonar_u1_controls_create(mixer);
+               if (err < 0)
+                       goto _error;
+       }
+
        err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
        if (err < 0)
                goto _error;