Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)