summaryrefslogtreecommitdiffstats
path: root/private/ntos/miniport/trantor/source/findpas.c
blob: 7b60bdb8caaadc6dec73d98e5c5d76d24ec084e3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*++

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
}