1 /* $NetBSD: bba.c,v 1.46 2020/09/12 05:19:16 isaki Exp $ */
2
3 /*
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* maxine/alpha baseboard audio (bba) */
30
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: bba.c,v 1.46 2020/09/12 05:19:16 isaki Exp $");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/device.h>
38 #include <sys/kmem.h>
39
40 #include <sys/bus.h>
41 #include <machine/autoconf.h>
42 #include <sys/cpu.h>
43
44 #include <sys/audioio.h>
45 #include <dev/audio/audio_if.h>
46
47 #include <dev/ic/am7930reg.h>
48 #include <dev/ic/am7930var.h>
49
50 #include <dev/tc/tcvar.h>
51 #include <dev/tc/ioasicreg.h>
52 #include <dev/tc/ioasicvar.h>
53
54 /* include mulaw.c (not .h file) here to expand mulaw32 */
55 void audio_mulaw32_to_internal(audio_filter_arg_t *);
56 void audio_internal_to_mulaw32(audio_filter_arg_t *);
57 #define MULAW32
58 #include <dev/audio/mulaw.c>
59
60 #ifdef AUDIO_DEBUG
61 #define DPRINTF(x) if (am7930debug) printf x
62 #else
63 #define DPRINTF(x)
64 #endif /* AUDIO_DEBUG */
65
66 #define BBA_MAX_DMA_SEGMENTS 16
67 #define BBA_DMABUF_SIZE (BBA_MAX_DMA_SEGMENTS*IOASIC_DMA_BLOCKSIZE)
68 #define BBA_DMABUF_ALIGN IOASIC_DMA_BLOCKSIZE
69 #define BBA_DMABUF_BOUNDARY 0
70
71 struct bba_mem {
72 struct bba_mem *next;
73 bus_addr_t addr;
74 bus_size_t size;
75 void *kva;
76 };
77
78 struct bba_dma_state {
79 bus_dmamap_t dmam; /* DMA map */
80 int active;
81 int curseg; /* current segment in DMA buffer */
82 void (*intr)(void *); /* higher-level audio handler */
83 void *intr_arg;
84 };
85
86 struct bba_softc {
87 struct am7930_softc sc_am7930; /* glue to MI code */
88
89 bus_space_tag_t sc_bst; /* IOASIC bus tag/handle */
90 bus_space_handle_t sc_bsh;
91 bus_dma_tag_t sc_dmat;
92 bus_space_handle_t sc_codec_bsh; /* codec bus space handle */
93
94 struct bba_mem *sc_mem_head; /* list of buffers */
95
96 struct bba_dma_state sc_tx_dma_state;
97 struct bba_dma_state sc_rx_dma_state;
98 };
99
100 static int bba_match(device_t, cfdata_t, void *);
101 static void bba_attach(device_t, device_t, void *);
102
103 CFATTACH_DECL_NEW(bba, sizeof(struct bba_softc),
104 bba_match, bba_attach, NULL, NULL);
105
106 /*
107 * Define our interface into the am7930 MI driver.
108 */
109
110 static uint8_t bba_codec_dread(struct am7930_softc *, int);
111 static void bba_codec_dwrite(struct am7930_softc *, int, uint8_t);
112
113 struct am7930_glue bba_glue = {
114 bba_codec_dread,
115 bba_codec_dwrite,
116 };
117
118 /*
119 * Define our interface to the higher level audio driver.
120 */
121
122 static int bba_query_format(void *, audio_format_query_t *);
123 static int bba_set_format(void *, int,
124 const audio_params_t *, const audio_params_t *,
125 audio_filter_reg_t *, audio_filter_reg_t *);
126 static int bba_round_blocksize(void *, int, int, const audio_params_t *);
127 static int bba_halt_output(void *);
128 static int bba_halt_input(void *);
129 static int bba_getdev(void *, struct audio_device *);
130 static void *bba_allocm(void *, int, size_t);
131 static void bba_freem(void *, void *, size_t);
132 static size_t bba_round_buffersize(void *, int, size_t);
133 static int bba_trigger_output(void *, void *, void *, int,
134 void (*)(void *), void *,
135 const audio_params_t *);
136 static int bba_trigger_input(void *, void *, void *, int,
137 void (*)(void *), void *,
138 const audio_params_t *);
139
140 static const struct audio_hw_if sa_hw_if = {
141 .query_format = bba_query_format,
142 .set_format = bba_set_format,
143 .round_blocksize = bba_round_blocksize, /* md */
144 .commit_settings = am7930_commit_settings,
145 .halt_output = bba_halt_output, /* md */
146 .halt_input = bba_halt_input, /* md */
147 .getdev = bba_getdev,
148 .set_port = am7930_set_port,
149 .get_port = am7930_get_port,
150 .query_devinfo = am7930_query_devinfo,
151 .allocm = bba_allocm, /* md */
152 .freem = bba_freem, /* md */
153 .round_buffersize = bba_round_buffersize, /* md */
154 .get_props = am7930_get_props,
155 .trigger_output = bba_trigger_output, /* md */
156 .trigger_input = bba_trigger_input, /* md */
157 .get_locks = am7930_get_locks,
158 };
159
160 static struct audio_device bba_device = {
161 "am7930",
162 "x",
163 "bba"
164 };
165
166 static const struct audio_format bba_format = {
167 .mode = AUMODE_PLAY | AUMODE_RECORD,
168 .encoding = AUDIO_ENCODING_ULAW, /* XXX */
169 .validbits = 32,
170 .precision = 32,
171 .channels = 1,
172 .channel_mask = AUFMT_MONAURAL,
173 .frequency_type = 1,
174 .frequency = { 8000 },
175 };
176
177 static int bba_intr(void *);
178 static void bba_reset(struct bba_softc *, int);
179
180 static int
bba_match(device_t parent,cfdata_t cf,void * aux)181 bba_match(device_t parent, cfdata_t cf, void *aux)
182 {
183 struct ioasicdev_attach_args *ia;
184
185 ia = aux;
186 if (strcmp(ia->iada_modname, "isdn") != 0 &&
187 strcmp(ia->iada_modname, "AMD79c30") != 0)
188 return 0;
189
190 return 1;
191 }
192
193
194 static void
bba_attach(device_t parent,device_t self,void * aux)195 bba_attach(device_t parent, device_t self, void *aux)
196 {
197 struct ioasicdev_attach_args *ia;
198 struct bba_softc *sc;
199 struct am7930_softc *amsc;
200 struct ioasic_softc *iosc = device_private(parent);
201
202 ia = aux;
203 sc = device_private(self);
204 amsc = &sc->sc_am7930;
205 amsc->sc_dev = self;
206 sc->sc_bst = iosc->sc_bst;
207 sc->sc_bsh = iosc->sc_bsh;
208 sc->sc_dmat = iosc->sc_dmat;
209
210 /* get the bus space handle for codec */
211 if (bus_space_subregion(sc->sc_bst, sc->sc_bsh,
212 ia->iada_offset, 0, &sc->sc_codec_bsh)) {
213 aprint_error_dev(self, "unable to map device\n");
214 return;
215 }
216
217 printf("\n");
218
219 bba_reset(sc, 1);
220
221 /*
222 * Set up glue for MI code early; we use some of it here.
223 */
224 amsc->sc_glue = &bba_glue;
225
226 /*
227 * MI initialisation. We will be doing DMA.
228 */
229 am7930_init(amsc, AUDIOAMD_DMA_MODE);
230
231 ioasic_intr_establish(parent, ia->iada_cookie, TC_IPL_NONE,
232 bba_intr, sc);
233
234 audio_attach_mi(&sa_hw_if, sc, self);
235 }
236
237
238 static void
bba_reset(struct bba_softc * sc,int reset)239 bba_reset(struct bba_softc *sc, int reset)
240 {
241 uint32_t ssr;
242
243 /* disable any DMA and reset the codec */
244 ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
245 ssr &= ~(IOASIC_CSR_DMAEN_ISDN_T | IOASIC_CSR_DMAEN_ISDN_R);
246 if (reset)
247 ssr &= ~IOASIC_CSR_ISDN_ENABLE;
248 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
249 DELAY(10); /* 400ns required for codec to reset */
250
251 /* initialise DMA pointers */
252 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR, -1);
253 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR, -1);
254 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR, -1);
255 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR, -1);
256
257 /* take out of reset state */
258 if (reset) {
259 ssr |= IOASIC_CSR_ISDN_ENABLE;
260 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
261 }
262 }
263
264
265 static void *
bba_allocm(void * addr,int direction,size_t size)266 bba_allocm(void *addr, int direction, size_t size)
267 {
268 struct am7930_softc *amsc;
269 struct bba_softc *sc;
270 bus_dma_segment_t seg;
271 int rseg;
272 void *kva;
273 struct bba_mem *m;
274 int state;
275
276 DPRINTF(("bba_allocm: size = %zu\n", size));
277 sc = addr;
278 amsc = addr;
279 state = 0;
280
281 if (bus_dmamem_alloc(sc->sc_dmat, size, BBA_DMABUF_ALIGN,
282 BBA_DMABUF_BOUNDARY, &seg, 1, &rseg, BUS_DMA_WAITOK)) {
283 aprint_error_dev(amsc->sc_dev, "can't allocate DMA buffer\n");
284 goto bad;
285 }
286 state |= 1;
287
288 if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
289 &kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT)) {
290 aprint_error_dev(amsc->sc_dev, "can't map DMA buffer\n");
291 goto bad;
292 }
293 state |= 2;
294
295 m = kmem_alloc(sizeof(struct bba_mem), KM_SLEEP);
296 m->addr = seg.ds_addr;
297 m->size = seg.ds_len;
298 m->kva = kva;
299 m->next = sc->sc_mem_head;
300 sc->sc_mem_head = m;
301
302 return (void *)kva;
303
304 bad:
305 if (state & 2)
306 bus_dmamem_unmap(sc->sc_dmat, kva, size);
307 if (state & 1)
308 bus_dmamem_free(sc->sc_dmat, &seg, 1);
309 return NULL;
310 }
311
312
313 static void
bba_freem(void * addr,void * ptr,size_t size)314 bba_freem(void *addr, void *ptr, size_t size)
315 {
316 struct bba_softc *sc;
317 struct bba_mem **mp, *m;
318 bus_dma_segment_t seg;
319 void *kva;
320
321 sc = addr;
322 kva = (void *)addr;
323 for (mp = &sc->sc_mem_head; *mp && (*mp)->kva != kva;
324 mp = &(*mp)->next)
325 continue;
326 m = *mp;
327 if (m == NULL) {
328 printf("bba_freem: freeing unallocated memory\n");
329 return;
330 }
331 *mp = m->next;
332 bus_dmamem_unmap(sc->sc_dmat, kva, m->size);
333
334 seg.ds_addr = m->addr;
335 seg.ds_len = m->size;
336 bus_dmamem_free(sc->sc_dmat, &seg, 1);
337 kmem_free(m, sizeof(struct bba_mem));
338 }
339
340
341 static size_t
bba_round_buffersize(void * addr,int direction,size_t size)342 bba_round_buffersize(void *addr, int direction, size_t size)
343 {
344
345 DPRINTF(("bba_round_buffersize: size=%zu\n", size));
346 return size > BBA_DMABUF_SIZE ? BBA_DMABUF_SIZE :
347 roundup(size, IOASIC_DMA_BLOCKSIZE);
348 }
349
350
351 static int
bba_halt_output(void * addr)352 bba_halt_output(void *addr)
353 {
354 struct bba_softc *sc;
355 struct bba_dma_state *d;
356 uint32_t ssr;
357
358 sc = addr;
359 d = &sc->sc_tx_dma_state;
360 /* disable any DMA */
361 ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
362 ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
363 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
364 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR, -1);
365 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR, -1);
366
367 if (d->active) {
368 bus_dmamap_unload(sc->sc_dmat, d->dmam);
369 bus_dmamap_destroy(sc->sc_dmat, d->dmam);
370 d->active = 0;
371 }
372
373 return 0;
374 }
375
376
377 static int
bba_halt_input(void * addr)378 bba_halt_input(void *addr)
379 {
380 struct bba_softc *sc;
381 struct bba_dma_state *d;
382 uint32_t ssr;
383
384 sc = addr;
385 d = &sc->sc_rx_dma_state;
386 /* disable any DMA */
387 ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
388 ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
389 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
390 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR, -1);
391 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR, -1);
392
393 if (d->active) {
394 bus_dmamap_unload(sc->sc_dmat, d->dmam);
395 bus_dmamap_destroy(sc->sc_dmat, d->dmam);
396 d->active = 0;
397 }
398
399 return 0;
400 }
401
402
403 static int
bba_getdev(void * addr,struct audio_device * retp)404 bba_getdev(void *addr, struct audio_device *retp)
405 {
406
407 *retp = bba_device;
408 return 0;
409 }
410
411
412 static int
bba_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)413 bba_trigger_output(void *addr, void *start, void *end, int blksize,
414 void (*intr)(void *), void *arg,
415 const audio_params_t *param)
416 {
417 struct bba_softc *sc;
418 struct bba_dma_state *d;
419 uint32_t ssr;
420 tc_addr_t phys, nphys;
421 int state;
422
423 DPRINTF(("bba_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
424 addr, start, end, blksize, intr, arg));
425 sc = addr;
426 d = &sc->sc_tx_dma_state;
427 state = 0;
428
429 /* disable any DMA */
430 ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
431 ssr &= ~IOASIC_CSR_DMAEN_ISDN_T;
432 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
433
434 if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
435 BBA_MAX_DMA_SEGMENTS, IOASIC_DMA_BLOCKSIZE,
436 BBA_DMABUF_BOUNDARY, BUS_DMA_NOWAIT, &d->dmam)) {
437 printf("bba_trigger_output: can't create DMA map\n");
438 goto bad;
439 }
440 state |= 1;
441
442 if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
443 (char *)end - (char *)start, NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT)) {
444 printf("bba_trigger_output: can't load DMA map\n");
445 goto bad;
446 }
447 state |= 2;
448
449 d->intr = intr;
450 d->intr_arg = arg;
451 d->curseg = 1;
452
453 /* get physical address of buffer start */
454 phys = (tc_addr_t)d->dmam->dm_segs[0].ds_addr;
455 nphys = (tc_addr_t)d->dmam->dm_segs[1].ds_addr;
456
457 /* setup DMA pointer */
458 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_DMAPTR,
459 IOASIC_DMA_ADDR(phys));
460 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_X_NEXTPTR,
461 IOASIC_DMA_ADDR(nphys));
462
463 /* kick off DMA */
464 ssr |= IOASIC_CSR_DMAEN_ISDN_T;
465 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
466
467 d->active = 1;
468
469 return 0;
470
471 bad:
472 if (state & 2)
473 bus_dmamap_unload(sc->sc_dmat, d->dmam);
474 if (state & 1)
475 bus_dmamap_destroy(sc->sc_dmat, d->dmam);
476 return 1;
477 }
478
479
480 static int
bba_trigger_input(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)481 bba_trigger_input(void *addr, void *start, void *end, int blksize,
482 void (*intr)(void *), void *arg, const audio_params_t *param)
483 {
484 struct bba_softc *sc;
485 struct bba_dma_state *d;
486 tc_addr_t phys, nphys;
487 uint32_t ssr;
488 int state = 0;
489
490 DPRINTF(("bba_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
491 addr, start, end, blksize, intr, arg));
492 sc = addr;
493 d = &sc->sc_rx_dma_state;
494 state = 0;
495
496 /* disable any DMA */
497 ssr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR);
498 ssr &= ~IOASIC_CSR_DMAEN_ISDN_R;
499 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
500
501 if (bus_dmamap_create(sc->sc_dmat, (char *)end - (char *)start,
502 BBA_MAX_DMA_SEGMENTS, IOASIC_DMA_BLOCKSIZE,
503 BBA_DMABUF_BOUNDARY, BUS_DMA_NOWAIT, &d->dmam)) {
504 printf("bba_trigger_input: can't create DMA map\n");
505 goto bad;
506 }
507 state |= 1;
508
509 if (bus_dmamap_load(sc->sc_dmat, d->dmam, start,
510 (char *)end - (char *)start, NULL, BUS_DMA_READ|BUS_DMA_NOWAIT)) {
511 printf("bba_trigger_input: can't load DMA map\n");
512 goto bad;
513 }
514 state |= 2;
515
516 d->intr = intr;
517 d->intr_arg = arg;
518 d->curseg = 1;
519
520 /* get physical address of buffer start */
521 phys = (tc_addr_t)d->dmam->dm_segs[0].ds_addr;
522 nphys = (tc_addr_t)d->dmam->dm_segs[1].ds_addr;
523
524 /* setup DMA pointer */
525 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_DMAPTR,
526 IOASIC_DMA_ADDR(phys));
527 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_ISDN_R_NEXTPTR,
528 IOASIC_DMA_ADDR(nphys));
529
530 /* kick off DMA */
531 ssr |= IOASIC_CSR_DMAEN_ISDN_R;
532 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_CSR, ssr);
533
534 d->active = 1;
535
536 return 0;
537
538 bad:
539 if (state & 2)
540 bus_dmamap_unload(sc->sc_dmat, d->dmam);
541 if (state & 1)
542 bus_dmamap_destroy(sc->sc_dmat, d->dmam);
543 return 1;
544 }
545
546 static int
bba_intr(void * addr)547 bba_intr(void *addr)
548 {
549 struct bba_softc *sc;
550 struct bba_dma_state *d;
551 tc_addr_t nphys;
552 int mask;
553
554 sc = addr;
555 mutex_enter(&sc->sc_am7930.sc_intr_lock);
556
557 mask = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_INTR);
558
559 if (mask & IOASIC_INTR_ISDN_TXLOAD) {
560 d = &sc->sc_tx_dma_state;
561 d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
562 nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
563 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
564 IOASIC_ISDN_X_NEXTPTR, IOASIC_DMA_ADDR(nphys));
565 if (d->intr != NULL)
566 (*d->intr)(d->intr_arg);
567 }
568 if (mask & IOASIC_INTR_ISDN_RXLOAD) {
569 d = &sc->sc_rx_dma_state;
570 d->curseg = (d->curseg+1) % d->dmam->dm_nsegs;
571 nphys = (tc_addr_t)d->dmam->dm_segs[d->curseg].ds_addr;
572 bus_space_write_4(sc->sc_bst, sc->sc_bsh,
573 IOASIC_ISDN_R_NEXTPTR, IOASIC_DMA_ADDR(nphys));
574 if (d->intr != NULL)
575 (*d->intr)(d->intr_arg);
576 }
577
578 mutex_exit(&sc->sc_am7930.sc_intr_lock);
579
580 return 0;
581 }
582
583 static int
bba_query_format(void * addr,audio_format_query_t * afp)584 bba_query_format(void *addr, audio_format_query_t *afp)
585 {
586
587 return audio_query_format(&bba_format, 1, afp);
588 }
589
590 static int
bba_set_format(void * addr,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)591 bba_set_format(void *addr, int setmode,
592 const audio_params_t *play, const audio_params_t *rec,
593 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
594 {
595
596 if ((setmode & AUMODE_PLAY) != 0) {
597 pfil->codec = audio_internal_to_mulaw32;
598 }
599 if ((setmode & AUMODE_RECORD) != 0) {
600 rfil->codec = audio_mulaw32_to_internal;
601 }
602
603 return 0;
604 }
605
606 static int
bba_round_blocksize(void * addr,int blk,int mode,const audio_params_t * param)607 bba_round_blocksize(void *addr, int blk, int mode, const audio_params_t *param)
608 {
609
610 return IOASIC_DMA_BLOCKSIZE;
611 }
612
613
614 /* direct write */
615 static void
bba_codec_dwrite(struct am7930_softc * amsc,int reg,uint8_t val)616 bba_codec_dwrite(struct am7930_softc *amsc, int reg, uint8_t val)
617 {
618 struct bba_softc *sc;
619
620 sc = (struct bba_softc *)amsc;
621 DPRINTF(("bba_codec_dwrite(): sc=%p, reg=%d, val=%d\n", sc, reg, val));
622
623 #if defined(__alpha__)
624 bus_space_write_4(sc->sc_bst, sc->sc_codec_bsh,
625 reg << 2, val << 8);
626 #else
627 bus_space_write_4(sc->sc_bst, sc->sc_codec_bsh,
628 reg << 6, val);
629 #endif
630 }
631
632 /* direct read */
633 static uint8_t
bba_codec_dread(struct am7930_softc * amsc,int reg)634 bba_codec_dread(struct am7930_softc *amsc, int reg)
635 {
636 struct bba_softc *sc;
637
638 sc = (struct bba_softc *)amsc;
639 DPRINTF(("bba_codec_dread(): sc=%p, reg=%d\n", sc, reg));
640
641 #if defined(__alpha__)
642 return ((bus_space_read_4(sc->sc_bst, sc->sc_codec_bsh,
643 reg << 2) >> 8) & 0xff);
644 #else
645 return (bus_space_read_4(sc->sc_bst, sc->sc_codec_bsh,
646 reg << 6) & 0xff);
647 #endif
648 }
649