^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) * (Tentative) 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) * Mixer control part
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * TODOs, for both the mixer and the streaming interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * - support for UAC2 effect units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * - support for graphical equalizers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - RANGE and MEM set commands (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - RANGE and MEM interrupt dispatchers (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * - audio channel clustering (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - audio sample rate converter units (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * - proper handling of clock multipliers (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * - dispatch clock change notifications (UAC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * - stop PCM streams which use a clock that became invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * - stop PCM streams which use a clock selector that has changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - parse available sample rates again when clock sources changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/usb/audio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/usb/audio-v2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/usb/audio-v3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <sound/hwdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "usbaudio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "mixer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "helper.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "mixer_quirks.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "power.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MAX_ID_ELEMS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct usb_audio_term {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int chconfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct usbmix_name_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct mixer_build {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct snd_usb_audio *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct usb_mixer_interface *mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) DECLARE_BITMAP(termbitmap, MAX_ID_ELEMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct usb_audio_term oterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) const struct usbmix_selector_map *selector_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) USB_XU_CLOCK_RATE = 0xe301,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) USB_XU_CLOCK_SOURCE = 0xe302,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) USB_XU_DIGITAL_IO_STATUS = 0xe303,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) USB_XU_DEVICE_OPTIONS = 0xe304,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) USB_XU_DIRECT_MONITORING = 0xe305,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) USB_XU_METERING = 0xe306
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * manual mapping of mixer names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * if the mixer topology is too complicated and the parsed names are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * ambiguous, add the entries in usbmixer_maps.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #include "mixer_maps.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static const struct usbmix_name_map *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) find_map(const struct usbmix_name_map *p, int unitid, int control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for (; p->id; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (p->id == unitid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) (!control || !p->control || control == p->control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* get the mapped name if the unit matches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!p || !p->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) buflen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return strlcpy(buf, p->name, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* ignore the error value if ignore_ctl_error flag is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define filter_error(cval, err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ((cval)->head.mixer->ignore_ctl_error ? 0 : (err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* check whether the control should be ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) check_ignored_ctl(const struct usbmix_name_map *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!p || p->name || p->dB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 1;
^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) /* dB mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline void check_mapped_dB(const struct usbmix_name_map *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct usb_mixer_elem_info *cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (p && p->dB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cval->dBmin = p->dB->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) cval->dBmax = p->dB->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* get the mapped selector source name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int check_mapped_selector_name(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int index, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) const struct usbmix_selector_map *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!state->selector_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) for (p = state->selector_map; p->id; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (p->id == unitid && index < p->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return strlcpy(buf, p->names[index], buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^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) * find an audio control unit with the given unit id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void *find_audio_control_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned char unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* we just parse the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct uac_feature_unit_descriptor *hdr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) USB_DT_CS_INTERFACE)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (hdr->bLength >= 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) hdr->bDescriptorSubtype <= UAC3_SAMPLE_RATE_CONVERTER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) hdr->bUnitID == unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * copy a string with the given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int snd_usb_copy_string_desc(struct snd_usb_audio *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int index, char *buf, int maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int len = usb_string(chip->dev, index, buf, maxlen - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (len < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) buf[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * convert from the byte/word on usb descriptor to the zero-based integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) switch (cval->val_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case USB_MIXER_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) case USB_MIXER_INV_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return !val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case USB_MIXER_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) val &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case USB_MIXER_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) val &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (val >= 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) val -= 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case USB_MIXER_U16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) val &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case USB_MIXER_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) val &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (val >= 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) val -= 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * convert from the zero-based int to the byte/word for usb descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) switch (cval->val_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case USB_MIXER_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case USB_MIXER_INV_BOOLEAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return !val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case USB_MIXER_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case USB_MIXER_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case USB_MIXER_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case USB_MIXER_U16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return val & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0; /* not reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!cval->res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (val < cval->min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else if (val >= cval->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return (cval->max - cval->min + cval->res - 1) / cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return (val - cval->min) / cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return cval->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!cval->res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) val *= cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) val += cval->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (val > cval->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return cval->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int uac2_ctl_value_size(int val_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (val_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case USB_MIXER_S32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case USB_MIXER_U32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case USB_MIXER_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case USB_MIXER_U16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0; /* unreachable */
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * retrieve a mixer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static inline int mixer_ctrl_intf(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return get_iface_desc(mixer->hostif)->bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int validx, int *value_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct snd_usb_audio *chip = cval->head.mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned char buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int idx = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) while (timeout-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) validx, idx, buf, val_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (err >= val_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) } else if (err == -ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) usb_audio_dbg(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) request, validx, idx, cval->val_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int validx, int *value_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct snd_usb_audio *chip = cval->head.mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /* enough space for one range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned char buf[sizeof(__u16) + 3 * sizeof(__u32)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned char *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int idx = 0, ret, val_size, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) __u8 bRequest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) val_size = uac2_ctl_value_size(cval->val_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (request == UAC_GET_CUR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) bRequest = UAC2_CS_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) size = val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) bRequest = UAC2_CS_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) size = sizeof(__u16) + 3 * val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) memset(buf, 0, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) validx, idx, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) usb_audio_err(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) request, validx, idx, cval->val_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* FIXME: how should we handle multiple triplets here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case UAC_GET_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) val = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case UAC_GET_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) val = buf + sizeof(__u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case UAC_GET_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) val = buf + sizeof(__u16) + val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case UAC_GET_RES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) val = buf + sizeof(__u16) + val_size * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *value_ret = convert_signed_value(cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) snd_usb_combine_bytes(val, val_size));
^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 int get_ctl_value(struct usb_mixer_elem_info *cval, int request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int validx, int *value_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) validx += cval->idx_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return (cval->head.mixer->protocol == UAC_VERSION_1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) get_ctl_value_v1(cval, request, validx, value_ret) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) get_ctl_value_v2(cval, request, validx, value_ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int get_cur_ctl_value(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int validx, int *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return get_ctl_value(cval, UAC_GET_CUR, validx, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* channel = 0: master, 1 = first channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int channel, int *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return get_ctl_value(cval, UAC_GET_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) (cval->control << 8) | channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int snd_usb_get_cur_mix_value(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int channel, int index, int *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (cval->cached & (1 << channel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *value = cval->cache_val[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) err = get_cur_mix_raw(cval, channel, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (!cval->head.mixer->ignore_ctl_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) usb_audio_dbg(cval->head.mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "cannot get current value for control %d ch %d: err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) cval->control, channel, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) cval->cached |= 1 << channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) cval->cache_val[index] = *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * set a mixer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int request, int validx, int value_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct snd_usb_audio *chip = cval->head.mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) unsigned char buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int idx = 0, val_len, err, timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) validx += cval->idx_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (cval->head.mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) } else { /* UAC_VERSION_2/3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) val_len = uac2_ctl_value_size(cval->val_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (request != UAC_SET_CUR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) usb_audio_dbg(chip, "RANGE setting not yet supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) request = UAC2_CS_CUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) value_set = convert_bytes_value(cval, value_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) buf[0] = value_set & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) buf[1] = (value_set >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) buf[2] = (value_set >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) buf[3] = (value_set >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) err = snd_usb_lock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) while (timeout-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) err = snd_usb_ctl_msg(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) usb_sndctrlpipe(chip->dev, 0), request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) validx, idx, buf, val_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (err >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) } else if (err == -ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) request, validx, idx, cval->val_type, buf[0], buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static int set_cur_ctl_value(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int validx, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int snd_usb_set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int index, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) unsigned int read_only = (channel == 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cval->master_readonly :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) cval->ch_readonly & (1 << (channel - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (read_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) usb_audio_dbg(cval->head.mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) "%s(): channel %d of control %d is read_only\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) __func__, channel, cval->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^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) err = snd_usb_mixer_set_ctl_value(cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) UAC_SET_CUR, (cval->control << 8) | channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cval->cached |= 1 << channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) cval->cache_val[index] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * TLV callback for mixer volume controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned int size, unsigned int __user *_tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) DECLARE_TLV_DB_MINMAX(scale, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (size < sizeof(scale))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (cval->min_mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) scale[2] = cval->dBmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) scale[3] = cval->dBmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (copy_to_user(_tlv, scale, sizeof(scale)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * parser routines begin here...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int parse_audio_unit(struct mixer_build *state, int unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * check if the input/output channel routing is enabled on the given bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * used for mixer unit parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static int check_matrix_bitmap(unsigned char *bmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int ich, int och, int num_outs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int idx = ich * num_outs + och;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return bmap[idx >> 3] & (0x80 >> (idx & 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * add an alsa control element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * search and increment the index until an empty slot is found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * if failed, give up and free the control instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int snd_usb_mixer_add_list(struct usb_mixer_elem_list *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bool is_std_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct usb_mixer_interface *mixer = list->mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) kctl->id.index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) err = snd_ctl_add(mixer->chip->card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) list->kctl = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) list->is_std_info = is_std_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) list->next_id_elem = mixer->id_elems[list->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) mixer->id_elems[list->id] = list;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * get a terminal name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static struct iterm_name_combo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) } iterm_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) { 0x0300, "Output" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) { 0x0301, "Speaker" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) { 0x0302, "Headphone" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) { 0x0303, "HMD Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) { 0x0304, "Desktop Speaker" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) { 0x0305, "Room Speaker" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) { 0x0306, "Com Speaker" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) { 0x0307, "LFE" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) { 0x0600, "External In" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) { 0x0601, "Analog In" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) { 0x0602, "Digital In" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) { 0x0603, "Line" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) { 0x0604, "Legacy In" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) { 0x0605, "IEC958 In" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) { 0x0606, "1394 DA Stream" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) { 0x0607, "1394 DV Stream" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) { 0x0700, "Embedded" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) { 0x0701, "Noise Source" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) { 0x0702, "Equalization Noise" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) { 0x0703, "CD" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) { 0x0704, "DAT" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) { 0x0705, "DCC" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) { 0x0706, "MiniDisk" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) { 0x0707, "Analog Tape" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) { 0x0708, "Phonograph" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) { 0x0709, "VCR Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) { 0x070a, "Video Disk Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) { 0x070b, "DVD Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) { 0x070c, "TV Tuner Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) { 0x070d, "Satellite Rec Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) { 0x070e, "Cable Tuner Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) { 0x070f, "DSS Audio" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) { 0x0710, "Radio Receiver" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) { 0x0711, "Radio Transmitter" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) { 0x0712, "Multi-Track Recorder" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) { 0x0713, "Synthesizer" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) unsigned char *name, int maxlen, int term_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct iterm_name_combo *names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (iterm->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) len = snd_usb_copy_string_desc(chip, iterm->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) name, maxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* virtual type - not a real terminal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (iterm->type >> 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (term_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) switch (iterm->type >> 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case UAC3_SELECTOR_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) strcpy(name, "Selector");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case UAC3_PROCESSING_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) strcpy(name, "Process Unit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case UAC3_EXTENSION_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) strcpy(name, "Ext Unit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) case UAC3_MIXER_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) strcpy(name, "Mixer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return sprintf(name, "Unit %d", iterm->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) switch (iterm->type & 0xff00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case 0x0100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) strcpy(name, "PCM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case 0x0200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) strcpy(name, "Mic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case 0x0400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) strcpy(name, "Headset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case 0x0500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) strcpy(name, "Phone");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return 5;
^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) for (names = iterm_names; names->type; names++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (names->type == iterm->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) strcpy(name, names->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return strlen(names->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * Get logical cluster information for UAC3 devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static int get_cluster_channels_v3(struct mixer_build *state, unsigned int cluster_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct uac3_cluster_header_descriptor c_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) err = snd_usb_ctl_msg(state->chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) usb_rcvctrlpipe(state->chip->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) cluster_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) snd_usb_ctrl_intf(state->chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) &c_header, sizeof(c_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (err != sizeof(c_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return c_header.bNrChannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) usb_audio_err(state->chip, "cannot request logical cluster ID: %d (err: %d)\n", cluster_id, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * Get number of channels for a Mixer Unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int uac_mixer_unit_get_channels(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct uac_mixer_unit_descriptor *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int mu_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) switch (state->mixer->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (desc->bLength < sizeof(*desc) + desc->bNrInPins + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return 0; /* no bmControls -> skip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) mu_channels = uac_mixer_unit_bNrChannels(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) mu_channels = get_cluster_channels_v3(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) uac3_mixer_unit_wClusterDescrID(desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return mu_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * Parse Input Terminal Unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int __check_input_term(struct mixer_build *state, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct usb_audio_term *term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static int parse_term_uac1_iterm_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct uac_input_terminal_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) term->type = le16_to_cpu(d->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) term->channels = d->bNrChannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) term->chconfig = le16_to_cpu(d->wChannelConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) term->name = d->iTerminal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static int parse_term_uac2_iterm_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct uac2_input_terminal_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* call recursively to verify the referenced clock entity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) err = __check_input_term(state, d->bCSourceID, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /* save input term properties after recursion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * to ensure they are not overriden by the recursion calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) term->type = le16_to_cpu(d->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) term->channels = d->bNrChannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) term->chconfig = le32_to_cpu(d->bmChannelConfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) term->name = d->iTerminal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static int parse_term_uac3_iterm_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct uac3_input_terminal_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* call recursively to verify the referenced clock entity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) err = __check_input_term(state, d->bCSourceID, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* save input term properties after recursion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * to ensure they are not overriden by the recursion calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) term->type = le16_to_cpu(d->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err = get_cluster_channels_v3(state, le16_to_cpu(d->wClusterDescrID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) term->channels = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* REVISIT: UAC3 IT doesn't have channels cfg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) term->chconfig = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) term->name = le16_to_cpu(d->wTerminalDescrStr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static int parse_term_mixer_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct uac_mixer_unit_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) int protocol = state->mixer->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) err = uac_mixer_unit_get_channels(state, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (err <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) term->type = UAC3_MIXER_UNIT << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) term->channels = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (protocol != UAC_VERSION_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) term->chconfig = uac_mixer_unit_wChannelConfig(d, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) term->name = uac_mixer_unit_iMixer(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return 0;
^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) static int parse_term_selector_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct uac_selector_unit_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* call recursively to retrieve the channel info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) err = __check_input_term(state, d->baSourceID[0], term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) term->type = UAC3_SELECTOR_UNIT << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (state->mixer->protocol != UAC_VERSION_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) term->name = uac_selector_unit_iSelector(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static int parse_term_proc_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) void *p1, int id, int vtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct uac_processing_unit_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) int protocol = state->mixer->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (d->bNrInPins) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* call recursively to retrieve the channel info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) err = __check_input_term(state, d->baSourceID[0], term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) term->type = vtype << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (protocol == UAC_VERSION_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!term->channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) term->channels = uac_processing_unit_bNrChannels(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) term->chconfig = uac_processing_unit_wChannelConfig(d, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) term->name = uac_processing_unit_iProcessing(d, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static int parse_term_effect_unit(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct uac2_effect_unit_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) err = __check_input_term(state, d->bSourceID, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) term->type = UAC3_EFFECT_UNIT << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static int parse_term_uac2_clock_source(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct uac_clock_source_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) term->type = UAC3_CLOCK_SOURCE << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) term->name = d->iClockSource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int parse_term_uac3_clock_source(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) void *p1, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct uac3_clock_source_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) term->type = UAC3_CLOCK_SOURCE << 16; /* virtual type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) term->name = le16_to_cpu(d->wClockSourceStr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) #define PTYPE(a, b) ((a) << 8 | (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) * parse the source unit recursively until it reaches to a terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * or a branched unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static int __check_input_term(struct mixer_build *state, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct usb_audio_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) int protocol = state->mixer->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) void *p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) unsigned char *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* a loop in the terminal chain? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (test_and_set_bit(id, state->termbitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) p1 = find_audio_control_unit(state, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!p1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!snd_usb_validate_audio_desc(p1, protocol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) break; /* bad descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) hdr = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) term->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) switch (PTYPE(protocol, hdr[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) case PTYPE(UAC_VERSION_1, UAC_FEATURE_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) case PTYPE(UAC_VERSION_2, UAC_FEATURE_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) case PTYPE(UAC_VERSION_3, UAC3_FEATURE_UNIT): {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* the header is the same for all versions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct uac_feature_unit_descriptor *d = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) id = d->bSourceID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) break; /* continue to parse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case PTYPE(UAC_VERSION_1, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return parse_term_uac1_iterm_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case PTYPE(UAC_VERSION_2, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return parse_term_uac2_iterm_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case PTYPE(UAC_VERSION_3, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return parse_term_uac3_iterm_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) case PTYPE(UAC_VERSION_1, UAC_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) case PTYPE(UAC_VERSION_2, UAC_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) case PTYPE(UAC_VERSION_3, UAC3_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return parse_term_mixer_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) case PTYPE(UAC_VERSION_1, UAC_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) case PTYPE(UAC_VERSION_2, UAC_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) case PTYPE(UAC_VERSION_2, UAC2_CLOCK_SELECTOR):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) case PTYPE(UAC_VERSION_3, UAC3_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) case PTYPE(UAC_VERSION_3, UAC3_CLOCK_SELECTOR):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return parse_term_selector_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) case PTYPE(UAC_VERSION_1, UAC1_PROCESSING_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) case PTYPE(UAC_VERSION_2, UAC2_PROCESSING_UNIT_V2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) case PTYPE(UAC_VERSION_3, UAC3_PROCESSING_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return parse_term_proc_unit(state, term, p1, id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) UAC3_PROCESSING_UNIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) case PTYPE(UAC_VERSION_2, UAC2_EFFECT_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) case PTYPE(UAC_VERSION_3, UAC3_EFFECT_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return parse_term_effect_unit(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) case PTYPE(UAC_VERSION_1, UAC1_EXTENSION_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) case PTYPE(UAC_VERSION_2, UAC2_EXTENSION_UNIT_V2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case PTYPE(UAC_VERSION_3, UAC3_EXTENSION_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return parse_term_proc_unit(state, term, p1, id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) UAC3_EXTENSION_UNIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) case PTYPE(UAC_VERSION_2, UAC2_CLOCK_SOURCE):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return parse_term_uac2_clock_source(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) case PTYPE(UAC_VERSION_3, UAC3_CLOCK_SOURCE):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return parse_term_uac3_clock_source(state, term, p1, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return -ENODEV;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static int check_input_term(struct mixer_build *state, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct usb_audio_term *term)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) memset(term, 0, sizeof(*term));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) memset(state->termbitmap, 0, sizeof(state->termbitmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return __check_input_term(state, id, term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * Feature Unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* feature unit control information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct usb_feature_control_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) int control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) int type; /* data type for uac1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) int type_uac2; /* data type for uac2 if different from uac1, else -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static const struct usb_feature_control_info audio_feature_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) { UAC_FU_MUTE, "Mute", USB_MIXER_INV_BOOLEAN, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) { UAC_FU_VOLUME, "Volume", USB_MIXER_S16, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) { UAC_FU_BASS, "Tone Control - Bass", USB_MIXER_S8, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) { UAC_FU_MID, "Tone Control - Mid", USB_MIXER_S8, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) { UAC_FU_TREBLE, "Tone Control - Treble", USB_MIXER_S8, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) { UAC_FU_GRAPHIC_EQUALIZER, "Graphic Equalizer", USB_MIXER_S8, -1 }, /* FIXME: not implemented yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) { UAC_FU_AUTOMATIC_GAIN, "Auto Gain Control", USB_MIXER_BOOLEAN, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) { UAC_FU_DELAY, "Delay Control", USB_MIXER_U16, USB_MIXER_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) { UAC_FU_BASS_BOOST, "Bass Boost", USB_MIXER_BOOLEAN, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) { UAC_FU_LOUDNESS, "Loudness", USB_MIXER_BOOLEAN, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* UAC2 specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) { UAC2_FU_INPUT_GAIN, "Input Gain Control", USB_MIXER_S16, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) { UAC2_FU_INPUT_GAIN_PAD, "Input Gain Pad Control", USB_MIXER_S16, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) { UAC2_FU_PHASE_INVERTER, "Phase Inverter Control", USB_MIXER_BOOLEAN, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static void usb_mixer_elem_info_free(struct usb_mixer_elem_info *cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) kfree(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* private_free callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) void snd_usb_mixer_elem_free(struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) usb_mixer_elem_info_free(kctl->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) kctl->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * interface to ALSA control for feature/mixer units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /* volume control quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static void volume_control_quirks(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct snd_usb_audio *chip = cval->head.mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) switch (chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (strcmp(kctl->id.name, "Effect Duration") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) cval->min = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) cval->max = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cval->res = 0x00e6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) cval->min = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) cval->max = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (strstr(kctl->id.name, "Effect Return") != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) cval->min = 0xb706;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) cval->max = 0xff7b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) cval->res = 0x0073;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) (strstr(kctl->id.name, "Effect Send") != NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) cval->max = 0xfcfe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) cval->res = 0x0073;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (strcmp(kctl->id.name, "Effect Duration") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) "set quirk for FTU Effect Duration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) cval->min = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) cval->max = 0x7f00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) cval->res = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) "set quirks for FTU Effect Feedback/Volume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) cval->min = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) cval->max = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) case USB_ID(0x0d8c, 0x0103):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (!strcmp(kctl->id.name, "PCM Playback Volume")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) "set volume quirk for CM102-A+/102S+\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) cval->min = -256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case USB_ID(0x0471, 0x0101):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) case USB_ID(0x0471, 0x0104):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) case USB_ID(0x0471, 0x0105):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) case USB_ID(0x0672, 0x1041):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* quirk for UDA1321/N101.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * note that detection between firmware 2.1.1.7 (N101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * and later 2.1.1.21 is not very clear from datasheets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * I hope that the min value is -15360 for newer firmware --jk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) cval->min == -15616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) "set volume quirk for UDA1321/N101 chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) cval->max = -256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) case USB_ID(0x046d, 0x09a4):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) "set volume quirk for QuickCam E3500\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) cval->min = 6080;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) cval->max = 8768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) cval->res = 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) case USB_ID(0x046d, 0x0807): /* Logitech Webcam C500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) case USB_ID(0x046d, 0x0808):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) case USB_ID(0x046d, 0x0809):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) case USB_ID(0x046d, 0x0819): /* Logitech Webcam C210 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) case USB_ID(0x046d, 0x0991):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) case USB_ID(0x046d, 0x09a2): /* QuickCam Communicate Deluxe/S7500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /* Most audio usb devices lie about volume resolution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * Most Logitech webcams have res = 384.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * Probably there is some logitech magic behind this number --fishor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) usb_audio_info(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "set resolution quirk: cval->res = 384\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) cval->res = 384;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) strstr(kctl->id.name, "Capture Volume") != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) cval->min >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) cval->max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * retrieve the minimum and maximum values for the specified control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) int default_min, struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* for failsafe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) cval->min = default_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) cval->max = cval->min + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) cval->dBmin = cval->dBmax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (cval->val_type == USB_MIXER_BOOLEAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) cval->val_type == USB_MIXER_INV_BOOLEAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) int minchn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (cval->cmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) for (i = 0; i < MAX_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (cval->cmask & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) minchn = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^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) if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) usb_audio_err(cval->head.mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) "%d:%d: cannot get min/max values for control %d (id %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) cval->head.id, mixer_ctrl_intf(cval->head.mixer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) cval->control, cval->head.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (get_ctl_value(cval, UAC_GET_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) (cval->control << 8) | minchn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) &cval->res) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) int last_valid_res = cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) while (cval->res > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) (cval->control << 8) | minchn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) cval->res / 2) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) cval->res /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (get_ctl_value(cval, UAC_GET_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) (cval->control << 8) | minchn, &cval->res) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cval->res = last_valid_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (cval->res == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /* Additional checks for the proper resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * Some devices report smaller resolutions than actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * reacting. They don't return errors but simply clip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * to the lower aligned value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (cval->min + cval->res < cval->max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) int last_valid_res = cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) int saved, test, check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (get_cur_mix_raw(cval, minchn, &saved) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) goto no_res_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) test = saved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (test < cval->max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) test += cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) test -= cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (test < cval->min || test > cval->max ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) snd_usb_set_cur_mix_value(cval, minchn, 0, test) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) get_cur_mix_raw(cval, minchn, &check)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) cval->res = last_valid_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (test == check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) cval->res *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) snd_usb_set_cur_mix_value(cval, minchn, 0, saved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) no_res_check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) volume_control_quirks(cval, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* USB descriptions contain the dB scale in 1/256 dB unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * while ALSA TLV contains in 1/100 dB unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (cval->dBmin > cval->dBmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) /* something is wrong; assume it's either from/to 0dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (cval->dBmin < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) cval->dBmax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) else if (cval->dBmin > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) cval->dBmin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (cval->dBmin > cval->dBmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* totally crap, return an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* if the max volume is too low, it's likely a bogus range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * here we use -96dB as the threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (cval->dBmax <= -9600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) usb_audio_info(cval->head.mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) "%d:%d: bogus dB values (%d/%d), disabling dB reporting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) cval->head.id, mixer_ctrl_intf(cval->head.mixer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) cval->dBmin, cval->dBmax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) cval->dBmin = cval->dBmax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* get a feature/mixer unit info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (cval->val_type == USB_MIXER_BOOLEAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) cval->val_type == USB_MIXER_INV_BOOLEAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) uinfo->count = cval->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (cval->val_type == USB_MIXER_BOOLEAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) cval->val_type == USB_MIXER_INV_BOOLEAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (!cval->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) get_min_max_with_quirks(cval, 0, kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (cval->initialized && cval->dBmin >= cval->dBmax) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) kcontrol->vd[0].access &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) snd_ctl_notify(cval->head.mixer->chip->card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) SNDRV_CTL_EVENT_MASK_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) &kcontrol->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) uinfo->value.integer.max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) (cval->max - cval->min + cval->res - 1) / cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) /* get the current value from feature/mixer unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int c, cnt, val, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ucontrol->value.integer.value[0] = cval->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (cval->cmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) for (c = 0; c < MAX_CHANNELS; c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (!(cval->cmask & (1 << c)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) val = get_relative_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ucontrol->value.integer.value[cnt] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /* master channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) err = snd_usb_get_cur_mix_value(cval, 0, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) val = get_relative_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* put the current value to feature/mixer unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) int c, cnt, val, oval, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (cval->cmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) for (c = 0; c < MAX_CHANNELS; c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (!(cval->cmask & (1 << c)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) err = snd_usb_get_cur_mix_value(cval, c + 1, cnt, &oval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) val = ucontrol->value.integer.value[cnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) val = get_abs_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (oval != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) snd_usb_set_cur_mix_value(cval, c + 1, cnt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /* master channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) err = snd_usb_get_cur_mix_value(cval, 0, 0, &oval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) val = get_abs_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) snd_usb_set_cur_mix_value(cval, 0, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /* get the boolean value from the master channel of a UAC control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) static int mixer_ctl_master_bool_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) int val, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) err = snd_usb_get_cur_mix_value(cval, 0, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) val = (val != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* get the connectors status and report it as boolean type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) struct snd_usb_audio *chip = cval->head.mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) int idx = 0, validx, ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) validx = cval->control << 8 | 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) ret = snd_usb_lock_shutdown(chip) ? -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (cval->head.mixer->protocol == UAC_VERSION_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) struct uac2_connectors_ctl_blk uac2_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) validx, idx, &uac2_conn, sizeof(uac2_conn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) val = !!uac2_conn.bNrChannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) } else { /* UAC_VERSION_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) struct uac3_insertion_ctl_blk uac3_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) validx, idx, &uac3_conn, sizeof(uac3_conn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) val = !!uac3_conn.bmConInserted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) snd_usb_unlock_shutdown(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (strstr(kcontrol->id.name, "Speaker")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ucontrol->value.integer.value[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) usb_audio_err(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) "cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) UAC_GET_CUR, validx, idx, cval->val_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) return filter_error(cval, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ucontrol->value.integer.value[0] = val;
^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 const struct snd_kcontrol_new usb_feature_unit_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .name = "", /* will be filled later manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .info = mixer_ctl_feature_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) .get = mixer_ctl_feature_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .put = mixer_ctl_feature_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* the read-only variant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) .name = "", /* will be filled later manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) .info = mixer_ctl_feature_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) .get = mixer_ctl_feature_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) .put = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * A control which shows the boolean value from reading a UAC control on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * the master channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) static const struct snd_kcontrol_new usb_bool_master_control_ctl_ro = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .name = "", /* will be filled later manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) .get = mixer_ctl_master_bool_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) .put = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) static const struct snd_kcontrol_new usb_connector_ctl_ro = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) .name = "", /* will be filled later manually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) .access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .get = mixer_ctl_connector_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) .put = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * This symbol is exported in order to allow the mixer quirks to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * hook up to the standard feature unit control mechanism
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) const struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * build a feature control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^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) * A lot of headsets/headphones have a "Speaker" mixer. Make sure we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) * rename it to "Headphone". We determine if something is a headphone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * similar to how udev determines form factor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) const char *names_to_check[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) "Headset", "headset", "Headphone", "headphone", NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) const char **s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (strcmp("Speaker", kctl->id.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) for (s = names_to_check; *s; s++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (strstr(card->shortname, *s)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) static const struct usb_feature_control_info *get_feature_control_info(int control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) for (i = 0; i < ARRAY_SIZE(audio_feature_info); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (audio_feature_info[i].control == control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return &audio_feature_info[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static void __build_feature_ctl(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) const struct usbmix_name_map *imap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) unsigned int ctl_mask, int control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct usb_audio_term *iterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) struct usb_audio_term *oterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) int unitid, int nameid, int readonly_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) const struct usb_feature_control_info *ctl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) unsigned int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) int mapped_name = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) unsigned int range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (control == UAC_FU_GRAPHIC_EQUALIZER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* FIXME: not supported yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) map = find_map(imap, unitid, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (check_ignored_ctl(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) cval->control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) cval->cmask = ctl_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) ctl_info = get_feature_control_info(control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (!ctl_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (mixer->protocol == UAC_VERSION_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) cval->val_type = ctl_info->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) else /* UAC_VERSION_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) cval->val_type = ctl_info->type_uac2 >= 0 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) ctl_info->type_uac2 : ctl_info->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (ctl_mask == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) cval->channels = 1; /* master channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) cval->master_readonly = readonly_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) int i, c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (ctl_mask & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) c++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) cval->channels = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) cval->ch_readonly = readonly_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) * If all channels in the mask are marked read-only, make the control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * read-only. snd_usb_set_cur_mix_value() will check the mask again and won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) * issue write commands to read-only channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (cval->channels == readonly_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) usb_audio_err(mixer->chip, "cannot malloc kcontrol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) mapped_name = len != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (!len && nameid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) len = snd_usb_copy_string_desc(mixer->chip, nameid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) kctl->id.name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) switch (control) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) case UAC_FU_MUTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) case UAC_FU_VOLUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * determine the control name. the rule is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * - if a name id is given in descriptor, use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) * - if the connected input can be determined, then use the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) * of terminal type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) * - if the connected output can be determined, use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) * - otherwise, anonymous name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (iterm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) len = get_term_name(mixer->chip, iterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) sizeof(kctl->id.name), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (!len && oterm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) len = get_term_name(mixer->chip, oterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) sizeof(kctl->id.name), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) snprintf(kctl->id.name, sizeof(kctl->id.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) "Feature %d", unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (!mapped_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) check_no_speaker_on_headset(kctl, mixer->chip->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * determine the stream direction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * if the connected output is USB stream, then it's likely a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * capture stream. otherwise it should be playback (hopefully :)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (!mapped_name && oterm && !(oterm->type >> 16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if ((oterm->type & 0xff00) == 0x0100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) append_ctl_name(kctl, " Capture");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) append_ctl_name(kctl, " Playback");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) append_ctl_name(kctl, control == UAC_FU_MUTE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) " Switch" : " Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) strlcpy(kctl->id.name, audio_feature_info[control-1].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) /* get min/max values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) get_min_max_with_quirks(cval, 0, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) /* skip a bogus volume range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (cval->max <= cval->min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) usb_audio_dbg(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) "[%d] FU [%s] skipped due to invalid volume\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) cval->head.id, kctl->id.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) snd_ctl_free_one(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (control == UAC_FU_VOLUME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) check_mapped_dB(map, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (cval->dBmin < cval->dBmax || !cval->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) kctl->tlv.c = snd_usb_mixer_vol_tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) kctl->vd[0].access |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) SNDRV_CTL_ELEM_ACCESS_TLV_READ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) snd_usb_mixer_fu_apply_quirk(mixer, cval, unitid, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) range = (cval->max - cval->min) / cval->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * Are there devices with volume range more than 255? I use a bit more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) * to be sure. 384 is a resolution magic number found on Logitech
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) * devices. It will definitively catch all buggy Logitech devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (range > 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) usb_audio_warn(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) "Warning! Unlikely big volume range (=%u), cval->res is probably wrong.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) usb_audio_warn(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) "[%d] FU [%s] ch = %d, val = %d/%d/%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) cval->head.id, kctl->id.name, cval->channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) cval->min, cval->max, cval->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) usb_audio_dbg(mixer->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) cval->head.id, kctl->id.name, cval->channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) cval->min, cval->max, cval->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) unsigned int ctl_mask, int control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) struct usb_audio_term *iterm, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) int readonly_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) struct uac_feature_unit_descriptor *desc = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) int nameid = uac_feature_unit_iFeature(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) __build_feature_ctl(state->mixer, state->map, ctl_mask, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) iterm, &state->oterm, unitid, nameid, readonly_mask);
^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 void build_feature_ctl_badd(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) unsigned int ctl_mask, int control, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) const struct usbmix_name_map *badd_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) __build_feature_ctl(mixer, badd_map, ctl_mask, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) NULL, NULL, unitid, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) static void get_connector_control_name(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) struct usb_audio_term *term,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) bool is_input, char *name, int name_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) int name_len = get_term_name(mixer->chip, term, name, name_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (name_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) strlcpy(name, "Unknown", name_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * sound/core/ctljack.c has a convention of naming jack controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) * by ending in " Jack". Make it slightly more useful by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) * indicating Input or Output after the terminal name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (is_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) strlcat(name, " - Input Jack", name_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) strlcat(name, " - Output Jack", name_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) /* Build a mixer control for a UAC connector control (jack-detect) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) static void build_connector_control(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) const struct usbmix_name_map *imap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) struct usb_audio_term *term, bool is_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) map = find_map(imap, term->id, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (check_ignored_ctl(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) * UAC2: The first byte from reading the UAC2_TE_CONNECTOR control returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * number of channels connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) * UAC3: The first byte specifies size of bitmap for the inserted controls. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * following byte(s) specifies which connectors are inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * This boolean ctl will simply report if any channels are connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (mixer->protocol == UAC_VERSION_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) cval->control = UAC2_TE_CONNECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) else /* UAC_VERSION_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) cval->control = UAC3_TE_INSERTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) cval->val_type = USB_MIXER_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) cval->channels = 1; /* report true if any channel is connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) cval->min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) cval->max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) kctl = snd_ctl_new1(&usb_connector_ctl_ro, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) usb_audio_err(mixer->chip, "cannot malloc kcontrol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) strlcat(kctl->id.name, " Jack", sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) get_connector_control_name(mixer, term, is_input, kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static int parse_clock_source_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) void *_ftr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) struct uac_clock_source_descriptor *hdr = _ftr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (state->mixer->protocol != UAC_VERSION_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) * The only property of this unit we are interested in is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) * clock source validity. If that isn't readable, just bail out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (!uac_v2v3_control_is_readable(hdr->bmControls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) UAC2_CS_CONTROL_CLOCK_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) snd_usb_mixer_elem_init_std(&cval->head, state->mixer, hdr->bClockID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) cval->min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) cval->max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) cval->channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) cval->val_type = USB_MIXER_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) cval->control = UAC2_CS_CONTROL_CLOCK_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) cval->master_readonly = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /* From UAC2 5.2.5.1.2 "Only the get request is supported." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) kctl = snd_ctl_new1(&usb_bool_master_control_ctl_ro, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) ret = snd_usb_copy_string_desc(state->chip, hdr->iClockSource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) name, sizeof(name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) snprintf(kctl->id.name, sizeof(kctl->id.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) "%s Validity", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) snprintf(kctl->id.name, sizeof(kctl->id.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) "Clock Source %d Validity", hdr->bClockID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) return snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) * parse a feature unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) * most of controls are defined here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) void *_ftr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) int channels, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) struct usb_audio_term iterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) unsigned int master_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) int err, csize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) struct uac_feature_unit_descriptor *hdr = _ftr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) __u8 *bmaControls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (state->mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) csize = hdr->bControlSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) channels = (hdr->bLength - 7) / csize - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) bmaControls = hdr->bmaControls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) } else if (state->mixer->protocol == UAC_VERSION_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) struct uac2_feature_unit_descriptor *ftr = _ftr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) csize = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) channels = (hdr->bLength - 6) / 4 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) bmaControls = ftr->bmaControls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) } else { /* UAC_VERSION_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct uac3_feature_unit_descriptor *ftr = _ftr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) csize = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) channels = (ftr->bLength - 7) / 4 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) bmaControls = ftr->bmaControls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* parse the source unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) err = parse_audio_unit(state, hdr->bSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) /* determine the input source type and name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) err = check_input_term(state, hdr->bSourceID, &iterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) master_bits = snd_usb_combine_bytes(bmaControls, csize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) /* master configuration quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) switch (state->chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) case USB_ID(0x08bb, 0x2702):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) usb_audio_info(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) "usbmixer: master volume quirk for PCM2702 chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* disable non-functional volume control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) case USB_ID(0x1130, 0xf211):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) usb_audio_info(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /* disable non-functional volume control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) channels = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (state->mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /* check all control types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) unsigned int ch_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) int control = audio_feature_info[i].control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) for (j = 0; j < channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) mask = snd_usb_combine_bytes(bmaControls +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) csize * (j+1), csize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) if (mask & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) ch_bits |= (1 << j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) /* audio class v1 controls are never read-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * The first channel must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) * (for ease of programming).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (ch_bits & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) build_feature_ctl(state, _ftr, ch_bits, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) &iterm, unitid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (master_bits & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) build_feature_ctl(state, _ftr, 0, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) &iterm, unitid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) } else { /* UAC_VERSION_2/3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) unsigned int ch_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) unsigned int ch_read_only = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) int control = audio_feature_info[i].control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) for (j = 0; j < channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) mask = snd_usb_combine_bytes(bmaControls +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) csize * (j+1), csize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (uac_v2v3_control_is_readable(mask, control)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) ch_bits |= (1 << j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (!uac_v2v3_control_is_writeable(mask, control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) ch_read_only |= (1 << j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * NOTE: build_feature_ctl() will mark the control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) * read-only if all channels are marked read-only in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * the descriptors. Otherwise, the control will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) * reported as writeable, but the driver will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) * actually issue a write command for read-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) * channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) * The first channel must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) * (for ease of programming).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) if (ch_bits & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) build_feature_ctl(state, _ftr, ch_bits, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) &iterm, unitid, ch_read_only);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (uac_v2v3_control_is_readable(master_bits, control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) build_feature_ctl(state, _ftr, 0, control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) &iterm, unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) !uac_v2v3_control_is_writeable(master_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) control));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) * Mixer Unit
^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) /* check whether the given in/out overflows bmMixerControls matrix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) int protocol, int num_ins, int num_outs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) u8 *hdr = (u8 *)desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) u8 *c = uac_mixer_unit_bmControls(desc, protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) size_t rest; /* remaining bytes after bmMixerControls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) rest = 1; /* iMixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) rest = 2; /* bmControls + iMixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) rest = 6; /* bmControls + wMixerDescrStr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) /* overflow? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) * build a mixer unit control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) * the callbacks are identical with feature unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) * input channel number (zero based) is given in control field instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static void build_mixer_unit_ctl(struct mixer_build *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) struct uac_mixer_unit_descriptor *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) int in_pin, int in_ch, int num_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) int unitid, struct usb_audio_term *iterm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) unsigned int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) map = find_map(state->map, unitid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (check_ignored_ctl(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) cval->control = in_ch + 1; /* based on 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) cval->val_type = USB_MIXER_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) for (i = 0; i < num_outs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) __u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (check_matrix_bitmap(c, in_ch, i, num_outs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) cval->cmask |= (1 << i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) cval->channels++;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /* get min/max values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) get_min_max(cval, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) usb_audio_err(state->chip, "cannot malloc kcontrol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) len = get_term_name(state->chip, iterm, kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) sizeof(kctl->id.name), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) append_ctl_name(kctl, " Volume");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) usb_audio_dbg(state->chip, "[%d] MU [%s] ch = %d, val = %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) cval->head.id, kctl->id.name, cval->channels, cval->min, cval->max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) void *raw_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) struct usb_audio_term iterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) unsigned int control, bmctls, term_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) if (state->mixer->protocol == UAC_VERSION_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) struct uac2_input_terminal_descriptor *d_v2 = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) control = UAC2_TE_CONNECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) term_id = d_v2->bTerminalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) bmctls = le16_to_cpu(d_v2->bmControls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) } else if (state->mixer->protocol == UAC_VERSION_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) struct uac3_input_terminal_descriptor *d_v3 = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) control = UAC3_TE_INSERTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) term_id = d_v3->bTerminalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) bmctls = le32_to_cpu(d_v3->bmControls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) return 0; /* UAC1. No Insertion control */
^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) check_input_term(state, term_id, &iterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /* Check for jack detection. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) if ((iterm.type & 0xff00) != 0x0100 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) uac_v2v3_control_is_readable(bmctls, control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) build_connector_control(state->mixer, state->map, &iterm, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) * parse a mixer unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) void *raw_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) struct uac_mixer_unit_descriptor *desc = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) struct usb_audio_term iterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) int input_pins, num_ins, num_outs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) int pin, ich, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) err = uac_mixer_unit_get_channels(state, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) usb_audio_err(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) "invalid MIXER UNIT descriptor %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return err;
^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) num_outs = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) input_pins = desc->bNrInPins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) num_ins = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) ich = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) for (pin = 0; pin < input_pins; pin++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) err = parse_audio_unit(state, desc->baSourceID[pin]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) /* no bmControls field (e.g. Maya44) -> ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (!num_outs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) err = check_input_term(state, desc->baSourceID[pin], &iterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) num_ins += iterm.channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) if (mixer_bitmap_overflow(desc, state->mixer->protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) num_ins, num_outs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) for (; ich < num_ins; ich++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) int och, ich_has_controls = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) for (och = 0; och < num_outs; och++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) __u8 *c = uac_mixer_unit_bmControls(desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if (check_matrix_bitmap(c, ich, och, num_outs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) ich_has_controls = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) break;
^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) if (ich_has_controls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) build_mixer_unit_ctl(state, desc, pin, ich, num_outs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) unitid, &iterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) * Processing Unit / Extension Unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) /* get callback for processing/extension unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) int err, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) err = get_cur_ctl_value(cval, cval->control << 8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) ucontrol->value.integer.value[0] = cval->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) val = get_relative_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) /* put callback for processing/extension unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) int val, oval, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) err = get_cur_ctl_value(cval, cval->control << 8, &oval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) val = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) val = get_abs_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) set_cur_ctl_value(cval, cval->control << 8, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) /* alsa control interface for processing/extension unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static const struct snd_kcontrol_new mixer_procunit_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) .name = "", /* will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) .info = mixer_ctl_feature_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) .get = mixer_ctl_procunit_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) .put = mixer_ctl_procunit_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) * predefined data for processing units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) struct procunit_value_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) int control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) const char *suffix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) int val_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) int min_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) struct procunit_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) const struct procunit_value_info *values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) static const struct procunit_value_info undefined_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) { 0x00, "Control Undefined", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) static const struct procunit_value_info updown_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) static const struct procunit_value_info prologic_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) { UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) { UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) static const struct procunit_value_info threed_enh_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) { UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) { UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) static const struct procunit_value_info reverb_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) { UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) { UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) { UAC_REVERB_TIME, "Time", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) { UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static const struct procunit_value_info chorus_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) { UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) { UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) { UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) { UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) static const struct procunit_value_info dcr_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) { UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) { UAC_DCR_RATE, "Ratio", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) { UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) { UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) { UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) { UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) static const struct procunit_info procunits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) { UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) { UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) { UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) { UAC_PROCESS_REVERB, "Reverb", reverb_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) { UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) static const struct procunit_value_info uac3_updown_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) { UAC3_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static const struct procunit_value_info uac3_stereo_ext_proc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) { UAC3_EXT_WIDTH_CONTROL, "Width Control", USB_MIXER_U8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static const struct procunit_info uac3_procunits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) { UAC3_PROCESS_UP_DOWNMIX, "Up Down", uac3_updown_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) { UAC3_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", uac3_stereo_ext_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) { UAC3_PROCESS_MULTI_FUNCTION, "Multi-Function", undefined_proc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) };
^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) * predefined data for extension units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) static const struct procunit_value_info clock_rate_xu_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static const struct procunit_value_info clock_source_xu_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) static const struct procunit_value_info spdif_format_xu_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) static const struct procunit_value_info soft_limit_xu_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) static const struct procunit_info extunits[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) };
^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) * build a processing/extension unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) static int build_audio_procunit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) void *raw_desc, const struct procunit_info *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) bool extension_unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) struct uac_processing_unit_descriptor *desc = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) int num_ins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) int i, err, nameid, type, len, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) const struct procunit_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) const struct procunit_value_info *valinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) static const struct procunit_value_info default_value_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) { 0x01, "Switch", USB_MIXER_BOOLEAN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) static const struct procunit_info default_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 0, NULL, default_value_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) const char *name = extension_unit ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) "Extension Unit" : "Processing Unit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) num_ins = desc->bNrInPins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) for (i = 0; i < num_ins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) err = parse_audio_unit(state, desc->baSourceID[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) type = le16_to_cpu(desc->wProcessType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) for (info = list; info && info->type; info++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (info->type == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (!info || !info->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) info = &default_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) for (valinfo = info->values; valinfo->control; valinfo++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) if (state->mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) if (!(controls[valinfo->control / 8] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) (1 << ((valinfo->control % 8) - 1))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) } else { /* UAC_VERSION_2/3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) if (!uac_v2v3_control_is_readable(controls[valinfo->control / 8],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) valinfo->control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) map = find_map(state->map, unitid, valinfo->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (check_ignored_ctl(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) cval->control = valinfo->control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) cval->val_type = valinfo->val_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) cval->channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) if (state->mixer->protocol > UAC_VERSION_1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) !uac_v2v3_control_is_writeable(controls[valinfo->control / 8],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) valinfo->control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) cval->master_readonly = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) /* get min/max values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) case UAC_PROCESS_UP_DOWNMIX: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) bool mode_sel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) switch (state->mixer->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (cval->control == UAC_UD_MODE_SELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) mode_sel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (cval->control == UAC3_UD_MODE_SELECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) mode_sel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) break;
^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) if (mode_sel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) __u8 *control_spec = uac_processing_unit_specific(desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) cval->min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) cval->max = control_spec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) break;
^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) get_min_max(cval, valinfo->min_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) case USB_XU_CLOCK_RATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * E-Mu USB 0404/0202/TrackerPre/0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) * samplerate control quirk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) cval->min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) cval->max = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) get_min_max(cval, valinfo->min_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) err = get_cur_ctl_value(cval, cval->control << 8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) if (!kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) kctl->private_free = snd_usb_mixer_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) /* nothing */ ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) } else if (info->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) if (extension_unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) nameid = uac_extension_unit_iExtension(desc, state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) if (nameid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) len = snd_usb_copy_string_desc(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) nameid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) append_ctl_name(kctl, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) append_ctl_name(kctl, valinfo->suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) usb_audio_dbg(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) "[%d] PU [%s] ch = %d, val = %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) cval->head.id, kctl->id.name, cval->channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) cval->min, cval->max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) err = snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) static int parse_audio_processing_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) void *raw_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) switch (state->mixer->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) return build_audio_procunit(state, unitid, raw_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) procunits, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) return build_audio_procunit(state, unitid, raw_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) uac3_procunits, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) static int parse_audio_extension_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) void *raw_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * Note that we parse extension units with processing unit descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) * That's ok as the layout is the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) return build_audio_procunit(state, unitid, raw_desc, extunits, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) * Selector Unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) * info callback for selector unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) * use an enumerator type for routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) const char **itemlist = (const char **)kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (snd_BUG_ON(!itemlist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) /* get callback for selector unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) int val, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) err = get_cur_ctl_value(cval, cval->control << 8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) ucontrol->value.enumerated.item[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) val = get_relative_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) ucontrol->value.enumerated.item[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) /* put callback for selector unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) struct usb_mixer_elem_info *cval = kcontrol->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) int val, oval, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) err = get_cur_ctl_value(cval, cval->control << 8, &oval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) return filter_error(cval, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) val = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) val = get_abs_value(cval, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) if (val != oval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) set_cur_ctl_value(cval, cval->control << 8, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) /* alsa control interface for selector unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) static const struct snd_kcontrol_new mixer_selectunit_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) .name = "", /* will be filled later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) .info = mixer_ctl_selector_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) .get = mixer_ctl_selector_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) .put = mixer_ctl_selector_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) * private free callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) * free both private_data and private_value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) int i, num_ins = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) if (kctl->private_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) struct usb_mixer_elem_info *cval = kctl->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) num_ins = cval->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) kctl->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) if (kctl->private_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) char **itemlist = (char **)kctl->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) for (i = 0; i < num_ins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) kfree(itemlist[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) kfree(itemlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) kctl->private_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) * parse a selector unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) void *raw_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) struct uac_selector_unit_descriptor *desc = raw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) unsigned int i, nameid, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) struct usb_mixer_elem_info *cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) const struct usbmix_name_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) char **namelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) for (i = 0; i < desc->bNrInPins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) err = parse_audio_unit(state, desc->baSourceID[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) if (desc->bNrInPins == 1) /* only one ? nonsense! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) map = find_map(state->map, unitid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (check_ignored_ctl(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) cval = kzalloc(sizeof(*cval), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) if (!cval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) cval->val_type = USB_MIXER_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) cval->channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) cval->min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) cval->max = desc->bNrInPins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) cval->res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) cval->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) switch (state->mixer->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) cval->control = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) desc->bDescriptorSubtype == UAC3_CLOCK_SELECTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) cval->control = UAC2_CX_CLOCK_SELECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) else /* UAC2/3_SELECTOR_UNIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) cval->control = UAC2_SU_SELECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) namelist = kcalloc(desc->bNrInPins, sizeof(char *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (!namelist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) goto error_cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) #define MAX_ITEM_NAME_LEN 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) for (i = 0; i < desc->bNrInPins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) struct usb_audio_term iterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) if (!namelist[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) goto error_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) len = check_mapped_selector_name(state, unitid, i, namelist[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) MAX_ITEM_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) len = get_term_name(state->chip, &iterm, namelist[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) MAX_ITEM_NAME_LEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) if (! len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) sprintf(namelist[i], "Input %u", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (! kctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) usb_audio_err(state->chip, "cannot malloc kcontrol\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) goto error_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) kctl->private_value = (unsigned long)namelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) kctl->private_free = usb_mixer_selector_elem_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) /* check the static mapping table at first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) /* no mapping ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) switch (state->mixer->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) /* if iSelector is given, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) nameid = uac_selector_unit_iSelector(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) if (nameid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) len = snd_usb_copy_string_desc(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) nameid, kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) /* TODO: Class-Specific strings not yet supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) /* ... or pick up the terminal name at next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) len = get_term_name(state->chip, &state->oterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) kctl->id.name, sizeof(kctl->id.name), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) /* ... or use the fixed string "USB" as the last resort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) /* and add the proper suffix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) desc->bDescriptorSubtype == UAC3_CLOCK_SELECTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) append_ctl_name(kctl, " Clock Source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) else if ((state->oterm.type & 0xff00) == 0x0100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) append_ctl_name(kctl, " Capture Source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) append_ctl_name(kctl, " Playback Source");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) usb_audio_dbg(state->chip, "[%d] SU [%s] items = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) cval->head.id, kctl->id.name, desc->bNrInPins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) return snd_usb_mixer_add_control(&cval->head, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) error_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) for (i = 0; i < desc->bNrInPins; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) kfree(namelist[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) kfree(namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) error_cval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) usb_mixer_elem_info_free(cval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) }
^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) * parse an audio unit recursively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) static int parse_audio_unit(struct mixer_build *state, int unitid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) unsigned char *p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) int protocol = state->mixer->protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) if (test_and_set_bit(unitid, state->unitbitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) return 0; /* the unit already visited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) p1 = find_audio_control_unit(state, unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) if (!p1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) usb_audio_err(state->chip, "unit %d not found!\n", unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) if (!snd_usb_validate_audio_desc(p1, protocol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) usb_audio_dbg(state->chip, "invalid unit %d\n", unitid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) return 0; /* skip invalid unit */
^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) switch (PTYPE(protocol, p1[2])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) case PTYPE(UAC_VERSION_1, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) case PTYPE(UAC_VERSION_2, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) case PTYPE(UAC_VERSION_3, UAC_INPUT_TERMINAL):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) return parse_audio_input_terminal(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) case PTYPE(UAC_VERSION_1, UAC_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) case PTYPE(UAC_VERSION_2, UAC_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) case PTYPE(UAC_VERSION_3, UAC3_MIXER_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) return parse_audio_mixer_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) case PTYPE(UAC_VERSION_2, UAC2_CLOCK_SOURCE):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) case PTYPE(UAC_VERSION_3, UAC3_CLOCK_SOURCE):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) return parse_clock_source_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) case PTYPE(UAC_VERSION_1, UAC_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) case PTYPE(UAC_VERSION_2, UAC_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) case PTYPE(UAC_VERSION_3, UAC3_SELECTOR_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) case PTYPE(UAC_VERSION_2, UAC2_CLOCK_SELECTOR):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) case PTYPE(UAC_VERSION_3, UAC3_CLOCK_SELECTOR):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) return parse_audio_selector_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) case PTYPE(UAC_VERSION_1, UAC_FEATURE_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) case PTYPE(UAC_VERSION_2, UAC_FEATURE_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) case PTYPE(UAC_VERSION_3, UAC3_FEATURE_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) return parse_audio_feature_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) case PTYPE(UAC_VERSION_1, UAC1_PROCESSING_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) case PTYPE(UAC_VERSION_2, UAC2_PROCESSING_UNIT_V2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) case PTYPE(UAC_VERSION_3, UAC3_PROCESSING_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) return parse_audio_processing_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) case PTYPE(UAC_VERSION_1, UAC1_EXTENSION_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) case PTYPE(UAC_VERSION_2, UAC2_EXTENSION_UNIT_V2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) case PTYPE(UAC_VERSION_3, UAC3_EXTENSION_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) return parse_audio_extension_unit(state, unitid, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) case PTYPE(UAC_VERSION_2, UAC2_EFFECT_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) case PTYPE(UAC_VERSION_3, UAC3_EFFECT_UNIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) return 0; /* FIXME - effect units not implemented yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) usb_audio_err(state->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) "unit %u: unexpected type 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) unitid, p1[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) /* kill pending URBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) snd_usb_mixer_disconnect(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) kfree(mixer->id_elems);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (mixer->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) kfree(mixer->urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) usb_free_urb(mixer->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) usb_free_urb(mixer->rc_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) kfree(mixer->rc_setup_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) kfree(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) static int snd_usb_mixer_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) struct usb_mixer_interface *mixer = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) snd_usb_mixer_free(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) /* UAC3 predefined channels configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) struct uac3_badd_profile {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) int subclass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) int c_chmask; /* capture channels mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) int p_chmask; /* playback channels mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) int st_chmask; /* side tone mixing channel mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) static const struct uac3_badd_profile uac3_badd_profiles[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) * BAIF, BAOF or combination of both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) * IN: Mono or Stereo cfg, Mono alt possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) * OUT: Mono or Stereo cfg, Mono alt possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) .subclass = UAC3_FUNCTION_SUBCLASS_GENERIC_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) .name = "GENERIC IO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) .c_chmask = -1, /* dynamic channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) .p_chmask = -1, /* dynamic channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) /* BAOF; Stereo only cfg, Mono alt possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) .subclass = UAC3_FUNCTION_SUBCLASS_HEADPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) .name = "HEADPHONE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) .p_chmask = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) /* BAOF; Mono or Stereo cfg, Mono alt possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) .name = "SPEAKER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) .p_chmask = -1, /* dynamic channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) /* BAIF; Mono or Stereo cfg, Mono alt possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) .subclass = UAC3_FUNCTION_SUBCLASS_MICROPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) .name = "MICROPHONE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) .c_chmask = -1, /* dynamic channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) * BAIOF topology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) * IN: Mono only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) * OUT: Mono or Stereo cfg, Mono alt possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) .name = "HEADSET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) .c_chmask = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) .p_chmask = -1, /* dynamic channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) .st_chmask = 1,
^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) /* BAIOF; IN: Mono only; OUT: Stereo only, Mono alt possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) .subclass = UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) .name = "HEADSET ADAPTER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) .c_chmask = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) .p_chmask = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) .st_chmask = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) /* BAIF + BAOF; IN: Mono only; OUT: Mono only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) .subclass = UAC3_FUNCTION_SUBCLASS_SPEAKERPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) .name = "SPEAKERPHONE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) .c_chmask = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) .p_chmask = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) { 0 } /* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) static bool uac3_badd_func_has_valid_channels(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) const struct uac3_badd_profile *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) int c_chmask, int p_chmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * If both playback/capture channels are dynamic, make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * at least one channel is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) if (f->c_chmask < 0 && f->p_chmask < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) if (!c_chmask && !p_chmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) usb_audio_warn(mixer->chip, "BAAD %s: no channels?",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) f->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) if ((f->c_chmask < 0 && !c_chmask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) (f->c_chmask >= 0 && f->c_chmask != c_chmask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) usb_audio_warn(mixer->chip, "BAAD %s c_chmask mismatch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) f->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) if ((f->p_chmask < 0 && !p_chmask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) (f->p_chmask >= 0 && f->p_chmask != p_chmask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) usb_audio_warn(mixer->chip, "BAAD %s p_chmask mismatch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) f->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) * create mixer controls for UAC3 BADD profiles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) * UAC3 BADD device doesn't contain CS descriptors thus we will guess everything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) * BADD device may contain Mixer Unit, which doesn't have any controls, skip it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) int ctrlif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) struct usb_device *dev = mixer->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) struct usb_interface_assoc_descriptor *assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) int badd_profile = mixer->chip->badd_profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) const struct uac3_badd_profile *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) const struct usbmix_ctl_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) int p_chmask = 0, c_chmask = 0, st_chmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) assoc = usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) /* Detect BADD capture/playback channels from AS EP descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) for (i = 0; i < assoc->bInterfaceCount; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) int intf = assoc->bFirstInterface + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) struct usb_interface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) struct usb_host_interface *alts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) struct usb_interface_descriptor *altsd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) unsigned int maxpacksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) char dir_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) int chmask, num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) if (intf == ctrlif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) iface = usb_ifnum_to_if(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) if (!iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) num = iface->num_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) if (num < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) * The number of Channels in an AudioStreaming interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) * and the audio sample bit resolution (16 bits or 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) * bits) can be derived from the wMaxPacketSize field in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) * the Standard AS Audio Data Endpoint descriptor in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) * Alternate Setting 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) alts = &iface->altsetting[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) altsd = get_iface_desc(alts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) if (altsd->bNumEndpoints < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) /* check direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) dir_in = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) switch (maxpacksize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) usb_audio_err(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) "incorrect wMaxPacketSize 0x%x for BADD profile\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) maxpacksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) case UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) case UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) chmask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) case UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) case UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) chmask = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (dir_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) c_chmask = chmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) p_chmask = chmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) usb_audio_dbg(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) "UAC3 BADD profile 0x%x: detected c_chmask=%d p_chmask=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) badd_profile, c_chmask, p_chmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) /* check the mapping table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) for (map = uac3_badd_usbmix_ctl_maps; map->id; map++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) if (map->id == badd_profile)
^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) if (!map->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) for (f = uac3_badd_profiles; f->name; f++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) if (badd_profile == f->subclass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) if (!f->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (!uac3_badd_func_has_valid_channels(mixer, f, c_chmask, p_chmask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) st_chmask = f->st_chmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) /* Playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) if (p_chmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) /* Master channel, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) UAC3_BADD_FU_ID2, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) /* Mono/Stereo volume channels, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) build_feature_ctl_badd(mixer, p_chmask, UAC_FU_VOLUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) UAC3_BADD_FU_ID2, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) /* Capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if (c_chmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) /* Master channel, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) UAC3_BADD_FU_ID5, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) /* Mono/Stereo volume channels, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) build_feature_ctl_badd(mixer, c_chmask, UAC_FU_VOLUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) UAC3_BADD_FU_ID5, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) /* Side tone-mixing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) if (st_chmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) /* Master channel, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) build_feature_ctl_badd(mixer, 0, UAC_FU_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) UAC3_BADD_FU_ID7, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) /* Mono volume channel, always writable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) build_feature_ctl_badd(mixer, 1, UAC_FU_VOLUME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) UAC3_BADD_FU_ID7, map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) /* Insertion Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) if (f->subclass == UAC3_FUNCTION_SUBCLASS_HEADSET_ADAPTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) struct usb_audio_term iterm, oterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) /* Input Term - Insertion control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) memset(&iterm, 0, sizeof(iterm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) iterm.id = UAC3_BADD_IT_ID4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) build_connector_control(mixer, map->map, &iterm, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) /* Output Term - Insertion control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) memset(&oterm, 0, sizeof(oterm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) oterm.id = UAC3_BADD_OT_ID3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) oterm.type = UAC_BIDIR_TERMINAL_HEADSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) build_connector_control(mixer, map->map, &oterm, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) return 0;
^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) * create mixer controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) * walk through all UAC_OUTPUT_TERMINAL descriptors to search for mixers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) struct mixer_build state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) const struct usbmix_ctl_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) memset(&state, 0, sizeof(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) state.chip = mixer->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) state.mixer = mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) state.buffer = mixer->hostif->extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) state.buflen = mixer->hostif->extralen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) /* check the mapping table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) for (map = usbmix_ctl_maps; map->id; map++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (map->id == state.chip->usb_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) state.map = map->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) state.selector_map = map->selector_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) mixer->connector_map = map->connector_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) mixer->ignore_ctl_error |= map->ignore_ctl_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) while ((p = snd_usb_find_csint_desc(mixer->hostif->extra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) mixer->hostif->extralen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) p, UAC_OUTPUT_TERMINAL)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) if (!snd_usb_validate_audio_desc(p, mixer->protocol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) continue; /* skip invalid descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) if (mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) struct uac1_output_terminal_descriptor *desc = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) /* mark terminal ID as visited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) set_bit(desc->bTerminalID, state.unitbitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) state.oterm.id = desc->bTerminalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) state.oterm.type = le16_to_cpu(desc->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) state.oterm.name = desc->iTerminal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) err = parse_audio_unit(&state, desc->bSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) if (err < 0 && err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) } else if (mixer->protocol == UAC_VERSION_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) struct uac2_output_terminal_descriptor *desc = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) /* mark terminal ID as visited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) set_bit(desc->bTerminalID, state.unitbitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) state.oterm.id = desc->bTerminalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) state.oterm.type = le16_to_cpu(desc->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) state.oterm.name = desc->iTerminal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) err = parse_audio_unit(&state, desc->bSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) if (err < 0 && err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) * For UAC2, use the same approach to also add the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) * clock selectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) err = parse_audio_unit(&state, desc->bCSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) if (err < 0 && err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) if ((state.oterm.type & 0xff00) != 0x0100 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) UAC2_TE_CONNECTOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) build_connector_control(state.mixer, state.map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) &state.oterm, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) } else { /* UAC_VERSION_3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) struct uac3_output_terminal_descriptor *desc = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) /* mark terminal ID as visited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) set_bit(desc->bTerminalID, state.unitbitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) state.oterm.id = desc->bTerminalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) state.oterm.type = le16_to_cpu(desc->wTerminalType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) state.oterm.name = le16_to_cpu(desc->wTerminalDescrStr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) err = parse_audio_unit(&state, desc->bSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (err < 0 && err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) * For UAC3, use the same approach to also add the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) * clock selectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) err = parse_audio_unit(&state, desc->bCSourceID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) if (err < 0 && err != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) if ((state.oterm.type & 0xff00) != 0x0100 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) UAC3_TE_INSERTION)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) build_connector_control(state.mixer, state.map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) &state.oterm, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) static int delegate_notify(struct usb_mixer_interface *mixer, int unitid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) u8 *control, u8 *channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) const struct usbmix_connector_map *map = mixer->connector_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) return unitid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) for (; map->id; map++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) if (map->id == unitid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) if (control && map->control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) *control = map->control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) if (channel && map->channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) *channel = map->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) return map->delegated_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) return unitid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) unitid = delegate_notify(mixer, unitid, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) for_each_mixer_elem(list, mixer, unitid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) struct usb_mixer_elem_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) if (!list->is_std_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) info = mixer_elem_list_to_info(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) /* invalidate cache, so the value is read from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) info->cached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) &list->kctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) static const char * const val_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) [USB_MIXER_BOOLEAN] = "BOOLEAN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) [USB_MIXER_INV_BOOLEAN] = "INV_BOOLEAN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) [USB_MIXER_S8] = "S8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) [USB_MIXER_U8] = "U8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) [USB_MIXER_S16] = "S16",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) [USB_MIXER_U16] = "U16",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) [USB_MIXER_S32] = "S32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) [USB_MIXER_U32] = "U32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) [USB_MIXER_BESPOKEN] = "BESPOKEN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) "channels=%i, type=\"%s\"\n", cval->head.id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) cval->control, cval->cmask, cval->channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) val_types[cval->val_type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) cval->min, cval->max, cval->dBmin, cval->dBmax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) struct snd_usb_audio *chip = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) struct usb_mixer_interface *mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) int unitid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) list_for_each_entry(mixer, &chip->mixer_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) chip->usb_id, mixer_ctrl_intf(mixer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) mixer->ignore_ctl_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) for_each_mixer_elem(list, mixer, unitid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) snd_iprintf(buffer, " Unit: %i\n", list->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if (list->kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) " Control: name=\"%s\", index=%i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) list->kctl->id.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) list->kctl->id.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (list->dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) list->dump(buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) int attribute, int value, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) __u8 unitid = (index >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) __u8 control = (value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) __u8 channel = value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) if (channel >= MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) usb_audio_dbg(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) "%s(): bogus channel number %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) __func__, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) unitid = delegate_notify(mixer, unitid, &control, &channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) for_each_mixer_elem(list, mixer, unitid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) for_each_mixer_elem(list, mixer, unitid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) struct usb_mixer_elem_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) if (!list->kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) if (!list->is_std_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) info = mixer_elem_list_to_info(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) if (count > 1 && info->control != control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) switch (attribute) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) case UAC2_CS_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) /* invalidate cache, so the value is read from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) if (channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) info->cached &= ~(1 << channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) else /* master channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) info->cached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) &info->head.kctl->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) case UAC2_CS_RANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) case UAC2_CS_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) /* TODO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) usb_audio_dbg(mixer->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) "unknown attribute %d in interrupt\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) attribute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) } /* switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) static void snd_usb_mixer_interrupt(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) struct usb_mixer_interface *mixer = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) int len = urb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) int ustatus = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) if (ustatus != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) goto requeue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) if (mixer->protocol == UAC_VERSION_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) struct uac1_status_word *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) for (status = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) len >= sizeof(*status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) len -= sizeof(*status), status++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) dev_dbg(&urb->dev->dev, "status interrupt: %02x %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) status->bStatusType,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) status->bOriginator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* ignore any notifications not from the control interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) snd_usb_mixer_notify_id(mixer, status->bOriginator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) } else { /* UAC_VERSION_2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) struct uac2_interrupt_data_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) for (msg = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) len >= sizeof(*msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) len -= sizeof(*msg), msg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) /* drop vendor specific and endpoint requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) (msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) le16_to_cpu(msg->wValue),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) le16_to_cpu(msg->wIndex));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) requeue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) if (ustatus != -ENOENT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) ustatus != -ECONNRESET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) ustatus != -ESHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) urb->dev = mixer->chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) /* create the handler for the optional status interrupt endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) struct usb_endpoint_descriptor *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) void *transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) int buffer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) unsigned int epnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) /* we need one interrupt input endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) ep = get_endpoint(mixer->hostif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) epnum = usb_endpoint_num(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) buffer_length = le16_to_cpu(ep->wMaxPacketSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) if (!transfer_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) if (!mixer->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) kfree(transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) usb_fill_int_urb(mixer->urb, mixer->chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) usb_rcvintpipe(mixer->chip->dev, epnum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) transfer_buffer, buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) snd_usb_mixer_interrupt, mixer, ep->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) usb_submit_urb(mixer->urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) static int keep_iface_ctl_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) ucontrol->value.integer.value[0] = mixer->chip->keep_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) static int keep_iface_ctl_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) bool keep_iface = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (mixer->chip->keep_iface == keep_iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) mixer->chip->keep_iface = keep_iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) static const struct snd_kcontrol_new keep_iface_ctl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) .iface = SNDRV_CTL_ELEM_IFACE_CARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) .name = "Keep Interface",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) .info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) .get = keep_iface_ctl_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) .put = keep_iface_ctl_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) static int create_keep_iface_ctl(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) struct snd_kcontrol *kctl = snd_ctl_new1(&keep_iface_ctl, mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) /* need only one control per card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) if (snd_ctl_find_id(mixer->chip->card, &kctl->id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) snd_ctl_free_one(kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) return snd_ctl_add(mixer->chip->card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) int ignore_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) static const struct snd_device_ops dev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) .dev_free = snd_usb_mixer_dev_free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) struct usb_mixer_interface *mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) strcpy(chip->card->mixername, "USB Mixer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) if (!mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) mixer->chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) mixer->ignore_ctl_error = ignore_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) if (!mixer->id_elems) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) kfree(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) case UAC_VERSION_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) mixer->protocol = UAC_VERSION_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) case UAC_VERSION_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) mixer->protocol = UAC_VERSION_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) case UAC_VERSION_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) mixer->protocol = UAC_VERSION_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if (mixer->protocol == UAC_VERSION_3 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) chip->badd_profile >= UAC3_FUNCTION_SUBCLASS_GENERIC_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) err = snd_usb_mixer_controls_badd(mixer, ctrlif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) err = snd_usb_mixer_controls(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) err = snd_usb_mixer_status_create(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) err = create_keep_iface_ctl(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) err = snd_usb_mixer_apply_create_quirk(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) err = snd_device_new(chip->card, SNDRV_DEV_CODEC, mixer, &dev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) goto _error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) if (list_empty(&chip->mixer_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) snd_card_ro_proc_new(chip->card, "usbmixer", chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) snd_usb_mixer_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) list_add(&mixer->list, &chip->mixer_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) _error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) snd_usb_mixer_free(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) if (mixer->disconnected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) if (mixer->urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) usb_kill_urb(mixer->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) if (mixer->rc_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) usb_kill_urb(mixer->rc_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) if (mixer->private_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) mixer->private_free(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) mixer->disconnected = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) /* stop any bus activity of a mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) static void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) usb_kill_urb(mixer->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) usb_kill_urb(mixer->rc_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) static int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) if (mixer->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) err = usb_submit_urb(mixer->urb, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) snd_usb_mixer_inactivate(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) if (mixer->private_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) mixer->private_suspend(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) static int restore_mixer_value(struct usb_mixer_elem_list *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) int c, err, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) if (cval->val_type == USB_MIXER_BESPOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) if (cval->cmask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) for (c = 0; c < MAX_CHANNELS; c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) if (!(cval->cmask & (1 << c)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) if (cval->cached & (1 << (c + 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) err = snd_usb_set_cur_mix_value(cval, c + 1, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) cval->cache_val[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) /* master */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) if (cval->cached) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) err = snd_usb_set_cur_mix_value(cval, 0, 0, *cval->cache_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) struct usb_mixer_elem_list *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) int id, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) if (reset_resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) /* restore cached mixer values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) for (id = 0; id < MAX_ID_ELEMS; id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) for_each_mixer_elem(list, mixer, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) if (list->resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) err = list->resume(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) snd_usb_mixer_resume_quirk(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) return snd_usb_mixer_activate(mixer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) void snd_usb_mixer_elem_init_std(struct usb_mixer_elem_list *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) struct usb_mixer_interface *mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) int unitid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) list->mixer = mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) list->id = unitid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) list->dump = snd_usb_mixer_dump_cval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) list->resume = restore_mixer_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) }