Several things:

* Use the new trigger_{in,out}put interface.
* Allow the play and record channels to have different encodings (but the
  same sample rate).
* Play u-law and a-law as 16-bit data.  (This may not work yet...)
This commit is contained in:
mycroft 1998-08-09 20:32:34 +00:00
parent 17431823fb
commit 4ffebebb25

View File

@ -1,13 +1,13 @@
/* $NetBSD: eap.c,v 1.8 1998/07/06 11:12:21 augustss Exp $ */
/* $NetBSD: eap.c,v 1.9 1998/08/09 20:32:34 mycroft Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Author: Lennart Augustsson <augustss@cs.chalmers.se>
* Charles Hannum <mycroft@netbsd.org>
*
* Debugging: Andreas Gustafsson <gson@araneus.fi>
* Charles Hannum <mycroft@netbsd.org>
* Testing: Chuck Cranor <chuck@maria.wustl.edu>
* Phil Nelson <phil@cs.wwu.edu>
*
@ -118,7 +118,6 @@
#define EAP_P2_S_EB 0x00000008
#define EAP_R1_S_MB 0x00000010
#define EAP_R1_S_EB 0x00000020
#define EAP_R1P2_BITS 0x0000003c
#define EAP_P2_DAC_SEN 0x00000040
#define EAP_P1_SCT_RLD 0x00000080
#define EAP_P1_INTR_EN 0x00000100
@ -240,11 +239,11 @@ int eap_intr __P((void *));
struct eap_dma {
bus_dmamap_t map;
caddr_t addr;
bus_dma_segment_t segs[1];
int nsegs;
size_t size;
struct eap_dma *next;
caddr_t addr;
bus_dma_segment_t segs[1];
int nsegs;
size_t size;
struct eap_dma *next;
};
#define DMAADDR(map) ((map)->segs[0].ds_addr)
#define KERNADDR(map) ((void *)((map)->addr))
@ -256,17 +255,19 @@ struct eap_softc {
bus_space_handle_t ioh;
bus_dma_tag_t sc_dmatag; /* DMA tag */
struct eap_dma *sc_dmas;
struct eap_dma *sc_dmas;
void (*sc_pintr)(void *); /* dma completion intr handler */
void *sc_parg; /* arg for sc_intr() */
#ifdef DIAGNOSTIC
char sc_prun;
#endif
void (*sc_rintr)(void *); /* dma completion intr handler */
void *sc_rarg; /* arg for sc_intr() */
#ifdef DIAGNOSTIC
char sc_rrun;
int sc_sampsize; /* bytes / sample */
#endif
u_char sc_port[AK_NPORTS]; /* mirror of the hardware setting */
u_int sc_record_source; /* recording source mask */
@ -290,12 +291,12 @@ void eap_close __P((void *));
int eap_query_encoding __P((void *, struct audio_encoding *));
int eap_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
int eap_round_blocksize __P((void *, int));
int eap_dma_init_output __P((void *, void *, int));
int eap_dma_init_input __P((void *, void *, int));
int eap_dma_output __P((void *, void *, int, void (*)(void *), void*));
int eap_dma_input __P((void *, void *, int, void (*)(void *), void*));
int eap_halt_in_dma __P((void *));
int eap_halt_out_dma __P((void *));
int eap_trigger_output __P((void *, void *, void *, int, void (*)(void *),
void *, struct audio_params *));
int eap_trigger_input __P((void *, void *, void *, int, void (*)(void *),
void *, struct audio_params *));
int eap_halt_output __P((void *));
int eap_halt_input __P((void *));
int eap_getdev __P((void *, struct audio_device *));
int eap_mixer_set_port __P((void *, mixer_ctrl_t *));
int eap_mixer_get_port __P((void *, mixer_ctrl_t *));
@ -316,12 +317,12 @@ struct audio_hw_if eap_hw_if = {
eap_set_params,
eap_round_blocksize,
NULL,
eap_dma_init_output,
eap_dma_init_input,
eap_dma_output,
eap_dma_input,
eap_halt_out_dma,
eap_halt_in_dma,
NULL,
NULL,
NULL,
NULL,
eap_halt_output,
eap_halt_input,
NULL,
eap_getdev,
NULL,
@ -333,6 +334,8 @@ struct audio_hw_if eap_hw_if = {
eap_round,
eap_mappage,
eap_get_props,
eap_trigger_output,
eap_trigger_input,
};
struct audio_device eap_device = {
@ -365,7 +368,7 @@ eap_write_codec(sc, a, d)
int icss;
do {
icss = EREAD4(sc, EAP_ICSS);
icss = EREAD4(sc, EAP_ICSS);
DPRINTFN(5,("eap: codec %d prog: icss=0x%08x\n", a, icss));
} while(icss & EAP_CWRIP);
EWRITE4(sc, EAP_CODEC, EAP_SET_CODEC(a, d));
@ -422,8 +425,8 @@ eap_attach(parent, self, aux)
printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
/* Enable interrupts and looping mode. */
EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
EWRITE4(sc, EAP_ICSC, EAP_CDC_EN); /* enable the parts we need */
EWRITE4(sc, EAP_SIC, EAP_P2_INTR_EN | EAP_R1_INTR_EN);
EWRITE4(sc, EAP_ICSC, EAP_CDC_EN); /* enable the parts we need */
eap_write_codec(sc, AK_RESET, AK_PD); /* reset codec */
eap_write_codec(sc, AK_RESET, AK_PD | AK_NRST); /* normal operation */
@ -449,7 +452,7 @@ eap_attach(parent, self, aux)
ctl.un.mask = 1 << EAP_MIC_VOL;
eap_mixer_set_port(sc, &ctl);
audio_attach_mi(&eap_hw_if, 0, sc, &sc->sc_dev);
audio_attach_mi(&eap_hw_if, 0, sc, &sc->sc_dev);
}
int
@ -459,43 +462,43 @@ eap_intr(p)
struct eap_softc *sc = p;
u_int32_t intr, sic;
intr = EREAD4(sc, EAP_ICSS);
if (!(intr & EAP_INTR))
return (0);
intr = EREAD4(sc, EAP_ICSS);
if (!(intr & EAP_INTR))
return (0);
sic = EREAD4(sc, EAP_SIC);
DPRINTFN(5, ("eap_intr: ICSS=0x%08x, SIC=0x%08x\n", intr, sic));
if (intr & EAP_I_ADC) {
/*
* XXX This is a hack!
* The EAP chip sometimes generates the recording interrupt
* while it is still transferring the data. To make sure
* it has all arrived we busy wait until the count is right.
* The transfer we are waiting for is 8 longwords.
*/
int s, nw, n;
EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
s = EREAD4(sc, EAP_ADC_CSR);
nw = ((s & 0xffff) + 1) / 4; /* # of words in DMA */
n = 0;
while (((EREAD4(sc, EAP_ADC_SIZE) >> 16) + 8) % nw == 0) {
delay(10);
if (++n > 100) {
printf("eapintr: dma fix timeout");
break;
}
}
/* Continue with normal interrupt handling. */
if (intr & EAP_I_ADC) {
/*
* XXX This is a hack!
* The EAP chip sometimes generates the recording interrupt
* while it is still transferring the data. To make sure
* it has all arrived we busy wait until the count is right.
* The transfer we are waiting for is 8 longwords.
*/
int s, nw, n;
EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
s = EREAD4(sc, EAP_ADC_CSR);
nw = ((s & 0xffff) + 1) >> 2; /* # of words in DMA */
n = 0;
while (((EREAD4(sc, EAP_ADC_SIZE) >> 16) + 8) % nw == 0) {
delay(10);
if (++n > 100) {
printf("eapintr: dma fix timeout");
break;
}
}
/* Continue with normal interrupt handling. */
EWRITE4(sc, EAP_SIC, sic & ~EAP_R1_INTR_EN);
EWRITE4(sc, EAP_SIC, sic);
if (sc->sc_rintr)
sc->sc_rintr(sc->sc_rarg);
}
if (intr & EAP_I_DAC2) {
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);
if (sc->sc_pintr)
sc->sc_pintr(sc->sc_parg);
}
if (sc->sc_pintr)
sc->sc_pintr(sc->sc_parg);
}
return (1);
}
@ -504,7 +507,7 @@ eap_allocmem(sc, size, align, p)
struct eap_softc *sc;
size_t size;
size_t align;
struct eap_dma *p;
struct eap_dma *p;
{
int error;
@ -543,7 +546,7 @@ free:
int
eap_freemem(sc, p)
struct eap_softc *sc;
struct eap_dma *p;
struct eap_dma *p;
{
bus_dmamap_unload(sc->sc_dmatag, p->map);
bus_dmamap_destroy(sc->sc_dmatag, p->map);
@ -557,14 +560,8 @@ eap_open(addr, flags)
void *addr;
int flags;
{
struct eap_softc *sc = addr;
DPRINTF(("eap_open: sc=%p\n", sc));
sc->sc_pintr = 0;
sc->sc_rintr = 0;
return (0);
return (0);
}
/*
@ -576,11 +573,11 @@ eap_close(addr)
{
struct eap_softc *sc = addr;
eap_halt_in_dma(sc);
eap_halt_out_dma(sc);
eap_halt_output(sc);
eap_halt_input(sc);
sc->sc_pintr = 0;
sc->sc_rintr = 0;
sc->sc_pintr = 0;
sc->sc_rintr = 0;
}
int
@ -613,7 +610,7 @@ eap_query_encoding(addr, fp)
fp->precision = 8;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
return (0);
case 4:
case 4:
strcpy(fp->name, AudioEslinear_le);
fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
fp->precision = 16;
@ -643,81 +640,97 @@ eap_query_encoding(addr, fp)
}
int
eap_set_params(addr, setmode, usemode, p, r)
eap_set_params(addr, setmode, usemode, play, rec)
void *addr;
int setmode, usemode;
struct audio_params *p, *r;
struct audio_params *play, *rec;
{
struct eap_softc *sc = addr;
void (*pswcode) __P((void *, u_char *buf, int cnt));
void (*rswcode) __P((void *, u_char *buf, int cnt));
u_int32_t mode, div;
struct audio_params *p;
u_int32_t mode, div;
pswcode = rswcode = 0;
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16)
rswcode = pswcode = swap_bytes;
/*
* This device only has one clock, so make the sample rates match.
*/
if (play->sample_rate != rec->sample_rate) {
if ((usemode | setmode) == AUMODE_PLAY)
rec->sample_rate = play->sample_rate;
else if ((usemode | setmode) == AUMODE_RECORD)
play->sample_rate = rec->sample_rate;
else
pswcode = rswcode = change_sign8;
break;
case AUDIO_ENCODING_SLINEAR_LE:
if (p->precision != 16)
pswcode = rswcode = change_sign8;
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16) {
pswcode = swap_bytes_change_sign16;
rswcode = change_sign16_swap_bytes;
return (EINVAL);
}
for (mode = AUMODE_RECORD; mode != -1;
mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
if ((setmode & mode) == 0)
continue;
p = mode == AUMODE_PLAY ? play : rec;
if (p->sample_rate < 4000 || p->sample_rate > 50000 ||
(p->precision != 8 && p->precision != 16) ||
(p->channels != 1 && p->channels != 2))
return (EINVAL);
p->factor = 1;
p->sw_code = 0;
switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16)
p->sw_code = swap_bytes;
else
p->sw_code = change_sign8;
break;
case AUDIO_ENCODING_SLINEAR_LE:
if (p->precision != 16)
p->sw_code = change_sign8;
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16)
if (mode == AUMODE_PLAY)
p->sw_code = swap_bytes_change_sign16;
else
p->sw_code = change_sign16_swap_bytes;
break;
case AUDIO_ENCODING_ULINEAR_LE:
if (p->precision == 16)
p->sw_code = change_sign16;
break;
case AUDIO_ENCODING_ULAW:
if (mode == AUMODE_PLAY) {
p->factor = 2;
p->sw_code = mulaw_to_slinear16;
} else
p->sw_code = ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
if (mode == AUMODE_PLAY) {
p->factor = 2;
p->sw_code = alaw_to_slinear16;
} else
p->sw_code = ulinear8_to_alaw;
break;
default:
return (EINVAL);
}
break;
case AUDIO_ENCODING_ULINEAR_LE:
if (p->precision == 16)
pswcode = rswcode = change_sign16;
break;
case AUDIO_ENCODING_ULAW:
pswcode = mulaw_to_ulinear8;
rswcode = ulinear8_to_mulaw;
break;
case AUDIO_ENCODING_ALAW:
pswcode = alaw_to_ulinear8;
rswcode = ulinear8_to_alaw;
break;
default:
return (EINVAL);
}
if (p->precision == 16)
mode = EAP_P2_S_EB | EAP_R1_S_EB;
else
mode = 0;
if (p->channels == 2)
mode |= EAP_P2_S_MB | EAP_R1_S_MB;
else if (p->channels != 1)
return (EINVAL);
if (p->sample_rate < 4000 || p->sample_rate > 50000)
return (EINVAL);
}
sc->sc_sampsize = p->precision / 8 * p->channels; /* bytes / sample */
p->sw_code = pswcode;
r->sw_code = rswcode;
/* Set the encoding */
mode |= EREAD4(sc, EAP_SIC) & ~(EAP_R1P2_BITS | EAP_INC_BITS);
mode |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(p->precision / 8);
EWRITE4(sc, EAP_SIC, mode);
DPRINTFN(2, ("eap_set_params: set SIC = 0x%08x\n", mode));
/* Set the speed */
/* Set the speed */
DPRINTFN(2, ("eap_set_params: old ICSC = 0x%08x\n",
EREAD4(sc, EAP_ICSC)));
div = EREAD4(sc, EAP_ICSC) & ~EAP_PCLKBITS;
div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / p->sample_rate - 2);
/*
* XXX
* The -2 isn't documented, but seemed to make the wall time match
* what I expect. - mycroft
*/
div |= EAP_SET_PCLKDIV(EAP_XTAL_FREQ / play->sample_rate - 2);
div |= EAP_CCB_INTRM;
EWRITE4(sc, EAP_ICSC, div);
EWRITE4(sc, EAP_ICSC, div);
DPRINTFN(2, ("eap_set_params: set ICSC = 0x%08x\n", div));
return (0);
return (0);
}
int
@ -729,169 +742,180 @@ eap_round_blocksize(addr, blk)
}
int
eap_dma_init_input(addr, buf, cc)
eap_trigger_output(addr, start, end, blksize, intr, arg, param)
void *addr;
void *buf;
int cc;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
DPRINTF(("eap_dma_init_input: dma start loop input addr=%p cc=%d\n",
buf, cc));
for (p = sc->sc_dmas; p && KERNADDR(p) != buf; p = p->next)
;
if (!p) {
printf("eap_dma_init_input: bad addr %p\n", buf);
return (EINVAL);
}
EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_ADC_SIZE, EAP_SET_SIZE(0, cc / 4 - 1));
DPRINTF(("eap_dma_init_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n",
(int)DMAADDR(p), EAP_SET_SIZE(0, cc / 4 - 1)));
return (0);
}
int
eap_dma_init_output(addr, buf, cc)
void *addr;
void *buf;
int cc;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
DPRINTF(("eap: dma start loop output buf=%p cc=%d\n", buf, cc));
for (p = sc->sc_dmas; p && KERNADDR(p) != buf; p = p->next)
;
if (!p) {
printf("eap_dma_init_output: bad addr %p\n", buf);
return (EINVAL);
}
EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_DAC2_SIZE, EAP_SET_SIZE(0, cc / 4 - 1));
DPRINTF(("eap_dma_init_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n",
(int)DMAADDR(p), EAP_SET_SIZE(0, cc / 4 - 1)));
return (0);
}
int
eap_dma_output(addr, p, cc, intr, arg)
void *addr;
void *p;
int cc;
void *start, *end;
int blksize;
void (*intr) __P((void *));
void *arg;
struct audio_params *param;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
u_int32_t mode;
int sampshift;
DPRINTFN(sc->sc_prun ? 5 : 1,
("eap_dma_output: sc=%p buf=%p cc=%d intr=%p(%p)\n",
addr, p, cc, intr, arg));
#ifdef DIAGNOSTIC
if (sc->sc_prun)
panic("eap_trigger_output: already running");
#endif
DPRINTFN(1, ("eap_trigger_output: sc=%p start=%p end=%d blksize=%d intr=%p(%p)\n",
addr, start, end, blksize, intr, arg));
sc->sc_pintr = intr;
sc->sc_parg = arg;
if (!sc->sc_prun) {
#if defined(DIAGNOSTIC) || defined(AUDIO_DEBUG)
if (sc->sc_sampsize == 0) {
printf("eap_dma_output: sampsize == 0\n");
return EINVAL;
}
#endif
EWRITE2(sc, EAP_DAC2_CSR, cc / sc->sc_sampsize - 1);
DPRINTFN(1, ("eap_dma_output: set DAC2_CSR = %d\n",
cc / sc->sc_sampsize - 1));
DPRINTFN(1, ("eap_dma_output: old ICSC = 0x%08x\n",
EREAD4(sc, EAP_ICSC)));
mode = EREAD4(sc, EAP_ICSC) & ~EAP_DAC2_EN;
EWRITE4(sc, EAP_ICSC, mode);
mode |= EAP_DAC2_EN;
EWRITE4(sc, EAP_ICSC, mode);
DPRINTFN(1, ("eap_dma_output: set ICSC = 0x%08x\n", mode));
sc->sc_prun = 1;
mode = EREAD4(sc, EAP_SIC) & ~(EAP_P2_S_EB | EAP_P2_S_MB | EAP_INC_BITS);
mode |= EAP_SET_P2_ST_INC(0) | EAP_SET_P2_END_INC(param->precision * param->factor / 8);
sampshift = 0;
if (param->precision * param->factor == 16) {
mode |= EAP_P2_S_EB;
sampshift++;
}
return (0);
if (param->channels == 2) {
mode |= EAP_P2_S_MB;
sampshift++;
}
EWRITE4(sc, EAP_SIC, mode);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
;
if (!p) {
printf("eap_trigger_output: bad addr %p\n", start);
return (EINVAL);
}
DPRINTF(("eap_trigger_output: DAC2_ADDR=0x%x, DAC2_SIZE=0x%x\n",
(int)DMAADDR(p), EAP_SET_SIZE(0, ((end - start) >> 2) - 1)));
EWRITE4(sc, EAP_MEMPAGE, EAP_DAC_PAGE);
EWRITE4(sc, EAP_DAC2_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_DAC2_SIZE, EAP_SET_SIZE(0, ((end - start) >> 2) - 1));
EWRITE2(sc, EAP_DAC2_CSR, (blksize >> sampshift) - 1);
mode = EREAD4(sc, EAP_ICSC) & ~EAP_DAC2_EN;
EWRITE4(sc, EAP_ICSC, mode);
mode |= EAP_DAC2_EN;
EWRITE4(sc, EAP_ICSC, mode);
DPRINTFN(1, ("eap_trigger_output: set ICSC = 0x%08x\n", mode));
#ifdef DIAGNOSTIC
sc->sc_prun = 1;
#endif
return (0);
}
int
eap_dma_input(addr, p, cc, intr, arg)
eap_trigger_input(addr, start, end, blksize, intr, arg, param)
void *addr;
void *p;
int cc;
void *start, *end;
int blksize;
void (*intr) __P((void *));
void *arg;
struct audio_params *param;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
u_int32_t mode;
int sampshift;
DPRINTFN(1, ("eap_dma_input: sc=%p buf=%p cc=%d intr=%p(%p)\n",
addr, p, cc, intr, arg));
#ifdef DIAGNOSTIC
if (sc->sc_rrun)
panic("eap_trigger_input: already running");
#endif
DPRINTFN(1, ("eap_trigger_input: sc=%p start=%p end=%d blksize=%d intr=%p(%p)\n",
addr, start, end, blksize, intr, arg));
sc->sc_rintr = intr;
sc->sc_rarg = arg;
if (!sc->sc_rrun) {
#if defined(DIAGNOSTIC) || defined(AUDIO_DEBUG)
if (sc->sc_sampsize == 0) {
printf("eap_dma_input: sampsize == 0\n");
return EINVAL;
}
#endif
EWRITE2(sc, EAP_ADC_CSR, cc / sc->sc_sampsize - 1);
mode = EREAD4(sc, EAP_ICSC) & ~EAP_ADC_EN;
EWRITE4(sc, EAP_ICSC, mode);
mode |= EAP_ADC_EN;
EWRITE4(sc, EAP_ICSC, mode);
DPRINTFN(1, ("eap_dma_input: set ICSC = 0x%08x\n", mode));
sc->sc_rrun = 1;
mode = EREAD4(sc, EAP_SIC) & ~(EAP_R1_S_EB | EAP_R1_S_MB);
sampshift = 0;
if (param->precision * param->factor == 16) {
mode |= EAP_R1_S_EB;
sampshift++;
}
return (0);
if (param->channels == 2) {
mode |= EAP_R1_S_MB;
sampshift++;
}
EWRITE4(sc, EAP_SIC, mode);
for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
;
if (!p) {
printf("eap_trigger_input: bad addr %p\n", start);
return (EINVAL);
}
DPRINTF(("eap_trigger_input: ADC_ADDR=0x%x, ADC_SIZE=0x%x\n",
(int)DMAADDR(p), EAP_SET_SIZE(0, ((end - start) >> 2) - 1)));
EWRITE4(sc, EAP_MEMPAGE, EAP_ADC_PAGE);
EWRITE4(sc, EAP_ADC_ADDR, DMAADDR(p));
EWRITE4(sc, EAP_ADC_SIZE, EAP_SET_SIZE(0, ((end - start) >> 2) - 1));
EWRITE2(sc, EAP_ADC_CSR, (blksize >> sampshift) - 1);
mode = EREAD4(sc, EAP_ICSC) & ~EAP_ADC_EN;
EWRITE4(sc, EAP_ICSC, mode);
mode |= EAP_ADC_EN;
EWRITE4(sc, EAP_ICSC, mode);
DPRINTFN(1, ("eap_trigger_input: set ICSC = 0x%08x\n", mode));
#ifdef DIAGNOSTIC
sc->sc_rrun = 1;
#endif
return (0);
}
int
eap_halt_out_dma(addr)
eap_halt_output(addr)
void *addr;
{
struct eap_softc *sc = addr;
u_int32_t mode;
DPRINTF(("eap: eap_halt_out_dma\n"));
DPRINTF(("eap: eap_halt_output\n"));
mode = EREAD4(sc, EAP_ICSC) & ~EAP_DAC2_EN;
EWRITE4(sc, EAP_ICSC, mode);
#ifdef DIAGNOSTIC
sc->sc_prun = 0;
return (0);
#endif
return (0);
}
int
eap_halt_in_dma(addr)
eap_halt_input(addr)
void *addr;
{
struct eap_softc *sc = addr;
u_int32_t mode;
DPRINTF(("eap: eap_halt_in_dma\n"));
DPRINTF(("eap: eap_halt_input\n"));
mode = EREAD4(sc, EAP_ICSC) & ~EAP_ADC_EN;
EWRITE4(sc, EAP_ICSC, mode);
#ifdef DIAGNOSTIC
sc->sc_rrun = 0;
return (0);
#endif
return (0);
}
int
eap_getdev(addr, retp)
void *addr;
struct audio_device *retp;
struct audio_device *retp;
{
*retp = eap_device;
return (0);
return (0);
}
void
eap_set_mixer(sc, a, d)
struct eap_softc *sc;
int a, d;
int a, d;
{
eap_write_codec(sc, a, d);
DPRINTFN(1, ("eap_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
DPRINTFN(1, ("eap_mixer_set_port port 0x%02x = 0x%02x\n", a, d));
}
@ -1018,8 +1042,8 @@ eap_mixer_get_port(addr, cp)
cp->un.mask = sc->sc_record_source;
return (0);
case EAP_OUTPUT_SELECT:
cp->un.mask = sc->sc_output_source;
return (0);
cp->un.mask = sc->sc_output_source;
return (0);
case EAP_MASTER_VOL:
l = ATT5_TO_VOL(sc->sc_port[AK_MASTER_L]);
r = ATT5_TO_VOL(sc->sc_port[AK_MASTER_R]);
@ -1200,19 +1224,19 @@ eap_malloc(addr, size, pool, flags)
int flags;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
int error;
struct eap_dma *p;
int error;
p = malloc(sizeof(*p), pool, flags);
if (!p)
return (0);
error = eap_allocmem(sc, size, 16, p);
if (error) {
free(p, pool);
return (0);
}
p->next = sc->sc_dmas;
sc->sc_dmas = p;
p = malloc(sizeof(*p), pool, flags);
if (!p)
return (0);
error = eap_allocmem(sc, size, 16, p);
if (error) {
free(p, pool);
return (0);
}
p->next = sc->sc_dmas;
sc->sc_dmas = p;
return (KERNADDR(p));
}
@ -1223,16 +1247,16 @@ eap_free(addr, ptr, pool)
int pool;
{
struct eap_softc *sc = addr;
struct eap_dma **p;
struct eap_dma **p;
for (p = &sc->sc_dmas; *p; p = &(*p)->next) {
if (KERNADDR(*p) == ptr) {
eap_freemem(sc, *p);
*p = (*p)->next;
free(*p, pool);
return;
}
}
for (p = &sc->sc_dmas; *p; p = &(*p)->next) {
if (KERNADDR(*p) == ptr) {
eap_freemem(sc, *p);
*p = (*p)->next;
free(*p, pool);
return;
}
}
}
u_long
@ -1246,14 +1270,14 @@ eap_round(addr, size)
int
eap_mappage(addr, mem, off, prot)
void *addr;
void *mem;
int off;
void *mem;
int off;
int prot;
{
struct eap_softc *sc = addr;
struct eap_dma *p;
struct eap_dma *p;
for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next)
for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next)
;
if (!p)
return (-1);
@ -1265,5 +1289,5 @@ int
eap_get_props(addr)
void *addr;
{
return (AUDIO_PROP_MMAP | AUDIO_PROP_FULLDUPLEX);
return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
}