1/*- 2 * Copyright (c) 2000-2004 Taku YAMAMOTO <taku@tackymt.homeip.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * maestro.c,v 1.23.2.1 2003/10/03 18:21:38 taku Exp 27 */ 28 29/* 30 * Credits: 31 * 32 * Part of this code (especially in many magic numbers) was heavily inspired 33 * by the Linux driver originally written by 34 * Alan Cox <alan.cox@linux.org>, modified heavily by 35 * Zach Brown <zab@zabbo.net>. 36 * 37 * busdma()-ize and buffer size reduction were suggested by 38 * Cameron Grant <cg@freebsd.org>. 39 * Also he showed me the way to use busdma() suite. 40 * 41 * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500 42 * were looked at by 43 * Munehiro Matsuda <haro@tk.kubota.co.jp>, 44 * who brought patches based on the Linux driver with some simplification. 45 * 46 * Hardware volume controller was implemented by 47 * John Baldwin <jhb@freebsd.org>. 48 */ 49 50#ifdef HAVE_KERNEL_OPTION_HEADERS 51#include "opt_snd.h" 52#endif 53 54#include <dev/sound/pcm/sound.h> 55#include <dev/sound/pcm/ac97.h> 56#include <dev/pci/pcireg.h> 57#include <dev/pci/pcivar.h> 58 59#include <dev/sound/pci/maestro_reg.h> 60 61SND_DECLARE_FILE("$FreeBSD$"); 62 63/* 64 * PCI IDs of supported chips: 65 * 66 * MAESTRO-1 0x01001285 67 * MAESTRO-2 0x1968125d 68 * MAESTRO-2E 0x1978125d 69 */ 70 71#define MAESTRO_1_PCI_ID 0x01001285 72#define MAESTRO_2_PCI_ID 0x1968125d 73#define MAESTRO_2E_PCI_ID 0x1978125d 74 75#define NEC_SUBID1 0x80581033 /* Taken from Linux driver */ 76#define NEC_SUBID2 0x803c1033 /* NEC VersaProNX VA26D */ 77 78#ifdef AGG_MAXPLAYCH 79# if AGG_MAXPLAYCH > 4 80# undef AGG_MAXPLAYCH 81# define AGG_MAXPLAYCH 4 82# endif 83#else 84# define AGG_MAXPLAYCH 4 85#endif 86 87#define AGG_DEFAULT_BUFSZ 0x4000 /* 0x1000, but gets underflows */ 88 89 90/* compatibility */ 91#if __FreeBSD_version < 500000 92# define critical_enter() disable_intr() 93# define critical_exit() enable_intr() 94#endif 95 96#ifndef PCIR_BAR 97#define PCIR_BAR(x) (PCIR_MAPS + (x) * 4) 98#endif 99 100 101/* ----------------------------- 102 * Data structures. 103 */ 104struct agg_chinfo { 105 /* parent softc */ 106 struct agg_info *parent; 107 108 /* FreeBSD newpcm related */ 109 struct pcm_channel *channel; 110 struct snd_dbuf *buffer; 111 112 /* OS independent */ 113 bus_addr_t phys; /* channel buffer physical address */ 114 bus_addr_t base; /* channel buffer segment base */ 115 u_int32_t blklen; /* DMA block length in WORDs */ 116 u_int32_t buflen; /* channel buffer length in WORDs */ 117 u_int32_t speed; 118 unsigned num : 3; 119 unsigned stereo : 1; 120 unsigned qs16 : 1; /* quantum size is 16bit */ 121 unsigned us : 1; /* in unsigned format */ 122}; 123 124struct agg_rchinfo { 125 /* parent softc */ 126 struct agg_info *parent; 127 128 /* FreeBSD newpcm related */ 129 struct pcm_channel *channel; 130 struct snd_dbuf *buffer; 131 132 /* OS independent */ 133 bus_addr_t phys; /* channel buffer physical address */ 134 bus_addr_t base; /* channel buffer segment base */ 135 u_int32_t blklen; /* DMA block length in WORDs */ 136 u_int32_t buflen; /* channel buffer length in WORDs */ 137 u_int32_t speed; 138 unsigned : 3; 139 unsigned stereo : 1; 140 bus_addr_t srcphys; 141 int16_t *src; /* stereo peer buffer */ 142 int16_t *sink; /* channel buffer pointer */ 143 volatile u_int32_t hwptr; /* ready point in 16bit sample */ 144}; 145 146struct agg_info { 147 /* FreeBSD newbus related */ 148 device_t dev; 149 150 /* I wonder whether bus_space_* are in common in *BSD... */ 151 struct resource *reg; 152 int regid; 153 bus_space_tag_t st; 154 bus_space_handle_t sh; 155 156 struct resource *irq; 157 int irqid; 158 void *ih; 159 160 bus_dma_tag_t buf_dmat; 161 bus_dma_tag_t stat_dmat; 162 163 /* FreeBSD SMPng related */ 164 struct mtx lock; /* mutual exclusion */ 165 /* FreeBSD newpcm related */ 166 struct ac97_info *codec; 167 168 /* OS independent */ 169 u_int8_t *stat; /* status buffer pointer */ 170 bus_addr_t phys; /* status buffer physical address */ 171 unsigned int bufsz; /* channel buffer size in bytes */ 172 u_int playchns; 173 volatile u_int active; 174 struct agg_chinfo pch[AGG_MAXPLAYCH]; 175 struct agg_rchinfo rch; 176 volatile u_int8_t curpwr; /* current power status: D[0-3] */ 177}; 178 179 180/* ----------------------------- 181 * Sysctls for debug. 182 */ 183static unsigned int powerstate_active = PCI_POWERSTATE_D1; 184#ifdef MAESTRO_AGGRESSIVE_POWERSAVE 185static unsigned int powerstate_idle = PCI_POWERSTATE_D2; 186#else 187static unsigned int powerstate_idle = PCI_POWERSTATE_D1; 188#endif 189static unsigned int powerstate_init = PCI_POWERSTATE_D2; 190 191/* XXX: this should move to a device specific sysctl dev.pcm.X.debug.Y via 192 device_get_sysctl_*() as discussed on multimedia@ in msg-id 193 <861wujij2q.fsf@xps.des.no> */ 194static SYSCTL_NODE(_debug, OID_AUTO, maestro, CTLFLAG_RD, 0, ""); 195SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_active, CTLFLAG_RW, 196 &powerstate_active, 0, "The Dx power state when active (0-1)"); 197SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_idle, CTLFLAG_RW, 198 &powerstate_idle, 0, "The Dx power state when idle (0-2)"); 199SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_init, CTLFLAG_RW, 200 &powerstate_init, 0, 201 "The Dx power state prior to the first use (0-2)"); 202 203 204/* ----------------------------- 205 * Prototypes 206 */ 207 208static void agg_sleep(struct agg_info*, const char *wmesg, int msec); 209 210static __inline u_int32_t agg_rd(struct agg_info*, int, int size); 211static __inline void agg_wr(struct agg_info*, int, u_int32_t data, 212 int size); 213static int agg_rdcodec(struct agg_info*, int); 214static int agg_wrcodec(struct agg_info*, int, u_int32_t); 215 216static void ringbus_setdest(struct agg_info*, int, int); 217 218static u_int16_t wp_rdreg(struct agg_info*, u_int16_t); 219static void wp_wrreg(struct agg_info*, u_int16_t, u_int16_t); 220static u_int16_t wp_rdapu(struct agg_info*, unsigned, u_int16_t); 221static void wp_wrapu(struct agg_info*, unsigned, u_int16_t, u_int16_t); 222static void wp_settimer(struct agg_info*, u_int); 223static void wp_starttimer(struct agg_info*); 224static void wp_stoptimer(struct agg_info*); 225 226#if 0 227static u_int16_t wc_rdreg(struct agg_info*, u_int16_t); 228#endif 229static void wc_wrreg(struct agg_info*, u_int16_t, u_int16_t); 230#if 0 231static u_int16_t wc_rdchctl(struct agg_info*, int); 232#endif 233static void wc_wrchctl(struct agg_info*, int, u_int16_t); 234 235static void agg_stopclock(struct agg_info*, int part, int st); 236 237static void agg_initcodec(struct agg_info*); 238static void agg_init(struct agg_info*); 239static void agg_power(struct agg_info*, int); 240 241static void aggch_start_dac(struct agg_chinfo*); 242static void aggch_stop_dac(struct agg_chinfo*); 243static void aggch_start_adc(struct agg_rchinfo*); 244static void aggch_stop_adc(struct agg_rchinfo*); 245static void aggch_feed_adc_stereo(struct agg_rchinfo*); 246static void aggch_feed_adc_mono(struct agg_rchinfo*); 247 248#ifdef AGG_JITTER_CORRECTION 249static void suppress_jitter(struct agg_chinfo*); 250static void suppress_rec_jitter(struct agg_rchinfo*); 251#endif 252 253static void set_timer(struct agg_info*); 254 255static void agg_intr(void *); 256static int agg_probe(device_t); 257static int agg_attach(device_t); 258static int agg_detach(device_t); 259static int agg_suspend(device_t); 260static int agg_resume(device_t); 261static int agg_shutdown(device_t); 262 263static void *dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*); 264static void dma_free(bus_dma_tag_t, void *); 265 266 267/* ----------------------------- 268 * Subsystems. 269 */ 270 271/* locking */ 272#define agg_lock(sc) snd_mtxlock(&((sc)->lock)) 273#define agg_unlock(sc) snd_mtxunlock(&((sc)->lock)) 274 275static void 276agg_sleep(struct agg_info *sc, const char *wmesg, int msec) 277{ 278 int timo; 279 280 timo = msec * hz / 1000; 281 if (timo == 0) 282 timo = 1; 283 msleep(sc, &sc->lock, PWAIT, wmesg, timo); 284} 285 286 287/* I/O port */ 288 289static __inline u_int32_t 290agg_rd(struct agg_info *sc, int regno, int size) 291{ 292 switch (size) { 293 case 1: 294 return bus_space_read_1(sc->st, sc->sh, regno); 295 case 2: 296 return bus_space_read_2(sc->st, sc->sh, regno); 297 case 4: 298 return bus_space_read_4(sc->st, sc->sh, regno); 299 default: 300 return ~(u_int32_t)0; 301 } 302} 303 304#define AGG_RD(sc, regno, size) \ 305 bus_space_read_##size( \ 306 ((struct agg_info*)(sc))->st, \ 307 ((struct agg_info*)(sc))->sh, (regno)) 308 309static __inline void 310agg_wr(struct agg_info *sc, int regno, u_int32_t data, int size) 311{ 312 switch (size) { 313 case 1: 314 bus_space_write_1(sc->st, sc->sh, regno, data); 315 break; 316 case 2: 317 bus_space_write_2(sc->st, sc->sh, regno, data); 318 break; 319 case 4: 320 bus_space_write_4(sc->st, sc->sh, regno, data); 321 break; 322 } 323} 324 325#define AGG_WR(sc, regno, data, size) \ 326 bus_space_write_##size( \ 327 ((struct agg_info*)(sc))->st, \ 328 ((struct agg_info*)(sc))->sh, (regno), (data)) 329 330/* -------------------------------------------------------------------- */ 331 332/* Codec/Ringbus */ 333 334static int 335agg_codec_wait4idle(struct agg_info *ess) 336{ 337 unsigned t = 26; 338 339 while (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK) { 340 if (--t == 0) 341 return EBUSY; 342 DELAY(2); /* 20.8us / 13 */ 343 } 344 return 0; 345} 346 347 348static int 349agg_rdcodec(struct agg_info *ess, int regno) 350{ 351 int ret; 352 353 /* We have to wait for a SAFE time to write addr/data */ 354 if (agg_codec_wait4idle(ess)) { 355 /* Timed out. No read performed. */ 356 device_printf(ess->dev, "agg_rdcodec() PROGLESS timed out.\n"); 357 return -1; 358 } 359 360 AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_READ | regno, 1); 361 /*DELAY(21); * AC97 cycle = 20.8usec */ 362 363 /* Wait for data retrieve */ 364 if (!agg_codec_wait4idle(ess)) { 365 ret = AGG_RD(ess, PORT_CODEC_REG, 2); 366 } else { 367 /* Timed out. No read performed. */ 368 device_printf(ess->dev, "agg_rdcodec() RW_DONE timed out.\n"); 369 ret = -1; 370 } 371 372 return ret; 373} 374 375static int 376agg_wrcodec(struct agg_info *ess, int regno, u_int32_t data) 377{ 378 /* We have to wait for a SAFE time to write addr/data */ 379 if (agg_codec_wait4idle(ess)) { 380 /* Timed out. Abort writing. */ 381 device_printf(ess->dev, "agg_wrcodec() PROGLESS timed out.\n"); 382 return -1; 383 } 384 385 AGG_WR(ess, PORT_CODEC_REG, data, 2); 386 AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_WRITE | regno, 1); 387 388 /* Wait for write completion */ 389 if (agg_codec_wait4idle(ess)) { 390 /* Timed out. */ 391 device_printf(ess->dev, "agg_wrcodec() RW_DONE timed out.\n"); 392 return -1; 393 } 394 395 return 0; 396} 397 398static void 399ringbus_setdest(struct agg_info *ess, int src, int dest) 400{ 401 u_int32_t data; 402 403 data = AGG_RD(ess, PORT_RINGBUS_CTRL, 4); 404 data &= ~(0xfU << src); 405 data |= (0xfU & dest) << src; 406 AGG_WR(ess, PORT_RINGBUS_CTRL, data, 4); 407} 408 409/* -------------------------------------------------------------------- */ 410 411/* Wave Processor */ 412 413static u_int16_t 414wp_rdreg(struct agg_info *ess, u_int16_t reg) 415{ 416 AGG_WR(ess, PORT_DSP_INDEX, reg, 2); 417 return AGG_RD(ess, PORT_DSP_DATA, 2); 418} 419 420static void 421wp_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) 422{ 423 AGG_WR(ess, PORT_DSP_INDEX, reg, 2); 424 AGG_WR(ess, PORT_DSP_DATA, data, 2); 425} 426 427static int 428wp_wait_data(struct agg_info *ess, u_int16_t data) 429{ 430 unsigned t = 0; 431 432 while (AGG_RD(ess, PORT_DSP_DATA, 2) != data) { 433 if (++t == 1000) { 434 return EAGAIN; 435 } 436 AGG_WR(ess, PORT_DSP_DATA, data, 2); 437 } 438 439 return 0; 440} 441 442static u_int16_t 443wp_rdapu(struct agg_info *ess, unsigned ch, u_int16_t reg) 444{ 445 wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4)); 446 if (wp_wait_data(ess, reg | (ch << 4)) != 0) 447 device_printf(ess->dev, "wp_rdapu() indexing timed out.\n"); 448 return wp_rdreg(ess, WPREG_DATA_PORT); 449} 450 451static void 452wp_wrapu(struct agg_info *ess, unsigned ch, u_int16_t reg, u_int16_t data) 453{ 454 wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4)); 455 if (wp_wait_data(ess, reg | (ch << 4)) == 0) { 456 wp_wrreg(ess, WPREG_DATA_PORT, data); 457 if (wp_wait_data(ess, data) != 0) 458 device_printf(ess->dev, 459 "wp_wrapu() write timed out.\n"); 460 } else { 461 device_printf(ess->dev, "wp_wrapu() indexing timed out.\n"); 462 } 463} 464 465static void 466apu_setparam(struct agg_info *ess, int apuch, 467 u_int32_t wpwa, u_int16_t size, int16_t pan, u_int dv) 468{ 469 wp_wrapu(ess, apuch, APUREG_WAVESPACE, (wpwa >> 8) & APU_64KPAGE_MASK); 470 wp_wrapu(ess, apuch, APUREG_CURPTR, wpwa); 471 wp_wrapu(ess, apuch, APUREG_ENDPTR, wpwa + size); 472 wp_wrapu(ess, apuch, APUREG_LOOPLEN, size); 473 wp_wrapu(ess, apuch, APUREG_ROUTING, 0); 474 wp_wrapu(ess, apuch, APUREG_AMPLITUDE, 0xf000); 475 wp_wrapu(ess, apuch, APUREG_POSITION, 0x8f00 476 | (APU_RADIUS_MASK & (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)) 477 | (APU_PAN_MASK & ((pan + PAN_FRONT) << APU_PAN_SHIFT))); 478 wp_wrapu(ess, apuch, APUREG_FREQ_LOBYTE, 479 APU_plus6dB | ((dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 480 wp_wrapu(ess, apuch, APUREG_FREQ_HIWORD, dv >> 8); 481} 482 483static void 484wp_settimer(struct agg_info *ess, u_int divide) 485{ 486 u_int prescale = 0; 487 488 RANGE(divide, 2, 32 << 7); 489 490 for (; divide > 32; divide >>= 1) { 491 prescale++; 492 divide++; 493 } 494 495 for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1) 496 prescale++; 497 498 wp_wrreg(ess, WPREG_TIMER_ENABLE, 0); 499 wp_wrreg(ess, WPREG_TIMER_FREQ, 0x9000 | 500 (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1)); 501 wp_wrreg(ess, WPREG_TIMER_ENABLE, 1); 502} 503 504static void 505wp_starttimer(struct agg_info *ess) 506{ 507 AGG_WR(ess, PORT_INT_STAT, 1, 2); 508 AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_INT_ENABLED 509 | AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2); 510 wp_wrreg(ess, WPREG_TIMER_START, 1); 511} 512 513static void 514wp_stoptimer(struct agg_info *ess) 515{ 516 AGG_WR(ess, PORT_HOSTINT_CTRL, ~HOSTINT_CTRL_DSOUND_INT_ENABLED 517 & AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2); 518 AGG_WR(ess, PORT_INT_STAT, 1, 2); 519 wp_wrreg(ess, WPREG_TIMER_START, 0); 520} 521 522/* -------------------------------------------------------------------- */ 523 524/* WaveCache */ 525 526#if 0 527static u_int16_t 528wc_rdreg(struct agg_info *ess, u_int16_t reg) 529{ 530 AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2); 531 return AGG_RD(ess, PORT_WAVCACHE_DATA, 2); 532} 533#endif 534 535static void 536wc_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data) 537{ 538 AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2); 539 AGG_WR(ess, PORT_WAVCACHE_DATA, data, 2); 540} 541 542#if 0 543static u_int16_t 544wc_rdchctl(struct agg_info *ess, int ch) 545{ 546 return wc_rdreg(ess, ch << 3); 547} 548#endif 549 550static void 551wc_wrchctl(struct agg_info *ess, int ch, u_int16_t data) 552{ 553 wc_wrreg(ess, ch << 3, data); 554} 555 556/* -------------------------------------------------------------------- */ 557 558/* Power management */ 559static void 560agg_stopclock(struct agg_info *ess, int part, int st) 561{ 562 u_int32_t data; 563 564 data = pci_read_config(ess->dev, CONF_ACPI_STOPCLOCK, 4); 565 if (part < 16) { 566 if (st == PCI_POWERSTATE_D1) 567 data &= ~(1 << part); 568 else 569 data |= (1 << part); 570 if (st == PCI_POWERSTATE_D1 || st == PCI_POWERSTATE_D2) 571 data |= (0x10000 << part); 572 else 573 data &= ~(0x10000 << part); 574 pci_write_config(ess->dev, CONF_ACPI_STOPCLOCK, data, 4); 575 } 576} 577 578 579/* ----------------------------- 580 * Controller. 581 */ 582 583static void 584agg_initcodec(struct agg_info* ess) 585{ 586 u_int16_t data; 587 588 if (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) & RINGBUS_CTRL_ACLINK_ENABLED) { 589 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); 590 DELAY(104); /* 20.8us * (4 + 1) */ 591 } 592 /* XXX - 2nd codec should be looked at. */ 593 AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET, 4); 594 DELAY(2); 595 AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4); 596 DELAY(50); 597 598 if (agg_rdcodec(ess, 0) < 0) { 599 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); 600 DELAY(21); 601 602 /* Try cold reset. */ 603 device_printf(ess->dev, "will perform cold reset.\n"); 604 data = AGG_RD(ess, PORT_GPIO_DIR, 2); 605 if (pci_read_config(ess->dev, 0x58, 2) & 1) 606 data |= 0x10; 607 data |= 0x009 & ~AGG_RD(ess, PORT_GPIO_DATA, 2); 608 AGG_WR(ess, PORT_GPIO_MASK, 0xff6, 2); 609 AGG_WR(ess, PORT_GPIO_DIR, data | 0x009, 2); 610 AGG_WR(ess, PORT_GPIO_DATA, 0x000, 2); 611 DELAY(2); 612 AGG_WR(ess, PORT_GPIO_DATA, 0x001, 2); 613 DELAY(1); 614 AGG_WR(ess, PORT_GPIO_DATA, 0x009, 2); 615 agg_sleep(ess, "agginicd", 500); 616 AGG_WR(ess, PORT_GPIO_DIR, data, 2); 617 DELAY(84); /* 20.8us * 4 */ 618 AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4); 619 DELAY(50); 620 } 621} 622 623static void 624agg_init(struct agg_info* ess) 625{ 626 u_int32_t data; 627 628 /* Setup PCI config registers. */ 629 630 /* Disable all legacy emulations. */ 631 data = pci_read_config(ess->dev, CONF_LEGACY, 2); 632 data |= LEGACY_DISABLED; 633 pci_write_config(ess->dev, CONF_LEGACY, data, 2); 634 635 /* Disconnect from CHI. (Makes Dell inspiron 7500 work?) 636 * Enable posted write. 637 * Prefer PCI timing rather than that of ISA. 638 * Don't swap L/R. */ 639 data = pci_read_config(ess->dev, CONF_MAESTRO, 4); 640 data |= MAESTRO_PMC; 641 data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING; 642 data &= ~MAESTRO_SWAP_LR; 643 pci_write_config(ess->dev, CONF_MAESTRO, data, 4); 644 645 /* Turn off unused parts if necessary. */ 646 /* consult CONF_MAESTRO. */ 647 if (data & MAESTRO_SPDIF) 648 agg_stopclock(ess, ACPI_PART_SPDIF, PCI_POWERSTATE_D2); 649 else 650 agg_stopclock(ess, ACPI_PART_SPDIF, PCI_POWERSTATE_D1); 651 if (data & MAESTRO_HWVOL) 652 agg_stopclock(ess, ACPI_PART_HW_VOL, PCI_POWERSTATE_D3); 653 else 654 agg_stopclock(ess, ACPI_PART_HW_VOL, PCI_POWERSTATE_D1); 655 656 /* parts that never be used */ 657 agg_stopclock(ess, ACPI_PART_978, PCI_POWERSTATE_D1); 658 agg_stopclock(ess, ACPI_PART_DAA, PCI_POWERSTATE_D1); 659 agg_stopclock(ess, ACPI_PART_GPIO, PCI_POWERSTATE_D1); 660 agg_stopclock(ess, ACPI_PART_SB, PCI_POWERSTATE_D1); 661 agg_stopclock(ess, ACPI_PART_FM, PCI_POWERSTATE_D1); 662 agg_stopclock(ess, ACPI_PART_MIDI, PCI_POWERSTATE_D1); 663 agg_stopclock(ess, ACPI_PART_GAME_PORT, PCI_POWERSTATE_D1); 664 665 /* parts that will be used only when play/recording */ 666 agg_stopclock(ess, ACPI_PART_WP, PCI_POWERSTATE_D2); 667 668 /* parts that should always be turned on */ 669 agg_stopclock(ess, ACPI_PART_CODEC_CLOCK, PCI_POWERSTATE_D3); 670 agg_stopclock(ess, ACPI_PART_GLUE, PCI_POWERSTATE_D3); 671 agg_stopclock(ess, ACPI_PART_PCI_IF, PCI_POWERSTATE_D3); 672 agg_stopclock(ess, ACPI_PART_RINGBUS, PCI_POWERSTATE_D3); 673 674 /* Reset direct sound. */ 675 AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_SOFT_RESET, 2); 676 DELAY(100); 677 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); 678 DELAY(100); 679 AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_RESET, 2); 680 DELAY(100); 681 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); 682 DELAY(100); 683 684 /* Enable hardware volume control interruption. */ 685 if (data & MAESTRO_HWVOL) /* XXX - why not use device flags? */ 686 AGG_WR(ess, PORT_HOSTINT_CTRL,HOSTINT_CTRL_HWVOL_ENABLED, 2); 687 688 /* Setup Wave Processor. */ 689 690 /* Enable WaveCache, set DMA base address. */ 691 wp_wrreg(ess, WPREG_WAVE_ROMRAM, 692 WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED); 693 wp_wrreg(ess, WPREG_CRAM_DATA, 0); 694 695 AGG_WR(ess, PORT_WAVCACHE_CTRL, 696 WAVCACHE_ENABLED | WAVCACHE_WTSIZE_2MB | WAVCACHE_SGC_32_47, 2); 697 698 for (data = WAVCACHE_PCMBAR; data < WAVCACHE_PCMBAR + 4; data++) 699 wc_wrreg(ess, data, ess->phys >> WAVCACHE_BASEADDR_SHIFT); 700 701 /* Setup Codec/Ringbus. */ 702 agg_initcodec(ess); 703 AGG_WR(ess, PORT_RINGBUS_CTRL, 704 RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED, 4); 705 706 wp_wrreg(ess, 0x08, 0xB004); 707 wp_wrreg(ess, 0x09, 0x001B); 708 wp_wrreg(ess, 0x0A, 0x8000); 709 wp_wrreg(ess, 0x0B, 0x3F37); 710 wp_wrreg(ess, WPREG_BASE, 0x8598); /* Parallel I/O */ 711 wp_wrreg(ess, WPREG_BASE + 1, 0x7632); 712 ringbus_setdest(ess, RINGBUS_SRC_ADC, 713 RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN); 714 ringbus_setdest(ess, RINGBUS_SRC_DSOUND, 715 RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC); 716 717 /* Enable S/PDIF if necessary. */ 718 if (pci_read_config(ess->dev, CONF_MAESTRO, 4) & MAESTRO_SPDIF) 719 /* XXX - why not use device flags? */ 720 AGG_WR(ess, PORT_RINGBUS_CTRL_B, RINGBUS_CTRL_SPDIF | 721 AGG_RD(ess, PORT_RINGBUS_CTRL_B, 1), 1); 722 723 /* Setup ASSP. Needed for Dell Inspiron 7500? */ 724 AGG_WR(ess, PORT_ASSP_CTRL_B, 0x00, 1); 725 AGG_WR(ess, PORT_ASSP_CTRL_A, 0x03, 1); 726 AGG_WR(ess, PORT_ASSP_CTRL_C, 0x00, 1); 727 728 /* 729 * Setup GPIO. 730 * There seems to be speciality with NEC systems. 731 */ 732 switch (pci_get_subvendor(ess->dev) 733 | (pci_get_subdevice(ess->dev) << 16)) { 734 case NEC_SUBID1: 735 case NEC_SUBID2: 736 /* Matthew Braithwaite <matt@braithwaite.net> reported that 737 * NEC Versa LX doesn't need GPIO operation. */ 738 AGG_WR(ess, PORT_GPIO_MASK, 0x9ff, 2); 739 AGG_WR(ess, PORT_GPIO_DIR, 740 AGG_RD(ess, PORT_GPIO_DIR, 2) | 0x600, 2); 741 AGG_WR(ess, PORT_GPIO_DATA, 0x200, 2); 742 break; 743 } 744} 745 746/* Deals power state transition. Must be called with softc->lock held. */ 747static void 748agg_power(struct agg_info *ess, int status) 749{ 750 u_int8_t lastpwr; 751 752 lastpwr = ess->curpwr; 753 if (lastpwr == status) 754 return; 755 756 switch (status) { 757 case PCI_POWERSTATE_D0: 758 case PCI_POWERSTATE_D1: 759 switch (lastpwr) { 760 case PCI_POWERSTATE_D2: 761 pci_set_powerstate(ess->dev, status); 762 /* Turn on PCM-related parts. */ 763 agg_wrcodec(ess, AC97_REG_POWER, 0); 764 DELAY(100); 765#if 0 766 if ((agg_rdcodec(ess, AC97_REG_POWER) & 3) != 3) 767 device_printf(ess->dev, 768 "warning: codec not ready.\n"); 769#endif 770 AGG_WR(ess, PORT_RINGBUS_CTRL, 771 (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) 772 & ~RINGBUS_CTRL_ACLINK_ENABLED) 773 | RINGBUS_CTRL_RINGBUS_ENABLED, 4); 774 DELAY(50); 775 AGG_WR(ess, PORT_RINGBUS_CTRL, 776 AGG_RD(ess, PORT_RINGBUS_CTRL, 4) 777 | RINGBUS_CTRL_ACLINK_ENABLED, 4); 778 break; 779 case PCI_POWERSTATE_D3: 780 /* Initialize. */ 781 pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0); 782 DELAY(100); 783 agg_init(ess); 784 /* FALLTHROUGH */ 785 case PCI_POWERSTATE_D0: 786 case PCI_POWERSTATE_D1: 787 pci_set_powerstate(ess->dev, status); 788 break; 789 } 790 break; 791 case PCI_POWERSTATE_D2: 792 switch (lastpwr) { 793 case PCI_POWERSTATE_D3: 794 /* Initialize. */ 795 pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0); 796 DELAY(100); 797 agg_init(ess); 798 /* FALLTHROUGH */ 799 case PCI_POWERSTATE_D0: 800 case PCI_POWERSTATE_D1: 801 /* Turn off PCM-related parts. */ 802 AGG_WR(ess, PORT_RINGBUS_CTRL, 803 AGG_RD(ess, PORT_RINGBUS_CTRL, 4) 804 & ~RINGBUS_CTRL_RINGBUS_ENABLED, 4); 805 DELAY(100); 806 agg_wrcodec(ess, AC97_REG_POWER, 0x300); 807 DELAY(100); 808 break; 809 } 810 pci_set_powerstate(ess->dev, status); 811 break; 812 case PCI_POWERSTATE_D3: 813 /* Entirely power down. */ 814 agg_wrcodec(ess, AC97_REG_POWER, 0xdf00); 815 DELAY(100); 816 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4); 817 /*DELAY(1);*/ 818 if (lastpwr != PCI_POWERSTATE_D2) 819 wp_stoptimer(ess); 820 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); 821 AGG_WR(ess, PORT_HOSTINT_STAT, 0xff, 1); 822 pci_set_powerstate(ess->dev, status); 823 break; 824 default: 825 /* Invalid power state; let it ignored. */ 826 status = lastpwr; 827 break; 828 } 829 830 ess->curpwr = status; 831} 832 833/* -------------------------------------------------------------------- */ 834 835/* Channel controller. */ 836 837static void 838aggch_start_dac(struct agg_chinfo *ch) 839{ 840 bus_addr_t wpwa; 841 u_int32_t speed; 842 u_int16_t size, apuch, wtbar, wcreg, aputype; 843 u_int dv; 844 int pan; 845 846 speed = ch->speed; 847 wpwa = (ch->phys - ch->base) >> 1; 848 wtbar = 0xc & (wpwa >> WPWA_WTBAR_SHIFT(2)); 849 wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 850 size = ch->buflen; 851 apuch = (ch->num << 1) | 32; 852 pan = PAN_RIGHT - PAN_FRONT; 853 854 if (ch->stereo) { 855 wcreg |= WAVCACHE_CHCTL_STEREO; 856 if (ch->qs16) { 857 aputype = APUTYPE_16BITSTEREO; 858 wpwa >>= 1; 859 size >>= 1; 860 pan = -pan; 861 } else 862 aputype = APUTYPE_8BITSTEREO; 863 } else { 864 pan = 0; 865 if (ch->qs16) 866 aputype = APUTYPE_16BITLINEAR; 867 else { 868 aputype = APUTYPE_8BITLINEAR; 869 speed >>= 1; 870 } 871 } 872 if (ch->us) 873 wcreg |= WAVCACHE_CHCTL_U8; 874 875 if (wtbar > 8) 876 wtbar = (wtbar >> 1) + 4; 877 878 dv = (((speed % 48000) << 16) + 24000) / 48000 879 + ((speed / 48000) << 16); 880 881 agg_lock(ch->parent); 882 agg_power(ch->parent, powerstate_active); 883 884 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar, 885 ch->base >> WAVCACHE_BASEADDR_SHIFT); 886 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 1, 887 ch->base >> WAVCACHE_BASEADDR_SHIFT); 888 if (wtbar < 8) { 889 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 2, 890 ch->base >> WAVCACHE_BASEADDR_SHIFT); 891 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 3, 892 ch->base >> WAVCACHE_BASEADDR_SHIFT); 893 } 894 wc_wrchctl(ch->parent, apuch, wcreg); 895 wc_wrchctl(ch->parent, apuch + 1, wcreg); 896 897 apu_setparam(ch->parent, apuch, wpwa, size, pan, dv); 898 if (ch->stereo) { 899 if (ch->qs16) 900 wpwa |= (WPWA_STEREO >> 1); 901 apu_setparam(ch->parent, apuch + 1, wpwa, size, -pan, dv); 902 903 critical_enter(); 904 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, 905 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 906 wp_wrapu(ch->parent, apuch + 1, APUREG_APUTYPE, 907 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 908 critical_exit(); 909 } else { 910 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, 911 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 912 } 913 914 /* to mark that this channel is ready for intr. */ 915 ch->parent->active |= (1 << ch->num); 916 917 set_timer(ch->parent); 918 wp_starttimer(ch->parent); 919 agg_unlock(ch->parent); 920} 921 922static void 923aggch_stop_dac(struct agg_chinfo *ch) 924{ 925 agg_lock(ch->parent); 926 927 /* to mark that this channel no longer needs further intrs. */ 928 ch->parent->active &= ~(1 << ch->num); 929 930 wp_wrapu(ch->parent, (ch->num << 1) | 32, APUREG_APUTYPE, 931 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 932 wp_wrapu(ch->parent, (ch->num << 1) | 33, APUREG_APUTYPE, 933 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 934 935 if (ch->parent->active) { 936 set_timer(ch->parent); 937 wp_starttimer(ch->parent); 938 } else { 939 wp_stoptimer(ch->parent); 940 agg_power(ch->parent, powerstate_idle); 941 } 942 agg_unlock(ch->parent); 943} 944 945static void 946aggch_start_adc(struct agg_rchinfo *ch) 947{ 948 bus_addr_t wpwa, wpwa2; 949 u_int16_t wcreg, wcreg2; 950 u_int dv; 951 int pan; 952 953 /* speed > 48000 not cared */ 954 dv = ((ch->speed << 16) + 24000) / 48000; 955 956 /* RATECONV doesn't seem to like dv == 0x10000. */ 957 if (dv == 0x10000) 958 dv--; 959 960 if (ch->stereo) { 961 wpwa = (ch->srcphys - ch->base) >> 1; 962 wpwa2 = (ch->srcphys + ch->parent->bufsz/2 - ch->base) >> 1; 963 wcreg = (ch->srcphys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 964 wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 965 pan = PAN_LEFT - PAN_FRONT; 966 } else { 967 wpwa = (ch->phys - ch->base) >> 1; 968 wpwa2 = (ch->srcphys - ch->base) >> 1; 969 wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 970 wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 971 pan = 0; 972 } 973 974 agg_lock(ch->parent); 975 976 ch->hwptr = 0; 977 agg_power(ch->parent, powerstate_active); 978 979 /* Invalidate WaveCache. */ 980 wc_wrchctl(ch->parent, 0, wcreg | WAVCACHE_CHCTL_STEREO); 981 wc_wrchctl(ch->parent, 1, wcreg | WAVCACHE_CHCTL_STEREO); 982 wc_wrchctl(ch->parent, 2, wcreg2 | WAVCACHE_CHCTL_STEREO); 983 wc_wrchctl(ch->parent, 3, wcreg2 | WAVCACHE_CHCTL_STEREO); 984 985 /* Load APU registers. */ 986 /* APU #0 : Sample rate converter for left/center. */ 987 apu_setparam(ch->parent, 0, WPWA_USE_SYSMEM | wpwa, 988 ch->buflen >> ch->stereo, 0, dv); 989 wp_wrapu(ch->parent, 0, APUREG_AMPLITUDE, 0); 990 wp_wrapu(ch->parent, 0, APUREG_ROUTING, 2 << APU_DATASRC_A_SHIFT); 991 992 /* APU #1 : Sample rate converter for right. */ 993 apu_setparam(ch->parent, 1, WPWA_USE_SYSMEM | wpwa2, 994 ch->buflen >> ch->stereo, 0, dv); 995 wp_wrapu(ch->parent, 1, APUREG_AMPLITUDE, 0); 996 wp_wrapu(ch->parent, 1, APUREG_ROUTING, 3 << APU_DATASRC_A_SHIFT); 997 998 /* APU #2 : Input mixer for left. */ 999 apu_setparam(ch->parent, 2, WPWA_USE_SYSMEM | 0, 1000 ch->parent->bufsz >> 2, pan, 0x10000); 1001 wp_wrapu(ch->parent, 2, APUREG_AMPLITUDE, 0); 1002 wp_wrapu(ch->parent, 2, APUREG_EFFECT_GAIN, 0xf0); 1003 wp_wrapu(ch->parent, 2, APUREG_ROUTING, 0x15 << APU_DATASRC_A_SHIFT); 1004 1005 /* APU #3 : Input mixer for right. */ 1006 apu_setparam(ch->parent, 3, WPWA_USE_SYSMEM | (ch->parent->bufsz >> 2), 1007 ch->parent->bufsz >> 2, -pan, 0x10000); 1008 wp_wrapu(ch->parent, 3, APUREG_AMPLITUDE, 0); 1009 wp_wrapu(ch->parent, 3, APUREG_EFFECT_GAIN, 0xf0); 1010 wp_wrapu(ch->parent, 3, APUREG_ROUTING, 0x14 << APU_DATASRC_A_SHIFT); 1011 1012 /* to mark this channel ready for intr. */ 1013 ch->parent->active |= (1 << ch->parent->playchns); 1014 1015 /* start adc */ 1016 critical_enter(); 1017 wp_wrapu(ch->parent, 0, APUREG_APUTYPE, 1018 (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 1019 wp_wrapu(ch->parent, 1, APUREG_APUTYPE, 1020 (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 1021 wp_wrapu(ch->parent, 2, APUREG_APUTYPE, 1022 (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf); 1023 wp_wrapu(ch->parent, 3, APUREG_APUTYPE, 1024 (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf); 1025 critical_exit(); 1026 1027 set_timer(ch->parent); 1028 wp_starttimer(ch->parent); 1029 agg_unlock(ch->parent); 1030} 1031 1032static void 1033aggch_stop_adc(struct agg_rchinfo *ch) 1034{ 1035 int apuch; 1036 1037 agg_lock(ch->parent); 1038 1039 /* to mark that this channel no longer needs further intrs. */ 1040 ch->parent->active &= ~(1 << ch->parent->playchns); 1041 1042 for (apuch = 0; apuch < 4; apuch++) 1043 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE, 1044 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 1045 1046 if (ch->parent->active) { 1047 set_timer(ch->parent); 1048 wp_starttimer(ch->parent); 1049 } else { 1050 wp_stoptimer(ch->parent); 1051 agg_power(ch->parent, powerstate_idle); 1052 } 1053 agg_unlock(ch->parent); 1054} 1055 1056/* 1057 * Feed from L/R channel of ADC to destination with stereo interleaving. 1058 * This function expects n not overwrapping the buffer boundary. 1059 * Note that n is measured in sample unit. 1060 * 1061 * XXX - this function works in 16bit stereo format only. 1062 */ 1063static void 1064interleave(int16_t *l, int16_t *r, int16_t *p, unsigned n) 1065{ 1066 int16_t *end; 1067 1068 for (end = l + n; l < end; ) { 1069 *p++ = *l++; 1070 *p++ = *r++; 1071 } 1072} 1073 1074static void 1075aggch_feed_adc_stereo(struct agg_rchinfo *ch) 1076{ 1077 unsigned cur, last; 1078 int16_t *src2; 1079 1080 agg_lock(ch->parent); 1081 cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR); 1082 agg_unlock(ch->parent); 1083 cur -= 0xffff & ((ch->srcphys - ch->base) >> 1); 1084 last = ch->hwptr; 1085 src2 = ch->src + ch->parent->bufsz/4; 1086 1087 if (cur < last) { 1088 interleave(ch->src + last, src2 + last, 1089 ch->sink + 2*last, ch->buflen/2 - last); 1090 interleave(ch->src, src2, 1091 ch->sink, cur); 1092 } else if (cur > last) 1093 interleave(ch->src + last, src2 + last, 1094 ch->sink + 2*last, cur - last); 1095 ch->hwptr = cur; 1096} 1097 1098/* 1099 * Feed from R channel of ADC and mixdown to destination L/center. 1100 * This function expects n not overwrapping the buffer boundary. 1101 * Note that n is measured in sample unit. 1102 * 1103 * XXX - this function works in 16bit monoral format only. 1104 */ 1105static void 1106mixdown(int16_t *src, int16_t *dest, unsigned n) 1107{ 1108 int16_t *end; 1109 1110 for (end = dest + n; dest < end; dest++) 1111 *dest = (int16_t)(((int)*dest - (int)*src++) / 2); 1112} 1113 1114static void 1115aggch_feed_adc_mono(struct agg_rchinfo *ch) 1116{ 1117 unsigned cur, last; 1118 1119 agg_lock(ch->parent); 1120 cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR); 1121 agg_unlock(ch->parent); 1122 cur -= 0xffff & ((ch->phys - ch->base) >> 1); 1123 last = ch->hwptr; 1124 1125 if (cur < last) { 1126 mixdown(ch->src + last, ch->sink + last, ch->buflen - last); 1127 mixdown(ch->src, ch->sink, cur); 1128 } else if (cur > last) 1129 mixdown(ch->src + last, ch->sink + last, cur - last); 1130 ch->hwptr = cur; 1131} 1132 1133#ifdef AGG_JITTER_CORRECTION 1134/* 1135 * Stereo jitter suppressor. 1136 * Sometimes playback pointers differ in stereo-paired channels. 1137 * Calling this routine within intr fixes the problem. 1138 */ 1139static void 1140suppress_jitter(struct agg_chinfo *ch) 1141{ 1142 if (ch->stereo) { 1143 int cp1, cp2, diff /*, halfsize*/ ; 1144 1145 /*halfsize = (ch->qs16? ch->buflen >> 2 : ch->buflen >> 1);*/ 1146 cp1 = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR); 1147 cp2 = wp_rdapu(ch->parent, (ch->num << 1) | 33, APUREG_CURPTR); 1148 if (cp1 != cp2) { 1149 diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1); 1150 if (diff > 1 /* && diff < halfsize*/ ) 1151 AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2); 1152 } 1153 } 1154} 1155 1156static void 1157suppress_rec_jitter(struct agg_rchinfo *ch) 1158{ 1159 int cp1, cp2, diff /*, halfsize*/ ; 1160 1161 /*halfsize = (ch->stereo? ch->buflen >> 2 : ch->buflen >> 1);*/ 1162 cp1 = (ch->stereo? ch->parent->bufsz >> 2 : ch->parent->bufsz >> 1) 1163 + wp_rdapu(ch->parent, 0, APUREG_CURPTR); 1164 cp2 = wp_rdapu(ch->parent, 1, APUREG_CURPTR); 1165 if (cp1 != cp2) { 1166 diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1); 1167 if (diff > 1 /* && diff < halfsize*/ ) 1168 AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2); 1169 } 1170} 1171#endif 1172 1173static u_int 1174calc_timer_div(struct agg_chinfo *ch) 1175{ 1176 u_int speed; 1177 1178 speed = ch->speed; 1179#ifdef INVARIANTS 1180 if (speed == 0) { 1181 printf("snd_maestro: pch[%d].speed == 0, which shouldn't\n", 1182 ch->num); 1183 speed = 1; 1184 } 1185#endif 1186 return (48000 * (ch->blklen << (!ch->qs16 + !ch->stereo)) 1187 + speed - 1) / speed; 1188} 1189 1190static u_int 1191calc_timer_div_rch(struct agg_rchinfo *ch) 1192{ 1193 u_int speed; 1194 1195 speed = ch->speed; 1196#ifdef INVARIANTS 1197 if (speed == 0) { 1198 printf("snd_maestro: rch.speed == 0, which shouldn't\n"); 1199 speed = 1; 1200 } 1201#endif 1202 return (48000 * (ch->blklen << (!ch->stereo)) 1203 + speed - 1) / speed; 1204} 1205 1206static void 1207set_timer(struct agg_info *ess) 1208{ 1209 int i; 1210 u_int dv = 32 << 7, newdv; 1211 1212 for (i = 0; i < ess->playchns; i++) 1213 if ((ess->active & (1 << i)) && 1214 (dv > (newdv = calc_timer_div(ess->pch + i)))) 1215 dv = newdv; 1216 if ((ess->active & (1 << i)) && 1217 (dv > (newdv = calc_timer_div_rch(&ess->rch)))) 1218 dv = newdv; 1219 1220 wp_settimer(ess, dv); 1221} 1222 1223 1224/* ----------------------------- 1225 * Newpcm glue. 1226 */ 1227 1228/* AC97 mixer interface. */ 1229 1230static u_int32_t 1231agg_ac97_init(kobj_t obj, void *sc) 1232{ 1233 struct agg_info *ess = sc; 1234 1235 return (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK)? 0 : 1; 1236} 1237 1238static int 1239agg_ac97_read(kobj_t obj, void *sc, int regno) 1240{ 1241 struct agg_info *ess = sc; 1242 int ret; 1243 1244 /* XXX sound locking violation: agg_lock(ess); */ 1245 ret = agg_rdcodec(ess, regno); 1246 /* agg_unlock(ess); */ 1247 return ret; 1248} 1249 1250static int 1251agg_ac97_write(kobj_t obj, void *sc, int regno, u_int32_t data) 1252{ 1253 struct agg_info *ess = sc; 1254 int ret; 1255 1256 /* XXX sound locking violation: agg_lock(ess); */ 1257 ret = agg_wrcodec(ess, regno, data); 1258 /* agg_unlock(ess); */ 1259 return ret; 1260} 1261 1262 1263static kobj_method_t agg_ac97_methods[] = { 1264 KOBJMETHOD(ac97_init, agg_ac97_init), 1265 KOBJMETHOD(ac97_read, agg_ac97_read), 1266 KOBJMETHOD(ac97_write, agg_ac97_write), 1267 KOBJMETHOD_END 1268}; 1269AC97_DECLARE(agg_ac97); 1270 1271 1272/* -------------------------------------------------------------------- */ 1273 1274/* Playback channel. */ 1275 1276static void * 1277aggpch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 1278 struct pcm_channel *c, int dir) 1279{ 1280 struct agg_info *ess = devinfo; 1281 struct agg_chinfo *ch; 1282 bus_addr_t physaddr; 1283 void *p; 1284 1285 KASSERT((dir == PCMDIR_PLAY), 1286 ("aggpch_init() called for RECORDING channel!")); 1287 ch = ess->pch + ess->playchns; 1288 1289 ch->parent = ess; 1290 ch->channel = c; 1291 ch->buffer = b; 1292 ch->num = ess->playchns; 1293 1294 p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr); 1295 if (p == NULL) 1296 return NULL; 1297 ch->phys = physaddr; 1298 ch->base = physaddr & ((~(bus_addr_t)0) << WAVCACHE_BASEADDR_SHIFT); 1299 1300 sndbuf_setup(b, p, ess->bufsz); 1301 ch->blklen = sndbuf_getblksz(b) / 2; 1302 ch->buflen = sndbuf_getsize(b) / 2; 1303 ess->playchns++; 1304 1305 return ch; 1306} 1307 1308static void 1309adjust_pchbase(struct agg_chinfo *chans, u_int n, u_int size) 1310{ 1311 struct agg_chinfo *pchs[AGG_MAXPLAYCH]; 1312 u_int i, j, k; 1313 bus_addr_t base; 1314 1315 /* sort pchs by phys address */ 1316 for (i = 0; i < n; i++) { 1317 for (j = 0; j < i; j++) 1318 if (chans[i].phys < pchs[j]->phys) { 1319 for (k = i; k > j; k--) 1320 pchs[k] = pchs[k - 1]; 1321 break; 1322 } 1323 pchs[j] = chans + i; 1324 } 1325 1326 /* use new base register if next buffer can not be addressed 1327 via current base. */ 1328#define BASE_SHIFT (WPWA_WTBAR_SHIFT(2) + 2 + 1) 1329 base = pchs[0]->base; 1330 for (k = 1, i = 1; i < n; i++) { 1331 if (pchs[i]->phys + size - base >= 1 << BASE_SHIFT) 1332 /* not addressable: assign new base */ 1333 base = (pchs[i]->base -= k++ << BASE_SHIFT); 1334 else 1335 pchs[i]->base = base; 1336 } 1337#undef BASE_SHIFT 1338 1339 if (bootverbose) { 1340 printf("Total of %d bases are assigned.\n", k); 1341 for (i = 0; i < n; i++) { 1342 printf("ch.%d: phys 0x%llx, wpwa 0x%llx\n", 1343 i, (long long)chans[i].phys, 1344 (long long)(chans[i].phys - 1345 chans[i].base) >> 1); 1346 } 1347 } 1348} 1349 1350static int 1351aggpch_free(kobj_t obj, void *data) 1352{ 1353 struct agg_chinfo *ch = data; 1354 struct agg_info *ess = ch->parent; 1355 1356 /* free up buffer - called after channel stopped */ 1357 dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer)); 1358 1359 /* return 0 if ok */ 1360 return 0; 1361} 1362 1363static int 1364aggpch_setformat(kobj_t obj, void *data, u_int32_t format) 1365{ 1366 struct agg_chinfo *ch = data; 1367 1368 if (format & AFMT_BIGENDIAN || format & AFMT_U16_LE) 1369 return EINVAL; 1370 ch->stereo = ch->qs16 = ch->us = 0; 1371 if (AFMT_CHANNEL(format) > 1) 1372 ch->stereo = 1; 1373 1374 if (format & AFMT_U8 || format & AFMT_S8) { 1375 if (format & AFMT_U8) 1376 ch->us = 1; 1377 } else 1378 ch->qs16 = 1; 1379 return 0; 1380} 1381 1382static u_int32_t 1383aggpch_setspeed(kobj_t obj, void *data, u_int32_t speed) 1384{ 1385 1386 ((struct agg_chinfo*)data)->speed = speed; 1387 1388 return (speed); 1389} 1390 1391static u_int32_t 1392aggpch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 1393{ 1394 struct agg_chinfo *ch = data; 1395 int blkcnt; 1396 1397 /* try to keep at least 20msec DMA space */ 1398 blkcnt = (ch->speed << (ch->stereo + ch->qs16)) / (50 * blocksize); 1399 RANGE(blkcnt, 2, ch->parent->bufsz / blocksize); 1400 1401 if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) { 1402 sndbuf_resize(ch->buffer, blkcnt, blocksize); 1403 blkcnt = sndbuf_getblkcnt(ch->buffer); 1404 blocksize = sndbuf_getblksz(ch->buffer); 1405 } else { 1406 sndbuf_setblkcnt(ch->buffer, blkcnt); 1407 sndbuf_setblksz(ch->buffer, blocksize); 1408 } 1409 1410 ch->blklen = blocksize / 2; 1411 ch->buflen = blkcnt * blocksize / 2; 1412 return blocksize; 1413} 1414 1415static int 1416aggpch_trigger(kobj_t obj, void *data, int go) 1417{ 1418 struct agg_chinfo *ch = data; 1419 1420 switch (go) { 1421 case PCMTRIG_EMLDMAWR: 1422 break; 1423 case PCMTRIG_START: 1424 aggch_start_dac(ch); 1425 break; 1426 case PCMTRIG_ABORT: 1427 case PCMTRIG_STOP: 1428 aggch_stop_dac(ch); 1429 break; 1430 } 1431 return 0; 1432} 1433 1434static u_int32_t 1435aggpch_getptr(kobj_t obj, void *data) 1436{ 1437 struct agg_chinfo *ch = data; 1438 u_int32_t cp; 1439 1440 agg_lock(ch->parent); 1441 cp = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR); 1442 agg_unlock(ch->parent); 1443 1444 return ch->qs16 && ch->stereo 1445 ? (cp << 2) - ((0xffff << 2) & (ch->phys - ch->base)) 1446 : (cp << 1) - ((0xffff << 1) & (ch->phys - ch->base)); 1447} 1448 1449static struct pcmchan_caps * 1450aggpch_getcaps(kobj_t obj, void *data) 1451{ 1452 static u_int32_t playfmt[] = { 1453 SND_FORMAT(AFMT_U8, 1, 0), 1454 SND_FORMAT(AFMT_U8, 2, 0), 1455 SND_FORMAT(AFMT_S8, 1, 0), 1456 SND_FORMAT(AFMT_S8, 2, 0), 1457 SND_FORMAT(AFMT_S16_LE, 1, 0), 1458 SND_FORMAT(AFMT_S16_LE, 2, 0), 1459 0 1460 }; 1461 static struct pcmchan_caps playcaps = {8000, 48000, playfmt, 0}; 1462 1463 return &playcaps; 1464} 1465 1466 1467static kobj_method_t aggpch_methods[] = { 1468 KOBJMETHOD(channel_init, aggpch_init), 1469 KOBJMETHOD(channel_free, aggpch_free), 1470 KOBJMETHOD(channel_setformat, aggpch_setformat), 1471 KOBJMETHOD(channel_setspeed, aggpch_setspeed), 1472 KOBJMETHOD(channel_setblocksize, aggpch_setblocksize), 1473 KOBJMETHOD(channel_trigger, aggpch_trigger), 1474 KOBJMETHOD(channel_getptr, aggpch_getptr), 1475 KOBJMETHOD(channel_getcaps, aggpch_getcaps), 1476 KOBJMETHOD_END 1477}; 1478CHANNEL_DECLARE(aggpch); 1479 1480 1481/* -------------------------------------------------------------------- */ 1482 1483/* Recording channel. */ 1484 1485static void * 1486aggrch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 1487 struct pcm_channel *c, int dir) 1488{ 1489 struct agg_info *ess = devinfo; 1490 struct agg_rchinfo *ch; 1491 u_int8_t *p; 1492 1493 KASSERT((dir == PCMDIR_REC), 1494 ("aggrch_init() called for PLAYBACK channel!")); 1495 ch = &ess->rch; 1496 1497 ch->parent = ess; 1498 ch->channel = c; 1499 ch->buffer = b; 1500 1501 /* Uses the bottom-half of the status buffer. */ 1502 p = ess->stat + ess->bufsz; 1503 ch->phys = ess->phys + ess->bufsz; 1504 ch->base = ess->phys; 1505 ch->src = (int16_t *)(p + ess->bufsz); 1506 ch->srcphys = ch->phys + ess->bufsz; 1507 ch->sink = (int16_t *)p; 1508 1509 sndbuf_setup(b, p, ess->bufsz); 1510 ch->blklen = sndbuf_getblksz(b) / 2; 1511 ch->buflen = sndbuf_getsize(b) / 2; 1512 1513 return ch; 1514} 1515 1516static int 1517aggrch_setformat(kobj_t obj, void *data, u_int32_t format) 1518{ 1519 struct agg_rchinfo *ch = data; 1520 1521 if (!(format & AFMT_S16_LE)) 1522 return EINVAL; 1523 if (AFMT_CHANNEL(format) > 1) 1524 ch->stereo = 1; 1525 else 1526 ch->stereo = 0; 1527 return 0; 1528} 1529 1530static u_int32_t 1531aggrch_setspeed(kobj_t obj, void *data, u_int32_t speed) 1532{ 1533 1534 ((struct agg_rchinfo*)data)->speed = speed; 1535 1536 return (speed); 1537} 1538 1539static u_int32_t 1540aggrch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 1541{ 1542 struct agg_rchinfo *ch = data; 1543 int blkcnt; 1544 1545 /* try to keep at least 20msec DMA space */ 1546 blkcnt = (ch->speed << ch->stereo) / (25 * blocksize); 1547 RANGE(blkcnt, 2, ch->parent->bufsz / blocksize); 1548 1549 if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) { 1550 sndbuf_resize(ch->buffer, blkcnt, blocksize); 1551 blkcnt = sndbuf_getblkcnt(ch->buffer); 1552 blocksize = sndbuf_getblksz(ch->buffer); 1553 } else { 1554 sndbuf_setblkcnt(ch->buffer, blkcnt); 1555 sndbuf_setblksz(ch->buffer, blocksize); 1556 } 1557 1558 ch->blklen = blocksize / 2; 1559 ch->buflen = blkcnt * blocksize / 2; 1560 return blocksize; 1561} 1562 1563static int 1564aggrch_trigger(kobj_t obj, void *sc, int go) 1565{ 1566 struct agg_rchinfo *ch = sc; 1567 1568 switch (go) { 1569 case PCMTRIG_EMLDMARD: 1570 if (ch->stereo) 1571 aggch_feed_adc_stereo(ch); 1572 else 1573 aggch_feed_adc_mono(ch); 1574 break; 1575 case PCMTRIG_START: 1576 aggch_start_adc(ch); 1577 break; 1578 case PCMTRIG_ABORT: 1579 case PCMTRIG_STOP: 1580 aggch_stop_adc(ch); 1581 break; 1582 } 1583 return 0; 1584} 1585 1586static u_int32_t 1587aggrch_getptr(kobj_t obj, void *sc) 1588{ 1589 struct agg_rchinfo *ch = sc; 1590 1591 return ch->stereo? ch->hwptr << 2 : ch->hwptr << 1; 1592} 1593 1594static struct pcmchan_caps * 1595aggrch_getcaps(kobj_t obj, void *sc) 1596{ 1597 static u_int32_t recfmt[] = { 1598 SND_FORMAT(AFMT_S16_LE, 1, 0), 1599 SND_FORMAT(AFMT_S16_LE, 2, 0), 1600 0 1601 }; 1602 static struct pcmchan_caps reccaps = {8000, 48000, recfmt, 0}; 1603 1604 return &reccaps; 1605} 1606 1607static kobj_method_t aggrch_methods[] = { 1608 KOBJMETHOD(channel_init, aggrch_init), 1609 /* channel_free: no-op */ 1610 KOBJMETHOD(channel_setformat, aggrch_setformat), 1611 KOBJMETHOD(channel_setspeed, aggrch_setspeed), 1612 KOBJMETHOD(channel_setblocksize, aggrch_setblocksize), 1613 KOBJMETHOD(channel_trigger, aggrch_trigger), 1614 KOBJMETHOD(channel_getptr, aggrch_getptr), 1615 KOBJMETHOD(channel_getcaps, aggrch_getcaps), 1616 KOBJMETHOD_END 1617}; 1618CHANNEL_DECLARE(aggrch); 1619 1620 1621/* ----------------------------- 1622 * Bus space. 1623 */ 1624 1625static void 1626agg_intr(void *sc) 1627{ 1628 struct agg_info* ess = sc; 1629 register u_int8_t status; 1630 int i; 1631 u_int m; 1632 1633 status = AGG_RD(ess, PORT_HOSTINT_STAT, 1); 1634 if (!status) 1635 return; 1636 1637 /* Acknowledge intr. */ 1638 AGG_WR(ess, PORT_HOSTINT_STAT, status, 1); 1639 1640 if (status & HOSTINT_STAT_DSOUND) { 1641#ifdef AGG_JITTER_CORRECTION 1642 agg_lock(ess); 1643#endif 1644 if (ess->curpwr <= PCI_POWERSTATE_D1) { 1645 AGG_WR(ess, PORT_INT_STAT, 1, 2); 1646#ifdef AGG_JITTER_CORRECTION 1647 for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) { 1648 if (ess->active & m) 1649 suppress_jitter(ess->pch + i); 1650 } 1651 if (ess->active & m) 1652 suppress_rec_jitter(&ess->rch); 1653 agg_unlock(ess); 1654#endif 1655 for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) { 1656 if (ess->active & m) { 1657 if (ess->curpwr <= PCI_POWERSTATE_D1) 1658 chn_intr(ess->pch[i].channel); 1659 else { 1660 m = 0; 1661 break; 1662 } 1663 } 1664 } 1665 if ((ess->active & m) 1666 && ess->curpwr <= PCI_POWERSTATE_D1) 1667 chn_intr(ess->rch.channel); 1668 } 1669#ifdef AGG_JITTER_CORRECTION 1670 else 1671 agg_unlock(ess); 1672#endif 1673 } 1674 1675 if (status & HOSTINT_STAT_HWVOL) { 1676 register u_int8_t event; 1677 1678 agg_lock(ess); 1679 event = AGG_RD(ess, PORT_HWVOL_MASTER, 1); 1680 AGG_WR(ess, PORT_HWVOL_MASTER, HWVOL_NOP, 1); 1681 agg_unlock(ess); 1682 1683 switch (event) { 1684 case HWVOL_UP: 1685 mixer_hwvol_step(ess->dev, 1, 1); 1686 break; 1687 case HWVOL_DOWN: 1688 mixer_hwvol_step(ess->dev, -1, -1); 1689 break; 1690 case HWVOL_NOP: 1691 break; 1692 default: 1693 if (event & HWVOL_MUTE) { 1694 mixer_hwvol_mute(ess->dev); 1695 break; 1696 } 1697 device_printf(ess->dev, 1698 "%s: unknown HWVOL event 0x%x\n", 1699 device_get_nameunit(ess->dev), event); 1700 } 1701 } 1702} 1703 1704static void 1705setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1706{ 1707 bus_addr_t *phys = arg; 1708 1709 *phys = error? 0 : segs->ds_addr; 1710 1711 if (bootverbose) { 1712 printf("setmap (%lx, %lx), nseg=%d, error=%d\n", 1713 (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len, 1714 nseg, error); 1715 } 1716} 1717 1718static void * 1719dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys) 1720{ 1721 void *buf; 1722 bus_dmamap_t map; 1723 1724 if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, &map)) 1725 return NULL; 1726 if (bus_dmamap_load(dmat, map, buf, sz, setmap, phys, 0) 1727 || !*phys || map) { 1728 bus_dmamem_free(dmat, buf, map); 1729 return NULL; 1730 } 1731 return buf; 1732} 1733 1734static void 1735dma_free(bus_dma_tag_t dmat, void *buf) 1736{ 1737 bus_dmamem_free(dmat, buf, NULL); 1738} 1739 1740static int 1741agg_probe(device_t dev) 1742{ 1743 char *s = NULL; 1744 1745 switch (pci_get_devid(dev)) { 1746 case MAESTRO_1_PCI_ID: 1747 s = "ESS Technology Maestro-1"; 1748 break; 1749 1750 case MAESTRO_2_PCI_ID: 1751 s = "ESS Technology Maestro-2"; 1752 break; 1753 1754 case MAESTRO_2E_PCI_ID: 1755 s = "ESS Technology Maestro-2E"; 1756 break; 1757 } 1758 1759 if (s != NULL && pci_get_class(dev) == PCIC_MULTIMEDIA) { 1760 device_set_desc(dev, s); 1761 return BUS_PROBE_DEFAULT; 1762 } 1763 return ENXIO; 1764} 1765 1766static int 1767agg_attach(device_t dev) 1768{ 1769 struct agg_info *ess = NULL; 1770 u_int32_t data; 1771 int regid = PCIR_BAR(0); 1772 struct resource *reg = NULL; 1773 struct ac97_info *codec = NULL; 1774 int irqid = 0; 1775 struct resource *irq = NULL; 1776 void *ih = NULL; 1777 char status[SND_STATUSLEN]; 1778 int dacn, ret = 0; 1779 1780 ess = malloc(sizeof(*ess), M_DEVBUF, M_WAITOK | M_ZERO); 1781 ess->dev = dev; 1782 1783 mtx_init(&ess->lock, device_get_desc(dev), "snd_maestro softc", 1784 MTX_DEF | MTX_RECURSE); 1785 if (!mtx_initialized(&ess->lock)) { 1786 device_printf(dev, "failed to create a mutex.\n"); 1787 ret = ENOMEM; 1788 goto bad; 1789 } 1790 1791 if (resource_int_value(device_get_name(dev), device_get_unit(dev), 1792 "dac", &dacn) == 0) { 1793 if (dacn < 1) 1794 dacn = 1; 1795 else if (dacn > AGG_MAXPLAYCH) 1796 dacn = AGG_MAXPLAYCH; 1797 } else 1798 dacn = AGG_MAXPLAYCH; 1799 1800 ess->bufsz = pcm_getbuffersize(dev, 4096, AGG_DEFAULT_BUFSZ, 65536); 1801 if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev), 1802 /*align */ 4, 1 << (16+1), 1803 /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR, 1804 /*filter*/ NULL, NULL, 1805 /*size */ ess->bufsz, 1, 0x3ffff, 1806 /*flags */ 0, 1807#if __FreeBSD_version >= 501102 1808 /*lock */ busdma_lock_mutex, &Giant, 1809#endif 1810 &ess->buf_dmat) != 0) { 1811 device_printf(dev, "unable to create dma tag\n"); 1812 ret = ENOMEM; 1813 goto bad; 1814 } 1815 1816 if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev), 1817 /*align */ 1 << WAVCACHE_BASEADDR_SHIFT, 1818 1 << (16+1), 1819 /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR, 1820 /*filter*/ NULL, NULL, 1821 /*size */ 3*ess->bufsz, 1, 0x3ffff, 1822 /*flags */ 0, 1823#if __FreeBSD_version >= 501102 1824 /*lock */ busdma_lock_mutex, &Giant, 1825#endif 1826 &ess->stat_dmat) != 0) { 1827 device_printf(dev, "unable to create dma tag\n"); 1828 ret = ENOMEM; 1829 goto bad; 1830 } 1831 1832 /* Allocate the room for brain-damaging status buffer. */ 1833 ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys); 1834 if (ess->stat == NULL) { 1835 device_printf(dev, "cannot allocate status buffer\n"); 1836 ret = ENOMEM; 1837 goto bad; 1838 } 1839 if (bootverbose) 1840 device_printf(dev, "Maestro status/record buffer: %#llx\n", 1841 (long long)ess->phys); 1842 1843 /* State D0-uninitialized. */ 1844 ess->curpwr = PCI_POWERSTATE_D3; 1845 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 1846 1847 pci_enable_busmaster(dev); 1848 1849 /* Allocate resources. */ 1850 reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, ®id, RF_ACTIVE); 1851 if (reg != NULL) { 1852 ess->reg = reg; 1853 ess->regid = regid; 1854 ess->st = rman_get_bustag(reg); 1855 ess->sh = rman_get_bushandle(reg); 1856 } else { 1857 device_printf(dev, "unable to map register space\n"); 1858 ret = ENXIO; 1859 goto bad; 1860 } 1861 irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqid, 1862 RF_ACTIVE | RF_SHAREABLE); 1863 if (irq != NULL) { 1864 ess->irq = irq; 1865 ess->irqid = irqid; 1866 } else { 1867 device_printf(dev, "unable to map interrupt\n"); 1868 ret = ENXIO; 1869 goto bad; 1870 } 1871 1872 /* Setup resources. */ 1873 if (snd_setup_intr(dev, irq, INTR_MPSAFE, agg_intr, ess, &ih)) { 1874 device_printf(dev, "unable to setup interrupt\n"); 1875 ret = ENXIO; 1876 goto bad; 1877 } else 1878 ess->ih = ih; 1879 1880 /* Transition from D0-uninitialized to D0. */ 1881 agg_lock(ess); 1882 agg_power(ess, PCI_POWERSTATE_D0); 1883 if (agg_rdcodec(ess, 0) == 0x80) { 1884 /* XXX - TODO: PT101 */ 1885 agg_unlock(ess); 1886 device_printf(dev, "PT101 codec detected!\n"); 1887 ret = ENXIO; 1888 goto bad; 1889 } 1890 agg_unlock(ess); 1891 codec = AC97_CREATE(dev, ess, agg_ac97); 1892 if (codec == NULL) { 1893 device_printf(dev, "failed to create AC97 codec softc!\n"); 1894 ret = ENOMEM; 1895 goto bad; 1896 } 1897 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) { 1898 device_printf(dev, "mixer initialization failed!\n"); 1899 ret = ENXIO; 1900 goto bad; 1901 } 1902 ess->codec = codec; 1903 1904 ret = pcm_register(dev, ess, dacn, 1); 1905 if (ret) 1906 goto bad; 1907 1908 mixer_hwvol_init(dev); 1909 agg_lock(ess); 1910 agg_power(ess, powerstate_init); 1911 agg_unlock(ess); 1912 for (data = 0; data < dacn; data++) 1913 pcm_addchan(dev, PCMDIR_PLAY, &aggpch_class, ess); 1914 pcm_addchan(dev, PCMDIR_REC, &aggrch_class, ess); 1915 adjust_pchbase(ess->pch, ess->playchns, ess->bufsz); 1916 1917 snprintf(status, SND_STATUSLEN, 1918 "port 0x%lx-0x%lx irq %ld at device %d.%d on pci%d", 1919 rman_get_start(reg), rman_get_end(reg), rman_get_start(irq), 1920 pci_get_slot(dev), pci_get_function(dev), pci_get_bus(dev)); 1921 pcm_setstatus(dev, status); 1922 1923 return 0; 1924 1925 bad: 1926 if (codec != NULL) 1927 ac97_destroy(codec); 1928 if (ih != NULL) 1929 bus_teardown_intr(dev, irq, ih); 1930 if (irq != NULL) 1931 bus_release_resource(dev, SYS_RES_IRQ, irqid, irq); 1932 if (reg != NULL) 1933 bus_release_resource(dev, SYS_RES_IOPORT, regid, reg); 1934 if (ess != NULL) { 1935 if (ess->stat != NULL) 1936 dma_free(ess->stat_dmat, ess->stat); 1937 if (ess->stat_dmat != NULL) 1938 bus_dma_tag_destroy(ess->stat_dmat); 1939 if (ess->buf_dmat != NULL) 1940 bus_dma_tag_destroy(ess->buf_dmat); 1941 if (mtx_initialized(&ess->lock)) 1942 mtx_destroy(&ess->lock); 1943 free(ess, M_DEVBUF); 1944 } 1945 1946 return ret; 1947} 1948 1949static int 1950agg_detach(device_t dev) 1951{ 1952 struct agg_info *ess = pcm_getdevinfo(dev); 1953 int r; 1954 u_int16_t icr; 1955 1956 icr = AGG_RD(ess, PORT_HOSTINT_CTRL, 2); 1957 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); 1958 1959 agg_lock(ess); 1960 if (ess->active) { 1961 AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2); 1962 agg_unlock(ess); 1963 return EBUSY; 1964 } 1965 agg_unlock(ess); 1966 1967 r = pcm_unregister(dev); 1968 if (r) { 1969 AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2); 1970 return r; 1971 } 1972 1973 agg_lock(ess); 1974 agg_power(ess, PCI_POWERSTATE_D3); 1975 agg_unlock(ess); 1976 1977 bus_teardown_intr(dev, ess->irq, ess->ih); 1978 bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq); 1979 bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg); 1980 dma_free(ess->stat_dmat, ess->stat); 1981 bus_dma_tag_destroy(ess->stat_dmat); 1982 bus_dma_tag_destroy(ess->buf_dmat); 1983 mtx_destroy(&ess->lock); 1984 free(ess, M_DEVBUF); 1985 return 0; 1986} 1987 1988static int 1989agg_suspend(device_t dev) 1990{ 1991 struct agg_info *ess = pcm_getdevinfo(dev); 1992 1993 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2); 1994 agg_lock(ess); 1995 agg_power(ess, PCI_POWERSTATE_D3); 1996 agg_unlock(ess); 1997 1998 return 0; 1999} 2000 2001static int 2002agg_resume(device_t dev) 2003{ 2004 int i; 2005 struct agg_info *ess = pcm_getdevinfo(dev); 2006 2007 for (i = 0; i < ess->playchns; i++) 2008 if (ess->active & (1 << i)) 2009 aggch_start_dac(ess->pch + i); 2010 if (ess->active & (1 << i)) 2011 aggch_start_adc(&ess->rch); 2012 2013 agg_lock(ess); 2014 if (!ess->active) 2015 agg_power(ess, powerstate_init); 2016 agg_unlock(ess); 2017 2018 if (mixer_reinit(dev)) { 2019 device_printf(dev, "unable to reinitialize the mixer\n"); 2020 return ENXIO; 2021 } 2022 2023 return 0; 2024} 2025 2026static int 2027agg_shutdown(device_t dev) 2028{ 2029 struct agg_info *ess = pcm_getdevinfo(dev); 2030 2031 agg_lock(ess); 2032 agg_power(ess, PCI_POWERSTATE_D3); 2033 agg_unlock(ess); 2034 2035 return 0; 2036} 2037 2038 2039static device_method_t agg_methods[] = { 2040 DEVMETHOD(device_probe, agg_probe), 2041 DEVMETHOD(device_attach, agg_attach), 2042 DEVMETHOD(device_detach, agg_detach), 2043 DEVMETHOD(device_suspend, agg_suspend), 2044 DEVMETHOD(device_resume, agg_resume), 2045 DEVMETHOD(device_shutdown, agg_shutdown), 2046 2047 { 0, 0 } 2048}; 2049 2050static driver_t agg_driver = { 2051 "pcm", 2052 agg_methods, 2053 PCM_SOFTC_SIZE, 2054}; 2055 2056/*static devclass_t pcm_devclass;*/ 2057 2058DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, 0, 0); 2059MODULE_DEPEND(snd_maestro, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 2060MODULE_VERSION(snd_maestro, 1); 2061