From 468b8fde24d49f5b34e9152981824b9d4ecd1a2e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 13 Jul 2009 11:39:29 +0200 Subject: sound: usb-audio: Xonar U1 digital output support Add support for the Asus Xonar U1. This device is mostly class compliant, but the digital output requires a vendor-specific request. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/usbmixer.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'sound') diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 4bd3a7a0edc1..84526971e675 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -86,6 +86,7 @@ struct usb_mixer_interface { u8 rc_buffer[6]; u8 audigy2nx_leds[3]; + u8 xonar_u1_status; }; @@ -2018,6 +2019,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) { @@ -2060,6 +2113,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; -- cgit v1.2.2