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