blob: f6c3bf79af9a7d9f7cabe6b83c3573a59964b826 [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>
Anssi Hannula42e31212015-12-13 20:49:58 +020040#include <sound/tlv.h>
Daniel Mack7b1eda22010-03-11 21:13:22 +010041
42#include "usbaudio.h"
Daniel Mackf0b5e632010-03-11 21:13:23 +010043#include "mixer.h"
Daniel Mack7b1eda22010-03-11 21:13:22 +010044#include "mixer_quirks.h"
Chris J Arges76b188c2014-11-12 12:07:02 -060045#include "mixer_scarlett.h"
Daniel Mack7b1eda22010-03-11 21:13:22 +010046#include "helper.h"
47
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +020048extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
49
Mark Hillsb71dad182012-06-09 13:16:38 +010050struct std_mono_table {
51 unsigned int unitid, control, cmask;
52 int val_type;
53 const char *name;
54 snd_kcontrol_tlv_rw_t *tlv_callback;
55};
56
Felix Homann8a4d1d32012-04-23 20:24:23 +020057/* This function allows for the creation of standard UAC controls.
58 * See the quirks for M-Audio FTUs or Ebox-44.
59 * If you don't want to set a TLV callback pass NULL.
60 *
61 * Since there doesn't seem to be a devices that needs a multichannel
62 * version, we keep it mono for simplicity.
63 */
Eldad Zack9f814102012-11-28 23:55:35 +010064static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
Felix Homann8a4d1d32012-04-23 20:24:23 +020065 unsigned int unitid,
66 unsigned int control,
67 unsigned int cmask,
68 int val_type,
Eldad Zack9f814102012-11-28 23:55:35 +010069 unsigned int idx_off,
Felix Homann8a4d1d32012-04-23 20:24:23 +020070 const char *name,
71 snd_kcontrol_tlv_rw_t *tlv_callback)
72{
Felix Homann8a4d1d32012-04-23 20:24:23 +020073 struct usb_mixer_elem_info *cval;
74 struct snd_kcontrol *kctl;
75
76 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
77 if (!cval)
78 return -ENOMEM;
79
Takashi Iwai3360b842014-11-18 11:47:04 +010080 snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid);
Felix Homann8a4d1d32012-04-23 20:24:23 +020081 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 */
Takashi Iwai3360b842014-11-18 11:47:04 +0100114 return snd_usb_mixer_add_control(&cval->head, kctl);
Felix Homann8a4d1d32012-04-23 20:24:23 +0200115}
116
Eldad Zack9f814102012-11-28 23:55:35 +0100117static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
118 unsigned int unitid,
119 unsigned int control,
120 unsigned int cmask,
121 int val_type,
122 const char *name,
123 snd_kcontrol_tlv_rw_t *tlv_callback)
124{
125 return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask,
126 val_type, 0 /* Offset */, name, tlv_callback);
127}
128
Daniel Mack7b1eda22010-03-11 21:13:22 +0100129/*
Mark Hillsb71dad182012-06-09 13:16:38 +0100130 * Create a set of standard UAC controls from a table
131 */
132static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
133 struct std_mono_table *t)
134{
135 int err;
136
137 while (t->name != NULL) {
138 err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
139 t->cmask, t->val_type, t->name, t->tlv_callback);
140 if (err < 0)
141 return err;
142 t++;
143 }
144
145 return 0;
146}
147
Takashi Iwai9cf36892014-11-18 12:58:51 +0100148static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
149 int id,
150 usb_mixer_elem_resume_func_t resume,
151 const struct snd_kcontrol_new *knew,
152 struct usb_mixer_elem_list **listp)
153{
154 struct usb_mixer_elem_list *list;
155 struct snd_kcontrol *kctl;
156
157 list = kzalloc(sizeof(*list), GFP_KERNEL);
158 if (!list)
159 return -ENOMEM;
160 if (listp)
161 *listp = list;
162 list->mixer = mixer;
163 list->id = id;
164 list->resume = resume;
165 kctl = snd_ctl_new1(knew, list);
166 if (!kctl) {
167 kfree(list);
168 return -ENOMEM;
169 }
170 kctl->private_free = snd_usb_mixer_elem_free;
171 return snd_usb_mixer_add_control(list, kctl);
172}
173
Mark Hillsb71dad182012-06-09 13:16:38 +0100174/*
Daniel Mack7b1eda22010-03-11 21:13:22 +0100175 * Sound Blaster remote control configuration
176 *
177 * format of remote control data:
178 * Extigy: xx 00
179 * Audigy 2 NX: 06 80 xx 00 00 00
180 * Live! 24-bit: 06 80 xx yy 22 83
181 */
182static const struct rc_config {
183 u32 usb_id;
184 u8 offset;
185 u8 length;
186 u8 packet_length;
187 u8 min_packet_length; /* minimum accepted length of the URB result */
188 u8 mute_mixer_id;
189 u32 mute_code;
190} rc_configs[] = {
191 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
192 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
193 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
Mandar Joshica8dc342010-11-02 14:43:19 +0000194 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200195 { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
Dmitry M. Fedin3dc85232015-04-09 17:37:03 +0300196 { USB_ID(0x041e, 0x3237), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
Daniel Mack7b1eda22010-03-11 21:13:22 +0100197 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
198};
199
200static void snd_usb_soundblaster_remote_complete(struct urb *urb)
201{
202 struct usb_mixer_interface *mixer = urb->context;
203 const struct rc_config *rc = mixer->rc_cfg;
204 u32 code;
205
206 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
207 return;
208
209 code = mixer->rc_buffer[rc->offset];
210 if (rc->length == 2)
211 code |= mixer->rc_buffer[rc->offset + 1] << 8;
212
213 /* the Mute button actually changes the mixer control */
214 if (code == rc->mute_code)
215 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
216 mixer->rc_code = code;
217 wmb();
218 wake_up(&mixer->rc_waitq);
219}
220
221static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
222 long count, loff_t *offset)
223{
224 struct usb_mixer_interface *mixer = hw->private_data;
225 int err;
226 u32 rc_code;
227
228 if (count != 1 && count != 4)
229 return -EINVAL;
230 err = wait_event_interruptible(mixer->rc_waitq,
231 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
232 if (err == 0) {
233 if (count == 1)
234 err = put_user(rc_code, buf);
235 else
236 err = put_user(rc_code, (u32 __user *)buf);
237 }
238 return err < 0 ? err : count;
239}
240
241static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
242 poll_table *wait)
243{
244 struct usb_mixer_interface *mixer = hw->private_data;
245
246 poll_wait(file, &mixer->rc_waitq, wait);
247 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
248}
249
250static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
251{
252 struct snd_hwdep *hwdep;
253 int err, len, i;
254
255 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
256 if (rc_configs[i].usb_id == mixer->chip->usb_id)
257 break;
258 if (i >= ARRAY_SIZE(rc_configs))
259 return 0;
260 mixer->rc_cfg = &rc_configs[i];
261
262 len = mixer->rc_cfg->packet_length;
263
264 init_waitqueue_head(&mixer->rc_waitq);
265 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
266 if (err < 0)
267 return err;
268 snprintf(hwdep->name, sizeof(hwdep->name),
269 "%s remote control", mixer->chip->card->shortname);
270 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
271 hwdep->private_data = mixer;
272 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
273 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
274 hwdep->exclusive = 1;
275
276 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
277 if (!mixer->rc_urb)
278 return -ENOMEM;
279 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
280 if (!mixer->rc_setup_packet) {
281 usb_free_urb(mixer->rc_urb);
282 mixer->rc_urb = NULL;
283 return -ENOMEM;
284 }
285 mixer->rc_setup_packet->bRequestType =
286 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
287 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
288 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
289 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
290 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
291 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
292 usb_rcvctrlpipe(mixer->chip->dev, 0),
293 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
294 snd_usb_soundblaster_remote_complete, mixer);
295 return 0;
296}
297
298#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
299
300static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
301{
Takashi Iwai9cf36892014-11-18 12:58:51 +0100302 ucontrol->value.integer.value[0] = kcontrol->private_value >> 8;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100303 return 0;
304}
305
Takashi Iwai9cf36892014-11-18 12:58:51 +0100306static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
307 int value, int index)
Daniel Mack7b1eda22010-03-11 21:13:22 +0100308{
Takashi Iwai9cf36892014-11-18 12:58:51 +0100309 struct snd_usb_audio *chip = mixer->chip;
310 int err;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100311
Takashi Iwai47ab1542015-08-25 16:09:00 +0200312 err = snd_usb_lock_shutdown(chip);
313 if (err < 0)
314 return err;
315
Takashi Iwai9cf36892014-11-18 12:58:51 +0100316 if (chip->usb_id == USB_ID(0x041e, 0x3042))
317 err = snd_usb_ctl_msg(chip->dev,
318 usb_sndctrlpipe(chip->dev, 0), 0x24,
Mandar Joshica8dc342010-11-02 14:43:19 +0000319 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200320 !value, 0, NULL, 0);
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200321 /* USB X-Fi S51 Pro */
Takashi Iwai9cf36892014-11-18 12:58:51 +0100322 if (chip->usb_id == USB_ID(0x041e, 0x30df))
323 err = snd_usb_ctl_msg(chip->dev,
324 usb_sndctrlpipe(chip->dev, 0), 0x24,
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200325 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200326 !value, 0, NULL, 0);
Mandar Joshica8dc342010-11-02 14:43:19 +0000327 else
Takashi Iwai9cf36892014-11-18 12:58:51 +0100328 err = snd_usb_ctl_msg(chip->dev,
329 usb_sndctrlpipe(chip->dev, 0), 0x24,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100330 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200331 value, index + 2, NULL, 0);
Takashi Iwai47ab1542015-08-25 16:09:00 +0200332 snd_usb_unlock_shutdown(chip);
Takashi Iwai9cf36892014-11-18 12:58:51 +0100333 return err;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100334}
335
Takashi Iwai9cf36892014-11-18 12:58:51 +0100336static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
338{
339 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
340 struct usb_mixer_interface *mixer = list->mixer;
341 int index = kcontrol->private_value & 0xff;
Dan Carpentere87359e2015-09-28 13:06:20 +0300342 unsigned int value = ucontrol->value.integer.value[0];
Takashi Iwai9cf36892014-11-18 12:58:51 +0100343 int old_value = kcontrol->private_value >> 8;
344 int err;
345
346 if (value > 1)
347 return -EINVAL;
348 if (value == old_value)
349 return 0;
350 kcontrol->private_value = (value << 8) | index;
351 err = snd_audigy2nx_led_update(mixer, value, index);
352 return err < 0 ? err : 1;
353}
354
355static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
356{
357 int priv_value = list->kctl->private_value;
358
359 return snd_audigy2nx_led_update(list->mixer, priv_value >> 8,
360 priv_value & 0xff);
361}
362
363/* name and private_value are set dynamically */
364static struct snd_kcontrol_new snd_audigy2nx_control = {
365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
366 .info = snd_audigy2nx_led_info,
367 .get = snd_audigy2nx_led_get,
368 .put = snd_audigy2nx_led_put,
369};
370
371static const char * const snd_audigy2nx_led_names[] = {
372 "CMSS LED Switch",
373 "Power LED Switch",
374 "Dolby Digital LED Switch",
Daniel Mack7b1eda22010-03-11 21:13:22 +0100375};
376
377static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
378{
379 int i, err;
380
Takashi Iwai9cf36892014-11-18 12:58:51 +0100381 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_led_names); ++i) {
382 struct snd_kcontrol_new knew;
383
Mandar Joshica8dc342010-11-02 14:43:19 +0000384 /* USB X-Fi S51 doesn't have a CMSS LED */
385 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
386 continue;
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200387 /* USB X-Fi S51 Pro doesn't have one either */
388 if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
389 continue;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100390 if (i > 1 && /* Live24ext has 2 LEDs only */
391 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
Mandar Joshica8dc342010-11-02 14:43:19 +0000392 mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +0200393 mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
Daniel Mack7b1eda22010-03-11 21:13:22 +0100394 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
395 break;
Takashi Iwai9cf36892014-11-18 12:58:51 +0100396
397 knew = snd_audigy2nx_control;
398 knew.name = snd_audigy2nx_led_names[i];
399 knew.private_value = (1 << 8) | i; /* LED on as default */
400 err = add_single_ctl_with_resume(mixer, 0,
401 snd_audigy2nx_led_resume,
402 &knew, NULL);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100403 if (err < 0)
404 return err;
405 }
Daniel Mack7b1eda22010-03-11 21:13:22 +0100406 return 0;
407}
408
409static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
410 struct snd_info_buffer *buffer)
411{
412 static const struct sb_jack {
413 int unitid;
414 const char *name;
415 } jacks_audigy2nx[] = {
416 {4, "dig in "},
417 {7, "line in"},
418 {19, "spk out"},
419 {20, "hph out"},
420 {-1, NULL}
421 }, jacks_live24ext[] = {
422 {4, "line in"}, /* &1=Line, &2=Mic*/
423 {3, "hph out"}, /* headphones */
424 {0, "RC "}, /* last command, 6 bytes see rc_config above */
425 {-1, NULL}
426 };
427 const struct sb_jack *jacks;
428 struct usb_mixer_interface *mixer = entry->private_data;
429 int i, err;
430 u8 buf[3];
431
432 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
433 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
434 jacks = jacks_audigy2nx;
435 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
436 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
437 jacks = jacks_live24ext;
438 else
439 return;
440
441 for (i = 0; jacks[i].name; ++i) {
442 snd_iprintf(buffer, "%s: ", jacks[i].name);
Takashi Iwai47ab1542015-08-25 16:09:00 +0200443 err = snd_usb_lock_shutdown(mixer->chip);
444 if (err < 0)
445 return;
446 err = snd_usb_ctl_msg(mixer->chip->dev,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100447 usb_rcvctrlpipe(mixer->chip->dev, 0),
448 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
449 USB_RECIP_INTERFACE, 0,
Clemens Ladisch17d900c2011-09-26 21:15:27 +0200450 jacks[i].unitid << 8, buf, 3);
Takashi Iwai47ab1542015-08-25 16:09:00 +0200451 snd_usb_unlock_shutdown(mixer->chip);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100452 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
453 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
454 else
455 snd_iprintf(buffer, "?\n");
456 }
457}
458
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300459/* EMU0204 */
460static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol,
461 struct snd_ctl_elem_info *uinfo)
462{
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200463 static const char * const texts[2] = {"1/2", "3/4"};
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300464
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200465 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300466}
467
468static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
470{
471 ucontrol->value.enumerated.item[0] = kcontrol->private_value;
472 return 0;
473}
474
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100475static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
476 int value)
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300477{
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100478 struct snd_usb_audio *chip = mixer->chip;
479 int err;
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300480 unsigned char buf[2];
481
Takashi Iwai47ab1542015-08-25 16:09:00 +0200482 err = snd_usb_lock_shutdown(chip);
483 if (err < 0)
484 return err;
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100485
486 buf[0] = 0x01;
487 buf[1] = value ? 0x02 : 0x01;
488 err = snd_usb_ctl_msg(chip->dev,
489 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300490 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
491 0x0400, 0x0e00, buf, 2);
Takashi Iwai47ab1542015-08-25 16:09:00 +0200492 snd_usb_unlock_shutdown(chip);
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100493 return err;
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300494}
495
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100496static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
500 struct usb_mixer_interface *mixer = list->mixer;
501 unsigned int value = ucontrol->value.enumerated.item[0];
502 int err;
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300503
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100504 if (value > 1)
505 return -EINVAL;
506
507 if (value == kcontrol->private_value)
508 return 0;
509
510 kcontrol->private_value = value;
511 err = snd_emu0204_ch_switch_update(mixer, value);
512 return err < 0 ? err : 1;
513}
514
515static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
516{
517 return snd_emu0204_ch_switch_update(list->mixer,
518 list->kctl->private_value);
519}
520
521static struct snd_kcontrol_new snd_emu0204_control = {
522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
523 .name = "Front Jack Channels",
524 .info = snd_emu0204_ch_switch_info,
525 .get = snd_emu0204_ch_switch_get,
526 .put = snd_emu0204_ch_switch_put,
527 .private_value = 0,
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300528};
529
530static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
531{
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100532 return add_single_ctl_with_resume(mixer, 0,
533 snd_emu0204_ch_switch_resume,
534 &snd_emu0204_control, NULL);
Vasily Khoruzhick44832a72013-11-13 13:13:35 +0300535}
Takashi Iwai5f503ee2014-11-18 16:11:37 +0100536
Denis Washington1d31aff2012-12-11 11:38:32 +0100537/* ASUS Xonar U1 / U3 controls */
538
Daniel Mack7b1eda22010-03-11 21:13:22 +0100539static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
540 struct snd_ctl_elem_value *ucontrol)
541{
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100542 ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100543 return 0;
544}
545
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100546static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
547 unsigned char status)
548{
549 struct snd_usb_audio *chip = mixer->chip;
550 int err;
551
Takashi Iwai47ab1542015-08-25 16:09:00 +0200552 err = snd_usb_lock_shutdown(chip);
553 if (err < 0)
554 return err;
555 err = snd_usb_ctl_msg(chip->dev,
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100556 usb_sndctrlpipe(chip->dev, 0), 0x08,
557 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
558 50, 0, &status, 1);
Takashi Iwai47ab1542015-08-25 16:09:00 +0200559 snd_usb_unlock_shutdown(chip);
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100560 return err;
561}
562
Daniel Mack7b1eda22010-03-11 21:13:22 +0100563static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
565{
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100566 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100567 u8 old_status, new_status;
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100568 int err;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100569
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100570 old_status = kcontrol->private_value;
Daniel Mack7b1eda22010-03-11 21:13:22 +0100571 if (ucontrol->value.integer.value[0])
572 new_status = old_status | 0x02;
573 else
574 new_status = old_status & ~0x02;
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100575 if (new_status == old_status)
576 return 0;
577
578 kcontrol->private_value = new_status;
579 err = snd_xonar_u1_switch_update(list->mixer, new_status);
580 return err < 0 ? err : 1;
581}
582
583static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
584{
585 return snd_xonar_u1_switch_update(list->mixer,
586 list->kctl->private_value);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100587}
588
589static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
590 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
591 .name = "Digital Playback Switch",
592 .info = snd_ctl_boolean_mono_info,
593 .get = snd_xonar_u1_switch_get,
594 .put = snd_xonar_u1_switch_put,
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100595 .private_value = 0x05,
Daniel Mack7b1eda22010-03-11 21:13:22 +0100596};
597
598static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
599{
Takashi Iwai2bfb14c2014-11-18 16:18:15 +0100600 return add_single_ctl_with_resume(mixer, 0,
601 snd_xonar_u1_switch_resume,
602 &snd_xonar_u1_output_switch, NULL);
Daniel Mack7b1eda22010-03-11 21:13:22 +0100603}
604
Damien Zammitd497a822014-11-12 01:09:54 +1100605/* Digidesign Mbox 1 clock source switch (internal/spdif) */
606
607static int snd_mbox1_switch_get(struct snd_kcontrol *kctl,
608 struct snd_ctl_elem_value *ucontrol)
609{
610 ucontrol->value.enumerated.item[0] = kctl->private_value;
611 return 0;
612}
613
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100614static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
Damien Zammitd497a822014-11-12 01:09:54 +1100615{
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100616 struct snd_usb_audio *chip = mixer->chip;
Damien Zammitd497a822014-11-12 01:09:54 +1100617 int err;
Damien Zammitd497a822014-11-12 01:09:54 +1100618 unsigned char buff[3];
619
Takashi Iwai47ab1542015-08-25 16:09:00 +0200620 err = snd_usb_lock_shutdown(chip);
621 if (err < 0)
622 return err;
Damien Zammitd497a822014-11-12 01:09:54 +1100623
624 /* Prepare for magic command to toggle clock source */
625 err = snd_usb_ctl_msg(chip->dev,
626 usb_rcvctrlpipe(chip->dev, 0), 0x81,
627 USB_DIR_IN |
628 USB_TYPE_CLASS |
629 USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1);
630 if (err < 0)
631 goto err;
632 err = snd_usb_ctl_msg(chip->dev,
633 usb_rcvctrlpipe(chip->dev, 0), 0x81,
634 USB_DIR_IN |
635 USB_TYPE_CLASS |
636 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
637 if (err < 0)
638 goto err;
639
640 /* 2 possibilities: Internal -> send sample rate
641 * S/PDIF sync -> send zeroes
642 * NB: Sample rate locked to 48kHz on purpose to
643 * prevent user from resetting the sample rate
644 * while S/PDIF sync is enabled and confusing
645 * this configuration.
646 */
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100647 if (val == 0) {
Damien Zammitd497a822014-11-12 01:09:54 +1100648 buff[0] = 0x80;
649 buff[1] = 0xbb;
650 buff[2] = 0x00;
651 } else {
652 buff[0] = buff[1] = buff[2] = 0x00;
653 }
654
655 /* Send the magic command to toggle the clock source */
656 err = snd_usb_ctl_msg(chip->dev,
657 usb_sndctrlpipe(chip->dev, 0), 0x1,
658 USB_TYPE_CLASS |
659 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
660 if (err < 0)
661 goto err;
662 err = snd_usb_ctl_msg(chip->dev,
663 usb_rcvctrlpipe(chip->dev, 0), 0x81,
664 USB_DIR_IN |
665 USB_TYPE_CLASS |
666 USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
667 if (err < 0)
668 goto err;
669 err = snd_usb_ctl_msg(chip->dev,
670 usb_rcvctrlpipe(chip->dev, 0), 0x81,
671 USB_DIR_IN |
672 USB_TYPE_CLASS |
673 USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3);
674 if (err < 0)
675 goto err;
Damien Zammitd497a822014-11-12 01:09:54 +1100676
677err:
Takashi Iwai47ab1542015-08-25 16:09:00 +0200678 snd_usb_unlock_shutdown(chip);
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100679 return err;
680}
681
682static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
683 struct snd_ctl_elem_value *ucontrol)
684{
685 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
686 struct usb_mixer_interface *mixer = list->mixer;
687 int err;
688 bool cur_val, new_val;
689
690 cur_val = kctl->private_value;
691 new_val = ucontrol->value.enumerated.item[0];
692 if (cur_val == new_val)
693 return 0;
694
695 kctl->private_value = new_val;
696 err = snd_mbox1_switch_update(mixer, new_val);
Damien Zammitd497a822014-11-12 01:09:54 +1100697 return err < 0 ? err : 1;
698}
699
700static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol,
701 struct snd_ctl_elem_info *uinfo)
702{
703 static const char *const texts[2] = {
704 "Internal",
705 "S/PDIF"
706 };
707
708 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
709}
710
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100711static int snd_mbox1_switch_resume(struct usb_mixer_elem_list *list)
712{
713 return snd_mbox1_switch_update(list->mixer, list->kctl->private_value);
714}
715
Damien Zammitd497a822014-11-12 01:09:54 +1100716static struct snd_kcontrol_new snd_mbox1_switch = {
717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
718 .name = "Clock Source",
719 .index = 0,
720 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
721 .info = snd_mbox1_switch_info,
722 .get = snd_mbox1_switch_get,
723 .put = snd_mbox1_switch_put,
724 .private_value = 0
725};
726
727static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
728{
Takashi Iwai25a9a4f2014-11-18 16:31:35 +0100729 return add_single_ctl_with_resume(mixer, 0,
730 snd_mbox1_switch_resume,
731 &snd_mbox1_switch, NULL);
Damien Zammitd497a822014-11-12 01:09:54 +1100732}
733
Daniel Mack54a8c502011-02-11 11:08:06 +0000734/* Native Instruments device quirks */
735
736#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
737
Takashi Iwaida6d2762014-11-18 16:59:47 +0100738static int snd_ni_control_init_val(struct usb_mixer_interface *mixer,
739 struct snd_kcontrol *kctl)
740{
741 struct usb_device *dev = mixer->chip->dev;
742 unsigned int pval = kctl->private_value;
743 u8 value;
744 int err;
745
746 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
747 (pval >> 16) & 0xff,
748 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
749 0, pval & 0xffff, &value, 1);
750 if (err < 0) {
751 dev_err(&dev->dev,
752 "unable to issue vendor read request (ret = %d)", err);
753 return err;
754 }
755
756 kctl->private_value |= (value << 24);
757 return 0;
758}
759
Daniel Mack54a8c502011-02-11 11:08:06 +0000760static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
762{
Takashi Iwaida6d2762014-11-18 16:59:47 +0100763 ucontrol->value.integer.value[0] = kcontrol->private_value >> 24;
Daniel Mack54a8c502011-02-11 11:08:06 +0000764 return 0;
765}
766
Takashi Iwaida6d2762014-11-18 16:59:47 +0100767static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
768{
769 struct snd_usb_audio *chip = list->mixer->chip;
770 unsigned int pval = list->kctl->private_value;
771 int err;
772
Takashi Iwai47ab1542015-08-25 16:09:00 +0200773 err = snd_usb_lock_shutdown(chip);
774 if (err < 0)
775 return err;
776 err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
777 (pval >> 16) & 0xff,
778 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
779 pval >> 24, pval & 0xffff, NULL, 0, 1000);
780 snd_usb_unlock_shutdown(chip);
Takashi Iwaida6d2762014-11-18 16:59:47 +0100781 return err;
782}
783
Daniel Mack54a8c502011-02-11 11:08:06 +0000784static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
Takashi Iwaida6d2762014-11-18 16:59:47 +0100787 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
788 u8 oldval = (kcontrol->private_value >> 24) & 0xff;
789 u8 newval = ucontrol->value.integer.value[0];
790 int err;
Daniel Mack54a8c502011-02-11 11:08:06 +0000791
Takashi Iwaida6d2762014-11-18 16:59:47 +0100792 if (oldval == newval)
793 return 0;
Daniel Mack54a8c502011-02-11 11:08:06 +0000794
Takashi Iwaida6d2762014-11-18 16:59:47 +0100795 kcontrol->private_value &= ~(0xff << 24);
Takashi Iwaic4a359a2016-01-13 07:20:13 +0100796 kcontrol->private_value |= (unsigned int)newval << 24;
Takashi Iwaida6d2762014-11-18 16:59:47 +0100797 err = snd_ni_update_cur_val(list);
798 return err < 0 ? err : 1;
Daniel Mack54a8c502011-02-11 11:08:06 +0000799}
800
801static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
802 {
803 .name = "Direct Thru Channel A",
804 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
805 },
806 {
807 .name = "Direct Thru Channel B",
808 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
809 },
810 {
811 .name = "Phono Input Channel A",
812 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
813 },
814 {
815 .name = "Phono Input Channel B",
816 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
817 },
818};
819
820static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
821 {
822 .name = "Direct Thru Channel A",
823 .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
824 },
825 {
826 .name = "Direct Thru Channel B",
827 .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
828 },
829 {
830 .name = "Direct Thru Channel C",
831 .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
832 },
833 {
834 .name = "Direct Thru Channel D",
835 .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
836 },
837 {
838 .name = "Phono Input Channel A",
839 .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
840 },
841 {
842 .name = "Phono Input Channel B",
843 .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
844 },
845 {
846 .name = "Phono Input Channel C",
847 .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
848 },
849 {
850 .name = "Phono Input Channel D",
851 .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
852 },
853};
854
855static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
856 const struct snd_kcontrol_new *kc,
857 unsigned int count)
858{
859 int i, err = 0;
860 struct snd_kcontrol_new template = {
861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
862 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
863 .get = snd_nativeinstruments_control_get,
864 .put = snd_nativeinstruments_control_put,
865 .info = snd_ctl_boolean_mono_info,
866 };
867
868 for (i = 0; i < count; i++) {
Takashi Iwaida6d2762014-11-18 16:59:47 +0100869 struct usb_mixer_elem_list *list;
Daniel Mack54a8c502011-02-11 11:08:06 +0000870
871 template.name = kc[i].name;
872 template.private_value = kc[i].private_value;
873
Takashi Iwaida6d2762014-11-18 16:59:47 +0100874 err = add_single_ctl_with_resume(mixer, 0,
875 snd_ni_update_cur_val,
876 &template, &list);
Daniel Mack54a8c502011-02-11 11:08:06 +0000877 if (err < 0)
878 break;
Takashi Iwaida6d2762014-11-18 16:59:47 +0100879 snd_ni_control_init_val(mixer, list->kctl);
Daniel Mack54a8c502011-02-11 11:08:06 +0000880 }
881
882 return err;
883}
884
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +0200885/* M-Audio FastTrack Ultra quirks */
Matt Gruskine9a25e02013-02-09 12:56:35 -0500886/* FTU Effect switch (also used by C400/C600) */
Felix Homannd34bf142012-04-23 20:24:27 +0200887static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
888 struct snd_ctl_elem_info *uinfo)
889{
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200890 static const char *const texts[8] = {
891 "Room 1", "Room 2", "Room 3", "Hall 1",
892 "Hall 2", "Plate", "Delay", "Echo"
Felix Homannd34bf142012-04-23 20:24:27 +0200893 };
894
Takashi Iwai7bbd03e2014-10-20 18:21:42 +0200895 return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
Felix Homannd34bf142012-04-23 20:24:27 +0200896}
897
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100898static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer,
899 struct snd_kcontrol *kctl)
Felix Homannd34bf142012-04-23 20:24:27 +0200900{
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100901 struct usb_device *dev = mixer->chip->dev;
902 unsigned int pval = kctl->private_value;
Felix Homannd34bf142012-04-23 20:24:27 +0200903 int err;
904 unsigned char value[2];
Felix Homannd34bf142012-04-23 20:24:27 +0200905
906 value[0] = 0x00;
907 value[1] = 0x00;
908
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100909 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
910 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
911 pval & 0xff00,
912 snd_usb_ctrl_intf(mixer->chip) | ((pval & 0xff) << 8),
913 value, 2);
Felix Homannd34bf142012-04-23 20:24:27 +0200914 if (err < 0)
915 return err;
916
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100917 kctl->private_value |= value[0] << 24;
Felix Homannd34bf142012-04-23 20:24:27 +0200918 return 0;
919}
920
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100921static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
922 struct snd_ctl_elem_value *ucontrol)
923{
924 ucontrol->value.enumerated.item[0] = kctl->private_value >> 24;
925 return 0;
926}
927
928static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
929{
930 struct snd_usb_audio *chip = list->mixer->chip;
931 unsigned int pval = list->kctl->private_value;
932 unsigned char value[2];
933 int err;
934
935 value[0] = pval >> 24;
936 value[1] = 0;
937
Takashi Iwai47ab1542015-08-25 16:09:00 +0200938 err = snd_usb_lock_shutdown(chip);
939 if (err < 0)
940 return err;
941 err = snd_usb_ctl_msg(chip->dev,
942 usb_sndctrlpipe(chip->dev, 0),
943 UAC_SET_CUR,
944 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
945 pval & 0xff00,
946 snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
947 value, 2);
948 snd_usb_unlock_shutdown(chip);
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100949 return err;
950}
951
Felix Homannd34bf142012-04-23 20:24:27 +0200952static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
953 struct snd_ctl_elem_value *ucontrol)
954{
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100955 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
956 unsigned int pval = list->kctl->private_value;
957 int cur_val, err, new_val;
Felix Homannd34bf142012-04-23 20:24:27 +0200958
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100959 cur_val = pval >> 24;
Felix Homannd34bf142012-04-23 20:24:27 +0200960 new_val = ucontrol->value.enumerated.item[0];
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100961 if (cur_val == new_val)
962 return 0;
Felix Homannd34bf142012-04-23 20:24:27 +0200963
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100964 kctl->private_value &= ~(0xff << 24);
965 kctl->private_value |= new_val << 24;
966 err = snd_ftu_eff_switch_update(list);
967 return err < 0 ? err : 1;
Takashi Iwai1a290582014-11-11 15:45:57 +0100968}
969
Eldad Zackd847ce02012-11-28 23:55:37 +0100970static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
971 int validx, int bUnitID)
Felix Homannd34bf142012-04-23 20:24:27 +0200972{
973 static struct snd_kcontrol_new template = {
974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
975 .name = "Effect Program Switch",
976 .index = 0,
977 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
978 .info = snd_ftu_eff_switch_info,
979 .get = snd_ftu_eff_switch_get,
980 .put = snd_ftu_eff_switch_put
981 };
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100982 struct usb_mixer_elem_list *list;
Felix Homannd34bf142012-04-23 20:24:27 +0200983 int err;
Felix Homannd34bf142012-04-23 20:24:27 +0200984
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100985 err = add_single_ctl_with_resume(mixer, bUnitID,
986 snd_ftu_eff_switch_update,
987 &template, &list);
Felix Homannd34bf142012-04-23 20:24:27 +0200988 if (err < 0)
989 return err;
Takashi Iwai0b4e9cf2014-11-18 17:37:40 +0100990 list->kctl->private_value = (validx << 8) | bUnitID;
991 snd_ftu_eff_switch_init(mixer, list->kctl);
Felix Homannd34bf142012-04-23 20:24:27 +0200992 return 0;
993}
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +0200994
Felix Homanncfe8f972012-04-23 20:24:26 +0200995/* Create volume controls for FTU devices*/
996static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +0200997{
998 char name[64];
Felix Homann8a4d1d32012-04-23 20:24:23 +0200999 unsigned int control, cmask;
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001000 int in, out, err;
1001
Felix Homann8a4d1d32012-04-23 20:24:23 +02001002 const unsigned int id = 5;
1003 const int val_type = USB_MIXER_S16;
1004
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001005 for (out = 0; out < 8; out++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001006 control = out + 1;
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001007 for (in = 0; in < 8; in++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001008 cmask = 1 << in;
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001009 snprintf(name, sizeof(name),
Felix Homann8a4d1d32012-04-23 20:24:23 +02001010 "AIn%d - Out%d Capture Volume",
1011 in + 1, out + 1);
1012 err = snd_create_std_mono_ctl(mixer, id, control,
1013 cmask, val_type, name,
Felix Homann25ee7ef2012-04-23 20:24:25 +02001014 &snd_usb_mixer_vol_tlv);
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001015 if (err < 0)
1016 return err;
1017 }
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001018 for (in = 8; in < 16; in++) {
Felix Homann8a4d1d32012-04-23 20:24:23 +02001019 cmask = 1 << in;
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001020 snprintf(name, sizeof(name),
Felix Homann8a4d1d32012-04-23 20:24:23 +02001021 "DIn%d - Out%d Playback Volume",
1022 in - 7, out + 1);
1023 err = snd_create_std_mono_ctl(mixer, id, control,
1024 cmask, val_type, name,
Felix Homann25ee7ef2012-04-23 20:24:25 +02001025 &snd_usb_mixer_vol_tlv);
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001026 if (err < 0)
1027 return err;
1028 }
1029 }
1030
1031 return 0;
1032}
1033
Felix Homannd34bf142012-04-23 20:24:27 +02001034/* This control needs a volume quirk, see mixer.c */
1035static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
1036{
1037 static const char name[] = "Effect Volume";
1038 const unsigned int id = 6;
1039 const int val_type = USB_MIXER_U8;
1040 const unsigned int control = 2;
1041 const unsigned int cmask = 0;
1042
1043 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1044 name, snd_usb_mixer_vol_tlv);
1045}
1046
1047/* This control needs a volume quirk, see mixer.c */
1048static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
1049{
1050 static const char name[] = "Effect Duration";
1051 const unsigned int id = 6;
1052 const int val_type = USB_MIXER_S16;
1053 const unsigned int control = 3;
1054 const unsigned int cmask = 0;
1055
1056 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1057 name, snd_usb_mixer_vol_tlv);
1058}
1059
1060/* This control needs a volume quirk, see mixer.c */
1061static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
1062{
1063 static const char name[] = "Effect Feedback Volume";
1064 const unsigned int id = 6;
1065 const int val_type = USB_MIXER_U8;
1066 const unsigned int control = 4;
1067 const unsigned int cmask = 0;
1068
1069 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1070 name, NULL);
1071}
1072
1073static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer)
1074{
1075 unsigned int cmask;
1076 int err, ch;
1077 char name[48];
1078
1079 const unsigned int id = 7;
1080 const int val_type = USB_MIXER_S16;
1081 const unsigned int control = 7;
1082
1083 for (ch = 0; ch < 4; ++ch) {
1084 cmask = 1 << ch;
1085 snprintf(name, sizeof(name),
1086 "Effect Return %d Volume", ch + 1);
1087 err = snd_create_std_mono_ctl(mixer, id, control,
1088 cmask, val_type, name,
1089 snd_usb_mixer_vol_tlv);
1090 if (err < 0)
1091 return err;
1092 }
1093
1094 return 0;
1095}
1096
1097static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer)
1098{
1099 unsigned int cmask;
1100 int err, ch;
1101 char name[48];
1102
1103 const unsigned int id = 5;
1104 const int val_type = USB_MIXER_S16;
1105 const unsigned int control = 9;
1106
1107 for (ch = 0; ch < 8; ++ch) {
1108 cmask = 1 << ch;
1109 snprintf(name, sizeof(name),
1110 "Effect Send AIn%d Volume", ch + 1);
1111 err = snd_create_std_mono_ctl(mixer, id, control, cmask,
1112 val_type, name,
1113 snd_usb_mixer_vol_tlv);
1114 if (err < 0)
1115 return err;
1116 }
1117 for (ch = 8; ch < 16; ++ch) {
1118 cmask = 1 << ch;
1119 snprintf(name, sizeof(name),
1120 "Effect Send DIn%d Volume", ch - 7);
1121 err = snd_create_std_mono_ctl(mixer, id, control, cmask,
1122 val_type, name,
1123 snd_usb_mixer_vol_tlv);
1124 if (err < 0)
1125 return err;
1126 }
1127 return 0;
1128}
1129
Felix Homanncfe8f972012-04-23 20:24:26 +02001130static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
Mark Hills7536c302012-04-14 17:19:24 +01001131{
Felix Homann8a4d1d32012-04-23 20:24:23 +02001132 int err;
Mark Hills7536c302012-04-14 17:19:24 +01001133
Felix Homanncfe8f972012-04-23 20:24:26 +02001134 err = snd_ftu_create_volume_ctls(mixer);
Felix Homann8a4d1d32012-04-23 20:24:23 +02001135 if (err < 0)
1136 return err;
Mark Hills7536c302012-04-14 17:19:24 +01001137
Eldad Zackd847ce02012-11-28 23:55:37 +01001138 err = snd_ftu_create_effect_switch(mixer, 1, 6);
Felix Homannd34bf142012-04-23 20:24:27 +02001139 if (err < 0)
1140 return err;
Eldad Zackd847ce02012-11-28 23:55:37 +01001141
Felix Homannd34bf142012-04-23 20:24:27 +02001142 err = snd_ftu_create_effect_volume_ctl(mixer);
1143 if (err < 0)
1144 return err;
1145
1146 err = snd_ftu_create_effect_duration_ctl(mixer);
1147 if (err < 0)
1148 return err;
1149
1150 err = snd_ftu_create_effect_feedback_ctl(mixer);
1151 if (err < 0)
1152 return err;
1153
1154 err = snd_ftu_create_effect_return_ctls(mixer);
1155 if (err < 0)
1156 return err;
1157
1158 err = snd_ftu_create_effect_send_ctls(mixer);
1159 if (err < 0)
1160 return err;
1161
Felix Homann8a4d1d32012-04-23 20:24:23 +02001162 return 0;
Mark Hills7536c302012-04-14 17:19:24 +01001163}
1164
Daniel Mack7b1eda22010-03-11 21:13:22 +01001165void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
1166 unsigned char samplerate_id)
1167{
1168 struct usb_mixer_interface *mixer;
1169 struct usb_mixer_elem_info *cval;
1170 int unitid = 12; /* SamleRate ExtensionUnit ID */
1171
1172 list_for_each_entry(mixer, &chip->mixer_list, list) {
Takashi Iwai3360b842014-11-18 11:47:04 +01001173 cval = (struct usb_mixer_elem_info *)mixer->id_elems[unitid];
Daniel Mack7b1eda22010-03-11 21:13:22 +01001174 if (cval) {
1175 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
1176 cval->control << 8,
1177 samplerate_id);
1178 snd_usb_mixer_notify_id(mixer, unitid);
1179 }
1180 break;
1181 }
1182}
1183
Matt Gruskine9a25e02013-02-09 12:56:35 -05001184/* M-Audio Fast Track C400/C600 */
1185/* C400/C600 volume controls, this control needs a volume quirk, see mixer.c */
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001186static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
1187{
1188 char name[64];
1189 unsigned int cmask, offset;
1190 int out, chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001191 int num_outs = 0;
1192 int num_ins = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001193
1194 const unsigned int id = 0x40;
1195 const int val_type = USB_MIXER_S16;
1196 const int control = 1;
1197
Matt Gruskine9a25e02013-02-09 12:56:35 -05001198 switch (mixer->chip->usb_id) {
1199 case USB_ID(0x0763, 0x2030):
1200 num_outs = 6;
1201 num_ins = 4;
1202 break;
1203 case USB_ID(0x0763, 0x2031):
1204 num_outs = 8;
1205 num_ins = 6;
1206 break;
1207 }
1208
1209 for (chan = 0; chan < num_outs + num_ins; chan++) {
1210 for (out = 0; out < num_outs; out++) {
1211 if (chan < num_outs) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001212 snprintf(name, sizeof(name),
1213 "PCM%d-Out%d Playback Volume",
1214 chan + 1, out + 1);
1215 } else {
1216 snprintf(name, sizeof(name),
1217 "In%d-Out%d Playback Volume",
Matt Gruskine9a25e02013-02-09 12:56:35 -05001218 chan - num_outs + 1, out + 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001219 }
1220
1221 cmask = (out == 0) ? 0 : 1 << (out - 1);
Matt Gruskine9a25e02013-02-09 12:56:35 -05001222 offset = chan * num_outs;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001223 err = snd_create_std_mono_ctl_offset(mixer, id, control,
1224 cmask, val_type, offset, name,
1225 &snd_usb_mixer_vol_tlv);
1226 if (err < 0)
1227 return err;
1228 }
1229 }
1230
1231 return 0;
1232}
1233
1234/* This control needs a volume quirk, see mixer.c */
1235static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
1236{
1237 static const char name[] = "Effect Volume";
1238 const unsigned int id = 0x43;
1239 const int val_type = USB_MIXER_U8;
1240 const unsigned int control = 3;
1241 const unsigned int cmask = 0;
1242
1243 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1244 name, snd_usb_mixer_vol_tlv);
1245}
1246
1247/* This control needs a volume quirk, see mixer.c */
1248static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
1249{
1250 static const char name[] = "Effect Duration";
1251 const unsigned int id = 0x43;
1252 const int val_type = USB_MIXER_S16;
1253 const unsigned int control = 4;
1254 const unsigned int cmask = 0;
1255
1256 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1257 name, snd_usb_mixer_vol_tlv);
1258}
1259
1260/* This control needs a volume quirk, see mixer.c */
1261static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
1262{
1263 static const char name[] = "Effect Feedback Volume";
1264 const unsigned int id = 0x43;
1265 const int val_type = USB_MIXER_U8;
1266 const unsigned int control = 5;
1267 const unsigned int cmask = 0;
1268
1269 return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
1270 name, NULL);
1271}
1272
1273static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
1274{
1275 char name[64];
1276 unsigned int cmask;
1277 int chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001278 int num_outs = 0;
1279 int num_ins = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001280
1281 const unsigned int id = 0x42;
1282 const int val_type = USB_MIXER_S16;
1283 const int control = 1;
1284
Matt Gruskine9a25e02013-02-09 12:56:35 -05001285 switch (mixer->chip->usb_id) {
1286 case USB_ID(0x0763, 0x2030):
1287 num_outs = 6;
1288 num_ins = 4;
1289 break;
1290 case USB_ID(0x0763, 0x2031):
1291 num_outs = 8;
1292 num_ins = 6;
1293 break;
1294 }
1295
1296 for (chan = 0; chan < num_outs + num_ins; chan++) {
1297 if (chan < num_outs) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001298 snprintf(name, sizeof(name),
1299 "Effect Send DOut%d",
1300 chan + 1);
1301 } else {
1302 snprintf(name, sizeof(name),
1303 "Effect Send AIn%d",
Matt Gruskine9a25e02013-02-09 12:56:35 -05001304 chan - num_outs + 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001305 }
1306
1307 cmask = (chan == 0) ? 0 : 1 << (chan - 1);
1308 err = snd_create_std_mono_ctl(mixer, id, control,
1309 cmask, val_type, name,
1310 &snd_usb_mixer_vol_tlv);
1311 if (err < 0)
1312 return err;
1313 }
1314
1315 return 0;
1316}
1317
1318static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer)
1319{
1320 char name[64];
1321 unsigned int cmask;
1322 int chan, err;
Matt Gruskine9a25e02013-02-09 12:56:35 -05001323 int num_outs = 0;
1324 int offset = 0;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001325
1326 const unsigned int id = 0x40;
1327 const int val_type = USB_MIXER_S16;
1328 const int control = 1;
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001329
Matt Gruskine9a25e02013-02-09 12:56:35 -05001330 switch (mixer->chip->usb_id) {
1331 case USB_ID(0x0763, 0x2030):
1332 num_outs = 6;
1333 offset = 0x3c;
1334 /* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */
1335 break;
1336 case USB_ID(0x0763, 0x2031):
1337 num_outs = 8;
1338 offset = 0x70;
1339 /* { 0x70, 0x79, 0x72, 0x7b, 0x74, 0x7d, 0x76, 0x7f } */
1340 break;
1341 }
1342
1343 for (chan = 0; chan < num_outs; chan++) {
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001344 snprintf(name, sizeof(name),
1345 "Effect Return %d",
1346 chan + 1);
1347
Matt Gruskine9a25e02013-02-09 12:56:35 -05001348 cmask = (chan == 0) ? 0 :
1349 1 << (chan + (chan % 2) * num_outs - 1);
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001350 err = snd_create_std_mono_ctl_offset(mixer, id, control,
1351 cmask, val_type, offset, name,
1352 &snd_usb_mixer_vol_tlv);
1353 if (err < 0)
1354 return err;
1355 }
1356
1357 return 0;
1358}
1359
1360static int snd_c400_create_mixer(struct usb_mixer_interface *mixer)
1361{
1362 int err;
1363
1364 err = snd_c400_create_vol_ctls(mixer);
1365 if (err < 0)
1366 return err;
1367
1368 err = snd_c400_create_effect_vol_ctls(mixer);
1369 if (err < 0)
1370 return err;
1371
1372 err = snd_c400_create_effect_ret_vol_ctls(mixer);
1373 if (err < 0)
1374 return err;
1375
1376 err = snd_ftu_create_effect_switch(mixer, 2, 0x43);
1377 if (err < 0)
1378 return err;
1379
1380 err = snd_c400_create_effect_volume_ctl(mixer);
1381 if (err < 0)
1382 return err;
1383
1384 err = snd_c400_create_effect_duration_ctl(mixer);
1385 if (err < 0)
1386 return err;
1387
1388 err = snd_c400_create_effect_feedback_ctl(mixer);
1389 if (err < 0)
1390 return err;
1391
1392 return 0;
1393}
1394
Mark Hillsb71dad182012-06-09 13:16:38 +01001395/*
1396 * The mixer units for Ebox-44 are corrupt, and even where they
1397 * are valid they presents mono controls as L and R channels of
1398 * stereo. So we provide a good mixer here.
1399 */
Sachin Kamate8e7da22013-01-10 11:19:14 +05301400static struct std_mono_table ebox44_table[] = {
Mark Hills989b0132012-06-09 13:16:39 +01001401 {
1402 .unitid = 4,
1403 .control = 1,
1404 .cmask = 0x0,
1405 .val_type = USB_MIXER_INV_BOOLEAN,
1406 .name = "Headphone Playback Switch"
1407 },
1408 {
1409 .unitid = 4,
1410 .control = 2,
1411 .cmask = 0x1,
1412 .val_type = USB_MIXER_S16,
1413 .name = "Headphone A Mix Playback Volume"
1414 },
1415 {
1416 .unitid = 4,
1417 .control = 2,
1418 .cmask = 0x2,
1419 .val_type = USB_MIXER_S16,
1420 .name = "Headphone B Mix Playback Volume"
1421 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001422
Mark Hills989b0132012-06-09 13:16:39 +01001423 {
1424 .unitid = 7,
1425 .control = 1,
1426 .cmask = 0x0,
1427 .val_type = USB_MIXER_INV_BOOLEAN,
1428 .name = "Output Playback Switch"
1429 },
1430 {
1431 .unitid = 7,
1432 .control = 2,
1433 .cmask = 0x1,
1434 .val_type = USB_MIXER_S16,
1435 .name = "Output A Playback Volume"
1436 },
1437 {
1438 .unitid = 7,
1439 .control = 2,
1440 .cmask = 0x2,
1441 .val_type = USB_MIXER_S16,
1442 .name = "Output B Playback Volume"
1443 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001444
Mark Hills989b0132012-06-09 13:16:39 +01001445 {
1446 .unitid = 10,
1447 .control = 1,
1448 .cmask = 0x0,
1449 .val_type = USB_MIXER_INV_BOOLEAN,
1450 .name = "Input Capture Switch"
1451 },
1452 {
1453 .unitid = 10,
1454 .control = 2,
1455 .cmask = 0x1,
1456 .val_type = USB_MIXER_S16,
1457 .name = "Input A Capture Volume"
1458 },
1459 {
1460 .unitid = 10,
1461 .control = 2,
1462 .cmask = 0x2,
1463 .val_type = USB_MIXER_S16,
1464 .name = "Input B Capture Volume"
1465 },
Mark Hillsb71dad182012-06-09 13:16:38 +01001466
Mark Hills989b0132012-06-09 13:16:39 +01001467 {}
Mark Hillsb71dad182012-06-09 13:16:38 +01001468};
1469
Przemek Rudy066624c2013-06-27 23:52:33 +02001470/* Audio Advantage Micro II findings:
1471 *
1472 * Mapping spdif AES bits to vendor register.bit:
1473 * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
1474 * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
1475 * AES2: [0 0 0 0 0 0 0 0]
1476 * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
1477 * (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
1478 *
1479 * power on values:
1480 * r2: 0x10
1481 * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
1482 * just after it to 0xa0, presumably it disables/mutes some analog
1483 * parts when there is no audio.)
1484 * r9: 0x28
1485 *
1486 * Optical transmitter on/off:
1487 * vendor register.bit: 9.1
1488 * 0 - on (0x28 register value)
1489 * 1 - off (0x2a register value)
1490 *
1491 */
1492static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
1493 struct snd_ctl_elem_info *uinfo)
1494{
1495 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1496 uinfo->count = 1;
1497 return 0;
1498}
1499
1500static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
1501 struct snd_ctl_elem_value *ucontrol)
1502{
Takashi Iwai288673b2014-11-18 18:06:17 +01001503 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
1504 struct snd_usb_audio *chip = list->mixer->chip;
Przemek Rudy066624c2013-06-27 23:52:33 +02001505 int err;
1506 struct usb_interface *iface;
1507 struct usb_host_interface *alts;
1508 unsigned int ep;
1509 unsigned char data[3];
1510 int rate;
1511
Takashi Iwai47ab1542015-08-25 16:09:00 +02001512 err = snd_usb_lock_shutdown(chip);
1513 if (err < 0)
1514 return err;
Takashi Iwai288673b2014-11-18 18:06:17 +01001515
Przemek Rudy066624c2013-06-27 23:52:33 +02001516 ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
1517 ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
1518 ucontrol->value.iec958.status[2] = 0x00;
1519
1520 /* use known values for that card: interface#1 altsetting#1 */
Takashi Iwai288673b2014-11-18 18:06:17 +01001521 iface = usb_ifnum_to_if(chip->dev, 1);
Takashi Iwai447d6272016-03-15 15:20:58 +01001522 if (!iface || iface->num_altsetting < 2)
1523 return -EINVAL;
Przemek Rudy066624c2013-06-27 23:52:33 +02001524 alts = &iface->altsetting[1];
Takashi Iwai447d6272016-03-15 15:20:58 +01001525 if (get_iface_desc(alts)->bNumEndpoints < 1)
1526 return -EINVAL;
Przemek Rudy066624c2013-06-27 23:52:33 +02001527 ep = get_endpoint(alts, 0)->bEndpointAddress;
1528
Takashi Iwai288673b2014-11-18 18:06:17 +01001529 err = snd_usb_ctl_msg(chip->dev,
1530 usb_rcvctrlpipe(chip->dev, 0),
Przemek Rudy066624c2013-06-27 23:52:33 +02001531 UAC_GET_CUR,
1532 USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
1533 UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
1534 ep,
1535 data,
1536 sizeof(data));
1537 if (err < 0)
1538 goto end;
1539
1540 rate = data[0] | (data[1] << 8) | (data[2] << 16);
1541 ucontrol->value.iec958.status[3] = (rate == 48000) ?
1542 IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
1543
1544 err = 0;
Takashi Iwai288673b2014-11-18 18:06:17 +01001545 end:
Takashi Iwai47ab1542015-08-25 16:09:00 +02001546 snd_usb_unlock_shutdown(chip);
Przemek Rudy066624c2013-06-27 23:52:33 +02001547 return err;
1548}
1549
Takashi Iwai288673b2014-11-18 18:06:17 +01001550static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
Przemek Rudy066624c2013-06-27 23:52:33 +02001551{
Takashi Iwai288673b2014-11-18 18:06:17 +01001552 struct snd_usb_audio *chip = list->mixer->chip;
1553 unsigned int pval = list->kctl->private_value;
Przemek Rudy066624c2013-06-27 23:52:33 +02001554 u8 reg;
Takashi Iwai288673b2014-11-18 18:06:17 +01001555 int err;
Przemek Rudy066624c2013-06-27 23:52:33 +02001556
Takashi Iwai47ab1542015-08-25 16:09:00 +02001557 err = snd_usb_lock_shutdown(chip);
1558 if (err < 0)
1559 return err;
Takashi Iwai288673b2014-11-18 18:06:17 +01001560
1561 reg = ((pval >> 4) & 0xf0) | (pval & 0x0f);
1562 err = snd_usb_ctl_msg(chip->dev,
1563 usb_sndctrlpipe(chip->dev, 0),
Przemek Rudy066624c2013-06-27 23:52:33 +02001564 UAC_SET_CUR,
1565 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1566 reg,
1567 2,
1568 NULL,
1569 0);
1570 if (err < 0)
1571 goto end;
1572
Takashi Iwai288673b2014-11-18 18:06:17 +01001573 reg = (pval & IEC958_AES0_NONAUDIO) ? 0xa0 : 0x20;
1574 reg |= (pval >> 12) & 0x0f;
1575 err = snd_usb_ctl_msg(chip->dev,
1576 usb_sndctrlpipe(chip->dev, 0),
Przemek Rudy066624c2013-06-27 23:52:33 +02001577 UAC_SET_CUR,
1578 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1579 reg,
1580 3,
1581 NULL,
1582 0);
1583 if (err < 0)
1584 goto end;
1585
Takashi Iwai288673b2014-11-18 18:06:17 +01001586 end:
Takashi Iwai47ab1542015-08-25 16:09:00 +02001587 snd_usb_unlock_shutdown(chip);
Takashi Iwai288673b2014-11-18 18:06:17 +01001588 return err;
1589}
1590
1591static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
1592 struct snd_ctl_elem_value *ucontrol)
1593{
1594 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
1595 unsigned int pval, pval_old;
1596 int err;
1597
1598 pval = pval_old = kcontrol->private_value;
1599 pval &= 0xfffff0f0;
1600 pval |= (ucontrol->value.iec958.status[1] & 0x0f) << 8;
1601 pval |= (ucontrol->value.iec958.status[0] & 0x0f);
1602
1603 pval &= 0xffff0fff;
1604 pval |= (ucontrol->value.iec958.status[1] & 0xf0) << 8;
Przemek Rudy066624c2013-06-27 23:52:33 +02001605
1606 /* The frequency bits in AES3 cannot be set via register access. */
1607
1608 /* Silently ignore any bits from the request that cannot be set. */
1609
Takashi Iwai288673b2014-11-18 18:06:17 +01001610 if (pval == pval_old)
1611 return 0;
1612
1613 kcontrol->private_value = pval;
1614 err = snd_microii_spdif_default_update(list);
1615 return err < 0 ? err : 1;
Przemek Rudy066624c2013-06-27 23:52:33 +02001616}
1617
1618static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
1619 struct snd_ctl_elem_value *ucontrol)
1620{
1621 ucontrol->value.iec958.status[0] = 0x0f;
1622 ucontrol->value.iec958.status[1] = 0xff;
1623 ucontrol->value.iec958.status[2] = 0x00;
1624 ucontrol->value.iec958.status[3] = 0x00;
1625
1626 return 0;
1627}
1628
1629static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
1630 struct snd_ctl_elem_value *ucontrol)
1631{
1632 ucontrol->value.integer.value[0] = !(kcontrol->private_value & 0x02);
1633
1634 return 0;
1635}
1636
Takashi Iwai288673b2014-11-18 18:06:17 +01001637static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
Przemek Rudy066624c2013-06-27 23:52:33 +02001638{
Takashi Iwai288673b2014-11-18 18:06:17 +01001639 struct snd_usb_audio *chip = list->mixer->chip;
1640 u8 reg = list->kctl->private_value;
Przemek Rudy066624c2013-06-27 23:52:33 +02001641 int err;
Przemek Rudy066624c2013-06-27 23:52:33 +02001642
Takashi Iwai47ab1542015-08-25 16:09:00 +02001643 err = snd_usb_lock_shutdown(chip);
1644 if (err < 0)
1645 return err;
Takashi Iwai288673b2014-11-18 18:06:17 +01001646
1647 err = snd_usb_ctl_msg(chip->dev,
1648 usb_sndctrlpipe(chip->dev, 0),
Przemek Rudy066624c2013-06-27 23:52:33 +02001649 UAC_SET_CUR,
1650 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1651 reg,
1652 9,
1653 NULL,
1654 0);
1655
Takashi Iwai47ab1542015-08-25 16:09:00 +02001656 snd_usb_unlock_shutdown(chip);
Przemek Rudy066624c2013-06-27 23:52:33 +02001657 return err;
1658}
1659
Takashi Iwai288673b2014-11-18 18:06:17 +01001660static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
1661 struct snd_ctl_elem_value *ucontrol)
1662{
1663 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
1664 u8 reg;
1665 int err;
1666
1667 reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a;
1668 if (reg != list->kctl->private_value)
1669 return 0;
1670
1671 kcontrol->private_value = reg;
1672 err = snd_microii_spdif_switch_update(list);
1673 return err < 0 ? err : 1;
1674}
1675
Przemek Rudy066624c2013-06-27 23:52:33 +02001676static struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
1677 {
1678 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1679 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1680 .info = snd_microii_spdif_info,
1681 .get = snd_microii_spdif_default_get,
1682 .put = snd_microii_spdif_default_put,
1683 .private_value = 0x00000100UL,/* reset value */
1684 },
1685 {
1686 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1687 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1688 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
1689 .info = snd_microii_spdif_info,
1690 .get = snd_microii_spdif_mask_get,
1691 },
1692 {
1693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1694 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
1695 .info = snd_ctl_boolean_mono_info,
1696 .get = snd_microii_spdif_switch_get,
1697 .put = snd_microii_spdif_switch_put,
1698 .private_value = 0x00000028UL,/* reset value */
1699 }
1700};
1701
1702static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
1703{
1704 int err, i;
Takashi Iwai288673b2014-11-18 18:06:17 +01001705 static usb_mixer_elem_resume_func_t resume_funcs[] = {
1706 snd_microii_spdif_default_update,
1707 NULL,
1708 snd_microii_spdif_switch_update
1709 };
Przemek Rudy066624c2013-06-27 23:52:33 +02001710
1711 for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) {
Takashi Iwai288673b2014-11-18 18:06:17 +01001712 err = add_single_ctl_with_resume(mixer, 0,
1713 resume_funcs[i],
1714 &snd_microii_mixer_spdif[i],
1715 NULL);
Przemek Rudy066624c2013-06-27 23:52:33 +02001716 if (err < 0)
1717 return err;
1718 }
1719
Mikulas Patocka18e47532013-12-05 14:32:43 -05001720 return 0;
Przemek Rudy066624c2013-06-27 23:52:33 +02001721}
1722
Daniel Mack7b1eda22010-03-11 21:13:22 +01001723int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1724{
Daniel Mack3347b262011-02-11 11:34:12 +00001725 int err = 0;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001726 struct snd_info_entry *entry;
1727
1728 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
1729 return err;
1730
Daniel Mack3347b262011-02-11 11:34:12 +00001731 switch (mixer->chip->usb_id) {
1732 case USB_ID(0x041e, 0x3020):
1733 case USB_ID(0x041e, 0x3040):
1734 case USB_ID(0x041e, 0x3042):
Mathieu Bouffard7cdd8d72011-05-18 17:09:17 +02001735 case USB_ID(0x041e, 0x30df):
Daniel Mack3347b262011-02-11 11:34:12 +00001736 case USB_ID(0x041e, 0x3048):
1737 err = snd_audigy2nx_controls_create(mixer);
1738 if (err < 0)
1739 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001740 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
1741 snd_info_set_text_ops(entry, mixer,
1742 snd_audigy2nx_proc_read);
Daniel Mack3347b262011-02-11 11:34:12 +00001743 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001744
Vasily Khoruzhick44832a72013-11-13 13:13:35 +03001745 /* EMU0204 */
1746 case USB_ID(0x041e, 0x3f19):
1747 err = snd_emu0204_controls_create(mixer);
1748 if (err < 0)
1749 break;
1750 break;
1751
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001752 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
Matt Gruskine9a25e02013-02-09 12:56:35 -05001753 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */
Eldad Zack09d8e3a2012-11-28 23:55:40 +01001754 err = snd_c400_create_mixer(mixer);
1755 break;
1756
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001757 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
1758 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
Felix Homanncfe8f972012-04-23 20:24:26 +02001759 err = snd_ftu_create_mixer(mixer);
Daniel Mackd5a0bf6cc2011-05-25 09:09:03 +02001760 break;
1761
Denis Washington1d31aff2012-12-11 11:38:32 +01001762 case USB_ID(0x0b05, 0x1739): /* ASUS Xonar U1 */
1763 case USB_ID(0x0b05, 0x1743): /* ASUS Xonar U1 (2) */
1764 case USB_ID(0x0b05, 0x17a0): /* ASUS Xonar U3 */
Daniel Mack7b1eda22010-03-11 21:13:22 +01001765 err = snd_xonar_u1_controls_create(mixer);
Daniel Mack3347b262011-02-11 11:34:12 +00001766 break;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001767
Przemek Rudy066624c2013-06-27 23:52:33 +02001768 case USB_ID(0x0d8c, 0x0103): /* Audio Advantage Micro II */
1769 err = snd_microii_controls_create(mixer);
1770 break;
1771
Damien Zammitd497a822014-11-12 01:09:54 +11001772 case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */
1773 err = snd_mbox1_create_sync_switch(mixer);
1774 break;
1775
Daniel Mack3347b262011-02-11 11:34:12 +00001776 case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
Daniel Mack54a8c502011-02-11 11:08:06 +00001777 err = snd_nativeinstruments_create_mixer(mixer,
1778 snd_nativeinstruments_ta6_mixers,
1779 ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
Daniel Mack3347b262011-02-11 11:34:12 +00001780 break;
Daniel Mack54a8c502011-02-11 11:08:06 +00001781
Daniel Mack3347b262011-02-11 11:34:12 +00001782 case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
Daniel Mack54a8c502011-02-11 11:08:06 +00001783 err = snd_nativeinstruments_create_mixer(mixer,
1784 snd_nativeinstruments_ta10_mixers,
1785 ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
Daniel Mack3347b262011-02-11 11:34:12 +00001786 break;
Mark Hills7536c302012-04-14 17:19:24 +01001787
1788 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
Mark Hillsb71dad182012-06-09 13:16:38 +01001789 /* detection is disabled in mixer_maps.c */
1790 err = snd_create_std_mono_table(mixer, ebox44_table);
Mark Hills7536c302012-04-14 17:19:24 +01001791 break;
Chris J Arges76b188c2014-11-12 12:07:02 -06001792
1793 case USB_ID(0x1235, 0x8012): /* Focusrite Scarlett 6i6 */
1794 case USB_ID(0x1235, 0x8002): /* Focusrite Scarlett 8i6 */
1795 case USB_ID(0x1235, 0x8004): /* Focusrite Scarlett 18i6 */
1796 case USB_ID(0x1235, 0x8014): /* Focusrite Scarlett 18i8 */
1797 case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */
1798 err = snd_scarlett_controls_create(mixer);
1799 break;
Daniel Mack54a8c502011-02-11 11:08:06 +00001800 }
1801
Daniel Mack3347b262011-02-11 11:34:12 +00001802 return err;
Daniel Mack7b1eda22010-03-11 21:13:22 +01001803}
1804
1805void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
1806 int unitid)
1807{
1808 if (!mixer->rc_cfg)
1809 return;
1810 /* unit ids specific to Extigy/Audigy 2 NX: */
1811 switch (unitid) {
1812 case 0: /* remote control */
1813 mixer->rc_urb->dev = mixer->chip->dev;
1814 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
1815 break;
1816 case 4: /* digital in jack */
1817 case 7: /* line in jacks */
1818 case 19: /* speaker out jacks */
1819 case 20: /* headphones out jack */
1820 break;
1821 /* live24ext: 4 = line-in jack */
1822 case 3: /* hp-out jack (may actuate Mute) */
1823 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1824 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1825 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1826 break;
1827 default:
Takashi Iwai0ba41d92014-02-26 13:02:17 +01001828 usb_audio_dbg(mixer->chip, "memory change in unknown unit %d\n", unitid);
Daniel Mack7b1eda22010-03-11 21:13:22 +01001829 break;
1830 }
1831}
1832
Anssi Hannula42e31212015-12-13 20:49:58 +02001833static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
1834 struct snd_kcontrol *kctl)
1835{
1836 /* Approximation using 10 ranges based on output measurement on hw v1.2.
1837 * This seems close to the cubic mapping e.g. alsamixer uses. */
1838 static const DECLARE_TLV_DB_RANGE(scale,
1839 0, 1, TLV_DB_MINMAX_ITEM(-5300, -4970),
1840 2, 5, TLV_DB_MINMAX_ITEM(-4710, -4160),
1841 6, 7, TLV_DB_MINMAX_ITEM(-3884, -3710),
1842 8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
1843 15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
1844 17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
1845 20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
1846 27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
1847 32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
1848 41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
1849 );
1850
1851 usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
1852 kctl->tlv.p = scale;
1853 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1854 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1855}
1856
1857void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
1858 struct usb_mixer_elem_info *cval, int unitid,
1859 struct snd_kcontrol *kctl)
1860{
1861 switch (mixer->chip->usb_id) {
1862 case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
1863 if (unitid == 7 && cval->min == 0 && cval->max == 50)
1864 snd_dragonfly_quirk_db_scale(mixer, kctl);
1865 break;
1866 }
1867}
1868