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