AC97: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
Line 28: Line 28:
|-
|-
| 0x1E || MIC_GAIN || Set Gain of Microphone || word
| 0x1E || MIC_GAIN || Set Gain of Microphone || word
|-
| 0x28 || EXT_ID || Supported extended functions || word
|-
| 0x2A || EXT_CTRL || Enabling extended functions || word
|-
| 0x2C || EXT_FRONT_RATE || Sample rate of front speaker || word
|-
|-
|}
|}

Revision as of 08:25, 26 January 2021

This page is a work in progress.
This page may thus be incomplete. Its content may be changed in the near future.

AC'97 is an audio codec standard developed by Intel Architecture Labs in 1997.

Detecting AC97 sound card

Sound card is connected into PCI with class 0x04 and subclass 0x01. If you found sound card you can check VendorID and DeviceID if it is supporting AC97. But, because today is used Intel HD Audio cards whose has subclass 0x03, you can probably expect every sound card with subclass 0x01 is sound card compatibile with AC97. AC97 use four BARs, but we need only BAR0 - Native Audio Mixer Base Address and BAR1 - Native Audio Bus Master Base Address. Important notice is that these BARs can be I/O or MMIO. Before any work with card, you must set bit 0 and bit 2 in PCI Command Register for right functionality.

Native Audio Mixer registers

Here is list of all useful registers of BAR0 base address.

Offset Name Description Lenght
0x00 RESET Reset Register word
0x02 MASTER_VOL Set Master Output Volume word
0x0E MIC_VOL Set Microphone Volume word
0x18 PCM_VOL Set Output Volume of PCM patterns word
0x1A REC_SLC Select Input Device word
0x1C REC_GAIN Set Input Gain word
0x1E MIC_GAIN Set Gain of Microphone word
0x28 EXT_ID Supported extended functions word
0x2A EXT_CTRL Enabling extended functions word
0x2C EXT_FRONT_RATE Sample rate of front speaker word

Native Audio Bus Master registers

Here is list of all useful registers of BAR1 base address.

Offset Name Description Lenght
0x00 PCM INPUT REGISTERS NABM register box for PCM IN below
0x10 PCM OUTPUT REGISTERS NABM register box for PCM OUT below
0x20 MICROPHONE INPUT REGISTERS NABM register box for Microphone below
0x2C GLOBAL_CTL Global Control Register dword
0x30 GLOBAL_STS Global Status Register dword

NABM register box contains these registers:

Offset Name Description Lenght
0x00 BUFFER_DSC_ADDR Physical Address of Buffer Descriptor List dword
0x04 CUR_ENTRY_VAL Number of Actual Processed Buffer Descriptor Entry byte
0x05 LAST_VALID_ENTRY Number of all Descriptor Entries byte
0x06 TRANSFER_ STS Status of Transferring Data word
0x08 CUR_IDX_PROC_SAMPLES Number of Transferred Samples in Actual Processed Entry word
0x0A PRCSD_ENTRY Number of Actual Processed Buffer Entry byte
0x0B BUFFER_CNT Most Important Register for controlling Transfers byte

Describe of NABM registers

NABM registers contains Global Control and Status, so it is better to describe it as first.

0x2C Global Control

Bit Type Name Description
0 RW Global Interrupt Enable(GIE) 0=Disable Interrupts 1=Enable Interrupts
1 RW Cold reset 0=Device is in reset and can not be used 1=Resume to operational state
2 RW Warm reset
3 RW Shut down 0=Device is powered 1=Shut down
6:4 RW (you do not need this bits)
19:7 RO Reserved
21:20 RW Channels for PCM Output 00=2 channels 01=4 channels 10=6 channels 11=Reserved
23:22 RW PCM Output mode 00=16 bit samples 01=20 bit samples

0x30 Global Status

Bit Type Name Description
21:20 RO Channel capabilites 00=2 channels 01=4 channels 10=6 channels 11=Reserved
23:22 RO Sample capabilites 01=16 and 20 bit samples are supported Other=Reserved, only 16 bit samples supported

This register contains much more bytes, but in fact you probably do not need it.

0x00 0x10 0x20 Buffer Descriptor Base Address

Bit Type Name Description
2:0 RO Hardwired to 0
31:3 RW Base Address Physical base address of Buffer Descriptor List

0x04 0x14 0x24 Current Processed Entry

Bit Type Name Description
4:0 RW Current Entry Number of Buffer Entry whose is actually processed
7:5 RO Hardwired to 0

0x05 0x15 0x25 Last Valid Entry

Bit Type Name Description
4:0 RW Last Entry Number of last Buffer Entry whose will be processed
7:5 RO Hardwired to 0

0x05 0x15 0x25 Transfer Status

Bit Type Name Description
0 RO DMA controller status 0=Transferring data 1=Halted
1 RO End of transfer 0=Current Entry not equal to Last Valid Entry 1=CE equal to LVE
2 R/WC Last Buffer Entry transfered Interrupt Software clears this bit writing 1 to it 1=Interrupt is firing
3 R/WC IOC Interrupt Software clears this bit writing 1 to it 1=Interrupt is firing
4 R/WC Fifo ERROR Interrupt Software clears this bit writing 1 to it 1=Interrupt is firing
15:5 RO Reserved

If you get some interrupt, you must clear this register by write value 0x1C otherwise the interrupt will be fired forever.

0x08 0x18 0x28 Position in Current Entry

Bit Type Name Description
15:0 R0 Number of transferred data Number of samples whose was transfered from actual processed Entry

0x0A 0x1A 0x2A Prefetched Entry

Bit Type Name Description
4:0 RW Prefetched Entry Number of prefetched Buffer Entry
7:5 RO Hardwired to 0

0x0B 0x1B 0x2B Transfer Control

Bit Type Name Description
0 RW DMA controller control 0=Pause transferring 1=Transfer sound data
1 RW Reset 0=Remove reset condition 1=Reset this NABM register box, this bit is selfcleared
2 RW Last Buffer Entry Interrupt enable 0=Diasble interrupt 1=Enable interrupt
3 RW IOC Interrupt enable 0=Diasble interrupt 1=Enable interrupt
4 RW Fifo ERROR Interrupt enable 0=Diasble interrupt 1=Enable interrupt
7:5 RO Reserved

For IOC interrupt see below part Buffer Descriptor List.

Describe of NAM registers

0x00 Reset Register

Writing any value info this register caused Register reset, what means that all NAM registers are changed into their default value.

0x02 Master Volume

Bit Type Name Description
5:0 RW Volume of right channel Number*1,5=Volume in decibels
7:6 RO Hardwired to 0
13:8 RW Volume of left channel Number*1,5=Volume in decibels
14 RO Hardwired to 0
15 RW Mute 1=Mute Sound

0 db means loudest output, 94,5 db means quietest output, mute bit set means no sound. Default value of this register is 0x8000.

0x0E Microphone Volume(gain)

Bit Type Name Description
4:0 RW Microphone gain Every step mean 1,5 db, see below
5 RO Hardwired to 0
6 RW 20 db 1=Add 20 db of volume(gain)
14:7 RO Hardwired to 0
15 RW Mute 1=Mute Sound

01000b means 0 db, so 00000b means 12 db, 11111b means -34,5 db and mute bit set means no sound. Default value of this register is 0x8008.

0x18 PCM output volume

Bit Type Name Description
4:0 RW Volume of right channel Every step mean 1,5 db, see below
7:5 RO Hardwired to 0
12:8 RW Volume of left channel Every step mean 1,5 db, see below
14:3 RO Hardwired to 0
15 RW Mute 1=Mute Sound

01000b means 0 db, so 00000b means 12 db, 11111b means -34,5 db and mute bit set means no sound. Default value of this register is 0x8808.

0x1A Select record input device

Only one usable values of this register is 0x0000 what means inbuilt Microphone input and 0x0303 what means AUX input(for extern microphone).

0x1C Record Gain

Bit Type Name Description
3:0 RW Gain of right channel Number*1,5=Volume in decibels
7:4 RO Hardwired to 0
11:8 RW Gain of left channel Number*1,5=Volume in decibels
14:2 RO Hardwired to 0
15 RW Mute 1=Mute Sound

0 db means max gain, 22,5 db means quietest gain, mute bit set means no gain. Default value of this register is 0x8000. This register is for recording sound something like Master Volume is for playing sound.

0x1C Record Gain of Microphone

Bit Type Name Description
3:0 RW Gain of right channel Number*1,5=Volume in decibels
7:4 RO Hardwired to 0
11:8 RW Gain of left channel Number*1,5=Volume in decibels
14:2 RO Hardwired to 0
15 RW Mute 1=Mute Sound

0 db means max gain, 22,5 db means quietest gain, mute bit set means no gain. Default value of this register is 0x8000.

Buffer Descriptor List

When you have sound data is memory, you must describe it in Buffer Descriptor List. Every entry of list have following format:

Offset Description Lenght
0x00 Physical Address to sound data in memory dword
0x04 Lenght of sound data-1 word
0x06 Bit 15=Interrupt fired when data from this entry is transferred Bit 14=Last entry of buffer, stop playing Other bits=Reserved word

Buffer can have max 32 entries. Every entry can transfer max 0xFFFF samples(write value 0xFFFE to lenght entry), but you must have in mind that one sample mean samples of all channels whose are use. So if you have 2 channels 16 bit audio, value 0xFFFE means that (2 bytes pre sample*2 channels*0xFFFF)=256 KB is transfered. Default are samples in 16 bit patterns, stored in 16 bit boxes, but AC97 can also support 20 bit quality. 20 bit pattern is stored in dwords in higher bytes. If entry have set bit 15(called IOC) after succesful transfer of all data from entry is fired interrupt. If you want use it, be sure that IOCE bit in BUFFER_CNT register is set. If is set bit 14(called BUP) it means that this entry is last from this list and AC97 stop playing sound after trasfering this entry.

Using AC97 sound card

In initalization of sound card you must resume card from cold reset and set power for it. It can be done by write value 0x2 to Global Control register if you do not want interrupts, or 0x3 if you want interrupts. After this, you should write any value to NAM reset register to set all NAM register to their defaults. After this, you can read card capability info from Global Status register what means how many channels it suport and if is 20 bit audio samples supported. Now is sound card ready to use.

Playing sound

Playing sound throught AC97 is easy as one, two, three:

  • Set Master Volume and PCM output volume
  • Load sound data to memory and describe it in Buffer Descriptor List
  • Set reset bit of output channel(NABM transfer control register 0x1B, value 0x2) and wait for card will clear it
  • Write physical position of BDL to NABM register 0x10(output BDL address register)
  • Write number of buffer entries to NABM register 0x15
  • Set bit for transfering data - NABM transfer control register 0x1B, value 0x1

Now wait for interrupt if you use it, do not forget to clear status register by write value 0x1C to it, if you do not use interrupt, you can pool for bit 1 of NABM transfer status.

Stop and resuming sound

Stopping sound is easy, you clear bit 0 in NABM transfer control register. If you want to resume playing, you can easy set this bit back. If you want absoultly stop sound or reprogram playing other sound, you must stop transferring data and after this reset this NABM register box(bit 1 in NABM transfer control register 0x1B).

See Also

External Links