Sync trunk.
[reactos.git] / 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 BOOLEAN DataAvailable = FALSE;
29
30 /* Should be called from DriverEntry with this IRQL */
31 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
32
33 WRITE_SB_DSP_RESET(BasePort, 0x01);
34 SleepMs(50); /* Should be enough */
35 WRITE_SB_DSP_RESET(BasePort, 0x00);
36
37 Expiry = QuerySystemTimeMs() + Timeout;
38
39 /* Wait for data to be available */
40 while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) )
41 {
42 if ( SB_DSP_DATA_AVAILABLE(BasePort) )
43 {
44 DataAvailable = TRUE;
45 break;
46 }
47 }
48
49 if ( ! DataAvailable )
50 {
51 return STATUS_TIMEOUT;
52 }
53
54 /* Data is available - wait for the "DSP ready" code */
55 while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) )
56 {
57 if ( READ_SB_DSP_DATA(BasePort) == SB_DSP_READY )
58 {
59 return STATUS_SUCCESS;
60 }
61 }
62
63 return STATUS_TIMEOUT;
64 }
65
66 NTSTATUS
67 SbDspWaitToWrite(
68 IN PUCHAR BasePort,
69 IN ULONG Timeout)
70 {
71 ULONG Expiry = QuerySystemTimeMs() + Timeout;
72
73 while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) )
74 {
75 if ( SB_DSP_CLEAR_TO_SEND(BasePort) )
76 {
77 return STATUS_SUCCESS;
78 }
79 }
80
81 return STATUS_TIMEOUT;
82 }
83
84 NTSTATUS
85 SbDspWaitToRead(
86 IN PUCHAR BasePort,
87 IN ULONG Timeout)
88 {
89 ULONG Expiry = QuerySystemTimeMs() + Timeout;
90
91 while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) )
92 {
93 if ( SB_DSP_DATA_AVAILABLE(BasePort) )
94 {
95 return STATUS_SUCCESS;
96 }
97 }
98
99 return STATUS_TIMEOUT;
100 }
101
102 NTSTATUS
103 SbDspWrite(
104 IN PUCHAR BasePort,
105 IN UCHAR DataByte,
106 IN ULONG Timeout)
107 {
108 NTSTATUS Status;
109
110 Status = SbDspWaitToWrite(BasePort, Timeout);
111
112 if ( Status != STATUS_SUCCESS )
113 {
114 return Status;
115 }
116
117 DbgPrint("SBDSP - Writing %02x\n", DataByte);
118 WRITE_SB_DSP_DATA(BasePort, DataByte);
119
120 return STATUS_SUCCESS;
121 }
122
123 NTSTATUS
124 SbDspRead(
125 IN PUCHAR BasePort,
126 OUT PUCHAR DataByte,
127 IN ULONG Timeout)
128 {
129 NTSTATUS Status;
130
131 if ( ! DataByte )
132 {
133 return STATUS_INVALID_PARAMETER_2;
134 }
135
136 Status = SbDspWaitToRead(BasePort, Timeout);
137
138 if ( Status != STATUS_SUCCESS )
139 {
140 return Status;
141 }
142
143 *DataByte = READ_SB_DSP_DATA(BasePort);
144 DbgPrint("SBDSP - Read %02x\n", *DataByte);
145
146 return STATUS_SUCCESS;
147 }