Commit fd28941c authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Takashi Iwai
Browse files

ALSA: usb-audio: Add new quirk FIXED_RATE for JBL Quantum810 Wireless

It seems that the firmware is broken and does not accept
the UAC_EP_CS_ATTR_SAMPLE_RATE URB. There is only one rate (48000Hz)
available in the descriptors for the output endpoint.

Create a new quirk QUIRK_FLAG_FIXED_RATE to skip the rate setup
when only one rate is available (fixed).

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216798


Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20221215153037.1163786-1-perex@perex.cz


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a95e163a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ struct snd_usb_endpoint {
	bool lowlatency_playback;	/* low-latency playback mode */
	bool need_setup;		/* (re-)need for hw_params? */
	bool need_prepare;		/* (re-)need for prepare? */
	bool fixed_rate;		/* skip rate setup */

	/* for hw constraints */
	const struct audioformat *cur_audiofmt;
+10 −6
Original line number Diff line number Diff line
@@ -769,7 +769,8 @@ struct snd_usb_endpoint *
snd_usb_endpoint_open(struct snd_usb_audio *chip,
		      const struct audioformat *fp,
		      const struct snd_pcm_hw_params *params,
		      bool is_sync_ep)
		      bool is_sync_ep,
		      bool fixed_rate)
{
	struct snd_usb_endpoint *ep;
	int ep_num = is_sync_ep ? fp->sync_ep : fp->endpoint;
@@ -825,6 +826,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
		ep->implicit_fb_sync = fp->implicit_fb;
		ep->need_setup = true;
		ep->need_prepare = true;
		ep->fixed_rate = fixed_rate;

		usb_audio_dbg(chip, "  channels=%d, rate=%d, format=%s, period_bytes=%d, periods=%d, implicit_fb=%d\n",
			      ep->cur_channels, ep->cur_rate,
@@ -1413,12 +1415,14 @@ static int init_sample_rate(struct snd_usb_audio *chip,
	if (clock && !clock->need_setup)
		return 0;

	if (!ep->fixed_rate) {
		err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt, rate);
		if (err < 0) {
			if (clock)
				clock->rate = 0; /* reset rate */
			return err;
		}
	}

	if (clock)
		clock->need_setup = false;
+2 −1
Original line number Diff line number Diff line
@@ -14,7 +14,8 @@ struct snd_usb_endpoint *
snd_usb_endpoint_open(struct snd_usb_audio *chip,
		      const struct audioformat *fp,
		      const struct snd_pcm_hw_params *params,
		      bool is_sync_ep);
		      bool is_sync_ep,
		      bool fixed_rate);
void snd_usb_endpoint_close(struct snd_usb_audio *chip,
			    struct snd_usb_endpoint *ep);
int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
+5 −1
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include "usbaudio.h"
#include "card.h"
#include "helper.h"
#include "pcm.h"
#include "implicit.h"

enum {
@@ -455,7 +456,8 @@ const struct audioformat *
snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
				     const struct audioformat *target,
				     const struct snd_pcm_hw_params *params,
				     int stream)
				     int stream,
				     bool *fixed_rate)
{
	struct snd_usb_substream *subs;
	const struct audioformat *fp, *sync_fmt = NULL;
@@ -483,6 +485,8 @@ snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
		}
	}

	if (fixed_rate)
		*fixed_rate = snd_usb_pcm_has_fixed_rate(subs);
	return sync_fmt;
}
+1 −1
Original line number Diff line number Diff line
@@ -9,6 +9,6 @@ const struct audioformat *
snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
				     const struct audioformat *target,
				     const struct snd_pcm_hw_params *params,
				     int stream);
				     int stream, bool *fixed_rate);

#endif /* __USBAUDIO_IMPLICIT_H */
Loading