This source file includes following definitions.
- scarlett_ctl_switch_info
- scarlett_ctl_switch_get
- scarlett_ctl_switch_put
- scarlett_ctl_resume
- scarlett_ctl_info
- scarlett_ctl_get
- scarlett_ctl_put
- scarlett_generate_name
- scarlett_ctl_enum_dynamic_info
- scarlett_ctl_enum_info
- scarlett_ctl_enum_get
- scarlett_ctl_enum_put
- scarlett_ctl_enum_resume
- scarlett_ctl_meter_get
- add_new_ctl
- add_output_ctls
- scarlett_controls_create_generic
- snd_scarlett_controls_create
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 
  60 
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 
 102 
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 #include <linux/slab.h>
 121 #include <linux/usb.h>
 122 #include <linux/usb/audio-v2.h>
 123 
 124 #include <sound/core.h>
 125 #include <sound/control.h>
 126 #include <sound/tlv.h>
 127 
 128 #include "usbaudio.h"
 129 #include "mixer.h"
 130 #include "helper.h"
 131 #include "power.h"
 132 
 133 #include "mixer_scarlett.h"
 134 
 135 
 136 #define SND_SCARLETT_LEVEL_BIAS 128
 137 #define SND_SCARLETT_MATRIX_IN_MAX 18
 138 #define SND_SCARLETT_CONTROLS_MAX 10
 139 #define SND_SCARLETT_OFFSETS_MAX 5
 140 
 141 enum {
 142         SCARLETT_OUTPUTS,
 143         SCARLETT_SWITCH_IMPEDANCE,
 144         SCARLETT_SWITCH_PAD,
 145 };
 146 
 147 enum {
 148         SCARLETT_OFFSET_PCM = 0,
 149         SCARLETT_OFFSET_ANALOG = 1,
 150         SCARLETT_OFFSET_SPDIF = 2,
 151         SCARLETT_OFFSET_ADAT = 3,
 152         SCARLETT_OFFSET_MIX = 4,
 153 };
 154 
 155 struct scarlett_mixer_elem_enum_info {
 156         int start;
 157         int len;
 158         int offsets[SND_SCARLETT_OFFSETS_MAX];
 159         char const * const *names;
 160 };
 161 
 162 struct scarlett_mixer_control {
 163         unsigned char num;
 164         unsigned char type;
 165         const char *name;
 166 };
 167 
 168 struct scarlett_device_info {
 169         int matrix_in;
 170         int matrix_out;
 171         int input_len;
 172         int output_len;
 173 
 174         struct scarlett_mixer_elem_enum_info opt_master;
 175         struct scarlett_mixer_elem_enum_info opt_matrix;
 176 
 177         
 178         int matrix_mux_init[SND_SCARLETT_MATRIX_IN_MAX];
 179 
 180         int num_controls;       
 181         const struct scarlett_mixer_control controls[SND_SCARLETT_CONTROLS_MAX];
 182 };
 183 
 184 
 185 
 186 static const struct scarlett_mixer_elem_enum_info opt_pad = {
 187         .start = 0,
 188         .len = 2,
 189         .offsets = {},
 190         .names = (char const * const []){
 191                 "0dB", "-10dB"
 192         }
 193 };
 194 
 195 static const struct scarlett_mixer_elem_enum_info opt_impedance = {
 196         .start = 0,
 197         .len = 2,
 198         .offsets = {},
 199         .names = (char const * const []){
 200                 "Line", "Hi-Z"
 201         }
 202 };
 203 
 204 static const struct scarlett_mixer_elem_enum_info opt_clock = {
 205         .start = 1,
 206         .len = 3,
 207         .offsets = {},
 208         .names = (char const * const []){
 209                 "Internal", "SPDIF", "ADAT"
 210         }
 211 };
 212 
 213 static const struct scarlett_mixer_elem_enum_info opt_sync = {
 214         .start = 0,
 215         .len = 2,
 216         .offsets = {},
 217         .names = (char const * const []){
 218                 "No Lock", "Locked"
 219         }
 220 };
 221 
 222 static int scarlett_ctl_switch_info(struct snd_kcontrol *kctl,
 223                 struct snd_ctl_elem_info *uinfo)
 224 {
 225         struct usb_mixer_elem_info *elem = kctl->private_data;
 226 
 227         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 228         uinfo->count = elem->channels;
 229         uinfo->value.integer.min = 0;
 230         uinfo->value.integer.max = 1;
 231         return 0;
 232 }
 233 
 234 static int scarlett_ctl_switch_get(struct snd_kcontrol *kctl,
 235                 struct snd_ctl_elem_value *ucontrol)
 236 {
 237         struct usb_mixer_elem_info *elem = kctl->private_data;
 238         int i, err, val;
 239 
 240         for (i = 0; i < elem->channels; i++) {
 241                 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
 242                 if (err < 0)
 243                         return err;
 244 
 245                 val = !val; 
 246                 ucontrol->value.integer.value[i] = val;
 247         }
 248 
 249         return 0;
 250 }
 251 
 252 static int scarlett_ctl_switch_put(struct snd_kcontrol *kctl,
 253                 struct snd_ctl_elem_value *ucontrol)
 254 {
 255         struct usb_mixer_elem_info *elem = kctl->private_data;
 256         int i, changed = 0;
 257         int err, oval, val;
 258 
 259         for (i = 0; i < elem->channels; i++) {
 260                 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
 261                 if (err < 0)
 262                         return err;
 263 
 264                 val = ucontrol->value.integer.value[i];
 265                 val = !val;
 266                 if (oval != val) {
 267                         err = snd_usb_set_cur_mix_value(elem, i, i, val);
 268                         if (err < 0)
 269                                 return err;
 270 
 271                         changed = 1;
 272                 }
 273         }
 274 
 275         return changed;
 276 }
 277 
 278 static int scarlett_ctl_resume(struct usb_mixer_elem_list *list)
 279 {
 280         struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
 281         int i;
 282 
 283         for (i = 0; i < elem->channels; i++)
 284                 if (elem->cached & (1 << i))
 285                         snd_usb_set_cur_mix_value(elem, i, i,
 286                                                   elem->cache_val[i]);
 287         return 0;
 288 }
 289 
 290 static int scarlett_ctl_info(struct snd_kcontrol *kctl,
 291                              struct snd_ctl_elem_info *uinfo)
 292 {
 293         struct usb_mixer_elem_info *elem = kctl->private_data;
 294 
 295         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 296         uinfo->count = elem->channels;
 297         uinfo->value.integer.min = 0;
 298         uinfo->value.integer.max = (int)kctl->private_value +
 299                 SND_SCARLETT_LEVEL_BIAS;
 300         uinfo->value.integer.step = 1;
 301         return 0;
 302 }
 303 
 304 static int scarlett_ctl_get(struct snd_kcontrol *kctl,
 305                             struct snd_ctl_elem_value *ucontrol)
 306 {
 307         struct usb_mixer_elem_info *elem = kctl->private_data;
 308         int i, err, val;
 309 
 310         for (i = 0; i < elem->channels; i++) {
 311                 err = snd_usb_get_cur_mix_value(elem, i, i, &val);
 312                 if (err < 0)
 313                         return err;
 314 
 315                 val = clamp(val / 256, -128, (int)kctl->private_value) +
 316                                     SND_SCARLETT_LEVEL_BIAS;
 317                 ucontrol->value.integer.value[i] = val;
 318         }
 319 
 320         return 0;
 321 }
 322 
 323 static int scarlett_ctl_put(struct snd_kcontrol *kctl,
 324                             struct snd_ctl_elem_value *ucontrol)
 325 {
 326         struct usb_mixer_elem_info *elem = kctl->private_data;
 327         int i, changed = 0;
 328         int err, oval, val;
 329 
 330         for (i = 0; i < elem->channels; i++) {
 331                 err = snd_usb_get_cur_mix_value(elem, i, i, &oval);
 332                 if (err < 0)
 333                         return err;
 334 
 335                 val = ucontrol->value.integer.value[i] -
 336                         SND_SCARLETT_LEVEL_BIAS;
 337                 val = val * 256;
 338                 if (oval != val) {
 339                         err = snd_usb_set_cur_mix_value(elem, i, i, val);
 340                         if (err < 0)
 341                                 return err;
 342 
 343                         changed = 1;
 344                 }
 345         }
 346 
 347         return changed;
 348 }
 349 
 350 static void scarlett_generate_name(int i, char *dst, int offsets[])
 351 {
 352         if (i > offsets[SCARLETT_OFFSET_MIX])
 353                 sprintf(dst, "Mix %c",
 354                         'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
 355         else if (i > offsets[SCARLETT_OFFSET_ADAT])
 356                 sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
 357         else if (i > offsets[SCARLETT_OFFSET_SPDIF])
 358                 sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
 359         else if (i > offsets[SCARLETT_OFFSET_ANALOG])
 360                 sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
 361         else if (i > offsets[SCARLETT_OFFSET_PCM])
 362                 sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
 363         else
 364                 sprintf(dst, "Off");
 365 }
 366 
 367 static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
 368                                           struct snd_ctl_elem_info *uinfo)
 369 {
 370         struct usb_mixer_elem_info *elem = kctl->private_data;
 371         struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
 372         unsigned int items = opt->len;
 373 
 374         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 375         uinfo->count = elem->channels;
 376         uinfo->value.enumerated.items = items;
 377 
 378         if (uinfo->value.enumerated.item >= items)
 379                 uinfo->value.enumerated.item = items - 1;
 380 
 381         
 382         scarlett_generate_name(uinfo->value.enumerated.item,
 383                                uinfo->value.enumerated.name,
 384                                opt->offsets);
 385 
 386         return 0;
 387 }
 388 
 389 static int scarlett_ctl_enum_info(struct snd_kcontrol *kctl,
 390                                   struct snd_ctl_elem_info *uinfo)
 391 {
 392         struct usb_mixer_elem_info *elem = kctl->private_data;
 393         struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
 394 
 395         return snd_ctl_enum_info(uinfo, elem->channels, opt->len,
 396                                  (const char * const *)opt->names);
 397 }
 398 
 399 static int scarlett_ctl_enum_get(struct snd_kcontrol *kctl,
 400                                  struct snd_ctl_elem_value *ucontrol)
 401 {
 402         struct usb_mixer_elem_info *elem = kctl->private_data;
 403         struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
 404         int err, val;
 405 
 406         err = snd_usb_get_cur_mix_value(elem, 0, 0, &val);
 407         if (err < 0)
 408                 return err;
 409 
 410         val = clamp(val - opt->start, 0, opt->len-1);
 411 
 412         ucontrol->value.enumerated.item[0] = val;
 413 
 414         return 0;
 415 }
 416 
 417 static int scarlett_ctl_enum_put(struct snd_kcontrol *kctl,
 418                                  struct snd_ctl_elem_value *ucontrol)
 419 {
 420         struct usb_mixer_elem_info *elem = kctl->private_data;
 421         struct scarlett_mixer_elem_enum_info *opt = elem->private_data;
 422         int err, oval, val;
 423 
 424         err = snd_usb_get_cur_mix_value(elem, 0, 0, &oval);
 425         if (err < 0)
 426                 return err;
 427 
 428         val = ucontrol->value.integer.value[0];
 429         val = val + opt->start;
 430         if (val != oval) {
 431                 snd_usb_set_cur_mix_value(elem, 0, 0, val);
 432                 return 1;
 433         }
 434         return 0;
 435 }
 436 
 437 static int scarlett_ctl_enum_resume(struct usb_mixer_elem_list *list)
 438 {
 439         struct usb_mixer_elem_info *elem = mixer_elem_list_to_info(list);
 440 
 441         if (elem->cached)
 442                 snd_usb_set_cur_mix_value(elem, 0, 0, *elem->cache_val);
 443         return 0;
 444 }
 445 
 446 static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
 447                                   struct snd_ctl_elem_value *ucontrol)
 448 {
 449         struct usb_mixer_elem_info *elem = kctl->private_data;
 450         struct snd_usb_audio *chip = elem->head.mixer->chip;
 451         unsigned char buf[2 * MAX_CHANNELS] = {0, };
 452         int wValue = (elem->control << 8) | elem->idx_off;
 453         int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
 454         int err;
 455 
 456         err = snd_usb_ctl_msg(chip->dev,
 457                                 usb_rcvctrlpipe(chip->dev, 0),
 458                                 UAC2_CS_MEM,
 459                                 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
 460                                 USB_DIR_IN, wValue, idx, buf, elem->channels);
 461         if (err < 0)
 462                 return err;
 463 
 464         ucontrol->value.enumerated.item[0] = clamp((int)buf[0], 0, 1);
 465         return 0;
 466 }
 467 
 468 static const struct snd_kcontrol_new usb_scarlett_ctl_switch = {
 469         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 470         .name = "",
 471         .info = scarlett_ctl_switch_info,
 472         .get =  scarlett_ctl_switch_get,
 473         .put =  scarlett_ctl_switch_put,
 474 };
 475 
 476 static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0);
 477 
 478 static const struct snd_kcontrol_new usb_scarlett_ctl = {
 479         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 480         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 481                   SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 482         .name = "",
 483         .info = scarlett_ctl_info,
 484         .get =  scarlett_ctl_get,
 485         .put =  scarlett_ctl_put,
 486         .private_value = 6,  
 487         .tlv = { .p = db_scale_scarlett_gain }
 488 };
 489 
 490 static const struct snd_kcontrol_new usb_scarlett_ctl_master = {
 491         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 492         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 493                   SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 494         .name = "",
 495         .info = scarlett_ctl_info,
 496         .get =  scarlett_ctl_get,
 497         .put =  scarlett_ctl_put,
 498         .private_value = 6,  
 499         .tlv = { .p = db_scale_scarlett_gain }
 500 };
 501 
 502 static const struct snd_kcontrol_new usb_scarlett_ctl_enum = {
 503         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 504         .name = "",
 505         .info = scarlett_ctl_enum_info,
 506         .get =  scarlett_ctl_enum_get,
 507         .put =  scarlett_ctl_enum_put,
 508 };
 509 
 510 static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = {
 511         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 512         .name = "",
 513         .info = scarlett_ctl_enum_dynamic_info,
 514         .get =  scarlett_ctl_enum_get,
 515         .put =  scarlett_ctl_enum_put,
 516 };
 517 
 518 static const struct snd_kcontrol_new usb_scarlett_ctl_sync = {
 519         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 520         .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 521         .name = "",
 522         .info = scarlett_ctl_enum_info,
 523         .get =  scarlett_ctl_meter_get,
 524 };
 525 
 526 static int add_new_ctl(struct usb_mixer_interface *mixer,
 527                        const struct snd_kcontrol_new *ncontrol,
 528                        usb_mixer_elem_resume_func_t resume,
 529                        int index, int offset, int num,
 530                        int val_type, int channels, const char *name,
 531                        const struct scarlett_mixer_elem_enum_info *opt,
 532                        struct usb_mixer_elem_info **elem_ret
 533 )
 534 {
 535         struct snd_kcontrol *kctl;
 536         struct usb_mixer_elem_info *elem;
 537         int err;
 538 
 539         elem = kzalloc(sizeof(*elem), GFP_KERNEL);
 540         if (!elem)
 541                 return -ENOMEM;
 542 
 543         elem->head.mixer = mixer;
 544         elem->head.resume = resume;
 545         elem->control = offset;
 546         elem->idx_off = num;
 547         elem->head.id = index;
 548         elem->val_type = val_type;
 549 
 550         elem->channels = channels;
 551 
 552         
 553         elem->private_data = (void *)opt;
 554 
 555         kctl = snd_ctl_new1(ncontrol, elem);
 556         if (!kctl) {
 557                 kfree(elem);
 558                 return -ENOMEM;
 559         }
 560         kctl->private_free = snd_usb_mixer_elem_free;
 561 
 562         strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
 563 
 564         err = snd_usb_mixer_add_control(&elem->head, kctl);
 565         if (err < 0)
 566                 return err;
 567 
 568         if (elem_ret)
 569                 *elem_ret = elem;
 570 
 571         return 0;
 572 }
 573 
 574 static int add_output_ctls(struct usb_mixer_interface *mixer,
 575                            int index, const char *name,
 576                            const struct scarlett_device_info *info)
 577 {
 578         int err;
 579         char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 580         struct usb_mixer_elem_info *elem;
 581 
 582         
 583         snprintf(mx, sizeof(mx), "Master %d (%s) Playback Switch",
 584                 index + 1, name);
 585         err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
 586                           scarlett_ctl_resume, 0x0a, 0x01,
 587                           2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
 588         if (err < 0)
 589                 return err;
 590 
 591         
 592         snprintf(mx, sizeof(mx), "Master %d (%s) Playback Volume",
 593                 index + 1, name);
 594         err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
 595                           scarlett_ctl_resume, 0x0a, 0x02,
 596                           2*index+1, USB_MIXER_S16, 2, mx, NULL, &elem);
 597         if (err < 0)
 598                 return err;
 599 
 600         
 601         snprintf(mx, sizeof(mx), "Master %dL (%s) Source Playback Enum",
 602                 index + 1, name);
 603         err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
 604                           scarlett_ctl_enum_resume, 0x33, 0x00,
 605                           2*index, USB_MIXER_S16, 1, mx, &info->opt_master,
 606                           &elem);
 607         if (err < 0)
 608                 return err;
 609 
 610         
 611         snprintf(mx, sizeof(mx), "Master %dR (%s) Source Playback Enum",
 612                 index + 1, name);
 613         err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
 614                           scarlett_ctl_enum_resume, 0x33, 0x00,
 615                           2*index+1, USB_MIXER_S16, 1, mx, &info->opt_master,
 616                           &elem);
 617         if (err < 0)
 618                 return err;
 619 
 620         return 0;
 621 }
 622 
 623 
 624 
 625 
 626 static struct scarlett_device_info s6i6_info = {
 627         .matrix_in = 18,
 628         .matrix_out = 8,
 629         .input_len = 6,
 630         .output_len = 6,
 631 
 632         .opt_master = {
 633                 .start = -1,
 634                 .len = 27,
 635                 .offsets = {0, 12, 16, 18, 18},
 636                 .names = NULL
 637         },
 638 
 639         .opt_matrix = {
 640                 .start = -1,
 641                 .len = 19,
 642                 .offsets = {0, 12, 16, 18, 18},
 643                 .names = NULL
 644         },
 645 
 646         .num_controls = 9,
 647         .controls = {
 648                 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
 649                 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
 650                 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
 651                 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 652                 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 653                 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 654                 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 655                 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 656                 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 657         },
 658 
 659         .matrix_mux_init = {
 660                 12, 13, 14, 15,                 
 661                 16, 17,                          
 662                 0, 1, 2, 3, 4, 5, 6, 7,     
 663                 8, 9, 10, 11
 664         }
 665 };
 666 
 667 
 668 static struct scarlett_device_info s8i6_info = {
 669         .matrix_in = 18,
 670         .matrix_out = 6,
 671         .input_len = 8,
 672         .output_len = 6,
 673 
 674         .opt_master = {
 675                 .start = -1,
 676                 .len = 25,
 677                 .offsets = {0, 12, 16, 18, 18},
 678                 .names = NULL
 679         },
 680 
 681         .opt_matrix = {
 682                 .start = -1,
 683                 .len = 19,
 684                 .offsets = {0, 12, 16, 18, 18},
 685                 .names = NULL
 686         },
 687 
 688         .num_controls = 7,
 689         .controls = {
 690                 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
 691                 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
 692                 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
 693                 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 694                 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 695                 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 696                 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 697         },
 698 
 699         .matrix_mux_init = {
 700                 12, 13, 14, 15,                 
 701                 16, 17,                          
 702                 0, 1, 2, 3, 4, 5, 6, 7,     
 703                 8, 9, 10, 11
 704         }
 705 };
 706 
 707 static struct scarlett_device_info s18i6_info = {
 708         .matrix_in = 18,
 709         .matrix_out = 6,
 710         .input_len = 18,
 711         .output_len = 6,
 712 
 713         .opt_master = {
 714                 .start = -1,
 715                 .len = 31,
 716                 .offsets = {0, 6, 14, 16, 24},
 717                 .names = NULL,
 718         },
 719 
 720         .opt_matrix = {
 721                 .start = -1,
 722                 .len = 25,
 723                 .offsets = {0, 6, 14, 16, 24},
 724                 .names = NULL,
 725         },
 726 
 727         .num_controls = 5,
 728         .controls = {
 729                 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
 730                 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone" },
 731                 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
 732                 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 733                 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 734         },
 735 
 736         .matrix_mux_init = {
 737                  6,  7,  8,  9, 10, 11, 12, 13, 
 738                 16, 17, 18, 19, 20, 21,     
 739                 14, 15,                          
 740                 0, 1                          
 741         }
 742 };
 743 
 744 static struct scarlett_device_info s18i8_info = {
 745         .matrix_in = 18,
 746         .matrix_out = 8,
 747         .input_len = 18,
 748         .output_len = 8,
 749 
 750         .opt_master = {
 751                 .start = -1,
 752                 .len = 35,
 753                 .offsets = {0, 8, 16, 18, 26},
 754                 .names = NULL
 755         },
 756 
 757         .opt_matrix = {
 758                 .start = -1,
 759                 .len = 27,
 760                 .offsets = {0, 8, 16, 18, 26},
 761                 .names = NULL
 762         },
 763 
 764         .num_controls = 10,
 765         .controls = {
 766                 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
 767                 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Headphone 1" },
 768                 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Headphone 2" },
 769                 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
 770                 { .num = 1, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 771                 { .num = 1, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 772                 { .num = 2, .type = SCARLETT_SWITCH_IMPEDANCE, .name = NULL},
 773                 { .num = 2, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 774                 { .num = 3, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 775                 { .num = 4, .type = SCARLETT_SWITCH_PAD, .name = NULL},
 776         },
 777 
 778         .matrix_mux_init = {
 779                  8,  9, 10, 11, 12, 13, 14, 15, 
 780                 18, 19, 20, 21, 22, 23,     
 781                 16, 17,                          
 782                 0, 1                          
 783         }
 784 };
 785 
 786 static struct scarlett_device_info s18i20_info = {
 787         .matrix_in = 18,
 788         .matrix_out = 8,
 789         .input_len = 18,
 790         .output_len = 20,
 791 
 792         .opt_master = {
 793                 .start = -1,
 794                 .len = 47,
 795                 .offsets = {0, 20, 28, 30, 38},
 796                 .names = NULL
 797         },
 798 
 799         .opt_matrix = {
 800                 .start = -1,
 801                 .len = 39,
 802                 .offsets = {0, 20, 28, 30, 38},
 803                 .names = NULL
 804         },
 805 
 806         .num_controls = 10,
 807         .controls = {
 808                 { .num = 0, .type = SCARLETT_OUTPUTS, .name = "Monitor" },
 809                 { .num = 1, .type = SCARLETT_OUTPUTS, .name = "Line 3/4" },
 810                 { .num = 2, .type = SCARLETT_OUTPUTS, .name = "Line 5/6" },
 811                 { .num = 3, .type = SCARLETT_OUTPUTS, .name = "Line 7/8" },
 812                 { .num = 4, .type = SCARLETT_OUTPUTS, .name = "Line 9/10" },
 813                 { .num = 5, .type = SCARLETT_OUTPUTS, .name = "SPDIF" },
 814                 { .num = 6, .type = SCARLETT_OUTPUTS, .name = "ADAT 1/2" },
 815                 { .num = 7, .type = SCARLETT_OUTPUTS, .name = "ADAT 3/4" },
 816                 { .num = 8, .type = SCARLETT_OUTPUTS, .name = "ADAT 5/6" },
 817                 { .num = 9, .type = SCARLETT_OUTPUTS, .name = "ADAT 7/8" },
 818                 
 819 
 820 
 821 
 822 
 823 
 824         },
 825 
 826         .matrix_mux_init = {
 827                 20, 21, 22, 23, 24, 25, 26, 27, 
 828                 30, 31, 32, 33, 34, 35,     
 829                 28, 29,                          
 830                 0, 1                          
 831         }
 832 };
 833 
 834 
 835 static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
 836         struct scarlett_device_info *info)
 837 {
 838         int i, err;
 839         char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 840         const struct scarlett_mixer_control *ctl;
 841         struct usb_mixer_elem_info *elem;
 842 
 843         
 844         err = add_new_ctl(mixer, &usb_scarlett_ctl_switch,
 845                           scarlett_ctl_resume, 0x0a, 0x01, 0,
 846                           USB_MIXER_S16, 1, "Master Playback Switch", NULL,
 847                           &elem);
 848         if (err < 0)
 849                 return err;
 850 
 851         err = add_new_ctl(mixer, &usb_scarlett_ctl_master,
 852                           scarlett_ctl_resume, 0x0a, 0x02, 0,
 853                           USB_MIXER_S16, 1, "Master Playback Volume", NULL,
 854                           &elem);
 855         if (err < 0)
 856                 return err;
 857 
 858         
 859         for (i = 0; i < info->num_controls; i++) {
 860                 ctl = &info->controls[i];
 861 
 862                 switch (ctl->type) {
 863                 case SCARLETT_OUTPUTS:
 864                         err = add_output_ctls(mixer, ctl->num, ctl->name, info);
 865                         if (err < 0)
 866                                 return err;
 867                         break;
 868                 case SCARLETT_SWITCH_IMPEDANCE:
 869                         sprintf(mx, "Input %d Impedance Switch", ctl->num);
 870                         err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
 871                                           scarlett_ctl_enum_resume, 0x01,
 872                                           0x09, ctl->num, USB_MIXER_S16, 1, mx,
 873                                           &opt_impedance, &elem);
 874                         if (err < 0)
 875                                 return err;
 876                         break;
 877                 case SCARLETT_SWITCH_PAD:
 878                         sprintf(mx, "Input %d Pad Switch", ctl->num);
 879                         err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
 880                                           scarlett_ctl_enum_resume, 0x01,
 881                                           0x0b, ctl->num, USB_MIXER_S16, 1, mx,
 882                                           &opt_pad, &elem);
 883                         if (err < 0)
 884                                 return err;
 885                         break;
 886                 }
 887         }
 888 
 889         return 0;
 890 }
 891 
 892 
 893 
 894 
 895 int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
 896 {
 897         int err, i, o;
 898         char mx[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 899         struct scarlett_device_info *info;
 900         struct usb_mixer_elem_info *elem;
 901         static char sample_rate_buffer[4] = { '\x80', '\xbb', '\x00', '\x00' };
 902 
 903         
 904         if (!mixer->protocol)
 905                 return 0;
 906 
 907         switch (mixer->chip->usb_id) {
 908         case USB_ID(0x1235, 0x8012):
 909                 info = &s6i6_info;
 910                 break;
 911         case USB_ID(0x1235, 0x8002):
 912                 info = &s8i6_info;
 913                 break;
 914         case USB_ID(0x1235, 0x8004):
 915                 info = &s18i6_info;
 916                 break;
 917         case USB_ID(0x1235, 0x8014):
 918                 info = &s18i8_info;
 919                 break;
 920         case USB_ID(0x1235, 0x800c):
 921                 info = &s18i20_info;
 922                 break;
 923         default: 
 924                 return -EINVAL;
 925         }
 926 
 927         
 928         err = scarlett_controls_create_generic(mixer, info);
 929         if (err < 0)
 930                 return err;
 931 
 932         
 933         for (i = 0; i < info->matrix_in; i++) {
 934                 snprintf(mx, sizeof(mx), "Matrix %02d Input Playback Route",
 935                          i+1);
 936                 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
 937                                   scarlett_ctl_enum_resume, 0x32,
 938                                   0x06, i, USB_MIXER_S16, 1, mx,
 939                                   &info->opt_matrix, &elem);
 940                 if (err < 0)
 941                         return err;
 942 
 943                 for (o = 0; o < info->matrix_out; o++) {
 944                         sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
 945                                 o+'A');
 946                         err = add_new_ctl(mixer, &usb_scarlett_ctl,
 947                                           scarlett_ctl_resume, 0x3c, 0x00,
 948                                           (i << 3) + (o & 0x07), USB_MIXER_S16,
 949                                           1, mx, NULL, &elem);
 950                         if (err < 0)
 951                                 return err;
 952 
 953                 }
 954         }
 955 
 956         for (i = 0; i < info->input_len; i++) {
 957                 snprintf(mx, sizeof(mx), "Input Source %02d Capture Route",
 958                          i+1);
 959                 err = add_new_ctl(mixer, &usb_scarlett_ctl_dynamic_enum,
 960                                   scarlett_ctl_enum_resume, 0x34,
 961                                   0x00, i, USB_MIXER_S16, 1, mx,
 962                                   &info->opt_master, &elem);
 963                 if (err < 0)
 964                         return err;
 965         }
 966 
 967         
 968         err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
 969                           scarlett_ctl_enum_resume, 0x28, 0x01, 0,
 970                           USB_MIXER_U8, 1, "Sample Clock Source",
 971                           &opt_clock, &elem);
 972         if (err < 0)
 973                 return err;
 974 
 975         
 976         err = add_new_ctl(mixer, &usb_scarlett_ctl_sync, NULL, 0x3c, 0x00, 2,
 977                           USB_MIXER_U8, 1, "Sample Clock Sync Status",
 978                           &opt_sync, &elem);
 979         if (err < 0)
 980                 return err;
 981 
 982         
 983         err = snd_usb_ctl_msg(mixer->chip->dev,
 984                 usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
 985                 USB_RECIP_INTERFACE | USB_TYPE_CLASS |
 986                 USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
 987                 (0x29 << 8), sample_rate_buffer, 4);
 988         if (err < 0)
 989                 return err;
 990 
 991         return err;
 992 }