blob: c07b3f8485e374d01c5586ad2d908a45c396cc0b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Mixer control part
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/bitops.h>
30#include <linux/init.h>
31#include <linux/list.h>
32#include <linux/slab.h>
33#include <linux/string.h>
34#include <linux/usb.h>
35#include <sound/core.h>
36#include <sound/control.h>
Clemens Ladischb259b102005-04-29 16:29:28 +020037#include <sound/hwdep.h>
Clemens Ladischaafad562005-05-10 14:47:38 +020038#include <sound/info.h>
Takashi Iwai7bc5ba72006-07-14 15:18:19 +020039#include <sound/tlv.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
41#include "usbaudio.h"
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043/*
44 */
45
46/* ignore error from controls - for debugging */
47/* #define IGNORE_CTL_ERROR */
48
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +020049/*
50 * Sound Blaster remote control configuration
51 *
52 * format of remote control data:
53 * Extigy: xx 00
54 * Audigy 2 NX: 06 80 xx 00 00 00
55 * Live! 24-bit: 06 80 xx yy 22 83
56 */
57static const struct rc_config {
58 u32 usb_id;
59 u8 offset;
60 u8 length;
61 u8 packet_length;
Phillip Michael Jordanb9c196e2008-08-05 11:01:00 +020062 u8 min_packet_length; /* minimum accepted length of the URB result */
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +020063 u8 mute_mixer_id;
64 u32 mute_code;
65} rc_configs[] = {
Phillip Michael Jordanb9c196e2008-08-05 11:01:00 +020066 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
67 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
68 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +020069};
70
Clemens Ladisch84957a82005-04-29 16:23:13 +020071struct usb_mixer_interface {
Takashi Iwai86e07d32005-11-17 15:08:02 +010072 struct snd_usb_audio *chip;
Clemens Ladisch84957a82005-04-29 16:23:13 +020073 unsigned int ctrlif;
74 struct list_head list;
75 unsigned int ignore_ctl_error;
Clemens Ladisch6639b6c2005-04-29 16:26:14 +020076 struct urb *urb;
Takashi Iwai86e07d32005-11-17 15:08:02 +010077 struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
Clemens Ladischb259b102005-04-29 16:29:28 +020078
79 /* Sound Blaster remote control stuff */
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +020080 const struct rc_config *rc_cfg;
Clemens Ladischb259b102005-04-29 16:29:28 +020081 unsigned long rc_hwdep_open;
82 u32 rc_code;
83 wait_queue_head_t rc_waitq;
84 struct urb *rc_urb;
85 struct usb_ctrlrequest *rc_setup_packet;
86 u8 rc_buffer[6];
Clemens Ladisch93446ed2005-05-03 08:02:40 +020087
88 u8 audigy2nx_leds[3];
Clemens Ladisch84957a82005-04-29 16:23:13 +020089};
90
91
Linus Torvalds1da177e2005-04-16 15:20:36 -070092struct usb_audio_term {
93 int id;
94 int type;
95 int channels;
96 unsigned int chconfig;
97 int name;
98};
99
100struct usbmix_name_map;
101
Takashi Iwai86e07d32005-11-17 15:08:02 +0100102struct mixer_build {
103 struct snd_usb_audio *chip;
Clemens Ladisch84957a82005-04-29 16:23:13 +0200104 struct usb_mixer_interface *mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 unsigned char *buffer;
106 unsigned int buflen;
Clemens Ladisch707e6072005-04-29 09:56:17 +0200107 DECLARE_BITMAP(unitbitmap, 256);
Takashi Iwai86e07d32005-11-17 15:08:02 +0100108 struct usb_audio_term oterm;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 const struct usbmix_name_map *map;
Clemens Ladisch8e062ec2005-04-22 15:49:52 +0200110 const struct usbmix_selector_map *selector_map;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111};
112
Takashi Iwai641b4872009-01-15 17:05:24 +0100113#define MAX_CHANNELS 10 /* max logical channels */
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115struct usb_mixer_elem_info {
Clemens Ladisch84957a82005-04-29 16:23:13 +0200116 struct usb_mixer_interface *mixer;
Takashi Iwai86e07d32005-11-17 15:08:02 +0100117 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
118 struct snd_ctl_elem_id *elem_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 unsigned int id;
120 unsigned int control; /* CS or ICN (high byte) */
121 unsigned int cmask; /* channel mask bitmap: 0 = master */
122 int channels;
123 int val_type;
124 int min, max, res;
Takashi Iwai641b4872009-01-15 17:05:24 +0100125 int cached;
126 int cache_val[MAX_CHANNELS];
Clemens Ladisch6639b6c2005-04-29 16:26:14 +0200127 u8 initialized;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128};
129
130
131enum {
132 USB_FEATURE_NONE = 0,
133 USB_FEATURE_MUTE = 1,
134 USB_FEATURE_VOLUME,
135 USB_FEATURE_BASS,
136 USB_FEATURE_MID,
137 USB_FEATURE_TREBLE,
138 USB_FEATURE_GEQ,
139 USB_FEATURE_AGC,
140 USB_FEATURE_DELAY,
141 USB_FEATURE_BASSBOOST,
142 USB_FEATURE_LOUDNESS
143};
144
145enum {
146 USB_MIXER_BOOLEAN,
147 USB_MIXER_INV_BOOLEAN,
148 USB_MIXER_S8,
149 USB_MIXER_U8,
150 USB_MIXER_S16,
151 USB_MIXER_U16,
152};
153
154enum {
155 USB_PROC_UPDOWN = 1,
156 USB_PROC_UPDOWN_SWITCH = 1,
157 USB_PROC_UPDOWN_MODE_SEL = 2,
158
159 USB_PROC_PROLOGIC = 2,
160 USB_PROC_PROLOGIC_SWITCH = 1,
161 USB_PROC_PROLOGIC_MODE_SEL = 2,
162
163 USB_PROC_3DENH = 3,
164 USB_PROC_3DENH_SWITCH = 1,
165 USB_PROC_3DENH_SPACE = 2,
166
167 USB_PROC_REVERB = 4,
168 USB_PROC_REVERB_SWITCH = 1,
169 USB_PROC_REVERB_LEVEL = 2,
170 USB_PROC_REVERB_TIME = 3,
171 USB_PROC_REVERB_DELAY = 4,
172
173 USB_PROC_CHORUS = 5,
174 USB_PROC_CHORUS_SWITCH = 1,
175 USB_PROC_CHORUS_LEVEL = 2,
176 USB_PROC_CHORUS_RATE = 3,
177 USB_PROC_CHORUS_DEPTH = 4,
178
179 USB_PROC_DCR = 6,
180 USB_PROC_DCR_SWITCH = 1,
181 USB_PROC_DCR_RATIO = 2,
182 USB_PROC_DCR_MAX_AMP = 3,
183 USB_PROC_DCR_THRESHOLD = 4,
184 USB_PROC_DCR_ATTACK = 5,
185 USB_PROC_DCR_RELEASE = 6,
186};
187
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188
189/*
190 * manual mapping of mixer names
191 * if the mixer topology is too complicated and the parsed names are
192 * ambiguous, add the entries in usbmixer_maps.c.
193 */
194#include "usbmixer_maps.c"
195
196/* get the mapped name if the unit matches */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100197static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198{
199 const struct usbmix_name_map *p;
200
201 if (! state->map)
202 return 0;
203
204 for (p = state->map; p->id; p++) {
205 if (p->id == unitid && p->name &&
206 (! control || ! p->control || control == p->control)) {
207 buflen--;
208 return strlcpy(buf, p->name, buflen);
209 }
210 }
211 return 0;
212}
213
214/* check whether the control should be ignored */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100215static int check_ignored_ctl(struct mixer_build *state, int unitid, int control)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216{
217 const struct usbmix_name_map *p;
218
219 if (! state->map)
220 return 0;
221 for (p = state->map; p->id; p++) {
222 if (p->id == unitid && ! p->name &&
223 (! control || ! p->control || control == p->control)) {
224 // printk("ignored control %d:%d\n", unitid, control);
225 return 1;
226 }
227 }
228 return 0;
229}
230
Clemens Ladisch8e062ec2005-04-22 15:49:52 +0200231/* get the mapped selector source name */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100232static int check_mapped_selector_name(struct mixer_build *state, int unitid,
Clemens Ladisch8e062ec2005-04-22 15:49:52 +0200233 int index, char *buf, int buflen)
234{
235 const struct usbmix_selector_map *p;
236
237 if (! state->selector_map)
238 return 0;
239 for (p = state->selector_map; p->id; p++) {
240 if (p->id == unitid && index < p->count)
241 return strlcpy(buf, p->names[index], buflen);
242 }
243 return 0;
244}
245
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246/*
247 * find an audio control unit with the given unit id
248 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100249static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250{
251 unsigned char *p;
252
253 p = NULL;
254 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
255 USB_DT_CS_INTERFACE)) != NULL) {
256 if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit)
257 return p;
258 }
259 return NULL;
260}
261
262
263/*
264 * copy a string with the given id
265 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100266static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267{
268 int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
269 buf[len] = 0;
270 return len;
271}
272
273/*
274 * convert from the byte/word on usb descriptor to the zero-based integer
275 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100276static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277{
278 switch (cval->val_type) {
279 case USB_MIXER_BOOLEAN:
280 return !!val;
281 case USB_MIXER_INV_BOOLEAN:
282 return !val;
283 case USB_MIXER_U8:
284 val &= 0xff;
285 break;
286 case USB_MIXER_S8:
287 val &= 0xff;
288 if (val >= 0x80)
289 val -= 0x100;
290 break;
291 case USB_MIXER_U16:
292 val &= 0xffff;
293 break;
294 case USB_MIXER_S16:
295 val &= 0xffff;
296 if (val >= 0x8000)
297 val -= 0x10000;
298 break;
299 }
300 return val;
301}
302
303/*
304 * convert from the zero-based int to the byte/word for usb descriptor
305 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100306static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307{
308 switch (cval->val_type) {
309 case USB_MIXER_BOOLEAN:
310 return !!val;
311 case USB_MIXER_INV_BOOLEAN:
312 return !val;
313 case USB_MIXER_S8:
314 case USB_MIXER_U8:
315 return val & 0xff;
316 case USB_MIXER_S16:
317 case USB_MIXER_U16:
318 return val & 0xffff;
319 }
320 return 0; /* not reached */
321}
322
Takashi Iwai86e07d32005-11-17 15:08:02 +0100323static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324{
325 if (! cval->res)
326 cval->res = 1;
327 if (val < cval->min)
328 return 0;
Takashi Iwai14790f12006-03-28 17:58:28 +0200329 else if (val >= cval->max)
330 return (cval->max - cval->min + cval->res - 1) / cval->res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 else
332 return (val - cval->min) / cval->res;
333}
334
Takashi Iwai86e07d32005-11-17 15:08:02 +0100335static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
337 if (val < 0)
338 return cval->min;
339 if (! cval->res)
340 cval->res = 1;
341 val *= cval->res;
342 val += cval->min;
343 if (val > cval->max)
344 return cval->max;
345 return val;
346}
347
348
349/*
350 * retrieve a mixer value
351 */
352
Takashi Iwai86e07d32005-11-17 15:08:02 +0100353static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354{
355 unsigned char buf[2];
356 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
357 int timeout = 10;
358
359 while (timeout-- > 0) {
Clemens Ladisch84957a82005-04-29 16:23:13 +0200360 if (snd_usb_ctl_msg(cval->mixer->chip->dev,
361 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 request,
363 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
Clemens Ladisch84957a82005-04-29 16:23:13 +0200364 validx, cval->mixer->ctrlif | (cval->id << 8),
Thomas Reitmayra04395e2007-05-15 11:47:48 +0200365 buf, val_len, 100) >= val_len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
367 return 0;
368 }
369 }
Clemens Ladisch84957a82005-04-29 16:23:13 +0200370 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
371 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 return -EINVAL;
373}
374
Takashi Iwai86e07d32005-11-17 15:08:02 +0100375static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376{
377 return get_ctl_value(cval, GET_CUR, validx, value);
378}
379
380/* channel = 0: master, 1 = first channel */
Takashi Iwai641b4872009-01-15 17:05:24 +0100381static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
382 int channel, int *value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383{
384 return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value);
385}
386
Takashi Iwai641b4872009-01-15 17:05:24 +0100387static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
388 int channel, int index, int *value)
389{
390 int err;
391
392 if (cval->cached & (1 << channel)) {
393 *value = cval->cache_val[index];
394 return 0;
395 }
396 err = get_cur_mix_raw(cval, channel, value);
397 if (err < 0) {
398 if (!cval->mixer->ignore_ctl_error)
399 snd_printd(KERN_ERR "cannot get current value for "
400 "control %d ch %d: err = %d\n",
401 cval->control, channel, err);
402 return err;
403 }
404 cval->cached |= 1 << channel;
405 cval->cache_val[index] = *value;
406 return 0;
407}
408
409
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410/*
411 * set a mixer value
412 */
413
Takashi Iwai86e07d32005-11-17 15:08:02 +0100414static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{
416 unsigned char buf[2];
417 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
418 int timeout = 10;
419
420 value_set = convert_bytes_value(cval, value_set);
421 buf[0] = value_set & 0xff;
422 buf[1] = (value_set >> 8) & 0xff;
423 while (timeout -- > 0)
Clemens Ladisch84957a82005-04-29 16:23:13 +0200424 if (snd_usb_ctl_msg(cval->mixer->chip->dev,
425 usb_sndctrlpipe(cval->mixer->chip->dev, 0),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 request,
427 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
Clemens Ladisch84957a82005-04-29 16:23:13 +0200428 validx, cval->mixer->ctrlif | (cval->id << 8),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 buf, val_len, 100) >= 0)
430 return 0;
Clemens Ladisch84957a82005-04-29 16:23:13 +0200431 snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
432 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 return -EINVAL;
434}
435
Takashi Iwai86e07d32005-11-17 15:08:02 +0100436static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
438 return set_ctl_value(cval, SET_CUR, validx, value);
439}
440
Takashi Iwai641b4872009-01-15 17:05:24 +0100441static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
442 int index, int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
Takashi Iwai641b4872009-01-15 17:05:24 +0100444 int err;
445 err = set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel,
446 value);
447 if (err < 0)
448 return err;
449 cval->cached |= 1 << channel;
450 cval->cache_val[index] = value;
451 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452}
453
Takashi Iwai7bc5ba72006-07-14 15:18:19 +0200454/*
455 * TLV callback for mixer volume controls
456 */
457static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
458 unsigned int size, unsigned int __user *_tlv)
459{
460 struct usb_mixer_elem_info *cval = kcontrol->private_data;
461 DECLARE_TLV_DB_SCALE(scale, 0, 0, 0);
462
463 if (size < sizeof(scale))
464 return -ENOMEM;
465 /* USB descriptions contain the dB scale in 1/256 dB unit
466 * while ALSA TLV contains in 1/100 dB unit
467 */
468 scale[2] = (convert_signed_value(cval, cval->min) * 100) / 256;
469 scale[3] = (convert_signed_value(cval, cval->res) * 100) / 256;
470 if (copy_to_user(_tlv, scale, sizeof(scale)))
471 return -EFAULT;
472 return 0;
473}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474
475/*
476 * parser routines begin here...
477 */
478
Takashi Iwai86e07d32005-11-17 15:08:02 +0100479static int parse_audio_unit(struct mixer_build *state, int unitid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481
482/*
483 * check if the input/output channel routing is enabled on the given bitmap.
484 * used for mixer unit parser
485 */
486static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
487{
488 int idx = ich * num_outs + och;
489 return bmap[idx >> 3] & (0x80 >> (idx & 7));
490}
491
492
493/*
494 * add an alsa control element
495 * search and increment the index until an empty slot is found.
496 *
497 * if failed, give up and free the control instance.
498 */
499
Takashi Iwai86e07d32005-11-17 15:08:02 +0100500static int add_control_to_empty(struct mixer_build *state, struct snd_kcontrol *kctl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501{
Takashi Iwai86e07d32005-11-17 15:08:02 +0100502 struct usb_mixer_elem_info *cval = kctl->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 int err;
Clemens Ladisch84957a82005-04-29 16:23:13 +0200504
505 while (snd_ctl_find_id(state->chip->card, &kctl->id))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 kctl->id.index++;
Clemens Ladisch84957a82005-04-29 16:23:13 +0200507 if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
Clemens Ladisch6639b6c2005-04-29 16:26:14 +0200509 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
Clemens Ladisch6639b6c2005-04-29 16:26:14 +0200511 cval->elem_id = &kctl->id;
512 cval->next_id_elem = state->mixer->id_elems[cval->id];
513 state->mixer->id_elems[cval->id] = cval;
514 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515}
516
517
518/*
519 * get a terminal name string
520 */
521
522static struct iterm_name_combo {
523 int type;
524 char *name;
525} iterm_names[] = {
526 { 0x0300, "Output" },
527 { 0x0301, "Speaker" },
528 { 0x0302, "Headphone" },
529 { 0x0303, "HMD Audio" },
530 { 0x0304, "Desktop Speaker" },
531 { 0x0305, "Room Speaker" },
532 { 0x0306, "Com Speaker" },
533 { 0x0307, "LFE" },
534 { 0x0600, "External In" },
535 { 0x0601, "Analog In" },
536 { 0x0602, "Digital In" },
537 { 0x0603, "Line" },
538 { 0x0604, "Legacy In" },
539 { 0x0605, "IEC958 In" },
540 { 0x0606, "1394 DA Stream" },
541 { 0x0607, "1394 DV Stream" },
542 { 0x0700, "Embedded" },
543 { 0x0701, "Noise Source" },
544 { 0x0702, "Equalization Noise" },
545 { 0x0703, "CD" },
546 { 0x0704, "DAT" },
547 { 0x0705, "DCC" },
548 { 0x0706, "MiniDisk" },
549 { 0x0707, "Analog Tape" },
550 { 0x0708, "Phonograph" },
551 { 0x0709, "VCR Audio" },
552 { 0x070a, "Video Disk Audio" },
553 { 0x070b, "DVD Audio" },
554 { 0x070c, "TV Tuner Audio" },
555 { 0x070d, "Satellite Rec Audio" },
556 { 0x070e, "Cable Tuner Audio" },
557 { 0x070f, "DSS Audio" },
558 { 0x0710, "Radio Receiver" },
559 { 0x0711, "Radio Transmitter" },
560 { 0x0712, "Multi-Track Recorder" },
561 { 0x0713, "Synthesizer" },
562 { 0 },
563};
564
Takashi Iwai86e07d32005-11-17 15:08:02 +0100565static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 unsigned char *name, int maxlen, int term_only)
567{
568 struct iterm_name_combo *names;
569
570 if (iterm->name)
571 return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
572
573 /* virtual type - not a real terminal */
574 if (iterm->type >> 16) {
575 if (term_only)
576 return 0;
577 switch (iterm->type >> 16) {
578 case SELECTOR_UNIT:
579 strcpy(name, "Selector"); return 8;
580 case PROCESSING_UNIT:
581 strcpy(name, "Process Unit"); return 12;
582 case EXTENSION_UNIT:
583 strcpy(name, "Ext Unit"); return 8;
584 case MIXER_UNIT:
585 strcpy(name, "Mixer"); return 5;
586 default:
587 return sprintf(name, "Unit %d", iterm->id);
588 }
589 }
590
591 switch (iterm->type & 0xff00) {
592 case 0x0100:
593 strcpy(name, "PCM"); return 3;
594 case 0x0200:
595 strcpy(name, "Mic"); return 3;
596 case 0x0400:
597 strcpy(name, "Headset"); return 7;
598 case 0x0500:
599 strcpy(name, "Phone"); return 5;
600 }
601
602 for (names = iterm_names; names->type; names++)
603 if (names->type == iterm->type) {
604 strcpy(name, names->name);
605 return strlen(names->name);
606 }
607 return 0;
608}
609
610
611/*
612 * parse the source unit recursively until it reaches to a terminal
613 * or a branched unit.
614 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100615static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616{
617 unsigned char *p1;
618
619 memset(term, 0, sizeof(*term));
620 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
621 term->id = id;
622 switch (p1[2]) {
623 case INPUT_TERMINAL:
624 term->type = combine_word(p1 + 4);
625 term->channels = p1[7];
626 term->chconfig = combine_word(p1 + 8);
627 term->name = p1[11];
628 return 0;
629 case FEATURE_UNIT:
630 id = p1[4];
631 break; /* continue to parse */
632 case MIXER_UNIT:
633 term->type = p1[2] << 16; /* virtual type */
634 term->channels = p1[5 + p1[4]];
635 term->chconfig = combine_word(p1 + 6 + p1[4]);
636 term->name = p1[p1[0] - 1];
637 return 0;
638 case SELECTOR_UNIT:
639 /* call recursively to retrieve the channel info */
640 if (check_input_term(state, p1[5], term) < 0)
641 return -ENODEV;
642 term->type = p1[2] << 16; /* virtual type */
643 term->id = id;
644 term->name = p1[9 + p1[0] - 1];
645 return 0;
646 case PROCESSING_UNIT:
647 case EXTENSION_UNIT:
648 if (p1[6] == 1) {
649 id = p1[7];
650 break; /* continue to parse */
651 }
652 term->type = p1[2] << 16; /* virtual type */
653 term->channels = p1[7 + p1[6]];
654 term->chconfig = combine_word(p1 + 8 + p1[6]);
655 term->name = p1[12 + p1[6] + p1[11 + p1[6]]];
656 return 0;
657 default:
658 return -ENODEV;
659 }
660 }
661 return -ENODEV;
662}
663
664
665/*
666 * Feature Unit
667 */
668
669/* feature unit control information */
670struct usb_feature_control_info {
671 const char *name;
672 unsigned int type; /* control type (mute, volume, etc.) */
673};
674
675static struct usb_feature_control_info audio_feature_info[] = {
676 { "Mute", USB_MIXER_INV_BOOLEAN },
677 { "Volume", USB_MIXER_S16 },
678 { "Tone Control - Bass", USB_MIXER_S8 },
679 { "Tone Control - Mid", USB_MIXER_S8 },
680 { "Tone Control - Treble", USB_MIXER_S8 },
681 { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */
682 { "Auto Gain Control", USB_MIXER_BOOLEAN },
683 { "Delay Control", USB_MIXER_U16 },
684 { "Bass Boost", USB_MIXER_BOOLEAN },
685 { "Loudness", USB_MIXER_BOOLEAN },
686};
687
688
689/* private_free callback */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100690static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691{
Jesper Juhl4d572772005-05-30 17:30:32 +0200692 kfree(kctl->private_data);
693 kctl->private_data = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694}
695
696
697/*
698 * interface to ALSA control for feature/mixer units
699 */
700
701/*
702 * retrieve the minimum and maximum values for the specified control
703 */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100704static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705{
706 /* for failsafe */
707 cval->min = default_min;
708 cval->max = cval->min + 1;
709 cval->res = 1;
710
711 if (cval->val_type == USB_MIXER_BOOLEAN ||
712 cval->val_type == USB_MIXER_INV_BOOLEAN) {
713 cval->initialized = 1;
714 } else {
715 int minchn = 0;
716 if (cval->cmask) {
717 int i;
718 for (i = 0; i < MAX_CHANNELS; i++)
719 if (cval->cmask & (1 << i)) {
720 minchn = i + 1;
721 break;
722 }
723 }
724 if (get_ctl_value(cval, GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
725 get_ctl_value(cval, GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
Clemens Ladisch84957a82005-04-29 16:23:13 +0200726 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
727 cval->id, cval->mixer->ctrlif, cval->control, cval->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 return -EINVAL;
729 }
730 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
731 cval->res = 1;
732 } else {
733 int last_valid_res = cval->res;
734
735 while (cval->res > 1) {
736 if (set_ctl_value(cval, SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0)
737 break;
738 cval->res /= 2;
739 }
740 if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
741 cval->res = last_valid_res;
742 }
743 if (cval->res == 0)
744 cval->res = 1;
Takashi Iwai14790f12006-03-28 17:58:28 +0200745
746 /* Additional checks for the proper resolution
747 *
748 * Some devices report smaller resolutions than actually
749 * reacting. They don't return errors but simply clip
750 * to the lower aligned value.
751 */
752 if (cval->min + cval->res < cval->max) {
753 int last_valid_res = cval->res;
754 int saved, test, check;
Takashi Iwai641b4872009-01-15 17:05:24 +0100755 get_cur_mix_raw(cval, minchn, &saved);
Takashi Iwai14790f12006-03-28 17:58:28 +0200756 for (;;) {
757 test = saved;
758 if (test < cval->max)
759 test += cval->res;
760 else
761 test -= cval->res;
762 if (test < cval->min || test > cval->max ||
Takashi Iwai641b4872009-01-15 17:05:24 +0100763 set_cur_mix_value(cval, minchn, 0, test) ||
764 get_cur_mix_raw(cval, minchn, &check)) {
Takashi Iwai14790f12006-03-28 17:58:28 +0200765 cval->res = last_valid_res;
766 break;
767 }
768 if (test == check)
769 break;
770 cval->res *= 2;
771 }
Takashi Iwai641b4872009-01-15 17:05:24 +0100772 set_cur_mix_value(cval, minchn, 0, saved);
Takashi Iwai14790f12006-03-28 17:58:28 +0200773 }
774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 cval->initialized = 1;
776 }
777 return 0;
778}
779
780
781/* get a feature/mixer unit info */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100782static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783{
Takashi Iwai86e07d32005-11-17 15:08:02 +0100784 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786 if (cval->val_type == USB_MIXER_BOOLEAN ||
787 cval->val_type == USB_MIXER_INV_BOOLEAN)
788 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
789 else
790 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
791 uinfo->count = cval->channels;
792 if (cval->val_type == USB_MIXER_BOOLEAN ||
793 cval->val_type == USB_MIXER_INV_BOOLEAN) {
794 uinfo->value.integer.min = 0;
795 uinfo->value.integer.max = 1;
796 } else {
797 if (! cval->initialized)
798 get_min_max(cval, 0);
799 uinfo->value.integer.min = 0;
Takashi Iwai14790f12006-03-28 17:58:28 +0200800 uinfo->value.integer.max =
801 (cval->max - cval->min + cval->res - 1) / cval->res;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 }
803 return 0;
804}
805
806/* get the current value from feature/mixer unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100807static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808{
Takashi Iwai86e07d32005-11-17 15:08:02 +0100809 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 int c, cnt, val, err;
811
Takashi Iwai641b4872009-01-15 17:05:24 +0100812 ucontrol->value.integer.value[0] = cval->min;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 if (cval->cmask) {
814 cnt = 0;
815 for (c = 0; c < MAX_CHANNELS; c++) {
Takashi Iwai641b4872009-01-15 17:05:24 +0100816 if (!(cval->cmask & (1 << c)))
817 continue;
818 err = get_cur_mix_value(cval, c + 1, cnt, &val);
819 if (err < 0)
820 return cval->mixer->ignore_ctl_error ? 0 : err;
821 val = get_relative_value(cval, val);
822 ucontrol->value.integer.value[cnt] = val;
823 cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 }
Takashi Iwai641b4872009-01-15 17:05:24 +0100825 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 } else {
827 /* master channel */
Takashi Iwai641b4872009-01-15 17:05:24 +0100828 err = get_cur_mix_value(cval, 0, 0, &val);
829 if (err < 0)
830 return cval->mixer->ignore_ctl_error ? 0 : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 val = get_relative_value(cval, val);
832 ucontrol->value.integer.value[0] = val;
833 }
834 return 0;
835}
836
837/* put the current value to feature/mixer unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +0100838static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
Takashi Iwai86e07d32005-11-17 15:08:02 +0100840 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 int c, cnt, val, oval, err;
842 int changed = 0;
843
844 if (cval->cmask) {
845 cnt = 0;
846 for (c = 0; c < MAX_CHANNELS; c++) {
Takashi Iwai641b4872009-01-15 17:05:24 +0100847 if (!(cval->cmask & (1 << c)))
848 continue;
849 err = get_cur_mix_value(cval, c + 1, cnt, &oval);
850 if (err < 0)
851 return cval->mixer->ignore_ctl_error ? 0 : err;
852 val = ucontrol->value.integer.value[cnt];
853 val = get_abs_value(cval, val);
854 if (oval != val) {
855 set_cur_mix_value(cval, c + 1, cnt, val);
856 changed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 }
Takashi Iwai641b4872009-01-15 17:05:24 +0100858 cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 }
860 } else {
861 /* master channel */
Takashi Iwai641b4872009-01-15 17:05:24 +0100862 err = get_cur_mix_value(cval, 0, 0, &oval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 if (err < 0)
Takashi Iwai641b4872009-01-15 17:05:24 +0100864 return cval->mixer->ignore_ctl_error ? 0 : err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 val = ucontrol->value.integer.value[0];
866 val = get_abs_value(cval, val);
867 if (val != oval) {
Takashi Iwai641b4872009-01-15 17:05:24 +0100868 set_cur_mix_value(cval, 0, 0, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 changed = 1;
870 }
871 }
872 return changed;
873}
874
Takashi Iwai86e07d32005-11-17 15:08:02 +0100875static struct snd_kcontrol_new usb_feature_unit_ctl = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 .name = "", /* will be filled later manually */
878 .info = mixer_ctl_feature_info,
879 .get = mixer_ctl_feature_get,
880 .put = mixer_ctl_feature_put,
881};
882
883
884/*
885 * build a feature control
886 */
887
Takashi Iwai86e07d32005-11-17 15:08:02 +0100888static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 unsigned int ctl_mask, int control,
Takashi Iwai86e07d32005-11-17 15:08:02 +0100890 struct usb_audio_term *iterm, int unitid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891{
892 unsigned int len = 0;
893 int mapped_name = 0;
894 int nameid = desc[desc[0] - 1];
Takashi Iwai86e07d32005-11-17 15:08:02 +0100895 struct snd_kcontrol *kctl;
896 struct usb_mixer_elem_info *cval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898 control++; /* change from zero-based to 1-based value */
899
900 if (control == USB_FEATURE_GEQ) {
901 /* FIXME: not supported yet */
902 return;
903 }
904
905 if (check_ignored_ctl(state, unitid, control))
906 return;
907
Takashi Iwai561b2202005-09-09 14:22:34 +0200908 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 if (! cval) {
910 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
911 return;
912 }
Clemens Ladisch84957a82005-04-29 16:23:13 +0200913 cval->mixer = state->mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 cval->id = unitid;
915 cval->control = control;
916 cval->cmask = ctl_mask;
917 cval->val_type = audio_feature_info[control-1].type;
918 if (ctl_mask == 0)
919 cval->channels = 1; /* master channel */
920 else {
921 int i, c = 0;
922 for (i = 0; i < 16; i++)
923 if (ctl_mask & (1 << i))
924 c++;
925 cval->channels = c;
926 }
927
928 /* get min/max values */
929 get_min_max(cval, 0);
930
931 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
932 if (! kctl) {
933 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
934 kfree(cval);
935 return;
936 }
937 kctl->private_free = usb_mixer_elem_free;
938
939 len = check_mapped_name(state, unitid, control, kctl->id.name, sizeof(kctl->id.name));
940 mapped_name = len != 0;
941 if (! len && nameid)
942 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
943
944 switch (control) {
945 case USB_FEATURE_MUTE:
946 case USB_FEATURE_VOLUME:
947 /* determine the control name. the rule is:
948 * - if a name id is given in descriptor, use it.
949 * - if the connected input can be determined, then use the name
950 * of terminal type.
951 * - if the connected output can be determined, use it.
952 * - otherwise, anonymous name.
953 */
954 if (! len) {
955 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
956 if (! len)
957 len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
958 if (! len)
959 len = snprintf(kctl->id.name, sizeof(kctl->id.name),
960 "Feature %d", unitid);
961 }
962 /* determine the stream direction:
963 * if the connected output is USB stream, then it's likely a
964 * capture stream. otherwise it should be playback (hopefully :)
965 */
966 if (! mapped_name && ! (state->oterm.type >> 16)) {
967 if ((state->oterm.type & 0xff00) == 0x0100) {
968 len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name));
969 } else {
970 len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name));
971 }
972 }
973 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume",
974 sizeof(kctl->id.name));
Takashi Iwai7bc5ba72006-07-14 15:18:19 +0200975 if (control == USB_FEATURE_VOLUME) {
976 kctl->tlv.c = mixer_vol_tlv;
977 kctl->vd[0].access |=
978 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
979 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
980 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 break;
982
983 default:
984 if (! len)
985 strlcpy(kctl->id.name, audio_feature_info[control-1].name,
986 sizeof(kctl->id.name));
987 break;
988 }
989
990 /* quirk for UDA1321/N101 */
991 /* note that detection between firmware 2.1.1.7 (N101) and later 2.1.1.21 */
992 /* is not very clear from datasheets */
993 /* I hope that the min value is -15360 for newer firmware --jk */
Clemens Ladisch27d10f52005-05-02 08:51:26 +0200994 switch (state->chip->usb_id) {
995 case USB_ID(0x0471, 0x0101):
996 case USB_ID(0x0471, 0x0104):
997 case USB_ID(0x0471, 0x0105):
998 case USB_ID(0x0672, 0x1041):
999 if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
1000 cval->min == -15616) {
Takashi Iwaid3d579f2005-10-21 16:20:11 +02001001 snd_printk(KERN_INFO "using volume control quirk for the UDA1321/N101 chip\n");
Clemens Ladisch27d10f52005-05-02 08:51:26 +02001002 cval->max = -256;
1003 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 }
1005
1006 snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
1007 cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001008 add_control_to_empty(state, kctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009}
1010
1011
1012
1013/*
1014 * parse a feature unit
1015 *
1016 * most of controlls are defined here.
1017 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001018static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019{
1020 int channels, i, j;
Takashi Iwai86e07d32005-11-17 15:08:02 +01001021 struct usb_audio_term iterm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 unsigned int master_bits, first_ch_bits;
1023 int err, csize;
1024
1025 if (ftr[0] < 7 || ! (csize = ftr[5]) || ftr[0] < 7 + csize) {
1026 snd_printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
1027 return -EINVAL;
1028 }
1029
1030 /* parse the source unit */
1031 if ((err = parse_audio_unit(state, ftr[4])) < 0)
1032 return err;
1033
1034 /* determine the input source type and name */
1035 if (check_input_term(state, ftr[4], &iterm) < 0)
1036 return -EINVAL;
1037
1038 channels = (ftr[0] - 7) / csize - 1;
1039
1040 master_bits = snd_usb_combine_bytes(ftr + 6, csize);
1041 if (channels > 0)
1042 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize);
1043 else
1044 first_ch_bits = 0;
1045 /* check all control types */
1046 for (i = 0; i < 10; i++) {
1047 unsigned int ch_bits = 0;
1048 for (j = 0; j < channels; j++) {
1049 unsigned int mask = snd_usb_combine_bytes(ftr + 6 + csize * (j+1), csize);
1050 if (mask & (1 << i))
1051 ch_bits |= (1 << j);
1052 }
1053 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1054 build_feature_ctl(state, ftr, ch_bits, i, &iterm, unitid);
1055 if (master_bits & (1 << i))
1056 build_feature_ctl(state, ftr, 0, i, &iterm, unitid);
1057 }
1058
1059 return 0;
1060}
1061
1062
1063/*
1064 * Mixer Unit
1065 */
1066
1067/*
1068 * build a mixer unit control
1069 *
1070 * the callbacks are identical with feature unit.
1071 * input channel number (zero based) is given in control field instead.
1072 */
1073
Takashi Iwai86e07d32005-11-17 15:08:02 +01001074static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 int in_pin, int in_ch, int unitid,
Takashi Iwai86e07d32005-11-17 15:08:02 +01001076 struct usb_audio_term *iterm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001078 struct usb_mixer_elem_info *cval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 unsigned int input_pins = desc[4];
1080 unsigned int num_outs = desc[5 + input_pins];
1081 unsigned int i, len;
Takashi Iwai86e07d32005-11-17 15:08:02 +01001082 struct snd_kcontrol *kctl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
1084 if (check_ignored_ctl(state, unitid, 0))
1085 return;
1086
Takashi Iwai561b2202005-09-09 14:22:34 +02001087 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 if (! cval)
1089 return;
1090
Clemens Ladisch84957a82005-04-29 16:23:13 +02001091 cval->mixer = state->mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 cval->id = unitid;
1093 cval->control = in_ch + 1; /* based on 1 */
1094 cval->val_type = USB_MIXER_S16;
1095 for (i = 0; i < num_outs; i++) {
1096 if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) {
1097 cval->cmask |= (1 << i);
1098 cval->channels++;
1099 }
1100 }
1101
1102 /* get min/max values */
1103 get_min_max(cval, 0);
1104
1105 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1106 if (! kctl) {
1107 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
1108 kfree(cval);
1109 return;
1110 }
1111 kctl->private_free = usb_mixer_elem_free;
1112
1113 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
1114 if (! len)
1115 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
1116 if (! len)
1117 len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
1118 strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name));
1119
1120 snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
1121 cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001122 add_control_to_empty(state, kctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123}
1124
1125
1126/*
1127 * parse a mixer unit
1128 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001129static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001131 struct usb_audio_term iterm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 int input_pins, num_ins, num_outs;
1133 int pin, ich, err;
1134
1135 if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) {
1136 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
1137 return -EINVAL;
1138 }
1139 /* no bmControls field (e.g. Maya44) -> ignore */
1140 if (desc[0] <= 10 + input_pins) {
1141 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
1142 return 0;
1143 }
1144
1145 num_ins = 0;
1146 ich = 0;
1147 for (pin = 0; pin < input_pins; pin++) {
1148 err = parse_audio_unit(state, desc[5 + pin]);
1149 if (err < 0)
1150 return err;
1151 err = check_input_term(state, desc[5 + pin], &iterm);
1152 if (err < 0)
1153 return err;
1154 num_ins += iterm.channels;
1155 for (; ich < num_ins; ++ich) {
1156 int och, ich_has_controls = 0;
1157
1158 for (och = 0; och < num_outs; ++och) {
1159 if (check_matrix_bitmap(desc + 9 + input_pins,
1160 ich, och, num_outs)) {
1161 ich_has_controls = 1;
1162 break;
1163 }
1164 }
1165 if (ich_has_controls)
1166 build_mixer_unit_ctl(state, desc, pin, ich,
1167 unitid, &iterm);
1168 }
1169 }
1170 return 0;
1171}
1172
1173
1174/*
1175 * Processing Unit / Extension Unit
1176 */
1177
1178/* get callback for processing/extension unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001179static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001181 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 int err, val;
1183
1184 err = get_cur_ctl_value(cval, cval->control << 8, &val);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001185 if (err < 0 && cval->mixer->ignore_ctl_error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 ucontrol->value.integer.value[0] = cval->min;
1187 return 0;
1188 }
1189 if (err < 0)
1190 return err;
1191 val = get_relative_value(cval, val);
1192 ucontrol->value.integer.value[0] = val;
1193 return 0;
1194}
1195
1196/* put callback for processing/extension unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001197static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001199 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 int val, oval, err;
1201
1202 err = get_cur_ctl_value(cval, cval->control << 8, &oval);
1203 if (err < 0) {
Clemens Ladisch84957a82005-04-29 16:23:13 +02001204 if (cval->mixer->ignore_ctl_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 return 0;
1206 return err;
1207 }
1208 val = ucontrol->value.integer.value[0];
1209 val = get_abs_value(cval, val);
1210 if (val != oval) {
1211 set_cur_ctl_value(cval, cval->control << 8, val);
1212 return 1;
1213 }
1214 return 0;
1215}
1216
1217/* alsa control interface for processing/extension unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001218static struct snd_kcontrol_new mixer_procunit_ctl = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1220 .name = "", /* will be filled later */
1221 .info = mixer_ctl_feature_info,
1222 .get = mixer_ctl_procunit_get,
1223 .put = mixer_ctl_procunit_put,
1224};
1225
1226
1227/*
1228 * predefined data for processing units
1229 */
1230struct procunit_value_info {
1231 int control;
1232 char *suffix;
1233 int val_type;
1234 int min_value;
1235};
1236
1237struct procunit_info {
1238 int type;
1239 char *name;
1240 struct procunit_value_info *values;
1241};
1242
1243static struct procunit_value_info updown_proc_info[] = {
1244 { USB_PROC_UPDOWN_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1245 { USB_PROC_UPDOWN_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 },
1246 { 0 }
1247};
1248static struct procunit_value_info prologic_proc_info[] = {
1249 { USB_PROC_PROLOGIC_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1250 { USB_PROC_PROLOGIC_MODE_SEL, "Mode Select", USB_MIXER_U8, 1 },
1251 { 0 }
1252};
1253static struct procunit_value_info threed_enh_proc_info[] = {
1254 { USB_PROC_3DENH_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1255 { USB_PROC_3DENH_SPACE, "Spaciousness", USB_MIXER_U8 },
1256 { 0 }
1257};
1258static struct procunit_value_info reverb_proc_info[] = {
1259 { USB_PROC_REVERB_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1260 { USB_PROC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
1261 { USB_PROC_REVERB_TIME, "Time", USB_MIXER_U16 },
1262 { USB_PROC_REVERB_DELAY, "Delay", USB_MIXER_U8 },
1263 { 0 }
1264};
1265static struct procunit_value_info chorus_proc_info[] = {
1266 { USB_PROC_CHORUS_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1267 { USB_PROC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
1268 { USB_PROC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
1269 { USB_PROC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
1270 { 0 }
1271};
1272static struct procunit_value_info dcr_proc_info[] = {
1273 { USB_PROC_DCR_SWITCH, "Switch", USB_MIXER_BOOLEAN },
1274 { USB_PROC_DCR_RATIO, "Ratio", USB_MIXER_U16 },
1275 { USB_PROC_DCR_MAX_AMP, "Max Amp", USB_MIXER_S16 },
1276 { USB_PROC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
1277 { USB_PROC_DCR_ATTACK, "Attack Time", USB_MIXER_U16 },
1278 { USB_PROC_DCR_RELEASE, "Release Time", USB_MIXER_U16 },
1279 { 0 }
1280};
1281
1282static struct procunit_info procunits[] = {
1283 { USB_PROC_UPDOWN, "Up Down", updown_proc_info },
1284 { USB_PROC_PROLOGIC, "Dolby Prologic", prologic_proc_info },
1285 { USB_PROC_3DENH, "3D Stereo Extender", threed_enh_proc_info },
1286 { USB_PROC_REVERB, "Reverb", reverb_proc_info },
1287 { USB_PROC_CHORUS, "Chorus", chorus_proc_info },
1288 { USB_PROC_DCR, "DCR", dcr_proc_info },
1289 { 0 },
1290};
1291
1292/*
1293 * build a processing/extension unit
1294 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001295static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296{
1297 int num_ins = dsc[6];
Takashi Iwai86e07d32005-11-17 15:08:02 +01001298 struct usb_mixer_elem_info *cval;
1299 struct snd_kcontrol *kctl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 int i, err, nameid, type, len;
1301 struct procunit_info *info;
1302 struct procunit_value_info *valinfo;
1303 static struct procunit_value_info default_value_info[] = {
1304 { 0x01, "Switch", USB_MIXER_BOOLEAN },
1305 { 0 }
1306 };
1307 static struct procunit_info default_info = {
1308 0, NULL, default_value_info
1309 };
1310
1311 if (dsc[0] < 13 || dsc[0] < 13 + num_ins || dsc[0] < num_ins + dsc[11 + num_ins]) {
1312 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
1313 return -EINVAL;
1314 }
1315
1316 for (i = 0; i < num_ins; i++) {
1317 if ((err = parse_audio_unit(state, dsc[7 + i])) < 0)
1318 return err;
1319 }
1320
1321 type = combine_word(&dsc[4]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 for (info = list; info && info->type; info++)
1323 if (info->type == type)
1324 break;
1325 if (! info || ! info->type)
1326 info = &default_info;
1327
1328 for (valinfo = info->values; valinfo->control; valinfo++) {
1329 /* FIXME: bitmap might be longer than 8bit */
1330 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1))))
1331 continue;
1332 if (check_ignored_ctl(state, unitid, valinfo->control))
1333 continue;
Takashi Iwai561b2202005-09-09 14:22:34 +02001334 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 if (! cval) {
1336 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
1337 return -ENOMEM;
1338 }
Clemens Ladisch84957a82005-04-29 16:23:13 +02001339 cval->mixer = state->mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 cval->id = unitid;
1341 cval->control = valinfo->control;
1342 cval->val_type = valinfo->val_type;
1343 cval->channels = 1;
1344
1345 /* get min/max values */
1346 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) {
1347 /* FIXME: hard-coded */
1348 cval->min = 1;
1349 cval->max = dsc[15];
1350 cval->res = 1;
1351 cval->initialized = 1;
1352 } else
1353 get_min_max(cval, valinfo->min_value);
1354
1355 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
1356 if (! kctl) {
1357 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
1358 kfree(cval);
1359 return -ENOMEM;
1360 }
1361 kctl->private_free = usb_mixer_elem_free;
1362
1363 if (check_mapped_name(state, unitid, cval->control, kctl->id.name, sizeof(kctl->id.name)))
1364 ;
1365 else if (info->name)
1366 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1367 else {
1368 nameid = dsc[12 + num_ins + dsc[11 + num_ins]];
1369 len = 0;
1370 if (nameid)
1371 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
1372 if (! len)
1373 strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
1374 }
1375 strlcat(kctl->id.name, " ", sizeof(kctl->id.name));
1376 strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name));
1377
1378 snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
1379 cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001380 if ((err = add_control_to_empty(state, kctl)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 return err;
1382 }
1383 return 0;
1384}
1385
1386
Takashi Iwai86e07d32005-11-17 15:08:02 +01001387static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388{
1389 return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit");
1390}
1391
Takashi Iwai86e07d32005-11-17 15:08:02 +01001392static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393{
1394 return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit");
1395}
1396
1397
1398/*
1399 * Selector Unit
1400 */
1401
1402/* info callback for selector unit
1403 * use an enumerator type for routing
1404 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001405static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001407 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 char **itemlist = (char **)kcontrol->private_value;
1409
Takashi Iwai5e246b82008-08-08 17:12:47 +02001410 if (snd_BUG_ON(!itemlist))
1411 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1413 uinfo->count = 1;
1414 uinfo->value.enumerated.items = cval->max;
1415 if ((int)uinfo->value.enumerated.item >= cval->max)
1416 uinfo->value.enumerated.item = cval->max - 1;
1417 strcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item]);
1418 return 0;
1419}
1420
1421/* get callback for selector unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001422static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001424 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 int val, err;
1426
1427 err = get_cur_ctl_value(cval, 0, &val);
1428 if (err < 0) {
Clemens Ladisch84957a82005-04-29 16:23:13 +02001429 if (cval->mixer->ignore_ctl_error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 ucontrol->value.enumerated.item[0] = 0;
1431 return 0;
1432 }
1433 return err;
1434 }
1435 val = get_relative_value(cval, val);
1436 ucontrol->value.enumerated.item[0] = val;
1437 return 0;
1438}
1439
1440/* put callback for selector unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001441static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001443 struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 int val, oval, err;
1445
1446 err = get_cur_ctl_value(cval, 0, &oval);
1447 if (err < 0) {
Clemens Ladisch84957a82005-04-29 16:23:13 +02001448 if (cval->mixer->ignore_ctl_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 return 0;
1450 return err;
1451 }
1452 val = ucontrol->value.enumerated.item[0];
1453 val = get_abs_value(cval, val);
1454 if (val != oval) {
1455 set_cur_ctl_value(cval, 0, val);
1456 return 1;
1457 }
1458 return 0;
1459}
1460
1461/* alsa control interface for selector unit */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001462static struct snd_kcontrol_new mixer_selectunit_ctl = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1464 .name = "", /* will be filled later */
1465 .info = mixer_ctl_selector_info,
1466 .get = mixer_ctl_selector_get,
1467 .put = mixer_ctl_selector_put,
1468};
1469
1470
1471/* private free callback.
1472 * free both private_data and private_value
1473 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001474static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475{
1476 int i, num_ins = 0;
1477
1478 if (kctl->private_data) {
Takashi Iwai86e07d32005-11-17 15:08:02 +01001479 struct usb_mixer_elem_info *cval = kctl->private_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 num_ins = cval->max;
1481 kfree(cval);
1482 kctl->private_data = NULL;
1483 }
1484 if (kctl->private_value) {
1485 char **itemlist = (char **)kctl->private_value;
1486 for (i = 0; i < num_ins; i++)
1487 kfree(itemlist[i]);
1488 kfree(itemlist);
1489 kctl->private_value = 0;
1490 }
1491}
1492
1493/*
1494 * parse a selector unit
1495 */
Takashi Iwai86e07d32005-11-17 15:08:02 +01001496static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497{
1498 unsigned int num_ins = desc[4];
1499 unsigned int i, nameid, len;
1500 int err;
Takashi Iwai86e07d32005-11-17 15:08:02 +01001501 struct usb_mixer_elem_info *cval;
1502 struct snd_kcontrol *kctl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 char **namelist;
1504
Russ Cox38977e92007-08-06 15:37:58 +02001505 if (! num_ins || desc[0] < 5 + num_ins) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
1507 return -EINVAL;
1508 }
1509
1510 for (i = 0; i < num_ins; i++) {
1511 if ((err = parse_audio_unit(state, desc[5 + i])) < 0)
1512 return err;
1513 }
1514
1515 if (num_ins == 1) /* only one ? nonsense! */
1516 return 0;
1517
1518 if (check_ignored_ctl(state, unitid, 0))
1519 return 0;
1520
Takashi Iwai561b2202005-09-09 14:22:34 +02001521 cval = kzalloc(sizeof(*cval), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 if (! cval) {
1523 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
1524 return -ENOMEM;
1525 }
Clemens Ladisch84957a82005-04-29 16:23:13 +02001526 cval->mixer = state->mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 cval->id = unitid;
1528 cval->val_type = USB_MIXER_U8;
1529 cval->channels = 1;
1530 cval->min = 1;
1531 cval->max = num_ins;
1532 cval->res = 1;
1533 cval->initialized = 1;
1534
1535 namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL);
1536 if (! namelist) {
1537 snd_printk(KERN_ERR "cannot malloc\n");
1538 kfree(cval);
1539 return -ENOMEM;
1540 }
1541#define MAX_ITEM_NAME_LEN 64
1542 for (i = 0; i < num_ins; i++) {
Takashi Iwai86e07d32005-11-17 15:08:02 +01001543 struct usb_audio_term iterm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 len = 0;
1545 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
1546 if (! namelist[i]) {
1547 snd_printk(KERN_ERR "cannot malloc\n");
Mariusz Kozlowski7fbe3ca2007-01-08 11:25:30 +01001548 while (i--)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 kfree(namelist[i]);
1550 kfree(namelist);
1551 kfree(cval);
1552 return -ENOMEM;
1553 }
Clemens Ladisch8e062ec2005-04-22 15:49:52 +02001554 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1555 MAX_ITEM_NAME_LEN);
1556 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1558 if (! len)
1559 sprintf(namelist[i], "Input %d", i);
1560 }
1561
1562 kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
1563 if (! kctl) {
1564 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
Jesper Juhl878b4782006-03-20 11:27:13 +01001565 kfree(namelist);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 kfree(cval);
1567 return -ENOMEM;
1568 }
1569 kctl->private_value = (unsigned long)namelist;
1570 kctl->private_free = usb_mixer_selector_elem_free;
1571
1572 nameid = desc[desc[0] - 1];
1573 len = check_mapped_name(state, unitid, 0, kctl->id.name, sizeof(kctl->id.name));
1574 if (len)
1575 ;
1576 else if (nameid)
1577 snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
1578 else {
1579 len = get_term_name(state, &state->oterm,
1580 kctl->id.name, sizeof(kctl->id.name), 0);
1581 if (! len)
1582 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
1583
1584 if ((state->oterm.type & 0xff00) == 0x0100)
1585 strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name));
1586 else
1587 strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name));
1588 }
1589
1590 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
1591 cval->id, kctl->id.name, num_ins);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001592 if ((err = add_control_to_empty(state, kctl)) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 return err;
1594
1595 return 0;
1596}
1597
1598
1599/*
1600 * parse an audio unit recursively
1601 */
1602
Takashi Iwai86e07d32005-11-17 15:08:02 +01001603static int parse_audio_unit(struct mixer_build *state, int unitid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604{
1605 unsigned char *p1;
1606
1607 if (test_and_set_bit(unitid, state->unitbitmap))
1608 return 0; /* the unit already visited */
1609
1610 p1 = find_audio_control_unit(state, unitid);
1611 if (!p1) {
1612 snd_printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
1613 return -EINVAL;
1614 }
1615
1616 switch (p1[2]) {
1617 case INPUT_TERMINAL:
1618 return 0; /* NOP */
1619 case MIXER_UNIT:
1620 return parse_audio_mixer_unit(state, unitid, p1);
1621 case SELECTOR_UNIT:
1622 return parse_audio_selector_unit(state, unitid, p1);
1623 case FEATURE_UNIT:
1624 return parse_audio_feature_unit(state, unitid, p1);
1625 case PROCESSING_UNIT:
1626 return parse_audio_processing_unit(state, unitid, p1);
1627 case EXTENSION_UNIT:
1628 return parse_audio_extension_unit(state, unitid, p1);
1629 default:
1630 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
1631 return -EINVAL;
1632 }
1633}
1634
Clemens Ladisch84957a82005-04-29 16:23:13 +02001635static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
1636{
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001637 kfree(mixer->id_elems);
1638 if (mixer->urb) {
1639 kfree(mixer->urb->transfer_buffer);
1640 usb_free_urb(mixer->urb);
1641 }
Mariusz Kozlowski68df9de2006-11-08 15:37:04 +01001642 usb_free_urb(mixer->rc_urb);
Clemens Ladischb259b102005-04-29 16:29:28 +02001643 kfree(mixer->rc_setup_packet);
Clemens Ladisch84957a82005-04-29 16:23:13 +02001644 kfree(mixer);
1645}
1646
Takashi Iwai86e07d32005-11-17 15:08:02 +01001647static int snd_usb_mixer_dev_free(struct snd_device *device)
Clemens Ladisch84957a82005-04-29 16:23:13 +02001648{
1649 struct usb_mixer_interface *mixer = device->device_data;
1650 snd_usb_mixer_free(mixer);
1651 return 0;
1652}
1653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654/*
1655 * create mixer controls
1656 *
1657 * walk through all OUTPUT_TERMINAL descriptors to search for mixers
1658 */
Clemens Ladisch84957a82005-04-29 16:23:13 +02001659static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660{
1661 unsigned char *desc;
Takashi Iwai86e07d32005-11-17 15:08:02 +01001662 struct mixer_build state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 int err;
1664 const struct usbmix_ctl_map *map;
Clemens Ladisch84957a82005-04-29 16:23:13 +02001665 struct usb_host_interface *hostif;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
Clemens Ladisch84957a82005-04-29 16:23:13 +02001667 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 memset(&state, 0, sizeof(state));
Clemens Ladisch84957a82005-04-29 16:23:13 +02001669 state.chip = mixer->chip;
1670 state.mixer = mixer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 state.buffer = hostif->extra;
1672 state.buflen = hostif->extralen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
1674 /* check the mapping table */
Clemens Ladisch27d10f52005-05-02 08:51:26 +02001675 for (map = usbmix_ctl_maps; map->id; map++) {
1676 if (map->id == state.chip->usb_id) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 state.map = map->map;
Clemens Ladisch8e062ec2005-04-22 15:49:52 +02001678 state.selector_map = map->selector_map;
Clemens Ladisch84957a82005-04-29 16:23:13 +02001679 mixer->ignore_ctl_error = map->ignore_ctl_error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 break;
1681 }
1682 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
1684 desc = NULL;
1685 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
1686 if (desc[0] < 9)
1687 continue; /* invalid descriptor? */
1688 set_bit(desc[3], state.unitbitmap); /* mark terminal ID as visited */
1689 state.oterm.id = desc[3];
1690 state.oterm.type = combine_word(&desc[4]);
1691 state.oterm.name = desc[8];
1692 err = parse_audio_unit(&state, desc[7]);
1693 if (err < 0)
1694 return err;
1695 }
1696 return 0;
1697}
Clemens Ladisch84957a82005-04-29 16:23:13 +02001698
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001699static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
1700 int unitid)
1701{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001702 struct usb_mixer_elem_info *info;
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001703
1704 for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
1705 snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1706 info->elem_id);
1707}
1708
Clemens Ladischb259b102005-04-29 16:29:28 +02001709static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1710 int unitid)
1711{
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001712 if (!mixer->rc_cfg)
Clemens Ladischaafad562005-05-10 14:47:38 +02001713 return;
1714 /* unit ids specific to Extigy/Audigy 2 NX: */
1715 switch (unitid) {
1716 case 0: /* remote control */
Clemens Ladischb259b102005-04-29 16:29:28 +02001717 mixer->rc_urb->dev = mixer->chip->dev;
1718 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
Clemens Ladischaafad562005-05-10 14:47:38 +02001719 break;
1720 case 4: /* digital in jack */
1721 case 7: /* line in jacks */
1722 case 19: /* speaker out jacks */
1723 case 20: /* headphones out jack */
1724 break;
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01001725 /* live24ext: 4 = line-in jack */
1726 case 3: /* hp-out jack (may actuate Mute) */
1727 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
1728 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1729 break;
Clemens Ladischaafad562005-05-10 14:47:38 +02001730 default:
1731 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
1732 break;
Clemens Ladischb259b102005-04-29 16:29:28 +02001733 }
1734}
1735
David Howells7d12e782006-10-05 14:55:46 +01001736static void snd_usb_mixer_status_complete(struct urb *urb)
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001737{
1738 struct usb_mixer_interface *mixer = urb->context;
1739
1740 if (urb->status == 0) {
1741 u8 *buf = urb->transfer_buffer;
1742 int i;
1743
1744 for (i = urb->actual_length; i >= 2; buf += 2, i -= 2) {
1745 snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
1746 buf[0], buf[1]);
1747 /* ignore any notifications not from the control interface */
1748 if ((buf[0] & 0x0f) != 0)
1749 continue;
1750 if (!(buf[0] & 0x40))
1751 snd_usb_mixer_notify_id(mixer, buf[1]);
Clemens Ladischb259b102005-04-29 16:29:28 +02001752 else
1753 snd_usb_mixer_memory_change(mixer, buf[1]);
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001754 }
1755 }
1756 if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
1757 urb->dev = mixer->chip->dev;
1758 usb_submit_urb(urb, GFP_ATOMIC);
1759 }
1760}
1761
1762/* create the handler for the optional status interrupt endpoint */
1763static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
1764{
1765 struct usb_host_interface *hostif;
1766 struct usb_endpoint_descriptor *ep;
1767 void *transfer_buffer;
1768 int buffer_length;
1769 unsigned int epnum;
1770
1771 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
1772 /* we need one interrupt input endpoint */
1773 if (get_iface_desc(hostif)->bNumEndpoints < 1)
1774 return 0;
1775 ep = get_endpoint(hostif, 0);
Julia Lawall913ae5a2009-01-03 17:54:53 +01001776 if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001777 return 0;
1778
Julia Lawall42a6e662008-12-29 11:23:02 +01001779 epnum = usb_endpoint_num(ep);
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02001780 buffer_length = le16_to_cpu(ep->wMaxPacketSize);
1781 transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
1782 if (!transfer_buffer)
1783 return -ENOMEM;
1784 mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
1785 if (!mixer->urb) {
1786 kfree(transfer_buffer);
1787 return -ENOMEM;
1788 }
1789 usb_fill_int_urb(mixer->urb, mixer->chip->dev,
1790 usb_rcvintpipe(mixer->chip->dev, epnum),
1791 transfer_buffer, buffer_length,
1792 snd_usb_mixer_status_complete, mixer, ep->bInterval);
1793 usb_submit_urb(mixer->urb, GFP_KERNEL);
1794 return 0;
1795}
1796
David Howells7d12e782006-10-05 14:55:46 +01001797static void snd_usb_soundblaster_remote_complete(struct urb *urb)
Clemens Ladischb259b102005-04-29 16:29:28 +02001798{
1799 struct usb_mixer_interface *mixer = urb->context;
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001800 const struct rc_config *rc = mixer->rc_cfg;
Clemens Ladischb259b102005-04-29 16:29:28 +02001801 u32 code;
1802
Phillip Michael Jordanb9c196e2008-08-05 11:01:00 +02001803 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
Clemens Ladischb259b102005-04-29 16:29:28 +02001804 return;
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001805
1806 code = mixer->rc_buffer[rc->offset];
1807 if (rc->length == 2)
1808 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1809
Clemens Ladischb259b102005-04-29 16:29:28 +02001810 /* the Mute button actually changes the mixer control */
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001811 if (code == rc->mute_code)
1812 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
Clemens Ladischb259b102005-04-29 16:29:28 +02001813 mixer->rc_code = code;
1814 wmb();
1815 wake_up(&mixer->rc_waitq);
1816}
1817
Takashi Iwai86e07d32005-11-17 15:08:02 +01001818static int snd_usb_sbrc_hwdep_open(struct snd_hwdep *hw, struct file *file)
Clemens Ladischb259b102005-04-29 16:29:28 +02001819{
1820 struct usb_mixer_interface *mixer = hw->private_data;
1821
1822 if (test_and_set_bit(0, &mixer->rc_hwdep_open))
1823 return -EBUSY;
1824 return 0;
1825}
1826
Takashi Iwai86e07d32005-11-17 15:08:02 +01001827static int snd_usb_sbrc_hwdep_release(struct snd_hwdep *hw, struct file *file)
Clemens Ladischb259b102005-04-29 16:29:28 +02001828{
1829 struct usb_mixer_interface *mixer = hw->private_data;
1830
1831 clear_bit(0, &mixer->rc_hwdep_open);
1832 smp_mb__after_clear_bit();
1833 return 0;
1834}
1835
Takashi Iwai86e07d32005-11-17 15:08:02 +01001836static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
Clemens Ladischb259b102005-04-29 16:29:28 +02001837 long count, loff_t *offset)
1838{
1839 struct usb_mixer_interface *mixer = hw->private_data;
1840 int err;
1841 u32 rc_code;
1842
Clemens Ladisch434b7f52005-05-02 08:58:31 +02001843 if (count != 1 && count != 4)
Clemens Ladischb259b102005-04-29 16:29:28 +02001844 return -EINVAL;
1845 err = wait_event_interruptible(mixer->rc_waitq,
1846 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
1847 if (err == 0) {
Clemens Ladisch434b7f52005-05-02 08:58:31 +02001848 if (count == 1)
1849 err = put_user(rc_code, buf);
1850 else
1851 err = put_user(rc_code, (u32 __user *)buf);
Clemens Ladischb259b102005-04-29 16:29:28 +02001852 }
1853 return err < 0 ? err : count;
1854}
1855
Takashi Iwai86e07d32005-11-17 15:08:02 +01001856static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
Clemens Ladischb259b102005-04-29 16:29:28 +02001857 poll_table *wait)
1858{
1859 struct usb_mixer_interface *mixer = hw->private_data;
1860
1861 poll_wait(file, &mixer->rc_waitq, wait);
1862 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
1863}
1864
1865static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
1866{
Takashi Iwai86e07d32005-11-17 15:08:02 +01001867 struct snd_hwdep *hwdep;
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001868 int err, len, i;
Clemens Ladischb259b102005-04-29 16:29:28 +02001869
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001870 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
1871 if (rc_configs[i].usb_id == mixer->chip->usb_id)
1872 break;
1873 if (i >= ARRAY_SIZE(rc_configs))
Clemens Ladischb259b102005-04-29 16:29:28 +02001874 return 0;
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001875 mixer->rc_cfg = &rc_configs[i];
Clemens Ladischb259b102005-04-29 16:29:28 +02001876
Raimonds Cicans4d1a70d2006-05-05 09:49:53 +02001877 len = mixer->rc_cfg->packet_length;
1878
Clemens Ladischb259b102005-04-29 16:29:28 +02001879 init_waitqueue_head(&mixer->rc_waitq);
1880 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
1881 if (err < 0)
1882 return err;
1883 snprintf(hwdep->name, sizeof(hwdep->name),
1884 "%s remote control", mixer->chip->card->shortname);
1885 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
1886 hwdep->private_data = mixer;
1887 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
1888 hwdep->ops.open = snd_usb_sbrc_hwdep_open;
1889 hwdep->ops.release = snd_usb_sbrc_hwdep_release;
1890 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
1891
1892 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
1893 if (!mixer->rc_urb)
1894 return -ENOMEM;
1895 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
1896 if (!mixer->rc_setup_packet) {
1897 usb_free_urb(mixer->rc_urb);
1898 mixer->rc_urb = NULL;
1899 return -ENOMEM;
1900 }
1901 mixer->rc_setup_packet->bRequestType =
1902 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
1903 mixer->rc_setup_packet->bRequest = GET_MEM;
1904 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
1905 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
1906 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
1907 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
1908 usb_rcvctrlpipe(mixer->chip->dev, 0),
1909 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
1910 snd_usb_soundblaster_remote_complete, mixer);
1911 return 0;
1912}
1913
Takashi Iwaia5ce8892007-07-23 15:42:26 +02001914#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
Clemens Ladisch93446ed2005-05-03 08:02:40 +02001915
Takashi Iwai86e07d32005-11-17 15:08:02 +01001916static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Clemens Ladisch93446ed2005-05-03 08:02:40 +02001917{
1918 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1919 int index = kcontrol->private_value;
1920
1921 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
1922 return 0;
1923}
1924
Takashi Iwai86e07d32005-11-17 15:08:02 +01001925static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
Clemens Ladisch93446ed2005-05-03 08:02:40 +02001926{
1927 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
1928 int index = kcontrol->private_value;
1929 int value = ucontrol->value.integer.value[0];
1930 int err, changed;
1931
1932 if (value > 1)
1933 return -EINVAL;
1934 changed = value != mixer->audigy2nx_leds[index];
1935 err = snd_usb_ctl_msg(mixer->chip->dev,
1936 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
1937 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
1938 value, index + 2, NULL, 0, 100);
1939 if (err < 0)
1940 return err;
1941 mixer->audigy2nx_leds[index] = value;
1942 return changed;
1943}
1944
Takashi Iwai86e07d32005-11-17 15:08:02 +01001945static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
Clemens Ladisch93446ed2005-05-03 08:02:40 +02001946 {
1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1948 .name = "CMSS LED Switch",
1949 .info = snd_audigy2nx_led_info,
1950 .get = snd_audigy2nx_led_get,
1951 .put = snd_audigy2nx_led_put,
1952 .private_value = 0,
1953 },
1954 {
1955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1956 .name = "Power LED Switch",
1957 .info = snd_audigy2nx_led_info,
1958 .get = snd_audigy2nx_led_get,
1959 .put = snd_audigy2nx_led_put,
1960 .private_value = 1,
1961 },
1962 {
1963 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1964 .name = "Dolby Digital LED Switch",
1965 .info = snd_audigy2nx_led_info,
1966 .get = snd_audigy2nx_led_get,
1967 .put = snd_audigy2nx_led_put,
1968 .private_value = 2,
1969 },
1970};
1971
1972static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
1973{
1974 int i, err;
1975
1976 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01001977 if (i > 1 && /* Live24ext has 2 LEDs only */
1978 mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
1979 break;
Clemens Ladisch93446ed2005-05-03 08:02:40 +02001980 err = snd_ctl_add(mixer->chip->card,
1981 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
1982 if (err < 0)
1983 return err;
1984 }
1985 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
1986 return 0;
1987}
1988
Takashi Iwai86e07d32005-11-17 15:08:02 +01001989static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
1990 struct snd_info_buffer *buffer)
Clemens Ladischaafad562005-05-10 14:47:38 +02001991{
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01001992 static const struct sb_jack {
Clemens Ladischaafad562005-05-10 14:47:38 +02001993 int unitid;
1994 const char *name;
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01001995 } jacks_audigy2nx[] = {
Clemens Ladischaafad562005-05-10 14:47:38 +02001996 {4, "dig in "},
1997 {7, "line in"},
1998 {19, "spk out"},
1999 {20, "hph out"},
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01002000 {-1, NULL}
2001 }, jacks_live24ext[] = {
2002 {4, "line in"}, /* &1=Line, &2=Mic*/
2003 {3, "hph out"}, /* headphones */
2004 {0, "RC "}, /* last command, 6 bytes see rc_config above */
2005 {-1, NULL}
Clemens Ladischaafad562005-05-10 14:47:38 +02002006 };
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01002007 const struct sb_jack *jacks;
Clemens Ladischaafad562005-05-10 14:47:38 +02002008 struct usb_mixer_interface *mixer = entry->private_data;
2009 int i, err;
2010 u8 buf[3];
2011
2012 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01002013 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
2014 jacks = jacks_audigy2nx;
2015 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
2016 jacks = jacks_live24ext;
2017 else
2018 return;
2019
2020 for (i = 0; jacks[i].name; ++i) {
Clemens Ladischaafad562005-05-10 14:47:38 +02002021 snd_iprintf(buffer, "%s: ", jacks[i].name);
2022 err = snd_usb_ctl_msg(mixer->chip->dev,
2023 usb_rcvctrlpipe(mixer->chip->dev, 0),
2024 GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2025 USB_RECIP_INTERFACE, 0,
2026 jacks[i].unitid << 8, buf, 3, 100);
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01002027 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
Clemens Ladischaafad562005-05-10 14:47:38 +02002028 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
2029 else
2030 snd_iprintf(buffer, "?\n");
2031 }
2032}
2033
Takashi Iwai7a9b8062008-08-13 15:40:53 +02002034int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2035 int ignore_error)
Clemens Ladisch84957a82005-04-29 16:23:13 +02002036{
Takashi Iwai86e07d32005-11-17 15:08:02 +01002037 static struct snd_device_ops dev_ops = {
Clemens Ladisch84957a82005-04-29 16:23:13 +02002038 .dev_free = snd_usb_mixer_dev_free
2039 };
2040 struct usb_mixer_interface *mixer;
2041 int err;
2042
2043 strcpy(chip->card->mixername, "USB Mixer");
2044
Takashi Iwai561b2202005-09-09 14:22:34 +02002045 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
Clemens Ladisch84957a82005-04-29 16:23:13 +02002046 if (!mixer)
2047 return -ENOMEM;
2048 mixer->chip = chip;
2049 mixer->ctrlif = ctrlif;
Takashi Iwai7a9b8062008-08-13 15:40:53 +02002050 mixer->ignore_ctl_error = ignore_error;
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02002051 mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL);
2052 if (!mixer->id_elems) {
2053 kfree(mixer);
2054 return -ENOMEM;
2055 }
Clemens Ladisch84957a82005-04-29 16:23:13 +02002056
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02002057 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
Clemens Ladisch93446ed2005-05-03 08:02:40 +02002058 (err = snd_usb_mixer_status_create(mixer)) < 0)
2059 goto _error;
Clemens Ladisch84957a82005-04-29 16:23:13 +02002060
Clemens Ladisch93446ed2005-05-03 08:02:40 +02002061 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
2062 goto _error;
2063
Timofei Bondarenko69b1f1e2007-10-30 15:28:14 +01002064 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2065 mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) {
Takashi Iwai86e07d32005-11-17 15:08:02 +01002066 struct snd_info_entry *entry;
Clemens Ladischaafad562005-05-10 14:47:38 +02002067
Clemens Ladisch93446ed2005-05-03 08:02:40 +02002068 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2069 goto _error;
Clemens Ladischaafad562005-05-10 14:47:38 +02002070 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
Takashi Iwaibf850202006-04-28 15:13:41 +02002071 snd_info_set_text_ops(entry, mixer,
Clemens Ladischaafad562005-05-10 14:47:38 +02002072 snd_audigy2nx_proc_read);
Clemens Ladischb259b102005-04-29 16:29:28 +02002073 }
2074
Clemens Ladisch84957a82005-04-29 16:23:13 +02002075 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
Clemens Ladisch93446ed2005-05-03 08:02:40 +02002076 if (err < 0)
2077 goto _error;
Clemens Ladisch84957a82005-04-29 16:23:13 +02002078 list_add(&mixer->list, &chip->mixer_list);
2079 return 0;
Clemens Ladisch93446ed2005-05-03 08:02:40 +02002080
2081_error:
2082 snd_usb_mixer_free(mixer);
2083 return err;
Clemens Ladisch84957a82005-04-29 16:23:13 +02002084}
2085
2086void snd_usb_mixer_disconnect(struct list_head *p)
2087{
Clemens Ladisch6639b6c2005-04-29 16:26:14 +02002088 struct usb_mixer_interface *mixer;
2089
2090 mixer = list_entry(p, struct usb_mixer_interface, list);
Mariusz Kozlowski68df9de2006-11-08 15:37:04 +01002091 usb_kill_urb(mixer->urb);
2092 usb_kill_urb(mixer->rc_urb);
Clemens Ladisch84957a82005-04-29 16:23:13 +02002093}