Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Eldad Zack <eldad@fogrefinery.com>
To: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>,
	Clemens Ladisch <clemens@ladisch.de>,
	Daniel Mack <zonque@gmail.com>,
	Torstein Hegge <hegge@resisty.net>
Cc: alsa-devel@alsa-project.org, Eldad Zack <eldad@fogrefinery.com>
Subject: [PATCHv2 10/10] ALSA: usb-audio: UAC2: support read-only freq control
Date: Wed,  3 Apr 2013 23:18:58 +0200	[thread overview]
Message-ID: <1365023938-1461-11-git-send-email-eldad@fogrefinery.com> (raw)
In-Reply-To: <1365023938-1461-1-git-send-email-eldad@fogrefinery.com>

Some clocks might be read-only, e.g., external clocks (see also
UAC2 4.7.2.1).

In this case, setting the sample frequency will always fail
(even if the rate is equal to the current clock rate),
therefore do not write, but read the value and compare to the
requested rate.
If the clock is read only, avoid reading it twice.

If it doesn't match, return -ENXIO since the clock is invalid for
this configuration.

Signed-off-by: Eldad Zack <eldad@fogrefinery.com>
---
 sound/usb/clock.c | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index a694e1c..ae35e7d 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -347,6 +347,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 	__le32 data;
 	int err, cur_rate, prev_rate;
 	int clock;
+	bool writeable;
+	struct uac_clock_source_descriptor *cs_desc;
 
 	clock = snd_usb_clock_find_source(chip, fmt->clock, true);
 	if (clock < 0)
@@ -354,20 +356,33 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
 
 	prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
 
-	data = cpu_to_le32(rate);
-	if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
-				   USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
-				   UAC2_CS_CONTROL_SAM_FREQ << 8,
-				   snd_usb_ctrl_intf(chip) | (clock << 8),
-				   &data, sizeof(data))) < 0) {
-		snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n",
-			   dev->devnum, iface, fmt->altsetting, rate, err);
-		return err;
-	}
+	cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
+	writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1);
+	if (writeable) {
+		data = cpu_to_le32(rate);
+		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
+				      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+				      UAC2_CS_CONTROL_SAM_FREQ << 8,
+				      snd_usb_ctrl_intf(chip) | (clock << 8),
+				      &data, sizeof(data));
+		if (err < 0) {
+			snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2): err %d\n",
+				   dev->devnum, iface, fmt->altsetting, rate, err);
+			return err;
+		}
 
-	cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
+		cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock);
+	} else {
+		cur_rate = prev_rate;
+	}
 
 	if (cur_rate != rate) {
+		if (!writeable) {
+			snd_printk(KERN_WARNING
+				   "%d:%d:%d: freq mismatch (RO clock): req %d, clock runs @%d\n",
+				   dev->devnum, iface, fmt->altsetting, rate, cur_rate);
+			return -ENXIO;
+		}
 		snd_printd(KERN_WARNING
 			   "current rate %d is different from the runtime rate %d\n",
 			   cur_rate, rate);
-- 
1.8.1.5

  parent reply	other threads:[~2013-04-03 21:19 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-03 21:18 [PATCHv2 00/10] UAC2: Automatic clock switching Eldad Zack
2013-04-03 21:18 ` [PATCHv2 01/10] ALSA: usb-audio: convert list_for_each to entry variant Eldad Zack
2013-04-03 21:18 ` [PATCHv2 02/10] ALSA: usb-audio: neaten MODULE_DEVICE_TABLE placement Eldad Zack
2013-04-03 21:18 ` [PATCHv2 03/10] ALSA: usb-audio: neaten EXPORT_SYMBOLS placement Eldad Zack
2013-04-03 21:18 ` [PATCHv2 04/10] ALSA: usb-audio: spelling correction Eldad Zack
2013-04-03 21:18 ` [PATCHv2 05/10] ALSA: usb-audio: use endianness macros Eldad Zack
2013-04-03 21:18 ` [PATCHv2 06/10] ALSA: usb-audio: UAC2: do clock validity check earlier Eldad Zack
2013-04-03 21:18 ` [PATCHv2 07/10] ALSA: usb-audio: UAC2: try to find and switch to valid clock Eldad Zack
2013-04-03 21:18 ` [PATCHv2 08/10] ALSA: usb-audio: UAC2: auto clock selection module param Eldad Zack
2013-04-03 21:18 ` [PATCHv2 09/10] ALSA: usb-audio: show err in set_sample_rate_v2 debug Eldad Zack
2013-04-03 21:18 ` Eldad Zack [this message]
2013-04-04  6:56 ` [PATCHv2 00/10] UAC2: Automatic clock switching Takashi Iwai

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=1365023938-1461-11-git-send-email-eldad@fogrefinery.com \
    --to=eldad@fogrefinery.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=hegge@resisty.net \
    --cc=perex@perex.cz \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox