9.1.1. bttv 驱动

9.1.1.1. bttv 和声音迷你指南

现在有大量基于 bt848/849/878/879 的板卡可用。让视频工作通常不是什么大问题,因为这完全由 bt8xx 芯片处理,该芯片在所有板卡上都很常见。但是声音在每个板卡上的处理方式略有不同。

为了正确处理采集卡,bttv-cards.c 中有一个数组 tvcards[],其中包含每个板卡所需的信息。只有使用正确的条目,声音才能工作(对于视频,通常没有区别)。bttv 驱动程序会在内核日志中打印一行,说明使用的卡类型。 像这样

bttv0: model: BT848(Hauppauge old) [autodetected]

您应该验证这是正确的。 如果不是,则必须将正确的板类型作为 insmod 参数传递,例如 insmod bttv card=2。 文件 BTTV 卡列表 列出了 card 的有效参数。

如果您的卡未在此处列出,您可以检查源代码中尚未列出的新条目。 如果没有适用于您的卡,您可以检查现有条目之一是否适用于您(只需反复试验......)。

一些板卡有一个额外的处理器用于声音,以进行立体声解码和其他不错的功能。 例如,Hauppauge 使用 msp34xx 芯片。 如果您的板卡有,您可能需要加载一个辅助模块,如 msp3400,以使声音工作。 如果没有适用于您的板卡上使用的芯片:运气不好。 开始编写一个新的。 好吧,您可能想先检查一下 video4linux 邮件列表存档......

当然,您需要正确安装的声卡,除非您将扬声器直接连接到采集卡。 提示:也要检查混音器设置。 例如,ALSA 默认情况下会静音所有内容。

9.1.1.1.1. 声音如何工作(详细)

仍然无法工作? 看起来需要进行一些驱动程序黑客攻击。 以下是为您准备的自助说明。

bt8xx 芯片有 32 个通用引脚和用于控制这些引脚的寄存器。 一个寄存器是输出使能寄存器 (BT848_GPIO_OUT_EN),它说明了哪些引脚由 bt848 芯片主动驱动。 另一个是数据寄存器 (BT848_GPIO_DATA),您可以在其中获取/设置这些引脚的状态。 它们可以用于输入和输出。

大多数采集卡供应商使用这些引脚来控制外部芯片,该芯片执行声音路由。 但是每个板卡都略有不同。 一些公司也使用这些引脚来驱动遥控接收器芯片。 一些板卡使用 i2c 总线而不是 gpio 引脚来连接 mux 芯片。

如上所述,有一个数组保存每个已知板卡所需的信息。 您基本上必须为您的板卡创建新的一行。 重要的字段是这两个

struct tvcard
{
      [ ... ]
      u32 gpiomask;
      u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
};

gpiomask 指定哪些引脚用于控制音频 mux 芯片。 输出使能寄存器 (BT848_GPIO_OUT_EN) 中的相应位将被设置,因为这些引脚必须由 bt848 芯片驱动。

audiomux[] 数组保存不同输入的数据值(即,对于调谐器/静音/...,哪些引脚必须为高/低)。 这将被写入数据寄存器 (BT848_GPIO_DATA) 以切换音频 mux。

您必须做的是找出 gpiomask 和 audiomux 数组的正确值。 如果您有 Windows 并且安装了您的卡的驱动程序,您可以检查是否可以读取 Windows 驱动程序使用的这些寄存器值。 可以从 http://btwincap.sourceforge.net/download.html 获得执行此操作的工具。

您也可以在 Windows 应用程序的 *.ini 文件中挖掘。 您可以查看板卡,以查看哪些 gpio 引脚已连接,然后开始反复试验...

从 0.7.41 版本开始,bttv 有一些 insmod 选项,可以更轻松地进行 gpio 调试

bttv_gpio=0/1

启用/禁用 gpio 调试消息

gpiomask=n

设置 gpiomask 值

audiomux=i,j,...

设置 audiomux 数组的值

audioall=a

设置 audiomux 数组的值(所有数组元素的一个值,可用于检查特定值的影响)。

使用 bttv_gpio=1 打印的消息如下所示

bttv0: gpio: en=00000027, out=00000024 in=00ffffd8 [audio: off]

en  =   output _en_able register (BT848_GPIO_OUT_EN)
out =   _out_put bits of the data register (BT848_GPIO_DATA),
        i.e. BT848_GPIO_DATA & BT848_GPIO_OUT_EN
in  =   _in_put bits of the data register,
        i.e. BT848_GPIO_DATA & ~BT848_GPIO_OUT_EN