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