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