aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/endpoint.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2021-09-29 10:08:36 +0200
committerTakashi Iwai <tiwai@suse.de>2021-09-30 13:55:18 +0200
commit4e7cf1fbb34ecb472c073980458cbe413afd4d64 (patch)
tree058c5de079f8c9a3e2e1619c6550740d4b59508c /sound/usb/endpoint.c
parentALSA: hda: Use position buffer for SKL+ again (diff)
downloadlinux-dev-4e7cf1fbb34ecb472c073980458cbe413afd4d64.tar.xz
linux-dev-4e7cf1fbb34ecb472c073980458cbe413afd4d64.zip
ALSA: usb-audio: Restrict rates for the shared clocks
When a single clock source is shared among several endpoints, we have to keep the same rate on all active endpoints as long as the clock is being used. For dealing with such a case, this patch adds one more check in the hw params constraint for the rate to take the shared clocks into account. The current rate is evaluated from the endpoint list that applies the same clock source. BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190418 Link: https://lore.kernel.org/r/20210929080844.11583-2-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r--sound/usb/endpoint.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 533919a28856..29c4865966f5 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -722,6 +722,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
ep->cur_period_frames = params_period_size(params);
ep->cur_period_bytes = ep->cur_period_frames * ep->cur_frame_bytes;
ep->cur_buffer_periods = params_periods(params);
+ ep->cur_clock = fp->clock;
if (ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
endpoint_set_syncinterval(chip, ep);
@@ -833,6 +834,7 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
ep->altsetting = 0;
ep->cur_audiofmt = NULL;
ep->cur_rate = 0;
+ ep->cur_clock = 0;
ep->iface_ref = NULL;
usb_audio_dbg(chip, "EP 0x%x closed\n", ep->ep_num);
}
@@ -1340,6 +1342,25 @@ unlock:
return err;
}
+/* get the current rate set to the given clock by any endpoint */
+int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock)
+{
+ struct snd_usb_endpoint *ep;
+ int rate = 0;
+
+ if (!clock)
+ return 0;
+ mutex_lock(&chip->mutex);
+ list_for_each_entry(ep, &chip->ep_list, list) {
+ if (ep->cur_clock == clock && ep->cur_rate) {
+ rate = ep->cur_rate;
+ break;
+ }
+ }
+ mutex_unlock(&chip->mutex);
+ return rate;
+}
+
/**
* snd_usb_endpoint_start: start an snd_usb_endpoint
*