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