20 #include <linux/bitops.h>
22 #include <linux/string.h>
24 #include <linux/usb/audio.h>
37 snd_usb_find_clock_source(
struct usb_host_interface *ctrl_iface,
53 snd_usb_find_clock_selector(
struct usb_host_interface *ctrl_iface,
69 snd_usb_find_clock_multiplier(
struct usb_host_interface *ctrl_iface,
84 static int uac_clock_selector_get_val(
struct snd_usb_audio *
chip,
int selector_id)
93 snd_usb_ctrl_intf(chip) | (selector_id << 8),
102 static bool uac_clock_source_is_valid(
struct snd_usb_audio *chip,
int source_id)
106 struct usb_device *
dev = chip->
dev;
108 snd_usb_find_clock_source(chip->
ctrl_intf, source_id);
114 if (!uac2_control_is_readable(cs_desc->
bmControls,
121 snd_usb_ctrl_intf(chip) | (source_id << 8),
122 &data,
sizeof(data));
126 __func__, source_id);
133 static int __uac_clock_find_source(
struct snd_usb_audio *chip,
134 int entity_id,
unsigned long *visited)
144 "%s(): recursive clock topology detected, id %d.\n",
145 __func__, entity_id);
150 source = snd_usb_find_clock_source(chip->
ctrl_intf, entity_id);
154 selector = snd_usb_find_clock_selector(chip->
ctrl_intf, entity_id);
160 ret = uac_clock_selector_get_val(chip, selector->
bClockID);
166 if (ret > selector->
bNrInPins || ret < 1) {
168 "%s(): selector reported illegal value, id %d, ret %d\n",
174 return __uac_clock_find_source(chip, selector->
baCSourceID[ret-1],
179 multiplier = snd_usb_find_clock_multiplier(chip->
ctrl_intf, entity_id);
181 return __uac_clock_find_source(chip, multiplier->
bCSourceID,
201 memset(visited, 0,
sizeof(visited));
202 return __uac_clock_find_source(chip, entity_id, visited);
205 static int set_sample_rate_v1(
struct snd_usb_audio *chip,
int iface,
206 struct usb_host_interface *alts,
209 struct usb_device *dev = chip->
dev;
211 unsigned char data[3];
222 data[2] = rate >> 16;
226 data,
sizeof(data))) < 0) {
228 dev->devnum, iface, fmt->
altsetting, rate, ep);
235 data,
sizeof(data))) < 0) {
241 crate = data[0] | (data[1] << 8) | (data[2] << 16);
250 static int set_sample_rate_v2(
struct snd_usb_audio *chip,
int iface,
251 struct usb_host_interface *alts,
254 struct usb_device *dev = chip->
dev;
255 unsigned char data[4];
262 if (!uac_clock_source_is_valid(chip, clock)) {
271 data[2] = rate >> 16;
272 data[3] = rate >> 24;
276 snd_usb_ctrl_intf(chip) | (clock << 8),
277 data,
sizeof(data))) < 0) {
286 snd_usb_ctrl_intf(chip) | (clock << 8),
287 data,
sizeof(data))) < 0) {
293 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
301 struct usb_host_interface *alts,
309 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
312 return set_sample_rate_v2(chip, iface, alts, fmt, rate);