Annotation of Examples/DriverKit/SoundBlaster8/SoundBlaster8_reloc.tproj/SoundBlaster8Inline.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1994 NeXT Computer, Inc.  All rights reserved. 
                      3:  *
                      4:  * HISTORY
                      5:  * 4-Mar-94    Rakesh Dubey at NeXT
                      6:  *      Created. 
                      7:  */
                      8: 
                      9: /*
                     10:  * Base address. 
                     11:  */
                     12: static unsigned int sbBaseRegisterAddress = 0;
                     13: 
                     14: /*
                     15:  * Register addresses. The base register addressess are determined at
                     16:  * run-time. 
                     17:  */
                     18: 
                     19: static unsigned int sbResetReg = 0;
                     20: static unsigned int sbReadDataReg = 0;
                     21: static unsigned int sbWriteDataOrCommandReg = 0;
                     22: 
                     23: static unsigned int sbWriteBufferStatusReg = 0;
                     24: static unsigned int sbDataAvailableStatusReg = 0;
                     25: 
                     26: static __inline__
                     27: void
                     28: assignDSPRegAddresses(void)
                     29: {
                     30:     sbResetReg = 
                     31:         (sbBaseRegisterAddress + SB_DSP_RESET_OFFSET);
                     32:     sbReadDataReg = 
                     33:         (sbBaseRegisterAddress + SB_DSP_READ_DATA_OFFSET);
                     34:     sbWriteDataOrCommandReg = 
                     35:         (sbBaseRegisterAddress + SB_DSP_WRITE_DATA_OR_COMMAND_OFFSET);
                     36:         
                     37:     sbWriteBufferStatusReg = 
                     38:         (sbBaseRegisterAddress + SB_DSP_WRITE_BUFFER_STATUS_OFFSET);
                     39:     sbDataAvailableStatusReg = 
                     40:         (sbBaseRegisterAddress + SB_DSP_DATA_AVAILABLE_STATUS_OFFSET);
                     41: }
                     42: 
                     43: 
                     44: /*
                     45:  * Print what is being written. 
                     46:  */
                     47: static __inline__
                     48: void
                     49: outbV(unsigned int address, unsigned int data)
                     50: {
                     51: #ifdef DEBUG
                     52:     IOLog("SoundBlaster8: Writing %x at address %x\n", data, address);
                     53: #endif DEBUG
                     54:     outb(address, data);
                     55: }
                     56: 
                     57: static unsigned int sbMixerAddressReg = 0;
                     58: static unsigned int sbMixerDataReg = 0;
                     59: 
                     60: static __inline__
                     61: void
                     62: assignMixerRegAddresses(void)
                     63: {
                     64:     sbMixerAddressReg = 
                     65:         (sbBaseRegisterAddress + SB_MIXER_ADDRESS_OFFSET);
                     66:     sbMixerDataReg = 
                     67:         (sbBaseRegisterAddress + SB_MIXER_DATA_OFFSET);
                     68: }
                     69: 
                     70: /*
                     71:  * Shadow registers for volume. Add more to this list when necessary. 
                     72:  */
                     73: 
                     74: static sbStereoMixerRegister_t volMaster =     {0};
                     75: static sbStereoMixerRegister_t volFM =                 {0};
                     76: static sbStereoMixerRegister_t volLine =       {0};
                     77: static sbStereoMixerRegister_t volVoc =        {0};
                     78: 
                     79: static sbMonoMixerRegister_t volMic =          {0};
                     80: static sbMonoMixerRegister_t volCD =           {0};
                     81: 
                     82: static sbRecordingMode_t sbRecord =            {0};
                     83: static sbPlaybackMode_t sbPlayback =           {0};
                     84: 
                     85: 
                     86: #define MAX_WAIT_FOR_DATA_AVAILABLE            2000
                     87: #define SB_WAIT_DELAY                          10
                     88: #define SB_RESET_DELAY                         100
                     89: 
                     90: static  __inline__
                     91: BOOL
                     92: dspReadWait()
                     93: {
                     94:     int     i;
                     95:     unsigned int val;
                     96: 
                     97:     for (i = 0; i < MAX_WAIT_FOR_DATA_AVAILABLE; i++) {
                     98:        IODelay(SB_WAIT_DELAY);
                     99:        val = inb(sbDataAvailableStatusReg);
                    100:        if (val & 0x080)   /* MSB == 1 before reading */
                    101:            return YES;
                    102:     }
                    103: 
                    104:     /* Reset DSP, hopefully we will recover. */
                    105:     outbV(sbResetReg, 0x01);
                    106:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    107:     outbV(sbResetReg, 0x00);
                    108:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    109:     IODelay(SB_RESET_DELAY);
                    110: 
                    111: #ifdef DEBUG
                    112:     IOLog("SoundBlaster8: DSP not ready for reading!\n");
                    113: #endif DEBUG
                    114: 
                    115:     return NO;
                    116: }
                    117: 
                    118: static __inline__
                    119: BOOL 
                    120: dspWriteWait()
                    121: {
                    122:     int     i;
                    123:     unsigned int val;
                    124: 
                    125:     for (i = 0; i < MAX_WAIT_FOR_DATA_AVAILABLE; i++) {
                    126:        IODelay(SB_WAIT_DELAY);
                    127:        val = inb(sbWriteBufferStatusReg);
                    128:        if (!(val & 0x080))     /* MSB == 0 before writing */
                    129:            return YES;
                    130:     }
                    131: 
                    132:     /* Reset DSP */
                    133:     outbV(sbResetReg, 0x01);
                    134:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    135:     outbV(sbResetReg, 0x00);
                    136:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    137:     IODelay(SB_RESET_DELAY);
                    138: 
                    139: #ifdef DEBUG
                    140:     IOLog("SoundBlaster8: DSP not ready for writing!\n");
                    141: #endif DEBUG
                    142: 
                    143:     return NO;
                    144: }
                    145: 
                    146: /*
                    147:  * Send some data or command to SoundBlaster8 DSP. 
                    148:  */
                    149: static
                    150: BOOL
                    151: writeToDSP(unsigned int dataOrCommand)
                    152: {
                    153:     outbV(sbWriteDataOrCommandReg, dataOrCommand);
                    154:     IODelay(SB_DATA_WRITE_DELAY);
                    155: 
                    156: #ifdef DEBUG
                    157:     //IOLog("SoundBlaster8: Wrote DSP command %x\n", dataOrCommand);
                    158: #endif DEBUG
                    159: 
                    160:     return YES;
                    161: }
                    162: 
                    163: /*
                    164:  * Read from the SoundBlaster DSP. 
                    165:  */
                    166: static
                    167: unsigned int
                    168: readFromDSP(void)
                    169: {
                    170:     unsigned int val;
                    171:     
                    172:     val = inb(sbReadDataReg);
                    173:     IODelay(SB_DATA_READ_DELAY);
                    174: 
                    175: #ifdef DEBUG
                    176:     IOLog("SoundBlaster8: read from DSP %x\n", val);
                    177: #endif DEBUG
                    178: 
                    179:     return val;
                    180: }
                    181:     
                    182: /*
                    183:  * Function to read from the Mixer registers. 
                    184:  */
                    185: static __inline__
                    186: unsigned int
                    187: inbIXMixer(unsigned int address)
                    188: {
                    189:     unsigned int val = 0xff;
                    190:         
                    191:     outbV(sbMixerAddressReg, address);
                    192:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    193:     val = inb(sbMixerDataReg);
                    194:     
                    195: #ifdef DEBUG
                    196:     IOLog("SoundBlaster8: Mixer address %x. Read %x\n", address, val);
                    197: #endif DEBUG
                    198:     return val;
                    199: }
                    200: 
                    201: /*
                    202:  * Function to write to the Mixer registers. 
                    203:  */
                    204: static  __inline__
                    205: void
                    206: outbIXMixer(unsigned int address, unsigned int val)
                    207: {
                    208:     outbV(sbMixerAddressReg, address);
                    209:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    210:     outbV(sbMixerDataReg, val);
                    211:     IODelay(SB_DATA_WRITE_DELAY);
                    212: 
                    213: #ifdef DEBUG
                    214:     IOLog("SoundBlaster8: Mixer address %x. Wrote %x\n", address, val);
                    215: #endif DEBUG
                    216: }
                    217: 
                    218: /*
                    219:  * Initialize DSP registers. There aren't any.
                    220:  */
                    221: 
                    222: static __inline__
                    223: void
                    224: initDSPRegisters(void)
                    225: {
                    226: }
                    227: 
                    228: /*
                    229:  * Initialize the registers on the Mixer. 
                    230:  */
                    231: 
                    232: static __inline__
                    233: void
                    234: initMixerRegisters(void)
                    235: {
                    236:     if (sbCardType.mixerPresent == NO)
                    237:         return;
                    238: 
                    239: #ifdef DEBUG
                    240:     IOLog("SoundBlaster8: Initializing mixer registers.\n");
                    241: #endif DEBUG
                    242: 
                    243:     /*
                    244:      * First set the volume controlling registers to their default values. 
                    245:      */
                    246:     volMaster.reg.left = 10;
                    247:     volMaster.reg.right = 10;
                    248:     outbIXMixer(MC_MASTER_VOLUME, volMaster.data);
                    249:     
                    250:     volFM.reg.left = 0;
                    251:     volFM.reg.right = 0;
                    252:     outbIXMixer(MC_FM_VOLUME, volFM.data);
                    253:     
                    254:     volCD = 0;
                    255:     outbIXMixer(MC_CD_VOLUME, volCD);
                    256:     
                    257:     volLine.reg.left = 0;
                    258:     volLine.reg.right = 0;
                    259:     outbIXMixer(MC_LINE_VOLUME, volLine.data);
                    260:     
                    261:     volVoc.reg.left = 10;
                    262:     volVoc.reg.right = 10;
                    263:     outbIXMixer(MC_VOC_VOLUME, volVoc.data);
                    264:     
                    265:     /* Microphone can go only upto 7. */
                    266:     volMic = 6;
                    267:     outbIXMixer(MC_MICROPHONE_VOLUME, volMic);
                    268:     
                    269:     /* 
                    270:      * Now set the record and playback mode registers.
                    271:      */
                    272:     sbRecord.data = 0;
                    273:     sbRecord.reg.source = SB_RECORD_SOURCE_MIC;
                    274:     sbRecord.reg.inputFilter = SB_RECORD_ANFI_OFF;
                    275:     sbRecord.reg.highFreq = SB_RECORD_FREQ_HIGH;
                    276:     outbIXMixer(MC_RECORD_CONTROL, sbRecord.data);
                    277:     
                    278:     sbPlayback.data = 0;
                    279:     sbPlayback.reg.outputFilter = SB_PLAYBACK_DNFI_OFF;
                    280:     sbPlayback.reg.stereo = SB_PLAYBACK_STEREO;
                    281:     outbIXMixer(MC_PLAYBACK_CONTROL, sbPlayback.data);
                    282: }
                    283: 
                    284: /*
                    285:  * Input can be either microphone level or line level. We don't support other
                    286:  * inputs. 
                    287:  */
                    288: 
                    289: static __inline__
                    290: void
                    291: setInputLevel(unsigned int level)
                    292: {
                    293:     if (sbCardType.mixerPresent == NO)
                    294:         return;
                    295:         
                    296:     if (level == LINE_LEVEL_INPUT)      {
                    297:         sbRecord.reg.source = SB_RECORD_SOURCE_LINE;
                    298:     } else {
                    299:         sbRecord.reg.source = SB_RECORD_SOURCE_MIC;
                    300:     }
                    301:     
                    302:     outbIXMixer(MC_RECORD_CONTROL, sbRecord.data);
                    303: }
                    304: 
                    305: /*
                    306:  * Output level cannot be changed. 
                    307:  */
                    308: 
                    309: static __inline__
                    310: void
                    311: setOutputLevel(unsigned int channel, unsigned int level)
                    312: {
                    313: #ifdef DEBUG
                    314:     IOLog("SoundBlaster8: Audio output level is fixed.\n");
                    315: #endif DEBUG
                    316: }
                    317: 
                    318: /*
                    319:  * Initialize the hardware registers. 
                    320:  */
                    321: static __inline__
                    322: void 
                    323: initRegisters(void)
                    324: {
                    325:     initDSPRegisters();
                    326:     initMixerRegisters();
                    327: }
                    328: 
                    329: 
                    330: /*
                    331:  * These two routines are used to avoid clicks. 
                    332:  */
                    333: 
                    334: static __inline__
                    335: void 
                    336: muteOutput(void)
                    337: {
                    338:     sbStereoMixerRegister_t volMaster = {0};
                    339:     
                    340:     if (sbCardType.mixerPresent == NO)
                    341:         return;
                    342:                 
                    343:     volMaster.reg.left = 0;
                    344:     volMaster.reg.right = 0;
                    345:     
                    346:     outbIXMixer(MC_MASTER_VOLUME, volMaster.data);
                    347: }
                    348: 
                    349: /*
                    350:  * This takes it back to the old values. So it is not exactly unmute.
                    351:  */
                    352: static __inline__
                    353: void 
                    354: unMuteOutput(void)
                    355: {
                    356:     if (sbCardType.mixerPresent == NO)
                    357:         return;
                    358:         
                    359:     outbIXMixer(MC_MASTER_VOLUME, volMaster.data);
                    360: }
                    361: 
                    362: /*
                    363:  * This routine does a quick reset of the card. This is needed because
                    364:  * apparently the SoundBlaster8 cards need to be reset if you go from the
                    365:  * high speed to the low speed mode (wonderful world of hardware). 
                    366:  */
                    367: 
                    368: static __inline__
                    369: void
                    370: resetDSPQuick(void)
                    371: {
                    372:     outbV(sbResetReg, 0x01);
                    373:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    374:     outbV(sbResetReg, 0x00);
                    375:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    376:     
                    377:     /* It takes about 100us to reset */
                    378:     dspReadWait();
                    379:     if (readFromDSP() != 0xaa)    {
                    380:         IOLog("SoundBlaster8: Can not reset DSP.\n");
                    381:     }
                    382: }
                    383: 
                    384: 
                    385: #define SB_DELAY                                       100
                    386: #define MAX_RESET_WAIT                         1000
                    387: 
                    388: /*
                    389:  * Reset the SoundBlaster card. This routine also detects if the card is
                    390:  * present and the type of card. 
                    391:  */
                    392: static __inline__
                    393: void
                    394: resetDSP(void)
                    395: {
                    396:     unsigned int val;
                    397: 
                    398:     /*
                    399:      * Assume no sound card in the system. 
                    400:      */
                    401:     sbCardType.version = SB_NONE;
                    402:     sbCardType.name = "";
                    403:     sbCardType.majorVersion = 0;
                    404:     sbCardType.minorVersion = 0;
                    405:     sbCardType.mixerPresent = NO;
                    406:     
                    407:     outbV(sbResetReg, 0x01);
                    408:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    409:     outbV(sbResetReg, 0x00);
                    410:     IODelay(SB_ADDRESS_WRITE_DELAY);
                    411:     
                    412:     /* Now we can read the data. */
                    413:     dspReadWait();
                    414:     val = readFromDSP();
                    415:     if (val == 0xaa)    {
                    416: #ifdef DEBUG
                    417:         IOLog("SoundBlaster8: DSP detected.\n");
                    418: #endif DEBUG
                    419:         IOSleep(1);
                    420:     } else {
                    421: #ifdef DEBUG
                    422:         IOLog("SoundBlaster8: Read ID %x is wrong.\n", val);
                    423:         IOLog("SoundBlaster8: SoundBlaster not detected at address 0x%0x.\n", 
                    424:                 sbBaseRegisterAddress);
                    425: #endif DEBUG
                    426:         return;
                    427:     }
                    428: 
                    429:     /*
                    430:      * We have a SoundBlaster card. We will upgrade it to a pro if we detect
                    431:      * a mixer as well. 
                    432:      */
                    433:     sbCardType.version = SB_CLASSIC;
                    434: 
                    435:     /*
                    436:      * Another confirmatory test here. This is not documented in the SB SDK
                    437:      * so it might fail on some compatible cards. Maybe we should just print
                    438:      * a warning message if this test fails. 
                    439:      */
                    440:     dspWriteWait();
                    441:     writeToDSP(DC_INVERT_BYTE);
                    442:     
                    443:     dspWriteWait();
                    444:     writeToDSP(0x43);   /* Send some test pattern. */
                    445:     
                    446:     dspReadWait();
                    447:     val = readFromDSP();
                    448:     
                    449:     if (val == 0xbc)    {
                    450: #ifdef DEBUG
                    451:         IOLog("SoundBlaster8: Invert test passed.\n");
                    452: #endif DEBUG
                    453:     } else      {
                    454: #ifdef DEBUG
                    455:         IOLog("SoundBlaster8: Invert test failed!!\n");
                    456:         IOLog("SoundBlaster8: SoundBlaster not detected at address 0x%0x.\n", 
                    457:                 sbBaseRegisterAddress);
                    458: #endif DEBUG
                    459:     }
                    460: 
                    461:     /*
                    462:      * Reset the DSP here because sometimes you may get crazy values as
                    463:      * version. So just to be on the safe side.. 
                    464:      */
                    465:     resetDSPQuick();
                    466:     
                    467:     /*
                    468:      * Now we know that a SoundBlaster or compatible card exists. We need to
                    469:      * find the version number to decide the type of card.
                    470:      */
                    471:     dspWriteWait();
                    472:     writeToDSP(DC_GET_VERSION);
                    473: 
                    474:     dspReadWait();
                    475:     sbCardType.majorVersion = readFromDSP() & 0x0f;
                    476:     sbCardType.minorVersion = readFromDSP() & 0x0f;
                    477:     
                    478: #ifdef DEBUG
                    479:     //IOLog("SoundBlaster8: Major 0x%x Minor 0x%x\n", sbCardType.majorVersion, sbCardType.minorVersion);
                    480: #endif DEBUG
                    481: 
                    482:     /*
                    483:      * Upgrade the card to SB_20 or SB_16 depending upon what the version
                    484:      * number reads. 
                    485:      */
                    486:     if (sbCardType.majorVersion >= 2)
                    487:         sbCardType.version = SB_20;
                    488:  
                    489:     if (sbCardType.majorVersion >= 4)
                    490:         sbCardType.version = SB_16;
                    491: }
                    492: 
                    493: 
                    494: 
                    495: static __inline__
                    496: void
                    497: resetMixer(void)
                    498: {
                    499:     unsigned int val1, val2;
                    500:     
                    501:     /*
                    502:      * Reset the mixer by sending zero to both address and data ports.
                    503:      */
                    504:      outbIXMixer(0x0, 0x0);
                    505: 
                    506:     /*
                    507:      * Now try to write and then read from one of the mixer registers. 
                    508:      */
                    509:      outbIXMixer(MC_MASTER_VOLUME, 0x15);
                    510:      outbIXMixer(MC_MICROPHONE_VOLUME, 0x13);
                    511:      
                    512:      val1 = inbIXMixer(MC_MASTER_VOLUME);
                    513:      val2 = inbIXMixer(MC_MICROPHONE_VOLUME);
                    514: 
                    515:     if ((val1 == 0x15) && (val2 == 0x13)) {
                    516:        sbCardType.mixerPresent = YES;
                    517:     } else {
                    518:        sbCardType.mixerPresent = NO;
                    519:     }
                    520:                 
                    521:     /*
                    522:      * Try once more, so that we are really sure. 
                    523:      */
                    524:      outbIXMixer(MC_LINE_VOLUME, 0x17);
                    525:      outbIXMixer(MC_FM_VOLUME, 0x19);
                    526: 
                    527:      val1 = inbIXMixer(MC_LINE_VOLUME);
                    528:      val2 = inbIXMixer(MC_FM_VOLUME);
                    529: 
                    530:     if ((val1 == 0x17) && (val2 == 0x19)) {
                    531:        sbCardType.mixerPresent = YES;
                    532:     } else {
                    533:        sbCardType.mixerPresent = NO;
                    534:     }
                    535: 
                    536:     /*
                    537:      * We have a pro card if we found the mixer. 
                    538:      */
                    539:     if (sbCardType.mixerPresent == YES) {
                    540:         sbCardType.version = SB_PRO;
                    541:         outbIXMixer(0x0, 0x0);          /* reset the mixer to a good state */
                    542:     }
                    543:      
                    544: #ifdef DEBUG
                    545:      if (sbCardType.mixerPresent == YES)
                    546:         IOLog("SoundBlaster8: Mixer detected.\n");
                    547:      else
                    548:         IOLog("SoundBlaster8: Mixer not detected.\n");
                    549: #endif DEBUG
                    550: }
                    551: 
                    552: 
                    553: /*
                    554:  * Reset all hardware and bring us back to the default state. 
                    555:  */
                    556: static __inline__
                    557: void 
                    558: resetHardware(void)
                    559: {
                    560:     resetDSP();
                    561:     resetMixer();
                    562:     initRegisters();
                    563: }
                    564: 
                    565: /*
                    566:  * There seems to be no way to change input gain. 
                    567:  */
                    568: static  __inline__
                    569: void 
                    570: setInputGain(unsigned int channel, unsigned int gain)
                    571: {
                    572:     if (sbCardType.mixerPresent == NO)
                    573:         return;
                    574:         
                    575:     volMic = gain;
                    576:     outbIXMixer(MC_MICROPHONE_VOLUME, volMic);
                    577:     
                    578: #ifdef DEBUG
                    579:     IOLog("SoundBlaster8: set input gain %d\n", gain);
                    580: #endif DEBUG
                    581: }
                    582: 
                    583: static  __inline__
                    584: void
                    585: setOutputAttenuation(unsigned int channel, unsigned int attenuation)
                    586: {
                    587:     if (sbCardType.mixerPresent == NO)
                    588:         return;
                    589:         
                    590:     if (channel == LEFT_CHANNEL) {
                    591:         volMaster.reg.left = attenuation;
                    592:         outbIXMixer(MC_MASTER_VOLUME, volMaster.data);
                    593: 
                    594:     } else {
                    595:         volMaster.reg.right = attenuation;
                    596:         outbIXMixer(MC_MASTER_VOLUME, volMaster.data);
                    597:     }
                    598: #ifdef DEBUG
                    599:     IOLog("SoundBlaster8: set output attenuation %d\n", attenuation);
                    600: #endif DEBUG
                    601: }
                    602: 
                    603: /*
                    604:  * This will not work for SB16 running in SBPro compatibility mode. The mixer
                    605:  * registers need to be written to mute output. 
                    606:  */
                    607: 
                    608: static __inline__
                    609: void
                    610: enableAudioOutput(BOOL enable)
                    611: {
                    612:     dspWriteWait();
                    613:     if (enable) {
                    614:         writeToDSP(DC_TURN_ON_SPEAKER);
                    615:     } else {
                    616:         writeToDSP(DC_TURN_OFF_SPEAKER);
                    617:     }
                    618: }
                    619: 
                    620: static  __inline__
                    621: void    setSampleBufferCounter(unsigned int count)
                    622: {
                    623:     if (!lowSpeedDMA)  {
                    624:        dspWriteWait();
                    625:         writeToDSP(DC_SET_BLOCK_SIZE);
                    626:     } 
                    627:     
                    628:     count -= 1;
                    629:     dspWriteWait();
                    630:     writeToDSP(count & 0x0ff);
                    631:     dspWriteWait();
                    632:     writeToDSP((count >> 8) & 0x0ff);
                    633: #ifdef DEBUG
                    634:     //IOLog("SoundBlaster8: buffer counter set to %x\n", count);
                    635: #endif DEBUG
                    636: }
                    637: 
                    638: /*
                    639:  * Start DMA. Command patterns are different depending upon whether we are
                    640:  * doing low speed or high speed transfers. 
                    641:  */
                    642:      
                    643: static __inline__
                    644: void startDMA(unsigned int direction)
                    645: {       
                    646:     dspWriteWait();
                    647:     if (lowSpeedDMA)    {
                    648:         if (direction == DMA_DIRECTION_IN) 
                    649:             writeToDSP(DC_START_LS_DMA_ADC_8);
                    650:         else
                    651:             writeToDSP(DC_START_LS_DMA_DAC_8);
                    652:     } else {
                    653:         if (direction == DMA_DIRECTION_IN) 
                    654:             writeToDSP(DC_START_HS_DMA_ADC_8);
                    655:         else
                    656:             writeToDSP(DC_START_HS_DMA_DAC_8);
                    657:     }
                    658: }
                    659: 
                    660: /* No can do */
                    661: static __inline__
                    662: void enableCodecInterrupts(void)
                    663: {
                    664: }
                    665: 
                    666: static __inline__
                    667: void disableCodecInterrupts(void)
                    668: {
                    669: }
                    670: 
                    671: static __inline__
                    672: void stopDMA(void)
                    673: {
                    674:     writeToDSP(DC_HALT_DMA);
                    675: }
                    676: 
                    677: /*
                    678:  * This routine will stop input dma. 
                    679:  */
                    680: static __inline__
                    681: void stopDMAInput(void)
                    682: {
                    683:     stopDMA();
                    684: }
                    685: 
                    686: /*
                    687:  * Likewise, but for output dma. 
                    688:  */
                    689: static __inline__
                    690: void stopDMAOutput(void)
                    691: {
                    692:     stopDMA();
                    693: }
                    694: 
                    695: /*
                    696:  * Select between DSP_MONO_MODE and DSP_STEREO_MODE mode. Note that stereo
                    697:  * recording is undocumented so it could potentially break on some clone
                    698:  * cards. 
                    699:  */
                    700: static __inline__
                    701: void setCodecDataMode(unsigned int mode, unsigned int dir)
                    702: {
                    703:     if (sbCardType.mixerPresent == NO)
                    704:         return;
                    705:         
                    706:     if (dir == DMA_DIRECTION_OUT) {
                    707:        if (mode == DSP_STEREO_MODE) {
                    708:            sbPlayback.reg.stereo = SB_PLAYBACK_STEREO;
                    709:        } else {
                    710:            sbPlayback.reg.stereo = SB_PLAYBACK_MONO;
                    711:        }
                    712:        outbIXMixer(MC_PLAYBACK_CONTROL, sbPlayback.data);
                    713:     } else if (dir == DMA_DIRECTION_IN)        {
                    714:        dspWriteWait();
                    715:        if (mode == DSP_STEREO_MODE) {
                    716:            writeToDSP(DC_RECORD_IN_STEREO);
                    717:        } else {
                    718:            writeToDSP(DC_RECORD_IN_MONO);
                    719:        }
                    720:     }
                    721: }
                    722: 
                    723: 
                    724: static __inline__
                    725: void setCodecSamplingRate(unsigned int rate)
                    726: {
                    727:     unsigned int timeConstant;
                    728:     
                    729:     /* Sanity check. */
                    730:     if (rate < SB_MIN_SAMPLE_RATE)
                    731:         rate = SB_MIN_SAMPLE_RATE;
                    732:     else if (rate > SB_MAX_SAMPLE_RATE)
                    733:         rate = SB_MAX_SAMPLE_RATE;
                    734:         
                    735:     dspWriteWait();
                    736:     if (lowSpeedDMA)    {
                    737:         timeConstant = 256 - (1000*1000)/rate;
                    738:         writeToDSP(DC_SET_TIME_CONSTANT);
                    739:        dspWriteWait();
                    740:         writeToDSP(timeConstant);
                    741: #ifdef DEBUG
                    742:     IOLog("SoundBlaster8: Sample rate = %u, timeConstant = %x\n", rate, timeConstant);
                    743: #endif DEBUG
                    744:     } else {
                    745:         timeConstant = 65536 - (256*1000*1000)/rate;
                    746:         writeToDSP(DC_SET_TIME_CONSTANT);
                    747:        dspWriteWait();
                    748:         writeToDSP(timeConstant >> 8);
                    749: #ifdef DEBUG
                    750:     IOLog("SoundBlaster8: Sample rate = %u, timeConstant = %x\n", rate, timeConstant >> 8);
                    751: #endif DEBUG
                    752:     }
                    753: }
                    754: 
                    755: /*
                    756:  * We test here if the user supplied dma/irq selections are correct. Actually
                    757:  * it is more complicated than this because not all kinds of cards can use
                    758:  * all dma/irq combinations. We simply allow the superset and avoid
                    759:  * complicated version dependent verification. (Available interrupts are 3,
                    760:  * 5, 7 for SBPro and 5, 7, 10 for other kinds, clone cards may have slight
                    761:  * differences.) 
                    762:  */
                    763: 
                    764: static  __inline__
                    765: BOOL
                    766: checkSelectedDMAAndIRQ(unsigned int channel, unsigned int irq)
                    767: {
                    768:     BOOL status = YES;
                    769: 
                    770:     if ((channel != 0) && (channel != 1) && (channel != 3)) {
                    771:         IOLog("SoundBlaster8: Audio DMA channel is %d.\n", channel);
                    772:         IOLog("SoundBlaster8: Audio DMA channel must be one of 0, 1, 3.\n");
                    773:         status = NO;
                    774:     }
                    775:     if ((irq != 3) && (irq != 5) &&
                    776:         (irq != 7) && (irq != 10)) {
                    777:         IOLog("SoundBlaster8: Audio irq is %d.\n", irq);
                    778:         IOLog("SoundBlaster8: Audio IRQ must be one of 3, 5, 7, 10.\n");
                    779:         status = NO;
                    780:     }
                    781:     
                    782:     return status;
                    783: }
                    784: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.