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:
parent
58e1f7b9b0
commit
69d2d27c1b
|
@ -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
|
||||
|
|
|
@ -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))
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue