瑞昱 PC 蜂鸣器隐藏寄存器¶
此文件记录了“PC 蜂鸣器隐藏寄存器”,该寄存器存在于某些瑞昱 HDA 编解码器中,并控制一个多路复用器和一对直通混音器,这些混音器可以在引脚之间路由音频,但它们本身不会暴露为 HDA 小部件。据我所知,这些隐藏的路由旨在为输出路径中没有混音器小部件的编解码器提供灵活的 PC 蜂鸣器输出。我不明白为什么将混音器隐藏在未公开的供应商寄存器后面比将其直接暴露为小部件更容易。
寄存器描述¶
该寄存器通过 NID 20h 上的处理系数 0x36 访问。下面未标识的位对我的机器(戴尔 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 蜂鸣器线路(来自内部蜂鸣器发生器,当使用 NID 01h 上的设置蜂鸣器生成动词启用时,否则来自外部 PCBEEP 引脚)。当不为零时,改为暴露耳机插孔(或某些机器上的线路输入)。如果选择 PC 蜂鸣器,则 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 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)<
背景¶
所有瑞昱 HDA 编解码器都有一个供应商定义的小部件,其节点 ID 为 20h,它提供对一组寄存器的访问,这些寄存器控制各种编解码器功能。寄存器通过标准 HDA 处理系数动词(设置/获取系数索引,设置/获取处理系数)读取和写入。该节点在公共数据手册的动词列表中被命名为“瑞昱供应商寄存器”,除此之外,它完全没有记录。
这个特定的寄存器,在系数 0x36 处暴露并由瑞昱的提交命名,值得注意:与大多数似乎控制不在 HDA 规范范围内的详细放大器参数的寄存器不同,它控制音频路由,该路由本可以使用标准 HDA 混音器和选择器小部件轻松定义。
具体来说,它在节点 ID (NID) 为 1Ah 的输入引脚小部件的两个源之间进行选择:小部件的信号可以来自音频插孔(在我的笔记本电脑 Dell XPS 13 9350 上,它是耳机插孔,但瑞昱提交中的注释表明,它在某些机器上可能是线路输入)或来自 PC 蜂鸣器线路(该线路本身在编解码器的内部蜂鸣器发生器和外部 PCBEEP 引脚之间多路复用,具体取决于是否通过 NID 01h 上的动词启用了蜂鸣器发生器)。此外,它可以将该信号(带有可选放大)混合到 21h 和/或 14h 输出引脚。
寄存器的重置值为 0x3717,对应于 1Ah 上的 PC 蜂鸣器,然后将其放大并混合到耳机和扬声器中。这不仅违反了 HDA 规范,该规范规定“[供应商定义的蜂鸣器输入引脚] 连接只能在断言链路复位 (RST#) 时保持”,这意味着如果我们关心 1Ah 否则会暴露的输入,或者如果 PCBEEP 走线屏蔽不良并拾取机箱噪声(这两种情况在我的机器上都是如此),我们就不能忽略该寄存器。
不幸的是,有很多方法可以使此寄存器配置错误。Linux 似乎经历了其中的大多数。首先,寄存器在 S3 挂起后重置:从现有代码判断,并非所有供应商寄存器都是这种情况,这导致了一些修复,这些修复改善了冷启动时的行为,但在挂起后不会持续。其他修复已成功地将 1Ah 输入从 PC 蜂鸣器切换开,但未能禁用两个回路路径。在我的机器上,这意味着耳机输入被放大并环回到耳机输出,耳机输出使用完全相同的引脚!正如你所预料的那样,这会导致可怕的耳机噪声,其特征由 1Ah 增益控制控制。(如果你在线上看到通过更改 ALSA 中的“耳机麦克风增益”来修复 XPS 13 耳机噪声的说明,现在你就知道原因了。)
此信息是通过对 ALC256 编解码器的行为进行黑盒逆向工程获得的,不能保证是正确的。它也可能适用于 ALC255、ALC257、ALC235 和 ALC236,因为这些编解码器似乎与 ALC256 非常接近。(它们都共享一个初始化函数。)此外,根据 patch_realtek.c
中的现有修复,其他编解码器(如 ALC225 和 ALC285)也具有此寄存器,但这些编解码器的特定数据(例如,节点 ID、位位置、引脚映射)可能与我在此处描述的不同。