1 /* $NetBSD: auacer.c,v 1.31 2012/10/27 17:18:28 chs Exp $ */ 2 3 /*- 4 * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Acer Labs M5455 audio driver 34 * 35 * Acer provides data sheets after signing an NDA, so this is guess work. 36 * The chip behaves somewhat like the Intel i8x0, so this driver 37 * is loosely based on the auich driver. Additional information taken from 38 * the ALSA intel8x0.c driver (which handles M5455 as well). 39 * 40 * As an historical note one can observe that the auich driver borrows 41 * lot from the first NetBSD PCI audio driver, the eap driver. But this 42 * is not attributed anywhere. 43 */ 44 45 46 #include <sys/cdefs.h> 47 __KERNEL_RCSID(0, "$NetBSD: auacer.c,v 1.31 2012/10/27 17:18:28 chs Exp $"); 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/kmem.h> 53 #include <sys/device.h> 54 #include <sys/fcntl.h> 55 #include <sys/proc.h> 56 57 #include <dev/pci/pcidevs.h> 58 #include <dev/pci/pcivar.h> 59 #include <dev/pci/auacerreg.h> 60 61 #include <sys/audioio.h> 62 #include <dev/audio_if.h> 63 #include <dev/mulaw.h> 64 #include <dev/auconv.h> 65 66 #include <sys/bus.h> 67 68 #include <dev/ic/ac97reg.h> 69 #include <dev/ic/ac97var.h> 70 71 struct auacer_dma { 72 bus_dmamap_t map; 73 void *addr; 74 bus_dma_segment_t segs[1]; 75 int nsegs; 76 size_t size; 77 struct auacer_dma *next; 78 }; 79 80 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 81 #define KERNADDR(p) ((void *)((p)->addr)) 82 83 struct auacer_cdata { 84 struct auacer_dmalist ic_dmalist_pcmo[ALI_DMALIST_MAX]; 85 }; 86 87 struct auacer_chan { 88 uint32_t ptr; 89 uint32_t start, p, end; 90 uint32_t blksize, fifoe; 91 uint32_t ack; 92 uint32_t port; 93 struct auacer_dmalist *dmalist; 94 void (*intr)(void *); 95 void *arg; 96 }; 97 98 struct auacer_softc { 99 device_t sc_dev; 100 void *sc_ih; 101 kmutex_t sc_lock; 102 kmutex_t sc_intr_lock; 103 104 audio_device_t sc_audev; 105 106 bus_space_tag_t iot; 107 bus_space_handle_t mix_ioh; 108 bus_space_handle_t aud_ioh; 109 bus_dma_tag_t dmat; 110 111 struct ac97_codec_if *codec_if; 112 struct ac97_host_if host_if; 113 114 /* DMA scatter-gather lists. */ 115 bus_dmamap_t sc_cddmamap; 116 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 117 118 struct auacer_cdata *sc_cdata; 119 120 struct auacer_chan sc_pcmo; 121 122 struct auacer_dma *sc_dmas; 123 124 pci_chipset_tag_t sc_pc; 125 pcitag_t sc_pt; 126 127 int sc_dmamap_flags; 128 129 #define AUACER_NFORMATS 3 130 struct audio_format sc_formats[AUACER_NFORMATS]; 131 struct audio_encoding_set *sc_encodings; 132 }; 133 134 #define READ1(sc, a) bus_space_read_1(sc->iot, sc->aud_ioh, a) 135 #define READ2(sc, a) bus_space_read_2(sc->iot, sc->aud_ioh, a) 136 #define READ4(sc, a) bus_space_read_4(sc->iot, sc->aud_ioh, a) 137 #define WRITE1(sc, a, v) bus_space_write_1(sc->iot, sc->aud_ioh, a, v) 138 #define WRITE2(sc, a, v) bus_space_write_2(sc->iot, sc->aud_ioh, a, v) 139 #define WRITE4(sc, a, v) bus_space_write_4(sc->iot, sc->aud_ioh, a, v) 140 141 /* Debug */ 142 #ifdef AUACER_DEBUG 143 #define DPRINTF(l,x) do { if (auacer_debug & (l)) printf x; } while(0) 144 int auacer_debug = 0; 145 #define ALI_DEBUG_CODECIO 0x0001 146 #define ALI_DEBUG_DMA 0x0002 147 #define ALI_DEBUG_INTR 0x0004 148 #define ALI_DEBUG_API 0x0008 149 #define ALI_DEBUG_MIXERAPI 0x0010 150 #else 151 #define DPRINTF(x,y) /* nothing */ 152 #endif 153 154 static int auacer_intr(void *); 155 156 static int auacer_query_encoding(void *, struct audio_encoding *); 157 static int auacer_set_params(void *, int, int, audio_params_t *, 158 audio_params_t *, stream_filter_list_t *, 159 stream_filter_list_t *); 160 static int auacer_round_blocksize(void *, int, int, 161 const audio_params_t *); 162 static int auacer_halt_output(void *); 163 static int auacer_halt_input(void *); 164 static int auacer_getdev(void *, struct audio_device *); 165 static int auacer_set_port(void *, mixer_ctrl_t *); 166 static int auacer_get_port(void *, mixer_ctrl_t *); 167 static int auacer_query_devinfo(void *, mixer_devinfo_t *); 168 static void *auacer_allocm(void *, int, size_t); 169 static void auacer_freem(void *, void *, size_t); 170 static size_t auacer_round_buffersize(void *, int, size_t); 171 static paddr_t auacer_mappage(void *, void *, off_t, int); 172 static int auacer_get_props(void *); 173 static int auacer_trigger_output(void *, void *, void *, int, 174 void (*)(void *), void *, 175 const audio_params_t *); 176 static int auacer_trigger_input(void *, void *, void *, int, 177 void (*)(void *), void *, 178 const audio_params_t *); 179 180 static int auacer_alloc_cdata(struct auacer_softc *); 181 182 static int auacer_allocmem(struct auacer_softc *, size_t, size_t, 183 struct auacer_dma *); 184 static int auacer_freemem(struct auacer_softc *, struct auacer_dma *); 185 static void auacer_get_locks(void *, kmutex_t **, kmutex_t **); 186 187 static bool auacer_resume(device_t, const pmf_qual_t *); 188 static int auacer_set_rate(struct auacer_softc *, int, u_int); 189 190 static void auacer_reset(struct auacer_softc *sc); 191 192 static struct audio_hw_if auacer_hw_if = { 193 NULL, /* open */ 194 NULL, /* close */ 195 NULL, /* drain */ 196 auacer_query_encoding, 197 auacer_set_params, 198 auacer_round_blocksize, 199 NULL, /* commit_setting */ 200 NULL, /* init_output */ 201 NULL, /* init_input */ 202 NULL, /* start_output */ 203 NULL, /* start_input */ 204 auacer_halt_output, 205 auacer_halt_input, 206 NULL, /* speaker_ctl */ 207 auacer_getdev, 208 NULL, /* getfd */ 209 auacer_set_port, 210 auacer_get_port, 211 auacer_query_devinfo, 212 auacer_allocm, 213 auacer_freem, 214 auacer_round_buffersize, 215 auacer_mappage, 216 auacer_get_props, 217 auacer_trigger_output, 218 auacer_trigger_input, 219 NULL, /* dev_ioctl */ 220 auacer_get_locks, 221 }; 222 223 #define AUACER_FORMATS_4CH 1 224 #define AUACER_FORMATS_6CH 2 225 static const struct audio_format auacer_formats[AUACER_NFORMATS] = { 226 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 227 2, AUFMT_STEREO, 0, {8000, 48000}}, 228 {NULL, AUMODE_PLAY, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 229 4, AUFMT_SURROUND4, 0, {8000, 48000}}, 230 {NULL, AUMODE_PLAY, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 231 6, AUFMT_DOLBY_5_1, 0, {8000, 48000}}, 232 }; 233 234 static int auacer_attach_codec(void *, struct ac97_codec_if *); 235 static int auacer_read_codec(void *, uint8_t, uint16_t *); 236 static int auacer_write_codec(void *, uint8_t, uint16_t); 237 static int auacer_reset_codec(void *); 238 239 static int 240 auacer_match(device_t parent, cfdata_t match, void *aux) 241 { 242 struct pci_attach_args *pa; 243 244 pa = (struct pci_attach_args *)aux; 245 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALI && 246 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALI_M5455) 247 return 1; 248 return 0; 249 } 250 251 static void 252 auacer_attach(device_t parent, device_t self, void *aux) 253 { 254 struct auacer_softc *sc; 255 struct pci_attach_args *pa; 256 pci_intr_handle_t ih; 257 bus_size_t aud_size; 258 pcireg_t v; 259 const char *intrstr; 260 int i; 261 262 sc = device_private(self); 263 sc->sc_dev = self; 264 pa = aux; 265 aprint_normal(": Acer Labs M5455 Audio controller\n"); 266 267 if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->iot, 268 &sc->aud_ioh, NULL, &aud_size)) { 269 aprint_error(": can't map i/o space\n"); 270 return; 271 } 272 273 sc->sc_pc = pa->pa_pc; 274 sc->sc_pt = pa->pa_tag; 275 sc->dmat = pa->pa_dmat; 276 277 sc->sc_dmamap_flags = BUS_DMA_COHERENT; /* XXX remove */ 278 279 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 280 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 281 282 /* enable bus mastering */ 283 v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 284 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 285 v | PCI_COMMAND_MASTER_ENABLE); 286 287 /* Map and establish the interrupt. */ 288 if (pci_intr_map(pa, &ih)) { 289 aprint_error_dev(sc->sc_dev, "can't map interrupt\n"); 290 mutex_destroy(&sc->sc_lock); 291 mutex_destroy(&sc->sc_intr_lock); 292 return; 293 } 294 intrstr = pci_intr_string(pa->pa_pc, ih); 295 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, 296 auacer_intr, sc); 297 if (sc->sc_ih == NULL) { 298 aprint_error_dev(sc->sc_dev, "can't establish interrupt"); 299 if (intrstr != NULL) 300 aprint_error(" at %s", intrstr); 301 aprint_error("\n"); 302 mutex_destroy(&sc->sc_lock); 303 mutex_destroy(&sc->sc_intr_lock); 304 return; 305 } 306 aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); 307 308 strlcpy(sc->sc_audev.name, "M5455 AC97", MAX_AUDIO_DEV_LEN); 309 snprintf(sc->sc_audev.version, MAX_AUDIO_DEV_LEN, 310 "0x%02x", PCI_REVISION(pa->pa_class)); 311 strlcpy(sc->sc_audev.config, device_xname(sc->sc_dev), MAX_AUDIO_DEV_LEN); 312 313 /* Set up DMA lists. */ 314 auacer_alloc_cdata(sc); 315 sc->sc_pcmo.dmalist = sc->sc_cdata->ic_dmalist_pcmo; 316 sc->sc_pcmo.ptr = 0; 317 sc->sc_pcmo.port = ALI_BASE_PO; 318 319 DPRINTF(ALI_DEBUG_DMA, ("auacer_attach: lists %p\n", 320 sc->sc_pcmo.dmalist)); 321 322 sc->host_if.arg = sc; 323 sc->host_if.attach = auacer_attach_codec; 324 sc->host_if.read = auacer_read_codec; 325 sc->host_if.write = auacer_write_codec; 326 sc->host_if.reset = auacer_reset_codec; 327 328 if (ac97_attach(&sc->host_if, self, &sc->sc_lock) != 0) { 329 mutex_destroy(&sc->sc_lock); 330 mutex_destroy(&sc->sc_intr_lock); 331 return; 332 } 333 334 /* setup audio_format */ 335 memcpy(sc->sc_formats, auacer_formats, sizeof(auacer_formats)); 336 mutex_enter(&sc->sc_lock); 337 if (!AC97_IS_4CH(sc->codec_if)) 338 AUFMT_INVALIDATE(&sc->sc_formats[AUACER_FORMATS_4CH]); 339 if (!AC97_IS_6CH(sc->codec_if)) 340 AUFMT_INVALIDATE(&sc->sc_formats[AUACER_FORMATS_6CH]); 341 if (AC97_IS_FIXED_RATE(sc->codec_if)) { 342 for (i = 0; i < AUACER_NFORMATS; i++) { 343 sc->sc_formats[i].frequency_type = 1; 344 sc->sc_formats[i].frequency[0] = 48000; 345 } 346 } 347 mutex_exit(&sc->sc_lock); 348 349 if (0 != auconv_create_encodings(sc->sc_formats, AUACER_NFORMATS, 350 &sc->sc_encodings)) { 351 mutex_destroy(&sc->sc_lock); 352 mutex_destroy(&sc->sc_intr_lock); 353 return; 354 } 355 356 mutex_enter(&sc->sc_lock); 357 mutex_spin_enter(&sc->sc_intr_lock); 358 auacer_reset(sc); 359 mutex_spin_exit(&sc->sc_intr_lock); 360 mutex_exit(&sc->sc_lock); 361 362 audio_attach_mi(&auacer_hw_if, sc, sc->sc_dev); 363 364 if (!pmf_device_register(self, NULL, auacer_resume)) 365 aprint_error_dev(self, "couldn't establish power handler\n"); 366 } 367 368 CFATTACH_DECL_NEW(auacer, sizeof(struct auacer_softc), 369 auacer_match, auacer_attach, NULL, NULL); 370 371 static int 372 auacer_ready_codec(struct auacer_softc *sc, int mask) 373 { 374 int count; 375 376 for (count = 0; count < 0x7f; count++) { 377 int val = READ1(sc, ALI_CSPSR); 378 if (val & mask) 379 return 0; 380 } 381 382 aprint_normal("auacer_ready_codec: AC97 codec ready timeout.\n"); 383 return EBUSY; 384 } 385 386 static int 387 auacer_sema_codec(struct auacer_softc *sc) 388 { 389 int ttime; 390 391 ttime = 100; 392 while (ttime-- && (READ4(sc, ALI_CAS) & ALI_CAS_SEM_BUSY)) 393 delay(1); 394 if (!ttime) 395 aprint_normal("auacer_sema_codec: timeout\n"); 396 return auacer_ready_codec(sc, ALI_CSPSR_CODEC_READY); 397 } 398 399 static int 400 auacer_read_codec(void *v, uint8_t reg, uint16_t *val) 401 { 402 struct auacer_softc *sc; 403 404 sc = v; 405 if (auacer_sema_codec(sc)) 406 return EIO; 407 408 reg |= ALI_CPR_ADDR_READ; 409 #if 0 410 if (ac97->num) 411 reg |= ALI_CPR_ADDR_SECONDARY; 412 #endif 413 WRITE2(sc, ALI_CPR_ADDR, reg); 414 if (auacer_ready_codec(sc, ALI_CSPSR_READ_OK)) 415 return EIO; 416 *val = READ2(sc, ALI_SPR); 417 418 DPRINTF(ALI_DEBUG_CODECIO, ("auacer_read_codec: reg=0x%x val=0x%x\n", 419 reg, *val)); 420 421 return 0; 422 } 423 424 int 425 auacer_write_codec(void *v, uint8_t reg, uint16_t val) 426 { 427 struct auacer_softc *sc; 428 429 DPRINTF(ALI_DEBUG_CODECIO, ("auacer_write_codec: reg=0x%x val=0x%x\n", 430 reg, val)); 431 sc = v; 432 if (auacer_sema_codec(sc)) 433 return EIO; 434 WRITE2(sc, ALI_CPR, val); 435 #if 0 436 if (ac97->num) 437 reg |= ALI_CPR_ADDR_SECONDARY; 438 #endif 439 WRITE2(sc, ALI_CPR_ADDR, reg); 440 auacer_ready_codec(sc, ALI_CSPSR_WRITE_OK); 441 return 0; 442 } 443 444 static int 445 auacer_attach_codec(void *v, struct ac97_codec_if *cif) 446 { 447 struct auacer_softc *sc; 448 449 sc = v; 450 sc->codec_if = cif; 451 return 0; 452 } 453 454 static int 455 auacer_reset_codec(void *v) 456 { 457 struct auacer_softc *sc; 458 uint32_t reg; 459 int i; 460 461 sc = v; 462 i = 0; 463 reg = READ4(sc, ALI_SCR); 464 if ((reg & 2) == 0) /* Cold required */ 465 reg |= 2; 466 else 467 reg |= 1; /* Warm */ 468 reg &= ~0x80000000; /* ACLink on */ 469 WRITE4(sc, ALI_SCR, reg); 470 471 while (i < 10) { 472 if ((READ4(sc, ALI_INTERRUPTSR) & ALI_INT_GPIO) == 0) 473 break; 474 delay(50000); /* XXX */ 475 i++; 476 } 477 if (i == 10) { 478 return EIO; 479 } 480 481 for (i = 0; i < 10; i++) { 482 reg = READ4(sc, ALI_RTSR); 483 if (reg & 0x80) /* primary codec */ 484 break; 485 WRITE4(sc, ALI_RTSR, reg | 0x80); 486 delay(50000); /* XXX */ 487 } 488 489 return 0; 490 } 491 492 static void 493 auacer_reset(struct auacer_softc *sc) 494 { 495 WRITE4(sc, ALI_SCR, ALI_SCR_RESET); 496 WRITE4(sc, ALI_FIFOCR1, 0x83838383); 497 WRITE4(sc, ALI_FIFOCR2, 0x83838383); 498 WRITE4(sc, ALI_FIFOCR3, 0x83838383); 499 WRITE4(sc, ALI_INTERFACECR, ALI_IF_PO); /* XXX pcm out only */ 500 WRITE4(sc, ALI_INTERRUPTCR, 0x00000000); 501 WRITE4(sc, ALI_INTERRUPTSR, 0x00000000); 502 } 503 504 static int 505 auacer_query_encoding(void *v, struct audio_encoding *aep) 506 { 507 struct auacer_softc *sc; 508 509 DPRINTF(ALI_DEBUG_API, ("auacer_query_encoding\n")); 510 sc = v; 511 return auconv_query_encoding(sc->sc_encodings, aep); 512 } 513 514 static int 515 auacer_set_rate(struct auacer_softc *sc, int mode, u_int srate) 516 { 517 int ret; 518 u_int ratetmp; 519 520 DPRINTF(ALI_DEBUG_API, ("auacer_set_rate: srate=%u\n", srate)); 521 522 ratetmp = srate; 523 if (mode == AUMODE_RECORD) 524 return sc->codec_if->vtbl->set_rate(sc->codec_if, 525 AC97_REG_PCM_LR_ADC_RATE, &ratetmp); 526 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 527 AC97_REG_PCM_FRONT_DAC_RATE, &ratetmp); 528 if (ret) 529 return ret; 530 ratetmp = srate; 531 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 532 AC97_REG_PCM_SURR_DAC_RATE, &ratetmp); 533 if (ret) 534 return ret; 535 ratetmp = srate; 536 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 537 AC97_REG_PCM_LFE_DAC_RATE, &ratetmp); 538 return ret; 539 } 540 541 static int 542 auacer_set_params(void *v, int setmode, int usemode, 543 audio_params_t *play, audio_params_t *rec, stream_filter_list_t *pfil, 544 stream_filter_list_t *rfil) 545 { 546 struct auacer_softc *sc; 547 struct audio_params *p; 548 stream_filter_list_t *fil; 549 uint32_t control; 550 int mode, index; 551 552 DPRINTF(ALI_DEBUG_API, ("auacer_set_params\n")); 553 sc = v; 554 for (mode = AUMODE_RECORD; mode != -1; 555 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 556 if ((setmode & mode) == 0) 557 continue; 558 559 p = mode == AUMODE_PLAY ? play : rec; 560 if (p == NULL) 561 continue; 562 563 if ((p->sample_rate != 8000) && 564 (p->sample_rate != 11025) && 565 (p->sample_rate != 12000) && 566 (p->sample_rate != 16000) && 567 (p->sample_rate != 22050) && 568 (p->sample_rate != 24000) && 569 (p->sample_rate != 32000) && 570 (p->sample_rate != 44100) && 571 (p->sample_rate != 48000)) 572 return (EINVAL); 573 574 fil = mode == AUMODE_PLAY ? pfil : rfil; 575 index = auconv_set_converter(sc->sc_formats, AUACER_NFORMATS, 576 mode, p, TRUE, fil); 577 if (index < 0) 578 return EINVAL; 579 if (fil->req_size > 0) 580 p = &fil->filters[0].param; 581 /* p points HW encoding */ 582 if (sc->sc_formats[index].frequency_type != 1 583 && auacer_set_rate(sc, mode, p->sample_rate)) 584 return EINVAL; 585 if (mode == AUMODE_PLAY) { 586 control = READ4(sc, ALI_SCR); 587 control &= ~ALI_SCR_PCM_246_MASK; 588 if (p->channels == 4) 589 control |= ALI_SCR_PCM_4; 590 else if (p->channels == 6) 591 control |= ALI_SCR_PCM_6; 592 WRITE4(sc, ALI_SCR, control); 593 } 594 } 595 596 return (0); 597 } 598 599 static int 600 auacer_round_blocksize(void *v, int blk, int mode, 601 const audio_params_t *param) 602 { 603 604 return blk & ~0x3f; /* keep good alignment */ 605 } 606 607 static void 608 auacer_halt(struct auacer_softc *sc, struct auacer_chan *chan) 609 { 610 uint32_t val; 611 uint8_t port; 612 uint32_t slot; 613 614 port = chan->port; 615 DPRINTF(ALI_DEBUG_API, ("auacer_halt: port=0x%x\n", port)); 616 chan->intr = 0; 617 618 slot = ALI_PORT2SLOT(port); 619 620 val = READ4(sc, ALI_DMACR); 621 val |= 1 << (slot+16); /* pause */ 622 val &= ~(1 << slot); /* no start */ 623 WRITE4(sc, ALI_DMACR, val); 624 WRITE1(sc, port + ALI_OFF_CR, 0); 625 while (READ1(sc, port + ALI_OFF_CR)) 626 ; 627 /* reset whole DMA things */ 628 WRITE1(sc, port + ALI_OFF_CR, ALI_CR_RR); 629 /* clear interrupts */ 630 WRITE1(sc, port + ALI_OFF_SR, READ1(sc, port+ALI_OFF_SR) | ALI_SR_W1TC); 631 WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(port)); 632 } 633 634 static int 635 auacer_halt_output(void *v) 636 { 637 struct auacer_softc *sc; 638 639 DPRINTF(ALI_DEBUG_DMA, ("auacer_halt_output\n")); 640 sc = v; 641 auacer_halt(sc, &sc->sc_pcmo); 642 643 return 0; 644 } 645 646 static int 647 auacer_halt_input(void *v) 648 { 649 DPRINTF(ALI_DEBUG_DMA, ("auacer_halt_input\n")); 650 651 return 0; 652 } 653 654 static int 655 auacer_getdev(void *v, struct audio_device *adp) 656 { 657 struct auacer_softc *sc; 658 659 DPRINTF(ALI_DEBUG_API, ("auacer_getdev\n")); 660 sc = v; 661 *adp = sc->sc_audev; 662 return 0; 663 } 664 665 static int 666 auacer_set_port(void *v, mixer_ctrl_t *cp) 667 { 668 struct auacer_softc *sc; 669 670 DPRINTF(ALI_DEBUG_MIXERAPI, ("auacer_set_port\n")); 671 sc = v; 672 return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp); 673 } 674 675 static int 676 auacer_get_port(void *v, mixer_ctrl_t *cp) 677 { 678 struct auacer_softc *sc; 679 680 DPRINTF(ALI_DEBUG_MIXERAPI, ("auacer_get_port\n")); 681 sc = v; 682 return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp); 683 } 684 685 static int 686 auacer_query_devinfo(void *v, mixer_devinfo_t *dp) 687 { 688 struct auacer_softc *sc; 689 690 DPRINTF(ALI_DEBUG_MIXERAPI, ("auacer_query_devinfo\n")); 691 sc = v; 692 return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp); 693 } 694 695 static void * 696 auacer_allocm(void *v, int direction, size_t size) 697 { 698 struct auacer_softc *sc; 699 struct auacer_dma *p; 700 int error; 701 702 if (size > (ALI_DMALIST_MAX * ALI_DMASEG_MAX)) 703 return NULL; 704 705 p = kmem_zalloc(sizeof(*p), KM_SLEEP); 706 if (p == NULL) 707 return NULL; 708 sc = v; 709 error = auacer_allocmem(sc, size, 0, p); 710 if (error) { 711 kmem_free(p, sizeof(*p)); 712 return NULL; 713 } 714 715 p->next = sc->sc_dmas; 716 sc->sc_dmas = p; 717 718 return KERNADDR(p); 719 } 720 721 static void 722 auacer_freem(void *v, void *ptr, size_t size) 723 { 724 struct auacer_softc *sc; 725 struct auacer_dma *p, **pp; 726 727 sc = v; 728 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 729 if (KERNADDR(p) == ptr) { 730 auacer_freemem(sc, p); 731 *pp = p->next; 732 kmem_free(p, sizeof(*p)); 733 return; 734 } 735 } 736 } 737 738 static size_t 739 auacer_round_buffersize(void *v, int direction, size_t size) 740 { 741 742 if (size > (ALI_DMALIST_MAX * ALI_DMASEG_MAX)) 743 size = ALI_DMALIST_MAX * ALI_DMASEG_MAX; 744 745 return size; 746 } 747 748 static paddr_t 749 auacer_mappage(void *v, void *mem, off_t off, int prot) 750 { 751 struct auacer_softc *sc; 752 struct auacer_dma *p; 753 754 if (off < 0) 755 return -1; 756 sc = v; 757 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 758 continue; 759 if (p == NULL) 760 return -1; 761 return bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs, 762 off, prot, BUS_DMA_WAITOK); 763 } 764 765 static int 766 auacer_get_props(void *v) 767 { 768 struct auacer_softc *sc; 769 int props; 770 771 sc = v; 772 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 773 /* 774 * Even if the codec is fixed-rate, set_param() succeeds for any sample 775 * rate because of aurateconv. Applications can't know what rate the 776 * device can process in the case of mmap(). 777 */ 778 if (!AC97_IS_FIXED_RATE(sc->codec_if)) 779 props |= AUDIO_PROP_MMAP; 780 return props; 781 } 782 783 static void 784 auacer_get_locks(void *v, kmutex_t **intr, kmutex_t **proc) 785 { 786 struct auacer_softc *sc; 787 788 sc = v; 789 *intr = &sc->sc_intr_lock; 790 *proc = &sc->sc_lock; 791 } 792 793 static void 794 auacer_add_entry(struct auacer_chan *chan) 795 { 796 struct auacer_dmalist *q; 797 798 q = &chan->dmalist[chan->ptr]; 799 800 DPRINTF(ALI_DEBUG_INTR, 801 ("auacer_add_entry: %p = %x @ 0x%x\n", 802 q, chan->blksize / 2, chan->p)); 803 804 q->base = htole32(chan->p); 805 q->len = htole32((chan->blksize / ALI_SAMPLE_SIZE) | ALI_DMAF_IOC); 806 chan->p += chan->blksize; 807 if (chan->p >= chan->end) 808 chan->p = chan->start; 809 810 if (++chan->ptr >= ALI_DMALIST_MAX) 811 chan->ptr = 0; 812 } 813 814 static void 815 auacer_upd_chan(struct auacer_softc *sc, struct auacer_chan *chan) 816 { 817 uint32_t sts; 818 uint32_t civ; 819 820 sts = READ2(sc, chan->port + ALI_OFF_SR); 821 /* intr ack */ 822 WRITE2(sc, chan->port + ALI_OFF_SR, sts & ALI_SR_W1TC); 823 WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(chan->port)); 824 825 DPRINTF(ALI_DEBUG_INTR, ("auacer_upd_chan: sts=0x%x\n", sts)); 826 827 if (sts & ALI_SR_DMA_INT_FIFO) { 828 printf("%s: fifo underrun # %u\n", 829 device_xname(sc->sc_dev), ++chan->fifoe); 830 } 831 832 civ = READ1(sc, chan->port + ALI_OFF_CIV); 833 834 DPRINTF(ALI_DEBUG_INTR,("auacer_intr: civ=%u ptr=%u\n",civ,chan->ptr)); 835 836 /* XXX */ 837 while (chan->ptr != civ) { 838 auacer_add_entry(chan); 839 } 840 841 WRITE1(sc, chan->port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK); 842 843 while (chan->ack != civ) { 844 if (chan->intr) { 845 DPRINTF(ALI_DEBUG_INTR,("auacer_upd_chan: callback\n")); 846 chan->intr(chan->arg); 847 } 848 chan->ack++; 849 if (chan->ack >= ALI_DMALIST_MAX) 850 chan->ack = 0; 851 } 852 } 853 854 static int 855 auacer_intr(void *v) 856 { 857 struct auacer_softc *sc; 858 int ret, intrs; 859 860 sc = v; 861 862 DPRINTF(ALI_DEBUG_INTR, ("auacer_intr: intrs=0x%x\n", 863 READ4(sc, ALI_INTERRUPTSR))); 864 865 mutex_spin_enter(&sc->sc_intr_lock); 866 intrs = READ4(sc, ALI_INTERRUPTSR); 867 ret = 0; 868 if (intrs & ALI_INT_PCMOUT) { 869 auacer_upd_chan(sc, &sc->sc_pcmo); 870 ret++; 871 } 872 mutex_spin_exit(&sc->sc_intr_lock); 873 874 return ret != 0; 875 } 876 877 static void 878 auacer_setup_chan(struct auacer_softc *sc, struct auacer_chan *chan, 879 uint32_t start, uint32_t size, uint32_t blksize, 880 void (*intr)(void *), void *arg) 881 { 882 uint32_t port, slot; 883 uint32_t offs, val; 884 885 chan->start = start; 886 chan->ptr = 0; 887 chan->p = chan->start; 888 chan->end = chan->start + size; 889 chan->blksize = blksize; 890 chan->ack = 0; 891 chan->intr = intr; 892 chan->arg = arg; 893 894 auacer_add_entry(chan); 895 auacer_add_entry(chan); 896 897 port = chan->port; 898 slot = ALI_PORT2SLOT(port); 899 900 WRITE1(sc, port + ALI_OFF_CIV, 0); 901 WRITE1(sc, port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK); 902 offs = (char *)chan->dmalist - (char *)sc->sc_cdata; 903 WRITE4(sc, port + ALI_OFF_BDBAR, sc->sc_cddma + offs); 904 WRITE1(sc, port + ALI_OFF_CR, 905 ALI_CR_IOCE | ALI_CR_FEIE | ALI_CR_LVBIE | ALI_CR_RPBM); 906 val = READ4(sc, ALI_DMACR); 907 val &= ~(1 << (slot+16)); /* no pause */ 908 val |= 1 << slot; /* start */ 909 WRITE4(sc, ALI_DMACR, val); 910 } 911 912 static int 913 auacer_trigger_output(void *v, void *start, void *end, int blksize, 914 void (*intr)(void *), void *arg, const audio_params_t *param) 915 { 916 struct auacer_softc *sc; 917 struct auacer_dma *p; 918 uint32_t size; 919 920 DPRINTF(ALI_DEBUG_DMA, 921 ("auacer_trigger_output(%p, %p, %d, %p, %p, %p)\n", 922 start, end, blksize, intr, arg, param)); 923 sc = v; 924 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 925 continue; 926 if (!p) { 927 printf("auacer_trigger_output: bad addr %p\n", start); 928 return (EINVAL); 929 } 930 931 size = (char *)end - (char *)start; 932 auacer_setup_chan(sc, &sc->sc_pcmo, DMAADDR(p), size, blksize, 933 intr, arg); 934 935 return 0; 936 } 937 938 static int 939 auacer_trigger_input(void *v, void *start, void *end, 940 int blksize, void (*intr)(void *), void *arg, 941 const audio_params_t *param) 942 { 943 return EINVAL; 944 } 945 946 static int 947 auacer_allocmem(struct auacer_softc *sc, size_t size, size_t align, 948 struct auacer_dma *p) 949 { 950 int error; 951 952 p->size = size; 953 error = bus_dmamem_alloc(sc->dmat, p->size, align, 0, 954 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 955 &p->nsegs, BUS_DMA_WAITOK); 956 if (error) 957 return error; 958 959 error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size, 960 &p->addr, BUS_DMA_WAITOK|sc->sc_dmamap_flags); 961 if (error) 962 goto free; 963 964 error = bus_dmamap_create(sc->dmat, p->size, 1, p->size, 965 0, BUS_DMA_WAITOK, &p->map); 966 if (error) 967 goto unmap; 968 969 error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, NULL, 970 BUS_DMA_WAITOK); 971 if (error) 972 goto destroy; 973 return (0); 974 975 destroy: 976 bus_dmamap_destroy(sc->dmat, p->map); 977 unmap: 978 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 979 free: 980 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 981 return error; 982 } 983 984 static int 985 auacer_freemem(struct auacer_softc *sc, struct auacer_dma *p) 986 { 987 988 bus_dmamap_unload(sc->dmat, p->map); 989 bus_dmamap_destroy(sc->dmat, p->map); 990 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 991 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 992 return 0; 993 } 994 995 static int 996 auacer_alloc_cdata(struct auacer_softc *sc) 997 { 998 bus_dma_segment_t seg; 999 int error, rseg; 1000 1001 /* 1002 * Allocate the control data structure, and create and load the 1003 * DMA map for it. 1004 */ 1005 if ((error = bus_dmamem_alloc(sc->dmat, 1006 sizeof(struct auacer_cdata), 1007 PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) { 1008 aprint_error_dev(sc->sc_dev, "unable to allocate control data, error = %d\n", 1009 error); 1010 goto fail_0; 1011 } 1012 1013 if ((error = bus_dmamem_map(sc->dmat, &seg, rseg, 1014 sizeof(struct auacer_cdata), 1015 (void **) &sc->sc_cdata, 1016 sc->sc_dmamap_flags)) != 0) { 1017 aprint_error_dev(sc->sc_dev, "unable to map control data, error = %d\n", 1018 error); 1019 goto fail_1; 1020 } 1021 1022 if ((error = bus_dmamap_create(sc->dmat, sizeof(struct auacer_cdata), 1, 1023 sizeof(struct auacer_cdata), 0, 0, 1024 &sc->sc_cddmamap)) != 0) { 1025 aprint_error_dev(sc->sc_dev, "unable to create control data DMA map, " 1026 "error = %d\n", error); 1027 goto fail_2; 1028 } 1029 1030 if ((error = bus_dmamap_load(sc->dmat, sc->sc_cddmamap, 1031 sc->sc_cdata, sizeof(struct auacer_cdata), 1032 NULL, 0)) != 0) { 1033 aprint_error_dev(sc->sc_dev, "unable to load control data DMA map, " 1034 "error = %d\n", error); 1035 goto fail_3; 1036 } 1037 1038 return 0; 1039 1040 fail_3: 1041 bus_dmamap_destroy(sc->dmat, sc->sc_cddmamap); 1042 fail_2: 1043 bus_dmamem_unmap(sc->dmat, (void *) sc->sc_cdata, 1044 sizeof(struct auacer_cdata)); 1045 fail_1: 1046 bus_dmamem_free(sc->dmat, &seg, rseg); 1047 fail_0: 1048 return error; 1049 } 1050 1051 static bool 1052 auacer_resume(device_t dv, const pmf_qual_t *qual) 1053 { 1054 struct auacer_softc *sc = device_private(dv); 1055 1056 mutex_enter(&sc->sc_lock); 1057 mutex_spin_enter(&sc->sc_intr_lock); 1058 auacer_reset_codec(sc); 1059 mutex_spin_exit(&sc->sc_intr_lock); 1060 delay(1000); 1061 sc->codec_if->vtbl->restore_ports(sc->codec_if); 1062 mutex_exit(&sc->sc_lock); 1063 1064 return true; 1065 } 1066