Use bus_space tags and handles, embedded in MD hooks AM7930_{READ_WRITE}_REG

to handle MD delay and bus padding. Tested on sparc2 by David Brownlee.

Should use regmaps, but that breaks sparc pDMA assembly code.
This commit is contained in:
jonathan 1999-03-14 22:29:00 +00:00
parent 58e1f7b9b0
commit 69d2d27c1b
7 changed files with 122 additions and 67 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930_sparc.c,v 1.43 1999/01/13 04:19:08 abs Exp $ */
/* $NetBSD: am7930_sparc.c,v 1.44 1999/03/14 22:29:00 jonathan Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@ -46,6 +46,7 @@
#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"
@ -107,7 +108,7 @@ int am7930_set_port __P((void *, mixer_ctrl_t *));
int am7930_get_port __P((void *, mixer_ctrl_t *));
int am7930_query_devinfo __P((void *, mixer_devinfo_t *));
void am7930_sparc_w16 __P((volatile struct am7930 *amd, u_int16_t val));
void am7930_sparc_w16 __P((bus_space_tag_t bt, bus_space_handle_t bh, u_int16_t val));
struct audio_hw_if sa_hw_if = {
am7930_open,
@ -188,7 +189,7 @@ am7930attach_mainbus(parent, self, aux)
printf("%s: cannot map registers\n", self->dv_xname);
return;
}
sc->sc_amd = (volatile struct am7930 *)bh;
sc->sc_bh = bh;
am7930_sparc_attach(sc, ma->ma_pri);
}
@ -213,7 +214,7 @@ am7930attach_sbus(parent, self, aux)
printf("%s: cannot map registers\n", self->dv_xname);
return;
}
sc->sc_amd = (volatile struct am7930 *)bh;
sc->sc_bh = bh;
am7930_sparc_attach(sc, sa->sa_pri);
}
@ -225,7 +226,6 @@ am7930_sparc_attach(sc, pri)
printf(" softpri %d\n", PIL_AUSOFT);
sc->sc_au.au_amd = sc->sc_amd;
am7930_init(sc);
sc->sc_wam16 = am7930_sparc_w16;
@ -255,12 +255,13 @@ am7930_sparc_attach(sc, pri)
* 16-bit register write, big-endian mapping.
*/
void
am7930_sparc_w16(amd, val)
volatile struct am7930 *amd;
am7930_sparc_w16(bt, bh, val)
bus_space_tag_t bt;
bus_space_handle_t bh;
u_int16_t val;
{
amd->dr = val;
amd->dr = val >> 8;
AM7930_WRITE_REG(bt, bh, dr, val);
AM7930_WRITE_REG(bt, bh, dr, val >> 8);
}
@ -310,11 +311,11 @@ am7930_start_output(addr, p, cc, intr, arg)
#endif
if (!sc->sc_locked) {
register volatile struct am7930 *amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
amd = sc->sc_au.au_amd;
amd->cr = AMDR_INIT;
amd->dr = AMD_INIT_PMS_ACTIVE;
AM7930_WRITE_REG(bt, bh, cr, AMDR_INIT);
AM7930_WRITE_REG(bt, bh, dr, AMD_INIT_PMS_ACTIVE);
sc->sc_locked = 1;
DPRINTF(("sa_start_output: started intrs.\n"));
}
@ -342,11 +343,11 @@ am7930_start_input(addr, p, cc, intr, arg)
#endif
if (!sc->sc_locked) {
register volatile struct am7930 *amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
amd = sc->sc_au.au_amd;
amd->cr = AMDR_INIT;
amd->dr = AMD_INIT_PMS_ACTIVE;
AM7930_WRITE_REG(bt, bh, cr, AMDR_INIT);
AM7930_WRITE_REG(bt, bh, dr, AMD_INIT_PMS_ACTIVE);
sc->sc_locked = 1;
DPRINTF(("sa_start_input: started intrs.\n"));
}
@ -371,17 +372,18 @@ am7930hwintr(au0)
void *au0;
{
register struct auio *au = au0;
register volatile struct am7930 *amd = au->au_amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
register u_char *d, *e;
register int k;
k = amd->ir; /* clear interrupt */
k = AM7930_READ_REG(bt, bh, ir); /* clear interrupt */
/* receive incoming data */
d = au->au_rdata;
e = au->au_rend;
if (d && d <= e) {
*d = amd->bbrb;
*d = AM7930_READ_REG(bt, bh, bbrb);
au->au_rdata++;
if (d == e) {
#ifdef AUDIO_DEBUG
@ -396,7 +398,7 @@ am7930hwintr(au0)
d = au->au_pdata;
e = au->au_pend;
if (d && d <= e) {
amd->bbtb = *d;
AM7930_WRITE_REG(bt, bh, bbtb, *d);
au->au_pdata++;
if (d == e) {
#ifdef AUDIO_DEBUG

View File

@ -0,0 +1,14 @@
/* $NetBSD: am7930_machdep.h,v 1.1 1999/03/14 22:29:00 jonathan Exp $ */
/*
* Machine-dependent register accessors for am7930.
* On Sparc, these are direct bus_space operations.
*/
#define AM7930_REGOFF(reg) (offsetof(struct am7930, reg))
#define AM7930_WRITE_REG(bt, bh, reg, val) \
bus_space_write_1((bt), (bh), AM7930_REGOFF(reg), (val))
#define AM7930_READ_REG(bt, bh, reg) \
bus_space_read_1((bt), (bh), AM7930_REGOFF(reg), (val))

View File

@ -1,4 +1,4 @@
/* $NetBSD: amd7930intr.s,v 1.14 1999/03/07 22:36:04 pk Exp $ */
/* $NetBSD: amd7930intr.s,v 1.15 1999/03/14 22:29:00 jonathan Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann.
* Copyright (c) 1992, 1993
@ -119,7 +119,7 @@ _ENTRY(_C_LABEL(amd7930_trap))
inc %l6
st %l6, [%l7 + AU_EVCNT]
ld [%l7 + AU_AMD], R_amd
ld [%l7 + AU_BH], R_amd
ldub [R_amd + AMD_IR], %g0 ! clear interrupt
! receive incoming data

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.19 1999/02/14 12:48:02 pk Exp $
# $NetBSD: genassym.cf,v 1.20 1999/03/14 22:29:00 jonathan Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -217,7 +217,7 @@ define ZSRR1_DO_bit ffs(ZSRR1_DO) - 1
endif
# audio trap handler fields
define AU_AMD offsetof(struct auio, au_amd)
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)

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930.c,v 1.40 1998/08/28 08:59:14 pk Exp $ */
/* $NetBSD: am7930.c,v 1.41 1999/03/14 22:29:01 jonathan Exp $ */
/*
* Copyright (c) 1995 Rolf Grossmann
@ -53,11 +53,13 @@
#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
int am7930debug = 0;
#define DPRINTF(x) if (am7930debug) printf x
#else
@ -65,7 +67,7 @@ int am7930debug = 0;
#endif
/* forward declarations */
static void init_amd __P((volatile struct am7930 *));
static void init_amd __P((bus_space_tag_t bt, bus_space_handle_t bh));
/*
* Audio device descriptor (attachment independent)
@ -156,6 +158,10 @@ void
am7930_init(sc)
struct am7930_softc *sc;
{
/* Save bustag and handle in pdma struct. XXX is this MI? */
sc->sc_au.au_bt = sc->sc_bustag;
sc->sc_au.au_bh = sc->sc_bh;
sc->sc_map.mr_mmr1 = AMD_MMR1_GX | AMD_MMR1_GER |
AMD_MMR1_GR | AMD_MMR1_STG;
@ -164,16 +170,18 @@ am7930_init(sc)
sc->sc_plevel = 128;
sc->sc_mlevel = 0;
sc->sc_out_port = SUNAUDIO_SPEAKER;
init_amd(sc->sc_amd);
init_amd(sc->sc_bustag, sc->sc_bh);
}
static void
init_amd(amd)
register volatile struct am7930 *amd;
init_amd(bt, bh)
register bus_space_tag_t bt;
register bus_space_handle_t bh;
{
/* disable interrupts */
amd->cr = AMDR_INIT;
amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
AM7930_WRITE_REG(bt, bh, cr, AMDR_INIT);
AM7930_WRITE_REG(bt, bh, dr,
AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
/*
* Initialize the mux unit. We use MCR3 to route audio (MAP)
@ -181,11 +189,11 @@ init_amd(amd)
* 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(bt, bh, cr, AMDR_MUX_1_4);
AM7930_WRITE_REG(bt, bh, dr, 0);
AM7930_WRITE_REG(bt, bh, dr, 0);
AM7930_WRITE_REG(bt, bh, dr, (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA);
AM7930_WRITE_REG(bt, bh, dr, AMD_MCR4_INT_ENABLE);
}
int
@ -205,7 +213,7 @@ am7930_open(addr, flags)
/* tell attach layer about open */
sc->sc_onopen(sc);
DPRINTF(("saopen: ok -> sc=%p\n", sc));
DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
return (0);
}
@ -276,13 +284,13 @@ am7930_commit_settings(addr)
{
register struct am7930_softc *sc = addr;
register struct mapreg *map;
register volatile struct am7930 *amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
register int s, level;
DPRINTF(("sa_commit.\n"));
map = &sc->sc_map;
amd = sc->sc_amd;
map->mr_gx = gx_coeff[sc->sc_rlevel];
map->mr_stgr = gx_coeff[sc->sc_mlevel];
@ -303,18 +311,22 @@ am7930_commit_settings(addr)
s = splaudio();
amd->cr = AMDR_MAP_MMR1;
amd->dr = map->mr_mmr1;
amd->cr = AMDR_MAP_GX;
WAMD16(sc, amd, map->mr_gx);
amd->cr = AMDR_MAP_STG;
WAMD16(sc, amd, map->mr_stgr);
amd->cr = AMDR_MAP_GR;
WAMD16(sc, amd, map->mr_gr);
amd->cr = AMDR_MAP_GER;
WAMD16(sc, amd, map->mr_ger);
amd->cr = AMDR_MAP_MMR2;
amd->dr = map->mr_mmr2;
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_MMR1);
AM7930_WRITE_REG(bt, bh, dr, map->mr_mmr1);
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_GX);
WAMD16(bt, bh, map->mr_gx);
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_STG);
WAMD16(bt, bh, map->mr_stgr);
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_GR);
WAMD16(bt, bh, map->mr_gr);
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_GER);
WAMD16(bt, bh, map->mr_ger);
AM7930_WRITE_REG(bt, bh, cr, AMDR_MAP_MMR2);
AM7930_WRITE_REG(bt, bh, dr, map->mr_mmr2);
splx(s);
return(0);
@ -325,11 +337,13 @@ am7930_halt_output(addr)
void *addr;
{
register struct am7930_softc *sc = addr;
register volatile struct am7930 *amd = sc->sc_amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
/* 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(bt, bh, cr, AMDR_INIT);
AM7930_WRITE_REG(bt, bh, dr,
AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
sc->sc_locked = 0;
return(0);
@ -340,11 +354,13 @@ am7930_halt_input(addr)
void *addr;
{
register struct am7930_softc *sc = addr;
register volatile struct am7930 *amd = sc->sc_amd;
register bus_space_tag_t bt = sc->sc_bustag;
register bus_space_handle_t bh = sc->sc_bh;
/* 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(bt, bh, cr, AMDR_INIT);
AM7930_WRITE_REG(bt, bh, dr,
AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE);
sc->sc_locked = 0;
return(0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930reg.h,v 1.2 1998/06/24 10:52:53 jonathan Exp $ */
/* $NetBSD: am7930reg.h,v 1.3 1999/03/14 22:29:01 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -68,6 +68,20 @@ struct am7930 {
u_char dsr2; /* D-channel status register 2 (ro) */
};
#define REG_CR offsetof(struct am7930, cr)
#define REG_DR offsetof(struct am7930, dr)
#define RREG_DSR1 offsetof(struct am7930, dsr1r)
#define REG_DER offsetof(struct am7930, der)
#define REG_DCTB offsetof(struct am7930, dctb)
#define REG_BCTB offsetof(struct am7930, bctb)
#define REG_DSR2 offsetof(struct am7930, dsr2)
/* aliases */
#define REG_DCRB AM7930_REG_DCTB
#define REG_BBRB AM7930_REG_BBTB
#define REG_BCRB AM7930_REG_BCTB
#define AMDR_INIT 0x21
#define AMD_INIT_PMS_IDLE 0x00
#define AMD_INIT_PMS_ACTIVE 0x01

View File

@ -1,4 +1,4 @@
/* $NetBSD: am7930var.h,v 1.5 1998/06/24 11:09:23 jonathan Exp $ */
/* $NetBSD: am7930var.h,v 1.6 1999/03/14 22:29:01 jonathan Exp $ */
/*
* Copyright (c) 1992, 1993
@ -71,7 +71,8 @@ struct mapreg {
* pdma state
*/
struct auio {
volatile struct am7930 *au_amd;/* chip registers */
bus_space_tag_t au_bt; /* bus tag */
bus_space_handle_t au_bh; /* handle to chip registers */
u_char *au_rdata; /* record data */
u_char *au_rend; /* end of record data */
@ -81,10 +82,19 @@ struct auio {
};
/*
* interrupt-hanlder status
* XXX should be MI or required in each port's <machine/cpu.h>
*/
struct am7930_intrhand {
int (*ih_fun) __P((void *));
void *ih_arg;
};
struct am7930_softc {
struct device sc_dev; /* base device */
bus_space_tag_t sc_bustag;
bus_space_tag_t sc_bustag; /* bus cookie */
bus_space_handle_t sc_bh; /* device registers */
int sc_open; /* single use device */
int sc_locked; /* true when transfering data */
@ -95,11 +105,11 @@ struct am7930_softc {
u_char sc_mlevel; /* monitor level */
u_char sc_out_port; /* output port */
volatile struct am7930 *sc_amd;/* chip registers */
/* Callbacks */
void (*sc_wam16) __P((volatile struct am7930 *amd, u_int16_t val));
#define WAMD16(sc, amd, v) (sc)->sc_wam16((amd), (v))
void (*sc_wam16) __P((bus_space_tag_t bt, bus_space_handle_t bh,
u_int16_t val));
#define WAMD16(bt, bh, v) (sc)->sc_wam16((bt), (bh), (v))
void (*sc_onopen) __P((struct am7930_softc *sc));
void (*sc_onclose) __P((struct am7930_softc *sc));
@ -110,8 +120,7 @@ struct am7930_softc {
* or replaced with an MI pdma type.
*/
/*struct intrhand sc_hwih; -* hardware interrupt vector */
struct intrhand sc_swih; /* software interrupt vector */
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 */