From: Eldad Zack <eldad@fogrefinery.com>
To: Takashi Iwai <tiwai@suse.de>, Daniel Mack <zonque@gmail.com>
Cc: Grant Diffey <gdiffey@gmail.com>,
Chris Cavey <chris-alsa@rauros.net>,
Eldad Zack <eldad@fogrefinery.com>,
Clemens Ladisch <clemens@ladisch.de>,
alsa-devel@alsa-project.org,
Felix Homann <linuxaudio@showlabor.de>,
George Willian Condomitti <georgecondomitti@gmail.com>,
Jeffrey Barish <jeff_barish@earthlink.net>
Subject: [PATCH sound-unstable] usb-audio: sync ep init fix for audioformat mismatch
Date: Mon, 3 Dec 2012 20:30:09 +0100 [thread overview]
Message-ID: <1354563009-1949-1-git-send-email-eldad@fogrefinery.com> (raw)
In-Reply-To: <alpine.LNX.2.00.1212031932420.1485@xoschi>
Commit 947d299686aa9cc8aecf749d54e8475c6e498956 , "ALSA: snd-usb:
properly initialize the sync endpoint", while correcting the
initialization of the sync endpoint when opening just the data
endpoint, prevents devices that has a sync endpoint, with a channel
number different than that of the data endpoint, from functioning.
Due to a different channel and period bytes count, attempting to
initialize the sync endpoint will fail at the usb host driver.
For example, when using xhci:
cannot submit urb 0, error -90: internal error
With this patch, if a sync endpoint has multiple audioformats, a
matching audioformat is preferred. An audioformat must be found
with at least one channel and support the requested sample rate
and PCM format, otherwise the stream will not be opened.
If the number of channels differ between the selected audioformat
and the requested format, adjust the period bytes count accordingly.
It is safe to perform the calculation on the basis of the channel
count, since the requested PCM audio format and the rate must be
supported by the selected audioformat.
Cc: Jeffrey Barish <jeff_barish@earthlink.net>
Cc: Daniel Mack <zonque@gmail.com>
Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
sound/usb/pcm.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 99 insertions(+), 7 deletions(-)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 5d3cf85..ec0318c 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -451,6 +451,103 @@ add_sync_ep:
}
/*
+ * Return the score of matching two audioformats.
+ * Veto the audioformat if:
+ * - It has no channels for some reason.
+ * - Requested PCM format is not supported.
+ * - Requested sample rate is not supported.
+ */
+static int match_endpoint_audioformats(struct audioformat *fp,
+ struct audioformat *match, int rate,
+ snd_pcm_format_t pcm_format)
+{
+ int i;
+ int score = 0;
+
+ if (fp->channels < 1) {
+ snd_printdd("%s: (fmt @%p) no channels\n", __func__, fp);
+ return 0;
+ }
+
+ if (!(fp->formats & (1ULL << pcm_format))) {
+ snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__,
+ fp, pcm_format);
+ return 0;
+ }
+
+ for (i = 0; i < fp->nr_rates; i++) {
+ if (fp->rate_table[i] == rate) {
+ score++;
+ break;
+ }
+ }
+ if (!score) {
+ snd_printdd("%s: (fmt @%p) no match for rate %d\n", __func__,
+ fp, rate);
+ return 0;
+ }
+
+ if (fp->channels == match->channels)
+ score++;
+
+ snd_printdd("%s: (fmt @%p) score %d\n", __func__, fp, score);
+
+ return score;
+}
+
+/*
+ * Configure the sync ep using the rate and pcm format of the data ep.
+ */
+static int configure_sync_endpoint(struct snd_usb_substream *subs)
+{
+ int ret;
+ struct audioformat *fp;
+ struct audioformat *sync_fp = NULL;
+ int cur_score = 0;
+ int sync_period_bytes = subs->period_bytes;
+ struct snd_usb_substream *sync_subs =
+ &subs->stream->substream[subs->direction ^ 1];
+
+ /* Try to find the best matching audioformat. */
+ list_for_each_entry(fp, &sync_subs->fmt_list, list) {
+ int score = match_endpoint_audioformats(fp, subs->cur_audiofmt,
+ subs->cur_rate, subs->pcm_format);
+
+ if (score > cur_score) {
+ sync_fp = fp;
+ cur_score = score;
+ }
+ }
+
+ if (unlikely(sync_fp == NULL)) {
+ snd_printk(KERN_ERR "%s: no valid audioformat for sync ep %x found\n",
+ __func__, sync_subs->ep_num);
+ return -EINVAL;
+ }
+
+ /*
+ * Recalculate the period bytes if channel number differ between
+ * data and sync ep audioformat.
+ */
+ if (sync_fp->channels != subs->channels) {
+ sync_period_bytes = (subs->period_bytes / subs->channels) *
+ sync_fp->channels;
+ snd_printdd("%s: adjusted sync ep period bytes (%d -> %d)\n",
+ __func__, subs->period_bytes, sync_period_bytes);
+ }
+
+ ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
+ subs->pcm_format,
+ sync_fp->channels,
+ sync_period_bytes,
+ subs->cur_rate,
+ sync_fp,
+ NULL);
+
+ return ret;
+}
+
+/*
* configure endpoint params
*
* called during initial setup and upon resume
@@ -472,13 +569,8 @@ static int configure_endpoint(struct snd_usb_substream *subs)
return ret;
if (subs->sync_endpoint)
- ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
- subs->pcm_format,
- subs->channels,
- subs->period_bytes,
- subs->cur_rate,
- subs->cur_audiofmt,
- NULL);
+ ret = configure_sync_endpoint(subs);
+
return ret;
}
--
1.7.8.6
next prev parent reply other threads:[~2012-12-03 19:30 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-28 22:55 [FT C400,PATCH RFC,v4 00/10] M-Audio Fast Track C400 Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 01/10] usb-audio: replace hardcoded value with const Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 02/10] usb-audio: correct sync ep init Eldad Zack
2012-11-29 8:02 ` Takashi Iwai
2012-12-01 22:47 ` Eldad Zack
2012-12-01 22:50 ` [PATCH sound-unstable] usb-audio: sync ep init fix for audioformat mistmatch Eldad Zack
2012-12-03 8:58 ` Takashi Iwai
2012-12-03 9:34 ` Daniel Mack
2012-12-03 9:43 ` Takashi Iwai
2012-12-03 18:48 ` Eldad Zack
2012-12-03 19:30 ` Eldad Zack [this message]
2012-12-04 7:18 ` [PATCH sound-unstable] usb-audio: sync ep init fix for audioformat mismatch Takashi Iwai
2012-12-06 21:34 ` Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 03/10] usb-audio: use sender stride for implicit feedback Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 04/10] usb-audio: add control index offset Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 05/10] usb-audio: skip UAC2 EFFECT_UNIT Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 06/10] usb-audio: parameterize FTU effect unit control Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 07/10] usb-audio: M-Audio Fast Track C400 quirks table Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 08/10] usb-audio: Fast Track C400 mixer ranges Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 09/10] usb-audio: Fast Track C400 mixer controls Eldad Zack
2012-11-28 22:55 ` [FT C400, PATCH RFC, v4 10/10] usb-audio: FT C400 sync playback EP to capture EP Eldad Zack
2012-11-29 7:53 ` [FT C400, PATCH RFC, v4 00/10] M-Audio Fast Track C400 Takashi Iwai
2012-11-30 14:06 ` Eldad Zack
2012-11-30 14:15 ` Takashi Iwai
2012-12-07 15:03 ` Felix Homann
2012-12-09 10:38 ` Eldad Zack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1354563009-1949-1-git-send-email-eldad@fogrefinery.com \
--to=eldad@fogrefinery.com \
--cc=alsa-devel@alsa-project.org \
--cc=chris-alsa@rauros.net \
--cc=clemens@ladisch.de \
--cc=gdiffey@gmail.com \
--cc=georgecondomitti@gmail.com \
--cc=jeff_barish@earthlink.net \
--cc=linuxaudio@showlabor.de \
--cc=tiwai@suse.de \
--cc=zonque@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.