AC97: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
General improvement of article
 
(21 intermediate revisions by 5 users not shown)
Line 1:
{{In Progress}}
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 isare mostly used Intel HD Audio cards whosewhich hashave subclass 0x03, you can probably expect that 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 thatBoth these BARs can beare I/O or MMIO. Before any work with card, you must set bit 0 and bit 2 in [https://wiki.osdev.org/PCI#Command_Register PCI Command Register] forto enable I/O space and rightbus functionalitymastering.
 
==Native Audio Mixer registers==
Line 11 ⟶ 10:
{| {{wikitable}}
! Offset
! Description
! Length
|-
| 0x00 || Reset Register/Capabilities || word
|-
| 0x02 || Set Master Output Volume || word
|-
| 0x04 || Set AUX Output Volume || word
|-
| 0x0E || Set Microphone Volume || word
|-
| 0x18 ||| Set PCM Output Volume || word
|-
| 0x1A || Select Input Device || word
|-
| 0x1C || Set Input Gain || word
|-
| 0x1E || Set Gain of Microphone || word
|-
| 0x28 || Extended capabilities || word
|-
| 0x2A || Control of extended capabilities || word
|-
| 0x2C || Sample rate of PCM Front DAC || word
|-
| 0x2E || Sample rate of PCM Surr DAC || word
|-
| 0x30 || Sample rate of PCM LFE DAC || word
|-
| 0x32 || Sample rate of PCM L/R ADC || word
|-
|}
 
Here is description for all registers:
 
===0x00 Reset Register===
Writing any value info this register will cause Register reset, what means that all NAM registers will be changed into their default value. When you read this register, it works as Capabilities register. Most useful is bit 4, that indicates, that sound card have headphone output.
 
===0x02 Master Volume / 0x04 AUX Output Volume===
{| {{wikitable}}
! Bit
! Type
! Name
! Description
! Lenght
|-
| 4:0 / 5:0 || RW || Volume of right channel || Number*1,5=Volume in decibels
| 0x00 || RESET || Reset Register || word
|-
| 0x027:6 || MASTER_VOLRO || SetHardwired Masterto Output Volume0 || word
|-
| 12:8 / 13:8 || RW || Volume of left channel || Number*1,5=Volume in decibels
| 0x0E || MIC_VOL || Set Microphone Volume || word
|-
| 0x1814 || PCM_VOLRO || SetHardwired Outputto Volume of PCM patterns0 || word
|-
| 0x1A15 || REC_SLCRW || Select Input DeviceMute || word1=Mute Sound
|-
|}
| 0x1C || REC_GAIN || Set Input Gain || word
 
0 db means loudest output, 34,5 / 94,5 db means quietest output, mute bit set means no sound. This register support either 32 or 64 steps of changing volume. You can find supported number of steps by setting bit 5 and bit 13. If these bits remains set, you can use 64 steps, if no, you can use only 32 steps.
 
Master Volume register controls volume of speaker.
 
AUX Output Volume register can control volume of one of three different types of devices (see part 5.2.1 in specification) which is hardwired by manufacturer. You have to find which one is it. If after register reset this register contain value 0x8000 and Capabilities register have set bit 4, it mean that this register controls output volume of headphone.
 
===0x0E Microphone Volume (gain)===
{| {{wikitable}}
! Bit
! Type
! Name
! Description
|-
| 0x1E4:0 || MIC_GAINRW || Set Gain of Microphone gain || wordEvery 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===
{| {{wikitable}}
! 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. Volume set in this register will affect all outputs that plays PCM data.
 
===0x1A Select record input device===
Only usable values of this register are 0x0000 (inbuilt Microphone input) and 0x0303 (AUX input - external microphone).
 
===0x1C Record Gain / 0x1E Record Gain of Microphone===
{| {{wikitable}}
! 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.
 
=== Extended capabilites registers ===
Some cards support more features. You have to check bits in Extended capabilities register to check whose features card support, and then enable them by setting same bits in Control of extended capabilities register.
 
Most useful feature is support for more sample rates than 48000. This feature have bit 0. If this bit is set in Extended capabilities register, you can activate it by setting bit 0 in Control of extended capabilities register. Then you can just write value of sample rate to four Sample rate registers. All card with this feature have to support sample rates 48000 and 44100 and optionally 32000, 22050, 16000, 11025 and 8000.
 
==Native Audio Bus Master registers==
Line 36 ⟶ 149:
{| {{wikitable}}
! Offset
! Name
! Description
! LenghtLength
|-
| 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
|-
|}
 
Every NABM register box containscontain these registers:
{| {{wikitable}}
! Offset
! Name
! Description
! LenghtLength
|-
| 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 Transferringtransferring Data || word
|-
| 0x08 || CUR_IDX_PROC_SAMPLES || Number of Transferredtransferred Samples in Actual Processed Entry || word
|-
| 0x0A || PRCSD_ENTRY || Number of Actualnext Processedprocessed Buffer Entry || byte
|-
| 0x0B || BUFFER_CNTTransfer || Most Important Register for controlling TransfersControl || byte
|-
|}
 
==DescribeHere ofare NABMdescriptions of registers==:
 
NABM registers contains Global Control and Status, so it is better to describe it as first.
===0x2C Global Control===
{| {{wikitable}}
Line 84 ⟶ 195:
! 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
Line 115 ⟶ 226:
|}
 
This register contains much more bytesbits, but in fact you probably do not need itthem.
 
===0x00 0x10 0x20 Buffer Descriptor Base Address===
Line 137 ⟶ 248:
! Description
|-
| 4:0 || RWRO || Current Entry || Number of Buffer Entry whosewhich is actually processed
|-
| 7:5 || RO || Hardwired to 0 ||
Line 150 ⟶ 261:
! Description
|-
| 4:0 || RW || Last Entry || Number of last Buffer Entry whosewhich will be processed
|-
| 7:5 || RO || Hardwired to 0 ||
Line 156 ⟶ 267:
|}
 
===0x050x06 0x150x16 0x250x26 Transfer Status===
{| {{wikitable}}
! Bit
Line 165 ⟶ 276:
| 0 || RO || DMA controller status || 0=Transferring data 1=Halted
|-
| 1 || RO || End of transfer || 0=Current Entry is not equal to Last Valid Entry 1=CE is equal to LVE
|-
| 12 || R/WC || Last Buffer Entry transfered Interrupt || Software clears this bit writing 1 to it 1=Interrupt is firing
|-
| 13 || R/WC || IOC Interrupt || Software clears this bit writing 1 to it 1=Interrupt is firing
|-
| 14 || R/WC || Fifo ERROR Interrupt || Software clears this bit writing 1 to it 1=Interrupt is firing
|-
| 15:5 || RO || Reserved ||
Line 179 ⟶ 290:
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===
==Describe of NAM registers==
{| {{wikitable}}
===0x00 Reset Register===
! Bit
Writing any value info this register caused Register reset, what means that all NAM registers are changed into their default value.
! Type
! Name
! Description
|-
| 15:0 || RO || Number of transferred data || Number of samples which were transferred from currently processed entry
|-
|}
 
===0x0A 0x1A 0x2A Prefetched Entry===
{| {{wikitable}}
! Bit
! Type
! Name
! Description
|-
| 4:0 || RO || Prefetched Entry || Number of prefetched Buffer Entry
|-
| 7:5 || RO || Hardwired to 0 ||
|-
|}
 
===0x0B 0x1B 0x2B Transfer Control===
{| {{wikitable}}
! 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 cleared by card when reset is complete
|-
| 2 || RW || Last Buffer Entry Interrupt enable || 0=Disable interrupt 1=Enable interrupt
|-
| 3 || RW || IOC Interrupt enable || 0=Disable interrupt 1=Enable interrupt
|-
| 4 || RW || Fifo ERROR Interrupt enable || 0=Disable interrupt 1=Enable interrupt
|-
| 7:5 || RO || Reserved ||
|-
|}
 
For IOC interrupt see below part Buffer Descriptor List.
 
==Buffer Descriptor List==
When you have PCM sound data isin memory, you must describe itthem in Buffer Descriptor List. Every entry of list have following format:
 
{| {{wikitable}}
! Offset
! Description
! LenghtLength
|-
| 0x00 || Physical Address to sound data in memory || dword
|-
| 0x04 || LenghtNumber of soundsamples data-1in this buffer || 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
Line 199 ⟶ 353:
|}
 
Buffer canDescription haveList maxhas 32 entries. While adding entries, you have to roll over. Every entry can transfer maxup 0xFFFFto 0xFFFE samples(write. valueIf 0xFFFEinput tocontains lenghtmultiple entry)channels, butall youare mustcounted haveinto inthis mindvalue, thatso oneto sampleplay meanfive samplesframes offrom allPCM data with 2 channels, whoseyou arehave use.to Sowrite ifvalue 10. If you have 2 channels 16 bit audio, value 0xFFFE means that (2 bytes preper sample*20xFFFE) channels*0xFFFF)=256 128 KB iswill transfered. Default are samples in 16 bit patterns, stored in 16 bit boxes, but AC97 can also support 20 bitbe qualitytransferred. 20Programming bit pattern is stored in dwords in higher bytes. If entry have set bit 15(called IOC) after succesful transfernumber of allsamples datawith froman entryodd isnumber firedsuch interrupt.as If you want use it, be sure that IOCE bit in BUFFER_CNT register0xFFFF is set.not 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 entryallowed.
 
Default samples are 16 bit samples stored in words, but AC97 can also support 20 bit samples that are stored in dwords in higher bytes. If entry have set bit 15 (called IOC), after successful transfer of all data interrupt will be fired. 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 will stop playing sound after transferring this entry.
 
===Theory of Operation===
 
During playing back, The BDL is a simple ring buffer between the producer (driver code running on the CPU) and the consumer (AC97's DMA).
 
The producer keeps updating the contents of the sample buffers described by the BDL entries and optionally the BDL itself, and the write pointer (Last Valid Entry register at offset 0x5 in the BOX).
 
The consumer keeps reading the BDL entries, the contents of the sample buffers, the read pointer (Current Processed Entry at offset 0x4 in the BOX), and a second read pointer (Prefetched Entry at offset 0xA in the BOX).
 
Unlike HDA's stream DMAs which can keep running in cycles by themselves, AC97's DMA will stop if its read pointer catches up with the write pointer.
 
Thus the driver code should take care to keep the sample buffers updated and the write pointer sufficiently ahead of the DMA's read pointer to avoid any underrun or DMA stoppage. The driver should also take note of the auxiliary read pointer if it needs to update BDL entries, as the DMA can prefetch BDL entries and possible read stale sample buffers if the driver updated the BDL entries after the prefetching.
 
==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 writing value 0x2 to Global Control register if you do not want to use interrupts, or 0x3 if you want to use interrupts. After this, you should write any value to NAM Reset register to reset all NAM registers. After this, you can read card capability info from Global Status register to found out if 20 bit audio samples are supported and also check out bit 4 in NAM Capabilites register and value in AUX Output to find out if this sound card support headhone output. As last thing, set maximal volume for PCM Output by writing value 0 to this register. Now sound card is ready to use.
 
===Playing sound===
* Set volume of output you want to use - Master Volume register (NAM register 0x02) for speaker and if supported, AUX Output register (NAM register 0x04) for headphone
* Load sound data to memory and describe it in Buffer Descriptor List
* Set reset bit of output channel (NABM register 0x1B, value 0x2) and wait for card to clear it
* Write physical position of BDL to Buffer Descriptor Base Address register (NABM register 0x10)
* Write number of last valid buffer entry to Last Valid Entry register (NABM register 0x15)
* Set bit for transfering data (NABM register 0x1B, value 0x1)
 
Now wait for interrupt if you use it and 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 register. While playing, you have to fill entries that were already transferred and then update Last Valid Entry.
 
===Stop and resuming sound===
Stopping sound is easy, you only need to clear bit 0 in NABM transfer control register. If you want to resume playing, set this bit back. If you want absoultely stop sound or reprogram playing other sound, you must stop transferring data and reset this NABM register box (bit 1 in NABM Transfer Control register 0x1B). Resetting will set all registers in box to zero.
 
== See Also ==
=== Drivers ===
* [https://github.com/VendelinSlezak/BleskOS/blob/master/source/drivers/sound/ac97.c BleskOS AC97 driver (C code)]
=== External Links ===
* http://www.lowlevel.eu/wiki/AC97
* [http://www-inst.eecs.berkeley.edu/~cs150/Documents/ac97_r23.pdf Audio Codec '97 Specification]
* [https://www.intel.com/content/damwww/docus/manualen/io/io-controller-hub-7-hd-audio-ac97-manual.pdfhtml Intel ICH7 HDA/AC'97 Programmer's Reference Manual]
* [https://www.intel.com/assets/pdf/manual/252751.pdf Intel ICH5/ICH5R/ICH4 AC'97 Programmer's Reference Manual]
 
[[Category:Sound]]