^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * USB Audio Driver for ALSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Quirks and vendor-specific extensions for mixer interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Many codes borrowed from audio.c by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Alan Cox (alan@lxorguk.ukuu.org.uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Thomas Sailer (sailer@ife.ee.ethz.ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Audio Advantage Micro II support added by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Przemek Rudy (prudy1@o2.pl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/usb/audio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <sound/hwdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "usbaudio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "mixer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "mixer_quirks.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "mixer_scarlett.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "mixer_scarlett_gen2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "mixer_us16x08.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "mixer_s1810c.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "helper.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct std_mono_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int unitid, control, cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int val_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) snd_kcontrol_tlv_rw_t *tlv_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* This function allows for the creation of standard UAC controls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * See the quirks for M-Audio FTUs or Ebox-44.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * If you don't want to set a TLV callback pass NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Since there doesn't seem to be a devices that needs a multichannel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * version, we keep it mono for simplicity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int idx_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) snd_kcontrol_tlv_rw_t *tlv_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cval->val_type = val_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) cval->channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) cval->control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) cval->cmask = cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) cval->idx_off = idx_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* get_min_max() is called only for integer volumes later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * so provide a short-cut for booleans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cval->min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) cval->max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) cval->res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) cval->dBmin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) cval->dBmax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* Create control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) kfree(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Set name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) snprintf(kctl->id.name, sizeof(kctl->id.name), name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* set TLV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (tlv_callback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kctl->tlv.c = tlv_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) kctl->vd[0].access |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) SNDRV_CTL_ELEM_ACCESS_TLV_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Add control to mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) snd_kcontrol_tlv_rw_t *tlv_callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) val_type, 0 /* Offset */, name, tlv_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Create a set of standard UAC controls from a table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) const struct std_mono_table *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) while (t->name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) t->cmask, t->val_type, t->name, t->tlv_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) t++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) usb_mixer_elem_resume_func_t resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) const struct snd_kcontrol_new *knew,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct usb_mixer_elem_list **listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) list = kzalloc(sizeof(*list), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *listp = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) list->mixer = mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) list->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) list->resume = resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kctl = snd_ctl_new1(knew, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) kfree(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* don't use snd_usb_mixer_add_control() here, this is a special list element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return snd_usb_mixer_add_list(list, kctl, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * Sound Blaster remote control configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * format of remote control data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Extigy: xx 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Audigy 2 NX: 06 80 xx 00 00 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Live! 24-bit: 06 80 xx yy 22 83
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static const struct rc_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 usb_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 packet_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 min_packet_length; /* minimum accepted length of the URB result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u8 mute_mixer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u32 mute_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } rc_configs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { USB_ID(0x041e, 0x3237), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { USB_ID(0x041e, 0x3263), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void snd_usb_soundblaster_remote_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct usb_mixer_interface *mixer = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) const struct rc_config *rc = mixer->rc_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) code = mixer->rc_buffer[rc->offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (rc->length == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) code |= mixer->rc_buffer[rc->offset + 1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* the Mute button actually changes the mixer control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (code == rc->mute_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mixer->rc_code = code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) wake_up(&mixer->rc_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) long count, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct usb_mixer_interface *mixer = hw->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u32 rc_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (count != 1 && count != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) err = wait_event_interruptible(mixer->rc_waitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) (rc_code = xchg(&mixer->rc_code, 0)) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err = put_user(rc_code, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err = put_user(rc_code, (u32 __user *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return err < 0 ? err : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static __poll_t snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct usb_mixer_interface *mixer = hw->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) poll_wait(file, &mixer->rc_waitq, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return mixer->rc_code ? EPOLLIN | EPOLLRDNORM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct snd_hwdep *hwdep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int err, len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (rc_configs[i].usb_id == mixer->chip->usb_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (i >= ARRAY_SIZE(rc_configs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mixer->rc_cfg = &rc_configs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) len = mixer->rc_cfg->packet_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) init_waitqueue_head(&mixer->rc_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) snprintf(hwdep->name, sizeof(hwdep->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "%s remote control", mixer->chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) hwdep->private_data = mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) hwdep->ops.read = snd_usb_sbrc_hwdep_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) hwdep->exclusive = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!mixer->rc_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!mixer->rc_setup_packet) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) usb_free_urb(mixer->rc_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mixer->rc_urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mixer->rc_setup_packet->bRequestType =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mixer->rc_setup_packet->wValue = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) mixer->rc_setup_packet->wLength = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) usb_rcvctrlpipe(mixer->chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) snd_usb_soundblaster_remote_complete, mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ucontrol->value.integer.value[0] = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int value, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (chip->usb_id == USB_ID(0x041e, 0x3042))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) usb_sndctrlpipe(chip->dev, 0), 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) !value, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* USB X-Fi S51 Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (chip->usb_id == USB_ID(0x041e, 0x30df))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) usb_sndctrlpipe(chip->dev, 0), 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) !value, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) usb_sndctrlpipe(chip->dev, 0), 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) value, index + 2, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int index = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned int value = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int old_value = kcontrol->private_value >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (value == old_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) kcontrol->private_value = (value << 8) | index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) err = snd_audigy2nx_led_update(mixer, value, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int priv_value = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return snd_audigy2nx_led_update(list->mixer, priv_value >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) priv_value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* name and private_value are set dynamically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static const struct snd_kcontrol_new snd_audigy2nx_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .info = snd_audigy2nx_led_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .get = snd_audigy2nx_led_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .put = snd_audigy2nx_led_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static const char * const snd_audigy2nx_led_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) "CMSS LED Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "Power LED Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) "Dolby Digital LED Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_led_names); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct snd_kcontrol_new knew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* USB X-Fi S51 doesn't have a CMSS LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* USB X-Fi S51 Pro doesn't have one either */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (i > 1 && /* Live24ext has 2 LEDs only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) knew = snd_audigy2nx_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) knew.name = snd_audigy2nx_led_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) knew.private_value = (1 << 8) | i; /* LED on as default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) err = add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) snd_audigy2nx_led_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) &knew, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static const struct sb_jack {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int unitid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } jacks_audigy2nx[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {4, "dig in "},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {7, "line in"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {19, "spk out"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {20, "hph out"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {-1, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }, jacks_live24ext[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {4, "line in"}, /* &1=Line, &2=Mic*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {3, "hph out"}, /* headphones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {0, "RC "}, /* last command, 6 bytes see rc_config above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {-1, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) const struct sb_jack *jacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct usb_mixer_interface *mixer = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) jacks = jacks_audigy2nx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) jacks = jacks_live24ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) for (i = 0; jacks[i].name; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) snd_iprintf(buffer, "%s: ", jacks[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) err = snd_usb_lock_shutdown(mixer->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err = snd_usb_ctl_msg(mixer->chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) usb_rcvctrlpipe(mixer->chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) USB_RECIP_INTERFACE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) jacks[i].unitid << 8, buf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) snd_usb_unlock_shutdown(mixer->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (err == 3 && (buf[0] == 3 || buf[0] == 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) snd_iprintf(buffer, "?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* EMU0204 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static const char * const texts[2] = {"1/2", "3/4"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ucontrol->value.enumerated.item[0] = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) unsigned char buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) buf[0] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) buf[1] = value ? 0x02 : 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 0x0400, 0x0e00, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) unsigned int value = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (value == kcontrol->private_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) kcontrol->private_value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = snd_emu0204_ch_switch_update(mixer, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return snd_emu0204_ch_switch_update(list->mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) list->kctl->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static const struct snd_kcontrol_new snd_emu0204_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .name = "Front Jack Channels",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .info = snd_emu0204_ch_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .get = snd_emu0204_ch_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .put = snd_emu0204_ch_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) snd_emu0204_ch_switch_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) &snd_emu0204_control, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* ASUS Xonar U1 / U3 controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) unsigned char status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) usb_sndctrlpipe(chip->dev, 0), 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 50, 0, &status, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u8 old_status, new_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) old_status = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) new_status = old_status | 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) new_status = old_status & ~0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (new_status == old_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) kcontrol->private_value = new_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) err = snd_xonar_u1_switch_update(list->mixer, new_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return snd_xonar_u1_switch_update(list->mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) list->kctl->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static const struct snd_kcontrol_new snd_xonar_u1_output_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .name = "Digital Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .get = snd_xonar_u1_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .put = snd_xonar_u1_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .private_value = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) snd_xonar_u1_switch_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) &snd_xonar_u1_output_switch, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Digidesign Mbox 1 clock source switch (internal/spdif) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int snd_mbox1_switch_get(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ucontrol->value.enumerated.item[0] = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int snd_mbox1_switch_update(struct usb_mixer_interface *mixer, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) unsigned char buff[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* Prepare for magic command to toggle clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) usb_rcvctrlpipe(chip->dev, 0), 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) USB_DIR_IN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) usb_rcvctrlpipe(chip->dev, 0), 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) USB_DIR_IN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* 2 possibilities: Internal -> send sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * S/PDIF sync -> send zeroes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * NB: Sample rate locked to 48kHz on purpose to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * prevent user from resetting the sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * while S/PDIF sync is enabled and confusing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * this configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) buff[0] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) buff[1] = 0xbb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) buff[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) buff[0] = buff[1] = buff[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* Send the magic command to toggle the clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) usb_sndctrlpipe(chip->dev, 0), 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) usb_rcvctrlpipe(chip->dev, 0), 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) USB_DIR_IN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) usb_rcvctrlpipe(chip->dev, 0), 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) USB_DIR_IN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) USB_TYPE_CLASS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) bool cur_val, new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) cur_val = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) new_val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (cur_val == new_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) kctl->private_value = new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) err = snd_mbox1_switch_update(mixer, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static const char *const texts[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) "Internal",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) "S/PDIF"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static int snd_mbox1_switch_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return snd_mbox1_switch_update(list->mixer, list->kctl->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static const struct snd_kcontrol_new snd_mbox1_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) .name = "Clock Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .info = snd_mbox1_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .get = snd_mbox1_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .put = snd_mbox1_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) .private_value = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) snd_mbox1_switch_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) &snd_mbox1_switch, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Native Instruments device quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int snd_ni_control_init_val(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct usb_device *dev = mixer->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) unsigned int pval = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) (pval >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 0, pval & 0xffff, &value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) dev_err(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) "unable to issue vendor read request (ret = %d)", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) kctl->private_value |= ((unsigned int)value << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ucontrol->value.integer.value[0] = kcontrol->private_value >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned int pval = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) (pval >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) pval >> 24, pval & 0xffff, NULL, 0, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u8 oldval = (kcontrol->private_value >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) u8 newval = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (oldval == newval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) kcontrol->private_value &= ~(0xff << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) kcontrol->private_value |= (unsigned int)newval << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err = snd_ni_update_cur_val(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) .name = "Direct Thru Channel A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .name = "Direct Thru Channel B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .name = "Phono Input Channel A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .name = "Phono Input Channel B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static const struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .name = "Direct Thru Channel A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .name = "Direct Thru Channel B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .name = "Direct Thru Channel C",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .name = "Direct Thru Channel D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .name = "Phono Input Channel A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .name = "Phono Input Channel B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .name = "Phono Input Channel C",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .name = "Phono Input Channel D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) const struct snd_kcontrol_new *kc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int i, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct snd_kcontrol_new template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .get = snd_nativeinstruments_control_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .put = snd_nativeinstruments_control_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) template.name = kc[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) template.private_value = kc[i].private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) err = add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) snd_ni_update_cur_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) &template, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) snd_ni_control_init_val(mixer, list->kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* M-Audio FastTrack Ultra quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* FTU Effect switch (also used by C400/C600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static const char *const texts[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) "Room 1", "Room 2", "Room 3", "Hall 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) "Hall 2", "Plate", "Delay", "Echo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct usb_device *dev = mixer->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) unsigned int pval = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) unsigned char value[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) value[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) value[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) pval & 0xff00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) snd_usb_ctrl_intf(mixer->chip) | ((pval & 0xff) << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) value, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) kctl->private_value |= (unsigned int)value[0] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ucontrol->value.enumerated.item[0] = kctl->private_value >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) unsigned int pval = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) unsigned char value[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) value[0] = pval >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) value[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pval & 0xff00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) value, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) unsigned int pval = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) int cur_val, err, new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) cur_val = pval >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) new_val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (cur_val == new_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) kctl->private_value &= ~(0xff << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) kctl->private_value |= new_val << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) err = snd_ftu_eff_switch_update(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) int validx, int bUnitID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static struct snd_kcontrol_new template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .name = "Effect Program Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .info = snd_ftu_eff_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .get = snd_ftu_eff_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .put = snd_ftu_eff_switch_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) err = add_single_ctl_with_resume(mixer, bUnitID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) snd_ftu_eff_switch_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) &template, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) list->kctl->private_value = (validx << 8) | bUnitID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) snd_ftu_eff_switch_init(mixer, list->kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* Create volume controls for FTU devices*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) unsigned int control, cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) int in, out, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) const unsigned int id = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) for (out = 0; out < 8; out++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) control = out + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) for (in = 0; in < 8; in++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) cmask = 1 << in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) "AIn%d - Out%d Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) in + 1, out + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) err = snd_create_std_mono_ctl(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) cmask, val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) &snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) for (in = 8; in < 16; in++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) cmask = 1 << in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) "DIn%d - Out%d Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) in - 7, out + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) err = snd_create_std_mono_ctl(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) cmask, val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) &snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static const char name[] = "Effect Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) const unsigned int id = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) const int val_type = USB_MIXER_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) const unsigned int control = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) name, snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static const char name[] = "Effect Duration";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) const unsigned int id = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) const unsigned int control = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) name, snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static const char name[] = "Effect Feedback Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) const unsigned int id = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) const int val_type = USB_MIXER_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) const unsigned int control = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) unsigned int cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) int err, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) char name[48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) const unsigned int id = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) const unsigned int control = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) for (ch = 0; ch < 4; ++ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) cmask = 1 << ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) "Effect Return %d Volume", ch + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err = snd_create_std_mono_ctl(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) cmask, val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) unsigned int cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int err, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) char name[48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const unsigned int id = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) const unsigned int control = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) for (ch = 0; ch < 8; ++ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) cmask = 1 << ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) "Effect Send AIn%d Volume", ch + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) err = snd_create_std_mono_ctl(mixer, id, control, cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) for (ch = 8; ch < 16; ++ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) cmask = 1 << ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) "Effect Send DIn%d Volume", ch - 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) err = snd_create_std_mono_ctl(mixer, id, control, cmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) err = snd_ftu_create_volume_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) err = snd_ftu_create_effect_switch(mixer, 1, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) err = snd_ftu_create_effect_volume_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) err = snd_ftu_create_effect_duration_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) err = snd_ftu_create_effect_feedback_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) err = snd_ftu_create_effect_return_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) err = snd_ftu_create_effect_send_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) unsigned char samplerate_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct usb_mixer_interface *mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) int unitid = 12; /* SampleRate ExtensionUnit ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) list_for_each_entry(mixer, &chip->mixer_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (mixer->id_elems[unitid]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) cval->control << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) samplerate_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) snd_usb_mixer_notify_id(mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* M-Audio Fast Track C400/C600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /* C400/C600 volume controls, this control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) unsigned int cmask, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int out, chan, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) int num_outs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) int num_ins = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) const unsigned int id = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) const int control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) case USB_ID(0x0763, 0x2030):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) num_outs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) num_ins = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) case USB_ID(0x0763, 0x2031):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) num_outs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) num_ins = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) for (chan = 0; chan < num_outs + num_ins; chan++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) for (out = 0; out < num_outs; out++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (chan < num_outs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) "PCM%d-Out%d Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) chan + 1, out + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) "In%d-Out%d Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) chan - num_outs + 1, out + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) cmask = (out == 0) ? 0 : 1 << (out - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) offset = chan * num_outs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) err = snd_create_std_mono_ctl_offset(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) cmask, val_type, offset, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) &snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static const char name[] = "Effect Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) const unsigned int id = 0x43;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) const int val_type = USB_MIXER_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) const unsigned int control = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) name, snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) static const char name[] = "Effect Duration";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) const unsigned int id = 0x43;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) const unsigned int control = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) name, snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /* This control needs a volume quirk, see mixer.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static const char name[] = "Effect Feedback Volume";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) const unsigned int id = 0x43;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) const int val_type = USB_MIXER_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) const unsigned int control = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) const unsigned int cmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) name, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) unsigned int cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int chan, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int num_outs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) int num_ins = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) const unsigned int id = 0x42;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) const int control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) case USB_ID(0x0763, 0x2030):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) num_outs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) num_ins = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) case USB_ID(0x0763, 0x2031):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) num_outs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) num_ins = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) for (chan = 0; chan < num_outs + num_ins; chan++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (chan < num_outs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) "Effect Send DOut%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) chan + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) "Effect Send AIn%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) chan - num_outs + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) cmask = (chan == 0) ? 0 : 1 << (chan - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) err = snd_create_std_mono_ctl(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) cmask, val_type, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) &snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) char name[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) unsigned int cmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) int chan, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) int num_outs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) int offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) const unsigned int id = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) const int val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) const int control = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) case USB_ID(0x0763, 0x2030):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) num_outs = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) offset = 0x3c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case USB_ID(0x0763, 0x2031):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) num_outs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) offset = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* { 0x70, 0x79, 0x72, 0x7b, 0x74, 0x7d, 0x76, 0x7f } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) for (chan = 0; chan < num_outs; chan++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) "Effect Return %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) chan + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) cmask = (chan == 0) ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 1 << (chan + (chan % 2) * num_outs - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) err = snd_create_std_mono_ctl_offset(mixer, id, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) cmask, val_type, offset, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) &snd_usb_mixer_vol_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int snd_c400_create_mixer(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) err = snd_c400_create_vol_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) err = snd_c400_create_effect_vol_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) err = snd_c400_create_effect_ret_vol_ctls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) err = snd_ftu_create_effect_switch(mixer, 2, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) err = snd_c400_create_effect_volume_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) err = snd_c400_create_effect_duration_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) err = snd_c400_create_effect_feedback_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * The mixer units for Ebox-44 are corrupt, and even where they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * are valid they presents mono controls as L and R channels of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * stereo. So we provide a good mixer here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static const struct std_mono_table ebox44_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) .unitid = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) .control = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .cmask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) .val_type = USB_MIXER_INV_BOOLEAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) .name = "Headphone Playback Switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) .unitid = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) .cmask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .name = "Headphone A Mix Playback Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) .unitid = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .cmask = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .name = "Headphone B Mix Playback Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .unitid = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .control = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) .cmask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .val_type = USB_MIXER_INV_BOOLEAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .name = "Output Playback Switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .unitid = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .cmask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .name = "Output A Playback Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) .unitid = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) .cmask = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .name = "Output B Playback Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .unitid = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) .control = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .cmask = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .val_type = USB_MIXER_INV_BOOLEAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .name = "Input Capture Switch"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .unitid = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .cmask = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .name = "Input A Capture Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) .unitid = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .control = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .cmask = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .val_type = USB_MIXER_S16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .name = "Input B Capture Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) /* Audio Advantage Micro II findings:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) * Mapping spdif AES bits to vendor register.bit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * AES2: [0 0 0 0 0 0 0 0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * power on values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * r2: 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * just after it to 0xa0, presumably it disables/mutes some analog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) * parts when there is no audio.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * r9: 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * Optical transmitter on/off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * vendor register.bit: 9.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * 0 - on (0x28 register value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * 1 - off (0x2a register value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) struct usb_interface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) struct usb_host_interface *alts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) unsigned int ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) unsigned char data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) ucontrol->value.iec958.status[0] = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) ucontrol->value.iec958.status[1] = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) ucontrol->value.iec958.status[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* use known values for that card: interface#1 altsetting#1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) iface = usb_ifnum_to_if(chip->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (!iface || iface->num_altsetting < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) alts = &iface->altsetting[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (get_iface_desc(alts)->bNumEndpoints < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ep = get_endpoint(alts, 0)->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) usb_rcvctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) UAC_GET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rate = data[0] | (data[1] << 8) | (data[2] << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ucontrol->value.iec958.status[3] = (rate == 48000) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) IEC958_AES3_CON_FS_48000 : IEC958_AES3_CON_FS_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) unsigned int pval = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) reg = ((pval >> 4) & 0xf0) | (pval & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) reg = (pval & IEC958_AES0_NONAUDIO) ? 0xa0 : 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) reg |= (pval >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) unsigned int pval, pval_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) pval = pval_old = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) pval &= 0xfffff0f0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) pval |= (ucontrol->value.iec958.status[1] & 0x0f) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) pval |= (ucontrol->value.iec958.status[0] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) pval &= 0xffff0fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) pval |= (ucontrol->value.iec958.status[1] & 0xf0) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /* The frequency bits in AES3 cannot be set via register access. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* Silently ignore any bits from the request that cannot be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if (pval == pval_old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) kcontrol->private_value = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) err = snd_microii_spdif_default_update(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) ucontrol->value.iec958.status[0] = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) ucontrol->value.iec958.status[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) ucontrol->value.iec958.status[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) ucontrol->value.iec958.status[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) ucontrol->value.integer.value[0] = !(kcontrol->private_value & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) u8 reg = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) reg = ucontrol->value.integer.value[0] ? 0x28 : 0x2a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (reg != list->kctl->private_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) kcontrol->private_value = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) err = snd_microii_spdif_switch_update(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) static const struct snd_kcontrol_new snd_microii_mixer_spdif[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) .info = snd_microii_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) .get = snd_microii_spdif_default_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) .put = snd_microii_spdif_default_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) .private_value = 0x00000100UL,/* reset value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) .iface = SNDRV_CTL_ELEM_IFACE_PCM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) .info = snd_microii_spdif_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) .get = snd_microii_spdif_mask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) .get = snd_microii_spdif_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) .put = snd_microii_spdif_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) .private_value = 0x00000028UL,/* reset value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) static const usb_mixer_elem_resume_func_t resume_funcs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) snd_microii_spdif_default_update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) snd_microii_spdif_switch_update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) for (i = 0; i < ARRAY_SIZE(snd_microii_mixer_spdif); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) err = add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) resume_funcs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) &snd_microii_mixer_spdif[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /* Creative Sound Blaster E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) ucontrol->value.integer.value[0] = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) unsigned char state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) unsigned char buff[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) buff[0] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) buff[1] = state ? 0x02 : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 0x0202, 3, buff, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) unsigned char value = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (kcontrol->private_value == value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) kcontrol->private_value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) err = snd_soundblaster_e1_switch_update(list->mixer, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) return snd_soundblaster_e1_switch_update(list->mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) list->kctl->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) static const char *const texts[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) "Mic", "Aux"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) static const struct snd_kcontrol_new snd_soundblaster_e1_input_switch = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) .name = "Input Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .info = snd_soundblaster_e1_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) .get = snd_soundblaster_e1_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .put = snd_soundblaster_e1_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .private_value = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) snd_soundblaster_e1_switch_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) &snd_soundblaster_e1_input_switch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) u16 buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) ch, snd_usb_ctrl_intf(chip) | (id << 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) &buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) static int dell_dock_mixer_init(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) /* fix to 0dB playback volumes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) dell_dock_init_vol(mixer->chip, 1, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) dell_dock_init_vol(mixer->chip, 2, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) dell_dock_init_vol(mixer->chip, 1, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) dell_dock_init_vol(mixer->chip, 2, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) /* RME Class Compliant device quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) #define SND_RME_GET_STATUS1 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) #define SND_RME_GET_CURRENT_FREQ 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) #define SND_RME_CLK_SYSTEM_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) #define SND_RME_CLK_SYSTEM_MASK 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) #define SND_RME_CLK_AES_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) #define SND_RME_CLK_SPDIF_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) #define SND_RME_CLK_AES_SPDIF_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) #define SND_RME_CLK_SYNC_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) #define SND_RME_CLK_SYNC_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) #define SND_RME_CLK_FREQMUL_SHIFT 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) #define SND_RME_CLK_FREQMUL_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) #define SND_RME_CLK_SYSTEM(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) ((x >> SND_RME_CLK_SYSTEM_SHIFT) & SND_RME_CLK_SYSTEM_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) #define SND_RME_CLK_AES(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) ((x >> SND_RME_CLK_AES_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) #define SND_RME_CLK_SPDIF(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) ((x >> SND_RME_CLK_SPDIF_SHIFT) & SND_RME_CLK_AES_SPDIF_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) #define SND_RME_CLK_SYNC(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ((x >> SND_RME_CLK_SYNC_SHIFT) & SND_RME_CLK_SYNC_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) #define SND_RME_CLK_FREQMUL(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) ((x >> SND_RME_CLK_FREQMUL_SHIFT) & SND_RME_CLK_FREQMUL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) #define SND_RME_CLK_AES_LOCK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) #define SND_RME_CLK_AES_SYNC 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) #define SND_RME_CLK_SPDIF_LOCK 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) #define SND_RME_CLK_SPDIF_SYNC 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) #define SND_RME_SPDIF_IF_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) #define SND_RME_SPDIF_FORMAT_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) #define SND_RME_BINARY_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) #define SND_RME_SPDIF_IF(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) ((x >> SND_RME_SPDIF_IF_SHIFT) & SND_RME_BINARY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) #define SND_RME_SPDIF_FORMAT(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) ((x >> SND_RME_SPDIF_FORMAT_SHIFT) & SND_RME_BINARY_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) static const u32 snd_rme_rate_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 32000, 44100, 48000, 50000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 64000, 88200, 96000, 100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 128000, 176400, 192000, 200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 256000, 352800, 384000, 400000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 512000, 705600, 768000, 800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) /* maximum number of items for AES and S/PDIF rates for above table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) #define SND_RME_RATE_IDX_AES_SPDIF_NUM 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) enum snd_rme_domain {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) SND_RME_DOMAIN_SYSTEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) SND_RME_DOMAIN_AES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) SND_RME_DOMAIN_SPDIF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) enum snd_rme_clock_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) SND_RME_CLOCK_NOLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) SND_RME_CLOCK_LOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) SND_RME_CLOCK_SYNC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) static int snd_rme_read_value(struct snd_usb_audio *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) unsigned int item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) struct usb_device *dev = chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) value, sizeof(*value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) dev_err(&dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) "unable to issue vendor read request %d (ret = %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) item, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) static int snd_rme_get_status1(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) u32 *status1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) static int snd_rme_rate_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) u32 rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) err = snd_rme_get_status1(kcontrol, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) case SND_RME_DOMAIN_SYSTEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) idx = SND_RME_CLK_SYSTEM(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (idx < ARRAY_SIZE(snd_rme_rate_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) rate = snd_rme_rate_table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) case SND_RME_DOMAIN_AES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) idx = SND_RME_CLK_AES(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (idx < SND_RME_RATE_IDX_AES_SPDIF_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) rate = snd_rme_rate_table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) case SND_RME_DOMAIN_SPDIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) idx = SND_RME_CLK_SPDIF(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (idx < SND_RME_RATE_IDX_AES_SPDIF_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) rate = snd_rme_rate_table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) ucontrol->value.integer.value[0] = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) static int snd_rme_sync_state_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) int idx = SND_RME_CLOCK_NOLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) err = snd_rme_get_status1(kcontrol, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) case SND_RME_DOMAIN_AES: /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (status1 & SND_RME_CLK_AES_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) idx = SND_RME_CLOCK_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) else if (status1 & SND_RME_CLK_AES_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) idx = SND_RME_CLOCK_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) case SND_RME_DOMAIN_SPDIF: /* SPDIF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (status1 & SND_RME_CLK_SPDIF_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) idx = SND_RME_CLOCK_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) else if (status1 & SND_RME_CLK_SPDIF_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) idx = SND_RME_CLOCK_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) ucontrol->value.enumerated.item[0] = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) static int snd_rme_spdif_if_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) err = snd_rme_get_status1(kcontrol, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) ucontrol->value.enumerated.item[0] = SND_RME_SPDIF_IF(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) static int snd_rme_spdif_format_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) err = snd_rme_get_status1(kcontrol, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) ucontrol->value.enumerated.item[0] = SND_RME_SPDIF_FORMAT(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) static int snd_rme_sync_source_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) err = snd_rme_get_status1(kcontrol, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) ucontrol->value.enumerated.item[0] = SND_RME_CLK_SYNC(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) static int snd_rme_current_freq_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) struct snd_usb_audio *chip = list->mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) u32 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) const u64 num = 104857600000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) u32 den;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) unsigned int freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) err = snd_rme_read_value(chip, SND_RME_GET_STATUS1, &status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) err = snd_rme_read_value(chip, SND_RME_GET_CURRENT_FREQ, &den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) freq = (den == 0) ? 0 : div64_u64(num, den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) freq <<= SND_RME_CLK_FREQMUL(status1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) ucontrol->value.integer.value[0] = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) static int snd_rme_rate_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) switch (kcontrol->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) case SND_RME_DOMAIN_SYSTEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) uinfo->value.integer.min = 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) uinfo->value.integer.max = 800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) case SND_RME_DOMAIN_AES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) case SND_RME_DOMAIN_SPDIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) uinfo->value.integer.max = 200000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) uinfo->value.integer.step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int snd_rme_sync_state_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) static const char *const sync_states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) "No Lock", "Lock", "Sync"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) return snd_ctl_enum_info(uinfo, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) ARRAY_SIZE(sync_states), sync_states);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static int snd_rme_spdif_if_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) static const char *const spdif_if[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) "Coaxial", "Optical"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) return snd_ctl_enum_info(uinfo, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) ARRAY_SIZE(spdif_if), spdif_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) static int snd_rme_spdif_format_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static const char *const optical_type[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) "Consumer", "Professional"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return snd_ctl_enum_info(uinfo, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) ARRAY_SIZE(optical_type), optical_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) static int snd_rme_sync_source_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) static const char *const sync_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) "Internal", "AES", "SPDIF", "Internal"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) return snd_ctl_enum_info(uinfo, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) ARRAY_SIZE(sync_sources), sync_sources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static const struct snd_kcontrol_new snd_rme_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) .name = "AES Rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) .info = snd_rme_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) .get = snd_rme_rate_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) .private_value = SND_RME_DOMAIN_AES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) .name = "AES Sync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) .info = snd_rme_sync_state_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) .get = snd_rme_sync_state_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) .private_value = SND_RME_DOMAIN_AES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) .name = "SPDIF Rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) .info = snd_rme_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) .get = snd_rme_rate_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) .private_value = SND_RME_DOMAIN_SPDIF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) .name = "SPDIF Sync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) .info = snd_rme_sync_state_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) .get = snd_rme_sync_state_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) .private_value = SND_RME_DOMAIN_SPDIF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) .name = "SPDIF Interface",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) .info = snd_rme_spdif_if_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) .get = snd_rme_spdif_if_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) .name = "SPDIF Format",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) .info = snd_rme_spdif_format_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) .get = snd_rme_spdif_format_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) .name = "Sync Source",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) .info = snd_rme_sync_source_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) .get = snd_rme_sync_source_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) .name = "System Rate",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) .info = snd_rme_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) .get = snd_rme_rate_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) .private_value = SND_RME_DOMAIN_SYSTEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) .name = "Current Frequency",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) .info = snd_rme_rate_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) .get = snd_rme_current_freq_get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) static int snd_rme_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) for (i = 0; i < ARRAY_SIZE(snd_rme_controls); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) err = add_single_ctl_with_resume(mixer, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) &snd_rme_controls[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) * RME Babyface Pro (FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) * These devices exposes a couple of DSP functions via request to EP0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) * Switches are available via control registers, while routing is controlled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) * by controlling the volume on each possible crossing point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) * Volume control is linear, from -inf (dec. 0) to +6dB (dec. 65536) with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) * 0dB being at dec. 32768.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) SND_BBFPRO_CTL_REG1 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) SND_BBFPRO_CTL_REG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) #define SND_BBFPRO_CTL_REG_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) #define SND_BBFPRO_CTL_IDX_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) #define SND_BBFPRO_CTL_IDX_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) #define SND_BBFPRO_CTL_VAL_MASK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) #define SND_BBFPRO_CTL_VAL_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) #define SND_BBFPRO_CTL_REG1_CLK_MASTER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) #define SND_BBFPRO_CTL_REG1_CLK_OPTICAL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) #define SND_BBFPRO_CTL_REG1_SPDIF_PRO 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) #define SND_BBFPRO_CTL_REG1_SPDIF_EMPH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) #define SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) #define SND_BBFPRO_CTL_REG2_48V_AN1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) #define SND_BBFPRO_CTL_REG2_48V_AN2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) #define SND_BBFPRO_CTL_REG2_SENS_IN3 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) #define SND_BBFPRO_CTL_REG2_SENS_IN4 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) #define SND_BBFPRO_CTL_REG2_PAD_AN1 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) #define SND_BBFPRO_CTL_REG2_PAD_AN2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) #define SND_BBFPRO_MIXER_IDX_MASK 0x1ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) #define SND_BBFPRO_MIXER_VAL_MASK 0x3ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) #define SND_BBFPRO_MIXER_VAL_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) #define SND_BBFPRO_MIXER_VAL_MIN 0 // -inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) #define SND_BBFPRO_MIXER_VAL_MAX 65536 // +6dB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) #define SND_BBFPRO_USBREQ_CTL_REG1 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) #define SND_BBFPRO_USBREQ_CTL_REG2 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) #define SND_BBFPRO_USBREQ_MIXER 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) u8 index, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) u16 usb_req, usb_idx, usb_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (reg == SND_BBFPRO_CTL_REG1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) usb_req = SND_BBFPRO_USBREQ_CTL_REG1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (index == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) usb_idx = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) usb_val = value ? 3 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) usb_idx = 1 << index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) usb_val = value ? usb_idx : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) usb_req = SND_BBFPRO_USBREQ_CTL_REG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) usb_idx = 1 << index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) usb_val = value ? usb_idx : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) usb_sndctrlpipe(chip->dev, 0), usb_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) usb_val, usb_idx, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) static int snd_bbfpro_ctl_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) u8 reg, idx, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) int pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) pv = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) reg = pv & SND_BBFPRO_CTL_REG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) val = kcontrol->private_value >> SND_BBFPRO_CTL_VAL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) if ((reg == SND_BBFPRO_CTL_REG1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) (reg == SND_BBFPRO_CTL_REG2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) ucontrol->value.enumerated.item[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) static int snd_bbfpro_ctl_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) u8 reg, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) int pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) pv = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) reg = pv & SND_BBFPRO_CTL_REG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (reg == SND_BBFPRO_CTL_REG1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) static const char * const texts[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) "AutoSync",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) "Internal"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) return snd_ctl_enum_info(uinfo, 1, 2, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) } else if (reg == SND_BBFPRO_CTL_REG2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) idx == SND_BBFPRO_CTL_REG2_SENS_IN4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static const char * const texts[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) "-10dBV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) "+4dBu"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) return snd_ctl_enum_info(uinfo, 1, 2, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) static int snd_bbfpro_ctl_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) u8 reg, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) int old_value, pv, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) pv = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) reg = pv & SND_BBFPRO_CTL_REG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) old_value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if ((reg == SND_BBFPRO_CTL_REG1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) idx == SND_BBFPRO_CTL_REG1_CLK_OPTICAL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) (reg == SND_BBFPRO_CTL_REG2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) (idx == SND_BBFPRO_CTL_REG2_SENS_IN3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) idx == SND_BBFPRO_CTL_REG2_SENS_IN4))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (val == old_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) kcontrol->private_value = reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) | ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) | ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) u8 reg, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) int value, pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) pv = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) reg = pv & SND_BBFPRO_CTL_REG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) idx = (pv >> SND_BBFPRO_CTL_IDX_SHIFT) & SND_BBFPRO_CTL_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) value = (pv >> SND_BBFPRO_CTL_VAL_SHIFT) & SND_BBFPRO_CTL_VAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) return snd_bbfpro_ctl_update(list->mixer, reg, idx, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) struct snd_usb_audio *chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) u16 usb_idx, usb_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) idx = index & SND_BBFPRO_MIXER_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) // 18 bit linear volume, split so 2 bits end up in index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) v = value & SND_BBFPRO_MIXER_VAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) usb_idx = idx | (v & 0x3) << 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) usb_val = (v >> 2) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) usb_sndctrlpipe(chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) SND_BBFPRO_USBREQ_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) usb_val, usb_idx, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) static int snd_bbfpro_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static int snd_bbfpro_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) uinfo->value.integer.min = SND_BBFPRO_MIXER_VAL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) uinfo->value.integer.max = SND_BBFPRO_MIXER_VAL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) static int snd_bbfpro_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) u32 new_val, old_value, uvalue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) uvalue = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) idx = kcontrol->private_value & SND_BBFPRO_MIXER_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) old_value = kcontrol->private_value >> SND_BBFPRO_MIXER_VAL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) if (uvalue > SND_BBFPRO_MIXER_VAL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) if (uvalue == old_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) kcontrol->private_value = idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) | (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) err = snd_bbfpro_vol_update(mixer, idx, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) return err < 0 ? err : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) int pv = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) u16 idx = pv & SND_BBFPRO_MIXER_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) u32 val = (pv >> SND_BBFPRO_MIXER_VAL_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) & SND_BBFPRO_MIXER_VAL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) return snd_bbfpro_vol_update(list->mixer, idx, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) // Predfine elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) static const struct snd_kcontrol_new snd_bbfpro_ctl_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) .info = snd_bbfpro_ctl_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) .get = snd_bbfpro_ctl_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) .put = snd_bbfpro_ctl_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) static const struct snd_kcontrol_new snd_bbfpro_vol_control = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) .info = snd_bbfpro_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) .get = snd_bbfpro_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) .put = snd_bbfpro_vol_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) static int snd_bbfpro_ctl_add(struct usb_mixer_interface *mixer, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) u8 index, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct snd_kcontrol_new knew = snd_bbfpro_ctl_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) knew.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) knew.private_value = (reg & SND_BBFPRO_CTL_REG_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) | ((index & SND_BBFPRO_CTL_IDX_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) << SND_BBFPRO_CTL_IDX_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_ctl_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) &knew, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) static int snd_bbfpro_vol_add(struct usb_mixer_interface *mixer, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) struct snd_kcontrol_new knew = snd_bbfpro_vol_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) knew.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) knew.private_value = index & SND_BBFPRO_MIXER_IDX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) return add_single_ctl_with_resume(mixer, 0, snd_bbfpro_vol_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) &knew, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) int err, i, o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) char name[48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static const char * const input[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) "AN1", "AN2", "IN3", "IN4", "AS1", "AS2", "ADAT3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) "ADAT4", "ADAT5", "ADAT6", "ADAT7", "ADAT8"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) static const char * const output[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) "AN1", "AN2", "PH3", "PH4", "AS1", "AS2", "ADAT3", "ADAT4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) "ADAT5", "ADAT6", "ADAT7", "ADAT8"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) for (o = 0 ; o < 12 ; ++o) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) for (i = 0 ; i < 12 ; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) // Line routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) "%s-%s-%s Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) (i < 2 ? "Mic" : "Line"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) input[i], output[o]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) err = snd_bbfpro_vol_add(mixer, (26 * o + i), name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) // PCM routing... yes, it is output remapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) snprintf(name, sizeof(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) "PCM-%s-%s Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) output[i], output[o]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) err = snd_bbfpro_vol_add(mixer, (26 * o + 12 + i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) // Control Reg 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) SND_BBFPRO_CTL_REG1_CLK_OPTICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) "Sample Clock Source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) SND_BBFPRO_CTL_REG1_SPDIF_PRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) "IEC958 Pro Mask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) SND_BBFPRO_CTL_REG1_SPDIF_EMPH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) "IEC958 Emphasis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) "IEC958 Switch");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) // Control Reg 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) SND_BBFPRO_CTL_REG2_48V_AN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) "Mic-AN1 48V");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) SND_BBFPRO_CTL_REG2_48V_AN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) "Mic-AN2 48V");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) SND_BBFPRO_CTL_REG2_SENS_IN3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) "Line-IN3 Sens.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) SND_BBFPRO_CTL_REG2_SENS_IN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) "Line-IN4 Sens.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) SND_BBFPRO_CTL_REG2_PAD_AN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) "Mic-AN1 PAD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) err = snd_bbfpro_ctl_add(mixer, SND_BBFPRO_CTL_REG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) SND_BBFPRO_CTL_REG2_PAD_AN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) "Mic-AN2 PAD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) * Pioneer DJ DJM Mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) * These devices generally have options for soft-switching the playback and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) * capture sources in addition to the recording level. Although different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) * devices have different configurations, there seems to be canonical values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) * for specific capture/playback types: See the definitions of these below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * The wValue is masked with the stereo channel number. e.g. Setting Ch2 to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) * capture phono would be 0x0203. Capture, playback and capture level have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) * different wIndexes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) // Capture types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) #define SND_DJM_CAP_LINE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) #define SND_DJM_CAP_CDLINE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) #define SND_DJM_CAP_DIGITAL 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) #define SND_DJM_CAP_PHONO 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) #define SND_DJM_CAP_PFADER 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) #define SND_DJM_CAP_XFADERA 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) #define SND_DJM_CAP_XFADERB 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) #define SND_DJM_CAP_MIC 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) #define SND_DJM_CAP_AUX 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) #define SND_DJM_CAP_RECOUT 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) #define SND_DJM_CAP_NONE 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) #define SND_DJM_CAP_CH1PFADER 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) #define SND_DJM_CAP_CH2PFADER 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) #define SND_DJM_CAP_CH3PFADER 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) #define SND_DJM_CAP_CH4PFADER 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) // Playback types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) #define SND_DJM_PB_CH1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) #define SND_DJM_PB_CH2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) #define SND_DJM_PB_AUX 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) #define SND_DJM_WINDEX_CAP 0x8002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) #define SND_DJM_WINDEX_CAPLVL 0x8003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) #define SND_DJM_WINDEX_PB 0x8016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) // kcontrol->private_value layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) #define SND_DJM_VALUE_MASK 0x0000ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) #define SND_DJM_GROUP_MASK 0x00ff0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) #define SND_DJM_DEVICE_MASK 0xff000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) #define SND_DJM_GROUP_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) #define SND_DJM_DEVICE_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) // device table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) #define SND_DJM_250MK2_IDX 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) #define SND_DJM_750_IDX 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) #define SND_DJM_900NXS2_IDX 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) #define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) .options = snd_djm_opts_##suffix, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) .noptions = ARRAY_SIZE(snd_djm_opts_##suffix), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) .default_value = _default_value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) .wIndex = _windex }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) #define SND_DJM_DEVICE(suffix) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) .controls = snd_djm_ctls_##suffix, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) .ncontrols = ARRAY_SIZE(snd_djm_ctls_##suffix) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) struct snd_djm_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) const struct snd_djm_ctl *controls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) size_t ncontrols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) struct snd_djm_ctl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) const u16 *options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) size_t noptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) u16 default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) u16 wIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) static const char *snd_djm_get_label_caplevel(u16 wvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) switch (wvalue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) case 0x0000: return "-19dB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) case 0x0100: return "-15dB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) case 0x0200: return "-10dB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) case 0x0300: return "-5dB";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) default: return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) static const char *snd_djm_get_label_cap(u16 wvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) switch (wvalue & 0x00ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) case SND_DJM_CAP_LINE: return "Control Tone LINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) case SND_DJM_CAP_CDLINE: return "Control Tone CD/LINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) case SND_DJM_CAP_DIGITAL: return "Control Tone DIGITAL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) case SND_DJM_CAP_PHONO: return "Control Tone PHONO";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) case SND_DJM_CAP_PFADER: return "Post Fader";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) case SND_DJM_CAP_XFADERA: return "Cross Fader A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) case SND_DJM_CAP_XFADERB: return "Cross Fader B";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) case SND_DJM_CAP_MIC: return "Mic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) case SND_DJM_CAP_RECOUT: return "Rec Out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) case SND_DJM_CAP_AUX: return "Aux";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) case SND_DJM_CAP_NONE: return "None";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) case SND_DJM_CAP_CH1PFADER: return "Post Fader Ch1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) case SND_DJM_CAP_CH2PFADER: return "Post Fader Ch2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) case SND_DJM_CAP_CH3PFADER: return "Post Fader Ch3";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) case SND_DJM_CAP_CH4PFADER: return "Post Fader Ch4";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) default: return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) static const char *snd_djm_get_label_pb(u16 wvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) switch (wvalue & 0x00ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) case SND_DJM_PB_CH1: return "Ch1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) case SND_DJM_PB_CH2: return "Ch2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) case SND_DJM_PB_AUX: return "Aux";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) default: return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) static const char *snd_djm_get_label(u16 wvalue, u16 windex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) switch (windex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) case SND_DJM_WINDEX_CAPLVL: return snd_djm_get_label_caplevel(wvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) case SND_DJM_WINDEX_CAP: return snd_djm_get_label_cap(wvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) case SND_DJM_WINDEX_PB: return snd_djm_get_label_pb(wvalue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) default: return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) // DJM-250MK2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) static const u16 snd_djm_opts_cap_level[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 0x0000, 0x0100, 0x0200, 0x0300 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) static const u16 snd_djm_opts_250mk2_cap1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static const u16 snd_djm_opts_250mk2_cap2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) static const u16 snd_djm_opts_250mk2_cap3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) static const u16 snd_djm_opts_250mk2_pb1[] = { 0x0100, 0x0101, 0x0104 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) static const u16 snd_djm_opts_250mk2_pb2[] = { 0x0200, 0x0201, 0x0204 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) static const u16 snd_djm_opts_250mk2_pb3[] = { 0x0300, 0x0301, 0x0304 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) SND_DJM_CTL("Ch1 Input", 250mk2_cap1, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) SND_DJM_CTL("Ch2 Input", 250mk2_cap2, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) SND_DJM_CTL("Ch3 Input", 250mk2_cap3, 0, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) SND_DJM_CTL("Ch1 Output", 250mk2_pb1, 0, SND_DJM_WINDEX_PB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) SND_DJM_CTL("Ch2 Output", 250mk2_pb2, 1, SND_DJM_WINDEX_PB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) SND_DJM_CTL("Ch3 Output", 250mk2_pb3, 2, SND_DJM_WINDEX_PB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) // DJM-750
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) static const u16 snd_djm_opts_750_cap1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) static const u16 snd_djm_opts_750_cap2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 0x0200, 0x0201, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) static const u16 snd_djm_opts_750_cap3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 0x0300, 0x0301, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a, 0x030f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) static const u16 snd_djm_opts_750_cap4[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 0x0401, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) static const struct snd_djm_ctl snd_djm_ctls_750[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) SND_DJM_CTL("Ch1 Input", 750_cap1, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) SND_DJM_CTL("Ch2 Input", 750_cap2, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) SND_DJM_CTL("Ch3 Input", 750_cap3, 0, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) SND_DJM_CTL("Ch4 Input", 750_cap4, 0, SND_DJM_WINDEX_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) // DJM-900NXS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) static const u16 snd_djm_opts_900nxs2_cap1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 0x0100, 0x0102, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) static const u16 snd_djm_opts_900nxs2_cap2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 0x0200, 0x0202, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) static const u16 snd_djm_opts_900nxs2_cap3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 0x0300, 0x0302, 0x0303, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) static const u16 snd_djm_opts_900nxs2_cap4[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 0x0400, 0x0402, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) static const u16 snd_djm_opts_900nxs2_cap5[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 0x0507, 0x0508, 0x0509, 0x050a, 0x0511, 0x0512, 0x0513, 0x0514 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) SND_DJM_CTL("Ch1 Input", 900nxs2_cap1, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) SND_DJM_CTL("Ch2 Input", 900nxs2_cap2, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) SND_DJM_CTL("Ch3 Input", 900nxs2_cap3, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) SND_DJM_CTL("Ch4 Input", 900nxs2_cap4, 2, SND_DJM_WINDEX_CAP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) SND_DJM_CTL("Ch5 Input", 900nxs2_cap5, 3, SND_DJM_WINDEX_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) static const struct snd_djm_device snd_djm_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) SND_DJM_DEVICE(250mk2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) SND_DJM_DEVICE(750),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) SND_DJM_DEVICE(900nxs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) static int snd_djm_controls_info(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) struct snd_ctl_elem_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) unsigned long private_value = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) u8 device_idx = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) u8 ctl_idx = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) const struct snd_djm_device *device = &snd_djm_devices[device_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) const struct snd_djm_ctl *ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) size_t noptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) if (ctl_idx >= device->ncontrols)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) ctl = &device->controls[ctl_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) noptions = ctl->noptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) if (info->value.enumerated.item >= noptions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) info->value.enumerated.item = noptions - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) name = snd_djm_get_label(ctl->options[info->value.enumerated.item],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) ctl->wIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) strlcpy(info->value.enumerated.name, name, sizeof(info->value.enumerated.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) info->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) info->value.enumerated.items = noptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) static int snd_djm_controls_update(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) u8 device_idx, u8 group, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) const struct snd_djm_device *device = &snd_djm_devices[device_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) if ((group >= device->ncontrols) || value >= device->controls[group].noptions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) err = snd_usb_lock_shutdown(mixer->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) err = snd_usb_ctl_msg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) USB_REQ_SET_FEATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) device->controls[group].options[value],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) device->controls[group].wIndex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) snd_usb_unlock_shutdown(mixer->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) static int snd_djm_controls_get(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) struct snd_ctl_elem_value *elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) elem->value.enumerated.item[0] = kctl->private_value & SND_DJM_VALUE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) unsigned long private_value = kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) u16 value = elem->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) kctl->private_value = (((unsigned long)device << SND_DJM_DEVICE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) (group << SND_DJM_GROUP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) return snd_djm_controls_update(mixer, device, group, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) static int snd_djm_controls_resume(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) unsigned long private_value = list->kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) u16 value = (private_value & SND_DJM_VALUE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) return snd_djm_controls_update(list->mixer, device, group, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) static int snd_djm_controls_create(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) const u8 device_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) const struct snd_djm_device *device = &snd_djm_devices[device_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) struct snd_kcontrol_new knew = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) .info = snd_djm_controls_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) .get = snd_djm_controls_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) .put = snd_djm_controls_put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) for (i = 0; i < device->ncontrols; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) value = device->controls[i].default_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) knew.name = device->controls[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) knew.private_value = (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) ((unsigned long)device_idx << SND_DJM_DEVICE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) (i << SND_DJM_GROUP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) err = snd_djm_controls_update(mixer, device_idx, i, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) err = add_single_ctl_with_resume(mixer, 0, snd_djm_controls_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) &knew, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) err = snd_usb_soundblaster_remote_init(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) /* Tascam US-16x08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) case USB_ID(0x0644, 0x8047):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) err = snd_us16x08_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) case USB_ID(0x041e, 0x3020):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) case USB_ID(0x041e, 0x3040):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) case USB_ID(0x041e, 0x3042):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) case USB_ID(0x041e, 0x30df):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) case USB_ID(0x041e, 0x3048):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) err = snd_audigy2nx_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) snd_card_ro_proc_new(mixer->chip->card, "audigy2nx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) mixer, snd_audigy2nx_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) /* EMU0204 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) case USB_ID(0x041e, 0x3f19):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) err = snd_emu0204_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) err = snd_c400_create_mixer(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) err = snd_ftu_create_mixer(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) case USB_ID(0x0b05, 0x1739): /* ASUS Xonar U1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) case USB_ID(0x0b05, 0x1743): /* ASUS Xonar U1 (2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) case USB_ID(0x0b05, 0x17a0): /* ASUS Xonar U3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) err = snd_xonar_u1_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) case USB_ID(0x0d8c, 0x0103): /* Audio Advantage Micro II */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) err = snd_microii_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) err = snd_mbox1_create_sync_switch(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) err = snd_nativeinstruments_create_mixer(mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) snd_nativeinstruments_ta6_mixers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) err = snd_nativeinstruments_create_mixer(mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) snd_nativeinstruments_ta10_mixers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) /* detection is disabled in mixer_maps.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) err = snd_create_std_mono_table(mixer, ebox44_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) case USB_ID(0x1235, 0x8012): /* Focusrite Scarlett 6i6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) case USB_ID(0x1235, 0x8002): /* Focusrite Scarlett 8i6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) case USB_ID(0x1235, 0x8004): /* Focusrite Scarlett 18i6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) case USB_ID(0x1235, 0x8014): /* Focusrite Scarlett 18i8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) err = snd_scarlett_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) case USB_ID(0x1235, 0x8203): /* Focusrite Scarlett 6i6 2nd Gen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) case USB_ID(0x1235, 0x8204): /* Focusrite Scarlett 18i8 2nd Gen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) case USB_ID(0x1235, 0x8201): /* Focusrite Scarlett 18i20 2nd Gen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) err = snd_scarlett_gen2_init(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) err = snd_soundblaster_e1_switch_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) err = dell_dock_mixer_init(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) case USB_ID(0x2a39, 0x3fd2): /* RME ADI-2 Pro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) case USB_ID(0x2a39, 0x3fd3): /* RME ADI-2 DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) case USB_ID(0x2a39, 0x3fd4): /* RME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) err = snd_rme_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) case USB_ID(0x194f, 0x010c): /* Presonus Studio 1810c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) err = snd_sc1810_init_mixer(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) err = snd_bbfpro_controls_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) err = snd_djm_controls_create(mixer, SND_DJM_750_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) err = snd_djm_controls_create(mixer, SND_DJM_900NXS2_IDX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) dell_dock_mixer_init(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) int unitid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) if (!mixer->rc_cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) /* unit ids specific to Extigy/Audigy 2 NX: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) switch (unitid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) case 0: /* remote control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) mixer->rc_urb->dev = mixer->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) case 4: /* digital in jack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) case 7: /* line in jacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) case 19: /* speaker out jacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) case 20: /* headphones out jack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) /* live24ext: 4 = line-in jack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) case 3: /* hp-out jack (may actuate Mute) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) usb_audio_dbg(mixer->chip, "memory change in unknown unit %d\n", unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) /* Approximation using 10 ranges based on output measurement on hw v1.2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) * This seems close to the cubic mapping e.g. alsamixer uses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) static const DECLARE_TLV_DB_RANGE(scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 0, 1, TLV_DB_MINMAX_ITEM(-5300, -4970),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 2, 5, TLV_DB_MINMAX_ITEM(-4710, -4160),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 6, 7, TLV_DB_MINMAX_ITEM(-3884, -3710),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if (cval->min == 0 && cval->max == 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) kctl->tlv.p = scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) } else if (cval->min == 0 && cval->max <= 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) /* Some other clearly broken DragonFly variant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) * At least a 0..53 variant (hw v1.0) exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) struct usb_mixer_elem_info *cval, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) switch (mixer->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) if (unitid == 7 && cval->control == UAC_FU_VOLUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) /* lowest playback value is muted on some devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) case USB_ID(0x0d8c, 0x000c): /* C-Media */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) case USB_ID(0x0d8c, 0x0014): /* C-Media */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) case USB_ID(0x19f7, 0x0003): /* RODE NT-USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) if (strstr(kctl->id.name, "Playback"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) cval->min_mute = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147)