summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2019-05-09 07:09:05 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2019-05-09 07:09:05 +0000
commitdc76454c98e13b8c359be1c73b6f09d262485de6 (patch)
tree25cceefb69291ab5a5480abccb0f807fe07dc557 /sys/dev
parent35e958785fdbc6c9aa9fe4ef71e743732bcb1872 (diff)
When changing device rate, send request to the clock source unit.
Currently we send the request to the unit indicated as clock source of the terminals, which may be a clock selector unit that doesn't support the request. Fix this by following the clock source path until the clock source unit is found.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uaudio.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c
index 0f847bfa4c7..355e52bd67d 100644
--- a/sys/dev/usb/uaudio.c
+++ b/sys/dev/usb/uaudio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uaudio.c,v 1.143 2019/05/09 07:00:38 ratchov Exp $ */
+/* $OpenBSD: uaudio.c,v 1.144 2019/05/09 07:09:04 ratchov Exp $ */
/*
* Copyright (c) 2018 Alexandre Ratchov <alex@caoua.org>
*
@@ -1019,6 +1019,37 @@ uaudio_alt_getrates(struct uaudio_softc *sc, struct uaudio_alt *p)
}
/*
+ * return the clock unit of the given terminal unit (v2 only)
+ */
+int
+uaudio_clock_id(struct uaudio_softc *sc)
+{
+ struct uaudio_unit *u;
+
+ u = sc->clock;
+ while (1) {
+ if (u == NULL) {
+ DPRINTF("%s: NULL clock pointer\n", __func__);
+ return -1;
+ }
+ switch (u->type) {
+ case UAUDIO_AC_CLKSRC:
+ return u->id;
+ case UAUDIO_AC_CLKSEL:
+ u = u->clock;
+ break;
+ case UAUDIO_AC_CLKMULT:
+ case UAUDIO_AC_RATECONV:
+ u = u->src_list;
+ break;
+ default:
+ DPRINTF("%s: no clock\n", __func__);
+ return -1;
+ }
+ }
+}
+
+/*
* Return the rates bitmap of the given parameters setting
*/
int
@@ -2770,7 +2801,7 @@ uaudio_stream_open(struct uaudio_softc *sc, int dir,
struct usbd_interface *iface;
unsigned char req_buf[4];
unsigned int bpa, spf_max, min_blksz;
- int err, i;
+ int err, clock_id, i;
if (dir == AUMODE_PLAY) {
s = &sc->pstream;
@@ -2933,9 +2964,14 @@ uaudio_stream_open(struct uaudio_softc *sc, int dir,
req_buf[1] = sc->rate >> 8;
req_buf[2] = sc->rate >> 16;
req_buf[3] = sc->rate >> 24;
+ clock_id = uaudio_clock_id(sc);
+ if (clock_id < 0) {
+ printf("%s: can't get clock id\n", DEVNAME(sc));
+ goto failed;
+ }
if (!uaudio_req(sc, UT_WRITE_CLASS_INTERFACE,
UAUDIO_V2_REQ_CUR, UAUDIO_REQSEL_RATE, 0,
- sc->ctl_ifnum, sc->clock->id, req_buf, 4)) {
+ sc->ctl_ifnum, clock_id, req_buf, 4)) {
DPRINTF("%s: not setting clock rate\n", __func__);
}
break;