1 /* $NetBSD: haltwo.c,v 1.16 2009/05/14 01:06:15 macallan Exp $ */
4 * Copyright (c) 2003 Ilpo Ruotsalainen
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.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.16 2009/05/14 01:06:15 macallan Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/audioio.h>
39 #include <sys/malloc.h>
40 #include <dev/audio_if.h>
41 #include <dev/auconv.h>
42 #include <dev/mulaw.h>
44 #include <uvm/uvm_extern.h>
46 #include <machine/bus.h>
47 #include <machine/sysconf.h>
49 #include <sgimips/hpc/hpcvar.h>
50 #include <sgimips/hpc/hpcreg.h>
52 #include <sgimips/hpc/haltworeg.h>
53 #include <sgimips/hpc/haltwovar.h>
56 #define DPRINTF(x) printf x
61 static int haltwo_query_encoding(void *, struct audio_encoding
*);
62 static int haltwo_set_params(void *, int, int, audio_params_t
*,
63 audio_params_t
*, stream_filter_list_t
*, stream_filter_list_t
*);
64 static int haltwo_round_blocksize(void *, int, int, const audio_params_t
*);
65 static int haltwo_halt_output(void *);
66 static int haltwo_halt_input(void *);
67 static int haltwo_getdev(void *, struct audio_device
*);
68 static int haltwo_set_port(void *, mixer_ctrl_t
*);
69 static int haltwo_get_port(void *, mixer_ctrl_t
*);
70 static int haltwo_query_devinfo(void *, mixer_devinfo_t
*);
71 static void *haltwo_malloc(void *, int, size_t, struct malloc_type
*, int);
72 static void haltwo_free(void *, void *, struct malloc_type
*);
73 static int haltwo_get_props(void *);
74 static int haltwo_trigger_output(void *, void *, void *, int, void (*)(void *),
75 void *, const audio_params_t
*);
76 static int haltwo_trigger_input(void *, void *, void *, int, void (*)(void *),
77 void *, const audio_params_t
*);
78 static bool haltwo_shutdown(device_t
, int);
80 static const struct audio_hw_if haltwo_hw_if
= {
84 haltwo_query_encoding
,
86 haltwo_round_blocksize
,
87 NULL
, /* commit_settings */
88 NULL
, /* init_output */
89 NULL
, /* init_input */
90 NULL
, /* start_output */
91 NULL
, /* start_input */
94 NULL
, /* speaker_ctl */
102 NULL
, /* round_buffersize */
105 haltwo_trigger_output
,
106 haltwo_trigger_input
,
110 static const struct audio_device haltwo_device
= {
116 static int haltwo_match(struct device
*, struct cfdata
*, void *);
117 static void haltwo_attach(struct device
*, struct device
*, void *);
118 static int haltwo_intr(void *);
120 CFATTACH_DECL(haltwo
, sizeof(struct haltwo_softc
),
121 haltwo_match
, haltwo_attach
, NULL
, NULL
);
123 #define haltwo_write(sc,type,off,val) \
124 bus_space_write_4(sc->sc_st, sc->sc_##type##_sh, off, val)
126 #define haltwo_read(sc,type,off) \
127 bus_space_read_4(sc->sc_st, sc->sc_##type##_sh, off)
130 haltwo_write_indirect(struct haltwo_softc
*sc
, uint32_t ireg
, uint16_t low
,
134 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IDR0
, low
);
135 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IDR1
, high
);
136 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IDR2
, 0);
137 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IDR3
, 0);
138 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IAR
, ireg
);
140 while (haltwo_read(sc
, ctl
, HAL2_REG_CTL_ISR
) & HAL2_ISR_TSTATUS
)
145 haltwo_read_indirect(struct haltwo_softc
*sc
, uint32_t ireg
, uint16_t *low
,
149 haltwo_write(sc
, ctl
, HAL2_REG_CTL_IAR
,
150 ireg
| HAL2_IAR_READ
);
152 while (haltwo_read(sc
, ctl
, HAL2_REG_CTL_ISR
) & HAL2_ISR_TSTATUS
)
156 *low
= haltwo_read(sc
, ctl
, HAL2_REG_CTL_IDR0
);
159 *high
= haltwo_read(sc
, ctl
, HAL2_REG_CTL_IDR1
);
163 haltwo_init_codec(struct haltwo_softc
*sc
, struct haltwo_codec
*codec
)
169 allocsz
= sizeof(struct hpc_dma_desc
) * HALTWO_MAX_DMASEGS
;
170 KASSERT(allocsz
<= PAGE_SIZE
);
172 err
= bus_dmamem_alloc(sc
->sc_dma_tag
, allocsz
, 0, 0, &codec
->dma_seg
,
173 1, &rseg
, BUS_DMA_NOWAIT
);
177 err
= bus_dmamem_map(sc
->sc_dma_tag
, &codec
->dma_seg
, rseg
, allocsz
,
178 (void **)&codec
->dma_descs
, BUS_DMA_NOWAIT
);
182 err
= bus_dmamap_create(sc
->sc_dma_tag
, allocsz
, 1, PAGE_SIZE
, 0,
183 BUS_DMA_NOWAIT
, &codec
->dma_map
);
187 err
= bus_dmamap_load(sc
->sc_dma_tag
, codec
->dma_map
, codec
->dma_descs
,
188 allocsz
, NULL
, BUS_DMA_NOWAIT
);
192 DPRINTF(("haltwo_init_codec: allocated %d descriptors (%d bytes)"
193 " at %p\n", HALTWO_MAX_DMASEGS
, allocsz
, codec
->dma_descs
));
195 memset(codec
->dma_descs
, 0, allocsz
);
200 bus_dmamap_destroy(sc
->sc_dma_tag
, codec
->dma_map
);
202 bus_dmamem_free(sc
->sc_dma_tag
, &codec
->dma_seg
, rseg
);
204 DPRINTF(("haltwo_init_codec failed: %d\n",err
));
210 haltwo_setup_dma(struct haltwo_softc
*sc
, struct haltwo_codec
*codec
,
211 struct haltwo_dmabuf
*dmabuf
, size_t len
, int blksize
,
212 void (*intr
)(void *), void *intrarg
)
215 bus_dma_segment_t
*segp
;
216 struct hpc_dma_desc
*descp
;
219 KASSERT(len
% blksize
== 0);
223 codec
->intr_arg
= intrarg
;
225 segp
= dmabuf
->dma_map
->dm_segs
;
226 descp
= codec
->dma_descs
;
228 /* Build descriptor chain for looping DMA, triggering interrupt every
230 for (i
= 0; i
< dmabuf
->dma_map
->dm_nsegs
; i
++) {
231 descp
->hpc3_hdd_bufptr
= segp
->ds_addr
;
232 descp
->hpc3_hdd_ctl
= segp
->ds_len
;
234 KASSERT(next_intr
>= segp
->ds_len
);
236 if (next_intr
== segp
->ds_len
) {
237 /* Generate intr after this DMA buffer */
238 descp
->hpc3_hdd_ctl
|= HPC3_HDD_CTL_INTR
;
241 next_intr
-= segp
->ds_len
;
243 if (i
< dmabuf
->dma_map
->dm_nsegs
- 1)
244 descp
->hdd_descptr
= codec
->dma_seg
.ds_addr
+
245 sizeof(struct hpc_dma_desc
) * (i
+ 1);
247 descp
->hdd_descptr
= codec
->dma_seg
.ds_addr
;
249 DPRINTF(("haltwo_setup_dma: hdd_bufptr = %x hdd_ctl = %x"
250 " hdd_descptr = %x\n", descp
->hpc3_hdd_bufptr
,
251 descp
->hpc3_hdd_ctl
, descp
->hdd_descptr
));
257 bus_dmamap_sync(sc
->sc_dma_tag
, codec
->dma_map
, 0,
258 codec
->dma_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
262 haltwo_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
264 struct hpc_attach_args
*haa
;
268 if (strcmp(haa
->ha_name
, cf
->cf_name
))
271 if ( platform
.badaddr((void *)(vaddr_t
)(haa
->ha_sh
+ haa
->ha_devoff
),
275 if ( platform
.badaddr(
276 (void *)(vaddr_t
)(haa
->ha_sh
+ haa
->ha_devoff
+ HAL2_REG_CTL_REV
),
280 rev
= *(uint32_t *)MIPS_PHYS_TO_KSEG1(haa
->ha_sh
+ haa
->ha_devoff
+
283 /* This bit is inverted, the test is correct */
284 if (rev
& HAL2_REV_AUDIO_PRESENT_N
)
291 haltwo_attach(struct device
*parent
, struct device
*self
, void *aux
)
293 struct haltwo_softc
*sc
;
294 struct hpc_attach_args
*haa
;
299 sc
->sc_st
= haa
->ha_st
;
300 sc
->sc_dma_tag
= haa
->ha_dmat
;
302 if (bus_space_subregion(haa
->ha_st
, haa
->ha_sh
, haa
->ha_devoff
,
303 HPC3_PBUS_CH0_DEVREGS_SIZE
, &sc
->sc_ctl_sh
)) {
304 aprint_error(": unable to map control registers\n");
308 if (bus_space_subregion(haa
->ha_st
, haa
->ha_sh
, HPC3_PBUS_CH2_DEVREGS
,
309 HPC3_PBUS_CH2_DEVREGS_SIZE
, &sc
->sc_vol_sh
)) {
310 aprint_error(": unable to map volume registers\n");
314 if (bus_space_subregion(haa
->ha_st
, haa
->ha_sh
, haa
->ha_dmaoff
,
315 HPC3_PBUS_DMAREGS_SIZE
, &sc
->sc_dma_sh
)) {
316 aprint_error(": unable to map DMA registers\n");
320 haltwo_write(sc
, ctl
, HAL2_REG_CTL_ISR
, 0);
321 haltwo_write(sc
, ctl
, HAL2_REG_CTL_ISR
,
322 HAL2_ISR_GLOBAL_RESET_N
| HAL2_ISR_CODEC_RESET_N
);
323 haltwo_write_indirect(sc
, HAL2_IREG_RELAY_C
, HAL2_RELAY_C_STATE
, 0);
325 rev
= haltwo_read(sc
, ctl
, HAL2_REG_CTL_REV
);
327 if (cpu_intr_establish(haa
->ha_irq
, IPL_AUDIO
, haltwo_intr
, sc
)
329 aprint_error(": unable to establish interrupt\n");
333 aprint_naive(": Audio controller\n");
335 aprint_normal(": HAL2 revision %d.%d.%d\n", (rev
& 0x7000) >> 12,
336 (rev
& 0x00F0) >> 4, rev
& 0x000F);
338 if (haltwo_init_codec(sc
, &sc
->sc_dac
)) {
340 "haltwo_attach: unable to create DMA descriptor list\n");
344 /* XXX Magic PBUS CFGDMA values from Linux HAL2 driver XXX */
345 bus_space_write_4(haa
->ha_st
, haa
->ha_sh
, HPC3_PBUS_CH0_CFGDMA
,
347 bus_space_write_4(haa
->ha_st
, haa
->ha_sh
, HPC3_PBUS_CH1_CFGDMA
,
351 /* XXX Add mute/unmute support to mixer ops? XXX */
352 haltwo_write_indirect(sc
, HAL2_IREG_DAC_C2
, 0, 0);
354 /* Set master volume to zero */
355 sc
->sc_vol_left
= sc
->sc_vol_right
= 0;
356 haltwo_write(sc
, vol
, HAL2_REG_VOL_LEFT
, sc
->sc_vol_left
);
357 haltwo_write(sc
, vol
, HAL2_REG_VOL_RIGHT
, sc
->sc_vol_right
);
359 audio_attach_mi(&haltwo_hw_if
, sc
, &sc
->sc_dev
);
361 if (!pmf_device_register1(self
, NULL
, NULL
, haltwo_shutdown
))
362 aprint_error_dev(self
,
363 "couldn't establish power handler\n");
369 struct haltwo_softc
*sc
;
374 if (bus_space_read_4(sc
->sc_st
, sc
->sc_dma_sh
, HPC3_PBUS_CH0_CTL
)
375 & HPC3_PBUS_DMACTL_IRQ
) {
376 sc
->sc_dac
.intr(sc
->sc_dac
.intr_arg
);
380 DPRINTF(("haltwo_intr: Huh?\n"));
386 haltwo_query_encoding(void *v
, struct audio_encoding
*e
)
391 strcpy(e
->name
, AudioEslinear_le
);
392 e
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
398 strcpy(e
->name
, AudioEslinear_be
);
399 e
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
405 strcpy(e
->name
, AudioEmulaw
);
406 e
->encoding
= AUDIO_ENCODING_ULAW
;
408 e
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
419 haltwo_set_params(void *v
, int setmode
, int usemode
,
420 audio_params_t
*play
, audio_params_t
*rec
,
421 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
424 struct haltwo_softc
*sc
;
425 int master
, inc
, mod
;
429 if (play
->sample_rate
< 4000)
430 play
->sample_rate
= 4000;
431 if (play
->sample_rate
> 48000)
432 play
->sample_rate
= 48000;
434 if (44100 % play
->sample_rate
< 48000 % play
->sample_rate
)
439 /* HAL2 specification 3.1.2.21: Codecs should be driven with INC/MOD
440 * fractions equivalent to 4/N, where N is a positive integer. */
442 mod
= master
* inc
/ play
->sample_rate
;
444 /* Fixup upper layers idea of HW sample rate to the actual final rate */
445 play
->sample_rate
= master
* inc
/ mod
;
447 DPRINTF(("haltwo_set_params: master = %d inc = %d mod = %d"
448 " sample_rate = %ld\n", master
, inc
, mod
,
452 switch (play
->encoding
) {
453 case AUDIO_ENCODING_ULAW
:
454 if (play
->precision
!= 8)
457 hw
.encoding
= AUDIO_ENCODING_SLINEAR_LE
;
458 pfil
->append(pfil
, mulaw_to_linear16
, &hw
);
461 case AUDIO_ENCODING_SLINEAR_BE
:
462 case AUDIO_ENCODING_SLINEAR_LE
:
468 /* play points HW encoding */
470 /* Setup samplerate to HW */
471 haltwo_write_indirect(sc
, HAL2_IREG_BRES1_C1
,
472 master
== 44100 ? 1 : 0, 0);
473 /* XXX Documentation disagrees but this seems to work XXX */
474 haltwo_write_indirect(sc
, HAL2_IREG_BRES1_C2
,
475 inc
, 0xFFFF & (inc
- mod
- 1));
477 /* Setup endianness to HW */
478 haltwo_read_indirect(sc
, HAL2_IREG_DMA_END
, &tmp
, NULL
);
479 if (play
->encoding
== AUDIO_ENCODING_SLINEAR_LE
)
480 tmp
|= HAL2_DMA_END_CODECTX
;
482 tmp
&= ~HAL2_DMA_END_CODECTX
;
483 haltwo_write_indirect(sc
, HAL2_IREG_DMA_END
, tmp
, 0);
485 /* Set PBUS channel, Bresenham clock source, number of channels to HW */
486 haltwo_write_indirect(sc
, HAL2_IREG_DAC_C1
,
487 (0 << HAL2_C1_DMA_SHIFT
) |
488 (1 << HAL2_C1_CLKID_SHIFT
) |
489 (play
->channels
<< HAL2_C1_DATAT_SHIFT
), 0);
491 DPRINTF(("haltwo_set_params: hw_encoding = %d hw_channels = %d\n",
492 play
->encoding
, play
->channels
));
498 haltwo_round_blocksize(void *v
, int blocksize
,
499 int mode
, const audio_params_t
*param
)
502 /* XXX Make this smarter and support DMA descriptor chaining XXX */
503 /* XXX Rounding to nearest PAGE_SIZE might work? XXX */
508 haltwo_halt_output(void *v
)
510 struct haltwo_softc
*sc
;
513 /* Disable PBUS DMA */
514 bus_space_write_4(sc
->sc_st
, sc
->sc_dma_sh
, HPC3_PBUS_CH0_CTL
,
515 HPC3_PBUS_DMACTL_ACT_LD
);
521 haltwo_halt_input(void *v
)
528 haltwo_getdev(void *v
, struct audio_device
*dev
)
531 *dev
= haltwo_device
;
536 haltwo_set_port(void *v
, mixer_ctrl_t
*mc
)
538 struct haltwo_softc
*sc
;
541 if (mc
->type
!= AUDIO_MIXER_VALUE
)
544 if (mc
->un
.value
.num_channels
== 1)
545 lval
= rval
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
546 else if (mc
->un
.value
.num_channels
== 2) {
547 lval
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
];
548 rval
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
];
554 case HALTWO_MASTER_VOL
:
555 sc
->sc_vol_left
= lval
;
556 sc
->sc_vol_right
= rval
;
558 haltwo_write(sc
, vol
, HAL2_REG_VOL_LEFT
,
560 haltwo_write(sc
, vol
, HAL2_REG_VOL_RIGHT
,
572 haltwo_get_port(void *v
, mixer_ctrl_t
*mc
)
574 struct haltwo_softc
*sc
;
578 case HALTWO_MASTER_VOL
:
581 r
= sc
->sc_vol_right
;
588 if (mc
->un
.value
.num_channels
== 1)
589 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] = (l
+r
) / 2;
590 else if (mc
->un
.value
.num_channels
== 2) {
591 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] = l
;
592 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] = r
;
600 haltwo_query_devinfo(void *v
, mixer_devinfo_t
*dev
)
603 switch (dev
->index
) {
605 case HALTWO_MASTER_VOL
:
606 dev
->type
= AUDIO_MIXER_VALUE
;
607 dev
->mixer_class
= HALTWO_OUTPUT_CLASS
;
608 dev
->prev
= dev
->next
= AUDIO_MIXER_LAST
;
609 strcpy(dev
->label
.name
, AudioNmaster
);
610 dev
->un
.v
.num_channels
= 2;
611 dev
->un
.v
.delta
= 16;
612 strcpy(dev
->un
.v
.units
.name
, AudioNvolume
);
616 case HALTWO_OUTPUT_CLASS
:
617 dev
->type
= AUDIO_MIXER_CLASS
;
618 dev
->mixer_class
= HALTWO_OUTPUT_CLASS
;
619 dev
->next
= dev
->prev
= AUDIO_MIXER_LAST
;
620 strcpy(dev
->label
.name
, AudioCoutputs
);
631 haltwo_alloc_dmamem(struct haltwo_softc
*sc
, size_t size
,
632 struct haltwo_dmabuf
*p
)
638 /* XXX Check align/boundary XXX */
639 /* XXX Pass flags and use them instead BUS_DMA_NOWAIT? XXX */
640 err
= bus_dmamem_alloc(sc
->sc_dma_tag
, p
->size
, 0, 0, p
->dma_segs
,
641 HALTWO_MAX_DMASEGS
, &p
->dma_segcount
, BUS_DMA_NOWAIT
);
645 /* XXX BUS_DMA_COHERENT? XXX */
646 err
= bus_dmamem_map(sc
->sc_dma_tag
, p
->dma_segs
, p
->dma_segcount
,
647 p
->size
, &p
->kern_addr
, BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
);
651 /* XXX Just guessing ... XXX */
652 err
= bus_dmamap_create(sc
->sc_dma_tag
, p
->size
, HALTWO_MAX_DMASEGS
,
653 PAGE_SIZE
, 0, BUS_DMA_NOWAIT
, &p
->dma_map
);
657 err
= bus_dmamap_load(sc
->sc_dma_tag
, p
->dma_map
, p
->kern_addr
,
658 p
->size
, NULL
, BUS_DMA_NOWAIT
);
665 bus_dmamap_destroy(sc
->sc_dma_tag
, p
->dma_map
);
667 bus_dmamem_free(sc
->sc_dma_tag
, p
->dma_segs
, p
->dma_segcount
);
669 DPRINTF(("haltwo_alloc_dmamem failed: %d\n",err
));
675 haltwo_malloc(void *v
, int direction
, size_t size
, struct malloc_type
*type
,
678 struct haltwo_softc
*sc
;
679 struct haltwo_dmabuf
*p
;
681 DPRINTF(("haltwo_malloc size = %d\n", size
));
683 p
= malloc(sizeof(struct haltwo_dmabuf
), type
, flags
);
687 if (haltwo_alloc_dmamem(sc
, size
, p
)) {
692 p
->next
= sc
->sc_dma_bufs
;
699 haltwo_free(void *v
, void *addr
, struct malloc_type
*type
)
701 struct haltwo_softc
*sc
;
702 struct haltwo_dmabuf
*p
, **pp
;
705 for (pp
= &sc
->sc_dma_bufs
; (p
= *pp
) != NULL
; pp
= &p
->next
) {
706 if (p
->kern_addr
== addr
) {
713 panic("haltwo_free: buffer not in list");
717 haltwo_get_props(void *v
)
724 haltwo_trigger_output(void *v
, void *start
, void *end
, int blksize
,
725 void (*intr
)(void *), void *intrarg
, const audio_params_t
*param
)
727 struct haltwo_softc
*sc
;
728 struct haltwo_dmabuf
*p
;
731 unsigned int fifobeg
, fifoend
, highwater
;
733 DPRINTF(("haltwo_trigger_output start = %p end = %p blksize = %d"
734 " param = %p\n", start
, end
, blksize
, param
));
736 for (p
= sc
->sc_dma_bufs
; p
!= NULL
; p
= p
->next
)
737 if (p
->kern_addr
== start
)
741 printf("haltwo_trigger_output: buffer not in list\n");
746 /* Disable PBUS DMA */
747 bus_space_write_4(sc
->sc_st
, sc
->sc_dma_sh
, HPC3_PBUS_CH0_CTL
,
748 HPC3_PBUS_DMACTL_ACT_LD
);
750 /* Disable HAL2 codec DMA */
751 haltwo_read_indirect(sc
, HAL2_IREG_DMA_PORT_EN
, &tmp
, NULL
);
752 haltwo_write_indirect(sc
, HAL2_IREG_DMA_PORT_EN
,
753 tmp
& ~HAL2_DMA_PORT_EN_CODECTX
, 0);
755 haltwo_setup_dma(sc
, &sc
->sc_dac
, p
, (char *)end
- (char *)start
,
756 blksize
, intr
, intrarg
);
758 highwater
= (param
->channels
* 4) >> 1;
760 fifoend
= (param
->channels
* 8) >> 3;
762 DPRINTF(("haltwo_trigger_output: hw_channels = %d highwater = %d"
763 " fifobeg = %d fifoend = %d\n", param
->hw_channels
, highwater
,
766 ctrl
= HPC3_PBUS_DMACTL_RT
767 | HPC3_PBUS_DMACTL_ACT_LD
768 | (highwater
<< HPC3_PBUS_DMACTL_HIGHWATER_SHIFT
)
769 | (fifobeg
<< HPC3_PBUS_DMACTL_FIFOBEG_SHIFT
)
770 | (fifoend
<< HPC3_PBUS_DMACTL_FIFOEND_SHIFT
);
772 /* Using PBUS CH0 for DAC DMA */
773 haltwo_write_indirect(sc
, HAL2_IREG_DMA_DRV
, 1, 0);
775 /* HAL2 is ready for action, now setup PBUS for DMA transfer */
776 bus_space_write_4(sc
->sc_st
, sc
->sc_dma_sh
, HPC3_PBUS_CH0_DP
,
777 sc
->sc_dac
.dma_seg
.ds_addr
);
778 bus_space_write_4(sc
->sc_st
, sc
->sc_dma_sh
, HPC3_PBUS_CH0_CTL
,
779 ctrl
| HPC3_PBUS_DMACTL_ACT
);
781 /* Both HAL2 and PBUS have been setup, now start it up */
782 haltwo_read_indirect(sc
, HAL2_IREG_DMA_PORT_EN
, &tmp
, NULL
);
783 haltwo_write_indirect(sc
, HAL2_IREG_DMA_PORT_EN
,
784 tmp
| HAL2_DMA_PORT_EN_CODECTX
, 0);
790 haltwo_trigger_input(void *v
, void *start
, void *end
, int blksize
,
791 void (*intr
)(void *), void *intrarg
, const audio_params_t
*param
)
793 struct haltwo_softc
*sc
;
794 struct haltwo_dmabuf
*p
;
796 DPRINTF(("haltwo_trigger_input start = %p end = %p blksize = %d\n",
797 start
, end
, blksize
));
799 for (p
= sc
->sc_dma_bufs
; p
!= NULL
; p
= p
->next
)
800 if (p
->kern_addr
== start
)
804 printf("haltwo_trigger_input: buffer not in list\n");
810 haltwo_setup_dma(sc
, &sc
->sc_adc
, p
, (char *)end
- (char *)start
,
811 blksize
, intr
, intrarg
);
818 haltwo_shutdown(device_t self
, int howto
)
820 struct haltwo_softc
*sc
;
822 sc
= device_private(self
);
823 haltwo_write(sc
, ctl
, HAL2_REG_CTL_ISR
, 0);
824 haltwo_write(sc
, ctl
, HAL2_REG_CTL_ISR
,
825 HAL2_ISR_GLOBAL_RESET_N
| HAL2_ISR_CODEC_RESET_N
);