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