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

Commit 06ffc1eb authored by Eldad Zack's avatar Eldad Zack Committed by Takashi Iwai
Browse files

ALSA: usb-audio: UAC2: do clock validity check earlier



Move the check that parse_audio_format_rates_v2() do after
receiving the clock source entity ID directly into the find
function and add a validation flag to the function.

This patch does not introduce any logic flow change.

It is provided to allow introducing automatic clock switching
easier later. By moving this uac_clock_source_is_valid callsite,
2 additional callsites can be avoided.

Signed-off-by: default avatarEldad Zack <eldad@fogrefinery.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f6a8bc70
Loading
Loading
Loading
Loading
+18 −16
Original line number Original line Diff line number Diff line
@@ -131,7 +131,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
}
}


static int __uac_clock_find_source(struct snd_usb_audio *chip,
static int __uac_clock_find_source(struct snd_usb_audio *chip,
				   int entity_id, unsigned long *visited)
				   int entity_id, unsigned long *visited,
				   bool validate)
{
{
	struct uac_clock_source_descriptor *source;
	struct uac_clock_source_descriptor *source;
	struct uac_clock_selector_descriptor *selector;
	struct uac_clock_selector_descriptor *selector;
@@ -148,8 +149,15 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,


	/* first, see if the ID we're looking for is a clock source already */
	/* first, see if the ID we're looking for is a clock source already */
	source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
	source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
	if (source)
	if (source) {
		return source->bClockID;
		entity_id = source->bClockID;
		if (validate && !uac_clock_source_is_valid(chip, entity_id)) {
			snd_printk(KERN_ERR "usb-audio:%d: clock source %d is not valid, cannot use\n",
				   chip->dev->devnum, entity_id);
			return -ENXIO;
		}
		return entity_id;
	}


	selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
	selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
	if (selector) {
	if (selector) {
@@ -164,7 +172,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
		/* Selector values are one-based */
		/* Selector values are one-based */


		if (ret > selector->bNrInPins || ret < 1) {
		if (ret > selector->bNrInPins || ret < 1) {
			printk(KERN_ERR
			snd_printk(KERN_ERR
				"%s(): selector reported illegal value, id %d, ret %d\n",
				"%s(): selector reported illegal value, id %d, ret %d\n",
				__func__, selector->bClockID, ret);
				__func__, selector->bClockID, ret);


@@ -172,14 +180,14 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
		}
		}


		return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
		return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
					       visited);
					       visited, validate);
	}
	}


	/* FIXME: multipliers only act as pass-thru element for now */
	/* FIXME: multipliers only act as pass-thru element for now */
	multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
	multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
	if (multiplier)
	if (multiplier)
		return __uac_clock_find_source(chip, multiplier->bCSourceID,
		return __uac_clock_find_source(chip, multiplier->bCSourceID,
						visited);
						visited, validate);


	return -EINVAL;
	return -EINVAL;
}
}
@@ -195,11 +203,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
 *
 *
 * Returns the clock source UnitID (>=0) on success, or an error.
 * Returns the clock source UnitID (>=0) on success, or an error.
 */
 */
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
			      bool validate)
{
{
	DECLARE_BITMAP(visited, 256);
	DECLARE_BITMAP(visited, 256);
	memset(visited, 0, sizeof(visited));
	memset(visited, 0, sizeof(visited));
	return __uac_clock_find_source(chip, entity_id, visited);
	return __uac_clock_find_source(chip, entity_id, visited, validate);
}
}


static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@@ -275,18 +284,11 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
	struct usb_device *dev = chip->dev;
	struct usb_device *dev = chip->dev;
	__le32 data;
	__le32 data;
	int err, cur_rate, prev_rate;
	int err, cur_rate, prev_rate;
	int clock = snd_usb_clock_find_source(chip, fmt->clock);
	int clock = snd_usb_clock_find_source(chip, fmt->clock, true);


	if (clock < 0)
	if (clock < 0)
		return clock;
		return clock;


	if (!uac_clock_source_is_valid(chip, clock)) {
		/* TODO: should we try to find valid clock setups by ourself? */
		snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
			   dev->devnum, iface, fmt->altsetting, clock);
		return -ENXIO;
	}

	prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
	prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);


	data = cpu_to_le32(rate);
	data = cpu_to_le32(rate);
+2 −1
Original line number Original line Diff line number Diff line
@@ -5,6 +5,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
			     struct usb_host_interface *alts,
			     struct usb_host_interface *alts,
			     struct audioformat *fmt, int rate);
			     struct audioformat *fmt, int rate);


int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id,
			     bool validate);


#endif /* __USBAUDIO_CLOCK_H */
#endif /* __USBAUDIO_CLOCK_H */
+1 −1
Original line number Original line Diff line number Diff line
@@ -280,7 +280,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
	struct usb_device *dev = chip->dev;
	struct usb_device *dev = chip->dev;
	unsigned char tmp[2], *data;
	unsigned char tmp[2], *data;
	int nr_triplets, data_size, ret = 0;
	int nr_triplets, data_size, ret = 0;
	int clock = snd_usb_clock_find_source(chip, fp->clock);
	int clock = snd_usb_clock_find_source(chip, fp->clock, false);


	if (clock < 0) {
	if (clock < 0) {
		snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
		snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",