Advertisement
Guest User

Untitled

a guest
Aug 18th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.99 KB | None | 0 0
  1. /*
  2.  *   USB Audio Driver for ALSA
  3.  *
  4.  *   Quirks and vendor-specific extensions for mixer interfaces
  5.  *
  6.  *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
  7.  *
  8.  *   Many codes borrowed from audio.c by
  9.  *      Alan Cox (alan@lxorguk.ukuu.org.uk)
  10.  *      Thomas Sailer (sailer@ife.ee.ethz.ch)
  11.  *
  12.  *
  13.  *   This program is free software; you can redistribute it and/or modify
  14.  *   it under the terms of the GNU General Public License as published by
  15.  *   the Free Software Foundation; either version 2 of the License, or
  16.  *   (at your option) any later version.
  17.  *
  18.  *   This program is distributed in the hope that it will be useful,
  19.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  *   GNU General Public License for more details.
  22.  *
  23.  *   You should have received a copy of the GNU General Public License
  24.  *   along with this program; if not, write to the Free Software
  25.  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  26.  */
  27.  
  28. #include <linux/init.h>
  29. #include <linux/slab.h>
  30. #include <linux/usb.h>
  31. #include <linux/usb/audio.h>
  32.  
  33. #include <sound/core.h>
  34. #include <sound/control.h>
  35. #include <sound/hwdep.h>
  36. #include <sound/info.h>
  37.  
  38. #include "usbaudio.h"
  39. #include "mixer.h"
  40. #include "mixer_quirks.h"
  41. #include "helper.h"
  42.  
  43. /*
  44.  * Sound Blaster remote control configuration
  45.  *
  46.  * format of remote control data:
  47.  * Extigy:       xx 00
  48.  * Audigy 2 NX:  06 80 xx 00 00 00
  49.  * Live! 24-bit: 06 80 xx yy 22 83
  50.  */
  51. static const struct rc_config {
  52.     u32 usb_id;
  53.     u8  offset;
  54.     u8  length;
  55.     u8  packet_length;
  56.     u8  min_packet_length; /* minimum accepted length of the URB result */
  57.     u8  mute_mixer_id;
  58.     u32 mute_code;
  59. } rc_configs[] = {
  60.     { USB_ID(0x041e, 0x3000), 0, 1, 2, 1,  18, 0x0013 }, /* Extigy       */
  61.     { USB_ID(0x041e, 0x3020), 2, 1, 6, 6,  18, 0x0013 }, /* Audigy 2 NX  */
  62.     { USB_ID(0x041e, 0x3040), 2, 2, 6, 6,  2,  0x6e91 }, /* Live! 24-bit */
  63.     { USB_ID(0x041e, 0x3042), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 */
  64.     { USB_ID(0x041e, 0x30df), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 Pro */
  65.     { USB_ID(0x041e, 0x3048), 2, 2, 6, 6,  2,  0x6e91 }, /* Toshiba SB0500 */
  66. };
  67.  
  68. static void snd_usb_soundblaster_remote_complete(struct urb *urb)
  69. {
  70.     struct usb_mixer_interface *mixer = urb->context;
  71.     const struct rc_config *rc = mixer->rc_cfg;
  72.     u32 code;
  73.  
  74.     if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
  75.         return;
  76.  
  77.     code = mixer->rc_buffer[rc->offset];
  78.     if (rc->length == 2)
  79.         code |= mixer->rc_buffer[rc->offset + 1] << 8;
  80.  
  81.     /* the Mute button actually changes the mixer control */
  82.     if (code == rc->mute_code)
  83.         snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
  84.     mixer->rc_code = code;
  85.     wmb();
  86.     wake_up(&mixer->rc_waitq);
  87. }
  88.  
  89. static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
  90.                      long count, loff_t *offset)
  91. {
  92.     struct usb_mixer_interface *mixer = hw->private_data;
  93.     int err;
  94.     u32 rc_code;
  95.  
  96.     if (count != 1 && count != 4)
  97.         return -EINVAL;
  98.     err = wait_event_interruptible(mixer->rc_waitq,
  99.                        (rc_code = xchg(&mixer->rc_code, 0)) != 0);
  100.     if (err == 0) {
  101.         if (count == 1)
  102.             err = put_user(rc_code, buf);
  103.         else
  104.             err = put_user(rc_code, (u32 __user *)buf);
  105.     }
  106.     return err < 0 ? err : count;
  107. }
  108.  
  109. static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
  110.                         poll_table *wait)
  111. {
  112.     struct usb_mixer_interface *mixer = hw->private_data;
  113.  
  114.     poll_wait(file, &mixer->rc_waitq, wait);
  115.     return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
  116. }
  117.  
  118. static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
  119. {
  120.     struct snd_hwdep *hwdep;
  121.     int err, len, i;
  122.  
  123.     for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
  124.         if (rc_configs[i].usb_id == mixer->chip->usb_id)
  125.             break;
  126.     if (i >= ARRAY_SIZE(rc_configs))
  127.         return 0;
  128.     mixer->rc_cfg = &rc_configs[i];
  129.  
  130.     len = mixer->rc_cfg->packet_length;
  131.  
  132.     init_waitqueue_head(&mixer->rc_waitq);
  133.     err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
  134.     if (err < 0)
  135.         return err;
  136.     snprintf(hwdep->name, sizeof(hwdep->name),
  137.          "%s remote control", mixer->chip->card->shortname);
  138.     hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
  139.     hwdep->private_data = mixer;
  140.     hwdep->ops.read = snd_usb_sbrc_hwdep_read;
  141.     hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
  142.     hwdep->exclusive = 1;
  143.  
  144.     mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
  145.     if (!mixer->rc_urb)
  146.         return -ENOMEM;
  147.     mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
  148.     if (!mixer->rc_setup_packet) {
  149.         usb_free_urb(mixer->rc_urb);
  150.         mixer->rc_urb = NULL;
  151.         return -ENOMEM;
  152.     }
  153.     mixer->rc_setup_packet->bRequestType =
  154.         USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
  155.     mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
  156.     mixer->rc_setup_packet->wValue = cpu_to_le16(0);
  157.     mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
  158.     mixer->rc_setup_packet->wLength = cpu_to_le16(len);
  159.     usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
  160.                  usb_rcvctrlpipe(mixer->chip->dev, 0),
  161.                  (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
  162.                  snd_usb_soundblaster_remote_complete, mixer);
  163.     return 0;
  164. }
  165.  
  166. #define snd_audigy2nx_led_info      snd_ctl_boolean_mono_info
  167.  
  168. static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  169. {
  170.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  171.     int index = kcontrol->private_value;
  172.  
  173.     ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
  174.     return 0;
  175. }
  176.  
  177. static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  178. {
  179.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  180.     int index = kcontrol->private_value;
  181.     int value = ucontrol->value.integer.value[0];
  182.     int err, changed;
  183.  
  184.     if (value > 1)
  185.         return -EINVAL;
  186.     changed = value != mixer->audigy2nx_leds[index];
  187.     if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
  188.         err = snd_usb_ctl_msg(mixer->chip->dev,
  189.                   usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
  190.                   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
  191.                   !value, 0, NULL, 0, 100);
  192.     /* USB X-Fi S51 Pro */
  193.     if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
  194.         err = snd_usb_ctl_msg(mixer->chip->dev,
  195.                   usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
  196.                   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
  197.                   !value, 0, NULL, 0, 100);
  198.     else
  199.         err = snd_usb_ctl_msg(mixer->chip->dev,
  200.                   usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
  201.                   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
  202.                   value, index + 2, NULL, 0, 100);
  203.     if (err < 0)
  204.         return err;
  205.     mixer->audigy2nx_leds[index] = value;
  206.     return changed;
  207. }
  208.  
  209. static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
  210.     {
  211.         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  212.         .name = "CMSS LED Switch",
  213.         .info = snd_audigy2nx_led_info,
  214.         .get = snd_audigy2nx_led_get,
  215.         .put = snd_audigy2nx_led_put,
  216.         .private_value = 0,
  217.     },
  218.     {
  219.         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  220.         .name = "Power LED Switch",
  221.         .info = snd_audigy2nx_led_info,
  222.         .get = snd_audigy2nx_led_get,
  223.         .put = snd_audigy2nx_led_put,
  224.         .private_value = 1,
  225.     },
  226.     {
  227.         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  228.         .name = "Dolby Digital LED Switch",
  229.         .info = snd_audigy2nx_led_info,
  230.         .get = snd_audigy2nx_led_get,
  231.         .put = snd_audigy2nx_led_put,
  232.         .private_value = 2,
  233.     },
  234. };
  235.  
  236. static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
  237. {
  238.     int i, err;
  239.  
  240.     for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
  241.         /* USB X-Fi S51 doesn't have a CMSS LED */
  242.         if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
  243.             continue;
  244.         /* USB X-Fi S51 Pro is the same */
  245.         if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
  246.             continue;
  247.         if (i > 1 && /* Live24ext has 2 LEDs only */
  248.             (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
  249.              mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
  250.              mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
  251.              mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
  252.             break;
  253.         err = snd_ctl_add(mixer->chip->card,
  254.                   snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
  255.         if (err < 0)
  256.             return err;
  257.     }
  258.     mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
  259.     return 0;
  260. }
  261.  
  262. static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
  263.                     struct snd_info_buffer *buffer)
  264. {
  265.     static const struct sb_jack {
  266.         int unitid;
  267.         const char *name;
  268.     }  jacks_audigy2nx[] = {
  269.         {4,  "dig in "},
  270.         {7,  "line in"},
  271.         {19, "spk out"},
  272.         {20, "hph out"},
  273.         {-1, NULL}
  274.     }, jacks_live24ext[] = {
  275.         {4,  "line in"}, /* &1=Line, &2=Mic*/
  276.         {3,  "hph out"}, /* headphones */
  277.         {0,  "RC     "}, /* last command, 6 bytes see rc_config above */
  278.         {-1, NULL}
  279.     };
  280.     const struct sb_jack *jacks;
  281.     struct usb_mixer_interface *mixer = entry->private_data;
  282.     int i, err;
  283.     u8 buf[3];
  284.  
  285.     snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
  286.     if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
  287.         jacks = jacks_audigy2nx;
  288.     else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
  289.          mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
  290.         jacks = jacks_live24ext;
  291.     else
  292.         return;
  293.  
  294.     for (i = 0; jacks[i].name; ++i) {
  295.         snd_iprintf(buffer, "%s: ", jacks[i].name);
  296.         err = snd_usb_ctl_msg(mixer->chip->dev,
  297.                       usb_rcvctrlpipe(mixer->chip->dev, 0),
  298.                       UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
  299.                       USB_RECIP_INTERFACE, 0,
  300.                       jacks[i].unitid << 8, buf, 3, 100);
  301.         if (err == 3 && (buf[0] == 3 || buf[0] == 6))
  302.             snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
  303.         else
  304.             snd_iprintf(buffer, "?\n");
  305.     }
  306. }
  307.  
  308. static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
  309.                    struct snd_ctl_elem_value *ucontrol)
  310. {
  311.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  312.  
  313.     ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
  314.     return 0;
  315. }
  316.  
  317. static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
  318.                    struct snd_ctl_elem_value *ucontrol)
  319. {
  320.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  321.     u8 old_status, new_status;
  322.     int err, changed;
  323.  
  324.     old_status = mixer->xonar_u1_status;
  325.     if (ucontrol->value.integer.value[0])
  326.         new_status = old_status | 0x02;
  327.     else
  328.         new_status = old_status & ~0x02;
  329.     changed = new_status != old_status;
  330.     err = snd_usb_ctl_msg(mixer->chip->dev,
  331.                   usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
  332.                   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
  333.                   50, 0, &new_status, 1, 100);
  334.     if (err < 0)
  335.         return err;
  336.     mixer->xonar_u1_status = new_status;
  337.     return changed;
  338. }
  339.  
  340. static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
  341.     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  342.     .name = "Digital Playback Switch",
  343.     .info = snd_ctl_boolean_mono_info,
  344.     .get = snd_xonar_u1_switch_get,
  345.     .put = snd_xonar_u1_switch_put,
  346. };
  347.  
  348. static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
  349. {
  350.     int err;
  351.  
  352.     err = snd_ctl_add(mixer->chip->card,
  353.               snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
  354.     if (err < 0)
  355.         return err;
  356.     mixer->xonar_u1_status = 0x05;
  357.     return 0;
  358. }
  359.  
  360. /* Native Instruments device quirks */
  361.  
  362. #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
  363.  
  364. static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
  365.                          struct snd_ctl_elem_value *ucontrol)
  366. {
  367.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  368.     struct usb_device *dev = mixer->chip->dev;
  369.     u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
  370.     u16 wIndex = kcontrol->private_value & 0xffff;
  371.     u8 tmp;
  372.  
  373.     int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
  374.                   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
  375.                   0, cpu_to_le16(wIndex),
  376.                   &tmp, sizeof(tmp), 1000);
  377.  
  378.     if (ret < 0) {
  379.         snd_printk(KERN_ERR
  380.                "unable to issue vendor read request (ret = %d)", ret);
  381.         return ret;
  382.     }
  383.  
  384.     ucontrol->value.integer.value[0] = tmp;
  385.  
  386.     return 0;
  387. }
  388.  
  389. static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
  390.                          struct snd_ctl_elem_value *ucontrol)
  391. {
  392.     struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
  393.     struct usb_device *dev = mixer->chip->dev;
  394.     u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
  395.     u16 wIndex = kcontrol->private_value & 0xffff;
  396.     u16 wValue = ucontrol->value.integer.value[0];
  397.  
  398.     int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
  399.                   USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
  400.                   cpu_to_le16(wValue), cpu_to_le16(wIndex),
  401.                   NULL, 0, 1000);
  402.  
  403.     if (ret < 0) {
  404.         snd_printk(KERN_ERR
  405.                "unable to issue vendor write request (ret = %d)", ret);
  406.         return ret;
  407.     }
  408.  
  409.     return 0;
  410. }
  411.  
  412. static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
  413.     {
  414.         .name = "Direct Thru Channel A",
  415.         .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
  416.     },
  417.     {
  418.         .name = "Direct Thru Channel B",
  419.         .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
  420.     },
  421.     {
  422.         .name = "Phono Input Channel A",
  423.         .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
  424.     },
  425.     {
  426.         .name = "Phono Input Channel B",
  427.         .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
  428.     },
  429. };
  430.  
  431. static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
  432.     {
  433.         .name = "Direct Thru Channel A",
  434.         .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
  435.     },
  436.     {
  437.         .name = "Direct Thru Channel B",
  438.         .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
  439.     },
  440.     {
  441.         .name = "Direct Thru Channel C",
  442.         .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
  443.     },
  444.     {
  445.         .name = "Direct Thru Channel D",
  446.         .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
  447.     },
  448.     {
  449.         .name = "Phono Input Channel A",
  450.         .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
  451.     },
  452.     {
  453.         .name = "Phono Input Channel B",
  454.         .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
  455.     },
  456.     {
  457.         .name = "Phono Input Channel C",
  458.         .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
  459.     },
  460.     {
  461.         .name = "Phono Input Channel D",
  462.         .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
  463.     },
  464. };
  465.  
  466. static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
  467.                           const struct snd_kcontrol_new *kc,
  468.                           unsigned int count)
  469. {
  470.     int i, err = 0;
  471.     struct snd_kcontrol_new template = {
  472.         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  473.         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
  474.         .get = snd_nativeinstruments_control_get,
  475.         .put = snd_nativeinstruments_control_put,
  476.         .info = snd_ctl_boolean_mono_info,
  477.     };
  478.  
  479.     for (i = 0; i < count; i++) {
  480.         struct snd_kcontrol *c;
  481.  
  482.         template.name = kc[i].name;
  483.         template.private_value = kc[i].private_value;
  484.  
  485.         c = snd_ctl_new1(&template, mixer);
  486.         err = snd_ctl_add(mixer->chip->card, c);
  487.  
  488.         if (err < 0)
  489.             break;
  490.     }
  491.  
  492.     return err;
  493. }
  494.  
  495. void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
  496.                    unsigned char samplerate_id)
  497. {
  498.     struct usb_mixer_interface *mixer;
  499.     struct usb_mixer_elem_info *cval;
  500.     int unitid = 12; /* SamleRate ExtensionUnit ID */
  501.  
  502.     list_for_each_entry(mixer, &chip->mixer_list, list) {
  503.         cval = mixer->id_elems[unitid];
  504.         if (cval) {
  505.             snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
  506.                             cval->control << 8,
  507.                             samplerate_id);
  508.             snd_usb_mixer_notify_id(mixer, unitid);
  509.         }
  510.         break;
  511.     }
  512. }
  513.  
  514. int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
  515. {
  516.     int err = 0;
  517.     struct snd_info_entry *entry;
  518.  
  519.     if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
  520.         return err;
  521.  
  522.     switch (mixer->chip->usb_id) {
  523.     case USB_ID(0x041e, 0x3020):
  524.     case USB_ID(0x041e, 0x3040):
  525.     case USB_ID(0x041e, 0x3042):
  526.     case USB_ID(0x041e, 0x30df):
  527.     case USB_ID(0x041e, 0x3048):
  528.         err = snd_audigy2nx_controls_create(mixer);
  529.         if (err < 0)
  530.             break;
  531.         if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
  532.             snd_info_set_text_ops(entry, mixer,
  533.                           snd_audigy2nx_proc_read);
  534.         break;
  535.  
  536.     case USB_ID(0x0b05, 0x1739):
  537.     case USB_ID(0x0b05, 0x1743):
  538.         err = snd_xonar_u1_controls_create(mixer);
  539.         break;
  540.  
  541.     case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
  542.         err = snd_nativeinstruments_create_mixer(mixer,
  543.                 snd_nativeinstruments_ta6_mixers,
  544.                 ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
  545.         break;
  546.  
  547.     case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
  548.         err = snd_nativeinstruments_create_mixer(mixer,
  549.                 snd_nativeinstruments_ta10_mixers,
  550.                 ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
  551.         break;
  552.     }
  553.  
  554.     return err;
  555. }
  556.  
  557. void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
  558.                     int unitid)
  559. {
  560.     if (!mixer->rc_cfg)
  561.         return;
  562.     /* unit ids specific to Extigy/Audigy 2 NX: */
  563.     switch (unitid) {
  564.     case 0: /* remote control */
  565.         mixer->rc_urb->dev = mixer->chip->dev;
  566.         usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
  567.         break;
  568.     case 4: /* digital in jack */
  569.     case 7: /* line in jacks */
  570.     case 19: /* speaker out jacks */
  571.     case 20: /* headphones out jack */
  572.         break;
  573.     /* live24ext: 4 = line-in jack */
  574.     case 3: /* hp-out jack (may actuate Mute) */
  575.         if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
  576.             mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
  577.             snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
  578.         break;
  579.     default:
  580.         snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
  581.         break;
  582.     }
  583. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement