1 /*
2  *
3  * COPYRIGHT:            See COPYING in the top level directory
4  * PROJECT:              ReactOS kernel
5  * FILE:                 drivers/dd/sndblst/portio.c (see also sndblst.h)
6  * PURPOSE:              Sound Blaster port I/O helper
7  * PROGRAMMER:           Andrew Greenwood
8  * UPDATE HISTORY:
9  *                       Sept 28, 2003: Created
10  */
11 
12 #include <ntddk.h>
13 #include "sndblst.h"
14 
15 BOOLEAN WaitToSend(ULONG BasePort)
16 {
17     int TimeOut;
18 
19     DPRINT("WaitToSend ");
20 
21     // Check if it's OK to send
22     for (TimeOut = SB_TIMEOUT;
23          ! SB_READY_TO_SEND(BasePort) && TimeOut > 0;
24          TimeOut --);
25 
26     // If a time-out occurs, we report failure
27     if (! TimeOut)
28     {
29         DPRINT("FAILED\n");
30         return FALSE;
31     }
32 
33     DPRINT("SUCCEEDED\n");
34 
35     return TRUE;
36 }
37 
38 BOOLEAN WaitToReceive(ULONG BasePort)
39 {
40     int TimeOut;
41 
42     DPRINT("WaitToReceive ");
43 
44     // Check if it's OK to receive
45     for (TimeOut = SB_TIMEOUT;
46          ! SB_READY_TO_RECEIVE(BasePort) && TimeOut > 0;
47          TimeOut --);
48 
49     // If a time-out occurs, we report failure
50     if (! TimeOut)
51     {
52         DPRINT("FAILED\n");
53         return FALSE;
54     }
55 
56     DPRINT("SUCCEEDED\n");
57 
58     return TRUE;
59 }
60 
61 
62 USHORT InitSoundCard(ULONG BasePort)
63 {
64     ULONG TimeOut;
65     BOOLEAN Status;
66     UCHAR DSP_Major, DSP_Minor;
67 
68     DPRINT("InitSoundCard() called\n");
69 
70     DPRINT("Resetting sound card\n");
71 //    if (!WaitToSend(BasePort))
72 //        return FALSE;
73 
74     SB_WRITE_RESET(BasePort, 0x01);
75     for (TimeOut = 0; TimeOut < 30000; TimeOut ++); // Wait a while
76     SB_WRITE_RESET(BasePort, 0x00);
77 
78     // Check if it's OK to receive (some cards will ignore the above reset
79     // command and so will not issue an ACK, so time out is NOT an error)
80     DPRINT("Waiting for an ACK\n");
81     if (WaitToReceive(BasePort))
82     {
83         // Check to make sure the reset was acknowledged:
84         for (TimeOut = SB_TIMEOUT;
85              (Status = (SB_READ_DATA(BasePort) != SB_DSP_READY) && (TimeOut > 0));
86              TimeOut --);
87     }
88 
89     DPRINT("Querying DSP version\n");
90     if (! WaitToSend(BasePort))
91         return FALSE;
92 
93     SB_WRITE_DATA(BasePort, SB_GET_DSP_VERSION);
94 
95     if (! WaitToReceive(BasePort))
96         return FALSE;
97 
98     DSP_Major = SB_READ_DATA(BasePort);
99     DSP_Minor = SB_READ_DATA(BasePort);
100 
101     DPRINT("DSP v%d.%d\n", DSP_Major, DSP_Minor);
102 
103     // if audio is disabled,
104     // version tests return 0xFF everywhere
105     if (DSP_Major == 0xFF && DSP_Minor == 0xFF)
106         return FALSE;
107 
108     DPRINT("Sound card initialized!\n");
109 
110     return (DSP_Major * 256) + DSP_Minor;
111 }
112