It appears there's a race condition when disabling a channel that causes us to

need to explicitly relatch the interrupt when firing it up again.  So, in the
trigger routines, explicitly disable and reenable the interrupt to relatch it,
like we do in the interrupt routine.

Also clean up some broken loop overrun checks.

My ES1371 seems to be more reliable now, but I'm not going to pretend to fully
understand this chip.
This commit is contained in:
mycroft 2001-04-24 21:03:33 +00:00
parent c28272808b
commit ad44e79f90
1 changed files with 31 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: eap.c,v 1.44 2001/01/27 18:53:33 augustss Exp $ */
/* $NetBSD: eap.c,v 1.45 2001/04/24 21:03:33 mycroft Exp $ */
/* $OpenBSD: eap.c,v 1.6 1999/10/05 19:24:42 csapuntz Exp $ */
/*
@ -335,7 +335,7 @@ eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
break;
delay(1);
}
if (to > EAP_WRITE_TIMEOUT)
if (to >= EAP_WRITE_TIMEOUT)
printf("%s: eap1371_ready_codec timeout 1\n",
sc->sc_dev.dv_xname);
@ -349,7 +349,7 @@ eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
break;
delay(1);
}
if (to > EAP_WRITE_TIMEOUT)
if (to >= EAP_READ_TIMEOUT)
printf("%s: eap1371_ready_codec timeout 2\n",
sc->sc_dev.dv_xname);
@ -359,7 +359,7 @@ eap1371_ready_codec(struct eap_softc *sc, u_int8_t a, u_int32_t wd)
break;
delay(1);
}
if (to > EAP_WRITE_TIMEOUT)
if (to >= EAP_READ_TIMEOUT)
printf("%s: eap1371_ready_codec timeout 3\n",
sc->sc_dev.dv_xname);
@ -442,12 +442,15 @@ eap1371_src_read(struct eap_softc *sc, int a)
src |= E1371_SRC_ADDR(a);
EWRITE4(sc, E1371_SRC, src | E1371_SRC_STATE_OK);
if ((eap1371_src_wait(sc) & E1371_SRC_STATE_MASK) != E1371_SRC_STATE_OK) {
for (to = 0; to < EAP_READ_TIMEOUT; to++) {
t = EREAD4(sc, E1371_SRC);
if ((t & E1371_SRC_STATE_MASK) == E1371_SRC_STATE_OK)
break;
delay(1);
}
}
EWRITE4(sc, E1371_SRC, src);
return t & E1371_SRC_DATAMASK;
@ -517,7 +520,7 @@ eap1371_set_dac_rate(struct eap_softc *sc, int rate, int which)
rate = 48000;
if (rate < 4000)
rate = 4000;
freq = (rate << 15) / 3000;
freq = ((rate << 15) + 1500) / 3000;
s = splaudio();
eap1371_src_wait(sc);
@ -770,6 +773,7 @@ eap_intr(void *p)
sic = EREAD4(sc, EAP_SIC);
DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic));
if (intr & EAP_I_ADC) {
#if 0
/*
* XXX This is a hack!
* The EAP chip sometimes generates the recording interrupt
@ -790,14 +794,15 @@ eap_intr(void *p)
}
}
/* Continue with normal interrupt handling. */
#endif
EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
EWRITE4(sc, EAP_SIC, sic);
EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
if (sc->sc_rintr)
sc->sc_rintr(sc->sc_rarg);
}
if (intr & EAP_I_DAC2) {
EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
EWRITE4(sc, EAP_SIC, sic);
EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
if (sc->sc_pintr)
sc->sc_pintr(sc->sc_parg);
}
@ -1084,9 +1089,6 @@ eap_trigger_output(
sc->sc_pintr = intr;
sc->sc_parg = arg;
icsc = EREAD4(sc, EAP_ICSC);
EWRITE4(sc, EAP_ICSC, icsc & ~EAP_DAC2_EN);
sic = EREAD4(sc, EAP_SIC);
sic &= ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS);
sic |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8);
@ -1099,7 +1101,8 @@ eap_trigger_output(
sic |= EAP_P2_S_MB;
sampshift++;
}
EWRITE4(sc, EAP_SIC, sic);
EWRITE4(sc, EAP_SIC, sic & ~EAP_P2_INTR_EN);
EWRITE4(sc, EAP_SIC, sic | EAP_P2_INTR_EN);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
;
@ -1116,8 +1119,12 @@ eap_trigger_output(
EWRITE4(sc, EAP_DAC2_SIZE,
EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
EWRITE2(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
EWRITE4(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
if (sc->sc_1371)
EWRITE4(sc, E1371_SRC, 0);
icsc = EREAD4(sc, EAP_ICSC);
EWRITE4(sc, EAP_ICSC, icsc | EAP_DAC2_EN);
DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", icsc));
@ -1151,9 +1158,6 @@ eap_trigger_input(
sc->sc_rintr = intr;
sc->sc_rarg = arg;
icsc = EREAD4(sc, EAP_ICSC);
EWRITE4(sc, EAP_ICSC, icsc & ~EAP_ADC_EN);
sic = EREAD4(sc, EAP_SIC);
sic &= ~(EAP_R1_S_EB | EAP_R1_S_MB);
sampshift = 0;
@ -1165,7 +1169,8 @@ eap_trigger_input(
sic |= EAP_R1_S_MB;
sampshift++;
}
EWRITE4(sc, EAP_SIC, sic);
EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
EWRITE4(sc, EAP_SIC, sic | EAP_R1_INTR_EN);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
;
@ -1182,8 +1187,12 @@ eap_trigger_input(
EWRITE4(sc, EAP_ADC_SIZE,
EAP_SET_SIZE(0, (((char *)end - (char *)start) >> 2) - 1));
EWRITE2(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1);
EWRITE4(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1);
if (sc->sc_1371)
EWRITE4(sc, E1371_SRC, 0);
icsc = EREAD4(sc, EAP_ICSC);
EWRITE4(sc, EAP_ICSC, icsc | EAP_ADC_EN);
DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", icsc));