1 /* $NetBSD: auich.c,v 1.60 2004/07/09 02:42:45 mycroft 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.60 2004/07/09 02:42:45 mycroft 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 } 646 647 int 648 auich_query_encoding(void *v, struct audio_encoding *aep) 649 { 650 651 switch (aep->index) { 652 case 0: 653 strcpy(aep->name, AudioEulinear); 654 aep->encoding = AUDIO_ENCODING_ULINEAR; 655 aep->precision = 8; 656 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 657 return (0); 658 case 1: 659 strcpy(aep->name, AudioEmulaw); 660 aep->encoding = AUDIO_ENCODING_ULAW; 661 aep->precision = 8; 662 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 663 return (0); 664 case 2: 665 strcpy(aep->name, AudioEalaw); 666 aep->encoding = AUDIO_ENCODING_ALAW; 667 aep->precision = 8; 668 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 669 return (0); 670 case 3: 671 strcpy(aep->name, AudioEslinear); 672 aep->encoding = AUDIO_ENCODING_SLINEAR; 673 aep->precision = 8; 674 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 675 return (0); 676 case 4: 677 strcpy(aep->name, AudioEslinear_le); 678 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 679 aep->precision = 16; 680 aep->flags = 0; 681 return (0); 682 case 5: 683 strcpy(aep->name, AudioEulinear_le); 684 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 685 aep->precision = 16; 686 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 687 return (0); 688 case 6: 689 strcpy(aep->name, AudioEslinear_be); 690 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 691 aep->precision = 16; 692 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 693 return (0); 694 case 7: 695 strcpy(aep->name, AudioEulinear_be); 696 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 697 aep->precision = 16; 698 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 699 return (0); 700 default: 701 return (EINVAL); 702 } 703 } 704 705 int 706 auich_set_rate(struct auich_softc *sc, int mode, u_long srate) 707 { 708 int ret; 709 u_long ratetmp; 710 711 ratetmp = srate; 712 if (mode == AUMODE_RECORD) 713 return sc->codec_if->vtbl->set_rate(sc->codec_if, 714 AC97_REG_PCM_LR_ADC_RATE, &ratetmp); 715 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 716 AC97_REG_PCM_FRONT_DAC_RATE, &ratetmp); 717 if (ret) 718 return ret; 719 ratetmp = srate; 720 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 721 AC97_REG_PCM_SURR_DAC_RATE, &ratetmp); 722 if (ret) 723 return ret; 724 ratetmp = srate; 725 ret = sc->codec_if->vtbl->set_rate(sc->codec_if, 726 AC97_REG_PCM_LFE_DAC_RATE, &ratetmp); 727 return ret; 728 } 729 730 int 731 auich_set_params(void *v, int setmode, int usemode, struct audio_params *play, 732 struct audio_params *rec) 733 { 734 struct auich_softc *sc = v; 735 struct audio_params *p; 736 int mode; 737 u_int32_t control; 738 739 for (mode = AUMODE_RECORD; mode != -1; 740 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 741 if ((setmode & mode) == 0) 742 continue; 743 744 p = mode == AUMODE_PLAY ? play : rec; 745 if (p == NULL) 746 continue; 747 748 if ((p->sample_rate != 8000) && 749 (p->sample_rate != 11025) && 750 (p->sample_rate != 12000) && 751 (p->sample_rate != 16000) && 752 (p->sample_rate != 22050) && 753 (p->sample_rate != 24000) && 754 (p->sample_rate != 32000) && 755 (p->sample_rate != 44100) && 756 (p->sample_rate != 48000)) 757 return (EINVAL); 758 759 p->factor = 1; 760 if (p->precision == 8) 761 p->factor *= 2; 762 763 p->sw_code = NULL; 764 /* setup hardware formats */ 765 p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE; 766 p->hw_precision = 16; 767 768 if (mode == AUMODE_RECORD) { 769 if (p->channels < 1 || p->channels > 2) 770 return EINVAL; 771 } else { 772 switch (p->channels) { 773 case 1: 774 break; 775 case 2: 776 break; 777 case 4: 778 if (!SUPPORTS_4CH(sc->codec_if)) 779 return EINVAL; 780 break; 781 case 6: 782 if (!SUPPORTS_6CH(sc->codec_if)) 783 return EINVAL; 784 break; 785 default: 786 return EINVAL; 787 } 788 } 789 /* If monaural is requested, aurateconv expands a monaural 790 * stream to stereo. */ 791 if (p->channels == 1) 792 p->hw_channels = 2; 793 794 switch (p->encoding) { 795 case AUDIO_ENCODING_SLINEAR_BE: 796 if (p->precision == 16) { 797 p->sw_code = swap_bytes; 798 } else { 799 if (mode == AUMODE_PLAY) 800 p->sw_code = linear8_to_linear16_le; 801 else 802 p->sw_code = linear16_to_linear8_le; 803 } 804 break; 805 806 case AUDIO_ENCODING_SLINEAR_LE: 807 if (p->precision != 16) { 808 if (mode == AUMODE_PLAY) 809 p->sw_code = linear8_to_linear16_le; 810 else 811 p->sw_code = linear16_to_linear8_le; 812 } 813 break; 814 815 case AUDIO_ENCODING_ULINEAR_BE: 816 if (p->precision == 16) { 817 if (mode == AUMODE_PLAY) 818 p->sw_code = 819 swap_bytes_change_sign16_le; 820 else 821 p->sw_code = 822 change_sign16_swap_bytes_le; 823 } else { 824 if (mode == AUMODE_PLAY) 825 p->sw_code = 826 ulinear8_to_slinear16_le; 827 else 828 p->sw_code = 829 slinear16_to_ulinear8_le; 830 } 831 break; 832 833 case AUDIO_ENCODING_ULINEAR_LE: 834 if (p->precision == 16) { 835 p->sw_code = change_sign16_le; 836 } else { 837 if (mode == AUMODE_PLAY) 838 p->sw_code = 839 ulinear8_to_slinear16_le; 840 else 841 p->sw_code = 842 slinear16_to_ulinear8_le; 843 } 844 break; 845 846 case AUDIO_ENCODING_ULAW: 847 if (mode == AUMODE_PLAY) { 848 p->sw_code = mulaw_to_slinear16_le; 849 } else { 850 p->sw_code = slinear16_to_mulaw_le; 851 } 852 break; 853 854 case AUDIO_ENCODING_ALAW: 855 if (mode == AUMODE_PLAY) { 856 p->sw_code = alaw_to_slinear16_le; 857 } else { 858 p->sw_code = slinear16_to_alaw_le; 859 } 860 break; 861 862 default: 863 return (EINVAL); 864 } 865 866 if (IS_FIXED_RATE(sc->codec_if)) { 867 p->hw_sample_rate = AC97_SINGLE_RATE; 868 /* If hw_sample_rate is changed, aurateconv works. */ 869 } else { 870 if (auich_set_rate(sc, mode, p->sample_rate)) 871 return EINVAL; 872 } 873 if (mode == AUMODE_PLAY) { 874 control = bus_space_read_4(sc->iot, sc->aud_ioh, ICH_GCTRL); 875 control &= ~ICH_PCM246_MASK; 876 if (p->channels == 4) { 877 control |= ICH_PCM4; 878 } else if (p->channels == 6) { 879 control |= ICH_PCM6; 880 } 881 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_GCTRL, control); 882 } 883 } 884 885 return (0); 886 } 887 888 int 889 auich_round_blocksize(void *v, int blk) 890 { 891 892 return (blk & ~0x3f); /* keep good alignment */ 893 } 894 895 int 896 auich_halt_output(void *v) 897 { 898 struct auich_softc *sc = v; 899 900 DPRINTF(ICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname)); 901 902 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, ICH_RR); 903 sc->sc_pintr = NULL; 904 905 return (0); 906 } 907 908 int 909 auich_halt_input(void *v) 910 { 911 struct auich_softc *sc = v; 912 913 DPRINTF(ICH_DEBUG_DMA, 914 ("%s: halt_input\n", sc->sc_dev.dv_xname)); 915 916 /* XXX halt both unless known otherwise */ 917 918 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 919 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_MICI + ICH_CTRL, ICH_RR); 920 sc->sc_rintr = NULL; 921 922 return (0); 923 } 924 925 int 926 auich_getdev(void *v, struct audio_device *adp) 927 { 928 struct auich_softc *sc = v; 929 930 *adp = sc->sc_audev; 931 return (0); 932 } 933 934 int 935 auich_set_port(void *v, mixer_ctrl_t *cp) 936 { 937 struct auich_softc *sc = v; 938 939 return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp)); 940 } 941 942 int 943 auich_get_port(void *v, mixer_ctrl_t *cp) 944 { 945 struct auich_softc *sc = v; 946 947 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp)); 948 } 949 950 int 951 auich_query_devinfo(void *v, mixer_devinfo_t *dp) 952 { 953 struct auich_softc *sc = v; 954 955 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp)); 956 } 957 958 void * 959 auich_allocm(void *v, int direction, size_t size, struct malloc_type *pool, 960 int flags) 961 { 962 struct auich_softc *sc = v; 963 struct auich_dma *p; 964 int error; 965 966 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 967 return (NULL); 968 969 p = malloc(sizeof(*p), pool, flags|M_ZERO); 970 if (p == NULL) 971 return (NULL); 972 973 error = auich_allocmem(sc, size, 0, p); 974 if (error) { 975 free(p, pool); 976 return (NULL); 977 } 978 979 p->next = sc->sc_dmas; 980 sc->sc_dmas = p; 981 982 return (KERNADDR(p)); 983 } 984 985 void 986 auich_freem(void *v, void *ptr, struct malloc_type *pool) 987 { 988 struct auich_softc *sc = v; 989 struct auich_dma *p, **pp; 990 991 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 992 if (KERNADDR(p) == ptr) { 993 auich_freemem(sc, p); 994 *pp = p->next; 995 free(p, pool); 996 return; 997 } 998 } 999 } 1000 1001 size_t 1002 auich_round_buffersize(void *v, int direction, size_t size) 1003 { 1004 1005 if (size > (ICH_DMALIST_MAX * ICH_DMASEG_MAX)) 1006 size = ICH_DMALIST_MAX * ICH_DMASEG_MAX; 1007 1008 return size; 1009 } 1010 1011 paddr_t 1012 auich_mappage(void *v, void *mem, off_t off, int prot) 1013 { 1014 struct auich_softc *sc = v; 1015 struct auich_dma *p; 1016 1017 if (off < 0) 1018 return (-1); 1019 1020 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1021 ; 1022 if (!p) 1023 return (-1); 1024 return (bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs, 1025 off, prot, BUS_DMA_WAITOK)); 1026 } 1027 1028 int 1029 auich_get_props(void *v) 1030 { 1031 struct auich_softc *sc = v; 1032 int props; 1033 1034 props = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1035 /* 1036 * Even if the codec is fixed-rate, set_param() succeeds for any sample 1037 * rate because of aurateconv. Applications can't know what rate the 1038 * device can process in the case of mmap(). 1039 */ 1040 if (!IS_FIXED_RATE(sc->codec_if)) 1041 props |= AUDIO_PROP_MMAP; 1042 return props; 1043 } 1044 1045 int 1046 auich_intr(void *v) 1047 { 1048 struct auich_softc *sc = v; 1049 int ret = 0, sts, gsts, i, qptr; 1050 1051 #ifdef DIAGNOSTIC 1052 int csts; 1053 #endif 1054 1055 #ifdef DIAGNOSTIC 1056 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1057 if (csts & PCI_STATUS_MASTER_ABORT) { 1058 printf("auich_intr: PCI master abort\n"); 1059 } 1060 #endif 1061 1062 gsts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_GSTS); 1063 DPRINTF(ICH_DEBUG_DMA, ("auich_intr: gsts=0x%x\n", gsts)); 1064 1065 if (gsts & ICH_POINT) { 1066 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMO+sc->sc_sts_reg); 1067 DPRINTF(ICH_DEBUG_DMA, 1068 ("auich_intr: osts=0x%x\n", sts)); 1069 1070 if (sts & ICH_FIFOE) { 1071 printf("%s: fifo underrun # %u\n", 1072 sc->sc_dev.dv_xname, ++sc->pcmo_fifoe); 1073 } 1074 1075 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CIV); 1076 if (sts & (ICH_LVBCI | ICH_CELV)) { 1077 struct auich_dmalist *q; 1078 1079 qptr = sc->ptr_pcmo; 1080 1081 while (qptr != i) { 1082 q = &sc->dmalist_pcmo[qptr]; 1083 1084 q->base = sc->pcmo_p; 1085 q->len = (sc->pcmo_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1086 DPRINTF(ICH_DEBUG_DMA, 1087 ("auich_intr: %p, %p = %x @ 0x%x\n", 1088 &sc->dmalist_pcmo[i], q, 1089 sc->pcmo_blksize / 2, sc->pcmo_p)); 1090 1091 sc->pcmo_p += sc->pcmo_blksize; 1092 if (sc->pcmo_p >= sc->pcmo_end) 1093 sc->pcmo_p = sc->pcmo_start; 1094 1095 if (++qptr == ICH_DMALIST_MAX) 1096 qptr = 0; 1097 } 1098 1099 sc->ptr_pcmo = qptr; 1100 bus_space_write_1(sc->iot, sc->aud_ioh, 1101 ICH_PCMO + ICH_LVI, 1102 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1103 } 1104 1105 if (sts & ICH_BCIS && sc->sc_pintr) 1106 sc->sc_pintr(sc->sc_parg); 1107 1108 /* int ack */ 1109 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMO + sc->sc_sts_reg, 1110 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1111 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_POINT); 1112 ret++; 1113 } 1114 1115 if (gsts & ICH_PIINT) { 1116 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_PCMI+sc->sc_sts_reg); 1117 DPRINTF(ICH_DEBUG_DMA, 1118 ("auich_intr: ists=0x%x\n", sts)); 1119 1120 if (sts & ICH_FIFOE) { 1121 printf("%s: fifo overrun # %u\n", 1122 sc->sc_dev.dv_xname, ++sc->pcmi_fifoe); 1123 } 1124 1125 i = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1126 if (sts & (ICH_LVBCI | ICH_CELV)) { 1127 struct auich_dmalist *q; 1128 1129 qptr = sc->ptr_pcmi; 1130 1131 while (qptr != i) { 1132 q = &sc->dmalist_pcmi[qptr]; 1133 1134 q->base = sc->pcmi_p; 1135 q->len = (sc->pcmi_blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1136 DPRINTF(ICH_DEBUG_DMA, 1137 ("auich_intr: %p, %p = %x @ 0x%x\n", 1138 &sc->dmalist_pcmi[i], q, 1139 sc->pcmi_blksize / 2, sc->pcmi_p)); 1140 1141 sc->pcmi_p += sc->pcmi_blksize; 1142 if (sc->pcmi_p >= sc->pcmi_end) 1143 sc->pcmi_p = sc->pcmi_start; 1144 1145 if (++qptr == ICH_DMALIST_MAX) 1146 qptr = 0; 1147 } 1148 1149 sc->ptr_pcmi = qptr; 1150 bus_space_write_1(sc->iot, sc->aud_ioh, 1151 ICH_PCMI + ICH_LVI, 1152 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1153 } 1154 1155 if (sts & ICH_BCIS && sc->sc_rintr) 1156 sc->sc_rintr(sc->sc_rarg); 1157 1158 /* int ack */ 1159 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_PCMI + sc->sc_sts_reg, 1160 sts & (ICH_LVBCI | ICH_CELV | ICH_BCIS | ICH_FIFOE)); 1161 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_PIINT); 1162 ret++; 1163 } 1164 1165 if (gsts & ICH_MIINT) { 1166 sts = bus_space_read_2(sc->iot, sc->aud_ioh, ICH_MICI+sc->sc_sts_reg); 1167 DPRINTF(ICH_DEBUG_DMA, 1168 ("auich_intr: ists=0x%x\n", sts)); 1169 if (sts & ICH_FIFOE) 1170 printf("%s: fifo overrun\n", sc->sc_dev.dv_xname); 1171 1172 /* TODO mic input DMA */ 1173 1174 bus_space_write_2(sc->iot, sc->aud_ioh, ICH_GSTS, ICH_MIINT); 1175 } 1176 1177 return ret; 1178 } 1179 1180 int 1181 auich_trigger_output(void *v, void *start, void *end, int blksize, 1182 void (*intr)(void *), void *arg, struct audio_params *param) 1183 { 1184 struct auich_softc *sc = v; 1185 struct auich_dmalist *q; 1186 struct auich_dma *p; 1187 size_t size; 1188 #ifdef DIAGNOSTIC 1189 int csts; 1190 #endif 1191 1192 DPRINTF(ICH_DEBUG_DMA, 1193 ("auich_trigger_output(%p, %p, %d, %p, %p, %p)\n", 1194 start, end, blksize, intr, arg, param)); 1195 1196 sc->sc_pintr = intr; 1197 sc->sc_parg = arg; 1198 #ifdef DIAGNOSTIC 1199 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1200 if (csts & PCI_STATUS_MASTER_ABORT) { 1201 printf("auich_trigger_output: PCI master abort\n"); 1202 } 1203 #endif 1204 1205 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1206 ; 1207 if (!p) { 1208 printf("auich_trigger_output: bad addr %p\n", start); 1209 return (EINVAL); 1210 } 1211 1212 size = (size_t)((caddr_t)end - (caddr_t)start); 1213 1214 /* 1215 * The logic behind this is: 1216 * setup one buffer to play, then LVI dump out the rest 1217 * to the scatter-gather chain. 1218 */ 1219 sc->pcmo_start = DMAADDR(p); 1220 sc->pcmo_p = sc->pcmo_start + blksize; 1221 sc->pcmo_end = sc->pcmo_start + size; 1222 sc->pcmo_blksize = blksize; 1223 1224 sc->ptr_pcmo = 0; 1225 q = &sc->dmalist_pcmo[sc->ptr_pcmo]; 1226 q->base = sc->pcmo_start; 1227 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1228 if (++sc->ptr_pcmo == ICH_DMALIST_MAX) 1229 sc->ptr_pcmo = 0; 1230 1231 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_BDBAR, 1232 sc->sc_cddma + ICH_PCMO_OFF(0)); 1233 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_CTRL, 1234 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1235 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMO + ICH_LVI, 1236 (sc->ptr_pcmo - 1) & ICH_LVI_MASK); 1237 1238 return (0); 1239 } 1240 1241 int 1242 auich_trigger_input(v, start, end, blksize, intr, arg, param) 1243 void *v; 1244 void *start, *end; 1245 int blksize; 1246 void (*intr)(void *); 1247 void *arg; 1248 struct audio_params *param; 1249 { 1250 struct auich_softc *sc = v; 1251 struct auich_dmalist *q; 1252 struct auich_dma *p; 1253 size_t size; 1254 #ifdef DIAGNOSTIC 1255 int csts; 1256 #endif 1257 1258 DPRINTF(ICH_DEBUG_DMA, 1259 ("auich_trigger_input(%p, %p, %d, %p, %p, %p)\n", 1260 start, end, blksize, intr, arg, param)); 1261 1262 sc->sc_rintr = intr; 1263 sc->sc_rarg = arg; 1264 1265 #ifdef DIAGNOSTIC 1266 csts = pci_conf_read(sc->sc_pc, sc->sc_pt, PCI_COMMAND_STATUS_REG); 1267 if (csts & PCI_STATUS_MASTER_ABORT) { 1268 printf("auich_trigger_input: PCI master abort\n"); 1269 } 1270 #endif 1271 1272 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 1273 ; 1274 if (!p) { 1275 printf("auich_trigger_input: bad addr %p\n", start); 1276 return (EINVAL); 1277 } 1278 1279 size = (size_t)((caddr_t)end - (caddr_t)start); 1280 1281 /* 1282 * The logic behind this is: 1283 * setup one buffer to play, then LVI dump out the rest 1284 * to the scatter-gather chain. 1285 */ 1286 sc->pcmi_start = DMAADDR(p); 1287 sc->pcmi_p = sc->pcmi_start + blksize; 1288 sc->pcmi_end = sc->pcmi_start + size; 1289 sc->pcmi_blksize = blksize; 1290 1291 sc->ptr_pcmi = 0; 1292 q = &sc->dmalist_pcmi[sc->ptr_pcmi]; 1293 q->base = sc->pcmi_start; 1294 q->len = (blksize / sc->sc_sample_size) | ICH_DMAF_IOC; 1295 if (++sc->ptr_pcmi == ICH_DMALIST_MAX) 1296 sc->ptr_pcmi = 0; 1297 1298 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1299 sc->sc_cddma + ICH_PCMI_OFF(0)); 1300 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 1301 ICH_IOCE | ICH_FEIE | ICH_LVBIE | ICH_RPBM); 1302 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1303 (sc->ptr_pcmi - 1) & ICH_LVI_MASK); 1304 1305 return (0); 1306 } 1307 1308 int 1309 auich_allocmem(struct auich_softc *sc, size_t size, size_t align, 1310 struct auich_dma *p) 1311 { 1312 int error; 1313 1314 p->size = size; 1315 error = bus_dmamem_alloc(sc->dmat, p->size, align, 0, 1316 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 1317 &p->nsegs, BUS_DMA_NOWAIT); 1318 if (error) 1319 return (error); 1320 1321 error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size, 1322 &p->addr, BUS_DMA_NOWAIT|sc->sc_dmamap_flags); 1323 if (error) 1324 goto free; 1325 1326 error = bus_dmamap_create(sc->dmat, p->size, 1, p->size, 1327 0, BUS_DMA_NOWAIT, &p->map); 1328 if (error) 1329 goto unmap; 1330 1331 error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, NULL, 1332 BUS_DMA_NOWAIT); 1333 if (error) 1334 goto destroy; 1335 return (0); 1336 1337 destroy: 1338 bus_dmamap_destroy(sc->dmat, p->map); 1339 unmap: 1340 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1341 free: 1342 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1343 return (error); 1344 } 1345 1346 int 1347 auich_freemem(struct auich_softc *sc, struct auich_dma *p) 1348 { 1349 1350 bus_dmamap_unload(sc->dmat, p->map); 1351 bus_dmamap_destroy(sc->dmat, p->map); 1352 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 1353 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 1354 return (0); 1355 } 1356 1357 int 1358 auich_alloc_cdata(struct auich_softc *sc) 1359 { 1360 bus_dma_segment_t seg; 1361 int error, rseg; 1362 1363 /* 1364 * Allocate the control data structure, and create and load the 1365 * DMA map for it. 1366 */ 1367 if ((error = bus_dmamem_alloc(sc->dmat, 1368 sizeof(struct auich_cdata), 1369 PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) { 1370 printf("%s: unable to allocate control data, error = %d\n", 1371 sc->sc_dev.dv_xname, error); 1372 goto fail_0; 1373 } 1374 1375 if ((error = bus_dmamem_map(sc->dmat, &seg, rseg, 1376 sizeof(struct auich_cdata), 1377 (caddr_t *) &sc->sc_cdata, 1378 sc->sc_dmamap_flags)) != 0) { 1379 printf("%s: unable to map control data, error = %d\n", 1380 sc->sc_dev.dv_xname, error); 1381 goto fail_1; 1382 } 1383 1384 if ((error = bus_dmamap_create(sc->dmat, sizeof(struct auich_cdata), 1, 1385 sizeof(struct auich_cdata), 0, 0, 1386 &sc->sc_cddmamap)) != 0) { 1387 printf("%s: unable to create control data DMA map, " 1388 "error = %d\n", sc->sc_dev.dv_xname, error); 1389 goto fail_2; 1390 } 1391 1392 if ((error = bus_dmamap_load(sc->dmat, sc->sc_cddmamap, 1393 sc->sc_cdata, sizeof(struct auich_cdata), 1394 NULL, 0)) != 0) { 1395 printf("%s: unable tp load control data DMA map, " 1396 "error = %d\n", sc->sc_dev.dv_xname, error); 1397 goto fail_3; 1398 } 1399 1400 return (0); 1401 1402 fail_3: 1403 bus_dmamap_destroy(sc->dmat, sc->sc_cddmamap); 1404 fail_2: 1405 bus_dmamem_unmap(sc->dmat, (caddr_t) sc->sc_cdata, 1406 sizeof(struct auich_cdata)); 1407 fail_1: 1408 bus_dmamem_free(sc->dmat, &seg, rseg); 1409 fail_0: 1410 return (error); 1411 } 1412 1413 void 1414 auich_powerhook(int why, void *addr) 1415 { 1416 struct auich_softc *sc = (struct auich_softc *)addr; 1417 1418 switch (why) { 1419 case PWR_SUSPEND: 1420 case PWR_STANDBY: 1421 /* Power down */ 1422 DPRINTF(1, ("%s: power down\n", sc->sc_dev.dv_xname)); 1423 sc->sc_suspend = why; 1424 auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_status); 1425 break; 1426 1427 case PWR_RESUME: 1428 /* Wake up */ 1429 DPRINTF(1, ("%s: power resume\n", sc->sc_dev.dv_xname)); 1430 if (sc->sc_suspend == PWR_RESUME) { 1431 printf("%s: resume without suspend.\n", 1432 sc->sc_dev.dv_xname); 1433 sc->sc_suspend = why; 1434 return; 1435 } 1436 sc->sc_suspend = why; 1437 auich_reset_codec(sc); 1438 DELAY(1000); 1439 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1440 auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_status); 1441 break; 1442 1443 case PWR_SOFTSUSPEND: 1444 case PWR_SOFTSTANDBY: 1445 case PWR_SOFTRESUME: 1446 break; 1447 } 1448 } 1449 1450 1451 /* -------------------------------------------------------------------- */ 1452 /* Calibrate card (some boards are overclocked and need scaling) */ 1453 1454 void 1455 auich_calibrate(struct auich_softc *sc) 1456 { 1457 struct timeval t1, t2; 1458 uint8_t ociv, nciv; 1459 uint64_t wait_us; 1460 uint32_t actual_48k_rate, bytes, ac97rate; 1461 void *temp_buffer; 1462 struct auich_dma *p; 1463 u_long rate; 1464 1465 /* 1466 * Grab audio from input for fixed interval and compare how 1467 * much we actually get with what we expect. Interval needs 1468 * to be sufficiently short that no interrupts are 1469 * generated. 1470 */ 1471 1472 /* Force the codec to a known state first. */ 1473 sc->codec_if->vtbl->set_clock(sc->codec_if, 48000); 1474 rate = 48000; 1475 sc->codec_if->vtbl->set_rate(sc->codec_if, AC97_REG_PCM_LR_ADC_RATE, 1476 &rate); 1477 1478 /* Setup a buffer */ 1479 bytes = 64000; 1480 temp_buffer = auich_allocm(sc, AUMODE_RECORD, bytes, M_DEVBUF, M_WAITOK); 1481 1482 for (p = sc->sc_dmas; p && KERNADDR(p) != temp_buffer; p = p->next) 1483 ; 1484 if (p == NULL) { 1485 printf("auich_calibrate: bad address %p\n", temp_buffer); 1486 return; 1487 } 1488 sc->dmalist_pcmi[0].base = DMAADDR(p); 1489 sc->dmalist_pcmi[0].len = (bytes / sc->sc_sample_size); 1490 1491 /* 1492 * our data format is stereo, 16 bit so each sample is 4 bytes. 1493 * assuming we get 48000 samples per second, we get 192000 bytes/sec. 1494 * we're going to start recording with interrupts disabled and measure 1495 * the time taken for one block to complete. we know the block size, 1496 * we know the time in microseconds, we calculate the sample rate: 1497 * 1498 * actual_rate [bps] = bytes / (time [s] * 4) 1499 * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4) 1500 * actual_rate [Hz] = (bytes * 250000) / time [us] 1501 */ 1502 1503 /* prepare */ 1504 ociv = bus_space_read_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CIV); 1505 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_BDBAR, 1506 sc->sc_cddma + ICH_PCMI_OFF(0)); 1507 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_LVI, 1508 (0 - 1) & ICH_LVI_MASK); 1509 1510 /* start */ 1511 microtime(&t1); 1512 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RPBM); 1513 1514 /* wait */ 1515 nciv = ociv; 1516 do { 1517 microtime(&t2); 1518 if (t2.tv_sec - t1.tv_sec > 1) 1519 break; 1520 nciv = bus_space_read_1(sc->iot, sc->aud_ioh, 1521 ICH_PCMI + ICH_CIV); 1522 } while (nciv == ociv); 1523 microtime(&t2); 1524 1525 /* stop */ 1526 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 0); 1527 1528 /* reset */ 1529 DELAY(100); 1530 bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RR); 1531 1532 /* turn time delta into us */ 1533 wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec; 1534 1535 auich_freem(sc, temp_buffer, M_DEVBUF); 1536 1537 if (nciv == ociv) { 1538 printf("%s: ac97 link rate calibration timed out after %" 1539 PRIu64 " us\n", sc->sc_dev.dv_xname, wait_us); 1540 return; 1541 } 1542 1543 actual_48k_rate = (bytes * UINT64_C(250000)) / wait_us; 1544 1545 if (actual_48k_rate < 50000) 1546 ac97rate = 48000; 1547 else 1548 ac97rate = ((actual_48k_rate + 500) / 1000) * 1000; 1549 1550 printf("%s: measured ac97 link rate at %d Hz", 1551 sc->sc_dev.dv_xname, actual_48k_rate); 1552 if (ac97rate != actual_48k_rate) 1553 printf(", will use %d Hz", ac97rate); 1554 printf("\n"); 1555 1556 sc->codec_if->vtbl->set_clock(sc->codec_if, ac97rate); 1557 } 1558