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: Eldad Zack <eldad@fogrefinery.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
f6a8bc70f8
commit
06ffc1ebdd
3 changed files with 21 additions and 18 deletions
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in a new issue