Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/arch/x68k/dev Pull up following revision(s) (requeste...



details:   https://anonhg.NetBSD.org/src/rev/18d10745f435
branches:  netbsd-8
changeset: 851043:18d10745f435
user:      snj <snj%NetBSD.org@localhost>
date:      Sat Sep 23 18:16:20 2017 +0000

description:
Pull up following revision(s) (requested by isaki in ticket #172):
        sys/arch/x68k/dev/vs.c: 1.38-1.39, 1.41-1.44, 1.47-1.48 via patch
        sys/arch/x68k/dev/vsvar.h: 1.12-1.15 via patch
Avoid panic when the device is closed when not playing.
Catch up vs_set_params() to recent MI audio (after in-kernel mixer).
Before that, MD part had to support all encodings I'd like to support,
but currently it's no longer necessary.  The hardware is
4bit/1ch/15.6kHz ADPCM but it behaves as 16bit/1ch/16.0kHz PCM.
For audio.c < 1.362, the device attach succeeded and playback is
still working.
For audio.c >= 1.363, the device attach fails again.
It does not work yet but I commit it for milestone.
Update confused vs_set_params().
play and rec are identical but pfil and rfil are independent.
XXX I introduce VS_USE_PREC8 option for debugging purposes
    temporarily.  I'll remove it if the problem is solved.
Remove temporary VS_USE_PREC8 option.
vs(4) now supports slinear16be and slinear8 (but now work yet).
vs(4) became to able to play audio again.
At the moment the encoding conversion using set_params() does
not seem to work for me.  So vs(4) uses local conversion to/from
ADPCM instead of it.  But this should be a temporary work.
XXX The playback quality is very poor compared to before...
XXX Recording is not tested.
Merge prate and rrate.  These can not be separated.
- Revert temporary local conversion introduced at rev 1.43.
- But does not revert to trigger method.  trigger method is not suitable for
  x68k ADPCM+DMA mechanism.
- Don't (re)start ADPCM when DMA is running.  This solves the noise.
  From Y.Sugahara.
- Cache dmac xfer.
- Finally MI audio supports 4bit precision format without null_filter hack!
- Fix reusing play/rec argument as local variables.  It is in/out parameter.

diffstat:

 sys/arch/x68k/dev/vs.c    |  348 +++++++++++++++++++++------------------------
 sys/arch/x68k/dev/vsvar.h |    9 +-
 2 files changed, 170 insertions(+), 187 deletions(-)

diffs (truncated from 530 to 300 lines):

diff -r b629a1145655 -r 18d10745f435 sys/arch/x68k/dev/vs.c
--- a/sys/arch/x68k/dev/vs.c    Sat Sep 23 17:58:25 2017 +0000
+++ b/sys/arch/x68k/dev/vs.c    Sat Sep 23 18:16:20 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vs.c,v 1.37.2.1 2017/09/23 17:55:13 snj Exp $  */
+/*     $NetBSD: vs.c,v 1.37.2.2 2017/09/23 18:16:20 snj Exp $  */
 
 /*
  * Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.37.2.1 2017/09/23 17:55:13 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.37.2.2 2017/09/23 18:16:20 snj Exp $");
 
 #include "audio.h"
 #include "vs.h"
@@ -78,10 +78,10 @@
 static int  vs_query_encoding(void *, struct audio_encoding *);
 static int  vs_set_params(void *, int, int, audio_params_t *,
        audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
-static int  vs_trigger_output(void *, void *, void *, int,
-       void (*)(void *), void *, const audio_params_t *);
-static int  vs_trigger_input(void *, void *, void *, int,
-       void (*)(void *), void *, const audio_params_t *);
+static int  vs_init_output(void *, void *, int);
+static int  vs_init_input(void *, void *, int);
+static int  vs_start_input(void *, void *, int, void (*)(void *), void *);
+static int  vs_start_output(void *, void *, int, void (*)(void *), void *);
 static int  vs_halt_output(void *);
 static int  vs_halt_input(void *);
 static int  vs_allocmem(struct vs_softc *, size_t, size_t, size_t,
@@ -117,10 +117,10 @@
        vs_set_params,
        NULL,                   /* round_blocksize */
        NULL,                   /* commit_settings */
-       NULL,                   /* init_output */
-       NULL,                   /* init_input */
-       NULL,                   /* start_output */
-       NULL,                   /* start_input */
+       vs_init_output,
+       vs_init_input,
+       vs_start_output,
+       vs_start_input,
        vs_halt_output,
        vs_halt_input,
        NULL,                   /* speaker_ctl */
@@ -134,8 +134,8 @@
        vs_round_buffersize,
        NULL,                   /* mappage */
        vs_get_props,
-       vs_trigger_output,
-       vs_trigger_input,
+       NULL,                   /* trigger_output */
+       NULL,                   /* trigger_input */
        NULL,
        vs_get_locks,
 };
@@ -160,19 +160,6 @@
 
 #define NUM_RATE       (sizeof(vs_l2r)/sizeof(vs_l2r[0]))
 
-struct {
-       const char *name;
-       int     encoding;
-       int     precision;
-} vs_encodings[] = {
-       {AudioEadpcm,      AUDIO_ENCODING_ADPCM,       4},
-       {AudioEslinear,    AUDIO_ENCODING_SLINEAR,     8},
-       {AudioEulinear,    AUDIO_ENCODING_ULINEAR,     8},
-       {AudioEmulaw,      AUDIO_ENCODING_ULAW,        8},
-       {AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16},
-       {AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16},
-};
-
 static int
 vs_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -232,6 +219,8 @@
        sc->sc_hw_if = &vs_hw_if;
        sc->sc_addr = (void *) ia->ia_addr;
        sc->sc_dmas = NULL;
+       sc->sc_prev_vd = NULL;
+       sc->sc_active = 0;
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 
@@ -266,26 +255,8 @@
        mutex_spin_enter(&sc->sc_intr_lock);
 
        if (sc->sc_pintr) {
-               /* start next transfer */
-               sc->sc_current.dmap += sc->sc_current.blksize;
-               if (sc->sc_current.dmap + sc->sc_current.blksize
-                   > sc->sc_current.bufsize)
-                       sc->sc_current.dmap -= sc->sc_current.bufsize;
-               dmac_start_xfer_offset(sc->sc_dma_ch->ch_softc,
-                                       sc->sc_current.xfer,
-                                       sc->sc_current.dmap,
-                                       sc->sc_current.blksize);
                sc->sc_pintr(sc->sc_parg);
        } else if (sc->sc_rintr) {
-               /* start next transfer */
-               sc->sc_current.dmap += sc->sc_current.blksize;
-               if (sc->sc_current.dmap + sc->sc_current.blksize
-                   > sc->sc_current.bufsize)
-                       sc->sc_current.dmap -= sc->sc_current.bufsize;
-               dmac_start_xfer_offset(sc->sc_dma_ch->ch_softc,
-                                       sc->sc_current.xfer,
-                                       sc->sc_current.dmap,
-                                       sc->sc_current.blksize);
                sc->sc_rintr(sc->sc_rarg);
        } else {
                printf("vs_dmaintr: spurious interrupt\n");
@@ -323,6 +294,7 @@
        sc = hdl;
        sc->sc_pintr = NULL;
        sc->sc_rintr = NULL;
+       sc->sc_active = 0;
 
        return 0;
 }
@@ -339,17 +311,22 @@
 {
 
        DPRINTF(1, ("vs_query_encoding\n"));
-       if (fp->index >= sizeof(vs_encodings) / sizeof(vs_encodings[0]))
-               return EINVAL;
 
-       strcpy(fp->name, vs_encodings[fp->index].name);
-       fp->encoding  = vs_encodings[fp->index].encoding;
-       fp->precision = vs_encodings[fp->index].precision;
-       if (fp->encoding == AUDIO_ENCODING_ADPCM)
+       if (fp->index == 0) {
+               strcpy(fp->name, AudioEslinear);
+               fp->encoding = AUDIO_ENCODING_SLINEAR;
+               fp->precision = 8;
                fp->flags = 0;
-       else
-               fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
-       return 0;
+               return 0;
+       }
+       if (fp->index == 1) {
+               strcpy(fp->name, AudioEslinear_be);
+               fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
+               fp->precision = 16;
+               fp->flags = 0;
+               return 0;
+       }
+       return EINVAL;
 }
 
 static int
@@ -386,95 +363,62 @@
        stream_filter_list_t *pfil, stream_filter_list_t *rfil)
 {
        struct vs_softc *sc;
-       struct audio_params *p;
-       int mode;
+       audio_params_t hw;
+       stream_filter_factory_t *pconv;
+       stream_filter_factory_t *rconv;
        int rate;
-       audio_params_t hw;
-       int matched;
-
-       DPRINTF(1, ("vs_set_params: setmode=%d, usemode=%d\n",
-               setmode, usemode));
 
        sc = hdl;
-       /* set first record info, then play info */
-       for (mode = AUMODE_RECORD; mode != -1;
-            mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
-               if ((setmode & mode) == 0)
-                       continue;
 
-               p = (mode == AUMODE_PLAY) ? play : rec;
+       DPRINTF(1, ("vs_set_params: mode=%d enc=%d rate=%d prec=%d ch=%d: ",
+               setmode, play->encoding, play->sample_rate,
+               play->precision, play->channels));
 
-               if (p->channels != 1)
-                       return EINVAL;
+       /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */
 
-               rate = p->sample_rate;
-               hw = *p;
-               hw.encoding = AUDIO_ENCODING_ADPCM;
-               hw.precision = hw.validbits = 4;
-               DPRINTF(1, ("vs_set_params: encoding=%d, precision=%d\n",
-                       p->encoding, p->precision));
-               matched = 0;
-               switch (p->precision) {
-               case 4:
-                       if (p->encoding == AUDIO_ENCODING_ADPCM)
-                               matched = 1;
-                       break;
-               case 8:
-                       switch (p->encoding) {
-                       case AUDIO_ENCODING_ULAW:
-                               matched = 1;
-                               hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
-                               hw.precision = hw.validbits = 8;
-                               pfil->prepend(pfil, mulaw_to_linear8, &hw);
-                               hw.encoding = AUDIO_ENCODING_ADPCM;
-                               hw.precision = hw.validbits = 4;
-                               pfil->prepend(pfil, msm6258_linear8_to_adpcm, &hw);
-                               rfil->append(rfil, msm6258_adpcm_to_linear8, &hw);
-                               hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
-                               hw.precision = hw.validbits = 8;
-                               rfil->append(rfil, linear8_to_mulaw, &hw);
-                               break;
-                       case AUDIO_ENCODING_SLINEAR:
-                       case AUDIO_ENCODING_SLINEAR_LE:
-                       case AUDIO_ENCODING_SLINEAR_BE:
-                       case AUDIO_ENCODING_ULINEAR:
-                       case AUDIO_ENCODING_ULINEAR_LE:
-                       case AUDIO_ENCODING_ULINEAR_BE:
-                               matched = 1;
-                               pfil->append(pfil, msm6258_linear8_to_adpcm, &hw);
-                               rfil->append(rfil, msm6258_adpcm_to_linear8, &hw);
-                               break;
-                       }
-                       break;
-               case 16:
-                       switch (p->encoding) {
-                       case AUDIO_ENCODING_SLINEAR_LE:
-                       case AUDIO_ENCODING_SLINEAR_BE:
-                               matched = 1;
-                               pfil->append(pfil, msm6258_slinear16_to_adpcm, &hw);
-                               rfil->append(rfil, msm6258_adpcm_to_slinear16, &hw);
-                               break;
-                       }
-                       break;
-               }
-               if (matched == 0) {
-                       DPRINTF(1, ("vs_set_params: mode=%d, encoding=%d\n",
-                               mode, p->encoding));
-                       return EINVAL;
-               }
+       if (play->channels != 1) {
+               DPRINTF(1, ("channels not matched\n"));
+               return EINVAL;
+       }
 
-               DPRINTF(1, ("vs_set_params: rate=%d -> ", rate));
-               rate = vs_round_sr(rate);
-               DPRINTF(1, ("%d\n", rate));
-               if (rate < 0)
-                       return EINVAL;
-               if (mode == AUMODE_PLAY) {
-                       sc->sc_current.prate = rate;
-               } else {
-                       sc->sc_current.rrate = rate;
-               }
+       rate = vs_round_sr(play->sample_rate);
+       if (rate < 0) {
+               DPRINTF(1, ("rate not matched\n"));
+               return EINVAL;
        }
 
+       if (play->precision == 8 && play->encoding == AUDIO_ENCODING_SLINEAR) {
+               pconv = msm6258_linear8_to_adpcm;
+               rconv = msm6258_adpcm_to_linear8;
+       } else if (play->precision == 16 &&
+                  play->encoding == AUDIO_ENCODING_SLINEAR_BE) {
+               pconv = msm6258_slinear16_to_adpcm;
+               rconv = msm6258_adpcm_to_slinear16;
+       } else {
+               DPRINTF(1, ("prec/enc not matched\n"));
+               return EINVAL;
+       }
+
+       sc->sc_current.rate = rate;
+
+       /* pfil and rfil are independent even if !AUDIO_PROP_INDEPENDENT */
+
+       if ((setmode & AUMODE_PLAY) != 0) {
+               hw = *play;
+               hw.encoding = AUDIO_ENCODING_ADPCM;
+               hw.precision = 4;
+               hw.validbits = 4;
+               pfil->prepend(pfil, pconv, &hw);
+       }
+       if ((setmode & AUMODE_RECORD) != 0) {
+               hw = *rec;
+               hw.encoding = AUDIO_ENCODING_ADPCM;
+               hw.precision = 4;
+               hw.validbits = 4;
+               rfil->prepend(rfil, rconv, &hw);
+       }
+
+       DPRINTF(1, ("accepted\n"));
        return 0;
 }
 
@@ -500,88 +444,120 @@
 }



Home | Main Index | Thread Index | Old Index