1 /* $OpenBSD: auich.c,v 1.37 2003/10/10 04:38:56 jason Exp $ */ 2 3 /* 4 * Copyright (c) 2000,2001 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* #define AUICH_DEBUG */ 30 /* 31 * AC'97 audio found on Intel 810/815/820/440MX chipsets. 32 * http://developer.intel.com/design/chipsets/datashts/290655.htm 33 * http://developer.intel.com/design/chipsets/manuals/298028.htm 34 * http://www.intel.com/design/chipsets/datashts/290716.htm 35 * http://www.intel.com/design/chipsets/datashts/290744.htm 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/kernel.h> 41 #include <sys/malloc.h> 42 #include <sys/device.h> 43 44 #include <dev/pci/pcidevs.h> 45 #include <dev/pci/pcivar.h> 46 47 #include <sys/audioio.h> 48 #include <dev/audio_if.h> 49 #include <dev/mulaw.h> 50 #include <dev/auconv.h> 51 52 #include <machine/bus.h> 53 54 #include <dev/ic/ac97.h> 55 56 /* 12.1.10 NAMBAR - native audio mixer base address register */ 57 #define AUICH_NAMBAR 0x10 58 /* 12.1.11 NABMBAR - native audio bus mastering base address register */ 59 #define AUICH_NABMBAR 0x14 60 61 /* table 12-3. native audio bus master control registers */ 62 #define AUICH_BDBAR 0x00 /* 8-byte aligned address */ 63 #define AUICH_CIV 0x04 /* 5 bits current index value */ 64 #define AUICH_LVI 0x05 /* 5 bits last valid index value */ 65 #define AUICH_LVI_MASK 0x1f 66 #define AUICH_STS 0x06 /* 16 bits status */ 67 #define AUICH_FIFOE 0x10 /* fifo error */ 68 #define AUICH_BCIS 0x08 /* r- buf cmplt int sts; wr ack */ 69 #define AUICH_LVBCI 0x04 /* r- last valid bci, wr ack */ 70 #define AUICH_CELV 0x02 /* current equals last valid */ 71 #define AUICH_DCH 0x01 /* dma halted */ 72 #define AUICH_ISTS_BITS "\020\01dch\02celv\03lvbci\04bcis\05fifoe" 73 #define AUICH_PICB 0x08 /* 16 bits */ 74 #define AUICH_PIV 0x0a /* 5 bits prefetched index value */ 75 #define AUICH_CTRL 0x0b /* control */ 76 #define AUICH_IOCE 0x10 /* int on completion enable */ 77 #define AUICH_FEIE 0x08 /* fifo error int enable */ 78 #define AUICH_LVBIE 0x04 /* last valid buf int enable */ 79 #define AUICH_RR 0x02 /* 1 - reset regs */ 80 #define AUICH_RPBM 0x01 /* 1 - run, 0 - pause */ 81 82 #define AUICH_PCMI 0x00 83 #define AUICH_PCMO 0x10 84 #define AUICH_MICI 0x20 85 86 #define AUICH_GCTRL 0x2c 87 #define AUICH_SSM_78 0x40000000 /* S/PDIF slots 7 and 8 */ 88 #define AUICH_SSM_69 0x80000000 /* S/PDIF slots 6 and 9 */ 89 #define AUICH_SSM_1011 0xc0000000 /* S/PDIF slots 10 and 11 */ 90 #define AUICH_POM16 0x000000 /* PCM out precision 16bit */ 91 #define AUICH_POM20 0x400000 /* PCM out precision 20bit */ 92 #define AUICH_PCM246_MASK 0x300000 93 #define AUICH_PCM2 0x000000 /* 2ch output */ 94 #define AUICH_PCM4 0x100000 /* 4ch output */ 95 #define AUICH_PCM6 0x200000 /* 6ch output */ 96 #define AUICH_S2RIE 0x40 /* int when tertiary codec resume */ 97 #define AUICH_SRIE 0x20 /* int when 2ndary codec resume */ 98 #define AUICH_PRIE 0x10 /* int when primary codec resume */ 99 #define AUICH_ACLSO 0x08 /* aclink shut off */ 100 #define AUICH_WRESET 0x04 /* warm reset */ 101 #define AUICH_CRESET 0x02 /* cold reset */ 102 #define AUICH_GIE 0x01 /* gpi int enable */ 103 #define AUICH_GSTS 0x30 104 #define AUICH_MD3 0x20000 /* pwr-dn semaphore for modem */ 105 #define AUICH_AD3 0x10000 /* pwr-dn semaphore for audio */ 106 #define AUICH_RCS 0x08000 /* read completion status */ 107 #define AUICH_B3S12 0x04000 /* bit 3 of slot 12 */ 108 #define AUICH_B2S12 0x02000 /* bit 2 of slot 12 */ 109 #define AUICH_B1S12 0x01000 /* bit 1 of slot 12 */ 110 #define AUICH_SRI 0x00800 /* secondary resume int */ 111 #define AUICH_PRI 0x00400 /* primary resume int */ 112 #define AUICH_SCR 0x00200 /* secondary codec ready */ 113 #define AUICH_PCR 0x00100 /* primary codec ready */ 114 #define AUICH_MINT 0x00080 /* mic in int */ 115 #define AUICH_POINT 0x00040 /* pcm out int */ 116 #define AUICH_PIINT 0x00020 /* pcm in int */ 117 #define AUICH_MOINT 0x00004 /* modem out int */ 118 #define AUICH_MIINT 0x00002 /* modem in int */ 119 #define AUICH_GSCI 0x00001 /* gpi status change */ 120 #define AUICH_GSTS_BITS "\020\01gsci\02miict\03moint\06piint\07point\010mint\011pcr\012scr\013pri\014sri\015b1s12\016b2s12\017b3s12\020rcs\021ad3\022md3" 121 #define AUICH_CAS 0x34 /* 1/8 bit */ 122 #define AUICH_SEMATIMO 1000 /* us */ 123 #define AUICH_RESETIMO 500000 /* us */ 124 125 /* 126 * according to the dev/audiovar.h AU_RING_SIZE is 2^16, what fits 127 * in our limits perfectly, i.e. setting it to higher value 128 * in your kernel config would improve perfomance, still 2^21 is the max 129 */ 130 #define AUICH_DMALIST_MAX 32 131 #define AUICH_DMASEG_MAX (65536*2) /* 64k samples, 2x16 bit samples */ 132 struct auich_dmalist { 133 u_int32_t base; 134 u_int32_t len; 135 #define AUICH_DMAF_IOC 0x80000000 /* 1-int on complete */ 136 #define AUICH_DMAF_BUP 0x40000000 /* 0-retrans last, 1-transmit 0 */ 137 }; 138 139 #define AUICH_FIXED_RATE 48000 140 141 struct auich_dma { 142 bus_dmamap_t map; 143 caddr_t addr; 144 bus_dma_segment_t segs[AUICH_DMALIST_MAX]; 145 int nsegs; 146 size_t size; 147 struct auich_dma *next; 148 }; 149 150 struct auich_softc { 151 struct device sc_dev; 152 void *sc_ih; 153 154 audio_device_t sc_audev; 155 156 bus_space_tag_t iot; 157 bus_space_handle_t mix_ioh; 158 bus_space_handle_t aud_ioh; 159 bus_dma_tag_t dmat; 160 161 struct ac97_codec_if *codec_if; 162 struct ac97_host_if host_if; 163 164 /* dma scatter-gather buffer lists, aligned to 8 bytes */ 165 struct auich_dmalist *dmalist_pcmo, *dmap_pcmo, 166 dmasto_pcmo[AUICH_DMALIST_MAX+1]; 167 struct auich_dmalist *dmalist_pcmi, *dmap_pcmi, 168 dmasto_pcmi[AUICH_DMALIST_MAX+1]; 169 struct auich_dmalist *dmalist_mici, *dmap_mici, 170 dmasto_mici[AUICH_DMALIST_MAX+1]; 171 /* i/o buffer pointers */ 172 u_int32_t pcmo_start, pcmo_p, pcmo_end; 173 int pcmo_blksize, pcmo_fifoe; 174 u_int32_t pcmi_start, pcmi_p, pcmi_end; 175 int pcmi_blksize, pcmi_fifoe; 176 u_int32_t mici_start, mici_p, mici_end; 177 int mici_blksize, mici_fifoe; 178 struct auich_dma *sc_dmas; 179 180 void (*sc_pintr)(void *); 181 void *sc_parg; 182 183 void (*sc_rintr)(void *); 184 void *sc_rarg; 185 186 void *powerhook; 187 int suspend; 188 u_int16_t ext_ctrl; 189 int sc_sample_size; 190 int sc_sts_reg; 191 int sc_ignore_codecready; 192 int flags; 193 int sc_ac97rate; 194 }; 195 196 #ifdef AUICH_DEBUG 197 #define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0) 198 int auich_debug = 0xfffe; 199 #define AUICH_DEBUG_CODECIO 0x0001 200 #define AUICH_DEBUG_DMA 0x0002 201 #define AUICH_DEBUG_PARAM 0x0004 202 #else 203 #define DPRINTF(x,y) /* nothing */ 204 #endif 205 206 struct cfdriver auich_cd = { 207 NULL, "auich", DV_DULL 208 }; 209 210 int auich_match(struct device *, void *, void *); 211 void auich_attach(struct device *, struct device *, void *); 212 int auich_intr(void *); 213 214 struct cfattach auich_ca = { 215 sizeof(struct auich_softc), auich_match, auich_attach 216 }; 217 218 static const struct auich_devtype { 219 int vendor; 220 int product; 221 int options; 222 char name[8]; 223 } auich_devices[] = { 224 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_ACA, 0, "ICH" }, 225 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_ACA, 0, "ICH0" }, 226 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_ACA, 0, "ICH2" }, 227 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_ACA, 0, "ICH3" }, 228 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_ACA, 0, "ICH4" }, 229 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_ACA, 0, "ICH5" }, 230 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX_ACA, 0, "440MX" }, 231 { PCI_VENDOR_SIS, PCI_PRODUCT_SIS_7012_ACA, 0, "SiS7012" }, 232 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE_ACA, 0, "nForce" }, 233 { PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_ACA, 0, "nForce2" }, 234 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PBC768_ACA, 0, "AMD768" }, 235 { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_8111_ACA, 0, "AMD8111" }, 236 }; 237 238 int auich_open(void *, int); 239 void auich_close(void *); 240 int auich_query_encoding(void *, struct audio_encoding *); 241 int auich_set_params(void *, int, int, struct audio_params *, 242 struct audio_params *); 243 int auich_round_blocksize(void *, int); 244 int auich_halt_output(void *); 245 int auich_halt_input(void *); 246 int auich_getdev(void *, struct audio_device *); 247 int auich_set_port(void *, mixer_ctrl_t *); 248 int auich_get_port(void *, mixer_ctrl_t *); 249 int auich_query_devinfo(void *, mixer_devinfo_t *); 250 void *auich_allocm(void *, int, size_t, int, int); 251 void auich_freem(void *, void *, int); 252 size_t auich_round_buffersize(void *, int, size_t); 253 paddr_t auich_mappage(void *, void *, off_t, int); 254 int auich_get_props(void *); 255 int auich_trigger_output(void *, void *, void *, int, void (*)(void *), 256 void *, struct audio_params *); 257 int auich_trigger_input(void *, void *, void *, int, void (*)(void *), 258 void *, struct audio_params *); 259 260 void auich_powerhook(int, void *); 261 262 struct audio_hw_if auich_hw_if = { 263 auich_open, 264 auich_close, 265 NULL, /* drain */ 266 auich_query_encoding, 267 auich_set_params, 268 auich_round_blocksize, 269 NULL, /* commit_setting */ 270 NULL, /* init_output */ 271 NULL, /* init_input */ 272 NULL, /* start_output */ 273 NULL, /* start_input */ 274 auich_halt_output, 275 auich_halt_input, 276 NULL, /* speaker_ctl */ 277 auich_getdev, 278 NULL, /* getfd */ 279 auich_set_port, 280 auich_get_port, 281 auich_query_devinfo, 282 auich_allocm, 283 auich_freem, 284 auich_round_buffersize, 285 auich_mappage, 286 auich_get_props, 287 auich_trigger_output, 288 auich_trigger_input 289 }; 290 291 int auich_attach_codec(void *, struct ac97_codec_if *); 292 int auich_read_codec(void *, u_int8_t, u_int16_t *); 293 int auich_write_codec(void *, u_int8_t, u_int16_t); 294 void auich_reset_codec(void *); 295 enum ac97_host_flags auich_flags_codec(void *); 296 unsigned int auich_calibrate(struct auich_softc *); 297 298 int 299 auich_match(parent, match, aux) 300 struct device *parent; 301 void *match; 302 void *aux; 303 { 304 struct pci_attach_args *pa = aux; 305 int i; 306 307 for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;) 308 if (PCI_VENDOR(pa->pa_id) == auich_devices[i].vendor && 309 PCI_PRODUCT(pa->pa_id) == auich_devices[i].product) 310 return 1; 311 312 return 0; 313 } 314 315 void 316 auich_attach(parent, self, aux) 317 struct device *parent, *self; 318 void *aux; 319 { 320 struct auich_softc *sc = (struct auich_softc *)self; 321 struct pci_attach_args *pa = aux; 322 pci_intr_handle_t ih; 323 bus_size_t mix_size, aud_size; 324 pcireg_t csr; 325 const char *intrstr; 326 u_int32_t status; 327 int i; 328 329 /* SiS 7012 needs special handling */ 330 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS && 331 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_7012_ACA) { 332 sc->sc_sts_reg = AUICH_PICB; 333 sc->sc_sample_size = 1; 334 } else { 335 sc->sc_sts_reg = AUICH_STS; 336 sc->sc_sample_size = 2; 337 } 338 339 if (pci_mapreg_map(pa, AUICH_NAMBAR, PCI_MAPREG_TYPE_IO, 0, 340 &sc->iot, &sc->mix_ioh, NULL, &mix_size, 0)) { 341 printf(": can't map codec i/o space\n"); 342 return; 343 } 344 if (pci_mapreg_map(pa, AUICH_NABMBAR, PCI_MAPREG_TYPE_IO, 0, 345 &sc->iot, &sc->aud_ioh, NULL, &aud_size, 0)) { 346 printf(": can't map device i/o space\n"); 347 bus_space_unmap(sc->iot, sc->mix_ioh, mix_size); 348 return; 349 } 350 sc->dmat = pa->pa_dmat; 351 352 /* enable bus mastering (should not it be mi?) */ 353 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 354 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 355 csr | PCI_COMMAND_MASTER_ENABLE); 356 357 if (pci_intr_map(pa, &ih)) { 358 printf(": can't map interrupt\n"); 359 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size); 360 bus_space_unmap(sc->iot, sc->mix_ioh, mix_size); 361 return; 362 } 363 intrstr = pci_intr_string(pa->pa_pc, ih); 364 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, auich_intr, 365 sc, sc->sc_dev.dv_xname); 366 if (!sc->sc_ih) { 367 printf(": can't establish interrupt"); 368 if (intrstr) 369 printf(" at %s", intrstr); 370 printf("\n"); 371 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size); 372 bus_space_unmap(sc->iot, sc->mix_ioh, mix_size); 373 return; 374 } 375 376 for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;) 377 if (PCI_PRODUCT(pa->pa_id) == auich_devices[i].product) 378 break; 379 380 snprintf(sc->sc_audev.name, sizeof sc->sc_audev.name, "%s AC97", 381 auich_devices[i].name); 382 snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x", 383 PCI_REVISION(pa->pa_class)); 384 strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname, 385 sizeof sc->sc_audev.config); 386 387 printf(": %s, %s\n", intrstr, sc->sc_audev.name); 388 389 /* allocate dma lists */ 390 #define a(a) (void *)(((u_long)(a) + sizeof(*(a)) - 1) & ~(sizeof(*(a))-1)) 391 sc->dmalist_pcmo = sc->dmap_pcmo = a(sc->dmasto_pcmo); 392 sc->dmalist_pcmi = sc->dmap_pcmi = a(sc->dmasto_pcmi); 393 sc->dmalist_mici = sc->dmap_mici = a(sc->dmasto_mici); 394 #undef a 395 DPRINTF(AUICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n", 396 sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici)); 397 398 /* Reset codec and AC'97 */ 399 auich_reset_codec(sc); 400 status = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS); 401 if (!(status & AUICH_PCR)) { /* reset failure */ 402 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && 403 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA) { 404 /* MSI 845G Max never return AUICH_PCR */ 405 sc->sc_ignore_codecready = 1; 406 } else 407 return; 408 } 409 410 sc->host_if.arg = sc; 411 sc->host_if.attach = auich_attach_codec; 412 sc->host_if.read = auich_read_codec; 413 sc->host_if.write = auich_write_codec; 414 sc->host_if.reset = auich_reset_codec; 415 sc->host_if.flags = auich_flags_codec; 416 if (sc->sc_dev.dv_cfdata->cf_flags & 0x0001) 417 sc->flags = AC97_HOST_SWAPPED_CHANNELS; 418 419 if (ac97_attach(&sc->host_if) != 0) { 420 pci_intr_disestablish(pa->pa_pc, sc->sc_ih); 421 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size); 422 bus_space_unmap(sc->iot, sc->mix_ioh, mix_size); 423 return; 424 } 425 426 audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev); 427 428 /* Watch for power changes */ 429 sc->suspend = PWR_RESUME; 430 sc->powerhook = powerhook_establish(auich_powerhook, sc); 431 432 sc->sc_ac97rate = auich_calibrate(sc); 433 } 434 435 int 436 auich_read_codec(v, reg, val) 437 void *v; 438 u_int8_t reg; 439 u_int16_t *val; 440 { 441 struct auich_softc *sc = v; 442 int i; 443 444 /* wait for an access semaphore */ 445 for (i = AUICH_SEMATIMO; i-- && 446 bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1)); 447 448 if (!sc->sc_ignore_codecready && i < 0) { 449 DPRINTF(AUICH_DEBUG_CODECIO, 450 ("%s: read_codec timeout\n", sc->sc_dev.dv_xname)); 451 return (-1); 452 } 453 454 *val = bus_space_read_2(sc->iot, sc->mix_ioh, reg); 455 DPRINTF(AUICH_DEBUG_CODECIO, ("%s: read_codec(%x, %x)\n", 456 sc->sc_dev.dv_xname, reg, *val)); 457 return (0); 458 } 459 460 int 461 auich_write_codec(v, reg, val) 462 void *v; 463 u_int8_t reg; 464 u_int16_t val; 465 { 466 struct auich_softc *sc = v; 467 int i; 468 469 /* wait for an access semaphore */ 470 for (i = AUICH_SEMATIMO; i-- && 471 bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1)); 472 473 if (sc->sc_ignore_codecready || i >= 0) { 474 DPRINTF(AUICH_DEBUG_CODECIO, ("%s: write_codec(%x, %x)\n", 475 sc->sc_dev.dv_xname, reg, val)); 476 bus_space_write_2(sc->iot, sc->mix_ioh, reg, val); 477 return (0); 478 } else { 479 DPRINTF(AUICH_DEBUG_CODECIO, 480 ("%s: write_codec timeout\n", sc->sc_dev.dv_xname)); 481 return (-1); 482 } 483 } 484 485 int 486 auich_attach_codec(v, cif) 487 void *v; 488 struct ac97_codec_if *cif; 489 { 490 struct auich_softc *sc = v; 491 492 sc->codec_if = cif; 493 return 0; 494 } 495 496 void 497 auich_reset_codec(v) 498 void *v; 499 { 500 struct auich_softc *sc = v; 501 u_int32_t control; 502 int i; 503 504 control = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GCTRL); 505 control &= ~(AUICH_ACLSO | AUICH_PCM246_MASK); 506 control |= (control & AUICH_CRESET) ? AUICH_WRESET : AUICH_CRESET; 507 bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GCTRL, AUICH_CRESET); 508 509 for (i = AUICH_RESETIMO; i-- && 510 !(bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS) & AUICH_PCR); 511 DELAY(1)); 512 513 if (i < 0) 514 DPRINTF(AUICH_DEBUG_CODECIO, 515 ("%s: reset_codec timeout\n", sc->sc_dev.dv_xname)); 516 } 517 518 enum ac97_host_flags 519 auich_flags_codec(void *v) 520 { 521 struct auich_softc *sc = v; 522 523 return (sc->flags); 524 } 525 526 int 527 auich_open(v, flags) 528 void *v; 529 int flags; 530 { 531 return 0; 532 } 533 534 void 535 auich_close(v) 536 void *v; 537 { 538 } 539 540 int 541 auich_query_encoding(v, aep) 542 void *v; 543 struct audio_encoding *aep; 544 { 545 switch (aep->index) { 546 case 0: 547 strlcpy(aep->name, AudioEulinear, sizeof aep->name); 548 aep->encoding = AUDIO_ENCODING_ULINEAR; 549 aep->precision = 8; 550 aep->flags = 0; 551 return (0); 552 case 1: 553 strlcpy(aep->name, AudioEmulaw, sizeof aep->name); 554 aep->encoding = AUDIO_ENCODING_ULAW; 555 aep->precision = 8; 556 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 557 return (0); 558 case 2: 559 strlcpy(aep->name, AudioEalaw, sizeof aep->name); 560 aep->encoding = AUDIO_ENCODING_ALAW; 561 aep->precision = 8; 562 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 563 return (0); 564 case 3: 565 strlcpy(aep->name, AudioEslinear, sizeof aep->name); 566 aep->encoding = AUDIO_ENCODING_SLINEAR; 567 aep->precision = 8; 568 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 569 return (0); 570 case 4: 571 strlcpy(aep->name, AudioEslinear_le, sizeof aep->name); 572 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 573 aep->precision = 16; 574 aep->flags = 0; 575 return (0); 576 case 5: 577 strlcpy(aep->name, AudioEulinear_le, sizeof aep->name); 578 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 579 aep->precision = 16; 580 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 581 return (0); 582 case 6: 583 strlcpy(aep->name, AudioEslinear_be, sizeof aep->name); 584 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 585 aep->precision = 16; 586 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 587 return (0); 588 case 7: 589 strlcpy(aep->name, AudioEulinear_be, sizeof aep->name); 590 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 591 aep->precision = 16; 592 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 593 return (0); 594 default: 595 return (EINVAL); 596 } 597 } 598 599 int 600 auich_set_params(v, setmode, usemode, play, rec) 601 void *v; 602 int setmode, usemode; 603 struct audio_params *play, *rec; 604 { 605 struct auich_softc *sc = v; 606 int error; 607 u_int orate; 608 609 if (setmode & AUMODE_PLAY) { 610 play->factor = 1; 611 play->sw_code = NULL; 612 switch(play->encoding) { 613 case AUDIO_ENCODING_ULAW: 614 switch (play->channels) { 615 case 1: 616 play->factor = 4; 617 play->sw_code = mulaw_to_slinear16_mts; 618 break; 619 case 2: 620 play->factor = 2; 621 play->sw_code = mulaw_to_slinear16; 622 break; 623 default: 624 return (EINVAL); 625 } 626 break; 627 case AUDIO_ENCODING_SLINEAR_LE: 628 switch (play->precision) { 629 case 8: 630 switch (play->channels) { 631 case 1: 632 play->factor = 4; 633 play->sw_code = linear8_to_linear16_mts; 634 break; 635 case 2: 636 play->factor = 2; 637 play->sw_code = linear8_to_linear16; 638 break; 639 default: 640 return (EINVAL); 641 } 642 break; 643 case 16: 644 switch (play->channels) { 645 case 1: 646 play->factor = 2; 647 play->sw_code = noswap_bytes_mts; 648 break; 649 case 2: 650 break; 651 default: 652 return (EINVAL); 653 } 654 break; 655 default: 656 return (EINVAL); 657 } 658 break; 659 case AUDIO_ENCODING_ULINEAR_LE: 660 switch (play->precision) { 661 case 8: 662 switch (play->channels) { 663 case 1: 664 play->factor = 4; 665 play->sw_code = ulinear8_to_linear16_mts; 666 break; 667 case 2: 668 play->factor = 2; 669 play->sw_code = ulinear8_to_linear16; 670 break; 671 default: 672 return (EINVAL); 673 } 674 break; 675 case 16: 676 switch (play->channels) { 677 case 1: 678 play->factor = 2; 679 play->sw_code = change_sign16_mts; 680 break; 681 case 2: 682 play->sw_code = change_sign16; 683 break; 684 default: 685 return (EINVAL); 686 } 687 break; 688 default: 689 return (EINVAL); 690 } 691 break; 692 case AUDIO_ENCODING_ALAW: 693 switch (play->channels) { 694 case 1: 695 play->factor = 4; 696 play->sw_code = alaw_to_slinear16_mts; 697 case 2: 698 play->factor = 2; 699 play->sw_code = alaw_to_slinear16; 700 default: 701 return (EINVAL); 702 } 703 break; 704 case AUDIO_ENCODING_SLINEAR_BE: 705 switch (play->precision) { 706 case 8: 707 switch (play->channels) { 708 case 1: 709 play->factor = 4; 710 play->sw_code = linear8_to_linear16_mts; 711 break; 712 case 2: 713 play->factor = 2; 714 play->sw_code = linear8_to_linear16; 715 break; 716 default: 717 return (EINVAL); 718 } 719 break; 720 case 16: 721 switch (play->channels) { 722 case 1: 723 play->factor = 2; 724 play->sw_code = swap_bytes_mts; 725 break; 726 case 2: 727 play->sw_code = swap_bytes; 728 break; 729 default: 730 return (EINVAL); 731 } 732 break; 733 default: 734 return (EINVAL); 735 } 736 break; 737 case AUDIO_ENCODING_ULINEAR_BE: 738 switch (play->precision) { 739 case 8: 740 switch (play->channels) { 741 case 1: 742 play->factor = 4; 743 play->sw_code = ulinear8_to_linear16_mts; 744 break; 745 case 2: 746 play->factor = 2; 747 play->sw_code = ulinear8_to_linear16; 748 break; 749 default: 750 return (EINVAL); 751 } 752 break; 753 case 16: 754 switch (play->channels) { 755 case 1: 756 play->factor = 2; 757 play->sw_code = change_sign16_swap_bytes_mts; 758 break; 759 case 2: 760 play->sw_code = change_sign16_swap_bytes; 761 break; 762 default: 763 return (EINVAL); 764 } 765 break; 766 default: 767 return (EINVAL); 768 } 769 break; 770 default: 771 return (EINVAL); 772 } 773 774 orate = play->sample_rate; 775 if (sc->sc_ac97rate != 0) 776 play->sample_rate = orate * AUICH_FIXED_RATE / 777 sc->sc_ac97rate; 778 error = ac97_set_rate(sc->codec_if, play, AUMODE_PLAY); 779 play->sample_rate = orate; 780 if (error) 781 return (error); 782 } 783 784 if (setmode & AUMODE_RECORD) { 785 rec->factor = 1; 786 rec->sw_code = 0; 787 switch(rec->encoding) { 788 case AUDIO_ENCODING_ULAW: 789 rec->sw_code = ulinear8_to_mulaw; 790 break; 791 case AUDIO_ENCODING_SLINEAR_LE: 792 if (rec->precision == 8) 793 rec->sw_code = change_sign8; 794 break; 795 case AUDIO_ENCODING_ULINEAR_LE: 796 if (rec->precision == 16) 797 rec->sw_code = change_sign16; 798 break; 799 case AUDIO_ENCODING_ALAW: 800 rec->sw_code = ulinear8_to_alaw; 801 break; 802 case AUDIO_ENCODING_SLINEAR_BE: 803 if (rec->precision == 16) 804 rec->sw_code = swap_bytes; 805 else 806 rec->sw_code = change_sign8; 807 break; 808 case AUDIO_ENCODING_ULINEAR_BE: 809 if (rec->precision == 16) 810 rec->sw_code = swap_bytes_change_sign16; 811 break; 812 default: 813 return (EINVAL); 814 } 815 816 orate = rec->sample_rate; 817 if (sc->sc_ac97rate != 0) 818 rec->sample_rate = orate * AUICH_FIXED_RATE / 819 sc->sc_ac97rate; 820 error = ac97_set_rate(sc->codec_if, rec, AUMODE_RECORD); 821 rec->sample_rate = orate; 822 if (error) 823 return (error); 824 } 825 826 return (0); 827 } 828 829 int 830 auich_round_blocksize(v, blk) 831 void *v; 832 int blk; 833 { 834 return blk & ~0x3f; 835 } 836 837 int 838 auich_halt_output(v) 839 void *v; 840 { 841 struct auich_softc *sc = v; 842 843 DPRINTF(AUICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname)); 844 845 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL, AUICH_RR); 846 847 return 0; 848 } 849 850 int 851 auich_halt_input(v) 852 void *v; 853 { 854 struct auich_softc *sc = v; 855 856 DPRINTF(AUICH_DEBUG_DMA, 857 ("%s: halt_input\n", sc->sc_dev.dv_xname)); 858 859 /* XXX halt both unless known otherwise */ 860 861 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR); 862 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR); 863 864 return 0; 865 } 866 867 int 868 auich_getdev(v, adp) 869 void *v; 870 struct audio_device *adp; 871 { 872 struct auich_softc *sc = v; 873 *adp = sc->sc_audev; 874 return 0; 875 } 876 877 int 878 auich_set_port(v, cp) 879 void *v; 880 mixer_ctrl_t *cp; 881 { 882 struct auich_softc *sc = v; 883 return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp); 884 } 885 886 int 887 auich_get_port(v, cp) 888 void *v; 889 mixer_ctrl_t *cp; 890 { 891 struct auich_softc *sc = v; 892 return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp); 893 } 894 895 int 896 auich_query_devinfo(v, dp) 897 void *v; 898 mixer_devinfo_t *dp; 899 { 900 struct auich_softc *sc = v; 901 return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp); 902 } 903 904 void * 905 auich_allocm(v, direction, size, pool, flags) 906 void *v; 907 int direction; 908 size_t size; 909 int pool, flags; 910 { 911 struct auich_softc *sc = v; 912 struct auich_dma *p; 913 int error; 914 915 if (size > AUICH_DMALIST_MAX * AUICH_DMASEG_MAX) 916 return NULL; 917 918 p = malloc(sizeof(*p), pool, flags); 919 if (!p) 920 return NULL; 921 bzero(p, sizeof(*p)); 922 923 p->size = size; 924 if ((error = bus_dmamem_alloc(sc->dmat, p->size, NBPG, 0, p->segs, 925 1, &p->nsegs, BUS_DMA_NOWAIT)) != 0) { 926 printf("%s: unable to allocate dma, error = %d\n", 927 sc->sc_dev.dv_xname, error); 928 free(p, pool); 929 return NULL; 930 } 931 932 if ((error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size, 933 &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 934 printf("%s: unable to map dma, error = %d\n", 935 sc->sc_dev.dv_xname, error); 936 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 937 free(p, pool); 938 return NULL; 939 } 940 941 if ((error = bus_dmamap_create(sc->dmat, p->size, 1, 942 p->size, 0, BUS_DMA_NOWAIT, &p->map)) != 0) { 943 printf("%s: unable to create dma map, error = %d\n", 944 sc->sc_dev.dv_xname, error); 945 bus_dmamem_unmap(sc->dmat, p->addr, size); 946 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 947 free(p, pool); 948 return NULL; 949 } 950 951 if ((error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, 952 NULL, BUS_DMA_NOWAIT)) != 0) { 953 printf("%s: unable to load dma map, error = %d\n", 954 sc->sc_dev.dv_xname, error); 955 bus_dmamap_destroy(sc->dmat, p->map); 956 bus_dmamem_unmap(sc->dmat, p->addr, size); 957 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 958 free(p, pool); 959 return NULL; 960 } 961 962 p->next = sc->sc_dmas; 963 sc->sc_dmas = p; 964 965 return p->addr; 966 } 967 968 void 969 auich_freem(v, ptr, pool) 970 void *v; 971 void *ptr; 972 int pool; 973 { 974 struct auich_softc *sc = v; 975 struct auich_dma *p; 976 977 for (p = sc->sc_dmas; p->addr != ptr; p = p->next) 978 if (p->next == NULL) { 979 printf("auich_freem: trying to free not allocated memory"); 980 return; 981 } 982 983 bus_dmamap_unload(sc->dmat, p->map); 984 bus_dmamap_destroy(sc->dmat, p->map); 985 bus_dmamem_unmap(sc->dmat, p->addr, p->size); 986 bus_dmamem_free(sc->dmat, p->segs, p->nsegs); 987 free(p, pool); 988 } 989 990 size_t 991 auich_round_buffersize(v, direction, size) 992 void *v; 993 int direction; 994 size_t size; 995 { 996 if (size > AUICH_DMALIST_MAX * AUICH_DMASEG_MAX) 997 size = AUICH_DMALIST_MAX * AUICH_DMASEG_MAX; 998 999 return size; 1000 } 1001 1002 paddr_t 1003 auich_mappage(v, mem, off, prot) 1004 void *v; 1005 void *mem; 1006 off_t off; 1007 int prot; 1008 { 1009 struct auich_softc *sc = v; 1010 struct auich_dma *p; 1011 1012 if (off < 0) 1013 return -1; 1014 1015 for (p = sc->sc_dmas; p && p->addr != mem; p = p->next); 1016 if (!p) 1017 return -1; 1018 1019 return bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs, 1020 off, prot, BUS_DMA_WAITOK); 1021 } 1022 1023 int 1024 auich_get_props(v) 1025 void *v; 1026 { 1027 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1028 } 1029 1030 int 1031 auich_intr(v) 1032 void *v; 1033 { 1034 struct auich_softc *sc = v; 1035 int ret = 0, sts, gsts, i; 1036 1037 gsts = bus_space_read_2(sc->iot, sc->aud_ioh, AUICH_GSTS); 1038 DPRINTF(AUICH_DEBUG_DMA, ("auich_intr: gsts=%b\n", gsts, AUICH_GSTS_BITS)); 1039 1040 if (gsts & AUICH_POINT) { 1041 sts = bus_space_read_2(sc->iot, sc->aud_ioh, 1042 AUICH_PCMO + sc->sc_sts_reg); 1043 DPRINTF(AUICH_DEBUG_DMA, 1044 ("auich_intr: osts=%b\n", sts, AUICH_ISTS_BITS)); 1045 1046 if (sts & AUICH_FIFOE) { 1047 printf("%s: fifo underrun # %u\n", 1048 sc->sc_dev.dv_xname, ++sc->pcmo_fifoe); 1049 } 1050 1051 i = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CIV); 1052 if (sts & (AUICH_LVBCI | AUICH_CELV)) { 1053 struct auich_dmalist *q, *qe; 1054 1055 q = sc->dmap_pcmo; 1056 qe = &sc->dmalist_pcmo[i]; 1057 1058 while (q != qe) { 1059 1060 q->base = sc->pcmo_p; 1061 q->len = (sc->pcmo_blksize / 1062 sc->sc_sample_size) | AUICH_DMAF_IOC; 1063 DPRINTF(AUICH_DEBUG_DMA, 1064 ("auich_intr: %p, %p = %x @ %p\n", 1065 qe, q, sc->pcmo_blksize / 1066 sc->sc_sample_size, sc->pcmo_p)); 1067 1068 sc->pcmo_p += sc->pcmo_blksize; 1069 if (sc->pcmo_p >= sc->pcmo_end) 1070 sc->pcmo_p = sc->pcmo_start; 1071 1072 if (++q == &sc->dmalist_pcmo[AUICH_DMALIST_MAX]) 1073 q = sc->dmalist_pcmo; 1074 } 1075 1076 sc->dmap_pcmo = q; 1077 bus_space_write_1(sc->iot, sc->aud_ioh, 1078 AUICH_PCMO + AUICH_LVI, 1079 (sc->dmap_pcmo - sc->dmalist_pcmo - 1) & 1080 AUICH_LVI_MASK); 1081 } 1082 1083 if (sts & AUICH_BCIS && sc->sc_pintr) 1084 sc->sc_pintr(sc->sc_parg); 1085 1086 /* int ack */ 1087 bus_space_write_2(sc->iot, sc->aud_ioh, 1088 AUICH_PCMO + sc->sc_sts_reg, sts & 1089 (AUICH_LVBCI | AUICH_CELV | AUICH_BCIS | AUICH_FIFOE)); 1090 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_POINT); 1091 ret++; 1092 } 1093 1094 if (gsts & AUICH_PIINT) { 1095 sts = bus_space_read_2(sc->iot, sc->aud_ioh, 1096 AUICH_PCMI + sc->sc_sts_reg); 1097 DPRINTF(AUICH_DEBUG_DMA, 1098 ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS)); 1099 1100 if (sts & AUICH_FIFOE) { 1101 printf("%s: in fifo overrun # %u\n", 1102 sc->sc_dev.dv_xname, ++sc->pcmi_fifoe); 1103 } 1104 1105 i = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV); 1106 if (sts & (AUICH_LVBCI | AUICH_CELV)) { 1107 struct auich_dmalist *q, *qe; 1108 1109 q = sc->dmap_pcmi; 1110 qe = &sc->dmalist_pcmi[i]; 1111 1112 while (q != qe) { 1113 1114 q->base = sc->pcmi_p; 1115 q->len = (sc->pcmi_blksize / 1116 sc->sc_sample_size) | AUICH_DMAF_IOC; 1117 DPRINTF(AUICH_DEBUG_DMA, 1118 ("auich_intr: %p, %p = %x @ %p\n", 1119 qe, q, sc->pcmi_blksize / 1120 sc->sc_sample_size, sc->pcmi_p)); 1121 1122 sc->pcmi_p += sc->pcmi_blksize; 1123 if (sc->pcmi_p >= sc->pcmi_end) 1124 sc->pcmi_p = sc->pcmi_start; 1125 1126 if (++q == &sc->dmalist_pcmi[AUICH_DMALIST_MAX]) 1127 q = sc->dmalist_pcmi; 1128 } 1129 1130 sc->dmap_pcmi = q; 1131 bus_space_write_1(sc->iot, sc->aud_ioh, 1132 AUICH_PCMI + AUICH_LVI, 1133 (sc->dmap_pcmi - sc->dmalist_pcmi - 1) & 1134 AUICH_LVI_MASK); 1135 } 1136 1137 if (sts & AUICH_BCIS && sc->sc_rintr) 1138 sc->sc_rintr(sc->sc_rarg); 1139 1140 /* int ack */ 1141 bus_space_write_2(sc->iot, sc->aud_ioh, 1142 AUICH_PCMI + sc->sc_sts_reg, sts & 1143 (AUICH_LVBCI | AUICH_CELV | AUICH_BCIS | AUICH_FIFOE)); 1144 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_POINT); 1145 ret++; 1146 } 1147 1148 if (gsts & AUICH_MIINT) { 1149 sts = bus_space_read_2(sc->iot, sc->aud_ioh, 1150 AUICH_MICI + sc->sc_sts_reg); 1151 DPRINTF(AUICH_DEBUG_DMA, 1152 ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS)); 1153 if (sts & AUICH_FIFOE) 1154 printf("%s: mic fifo overrun\n", sc->sc_dev.dv_xname); 1155 1156 /* TODO mic input dma */ 1157 1158 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_MIINT); 1159 } 1160 1161 return ret; 1162 } 1163 1164 int 1165 auich_trigger_output(v, start, end, blksize, intr, arg, param) 1166 void *v; 1167 void *start, *end; 1168 int blksize; 1169 void (*intr)(void *); 1170 void *arg; 1171 struct audio_params *param; 1172 { 1173 struct auich_softc *sc = v; 1174 struct auich_dmalist *q; 1175 struct auich_dma *p; 1176 1177 DPRINTF(AUICH_DEBUG_DMA, 1178 ("auich_trigger_output(%x, %x, %d, %p, %p, %p)\n", 1179 start, end, blksize, intr, arg, param)); 1180 1181 for (p = sc->sc_dmas; p && p->addr != start; p = p->next); 1182 if (!p) 1183 return -1; 1184 1185 sc->sc_pintr = intr; 1186 sc->sc_parg = arg; 1187 1188 /* 1189 * The logic behind this is: 1190 * setup one buffer to play, then LVI dump out the rest 1191 * to the scatter-gather chain. 1192 */ 1193 sc->pcmo_start = p->segs->ds_addr; 1194 sc->pcmo_p = sc->pcmo_start + blksize; 1195 sc->pcmo_end = sc->pcmo_start + (end - start); 1196 sc->pcmo_blksize = blksize; 1197 1198 q = sc->dmap_pcmo = sc->dmalist_pcmo; 1199 q->base = sc->pcmo_start; 1200 q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC; 1201 if (++q == &sc->dmalist_pcmo[AUICH_DMALIST_MAX]) 1202 q = sc->dmalist_pcmo; 1203 sc->dmap_pcmo = q; 1204 1205 bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_BDBAR, 1206 kvtop((caddr_t)sc->dmalist_pcmo)); 1207 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL, 1208 AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM); 1209 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_LVI, 1210 (sc->dmap_pcmo - 1 - sc->dmalist_pcmo) & AUICH_LVI_MASK); 1211 1212 return 0; 1213 } 1214 1215 int 1216 auich_trigger_input(v, start, end, blksize, intr, arg, param) 1217 void *v; 1218 void *start, *end; 1219 int blksize; 1220 void (*intr)(void *); 1221 void *arg; 1222 struct audio_params *param; 1223 { 1224 struct auich_softc *sc = v; 1225 struct auich_dmalist *q; 1226 struct auich_dma *p; 1227 1228 DPRINTF(AUICH_DEBUG_DMA, 1229 ("auich_trigger_input(%x, %x, %d, %p, %p, %p)\n", 1230 start, end, blksize, intr, arg, param)); 1231 1232 for (p = sc->sc_dmas; p && p->addr != start; p = p->next); 1233 if (!p) 1234 return -1; 1235 1236 sc->sc_rintr = intr; 1237 sc->sc_rarg = arg; 1238 1239 /* 1240 * The logic behind this is: 1241 * setup one buffer to play, then LVI dump out the rest 1242 * to the scatter-gather chain. 1243 */ 1244 sc->pcmi_start = p->segs->ds_addr; 1245 sc->pcmi_p = sc->pcmi_start + blksize; 1246 sc->pcmi_end = sc->pcmi_start + (end - start); 1247 sc->pcmi_blksize = blksize; 1248 1249 q = sc->dmap_pcmi = sc->dmalist_pcmi; 1250 q->base = sc->pcmi_start; 1251 q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC; 1252 if (++q == &sc->dmalist_pcmi[AUICH_DMALIST_MAX]) 1253 q = sc->dmalist_pcmi; 1254 sc->dmap_pcmi = q; 1255 1256 bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR, 1257 kvtop((caddr_t)sc->dmalist_pcmi)); 1258 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, 1259 AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM); 1260 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI, 1261 (sc->dmap_pcmi - 1 - sc->dmalist_pcmi) & AUICH_LVI_MASK); 1262 1263 return 0; 1264 } 1265 1266 void 1267 auich_powerhook(why, self) 1268 int why; 1269 void *self; 1270 { 1271 struct auich_softc *sc = (struct auich_softc *)self; 1272 1273 if (why != PWR_RESUME) { 1274 /* Power down */ 1275 DPRINTF(1, ("auich: power down\n")); 1276 sc->suspend = why; 1277 auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_ctrl); 1278 1279 } else { 1280 /* Wake up */ 1281 DPRINTF(1, ("auich: power resume\n")); 1282 if (sc->suspend == PWR_RESUME) { 1283 printf("%s: resume without suspend?\n", 1284 sc->sc_dev.dv_xname); 1285 sc->suspend = why; 1286 return; 1287 } 1288 sc->suspend = why; 1289 auich_reset_codec(sc); 1290 DELAY(1000); 1291 (sc->codec_if->vtbl->restore_ports)(sc->codec_if); 1292 auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_ctrl); 1293 } 1294 } 1295 1296 1297 1298 /* -------------------------------------------------------------------- */ 1299 /* Calibrate card (some boards are overclocked and need scaling) */ 1300 1301 unsigned int 1302 auich_calibrate(struct auich_softc *sc) 1303 { 1304 struct timeval t1, t2; 1305 u_int8_t ociv, nciv; 1306 u_int32_t wait_us, actual_48k_rate, bytes, ac97rate; 1307 void *temp_buffer; 1308 struct auich_dma *p; 1309 int i; 1310 1311 ac97rate = AUICH_FIXED_RATE; 1312 /* 1313 * Grab audio from input for fixed interval and compare how 1314 * much we actually get with what we expect. Interval needs 1315 * to be sufficiently short that no interrupts are 1316 * generated. 1317 */ 1318 1319 /* Setup a buffer */ 1320 bytes = 16000; 1321 temp_buffer = auich_allocm(sc, AUMODE_RECORD, bytes, M_DEVBUF, 1322 M_NOWAIT); 1323 if (temp_buffer == NULL) 1324 return (ac97rate); 1325 for (p = sc->sc_dmas; p && p->addr != temp_buffer; p = p->next) 1326 ; 1327 if (p == NULL) { 1328 printf("auich_calibrate: bad address %p\n", temp_buffer); 1329 return (ac97rate); 1330 } 1331 1332 for (i = 0; i < AUICH_DMALIST_MAX; i++) { 1333 sc->dmalist_pcmi[i].base = p->map->dm_segs[0].ds_addr; 1334 sc->dmalist_pcmi[i].len = bytes / sc->sc_sample_size; 1335 } 1336 1337 /* 1338 * our data format is stereo, 16 bit so each sample is 4 bytes. 1339 * assuming we get 48000 samples per second, we get 192000 bytes/sec. 1340 * we're going to start recording with interrupts disabled and measure 1341 * the time taken for one block to complete. we know the block size, 1342 * we know the time in microseconds, we calculate the sample rate: 1343 * 1344 * actual_rate [bps] = bytes / (time [s] * 4) 1345 * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4) 1346 * actual_rate [Hz] = (bytes * 250000) / time [us] 1347 */ 1348 1349 /* prepare */ 1350 ociv = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV); 1351 nciv = ociv; 1352 bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR, 1353 kvtop((caddr_t)sc->dmalist_pcmi)); 1354 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI, 1355 (0 - 1) & AUICH_LVI_MASK); 1356 1357 /* start */ 1358 microtime(&t1); 1359 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, 1360 AUICH_RPBM); 1361 1362 /* wait */ 1363 while (nciv == ociv) { 1364 microtime(&t2); 1365 if (t2.tv_sec - t1.tv_sec > 1) 1366 break; 1367 nciv = bus_space_read_1(sc->iot, sc->aud_ioh, 1368 AUICH_PCMI + AUICH_CIV); 1369 } 1370 microtime(&t2); 1371 1372 /* reset */ 1373 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR); 1374 bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR); 1375 DELAY(100); 1376 1377 /* turn time delta into us */ 1378 wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec; 1379 1380 #if 0 1381 auich_freem(sc, temp_buffer, M_DEVBUF); 1382 #endif 1383 1384 if (nciv == ociv) { 1385 printf("%s: ac97 link rate calibration timed out after %d us\n", 1386 sc->sc_dev.dv_xname, wait_us); 1387 return (ac97rate); 1388 } 1389 1390 actual_48k_rate = (bytes * 250000) / wait_us; 1391 1392 if (actual_48k_rate <= 48500) 1393 ac97rate = AUICH_FIXED_RATE; 1394 else 1395 ac97rate = actual_48k_rate; 1396 1397 printf("%s: measured ac97 link rate at %d Hz", 1398 sc->sc_dev.dv_xname, actual_48k_rate); 1399 if (ac97rate != actual_48k_rate) 1400 printf(", will use %d Hz", ac97rate); 1401 printf("\n"); 1402 1403 return (ac97rate); 1404 } 1405