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__)