rewrite suspend/resume routine. If you suspend while playing audio,
clcs and clct continue playing when resume.
This commit is contained in:
parent
8490f0b0c0
commit
109656b0a7
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cs4280.c,v 1.15 2001/02/13 04:11:11 tacha Exp $ */
|
||||
/* $NetBSD: cs4280.c,v 1.16 2001/04/18 01:35:06 tacha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000 Tatoku Ogaito. All rights reserved.
|
||||
|
@ -660,9 +660,7 @@ cs4280_halt_output(addr)
|
|||
|
||||
mem = BA1READ4(sc, CS4280_PCTL);
|
||||
BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
|
||||
#ifdef DIAGNOSTIC
|
||||
sc->sc_prun = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -675,9 +673,7 @@ cs4280_halt_input(addr)
|
|||
|
||||
mem = BA1READ4(sc, CS4280_CCTL);
|
||||
BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK);
|
||||
#ifdef DIAGNOSTIC
|
||||
sc->sc_rrun = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -706,8 +702,8 @@ cs4280_trigger_output(addr, start, end, blksize, intr, arg, param)
|
|||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_prun)
|
||||
printf("cs4280_trigger_output: already running\n");
|
||||
sc->sc_prun = 1;
|
||||
#endif
|
||||
sc->sc_prun = 1;
|
||||
|
||||
DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p "
|
||||
"blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
|
||||
|
@ -774,6 +770,7 @@ cs4280_trigger_output(addr, start, end, blksize, intr, arg, param)
|
|||
|
||||
BA1WRITE4(sc, CS4280_PFIE, pfie | PFIE_PI_ENABLE);
|
||||
|
||||
sc->sc_prate = param->sample_rate;
|
||||
cs4280_set_dac_rate(sc, param->sample_rate);
|
||||
|
||||
pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK;
|
||||
|
@ -798,8 +795,9 @@ cs4280_trigger_input(addr, start, end, blksize, intr, arg, param)
|
|||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_rrun)
|
||||
printf("cs4280_trigger_input: already running\n");
|
||||
sc->sc_rrun = 1;
|
||||
#endif
|
||||
sc->sc_rrun = 1;
|
||||
|
||||
DPRINTF(("cs4280_trigger_input: sc=%p start=%p end=%p "
|
||||
"blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
|
||||
sc->sc_rintr = intr;
|
||||
|
@ -846,6 +844,7 @@ cs4280_trigger_input(addr, start, end, blksize, intr, arg, param)
|
|||
cie = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK;
|
||||
BA1WRITE4(sc, CS4280_CIE, cie | CIE_CI_ENABLE);
|
||||
|
||||
sc->sc_rrate = param->sample_rate;
|
||||
cs4280_set_adc_rate(sc, param->sample_rate);
|
||||
|
||||
cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK;
|
||||
|
@ -861,6 +860,8 @@ cs4280_power(why, v)
|
|||
void *v;
|
||||
{
|
||||
struct cs428x_softc *sc = (struct cs428x_softc *)v;
|
||||
static u_int32_t pctl = 0, pba = 0, pfie = 0, pdtc = 0;
|
||||
static u_int32_t cctl = 0, cba = 0, cie = 0;
|
||||
|
||||
DPRINTF(("%s: cs4280_power why=%d\n",
|
||||
sc->sc_dev.dv_xname, why));
|
||||
|
@ -869,10 +870,28 @@ cs4280_power(why, v)
|
|||
case PWR_STANDBY:
|
||||
sc->sc_suspend = why;
|
||||
|
||||
cs4280_halt_output(sc);
|
||||
cs4280_halt_input(sc);
|
||||
/* should I powerdown here ? */
|
||||
cs428x_write_codec(sc, AC97_REG_POWER, CS4280_POWER_DOWN_ALL);
|
||||
/* save current playback status */
|
||||
if ( sc->sc_prun ) {
|
||||
pctl = BA1READ4(sc, CS4280_PCTL);
|
||||
pfie = BA1READ4(sc, CS4280_PFIE);
|
||||
pba = BA1READ4(sc, CS4280_PBA);
|
||||
pdtc = BA1READ4(sc, CS4280_PDTC);
|
||||
DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
|
||||
pctl, pfie, pba, pdtc));
|
||||
}
|
||||
|
||||
/* save current capture status */
|
||||
if ( sc->sc_rrun ) {
|
||||
cctl = BA1READ4(sc, CS4280_CCTL);
|
||||
cie = BA1READ4(sc, CS4280_CIE);
|
||||
cba = BA1READ4(sc, CS4280_CBA);
|
||||
DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
|
||||
cctl, cie, cba));
|
||||
}
|
||||
|
||||
/* Stop DMA */
|
||||
BA1WRITE4(sc, CS4280_PCTL, pctl & ~PCTL_MASK);
|
||||
BA1WRITE4(sc, CS4280_CCTL, BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK);
|
||||
break;
|
||||
case PWR_RESUME:
|
||||
if (sc->sc_suspend == PWR_RESUME) {
|
||||
|
@ -884,7 +903,28 @@ cs4280_power(why, v)
|
|||
cs4280_init(sc, 0);
|
||||
cs4280_reset_codec(sc);
|
||||
|
||||
/* restore ac97 registers */
|
||||
(*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
|
||||
|
||||
/* restore DMA related status */
|
||||
if(sc->sc_prun) {
|
||||
DPRINTF(("pctl=0x%08x pfie=0x%08x pba=0x%08x pdtc=0x%08x\n",
|
||||
pctl, pfie, pba, pdtc));
|
||||
cs4280_set_dac_rate(sc, sc->sc_prate);
|
||||
BA1WRITE4(sc, CS4280_PDTC, pdtc);
|
||||
BA1WRITE4(sc, CS4280_PBA, pba);
|
||||
BA1WRITE4(sc, CS4280_PFIE, pfie);
|
||||
BA1WRITE4(sc, CS4280_PCTL, pctl);
|
||||
}
|
||||
|
||||
if (sc->sc_rrun) {
|
||||
DPRINTF(("cctl=0x%08x cie=0x%08x cba=0x%08x\n",
|
||||
cctl, cie, cba));
|
||||
cs4280_set_adc_rate(sc, sc->sc_rrate);
|
||||
BA1WRITE4(sc, CS4280_CBA, cba);
|
||||
BA1WRITE4(sc, CS4280_CIE, cie);
|
||||
BA1WRITE4(sc, CS4280_CCTL, cctl);
|
||||
}
|
||||
break;
|
||||
case PWR_SOFTSUSPEND:
|
||||
case PWR_SOFTSTANDBY:
|
||||
|
@ -1291,7 +1331,9 @@ cs4280_init(sc, init)
|
|||
*/
|
||||
mem = BA1READ4(sc, CS4280_PCTL);
|
||||
sc->pctl = mem & PCTL_MASK; /* save startup value */
|
||||
cs4280_halt_output(sc);
|
||||
BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
|
||||
if (init != 0)
|
||||
sc->sc_prun = 0;
|
||||
|
||||
/* Save capture parameter and then write zero.
|
||||
* this ensures that DMA doesn't immediately occur upon
|
||||
|
@ -1299,7 +1341,9 @@ cs4280_init(sc, init)
|
|||
*/
|
||||
mem = BA1READ4(sc, CS4280_CCTL);
|
||||
sc->cctl = mem & CCTL_MASK; /* save startup value */
|
||||
cs4280_halt_input(sc);
|
||||
BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK);
|
||||
if (init != 0)
|
||||
sc->sc_rrun = 0;
|
||||
|
||||
/* Processor Startup Procedure */
|
||||
BA1WRITE4(sc, CS4280_FRMT, FRMT_FTV);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cs4281.c,v 1.3 2001/02/07 14:41:11 tacha Exp $ */
|
||||
/* $NetBSD: cs4281.c,v 1.4 2001/04/18 01:35:07 tacha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Tatoku Ogaito. All rights reserved.
|
||||
|
@ -95,9 +95,9 @@ void cs4281_reset_codec(void *);
|
|||
|
||||
/* Internal functions */
|
||||
u_int8_t cs4281_sr2regval(int);
|
||||
void cs4281_set_dac_rate(struct cs428x_softc *, int );
|
||||
void cs4281_set_adc_rate(struct cs428x_softc *, int );
|
||||
int cs4281_init(struct cs428x_softc *);
|
||||
void cs4281_set_dac_rate(struct cs428x_softc *, int);
|
||||
void cs4281_set_adc_rate(struct cs428x_softc *, int);
|
||||
int cs4281_init(struct cs428x_softc *, int);
|
||||
|
||||
/* Power Management */
|
||||
void cs4281_power(int, void *);
|
||||
|
@ -262,7 +262,7 @@ cs4281_attach(parent, self, aux)
|
|||
/*
|
||||
* Sound System start-up
|
||||
*/
|
||||
if (cs4281_init(sc) != 0)
|
||||
if (cs4281_init(sc,1) != 0)
|
||||
return;
|
||||
|
||||
sc->type = TYPE_CS4281;
|
||||
|
@ -509,9 +509,7 @@ cs4281_halt_output(addr)
|
|||
struct cs428x_softc *sc = addr;
|
||||
|
||||
BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
|
||||
#ifdef DIAGNOSTIC
|
||||
sc->sc_prun = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -522,9 +520,7 @@ cs4281_halt_input(addr)
|
|||
struct cs428x_softc *sc = addr;
|
||||
|
||||
BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
|
||||
#ifdef DIAGNOSTIC
|
||||
sc->sc_rrun = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -554,8 +550,8 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param)
|
|||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_prun)
|
||||
printf("cs4281_trigger_output: already running\n");
|
||||
sc->sc_prun = 1;
|
||||
#endif
|
||||
sc->sc_prun = 1;
|
||||
|
||||
DPRINTF(("cs4281_trigger_output: sc=%p start=%p end=%p "
|
||||
"blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
|
||||
|
@ -617,6 +613,7 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param)
|
|||
BA0WRITE4(sc, CS4281_DMR0, fmt);
|
||||
|
||||
/* set sample rate */
|
||||
sc->sc_prate = param->sample_rate;
|
||||
cs4281_set_dac_rate(sc, param->sample_rate);
|
||||
|
||||
/* start DMA */
|
||||
|
@ -624,14 +621,6 @@ cs4281_trigger_output(addr, start, end, blksize, intr, arg, param)
|
|||
/* Enable interrupts */
|
||||
BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
|
||||
|
||||
#if 1
|
||||
/* XXX
|
||||
* I think these BA0WRITE4 should not be here
|
||||
*/
|
||||
BA0WRITE4(sc, CS4281_PPRVC, 7);
|
||||
BA0WRITE4(sc, CS4281_PPLVC, 7);
|
||||
#endif
|
||||
|
||||
DPRINTF(("HICR =0x%08x(expected 0x00000001)\n", BA0READ4(sc, CS4281_HICR)));
|
||||
DPRINTF(("HIMR =0x%08x(expected 0x00f0fc3f)\n", BA0READ4(sc, CS4281_HIMR)));
|
||||
DPRINTF(("DMR0 =0x%08x(expected 0x2???0018)\n", BA0READ4(sc, CS4281_DMR0)));
|
||||
|
@ -664,8 +653,8 @@ cs4281_trigger_input(addr, start, end, blksize, intr, arg, param)
|
|||
#ifdef DIAGNOSTIC
|
||||
if (sc->sc_rrun)
|
||||
printf("cs4281_trigger_input: already running\n");
|
||||
sc->sc_rrun = 1;
|
||||
#endif
|
||||
sc->sc_rrun = 1;
|
||||
DPRINTF(("cs4281_trigger_input: sc=%p start=%p end=%p "
|
||||
"blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
|
||||
sc->sc_rintr = intr;
|
||||
|
@ -715,6 +704,7 @@ cs4281_trigger_input(addr, start, end, blksize, intr, arg, param)
|
|||
BA0WRITE4(sc, CS4281_DMR1, fmt);
|
||||
|
||||
/* set sample rate */
|
||||
sc->sc_rrate = param->sample_rate;
|
||||
cs4281_set_adc_rate(sc, param->sample_rate);
|
||||
|
||||
/* Start DMA */
|
||||
|
@ -737,6 +727,8 @@ cs4281_power(why, v)
|
|||
void *v;
|
||||
{
|
||||
struct cs428x_softc *sc = (struct cs428x_softc *)v;
|
||||
static u_int32_t dba0 = 0, dbc0 = 0, dmr0 = 0, dcr0 = 0;
|
||||
static u_int32_t dba1 = 0, dbc1 = 0, dmr1 = 0, dcr1 = 0;
|
||||
|
||||
DPRINTF(("%s: cs4281_power why=%d\n", sc->sc_dev.dv_xname, why));
|
||||
switch (why) {
|
||||
|
@ -744,10 +736,24 @@ cs4281_power(why, v)
|
|||
case PWR_STANDBY:
|
||||
sc->sc_suspend = why;
|
||||
|
||||
cs4281_halt_output(sc);
|
||||
cs4281_halt_input(sc);
|
||||
/* should I powerdown here ? */
|
||||
cs428x_write_codec(sc, AC97_REG_POWER, CS4281_POWER_DOWN_ALL);
|
||||
/* save current playback status */
|
||||
if (sc->sc_prun) {
|
||||
dcr0 = BA0READ4(sc, CS4281_DCR0);
|
||||
dmr0 = BA0READ4(sc, CS4281_DMR0);
|
||||
dbc0 = BA0READ4(sc, CS4281_DBC0);
|
||||
dba0 = BA0READ4(sc, CS4281_DBA0);
|
||||
}
|
||||
|
||||
/* save current capture status */
|
||||
if (sc->sc_rrun) {
|
||||
dcr1 = BA0READ4(sc, CS4281_DCR1);
|
||||
dmr1 = BA0READ4(sc, CS4281_DMR1);
|
||||
dbc1 = BA0READ4(sc, CS4281_DBC1);
|
||||
dba1 = BA0READ4(sc, CS4281_DBA1);
|
||||
}
|
||||
/* Stop DMA */
|
||||
BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
|
||||
BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
|
||||
break;
|
||||
case PWR_RESUME:
|
||||
if (sc->sc_suspend == PWR_RESUME) {
|
||||
|
@ -756,10 +762,30 @@ cs4281_power(why, v)
|
|||
return;
|
||||
}
|
||||
sc->sc_suspend = why;
|
||||
cs4281_init(sc);
|
||||
cs4281_init(sc,0);
|
||||
cs4281_reset_codec(sc);
|
||||
|
||||
/* restore ac97 registers */
|
||||
(*sc->codec_if->vtbl->restore_ports)(sc->codec_if);
|
||||
|
||||
/* restore DMA related status */
|
||||
if (sc->sc_prun) {
|
||||
cs4281_set_dac_rate(sc, sc->sc_prate);
|
||||
BA0WRITE4(sc, CS4281_DBA0, dba0);
|
||||
BA0WRITE4(sc, CS4281_DBC0, dbc0);
|
||||
BA0WRITE4(sc, CS4281_DMR0, dmr0);
|
||||
BA0WRITE4(sc, CS4281_DCR0, dcr0);
|
||||
}
|
||||
if (sc->sc_rrun) {
|
||||
cs4281_set_adc_rate(sc, sc->sc_rrate);
|
||||
BA0WRITE4(sc, CS4281_DBA1, dba1);
|
||||
BA0WRITE4(sc, CS4281_DBC1, dbc1);
|
||||
BA0WRITE4(sc, CS4281_DMR1, dmr1);
|
||||
BA0WRITE4(sc, CS4281_DCR1, dcr1);
|
||||
}
|
||||
/* enable intterupts */
|
||||
if (sc->sc_prun || sc->sc_rrun)
|
||||
BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
|
||||
break;
|
||||
case PWR_SOFTSUSPEND:
|
||||
case PWR_SOFTSTANDBY:
|
||||
|
@ -924,8 +950,9 @@ cs4281_set_dac_rate(sc, rate)
|
|||
}
|
||||
|
||||
int
|
||||
cs4281_init(sc)
|
||||
cs4281_init(sc, init)
|
||||
struct cs428x_softc *sc;
|
||||
int init;
|
||||
{
|
||||
int n;
|
||||
u_int16_t data;
|
||||
|
@ -1219,5 +1246,16 @@ cs4281_init(sc)
|
|||
dat32 = ~HIMR_DMAIM & ~HIMR_D1IM & ~HIMR_D0IM;
|
||||
BA0WRITE4(sc, CS4281_HIMR,
|
||||
BA0READ4(sc, CS4281_HIMR) & dat32);
|
||||
|
||||
/* set current status */
|
||||
if (init != 0) {
|
||||
sc->sc_prun = 0;
|
||||
sc->sc_rrun = 0;
|
||||
}
|
||||
|
||||
/* setup playback volume */
|
||||
BA0WRITE4(sc, CS4281_PPRVC, 7);
|
||||
BA0WRITE4(sc, CS4281_PPLVC, 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cs428x.c,v 1.1 2001/02/07 14:41:12 tacha Exp $ */
|
||||
/* $NetBSD: cs428x.c,v 1.2 2001/04/18 01:35:07 tacha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Tatoku Ogaito. All rights reserved.
|
||||
|
@ -377,8 +377,11 @@ cs428x_src_wait(sc)
|
|||
n = 0;
|
||||
while ((BA0READ4(sc, CS428X_ACCTL) & ACCTL_DCV)) {
|
||||
delay(1000);
|
||||
while (++n > 1000)
|
||||
while (++n > 1000) {
|
||||
printf("cs428x_src_wait: 0x%08x\n",
|
||||
BA0READ4(sc, CS428X_ACCTL));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cs428x.h,v 1.3 2001/02/07 14:41:12 tacha Exp $ */
|
||||
/* $NetBSD: cs428x.h,v 1.4 2001/04/18 01:35:08 tacha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Tatoku Ogaito. All rights reserved.
|
||||
|
@ -93,9 +93,8 @@ struct cs428x_softc {
|
|||
struct cs428x_dma *sc_pdma;
|
||||
char *sc_pbuf;
|
||||
int (*halt_output)__P((void *));
|
||||
#ifdef DIAGNOSTIC
|
||||
char sc_prun;
|
||||
#endif
|
||||
char sc_prun; /* playback status */
|
||||
int sc_prate; /* playback sample rate */
|
||||
|
||||
/* capturing */
|
||||
void (*sc_rintr)(void *); /* dma completion intr handler */
|
||||
|
@ -107,9 +106,8 @@ struct cs428x_softc {
|
|||
char *sc_rbuf;
|
||||
int sc_rparam; /* record format */
|
||||
int (*halt_input)__P((void *));
|
||||
#ifdef DIAGNOSTIC
|
||||
char sc_rrun;
|
||||
#endif
|
||||
char sc_rrun; /* recording status */
|
||||
int sc_rrate; /* recording sample rate */
|
||||
|
||||
/* Although cs4281 does not support midi (yet),
|
||||
* don't remove these definition.
|
||||
|
|
Loading…
Reference in New Issue