e45d613c0e996f98fca8bc0b7e22b17cd9dc259d
[reactos.git] / reactos / lib / drivers / sound / soundblaster / dsp_io.c
1 /*
2 ReactOS Sound System
3 Sound Blaster DSP support
4 General I/O
5
6 Author:
7 Andrew Greenwood (silverblade@reactos.org)
8
9 History:
10 2 July 2008 - Created (split from sbdsp.c)
11
12 Notes:
13 Functions documented in sbdsp.h
14 */
15
16 #include <ntddk.h>
17 #include <debug.h>
18
19 #include <time.h>
20 #include <sbdsp.h>
21
22 NTSTATUS
23 SbDspReset(
24 IN PUCHAR BasePort,
25 IN ULONG Timeout)
26 {
27 ULONG Expiry;
28 KIRQL CurrentIrqLevel = KeGetCurrentIrql();
29 BOOLEAN DataAvailable = FALSE;
30
31 /* Should be called from DriverEntry with this IRQL */
32 ASSERT(CurrentIrqLevel == PASSIVE_LEVEL);
33
34 WRITE_SB_DSP_RESET(BasePort, 0x01);
35 SleepMs(50); /* Should be enough */
36 WRITE_SB_DSP_RESET(BasePort, 0x00);
37
38 Expiry = QuerySystemTimeMs() + Timeout;
39
40 /* Wait for data to be available */
41 while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) )
42 {
43 if ( SB_DSP_DATA_AVAILABLE(BasePort) )
44 {
45 DataAvailable = TRUE;
46 break;
47 }
48 }
49
50 if ( ! DataAvailable )
51 {
52 return STATUS_TIMEOUT;
53 }
54
55 /* Data is available - wait for the "DSP ready" code */
56 while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) )
57 {
58 if ( READ_SB_DSP_DATA(BasePort) == SB_DSP_READY )
59 {
60 return STATUS_SUCCESS;
61 }
62 }
63
64 return STATUS_TIMEOUT;
65 }
66
67 NTSTATUS
68 SbDspWaitToWrite(
69 IN PUCHAR BasePort,
70 IN ULONG Timeout)
71 {
72 ULONG Expiry = QuerySystemTimeMs() + Timeout;
73
74 while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) )
75 {
76 if ( SB_DSP_CLEAR_TO_SEND(BasePort) )
77 {
78 return STATUS_SUCCESS;
79 }
80 }
81
82 return STATUS_TIMEOUT;
83 }
84
85 NTSTATUS
86 SbDspWaitToRead(
87 IN PUCHAR BasePort,
88 IN ULONG Timeout)
89 {
90 ULONG Expiry = QuerySystemTimeMs() + Timeout;
91
92 while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) )
93 {
94 if ( SB_DSP_DATA_AVAILABLE(BasePort) )
95 {
96 return STATUS_SUCCESS;
97 }
98 }
99
100 return STATUS_TIMEOUT;
101 }
102
103 NTSTATUS
104 SbDspWrite(
105 IN PUCHAR BasePort,
106 IN UCHAR DataByte,
107 IN ULONG Timeout)
108 {
109 NTSTATUS Status;
110
111 Status = SbDspWaitToWrite(BasePort, Timeout);
112
113 if ( Status != STATUS_SUCCESS )
114 {
115 return Status;
116 }
117
118 DbgPrint("SBDSP - Writing %02x\n", DataByte);
119 WRITE_SB_DSP_DATA(BasePort, DataByte);
120
121 return STATUS_SUCCESS;
122 }
123
124 NTSTATUS
125 SbDspRead(
126 IN PUCHAR BasePort,
127 OUT PUCHAR DataByte,
128 IN ULONG Timeout)
129 {
130 NTSTATUS Status;
131
132 if ( ! DataByte )
133 {
134 return STATUS_INVALID_PARAMETER_2;
135 }
136
137 Status = SbDspWaitToRead(BasePort, Timeout);
138
139 if ( Status != STATUS_SUCCESS )
140 {
141 return Status;
142 }
143
144 *DataByte = READ_SB_DSP_DATA(BasePort);
145 DbgPrint("SBDSP - Read %02x\n", *DataByte);
146
147 return STATUS_SUCCESS;
148 }