From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/sound/usb/quirks.c | 423 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 382 insertions(+), 41 deletions(-)
diff --git a/kernel/sound/usb/quirks.c b/kernel/sound/usb/quirks.c
index 28f2880..7524221 100644
--- a/kernel/sound/usb/quirks.c
+++ b/kernel/sound/usb/quirks.c
@@ -1,17 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
@@ -19,6 +7,7 @@
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <linux/usb/midi.h>
+#include <linux/bits.h>
#include <sound/control.h>
#include <sound/core.h>
@@ -537,6 +526,15 @@
return 1; /* Continue with creating streams and mixer */
}
+static int setup_disable_autosuspend(struct snd_usb_audio *chip,
+ struct usb_interface *iface,
+ struct usb_driver *driver,
+ const struct snd_usb_audio_quirk *quirk)
+{
+ usb_disable_autosuspend(interface_to_usbdev(iface));
+ return 1; /* Continue with creating streams and mixer */
+}
+
/*
* audio-interface quirks
*
@@ -576,6 +574,7 @@
[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
[QUIRK_SETUP_FMT_AFTER_RESUME] = setup_fmt_after_resume_quirk,
+ [QUIRK_SETUP_DISABLE_AUTOSUSPEND] = setup_disable_autosuspend,
};
if (quirk->type < QUIRK_TYPE_COUNT) {
@@ -690,15 +689,133 @@
}
/*
- * C-Media CM6206 is based on CM106 with two additional
- * registers that are not documented in the data sheet.
- * Values here are chosen based on sniffing USB traffic
- * under Windows.
+ * CM6206 registers from the CM6206 datasheet rev 2.1
*/
+#define CM6206_REG0_DMA_MASTER BIT(15)
+#define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
+#define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
+/* Bit 4 thru 11 is the S/PDIF category code */
+#define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
+#define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
+#define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
+#define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
+#define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)
+
+#define CM6206_REG1_TEST_SEL_CLK BIT(14)
+#define CM6206_REG1_PLLBIN_EN BIT(13)
+#define CM6206_REG1_SOFT_MUTE_EN BIT(12)
+#define CM6206_REG1_GPIO4_OUT BIT(11)
+#define CM6206_REG1_GPIO4_OE BIT(10)
+#define CM6206_REG1_GPIO3_OUT BIT(9)
+#define CM6206_REG1_GPIO3_OE BIT(8)
+#define CM6206_REG1_GPIO2_OUT BIT(7)
+#define CM6206_REG1_GPIO2_OE BIT(6)
+#define CM6206_REG1_GPIO1_OUT BIT(5)
+#define CM6206_REG1_GPIO1_OE BIT(4)
+#define CM6206_REG1_SPDIFO_INVALID BIT(3)
+#define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
+#define CM6206_REG1_SPDIFO_DIS BIT(1)
+#define CM6206_REG1_SPDIFI_MIX BIT(0)
+
+#define CM6206_REG2_DRIVER_ON BIT(15)
+#define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
+#define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
+#define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
+#define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
+#define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
+#define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
+#define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
+#define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
+#define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
+#define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
+#define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
+#define CM6206_REG2_MUTE_CENTER BIT(5)
+#define CM6206_REG2_MUTE_RIGHT_FRONT BIT(3)
+#define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
+#define CM6206_REG2_EN_BTL BIT(2)
+#define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
+#define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
+#define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
+#define CM6206_REG2_MCUCLKSEL_12_MHZ (3)
+
+/* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
+#define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
+#define CM6206_REG3_VRAP25EN BIT(10)
+#define CM6206_REG3_MSEL1 BIT(9)
+#define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
+#define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
+#define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
+#define CM6206_REG3_PINSEL BIT(6)
+#define CM6206_REG3_FOE BIT(5)
+#define CM6206_REG3_ROE BIT(4)
+#define CM6206_REG3_CBOE BIT(3)
+#define CM6206_REG3_LOSE BIT(2)
+#define CM6206_REG3_HPOE BIT(1)
+#define CM6206_REG3_SPDIFI_CANREC BIT(0)
+
+#define CM6206_REG5_DA_RSTN BIT(13)
+#define CM6206_REG5_AD_RSTN BIT(12)
+#define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
+#define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
+#define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
+#define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
+#define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
+#define CM6206_REG5_CODECM BIT(8)
+#define CM6206_REG5_EN_HPF BIT(7)
+#define CM6206_REG5_T_SEL_DSDA4 BIT(6)
+#define CM6206_REG5_T_SEL_DSDA3 BIT(5)
+#define CM6206_REG5_T_SEL_DSDA2 BIT(4)
+#define CM6206_REG5_T_SEL_DSDA1 BIT(3)
+#define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
+#define CM6206_REG5_T_SEL_DSDAD_FRONT 4
+#define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
+#define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
+#define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7
+
static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
{
int err = 0, reg;
- int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
+ int val[] = {
+ /*
+ * Values here are chosen based on sniffing USB traffic
+ * under Windows.
+ *
+ * REG0: DAC is master, sample rate 48kHz, no copyright
+ */
+ CM6206_REG0_SPDIFO_RATE_48K |
+ CM6206_REG0_SPDIFO_COPYRIGHT_NA,
+ /*
+ * REG1: PLL binary search enable, soft mute enable.
+ */
+ CM6206_REG1_PLLBIN_EN |
+ CM6206_REG1_SOFT_MUTE_EN,
+ /*
+ * REG2: enable output drivers,
+ * select front channels to the headphone output,
+ * then mute the headphone channels, run the MCU
+ * at 1.5 MHz.
+ */
+ CM6206_REG2_DRIVER_ON |
+ CM6206_REG2_HEADP_SEL_FRONT_CHANNELS |
+ CM6206_REG2_MUTE_HEADPHONE_RIGHT |
+ CM6206_REG2_MUTE_HEADPHONE_LEFT,
+ /*
+ * REG3: default flyspeed, set 2.5V mic bias
+ * enable all line out ports and enable SPDIF
+ */
+ CM6206_REG3_FLYSPEED_DEFAULT |
+ CM6206_REG3_VRAP25EN |
+ CM6206_REG3_FOE |
+ CM6206_REG3_ROE |
+ CM6206_REG3_CBOE |
+ CM6206_REG3_LOSE |
+ CM6206_REG3_HPOE |
+ CM6206_REG3_SPDIFI_CANREC,
+ /* REG4 is just a bunch of GPIO lines */
+ 0x0000,
+ /* REG5: de-assert AD/DA reset signals */
+ CM6206_REG5_DA_RSTN |
+ CM6206_REG5_AD_RSTN };
for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
@@ -743,11 +860,13 @@
static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
{
int err, actual_length;
-
/* "midi send" enable */
static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
+ void *buf;
- void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
+ if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x05)))
+ return -EINVAL;
+ buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
if (!buf)
return -ENOMEM;
err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
@@ -772,7 +891,9 @@
static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
{
- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ int ret;
+
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1, 0, NULL, 0, 1000);
@@ -903,20 +1024,146 @@
return 0;
}
+
+#define MICROBOOK_BUF_SIZE 128
+
+static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf,
+ int buf_size, int *length)
+{
+ int err, actual_length;
+
+ if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x01)))
+ return -EINVAL;
+ err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length,
+ &actual_length, 1000);
+ if (err < 0)
+ return err;
+
+ print_hex_dump(KERN_DEBUG, "MicroBookII snd: ", DUMP_PREFIX_NONE, 16, 1,
+ buf, actual_length, false);
+
+ memset(buf, 0, buf_size);
+
+ if (usb_pipe_type_check(dev, usb_rcvintpipe(dev, 0x82)))
+ return -EINVAL;
+ err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size,
+ &actual_length, 1000);
+ if (err < 0)
+ return err;
+
+ print_hex_dump(KERN_DEBUG, "MicroBookII rcv: ", DUMP_PREFIX_NONE, 16, 1,
+ buf, actual_length, false);
+
+ *length = actual_length;
+ return 0;
+}
+
+static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
+{
+ int err, actual_length, poll_attempts = 0;
+ static const u8 set_samplerate_seq[] = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0b, 0x14,
+ 0x00, 0x00, 0x00, 0x01 };
+ static const u8 poll_ready_seq[] = { 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x0b, 0x18 };
+ u8 *buf = kzalloc(MICROBOOK_BUF_SIZE, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ dev_info(&dev->dev, "Waiting for MOTU Microbook II to boot up...\n");
+
+ /* First we tell the device which sample rate to use. */
+ memcpy(buf, set_samplerate_seq, sizeof(set_samplerate_seq));
+ actual_length = sizeof(set_samplerate_seq);
+ err = snd_usb_motu_microbookii_communicate(dev, buf, MICROBOOK_BUF_SIZE,
+ &actual_length);
+
+ if (err < 0) {
+ dev_err(&dev->dev,
+ "failed setting the sample rate for Motu MicroBook II: %d\n",
+ err);
+ goto free_buf;
+ }
+
+ /* Then we poll every 100 ms until the device informs of its readiness. */
+ while (true) {
+ if (++poll_attempts > 100) {
+ dev_err(&dev->dev,
+ "failed booting Motu MicroBook II: timeout\n");
+ err = -ENODEV;
+ goto free_buf;
+ }
+
+ memset(buf, 0, MICROBOOK_BUF_SIZE);
+ memcpy(buf, poll_ready_seq, sizeof(poll_ready_seq));
+
+ actual_length = sizeof(poll_ready_seq);
+ err = snd_usb_motu_microbookii_communicate(
+ dev, buf, MICROBOOK_BUF_SIZE, &actual_length);
+ if (err < 0) {
+ dev_err(&dev->dev,
+ "failed booting Motu MicroBook II: communication error %d\n",
+ err);
+ goto free_buf;
+ }
+
+ /* the device signals its readiness through a message of the
+ * form
+ * XX 06 00 00 00 00 0b 18 00 00 00 01
+ * If the device is not yet ready to accept audio data, the
+ * last byte of that sequence is 00.
+ */
+ if (actual_length == 12 && buf[actual_length - 1] == 1)
+ break;
+
+ msleep(100);
+ }
+
+ dev_info(&dev->dev, "MOTU MicroBook II ready\n");
+
+free_buf:
+ kfree(buf);
+ return err;
+}
+
+static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
+{
+ int ret;
+
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x0, 0, NULL, 0, 1000);
+
+ if (ret < 0)
+ return ret;
+
+ msleep(2000);
+
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x20, 0, NULL, 0, 1000);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
/*
* Setup quirks
*/
#define MAUDIO_SET 0x01 /* parse device_setup */
#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
-#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
+#define MAUDIO_SET_96K 0x04 /* 48-96kHz rate if set, 8-48kHz otherwise */
#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
-#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
-#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
-#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
-#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
+#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48kHz+Digital Input */
+#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48kHz+No Digital Input */
+#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48kHz+Digital Input */
+#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48kHz+No Digital Input */
static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
int iface, int altno)
@@ -1017,6 +1264,38 @@
return 0; /* keep this altsetting */
}
+static int s1810c_skip_setting_quirk(struct snd_usb_audio *chip,
+ int iface, int altno)
+{
+ /*
+ * Altno settings:
+ *
+ * Playback (Interface 1):
+ * 1: 6 Analog + 2 S/PDIF
+ * 2: 6 Analog + 2 S/PDIF
+ * 3: 6 Analog
+ *
+ * Capture (Interface 2):
+ * 1: 8 Analog + 2 S/PDIF + 8 ADAT
+ * 2: 8 Analog + 2 S/PDIF + 4 ADAT
+ * 3: 8 Analog
+ */
+
+ /*
+ * I'll leave 2 as the default one and
+ * use device_setup to switch to the
+ * other two.
+ */
+ if ((chip->setup == 0 || chip->setup > 2) && altno != 2)
+ return 1;
+ else if (chip->setup == 1 && altno != 1)
+ return 1;
+ else if (chip->setup == 2 && altno != 3)
+ return 1;
+
+ return 0;
+}
+
int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
int iface,
int altno)
@@ -1030,6 +1309,10 @@
/* fasttrackpro usb: skip altsets incompatible with device_setup */
if (chip->usb_id == USB_ID(0x0763, 0x2012))
return fasttrackpro_skip_setting_quirk(chip, iface, altno);
+ /* presonus studio 1810c: skip altsets incompatible with device_setup */
+ if (chip->usb_id == USB_ID(0x194f, 0x010c))
+ return s1810c_skip_setting_quirk(chip, iface, altno);
+
return 0;
}
@@ -1080,6 +1363,29 @@
return snd_usb_gamecon780_boot_quirk(dev);
case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */
return snd_usb_axefx3_boot_quirk(dev);
+ case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */
+ /*
+ * For some reason interface 3 with vendor-spec class is
+ * detected on MicroBook IIc.
+ */
+ if (get_iface_desc(intf->altsetting)->bInterfaceClass ==
+ USB_CLASS_VENDOR_SPEC &&
+ get_iface_desc(intf->altsetting)->bInterfaceNumber < 3)
+ return snd_usb_motu_microbookii_boot_quirk(dev);
+ break;
+ }
+
+ return 0;
+}
+
+int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
+ struct usb_interface *intf,
+ const struct snd_usb_audio_quirk *quirk,
+ unsigned int id)
+{
+ switch (id) {
+ case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
+ return snd_usb_motu_m_series_boot_quirk(dev);
}
return 0;
@@ -1164,6 +1470,30 @@
subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
}
+
+/*
+ * Pioneer DJ DJM-900NXS2
+ * Device needs to know the sample rate each time substream is started
+ */
+static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs)
+{
+
+ /* Convert sample rate value to little endian */
+ u8 sr[3];
+
+ sr[0] = subs->cur_rate & 0xff;
+ sr[1] = (subs->cur_rate >> 8) & 0xff;
+ sr[2] = (subs->cur_rate >> 16) & 0xff;
+
+ /* Configure device */
+ usb_set_interface(subs->dev, 0, 1);
+ snd_usb_ctl_msg(subs->stream->chip->dev,
+ usb_rcvctrlpipe(subs->stream->chip->dev, 0),
+ 0x01, 0x22, 0x0100, 0x0082, &sr, 0x0003);
+
+ return 0;
+}
+
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
struct audioformat *fmt)
{
@@ -1174,6 +1504,14 @@
case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
set_format_emu_quirk(subs, fmt);
break;
+ case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
+ case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
+ pioneer_djm_set_format_quirk(subs);
+ break;
+ case USB_ID(0x534d, 0x0021): /* MacroSilicon MS2100/MS2106 */
+ case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
+ subs->stream_offset_adj = 2;
+ break;
}
}
@@ -1181,18 +1519,15 @@
{
/* devices which do not support reading the sample rate. */
switch (chip->usb_id) {
- case USB_ID(0x041E, 0x4080): /* Creative Live Cam VF0610 */
- case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
+ case USB_ID(0x041e, 0x4080): /* Creative Live Cam VF0610 */
+ case USB_ID(0x04d8, 0xfeea): /* Benchmark DAC1 Pre */
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
- case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
+ case USB_ID(0x05a3, 0x9420): /* ELP HD USB Camera */
case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
-#ifdef CONFIG_HID_RKVR
- case USB_ID(0x071B, 0x3205): /* RockChip NanoC VR */
-#endif
- case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
+ case USB_ID(0x074d, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
- case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
+ case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */
case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */
case USB_ID(0x046d, 0x084c): /* Logitech ConferenceCam Connect */
@@ -1201,8 +1536,8 @@
/* devices of these vendors don't support reading rate, either */
switch (USB_ID_VENDOR(chip->usb_id)) {
- case 0x045E: /* MS Lifecam */
- case 0x047F: /* Plantronics */
+ case 0x045e: /* MS Lifecam */
+ case 0x047f: /* Plantronics */
case 0x1de7: /* Phoenix Audio */
return true;
}
@@ -1281,7 +1616,7 @@
/*
* M-Audio Fast Track C400/C600 - when packets are not skipped, real
- * world latency varies by approx. +/- 50 frames (at 96KHz) each time
+ * world latency varies by approx. +/- 50 frames (at 96kHz) each time
* the stream is (re)started. When skipping packets 16 at endpoint
* start up, the real world latency is stable within +/- 1 frame (also
* across power cycles).
@@ -1409,6 +1744,7 @@
/* XMOS based USB DACs */
switch (chip->usb_id) {
case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */
+ case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */
case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
if (fp->altsetting == 2)
@@ -1504,9 +1840,6 @@
int stream)
{
switch (chip->usb_id) {
-#ifdef CONFIG_HID_RKVR
- case USB_ID(0x071B, 0x3205): /* RockChip NanoC VR */
-#endif
case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
/* Optoplay sets the sample rate attribute although
* it seems not supporting it in fact.
@@ -1532,6 +1865,14 @@
fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
else
fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
+ break;
+ case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook IIc */
+ /*
+ * MaxPacketsOnly attribute is erroneously set in endpoint
+ * descriptors. As a result this card produces noise with
+ * all sample rates other than 96 kHz.
+ */
+ fp->attributes &= ~UAC_EP_CS_ATTR_FILL_MAX;
break;
}
}
@@ -1572,7 +1913,7 @@
for (q = registration_quirks; q->usb_id; q++)
if (chip->usb_id == q->usb_id)
- return iface != q->interface;
+ return iface < q->interface;
/* Register as normal */
return false;
--
Gitblit v1.6.2