Subject: am7930 driver revisited...
To: None <tech-kern@netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-kern
Date: 03/07/1999 21:53:11
i have some ~8-months old patches to start using the am79c30 attached
to the DEC ioctl asic on TC alphas and the Personal DECstation.
One of the big gotchtas is that sys/dev/ic/am7930.c frobs a device
struct directly. That doesn't work very well with the DMA-based ioctl
attachment, not to mention endian-ness issues.
At the time i hacked up some MD macros (see below); should we commit
this (modulo updates in the meantime), or frob the driver directly to
bus_space(9) and make all attachments pass in a bus-space tag?
--- /sys/dev/ic/am7930.c Fri Aug 28 04:11:14 1998
+++ /sys/dev/ic/am7930subr.c Sun Jun 21 23:05:16 1998
@@ -1,4 +1,4 @@
-/* $NetBSD: am7930.c,v 1.40 1998/08/28 08:59:14 pk Exp $ */
+/* $NetBSD: am7930.c,v 1.33.2.1 1997/12/09 20:22:24 thorpej Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@@ -53,13 +53,16 @@
#include <dev/audio_if.h>
#include <dev/ic/am7930reg.h>
+#include <machine/am7930_machdep.h>
#include <dev/ic/am7930var.h>
#define AUDIO_ROM_NAME "audio"
#ifdef AUDIO_DEBUG
+extern void Dprintf __P((const char *, ...));
+
int am7930debug = 0;
-#define DPRINTF(x) if (am7930debug) printf x
+#define DPRINTF(x) if (am7930debug) Dprintf x
#else
#define DPRINTF(x)
#endif
@@ -164,16 +167,20 @@
sc->sc_plevel = 128;
sc->sc_mlevel = 0;
sc->sc_out_port = SUNAUDIO_SPEAKER;
+/*XXX*/ printf("doing init_amd()\n");
init_amd(sc->sc_amd);
+/*XXX*/ printf("done init_amd()\n");
}
static void
init_amd(amd)
register volatile struct am7930 *amd;
{
+/*XXX*/ printf("in init_amd()\n");
/* disable interrupts */
- amd->cr = AMDR_INIT;
- amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
+ AM7930_WRITE_REG(amd, cr, AMDR_INIT);
+/*XXX*/ printf("in init_amd()\n");
+ AM7930_WRITE_REG(amd, dr, AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
/*
* Initialize the mux unit. We use MCR3 to route audio (MAP)
@@ -181,11 +188,11 @@
* Setting the INT enable bit in MCR4 will generate an interrupt
* on each converted audio sample.
*/
- amd->cr = AMDR_MUX_1_4;
- amd->dr = 0;
- amd->dr = 0;
- amd->dr = (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA;
- amd->dr = AMD_MCR4_INT_ENABLE;
+ AM7930_WRITE_REG(amd, cr, AMDR_MUX_1_4);
+ AM7930_WRITE_REG(amd, dr, 0);
+ AM7930_WRITE_REG(amd, dr, 0);
+ AM7930_WRITE_REG(amd, dr, (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA);
+ AM7930_WRITE_REG(amd, dr, AMD_MCR4_INT_ENABLE);
}
int
@@ -205,7 +212,7 @@
/* tell attach layer about open */
sc->sc_onopen(sc);
- DPRINTF(("saopen: ok -> sc=%p\n", sc));
+ DPRINTF(("saopen: ok -> sc=0x%x\n",sc));
return (0);
}
@@ -216,7 +223,7 @@
{
register struct am7930_softc *sc = addr;
- DPRINTF(("sa_close: sc=%p\n", sc));
+ DPRINTF(("sa_close: sc=0x%x\n", sc));
/*
* halt i/o, clear open flag, and done.
*/
@@ -303,18 +310,22 @@
s = splaudio();
- amd->cr = AMDR_MAP_MMR1;
- amd->dr = map->mr_mmr1;
- amd->cr = AMDR_MAP_GX;
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_MMR1);
+ AM7930_WRITE_REG(amd, dr, map->mr_mmr1);
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_GX);
WAMD16(sc, amd, map->mr_gx);
- amd->cr = AMDR_MAP_STG;
+
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_STG);
WAMD16(sc, amd, map->mr_stgr);
- amd->cr = AMDR_MAP_GR;
+
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_GR);
WAMD16(sc, amd, map->mr_gr);
- amd->cr = AMDR_MAP_GER;
+
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_GER);
WAMD16(sc, amd, map->mr_ger);
- amd->cr = AMDR_MAP_MMR2;
- amd->dr = map->mr_mmr2;
+
+ AM7930_WRITE_REG(amd, cr, AMDR_MAP_MMR2);
+ AM7930_WRITE_REG(amd, dr, map->mr_mmr2);
splx(s);
return(0);
@@ -328,8 +339,8 @@
register volatile struct am7930 *amd = sc->sc_amd;
/* XXX only halt, if input is also halted ?? */
- amd->cr = AMDR_INIT;
- amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
+ AM7930_WRITE_REG(amd, cr, AMDR_INIT);
+ AM7930_WRITE_REG(amd, dr, AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
sc->sc_locked = 0;
return(0);
@@ -343,8 +354,8 @@
register volatile struct am7930 *amd = sc->sc_amd;
/* XXX only halt, if output is also halted ?? */
- amd->cr = AMDR_INIT;
- amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
+ AM7930_WRITE_REG(amd, cr, AMDR_INIT);
+ AM7930_WRITE_REG(amd, dr, AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
sc->sc_locked = 0;
return(0);
--- /dev/null Sun Mar 7 20:20:35 1999
+++ /sys/arch/pmax/include/am7930_machdep.h Mon Jun 22 00:02:28 1998
@@ -0,0 +1,21 @@
+/* $NetBSD: am7930_machdep.h,v 1.0 1998/06/20 20:22:24 jonathan Exp $ */
+
+#ifndef _AM7930_MACHDEP_H_
+#define _AM7930_MACHDEP_H_
+
+#define AUDIO_C_HANDLER /* use C code to move samples, byte by byte */
+
+#define AM7930_REGOFF(rreg) (offsetof(struct am7930, rreg) * (1 << 6))
+
+#define AM7930_WRITE_REG(amd, reg, val) \
+ do {((volatile u_char*)amd)[AM7930_REGOFF(reg)] = (val); tc_wmb();} while (0)
+
+#define AM7930_READ_REG(amd, reg) \
+ ( ((u_char*)amd)[AM7930_REGOFF(reg)] )
+
+struct intrhand {
+ int (*ih_fun) __P((void*));
+ void * ih_arg;
+};
+
+#endif /* _AM7930_MACHDEP_H_ */