home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Examples / DriverKit / ProAudioSpectrum16 / ProAudioSpectrum16_reloc.tproj / ProAudioSpectrum16Inline.h < prev    next >
Text File  |  1996-03-27  |  19KB  |  830 lines

  1. /* 
  2.  * Copyright (c) 1993-1996 NeXT Software, 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.  
  830.