blob: b8b1f48c1f502c9e15fd4a6600ebbe481d0e9e1b [file] [log] [blame]
Daniel Mack7b1eda22010-03-11 21:13:22 +01001/*
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 *
Przemek Rudy066624c2013-06-27 23:52:33 +020012 * Audio Advantage Micro II support added by:
13 * Przemek Rudy (prudy1@o2.pl)
Daniel Mack7b1eda22010-03-11 21:13:22 +010014 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/init.h>
Stephen Rothwell36db0452010-03-29 16:02:50 +110031#include <linux/slab.h>
Daniel Mack7b1eda22010-03-11 21:13:22 +010032#include <linux/usb.h>
33#include <linux/usb/audio.h>
34
Przemek Rudy066624c2013-06-27 23:52:33 +020035#include <sound/asoundef.h>
Daniel Mack7b1eda22010-03-11 21:13:22 +010036#include <sound/core.h>
37#include <sound/control.h>
38#include <sound/hwdep.h>
39#include <sound/info.h>
40
41#include "usbaudio.h"
Daniel Mackf0b5e632010-03-11 21:13:23 +010042#include "mixer.h"
Daniel Mack7b1eda22010-03-11 21:13:22 +010043#include "mixer_quirks.h"
44#include "helper.h"
45
Daniel Mackd5a0bf62011-05-25 09:09:03 +020046extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
47
Mark Hillsb71dad182012-06-09 13:16:38 +010048struct std_mono_table {
49 unsigned int unitid, control, cmask;
50 int val_type;
51 const char *name;
52 snd_kcontrol_tlv_rw_t *tlv_callback;
53};
54
Felix Homann8a4d1d32012-04-23 20:24:23 +020055/* This function allows for the creation of standard UAC controls.
56 * See the quirks for M-Audio FTUs or Ebox-44.
57 * If you don't want to set a TLV callback pass NULL.
58 *
59 * Since there doesn't seem to be a devices that needs a multichannel
60 * version, we keep it mono for simplicity.
61 */
Eldad Zack9f814102012-11-28 23:55:35 +010062static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
Felix Homann8a4d1d32012-04-23 20:24:23 +020063 unsigned int unitid,
64 unsigned int control,
65 unsigned int cmask,
66 int val_type,
Eldad Zack9f814102012-11-28 23:55:35 +010067 unsigned int idx_off,
Felix Homann8a4d1d32012-04-23 20:24:23 +020068 const char *name,
69 snd_kcontrol_tlv_rw_t *tlv_callback)
70{
71 int err;
72 struct usb_mixer_elem_info *cval;
73 struct snd_kcontrol *kctl;
74
75 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
76 if (!cval)
77 return -ENOMEM;
78
79 cval->id = unitid;
80 cval->mixer = mixer;
81 cval->val_type = val_type;
82 cval->channels = 1;
83 cval->control = control;
84 cval->cmask = cmask;
Eldad Zack9f814102012-11-28 23:55:35 +010085 cval->idx_off = idx_off;
Felix Homann8a4d1d32012-04-23 20:24:23 +020086
Mark Hills7df4a692012-05-11 18:31:55 +010087 /* get_min_max() is called only for integer volumes later,
88 * so provide a short-cut for booleans */
Felix Homann8a4d1d32012-04-23 20:24:23 +020089 cval->min = 0;
90 cval->max = 1;
91 cval->res = 0;
92 cval->dBmin = 0;
93 cval->dBmax = 0;
94
95 /* Create control */
96 kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
97 if (!kctl) {
98 kfree(cval);
99 return -ENOMEM;
100 }
101
102 /* Set name */
103 snprintf(kctl->id.name, sizeof(kctl->id.name), name);
Chris J Argeseef90452014-11-12 12:07:01 -0600104 kctl->private_free = snd_usb_mixer_elem_free;
Felix Homann8a4d1d32012-04-23 20:24:23 +0200105
106 /* set TLV */
107 if (tlv_callback) {
108 kctl->tlv.c = tlv_callback;
109 kctl->vd[0].access |=
110 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
111 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
112 }
113 /* Add control to mixer */
114 err = snd_usb_mixer_add_control(mixer, kctl);
115 if (err < 0)
116 return err;
117
118 return 0;
119}
120
Eldad Zack9f814102012-11-28 23:55:35 +0100121static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
122 unsigned int unitid,
123 unsigned int control,
124 unsigned int cmask,
125 int val_type,
126 const char *name,
127 snd_kcontrol_tlv_rw_t *tlv_callback)
128{
129 return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask,
130 val_type, 0 /* Offset */, name, tlv_callback);
131}
132
Daniel Mack7b1eda22010-03-11 21:13:22 +0100133/*
Mark Hillsb71dad182012-06-09 13:16:38 +0100134 * Create a set of standard UAC controls from a table
135 */
136static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
137 struct std_mono_table *t)
138{
139 int err;
140
141 while (t->name != NULL) {
142 err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
143 t->cmask, t->val_type, t->name, t->tlv_callback);
144 if (err < 0)
145 return err;
146 t++;
147 }
148
149 return 0;
150}
151
152/*
Daniel Mack7b1eda22010-03-11 21:13:22 +0100153 * Sound Blaster remote control configuration
154 *
155 * format of remote control data:
156 * Extigy: xx 00
157 * Audigy 2 NX: 06 80 xx 00 00 00
158 * Live! 24-bit: 06 80 xx yy 22 83
159 */
160static const struct rc_config {
161 u32 usb_id;
162 u8 offset;
163 u8 length;
164 u8 packet_length;
165 u8 min_packet_length; /* minimum accepted length of the URB result */
166 u8 mute_mixer_id;
167 u32 mute_code;
168} rc_configs[] = {
169 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
170 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
171 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
Mandar Joshica8dc342010-11-02 14:43:19 +0000172 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200173 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
Daniel Mack7b1eda22010-03-11 21:13:22 +0100174 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
175};
176
177static void snd_usb_soundblaster_remote_complete(struct urb *urb)
178{
179 struct usb_mixer_interface *mixer = urb->context;
180 const struct rc_config *rc = mixer->rc_cfg;
181 u32 code;
182
183 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
184 return;
185
186 code = mixer->rc_buffer[rc->offset];
187 if (rc->length == 2)
188 code |= mixer->rc_buffer[rc->offset + 1] << 8;
189
190 /* the Mute button actually changes the mixer control */
191 if (code == rc->mute_code)
192 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
193 mixer->rc_code = code;
194 wmb();
195 wake_up(&mixer->rc_waitq);
196}
197
198static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
199 long count, loff_t *offset)
200{
201 struct usb_mixer_interface *mixer = hw->private_data;
202 int err;
203 u32 rc_code;
204
205 if (count != 1 && count != 4)
206 return -EINVAL;
207 err = wait_event_interruptible(mixer->rc_waitq,
208 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
209 if (err == 0) {
210 if (count == 1)
211 err = put_user(rc_code, buf);
212 else
213 err = put_user(rc_code, (u32 __user *)buf);
214 }
215 return err < 0 ? err : count;
216}
217
218static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
219 poll_table *wait)
220{
221 struct usb_mixer_interface *mixer = hw->private_data;
222
223 poll_wait(file, &mixer->rc_waitq, wait);
224 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
225}
226
227static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
228{
229 struct snd_hwdep *hwdep;
230 int err, len, i;
231
232 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
233 if (rc_configs[i].usb_id == mixer->chip->usb_id)
234 break;
235 if (i >= ARRAY_SIZE(rc_configs))
236 return 0;
237 mixer->rc_cfg = &rc_configs[i];
238
239 len = mixer->rc_cfg->packet_length;
240
241 init_waitqueue_head(&mixer->rc_waitq);
242 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
243 if (err < 0)
244 return err;
245 snprintf(hwdep->name, sizeof(hwdep->name),
246 "%s remote control", mixer->chip->card->shortname);
247 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
248 hwdep->private_data = mixer;
249 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
250 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
251 hwdep->exclusive = 1;
252
253 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
254 if (!mixer->rc_urb)
255 return -ENOMEM;
256 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
257 if (!mixer->rc_setup_packet) {
258 usb_free_urb(mixer->rc_urb);
259 mixer->rc_urb = NULL;
260 return -ENOMEM;
261 }
262 mixer->rc_setup_packet->bRequestType =
263 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
264 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
265 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
266 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
267 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
268 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
269 usb_rcvctrlpipe(mixer->chip->dev, 0),
270 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
271 snd_usb_soundblaster_remote_complete, mixer);
272 return 0;
273}
274
275#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
276
277static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
278{
279 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
280 int index = kcontrol->private_value;
281
282 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
283 return 0;
284}
285
286static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
287{
288 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
289 int index = kcontrol->private_value;
290 int value = ucontrol->value.integer.value[0];
291 int err, changed;
292
293 if (value > 1)
294 return -EINVAL;
295 changed = value != mixer->audigy2nx_leds[index];
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200296 down_read(&mixer->chip->shutdown_rwsem);
297 if (mixer->chip->shutdown) {
298 err = -ENODEV;
299 goto out;
300 }
Mandar Joshica8dc342010-11-02 14:43:19 +0000301 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
302 err = snd_usb_ctl_msg(mixer->chip->dev,
303 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
304 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200305 !value, 0, NULL, 0);
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200306 /* USB X-Fi S51 Pro */
307 if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
308 err = snd_usb_ctl_msg(mixer->chip->dev,
309 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
310 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200311 !value, 0, NULL, 0);
Mandar Joshica8dc342010-11-02 14:43:19 +0000312 else
313 err = snd_usb_ctl_msg(mixer->chip->dev,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100314 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
315 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200316 value, index + 2, NULL, 0);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200317 out:
318 up_read(&mixer->chip->shutdown_rwsem);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100319 if (err < 0)
320 return err;
321 mixer->audigy2nx_leds[index] = value;
322 return changed;
323}
324
325static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
326 {
327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
328 .name = "CMSS LED Switch",
329 .info = snd_audigy2nx_led_info,
330 .get = snd_audigy2nx_led_get,
331 .put = snd_audigy2nx_led_put,
332 .private_value = 0,
333 },
334 {
335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
336 .name = "Power LED Switch",
337 .info = snd_audigy2nx_led_info,
338 .get = snd_audigy2nx_led_get,
339 .put = snd_audigy2nx_led_put,
340 .private_value = 1,
341 },
342 {
343 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
344 .name = "Dolby Digital LED Switch",
345 .info = snd_audigy2nx_led_info,
346 .get = snd_audigy2nx_led_get,
347 .put = snd_audigy2nx_led_put,
348 .private_value = 2,
349 },
350};
351
352static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
353{
354 int i, err;
355
356 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
Mandar Joshica8dc342010-11-02 14:43:19 +0000357 /* USB X-Fi S51 doesn't have a CMSS LED */
358 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
359 continue;
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200360 /* USB X-Fi S51 Pro doesn't have one either */
361 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
362 continue;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100363 if (i > 1 && /* Live24ext has 2 LEDs only */
364 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
Mandar Joshica8dc342010-11-02 14:43:19 +0000365 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200366 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
Daniel Mack7b1eda22010-03-11 21:13:22 +0100367 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
368 break;
369 err = snd_ctl_add(mixer->chip->card,
370 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
371 if (err < 0)
372 return err;
373 }
374 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
375 return 0;
376}
377
378static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
379 struct snd_info_buffer *buffer)
380{
381 static const struct sb_jack {
382 int unitid;
383 const char *name;
384 } jacks_audigy2nx[] = {
385 {4, "dig in "},
386 {7, "line in"},
387 {19, "spk out"},
388 {20, "hph out"},
389 {-1, NULL}
390 }, jacks_live24ext[] = {
391 {4, "line in"}, /* &1=Line, &2=Mic*/
392 {3, "hph out"}, /* headphones */
393 {0, "RC "}, /* last command, 6 bytes see rc_config above */
394 {-1, NULL}
395 };
396 const struct sb_jack *jacks;
397 struct usb_mixer_interface *mixer = entry->private_data;
398 int i, err;
399 u8 buf[3];
400
401 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
402 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
403 jacks = jacks_audigy2nx;
404 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
405 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
406 jacks = jacks_live24ext;
407 else
408 return;
409
410 for (i = 0; jacks[i].name; ++i) {
411 snd_iprintf(buffer, "%s: ", jacks[i].name);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200412 down_read(&mixer->chip->shutdown_rwsem);
413 if (mixer->chip->shutdown)
414 err = 0;
415 else
416 err = snd_usb_ctl_msg(mixer->chip->dev,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100417 usb_rcvctrlpipe(mixer->chip->dev, 0),
418 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
419 USB_RECIP_INTERFACE, 0,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200420 jacks[i].unitid << 8, buf, 3);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200421 up_read(&mixer->chip->shutdown_rwsem);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100422 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
423 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
424 else
425 snd_iprintf(buffer, "?\n");
426 }
427}
428
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300429/* EMU0204 */
430static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol,
431 struct snd_ctl_elem_info *uinfo)
432{
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200433 static const char * const texts[2] = {"1/2", "3/4"};
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300434
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200435 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300436}
437
438static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
439 struct snd_ctl_elem_value *ucontrol)
440{
441 ucontrol->value.enumerated.item[0] = kcontrol->private_value;
442 return 0;
443}
444
445static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
449 unsigned int value = ucontrol->value.enumerated.item[0];
450 int err, changed;
451 unsigned char buf[2];
452
453 if (value > 1)
454 return -EINVAL;
455
456 buf[0] = 0x01;
457 buf[1] = value ? 0x02 : 0x01;
458
459 changed = value != kcontrol->private_value;
460 down_read(&mixer->chip->shutdown_rwsem);
461 if (mixer->chip->shutdown) {
462 err = -ENODEV;
463 goto out;
464 }
465 err = snd_usb_ctl_msg(mixer->chip->dev,
466 usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR,
467 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
468 0x0400, 0x0e00, buf, 2);
469 out:
470 up_read(&mixer->chip->shutdown_rwsem);
471 if (err < 0)
472 return err;
473 kcontrol->private_value = value;
474 return changed;
475}
476
477
478static struct snd_kcontrol_new snd_emu0204_controls[] = {
479 {
480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
481 .name = "Front Jack Channels",
482 .info = snd_emu0204_ch_switch_info,
483 .get = snd_emu0204_ch_switch_get,
484 .put = snd_emu0204_ch_switch_put,
485 .private_value = 0,
486 },
487};
488
489static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
490{
491 int i, err;
492
493 for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) {
494 err = snd_ctl_add(mixer->chip->card,
495 snd_ctl_new1(&snd_emu0204_controls[i], mixer));
496 if (err < 0)
497 return err;
498 }
499
500 return 0;
501}
Denis Washington1d31aff2012-12-11 11:38:32 +0100502/* ASUS Xonar U1 / U3 controls */
503
Daniel Mack7b1eda22010-03-11 21:13:22 +0100504static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_value *ucontrol)
506{
507 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
508
509 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
510 return 0;
511}
512
513static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
515{
516 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
517 u8 old_status, new_status;
518 int err, changed;
519
520 old_status = mixer->xonar_u1_status;
521 if (ucontrol->value.integer.value[0])
522 new_status = old_status | 0x02;
523 else
524 new_status = old_status & ~0x02;
525 changed = new_status != old_status;
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200526 down_read(&mixer->chip->shutdown_rwsem);
527 if (mixer->chip->shutdown)
528 err = -ENODEV;
529 else
530 err = snd_usb_ctl_msg(mixer->chip->dev,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100531 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
532 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200533 50, 0, &new_status, 1);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200534 up_read(&mixer->chip->shutdown_rwsem);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100535 if (err < 0)
536 return err;
537 mixer->xonar_u1_status = new_status;
538 return changed;
539}
540
541static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
543 .name = "Digital Playback Switch",
544 .info = snd_ctl_boolean_mono_info,
545 .get = snd_xonar_u1_switch_get,
546 .put = snd_xonar_u1_switch_put,
547};
548
549static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
550{
551 int err;
552
553 err = snd_ctl_add(mixer->chip->card,
554 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
555 if (err < 0)
556 return err;
557 mixer->xonar_u1_status = 0x05;
558 return 0;
559}
560
Damien Zammitd497a822014-11-12 01:09:54 +1100561/* Digidesign Mbox 1 clock source switch (internal/spdif) */
562
563static int snd_mbox1_switch_get(struct snd_kcontrol *kctl,
564 struct snd_ctl_elem_value *ucontrol)
565{
566 ucontrol->value.enumerated.item[0] = kctl->private_value;
567 return 0;
568}
569
570static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
571 struct snd_ctl_elem_value *ucontrol)
572{
573 struct snd_usb_audio *chip;
574 struct usb_mixer_interface *mixer;
575 int err;
576 bool cur_val, new_val;
577 unsigned char buff[3];
578
579 cur_val = kctl->private_value;
580 new_val = ucontrol->value.enumerated.item[0];
581
582 mixer = snd_kcontrol_chip(kctl);
583 if (snd_BUG_ON(!mixer))
584 return -EINVAL;
585
586 chip = mixer->chip;
587 if (snd_BUG_ON(!chip))
588 return -EINVAL;
589
590 if (cur_val == new_val)
591 return 0;
592
593 down_read(&chip->shutdown_rwsem);
594 if (chip->shutdown) {
595 err = -ENODEV;
596 goto err;
597 }
598
599 /* Prepare for magic command to toggle clock source */
600 err = snd_usb_ctl_msg(chip->dev,
601 usb_rcvctrlpipe(chip->dev, 0), 0x81,
602 USB_DIR_IN |
603 USB_TYPE_CLASS |
604 USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1);
605 if (err < 0)
606 goto err;
607 err = snd_usb_ctl_msg(chip->dev,
608 usb_rcvctrlpipe(chip->dev, 0), 0x81,
609 USB_DIR_IN |
610 USB_TYPE_CLASS |
611 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
612 if (err < 0)
613 goto err;
614
615 /* 2 possibilities: Internal -> send sample rate
616 * S/PDIF sync -> send zeroes
617 * NB: Sample rate locked to 48kHz on purpose to
618 * prevent user from resetting the sample rate
619 * while S/PDIF sync is enabled and confusing
620 * this configuration.
621 */
622 if (new_val == 0) {
623 buff[0] = 0x80;
624 buff[1] = 0xbb;
625 buff[2] = 0x00;
626 } else {
627 buff[0] = buff[1] = buff[2] = 0x00;
628 }
629
630 /* Send the magic command to toggle the clock source */
631 err = snd_usb_ctl_msg(chip->dev,
632 usb_sndctrlpipe(chip->dev, 0), 0x1,
633 USB_TYPE_CLASS |
634 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
635 if (err < 0)
636 goto err;
637 err = snd_usb_ctl_msg(chip->dev,
638 usb_rcvctrlpipe(chip->dev, 0), 0x81,
639 USB_DIR_IN |
640 USB_TYPE_CLASS |
641 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
642 if (err < 0)
643 goto err;
644 err = snd_usb_ctl_msg(chip->dev,
645 usb_rcvctrlpipe(chip->dev, 0), 0x81,
646 USB_DIR_IN |
647 USB_TYPE_CLASS |
648 USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3);
649 if (err < 0)
650 goto err;
651 kctl->private_value = new_val;
652
653err:
654 up_read(&chip->shutdown_rwsem);
655 return err < 0 ? err : 1;
656}
657
658static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol,
659 struct snd_ctl_elem_info *uinfo)
660{
661 static const char *const texts[2] = {
662 "Internal",
663 "S/PDIF"
664 };
665
666 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
667}
668
669static struct snd_kcontrol_new snd_mbox1_switch = {
670 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
671 .name = "Clock Source",
672 .index = 0,
673 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
674 .info = snd_mbox1_switch_info,
675 .get = snd_mbox1_switch_get,
676 .put = snd_mbox1_switch_put,
677 .private_value = 0
678};
679
680static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
681{
682 return snd_ctl_add(mixer->chip->card,
683 snd_ctl_new1(&snd_mbox1_switch, mixer));
684}
685
Daniel Mack54a8c502011-02-11 11:08:06 +0000686/* Native Instruments device quirks */
687
688#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
689
690static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
691 struct snd_ctl_elem_value *ucontrol)
692{
693 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
694 struct usb_device *dev = mixer->chip->dev;
695 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
696 u16 wIndex = kcontrol->private_value & 0xffff;
697 u8 tmp;
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200698 int ret;
Daniel Mack54a8c502011-02-11 11:08:06 +0000699
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200700 down_read(&mixer->chip->shutdown_rwsem);
701 if (mixer->chip->shutdown)
702 ret = -ENODEV;
703 else
704 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
Daniel Mack54a8c502011-02-11 11:08:06 +0000705 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
Eldad Zack889d6682013-04-05 20:49:46 +0200706 0, wIndex,
Daniel Mack54a8c502011-02-11 11:08:06 +0000707 &tmp, sizeof(tmp), 1000);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200708 up_read(&mixer->chip->shutdown_rwsem);
Daniel Mack54a8c502011-02-11 11:08:06 +0000709
710 if (ret < 0) {
Takashi Iwai0ba41d92014-02-26 13:02:17 +0100711 dev_err(&dev->dev,
712 "unable to issue vendor read request (ret = %d)", ret);
Daniel Mack54a8c502011-02-11 11:08:06 +0000713 return ret;
714 }
715
716 ucontrol->value.integer.value[0] = tmp;
717
718 return 0;
719}
720
721static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
723{
724 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
725 struct usb_device *dev = mixer->chip->dev;
726 u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
727 u16 wIndex = kcontrol->private_value & 0xffff;
728 u16 wValue = ucontrol->value.integer.value[0];
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200729 int ret;
Daniel Mack54a8c502011-02-11 11:08:06 +0000730
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200731 down_read(&mixer->chip->shutdown_rwsem);
732 if (mixer->chip->shutdown)
733 ret = -ENODEV;
734 else
735 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
Daniel Mack54a8c502011-02-11 11:08:06 +0000736 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
Eldad Zack889d6682013-04-05 20:49:46 +0200737 wValue, wIndex,
Daniel Mack54a8c502011-02-11 11:08:06 +0000738 NULL, 0, 1000);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200739 up_read(&mixer->chip->shutdown_rwsem);
Daniel Mack54a8c502011-02-11 11:08:06 +0000740
741 if (ret < 0) {
Takashi Iwai0ba41d92014-02-26 13:02:17 +0100742 dev_err(&dev->dev,
743 "unable to issue vendor write request (ret = %d)", ret);
Daniel Mack54a8c502011-02-11 11:08:06 +0000744 return ret;
745 }
746
747 return 0;
748}
749
750static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
751 {
752 .name = "Direct Thru Channel A",
753 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
754 },
755 {
756 .name = "Direct Thru Channel B",
757 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
758 },
759 {
760 .name = "Phono Input Channel A",
761 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
762 },
763 {
764 .name = "Phono Input Channel B",
765 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
766 },
767};
768
769static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
770 {
771 .name = "Direct Thru Channel A",
772 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
773 },
774 {
775 .name = "Direct Thru Channel B",
776 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
777 },
778 {
779 .name = "Direct Thru Channel C",
780 .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
781 },
782 {
783 .name = "Direct Thru Channel D",
784 .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
785 },
786 {
787 .name = "Phono Input Channel A",
788 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
789 },
790 {
791 .name = "Phono Input Channel B",
792 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
793 },
794 {
795 .name = "Phono Input Channel C",
796 .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
797 },
798 {
799 .name = "Phono Input Channel D",
800 .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
801 },
802};
803
804static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
805 const struct snd_kcontrol_new *kc,
806 unsigned int count)
807{
808 int i, err = 0;
809 struct snd_kcontrol_new template = {
810 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
811 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
812 .get = snd_nativeinstruments_control_get,
813 .put = snd_nativeinstruments_control_put,
814 .info = snd_ctl_boolean_mono_info,
815 };
816
817 for (i = 0; i < count; i++) {
818 struct snd_kcontrol *c;
819
820 template.name = kc[i].name;
821 template.private_value = kc[i].private_value;
822
823 c = snd_ctl_new1(&template, mixer);
824 err = snd_ctl_add(mixer->chip->card, c);
825
826 if (err < 0)
827 break;
828 }
829
830 return err;
831}
832
Daniel Mackd5a0bf62011-05-25 09:09:03 +0200833/* M-Audio FastTrack Ultra quirks */
Matt Gruskine9a25e02013-02-09 12:56:35 -0500834/* FTU Effect switch (also used by C400/C600) */
Felix Homannd34bf142012-04-23 20:24:27 +0200835struct snd_ftu_eff_switch_priv_val {
836 struct usb_mixer_interface *mixer;
837 int cached_value;
838 int is_cached;
Eldad Zackd847ce02012-11-28 23:55:37 +0100839 int bUnitID;
840 int validx;
Felix Homannd34bf142012-04-23 20:24:27 +0200841};
842
843static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
844 struct snd_ctl_elem_info *uinfo)
845{
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200846 static const char *const texts[8] = {
847 "Room 1", "Room 2", "Room 3", "Hall 1",
848 "Hall 2", "Plate", "Delay", "Echo"
Felix Homannd34bf142012-04-23 20:24:27 +0200849 };
850
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200851 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
Felix Homannd34bf142012-04-23 20:24:27 +0200852}
853
854static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
855 struct snd_ctl_elem_value *ucontrol)
856{
857 struct snd_usb_audio *chip;
858 struct usb_mixer_interface *mixer;
859 struct snd_ftu_eff_switch_priv_val *pval;
860 int err;
861 unsigned char value[2];
Eldad Zackd847ce02012-11-28 23:55:37 +0100862 int id, validx;
Felix Homannd34bf142012-04-23 20:24:27 +0200863
Felix Homannd34bf142012-04-23 20:24:27 +0200864 const int val_len = 2;
865
866 value[0] = 0x00;
867 value[1] = 0x00;
868
869 pval = (struct snd_ftu_eff_switch_priv_val *)
870 kctl->private_value;
871
872 if (pval->is_cached) {
873 ucontrol->value.enumerated.item[0] = pval->cached_value;
874 return 0;
875 }
876
877 mixer = (struct usb_mixer_interface *) pval->mixer;
878 if (snd_BUG_ON(!mixer))
879 return -EINVAL;
880
881 chip = (struct snd_usb_audio *) mixer->chip;
882 if (snd_BUG_ON(!chip))
883 return -EINVAL;
884
Eldad Zackd847ce02012-11-28 23:55:37 +0100885 id = pval->bUnitID;
886 validx = pval->validx;
Felix Homannd34bf142012-04-23 20:24:27 +0200887
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200888 down_read(&mixer->chip->shutdown_rwsem);
889 if (mixer->chip->shutdown)
890 err = -ENODEV;
891 else
892 err = snd_usb_ctl_msg(chip->dev,
Felix Homannd34bf142012-04-23 20:24:27 +0200893 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
894 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
895 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
896 value, val_len);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200897 up_read(&mixer->chip->shutdown_rwsem);
Felix Homannd34bf142012-04-23 20:24:27 +0200898 if (err < 0)
899 return err;
900
901 ucontrol->value.enumerated.item[0] = value[0];
902 pval->cached_value = value[0];
903 pval->is_cached = 1;
904
905 return 0;
906}
907
908static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
909 struct snd_ctl_elem_value *ucontrol)
910{
911 struct snd_usb_audio *chip;
912 struct snd_ftu_eff_switch_priv_val *pval;
913
914 struct usb_mixer_interface *mixer;
915 int changed, cur_val, err, new_val;
916 unsigned char value[2];
Eldad Zackd847ce02012-11-28 23:55:37 +0100917 int id, validx;
Felix Homannd34bf142012-04-23 20:24:27 +0200918
Felix Homannd34bf142012-04-23 20:24:27 +0200919 const int val_len = 2;
920
921 changed = 0;
922
923 pval = (struct snd_ftu_eff_switch_priv_val *)
924 kctl->private_value;
925 cur_val = pval->cached_value;
926 new_val = ucontrol->value.enumerated.item[0];
927
928 mixer = (struct usb_mixer_interface *) pval->mixer;
929 if (snd_BUG_ON(!mixer))
930 return -EINVAL;
931
932 chip = (struct snd_usb_audio *) mixer->chip;
933 if (snd_BUG_ON(!chip))
934 return -EINVAL;
935
Eldad Zackd847ce02012-11-28 23:55:37 +0100936 id = pval->bUnitID;
937 validx = pval->validx;
938
Felix Homannd34bf142012-04-23 20:24:27 +0200939 if (!pval->is_cached) {
940 /* Read current value */
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200941 down_read(&mixer->chip->shutdown_rwsem);
942 if (mixer->chip->shutdown)
943 err = -ENODEV;
944 else
945 err = snd_usb_ctl_msg(chip->dev,
Felix Homannd34bf142012-04-23 20:24:27 +0200946 usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
947 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
948 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
949 value, val_len);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200950 up_read(&mixer->chip->shutdown_rwsem);
Felix Homannd34bf142012-04-23 20:24:27 +0200951 if (err < 0)
952 return err;
953
954 cur_val = value[0];
955 pval->cached_value = cur_val;
956 pval->is_cached = 1;
957 }
958 /* update value if needed */
959 if (cur_val != new_val) {
960 value[0] = new_val;
961 value[1] = 0;
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200962 down_read(&mixer->chip->shutdown_rwsem);
963 if (mixer->chip->shutdown)
964 err = -ENODEV;
965 else
966 err = snd_usb_ctl_msg(chip->dev,
Felix Homannd34bf142012-04-23 20:24:27 +0200967 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
968 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
969 validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
970 value, val_len);
Takashi Iwai888ea7d2012-10-15 12:40:37 +0200971 up_read(&mixer->chip->shutdown_rwsem);
Felix Homannd34bf142012-04-23 20:24:27 +0200972 if (err < 0)
973 return err;
974
975 pval->cached_value = new_val;
976 pval->is_cached = 1;
977 changed = 1;
978 }
979
980 return changed;
981}
982
Eldad Zackd847ce02012-11-28 23:55:37 +0100983static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
984 int validx, int bUnitID)
Felix Homannd34bf142012-04-23 20:24:27 +0200985{
986 static struct snd_kcontrol_new template = {
987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
988 .name = "Effect Program Switch",
989 .index = 0,
990 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
991 .info = snd_ftu_eff_switch_info,
992 .get = snd_ftu_eff_switch_get,
993 .put = snd_ftu_eff_switch_put
994 };
995
996 int err;
997 struct snd_kcontrol *kctl;
998 struct snd_ftu_eff_switch_priv_val *pval;
999
1000 pval = kzalloc(sizeof(*pval), GFP_KERNEL);
1001 if (!pval)
1002 return -ENOMEM;
1003
1004 pval->cached_value = 0;
1005 pval->is_cached = 0;
1006 pval->mixer = mixer;
Eldad Zackd847ce02012-11-28 23:55:37 +01001007 pval->bUnitID = bUnitID;
1008 pval->validx = validx;
Felix Homannd34bf142012-04-23 20:24:27 +02001009
1010 template.private_value = (unsigned long) pval;
1011 kctl = snd_ctl_new1(&template, mixer->chip);
1012 if (!kctl) {
1013 kfree(pval);
1014 return -ENOMEM;
1015 }
1016
1017 err = snd_ctl_add(mixer->chip->card, kctl);
1018 if (err < 0)
1019 return err;
1020
1021 return 0;
1022}
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001023
Felix Homanncfe8f972012-04-23 20:24:26 +02001024/* Create volume controls for FTU devices*/
1025static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001026{
1027 char name[64];
Felix Homann8a4d1d32012-04-23 20:24:23 +02001028 unsigned int control, cmask;
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001029 int in, out, err;
1030
Felix Homann8a4d1d32012-04-23 20:24:23 +02001031 const unsigned int id = 5;
1032 const int val_type = USB_MIXER_S16;
1033
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001034 for (out = 0; out < 8; out++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001035 control = out + 1;
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001036 for (in = 0; in < 8; in++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001037 cmask = 1 << in;
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001038 snprintf(name, sizeof(name),
Felix Homann8a4d1d32012-04-23 20:24:23 +02001039 "AIn%d - Out%d Capture Volume",
1040 in + 1, out + 1);
1041 err = snd_create_std_mono_ctl(mixer, id, control,
1042 cmask, val_type, name,
Felix Homann25ee7ef2012-04-23 20:24:25 +02001043 &snd_usb_mixer_vol_tlv);
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001044 if (err < 0)
1045 return err;
1046 }
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001047 for (in = 8; in < 16; in++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001048 cmask = 1 << in;
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001049 snprintf(name, sizeof(name),
Felix Homann8a4d1d32012-04-23 20:24:23 +02001050 "DIn%d - Out%d Playback Volume",
1051 in - 7, out + 1);
1052 err = snd_create_std_mono_ctl(mixer, id, control,
1053 cmask, val_type, name,
Felix Homann25ee7ef2012-04-23 20:24:25 +02001054 &snd_usb_mixer_vol_tlv);
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001055 if (err < 0)
1056 return err;
1057 }
1058 }
1059
1060 return 0;
1061}
1062
Felix Homannd34bf142012-04-23 20:24:27 +02001063/* This control needs a volume quirk, see mixer.c */
1064static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
1065{
1066 static const char name[] = "Effect Volume";
1067 const unsigned int id = 6;
1068 const int val_type = USB_MIXER_U8;
1069 const unsigned int control = 2;
1070 const unsigned int cmask = 0;
1071
1072 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1073 name, snd_usb_mixer_vol_tlv);
1074}
1075
1076/* This control needs a volume quirk, see mixer.c */
1077static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
1078{
1079 static const char name[] = "Effect Duration";
1080 const unsigned int id = 6;
1081 const int val_type = USB_MIXER_S16;
1082 const unsigned int control = 3;
1083 const unsigned int cmask = 0;
1084
1085 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1086 name, snd_usb_mixer_vol_tlv);
1087}
1088
1089/* This control needs a volume quirk, see mixer.c */
1090static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
1091{
1092 static const char name[] = "Effect Feedback Volume";
1093 const unsigned int id = 6;
1094 const int val_type = USB_MIXER_U8;
1095 const unsigned int control = 4;
1096 const unsigned int cmask = 0;
1097
1098 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1099 name, NULL);
1100}
1101
1102static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer)
1103{
1104 unsigned int cmask;
1105 int err, ch;
1106 char name[48];
1107
1108 const unsigned int id = 7;
1109 const int val_type = USB_MIXER_S16;
1110 const unsigned int control = 7;
1111
1112 for (ch = 0; ch < 4; ++ch) {
1113 cmask = 1 << ch;
1114 snprintf(name, sizeof(name),
1115 "Effect Return %d Volume", ch + 1);
1116 err = snd_create_std_mono_ctl(mixer, id, control,
1117 cmask, val_type, name,
1118 snd_usb_mixer_vol_tlv);
1119 if (err < 0)
1120 return err;
1121 }
1122
1123 return 0;
1124}
1125
1126static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer)
1127{
1128 unsigned int cmask;
1129 int err, ch;
1130 char name[48];
1131
1132 const unsigned int id = 5;
1133 const int val_type = USB_MIXER_S16;
1134 const unsigned int control = 9;
1135
1136 for (ch = 0; ch < 8; ++ch) {
1137 cmask = 1 << ch;
1138 snprintf(name, sizeof(name),
1139 "Effect Send AIn%d Volume", ch + 1);
1140 err = snd_create_std_mono_ctl(mixer, id, control, cmask,
1141 val_type, name,
1142 snd_usb_mixer_vol_tlv);
1143 if (err < 0)
1144 return err;
1145 }
1146 for (ch = 8; ch < 16; ++ch) {
1147 cmask = 1 << ch;
1148 snprintf(name, sizeof(name),
1149 "Effect Send DIn%d Volume", ch - 7);
1150 err = snd_create_std_mono_ctl(mixer, id, control, cmask,
1151 val_type, name,
1152 snd_usb_mixer_vol_tlv);
1153 if (err < 0)
1154 return err;
1155 }
1156 return 0;
1157}
1158
Felix Homanncfe8f972012-04-23 20:24:26 +02001159static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
Mark Hills7536c302012-04-14 17:19:24 +01001160{
Felix Homann8a4d1d32012-04-23 20:24:23 +02001161 int err;
Mark Hills7536c302012-04-14 17:19:24 +01001162
Felix Homanncfe8f972012-04-23 20:24:26 +02001163 err = snd_ftu_create_volume_ctls(mixer);
Felix Homann8a4d1d32012-04-23 20:24:23 +02001164 if (err < 0)
1165 return err;
Mark Hills7536c302012-04-14 17:19:24 +01001166
Eldad Zackd847ce02012-11-28 23:55:37 +01001167 err = snd_ftu_create_effect_switch(mixer, 1, 6);
Felix Homannd34bf142012-04-23 20:24:27 +02001168 if (err < 0)
1169 return err;
Eldad Zackd847ce02012-11-28 23:55:37 +01001170
Felix Homannd34bf142012-04-23 20:24:27 +02001171 err = snd_ftu_create_effect_volume_ctl(mixer);
1172 if (err < 0)
1173 return err;
1174
1175 err = snd_ftu_create_effect_duration_ctl(mixer);
1176 if (err < 0)
1177 return err;
1178
1179 err = snd_ftu_create_effect_feedback_ctl(mixer);
1180 if (err < 0)
1181 return err;
1182
1183 err = snd_ftu_create_effect_return_ctls(mixer);
1184 if (err < 0)
1185 return err;
1186
1187 err = snd_ftu_create_effect_send_ctls(mixer);
1188 if (err < 0)
1189 return err;
1190
Felix Homann8a4d1d32012-04-23 20:24:23 +02001191 return 0;
Mark Hills7536c302012-04-14 17:19:24 +01001192}
1193
Daniel Mack7b1eda22010-03-11 21:13:22 +01001194void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
1195 unsigned char samplerate_id)
1196{
1197 struct usb_mixer_interface *mixer;
1198 struct usb_mixer_elem_info *cval;
1199 int unitid = 12; /* SamleRate ExtensionUnit ID */
1200
1201 list_for_each_entry(mixer, &chip->mixer_list, list) {
1202 cval = mixer->id_elems[unitid];
1203 if (cval) {
1204 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
1205 cval->control << 8,
1206 samplerate_id);
1207 snd_usb_mixer_notify_id(mixer, unitid);
1208 }
1209 break;
1210 }
1211}
1212
Matt Gruskine9a25e02013-02-09 12:56:35 -05001213/* M-Audio Fast Track C400/C600 */
1214/* C400/C600 volume controls, this control needs a volume quirk, see mixer.c */
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001215static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
1216{
1217 char name[64];
1218 unsigned int cmask, offset;
1219 int out, chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001220 int num_outs = 0;
1221 int num_ins = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001222
1223 const unsigned int id = 0x40;
1224 const int val_type = USB_MIXER_S16;
1225 const int control = 1;
1226
Matt Gruskine9a25e02013-02-09 12:56:35 -05001227 switch (mixer->chip->usb_id) {
1228 case USB_ID(0x0763, 0x2030):
1229 num_outs = 6;
1230 num_ins = 4;
1231 break;
1232 case USB_ID(0x0763, 0x2031):
1233 num_outs = 8;
1234 num_ins = 6;
1235 break;
1236 }
1237
1238 for (chan = 0; chan < num_outs + num_ins; chan++) {
1239 for (out = 0; out < num_outs; out++) {
1240 if (chan < num_outs) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001241 snprintf(name, sizeof(name),
1242 "PCM%d-Out%d Playback Volume",
1243 chan + 1, out + 1);
1244 } else {
1245 snprintf(name, sizeof(name),
1246 "In%d-Out%d Playback Volume",
Matt Gruskine9a25e02013-02-09 12:56:35 -05001247 chan - num_outs + 1, out + 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001248 }
1249
1250 cmask = (out == 0) ? 0 : 1 << (out - 1);
Matt Gruskine9a25e02013-02-09 12:56:35 -05001251 offset = chan * num_outs;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001252 err = snd_create_std_mono_ctl_offset(mixer, id, control,
1253 cmask, val_type, offset, name,
1254 &snd_usb_mixer_vol_tlv);
1255 if (err < 0)
1256 return err;
1257 }
1258 }
1259
1260 return 0;
1261}
1262
1263/* This control needs a volume quirk, see mixer.c */
1264static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
1265{
1266 static const char name[] = "Effect Volume";
1267 const unsigned int id = 0x43;
1268 const int val_type = USB_MIXER_U8;
1269 const unsigned int control = 3;
1270 const unsigned int cmask = 0;
1271
1272 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1273 name, snd_usb_mixer_vol_tlv);
1274}
1275
1276/* This control needs a volume quirk, see mixer.c */
1277static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
1278{
1279 static const char name[] = "Effect Duration";
1280 const unsigned int id = 0x43;
1281 const int val_type = USB_MIXER_S16;
1282 const unsigned int control = 4;
1283 const unsigned int cmask = 0;
1284
1285 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1286 name, snd_usb_mixer_vol_tlv);
1287}
1288
1289/* This control needs a volume quirk, see mixer.c */
1290static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
1291{
1292 static const char name[] = "Effect Feedback Volume";
1293 const unsigned int id = 0x43;
1294 const int val_type = USB_MIXER_U8;
1295 const unsigned int control = 5;
1296 const unsigned int cmask = 0;
1297
1298 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1299 name, NULL);
1300}
1301
1302static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
1303{
1304 char name[64];
1305 unsigned int cmask;
1306 int chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001307 int num_outs = 0;
1308 int num_ins = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001309
1310 const unsigned int id = 0x42;
1311 const int val_type = USB_MIXER_S16;
1312 const int control = 1;
1313
Matt Gruskine9a25e02013-02-09 12:56:35 -05001314 switch (mixer->chip->usb_id) {
1315 case USB_ID(0x0763, 0x2030):
1316 num_outs = 6;
1317 num_ins = 4;
1318 break;
1319 case USB_ID(0x0763, 0x2031):
1320 num_outs = 8;
1321 num_ins = 6;
1322 break;
1323 }
1324
1325 for (chan = 0; chan < num_outs + num_ins; chan++) {
1326 if (chan < num_outs) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001327 snprintf(name, sizeof(name),
1328 "Effect Send DOut%d",
1329 chan + 1);
1330 } else {
1331 snprintf(name, sizeof(name),
1332 "Effect Send AIn%d",
Matt Gruskine9a25e02013-02-09 12:56:35 -05001333 chan - num_outs + 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001334 }
1335
1336 cmask = (chan == 0) ? 0 : 1 << (chan - 1);
1337 err = snd_create_std_mono_ctl(mixer, id, control,
1338 cmask, val_type, name,
1339 &snd_usb_mixer_vol_tlv);
1340 if (err < 0)
1341 return err;
1342 }
1343
1344 return 0;
1345}
1346
1347static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer)
1348{
1349 char name[64];
1350 unsigned int cmask;
1351 int chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001352 int num_outs = 0;
1353 int offset = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001354
1355 const unsigned int id = 0x40;
1356 const int val_type = USB_MIXER_S16;
1357 const int control = 1;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001358
Matt Gruskine9a25e02013-02-09 12:56:35 -05001359 switch (mixer->chip->usb_id) {
1360 case USB_ID(0x0763, 0x2030):
1361 num_outs = 6;
1362 offset = 0x3c;
1363 /* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */
1364 break;
1365 case USB_ID(0x0763, 0x2031):
1366 num_outs = 8;
1367 offset = 0x70;
1368 /* { 0x70, 0x79, 0x72, 0x7b, 0x74, 0x7d, 0x76, 0x7f } */
1369 break;
1370 }
1371
1372 for (chan = 0; chan < num_outs; chan++) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001373 snprintf(name, sizeof(name),
1374 "Effect Return %d",
1375 chan + 1);
1376
Matt Gruskine9a25e02013-02-09 12:56:35 -05001377 cmask = (chan == 0) ? 0 :
1378 1 << (chan + (chan % 2) * num_outs - 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001379 err = snd_create_std_mono_ctl_offset(mixer, id, control,
1380 cmask, val_type, offset, name,
1381 &snd_usb_mixer_vol_tlv);
1382 if (err < 0)
1383 return err;
1384 }
1385
1386 return 0;
1387}
1388
1389static int snd_c400_create_mixer(struct usb_mixer_interface *mixer)
1390{
1391 int err;
1392
1393 err = snd_c400_create_vol_ctls(mixer);
1394 if (err < 0)
1395 return err;
1396
1397 err = snd_c400_create_effect_vol_ctls(mixer);
1398 if (err < 0)
1399 return err;
1400
1401 err = snd_c400_create_effect_ret_vol_ctls(mixer);
1402 if (err < 0)
1403 return err;
1404
1405 err = snd_ftu_create_effect_switch(mixer, 2, 0x43);
1406 if (err < 0)
1407 return err;
1408
1409 err = snd_c400_create_effect_volume_ctl(mixer);
1410 if (err < 0)
1411 return err;
1412
1413 err = snd_c400_create_effect_duration_ctl(mixer);
1414 if (err < 0)
1415 return err;
1416
1417 err = snd_c400_create_effect_feedback_ctl(mixer);
1418 if (err < 0)
1419 return err;
1420
1421 return 0;
1422}
1423
Mark Hillsb71dad182012-06-09 13:16:38 +01001424/*
1425 * The mixer units for Ebox-44 are corrupt, and even where they
1426 * are valid they presents mono controls as L and R channels of
1427 * stereo. So we provide a good mixer here.
1428 */
Sachin Kamate8e7da22013-01-10 11:19:14 +05301429static struct std_mono_table ebox44_table[] = {
Mark Hills989b0132012-06-09 13:16:39 +01001430 {
1431 .unitid = 4,
1432 .control = 1,
1433 .cmask = 0x0,
1434 .val_type = USB_MIXER_INV_BOOLEAN,
1435 .name = "Headphone Playback Switch"
1436 },
1437 {
1438 .unitid = 4,
1439 .control = 2,
1440 .cmask = 0x1,
1441 .val_type = USB_MIXER_S16,
1442 .name = "Headphone A Mix Playback Volume"
1443 },
1444 {
1445 .unitid = 4,
1446 .control = 2,
1447 .cmask = 0x2,
1448 .val_type = USB_MIXER_S16,
1449 .name = "Headphone B Mix Playback Volume"
1450 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001451
Mark Hills989b0132012-06-09 13:16:39 +01001452 {
1453 .unitid = 7,
1454 .control = 1,
1455 .cmask = 0x0,
1456 .val_type = USB_MIXER_INV_BOOLEAN,
1457 .name = "Output Playback Switch"
1458 },
1459 {
1460 .unitid = 7,
1461 .control = 2,
1462 .cmask = 0x1,
1463 .val_type = USB_MIXER_S16,
1464 .name = "Output A Playback Volume"
1465 },
1466 {
1467 .unitid = 7,
1468 .control = 2,
1469 .cmask = 0x2,
1470 .val_type = USB_MIXER_S16,
1471 .name = "Output B Playback Volume"
1472 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001473
Mark Hills989b0132012-06-09 13:16:39 +01001474 {
1475 .unitid = 10,
1476 .control = 1,
1477 .cmask = 0x0,
1478 .val_type = USB_MIXER_INV_BOOLEAN,
1479 .name = "Input Capture Switch"
1480 },
1481 {
1482 .unitid = 10,
1483 .control = 2,
1484 .cmask = 0x1,
1485 .val_type = USB_MIXER_S16,
1486 .name = "Input A Capture Volume"
1487 },
1488 {
1489 .unitid = 10,
1490 .control = 2,
1491 .cmask = 0x2,
1492 .val_type = USB_MIXER_S16,
1493 .name = "Input B Capture Volume"
1494 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001495
Mark Hills989b0132012-06-09 13:16:39 +01001496 {}
Mark Hillsb71dad182012-06-09 13:16:38 +01001497};
1498
Przemek Rudy066624c2013-06-27 23:52:33 +02001499/* Audio Advantage Micro II findings:
1500 *
1501 * Mapping spdif AES bits to vendor register.bit:
1502 * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
1503 * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
1504 * AES2: [0 0 0 0 0 0 0 0]
1505 * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
1506 * (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
1507 *
1508 * power on values:
1509 * r2: 0x10
1510 * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
1511 * just after it to 0xa0, presumably it disables/mutes some analog
1512 * parts when there is no audio.)
1513 * r9: 0x28
1514 *
1515 * Optical transmitter on/off:
1516 * vendor register.bit: 9.1
1517 * 0 - on (0x28 register value)
1518 * 1 - off (0x2a register value)
1519 *
1520 */
1521static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
1522 struct snd_ctl_elem_info *uinfo)
1523{
1524 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1525 uinfo->count = 1;
1526 return 0;
1527}
1528
1529static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
1530 struct snd_ctl_elem_value *ucontrol)
1531{
1532 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1533 int err;
1534 struct usb_interface *iface;
1535 struct usb_host_interface *alts;
1536 unsigned int ep;
1537 unsigned char data[3];
1538 int rate;
1539
1540 ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
1541 ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
1542 ucontrol->value.iec958.status[2] = 0x00;
1543
1544 /* use known values for that card: interface#1 altsetting#1 */
1545 iface = usb_ifnum_to_if(mixer->chip->dev, 1);
1546 alts = &iface->altsetting[1];
1547 ep = get_endpoint(alts, 0)->bEndpointAddress;
1548
1549 err = snd_usb_ctl_msg(mixer->chip->dev,
1550 usb_rcvctrlpipe(mixer->chip->dev, 0),
1551 UAC_GET_CUR,
1552 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
1553 UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
1554 ep,
1555 data,
1556 sizeof(data));
1557 if (err < 0)
1558 goto end;
1559
1560 rate = data[0] | (data[1] << 8) | (data[2] << 16);
1561 ucontrol->value.iec958.status[3] = (rate == 48000) ?
1562 IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
1563
1564 err = 0;
1565end:
1566 return err;
1567}
1568
1569static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
1570 struct snd_ctl_elem_value *ucontrol)
1571{
1572 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1573 int err;
1574 u8 reg;
1575 unsigned long priv_backup = kcontrol->private_value;
1576
1577 reg = ((ucontrol->value.iec958.status[1] & 0x0f) << 4) |
1578 (ucontrol->value.iec958.status[0] & 0x0f);
1579 err = snd_usb_ctl_msg(mixer->chip->dev,
1580 usb_sndctrlpipe(mixer->chip->dev, 0),
1581 UAC_SET_CUR,
1582 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1583 reg,
1584 2,
1585 NULL,
1586 0);
1587 if (err < 0)
1588 goto end;
1589
1590 kcontrol->private_value &= 0xfffff0f0;
1591 kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0x0f) << 8;
1592 kcontrol->private_value |= (ucontrol->value.iec958.status[0] & 0x0f);
1593
1594 reg = (ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO) ?
1595 0xa0 : 0x20;
1596 reg |= (ucontrol->value.iec958.status[1] >> 4) & 0x0f;
1597 err = snd_usb_ctl_msg(mixer->chip->dev,
1598 usb_sndctrlpipe(mixer->chip->dev, 0),
1599 UAC_SET_CUR,
1600 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1601 reg,
1602 3,
1603 NULL,
1604 0);
1605 if (err < 0)
1606 goto end;
1607
1608 kcontrol->private_value &= 0xffff0fff;
1609 kcontrol->private_value |= (ucontrol->value.iec958.status[1] & 0xf0) << 8;
1610
1611 /* The frequency bits in AES3 cannot be set via register access. */
1612
1613 /* Silently ignore any bits from the request that cannot be set. */
1614
1615 err = (priv_backup != kcontrol->private_value);
1616end:
1617 return err;
1618}
1619
1620static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
1621 struct snd_ctl_elem_value *ucontrol)
1622{
1623 ucontrol->value.iec958.status[0] = 0x0f;
1624 ucontrol->value.iec958.status[1] = 0xff;
1625 ucontrol->value.iec958.status[2] = 0x00;
1626 ucontrol->value.iec958.status[3] = 0x00;
1627
1628 return 0;
1629}
1630
1631static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
1632 struct snd_ctl_elem_value *ucontrol)
1633{
1634 ucontrol->value.integer.value[0] = !(kcontrol->private_value & 0x02);
1635
1636 return 0;
1637}
1638
1639static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
1640 struct snd_ctl_elem_value *ucontrol)
1641{
1642 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1643 int err;
1644 u8 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a;
1645
1646 err = snd_usb_ctl_msg(mixer->chip->dev,
1647 usb_sndctrlpipe(mixer->chip->dev, 0),
1648 UAC_SET_CUR,
1649 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1650 reg,
1651 9,
1652 NULL,
1653 0);
1654
1655 if (!err) {
1656 err = (reg != (kcontrol->private_value & 0x0ff));
1657 if (err)
1658 kcontrol->private_value = reg;
1659 }
1660
1661 return err;
1662}
1663
1664static struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
1665 {
1666 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1667 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1668 .info = snd_microii_spdif_info,
1669 .get = snd_microii_spdif_default_get,
1670 .put = snd_microii_spdif_default_put,
1671 .private_value = 0x00000100UL,/* reset value */
1672 },
1673 {
1674 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1675 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1676 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
1677 .info = snd_microii_spdif_info,
1678 .get = snd_microii_spdif_mask_get,
1679 },
1680 {
1681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1682 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
1683 .info = snd_ctl_boolean_mono_info,
1684 .get = snd_microii_spdif_switch_get,
1685 .put = snd_microii_spdif_switch_put,
1686 .private_value = 0x00000028UL,/* reset value */
1687 }
1688};
1689
1690static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
1691{
1692 int err, i;
1693
1694 for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) {
1695 err = snd_ctl_add(mixer->chip->card,
1696 snd_ctl_new1(&snd_microii_mixer_spdif[i], mixer));
1697 if (err < 0)
1698 return err;
1699 }
1700
Mikulas Patocka18e47532013-12-05 14:32:43 -05001701 return 0;
Przemek Rudy066624c2013-06-27 23:52:33 +02001702}
1703
Daniel Mack7b1eda22010-03-11 21:13:22 +01001704int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1705{
Daniel Mack3347b262011-02-11 11:34:12 +00001706 int err = 0;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001707 struct snd_info_entry *entry;
1708
1709 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
1710 return err;
1711
Daniel Mack3347b262011-02-11 11:34:12 +00001712 switch (mixer->chip->usb_id) {
1713 case USB_ID(0x041e, 0x3020):
1714 case USB_ID(0x041e, 0x3040):
1715 case USB_ID(0x041e, 0x3042):
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +02001716 case USB_ID(0x041e, 0x30df):
Daniel Mack3347b262011-02-11 11:34:12 +00001717 case USB_ID(0x041e, 0x3048):
1718 err = snd_audigy2nx_controls_create(mixer);
1719 if (err < 0)
1720 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001721 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
1722 snd_info_set_text_ops(entry, mixer,
1723 snd_audigy2nx_proc_read);
Daniel Mack3347b262011-02-11 11:34:12 +00001724 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001725
Vasily Khoruzhick44832a72013-11-13 13:13:35 +03001726 /* EMU0204 */
1727 case USB_ID(0x041e, 0x3f19):
1728 err = snd_emu0204_controls_create(mixer);
1729 if (err < 0)
1730 break;
1731 break;
1732
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001733 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
Matt Gruskine9a25e02013-02-09 12:56:35 -05001734 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001735 err = snd_c400_create_mixer(mixer);
1736 break;
1737
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001738 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
1739 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
Felix Homanncfe8f972012-04-23 20:24:26 +02001740 err = snd_ftu_create_mixer(mixer);
Daniel Mackd5a0bf62011-05-25 09:09:03 +02001741 break;
1742
Denis Washington1d31aff2012-12-11 11:38:32 +01001743 case USB_ID(0x0b05, 0x1739): /* ASUS Xonar U1 */
1744 case USB_ID(0x0b05, 0x1743): /* ASUS Xonar U1 (2) */
1745 case USB_ID(0x0b05, 0x17a0): /* ASUS Xonar U3 */
Daniel Mack7b1eda22010-03-11 21:13:22 +01001746 err = snd_xonar_u1_controls_create(mixer);
Daniel Mack3347b262011-02-11 11:34:12 +00001747 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001748
Przemek Rudy066624c2013-06-27 23:52:33 +02001749 case USB_ID(0x0d8c, 0x0103): /* Audio Advantage Micro II */
1750 err = snd_microii_controls_create(mixer);
1751 break;
1752
Damien Zammitd497a822014-11-12 01:09:54 +11001753 case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */
1754 err = snd_mbox1_create_sync_switch(mixer);
1755 break;
1756
Daniel Mack3347b262011-02-11 11:34:12 +00001757 case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
Daniel Mack54a8c502011-02-11 11:08:06 +00001758 err = snd_nativeinstruments_create_mixer(mixer,
1759 snd_nativeinstruments_ta6_mixers,
1760 ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
Daniel Mack3347b262011-02-11 11:34:12 +00001761 break;
Daniel Mack54a8c502011-02-11 11:08:06 +00001762
Daniel Mack3347b262011-02-11 11:34:12 +00001763 case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
Daniel Mack54a8c502011-02-11 11:08:06 +00001764 err = snd_nativeinstruments_create_mixer(mixer,
1765 snd_nativeinstruments_ta10_mixers,
1766 ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
Daniel Mack3347b262011-02-11 11:34:12 +00001767 break;
Mark Hills7536c302012-04-14 17:19:24 +01001768
1769 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
Mark Hillsb71dad182012-06-09 13:16:38 +01001770 /* detection is disabled in mixer_maps.c */
1771 err = snd_create_std_mono_table(mixer, ebox44_table);
Mark Hills7536c302012-04-14 17:19:24 +01001772 break;
Daniel Mack54a8c502011-02-11 11:08:06 +00001773 }
1774
Daniel Mack3347b262011-02-11 11:34:12 +00001775 return err;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001776}
1777
1778void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
1779 int unitid)
1780{
1781 if (!mixer->rc_cfg)
1782 return;
1783 /* unit ids specific to Extigy/Audigy 2 NX: */
1784 switch (unitid) {
1785 case 0: /* remote control */
1786 mixer->rc_urb->dev = mixer->chip->dev;
1787 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
1788 break;
1789 case 4: /* digital in jack */
1790 case 7: /* line in jacks */
1791 case 19: /* speaker out jacks */
1792 case 20: /* headphones out jack */
1793 break;
1794 /* live24ext: 4 = line-in jack */
1795 case 3: /* hp-out jack (may actuate Mute) */
1796 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1797 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1798 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1799 break;
1800 default:
Takashi Iwai0ba41d92014-02-26 13:02:17 +01001801 usb_audio_dbg(mixer->chip, "memory change in unknown unit %d\n", unitid);
Daniel Mack7b1eda22010-03-11 21:13:22 +01001802 break;
1803 }
1804}
1805