1 /* $NetBSD: auich.c,v 1.58 2004/01/13 14:42:50 kent Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (c) 2000 Michael Shalayeff 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. The name of the author may not be used to endorse or promote products 52 * derived from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 58 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 59 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 60 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 62 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 63 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 64 * THE POSSIBILITY OF SUCH DAMAGE. 65 * 66 * from OpenBSD: ich.c,v 1.3 2000/08/11 06:17:18 mickey Exp 67 */ 68 69 /* 70 * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp> 71 * Copyright (c) 2001 Cameron Grant <cg@freebsd.org> 72 * All rights reserved. 73 * 74 * Redistribution and use in source and binary forms, with or without 75 * modification, are permitted provided that the following conditions 76 * are met: 77 * 1. Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 2. Redistributions in binary form must reproduce the above copyright 80 * notice, this list of conditions and the following disclaimer in the 81 * documentation and/or other materials provided with the distribution. 82 * 83 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 84 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 85 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 86 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 89 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 90 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 91 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 92 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 93 * SUCH DAMAGE. 94 * 95 * auich_calibrate() was from FreeBSD: ich.c,v 1.22 2002/06/27 22:36:01 scottl Exp 96 */ 97 98 99 /* #define ICH_DEBUG */ 100 /* 101 * AC'97 audio found on Intel 810/820/440MX chipsets. 102 * http://developer.intel.com/design/chipsets/datashts/290655.htm 103 * http://developer.intel.com/design/chipsets/manuals/298028.htm 104 * ICH3:http://www.intel.com/design/chipsets/datashts/290716.htm 105 * ICH4:http://www.intel.com/design/chipsets/datashts/290744.htm 106 * ICH5:http://www.intel.com/design/chipsets/datashts/252516.htm 107 * AMD8111: 108 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24674.pdf 109 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25720.pdf 110 * 111 * TODO: 112 * - Add support for the dedicated microphone input. 113 * 114 * NOTE: 115 * - The 440MX B-stepping at running 100MHz has a hardware erratum. 116 * It causes PCI master abort and hangups until cold reboot. 117 * http://www.intel.com/design/chipsets/specupdt/245051.htm 118 */ 119 120 #include <sys/cdefs.h> 121 __KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.58 2004/01/13 14:42:50 kent Exp $"); 122 123 #include <sys/param.h> 124 #include <sys/systm.h> 125 #include <sys/kernel.h> 126 #include <sys/malloc.h> 127 #include <sys/device.h> 128 #include <sys/fcntl.h> 129 #include <sys/proc.h> 130 131 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 132 133 #include <dev/pci/pcidevs.h> 134 #include <dev/pci/pcivar.h> 135 #include <dev/pci/auichreg.h> 136 137 #include <sys/audioio.h> 138 #include <dev/audio_if.h> 139 #include <dev/mulaw.h> 140 #include <dev/auconv.h> 141 142 #include <machine/bus.h> 143 144 #include <dev/ic/ac97reg.h> 145 #include <dev/ic/ac97var.h> 146 147 struct auich_dma { 148 bus_dmamap_t map; 149 caddr_t addr; 150 bus_dma_segment_t segs[1]; 151 int nsegs; 152 size_t size; 153 struct auich_dma *next; 154 }; 155 156 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 157 #define KERNADDR(p) ((void *)((p)->addr)) 158 159 struct auich_cdata { 160 struct auich_dmalist ic_dmalist_pcmo[ICH_DMALIST_MAX]; 161 struct auich_dmalist ic_dmalist_pcmi[ICH_DMALIST_MAX]; 162 struct auich_dmalist ic_dmalist_mici[ICH_DMALIST_MAX]; 163 }; 164 165 #define ICH_CDOFF(x) offsetof(struct auich_cdata, x) 166 #define ICH_PCMO_OFF(x) ICH_CDOFF(ic_dmalist_pcmo[(x)]) 167 #define ICH_PCMI_OFF(x) ICH_CDOFF(ic_dmalist_pcmi[(x)]) 168 #define ICH_MICI_OFF(x) ICH_CDOFF(ic_dmalist_mici[(x)]) 169 170 struct auich_softc { 171 struct device sc_dev; 172 void *sc_ih; 173 174 audio_device_t sc_audev; 175 176 bus_space_tag_t iot; 177 bus_space_handle_t mix_ioh; 178 bus_space_handle_t aud_ioh; 179 bus_dma_tag_t dmat; 180 181 struct ac97_codec_if *codec_if; 182 struct ac97_host_if host_if; 183 184 /* DMA scatter-gather lists. */ 185 bus_dmamap_t sc_cddmamap; 186 #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr 187 188 struct auich_cdata *sc_cdata; 189 #define dmalist_pcmo sc_cdata->ic_dmalist_pcmo 190 #define dmalist_pcmi sc_cdata->ic_dmalist_pcmi 191 #define dmalist_mici sc_cdata->ic_dmalist_mici 192 193 int ptr_pcmo, 194 ptr_pcmi, 195 ptr_mici; 196 197 /* i/o buffer pointers */ 198 u_int32_t pcmo_start, pcmo_p, pcmo_end; 199 int pcmo_blksize, pcmo_fifoe; 200 201 u_int32_t pcmi_start, pcmi_p, pcmi_end; 202 int pcmi_blksize, pcmi_fifoe; 203 204 u_int32_t mici_start, mici_p, mici_end; 205 int mici_blksize, mici_fifoe; 206 207 struct auich_dma *sc_dmas; 208 209 #ifdef DIAGNOSTIC 210 pci_chipset_tag_t sc_pc; 211 pcitag_t sc_pt; 212 #endif 213 /* SiS 7012 hack */ 214 int sc_sample_size; 215 int sc_sts_reg; 216 /* 440MX workaround */ 217 int sc_dmamap_flags; 218 219 void (*sc_pintr)(void *); 220 void *sc_parg; 221 222 void (*sc_rintr)(void *); 223 void *sc_rarg; 224 225 /* Power Management */ 226 void *sc_powerhook; 227 int sc_suspend; 228 u_int16_t ext_status; 229 }; 230 231 #define IS_FIXED_RATE(codec) !((codec)->vtbl->get_extcaps(codec) \ 232 & AC97_EXT_AUDIO_VRA) 233 #define SUPPORTS_4CH(codec) ((codec)->vtbl->get_extcaps(codec) \ 234 & AC97_EXT_AUDIO_SDAC) 235 #define AC97_6CH_DACS (AC97_EXT_AUDIO_SDAC | AC97_EXT_AUDIO_CDAC \ 236 | AC97_EXT_AUDIO_LDAC) 237 #define SUPPORTS_6CH(codec) (((codec)->vtbl->get_extcaps(codec) \ 238 & AC97_6CH_DACS) == AC97_6CH_DACS) 239 240 /* Debug */ 241 #ifdef AUDIO_DEBUG 242 #define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0) 243 int auich_debug = 0xfffe; 244 #define ICH_DEBUG_CODECIO 0x0001 245 #define ICH_DEBUG_DMA 0x0002 246 #define ICH_DEBUG_PARAM 0x0004 247 #else 248 #define DPRINTF(x,y) /* nothing */ 249 #endif 250 251 int auich_match(struct device *, struct cfdata *, void *); 252 void auich_attach(struct device *, struct device *, void *); 253 int auich_intr(void *); 254 255 CFATTACH_DECL(auich, sizeof(struct auich_softc), 256 auich_match, auich_attach, NULL, NULL); 257 258 int auich_open(void *, int); 259 void auich_close(void *); 260 int auich_query_encoding(void *, struct audio_encoding *); 261 int auich_set_params(void *, int, int, struct audio_params *, 262 struct audio_params *); 263 int auich_round_blocksize(void *, int); 264 int auich_halt_output(void *); 265 int auich_halt_input(void *); 266 int auich_getdev(void *, struct audio_device *); 267 int auich_set_port(void *, mixer_ctrl_t *); 268 int auich_get_port(void *, mixer_ctrl_t *); 269 int auich_query_devinfo(void *, mixer_devinfo_t *); 270 void *auich_allocm(void *, int, size_t, struct malloc_type *, int); 271 void auich_freem(void *, void *, struct malloc_type *); 272 size_t auich_round_buffersize(void *, int, size_t); 273 paddr_t auich_mappage(void *, void *, off_t, int); 274 int auich_get_props(void *); 275 int auich_trigger_output(void *, void *, void *, int, void (*)(void *), 276 void *, struct audio_params *); 277 int auich_trigger_input(void *, void *, void *, int, void (*)(void *), 278 void *, struct audio_params *); 279 280 int auich_alloc_cdata(struct auich_softc *); 281 282 int auich_allocmem(struct auich_softc *, size_t, size_t, 283 struct auich_dma *); 284 int auich_freemem(struct auich_softc *, struct auich_dma *); 285 286 void auich_powerhook(int, void *); 287 int auich_set_rate(struct auich_softc *, int, u_long); 288 void auich_finish_attach(struct device *); 289 void auich_calibrate(struct auich_softc *); 290 291 292 struct audio_hw_if auich_hw_if = { 293 auich_open, 294 auich_close, 295 NULL, /* drain */ 296 auich_query_encoding, 297 auich_set_params, 298 auich_round_blocksize, 299 NULL, /* commit_setting */ 300 NULL, /* init_output */ 301 NULL, /* init_input */ 302 NULL, /* start_output */ 303 NULL, /* start_input */ 304 auich_halt_output, 305 auich_halt_input, 306 NULL, /* speaker_ctl */ 307 auich_getdev, 308 NULL, /* getfd */ 309 auich_set_port, 310 auich_get_port, 311 auich_query_devinfo, 312 auich_allocm, 313 auich_freem, 314 auich_round_buffersize, 315 auich_mappage, 316 auich_get_props, 317 auich_trigger_output, 318 auich_trigger_input, 319 NULL, /* dev_ioctl */ 320 }; 321 322 int auich_attach_codec(void *, struct ac97_codec_if *); 323 int auich_read_codec(void *, u_int8_t, u_int16_t *); 324 int auich_write_codec(void *, u_int8_t, u_int16_t); 325 void auich_reset_codec(void *); 326 327 static const struct auich_devtype { 328 int vendor; 329 int product; 330 const char *name; 331 const char *shortname; /* must be less than 11 characters */ 332 } auich_devices[] = { 333 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_ACA, 334 "i82801AA (ICH) AC-97 Audio", "ICH" }, 335 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_ACA, 336 "i82801AB (ICH0) AC-97 Audio", "ICH0" }, 337 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_ACA, 338 "i82801BA (ICH2) AC-97 Audio", "ICH2" }, 339 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_ACA, 340 "i82440MX AC-97 Audio", "440MX" }, 341 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_AC, 342 "i82801CA (ICH3) AC-97 Audio", "ICH3" }, 343 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_AC, 344 "i82801DB/DBM (ICH4/ICH4M) AC-97 Audio", "ICH4" }, 345 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_AC, 346 "i82801EB (ICH5) AC-97 Audio", "ICH5" }, 347 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7012_AC, 348 "SiS 7012 AC-97 Audio", "SiS7012" }, 349 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE_MCP_AC, 350 "nForce MCP AC-97 Audio", "nForce" }, 351 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_MCPT_AC, 352 "nForce2 MCP-T AC-97 Audio", "nForce2" }, 353 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE3_MCPT_AC, 354 "nForce3 MCP-T AC-97 Audio", "nForce3" }, 355 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_AC, 356 "AMD768 AC-97 Audio", "AMD768" }, 357 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC8111_AC, 358 "AMD8111 AC-97 Audio", "AMD8111" }, 359 { 0, 0, 360 NULL, NULL }, 361 }; 362 363 static const struct auich_devtype * 364 auich_lookup(struct pci_attach_args *pa) 365 { 366 const struct auich_devtype *d; 367 368 for (d = auich_devices; d->name != NULL; d++) { 369 if (PCI_VENDOR(pa->pa_id) == d->vendor 370 && PCI_PRODUCT(pa->pa_id) == d->product) 371 return (d); 372 } 373 374 return (NULL); 375 } 376 377 int 378 auich_match(struct device *parent, struct cfdata *match, void *aux) 379 { 380 struct pci_attach_args *pa = aux; 381 382 if (auich_lookup(pa) != NULL) 383 return (1); 384 385 return (0); 386 } 387 388 void 389 auich_attach(struct device *parent, struct device *self, void *aux) 390 { 391 struct auich_softc *sc = (struct auich_softc *)self; 392 struct pci_attach_args *pa = aux; 393 pci_intr_handle_t ih; 394 bus_size_t mix_size, aud_size; 395 pcireg_t v; 396 const char *intrstr; 397 const struct auich_devtype *d; 398 399 aprint_naive(": Audio controller\n"); 400 401 d = auich_lookup(pa); 402 if (d == NULL) 403 panic("auich_attach: impossible"); 404 405 #ifdef DIAGNOSTIC 406 sc->sc_pc = pa->pa_pc; 407 sc->sc_pt = pa->pa_tag; 408 #endif 409 410 aprint_normal(": %s\n", d->name); 411 412 if ((d->vendor == PCI_VENDOR_INTEL 413 && d->product == PCI_PRODUCT_INTEL_82801DB_AC) 414 || (d->vendor == PCI_VENDOR_INTEL 415 && d->product == PCI_PRODUCT_INTEL_82801EB_AC)) { 416 /* 417 * Use native mode for ICH4/ICH5 418 */ 419 if (pci_mapreg_map(pa, ICH_MMBAR, PCI_MAPREG_TYPE_MEM, 0, 420 &sc->iot, &sc->mix_ioh, NULL, &mix_size)) { 421 v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_CFG); 422 pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_CFG, 423 v | ICH_CFG_IOSE); 424 if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO, 425 0, &sc->iot, &sc->mix_ioh, NULL, 426 &mix_size)) { 427 aprint_error("%s: can't map codec i/o space\n", 428 sc->sc_dev.dv_xname); 429 return; 430 } 431 } 432 if (pci_mapreg_map(pa, ICH_MBBAR, PCI_MAPREG_TYPE_MEM, 0, 433 &sc->iot, &sc->aud_ioh, NULL, &aud_size)) { 434 v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_CFG); 435 pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_CFG, 436 v | ICH_CFG_IOSE); 437 if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO, 438 0, &sc->iot, &sc->aud_ioh, NULL, 439 &aud_size)) { 440 aprint_error("%s: can't map device i/o space\n", 441 sc->sc_dev.dv_xname); 442 return; 443 } 444 } 445 } else { 446 if (pci_mapreg_map(pa, ICH_NAMBAR, PCI_MAPREG_TYPE_IO, 0, 447 &sc->iot, &sc->mix_ioh, NULL, &mix_size)) { 448 aprint_error("%s: can't map codec i/o space\n", 449 sc->sc_dev.dv_xname); 450 return; 451 } 452 if (pci_mapreg_map(pa, ICH_NABMBAR, PCI_MAPREG_TYPE_IO, 0, 453 &sc->iot, &sc->aud_ioh, NULL, &aud_size)) { 454 aprint_error("%s: can't map device i/o space\n", 455 sc->sc_dev.dv_xname); 456 return; 457 } 458 } 459 sc->dmat = pa->pa_dmat; 460 461 /* enable bus mastering */ 462 v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 463 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 464 v | PCI_COMMAND_MASTER_ENABLE); 465 466 /* Map and establish the interrupt. */ 467 if (pci_intr_map(pa, &ih)) { 468 aprint_error("%s: can't map interrupt\n", sc->sc_dev.dv_xname); 469 return; 470 } 471 intrstr = pci_intr_string(pa->pa_pc, ih); 472 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, 473 auich_intr, sc); 474 if (sc->sc_ih == NULL) { 475 aprint_error("%s: can't establish interrupt", 476 sc->sc_dev.dv_xname); 477 if (intrstr != NULL) 478 aprint_normal(" at %s", intrstr); 479 aprint_normal("\n"); 480 return; 481 } 482 aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); 483 484 snprintf(sc->sc_audev.name, MAX_AUDIO_DEV_LEN, "%s AC97", d->shortname); 485 snprintf(sc->sc_audev.version, MAX_AUDIO_DEV_LEN, 486 "0x%02x", PCI_REVISION(pa->pa_class)); 487 strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname, MAX_AUDIO_DEV_LEN); 488 489 /* SiS 7012 needs special handling */ 490 if (d->vendor == PCI_VENDOR_SIS 491 && d->product == PCI_PRODUCT_SIS_7012_AC) { 492 sc->sc_sts_reg = ICH_PICB; 493 sc->sc_sample_size = 1; 494 } else { 495 sc->sc_sts_reg = ICH_STS; 496 sc->sc_sample_size = 2; 497 } 498 499 /* Workaround for a 440MX B-stepping erratum */ 500 sc->sc_dmamap_flags = BUS_DMA_COHERENT; 501 if (d->vendor == PCI_VENDOR_INTEL 502 && d->product == PCI_PRODUCT_INTEL_82440MX_ACA) { 503 sc->sc_dmamap_flags |= BUS_DMA_NOCACHE; 504 printf("%s: DMA bug workaround enabled\n", sc->sc_dev.dv_xname); 505 } 506 507 /* Set up DMA lists. */ 508 sc->ptr_pcmo = sc->ptr_pcmi = sc->ptr_mici = 0; 509 auich_alloc_cdata(sc); 510 511 DPRINTF(ICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n", 512 sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici)); 513 514 sc->host_if.arg = sc; 515 sc->host_if.attach = auich_attach_codec; 516 sc->host_if.read = auich_read_codec; 517 sc->host_if.write = auich_write_codec; 518 sc->host_if.reset = auich_reset_codec; 519 520 if (ac97_attach(&sc->host_if) != 0) 521 return; 522 523 /* Watch for power change */ 524 sc->sc_suspend = PWR_RESUME; 525 sc->sc_powerhook = powerhook_establish(auich_powerhook, sc); 526 527 config_interrupts(self, auich_finish_attach); 528 } 529 530 void 531 auich_finish_attach(struct device *self) 532 { 533 struct auich_softc *sc = (void *)self; 534 535 if (!IS_FIXED_RATE(sc->codec_if)) 536 auich_calibrate(sc); 537 538 audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev); 539 } 540 541 #define ICH_CODECIO_INTERVAL 10 542 int 543 auich_read_codec(void *v, u_int8_t reg, u_int16_t *val) 544 { 545 struct auich_softc *sc = v; 546 int i; 547 uint32_t status; 548 549 /* wait for an access semaphore */ 550 for (i = ICH_SEMATIMO / ICH_CODECIO_INTERVAL; i-- && 551 bus_space_read_1(sc->iot, sc->aud_ioh, ICH_CAS) & 1; 552 DELAY(ICH_CODECIO_INTERVAL)); 553 554 if (i > 0) { 555 *val = bus_space_read_2(sc->iot, sc->mix_ioh, reg); 556 DPRINTF(ICH_DEBUG_CODECIO, 557 ("auich_read_codec(%x, %x)\n", reg, *val)); 558 status = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS); 559 if (status & ICH_RCS) { 560 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GSTS, 561 status & ~(ICH_SRI|ICH_PRI|ICH_GSCI)); 562 *val = 0xffff; 563 } 564 return 0; 565 } else { 566 DPRINTF(ICH_DEBUG_CODECIO, 567 ("%s: read_codec timeout\n", sc->sc_dev.dv_xname)); 568 return -1; 569 } 570 } 571 572 int 573 auich_write_codec(void *v, u_int8_t reg, u_int16_t val) 574 { 575 struct auich_softc *sc = v; 576 int i; 577 578 DPRINTF(ICH_DEBUG_CODECIO, ("auich_write_codec(%x, %x)\n", reg, val)); 579 /* wait for an access semaphore */ 580 for (i = ICH_SEMATIMO / ICH_CODECIO_INTERVAL; i-- && 581 bus_space_read_1(sc->iot, sc->aud_ioh, ICH_CAS) & 1; 582 DELAY(ICH_CODECIO_INTERVAL)); 583 584 if (i > 0) { 585 bus_space_write_2(sc->iot, sc->mix_ioh, reg, val); 586 return 0; 587 } else { 588 DPRINTF(ICH_DEBUG_CODECIO, 589 ("%s: write_codec timeout\n", sc->sc_dev.dv_xname)); 590 return -1; 591 } 592 } 593 594 int 595 auich_attach_codec(void *v, struct ac97_codec_if *cif) 596 { 597 struct auich_softc *sc = v; 598 599 sc->codec_if = cif; 600 return 0; 601 } 602 603 void 604 auich_reset_codec(void *v) 605 { 606 struct auich_softc *sc = v; 607 int i; 608 uint32_t control, status; 609 610 control = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GCTRL); 611 control &= ~(ICH_ACLSO | ICH_PCM246_MASK); 612 control |= (control & ICH_CRESET) ? ICH_WRESET : ICH_CRESET; 613 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GCTRL, control); 614 615 for (i = 500000; i >= 0; i--) { 616 status = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GSTS); 617 if (status & (ICH_PCR | ICH_SCR | ICH_S2CR)) 618 break; 619 DELAY(1); 620 } 621 if (i <= 0) { 622 printf("%s: auich_reset_codec: time out\n", sc->sc_dev.dv_xname); 623 /* XXX: should not attach the audio device */ 624 } else { 625 #ifdef DEBUG 626 if (status & ICH_SCR) 627 printf("%s: The 2nd codec is ready.\n", 628 sc->sc_dev.dv_xname); 629 if (status & ICH_S2CR) 630 printf("%s: The 3rd codec is ready.\n", 631 sc->sc_dev.dv_xname); 632 #endif 633 } 634 } 635 636 int 637 auich_open(void *v, int flags) 638 { 639 return 0; 640 } 641 642 void 643 auich_close(void *v) 644 { 645 struct auich_softc *sc = v; 646 647 auich_halt_output(sc); 648 auich_halt_input(sc); 649 650 sc->sc_pintr = NULL; 651 sc->sc_rintr = NULL; 652 } 653 654 int 655 auich_query_encoding(void *v, struct audio_encoding *aep) 656 { 657 658 switch (aep->index) { 659 case 0: 660 strcpy(aep->name, AudioEulinear); 661 aep->encoding = AUDIO_ENCODING_ULINEAR; 662 aep->precision = 8; 663 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 664 return (0); 665 case 1: 666 strcpy(aep->name, AudioEmulaw); 667 aep->encoding = AUDIO_ENCODING_ULAW; 668 aep->precision = 8; 669 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 670 return (0); 671 case 2: 672 strcpy(aep->name, AudioEalaw); 673 aep->encoding = AUDIO_ENCODING_ALAW; 674 aep->precision = 8; 675 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 676 return (0); 677 case 3: 678 strcpy(aep->name, AudioEslinear); 679 aep->encoding = AUDIO_ENCODING_SLINEAR; 680 aep->precision = 8; 681 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 682 return (0); 683 case 4: 684 strcpy(aep->name, AudioEslinear_le); 685 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 686 aep->precision = 16; 687 aep->flags = 0; 688 return (0); 689 case 5: 690 strcpy(aep->name, AudioEulinear_le); 691 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 692 aep->precision = 16; 693 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 694 return (0); 695 case 6: 696 strcpy(aep->name, AudioEslinear_be); 697 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 698 aep->precision = 16; 699 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 700 return (0); 701 case 7: 702 strcpy(aep->name, AudioEulinear_be); 703 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 704 aep->precision = 16; 705 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 706 return (0); 707 default: 708 return (EINVAL); 709 } 710 } 711 712 int 713 auich_set_rate(struct auich_softc *sc, int mode, u_long srate) 714 { 715 int ret; 716 u_long ratetmp; 717 718 ratetmp = srate; 719 if (mode == AUMODE_RECORD) 720 return sc->codec_if->vtbl->set_rate(sc->codec_if, 721 AC97_REG_PCM_LR_ADC_RATE, &ratetmp); 722 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 723 AC97_REG_PCM_FRONT_DAC_RATE, &ratetmp); 724 if (ret) 725 return ret; 726 ratetmp = srate; 727 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 728 AC97_REG_PCM_SURR_DAC_RATE, &ratetmp); 729 if (ret) 730 return ret; 731 ratetmp = srate; 732 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 733 AC97_REG_PCM_LFE_DAC_RATE, &ratetmp); 734 return ret; 735 } 736 737 int 738 auich_set_params(void *v, int setmode, int usemode, struct audio_params *play, 739 struct audio_params *rec) 740 { 741 struct auich_softc *sc = v; 742 struct audio_params *p; 743 int mode; 744 u_int32_t control; 745 746 for (mode = AUMODE_RECORD; mode != -1; 747 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 748 if ((setmode & mode) == 0) 749 continue; 750 751 p = mode == AUMODE_PLAY ? play : rec; 752 if (p == NULL) 753 continue; 754 755 if ((p->sample_rate != 8000) && 756 (p->sample_rate != 11025) && 757 (p->sample_rate != 12000) && 758 (p->sample_rate != 16000) && 759 (p->sample_rate != 22050) && 760 (p->sample_rate != 24000) && 761 (p->sample_rate != 32000) && 762 (p->sample_rate != 44100) && 763 (p->sample_rate != 48000)) 764 return (EINVAL); 765 766 p->factor = 1; 767 if (p->precision == 8) 768 p->factor *= 2; 769 770 p->sw_code = NULL; 771 /* setup hardware formats */ 772 p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE; 773 p->hw_precision = 16; 774 775 if (mode == AUMODE_RECORD) { 776 if (p->channels < 1 || p->channels > 2) 777 return EINVAL; 778 } else { 779 switch (p->channels) { 780 case 1: 781 break; 782 case 2: 783 break; 784 case 4: 785 if (!SUPPORTS_4CH(sc->codec_if)) 786 return EINVAL; 787 break; 788 case 6: 789 if (!SUPPORTS_6CH(sc->codec_if)) 790 return EINVAL; 791 break; 792 default: 793 return EINVAL; 794 } 795 } 796 /* If monaural is requested, aurateconv expands a monaural 797 * stream to stereo. */ 798 if (p->channels == 1) 799 p->hw_channels = 2; 800 801 switch (p->encoding) { 802 case AUDIO_ENCODING_SLINEAR_BE: 803 if (p->precision == 16) { 804 p->sw_code = swap_bytes; 805 } else { 806 if (mode == AUMODE_PLAY) 807 p->sw_code = linear8_to_linear16_le; 808 else 809 p->sw_code = linear16_to_linear8_le; 810 } 811 break; 812 813 case AUDIO_ENCODING_SLINEAR_LE: 814 if (p->precision != 16) { 815 if (mode == AUMODE_PLAY) 816 p->sw_code = linear8_to_linear16_le; 817 else 818 p->sw_code = linear16_to_linear8_le; 819 } 820 break; 821 822 case AUDIO_ENCODING_ULINEAR_BE: 823 if (p->precision == 16) { 824 if (mode == AUMODE_PLAY) 825 p->sw_code = 826 swap_bytes_change_sign16_le; 827 else 828 p->sw_code = 829 change_sign16_swap_bytes_le; 830 } else { 831 if (mode == AUMODE_PLAY) 832 p->sw_code = 833 ulinear8_to_slinear16_le; 834 else 835 p->sw_code = 836 slinear16_to_ulinear8_le; 837 } 838 break; 839 840 case AUDIO_ENCODING_ULINEAR_LE: 841 if (p->precision == 16) { 842 p->sw_code = change_sign16_le; 843 } else { 844 if (mode == AUMODE_PLAY) 845 p->sw_code = 846 ulinear8_to_slinear16_le; 847 else 848 p->sw_code = 849 slinear16_to_ulinear8_le; 850 } 851 break; 852 853 case AUDIO_ENCODING_ULAW: 854 if (mode == AUMODE_PLAY) { 855 p->sw_code = mulaw_to_slinear16_le; 856 } else { 857 p->sw_code = slinear16_to_mulaw_le; 858 } 859 break; 860 861 case AUDIO_ENCODING_ALAW: 862 if (mode == AUMODE_PLAY) { 863 p->sw_code = alaw_to_slinear16_le; 864 } else { 865 p->sw_code = slinear16_to_alaw_le; 866 } 867 break; 868 869 default: 870 return (EINVAL); 871 } 872 873 if (IS_FIXED_RATE(sc->codec_if)) { 874 p->hw_sample_rate = AC97_SINGLE_RATE; 875 /* If hw_sample_rate is changed, aurateconv works. */ 876 } else { 877 if (auich_set_rate(sc, mode, p->sample_rate)) 878 return EINVAL; 879 } 880 if (mode == AUMODE_PLAY) { 881 control = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GCTRL); 882 control &= ~ICH_PCM246_MASK; 883 if (p->channels == 4) { 884 control |= ICH_PCM4; 885 } else if (p->channels == 6) { 886 control |= ICH_PCM6; 887 } 888 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GCTRL, control); 889 } 890 } 891 892 return (0); 893 } 894 895 int 896 auich_round_blocksize(void *v, int blk) 897 { 898 899 return (blk & ~0x3f); /* keep good alignment */ 900 } 901 902 int 903 auich_halt_output(void *v) 904 { 905 struct auich_softc *sc = v; 906 907 DPRINTF(ICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname)); 908 909 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, ICH_RR); 910 911 return (0); 912 } 913 914 int 915 auich_halt_input(void *v) 916 { 917 struct auich_softc *sc = v; 918 919 DPRINTF(ICH_DEBUG_DMA, 920 ("%s: halt_input\n", sc->sc_dev.dv_xname)); 921 922 /* XXX halt both unless known otherwise */ 923 924 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 925 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_MICI + ICH_CTRL, ICH_RR); 926 927 return (0); 928 } 929 930 int 931 auich_getdev(void *v, struct audio_device *adp) 932 { 933 struct auich_softc *sc = v; 934 935 *adp = sc->sc_audev; 936 return (0); 937 } 938 939 int 940 auich_set_port(void *v, mixer_ctrl_t *cp) 941 { 942 struct auich_softc *sc = v; 943 944 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp)); 945 } 946 947 int 948 auich_get_port(void *v, mixer_ctrl_t *cp) 949 { 950 struct auich_softc *sc = v; 951 952 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 953 } 954 955 int 956 auich_query_devinfo(void *v, mixer_devinfo_t *dp) 957 { 958 struct auich_softc *sc = v; 959 960 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp)); 961 } 962 963 void * 964 auich_allocm(void *v, int direction, size_t size, struct malloc_type *pool, 965 int flags) 966 { 967 struct auich_softc *sc = v; 968 struct auich_dma *p; 969 int error; 970 971 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 972 return (NULL); 973 974 p = malloc(sizeof(*p), pool, flags|M_ZERO); 975 if (p == NULL) 976 return (NULL); 977 978 error = auich_allocmem(sc, size, 0, p); 979 if (error) { 980 free(p, pool); 981 return (NULL); 982 } 983 984 p->next = sc->sc_dmas; 985 sc->sc_dmas = p; 986 987 return (KERNADDR(p)); 988 } 989 990 void 991 auich_freem(void *v, void *ptr, struct malloc_type *pool) 992 { 993 struct auich_softc *sc = v; 994 struct auich_dma *p, **pp; 995 996 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 997 if (KERNADDR(p) == ptr) { 998 auich_freemem(sc, p); 999 *pp = p->next; 1000 free(p, pool); 1001 return; 1002 } 1003 } 1004 } 1005 1006 size_t 1007 auich_round_buffersize(void *v, int direction, size_t size) 1008 { 1009 1010 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 1011 size = ICH_DMALIST_MAX * ICH_DMASEG_MAX; 1012 1013 return size; 1014 } 1015 1016 paddr_t 1017 auich_mappage(void *v, void *mem, off_t off, int prot) 1018 { 1019 struct auich_softc *sc = v; 1020 struct auich_dma *p; 1021 1022 if (off < 0) 1023 return (-1); 1024 1025 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1026 ; 1027 if (!p) 1028 return (-1); 1029 return (bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs, 1030 off, prot, BUS_DMA_WAITOK)); 1031 } 1032 1033 int 1034 auich_get_props(void *v) 1035 { 1036 struct auich_softc *sc = v; 1037 int props; 1038 1039 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1040 /* 1041 * Even if the codec is fixed-rate, set_param() succeeds for any sample 1042 * rate because of aurateconv. Applications can't know what rate the 1043 * device can process in the case of mmap(). 1044 */ 1045 if (!IS_FIXED_RATE(sc->codec_if)) 1046 props |= AUDIO_PROP_MMAP; 1047 return props; 1048 } 1049 1050 int 1051 auich_intr(void *v) 1052 { 1053 struct auich_softc *sc = v; 1054 int ret = 0, sts, gsts, i, qptr; 1055 1056 #ifdef DIAGNOSTIC 1057 int csts; 1058 #endif 1059 1060 #ifdef DIAGNOSTIC 1061 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1062 if (csts & PCI_STATUS_MASTER_ABORT) { 1063 printf("auich_intr: PCI master abort\n"); 1064 } 1065 #endif 1066 1067 gsts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_GSTS); 1068 DPRINTF(ICH_DEBUG_DMA, ("auich_intr: gsts=0x%x\n", gsts)); 1069 1070 if (gsts & ICH_POINT) { 1071 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMO+sc->sc_sts_reg); 1072 DPRINTF(ICH_DEBUG_DMA, 1073 ("auich_intr: osts=0x%x\n", sts)); 1074 1075 if (sts & ICH_FIFOE) { 1076 printf("%s: fifo underrun # %u\n", 1077 sc->sc_dev.dv_xname, ++sc->pcmo_fifoe); 1078 } 1079 1080 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CIV); 1081 if (sts & (ICH_LVBCI | ICH_CELV)) { 1082 struct auich_dmalist *q; 1083 1084 qptr = sc->ptr_pcmo; 1085 1086 while (qptr != i) { 1087 q = &sc->dmalist_pcmo[qptr]; 1088 1089 q->base = sc->pcmo_p; 1090 q->len = (sc->pcmo_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1091 DPRINTF(ICH_DEBUG_DMA, 1092 ("auich_intr: %p, %p = %x @ 0x%x\n", 1093 &sc->dmalist_pcmo[i], q, 1094 sc->pcmo_blksize / 2, sc->pcmo_p)); 1095 1096 sc->pcmo_p += sc->pcmo_blksize; 1097 if (sc->pcmo_p >= sc->pcmo_end) 1098 sc->pcmo_p = sc->pcmo_start; 1099 1100 if (++qptr == ICH_DMALIST_MAX) 1101 qptr = 0; 1102 } 1103 1104 sc->ptr_pcmo = qptr; 1105 bus_space_write_1(sc->iot, sc->aud_ioh, 1106 ICH_PCMO + ICH_LVI, 1107 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1108 } 1109 1110 if (sts & ICH_BCIS && sc->sc_pintr) 1111 sc->sc_pintr(sc->sc_parg); 1112 1113 /* int ack */ 1114 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMO + sc->sc_sts_reg, 1115 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1116 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_POINT); 1117 ret++; 1118 } 1119 1120 if (gsts & ICH_PIINT) { 1121 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMI+sc->sc_sts_reg); 1122 DPRINTF(ICH_DEBUG_DMA, 1123 ("auich_intr: ists=0x%x\n", sts)); 1124 1125 if (sts & ICH_FIFOE) { 1126 printf("%s: fifo overrun # %u\n", 1127 sc->sc_dev.dv_xname, ++sc->pcmi_fifoe); 1128 } 1129 1130 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1131 if (sts & (ICH_LVBCI | ICH_CELV)) { 1132 struct auich_dmalist *q; 1133 1134 qptr = sc->ptr_pcmi; 1135 1136 while (qptr != i) { 1137 q = &sc->dmalist_pcmi[qptr]; 1138 1139 q->base = sc->pcmi_p; 1140 q->len = (sc->pcmi_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1141 DPRINTF(ICH_DEBUG_DMA, 1142 ("auich_intr: %p, %p = %x @ 0x%x\n", 1143 &sc->dmalist_pcmi[i], q, 1144 sc->pcmi_blksize / 2, sc->pcmi_p)); 1145 1146 sc->pcmi_p += sc->pcmi_blksize; 1147 if (sc->pcmi_p >= sc->pcmi_end) 1148 sc->pcmi_p = sc->pcmi_start; 1149 1150 if (++qptr == ICH_DMALIST_MAX) 1151 qptr = 0; 1152 } 1153 1154 sc->ptr_pcmi = qptr; 1155 bus_space_write_1(sc->iot, sc->aud_ioh, 1156 ICH_PCMI + ICH_LVI, 1157 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1158 } 1159 1160 if (sts & ICH_BCIS && sc->sc_rintr) 1161 sc->sc_rintr(sc->sc_rarg); 1162 1163 /* int ack */ 1164 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMI + sc->sc_sts_reg, 1165 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1166 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_PIINT); 1167 ret++; 1168 } 1169 1170 if (gsts & ICH_MIINT) { 1171 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_MICI+sc->sc_sts_reg); 1172 DPRINTF(ICH_DEBUG_DMA, 1173 ("auich_intr: ists=0x%x\n", sts)); 1174 if (sts & ICH_FIFOE) 1175 printf("%s: fifo overrun\n", sc->sc_dev.dv_xname); 1176 1177 /* TODO mic input DMA */ 1178 1179 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_MIINT); 1180 } 1181 1182 return ret; 1183 } 1184 1185 int 1186 auich_trigger_output(void *v, void *start, void *end, int blksize, 1187 void (*intr)(void *), void *arg, struct audio_params *param) 1188 { 1189 struct auich_softc *sc = v; 1190 struct auich_dmalist *q; 1191 struct auich_dma *p; 1192 size_t size; 1193 #ifdef DIAGNOSTIC 1194 int csts; 1195 #endif 1196 1197 DPRINTF(ICH_DEBUG_DMA, 1198 ("auich_trigger_output(%p, %p, %d, %p, %p, %p)\n", 1199 start, end, blksize, intr, arg, param)); 1200 1201 sc->sc_pintr = intr; 1202 sc->sc_parg = arg; 1203 #ifdef DIAGNOSTIC 1204 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1205 if (csts & PCI_STATUS_MASTER_ABORT) { 1206 printf("auich_trigger_output: PCI master abort\n"); 1207 } 1208 #endif 1209 1210 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1211 ; 1212 if (!p) { 1213 printf("auich_trigger_output: bad addr %p\n", start); 1214 return (EINVAL); 1215 } 1216 1217 size = (size_t)((caddr_t)end - (caddr_t)start); 1218 1219 /* 1220 * The logic behind this is: 1221 * setup one buffer to play, then LVI dump out the rest 1222 * to the scatter-gather chain. 1223 */ 1224 sc->pcmo_start = DMAADDR(p); 1225 sc->pcmo_p = sc->pcmo_start + blksize; 1226 sc->pcmo_end = sc->pcmo_start + size; 1227 sc->pcmo_blksize = blksize; 1228 1229 sc->ptr_pcmo = 0; 1230 q = &sc->dmalist_pcmo[sc->ptr_pcmo]; 1231 q->base = sc->pcmo_start; 1232 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1233 if (++sc->ptr_pcmo == ICH_DMALIST_MAX) 1234 sc->ptr_pcmo = 0; 1235 1236 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_BDBAR, 1237 sc->sc_cddma + ICH_PCMO_OFF(0)); 1238 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, 1239 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1240 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_LVI, 1241 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1242 1243 return (0); 1244 } 1245 1246 int 1247 auich_trigger_input(v, start, end, blksize, intr, arg, param) 1248 void *v; 1249 void *start, *end; 1250 int blksize; 1251 void (*intr)(void *); 1252 void *arg; 1253 struct audio_params *param; 1254 { 1255 struct auich_softc *sc = v; 1256 struct auich_dmalist *q; 1257 struct auich_dma *p; 1258 size_t size; 1259 #ifdef DIAGNOSTIC 1260 int csts; 1261 #endif 1262 1263 DPRINTF(ICH_DEBUG_DMA, 1264 ("auich_trigger_input(%p, %p, %d, %p, %p, %p)\n", 1265 start, end, blksize, intr, arg, param)); 1266 1267 sc->sc_rintr = intr; 1268 sc->sc_rarg = arg; 1269 1270 #ifdef DIAGNOSTIC 1271 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1272 if (csts & PCI_STATUS_MASTER_ABORT) { 1273 printf("auich_trigger_input: PCI master abort\n"); 1274 } 1275 #endif 1276 1277 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1278 ; 1279 if (!p) { 1280 printf("auich_trigger_input: bad addr %p\n", start); 1281 return (EINVAL); 1282 } 1283 1284 size = (size_t)((caddr_t)end - (caddr_t)start); 1285 1286 /* 1287 * The logic behind this is: 1288 * setup one buffer to play, then LVI dump out the rest 1289 * to the scatter-gather chain. 1290 */ 1291 sc->pcmi_start = DMAADDR(p); 1292 sc->pcmi_p = sc->pcmi_start + blksize; 1293 sc->pcmi_end = sc->pcmi_start + size; 1294 sc->pcmi_blksize = blksize; 1295 1296 sc->ptr_pcmi = 0; 1297 q = &sc->dmalist_pcmi[sc->ptr_pcmi]; 1298 q->base = sc->pcmi_start; 1299 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1300 if (++sc->ptr_pcmi == ICH_DMALIST_MAX) 1301 sc->ptr_pcmi = 0; 1302 1303 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1304 sc->sc_cddma + ICH_PCMI_OFF(0)); 1305 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 1306 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1307 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1308 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1309 1310 return (0); 1311 } 1312 1313 int 1314 auich_allocmem(struct auich_softc *sc, size_t size, size_t align, 1315 struct auich_dma *p) 1316 { 1317 int error; 1318 1319 p->size = size; 1320 error = bus_dmamem_alloc(sc->dmat, p->size, align, 0, 1321 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 1322 &p->nsegs, BUS_DMA_NOWAIT); 1323 if (error) 1324 return (error); 1325 1326 error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size, 1327 &p->addr, BUS_DMA_NOWAIT|sc->sc_dmamap_flags); 1328 if (error) 1329 goto free; 1330 1331 error = bus_dmamap_create(sc->dmat, p->size, 1, p->size, 1332 0, BUS_DMA_NOWAIT, &p->map); 1333 if (error) 1334 goto unmap; 1335 1336 error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, NULL, 1337 BUS_DMA_NOWAIT); 1338 if (error) 1339 goto destroy; 1340 return (0); 1341 1342 destroy: 1343 bus_dmamap_destroy(sc->dmat, p->map); 1344 unmap: 1345 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1346 free: 1347 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1348 return (error); 1349 } 1350 1351 int 1352 auich_freemem(struct auich_softc *sc, struct auich_dma *p) 1353 { 1354 1355 bus_dmamap_unload(sc->dmat, p->map); 1356 bus_dmamap_destroy(sc->dmat, p->map); 1357 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1358 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1359 return (0); 1360 } 1361 1362 int 1363 auich_alloc_cdata(struct auich_softc *sc) 1364 { 1365 bus_dma_segment_t seg; 1366 int error, rseg; 1367 1368 /* 1369 * Allocate the control data structure, and create and load the 1370 * DMA map for it. 1371 */ 1372 if ((error = bus_dmamem_alloc(sc->dmat, 1373 sizeof(struct auich_cdata), 1374 PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) { 1375 printf("%s: unable to allocate control data, error = %d\n", 1376 sc->sc_dev.dv_xname, error); 1377 goto fail_0; 1378 } 1379 1380 if ((error = bus_dmamem_map(sc->dmat, &seg, rseg, 1381 sizeof(struct auich_cdata), 1382 (caddr_t *) &sc->sc_cdata, 1383 sc->sc_dmamap_flags)) != 0) { 1384 printf("%s: unable to map control data, error = %d\n", 1385 sc->sc_dev.dv_xname, error); 1386 goto fail_1; 1387 } 1388 1389 if ((error = bus_dmamap_create(sc->dmat, sizeof(struct auich_cdata), 1, 1390 sizeof(struct auich_cdata), 0, 0, 1391 &sc->sc_cddmamap)) != 0) { 1392 printf("%s: unable to create control data DMA map, " 1393 "error = %d\n", sc->sc_dev.dv_xname, error); 1394 goto fail_2; 1395 } 1396 1397 if ((error = bus_dmamap_load(sc->dmat, sc->sc_cddmamap, 1398 sc->sc_cdata, sizeof(struct auich_cdata), 1399 NULL, 0)) != 0) { 1400 printf("%s: unable tp load control data DMA map, " 1401 "error = %d\n", sc->sc_dev.dv_xname, error); 1402 goto fail_3; 1403 } 1404 1405 return (0); 1406 1407 fail_3: 1408 bus_dmamap_destroy(sc->dmat, sc->sc_cddmamap); 1409 fail_2: 1410 bus_dmamem_unmap(sc->dmat, (caddr_t) sc->sc_cdata, 1411 sizeof(struct auich_cdata)); 1412 fail_1: 1413 bus_dmamem_free(sc->dmat, &seg, rseg); 1414 fail_0: 1415 return (error); 1416 } 1417 1418 void 1419 auich_powerhook(int why, void *addr) 1420 { 1421 struct auich_softc *sc = (struct auich_softc *)addr; 1422 1423 switch (why) { 1424 case PWR_SUSPEND: 1425 case PWR_STANDBY: 1426 /* Power down */ 1427 DPRINTF(1, ("%s: power down\n", sc->sc_dev.dv_xname)); 1428 sc->sc_suspend = why; 1429 auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_status); 1430 break; 1431 1432 case PWR_RESUME: 1433 /* Wake up */ 1434 DPRINTF(1, ("%s: power resume\n", sc->sc_dev.dv_xname)); 1435 if (sc->sc_suspend == PWR_RESUME) { 1436 printf("%s: resume without suspend.\n", 1437 sc->sc_dev.dv_xname); 1438 sc->sc_suspend = why; 1439 return; 1440 } 1441 sc->sc_suspend = why; 1442 auich_reset_codec(sc); 1443 DELAY(1000); 1444 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1445 auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_status); 1446 break; 1447 1448 case PWR_SOFTSUSPEND: 1449 case PWR_SOFTSTANDBY: 1450 case PWR_SOFTRESUME: 1451 break; 1452 } 1453 } 1454 1455 1456 /* -------------------------------------------------------------------- */ 1457 /* Calibrate card (some boards are overclocked and need scaling) */ 1458 1459 void 1460 auich_calibrate(struct auich_softc *sc) 1461 { 1462 struct timeval t1, t2; 1463 uint8_t ociv, nciv; 1464 uint64_t wait_us; 1465 uint32_t actual_48k_rate, bytes, ac97rate; 1466 void *temp_buffer; 1467 struct auich_dma *p; 1468 u_long rate; 1469 1470 /* 1471 * Grab audio from input for fixed interval and compare how 1472 * much we actually get with what we expect. Interval needs 1473 * to be sufficiently short that no interrupts are 1474 * generated. 1475 */ 1476 1477 /* Force the codec to a known state first. */ 1478 sc->codec_if->vtbl->set_clock(sc->codec_if, 48000); 1479 rate = 48000; 1480 sc->codec_if->vtbl->set_rate(sc->codec_if, AC97_REG_PCM_LR_ADC_RATE, 1481 &rate); 1482 1483 /* Setup a buffer */ 1484 bytes = 64000; 1485 temp_buffer = auich_allocm(sc, AUMODE_RECORD, bytes, M_DEVBUF, M_WAITOK); 1486 1487 for (p = sc->sc_dmas; p && KERNADDR(p) != temp_buffer; p = p->next) 1488 ; 1489 if (p == NULL) { 1490 printf("auich_calibrate: bad address %p\n", temp_buffer); 1491 return; 1492 } 1493 sc->dmalist_pcmi[0].base = DMAADDR(p); 1494 sc->dmalist_pcmi[0].len = (bytes / sc->sc_sample_size); 1495 1496 /* 1497 * our data format is stereo, 16 bit so each sample is 4 bytes. 1498 * assuming we get 48000 samples per second, we get 192000 bytes/sec. 1499 * we're going to start recording with interrupts disabled and measure 1500 * the time taken for one block to complete. we know the block size, 1501 * we know the time in microseconds, we calculate the sample rate: 1502 * 1503 * actual_rate [bps] = bytes / (time [s] * 4) 1504 * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4) 1505 * actual_rate [Hz] = (bytes * 250000) / time [us] 1506 */ 1507 1508 /* prepare */ 1509 ociv = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1510 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1511 sc->sc_cddma + ICH_PCMI_OFF(0)); 1512 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1513 (0 - 1) & ICH_LVI_MASK); 1514 1515 /* start */ 1516 microtime(&t1); 1517 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RPBM); 1518 1519 /* wait */ 1520 nciv = ociv; 1521 do { 1522 microtime(&t2); 1523 if (t2.tv_sec - t1.tv_sec > 1) 1524 break; 1525 nciv = bus_space_read_1(sc->iot, sc->aud_ioh, 1526 ICH_PCMI + ICH_CIV); 1527 } while (nciv == ociv); 1528 microtime(&t2); 1529 1530 /* stop */ 1531 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 0); 1532 1533 /* reset */ 1534 DELAY(100); 1535 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 1536 1537 /* turn time delta into us */ 1538 wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec; 1539 1540 auich_freem(sc, temp_buffer, M_DEVBUF); 1541 1542 if (nciv == ociv) { 1543 printf("%s: ac97 link rate calibration timed out after %" 1544 PRIu64 " us\n", sc->sc_dev.dv_xname, wait_us); 1545 return; 1546 } 1547 1548 actual_48k_rate = (bytes * UINT64_C(250000)) / wait_us; 1549 1550 if (actual_48k_rate < 50000) 1551 ac97rate = 48000; 1552 else 1553 ac97rate = ((actual_48k_rate + 500) / 1000) * 1000; 1554 1555 printf("%s: measured ac97 link rate at %d Hz", 1556 sc->sc_dev.dv_xname, actual_48k_rate); 1557 if (ac97rate != actual_48k_rate) 1558 printf(", will use %d Hz", ac97rate); 1559 printf("\n"); 1560 1561 sc->codec_if->vtbl->set_clock(sc->codec_if, ac97rate); 1562 } 1563