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:
parent
c28272808b
commit
ad44e79f90
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue