1 /* $NetBSD: neo.c,v 1.43 2009/11/26 15:17:10 njoly Exp $ */
4 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
7 * Derived from the public domain Linux driver
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
30 * FreeBSD: src/sys/dev/sound/pci/neomagic.c,v 1.8 2000/03/20 15:30:50 cg Exp
31 * OpenBSD: neo.c,v 1.4 2000/07/19 09:04:37 csapuntz Exp
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: neo.c,v 1.43 2009/11/26 15:17:10 njoly Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/device.h>
45 #include <dev/pci/pcidevs.h>
46 #include <dev/pci/pcivar.h>
48 #include <dev/pci/neoreg.h>
49 #include <dev/pci/neo-coeff.h>
51 #include <sys/audioio.h>
52 #include <dev/audio_if.h>
53 #include <dev/mulaw.h>
54 #include <dev/auconv.h>
56 #include <dev/ic/ac97var.h>
59 /* -------------------------------------------------------------------- */
61 * As of 04/13/00, public documentation on the Neomagic 256 is not available.
62 * These comments were gleaned by looking at the driver carefully.
64 * The Neomagic 256 AV/ZX chips provide both video and audio capabilities
65 * on one chip. About 2-6 megabytes of memory are associated with
66 * the chip. Most of this goes to video frame buffers, but some is used for
69 * Unlike most PCI audio chips, the Neomagic chip does not rely on DMA.
70 * Instead, the chip allows you to carve out two ring buffers out of its
71 * memory. However you carve this and how much you can carve seems to be
72 * voodoo. The algorithm is in nm_init.
74 * Most Neomagic audio chips use the AC-97 codec interface. However, there
75 * seem to be a select few chips 256AV chips that do not support AC-97.
76 * This driver does not support them but there are rumors that it
77 * might work with wss isa drivers. This might require some playing around
80 * The Neomagic 256 AV/ZX have 2 PCI I/O region descriptors. Both of
81 * them describe a memory region. The frame buffer is the first region
82 * and the register set is the secodn region.
84 * The register manipulation logic is taken from the Linux driver,
85 * which is in the public domain.
87 * The Neomagic is even nice enough to map the AC-97 codec registers into
88 * the register space to allow direct manipulation. Watch out, accessing
89 * AC-97 registers on the Neomagic requires great delicateness, otherwise
90 * the thing will hang the PCI bus, rendering your system frozen.
92 * For one, it seems the Neomagic status register that reports AC-97
93 * readiness should NOT be polled more often than once each 1ms.
95 * Also, writes to the AC-97 register space may take order 40us to
98 * Unlike many sound engines, the Neomagic does not support (as far as
99 * we know :) the notion of interrupting every n bytes transferred,
100 * unlike many DMA engines. Instead, it allows you to specify one
101 * location in each ring buffer (called the watermark). When the chip
102 * passes that location while playing, it signals an interrupt.
104 * The ring buffer size is currently 16k. That is about 100ms of audio
105 * at 44.1kHz/stero/16 bit. However, to keep the buffer full, interrupts
106 * are generated more often than that, so 20-40 interrupts per second
107 * should not be unexpected. Increasing BUFFSIZE should help minimize
108 * of glitches due to drivers that spend to much time looping at high
109 * privelege levels as well as the impact of badly written audio
113 * Figure out interaction with video stuff (look at Xfree86 driver?)
115 * Figure out how to shrink that huge table neo-coeff.h
118 #define NM_BUFFSIZE 16384
120 /* device private data */
124 bus_space_tag_t bufiot
;
125 bus_space_handle_t bufioh
;
127 bus_space_tag_t regiot
;
128 bus_space_handle_t regioh
;
133 void (*pintr
)(void *); /* DMA completion intr handler */
134 void *parg
; /* arg for intr() */
136 void (*rintr
)(void *); /* DMA completion intr handler */
137 void *rarg
; /* arg for intr() */
145 bus_addr_t buf_pciaddr
;
146 bus_addr_t rbuf_pciaddr
;
147 bus_addr_t pbuf_pciaddr
;
149 uint32_t ac97_base
, ac97_status
, ac97_busy
;
150 uint32_t buftop
, pbuf
, rbuf
, cbuf
, acbuf
;
151 uint32_t playint
, recint
, misc1int
, misc2int
;
152 uint32_t irsz
, badintr
;
163 struct ac97_codec_if
*codec_if
;
164 struct ac97_host_if host_if
;
167 /* -------------------------------------------------------------------- */
173 static int nm_waitcd(struct neo_softc
*);
174 static int nm_loadcoeff(struct neo_softc
*, int, int);
175 static int nm_init(struct neo_softc
*);
177 static int neo_match(device_t
, cfdata_t
, void *);
178 static void neo_attach(device_t
, device_t
, void *);
179 static int neo_intr(void *);
181 static int neo_query_encoding(void *, struct audio_encoding
*);
182 static int neo_set_params(void *, int, int, audio_params_t
*,
183 audio_params_t
*, stream_filter_list_t
*,
184 stream_filter_list_t
*);
185 static int neo_round_blocksize(void *, int, int, const audio_params_t
*);
186 static int neo_trigger_output(void *, void *, void *, int,
187 void (*)(void *), void *,
188 const audio_params_t
*);
189 static int neo_trigger_input(void *, void *, void *, int,
190 void (*)(void *), void *,
191 const audio_params_t
*);
192 static int neo_halt_output(void *);
193 static int neo_halt_input(void *);
194 static int neo_getdev(void *, struct audio_device
*);
195 static int neo_mixer_set_port(void *, mixer_ctrl_t
*);
196 static int neo_mixer_get_port(void *, mixer_ctrl_t
*);
197 static int neo_attach_codec(void *, struct ac97_codec_if
*);
198 static int neo_read_codec(void *, uint8_t, uint16_t *);
199 static int neo_write_codec(void *, uint8_t, uint16_t);
200 static int neo_reset_codec(void *);
201 static enum ac97_host_flags
neo_flags_codec(void *);
202 static int neo_query_devinfo(void *, mixer_devinfo_t
*);
203 static void * neo_malloc(void *, int, size_t, struct malloc_type
*, int);
204 static void neo_free(void *, void *, struct malloc_type
*);
205 static size_t neo_round_buffersize(void *, int, size_t);
206 static paddr_t
neo_mappage(void *, void *, off_t
, int);
207 static int neo_get_props(void *);
209 CFATTACH_DECL(neo
, sizeof(struct neo_softc
),
210 neo_match
, neo_attach
, NULL
, NULL
);
212 static struct audio_device neo_device
= {
218 /* The actual rates supported by the card. */
219 static const int samplerates
[9] = {
231 #define NEO_NFORMATS 4
232 static const struct audio_format neo_formats
[NEO_NFORMATS
] = {
233 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 16, 16,
234 2, AUFMT_STEREO
, 8, {8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000}},
235 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 16, 16,
236 1, AUFMT_MONAURAL
, 8, {8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000}},
237 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 8, 8,
238 2, AUFMT_STEREO
, 8, {8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000}},
239 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 8, 8,
240 1, AUFMT_MONAURAL
, 8, {8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000}},
243 /* -------------------------------------------------------------------- */
245 static const struct audio_hw_if neo_hw_if
= {
252 NULL
, /* commit_setting */
253 NULL
, /* init_output */
254 NULL
, /* init_input */
255 NULL
, /* start_output */
256 NULL
, /* start_input */
259 NULL
, /* speaker_ctl */
267 neo_round_buffersize
,
276 /* -------------------------------------------------------------------- */
278 #define nm_rd_1(sc, regno) \
279 bus_space_read_1((sc)->regiot, (sc)->regioh, (regno))
281 #define nm_rd_2(sc, regno) \
282 bus_space_read_2((sc)->regiot, (sc)->regioh, (regno))
284 #define nm_rd_4(sc, regno) \
285 bus_space_read_4((sc)->regiot, (sc)->regioh, (regno))
287 #define nm_wr_1(sc, regno, val) \
288 bus_space_write_1((sc)->regiot, (sc)->regioh, (regno), (val))
290 #define nm_wr_2(sc, regno, val) \
291 bus_space_write_2((sc)->regiot, (sc)->regioh, (regno), (val))
293 #define nm_wr_4(sc, regno, val) \
294 bus_space_write_4((sc)->regiot, (sc)->regioh, (regno), (val))
296 #define nm_rdbuf_4(sc, regno) \
297 bus_space_read_4((sc)->bufiot, (sc)->bufioh, (regno))
299 #define nm_wrbuf_1(sc, regno, val) \
300 bus_space_write_1((sc)->bufiot, (sc)->bufioh, (regno), (val))
304 nm_waitcd(struct neo_softc
*sc
)
312 if (nm_rd_2(sc
, sc
->ac97_status
) & sc
->ac97_busy
)
323 nm_ackint(struct neo_softc
*sc
, uint32_t num
)
327 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU
:
328 nm_wr_2(sc
, NM_INT_REG
, num
<< 1);
331 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU
:
332 nm_wr_4(sc
, NM_INT_REG
, num
);
338 nm_loadcoeff(struct neo_softc
*sc
, int dir
, int num
)
343 addr
= (dir
== AUMODE_PLAY
)? 0x01c : 0x21c;
344 if (dir
== AUMODE_RECORD
)
346 sz
= coefficientSizes
[num
];
349 ofs
+= coefficientSizes
[num
];
350 for (i
= 0; i
< sz
; i
++)
351 nm_wrbuf_1(sc
, sc
->cbuf
+ i
, coefficients
[ofs
+ i
]);
352 nm_wr_4(sc
, addr
, sc
->cbuf
);
353 if (dir
== AUMODE_PLAY
)
355 nm_wr_4(sc
, addr
+ 4, sc
->cbuf
+ sz
);
359 /* The interrupt handler */
363 struct neo_softc
*sc
;
367 sc
= (struct neo_softc
*)p
;
369 status
= (sc
->irsz
== 2) ?
370 nm_rd_2(sc
, NM_INT_REG
) :
371 nm_rd_4(sc
, NM_INT_REG
);
373 if (status
& sc
->playint
) {
374 status
&= ~sc
->playint
;
376 sc
->pwmark
+= sc
->pblksize
;
377 sc
->pwmark
%= sc
->pbufsize
;
379 nm_wr_4(sc
, NM_PBUFFER_WMARK
, sc
->pbuf
+ sc
->pwmark
);
381 nm_ackint(sc
, sc
->playint
);
384 (*sc
->pintr
)(sc
->parg
);
388 if (status
& sc
->recint
) {
389 status
&= ~sc
->recint
;
391 sc
->rwmark
+= sc
->rblksize
;
392 sc
->rwmark
%= sc
->rbufsize
;
393 nm_wr_4(sc
, NM_RBUFFER_WMARK
, sc
->rbuf
+ sc
->rwmark
);
394 nm_ackint(sc
, sc
->recint
);
396 (*sc
->rintr
)(sc
->rarg
);
400 if (status
& sc
->misc1int
) {
401 status
&= ~sc
->misc1int
;
402 nm_ackint(sc
, sc
->misc1int
);
403 x
= nm_rd_1(sc
, 0x400);
404 nm_wr_1(sc
, 0x400, x
| 2);
405 printf("%s: misc int 1\n", device_xname(&sc
->dev
));
408 if (status
& sc
->misc2int
) {
409 status
&= ~sc
->misc2int
;
410 nm_ackint(sc
, sc
->misc2int
);
411 x
= nm_rd_1(sc
, 0x400);
412 nm_wr_1(sc
, 0x400, x
& ~2);
413 printf("%s: misc int 2\n", device_xname(&sc
->dev
));
417 status
&= ~sc
->misc2int
;
418 nm_ackint(sc
, sc
->misc2int
);
419 printf("%s: unknown int\n", device_xname(&sc
->dev
));
426 /* -------------------------------------------------------------------- */
429 * Probe and attach the card
433 nm_init(struct neo_softc
*sc
)
438 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU
:
439 sc
->ac97_base
= NM_MIXER_OFFSET
;
440 sc
->ac97_status
= NM_MIXER_STATUS_OFFSET
;
441 sc
->ac97_busy
= NM_MIXER_READY_MASK
;
443 sc
->buftop
= 2560 * 1024;
446 sc
->playint
= NM_PLAYBACK_INT
;
447 sc
->recint
= NM_RECORD_INT
;
448 sc
->misc1int
= NM_MISC_INT_1
;
449 sc
->misc2int
= NM_MISC_INT_2
;
452 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU
:
453 sc
->ac97_base
= NM_MIXER_OFFSET
;
454 sc
->ac97_status
= NM2_MIXER_STATUS_OFFSET
;
455 sc
->ac97_busy
= NM2_MIXER_READY_MASK
;
457 sc
->buftop
= (nm_rd_2(sc
, 0xa0b) ? 6144 : 4096) * 1024;
460 sc
->playint
= NM2_PLAYBACK_INT
;
461 sc
->recint
= NM2_RECORD_INT
;
462 sc
->misc1int
= NM2_MISC_INT_1
;
463 sc
->misc2int
= NM2_MISC_INT_2
;
467 panic("nm_init: impossible");
472 ofs
= sc
->buftop
- 0x0400;
473 sc
->buftop
-= 0x1400;
475 if ((nm_rdbuf_4(sc
, ofs
) & NM_SIG_MASK
) == NM_SIGNATURE
) {
476 i
= nm_rdbuf_4(sc
, ofs
+ 4);
477 if (i
!= 0 && i
!= 0xffffffff)
481 sc
->cbuf
= sc
->buftop
- NM_MAX_COEFFICIENT
;
482 sc
->rbuf
= sc
->cbuf
- NM_BUFFSIZE
;
483 sc
->pbuf
= sc
->rbuf
- NM_BUFFSIZE
;
484 sc
->acbuf
= sc
->pbuf
- (NM_TOTAL_COEFF_COUNT
* 4);
486 sc
->buf_vaddr
= (vaddr_t
) bus_space_vaddr(sc
->bufiot
, sc
->bufioh
);
487 sc
->rbuf_vaddr
= sc
->buf_vaddr
+ sc
->rbuf
;
488 sc
->pbuf_vaddr
= sc
->buf_vaddr
+ sc
->pbuf
;
490 sc
->rbuf_pciaddr
= sc
->buf_pciaddr
+ sc
->rbuf
;
491 sc
->pbuf_pciaddr
= sc
->buf_pciaddr
+ sc
->pbuf
;
493 nm_wr_1(sc
, 0, 0x11);
494 nm_wr_1(sc
, NM_RECORD_ENABLE_REG
, 0);
495 nm_wr_2(sc
, 0x214, 0);
501 neo_match(device_t parent
, cfdata_t match
, void *aux
)
503 struct pci_attach_args
*pa
;
507 if (PCI_VENDOR(pa
->pa_id
) != PCI_VENDOR_NEOMAGIC
)
510 subdev
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_SUBSYS_ID_REG
);
512 switch (PCI_PRODUCT(pa
->pa_id
)) {
513 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU
:
515 * We have to weed-out the non-AC'97 versions of
516 * the chip (i.e. the ones that are known to work
517 * in WSS emulation mode), as they won't work with
520 switch (PCI_VENDOR(subdev
)) {
521 case PCI_VENDOR_DELL
:
522 switch (PCI_PRODUCT(subdev
)) {
529 switch (PCI_PRODUCT(subdev
)) {
536 switch (PCI_PRODUCT(subdev
)) {
544 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU
:
552 neo_resume(device_t dv
, pmf_qual_t qual
)
554 struct neo_softc
*sc
= device_private(dv
);
557 sc
->codec_if
->vtbl
->restore_ports(sc
->codec_if
);
563 neo_attach(device_t parent
, device_t self
, void *aux
)
565 struct neo_softc
*sc
;
566 struct pci_attach_args
*pa
;
567 pci_chipset_tag_t pc
;
569 pci_intr_handle_t ih
;
572 sc
= device_private(self
);
573 pa
= (struct pci_attach_args
*)aux
;
576 sc
->type
= PCI_PRODUCT(pa
->pa_id
);
578 printf(": NeoMagic 256%s audio\n",
579 sc
->type
== PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU
? "AV" : "ZX");
581 /* Map I/O register */
582 if (pci_mapreg_map(pa
, PCI_MAPREG_START
, PCI_MAPREG_TYPE_MEM
, 0,
583 &sc
->bufiot
, &sc
->bufioh
, &sc
->buf_pciaddr
, NULL
)) {
584 aprint_error_dev(&sc
->dev
, "can't map buffer\n");
588 if (pci_mapreg_map(pa
, PCI_MAPREG_START
+ 4, PCI_MAPREG_TYPE_MEM
,
589 BUS_SPACE_MAP_LINEAR
, &sc
->regiot
, &sc
->regioh
, NULL
, NULL
)) {
590 aprint_error_dev(&sc
->dev
, "can't map registers\n");
594 /* Map and establish the interrupt. */
595 if (pci_intr_map(pa
, &ih
)) {
596 aprint_error_dev(&sc
->dev
, "couldn't map interrupt\n");
600 intrstr
= pci_intr_string(pc
, ih
);
601 sc
->ih
= pci_intr_establish(pc
, ih
, IPL_AUDIO
, neo_intr
, sc
);
603 if (sc
->ih
== NULL
) {
604 aprint_error_dev(&sc
->dev
, "couldn't establish interrupt");
606 aprint_error(" at %s", intrstr
);
610 aprint_normal_dev(&sc
->dev
, "interrupting at %s\n", intrstr
);
612 if (nm_init(sc
) != 0)
615 /* Enable the device. */
616 csr
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
617 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
,
618 csr
| PCI_COMMAND_MASTER_ENABLE
);
620 sc
->host_if
.arg
= sc
;
622 sc
->host_if
.attach
= neo_attach_codec
;
623 sc
->host_if
.read
= neo_read_codec
;
624 sc
->host_if
.write
= neo_write_codec
;
625 sc
->host_if
.reset
= neo_reset_codec
;
626 sc
->host_if
.flags
= neo_flags_codec
;
628 if (ac97_attach(&sc
->host_if
, self
) != 0)
631 if (!pmf_device_register(self
, NULL
, neo_resume
))
632 aprint_error_dev(self
, "couldn't establish power handler\n");
634 audio_attach_mi(&neo_hw_if
, sc
, &sc
->dev
);
638 neo_read_codec(void *v
, uint8_t a
, uint16_t *d
)
640 struct neo_softc
*sc
;
643 if (!nm_waitcd(sc
)) {
644 *d
= nm_rd_2(sc
, sc
->ac97_base
+ a
);
654 neo_write_codec(void *v
, u_int8_t a
, u_int16_t d
)
656 struct neo_softc
*sc
;
661 if (!nm_waitcd(sc
)) {
663 nm_wr_2(sc
, sc
->ac97_base
+ a
, d
);
664 if (!nm_waitcd(sc
)) {
675 neo_attach_codec(void *v
, struct ac97_codec_if
*codec_if
)
677 struct neo_softc
*sc
;
680 sc
->codec_if
= codec_if
;
685 neo_reset_codec(void *v
)
687 struct neo_softc
*sc
;
690 nm_wr_1(sc
, 0x6c0, 0x01);
691 nm_wr_1(sc
, 0x6cc, 0x87);
692 nm_wr_1(sc
, 0x6cc, 0x80);
693 nm_wr_1(sc
, 0x6cc, 0x00);
697 static enum ac97_host_flags
698 neo_flags_codec(void *v
)
701 return AC97_HOST_DONT_READ
;
705 neo_query_encoding(void *addr
, struct audio_encoding
*fp
)
710 strcpy(fp
->name
, AudioEulinear
);
711 fp
->encoding
= AUDIO_ENCODING_ULINEAR
;
716 strcpy(fp
->name
, AudioEmulaw
);
717 fp
->encoding
= AUDIO_ENCODING_ULAW
;
719 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
722 strcpy(fp
->name
, AudioEalaw
);
723 fp
->encoding
= AUDIO_ENCODING_ALAW
;
725 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
728 strcpy(fp
->name
, AudioEslinear
);
729 fp
->encoding
= AUDIO_ENCODING_SLINEAR
;
731 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
734 strcpy(fp
->name
, AudioEslinear_le
);
735 fp
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
740 strcpy(fp
->name
, AudioEulinear_le
);
741 fp
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
743 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
746 strcpy(fp
->name
, AudioEslinear_be
);
747 fp
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
749 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
752 strcpy(fp
->name
, AudioEulinear_be
);
753 fp
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
755 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
762 /* Todo: don't commit settings to card until we've verified all parameters */
764 neo_set_params(void *addr
, int setmode
, int usemode
,
765 audio_params_t
*play
, audio_params_t
*rec
, stream_filter_list_t
*pfil
,
766 stream_filter_list_t
*rfil
)
768 struct neo_softc
*sc
;
770 stream_filter_list_t
*fil
;
776 for (mode
= AUMODE_RECORD
; mode
!= -1;
777 mode
= mode
== AUMODE_RECORD
? AUMODE_PLAY
: -1) {
778 if ((setmode
& mode
) == 0)
781 p
= mode
== AUMODE_PLAY
? play
: rec
;
783 if (p
== NULL
) continue;
785 for (x
= 0; x
< 8; x
++) {
787 (samplerates
[x
] + samplerates
[x
+ 1]) / 2)
793 p
->sample_rate
= samplerates
[x
];
794 nm_loadcoeff(sc
, mode
, x
);
798 if (p
->precision
== 16)
799 x
|= NM_RATE_BITS_16
;
800 if (p
->channels
== 2)
803 base
= (mode
== AUMODE_PLAY
)?
804 NM_PLAYBACK_REG_OFFSET
: NM_RECORD_REG_OFFSET
;
805 nm_wr_1(sc
, base
+ NM_RATE_REG_OFFSET
, x
);
807 fil
= mode
== AUMODE_PLAY
? pfil
: rfil
;
808 i
= auconv_set_converter(neo_formats
, NEO_NFORMATS
,
809 mode
, p
, FALSE
, fil
);
818 neo_round_blocksize(void *addr
, int blk
, int mode
,
819 const audio_params_t
*param
)
822 return NM_BUFFSIZE
/ 2;
826 neo_trigger_output(void *addr
, void *start
, void *end
, int blksize
,
827 void (*intr
)(void *), void *arg
, const audio_params_t
*param
)
829 struct neo_softc
*sc
;
836 ssz
= (param
->precision
== 16) ? 2 : 1;
837 if (param
->channels
== 2)
840 sc
->pbufsize
= ((char*)end
- (char *)start
);
841 sc
->pblksize
= blksize
;
842 sc
->pwmark
= blksize
;
844 nm_wr_4(sc
, NM_PBUFFER_START
, sc
->pbuf
);
845 nm_wr_4(sc
, NM_PBUFFER_END
, sc
->pbuf
+ sc
->pbufsize
- ssz
);
846 nm_wr_4(sc
, NM_PBUFFER_CURRP
, sc
->pbuf
);
847 nm_wr_4(sc
, NM_PBUFFER_WMARK
, sc
->pbuf
+ sc
->pwmark
);
848 nm_wr_1(sc
, NM_PLAYBACK_ENABLE_REG
, NM_PLAYBACK_FREERUN
|
849 NM_PLAYBACK_ENABLE_FLAG
);
850 nm_wr_2(sc
, NM_AUDIO_MUTE_REG
, 0);
856 neo_trigger_input(void *addr
, void *start
, void *end
, int blksize
,
857 void (*intr
)(void *), void *arg
, const audio_params_t
*param
)
859 struct neo_softc
*sc
;
866 ssz
= (param
->precision
== 16) ? 2 : 1;
867 if (param
->channels
== 2)
870 sc
->rbufsize
= ((char*)end
- (char *)start
);
871 sc
->rblksize
= blksize
;
872 sc
->rwmark
= blksize
;
874 nm_wr_4(sc
, NM_RBUFFER_START
, sc
->rbuf
);
875 nm_wr_4(sc
, NM_RBUFFER_END
, sc
->rbuf
+ sc
->rbufsize
);
876 nm_wr_4(sc
, NM_RBUFFER_CURRP
, sc
->rbuf
);
877 nm_wr_4(sc
, NM_RBUFFER_WMARK
, sc
->rbuf
+ sc
->rwmark
);
878 nm_wr_1(sc
, NM_RECORD_ENABLE_REG
, NM_RECORD_FREERUN
|
879 NM_RECORD_ENABLE_FLAG
);
885 neo_halt_output(void *addr
)
887 struct neo_softc
*sc
;
889 sc
= (struct neo_softc
*)addr
;
890 nm_wr_1(sc
, NM_PLAYBACK_ENABLE_REG
, 0);
891 nm_wr_2(sc
, NM_AUDIO_MUTE_REG
, NM_AUDIO_MUTE_BOTH
);
898 neo_halt_input(void *addr
)
900 struct neo_softc
*sc
;
902 sc
= (struct neo_softc
*)addr
;
903 nm_wr_1(sc
, NM_RECORD_ENABLE_REG
, 0);
910 neo_getdev(void *addr
, struct audio_device
*retp
)
918 neo_mixer_set_port(void *addr
, mixer_ctrl_t
*cp
)
920 struct neo_softc
*sc
;
923 return sc
->codec_if
->vtbl
->mixer_set_port(sc
->codec_if
, cp
);
927 neo_mixer_get_port(void *addr
, mixer_ctrl_t
*cp
)
929 struct neo_softc
*sc
;
932 return sc
->codec_if
->vtbl
->mixer_get_port(sc
->codec_if
, cp
);
936 neo_query_devinfo(void *addr
, mixer_devinfo_t
*dip
)
938 struct neo_softc
*sc
;
941 return sc
->codec_if
->vtbl
->query_devinfo(sc
->codec_if
, dip
);
945 neo_malloc(void *addr
, int direction
, size_t size
,
946 struct malloc_type
*pool
, int flags
)
948 struct neo_softc
*sc
;
955 if (sc
->pbuf_allocated
== 0) {
956 rv
= (void *) sc
->pbuf_vaddr
;
957 sc
->pbuf_allocated
= 1;
962 if (sc
->rbuf_allocated
== 0) {
963 rv
= (void *) sc
->rbuf_vaddr
;
964 sc
->rbuf_allocated
= 1;
973 neo_free(void *addr
, void *ptr
, struct malloc_type
*pool
)
975 struct neo_softc
*sc
;
980 if (v
== sc
->pbuf_vaddr
)
981 sc
->pbuf_allocated
= 0;
982 else if (v
== sc
->rbuf_vaddr
)
983 sc
->rbuf_allocated
= 0;
985 printf("neo_free: bad address %p\n", ptr
);
989 neo_round_buffersize(void *addr
, int direction
,
997 neo_mappage(void *addr
, void *mem
, off_t off
, int prot
)
999 struct neo_softc
*sc
;
1005 if (v
== sc
->pbuf_vaddr
)
1006 pciaddr
= sc
->pbuf_pciaddr
;
1007 else if (v
== sc
->rbuf_vaddr
)
1008 pciaddr
= sc
->rbuf_pciaddr
;
1012 return bus_space_mmap(sc
->bufiot
, pciaddr
, off
, prot
,
1013 BUS_SPACE_MAP_LINEAR
);
1017 neo_get_props(void *addr
)
1020 return AUDIO_PROP_INDEPENDENT
| AUDIO_PROP_MMAP
|
1021 AUDIO_PROP_FULLDUPLEX
;