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 702 switch (kcontrol->private_value) { 703 case 0: { 704 char tmp[sizeof(mix_init_msg1)]; 705 706 memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1)); 707 snd_us16x08_send_urb(chip, tmp, 4); 708 snd_us16x08_recv_urb(chip, meter_urb, 709 sizeof(meter_urb)); 710 kcontrol->private_value++; 711 break; 712 } 713 case 1: 714 snd_us16x08_recv_urb(chip, meter_urb, 715 sizeof(meter_urb)); 716 kcontrol->private_value++; 717 break; 718 case 2: 719 snd_us16x08_recv_urb(chip, meter_urb, 720 sizeof(meter_urb)); 721 kcontrol->private_value++; 722 break; 723 case 3: { 724 char tmp[sizeof(mix_init_msg2)]; 725 726 memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); 727 tmp[2] = snd_get_meter_comp_index(store); 728 snd_us16x08_send_urb(chip, tmp, 10); 729 snd_us16x08_recv_urb(chip, meter_urb, 730 sizeof(meter_urb)); 731 kcontrol->private_value = 0; 732 break; 733 } 734 } 735 736 for (set = 0; set < 6; set++) 737 get_meter_levels_from_urb(set, store, meter_urb); 738 739 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 740 ucontrol->value.integer.value[i] = 741 store ? store->meter_level[i] : 0; 742 } 743 744 ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0; 745 ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0; 746 747 for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++) 748 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] = 749 store ? store->comp_level[i - 2] : 0; 750 751 return 1; 752 } 753 754 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol, 755 struct snd_ctl_elem_value *ucontrol) 756 { 757 struct usb_mixer_elem_info *elem = kcontrol->private_data; 758 struct snd_us16x08_meter_store *store = elem->private_data; 759 int val; 760 761 val = ucontrol->value.integer.value[0]; 762 763 /* sanity check */ 764 if (val < 0 || val >= SND_US16X08_MAX_CHANNELS) 765 return -EINVAL; 766 767 store->comp_active_index = val; 768 store->comp_index = val; 769 770 return 1; 771 } 772 773 static struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = { 774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 775 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 776 .count = 16, 777 .info = snd_us16x08_switch_info, 778 .get = snd_us16x08_channel_get, 779 .put = snd_us16x08_channel_put, 780 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 781 }; 782 783 static struct snd_kcontrol_new snd_us16x08_ch_int_ctl = { 784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 785 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 786 .count = 16, 787 .info = snd_us16x08_mix_info, 788 .get = snd_us16x08_channel_get, 789 .put = snd_us16x08_channel_put, 790 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133) 791 }; 792 793 static struct snd_kcontrol_new snd_us16x08_pan_int_ctl = { 794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 795 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 796 .count = 16, 797 .info = snd_us16x08_mix_info, 798 .get = snd_us16x08_channel_get, 799 .put = snd_us16x08_channel_put, 800 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 255) 801 }; 802 803 static struct snd_kcontrol_new snd_us16x08_master_ctl = { 804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 805 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 806 .count = 1, 807 .info = snd_us16x08_master_info, 808 .get = snd_us16x08_master_get, 809 .put = snd_us16x08_master_put, 810 .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133) 811 }; 812 813 static struct snd_kcontrol_new snd_us16x08_route_ctl = { 814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 815 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 816 .count = 8, 817 .info = snd_us16x08_route_info, 818 .get = snd_us16x08_route_get, 819 .put = snd_us16x08_route_put, 820 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9) 821 }; 822 823 static struct snd_kcontrol_new snd_us16x08_bus_ctl = { 824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 825 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 826 .count = 1, 827 .info = snd_us16x08_switch_info, 828 .get = snd_us16x08_bus_get, 829 .put = snd_us16x08_bus_put, 830 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 831 }; 832 833 static struct snd_kcontrol_new snd_us16x08_compswitch_ctl = { 834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 836 .count = 16, 837 .info = snd_us16x08_switch_info, 838 .get = snd_us16x08_comp_get, 839 .put = snd_us16x08_comp_put, 840 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 841 }; 842 843 static struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = { 844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 845 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 846 .count = 16, 847 .info = snd_us16x08_mix_info, 848 .get = snd_us16x08_comp_get, 849 .put = snd_us16x08_comp_put, 850 .private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1, 851 0, 0x20) 852 }; 853 854 static struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = { 855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 856 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 857 .count = 16, 858 .info = snd_us16x08_mix_info, 859 .get = snd_us16x08_comp_get, 860 .put = snd_us16x08_comp_put, 861 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 862 sizeof(ratio_map) - 1), /*max*/ 863 }; 864 865 static struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = { 866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 867 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 868 .count = 16, 869 .info = snd_us16x08_mix_info, 870 .get = snd_us16x08_comp_get, 871 .put = snd_us16x08_comp_put, 872 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14) 873 }; 874 875 static struct snd_kcontrol_new snd_us16x08_comp_attack_ctl = { 876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 877 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 878 .count = 16, 879 .info = snd_us16x08_mix_info, 880 .get = snd_us16x08_comp_get, 881 .put = snd_us16x08_comp_put, 882 .private_value = 883 SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6), 884 }; 885 886 static struct snd_kcontrol_new snd_us16x08_comp_release_ctl = { 887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 888 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 889 .count = 16, 890 .info = snd_us16x08_mix_info, 891 .get = snd_us16x08_comp_get, 892 .put = snd_us16x08_comp_put, 893 .private_value = 894 SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63), 895 }; 896 897 static struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = { 898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 899 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 900 .count = 16, 901 .info = snd_us16x08_mix_info, 902 .get = snd_us16x08_eq_get, 903 .put = snd_us16x08_eq_put, 904 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24), 905 }; 906 907 static struct snd_kcontrol_new snd_us16x08_eq_low_freq_ctl = { 908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 909 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 910 .count = 16, 911 .info = snd_us16x08_mix_info, 912 .get = snd_us16x08_eq_get, 913 .put = snd_us16x08_eq_put, 914 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x1F), 915 }; 916 917 static struct snd_kcontrol_new snd_us16x08_eq_mid_freq_ctl = { 918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 919 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 920 .count = 16, 921 .info = snd_us16x08_mix_info, 922 .get = snd_us16x08_eq_get, 923 .put = snd_us16x08_eq_put, 924 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x3F) 925 }; 926 927 static struct snd_kcontrol_new snd_us16x08_eq_mid_width_ctl = { 928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 929 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 930 .count = 16, 931 .info = snd_us16x08_mix_info, 932 .get = snd_us16x08_eq_get, 933 .put = snd_us16x08_eq_put, 934 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x06) 935 }; 936 937 static struct snd_kcontrol_new snd_us16x08_eq_high_freq_ctl = { 938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 939 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 940 .count = 16, 941 .info = snd_us16x08_mix_info, 942 .get = snd_us16x08_eq_get, 943 .put = snd_us16x08_eq_put, 944 .private_value = 945 SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F) 946 }; 947 948 static struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = { 949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 950 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 951 .count = 16, 952 .info = snd_us16x08_switch_info, 953 .get = snd_us16x08_eqswitch_get, 954 .put = snd_us16x08_eqswitch_put, 955 .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1) 956 }; 957 958 static struct snd_kcontrol_new snd_us16x08_meter_ctl = { 959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 960 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 961 .count = 1, 962 .info = snd_us16x08_meter_info, 963 .get = snd_us16x08_meter_get, 964 .put = snd_us16x08_meter_put 965 }; 966 967 /* control store preparation */ 968 969 /* setup compressor store and assign default value */ 970 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void) 971 { 972 int i; 973 struct snd_us16x08_comp_store *tmp; 974 975 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 976 if (!tmp) 977 return NULL; 978 979 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 980 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i] 981 = 0x20; 982 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00; 983 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00; 984 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00; 985 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00; 986 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00; 987 } 988 return tmp; 989 } 990 991 /* setup EQ store and assign default values */ 992 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void) 993 { 994 int i, b_idx; 995 struct snd_us16x08_eq_store *tmp; 996 997 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 998 if (!tmp) 999 return NULL; 1000 1001 for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) { 1002 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) { 1003 tmp->val[b_idx][0][i] = 0x0c; 1004 tmp->val[b_idx][3][i] = 0x00; 1005 switch (b_idx) { 1006 case 0: /* EQ Low */ 1007 tmp->val[b_idx][1][i] = 0x05; 1008 tmp->val[b_idx][2][i] = 0xff; 1009 break; 1010 case 1: /* EQ Mid low */ 1011 tmp->val[b_idx][1][i] = 0x0e; 1012 tmp->val[b_idx][2][i] = 0x02; 1013 break; 1014 case 2: /* EQ Mid High */ 1015 tmp->val[b_idx][1][i] = 0x1b; 1016 tmp->val[b_idx][2][i] = 0x02; 1017 break; 1018 case 3: /* EQ High */ 1019 tmp->val[b_idx][1][i] = 0x2f 1020 - SND_US16X08_EQ_HIGHFREQ_BIAS; 1021 tmp->val[b_idx][2][i] = 0xff; 1022 break; 1023 } 1024 } 1025 } 1026 return tmp; 1027 } 1028 1029 static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void) 1030 { 1031 struct snd_us16x08_meter_store *tmp; 1032 1033 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 1034 if (!tmp) 1035 return NULL; 1036 tmp->comp_index = 1; 1037 tmp->comp_active_index = 0; 1038 return tmp; 1039 } 1040 1041 /* release elem->private_free as well; called only once for each *_store */ 1042 static void elem_private_free(struct snd_kcontrol *kctl) 1043 { 1044 struct usb_mixer_elem_info *elem = kctl->private_data; 1045 1046 if (elem) 1047 kfree(elem->private_data); 1048 kfree(elem); 1049 kctl->private_data = NULL; 1050 } 1051 1052 static int add_new_ctl(struct usb_mixer_interface *mixer, 1053 const struct snd_kcontrol_new *ncontrol, 1054 int index, int val_type, int channels, 1055 const char *name, void *opt, 1056 bool do_private_free, 1057 struct usb_mixer_elem_info **elem_ret) 1058 { 1059 struct snd_kcontrol *kctl; 1060 struct usb_mixer_elem_info *elem; 1061 int err; 1062 1063 usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name); 1064 1065 elem = kzalloc(sizeof(*elem), GFP_KERNEL); 1066 if (!elem) 1067 return -ENOMEM; 1068 1069 elem->head.mixer = mixer; 1070 elem->head.resume = NULL; 1071 elem->control = 0; 1072 elem->idx_off = 0; 1073 elem->head.id = index; 1074 elem->val_type = val_type; 1075 elem->channels = channels; 1076 elem->private_data = opt; 1077 1078 kctl = snd_ctl_new1(ncontrol, elem); 1079 if (!kctl) { 1080 kfree(elem); 1081 return -ENOMEM; 1082 } 1083 1084 if (do_private_free) 1085 kctl->private_free = elem_private_free; 1086 else 1087 kctl->private_free = snd_usb_mixer_elem_free; 1088 1089 strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); 1090 1091 err = snd_usb_mixer_add_control(&elem->head, kctl); 1092 if (err < 0) 1093 return err; 1094 1095 if (elem_ret) 1096 *elem_ret = elem; 1097 1098 return 0; 1099 } 1100 1101 /* table of EQ controls */ 1102 static const struct snd_us16x08_control_params eq_controls[] = { 1103 { /* EQ switch */ 1104 .kcontrol_new = &snd_us16x08_eq_switch_ctl, 1105 .control_id = SND_US16X08_ID_EQENABLE, 1106 .type = USB_MIXER_BOOLEAN, 1107 .num_channels = 16, 1108 .name = "EQ Switch", 1109 }, 1110 { /* EQ low gain */ 1111 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1112 .control_id = SND_US16X08_ID_EQLOWLEVEL, 1113 .type = USB_MIXER_U8, 1114 .num_channels = 16, 1115 .name = "EQ Low Volume", 1116 }, 1117 { /* EQ low freq */ 1118 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl, 1119 .control_id = SND_US16X08_ID_EQLOWFREQ, 1120 .type = USB_MIXER_U8, 1121 .num_channels = 16, 1122 .name = "EQ Low Frequence", 1123 }, 1124 { /* EQ mid low gain */ 1125 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1126 .control_id = SND_US16X08_ID_EQLOWMIDLEVEL, 1127 .type = USB_MIXER_U8, 1128 .num_channels = 16, 1129 .name = "EQ MidLow Volume", 1130 }, 1131 { /* EQ mid low freq */ 1132 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1133 .control_id = SND_US16X08_ID_EQLOWMIDFREQ, 1134 .type = USB_MIXER_U8, 1135 .num_channels = 16, 1136 .name = "EQ MidLow Frequence", 1137 }, 1138 { /* EQ mid low Q */ 1139 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1140 .control_id = SND_US16X08_ID_EQLOWMIDWIDTH, 1141 .type = USB_MIXER_U8, 1142 .num_channels = 16, 1143 .name = "EQ MidLow Q", 1144 }, 1145 { /* EQ mid high gain */ 1146 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1147 .control_id = SND_US16X08_ID_EQHIGHMIDLEVEL, 1148 .type = USB_MIXER_U8, 1149 .num_channels = 16, 1150 .name = "EQ MidHigh Volume", 1151 }, 1152 { /* EQ mid high freq */ 1153 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1154 .control_id = SND_US16X08_ID_EQHIGHMIDFREQ, 1155 .type = USB_MIXER_U8, 1156 .num_channels = 16, 1157 .name = "EQ MidHigh Frequence", 1158 }, 1159 { /* EQ mid high Q */ 1160 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1161 .control_id = SND_US16X08_ID_EQHIGHMIDWIDTH, 1162 .type = USB_MIXER_U8, 1163 .num_channels = 16, 1164 .name = "EQ MidHigh Q", 1165 }, 1166 { /* EQ high gain */ 1167 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1168 .control_id = SND_US16X08_ID_EQHIGHLEVEL, 1169 .type = USB_MIXER_U8, 1170 .num_channels = 16, 1171 .name = "EQ High Volume", 1172 }, 1173 { /* EQ low freq */ 1174 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl, 1175 .control_id = SND_US16X08_ID_EQHIGHFREQ, 1176 .type = USB_MIXER_U8, 1177 .num_channels = 16, 1178 .name = "EQ High Frequence", 1179 }, 1180 }; 1181 1182 /* table of compressor controls */ 1183 static const struct snd_us16x08_control_params comp_controls[] = { 1184 { /* Comp enable */ 1185 .kcontrol_new = &snd_us16x08_compswitch_ctl, 1186 .control_id = SND_US16X08_ID_COMP_SWITCH, 1187 .type = USB_MIXER_BOOLEAN, 1188 .num_channels = 16, 1189 .name = "Compressor Switch", 1190 }, 1191 { /* Comp threshold */ 1192 .kcontrol_new = &snd_us16x08_comp_threshold_ctl, 1193 .control_id = SND_US16X08_ID_COMP_THRESHOLD, 1194 .type = USB_MIXER_U8, 1195 .num_channels = 16, 1196 .name = "Compressor Threshold Volume", 1197 }, 1198 { /* Comp ratio */ 1199 .kcontrol_new = &snd_us16x08_comp_ratio_ctl, 1200 .control_id = SND_US16X08_ID_COMP_RATIO, 1201 .type = USB_MIXER_U8, 1202 .num_channels = 16, 1203 .name = "Compressor Ratio", 1204 }, 1205 { /* Comp attack */ 1206 .kcontrol_new = &snd_us16x08_comp_attack_ctl, 1207 .control_id = SND_US16X08_ID_COMP_ATTACK, 1208 .type = USB_MIXER_U8, 1209 .num_channels = 16, 1210 .name = "Compressor Attack", 1211 }, 1212 { /* Comp release */ 1213 .kcontrol_new = &snd_us16x08_comp_release_ctl, 1214 .control_id = SND_US16X08_ID_COMP_RELEASE, 1215 .type = USB_MIXER_U8, 1216 .num_channels = 16, 1217 .name = "Compressor Release", 1218 }, 1219 { /* Comp gain */ 1220 .kcontrol_new = &snd_us16x08_comp_gain_ctl, 1221 .control_id = SND_US16X08_ID_COMP_GAIN, 1222 .type = USB_MIXER_U8, 1223 .num_channels = 16, 1224 .name = "Compressor Volume", 1225 }, 1226 }; 1227 1228 /* table of channel controls */ 1229 static const struct snd_us16x08_control_params channel_controls[] = { 1230 { /* Phase */ 1231 .kcontrol_new = &snd_us16x08_ch_boolean_ctl, 1232 .control_id = SND_US16X08_ID_PHASE, 1233 .type = USB_MIXER_BOOLEAN, 1234 .num_channels = 16, 1235 .name = "Phase Switch", 1236 .default_val = 0 1237 }, 1238 { /* Fader */ 1239 .kcontrol_new = &snd_us16x08_ch_int_ctl, 1240 .control_id = SND_US16X08_ID_FADER, 1241 .type = USB_MIXER_U8, 1242 .num_channels = 16, 1243 .name = "Line Volume", 1244 .default_val = 127 1245 }, 1246 { /* Mute */ 1247 .kcontrol_new = &snd_us16x08_ch_boolean_ctl, 1248 .control_id = SND_US16X08_ID_MUTE, 1249 .type = USB_MIXER_BOOLEAN, 1250 .num_channels = 16, 1251 .name = "Mute Switch", 1252 .default_val = 0 1253 }, 1254 { /* Pan */ 1255 .kcontrol_new = &snd_us16x08_pan_int_ctl, 1256 .control_id = SND_US16X08_ID_PAN, 1257 .type = USB_MIXER_U16, 1258 .num_channels = 16, 1259 .name = "Pan Left-Right Volume", 1260 .default_val = 127 1261 }, 1262 }; 1263 1264 /* table of master controls */ 1265 static const struct snd_us16x08_control_params master_controls[] = { 1266 { /* Master */ 1267 .kcontrol_new = &snd_us16x08_master_ctl, 1268 .control_id = SND_US16X08_ID_FADER, 1269 .type = USB_MIXER_U8, 1270 .num_channels = 16, 1271 .name = "Master Volume", 1272 .default_val = 127 1273 }, 1274 { /* Bypass */ 1275 .kcontrol_new = &snd_us16x08_bus_ctl, 1276 .control_id = SND_US16X08_ID_BYPASS, 1277 .type = USB_MIXER_BOOLEAN, 1278 .num_channels = 16, 1279 .name = "DSP Bypass Switch", 1280 .default_val = 0 1281 }, 1282 { /* Buss out */ 1283 .kcontrol_new = &snd_us16x08_bus_ctl, 1284 .control_id = SND_US16X08_ID_BUSS_OUT, 1285 .type = USB_MIXER_BOOLEAN, 1286 .num_channels = 16, 1287 .name = "Buss Out Switch", 1288 .default_val = 0 1289 }, 1290 { /* Master mute */ 1291 .kcontrol_new = &snd_us16x08_bus_ctl, 1292 .control_id = SND_US16X08_ID_MUTE, 1293 .type = USB_MIXER_BOOLEAN, 1294 .num_channels = 16, 1295 .name = "Master Mute Switch", 1296 .default_val = 0 1297 }, 1298 1299 }; 1300 1301 int snd_us16x08_controls_create(struct usb_mixer_interface *mixer) 1302 { 1303 int i, j; 1304 int err; 1305 struct usb_mixer_elem_info *elem; 1306 struct snd_us16x08_comp_store *comp_store; 1307 struct snd_us16x08_meter_store *meter_store; 1308 struct snd_us16x08_eq_store *eq_store; 1309 1310 /* just check for non-MIDI interface */ 1311 if (mixer->hostif->desc.bInterfaceNumber == 3) { 1312 1313 /* add routing control */ 1314 err = add_new_ctl(mixer, &snd_us16x08_route_ctl, 1315 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route", 1316 NULL, false, &elem); 1317 if (err < 0) { 1318 usb_audio_dbg(mixer->chip, 1319 "Failed to create route control, err:%d\n", 1320 err); 1321 return err; 1322 } 1323 for (i = 0; i < 8; i++) 1324 elem->cache_val[i] = i < 2 ? i : i + 2; 1325 elem->cached = 0xff; 1326 1327 /* create compressor mixer elements */ 1328 comp_store = snd_us16x08_create_comp_store(); 1329 if (!comp_store) 1330 return -ENOMEM; 1331 1332 /* add master controls */ 1333 for (i = 0; i < ARRAY_SIZE(master_controls); i++) { 1334 1335 err = add_new_ctl(mixer, 1336 master_controls[i].kcontrol_new, 1337 master_controls[i].control_id, 1338 master_controls[i].type, 1339 master_controls[i].num_channels, 1340 master_controls[i].name, 1341 comp_store, 1342 i == 0, /* release comp_store only once */ 1343 &elem); 1344 if (err < 0) 1345 return err; 1346 elem->cache_val[0] = master_controls[i].default_val; 1347 elem->cached = 1; 1348 } 1349 1350 /* add channel controls */ 1351 for (i = 0; i < ARRAY_SIZE(channel_controls); i++) { 1352 1353 err = add_new_ctl(mixer, 1354 channel_controls[i].kcontrol_new, 1355 channel_controls[i].control_id, 1356 channel_controls[i].type, 1357 channel_controls[i].num_channels, 1358 channel_controls[i].name, 1359 comp_store, 1360 false, &elem); 1361 if (err < 0) 1362 return err; 1363 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) { 1364 elem->cache_val[j] = 1365 channel_controls[i].default_val; 1366 } 1367 elem->cached = 0xffff; 1368 } 1369 1370 /* create eq store */ 1371 eq_store = snd_us16x08_create_eq_store(); 1372 if (!eq_store) 1373 return -ENOMEM; 1374 1375 /* add EQ controls */ 1376 for (i = 0; i < ARRAY_SIZE(eq_controls); i++) { 1377 1378 err = add_new_ctl(mixer, 1379 eq_controls[i].kcontrol_new, 1380 eq_controls[i].control_id, 1381 eq_controls[i].type, 1382 eq_controls[i].num_channels, 1383 eq_controls[i].name, 1384 eq_store, 1385 i == 0, /* release eq_store only once */ 1386 NULL); 1387 if (err < 0) 1388 return err; 1389 } 1390 1391 /* add compressor controls */ 1392 for (i = 0; i < ARRAY_SIZE(comp_controls); i++) { 1393 1394 err = add_new_ctl(mixer, 1395 comp_controls[i].kcontrol_new, 1396 comp_controls[i].control_id, 1397 comp_controls[i].type, 1398 comp_controls[i].num_channels, 1399 comp_controls[i].name, 1400 comp_store, 1401 false, NULL); 1402 if (err < 0) 1403 return err; 1404 } 1405 1406 /* create meters store */ 1407 meter_store = snd_us16x08_create_meter_store(); 1408 if (!meter_store) 1409 return -ENOMEM; 1410 1411 /* meter function 'get' must access to compressor store 1412 * so place a reference here 1413 */ 1414 meter_store->comp_store = comp_store; 1415 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl, 1416 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter", 1417 meter_store, true, NULL); 1418 if (err < 0) 1419 return err; 1420 } 1421 1422 return 0; 1423 } 1424 1425