|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1993 NeXT Computer, Inc. All rights reserved. ! 3: */ ! 4: ! 5: #import "ProAudioSpectrum16Registers.h" ! 6: #import <driverkit/i386/ioPorts.h> ! 7: #import <driverkit/generalFuncs.h> ! 8: ! 9: static inline ! 10: void ! 11: setBaseAddress(unsigned int baseAddress) ! 12: { ! 13: /* ! 14: * To relocate the I/O addresses, two 8-bit values are written to the ! 15: * Master Address Pointer (0x9a01): ! 16: * (1) board ID value (valid settings are 0xbc-0xbf) ! 17: * (2) base address shifted right by two positions ! 18: */ ! 19: outb(MASTER_ADDRESS_POINTER, FIRST_BOARD_ID); ! 20: outb(MASTER_ADDRESS_POINTER, (baseAddress) >> 2); ! 21: } ! 22: ! 23: static inline ! 24: filterControl_t ! 25: getFilterControl() ! 26: { ! 27: union { ! 28: filterControl_t reg; ! 29: unsigned char data; ! 30: } filterControl; ! 31: ! 32: filterControl.data = inb(FILTER_CONTROL); ! 33: ! 34: return (filterControl.reg); ! 35: } ! 36: ! 37: static inline ! 38: void ! 39: setFilterControl(filterControl_t reg) ! 40: { ! 41: union { ! 42: filterControl_t reg; ! 43: unsigned char data; ! 44: } filterControl; ! 45: ! 46: filterControl.reg = reg; ! 47: ! 48: outb(FILTER_CONTROL, filterControl.data); ! 49: } ! 50: ! 51: static inline ! 52: void ! 53: enableAudioOutput(boolean_t enable) ! 54: { ! 55: filterControl_t filterControl = {0}; ! 56: ! 57: filterControl = getFilterControl(); ! 58: filterControl.enableAudioOutput = enable; ! 59: setFilterControl(filterControl); ! 60: } ! 61: ! 62: static inline ! 63: interruptControl_t ! 64: getInterruptControl() ! 65: { ! 66: union { ! 67: interruptControl_t reg; ! 68: unsigned char data; ! 69: } interruptControl; ! 70: ! 71: interruptControl.data = inb(INTERRUPT_CONTROL); ! 72: ! 73: return (interruptControl.reg); ! 74: } ! 75: ! 76: static inline ! 77: void ! 78: setInterruptControl(interruptControl_t reg) ! 79: { ! 80: union { ! 81: interruptControl_t reg; ! 82: unsigned char data; ! 83: } interruptControl; ! 84: ! 85: interruptControl.reg = reg; ! 86: ! 87: outb(INTERRUPT_CONTROL, interruptControl.data); ! 88: } ! 89: ! 90: static inline ! 91: interruptStatus_t ! 92: getInterruptStatus() ! 93: { ! 94: union { ! 95: interruptStatus_t reg; ! 96: unsigned char data; ! 97: } interruptStatus; ! 98: ! 99: interruptStatus.data = inb(INTERRUPT_STATUS); ! 100: ! 101: return (interruptStatus.reg); ! 102: } ! 103: ! 104: static inline ! 105: void ! 106: setInterruptStatus(interruptStatus_t reg) ! 107: { ! 108: union { ! 109: interruptStatus_t reg; ! 110: unsigned char data; ! 111: } interruptStatus; ! 112: ! 113: interruptStatus.reg = reg; ! 114: ! 115: outb(INTERRUPT_STATUS, interruptStatus.data); ! 116: } ! 117: ! 118: static inline ! 119: crossChannelControl_t ! 120: getCrossChannelControl() ! 121: { ! 122: union { ! 123: crossChannelControl_t reg; ! 124: unsigned char data; ! 125: } crossChannelControl; ! 126: ! 127: crossChannelControl.data = inb(CROSS_CHANNEL_CONTROL); ! 128: ! 129: return (crossChannelControl.reg); ! 130: } ! 131: ! 132: static inline ! 133: void ! 134: setCrossChannelControl(crossChannelControl_t reg) ! 135: { ! 136: union { ! 137: crossChannelControl_t reg; ! 138: unsigned char data; ! 139: } crossChannelControl; ! 140: ! 141: crossChannelControl.reg = reg; ! 142: ! 143: outb(CROSS_CHANNEL_CONTROL, crossChannelControl.data); ! 144: } ! 145: ! 146: static inline ! 147: sampleCounterControl_t ! 148: getSampleCounterControl() ! 149: { ! 150: union { ! 151: sampleCounterControl_t reg; ! 152: unsigned char data; ! 153: } sampleCounterControl; ! 154: ! 155: sampleCounterControl.data = inb(SAMPLE_COUNTER_CONTROL); ! 156: ! 157: return (sampleCounterControl.reg); ! 158: } ! 159: ! 160: static inline ! 161: void ! 162: setSampleCounterControl(sampleCounterControl_t reg) ! 163: { ! 164: union { ! 165: sampleCounterControl_t reg; ! 166: unsigned char data; ! 167: } sampleCounterControl; ! 168: ! 169: sampleCounterControl.reg = reg; ! 170: ! 171: outb(SAMPLE_COUNTER_CONTROL, sampleCounterControl.data); ! 172: } ! 173: ! 174: static inline ! 175: systemConfiguration1_t ! 176: getSystemConfiguration1() ! 177: { ! 178: union { ! 179: systemConfiguration1_t reg; ! 180: unsigned char data; ! 181: } systemConfiguration1; ! 182: ! 183: systemConfiguration1.data = inb(SYSTEM_CONFIGURATION_1); ! 184: ! 185: return (systemConfiguration1.reg); ! 186: } ! 187: ! 188: static inline ! 189: void ! 190: setSystemConfiguration1(systemConfiguration1_t reg) ! 191: { ! 192: union { ! 193: systemConfiguration1_t reg; ! 194: unsigned char data; ! 195: } systemConfiguration1; ! 196: ! 197: systemConfiguration1.reg = reg; ! 198: ! 199: outb(SYSTEM_CONFIGURATION_1, systemConfiguration1.data); ! 200: } ! 201: ! 202: static inline ! 203: systemConfiguration2_t ! 204: getSystemConfiguration2() ! 205: { ! 206: union { ! 207: systemConfiguration2_t reg; ! 208: unsigned char data; ! 209: } systemConfiguration2; ! 210: ! 211: systemConfiguration2.data = inb(SYSTEM_CONFIGURATION_2); ! 212: ! 213: return (systemConfiguration2.reg); ! 214: } ! 215: ! 216: static inline ! 217: void ! 218: setSystemConfiguration2(systemConfiguration2_t reg) ! 219: { ! 220: union { ! 221: systemConfiguration2_t reg; ! 222: unsigned char data; ! 223: } systemConfiguration2; ! 224: ! 225: systemConfiguration2.reg = reg; ! 226: ! 227: outb(SYSTEM_CONFIGURATION_2, systemConfiguration2.data); ! 228: } ! 229: ! 230: static inline ! 231: DMAChannelConfiguration_t ! 232: getDMAChannelConfiguration() ! 233: { ! 234: union { ! 235: DMAChannelConfiguration_t reg; ! 236: unsigned char data; ! 237: } DMAChannelConfiguration; ! 238: ! 239: DMAChannelConfiguration.data = inb(DMA_CHANNEL_CONFIGURATION); ! 240: ! 241: return (DMAChannelConfiguration.reg); ! 242: } ! 243: ! 244: static inline ! 245: void ! 246: setDMAChannelConfiguration(DMAChannelConfiguration_t reg) ! 247: { ! 248: union { ! 249: DMAChannelConfiguration_t reg; ! 250: unsigned char data; ! 251: } DMAChannelConfiguration; ! 252: ! 253: DMAChannelConfiguration.reg = reg; ! 254: ! 255: outb(DMA_CHANNEL_CONFIGURATION, DMAChannelConfiguration.data); ! 256: } ! 257: ! 258: static inline ! 259: boolean_t ! 260: setDMAChannel(int channel) ! 261: { ! 262: static DMAChannelConfiguration_t DMAChannelConfiguration = {0}; ! 263: static const unsigned char DMAMap[] = { ! 264: DMA_CHANNEL_0, ! 265: DMA_CHANNEL_1, ! 266: DMA_CHANNEL_2, ! 267: DMA_CHANNEL_3, ! 268: DMA_CHANNEL_NONE, ! 269: DMA_CHANNEL_5, ! 270: DMA_CHANNEL_6, ! 271: DMA_CHANNEL_7, ! 272: }; ! 273: ! 274: if (DMAMap[channel] == DMA_CHANNEL_NONE) ! 275: return FALSE; ! 276: ! 277: DMAChannelConfiguration.channel = DMAMap[channel]; ! 278: setDMAChannelConfiguration(DMAChannelConfiguration); ! 279: return TRUE; ! 280: ! 281: } ! 282: ! 283: static inline ! 284: IRQConfiguration_t ! 285: getIRQConfiguration() ! 286: { ! 287: union { ! 288: IRQConfiguration_t reg; ! 289: unsigned char data; ! 290: } IRQConfiguration; ! 291: ! 292: IRQConfiguration.data = inb(IRQ_CONFIGURATION); ! 293: ! 294: return (IRQConfiguration.reg); ! 295: } ! 296: ! 297: static inline ! 298: void ! 299: setIRQConfiguration(IRQConfiguration_t reg) ! 300: { ! 301: union { ! 302: IRQConfiguration_t reg; ! 303: unsigned char data; ! 304: } IRQConfiguration; ! 305: ! 306: IRQConfiguration.reg = reg; ! 307: ! 308: outb(IRQ_CONFIGURATION, IRQConfiguration.data); ! 309: } ! 310: ! 311: static inline ! 312: boolean_t ! 313: setInterrupt(int interrupt) ! 314: { ! 315: ! 316: static IRQConfiguration_t IRQConfiguration = {0}; ! 317: static const unsigned char IRQMap[] = { ! 318: INTERRUPT_NONE, ! 319: INTERRUPT_NONE, ! 320: INTERRUPT_2, ! 321: INTERRUPT_3, ! 322: INTERRUPT_4, ! 323: INTERRUPT_5, ! 324: INTERRUPT_6, ! 325: INTERRUPT_7, ! 326: INTERRUPT_NONE, ! 327: INTERRUPT_NONE, ! 328: INTERRUPT_10, ! 329: INTERRUPT_11, ! 330: INTERRUPT_12, ! 331: INTERRUPT_NONE, ! 332: INTERRUPT_14, ! 333: INTERRUPT_15 ! 334: }; ! 335: ! 336: if (IRQMap[interrupt] == INTERRUPT_NONE) ! 337: return FALSE; ! 338: ! 339: IRQConfiguration.interrupt = IRQMap[interrupt]; ! 340: setIRQConfiguration(IRQConfiguration); ! 341: return TRUE; ! 342: } ! 343: ! 344: ! 345: static inline ! 346: void ! 347: setMasterOutputAttenuation(u_int channel, masterAttenuation_t attenuation) ! 348: { ! 349: union { ! 350: channelSelection_t reg; ! 351: unsigned char data; ! 352: } channelSelection; ! 353: ! 354: // avoid a warning ! 355: channelSelection.data = 0; ! 356: ! 357: // select the master A mixer ! 358: channelSelection.reg.selectAddress = MIXER_A_MASTER; ! 359: channelSelection.reg.selectChannel = channel; ! 360: channelSelection.reg.isTransfer = TRUE; ! 361: ! 362: outb(MIXER_CONTROL, channelSelection.data); ! 363: ! 364: // set the attenuation ! 365: outb(MIXER_CONTROL, (char)attenuation); ! 366: } ! 367: ! 368: static inline ! 369: void ! 370: setOutputAttenuation(u_int address, u_int channel, u_int attenuation) ! 371: { ! 372: ! 373: union { ! 374: channelSelection_t reg; ! 375: unsigned char data; ! 376: } channelSelection; ! 377: ! 378: union { ! 379: channelAttenuation_t reg; ! 380: unsigned char data; ! 381: } channelAttenuation; ! 382: ! 383: // avoid a warning ! 384: channelSelection.data = 0; ! 385: channelAttenuation.data = 0; ! 386: ! 387: channelSelection.reg.selectAddress = address; ! 388: channelSelection.reg.selectChannel = channel; ! 389: channelSelection.reg.isTransfer = TRUE; ! 390: outb(MIXER_CONTROL, channelSelection.data); ! 391: ! 392: channelAttenuation.reg.attenuation = attenuation; ! 393: channelAttenuation.reg.routeChannel = MIXER_A_ROUTE; ! 394: channelAttenuation.reg.swapChannels = NORMAL_STEREO; ! 395: outb(MIXER_CONTROL, channelAttenuation.data); ! 396: } ! 397: ! 398: static inline ! 399: void ! 400: setMasterInputAttenuation(u_int channel, masterAttenuation_t attenuation) ! 401: { ! 402: union { ! 403: channelSelection_t reg; ! 404: unsigned char data; ! 405: } channelSelection; ! 406: ! 407: // avoid a warning ! 408: channelSelection.data = 0; ! 409: ! 410: // select the master B mixer ! 411: channelSelection.reg.selectAddress = MIXER_B_MASTER; ! 412: channelSelection.reg.selectChannel = channel; ! 413: channelSelection.reg.isTransfer = TRUE; ! 414: outb(MIXER_CONTROL, channelSelection.data); ! 415: ! 416: // set the attenuation ! 417: outb(MIXER_CONTROL, (char)attenuation); ! 418: } ! 419: ! 420: static inline ! 421: void ! 422: setInputAttenuation(u_int address, u_int channel, u_int attenuation) ! 423: { ! 424: union { ! 425: channelSelection_t reg; ! 426: unsigned char data; ! 427: } channelSelection; ! 428: ! 429: union { ! 430: channelAttenuation_t reg; ! 431: unsigned char data; ! 432: } channelAttenuation; ! 433: ! 434: // avoid a warning ! 435: channelSelection.data = 0; ! 436: channelAttenuation.data = 0; ! 437: ! 438: channelSelection.reg.selectAddress = address; ! 439: channelSelection.reg.selectChannel = channel; ! 440: channelSelection.reg.isTransfer = TRUE; ! 441: outb(MIXER_CONTROL, channelSelection.data); ! 442: ! 443: channelAttenuation.reg.attenuation = attenuation; ! 444: channelAttenuation.reg.routeChannel = MIXER_B_ROUTE; ! 445: channelAttenuation.reg.swapChannels = NORMAL_STEREO; ! 446: outb(MIXER_CONTROL, channelAttenuation.data); ! 447: ! 448: } ! 449: ! 450: /* ! 451: * In the 3.1 release, the driver set the sample rate using the technique ! 452: * described in the Developer Reference. Unfortunately, this was imprecise ! 453: * due to rounding errors. The values were calculated as follows: ! 454: * ! 455: * 1193180 / (sample rate * channel count) ! 456: * 1193180 / (44100 * 1) = 27 // 44.1 kHz mono ! 457: * 1193180 / (44100 * 2) = 13 // 44.1 kHz stereo ! 458: * ! 459: * MediaVision has provided us with the calculateRate function which calculates ! 460: * the sample rate with more precision. This technique (which also sets the ! 461: * prescale register) is undocumented in their reference manual. ! 462: * ! 463: */ ! 464: static inline ! 465: void ! 466: calculateRate(u_int sampleRate, u_int *timer, u_int *prescale) ! 467: { ! 468: long targetRatio; ! 469: long bestRatio; ! 470: long testRatio; ! 471: long bestDifference; ! 472: long lastDifference; ! 473: long testDifference; ! 474: long p; ! 475: long t; ! 476: ! 477: targetRatio = (441000L << 10) / sampleRate; ! 478: bestRatio = 300L << 10; ! 479: bestDifference = 7000L << 10; ! 480: *prescale = 0; ! 481: *timer = 0; ! 482: ! 483: for (p = 2; p < 256; p++) { ! 484: lastDifference = 300L << 10; ! 485: ! 486: for (t = p+1; t < 256; t++) { ! 487: testRatio = (t << 10) / p; ! 488: ! 489: if (testRatio == targetRatio) { ! 490: bestRatio = testRatio; ! 491: *prescale = p; ! 492: *timer = t; ! 493: return; ! 494: } ! 495: ! 496: testDifference = testRatio - targetRatio; ! 497: ! 498: if (testDifference < 0) ! 499: testDifference = -testDifference; ! 500: ! 501: if (testDifference > lastDifference) ! 502: break; ! 503: ! 504: if (testDifference < bestDifference) { ! 505: bestRatio = testRatio; ! 506: bestDifference = testDifference; ! 507: *prescale = p; ! 508: *timer = t; ! 509: } ! 510: ! 511: lastDifference = testDifference; ! 512: } ! 513: } ! 514: } ! 515: ! 516: static inline ! 517: void ! 518: setSampleRateTimer(u_int rate) ! 519: { ! 520: ! 521: u_int prescale; ! 522: u_int timer; ! 523: ! 524: union { ! 525: sampleRateTimer_t rate; ! 526: unsigned char data[2]; ! 527: } sampleRateTimer; ! 528: ! 529: ! 530: filterControl_t filterControl = {0}; ! 531: sampleCounterControl_t sampleCounterControl = {0}; ! 532: ! 533: /* ! 534: * Before setting the sample rate interval, be sure to select the ! 535: * Sample Rate Timer using Local Timer Control Register (0x138b). Also ! 536: * remember to set the Sample Rate Timer Gate of the Audio Filter Control ! 537: * Register (0xb8a) to 0 before programming the timer. ! 538: */ ! 539: filterControl = getFilterControl(); ! 540: filterControl.enableSampleRateTimer = FALSE; ! 541: setFilterControl(filterControl); ! 542: ! 543: sampleCounterControl.countFormat = BINARY_COUNT_FORMAT; ! 544: sampleCounterControl.selectMode = SAMPLE_RATE_MODE; ! 545: sampleCounterControl.latchCounter = 3; ! 546: sampleCounterControl.selectCounter = SAMPLE_RATE_COUNT; ! 547: setSampleCounterControl(sampleCounterControl); ! 548: ! 549: switch (rate) { ! 550: ! 551: case 44100: ! 552: timer = 20; ! 553: prescale = 2; ! 554: break; ! 555: ! 556: case 22050: ! 557: timer = 40; ! 558: prescale = 2; ! 559: break; ! 560: ! 561: case 8012: ! 562: timer = 110; ! 563: prescale = 2; ! 564: break; ! 565: ! 566: default: ! 567: calculateRate(rate, &timer, &prescale); ! 568: break; ! 569: } ! 570: ! 571: sampleRateTimer.rate = timer; ! 572: ! 573: outb(SAMPLE_RATE_TIMER, sampleRateTimer.data[0]); ! 574: outb(SAMPLE_RATE_TIMER, sampleRateTimer.data[1]); ! 575: ! 576: outb(PRESCALE_DIVIDER, prescale & 0x0F); ! 577: ! 578: } ! 579: ! 580: static inline ! 581: void ! 582: setSampleBufferCounter(sampleBufferCounter_t count) ! 583: { ! 584: union { ! 585: sampleBufferCounter_t count; ! 586: unsigned char data[2]; ! 587: } sampleBufferCounter; ! 588: ! 589: filterControl_t filterControl = {0}; ! 590: sampleCounterControl_t sampleCounterControl = {0}; ! 591: ! 592: filterControl = getFilterControl(); ! 593: filterControl.enableSampleBufferCounter = FALSE; ! 594: setFilterControl(filterControl); ! 595: ! 596: sampleCounterControl.countFormat = BINARY_COUNT_FORMAT; ! 597: sampleCounterControl.latchCounter = 3; ! 598: sampleCounterControl.selectMode = SAMPLE_BUFFER_MODE; ! 599: sampleCounterControl.selectCounter = SAMPLE_BUFFER_COUNT; ! 600: setSampleCounterControl(sampleCounterControl); ! 601: ! 602: sampleBufferCounter.count = count; ! 603: outb(SAMPLE_BUFFER_COUNTER, sampleBufferCounter.data[0]); ! 604: outb(SAMPLE_BUFFER_COUNTER, sampleBufferCounter.data[1]); ! 605: } ! 606: ! 607: static inline ! 608: void ! 609: setMasterModeControl(masterModeControl_t mode) ! 610: { ! 611: union { ! 612: masterModeControl_t reg; ! 613: unsigned char data; ! 614: } masterModeControl; ! 615: ! 616: union { ! 617: channelSelection_t reg; ! 618: unsigned char data; ! 619: } channelSelection; ! 620: ! 621: ! 622: // avoid a warning ! 623: channelSelection.data = 0; ! 624: ! 625: channelSelection.reg.selectAddress = MASTER_MODE_CONTROL; ! 626: channelSelection.reg.selectChannel = BOTH_CHANNELS; ! 627: channelSelection.reg.isTransfer = TRUE; ! 628: outb(MIXER_CONTROL, channelSelection.data); ! 629: ! 630: masterModeControl.reg = mode; ! 631: outb(MIXER_CONTROL, masterModeControl.data); ! 632: } ! 633: ! 634: static inline ! 635: void ! 636: setLoudnessFilter(boolean_t flag) ! 637: { ! 638: masterModeControl_t masterModeControl = {0}; ! 639: ! 640: masterModeControl.loudnessFilter = flag; ! 641: setMasterModeControl(masterModeControl); ! 642: } ! 643: ! 644: ! 645: static inline ! 646: void ! 647: setBassControl(unsigned char boost) ! 648: { ! 649: union { ! 650: channelSelection_t reg; ! 651: unsigned char data; ! 652: } channelSelection; ! 653: ! 654: // avoid a warning ! 655: channelSelection.data = 0; ! 656: ! 657: channelSelection.reg.selectAddress = BASS_CONTROL; ! 658: channelSelection.reg.selectChannel = BOTH_CHANNELS; ! 659: channelSelection.reg.isTransfer = TRUE; ! 660: outb(MIXER_CONTROL, channelSelection.data); ! 661: ! 662: outb(MIXER_CONTROL, boost); ! 663: } ! 664: ! 665: static inline ! 666: void ! 667: setTrebleControl(unsigned char boost) ! 668: { ! 669: union { ! 670: channelSelection_t reg; ! 671: unsigned char data; ! 672: } channelSelection; ! 673: ! 674: // avoid a warning ! 675: channelSelection.data = 0; ! 676: ! 677: channelSelection.reg.selectAddress = TREBLE_CONTROL; ! 678: channelSelection.reg.selectChannel = BOTH_CHANNELS; ! 679: channelSelection.reg.isTransfer = TRUE; ! 680: outb(MIXER_CONTROL, channelSelection.data); ! 681: ! 682: outb(MIXER_CONTROL, boost); ! 683: } ! 684: ! 685: static inline ! 686: void ! 687: resetMixer() ! 688: { ! 689: setMasterOutputAttenuation(BOTH_CHANNELS, ! 690: DEFAULT_MASTER_OUTPUT_ATTENUATION); ! 691: ! 692: setOutputAttenuation(PCM, ! 693: BOTH_CHANNELS, ! 694: DEFAULT_OUTPUT_ATTENUATION); ! 695: ! 696: /* ! 697: * mute all other output channels ! 698: */ ! 699: setOutputAttenuation(INPUT_MIXER_LOOPBACK, ! 700: BOTH_CHANNELS, ! 701: MUTE); ! 702: ! 703: setMasterInputAttenuation(BOTH_CHANNELS, ! 704: DEFAULT_MASTER_INPUT_ATTENUATION); ! 705: ! 706: setInputAttenuation(MICROPHONE, ! 707: BOTH_CHANNELS, ! 708: DEFAULT_MICROPHONE_ATTENUATION); ! 709: ! 710: setInputAttenuation(EXTERNAL_LINE_IN, ! 711: BOTH_CHANNELS, ! 712: DEFAULT_INPUT_ATTENUATION); ! 713: ! 714: /* ! 715: * mute all other input channels ! 716: */ ! 717: setInputAttenuation(FM_SYNTHESIS, ! 718: BOTH_CHANNELS, ! 719: MUTE); ! 720: ! 721: setInputAttenuation(INTERNAL_LINE_IN, ! 722: BOTH_CHANNELS, ! 723: MUTE); ! 724: ! 725: setInputAttenuation(SPEAKER, ! 726: BOTH_CHANNELS, ! 727: MUTE); ! 728: ! 729: setInputAttenuation(SOUNDBLASTER, ! 730: BOTH_CHANNELS, ! 731: MUTE); ! 732: ! 733: /* ! 734: * set treble and bass boost to 0db ! 735: */ ! 736: setBassControl(DEFAULT_BASS_BOOST); ! 737: setTrebleControl(DEFAULT_TREBLE_BOOST); ! 738: } ! 739: ! 740: ! 741: ! 742: /* ! 743: * resetHardware uses "magic" values recommended by MediaVision. These ! 744: * settings are not always documented in the reference guide. In addition, ! 745: * some of the values are specific to a particular version of the hardware. ! 746: */ ! 747: static inline ! 748: boolean_t ! 749: resetHardware() ! 750: { ! 751: systemConfiguration1_t systemConfiguration1; ! 752: ! 753: union { ! 754: interruptControl_t reg; ! 755: unsigned char data; ! 756: } interruptControl; ! 757: ! 758: unsigned char version; ! 759: ! 760: /* ! 761: * The presence of the hardware is verified. The version bits in the ! 762: * interrupt control register are read only. ! 763: */ ! 764: interruptControl.data = inb(INTERRUPT_CONTROL); ! 765: ! 766: if (interruptControl.data == 0xff) ! 767: return FALSE; ! 768: ! 769: version = interruptControl.reg.version; ! 770: interruptControl.reg.version = 0; ! 771: ! 772: outb(INTERRUPT_CONTROL, interruptControl.data); ! 773: interruptControl.data = inb(INTERRUPT_CONTROL); ! 774: ! 775: if (interruptControl.reg.version != version) ! 776: return FALSE; ! 777: ! 778: /* ! 779: * Turn off MPU and SoundBlaster emulation ! 780: * ! 781: outb(COMPATIBILITY_ENABLE, 0); ! 782: ! 783: /* ! 784: * Turn off MPU and SoundBlaster interrupts ! 785: */ ! 786: outb(EMULATION_CONFIGURATION, 0); ! 787: ! 788: /* ! 789: * Sets wait state to 140ns period ! 790: */ ! 791: outb(WAIT_STATE, WAIT_STATE_RESET); ! 792: ! 793: /* ! 794: * D0 - resets FM ! 795: * D1 - resets Codec ! 796: * D2 - resets SoundBlaster ! 797: * D4 - resets MVA508 Mixer ! 798: */ ! 799: outb(AUDIO_MIXER, 0); ! 800: outb(AUDIO_MIXER, AUDIO_MIXER_RESET); ! 801: ! 802: /* ! 803: * This is required when using the prescale register for more precise ! 804: * sample rate timing. ! 805: */ ! 806: systemConfiguration1 = getSystemConfiguration1(); ! 807: systemConfiguration1.selectCompatibleClock = TRUE; ! 808: setSystemConfiguration1(systemConfiguration1); ! 809: ! 810: outb(SYSTEM_CONFIGURATION_2, SYSTEM_CONFIGURATION_2_RESET); ! 811: /* ! 812: * D3 (invert bclk output) ! 813: * D4 (use codec sync output) ! 814: */ ! 815: outb(SYSTEM_CONFIGURATION_3, SYSTEM_CONFIGURATION_3_RESET); ! 816: ! 817: outb(SYSTEM_CONFIGURATION_4, SYSTEM_CONFIGURATION_4_RESET); ! 818: ! 819: /* ! 820: * When a 16 bit Codec is attached, the Prescale counter is used to ! 821: * set the ratio between the incoming Codec bit clock and the outgoing ! 822: * master clock. ! 823: */ ! 824: outb(PRESCALE_DIVIDER, PRESCALE_DIVIDER_RESET); ! 825: ! 826: resetMixer(); ! 827: return TRUE; ! 828: } ! 829:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.