ReactOS 0.4.16-dev-2293-g4d8327b
hdac_controller.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _HDA_ASYNC_CONTEXT
 

Typedefs

typedef struct _HDA_ASYNC_CONTEXT HDA_ASYNC_CONTEXT
 
typedef struct _HDA_ASYNC_CONTEXTPHDA_ASYNC_CONTEXT
 

Functions

 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME (HDA_ASYNC_CONTEXT, HDAAsyncWorkItem_GetContext)
 
NTSTATUS GetHDACapabilities (PFDO_CONTEXT fdoCtx)
 
NTSTATUS StartHDAController (PFDO_CONTEXT fdoCtx)
 
NTSTATUS StopHDAController (PFDO_CONTEXT fdoCtx)
 
NTSTATUS SendHDACmds (PFDO_CONTEXT fdoCtx, ULONG count, PHDAUDIO_CODEC_TRANSFER CodecTransfer)
 
NTSTATUS RunSingleHDACmd (PFDO_CONTEXT fdoCtx, ULONG val, ULONG *res)
 
BOOLEAN NTAPI hda_interrupt (WDFINTERRUPT Interrupt, ULONG MessageID)
 
void NTAPI hda_dpc (WDFINTERRUPT Interrupt, WDFOBJECT AssociatedObject)
 

Typedef Documentation

◆ HDA_ASYNC_CONTEXT

◆ PHDA_ASYNC_CONTEXT

Function Documentation

◆ GetHDACapabilities()

NTSTATUS GetHDACapabilities ( PFDO_CONTEXT  fdoCtx)

Definition at line 72 of file hdac_controller.cpp.

72 {
73 UINT16 gcap = hda_read16(fdoCtx, GCAP);
74 SklHdAudBusPrint(DEBUG_LEVEL_INFO, DBG_INIT,
75 "chipset global capabilities = 0x%x\n", gcap);
76
77 fdoCtx->is64BitOK = !!(gcap & 0x1);
78 SklHdAudBusPrint(DEBUG_LEVEL_INFO, DBG_INIT,
79 "64 bit OK? %d\n", fdoCtx->is64BitOK);
80
81 fdoCtx->hwVersion = (hda_read8(fdoCtx, VMAJ) << 8) | hda_read8(fdoCtx, VMIN);
82
83 fdoCtx->captureStreams = (gcap >> 8) & 0x0f;
84 fdoCtx->playbackStreams = (gcap >> 12) & 0x0f;
85
86 SklHdAudBusPrint(DEBUG_LEVEL_INFO, DBG_INIT,
87 "streams (cap %d, playback %d)\n", fdoCtx->captureStreams, fdoCtx->playbackStreams);
88
89 fdoCtx->captureIndexOff = 0;
90 fdoCtx->playbackIndexOff = fdoCtx->captureStreams;
91 fdoCtx->numStreams = fdoCtx->captureStreams + fdoCtx->playbackStreams;
92
93 UINT8 corbSize = hda_read8(fdoCtx, CORBSIZE);
94 if (!(corbSize & 0x40)) {
95 return STATUS_DEVICE_FEATURE_NOT_SUPPORTED; //CORB must support 256
96 }
97
98 UINT8 rirbSize = hda_read8(fdoCtx, RIRBSIZE);
99 if (!(rirbSize & 0x40)) {
100 return STATUS_DEVICE_FEATURE_NOT_SUPPORTED; //RIRB must support 256
101 }
102
103 return STATUS_SUCCESS;
104}
unsigned short UINT16
Definition: actypes.h:129
unsigned char UINT8
Definition: actypes.h:128
#define SklHdAudBusPrint(dbglevel, fmt,...)
Definition: driver.h:111
#define STATUS_DEVICE_FEATURE_NOT_SUPPORTED
Definition: ntstatus.h:1137
#define hda_read8(ctx, reg)
Definition: regfuncs.h:53
#define hda_read16(ctx, reg)
Definition: regfuncs.h:56
#define STATUS_SUCCESS
Definition: shellext.h:65
UINT32 playbackStreams
Definition: fdo.h:146
UINT32 captureIndexOff
Definition: fdo.h:143
BOOLEAN is64BitOK
Definition: fdo.h:140
UINT32 numStreams
Definition: fdo.h:147
UINT32 playbackIndexOff
Definition: fdo.h:144
UINT16 hwVersion
Definition: fdo.h:141
UINT32 captureStreams
Definition: fdo.h:145

Referenced by Fdo_EvtDevicePrepareHardware().

◆ hda_dpc()

void NTAPI hda_dpc ( WDFINTERRUPT  Interrupt,
WDFOBJECT  AssociatedObject 
)

Definition at line 415 of file hdac_controller.cpp.

418 {
420
422 PFDO_CONTEXT fdoCtx = Fdo_GetContext(Device);
423
424 for (UINT32 i = 0; i < fdoCtx->numStreams; i++) {
425 PHDAC_STREAM stream = &fdoCtx->streams[i];
426 if (stream->irqReceived) {
427 stream->irqReceived = FALSE;
428
429 for (int j = 0; j < MAX_NOTIF_EVENTS; j++) {
430 if (stream->registeredCallbacks[j].InUse) {
431 LARGE_INTEGER unknownVal = { 0 };
432 KeQuerySystemTime(&unknownVal);
433 stream->registeredCallbacks[j].NotificationCallback(stream->registeredCallbacks[j].CallbackContext, unknownVal);
434 }
435 }
436
437 for (int j = 0; j < MAX_NOTIF_EVENTS; j++) {
438 if (stream->registeredEvents[j]) {
439 KeSetEvent(stream->registeredEvents[j], IO_NO_INCREMENT, FALSE);
440 }
441 }
442 }
443 }
444
445 if (fdoCtx->processRirb) {
446 fdoCtx->processRirb = FALSE;
447 HDAFlushRIRB(fdoCtx);
448 }
449}
#define FALSE
Definition: types.h:117
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define MAX_NOTIF_EVENTS
Definition: fdo.h:17
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static void HDAFlushRIRB(PFDO_CONTEXT fdoCtx)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BOOL processRirb
Definition: fdo.h:165
PHDAC_STREAM streams
Definition: fdo.h:149
Definition: parse.h:23
uint32_t UINT32
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
FORCEINLINE WDFDEVICE WdfInterruptGetDevice(_In_ WDFINTERRUPT Interrupt)
Definition: wdfinterrupt.h:721
_In_ WDFOBJECT AssociatedObject
Definition: wdfinterrupt.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by Fdo_Initialize().

◆ hda_interrupt()

BOOLEAN NTAPI hda_interrupt ( WDFINTERRUPT  Interrupt,
ULONG  MessageID 
)

Definition at line 374 of file hdac_controller.cpp.

376 {
378
380 PFDO_CONTEXT fdoCtx = Fdo_GetContext(Device);
381
382 BOOLEAN handled = FALSE;
383
384 if (fdoCtx->dspInterruptCallback) {
385 handled = (BOOLEAN)fdoCtx->dspInterruptCallback(fdoCtx->dspInterruptContext);
386 }
387
388 if (!fdoCtx->ControllerEnabled)
389 return handled;
390
391 UINT32 status = hda_read32(fdoCtx, INTSTS);
392 if (status == 0 || status == 0xffffffff)
393 return handled;
394
395 handled = TRUE;
396
397 if (hda_stream_interrupt(fdoCtx, status)) {
399 }
400
401 status = hda_read8(fdoCtx, RIRBSTS);
402 if (status & RIRB_INT_MASK) {
403 hda_write8(fdoCtx, RIRBSTS, RIRB_INT_MASK);
405 fdoCtx->processRirb = TRUE;
407 }
408 }
409
410 return handled;
411}
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
#define RIRB_INT_MASK
#define RIRB_INT_RESPONSE
int hda_stream_interrupt(PFDO_CONTEXT fdoCtx, unsigned int status)
#define BOOLEAN
Definition: pedump.c:73
#define hda_read32(ctx, reg)
Definition: regfuncs.h:59
#define hda_write8(ctx, reg, data)
Definition: regfuncs.h:54
PVOID dspInterruptContext
Definition: fdo.h:153
BOOLEAN ControllerEnabled
Definition: fdo.h:138
PADSP_INTERRUPT_CALLBACK dspInterruptCallback
Definition: fdo.h:152
Definition: ps.c:97
_In_ ULONG MessageID
Definition: wdfinterrupt.h:92
FORCEINLINE BOOLEAN WdfInterruptQueueDpcForIsr(_In_ WDFINTERRUPT Interrupt)
Definition: wdfinterrupt.h:414

Referenced by Fdo_Initialize().

◆ RunSingleHDACmd()

NTSTATUS RunSingleHDACmd ( PFDO_CONTEXT  fdoCtx,
ULONG  val,
ULONG res 
)

Definition at line 249 of file hdac_controller.cpp.

249 {
250 HDAUDIO_CODEC_TRANSFER transfer = { 0 };
251 transfer.Output.Command = val;
252
253 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
254 "%s: Called. Command: 0x%x\n", __func__, val);
255
256 NTSTATUS status = SendHDACmds(fdoCtx, 1, &transfer);
257 if (!NT_SUCCESS(status)) {
258 return status;
259 }
260
262 status = HDA_WaitForTransfer(fdoCtx, addr, 1, &transfer);
263 if (transfer.Input.IsValid && res) {
264 *res = transfer.Input.Response;
265 }
266 return status;
267}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS HDA_WaitForTransfer(PFDO_CONTEXT fdoCtx, UINT16 codecAddr, _In_ ULONG Count, _Inout_updates_(Count) PHDAUDIO_CODEC_TRANSFER CodecTransfer)
Definition: hdaudio.cpp:3
GLuint res
Definition: glext.h:9613
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLfloat * val
Definition: glext.h:7180
NTSTATUS SendHDACmds(PFDO_CONTEXT fdoCtx, ULONG count, PHDAUDIO_CODEC_TRANSFER CodecTransfer)
static UINT16 HDACommandAddr(UINT32 cmd)
HDAUDIO_CODEC_RESPONSE Input
Definition: hdaudio.h:58
HDAUDIO_CODEC_COMMAND Output
Definition: hdaudio.h:57

Referenced by Fdo_EnumerateCodec(), and Fdo_EvtDeviceD0EntryPostInterrupts().

◆ SendHDACmds()

NTSTATUS SendHDACmds ( PFDO_CONTEXT  fdoCtx,
ULONG  count,
PHDAUDIO_CODEC_TRANSFER  CodecTransfer 
)

Definition at line 207 of file hdac_controller.cpp.

207 {
208 WdfInterruptAcquireLock(fdoCtx->Interrupt);
209 for (ULONG i = 0; i < count; i++) {
210 PHDAUDIO_CODEC_TRANSFER transfer = &CodecTransfer[i];
211 RtlZeroMemory(&transfer->Input, sizeof(transfer->Input));
212
214
215 //Add command to corb
216 UINT16 wp = hda_read16(fdoCtx, CORBWP);
217 if (wp == 0xffff) {
218 //Something wrong, controller likely went to sleep
219 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
220 "%s: device not found\n", __func__);
221 WdfInterruptReleaseLock(fdoCtx->Interrupt);
223 }
224
225 wp++;
227
228 UINT16 rp = hda_read16(fdoCtx, CORBRP);
229 if (wp == rp) {
230 //Oops it's full
231 SklHdAudBusPrint(DEBUG_LEVEL_ERROR, DBG_IOCTL,
232 "%s: device busy\n", __func__);
233 WdfInterruptReleaseLock(fdoCtx->Interrupt);
234 return STATUS_RETRY;
235 }
236
237 LONG oldVal = InterlockedIncrement(&fdoCtx->rirb.cmds[addr]);
238 fdoCtx->rirb.xfer[addr].xfer[oldVal - 1] = transfer;
239
240 fdoCtx->corb.buf[wp] = transfer->Output.Command;
241
242 hda_write16(fdoCtx, CORBWP, wp);
243 }
244
245 WdfInterruptReleaseLock(fdoCtx->Interrupt);
246 return STATUS_SUCCESS;
247}
#define InterlockedIncrement
Definition: armddk.h:53
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HDA_MAX_CORB_ENTRIES
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:522
long LONG
Definition: pedump.c:60
#define hda_write16(ctx, reg, data)
Definition: regfuncs.h:57
HDAC_RB corb
Definition: fdo.h:163
HDAC_RB rirb
Definition: fdo.h:164
WDFINTERRUPT Interrupt
Definition: fdo.h:124
PHDAUDIO_CODEC_TRANSFER xfer[HDA_MAX_CORB_ENTRIES]
Definition: fdo.h:85
HDAC_CODEC_XFER xfer[HDA_MAX_CODECS]
Definition: fdo.h:97
UINT32 * buf
Definition: fdo.h:90
LONG cmds[HDA_MAX_CODECS]
Definition: fdo.h:95
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_RETRY
Definition: udferr_usr.h:182

Referenced by HDA_TransferCodecVerbs(), and RunSingleHDACmd().

◆ StartHDAController()

NTSTATUS StartHDAController ( PFDO_CONTEXT  fdoCtx)

Definition at line 162 of file hdac_controller.cpp.

162 {
164 status = ResetHDAController(fdoCtx, TRUE);
165 if (!NT_SUCCESS(status)) {
166 goto exit;
167 }
168
169 //Clear STATESTS
170 hda_write16(fdoCtx, STATESTS, STATESTS_INT_MASK);
171
172 HDAInitCorb(fdoCtx);
173 HDAInitRirb(fdoCtx);
174
175 HDAStartCorb(fdoCtx);
176 HDAStartRirb(fdoCtx);
177
178 //Enabling Controller Interrupt
179 hda_write32(fdoCtx, GCTL, hda_read32(fdoCtx, GCTL) | HDA_GCTL_UNSOL);
180 hda_write32(fdoCtx, INTCTL, hda_read32(fdoCtx, INTCTL) | HDA_INT_CTRL_EN | HDA_INT_GLOBAL_EN);
181
182 {
183 //Program position buffer
184 PHYSICAL_ADDRESS posbufAddr = MmGetPhysicalAddress(fdoCtx->posbuf);
185 hda_write32(fdoCtx, DPLBASE, posbufAddr.LowPart);
186 hda_write32(fdoCtx, DPUBASE, posbufAddr.HighPart);
187 }
188
189 udelay(1000);
190
191 fdoCtx->ControllerEnabled = TRUE;
192
193exit:
194 return status;
195}
static void udelay(LONG usec)
Definition: driver.h:80
#define HDA_GCTL_UNSOL
Definition: hda_registers.h:14
#define HDA_INT_GLOBAL_EN
#define HDA_INT_CTRL_EN
#define STATESTS_INT_MASK
void HDAInitRirb(PFDO_CONTEXT fdoCtx)
void HDAStartRirb(PFDO_CONTEXT fdoCtx)
void HDAStartCorb(PFDO_CONTEXT fdoCtx)
NTSTATUS ResetHDAController(PFDO_CONTEXT fdoCtx, BOOLEAN wakeup)
void HDAInitCorb(PFDO_CONTEXT fdoCtx)
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
#define hda_write32(ctx, reg, data)
Definition: regfuncs.h:60
#define exit(n)
Definition: config.h:202
PVOID posbuf
Definition: fdo.h:168
ULONG LowPart
Definition: typedefs.h:106

Referenced by Fdo_EvtDeviceD0Entry().

◆ StopHDAController()

NTSTATUS StopHDAController ( PFDO_CONTEXT  fdoCtx)

Definition at line 197 of file hdac_controller.cpp.

197 {
199 fdoCtx->ControllerEnabled = FALSE;
200 return status;
201}

Referenced by Fdo_EvtDeviceD0Exit().

◆ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME()

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME ( HDA_ASYNC_CONTEXT  ,
HDAAsyncWorkItem_GetContext   
)