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