diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2019-05-09 07:09:05 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2019-05-09 07:09:05 +0000 |
commit | dc76454c98e13b8c359be1c73b6f09d262485de6 (patch) | |
tree | 25cceefb69291ab5a5480abccb0f807fe07dc557 /sys/dev | |
parent | 35e958785fdbc6c9aa9fe4ef71e743732bcb1872 (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.c | 42 |
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; |