1 /* $OpenBSD: maestro.c,v 1.32 2011/12/23 21:43:20 kettenis Exp $ */ 2 /* $FreeBSD: /c/ncvs/src/sys/dev/sound/pci/maestro.c,v 1.3 2000/11/21 12:22:11 julian Exp $ */ 3 /* 4 * FreeBSD's ESS Agogo/Maestro driver 5 * Converted from FreeBSD's pcm to OpenBSD's audio. 6 * Copyright (c) 2000, 2001 David Leonard & Marc Espie 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 /*- 31 * (FreeBSD) Credits: 32 * Copyright (c) 2000 Taku YAMAMOTO <taku@cent.saitama-u.ac.jp> 33 * 34 * Part of this code (especially in many magic numbers) was heavily inspired 35 * by the Linux driver originally written by 36 * Alan Cox <alan.cox@linux.org>, modified heavily by 37 * Zach Brown <zab@zabbo.net>. 38 * 39 * busdma()-ize and buffer size reduction were suggested by 40 * Cameron Grant <gandalf@vilnya.demon.co.uk>. 41 * Also he showed me the way to use busdma() suite. 42 * 43 * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500 44 * were looked at by 45 * Munehiro Matsuda <haro@tk.kubota.co.jp>, 46 * who brought patches based on the Linux driver with some simplification. 47 */ 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/malloc.h> 53 #include <sys/device.h> 54 #include <sys/queue.h> 55 #include <sys/fcntl.h> 56 57 #include <dev/pci/pcidevs.h> 58 #include <dev/pci/pcivar.h> 59 60 #include <sys/audioio.h> 61 #include <dev/audio_if.h> 62 #include <dev/mulaw.h> 63 #include <dev/auconv.h> 64 65 #include <dev/ic/ac97.h> 66 67 /* ----------------------------- 68 * PCI config registers 69 */ 70 71 /* Legacy emulation */ 72 #define CONF_LEGACY 0x40 73 74 #define LEGACY_DISABLED 0x8000 75 76 /* Chip configurations */ 77 #define CONF_MAESTRO 0x50 78 #define MAESTRO_CHIBUS 0x00100000 79 #define MAESTRO_POSTEDWRITE 0x00000080 80 #define MAESTRO_DMA_PCITIMING 0x00000040 81 #define MAESTRO_SWAP_LR 0x00000010 82 83 /* ACPI configurations */ 84 #define CONF_ACPI_STOPCLOCK 0x54 85 #define ACPI_PART_2ndC_CLOCK 15 86 #define ACPI_PART_CODEC_CLOCK 14 87 #define ACPI_PART_978 13 /* Docking station or something */ 88 #define ACPI_PART_SPDIF 12 89 #define ACPI_PART_GLUE 11 /* What? */ 90 #define ACPI_PART_DAA 10 91 #define ACPI_PART_PCI_IF 9 92 #define ACPI_PART_HW_VOL 8 93 #define ACPI_PART_GPIO 7 94 #define ACPI_PART_ASSP 6 95 #define ACPI_PART_SB 5 96 #define ACPI_PART_FM 4 97 #define ACPI_PART_RINGBUS 3 98 #define ACPI_PART_MIDI 2 99 #define ACPI_PART_GAME_PORT 1 100 #define ACPI_PART_WP 0 101 102 103 /* ----------------------------- 104 * I/O ports 105 */ 106 107 /* Direct Sound Processor (aka Wave Processor) */ 108 #define PORT_DSP_DATA 0x00 /* WORD RW */ 109 #define PORT_DSP_INDEX 0x02 /* WORD RW */ 110 #define PORT_INT_STAT 0x04 /* WORD RW */ 111 #define PORT_SAMPLE_CNT 0x06 /* WORD RO */ 112 113 /* WaveCache */ 114 #define PORT_WAVCACHE_INDEX 0x10 /* WORD RW */ 115 #define PORT_WAVCACHE_DATA 0x12 /* WORD RW */ 116 #define WAVCACHE_PCMBAR 0x1fc 117 #define WAVCACHE_WTBAR 0x1f0 118 #define WAVCACHE_BASEADDR_SHIFT 12 119 120 #define WAVCACHE_CHCTL_ADDRTAG_MASK 0xfff8 121 #define WAVCACHE_CHCTL_U8 0x0004 122 #define WAVCACHE_CHCTL_STEREO 0x0002 123 #define WAVCACHE_CHCTL_DECREMENTAL 0x0001 124 125 #define PORT_WAVCACHE_CTRL 0x14 /* WORD RW */ 126 #define WAVCACHE_EXTRA_CH_ENABLED 0x0200 127 #define WAVCACHE_ENABLED 0x0100 128 #define WAVCACHE_CH_60_ENABLED 0x0080 129 #define WAVCACHE_WTSIZE_MASK 0x0060 130 #define WAVCACHE_WTSIZE_1MB 0x0000 131 #define WAVCACHE_WTSIZE_2MB 0x0020 132 #define WAVCACHE_WTSIZE_4MB 0x0040 133 #define WAVCACHE_WTSIZE_8MB 0x0060 134 #define WAVCACHE_SGC_MASK 0x000c 135 #define WAVCACHE_SGC_DISABLED 0x0000 136 #define WAVCACHE_SGC_40_47 0x0004 137 #define WAVCACHE_SGC_32_47 0x0008 138 #define WAVCACHE_TESTMODE 0x0001 139 140 /* Host Interruption */ 141 #define PORT_HOSTINT_CTRL 0x18 /* WORD RW */ 142 #define HOSTINT_CTRL_SOFT_RESET 0x8000 143 #define HOSTINT_CTRL_DSOUND_RESET 0x4000 144 #define HOSTINT_CTRL_HW_VOL_TO_PME 0x0400 145 #define HOSTINT_CTRL_CLKRUN_ENABLED 0x0100 146 #define HOSTINT_CTRL_HWVOL_ENABLED 0x0040 147 #define HOSTINT_CTRL_ASSP_INT_ENABLED 0x0010 148 #define HOSTINT_CTRL_ISDN_INT_ENABLED 0x0008 149 #define HOSTINT_CTRL_DSOUND_INT_ENABLED 0x0004 150 #define HOSTINT_CTRL_MPU401_INT_ENABLED 0x0002 151 #define HOSTINT_CTRL_SB_INT_ENABLED 0x0001 152 153 #define PORT_HOSTINT_STAT 0x1a /* BYTE RW */ 154 #define HOSTINT_STAT_HWVOL 0x40 155 #define HOSTINT_STAT_ASSP 0x10 156 #define HOSTINT_STAT_ISDN 0x08 157 #define HOSTINT_STAT_DSOUND 0x04 158 #define HOSTINT_STAT_MPU401 0x02 159 #define HOSTINT_STAT_SB 0x01 160 161 /* Hardware volume */ 162 #define PORT_HWVOL_VOICE_SHADOW 0x1c /* BYTE RW */ 163 #define PORT_HWVOL_VOICE 0x1d /* BYTE RW */ 164 #define PORT_HWVOL_MASTER_SHADOW 0x1e /* BYTE RW */ 165 #define PORT_HWVOL_MASTER 0x1f /* BYTE RW */ 166 167 /* CODEC */ 168 #define PORT_CODEC_CMD 0x30 /* BYTE W */ 169 #define CODEC_CMD_READ 0x80 170 #define CODEC_CMD_WRITE 0x00 171 #define CODEC_CMD_ADDR_MASK 0x7f 172 173 #define PORT_CODEC_STAT 0x30 /* BYTE R */ 174 #define CODEC_STAT_MASK 0x01 175 #define CODEC_STAT_RW_DONE 0x00 176 #define CODEC_STAT_PROGLESS 0x01 177 178 #define PORT_CODEC_REG 0x32 /* WORD RW */ 179 180 /* Ring bus control */ 181 #define PORT_RINGBUS_CTRL 0x34 /* DWORD RW */ 182 #define RINGBUS_CTRL_I2S_ENABLED 0x80000000 183 #define RINGBUS_CTRL_RINGBUS_ENABLED 0x20000000 184 #define RINGBUS_CTRL_ACLINK_ENABLED 0x10000000 185 #define RINGBUS_CTRL_AC97_SWRESET 0x08000000 186 #define RINGBUS_CTRL_IODMA_PLAYBACK_ENABLED 0x04000000 187 #define RINGBUS_CTRL_IODMA_RECORD_ENABLED 0x02000000 188 189 #define RINGBUS_SRC_MIC 20 190 #define RINGBUS_SRC_I2S 16 191 #define RINGBUS_SRC_ADC 12 192 #define RINGBUS_SRC_MODEM 8 193 #define RINGBUS_SRC_DSOUND 4 194 #define RINGBUS_SRC_ASSP 0 195 196 #define RINGBUS_DEST_MONORAL 000 197 #define RINGBUS_DEST_STEREO 010 198 #define RINGBUS_DEST_NONE 0 199 #define RINGBUS_DEST_DAC 1 200 #define RINGBUS_DEST_MODEM_IN 2 201 #define RINGBUS_DEST_RESERVED3 3 202 #define RINGBUS_DEST_DSOUND_IN 4 203 #define RINGBUS_DEST_ASSP_IN 5 204 205 /* General Purpose I/O */ 206 #define PORT_GPIO_DATA 0x60 /* WORD RW */ 207 #define PORT_GPIO_MASK 0x64 /* WORD RW */ 208 #define PORT_GPIO_DIR 0x68 /* WORD RW */ 209 210 /* Application Specific Signal Processor */ 211 #define PORT_ASSP_MEM_INDEX 0x80 /* DWORD RW */ 212 #define PORT_ASSP_MEM_DATA 0x84 /* WORD RW */ 213 #define PORT_ASSP_CTRL_A 0xa2 /* BYTE RW */ 214 #define PORT_ASSP_CTRL_B 0xa4 /* BYTE RW */ 215 #define PORT_ASSP_CTRL_C 0xa6 /* BYTE RW */ 216 #define PORT_ASSP_HOST_WR_INDEX 0xa8 /* BYTE W */ 217 #define PORT_ASSP_HOST_WR_DATA 0xaa /* BYTE RW */ 218 #define PORT_ASSP_INT_STAT 0xac /* BYTE RW */ 219 220 221 /* ----------------------------- 222 * Wave Processor Indexed Data Registers. 223 */ 224 225 #define WPREG_DATA_PORT 0 226 #define WPREG_CRAM_PTR 1 227 #define WPREG_CRAM_DATA 2 228 #define WPREG_WAVE_DATA 3 229 #define WPREG_WAVE_PTR_LOW 4 230 #define WPREG_WAVE_PTR_HIGH 5 231 232 #define WPREG_TIMER_FREQ 6 233 #define WP_TIMER_FREQ_PRESCALE_MASK 0x00e0 /* actual - 9 */ 234 #define WP_TIMER_FREQ_PRESCALE_SHIFT 5 235 #define WP_TIMER_FREQ_DIVIDE_MASK 0x001f 236 #define WP_TIMER_FREQ_DIVIDE_SHIFT 0 237 238 #define WPREG_WAVE_ROMRAM 7 239 #define WP_WAVE_VIRTUAL_ENABLED 0x0400 240 #define WP_WAVE_8BITRAM_ENABLED 0x0200 241 #define WP_WAVE_DRAM_ENABLED 0x0100 242 #define WP_WAVE_RAMSPLIT_MASK 0x00ff 243 #define WP_WAVE_RAMSPLIT_SHIFT 0 244 245 #define WPREG_BASE 12 246 #define WP_PARAOUT_BASE_MASK 0xf000 247 #define WP_PARAOUT_BASE_SHIFT 12 248 #define WP_PARAIN_BASE_MASK 0x0f00 249 #define WP_PARAIN_BASE_SHIFT 8 250 #define WP_SERIAL0_BASE_MASK 0x00f0 251 #define WP_SERIAL0_BASE_SHIFT 4 252 #define WP_SERIAL1_BASE_MASK 0x000f 253 #define WP_SERIAL1_BASE_SHIFT 0 254 255 #define WPREG_TIMER_ENABLE 17 256 #define WPREG_TIMER_START 23 257 258 259 /* ----------------------------- 260 * Audio Processing Unit. 261 */ 262 #define APUREG_APUTYPE 0 263 #define APU_DMA_ENABLED 0x4000 264 #define APU_INT_ON_LOOP 0x2000 265 #define APU_ENDCURVE 0x1000 266 #define APU_APUTYPE_MASK 0x00f0 267 #define APU_FILTERTYPE_MASK 0x000c 268 #define APU_FILTERQ_MASK 0x0003 269 270 /* APU types */ 271 #define APU_APUTYPE_SHIFT 4 272 273 #define APUTYPE_INACTIVE 0 274 #define APUTYPE_16BITLINEAR 1 275 #define APUTYPE_16BITSTEREO 2 276 #define APUTYPE_8BITLINEAR 3 277 #define APUTYPE_8BITSTEREO 4 278 #define APUTYPE_8BITDIFF 5 279 #define APUTYPE_DIGITALDELAY 6 280 #define APUTYPE_DUALTAP_READER 7 281 #define APUTYPE_CORRELATOR 8 282 #define APUTYPE_INPUTMIXER 9 283 #define APUTYPE_WAVETABLE 10 284 #define APUTYPE_RATECONV 11 285 #define APUTYPE_16BITPINGPONG 12 286 /* APU type 13 through 15 are reserved. */ 287 288 /* Filter types */ 289 #define APU_FILTERTYPE_SHIFT 2 290 291 #define FILTERTYPE_2POLE_LOPASS 0 292 #define FILTERTYPE_2POLE_BANDPASS 1 293 #define FILTERTYPE_2POLE_HIPASS 2 294 #define FILTERTYPE_1POLE_LOPASS 3 295 #define FILTERTYPE_1POLE_HIPASS 4 296 #define FILTERTYPE_PASSTHROUGH 5 297 298 /* Filter Q */ 299 #define APU_FILTERQ_SHIFT 0 300 301 #define FILTERQ_LESSQ 0 302 #define FILTERQ_MOREQ 3 303 304 /* APU register 2 */ 305 #define APUREG_FREQ_LOBYTE 2 306 #define APU_FREQ_LOBYTE_MASK 0xff00 307 #define APU_plus6dB 0x0010 308 309 /* APU register 3 */ 310 #define APUREG_FREQ_HIWORD 3 311 #define APU_FREQ_HIWORD_MASK 0x0fff 312 313 /* Frequency */ 314 #define APU_FREQ_LOBYTE_SHIFT 8 315 #define APU_FREQ_HIWORD_SHIFT 0 316 #define FREQ_Hz2DIV(freq) (((u_int64_t)(freq) << 16) / 48000) 317 318 /* APU register 4 */ 319 #define APUREG_WAVESPACE 4 320 #define APU_STEREO 0x8000 321 #define APU_USE_SYSMEM 0x4000 322 #define APU_PCMBAR_MASK 0x6000 323 #define APU_64KPAGE_MASK 0xff00 324 325 /* PCM Base Address Register selection */ 326 #define APU_PCMBAR_SHIFT 13 327 328 /* 64KW (==128KB) Page */ 329 #define APU_64KPAGE_SHIFT 8 330 331 /* APU register 5 - 7 */ 332 #define APUREG_CURPTR 5 333 #define APUREG_ENDPTR 6 334 #define APUREG_LOOPLEN 7 335 336 /* APU register 9 */ 337 #define APUREG_AMPLITUDE 9 338 #define APU_AMPLITUDE_NOW_MASK 0xff00 339 #define APU_AMPLITUDE_DEST_MASK 0x00ff 340 341 /* Amplitude now? */ 342 #define APU_AMPLITUDE_NOW_SHIFT 8 343 344 /* APU register 10 */ 345 #define APUREG_POSITION 10 346 #define APU_RADIUS_MASK 0x00c0 347 #define APU_PAN_MASK 0x003f 348 349 /* Radius control. */ 350 #define APU_RADIUS_SHIFT 6 351 #define RADIUS_CENTERCIRCLE 0 352 #define RADIUS_MIDDLE 1 353 #define RADIUS_OUTSIDE 2 354 355 /* Polar pan. */ 356 #define APU_PAN_SHIFT 0 357 #define PAN_RIGHT 0x00 358 #define PAN_FRONT 0x08 359 #define PAN_LEFT 0x10 360 361 362 /* ----------------------------- 363 * Limits. 364 */ 365 #define WPWA_MAX ((1 << 22) - 1) 366 #define WPWA_MAXADDR ((1 << 23) - 1) 367 #define MAESTRO_MAXADDR ((1 << 28) - 1) 368 369 370 371 #ifdef AUDIO_DEBUG 372 #define DPRINTF(x) if (maestrodebug) printf x 373 #define DLPRINTF(i, x) if (maestrodebug & i) printf x 374 int maestrodebug = 0; 375 u_long maestrointr_called; 376 u_long maestrodma_effective; 377 378 #define MAESTRODEBUG_INTR 1 379 #define MAESTRODEBUG_TIMER 2 380 #else 381 #define DPRINTF(x) 382 #define DLPRINTF(i, x) 383 #endif 384 385 #define MAESTRO_BUFSIZ 0x4000 386 #define lengthof(array) (sizeof (array) / sizeof (array)[0]) 387 388 #define STEP_VOLUME 0x22 389 #define MIDDLE_VOLUME (STEP_VOLUME * 4) 390 391 typedef struct salloc_pool { 392 struct salloc_zone { 393 SLIST_ENTRY(salloc_zone) link; 394 caddr_t addr; 395 size_t size; 396 } *zones; 397 SLIST_HEAD(salloc_head, salloc_zone) free, used, spare; 398 } *salloc_t; 399 400 struct maestro_softc; 401 402 #define MAESTRO_PLAY 1 403 #define MAESTRO_STEREO 2 404 #define MAESTRO_8BIT 4 405 #define MAESTRO_UNSIGNED 8 406 #define MAESTRO_RUNNING 16 407 408 struct maestro_channel { 409 struct maestro_softc *sc; 410 int num; 411 u_int32_t blocksize; 412 u_int16_t mode; 413 u_int32_t speed; 414 u_int32_t dv; 415 u_int16_t start; 416 u_int16_t threshold; 417 u_int16_t end; 418 u_int16_t current; 419 u_int wpwa; 420 void (*intr)(void *); 421 void *intr_arg; 422 }; 423 424 struct maestro_softc { 425 struct device dev; 426 427 void *ih; 428 pci_chipset_tag_t pc; 429 pcitag_t pt; 430 431 #define MAESTRO_FLAG_SETUPGPIO 0x0001 432 int flags; 433 bus_space_tag_t iot; 434 bus_space_handle_t ioh; 435 bus_dma_tag_t dmat; 436 437 caddr_t dmabase; 438 bus_addr_t physaddr; 439 size_t dmasize; 440 bus_dmamap_t dmamap; 441 bus_dma_segment_t dmaseg; 442 salloc_t dmapool; 443 444 struct ac97_codec_if *codec_if; 445 struct ac97_host_if host_if; 446 struct audio_device *sc_audev; 447 448 int suspend; 449 450 struct maestro_channel play; 451 struct maestro_channel record; 452 }; 453 454 455 typedef u_int16_t wpreg_t; 456 typedef u_int16_t wcreg_t; 457 458 salloc_t salloc_new(caddr_t, size_t, int); 459 void salloc_destroy(salloc_t); 460 caddr_t salloc_alloc(salloc_t, size_t); 461 void salloc_free(salloc_t, caddr_t); 462 void salloc_insert(salloc_t, struct salloc_head *, 463 struct salloc_zone *, int); 464 465 int maestro_match(struct device *, void *, void *); 466 void maestro_attach(struct device *, struct device *, void *); 467 int maestro_activate(struct device *, int); 468 int maestro_intr(void *); 469 470 int maestro_open(void *, int); 471 void maestro_close(void *); 472 int maestro_query_encoding(void *, struct audio_encoding *); 473 int maestro_set_params(void *, int, int, struct audio_params *, 474 struct audio_params *); 475 void maestro_get_default_params(void *, int, struct audio_params *); 476 int maestro_round_blocksize(void *, int); 477 int maestro_halt_output(void *); 478 int maestro_halt_input(void *); 479 int maestro_getdev(void *, struct audio_device *); 480 int maestro_set_port(void *, mixer_ctrl_t *); 481 int maestro_get_port(void *, mixer_ctrl_t *); 482 int maestro_query_devinfo(void *, mixer_devinfo_t *); 483 void *maestro_malloc(void *, int, size_t, int, int); 484 void maestro_free(void *, void *, int); 485 paddr_t maestro_mappage(void *, void *, off_t, int); 486 int maestro_get_props(void *); 487 int maestro_trigger_output(void *, void *, void *, int, void (*)(void *), 488 void *, struct audio_params *); 489 int maestro_trigger_input(void *, void *, void *, int, void (*)(void *), 490 void *, struct audio_params *); 491 492 int maestro_attach_codec(void *, struct ac97_codec_if *); 493 enum ac97_host_flags maestro_codec_flags(void *); 494 int maestro_read_codec(void *, u_int8_t, u_int16_t *); 495 int maestro_write_codec(void *, u_int8_t, u_int16_t); 496 void maestro_reset_codec(void *); 497 498 void maestro_initcodec(void *); 499 500 void maestro_set_speed(struct maestro_channel *, u_long *); 501 void maestro_init(struct maestro_softc *); 502 503 void maestro_channel_start(struct maestro_channel *); 504 void maestro_channel_stop(struct maestro_channel *); 505 void maestro_channel_advance_dma(struct maestro_channel *); 506 void maestro_channel_suppress_jitter(struct maestro_channel *); 507 508 int maestro_get_flags(struct pci_attach_args *); 509 510 void ringbus_setdest(struct maestro_softc *, int, int); 511 512 wpreg_t wp_reg_read(struct maestro_softc *, int); 513 void wp_reg_write(struct maestro_softc *, int, wpreg_t); 514 wpreg_t wp_apu_read(struct maestro_softc *, int, int); 515 void wp_apu_write(struct maestro_softc *, int, int, wpreg_t); 516 void wp_settimer(struct maestro_softc *, u_int); 517 void wp_starttimer(struct maestro_softc *); 518 void wp_stoptimer(struct maestro_softc *); 519 520 wcreg_t wc_reg_read(struct maestro_softc *, int); 521 void wc_reg_write(struct maestro_softc *, int, wcreg_t); 522 wcreg_t wc_ctrl_read(struct maestro_softc *, int); 523 void wc_ctrl_write(struct maestro_softc *, int, wcreg_t); 524 525 u_int maestro_calc_timer_freq(struct maestro_channel *); 526 void maestro_update_timer(struct maestro_softc *); 527 528 struct cfdriver maestro_cd = { 529 NULL, "maestro", DV_DULL 530 }; 531 532 struct cfattach maestro_ca = { 533 sizeof (struct maestro_softc), maestro_match, maestro_attach, 534 NULL, maestro_activate 535 }; 536 537 struct audio_hw_if maestro_hw_if = { 538 maestro_open, 539 maestro_close, 540 NULL, 541 maestro_query_encoding, 542 maestro_set_params, 543 maestro_round_blocksize, 544 NULL, 545 NULL, 546 NULL, 547 NULL, 548 NULL, 549 maestro_halt_output, 550 maestro_halt_input, 551 NULL, 552 maestro_getdev, 553 NULL, 554 maestro_set_port, 555 maestro_get_port, 556 maestro_query_devinfo, 557 maestro_malloc, 558 maestro_free, 559 NULL, 560 maestro_mappage, 561 maestro_get_props, 562 maestro_trigger_output, 563 maestro_trigger_input, 564 maestro_get_default_params 565 }; 566 567 struct audio_device maestro_audev = { 568 "ESS Maestro", "", "maestro" 569 }; 570 571 struct { 572 u_short vendor, product; 573 int flags; 574 } maestro_pcitab[] = { 575 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTROII, 0 }, 576 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO2E, 0 }, 577 { PCI_VENDOR_PLATFORM, PCI_PRODUCT_PLATFORM_ES1849, 0 }, 578 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAMAESTRO, MAESTRO_FLAG_SETUPGPIO }, 579 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAPRONXVA26D, MAESTRO_FLAG_SETUPGPIO } 580 }; 581 #define NMAESTRO_PCITAB lengthof(maestro_pcitab) 582 583 int 584 maestro_get_flags(pa) 585 struct pci_attach_args *pa; 586 { 587 int i; 588 589 /* Distinguish audio devices from modems with the same manfid */ 590 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_MULTIMEDIA) 591 return (-1); 592 if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MULTIMEDIA_AUDIO) 593 return (-1); 594 for (i = 0; i < NMAESTRO_PCITAB; i++) 595 if (PCI_VENDOR(pa->pa_id) == maestro_pcitab[i].vendor && 596 PCI_PRODUCT(pa->pa_id) == maestro_pcitab[i].product) 597 return (maestro_pcitab[i].flags); 598 return (-1); 599 } 600 601 /* ----------------------------- 602 * Driver interface. 603 */ 604 605 int 606 maestro_match(parent, match, aux) 607 struct device *parent; 608 void *match; 609 void *aux; 610 { 611 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 612 613 if (maestro_get_flags(pa) == -1) 614 return (0); 615 else 616 return (1); 617 } 618 619 void 620 maestro_attach(parent, self, aux) 621 struct device *parent; 622 struct device *self; 623 void *aux; 624 { 625 struct maestro_softc *sc = (struct maestro_softc *)self; 626 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 627 pci_chipset_tag_t pc = pa->pa_pc; 628 char const *intrstr; 629 pci_intr_handle_t ih; 630 int error; 631 u_int16_t cdata; 632 int dmastage = 0; 633 int rseg; 634 635 sc->sc_audev = &maestro_audev; 636 sc->flags = maestro_get_flags(pa); 637 638 sc->pc = pa->pa_pc; 639 sc->pt = pa->pa_tag; 640 sc->dmat = pa->pa_dmat; 641 642 /* Map interrupt */ 643 if (pci_intr_map(pa, &ih)) { 644 printf(": can't map interrupt\n"); 645 return; 646 } 647 intrstr = pci_intr_string(pc, ih); 648 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, maestro_intr, sc, 649 sc->dev.dv_xname); 650 if (sc->ih == NULL) { 651 printf(": can't establish interrupt"); 652 if (intrstr != NULL) 653 printf(" at %s\n", intrstr); 654 return; 655 } 656 printf(": %s", intrstr); 657 658 /* Rangers, power up */ 659 pci_set_powerstate(pc, sc->pt, PCI_PMCSR_STATE_D0); 660 DELAY(100000); 661 662 /* Map i/o */ 663 if ((error = pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_IO, 664 0, &sc->iot, &sc->ioh, NULL, NULL, 0)) != 0) { 665 printf(", can't map i/o space\n"); 666 goto bad; 667 }; 668 669 /* Allocate fixed DMA segment :-( */ 670 sc->dmasize = MAESTRO_BUFSIZ * 16; 671 if ((error = bus_dmamem_alloc(sc->dmat, sc->dmasize, NBPG, 0, 672 &sc->dmaseg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 673 printf(", unable to alloc dma, error %d\n", error); 674 goto bad; 675 } 676 dmastage = 1; 677 if ((error = bus_dmamem_map(sc->dmat, &sc->dmaseg, 1, 678 sc->dmasize, &sc->dmabase, BUS_DMA_NOWAIT | 679 BUS_DMA_COHERENT)) != 0) { 680 printf(", unable to map dma, error %d\n", error); 681 goto bad; 682 } 683 dmastage = 2; 684 if ((error = bus_dmamap_create(sc->dmat, sc->dmasize, 1, 685 sc->dmasize, 0, BUS_DMA_NOWAIT, &sc->dmamap)) != 0) { 686 printf(", unable to create dma map, error %d\n", error); 687 goto bad; 688 } 689 dmastage = 3; 690 if ((error = bus_dmamap_load(sc->dmat, sc->dmamap, 691 sc->dmabase, sc->dmasize, NULL, BUS_DMA_NOWAIT)) != 0) { 692 printf(", unable to load dma map, error %d\n", error); 693 goto bad; 694 } 695 696 /* XXX 697 * The first byte of the allocated memory is not usable, 698 * the WP sometimes uses it to store status. 699 */ 700 /* Make DMA memory pool */ 701 if ((sc->dmapool = salloc_new(sc->dmabase+16, sc->dmasize-16, 702 128/*overkill?*/)) == NULL) { 703 printf(", unable to make dma pool\n"); 704 goto bad; 705 } 706 707 sc->physaddr = sc->dmamap->dm_segs[0].ds_addr; 708 709 printf("\n"); 710 711 /* Kick device */ 712 maestro_init(sc); 713 maestro_read_codec(sc, 0, &cdata); 714 if (cdata == 0x80) { 715 printf("%s: PT101 codec unsupported, no mixer\n", 716 sc->dev.dv_xname); 717 /* Init values from Linux, no idea what this does. */ 718 maestro_write_codec(sc, 0x2a, 0x0001); 719 maestro_write_codec(sc, 0x2C, 0x0000); 720 maestro_write_codec(sc, 0x2C, 0xFFFF); 721 maestro_write_codec(sc, 0x10, 0x9F1F); 722 maestro_write_codec(sc, 0x12, 0x0808); 723 maestro_write_codec(sc, 0x14, 0x9F1F); 724 maestro_write_codec(sc, 0x16, 0x9F1F); 725 maestro_write_codec(sc, 0x18, 0x0404); 726 maestro_write_codec(sc, 0x1A, 0x0000); 727 maestro_write_codec(sc, 0x1C, 0x0000); 728 maestro_write_codec(sc, 0x02, 0x0404); 729 maestro_write_codec(sc, 0x04, 0x0808); 730 maestro_write_codec(sc, 0x0C, 0x801F); 731 maestro_write_codec(sc, 0x0E, 0x801F); 732 /* no control over the mixer, sorry */ 733 sc->codec_if = NULL; 734 } else { 735 /* Attach the AC'97 */ 736 sc->host_if.arg = sc; 737 sc->host_if.attach = maestro_attach_codec; 738 sc->host_if.flags = maestro_codec_flags; 739 sc->host_if.read = maestro_read_codec; 740 sc->host_if.write = maestro_write_codec; 741 sc->host_if.reset = maestro_reset_codec; 742 if (ac97_attach(&sc->host_if) != 0) { 743 printf("%s: can't attach codec\n", sc->dev.dv_xname); 744 goto bad; 745 } 746 } 747 748 sc->play.mode = MAESTRO_PLAY; 749 sc->play.sc = sc; 750 sc->play.num = 0; 751 sc->record.sc = sc; 752 sc->record.num = 2; 753 sc->record.mode = 0; 754 755 /* Attach audio */ 756 audio_attach_mi(&maestro_hw_if, sc, &sc->dev); 757 return; 758 759 bad: 760 /* Power down. */ 761 pci_set_powerstate(pc, sc->pt, PCI_PMCSR_STATE_D3); 762 if (sc->ih) 763 pci_intr_disestablish(pc, sc->ih); 764 printf("%s: disabled\n", sc->dev.dv_xname); 765 if (sc->dmapool) 766 salloc_destroy(sc->dmapool); 767 if (dmastage >= 3) 768 bus_dmamap_destroy(sc->dmat, sc->dmamap); 769 if (dmastage >= 2) 770 bus_dmamem_unmap(sc->dmat, sc->dmabase, sc->dmasize); 771 if (dmastage >= 1) 772 bus_dmamem_free(sc->dmat, &sc->dmaseg, 1); 773 } 774 775 void 776 maestro_init(sc) 777 struct maestro_softc *sc; 778 { 779 int reg; 780 pcireg_t data; 781 782 /* Disable all legacy emulations. */ 783 data = pci_conf_read(sc->pc, sc->pt, CONF_LEGACY); 784 data |= LEGACY_DISABLED; 785 pci_conf_write(sc->pc, sc->pt, CONF_LEGACY, data); 786 787 /* Disconnect from CHI. (Makes Dell inspiron 7500 work?) 788 * Enable posted write. 789 * Prefer PCI timing rather than that of ISA. 790 * Don't swap L/R. */ 791 data = pci_conf_read(sc->pc, sc->pt, CONF_MAESTRO); 792 data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING; 793 data &= ~MAESTRO_SWAP_LR; 794 pci_conf_write(sc->pc, sc->pt, CONF_MAESTRO, data); 795 /* Reset direct sound. */ 796 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 797 HOSTINT_CTRL_DSOUND_RESET); 798 DELAY(10000); /* XXX - too long? */ 799 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0); 800 DELAY(10000); 801 802 /* Enable direct sound and hardware volume control interruptions. */ 803 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 804 HOSTINT_CTRL_DSOUND_INT_ENABLED | HOSTINT_CTRL_HWVOL_ENABLED); 805 806 /* Setup Wave Processor. */ 807 808 /* Enable WaveCache, set DMA base address. */ 809 wp_reg_write(sc, WPREG_WAVE_ROMRAM, 810 WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED); 811 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_CTRL, 812 WAVCACHE_ENABLED | WAVCACHE_WTSIZE_4MB); 813 814 for (reg = WAVCACHE_PCMBAR; reg < WAVCACHE_PCMBAR + 4; reg++) 815 wc_reg_write(sc, reg, 816 sc->physaddr >> WAVCACHE_BASEADDR_SHIFT); 817 818 /* Setup Codec/Ringbus. */ 819 maestro_initcodec(sc); 820 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 821 RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED); 822 823 wp_reg_write(sc, WPREG_BASE, 0x8500); /* Parallel I/O */ 824 ringbus_setdest(sc, RINGBUS_SRC_ADC, 825 RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN); 826 ringbus_setdest(sc, RINGBUS_SRC_DSOUND, 827 RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC); 828 829 /* Setup ASSP. Needed for Dell Inspiron 7500? */ 830 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_B, 0x00); 831 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_A, 0x03); 832 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_C, 0x00); 833 834 /* 835 * Reset hw volume to a known value so that we may handle diffs 836 * off to AC'97. 837 */ 838 839 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, MIDDLE_VOLUME); 840 /* Setup GPIO if needed (NEC systems) */ 841 if (sc->flags & MAESTRO_FLAG_SETUPGPIO) { 842 /* Matthew Braithwaite <matt@braithwaite.net> reported that 843 * NEC Versa LX doesn't need GPIO operation. */ 844 bus_space_write_2(sc->iot, sc->ioh, 845 PORT_GPIO_MASK, 0x9ff); 846 bus_space_write_2(sc->iot, sc->ioh, PORT_GPIO_DIR, 847 bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR) | 0x600); 848 bus_space_write_2(sc->iot, sc->ioh, 849 PORT_GPIO_DATA, 0x200); 850 } 851 } 852 853 /* ----------------------------- 854 * Audio interface 855 */ 856 857 int 858 maestro_round_blocksize(self, blk) 859 void *self; 860 int blk; 861 { 862 return ((blk + 0xf) & ~0xf); 863 } 864 865 void * 866 maestro_malloc(arg, dir, size, pool, flags) 867 void *arg; 868 int dir; 869 size_t size; 870 int pool, flags; 871 { 872 struct maestro_softc *sc = (struct maestro_softc *)arg; 873 874 return (salloc_alloc(sc->dmapool, size)); 875 } 876 877 void 878 maestro_free(self, ptr, pool) 879 void *self, *ptr; 880 int pool; 881 { 882 struct maestro_softc *sc = (struct maestro_softc *)self; 883 884 salloc_free(sc->dmapool, ptr); 885 } 886 887 paddr_t 888 maestro_mappage(self, mem, off, prot) 889 void *self, *mem; 890 off_t off; 891 int prot; 892 { 893 struct maestro_softc *sc = (struct maestro_softc *)self; 894 895 if (off < 0) 896 return -1; 897 return bus_dmamem_mmap(sc->dmat, &sc->dmaseg, 1, 898 off, prot, BUS_DMA_WAITOK); 899 } 900 901 int 902 maestro_get_props(self) 903 void *self; 904 { 905 /* struct maestro_softc *sc = (struct maestro_softc *)self; */ 906 907 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT); /* XXX */ 908 } 909 910 int 911 maestro_getdev(self, retp) 912 void *self; 913 struct audio_device *retp; 914 { 915 struct maestro_softc *sc = (struct maestro_softc *)self; 916 917 *retp = *sc->sc_audev; 918 return 0; 919 } 920 921 int 922 maestro_set_port(self, cp) 923 void *self; 924 mixer_ctrl_t *cp; 925 { 926 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 927 928 if (c) 929 return (c->vtbl->mixer_set_port(c, cp)); 930 else 931 return (ENXIO); 932 } 933 934 int 935 maestro_get_port(self, cp) 936 void *self; 937 mixer_ctrl_t *cp; 938 { 939 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 940 941 if (c) 942 return (c->vtbl->mixer_get_port(c, cp)); 943 else 944 return (ENXIO); 945 } 946 947 int 948 maestro_query_devinfo(self, cp) 949 void *self; 950 mixer_devinfo_t *cp; 951 { 952 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if; 953 954 if (c) 955 return (c->vtbl->query_devinfo(c, cp)); 956 else 957 return (ENXIO); 958 } 959 960 struct audio_encoding maestro_tab[] = { 961 {0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 2, 1, 0}, 962 {1, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 1, 1, 0}, 963 {2, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 1, 1, 0}, 964 {3, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16, 2, 1, 965 AUDIO_ENCODINGFLAG_EMULATED}, 966 {4, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16, 2, 1, 967 AUDIO_ENCODINGFLAG_EMULATED}, 968 {5, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16, 2, 1, 969 AUDIO_ENCODINGFLAG_EMULATED}, 970 {6, AudioEmulaw, AUDIO_ENCODING_ULAW, 8, 1, 1, 971 AUDIO_ENCODINGFLAG_EMULATED}, 972 {7, AudioEalaw, AUDIO_ENCODING_ALAW, 8, 1, 1, 973 AUDIO_ENCODINGFLAG_EMULATED} 974 }; 975 976 int 977 maestro_query_encoding(hdl, fp) 978 void *hdl; 979 struct audio_encoding *fp; 980 { 981 if (fp->index < 0 || fp->index >= lengthof(maestro_tab)) 982 return (EINVAL); 983 *fp = maestro_tab[fp->index]; 984 return (0); 985 } 986 987 void 988 maestro_get_default_params(void *addr, int mode, struct audio_params *params) 989 { 990 ac97_get_default_params(params); 991 } 992 993 #define UNUSED __attribute__((unused)) 994 995 void 996 maestro_set_speed(ch, prate) 997 struct maestro_channel *ch; 998 u_long *prate; 999 { 1000 ch->speed = *prate; 1001 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT) 1002 ch->speed /= 2; 1003 1004 /* special common case */ 1005 if (ch->speed == 48000) { 1006 ch->dv = 0x10000; 1007 } else { 1008 /* compute 16 bits fixed point value of speed/48000, 1009 * being careful not to overflow */ 1010 ch->dv = (((ch->speed % 48000) << 16U) + 24000) / 48000 1011 + ((ch->speed / 48000) << 16U); 1012 /* And this is the real rate obtained */ 1013 ch->speed = (ch->dv >> 16U) * 48000 + 1014 (((ch->dv & 0xffff)*48000)>>16U); 1015 } 1016 *prate = ch->speed; 1017 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT) 1018 *prate *= 2; 1019 } 1020 1021 u_int 1022 maestro_calc_timer_freq(ch) 1023 struct maestro_channel *ch; 1024 { 1025 u_int ss = 2; 1026 1027 if (ch->mode & MAESTRO_8BIT) 1028 ss = 1; 1029 return (ch->speed * ss) / ch->blocksize; 1030 } 1031 1032 void 1033 maestro_update_timer(sc) 1034 struct maestro_softc *sc; 1035 { 1036 u_int freq = 0; 1037 u_int n; 1038 1039 if (sc->play.mode & MAESTRO_RUNNING) 1040 freq = maestro_calc_timer_freq(&sc->play); 1041 if (sc->record.mode & MAESTRO_RUNNING) { 1042 n = maestro_calc_timer_freq(&sc->record); 1043 if (freq < n) 1044 freq = n; 1045 } 1046 if (freq) { 1047 wp_settimer(sc, freq); 1048 wp_starttimer(sc); 1049 } else 1050 wp_stoptimer(sc); 1051 } 1052 1053 1054 int 1055 maestro_set_params(hdl, setmode, usemode, play, rec) 1056 void *hdl; 1057 int setmode, usemode; 1058 struct audio_params *play, *rec; 1059 { 1060 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1061 1062 if ((setmode & AUMODE_PLAY) == 0) 1063 return (0); 1064 1065 /* Disallow parameter change on a running audio for now */ 1066 if (sc->play.mode & MAESTRO_RUNNING) 1067 return (EINVAL); 1068 1069 if (play->sample_rate < 4000) 1070 play->sample_rate = 4000; 1071 else if (play->sample_rate > 48000) 1072 play->sample_rate = 48000; 1073 1074 play->factor = 1; 1075 play->sw_code = NULL; 1076 if (play->channels > 2) 1077 play->channels = 2; 1078 1079 sc->play.mode = MAESTRO_PLAY; 1080 if (play->channels == 2) 1081 sc->play.mode |= MAESTRO_STEREO; 1082 1083 if (play->encoding == AUDIO_ENCODING_ULAW) { 1084 play->factor = 2; 1085 play->sw_code = mulaw_to_slinear16_le; 1086 } else if (play->encoding == AUDIO_ENCODING_ALAW) { 1087 play->factor = 2; 1088 play->sw_code = alaw_to_slinear16_le; 1089 } else if (play->precision == 8) { 1090 sc->play.mode |= MAESTRO_8BIT; 1091 if (play->encoding == AUDIO_ENCODING_ULINEAR_LE || 1092 play->encoding == AUDIO_ENCODING_ULINEAR_BE) 1093 sc->play.mode |= MAESTRO_UNSIGNED; 1094 } 1095 else if (play->encoding == AUDIO_ENCODING_ULINEAR_LE) 1096 play->sw_code = change_sign16_le; 1097 else if (play->encoding == AUDIO_ENCODING_SLINEAR_BE) 1098 play->sw_code = swap_bytes; 1099 else if (play->encoding == AUDIO_ENCODING_ULINEAR_BE) 1100 play->sw_code = change_sign16_swap_bytes_le; 1101 else if (play->encoding != AUDIO_ENCODING_SLINEAR_LE) 1102 return (EINVAL); 1103 1104 play->bps = AUDIO_BPS(play->precision); 1105 play->msb = 1; 1106 1107 maestro_set_speed(&sc->play, &play->sample_rate); 1108 return (0); 1109 } 1110 1111 int 1112 maestro_open(hdl, flags) 1113 void *hdl; 1114 int flags; 1115 { 1116 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1117 DPRINTF(("%s: open(%d)\n", sc->dev.dv_xname, flags)); 1118 1119 /* XXX work around VM brokeness */ 1120 #if 0 1121 if ((OFLAGS(flags) & O_ACCMODE) != O_WRONLY) 1122 return (EINVAL); 1123 #endif 1124 sc->play.mode = MAESTRO_PLAY; 1125 sc->record.mode = 0; 1126 #ifdef AUDIO_DEBUG 1127 maestrointr_called = 0; 1128 maestrodma_effective = 0; 1129 #endif 1130 return (0); 1131 } 1132 1133 void 1134 maestro_close(hdl) 1135 void *hdl; 1136 { 1137 struct maestro_softc *sc UNUSED = (struct maestro_softc *)hdl; 1138 /* nothing to do */ 1139 } 1140 1141 1142 void 1143 maestro_channel_stop(ch) 1144 struct maestro_channel *ch; 1145 { 1146 wp_apu_write(ch->sc, ch->num, APUREG_APUTYPE, 1147 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 1148 if (ch->mode & MAESTRO_STEREO) 1149 wp_apu_write(ch->sc, ch->num+1, APUREG_APUTYPE, 1150 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 1151 /* four channels for record... */ 1152 if (ch->mode & MAESTRO_PLAY) 1153 return; 1154 wp_apu_write(ch->sc, ch->num+2, APUREG_APUTYPE, 1155 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 1156 if (ch->mode & MAESTRO_STEREO) 1157 wp_apu_write(ch->sc, ch->num+3, APUREG_APUTYPE, 1158 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT); 1159 1160 } 1161 1162 int 1163 maestro_halt_input(hdl) 1164 void *hdl; 1165 { 1166 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1167 maestro_channel_stop(&sc->record); 1168 sc->record.mode &= ~MAESTRO_RUNNING; 1169 maestro_update_timer(sc); 1170 return 0; 1171 } 1172 1173 int 1174 maestro_halt_output(hdl) 1175 void *hdl; 1176 { 1177 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1178 1179 maestro_channel_stop(&sc->play); 1180 sc->play.mode &= ~MAESTRO_RUNNING; 1181 maestro_update_timer(sc); 1182 return 0; 1183 } 1184 1185 int 1186 maestro_trigger_input(hdl, start, end, blksize, intr, arg, param) 1187 void *hdl; 1188 void *start, *end; 1189 int blksize; 1190 void (*intr)(void *); 1191 void *arg; 1192 struct audio_params *param; 1193 { 1194 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1195 1196 sc->record.mode |= MAESTRO_RUNNING; 1197 sc->record.blocksize = blksize; 1198 1199 maestro_channel_start(&sc->record); 1200 1201 sc->record.threshold = sc->record.start; 1202 maestro_update_timer(sc); 1203 return 0; 1204 } 1205 1206 void 1207 maestro_channel_start(ch) 1208 struct maestro_channel *ch; 1209 { 1210 struct maestro_softc *sc = ch->sc; 1211 int n = ch->num; 1212 int aputype; 1213 wcreg_t wcreg = (sc->physaddr - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK; 1214 1215 switch(ch->mode & (MAESTRO_STEREO | MAESTRO_8BIT)) { 1216 case 0: 1217 aputype = APUTYPE_16BITLINEAR; 1218 break; 1219 case MAESTRO_STEREO: 1220 aputype = APUTYPE_16BITSTEREO; 1221 break; 1222 case MAESTRO_8BIT: 1223 aputype = APUTYPE_8BITLINEAR; 1224 break; 1225 case MAESTRO_8BIT|MAESTRO_STEREO: 1226 aputype = APUTYPE_8BITSTEREO; 1227 break; 1228 } 1229 if (ch->mode & MAESTRO_UNSIGNED) 1230 wcreg |= WAVCACHE_CHCTL_U8; 1231 if ((ch->mode & MAESTRO_STEREO) == 0) { 1232 DPRINTF(("Setting mono parameters\n")); 1233 wp_apu_write(sc, n, APUREG_WAVESPACE, ch->wpwa & 0xff00); 1234 wp_apu_write(sc, n, APUREG_CURPTR, ch->current); 1235 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end); 1236 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start); 1237 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800); 1238 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00 1239 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 1240 | (PAN_FRONT << APU_PAN_SHIFT)); 1241 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB 1242 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 1243 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8); 1244 wc_ctrl_write(sc, n, wcreg); 1245 wp_apu_write(sc, n, APUREG_APUTYPE, 1246 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 1247 } else { 1248 wcreg |= WAVCACHE_CHCTL_STEREO; 1249 DPRINTF(("Setting stereo parameters\n")); 1250 wp_apu_write(sc, n+1, APUREG_WAVESPACE, ch->wpwa & 0xff00); 1251 wp_apu_write(sc, n+1, APUREG_CURPTR, ch->current); 1252 wp_apu_write(sc, n+1, APUREG_ENDPTR, ch->end); 1253 wp_apu_write(sc, n+1, APUREG_LOOPLEN, ch->end - ch->start); 1254 wp_apu_write(sc, n+1, APUREG_AMPLITUDE, 0xe800); 1255 wp_apu_write(sc, n+1, APUREG_POSITION, 0x8f00 1256 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 1257 | (PAN_LEFT << APU_PAN_SHIFT)); 1258 wp_apu_write(sc, n+1, APUREG_FREQ_LOBYTE, APU_plus6dB 1259 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 1260 wp_apu_write(sc, n+1, APUREG_FREQ_HIWORD, ch->dv >> 8); 1261 if (ch->mode & MAESTRO_8BIT) 1262 wp_apu_write(sc, n, APUREG_WAVESPACE, 1263 ch->wpwa & 0xff00); 1264 else 1265 wp_apu_write(sc, n, APUREG_WAVESPACE, 1266 (ch->wpwa|(APU_STEREO >> 1)) & 0xff00); 1267 wp_apu_write(sc, n, APUREG_CURPTR, ch->current); 1268 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end); 1269 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start); 1270 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800); 1271 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00 1272 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT) 1273 | (PAN_RIGHT << APU_PAN_SHIFT)); 1274 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB 1275 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT)); 1276 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8); 1277 wc_ctrl_write(sc, n, wcreg); 1278 wc_ctrl_write(sc, n+1, wcreg); 1279 wp_apu_write(sc, n, APUREG_APUTYPE, 1280 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 1281 wp_apu_write(sc, n+1, APUREG_APUTYPE, 1282 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf); 1283 } 1284 } 1285 1286 int 1287 maestro_trigger_output(hdl, start, end, blksize, intr, arg, param) 1288 void *hdl; 1289 void *start, *end; 1290 int blksize; 1291 void (*intr)(void *); 1292 void *arg; 1293 struct audio_params *param; 1294 { 1295 struct maestro_softc *sc = (struct maestro_softc *)hdl; 1296 1297 u_int offset = ((caddr_t)start - sc->dmabase) >> 1; 1298 u_int size = ((char *)end - (char *)start) >> 1; 1299 sc->play.mode |= MAESTRO_RUNNING; 1300 sc->play.wpwa = APU_USE_SYSMEM | (offset >> 8); 1301 DPRINTF(("maestro_trigger_output: start=%x, end=%x, blksize=%x ", 1302 start, end, blksize)); 1303 DPRINTF(("offset = %x, size=%x\n", offset, size)); 1304 1305 sc->play.intr = intr; 1306 sc->play.intr_arg = arg; 1307 sc->play.blocksize = blksize; 1308 sc->play.end = offset+size; 1309 sc->play.start = offset; 1310 sc->play.current = sc->play.start; 1311 if ((sc->play.mode & (MAESTRO_STEREO | MAESTRO_8BIT)) == MAESTRO_STEREO) { 1312 sc->play.wpwa >>= 1; 1313 sc->play.start >>= 1; 1314 sc->play.end >>= 1; 1315 sc->play.blocksize >>= 1; 1316 } 1317 maestro_channel_start(&sc->play); 1318 1319 sc->play.threshold = sc->play.start; 1320 maestro_update_timer(sc); 1321 1322 return 0; 1323 } 1324 1325 /* ----------------------------- 1326 * Codec interface 1327 */ 1328 1329 enum ac97_host_flags 1330 maestro_codec_flags(self) 1331 void *self; 1332 { 1333 return AC97_HOST_DONT_READ; 1334 } 1335 1336 int 1337 maestro_read_codec(self, regno, datap) 1338 void *self; 1339 u_int8_t regno; 1340 u_int16_t *datap; 1341 { 1342 struct maestro_softc *sc = (struct maestro_softc *)self; 1343 int t; 1344 1345 /* We have to wait for a SAFE time to write addr/data */ 1346 for (t = 0; t < 20; t++) { 1347 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1348 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) 1349 break; 1350 DELAY(2); /* 20.8us / 13 */ 1351 } 1352 if (t == 20) 1353 printf("%s: maestro_read_codec() PROGLESS timed out.\n", 1354 sc->dev.dv_xname); 1355 /* XXX return 1 */ 1356 1357 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD, 1358 CODEC_CMD_READ | regno); 1359 DELAY(21); /* AC97 cycle = 20.8usec */ 1360 1361 /* Wait for data retrieve */ 1362 for (t = 0; t < 20; t++) { 1363 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1364 & CODEC_STAT_MASK) == CODEC_STAT_RW_DONE) 1365 break; 1366 DELAY(2); /* 20.8us / 13 */ 1367 } 1368 if (t == 20) 1369 /* Timed out, but perform dummy read. */ 1370 printf("%s: maestro_read_codec() RW_DONE timed out.\n", 1371 sc->dev.dv_xname); 1372 1373 *datap = bus_space_read_2(sc->iot, sc->ioh, PORT_CODEC_REG); 1374 return 0; 1375 } 1376 1377 int 1378 maestro_write_codec(self, regno, data) 1379 void *self; 1380 u_int8_t regno; 1381 u_int16_t data; 1382 { 1383 struct maestro_softc *sc = (struct maestro_softc *)self; 1384 int t; 1385 1386 /* We have to wait for a SAFE time to write addr/data */ 1387 for (t = 0; t < 20; t++) { 1388 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1389 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS) 1390 break; 1391 DELAY(2); /* 20.8us / 13 */ 1392 } 1393 if (t == 20) { 1394 /* Timed out. Abort writing. */ 1395 printf("%s: maestro_write_codec() PROGLESS timed out.\n", 1396 sc->dev.dv_xname); 1397 return 1; 1398 } 1399 1400 bus_space_write_2(sc->iot, sc->ioh, PORT_CODEC_REG, data); 1401 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD, 1402 CODEC_CMD_WRITE | regno); 1403 1404 return 0; 1405 } 1406 1407 int 1408 maestro_attach_codec(self, cif) 1409 void *self; 1410 struct ac97_codec_if *cif; 1411 { 1412 struct maestro_softc *sc = (struct maestro_softc *)self; 1413 1414 sc->codec_if = cif; 1415 return 0; 1416 } 1417 1418 void 1419 maestro_reset_codec(self) 1420 void *self UNUSED; 1421 { 1422 } 1423 1424 void 1425 maestro_initcodec(self) 1426 void *self; 1427 { 1428 struct maestro_softc *sc = (struct maestro_softc *)self; 1429 u_int16_t data; 1430 1431 if (bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL) 1432 & RINGBUS_CTRL_ACLINK_ENABLED) { 1433 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0); 1434 DELAY(104); /* 20.8us * (4 + 1) */ 1435 } 1436 /* XXX - 2nd codec should be looked at. */ 1437 bus_space_write_4(sc->iot, sc->ioh, 1438 PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET); 1439 DELAY(2); 1440 bus_space_write_4(sc->iot, sc->ioh, 1441 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED); 1442 DELAY(21); 1443 1444 maestro_read_codec(sc, 0, &data); 1445 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) 1446 & CODEC_STAT_MASK) != 0) { 1447 bus_space_write_4(sc->iot, sc->ioh, 1448 PORT_RINGBUS_CTRL, 0); 1449 DELAY(21); 1450 1451 /* Try cold reset. */ 1452 printf("%s: resetting codec\n", sc->dev.dv_xname); 1453 1454 data = bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR); 1455 if (pci_conf_read(sc->pc, sc->pt, 0x58) & 1) 1456 data |= 0x10; 1457 data |= 0x009 & 1458 ~bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DATA); 1459 bus_space_write_2(sc->iot, sc->ioh, 1460 PORT_GPIO_MASK, 0xff6); 1461 bus_space_write_2(sc->iot, sc->ioh, 1462 PORT_GPIO_DIR, data | 0x009); 1463 bus_space_write_2(sc->iot, sc->ioh, 1464 PORT_GPIO_DATA, 0x000); 1465 DELAY(2); 1466 bus_space_write_2(sc->iot, sc->ioh, 1467 PORT_GPIO_DATA, 0x001); 1468 DELAY(1); 1469 bus_space_write_2(sc->iot, sc->ioh, 1470 PORT_GPIO_DATA, 0x009); 1471 DELAY(500000); 1472 bus_space_write_2(sc->iot, sc->ioh, 1473 PORT_GPIO_DIR, data); 1474 DELAY(84); /* 20.8us * 4 */ 1475 bus_space_write_4(sc->iot, sc->ioh, 1476 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED); 1477 DELAY(21); 1478 } 1479 1480 /* Check the codec to see is still busy */ 1481 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) & 1482 CODEC_STAT_MASK) != 0) { 1483 printf("%s: codec failure\n", sc->dev.dv_xname); 1484 } 1485 } 1486 1487 /* ----------------------------- 1488 * Power management interface 1489 */ 1490 1491 int 1492 maestro_activate(struct device *self, int act) 1493 { 1494 struct maestro_softc *sc = (struct maestro_softc *)self; 1495 1496 switch (act) { 1497 case DVACT_SUSPEND: 1498 /* Power down device on shutdown. */ 1499 DPRINTF(("maestro: power down\n")); 1500 if (sc->record.mode & MAESTRO_RUNNING) { 1501 sc->record.current = wp_apu_read(sc, sc->record.num, APUREG_CURPTR); 1502 maestro_channel_stop(&sc->record); 1503 } 1504 if (sc->play.mode & MAESTRO_RUNNING) { 1505 sc->play.current = wp_apu_read(sc, sc->play.num, APUREG_CURPTR); 1506 maestro_channel_stop(&sc->play); 1507 } 1508 1509 wp_stoptimer(sc); 1510 1511 /* Power down everything except clock. */ 1512 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0); 1513 maestro_write_codec(sc, AC97_REG_POWER, 0xdf00); 1514 DELAY(20); 1515 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0); 1516 DELAY(1); 1517 pci_set_powerstate(sc->pc, sc->pt, PCI_PMCSR_STATE_D3); 1518 break; 1519 case DVACT_RESUME: 1520 /* Power up device on resume. */ 1521 DPRINTF(("maestro: power resume\n")); 1522 pci_set_powerstate(sc->pc, sc->pt, PCI_PMCSR_STATE_D0); 1523 DELAY(100000); 1524 maestro_init(sc); 1525 /* Restore codec settings */ 1526 if (sc->codec_if) 1527 sc->codec_if->vtbl->restore_ports(sc->codec_if); 1528 if (sc->play.mode & MAESTRO_RUNNING) 1529 maestro_channel_start(&sc->play); 1530 if (sc->record.mode & MAESTRO_RUNNING) 1531 maestro_channel_start(&sc->record); 1532 maestro_update_timer(sc); 1533 break; 1534 } 1535 return 0; 1536 } 1537 1538 void 1539 maestro_channel_advance_dma(ch) 1540 struct maestro_channel *ch; 1541 { 1542 wpreg_t pos; 1543 #ifdef AUDIO_DEBUG 1544 maestrointr_called++; 1545 #endif 1546 for (;;) { 1547 pos = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR); 1548 /* Are we still processing the current dma block ? */ 1549 if (pos >= ch->threshold && 1550 pos < ch->threshold + ch->blocksize/2) 1551 break; 1552 ch->threshold += ch->blocksize/2; 1553 if (ch->threshold >= ch->end) 1554 ch->threshold = ch->start; 1555 (*ch->intr)(ch->intr_arg); 1556 #ifdef AUDIO_DEBUG 1557 maestrodma_effective++; 1558 #endif 1559 } 1560 1561 #ifdef AUDIO_DEBUG 1562 if (maestrodebug && maestrointr_called % 64 == 0) 1563 printf("maestro: dma advanced %lu for %lu calls\n", 1564 maestrodma_effective, maestrointr_called); 1565 #endif 1566 } 1567 1568 /* Some maestro makes sometimes get desynchronized in stereo mode. */ 1569 void 1570 maestro_channel_suppress_jitter(ch) 1571 struct maestro_channel *ch; 1572 { 1573 int cp, diff; 1574 1575 /* Verify that both channels are not too far off. */ 1576 cp = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR); 1577 diff = wp_apu_read(ch->sc, ch->num+1, APUREG_CURPTR) - cp; 1578 if (diff > 4 || diff < -4) 1579 /* Otherwise, directly resynch the 2nd channel. */ 1580 bus_space_write_2(ch->sc->iot, ch->sc->ioh, 1581 PORT_DSP_DATA, cp); 1582 } 1583 1584 /* ----------------------------- 1585 * Interrupt handler interface 1586 */ 1587 int 1588 maestro_intr(arg) 1589 void *arg; 1590 { 1591 struct maestro_softc *sc = (struct maestro_softc *)arg; 1592 u_int16_t status; 1593 1594 status = bus_space_read_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT); 1595 if (status == 0) 1596 return 0; /* Not for us? */ 1597 1598 /* Acknowledge all. */ 1599 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1); 1600 bus_space_write_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT, status); 1601 1602 /* Hardware volume support */ 1603 if (status & HOSTINT_STAT_HWVOL && sc->codec_if != NULL) { 1604 int n, i, delta, v; 1605 mixer_ctrl_t hwvol; 1606 1607 n = bus_space_read_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER); 1608 /* Special case: Mute key */ 1609 if (n & 0x11) { 1610 hwvol.type = AUDIO_MIXER_ENUM; 1611 hwvol.dev = 1612 sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, 1613 AudioCoutputs, AudioNmaster, AudioNmute); 1614 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol); 1615 hwvol.un.ord = !hwvol.un.ord; 1616 } else { 1617 hwvol.type = AUDIO_MIXER_VALUE; 1618 hwvol.un.value.num_channels = 2; 1619 hwvol.dev = 1620 sc->codec_if->vtbl->get_portnum_by_name( 1621 sc->codec_if, AudioCoutputs, AudioNmaster, 1622 NULL); 1623 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol); 1624 /* XXX AC'97 yields five bits for master volume. */ 1625 delta = (n - MIDDLE_VOLUME)/STEP_VOLUME * 8; 1626 for (i = 0; i < hwvol.un.value.num_channels; i++) { 1627 v = ((int)hwvol.un.value.level[i]) + delta; 1628 if (v < 0) 1629 v = 0; 1630 else if (v > 255) 1631 v = 255; 1632 hwvol.un.value.level[i] = v; 1633 } 1634 } 1635 sc->codec_if->vtbl->mixer_set_port(sc->codec_if, &hwvol); 1636 /* Reset to compute next diffs */ 1637 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, 1638 MIDDLE_VOLUME); 1639 } 1640 1641 if (sc->play.mode & MAESTRO_RUNNING) { 1642 maestro_channel_advance_dma(&sc->play); 1643 if (sc->play.mode & MAESTRO_STEREO) 1644 maestro_channel_suppress_jitter(&sc->play); 1645 } 1646 1647 if (sc->record.mode & MAESTRO_RUNNING) 1648 maestro_channel_advance_dma(&sc->record); 1649 1650 return 1; 1651 } 1652 1653 /* ----------------------------- 1654 * Hardware interface 1655 */ 1656 1657 /* Codec/Ringbus */ 1658 1659 void 1660 ringbus_setdest(struct maestro_softc *sc, int src, int dest) 1661 { 1662 u_int32_t data; 1663 1664 data = bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL); 1665 data &= ~(0xfU << src); 1666 data |= (0xfU & dest) << src; 1667 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, data); 1668 } 1669 1670 /* Wave Processor */ 1671 1672 wpreg_t 1673 wp_reg_read(struct maestro_softc *sc, int reg) 1674 { 1675 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg); 1676 return bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA); 1677 } 1678 1679 void 1680 wp_reg_write(struct maestro_softc *sc, int reg, wpreg_t data) 1681 { 1682 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg); 1683 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data); 1684 } 1685 1686 static void 1687 apu_setindex(struct maestro_softc *sc, int reg) 1688 { 1689 int t; 1690 1691 wp_reg_write(sc, WPREG_CRAM_PTR, reg); 1692 /* Sometimes WP fails to set apu register index. */ 1693 for (t = 0; t < 1000; t++) { 1694 if (bus_space_read_2(sc->iot, sc->ioh, 1695 PORT_DSP_DATA) == reg) 1696 break; 1697 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, reg); 1698 } 1699 if (t == 1000) 1700 printf("%s: apu_setindex() timeout\n", sc->dev.dv_xname); 1701 } 1702 1703 wpreg_t 1704 wp_apu_read(struct maestro_softc *sc, int ch, int reg) 1705 { 1706 wpreg_t ret; 1707 1708 apu_setindex(sc, ((unsigned)ch << 4) + reg); 1709 ret = wp_reg_read(sc, WPREG_DATA_PORT); 1710 return ret; 1711 } 1712 1713 void 1714 wp_apu_write(struct maestro_softc *sc, int ch, int reg, wpreg_t data) 1715 { 1716 int t; 1717 1718 apu_setindex(sc, ((unsigned)ch << 4) + reg); 1719 wp_reg_write(sc, WPREG_DATA_PORT, data); 1720 for (t = 0; t < 1000; t++) { 1721 if (bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA) == data) 1722 break; 1723 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data); 1724 } 1725 if (t == 1000) 1726 printf("%s: wp_apu_write() timeout\n", sc->dev.dv_xname); 1727 } 1728 1729 void 1730 wp_settimer(struct maestro_softc *sc, u_int freq) 1731 { 1732 u_int clock = 48000 << 2; 1733 u_int prescale = 0, divide = (freq != 0) ? (clock / freq) : ~0; 1734 1735 if (divide < 4) 1736 divide = 4; 1737 else if (divide > 32 << 8) 1738 divide = 32 << 8; 1739 1740 for (; divide > 32 << 1; divide >>= 1) 1741 prescale++; 1742 divide = (divide + 1) >> 1; 1743 1744 for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1) 1745 prescale++; 1746 1747 wp_reg_write(sc, WPREG_TIMER_ENABLE, 0); 1748 wp_reg_write(sc, WPREG_TIMER_FREQ, 1749 (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1)); 1750 wp_reg_write(sc, WPREG_TIMER_ENABLE, 1); 1751 } 1752 1753 void 1754 wp_starttimer(struct maestro_softc *sc) 1755 { 1756 wp_reg_write(sc, WPREG_TIMER_START, 1); 1757 } 1758 1759 void 1760 wp_stoptimer(struct maestro_softc *sc) 1761 { 1762 wp_reg_write(sc, WPREG_TIMER_START, 0); 1763 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1); 1764 } 1765 1766 /* WaveCache */ 1767 1768 wcreg_t 1769 wc_reg_read(struct maestro_softc *sc, int reg) 1770 { 1771 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg); 1772 return bus_space_read_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA); 1773 } 1774 1775 void 1776 wc_reg_write(struct maestro_softc *sc, int reg, wcreg_t data) 1777 { 1778 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg); 1779 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA, data); 1780 } 1781 1782 u_int16_t 1783 wc_ctrl_read(struct maestro_softc *sc, int ch) 1784 { 1785 return wc_reg_read(sc, ch << 3); 1786 } 1787 1788 void 1789 wc_ctrl_write(struct maestro_softc *sc, int ch, wcreg_t data) 1790 { 1791 wc_reg_write(sc, ch << 3, data); 1792 } 1793 1794 /* ----------------------------- 1795 * Simple zone allocator. 1796 * (All memory allocated in advance) 1797 */ 1798 1799 salloc_t 1800 salloc_new(addr, size, nzones) 1801 caddr_t addr; 1802 size_t size; 1803 int nzones; 1804 { 1805 struct salloc_pool *pool; 1806 struct salloc_zone *space; 1807 int i; 1808 1809 pool = malloc(sizeof *pool + nzones * sizeof pool->zones[0], 1810 M_TEMP, M_NOWAIT); 1811 if (pool == NULL) 1812 return NULL; 1813 SLIST_INIT(&pool->free); 1814 SLIST_INIT(&pool->used); 1815 SLIST_INIT(&pool->spare); 1816 /* Espie says the following line is obvious */ 1817 pool->zones = (struct salloc_zone *)(pool + 1); 1818 for (i = 1; i < nzones; i++) 1819 SLIST_INSERT_HEAD(&pool->spare, &pool->zones[i], link); 1820 space = &pool->zones[0]; 1821 space->addr = addr; 1822 space->size = size; 1823 SLIST_INSERT_HEAD(&pool->free, space, link); 1824 return pool; 1825 } 1826 1827 void 1828 salloc_destroy(pool) 1829 salloc_t pool; 1830 { 1831 free(pool, M_TEMP); 1832 } 1833 1834 void 1835 salloc_insert(pool, head, zone, merge) 1836 salloc_t pool; 1837 struct salloc_head *head; 1838 struct salloc_zone *zone; 1839 int merge; 1840 { 1841 struct salloc_zone *prev, *next; 1842 1843 /* 1844 * Insert a zone into an ordered list of zones, possibly 1845 * merging adjacent zones. 1846 */ 1847 prev = NULL; 1848 SLIST_FOREACH(next, head, link) { 1849 if (next->addr > zone->addr) 1850 break; 1851 prev = next; 1852 } 1853 1854 if (merge && prev && prev->addr + prev->size == zone->addr) { 1855 prev->size += zone->size; 1856 SLIST_INSERT_HEAD(&pool->spare, zone, link); 1857 zone = prev; 1858 } else if (prev) 1859 SLIST_INSERT_AFTER(prev, zone, link); 1860 else 1861 SLIST_INSERT_HEAD(head, zone, link); 1862 if (merge && next && zone->addr + zone->size == next->addr) { 1863 zone->size += next->size; 1864 SLIST_REMOVE(head, next, salloc_zone, link); 1865 SLIST_INSERT_HEAD(&pool->spare, next, link); 1866 } 1867 } 1868 1869 caddr_t 1870 salloc_alloc(pool, size) 1871 salloc_t pool; 1872 size_t size; 1873 { 1874 struct salloc_zone *zone, *uzone; 1875 1876 SLIST_FOREACH(zone, &pool->free, link) 1877 if (zone->size >= size) 1878 break; 1879 if (zone == SLIST_END(&pool->free)) 1880 return NULL; 1881 if (zone->size == size) { 1882 SLIST_REMOVE(&pool->free, zone, salloc_zone, link); 1883 uzone = zone; 1884 } else { 1885 uzone = SLIST_FIRST(&pool->spare); 1886 if (uzone == NULL) 1887 return NULL; /* XXX */ 1888 SLIST_REMOVE_HEAD(&pool->spare, link); 1889 uzone->size = size; 1890 uzone->addr = zone->addr; 1891 zone->size -= size; 1892 zone->addr += size; 1893 } 1894 salloc_insert(pool, &pool->used, uzone, 0); 1895 return uzone->addr; 1896 } 1897 1898 void 1899 salloc_free(pool, addr) 1900 salloc_t pool; 1901 caddr_t addr; 1902 { 1903 struct salloc_zone *zone; 1904 1905 SLIST_FOREACH(zone, &pool->used, link) 1906 if (zone->addr == addr) 1907 break; 1908 #ifdef DIAGNOSTIC 1909 if (zone == SLIST_END(&pool->used)) 1910 panic("salloc_free: freeing unallocated memory"); 1911 #endif 1912 SLIST_REMOVE(&pool->used, zone, salloc_zone, link); 1913 salloc_insert(pool, &pool->free, zone, 1); 1914 } 1915