linux/sound/usb/mixer_quirks.c
<<
>>
Prefs
   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
  43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
  44
  45struct std_mono_table {
  46        unsigned int unitid, control, cmask;
  47        int val_type;
  48        const char *name;
  49        snd_kcontrol_tlv_rw_t *tlv_callback;
  50};
  51
  52/* private_free callback */
  53static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
  54{
  55        kfree(kctl->private_data);
  56        kctl->private_data = NULL;
  57}
  58
  59/* This function allows for the creation of standard UAC controls.
  60 * See the quirks for M-Audio FTUs or Ebox-44.
  61 * If you don't want to set a TLV callback pass NULL.
  62 *
  63 * Since there doesn't seem to be a devices that needs a multichannel
  64 * version, we keep it mono for simplicity.
  65 */
  66static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
  67                                unsigned int unitid,
  68                                unsigned int control,
  69                                unsigned int cmask,
  70                                int val_type,
  71                                const char *name,
  72                                snd_kcontrol_tlv_rw_t *tlv_callback)
  73{
  74        int err;
  75        struct usb_mixer_elem_info *cval;
  76        struct snd_kcontrol *kctl;
  77
  78        cval = kzalloc(sizeof(*cval), GFP_KERNEL);
  79        if (!cval)
  80                return -ENOMEM;
  81
  82        cval->id = unitid;
  83        cval->mixer = mixer;
  84        cval->val_type = val_type;
  85        cval->channels = 1;
  86        cval->control = control;
  87        cval->cmask = cmask;
  88
  89        /* get_min_max() is called only for integer volumes later,
  90         * so provide a short-cut for booleans */
  91        cval->min = 0;
  92        cval->max = 1;
  93        cval->res = 0;
  94        cval->dBmin = 0;
  95        cval->dBmax = 0;
  96
  97        /* Create control */
  98        kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
  99        if (!kctl) {
 100                kfree(cval);
 101                return -ENOMEM;
 102        }
 103
 104        /* Set name */
 105        snprintf(kctl->id.name, sizeof(kctl->id.name), name);
 106        kctl->private_free = usb_mixer_elem_free;
 107
 108        /* set TLV */
 109        if (tlv_callback) {
 110                kctl->tlv.c = tlv_callback;
 111                kctl->vd[0].access |=
 112                        SNDRV_CTL_ELEM_ACCESS_TLV_READ |
 113                        SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
 114        }
 115        /* Add control to mixer */
 116        err = snd_usb_mixer_add_control(mixer, kctl);
 117        if (err < 0)
 118                return err;
 119
 120        return 0;
 121}
 122
 123/*
 124 * Create a set of standard UAC controls from a table
 125 */
 126static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
 127                                struct std_mono_table *t)
 128{
 129        int err;
 130
 131        while (t->name != NULL) {
 132                err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
 133                                t->cmask, t->val_type, t->name, t->tlv_callback);
 134                if (err < 0)
 135                        return err;
 136                t++;
 137        }
 138
 139        return 0;
 140}
 141
 142/*
 143 * Sound Blaster remote control configuration
 144 *
 145 * format of remote control data:
 146 * Extigy:       xx 00
 147 * Audigy 2 NX:  06 80 xx 00 00 00
 148 * Live! 24-bit: 06 80 xx yy 22 83
 149 */
 150static const struct rc_config {
 151        u32 usb_id;
 152        u8  offset;
 153        u8  length;
 154        u8  packet_length;
 155        u8  min_packet_length; /* minimum accepted length of the URB result */
 156        u8  mute_mixer_id;
 157        u32 mute_code;
 158} rc_configs[] = {
 159        { USB_ID(0x041e, 0x3000), 0, 1, 2, 1,  18, 0x0013 }, /* Extigy       */
 160        { USB_ID(0x041e, 0x3020), 2, 1, 6, 6,  18, 0x0013 }, /* Audigy 2 NX  */
 161        { USB_ID(0x041e, 0x3040), 2, 2, 6, 6,  2,  0x6e91 }, /* Live! 24-bit */
 162        { USB_ID(0x041e, 0x3042), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 */
 163        { USB_ID(0x041e, 0x30df), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 Pro */
 164        { USB_ID(0x041e, 0x3048), 2, 2, 6, 6,  2,  0x6e91 }, /* Toshiba SB0500 */
 165};
 166
 167static void snd_usb_soundblaster_remote_complete(struct urb *urb)
 168{
 169        struct usb_mixer_interface *mixer = urb->context;
 170        const struct rc_config *rc = mixer->rc_cfg;
 171        u32 code;
 172
 173        if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
 174                return;
 175
 176        code = mixer->rc_buffer[rc->offset];
 177        if (rc->length == 2)
 178                code |= mixer->rc_buffer[rc->offset + 1] << 8;
 179
 180        /* the Mute button actually changes the mixer control */
 181        if (code == rc->mute_code)
 182                snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
 183        mixer->rc_code = code;
 184        wmb();
 185        wake_up(&mixer->rc_waitq);
 186}
 187
 188static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
 189                                     long count, loff_t *offset)
 190{
 191        struct usb_mixer_interface *mixer = hw->private_data;
 192        int err;
 193        u32 rc_code;
 194
 195        if (count != 1 && count != 4)
 196                return -EINVAL;
 197        err = wait_event_interruptible(mixer->rc_waitq,
 198                                       (rc_code = xchg(&mixer->rc_code, 0)) != 0);
 199        if (err == 0) {
 200                if (count == 1)
 201                        err = put_user(rc_code, buf);
 202                else
 203                        err = put_user(rc_code, (u32 __user *)buf);
 204        }
 205        return err < 0 ? err : count;
 206}
 207
 208static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
 209                                            poll_table *wait)
 210{
 211        struct usb_mixer_interface *mixer = hw->private_data;
 212
 213        poll_wait(file, &mixer->rc_waitq, wait);
 214        return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
 215}
 216
 217static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
 218{
 219        struct snd_hwdep *hwdep;
 220        int err, len, i;
 221
 222        for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
 223                if (rc_configs[i].usb_id == mixer->chip->usb_id)
 224                        break;
 225        if (i >= ARRAY_SIZE(rc_configs))
 226                return 0;
 227        mixer->rc_cfg = &rc_configs[i];
 228
 229        len = mixer->rc_cfg->packet_length;
 230
 231        init_waitqueue_head(&mixer->rc_waitq);
 232        err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
 233        if (err < 0)
 234                return err;
 235        snprintf(hwdep->name, sizeof(hwdep->name),
 236                 "%s remote control", mixer->chip->card->shortname);
 237        hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
 238        hwdep->private_data = mixer;
 239        hwdep->ops.read = snd_usb_sbrc_hwdep_read;
 240        hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
 241        hwdep->exclusive = 1;
 242
 243        mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
 244        if (!mixer->rc_urb)
 245                return -ENOMEM;
 246        mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
 247        if (!mixer->rc_setup_packet) {
 248                usb_free_urb(mixer->rc_urb);
 249                mixer->rc_urb = NULL;
 250                return -ENOMEM;
 251        }
 252        mixer->rc_setup_packet->bRequestType =
 253                USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
 254        mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
 255        mixer->rc_setup_packet->wValue = cpu_to_le16(0);
 256        mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
 257        mixer->rc_setup_packet->wLength = cpu_to_le16(len);
 258        usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
 259                             usb_rcvctrlpipe(mixer->chip->dev, 0),
 260                             (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
 261                             snd_usb_soundblaster_remote_complete, mixer);
 262        return 0;
 263}
 264
 265#define snd_audigy2nx_led_info          snd_ctl_boolean_mono_info
 266
 267static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 268{
 269        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 270        int index = kcontrol->private_value;
 271
 272        ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
 273        return 0;
 274}
 275
 276static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 277{
 278        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 279        int index = kcontrol->private_value;
 280        int value = ucontrol->value.integer.value[0];
 281        int err, changed;
 282
 283        if (value > 1)
 284                return -EINVAL;
 285        changed = value != mixer->audigy2nx_leds[index];
 286        down_read(&mixer->chip->shutdown_rwsem);
 287        if (mixer->chip->shutdown) {
 288                err = -ENODEV;
 289                goto out;
 290        }
 291        if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
 292                err = snd_usb_ctl_msg(mixer->chip->dev,
 293                              usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
 294                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 295                              !value, 0, NULL, 0);
 296        /* USB X-Fi S51 Pro */
 297        if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
 298                err = snd_usb_ctl_msg(mixer->chip->dev,
 299                              usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
 300                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 301                              !value, 0, NULL, 0);
 302        else
 303                err = snd_usb_ctl_msg(mixer->chip->dev,
 304                              usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
 305                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 306                              value, index + 2, NULL, 0);
 307 out:
 308        up_read(&mixer->chip->shutdown_rwsem);
 309        if (err < 0)
 310                return err;
 311        mixer->audigy2nx_leds[index] = value;
 312        return changed;
 313}
 314
 315static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
 316        {
 317                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 318                .name = "CMSS LED Switch",
 319                .info = snd_audigy2nx_led_info,
 320                .get = snd_audigy2nx_led_get,
 321                .put = snd_audigy2nx_led_put,
 322                .private_value = 0,
 323        },
 324        {
 325                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 326                .name = "Power LED Switch",
 327                .info = snd_audigy2nx_led_info,
 328                .get = snd_audigy2nx_led_get,
 329                .put = snd_audigy2nx_led_put,
 330                .private_value = 1,
 331        },
 332        {
 333                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 334                .name = "Dolby Digital LED Switch",
 335                .info = snd_audigy2nx_led_info,
 336                .get = snd_audigy2nx_led_get,
 337                .put = snd_audigy2nx_led_put,
 338                .private_value = 2,
 339        },
 340};
 341
 342static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
 343{
 344        int i, err;
 345
 346        for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
 347                /* USB X-Fi S51 doesn't have a CMSS LED */
 348                if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
 349                        continue;
 350                /* USB X-Fi S51 Pro doesn't have one either */
 351                if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
 352                        continue;
 353                if (i > 1 && /* Live24ext has 2 LEDs only */
 354                        (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
 355                         mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
 356                         mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
 357                         mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
 358                        break; 
 359                err = snd_ctl_add(mixer->chip->card,
 360                                  snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
 361                if (err < 0)
 362                        return err;
 363        }
 364        mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
 365        return 0;
 366}
 367
 368static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
 369                                    struct snd_info_buffer *buffer)
 370{
 371        static const struct sb_jack {
 372                int unitid;
 373                const char *name;
 374        }  jacks_audigy2nx[] = {
 375                {4,  "dig in "},
 376                {7,  "line in"},
 377                {19, "spk out"},
 378                {20, "hph out"},
 379                {-1, NULL}
 380        }, jacks_live24ext[] = {
 381                {4,  "line in"}, /* &1=Line, &2=Mic*/
 382                {3,  "hph out"}, /* headphones */
 383                {0,  "RC     "}, /* last command, 6 bytes see rc_config above */
 384                {-1, NULL}
 385        };
 386        const struct sb_jack *jacks;
 387        struct usb_mixer_interface *mixer = entry->private_data;
 388        int i, err;
 389        u8 buf[3];
 390
 391        snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
 392        if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
 393                jacks = jacks_audigy2nx;
 394        else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
 395                 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
 396                jacks = jacks_live24ext;
 397        else
 398                return;
 399
 400        for (i = 0; jacks[i].name; ++i) {
 401                snd_iprintf(buffer, "%s: ", jacks[i].name);
 402                down_read(&mixer->chip->shutdown_rwsem);
 403                if (mixer->chip->shutdown)
 404                        err = 0;
 405                else
 406                        err = snd_usb_ctl_msg(mixer->chip->dev,
 407                                      usb_rcvctrlpipe(mixer->chip->dev, 0),
 408                                      UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
 409                                      USB_RECIP_INTERFACE, 0,
 410                                      jacks[i].unitid << 8, buf, 3);
 411                up_read(&mixer->chip->shutdown_rwsem);
 412                if (err == 3 && (buf[0] == 3 || buf[0] == 6))
 413                        snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
 414                else
 415                        snd_iprintf(buffer, "?\n");
 416        }
 417}
 418
 419static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
 420                                   struct snd_ctl_elem_value *ucontrol)
 421{
 422        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 423
 424        ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
 425        return 0;
 426}
 427
 428static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
 429                                   struct snd_ctl_elem_value *ucontrol)
 430{
 431        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 432        u8 old_status, new_status;
 433        int err, changed;
 434
 435        old_status = mixer->xonar_u1_status;
 436        if (ucontrol->value.integer.value[0])
 437                new_status = old_status | 0x02;
 438        else
 439                new_status = old_status & ~0x02;
 440        changed = new_status != old_status;
 441        down_read(&mixer->chip->shutdown_rwsem);
 442        if (mixer->chip->shutdown)
 443                err = -ENODEV;
 444        else
 445                err = snd_usb_ctl_msg(mixer->chip->dev,
 446                              usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
 447                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
 448                              50, 0, &new_status, 1);
 449        up_read(&mixer->chip->shutdown_rwsem);
 450        if (err < 0)
 451                return err;
 452        mixer->xonar_u1_status = new_status;
 453        return changed;
 454}
 455
 456static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
 457        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 458        .name = "Digital Playback Switch",
 459        .info = snd_ctl_boolean_mono_info,
 460        .get = snd_xonar_u1_switch_get,
 461        .put = snd_xonar_u1_switch_put,
 462};
 463
 464static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
 465{
 466        int err;
 467
 468        err = snd_ctl_add(mixer->chip->card,
 469                          snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
 470        if (err < 0)
 471                return err;
 472        mixer->xonar_u1_status = 0x05;
 473        return 0;
 474}
 475
 476/* Native Instruments device quirks */
 477
 478#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
 479
 480static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
 481                                             struct snd_ctl_elem_value *ucontrol)
 482{
 483        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 484        struct usb_device *dev = mixer->chip->dev;
 485        u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
 486        u16 wIndex = kcontrol->private_value & 0xffff;
 487        u8 tmp;
 488        int ret;
 489
 490        down_read(&mixer->chip->shutdown_rwsem);
 491        if (mixer->chip->shutdown)
 492                ret = -ENODEV;
 493        else
 494                ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
 495                                  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
 496                                  0, cpu_to_le16(wIndex),
 497                                  &tmp, sizeof(tmp), 1000);
 498        up_read(&mixer->chip->shutdown_rwsem);
 499
 500        if (ret < 0) {
 501                snd_printk(KERN_ERR
 502                           "unable to issue vendor read request (ret = %d)", ret);
 503                return ret;
 504        }
 505
 506        ucontrol->value.integer.value[0] = tmp;
 507
 508        return 0;
 509}
 510
 511static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
 512                                             struct snd_ctl_elem_value *ucontrol)
 513{
 514        struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 515        struct usb_device *dev = mixer->chip->dev;
 516        u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
 517        u16 wIndex = kcontrol->private_value & 0xffff;
 518        u16 wValue = ucontrol->value.integer.value[0];
 519        int ret;
 520
 521        down_read(&mixer->chip->shutdown_rwsem);
 522        if (mixer->chip->shutdown)
 523                ret = -ENODEV;
 524        else
 525                ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
 526                                  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
 527                                  cpu_to_le16(wValue), cpu_to_le16(wIndex),
 528                                  NULL, 0, 1000);
 529        up_read(&mixer->chip->shutdown_rwsem);
 530
 531        if (ret < 0) {
 532                snd_printk(KERN_ERR
 533                           "unable to issue vendor write request (ret = %d)", ret);
 534                return ret;
 535        }
 536
 537        return 0;
 538}
 539
 540static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
 541        {
 542                .name = "Direct Thru Channel A",
 543                .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
 544        },
 545        {
 546                .name = "Direct Thru Channel B",
 547                .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
 548        },
 549        {
 550                .name = "Phono Input Channel A",
 551                .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
 552        },
 553        {
 554                .name = "Phono Input Channel B",
 555                .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
 556        },
 557};
 558
 559static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
 560        {
 561                .name = "Direct Thru Channel A",
 562                .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
 563        },
 564        {
 565                .name = "Direct Thru Channel B",
 566                .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
 567        },
 568        {
 569                .name = "Direct Thru Channel C",
 570                .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
 571        },
 572        {
 573                .name = "Direct Thru Channel D",
 574                .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
 575        },
 576        {
 577                .name = "Phono Input Channel A",
 578                .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
 579        },
 580        {
 581                .name = "Phono Input Channel B",
 582                .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
 583        },
 584        {
 585                .name = "Phono Input Channel C",
 586                .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
 587        },
 588        {
 589                .name = "Phono Input Channel D",
 590                .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
 591        },
 592};
 593
 594static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
 595                                              const struct snd_kcontrol_new *kc,
 596                                              unsigned int count)
 597{
 598        int i, err = 0;
 599        struct snd_kcontrol_new template = {
 600                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 601                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 602                .get = snd_nativeinstruments_control_get,
 603                .put = snd_nativeinstruments_control_put,
 604                .info = snd_ctl_boolean_mono_info,
 605        };
 606
 607        for (i = 0; i < count; i++) {
 608                struct snd_kcontrol *c;
 609
 610                template.name = kc[i].name;
 611                template.private_value = kc[i].private_value;
 612
 613                c = snd_ctl_new1(&template, mixer);
 614                err = snd_ctl_add(mixer->chip->card, c);
 615
 616                if (err < 0)
 617                        break;
 618        }
 619
 620        return err;
 621}
 622
 623/* M-Audio FastTrack Ultra quirks */
 624/* FTU Effect switch */
 625struct snd_ftu_eff_switch_priv_val {
 626        struct usb_mixer_interface *mixer;
 627        int cached_value;
 628        int is_cached;
 629};
 630
 631static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
 632                                        struct snd_ctl_elem_info *uinfo)
 633{
 634        static const char *texts[8] = {"Room 1",
 635                                       "Room 2",
 636                                       "Room 3",
 637                                       "Hall 1",
 638                                       "Hall 2",
 639                                       "Plate",
 640                                       "Delay",
 641                                       "Echo"
 642        };
 643
 644        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 645        uinfo->count = 1;
 646        uinfo->value.enumerated.items = 8;
 647        if (uinfo->value.enumerated.item > 7)
 648                uinfo->value.enumerated.item = 7;
 649        strcpy(uinfo->value.enumerated.name,
 650                texts[uinfo->value.enumerated.item]);
 651
 652        return 0;
 653}
 654
 655static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
 656                                        struct snd_ctl_elem_value *ucontrol)
 657{
 658        struct snd_usb_audio *chip;
 659        struct usb_mixer_interface *mixer;
 660        struct snd_ftu_eff_switch_priv_val *pval;
 661        int err;
 662        unsigned char value[2];
 663
 664        const int id = 6;
 665        const int validx = 1;
 666        const int val_len = 2;
 667
 668        value[0] = 0x00;
 669        value[1] = 0x00;
 670
 671        pval = (struct snd_ftu_eff_switch_priv_val *)
 672                kctl->private_value;
 673
 674        if (pval->is_cached) {
 675                ucontrol->value.enumerated.item[0] = pval->cached_value;
 676                return 0;
 677        }
 678
 679        mixer = (struct usb_mixer_interface *) pval->mixer;
 680        if (snd_BUG_ON(!mixer))
 681                return -EINVAL;
 682
 683        chip = (struct snd_usb_audio *) mixer->chip;
 684        if (snd_BUG_ON(!chip))
 685                return -EINVAL;
 686
 687
 688        down_read(&mixer->chip->shutdown_rwsem);
 689        if (mixer->chip->shutdown)
 690                err = -ENODEV;
 691        else
 692                err = snd_usb_ctl_msg(chip->dev,
 693                        usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
 694                        USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 695                        validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 696                        value, val_len);
 697        up_read(&mixer->chip->shutdown_rwsem);
 698        if (err < 0)
 699                return err;
 700
 701        ucontrol->value.enumerated.item[0] = value[0];
 702        pval->cached_value = value[0];
 703        pval->is_cached = 1;
 704
 705        return 0;
 706}
 707
 708static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
 709                                        struct snd_ctl_elem_value *ucontrol)
 710{
 711        struct snd_usb_audio *chip;
 712        struct snd_ftu_eff_switch_priv_val *pval;
 713
 714        struct usb_mixer_interface *mixer;
 715        int changed, cur_val, err, new_val;
 716        unsigned char value[2];
 717
 718
 719        const int id = 6;
 720        const int validx = 1;
 721        const int val_len = 2;
 722
 723        changed = 0;
 724
 725        pval = (struct snd_ftu_eff_switch_priv_val *)
 726                kctl->private_value;
 727        cur_val = pval->cached_value;
 728        new_val = ucontrol->value.enumerated.item[0];
 729
 730        mixer = (struct usb_mixer_interface *) pval->mixer;
 731        if (snd_BUG_ON(!mixer))
 732                return -EINVAL;
 733
 734        chip = (struct snd_usb_audio *) mixer->chip;
 735        if (snd_BUG_ON(!chip))
 736                return -EINVAL;
 737
 738        if (!pval->is_cached) {
 739                /* Read current value */
 740                down_read(&mixer->chip->shutdown_rwsem);
 741                if (mixer->chip->shutdown)
 742                        err = -ENODEV;
 743                else
 744                        err = snd_usb_ctl_msg(chip->dev,
 745                                usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
 746                                USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 747                                validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 748                                value, val_len);
 749                up_read(&mixer->chip->shutdown_rwsem);
 750                if (err < 0)
 751                        return err;
 752
 753                cur_val = value[0];
 754                pval->cached_value = cur_val;
 755                pval->is_cached = 1;
 756        }
 757        /* update value if needed */
 758        if (cur_val != new_val) {
 759                value[0] = new_val;
 760                value[1] = 0;
 761                down_read(&mixer->chip->shutdown_rwsem);
 762                if (mixer->chip->shutdown)
 763                        err = -ENODEV;
 764                else
 765                        err = snd_usb_ctl_msg(chip->dev,
 766                                usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
 767                                USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
 768                                validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
 769                                value, val_len);
 770                up_read(&mixer->chip->shutdown_rwsem);
 771                if (err < 0)
 772                        return err;
 773
 774                pval->cached_value = new_val;
 775                pval->is_cached = 1;
 776                changed = 1;
 777        }
 778
 779        return changed;
 780}
 781
 782static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer)
 783{
 784        static struct snd_kcontrol_new template = {
 785                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 786                .name = "Effect Program Switch",
 787                .index = 0,
 788                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 789                .info = snd_ftu_eff_switch_info,
 790                .get = snd_ftu_eff_switch_get,
 791                .put = snd_ftu_eff_switch_put
 792        };
 793
 794        int err;
 795        struct snd_kcontrol *kctl;
 796        struct snd_ftu_eff_switch_priv_val *pval;
 797
 798        pval = kzalloc(sizeof(*pval), GFP_KERNEL);
 799        if (!pval)
 800                return -ENOMEM;
 801
 802        pval->cached_value = 0;
 803        pval->is_cached = 0;
 804        pval->mixer = mixer;
 805
 806        template.private_value = (unsigned long) pval;
 807        kctl = snd_ctl_new1(&template, mixer->chip);
 808        if (!kctl) {
 809                kfree(pval);
 810                return -ENOMEM;
 811        }
 812
 813        err = snd_ctl_add(mixer->chip->card, kctl);
 814        if (err < 0)
 815                return err;
 816
 817        return 0;
 818}
 819
 820/* Create volume controls for FTU devices*/
 821static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
 822{
 823        char name[64];
 824        unsigned int control, cmask;
 825        int in, out, err;
 826
 827        const unsigned int id = 5;
 828        const int val_type = USB_MIXER_S16;
 829
 830        for (out = 0; out < 8; out++) {
 831                control = out + 1;
 832                for (in = 0; in < 8; in++) {
 833                        cmask = 1 << in;
 834                        snprintf(name, sizeof(name),
 835                                "AIn%d - Out%d Capture Volume",
 836                                in  + 1, out + 1);
 837                        err = snd_create_std_mono_ctl(mixer, id, control,
 838                                                        cmask, val_type, name,
 839                                                        &snd_usb_mixer_vol_tlv);
 840                        if (err < 0)
 841                                return err;
 842                }
 843                for (in = 8; in < 16; in++) {
 844                        cmask = 1 << in;
 845                        snprintf(name, sizeof(name),
 846                                "DIn%d - Out%d Playback Volume",
 847                                in - 7, out + 1);
 848                        err = snd_create_std_mono_ctl(mixer, id, control,
 849                                                        cmask, val_type, name,
 850                                                        &snd_usb_mixer_vol_tlv);
 851                        if (err < 0)
 852                                return err;
 853                }
 854        }
 855
 856        return 0;
 857}
 858
 859/* This control needs a volume quirk, see mixer.c */
 860static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
 861{
 862        static const char name[] = "Effect Volume";
 863        const unsigned int id = 6;
 864        const int val_type = USB_MIXER_U8;
 865        const unsigned int control = 2;
 866        const unsigned int cmask = 0;
 867
 868        return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
 869                                        name, snd_usb_mixer_vol_tlv);
 870}
 871
 872/* This control needs a volume quirk, see mixer.c */
 873static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
 874{
 875        static const char name[] = "Effect Duration";
 876        const unsigned int id = 6;
 877        const int val_type = USB_MIXER_S16;
 878        const unsigned int control = 3;
 879        const unsigned int cmask = 0;
 880
 881        return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
 882                                        name, snd_usb_mixer_vol_tlv);
 883}
 884
 885/* This control needs a volume quirk, see mixer.c */
 886static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
 887{
 888        static const char name[] = "Effect Feedback Volume";
 889        const unsigned int id = 6;
 890        const int val_type = USB_MIXER_U8;
 891        const unsigned int control = 4;
 892        const unsigned int cmask = 0;
 893
 894        return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
 895                                        name, NULL);
 896}
 897
 898static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer)
 899{
 900        unsigned int cmask;
 901        int err, ch;
 902        char name[48];
 903
 904        const unsigned int id = 7;
 905        const int val_type = USB_MIXER_S16;
 906        const unsigned int control = 7;
 907
 908        for (ch = 0; ch < 4; ++ch) {
 909                cmask = 1 << ch;
 910                snprintf(name, sizeof(name),
 911                        "Effect Return %d Volume", ch + 1);
 912                err = snd_create_std_mono_ctl(mixer, id, control,
 913                                                cmask, val_type, name,
 914                                                snd_usb_mixer_vol_tlv);
 915                if (err < 0)
 916                        return err;
 917        }
 918
 919        return 0;
 920}
 921
 922static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer)
 923{
 924        unsigned int  cmask;
 925        int err, ch;
 926        char name[48];
 927
 928        const unsigned int id = 5;
 929        const int val_type = USB_MIXER_S16;
 930        const unsigned int control = 9;
 931
 932        for (ch = 0; ch < 8; ++ch) {
 933                cmask = 1 << ch;
 934                snprintf(name, sizeof(name),
 935                        "Effect Send AIn%d Volume", ch + 1);
 936                err = snd_create_std_mono_ctl(mixer, id, control, cmask,
 937                                                val_type, name,
 938                                                snd_usb_mixer_vol_tlv);
 939                if (err < 0)
 940                        return err;
 941        }
 942        for (ch = 8; ch < 16; ++ch) {
 943                cmask = 1 << ch;
 944                snprintf(name, sizeof(name),
 945                        "Effect Send DIn%d Volume", ch - 7);
 946                err = snd_create_std_mono_ctl(mixer, id, control, cmask,
 947                                                val_type, name,
 948                                                snd_usb_mixer_vol_tlv);
 949                if (err < 0)
 950                        return err;
 951        }
 952        return 0;
 953}
 954
 955static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
 956{
 957        int err;
 958
 959        err = snd_ftu_create_volume_ctls(mixer);
 960        if (err < 0)
 961                return err;
 962
 963        err = snd_ftu_create_effect_switch(mixer);
 964        if (err < 0)
 965                return err;
 966        err = snd_ftu_create_effect_volume_ctl(mixer);
 967        if (err < 0)
 968                return err;
 969
 970        err = snd_ftu_create_effect_duration_ctl(mixer);
 971        if (err < 0)
 972                return err;
 973
 974        err = snd_ftu_create_effect_feedback_ctl(mixer);
 975        if (err < 0)
 976                return err;
 977
 978        err = snd_ftu_create_effect_return_ctls(mixer);
 979        if (err < 0)
 980                return err;
 981
 982        err = snd_ftu_create_effect_send_ctls(mixer);
 983        if (err < 0)
 984                return err;
 985
 986        return 0;
 987}
 988
 989void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
 990                               unsigned char samplerate_id)
 991{
 992        struct usb_mixer_interface *mixer;
 993        struct usb_mixer_elem_info *cval;
 994        int unitid = 12; /* SamleRate ExtensionUnit ID */
 995
 996        list_for_each_entry(mixer, &chip->mixer_list, list) {
 997                cval = mixer->id_elems[unitid];
 998                if (cval) {
 999                        snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
1000                                                    cval->control << 8,
1001                                                    samplerate_id);
1002                        snd_usb_mixer_notify_id(mixer, unitid);
1003                }
1004                break;
1005        }
1006}
1007
1008/*
1009 * The mixer units for Ebox-44 are corrupt, and even where they
1010 * are valid they presents mono controls as L and R channels of
1011 * stereo. So we provide a good mixer here.
1012 */
1013struct std_mono_table ebox44_table[] = {
1014        {
1015                .unitid = 4,
1016                .control = 1,
1017                .cmask = 0x0,
1018                .val_type = USB_MIXER_INV_BOOLEAN,
1019                .name = "Headphone Playback Switch"
1020        },
1021        {
1022                .unitid = 4,
1023                .control = 2,
1024                .cmask = 0x1,
1025                .val_type = USB_MIXER_S16,
1026                .name = "Headphone A Mix Playback Volume"
1027        },
1028        {
1029                .unitid = 4,
1030                .control = 2,
1031                .cmask = 0x2,
1032                .val_type = USB_MIXER_S16,
1033                .name = "Headphone B Mix Playback Volume"
1034        },
1035
1036        {
1037                .unitid = 7,
1038                .control = 1,
1039                .cmask = 0x0,
1040                .val_type = USB_MIXER_INV_BOOLEAN,
1041                .name = "Output Playback Switch"
1042        },
1043        {
1044                .unitid = 7,
1045                .control = 2,
1046                .cmask = 0x1,
1047                .val_type = USB_MIXER_S16,
1048                .name = "Output A Playback Volume"
1049        },
1050        {
1051                .unitid = 7,
1052                .control = 2,
1053                .cmask = 0x2,
1054                .val_type = USB_MIXER_S16,
1055                .name = "Output B Playback Volume"
1056        },
1057
1058        {
1059                .unitid = 10,
1060                .control = 1,
1061                .cmask = 0x0,
1062                .val_type = USB_MIXER_INV_BOOLEAN,
1063                .name = "Input Capture Switch"
1064        },
1065        {
1066                .unitid = 10,
1067                .control = 2,
1068                .cmask = 0x1,
1069                .val_type = USB_MIXER_S16,
1070                .name = "Input A Capture Volume"
1071        },
1072        {
1073                .unitid = 10,
1074                .control = 2,
1075                .cmask = 0x2,
1076                .val_type = USB_MIXER_S16,
1077                .name = "Input B Capture Volume"
1078        },
1079
1080        {}
1081};
1082
1083int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1084{
1085        int err = 0;
1086        struct snd_info_entry *entry;
1087
1088        if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
1089                return err;
1090
1091        switch (mixer->chip->usb_id) {
1092        case USB_ID(0x041e, 0x3020):
1093        case USB_ID(0x041e, 0x3040):
1094        case USB_ID(0x041e, 0x3042):
1095        case USB_ID(0x041e, 0x30df):
1096        case USB_ID(0x041e, 0x3048):
1097                err = snd_audigy2nx_controls_create(mixer);
1098                if (err < 0)
1099                        break;
1100                if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
1101                        snd_info_set_text_ops(entry, mixer,
1102                                              snd_audigy2nx_proc_read);
1103                break;
1104
1105        case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
1106        case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
1107                err = snd_ftu_create_mixer(mixer);
1108                break;
1109
1110        case USB_ID(0x0b05, 0x1739):
1111        case USB_ID(0x0b05, 0x1743):
1112                err = snd_xonar_u1_controls_create(mixer);
1113                break;
1114
1115        case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
1116                err = snd_nativeinstruments_create_mixer(mixer,
1117                                snd_nativeinstruments_ta6_mixers,
1118                                ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
1119                break;
1120
1121        case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
1122                err = snd_nativeinstruments_create_mixer(mixer,
1123                                snd_nativeinstruments_ta10_mixers,
1124                                ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
1125                break;
1126
1127        case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
1128                /* detection is disabled in mixer_maps.c */
1129                err = snd_create_std_mono_table(mixer, ebox44_table);
1130                break;
1131        }
1132
1133        return err;
1134}
1135
1136void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
1137                                    int unitid)
1138{
1139        if (!mixer->rc_cfg)
1140                return;
1141        /* unit ids specific to Extigy/Audigy 2 NX: */
1142        switch (unitid) {
1143        case 0: /* remote control */
1144                mixer->rc_urb->dev = mixer->chip->dev;
1145                usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
1146                break;
1147        case 4: /* digital in jack */
1148        case 7: /* line in jacks */
1149        case 19: /* speaker out jacks */
1150        case 20: /* headphones out jack */
1151                break;
1152        /* live24ext: 4 = line-in jack */
1153        case 3: /* hp-out jack (may actuate Mute) */
1154                if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1155                    mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1156                        snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1157                break;
1158        default:
1159                snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
1160                break;
1161        }
1162}
1163
1164
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.