0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include <linux/usb.h>
0010 #include <linux/usb/audio-v2.h>
0011
0012 #include <sound/core.h>
0013 #include <sound/control.h>
0014
0015 #include "usbaudio.h"
0016 #include "mixer.h"
0017 #include "helper.h"
0018
0019 #include "mixer_us16x08.h"
0020
0021
0022 static const char route_msg[] = {
0023 0x61,
0024 0x02,
0025 0x03,
0026 0x62,
0027 0x02,
0028 0x01,
0029 0x41,
0030 0x01,
0031 0x61,
0032 0x02,
0033 0x01,
0034 0x62,
0035 0x02,
0036 0x01,
0037 0x42,
0038 0x01,
0039 0x43,
0040 0x01,
0041 0x00,
0042 0x00
0043 };
0044
0045 static const char mix_init_msg1[] = {
0046 0x71, 0x01, 0x00, 0x00
0047 };
0048
0049 static const char mix_init_msg2[] = {
0050 0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00
0051 };
0052
0053 static const char mix_msg_in[] = {
0054
0055 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
0056 0x81,
0057 0x02,
0058 0x00,
0059 0x00,
0060 0x00
0061 };
0062
0063 static const char mix_msg_out[] = {
0064
0065 0x61, 0x02, 0x02, 0x62, 0x02, 0x01,
0066 0x81,
0067 0x02,
0068 0x00,
0069 0x00,
0070 0x00
0071 };
0072
0073 static const char bypass_msg_out[] = {
0074 0x45,
0075 0x02,
0076 0x01,
0077 0x00,
0078 0x00
0079 };
0080
0081 static const char bus_msg_out[] = {
0082 0x44,
0083 0x02,
0084 0x01,
0085 0x00,
0086 0x00
0087 };
0088
0089 static const char comp_msg[] = {
0090
0091 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
0092 0x91,
0093 0x02,
0094 0xf0,
0095 0x92,
0096 0x02,
0097 0x0a,
0098 0x93,
0099 0x02,
0100 0x02,
0101 0x94,
0102 0x02,
0103 0x01,
0104 0x95,
0105 0x02,
0106 0x03,
0107 0x96,
0108 0x02,
0109 0x01,
0110 0x97,
0111 0x02,
0112 0x01,
0113 0x00,
0114 0x00
0115 };
0116
0117 static const char eqs_msq[] = {
0118
0119 0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
0120 0x51,
0121 0x02,
0122 0x04,
0123 0x52,
0124 0x02,
0125 0x0c,
0126 0x53,
0127 0x02,
0128 0x0f,
0129 0x54,
0130 0x02,
0131 0x02,
0132 0x55,
0133 0x02,
0134 0x01,
0135 0x00,
0136 0x00
0137 };
0138
0139
0140 static const char ratio_map[] = {
0141 0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e,
0142 0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff
0143 };
0144
0145
0146 static const char *const route_names[] = {
0147 "Master Left", "Master Right", "Output 1", "Output 2", "Output 3",
0148 "Output 4", "Output 5", "Output 6", "Output 7", "Output 8",
0149 };
0150
0151 static int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
0152 unsigned char *buf, int size)
0153 {
0154
0155 mutex_lock(&chip->mutex);
0156 snd_usb_ctl_msg(chip->dev,
0157 usb_rcvctrlpipe(chip->dev, 0),
0158 SND_US16X08_URB_METER_REQUEST,
0159 SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
0160 mutex_unlock(&chip->mutex);
0161 return 0;
0162 }
0163
0164
0165
0166
0167 static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size)
0168 {
0169 return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
0170 SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE,
0171 0, 0, buf, size);
0172 }
0173
0174 static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol,
0175 struct snd_ctl_elem_info *uinfo)
0176 {
0177 return snd_ctl_enum_info(uinfo, 1, 10, route_names);
0178 }
0179
0180 static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol,
0181 struct snd_ctl_elem_value *ucontrol)
0182 {
0183 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0184 int index = ucontrol->id.index;
0185
0186
0187 ucontrol->value.enumerated.item[0] = elem->cache_val[index];
0188
0189 return 0;
0190 }
0191
0192 static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
0193 struct snd_ctl_elem_value *ucontrol)
0194 {
0195 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0196 struct snd_usb_audio *chip = elem->head.mixer->chip;
0197 int index = ucontrol->id.index;
0198 char buf[sizeof(route_msg)];
0199 int val, val_org, err;
0200
0201
0202 val = ucontrol->value.enumerated.item[0];
0203
0204
0205 if (val < 0 || val > 9)
0206 return -EINVAL;
0207
0208
0209 memcpy(buf, route_msg, sizeof(route_msg));
0210
0211 if (val < 2) {
0212
0213 val_org = val;
0214 buf[2] = 0x02;
0215 } else {
0216
0217 buf[2] = 0x03;
0218 val_org = val - 2;
0219 }
0220
0221
0222 buf[5] = (unsigned char) (val_org & 0x0f) + 1;
0223
0224 buf[13] = index + 1;
0225
0226 err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
0227
0228 if (err > 0) {
0229 elem->cached |= 1 << index;
0230 elem->cache_val[index] = val;
0231 } else {
0232 usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
0233 }
0234
0235 return err > 0 ? 1 : 0;
0236 }
0237
0238 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
0239 struct snd_ctl_elem_info *uinfo)
0240 {
0241 uinfo->count = 1;
0242 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0243 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
0244 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
0245 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
0246 return 0;
0247 }
0248
0249 static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol,
0250 struct snd_ctl_elem_value *ucontrol)
0251 {
0252 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0253 int index = ucontrol->id.index;
0254
0255 ucontrol->value.integer.value[0] = elem->cache_val[index];
0256
0257 return 0;
0258 }
0259
0260 static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
0261 struct snd_ctl_elem_value *ucontrol)
0262 {
0263 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0264 struct snd_usb_audio *chip = elem->head.mixer->chip;
0265 char buf[sizeof(mix_msg_out)];
0266 int val, err;
0267 int index = ucontrol->id.index;
0268
0269
0270 val = ucontrol->value.integer.value[0];
0271
0272
0273 if (val < SND_US16X08_KCMIN(kcontrol)
0274 || val > SND_US16X08_KCMAX(kcontrol))
0275 return -EINVAL;
0276
0277
0278 memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
0279
0280 buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
0281 buf[6] = elem->head.id;
0282
0283
0284 buf[5] = index + 1;
0285 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
0286
0287 if (err > 0) {
0288 elem->cached |= 1 << index;
0289 elem->cache_val[index] = val;
0290 } else {
0291 usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
0292 }
0293
0294 return err > 0 ? 1 : 0;
0295 }
0296
0297 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
0298 struct snd_ctl_elem_value *ucontrol)
0299 {
0300 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0301 struct snd_usb_audio *chip = elem->head.mixer->chip;
0302 char buf[sizeof(mix_msg_out)];
0303 int val, err = 0;
0304
0305 val = ucontrol->value.integer.value[0];
0306
0307
0308 switch (elem->head.id) {
0309 case SND_US16X08_ID_BYPASS:
0310 memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out));
0311 buf[2] = val;
0312 err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out));
0313 break;
0314 case SND_US16X08_ID_BUSS_OUT:
0315 memcpy(buf, bus_msg_out, sizeof(bus_msg_out));
0316 buf[2] = val;
0317 err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out));
0318 break;
0319 case SND_US16X08_ID_MUTE:
0320 memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
0321 buf[8] = val;
0322 buf[6] = elem->head.id;
0323 buf[5] = 1;
0324 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
0325 break;
0326 }
0327
0328 if (err > 0) {
0329 elem->cached |= 1;
0330 elem->cache_val[0] = val;
0331 } else {
0332 usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
0333 }
0334
0335 return err > 0 ? 1 : 0;
0336 }
0337
0338 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
0339 struct snd_ctl_elem_value *ucontrol)
0340 {
0341 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0342
0343 switch (elem->head.id) {
0344 case SND_US16X08_ID_BUSS_OUT:
0345 ucontrol->value.integer.value[0] = elem->cache_val[0];
0346 break;
0347 case SND_US16X08_ID_BYPASS:
0348 ucontrol->value.integer.value[0] = elem->cache_val[0];
0349 break;
0350 case SND_US16X08_ID_MUTE:
0351 ucontrol->value.integer.value[0] = elem->cache_val[0];
0352 break;
0353 }
0354
0355 return 0;
0356 }
0357
0358
0359 static int snd_us16x08_channel_get(struct snd_kcontrol *kcontrol,
0360 struct snd_ctl_elem_value *ucontrol)
0361 {
0362 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0363 int index = ucontrol->id.index;
0364
0365 ucontrol->value.integer.value[0] = elem->cache_val[index];
0366
0367 return 0;
0368 }
0369
0370 static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,
0371 struct snd_ctl_elem_value *ucontrol)
0372 {
0373 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0374 struct snd_usb_audio *chip = elem->head.mixer->chip;
0375 char buf[sizeof(mix_msg_in)];
0376 int val, err;
0377 int index = ucontrol->id.index;
0378
0379 val = ucontrol->value.integer.value[0];
0380
0381
0382 if (val < SND_US16X08_KCMIN(kcontrol)
0383 || val > SND_US16X08_KCMAX(kcontrol))
0384 return -EINVAL;
0385
0386
0387 memcpy(buf, mix_msg_in, sizeof(mix_msg_in));
0388
0389
0390 buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
0391 buf[6] = elem->head.id;
0392 buf[5] = index + 1;
0393
0394 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
0395
0396 if (err > 0) {
0397 elem->cached |= 1 << index;
0398 elem->cache_val[index] = val;
0399 } else {
0400 usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
0401 }
0402
0403 return err > 0 ? 1 : 0;
0404 }
0405
0406 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
0407 struct snd_ctl_elem_info *uinfo)
0408 {
0409 uinfo->count = 1;
0410 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0411 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
0412 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
0413 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
0414 return 0;
0415 }
0416
0417 static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol,
0418 struct snd_ctl_elem_value *ucontrol)
0419 {
0420 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0421 struct snd_us16x08_comp_store *store = elem->private_data;
0422 int index = ucontrol->id.index;
0423 int val_idx = COMP_STORE_IDX(elem->head.id);
0424
0425 ucontrol->value.integer.value[0] = store->val[val_idx][index];
0426
0427 return 0;
0428 }
0429
0430 static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
0431 struct snd_ctl_elem_value *ucontrol)
0432 {
0433 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0434 struct snd_usb_audio *chip = elem->head.mixer->chip;
0435 struct snd_us16x08_comp_store *store = elem->private_data;
0436 int index = ucontrol->id.index;
0437 char buf[sizeof(comp_msg)];
0438 int val_idx, val;
0439 int err;
0440
0441 val = ucontrol->value.integer.value[0];
0442
0443
0444 if (val < SND_US16X08_KCMIN(kcontrol)
0445 || val > SND_US16X08_KCMAX(kcontrol))
0446 return -EINVAL;
0447
0448
0449 val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
0450
0451 store->val[val_idx][index] = ucontrol->value.integer.value[0];
0452
0453
0454 memcpy(buf, comp_msg, sizeof(comp_msg));
0455
0456
0457 buf[8] = store->val[
0458 COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
0459 - SND_US16X08_COMP_THRESHOLD_BIAS;
0460 buf[11] = ratio_map[store->val[
0461 COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
0462 buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
0463 + SND_US16X08_COMP_ATTACK_BIAS;
0464 buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
0465 + SND_US16X08_COMP_RELEASE_BIAS;
0466 buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
0467 buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
0468
0469
0470 buf[5] = index + 1;
0471
0472 err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
0473
0474 if (err > 0) {
0475 elem->cached |= 1 << index;
0476 elem->cache_val[index] = val;
0477 } else {
0478 usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
0479 }
0480
0481 return 1;
0482 }
0483
0484 static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
0485 struct snd_ctl_elem_value *ucontrol)
0486 {
0487 int val;
0488 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0489 struct snd_us16x08_eq_store *store = elem->private_data;
0490 int index = ucontrol->id.index;
0491
0492
0493 val = store->val[EQ_STORE_BAND_IDX(elem->head.id)]
0494 [EQ_STORE_PARAM_IDX(elem->head.id)][index];
0495 ucontrol->value.integer.value[0] = val;
0496
0497 return 0;
0498 }
0499
0500 static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
0501 struct snd_ctl_elem_value *ucontrol)
0502 {
0503 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0504 struct snd_usb_audio *chip = elem->head.mixer->chip;
0505 struct snd_us16x08_eq_store *store = elem->private_data;
0506 int index = ucontrol->id.index;
0507 char buf[sizeof(eqs_msq)];
0508 int val, err = 0;
0509 int b_idx;
0510
0511
0512 val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol);
0513
0514
0515 memcpy(buf, eqs_msq, sizeof(eqs_msq));
0516
0517
0518 buf[5] = index + 1;
0519 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
0520
0521 buf[20] = val;
0522 buf[17] = store->val[b_idx][2][index];
0523 buf[14] = store->val[b_idx][1][index];
0524 buf[11] = store->val[b_idx][0][index];
0525 buf[8] = b_idx + 1;
0526 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
0527 if (err < 0)
0528 break;
0529 store->val[b_idx][3][index] = val;
0530 msleep(15);
0531 }
0532
0533 if (err > 0) {
0534 elem->cached |= 1 << index;
0535 elem->cache_val[index] = val;
0536 } else {
0537 usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
0538 }
0539
0540 return 1;
0541 }
0542
0543 static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
0544 struct snd_ctl_elem_value *ucontrol)
0545 {
0546 int val;
0547 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0548 struct snd_us16x08_eq_store *store = elem->private_data;
0549 int index = ucontrol->id.index;
0550 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
0551 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
0552
0553 val = store->val[b_idx][p_idx][index];
0554
0555 ucontrol->value.integer.value[0] = val;
0556
0557 return 0;
0558 }
0559
0560 static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
0561 struct snd_ctl_elem_value *ucontrol)
0562 {
0563 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0564 struct snd_usb_audio *chip = elem->head.mixer->chip;
0565 struct snd_us16x08_eq_store *store = elem->private_data;
0566 int index = ucontrol->id.index;
0567 char buf[sizeof(eqs_msq)];
0568 int val, err;
0569 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
0570 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
0571
0572 val = ucontrol->value.integer.value[0];
0573
0574
0575 if (val < SND_US16X08_KCMIN(kcontrol)
0576 || val > SND_US16X08_KCMAX(kcontrol))
0577 return -EINVAL;
0578
0579
0580 memcpy(buf, eqs_msq, sizeof(eqs_msq));
0581
0582 store->val[b_idx][p_idx][index] = val;
0583 buf[20] = store->val[b_idx][3][index];
0584 buf[17] = store->val[b_idx][2][index];
0585 buf[14] = store->val[b_idx][1][index];
0586 buf[11] = store->val[b_idx][0][index];
0587
0588
0589 buf[5] = index + 1;
0590
0591
0592 buf[8] = b_idx + 1;
0593
0594 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
0595
0596 if (err > 0) {
0597
0598 elem->cached |= 1 << index;
0599 elem->cache_val[index] = val;
0600 } else {
0601 usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
0602 }
0603
0604 return 1;
0605 }
0606
0607 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
0608 struct snd_ctl_elem_info *uinfo)
0609 {
0610 uinfo->count = 34;
0611 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0612 uinfo->value.integer.max = 0x7FFF;
0613 uinfo->value.integer.min = 0;
0614
0615 return 0;
0616 }
0617
0618
0619 static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store)
0620 {
0621 int ret;
0622
0623
0624 if (store->comp_active_index) {
0625
0626 if (store->comp_active_index & 0x20) {
0627
0628 if (store->comp_index -
0629 store->comp_active_index > 1)
0630 store->comp_index =
0631 store->comp_active_index;
0632
0633 ret = store->comp_index++ & 0x1F;
0634 } else {
0635
0636 ret = store->comp_active_index;
0637 }
0638 } else {
0639
0640 while (store->comp_index <= SND_US16X08_MAX_CHANNELS
0641 && !store->comp_store->val[
0642 COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
0643 [store->comp_index - 1]) {
0644 store->comp_index++;
0645 }
0646 ret = store->comp_index++;
0647 if (store->comp_index > SND_US16X08_MAX_CHANNELS)
0648 store->comp_index = 1;
0649 }
0650 return ret;
0651 }
0652
0653
0654 static void get_meter_levels_from_urb(int s,
0655 struct snd_us16x08_meter_store *store,
0656 u8 *meter_urb)
0657 {
0658 int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
0659
0660 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
0661 MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
0662 if (MUC0(meter_urb, s) == 0x72)
0663 store->meter_level[MUB2(meter_urb, s) - 1] = val;
0664 if (MUC0(meter_urb, s) == 0xb2)
0665 store->comp_level[MUB2(meter_urb, s) - 1] = val;
0666 }
0667 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
0668 MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62)
0669 store->master_level[MUB2(meter_urb, s) - 1] = val;
0670 }
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
0684 struct snd_ctl_elem_value *ucontrol)
0685 {
0686 int i, set;
0687 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0688 struct snd_usb_audio *chip = elem->head.mixer->chip;
0689 struct snd_us16x08_meter_store *store = elem->private_data;
0690 u8 meter_urb[64];
0691
0692 switch (kcontrol->private_value) {
0693 case 0: {
0694 char tmp[sizeof(mix_init_msg1)];
0695
0696 memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
0697 snd_us16x08_send_urb(chip, tmp, 4);
0698 snd_us16x08_recv_urb(chip, meter_urb,
0699 sizeof(meter_urb));
0700 kcontrol->private_value++;
0701 break;
0702 }
0703 case 1:
0704 snd_us16x08_recv_urb(chip, meter_urb,
0705 sizeof(meter_urb));
0706 kcontrol->private_value++;
0707 break;
0708 case 2:
0709 snd_us16x08_recv_urb(chip, meter_urb,
0710 sizeof(meter_urb));
0711 kcontrol->private_value++;
0712 break;
0713 case 3: {
0714 char tmp[sizeof(mix_init_msg2)];
0715
0716 memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
0717 tmp[2] = snd_get_meter_comp_index(store);
0718 snd_us16x08_send_urb(chip, tmp, 10);
0719 snd_us16x08_recv_urb(chip, meter_urb,
0720 sizeof(meter_urb));
0721 kcontrol->private_value = 0;
0722 break;
0723 }
0724 }
0725
0726 for (set = 0; set < 6; set++)
0727 get_meter_levels_from_urb(set, store, meter_urb);
0728
0729 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
0730 ucontrol->value.integer.value[i] =
0731 store ? store->meter_level[i] : 0;
0732 }
0733
0734 ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
0735 ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
0736
0737 for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
0738 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
0739 store ? store->comp_level[i - 2] : 0;
0740
0741 return 1;
0742 }
0743
0744 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
0745 struct snd_ctl_elem_value *ucontrol)
0746 {
0747 struct usb_mixer_elem_info *elem = kcontrol->private_data;
0748 struct snd_us16x08_meter_store *store = elem->private_data;
0749 int val;
0750
0751 val = ucontrol->value.integer.value[0];
0752
0753
0754 if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
0755 return -EINVAL;
0756
0757 store->comp_active_index = val;
0758 store->comp_index = val;
0759
0760 return 1;
0761 }
0762
0763 static const struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
0764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0765 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0766 .count = 16,
0767 .info = snd_us16x08_switch_info,
0768 .get = snd_us16x08_channel_get,
0769 .put = snd_us16x08_channel_put,
0770 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
0771 };
0772
0773 static const struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
0774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0775 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0776 .count = 16,
0777 .info = snd_us16x08_mix_info,
0778 .get = snd_us16x08_channel_get,
0779 .put = snd_us16x08_channel_put,
0780 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
0781 };
0782
0783 static const struct snd_kcontrol_new snd_us16x08_pan_int_ctl = {
0784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0785 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0786 .count = 16,
0787 .info = snd_us16x08_mix_info,
0788 .get = snd_us16x08_channel_get,
0789 .put = snd_us16x08_channel_put,
0790 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255)
0791 };
0792
0793 static const struct snd_kcontrol_new snd_us16x08_master_ctl = {
0794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0795 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0796 .count = 1,
0797 .info = snd_us16x08_master_info,
0798 .get = snd_us16x08_master_get,
0799 .put = snd_us16x08_master_put,
0800 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
0801 };
0802
0803 static const struct snd_kcontrol_new snd_us16x08_route_ctl = {
0804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0805 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0806 .count = 8,
0807 .info = snd_us16x08_route_info,
0808 .get = snd_us16x08_route_get,
0809 .put = snd_us16x08_route_put,
0810 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
0811 };
0812
0813 static const struct snd_kcontrol_new snd_us16x08_bus_ctl = {
0814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0815 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0816 .count = 1,
0817 .info = snd_us16x08_switch_info,
0818 .get = snd_us16x08_bus_get,
0819 .put = snd_us16x08_bus_put,
0820 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
0821 };
0822
0823 static const struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
0824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0825 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0826 .count = 16,
0827 .info = snd_us16x08_switch_info,
0828 .get = snd_us16x08_comp_get,
0829 .put = snd_us16x08_comp_put,
0830 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
0831 };
0832
0833 static const struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
0834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0836 .count = 16,
0837 .info = snd_us16x08_mix_info,
0838 .get = snd_us16x08_comp_get,
0839 .put = snd_us16x08_comp_put,
0840 .private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
0841 0, 0x20)
0842 };
0843
0844 static const struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
0845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0846 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0847 .count = 16,
0848 .info = snd_us16x08_mix_info,
0849 .get = snd_us16x08_comp_get,
0850 .put = snd_us16x08_comp_put,
0851 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
0852 sizeof(ratio_map) - 1),
0853 };
0854
0855 static const struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
0856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0857 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0858 .count = 16,
0859 .info = snd_us16x08_mix_info,
0860 .get = snd_us16x08_comp_get,
0861 .put = snd_us16x08_comp_put,
0862 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
0863 };
0864
0865 static const struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = {
0866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0867 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0868 .count = 16,
0869 .info = snd_us16x08_mix_info,
0870 .get = snd_us16x08_comp_get,
0871 .put = snd_us16x08_comp_put,
0872 .private_value =
0873 SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
0874 };
0875
0876 static const struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
0877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0878 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0879 .count = 16,
0880 .info = snd_us16x08_mix_info,
0881 .get = snd_us16x08_comp_get,
0882 .put = snd_us16x08_comp_put,
0883 .private_value =
0884 SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
0885 };
0886
0887 static const struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
0888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0889 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0890 .count = 16,
0891 .info = snd_us16x08_mix_info,
0892 .get = snd_us16x08_eq_get,
0893 .put = snd_us16x08_eq_put,
0894 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
0895 };
0896
0897 static const struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = {
0898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0899 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0900 .count = 16,
0901 .info = snd_us16x08_mix_info,
0902 .get = snd_us16x08_eq_get,
0903 .put = snd_us16x08_eq_put,
0904 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F),
0905 };
0906
0907 static const struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = {
0908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0909 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0910 .count = 16,
0911 .info = snd_us16x08_mix_info,
0912 .get = snd_us16x08_eq_get,
0913 .put = snd_us16x08_eq_put,
0914 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F)
0915 };
0916
0917 static const struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = {
0918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0919 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0920 .count = 16,
0921 .info = snd_us16x08_mix_info,
0922 .get = snd_us16x08_eq_get,
0923 .put = snd_us16x08_eq_put,
0924 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06)
0925 };
0926
0927 static const struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = {
0928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0929 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0930 .count = 16,
0931 .info = snd_us16x08_mix_info,
0932 .get = snd_us16x08_eq_get,
0933 .put = snd_us16x08_eq_put,
0934 .private_value =
0935 SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
0936 };
0937
0938 static const struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
0939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0940 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0941 .count = 16,
0942 .info = snd_us16x08_switch_info,
0943 .get = snd_us16x08_eqswitch_get,
0944 .put = snd_us16x08_eqswitch_put,
0945 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
0946 };
0947
0948 static const struct snd_kcontrol_new snd_us16x08_meter_ctl = {
0949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0950 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
0951 .count = 1,
0952 .info = snd_us16x08_meter_info,
0953 .get = snd_us16x08_meter_get,
0954 .put = snd_us16x08_meter_put
0955 };
0956
0957
0958
0959
0960 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
0961 {
0962 int i;
0963 struct snd_us16x08_comp_store *tmp;
0964
0965 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
0966 if (!tmp)
0967 return NULL;
0968
0969 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
0970 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
0971 = 0x20;
0972 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
0973 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
0974 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
0975 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
0976 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
0977 }
0978 return tmp;
0979 }
0980
0981
0982 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
0983 {
0984 int i, b_idx;
0985 struct snd_us16x08_eq_store *tmp;
0986
0987 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
0988 if (!tmp)
0989 return NULL;
0990
0991 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
0992 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
0993 tmp->val[b_idx][0][i] = 0x0c;
0994 tmp->val[b_idx][3][i] = 0x00;
0995 switch (b_idx) {
0996 case 0:
0997 tmp->val[b_idx][1][i] = 0x05;
0998 tmp->val[b_idx][2][i] = 0xff;
0999 break;
1000 case 1:
1001 tmp->val[b_idx][1][i] = 0x0e;
1002 tmp->val[b_idx][2][i] = 0x02;
1003 break;
1004 case 2:
1005 tmp->val[b_idx][1][i] = 0x1b;
1006 tmp->val[b_idx][2][i] = 0x02;
1007 break;
1008 case 3:
1009 tmp->val[b_idx][1][i] = 0x2f
1010 - SND_US16X08_EQ_HIGHFREQ_BIAS;
1011 tmp->val[b_idx][2][i] = 0xff;
1012 break;
1013 }
1014 }
1015 }
1016 return tmp;
1017 }
1018
1019 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
1020 {
1021 struct snd_us16x08_meter_store *tmp;
1022
1023 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
1024 if (!tmp)
1025 return NULL;
1026 tmp->comp_index = 1;
1027 tmp->comp_active_index = 0;
1028 return tmp;
1029 }
1030
1031
1032 static void elem_private_free(struct snd_kcontrol *kctl)
1033 {
1034 struct usb_mixer_elem_info *elem = kctl->private_data;
1035
1036 if (elem)
1037 kfree(elem->private_data);
1038 kfree(elem);
1039 kctl->private_data = NULL;
1040 }
1041
1042 static int add_new_ctl(struct usb_mixer_interface *mixer,
1043 const struct snd_kcontrol_new *ncontrol,
1044 int index, int val_type, int channels,
1045 const char *name, void *opt,
1046 bool do_private_free,
1047 struct usb_mixer_elem_info **elem_ret)
1048 {
1049 struct snd_kcontrol *kctl;
1050 struct usb_mixer_elem_info *elem;
1051 int err;
1052
1053 usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name);
1054
1055 elem = kzalloc(sizeof(*elem), GFP_KERNEL);
1056 if (!elem)
1057 return -ENOMEM;
1058
1059 elem->head.mixer = mixer;
1060 elem->head.resume = NULL;
1061 elem->control = 0;
1062 elem->idx_off = 0;
1063 elem->head.id = index;
1064 elem->val_type = val_type;
1065 elem->channels = channels;
1066 elem->private_data = opt;
1067
1068 kctl = snd_ctl_new1(ncontrol, elem);
1069 if (!kctl) {
1070 kfree(elem);
1071 return -ENOMEM;
1072 }
1073
1074 if (do_private_free)
1075 kctl->private_free = elem_private_free;
1076 else
1077 kctl->private_free = snd_usb_mixer_elem_free;
1078
1079 strscpy(kctl->id.name, name, sizeof(kctl->id.name));
1080
1081 err = snd_usb_mixer_add_control(&elem->head, kctl);
1082 if (err < 0)
1083 return err;
1084
1085 if (elem_ret)
1086 *elem_ret = elem;
1087
1088 return 0;
1089 }
1090
1091
1092 static const struct snd_us16x08_control_params eq_controls[] = {
1093 {
1094 .kcontrol_new = &snd_us16x08_eq_switch_ctl,
1095 .control_id = SND_US16X08_ID_EQENABLE,
1096 .type = USB_MIXER_BOOLEAN,
1097 .num_channels = 16,
1098 .name = "EQ Switch",
1099 },
1100 {
1101 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1102 .control_id = SND_US16X08_ID_EQLOWLEVEL,
1103 .type = USB_MIXER_U8,
1104 .num_channels = 16,
1105 .name = "EQ Low Volume",
1106 },
1107 {
1108 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
1109 .control_id = SND_US16X08_ID_EQLOWFREQ,
1110 .type = USB_MIXER_U8,
1111 .num_channels = 16,
1112 .name = "EQ Low Frequency",
1113 },
1114 {
1115 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1116 .control_id = SND_US16X08_ID_EQLOWMIDLEVEL,
1117 .type = USB_MIXER_U8,
1118 .num_channels = 16,
1119 .name = "EQ MidLow Volume",
1120 },
1121 {
1122 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1123 .control_id = SND_US16X08_ID_EQLOWMIDFREQ,
1124 .type = USB_MIXER_U8,
1125 .num_channels = 16,
1126 .name = "EQ MidLow Frequency",
1127 },
1128 {
1129 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1130 .control_id = SND_US16X08_ID_EQLOWMIDWIDTH,
1131 .type = USB_MIXER_U8,
1132 .num_channels = 16,
1133 .name = "EQ MidLow Q",
1134 },
1135 {
1136 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1137 .control_id = SND_US16X08_ID_EQHIGHMIDLEVEL,
1138 .type = USB_MIXER_U8,
1139 .num_channels = 16,
1140 .name = "EQ MidHigh Volume",
1141 },
1142 {
1143 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
1144 .control_id = SND_US16X08_ID_EQHIGHMIDFREQ,
1145 .type = USB_MIXER_U8,
1146 .num_channels = 16,
1147 .name = "EQ MidHigh Frequency",
1148 },
1149 {
1150 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
1151 .control_id = SND_US16X08_ID_EQHIGHMIDWIDTH,
1152 .type = USB_MIXER_U8,
1153 .num_channels = 16,
1154 .name = "EQ MidHigh Q",
1155 },
1156 {
1157 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
1158 .control_id = SND_US16X08_ID_EQHIGHLEVEL,
1159 .type = USB_MIXER_U8,
1160 .num_channels = 16,
1161 .name = "EQ High Volume",
1162 },
1163 {
1164 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
1165 .control_id = SND_US16X08_ID_EQHIGHFREQ,
1166 .type = USB_MIXER_U8,
1167 .num_channels = 16,
1168 .name = "EQ High Frequency",
1169 },
1170 };
1171
1172
1173 static const struct snd_us16x08_control_params comp_controls[] = {
1174 {
1175 .kcontrol_new = &snd_us16x08_compswitch_ctl,
1176 .control_id = SND_US16X08_ID_COMP_SWITCH,
1177 .type = USB_MIXER_BOOLEAN,
1178 .num_channels = 16,
1179 .name = "Compressor Switch",
1180 },
1181 {
1182 .kcontrol_new = &snd_us16x08_comp_threshold_ctl,
1183 .control_id = SND_US16X08_ID_COMP_THRESHOLD,
1184 .type = USB_MIXER_U8,
1185 .num_channels = 16,
1186 .name = "Compressor Threshold Volume",
1187 },
1188 {
1189 .kcontrol_new = &snd_us16x08_comp_ratio_ctl,
1190 .control_id = SND_US16X08_ID_COMP_RATIO,
1191 .type = USB_MIXER_U8,
1192 .num_channels = 16,
1193 .name = "Compressor Ratio",
1194 },
1195 {
1196 .kcontrol_new = &snd_us16x08_comp_attack_ctl,
1197 .control_id = SND_US16X08_ID_COMP_ATTACK,
1198 .type = USB_MIXER_U8,
1199 .num_channels = 16,
1200 .name = "Compressor Attack",
1201 },
1202 {
1203 .kcontrol_new = &snd_us16x08_comp_release_ctl,
1204 .control_id = SND_US16X08_ID_COMP_RELEASE,
1205 .type = USB_MIXER_U8,
1206 .num_channels = 16,
1207 .name = "Compressor Release",
1208 },
1209 {
1210 .kcontrol_new = &snd_us16x08_comp_gain_ctl,
1211 .control_id = SND_US16X08_ID_COMP_GAIN,
1212 .type = USB_MIXER_U8,
1213 .num_channels = 16,
1214 .name = "Compressor Volume",
1215 },
1216 };
1217
1218
1219 static const struct snd_us16x08_control_params channel_controls[] = {
1220 {
1221 .kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1222 .control_id = SND_US16X08_ID_PHASE,
1223 .type = USB_MIXER_BOOLEAN,
1224 .num_channels = 16,
1225 .name = "Phase Switch",
1226 .default_val = 0
1227 },
1228 {
1229 .kcontrol_new = &snd_us16x08_ch_int_ctl,
1230 .control_id = SND_US16X08_ID_FADER,
1231 .type = USB_MIXER_U8,
1232 .num_channels = 16,
1233 .name = "Line Volume",
1234 .default_val = 127
1235 },
1236 {
1237 .kcontrol_new = &snd_us16x08_ch_boolean_ctl,
1238 .control_id = SND_US16X08_ID_MUTE,
1239 .type = USB_MIXER_BOOLEAN,
1240 .num_channels = 16,
1241 .name = "Mute Switch",
1242 .default_val = 0
1243 },
1244 {
1245 .kcontrol_new = &snd_us16x08_pan_int_ctl,
1246 .control_id = SND_US16X08_ID_PAN,
1247 .type = USB_MIXER_U16,
1248 .num_channels = 16,
1249 .name = "Pan Left-Right Volume",
1250 .default_val = 127
1251 },
1252 };
1253
1254
1255 static const struct snd_us16x08_control_params master_controls[] = {
1256 {
1257 .kcontrol_new = &snd_us16x08_master_ctl,
1258 .control_id = SND_US16X08_ID_FADER,
1259 .type = USB_MIXER_U8,
1260 .num_channels = 16,
1261 .name = "Master Volume",
1262 .default_val = 127
1263 },
1264 {
1265 .kcontrol_new = &snd_us16x08_bus_ctl,
1266 .control_id = SND_US16X08_ID_BYPASS,
1267 .type = USB_MIXER_BOOLEAN,
1268 .num_channels = 16,
1269 .name = "DSP Bypass Switch",
1270 .default_val = 0
1271 },
1272 {
1273 .kcontrol_new = &snd_us16x08_bus_ctl,
1274 .control_id = SND_US16X08_ID_BUSS_OUT,
1275 .type = USB_MIXER_BOOLEAN,
1276 .num_channels = 16,
1277 .name = "Buss Out Switch",
1278 .default_val = 0
1279 },
1280 {
1281 .kcontrol_new = &snd_us16x08_bus_ctl,
1282 .control_id = SND_US16X08_ID_MUTE,
1283 .type = USB_MIXER_BOOLEAN,
1284 .num_channels = 16,
1285 .name = "Master Mute Switch",
1286 .default_val = 0
1287 },
1288
1289 };
1290
1291 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1292 {
1293 int i, j;
1294 int err;
1295 struct usb_mixer_elem_info *elem;
1296 struct snd_us16x08_comp_store *comp_store;
1297 struct snd_us16x08_meter_store *meter_store;
1298 struct snd_us16x08_eq_store *eq_store;
1299
1300
1301 if (mixer->hostif->desc.bInterfaceNumber == 3) {
1302
1303
1304 err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
1305 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
1306 NULL, false, &elem);
1307 if (err < 0) {
1308 usb_audio_dbg(mixer->chip,
1309 "Failed to create route control, err:%d\n",
1310 err);
1311 return err;
1312 }
1313 for (i = 0; i < 8; i++)
1314 elem->cache_val[i] = i < 2 ? i : i + 2;
1315 elem->cached = 0xff;
1316
1317
1318 comp_store = snd_us16x08_create_comp_store();
1319 if (!comp_store)
1320 return -ENOMEM;
1321
1322
1323 for (i = 0; i < ARRAY_SIZE(master_controls); i++) {
1324
1325 err = add_new_ctl(mixer,
1326 master_controls[i].kcontrol_new,
1327 master_controls[i].control_id,
1328 master_controls[i].type,
1329 master_controls[i].num_channels,
1330 master_controls[i].name,
1331 comp_store,
1332 i == 0,
1333 &elem);
1334 if (err < 0)
1335 return err;
1336 elem->cache_val[0] = master_controls[i].default_val;
1337 elem->cached = 1;
1338 }
1339
1340
1341 for (i = 0; i < ARRAY_SIZE(channel_controls); i++) {
1342
1343 err = add_new_ctl(mixer,
1344 channel_controls[i].kcontrol_new,
1345 channel_controls[i].control_id,
1346 channel_controls[i].type,
1347 channel_controls[i].num_channels,
1348 channel_controls[i].name,
1349 comp_store,
1350 false, &elem);
1351 if (err < 0)
1352 return err;
1353 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
1354 elem->cache_val[j] =
1355 channel_controls[i].default_val;
1356 }
1357 elem->cached = 0xffff;
1358 }
1359
1360
1361 eq_store = snd_us16x08_create_eq_store();
1362 if (!eq_store)
1363 return -ENOMEM;
1364
1365
1366 for (i = 0; i < ARRAY_SIZE(eq_controls); i++) {
1367
1368 err = add_new_ctl(mixer,
1369 eq_controls[i].kcontrol_new,
1370 eq_controls[i].control_id,
1371 eq_controls[i].type,
1372 eq_controls[i].num_channels,
1373 eq_controls[i].name,
1374 eq_store,
1375 i == 0,
1376 NULL);
1377 if (err < 0)
1378 return err;
1379 }
1380
1381
1382 for (i = 0; i < ARRAY_SIZE(comp_controls); i++) {
1383
1384 err = add_new_ctl(mixer,
1385 comp_controls[i].kcontrol_new,
1386 comp_controls[i].control_id,
1387 comp_controls[i].type,
1388 comp_controls[i].num_channels,
1389 comp_controls[i].name,
1390 comp_store,
1391 false, NULL);
1392 if (err < 0)
1393 return err;
1394 }
1395
1396
1397 meter_store = snd_us16x08_create_meter_store();
1398 if (!meter_store)
1399 return -ENOMEM;
1400
1401
1402
1403
1404 meter_store->comp_store = comp_store;
1405 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
1406 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
1407 meter_store, true, NULL);
1408 if (err < 0)
1409 return err;
1410 }
1411
1412 return 0;
1413 }
1414