- 根目录:
- sound
- usb
- mixer.c
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/hwdep.h>
#include <sound/info.h>
#include <sound/tlv.h>
#include "usbaudio.h"
#include "mixer.h"
#include "helper.h"
#include "mixer_quirks.h"
#include "power.h"
#define MAX_ID_ELEMS 256
struct usb_audio_term {
int id;
int type;
int channels;
unsigned int chconfig;
int name;
};
struct usbmix_name_map;
struct mixer_build {
struct snd_usb_audio *chip;
struct usb_mixer_interface *mixer;
unsigned char *buffer;
unsigned int buflen;
DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
struct usb_audio_term oterm;
const struct usbmix_name_map *map;
const struct usbmix_selector_map *selector_map;
};
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,
USB_XU_CLOCK_RATE_SELECTOR = 0x03,
USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01,
USB_XU_SOFT_LIMIT_SELECTOR = 0x03
};
#include "mixer_maps.c"
static const struct usbmix_name_map *
find_map(struct mixer_build *state, int unitid, int control)
{
const struct usbmix_name_map *p = state->map;
if (!p)
return NULL;
for (p = state->map; p->id; p++) {
if (p->id == unitid &&
(!control || !p->control || control == p->control))
return p;
}
return NULL;
}
static int
check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
{
if (!p || !p->name)
return 0;
buflen--;
return strlcpy(buf, p->name, buflen);
}
static inline int
check_ignored_ctl(const struct usbmix_name_map *p)
{
if (!p || p->name || p->dB)
return 0;
return 1;
}
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;
cval->initialized = 1;
}
}
static int check_mapped_selector_name(struct mixer_build *state, int unitid,
int index, char *buf, int buflen)
{
const struct usbmix_selector_map *p;
if (! state->selector_map)
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;
}
static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
{
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 &&
hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER &&
hdr->bUnitID == unit)
return hdr;
}
return NULL;
}
static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
{
int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
buf[len] = 0;
return len;
}
static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
{
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;
}
static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
{
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;
}
static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
{
if (! cval->res)
cval->res = 1;
if (val < cval->min)
return 0;
else if (val >= cval->max)
return (cval->max - cval->min + cval->res - 1) / cval->res;
else
return (val - cval->min) / cval->res;
}
static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
{
if (val < 0)
return cval->min;
if (! cval->res)
cval->res = 1;
val *= cval->res;
val += cval->min;
if (val > cval->max)
return cval->max;
return val;
}
static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
int timeout = 10;
int idx = 0, err;
err = snd_usb_autoresume(cval->mixer->chip);
if (err < 0)
return -EIO;
down_read(&chip->shutdown_rwsem);
while (timeout-- > 0) {
if (chip->shutdown)
break;
idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
if (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) >= val_len) {
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
err = 0;
goto out;
}
}
snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, idx, cval->val_type);
err = -EINVAL;
out:
up_read(&chip->shutdown_rwsem);
snd_usb_autosuspend(cval->mixer->chip);
return err;
}
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2 + 3*sizeof(__u16)];
unsigned char *val;
int idx = 0, ret, size;
__u8 bRequest;
if (request == UAC_GET_CUR) {
bRequest = UAC2_CS_CUR;
size = sizeof(__u16);
} else {
bRequest = UAC2_CS_RANGE;
size = sizeof(buf);
}
memset(buf, 0, sizeof(buf));
ret = snd_usb_autoresume(chip) ? -EIO : 0;
if (ret)
goto error;
down_read(&chip->shutdown_rwsem);
if (chip->shutdown)
ret = -ENODEV;
else {
idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, idx, buf, size);
}
up_read(&chip->shutdown_rwsem);
snd_usb_autosuspend(chip);
if (ret < 0) {
error:
snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, idx, cval->val_type);
return ret;
}
switch (request) {
case UAC_GET_CUR:
val = buf;
break;
case UAC_GET_MIN:
val = buf + sizeof(__u16);
break;
case UAC_GET_MAX:
val = buf + sizeof(__u16) * 2;
break;
case UAC_GET_RES:
val = buf + sizeof(__u16) * 3;
break;
default:
return -EINVAL;
}
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
return 0;
}
static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
validx += cval->idx_off;
return (cval->mixer->protocol == UAC_VERSION_1) ?
get_ctl_value_v1(cval, request, validx, value_ret) :
get_ctl_value_v2(cval, request, validx, value_ret);
}
static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
{
return get_ctl_value(cval, UAC_GET_CUR, validx, value);
}
static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
int channel, int *value)
{
return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
}
static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
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) {
if (!cval->mixer->ignore_ctl_error)
snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
cval->control, channel, err);
return err;
}
cval->cached |= 1 << channel;
cval->cache_val[index] = *value;
return 0;
}
int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
int request, int validx, int value_set)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
int idx = 0, val_len, err, timeout = 10;
validx += cval->idx_off;
if (cval->mixer->protocol == UAC_VERSION_1) {
val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
} else {
val_len = sizeof(__u16);
if (request != UAC_SET_CUR) {
snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
return -EINVAL;
}
request = UAC2_CS_CUR;
}
value_set = convert_bytes_value(cval, value_set);
buf[0] = value_set & 0xff;
buf[1] = (value_set >> 8) & 0xff;
err = snd_usb_autoresume(chip);
if (err < 0)
return -EIO;
down_read(&chip->shutdown_rwsem);
while (timeout-- > 0) {
if (chip->shutdown)
break;
idx = snd_usb_ctrl_intf(chip) | (cval->id << 8);
if (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) >= 0) {
err = 0;
goto out;
}
}
snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
request, validx, idx, cval->val_type, buf[0], buf[1]);
err = -EINVAL;
out:
up_read(&chip->shutdown_rwsem);
snd_usb_autosuspend(chip);
return err;
}
static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
{
return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
}
static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
int index, int value)
{
int err;
unsigned int read_only = (channel == 0) ?
cval->master_readonly :
cval->ch_readonly & (1 << (channel - 1));
if (read_only) {
snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n",
__func__, channel, cval->control);
return 0;
}
err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
value);
if (err < 0)
return err;
cval->cached |= 1 << channel;
cval->cache_val[index] = value;
return 0;
}
int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *_tlv)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
DECLARE_TLV_DB_MINMAX(scale, 0, 0);
if (size < sizeof(scale))
return -ENOMEM;
scale[2] = cval->dBmin;
scale[3] = cval->dBmax;
if (copy_to_user(_tlv, scale, sizeof(scale)))
return -EFAULT;
return 0;
}
static int parse_audio_unit(struct mixer_build *state, int unitid);
static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
{
int idx = ich * num_outs + och;
return bmap[idx >> 3] & (0x80 >> (idx & 7));
}
int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
struct snd_kcontrol *kctl)
{
struct usb_mixer_elem_info *cval = kctl->private_data;
int err;
while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
kctl->id.index++;
if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
return err;
}
cval->elem_id = &kctl->id;
cval->next_id_elem = mixer->id_elems[cval->id];
mixer->id_elems[cval->id] = cval;
return 0;
}
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 },
};
static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm,
unsigned char *name, int maxlen, int term_only)
{
struct iterm_name_combo *names;
if (iterm->name)
return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
if (iterm->type >> 16) {
if (term_only)
return 0;
switch (iterm->type >> 16) {
case UAC_SELECTOR_UNIT:
strcpy(name, "Selector"); return 8;
case UAC1_PROCESSING_UNIT:
strcpy(name, "Process Unit"); return 12;
case UAC1_EXTENSION_UNIT:
strcpy(name, "Ext Unit"); return 8;
case UAC_MIXER_UNIT:
strcpy(name, "Mixer"); return 5;
default:
return sprintf(name, "Unit %d", iterm->id);
}
}
switch (iterm->type & 0xff00) {
case 0x0100:
strcpy(name, "PCM"); return 3;
case 0x0200:
strcpy(name, "Mic"); return 3;
case 0x0400:
strcpy(name, "Headset"); return 7;
case 0x0500:
strcpy(name, "Phone"); return 5;
}
for (names = iterm_names; names->type; names++)
if (names->type == iterm->type) {
strcpy(name, names->name);
return strlen(names->name);
}
return 0;
}
static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
{
int err;
void *p1;
memset(term, 0, sizeof(*term));
while ((p1 = find_audio_control_unit(state, id)) != NULL) {
unsigned char *hdr = p1;
term->id = id;
switch (hdr[2]) {
case UAC_INPUT_TERMINAL:
if (state->mixer->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 {
struct uac2_input_terminal_descriptor *d = p1;
term->type = le16_to_cpu(d->wTerminalType);
term->channels = d->bNrChannels;
term->chconfig = le32_to_cpu(d->bmChannelConfig);
term->name = d->iTerminal;
err = check_input_term(state, d->bCSourceID, term);
if (err < 0)
return err;
}
return 0;
case UAC_FEATURE_UNIT: {
struct uac_feature_unit_descriptor *d = p1;
id = d->bSourceID;
break;
}
case UAC_MIXER_UNIT: {
struct uac_mixer_unit_descriptor *d = p1;
term->type = d->bDescriptorSubtype << 16;
term->channels = uac_mixer_unit_bNrChannels(d);
term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->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;
err = check_input_term(state, d->baSourceID[0], term);
if (err < 0)
return err;
term->type = d->bDescriptorSubtype << 16;
term->id = id;
term->name = uac_selector_unit_iSelector(d);
return 0;
}
case UAC1_PROCESSING_UNIT:
case UAC1_EXTENSION_UNIT:
case UAC2_EXTENSION_UNIT_V2: {
struct uac_processing_unit_descriptor *d = p1;
if (state->mixer->protocol == UAC_VERSION_2 &&
hdr[2] == UAC2_EFFECT_UNIT) {
return 0;
}
if (d->bNrInPins) {
id = d->baSourceID[0];
break;
}
term->type = d->bDescriptorSubtype << 16;
term->channels = uac_processing_unit_bNrChannels(d);
term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
return 0;
}
case UAC2_CLOCK_SOURCE: {
struct uac_clock_source_descriptor *d = p1;
term->type = d->bDescriptorSubtype << 16;
term->id = id;
term->name = d->iClockSource;
return 0;
}
default:
return -ENODEV;
}
}
return -ENODEV;
}
struct usb_feature_control_info {
const char *name;
unsigned int type;
};
static struct usb_feature_control_info audio_feature_info[] = {
{ "Mute", USB_MIXER_INV_BOOLEAN },
{ "Volume", USB_MIXER_S16 },
{ "Tone Control - Bass", USB_MIXER_S8 },
{ "Tone Control - Mid", USB_MIXER_S8 },
{ "Tone Control - Treble", USB_MIXER_S8 },
{ "Graphic Equalizer", USB_MIXER_S8 },
{ "Auto Gain Control", USB_MIXER_BOOLEAN },
{ "Delay Control", USB_MIXER_U16 },
{ "Bass Boost", USB_MIXER_BOOLEAN },
{ "Loudness", USB_MIXER_BOOLEAN },
{ "Input Gain Control", USB_MIXER_U16 },
{ "Input Gain Pad Control", USB_MIXER_BOOLEAN },
{ "Phase Inverter Control", USB_MIXER_BOOLEAN },
};
static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
{
kfree(kctl->private_data);
kctl->private_data = NULL;
}
static void volume_control_quirks(struct usb_mixer_elem_info *cval,
struct snd_kcontrol *kctl)
{
switch (cval->mixer->chip->usb_id) {
case USB_ID(0x0763, 0x2030):
case USB_ID(0x0763, 0x2031):
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;
cval->max = 0xfcfe;
cval->res = 0x0073;
}
break;
case USB_ID(0x0763, 0x2081):
case USB_ID(0x0763, 0x2080):
if (strcmp(kctl->id.name, "Effect Duration") == 0) {
snd_printk(KERN_INFO
"usb-audio: set quirk for FTU Effect Duration\n");
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) {
snd_printk(KERN_INFO
"usb-audio: set quirks for FTU Effect Feedback/Volume\n");
cval->min = 0x00;
cval->max = 0x7f;
break;
}
break;
case USB_ID(0x0471, 0x0101):
case USB_ID(0x0471, 0x0104):
case USB_ID(0x0471, 0x0105):
case USB_ID(0x0672, 0x1041):
if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
cval->min == -15616) {
snd_printk(KERN_INFO
"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")) {
snd_printk(KERN_INFO
"set volume quirk for QuickCam E3500\n");
cval->min = 6080;
cval->max = 8768;
cval->res = 192;
}
break;
case USB_ID(0x046d, 0x0808):
case USB_ID(0x046d, 0x0809):
case USB_ID(0x046d, 0x081b):
case USB_ID(0x046d, 0x081d):
case USB_ID(0x046d, 0x0825):
case USB_ID(0x046d, 0x0991):
if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
snd_printk(KERN_INFO
"set resolution quirk: cval->res = 384\n");
cval->res = 384;
}
break;
}
}
static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
int default_min, struct snd_kcontrol *kctl)
{
cval->min = default_min;
cval->max = cval->min + 1;
cval->res = 1;
cval->dBmin = cval->dBmax = 0;
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;
}
}
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) {
snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
return -EINVAL;
}
if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
cval->res = 1;
} else {
int last_valid_res = cval->res;
while (cval->res > 1) {
if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
(cval->control << 8) | minchn, cval->res / 2) < 0)
break;
cval->res /= 2;
}
if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
cval->res = last_valid_res;
}
if (cval->res == 0)
cval->res = 1;
if (cval->min + cval->res < cval->max) {
int last_valid_res = cval->res;
int saved, test, check;
get_cur_mix_raw(cval, minchn, &saved);
for (;;) {
test = saved;
if (test < cval->max)
test += cval->res;
else
test -= cval->res;
if (test < cval->min || test > cval->max ||
set_cur_mix_value(cval, minchn, 0, test) ||
get_cur_mix_raw(cval, minchn, &check)) {
cval->res = last_valid_res;
break;
}
if (test == check)
break;
cval->res *= 2;
}
set_cur_mix_value(cval, minchn, 0, saved);
}
cval->initialized = 1;
}
if (kctl)
volume_control_quirks(cval, kctl);
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) {
if (cval->dBmin < 0)
cval->dBmax = 0;
else if (cval->dBmin > 0)
cval->dBmin = 0;
if (cval->dBmin > cval->dBmax) {
return -EINVAL;
}
}
return 0;
}
#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
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 {
if (!cval->initialized) {
get_min_max_with_quirks(cval, 0, kcontrol);
if (cval->initialized && cval->dBmin >= cval->dBmax) {
kcontrol->vd[0].access &=
~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
snd_ctl_notify(cval->mixer->chip->card,
SNDRV_CTL_EVENT_MASK_INFO,
&kcontrol->id);
}
}
uinfo->value.integer.min = 0;
uinfo->value.integer.max =
(cval->max - cval->min + cval->res - 1) / cval->res;
}
return 0;
}
static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, err;
ucontrol->value.integer.value[0] = cval->min;
if (cval->cmask) {
cnt = 0;
for (c = 0; c < MAX_CHANNELS; c++) {
if (!(cval->cmask & (1 << c)))
continue;
err = get_cur_mix_value(cval, c + 1, cnt, &val);
if (err < 0)
return cval->mixer->ignore_ctl_error ? 0 : err;
val = get_relative_value(cval, val);
ucontrol->value.integer.value[cnt] = val;
cnt++;
}
return 0;
} else {
err = get_cur_mix_value(cval, 0, 0, &val);
if (err < 0)
return cval->mixer->ignore_ctl_error ? 0 : err;
val = get_relative_value(cval, val);
ucontrol->value.integer.value[0] = val;
}
return 0;
}
static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int c, cnt, val, oval, err;
int changed = 0;
if (cval->cmask) {
cnt = 0;
for (c = 0; c < MAX_CHANNELS; c++) {
if (!(cval->cmask & (1 << c)))
continue;
err = get_cur_mix_value(cval, c + 1, cnt, &oval);
if (err < 0)
return cval->mixer->ignore_ctl_error ? 0 : err;
val = ucontrol->value.integer.value[cnt];
val = get_abs_value(cval, val);
if (oval != val) {
set_cur_mix_value(cval, c + 1, cnt, val);
changed = 1;
}
cnt++;
}
} else {
err = get_cur_mix_value(cval, 0, 0, &oval);
if (err < 0)
return cval->mixer->ignore_ctl_error ? 0 : err;
val = ucontrol->value.integer.value[0];
val = get_abs_value(cval, val);
if (val != oval) {
set_cur_mix_value(cval, 0, 0, val);
changed = 1;
}
}
return changed;
}
static struct snd_kcontrol_new usb_feature_unit_ctl = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "",
.info = mixer_ctl_feature_info,
.get = mixer_ctl_feature_get,
.put = mixer_ctl_feature_put,
};
static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "",
.info = mixer_ctl_feature_info,
.get = mixer_ctl_feature_get,
.put = NULL,
};
struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
{
return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
}
static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
struct snd_card *card)
{
const char *names_to_check[] = {
"Headset", "headset", "Headphone", "headphone", NULL};
const char **s;
bool found = 0;
if (strcmp("Speaker", kctl->id.name))
return;
for (s = names_to_check; *s; s++)
if (strstr(card->shortname, *s)) {
found = 1;
break;
}
if (!found)
return;
strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
}
static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
unsigned int ctl_mask, int control,
struct usb_audio_term *iterm, int unitid,
int readonly_mask)
{
struct uac_feature_unit_descriptor *desc = raw_desc;
unsigned int len = 0;
int mapped_name = 0;
int nameid = uac_feature_unit_iFeature(desc);
struct snd_kcontrol *kctl;
struct usb_mixer_elem_info *cval;
const struct usbmix_name_map *map;
unsigned int range;
control++;
if (control == UAC_FU_GRAPHIC_EQUALIZER) {
return;
}
map = find_map(state, unitid, control);
if (check_ignored_ctl(map))
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return;
}
cval->mixer = state->mixer;
cval->id = unitid;
cval->control = control;
cval->cmask = ctl_mask;
cval->val_type = audio_feature_info[control-1].type;
if (ctl_mask == 0) {
cval->channels = 1;
cval->master_readonly = readonly_mask;
} else {
int i, c = 0;
for (i = 0; i < 16; i++)
if (ctl_mask & (1 << i))
c++;
cval->channels = c;
cval->ch_readonly = readonly_mask;
}
if (cval->channels == readonly_mask)
kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
else
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
kfree(cval);
return;
}
kctl->private_free = usb_mixer_elem_free;
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
mapped_name = len != 0;
if (! len && nameid)
len = snd_usb_copy_string_desc(state, nameid,
kctl->id.name, sizeof(kctl->id.name));
switch (control) {
case UAC_FU_MUTE:
case UAC_FU_VOLUME:
if (! len) {
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
if (! len)
len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
if (! len)
len = snprintf(kctl->id.name, sizeof(kctl->id.name),
"Feature %d", unitid);
}
if (!mapped_name)
check_no_speaker_on_headset(kctl, state->mixer->chip->card);
if (! mapped_name && ! (state->oterm.type >> 16)) {
if ((state->oterm.type & 0xff00) == 0x0100) {
len = append_ctl_name(kctl, " Capture");
} else {
len = append_ctl_name(kctl, " Playback");
}
}
append_ctl_name(kctl, control == UAC_FU_MUTE ?
" Switch" : " Volume");
break;
default:
if (! len)
strlcpy(kctl->id.name, audio_feature_info[control-1].name,
sizeof(kctl->id.name));
break;
}
get_min_max_with_quirks(cval, 0, kctl);
if (control == UAC_FU_VOLUME) {
check_mapped_dB(map, cval);
if (cval->dBmin < cval->dBmax || !cval->initialized) {
kctl->tlv.c = snd_usb_mixer_vol_tlv;
kctl->vd[0].access |=
SNDRV_CTL_ELEM_ACCESS_TLV_READ |
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
}
}
range = (cval->max - cval->min) / cval->res;
if (range > 384) {
snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big "
"volume range (=%u), cval->res is probably wrong.",
range);
snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, "
"val = %d/%d/%d", cval->id,
kctl->id.name, cval->channels,
cval->min, cval->max, cval->res);
}
snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
snd_usb_mixer_add_control(state->mixer, kctl);
}
static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
{
int channels, i, j;
struct usb_audio_term iterm;
unsigned int master_bits, first_ch_bits;
int err, csize;
struct uac_feature_unit_descriptor *hdr = _ftr;
__u8 *bmaControls;
if (state->mixer->protocol == UAC_VERSION_1) {
csize = hdr->bControlSize;
if (!csize) {
snd_printdd(KERN_ERR "usbaudio: unit %u: "
"invalid bControlSize == 0\n", unitid);
return -EINVAL;
}
channels = (hdr->bLength - 7) / csize - 1;
bmaControls = hdr->bmaControls;
if (hdr->bLength < 7 + csize) {
snd_printk(KERN_ERR "usbaudio: unit %u: "
"invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
} else {
struct uac2_feature_unit_descriptor *ftr = _ftr;
csize = 4;
channels = (hdr->bLength - 6) / 4 - 1;
bmaControls = ftr->bmaControls;
if (hdr->bLength < 6 + csize) {
snd_printk(KERN_ERR "usbaudio: unit %u: "
"invalid UAC_FEATURE_UNIT descriptor\n",
unitid);
return -EINVAL;
}
}
if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
return err;
err = check_input_term(state, hdr->bSourceID, &iterm);
if (err < 0)
return err;
master_bits = snd_usb_combine_bytes(bmaControls, csize);
switch (state->chip->usb_id) {
case USB_ID(0x08bb, 0x2702):
snd_printk(KERN_INFO
"usbmixer: master volume quirk for PCM2702 chip\n");
master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
break;
case USB_ID(0x1130, 0xf211):
snd_printk(KERN_INFO
"usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");
channels = 0;
break;
}
if (channels > 0)
first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
else
first_ch_bits = 0;
if (state->mixer->protocol == UAC_VERSION_1) {
for (i = 0; i < 10; i++) {
unsigned int ch_bits = 0;
for (j = 0; j < channels; j++) {
unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
if (mask & (1 << i))
ch_bits |= (1 << j);
}
if (ch_bits & 1)
build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
if (master_bits & (1 << i))
build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
}
} else {
for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
unsigned int ch_bits = 0;
unsigned int ch_read_only = 0;
for (j = 0; j < channels; j++) {
unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
if (uac2_control_is_readable(mask, i)) {
ch_bits |= (1 << j);
if (!uac2_control_is_writeable(mask, i))
ch_read_only |= (1 << j);
}
}
if (ch_bits & 1)
build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
if (uac2_control_is_readable(master_bits, i))
build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
!uac2_control_is_writeable(master_bits, i));
}
}
return 0;
}
static void build_mixer_unit_ctl(struct mixer_build *state,
struct uac_mixer_unit_descriptor *desc,
int in_pin, int in_ch, int unitid,
struct usb_audio_term *iterm)
{
struct usb_mixer_elem_info *cval;
unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
unsigned int i, len;
struct snd_kcontrol *kctl;
const struct usbmix_name_map *map;
map = find_map(state, unitid, 0);
if (check_ignored_ctl(map))
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval)
return;
cval->mixer = state->mixer;
cval->id = unitid;
cval->control = in_ch + 1;
cval->val_type = USB_MIXER_S16;
for (i = 0; i < num_outs; i++) {
if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
cval->cmask |= (1 << i);
cval->channels++;
}
}
get_min_max(cval, 0);
kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
if (! kctl) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
kfree(cval);
return;
}
kctl->private_free = usb_mixer_elem_free;
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
if (! len)
len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
if (! len)
len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
append_ctl_name(kctl, " Volume");
snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
snd_usb_mixer_add_control(state->mixer, kctl);
}
static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
{
struct uac_mixer_unit_descriptor *desc = raw_desc;
struct usb_audio_term iterm;
int input_pins, num_ins, num_outs;
int pin, ich, err;
if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
return -EINVAL;
}
if (desc->bLength <= 10 + input_pins) {
snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
return 0;
}
num_ins = 0;
ich = 0;
for (pin = 0; pin < input_pins; pin++) {
err = parse_audio_unit(state, desc->baSourceID[pin]);
if (err < 0)
continue;
err = check_input_term(state, desc->baSourceID[pin], &iterm);
if (err < 0)
return err;
num_ins += iterm.channels;
for (; ich < num_ins; ++ich) {
int och, ich_has_controls = 0;
for (och = 0; och < num_outs; ++och) {
if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
ich, och, num_outs)) {
ich_has_controls = 1;
break;
}
}
if (ich_has_controls)
build_mixer_unit_ctl(state, desc, pin, ich,
unitid, &iterm);
}
}
return 0;
}
static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int err, val;
err = get_cur_ctl_value(cval, cval->control << 8, &val);
if (err < 0 && cval->mixer->ignore_ctl_error) {
ucontrol->value.integer.value[0] = cval->min;
return 0;
}
if (err < 0)
return err;
val = get_relative_value(cval, val);
ucontrol->value.integer.value[0] = val;
return 0;
}
static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
err = get_cur_ctl_value(cval, cval->control << 8, &oval);
if (err < 0) {
if (cval->mixer->ignore_ctl_error)
return 0;
return err;
}
val = ucontrol->value.integer.value[0];
val = get_abs_value(cval, val);
if (val != oval) {
set_cur_ctl_value(cval, cval->control << 8, val);
return 1;
}
return 0;
}
static struct snd_kcontrol_new mixer_procunit_ctl = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "",
.info = mixer_ctl_feature_info,
.get = mixer_ctl_procunit_get,
.put = mixer_ctl_procunit_put,
};
struct procunit_value_info {
int control;
char *suffix;
int val_type;
int min_value;
};
struct procunit_info {
int type;
char *name;
struct procunit_value_info *values;
};
static struct procunit_value_info updown_proc_info[] = {
{ UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
{ 0 }
};
static struct procunit_value_info prologic_proc_info[] = {
{ UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
{ 0 }
};
static struct procunit_value_info threed_enh_proc_info[] = {
{ UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 },
{ 0 }
};
static struct procunit_value_info reverb_proc_info[] = {
{ UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
{ UAC_REVERB_TIME, "Time", USB_MIXER_U16 },
{ UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 },
{ 0 }
};
static struct procunit_value_info chorus_proc_info[] = {
{ UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
{ UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
{ UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
{ 0 }
};
static struct procunit_value_info dcr_proc_info[] = {
{ UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN },
{ UAC_DCR_RATE, "Ratio", USB_MIXER_U16 },
{ UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 },
{ UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
{ UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 },
{ UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 },
{ 0 }
};
static struct procunit_info procunits[] = {
{ UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info },
{ UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info },
{ UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info },
{ UAC_PROCESS_REVERB, "Reverb", reverb_proc_info },
{ UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info },
{ UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
{ 0 },
};
static struct procunit_value_info clock_rate_xu_info[] = {
{ USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
{ 0 }
};
static struct procunit_value_info clock_source_xu_info[] = {
{ USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
{ 0 }
};
static struct procunit_value_info spdif_format_xu_info[] = {
{ USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
{ 0 }
};
static struct procunit_value_info soft_limit_xu_info[] = {
{ USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
{ 0 }
};
static struct procunit_info extunits[] = {
{ USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
{ USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
{ USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
{ USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
{ 0 }
};
static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
{
struct uac_processing_unit_descriptor *desc = raw_desc;
int num_ins = desc->bNrInPins;
struct usb_mixer_elem_info *cval;
struct snd_kcontrol *kctl;
int i, err, nameid, type, len;
struct procunit_info *info;
struct procunit_value_info *valinfo;
const struct usbmix_name_map *map;
static struct procunit_value_info default_value_info[] = {
{ 0x01, "Switch", USB_MIXER_BOOLEAN },
{ 0 }
};
static struct procunit_info default_info = {
0, NULL, default_value_info
};
if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
return -EINVAL;
}
for (i = 0; i < num_ins; i++) {
if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
return err;
}
type = le16_to_cpu(desc->wProcessType);
for (info = list; info && info->type; info++)
if (info->type == type)
break;
if (! info || ! info->type)
info = &default_info;
for (valinfo = info->values; valinfo->control; valinfo++) {
__u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
continue;
map = find_map(state, unitid, valinfo->control);
if (check_ignored_ctl(map))
continue;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return -ENOMEM;
}
cval->mixer = state->mixer;
cval->id = unitid;
cval->control = valinfo->control;
cval->val_type = valinfo->val_type;
cval->channels = 1;
if (type == UAC_PROCESS_UP_DOWNMIX && cval->control == UAC_UD_MODE_SELECT) {
__u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
cval->min = 1;
cval->max = control_spec[0];
cval->res = 1;
cval->initialized = 1;
} else {
if (type == USB_XU_CLOCK_RATE) {
cval->min = 0;
cval->max = 5;
cval->res = 1;
cval->initialized = 1;
} else
get_min_max(cval, valinfo->min_value);
}
kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
if (! kctl) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
kfree(cval);
return -ENOMEM;
}
kctl->private_free = usb_mixer_elem_free;
if (check_mapped_name(map, kctl->id.name,
sizeof(kctl->id.name)))
;
else if (info->name)
strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
else {
nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
len = 0;
if (nameid)
len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
if (! len)
strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
}
append_ctl_name(kctl, " ");
append_ctl_name(kctl, valinfo->suffix);
snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
return err;
}
return 0;
}
static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
{
return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
}
static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
{
return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
}
static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
const char **itemlist = (const char **)kcontrol->private_value;
if (snd_BUG_ON(!itemlist))
return -EINVAL;
return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
}
static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, err;
err = get_cur_ctl_value(cval, cval->control << 8, &val);
if (err < 0) {
if (cval->mixer->ignore_ctl_error) {
ucontrol->value.enumerated.item[0] = 0;
return 0;
}
return err;
}
val = get_relative_value(cval, val);
ucontrol->value.enumerated.item[0] = val;
return 0;
}
static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *cval = kcontrol->private_data;
int val, oval, err;
err = get_cur_ctl_value(cval, cval->control << 8, &oval);
if (err < 0) {
if (cval->mixer->ignore_ctl_error)
return 0;
return err;
}
val = ucontrol->value.enumerated.item[0];
val = get_abs_value(cval, val);
if (val != oval) {
set_cur_ctl_value(cval, cval->control << 8, val);
return 1;
}
return 0;
}
static struct snd_kcontrol_new mixer_selectunit_ctl = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "",
.info = mixer_ctl_selector_info,
.get = mixer_ctl_selector_get,
.put = mixer_ctl_selector_put,
};
static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
{
int i, num_ins = 0;
if (kctl->private_data) {
struct usb_mixer_elem_info *cval = kctl->private_data;
num_ins = cval->max;
kfree(cval);
kctl->private_data = NULL;
}
if (kctl->private_value) {
char **itemlist = (char **)kctl->private_value;
for (i = 0; i < num_ins; i++)
kfree(itemlist[i]);
kfree(itemlist);
kctl->private_value = 0;
}
}
static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
{
struct uac_selector_unit_descriptor *desc = raw_desc;
unsigned int i, nameid, len;
int err;
struct usb_mixer_elem_info *cval;
struct snd_kcontrol *kctl;
const struct usbmix_name_map *map;
char **namelist;
if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
return -EINVAL;
}
for (i = 0; i < desc->bNrInPins; i++) {
if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
return err;
}
if (desc->bNrInPins == 1)
return 0;
map = find_map(state, unitid, 0);
if (check_ignored_ctl(map))
return 0;
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (! cval) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
return -ENOMEM;
}
cval->mixer = state->mixer;
cval->id = unitid;
cval->val_type = USB_MIXER_U8;
cval->channels = 1;
cval->min = 1;
cval->max = desc->bNrInPins;
cval->res = 1;
cval->initialized = 1;
if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
cval->control = UAC2_CX_CLOCK_SELECTOR;
else
cval->control = 0;
namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
if (! namelist) {
snd_printk(KERN_ERR "cannot malloc\n");
kfree(cval);
return -ENOMEM;
}
#define MAX_ITEM_NAME_LEN 64
for (i = 0; i < desc->bNrInPins; i++) {
struct usb_audio_term iterm;
len = 0;
namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
if (! namelist[i]) {
snd_printk(KERN_ERR "cannot malloc\n");
while (i--)
kfree(namelist[i]);
kfree(namelist);
kfree(cval);
return -ENOMEM;
}
len = check_mapped_selector_name(state, unitid, i, namelist[i],
MAX_ITEM_NAME_LEN);
if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
if (! len)
sprintf(namelist[i], "Input %d", i);
}
kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
if (! kctl) {
snd_printk(KERN_ERR "cannot malloc kcontrol\n");
kfree(namelist);
kfree(cval);
return -ENOMEM;
}
kctl->private_value = (unsigned long)namelist;
kctl->private_free = usb_mixer_selector_elem_free;
nameid = uac_selector_unit_iSelector(desc);
len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
if (len)
;
else if (nameid)
snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
else {
len = get_term_name(state, &state->oterm,
kctl->id.name, sizeof(kctl->id.name), 0);
if (! len)
strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
append_ctl_name(kctl, " Clock Source");
else if ((state->oterm.type & 0xff00) == 0x0100)
append_ctl_name(kctl, " Capture Source");
else
append_ctl_name(kctl, " Playback Source");
}
snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
cval->id, kctl->id.name, desc->bNrInPins);
if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
return err;
return 0;
}
static int parse_audio_unit(struct mixer_build *state, int unitid)
{
unsigned char *p1;
if (test_and_set_bit(unitid, state->unitbitmap))
return 0;
p1 = find_audio_control_unit(state, unitid);
if (!p1) {
snd_printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
return -EINVAL;
}
switch (p1[2]) {
case UAC_INPUT_TERMINAL:
case UAC2_CLOCK_SOURCE:
return 0;
case UAC_MIXER_UNIT:
return parse_audio_mixer_unit(state, unitid, p1);
case UAC_SELECTOR_UNIT:
case UAC2_CLOCK_SELECTOR:
return parse_audio_selector_unit(state, unitid, p1);
case UAC_FEATURE_UNIT:
return parse_audio_feature_unit(state, unitid, p1);
case UAC1_PROCESSING_UNIT:
if (state->mixer->protocol == UAC_VERSION_1)
return parse_audio_processing_unit(state, unitid, p1);
else
return 0;
case UAC1_EXTENSION_UNIT:
if (state->mixer->protocol == UAC_VERSION_1)
return parse_audio_extension_unit(state, unitid, p1);
else
return parse_audio_processing_unit(state, unitid, p1);
case UAC2_EXTENSION_UNIT_V2:
return parse_audio_extension_unit(state, unitid, p1);
default:
snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
return -EINVAL;
}
}
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
kfree(mixer->id_elems);
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
usb_free_urb(mixer->urb);
}
usb_free_urb(mixer->rc_urb);
kfree(mixer->rc_setup_packet);
kfree(mixer);
}
static int snd_usb_mixer_dev_free(struct snd_device *device)
{
struct usb_mixer_interface *mixer = device->device_data;
snd_usb_mixer_free(mixer);
return 0;
}
static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
{
struct mixer_build state;
int err;
const struct usbmix_ctl_map *map;
void *p;
memset(&state, 0, sizeof(state));
state.chip = mixer->chip;
state.mixer = mixer;
state.buffer = mixer->hostif->extra;
state.buflen = mixer->hostif->extralen;
for (map = usbmix_ctl_maps; map->id; map++) {
if (map->id == state.chip->usb_id) {
state.map = map->map;
state.selector_map = map->selector_map;
mixer->ignore_ctl_error = map->ignore_ctl_error;
break;
}
}
p = NULL;
while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
p, UAC_OUTPUT_TERMINAL)) != NULL) {
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;
if (desc->bLength < sizeof(*desc))
continue;
set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
err = parse_audio_unit(&state, desc->bSourceID);
if (err < 0 && err != -EINVAL)
return err;
} else {
struct uac2_output_terminal_descriptor *desc = p;
if (desc->bLength < sizeof(*desc))
continue;
set_bit(desc->bTerminalID, state.unitbitmap);
state.oterm.id = desc->bTerminalID;
state.oterm.type = le16_to_cpu(desc->wTerminalType);
state.oterm.name = desc->iTerminal;
err = parse_audio_unit(&state, desc->bSourceID);
if (err < 0 && err != -EINVAL)
return err;
err = parse_audio_unit(&state, desc->bCSourceID);
if (err < 0 && err != -EINVAL)
return err;
}
}
return 0;
}
void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
{
struct usb_mixer_elem_info *info;
for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
info->elem_id);
}
static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
int unitid,
struct usb_mixer_elem_info *cval)
{
static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
"S8", "U8", "S16", "U16"};
snd_iprintf(buffer, " Unit: %i\n", unitid);
if (cval->elem_id)
snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
cval->elem_id->name, cval->elem_id->index);
snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
"channels=%i, type=\"%s\"\n", cval->id,
cval->control, cval->cmask, cval->channels,
val_types[cval->val_type]);
snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
cval->min, cval->max, cval->dBmin, cval->dBmax);
}
static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_usb_audio *chip = entry->private_data;
struct usb_mixer_interface *mixer;
struct usb_mixer_elem_info *cval;
int unitid;
list_for_each_entry(mixer, &chip->mixer_list, list) {
snd_iprintf(buffer,
"USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
chip->usb_id, snd_usb_ctrl_intf(chip),
mixer->ignore_ctl_error);
snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
for (cval = mixer->id_elems[unitid]; cval;
cval = cval->next_id_elem)
snd_usb_mixer_dump_cval(buffer, unitid, cval);
}
}
}
static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
int attribute, int value, int index)
{
struct usb_mixer_elem_info *info;
__u8 unitid = (index >> 8) & 0xff;
__u8 control = (value >> 8) & 0xff;
__u8 channel = value & 0xff;
if (channel >= MAX_CHANNELS) {
snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n",
__func__, channel);
return;
}
for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) {
if (info->control != control)
continue;
switch (attribute) {
case UAC2_CS_CUR:
if (channel)
info->cached &= ~(1 << channel);
else
info->cached = 0;
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
info->elem_id);
break;
case UAC2_CS_RANGE:
break;
case UAC2_CS_MEM:
break;
default:
snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n",
attribute);
break;
}
}
}
static void snd_usb_mixer_interrupt(struct urb *urb)
{
struct usb_mixer_interface *mixer = urb->context;
int len = urb->actual_length;
int ustatus = urb->status;
if (ustatus != 0)
goto requeue;
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_status_word *status;
for (status = urb->transfer_buffer;
len >= sizeof(*status);
len -= sizeof(*status), status++) {
snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
status->bStatusType,
status->bOriginator);
if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
continue;
if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
else
snd_usb_mixer_notify_id(mixer, status->bOriginator);
}
} else {
struct uac2_interrupt_data_msg *msg;
for (msg = urb->transfer_buffer;
len >= sizeof(*msg);
len -= sizeof(*msg), msg++) {
if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
(msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
continue;
snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
le16_to_cpu(msg->wValue),
le16_to_cpu(msg->wIndex));
}
}
requeue:
if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
urb->dev = mixer->chip->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
}
void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
{
usb_kill_urb(mixer->urb);
usb_kill_urb(mixer->rc_urb);
}
int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
{
int err;
if (mixer->urb) {
err = usb_submit_urb(mixer->urb, GFP_NOIO);
if (err < 0)
return err;
}
return 0;
}
static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
{
struct usb_endpoint_descriptor *ep;
void *transfer_buffer;
int buffer_length;
unsigned int epnum;
if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1)
return 0;
ep = get_endpoint(mixer->hostif, 0);
if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
return 0;
epnum = usb_endpoint_num(ep);
buffer_length = le16_to_cpu(ep->wMaxPacketSize);
transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
if (!transfer_buffer)
return -ENOMEM;
mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!mixer->urb) {
kfree(transfer_buffer);
return -ENOMEM;
}
usb_fill_int_urb(mixer->urb, mixer->chip->dev,
usb_rcvintpipe(mixer->chip->dev, epnum),
transfer_buffer, buffer_length,
snd_usb_mixer_interrupt, mixer, ep->bInterval);
usb_submit_urb(mixer->urb, GFP_KERNEL);
return 0;
}
int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
int ignore_error)
{
static struct snd_device_ops dev_ops = {
.dev_free = snd_usb_mixer_dev_free
};
struct usb_mixer_interface *mixer;
struct snd_info_entry *entry;
int err;
strcpy(chip->card->mixername, "USB Mixer");
mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
if (!mixer)
return -ENOMEM;
mixer->chip = chip;
mixer->ignore_ctl_error = ignore_error;
mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
GFP_KERNEL);
if (!mixer->id_elems) {
kfree(mixer);
return -ENOMEM;
}
mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) {
case UAC_VERSION_1:
default:
mixer->protocol = UAC_VERSION_1;
break;
case UAC_VERSION_2:
mixer->protocol = UAC_VERSION_2;
break;
}
if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
(err = snd_usb_mixer_status_create(mixer)) < 0)
goto _error;
snd_usb_mixer_apply_create_quirk(mixer);
err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
if (err < 0)
goto _error;
if (list_empty(&chip->mixer_list) &&
!snd_card_proc_new(chip->card, "usbmixer", &entry))
snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
list_add(&mixer->list, &chip->mixer_list);
return 0;
_error:
snd_usb_mixer_free(mixer);
return err;
}
void snd_usb_mixer_disconnect(struct list_head *p)
{
struct usb_mixer_interface *mixer;
mixer = list_entry(p, struct usb_mixer_interface, list);
usb_kill_urb(mixer->urb);
usb_kill_urb(mixer->rc_urb);
}
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 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
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 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
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 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
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 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
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 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
- 1025
- 1026
- 1027
- 1028
- 1029
- 1030
- 1031
- 1032
- 1033
- 1034
- 1035
- 1036
- 1037
- 1038
- 1039
- 1040
- 1041
- 1042
- 1043
- 1044
- 1045
- 1046
- 1047
- 1048
- 1049
- 1050
- 1051
- 1052
- 1053
- 1054
- 1055
- 1056
- 1057
- 1058
- 1059
- 1060
- 1061
- 1062
- 1063
- 1064
- 1065
- 1066
- 1067
- 1068
- 1069
- 1070
- 1071
- 1072
- 1073
- 1074
- 1075
- 1076
- 1077
- 1078
- 1079
- 1080
- 1081
- 1082
- 1083
- 1084
- 1085
- 1086
- 1087
- 1088
- 1089
- 1090
- 1091
- 1092
- 1093
- 1094
- 1095
- 1096
- 1097
- 1098
- 1099
- 1100
- 1101
- 1102
- 1103
- 1104
- 1105
- 1106
- 1107
- 1108
- 1109
- 1110
- 1111
- 1112
- 1113
- 1114
- 1115
- 1116
- 1117
- 1118
- 1119
- 1120
- 1121
- 1122
- 1123
- 1124
- 1125
- 1126
- 1127
- 1128
- 1129
- 1130
- 1131
- 1132
- 1133
- 1134
- 1135
- 1136
- 1137
- 1138
- 1139
- 1140
- 1141
- 1142
- 1143
- 1144
- 1145
- 1146
- 1147
- 1148
- 1149
- 1150
- 1151
- 1152
- 1153
- 1154
- 1155
- 1156
- 1157
- 1158
- 1159
- 1160
- 1161
- 1162
- 1163
- 1164
- 1165
- 1166
- 1167
- 1168
- 1169
- 1170
- 1171
- 1172
- 1173
- 1174
- 1175
- 1176
- 1177
- 1178
- 1179
- 1180
- 1181
- 1182
- 1183
- 1184
- 1185
- 1186
- 1187
- 1188
- 1189
- 1190
- 1191
- 1192
- 1193
- 1194
- 1195
- 1196
- 1197
- 1198
- 1199
- 1200
- 1201
- 1202
- 1203
- 1204
- 1205
- 1206
- 1207
- 1208
- 1209
- 1210
- 1211
- 1212
- 1213
- 1214
- 1215
- 1216
- 1217
- 1218
- 1219
- 1220
- 1221
- 1222
- 1223
- 1224
- 1225
- 1226
- 1227
- 1228
- 1229
- 1230
- 1231
- 1232
- 1233
- 1234
- 1235
- 1236
- 1237
- 1238
- 1239
- 1240
- 1241
- 1242
- 1243
- 1244
- 1245
- 1246
- 1247
- 1248
- 1249
- 1250
- 1251
- 1252
- 1253
- 1254
- 1255
- 1256
- 1257
- 1258
- 1259
- 1260
- 1261
- 1262
- 1263
- 1264
- 1265
- 1266
- 1267
- 1268
- 1269
- 1270
- 1271
- 1272
- 1273
- 1274
- 1275
- 1276
- 1277
- 1278
- 1279
- 1280
- 1281
- 1282
- 1283
- 1284
- 1285
- 1286
- 1287
- 1288
- 1289
- 1290
- 1291
- 1292
- 1293
- 1294
- 1295
- 1296
- 1297
- 1298
- 1299
- 1300
- 1301
- 1302
- 1303
- 1304
- 1305
- 1306
- 1307
- 1308
- 1309
- 1310
- 1311
- 1312
- 1313
- 1314
- 1315
- 1316
- 1317
- 1318
- 1319
- 1320
- 1321
- 1322
- 1323
- 1324
- 1325
- 1326
- 1327
- 1328
- 1329
- 1330
- 1331
- 1332
- 1333
- 1334
- 1335
- 1336
- 1337
- 1338
- 1339
- 1340
- 1341
- 1342
- 1343
- 1344
- 1345
- 1346
- 1347
- 1348
- 1349
- 1350
- 1351
- 1352
- 1353
- 1354
- 1355
- 1356
- 1357
- 1358
- 1359
- 1360
- 1361
- 1362
- 1363
- 1364
- 1365
- 1366
- 1367
- 1368
- 1369
- 1370
- 1371
- 1372
- 1373
- 1374
- 1375
- 1376
- 1377
- 1378
- 1379
- 1380
- 1381
- 1382
- 1383
- 1384
- 1385
- 1386
- 1387
- 1388
- 1389
- 1390
- 1391
- 1392
- 1393
- 1394
- 1395
- 1396
- 1397
- 1398
- 1399
- 1400
- 1401
- 1402
- 1403
- 1404
- 1405
- 1406
- 1407
- 1408
- 1409
- 1410
- 1411
- 1412
- 1413
- 1414
- 1415
- 1416
- 1417
- 1418
- 1419
- 1420
- 1421
- 1422
- 1423
- 1424
- 1425
- 1426
- 1427
- 1428
- 1429
- 1430
- 1431
- 1432
- 1433
- 1434
- 1435
- 1436
- 1437
- 1438
- 1439
- 1440
- 1441
- 1442
- 1443
- 1444
- 1445
- 1446
- 1447
- 1448
- 1449
- 1450
- 1451
- 1452
- 1453
- 1454
- 1455
- 1456
- 1457
- 1458
- 1459
- 1460
- 1461
- 1462
- 1463
- 1464
- 1465
- 1466
- 1467
- 1468
- 1469
- 1470
- 1471
- 1472
- 1473
- 1474
- 1475
- 1476
- 1477
- 1478
- 1479
- 1480
- 1481
- 1482
- 1483
- 1484
- 1485
- 1486
- 1487
- 1488
- 1489
- 1490
- 1491
- 1492
- 1493
- 1494
- 1495
- 1496
- 1497
- 1498
- 1499
- 1500
- 1501
- 1502
- 1503
- 1504
- 1505
- 1506
- 1507
- 1508
- 1509
- 1510
- 1511
- 1512
- 1513
- 1514
- 1515
- 1516
- 1517
- 1518
- 1519
- 1520
- 1521
- 1522
- 1523
- 1524
- 1525
- 1526
- 1527
- 1528
- 1529
- 1530
- 1531
- 1532
- 1533
- 1534
- 1535
- 1536
- 1537
- 1538
- 1539
- 1540
- 1541
- 1542
- 1543
- 1544
- 1545
- 1546
- 1547
- 1548
- 1549
- 1550
- 1551
- 1552
- 1553
- 1554
- 1555
- 1556
- 1557
- 1558
- 1559
- 1560
- 1561
- 1562
- 1563
- 1564
- 1565
- 1566
- 1567
- 1568
- 1569
- 1570
- 1571
- 1572
- 1573
- 1574
- 1575
- 1576
- 1577
- 1578
- 1579
- 1580
- 1581
- 1582
- 1583
- 1584
- 1585
- 1586
- 1587
- 1588
- 1589
- 1590
- 1591
- 1592
- 1593
- 1594
- 1595
- 1596
- 1597
- 1598
- 1599
- 1600
- 1601
- 1602
- 1603
- 1604
- 1605
- 1606
- 1607
- 1608
- 1609
- 1610
- 1611
- 1612
- 1613
- 1614
- 1615
- 1616
- 1617
- 1618
- 1619
- 1620
- 1621
- 1622
- 1623
- 1624
- 1625
- 1626
- 1627
- 1628
- 1629
- 1630
- 1631
- 1632
- 1633
- 1634
- 1635
- 1636
- 1637
- 1638
- 1639
- 1640
- 1641
- 1642
- 1643
- 1644
- 1645
- 1646
- 1647
- 1648
- 1649
- 1650
- 1651
- 1652
- 1653
- 1654
- 1655
- 1656
- 1657
- 1658
- 1659
- 1660
- 1661
- 1662
- 1663
- 1664
- 1665
- 1666
- 1667
- 1668
- 1669
- 1670
- 1671
- 1672
- 1673
- 1674
- 1675
- 1676
- 1677
- 1678
- 1679
- 1680
- 1681
- 1682
- 1683
- 1684
- 1685
- 1686
- 1687
- 1688
- 1689
- 1690
- 1691
- 1692
- 1693
- 1694
- 1695
- 1696
- 1697
- 1698
- 1699
- 1700
- 1701
- 1702
- 1703
- 1704
- 1705
- 1706
- 1707
- 1708
- 1709
- 1710
- 1711
- 1712
- 1713
- 1714
- 1715
- 1716
- 1717
- 1718
- 1719
- 1720
- 1721
- 1722
- 1723
- 1724
- 1725
- 1726
- 1727
- 1728
- 1729
- 1730
- 1731
- 1732
- 1733
- 1734
- 1735
- 1736
- 1737
- 1738
- 1739
- 1740
- 1741
- 1742
- 1743
- 1744
- 1745
- 1746
- 1747
- 1748
- 1749
- 1750
- 1751
- 1752
- 1753
- 1754
- 1755
- 1756
- 1757
- 1758
- 1759
- 1760
- 1761
- 1762
- 1763
- 1764
- 1765
- 1766
- 1767
- 1768
- 1769
- 1770
- 1771
- 1772
- 1773
- 1774
- 1775
- 1776
- 1777
- 1778
- 1779
- 1780
- 1781
- 1782
- 1783
- 1784
- 1785
- 1786
- 1787
- 1788
- 1789
- 1790
- 1791
- 1792
- 1793
- 1794
- 1795
- 1796
- 1797
- 1798
- 1799
- 1800
- 1801
- 1802
- 1803
- 1804
- 1805
- 1806
- 1807
- 1808
- 1809
- 1810
- 1811
- 1812
- 1813
- 1814
- 1815
- 1816
- 1817
- 1818
- 1819
- 1820
- 1821
- 1822
- 1823
- 1824
- 1825
- 1826
- 1827
- 1828
- 1829
- 1830
- 1831
- 1832
- 1833
- 1834
- 1835
- 1836
- 1837
- 1838
- 1839
- 1840
- 1841
- 1842
- 1843
- 1844
- 1845
- 1846
- 1847
- 1848
- 1849
- 1850
- 1851
- 1852
- 1853
- 1854
- 1855
- 1856
- 1857
- 1858
- 1859
- 1860
- 1861
- 1862
- 1863
- 1864
- 1865
- 1866
- 1867
- 1868
- 1869
- 1870
- 1871
- 1872
- 1873
- 1874
- 1875
- 1876
- 1877
- 1878
- 1879
- 1880
- 1881
- 1882
- 1883
- 1884
- 1885
- 1886
- 1887
- 1888
- 1889
- 1890
- 1891
- 1892
- 1893
- 1894
- 1895
- 1896
- 1897
- 1898
- 1899
- 1900
- 1901
- 1902
- 1903
- 1904
- 1905
- 1906
- 1907
- 1908
- 1909
- 1910
- 1911
- 1912
- 1913
- 1914
- 1915
- 1916
- 1917
- 1918
- 1919
- 1920
- 1921
- 1922
- 1923
- 1924
- 1925
- 1926
- 1927
- 1928
- 1929
- 1930
- 1931
- 1932
- 1933
- 1934
- 1935
- 1936
- 1937
- 1938
- 1939
- 1940
- 1941
- 1942
- 1943
- 1944
- 1945
- 1946
- 1947
- 1948
- 1949
- 1950
- 1951
- 1952
- 1953
- 1954
- 1955
- 1956
- 1957
- 1958
- 1959
- 1960
- 1961
- 1962
- 1963
- 1964
- 1965
- 1966
- 1967
- 1968
- 1969
- 1970
- 1971
- 1972
- 1973
- 1974
- 1975
- 1976
- 1977
- 1978
- 1979
- 1980
- 1981
- 1982
- 1983
- 1984
- 1985
- 1986
- 1987
- 1988
- 1989
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
- 2000
- 2001
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2017
- 2018
- 2019
- 2020
- 2021
- 2022
- 2023
- 2024
- 2025
- 2026
- 2027
- 2028
- 2029
- 2030
- 2031
- 2032
- 2033
- 2034
- 2035
- 2036
- 2037
- 2038
- 2039
- 2040
- 2041
- 2042
- 2043
- 2044
- 2045
- 2046
- 2047
- 2048
- 2049
- 2050
- 2051
- 2052
- 2053
- 2054
- 2055
- 2056
- 2057
- 2058
- 2059
- 2060
- 2061
- 2062
- 2063
- 2064
- 2065
- 2066
- 2067
- 2068
- 2069
- 2070
- 2071
- 2072
- 2073
- 2074
- 2075
- 2076
- 2077
- 2078
- 2079
- 2080
- 2081
- 2082
- 2083
- 2084
- 2085
- 2086
- 2087
- 2088
- 2089
- 2090
- 2091
- 2092
- 2093
- 2094
- 2095
- 2096
- 2097
- 2098
- 2099
- 2100
- 2101
- 2102
- 2103
- 2104
- 2105
- 2106
- 2107
- 2108
- 2109
- 2110
- 2111
- 2112
- 2113
- 2114
- 2115
- 2116
- 2117
- 2118
- 2119
- 2120
- 2121
- 2122
- 2123
- 2124
- 2125
- 2126
- 2127
- 2128
- 2129
- 2130
- 2131
- 2132
- 2133
- 2134
- 2135
- 2136
- 2137
- 2138
- 2139
- 2140
- 2141
- 2142
- 2143
- 2144
- 2145
- 2146
- 2147
- 2148
- 2149
- 2150
- 2151
- 2152
- 2153
- 2154
- 2155
- 2156
- 2157
- 2158
- 2159
- 2160
- 2161
- 2162
- 2163
- 2164
- 2165
- 2166
- 2167
- 2168
- 2169
- 2170
- 2171
- 2172
- 2173
- 2174
- 2175
- 2176
- 2177
- 2178
- 2179
- 2180
- 2181
- 2182
- 2183
- 2184
- 2185
- 2186
- 2187
- 2188
- 2189
- 2190
- 2191
- 2192
- 2193
- 2194
- 2195
- 2196
- 2197
- 2198
- 2199
- 2200
- 2201
- 2202
- 2203
- 2204
- 2205
- 2206
- 2207
- 2208
- 2209
- 2210
- 2211
- 2212
- 2213
- 2214
- 2215
- 2216
- 2217
- 2218
- 2219
- 2220
- 2221
- 2222
- 2223
- 2224
- 2225
- 2226
- 2227
- 2228
- 2229
- 2230
- 2231
- 2232
- 2233
- 2234
- 2235
- 2236
- 2237
- 2238
- 2239
- 2240
- 2241
- 2242
- 2243
- 2244
- 2245
- 2246
- 2247
- 2248
- 2249
- 2250
- 2251
- 2252
- 2253
- 2254
- 2255
- 2256
- 2257
- 2258
- 2259
- 2260
- 2261
- 2262
- 2263
- 2264
- 2265
- 2266
- 2267
- 2268
- 2269
- 2270
- 2271
- 2272
- 2273
- 2274
- 2275
- 2276
- 2277
- 2278
- 2279
- 2280
- 2281
- 2282
- 2283
- 2284
- 2285
- 2286
- 2287
- 2288
- 2289
- 2290
- 2291
- 2292
- 2293
- 2294
- 2295
- 2296
- 2297
- 2298
- 2299
- 2300
- 2301
- 2302
- 2303
- 2304
- 2305
- 2306
- 2307
- 2308
- 2309
- 2310
- 2311
- 2312
- 2313
- 2314
- 2315
- 2316
- 2317
- 2318
- 2319
- 2320
- 2321
- 2322
- 2323
- 2324
- 2325
- 2326
- 2327
- 2328
- 2329
- 2330
- 2331
- 2332
- 2333
- 2334
- 2335
- 2336
- 2337
- 2338
- 2339
- 2340
- 2341
- 2342
- 2343
- 2344
- 2345
- 2346
- 2347
- 2348
- 2349
- 2350
- 2351
- 2352
- 2353
- 2354
- 2355
- 2356
- 2357
- 2358
- 2359
- 2360
- 2361
- 2362
- 2363
- 2364
- 2365
- 2366
- 2367
- 2368
- 2369
- 2370
- 2371
- 2372
- 2373
- 2374
- 2375
- 2376
- 2377
- 2378
- 2379
- 2380
- 2381
- 2382
- 2383
- 2384
- 2385
- 2386
- 2387
- 2388
- 2389
- 2390
- 2391
- 2392
- 2393
- 2394
- 2395
- 2396
- 2397
- 2398
- 2399
- 2400
- 2401
- 2402
- 2403
- 2404
- 2405
- 2406
- 2407
- 2408
- 2409
- 2410
- 2411
- 2412
- 2413
- 2414
- 2415
- 2416
- 2417
- 2418