hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/usb/clock.c
....@@ -1,20 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Clock domain and sample rate management functions
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
- *
184 */
195
206 #include <linux/bitops.h>
....@@ -165,16 +151,15 @@
165151 return ret;
166152 }
167153
168
-/*
169
- * Assume the clock is valid if clock source supports only one single sample
170
- * rate, the terminal is connected directly to it (there is no clock selector)
171
- * and clock type is internal. This is to deal with some Denon DJ controllers
172
- * that always reports that clock is invalid.
173
- */
174154 static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
175155 struct audioformat *fmt,
176156 int source_id)
177157 {
158
+ bool ret = false;
159
+ int count;
160
+ unsigned char data;
161
+ struct usb_device *dev = chip->dev;
162
+
178163 if (fmt->protocol == UAC_VERSION_2) {
179164 struct uac_clock_source_descriptor *cs_desc =
180165 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
....@@ -182,13 +167,51 @@
182167 if (!cs_desc)
183168 return false;
184169
185
- return (fmt->nr_rates == 1 &&
186
- (fmt->clock & 0xff) == cs_desc->bClockID &&
187
- (cs_desc->bmAttributes & 0x3) !=
188
- UAC_CLOCK_SOURCE_TYPE_EXT);
170
+ /*
171
+ * Assume the clock is valid if clock source supports only one
172
+ * single sample rate, the terminal is connected directly to it
173
+ * (there is no clock selector) and clock type is internal.
174
+ * This is to deal with some Denon DJ controllers that always
175
+ * reports that clock is invalid.
176
+ */
177
+ if (fmt->nr_rates == 1 &&
178
+ (fmt->clock & 0xff) == cs_desc->bClockID &&
179
+ (cs_desc->bmAttributes & 0x3) !=
180
+ UAC_CLOCK_SOURCE_TYPE_EXT)
181
+ return true;
189182 }
190183
191
- return false;
184
+ /*
185
+ * MOTU MicroBook IIc
186
+ * Sample rate changes takes more than 2 seconds for this device. Clock
187
+ * validity request returns false during that period.
188
+ */
189
+ if (chip->usb_id == USB_ID(0x07fd, 0x0004)) {
190
+ count = 0;
191
+
192
+ while ((!ret) && (count < 50)) {
193
+ int err;
194
+
195
+ msleep(100);
196
+
197
+ err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
198
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
199
+ UAC2_CS_CONTROL_CLOCK_VALID << 8,
200
+ snd_usb_ctrl_intf(chip) | (source_id << 8),
201
+ &data, sizeof(data));
202
+ if (err < 0) {
203
+ dev_warn(&dev->dev,
204
+ "%s(): cannot get clock validity for id %d\n",
205
+ __func__, source_id);
206
+ return false;
207
+ }
208
+
209
+ ret = !!data;
210
+ count++;
211
+ }
212
+ }
213
+
214
+ return ret;
192215 }
193216
194217 static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
....@@ -641,8 +664,13 @@
641664 * interface is active. */
642665 if (rate != prev_rate) {
643666 usb_set_interface(dev, iface, 0);
667
+
668
+ snd_vendor_set_interface(dev, alts, iface, 0);
669
+
644670 snd_usb_set_interface_quirk(dev);
645671 usb_set_interface(dev, iface, fmt->altsetting);
672
+
673
+ snd_vendor_set_interface(dev, alts, iface, fmt->altsetting);
646674 snd_usb_set_interface_quirk(dev);
647675 }
648676
....@@ -669,7 +697,7 @@
669697 else
670698 return 0;
671699 }
672
- /* fall through */
700
+ fallthrough;
673701 case UAC_VERSION_2:
674702 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate);
675703 }