1 /* $NetBSD: gcscaudio.c,v 1.6 2010/11/13 13:52:05 uebayasi Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 SHIMIZU Ryo <ryo@nerv.org> 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 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: gcscaudio.c,v 1.6 2010/11/13 13:52:05 uebayasi Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/malloc.h> 35 #include <sys/device.h> 36 #include <sys/queue.h> 37 38 #include <dev/pci/pcidevs.h> 39 #include <dev/pci/pcivar.h> 40 41 #include <sys/audioio.h> 42 #include <dev/audio_if.h> 43 #include <dev/mulaw.h> 44 #include <dev/auconv.h> 45 #include <dev/ic/ac97reg.h> 46 #include <dev/ic/ac97var.h> 47 48 #include <dev/pci/gcscaudioreg.h> 49 50 51 #define GCSCAUDIO_NPRDTABLE 256 /* including a JMP-PRD for loop */ 52 #define GCSCAUDIO_PRD_SIZE_MAX 65532 /* limited by CS5536 Controller */ 53 #define GCSCAUDIO_BUFSIZE_MAX (GCSCAUDIO_PRD_SIZE_MAX * (GCSCAUDIO_NPRDTABLE - 1)) 54 55 struct gcscaudio_prd { 56 /* PRD table for play/rec */ 57 struct gcscaudio_prdtables { 58 #define PRD_TABLE_FRONT 0 59 #define PRD_TABLE_SURR 1 60 #define PRD_TABLE_CENTER 2 61 #define PRD_TABLE_LFE 3 62 #define PRD_TABLE_REC 4 63 #define PRD_TABLE_MAX 5 64 struct acc_prd prdtbl[PRD_TABLE_MAX][GCSCAUDIO_NPRDTABLE]; 65 } *p_prdtables; 66 bus_dmamap_t p_prdmap; 67 bus_dma_segment_t p_prdsegs[1]; 68 int p_prdnseg; 69 }; 70 71 struct gcscaudio_dma { 72 LIST_ENTRY(gcscaudio_dma) list; 73 bus_dmamap_t map; 74 void *addr; 75 size_t size; 76 bus_dma_segment_t segs[1]; 77 int nseg; 78 }; 79 80 struct gcscaudio_softc_ch { 81 void (*ch_intr)(void *); 82 void *ch_intr_arg; 83 struct audio_params ch_params; 84 }; 85 86 struct gcscaudio_softc { 87 struct device sc_dev; 88 pci_chipset_tag_t sc_pc; 89 pcitag_t sc_pt; 90 void *sc_ih; 91 bus_space_tag_t sc_iot; 92 bus_space_handle_t sc_ioh; 93 bus_size_t sc_ios; 94 bus_dma_tag_t sc_dmat; 95 96 /* allocated DMA buffer list */ 97 LIST_HEAD(, gcscaudio_dma) sc_dmalist; 98 99 #define GCSCAUDIO_MAXFORMATS 4 100 struct audio_format sc_formats[GCSCAUDIO_MAXFORMATS]; 101 int sc_nformats; 102 struct audio_encoding_set *sc_encodings; 103 104 /* AC97 codec */ 105 struct ac97_host_if host_if; 106 struct ac97_codec_if *codec_if; 107 108 /* input, output channels */ 109 struct gcscaudio_softc_ch sc_play; 110 struct gcscaudio_softc_ch sc_rec; 111 struct gcscaudio_prd sc_prd; 112 113 /* multi channel splitter work; {4,6}ch stream to {2,4} DMA buffers */ 114 void *sc_mch_split_buf; 115 void *sc_mch_split_start; 116 int sc_mch_split_off; 117 int sc_mch_split_size; 118 int sc_mch_split_blksize; 119 void (*sc_mch_splitter)(void *, void *, int, int); 120 bool sc_spdif; 121 }; 122 123 /* for cfattach */ 124 static int gcscaudio_match(device_t, cfdata_t, void *); 125 static void gcscaudio_attach(device_t, device_t, void *); 126 127 /* for audio_hw_if */ 128 static int gcscaudio_open(void *, int); 129 static void gcscaudio_close(void *); 130 static int gcscaudio_query_encoding(void *, struct audio_encoding *); 131 static int gcscaudio_set_params(void *, int, int, audio_params_t *, 132 audio_params_t *, stream_filter_list_t *, 133 stream_filter_list_t *); 134 static int gcscaudio_round_blocksize(void *, int, int, const audio_params_t *); 135 static int gcscaudio_halt_output(void *); 136 static int gcscaudio_halt_input(void *); 137 static int gcscaudio_getdev(void *, struct audio_device *); 138 static int gcscaudio_set_port(void *, mixer_ctrl_t *); 139 static int gcscaudio_get_port(void *, mixer_ctrl_t *); 140 static int gcscaudio_query_devinfo(void *, mixer_devinfo_t *); 141 static void *gcscaudio_malloc(void *, int, size_t, struct malloc_type *, int); 142 static void gcscaudio_free(void *, void *, struct malloc_type *); 143 static size_t gcscaudio_round_buffersize(void *, int, size_t); 144 static paddr_t gcscaudio_mappage(void *, void *, off_t, int); 145 static int gcscaudio_get_props(void *); 146 static int gcscaudio_trigger_output(void *, void *, void *, int, 147 void (*)(void *), void *, 148 const audio_params_t *); 149 static int gcscaudio_trigger_input(void *, void *, void *, int, 150 void (*)(void *), void *, 151 const audio_params_t *); 152 static bool gcscaudio_resume(device_t, const pmf_qual_t *); 153 static int gcscaudio_intr(void *); 154 155 /* for codec_if */ 156 static int gcscaudio_attach_codec(void *, struct ac97_codec_if *); 157 static int gcscaudio_write_codec(void *, uint8_t, uint16_t); 158 static int gcscaudio_read_codec(void *, uint8_t, uint16_t *); 159 static int gcscaudio_reset_codec(void *); 160 static void gcscaudio_spdif_event_codec(void *, bool); 161 162 /* misc */ 163 static int gcscaudio_append_formats(struct gcscaudio_softc *, 164 const struct audio_format *); 165 static int gcscaudio_wait_ready_codec(struct gcscaudio_softc *sc, const char *); 166 static int gcscaudio_set_params_ch(struct gcscaudio_softc *, 167 struct gcscaudio_softc_ch *, int, 168 audio_params_t *, stream_filter_list_t *); 169 static int gcscaudio_allocate_dma(struct gcscaudio_softc *, size_t, void **, 170 bus_dma_segment_t *, int, int *, 171 int, bus_dmamap_t *); 172 173 174 CFATTACH_DECL(gcscaudio, sizeof (struct gcscaudio_softc), 175 gcscaudio_match, gcscaudio_attach, NULL, NULL); 176 177 178 static struct audio_device gcscaudio_device = { 179 "AMD Geode CS5536", 180 "", 181 "gcscaudio" 182 }; 183 184 static const struct audio_hw_if gcscaudio_hw_if = { 185 .open = gcscaudio_open, 186 .close = gcscaudio_close, 187 .drain = NULL, 188 .query_encoding = gcscaudio_query_encoding, 189 .set_params = gcscaudio_set_params, 190 .round_blocksize = gcscaudio_round_blocksize, 191 .commit_settings = NULL, 192 .init_output = NULL, 193 .init_input = NULL, 194 .start_output = NULL, 195 .start_input = NULL, 196 .halt_output = gcscaudio_halt_output, 197 .halt_input = gcscaudio_halt_input, 198 .speaker_ctl = NULL, 199 .getdev = gcscaudio_getdev, 200 .setfd = NULL, 201 .set_port = gcscaudio_set_port, 202 .get_port = gcscaudio_get_port, 203 .query_devinfo = gcscaudio_query_devinfo, 204 .allocm = gcscaudio_malloc, 205 .freem = gcscaudio_free, 206 .round_buffersize = gcscaudio_round_buffersize, 207 .mappage = gcscaudio_mappage, 208 .get_props = gcscaudio_get_props, 209 .trigger_output = gcscaudio_trigger_output, 210 .trigger_input = gcscaudio_trigger_input, 211 .dev_ioctl = NULL, 212 .powerstate = NULL 213 }; 214 215 static const struct audio_format gcscaudio_formats_2ch = { 216 NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 217 2, AUFMT_STEREO, 0, {8000, 48000} 218 }; 219 220 static const struct audio_format gcscaudio_formats_4ch = { 221 NULL, AUMODE_PLAY, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 222 4, AUFMT_SURROUND4, 0, {8000, 48000} 223 }; 224 225 static const struct audio_format gcscaudio_formats_6ch = { 226 NULL, AUMODE_PLAY, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 227 6, AUFMT_DOLBY_5_1, 0, {8000, 48000} 228 }; 229 230 static int 231 gcscaudio_match(device_t parent, cfdata_t match, void *aux) 232 { 233 struct pci_attach_args *pa; 234 235 pa = (struct pci_attach_args *)aux; 236 if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD) && 237 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_CS5536_AUDIO)) 238 return 1; 239 240 return 0; 241 } 242 243 static int 244 gcscaudio_append_formats(struct gcscaudio_softc *sc, 245 const struct audio_format *format) 246 { 247 if (sc->sc_nformats >= GCSCAUDIO_MAXFORMATS) { 248 aprint_error_dev(&sc->sc_dev, "too many formats\n"); 249 return EINVAL; 250 } 251 sc->sc_formats[sc->sc_nformats++] = *format; 252 return 0; 253 } 254 255 static void 256 gcscaudio_attach(device_t parent, device_t self, void *aux) 257 { 258 struct gcscaudio_softc *sc; 259 struct pci_attach_args *pa; 260 const char *intrstr; 261 pci_intr_handle_t ih; 262 int rc, i; 263 264 sc = device_private(self); 265 266 aprint_naive(": Audio controller\n"); 267 268 pa = aux; 269 sc->sc_pc = pa->pa_pc; 270 sc->sc_pt = pa->pa_tag; 271 sc->sc_dmat = pa->pa_dmat; 272 LIST_INIT(&sc->sc_dmalist); 273 sc->sc_mch_split_buf = NULL; 274 275 aprint_normal(": AMD Geode CS5536 Audio\n"); 276 277 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0, 278 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)) { 279 aprint_error_dev(&sc->sc_dev, "can't map i/o space\n"); 280 return; 281 } 282 283 if (pci_intr_map(pa, &ih)) { 284 aprint_error_dev(&sc->sc_dev, "couldn't map interrupt\n"); 285 goto attach_failure_unmap; 286 } 287 intrstr = pci_intr_string(sc->sc_pc, ih); 288 289 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_AUDIO, 290 gcscaudio_intr, sc); 291 if (sc->sc_ih == NULL) { 292 aprint_error_dev(&sc->sc_dev, "couldn't establish interrupt"); 293 if (intrstr != NULL) 294 aprint_error(" at %s", intrstr); 295 aprint_error("\n"); 296 goto attach_failure_unmap; 297 } 298 299 aprint_normal_dev(&sc->sc_dev, "interrupting at %s\n", intrstr); 300 301 302 if (gcscaudio_allocate_dma(sc, sizeof(*sc->sc_prd.p_prdtables), 303 (void **)&(sc->sc_prd.p_prdtables), sc->sc_prd.p_prdsegs, 1, 304 &(sc->sc_prd.p_prdnseg), M_WAITOK, &(sc->sc_prd.p_prdmap)) != 0) 305 goto attach_failure_intr; 306 307 sc->host_if.arg = sc; 308 sc->host_if.attach = gcscaudio_attach_codec; 309 sc->host_if.read = gcscaudio_read_codec; 310 sc->host_if.write = gcscaudio_write_codec; 311 sc->host_if.reset = gcscaudio_reset_codec; 312 sc->host_if.spdif_event = gcscaudio_spdif_event_codec; 313 314 if ((rc = ac97_attach(&sc->host_if, self)) != 0) { 315 aprint_error_dev(&sc->sc_dev, 316 "can't attach codec (error=%d)\n", rc); 317 goto attach_failure_intr; 318 } 319 320 if (!pmf_device_register(self, NULL, gcscaudio_resume)) 321 aprint_error_dev(self, "couldn't establish power handler\n"); 322 323 324 sc->sc_nformats = 0; 325 gcscaudio_append_formats(sc, &gcscaudio_formats_2ch); 326 if (AC97_IS_4CH(sc->codec_if)) 327 gcscaudio_append_formats(sc, &gcscaudio_formats_4ch); 328 if (AC97_IS_6CH(sc->codec_if)) 329 gcscaudio_append_formats(sc, &gcscaudio_formats_6ch); 330 if (AC97_IS_FIXED_RATE(sc->codec_if)) { 331 for (i = 0; i < sc->sc_nformats; i++) { 332 sc->sc_formats[i].frequency_type = 1; 333 sc->sc_formats[i].frequency[0] = 48000; 334 } 335 } 336 337 if ((rc = auconv_create_encodings(sc->sc_formats, sc->sc_nformats, 338 &sc->sc_encodings)) != 0) { 339 aprint_error_dev(self, 340 "auconv_create_encoding: error=%d\n", rc); 341 goto attach_failure_codec; 342 } 343 344 audio_attach_mi(&gcscaudio_hw_if, sc, &sc->sc_dev); 345 sc->codec_if->vtbl->unlock(sc->codec_if); 346 return; 347 348 attach_failure_codec: 349 sc->codec_if->vtbl->detach(sc->codec_if); 350 attach_failure_intr: 351 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 352 attach_failure_unmap: 353 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 354 return; 355 } 356 357 static int 358 gcscaudio_attach_codec(void *arg, struct ac97_codec_if *codec_if) 359 { 360 struct gcscaudio_softc *sc; 361 362 sc = (struct gcscaudio_softc *)arg; 363 sc->codec_if = codec_if; 364 return 0; 365 } 366 367 static int 368 gcscaudio_reset_codec(void *arg) 369 { 370 struct gcscaudio_softc *sc; 371 sc = (struct gcscaudio_softc *)arg; 372 373 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL, 374 ACC_CODEC_CNTL_LNK_WRM_RST | 375 ACC_CODEC_CNTL_CMD_NEW); 376 377 if (gcscaudio_wait_ready_codec(sc, "reset timeout\n")) 378 return 1; 379 380 return 0; 381 } 382 383 static void 384 gcscaudio_spdif_event_codec(void *arg, bool flag) 385 { 386 struct gcscaudio_softc *sc; 387 388 sc = (struct gcscaudio_softc *)arg; 389 sc->sc_spdif = flag; 390 } 391 392 static int 393 gcscaudio_wait_ready_codec(struct gcscaudio_softc *sc, const char *timeout_msg) 394 { 395 int i; 396 397 #define GCSCAUDIO_WAIT_READY_CODEC_TIMEOUT 500 398 for (i = GCSCAUDIO_WAIT_READY_CODEC_TIMEOUT; (i >= 0) && 399 (bus_space_read_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL) & 400 ACC_CODEC_CNTL_CMD_NEW); i--) 401 delay(1); 402 403 if (i < 0) { 404 aprint_error_dev(&sc->sc_dev, timeout_msg); 405 return 1; 406 } 407 408 return 0; 409 } 410 411 static int 412 gcscaudio_write_codec(void *arg, uint8_t reg, uint16_t val) 413 { 414 struct gcscaudio_softc *sc; 415 416 sc = (struct gcscaudio_softc *)arg; 417 418 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL, 419 ACC_CODEC_CNTL_WRITE_CMD | 420 ACC_CODEC_CNTL_CMD_NEW | 421 ACC_CODEC_REG2ADDR(reg) | 422 (val & ACC_CODEC_CNTL_CMD_DATA_MASK)); 423 424 if (gcscaudio_wait_ready_codec(sc, "codec write timeout\n")) 425 return 1; 426 427 #ifdef GCSCAUDIO_CODEC_DEBUG 428 aprint_error_dev(&sc->sc_dev, "codec write: reg=0x%02x, val=0x%04x\n", 429 reg, val); 430 #endif 431 432 return 0; 433 } 434 435 static int 436 gcscaudio_read_codec(void *arg, uint8_t reg, uint16_t *val) 437 { 438 struct gcscaudio_softc *sc; 439 uint32_t v; 440 int i; 441 442 sc = (struct gcscaudio_softc *)arg; 443 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_CNTL, 444 ACC_CODEC_CNTL_READ_CMD | ACC_CODEC_CNTL_CMD_NEW | 445 ACC_CODEC_REG2ADDR(reg)); 446 447 if (gcscaudio_wait_ready_codec(sc, "codec write timeout for reading")) 448 return 1; 449 450 #define GCSCAUDIO_READ_CODEC_TIMEOUT 50 451 for (i = GCSCAUDIO_READ_CODEC_TIMEOUT; i >= 0; i--) { 452 v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ACC_CODEC_STATUS); 453 if ((v & ACC_CODEC_STATUS_STS_NEW) && 454 (ACC_CODEC_ADDR2REG(v) == reg)) 455 break; 456 457 delay(10); 458 } 459 460 if (i < 0) { 461 aprint_error_dev(&sc->sc_dev, "codec read timeout\n"); 462 return 1; 463 } 464 465 #ifdef GCSCAUDIO_CODEC_DEBUG 466 aprint_error_dev(&sc->sc_dev, "codec read: reg=0x%02x, val=0x%04x\n", 467 reg, v & ACC_CODEC_STATUS_STS_DATA_MASK); 468 #endif 469 470 *val = v; 471 return 0; 472 } 473 474 static int 475 gcscaudio_open(void *arg, int flags) 476 { 477 struct gcscaudio_softc *sc; 478 479 sc = (struct gcscaudio_softc *)arg; 480 sc->codec_if->vtbl->lock(sc->codec_if); 481 return 0; 482 } 483 484 static void 485 gcscaudio_close(void *arg) 486 { 487 struct gcscaudio_softc *sc; 488 489 sc = (struct gcscaudio_softc *)arg; 490 sc->codec_if->vtbl->unlock(sc->codec_if); 491 } 492 493 static int 494 gcscaudio_query_encoding(void *arg, struct audio_encoding *fp) 495 { 496 struct gcscaudio_softc *sc; 497 498 sc = (struct gcscaudio_softc *)arg; 499 return auconv_query_encoding(sc->sc_encodings, fp); 500 } 501 502 static int 503 gcscaudio_set_params_ch(struct gcscaudio_softc *sc, 504 struct gcscaudio_softc_ch *ch, int mode, 505 audio_params_t *p, stream_filter_list_t *fil) 506 { 507 int error, idx; 508 509 if ((p->sample_rate < 8000) || (p->sample_rate > 48000)) 510 return EINVAL; 511 512 if (p->precision != 8 && p->precision != 16) 513 return EINVAL; 514 515 if ((idx = auconv_set_converter(sc->sc_formats, sc->sc_nformats, 516 mode, p, TRUE, fil)) < 0) 517 return EINVAL; 518 519 if (fil->req_size > 0) 520 p = &fil->filters[0].param; 521 522 if (mode == AUMODE_PLAY) { 523 if (!AC97_IS_FIXED_RATE(sc->codec_if)) { 524 /* setup rate of DAC/ADC */ 525 if ((error = sc->codec_if->vtbl->set_rate(sc->codec_if, 526 AC97_REG_PCM_LR_ADC_RATE, &p->sample_rate)) != 0) 527 return error; 528 529 /* additional rate of DAC for Surround */ 530 if ((p->channels >= 4) && 531 (error = sc->codec_if->vtbl->set_rate(sc->codec_if, 532 AC97_REG_PCM_SURR_DAC_RATE, &p->sample_rate)) != 0) 533 return error; 534 535 /* additional rate of DAC for LowFrequencyEffect */ 536 if ((p->channels == 6) && 537 (error = sc->codec_if->vtbl->set_rate(sc->codec_if, 538 AC97_REG_PCM_LFE_DAC_RATE, &p->sample_rate)) != 0) 539 return error; 540 } 541 } 542 543 if (mode == AUMODE_RECORD) { 544 if (!AC97_IS_FIXED_RATE(sc->codec_if)) { 545 /* setup rate of DAC/ADC */ 546 if ((error = sc->codec_if->vtbl->set_rate(sc->codec_if, 547 AC97_REG_PCM_FRONT_DAC_RATE, &p->sample_rate)) != 0) 548 return error; 549 } 550 } 551 552 ch->ch_params = *p; 553 return 0; 554 } 555 556 static int 557 gcscaudio_set_params(void *arg, int setmode, int usemode, 558 audio_params_t *play, audio_params_t *rec, 559 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 560 { 561 struct gcscaudio_softc *sc; 562 int error; 563 564 sc = (struct gcscaudio_softc *)arg; 565 566 if (setmode & AUMODE_PLAY) { 567 if ((error = gcscaudio_set_params_ch(sc, &sc->sc_play, 568 AUMODE_PLAY, play, pfil)) != 0) 569 return error; 570 } 571 if (setmode & AUMODE_RECORD) { 572 if ((error = gcscaudio_set_params_ch(sc, &sc->sc_rec, 573 AUMODE_RECORD, rec, rfil)) != 0) 574 return error; 575 } 576 577 return 0; 578 } 579 580 static int 581 gcscaudio_round_blocksize(void *arg, int blk, int mode, 582 const audio_params_t *param) 583 { 584 blk &= -4; 585 if (blk > GCSCAUDIO_PRD_SIZE_MAX) 586 blk = GCSCAUDIO_PRD_SIZE_MAX; 587 588 return blk; 589 } 590 591 static int 592 gcscaudio_halt_output(void *arg) 593 { 594 struct gcscaudio_softc *sc; 595 596 sc = (struct gcscaudio_softc *)arg; 597 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, 598 ACC_BMx_CMD_BM_CTL_DISABLE); 599 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM4_CMD, 600 ACC_BMx_CMD_BM_CTL_DISABLE); 601 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD, 602 ACC_BMx_CMD_BM_CTL_DISABLE); 603 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM7_CMD, 604 ACC_BMx_CMD_BM_CTL_DISABLE); 605 sc->sc_play.ch_intr = NULL; 606 607 /* channel splitter */ 608 sc->sc_mch_splitter = NULL; 609 if (sc->sc_mch_split_buf) 610 gcscaudio_free(sc, sc->sc_mch_split_buf, M_DEVBUF); 611 sc->sc_mch_split_buf = NULL; 612 613 return 0; 614 } 615 616 static int 617 gcscaudio_halt_input(void *arg) 618 { 619 struct gcscaudio_softc *sc; 620 621 sc = (struct gcscaudio_softc *)arg; 622 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM1_CMD, 623 ACC_BMx_CMD_BM_CTL_DISABLE); 624 sc->sc_rec.ch_intr = NULL; 625 return 0; 626 } 627 628 static int 629 gcscaudio_getdev(void *addr, struct audio_device *retp) 630 { 631 *retp = gcscaudio_device; 632 return 0; 633 } 634 635 static int 636 gcscaudio_set_port(void *addr, mixer_ctrl_t *cp) 637 { 638 struct gcscaudio_softc *sc; 639 640 sc = addr; 641 return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp); 642 } 643 644 static int 645 gcscaudio_get_port(void *addr, mixer_ctrl_t *cp) 646 { 647 struct gcscaudio_softc *sc; 648 649 sc = addr; 650 return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp); 651 } 652 653 static int 654 gcscaudio_query_devinfo(void *addr, mixer_devinfo_t *dip) 655 { 656 struct gcscaudio_softc *sc; 657 658 sc = addr; 659 return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip); 660 } 661 662 static void * 663 gcscaudio_malloc(void *arg, int direction, size_t size, 664 struct malloc_type *pool, int flags) 665 { 666 struct gcscaudio_softc *sc; 667 struct gcscaudio_dma *p; 668 int error; 669 670 sc = (struct gcscaudio_softc *)arg; 671 672 p = malloc(sizeof(*p), pool, flags); 673 if (p == NULL) 674 return NULL; 675 p->size = size; 676 677 error = gcscaudio_allocate_dma(sc, size, &p->addr, 678 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), &p->nseg, 679 BUS_DMA_NOWAIT, &p->map); 680 681 if (error) { 682 free(p, pool); 683 return NULL; 684 } 685 686 LIST_INSERT_HEAD(&sc->sc_dmalist, p, list); 687 return p->addr; 688 } 689 690 static void 691 gcscaudio_free(void *arg, void *ptr, struct malloc_type *pool) 692 { 693 struct gcscaudio_softc *sc; 694 struct gcscaudio_dma *p; 695 696 sc = (struct gcscaudio_softc *)arg; 697 698 LIST_FOREACH(p, &sc->sc_dmalist, list) { 699 if (p->addr == ptr) { 700 bus_dmamap_unload(sc->sc_dmat, p->map); 701 bus_dmamap_destroy(sc->sc_dmat, p->map); 702 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 703 bus_dmamem_free(sc->sc_dmat, p->segs, p->nseg); 704 705 LIST_REMOVE(p, list); 706 free(p, pool); 707 break; 708 } 709 } 710 } 711 712 static paddr_t 713 gcscaudio_mappage(void *arg, void *mem, off_t off, int prot) 714 { 715 struct gcscaudio_softc *sc; 716 struct gcscaudio_dma *p; 717 718 if (off < 0) 719 return -1; 720 721 sc = (struct gcscaudio_softc *)arg; 722 LIST_FOREACH(p, &sc->sc_dmalist, list) { 723 if (p->addr == mem) { 724 return bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nseg, 725 off, prot, BUS_DMA_WAITOK); 726 } 727 } 728 729 return -1; 730 } 731 732 static size_t 733 gcscaudio_round_buffersize(void *addr, int direction, size_t size) 734 { 735 if (size > GCSCAUDIO_BUFSIZE_MAX) 736 size = GCSCAUDIO_BUFSIZE_MAX; 737 738 return size; 739 } 740 741 static int 742 gcscaudio_get_props(void *addr) 743 { 744 struct gcscaudio_softc *sc; 745 int props; 746 747 sc = (struct gcscaudio_softc *)addr; 748 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 749 /* 750 * Even if the codec is fixed-rate, set_param() succeeds for any sample 751 * rate because of aurateconv. Applications can't know what rate the 752 * device can process in the case of mmap(). 753 */ 754 if (!AC97_IS_FIXED_RATE(sc->codec_if)) 755 props |= AUDIO_PROP_MMAP; 756 return props; 757 } 758 759 static int 760 build_prdtables(struct gcscaudio_softc *sc, int prdidx, 761 void *addr, size_t size, int blksize, int blklen, int blkoff) 762 { 763 struct gcscaudio_dma *p; 764 struct acc_prd *prdp; 765 bus_addr_t paddr; 766 int i; 767 768 /* get physical address of start */ 769 paddr = (bus_addr_t)0; 770 LIST_FOREACH(p, &sc->sc_dmalist, list) { 771 if (p->addr == addr) { 772 paddr = p->map->dm_segs[0].ds_addr; 773 break; 774 } 775 } 776 if (!paddr) { 777 aprint_error_dev(&sc->sc_dev, 778 "bad addr %p\n", addr); 779 return EINVAL; 780 } 781 782 #define PRDADDR(prdidx,idx) \ 783 (sc->sc_prd.p_prdmap->dm_segs[0].ds_addr) + sizeof(struct acc_prd) * \ 784 (((prdidx) * GCSCAUDIO_NPRDTABLE) + (idx)) 785 786 /* 787 * build PRD table 788 * prdtbl[] = <PRD0>, <PRD1>, <PRD2>, ..., <PRDn>, <jmp to PRD0> 789 */ 790 prdp = sc->sc_prd.p_prdtables->prdtbl[prdidx]; 791 for (i = 0; size > 0; size -= blksize, i++) { 792 prdp[i].address = paddr + blksize * i + blkoff; 793 prdp[i].ctrlsize = 794 (size < blklen ? size : blklen) | ACC_BMx_PRD_CTRL_EOP; 795 } 796 prdp[i].address = PRDADDR(prdidx, 0); 797 prdp[i].ctrlsize = ACC_BMx_PRD_CTRL_JMP; 798 799 bus_dmamap_sync(sc->sc_dmat, sc->sc_prd.p_prdmap, 0, 800 sizeof(struct acc_prd) * i, BUS_DMASYNC_PREWRITE); 801 802 return 0; 803 } 804 805 static void 806 split_buffer_4ch(void *dst, void *src, int size, int blksize) 807 { 808 int left, i; 809 uint16_t *s, *d; 810 811 /* 812 * src[blk0]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,.... 813 * src[blk1]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,.... 814 * src[blk2]: L,R,SL,SR,L,R,SL,SR,L,R,SL,SR,.... 815 * : 816 * 817 * rearrange to 818 * 819 * src[blk0]: L,R,L,R,L,R,L,R,.. 820 * src[blk1]: L,R,L,R,L,R,L,R,.. 821 * src[blk2]: L,R,L,R,L,R,L,R,.. 822 * : 823 * dst[blk0]: SL,SR,SL,SR,SL,SR,SL,SR,.. 824 * dst[blk1]: SL,SR,SL,SR,SL,SR,SL,SR,.. 825 * dst[blk2]: SL,SR,SL,SR,SL,SR,SL,SR,.. 826 * : 827 */ 828 for (left = size; left > 0; left -= blksize) { 829 s = (uint16_t *)src; 830 d = (uint16_t *)dst; 831 for (i = 0; i < blksize / sizeof(uint16_t) / 4; i++) { 832 /* L,R,SL,SR -> SL,SR */ 833 s++; 834 s++; 835 *d++ = *s++; 836 *d++ = *s++; 837 } 838 839 s = (uint16_t *)src; 840 d = (uint16_t *)src; 841 for (i = 0; i < blksize / sizeof(uint16_t) / 2 / 2; i++) { 842 /* L,R,SL,SR -> L,R */ 843 *d++ = *s++; 844 *d++ = *s++; 845 s++; 846 s++; 847 } 848 849 src = (char *)src + blksize; 850 dst = (char *)dst + blksize; 851 } 852 } 853 854 static void 855 split_buffer_6ch(void *dst, void *src, int size, int blksize) 856 { 857 int left, i; 858 uint16_t *s, *d, *dc, *dl; 859 860 /* 861 * by default, treat as WAV style 5.1ch order 862 * 5.1ch(WAV): L R C LFE SL SR 863 * 5.1ch(AAC): C L R SL SR LFE 864 * : 865 */ 866 867 /* 868 * src[blk0]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,... 869 * src[blk1]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,... 870 * src[blk2]: L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,... 871 * : 872 * src[N-1] : L,R,C,LFE,SL,SR,L,R,C,LFE,SL,SR,... 873 * 874 * rearrange to 875 * 876 * src[blk0]: L,R,L,R,.. 877 * src[blk1]: L,R,L,R,.. 878 * src[blk2]: L,R,L,R,.. 879 * : 880 * 881 * dst[blk0]: SL,SR,SL,SR,.. 882 * dst[blk1]: SL,SR,SL,SR,.. 883 * dst[blk2]: SL,SR,SL,SR,.. 884 * : 885 * 886 * dst[N/2+0]: C,C,C,.. 887 * dst[N/2+1]: C,C,C,.. 888 * : 889 * 890 * dst[N/2+N/4+0]: LFE,LFE,LFE,.. 891 * dst[N/2+N/4+1]: LFE,LFE,LFE,.. 892 * : 893 */ 894 895 for (left = size; left > 0; left -= blksize) { 896 s = (uint16_t *)src; 897 d = (uint16_t *)dst; 898 dc = (uint16_t *)((char *)dst + blksize / 2); 899 dl = (uint16_t *)((char *)dst + blksize / 2 + blksize / 4); 900 for (i = 0; i < blksize / sizeof(uint16_t) / 6; i++) { 901 #ifdef GCSCAUDIO_5_1CH_AAC_ORDER 902 /* 903 * AAC: [C,L,R,SL,SR,LFE] 904 * => [SL,SR] 905 * => [C] 906 * => [LFE] 907 */ 908 *dc++ = s[0]; /* C */ 909 *dl++ = s[5]; /* LFE */ 910 *d++ = s[3]; /* SL */ 911 *d++ = s[4]; /* SR */ 912 #else 913 /* 914 * WAV: [L,R,C,LFE,SL,SR] 915 * => [SL,SR] 916 * => [C] 917 * => [LFE] 918 */ 919 *dc++ = s[2]; /* C */ 920 *dl++ = s[3]; /* LFE */ 921 *d++ = s[4]; /* SL */ 922 *d++ = s[5]; /* SR */ 923 #endif 924 s += 6; 925 } 926 927 s = (uint16_t *)src; 928 d = (uint16_t *)src; 929 for (i = 0; i < blksize / sizeof(uint16_t) / 2 / 2; i++) { 930 #ifdef GCSCAUDIO_5_1CH_AAC_ORDER 931 /* AAC: [C,L,R,SL,SR,LFE] => [L,R] */ 932 *d++ = s[1]; 933 *d++ = s[2]; 934 #else 935 /* WAV: [L,R,C,LFE,SL,SR] => [L,R] */ 936 *d++ = s[0]; 937 *d++ = s[1]; 938 #endif 939 s += 6; 940 } 941 942 src = (char *)src + blksize; 943 dst = (char *)dst + blksize; 944 } 945 } 946 947 static void 948 channel_splitter(struct gcscaudio_softc *sc) 949 { 950 int splitsize, left; 951 void *src, *dst; 952 953 if (sc->sc_mch_splitter == NULL) 954 return; 955 956 left = sc->sc_mch_split_size - sc->sc_mch_split_off; 957 splitsize = sc->sc_mch_split_blksize; 958 if (left < splitsize) 959 splitsize = left; 960 961 src = (char *)sc->sc_mch_split_start + sc->sc_mch_split_off; 962 dst = (char *)sc->sc_mch_split_buf + sc->sc_mch_split_off; 963 964 sc->sc_mch_splitter(dst, src, splitsize, sc->sc_mch_split_blksize); 965 966 sc->sc_mch_split_off += sc->sc_mch_split_blksize; 967 if (sc->sc_mch_split_off >= sc->sc_mch_split_size) 968 sc->sc_mch_split_off = 0; 969 } 970 971 static int 972 gcscaudio_trigger_output(void *addr, void *start, void *end, int blksize, 973 void (*intr)(void *), void *arg, 974 const audio_params_t *param) 975 { 976 struct gcscaudio_softc *sc; 977 size_t size; 978 979 sc = (struct gcscaudio_softc *)addr; 980 sc->sc_play.ch_intr = intr; 981 sc->sc_play.ch_intr_arg = arg; 982 size = (char *)end - (char *)start; 983 984 switch (sc->sc_play.ch_params.channels) { 985 case 2: 986 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize, 987 blksize, 0)) 988 return EINVAL; 989 990 if (!AC97_IS_4CH(sc->codec_if)) { 991 /* 992 * output 2ch PCM to FRONT.LR(BM0) 993 * 994 * 2ch: L,R,L,R,L,R,L,R,... => BM0: L,R,L,R,L,R,L,R,... 995 * 996 */ 997 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD, 998 PRDADDR(PRD_TABLE_FRONT, 0)); 999 1000 /* start DMA transfer */ 1001 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, 1002 ACC_BMx_CMD_WRITE | 1003 ACC_BMx_CMD_BYTE_ORD_EL | 1004 ACC_BMx_CMD_BM_CTL_ENABLE); 1005 } else { 1006 /* 1007 * output same PCM to FRONT.LR(BM0) and SURROUND.LR(BM6). 1008 * CENTER(BM4) and LFE(BM7) doesn't sound. 1009 * 1010 * 2ch: L,R,L,R,L,R,L,R,... => BM0: L,R,L,R,L,R,L,R,... 1011 * BM6: (same of BM0) 1012 * BM4: none 1013 * BM7: none 1014 */ 1015 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD, 1016 PRDADDR(PRD_TABLE_FRONT, 0)); 1017 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD, 1018 PRDADDR(PRD_TABLE_FRONT, 0)); 1019 1020 /* start DMA transfer */ 1021 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, 1022 ACC_BMx_CMD_WRITE | 1023 ACC_BMx_CMD_BYTE_ORD_EL | 1024 ACC_BMx_CMD_BM_CTL_ENABLE); 1025 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD, 1026 ACC_BMx_CMD_WRITE | 1027 ACC_BMx_CMD_BYTE_ORD_EL | 1028 ACC_BMx_CMD_BM_CTL_ENABLE); 1029 } 1030 break; 1031 case 4: 1032 /* 1033 * output 4ch PCM split to FRONT.LR(BM0) and SURROUND.LR(BM6). 1034 * CENTER(BM4) and LFE(BM7) doesn't sound. 1035 * 1036 * rearrange ordered channel to continuous per channel 1037 * 1038 * 4ch: L,R,SL,SR,L,R,SL,SR,... => BM0: L,R,L,R,... 1039 * BM6: SL,SR,SL,SR,... 1040 * BM4: none 1041 * BM7: none 1042 */ 1043 if (sc->sc_mch_split_buf) 1044 gcscaudio_free(sc, sc->sc_mch_split_buf, M_DEVBUF); 1045 1046 if ((sc->sc_mch_split_buf = gcscaudio_malloc(sc, AUMODE_PLAY, 1047 size, M_DEVBUF, M_WAITOK)) == NULL) 1048 return ENOMEM; 1049 1050 /* 1051 * 1st and 2nd blocks are split immediately. 1052 * Other blocks will be split synchronous with intr. 1053 */ 1054 split_buffer_4ch(sc->sc_mch_split_buf, start, blksize * 2, 1055 blksize); 1056 1057 sc->sc_mch_split_start = start; 1058 sc->sc_mch_split_size = size; 1059 sc->sc_mch_split_blksize = blksize; 1060 sc->sc_mch_split_off = (blksize * 2) % size; 1061 sc->sc_mch_splitter = split_buffer_4ch; /* split function */ 1062 1063 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize, 1064 blksize / 2, 0)) 1065 return EINVAL; 1066 if (build_prdtables(sc, PRD_TABLE_SURR, sc->sc_mch_split_buf, 1067 size, blksize, blksize / 2, 0)) 1068 return EINVAL; 1069 1070 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD, 1071 PRDADDR(PRD_TABLE_FRONT, 0)); 1072 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD, 1073 PRDADDR(PRD_TABLE_SURR, 0)); 1074 1075 /* start DMA transfer */ 1076 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, 1077 ACC_BMx_CMD_WRITE | 1078 ACC_BMx_CMD_BYTE_ORD_EL | 1079 ACC_BMx_CMD_BM_CTL_ENABLE); 1080 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD, 1081 ACC_BMx_CMD_WRITE | 1082 ACC_BMx_CMD_BYTE_ORD_EL | 1083 ACC_BMx_CMD_BM_CTL_ENABLE); 1084 break; 1085 case 6: 1086 /* 1087 * output 6ch PCM split to 1088 * FRONT.LR(BM0), SURROUND.LR(BM6), CENTER(BM4) and LFE(BM7) 1089 * 1090 * rearrange ordered channel to continuous per channel 1091 * 1092 * 5.1ch: L,R,C,LFE,SL,SR,... => BM0: L,R,... 1093 * BM4: C,... 1094 * BM6: SL,SR,... 1095 * BM7: LFE,... 1096 * 1097 */ 1098 if (sc->sc_mch_split_buf) 1099 gcscaudio_free(sc, sc->sc_mch_split_buf, M_DEVBUF); 1100 1101 if ((sc->sc_mch_split_buf = gcscaudio_malloc(sc, AUMODE_PLAY, 1102 size, M_DEVBUF, M_WAITOK)) == NULL) 1103 return ENOMEM; 1104 1105 /* 1106 * 1st and 2nd blocks are split immediately. 1107 * Other block will be split synchronous with intr. 1108 */ 1109 split_buffer_6ch(sc->sc_mch_split_buf, start, blksize * 2, 1110 blksize); 1111 1112 sc->sc_mch_split_start = start; 1113 sc->sc_mch_split_size = size; 1114 sc->sc_mch_split_blksize = blksize; 1115 sc->sc_mch_split_off = (blksize * 2) % size; 1116 sc->sc_mch_splitter = split_buffer_6ch; /* split function */ 1117 1118 if (build_prdtables(sc, PRD_TABLE_FRONT, start, size, blksize, 1119 blksize / 3, 0)) 1120 return EINVAL; 1121 if (build_prdtables(sc, PRD_TABLE_CENTER, sc->sc_mch_split_buf, 1122 size, blksize, blksize / 3, blksize / 2)) 1123 return EINVAL; 1124 if (build_prdtables(sc, PRD_TABLE_SURR, sc->sc_mch_split_buf, 1125 size, blksize, blksize / 3, 0)) 1126 return EINVAL; 1127 if (build_prdtables(sc, PRD_TABLE_LFE, sc->sc_mch_split_buf, 1128 size, blksize, blksize / 3, blksize / 2 + blksize / 4)) 1129 return EINVAL; 1130 1131 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM0_PRD, 1132 PRDADDR(PRD_TABLE_FRONT, 0)); 1133 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM4_PRD, 1134 PRDADDR(PRD_TABLE_CENTER, 0)); 1135 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM6_PRD, 1136 PRDADDR(PRD_TABLE_SURR, 0)); 1137 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM7_PRD, 1138 PRDADDR(PRD_TABLE_LFE, 0)); 1139 1140 /* start DMA transfer */ 1141 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_CMD, 1142 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL | 1143 ACC_BMx_CMD_BM_CTL_ENABLE); 1144 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM4_CMD, 1145 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL | 1146 ACC_BMx_CMD_BM_CTL_ENABLE); 1147 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_CMD, 1148 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL | 1149 ACC_BMx_CMD_BM_CTL_ENABLE); 1150 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM7_CMD, 1151 ACC_BMx_CMD_WRITE | ACC_BMx_CMD_BYTE_ORD_EL | 1152 ACC_BMx_CMD_BM_CTL_ENABLE); 1153 break; 1154 } 1155 1156 return 0; 1157 } 1158 1159 static int 1160 gcscaudio_trigger_input(void *addr, void *start, void *end, int blksize, 1161 void (*intr)(void *), void *arg, 1162 const audio_params_t *param) 1163 { 1164 struct gcscaudio_softc *sc; 1165 size_t size; 1166 1167 sc = (struct gcscaudio_softc *)addr; 1168 sc->sc_rec.ch_intr = intr; 1169 sc->sc_rec.ch_intr_arg = arg; 1170 size = (char *)end - (char *)start; 1171 1172 if (build_prdtables(sc, PRD_TABLE_REC, start, size, blksize, blksize, 0)) 1173 return EINVAL; 1174 1175 bus_space_write_4(sc->sc_iot, sc->sc_ioh, ACC_BM1_PRD, 1176 PRDADDR(PRD_TABLE_REC, 0)); 1177 1178 /* start transfer */ 1179 bus_space_write_1(sc->sc_iot, sc->sc_ioh, ACC_BM1_CMD, 1180 ACC_BMx_CMD_READ | 1181 ACC_BMx_CMD_BYTE_ORD_EL | 1182 ACC_BMx_CMD_BM_CTL_ENABLE); 1183 1184 return 0; 1185 } 1186 1187 static int 1188 gcscaudio_intr(void *arg) 1189 { 1190 struct gcscaudio_softc *sc; 1191 uint16_t intr; 1192 uint8_t bmstat; 1193 int nintr; 1194 1195 nintr = 0; 1196 sc = (struct gcscaudio_softc *)arg; 1197 intr = bus_space_read_2(sc->sc_iot, sc->sc_ioh, ACC_IRQ_STATUS); 1198 if (intr == 0) 1199 return 0; 1200 1201 /* Front output */ 1202 if (intr & ACC_IRQ_STATUS_BM0_IRQ_STS) { 1203 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM0_STATUS); 1204 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR) 1205 aprint_normal_dev(&sc->sc_dev, "BM0: Bus Master Error\n"); 1206 if (!(bmstat & ACC_BMx_STATUS_EOP)) 1207 aprint_normal_dev(&sc->sc_dev, "BM0: NO End of Page?\n"); 1208 1209 if (sc->sc_play.ch_intr) { 1210 sc->sc_play.ch_intr(sc->sc_play.ch_intr_arg); 1211 channel_splitter(sc); 1212 } 1213 nintr++; 1214 } 1215 1216 /* Center output */ 1217 if (intr & ACC_IRQ_STATUS_BM4_IRQ_STS) { 1218 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM4_STATUS); 1219 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR) 1220 aprint_normal_dev(&sc->sc_dev, "BM4: Bus Master Error\n"); 1221 if (!(bmstat & ACC_BMx_STATUS_EOP)) 1222 aprint_normal_dev(&sc->sc_dev, "BM4: NO End of Page?\n"); 1223 1224 nintr++; 1225 } 1226 1227 /* Surround output */ 1228 if (intr & ACC_IRQ_STATUS_BM6_IRQ_STS) { 1229 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM6_STATUS); 1230 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR) 1231 aprint_normal_dev(&sc->sc_dev, "BM6: Bus Master Error\n"); 1232 if (!(bmstat & ACC_BMx_STATUS_EOP)) 1233 aprint_normal_dev(&sc->sc_dev, "BM6: NO End of Page?\n"); 1234 1235 nintr++; 1236 } 1237 1238 /* LowFrequencyEffect output */ 1239 if (intr & ACC_IRQ_STATUS_BM7_IRQ_STS) { 1240 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM7_STATUS); 1241 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR) 1242 aprint_normal_dev(&sc->sc_dev, "BM7: Bus Master Error\n"); 1243 if (!(bmstat & ACC_BMx_STATUS_EOP)) 1244 aprint_normal_dev(&sc->sc_dev, "BM7: NO End of Page?\n"); 1245 1246 nintr++; 1247 } 1248 1249 /* record */ 1250 if (intr & ACC_IRQ_STATUS_BM1_IRQ_STS) { 1251 bmstat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ACC_BM1_STATUS); 1252 if (bmstat & ACC_BMx_STATUS_BM_EOP_ERR) 1253 aprint_normal_dev(&sc->sc_dev, "BM1: Bus Master Error\n"); 1254 if (!(bmstat & ACC_BMx_STATUS_EOP)) 1255 aprint_normal_dev(&sc->sc_dev, "BM1: NO End of Page?\n"); 1256 1257 if (sc->sc_rec.ch_intr) { 1258 sc->sc_rec.ch_intr(sc->sc_rec.ch_intr_arg); 1259 } 1260 nintr++; 1261 } 1262 1263 #ifdef GCSCAUDIO_DEBUG 1264 if (intr & ACC_IRQ_STATUS_IRQ_STS) 1265 aprint_normal_dev(&sc->sc_dev, "Codec GPIO IRQ Status\n"); 1266 if (intr & ACC_IRQ_STATUS_WU_IRQ_STS) 1267 aprint_normal_dev(&sc->sc_dev, "Codec GPIO Wakeup IRQ Status\n"); 1268 if (intr & ACC_IRQ_STATUS_BM2_IRQ_STS) 1269 aprint_normal_dev(&sc->sc_dev, "Audio Bus Master 2 IRQ Status\n"); 1270 if (intr & ACC_IRQ_STATUS_BM3_IRQ_STS) 1271 aprint_normal_dev(&sc->sc_dev, "Audio Bus Master 3 IRQ Status\n"); 1272 if (intr & ACC_IRQ_STATUS_BM5_IRQ_STS) 1273 aprint_normal_dev(&sc->sc_dev, "Audio Bus Master 5 IRQ Status\n"); 1274 #endif 1275 1276 return nintr ? 1 : 0; 1277 } 1278 1279 static bool 1280 gcscaudio_resume(device_t dv, const pmf_qual_t *qual) 1281 { 1282 struct gcscaudio_softc *sc = device_private(dv); 1283 1284 gcscaudio_reset_codec(sc); 1285 DELAY(1000); 1286 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1287 1288 return true; 1289 } 1290 1291 static int 1292 gcscaudio_allocate_dma(struct gcscaudio_softc *sc, size_t size, void **addrp, 1293 bus_dma_segment_t *seglist, int nseg, int *rsegp, 1294 int flags, bus_dmamap_t *mapp) 1295 { 1296 int error; 1297 1298 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, seglist, 1299 nseg, rsegp, flags)) != 0) { 1300 aprint_error_dev(&sc->sc_dev, 1301 "unable to allocate DMA buffer, error=%d\n", error); 1302 goto fail_alloc; 1303 } 1304 1305 if ((error = bus_dmamem_map(sc->sc_dmat, seglist, nseg, size, addrp, 1306 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 1307 aprint_error_dev(&sc->sc_dev, 1308 "unable to map DMA buffer, error=%d\n", 1309 error); 1310 goto fail_map; 1311 } 1312 1313 if ((error = bus_dmamap_create(sc->sc_dmat, size, nseg, size, 0, 1314 BUS_DMA_NOWAIT, mapp)) != 0) { 1315 aprint_error_dev(&sc->sc_dev, 1316 "unable to create DMA map, error=%d\n", error); 1317 goto fail_create; 1318 } 1319 1320 if ((error = bus_dmamap_load(sc->sc_dmat, *mapp, *addrp, size, NULL, 1321 BUS_DMA_NOWAIT)) != 0) { 1322 aprint_error_dev(&sc->sc_dev, 1323 "unable to load DMA map, error=%d\n", error); 1324 goto fail_load; 1325 } 1326 1327 return 0; 1328 1329 fail_load: 1330 bus_dmamap_destroy(sc->sc_dmat, *mapp); 1331 fail_create: 1332 bus_dmamem_unmap(sc->sc_dmat, *addrp, size); 1333 fail_map: 1334 bus_dmamem_free(sc->sc_dmat, seglist, nseg); 1335 fail_alloc: 1336 return error; 1337 } 1338