1 /* $NetBSD: autri.c,v 1.44 2009/11/26 15:17:08 njoly Exp $ */
4 * Copyright (c) 2001 SOMEYA Yoshihiko and KUROSAWA Takahiro.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Trident 4DWAVE-DX/NX, SiS 7018, ALi M5451 Sound Driver
31 * The register information is taken from the ALSA driver.
33 * Documentation links:
34 * - ftp://ftp.alsa-project.org/pub/manuals/trident/
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: autri.c,v 1.44 2009/11/26 15:17:08 njoly Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/fcntl.h>
46 #include <sys/malloc.h>
47 #include <sys/device.h>
50 #include <dev/pci/pcidevs.h>
51 #include <dev/pci/pcireg.h>
52 #include <dev/pci/pcivar.h>
54 #include <sys/audioio.h>
55 #include <dev/audio_if.h>
56 #include <dev/midi_if.h>
57 #include <dev/mulaw.h>
58 #include <dev/auconv.h>
59 #include <dev/ic/ac97reg.h>
60 #include <dev/ic/ac97var.h>
61 #include <dev/ic/mpuvar.h>
66 #include <dev/pci/autrireg.h>
67 #include <dev/pci/autrivar.h>
70 # define DPRINTF(x) if (autridebug) printf x
71 # define DPRINTFN(n,x) if (autridebug > (n)) printf x
75 # define DPRINTFN(n,x)
78 static int autri_intr(void *);
80 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
81 #define KERNADDR(p) ((void *)((p)->addr))
83 static int autri_allocmem(struct autri_softc
*, size_t,
84 size_t, struct autri_dma
*);
85 static int autri_freemem(struct autri_softc
*, struct autri_dma
*);
87 #define TWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x))
88 #define TWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x))
89 #define TWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x))
90 #define TREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r))
91 #define TREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r))
92 #define TREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r))
94 static int autri_attach_codec(void *, struct ac97_codec_if
*);
95 static int autri_read_codec(void *, uint8_t, uint16_t *);
96 static int autri_write_codec(void *, uint8_t, uint16_t);
97 static int autri_reset_codec(void *);
98 static enum ac97_host_flags
autri_flags_codec(void *);
100 static bool autri_resume(device_t
, pmf_qual_t
);
101 static int autri_init(void *);
102 static struct autri_dma
*autri_find_dma(struct autri_softc
*, void *);
103 static void autri_setup_channel(struct autri_softc
*, int,
104 const audio_params_t
*param
);
105 static void autri_enable_interrupt(struct autri_softc
*, int);
106 static void autri_disable_interrupt(struct autri_softc
*, int);
107 static void autri_startch(struct autri_softc
*, int, int);
108 static void autri_stopch(struct autri_softc
*, int, int);
109 static void autri_enable_loop_interrupt(void *);
111 static void autri_disable_loop_interrupt(void *);
114 static int autri_open(void *, int);
115 static int autri_query_encoding(void *, struct audio_encoding
*);
116 static int autri_set_params(void *, int, int, audio_params_t
*,
117 audio_params_t
*, stream_filter_list_t
*,
118 stream_filter_list_t
*);
119 static int autri_round_blocksize(void *, int, int, const audio_params_t
*);
120 static int autri_trigger_output(void *, void *, void *, int,
121 void (*)(void *), void *,
122 const audio_params_t
*);
123 static int autri_trigger_input(void *, void *, void *, int,
124 void (*)(void *), void *,
125 const audio_params_t
*);
126 static int autri_halt_output(void *);
127 static int autri_halt_input(void *);
128 static int autri_getdev(void *, struct audio_device
*);
129 static int autri_mixer_set_port(void *, mixer_ctrl_t
*);
130 static int autri_mixer_get_port(void *, mixer_ctrl_t
*);
131 static void* autri_malloc(void *, int, size_t, struct malloc_type
*, int);
132 static void autri_free(void *, void *, struct malloc_type
*);
133 static size_t autri_round_buffersize(void *, int, size_t);
134 static paddr_t
autri_mappage(void *, void *, off_t
, int);
135 static int autri_get_props(void *);
136 static int autri_query_devinfo(void *, mixer_devinfo_t
*);
138 static const struct audio_hw_if autri_hw_if
= {
142 autri_query_encoding
,
144 autri_round_blocksize
,
145 NULL
, /* commit_settings */
146 NULL
, /* init_output */
147 NULL
, /* init_input */
148 NULL
, /* start_output */
149 NULL
, /* start_input */
152 NULL
, /* speaker_ctl */
155 autri_mixer_set_port
,
156 autri_mixer_get_port
,
160 autri_round_buffersize
,
163 autri_trigger_output
,
165 NULL
, /* dev_ioctl */
166 NULL
, /* powerstate */
170 static void autri_midi_close(void *);
171 static void autri_midi_getinfo(void *, struct midi_info
*);
172 static int autri_midi_open(void *, int, void (*)(void *, int),
173 void (*)(void *), void *);
174 static int autri_midi_output(void *, int);
176 static const struct midi_hw_if autri_midi_hw_if
= {
185 #define AUTRI_NFORMATS 8
186 static const struct audio_format autri_formats
[AUTRI_NFORMATS
] = {
187 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 16, 16,
188 2, AUFMT_STEREO
, 0, {4000, 48000}},
189 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 16, 16,
190 1, AUFMT_MONAURAL
, 0, {4000, 48000}},
191 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 16, 16,
192 2, AUFMT_STEREO
, 0, {4000, 48000}},
193 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 16, 16,
194 1, AUFMT_MONAURAL
, 0, {4000, 48000}},
195 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 8, 8,
196 2, AUFMT_STEREO
, 0, {4000, 48000}},
197 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_ULINEAR_LE
, 8, 8,
198 1, AUFMT_MONAURAL
, 0, {4000, 48000}},
199 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 8, 8,
200 2, AUFMT_STEREO
, 0, {4000, 48000}},
201 {NULL
, AUMODE_PLAY
| AUMODE_RECORD
, AUDIO_ENCODING_SLINEAR_LE
, 8, 8,
202 1, AUFMT_MONAURAL
, 0, {4000, 48000}},
206 * register set/clear bit
209 autri_reg_set_1(struct autri_softc
*sc
, int no
, uint8_t mask
)
211 bus_space_write_1(sc
->memt
, sc
->memh
, no
,
212 (bus_space_read_1(sc
->memt
, sc
->memh
, no
) | mask
));
216 autri_reg_clear_1(struct autri_softc
*sc
, int no
, uint8_t mask
)
218 bus_space_write_1(sc
->memt
, sc
->memh
, no
,
219 (bus_space_read_1(sc
->memt
, sc
->memh
, no
) & ~mask
));
223 autri_reg_set_4(struct autri_softc
*sc
, int no
, uint32_t mask
)
225 bus_space_write_4(sc
->memt
, sc
->memh
, no
,
226 (bus_space_read_4(sc
->memt
, sc
->memh
, no
) | mask
));
230 autri_reg_clear_4(struct autri_softc
*sc
, int no
, uint32_t mask
)
232 bus_space_write_4(sc
->memt
, sc
->memh
, no
,
233 (bus_space_read_4(sc
->memt
, sc
->memh
, no
) & ~mask
));
240 autri_attach_codec(void *sc_
, struct ac97_codec_if
*codec_if
)
242 struct autri_codec_softc
*sc
;
244 DPRINTF(("autri_attach_codec()\n"));
246 sc
->codec_if
= codec_if
;
251 autri_read_codec(void *sc_
, uint8_t index
, uint16_t *data
)
253 struct autri_codec_softc
*codec
;
254 struct autri_softc
*sc
;
255 uint32_t status
, addr
, cmd
, busy
;
260 /*DPRINTF(("sc->sc->type : 0x%X",sc->sc->type));*/
262 switch (sc
->sc_devid
) {
263 case AUTRI_DEVICE_ID_4DWAVE_DX
:
264 addr
= AUTRI_DX_ACR1
;
265 cmd
= AUTRI_DX_ACR1_CMD_READ
;
266 busy
= AUTRI_DX_ACR1_BUSY_READ
;
268 case AUTRI_DEVICE_ID_4DWAVE_NX
:
269 addr
= AUTRI_NX_ACR2
;
270 cmd
= AUTRI_NX_ACR2_CMD_READ
;
271 busy
= AUTRI_NX_ACR2_BUSY_READ
| AUTRI_NX_ACR2_RECV_WAIT
;
273 case AUTRI_DEVICE_ID_SIS_7018
:
274 addr
= AUTRI_SIS_ACRD
;
275 cmd
= AUTRI_SIS_ACRD_CMD_READ
;
276 busy
= AUTRI_SIS_ACRD_BUSY_READ
| AUTRI_SIS_ACRD_AUDIO_BUSY
;
278 case AUTRI_DEVICE_ID_ALI_M5451
:
279 if (sc
->sc_revision
> 0x01)
280 addr
= AUTRI_ALI_ACWR
;
282 addr
= AUTRI_ALI_ACRD
;
283 cmd
= AUTRI_ALI_ACRD_CMD_READ
;
284 busy
= AUTRI_ALI_ACRD_BUSY_READ
;
287 printf("%s: autri_read_codec : unknown device\n",
288 device_xname(&sc
->sc_dev
));
292 /* wait for 'Ready to Read' */
293 for (count
=0; count
<0xffff; count
++) {
294 if ((TREAD4(sc
, addr
) & busy
) == 0)
298 if (count
== 0xffff) {
299 printf("%s: Codec timeout. Busy reading AC'97 codec.\n",
300 device_xname(&sc
->sc_dev
));
304 /* send Read Command to AC'97 */
305 TWRITE4(sc
, addr
, (index
& 0x7f) | cmd
);
307 /* wait for 'Returned data is avalable' */
308 for (count
=0; count
<0xffff; count
++) {
309 status
= TREAD4(sc
, addr
);
310 if ((status
& busy
) == 0)
314 if (count
== 0xffff) {
315 printf("%s: Codec timeout. Busy reading AC'97 codec.\n",
316 device_xname(&sc
->sc_dev
));
320 *data
= (status
>> 16) & 0x0000ffff;
321 /*DPRINTF(("autri_read_codec(0x%X) return 0x%X\n",reg,*data));*/
326 autri_write_codec(void *sc_
, uint8_t index
, uint16_t data
)
328 struct autri_codec_softc
*codec
;
329 struct autri_softc
*sc
;
330 uint32_t addr
, cmd
, busy
;
335 /*DPRINTF(("autri_write_codec(0x%X,0x%X)\n",index,data));*/
337 switch (sc
->sc_devid
) {
338 case AUTRI_DEVICE_ID_4DWAVE_DX
:
339 addr
= AUTRI_DX_ACR0
;
340 cmd
= AUTRI_DX_ACR0_CMD_WRITE
;
341 busy
= AUTRI_DX_ACR0_BUSY_WRITE
;
343 case AUTRI_DEVICE_ID_4DWAVE_NX
:
344 addr
= AUTRI_NX_ACR1
;
345 cmd
= AUTRI_NX_ACR1_CMD_WRITE
;
346 busy
= AUTRI_NX_ACR1_BUSY_WRITE
;
348 case AUTRI_DEVICE_ID_SIS_7018
:
349 addr
= AUTRI_SIS_ACWR
;
350 cmd
= AUTRI_SIS_ACWR_CMD_WRITE
;
351 busy
= AUTRI_SIS_ACWR_BUSY_WRITE
| AUTRI_SIS_ACWR_AUDIO_BUSY
;
353 case AUTRI_DEVICE_ID_ALI_M5451
:
354 addr
= AUTRI_ALI_ACWR
;
355 cmd
= AUTRI_ALI_ACWR_CMD_WRITE
;
356 if (sc
->sc_revision
> 0x01)
358 busy
= AUTRI_ALI_ACWR_BUSY_WRITE
;
361 printf("%s: autri_write_codec : unknown device.\n",
362 device_xname(&sc
->sc_dev
));
366 /* wait for 'Ready to Write' */
367 for (count
=0; count
<0xffff; count
++) {
368 if ((TREAD4(sc
, addr
) & busy
) == 0)
372 if (count
== 0xffff) {
373 printf("%s: Codec timeout. Busy writing AC'97 codec\n",
374 device_xname(&sc
->sc_dev
));
378 /* send Write Command to AC'97 */
379 TWRITE4(sc
, addr
, (data
<< 16) | (index
& 0x7f) | cmd
);
385 autri_reset_codec(void *sc_
)
387 struct autri_codec_softc
*codec
;
388 struct autri_softc
*sc
;
395 DPRINTF(("autri_reset_codec(codec=%p,sc=%p)\n", codec
, sc
));
396 DPRINTF(("sc->sc_devid=%X\n", sc
->sc_devid
));
398 switch (sc
->sc_devid
) {
399 case AUTRI_DEVICE_ID_4DWAVE_DX
:
400 /* warm reset AC'97 codec */
401 autri_reg_set_4(sc
, AUTRI_DX_ACR2
, 1);
404 autri_reg_clear_4(sc
, AUTRI_DX_ACR2
, 1);
407 addr
= AUTRI_DX_ACR2
;
408 ready
= AUTRI_DX_ACR2_CODEC_READY
;
410 case AUTRI_DEVICE_ID_4DWAVE_NX
:
411 /* warm reset AC'97 codec */
412 autri_reg_set_4(sc
, AUTRI_NX_ACR0
, 1);
415 autri_reg_clear_4(sc
, AUTRI_NX_ACR0
, 1);
418 addr
= AUTRI_NX_ACR0
;
419 ready
= AUTRI_NX_ACR0_CODEC_READY
;
421 case AUTRI_DEVICE_ID_SIS_7018
:
422 /* cold reset AC'97 codec */
423 autri_reg_set_4(sc
, AUTRI_SIS_SCTRL
, 2);
425 /* release reset (warm & cold) */
426 autri_reg_clear_4(sc
, AUTRI_SIS_SCTRL
, 3);
429 addr
= AUTRI_SIS_SCTRL
;
430 ready
= AUTRI_SIS_SCTRL_CODEC_READY
;
432 case AUTRI_DEVICE_ID_ALI_M5451
:
433 /* warm reset AC'97 codec */
434 autri_reg_set_4(sc
, AUTRI_ALI_SCTRL
, 1);
436 /* release reset (warm & cold) */
437 autri_reg_clear_4(sc
, AUTRI_ALI_SCTRL
, 3);
440 addr
= AUTRI_ALI_SCTRL
;
441 ready
= AUTRI_ALI_SCTRL_CODEC_READY
;
444 printf("%s: autri_reset_codec : unknown device\n",
445 device_xname(&sc
->sc_dev
));
449 /* wait for 'Codec Ready' */
451 reg
= TREAD4(sc
, addr
);
458 printf("%s: Codec timeout. AC'97 is not ready for operation.\n",
459 device_xname(&sc
->sc_dev
));
465 static enum ac97_host_flags
466 autri_flags_codec(void *sc
)
468 return AC97_HOST_DONT_READ
;
476 autri_match(device_t parent
, cfdata_t match
, void *aux
)
478 struct pci_attach_args
*pa
;
480 pa
= (struct pci_attach_args
*)aux
;
481 switch (PCI_VENDOR(pa
->pa_id
)) {
482 case PCI_VENDOR_TRIDENT
:
483 switch (PCI_PRODUCT(pa
->pa_id
)) {
484 case PCI_PRODUCT_TRIDENT_4DWAVE_DX
:
486 * IBM makes a pcn network card and improperly
487 * sets the vendor and product ID's. Avoid matching.
489 if (PCI_CLASS(pa
->pa_class
) == PCI_CLASS_NETWORK
)
492 case PCI_PRODUCT_TRIDENT_4DWAVE_NX
:
497 switch (PCI_PRODUCT(pa
->pa_id
)) {
498 case PCI_PRODUCT_SIS_7018
:
503 switch (PCI_PRODUCT(pa
->pa_id
)) {
504 case PCI_PRODUCT_ALI_M5451
:
514 autri_attach(device_t parent
, device_t self
, void *aux
)
516 struct autri_softc
*sc
;
517 struct pci_attach_args
*pa
;
518 pci_chipset_tag_t pc
;
519 struct autri_codec_softc
*codec
;
520 pci_intr_handle_t ih
;
526 sc
= device_private(self
);
527 pa
= (struct pci_attach_args
*)aux
;
529 aprint_naive(": Audio controller\n");
531 sc
->sc_devid
= pa
->pa_id
;
532 sc
->sc_class
= pa
->pa_class
;
534 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
535 sc
->sc_revision
= PCI_REVISION(pa
->pa_class
);
536 aprint_normal(": %s (rev. 0x%02x)\n", devinfo
, sc
->sc_revision
);
538 /* map register to memory */
539 if (pci_mapreg_map(pa
, AUTRI_PCI_MEMORY_BASE
,
540 PCI_MAPREG_TYPE_MEM
, 0, &sc
->memt
, &sc
->memh
, NULL
, NULL
)) {
541 aprint_error_dev(&sc
->sc_dev
, "can't map memory space\n");
545 /* map and establish the interrupt */
546 if (pci_intr_map(pa
, &ih
)) {
547 aprint_error_dev(&sc
->sc_dev
, "couldn't map interrupt\n");
550 intrstr
= pci_intr_string(pc
, ih
);
551 sc
->sc_ih
= pci_intr_establish(pc
, ih
, IPL_AUDIO
, autri_intr
, sc
);
552 if (sc
->sc_ih
== NULL
) {
553 aprint_error_dev(&sc
->sc_dev
, "couldn't establish interrupt");
555 aprint_error(" at %s", intrstr
);
559 aprint_normal_dev(&sc
->sc_dev
, "interrupting at %s\n", intrstr
);
561 sc
->sc_dmatag
= pa
->pa_dmat
;
563 sc
->sc_pt
= pa
->pa_tag
;
565 /* enable the device */
566 reg
= pci_conf_read(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
567 reg
|= (PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE
);
568 pci_conf_write(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
, reg
);
570 /* initialize the device */
573 /* attach AC'97 codec */
574 codec
= &sc
->sc_codec
;
575 memcpy(&codec
->sc_dev
, &sc
->sc_dev
, sizeof(codec
->sc_dev
));
578 codec
->host_if
.arg
= codec
;
579 codec
->host_if
.attach
= autri_attach_codec
;
580 codec
->host_if
.reset
= autri_reset_codec
;
581 codec
->host_if
.read
= autri_read_codec
;
582 codec
->host_if
.write
= autri_write_codec
;
583 codec
->host_if
.flags
= autri_flags_codec
;
585 if ((r
= ac97_attach(&codec
->host_if
, self
)) != 0) {
586 aprint_error_dev(&sc
->sc_dev
, "can't attach codec (error 0x%X)\n", r
);
590 if (!pmf_device_register(self
, NULL
, autri_resume
))
591 aprint_error_dev(self
, "couldn't establish power handler\n");
593 audio_attach_mi(&autri_hw_if
, sc
, &sc
->sc_dev
);
596 midi_attach_mi(&autri_midi_hw_if
, sc
, &sc
->sc_dev
);
600 CFATTACH_DECL(autri
, sizeof(struct autri_softc
),
601 autri_match
, autri_attach
, NULL
, NULL
);
604 autri_resume(device_t dv
, pmf_qual_t qual
)
606 struct autri_softc
*sc
= device_private(dv
);
609 (sc
->sc_codec
.codec_if
->vtbl
->restore_ports
)(sc
->sc_codec
.codec_if
);
615 autri_init(void *sc_
)
617 struct autri_softc
*sc
;
619 pci_chipset_tag_t pc
;
625 DPRINTF(("in autri_init()\n"));
626 DPRINTFN(5,("pci_conf_read(0x40) : 0x%X\n",pci_conf_read(pc
,pt
,0x40)));
627 DPRINTFN(5,("pci_conf_read(0x44) : 0x%X\n",pci_conf_read(pc
,pt
,0x44)));
629 switch (sc
->sc_devid
) {
630 case AUTRI_DEVICE_ID_4DWAVE_DX
:
631 /* disable Legacy Control */
632 pci_conf_write(pc
, pt
, AUTRI_PCI_DDMA_CFG
,0);
633 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
634 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& 0xffff0000);
636 /* audio engine reset */
637 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
638 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
| 0x00040000);
641 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
642 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& ~0x00040000);
645 autri_reg_set_4(sc
,AUTRI_DX_ACR2
,0x02);
647 case AUTRI_DEVICE_ID_4DWAVE_NX
:
648 /* disable Legacy Control */
649 pci_conf_write(pc
, pt
, AUTRI_PCI_DDMA_CFG
,0);
650 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
651 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& 0xffff0000);
653 /* audio engine reset */
654 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
655 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
| 0x00010000);
658 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
659 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& ~0x00010000);
662 autri_reg_set_4(sc
,AUTRI_NX_ACR0
,0x02);
664 case AUTRI_DEVICE_ID_SIS_7018
:
665 /* disable Legacy Control */
666 pci_conf_write(pc
, pt
, AUTRI_PCI_DDMA_CFG
,0);
667 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
668 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& 0xffff0000);
670 /* reset Digital Controller */
671 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
672 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
| 0x000c0000);
675 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
676 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& ~0x00040000);
678 /* disable AC97 GPIO interrupt */
679 TWRITE1(sc
, AUTRI_SIS_ACGPIO
, 0);
680 /* enable 64 channel mode */
681 autri_reg_set_4(sc
, AUTRI_LFO_GC_CIR
, BANK_B_EN
);
683 case AUTRI_DEVICE_ID_ALI_M5451
:
684 /* disable Legacy Control */
685 pci_conf_write(pc
, pt
, AUTRI_PCI_DDMA_CFG
,0);
686 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
687 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& 0xffff0000);
689 /* reset Digital Controller */
690 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
691 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
| 0x000c0000);
694 reg
= pci_conf_read(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
);
695 pci_conf_write(pc
, pt
, AUTRI_PCI_LEGACY_IOBASE
, reg
& ~0x00040000);
697 /* enable PCM input */
698 autri_reg_set_4(sc
, AUTRI_ALI_GCONTROL
, AUTRI_ALI_GCONTROL_PCM_IN
);
702 if (sc
->sc_devid
== AUTRI_DEVICE_ID_ALI_M5451
) {
704 sc
->sc_play
.ch_intr
= 1;
706 sc
->sc_rec
.ch_intr
= 2;
708 sc
->sc_play
.ch
= 0x20;
709 sc
->sc_play
.ch_intr
= 0x21;
710 sc
->sc_rec
.ch
= 0x22;
711 sc
->sc_rec
.ch_intr
= 0x23;
714 /* clear channel status */
715 TWRITE4(sc
, AUTRI_STOP_A
, 0xffffffff);
716 TWRITE4(sc
, AUTRI_STOP_B
, 0xffffffff);
718 /* disable channel interrupt */
719 TWRITE4(sc
, AUTRI_AINTEN_A
, 0);
720 TWRITE4(sc
, AUTRI_AINTEN_B
, 0);
724 if (sc
->sc_devid
== AUTRI_DEVICE_ID_4DWAVE_NX
) {
725 TWRITE4(sc
,AUTRI_NX_TLBC
,0);
729 autri_enable_loop_interrupt(sc
);
731 DPRINTF(("out autri_init()\n"));
736 autri_enable_loop_interrupt(void *sc_
)
738 struct autri_softc
*sc
;
741 /*reg = (ENDLP_IE | MIDLP_IE);*/
744 if (sc
->sc_devid
== AUTRI_DEVICE_ID_SIS_7018
)
747 autri_reg_set_4(sc
, AUTRI_LFO_GC_CIR
, reg
);
752 autri_disable_loop_interrupt(void *sc_
)
754 struct autri_softc
*sc
;
757 reg
= (ENDLP_IE
| MIDLP_IE
);
759 autri_reg_clear_4(sc
, AUTRI_LFO_GC_CIR
, reg
);
766 struct autri_softc
*sc
;
768 uint32_t mask
, active
[2];
775 intsrc
= TREAD4(sc
, AUTRI_MISCINT
);
776 if ((intsrc
& (ADDRESS_IRQ
| MPU401_IRQ
)) == 0)
779 if (intsrc
& ADDRESS_IRQ
) {
781 active
[0] = TREAD4(sc
,AUTRI_AIN_A
);
782 active
[1] = TREAD4(sc
,AUTRI_AIN_B
);
784 if (sc
->sc_devid
== AUTRI_DEVICE_ID_ALI_M5451
) {
790 for (ch
= 0; ch
< endch
; ch
++) {
791 mask
= 1 << (ch
& 0x1f);
792 if (active
[(ch
& 0x20) ? 1 : 0] & mask
) {
794 /* clear interrupt */
795 TWRITE4(sc
, (ch
& 0x20) ? AUTRI_AIN_B
: AUTRI_AIN_A
, mask
);
796 /* disable interrupt */
797 autri_reg_clear_4(sc
,(ch
& 0x20) ? AUTRI_AINTEN_B
: AUTRI_AINTEN_A
, mask
);
799 reg
= TREAD4(sc
,AUTRI_LFO_GC_CIR
) & ~0x0000003f;
800 TWRITE4(sc
,AUTRI_LFO_GC_CIR
, reg
| ch
);
802 if (sc
->sc_devid
== AUTRI_DEVICE_ID_4DWAVE_NX
) {
803 cso
= TREAD4(sc
, 0xe0) & 0x00ffffff;
804 eso
= TREAD4(sc
, 0xe8) & 0x00ffffff;
806 cso
= (TREAD4(sc
, 0xe0) >> 16) & 0x0000ffff;
807 eso
= (TREAD4(sc
, 0xe8) >> 16) & 0x0000ffff;
809 /*printf("cso=%d, eso=%d\n",cso,eso);*/
811 if (ch
== sc
->sc_play
.ch_intr
) {
812 if (sc
->sc_play
.intr
)
813 sc
->sc_play
.intr(sc
->sc_play
.intr_arg
);
816 if (ch
== sc
->sc_rec
.ch_intr
) {
818 sc
->sc_rec
.intr(sc
->sc_rec
.intr_arg
);
821 /* enable interrupt */
822 autri_reg_set_4(sc
, (ch
& 0x20) ? AUTRI_AINTEN_B
: AUTRI_AINTEN_A
, mask
);
827 if (intsrc
& MPU401_IRQ
) {
831 autri_reg_set_4(sc
,AUTRI_MISCINT
,
832 ST_TARGET_REACHED
| MIXER_OVERFLOW
| MIXER_UNDERFLOW
);
842 autri_allocmem(struct autri_softc
*sc
, size_t size
, size_t align
,
848 error
= bus_dmamem_alloc(sc
->sc_dmatag
, p
->size
, align
, 0,
849 p
->segs
, sizeof(p
->segs
)/sizeof(p
->segs
[0]),
850 &p
->nsegs
, BUS_DMA_NOWAIT
);
854 error
= bus_dmamem_map(sc
->sc_dmatag
, p
->segs
, p
->nsegs
, p
->size
,
855 &p
->addr
, BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
);
859 error
= bus_dmamap_create(sc
->sc_dmatag
, p
->size
, 1, p
->size
,
860 0, BUS_DMA_NOWAIT
, &p
->map
);
864 error
= bus_dmamap_load(sc
->sc_dmatag
, p
->map
, p
->addr
, p
->size
, NULL
,
871 bus_dmamap_destroy(sc
->sc_dmatag
, p
->map
);
873 bus_dmamem_unmap(sc
->sc_dmatag
, p
->addr
, p
->size
);
875 bus_dmamem_free(sc
->sc_dmatag
, p
->segs
, p
->nsegs
);
880 autri_freemem(struct autri_softc
*sc
, struct autri_dma
*p
)
883 bus_dmamap_unload(sc
->sc_dmatag
, p
->map
);
884 bus_dmamap_destroy(sc
->sc_dmatag
, p
->map
);
885 bus_dmamem_unmap(sc
->sc_dmatag
, p
->addr
, p
->size
);
886 bus_dmamem_free(sc
->sc_dmatag
, p
->segs
, p
->nsegs
);
891 autri_open(void *addr
, int flags
)
893 DPRINTF(("autri_open()\n"));
894 DPRINTFN(5,("MISCINT : 0x%08X\n",
895 TREAD4((struct autri_softc
*)addr
, AUTRI_MISCINT
)));
896 DPRINTFN(5,("LFO_GC_CIR : 0x%08X\n",
897 TREAD4((struct autri_softc
*)addr
, AUTRI_LFO_GC_CIR
)));
902 autri_query_encoding(void *addr
, struct audio_encoding
*fp
)
907 strcpy(fp
->name
, AudioEulinear
);
908 fp
->encoding
= AUDIO_ENCODING_ULINEAR
;
913 strcpy(fp
->name
, AudioEmulaw
);
914 fp
->encoding
= AUDIO_ENCODING_ULAW
;
916 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
919 strcpy(fp
->name
, AudioEalaw
);
920 fp
->encoding
= AUDIO_ENCODING_ALAW
;
922 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
925 strcpy(fp
->name
, AudioEslinear
);
926 fp
->encoding
= AUDIO_ENCODING_SLINEAR
;
931 strcpy(fp
->name
, AudioEslinear_le
);
932 fp
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
937 strcpy(fp
->name
, AudioEulinear_le
);
938 fp
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
943 strcpy(fp
->name
, AudioEslinear_be
);
944 fp
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
946 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
949 strcpy(fp
->name
, AudioEulinear_be
);
950 fp
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
952 fp
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
962 autri_set_params(void *addr
, int setmode
, int usemode
,
963 audio_params_t
*play
, audio_params_t
*rec
, stream_filter_list_t
*pfil
,
964 stream_filter_list_t
*rfil
)
966 if (setmode
& AUMODE_RECORD
) {
967 if (auconv_set_converter(autri_formats
, AUTRI_NFORMATS
,
968 AUMODE_RECORD
, rec
, FALSE
, rfil
) < 0)
971 if (setmode
& AUMODE_PLAY
) {
972 if (auconv_set_converter(autri_formats
, AUTRI_NFORMATS
,
973 AUMODE_PLAY
, play
, FALSE
, pfil
) < 0)
980 autri_round_blocksize(void *addr
, int block
,
981 int mode
, const audio_params_t
*param
)
987 autri_halt_output(void *addr
)
989 struct autri_softc
*sc
;
991 DPRINTF(("autri_halt_output()\n"));
993 sc
->sc_play
.intr
= NULL
;
994 autri_stopch(sc
, sc
->sc_play
.ch
, sc
->sc_play
.ch_intr
);
995 autri_disable_interrupt(sc
, sc
->sc_play
.ch_intr
);
1001 autri_halt_input(void *addr
)
1003 struct autri_softc
*sc
;
1005 DPRINTF(("autri_halt_input()\n"));
1007 sc
->sc_rec
.intr
= NULL
;
1008 autri_stopch(sc
, sc
->sc_rec
.ch
, sc
->sc_rec
.ch_intr
);
1009 autri_disable_interrupt(sc
, sc
->sc_rec
.ch_intr
);
1015 autri_getdev(void *addr
, struct audio_device
*retp
)
1017 struct autri_softc
*sc
;
1019 DPRINTF(("autri_getdev().\n"));
1021 strncpy(retp
->name
, "Trident 4DWAVE", sizeof(retp
->name
));
1022 snprintf(retp
->version
, sizeof(retp
->version
), "0x%02x",
1023 PCI_REVISION(sc
->sc_class
));
1025 switch (sc
->sc_devid
) {
1026 case AUTRI_DEVICE_ID_4DWAVE_DX
:
1027 strncpy(retp
->config
, "4DWAVE-DX", sizeof(retp
->config
));
1029 case AUTRI_DEVICE_ID_4DWAVE_NX
:
1030 strncpy(retp
->config
, "4DWAVE-NX", sizeof(retp
->config
));
1032 case AUTRI_DEVICE_ID_SIS_7018
:
1033 strncpy(retp
->config
, "SiS 7018", sizeof(retp
->config
));
1035 case AUTRI_DEVICE_ID_ALI_M5451
:
1036 strncpy(retp
->config
, "ALi M5451", sizeof(retp
->config
));
1039 strncpy(retp
->config
, "unknown", sizeof(retp
->config
));
1046 autri_mixer_set_port(void *addr
, mixer_ctrl_t
*cp
)
1048 struct autri_softc
*sc
;
1051 return sc
->sc_codec
.codec_if
->vtbl
->mixer_set_port(
1052 sc
->sc_codec
.codec_if
, cp
);
1056 autri_mixer_get_port(void *addr
, mixer_ctrl_t
*cp
)
1058 struct autri_softc
*sc
;
1061 return sc
->sc_codec
.codec_if
->vtbl
->mixer_get_port(
1062 sc
->sc_codec
.codec_if
, cp
);
1066 autri_query_devinfo(void *addr
, mixer_devinfo_t
*dip
)
1068 struct autri_softc
*sc
;
1071 return sc
->sc_codec
.codec_if
->vtbl
->query_devinfo(
1072 sc
->sc_codec
.codec_if
, dip
);
1076 autri_malloc(void *addr
, int direction
, size_t size
,
1077 struct malloc_type
*pool
, int flags
)
1079 struct autri_softc
*sc
;
1080 struct autri_dma
*p
;
1083 p
= malloc(sizeof(*p
), pool
, flags
);
1088 error
= autri_allocmem(sc
, size
, 16, p
);
1090 error
= autri_allocmem(sc
, size
, 0x10000, p
);
1096 p
->next
= sc
->sc_dmas
;
1102 autri_free(void *addr
, void *ptr
, struct malloc_type
*pool
)
1104 struct autri_softc
*sc
;
1105 struct autri_dma
**pp
, *p
;
1108 for (pp
= &sc
->sc_dmas
; (p
= *pp
) != NULL
; pp
= &p
->next
) {
1109 if (KERNADDR(p
) == ptr
) {
1110 autri_freemem(sc
, p
);
1118 static struct autri_dma
*
1119 autri_find_dma(struct autri_softc
*sc
, void *addr
)
1121 struct autri_dma
*p
;
1123 for (p
= sc
->sc_dmas
; p
&& KERNADDR(p
) != addr
; p
= p
->next
)
1130 autri_round_buffersize(void *addr
, int direction
, size_t size
)
1137 autri_mappage(void *addr
, void *mem
, off_t off
, int prot
)
1139 struct autri_softc
*sc
;
1140 struct autri_dma
*p
;
1145 p
= autri_find_dma(sc
, mem
);
1149 return bus_dmamem_mmap(sc
->sc_dmatag
, p
->segs
, p
->nsegs
,
1150 off
, prot
, BUS_DMA_WAITOK
);
1154 autri_get_props(void *addr
)
1156 return AUDIO_PROP_MMAP
| AUDIO_PROP_INDEPENDENT
|
1157 AUDIO_PROP_FULLDUPLEX
;
1161 autri_setup_channel(struct autri_softc
*sc
, int mode
,
1162 const audio_params_t
*param
)
1165 uint32_t reg
, cr
[5];
1167 uint32_t delta
, dch
[2], ctrl
;
1168 uint32_t alpha_fms
, fm_vol
, attribute
;
1170 uint32_t dmaaddr
, dmalen
;
1171 int factor
, rvol
, cvol
;
1172 struct autri_chstatus
*chst
;
1174 ctrl
= AUTRI_CTRL_LOOPMODE
;
1175 switch (param
->encoding
) {
1176 case AUDIO_ENCODING_SLINEAR_BE
:
1177 case AUDIO_ENCODING_SLINEAR_LE
:
1178 ctrl
|= AUTRI_CTRL_SIGNED
;
1183 if (param
->precision
== 16) {
1184 ctrl
|= AUTRI_CTRL_16BIT
;
1188 if (param
->channels
== 2) {
1189 ctrl
|= AUTRI_CTRL_STEREO
;
1193 delta
= param
->sample_rate
;
1201 dch
[1] = ((delta
<< 12) / 48000) & 0x0000ffff;
1202 if (mode
== AUMODE_PLAY
) {
1203 chst
= &sc
->sc_play
;
1204 dch
[0] = ((delta
<< 12) / 48000) & 0x0000ffff;
1205 ctrl
|= AUTRI_CTRL_WAVEVOL
;
1208 dch
[0] = ((48000 << 12) / delta
) & 0x0000ffff;
1209 if (sc
->sc_devid
== AUTRI_DEVICE_ID_SIS_7018
) {
1210 ctrl
|= AUTRI_CTRL_MUTEVOL_SIS
;
1211 attribute
= AUTRI_ATTR_PCMREC_SIS
;
1213 attribute
|= AUTRI_ATTR_ENASRC_SIS
;
1215 ctrl
|= AUTRI_CTRL_MUTEVOL
;
1218 dmaaddr
= DMAADDR(chst
->dma
);
1219 cso
= alpha_fms
= 0;
1221 fm_vol
= 0x0 | ((rvol
& 0x7f) << 7) | (cvol
& 0x7f);
1223 for (ch
= 0; ch
< 2; ch
++) {
1226 dmalen
= (chst
->length
>> factor
);
1228 /* channel for interrupt */
1229 dmalen
= (chst
->blksize
>> factor
);
1230 if (sc
->sc_devid
== AUTRI_DEVICE_ID_SIS_7018
)
1231 ctrl
|= AUTRI_CTRL_MUTEVOL_SIS
;
1233 ctrl
|= AUTRI_CTRL_MUTEVOL
;
1240 switch (sc
->sc_devid
) {
1241 case AUTRI_DEVICE_ID_4DWAVE_DX
:
1242 cr
[0] = (cso
<< 16) | (alpha_fms
& 0x0000ffff);
1244 cr
[2] = (eso
<< 16) | (dch
[ch
] & 0x0000ffff);
1248 case AUTRI_DEVICE_ID_4DWAVE_NX
:
1249 cr
[0] = (dch
[ch
] << 24) | (cso
& 0x00ffffff);
1251 cr
[2] = ((dch
[ch
] << 16) & 0xff000000) | (eso
& 0x00ffffff);
1252 cr
[3] = (alpha_fms
<< 16) | (fm_vol
& 0x0000ffff);
1255 case AUTRI_DEVICE_ID_SIS_7018
:
1256 cr
[0] = (cso
<< 16) | (alpha_fms
& 0x0000ffff);
1258 cr
[2] = (eso
<< 16) | (dch
[ch
] & 0x0000ffff);
1262 case AUTRI_DEVICE_ID_ALI_M5451
:
1263 cr
[0] = (cso
<< 16) | (alpha_fms
& 0x0000ffff);
1265 cr
[2] = (eso
<< 16) | (dch
[ch
] & 0x0000ffff);
1271 /* write channel data */
1272 channel
= (ch
== 0) ? chst
->ch
: chst
->ch_intr
;
1274 reg
= TREAD4(sc
,AUTRI_LFO_GC_CIR
) & ~0x0000003f;
1275 TWRITE4(sc
,AUTRI_LFO_GC_CIR
, reg
| channel
);
1277 for (i
= 0; i
< 5; i
++) {
1278 TWRITE4(sc
, AUTRI_ARAM_CR
+ i
*sizeof(cr
[0]), cr
[i
]);
1279 DPRINTFN(5,("cr[%d] : 0x%08X\n", i
, cr
[i
]));
1283 if (channel
< 0x20) {
1284 TWRITE4(sc
, AUTRI_EBUF1
, AUTRI_EMOD_STILL
);
1285 TWRITE4(sc
, AUTRI_EBUF2
, AUTRI_EMOD_STILL
);
1292 autri_trigger_output(void *addr
, void *start
, void *end
, int blksize
,
1293 void (*intr
)(void *), void *arg
,
1294 const audio_params_t
*param
)
1296 struct autri_softc
*sc
;
1297 struct autri_dma
*p
;
1299 DPRINTFN(5,("autri_trigger_output: sc=%p start=%p end=%p "
1300 "blksize=%d intr=%p(%p)\n", addr
, start
, end
, blksize
, intr
, arg
));
1302 sc
->sc_play
.intr
= intr
;
1303 sc
->sc_play
.intr_arg
= arg
;
1304 sc
->sc_play
.offset
= 0;
1305 sc
->sc_play
.blksize
= blksize
;
1306 sc
->sc_play
.length
= (char *)end
- (char *)start
;
1308 p
= autri_find_dma(sc
, start
);
1310 printf("autri_trigger_output: bad addr %p\n", start
);
1314 sc
->sc_play
.dma
= p
;
1317 autri_setup_channel(sc
, AUMODE_PLAY
, param
);
1319 /* volume set to no attenuation */
1320 TWRITE4(sc
, AUTRI_MUSICVOL_WAVEVOL
, 0);
1322 /* enable interrupt */
1323 autri_enable_interrupt(sc
, sc
->sc_play
.ch_intr
);
1326 autri_startch(sc
, sc
->sc_play
.ch
, sc
->sc_play
.ch_intr
);
1332 autri_trigger_input(void *addr
, void *start
, void *end
, int blksize
,
1333 void (*intr
)(void *), void *arg
,
1334 const audio_params_t
*param
)
1336 struct autri_softc
*sc
;
1337 struct autri_dma
*p
;
1339 DPRINTFN(5,("autri_trigger_input: sc=%p start=%p end=%p "
1340 "blksize=%d intr=%p(%p)\n", addr
, start
, end
, blksize
, intr
, arg
));
1342 sc
->sc_rec
.intr
= intr
;
1343 sc
->sc_rec
.intr_arg
= arg
;
1344 sc
->sc_rec
.offset
= 0;
1345 sc
->sc_rec
.blksize
= blksize
;
1346 sc
->sc_rec
.length
= (char *)end
- (char *)start
;
1349 p
= autri_find_dma(sc
, start
);
1351 printf("autri_trigger_input: bad addr %p\n", start
);
1358 if (sc
->sc_devid
== AUTRI_DEVICE_ID_4DWAVE_NX
) {
1359 autri_reg_set_4(sc
, AUTRI_NX_ACR0
, AUTRI_NX_ACR0_PSB_CAPTURE
);
1360 TWRITE1(sc
, AUTRI_NX_RCI3
, AUTRI_NX_RCI3_ENABLE
| sc
->sc_rec
.ch
);
1364 /* 4DWAVE only allows capturing at a 48 kHz rate */
1365 if (sc
->sc_devid
== AUTRI_DEVICE_ID_4DWAVE_DX
||
1366 sc
->sc_devid
== AUTRI_DEVICE_ID_4DWAVE_NX
)
1367 param
->sample_rate
= 48000;
1370 autri_setup_channel(sc
, AUMODE_RECORD
, param
);
1372 /* enable interrupt */
1373 autri_enable_interrupt(sc
, sc
->sc_rec
.ch_intr
);
1376 autri_startch(sc
, sc
->sc_rec
.ch
, sc
->sc_rec
.ch_intr
);
1383 autri_halt(struct autri_softc
*sc
)
1386 DPRINTF(("autri_halt().\n"));
1387 /*autri_stopch(sc);*/
1388 autri_disable_interrupt(sc
, sc
->sc_play
.channel
);
1389 autri_disable_interrupt(sc
, sc
->sc_rec
.channel
);
1395 autri_enable_interrupt(struct autri_softc
*sc
, int ch
)
1399 reg
= (ch
& 0x20) ? AUTRI_AINTEN_B
: AUTRI_AINTEN_A
;
1402 autri_reg_set_4(sc
, reg
, 1 << ch
);
1406 autri_disable_interrupt(struct autri_softc
*sc
, int ch
)
1410 reg
= (ch
& 0x20) ? AUTRI_AINTEN_B
: AUTRI_AINTEN_A
;
1413 autri_reg_clear_4(sc
, reg
, 1 << ch
);
1417 autri_startch(struct autri_softc
*sc
, int ch
, int ch_intr
)
1422 reg
= (ch
& 0x20) ? AUTRI_START_B
: AUTRI_START_A
;
1425 chmask
= (1 << ch
) | (1 << ch_intr
);
1427 autri_reg_set_4(sc
, reg
, chmask
);
1431 autri_stopch(struct autri_softc
*sc
, int ch
, int ch_intr
)
1436 reg
= (ch
& 0x20) ? AUTRI_STOP_B
: AUTRI_STOP_A
;
1439 chmask
= (1 << ch
) | (1 << ch_intr
);
1441 autri_reg_set_4(sc
, reg
, chmask
);
1446 autri_midi_open(void *addr
, int flags
, void (*iintr
)(void *, int),
1447 void (*ointr
)(void *), void *arg
)
1449 struct autri_softc
*sc
;
1451 DPRINTF(("autri_midi_open()\n"));
1453 DPRINTFN(5,("MPUR1 : 0x%02X\n", TREAD1(sc
, AUTRI_MPUR1
)));
1454 DPRINTFN(5,("MPUR2 : 0x%02X\n", TREAD1(sc
, AUTRI_MPUR2
)));
1456 sc
->sc_iintr
= iintr
;
1457 sc
->sc_ointr
= ointr
;
1461 autri_reg_clear_1(sc
, AUTRI_MPUR2
, AUTRI_MIDIIN_ENABLE_INTR
);
1464 autri_reg_set_1(sc
, AUTRI_MPUR2
, AUTRI_MIDIOUT_CONNECT
);
1470 autri_midi_close(void *addr
)
1472 struct autri_softc
*sc
;
1474 DPRINTF(("autri_midi_close()\n"));
1476 tsleep(sc
, PWAIT
, "autri", hz
/10); /* give uart a chance to drain */
1478 sc
->sc_iintr
= NULL
;
1479 sc
->sc_ointr
= NULL
;
1483 autri_midi_output(void *addr
, int d
)
1485 struct autri_softc
*sc
;
1489 for (x
= 0; x
!= MIDI_BUSY_WAIT
; x
++) {
1490 if ((TREAD1(sc
, AUTRI_MPUR1
) & AUTRI_MIDIOUT_READY
) == 0) {
1491 TWRITE1(sc
, AUTRI_MPUR0
, d
);
1494 delay(MIDI_BUSY_DELAY
);
1500 autri_midi_getinfo(void *addr
, struct midi_info
*mi
)
1503 mi
->name
= "4DWAVE MIDI UART";
1504 mi
->props
= MIDI_PROP_CAN_INPUT
;