This source file includes following definitions.
- snd_us16x08_recv_urb
- snd_us16x08_send_urb
- snd_us16x08_route_info
- snd_us16x08_route_get
- snd_us16x08_route_put
- snd_us16x08_master_info
- snd_us16x08_master_get
- snd_us16x08_master_put
- snd_us16x08_bus_put
- snd_us16x08_bus_get
- snd_us16x08_channel_get
- snd_us16x08_channel_put
- snd_us16x08_mix_info
- snd_us16x08_comp_get
- snd_us16x08_comp_put
- snd_us16x08_eqswitch_get
- snd_us16x08_eqswitch_put
- snd_us16x08_eq_get
- snd_us16x08_eq_put
- snd_us16x08_meter_info
- snd_get_meter_comp_index
- get_meter_levels_from_urb
- snd_us16x08_meter_get
- snd_us16x08_meter_put
- snd_us16x08_create_comp_store
- snd_us16x08_create_eq_store
- snd_us16x08_create_meter_store
- elem_private_free
- add_new_ctl
- snd_us16x08_controls_create
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include <linux/slab.h>
   9 #include <linux/usb.h>
  10 #include <linux/usb/audio-v2.h>
  11 
  12 #include <sound/core.h>
  13 #include <sound/control.h>
  14 
  15 #include "usbaudio.h"
  16 #include "mixer.h"
  17 #include "helper.h"
  18 
  19 #include "mixer_us16x08.h"
  20 
  21 
  22 static const char route_msg[] = {
  23         0x61,
  24         0x02,
  25         0x03, 
  26         0x62,
  27         0x02,
  28         0x01, 
  29         0x41,
  30         0x01,
  31         0x61,
  32         0x02,
  33         0x01,
  34         0x62,
  35         0x02,
  36         0x01, 
  37         0x42,
  38         0x01,
  39         0x43,
  40         0x01,
  41         0x00,
  42         0x00
  43 };
  44 
  45 static const char mix_init_msg1[] = {
  46         0x71, 0x01, 0x00, 0x00
  47 };
  48 
  49 static const char mix_init_msg2[] = {
  50         0x62, 0x02, 0x00, 0x61, 0x02, 0x04, 0xb1, 0x01, 0x00, 0x00
  51 };
  52 
  53 static const char mix_msg_in[] = {
  54         
  55         0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
  56         0x81, 
  57         0x02, 
  58         0x00, 
  59         0x00,
  60         0x00
  61 };
  62 
  63 static const char mix_msg_out[] = {
  64         
  65         0x61, 0x02, 0x02, 0x62, 0x02, 0x01,
  66         0x81, 
  67         0x02, 
  68         0x00, 
  69         0x00,
  70         0x00
  71 };
  72 
  73 static const char bypass_msg_out[] = {
  74         0x45,
  75         0x02,
  76         0x01, 
  77         0x00,
  78         0x00
  79 };
  80 
  81 static const char bus_msg_out[] = {
  82         0x44,
  83         0x02,
  84         0x01, 
  85         0x00,
  86         0x00
  87 };
  88 
  89 static const char comp_msg[] = {
  90         
  91         0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
  92         0x91,
  93         0x02,
  94         0xf0, 
  95         0x92,
  96         0x02,
  97         0x0a, 
  98         0x93,
  99         0x02,
 100         0x02, 
 101         0x94,
 102         0x02,
 103         0x01, 
 104         0x95,
 105         0x02,
 106         0x03, 
 107         0x96,
 108         0x02,
 109         0x01,
 110         0x97,
 111         0x02,
 112         0x01, 
 113         0x00,
 114         0x00
 115 };
 116 
 117 static const char eqs_msq[] = {
 118         
 119         0x61, 0x02, 0x04, 0x62, 0x02, 0x01,
 120         0x51, 
 121         0x02,
 122         0x04, 
 123         0x52,
 124         0x02,
 125         0x0c, 
 126         0x53,
 127         0x02,
 128         0x0f, 
 129         0x54,
 130         0x02,
 131         0x02, 
 132         0x55,
 133         0x02,
 134         0x01, 
 135         0x00,
 136         0x00
 137 };
 138 
 139 
 140 static const char ratio_map[] = {
 141         0x0a, 0x0b, 0x0d, 0x0f, 0x11, 0x14, 0x19, 0x1e,
 142         0x23, 0x28, 0x32, 0x3c, 0x50, 0xa0, 0xff
 143 };
 144 
 145 
 146 static const char *const route_names[] = {
 147         "Master Left", "Master Right", "Output 1", "Output 2", "Output 3",
 148         "Output 4", "Output 5", "Output 6", "Output 7", "Output 8",
 149 };
 150 
 151 static int snd_us16x08_recv_urb(struct snd_usb_audio *chip,
 152         unsigned char *buf, int size)
 153 {
 154 
 155         mutex_lock(&chip->mutex);
 156         snd_usb_ctl_msg(chip->dev,
 157                 usb_rcvctrlpipe(chip->dev, 0),
 158                 SND_US16X08_URB_METER_REQUEST,
 159                 SND_US16X08_URB_METER_REQUESTTYPE, 0, 0, buf, size);
 160         mutex_unlock(&chip->mutex);
 161         return 0;
 162 }
 163 
 164 
 165 
 166 
 167 static int snd_us16x08_send_urb(struct snd_usb_audio *chip, char *buf, int size)
 168 {
 169         return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
 170                         SND_US16X08_URB_REQUEST, SND_US16X08_URB_REQUESTTYPE,
 171                         0, 0, buf, size);
 172 }
 173 
 174 static int snd_us16x08_route_info(struct snd_kcontrol *kcontrol,
 175         struct snd_ctl_elem_info *uinfo)
 176 {
 177         return snd_ctl_enum_info(uinfo, 1, 10, route_names);
 178 }
 179 
 180 static int snd_us16x08_route_get(struct snd_kcontrol *kcontrol,
 181         struct snd_ctl_elem_value *ucontrol)
 182 {
 183         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 184         int index = ucontrol->id.index;
 185 
 186         
 187         ucontrol->value.enumerated.item[0] = elem->cache_val[index];
 188 
 189         return 0;
 190 }
 191 
 192 static int snd_us16x08_route_put(struct snd_kcontrol *kcontrol,
 193         struct snd_ctl_elem_value *ucontrol)
 194 {
 195         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 196         struct snd_usb_audio *chip = elem->head.mixer->chip;
 197         int index = ucontrol->id.index;
 198         char buf[sizeof(route_msg)];
 199         int val, val_org, err;
 200 
 201         
 202         val = ucontrol->value.enumerated.item[0];
 203 
 204         
 205         if (val < 0 || val > 9)
 206                 return -EINVAL;
 207 
 208         
 209         memcpy(buf, route_msg, sizeof(route_msg));
 210 
 211         if (val < 2) {
 212                 
 213                 val_org = val;
 214                 buf[2] = 0x02;
 215         } else {
 216                 
 217                 buf[2] = 0x03;
 218                 val_org = val - 2;
 219         }
 220 
 221         
 222         buf[5] = (unsigned char) (val_org & 0x0f) + 1;
 223         
 224         buf[13] = index + 1;
 225 
 226         err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
 227 
 228         if (err > 0) {
 229                 elem->cached |= 1 << index;
 230                 elem->cache_val[index] = val;
 231         } else {
 232                 usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
 233         }
 234 
 235         return err > 0 ? 1 : 0;
 236 }
 237 
 238 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
 239         struct snd_ctl_elem_info *uinfo)
 240 {
 241         uinfo->count = 1;
 242         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 243         uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
 244         uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
 245         uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
 246         return 0;
 247 }
 248 
 249 static int snd_us16x08_master_get(struct snd_kcontrol *kcontrol,
 250         struct snd_ctl_elem_value *ucontrol)
 251 {
 252         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 253         int index = ucontrol->id.index;
 254 
 255         ucontrol->value.integer.value[0] = elem->cache_val[index];
 256 
 257         return 0;
 258 }
 259 
 260 static int snd_us16x08_master_put(struct snd_kcontrol *kcontrol,
 261         struct snd_ctl_elem_value *ucontrol)
 262 {
 263         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 264         struct snd_usb_audio *chip = elem->head.mixer->chip;
 265         char buf[sizeof(mix_msg_out)];
 266         int val, err;
 267         int index = ucontrol->id.index;
 268 
 269         
 270         val = ucontrol->value.integer.value[0];
 271 
 272         
 273         if (val < SND_US16X08_KCMIN(kcontrol)
 274                 || val > SND_US16X08_KCMAX(kcontrol))
 275                 return -EINVAL;
 276 
 277         
 278         memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
 279 
 280         buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
 281         buf[6] = elem->head.id;
 282 
 283         
 284         buf[5] = index + 1;
 285         err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
 286 
 287         if (err > 0) {
 288                 elem->cached |= 1 << index;
 289                 elem->cache_val[index] = val;
 290         } else {
 291                 usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
 292         }
 293 
 294         return err > 0 ? 1 : 0;
 295 }
 296 
 297 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
 298         struct snd_ctl_elem_value *ucontrol)
 299 {
 300         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 301         struct snd_usb_audio *chip = elem->head.mixer->chip;
 302         char buf[sizeof(mix_msg_out)];
 303         int val, err = 0;
 304 
 305         val = ucontrol->value.integer.value[0];
 306 
 307         
 308         switch (elem->head.id) {
 309         case SND_US16X08_ID_BYPASS:
 310                 memcpy(buf, bypass_msg_out, sizeof(bypass_msg_out));
 311                 buf[2] = val;
 312                 err = snd_us16x08_send_urb(chip, buf, sizeof(bypass_msg_out));
 313                 break;
 314         case SND_US16X08_ID_BUSS_OUT:
 315                 memcpy(buf, bus_msg_out, sizeof(bus_msg_out));
 316                 buf[2] = val;
 317                 err = snd_us16x08_send_urb(chip, buf, sizeof(bus_msg_out));
 318                 break;
 319         case SND_US16X08_ID_MUTE:
 320                 memcpy(buf, mix_msg_out, sizeof(mix_msg_out));
 321                 buf[8] = val;
 322                 buf[6] = elem->head.id;
 323                 buf[5] = 1;
 324                 err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
 325                 break;
 326         }
 327 
 328         if (err > 0) {
 329                 elem->cached |= 1;
 330                 elem->cache_val[0] = val;
 331         } else {
 332                 usb_audio_dbg(chip, "Failed to set buss param, err:%d\n", err);
 333         }
 334 
 335         return err > 0 ? 1 : 0;
 336 }
 337 
 338 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
 339         struct snd_ctl_elem_value *ucontrol)
 340 {
 341         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 342 
 343         switch (elem->head.id) {
 344         case SND_US16X08_ID_BUSS_OUT:
 345                 ucontrol->value.integer.value[0] = elem->cache_val[0];
 346                 break;
 347         case SND_US16X08_ID_BYPASS:
 348                 ucontrol->value.integer.value[0] = elem->cache_val[0];
 349                 break;
 350         case SND_US16X08_ID_MUTE:
 351                 ucontrol->value.integer.value[0] = elem->cache_val[0];
 352                 break;
 353         }
 354 
 355         return 0;
 356 }
 357 
 358 
 359 static int snd_us16x08_channel_get(struct snd_kcontrol *kcontrol,
 360         struct snd_ctl_elem_value *ucontrol)
 361 {
 362         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 363         int index = ucontrol->id.index;
 364 
 365         ucontrol->value.integer.value[0] = elem->cache_val[index];
 366 
 367         return 0;
 368 }
 369 
 370 static int snd_us16x08_channel_put(struct snd_kcontrol *kcontrol,
 371         struct snd_ctl_elem_value *ucontrol)
 372 {
 373         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 374         struct snd_usb_audio *chip = elem->head.mixer->chip;
 375         char buf[sizeof(mix_msg_in)];
 376         int val, err;
 377         int index = ucontrol->id.index;
 378 
 379         val = ucontrol->value.integer.value[0];
 380 
 381         
 382         if (val < SND_US16X08_KCMIN(kcontrol)
 383                 || val > SND_US16X08_KCMAX(kcontrol))
 384                 return -EINVAL;
 385 
 386         
 387         memcpy(buf, mix_msg_in, sizeof(mix_msg_in));
 388 
 389         
 390         buf[8] = val - SND_US16X08_KCBIAS(kcontrol);
 391         buf[6] = elem->head.id;
 392         buf[5] = index + 1;
 393 
 394         err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
 395 
 396         if (err > 0) {
 397                 elem->cached |= 1 << index;
 398                 elem->cache_val[index] = val;
 399         } else {
 400                 usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
 401         }
 402 
 403         return err > 0 ? 1 : 0;
 404 }
 405 
 406 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
 407         struct snd_ctl_elem_info *uinfo)
 408 {
 409         uinfo->count = 1;
 410         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 411         uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol);
 412         uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol);
 413         uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol);
 414         return 0;
 415 }
 416 
 417 static int snd_us16x08_comp_get(struct snd_kcontrol *kcontrol,
 418         struct snd_ctl_elem_value *ucontrol)
 419 {
 420         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 421         struct snd_us16x08_comp_store *store = elem->private_data;
 422         int index = ucontrol->id.index;
 423         int val_idx = COMP_STORE_IDX(elem->head.id);
 424 
 425         ucontrol->value.integer.value[0] = store->val[val_idx][index];
 426 
 427         return 0;
 428 }
 429 
 430 static int snd_us16x08_comp_put(struct snd_kcontrol *kcontrol,
 431         struct snd_ctl_elem_value *ucontrol)
 432 {
 433         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 434         struct snd_usb_audio *chip = elem->head.mixer->chip;
 435         struct snd_us16x08_comp_store *store = elem->private_data;
 436         int index = ucontrol->id.index;
 437         char buf[sizeof(comp_msg)];
 438         int val_idx, val;
 439         int err;
 440 
 441         val = ucontrol->value.integer.value[0];
 442 
 443         
 444         if (val < SND_US16X08_KCMIN(kcontrol)
 445                 || val > SND_US16X08_KCMAX(kcontrol))
 446                 return -EINVAL;
 447 
 448         
 449         val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
 450 
 451         store->val[val_idx][index] = ucontrol->value.integer.value[0];
 452 
 453         
 454         memcpy(buf, comp_msg, sizeof(comp_msg));
 455 
 456         
 457         buf[8] = store->val[
 458                 COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
 459                 - SND_US16X08_COMP_THRESHOLD_BIAS;
 460         buf[11] = ratio_map[store->val[
 461                 COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
 462         buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
 463                 + SND_US16X08_COMP_ATTACK_BIAS;
 464         buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
 465                 + SND_US16X08_COMP_RELEASE_BIAS;
 466         buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
 467         buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
 468 
 469         
 470         buf[5] = index + 1;
 471 
 472         err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
 473 
 474         if (err > 0) {
 475                 elem->cached |= 1 << index;
 476                 elem->cache_val[index] = val;
 477         } else {
 478                 usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
 479         }
 480 
 481         return 1;
 482 }
 483 
 484 static int snd_us16x08_eqswitch_get(struct snd_kcontrol *kcontrol,
 485         struct snd_ctl_elem_value *ucontrol)
 486 {
 487         int val;
 488         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 489         struct snd_us16x08_eq_store *store = elem->private_data;
 490         int index = ucontrol->id.index;
 491 
 492         
 493         val = store->val[EQ_STORE_BAND_IDX(elem->head.id)]
 494                 [EQ_STORE_PARAM_IDX(elem->head.id)][index];
 495         ucontrol->value.integer.value[0] = val;
 496 
 497         return 0;
 498 }
 499 
 500 static int snd_us16x08_eqswitch_put(struct snd_kcontrol *kcontrol,
 501         struct snd_ctl_elem_value *ucontrol)
 502 {
 503         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 504         struct snd_usb_audio *chip = elem->head.mixer->chip;
 505         struct snd_us16x08_eq_store *store = elem->private_data;
 506         int index = ucontrol->id.index;
 507         char buf[sizeof(eqs_msq)];
 508         int val, err = 0;
 509         int b_idx;
 510 
 511         
 512         val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol);
 513 
 514         
 515         memcpy(buf, eqs_msq, sizeof(eqs_msq));
 516 
 517         
 518         buf[5] = index + 1;
 519         for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
 520                 
 521                 buf[20] = val;
 522                 buf[17] = store->val[b_idx][2][index];
 523                 buf[14] = store->val[b_idx][1][index];
 524                 buf[11] = store->val[b_idx][0][index];
 525                 buf[8] = b_idx + 1;
 526                 err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
 527                 if (err < 0)
 528                         break;
 529                 store->val[b_idx][3][index] = val;
 530                 msleep(15);
 531         }
 532 
 533         if (err > 0) {
 534                 elem->cached |= 1 << index;
 535                 elem->cache_val[index] = val;
 536         } else {
 537                 usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
 538         }
 539 
 540         return 1;
 541 }
 542 
 543 static int snd_us16x08_eq_get(struct snd_kcontrol *kcontrol,
 544         struct snd_ctl_elem_value *ucontrol)
 545 {
 546         int val;
 547         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 548         struct snd_us16x08_eq_store *store = elem->private_data;
 549         int index = ucontrol->id.index;
 550         int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
 551         int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
 552 
 553         val = store->val[b_idx][p_idx][index];
 554 
 555         ucontrol->value.integer.value[0] = val;
 556 
 557         return 0;
 558 }
 559 
 560 static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
 561         struct snd_ctl_elem_value *ucontrol)
 562 {
 563         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 564         struct snd_usb_audio *chip = elem->head.mixer->chip;
 565         struct snd_us16x08_eq_store *store = elem->private_data;
 566         int index = ucontrol->id.index;
 567         char buf[sizeof(eqs_msq)];
 568         int val, err;
 569         int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1;
 570         int p_idx = EQ_STORE_PARAM_IDX(elem->head.id);
 571 
 572         val = ucontrol->value.integer.value[0];
 573 
 574         
 575         if (val < SND_US16X08_KCMIN(kcontrol)
 576                 || val > SND_US16X08_KCMAX(kcontrol))
 577                 return -EINVAL;
 578 
 579         
 580         memcpy(buf, eqs_msq, sizeof(eqs_msq));
 581 
 582         store->val[b_idx][p_idx][index] = val;
 583         buf[20] = store->val[b_idx][3][index];
 584         buf[17] = store->val[b_idx][2][index];
 585         buf[14] = store->val[b_idx][1][index];
 586         buf[11] = store->val[b_idx][0][index];
 587 
 588         
 589         buf[5] = index + 1;
 590 
 591         
 592         buf[8] = b_idx + 1;
 593 
 594         err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
 595 
 596         if (err > 0) {
 597                 
 598                 elem->cached |= 1 << index;
 599                 elem->cache_val[index] = val;
 600         } else {
 601                 usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
 602         }
 603 
 604         return 1;
 605 }
 606 
 607 static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
 608         struct snd_ctl_elem_info *uinfo)
 609 {
 610         uinfo->count = 1;
 611         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 612         uinfo->value.integer.max = 0x7FFF;
 613         uinfo->value.integer.min = 0;
 614 
 615         return 0;
 616 }
 617 
 618 
 619 static int snd_get_meter_comp_index(struct snd_us16x08_meter_store *store)
 620 {
 621         int ret;
 622 
 623         
 624         if (store->comp_active_index) {
 625                 
 626                 if (store->comp_active_index & 0x20) {
 627                         
 628                         if (store->comp_index -
 629                                 store->comp_active_index > 1)
 630                                 store->comp_index =
 631                                 store->comp_active_index;
 632 
 633                         ret = store->comp_index++ & 0x1F;
 634                 } else {
 635                         
 636                         ret = store->comp_active_index;
 637                 }
 638         } else {
 639                 
 640                 while (!store->comp_store->val[
 641                         COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
 642                         [store->comp_index - 1]
 643                         && store->comp_index <= SND_US16X08_MAX_CHANNELS) {
 644                         store->comp_index++;
 645                 }
 646                 ret = store->comp_index++;
 647                 if (store->comp_index > SND_US16X08_MAX_CHANNELS)
 648                         store->comp_index = 1;
 649         }
 650         return ret;
 651 }
 652 
 653 
 654 static void get_meter_levels_from_urb(int s,
 655         struct snd_us16x08_meter_store *store,
 656         u8 *meter_urb)
 657 {
 658         int val = MUC2(meter_urb, s) + (MUC3(meter_urb, s) << 8);
 659 
 660         if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
 661                 MUA2(meter_urb, s) == 0x04 && MUB0(meter_urb, s) == 0x62) {
 662                 if (MUC0(meter_urb, s) == 0x72)
 663                         store->meter_level[MUB2(meter_urb, s) - 1] = val;
 664                 if (MUC0(meter_urb, s) == 0xb2)
 665                         store->comp_level[MUB2(meter_urb, s) - 1] = val;
 666         }
 667         if (MUA0(meter_urb, s) == 0x61 && MUA1(meter_urb, s) == 0x02 &&
 668                 MUA2(meter_urb, s) == 0x02 && MUB0(meter_urb, s) == 0x62)
 669                 store->master_level[MUB2(meter_urb, s) - 1] = val;
 670 }
 671 
 672 
 673 
 674 
 675 
 676 
 677 
 678 
 679 
 680 
 681 
 682 
 683 static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
 684         struct snd_ctl_elem_value *ucontrol)
 685 {
 686         int i, set;
 687         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 688         struct snd_usb_audio *chip = elem->head.mixer->chip;
 689         struct snd_us16x08_meter_store *store = elem->private_data;
 690         u8 meter_urb[64];
 691 
 692         switch (kcontrol->private_value) {
 693         case 0: {
 694                 char tmp[sizeof(mix_init_msg1)];
 695 
 696                 memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
 697                 snd_us16x08_send_urb(chip, tmp, 4);
 698                 snd_us16x08_recv_urb(chip, meter_urb,
 699                         sizeof(meter_urb));
 700                 kcontrol->private_value++;
 701                 break;
 702         }
 703         case 1:
 704                 snd_us16x08_recv_urb(chip, meter_urb,
 705                         sizeof(meter_urb));
 706                 kcontrol->private_value++;
 707                 break;
 708         case 2:
 709                 snd_us16x08_recv_urb(chip, meter_urb,
 710                         sizeof(meter_urb));
 711                 kcontrol->private_value++;
 712                 break;
 713         case 3: {
 714                 char tmp[sizeof(mix_init_msg2)];
 715 
 716                 memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
 717                 tmp[2] = snd_get_meter_comp_index(store);
 718                 snd_us16x08_send_urb(chip, tmp, 10);
 719                 snd_us16x08_recv_urb(chip, meter_urb,
 720                         sizeof(meter_urb));
 721                 kcontrol->private_value = 0;
 722                 break;
 723         }
 724         }
 725 
 726         for (set = 0; set < 6; set++)
 727                 get_meter_levels_from_urb(set, store, meter_urb);
 728 
 729         for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
 730                 ucontrol->value.integer.value[i] =
 731                         store ? store->meter_level[i] : 0;
 732         }
 733 
 734         ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0;
 735         ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0;
 736 
 737         for (i = 2; i < SND_US16X08_MAX_CHANNELS + 2; i++)
 738                 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] =
 739                 store ? store->comp_level[i - 2] : 0;
 740 
 741         return 1;
 742 }
 743 
 744 static int snd_us16x08_meter_put(struct snd_kcontrol *kcontrol,
 745         struct snd_ctl_elem_value *ucontrol)
 746 {
 747         struct usb_mixer_elem_info *elem = kcontrol->private_data;
 748         struct snd_us16x08_meter_store *store = elem->private_data;
 749         int val;
 750 
 751         val = ucontrol->value.integer.value[0];
 752 
 753         
 754         if (val < 0 || val >= SND_US16X08_MAX_CHANNELS)
 755                 return -EINVAL;
 756 
 757         store->comp_active_index = val;
 758         store->comp_index = val;
 759 
 760         return 1;
 761 }
 762 
 763 static struct snd_kcontrol_new snd_us16x08_ch_boolean_ctl = {
 764         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 765         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 766         .count = 16,
 767         .info = snd_us16x08_switch_info,
 768         .get = snd_us16x08_channel_get,
 769         .put = snd_us16x08_channel_put,
 770         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
 771 };
 772 
 773 static struct snd_kcontrol_new snd_us16x08_ch_int_ctl = {
 774         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 775         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 776         .count = 16,
 777         .info = snd_us16x08_mix_info,
 778         .get = snd_us16x08_channel_get,
 779         .put = snd_us16x08_channel_put,
 780         .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
 781 };
 782 
 783 static struct snd_kcontrol_new snd_us16x08_pan_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, 255)
 791 };
 792 
 793 static struct snd_kcontrol_new snd_us16x08_master_ctl = {
 794         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 795         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 796         .count = 1,
 797         .info = snd_us16x08_master_info,
 798         .get = snd_us16x08_master_get,
 799         .put = snd_us16x08_master_put,
 800         .private_value = SND_US16X08_KCSET(SND_US16X08_FADER_BIAS, 1, 0, 133)
 801 };
 802 
 803 static struct snd_kcontrol_new snd_us16x08_route_ctl = {
 804         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 805         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 806         .count = 8,
 807         .info = snd_us16x08_route_info,
 808         .get = snd_us16x08_route_get,
 809         .put = snd_us16x08_route_put,
 810         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 9)
 811 };
 812 
 813 static struct snd_kcontrol_new snd_us16x08_bus_ctl = {
 814         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 815         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 816         .count = 1,
 817         .info = snd_us16x08_switch_info,
 818         .get = snd_us16x08_bus_get,
 819         .put = snd_us16x08_bus_put,
 820         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
 821 };
 822 
 823 static struct snd_kcontrol_new snd_us16x08_compswitch_ctl = {
 824         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 825         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 826         .count = 16,
 827         .info = snd_us16x08_switch_info,
 828         .get = snd_us16x08_comp_get,
 829         .put = snd_us16x08_comp_put,
 830         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
 831 };
 832 
 833 static struct snd_kcontrol_new snd_us16x08_comp_threshold_ctl = {
 834         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 835         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 836         .count = 16,
 837         .info = snd_us16x08_mix_info,
 838         .get = snd_us16x08_comp_get,
 839         .put = snd_us16x08_comp_put,
 840         .private_value = SND_US16X08_KCSET(SND_US16X08_COMP_THRESHOLD_BIAS, 1,
 841         0, 0x20)
 842 };
 843 
 844 static struct snd_kcontrol_new snd_us16x08_comp_ratio_ctl = {
 845         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 846         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 847         .count = 16,
 848         .info = snd_us16x08_mix_info,
 849         .get = snd_us16x08_comp_get,
 850         .put = snd_us16x08_comp_put,
 851         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0,
 852         sizeof(ratio_map) - 1), 
 853 };
 854 
 855 static struct snd_kcontrol_new snd_us16x08_comp_gain_ctl = {
 856         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 857         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 858         .count = 16,
 859         .info = snd_us16x08_mix_info,
 860         .get = snd_us16x08_comp_get,
 861         .put = snd_us16x08_comp_put,
 862         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 0x14)
 863 };
 864 
 865 static struct snd_kcontrol_new snd_us16x08_comp_attack_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 =
 873         SND_US16X08_KCSET(SND_US16X08_COMP_ATTACK_BIAS, 1, 0, 0xc6),
 874 };
 875 
 876 static struct snd_kcontrol_new snd_us16x08_comp_release_ctl = {
 877         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 878         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 879         .count = 16,
 880         .info = snd_us16x08_mix_info,
 881         .get = snd_us16x08_comp_get,
 882         .put = snd_us16x08_comp_put,
 883         .private_value =
 884         SND_US16X08_KCSET(SND_US16X08_COMP_RELEASE_BIAS, 1, 0, 0x63),
 885 };
 886 
 887 static struct snd_kcontrol_new snd_us16x08_eq_gain_ctl = {
 888         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 889         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 890         .count = 16,
 891         .info = snd_us16x08_mix_info,
 892         .get = snd_us16x08_eq_get,
 893         .put = snd_us16x08_eq_put,
 894         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 24),
 895 };
 896 
 897 static struct snd_kcontrol_new snd_us16x08_eq_low_freq_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, 0x1F),
 905 };
 906 
 907 static struct snd_kcontrol_new snd_us16x08_eq_mid_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, 0x3F)
 915 };
 916 
 917 static struct snd_kcontrol_new snd_us16x08_eq_mid_width_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, 0x06)
 925 };
 926 
 927 static struct snd_kcontrol_new snd_us16x08_eq_high_freq_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 =
 935         SND_US16X08_KCSET(SND_US16X08_EQ_HIGHFREQ_BIAS, 1, 0, 0x1F)
 936 };
 937 
 938 static struct snd_kcontrol_new snd_us16x08_eq_switch_ctl = {
 939         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 940         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 941         .count = 16,
 942         .info = snd_us16x08_switch_info,
 943         .get = snd_us16x08_eqswitch_get,
 944         .put = snd_us16x08_eqswitch_put,
 945         .private_value = SND_US16X08_KCSET(SND_US16X08_NO_BIAS, 1, 0, 1)
 946 };
 947 
 948 static struct snd_kcontrol_new snd_us16x08_meter_ctl = {
 949         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 950         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 951         .count = 1,
 952         .info = snd_us16x08_meter_info,
 953         .get = snd_us16x08_meter_get,
 954         .put = snd_us16x08_meter_put
 955 };
 956 
 957 
 958 
 959 
 960 static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void)
 961 {
 962         int i;
 963         struct snd_us16x08_comp_store *tmp;
 964 
 965         tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
 966         if (!tmp)
 967                 return NULL;
 968 
 969         for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
 970                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i]
 971                         = 0x20;
 972                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00;
 973                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00;
 974                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00;
 975                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00;
 976                 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00;
 977         }
 978         return tmp;
 979 }
 980 
 981 
 982 static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void)
 983 {
 984         int i, b_idx;
 985         struct snd_us16x08_eq_store *tmp;
 986 
 987         tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
 988         if (!tmp)
 989                 return NULL;
 990 
 991         for (i = 0; i < SND_US16X08_MAX_CHANNELS; i++) {
 992                 for (b_idx = 0; b_idx < SND_US16X08_ID_EQ_BAND_COUNT; b_idx++) {
 993                         tmp->val[b_idx][0][i] = 0x0c;
 994                         tmp->val[b_idx][3][i] = 0x00;
 995                         switch (b_idx) {
 996                         case 0: 
 997                                 tmp->val[b_idx][1][i] = 0x05;
 998                                 tmp->val[b_idx][2][i] = 0xff;
 999                                 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         strlcpy(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 Frequence",
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 Frequence",
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 Frequence",
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 Frequence",
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