更多关于HD-Audio驱动程序的说明

Takashi Iwai <tiwai@suse.de>

一般

HD-audio是AC97之后现代PC上新的板载音频组件标准。虽然Linux早已支持HD-audio,但新机器上经常出现问题。部分问题是由于BIOS损坏,其余是驱动程序实现的问题。本文档解释了HD-audio硬件的简要故障排除和调试方法。

HD-audio组件由两部分组成:控制器芯片和HD-audio总线上的编解码器芯片。Linux为所有控制器提供了一个单一的驱动程序,即snd-hda-intel。尽管驱动程序名称中包含了一个著名硬件供应商的名称,但它并非专门针对该供应商,而是适用于所有其他公司的控制器芯片。由于HD-audio控制器应该兼容,因此单一的snd-hda-驱动程序在大多数情况下都应能正常工作。但不出所料,存在一些特定于每种控制器类型的已知错误和问题。snd-hda-intel驱动程序对此进行了一些变通处理,如下所述。

一个控制器可能连接多个编解码器。通常,您会有一个音频编解码器,并可选地一个调制解调器编解码器。理论上,可能存在多个音频编解码器,例如用于模拟和数字输出,并且驱动程序可能因混音器元素冲突而无法正常工作。如果确实存在此类硬件,这将在未来得到修复。

snd-hda-intel驱动程序根据编解码器类型有几种不同的编解码器解析器。它有一个通用解析器作为备用,但迄今为止其功能相当有限。通常,编解码器特定的解析器(在patch_*.c中编码)用于编解码器特定的实现,而不是通用解析器。有关编解码器特定问题的详细信息将在后面的章节中解释。

如果您对HD-audio的深度调试感兴趣,请首先阅读HD-audio规范。该规范可以在Intel的网页上找到,例如:

HD-Audio控制器

DMA位置问题

控制器最常见的问题是DMA指针报告不准确。播放和捕获的DMA指针可以通过两种方式读取:通过LPIB寄存器或通过位置缓冲区映射。默认情况下,驱动程序尝试从IO映射的位置缓冲区读取,如果位置缓冲区似乎不活动,则回退到LPIB。然而,在某些设备上,这种检测并不完美。在这种情况下,您可以通过position_fix选项更改默认方法。

position_fix=1表示明确使用LPIB方法。position_fix=2表示使用位置缓冲区。position_fix=3表示使用两种方法的组合,某些VIA控制器需要。捕获流位置通过比较LPIB和位置缓冲区值来校正。position_fix=4是所有控制器可用的另一种组合,它将LPIB用于播放流,将位置缓冲区用于捕获流。position_fix=5目前是Intel平台特有的,适用于Skylake及以后的平台。它应用延迟计算以实现精确的位置报告。position_fix=6用于使用固定的FIFO大小校正位置,主要针对最近的AMD控制器。0是所有其他控制器的默认值,即上述的自动检查并回退到LPIB。如果您遇到声音重复的问题,此选项可能会有所帮助。

除此之外,已知每个控制器在唤醒时间方面都存在问题。它会在实际处理缓冲区数据之前几采样唤醒。这导致了很多问题,例如使用ALSA dmix或JACK时。从2.6.27内核开始,驱动程序会给唤醒时间添加一个人为延迟。此延迟通过bdl_pos_adj选项控制。

bdl_pos_adj为负值(默认值)时,它会根据控制器芯片被分配一个合适的值。对于英特尔芯片,它将是1,而对于其他芯片,它将是32。通常这会奏效。只有在它不起作用并收到警告消息时,才应该将此参数更改为其他值。

编解码器探测问题

一个不那么常见但更严重的问题是编解码器探测。当BIOS错误地报告可用的编解码器插槽时,驱动程序会感到困惑,并尝试访问不存在的编解码器插槽。这通常会导致完全的混乱,并破坏与编解码器芯片的进一步通信。症状通常表现为如下错误消息:

hda_intel: azx_get_response timeout, switching to polling mode:
      last cmd=0x12345678
hda_intel: azx_get_response timeout, switching to single_cmd mode:
      last cmd=0x12345678

第一行是警告,通常相对无害。这意味着编解码器响应没有通过IRQ通知。驱动程序使用显式轮询方法读取响应。这会带来非常轻微的CPU开销,但您不太可能注意到它。

然而,第二行是致命错误。如果发生这种情况,通常意味着情况确实很糟糕。最有可能的情况是您正在访问一个不存在的编解码器插槽。

因此,如果出现第二条错误消息,请尝试通过probe_mask选项缩小探测的编解码器插槽范围。它是一个位掩码,每个位对应一个编解码器插槽。例如,要仅探测第一个插槽,请传递probe_mask=1。对于第一个和第三个插槽,请传递probe_mask=5(其中5 = 1 | 4),依此类推。

然而,从2.6.29内核开始,驱动程序拥有更健壮的探测方法,因此这种错误可能很少发生。

在BIOS损坏的机器上,有时您需要强制驱动程序探测硬件未报告使用的编解码器插槽。在这种情况下,请将probe_mask选项的第8位(0x100)打开。然后将剩下的8位作为编解码器插槽无条件地进行探测。例如,probe_mask=0x103将强制探测编解码器插槽0和1,无论硬件报告什么。

中断处理

HD-audio驱动程序从2.6.33内核开始默认使用MSI(如果可用),因为MSI在某些机器上表现更好,并且通常对性能更有利。然而,Nvidia控制器在使用MSI时表现出糟糕的退化(特别是在与AMD芯片组结合时),因此我们为它们禁用了MSI。

似乎还有其他设备无法与MSI配合使用。如果您在最新内核中发现声音质量下降(卡顿等)或死锁,请尝试传递enable_msi=0选项以禁用MSI。如果它有效,您可以将已知不良设备添加到hda_intel.c中定义的黑名单。在这种情况下,请向上游开发者报告并提供补丁。

HD-Audio编解码器

模型选项

HD-audio驱动程序最常见的问题是编解码器功能不受支持或设备配置不匹配。大多数编解码器特定代码都有几个预设模型,用于覆盖BIOS设置或提供更全面的功能。

驱动程序检查PCI SSID并遍历静态配置表,直到找到任何匹配的条目。如果您有一台新机器,您可能会看到如下消息:

hda_codec: ALC880: BIOS auto-probing.

同时,在早期版本中,您可能会看到一条类似的消息

hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...

即使你看到这样的信息,不要惊慌。深吸一口气,拿着你的毛巾。首先,这是一条信息性消息,不是警告,也不是错误。这意味着你的设备的PCI SSID没有列在已知的预设模型(白)列表中。但是,这并不意味着驱动程序损坏了。许多编解码器驱动程序提供了基于BIOS设置的自动配置机制。

HD-audio编解码器通常有“pin”部件,BIOS会设置每个pin的默认配置,指示位置、连接类型、插孔颜色等。HD-audio驱动程序可以根据这些默认配置值猜测正确的连接。然而——一些编解码器支持代码,例如patch_analog.c,还不支持自动探测(截至2.6.28)。而且,BIOS经常,是的,非常经常损坏。它设置了错误的值并搞砸了驱动程序。

提供预设模型(或最近称为“fix-up”)基本上是为了克服这种情况。当在白名单中找到匹配的预设模型时,驱动程序将采用该预设的静态配置,并具有正确的引脚设置等。因此,如果您有一台较新的机器,其PCI SSID(或编解码器SSID)与现有机器略有不同,您很有可能重用相同的模型。您可以通过model选项指定预设模型,而不是通过PCI(和编解码器)SSID查找。

model选项的可用值取决于编解码器芯片。从编解码器proc文件(参见下面的“Codec Proc-File”部分)检查您的编解码器芯片。它将显示您的编解码器芯片的供应商/产品名称。然后,请参阅HD-Audio编解码器特定型号文件,即HD-audio驱动程序部分。您可以找到编解码器列表和属于每个编解码器的model选项。例如,对于Realtek ALC262编解码器芯片,对于与三星Q1 Ultra兼容的设备,请传递model=ultra

因此,对于任何全新的、不支持且无法工作的HD-audio硬件,您首先要做的就是检查HD-audio编解码器和几种不同的model选项值。如果幸运的话,其中一些可能非常适合您的设备。

有几个特殊的模型选项值

  • 当传入“nofixup”时,编解码器解析器中的设备特定修复程序将被跳过。

  • 当传入generic时,编解码器特定解析器将被跳过,只使用通用解析器。

从5.15内核开始引入的一种新式模型选项是,以model=XXXX:YYYY的形式传递PCI或编解码器SSID,其中XXXX和YYYY分别是十六进制数字的子供应商和子设备ID。这是一种将设备别名为另一个设备的方式;当给出此形式时,驱动程序将把该SSID作为参考来查找异常表。这在目标异常未列在模型表中时特别有用。例如,传递model=103c:8862将应用于HP ProBook 445 G8的异常(撰写本文时未在模型表中找到),只要该设备由同一驱动程序等效处理。

扬声器和耳机输出

HD-audio最常见(也最明显)的bug之一是内置扬声器或耳机插孔(或两者)无声输出。一般来说,您应该首先尝试耳机输出。扬声器输出通常需要更多的额外控制,例如外部放大器位。因此,耳机输出成功的机会稍大一些。

在提交错误报告之前,请仔细检查混音器是否设置正确。最新版本的snd-hda-intel驱动程序主要提供“主音量”控制以及“前置”音量(其中“前置”表示前置声道)。此外,还可能有单独的“耳机”和“扬声器”控制。

扬声器输出也是如此。某些编解码器上可能有一个“外部放大器”开关。如果存在,请将其打开。

另一个相关问题是耳机插入时扬声器输出的自动静音。此功能在大多数情况下都已实现,但并非所有预设模型或编解码器支持代码都支持。

无论如何,如果您有此类问题,请尝试不同的模型选项。一些其他模型可能更匹配,并为您提供更多匹配的功能。如果所有可用模型都无效,请发送错误报告。有关详细信息,请参阅错误报告部分。

如果你是受虐狂,想要调试驱动程序问题,请注意以下几点:

  • 扬声器(也包括耳机)输出通常需要外部放大器。这通常可以通过EAPD verb或某个GPIO进行设置。如果编解码器引脚支持EAPD,您可以通过SET_EAPD_BTL verb(0x70c)获得更好的机会。在其他情况下,GPIO引脚(通常是GPIO0或GPIO1)可能会打开/关闭EAPD。

  • 某些Realtek编解码器需要特殊的供应商特定系数才能打开放大器。参见patch_realtek.c。

  • IDT编解码器可能在每个模拟引脚上都有额外的电源启用/禁用控制。参见patch_sigmatel.c。

  • 极少数情况下,某些设备在触发之前不接受引脚检测动词。发出GET_PIN_SENSE动词(0xf09)可能导致编解码器通信停滞。一些示例可以在patch_realtek.c中找到。

捕获问题

捕获问题通常是由于混音器设置缺失造成的。因此,在提交错误报告之前,请确保正确设置混音器。例如,除了正确的“捕获源”或“输入源”选择之外,“捕获音量”和“捕获开关”也必须正确设置。有些设备有“麦克风增强”音量或开关。

当通过“default”PCM(不带pulse-audio插件)打开PCM设备时,您很可能也会有“数字捕获音量”控制。这用于在软件中对信号进行额外的增益/衰减,特别是对于没有硬件音量控制的输入,例如数字麦克风。除非真正需要,否则此应设置为正好50%,相当于0dB——既无额外增益也无衰减。但是,当您使用“hw”PCM,即原始访问PCM时,此控制将不起作用。

众所周知,一些编解码器/设备具有相当差的模拟电路,录制的声音包含一定的直流偏移。这不是驱动程序的错误。

大多数现代笔记本电脑没有模拟CD输入连接。因此,即使驱动程序将其作为捕获源提供,从CD输入录音在许多情况下也无法工作。请改用CDDA。

某些编解码器模型实现了内置麦克风和外部麦克风之间插入时的自动切换,但并非所有模型都实现。部分原因是我的懒惰,但主要是缺乏测试人员。欢迎向作者提交改进补丁。

直接调试

如果没有模型选项能为您带来更好的结果,并且您是一个勇于与邪恶作斗争的硬汉,请尝试通过向设备发送原始HD-audio编解码器指令进行调试。有一些工具可用:hda-emu 和 hda-analyzer。详细说明请参阅以下章节。您需要启用hwdep才能使用这些工具。请参阅“内核配置”章节。

其他问题

内核配置

通常,我建议您启用声音调试选项CONFIG_SND_DEBUG=y,无论您是否正在调试。

别忘了打开相应的CONFIG_SND_HDA_CODEC_*选项。请注意,每个选项都对应于编解码器芯片,而不是控制器芯片。因此,即使lspci显示的是Nvidia控制器,您可能也需要选择其他供应商的选项。如果您不确定,只需全部选择“是”。

CONFIG_SND_HDA_HWDEP是一个有用的驱动程序调试选项。启用此选项后,驱动程序会创建硬件相关的设备(每个编解码器一个),您可以通过这些设备文件直接访问设备。例如,对于第一张声卡(#0)的编解码器插槽#2,将创建hwC0D2。对于hda-verb和hda-analyzer等调试工具,必须启用hwdep设备。因此,最好始终将其打开。

CONFIG_SND_HDA_RECONFIG是一个新选项,它依赖于上面的hwdep选项。启用后,您将在相应的hwdep目录(例如/sys/class/sound/hwC0D0)下拥有一些sysfs文件。有关详细信息,请参阅下面的“HD-audio重新配置”部分。

CONFIG_SND_HDA_POWER_SAVE选项启用省电功能。请参阅下面的“省电”部分。

编解码器 Proc 文件

编解码器proc文件是调试HD-audio的宝藏。它显示了每个编解码器小部件的大部分有用信息。

proc文件位于/proc/asound/card*/codec#*,每个编解码器插槽一个文件。您可以了解编解码器供应商、产品ID和名称、每个小部件的类型、功能等。然而,到目前为止,此文件不显示插孔传感状态。这是因为插孔传感可能取决于触发状态。

此文件将由调试工具选取,也可以作为主要编解码器信息提供给模拟器。请参阅下面的调试工具部分。

此proc文件也可用于检查是否使用了通用解析器。当使用通用解析器时,供应商/产品ID名称将显示为“Realtek ID 0262”,而不是“Realtek ALC262”。

HD-Audio重配置

这是一项实验性功能,允许您无需重新加载驱动程序即可动态重新配置HD-audio编解码器。以下sysfs文件在每个编解码器hwdep设备目录(例如/sys/class/sound/hwC0D0)下可用:

vendor_id

显示32位编解码器供应商ID十六进制数字。您可以通过写入此文件来更改供应商ID值。

subsystem_id

显示32位编解码器子系统ID十六进制数字。您可以通过写入此文件来更改子系统ID值。

revision_id

显示32位编解码器修订ID十六进制数字。您可以通过写入此文件来更改修订ID值。

afg

显示AFG ID。这是只读的。

mfg

显示MFG ID。这是只读的。

name

显示编解码器名称字符串。可以通过写入此文件进行更改。

modelname

显示当前设置的model选项。可以通过写入此文件进行更改。

init_verbs

初始化时执行的额外verbs。您可以通过写入此文件添加一个verb。传入三个数字:nid、verb和parameter(用空格分隔)。

hints

显示/存储用于编解码器解析器的任何用途的提示字符串。其格式为key = value。例如,传入jack_detect = no将完全禁用机器的插孔检测。

init_pin_configs

显示由BIOS设置的初始引脚默认配置值。

driver_pin_configs

显示由编解码器解析器显式设置的引脚默认值。这不显示所有引脚值,只显示解析器更改的值。也就是说,如果解析器本身不更改引脚默认配置值,则此项将不包含任何内容。

user_pin_configs

显示用于覆盖BIOS设置的引脚默认配置值。写入此文件(带两个数字,NID和值)将追加新值。在下次重新配置时,给定值将取代初始BIOS值。请注意,此配置甚至也会覆盖驱动程序引脚配置。

reconfig

触发编解码器重新配置。当任何值写入此文件时,驱动程序会重新初始化并再次解析编解码器树。上述sysfs条目所做的所有更改都会被考虑在内。

clear

重置编解码器,移除指定编解码器的混音器元素和PCM内容,并清除所有初始化指令和提示。

例如,当您想将引脚部件0x14的引脚默认配置值更改为0x9993013f,并让驱动程序根据该状态重新配置时,请运行如下命令:

# echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs
# echo 1 > /sys/class/sound/hwC0D0/reconfig

提示字符串

编解码器解析器有几个开关和调整旋钮,以便更好地匹配实际的编解码器或设备行为。其中许多可以通过“hints”字符串动态调整,如上文所述。例如,通过sysfs或补丁文件传递jack_detect = no字符串,可以禁用插孔检测,从而使编解码器解析器跳过自动静音或麦克风自动切换等功能。作为布尔值,可以传递yesnotruefalse10

通用解析器支持以下提示:

jack_detect (布尔值)

指定本机是否支持插孔检测;默认为true

inv_jack_detect (布尔值)

表示插孔检测逻辑是反向的

trigger_sense (布尔值)

表示插孔检测需要显式调用AC_VERB_SET_PIN_SENSE动词

inv_eapd (布尔值)

表示EAPD以反向逻辑实现

pcm_format_first (布尔值)

在流标签和通道ID之前设置PCM格式

sticky_stream (布尔值)

尽可能长时间地保留PCM格式、流标签和ID;默认为true

spdif_status_reset (布尔值)

每次设置SPDIF流时重置SPDIF状态位

pin_amp_workaround (布尔值)

输出引脚可能有多个放大器值

single_adc_amp (布尔值)

ADC只能有单个输入放大器

auto_mute (布尔值)

启用/禁用耳机自动静音功能;默认为true

auto_mic (布尔值)

启用/禁用麦克风自动切换功能;默认为true

line_in_auto_switch (布尔值)

启用/禁用线路输入自动切换功能;默认为false

need_dac_fix (布尔值)

根据通道数限制DAC

primary_hp (布尔值)

将耳机插孔探测为主输出;默认为true

multi_io (布尔值)

尝试探测多I/O配置(例如共享的线路输入/环绕声、麦克风/CLFE插孔)

multi_cap_vol (布尔值)

提供多个捕获音量

inv_dmic_split (布尔值)

为相位反转的数字麦克风提供独立的内置麦克风音量/开关

indep_hp (布尔值)

如果可用,提供独立的耳机PCM流和相应的混音器控制

add_stereo_mix_input (布尔值)

如果可用,将立体声混音(模拟环回混音)添加到输入多路复用器

add_jack_modes (布尔值)

为每个I/O插孔添加“xxx 插孔模式”枚举控件,以允许更改耳机放大器和麦克风偏置VREF功能

power_save_node (布尔值)

每个小部件的高级电源管理,根据实际引脚和流状态控制每个小部件节点的电源状态(D0/D3)

power_down_unused (布尔值)

关闭未使用的部件电源,它是power_save_node的一个子集,未来将被移除

add_hp_mic (布尔值)

如果可能,将耳机添加到捕获源

hp_mic_detect (布尔值)

在只有一个内置麦克风的情况下,启用/禁用耳机/麦克风共享输入;默认为true

vmaster (布尔值)

启用/禁用虚拟主控制;默认为true

mixer_nid (整型)

指定模拟环回混音器的部件NID

早期打补丁

当设置CONFIG_SND_HDA_PATCH_LOADER=y时,您可以将“补丁”作为固件文件传递,以便在初始化编解码器之前修改HD-audio设置。这基本上可以像上述通过sysfs重新配置一样工作,但它在第一次编解码器配置之前进行。

补丁文件是一个纯文本文件,内容如下所示:

[codec]
0x12345678 0xabcd1234 2

[model]
auto

[pincfg]
0x12 0x411111f0

[verb]
0x20 0x500 0x03
0x20 0x400 0xff

[hint]
jack_detect = no

文件必须包含一行[codec]。下一行应包含三个数字,表示编解码器供应商ID(示例中为0x12345678)、编解码器子系统ID(0xabcd1234)和编解码器地址(2)。其余的补丁条目将应用于此指定的编解码器,直到给出另一个编解码器条目。将第一个或第二个值设置为0或负数将跳过相应字段的检查。这对于那些无法正确初始化SSID的真正损坏的设备将很有用。

[model]行允许更改每个编解码器的模型名称。在上面的示例中,它将更改为model=auto。请注意,这会覆盖模块选项。

[pincfg]行之后,内容被解析为初始默认引脚配置,就像上面user_pin_configs sysfs一样。这些值也可以在user_pin_configs sysfs文件中显示。

类似地,[verb]行之后的内容被解析为init_verbs sysfs条目,而[hint]行之后的内容分别被解析为hints sysfs条目。

另一个将编解码器供应商ID从0x12345678覆盖为0xdeadbeef的示例如下:

[codec]
0x12345678 0xabcd1234 2

[vendor_id]
0xdeadbeef

类似地,您可以通过[subsystem_id]覆盖编解码器子系统ID,通过[revision_id]行覆盖修订ID。此外,编解码器芯片名称可以通过[chip_name]行重写。

[codec]
0x12345678 0xabcd1234 2

[subsystem_id]
0xffff1111

[revision_id]
0x10

[chip_name]
My-own NEWS-0002

hd-audio驱动程序通过request_firmware()读取文件。因此,补丁文件必须位于适当的固件路径上,通常是/lib/firmware。例如,当您传递选项patch=hda-init.fw时,文件/lib/firmware/hda-init.fw必须存在。

补丁模块选项是针对每个卡实例特定的,您需要为每个实例提供一个文件名,用逗号分隔。例如,如果您有两张卡,一张用于板载模拟,另一张用于HDMI视频板,您可以按如下方式传递补丁选项:

options snd-hda-intel patch=on-board-patch,hdmi-patch

省电

省电是一种设备自动暂停功能。当设备在一定时间内不活动时,设备会自动关闭以节省电量。关闭时间由power_save模块选项指定,并且此选项可以通过sysfs动态更改。

当某些编解码器上的模拟回环启用时,省电功能将不起作用。请确保在需要省电时将所有不需要的信号路径静音。

根据设备的不同,省电功能可能会在每次断电/上电时引起可听见的咔嗒声。其中一些可能可以解决,但有些则很难,恐怕如此。某些发行版(如openSUSE)在拔掉电源线时会自动启用省电功能。因此,如果您听到噪音,请首先怀疑是省电功能。请参阅/sys/module/snd_hda_intel/parameters/power_save以检查当前值。如果是非零值,则该功能已打开。

最新内核也支持HD-audio控制器芯片的运行时PM。这意味着HD-audio控制器也可以动态地开启/关闭电源。此功能仅适用于某些控制器芯片,如Intel LynxPoint。您可以通过设置power_save_controller选项强制启用/禁用此功能,该选项也位于/sys/module/snd_hda_intel/parameters目录中。

跟踪点

hd-audio驱动程序提供了一些基本的跟踪点。hda:hda_send_cmd跟踪每次CORB写入,而hda:hda_get_response跟踪RIRB的响应(仅当从编解码器驱动程序读取时)。hda:hda_bus_reset跟踪由于致命错误等导致的总线复位,hda:hda_unsol_event跟踪非请求事件,hda:hda_power_downhda:hda_power_up跟踪通过省电行为进行的断电/上电。

启用所有跟踪点可以像这样完成:

# echo 1 > /sys/kernel/tracing/events/hda/enable

然后执行一些命令后,您可以从/sys/kernel/tracing/trace文件跟踪。例如,当您想跟踪发送了哪些编解码器命令时,请启用跟踪点,如下所示:

# cat /sys/kernel/tracing/trace
# tracer: nop
#
#       TASK-PID    CPU#    TIMESTAMP  FUNCTION
#          | |       |          |         |
       <...>-7807  [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019
       <...>-7807  [002] 105147.774893: hda_send_cmd: [0:0] val=e39019
       <...>-7807  [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a
       <...>-7807  [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a
       <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019
       <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019
       <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a
       <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a

这里[0:0]分别表示声卡编号和编解码器地址,val显示发送到编解码器的值。该值是一个打包值,您可以使用hda-emu包中包含的hda-decode-verb程序对其进行解码。例如,值e3a019是将左输出放大器值设置为25。

% hda-decode-verb 0xe3a019
raw value = 0x00e3a019
cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19
raw value: verb = 0x3a0, parm = 0x19
verbname = set_amp_gain_mute
amp raw val = 0xa019
output, left, idx=0, mute=0, val=25

开发树

HD-audio的最新开发代码可在sound git tree中找到:

  • git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git

master分支或for-next分支通常可用作主要开发分支,而当前和下一个内核的开发分别在for-linus和for-next分支中。

发送错误报告

如果您的设备没有任何模型或模块选项可用,那么是时候向开发者发送错误报告了。在您的错误报告中提供以下信息:

  • 硬件供应商、产品和型号名称

  • 内核版本(如果您是外部构建的ALSA驱动程序版本)

  • alsa-info.sh输出;使用--no-upload选项运行。请参阅下面关于alsa-info的部分

如果这是一个回归问题,最好发送工作和不工作内核的alsa-info输出。这真的很有帮助,因为我们可以直接比较编解码器寄存器。

通过以下方式发送错误报告:

kernel-bugzilla

https://bugzilla.kernel.org/

alsa-devel ML

alsa-devel@alsa-project.org

调试工具

本节描述了一些可用于调试HD-audio问题的工具。

alsa-info

脚本alsa-info.sh是一个非常有用的工具,用于收集音频设备信息。它包含在alsa-utils软件包中。最新版本可在git仓库中找到:

  • git://git.alsa-project.org/alsa-utils.git

该脚本也可以直接从以下URL获取:

以root身份运行此脚本,它将收集重要的信息,例如模块列表、模块参数、proc文件内容(包括编解码器proc文件)、混音器输出和控制元素。默认情况下,它会将信息存储到alsa-project.org的Web服务器上。但是,如果您要发送错误报告,最好使用--no-upload选项运行,并附上生成的文件。

还有一些其他有用的选项。有关详细信息,请参阅--help选项输出。

当发生探测错误或驱动程序明显分配了不匹配的模型时,最好使用probe_only=1选项(最好在冷启动后)加载驱动程序,并在这种状态下运行alsa-info。使用此选项,驱动程序不会配置混音器和PCM,而只是尝试探测编解码器插槽。探测完成后,proc文件可用,因此您可以在驱动程序修改之前获取原始编解码器信息。当然,驱动程序不能与probe_only=1一起使用。但是如果hda-reconfig选项已启用,您可以通过hwdep sysfs文件继续配置。使用probe_only掩码2将跳过HDA编解码器的重置(将probe_only=3用作模块选项)。hwdep接口可用于确定BIOS编解码器初始化。

hda-verb

hda-verb是一个小型程序,允许您直接访问HD-audio编解码器。您可以使用它执行原始HD-audio编解码器动词。此程序访问hwdep设备,因此您需要事先启用内核配置CONFIG_SND_HDA_HWDEP=y

hda-verb程序接受四个参数:hwdep设备文件、小部件NID、动词和参数。当您访问声卡0的插槽2上的编解码器时,通常将/dev/snd/hwC0D2传递给第一个参数。(但是,实际路径名取决于系统。)

第二个参数是要访问的小部件编号ID。第三个参数可以是十六进制/数字或与动词对应的字符串。类似地,最后一个参数是要写入的值,或者可以是参数类型的字符串。

% hda-verb /dev/snd/hwC0D0 0x12 0x701 2
nid = 0x12, verb = 0x701, param = 0x2
value = 0x0

% hda-verb /dev/snd/hwC0D0 0x0 PARAMETERS VENDOR_ID
nid = 0x0, verb = 0xf00, param = 0x0
value = 0x10ec0262

% hda-verb /dev/snd/hwC0D0 2 set_a 0xb080
nid = 0x2, verb = 0x300, param = 0xb080
value = 0x0

尽管您可以使用此程序发出任何动词,但驱动程序状态并非总是更新。例如,音量值通常在驱动程序中缓存,因此通过hda-verb直接更改小部件放大器值不会更改混音器值。

hda-verb 程序现在包含在 alsa-tools 中:

  • git://git.alsa-project.org/alsa-tools.git

此外,旧的独立软件包可在ftp目录中找到:

还有一个git仓库可用:

  • git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-verb.git

有关hda-verb程序的更多详细信息,请参阅tarball中的README文件。

hda-analyzer

hda-analyzer提供了一个图形界面,用于访问原始HD-audio控制,基于pyGTK2绑定。它是hda-verb的一个更强大的版本。该程序提供了易于使用的GUI,用于显示小部件信息和调整放大器值,以及与proc兼容的输出。

hda-analyzer

是alsa-project.org中alsa.git仓库的一部分

  • git://git.alsa-project.org/alsa.git

Codecgraph

Codecgraph是一个实用程序,用于生成图形并可视化编解码器芯片的编解码器节点连接。在分析或调试没有适当数据手册的编解码器时特别有用。该程序解析给定的编解码器proc文件,并通过graphiz程序将其转换为SVG。

tarball和GIT树可在以下网页找到:

hda-emu

hda-emu是一个HD-audio模拟器。此程序的主要目的是在没有实际硬件的情况下调试HD-audio编解码器。因此,它不模拟实际音频I/O的行为,而只是在探测和操作HD-audio驱动程序时转储编解码器寄存器更改和ALSA驱动程序内部更改。

程序需要一个编解码器proc文件进行模拟。事先获取目标编解码器的proc文件,或者从tarball中的编解码器proc集合中选择一个示例编解码器。然后,使用proc文件运行程序,hda-emu程序将开始解析编解码器文件并模拟HD-audio驱动程序

% hda-emu codecs/stac9200-dell-d820-laptop
# Parsing..
hda_codec: Unknown model for STAC9200, using BIOS defaults
hda_codec: pin nid 08 bios pin config 40c003fa
....

该程序只提供一个非常简单的命令行界面。您可以获取当前状态的proc文件转储,获取控制(混音器)元素列表,设置/获取控制元素值,模拟PCM操作,插孔插拔模拟等。

该程序可在以下git仓库中找到:

  • git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/hda-emu.git

有关hda-emu程序的更多详细信息,请参阅存储库中的README文件。

hda-jack-retask

hda-jack-retask是一个用户友好的GUI程序,用于操作HD-audio引脚控制以进行插孔重分配。如果您遇到插孔分配问题,请尝试此程序并检查是否能获得有用的结果。一旦您确定了正确的引脚分配,可以通过静态修改驱动程序代码或通过传递固件补丁文件(参见“早期补丁”部分)来修复。

该程序现在包含在alsa-tools中

  • git://git.alsa-project.org/alsa-tools.git