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