Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Add some code for recording, still untested.
details: https://anonhg.NetBSD.org/src/rev/f9db09b60122
branches: trunk
changeset: 477617:f9db09b60122
user: augustss <augustss%NetBSD.org@localhost>
date: Mon Oct 25 10:16:49 1999 +0000
description:
Add some code for recording, still untested.
diffstat:
sys/dev/usb/uaudio.c | 257 +++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 207 insertions(+), 50 deletions(-)
diffs (truncated from 496 to 300 lines):
diff -r 406d0b4a47fb -r f9db09b60122 sys/dev/usb/uaudio.c
--- a/sys/dev/usb/uaudio.c Mon Oct 25 02:29:45 1999 +0000
+++ b/sys/dev/usb/uaudio.c Mon Oct 25 10:16:49 1999 +0000
@@ -1,11 +1,12 @@
-/* $NetBSD: uaudio.c,v 1.4 1999/10/14 01:18:40 augustss Exp $ */
+/* $NetBSD: uaudio.c,v 1.5 1999/10/25 10:16:49 augustss Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
- * Author: Lennart Augustsson <augustss%carlstedt.se@localhost>
- * Carlstedt Research & Technology
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (augustss%carlstedt.se@localhost) at
+ * Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -113,6 +114,7 @@
void (*intr) __P((void *)); /* dma completion intr handler */
void *arg; /* arg for intr() */
usbd_pipe_handle pipe;
+ int dir; /* direction, UE_DIR_XXX */
u_int sample_size;
u_int sample_rate;
@@ -145,8 +147,7 @@
usbd_interface_handle sc_ac_ifaceh;
usbd_interface_handle sc_as_ifaceh;
- struct chan sc_pchan;
- struct chan sc_rchan;
+ struct chan sc_chan;
int sc_curaltidx;
@@ -229,10 +230,14 @@
void uaudio_chan_free_buffers __P((struct uaudio_softc *, struct chan *));
void uaudio_chan_set_param __P((struct chan *ch, struct audio_params *param,
u_char *start, u_char *end, int blksize));
-void uaudio_chan_transfer __P((struct chan *ch));
+void uaudio_chan_ptransfer __P((struct chan *ch));
void uaudio_chan_pintr __P((usbd_request_handle reqh,
usbd_private_handle priv, usbd_status status));
+void uaudio_chan_rtransfer __P((struct chan *ch));
+void uaudio_chan_rintr __P((usbd_request_handle reqh,
+ usbd_private_handle priv, usbd_status status));
+
int uaudio_open __P((void *, int));
@@ -626,6 +631,7 @@
d->bNrChannels, UGETW(d->wChannelConfig),
d->iChannelNames, d->iTerminal));
#endif
+ printf("uaudio_add_input: not implemented\n");
}
void
@@ -943,6 +949,7 @@
usb_endpoint_descriptor_audio_t *ed;
struct usb_audio_streaming_endpoint_descriptor *sed;
int format, chan, prec, enc;
+ int dir, type;
struct as_info ai;
asid = (void *)(buf + offs);
@@ -969,16 +976,25 @@
ed = (void *)(buf + offs);
if (ed->bDescriptorType != UDESC_ENDPOINT)
return (USBD_INVAL);
+ DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
+ "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
+ "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
+ ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
+ ed->bmAttributes, UGETW(ed->wMaxPacketSize),
+ ed->bInterval, ed->bRefresh, ed->bSynchAddress));
offs += ed->bLength;
if (offs > size)
return (USBD_INVAL);
- if ((ed->bmAttributes & UE_XFERTYPE) !=
- UE_ISOCHRONOUS)
+ if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
return (USBD_INVAL);
- if ((ed->bmAttributes & UE_ISO_TYPE) !=
- UE_ISO_ADAPT) {
- printf("%s: ignored endpoint of type 0x%x\n",
+
+ dir = UE_GET_DIR(ed->bEndpointAddress);
+ type = UE_GET_ISO_TYPE(ed->bmAttributes);
+ /* We can't handle endpoints that need a sync pipe. */
+ if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) {
+ printf("%s: ignored %sput endpoint of type 0x%x\n",
USBDEVNAME(sc->sc_dev),
+ dir == UE_DIR_IN ? "in" : "out",
ed->bmAttributes & UE_ISO_TYPE);
return (USBD_NORMAL_COMPLETION);
}
@@ -1004,18 +1020,18 @@
switch (format) {
case UA_FMT_PCM:
sc->sc_altflags |= prec == 8 ? HAS_8 : HAS_16;
- enc = AUDIO_ENCODING_SLINEAR_LE;
+ enc = AUDIO_ENCODING_SLINEAR_LE;
break;
case UA_FMT_PCM8:
- enc = AUDIO_ENCODING_ULINEAR;
+ enc = AUDIO_ENCODING_ULINEAR_LE;
sc->sc_altflags |= HAS_8U;
break;
case UA_FMT_ALAW:
- enc = AUDIO_ENCODING_ALAW;
+ enc = AUDIO_ENCODING_ALAW;
sc->sc_altflags |= HAS_ALAW;
break;
case UA_FMT_MULAW:
- enc = AUDIO_ENCODING_ULAW;
+ enc = AUDIO_ENCODING_ULAW;
sc->sc_altflags |= HAS_MULAW;
break;
default:
@@ -1031,7 +1047,8 @@
ai.edesc = ed;
ai.asf1desc = asf1d;
uaudio_add_alt(sc, &ai);
- sc->sc_pchan.terminal = asid->bTerminalLink; /* XXX */
+ sc->sc_chan.terminal = asid->bTerminalLink; /* XXX */
+ sc->sc_chan.dir = dir;
return (USBD_NORMAL_COMPLETION);
}
#undef offs
@@ -1057,8 +1074,7 @@
sc->sc_as_iface = id->bInterfaceNumber;
DPRINTF(("uaudio_identify_as: AS interface is %d\n", sc->sc_as_iface));
- sc->sc_pchan.terminal = -1;
- sc->sc_rchan.terminal = -1;
+ sc->sc_chan.terminal = -1;
/* Loop through all the alternate settings. */
while (offs <= size) {
@@ -1086,6 +1102,11 @@
if (offs > size)
return (USBD_INVAL);
DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
+ if (sc->sc_chan.terminal < 0) {
+ printf("%s: no useable endpoint found\n",
+ USBDEVNAME(sc->sc_dev));
+ return (USBD_INVAL);
+ }
return (USBD_NORMAL_COMPLETION);
}
@@ -1122,11 +1143,10 @@
aclen = UGETW(acdp->wTotalLength);
if (offs + aclen > size)
return (USBD_INVAL);
-#if 0
+
if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
UGETW(acdp->bcdADC) != UAUDIO_VERSION)
return (USBD_INVAL);
-#endif
DPRINTFN(2,("uaudio_identify: found AC header, vers=%03x, len=%d\n",
UGETW(acdp->bcdADC), aclen));
@@ -1270,13 +1290,15 @@
if (sc->sc_dying)
return (EIO);
- if ((flags & FREAD) && sc->sc_rchan.terminal < 0)
+ if (sc->sc_chan.terminal < 0)
+ return (ENXIO);
+
+ if ((flags & FREAD) && sc->sc_chan.dir != UE_DIR_IN)
return (EACCES);
- if ((flags & FWRITE) && sc->sc_pchan.terminal < 0)
+ if ((flags & FWRITE) && sc->sc_chan.dir != UE_DIR_OUT)
return (EACCES);
- sc->sc_pchan.intr = 0;
- sc->sc_rchan.intr = 0;
+ sc->sc_chan.intr = 0;
return (0);
}
@@ -1294,8 +1316,7 @@
uaudio_halt_in_dma(sc);
uaudio_halt_out_dma(sc);
- sc->sc_pchan.intr = 0;
- sc->sc_rchan.intr = 0;
+ sc->sc_chan.intr = 0;
}
int
@@ -1316,10 +1337,10 @@
struct uaudio_softc *sc = addr;
DPRINTF(("uaudio_halt_out_dma: enter\n"));
- if (sc->sc_pchan.pipe) {
- uaudio_chan_close(sc, &sc->sc_pchan);
- sc->sc_pchan.pipe = 0;
- uaudio_chan_free_buffers(sc, &sc->sc_pchan);
+ if (sc->sc_chan.pipe) {
+ uaudio_chan_close(sc, &sc->sc_chan);
+ sc->sc_chan.pipe = 0;
+ uaudio_chan_free_buffers(sc, &sc->sc_chan);
}
return (0);
}
@@ -1331,9 +1352,11 @@
struct uaudio_softc *sc = addr;
DPRINTF(("uaudio_halt_in_dma: enter\n"));
- if (sc->sc_dying)
- return (EIO);
- /* XXX */
+ if (sc->sc_chan.pipe) {
+ uaudio_chan_close(sc, &sc->sc_chan);
+ sc->sc_chan.pipe = 0;
+ uaudio_chan_free_buffers(sc, &sc->sc_chan);
+ }
return (0);
}
@@ -1363,9 +1386,7 @@
struct uaudio_softc *sc = addr;
int bpf;
- /* We don't know which channel we are setting, so be safe. */
- bpf = max(sc->sc_pchan.bytes_per_frame + sc->sc_pchan.sample_size,
- sc->sc_rchan.bytes_per_frame + sc->sc_rchan.sample_size);
+ bpf = sc->sc_chan.bytes_per_frame + sc->sc_chan.sample_size;
/* XXX */
bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
@@ -1374,6 +1395,13 @@
if (blk < bpf)
blk = bpf;
+#ifdef DIAGNOSTIC
+ if (blk <= 0) {
+ printf("uaudio_round_blocksize: blk=%d\n", blk);
+ blk = 512;
+ }
+#endif
+
DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
return (blk);
}
@@ -1633,14 +1661,40 @@
struct audio_params *param;
{
struct uaudio_softc *sc = addr;
+ struct chan *ch = &sc->sc_chan;
+ usbd_status r;
+ int i, s;
if (sc->sc_dying)
return (EIO);
- DPRINTFN(2,("uaudio_trigger_input: sc=%p start=%p end=%p "
+ DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
"blksize=%d\n", sc, start, end, blksize));
- return (ENXIO);
+ uaudio_chan_set_param(ch, param, start, end, blksize);
+ DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
+ "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
+ ch->fraction));
+
+ r = uaudio_chan_alloc_buffers(sc, ch);
+ if (r != USBD_NORMAL_COMPLETION)
+ return (EIO);
+
+ r = uaudio_chan_open(sc, ch);
+ if (r != USBD_NORMAL_COMPLETION) {
+ uaudio_chan_free_buffers(sc, ch);
+ return (EIO);
+ }
+
+ sc->sc_chan.intr = intr;
+ sc->sc_chan.arg = arg;
+
+ s = splusb();
+ for (i = 0; i < UAUDIO_NCHANBUFS; i++)
+ uaudio_chan_rtransfer(ch);
+ splx(s);
+
+ return (0);
}
int
@@ -1653,7 +1707,7 @@
struct audio_params *param;
{
struct uaudio_softc *sc = addr;
Home |
Main Index |
Thread Index |
Old Index