Realtek PC Beep 隱藏暫存器¶
此檔案記錄了 “PC Beep 隱藏暫存器”,它存在於某些 Realtek HDA 編解碼器中,並控制一個多路複用器和一對直通混音器,這些混音器可以在引腳之間路由音訊,但本身不會作為 HDA 小部件公開。 據我所知,這些隱藏的路由旨在為沒有輸出路徑中的混音器小部件的編解碼器提供靈活的 PC Beep 輸出。 為什麼隱藏混音器比僅僅將其作為小部件公開更容易,我不知道。
暫存器描述¶
該暫存器透過 NID 20h 上的處理係數 0x36 訪問。 下面未標識的位對我的機器(Dell XPS 13 9350)沒有明顯的影響
MSB LSB
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |h|S|L| | B |R| | Known bits
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 1Ah 輸入選擇 (B): 2 位
當為零時,在 1Ah 引腳節點上公開 PC Beep 線(來自內部蜂鳴器發生器,當在 NID 01h 上使用 Set Beep Generation 動詞啟用時,或者來自外部 PCBEEP 引腳)。 當非零時,改為公開耳機插孔(或某些機器上的線路輸入)。 如果選擇了 PC Beep,則 1Ah 提升控制無效。
- 放大 1Ah 迴路,左 (L): 1 位
在將 1Ah 的左聲道混音到 h 和 S 位指定的輸出之前對其進行放大。 不影響暴露給其他小部件的 1Ah 的電平。
- 放大 1Ah 迴路,右 (R): 1 位
在將 1Ah 的右聲道混音到 h 和 S 位指定的輸出之前對其進行放大。 不影響暴露給其他小部件的 1Ah 的電平。
- 將 1Ah 迴路到 21h [低電平有效] (h): 1 位
當為零時,將 1Ah(可能具有放大,具體取決於 L 和 R 位)混音到 21h(我機器上的耳機插孔)。 混合訊號遵循 21h 上的靜音設定。
- 將 1Ah 迴路到 14h (S): 1 位
當為一時,將 1Ah(可能具有放大,具體取決於 L 和 R 位)混音到 14h(我機器上的內建揚聲器)。 混合訊號忽略 14h 上的靜音設定,並且只要 14h 配置為輸出,就存在。
路徑圖¶
1Ah 輸入選擇 (DIV 是在 NID 01h 上設定的 PC Beep 分頻器)
<Beep generator> <PCBEEP pin> <Headphone jack>
| | |
+--DIV--+--!DIV--+ {1Ah boost control}
| |
+--(b == 0)--+--(b != 0)--+
|
>1Ah (Beep/Headphone Mic/Line In)<
1Ah 到 21h/14h 的迴路
<1Ah (Beep/Headphone Mic/Line In)>
|
{amplify if L/R}
|
+-----!h-----+-----S-----+
| |
{21h mute control} |
| |
>21h (Headphone)< >14h (Internal Speaker)<
背景¶
所有 Realtek HDA 編解碼器都有一個供應商定義的小部件,其節點 ID 為 20h,它提供對控制各種編解碼器功能的暫存器組的訪問。 暫存器透過標準 HDA 處理係數動詞(Set/Get Coefficient Index, Set/Get Processing Coefficient)進行讀取和寫入。 該節點在公共資料表的動詞列表中被命名為 “Realtek Vendor Registers”,除此之外,完全沒有文件記錄。
這個特定的暫存器,在係數 0x36 處公開,並在 Realtek 的提交中命名,值得注意:與大多數似乎控制不在 HDA 規範範圍內的詳細放大器引數的暫存器不同,它控制音訊路由,音訊路由同樣可以使用標準 HDA 混音器和選擇器小部件來定義。
具體來說,它在節點 ID (NID) 為 1Ah 的輸入引腳小部件的兩個源之間進行選擇:小部件的訊號可以來自音訊插孔(在我的筆記型電腦 Dell XPS 13 9350 上,它是耳機插孔,但 Realtek 提交中的註釋表明它可能是某些機器上的線路輸入)或來自 PC Beep 線(它本身在編解碼器的內部蜂鳴器發生器和外部 PCBEEP 引腳之間進行多路複用,具體取決於是否透過 NID 01h 上的動詞啟用了蜂鳴器發生器)。 此外,它可以(透過可選的放大)將該訊號混合到 21h 和/或 14h 輸出引腳上。
暫存器的重置值為 0x3717,對應於 1Ah 上的 PC Beep,然後將其放大並混合到耳機和揚聲器中。 這不僅違反了 HDA 規範,該規範指出“[供應商定義的蜂鳴器輸入引腳]連線只能在 Link 重置 (RST#) 斷言時保持”,而且意味著如果我們關心 1Ah 可能公開的輸入或者 PCBEEP 走線遮蔽不良並拾取機箱噪聲(這兩種情況都在我的機器上)時,我們不能忽略該暫存器。
不幸的是,有很多方法可以錯誤地配置此暫存器。 似乎 Linux 已經經歷了其中的大多數方法。 例如,該暫存器在 S3 掛起後重置:從現有程式碼判斷,並非所有供應商暫存器都是這種情況,並且它導致了一些修復,這些修復改善了冷啟動時的行為,但在掛起後不會持續。 其他修復程式已成功將 1Ah 輸入從 PC Beep 切換出來,但未能停用兩個迴路路徑。 在我的機器上,這意味著耳機輸入被放大並回路到耳機輸出,耳機輸出使用完全相同的引腳! 正如您可能預期的那樣,這會導致可怕的耳機噪聲,其特徵由 1Ah 提升控制控制。 (如果您在網上看到透過在 ALSA 中更改 “Headphone Mic Boost” 來修復 XPS 13 耳機噪聲的說明,現在您知道原因了。)
這裡的資訊是透過對 ALC256 編解碼器的行為進行黑盒逆向工程獲得的,並且不能保證是正確的。 它可能也適用於 ALC255、ALC257、ALC235 和 ALC236,因為這些編解碼器似乎與 ALC256 密切相關。 (它們都共享一個初始化函式。) 此外,其他編解碼器(如 ALC225 和 ALC285)也具有此暫存器,從 patch_realtek.c 中的現有修復程式判斷,但這些編解碼器的特定資料(例如,節點 ID、位位置、引腳對映)可能與我在此處描述的不同。