漫谈 Linux 声卡驱动开发的设备树与 I2S

最近在研究 Ubuntu 下的 ES8156 的声卡驱动,顺便学习了一下设备树(Device Tree)I2S 声卡的工作原理。首先要搞懂这两个概念,简单来说,把写驱动比作盖房子,盖房子之前,先要看懂设计图纸(设备树)和水电原理(I2S协议)。

下面用最通俗的方式为你拆解这两个核心概念:


🌳 什么是设备树 (Device Tree)?

在以前的 Linux 内核中,硬件信息(比如有几个 CPU、内存多大、GPIO 接了什么设备)是直接写死在 C 语言代码里的。这导致内核代码非常臃肿,同一个内核代码无法通用于不同配置的开发板。

设备树就是一份"硬件说明书"。

它的作用是告诉 Linux 内核:"嘿,我现在这台电脑(开发板)上,长什么样,有哪些外设。"

1. 核心比喻:树状结构

想象一棵树:

  • 树根 (Root):代表整个系统(SoC,也就是树莓派的芯片)。
  • 树枝 (Buses):代表连接方式,比如 I2C 总线、SPI 总线、I2S 总线。
  • 树叶 (Devices):代表具体的硬件,比如 ES8156 芯片。
2. 关键术语
  • DTS (Device Tree Source) :后缀为 .dts 的文本文件,人类可读,我们写的代码就是这个。
  • DTB (Device Tree Blob) :后缀为 .dtb 的二进制文件,由 DTS 编译而来,内核能读懂。
  • Node (节点):描述一个硬件对象。例如一个 I2C 控制器是一个节点,挂在这个控制器上的 ES8156 也是一个节点。
  • Property (属性) :节点的特征。例如 compatible(兼容性)、reg(寄存器地址/I2C地址)、clocks(时钟)。
3. 驱动匹配的"暗号"

这是最关键的一点:驱动程序是如何知道自己要控制哪个硬件的?

答案是:compatible 属性

  • 设备树 里,写:compatible = "everest,es8156";
  • 驱动源码 里,开发者也写了一个列表:{"everest,es8156", ...}
  • 内核启动时,会拿着设备树里的字符串去驱动列表里找。只要这两个字符串对上了,内核就把这个硬件分配给这个驱动来管理。

🔊 I2S 声卡的工作原理

I2S 全称是 Inter-IC Sound,是飞利浦公司制定的一种数字音频传输标准。它专门用来在芯片之间传输声音数据(比如 CPU 和 音频解码芯片之间)。

为什么不用 USB 或网络传输音频?因为 I2S 是纯数字、点对点、低延迟的,音质最纯净。

1. 三根核心线 (信号)

I2S 接口通常由 3-4 根线组成,它们就像乐队的指挥和乐手:

表格

信号线 全称 作用 比喻
BCLK Bit Clock (位时钟) 每传输 1 个 bit,它就跳变一次。频率非常高。 节拍器:每响一声,传一个音符。
LRCLK Left/Right Clock (声道时钟) 高电平代表右声道,低电平代表左声道。 指挥棒:指左边乐队奏,指右边乐队停。
DIN/DOUT Data In/Out (数据线) 真正传输声音波形数据的线路。 乐谱:上面写着具体要唱什么音。
MCLK Master Clock (主时钟) 通常是采样率的 256 或 384 倍,用于同步芯片内部振荡。 校准表:确保大家的表时间一致,不走音。
2. 数据是怎么传的?

想象你要传输一个立体声(左/右)的音乐:

  1. LRCLK 变成低电平(代表左声道开始)。
  2. BCLK 开始疯狂跳动(比如 2.3MHz)。
  3. DIN 上按照 BCLK 的节奏,一位一位地送出左声道的数字(比如 16 位或 24 位数据)。
  4. LRCLK 变成高电平(代表右声道开始)。
  5. BCLK 继续跳动,DIN 上送出右声道的数据。
  6. 如此循环,形成了连续的声音流。
3. 常见的"坑" (极性)

I2S 虽然标准,但不同芯片的厂商习惯不同。

  • 左对齐 (Left Justified) vs I2S 标准 (Philips Standard):数据是在 LRCLK 变化后的第一个时钟有效,还是第二个时钟有效?
  • LRCLK 极性:高电平到底是左声道还是右声道?
  • 解决方案 :这通常在设备树或驱动代码中通过 dai-format = "i2s";dai-format = "left_j"; 来配置。如果配置错了,你会听到噪音,或者只有单声道。

🛠️ 开发调试 ES8156 的具体步骤

结合前面的理论,现在要做的事情可以拆解为以下 5 个步骤:

第一步:硬件连接 (物理层)
  • 把树莓派的 GPIO 和 ES8156 的引脚焊对。
  • I2C 线:连接 SDA、SCL(用于发送"播放"、"静音"、"调音量"等指令)。
  • I2S 线:连接 BCLK、LRCLK、DIN/DOUT(用于传输真正的音乐数据流)。
  • 供电:检查 VCC 和 GND。
第二步:确认 I2C 通信 (控制层)
  • 在 Ubuntu 命令行输入 i2cdetect -y -1
  • 目的:确认电脑能看到 ES8156 这个"人"。如果扫到了地址(比如 0x1b),说明控制通道通了。
第三步:编写设备树 (描述层)
  • 创建一个 .dts 文件。
  • 内容
    1. 告诉内核:"我在 I2C 总线上挂了一个设备,地址是 0x1b,它的名字叫 everest,es8156"。
    2. 告诉内核:"请把简单的音频卡(Simple Card)配置好,CPU 端用 I2S,Codec 端用刚才那个 ES8156"。
第四步:加载与匹配 (软件层)
  • 编译设备树,重启或动态加载。
  • 输入 dmesg | grep es8156
  • 理想输出es8156_probe: entered。这意味着驱动程序的 probe 函数被调用了,说明设备树和驱动匹配成功
第五步:测试音频 (应用层)
  • 输入 aplay -l
  • 如果能看到声卡列表里多了一个设备,恭喜你,硬件和驱动都通了!接下来就是调音量和测试播放了。

📌 总结

  • 设备树 = 给内核看的 简历,告诉内核硬件长什么样。
  • I2S = 芯片间传输声音的 专用高速公路,有严格的时钟同步要求。
  • 调试核心 :先通 I2C(控制),再通 I2S(数据),靠 compatible 字符串牵线搭桥。

老徐,2026 0123

相关推荐
wdfk_prog1 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
七夜zippoe2 小时前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
盟接之桥2 小时前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
忆~遂愿2 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
湘-枫叶情缘2 小时前
1990:种下那棵不落叶的树-第6集 圆明园的对话
linux·系统架构
Fcy6483 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满3 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠3 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Gary Studio3 小时前
rk芯片驱动编写
linux·学习
mango_mangojuice3 小时前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习