some cosmetics, changed channel setup and revamped irq handling - ignore

repeated interrupts
This commit is contained in:
Cameron Grant 2001-01-24 01:20:04 +00:00
parent 6e64c174bd
commit 7ed9700b1f
2 changed files with 57 additions and 26 deletions

View File

@ -38,9 +38,8 @@
#define TDX_PCI_ID 0x20001023
#define TNX_PCI_ID 0x20011023
#define TR_BUFFSIZE 0xf000
#define TR_BUFFSIZE 0x1000
#define TR_TIMEOUT_CDC 0xffff
#define TR_INTSAMPLES 0x2000
#define TR_MAXPLAYCH 4
struct tr_info;
@ -52,7 +51,7 @@ struct tr_chinfo {
u_int32_t eso, delta;
u_int32_t rvol, cvol;
u_int32_t gvsel, pan, vol, ctrl;
int index;
int index, bufhalf;
snd_dbuf *buffer;
pcm_channel *channel;
struct tr_info *parent;
@ -112,16 +111,6 @@ static pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0};
/* -------------------------------------------------------------------- */
static u_int32_t
tr_fmttobits(u_int32_t fmt)
{
u_int32_t bits = 0;
bits |= (fmt & AFMT_STEREO)? 0x4 : 0;
bits |= (fmt & (AFMT_S8 | AFMT_S16_LE))? 0x2 : 0;
bits |= (fmt & (AFMT_S16_LE | AFMT_U16_LE))? 0x8 : 0;
return bits;
}
/* Hardware */
static u_int32_t
@ -230,6 +219,7 @@ AC97_DECLARE(tr_ac97);
/* -------------------------------------------------------------------- */
/* playback channel interrupts */
#if 0
static u_int32_t
tr_testint(struct tr_chinfo *ch)
{
@ -240,6 +230,7 @@ tr_testint(struct tr_chinfo *ch)
chan = ch->index & 0x1f;
return tr_rd(tr, bank? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 4) & (1 << chan);
}
#endif
static void
tr_clrint(struct tr_chinfo *ch)
@ -327,8 +318,8 @@ tr_wrch(struct tr_chinfo *ch)
ch->lba &= 0x3fffffff;
cr[1]=ch->lba;
cr[3]=(ch->rvol<<7) | (ch->cvol);
cr[4]=(ch->gvsel<<31)|(ch->pan<<24)|(ch->vol<<16)|(ch->ctrl<<12)|(ch->ec);
cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol);
cr[4]=(ch->gvsel<<31) | (ch->pan<<24) | (ch->vol<<16) | (ch->ctrl<<12) | (ch->ec);
switch (tr->type) {
case TDX_PCI_ID:
@ -336,7 +327,6 @@ tr_wrch(struct tr_chinfo *ch)
ch->eso &= 0x0000ffff;
cr[0]=(ch->cso<<16) | (ch->alpha<<4) | (ch->fms);
cr[2]=(ch->eso<<16) | (ch->delta);
cr[3]|=0x0000c000;
break;
case TNX_PCI_ID:
ch->cso &= 0x00ffffff;
@ -389,6 +379,19 @@ tr_rdch(struct tr_chinfo *ch)
}
}
static u_int32_t
tr_fmttobits(u_int32_t fmt)
{
u_int32_t bits;
bits = 0;
bits |= (fmt & AFMT_SIGNED)? 0x2 : 0;
bits |= (fmt & AFMT_STEREO)? 0x4 : 0;
bits |= (fmt & AFMT_16BIT)? 0x8 : 0;
return bits;
}
/* -------------------------------------------------------------------- */
/* channel interface */
@ -447,14 +450,18 @@ trpchan_trigger(kobj_t obj, void *data, int go)
return 0;
if (go == PCMTRIG_START) {
ch->fmc = ch->fms = ch->ec = ch->alpha = 0;
ch->fmc = 3;
ch->fms = 0;
ch->ec = 0;
ch->alpha = 0;
ch->lba = vtophys(sndbuf_getbuf(ch->buffer));
ch->cso = 0;
ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getbps(ch->buffer)) - 1;
ch->rvol = ch->cvol = 0;
ch->rvol = ch->cvol = 0x7f;
ch->gvsel = 0;
ch->pan = 0;
ch->vol = 0;
ch->bufhalf = 0;
tr_wrch(ch);
tr_enaint(ch, 1);
tr_startch(ch);
@ -520,7 +527,7 @@ trrchan_setformat(kobj_t obj, void *data, u_int32_t format)
bits = tr_fmttobits(format);
/* set # of samples between interrupts */
i = (TR_INTSAMPLES >> ((bits & 0x08)? 1 : 0)) - 1;
i = (sndbuf_runsz(ch->buffer) >> ((bits & 0x08)? 1 : 0)) - 1;
tr_wr(tr, TR_REG_SBBL, i | (i << 16), 4);
/* set sample format */
i = 0x18 | (bits << 4);
@ -619,16 +626,38 @@ tr_intr(void *p)
{
struct tr_info *tr = (struct tr_info *)p;
struct tr_chinfo *ch;
u_int32_t i, intsrc;
u_int32_t active, mask, bufhalf, chnum, intsrc;
int tmp;
intsrc = tr_rd(tr, TR_REG_MISCINT, 4);
if (intsrc & TR_INT_ADDR) {
for (i = 0; i < tr->playchns; i++) {
ch = &tr->chinfo[i];
if (tr_testint(ch)) {
chn_intr(ch->channel);
tr_clrint(ch);
}
chnum = 0;
while (chnum < 64) {
mask = 0x00000001;
active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4);
bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4);
if (active) {
do {
if (active & mask) {
tmp = (bufhalf & mask)? 1 : 0;
if (chnum < tr->playchns) {
ch = &tr->chinfo[chnum];
/* printf("%d @ %d, ", chnum, trpchan_getptr(NULL, ch)); */
if (ch->bufhalf != tmp) {
chn_intr(ch->channel);
ch->bufhalf = tmp;
} else
printf("same bufhalf\n");
}
}
chnum++;
mask <<= 1;
} while (chnum & 31);
} else
chnum += 32;
tr_wr(tr, (chnum <= 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, active, 4);
}
}
if (intsrc & TR_INT_SB) {

View File

@ -81,11 +81,13 @@
#define TR_REG_STARTA 0x80
#define TR_REG_STOPA 0x84
#define TR_REG_CSPF_A 0x90
#define TR_REG_ADDRINTA 0x98
#define TR_REG_INTENA 0xa4
#define TR_REG_STARTB 0xb4
#define TR_REG_STOPB 0xb8
#define TR_REG_CSPF_B 0xbc
#define TR_REG_ADDRINTB 0xd8
#define TR_REG_INTENB 0xdc