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 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 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 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 * 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 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 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 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 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 404 bba_getdev(void *addr, struct audio_device *retp) 405 { 406 407 *retp = bba_device; 408 return 0; 409 } 410 411 412 static int 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 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 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 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 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 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 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 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