简介:面向 MediaTek 平台的 LT9611 显示驱动源码包,适合嵌入式驱动开发与 BSP 工程师参考,用于在 MTK 平台上适配 LT9611 芯片并实现默认 1080p 视频输出。压缩包共 5 个文件,包括 3 个 C 驱动源文件与 2 个 DWS 配置文件,整体仅 21KB,结构精简;C 文件覆盖 DSI 转 HDMI 的驱动逻辑,DWS 文件用于引脚复用与 codegen 配置。资源同时包含 lk 与 kernel 阶段的驱动源文件,便于对照启动早期和内核态的初始化流程,也能理解显示输出设备在不同阶段的管理差异。已有 968 人浏览学习,说明它在同类 MTK 调试项目中具有一定参考价值。这些文件能帮助开发者快速熟悉 LT9611 的驱动注册、时钟与显示通路配置,减少从零移植和排查无显示、花屏等问题的弯路;结合 DWS 配置还可快速定位引脚复用错误,尤其适合需要输出 1080p 高清信号的智能电视、显示器转接等 MTK 设备方案。
1. 一个工程名背后:MTK 平台怎么把 HDMI 输出交给 LT9611
如果你在某台 MTK 方案的内核源码目录里翻到mtk-lt9611_stomachhcc_lt9611_mtk这样的命名,第一反应多半是方案公司发的桥接驱动包。LT9611 是一颗把 MIPI DSI 信号转成 HDMI 1.4 输出的桥接芯片,MTK 的平板和工控板没有原生 HDMI TX 时,十有八九会用它补一个 HDMI 口。我的血泪经验是,这个工程名看着像乱码,背后其实是完整的驱动源码、dts 配置和调试工具打包习惯。这篇文章只讲一件事:拿到这类工程,怎么在 MTK 平台上把 LT9611 这根 HDMI 链路调通,避开我第一次做时踩过的坑。如果你手头是 MTK 平板方案、广告机或带 HDMI 输入的开发板,这份流程可以直接照着走。
2. LT9611 桥接芯片:选型理由、工作模式和 MTK 内核里的驱动骨架
我第一次拿到 LT9611 相关工程时,第一反应是去翻处理器手册,而不是芯片手册。这个顺序其实错了。MTK 平台里,桥接芯片能不能起来,更多取决于 DSI 输出时序和 bridge 驱动的挂载方式,而不是 SoC 手册里的 GPIO 说明。
2.1 为什么是 LT9611,而不是直接做 HDMI
我最早接触 LT9611,是在一款 10.1 寸平板的改款项目上。产品经理要求加一个 HDMI 接口,主板原来的 SoC 只有 DSI 输出。当时有两个选择:换一颗带 HDMI TX 的 SoC,或者在 DSI 后面搭一颗转换芯片。评估下来,换 SoC 的硬件改动要重画基带部分,固件、DDR 布线、电源树都要重新验证,周期至少多两个月。搭 LT9611,硬件改动只在显示链路上,驱动由方案商给,两三天就能亮起来。这是它存在的核心价值。
MTK 与高通的差异在这里非常明显:高通平台从 MDSS 到 HDMI 往往有现成的 display driver,桥接芯片只是辅助;MTK 的平板 SoC 则经常完全没有 HDMI controller,DSI 是唯一的输出途径。LT9611 挂在 DSI 之后,本质上相当于把 DSI 协议翻译成 HDMI 协议,所以调试时要同时懂 DSI 和 HDMI 两端。很多从高通项目转过来的人,习惯先去搜板级 HDMI 的 DTS 属性,结果在 MTK 平台上找不到,就卡住了。
LT9611 的标称能力是 HDMI 1.4,1080p60,双 DSI 输入。单 DSI 4-lane RGB888 也能跑 1080p60,但余量很小。如果产品未来要上 4K,这颗芯片就不太合适。选型时要把这个边界跟项目经理说清楚,不然项目后期会因为分辨率要求变更推倒重来,到时候板子已经贴片了,后悔药都没得吃。
另外这颗芯片支持音频 SPI/I2S,可以把 I2S 音频也打进 HDMI。对带扬声器的商显产品,这功能很关键。但音频调试要注意 MTK 的 audio path 和 LT9611 的 audio enable 顺序,顺序错了容易只有画面没有声音。这个问题单独查驱动看不出来,要配合 alsa 的声卡 setting 一起看,后面调试章节会提到。
2.2 三个必看的工作模式:DSI to HDMI、HDMI to DSI、以及 I2C 配置
LT9611 芯片名称容易让人混淆,它的核心角色是 DSI to HDMI,但一些变体支持 HDMI to DSI 的反向桥接。驱动里通过 device id 区分。拿到工程先确认lt9611_read读到的 chip id 跟你代码里 switch-case 匹配。有次我们用了带 UXC 后缀的新料,驱动还在用老 id 表,结果每次 probe 都会 fail,后来加了 id 才解决。所以不要以为驱动文件叫 lt9611,就一定支持你板子上的那颗料。
第二个需要关注的是双 DSI 模式。当你想跑 2560x1440 这类超过单路 DSI 带宽的分辨率时,LT9611 可以用两路 DSI 同时输入。这个模式不是简单的“把两条 lane 接到同一个 controller”,而是要在 DSI 驱动里设置dual-channel,并且把两个 channel 的时序同步起来。MTK 平台上,双通道 DSI 的配置散落在mtk_dsi.c和 dts 的port节点中,一旦没配好,现象往往是一半画面撕裂。
第三个模式是 loopback,通常只在产线测试时使用。芯片会把 HDMI 的输入回环到 DSI 端,用来验证连接器是否焊接正常。这个模式在正常 Android 启动流程里不会用到,但一些方案商提供的 init 脚本里会留一个lt9611_loopback_test命令。你在调试规格书之外的问题时,可以用它隔离是 SoC DSI 的问题还是 LT9611 的问题,省掉很多无效排查。
I2C 配置是另一个容易翻车的点。LT9611 的寄存器页划分一般通过PAGE_SELECT寄存器切换。0x00 页是系统控制,0x01 页是 HDMI 发送器,0x02 页是 HDCP,0x03 页是 DSI 接收器。还有一些厂商固化参数在 0x04 之后。驱动初始化流程会先复位芯片,再切页配置 DSI 和 HDMI。你改动 dts 的 resolution 后,如果没在对应页写 pixel clock,等于没配。
I2C 从地址常见的是0x3b,但有的板子设计成0x29,原理图和驱动可能不一致。驱动在 probe 阶段会读一个芯片 ID 寄存器,读不到就会直接返回-ENXIO。拿不定时用i2cdetect扫描,读到几个,再对照原理图。芯片内部的寄存器还分成多个 page,需要先写 page select 再访问功能寄存器。所以你在写初始化脚本时,不要想当然地连续读写,要先确认当前 page 指向哪里。
2.3 内核里常见的驱动路径和 device tree 结构
在 Linux DRM 子系统里,桥接驱动通常通过drm_bridge_add注册。lt9611.c里实现drm_bridge_funcs的几个回调:attach、mode_valid、enable、disable。MTK 的 DSI 驱动会在mtk_dsi_encoder_enable里调用 bridge chain 的pre_enable和enable。所以 LT9611 驱动能否工作,跟 DSI 驱动的 trigger 时机强相关。最常见的错误是 bridge 已经 attach,但 DSI 的encoder没有把bridge_list串起来。
设备树节点一般挂在某个 I2C 总线下。下面是一个典型的节点模板,按我们用的板子为例:
&i2c3 { lt9611_bridge: lt9611@3b { compatible = "lontium,lt9611"; reg = <0x3b>; reset-gpios = <&pio 25 GPIO_ACTIVE_LOW>; interrupt-parent = <&pio>; interrupts = <26 IRQ_TYPE_EDGE_FALLING>; vcc-supply = <®_vcc3v3>; mode = "dsi-to-hdmi"; pinctrl-names = "default"; pinctrl-0 = <<9611_pins>; status = "okay"; }; }; &pio { lt9611_pins: lt9611_pins { pinmux = <PINMUX_GPIO25__FUNC_GPIO25>, <PINMUX_GPIO26__FUNC_GPIO26>; bias-pull-up; }; };这个节点里,reset-gpios的极性非常关键。很多 MTK 板子的 reset 管脚外围有一个反向缓冲器,原理图标注 ACTIVE_HIGH,但实际跟驱动预期相反。如果驱动默认用GPIO_ACTIVE_LOW,就会出现“reset 已经被拉高,但其实芯片一直处于复位状态”的假象,后面做什么都不对。
vcc-supply也不可省。LT9611 需要 3.3V 和 1.8V 两组电,有的板子只接了 3.3V,I2C 能通,HDMI TX 部分不工作,现象非常隐蔽。拿到板子先量电压,比查驱动快得多。
MTK 平台还有一个坑:pinctrl。HDMI 相关 GPIO 往往和 PCM、SPI 复用,厂商的 pinctrl 驱动可能把同一 pin 配置成多个功能。你 dts 写了pinmux = <PINMUX_GPIO25__FUNC_GPIO25>,但另一处 i2c 或者 pcm 节点又占了 GPIO25,编译能过,运行时不生效。排查方法用 debugfs 看 pinctrl 的实际分配:
mount -t debugfs none /sys/kernel/debug cat /sys/kernel/debug/pinctrl/pinctrl-handles如果发现同一个 pin 被两个节点引用,优先改另一个节点,或者跟硬件确认是不是 GPIO 选错。这类问题在常见的 MTK 参考设计上不多,但定制板一多,概率就上升了。
3. 把 lt9611 驱动编进 MTK 平台:从源码到 boot image 的最小流程
这一章不讲复杂 build system,只讲最快走通的一条路:在 MTK 内核源码树里编出 boot.img,再用 MTK 刷机工具烧进去。整个过程最耗时间的不是编译,而是搞错分支和白折腾 dts。
3.1 先确认内核版本和驱动源:不要拿错分支
MTK 平台的内核版本非常混乱,有 Linux 4.4、4.9、4.14、4.19、5.4、5.15 等等。LT9611 驱动在不同版本里的 DRM bridge API 完全不同。老内核用drm_bridge_attach(encoder, bridge, NULL),新内核要求第三个参数是 previous bridge。直接互换会出现编译错误或者运行时空指针。所以不要自己从网上随便拷一个驱动,更不要指望主线内核版本能直接套在 MTK 方案上。
正确做法是:先把包里的drivers/gpu/drm/bridge/lontium/和arch/arm64/boot/dts/mediatek/原封不动放进对应的内核分支,再确认 Kconfig 里有没有CONFIG_DRM_LONTIUM_LT9611。如果找不到这个选项,多半是 bridge 目录下的 Makefile 没有把lontium/包含进来。检查drivers/gpu/drm/bridge/Makefile是否有obj-y += lontium/。
我一般会先在目标内核上执行一次干净编译,确认 baseline 没有报错,再合入驱动。这样后续任何编译问题都能确定是驱动代码引入的,而不是原内核本来就坏的。如果编译报错提示struct drm_bridge缺少某个字段,大概率是拿错了内核分支。把驱动里的drm_bridge_funcs和当前内核头文件的定义对比一下,几分钟就能定位。
还有一个容易被忽略的点:源码包里可能同时存在lt9611.c和lt9611_uxc.c,或者有多个平台文件夹。MTK 方案商经常把多个项目的驱动合到一个包,Makefile 用不同的 Kconfig 符号区分。不要只看文件名,要看Makefile里实际编的是哪个对象。我见过有人改了lt9611.c,编译刷机后没有任何变化,折腾半天才发现 Makefile 编的是lt9611_uxc.c。
3.2 dts 节点怎么配:reg、reset-gpio、supply 和中断
上一章已经给出了模板,这里补充几个容易配错的点。reg地址不是随便填的,它必须和 LT9611 的 I2C 从地址一致,并且 I2C 控制器地址位宽要支持 7-bit。多数板子用 7-bit 地址,直接填0x3b没问题。如果驱动里用的是i2c_new_device或者i2c_get_match_data,还要确认平台 i2c 总线号跟 dts 里的i2c3对应,不然驱动挂在 0 号总线,实际芯片在 3 号总线上,读不到任何数据。
reset-gpios的使用还有一个细节:驱动 probe 时会把 reset 拉低再拉高,如果 GPIO 默认方向和备用功能被其他设备占用,probe 就会卡在devm_gpiod_get_optional。检查 pinctrl 是不是把该管脚复用成了GPIO25__FUNC_GPIO25,而不是别的功能。有的 SDK 要求 reset 是开漏输出,需要在 dts 里加drive-open-drain,否则拉低时电平不够,芯片一直处于复位状态。
interrupts不一定要配。LT9611 的 HPD 事件可以通过中断上报给 DRM,但如果你的板子没有把 HDMI 热插拔连接到 SoC 的 GPIO,那就千万别配,否则 probe 阶段申请中断失败导致整个 bridge 初始化失败。没有 HPD 时,靠轮询 EDID 也能工作,只是热插拔响应慢几秒。我习惯先不配中断,把基本显示调通后再加,加之前先确认中断 GPIO 上确实有电平跳变。
下面把几个关键属性的常见错误整理成一个表,方便对照排查:
| 属性 | 作用 | 常见错误 |
|---|---|---|
compatible | 匹配驱动 | 写错成lt9611uxc导致不 probe |
reg | I2C 从地址 | 与原理图不一致 |
reset-gpios | 复位控制 | 极性反了或 pinctrl 被占用 |
vcc-supply | 主电源 regulator | 供电没起或延时不足 |
interrupts | HPD 中断 | 板子没有 HPD 硬线却配了中断 |
3.3 编译并生成 boot.img:一条命令与参数说明
MTK 的编译流程通常基于make bootimage而不是make Image。下面是我在 MT8167 平台上的最小流程:
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- # 先加载方案默认配置 make mt8167_defconfig # 用 scripts/config 直接打开桥接驱动选项,避免手工 menuconfig scripts/config --file .config -e CONFIG_DRM_LONTIUM_LT9611 make olddefconfig # 编设备树 make dtbs # 编 boot.img make bootimage -j8这里scripts/config是内核自带工具,直接修改.config里的符号,不用进 menuconfig。CONFIG_DRM_LONTIUM_LT9611如果已经被编译成模块,还要确认镜像里有没有把lt9611.ko放到vendor/lib/modules,否则 probe 会因为模块没加载而失败。MTK 的 Android 内核通常把 module 放 vendor_boot,需要单独执行make modules_install按分区路径拷贝。
make bootimage会调用 MTK 的打包脚本,把 kernel 和 dtb 封装成 Android boot image。如果你的平台不是 MT8167,把mt8167_defconfig换成方案自己的 defconfig 即可。注意make dtbs之后,必须确认arch/arm64/boot/dts/mediatek/*.dtb的修改时间更新了,有时候 Makefile 依赖没触发,会用旧 dtb 打包,这是后续黑屏的常见来源。
烧录时,操作系统需要先装好 MTK 端口驱动安装。Windows 下接入设备,如果设备管理器里始终是未知设备,就是 VCOM 驱动没装。装好之后,用 SP Flash Tool 或者方案商提供的下载工具,选择boot分区镜像,对照 scatter 文件烧写。SP Flash Tool 是 MTK 刷机工具里最常用的一种,但版本差异容易导致DA mismatch,优先用方案商在 README 里指定的版本。
如果 bootloader 还没解锁,先做好 mtk client 解 bl 操作,不然后面刷任何分区都会报ERROR : S_BROM_CMD_STARTCMD_FAIL。解锁步骤一般是先使能 OEM 解锁,再执行fastboot oem unlock,然后重启进 bootloader。注意解锁之后不要恢复原厂 lock,否则可能变砖。这是血泪教训。
4. LT9611 调试避坑:5 个真实问题的现象、原因与解决
这个标题看起来简单,实际是我在三个项目里反复踩过的坑。下面每条都按“现象、原因、解决”整理,你可以直接拿着去对照 dmesg 和寄存器。
4.1 上电后 HDMI 黑屏,但内核日志里 lt9611 已经 probe 成功
现象:开机后 dmesg 有lt9611 3-003b: LT9611 initialization done,但接上 HDMI 显示器一直是黑屏。
原因:probe 成功只代表 I2C 通信正常,不代表 DSI 链路已经传数据。最常见的根因是 LT9611 在 probe 时第一次读 EDID 读不到,HPD 还没有拉高,主控侧不知道对面显示器到底支不支持当前时序。另一种根因是 DSI 的 clock-frequency 与 LT9611 要求的 HDMI 像素时钟差太多,PLL 整不出来。
解决:先用cat /sys/class/drm/card0-DSI-1/status看 connector 状态,如果显示connected但黑屏,就是时序问题。接着在 dmesg 里查 DSI PLL 和 clock 相关日志,确认 DSI bitrate 在合理范围。我一般会加一段调试打印,把mode->clock和mode->htotal * mode->vtotal * 60输出的值对比,偏差超过几个百分点就是模式没设对。
dmesg | grep -E "lt9611|DSI|HDMI" cat /sys/class/drm/card0-DSI-1/status如果 DSI 端读到的 EDID 是空的,检查 LT9611 的 HPD 引脚是否接到中断对应的 GPIO,或者干脆去掉 dts 里的 interrupt,让驱动走轮询。EDID 轮询在 Linux DRM 里通过drm_helper_hpd_irq_event触发,没有检测到连接时,显示器拔插不会自动重试,需要在调试阶段手动触发connector->funcs->detect。
4.2 分辨率超出面板参数,画面闪屏
现象:设置 1920x1080@60 输出,画面上下滚动、间断性闪烁,偶尔花屏。
原因:LT9611 的 HDMI 输出能力虽然标称 1080p60,但 MIPI DSI 的带宽要算上 blanking。很多 MTK 方案的最高 DSI clock 有限,RGB888 的 60fps 和 30fps 的 bitrate 差一倍,超出后数据丢失就是闪烁翻车。
解决:先算实际需求:
pixel_clock (Hz) = htotal * vtotal * refresh_rate dsi_bitrate (bps) = pixel_clock * bits_per_pixel / lanes以 1920x1080@60 为例,htotal = 2200、vtotal = 1125、bpp = 24、lanes = 4,算出 DSI bitrate 约 891 Mbps。如果平台 DSI 最高只有 800 Mbps,就必须把刷新率降到 50 或减少色深到 RGB565。驱动节点里的bus-format和clock-frequency要一起改,不能只改一个。只调clock-frequency而bus-format还写 RGB888,驱动仍会按 24bpp 计算 lane 数,结果不变。
还有一个容易忽视的因素是 LT9611 内部 MIPI receiver 的 lane speed 上限。不同批次芯片规格可能不同,方案商驱动里通常会在lt9611_mipi_set里写死一个0x81之类的配置。如果你的屏参很高,可以尝试把 DSI 的non-continuous-clock打开,有时能把多余 EMI 和抖动压下去,虽然没有提升带宽,但画面稳定不少。
4.3 I2C 读取失败导致驱动初始化崩溃
现象:probe 直接报failed to read chip id或lt9611_init error -110,有时候整个 DSI probe 失败,屏幕连背光都不亮。
原因:除了地址不对,更隐蔽的是 LT9611 的供电还没起来就被访问了。dts 里vcc-supply虽然配了,但 regulator 的startup-delay-us和settling-time-us没设置,驱动读写 I2C 时芯片还在上电复位。
解决:先在 I2C 总线上手动读一次 chip id,用下面命令快速验证地址和总线:
i2cdetect -y -r 3 i2ctransfer -y 3 w1@0x3b 0x08 r1如果读不到,用示波器量 reset 和 VCC 上电时序。解决方式有两种:一种是在vcc-supply的 regulator 节点加启动延时,另一种是在驱动 probe 函数开头加msleep(50)。我更喜欢前者,功耗表现更正常,而且不用改代码。
如果 I2C 地址对但仍然报-ENXIO,检查 I2C 总线上是否有多个设备冲突。LT9611 的 address pin 是硬件决定的,同一总线上可能还有其他从设备占用地址。这时候要么改目标芯片地址,要么换到空闲 I2C。千万不要用i2c-dev随便乱读,可能导致其他从设备进入异常状态。
4.4 休眠唤醒后 LT9611 不恢复输出
现象:Android 休眠再唤醒后 dmesg 里没有报错,但 HDMI 画面消失,拔插一次才好。
原因:MTK 平台在 suspend 时把 DSI 输出关掉,同时把 LT9611 的供电或 reset 拉低。resume 时 MTK 只恢复 DSI controller,不会重新执行 LT9611 的初始化,芯片内部状态已经丢了。
解决:在 lt9611_ops 里实现atomic_check、atomic_mode_set,并在其中调用重新初始化函数。如果驱动版本没有pm_ops,可以在mtk_dsi的resume里调用 bridge 的post_disable+pre_enable。还有一个土办法,就是把 LT9611 的供电接成“常开”,reset 由 GPIO 拉高,不让它在 suspend 期间掉电。这个方案不算优雅,但在没有驱动维护能力的产品上非常可靠。
更彻底的排查方法是先确认 suspend 期间到底有没有掉电。在 dmesg 里加一个late_resume打印,量 LT9611 的 VDD 和 reset 电平。如果掉电,就是 PM_SUSPEND 的 regulator 行为;如果没掉电但驱动还是丢了配置,那多半是 DSI 的 clock 被关了。按照从电源到时钟的链路逐段查,比瞎试pm_runtime_put_sync有用得多。
4.5 修改 dts 后没生效,重刷 boot.img 却是旧状态
现象:改了 dts 里reset-gpios的 GPIO 编号,编译、烧录后 dmesg 打印的 pin 还是原来的值。
原因:MTK 的 boot 镜像里除了 kernel,还有 dtb 或者 dt.img。make dtbs生成的新 dtb 不一定被打进 boot.img,因为 Makefile 依赖经常不追踪.dtb文件变化。另外,散件目录里可能有多个 dtb,SP Flash Tool 烧的 dtb 分区和你改的不是同一个文件。
解决:检查 boot.img 里面的 dtb 内容。用方案商提供的mkbootimg解包:
mkbootimg --unpack boot.img xxd kernel_dtb.raw | head确认你改的 GPIO 出现在 raw data 里。如果没有,就是编译打包步骤错了。也可以直接单独烧 dtb 分区,把arch/arm64/boot/dts/mediatek/xxx.dtb按 scatter 文件里DTB分区名称烧入。不要依赖make bootimage内部逻辑,裸编后逐个确认文件时间戳,能省掉一个下午。
还有一个坑是 Android 的 boot 镜像可能同时包含 DTB 和 recovery ramdisk,你改了 dts 但只刷boot分区,而vendor_boot里有另一份 dtb。现在新平台都流行 vendor_boot 存放 dtb,这种情况下要用androidboot参数指定dtb_index。检查fastboot getvar current-slot,确认两个 slot 都刷了新镜像,否则 AB 系统切换时又会回到旧 dts。
5. 从黑盒到可验证:把 LT9611 的寄存器 dump 和时钟状态做成调试入口
这部分讲一个我最后沉淀下来的习惯:让 LT9611 的可调试性从“厂商没给工具”变成“自己也能出证据”。LT9611 是桥接芯片,内部寄存器很多,逐页看太慢。我一般在驱动里加一个 debugfs 入口,把关键页的寄存器全部导出来。
5.1 在 debugfs 里暴露 LT9611 寄存器
在lt9611_probe后面加几行 debugfs 创建逻辑:
#include <linux/debugfs.h> static int lt9611_regs_show(struct seq_file *s, void *unused) { struct lt9611 *lt = s->private; u8 page; for (page = 0; page < 0x08; page++) { /* 切换 page 后连续读 0x10 个寄存器 */ lt9611_write(lt, LT9611_PAGE_SELECT, page); seq_printf(s, "page %u:\n", page); for (i = 0; i < 0x10; i++) seq_printf(s, " [%02x] %02x\n", i, lt9611_read(lt, LT9611_REG_BASE + i)); } return 0; } DEFINE_SHOW_ATTRIBUTE(lt9611_regs);这段代码不用跟具体 SDK 完全一致,重点是把LT9611_PAGE_SELECT和读函数当成抽象接口,替换成你驱动里实际存在的函数即可。添加后,调试时直接:
mount -t debugfs none /sys/kernel/debug cat /sys/kernel/debug/lt9611/regs就能拿到一排寄存器值,和初始化失败后的状态对比,能快判断是不是 PLL 失锁。
5.2 用 dmesg 和寄存器快照快速定位链路
没有串口的 MTK 板子,我一般先用 adb over ethernet 连进去。MTK Android 以太网配置是在设置里打开“以太网”,然后adb connect 板子IP,实测比 USB 稳定。连进去之后,按顺序执行:
dmesg | grep -E "lt9611|DSI|HDMI" cat /sys/kernel/debug/lt9611/regs > /data/local/tmp/lt9611_regs.txt把lt9611_regs.txt拉出来,和上次正常的快照 diff,能直接看到哪一页寄存器被初始化脚本改掉。很多看起来像玄学的闪屏,其实都是某个寄存器的 bit 没写对。
5.3 每次调试的寄存器快照留在工程目录
最后是一个简单习惯:每次调完参数,把 dmesg 和 debugfs 寄存器快照存到工程目录,用日期命名。
dmesg > dmesg_$(date +%Y%m%d_%H%M).log cat /sys/kernel/debug/lt9611/regs > lt9611_regs_$(date +%Y%m%d).txt这个习惯最开始是被项目里“改了一个参数之后画面好了,但回退代码后画面又坏了”搞怕了才养成的。后来发现,对比两次快照能直接看到是哪一次改动让画面恢复,很多靠记忆回滚的状态就不会再丢。回到mtk-lt9611_stomachhcc_lt9611_mtk这个工程,我现在的第一步是先看 git diff,不急着看原理图;然后确保 debugfs 入口已经编译进去,再做任何修改前存一份寄存器快照。这套流程能少走不少弯路,希望帮到你。
本文还有配套的精品资源,点击获取