mixer.c 91.5 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 *   (Tentative) USB Audio Driver for ALSA
 *
 *   Mixer control part
 *
 *   Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
 *
 *   Many codes borrowed from audio.c by
 *	    Alan Cox (alan@lxorguk.ukuu.org.uk)
 *	    Thomas Sailer (sailer@ife.ee.ethz.ch)
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * TODOs, for both the mixer and the streaming interfaces:
 *
 *  - support for UAC2 effect units
 *  - support for graphical equalizers
 *  - RANGE and MEM set commands (UAC2)
 *  - RANGE and MEM interrupt dispatchers (UAC2)
 *  - audio channel clustering (UAC2)
 *  - audio sample rate converter units (UAC2)
 *  - proper handling of clock multipliers (UAC2)
 *  - dispatch clock change notifications (UAC2)
 *  	- stop PCM streams which use a clock that became invalid
 *  	- stop PCM streams which use a clock selector that has changed
 *  	- parse available sample rates again when clock sources changed
 */

Linus Torvalds's avatar
Linus Torvalds committed
45
46
47
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
48
#include <linux/log2.h>
Linus Torvalds's avatar
Linus Torvalds committed
49
50
51
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/usb.h>
52
#include <linux/usb/audio.h>
53
#include <linux/usb/audio-v2.h>
54
#include <linux/usb/audio-v3.h>
55

Linus Torvalds's avatar
Linus Torvalds committed
56
57
#include <sound/core.h>
#include <sound/control.h>
58
#include <sound/hwdep.h>
59
#include <sound/info.h>
60
#include <sound/tlv.h>
Linus Torvalds's avatar
Linus Torvalds committed
61
62

#include "usbaudio.h"
63
#include "mixer.h"
Daniel Mack's avatar
Daniel Mack committed
64
#include "helper.h"
65
#include "mixer_quirks.h"
66
#include "power.h"
67

68
69
#define MAX_ID_ELEMS	256

Linus Torvalds's avatar
Linus Torvalds committed
70
71
72
73
74
75
76
77
78
79
struct usb_audio_term {
	int id;
	int type;
	int channels;
	unsigned int chconfig;
	int name;
};

struct usbmix_name_map;

80
81
struct mixer_build {
	struct snd_usb_audio *chip;
82
	struct usb_mixer_interface *mixer;
Linus Torvalds's avatar
Linus Torvalds committed
83
84
	unsigned char *buffer;
	unsigned int buflen;
85
	DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
86
	struct usb_audio_term oterm;
Linus Torvalds's avatar
Linus Torvalds committed
87
	const struct usbmix_name_map *map;
88
	const struct usbmix_selector_map *selector_map;
Linus Torvalds's avatar
Linus Torvalds committed
89
90
};

91
/*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
92
93
94
95
96
97
98
99
100
101
102
103
104
105
enum {
	USB_XU_CLOCK_RATE 		= 0xe301,
	USB_XU_CLOCK_SOURCE		= 0xe302,
	USB_XU_DIGITAL_IO_STATUS	= 0xe303,
	USB_XU_DEVICE_OPTIONS		= 0xe304,
	USB_XU_DIRECT_MONITORING	= 0xe305,
	USB_XU_METERING			= 0xe306
};
enum {
	USB_XU_CLOCK_SOURCE_SELECTOR = 0x02,	/* clock source*/
	USB_XU_CLOCK_RATE_SELECTOR = 0x03,	/* clock rate */
	USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01,	/* the spdif format */
	USB_XU_SOFT_LIMIT_SELECTOR = 0x03	/* soft limiter */
};
Linus Torvalds's avatar
Linus Torvalds committed
106
107
108
109
110
111

/*
 * manual mapping of mixer names
 * if the mixer topology is too complicated and the parsed names are
 * ambiguous, add the entries in usbmixer_maps.c.
 */
112
#include "mixer_maps.c"
Linus Torvalds's avatar
Linus Torvalds committed
113

114
static const struct usbmix_name_map *
115
find_map(const struct usbmix_name_map *p, int unitid, int control)
Linus Torvalds's avatar
Linus Torvalds committed
116
{
117
118
	if (!p)
		return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
119

120
	for (; p->id; p++) {
121
122
123
		if (p->id == unitid &&
		    (!control || !p->control || control == p->control))
			return p;
Linus Torvalds's avatar
Linus Torvalds committed
124
	}
125
	return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
126
127
}

128
129
130
/* get the mapped name if the unit matches */
static int
check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
Linus Torvalds's avatar
Linus Torvalds committed
131
{
132
133
	if (!p || !p->name)
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
134

135
136
137
138
	buflen--;
	return strlcpy(buf, p->name, buflen);
}

139
140
/* ignore the error value if ignore_ctl_error flag is set */
#define filter_error(cval, err) \
141
	((cval)->head.mixer->ignore_ctl_error ? 0 : (err))
142

143
144
145
146
147
/* check whether the control should be ignored */
static inline int
check_ignored_ctl(const struct usbmix_name_map *p)
{
	if (!p || p->name || p->dB)
Linus Torvalds's avatar
Linus Torvalds committed
148
		return 0;
149
150
151
152
153
154
155
156
157
158
	return 1;
}

/* dB mapping */
static inline void check_mapped_dB(const struct usbmix_name_map *p,
				   struct usb_mixer_elem_info *cval)
{
	if (p && p->dB) {
		cval->dBmin = p->dB->min;
		cval->dBmax = p->dB->max;
159
		cval->initialized = 1;
Linus Torvalds's avatar
Linus Torvalds committed
160
161
162
	}
}

163
/* get the mapped selector source name */
164
static int check_mapped_selector_name(struct mixer_build *state, int unitid,
165
166
167
168
				      int index, char *buf, int buflen)
{
	const struct usbmix_selector_map *p;

169
	if (!state->selector_map)
170
171
172
173
174
175
176
177
		return 0;
	for (p = state->selector_map; p->id; p++) {
		if (p->id == unitid && index < p->count)
			return strlcpy(buf, p->names[index], buflen);
	}
	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
178
179
180
/*
 * find an audio control unit with the given unit id
 */
181
182
static void *find_audio_control_unit(struct mixer_build *state,
				     unsigned char unit)
Linus Torvalds's avatar
Linus Torvalds committed
183
{
184
185
186
187
188
189
190
	/* we just parse the header */
	struct uac_feature_unit_descriptor *hdr = NULL;

	while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr,
					USB_DT_CS_INTERFACE)) != NULL) {
		if (hdr->bLength >= 4 &&
		    hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
191
		    hdr->bDescriptorSubtype <= UAC3_SAMPLE_RATE_CONVERTER &&
192
193
		    hdr->bUnitID == unit)
			return hdr;
Linus Torvalds's avatar
Linus Torvalds committed
194
	}
195

Linus Torvalds's avatar
Linus Torvalds committed
196
197
198
199
200
201
	return NULL;
}

/*
 * copy a string with the given id
 */
202
static int snd_usb_copy_string_desc(struct snd_usb_audio *chip,
203
				    int index, char *buf, int maxlen)
Linus Torvalds's avatar
Linus Torvalds committed
204
{
205
	int len = usb_string(chip->dev, index, buf, maxlen - 1);
206
207
208
209

	if (len < 0)
		return 0;

Linus Torvalds's avatar
Linus Torvalds committed
210
211
212
213
214
215
216
	buf[len] = 0;
	return len;
}

/*
 * convert from the byte/word on usb descriptor to the zero-based integer
 */
217
static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds's avatar
Linus Torvalds committed
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
{
	switch (cval->val_type) {
	case USB_MIXER_BOOLEAN:
		return !!val;
	case USB_MIXER_INV_BOOLEAN:
		return !val;
	case USB_MIXER_U8:
		val &= 0xff;
		break;
	case USB_MIXER_S8:
		val &= 0xff;
		if (val >= 0x80)
			val -= 0x100;
		break;
	case USB_MIXER_U16:
		val &= 0xffff;
		break;
	case USB_MIXER_S16:
		val &= 0xffff;
		if (val >= 0x8000)
			val -= 0x10000;
		break;
	}
	return val;
}

/*
 * convert from the zero-based int to the byte/word for usb descriptor
 */
247
static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds's avatar
Linus Torvalds committed
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
{
	switch (cval->val_type) {
	case USB_MIXER_BOOLEAN:
		return !!val;
	case USB_MIXER_INV_BOOLEAN:
		return !val;
	case USB_MIXER_S8:
	case USB_MIXER_U8:
		return val & 0xff;
	case USB_MIXER_S16:
	case USB_MIXER_U16:
		return val & 0xffff;
	}
	return 0; /* not reached */
}

264
static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds's avatar
Linus Torvalds committed
265
{
266
	if (!cval->res)
Linus Torvalds's avatar
Linus Torvalds committed
267
268
269
		cval->res = 1;
	if (val < cval->min)
		return 0;
270
271
	else if (val >= cval->max)
		return (cval->max - cval->min + cval->res - 1) / cval->res;
Linus Torvalds's avatar
Linus Torvalds committed
272
273
274
275
	else
		return (val - cval->min) / cval->res;
}

276
static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
Linus Torvalds's avatar
Linus Torvalds committed
277
278
279
{
	if (val < 0)
		return cval->min;
280
	if (!cval->res)
Linus Torvalds's avatar
Linus Torvalds committed
281
282
283
284
285
286
287
288
		cval->res = 1;
	val *= cval->res;
	val += cval->min;
	if (val > cval->max)
		return cval->max;
	return val;
}

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
static int uac2_ctl_value_size(int val_type)
{
	switch (val_type) {
	case USB_MIXER_S32:
	case USB_MIXER_U32:
		return 4;
	case USB_MIXER_S16:
	case USB_MIXER_U16:
		return 2;
	default:
		return 1;
	}
	return 0; /* unreachable */
}

Linus Torvalds's avatar
Linus Torvalds committed
304
305
306
307
308

/*
 * retrieve a mixer value
 */

309
310
static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
			    int validx, int *value_ret)
Linus Torvalds's avatar
Linus Torvalds committed
311
{
312
	struct snd_usb_audio *chip = cval->head.mixer->chip;
Linus Torvalds's avatar
Linus Torvalds committed
313
314
315
	unsigned char buf[2];
	int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
	int timeout = 10;
316
	int idx = 0, err;
Linus Torvalds's avatar
Linus Torvalds committed
317

318
	err = snd_usb_lock_shutdown(chip);
319
320
	if (err < 0)
		return -EIO;
321

Linus Torvalds's avatar
Linus Torvalds committed
322
	while (timeout-- > 0) {
323
		idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
324
325
326
327
		err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
				      validx, idx, buf, val_len);
		if (err >= val_len) {
Linus Torvalds's avatar
Linus Torvalds committed
328
			*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
329
330
			err = 0;
			goto out;
331
332
		} else if (err == -ETIMEDOUT) {
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
333
334
		}
	}
335
336
337
	usb_audio_dbg(chip,
		"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
		request, validx, idx, cval->val_type);
338
339
340
	err = -EINVAL;

 out:
341
	snd_usb_unlock_shutdown(chip);
342
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
343
344
}

345
346
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
			    int validx, int *value_ret)
347
{
348
	struct snd_usb_audio *chip = cval->head.mixer->chip;
349
350
	/* enough space for one range */
	unsigned char buf[sizeof(__u16) + 3 * sizeof(__u32)];
351
	unsigned char *val;
352
	int idx = 0, ret, val_size, size;
353
354
	__u8 bRequest;

355
356
	val_size = uac2_ctl_value_size(cval->val_type);

357
358
	if (request == UAC_GET_CUR) {
		bRequest = UAC2_CS_CUR;
359
		size = val_size;
360
361
	} else {
		bRequest = UAC2_CS_RANGE;
362
		size = sizeof(__u16) + 3 * val_size;
363
364
365
	}

	memset(buf, 0, sizeof(buf));
366

367
	ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
368
369
370
	if (ret)
		goto error;

371
372
	idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
	ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
373
			      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
374
			      validx, idx, buf, size);
375
	snd_usb_unlock_shutdown(chip);
376
377

	if (ret < 0) {
378
error:
379
380
381
		usb_audio_err(chip,
			"cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
			request, validx, idx, cval->val_type);
382
383
384
		return ret;
	}

385
386
	/* FIXME: how should we handle multiple triplets here? */

387
388
389
390
391
392
393
394
	switch (request) {
	case UAC_GET_CUR:
		val = buf;
		break;
	case UAC_GET_MIN:
		val = buf + sizeof(__u16);
		break;
	case UAC_GET_MAX:
395
		val = buf + sizeof(__u16) + val_size;
396
397
		break;
	case UAC_GET_RES:
398
		val = buf + sizeof(__u16) + val_size * 2;
399
400
401
402
403
		break;
	default:
		return -EINVAL;
	}

404
405
	*value_ret = convert_signed_value(cval,
					  snd_usb_combine_bytes(val, val_size));
406
407
408
409

	return 0;
}

410
411
static int get_ctl_value(struct usb_mixer_elem_info *cval, int request,
			 int validx, int *value_ret)
412
{
413
414
	validx += cval->idx_off;

415
	return (cval->head.mixer->protocol == UAC_VERSION_1) ?
416
417
418
419
		get_ctl_value_v1(cval, request, validx, value_ret) :
		get_ctl_value_v2(cval, request, validx, value_ret);
}

420
421
static int get_cur_ctl_value(struct usb_mixer_elem_info *cval,
			     int validx, int *value)
Linus Torvalds's avatar
Linus Torvalds committed
422
{
423
	return get_ctl_value(cval, UAC_GET_CUR, validx, value);
Linus Torvalds's avatar
Linus Torvalds committed
424
425
426
}

/* channel = 0: master, 1 = first channel */
427
428
static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
				  int channel, int *value)
Linus Torvalds's avatar
Linus Torvalds committed
429
{
430
431
432
	return get_ctl_value(cval, UAC_GET_CUR,
			     (cval->control << 8) | channel,
			     value);
Linus Torvalds's avatar
Linus Torvalds committed
433
434
}

435
int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval,
436
437
438
439
440
441
442
443
444
445
			     int channel, int index, int *value)
{
	int err;

	if (cval->cached & (1 << channel)) {
		*value = cval->cache_val[index];
		return 0;
	}
	err = get_cur_mix_raw(cval, channel, value);
	if (err < 0) {
446
447
		if (!cval->head.mixer->ignore_ctl_error)
			usb_audio_dbg(cval->head.mixer->chip,
448
				"cannot get current value for control %d ch %d: err = %d\n",
449
				      cval->control, channel, err);
450
451
452
453
454
455
456
		return err;
	}
	cval->cached |= 1 << channel;
	cval->cache_val[index] = *value;
	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
457
458
459
460
/*
 * set a mixer value
 */

461
462
int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
				int request, int validx, int value_set)
Linus Torvalds's avatar
Linus Torvalds committed
463
{
464
	struct snd_usb_audio *chip = cval->head.mixer->chip;
465
	unsigned char buf[4];
466
	int idx = 0, val_len, err, timeout = 10;
467

468
469
	validx += cval->idx_off;

470

471
	if (cval->head.mixer->protocol == UAC_VERSION_1) {
472
		val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
473
	} else { /* UAC_VERSION_2/3 */
474
		val_len = uac2_ctl_value_size(cval->val_type);
475
476
477

		/* FIXME */
		if (request != UAC_SET_CUR) {
478
			usb_audio_dbg(chip, "RANGE setting not yet supported\n");
479
480
481
482
483
			return -EINVAL;
		}

		request = UAC2_CS_CUR;
	}
Linus Torvalds's avatar
Linus Torvalds committed
484
485
486
487

	value_set = convert_bytes_value(cval, value_set);
	buf[0] = value_set & 0xff;
	buf[1] = (value_set >> 8) & 0xff;
488
489
	buf[2] = (value_set >> 16) & 0xff;
	buf[3] = (value_set >> 24) & 0xff;
490
491

	err = snd_usb_lock_shutdown(chip);
492
493
	if (err < 0)
		return -EIO;
494

495
	while (timeout-- > 0) {
496
		idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
497
498
499
500
501
		err = snd_usb_ctl_msg(chip->dev,
				      usb_sndctrlpipe(chip->dev, 0), request,
				      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
				      validx, idx, buf, val_len);
		if (err >= 0) {
502
503
			err = 0;
			goto out;
504
505
		} else if (err == -ETIMEDOUT) {
			goto out;
506
		}
507
	}
508
	usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
509
		      request, validx, idx, cval->val_type, buf[0], buf[1]);
510
511
512
	err = -EINVAL;

 out:
513
	snd_usb_unlock_shutdown(chip);
514
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
515
516
}

517
518
static int set_cur_ctl_value(struct usb_mixer_elem_info *cval,
			     int validx, int value)
Linus Torvalds's avatar
Linus Torvalds committed
519
{
520
	return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
Linus Torvalds's avatar
Linus Torvalds committed
521
522
}

523
int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
524
			     int index, int value)
Linus Torvalds's avatar
Linus Torvalds committed
525
{
526
	int err;
527
528
529
530
531
	unsigned int read_only = (channel == 0) ?
		cval->master_readonly :
		cval->ch_readonly & (1 << (channel - 1));

	if (read_only) {
532
		usb_audio_dbg(cval->head.mixer->chip,
533
			      "%s(): channel %d of control %d is read_only\n",
534
535
536
537
			    __func__, channel, cval->control);
		return 0;
	}

538
539
540
	err = snd_usb_mixer_set_ctl_value(cval,
					  UAC_SET_CUR, (cval->control << 8) | channel,
					  value);
541
542
543
544
545
	if (err < 0)
		return err;
	cval->cached |= 1 << channel;
	cval->cache_val[index] = value;
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
546
547
}

548
549
550
/*
 * TLV callback for mixer volume controls
 */
551
int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
552
553
554
			 unsigned int size, unsigned int __user *_tlv)
{
	struct usb_mixer_elem_info *cval = kcontrol->private_data;
555
	DECLARE_TLV_DB_MINMAX(scale, 0, 0);
556
557
558

	if (size < sizeof(scale))
		return -ENOMEM;
559
560
	if (cval->min_mute)
		scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
561
562
	scale[2] = cval->dBmin;
	scale[3] = cval->dBmax;
563
564
565
566
	if (copy_to_user(_tlv, scale, sizeof(scale)))
		return -EFAULT;
	return 0;
}
Linus Torvalds's avatar
Linus Torvalds committed
567
568
569
570
571

/*
 * parser routines begin here...
 */

572
static int parse_audio_unit(struct mixer_build *state, int unitid);
Linus Torvalds's avatar
Linus Torvalds committed
573
574
575
576
577
578


/*
 * check if the input/output channel routing is enabled on the given bitmap.
 * used for mixer unit parser
 */
579
580
static int check_matrix_bitmap(unsigned char *bmap,
			       int ich, int och, int num_outs)
Linus Torvalds's avatar
Linus Torvalds committed
581
582
583
584
585
586
587
588
589
590
591
592
{
	int idx = ich * num_outs + och;
	return bmap[idx >> 3] & (0x80 >> (idx & 7));
}

/*
 * add an alsa control element
 * search and increment the index until an empty slot is found.
 *
 * if failed, give up and free the control instance.
 */

593
int snd_usb_mixer_add_control(struct usb_mixer_elem_list *list,
594
			      struct snd_kcontrol *kctl)
Linus Torvalds's avatar
Linus Torvalds committed
595
{
596
	struct usb_mixer_interface *mixer = list->mixer;
Linus Torvalds's avatar
Linus Torvalds committed
597
	int err;
598

599
	while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
Linus Torvalds's avatar
Linus Torvalds committed
600
		kctl->id.index++;
601
602
	err = snd_ctl_add(mixer->chip->card, kctl);
	if (err < 0) {
603
604
		usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n",
			      err);
605
		return err;
Linus Torvalds's avatar
Linus Torvalds committed
606
	}
607
608
609
	list->kctl = kctl;
	list->next_id_elem = mixer->id_elems[list->id];
	mixer->id_elems[list->id] = list;
610
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
}

/*
 * get a terminal name string
 */

static struct iterm_name_combo {
	int type;
	char *name;
} iterm_names[] = {
	{ 0x0300, "Output" },
	{ 0x0301, "Speaker" },
	{ 0x0302, "Headphone" },
	{ 0x0303, "HMD Audio" },
	{ 0x0304, "Desktop Speaker" },
	{ 0x0305, "Room Speaker" },
	{ 0x0306, "Com Speaker" },
	{ 0x0307, "LFE" },
	{ 0x0600, "External In" },
	{ 0x0601, "Analog In" },
	{ 0x0602, "Digital In" },
	{ 0x0603, "Line" },
	{ 0x0604, "Legacy In" },
	{ 0x0605, "IEC958 In" },
	{ 0x0606, "1394 DA Stream" },
	{ 0x0607, "1394 DV Stream" },
	{ 0x0700, "Embedded" },
	{ 0x0701, "Noise Source" },
	{ 0x0702, "Equalization Noise" },
	{ 0x0703, "CD" },
	{ 0x0704, "DAT" },
	{ 0x0705, "DCC" },
	{ 0x0706, "MiniDisk" },
	{ 0x0707, "Analog Tape" },
	{ 0x0708, "Phonograph" },
	{ 0x0709, "VCR Audio" },
	{ 0x070a, "Video Disk Audio" },
	{ 0x070b, "DVD Audio" },
	{ 0x070c, "TV Tuner Audio" },
	{ 0x070d, "Satellite Rec Audio" },
	{ 0x070e, "Cable Tuner Audio" },
	{ 0x070f, "DSS Audio" },
	{ 0x0710, "Radio Receiver" },
	{ 0x0711, "Radio Transmitter" },
	{ 0x0712, "Multi-Track Recorder" },
	{ 0x0713, "Synthesizer" },
	{ 0 },
};

660
static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iterm,
Linus Torvalds's avatar
Linus Torvalds committed
661
662
663
			 unsigned char *name, int maxlen, int term_only)
{
	struct iterm_name_combo *names;
664
	int len;
Linus Torvalds's avatar
Linus Torvalds committed
665

666
	if (iterm->name) {
667
		len = snd_usb_copy_string_desc(chip, iterm->name,
668
						name, maxlen);
669
670
671
		if (len)
			return len;
	}
Linus Torvalds's avatar
Linus Torvalds committed
672
673
674
675
676
677

	/* virtual type - not a real terminal */
	if (iterm->type >> 16) {
		if (term_only)
			return 0;
		switch (iterm->type >> 16) {
678
		case UAC_SELECTOR_UNIT:
679
680
			strcpy(name, "Selector");
			return 8;
681
		case UAC1_PROCESSING_UNIT:
682
683
			strcpy(name, "Process Unit");
			return 12;
684
		case UAC1_EXTENSION_UNIT:
685
686
			strcpy(name, "Ext Unit");
			return 8;
687
		case UAC_MIXER_UNIT:
688
689
			strcpy(name, "Mixer");
			return 5;
Linus Torvalds's avatar
Linus Torvalds committed
690
691
692
693
694
695
696
		default:
			return sprintf(name, "Unit %d", iterm->id);
		}
	}

	switch (iterm->type & 0xff00) {
	case 0x0100:
697
698
		strcpy(name, "PCM");
		return 3;
Linus Torvalds's avatar
Linus Torvalds committed
699
	case 0x0200:
700
701
		strcpy(name, "Mic");
		return 3;
Linus Torvalds's avatar
Linus Torvalds committed
702
	case 0x0400:
703
704
		strcpy(name, "Headset");
		return 7;
Linus Torvalds's avatar
Linus Torvalds committed
705
	case 0x0500:
706
707
		strcpy(name, "Phone");
		return 5;
Linus Torvalds's avatar
Linus Torvalds committed
708
709
	}

710
	for (names = iterm_names; names->type; names++) {
Linus Torvalds's avatar
Linus Torvalds committed
711
712
713
714
		if (names->type == iterm->type) {
			strcpy(name, names->name);
			return strlen(names->name);
		}
715
716
	}

Linus Torvalds's avatar
Linus Torvalds committed
717
718
719
	return 0;
}

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
/*
 * Get logical cluster information for UAC3 devices.
 */
static int get_cluster_channels_v3(struct mixer_build *state, unsigned int cluster_id)
{
	struct uac3_cluster_header_descriptor c_header;
	int err;

	err = snd_usb_ctl_msg(state->chip->dev,
			usb_rcvctrlpipe(state->chip->dev, 0),
			UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
			cluster_id,
			snd_usb_ctrl_intf(state->chip),
			&c_header, sizeof(c_header));
	if (err < 0)
		goto error;
	if (err != sizeof(c_header)) {
		err = -EIO;
		goto error;
	}

	return c_header.bNrChannels;

error:
	usb_audio_err(state->chip, "cannot request logical cluster ID: %d (err: %d)\n", cluster_id, err);
	return err;
}

/*
 * Get number of channels for a Mixer Unit.
 */
static int uac_mixer_unit_get_channels(struct mixer_build *state,
				       struct uac_mixer_unit_descriptor *desc)
{
	int mu_channels;

	if (desc->bLength < 11)
		return -EINVAL;
	if (!desc->bNrInPins)
		return -EINVAL;

	switch (state->mixer->protocol) {
	case UAC_VERSION_1:
	case UAC_VERSION_2:
	default:
		mu_channels = uac_mixer_unit_bNrChannels(desc);
		break;
	case UAC_VERSION_3:
		mu_channels = get_cluster_channels_v3(state,
				uac3_mixer_unit_wClusterDescrID(desc));
		break;
	}

	if (!mu_channels)
		return -EINVAL;

	return mu_channels;
}

Linus Torvalds's avatar
Linus Torvalds committed
780
781
782
783
/*
 * parse the source unit recursively until it reaches to a terminal
 * or a branched unit.
 */
784
785
static int check_input_term(struct mixer_build *state, int id,
			    struct usb_audio_term *term)
Linus Torvalds's avatar
Linus Torvalds committed
786
{
787
	int protocol = state->mixer->protocol;
788
	int err;
789
	void *p1;
Linus Torvalds's avatar
Linus Torvalds committed
790
791
792

	memset(term, 0, sizeof(*term));
	while ((p1 = find_audio_control_unit(state, id)) != NULL) {
793
		unsigned char *hdr = p1;
Linus Torvalds's avatar
Linus Torvalds committed
794
		term->id = id;
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

		if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
			switch (hdr[2]) {
			case UAC_INPUT_TERMINAL:
				if (protocol == UAC_VERSION_1) {
					struct uac_input_terminal_descriptor *d = p1;

					term->type = le16_to_cpu(d->wTerminalType);
					term->channels = d->bNrChannels;
					term->chconfig = le16_to_cpu(d->wChannelConfig);
					term->name = d->iTerminal;
				} else { /* UAC_VERSION_2 */
					struct uac2_input_terminal_descriptor *d = p1;

					/* call recursively to verify that the
					 * referenced clock entity is valid */
					err = check_input_term(state, d->bCSourceID, term);
					if (err < 0)
						return err;

					/* save input term properties after recursion,
					 * to ensure they are not overriden by the
					 * recursion calls */
					term->id = id;
					term->type = le16_to_cpu(d->wTerminalType);
					term->channels = d->bNrChannels;
					term->chconfig = le32_to_cpu(d->bmChannelConfig);
					term->name = d->iTerminal;
				}
				return 0;
			case UAC_FEATURE_UNIT: {
				/* the header is the same for v1 and v2 */
				struct uac_feature_unit_descriptor *d = p1;

				id = d->bSourceID;
				break; /* continue to parse */
			}
			case UAC_MIXER_UNIT: {
				struct uac_mixer_unit_descriptor *d = p1;

				term->type = d->bDescriptorSubtype << 16; /* virtual type */
				term->channels = uac_mixer_unit_bNrChannels(d);
				term->chconfig = uac_mixer_unit_wChannelConfig(d, protocol);
				term->name = uac_mixer_unit_iMixer(d);
				return 0;
			}
			case UAC_SELECTOR_UNIT:
			case UAC2_CLOCK_SELECTOR: {
				struct uac_selector_unit_descriptor *d = p1;
				/* call recursively to retrieve the channel info */
				err = check_input_term(state, d->baSourceID[0], term);
				if (err < 0)
					return err;
				term->type = d->bDescriptorSubtype << 16; /* virtual type */
				term->id = id;
				term->name = uac_selector_unit_iSelector(d);
				return 0;
			}
			case UAC1_PROCESSING_UNIT:
			case UAC1_EXTENSION_UNIT:
			/* UAC2_PROCESSING_UNIT_V2 */
			/* UAC2_EFFECT_UNIT */
			case UAC2_EXTENSION_UNIT_V2: {
				struct uac_processing_unit_descriptor *d = p1;

				if (protocol == UAC_VERSION_2 &&
					hdr[2] == UAC2_EFFECT_UNIT) {
					/* UAC2/UAC1 unit IDs overlap here in an
					 * uncompatible way. Ignore this unit for now.
					 */
					return 0;
				}

				if (d->bNrInPins) {
					id = d->baSourceID[0];
					break; /* continue to parse */
				}
				term->type = d->bDescriptorSubtype << 16; /* virtual type */
				term->channels = uac_processing_unit_bNrChannels(d);
				term->chconfig = uac_processing_unit_wChannelConfig(d, protocol);
				term->name = uac_processing_unit_iProcessing(d, protocol);
				return 0;
			}
			case UAC2_CLOCK_SOURCE: {
				struct uac_clock_source_descriptor *d = p1;

				term->type = d->bDescriptorSubtype << 16; /* virtual type */
				term->id = id;
				term->name = d->iClockSource;
				return 0;
			}
			default:
				return -ENODEV;
			}
		} else { /* UAC_VERSION_3 */
			switch (hdr[2]) {
			case UAC_INPUT_TERMINAL: {
				struct uac3_input_terminal_descriptor *d = p1;
893

894
895
				/* call recursively to verify that the
				 * referenced clock entity is valid */
896
897
898
				err = check_input_term(state, d->bCSourceID, term);
				if (err < 0)
					return err;
899
900
901
902
903
904

				/* save input term properties after recursion,
				 * to ensure they are not overriden by the
				 * recursion calls */
				term->id = id;
				term->type = le16_to_cpu(d->wTerminalType);
905

906
907
908
909
910
911
				err = get_cluster_channels_v3(state, le16_to_cpu(d->wClusterDescrID));
				if (err < 0)
					return err;
				term->channels = err;

				/* REVISIT: UAC3 IT doesn't have channels cfg */
912
913
914
				term->chconfig = 0;

				term->name = le16_to_cpu(d->wTerminalDescrStr);
915
916
				return 0;
			}
917
918
			case UAC3_FEATURE_UNIT: {
				struct uac3_feature_unit_descriptor *d = p1;
919

920
				id = d->bSourceID;
Linus Torvalds's avatar
Linus Torvalds committed
921
922
				break; /* continue to parse */
			}
923
924
925
926
927
928
929
930
			case UAC3_CLOCK_SOURCE: {
				struct uac3_clock_source_descriptor *d = p1;

				term->type = d->bDescriptorSubtype << 16; /* virtual type */
				term->id = id;
				term->name = le16_to_cpu(d->wClockSourceStr);
				return 0;
			}
931
932
933
934
935
936
937
938
939
940
941
942
			case UAC3_MIXER_UNIT: {
				struct uac_mixer_unit_descriptor *d = p1;

				err = uac_mixer_unit_get_channels(state, d);
				if (err < 0)
					return err;

				term->channels = err;
				term->type = d->bDescriptorSubtype << 16; /* virtual type */

				return 0;
			}
943
944
945
			default:
				return -ENODEV;
			}
Linus Torvalds's avatar
Linus Torvalds committed
946
947
948
949
950
951
952
953
954
955
956
		}
	}
	return -ENODEV;
}

/*
 * Feature Unit
 */

/* feature unit control information */
struct usb_feature_control_info {
957
	int control;
Linus Torvalds's avatar
Linus Torvalds committed
958
	const char *name;
959
960
	int type;	/* data type for uac1 */
	int type_uac2;	/* data type for uac2 if different from uac1, else -1 */
Linus Torvalds's avatar
Linus Torvalds committed
961
962
963
};

static struct usb_feature_control_info audio_feature_info[] = {
964
965
966
967
968
969
970
971
972
973
	{ UAC_FU_MUTE,			"Mute",			USB_MIXER_INV_BOOLEAN, -1 },
	{ UAC_FU_VOLUME,		"Volume",		USB_MIXER_S16, -1 },
	{ UAC_FU_BASS,			"Tone Control - Bass",	USB_MIXER_S8, -1 },
	{ UAC_FU_MID,			"Tone Control - Mid",	USB_MIXER_S8, -1 },
	{ UAC_FU_TREBLE,		"Tone Control - Treble", USB_MIXER_S8, -1 },
	{ UAC_FU_GRAPHIC_EQUALIZER,	"Graphic Equalizer",	USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */
	{ UAC_FU_AUTOMATIC_GAIN,	"Auto Gain Control",	USB_MIXER_BOOLEAN, -1 },
	{ UAC_FU_DELAY,			"Delay Control",	USB_MIXER_U16, USB_MIXER_U32 },
	{ UAC_FU_BASS_BOOST,		"Bass Boost",		USB_MIXER_BOOLEAN, -1 },
	{ UAC_FU_LOUDNESS,		"Loudness",		USB_MIXER_BOOLEAN, -1 },
974
	/* UAC2 specific */
975
976
977
	{ UAC2_FU_INPUT_GAIN,		"Input Gain Control",	USB_MIXER_S16, -1 },
	{ UAC2_FU_INPUT_GAIN_PAD,	"Input Gain Pad Control", USB_MIXER_S16, -1 },
	{ UAC2_FU_PHASE_INVERTER,	 "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 },
Linus Torvalds's avatar
Linus Torvalds committed
978
979
980
};

/* private_free callback */
981
void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl)
Linus Torvalds's avatar
Linus Torvalds committed
982
{
983
984
	kfree(kctl->private_data);
	kctl->private_data = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
985
986
987
988
989
990
}

/*
 * interface to ALSA control for feature/mixer units
 */

991
992
993
994
/* volume control quirks */
static void volume_control_quirks(struct usb_mixer_elem_info *cval,
				  struct snd_kcontrol *kctl)
{
995
	struct snd_usb_audio *chip = cval->head.mixer->chip;
996
	switch (chip->usb_id) {
997
	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
998
	case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
			cval->min = 0x0000;
			cval->max = 0xffff;
			cval->res = 0x00e6;
			break;
		}
		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
			cval->min = 0x00;
			cval->max = 0xff;
			break;
		}
		if (strstr(kctl->id.name, "Effect Return") != NULL) {
			cval->min = 0xb706;
			cval->max = 0xff7b;
			cval->res = 0x0073;
			break;
		}
		if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
			(strstr(kctl->id.name, "Effect Send") != NULL)) {
			cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
			cval->max = 0xfcfe;
			cval->res = 0x0073;
		}
		break;

1025
1026
1027
	case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
	case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
1028
1029
			usb_audio_info(chip,
				       "set quirk for FTU Effect Duration\n");
1030
1031
1032
1033
1034
1035
1036
			cval->min = 0x0000;
			cval->max = 0x7f00;
			cval->res = 0x0100;
			break;
		}
		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
1037
1038
			usb_audio_info(chip,
				       "set quirks for FTU Effect Feedback/Volume\n");
1039
1040
1041
1042
1043
1044
			cval->min = 0x00;
			cval->max = 0x7f;
			break;
		}
		break;

1045
1046
1047
1048
1049
1050
1051
1052
	case USB_ID(0x0d8c, 0x0103):
		if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
			usb_audio_info(chip,
				 "set volume quirk for CM102-A+/102S+\n");
			cval->min = -256;
		}
		break;

1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
	case USB_ID(0x0471, 0x0101):
	case USB_ID(0x0471, 0x0104):
	case USB_ID(0x0471, 0x0105):
	case USB_ID(0x0672, 0x1041):
	/* quirk for UDA1321/N101.
	 * note that detection between firmware 2.1.1.7 (N101)
	 * and later 2.1.1.21 is not very clear from datasheets.
	 * I hope that the min value is -15360 for newer firmware --jk
	 */
		if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
		    cval->min == -15616) {
1064
			usb_audio_info(chip,
1065
1066
1067
1068
1069
1070
1071
				 "set volume quirk for UDA1321/N101 chip\n");
			cval->max = -256;
		}
		break;

	case USB_ID(0x046d, 0x09a4):
		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
1072
			usb_audio_info(chip,
1073
1074
1075
1076
1077
1078
1079
				"set volume quirk for QuickCam E3500\n");
			cval->min = 6080;
			cval->max = 8768;
			cval->res = 192;
		}
		break;

1080
	case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */
1081
1082
	case USB_ID(0x046d, 0x0808):
	case USB_ID(0x046d, 0x0809):
1083
	case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */
1084
	case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
1085
	case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
1086
	case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
1087
	case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
1088
	case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */
1089
	case USB_ID(0x046d, 0x0991):
1090
	case USB_ID(0x046d, 0x09a2): /* QuickCam Communicate Deluxe/S7500 */
1091
1092
	/* Most audio usb devices lie about volume resolution.
	 * Most Logitech webcams have res = 384.
1093
	 * Probably there is some logitech magic behind this number --fishor
1094
1095
	 */
		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
1096
			usb_audio_info(chip,
1097
1098
1099
1100
1101
1102
1103
				"set resolution quirk: cval->res = 384\n");
			cval->res = 384;
		}
		break;
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
1104
1105
1106
/*
 * retrieve the minimum and maximum values for the specified control
 */
1107
1108
static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
				   int default_min, struct snd_kcontrol *kctl)
Linus Torvalds's avatar
Linus Torvalds committed
1109
1110
1111
1112
1113
{
	/* for failsafe */
	cval->min = default_min;
	cval->max = cval->min + 1;
	cval->res = 1;
1114
	cval->dBmin = cval->dBmax = 0;
Linus Torvalds's avatar
Linus Torvalds committed
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128

	if (cval->val_type == USB_MIXER_BOOLEAN ||
	    cval->val_type == USB_MIXER_INV_BOOLEAN) {
		cval->initialized = 1;
	} else {
		int minchn = 0;
		if (cval->cmask) {
			int i;
			for (i = 0; i < MAX_CHANNELS; i++)
				if (cval->cmask & (1 << i)) {
					minchn = i + 1;
					break;
				}
		}
1129
1130
		if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
		    get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
1131
			usb_audio_err(cval->head.mixer->chip,
1132
				      "%d:%d: cannot get min/max values for control %d (id %d)\n",
1133
1134
				   cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip),
							       cval->control, cval->head.id);
Linus Torvalds's avatar
Linus Torvalds committed
1135
1136
			return -EINVAL;
		}
1137
1138
1139
		if (get_ctl_value(cval, UAC_GET_RES,
				  (cval->control << 8) | minchn,
				  &cval->res) < 0) {
Linus Torvalds's avatar
Linus Torvalds committed
1140
1141
1142
1143
1144
			cval->res = 1;
		} else {
			int last_valid_res = cval->res;

			while (cval->res > 1) {
1145
				if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
1146
1147
								(cval->control << 8) | minchn,
								cval->res / 2) < 0)
Linus Torvalds's avatar
Linus Torvalds committed
1148
1149
1150
					break;
				cval->res /= 2;
			}
1151
1152
			if (get_ctl_value(cval, UAC_GET_RES,
					  (cval->control << 8) | minchn, &cval->res) < 0)
Linus Torvalds's avatar
Linus Torvalds committed
1153
1154
1155
1156
				cval->res = last_valid_res;
		}
		if (cval->res == 0)
			cval->res = 1;
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166

		/* Additional checks for the proper resolution
		 *
		 * Some devices report smaller resolutions than actually
		 * reacting.  They don't return errors but simply clip
		 * to the lower aligned value.
		 */
		if (cval->min + cval->res < cval->max) {
			int last_valid_res = cval->res;
			int saved, test, check;
1167
			get_cur_mix_raw(cval, minchn, &saved);
1168
1169
1170
1171
1172
1173
1174
			for (;;) {
				test = saved;
				if (test < cval->max)
					test += cval->res;
				else
					test -= cval->res;
				if (test < cval->min || test > cval->max ||
1175
				    snd_usb_set_cur_mix_value(cval, minchn, 0, test) ||
1176
				    get_cur_mix_raw(cval, minchn, &check)) {
1177
1178
1179
1180
1181
1182
1183
					cval->res = last_valid_res;
					break;
				}
				if (test == check)
					break;
				cval->res *= 2;
			}
1184
			snd_usb_set_cur_mix_value(cval, minchn, 0, saved);
1185
1186
		}

Linus Torvalds's avatar
Linus Torvalds committed
1187
1188
		cval->initialized = 1;
	}
1189

1190
1191
1192
	if (kctl)
		volume_control_quirks(cval, kctl);

1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
	/* USB descriptions contain the dB scale in 1/256 dB unit
	 * while ALSA TLV contains in 1/100 dB unit
	 */
	cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
	cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
	if (cval->dBmin > cval->dBmax) {
		/* something is wrong; assume it's either from/to 0dB */
		if (cval->dBmin < 0)
			cval->dBmax = 0;
		else if (cval->dBmin > 0)
			cval->dBmin = 0;
		if (cval->dBmin > cval->dBmax) {
			/* totally crap, return an error */
			return -EINVAL;
		}
	}

Linus Torvalds's avatar
Linus Torvalds committed
1210
1211
1212
	return 0;
}

1213
#define get_min_max(cval, def)	get_min_max_with_quirks(cval, def, NULL)
Linus Torvalds's avatar
Linus Torvalds committed
1214
1215

/* get a feature/mixer unit info */
1216
1217
static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_info *uinfo)
Linus Torvalds's avatar
Linus Torvalds committed
1218
{
1219
	struct usb_mixer_elem_info *cval = kcontrol->private_data;
Linus Torvalds's avatar
Linus Torvalds committed
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231

	if (cval->val_type == USB_MIXER_BOOLEAN ||
	    cval->val_type == USB_MIXER_INV_BOOLEAN)
		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	else
		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = cval->channels;
	if (cval->val_type == USB_MIXER_BOOLEAN ||
	    cval->val_type == USB_MIXER_INV_BOOLEAN) {
		uinfo->value.integer.min = 0;
		uinfo->value.integer.max = 1;
	} else {
1232
		if (!cval->initialized) {
1233
			get_min_max_with_quirks(cval, 0, kcontrol);
1234
1235
1236
1237
			if (cval->initialized && cval->dBmin >= cval->dBmax) {
				kcontrol->vd[0].access &= 
					~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
					  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
1238
				snd_ctl_notify(cval->head.mixer->chip->card,
1239
1240
1241
1242
					       SNDRV_CTL_EVENT_MASK_INFO,