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