
简介本资源面向嵌入式软硬件工程师与驱动开发者围绕Silicon Labs的Sil9136-3 USB转串行桥接芯片提供参考手册与驱动源码帮助解决芯片初始化、接口配置与数据传输等开发问题。压缩包共24个文件约13.73MB包含PDF参考手册与编程指南、C与H源码、Makefile构建脚本、ko内核模块及o目标文件另附h264测试视频与readme说明覆盖硬件电气特性、寄存器操作到驱动编译加载的完整链路。已有571人学习下载。读者可借助Programmers Reference掌握编程接口与配置选项结合sil9024驱动源码理解底层读写、中断处理与抽象层设计并参考Makefile与模块文件快速完成编译验证适用于工业控制、智能家居、物联网模块等串行接口扩展场景。1. 拿到 sil9136 参考手册和驱动源码压缩包先别急着解压很多做嵌入式显示驱动的朋友第一次拿到 sil9136 参考手册_驱动源码.zip 这种组合包第一反应是双击解压、打开源码、找 main 函数。我当年也这样结果在 HDMI 输出花屏这件事上卡了整整两周。sil9136 是一颗常见的 HDMI 发送芯片广泛用在工控主板、广告机、车载中控这类需要把并行 RGB 或 BT1120 转成 HDMI 信号的场景。这个压缩包的价值不在于源码有多完整而在于它把寄存器手册和驱动实现放在了一起——你可以对着手册翻寄存器再对着源码看人家怎么配这是纯看手册或纯抄驱动都做不到的。适合谁看写过 I2C 驱动、调过 LCD 时序、但一碰 HDMI 就心里没底的中级嵌入式工程师。如果你连 I2C 读写都没独立做过建议先补总线基础再回来。这篇笔记按「先搞懂芯片在系统里的位置 → 把源码跑起来 → 逐段拆初始化 → 避坑 → 进阶验证」的顺序走每一步都落到能复现的命令和参数上。2. sil9136 在显示链路里的位置与最小系统搭建2.1 先搞清楚它到底管什么信号sil9136 的核心工作是把输入端的并行视频信号通常是 24 位 RGB 或 16 位 BT1120加上独立的行场同步、像素时钟转换成 TMDS 差分信号输出给 HDMI 接口。它内部有 EDID 解析、HDCP 加密、音频嵌入、色彩空间转换这几大块。参考手册里寄存器分页很细0x00 到 0x0F 页管视频输入格式0x10 页往后管输出和音频。驱动源码里最常见的结构是一个 i2c_driver 加一个 drm_bridge 或 fbdev 的适配层。你要先确认自己板子上的连接方式是 SoC 的 RGB 口直连 sil9136还是通过 FPGA 中转。这决定了你改源码时动的是哪个文件。常见做法是先在设备树里把 I2C 地址写对sil9136 的 7 位地址通常是 0x39 或 0x3B取决于 ADDR 引脚电平。2.2 硬件最小系统与上电时序检查在写任何代码之前用万用表确认三路电源1.2V 内核、1.8V 或 3.3V IO、以及 TMDS 的 1.8V。sil9136 对上电顺序有要求一般是内核先于 IO。如果顺序反了I2C 能通但 TMDS 无输出这种玄学问题我踩过不止一次。复位引脚要保证在电源稳定后至少拉低 10ms 再释放。晶振通常是 27MHz给内部 PLL 做参考。你可以先用示波器量晶振起振没有再量像素时钟输入有没有。这两步不过后面全是白费。2.3 把源码挂进内核并编译的最小步骤假设你拿到的是基于 Linux 的驱动源码目录里一般有 Makefile 和 Kconfig。先别改代码原样编译一遍看能不能过。# 进入驱动源码目录先看目录结构 ls -l # 常见文件sil9136.c sil9136.h Makefile Kconfig # 把驱动放到内核源码树对应位置以显示驱动为例 cp -r sil9136_driver /path/to/kernel/drivers/gpu/drm/bridge/ # 编辑 Kconfig加入配置项 # 在 drivers/gpu/drm/bridge/Kconfig 末尾添加 # config DRM_SIL9136 # tristate Sil9136 HDMI transmitter # depends on DRM I2C # help # HDMI transmitter driver for sil9136 # 编辑 Makefile # obj-$(CONFIG_DRM_SIL9136) sil9136.o # 配置内核 make menuconfig # 路径Device Drivers - Graphics support - Display Interface Bridges - Sil9136 # 编译 make -j4 modules逻辑说明这段操作的核心是把外部驱动纳入内核构建体系。Kconfig 里的 tristate 表示可以编成模块或内置调试阶段建议编成模块方便反复加载卸载。Makefile 里的 obj 规则决定了最终生成 sil9136.ko。参数上注意 depends on 要写全漏了 I2C 会导致编译时找不到符号。编译通过后用 insmod 加载然后 dmesg 看有没有 probe 成功的打印。如果报 -ENODEV八成是设备树里 I2C 地址或 compatible 字符串对不上。3. 逐段拆解驱动源码里的初始化序列3.1 寄存器写入封装与页切换机制sil9136 的寄存器是分页的直接写偏移会串页。驱动里通常有一个写页寄存器的函数先写 0x0F 页的 0x00 寄存器切页再写目标寄存器。源码里常见这样的封装/* 假设 i2c_client 已经就绪 */ static int sil9136_write_page(struct i2c_client *client, u8 page, u8 reg, u8 val) { int ret; /* 切页先写页选择寄存器 */ ret i2c_smbus_write_byte_data(client, 0x0F, page); if (ret 0) return ret; /* 再写目标寄存器 */ return i2c_smbus_write_byte_data(client, reg, val); } /* 读操作同理注意读之前也要切页 */ static int sil9136_read_page(struct i2c_client *client, u8 page, u8 reg) { int ret; ret i2c_smbus_write_byte_data(client, 0x0F, page); if (ret 0) return ret; return i2c_smbus_read_byte_data(client, reg); }逻辑说明i2c_smbus_write_byte_data 的第一个参数是 client第二个是寄存器地址第三个是值。这里的关键是每次读写前都切页不能假设页状态保持。参数上页号范围参考手册常见 0x00 到 0x0F。如果你发现读出来的值总是 0xFF 或 0x00先查切页有没有成功用示波器抓 I2C 波形看 ACK。3.2 视频输入格式配置RGB 与 BT1120 的差异输入格式配错是花屏的第一大原因。源码里一般有一个 sil9136_set_input_format 函数根据板级配置写 0x00 页的几个寄存器。RGB 模式下行场同步是独立信号BT1120 模式下同步信号嵌入在数据里。手册里 0x00 页的 0x08 到 0x0B 管输入格式和同步极性。/* 配置为 24 位 RGB 输入上升沿采样 */ static void sil9136_set_rgb_input(struct i2c_client *client) { /* 0x00 页 0x08输入格式选择0x00 表示 RGB */ sil9136_write_page(client, 0x00, 0x08, 0x00); /* 0x09位宽0x03 表示 24 位 */ sil9136_write_page(client, 0x00, 0x09, 0x03); /* 0x0A同步极性bit0 行同步bit1 场同步0 表示高有效 */ sil9136_write_page(client, 0x00, 0x0A, 0x00); /* 0x0B采样沿0 表示上升沿 */ sil9136_write_page(client, 0x00, 0x0B, 0x00); }逻辑说明这四个寄存器必须一起配单独改一个往往不生效。参数上位宽 0x03 对应 24 位如果是 16 位 BT1120 则写 0x01。同步极性要和你的 SoC 输出一致不一致会图像偏移或抖动。改完这些还要配 0x0C 到 0x0F 的消隐区参数否则边缘会出黑边或裁切。3.3 输出端 TMDS 与音频嵌入的配置顺序输出端配置在 0x10 页之后。先配 TMDS 驱动电流和预加重再配音频。顺序反了会导致音频无声或 TMDS 眼图变差。源码里通常先调 sil9136_set_tmds再调 sil9136_set_audio。/* TMDS 输出配置 */ static void sil9136_set_tmds(struct i2c_client *client) { /* 0x10 页 0x00TMDS 使能0x01 开 */ sil9136_write_page(client, 0x10, 0x00, 0x01); /* 0x01驱动电流0x03 中等线长时加大 */ sil9136_write_page(client, 0x10, 0x01, 0x03); /* 0x02预加重0x01 开 */ sil9136_write_page(client, 0x10, 0x02, 0x01); }逻辑说明驱动电流和预加重要根据 PCB 走线长度调。线短了电流大反而过冲线长了电流小会丢信号。常见做法是先按手册推荐值配再用眼图仪看没有眼图仪就靠实际显示效果微调。音频配置涉及 I2S 格式和采样率在 0x20 页附近配错会出杂音。4. 避坑sil9136 调试中最容易翻车的五个点4.1 现象I2C 能读到 ID 但 TMDS 无输出原因上电时序不对或者复位释放太早。sil9136 内部 PLL 需要参考时钟稳定后才锁定复位早释放会导致 PLL 配置丢失。解决在驱动 probe 里加延时复位释放后至少等 20ms 再配寄存器。用示波器确认 27MHz 晶振在复位释放前已经稳定。4.2 现象图像显示但颜色偏红或偏蓝原因RGB 通道映射顺序错了。手册里 0x00 页有寄存器控制 R 和 B 交换默认可能是 BGR。解决找到 0x00 页的通道交换寄存器翻转对应 bit。或者直接在源码里把 RGB 分量顺序调换。这个坑很隐蔽因为图像结构是对的只是颜色不对。4.3 现象热插拔 HDMI 后花屏原因EDID 重新读取后输出分辨率变了但驱动没有重新配置 TMDS 和消隐区。解决在 hpd 中断处理里重新走一遍完整的输出配置流程不能只读 EDID。源码里如果有 drm_bridge 的 detect 回调确保它触发 mode_set。4.4 现象音频有杂音或断续原因I2S 时钟和像素时钟不同源或者音频采样率寄存器配错。解决确认 I2S 的 MCLK 是由 sil9136 输出还是外部输入。如果是输出检查 0x20 页的分频寄存器。采样率常见 48kHz 对应分频值手册里有表别自己算。4.5 现象加载驱动后内核 panic原因源码里的寄存器读写没有做返回值检查I2C 失败后继续操作空指针。解决在每个 i2c_smbus 调用后加 ret 检查失败就返回。调试阶段可以在 probe 里加 printk 打印每一步的返回值定位到具体哪个寄存器写失败。5. 进阶用示波器和 EDID 分析验证 sil9136 输出质量5.1 用示波器看 TMDS 眼图判断驱动电流是否合适TMDS 是差分信号测的时候用差分探头单端探头看到的是半个眼图。把探头接到 HDMI 连接器的 TMDS 数据对和时钟对上触发用像素时钟。眼图张开度大、交叉点清晰说明驱动电流和预加重合适。如果眼图闭合先加大驱动电流再调预加重。注意示波器带宽至少是像素时钟的 3 倍1080p60 的像素时钟 148.5MHz带宽要 500MHz 以上。5.2 解析 EDID 确认输出模式协商正确EDID 是显示器告诉源端自己支持哪些分辨率的 I2C 数据。你可以用 i2cget 直接读也可以在内核里看 drm 的 edid 调试节点。# 假设 sil9136 挂在 i2c-3 上地址 0x39 # 读 EDID 前 128 字节 i2cdump -y 3 0x39 # 或者用内核 debugfs cat /sys/kernel/debug/dri/0/HDMI-A-1/edid | hexdump -C逻辑说明i2cdump 会打印所有寄存器值EDID 从 0x00 开始头是 00 FF FF FF FF FF FF 00。如果读出来全是 FF说明 HPD 没拉高或 DDC 通道不通。参数上 -y 表示跳过交互确认3 是 I2C 总线号0x39 是 sil9136 地址。读到的 EDID 可以用在线解析工具看支持的模式确认你的输出模式在列表里。5.3 一个我常用的快速验证习惯每次改完寄存器配置我不急着看屏幕而是先读回关键寄存器确认写入生效。具体做法是在驱动里加一个 debugfs 节点把 0x00、0x10、0x20 页的关键寄存器 dump 出来。这样屏幕不亮的时候我能立刻判断是配置没写进去还是写进去了但硬件没响应。这个习惯帮我省了无数次拆机重烧的时间。希望帮到你。本文还有配套的精品资源点击获取