AMD Geode 5536 ac97 support
git-svn-id: svn://kolibrios.org@981 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
6e7de80aba
commit
e2f30062dd
37
drivers/a5536/geode.asm
Normal file
37
drivers/a5536/geode.asm
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
use32
|
||||
|
||||
db 'MENUET01'
|
||||
dd 1
|
||||
dd start
|
||||
dd i_end
|
||||
dd mem
|
||||
dd mem
|
||||
dd 0
|
||||
dd 0
|
||||
|
||||
start:
|
||||
mov eax, 68
|
||||
mov ebx, 16
|
||||
mov ecx, sz_sound
|
||||
int 0x40
|
||||
test eax, eax
|
||||
jnz .exit
|
||||
|
||||
mov eax, 68
|
||||
mov ebx, 21
|
||||
mov ecx, sz_path
|
||||
int 0x40
|
||||
|
||||
.exit:
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
|
||||
sz_sound db 'SOUND',0
|
||||
sz_path db '/rd/1/drivers/geode.drv',0
|
||||
|
||||
align 4
|
||||
i_end:
|
||||
rb 128
|
||||
mem:
|
3
drivers/a5536/geode.bat
Normal file
3
drivers/a5536/geode.bat
Normal file
@ -0,0 +1,3 @@
|
||||
del geode.dll
|
||||
make
|
||||
@pause
|
551
drivers/a5536/geode.c
Normal file
551
drivers/a5536/geode.c
Normal file
@ -0,0 +1,551 @@
|
||||
|
||||
|
||||
#define FORCED_PIO
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include "pci.h"
|
||||
#include "syscall.h"
|
||||
|
||||
#include "geode.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(format,...) dbgprintf(format,##__VA_ARGS__)
|
||||
#else
|
||||
#define DBG(format,...)
|
||||
#endif
|
||||
|
||||
#define BM0_IRQ 0x04
|
||||
#define BM1_IRQ 0x08
|
||||
#define BITS_8_TO_16(x) ( ( (long) ((unsigned char) x - 128) ) << 8 )
|
||||
|
||||
#define PCI_VENDOR_ID_NS 0x100b
|
||||
#define PCI_VENDOR_ID_AMD 0x1022
|
||||
|
||||
|
||||
#ifndef PCI_DEVICE_ID_NS_CS5535_AUDIO
|
||||
#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_AMD_CS5536_AUDIO
|
||||
#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
|
||||
#endif
|
||||
|
||||
#define ID_DEV_1 ((PCI_DEVICE_ID_NS_CS5535_AUDIO << 16)|PCI_VENDOR_ID_NS)
|
||||
#define ID_DEV_2 ((PCI_DEVICE_ID_AMD_CS5536_AUDIO << 16)|PCI_VENDOR_ID_AMD)
|
||||
|
||||
#define SET 1
|
||||
#define CLEAR 0
|
||||
|
||||
int __stdcall srv_sound(ioctl_t *io);
|
||||
|
||||
|
||||
PRD_ENTRY __attribute__((aligned(16))) prd_tab[5];
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PCITAG pciTag;
|
||||
Bool is_iomapped;
|
||||
addr_t F3BAR0;
|
||||
|
||||
Bool fAD1819A;
|
||||
|
||||
int CurrentPowerState;
|
||||
|
||||
addr_t buffer;
|
||||
addr_t prd_dma;
|
||||
|
||||
addr_t irq_line;
|
||||
u32_t irq_mask;
|
||||
|
||||
void __stdcall (*callback)(addr_t buffer);
|
||||
}geode_t;
|
||||
|
||||
geode_t geode;
|
||||
|
||||
|
||||
static inline void ctrl_write_32(addr_t reg, u32_t data)
|
||||
{
|
||||
reg+= geode.F3BAR0;
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
out32((u16_t)reg, data);
|
||||
#else
|
||||
if(geode.is_iomapped)
|
||||
out32((u16_t)reg, data);
|
||||
else
|
||||
*(u32_t*)reg = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u32_t ctrl_read_32(addr_t reg)
|
||||
{
|
||||
reg+= geode.F3BAR0;
|
||||
#ifdef FORCED_PIO
|
||||
return in32((u16_t)reg);
|
||||
#else
|
||||
if(geode.is_iomapped)
|
||||
return in32((u16_t)reg);
|
||||
else
|
||||
return *(u32_t*)reg;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bool snd_hw_WaitForBit(addr_t offset, u32_t Bit,
|
||||
unsigned char Operation,
|
||||
count_t timeout,
|
||||
u32_t *pReturnValue)
|
||||
{
|
||||
volatile u32_t tmp;
|
||||
|
||||
tmp = ctrl_read_32(offset);
|
||||
|
||||
while (timeout)
|
||||
{
|
||||
if (Operation==CLEAR){
|
||||
if (!(tmp & Bit))
|
||||
break;
|
||||
} else if (tmp & Bit)
|
||||
break;
|
||||
|
||||
/*If the Bit is not clear yet, we wait for 10 milisecond and try again*/
|
||||
delay(10/10);
|
||||
|
||||
tmp = ctrl_read_32(offset);
|
||||
|
||||
timeout--;
|
||||
};
|
||||
|
||||
if (pReturnValue)
|
||||
*pReturnValue=tmp;
|
||||
|
||||
if (!timeout)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u16_t snd_hw_CodecRead ( u8_t CodecRegister )
|
||||
{
|
||||
u32_t CodecRegister_data = 0;
|
||||
u32_t timeout=10;
|
||||
volatile u32_t val=0;
|
||||
|
||||
CodecRegister_data = ((u32_t)CodecRegister)<<24;
|
||||
CodecRegister_data |= 0x80000000; /* High-bit set (p.106) is a CODEC reg READ.*/
|
||||
|
||||
/* Set the bit. We are going to access the CODEC...*/
|
||||
CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
|
||||
|
||||
/*Request the data*/
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
|
||||
|
||||
/* Now we need to wait for BIT_5535_CODEC_COMMAND_NEW of the Codec control register to clear
|
||||
(For subsequent Reads/Writes)*/
|
||||
if (!snd_hw_WaitForBit (CODEC_CONTROL_REG_5535,
|
||||
BIT_5535_CODEC_COMMAND_NEW, CLEAR, 50, NULL))
|
||||
DBG("BIT_5535_CODEC_COMMAND_NEW did not clear!!\n");
|
||||
|
||||
/* Wait for CODEC_STATUS_NEW and confirm the read of the requested register*/
|
||||
timeout = 50;
|
||||
do
|
||||
{
|
||||
val = ctrl_read_32(CODEC_STATUS_REG_5535);
|
||||
if ((val & BIT_5535_CODEC_STATUS_NEW) &&
|
||||
((u32_t) CodecRegister == ((0xFF000000 & val)>>24)))
|
||||
break;
|
||||
else
|
||||
/*Wait for 10 miliseconds and try again*/
|
||||
delay(10/10);
|
||||
} while ( --timeout);
|
||||
|
||||
if (!timeout)
|
||||
DBG("Could not read the CODEC!! Returning what we got.\n");
|
||||
|
||||
return( (u16_t)val );
|
||||
}
|
||||
|
||||
void snd_hw_CodecWrite( u8_t CodecRegister, u16_t CodecData )
|
||||
{
|
||||
u32_t CodecRegister_data;
|
||||
u32_t Temp, timeout;
|
||||
|
||||
CodecRegister_data = ((u32_t) CodecRegister)<<24;
|
||||
CodecRegister_data |= (u32_t) CodecData;
|
||||
CodecRegister_data &= CODEC_COMMAND_MASK;
|
||||
|
||||
/*Set the bit. We are going to access the CODEC...*/
|
||||
CodecRegister_data |= BIT_5535_CODEC_COMMAND_NEW;
|
||||
|
||||
/*Write the data*/
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, CodecRegister_data);
|
||||
//OS_DbgMsg("Writing: %08X\n", CodecRegister_data);
|
||||
|
||||
/*We need to wait for bit16 of the Codec control register to clear*/
|
||||
Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
|
||||
|
||||
timeout = 50;
|
||||
|
||||
while ((Temp & BIT_5535_CODEC_COMMAND_NEW) && timeout-- )
|
||||
Temp = ctrl_read_32(CODEC_CONTROL_REG_5535);
|
||||
|
||||
if (!timeout)
|
||||
DBG("Could not Write the CODEC!!\n"
|
||||
"BIT_5535_CODEC_COMMAND_NEW did not clear!\n");
|
||||
}
|
||||
|
||||
|
||||
void snd_hw_SetCodecRate(u32_t SampleRate)
|
||||
{
|
||||
u16_t val;
|
||||
|
||||
DBG("Rate: %d\n", SampleRate);
|
||||
|
||||
/*If Double-Rate is supported (Bit 2 on register 28h)...*/
|
||||
val=snd_hw_CodecRead(EXTENDED_AUDIO_ID);
|
||||
|
||||
if (val & 0x02)
|
||||
{
|
||||
DBG("Codec supports Double rate.\n");
|
||||
val=snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT);
|
||||
|
||||
if (SampleRate>48000)
|
||||
{
|
||||
snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val|0x0002));
|
||||
SampleRate/=2;
|
||||
}
|
||||
else
|
||||
snd_hw_CodecWrite(EXT_AUDIO_CTRL_STAT, (u16_t) (val&0xFFFD));
|
||||
}
|
||||
if (geode.fAD1819A)
|
||||
{
|
||||
DBG("AD1819...\n");
|
||||
snd_hw_CodecWrite(AD1819A_PCM_SR0,(u16_t)SampleRate);
|
||||
}
|
||||
else
|
||||
snd_hw_CodecWrite(PCM_FRONT_DAC_RATE,(u16_t)SampleRate);
|
||||
}
|
||||
|
||||
Bool init_device()
|
||||
{
|
||||
u32_t io_base = pciReadLong(geode.pciTag, 0x10);
|
||||
|
||||
if( PCI_MAP_IS_IO(io_base))
|
||||
{
|
||||
geode.is_iomapped = TRUE;
|
||||
geode.F3BAR0 = PCIGETIO(io_base);
|
||||
DBG("io mapped F3BAR0 %x\n", geode.F3BAR0);
|
||||
}
|
||||
else if(PCI_MAP_IS_MEM(io_base))
|
||||
{
|
||||
geode.is_iomapped = FALSE;
|
||||
io_base = PCIGETMEMORY(io_base);
|
||||
geode.F3BAR0 = MapIoMem(io_base, 128, PG_SW+PG_NOCACHE);
|
||||
DBG("memory mapped F3BAR0 %x\n", geode.F3BAR0);
|
||||
}
|
||||
|
||||
geode.buffer = KernelAlloc(64*1024);
|
||||
|
||||
addr_t buffer = geode.buffer;
|
||||
addr_t dma = GetPgAddr(geode.buffer);
|
||||
|
||||
geode.prd_dma = (((addr_t)prd_tab) & 4095) + GetPgAddr((void*)prd_tab);
|
||||
|
||||
prd_tab[0].ulPhysAddr = dma;
|
||||
prd_tab[0].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[1].ulPhysAddr = dma + 16384;
|
||||
prd_tab[1].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[2].ulPhysAddr = dma + 16384*2;
|
||||
prd_tab[2].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[3].ulPhysAddr = dma + 16384*3;
|
||||
prd_tab[3].SizeFlags = 16384 | PRD_EOP_BIT ;
|
||||
|
||||
prd_tab[4].ulPhysAddr = geode.prd_dma;
|
||||
prd_tab[4].SizeFlags = PRD_JMP_BIT ;
|
||||
|
||||
ctrl_write_32(0x24, geode.prd_dma);
|
||||
|
||||
__clear((void*)buffer,64*1024);
|
||||
// u32_t tmp = ctrl_read_32(0x24);
|
||||
|
||||
// dbgprintf("Create primary buffer at %x dma at %x\n", geode.buffer, dma );
|
||||
|
||||
// dbgprintf("Set prd dma %x, read prd dma %x\n", geode.prd_dma, tmp);
|
||||
|
||||
geode.irq_line = pciReadLong(geode.pciTag, 0x3C) & 0xFF;
|
||||
geode.irq_mask = ~(1<<geode.irq_line);
|
||||
|
||||
DBG("Irq line %d, mask %x\n", geode.irq_line, geode.irq_mask);
|
||||
|
||||
|
||||
/*
|
||||
geode.CommandRegister = geode.F3BAR0+0x20;
|
||||
geode.PRDTableAddress = geode.F3BAR0+0x24;
|
||||
geode.DMAPointer = geode.F3BAR0+0x60;
|
||||
|
||||
geode.IRQControlRegister = geode.F3BAR0+0x1C;
|
||||
geode.InternalIRQEnableRegister = geode.F3BAR0+0x1A;
|
||||
geode.SMI_StatusRegister = geode.F3BAR0+0x21;
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*CODEC - RESET and volumes initalization.*/
|
||||
/*Set the Warm RESET and CODEC_COMMAND_NEW bits.*/
|
||||
|
||||
DBG("reset codec...\n");
|
||||
|
||||
ctrl_write_32(CODEC_CONTROL_REG_5535, 0x00030000 );
|
||||
|
||||
if (!snd_hw_WaitForBit (CODEC_STATUS_REG_5535, BIT_CODEC_READY, SET, 40, NULL))
|
||||
{
|
||||
DBG("Primary Codec NOT Ready...Aborting\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*Check which codec is being used */
|
||||
if (snd_hw_CodecRead(AD1819A_VENDORID1) == 0x4144 &&
|
||||
snd_hw_CodecRead(AD1819A_VENDORID2) == 0x5303)
|
||||
{
|
||||
geode.fAD1819A = TRUE;
|
||||
/* Enable non-48kHz sample rates. */
|
||||
snd_hw_CodecWrite (AD1819A_SER_CONF,
|
||||
snd_hw_CodecRead(AD1819A_SER_CONF>>8) |
|
||||
AD1819A_SER_CONF_DRQEN);
|
||||
DBG("detect AD1819A audio codec\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
geode.fAD1819A = FALSE;
|
||||
snd_hw_CodecWrite (EXT_AUDIO_CTRL_STAT,
|
||||
(snd_hw_CodecRead(EXT_AUDIO_CTRL_STAT) | 0x0001));
|
||||
/* set the VRA bit to ON*/
|
||||
}
|
||||
|
||||
/* set default volume*/
|
||||
snd_hw_CodecWrite( MASTER_VOLUME, 0x0B0B);
|
||||
snd_hw_CodecWrite( PCM_OUT_VOL, 0x0808);
|
||||
snd_hw_CodecWrite( PC_BEEP_VOLUME, 0x0000);
|
||||
snd_hw_CodecWrite( PHONE_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( MIC_VOLUME, 0x8048);
|
||||
snd_hw_CodecWrite( LINE_IN_VOLUME, 0x0808);
|
||||
snd_hw_CodecWrite( CD_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( VIDEO_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( TV_VOLUME, 0x8000);
|
||||
snd_hw_CodecWrite( RECORD_SELECT, 0x0000);
|
||||
snd_hw_CodecWrite( RECORD_GAIN, 0x0a0a);
|
||||
snd_hw_CodecWrite( GENERAL_PURPOSE, 0x0200);
|
||||
snd_hw_CodecWrite( MASTER_VOLUME_MONO, 0x0000);
|
||||
|
||||
snd_hw_SetCodecRate(48000);
|
||||
/*Set all the power state bits to 0 (Reg 26h)*/
|
||||
snd_hw_CodecWrite (POWERDOWN_CTRL_STAT, 0x0000);
|
||||
geode.CurrentPowerState = GEODEAUDIO_D0;
|
||||
// OS_DbgMsg("<--snd_hw_InitAudioRegs\n");
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int snd_StartDMA ()
|
||||
{
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
out8( (u16_t)(geode.F3BAR0+0x20),PCI_READS | ENABLE_BUSMASTER);
|
||||
else
|
||||
*(u8_t*)(geode.F3BAR0+0x20)= PCI_READS | ENABLE_BUSMASTER;
|
||||
#endif
|
||||
return 0;
|
||||
};
|
||||
|
||||
static u8_t snd_hw_InterruptID ()
|
||||
{
|
||||
volatile u8_t *TempInterruptID, ID;
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
ID=(u8_t) in16((u16_t)(geode.F3BAR0 + 0x12));
|
||||
else
|
||||
{
|
||||
TempInterruptID=(u8_t*)(geode.F3BAR0 + 0x12);
|
||||
ID=*TempInterruptID;
|
||||
}
|
||||
#endif
|
||||
return (ID);
|
||||
}
|
||||
|
||||
|
||||
static u8_t snd_hw_ClearStat(int Channel)
|
||||
{
|
||||
volatile u8_t status; /*Volatile to force read-to-clear.*/
|
||||
|
||||
/*Read to clear*/
|
||||
|
||||
#ifdef FORCED_PIO
|
||||
status = in8((u16_t) geode.F3BAR0 + 0x21);
|
||||
#else
|
||||
if (geode.is_iomapped)
|
||||
status = in8((u16_t) geode.F3BAR0 + 0x21);
|
||||
else
|
||||
status = *((u8_t*)geode.F3BAR0 + 0x21);
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void snd_interrupt()
|
||||
{
|
||||
u8_t IntID;
|
||||
|
||||
IntID = snd_hw_InterruptID();
|
||||
|
||||
// dbgprintf("IRQ id %x\n", IntID);
|
||||
|
||||
snd_hw_ClearStat(CHANNEL0_PLAYBACK);
|
||||
// snd_hw_ClearStat(CHANNEL1_RECORD);
|
||||
|
||||
if(IntID & BM0_IRQ)
|
||||
{
|
||||
addr_t prd, offset, base;
|
||||
|
||||
prd = ctrl_read_32(0x24);
|
||||
offset = (1 + (prd - geode.prd_dma)>>3) & 3;
|
||||
|
||||
base = geode.buffer + 16384*offset;
|
||||
|
||||
geode.callback(base);
|
||||
__asm__ volatile("":::"ebx","esi","edi");
|
||||
|
||||
// dbgprintf(">>BM0_IRQ prd %x offset %x base %x\n", prd, offset, base);
|
||||
};
|
||||
};
|
||||
|
||||
Bool FindPciDevice()
|
||||
{
|
||||
u32_t bus, last_bus;
|
||||
PCITAG tag;
|
||||
|
||||
if( (last_bus = PciApi(1))==-1)
|
||||
return FALSE;
|
||||
|
||||
for(bus=0;bus<=last_bus;bus++)
|
||||
{
|
||||
u32_t devfn;
|
||||
|
||||
for(devfn=0;devfn<256;devfn++)
|
||||
{
|
||||
u32_t pciId=0;
|
||||
|
||||
pciId = PciRead32(bus,devfn, 0);
|
||||
|
||||
if( (pciId == ID_DEV_1) ||
|
||||
(pciId == ID_DEV_2) )
|
||||
{
|
||||
DBG("detect companion audio device %x\n", pciId);
|
||||
geode.pciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||
return TRUE;
|
||||
};
|
||||
};
|
||||
};
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
|
||||
u32_t __stdcall drvEntry(int action)
|
||||
{
|
||||
u32_t retval;
|
||||
|
||||
int i;
|
||||
|
||||
if(action != 1)
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
if(!dbg_open("/rd/1/drivers/geode.log"))
|
||||
{
|
||||
printf("Can't open /rd/1/drivers/geode.log\nExit\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FindPciDevice() == FALSE)
|
||||
{
|
||||
DBG("Device not found\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
init_device();
|
||||
|
||||
retval = RegService("SOUND", srv_sound);
|
||||
|
||||
AttachIntHandler(geode.irq_line, snd_interrupt, 0);
|
||||
|
||||
DBG("reg service %s as: %x\n", "SOUND", retval);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
|
||||
#define API_VERSION 0x01000100
|
||||
|
||||
#define SRV_GETVERSION 0
|
||||
#define DEV_PLAY 1
|
||||
#define DEV_STOP 2
|
||||
#define DEV_CALLBACK 3
|
||||
#define DEV_SET_BUFF 4
|
||||
#define DEV_NOTIFY 5
|
||||
#define DEV_SET_MASTERVOL 6
|
||||
#define DEV_GET_MASTERVOL 7
|
||||
#define DEV_GET_INFO 8
|
||||
|
||||
|
||||
int __stdcall srv_sound(ioctl_t *io)
|
||||
{
|
||||
u32_t *inp;
|
||||
u32_t *outp;
|
||||
|
||||
inp = io->input;
|
||||
outp = io->output;
|
||||
|
||||
switch(io->io_code)
|
||||
{
|
||||
case SRV_GETVERSION:
|
||||
if(io->out_size==4)
|
||||
{
|
||||
*outp = API_VERSION;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEV_PLAY:
|
||||
return snd_StartDMA();
|
||||
break;
|
||||
|
||||
case DEV_STOP:
|
||||
break;
|
||||
|
||||
case DEV_CALLBACK:
|
||||
if(io->inp_size==4)
|
||||
{
|
||||
geode.callback = (void*)(*inp);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PARAM;
|
||||
};
|
||||
return ERR_PARAM;
|
||||
}
|
||||
|
||||
|
200
drivers/a5536/geode.h
Normal file
200
drivers/a5536/geode.h
Normal file
@ -0,0 +1,200 @@
|
||||
|
||||
|
||||
//
|
||||
// Device and Vendor IDs - Needed like this for OSS only
|
||||
//
|
||||
#define CYRIX_VENDOR_ID 0x1078
|
||||
#define NATIONAL_VENDOR_ID 0x100B
|
||||
|
||||
//
|
||||
// Audio Device IDs
|
||||
//
|
||||
#define CX5530_DEV_ID 0x0103
|
||||
#define SC1200_DEV_ID 0x0503
|
||||
#define CS5535_DEV_ID 0x002E
|
||||
|
||||
//
|
||||
// Function 3 of 5530 PCI dev is Audio (ISA idx).
|
||||
//
|
||||
#define PCI_FUNC3_AUDIO 0x300
|
||||
#define PCI_AUDIO_CMD_REG 0x04
|
||||
|
||||
typedef unsigned char AUDIO_STATE;
|
||||
|
||||
#define AUDIO_STATE_IGNORE 0
|
||||
#define AUDIO_STATE_IN_RECORDING 0x01
|
||||
#define AUDIO_STATE_IN_OVERFLOW 0x02
|
||||
#define AUDIO_STATE_IN_STOPPED 0x03
|
||||
#define AUDIO_STATE_IN_MASK 0x0F
|
||||
#define AUDIO_STATE_OUT_PLAYING 0x10
|
||||
#define AUDIO_STATE_OUT_UNDERFLOW 0x20
|
||||
#define AUDIO_STATE_OUT_STOPPED 0x30
|
||||
#define AUDIO_STATE_OUT_MASK 0xF0
|
||||
|
||||
#define RECORD_RUNNING 0x01
|
||||
#define RECORD_OVERFLOW 0x02
|
||||
#define RECORD_STOPPED 0x03
|
||||
|
||||
#define PLAYBACK_RUNNING 0x10
|
||||
#define PLAYBACK_UNDERFLOW 0x20
|
||||
#define PLAYBACK_STOPPED 0x30
|
||||
|
||||
//
|
||||
// The CODEC commands are actually 16-bit words, into which is inserted
|
||||
// the codec "target" register, identified by a byte. The 5530 Codec
|
||||
// controller writes a command unsigned short of 32-bits, that includes the codec
|
||||
// command unsigned short.
|
||||
//
|
||||
#define CODEC_COMMAND_MASK 0xFF00FFFF
|
||||
|
||||
//
|
||||
// The Interaction with the CODEC is a bit cumbersome
|
||||
// because of the serial interface.
|
||||
//
|
||||
#define CODEC_STATUS_REG 0x08 // In Audio mem-map.
|
||||
#define CODEC_CMD_REG 0x0c // In audio mem-map.
|
||||
#define CODEC_CMD_VALID 0x00010000
|
||||
#define CODEC_STATUS_VALID 0x00020000
|
||||
#define CODEC_STATUS_NEW 0x00010000
|
||||
#define BIT_CODEC_READY 0x00800000
|
||||
|
||||
//
|
||||
// Registers for the 5535
|
||||
//
|
||||
#define CODEC_STATUS_REG_5535 0x08
|
||||
#define CODEC_CONTROL_REG_5535 0x0c
|
||||
|
||||
//
|
||||
// 5535 Bits
|
||||
//
|
||||
#define BIT_5535_CODEC_COMMAND_NEW 0x00010000
|
||||
#define BIT_5535_CODEC_STATUS_NEW 0x00020000
|
||||
#define BIT_5535_ACLINK_SHUTDOWN 0x00040000
|
||||
#define BIT_5535_ACLINK_WARM_RESET 0x00020000
|
||||
#define BIT_5535_CODEC_READY_PRIM 0x00800000
|
||||
|
||||
//
|
||||
// Codec register indexes. Note these are all shifted left by 16 bits.
|
||||
//
|
||||
#define RESET 0x00
|
||||
#define MASTER_VOLUME 0x02
|
||||
#define LINE_LEV_OUT_VOL 0x04
|
||||
#define MASTER_VOLUME_MONO 0x06
|
||||
#define MASTER_TONE_RL 0x08
|
||||
#define PC_BEEP_VOLUME 0x0a
|
||||
#define PHONE_VOLUME 0x0c
|
||||
#define MIC_VOLUME 0x0e
|
||||
#define LINE_IN_VOLUME 0x10
|
||||
#define CD_VOLUME 0x12
|
||||
#define VIDEO_VOLUME 0x14
|
||||
#define TV_VOLUME 0x16
|
||||
#define PCM_OUT_VOL 0x18
|
||||
#define RECORD_SELECT 0x1a
|
||||
#define RECORD_GAIN 0x1c
|
||||
#define RECORD_MIC_GAIN 0x1e
|
||||
#define GENERAL_PURPOSE 0x20
|
||||
#define CONTROL_3D 0x22
|
||||
#define MODEM_RATE 0x24
|
||||
#define POWERDOWN_CTRL_STAT 0x26
|
||||
#define EXTENDED_AUDIO_ID 0x28
|
||||
#define EXT_AUDIO_CTRL_STAT 0x2A
|
||||
#define PCM_FRONT_DAC_RATE 0x2C
|
||||
#define PCM_LR_ADC_RATE 0x32
|
||||
#define VENDOR_ID1 0x7c
|
||||
#define VENDOR_ID2 0x7e
|
||||
|
||||
#define MUTE_MASK 0x8000
|
||||
#define HEADHONE_AVAIL 0x0010
|
||||
#define LINE_LEV_RESET_VOL 0x0000 // the reset without the mask
|
||||
|
||||
#ifdef AC97_2DOT1_6BIT_COMPLIANT
|
||||
# define MASTER_ATTEN_CTL_BITS 6
|
||||
#else
|
||||
# define MASTER_ATTEN_CTL_BITS 5
|
||||
#endif
|
||||
|
||||
#define MASTER_VOLUME_MAX ( ( 1 << MASTER_ATTEN_CTL_BITS ) - 1 )
|
||||
#define LINE_LEV_OUT_MAX ( ( 1 << MASTER_ATTEN_CTL_BITS ) - 1 )
|
||||
|
||||
//
|
||||
// AD1819A registers
|
||||
//
|
||||
#define AD1819A_SER_CONF 0x74
|
||||
#define AD1819A_SER_CONF_DRQEN 0x08
|
||||
#define AD1819A_MISC 0x76
|
||||
#define AD1819A_PCM_SR0 0x78
|
||||
#define AD1819A_PCM_SR1 0x7A
|
||||
#define AD1819A_VENDORID1 0x7C
|
||||
#define AD1819A_VENDORID2 0x7E
|
||||
|
||||
//
|
||||
// Power Management bits
|
||||
//
|
||||
#define GEODEAUDIO_PWR_PR0 0x0100 // PCM in ADC's & input Mux Powerdown
|
||||
#define GEODEAUDIO_PWR_PR1 0x0200 // PCM out DACs Powerdown
|
||||
#define GEODEAUDIO_PWR_PR2 0x0400 // Analog Mixer powerdown (Vref still on)
|
||||
#define GEODEAUDIO_PWR_PR3 0x0800 // Analog Mxer powerdown (Vref off)
|
||||
#define GEODEAUDIO_PWR_PR4 0x1000 // Digital interface (AC-link) powerdown (external clk off)
|
||||
#define GEODEAUDIO_PWR_PR5 0x2000 // Internal Clk disable
|
||||
#define GEODEAUDIO_PWR_PR6 0x4000 // HP amp powerdown
|
||||
#define GEODEAUDIO_PWR_PR7 0x8000 // External Amplifier Power Down
|
||||
|
||||
#define GEODEAUDIO_PWR_D0 0x0000
|
||||
#define GEODEAUDIO_PWR_D1 GEODEAUDIO_PWR_EXTOFF
|
||||
#define GEODEAUDIO_PWR_D2 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_D3 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_D4 GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3|GEODEAUDIO_PWR_PR4|GEODEAUDIO_PWR_PR5|GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7
|
||||
#define GEODEAUDIO_PWR_ANLOFF GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3 // Analog section OFF
|
||||
#define GEODEAUDIO_PWR_EXTOFF GEODEAUDIO_PWR_PR6|GEODEAUDIO_PWR_PR7 // HP amp and External Amplifier OFF
|
||||
#define GEODEAUDIO_PWR_D1_HAWK GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1|GEODEAUDIO_PWR_PR2|GEODEAUDIO_PWR_PR3|GEODEAUDIO_PWR_PR4
|
||||
#define GEODEAUDIO_PWR_DIGOFF GEODEAUDIO_PWR_PR0|GEODEAUDIO_PWR_PR1 // Digital section OFF
|
||||
|
||||
#define GEODEAUDIO_PWRUP_STEP1 0x0F00 // Clear EAPD,PR6 and AC-link to power up external and HP amp and Digital interface
|
||||
#define GEODEAUDIO_PWRUP_STEP2 0x0700 // Clear PR3 to power up Analog (Vref off)
|
||||
#define GEODEAUDIO_PWRUP_STEP3 0x0300 // Clear PR2 to power up Analog (Vref on)
|
||||
#define GEODEAUDIO_PWRUP_STEP4 0x0100 // Clear PR1 to power up DAC
|
||||
#define GEODEAUDIO_PWRUP_STEP5 0x0000 // Clear PR0 to power up ADC
|
||||
|
||||
#define GEODEAUDIO_CODEC_POWER_ADC 0x0001
|
||||
#define GEODEAUDIO_CODEC_POWER_DAC 0x0002
|
||||
#define GEODEAUDIO_CODEC_POWER_ANL 0x0004
|
||||
#define GEODEAUDIO_CODEC_POWER_REF 0x0008
|
||||
|
||||
//
|
||||
// Device Power States
|
||||
//
|
||||
typedef enum _GEODEAUDIO_POWER_STATE
|
||||
{
|
||||
GEODEAUDIO_D0 = 0, // Full On: full power, full functionality
|
||||
GEODEAUDIO_D1, // Low Power On: fully functional at low power/performance
|
||||
GEODEAUDIO_D2, // Standby: partially powered with automatic wake
|
||||
GEODEAUDIO_D3, // Sleep: partially powered with device initiated wake
|
||||
GEODEAUDIO_D4, // Off: unpowered
|
||||
} GEODEAUDIO_POWER_STATE, *PGEODEAUDIO_POWER_STATE;
|
||||
|
||||
// PRD table flags
|
||||
#define PRD_JMP_BIT 0x20000000
|
||||
#define PRD_EOP_BIT 0x40000000
|
||||
#define PRD_EOT_BIT 0x80000000
|
||||
|
||||
typedef struct tagPRDEntry
|
||||
{
|
||||
unsigned long ulPhysAddr;
|
||||
unsigned long SizeFlags;
|
||||
} PRD_ENTRY, *PPRD_ENTRY;
|
||||
|
||||
|
||||
//
|
||||
// Command register bits
|
||||
//
|
||||
#define PCI_READS 0x00
|
||||
#define PCI_WRITES 0x08
|
||||
|
||||
#define ENABLE_BUSMASTER 0x01
|
||||
#define PAUSE_BUSMASTER 0x03
|
||||
#define STOP_BUSMASTER 0x00
|
||||
|
||||
#define CHANNEL0_PLAYBACK 0
|
||||
#define CHANNEL1_RECORD 1
|
||||
#define MAX_CHANNELS 2
|
||||
|
30
drivers/a5536/makefile
Normal file
30
drivers/a5536/makefile
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
CC = gcc
|
||||
FASM = e:/fasm/fasm.exe
|
||||
CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf
|
||||
LDRHD = -shared -T ld.x -s --file-alignment 32
|
||||
|
||||
INCLUDES = -I ../include
|
||||
|
||||
HFILES:= ../include/types.h \
|
||||
../include/syscall.h \
|
||||
geode.h \
|
||||
pci.h
|
||||
|
||||
SRC_DEP:=
|
||||
GEODE_SRC:= amd_geode.h
|
||||
|
||||
NAME:= geode
|
||||
GEODE:= geode.dll
|
||||
|
||||
all: $(GEODE)
|
||||
|
||||
$(GEODE): geode.obj $(SRC_DEP) $(HFILES) Makefile
|
||||
wlink name $(GEODE) SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @$(NAME).lk
|
||||
kpack.exe geode.dll geode.drv
|
||||
|
||||
geode.obj : geode.c $(SRC_DEP) $(HFILES) Makefile
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -o geode.obj geode.c
|
||||
|
||||
|
||||
|
182
drivers/a5536/pci.h
Normal file
182
drivers/a5536/pci.h
Normal file
@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
u16_t device;
|
||||
u16_t ChipSet;
|
||||
}PciChipset_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define VENDOR_ATI 0x1002
|
||||
|
||||
|
||||
#define PCI_CLASS_DISPLAY_VGA 0x0300
|
||||
/*
|
||||
* Under PCI, each device has 256 bytes of configuration address space,
|
||||
* of which the first 64 bytes are standardized as follows:
|
||||
*/
|
||||
#define PCI_VENDOR_ID 0x00 /* 16 bits */
|
||||
#define PCI_DEVICE_ID 0x02 /* 16 bits */
|
||||
#define PCI_COMMAND 0x04 /* 16 bits */
|
||||
#define PCI_COMMAND_IO 0x01 /* Enable response in I/O space */
|
||||
#define PCI_COMMAND_MEMORY 0x02 /* Enable response in Memory space */
|
||||
#define PCI_COMMAND_MASTER 0x04 /* Enable bus mastering */
|
||||
#define PCI_COMMAND_SPECIAL 0x08 /* Enable response to special cycles */
|
||||
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
|
||||
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
|
||||
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
|
||||
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
|
||||
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
|
||||
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
|
||||
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
|
||||
|
||||
#define PCI_STATUS 0x06 /* 16 bits */
|
||||
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
|
||||
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
|
||||
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
|
||||
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
|
||||
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
|
||||
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
|
||||
#define PCI_STATUS_DEVSEL_FAST 0x000
|
||||
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
|
||||
#define PCI_STATUS_DEVSEL_SLOW 0x400
|
||||
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
|
||||
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
|
||||
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
|
||||
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
|
||||
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
|
||||
|
||||
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
|
||||
#define PCI_REVISION_ID 0x08 /* Revision ID */
|
||||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
|
||||
#define PCI_HEADER_TYPE_NORMAL 0
|
||||
#define PCI_HEADER_TYPE_BRIDGE 1
|
||||
#define PCI_HEADER_TYPE_CARDBUS 2
|
||||
|
||||
#define PCI_BIST 0x0f /* 8 bits */
|
||||
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
|
||||
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
|
||||
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
|
||||
|
||||
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
|
||||
#define PCI_CB_CAPABILITY_LIST 0x14
|
||||
/* Capability lists */
|
||||
|
||||
#define PCI_CAP_LIST_ID 0 /* Capability ID */
|
||||
#define PCI_CAP_ID_PM 0x01 /* Power Management */
|
||||
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
|
||||
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
|
||||
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
|
||||
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
|
||||
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
|
||||
#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
|
||||
#define PCI_CAP_ID_HT 0x08 /* HyperTransport */
|
||||
#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */
|
||||
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
|
||||
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
|
||||
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
|
||||
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
|
||||
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
|
||||
#define PCI_CAP_SIZEOF 4
|
||||
|
||||
|
||||
/* AGP registers */
|
||||
|
||||
#define PCI_AGP_VERSION 2 /* BCD version number */
|
||||
#define PCI_AGP_RFU 3 /* Rest of capability flags */
|
||||
#define PCI_AGP_STATUS 4 /* Status register */
|
||||
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
|
||||
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
|
||||
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
|
||||
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
|
||||
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
|
||||
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
|
||||
#define PCI_AGP_COMMAND 8 /* Control register */
|
||||
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
|
||||
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
|
||||
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
|
||||
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
|
||||
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
|
||||
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
|
||||
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
|
||||
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
|
||||
#define PCI_AGP_SIZEOF 12
|
||||
|
||||
|
||||
#define PCI_MAP_REG_START 0x10
|
||||
#define PCI_MAP_REG_END 0x28
|
||||
#define PCI_MAP_ROM_REG 0x30
|
||||
|
||||
#define PCI_MAP_MEMORY 0x00000000
|
||||
#define PCI_MAP_IO 0x00000001
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE 0x00000007
|
||||
#define PCI_MAP_IO_TYPE 0x00000003
|
||||
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
|
||||
#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
|
||||
#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
|
||||
#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
|
||||
#define PCI_MAP_MEMORY_CACHABLE 0x00000008
|
||||
#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ATTR_MASK 0x00000003
|
||||
|
||||
#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
|
||||
#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
|
||||
|
||||
#define PCI_MAP_IS64BITMEM(b) \
|
||||
(((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
|
||||
|
||||
#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
|
||||
#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1))
|
||||
#define PCIGETMEMORY64(b) \
|
||||
(PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32))
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
|
||||
#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
|
||||
|
||||
#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
|
||||
#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
|
||||
|
||||
#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
|
||||
|
||||
|
||||
#ifndef PCI_DOM_MASK
|
||||
# define PCI_DOM_MASK 0x0ffu
|
||||
#endif
|
||||
#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu)
|
||||
|
||||
#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \
|
||||
(((d) & 0x00001fu) << 11) | \
|
||||
(((f) & 0x000007u) << 8))
|
||||
|
||||
#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK))
|
||||
#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11)
|
||||
#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
|
||||
#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8)
|
||||
|
||||
|
||||
typedef unsigned int PCITAG;
|
||||
|
||||
extern inline PCITAG
|
||||
pciTag(int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
const PciChipset_t *PciDevMatch(u16_t dev,const PciChipset_t *list);
|
||||
u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min);
|
||||
|
||||
#define PCI_ANY_ID (~0)
|
||||
|
||||
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d))!=-1)
|
Loading…
Reference in New Issue
Block a user