linux/sound/usb/mixer_quirks.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   USB Audio Driver for ALSA
 *
 *   Quirks and vendor-specific extensions for mixer interfaces
 *
 *   Copyright (c) 2002 by Takashi Iwai <[email protected]>
 *
 *   Many codes borrowed from audio.c by
 *	    Alan Cox ([email protected])
 *	    Thomas Sailer ([email protected])
 *
 *   Audio Advantage Micro II support added by:
 *	    Przemek Rudy ([email protected])
 */

#include <linux/hid.h>
#include <linux/init.h>
#include <linux/math64.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>

#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/hda_verbs.h>
#include <sound/hwdep.h>
#include <sound/info.h>
#include <sound/tlv.h>

#include "usbaudio.h"
#include "mixer.h"
#include "mixer_quirks.h"
#include "mixer_scarlett.h"
#include "mixer_scarlett2.h"
#include "mixer_us16x08.h"
#include "mixer_s1810c.h"
#include "helper.h"

struct std_mono_table {};

/* This function allows for the creation of standard UAC controls.
 * See the quirks for M-Audio FTUs or Ebox-44.
 * If you don't want to set a TLV callback pass NULL.
 *
 * Since there doesn't seem to be a devices that needs a multichannel
 * version, we keep it mono for simplicity.
 */
static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
				unsigned int unitid,
				unsigned int control,
				unsigned int cmask,
				int val_type,
				unsigned int idx_off,
				const char *name,
				snd_kcontrol_tlv_rw_t *tlv_callback)
{}

static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
				unsigned int unitid,
				unsigned int control,
				unsigned int cmask,
				int val_type,
				const char *name,
				snd_kcontrol_tlv_rw_t *tlv_callback)
{}

/*
 * Create a set of standard UAC controls from a table
 */
static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
				     const struct std_mono_table *t)
{}

static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer,
				      int id,
				      usb_mixer_elem_resume_func_t resume,
				      const struct snd_kcontrol_new *knew,
				      struct usb_mixer_elem_list **listp)
{}

/*
 * Sound Blaster remote control configuration
 *
 * format of remote control data:
 * Extigy:       xx 00
 * Audigy 2 NX:  06 80 xx 00 00 00
 * Live! 24-bit: 06 80 xx yy 22 83
 */
static const struct rc_config {} rc_configs[] =;

static void snd_usb_soundblaster_remote_complete(struct urb *urb)
{}

static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
				     long count, loff_t *offset)
{}

static __poll_t snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
					    poll_table *wait)
{}

static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
{}

#define snd_audigy2nx_led_info

static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{}

static int snd_audigy2nx_led_update(struct usb_mixer_interface *mixer,
				    int value, int index)
{}

static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{}

static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
{}

/* name and private_value are set dynamically */
static const struct snd_kcontrol_new snd_audigy2nx_control =;

static const char * const snd_audigy2nx_led_names[] =;

static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
{}

static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
				    struct snd_info_buffer *buffer)
{}

/* EMU0204 */
static int snd_emu0204_ch_switch_info(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_info *uinfo)
{}

static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{}

static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
					int value)
{}

static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{}

static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
{}

static const struct snd_kcontrol_new snd_emu0204_control =;

static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
{}

/* ASUS Xonar U1 / U3 controls */

static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{}

static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
				      unsigned char status)
{}

static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{}

static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
{}

static const struct snd_kcontrol_new snd_xonar_u1_output_switch =;

static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
{}

/* Digidesign Mbox 1 helper functions */

static int snd_mbox1_is_spdif_synced(struct snd_usb_audio *chip)
{}

static int snd_mbox1_set_clk_source(struct snd_usb_audio *chip, int rate_or_zero)
{}

static int snd_mbox1_is_spdif_input(struct snd_usb_audio *chip)
{}

static int snd_mbox1_set_input_source(struct snd_usb_audio *chip, int is_spdif)
{}

/* Digidesign Mbox 1 clock source switch (internal/spdif) */

static int snd_mbox1_clk_switch_get(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_mbox1_clk_switch_update(struct usb_mixer_interface *mixer, int is_spdif_sync)
{}

static int snd_mbox1_clk_switch_put(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_mbox1_clk_switch_info(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{}

static int snd_mbox1_clk_switch_resume(struct usb_mixer_elem_list *list)
{}

/* Digidesign Mbox 1 input source switch (analog/spdif) */

static int snd_mbox1_src_switch_get(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_mbox1_src_switch_update(struct usb_mixer_interface *mixer, int is_spdif_input)
{}

static int snd_mbox1_src_switch_put(struct snd_kcontrol *kctl,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_mbox1_src_switch_info(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{}

static int snd_mbox1_src_switch_resume(struct usb_mixer_elem_list *list)
{}

static const struct snd_kcontrol_new snd_mbox1_clk_switch =;

static const struct snd_kcontrol_new snd_mbox1_src_switch =;

static int snd_mbox1_controls_create(struct usb_mixer_interface *mixer)
{}

/* Native Instruments device quirks */

#define _MAKE_NI_CONTROL(bRequest,wIndex)

static int snd_ni_control_init_val(struct usb_mixer_interface *mixer,
				   struct snd_kcontrol *kctl)
{}

static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
					     struct snd_ctl_elem_value *ucontrol)
{}

static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
{}

static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
					     struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] =;

static const struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] =;

static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
					      const struct snd_kcontrol_new *kc,
					      unsigned int count)
{}

/* M-Audio FastTrack Ultra quirks */
/* FTU Effect switch (also used by C400/C600) */
static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_info *uinfo)
{}

static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer,
				   struct snd_kcontrol *kctl)
{}

static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
{}

static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
					struct snd_ctl_elem_value *ucontrol)
{}

static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
	int validx, int bUnitID)
{}

/* Create volume controls for FTU devices*/
static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
{}

static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer)
{}

static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer)
{}

static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
{}

void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
			       unsigned char samplerate_id)
{}

/* M-Audio Fast Track C400/C600 */
/* C400/C600 volume controls, this control needs a volume quirk, see mixer.c */
static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
{}

/* This control needs a volume quirk, see mixer.c */
static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
{}

static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
{}

static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer)
{}

static int snd_c400_create_mixer(struct usb_mixer_interface *mixer)
{}

/*
 * The mixer units for Ebox-44 are corrupt, and even where they
 * are valid they presents mono controls as L and R channels of
 * stereo. So we provide a good mixer here.
 */
static const struct std_mono_table ebox44_table[] =;

/* Audio Advantage Micro II findings:
 *
 * Mapping spdif AES bits to vendor register.bit:
 * AES0: [0 0 0 0 2.3 2.2 2.1 2.0] - default 0x00
 * AES1: [3.3 3.2.3.1.3.0 2.7 2.6 2.5 2.4] - default: 0x01
 * AES2: [0 0 0 0 0 0 0 0]
 * AES3: [0 0 0 0 0 0 x 0] - 'x' bit is set basing on standard usb request
 *                           (UAC_EP_CS_ATTR_SAMPLE_RATE) for Audio Devices
 *
 * power on values:
 * r2: 0x10
 * r3: 0x20 (b7 is zeroed just before playback (except IEC61937) and set
 *           just after it to 0xa0, presumably it disables/mutes some analog
 *           parts when there is no audio.)
 * r9: 0x28
 *
 * Optical transmitter on/off:
 * vendor register.bit: 9.1
 * 0 - on (0x28 register value)
 * 1 - off (0x2a register value)
 *
 */
static int snd_microii_spdif_info(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_info *uinfo)
{}

static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{}

static int snd_microii_spdif_default_update(struct usb_mixer_elem_list *list)
{}

static int snd_microii_spdif_default_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{}

static int snd_microii_spdif_mask_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{}

static int snd_microii_spdif_switch_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{}

static int snd_microii_spdif_switch_update(struct usb_mixer_elem_list *list)
{}

static int snd_microii_spdif_switch_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new snd_microii_mixer_spdif[] =;

static int snd_microii_controls_create(struct usb_mixer_interface *mixer)
{}

/* Creative Sound Blaster E1 */

static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_value *ucontrol)
{}

static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer,
					     unsigned char state)
{}

static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_value *ucontrol)
{}

static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
{}

static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new snd_soundblaster_e1_input_switch =;

static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer)
{}

/*
 * Dell WD15 dock jack detection
 *
 * The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec
 * from Realtek. It is a UAC 1 device, and UAC 1 does not support jack
 * detection. Instead, jack detection works by sending HD Audio commands over
 * vendor-type USB messages.
 */

#define HDA_VERB_CMD(V, N, D)

#define REALTEK_HDA_VALUE

#define REALTEK_HDA_SET
#define REALTEK_MANUAL_MODE
#define REALTEK_HDA_GET_OUT
#define REALTEK_HDA_GET_IN

#define REALTEK_AUDIO_FUNCTION_GROUP
#define REALTEK_LINE1
#define REALTEK_VENDOR_REGISTERS
#define REALTEK_HP_OUT

#define REALTEK_CBJ_CTRL2

#define REALTEK_JACK_INTERRUPT_NODE

#define REALTEK_MIC_FLAG

static int realtek_hda_set(struct snd_usb_audio *chip, u32 cmd)
{}

static int realtek_hda_get(struct snd_usb_audio *chip, u32 cmd, u32 *value)
{}

static int realtek_ctl_connector_get(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{}

static const struct snd_kcontrol_new realtek_connector_ctl_ro =;

static int realtek_resume_jack(struct usb_mixer_elem_list *list)
{}

static int realtek_add_jack(struct usb_mixer_interface *mixer,
			    char *name, u32 val)
{}

static int dell_dock_mixer_create(struct usb_mixer_interface *mixer)
{}

static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id)
{}

static int dell_dock_mixer_init(struct usb_mixer_interface *mixer)
{}

/* RME Class Compliant device quirks */

#define SND_RME_GET_STATUS1
#define SND_RME_GET_CURRENT_FREQ
#define SND_RME_CLK_SYSTEM_SHIFT
#define SND_RME_CLK_SYSTEM_MASK
#define SND_RME_CLK_AES_SHIFT
#define SND_RME_CLK_SPDIF_SHIFT
#define SND_RME_CLK_AES_SPDIF_MASK
#define SND_RME_CLK_SYNC_SHIFT
#define SND_RME_CLK_SYNC_MASK
#define SND_RME_CLK_FREQMUL_SHIFT
#define SND_RME_CLK_FREQMUL_MASK
#define SND_RME_CLK_SYSTEM(x)
#define SND_RME_CLK_AES(x)
#define SND_RME_CLK_SPDIF(x)
#define SND_RME_CLK_SYNC(x)
#define SND_RME_CLK_FREQMUL(x)
#define SND_RME_CLK_AES_LOCK
#define SND_RME_CLK_AES_SYNC
#define SND_RME_CLK_SPDIF_LOCK
#define SND_RME_CLK_SPDIF_SYNC
#define SND_RME_SPDIF_IF_SHIFT
#define SND_RME_SPDIF_FORMAT_SHIFT
#define SND_RME_BINARY_MASK
#define SND_RME_SPDIF_IF(x)
#define SND_RME_SPDIF_FORMAT(x)

static const u32 snd_rme_rate_table[] =;
/* maximum number of items for AES and S/PDIF rates for above table */
#define SND_RME_RATE_IDX_AES_SPDIF_NUM

enum snd_rme_domain {};

enum snd_rme_clock_status {};

static int snd_rme_read_value(struct snd_usb_audio *chip,
			      unsigned int item,
			      u32 *value)
{}

static int snd_rme_get_status1(struct snd_kcontrol *kcontrol,
			       u32 *status1)
{}

static int snd_rme_rate_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_sync_state_get(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_spdif_if_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_spdif_format_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_sync_source_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_current_freq_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{}

static int snd_rme_rate_info(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_info *uinfo)
{}

static int snd_rme_sync_state_info(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_info *uinfo)
{}

static int snd_rme_spdif_if_info(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_info *uinfo)
{}

static int snd_rme_spdif_format_info(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_info *uinfo)
{}

static int snd_rme_sync_source_info(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_info *uinfo)
{}

static const struct snd_kcontrol_new snd_rme_controls[] =;

static int snd_rme_controls_create(struct usb_mixer_interface *mixer)
{}

/*
 * RME Babyface Pro (FS)
 *
 * These devices exposes a couple of DSP functions via request to EP0.
 * Switches are available via control registers, while routing is controlled
 * by controlling the volume on each possible crossing point.
 * Volume control is linear, from -inf (dec. 0) to +6dB (dec. 65536) with
 * 0dB being at dec. 32768.
 */
enum {};

#define SND_BBFPRO_CTL_REG_MASK
#define SND_BBFPRO_CTL_IDX_MASK
#define SND_BBFPRO_CTL_IDX_SHIFT
#define SND_BBFPRO_CTL_VAL_MASK
#define SND_BBFPRO_CTL_VAL_SHIFT
#define SND_BBFPRO_CTL_REG1_CLK_MASTER
#define SND_BBFPRO_CTL_REG1_CLK_OPTICAL
#define SND_BBFPRO_CTL_REG1_SPDIF_PRO
#define SND_BBFPRO_CTL_REG1_SPDIF_EMPH
#define SND_BBFPRO_CTL_REG1_SPDIF_OPTICAL
#define SND_BBFPRO_CTL_REG2_48V_AN1
#define SND_BBFPRO_CTL_REG2_48V_AN2
#define SND_BBFPRO_CTL_REG2_SENS_IN3
#define SND_BBFPRO_CTL_REG2_SENS_IN4
#define SND_BBFPRO_CTL_REG2_PAD_AN1
#define SND_BBFPRO_CTL_REG2_PAD_AN2

#define SND_BBFPRO_MIXER_IDX_MASK
#define SND_BBFPRO_MIXER_VAL_MASK
#define SND_BBFPRO_MIXER_VAL_SHIFT
#define SND_BBFPRO_MIXER_VAL_MIN
#define SND_BBFPRO_MIXER_VAL_MAX

#define SND_BBFPRO_USBREQ_CTL_REG1
#define SND_BBFPRO_USBREQ_CTL_REG2
#define SND_BBFPRO_USBREQ_MIXER

static int snd_bbfpro_ctl_update(struct usb_mixer_interface *mixer, u8 reg,
				 u8 index, u8 value)
{}

static int snd_bbfpro_ctl_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_bbfpro_ctl_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{}

static int snd_bbfpro_ctl_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
{}

static int snd_bbfpro_vol_update(struct usb_mixer_interface *mixer, u16 index,
				 u32 value)
{}

static int snd_bbfpro_vol_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_bbfpro_vol_info(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_info *uinfo)
{}

static int snd_bbfpro_vol_put(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{}

static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
{}

// Predfine elements
static const struct snd_kcontrol_new snd_bbfpro_ctl_control =;

static const struct snd_kcontrol_new snd_bbfpro_vol_control =;

static int snd_bbfpro_ctl_add(struct usb_mixer_interface *mixer, u8 reg,
			      u8 index, char *name)
{}

static int snd_bbfpro_vol_add(struct usb_mixer_interface *mixer, u16 index,
			      char *name)
{}

static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
{}

/*
 * Pioneer DJ DJM Mixers
 *
 * These devices generally have options for soft-switching the playback and
 * capture sources in addition to the recording level. Although different
 * devices have different configurations, there seems to be canonical values
 * for specific capture/playback types:  See the definitions of these below.
 *
 * The wValue is masked with the stereo channel number. e.g. Setting Ch2 to
 * capture phono would be 0x0203. Capture, playback and capture level have
 * different wIndexes.
 */

// Capture types
#define SND_DJM_CAP_LINE
#define SND_DJM_CAP_CDLINE
#define SND_DJM_CAP_DIGITAL
#define SND_DJM_CAP_PHONO
#define SND_DJM_CAP_PFADER
#define SND_DJM_CAP_XFADERA
#define SND_DJM_CAP_XFADERB
#define SND_DJM_CAP_MIC
#define SND_DJM_CAP_AUX
#define SND_DJM_CAP_RECOUT
#define SND_DJM_CAP_NONE
#define SND_DJM_CAP_CH1PFADER
#define SND_DJM_CAP_CH2PFADER
#define SND_DJM_CAP_CH3PFADER
#define SND_DJM_CAP_CH4PFADER

// Playback types
#define SND_DJM_PB_CH1
#define SND_DJM_PB_CH2
#define SND_DJM_PB_AUX

#define SND_DJM_WINDEX_CAP
#define SND_DJM_WINDEX_CAPLVL
#define SND_DJM_WINDEX_PB

// kcontrol->private_value layout
#define SND_DJM_VALUE_MASK
#define SND_DJM_GROUP_MASK
#define SND_DJM_DEVICE_MASK
#define SND_DJM_GROUP_SHIFT
#define SND_DJM_DEVICE_SHIFT

// device table index
// used for the snd_djm_devices table, so please update accordingly
#define SND_DJM_250MK2_IDX
#define SND_DJM_750_IDX
#define SND_DJM_850_IDX
#define SND_DJM_900NXS2_IDX
#define SND_DJM_750MK2_IDX
#define SND_DJM_450_IDX


#define SND_DJM_CTL(_name, suffix, _default_value, _windex)

#define SND_DJM_DEVICE(suffix)


struct snd_djm_device {};

struct snd_djm_ctl {};

static const char *snd_djm_get_label_caplevel(u16 wvalue)
{
	switch (wvalue) {
	case 0x0000:	return "-19dB";
	case 0x0100:	return "-15dB";
	case 0x0200:	return "-10dB";
	case 0x0300:	return "-5dB";
	default:	return NULL;
	}
};

static const char *snd_djm_get_label_cap_common(u16 wvalue)
{
	switch (wvalue & 0x00ff) {
	case SND_DJM_CAP_LINE:		return "Control Tone LINE";
	case SND_DJM_CAP_CDLINE:	return "Control Tone CD/LINE";
	case SND_DJM_CAP_DIGITAL:	return "Control Tone DIGITAL";
	case SND_DJM_CAP_PHONO:		return "Control Tone PHONO";
	case SND_DJM_CAP_PFADER:	return "Post Fader";
	case SND_DJM_CAP_XFADERA:	return "Cross Fader A";
	case SND_DJM_CAP_XFADERB:	return "Cross Fader B";
	case SND_DJM_CAP_MIC:		return "Mic";
	case SND_DJM_CAP_RECOUT:	return "Rec Out";
	case SND_DJM_CAP_AUX:		return "Aux";
	case SND_DJM_CAP_NONE:		return "None";
	case SND_DJM_CAP_CH1PFADER:	return "Post Fader Ch1";
	case SND_DJM_CAP_CH2PFADER:	return "Post Fader Ch2";
	case SND_DJM_CAP_CH3PFADER:	return "Post Fader Ch3";
	case SND_DJM_CAP_CH4PFADER:	return "Post Fader Ch4";
	default:			return NULL;
	}
};

// The DJM-850 has different values for CD/LINE and LINE capture
// control options than the other DJM declared in this file.
static const char *snd_djm_get_label_cap_850(u16 wvalue)
{
	switch (wvalue & 0x00ff) {
	case 0x00:		return "Control Tone CD/LINE";
	case 0x01:		return "Control Tone LINE";
	default:		return snd_djm_get_label_cap_common(wvalue);
	}
};

static const char *snd_djm_get_label_cap(u8 device_idx, u16 wvalue)
{
	switch (device_idx) {
	case SND_DJM_850_IDX:		return snd_djm_get_label_cap_850(wvalue);
	default:			return snd_djm_get_label_cap_common(wvalue);
	}
};

static const char *snd_djm_get_label_pb(u16 wvalue)
{
	switch (wvalue & 0x00ff) {
	case SND_DJM_PB_CH1:	return "Ch1";
	case SND_DJM_PB_CH2:	return "Ch2";
	case SND_DJM_PB_AUX:	return "Aux";
	default:		return NULL;
	}
};

static const char *snd_djm_get_label(u8 device_idx, u16 wvalue, u16 windex)
{
	switch (windex) {
	case SND_DJM_WINDEX_CAPLVL:	return snd_djm_get_label_caplevel(wvalue);
	case SND_DJM_WINDEX_CAP:	return snd_djm_get_label_cap(device_idx, wvalue);
	case SND_DJM_WINDEX_PB:		return snd_djm_get_label_pb(wvalue);
	default:			return NULL;
	}
};

// common DJM capture level option values
static const u16 snd_djm_opts_cap_level[] =;


// DJM-250MK2
static const u16 snd_djm_opts_250mk2_cap1[] =;

static const u16 snd_djm_opts_250mk2_cap2[] =;

static const u16 snd_djm_opts_250mk2_cap3[] =;

static const u16 snd_djm_opts_250mk2_pb1[] =;
static const u16 snd_djm_opts_250mk2_pb2[] =;
static const u16 snd_djm_opts_250mk2_pb3[] =;

static const struct snd_djm_ctl snd_djm_ctls_250mk2[] =;


// DJM-450
static const u16 snd_djm_opts_450_cap1[] =;

static const u16 snd_djm_opts_450_cap2[] =;

static const u16 snd_djm_opts_450_cap3[] =;

static const u16 snd_djm_opts_450_pb1[] =;
static const u16 snd_djm_opts_450_pb2[] =;
static const u16 snd_djm_opts_450_pb3[] =;

static const struct snd_djm_ctl snd_djm_ctls_450[] =;


// DJM-750
static const u16 snd_djm_opts_750_cap1[] =;
static const u16 snd_djm_opts_750_cap2[] =;
static const u16 snd_djm_opts_750_cap3[] =;
static const u16 snd_djm_opts_750_cap4[] =;

static const struct snd_djm_ctl snd_djm_ctls_750[] =;


// DJM-850
static const u16 snd_djm_opts_850_cap1[] =;
static const u16 snd_djm_opts_850_cap2[] =;
static const u16 snd_djm_opts_850_cap3[] =;
static const u16 snd_djm_opts_850_cap4[] =;

static const struct snd_djm_ctl snd_djm_ctls_850[] =;


// DJM-900NXS2
static const u16 snd_djm_opts_900nxs2_cap1[] =;
static const u16 snd_djm_opts_900nxs2_cap2[] =;
static const u16 snd_djm_opts_900nxs2_cap3[] =;
static const u16 snd_djm_opts_900nxs2_cap4[] =;
static const u16 snd_djm_opts_900nxs2_cap5[] =;

static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] =;

// DJM-750MK2
static const u16 snd_djm_opts_750mk2_cap1[] =;
static const u16 snd_djm_opts_750mk2_cap2[] =;
static const u16 snd_djm_opts_750mk2_cap3[] =;
static const u16 snd_djm_opts_750mk2_cap4[] =;
static const u16 snd_djm_opts_750mk2_cap5[] =;

static const u16 snd_djm_opts_750mk2_pb1[] =;
static const u16 snd_djm_opts_750mk2_pb2[] =;
static const u16 snd_djm_opts_750mk2_pb3[] =;


static const struct snd_djm_ctl snd_djm_ctls_750mk2[] =;


static const struct snd_djm_device snd_djm_devices[] =;


static int snd_djm_controls_info(struct snd_kcontrol *kctl,
				struct snd_ctl_elem_info *info)
{}

static int snd_djm_controls_update(struct usb_mixer_interface *mixer,
				u8 device_idx, u8 group, u16 value)
{}

static int snd_djm_controls_get(struct snd_kcontrol *kctl,
				struct snd_ctl_elem_value *elem)
{}

static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem)
{}

static int snd_djm_controls_resume(struct usb_mixer_elem_list *list)
{}

static int snd_djm_controls_create(struct usb_mixer_interface *mixer,
		const u8 device_idx)
{}

int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
{}

void snd_usb_mixer_resume_quirk(struct usb_mixer_interface *mixer)
{}

void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
				    int unitid)
{}

static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
					 struct usb_mixer_elem_info *cval,
					 struct snd_kcontrol *kctl)
{}

void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
				  struct usb_mixer_elem_info *cval, int unitid,
				  struct snd_kcontrol *kctl)
{}