Module Name: src
Committed By: isaki
Date: Sat Sep 12 05:19:16 UTC 2020
Modified Files:
src/sys/arch/sparc/conf: files.sparc
src/sys/arch/sparc/dev: audioamd.c
src/sys/arch/sparc/sparc: genassym.cf
src/sys/arch/vax/vsa: vsaudio.c
src/sys/dev/ic: am7930.c am7930var.h
src/sys/dev/tc: bba.c
Removed Files:
src/sys/arch/sparc/dev: audioamdvar.h
src/sys/arch/sparc/include: am7930_machdep.h
src/sys/arch/sparc/sparc: amd7930intr.s
Log Message:
Improve am7930 family drivers to share more code.
audioamd(4) on sparc, vsaudio(4) on vax, and bba(4) are.
- Remove complex and useless callbacks: onopen, onclose, and
indirect_{read,write}. This makes audioamd and vsaudio almost the same.
- Remove (already disabled) assembly fast interrupt path from audioamd(4).
cf. http://mail-index.netbsd.org/source-changes/2009/12/19/msg004585.html
- Use trigger_* method rather than start_* method. It's more suitable.
vsaudio(4) was tested by naru@, bba(4) was tested by tsutsui@.
To generate a diff of this commit:
cvs rdiff -u -r1.159 -r1.160 src/sys/arch/sparc/conf/files.sparc
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/sparc/dev/audioamd.c
cvs rdiff -u -r1.4 -r0 src/sys/arch/sparc/dev/audioamdvar.h
cvs rdiff -u -r1.1 -r0 src/sys/arch/sparc/include/am7930_machdep.h
cvs rdiff -u -r1.23 -r0 src/sys/arch/sparc/sparc/amd7930intr.s
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/sparc/sparc/genassym.cf
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/vax/vsa/vsaudio.c
cvs rdiff -u -r1.59 -r1.60 src/sys/dev/ic/am7930.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/ic/am7930var.h
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/tc/bba.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sparc/conf/files.sparc
diff -u src/sys/arch/sparc/conf/files.sparc:1.159 src/sys/arch/sparc/conf/files.sparc:1.160
--- src/sys/arch/sparc/conf/files.sparc:1.159 Fri Mar 1 02:28:27 2019
+++ src/sys/arch/sparc/conf/files.sparc Sat Sep 12 05:19:15 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.sparc,v 1.159 2019/03/01 02:28:27 macallan Exp $
+# $NetBSD: files.sparc,v 1.160 2020/09/12 05:19:15 isaki Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
# sparc-specific configuration info
@@ -233,7 +233,6 @@ attach audioamd at mainbus with audioamd
attach audioamd at obio with audioamd_obio
attach audioamd at sbus with audioamd_sbus
file arch/sparc/dev/audioamd.c audioamd
-file arch/sparc/sparc/amd7930intr.s audioamd
device apc
attach apc at sbus
Index: src/sys/arch/sparc/dev/audioamd.c
diff -u src/sys/arch/sparc/dev/audioamd.c:1.29 src/sys/arch/sparc/dev/audioamd.c:1.30
--- src/sys/arch/sparc/dev/audioamd.c:1.29 Wed May 8 13:40:16 2019
+++ src/sys/arch/sparc/dev/audioamd.c Sat Sep 12 05:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: audioamd.c,v 1.29 2019/05/08 13:40:16 isaki Exp $ */
+/* $NetBSD: audioamd.c,v 1.30 2020/09/12 05:19:16 isaki Exp $ */
/* NetBSD: am7930_sparc.c,v 1.44 1999/03/14 22:29:00 jonathan Exp */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audioamd.c,v 1.29 2019/05/08 13:40:16 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audioamd.c,v 1.30 2020/09/12 05:19:16 isaki Exp $");
#include "audio.h"
#if NAUDIO > 0
@@ -52,52 +52,14 @@ __KERNEL_RCSID(0, "$NetBSD: audioamd.c,v
#include <dev/ic/am7930reg.h>
#include <dev/ic/am7930var.h>
-#include <sparc/dev/audioamdvar.h>
#define AUDIO_ROM_NAME "audio"
-#ifdef AUDIO_DEBUG
-#define DPRINTF(x) if (am7930debug) printf x
-#define DPRINTFN(n,x) if (am7930debug>(n)) printf x
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif /* AUDIO_DEBUG */
-
-
-/* interrupt interfaces */
-int am7930hwintr(void *);
-struct auio *auiop;
-void am7930swintr(void *);
-
-/* from amd7930intr.s: */
-void amd7930_trap(void);
-
-/*
- * interrupt-handler status
- */
-struct am7930_intrhand {
- int (*ih_fun)(void *);
- void *ih_arg;
-};
-
struct audioamd_softc {
struct am7930_softc sc_am7930; /* glue to MI code */
bus_space_tag_t sc_bt; /* bus cookie */
bus_space_handle_t sc_bh; /* device registers */
-
- struct am7930_intrhand sc_ih; /* interrupt vector (hw or sw) */
- void (*sc_rintr)(void*); /* input completion intr handler */
- void *sc_rarg; /* arg for sc_rintr() */
- void (*sc_pintr)(void*); /* output completion intr handler */
- void *sc_parg; /* arg for sc_pintr() */
-
- /* sc_au is special in that the hardware interrupt handler uses it */
- struct auio sc_au; /* recv and xmit buffers, etc */
-#define sc_intrcnt sc_au.au_intrcnt /* statistics */
- void *sc_sicookie; /* softintr(9) cookie */
- kmutex_t sc_lock;
};
int audioamd_mainbus_match(device_t, cfdata_t, void *);
@@ -121,40 +83,25 @@ CFATTACH_DECL_NEW(audioamd_sbus, sizeof(
* Define our interface into the am7930 MI driver.
*/
-uint8_t audioamd_codec_iread(struct am7930_softc *, int);
-uint16_t audioamd_codec_iread16(struct am7930_softc *, int);
-uint8_t audioamd_codec_dread(struct audioamd_softc *, int);
-void audioamd_codec_iwrite(struct am7930_softc *, int, uint8_t);
-void audioamd_codec_iwrite16(struct am7930_softc *, int, uint16_t);
-void audioamd_codec_dwrite(struct audioamd_softc *, int, uint8_t);
-void audioamd_onopen(struct am7930_softc *);
-void audioamd_onclose(struct am7930_softc *);
+uint8_t audioamd_codec_dread(struct am7930_softc *, int);
+void audioamd_codec_dwrite(struct am7930_softc *, int, uint8_t);
struct am7930_glue audioamd_glue = {
- audioamd_codec_iread,
- audioamd_codec_iwrite,
- audioamd_codec_iread16,
- audioamd_codec_iwrite16,
- audioamd_onopen,
- audioamd_onclose,
+ audioamd_codec_dread,
+ audioamd_codec_dwrite,
};
/*
* Define our interface to the higher level audio driver.
*/
-int audioamd_start_output(void *, void *, int, void (*)(void *), void *);
-int audioamd_start_input(void *, void *, int, void (*)(void *), void *);
int audioamd_getdev(void *, struct audio_device *);
-void audioamd_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread);
const struct audio_hw_if sa_hw_if = {
- .open = am7930_open,
- .close = am7930_close,
.query_format = am7930_query_format,
.set_format = am7930_set_format,
.commit_settings = am7930_commit_settings,
- .start_output = audioamd_start_output, /* md */
- .start_input = audioamd_start_input, /* md */
+ .trigger_output = am7930_trigger_output,
+ .trigger_input = am7930_trigger_input,
.halt_output = am7930_halt_output,
.halt_input = am7930_halt_input,
.getdev = audioamd_getdev,
@@ -162,7 +109,7 @@ const struct audio_hw_if sa_hw_if = {
.get_port = am7930_get_port,
.query_devinfo = am7930_query_devinfo,
.get_props = am7930_get_props,
- .get_locks = audioamd_get_locks,
+ .get_locks = am7930_get_locks,
};
struct audio_device audioamd_device = {
@@ -280,258 +227,42 @@ audioamd_sbus_attach(device_t parent, de
void
audioamd_attach(struct audioamd_softc *sc, int pri)
{
+ struct am7930_softc *amsc = &sc->sc_am7930;
device_t self;
/*
* Set up glue for MI code early; we use some of it here.
*/
- self = sc->sc_am7930.sc_dev;
- sc->sc_am7930.sc_glue = &audioamd_glue;
- mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
-
- am7930_init(&sc->sc_am7930, AUDIOAMD_POLL_MODE);
-
- auiop = &sc->sc_au;
+ amsc->sc_glue = &audioamd_glue;
+ am7930_init(amsc, AUDIOAMD_POLL_MODE);
- /* Copy bus tag & handle for use by am7930_trap */
- sc->sc_au.au_bt = sc->sc_bt;
- sc->sc_au.au_bh = sc->sc_bh;
(void)bus_intr_establish2(sc->sc_bt, pri, IPL_HIGH,
- am7930hwintr, sc,
-#ifdef notyet /* XXX amd7930intr.s needs to be fixed for MI softint(9) */
- amd7930_trap
-#else
- NULL
-#endif
- );
-
- sc->sc_sicookie = softint_establish(SOFTINT_SERIAL, am7930swintr, sc);
- if (sc->sc_sicookie == NULL) {
- printf("\n%s: cannot establish software interrupt\n",
- device_xname(self));
- return;
- }
-
- printf(" softpri %d\n", IPL_SOFTAUDIO);
+ am7930_hwintr, sc, NULL);
+ printf("\n");
- evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
+ self = amsc->sc_dev;
+ evcnt_attach_dynamic(&amsc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
device_xname(self), "intr");
audio_attach_mi(&sa_hw_if, sc, self);
}
-void
-audioamd_onopen(struct am7930_softc *sc)
-{
- struct audioamd_softc *mdsc;
-
- mdsc = (struct audioamd_softc *)sc;
-
- /* reset pdma state */
- mutex_spin_enter(&mdsc->sc_lock);
- mdsc->sc_rintr = 0;
- mdsc->sc_rarg = 0;
- mdsc->sc_pintr = 0;
- mdsc->sc_parg = 0;
- mdsc->sc_au.au_rdata = 0;
- mdsc->sc_au.au_pdata = 0;
- mutex_spin_exit(&mdsc->sc_lock);
-}
-
-
-void
-audioamd_onclose(struct am7930_softc *sc)
-{
- /* On sparc, just do the chipset-level halt. */
- am7930_halt_input(sc);
- am7930_halt_output(sc);
-}
-
-int
-audioamd_start_output(void *addr, void *p, int cc,
- void (*intr)(void *), void *arg)
-{
- struct audioamd_softc *sc;
-
- DPRINTFN(1, ("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
- sc = addr;
-
- mutex_spin_enter(&sc->sc_lock);
- audioamd_codec_iwrite(&sc->sc_am7930,
- AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
- sc->sc_pintr = intr;
- sc->sc_parg = arg;
- sc->sc_au.au_pdata = p;
- sc->sc_au.au_pend = (char *)p + cc - 1;
- mutex_spin_exit(&sc->sc_lock);
-
- DPRINTF(("sa_start_output: started intrs.\n"));
- return(0);
-}
-
-int
-audioamd_start_input(void *addr, void *p, int cc,
- void (*intr)(void *), void *arg)
-{
- struct audioamd_softc *sc;
-
- DPRINTFN(1, ("sa_start_input: cc=%d %p (%p)\n", cc, intr, arg));
- sc = addr;
-
- mutex_spin_enter(&sc->sc_lock);
- audioamd_codec_iwrite(&sc->sc_am7930,
- AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
- sc->sc_rintr = intr;
- sc->sc_rarg = arg;
- sc->sc_au.au_rdata = p;
- sc->sc_au.au_rend = (char *)p + cc -1;
- mutex_spin_exit(&sc->sc_lock);
-
- DPRINTF(("sa_start_input: started intrs.\n"));
-
- return(0);
-}
-
-
-/*
- * Pseudo-DMA support: either C or locore assember.
- */
-
-int
-am7930hwintr(void *v)
-{
- struct audioamd_softc *sc;
- struct auio *au;
- uint8_t *d, *e;
- int k;
-
- sc = v;
- au = &sc->sc_au;
- mutex_spin_enter(&sc->sc_lock);
-
- /* clear interrupt */
- k = audioamd_codec_dread(sc, AM7930_DREG_IR);
- if ((k & (AM7930_IR_DTTHRSH|AM7930_IR_DRTHRSH|AM7930_IR_DSRI|
- AM7930_IR_DERI|AM7930_IR_BBUFF)) == 0) {
- mutex_spin_exit(&sc->sc_lock);
- return 0;
- }
-
- /* receive incoming data */
- d = au->au_rdata;
- e = au->au_rend;
- if (d && d <= e) {
- *d = audioamd_codec_dread(sc, AM7930_DREG_BBRB);
- au->au_rdata++;
- if (d == e) {
- DPRINTFN(1, ("am7930hwintr: swintr(r) requested"));
- softint_schedule(sc->sc_sicookie);
- }
- }
-
- /* send outgoing data */
- d = au->au_pdata;
- e = au->au_pend;
- if (d && d <= e) {
- audioamd_codec_dwrite(sc, AM7930_DREG_BBTB, *d);
- au->au_pdata++;
- if (d == e) {
- DPRINTFN(1, ("am7930hwintr: swintr(p) requested"));
- softint_schedule(sc->sc_sicookie);
- }
- }
-
- au->au_intrcnt.ev_count++;
- mutex_spin_exit(&sc->sc_lock);
-
- return 1;
-}
-
-void
-am7930swintr(void *sc0)
-{
- struct audioamd_softc *sc;
- struct auio *au;
- bool pint;
-
- sc = sc0;
- DPRINTFN(1, ("audiointr: sc=%p\n", sc););
-
- au = &sc->sc_au;
-
- mutex_spin_enter(&sc->sc_am7930.sc_lock);
- if (au->au_rdata > au->au_rend && sc->sc_rintr != NULL) {
- (*sc->sc_rintr)(sc->sc_rarg);
- }
- pint = (au->au_pdata > au->au_pend && sc->sc_pintr != NULL);
- if (pint)
- (*sc->sc_pintr)(sc->sc_parg);
-
- mutex_spin_exit(&sc->sc_am7930.sc_lock);
-}
-
-
-/* indirect write */
-void
-audioamd_codec_iwrite(struct am7930_softc *sc, int reg, uint8_t val)
-{
- struct audioamd_softc *mdsc;
-
- mdsc = (struct audioamd_softc *)sc;
- audioamd_codec_dwrite(mdsc, AM7930_DREG_CR, reg);
- audioamd_codec_dwrite(mdsc, AM7930_DREG_DR, val);
-}
-
-void
-audioamd_codec_iwrite16(struct am7930_softc *sc, int reg, uint16_t val)
-{
- struct audioamd_softc *mdsc;
-
- mdsc = (struct audioamd_softc *)sc;
- audioamd_codec_dwrite(mdsc, AM7930_DREG_CR, reg);
- audioamd_codec_dwrite(mdsc, AM7930_DREG_DR, val);
- audioamd_codec_dwrite(mdsc, AM7930_DREG_DR, val>>8);
-}
-
-
-/* indirect read */
-uint8_t
-audioamd_codec_iread(struct am7930_softc *sc, int reg)
-{
- struct audioamd_softc *mdsc;
-
- mdsc = (struct audioamd_softc *)sc;
- audioamd_codec_dwrite(mdsc, AM7930_DREG_CR, reg);
- return (audioamd_codec_dread(mdsc, AM7930_DREG_DR));
-}
-
-uint16_t
-audioamd_codec_iread16(struct am7930_softc *sc, int reg)
-{
- struct audioamd_softc *mdsc;
- uint8_t lo, hi;
-
- mdsc = (struct audioamd_softc *)sc;
- audioamd_codec_dwrite(mdsc, AM7930_DREG_CR, reg);
- lo = audioamd_codec_dread(mdsc, AM7930_DREG_DR);
- hi = audioamd_codec_dread(mdsc, AM7930_DREG_DR);
- return (hi << 8) | lo;
-}
-
/* direct read */
uint8_t
-audioamd_codec_dread(struct audioamd_softc *sc, int reg)
+audioamd_codec_dread(struct am7930_softc *amsc, int reg)
{
+ struct audioamd_softc *sc = (struct audioamd_softc *)amsc;
return bus_space_read_1(sc->sc_bt, sc->sc_bh, reg);
}
/* direct write */
void
-audioamd_codec_dwrite(struct audioamd_softc *sc, int reg, uint8_t val)
+audioamd_codec_dwrite(struct am7930_softc *amsc, int reg, uint8_t val)
{
+ struct audioamd_softc *sc = (struct audioamd_softc *)amsc;
bus_space_write_1(sc->sc_bt, sc->sc_bh, reg, val);
}
@@ -544,14 +275,4 @@ audioamd_getdev(void *addr, struct audio
return 0;
}
-void
-audioamd_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
-{
- struct audioamd_softc *asc = opaque;
- struct am7930_softc *sc = &asc->sc_am7930;
-
- *intr = &sc->sc_intr_lock;
- *thread = &sc->sc_lock;
-}
-
#endif /* NAUDIO > 0 */
Index: src/sys/arch/sparc/sparc/genassym.cf
diff -u src/sys/arch/sparc/sparc/genassym.cf:1.70 src/sys/arch/sparc/sparc/genassym.cf:1.71
--- src/sys/arch/sparc/sparc/genassym.cf:1.70 Thu Feb 20 08:27:39 2020
+++ src/sys/arch/sparc/sparc/genassym.cf Sat Sep 12 05:19:16 2020
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.70 2020/02/20 08:27:39 skrll Exp $
+# $NetBSD: genassym.cf,v 1.71 2020/09/12 05:19:16 isaki Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -97,7 +97,6 @@ include <sparc/dev/zsvar.h>
endif
include <sys/bus.h>
-include <sparc/dev/audioamdvar.h>
include <sparc/dev/fdreg.h>
include <sparc/dev/fdvar.h>
@@ -237,14 +236,6 @@ define ZL_RBUF offsetof(struct zs_line,
define ZSRR1_DO_bit ffs(ZSRR1_DO) - 1
endif
-# audio trap handler fields
-define AU_BH offsetof(struct auio, au_bh)
-define AU_RDATA offsetof(struct auio, au_rdata)
-define AU_REND offsetof(struct auio, au_rend)
-define AU_PDATA offsetof(struct auio, au_pdata)
-define AU_PEND offsetof(struct auio, au_pend)
-define AU_EVCNT offsetof(struct auio, au_intrcnt.ev_count)
-
define PROM_BASE PROM_BASE
define PV_MAGIC offsetof(struct promvec, pv_magic)
Index: src/sys/arch/vax/vsa/vsaudio.c
diff -u src/sys/arch/vax/vsa/vsaudio.c:1.6 src/sys/arch/vax/vsa/vsaudio.c:1.7
--- src/sys/arch/vax/vsa/vsaudio.c:1.6 Wed Aug 26 12:59:28 2020
+++ src/sys/arch/vax/vsa/vsaudio.c Sat Sep 12 05:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vsaudio.c,v 1.6 2020/08/26 12:59:28 isaki Exp $ */
+/* $NetBSD: vsaudio.c,v 1.7 2020/09/12 05:19:16 isaki Exp $ */
/* $OpenBSD: vsaudio.c,v 1.4 2013/05/15 21:21:11 ratchov Exp $ */
/*
@@ -82,111 +82,47 @@
#include <dev/ic/am7930reg.h>
#include <dev/ic/am7930var.h>
-#ifdef AUDIO_DEBUG
-#define DPRINTF(x) if (am7930debug) printf x
-#define DPRINTFN(n,x) if (am7930debug>(n)) printf x
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif /* AUDIO_DEBUG */
-
/* physical addresses of the AM79C30 chip */
#define VSAUDIO_CSR 0x200d0000
#define VSAUDIO_CSR_KA49 0x26800000
-/* pdma state */
-struct auio {
- bus_space_tag_t au_bt; /* bus tag */
- bus_space_handle_t au_bh; /* handle to chip registers */
-
- uint8_t *au_rdata; /* record data */
- uint8_t *au_rend; /* end of record data */
- uint8_t *au_pdata; /* play data */
- uint8_t *au_pend; /* end of play data */
- struct evcnt au_intrcnt; /* statistics */
-};
-
-struct am7930_intrhand {
- int (*ih_fun)(void *);
- void *ih_arg;
-};
-
-
struct vsaudio_softc {
struct am7930_softc sc_am7930; /* glue to MI code */
+
bus_space_tag_t sc_bt; /* bus cookie */
bus_space_handle_t sc_bh; /* device registers */
-
- struct am7930_intrhand sc_ih; /* interrupt vector (hw or sw) */
- void (*sc_rintr)(void*); /* input completion intr handler */
- void *sc_rarg; /* arg for sc_rintr() */
- void (*sc_pintr)(void*); /* output completion intr handler */
- void *sc_parg; /* arg for sc_pintr() */
-
- uint8_t *sc_rdata; /* record data */
- uint8_t *sc_rend; /* end of record data */
- uint8_t *sc_pdata; /* play data */
- uint8_t *sc_pend; /* end of play data */
-
- struct auio sc_au; /* recv and xmit buffers, etc */
-#define sc_intrcnt sc_au.au_intrcnt /* statistics */
- void *sc_sicookie; /* softintr(9) cookie */
- int sc_cvec;
- kmutex_t sc_lock;
};
static int vsaudio_match(struct device *parent, struct cfdata *match, void *);
static void vsaudio_attach(device_t parent, device_t self, void *);
+static void vsaudio_hwintr(void *);
+
CFATTACH_DECL_NEW(vsaudio, sizeof(struct vsaudio_softc), vsaudio_match,
vsaudio_attach, NULL, NULL);
/*
* Hardware access routines for the MI code
*/
-uint8_t vsaudio_codec_iread(struct am7930_softc *, int);
-uint16_t vsaudio_codec_iread16(struct am7930_softc *, int);
-uint8_t vsaudio_codec_dread(struct vsaudio_softc *, int);
-void vsaudio_codec_iwrite(struct am7930_softc *, int, uint8_t);
-void vsaudio_codec_iwrite16(struct am7930_softc *, int, uint16_t);
-void vsaudio_codec_dwrite(struct vsaudio_softc *, int, uint8_t);
-void vsaudio_onopen(struct am7930_softc *);
-void vsaudio_onclose(struct am7930_softc *);
-
-/*
-static stream_filter_factory_t vsaudio_output_conv;
-static stream_filter_factory_t vsaudio_input_conv;
-static int vsaudio_output_conv_fetch_to(struct audio_softc *,
- stream_fetcher_t *, audio_stream_t *, int);
-static int vsaudio_input_conv_fetch_to(struct audio_softc *,
- stream_fetcher_t *, audio_stream_t *, int);
- */
+uint8_t vsaudio_codec_dread(struct am7930_softc *, int);
+void vsaudio_codec_dwrite(struct am7930_softc *, int, uint8_t);
struct am7930_glue vsaudio_glue = {
- vsaudio_codec_iread,
- vsaudio_codec_iwrite,
- vsaudio_codec_iread16,
- vsaudio_codec_iwrite16,
- vsaudio_onopen,
- vsaudio_onclose,
+ vsaudio_codec_dread,
+ vsaudio_codec_dwrite,
};
/*
* Interface to the MI audio layer.
*/
-int vsaudio_start_output(void *, void *, int, void (*)(void *), void *);
-int vsaudio_start_input(void *, void *, int, void (*)(void *), void *);
int vsaudio_getdev(void *, struct audio_device *);
-void vsaudio_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread);
struct audio_hw_if vsaudio_hw_if = {
- .open = am7930_open,
- .close = am7930_close,
.query_format = am7930_query_format,
.set_format = am7930_set_format,
.commit_settings = am7930_commit_settings,
- .start_output = vsaudio_start_output,
- .start_input = vsaudio_start_input,
+ .trigger_output = am7930_trigger_output,
+ .trigger_input = am7930_trigger_input,
.halt_output = am7930_halt_output,
.halt_input = am7930_halt_input,
.getdev = vsaudio_getdev,
@@ -194,7 +130,7 @@ struct audio_hw_if vsaudio_hw_if = {
.get_port = am7930_get_port,
.query_devinfo = am7930_query_devinfo,
.get_props = am7930_get_props,
- .get_locks = vsaudio_get_locks,
+ .get_locks = am7930_get_locks,
};
@@ -204,15 +140,10 @@ struct audio_device vsaudio_device = {
"vsaudio"
};
-void vsaudio_hwintr(void *);
-void vsaudio_swintr(void *);
-struct auio *auiop;
-
static int
vsaudio_match(struct device *parent, struct cfdata *match, void *aux)
{
- struct vsbus_softc *sc __attribute__((__unused__)) = device_private(parent);
struct vsbus_attach_args *va = aux;
volatile uint32_t *regs;
int i;
@@ -264,6 +195,7 @@ vsaudio_attach(device_t parent, device_t
{
struct vsbus_attach_args *va = aux;
struct vsaudio_softc *sc = device_private(self);
+ struct am7930_softc *amsc = &sc->sc_am7930;
if (bus_space_map(va->va_memt, va->va_paddr, AM7930_DREG_SIZE << 2, 0,
&sc->sc_bh) != 0) {
@@ -271,249 +203,49 @@ vsaudio_attach(device_t parent, device_t
return;
}
sc->sc_bt = va->va_memt;
- sc->sc_am7930.sc_dev = self;
- sc->sc_am7930.sc_glue = &vsaudio_glue;
- mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
- am7930_init(&sc->sc_am7930, AUDIOAMD_POLL_MODE);
- auiop = &sc->sc_au;
- /* Copy bus tag & handle for use by am7930_trap */
- sc->sc_au.au_bt = sc->sc_bt;
- sc->sc_au.au_bh = sc->sc_bh;
- scb_vecalloc(va->va_cvec, vsaudio_hwintr, sc, SCB_ISTACK,
- &sc->sc_intrcnt);
- sc->sc_cvec = va->va_cvec;
- evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
+ amsc->sc_dev = self;
+ amsc->sc_glue = &vsaudio_glue;
+ am7930_init(amsc, AUDIOAMD_POLL_MODE);
+ scb_vecalloc(va->va_cvec, vsaudio_hwintr, amsc, SCB_ISTACK,
+ &amsc->sc_intrcnt);
+ evcnt_attach_dynamic(&amsc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
device_xname(self), "intr");
- sc->sc_sicookie = softint_establish(SOFTINT_SERIAL,
- &vsaudio_swintr, sc);
- if (sc->sc_sicookie == NULL) {
- aprint_normal("\n%s: cannot establish software interrupt\n",
- device_xname(self));
- return;
- }
-
aprint_normal("\n");
audio_attach_mi(&vsaudio_hw_if, sc, self);
-
-}
-
-void
-vsaudio_onopen(struct am7930_softc *sc)
-{
- struct vsaudio_softc *vssc = (struct vsaudio_softc *)sc;
-
- mutex_spin_enter(&vssc->sc_lock);
- /* reset pdma state */
- vssc->sc_rintr = NULL;
- vssc->sc_rarg = 0;
- vssc->sc_pintr = NULL;
- vssc->sc_parg = 0;
-
- vssc->sc_rdata = NULL;
- vssc->sc_pdata = NULL;
- mutex_spin_exit(&vssc->sc_lock);
}
-void
-vsaudio_onclose(struct am7930_softc *sc)
-{
- am7930_halt_input(sc);
- am7930_halt_output(sc);
-}
-
-/*
- * this is called by interrupt code-path, don't lock
- */
-int
-vsaudio_start_output(void *addr, void *p, int cc,
- void (*intr)(void *), void *arg)
-{
- struct vsaudio_softc *sc = addr;
-
- DPRINTFN(1, ("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
-
- mutex_spin_enter(&sc->sc_lock);
- vsaudio_codec_iwrite(&sc->sc_am7930,
- AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
- DPRINTF(("sa_start_output: started intrs.\n"));
- sc->sc_pintr = intr;
- sc->sc_parg = arg;
- sc->sc_au.au_pdata = p;
- sc->sc_au.au_pend = (char *)p + cc - 1;
- mutex_spin_exit(&sc->sc_lock);
- return 0;
-}
-
-/*
- * this is called by interrupt code-path, don't lock
- */
-int
-vsaudio_start_input(void *addr, void *p, int cc,
- void (*intr)(void *), void *arg)
-{
- struct vsaudio_softc *sc = addr;
-
- DPRINTFN(1, ("sa_start_input: cc=%d %p (%p)\n", cc, intr, arg));
-
- mutex_spin_enter(&sc->sc_lock);
- vsaudio_codec_iwrite(&sc->sc_am7930,
- AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
-
- sc->sc_rintr = intr;
- sc->sc_rarg = arg;
- sc->sc_au.au_rdata = p;
- sc->sc_au.au_rend = (char *)p + cc -1;
- mutex_spin_exit(&sc->sc_lock);
- DPRINTF(("sa_start_input: started intrs.\n"));
- return 0;
-}
-
-
-void
-vsaudio_hwintr(void *v)
-{
- struct vsaudio_softc *sc;
- struct auio *au;
- uint8_t *d, *e;
- int __attribute__((__unused__)) k;
-
- sc = v;
- au = &sc->sc_au;
- mutex_spin_enter(&sc->sc_lock);
- /* clear interrupt */
- k = vsaudio_codec_dread(sc, AM7930_DREG_IR);
-#if 0 /* interrupt is not shared, this shouldn't happen */
- if ((k & (AM7930_IR_DTTHRSH | AM7930_IR_DRTHRSH | AM7930_IR_DSRI |
- AM7930_IR_DERI | AM7930_IR_BBUFF)) == 0) {
- mtx_leave(&audio_lock);
- return 0;
- }
-#endif
- /* receive incoming data */
- d = au->au_rdata;
- e = au->au_rend;
- if (d != NULL && d <= e) {
- *d = vsaudio_codec_dread(sc, AM7930_DREG_BBRB);
- au->au_rdata++;
- if (d == e) {
- DPRINTFN(1, ("vsaudio_hwintr: swintr(r) requested"));
- softint_schedule(sc->sc_sicookie);
- }
- }
-
- /* send outgoing data */
- d = au->au_pdata;
- e = au->au_pend;
- if (d != NULL && d <= e) {
- vsaudio_codec_dwrite(sc, AM7930_DREG_BBTB, *d);
- au->au_pdata++;
- if (d == e) {
- DPRINTFN(1, ("vsaudio_hwintr: swintr(p) requested"));
- softint_schedule(sc->sc_sicookie);
- }
- }
- mutex_spin_exit(&sc->sc_lock);
-}
-
-void
-vsaudio_swintr(void *v)
-{
- struct vsaudio_softc *sc;
- struct auio *au;
- int dor, dow;
-
- sc = v;
- au = &sc->sc_au;
-
- DPRINTFN(1, ("audiointr: sc=%p\n", sc));
-
- dor = dow = 0;
- mutex_spin_enter(&sc->sc_am7930.sc_intr_lock);
- if (au->au_rdata > au->au_rend && sc->sc_rintr != NULL)
- dor = 1;
- if (au->au_pdata > au->au_pend && sc->sc_pintr != NULL)
- dow = 1;
-
- if (dor != 0)
- (*sc->sc_rintr)(sc->sc_rarg);
- if (dow != 0)
- (*sc->sc_pintr)(sc->sc_parg);
- mutex_spin_exit(&sc->sc_am7930.sc_intr_lock);
-}
-
-
-/* indirect write */
-void
-vsaudio_codec_iwrite(struct am7930_softc *sc, int reg, uint8_t val)
-{
- struct vsaudio_softc *vssc = (struct vsaudio_softc *)sc;
-
- vsaudio_codec_dwrite(vssc, AM7930_DREG_CR, reg);
- vsaudio_codec_dwrite(vssc, AM7930_DREG_DR, val);
-}
-
-void
-vsaudio_codec_iwrite16(struct am7930_softc *sc, int reg, uint16_t val)
-{
- struct vsaudio_softc *vssc = (struct vsaudio_softc *)sc;
-
- vsaudio_codec_dwrite(vssc, AM7930_DREG_CR, reg);
- vsaudio_codec_dwrite(vssc, AM7930_DREG_DR, val);
- vsaudio_codec_dwrite(vssc, AM7930_DREG_DR, val >> 8);
-}
-
-/* indirect read */
-uint8_t
-vsaudio_codec_iread(struct am7930_softc *sc, int reg)
-{
- struct vsaudio_softc *vssc = (struct vsaudio_softc *)sc;
-
- vsaudio_codec_dwrite(vssc, AM7930_DREG_CR, reg);
- return vsaudio_codec_dread(vssc, AM7930_DREG_DR);
-}
-
-uint16_t
-vsaudio_codec_iread16(struct am7930_softc *sc, int reg)
+static void
+vsaudio_hwintr(void *arg)
{
- struct vsaudio_softc *vssc = (struct vsaudio_softc *)sc;
- uint lo, hi;
- vsaudio_codec_dwrite(vssc, AM7930_DREG_CR, reg);
- lo = vsaudio_codec_dread(vssc, AM7930_DREG_DR);
- hi = vsaudio_codec_dread(vssc, AM7930_DREG_DR);
- return (hi << 8) | lo;
+ am7930_hwintr(arg);
}
/* direct read */
uint8_t
-vsaudio_codec_dread(struct vsaudio_softc *sc, int reg)
+vsaudio_codec_dread(struct am7930_softc *amsc, int reg)
{
+ struct vsaudio_softc *sc = (struct vsaudio_softc *)amsc;
+
return bus_space_read_1(sc->sc_bt, sc->sc_bh, reg << 2);
}
/* direct write */
void
-vsaudio_codec_dwrite(struct vsaudio_softc *sc, int reg, uint8_t val)
+vsaudio_codec_dwrite(struct am7930_softc *amsc, int reg, uint8_t val)
{
+ struct vsaudio_softc *sc = (struct vsaudio_softc *)amsc;
+
bus_space_write_1(sc->sc_bt, sc->sc_bh, reg << 2, val);
}
int
vsaudio_getdev(void *addr, struct audio_device *retp)
{
+
*retp = vsaudio_device;
return 0;
}
-void
-vsaudio_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
-{
- struct vsaudio_softc *asc = opaque;
- struct am7930_softc *sc = &asc->sc_am7930;
-
- *intr = &sc->sc_intr_lock;
- *thread = &sc->sc_lock;
-}
-
#endif /* NAUDIO > 0 */
Index: src/sys/dev/ic/am7930.c
diff -u src/sys/dev/ic/am7930.c:1.59 src/sys/dev/ic/am7930.c:1.60
--- src/sys/dev/ic/am7930.c:1.59 Sat Jun 8 08:02:38 2019
+++ src/sys/dev/ic/am7930.c Sat Sep 12 05:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: am7930.c,v 1.59 2019/06/08 08:02:38 isaki Exp $ */
+/* $NetBSD: am7930.c,v 1.60 2020/09/12 05:19:16 isaki Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@@ -36,13 +36,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: am7930.c,v 1.59 2019/06/08 08:02:38 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: am7930.c,v 1.60 2020/09/12 05:19:16 isaki Exp $");
#include "audio.h"
#if NAUDIO > 0
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/atomic.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/device.h>
@@ -149,13 +150,58 @@ static const struct audio_format am7930_
};
/*
+ * Indirect access functions.
+ */
+
+static void
+am7930_iwrite(struct am7930_softc *sc, int reg, uint8_t val)
+{
+
+ AM7930_DWRITE(sc, AM7930_DREG_CR, reg);
+ AM7930_DWRITE(sc, AM7930_DREG_DR, val);
+}
+
+static uint8_t
+am7930_iread(struct am7930_softc *sc, int reg)
+{
+
+ AM7930_DWRITE(sc, AM7930_DREG_CR, reg);
+ return AM7930_DREAD(sc, AM7930_DREG_DR);
+}
+
+static void
+am7930_iwrite16(struct am7930_softc *sc, int reg, uint16_t val)
+{
+
+ AM7930_DWRITE(sc, AM7930_DREG_CR, reg);
+ AM7930_DWRITE(sc, AM7930_DREG_DR, val);
+ AM7930_DWRITE(sc, AM7930_DREG_DR, val >> 8);
+}
+
+static uint16_t __unused
+am7930_iread16(struct am7930_softc *sc, int reg)
+{
+ uint lo, hi;
+
+ AM7930_DWRITE(sc, AM7930_DREG_CR, reg);
+ lo = AM7930_DREAD(sc, AM7930_DREG_DR);
+ hi = AM7930_DREAD(sc, AM7930_DREG_DR);
+ return (hi << 8) | lo;
+}
+
+#define AM7930_IWRITE(sc,r,v) am7930_iwrite(sc,r,v)
+#define AM7930_IREAD(sc,r) am7930_iread(sc,r)
+#define AM7930_IWRITE16(sc,r,v) am7930_iwrite16(sc,r,v)
+#define AM7930_IREAD16(sc,r) am7930_iread16(sc,r)
+
+/*
* Reset chip and set boot-time softc defaults.
*/
void
am7930_init(struct am7930_softc *sc, int flag)
{
- DPRINTF(("am7930_init()\n"));
+ DPRINTF(("%s\n", __func__));
/* set boot defaults */
sc->sc_rlevel = 128;
@@ -164,6 +210,9 @@ am7930_init(struct am7930_softc *sc, int
sc->sc_out_port = AUDIOAMD_SPEAKER_VOL;
sc->sc_mic_mute = 0;
+ memset(&sc->sc_p, 0, sizeof(sc->sc_p));
+ memset(&sc->sc_r, 0, sizeof(sc->sc_r));
+
/* disable sample interrupts */
AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4, 0);
@@ -184,6 +233,7 @@ am7930_init(struct am7930_softc *sc, int
AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR2, AM7930_MCRCHAN_NC);
AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR3, AM7930_MCRCHAN_NC);
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
} else {
/*
@@ -198,33 +248,18 @@ am7930_init(struct am7930_softc *sc, int
(AM7930_MCRCHAN_BB << 4) | AM7930_MCRCHAN_BA);
AM7930_IWRITE(sc, AM7930_IREG_MUX_MCR4,
AM7930_MCR4_INT_ENABLE);
+
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SOFTSERIAL);
}
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
-}
-int
-am7930_open(void *addr, int flags)
-{
- struct am7930_softc *sc;
-
- sc = addr;
- DPRINTF(("sa_open: unit %p\n", sc));
- sc->sc_glue->onopen(sc);
- DPRINTF(("saopen: ok -> sc=%p\n",sc));
- return 0;
-}
-
-void
-am7930_close(void *addr)
-{
- struct am7930_softc *sc;
-
- sc = addr;
- DPRINTF(("sa_close: sc=%p\n", sc));
- sc->sc_glue->onclose(sc);
- DPRINTF(("sa_close: closed.\n"));
+ sc->sc_sicookie = softint_establish(SOFTINT_SERIAL, &am7930_swintr, sc);
+ if (sc->sc_sicookie == NULL) {
+ aprint_error_dev(sc->sc_dev,
+ "cannot establish software interrupt\n");
+ return;
+ }
}
int
@@ -258,7 +293,7 @@ am7930_commit_settings(void *addr)
uint8_t mmr2, mmr3;
int level;
- DPRINTF(("sa_commit.\n"));
+ DPRINTF(("%s\n", __func__));
sc = addr;
gx = gx_coeff[sc->sc_rlevel];
stgr = gx_coeff[sc->sc_mlevel];
@@ -303,14 +338,65 @@ am7930_commit_settings(void *addr)
}
int
+am7930_trigger_output(void *addr, void *start, void *end, int blksize,
+ void (*intr)(void *), void *arg, const audio_params_t *params)
+{
+ struct am7930_softc *sc;
+
+ DPRINTF(("%s: blksize=%d %p(%p)\n", __func__, blksize, intr, arg));
+ sc = addr;
+ sc->sc_p.intr = intr;
+ sc->sc_p.arg = arg;
+ sc->sc_p.start = start;
+ sc->sc_p.end = end;
+ sc->sc_p.blksize = blksize;
+ sc->sc_p.data = sc->sc_p.start;
+ sc->sc_p.blkend = sc->sc_p.start + sc->sc_p.blksize;
+
+ /* Start if either play or rec start. */
+ if (sc->sc_r.intr == NULL) {
+ AM7930_IWRITE(sc, AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
+ DPRINTF(("%s: started intrs.\n", __func__));
+ }
+ return 0;
+}
+
+int
+am7930_trigger_input(void *addr, void *start, void *end, int blksize,
+ void (*intr)(void *), void *arg, const audio_params_t *params)
+{
+ struct am7930_softc *sc;
+
+ DPRINTF(("%s: blksize=%d %p(%p)\n", __func__, blksize, intr, arg));
+ sc = addr;
+ sc->sc_r.intr = intr;
+ sc->sc_r.arg = arg;
+ sc->sc_r.start = start;
+ sc->sc_r.end = end;
+ sc->sc_r.blksize = blksize;
+ sc->sc_r.data = sc->sc_r.start;
+ sc->sc_r.blkend = sc->sc_r.start + sc->sc_r.blksize;
+
+ /* Start if either play or rec start. */
+ if (sc->sc_p.intr == NULL) {
+ AM7930_IWRITE(sc, AM7930_IREG_INIT, AM7930_INIT_PMS_ACTIVE);
+ DPRINTF(("%s: started intrs.\n", __func__));
+ }
+ return 0;
+}
+
+int
am7930_halt_output(void *addr)
{
struct am7930_softc *sc;
sc = addr;
- /* XXX only halt, if input is also halted ?? */
- AM7930_IWRITE(sc, AM7930_IREG_INIT,
- AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
+ sc->sc_p.intr = NULL;
+ /* Halt if both of play and rec halt. */
+ if (sc->sc_r.intr == NULL) {
+ AM7930_IWRITE(sc, AM7930_IREG_INIT,
+ AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
+ }
return 0;
}
@@ -320,12 +406,85 @@ am7930_halt_input(void *addr)
struct am7930_softc *sc;
sc = addr;
- /* XXX only halt, if output is also halted ?? */
- AM7930_IWRITE(sc, AM7930_IREG_INIT,
- AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
+ sc->sc_r.intr = NULL;
+ /* Halt if both of play and rec halt. */
+ if (sc->sc_p.intr == NULL) {
+ AM7930_IWRITE(sc, AM7930_IREG_INIT,
+ AM7930_INIT_PMS_ACTIVE | AM7930_INIT_INT_DISABLE);
+ }
return 0;
}
+int
+am7930_hwintr(void *arg)
+{
+ struct am7930_softc *sc;
+ int k __unused;
+
+ sc = arg;
+
+ /*
+ * This hwintr is called as pseudo-DMA. So don't acquire intr_lock.
+ */
+
+ /* clear interrupt */
+ k = AM7930_DREAD(sc, AM7930_DREG_IR);
+#if !defined(__vax__)
+ /* On vax, interrupt is not shared, this shouldn't happen */
+ if ((k & (AM7930_IR_DTTHRSH | AM7930_IR_DRTHRSH | AM7930_IR_DSRI |
+ AM7930_IR_DERI | AM7930_IR_BBUFF)) == 0) {
+ return 0;
+ }
+#endif
+
+ /* receive incoming data */
+ if (sc->sc_r.intr) {
+ *sc->sc_r.data++ = AM7930_DREAD(sc, AM7930_DREG_BBRB);
+ if (sc->sc_r.data == sc->sc_r.blkend) {
+ if (sc->sc_r.blkend == sc->sc_r.end) {
+ sc->sc_r.data = sc->sc_r.start;
+ sc->sc_r.blkend = sc->sc_r.start;
+ }
+ sc->sc_r.blkend += sc->sc_r.blksize;
+ atomic_store_relaxed(&sc->sc_r.intr_pending, 1);
+ softint_schedule(sc->sc_sicookie);
+ }
+ }
+
+ /* send outgoing data */
+ if (sc->sc_p.intr) {
+ AM7930_DWRITE(sc, AM7930_DREG_BBTB, *sc->sc_p.data++);
+ if (sc->sc_p.data == sc->sc_p.blkend) {
+ if (sc->sc_p.blkend == sc->sc_p.end) {
+ sc->sc_p.data = sc->sc_p.start;
+ sc->sc_p.blkend = sc->sc_p.start;
+ }
+ sc->sc_p.blkend += sc->sc_p.blksize;
+ atomic_store_relaxed(&sc->sc_p.intr_pending, 1);
+ softint_schedule(sc->sc_sicookie);
+ }
+ }
+
+ sc->sc_intrcnt.ev_count++;
+ return 1;
+}
+
+void
+am7930_swintr(void *cookie)
+{
+ struct am7930_softc *sc = cookie;
+
+ mutex_enter(&sc->sc_intr_lock);
+ if (atomic_cas_uint(&sc->sc_r.intr_pending, 1, 0) == 1) {
+ (*sc->sc_r.intr)(sc->sc_r.arg);
+ }
+ if (atomic_cas_uint(&sc->sc_p.intr_pending, 1, 0) == 1) {
+ (*sc->sc_p.intr)(sc->sc_p.arg);
+ }
+ mutex_exit(&sc->sc_intr_lock);
+}
+
+
/*
* XXX chip is full-duplex, but really attach-dependent.
* For now we know of no half-duplex attachments.
@@ -346,7 +505,7 @@ am7930_set_port(void *addr, mixer_ctrl_t
{
struct am7930_softc *sc;
- DPRINTF(("am7930_set_port: port=%d", cp->dev));
+ DPRINTF(("%s: port=%d\n", __func__, cp->dev));
sc = addr;
if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
@@ -394,7 +553,7 @@ am7930_get_port(void *addr, mixer_ctrl_t
{
struct am7930_softc *sc;
- DPRINTF(("am7930_get_port: port=%d\n", cp->dev));
+ DPRINTF(("%s: port=%d\n", __func__, cp->dev));
sc = addr;
if (cp->dev == AUDIOAMD_RECORD_SOURCE ||
cp->dev == AUDIOAMD_MONITOR_OUTPUT ||
@@ -441,7 +600,7 @@ int
am7930_query_devinfo(void *addr, mixer_devinfo_t *dip)
{
- DPRINTF(("am7930_query_devinfo()\n"));
+ DPRINTF(("%s\n", __func__));
switch(dip->index) {
case AUDIOAMD_MIC_VOL:
@@ -543,4 +702,14 @@ am7930_query_devinfo(void *addr, mixer_d
return 0;
}
+void
+am7930_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
+{
+ struct am7930_softc *sc;
+
+ sc = addr;
+ *intr = &sc->sc_intr_lock;
+ *thread = &sc->sc_lock;
+}
+
#endif /* NAUDIO */
Index: src/sys/dev/ic/am7930var.h
diff -u src/sys/dev/ic/am7930var.h:1.14 src/sys/dev/ic/am7930var.h:1.15
--- src/sys/dev/ic/am7930var.h:1.14 Wed May 8 13:40:18 2019
+++ src/sys/dev/ic/am7930var.h Sat Sep 12 05:19:16 2020
@@ -1,14 +1,22 @@
-/* $NetBSD: am7930var.h,v 1.14 2019/05/08 13:40:18 isaki Exp $ */
+/* $NetBSD: am7930var.h,v 1.15 2020/09/12 05:19:16 isaki Exp $ */
struct am7930_softc;
struct am7930_glue {
- uint8_t (*codec_iread)(struct am7930_softc *sc, int);
- void (*codec_iwrite)(struct am7930_softc *sc, int, uint8_t);
- uint16_t (*codec_iread16)(struct am7930_softc *sc, int);
- void (*codec_iwrite16)(struct am7930_softc *sc, int, uint16_t);
- void (*onopen)(struct am7930_softc *sc);
- void (*onclose)(struct am7930_softc *sc);
+ uint8_t (*codec_dread)(struct am7930_softc *sc, int);
+ void (*codec_dwrite)(struct am7930_softc *sc, int, uint8_t);
+};
+
+struct am7930_buf {
+ uint8_t *start;
+ uint8_t *end;
+ uint8_t *data;
+ uint8_t *blkend;
+ uint blksize;
+
+ void (*intr)(void *);
+ void *arg;
+ uint intr_pending;
};
struct am7930_softc {
@@ -21,19 +29,25 @@ struct am7930_softc {
uint8_t sc_mic_mute;
struct am7930_glue *sc_glue;
+ struct am7930_buf sc_p; /* for play */
+ struct am7930_buf sc_r; /* for rec */
kmutex_t sc_lock;
kmutex_t sc_intr_lock;
+ void *sc_sicookie; /* softint(9) cookie */
+ struct evcnt sc_intrcnt; /* statistics */
};
extern int am7930debug;
void am7930_init(struct am7930_softc *, int);
+int am7930_hwintr(void *);
+void am7930_swintr(void *);
+
+/* direct access functions */
+#define AM7930_DWRITE(x,y,z) (*(x)->sc_glue->codec_dwrite)((x),(y),(z))
+#define AM7930_DREAD(x,y) (*(x)->sc_glue->codec_dread)((x),(y))
-#define AM7930_IWRITE(x,y,z) (*(x)->sc_glue->codec_iwrite)((x),(y),(z))
-#define AM7930_IREAD(x,y) (*(x)->sc_glue->codec_iread)((x),(y))
-#define AM7930_IWRITE16(x,y,z) (*(x)->sc_glue->codec_iwrite16)((x),(y),(z))
-#define AM7930_IREAD16(x,y) (*(x)->sc_glue->codec_iread16)((x),(y))
#define AUDIOAMD_POLL_MODE 0
#define AUDIOAMD_DMA_MODE 1
@@ -61,17 +75,15 @@ void am7930_init(struct am7930_softc *,
* audio(9) MI callbacks from upper-level audio layer.
*/
-struct audio_device;
-struct audio_encoding;
-struct audio_params;
-
-int am7930_open(void *, int);
-void am7930_close(void *);
int am7930_query_format(void *, audio_format_query_t *);
int am7930_set_format(void *, int,
const audio_params_t *, const audio_params_t *,
audio_filter_reg_t *, audio_filter_reg_t *);
int am7930_commit_settings(void *);
+int am7930_trigger_output(void *, void *, void *, int, void (*)(void *),
+ void *, const audio_params_t *);
+int am7930_trigger_input(void *, void *, void *, int, void (*)(void *),
+ void *, const audio_params_t *);
int am7930_halt_output(void *);
int am7930_halt_input(void *);
int am7930_getdev(void *, struct audio_device *);
@@ -79,3 +91,4 @@ int am7930_get_props(void *);
int am7930_set_port(void *, mixer_ctrl_t *);
int am7930_get_port(void *, mixer_ctrl_t *);
int am7930_query_devinfo(void *, mixer_devinfo_t *);
+void am7930_get_locks(void *, kmutex_t **, kmutex_t **);
Index: src/sys/dev/tc/bba.c
diff -u src/sys/dev/tc/bba.c:1.45 src/sys/dev/tc/bba.c:1.46
--- src/sys/dev/tc/bba.c:1.45 Sat Aug 29 03:24:31 2020
+++ src/sys/dev/tc/bba.c Sat Sep 12 05:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: bba.c,v 1.45 2020/08/29 03:24:31 isaki Exp $ */
+/* $NetBSD: bba.c,v 1.46 2020/09/12 05:19:16 isaki Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
/* maxine/alpha baseboard audio (bba) */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bba.c,v 1.45 2020/08/29 03:24:31 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bba.c,v 1.46 2020/09/12 05:19:16 isaki Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -107,20 +107,12 @@ CFATTACH_DECL_NEW(bba, sizeof(struct bba
* Define our interface into the am7930 MI driver.
*/
-static uint8_t bba_codec_iread(struct am7930_softc *, int);
-static uint16_t bba_codec_iread16(struct am7930_softc *, int);
-static void bba_codec_iwrite(struct am7930_softc *, int, uint8_t);
-static void bba_codec_iwrite16(struct am7930_softc *, int, uint16_t);
-static void bba_onopen(struct am7930_softc *);
-static void bba_onclose(struct am7930_softc *);
+static uint8_t bba_codec_dread(struct am7930_softc *, int);
+static void bba_codec_dwrite(struct am7930_softc *, int, uint8_t);
struct am7930_glue bba_glue = {
- bba_codec_iread,
- bba_codec_iwrite,
- bba_codec_iread16,
- bba_codec_iwrite16,
- bba_onopen,
- bba_onclose,
+ bba_codec_dread,
+ bba_codec_dwrite,
};
/*
@@ -144,12 +136,8 @@ static int bba_trigger_output(void *, vo
static int bba_trigger_input(void *, void *, void *, int,
void (*)(void *), void *,
const audio_params_t *);
-static void bba_get_locks(void *opaque, kmutex_t **intr,
- kmutex_t **thread);
static const struct audio_hw_if sa_hw_if = {
- .open = am7930_open,
- .close = am7930_close,
.query_format = bba_query_format,
.set_format = bba_set_format,
.round_blocksize = bba_round_blocksize, /* md */
@@ -166,7 +154,7 @@ static const struct audio_hw_if sa_hw_if
.get_props = am7930_get_props,
.trigger_output = bba_trigger_output, /* md */
.trigger_input = bba_trigger_input, /* md */
- .get_locks = bba_get_locks,
+ .get_locks = am7930_get_locks,
};
static struct audio_device bba_device = {
@@ -188,8 +176,6 @@ static const struct audio_format bba_for
static int bba_intr(void *);
static void bba_reset(struct bba_softc *, int);
-static void bba_codec_dwrite(struct am7930_softc *, int, uint8_t);
-static uint8_t bba_codec_dread(struct am7930_softc *, int);
static int
bba_match(device_t parent, cfdata_t cf, void *aux)
@@ -210,13 +196,13 @@ bba_attach(device_t parent, device_t sel
{
struct ioasicdev_attach_args *ia;
struct bba_softc *sc;
- struct am7930_softc *asc;
+ struct am7930_softc *amsc;
struct ioasic_softc *iosc = device_private(parent);
ia = aux;
sc = device_private(self);
- asc = &sc->sc_am7930;
- asc->sc_dev = self;
+ amsc = &sc->sc_am7930;
+ amsc->sc_dev = self;
sc->sc_bst = iosc->sc_bst;
sc->sc_bsh = iosc->sc_bsh;
sc->sc_dmat = iosc->sc_dmat;
@@ -235,29 +221,17 @@ bba_attach(device_t parent, device_t sel
/*
* Set up glue for MI code early; we use some of it here.
*/
- asc->sc_glue = &bba_glue;
+ amsc->sc_glue = &bba_glue;
/*
* MI initialisation. We will be doing DMA.
*/
- am7930_init(asc, AUDIOAMD_DMA_MODE);
+ am7930_init(amsc, AUDIOAMD_DMA_MODE);
ioasic_intr_establish(parent, ia->iada_cookie, TC_IPL_NONE,
bba_intr, sc);
- audio_attach_mi(&sa_hw_if, asc, self);
-}
-
-
-static void
-bba_onopen(struct am7930_softc *sc)
-{
-}
-
-
-static void
-bba_onclose(struct am7930_softc *sc)
-{
+ audio_attach_mi(&sa_hw_if, sc, self);
}
@@ -291,7 +265,7 @@ bba_reset(struct bba_softc *sc, int rese
static void *
bba_allocm(void *addr, int direction, size_t size)
{
- struct am7930_softc *asc;
+ struct am7930_softc *amsc;
struct bba_softc *sc;
bus_dma_segment_t seg;
int rseg;
@@ -300,20 +274,20 @@ bba_allocm(void *addr, int direction, si
int state;
DPRINTF(("bba_allocm: size = %zu\n", size));
- asc = addr;
sc = addr;
+ amsc = addr;
state = 0;
if (bus_dmamem_alloc(sc->sc_dmat, size, BBA_DMABUF_ALIGN,
BBA_DMABUF_BOUNDARY, &seg, 1, &rseg, BUS_DMA_WAITOK)) {
- aprint_error_dev(asc->sc_dev, "can't allocate DMA buffer\n");
+ aprint_error_dev(amsc->sc_dev, "can't allocate DMA buffer\n");
goto bad;
}
state |= 1;
if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
&kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT)) {
- aprint_error_dev(asc->sc_dev, "can't map DMA buffer\n");
+ aprint_error_dev(amsc->sc_dev, "can't map DMA buffer\n");
goto bad;
}
state |= 2;
@@ -569,16 +543,6 @@ bad:
return 1;
}
-static void
-bba_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
-{
- struct bba_softc *bsc = opaque;
- struct am7930_softc *sc = &bsc->sc_am7930;
-
- *intr = &sc->sc_intr_lock;
- *thread = &sc->sc_lock;
-}
-
static int
bba_intr(void *addr)
{
@@ -647,64 +611,13 @@ bba_round_blocksize(void *addr, int blk,
}
-/* indirect write */
-static void
-bba_codec_iwrite(struct am7930_softc *sc, int reg, uint8_t val)
-{
-
- DPRINTF(("bba_codec_iwrite(): sc=%p, reg=%d, val=%d\n", sc, reg, val));
- bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
- bba_codec_dwrite(sc, AM7930_DREG_DR, val);
-}
-
-
-static void
-bba_codec_iwrite16(struct am7930_softc *sc, int reg, uint16_t val)
-{
-
- DPRINTF(("bba_codec_iwrite16(): sc=%p, reg=%d, val=%d\n", sc, reg, val));
- bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
- bba_codec_dwrite(sc, AM7930_DREG_DR, val);
- bba_codec_dwrite(sc, AM7930_DREG_DR, val>>8);
-}
-
-
-static uint16_t
-bba_codec_iread16(struct am7930_softc *sc, int reg)
-{
- uint16_t val;
-
- DPRINTF(("bba_codec_iread16(): sc=%p, reg=%d\n", sc, reg));
- bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
- val = bba_codec_dread(sc, AM7930_DREG_DR) << 8;
- val |= bba_codec_dread(sc, AM7930_DREG_DR);
-
- return val;
-}
-
-
-/* indirect read */
-static uint8_t
-bba_codec_iread(struct am7930_softc *sc, int reg)
-{
- uint8_t val;
-
- DPRINTF(("bba_codec_iread(): sc=%p, reg=%d\n", sc, reg));
- bba_codec_dwrite(sc, AM7930_DREG_CR, reg);
- val = bba_codec_dread(sc, AM7930_DREG_DR);
-
- DPRINTF(("read 0x%x (%d)\n", val, val));
-
- return val;
-}
-
/* direct write */
static void
-bba_codec_dwrite(struct am7930_softc *asc, int reg, uint8_t val)
+bba_codec_dwrite(struct am7930_softc *amsc, int reg, uint8_t val)
{
struct bba_softc *sc;
- sc = (struct bba_softc *)asc;
+ sc = (struct bba_softc *)amsc;
DPRINTF(("bba_codec_dwrite(): sc=%p, reg=%d, val=%d\n", sc, reg, val));
#if defined(__alpha__)
@@ -718,11 +631,11 @@ bba_codec_dwrite(struct am7930_softc *as
/* direct read */
static uint8_t
-bba_codec_dread(struct am7930_softc *asc, int reg)
+bba_codec_dread(struct am7930_softc *amsc, int reg)
{
struct bba_softc *sc;
- sc = (struct bba_softc *)asc;
+ sc = (struct bba_softc *)amsc;
DPRINTF(("bba_codec_dread(): sc=%p, reg=%d\n", sc, reg));
#if defined(__alpha__)