aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/sound/pci/csapcm.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index fff8bb2415853..b50be346e6bd2 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -49,6 +49,7 @@ struct csa_chinfo {
snd_dbuf *buffer;
int dir;
u_int32_t fmt;
+ int dma;
};
struct csa_info {
@@ -408,11 +409,14 @@ csa_startplaydma(struct csa_info *csa)
csa_res *resp;
u_long ul;
- resp = &csa->res;
- ul = csa_readmem(resp, BA1_PCTL);
- ul &= 0x0000ffff;
- csa_writemem(resp, BA1_PCTL, ul | csa->pctl);
- csa_writemem(resp, BA1_PVOL, 0x80008000);
+ if (!csa->pch.dma) {
+ resp = &csa->res;
+ ul = csa_readmem(resp, BA1_PCTL);
+ ul &= 0x0000ffff;
+ csa_writemem(resp, BA1_PCTL, ul | csa->pctl);
+ csa_writemem(resp, BA1_PVOL, 0x80008000);
+ csa->pch.dma = 1;
+ }
}
static void
@@ -421,11 +425,14 @@ csa_startcapturedma(struct csa_info *csa)
csa_res *resp;
u_long ul;
- resp = &csa->res;
- ul = csa_readmem(resp, BA1_CCTL);
- ul &= 0xffff0000;
- csa_writemem(resp, BA1_CCTL, ul | csa->cctl);
- csa_writemem(resp, BA1_CVOL, 0x80008000);
+ if (!csa->rch.dma) {
+ resp = &csa->res;
+ ul = csa_readmem(resp, BA1_CCTL);
+ ul &= 0xffff0000;
+ csa_writemem(resp, BA1_CCTL, ul | csa->cctl);
+ csa_writemem(resp, BA1_CVOL, 0x80008000);
+ csa->rch.dma = 1;
+ }
}
static void
@@ -434,14 +441,17 @@ csa_stopplaydma(struct csa_info *csa)
csa_res *resp;
u_long ul;
- resp = &csa->res;
- ul = csa_readmem(resp, BA1_PCTL);
- csa->pctl = ul & 0xffff0000;
- csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff);
- csa_writemem(resp, BA1_PVOL, 0xffffffff);
+ if (csa->pch.dma) {
+ resp = &csa->res;
+ ul = csa_readmem(resp, BA1_PCTL);
+ csa->pctl = ul & 0xffff0000;
+ csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff);
+ csa_writemem(resp, BA1_PVOL, 0xffffffff);
- /* Clear the serial fifos. */
- csa_clearserialfifos(resp);
+ /* Clear the serial fifos. */
+ csa_clearserialfifos(resp);
+ csa->pch.dma = 0;
+ }
}
static void
@@ -450,11 +460,14 @@ csa_stopcapturedma(struct csa_info *csa)
csa_res *resp;
u_long ul;
- resp = &csa->res;
- ul = csa_readmem(resp, BA1_CCTL);
- csa->cctl = ul & 0x0000ffff;
- csa_writemem(resp, BA1_CCTL, ul & 0xffff0000);
- csa_writemem(resp, BA1_CVOL, 0xffffffff);
+ if (csa->rch.dma) {
+ resp = &csa->res;
+ ul = csa_readmem(resp, BA1_CCTL);
+ csa->cctl = ul & 0x0000ffff;
+ csa_writemem(resp, BA1_CCTL, ul & 0xffff0000);
+ csa_writemem(resp, BA1_CVOL, 0xffffffff);
+ csa->rch.dma = 0;
+ }
}
static void
@@ -754,6 +767,12 @@ pcmcsa_attach(device_t dev)
unit = device_get_unit(dev);
func = device_get_ivars(dev);
csa->binfo = func->varinfo;
+ /*
+ * Fake the status of DMA so that the initial value of
+ * PCTL and CCTL can be stored into csa->pctl and csa->cctl,
+ * respectively.
+ */
+ csa->pch.dma = csa->rch.dma = 1;
/* Allocate the resources. */
resp = &csa->res;