summaryrefslogblamecommitdiffstats
path: root/private/ntos/miniport/trantor/source/findpas.c
blob: 7b60bdb8caaadc6dec73d98e5c5d76d24ec084e3 (plain) (tree)














































































































































































































































































































                                                                                                                                 
/*++

Copyright (c) 1992  Microsoft Corporation

Module Name:

    findpas.c

Abstract:

    This module contains code configuration code MediaVision's Pro audio
    spectrum.  The card is run in Sound Blaster compatibiltiy mode.

    Support is provided for volume setting and line input and
    microphone mix level setting.

    The card is located by searching.  No user configuration is supported.

Author:

    Adapted from work by Robin Speed (RobinSp) 17-Oct-1992

Environment:

    Kernel mode

Revision History:

--*/

#include CARDTXXX_H
#include "findpas.h"



//--------------========================---------------------------
//---------====< GLOBAL DATA SECTION >====-------------------------
//--------------========================---------------------------

// The board signature is the first value in the PAS 16 wakeup sequence
// BC is the factory default.  A board jumpered to recognize the BD signature
// will not respond to a BC init command.

UCHAR SignatureTable[4]={0xBC,0xBD,0xBE,0xBF};

//
// MPU stuff here until we work out what we want
//

#define MPU_ADDR       0x330

#define MPU_IRQ        2
#define MPU_EMUL_IRQ   EMUL_IRQ_2


//
// Local routines
//


BOOLEAN
VerifyProHardware(
    PFOUNDINFO pFI,
    ULONG port);

BOOLEAN
WakeUpAtAddress(
    PFOUNDINFO pFoundInfo,
    ULONG wPort);

;   /*\
;---|*|------====< DWORD GetProTableRead() >====------
;---|*|
;---|*| Detects which version of the Pro AudioSpectrum is installed
;---|*|
;---|*| Entry Conditions:
;---|*| Pointer to Profile Structure.  If the caller wants to specify
;---|*| the preferred base address for cards not yet init'd, they
;---|*| are passed in this structure.  The NumFound field indicates
;---|*| the number of location requests and the board address elements
;---|*| indicate the locations.
;---|*|
;---|*| Also passed in pointer to port (the one we found in the registry
;---|*| if any
;---|*|
;---|*| Exit Conditions:
;---|*| Returns number of cards found
;---|*| ProFile structure has been updated.
;---|*|
;   \*/


int 
FindPasHardware(
    PFOUNDINFO pFoundInfo
)
 //   PSB_CONFIG_DATA ConfigData )
{

    if (WakeUpAtAddress(pFoundInfo, pFoundInfo->ProPort)) {

        return 1;
    }

    return 0;
}

;   /*\
;---|*|------====< int VerifyProHardware() >====------
;---|*|
;---|*| Detects which version of the Pro AudioSpectrum is installed
;---|*|
;---|*| Entry Conditions:
;---|*|     pFI - found info pointer -- has PROBase mapped I/O space.
;---|*|     port - I/O port location to search -- not mapped.
;---|*|
;---|*| Exit Conditions:
;---|*|     Returns TRUE if ProAudio found.
;---|*|     Returns FALSE if not found.
;---|*|
;   \*/


BOOLEAN
VerifyProHardware(
    PFOUNDINFO pFI,
    ULONG port)
{
    UCHAR bData, bTemp;

    DebugPrint((DEBUG_LEVEL,"VerifyProHardware (proport %X,probase %X, port %X)\n",pFI->ProPort,pFI->PROBase,port));
    pFI->TranslateCode = port ^ DEFAULT_BASE;

    bData=PASX_IN (pFI, INTERRUPT_CTRL_REG);

    if (bData==0xFF) {                      // 0xFF usually means nothing there
        goto VerifyFailed;
    }
    pFI->wBoardRev= (bData >>5);            // board rev is 3 topmost bits

    switch (pFI->wBoardRev) {
#ifndef WINNT
    // winnt does not want support for old cards, this code recognizes
    // some sound blasters
    case PAS_VERSION_1:
#endif
    //case PAS_PLUS:                    // same boardrev as PAS_SIXTEEN
    case PAS_STUDIO:
    case PAS_SIXTEEN:
    case PAS_CDPC:
    case 4: // Memphis
        break;

    default:
        goto VerifyFailed;              // unknown hardware type
    }

    PASX_OUT(pFI, INTERRUPT_CTRL_REG, bData ^ 0xE0);  // try changing version bits
    bTemp=PASX_IN (pFI, INTERRUPT_CTRL_REG);           // they should be read only

    if ((bTemp & (D7+D6+D5)) != (bData & (D7+D6+D5))) {
        PASX_OUT(pFI,  INTERRUPT_CTRL_REG, bData);     // Excuse me, stranger.
        goto VerifyFailed;
    }

    if (pFI->wBoardRev==PAS_VERSION_1) {

        pFI->Caps.CapsBits.CDInterfaceType=SCSI_TYPE;

        //
        // test for Enhanced SCSI mod (U48)
        //

        PASX_OUT(pFI,  ENHANCED_SCSI_DETECT_REG, 0 );    // write to try changing version bits
        ScsiPortStallExecution(10); // wait 10 us
        bTemp=PASX_IN ( pFI, ENHANCED_SCSI_DETECT_REG );     // they should be read only

        switch (bTemp & 1) {     // bit0==1 means old SCSI PAL
        case 0:
            pFI->Caps.CapsBits.EnhancedSCSI=TRUE;
            // allow to fall thru

        case 1:
            goto ProVerified;
        }
    } else {
        // if PAS hardware installed, the reset bit can never be on

        bTemp=PASX_IN (pFI, SYSTEM_CONFIG_1);     // get PAS config register
        if (bTemp & D7) {                         // D7 is reset bit
            goto VerifyFailed;
        }

        bTemp=PASX_IN (pFI, SLAVE_MODE_READ);

        if (bTemp & SLAVE_MODE_OPL3) {
            pFI->Caps.CapsBits.OPL_3=TRUE;
        }

        if (bTemp & SLAVE_MODE_16) {
            pFI->Caps.CapsBits.DAC16=TRUE;
            pFI->Caps.CapsBits.DualDAC=TRUE;

            // if 16-bit DAC, and not a CDPC, it has a 508 chip.
            // Note: PAS 16 w/ VGA will have Mixer 508 also.

            if (pFI->wBoardRev != PAS_CDPC) {
                pFI->Caps.CapsBits.Mixer_508=TRUE;
            }
        }

        pFI->Caps.CapsBits.CDInterfaceType=(bTemp & (D1+D0));

        if (pFI->Caps.CapsBits.CDInterfaceType==SCSI_TYPE) {
            pFI->Caps.CapsBits.SCSI_IO_16=TRUE;
        }

        pFI->Caps.CapsBits.Slot16=TRUE;
        pFI->Caps.CapsBits.SoundBlaster=TRUE;

        bTemp=PASX_IN (pFI, MASTER_MODE_READ);        // get slave bits
        if ((bTemp & D0)==0) {
            pFI->Caps.CapsBits.MCA=TRUE;
        }

        if (bTemp & D2) {
            pFI->Caps.CapsBits.CDPC=TRUE;
        }

        pFI->wChipRev=PASX_IN (pFI, CHIP_REV);
    }

ProVerified:

    DebugPrint((DEBUG_LEVEL,"\n\nFound PRO hardware at %X\n", port));
    pFI->ProPort=port;                  // found at this port
    return TRUE;

////////////////////////////////

VerifyFailed:
    pFI->wBoardRev=0;               // found at this port
    pFI->Caps.dwCaps=0;             // No Board, No Caps
    return FALSE;
}

;   /*\
;---|*|------====< int WakeUpAtAddress(WORD wPort) >====------
;---|*|
;---|*| Tries to wake up sleeping relocatable hardware at a specified
;---|*| address.  Does not check for hardware already in that location
;---|*| If it does wake up a card, it does the minimum amount of
;---|*| initialization to enable the hardware.
;---|*|
;---|*| Entry Conditions:
;---|*|     wPort= Base I/O address to wake card up at.
;---|*|
;---|*| Exit Conditions:
;---|*|     Returns TRUE if ProAudio hardware found.
;---|*|     Returns FALSE if not.
;---|*|
;   \*/
BOOLEAN
WakeUpAtAddress(
    PFOUNDINFO pFoundInfo,
    ULONG wPort)
{
    int     i,j;

    DebugPrint((DEBUG_LEVEL,"WakeUpAtAddress (proport %X,probase %X, port %X)\n",pFoundInfo->ProPort,pFoundInfo->PROBase,wPort));
    for (i = 0; i < sizeof(SignatureTable) / sizeof(SignatureTable[0]); i++) {
        for (j = 0; j < 20; j++) {
            WRITE_PORT_UCHAR(pFoundInfo->PROBase + PAS_2_WAKE_UP_REG, SignatureTable[i]);
            ScsiPortStallExecution(1);
            WRITE_PORT_UCHAR(pFoundInfo->PROBase + PAS_2_WAKE_UP_REG, (UCHAR)((wPort >> 2) & 0xFF));
            ScsiPortStallExecution(1);
        }

        if (VerifyProHardware(pFoundInfo, wPort)) {

            //
            // Found one - wTranslateCode translates to the board's
            // correct port.
            //

            pFoundInfo->Caps.CapsBits.Did_HW_Init=TRUE;

            if (pFoundInfo->wBoardRev > PAS_VERSION_1 ) {
                /* Only enable FM feature if we're going to sit at
                   the right address */

                UCHAR Features = PCM_FEATURE_ENABLE | MIXER_FEATURE_ENABLE |
                                 SB_FEATURE_ENABLE | FM_FEATURE_ENABLE;

                PASX_OUT(pFoundInfo, FEATURE_ENABLE, Features);
            }

            return (TRUE);
        }
    }
    return (FALSE);     // not found
}