Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/isaki-audio2]: src/sys Adapt to audio2.



details:   https://anonhg.NetBSD.org/src/rev/93c45d3e2f76
branches:  isaki-audio2
changeset: 455972:93c45d3e2f76
user:      isaki <isaki%NetBSD.org@localhost>
date:      Sun Apr 21 06:55:34 2019 +0000

description:
Adapt to audio2.
- Use mulaw as default format.  HW supports slinear_be:16 actually
  but it's hard to use due to several hardware restrictions.
- Improve data transfer and interrupt.
Tested by tsutsui@ (a few months ago).  Thank you.

diffstat:

 sys/arch/hp300/dev/arcofi_dio.c |    7 +-
 sys/dev/ic/arcofi.c             |  299 ++++++++++++++-------------------------
 sys/dev/ic/arcofivar.h          |    6 +-
 3 files changed, 114 insertions(+), 198 deletions(-)

diffs (truncated from 480 to 300 lines):

diff -r be3569b01c88 -r 93c45d3e2f76 sys/arch/hp300/dev/arcofi_dio.c
--- a/sys/arch/hp300/dev/arcofi_dio.c   Sun Apr 21 06:17:02 2019 +0000
+++ b/sys/arch/hp300/dev/arcofi_dio.c   Sun Apr 21 06:55:34 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: arcofi_dio.c,v 1.1 2014/08/24 08:17:44 tsutsui Exp $   */
+/*     $NetBSD: arcofi_dio.c,v 1.1.26.1 2019/04/21 06:55:34 isaki Exp $        */
 /*     $OpenBSD: arcofi_dio.c,v 1.1 2011/12/21 23:12:03 miod Exp $     */
 
 /*
@@ -80,11 +80,6 @@
                return;
        }
 
-       sc->sc_sih = softint_establish(SOFTINT_AUDIO, arcofi_swintr, sc);
-       if (sc->sc_sih == NULL) {
-               aprint_error(": can't register soft interrupt\n");
-               return;
-       }
        ipl = da->da_ipl;
        dio_intr_establish(arcofi_hwintr, sc, ipl, IPL_AUDIO);
 
diff -r be3569b01c88 -r 93c45d3e2f76 sys/dev/ic/arcofi.c
--- a/sys/dev/ic/arcofi.c       Sun Apr 21 06:17:02 2019 +0000
+++ b/sys/dev/ic/arcofi.c       Sun Apr 21 06:55:34 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: arcofi.c,v 1.1.28.1 2019/04/21 05:11:22 isaki Exp $    */
+/*     $NetBSD: arcofi.c,v 1.1.28.2 2019/04/21 06:55:34 isaki Exp $    */
 /*     $OpenBSD: arcofi.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $      */
 
 /*
@@ -36,15 +36,13 @@
 #include <sys/kernel.h>
 #include <sys/proc.h>
 #include <sys/mutex.h>
-#include <sys/condvar.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
 
 #include <sys/audioio.h>
 
 #include <dev/audio_if.h>
-#include <dev/auconv.h>
-#include <dev/mulaw.h>
+#include <dev/audio/mulaw.h>
 
 #include <dev/ic/arcofivar.h>
 
@@ -200,11 +198,10 @@
 
 static int     arcofi_open(void *, int);
 static void    arcofi_close(void *);
-static int     arcofi_drain(void *);
-static int     arcofi_query_encoding(void *, struct audio_encoding *);
-static int     arcofi_set_params(void *, int, int,
-                   struct audio_params *, struct audio_params *,
-                   stream_filter_list_t *, stream_filter_list_t *);
+static int     arcofi_query_format(void *, audio_format_query_t *);
+static int     arcofi_set_format(void *, int,
+                   const audio_params_t *, const audio_params_t *,
+                   audio_filter_reg_t *, audio_filter_reg_t *);
 static int     arcofi_round_blocksize(void *, int, int,
                    const audio_params_t *);
 static int     arcofi_commit_settings(void *);
@@ -224,9 +221,8 @@
 static const struct audio_hw_if arcofi_hw_if = {
        .open             = arcofi_open,
        .close            = arcofi_close,
-       .drain            = arcofi_drain,
-       .query_encoding   = arcofi_query_encoding,
-       .set_params       = arcofi_set_params,
+       .query_format     = arcofi_query_format,
+       .set_format       = arcofi_set_format,
        .round_blocksize  = arcofi_round_blocksize,
        .commit_settings  = arcofi_commit_settings,
        .start_output     = arcofi_start_output,
@@ -250,9 +246,10 @@
        .get_locks        = arcofi_get_locks,
 };
 
-#define ARCOFI_FORMAT(enc, prec) \
+#define ARCOFI_FORMAT(prio, enc, prec) \
        { \
                .mode           = AUMODE_PLAY | AUMODE_RECORD, \
+               .priority       = (prio), \
                .encoding       = (enc), \
                .validbits      = (prec), \
                .precision      = (prec), \
@@ -263,18 +260,15 @@
        }
 static const struct audio_format arcofi_formats[] = {
        /*
-        * 8-bit encodings:
-        *  - u-Law and A-Law are native
-        *  - linear are converted to 16-bit by auconv
+        * 8-bit u-Law and A-Law are native.
         */
-       ARCOFI_FORMAT(AUDIO_ENCODING_ULAW,        8),
-       ARCOFI_FORMAT(AUDIO_ENCODING_ALAW,        8),
+       ARCOFI_FORMAT(1, AUDIO_ENCODING_ULAW,        8),
+       ARCOFI_FORMAT(0, AUDIO_ENCODING_ALAW,        8),
        /*
-        * 16-bit encodings:
-        *  - slinear big-endian is native
-        *  - unsigned or little-endian are converted by auconv
+        * 16-bit slinear big-endian is native.
+        * But it's hard to use due to hardware restrictions.
         */
-       ARCOFI_FORMAT(AUDIO_ENCODING_SLINEAR_BE, 16),
+       ARCOFI_FORMAT(0, AUDIO_ENCODING_SLINEAR_BE, 16),
 };
 #define ARCOFI_NFORMATS  __arraycount(arcofi_formats)
 
@@ -339,107 +333,60 @@
 {
        struct arcofi_softc *sc = (struct arcofi_softc *)v;
 
-       arcofi_halt_input(v);
-       arcofi_halt_output(v);
        sc->sc_open = 0;
 }
 
 static int
-arcofi_drain(void *v)
+arcofi_query_format(void *v, audio_format_query_t *afp)
 {
-       struct arcofi_softc *sc = (struct arcofi_softc *)v;
 
-#ifdef ARCOFI_DEBUG
-       printf("%s: %s, mode %d\n",
-           device_xname(sc->sc_dev), __func__, sc->sc_mode);
-#endif
-       if ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_EMPTY) == 0) {
-               /* enable output FIFO empty interrupt... */
-               arcofi_write(sc, ARCOFI_FIFO_IR,
-                   arcofi_read(sc, ARCOFI_FIFO_IR) |
-                   FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
-               /* ...and wait for it to fire */
-               if (cv_timedwait(&sc->sc_cv, &sc->sc_intr_lock,
-                   ((ARCOFI_FIFO_SIZE * hz) / 8000) + 100) != 0) {
-                       printf("%s: drain did not complete\n",
-                           device_xname(sc->sc_dev));
-                       arcofi_write(sc, ARCOFI_FIFO_IR,
-                           arcofi_read(sc, ARCOFI_FIFO_IR) &
-                           ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
-               }
-       }
-       return 0;
+       return audio_query_format(arcofi_formats, ARCOFI_NFORMATS, afp);
 }
 
 static int
-arcofi_query_encoding(void *v, struct audio_encoding *aep)
-{
-       struct arcofi_softc *sc = (struct arcofi_softc *)v;
-
-       return auconv_query_encoding(sc->sc_encodings, aep);
-}
-
-/*
- * Compute proper sample and hardware settings.
- */
-static int
-arcofi_set_params(void *handle, int setmode, int usemode,
-    audio_params_t *play, audio_params_t *rec,
-    stream_filter_list_t *pfil, stream_filter_list_t *rfil)
+arcofi_set_format(void *handle, int setmode,
+    const audio_params_t *play, const audio_params_t *rec,
+    audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
 {
        struct arcofi_softc *sc;
-       int i;
 
        sc = handle;
-       for (i = 0; i < 2; i++) {
-               int mode;
-               audio_params_t *p;
-               stream_filter_list_t *fil;
-               int ind;
-
-               switch (i) {
-               case 0:
-                       mode = AUMODE_PLAY;
-                       p = play;
-                       fil = pfil;
-                       break;
-               case 1:
-                       mode = AUMODE_RECORD;
-                       p = rec;
-                       fil = rfil;
-                       break;
-               default:
-                       return EINVAL;
-               }
-
-               if ((setmode & mode) == 0)
-                       continue;
 
-#ifdef ARCOFI_DEBUG
-               printf("%s: %s, mode %d encoding %d precision %d\n",
-                   device_xname(sc->sc_dev), __func__,
-                   mode, p->encoding, p->precision);
-#endif
+       if ((setmode & AUMODE_PLAY)) {
+               switch (play->encoding) {
+               case AUDIO_ENCODING_ULAW:
+                       pfil->codec = audio_internal_to_mulaw;
+                       break;
+               case AUDIO_ENCODING_ALAW:
+                       pfil->codec = audio_internal_to_alaw;
+                       break;
+               }
+       }
+       if ((setmode & AUMODE_RECORD)) {
+               switch (rec->encoding) {
+               case AUDIO_ENCODING_ULAW:
+                       rfil->codec = audio_mulaw_to_internal;
+                       break;
+               case AUDIO_ENCODING_ALAW:
+                       rfil->codec = audio_alaw_to_internal;
+                       break;
+               }
+       }
 
-               ind = auconv_set_converter(arcofi_formats, ARCOFI_NFORMATS,
-                   mode, p, false, fil);
-               if (ind < 0)
-                       return EINVAL;
-               if (fil->req_size > 0)
-                       p = &fil->filters[0].param;
-               if (p->precision == 8) {
-                       if (p->encoding == AUDIO_ENCODING_ALAW)
-                               sc->sc_shadow.cr4 &= ~CR4_ULAW;
-                       else
-                               sc->sc_shadow.cr4 |= CR4_ULAW;
-                       sc->sc_shadow.cr3 =
-                           (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
-                           CR3_OPMODE_NORMAL;
-               } else {
-                       sc->sc_shadow.cr3 =
-                           (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
-                           CR3_OPMODE_LINEAR;
-               }
+       /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */
+
+       if (play->precision == 8) {
+               if (play->encoding == AUDIO_ENCODING_ULAW)
+                       sc->sc_shadow.cr4 |= CR4_ULAW;
+               else
+                       sc->sc_shadow.cr4 &= ~CR4_ULAW;
+               sc->sc_shadow.cr3 =
+                   (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
+                   CR3_OPMODE_NORMAL;
+       } else {
+               sc->sc_shadow.cr3 =
+                   (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
+                   CR3_OPMODE_LINEAR;
        }
 
        return 0;
@@ -528,6 +475,48 @@
        return rc;
 }
 
+/*
+ * Take it out of the queue as much as possible.
+ */
+static int
+arcofi_recv_data(struct arcofi_softc *sc)
+{
+       uint8_t *cur;
+       uint8_t *past;
+
+       cur = sc->sc_recv.buf;
+       past = sc->sc_recv.past;
+
+       while (cur != past &&
+           (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_IN_EMPTY) == 0) {
+               *cur++ = arcofi_read(sc, ARCOFI_FIFO_DATA);
+       }
+       sc->sc_recv.buf = cur;
+
+       return past - cur;
+}
+
+/*
+ * Fill the queue as much as possible.
+ */
+static int
+arcofi_xmit_data(struct arcofi_softc *sc)
+{
+       uint8_t *cur;
+       uint8_t *past;
+
+       cur = sc->sc_xmit.buf;
+       past = sc->sc_xmit.past;
+
+       while (cur != past &&
+           (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_FULL) == 0) {
+               arcofi_write(sc, ARCOFI_FIFO_DATA, *cur++);
+       }



Home | Main Index | Thread Index | Old Index