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/097f6ef3d7a7
branches: isaki-audio2
changeset: 450637:097f6ef3d7a7
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 a908ced2f8fa -r 097f6ef3d7a7 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 a908ced2f8fa -r 097f6ef3d7a7 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