|
@@ -35,105 +35,85 @@
|
|
|
#include "clock.h"
|
|
|
#include "quirks.h"
|
|
|
|
|
|
-static struct uac_clock_source_descriptor *
|
|
|
- snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static void *find_uac_clock_desc(struct usb_host_interface *iface, int id,
|
|
|
+ bool (*validator)(void *, int), u8 type)
|
|
|
{
|
|
|
- struct uac_clock_source_descriptor *cs = NULL;
|
|
|
+ void *cs = NULL;
|
|
|
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC2_CLOCK_SOURCE))) {
|
|
|
- if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
|
|
|
+ while ((cs = snd_usb_find_csint_desc(iface->extra, iface->extralen,
|
|
|
+ cs, type))) {
|
|
|
+ if (validator(cs, id))
|
|
|
return cs;
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-static struct uac3_clock_source_descriptor *
|
|
|
- snd_usb_find_clock_source_v3(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static bool validate_clock_source_v2(void *p, int id)
|
|
|
{
|
|
|
- struct uac3_clock_source_descriptor *cs = NULL;
|
|
|
-
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC3_CLOCK_SOURCE))) {
|
|
|
- if (cs->bClockID == clock_id)
|
|
|
- return cs;
|
|
|
- }
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ struct uac_clock_source_descriptor *cs = p;
|
|
|
+ return cs->bLength == sizeof(*cs) && cs->bClockID == id;
|
|
|
}
|
|
|
|
|
|
-static struct uac_clock_selector_descriptor *
|
|
|
- snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static bool validate_clock_source_v3(void *p, int id)
|
|
|
{
|
|
|
- struct uac_clock_selector_descriptor *cs = NULL;
|
|
|
-
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC2_CLOCK_SELECTOR))) {
|
|
|
- if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) {
|
|
|
- if (cs->bLength < 5 + cs->bNrInPins)
|
|
|
- return NULL;
|
|
|
- return cs;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ struct uac3_clock_source_descriptor *cs = p;
|
|
|
+ return cs->bLength == sizeof(*cs) && cs->bClockID == id;
|
|
|
}
|
|
|
|
|
|
-static struct uac3_clock_selector_descriptor *
|
|
|
- snd_usb_find_clock_selector_v3(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static bool validate_clock_selector_v2(void *p, int id)
|
|
|
{
|
|
|
- struct uac3_clock_selector_descriptor *cs = NULL;
|
|
|
-
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC3_CLOCK_SELECTOR))) {
|
|
|
- if (cs->bClockID == clock_id)
|
|
|
- return cs;
|
|
|
- }
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ struct uac_clock_selector_descriptor *cs = p;
|
|
|
+ return cs->bLength >= sizeof(*cs) && cs->bClockID == id &&
|
|
|
+ cs->bLength == 7 + cs->bNrInPins;
|
|
|
}
|
|
|
|
|
|
-static struct uac_clock_multiplier_descriptor *
|
|
|
- snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static bool validate_clock_selector_v3(void *p, int id)
|
|
|
{
|
|
|
- struct uac_clock_multiplier_descriptor *cs = NULL;
|
|
|
-
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC2_CLOCK_MULTIPLIER))) {
|
|
|
- if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
|
|
|
- return cs;
|
|
|
- }
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ struct uac3_clock_selector_descriptor *cs = p;
|
|
|
+ return cs->bLength >= sizeof(*cs) && cs->bClockID == id &&
|
|
|
+ cs->bLength == 11 + cs->bNrInPins;
|
|
|
}
|
|
|
|
|
|
-static struct uac3_clock_multiplier_descriptor *
|
|
|
- snd_usb_find_clock_multiplier_v3(struct usb_host_interface *ctrl_iface,
|
|
|
- int clock_id)
|
|
|
+static bool validate_clock_multiplier_v2(void *p, int id)
|
|
|
{
|
|
|
- struct uac3_clock_multiplier_descriptor *cs = NULL;
|
|
|
+ struct uac_clock_multiplier_descriptor *cs = p;
|
|
|
+ return cs->bLength == sizeof(*cs) && cs->bClockID == id;
|
|
|
+}
|
|
|
|
|
|
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
|
|
|
- ctrl_iface->extralen,
|
|
|
- cs, UAC3_CLOCK_MULTIPLIER))) {
|
|
|
- if (cs->bClockID == clock_id)
|
|
|
- return cs;
|
|
|
- }
|
|
|
+static bool validate_clock_multiplier_v3(void *p, int id)
|
|
|
+{
|
|
|
+ struct uac3_clock_multiplier_descriptor *cs = p;
|
|
|
+ return cs->bLength == sizeof(*cs) && cs->bClockID == id;
|
|
|
+}
|
|
|
|
|
|
- return NULL;
|
|
|
+#define DEFINE_FIND_HELPER(name, obj, validator, type) \
|
|
|
+static obj *name(struct usb_host_interface *iface, int id) \
|
|
|
+{ \
|
|
|
+ return find_uac_clock_desc(iface, id, validator, type); \
|
|
|
}
|
|
|
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_source,
|
|
|
+ struct uac_clock_source_descriptor,
|
|
|
+ validate_clock_source_v2, UAC2_CLOCK_SOURCE);
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_source_v3,
|
|
|
+ struct uac3_clock_source_descriptor,
|
|
|
+ validate_clock_source_v3, UAC3_CLOCK_SOURCE);
|
|
|
+
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_selector,
|
|
|
+ struct uac_clock_selector_descriptor,
|
|
|
+ validate_clock_selector_v2, UAC2_CLOCK_SELECTOR);
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_selector_v3,
|
|
|
+ struct uac3_clock_selector_descriptor,
|
|
|
+ validate_clock_selector_v3, UAC3_CLOCK_SELECTOR);
|
|
|
+
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier,
|
|
|
+ struct uac_clock_multiplier_descriptor,
|
|
|
+ validate_clock_multiplier_v2, UAC2_CLOCK_MULTIPLIER);
|
|
|
+DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier_v3,
|
|
|
+ struct uac3_clock_multiplier_descriptor,
|
|
|
+ validate_clock_multiplier_v3, UAC3_CLOCK_MULTIPLIER);
|
|
|
+
|
|
|
static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
|
|
|
{
|
|
|
unsigned char buf;
|