Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7645bd6 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: usb-audio: Refactor clock finder helpers



There are lots of open-coded functions to find a clock source,
selector and multiplier.  Now there are both v2 and v3, so six
variants.

This patch refactors the code to use a common helper for the main
loop, and define each validator function for each target.
There is no functional change.

Fixes: 9a2fe9b8 ("ALSA: usb: initial USB Audio Device Class 3.0 support")
Reviewed-by: default avatarRuslan Bilovol <ruslan.bilovol@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a820ccbe
Loading
Loading
Loading
Loading
+53 −74
Original line number Diff line number Diff line
@@ -35,104 +35,83 @@
#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;
	struct uac_clock_source_descriptor *cs = p;
	return cs->bLength >= sizeof(*cs) && cs->bClockID == id;
}

	return NULL;
}

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;
		}
	struct uac3_clock_source_descriptor *cs = p;
	return cs->bClockID == id;
}

	return NULL;
}

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;
	struct uac_clock_selector_descriptor *cs = p;
	return cs->bLength >= sizeof(*cs) && cs->bClockID == id &&
		cs->bLength >= 5 + cs->bNrInPins;
}

	return NULL;
}

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;
	struct uac3_clock_selector_descriptor *cs = p;
	return cs->bClockID == id;
}

	return NULL;
}

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;

	while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
					     ctrl_iface->extralen,
					     cs, UAC3_CLOCK_MULTIPLIER))) {
		if (cs->bClockID == clock_id)
			return cs;
	struct uac_clock_multiplier_descriptor *cs = p;
	return cs->bLength >= sizeof(*cs) && cs->bClockID == id;
}

	return NULL;
}
static bool validate_clock_multiplier_v3(void *p, int id)
{
	struct uac3_clock_multiplier_descriptor *cs = p;
	return cs->bClockID == id;
}

#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)
{