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