add code to recognize sync-pipe audio stream.
The code is not enabled yet.
This commit is contained in:
parent
211a72de86
commit
e61cc9d9a5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uaudio.c,v 1.79 2004/10/03 06:01:09 kent Exp $ */
|
||||
/* $NetBSD: uaudio.c,v 1.80 2004/10/16 18:08:50 kent Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
|
@ -44,7 +44,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.79 2004/10/03 06:01:09 kent Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.80 2004/10/16 18:08:50 kent Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -74,6 +74,8 @@ __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.79 2004/10/03 06:01:09 kent Exp $");
|
|||
|
||||
#include <dev/usb/uaudioreg.h>
|
||||
|
||||
/* #define UAUDIO_DEBUG */
|
||||
/* #define UAUDIO_MULTIPLE_ENDPOINTS */
|
||||
#ifdef UAUDIO_DEBUG
|
||||
#define DPRINTF(x) if (uaudiodebug) logprintf x
|
||||
#define DPRINTFN(n,x) if (uaudiodebug>(n)) logprintf x
|
||||
|
@ -118,6 +120,7 @@ struct as_info {
|
|||
usbd_interface_handle ifaceh;
|
||||
const usb_interface_descriptor_t *idesc;
|
||||
const usb_endpoint_descriptor_audio_t *edesc;
|
||||
const usb_endpoint_descriptor_audio_t *edesc1;
|
||||
const struct usb_audio_streaming_type1_descriptor *asf1desc;
|
||||
int sc_busy; /* currently used */
|
||||
};
|
||||
|
@ -1098,9 +1101,10 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
|
|||
const struct usb_audio_streaming_interface_descriptor *asid;
|
||||
const struct usb_audio_streaming_type1_descriptor *asf1d;
|
||||
const usb_endpoint_descriptor_audio_t *ed;
|
||||
const usb_endpoint_descriptor_audio_t *epdesc1;
|
||||
const struct usb_audio_streaming_endpoint_descriptor *sed;
|
||||
int format, chan, prec, enc;
|
||||
int dir, type;
|
||||
int dir, type, sync;
|
||||
struct as_info ai;
|
||||
const char *format_str;
|
||||
|
||||
|
@ -1131,7 +1135,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
|
|||
ed = (const void *)(buf + offs);
|
||||
if (ed->bDescriptorType != UDESC_ENDPOINT)
|
||||
return (USBD_INVAL);
|
||||
DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
|
||||
DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
|
||||
"bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
|
||||
"bInterval=%d bRefresh=%d bSynchAddress=%d\n",
|
||||
ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
|
||||
|
@ -1150,25 +1154,80 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
|
|||
type = UE_ISO_ASYNC;
|
||||
|
||||
/* We can't handle endpoints that need a sync pipe yet. */
|
||||
sync = FALSE;
|
||||
if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
|
||||
sync = TRUE;
|
||||
#ifndef UAUDIO_MULTIPLE_ENDPOINTS
|
||||
printf("%s: ignored input endpoint of type adaptive\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return (USBD_NORMAL_COMPLETION);
|
||||
#endif
|
||||
}
|
||||
if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
|
||||
sync = TRUE;
|
||||
#ifndef UAUDIO_MULTIPLE_ENDPOINTS
|
||||
printf("%s: ignored output endpoint of type async\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return (USBD_NORMAL_COMPLETION);
|
||||
#endif
|
||||
}
|
||||
|
||||
sed = (const void *)(buf + offs);
|
||||
if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
|
||||
sed->bDescriptorSubtype != AS_GENERAL)
|
||||
return (USBD_INVAL);
|
||||
DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
|
||||
offs += sed->bLength;
|
||||
if (offs > size)
|
||||
return (USBD_INVAL);
|
||||
|
||||
if (sync && id->bNumEndpoints <= 1) {
|
||||
printf("%s: a sync-pipe endpoint but no other endpoint\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return USBD_INVAL;
|
||||
}
|
||||
if (!sync && id->bNumEndpoints > 1) {
|
||||
printf("%s: non sync-pipe endpoint but multiple endpoints\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return USBD_INVAL;
|
||||
}
|
||||
epdesc1 = NULL;
|
||||
if (id->bNumEndpoints > 1) {
|
||||
epdesc1 = (const void*)(buf + offs);
|
||||
if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
|
||||
return USBD_INVAL;
|
||||
DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
|
||||
"bDescriptorType=%d bEndpointAddress=%d "
|
||||
"bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
|
||||
"bRefresh=%d bSynchAddress=%d\n",
|
||||
epdesc1->bLength, epdesc1->bDescriptorType,
|
||||
epdesc1->bEndpointAddress, epdesc1->bmAttributes,
|
||||
UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
|
||||
epdesc1->bRefresh, epdesc1->bSynchAddress));
|
||||
offs += epdesc1->bLength;
|
||||
if (offs > size)
|
||||
return USBD_INVAL;
|
||||
if (epdesc1->bSynchAddress != 0) {
|
||||
printf("%s: invalid endpoint: bSynchAddress=0\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return USBD_INVAL;
|
||||
}
|
||||
if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
|
||||
printf("%s: invalid endpoint: bmAttributes=0x%x\n",
|
||||
USBDEVNAME(sc->sc_dev), epdesc1->bmAttributes);
|
||||
return USBD_INVAL;
|
||||
}
|
||||
if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
|
||||
printf("%s: invalid endpoint addresses: "
|
||||
"ep[0]->bSynchAddress=0x%x "
|
||||
"ep[1]->bEndpointAddress=0x%x\n",
|
||||
USBDEVNAME(sc->sc_dev), ed->bSynchAddress,
|
||||
epdesc1->bEndpointAddress);
|
||||
return USBD_INVAL;
|
||||
}
|
||||
/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
|
||||
}
|
||||
|
||||
format = UGETW(asid->wFormatTag);
|
||||
chan = asf1d->bNrChannels;
|
||||
prec = asf1d->bBitResolution;
|
||||
|
@ -1204,6 +1263,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
|
|||
sc->sc_altflags |= HAS_MULAW;
|
||||
format_str = "mulaw";
|
||||
break;
|
||||
case UA_FMT_IEEE_FLOAT:
|
||||
default:
|
||||
printf("%s: ignored setting with format %d\n",
|
||||
USBDEVNAME(sc->sc_dev), format);
|
||||
|
@ -1228,6 +1288,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
|
|||
ai.attributes = sed->bmAttributes;
|
||||
ai.idesc = id;
|
||||
ai.edesc = ed;
|
||||
ai.edesc1 = epdesc1;
|
||||
ai.asf1desc = asf1d;
|
||||
ai.sc_busy = 0;
|
||||
uaudio_add_alt(sc, &ai);
|
||||
|
@ -1262,8 +1323,8 @@ uaudio_identify_as(struct uaudio_softc *sc,
|
|||
|
||||
/* Loop through all the alternate settings. */
|
||||
while (offs <= size) {
|
||||
DPRINTFN(2, ("uaudio_identify: interface %d\n",
|
||||
id->bInterfaceNumber));
|
||||
DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
|
||||
id->bInterfaceNumber, offs));
|
||||
switch (id->bNumEndpoints) {
|
||||
case 0:
|
||||
DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
|
||||
|
@ -1271,6 +1332,9 @@ uaudio_identify_as(struct uaudio_softc *sc,
|
|||
sc->sc_nullalt = id->bAlternateSetting;
|
||||
break;
|
||||
case 1:
|
||||
#ifdef UAUDIO_MULTIPLE_ENDPOINTS
|
||||
case 2:
|
||||
#endif
|
||||
uaudio_process_as(sc, buf, &offs, size, id);
|
||||
break;
|
||||
default:
|
||||
|
@ -2306,13 +2370,13 @@ uaudio_match_alt_sub(int nalts, const struct as_info *alts,
|
|||
if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
|
||||
continue;
|
||||
if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
|
||||
DPRINTFN(2,("uaudio_match_alt_sub: cont %d-%d\n",
|
||||
DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
|
||||
UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
|
||||
if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
|
||||
return i;
|
||||
} else {
|
||||
for (j = 0; j < a1d->bSamFreqType; j++) {
|
||||
DPRINTFN(2,("uaudio_match_alt_sub: disc #%d: %d\n",
|
||||
DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
|
||||
j, UA_GETSAMP(a1d, j)));
|
||||
/* XXX allow for some slack */
|
||||
if (UA_GETSAMP(a1d, j) == rate)
|
||||
|
|
Loading…
Reference in New Issue