1 /* 2 * Tascam US-16x08 ALSA driver 3 * 4 * Copyright (c) 2016 by Detlef Urban (onkel@paraair.de) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 */ 17 18 #include <linux/slab.h> 19 #include <linux/usb.h> 20 #include <linux/usb/audio-v2.h> 21 22 #include <sound/core.h> 23 #include <sound/control.h> 24 25 #include "usbaudio.h" 26 #include "mixer.h" 27 #include "helper.h" 28 29 #include "mixer_us16x08.h" 30 31 /* USB control message templates */ 32 static const char route_msg[] = { 33 0x61, 34 0x02, 35 0x03, /* input from master (0x02) or input from computer bus (0x03) */ 36 0x62, 37 0x02, 38 0x01, /* input index (0x01/0x02 eq. left/right) or bus (0x01-0x08) */ 39 0x41, 40 0x01, 41 0x61, 42 0x02, 43 0x01, 44 0x62, 45 0x02, 46 0x01, /* output index (0x01-0x08) */ 47 0x42, 48 0x01, 49 0x43, 50 0x01, 51 0x00, 52 0x00 53 }; 54 55 static const char mix_init_msg1[] = { 56 0x71, 0x01, 0x00, 0x00 57 }; 58 59 static const char mix_init_msg2[] = { 60 0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00 61 }; 62 63 static const char mix_msg_in[] = { 64 /* default message head, equal to all mixers */ 65 0x61, 0x02, 0x04, 0x62, 0x02, 0x01, 66 0x81, /* 0x06: Controller ID */ 67 0x02, /* 0x07: */ 68 0x00, /* 0x08: Value of common mixer */ 69 0x00, 70 0x00 71 }; 72 73 static const char mix_msg_out[] = { 74 /* default message head, equal to all mixers */ 75 0x61, 0x02, 0x02, 0x62, 0x02, 0x01, 76 0x81, /* 0x06: Controller ID */ 77 0x02, /* 0x07: */ 78 0x00, /* 0x08: Value of common mixer */ 79 0x00, 80 0x00 81 }; 82 83 static const char bypass_msg_out[] = { 84 0x45, 85 0x02, 86 0x01, /* on/off flag */ 87 0x00, 88 0x00 89 }; 90 91 static const char bus_msg_out[] = { 92 0x44, 93 0x02, 94 0x01, /* on/off flag */ 95 0x00, 96 0x00 97 }; 98 99 static const char comp_msg[] = { 100 /* default message head, equal to all mixers */ 101 0x61, 0x02, 0x04, 0x62, 0x02, 0x01, 102 0x91, 103 0x02, 104 0xf0, /* 0x08: Threshold db (8) (e0 ... 00) (+-0dB -- -32dB) x-32 */ 105 0x92, 106 0x02, 107 0x0a, /* 0x0b: Ratio (0a,0b,0d,0f,11,14,19,1e,23,28,32,3c,50,a0,ff) */ 108 0x93, 109 0x02, 110 0x02, /* 0x0e: Attack (0x02 ... 0xc0) (2ms ... 200ms) */ 111 0x94, 112 0x02, 113 0x01, /* 0x11: Release (0x01 ... 0x64) (10ms ... 1000ms) x*10 */ 114 0x95, 115 0x02, 116 0x03, /* 0x14: gain (0 ... 20) (0dB .. 20dB) */ 117 0x96, 118 0x02, 119 0x01, 120 0x97, 121 0x02, 122 0x01, /* 0x1a: main Comp switch (0 ... 1) (off ... on)) */ 123 0x00, 124 0x00 125 }; 126 127 static const char eqs_msq[] = { 128 /* default message head, equal to all mixers */ 129 0x61, 0x02, 0x04, 0x62, 0x02, 0x01, 130 0x51, /* 0x06: Controller ID */ 131 0x02, 132 0x04, /* 0x08: EQ set num (0x01..0x04) (LOW, LOWMID, HIGHMID, HIGH)) */ 133 0x52, 134 0x02, 135 0x0c, /* 0x0b: value dB (0 ... 12) (-12db .. +12db) x-6 */ 136 0x53, 137 0x02, 138 0x0f, /* 0x0e: value freq (32-47) (1.7kHz..18kHz) */ 139 0x54, 140 0x02, 141 0x02, /* 0x11: band width (0-6) (Q16-Q0.25) 2^x/4 (EQ xxMID only) */ 142 0x55, 143 0x02, 144 0x01, /* 0x14: main EQ switch (0 ... 1) (off ... on)) */ 145 0x00, 146 0x00 147 }; 148 149 /* compressor ratio map */ 150 static const char ratio_map[] = { 151 0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e, 152 0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff 153 }; 154 155 /* route enumeration names */ 156 static const char *const route_names[] = { 157 "Master Left", "Master Right", "Output 1", "Output 2", "Output 3", 158 "Output 4", "Output 5", "Output 6", "Output 7", "Output 8", 159 }; 160 161 static int snd_us16x08_recv_urb(struct snd_usb_audio *chip, 162 unsigned char *buf, int size) 163 { 164 165 mutex_lock(&chip->mutex); 166 snd_usb_ctl_msg(chip->dev, 167 usb_rcvctrlpipe(chip->dev, 0), 168 SND_US16X08_URB_METER_REQUEST, 169 SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size); 170 mutex_unlock(&chip->mutex); 171 return 0; 172 } 173 174 /* wrapper function to send prepared URB buffer to usb device. Return an error 175 * code if something went wrong 176 */ 177 static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size) 178 { 179 return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), 180 SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE, 181 0, 0, buf, size); 182 } 183 184 static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol, 185 struct snd_ctl_elem_info *uinfo) 186 { 187 return snd_ctl_enum_info(uinfo, 1, 10, route_names); 188 } 189 190 static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol, 191 struct snd_ctl_elem_value *ucontrol) 192 { 193 struct usb_mixer_elem_info *elem = kcontrol->private_data; 194 int index = ucontrol->id.index; 195 196 /* route has no bias */ 197 ucontrol->value.enumerated.item[0] = elem->cache_val[index]; 198 199 return 0; 200 } 201 202 static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol, 203 struct snd_ctl_elem_value *ucontrol) 204 { 205 struct usb_mixer_elem_info *elem = kcontrol->private_data; 206 struct snd_usb_audio *chip = elem->head.mixer->chip; 207 int index = ucontrol->id.index; 208 char buf[sizeof(route_msg)]; 209 int val, val_org, err; 210 211 /* get the new value (no bias for routes) */ 212 val = ucontrol->value.enumerated.item[0]; 213 214 /* sanity check */ 215 if (val < 0 || val > 9) 216 return -EINVAL; 217 218 /* prepare the message buffer from template */ 219 memcpy(buf, route_msg, sizeof(route_msg)); 220 221 if (val < 2) { 222 /* input comes from a master channel */ 223 val_org = val; 224 buf[2] = 0x02; 225 } else { 226 /* input comes from a computer channel */ 227 buf[2] = 0x03; 228 val_org = val - 2; 229 } 230 231 /* place new route selection in URB message */ 232 buf[5] = (unsigned char) (val_org & 0x0f) + 1; 233 /* place route selector in URB message */ 234 buf[13] = index + 1; 235 236 err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg)); 237 238 if (err > 0) { 239 elem->cached |= 1 << index; 240 elem->cache_val[index] = val; 241 } else { 242 usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err); 243 } 244 245 return err > 0 ? 1 : 0; 246 } 247 248 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol, 249 struct snd_ctl_elem_info *uinfo) 250 { 251 uinfo->count = 1; 252 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 253 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol); 254 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol); 255 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol); 256 return 0; 257 } 258 259 static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol, 260 struct snd_ctl_elem_value *ucontrol) 261 { 262 struct usb_mixer_elem_info *elem = kcontrol->private_data; 263 int index = ucontrol->id.index; 264 265 ucontrol->value.integer.value[0] = elem->cache_val[index]; 266 267 return 0; 268 } 269 270 static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol, 271 struct snd_ctl_elem_value *ucontrol) 272 { 273 struct usb_mixer_elem_info *elem = kcontrol->private_data; 274 struct snd_usb_audio *chip = elem->head.mixer->chip; 275 char buf[sizeof(mix_msg_out)]; 276 int val, err; 277 int index = ucontrol->id.index; 278 279 /* new control value incl. bias*/ 280 val = ucontrol->value.integer.value[0]; 281 282 /* sanity check */ 283 if (val < SND_US16X08_KCMIN(kcontrol) 284 || val > SND_US16X08_KCMAX(kcontrol)) 285 return -EINVAL; 286 287 /* prepare the message buffer from template */ 288 memcpy(buf, mix_msg_out, sizeof(mix_msg_out)); 289 290 buf[8] = val - SND_US16X08_KCBIAS(kcontrol); 291 buf[6] = elem->head.id; 292 293 /* place channel selector in URB message */ 294 buf[5] = index + 1; 295 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out)); 296 297 if (err > 0) { 298 elem->cached |= 1 << index; 299 elem->cache_val[index] = val; 300 } else { 301 usb_audio_dbg(chip, "Failed to set master, err:%d\n", err); 302 } 303 304 return err > 0 ? 1 : 0; 305 } 306 307 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol, 308 struct snd_ctl_elem_value *ucontrol) 309 { 310 struct usb_mixer_elem_info *elem = kcontrol->private_data; 311 struct snd_usb_audio *chip = elem->head.mixer->chip; 312 char buf[sizeof(mix_msg_out)]; 313 int val, err = 0; 314 315 val = ucontrol->value.integer.value[0]; 316 317 /* prepare the message buffer from template */ 318 switch (elem->head.id) { 319 case SND_US16X08_ID_BYPASS: 320 memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out)); 321 buf[2] = val; 322 err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out)); 323 break; 324 case SND_US16X08_ID_BUSS_OUT: 325 memcpy(buf, bus_msg_out, sizeof(bus_msg_out)); 326 buf[2] = val; 327 err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out)); 328 break; 329 case SND_US16X08_ID_MUTE: 330 memcpy(buf, mix_msg_out, sizeof(mix_msg_out)); 331 buf[8] = val; 332 buf[6] = elem->head.id; 333 buf[5] = 1; 334 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out)); 335 break; 336 } 337 338 if (err > 0) { 339 elem->cached |= 1; 340 elem->cache_val[0] = val; 341 } else { 342 usb_audio_dbg(chip, "Failed to set buss param, err:%d\n", err); 343 } 344 345 return err > 0 ? 1 : 0; 346 } 347 348 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol, 349 struct snd_ctl_elem_value *ucontrol) 350 { 351 struct usb_mixer_elem_info *elem = kcontrol->private_data; 352 353 switch (elem->head.id) { 354 case SND_US16X08_ID_BUSS_OUT: 355 ucontrol->value.integer.value[0] = elem->cache_val[0]; 356 break; 357 case SND_US16X08_ID_BYPASS: 358 ucontrol->value.integer.value[0] = elem->cache_val[0]; 359 break; 360 case SND_US16X08_ID_MUTE: 361 ucontrol->value.integer.value[0] = elem->cache_val[0]; 362 break; 363 } 364 365 return 0; 366 } 367 368 /* gets a current mixer value from common store */ 369 static int snd_us16x08_channel_get(struct snd_kcontrol *kcontrol, 370 struct snd_ctl_elem_value *ucontrol) 371 { 372 struct usb_mixer_elem_info *elem = kcontrol->private_data; 373 int index = ucontrol->id.index; 374 375 ucontrol->value.integer.value[0] = elem->cache_val[index]; 376 377 return 0; 378 } 379 380 static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol, 381 struct snd_ctl_elem_value *ucontrol) 382 { 383 struct usb_mixer_elem_info *elem = kcontrol->private_data; 384 struct snd_usb_audio *chip = elem->head.mixer->chip; 385 char buf[sizeof(mix_msg_in)]; 386 int val, err; 387 int index = ucontrol->id.index; 388 389 val = ucontrol->value.integer.value[0]; 390 391 /* sanity check */ 392 if (val < SND_US16X08_KCMIN(kcontrol) 393 || val > SND_US16X08_KCMAX(kcontrol)) 394 return -EINVAL; 395 396 /* prepare URB message from template */ 397 memcpy(buf, mix_msg_in, sizeof(mix_msg_in)); 398 399 /* add the bias to the new value */ 400 buf[8] = val - SND_US16X08_KCBIAS(kcontrol); 401 buf[6] = elem->head.id; 402 buf[5] = index + 1; 403 404 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in)); 405 406 if (err > 0) { 407 elem->cached |= 1 << index; 408 elem->cache_val[index] = val; 409 } else { 410 usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err); 411 } 412 413 return err > 0 ? 1 : 0; 414 } 415 416 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol, 417 struct snd_ctl_elem_info *uinfo) 418 { 419 uinfo->count = 1; 420 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 421 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol); 422 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol); 423 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol); 424 return 0; 425 } 426 427 static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol, 428 struct snd_ctl_elem_value *ucontrol) 429 { 430 struct usb_mixer_elem_info *elem = kcontrol->private_data; 431 struct snd_us16x08_comp_store *store = elem->private_data; 432 int index = ucontrol->id.index; 433 int val_idx = COMP_STORE_IDX(elem->head.id); 434 435 ucontrol->value.integer.value[0] = store->val[val_idx][index]; 436 437 return 0; 438 } 439 440 static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol, 441 struct snd_ctl_elem_value *ucontrol) 442 { 443 struct usb_mixer_elem_info *elem = kcontrol->private_data; 444 struct snd_usb_audio *chip = elem->head.mixer->chip; 445 struct snd_us16x08_comp_store *store = elem->private_data; 446 int index = ucontrol->id.index; 447 char buf[sizeof(comp_msg)]; 448 int val_idx, val; 449 int err; 450 451 val = ucontrol->value.integer.value[0]; 452 453 /* sanity check */ 454 if (val < SND_US16X08_KCMIN(kcontrol) 455 || val > SND_US16X08_KCMAX(kcontrol)) 456 return -EINVAL; 457 458 /* new control value incl. bias*/ 459 val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE; 460 461 store->val[val_idx][index] = ucontrol->value.integer.value[0]; 462 463 /* prepare compressor URB message from template */ 464 memcpy(buf, comp_msg, sizeof(comp_msg)); 465 466 /* place comp values in message buffer watch bias! */ 467 buf[8] = store->val[ 468 COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index] 469 - SND_US16X08_COMP_THRESHOLD_BIAS; 470 buf[11] = ratio_map[store->val[ 471 COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]]; 472 buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index] 473 + SND_US16X08_COMP_ATTACK_BIAS; 474 buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index] 475 + SND_US16X08_COMP_RELEASE_BIAS; 476 buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index]; 477 buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index]; 478 479 /* place channel selector in message buffer */ 480 buf[5] = index + 1; 481 482 err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg)); 483 484 if (err > 0) { 485 elem->cached |= 1 << index; 486 elem->cache_val[index] = val; 487 } else { 488 usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err); 489 } 490 491 return 1; 492 } 493 494 static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol, 495 struct snd_ctl_elem_value *ucontrol) 496 { 497 int val; 498 struct usb_mixer_elem_info *elem = kcontrol->private_data; 499 struct snd_us16x08_eq_store *store = elem->private_data; 500 int index = ucontrol->id.index; 501 502 /* get low switch from cache is enough, cause all bands are together */ 503 val = store->val[EQ_STORE_BAND_IDX(elem->head.id)] 504 [EQ_STORE_PARAM_IDX(elem->head.id)][index]; 505 ucontrol->value.integer.value[0] = val; 506 507 return 0; 508 } 509 510 static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol, 511 struct snd_ctl_elem_value *ucontrol) 512 { 513 struct usb_mixer_elem_info *elem = kcontrol->private_data; 514 struct snd_usb_audio *chip = elem->head.mixer->chip; 515 struct snd_us16x08_eq_store *store = elem->private_data; 516 int index = ucontrol->id.index; 517 char buf[sizeof(eqs_msq)]; 518 int val, err = 0; 519 int b_idx; 520 521 /* new control value incl. bias*/ 522 val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol); 523 524 /* prepare URB message from EQ template */ 525 memcpy(buf, eqs_msq, sizeof(eqs_msq)); 526 527 /* place channel index in URB message */ 528 buf[5] = index + 1; 529 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) { 530 /* all four EQ bands have to be enabled/disabled in once */ 531 buf[20] = val; 532 buf[17] = store->val[b_idx][2][index]; 533 buf[14] = store->val[b_idx][1][index]; 534 buf[11] = store->val[b_idx][0][index]; 535 buf[8] = b_idx + 1; 536 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq)); 537 if (err < 0) 538 break; 539 store->val[b_idx][3][index] = val; 540 msleep(15); 541 } 542 543 if (err > 0) { 544 elem->cached |= 1 << index; 545 elem->cache_val[index] = val; 546 } else { 547 usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err); 548 } 549 550 return 1; 551 } 552 553 static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol, 554 struct snd_ctl_elem_value *ucontrol) 555 { 556 int val; 557 struct usb_mixer_elem_info *elem = kcontrol->private_data; 558 struct snd_us16x08_eq_store *store = elem->private_data; 559 int index = ucontrol->id.index; 560 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; 561 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); 562 563 val = store->val[b_idx][p_idx][index]; 564 565 ucontrol->value.integer.value[0] = val; 566 567 return 0; 568 } 569 570 static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol, 571 struct snd_ctl_elem_value *ucontrol) 572 { 573 struct usb_mixer_elem_info *elem = kcontrol->private_data; 574 struct snd_usb_audio *chip = elem->head.mixer->chip; 575 struct snd_us16x08_eq_store *store = elem->private_data; 576 int index = ucontrol->id.index; 577 char buf[sizeof(eqs_msq)]; 578 int val, err; 579 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; 580 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); 581 582 val = ucontrol->value.integer.value[0]; 583 584 /* sanity check */ 585 if (val < SND_US16X08_KCMIN(kcontrol) 586 || val > SND_US16X08_KCMAX(kcontrol)) 587 return -EINVAL; 588 589 /* copy URB buffer from EQ template */ 590 memcpy(buf, eqs_msq, sizeof(eqs_msq)); 591 592 store->val[b_idx][p_idx][index] = val; 593 buf[20] = store->val[b_idx][3][index]; 594 buf[17] = store->val[b_idx][2][index]; 595 buf[14] = store->val[b_idx][1][index]; 596 buf[11] = store->val[b_idx][0][index]; 597 598 /* place channel index in URB buffer */ 599 buf[5] = index + 1; 600 601 /* place EQ band in URB buffer */ 602 buf[8] = b_idx + 1; 603 604 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq)); 605 606 if (err > 0) { 607 /* store new value in EQ band cache */ 608 elem->cached |= 1 << index; 609 elem->cache_val[index] = val; 610 } else { 611 usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err); 612 } 613 614 return 1; 615 } 616 617 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol, 618 struct snd_ctl_elem_info *uinfo) 619 { 620 uinfo->count = 1; 621 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 622 uinfo->value.integer.max = 0x7FFF; 623 uinfo->value.integer.min = 0; 624 625 return 0; 626 } 627 628 /* calculate compressor index for reduction level request */ 629 static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store) 630 { 631 int ret; 632 633 /* any channel active */ 634 if (store->comp_active_index) { 635 /* check for stereo link */ 636 if (store->comp_active_index & 0x20) { 637 /* reset comp_index to left channel*/ 638 if (store->comp_index - 639 store->comp_active_index > 1) 640 store->comp_index = 641 store->comp_active_index; 642 643 ret = store->comp_index++ & 0x1F; 644 } else { 645 /* no stereo link */ 646 ret = store->comp_active_index; 647 } 648 } else { 649 /* skip channels with no compressor active */ 650 while (!store->comp_store->val[ 651 COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)] 652 [store->comp_index - 1] 653 && store->comp_index <= SND_US16X08_MAX_CHANNELS) { 654 store->comp_index++; 655 } 656 ret = store->comp_index++; 657 if (store->comp_index > SND_US16X08_MAX_CHANNELS) 658 store->comp_index = 1; 659 } 660 return ret; 661 } 662 663 /* retrieve the meter level values from URB message */ 664 static void get_meter_levels_from_urb(int s, 665 struct snd_us16x08_meter_store *store, 666 u8 *meter_urb) 667 { 668 int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8); 669 670 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 && 671 MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) { 672 if (MUC0(meter_urb, s) == 0x72) 673 store->meter_level[MUB2(meter_urb, s) - 1] = val; 674 if (MUC0(meter_urb, s) == 0xb2) 675 store->comp_level[MUB2(meter_urb, s) - 1] = val; 676 } 677 if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 && 678 MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62) 679 store->master_level[MUB2(meter_urb, s) - 1] = val; 680 } 681 682 /* Function to retrieve current meter values from the device. 683 * 684 * The device needs to be polled for meter values with an initial 685 * requests. It will return with a sequence of different meter value 686 * packages. The first request (case 0:) initiate this meter response sequence. 687 * After the third response, an additional request can be placed, 688 * to retrieve compressor reduction level value for given channel. This round 689 * trip channel selector will skip all inactive compressors. 690 * A mixer can interrupt this round-trip by selecting one ore two (stereo-link) 691 * specific channels. 692 */ 693 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, 694 struct snd_ctl_elem_value *ucontrol) 695 { 696 int i, set; 697 struct usb_mixer_elem_info *elem = kcontrol->private_data; 698 struct snd_usb_audio *chip = elem->head.mixer->chip; 699 struct snd_us16x08_meter_store *store = elem->private_data; 700 u8 meter_urb[64]; 701 char tmp[sizeof(mix_init_msg2)] = {0}; 702 703 switch (kcontrol->private_value) { 704 case 0: 705 snd_us16x08_send_urb(chip, (char *)mix_init_msg1, 706 sizeof(mix_init_msg1)); 707 snd_us16x08_recv_urb(chip, meter_urb, 708 sizeof(meter_urb)); 709 kcontrol->private_value++; 710 break; 711 case 1: 712 snd_us16x08_recv_urb(chip, meter_urb, 713 sizeof(meter_urb)); 714 kcontrol->private_value++; 715 break; 716 case 2: 717 snd_us16x08_recv_urb(chip, meter_urb, 718 sizeof(meter_urb)); 719 kcontrol->private_value++; 720 break; 721 case 3: 722 memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); 723 tmp[2] = snd_get_meter_comp_index(store); 724 snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2)); 725 snd_us16x08_recv_urb(chip, meter_urb, 726 sizeof(meter_urb)); 727 kcontrol->private_value = 0; 728 break; 729 } 730 731 for (set = 0; set < 6; set++) 732 get_meter_levels_from_urb(set, store, meter_urb); 733 734 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 735 ucontrol->value.integer.value[i] = 736 store ? store->meter_level[i] : 0; 737 } 738 739 ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0; 740 ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0; 741 742 for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++) 743 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] = 744 store ? store->comp_level[i - 2] : 0; 745 746 return 1; 747 } 748 749 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol, 750 struct snd_ctl_elem_value *ucontrol) 751 { 752 struct usb_mixer_elem_info *elem = kcontrol->private_data; 753 struct snd_us16x08_meter_store *store = elem->private_data; 754 int val; 755 756 val = ucontrol->value.integer.value[0]; 757 758 /* sanity check */ 759 if (val < 0 || val >= SND_US16X08_MAX_CHANNELS) 760 return -EINVAL; 761 762 store->comp_active_index = val; 763 store->comp_index = val; 764 765 return 1; 766 } 767 768 static struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = { 769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 770 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 771 .count = 16, 772 .info = snd_us16x08_switch_info, 773 .get = snd_us16x08_channel_get, 774 .put = snd_us16x08_channel_put, 775 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 776 }; 777 778 static struct snd_kcontrol_new snd_us16x08_ch_int_ctl = { 779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 780 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 781 .count = 16, 782 .info = snd_us16x08_mix_info, 783 .get = snd_us16x08_channel_get, 784 .put = snd_us16x08_channel_put, 785 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133) 786 }; 787 788 static struct snd_kcontrol_new snd_us16x08_pan_int_ctl = { 789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 790 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 791 .count = 16, 792 .info = snd_us16x08_mix_info, 793 .get = snd_us16x08_channel_get, 794 .put = snd_us16x08_channel_put, 795 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255) 796 }; 797 798 static struct snd_kcontrol_new snd_us16x08_master_ctl = { 799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 801 .count = 1, 802 .info = snd_us16x08_master_info, 803 .get = snd_us16x08_master_get, 804 .put = snd_us16x08_master_put, 805 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133) 806 }; 807 808 static struct snd_kcontrol_new snd_us16x08_route_ctl = { 809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 810 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 811 .count = 8, 812 .info = snd_us16x08_route_info, 813 .get = snd_us16x08_route_get, 814 .put = snd_us16x08_route_put, 815 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9) 816 }; 817 818 static struct snd_kcontrol_new snd_us16x08_bus_ctl = { 819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 820 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 821 .count = 1, 822 .info = snd_us16x08_switch_info, 823 .get = snd_us16x08_bus_get, 824 .put = snd_us16x08_bus_put, 825 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 826 }; 827 828 static struct snd_kcontrol_new snd_us16x08_compswitch_ctl = { 829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 830 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 831 .count = 16, 832 .info = snd_us16x08_switch_info, 833 .get = snd_us16x08_comp_get, 834 .put = snd_us16x08_comp_put, 835 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 836 }; 837 838 static struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = { 839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 840 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 841 .count = 16, 842 .info = snd_us16x08_mix_info, 843 .get = snd_us16x08_comp_get, 844 .put = snd_us16x08_comp_put, 845 .private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1, 846 0, 0x20) 847 }; 848 849 static struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = { 850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 852 .count = 16, 853 .info = snd_us16x08_mix_info, 854 .get = snd_us16x08_comp_get, 855 .put = snd_us16x08_comp_put, 856 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 857 sizeof(ratio_map) - 1), /*max*/ 858 }; 859 860 static struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = { 861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 862 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 863 .count = 16, 864 .info = snd_us16x08_mix_info, 865 .get = snd_us16x08_comp_get, 866 .put = snd_us16x08_comp_put, 867 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14) 868 }; 869 870 static struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = { 871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 872 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 873 .count = 16, 874 .info = snd_us16x08_mix_info, 875 .get = snd_us16x08_comp_get, 876 .put = snd_us16x08_comp_put, 877 .private_value = 878 SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6), 879 }; 880 881 static struct snd_kcontrol_new snd_us16x08_comp_release_ctl = { 882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 883 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 884 .count = 16, 885 .info = snd_us16x08_mix_info, 886 .get = snd_us16x08_comp_get, 887 .put = snd_us16x08_comp_put, 888 .private_value = 889 SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63), 890 }; 891 892 static struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = { 893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 894 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 895 .count = 16, 896 .info = snd_us16x08_mix_info, 897 .get = snd_us16x08_eq_get, 898 .put = snd_us16x08_eq_put, 899 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24), 900 }; 901 902 static struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = { 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 904 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 905 .count = 16, 906 .info = snd_us16x08_mix_info, 907 .get = snd_us16x08_eq_get, 908 .put = snd_us16x08_eq_put, 909 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F), 910 }; 911 912 static struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = { 913 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 914 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 915 .count = 16, 916 .info = snd_us16x08_mix_info, 917 .get = snd_us16x08_eq_get, 918 .put = snd_us16x08_eq_put, 919 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F) 920 }; 921 922 static struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = { 923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 924 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 925 .count = 16, 926 .info = snd_us16x08_mix_info, 927 .get = snd_us16x08_eq_get, 928 .put = snd_us16x08_eq_put, 929 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06) 930 }; 931 932 static struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = { 933 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 934 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 935 .count = 16, 936 .info = snd_us16x08_mix_info, 937 .get = snd_us16x08_eq_get, 938 .put = snd_us16x08_eq_put, 939 .private_value = 940 SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F) 941 }; 942 943 static struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = { 944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 945 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 946 .count = 16, 947 .info = snd_us16x08_switch_info, 948 .get = snd_us16x08_eqswitch_get, 949 .put = snd_us16x08_eqswitch_put, 950 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 951 }; 952 953 static struct snd_kcontrol_new snd_us16x08_meter_ctl = { 954 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 955 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 956 .count = 1, 957 .info = snd_us16x08_meter_info, 958 .get = snd_us16x08_meter_get, 959 .put = snd_us16x08_meter_put 960 }; 961 962 /* control store preparation */ 963 964 /* setup compressor store and assign default value */ 965 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void) 966 { 967 int i; 968 struct snd_us16x08_comp_store *tmp; 969 970 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 971 if (!tmp) 972 return NULL; 973 974 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 975 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i] 976 = 0x20; 977 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00; 978 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00; 979 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00; 980 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00; 981 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00; 982 } 983 return tmp; 984 } 985 986 /* setup EQ store and assign default values */ 987 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void) 988 { 989 int i, b_idx; 990 struct snd_us16x08_eq_store *tmp; 991 992 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 993 if (!tmp) 994 return NULL; 995 996 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 997 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) { 998 tmp->val[b_idx][0][i] = 0x0c; 999 tmp->val[b_idx][3][i] = 0x00; 1000 switch (b_idx) { 1001 case 0: /* EQ Low */ 1002 tmp->val[b_idx][1][i] = 0x05; 1003 tmp->val[b_idx][2][i] = 0xff; 1004 break; 1005 case 1: /* EQ Mid low */ 1006 tmp->val[b_idx][1][i] = 0x0e; 1007 tmp->val[b_idx][2][i] = 0x02; 1008 break; 1009 case 2: /* EQ Mid High */ 1010 tmp->val[b_idx][1][i] = 0x1b; 1011 tmp->val[b_idx][2][i] = 0x02; 1012 break; 1013 case 3: /* EQ High */ 1014 tmp->val[b_idx][1][i] = 0x2f 1015 - SND_US16X08_EQ_HIGHFREQ_BIAS; 1016 tmp->val[b_idx][2][i] = 0xff; 1017 break; 1018 } 1019 } 1020 } 1021 return tmp; 1022 } 1023 1024 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void) 1025 { 1026 struct snd_us16x08_meter_store *tmp; 1027 1028 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 1029 if (!tmp) 1030 return NULL; 1031 tmp->comp_index = 1; 1032 tmp->comp_active_index = 0; 1033 return tmp; 1034 } 1035 1036 /* release elem->private_free as well; called only once for each *_store */ 1037 static void elem_private_free(struct snd_kcontrol *kctl) 1038 { 1039 struct usb_mixer_elem_info *elem = kctl->private_data; 1040 1041 if (elem) 1042 kfree(elem->private_data); 1043 kfree(elem); 1044 kctl->private_data = NULL; 1045 } 1046 1047 static int add_new_ctl(struct usb_mixer_interface *mixer, 1048 const struct snd_kcontrol_new *ncontrol, 1049 int index, int val_type, int channels, 1050 const char *name, void *opt, 1051 bool do_private_free, 1052 struct usb_mixer_elem_info **elem_ret) 1053 { 1054 struct snd_kcontrol *kctl; 1055 struct usb_mixer_elem_info *elem; 1056 int err; 1057 1058 usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name); 1059 1060 elem = kzalloc(sizeof(*elem), GFP_KERNEL); 1061 if (!elem) 1062 return -ENOMEM; 1063 1064 elem->head.mixer = mixer; 1065 elem->head.resume = NULL; 1066 elem->control = 0; 1067 elem->idx_off = 0; 1068 elem->head.id = index; 1069 elem->val_type = val_type; 1070 elem->channels = channels; 1071 elem->private_data = opt; 1072 1073 kctl = snd_ctl_new1(ncontrol, elem); 1074 if (!kctl) { 1075 kfree(elem); 1076 return -ENOMEM; 1077 } 1078 1079 if (do_private_free) 1080 kctl->private_free = elem_private_free; 1081 else 1082 kctl->private_free = snd_usb_mixer_elem_free; 1083 1084 strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); 1085 1086 err = snd_usb_mixer_add_control(&elem->head, kctl); 1087 if (err < 0) 1088 return err; 1089 1090 if (elem_ret) 1091 *elem_ret = elem; 1092 1093 return 0; 1094 } 1095 1096 /* table of EQ controls */ 1097 static const struct snd_us16x08_control_params eq_controls[] = { 1098 { /* EQ switch */ 1099 .kcontrol_new = &snd_us16x08_eq_switch_ctl, 1100 .control_id = SND_US16X08_ID_EQENABLE, 1101 .type = USB_MIXER_BOOLEAN, 1102 .num_channels = 16, 1103 .name = "EQ Switch", 1104 }, 1105 { /* EQ low gain */ 1106 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1107 .control_id = SND_US16X08_ID_EQLOWLEVEL, 1108 .type = USB_MIXER_U8, 1109 .num_channels = 16, 1110 .name = "EQ Low Volume", 1111 }, 1112 { /* EQ low freq */ 1113 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl, 1114 .control_id = SND_US16X08_ID_EQLOWFREQ, 1115 .type = USB_MIXER_U8, 1116 .num_channels = 16, 1117 .name = "EQ Low Frequence", 1118 }, 1119 { /* EQ mid low gain */ 1120 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1121 .control_id = SND_US16X08_ID_EQLOWMIDLEVEL, 1122 .type = USB_MIXER_U8, 1123 .num_channels = 16, 1124 .name = "EQ MidLow Volume", 1125 }, 1126 { /* EQ mid low freq */ 1127 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1128 .control_id = SND_US16X08_ID_EQLOWMIDFREQ, 1129 .type = USB_MIXER_U8, 1130 .num_channels = 16, 1131 .name = "EQ MidLow Frequence", 1132 }, 1133 { /* EQ mid low Q */ 1134 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1135 .control_id = SND_US16X08_ID_EQLOWMIDWIDTH, 1136 .type = USB_MIXER_U8, 1137 .num_channels = 16, 1138 .name = "EQ MidQLow Q", 1139 }, 1140 { /* EQ mid high gain */ 1141 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1142 .control_id = SND_US16X08_ID_EQHIGHMIDLEVEL, 1143 .type = USB_MIXER_U8, 1144 .num_channels = 16, 1145 .name = "EQ MidHigh Volume", 1146 }, 1147 { /* EQ mid high freq */ 1148 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1149 .control_id = SND_US16X08_ID_EQHIGHMIDFREQ, 1150 .type = USB_MIXER_U8, 1151 .num_channels = 16, 1152 .name = "EQ MidHigh Frequence", 1153 }, 1154 { /* EQ mid high Q */ 1155 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1156 .control_id = SND_US16X08_ID_EQHIGHMIDWIDTH, 1157 .type = USB_MIXER_U8, 1158 .num_channels = 16, 1159 .name = "EQ MidHigh Q", 1160 }, 1161 { /* EQ high gain */ 1162 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1163 .control_id = SND_US16X08_ID_EQHIGHLEVEL, 1164 .type = USB_MIXER_U8, 1165 .num_channels = 16, 1166 .name = "EQ High Volume", 1167 }, 1168 { /* EQ low freq */ 1169 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl, 1170 .control_id = SND_US16X08_ID_EQHIGHFREQ, 1171 .type = USB_MIXER_U8, 1172 .num_channels = 16, 1173 .name = "EQ High Frequence", 1174 }, 1175 }; 1176 1177 /* table of compressor controls */ 1178 static const struct snd_us16x08_control_params comp_controls[] = { 1179 { /* Comp enable */ 1180 .kcontrol_new = &snd_us16x08_compswitch_ctl, 1181 .control_id = SND_US16X08_ID_COMP_SWITCH, 1182 .type = USB_MIXER_BOOLEAN, 1183 .num_channels = 16, 1184 .name = "Compressor Switch", 1185 }, 1186 { /* Comp threshold */ 1187 .kcontrol_new = &snd_us16x08_comp_threshold_ctl, 1188 .control_id = SND_US16X08_ID_COMP_THRESHOLD, 1189 .type = USB_MIXER_U8, 1190 .num_channels = 16, 1191 .name = "Compressor Threshold Volume", 1192 }, 1193 { /* Comp ratio */ 1194 .kcontrol_new = &snd_us16x08_comp_ratio_ctl, 1195 .control_id = SND_US16X08_ID_COMP_RATIO, 1196 .type = USB_MIXER_U8, 1197 .num_channels = 16, 1198 .name = "Compressor Ratio", 1199 }, 1200 { /* Comp attack */ 1201 .kcontrol_new = &snd_us16x08_comp_attack_ctl, 1202 .control_id = SND_US16X08_ID_COMP_ATTACK, 1203 .type = USB_MIXER_U8, 1204 .num_channels = 16, 1205 .name = "Compressor Attack", 1206 }, 1207 { /* Comp release */ 1208 .kcontrol_new = &snd_us16x08_comp_release_ctl, 1209 .control_id = SND_US16X08_ID_COMP_RELEASE, 1210 .type = USB_MIXER_U8, 1211 .num_channels = 16, 1212 .name = "Compressor Release", 1213 }, 1214 { /* Comp gain */ 1215 .kcontrol_new = &snd_us16x08_comp_gain_ctl, 1216 .control_id = SND_US16X08_ID_COMP_GAIN, 1217 .type = USB_MIXER_U8, 1218 .num_channels = 16, 1219 .name = "Compressor Volume", 1220 }, 1221 }; 1222 1223 /* table of channel controls */ 1224 static const struct snd_us16x08_control_params channel_controls[] = { 1225 { /* Phase */ 1226 .kcontrol_new = &snd_us16x08_ch_boolean_ctl, 1227 .control_id = SND_US16X08_ID_PHASE, 1228 .type = USB_MIXER_BOOLEAN, 1229 .num_channels = 16, 1230 .name = "Phase Switch", 1231 .default_val = 0 1232 }, 1233 { /* Fader */ 1234 .kcontrol_new = &snd_us16x08_ch_int_ctl, 1235 .control_id = SND_US16X08_ID_FADER, 1236 .type = USB_MIXER_U8, 1237 .num_channels = 16, 1238 .name = "Line Volume", 1239 .default_val = 127 1240 }, 1241 { /* Mute */ 1242 .kcontrol_new = &snd_us16x08_ch_boolean_ctl, 1243 .control_id = SND_US16X08_ID_MUTE, 1244 .type = USB_MIXER_BOOLEAN, 1245 .num_channels = 16, 1246 .name = "Mute Switch", 1247 .default_val = 0 1248 }, 1249 { /* Pan */ 1250 .kcontrol_new = &snd_us16x08_pan_int_ctl, 1251 .control_id = SND_US16X08_ID_PAN, 1252 .type = USB_MIXER_U16, 1253 .num_channels = 16, 1254 .name = "Pan Left-Right Volume", 1255 .default_val = 127 1256 }, 1257 }; 1258 1259 /* table of master controls */ 1260 static const struct snd_us16x08_control_params master_controls[] = { 1261 { /* Master */ 1262 .kcontrol_new = &snd_us16x08_master_ctl, 1263 .control_id = SND_US16X08_ID_FADER, 1264 .type = USB_MIXER_U8, 1265 .num_channels = 16, 1266 .name = "Master Volume", 1267 .default_val = 127 1268 }, 1269 { /* Bypass */ 1270 .kcontrol_new = &snd_us16x08_bus_ctl, 1271 .control_id = SND_US16X08_ID_BYPASS, 1272 .type = USB_MIXER_BOOLEAN, 1273 .num_channels = 16, 1274 .name = "DSP Bypass Switch", 1275 .default_val = 0 1276 }, 1277 { /* Buss out */ 1278 .kcontrol_new = &snd_us16x08_bus_ctl, 1279 .control_id = SND_US16X08_ID_BUSS_OUT, 1280 .type = USB_MIXER_BOOLEAN, 1281 .num_channels = 16, 1282 .name = "Buss Out Switch", 1283 .default_val = 0 1284 }, 1285 { /* Master mute */ 1286 .kcontrol_new = &snd_us16x08_bus_ctl, 1287 .control_id = SND_US16X08_ID_MUTE, 1288 .type = USB_MIXER_BOOLEAN, 1289 .num_channels = 16, 1290 .name = "Master Mute Switch", 1291 .default_val = 0 1292 }, 1293 1294 }; 1295 1296 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) 1297 { 1298 int i, j; 1299 int err; 1300 struct usb_mixer_elem_info *elem; 1301 struct snd_us16x08_comp_store *comp_store; 1302 struct snd_us16x08_meter_store *meter_store; 1303 struct snd_us16x08_eq_store *eq_store; 1304 1305 /* just check for non-MIDI interface */ 1306 if (mixer->hostif->desc.bInterfaceNumber == 3) { 1307 1308 /* add routing control */ 1309 err = add_new_ctl(mixer, &snd_us16x08_route_ctl, 1310 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route", 1311 NULL, false, &elem); 1312 if (err < 0) { 1313 usb_audio_dbg(mixer->chip, 1314 "Failed to create route control, err:%d\n", 1315 err); 1316 return err; 1317 } 1318 for (i = 0; i < 8; i++) 1319 elem->cache_val[i] = i < 2 ? i : i + 2; 1320 elem->cached = 0xff; 1321 1322 /* create compressor mixer elements */ 1323 comp_store = snd_us16x08_create_comp_store(); 1324 if (!comp_store) 1325 return -ENOMEM; 1326 1327 /* add master controls */ 1328 for (i = 0; i < ARRAY_SIZE(master_controls); i++) { 1329 1330 err = add_new_ctl(mixer, 1331 master_controls[i].kcontrol_new, 1332 master_controls[i].control_id, 1333 master_controls[i].type, 1334 master_controls[i].num_channels, 1335 master_controls[i].name, 1336 comp_store, 1337 i == 0, /* release comp_store only once */ 1338 &elem); 1339 if (err < 0) 1340 return err; 1341 elem->cache_val[0] = master_controls[i].default_val; 1342 elem->cached = 1; 1343 } 1344 1345 /* add channel controls */ 1346 for (i = 0; i < ARRAY_SIZE(channel_controls); i++) { 1347 1348 err = add_new_ctl(mixer, 1349 channel_controls[i].kcontrol_new, 1350 channel_controls[i].control_id, 1351 channel_controls[i].type, 1352 channel_controls[i].num_channels, 1353 channel_controls[i].name, 1354 comp_store, 1355 false, &elem); 1356 if (err < 0) 1357 return err; 1358 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) { 1359 elem->cache_val[j] = 1360 channel_controls[i].default_val; 1361 } 1362 elem->cached = 0xffff; 1363 } 1364 1365 /* create eq store */ 1366 eq_store = snd_us16x08_create_eq_store(); 1367 if (!eq_store) 1368 return -ENOMEM; 1369 1370 /* add EQ controls */ 1371 for (i = 0; i < ARRAY_SIZE(eq_controls); i++) { 1372 1373 err = add_new_ctl(mixer, 1374 eq_controls[i].kcontrol_new, 1375 eq_controls[i].control_id, 1376 eq_controls[i].type, 1377 eq_controls[i].num_channels, 1378 eq_controls[i].name, 1379 eq_store, 1380 i == 0, /* release eq_store only once */ 1381 NULL); 1382 if (err < 0) 1383 return err; 1384 } 1385 1386 /* add compressor controls */ 1387 for (i = 0; i < ARRAY_SIZE(comp_controls); i++) { 1388 1389 err = add_new_ctl(mixer, 1390 comp_controls[i].kcontrol_new, 1391 comp_controls[i].control_id, 1392 comp_controls[i].type, 1393 comp_controls[i].num_channels, 1394 comp_controls[i].name, 1395 comp_store, 1396 false, NULL); 1397 if (err < 0) 1398 return err; 1399 } 1400 1401 /* create meters store */ 1402 meter_store = snd_us16x08_create_meter_store(); 1403 if (!meter_store) 1404 return -ENOMEM; 1405 1406 /* meter function 'get' must access to compressor store 1407 * so place a reference here 1408 */ 1409 meter_store->comp_store = comp_store; 1410 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl, 1411 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter", 1412 meter_store, true, NULL); 1413 if (err < 0) 1414 return err; 1415 } 1416 1417 return 0; 1418 } 1419 1420