I follow http://www.lowlevel.eu/wiki/AC97, but my AC97 driver is not playing sound. Sound card is on bus 0, device 4 and function 0.
Code: Select all
//NAM offsets
#define AC97_NAM_PORT_RESET 0x00
#define AC97_NAM_PORT_MASTER_VOLUME 0x02
#define AC97_NAM_PORT_MONO_VOLUME 0x06
#define AC97_NAM_PORT_PC_BEEP 0x0A
#define AC97_NAM_PORT_PCM_VOLUME 0x18
#define AC97_NAM_PORT_EXT_AUDIO_ID 0x28
#define AC97_NAM_PORT_EXT_AUDIO_STC 0x2A
#define AC97_NAM_PORT_EXT_FRONT_SPLRATE 0x2C
#define AC97_NAM_PORT_EXT_LR_SPLRATE 0x0032
//NABM offsets
#define AC97_NABM_PORT_POBDBAR 0x10
#define AC97_NABM_PORT_POLVI 0x15
#define AC97_NABM_PORT_POCONTROL 0x1B
#define AC97_NABM_PORT_GLB_CTRL_STAT 0x60
//BUFFERS
struct buffer_desc{
void *buffer;
unsigned short length;
int reserved : 14;
unsigned int bup : 1;
unsigned int ioc : 1;
} __attribute__((packed));
struct buffer_desc *BufDescList; //Buffer Descriptor List
uint16_t sound_buffer[65536];
void wait(int miliseconds) {
while(miliseconds>0) {
for(int i=0; i<10000; i++) {
inb(0x3F6); //wait
}
miliseconds--;
}
}
void ac97_init(uint16_t volume) {
pci_write(sound_card_bus, sound_card_device, sound_card_function, 0x04, (pci_get_command(sound_card_bus, sound_card_device, sound_card_function) | 5) );
//reset
outw(sound_card_nam_bar + AC97_NAM_PORT_RESET, 42);
outb(sound_card_nabm_bar + AC97_NABM_PORT_GLB_CTRL_STAT, 2);
wait(10);
//set volume
outw(sound_card_nam_bar + AC97_NAM_PORT_MASTER_VOLUME, (volume<<8) | volume);
outw(sound_card_nam_bar + AC97_NAM_PORT_MONO_VOLUME, volume);
outw(sound_card_nam_bar + AC97_NAM_PORT_PC_BEEP, volume);
outw(sound_card_nam_bar + AC97_NAM_PORT_PCM_VOLUME, (volume<<8) | volume);
wait(10);
//sample output rate
outw(sound_card_nam_bar + AC97_NAM_PORT_EXT_AUDIO_STC, (inw(sound_card_nam_bar + AC97_NAM_PORT_EXT_AUDIO_STC) | 1) );
wait(10);
outw(sound_card_nam_bar + AC97_NAM_PORT_EXT_FRONT_SPLRATE, 44100);
outw(sound_card_nam_bar + AC97_NAM_PORT_EXT_LR_SPLRATE, 44100);
wait(10);
}
void ac97_play_buffer(void) {
BufDescList[0].buffer=((uint32_t)(sound_buffer));
BufDescList[0].length=0xFFFE;
BufDescList[0].bup=1;
outl(sound_card_nabm_bar + AC97_NABM_PORT_POBDBAR, (uint32_t)(BufDescList));
outb(sound_card_nabm_bar + AC97_NABM_PORT_POLVI, 0);
outb(sound_card_nabm_bar + AC97_NABM_PORT_POCONTROL, 0x15);
}