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