Added TrueType base and HDA driver

This commit is contained in:
Jozef Nagy 2025-04-20 16:43:59 +02:00
parent aa3f734406
commit 42cc0d9f40
Signed by untrusted user who does not match committer: crz
GPG key ID: 459A4811CEAC7068
30 changed files with 7120 additions and 35 deletions

View file

@ -0,0 +1,688 @@
/*********************************************************************************/
/* Module Name: hda.h */
/* Project: AurixOS */
/* */
/* Copyright (c) 2018-2025, Rafael Rodrigues Machado, Jozef Nagy */
/* All rights reserved. */
/* This program and the accompanying materials are licensed and made available */
/* under the terms and conditions of the BSD License which accompanies */
/* this distribution. The full text of the license may be found at */
/* http://opensource.org/licenses/bsd-license. */
/* */
/* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. */
/*********************************************************************************/
#ifndef _HDA_HDA_H
#define _HDA_HDA_H
#include <stdint.h>
#include <stdbool.h>
// Intel HDA Controller location
#define HDA_BUS 0
#define HDA_DEV 27
#define HDA_FUNC 0
// HDA Spec page 57
#define HDA_BUFFER_DESC_LIST_MAX_ENTRIES 256
// IO-Controller_Hub-7-hd-audio-ac97 manual, page 13
typedef struct {
uint16_t VID;
uint16_t DID;
uint16_t PCICMD;
uint16_t PCISTS;
uint8_t RID;
uint8_t PI;
uint8_t SC;
uint8_t BCC;
uint8_t CLS;
uint8_t LT;
uint8_t HEADTYP;
uint8_t RES0;
uint32_t HDBARL;
uint32_t HDBARU;
uint8_t RESV1[20];
uint16_t SVID;
uint16_t SID;
uint8_t RESV2[4];
uint8_t CAPPTR;
uint8_t RESV3[7];
uint8_t INTLN;
uint8_t INTPN;
uint8_t RESV4[2];
uint8_t HDCTL;
uint8_t RESV5[3];
uint8_t TCSEL;
uint8_t RESV6[8];
uint8_t DCKSTS;
uint8_t RESV7[2];
uint16_t PID;
uint16_t PC;
uint32_t PCS;
uint8_t RESV8[8];
uint16_t MID;
uint16_t MMC;
uint32_t MMLA;
uint32_t MMUA;
uint16_t MMD;
uint8_t RESV9[2];
uint16_t PXID;
uint16_t PXC;
uint32_t DEVCAP;
uint16_t DEVCTL;
uint16_t DEVS;
uint8_t RESV10[132];
uint32_t VCCAP;
uint32_t PVCCAP1;
uint32_t PVCCAP2;
uint16_t PVCCTL;
uint16_t PVCSTS;
uint32_t VC0CAP;
uint32_t VC0CTL;
uint8_t RESV11[2];
uint16_t VC0STS;
uint32_t VciCAP;
uint32_t VciCTL;
uint8_t RESV12[2];
uint16_t VciSTS;
uint8_t RESV13[8];
uint32_t RCCAP;
uint32_t ESD;
uint8_t RESV14[8];
uint32_t L1DESC;
uint8_t RESV15[4];
uint32_t L1ADDL;
uint32_t L1ADDU;
} PCI_HDA_REGION;
// Register offsets defined at HDA PCIe config space
#define HDA_OFFSET_PCIE_VID 0x0
#define HDA_OFFSET_PCIE_DID 0x2
#define HDA_OFFSET_PCIE_PCICMD 0x4
#define HDA_OFFSET_PCIE_PCISTS 0x6
#define HDA_OFFSET_PCIE_RID 0x8
#define HDA_OFFSET_PCIE_PI 0x9
#define HDA_OFFSET_PCIE_SCC 0xA
#define HDA_OFFSET_PCIE_BCC 0xB
#define HDA_OFFSET_PCIE_CLS 0xC
#define HDA_OFFSET_PCIE_LT 0xD
#define HDA_OFFSET_PCIE_HEADTYP 0xE
#define HDA_OFFSET_PCIE_HDBARL 0x10
#define HDA_OFFSET_PCIE_HDBARU 0x14
#define HDA_OFFSET_PCIE_SVID 0x2C
#define HDA_OFFSET_PCIE_SID 0x2E
#define HDA_OFFSET_PCIE_CAPPTR 0x34
#define HDA_OFFSET_PCIE_INTLN 0x3C
#define HDA_OFFSET_PCIE_INTPN 0x3D
#define HDA_OFFSET_PCIE_HDCTL 0x40
#define HDA_OFFSET_PCIE_TCSEL 0x44
#define HDA_OFFSET_PCIE_DCKSTS 0x4D
#define HDA_OFFSET_PCIE_PID 0x50
#define HDA_OFFSET_PCIE_PC 0x52
#define HDA_OFFSET_PCIE_PCS 0x54
#define HDA_OFFSET_PCIE_MID 0x60
#define HDA_OFFSET_PCIE_MMC 0x62
#define HDA_OFFSET_PCIE_MMLA 0x64
#define HDA_OFFSET_PCIE_MMUA 0x68
#define HDA_OFFSET_PCIE_MMD 0x6C
#define HDA_OFFSET_PCIE_PXID 0x70
#define HDA_OFFSET_PCIE_PXC 0x72
#define HDA_OFFSET_PCIE_DEVCAP 0x74
#define HDA_OFFSET_PCIE_DEVCTL 0x78
#define HDA_OFFSET_PCIE_DEVS 0x7A
#define HDA_OFFSET_PCIE_VCCAP 0x100
#define HDA_OFFSET_PCIE_PVCCAP1 0x104
#define HDA_OFFSET_PCIE_PVCCAP2 0x108
#define HDA_OFFSET_PCIE_PVCCTL 0x10C
#define HDA_OFFSET_PCIE_PVCSTS 0x10E
#define HDA_OFFSET_PCIE_VC0CAP 0x110
#define HDA_OFFSET_PCIE_VC0CTL 0x114
#define HDA_OFFSET_PCIE_VC0STS 0x11A
#define HDA_OFFSET_PCIE_VciCAP 0x11C
#define HDA_OFFSET_PCIE_VciCTL 0x120
#define HDA_OFFSET_PCIE_VciSTS 0x126
#define HDA_OFFSET_PCIE_RCCAP 0x130
#define HDA_OFFSET_PCIE_ESD 0x134
#define HDA_OFFSET_PCIE_L1DESC 0x140
#define HDA_OFFSET_PCIE_L1ADDL 0x148
#define HDA_OFFSET_PCIE_L1ADDU 0x14C
/* Offsets of the registers defined at HDA
* compatible controllers.
* Details can be found at the page 27 of the
* HDA Specification Rev 1.0a
*/
// Register offsets defined at HDA compatible controllers
#define HDA_OFFSET_GCAP 0x0
#define HDA_OFFSET_VMIN 0x2
#define HDA_OFFSET_VMAJ 0x3
#define HDA_OFFSET_OUTPAY 0x4
#define HDA_OFFSET_INPAY 0x6
#define HDA_OFFSET_GCTL 0x8
#define HDA_OFFSET_WAKEEN 0x0C
#define HDA_OFFSET_WAKESTS 0x0E
#define HDA_OFFSET_GSTS 0x10
#define HDA_OFFSET_Rsvd 0x12
#define HDA_OFFSET_OUTSTRMPAY 0x18
#define HDA_OFFSET_INSTRMPAY 0x1A
#define HDA_OFFSET_INTCTL 0x20
#define HDA_OFFSET_INTSTS 0x24
#define HDA_OFFSET_WALCLK 0x30
#define HDA_OFFSET_SSYNC 0x38
#define HDA_OFFSET_CORBLBASE 0x40
#define HDA_OFFSET_CORBUBASE 0x44
#define HDA_OFFSET_CORBWP 0x48
#define HDA_OFFSET_CORBRP 0x4A
#define HDA_OFFSET_CORBCTL 0x4C
#define HDA_OFFSET_CORBSTS 0x4D
#define HDA_OFFSET_CORBSIZE 0x4E
#define HDA_OFFSET_RIRBLBASE 0x50
#define HDA_OFFSET_RIRBUBASE 0x54
#define HDA_OFFSET_RIRBWP 0x58
#define HDA_OFFSET_RINTCNT 0x5A
#define HDA_OFFSET_RIRBCTL 0x5C
#define HDA_OFFSET_RIRBSTS 0x5D
#define HDA_OFFSET_RIRBSIZE 0x5E
#define HDA_OFFSET_ICOI 0x60
#define HDA_OFFSET_ICII 0x64
#define HDA_OFFSET_ICIS 0x68
#define HDA_OFFSET_DPIBLBASE 0x70
#define HDA_OFFSET_DPIBUBASE 0x74
#define HDA_OFFSET_SD0CTL 0x80
#define HDA_OFFSET_SD0STS 0x83
#define HDA_OFFSET_SD0LPIB 0x84
#define HDA_OFFSET_SD0CBL 0x88
#define HDA_OFFSET_SD0LVI 0x8C
#define HDA_OFFSET_SD0FIFOS 0x90
#define HDA_OFFSET_SD0FMT 0x92
#define HDA_OFFSET_SD0BDPL 0x98
#define HDA_OFFSET_SD0BDPU 0x9C
// HDA Spec 1.0a page 27
#define HDA_RELATIVE_OFFSET_SDXCTL 0
#define HDA_RELATIVE_OFFSET_SDXSTS 0x3
#define HDA_RELATIVE_OFFSET_SDXLPIB 0x4
#define HDA_RELATIVE_OFFSET_SDXCBL 0x8
#define HDA_RELATIVE_OFFSET_SDXLVI 0xC
#define HDA_RELATIVE_OFFSET_SDXFIFOS 0x10
#define HDA_RELATIVE_OFFSET_SDXFMT 0x12
#define HDA_RELATIVE_OFFSET_SDXBDPL 0x18
#define HDA_RELATIVE_OFFSET_SDXBDPU 0x1C
// Extract OSS count from controller's global capabilities register
#define HDA_OSS_COUNT(GCAP) ((GCAP >> 12) & 0xF)
// Extract ISS count from controller's global capabilities register
#define HDA_ISS_COUNT(GCAP) ((GCAP >> 8) & 0xF)
// Extract BSS count from controller's global capabilities register
#define HDA_BSS_COUNT(GCAP) ((GCAP >> 3) & 0x1F)
///
// Calculate offset of stream descriptors
#define CALCULATE_ISSN_OFFSET(StreamIndex) (HDA_OFFSET_SD0CTL + (StreamIndex * 0x20))
#define CALCULATE_OSSN_OFFSET(StreamIndex,GCAP) (HDA_OFFSET_SD0CTL + (HDA_ISS_COUNT(GCAP) * 0x20 ) + (StreamIndex * 0x20))
#define CALCULATE_BSSN_OFFSET(StreamIndex,GCAP) (HDA_OFFSET_SD0CTL + (HDA_ISS_COUNT(GCAP) * 0x20) + (HDA_OSS_COUNT(GCAP) * 0x20) + (StreamIndex * 0x20))
typedef struct {
uint8_t StreamReset: 1;
uint8_t StreamRun: 1;
uint8_t InterruptOnCompletionEnable: 1;
uint8_t FIFOErrorInterruptEnable: 1;
uint8_t DescriptorErrorInterruptEnable: 1;
uint8_t Reserved1: 3;
uint8_t Reserved2;
uint8_t StrippeControl: 2;
uint8_t TrafficPriority: 1;
uint8_t BidirectionalDirectionControl: 1;
uint8_t StreamNumber: 4;
} HDA_CONTROLLER_STREAM_DESCRIPTOR_CONTROL;
typedef struct {
uint8_t SD0CTL[3]; // HDA_CONTROLLER_STREAM_DESCRIPTOR_CONTROL
uint8_t SD0STS;
uint32_t SD0LPIB;
uint32_t SD0CBL;
uint16_t SD0LVI;
uint16_t Rsvd8;
uint16_t SD0FIFOS;
uint16_t SD0FMT;
uint32_t Rsvd9;
uint32_t SD0BDPL;
uint32_t SD0BDPU;
} HDA_CONTROLLER_STREAM_DESCRIPTOR;
// HDA controller register set
// HDA Specification 1.0a page 27
typedef struct {
uint16_t GCAP;
uint8_t VMIN;
uint8_t VMAJ;
uint16_t OUTPAY;
uint16_t INPAY;
uint32_t GCTL;
uint16_t WAKEEN;
uint16_t STATESTS;
uint16_t GSTS;
uint8_t Rsvd0[6];
uint16_t OUTSTRMPAY;
uint16_t INSTRMPAY;
uint32_t Rsvd;
uint32_t INTCTL;
uint32_t INTSTS;
uint8_t Rsvd1[8];
uint32_t WALCLK;
uint32_t Rsvd2;
uint32_t SSYNC;
uint32_t Rsvd3;
uint32_t CORBLBASE;
uint32_t CORBUBASE;
uint16_t CORBWP;
uint16_t CORBRP;
uint8_t CORBCTL;
uint8_t CORBSTS;
uint8_t CORBSIZE;
uint8_t Rsvd4;
uint32_t RIRBLBASE;
uint32_t RIRBUBASE;
uint16_t RIRBWP;
uint16_t RINTCNT;
uint8_t RIRBCTL;
uint8_t RIRBSTS;
uint8_t RIRBSIZE;
uint8_t Rsvd5;
uint32_t ICOI;
uint32_t ICII;
uint16_t ICIS;
uint8_t Rsvd6[6];
uint32_t DPIBLBASE;
uint32_t DPIBUBASE;
uint8_t Rsvd7[8];
HDA_CONTROLLER_STREAM_DESCRIPTOR *ISS;
HDA_CONTROLLER_STREAM_DESCRIPTOR *OSS;
HDA_CONTROLLER_STREAM_DESCRIPTOR *BSS;
} HDA_CONTROLLER_REGISTER_SET;
// Executable verbs of widgets on a HDA compatible codec
// HDA Specification 1.0a page 218
typedef enum {
HDA_VRB_GET_PARAMETER = 0xF00,
HDA_VRB_GET_CONNECTION_SELECT = 0xF01,
HDA_VRB_GET_GET_CONNECTION_LIST_ENTRY = 0xF02,
HDA_VRB_GET_PROCESSING_STATE = 0xF03,
// These are widget dependent
HDA_VRB_GET_COEFFICIENT_INDEX = 0xD,
HDA_VRB_GET_PROCESSING_COEFFICIENT = 0xC,
HDA_VRB_GET_AMPLIFIER_GAIN_MUTE = 0xBA0,
HDA_VRB_GET_STREAM_FORMAT = 0xA,
HDA_VRB_GET_DIGITAL_CONVERTER_1 = 0xF0D,
//HDA_VRB_GET_DIGITAL_CONVERTER_2 = 0xF0D,
//HDA_VRB_GET_DIGITAL_CONVERTER_3 = 0xF0D,
//HDA_VRB_GET_DIGITAL_CONVERTER_4 = 0xF0D,
HDA_VRB_GET_POWER_STATE = 0xF05,
HDA_VRB_GET_CHANNEL_STREAM_ID = 0xF06,
HDA_VRB_GET_SDI_SELECT = 0xF04,
HDA_VRB_GET_PIN_WIDGET_CONTROL = 0xF07,
HDA_VRB_GET_UNSOLICITED_ENABLE = 0xF08,
HDA_VRB_GET_PIN_SENSE = 0xF09,
HDA_VRB_GET_EAPD_BTL_ENABLE = 0xF0C,
HDA_VRB_GET_ALL_GPI_CONTROLS_F10 = 0xF10,
HDA_VRB_GET_ALL_GPI_CONTROLS_F11 = 0xF11,
HDA_VRB_GET_ALL_GPI_CONTROLS_F12 = 0xF12,
HDA_VRB_GET_ALL_GPI_CONTROLS_F13 = 0xF13,
HDA_VRB_GET_ALL_GPI_CONTROLS_F14 = 0xF14,
HDA_VRB_GET_ALL_GPI_CONTROLS_F15 = 0xF15,
HDA_VRB_GET_ALL_GPI_CONTROLS_F16 = 0xF16,
HDA_VRB_GET_ALL_GPI_CONTROLS_F17 = 0xF17,
HDA_VRB_GET_ALL_GPI_CONTROLS_F18 = 0xF18,
HDA_VRB_GET_ALL_GPI_CONTROLS_F19 = 0xF19,
HDA_VRB_GET_ALL_GPI_CONTROLS_F1A = 0xF1A,
HDA_VRB_GET_BEEP_GENERATION_CONTROL = 0xF0A,
HDA_VRB_GET_VOLUME_KNOB_CONTROL = 0xF0F,
HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_0 = 0xF20,
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_1 = 0xF20,
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_2 = 0xF20,
//HDA_VRB_GET_IMPLEMENTATION_ID_BYTE_3 = 0xF20,
HDA_VRB_GET_CONFIG_DEFAULT_BYTE_0 = 0xF1C,
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_1 = 0xF1C,
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_2 = 0xF1C,
//HDA_VRB_GET_CONFIG_DEFAULT_BYTE_3 = 0xF1C,
HDA_VRB_GET_STRIPE_CONTROL = 0xF24,
HDA_VRB_GET_CONVERTER_CHANNEL_COUNT = 0xF2D,
HDA_VRB_GET_DIP_SIZE = 0xF2E,
HDA_VRB_GET_ELD_DATA = 0xF2F,
HDA_VRB_GET_DIP_INDEX = 0xF30,
HDA_VRB_GET_DIP_DATA = 0xF31,
HDA_VRB_GET_DIP_XMITCTRL = 0xF32,
HDA_VRB_GET_CONTENT_PROTECTION_CONTROL = 0xF33,
HDA_VRB_GET_ASP_CHANNEL_MAPPING = 0xF34,
HDA_VRB_SET_CONNECTION_SELECT = 0x701,
// These are widget dependent
HDA_VRB_SET_COEFFICIENT_INDEX = 0x5,
HDA_VRB_SET_PROCESSING_COEFFICIENT = 0x4,
HDA_VRB_SET_AMPLIFIER_GAIN_MUTE = 0x3B0,
HDA_VRB_SET_STREAM_FORMAT = 0x2,
HDA_VRB_SET_DIGITAL_CONVERTER_1 = 0x70D,
HDA_VRB_SET_DIGITAL_CONVERTER_2 = 0x70E,
HDA_VRB_SET_DIGITAL_CONVERTER_3 = 0x73E,
HDA_VRB_SET_DIGITAL_CONVERTER_4 = 0x73F,
HDA_VRB_SET_POWER_STATE = 0x705,
HDA_VRB_SET_CHANNEL_STREAM_ID = 0x706,
HDA_VRB_SET_SDI_SELECT = 0x704,
HDA_VRB_SET_PIN_WIDGET_CONTROL = 0x707,
HDA_VRB_SET_UNSOLICITED_ENABLE = 0x708,
HDA_VRB_SET_PIN_SENSE = 0x709,
HDA_VRB_SET_EAPD_BTL_ENABLE = 0x70C,
HDA_VRB_SET_ALL_GPI_CONTROLS_710 = 0x710,
HDA_VRB_SET_ALL_GPI_CONTROLS_711 = 0x711,
HDA_VRB_SET_ALL_GPI_CONTROLS_712 = 0x712,
HDA_VRB_SET_ALL_GPI_CONTROLS_713 = 0x713,
HDA_VRB_SET_ALL_GPI_CONTROLS_714 = 0x714,
HDA_VRB_SET_ALL_GPI_CONTROLS_715 = 0x715,
HDA_VRB_SET_ALL_GPI_CONTROLS_716 = 0x716,
HDA_VRB_SET_ALL_GPI_CONTROLS_717 = 0x717,
HDA_VRB_SET_ALL_GPI_CONTROLS_718 = 0x718,
HDA_VRB_SET_ALL_GPI_CONTROLS_719 = 0x719,
HDA_VRB_SET_ALL_GPI_CONTROLS_71A = 0x71A,
HDA_VRB_SET_BEEP_GENERATION_CONTROL = 0x70A,
HDA_VRB_SET_VOLUME_KNOB_CONTROL = 0x70F,
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_0 = 0x720,
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_1 = 0x721,
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_2 = 0x722,
HDA_VRB_SET_IMPLEMENTATION_ID_BYTE_3 = 0x723,
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_0 = 0x71C,
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_1 = 0x71D,
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_2 = 0x71E,
HDA_VRB_SET_CONFIG_DEFAULT_BYTE_3 = 0x723,
HDA_VRB_SET_STRIPE_CONTROL = 0x724,
HDA_VRB_SET_CONVERTER_CHANNEL_COUNT = 0x72D,
HDA_VRB_SET_DIP_INDEX = 0x730,
HDA_VRB_SET_DIP_DATA = 0x731,
HDA_VRB_SET_DIP_XMITCTRL = 0x732,
HDA_VRB_SET_CONTENT_PROTECTION_CONTROL = 0x733,
HDA_VRB_SET_ASP_CHANNEL_MAPPING = 0x734,
HDA_VRB_SET_RESET = 0x7FF
} HDA_VERB;
#define HDA_START_PROCESSING_IMMEDIATE_COMMAND 0x01
// Extract the total node count from a SubordinateNodeCount property
#define HDA_SUB_NODE_COUNT_TOTAL_NODE(Subordinate) (Subordinate & 0xFF)
// Extract the total node count from a SubordinateNodeCount poperty
#define HDA_SUB_NODE_COUNT_START_NODE(Subordinate) ((Subordinate >> 16) & 0xFF)
// Extract the node type from a FunctionGroup property
#define HDA_NODE_TYPE(FunctionGroupType) (FunctionGroupType & 0xFF)
// Check if a given function group can generate unsolicited responses
#define HDA_UNSOLICITED_RESPONSE_CAPABLE(FunctionGroupType) ((FunctionGroupType >> 8) & 0x01)
// Extract widget type from widget capabilities information
#define HDA_WIDGET_TYPE(WidgetCap) ((WidgetCap >> 20) & 0xF)
// HDA command with an 8-bit payload
typedef struct {
uint32_t VerbPayload : 8;
uint32_t VerbIdent : 12; // verb
uint32_t NID : 8; // node ID
uint32_t CAd : 4; // codec address
uint8_t Reserved;
} HDA_COMMAND_FIELD_8BIT_PAYLOAD;
// HDA command with an 16-bit payload
typedef struct {
uint32_t VerbPayload : 16;
uint32_t VerbIdent : 4; // verb
uint32_t NID : 8; // node ID
uint32_t CAd : 4; // codec address
uint8_t Reserved;
} HDA_COMMAND_FIELD_16BIT_PAYLOAD;
// Stream format
// HDA Specification 1.0a page 58
typedef struct {
uint16_t NumberOfChannels : 4;
uint16_t BitsPerSample : 3;
uint16_t Reserved : 1;
uint16_t SampleBaseRateBaseDivisor : 3;
uint16_t SampleBaseRateMultiple : 3;
uint16_t SampleBaseRate : 1;
uint16_t StreamType : 1;
} HDA_STREAM_FORMAT;
// Stream descriptor format
// HDA Specification 1.0a page 48
typedef struct {
uint16_t NumberOfChannels : 4;
uint16_t BitsPerSample : 3;
uint16_t Reserved : 1;
uint16_t SampleBaseRateBaseDivisor : 3;
uint16_t SampleBaseRateMultiple : 3;
uint16_t SampleBaseRate : 1;
uint16_t Reserved2 : 1;
} HDA_STREAM_DESCRIPTOR_FORMAT;
#define PCM_STRUCT_BITS_PER_SAMPLE_8 0
#define PCM_STRUCT_BITS_PER_SAMPLE_16 1
#define PCM_STRUCT_BITS_PER_SAMPLE_20 2
#define PCM_STRUCT_BITS_PER_SAMPLE_24 3
#define PCM_STRUCT_BITS_PER_SAMPLE_32 4
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_1 0
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_2 1
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_3 2
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_4 3
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_5 4
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_6 5
#define PCM_STRUCT_SAMPLE_BASE_DIV_BY_7 6
//192 kHz, 176.4 kHz
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X4 3
//144 kHz
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X3 2
//96 kHz, 88.2 kHz, 32 kHz
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_X2 1
//48KHz/44.1kHz or less
#define PCM_STRUCT_SAMPLE_BASE_MULTIPLE_48_OR_LESS 0
#define PCM_STRUCT_SAMPLE_BASE_44_1KHZ 1
#define PCM_STRUCT_SAMPLE_BASE_48KHZ 0
#define PCM_STRUCT_TYPE_PCM 0
#define PCM_STRUCT_TYPE_NON_PCM 1
// All possible parameters for executing HDA_VRB_GET_PARAMETER
// HDA Specification 1.0a page 217
typedef enum {
HDA_PARAM_VENDOR_ID = 0x00,
HDA_PARAM_REVISION_ID = 0x02,
HDA_PARAM_SUBORDINATE_NODE_COUNT = 0x04,
HDA_PARAM_FUNCTION_GROUP_TYPE = 0x05,
HDA_PARAM_AUDIO_FUNC_CAP = 0x08,
HDA_PARAM_AUDIO_WIDGET_CAP = 0x09,
HDA_PARAM_SAMPLE_SIZE_RATE_CAP = 0x0A,
HDA_PARAM_STREAM_FORMATS = 0x0B,
HDA_PARAM_PIN_CAP = 0x0C,
HDA_PARAM_INPUT_AMP_CAP = 0x0D,
HDA_PARAM_OUTPUT_AMP_CAP = 0x12,
HDA_PARAM_CONNECTION_LIST_LENGTH = 0x0E,
HDA_PARAM_SUPPORTED_POWER_STATES = 0x0F,
HDA_PARAM_PROCESSING_CAP = 0x10,
HDA_PARAM_GPIO_COUNT = 0x11,
HDA_PARAM_VOLUME_KNOB_CAP = 0x13
} HDA_PARAMETER;
// All possible parameters widget types present
typedef enum {
HDA_WIDGET_TYPE_AUDIO_OUTPUT = 0x0,
HDA_WIDGET_TYPE_AUDIO_INPUT = 0x1,
HDA_WIDGET_TYPE_AUDIO_MIXER = 0x2,
HDA_WIDGET_TYPE_AUDIO_SELECTOR = 0x3,
HDA_WIDGET_TYPE_AUDIO_PIN_CONPLEX = 0x4,
HDA_WIDGET_TYPE_AUDIO_POWER = 0x5,
HDA_WIDGET_TYPE_AUDIO_VOLUME_KNOB = 0x6,
HDA_WIDGET_TYPE_AUDIO_BEEP_GENERATOR = 0x7,
HDA_WIDGET_TYPE_AUDIO_VENDOR_DEFINED = 0xF
} HDA_WIDGET_TYPE;
// Function group types
typedef enum {
HDA_FUNCTION_GROUP_TYPE_AUDIO = 0x1,
HDA_FUNCTION_GROUP_TYPE_MODEM = 0x2
} HDA_FUNCTION_GROUP_TYPE;
// All possible node types available at a codec
typedef enum {
HDA_NODE_ROOT = 0x0,
HDA_NODE_FUNCTION_GROUP = 0x1,
HDA_NODE_WIDGET = 0x2,
HDA_UNKNOWN = 0xFF
} HDA_NODE_TYPE;
// Empty payload
#define HDA_VRB_EMPTY_PAYLOAD 0
// All possible power stats a node can present
// HDA Specification 1.0a page 151
typedef enum {
HDA_POWER_D0 = 0x0,
HDA_POWER_D1 = 0x1,
HDA_POWER_D2 = 0x2,
HDA_POWER_D3 = 0x3,
HDA_POWER_D3_COLD = 0x4,
} HDA_POWER_STATE;
// HDA codec node
struct Node {
uint32_t NodeId;
HDA_NODE_TYPE NodeType;
HDA_WIDGET_TYPE WidgetType;
uint32_t VendorId;
uint32_t RevisionId;
uint32_t StartingChildNodeAddess;
uint32_t SubordinateNodeCount;
uint32_t FunctionGroupType;
uint32_t FuncCap;
uint32_t WidgetCap;
uint32_t SampleSizeRateCap;
uint32_t StreamFormat;
uint32_t PinCap;
uint32_t InputAmpCap;
uint32_t OutputAmpCap;
uint32_t ConnectionListLength;
uint32_t SupportedPowerStates;
uint32_t ProcessingCap;
uint32_t GPIOCount;
uint32_t VolKnobCap;
uint32_t PowerState;
uint32_t RightGain;
uint32_t LeftGain;
uint32_t ChannelStreamId;
struct Node *ChildNodes;
};
// HDA Specification 1.0a page 142
typedef struct {
uint32_t Response;
uint8_t Reserved : 2;
uint8_t UnSol : 1;
uint8_t Valid : 1;
uint8_t Unused : 4;
} HDA_RESPONSE_FIELD;
typedef struct {
uint64_t Address;
uint32_t Length;
uint32_t IntrptOnComp : 1;
uint32_t Resv : 31;
} HDA_BUFFER_DESCRIPTOR_LIST_ENTRY;
typedef struct {
HDA_BUFFER_DESCRIPTOR_LIST_ENTRY BDLEntry[HDA_BUFFER_DESC_LIST_MAX_ENTRIES];
} HDA_BUFFER_DESCRIPTOR_LIST;
EFI_STATUS InitHda();
EFI_STATUS AllocateCORBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace);
EFI_STATUS AllocateRIRBBuffer(PCI_HDA_REGION* PcieDeviceConfigSpace);
EFI_STATUS FillCodecNode(PCI_HDA_REGION *PcieDeviceConfigSpace,
uint32_t CurrentNodeId,
HDA_NODE_TYPE NodeType,
struct Node *CurrentNode);
EFI_STATUS GetNodeById(struct Node *RootNode,
uint32_t NodeIdToSearch,
struct Node *NodeDetected);
EFI_STATUS GetCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
struct Node *RootNode);
EFI_STATUS ReleaseCodecTree(PCI_HDA_REGION *PcieDeviceConfigSpace,
struct Node *RootNode);
EFI_STATUS GetCodecData8BitPayload(PCI_HDA_REGION *PcieDeviceConfigSpace,
uint8_t CodecAddress, uint8_t NodeId,
HDA_VERB Verb, uint8_t VerbPayload,
uint32_t *Response);
EFI_STATUS GetCodecData8BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
uint8_t CodecAddress, uint8_t NodeId,
HDA_VERB Verb, uint8_t VerbPayload,
uint32_t *Response);
EFI_STATUS GetCodecData16BitPayloadCorbRirb(PCI_HDA_REGION *PcieDeviceConfigSpace,
uint8_t CodecAddress, uint8_t NodeId,
HDA_VERB Verb, uint16_t VerbPayload,
uint32_t *Response);
EFI_STATUS SendCommandToAllWidgets8BitPayload (
PCI_HDA_REGION *PcieDeviceConfigSpace,
HDA_VERB Verb, uint8_t VerbPayload);
EFI_STATUS SendCommandToAllWidgets16BitPayload (
PCI_HDA_REGION* PcieDeviceConfigSpace,
HDA_VERB Verb, uint16_t VerbPayload);
EFI_STATUS GetCodecData16BitPayload(PCI_HDA_REGION* PcieDeviceConfigSpace,
uint8_t CodecAddress, uint8_t NodeId,
HDA_VERB Verb, uint16_t VerbPayload,
uint32_t *Response);
uint32_t GetAmplifierGain(PCI_HDA_REGION *PcieDeviceConfigSpace,
uint8_t NodeId, bool InputOutput,
bool LeftRight);
EFI_STATUS DisablePcieInterrupts(PCI_HDA_REGION *PcieDeviceConfigSpace);
EFI_STATUS EnablePcieNoSnoop(PCI_HDA_REGION *PcieDeviceConfigSpace);
EFI_STATUS AddDescriptorListEntryOss0(PCI_HDA_REGION *PcieDeviceConfigSpace,
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet,
uint64_t DataAddress,
uint32_t DataLength,
uint8_t BdlEntryIndex,
uint32_t SdxLastValidIndex);
EFI_STATUS AllocateStreamsPages(PCI_HDA_REGION *PcieDeviceConfigSpace,
HDA_CONTROLLER_REGISTER_SET *ControllerRegisterSet);
#endif /* _HDA_HDA_H */