mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 14:34:57 +08:00
[DRIVERS] Remove old HD audio bus driver
since it's obsolete now and is not used any more.
This commit is contained in:
committed by
Mark Jansen
parent
dcd45a59d1
commit
b308bcc311
@@ -1,17 +0,0 @@
|
||||
|
||||
|
||||
remove_definitions(-D_WIN32_WINNT=0x502)
|
||||
add_definitions(-D_WIN32_WINNT=0x600)
|
||||
|
||||
list(APPEND SOURCE
|
||||
hdaudbus.cpp
|
||||
fdo.cpp
|
||||
pdo.cpp
|
||||
businterface.cpp)
|
||||
|
||||
add_library(hdaudbus MODULE ${SOURCE})
|
||||
set_module_type(hdaudbus kernelmodedriver)
|
||||
target_link_libraries(hdaudbus libcntpr ${PSEH_LIB})
|
||||
add_importlibs(hdaudbus ntoskrnl hal)
|
||||
add_cd_file(TARGET hdaudbus DESTINATION reactos/system32/drivers FOR all)
|
||||
add_driver_inf(hdaudbus hdaudbus.inf)
|
||||
@@ -1,372 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel Streaming
|
||||
* FILE: drivers/wdm/audio/hdaudbus/hdaudbus.cpp
|
||||
* PURPOSE: HDA Driver Entry
|
||||
* PROGRAMMER: Johannes Anderwald
|
||||
*/
|
||||
#include "hdaudbus.h"
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_InterfaceReference(
|
||||
PVOID BusContext)
|
||||
{
|
||||
DPRINT1("HDA_InterfaceReference\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_InterfaceDereference(
|
||||
PVOID BusContext)
|
||||
{
|
||||
DPRINT1("HDA_InterfaceDereference\n");
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_TransferCodecVerbs(
|
||||
IN PVOID _context,
|
||||
IN ULONG Count,
|
||||
IN OUT PHDAUDIO_CODEC_TRANSFER CodecTransfer,
|
||||
IN PHDAUDIO_TRANSFER_COMPLETE_CALLBACK Callback,
|
||||
IN PVOID Context)
|
||||
{
|
||||
ULONG Verbs[MAX_CODEC_RESPONSES], Responses[MAX_CODEC_RESPONSES];
|
||||
ULONG Index;
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DPRINT1("HDA_TransferCodecVerbs Count %lu CodecTransfer %p Callback %p Context %p\n", Count, CodecTransfer, Callback, Context);
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)_context;
|
||||
ASSERT(DeviceExtension->IsFDO == FALSE);
|
||||
|
||||
/* FIXME handle callback*/
|
||||
ASSERT(Callback == NULL);
|
||||
|
||||
for (Index = 0; Index < Count; Index++)
|
||||
{
|
||||
Verbs[Index] = CodecTransfer[Index].Output.Command;
|
||||
}
|
||||
|
||||
HDA_SendVerbs(DeviceExtension->FDO, DeviceExtension->Codec, Verbs, Responses, Count);
|
||||
|
||||
for (Index = 0; Index < DeviceExtension->Codec->ResponseCount; Index++)
|
||||
{
|
||||
CodecTransfer[Index].Input.Response = DeviceExtension->Codec->Responses[Index];
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_AllocateCaptureDmaEngine(
|
||||
IN PVOID _context,
|
||||
IN UCHAR CodecAddress,
|
||||
IN PHDAUDIO_STREAM_FORMAT StreamFormat,
|
||||
OUT PHANDLE Handle,
|
||||
OUT PHDAUDIO_CONVERTER_FORMAT ConverterFormat)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_AllocateRenderDmaEngine(
|
||||
IN PVOID _context,
|
||||
IN PHDAUDIO_STREAM_FORMAT StreamFormat,
|
||||
IN BOOLEAN Stripe,
|
||||
OUT PHANDLE Handle,
|
||||
OUT PHDAUDIO_CONVERTER_FORMAT ConverterFormat)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_ChangeBandwidthAllocation(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
IN PHDAUDIO_STREAM_FORMAT StreamFormat,
|
||||
OUT PHDAUDIO_CONVERTER_FORMAT ConverterFormat)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_AllocateDmaBuffer(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
IN SIZE_T RequestedBufferSize,
|
||||
OUT PMDL *BufferMdl,
|
||||
OUT PSIZE_T AllocatedBufferSize,
|
||||
OUT PUCHAR StreamId,
|
||||
OUT PULONG FifoSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FreeDmaBuffer(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FreeDmaEngine(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_SetDmaEngineState(
|
||||
IN PVOID _context,
|
||||
IN HDAUDIO_STREAM_STATE StreamState,
|
||||
IN ULONG NumberOfHandles,
|
||||
IN PHANDLE Handles)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_GetWallClockRegister(
|
||||
IN PVOID _context,
|
||||
OUT PULONG *Wallclock)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_GetLinkPositionRegister(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
OUT PULONG *Position)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_RegisterEventCallback(
|
||||
IN PVOID _context,
|
||||
IN PHDAUDIO_UNSOLICITED_RESPONSE_CALLBACK Routine,
|
||||
IN PVOID Context,
|
||||
OUT PUCHAR Tag)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
*Tag = 1;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_UnregisterEventCallback(
|
||||
IN PVOID _context,
|
||||
IN UCHAR Tag)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_GetDeviceInformation(
|
||||
IN PVOID _context,
|
||||
OUT PHDAUDIO_DEVICE_INFORMATION DeviceInformation)
|
||||
{
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)_context;
|
||||
|
||||
DPRINT1("HDA_GetDeviceInformation\n");
|
||||
|
||||
DeviceInformation->Size = sizeof(HDAUDIO_DEVICE_INFORMATION);
|
||||
DeviceInformation->CodecsDetected = 1; // FIXME
|
||||
DeviceInformation->DeviceVersion = DeviceExtension->Codec->Major << 8 | DeviceExtension->Codec->Minor;
|
||||
DeviceInformation->DriverVersion = DeviceExtension->Codec->Major << 8 | DeviceExtension->Codec->Minor;
|
||||
DeviceInformation->IsStripingSupported = FALSE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_GetResourceInformation(
|
||||
IN PVOID _context,
|
||||
OUT PUCHAR CodecAddress,
|
||||
OUT PUCHAR FunctionGroupStartNode)
|
||||
{
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)_context;
|
||||
|
||||
DPRINT1("HDA_GetResourceInformation Addr %x NodeId %x\n", DeviceExtension->Codec->Addr, DeviceExtension->AudioGroup->NodeId);
|
||||
|
||||
*CodecAddress = DeviceExtension->Codec->Addr;
|
||||
*FunctionGroupStartNode = DeviceExtension->AudioGroup->NodeId;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_AllocateDmaBufferWithNotification(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
IN ULONG NotificationCount,
|
||||
IN SIZE_T RequestedBufferSize,
|
||||
OUT PMDL *BufferMdl,
|
||||
OUT PSIZE_T AllocatedBufferSize,
|
||||
OUT PSIZE_T OffsetFromFirstPage,
|
||||
OUT PUCHAR StreamId,
|
||||
OUT PULONG FifoSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
}
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FreeDmaBufferWithNotification(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
IN PMDL BufferMdl,
|
||||
IN SIZE_T BufferSize)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_RegisterNotificationEvent(
|
||||
PVOID _context,
|
||||
HANDLE Handle,
|
||||
IN PKEVENT NotificationEvent)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_UnregisterNotificationEvent(
|
||||
IN PVOID _context,
|
||||
IN HANDLE Handle,
|
||||
IN PKEVENT NotificationEvent)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOHandleQueryInterface(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PHDAUDIO_BUS_INTERFACE_V2 InterfaceHDA;
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->IsFDO == FALSE);
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, GUID_HDAUDIO_BUS_INTERFACE))
|
||||
{
|
||||
InterfaceHDA = (PHDAUDIO_BUS_INTERFACE_V2)IoStack->Parameters.QueryInterface.Interface;
|
||||
InterfaceHDA->Version = IoStack->Parameters.QueryInterface.Version;
|
||||
InterfaceHDA->Size = sizeof(HDAUDIO_BUS_INTERFACE);
|
||||
InterfaceHDA->Context = DeviceExtension;
|
||||
InterfaceHDA->InterfaceReference = HDA_InterfaceReference;
|
||||
InterfaceHDA->InterfaceDereference = HDA_InterfaceDereference;
|
||||
|
||||
InterfaceHDA->TransferCodecVerbs = HDA_TransferCodecVerbs;
|
||||
InterfaceHDA->AllocateCaptureDmaEngine = HDA_AllocateCaptureDmaEngine;
|
||||
InterfaceHDA->AllocateRenderDmaEngine = HDA_AllocateRenderDmaEngine;
|
||||
InterfaceHDA->ChangeBandwidthAllocation = HDA_ChangeBandwidthAllocation;
|
||||
InterfaceHDA->AllocateDmaBuffer = HDA_AllocateDmaBuffer;
|
||||
InterfaceHDA->FreeDmaBuffer = HDA_FreeDmaBuffer;
|
||||
InterfaceHDA->FreeDmaEngine = HDA_FreeDmaEngine;
|
||||
InterfaceHDA->SetDmaEngineState = HDA_SetDmaEngineState;
|
||||
InterfaceHDA->GetWallClockRegister = HDA_GetWallClockRegister;
|
||||
InterfaceHDA->GetLinkPositionRegister = HDA_GetLinkPositionRegister;
|
||||
InterfaceHDA->RegisterEventCallback = HDA_RegisterEventCallback;
|
||||
InterfaceHDA->UnregisterEventCallback = HDA_UnregisterEventCallback;
|
||||
InterfaceHDA->GetDeviceInformation = HDA_GetDeviceInformation;
|
||||
InterfaceHDA->GetResourceInformation = HDA_GetResourceInformation;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, GUID_HDAUDIO_BUS_INTERFACE_V2))
|
||||
{
|
||||
InterfaceHDA = (PHDAUDIO_BUS_INTERFACE_V2)IoStack->Parameters.QueryInterface.Interface;
|
||||
InterfaceHDA->Version = IoStack->Parameters.QueryInterface.Version;
|
||||
InterfaceHDA->Size = sizeof(HDAUDIO_BUS_INTERFACE_V2);
|
||||
InterfaceHDA->Context = DeviceExtension;
|
||||
InterfaceHDA->InterfaceReference = HDA_InterfaceReference;
|
||||
InterfaceHDA->InterfaceDereference = HDA_InterfaceDereference;
|
||||
|
||||
InterfaceHDA->TransferCodecVerbs = HDA_TransferCodecVerbs;
|
||||
InterfaceHDA->AllocateCaptureDmaEngine = HDA_AllocateCaptureDmaEngine;
|
||||
InterfaceHDA->AllocateRenderDmaEngine = HDA_AllocateRenderDmaEngine;
|
||||
InterfaceHDA->ChangeBandwidthAllocation = HDA_ChangeBandwidthAllocation;
|
||||
InterfaceHDA->AllocateDmaBuffer = HDA_AllocateDmaBuffer;
|
||||
InterfaceHDA->FreeDmaBuffer = HDA_FreeDmaBuffer;
|
||||
InterfaceHDA->FreeDmaEngine = HDA_FreeDmaEngine;
|
||||
InterfaceHDA->SetDmaEngineState = HDA_SetDmaEngineState;
|
||||
InterfaceHDA->GetWallClockRegister = HDA_GetWallClockRegister;
|
||||
InterfaceHDA->GetLinkPositionRegister = HDA_GetLinkPositionRegister;
|
||||
InterfaceHDA->RegisterEventCallback = HDA_RegisterEventCallback;
|
||||
InterfaceHDA->UnregisterEventCallback = HDA_UnregisterEventCallback;
|
||||
InterfaceHDA->GetDeviceInformation = HDA_GetDeviceInformation;
|
||||
InterfaceHDA->GetResourceInformation = HDA_GetResourceInformation;
|
||||
|
||||
InterfaceHDA->AllocateDmaBufferWithNotification = HDA_AllocateDmaBufferWithNotification;
|
||||
InterfaceHDA->FreeDmaBufferWithNotification = HDA_FreeDmaBufferWithNotification;
|
||||
InterfaceHDA->RegisterNotificationEvent = HDA_RegisterNotificationEvent;
|
||||
InterfaceHDA->UnregisterNotificationEvent = HDA_UnregisterNotificationEvent;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// implement support for GUID_HDAUDIO_BUS_INTERFACE_BDL
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar Adema, ithamar AT unet DOT nl
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef _HDA_H_
|
||||
#define _HDA_H_
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#include <KernelExport.h>
|
||||
#include <Drivers.h>
|
||||
#include <PCI.h>
|
||||
#include <PCI_x86.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
# define DEVFS_PATH_FORMAT "audio/multi/hda/%lu"
|
||||
# include <multi_audio.h>
|
||||
#else
|
||||
# define DEVFS_PATH_FORMAT "audio/hmulti/hda/%lu"
|
||||
# include <hmulti_audio.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "hda_controller_defs.h"
|
||||
#include "hda_codec_defs.h"
|
||||
|
||||
#define MAX_CARDS 4
|
||||
|
||||
/* values for the class_sub field for class_base = 0x04 (multimedia device) */
|
||||
#ifndef __HAIKU__
|
||||
# define PCI_hd_audio 3
|
||||
#endif
|
||||
|
||||
#define HDA_MAX_AUDIO_GROUPS 15
|
||||
#define HDA_MAX_CODECS 15
|
||||
#define HDA_MAX_STREAMS 16
|
||||
#define MAX_CODEC_RESPONSES 16
|
||||
#define MAX_CODEC_UNSOL_RESPONSES 16
|
||||
#define MAX_INPUTS 32
|
||||
#define MAX_IO_WIDGETS 8
|
||||
#define MAX_ASSOCIATIONS 16
|
||||
#define MAX_ASSOCIATION_PINS 16
|
||||
|
||||
#define STREAM_MAX_BUFFERS 10
|
||||
#define STREAM_MIN_BUFFERS 2
|
||||
|
||||
|
||||
enum {
|
||||
STREAM_PLAYBACK,
|
||||
STREAM_RECORD
|
||||
};
|
||||
|
||||
struct hda_codec;
|
||||
struct hda_stream;
|
||||
struct hda_multi;
|
||||
|
||||
/*! This structure describes a single HDA compliant
|
||||
controller. It contains a list of available streams
|
||||
for use by the codecs contained, and the messaging queue
|
||||
(verb/response) buffers for communication.
|
||||
*/
|
||||
#ifndef __REACTOS__
|
||||
struct hda_controller {
|
||||
struct pci_info pci_info;
|
||||
int32 opened;
|
||||
const char* devfs_path;
|
||||
|
||||
area_id regs_area;
|
||||
vuint8* regs;
|
||||
uint32 irq;
|
||||
bool msi;
|
||||
bool dma_snooping;
|
||||
|
||||
uint16 codec_status;
|
||||
uint32 num_input_streams;
|
||||
uint32 num_output_streams;
|
||||
uint32 num_bidir_streams;
|
||||
|
||||
uint32 corb_length;
|
||||
uint32 rirb_length;
|
||||
uint32 rirb_read_pos;
|
||||
uint32 corb_write_pos;
|
||||
area_id corb_rirb_pos_area;
|
||||
corb_t* corb;
|
||||
rirb_t* rirb;
|
||||
uint32* stream_positions;
|
||||
|
||||
hda_codec* codecs[HDA_MAX_CODECS + 1];
|
||||
hda_codec* active_codec;
|
||||
uint32 num_codecs;
|
||||
|
||||
hda_stream* streams[HDA_MAX_STREAMS];
|
||||
sem_id buffer_ready_sem;
|
||||
|
||||
uint8 Read8(uint32 reg)
|
||||
{
|
||||
return *(regs + reg);
|
||||
}
|
||||
|
||||
uint16 Read16(uint32 reg)
|
||||
{
|
||||
return *(vuint16*)(regs + reg);
|
||||
}
|
||||
|
||||
uint32 Read32(uint32 reg)
|
||||
{
|
||||
return *(vuint32*)(regs + reg);
|
||||
}
|
||||
|
||||
void Write8(uint32 reg, uint8 value)
|
||||
{
|
||||
*(regs + reg) = value;
|
||||
}
|
||||
|
||||
void Write16(uint32 reg, uint16 value)
|
||||
{
|
||||
*(vuint16*)(regs + reg) = value;
|
||||
}
|
||||
|
||||
void Write32(uint32 reg, uint32 value)
|
||||
{
|
||||
*(vuint32*)(regs + reg) = value;
|
||||
}
|
||||
|
||||
void ReadModifyWrite8(uint32 reg, uint8 mask, uint8 value)
|
||||
{
|
||||
uint8 temp = Read8(reg);
|
||||
temp &= ~mask;
|
||||
temp |= value;
|
||||
Write8(reg, temp);
|
||||
}
|
||||
|
||||
void ReadModifyWrite16(uint32 reg, uint16 mask, uint16 value)
|
||||
{
|
||||
uint16 temp = Read16(reg);
|
||||
temp &= ~mask;
|
||||
temp |= value;
|
||||
Write16(reg, temp);
|
||||
}
|
||||
|
||||
void ReadModifyWrite32(uint32 reg, uint32 mask, uint32 value)
|
||||
{
|
||||
uint32 temp = Read32(reg);
|
||||
temp &= ~mask;
|
||||
temp |= value;
|
||||
Write32(reg, temp);
|
||||
}
|
||||
};
|
||||
|
||||
/*! This structure describes a single stream of audio data,
|
||||
which is can have multiple channels (for stereo or better).
|
||||
*/
|
||||
struct hda_stream {
|
||||
uint32 id; /* HDA controller stream # */
|
||||
uint32 offset; /* HDA I/O/B descriptor offset */
|
||||
bool running;
|
||||
spinlock lock; /* Write lock */
|
||||
uint32 type;
|
||||
|
||||
hda_controller* controller;
|
||||
|
||||
uint32 pin_widget; /* PIN Widget ID */
|
||||
uint32 io_widgets[MAX_IO_WIDGETS]; /* Input/Output Converter Widget ID */
|
||||
uint32 num_io_widgets;
|
||||
|
||||
uint32 sample_rate;
|
||||
uint32 sample_format;
|
||||
|
||||
uint32 num_buffers;
|
||||
uint32 num_channels;
|
||||
uint32 buffer_length; /* size of buffer in samples */
|
||||
uint32 buffer_size; /* actual (aligned) size of buffer in bytes */
|
||||
uint32 sample_size;
|
||||
uint8* buffers[STREAM_MAX_BUFFERS];
|
||||
/* Virtual addresses for buffer */
|
||||
phys_addr_t physical_buffers[STREAM_MAX_BUFFERS];
|
||||
/* Physical addresses for buffer */
|
||||
|
||||
volatile bigtime_t real_time;
|
||||
volatile uint64 frames_count;
|
||||
uint32 last_link_frame_position;
|
||||
volatile int32 buffer_cycle;
|
||||
|
||||
uint32 rate, bps; /* Samplerate & bits per sample */
|
||||
|
||||
area_id buffer_area;
|
||||
area_id buffer_descriptors_area;
|
||||
phys_addr_t physical_buffer_descriptors; /* BDL physical address */
|
||||
|
||||
int32 incorrect_position_count;
|
||||
bool use_dma_position;
|
||||
|
||||
uint8 Read8(uint32 reg)
|
||||
{
|
||||
return controller->Read8(HDAC_STREAM_BASE + offset + reg);
|
||||
}
|
||||
|
||||
uint16 Read16(uint32 reg)
|
||||
{
|
||||
return controller->Read16(HDAC_STREAM_BASE + offset + reg);
|
||||
}
|
||||
|
||||
uint32 Read32(uint32 reg)
|
||||
{
|
||||
return controller->Read32(HDAC_STREAM_BASE + offset + reg);
|
||||
}
|
||||
|
||||
void Write8(uint32 reg, uint8 value)
|
||||
{
|
||||
*(controller->regs + HDAC_STREAM_BASE + offset + reg) = value;
|
||||
}
|
||||
|
||||
void Write16(uint32 reg, uint16 value)
|
||||
{
|
||||
*(vuint16*)(controller->regs + HDAC_STREAM_BASE + offset + reg) = value;
|
||||
}
|
||||
|
||||
void Write32(uint32 reg, uint32 value)
|
||||
{
|
||||
*(vuint32*)(controller->regs + HDAC_STREAM_BASE + offset + reg) = value;
|
||||
}
|
||||
};
|
||||
|
||||
struct hda_widget {
|
||||
uint32 node_id;
|
||||
|
||||
uint32 num_inputs;
|
||||
int32 active_input;
|
||||
uint32 inputs[MAX_INPUTS];
|
||||
uint32 flags;
|
||||
|
||||
hda_widget_type type;
|
||||
uint32 pm;
|
||||
|
||||
struct {
|
||||
uint32 audio;
|
||||
uint32 output_amplifier;
|
||||
uint32 input_amplifier;
|
||||
} capabilities;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32 formats;
|
||||
uint32 rates;
|
||||
} io;
|
||||
struct {
|
||||
} mixer;
|
||||
struct {
|
||||
uint32 capabilities;
|
||||
uint32 config;
|
||||
} pin;
|
||||
} d;
|
||||
};
|
||||
|
||||
struct hda_association {
|
||||
uint32 index;
|
||||
bool enabled;
|
||||
uint32 pin_count;
|
||||
uint32 pins[MAX_ASSOCIATION_PINS];
|
||||
};
|
||||
#endif
|
||||
|
||||
#define WIDGET_FLAG_OUTPUT_PATH 0x01
|
||||
#define WIDGET_FLAG_INPUT_PATH 0x02
|
||||
#define WIDGET_FLAG_WIDGET_PATH 0x04
|
||||
|
||||
/*! This structure describes a single Audio Function Group. An AFG
|
||||
is a group of audio widgets which can be used to configure multiple
|
||||
streams of audio either from the HDA Link to an output device (= playback)
|
||||
or from an input device to the HDA link (= recording).
|
||||
*/
|
||||
#ifndef __REACTOS__
|
||||
struct hda_audio_group {
|
||||
hda_codec* codec;
|
||||
hda_widget widget;
|
||||
|
||||
/* Multi Audio API data */
|
||||
hda_stream* playback_stream;
|
||||
hda_stream* record_stream;
|
||||
|
||||
uint32 widget_start;
|
||||
uint32 widget_count;
|
||||
|
||||
uint32 association_count;
|
||||
uint32 gpio;
|
||||
|
||||
hda_widget* widgets;
|
||||
hda_association associations[MAX_ASSOCIATIONS];
|
||||
|
||||
hda_multi* multi;
|
||||
};
|
||||
|
||||
/*! This structure describes a single codec module in the
|
||||
HDA compliant device. This is a discrete component, which
|
||||
can contain both Audio Function Groups, Modem Function Groups,
|
||||
and other customized (vendor specific) Function Groups.
|
||||
|
||||
NOTE: ATM, only Audio Function Groups are supported.
|
||||
*/
|
||||
struct hda_codec {
|
||||
uint16 vendor_id;
|
||||
uint16 product_id;
|
||||
uint8 major;
|
||||
uint8 minor;
|
||||
uint8 revision;
|
||||
uint8 stepping;
|
||||
uint8 addr;
|
||||
|
||||
uint32 quirks;
|
||||
|
||||
sem_id response_sem;
|
||||
uint32 responses[MAX_CODEC_RESPONSES];
|
||||
uint32 response_count;
|
||||
|
||||
sem_id unsol_response_sem;
|
||||
thread_id unsol_response_thread;
|
||||
uint32 unsol_responses[MAX_CODEC_UNSOL_RESPONSES];
|
||||
uint32 unsol_response_read, unsol_response_write;
|
||||
|
||||
hda_audio_group* audio_groups[HDA_MAX_AUDIO_GROUPS];
|
||||
uint32 num_audio_groups;
|
||||
|
||||
struct hda_controller* controller;
|
||||
};
|
||||
|
||||
|
||||
#define MULTI_CONTROL_FIRSTID 1024
|
||||
#define MULTI_CONTROL_MASTERID 0
|
||||
#define MULTI_MAX_CONTROLS 128
|
||||
#define MULTI_MAX_CHANNELS 128
|
||||
|
||||
struct hda_multi_mixer_control {
|
||||
hda_multi *multi;
|
||||
int32 nid;
|
||||
int32 type;
|
||||
bool input;
|
||||
uint32 mute;
|
||||
uint32 gain;
|
||||
uint32 capabilities;
|
||||
int32 index;
|
||||
multi_mix_control mix_control;
|
||||
};
|
||||
|
||||
|
||||
struct hda_multi {
|
||||
hda_audio_group *group;
|
||||
hda_multi_mixer_control controls[MULTI_MAX_CONTROLS];
|
||||
uint32 control_count;
|
||||
|
||||
multi_channel_info chans[MULTI_MAX_CHANNELS];
|
||||
uint32 output_channel_count;
|
||||
uint32 input_channel_count;
|
||||
uint32 output_bus_channel_count;
|
||||
uint32 input_bus_channel_count;
|
||||
uint32 aux_bus_channel_count;
|
||||
};
|
||||
|
||||
|
||||
/* driver.c */
|
||||
extern device_hooks gDriverHooks;
|
||||
extern pci_module_info* gPci;
|
||||
extern pci_x86_module_info* gPCIx86Module;
|
||||
extern hda_controller gCards[MAX_CARDS];
|
||||
extern uint32 gNumCards;
|
||||
|
||||
/* hda_codec.c */
|
||||
const char* get_widget_location(uint32 location);
|
||||
hda_widget* hda_audio_group_get_widget(hda_audio_group* audioGroup, uint32 nodeID);
|
||||
|
||||
status_t hda_audio_group_get_widgets(hda_audio_group* audioGroup,
|
||||
hda_stream* stream);
|
||||
hda_codec* hda_codec_new(hda_controller* controller, uint32 cad);
|
||||
void hda_codec_delete(hda_codec* codec);
|
||||
|
||||
/* hda_multi_audio.c */
|
||||
status_t multi_audio_control(void* cookie, uint32 op, void* arg, size_t length);
|
||||
|
||||
/* hda_controller.c: Basic controller support */
|
||||
status_t hda_hw_init(hda_controller* controller);
|
||||
void hda_hw_stop(hda_controller* controller);
|
||||
void hda_hw_uninit(hda_controller* controller);
|
||||
status_t hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses,
|
||||
uint32 count);
|
||||
status_t hda_verb_write(hda_codec* codec, uint32 nid, uint32 vid, uint16 payload);
|
||||
status_t hda_verb_read(hda_codec* codec, uint32 nid, uint32 vid, uint32 *response);
|
||||
|
||||
/* hda_controller.c: Stream support */
|
||||
hda_stream* hda_stream_new(hda_audio_group* audioGroup, int type);
|
||||
void hda_stream_delete(hda_stream* stream);
|
||||
status_t hda_stream_setup_buffers(hda_audio_group* audioGroup,
|
||||
hda_stream* stream, const char* desc);
|
||||
status_t hda_stream_start(hda_controller* controller, hda_stream* stream);
|
||||
status_t hda_stream_stop(hda_controller* controller, hda_stream* stream);
|
||||
#endif
|
||||
|
||||
#endif /* _HDA_H_ */
|
||||
@@ -1,815 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel Streaming
|
||||
* FILE: drivers/wdm/audio/hdaudbus/fdo.cpp
|
||||
* PURPOSE: HDA Driver Entry
|
||||
* PROGRAMMER: Johannes Anderwald
|
||||
*/
|
||||
|
||||
#include "hdaudbus.h"
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
HDA_InterruptService(
|
||||
IN PKINTERRUPT Interrupt,
|
||||
IN PVOID ServiceContext)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG InterruptStatus;
|
||||
UCHAR RirbStatus, CorbStatus;
|
||||
|
||||
/* get device extension */
|
||||
DeviceObject = static_cast<PDEVICE_OBJECT>(ServiceContext);
|
||||
DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
ASSERT(DeviceExtension->IsFDO == TRUE);
|
||||
|
||||
// Check if this interrupt is ours
|
||||
InterruptStatus = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_INTR_STATUS));
|
||||
|
||||
DPRINT("HDA_InterruptService %lx\n", InterruptStatus);
|
||||
if ((InterruptStatus & INTR_STATUS_GLOBAL) == 0)
|
||||
return FALSE;
|
||||
|
||||
// Controller or stream related?
|
||||
if (InterruptStatus & INTR_STATUS_CONTROLLER) {
|
||||
RirbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS);
|
||||
CorbStatus = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS);
|
||||
|
||||
// Check for incoming responses
|
||||
if (RirbStatus) {
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_STATUS, RirbStatus);
|
||||
|
||||
if (DeviceExtension->RirbLength == 0)
|
||||
{
|
||||
/* HACK: spurious interrupt */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((RirbStatus & RIRB_STATUS_RESPONSE) != 0) {
|
||||
IoRequestDpc(DeviceObject, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((RirbStatus & RIRB_STATUS_OVERRUN) != 0)
|
||||
DPRINT1("hda: RIRB Overflow\n");
|
||||
}
|
||||
|
||||
// Check for sending errors
|
||||
if (CorbStatus) {
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_STATUS, CorbStatus);
|
||||
|
||||
if ((CorbStatus & CORB_STATUS_MEMORY_ERROR) != 0)
|
||||
DPRINT1("hda: CORB Memory Error!\n");
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if ((intrStatus & INTR_STATUS_STREAM_MASK) != 0) {
|
||||
for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) {
|
||||
if ((intrStatus & (1 << index)) != 0) {
|
||||
if (controller->streams[index]) {
|
||||
if (stream_handle_interrupt(controller,
|
||||
controller->streams[index], index)) {
|
||||
handled = B_INVOKE_SCHEDULER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
dprintf("hda: Stream interrupt for unconfigured stream "
|
||||
"%ld!\n", index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_DpcForIsr(
|
||||
_In_ PKDPC Dpc,
|
||||
_In_opt_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp,
|
||||
_In_opt_ PVOID Context)
|
||||
{
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Response, ResponseFlags, Cad;
|
||||
USHORT WritePos;
|
||||
PHDA_CODEC_ENTRY Codec;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
ASSERT(DeviceExtension->IsFDO == TRUE);
|
||||
|
||||
WritePos = (READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) + 1) % DeviceExtension->RirbLength;
|
||||
|
||||
for (; DeviceExtension->RirbReadPos != WritePos; DeviceExtension->RirbReadPos = (DeviceExtension->RirbReadPos + 1) % DeviceExtension->RirbLength)
|
||||
{
|
||||
Response = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].response;
|
||||
ResponseFlags = DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].flags;
|
||||
Cad = ResponseFlags & RESPONSE_FLAGS_CODEC_MASK;
|
||||
DPRINT1("Response %lx ResponseFlags %lx Cad %lx\n", Response, ResponseFlags, Cad);
|
||||
|
||||
/* get codec */
|
||||
Codec = DeviceExtension->Codecs[Cad];
|
||||
if (Codec == NULL)
|
||||
{
|
||||
DPRINT1("hda: response for unknown codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check response count */
|
||||
if (Codec->ResponseCount >= MAX_CODEC_RESPONSES)
|
||||
{
|
||||
DPRINT1("too many responses for codec %x Response %x ResponseFlags %x\n", Cad, Response, ResponseFlags);
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME handle unsolicited responses
|
||||
ASSERT((ResponseFlags & RESPONSE_FLAGS_UNSOLICITED) == 0);
|
||||
|
||||
/* store response */
|
||||
Codec->Responses[Codec->ResponseCount] = Response;
|
||||
Codec->ResponseCount++;
|
||||
KeReleaseSemaphore(&Codec->ResponseSemaphore, IO_NO_INCREMENT, 1, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
HDA_SendVerbs(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PHDA_CODEC_ENTRY Codec,
|
||||
IN PULONG Verbs,
|
||||
OUT PULONG Responses,
|
||||
IN ULONG Count)
|
||||
{
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Sent = 0, ReadPosition, WritePosition, Queued;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->IsFDO);
|
||||
|
||||
/* reset response count */
|
||||
Codec->ResponseCount = 0;
|
||||
|
||||
while (Sent < Count) {
|
||||
ReadPosition = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
|
||||
|
||||
Queued = 0;
|
||||
|
||||
while (Sent < Count) {
|
||||
WritePosition = (DeviceExtension->CorbWritePos + 1) % DeviceExtension->CorbLength;
|
||||
|
||||
if (WritePosition == ReadPosition) {
|
||||
// There is no space left in the ring buffer; execute the
|
||||
// queued commands and wait until
|
||||
break;
|
||||
}
|
||||
|
||||
DeviceExtension->CorbBase[WritePosition] = Verbs[Sent++];
|
||||
DeviceExtension->CorbWritePos = WritePosition;
|
||||
Queued++;
|
||||
}
|
||||
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos);
|
||||
}
|
||||
|
||||
while (Queued--)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
Timeout.QuadPart = -1000LL * 10000; // 1 sec
|
||||
|
||||
NTSTATUS waitStatus = KeWaitForSingleObject(&Codec->ResponseSemaphore,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
&Timeout);
|
||||
|
||||
if (waitStatus == STATUS_TIMEOUT)
|
||||
{
|
||||
DPRINT1("HDA_SendVerbs: timeout! Queued: %u\n", Queued);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
if (Responses != NULL) {
|
||||
memcpy(Responses, Codec->Responses, Codec->ResponseCount * sizeof(ULONG));
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_InitCodec(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG codecAddress)
|
||||
{
|
||||
PHDA_CODEC_ENTRY Entry;
|
||||
ULONG verbs[3];
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
CODEC_RESPONSE Response;
|
||||
ULONG NodeId, GroupType;
|
||||
NTSTATUS Status;
|
||||
PHDA_CODEC_AUDIO_GROUP AudioGroup;
|
||||
PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
|
||||
|
||||
/* lets allocate the entry */
|
||||
Entry = (PHDA_CODEC_ENTRY)AllocateItem(NonPagedPool, sizeof(HDA_CODEC_ENTRY));
|
||||
if (!Entry)
|
||||
{
|
||||
DPRINT1("hda: failed to allocate memory\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* init codec */
|
||||
Entry->Addr = codecAddress;
|
||||
KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES);
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* store codec */
|
||||
DeviceExtension->Codecs[codecAddress] = Entry;
|
||||
|
||||
verbs[0] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_VENDOR_ID);
|
||||
verbs[1] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_REVISION_ID);
|
||||
verbs[2] = MAKE_VERB(codecAddress, 0, VID_GET_PARAMETER, PID_SUB_NODE_COUNT);
|
||||
|
||||
/* get basic info */
|
||||
Status = HDA_SendVerbs(DeviceObject, Entry, verbs, (PULONG)&Response, 3);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FreeItem(Entry);
|
||||
DeviceExtension->Codecs[codecAddress] = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* store codec details */
|
||||
Entry->Major = Response.major;
|
||||
Entry->Minor = Response.minor;
|
||||
Entry->ProductId = Response.device;
|
||||
Entry->Revision = Response.revision;
|
||||
Entry->Stepping = Response.stepping;
|
||||
Entry->VendorId = Response.vendor;
|
||||
|
||||
DPRINT1("hda Codec %ld Vendor: %04lx Product: %04lx, Revision: %lu.%lu.%lu.%lu NodeStart %u NodeCount %u \n", codecAddress, Response.vendor,
|
||||
Response.device, Response.major, Response.minor, Response.revision, Response.stepping, Response.start, Response.count);
|
||||
|
||||
for (NodeId = Response.start; NodeId < Response.start + Response.count; NodeId++) {
|
||||
|
||||
/* get function type */
|
||||
verbs[0] = MAKE_VERB(codecAddress, NodeId, VID_GET_PARAMETER, PID_FUNCTION_GROUP_TYPE);
|
||||
|
||||
Status = HDA_SendVerbs(DeviceObject, Entry, verbs, &GroupType, 1);
|
||||
DPRINT1("Status %x NodeId %u GroupType %x\n", Status, NodeId, GroupType);
|
||||
|
||||
|
||||
if (NT_SUCCESS(Status) &&
|
||||
(GroupType & FUNCTION_GROUP_NODETYPE_MASK) == FUNCTION_GROUP_NODETYPE_AUDIO)
|
||||
{
|
||||
if (Entry->AudioGroupCount >= HDA_MAX_AUDIO_GROUPS)
|
||||
{
|
||||
DPRINT1("Too many audio groups in node %u. Skipping.\n", NodeId);
|
||||
break;
|
||||
}
|
||||
|
||||
AudioGroup = (PHDA_CODEC_AUDIO_GROUP)AllocateItem(NonPagedPool, sizeof(HDA_CODEC_AUDIO_GROUP));
|
||||
if (!AudioGroup)
|
||||
{
|
||||
DPRINT1("hda: insufficient memory\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* init audio group */
|
||||
AudioGroup->NodeId = NodeId;
|
||||
AudioGroup->FunctionGroup = FUNCTION_GROUP_NODETYPE_AUDIO;
|
||||
|
||||
// Found an Audio Function Group!
|
||||
DPRINT1("NodeId %x found an audio function group!\n", NodeId);
|
||||
|
||||
Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(HDA_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_SOUND, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &AudioGroup->ChildPDO);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FreeItem(AudioGroup);
|
||||
DPRINT1("hda failed to create device object %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* init child pdo*/
|
||||
ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension;
|
||||
ChildDeviceExtension->IsFDO = FALSE;
|
||||
ChildDeviceExtension->ReportedMissing = FALSE;
|
||||
ChildDeviceExtension->Codec = Entry;
|
||||
ChildDeviceExtension->AudioGroup = AudioGroup;
|
||||
ChildDeviceExtension->FDO = DeviceObject;
|
||||
|
||||
/* setup flags */
|
||||
AudioGroup->ChildPDO->Flags |= DO_POWER_PAGABLE;
|
||||
AudioGroup->ChildPDO->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
/* add audio group*/
|
||||
Entry->AudioGroups[Entry->AudioGroupCount] = AudioGroup;
|
||||
Entry->AudioGroupCount++;
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_InitCorbRirbPos(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
UCHAR corbSize, value, rirbSize;
|
||||
PHYSICAL_ADDRESS HighestPhysicalAddress, CorbPhysicalAddress;
|
||||
ULONG Index;
|
||||
USHORT corbReadPointer, rirbWritePointer, interruptValue, corbControl, rirbControl;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
// Determine and set size of CORB
|
||||
corbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE);
|
||||
if ((corbSize & CORB_SIZE_CAP_256_ENTRIES) != 0) {
|
||||
DeviceExtension->CorbLength = 256;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE, value | CORB_SIZE_256_ENTRIES);
|
||||
}
|
||||
else if (corbSize & CORB_SIZE_CAP_16_ENTRIES) {
|
||||
DeviceExtension->CorbLength = 16;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE, value | CORB_SIZE_16_ENTRIES);
|
||||
}
|
||||
else if (corbSize & CORB_SIZE_CAP_2_ENTRIES) {
|
||||
DeviceExtension->CorbLength = 2;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE) & ~HDAC_CORB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_SIZE, value | CORB_SIZE_2_ENTRIES);
|
||||
}
|
||||
|
||||
// Determine and set size of RIRB
|
||||
rirbSize = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE);
|
||||
if (rirbSize & RIRB_SIZE_CAP_256_ENTRIES) {
|
||||
DeviceExtension->RirbLength = 256;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE, value | RIRB_SIZE_256_ENTRIES);
|
||||
}
|
||||
else if (rirbSize & RIRB_SIZE_CAP_16_ENTRIES) {
|
||||
DeviceExtension->RirbLength = 16;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE, value | RIRB_SIZE_16_ENTRIES);
|
||||
}
|
||||
else if (rirbSize & RIRB_SIZE_CAP_2_ENTRIES) {
|
||||
DeviceExtension->RirbLength = 2;
|
||||
|
||||
value = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE) & ~HDAC_RIRB_SIZE_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_SIZE, value | RIRB_SIZE_2_ENTRIES);
|
||||
}
|
||||
|
||||
/* init corb */
|
||||
HighestPhysicalAddress.QuadPart = 0x00000000FFFFFFFF;
|
||||
DeviceExtension->CorbBase = (PULONG)MmAllocateContiguousMemory(PAGE_SIZE * 3, HighestPhysicalAddress);
|
||||
ASSERT(DeviceExtension->CorbBase != NULL);
|
||||
|
||||
// FIXME align rirb 128bytes
|
||||
ASSERT(DeviceExtension->CorbLength == 256);
|
||||
ASSERT(DeviceExtension->RirbLength == 256);
|
||||
|
||||
CorbPhysicalAddress = MmGetPhysicalAddress(DeviceExtension->CorbBase);
|
||||
ASSERT(CorbPhysicalAddress.QuadPart != 0LL);
|
||||
|
||||
// Program CORB/RIRB for these locations
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_LOWER), CorbPhysicalAddress.LowPart);
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_CORB_BASE_UPPER), CorbPhysicalAddress.HighPart);
|
||||
|
||||
DeviceExtension->RirbBase = (PRIRB_RESPONSE)((ULONG_PTR)DeviceExtension->CorbBase + PAGE_SIZE);
|
||||
CorbPhysicalAddress.QuadPart += PAGE_SIZE;
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_LOWER), CorbPhysicalAddress.LowPart);
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_RIRB_BASE_UPPER), CorbPhysicalAddress.HighPart);
|
||||
|
||||
// Program DMA position update
|
||||
DeviceExtension->StreamPositions = (PVOID)((ULONG_PTR)DeviceExtension->RirbBase + PAGE_SIZE);
|
||||
CorbPhysicalAddress.QuadPart += PAGE_SIZE;
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_LOWER), CorbPhysicalAddress.LowPart);
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_UPPER), CorbPhysicalAddress.HighPart);
|
||||
|
||||
value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS)) & ~HDAC_CORB_WRITE_POS_MASK;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_WRITE_POS), value);
|
||||
|
||||
// Reset CORB read pointer. Preserve bits marked as RsvdP.
|
||||
// After setting the reset bit, we must wait for the hardware
|
||||
// to acknowledge it, then manually unset it and wait for that
|
||||
// to be acknowledged as well.
|
||||
corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
|
||||
|
||||
corbReadPointer |= CORB_READ_POS_RESET;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
|
||||
|
||||
for (Index = 0; Index < 10; Index++) {
|
||||
KeStallExecutionProcessor(100);
|
||||
corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
|
||||
if ((corbReadPointer & CORB_READ_POS_RESET) != 0)
|
||||
break;
|
||||
}
|
||||
if ((corbReadPointer & CORB_READ_POS_RESET) == 0) {
|
||||
DPRINT1("hda: CORB read pointer reset not acknowledged\n");
|
||||
|
||||
// According to HDA spec v1.0a ch3.3.21, software must read the
|
||||
// bit as 1 to verify that the reset completed. However, at least
|
||||
// some nVidia HDA controllers do not update the bit after reset.
|
||||
// Thus don't fail here on nVidia controllers.
|
||||
//if (controller->pci_info.vendor_id != PCI_VENDOR_NVIDIA)
|
||||
// return B_BUSY;
|
||||
}
|
||||
|
||||
corbReadPointer &= ~CORB_READ_POS_RESET;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS), corbReadPointer);
|
||||
for (Index = 0; Index < 10; Index++) {
|
||||
KeStallExecutionProcessor(100);
|
||||
corbReadPointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_READ_POS));
|
||||
if ((corbReadPointer & CORB_READ_POS_RESET) == 0)
|
||||
break;
|
||||
}
|
||||
if ((corbReadPointer & CORB_READ_POS_RESET) != 0) {
|
||||
DPRINT1("hda: CORB read pointer reset failed\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Reset RIRB write pointer
|
||||
rirbWritePointer = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS)) & ~RIRB_WRITE_POS_RESET;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_WRITE_POS), rirbWritePointer | RIRB_WRITE_POS_RESET);
|
||||
|
||||
// Generate interrupt for every response
|
||||
interruptValue = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RESPONSE_INTR_COUNT)) & ~HDAC_RESPONSE_INTR_COUNT_MASK;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RESPONSE_INTR_COUNT), interruptValue | 1);
|
||||
|
||||
// Setup cached read/write indices
|
||||
DeviceExtension->RirbReadPos = 1;
|
||||
DeviceExtension->CorbWritePos = 0;
|
||||
|
||||
// Gentlemen, start your engines...
|
||||
corbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_CONTROL)) & ~HDAC_CORB_CONTROL_MASK;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_CORB_CONTROL), corbControl | CORB_CONTROL_RUN | CORB_CONTROL_MEMORY_ERROR_INTR);
|
||||
|
||||
rirbControl = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_CONTROL)) & ~HDAC_RIRB_CONTROL_MASK;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_RIRB_CONTROL), rirbControl | RIRB_CONTROL_DMA_ENABLE | RIRB_CONTROL_OVERRUN_INTR | RIRB_CONTROL_RESPONSE_INTR);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_ResetController(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
USHORT ValCapabilities;
|
||||
ULONG Index;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG InputStreams, OutputStreams, BiDirStreams, Control;
|
||||
UCHAR corbControl, rirbControl;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* read caps */
|
||||
ValCapabilities = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_GLOBAL_CAP));
|
||||
|
||||
InputStreams = GLOBAL_CAP_INPUT_STREAMS(ValCapabilities);
|
||||
OutputStreams = GLOBAL_CAP_OUTPUT_STREAMS(ValCapabilities);
|
||||
BiDirStreams = GLOBAL_CAP_BIDIR_STREAMS(ValCapabilities);
|
||||
|
||||
DPRINT1("NumInputStreams %u\n", InputStreams);
|
||||
DPRINT1("NumOutputStreams %u\n", OutputStreams);
|
||||
DPRINT1("NumBiDirStreams %u\n", BiDirStreams);
|
||||
|
||||
/* stop all streams */
|
||||
for (Index = 0; Index < InputStreams; Index++)
|
||||
{
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE + HDAC_INPUT_STREAM_OFFSET(Index), 0);
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_STATUS + HDAC_STREAM_BASE + HDAC_INPUT_STREAM_OFFSET(Index), 0);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < OutputStreams; Index++) {
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE + HDAC_OUTPUT_STREAM_OFFSET(InputStreams, Index), 0);
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_STATUS + HDAC_STREAM_BASE + HDAC_OUTPUT_STREAM_OFFSET(InputStreams, Index), 0);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < BiDirStreams; Index++) {
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_CONTROL0 + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_STREAM_STATUS + HDAC_STREAM_BASE + HDAC_BIDIR_STREAM_OFFSET(InputStreams, OutputStreams, Index), 0);
|
||||
}
|
||||
|
||||
// stop DMA
|
||||
Control = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL) & ~HDAC_CORB_CONTROL_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL, Control);
|
||||
|
||||
Control = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL) & ~HDAC_RIRB_CONTROL_MASK;
|
||||
WRITE_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL, Control);
|
||||
|
||||
for (int timeout = 0; timeout < 10; timeout++) {
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
corbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_CORB_CONTROL);
|
||||
rirbControl = READ_REGISTER_UCHAR(DeviceExtension->RegBase + HDAC_RIRB_CONTROL);
|
||||
if (corbControl == 0 && rirbControl == 0)
|
||||
break;
|
||||
}
|
||||
if (corbControl != 0 || rirbControl != 0) {
|
||||
DPRINT1("hda: unable to stop dma\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// reset DMA position buffer
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_LOWER), 0);
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_DMA_POSITION_BASE_UPPER), 0);
|
||||
|
||||
// Set reset bit - it must be asserted for at least 100us
|
||||
Control = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL));
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL), Control & ~GLOBAL_CONTROL_RESET);
|
||||
|
||||
for (int timeout = 0; timeout < 10; timeout++) {
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
Control = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL));
|
||||
if ((Control & GLOBAL_CONTROL_RESET) == 0)
|
||||
break;
|
||||
}
|
||||
if ((Control & GLOBAL_CONTROL_RESET) != 0)
|
||||
{
|
||||
DPRINT1("hda: unable to reset controller\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Unset reset bit
|
||||
Control = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL));
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL), Control | GLOBAL_CONTROL_RESET);
|
||||
|
||||
for (int timeout = 0; timeout < 10; timeout++) {
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
Control = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL));
|
||||
if ((Control & GLOBAL_CONTROL_RESET) != 0)
|
||||
break;
|
||||
}
|
||||
if ((Control & GLOBAL_CONTROL_RESET) == 0) {
|
||||
DPRINT1("hda: unable to exit reset\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
// Wait for codecs to finish their own reset (apparently needs more
|
||||
// time than documented in the specs)
|
||||
KeStallExecutionProcessor(1000);
|
||||
|
||||
// Enable unsolicited responses
|
||||
Control = READ_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL));
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_GLOBAL_CONTROL), Control | GLOBAL_CONTROL_UNSOLICITED);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDOStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PCM_RESOURCE_LIST Resources;
|
||||
ULONG Index;
|
||||
USHORT Value;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->IsFDO == TRUE);
|
||||
|
||||
/* forward irp to lower device */
|
||||
if (!IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
Status = Irp->IoStatus.Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
// failed to start
|
||||
DPRINT1("HDA_StartDevice Lower device failed to start %x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* get current irp stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Resources = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
||||
for (Index = 0; Index < Resources->List[0].PartialResourceList.Count; Index++)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &Resources->List[0].PartialResourceList.PartialDescriptors[Index];
|
||||
|
||||
if (Descriptor->Type == CmResourceTypeMemory)
|
||||
{
|
||||
DeviceExtension->RegLength = Descriptor->u.Memory.Length;
|
||||
DeviceExtension->RegBase = (PUCHAR)MmMapIoSpace(Descriptor->u.Memory.Start, Descriptor->u.Memory.Length, MmNonCached);
|
||||
if (DeviceExtension->RegBase == NULL)
|
||||
{
|
||||
DPRINT1("[HDAB] Failed to map registers\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Descriptor->Type == CmResourceTypeInterrupt)
|
||||
{
|
||||
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
|
||||
HDA_InterruptService,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
Descriptor->u.Interrupt.Vector,
|
||||
Descriptor->u.Interrupt.Level,
|
||||
Descriptor->u.Interrupt.Level,
|
||||
(KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
|
||||
(Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
|
||||
Descriptor->u.Interrupt.Affinity,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("[HDAB] Failed to connect interrupt. Status=%lx\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
// Get controller into valid state
|
||||
Status = HDA_ResetController(DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
// Setup CORB/RIRB/DMA POS
|
||||
Status = HDA_InitCorbRirbPos(DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
|
||||
// Don't enable codec state change interrupts. We don't handle
|
||||
// them, as we want to use the STATE_STATUS register to identify
|
||||
// available codecs. We'd have to clear that register in the interrupt
|
||||
// handler to 'ack' the codec change.
|
||||
Value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_WAKE_ENABLE)) & ~HDAC_WAKE_ENABLE_MASK;
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_WAKE_ENABLE), Value);
|
||||
|
||||
// Enable controller interrupts
|
||||
WRITE_REGISTER_ULONG((PULONG)(DeviceExtension->RegBase + HDAC_INTR_CONTROL), INTR_CONTROL_GLOBAL_ENABLE | INTR_CONTROL_CONTROLLER_ENABLE);
|
||||
|
||||
KeStallExecutionProcessor(1000);
|
||||
|
||||
Value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_STATE_STATUS));
|
||||
if (!Value) {
|
||||
DPRINT1("hda: bad codec status\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_STATE_STATUS), Value);
|
||||
|
||||
// Create codecs
|
||||
DPRINT1("Codecs %lx\n", Value);
|
||||
for (Index = 0; Index < HDA_MAX_CODECS; Index++) {
|
||||
if ((Value & (1 << Index)) != 0) {
|
||||
HDA_InitCodec(DeviceObject, Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDORemoveDevice(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG CodecIndex, AFGIndex;
|
||||
PHDA_CODEC_ENTRY CodecEntry;
|
||||
PDEVICE_OBJECT ChildPDO;
|
||||
PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
ASSERT(DeviceExtension->IsFDO == TRUE);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
|
||||
|
||||
IoDetachDevice(DeviceExtension->LowerDevice);
|
||||
|
||||
if (DeviceExtension->RegBase != NULL)
|
||||
{
|
||||
MmUnmapIoSpace(DeviceExtension->RegBase,
|
||||
DeviceExtension->RegLength);
|
||||
}
|
||||
if (DeviceExtension->Interrupt != NULL)
|
||||
{
|
||||
IoDisconnectInterrupt(DeviceExtension->Interrupt);
|
||||
}
|
||||
if (DeviceExtension->CorbBase != NULL)
|
||||
{
|
||||
MmFreeContiguousMemory(DeviceExtension->CorbBase);
|
||||
}
|
||||
|
||||
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
|
||||
{
|
||||
CodecEntry = DeviceExtension->Codecs[CodecIndex];
|
||||
if (CodecEntry == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT(CodecEntry->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS);
|
||||
for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
|
||||
{
|
||||
ChildPDO = CodecEntry->AudioGroups[AFGIndex]->ChildPDO;
|
||||
if (ChildPDO != NULL)
|
||||
{
|
||||
ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(ChildPDO->DeviceExtension);
|
||||
ChildDeviceExtension->Codec = NULL;
|
||||
ChildDeviceExtension->AudioGroup = NULL;
|
||||
ChildDeviceExtension->FDO = NULL;
|
||||
ChildDeviceExtension->ReportedMissing = TRUE;
|
||||
HDA_PDORemoveDevice(ChildPDO);
|
||||
}
|
||||
FreeItem(CodecEntry->AudioGroups[AFGIndex]);
|
||||
}
|
||||
FreeItem(CodecEntry);
|
||||
}
|
||||
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDOQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG DeviceCount, CodecIndex, AFGIndex;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PHDA_CODEC_ENTRY Codec;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->IsFDO == TRUE);
|
||||
|
||||
DeviceCount = 0;
|
||||
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
|
||||
{
|
||||
if (DeviceExtension->Codecs[CodecIndex] == NULL)
|
||||
continue;
|
||||
|
||||
Codec = DeviceExtension->Codecs[CodecIndex];
|
||||
DeviceCount += Codec->AudioGroupCount;
|
||||
}
|
||||
|
||||
if (DeviceCount == 0)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(NonPagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? sizeof(PDEVICE_OBJECT) * (DeviceCount - 1) : 0));
|
||||
if (!DeviceRelations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
DeviceRelations->Count = 0;
|
||||
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
|
||||
{
|
||||
if (DeviceExtension->Codecs[CodecIndex] == NULL)
|
||||
continue;
|
||||
|
||||
Codec = DeviceExtension->Codecs[CodecIndex];
|
||||
ASSERT(Codec->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS);
|
||||
for (AFGIndex = 0; AFGIndex < Codec->AudioGroupCount; AFGIndex++)
|
||||
{
|
||||
DeviceRelations->Objects[DeviceRelations->Count] = Codec->AudioGroups[AFGIndex]->ChildPDO;
|
||||
ObReferenceObject(Codec->AudioGroups[AFGIndex]->ChildPDO);
|
||||
DeviceRelations->Count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME handle existing device relations */
|
||||
ASSERT(Irp->IoStatus.Information == 0);
|
||||
|
||||
/* store device relations */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
|
||||
/* done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1,386 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar Adema, ithamar AT unet DOT nl
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef HDA_CODEC_H
|
||||
#define HDA_CODEC_H
|
||||
|
||||
enum hda_widget_type {
|
||||
WT_AUDIO_OUTPUT = 0,
|
||||
WT_AUDIO_INPUT = 1,
|
||||
WT_AUDIO_MIXER = 2,
|
||||
WT_AUDIO_SELECTOR = 3,
|
||||
WT_PIN_COMPLEX = 4,
|
||||
WT_POWER = 5,
|
||||
WT_VOLUME_KNOB = 6,
|
||||
WT_BEEP_GENERATOR = 7,
|
||||
WT_VENDOR_DEFINED = 15
|
||||
};
|
||||
|
||||
enum pin_connectivity_type {
|
||||
PIN_CONN_JACK,
|
||||
PIN_CONN_NONE,
|
||||
PIN_CONN_FIXED,
|
||||
PIN_CONN_BOTH
|
||||
};
|
||||
|
||||
enum pin_dev_type {
|
||||
PIN_DEV_LINE_OUT = 0,
|
||||
PIN_DEV_SPEAKER,
|
||||
PIN_DEV_HEAD_PHONE_OUT,
|
||||
PIN_DEV_CD,
|
||||
PIN_DEV_SPDIF_OUT,
|
||||
PIN_DEV_DIGITAL_OTHER_OUT,
|
||||
PIN_DEV_MODEM_LINE_SIDE,
|
||||
PIN_DEV_MODEM_HAND_SIDE,
|
||||
PIN_DEV_LINE_IN,
|
||||
PIN_DEV_AUX,
|
||||
PIN_DEV_MIC_IN,
|
||||
PIN_DEV_TELEPHONY,
|
||||
PIN_DEV_SPDIF_IN,
|
||||
PIN_DEV_DIGITAL_OTHER_IN,
|
||||
PIN_DEV_RESERVED,
|
||||
PIN_DEV_OTHER
|
||||
};
|
||||
|
||||
|
||||
/* Verb Helper Macro */
|
||||
#define MAKE_VERB(cad, nid, vid, payload) \
|
||||
(((cad) << 28) | ((nid) << 20) | (vid) | (payload))
|
||||
|
||||
/* Verb IDs */
|
||||
#define VID_GET_PARAMETER 0xf0000
|
||||
#define VID_GET_CONNECTION_SELECT 0xf0100
|
||||
#define VID_SET_CONNECTION_SELECT 0x70100
|
||||
#define VID_GET_CONNECTION_LIST_ENTRY 0xf0200
|
||||
#define VID_GET_PROCESSING_STATE 0xf0300
|
||||
#define VID_SET_PROCESSING_STATE 0x70300
|
||||
#define VID_GET_COEFFICIENT_INDEX 0xd0000
|
||||
#define VID_SET_COEFFICIENT_INDEX 0x50000
|
||||
#define VID_GET_PROCESSING_COEFFICIENT 0xc0000
|
||||
#define VID_SET_PROCESSING_COEFFICIENT 0x40000
|
||||
#define VID_GET_AMPLIFIER_GAIN_MUTE 0xb0000
|
||||
#define VID_SET_AMPLIFIER_GAIN_MUTE 0x30000
|
||||
#define VID_GET_CONVERTER_FORMAT 0xa0000
|
||||
#define VID_SET_CONVERTER_FORMAT 0x20000
|
||||
#define VID_GET_CONVERTER_STREAM_CHANNEL 0xf0600
|
||||
#define VID_SET_CONVERTER_STREAM_CHANNEL 0x70600
|
||||
#define VID_GET_DIGITAL_CONVERTER_CONTROL 0xf0d00
|
||||
#define VID_SET_DIGITAL_CONVERTER_CONTROL1 0x70d00
|
||||
#define VID_SET_DIGITAL_CONVERTER_CONTROL2 0x70e00
|
||||
#define VID_GET_POWER_STATE 0xf0500
|
||||
#define VID_SET_POWER_STATE 0x70500
|
||||
#define VID_GET_SDI_SELECT 0xf0400
|
||||
#define VID_SET_SDI_SELECT 0x70400
|
||||
#define VID_GET_PIN_WIDGET_CONTROL 0xf0700
|
||||
#define VID_SET_PIN_WIDGET_CONTROL 0x70700
|
||||
#define VID_GET_UNSOLRESP 0xF0800
|
||||
#define VID_SET_UNSOLRESP 0x70800
|
||||
#define VID_GET_PINSENSE 0xF0900
|
||||
#define VID_SET_PINSENSE 0x70900
|
||||
#define VID_GET_EAPDBTL_EN 0xF0C00
|
||||
#define VID_SET_EAPDBTL_EN 0x70C00
|
||||
#define VID_GET_VOLUME_KNOB_CONTROL 0xF0F00
|
||||
#define VID_SET_VOLUME_KNOB_CONTROL 0x70F00
|
||||
#define VID_GET_GPIDATA 0xF1000
|
||||
#define VID_SET_GPIDATA 0x71000
|
||||
#define VID_GET_GPIWAKE_EN 0xF1100
|
||||
#define VID_SET_GPIWAKE_EN 0x71100
|
||||
#define VID_GET_GPIUNSOL 0xF1200
|
||||
#define VID_SET_GPIUNSOL 0x71200
|
||||
#define VID_GET_GPISTICKY 0xF1300
|
||||
#define VID_SET_GPISTICKY 0x71300
|
||||
#define VID_GET_GPO_DATA 0xF1400
|
||||
#define VID_SET_GPO_DATA 0x71400
|
||||
#define VID_GET_GPIO_DATA 0xF1500
|
||||
#define VID_SET_GPIO_DATA 0x71500
|
||||
#define VID_GET_GPIO_EN 0xF1600
|
||||
#define VID_SET_GPIO_EN 0x71600
|
||||
#define VID_GET_GPIO_DIR 0xF1700
|
||||
#define VID_SET_GPIO_DIR 0x71700
|
||||
#define VID_GET_GPIOWAKE_EN 0xF1800
|
||||
#define VID_SET_GPIOWAKE_EN 0x71800
|
||||
#define VID_GET_GPIOUNSOL_EN 0xF1900
|
||||
#define VID_SET_GPIOUNSOL_EN 0x71900
|
||||
#define VID_GET_GPIOSTICKY 0xF1A00
|
||||
#define VID_SET_GPIOSTICKY 0x71A00
|
||||
#define VID_GET_BEEPGEN 0xF0A00
|
||||
#define VID_SET_BEEPGEN 0x70A00
|
||||
#define VID_GET_VOLUME_KNOB 0xf0f00
|
||||
#define VID_SET_VOLUME_KNOB 0x70f00
|
||||
#define VID_GET_SUBSYSTEMID 0xF2000
|
||||
#define VID_SET_SUBSYSTEMID1 0x72000
|
||||
#define VID_SET_SUBSYSTEMID2 0x72100
|
||||
#define VID_SET_SUBSYSTEMID3 0x72200
|
||||
#define VID_SET_SUBSYSTEMID4 0x72300
|
||||
#define VID_GET_CONFIGURATION_DEFAULT 0xf1c00
|
||||
#define VID_SET_CONFIGURATION_DEFAULT1 0x71c00
|
||||
#define VID_SET_CONFIGURATION_DEFAULT2 0x71d00
|
||||
#define VID_SET_CONFIGURATION_DEFAULT3 0x71e00
|
||||
#define VID_SET_CONFIGURATION_DEFAULT4 0x71f00
|
||||
#define VID_GET_STRIPE_CONTROL 0xf2400
|
||||
#define VID_SET_STRIPE_CONTROL 0x72000
|
||||
#define VID_FUNCTION_RESET 0x7ff00
|
||||
/* later specification updates */
|
||||
#define VID_GET_EDID_LIKE_DATA 0xf2f00
|
||||
#define VID_GET_CONVERTER_CHANNEL_COUNT 0xf2d00
|
||||
#define VID_SET_CONVERTER_CHANNEL_COUNT 0x72d00
|
||||
#define VID_GET_DATA_ISLAND_PACKET_SIZE 0xf2e00
|
||||
#define VID_GET_DATA_ISLAND_PACKET_INDEX 0xf3000
|
||||
#define VID_SET_DATA_ISLAND_PACKET_INDEX 0x73000
|
||||
#define VID_GET_DATA_ISLAND_PACKET_DATA 0xf3100
|
||||
#define VID_SET_DATA_ISLAND_PACKET_DATA 0x73100
|
||||
#define VID_GET_DATA_ISLAND_PACKET_XMITCTRL 0xf3200
|
||||
#define VID_SET_DATA_ISLAND_PACKET_XMITCTRL 0x73200
|
||||
#define VID_GET_CONTENT_PROTECTION_CONTROL 0xf3300
|
||||
#define VID_SET_CONTENT_PROTECTION_CONTROL 0x73300
|
||||
#define VID_GET_ASP_CHANNEL_MAPPING 0xf3400
|
||||
#define VID_SET_ASP_CHANNEL_MAPPING 0x73400
|
||||
|
||||
/* Parameter IDs */
|
||||
#define PID_VENDOR_ID 0x00
|
||||
#define PID_REVISION_ID 0x02
|
||||
#define PID_SUB_NODE_COUNT 0x04
|
||||
#define PID_FUNCTION_GROUP_TYPE 0x05
|
||||
#define PID_AUDIO_GROUP_CAP 0x08
|
||||
#define PID_AUDIO_WIDGET_CAP 0x09
|
||||
#define PID_PCM_SUPPORT 0x0a
|
||||
#define PID_STREAM_SUPPORT 0x0b
|
||||
#define PID_PIN_CAP 0x0c
|
||||
#define PID_INPUT_AMPLIFIER_CAP 0x0d
|
||||
#define PID_CONNECTION_LIST_LENGTH 0x0e
|
||||
#define PID_POWERSTATE_SUPPORT 0x0f
|
||||
#define PID_PROCESSING_CAP 0x10
|
||||
#define PID_GPIO_COUNT 0x11
|
||||
#define PID_OUTPUT_AMPLIFIER_CAP 0x12
|
||||
#define PID_VOLUME_KNOB_CAP 0x13
|
||||
|
||||
/* Subordinate node count */
|
||||
#define SUB_NODE_COUNT_TOTAL_MASK 0x000000ff
|
||||
#define SUB_NODE_COUNT_TOTAL_SHIFT 0
|
||||
#define SUB_NODE_COUNT_START_MASK 0x00ff0000
|
||||
#define SUB_NODE_COUNT_START_SHIFT 16
|
||||
|
||||
#define SUB_NODE_COUNT_TOTAL(c) ((c & SUB_NODE_COUNT_TOTAL_MASK) \
|
||||
>> SUB_NODE_COUNT_TOTAL_SHIFT)
|
||||
#define SUB_NODE_COUNT_START(c) ((c & SUB_NODE_COUNT_START_MASK) \
|
||||
>> SUB_NODE_COUNT_START_SHIFT)
|
||||
|
||||
/* Function group type */
|
||||
#define FUNCTION_GROUP_NODETYPE_MASK 0x000000ff
|
||||
#define FUNCTION_GROUP_UNSOLCAPABLE_MASK 0x00000100
|
||||
|
||||
#define FUNCTION_GROUP_NODETYPE_AUDIO 0x00000001
|
||||
#define FUNCTION_GROUP_NODETYPE_MODEM 0x00000002
|
||||
|
||||
/* Audio Function group capabilities */
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY_MASK 0x0000000f
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY_SHIFT 0
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY_MASK 0x00000f00
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY_SHIFT 8
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN_MASK 0x00010000
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN_SHIFT 16
|
||||
|
||||
#define AUDIO_GROUP_CAP_OUTPUT_DELAY(c) ((c & AUDIO_GROUP_CAP_OUTPUT_DELAY_MASK) \
|
||||
>> AUDIO_GROUP_CAP_OUTPUT_DELAY_SHIFT)
|
||||
#define AUDIO_GROUP_CAP_INPUT_DELAY(c) ((c & AUDIO_GROUP_CAP_INPUT_DELAY_MASK) \
|
||||
>> AUDIO_GROUP_CAP_INPUT_DELAY_SHIFT)
|
||||
#define AUDIO_GROUP_CAP_BEEPGEN(c) ((c & AUDIO_GROUP_CAP_BEEPGEN_MASK) \
|
||||
>> AUDIO_GROUP_CAP_BEEPGEN_SHIFT)
|
||||
|
||||
|
||||
/* Audio widget capabilities */
|
||||
#define AUDIO_CAP_CHANNEL_COUNT_MASK 0x0000e000
|
||||
#define AUDIO_CAP_CHANNEL_COUNT_SHIFT 13
|
||||
#define AUDIO_CAP_DELAY_MASK 0x000f0000
|
||||
#define AUDIO_CAP_DELAY_SHIFT 16
|
||||
#define AUDIO_CAP_TYPE_MASK 0x00f00000
|
||||
#define AUDIO_CAP_TYPE_SHIFT 20
|
||||
|
||||
#define AUDIO_CAP_STEREO (1L << 0)
|
||||
#define AUDIO_CAP_INPUT_AMPLIFIER (1L << 1)
|
||||
#define AUDIO_CAP_OUTPUT_AMPLIFIER (1L << 2)
|
||||
#define AUDIO_CAP_AMPLIFIER_OVERRIDE (1L << 3)
|
||||
#define AUDIO_CAP_FORMAT_OVERRIDE (1L << 4)
|
||||
#define AUDIO_CAP_STRIPE (1L << 5)
|
||||
#define AUDIO_CAP_PROCESSING_CONTROLS (1L << 6)
|
||||
#define AUDIO_CAP_UNSOLICITED_RESPONSES (1L << 7)
|
||||
#define AUDIO_CAP_CONNECTION_LIST (1L << 8)
|
||||
#define AUDIO_CAP_DIGITAL (1L << 9)
|
||||
#define AUDIO_CAP_POWER_CONTROL (1L << 10)
|
||||
#define AUDIO_CAP_LEFT_RIGHT_SWAP (1L << 11)
|
||||
#define AUDIO_CAP_CP_CAPS (1L << 12)
|
||||
|
||||
#define AUDIO_CAP_CHANNEL_COUNT(c) \
|
||||
(((c & AUDIO_CAP_CHANNEL_COUNT_MASK) >> (AUDIO_CAP_CHANNEL_COUNT_SHIFT - 1)) \
|
||||
| AUDIO_CAP_STEREO)
|
||||
|
||||
/* Amplifier capabilities */
|
||||
#define AMP_CAP_MUTE 0xf0000000
|
||||
#define AMP_CAP_STEP_SIZE_MASK 0x007f0000
|
||||
#define AMP_CAP_STEP_SIZE_SHIFT 16
|
||||
#define AMP_CAP_NUM_STEPS_MASK 0x00007f00
|
||||
#define AMP_CAP_NUM_STEPS_SHIFT 8
|
||||
#define AMP_CAP_OFFSET_MASK 0x0000007f
|
||||
|
||||
#define AMP_CAP_STEP_SIZE(c) ((((c & AMP_CAP_STEP_SIZE_MASK) \
|
||||
>> AMP_CAP_STEP_SIZE_SHIFT) + 1) / 4.0)
|
||||
#define AMP_CAP_NUM_STEPS(c) ((c & AMP_CAP_NUM_STEPS_MASK) \
|
||||
>> AMP_CAP_NUM_STEPS_SHIFT)
|
||||
#define AMP_CAP_OFFSET(c) (c & AMP_CAP_OFFSET_MASK)
|
||||
|
||||
/* Pin capabilities */
|
||||
#define PIN_CAP_IMP_SENSE (1L << 0)
|
||||
#define PIN_CAP_TRIGGER_REQ (1L << 1)
|
||||
#define PIN_CAP_PRES_DETECT (1L << 2)
|
||||
#define PIN_CAP_HP_DRIVE (1L << 3)
|
||||
#define PIN_CAP_OUTPUT (1L << 4)
|
||||
#define PIN_CAP_INPUT (1L << 5)
|
||||
#define PIN_CAP_BALANCE (1L << 6)
|
||||
#define PIN_CAP_HDMI (1L << 7)
|
||||
#define PIN_CAP_VREF_CTRL_HIZ (1L << 8)
|
||||
#define PIN_CAP_VREF_CTRL_50 (1L << 9)
|
||||
#define PIN_CAP_VREF_CTRL_GROUND (1L << 10)
|
||||
#define PIN_CAP_VREF_CTRL_80 (1L << 12)
|
||||
#define PIN_CAP_VREF_CTRL_100 (1L << 13)
|
||||
#define PIN_CAP_EAPD_CAP (1L << 16)
|
||||
#define PIN_CAP_DP (1L << 24)
|
||||
#define PIN_CAP_HBR (1L << 27)
|
||||
|
||||
#define PIN_CAP_IS_PRES_DETECT_CAP(c) ((c & PIN_CAP_PRES_DETECT) != 0)
|
||||
#define PIN_CAP_IS_OUTPUT(c) ((c & PIN_CAP_OUTPUT) != 0)
|
||||
#define PIN_CAP_IS_INPUT(c) ((c & PIN_CAP_INPUT) != 0)
|
||||
#define PIN_CAP_IS_BALANCE(c) ((c & PIN_CAP_BALANCE) != 0)
|
||||
#define PIN_CAP_IS_HDMI(c) ((c & PIN_CAP_HDMI) != 0)
|
||||
#define PIN_CAP_IS_VREF_CTRL_50_CAP(c) ((c & PIN_CAP_VREF_CTRL_50) != 0)
|
||||
#define PIN_CAP_IS_VREF_CTRL_80_CAP(c) ((c & PIN_CAP_VREF_CTRL_80) != 0)
|
||||
#define PIN_CAP_IS_VREF_CTRL_100_CAP(c) ((c & PIN_CAP_VREF_CTRL_100) != 0)
|
||||
#define PIN_CAP_IS_EAPD_CAP(c) ((c & PIN_CAP_EAPD_CAP) != 0)
|
||||
#define PIN_CAP_IS_DP(c) ((c & PIN_CAP_DP) != 0)
|
||||
#define PIN_CAP_IS_HBR(c) ((c & PIN_CAP_HBR) != 0)
|
||||
|
||||
/* PCM support */
|
||||
#define PCM_8_BIT (1L << 16)
|
||||
#define PCM_16_BIT (1L << 17)
|
||||
#define PCM_20_BIT (1L << 18)
|
||||
#define PCM_24_BIT (1L << 19)
|
||||
#define PCM_32_BIT (1L << 20)
|
||||
|
||||
/* stream support */
|
||||
#define STREAM_AC3 0x00000004
|
||||
#define STREAM_FLOAT 0x00000002
|
||||
#define STREAM_PCM 0x00000001
|
||||
|
||||
/* Amplifier Gain/Mute */
|
||||
#define AMP_GET_OUTPUT (1L << 15)
|
||||
#define AMP_GET_INPUT (0L << 15)
|
||||
#define AMP_GET_LEFT_CHANNEL (1L << 13)
|
||||
#define AMP_GET_RIGHT_CHANNEL (0L << 13)
|
||||
#define AMP_GET_INPUT_INDEX_MASK 0x0000000f
|
||||
#define AMP_GET_INPUT_INDEX_SHIFT 0
|
||||
|
||||
#define AMP_GET_INPUT_INDEX(x) ((x << AMP_GET_INPUT_INDEX_SHIFT) & AMP_GET_INPUT_INDEX_MASK)
|
||||
|
||||
#define AMP_SET_OUTPUT (1L << 15)
|
||||
#define AMP_SET_INPUT (1L << 14)
|
||||
#define AMP_SET_LEFT_CHANNEL (1L << 13)
|
||||
#define AMP_SET_RIGHT_CHANNEL (1L << 12)
|
||||
#define AMP_SET_INPUT_INDEX_MASK 0x00000f00
|
||||
#define AMP_SET_INPUT_INDEX_SHIFT 8
|
||||
|
||||
#define AMP_SET_INPUT_INDEX(x) ((x << AMP_SET_INPUT_INDEX_SHIFT) & AMP_SET_INPUT_INDEX_MASK)
|
||||
|
||||
#define AMP_GAIN_MASK 0x0000007f
|
||||
#define AMP_MUTE (1L << 7)
|
||||
|
||||
/* Pin Widget Control */
|
||||
#define PIN_ENABLE_HEAD_PHONE (1L << 7)
|
||||
#define PIN_ENABLE_OUTPUT (1L << 6)
|
||||
#define PIN_ENABLE_INPUT (1L << 5)
|
||||
#define PIN_ENABLE_VREF_HIZ 0
|
||||
#define PIN_ENABLE_VREF_50 1
|
||||
#define PIN_ENABLE_VREF_GROUND 2
|
||||
#define PIN_ENABLE_VREF_80 4
|
||||
#define PIN_ENABLE_VREF_100 5
|
||||
|
||||
/* Unsolicited Response */
|
||||
#define UNSOLRESP_ENABLE (1L << 7)
|
||||
#define UNSOLRESP_TAG_MASK 0x0000003f
|
||||
#define UNSOLRESP_TAG_SHIFT 0
|
||||
|
||||
/* Pin sense */
|
||||
#define PIN_SENSE_PRESENCE_DETECT (1L << 31)
|
||||
#define PIN_SENSE_ELD_VALID (1L << 30)
|
||||
#define PIN_SENSE_IMPEDANCE_MASK 0x7fffffff
|
||||
#define PIN_SENSE_IMPEDANCE_SHIFT 0
|
||||
|
||||
#define PIN_SENSE_IMPEDANCE_INVALID 0x7fffffff
|
||||
#define PIN_SENSE_SET_CHANNEL_LEFT 0
|
||||
#define PIN_SENSE_SET_CHANNEL_RIGHT 1
|
||||
|
||||
/* Supported power states */
|
||||
#define POWER_STATE_D0 (1L << 0)
|
||||
#define POWER_STATE_D1 (1L << 1)
|
||||
#define POWER_STATE_D2 (1L << 2)
|
||||
#define POWER_STATE_D3 (1L << 3)
|
||||
#define POWER_STATE_D3COLD (1L << 4)
|
||||
#define POWER_STATE_S3D3COLD (1L << 29)
|
||||
#define POWER_STATE_CLKSTOP (1L << 30)
|
||||
#define POWER_STATE_EPSS (1L << 31)
|
||||
|
||||
/* Configuration default */
|
||||
#define CONF_DEFAULT_SEQUENCE_MASK 0x0000000f
|
||||
#define CONF_DEFAULT_SEQUENCE_SHIFT 0
|
||||
#define CONF_DEFAULT_ASSOCIATION_MASK 0x000000f0
|
||||
#define CONF_DEFAULT_ASSOCIATION_SHIFT 4
|
||||
#define CONF_DEFAULT_MISC_MASK 0x00000f00
|
||||
#define CONF_DEFAULT_MISC_SHIFT 8
|
||||
#define CONF_DEFAULT_COLOR_MASK 0x0000f000
|
||||
#define CONF_DEFAULT_COLOR_SHIFT 12
|
||||
#define CONF_DEFAULT_CONNTYPE_MASK 0x000f0000
|
||||
#define CONF_DEFAULT_CONNTYPE_SHIFT 16
|
||||
#define CONF_DEFAULT_DEVICE_MASK 0x00f00000
|
||||
#define CONF_DEFAULT_DEVICE_SHIFT 20
|
||||
#define CONF_DEFAULT_LOCATION_MASK 0x3f000000
|
||||
#define CONF_DEFAULT_LOCATION_SHIFT 24
|
||||
#define CONF_DEFAULT_CONNECTIVITY_MASK 0xc0000000
|
||||
#define CONF_DEFAULT_CONNECTIVITY_SHIFT 30
|
||||
|
||||
#define CONF_DEFAULT_SEQUENCE(c) ((c & CONF_DEFAULT_SEQUENCE_MASK) >> CONF_DEFAULT_SEQUENCE_SHIFT)
|
||||
#define CONF_DEFAULT_ASSOCIATION(c) ((c & CONF_DEFAULT_ASSOCIATION_MASK) >> CONF_DEFAULT_ASSOCIATION_SHIFT)
|
||||
#define CONF_DEFAULT_MISC(c) ((c & CONF_DEFAULT_MISC_MASK) >> CONF_DEFAULT_MISC_SHIFT)
|
||||
#define CONF_DEFAULT_COLOR(c) ((c & CONF_DEFAULT_COLOR_MASK) >> CONF_DEFAULT_COLOR_SHIFT)
|
||||
#define CONF_DEFAULT_CONNTYPE(c) ((c & CONF_DEFAULT_CONNTYPE_MASK) >> CONF_DEFAULT_CONNTYPE_SHIFT)
|
||||
#define CONF_DEFAULT_DEVICE(c) ((c & CONF_DEFAULT_DEVICE_MASK) >> CONF_DEFAULT_DEVICE_SHIFT)
|
||||
#define CONF_DEFAULT_LOCATION(c) ((c & CONF_DEFAULT_LOCATION_MASK) >> CONF_DEFAULT_LOCATION_SHIFT)
|
||||
#define CONF_DEFAULT_CONNECTIVITY(c) ((c & CONF_DEFAULT_CONNECTIVITY_MASK) >> CONF_DEFAULT_CONNECTIVITY_SHIFT)
|
||||
|
||||
/* EAPD/BTL enable */
|
||||
#define EAPDBTL_ENABLE_BTL 0x1
|
||||
#define EAPDBTL_ENABLE_EAPD 0x2
|
||||
#define EAPDBTL_ENABLE_LRSWAP 0x4
|
||||
|
||||
/* GP I/O count */
|
||||
#define GPIO_COUNT_NUM_GPIO_MASK 0x000000ff
|
||||
#define GPIO_COUNT_NUM_GPIO_SHIFT 0
|
||||
#define GPIO_COUNT_NUM_GPO_MASK 0x0000ff00
|
||||
#define GPIO_COUNT_NUM_GPO_SHIFT 8
|
||||
#define GPIO_COUNT_NUM_GPI_MASK 0x00ff0000
|
||||
#define GPIO_COUNT_NUM_GPI_SHIFT 16
|
||||
#define GPIO_COUNT_GPIUNSOL_MASK 0x40000000
|
||||
#define GPIO_COUNT_GPIUNSOL_SHIFT 30
|
||||
#define GPIO_COUNT_GPIWAKE_MASK 0x80000000
|
||||
#define GPIO_COUNT_GPIWAKE_SHIFT 31
|
||||
|
||||
#define GPIO_COUNT_NUM_GPIO(c) ((c & GPIO_COUNT_NUM_GPIO_MASK) >> GPIO_COUNT_NUM_GPIO_SHIFT)
|
||||
#define GPIO_COUNT_NUM_GPO(c) ((c & GPIO_COUNT_NUM_GPO_MASK) >> GPIO_COUNT_NUM_GPO_SHIFT)
|
||||
#define GPIO_COUNT_NUM_GPI(c) ((c & GPIO_COUNT_NUM_GPI_MASK) >> GPIO_COUNT_NUM_GPI_SHIFT)
|
||||
#define GPIO_COUNT_GPIUNSOL(c) ((c & GPIO_COUNT_GPIUNSOL_MASK) >> GPIO_COUNT_GPIUNSOL_SHIFT)
|
||||
#define GPIO_COUNT_GPIWAKE(c) ((c & GPIO_COUNT_GPIWAKE_MASK) >> GPIO_COUNT_GPIWAKE_SHIFT)
|
||||
|
||||
|
||||
#endif /* HDA_CODEC_H */
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ithamar Adema, ithamar AT unet DOT nl
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef HDAC_REGS_H
|
||||
#define HDAC_REGS_H
|
||||
|
||||
#ifndef __REACTOS__
|
||||
#include <SupportDefs.h>
|
||||
#endif
|
||||
|
||||
/* Controller register definitions */
|
||||
#define HDAC_GLOBAL_CAP 0x00 // 16bits, GCAP
|
||||
#define GLOBAL_CAP_OUTPUT_STREAMS(cap) (((cap) >> 12) & 15)
|
||||
#define GLOBAL_CAP_INPUT_STREAMS(cap) (((cap) >> 8) & 15)
|
||||
#define GLOBAL_CAP_BIDIR_STREAMS(cap) (((cap) >> 3) & 15)
|
||||
#define GLOBAL_CAP_NUM_SDO(cap) ((((cap) >> 1) & 3) ? (cap & 6) : 1)
|
||||
#define GLOBAL_CAP_64BIT(cap) (((cap) & 1) != 0)
|
||||
|
||||
#define HDAC_VERSION_MINOR 0x02 // 8bits, VMIN
|
||||
#define HDAC_VERSION_MAJOR 0x03 // 8bits, VMAJ
|
||||
|
||||
#define HDAC_GLOBAL_CONTROL 0x08 // 32bits, GCTL
|
||||
#define GLOBAL_CONTROL_UNSOLICITED (1 << 8)
|
||||
// accept unsolicited responses
|
||||
#define GLOBAL_CONTROL_FLUSH (1 << 1)
|
||||
#define GLOBAL_CONTROL_RESET (1 << 0)
|
||||
|
||||
#define HDAC_WAKE_ENABLE 0x0c // 16bits, WAKEEN
|
||||
#define HDAC_WAKE_ENABLE_MASK 0x7fff
|
||||
#define HDAC_STATE_STATUS 0x0e // 16bits, STATESTS
|
||||
|
||||
#define HDAC_INTR_CONTROL 0x20 // 32bits, INTCTL
|
||||
#define INTR_CONTROL_GLOBAL_ENABLE (1U << 31)
|
||||
#define INTR_CONTROL_CONTROLLER_ENABLE (1 << 30)
|
||||
|
||||
#define HDAC_INTR_STATUS 0x24 // 32bits, INTSTS
|
||||
#define INTR_STATUS_GLOBAL (1U << 31)
|
||||
#define INTR_STATUS_CONTROLLER (1 << 30)
|
||||
#define INTR_STATUS_STREAM_MASK 0x3fffffff
|
||||
|
||||
#define HDAC_CORB_BASE_LOWER 0x40 // 32bits, CORBLBASE
|
||||
#define HDAC_CORB_BASE_UPPER 0x44 // 32bits, CORBUBASE
|
||||
#define HDAC_CORB_WRITE_POS 0x48 // 16bits, CORBWP
|
||||
#define HDAC_CORB_WRITE_POS_MASK 0xff
|
||||
|
||||
#define HDAC_CORB_READ_POS 0x4a // 16bits, CORBRP
|
||||
#define CORB_READ_POS_RESET (1 << 15)
|
||||
|
||||
#define HDAC_CORB_CONTROL 0x4c // 8bits, CORBCTL
|
||||
#define HDAC_CORB_CONTROL_MASK 0x3
|
||||
#define CORB_CONTROL_RUN (1 << 1)
|
||||
#define CORB_CONTROL_MEMORY_ERROR_INTR (1 << 0)
|
||||
|
||||
#define HDAC_CORB_STATUS 0x4d // 8bits, CORBSTS
|
||||
#define CORB_STATUS_MEMORY_ERROR (1 << 0)
|
||||
|
||||
#define HDAC_CORB_SIZE 0x4e // 8bits, CORBSIZE
|
||||
#define HDAC_CORB_SIZE_MASK 0x3
|
||||
#define CORB_SIZE_CAP_2_ENTRIES (1 << 4)
|
||||
#define CORB_SIZE_CAP_16_ENTRIES (1 << 5)
|
||||
#define CORB_SIZE_CAP_256_ENTRIES (1 << 6)
|
||||
#define CORB_SIZE_2_ENTRIES 0x00 // 8 byte
|
||||
#define CORB_SIZE_16_ENTRIES 0x01 // 64 byte
|
||||
#define CORB_SIZE_256_ENTRIES 0x02 // 1024 byte
|
||||
|
||||
#define HDAC_RIRB_BASE_LOWER 0x50 // 32bits, RIRBLBASE
|
||||
#define HDAC_RIRB_BASE_UPPER 0x54 // 32bits, RIRBUBASE
|
||||
|
||||
#define HDAC_RIRB_WRITE_POS 0x58 // 16bits, RIRBWP
|
||||
#define RIRB_WRITE_POS_RESET (1 << 15)
|
||||
|
||||
#define HDAC_RESPONSE_INTR_COUNT 0x5a // 16bits, RINTCNT
|
||||
#define HDAC_RESPONSE_INTR_COUNT_MASK 0xff
|
||||
|
||||
#define HDAC_RIRB_CONTROL 0x5c // 8bits, RIRBCTL
|
||||
#define HDAC_RIRB_CONTROL_MASK 0x7
|
||||
#define RIRB_CONTROL_OVERRUN_INTR (1 << 2)
|
||||
#define RIRB_CONTROL_DMA_ENABLE (1 << 1)
|
||||
#define RIRB_CONTROL_RESPONSE_INTR (1 << 0)
|
||||
|
||||
#define HDAC_RIRB_STATUS 0x5d // 8bits, RIRBSTS
|
||||
#define RIRB_STATUS_OVERRUN (1 << 2)
|
||||
#define RIRB_STATUS_RESPONSE (1 << 0)
|
||||
|
||||
#define HDAC_RIRB_SIZE 0x5e // 8bits, RIRBSIZE
|
||||
#define HDAC_RIRB_SIZE_MASK 0x3
|
||||
#define RIRB_SIZE_CAP_2_ENTRIES (1 << 4)
|
||||
#define RIRB_SIZE_CAP_16_ENTRIES (1 << 5)
|
||||
#define RIRB_SIZE_CAP_256_ENTRIES (1 << 6)
|
||||
#define RIRB_SIZE_2_ENTRIES 0x00
|
||||
#define RIRB_SIZE_16_ENTRIES 0x01
|
||||
#define RIRB_SIZE_256_ENTRIES 0x02
|
||||
|
||||
#define HDAC_DMA_POSITION_BASE_LOWER 0x70 // 32bits, DPLBASE
|
||||
#define HDAC_DMA_POSITION_BASE_UPPER 0x74 // 32bits, DPUBASE
|
||||
#define DMA_POSITION_ENABLED 1
|
||||
|
||||
/* Stream Descriptor Registers */
|
||||
#define HDAC_STREAM_BASE 0x80
|
||||
#define HDAC_STREAM_SIZE 0x20
|
||||
|
||||
#define HDAC_STREAM_CONTROL0 0x00 // 8bits, CTL0
|
||||
#define CONTROL0_RESET (1 << 0)
|
||||
#define CONTROL0_RUN (1 << 1)
|
||||
#define CONTROL0_BUFFER_COMPLETED_INTR (1 << 2)
|
||||
#define CONTROL0_FIFO_ERROR_INTR (1 << 3)
|
||||
#define CONTROL0_DESCRIPTOR_ERROR_INTR (1 << 4)
|
||||
#define HDAC_STREAM_CONTROL1 0x01 // 8bits, CTL1
|
||||
#define HDAC_STREAM_CONTROL2 0x02 // 8bits, CTL2
|
||||
#define CONTROL2_STREAM_MASK 0xf0
|
||||
#define CONTROL2_STREAM_SHIFT 4
|
||||
#define CONTROL2_BIDIR (1 << 3)
|
||||
#define CONTROL2_TRAFFIC_PRIORITY (1 << 2)
|
||||
#define CONTROL2_STRIPE_SDO_MASK 0x03
|
||||
#define HDAC_STREAM_STATUS 0x03 // 8bits, STS
|
||||
#define STATUS_BUFFER_COMPLETED (1 << 2)
|
||||
#define STATUS_FIFO_ERROR (1 << 3)
|
||||
#define STATUS_DESCRIPTOR_ERROR (1 << 4)
|
||||
#define STATUS_FIFO_READY (1 << 5)
|
||||
#define HDAC_STREAM_POSITION 0x04 // 32bits, LPIB
|
||||
#define HDAC_STREAM_BUFFER_SIZE 0x08 // 32bits, CBL
|
||||
#define HDAC_STREAM_LAST_VALID 0x0c // 16bits, LVI
|
||||
#define HDAC_STREAM_FIFO_SIZE 0x10 // 16bits, FIFOS
|
||||
#define HDAC_STREAM_FORMAT 0x12 // 16bits, FMT
|
||||
#define FORMAT_8BIT (0 << 4)
|
||||
#define FORMAT_16BIT (1 << 4)
|
||||
#define FORMAT_20BIT (2 << 4)
|
||||
#define FORMAT_24BIT (3 << 4)
|
||||
#define FORMAT_32BIT (4 << 4)
|
||||
#define FORMAT_44_1_BASE_RATE (1 << 14)
|
||||
#define FORMAT_MULTIPLY_RATE_SHIFT 11
|
||||
#define FORMAT_DIVIDE_RATE_SHIFT 8
|
||||
#define HDAC_STREAM_BUFFERS_BASE_LOWER 0x18 // 32bits, BDPL
|
||||
#define HDAC_STREAM_BUFFERS_BASE_UPPER 0x1c // 32bits, BDPU
|
||||
|
||||
/* PCI space register definitions */
|
||||
#define PCI_HDA_TCSEL 0x44
|
||||
#define PCI_HDA_TCSEL_MASK 0xf8
|
||||
|
||||
#define ATI_HDA_MISC_CNTR2 0x42
|
||||
#define ATI_HDA_MISC_CNTR2_MASK 0xf8
|
||||
#define ATI_HDA_ENABLE_SNOOP 0x02
|
||||
#define NVIDIA_HDA_OSTRM_COH 0x4c
|
||||
#define NVIDIA_HDA_ISTRM_COH 0x4d
|
||||
#define NVIDIA_HDA_ENABLE_COHBIT 0x01
|
||||
#define NVIDIA_HDA_TRANSREG 0x4e
|
||||
#define NVIDIA_HDA_TRANSREG_MASK 0xf0
|
||||
#define NVIDIA_HDA_ENABLE_COHBITS 0x0f
|
||||
#define INTEL_SCH_HDA_DEVC 0x78
|
||||
#define INTEL_SCH_HDA_DEVC_SNOOP 0x800
|
||||
|
||||
|
||||
#ifndef __REACTOS__
|
||||
typedef uint32 corb_t;
|
||||
typedef struct {
|
||||
uint32 response;
|
||||
uint32 flags;
|
||||
} rirb_t;
|
||||
#endif
|
||||
|
||||
#define RESPONSE_FLAGS_CODEC_MASK 0x0000000f
|
||||
#define RESPONSE_FLAGS_UNSOLICITED (1 << 4)
|
||||
|
||||
#ifndef __REACTOS__
|
||||
typedef struct {
|
||||
uint32 lower;
|
||||
uint32 upper;
|
||||
uint32 length;
|
||||
uint32 ioc;
|
||||
} bdl_entry_t;
|
||||
#endif
|
||||
|
||||
#endif /* HDAC_REGS_H */
|
||||
@@ -1,320 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel Streaming
|
||||
* FILE: drivers/wdm/audio/hdaudbus/hdaudbus.cpp
|
||||
* PURPOSE: HDA Driver Entry
|
||||
* PROGRAMMER: Johannes Anderwald
|
||||
*/
|
||||
|
||||
#include "hdaudbus.h"
|
||||
|
||||
DRIVER_DISPATCH HDA_Pnp;
|
||||
DRIVER_DISPATCH HDA_SystemControl;
|
||||
DRIVER_DISPATCH HDA_Power;
|
||||
DRIVER_ADD_DEVICE HDA_AddDevice;
|
||||
DRIVER_UNLOAD HDA_Unload;
|
||||
extern "C" DRIVER_INITIALIZE DriverEntry;
|
||||
|
||||
PVOID
|
||||
AllocateItem(
|
||||
_In_ POOL_TYPE PoolType,
|
||||
_In_ SIZE_T NumberOfBytes)
|
||||
{
|
||||
return ExAllocatePoolZero(PoolType, NumberOfBytes, TAG_HDA);
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeItem(
|
||||
__drv_freesMem(Mem) PVOID Item)
|
||||
{
|
||||
ExFreePoolWithTag(Item, TAG_HDA);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_FdoPnp(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
ULONG CodecIndex, AFGIndex;
|
||||
PHDA_CODEC_ENTRY CodecEntry;
|
||||
PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
|
||||
|
||||
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
Status = HDA_FDOStartDevice(DeviceObject, Irp);
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
return HDA_FDORemoveDevice(DeviceObject, Irp);
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
|
||||
{
|
||||
CodecEntry = FDODeviceExtension->Codecs[CodecIndex];
|
||||
|
||||
ASSERT(CodecEntry->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS);
|
||||
for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
|
||||
{
|
||||
ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension);
|
||||
ChildDeviceExtension->ReportedMissing = TRUE;
|
||||
}
|
||||
}
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
/* handle bus device relations */
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
||||
{
|
||||
Status = HDA_FDOQueryBusRelations(DeviceObject, Irp);
|
||||
Irp->IoStatus.Status = Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_PdoPnp(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PDEVICE_RELATIONS DeviceRelation;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
/* no op for pdo */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
Status = HDA_PDORemoveDevice(DeviceObject);
|
||||
break;
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||
/* query bus information */
|
||||
Status = HDA_PDOQueryBusInformation(Irp);
|
||||
break;
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
/* query pnp state */
|
||||
Status = HDA_PDOQueryBusDevicePnpState(Irp);
|
||||
break;
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
|
||||
{
|
||||
/* handle target device relations */
|
||||
ASSERT(Irp->IoStatus.Information == 0);
|
||||
|
||||
/* allocate device relation */
|
||||
DeviceRelation = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
|
||||
if (DeviceRelation)
|
||||
{
|
||||
DeviceRelation->Count = 1;
|
||||
DeviceRelation->Objects[0] = DeviceObject;
|
||||
|
||||
/* reference self */
|
||||
ObReferenceObject(DeviceObject);
|
||||
|
||||
/* store result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
|
||||
|
||||
/* done */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no memory */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
break;
|
||||
case IRP_MN_QUERY_CAPABILITIES:
|
||||
/* query capabilities */
|
||||
Status = HDA_PDOQueryBusDeviceCapabilities(Irp);
|
||||
break;
|
||||
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
|
||||
/* no op */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_QUERY_RESOURCES:
|
||||
/* no op */
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IRP_MN_QUERY_ID:
|
||||
Status = HDA_PDOQueryId(DeviceObject, Irp);
|
||||
break;
|
||||
case IRP_MN_QUERY_DEVICE_TEXT:
|
||||
Status = HDA_PDOHandleQueryDeviceText(Irp);
|
||||
break;
|
||||
case IRP_MN_QUERY_INTERFACE:
|
||||
Status = HDA_PDOHandleQueryInterface(DeviceObject, Irp);
|
||||
break;
|
||||
default:
|
||||
/* get default status */
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_Pnp(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
|
||||
if (FDODeviceExtension->IsFDO)
|
||||
{
|
||||
return HDA_FdoPnp(DeviceObject, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HDA_PdoPnp(DeviceObject, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_SystemControl(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
|
||||
if (FDODeviceExtension->IsFDO)
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(FDODeviceExtension->LowerDevice, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Irp->IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_Power(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
|
||||
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
|
||||
if (FDODeviceExtension->IsFDO)
|
||||
{
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(FDODeviceExtension->LowerDevice, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Irp->IoStatus.Status;
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_AddDevice(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* create device object */
|
||||
Status = IoCreateDevice(DriverObject, sizeof(HDA_FDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* get device extension*/
|
||||
DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* init device extension*/
|
||||
DeviceExtension->IsFDO = TRUE;
|
||||
DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
|
||||
IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr);
|
||||
RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS + 1));
|
||||
|
||||
/* set device flags */
|
||||
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HDA_Unload(
|
||||
_In_ PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPathName)
|
||||
{
|
||||
DriverObject->DriverUnload = HDA_Unload;
|
||||
DriverObject->DriverExtension->AddDevice = HDA_AddDevice;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = HDA_Power;
|
||||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HDA_SystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = HDA_Pnp;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -1,180 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <initguid.h>
|
||||
#include <hdaudio.h>
|
||||
#include <stdio.h>
|
||||
#include <ntstrsafe.h>
|
||||
|
||||
// Include Haiku headers
|
||||
#include "driver.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define TAG_HDA 'bADH'
|
||||
|
||||
#define MAKE_RATE(base, multiply, divide) \
|
||||
((base == 44100 ? FORMAT_44_1_BASE_RATE : 0) \
|
||||
| ((multiply - 1) << FORMAT_MULTIPLY_RATE_SHIFT) \
|
||||
| ((divide - 1) << FORMAT_DIVIDE_RATE_SHIFT))
|
||||
|
||||
#define HDAC_INPUT_STREAM_OFFSET(index) \
|
||||
((index) * HDAC_STREAM_SIZE)
|
||||
#define HDAC_OUTPUT_STREAM_OFFSET(num_input_streams, index) \
|
||||
((num_input_streams + (index)) * HDAC_STREAM_SIZE)
|
||||
#define HDAC_BIDIR_STREAM_OFFSET(num_input_streams, num_output_streams, index) \
|
||||
((num_input_streams + num_output_streams \
|
||||
+ (index)) * HDAC_STREAM_SIZE)
|
||||
|
||||
#define ALIGN(size, align) (((size) + align - 1) & ~(align - 1))
|
||||
|
||||
typedef struct {
|
||||
ULONG response;
|
||||
ULONG flags;
|
||||
}RIRB_RESPONSE, *PRIRB_RESPONSE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PDEVICE_OBJECT ChildPDO;
|
||||
ULONG FunctionGroup;
|
||||
ULONG NodeId;
|
||||
}HDA_CODEC_AUDIO_GROUP, *PHDA_CODEC_AUDIO_GROUP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
USHORT VendorId;
|
||||
USHORT ProductId;
|
||||
UCHAR Major;
|
||||
UCHAR Minor;
|
||||
UCHAR Revision;
|
||||
UCHAR Stepping;
|
||||
UCHAR Addr;
|
||||
|
||||
ULONG Responses[MAX_CODEC_RESPONSES];
|
||||
ULONG ResponseCount;
|
||||
KSEMAPHORE ResponseSemaphore;
|
||||
|
||||
PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS];
|
||||
ULONG AudioGroupCount;
|
||||
|
||||
}HDA_CODEC_ENTRY, *PHDA_CODEC_ENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
|
||||
PUCHAR RegBase;
|
||||
SIZE_T RegLength;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
ULONG CorbLength;
|
||||
PULONG CorbBase;
|
||||
ULONG RirbLength;
|
||||
PRIRB_RESPONSE RirbBase;
|
||||
ULONG RirbReadPos;
|
||||
ULONG CorbWritePos;
|
||||
PVOID StreamPositions;
|
||||
|
||||
PHDA_CODEC_ENTRY Codecs[HDA_MAX_CODECS + 1];
|
||||
|
||||
}HDA_FDO_DEVICE_EXTENSION, *PHDA_FDO_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
BOOLEAN ReportedMissing;
|
||||
PHDA_CODEC_ENTRY Codec;
|
||||
PHDA_CODEC_AUDIO_GROUP AudioGroup;
|
||||
PDEVICE_OBJECT FDO;
|
||||
}HDA_PDO_DEVICE_EXTENSION, *PHDA_PDO_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct {
|
||||
ULONG device : 16;
|
||||
ULONG vendor : 16;
|
||||
ULONG stepping : 8;
|
||||
ULONG revision : 8;
|
||||
ULONG minor : 4;
|
||||
ULONG major : 4;
|
||||
ULONG _reserved0 : 8;
|
||||
ULONG count : 8;
|
||||
ULONG _reserved1 : 8;
|
||||
ULONG start : 8;
|
||||
ULONG _reserved2 : 8;
|
||||
}CODEC_RESPONSE, *PCODEC_RESPONSE;
|
||||
|
||||
PVOID
|
||||
AllocateItem(
|
||||
IN POOL_TYPE PoolType,
|
||||
IN SIZE_T NumberOfBytes);
|
||||
|
||||
VOID
|
||||
FreeItem(
|
||||
IN PVOID Item);
|
||||
|
||||
/* fdo.cpp */
|
||||
|
||||
KSERVICE_ROUTINE HDA_InterruptService;
|
||||
IO_DPC_ROUTINE HDA_DpcForIsr;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDOStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDORemoveDevice(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_FDOQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
HDA_SendVerbs(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PHDA_CODEC_ENTRY Codec,
|
||||
IN PULONG Verbs,
|
||||
OUT PULONG Responses,
|
||||
IN ULONG Count);
|
||||
|
||||
/* pdo.cpp*/
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDORemoveDevice(
|
||||
_In_ PDEVICE_OBJECT DeviceObject);
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusInformation(
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_PDOQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOHandleQueryDeviceText(
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusDeviceCapabilities(
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusDevicePnpState(
|
||||
IN PIRP Irp);
|
||||
|
||||
/* businterface.cpp */
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOHandleQueryInterface(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
@@ -1,112 +0,0 @@
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = System
|
||||
ClassGuid = {4D36E97D-E325-11CE-BFC1-08002BE10318}
|
||||
Provider = ReactOS
|
||||
DriverVer=11/19/2010,6.1.7601.17514
|
||||
PnPLockdown=1
|
||||
|
||||
[SourceDisksFiles]
|
||||
hdaudbus.sys = 3426
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 12 ; windows\system32\drivers
|
||||
|
||||
[Manufacturer]
|
||||
Microsoft = GenericMfg
|
||||
|
||||
[ControlFlags]
|
||||
ExcludeFromSelect = PCI\CC_0403
|
||||
;ExcludeFromSelect = PCI\VEN_8086&DEV_2668
|
||||
|
||||
[GenericMfg]
|
||||
%HDAudio.DeviceDesc% = HDAudio_Device, PCI\CC_0403
|
||||
%HDAudio.DeviceDesc% = HDAudio_Device, PCI\VEN_8086&DEV_2668
|
||||
|
||||
[HDAudio_Device.NT]
|
||||
CopyFiles = Drivers_Dir
|
||||
AddReg = HDAudio.AddReg
|
||||
|
||||
[Drivers_Dir]
|
||||
hdaudbus.sys,,,0x0100
|
||||
|
||||
[HDAudio.AddReg]
|
||||
HKR,Settings,DeviceDescription_FUNC_01,,%AUDIOFG%
|
||||
HKR,Settings,DeviceDescription_FUNC_02,,%MODEMFG%
|
||||
HKR,Settings,DeviceDescription_Default,,%UNKNOWNFG%
|
||||
HKR,Settings,DeviceLocation,,%HDAudioBUS%
|
||||
HKR,Interrupt Management,,0x00000010
|
||||
HKR,Interrupt Management\MessageSignaledInterruptProperties,,0x00000010
|
||||
HKR,Interrupt Management\MessageSignaledInterruptProperties,MSISupported,0x00010001,1
|
||||
|
||||
;-------------- Service installation
|
||||
[HDAudio_Device.NT.Services]
|
||||
AddService = HDAudBus, 0x00000002, HDAudio_Service_Inst
|
||||
|
||||
; -------------- HDAudio driver install sections
|
||||
[HDAudio_Service_Inst]
|
||||
DisplayName = %HDAudBus.SVCDESC%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\HDAudBus.sys
|
||||
LoadOrderGroup = Extended Base
|
||||
|
||||
[SignatureAttributes]
|
||||
hdaudbus.sys=SignatureAttributes.DRM
|
||||
|
||||
[SignatureAttributes.DRM]
|
||||
DRMLevel=1300
|
||||
|
||||
[Strings]
|
||||
DiskId1 = "ReactOS UAA Bus Driver for High Definition Audio. Installation Disk #1"
|
||||
HDAudio.DeviceDesc = "High Definition Audio Controller"
|
||||
HDAudBus.SVCDESC = "ReactOS UAA Bus Driver for High Definition Audio"
|
||||
AUDIOFG = "Audio Device on High Definition Audio Bus"
|
||||
MODEMFG = "Modem Device on High Definition Audio Bus"
|
||||
UNKNOWNFG = "Unknown Device on High Definition Audio Bus"
|
||||
HDAudioBUS = "Internal High Definition Audio Bus"
|
||||
|
||||
[Strings.0415]
|
||||
DiskId1 = "Sterownik magistrali ReactOS UAA dla High Definition Audio. Dysk instalacyjny #1"
|
||||
HDAudio.DeviceDesc = "Kontroler High Definition Audio"
|
||||
HDAudBus.SVCDESC = "Sterownik magistrali ReactOS UAA dla High Definition Audio."
|
||||
AUDIOFG = "Urządzenie audio na High Definition Audio Bus"
|
||||
MODEMFG = "Urządzenie telefoniczne na High Definition Audio Bus"
|
||||
UNKNOWNFG = "Nieznane urządzenie na High Definition Audio Bus"
|
||||
HDAudioBUS = "Wewnętrzna magistrala High Definition Audio"
|
||||
|
||||
[Strings.0418]
|
||||
DiskId1 = "Driver ReactOS de magistrală UAA pentru dispozitive audio de înaltă definiție. Disc de instalare №1"
|
||||
HDAudio.DeviceDesc = "Dispozitiv de control audio de înaltă definiție"
|
||||
HDAudBus.SVCDESC = "Driver ReactOS pentru magistrală UAA pentru dispozitive audio de înaltă definiție"
|
||||
AUDIOFG = "Dispozitiv audio pe magistrala audio de înaltă definiție"
|
||||
MODEMFG = "Dispozitiv modem pe magistrala audio de înaltă definiție"
|
||||
UNKNOWNFG = "Dispozitiv nespecificat pe magistrala audio de înaltă definiție"
|
||||
HDAudioBUS = "Magistrală internă audio de înaltă definiție"
|
||||
|
||||
[Strings.041f]
|
||||
DiskId1 = "Yüksek Tanımlı Ses İçin ReactOS UAA Veri Yolu Sürücüsü. 1. Kurulum Diski"
|
||||
HDAudio.DeviceDesc = "Yüksek Tanımlı Ses Denetleyicisi"
|
||||
HDAudBus.SVCDESC = "Yüksek Tanımlı Ses için ReactOS UAA Veri Yolu Sürücüsü"
|
||||
AUDIOFG = "Yüksek Tanımlı Ses Veri Yolu Üzerinde Ses Aygıtı"
|
||||
MODEMFG = "Yüksek Tanımlı Ses Veri Yolu Üzerinde Çevirge Aygıtı"
|
||||
UNKNOWNFG = "Yüksek Tanımlı Ses Veri Yolu Üzerinde Bilinmeyen Aygıt"
|
||||
HDAudioBUS = "İç Yüksek Tanımlı Ses Veri Yolu"
|
||||
|
||||
[Strings.0804]
|
||||
HDAudio.DeviceDesc = "高保真音频控制器"
|
||||
HDAudBus.SVCDESC = "ReactOS 高保真音频 UAA 总线驱动"
|
||||
AUDIOFG = "HDA 总线上的音频设备"
|
||||
MODEMFG = "HDA 总线上的 Modem 设备"
|
||||
UNKNOWNFG = "HDA 总线上的未知设备"
|
||||
HDAudioBUS = "内部 HDA 总线"
|
||||
|
||||
[Strings.0a]
|
||||
DiskId1 = "Driver Bus UAA de ReactOS para Audio de Alta Fidelidad. Disco de instalación 1"
|
||||
HDAudio.DeviceDesc = "Controlador de Audio de Alta Fidelidad"
|
||||
HDAudBus.SVCDESC = "Driver Bus UAA de ReactOS para Audio de Alta Fidelidad"
|
||||
AUDIOFG = "Dispositivo de Audio en el Bus de Audio de Alta Fidelidad"
|
||||
MODEMFG = "Dispositivo Modem en el Bus de Audio de Alta Fidelidad"
|
||||
UNKNOWNFG = "Dispositivo desconocido en el Bus de Audio de Alta Fidelidad"
|
||||
HDAudioBUS = "Bus Interno de Audio de Alta Fidelidad"
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel Streaming
|
||||
* FILE: drivers/wdm/audio/hdaudbus/pdo.cpp
|
||||
* PURPOSE: HDA Driver Entry
|
||||
* PROGRAMMER: Johannes Anderwald
|
||||
*/
|
||||
#include "hdaudbus.h"
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDORemoveDevice(
|
||||
_In_ PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
|
||||
ASSERT(DeviceExtension->IsFDO == FALSE);
|
||||
|
||||
if (DeviceExtension->ReportedMissing)
|
||||
{
|
||||
if (DeviceExtension->AudioGroup != NULL)
|
||||
{
|
||||
DeviceExtension->AudioGroup->ChildPDO = NULL;
|
||||
}
|
||||
IoDeleteDevice(DeviceObject);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusInformation(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PPNP_BUS_INFORMATION BusInformation;
|
||||
|
||||
/* allocate bus information */
|
||||
BusInformation = (PPNP_BUS_INFORMATION)AllocateItem(PagedPool, sizeof(PNP_BUS_INFORMATION));
|
||||
|
||||
if (!BusInformation)
|
||||
{
|
||||
/* no memory */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* return info */
|
||||
BusInformation->BusNumber = 0;
|
||||
BusInformation->LegacyBusType = PCIBus;
|
||||
RtlMoveMemory(&BusInformation->BusTypeGuid, &GUID_HDAUDIO_BUS_INTERFACE, sizeof(GUID));
|
||||
|
||||
/* store result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
|
||||
|
||||
/* done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
HDA_PDOQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
WCHAR DeviceName[200];
|
||||
PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Length;
|
||||
LPWSTR Device;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->IsFDO == FALSE);
|
||||
|
||||
/* get current irp stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
|
||||
{
|
||||
Status = RtlStringCbPrintfW(DeviceName,
|
||||
sizeof(DeviceName),
|
||||
L"%02x%02x",
|
||||
DeviceExtension->Codec->Addr,
|
||||
DeviceExtension->AudioGroup->NodeId);
|
||||
NT_ASSERT(NT_SUCCESS(Status));
|
||||
Length = wcslen(DeviceName) + 1;
|
||||
|
||||
/* allocate result buffer*/
|
||||
Device = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
|
||||
if (!Device)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Status = RtlStringCbCopyW(Device,
|
||||
Length * sizeof(WCHAR),
|
||||
DeviceName);
|
||||
NT_ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
DPRINT1("ID: %S\n", Device);
|
||||
/* store result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Device;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID ||
|
||||
IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
|
||||
{
|
||||
|
||||
/* calculate size */
|
||||
swprintf(DeviceName, L"HDAUDIO\\FUNC_%02X&VEN_%04X&DEV_%04X&SUBSYS_%08X", DeviceExtension->AudioGroup->FunctionGroup, DeviceExtension->Codec->VendorId, DeviceExtension->Codec->ProductId, DeviceExtension->Codec->VendorId << 16 | DeviceExtension->Codec->ProductId);
|
||||
Length = wcslen(DeviceName) + 20;
|
||||
|
||||
/* allocate result buffer*/
|
||||
Device = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
|
||||
if (!Device)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
wcscpy(Device, DeviceName);
|
||||
|
||||
DPRINT1("ID: %S\n", Device);
|
||||
/* store result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Device;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
|
||||
{
|
||||
RtlZeroMemory(DeviceName, sizeof(DeviceName));
|
||||
Length = swprintf(DeviceName, L"HDAUDIO\\FUNC_%02X&VEN_%04X&DEV_%04X&REV_%04X", DeviceExtension->AudioGroup->FunctionGroup, DeviceExtension->Codec->VendorId, DeviceExtension->Codec->ProductId, DeviceExtension->Codec->Major << 12 | DeviceExtension->Codec->Minor << 8 | DeviceExtension->Codec->Revision) + 1;
|
||||
Length += swprintf(&DeviceName[Length], L"HDAUDIO\\FUNC_%02X&VEN_%04X&DEV_%04X", DeviceExtension->AudioGroup->FunctionGroup, DeviceExtension->Codec->VendorId, DeviceExtension->Codec->ProductId) + 1;
|
||||
Length += swprintf(&DeviceName[Length], L"HDAUDIO\\FUNC_%02X&VEN_%04X", DeviceExtension->AudioGroup->FunctionGroup, DeviceExtension->Codec->VendorId) + 1;
|
||||
Length += swprintf(&DeviceName[Length], L"HDAUDIO\\FUNC_%02X", DeviceExtension->AudioGroup->FunctionGroup) + 2;
|
||||
|
||||
/* allocate result buffer*/
|
||||
Device = (LPWSTR)AllocateItem(PagedPool, Length * sizeof(WCHAR));
|
||||
if (!Device)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlCopyMemory(Device, DeviceName, Length * sizeof(WCHAR));
|
||||
|
||||
DPRINT1("ID: %S\n", Device);
|
||||
/* store result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Device;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("QueryID Type %x not implemented\n", IoStack->Parameters.QueryId.IdType);
|
||||
return Irp->IoStatus.Status;
|
||||
}
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOHandleQueryDeviceText(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
LPWSTR Buffer;
|
||||
static WCHAR DeviceText[] = L"Audio Device on High Definition Audio Bus";
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
if (IoStack->Parameters.QueryDeviceText.DeviceTextType == DeviceTextDescription)
|
||||
{
|
||||
DPRINT("HDA_PdoHandleQueryDeviceText DeviceTextDescription\n");
|
||||
|
||||
Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
|
||||
if (!Buffer)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
wcscpy(Buffer, DeviceText);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("HDA_PdoHandleQueryDeviceText DeviceTextLocationInformation\n");
|
||||
|
||||
Buffer = (LPWSTR)AllocateItem(PagedPool, sizeof(DeviceText));
|
||||
if (!Buffer)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
wcscpy(Buffer, DeviceText);
|
||||
|
||||
/* save result */
|
||||
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusDeviceCapabilities(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_CAPABILITIES Capabilities;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
/* get stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* get capabilities */
|
||||
Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
|
||||
|
||||
RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
|
||||
|
||||
/* setup capabilities */
|
||||
Capabilities->UniqueID = TRUE;
|
||||
Capabilities->SilentInstall = TRUE;
|
||||
Capabilities->SurpriseRemovalOK = TRUE;
|
||||
Capabilities->Address = 0;
|
||||
Capabilities->UINumber = 0;
|
||||
Capabilities->SystemWake = PowerSystemWorking; /* FIXME common device extension */
|
||||
Capabilities->DeviceWake = PowerDeviceD0;
|
||||
|
||||
/* done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HDA_PDOQueryBusDevicePnpState(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
/* set device flags */
|
||||
Irp->IoStatus.Information = PNP_DEVICE_DONT_DISPLAY_IN_UI | PNP_DEVICE_NOT_DISABLEABLE;
|
||||
|
||||
/* done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user