kevin知识库
首页 / Audio / /audio/volume-key-waveform-issue/
整理中 创建 2026/06/06 更新 2026/06/06

记录 音量按键波形异常 的问题现象、排查过程、修改方案和验证方法。

#audio

音量按键波形异常


MT8781 音量减按键异常:KPROW0 固定拉低 + KPCOL0 输入检测方案

1. 问题背景

MT8781 项目中出现 音量减按键异常 问题。

根据硬件原理图,音量减按键不是单独 GPIO 按键,而是 keypad 矩阵按键:

Volume Down = KPROW0 + KPCOL0

对应 MT8781/MT6789 平台 pinmux 关系:

GPIO68 = KPROW0
GPIO66 = KPCOL0

也就是说,音量减按键由两根 keypad 矩阵线组合实现:


2. 原始问题分析

正常 keypad 矩阵按键需要同时配置 row 和 column,通过 keypad 驱动扫描识别按键事件。

但当前项目中并没有采用完整的 keypad row/col 扫描方式,而是参考其他项目采用 workaround:

GPIO68 / KPROW0 固定输出低电平
GPIO66 / KPCOL0 作为输入检测

这样处理后,音量减按键按下时:

KPCOL0 与 KPROW0 导通

KPROW0 已固定为低电平

KPCOL0 被拉低

keypad 驱动检测到按键事件

因此,本问题不是单纯配置 KPCOL0 就可以解决的。

因为硬件上音量减实际依赖:

KPROW0 + KPCOL0

如果只配置 GPIO66 = KPCOL0,而 GPIO68 = KPROW0 没有稳定电平,则按键按下后 KPCOL0 不一定能被有效拉低,可能导致音量减无效或波形异常。


3. DTS 修改方案

3.1 新增 gpio_key_rom pinctrl

&pio 节点中新增 gpio_key_rom,将 GPIO68 配置为普通 GPIO,并输出低电平。

&pio {
	gpio_key_rom: key_low {
		pins_cmd_dat {
			pinmux = <PINMUX_GPIO68__FUNC_GPIO68>;
			slew-rate = <1>;
			output-low;
		};
	};
};

关键点:


3.2 panel 节点绑定 key_rom

在 panel 节点中绑定该 pinctrl 状态:

pinctrl-names = "key_rom";
pinctrl-0 = <&gpio_key_rom>;

如果 panel 节点原本已经存在其他 pinctrl,例如 LCM 电源、复位、bias 相关 GPIO,不能直接覆盖原有配置,而应该追加:

pinctrl-names = "xxx", "xxx", "key_rom";
pinctrl-x = <&gpio_key_rom>;

否则可能影响屏幕上电、复位或 bias 时序。


3.3 keypad 侧配置 KPCOL0

keypad 侧仅配置 GPIO66 为 KPCOL0,并作为输入检测:

&keypad {
	pinctrl-names = "default";
	pinctrl-0 = <&kpd_pins_default>;
};

&pio {
	kpd_pins_default: kpdgpiodefault {
		pins_cmd_dat {
			pinmux = <PINMUX_GPIO66__FUNC_KPCOL0>;
			bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
			input-enable;
			input-schmitt-enable;
		};
	};
};

关键点:


4. panel 驱动修改方案

仅在 DTS 中定义 gpio_key_rom 不一定会自动生效。

需要在 panel 驱动中主动获取并选择该 pinctrl 状态。

在 panel probe 阶段增加如下逻辑:

ctx->pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(ctx->pinctrl)) {
	dev_info(dev, "cannot get panel pinctrl %ld\n",
		 PTR_ERR(ctx->pinctrl));
	ctx->pinctrl = NULL;
} else {
	ctx->gpio_key_rom = pinctrl_lookup_state(ctx->pinctrl, "key_rom");
	if (IS_ERR(ctx->gpio_key_rom)) {
		dev_info(dev, "cannot find pinctrl key_rom %ld\n",
			 PTR_ERR(ctx->gpio_key_rom));
		ctx->gpio_key_rom = NULL;
	} else {
		pinctrl_select_state(ctx->pinctrl, ctx->gpio_key_rom);
	}
}

作用:

panel probe

获取 panel 节点的 pinctrl

查找名为 key_rom 的 pinctrl state

选择 key_rom 状态

GPIO68 生效为普通 GPIO 输出低电平

5. 核心结论

本问题的本质是:

音量减硬件上由 KPROW0 + KPCOL0 构成

但当前方案没有使用完整 keypad row/col 扫描,而是采用 workaround:

GPIO68 / KPROW0 固定输出低电平
GPIO66 / KPCOL0 作为 keypad 输入

因此,最终按键检测路径为:

按下音量减

KPROW0 与 KPCOL0 导通

GPIO68 / KPROW0 已固定输出低电平

GPIO66 / KPCOL0 被拉低

keypad 驱动检测到音量减按键事件

6. 注意事项

6.1 GPIO68 不应再作为正常 KPROW0 扫描使用

本方案中 GPIO68 被配置为:

普通 GPIO 输出低电平

因此它不再作为标准 keypad row 扫描线使用。

如果后续要恢复完整 keypad 矩阵扫描,则需要重新配置:

GPIO68 = KPROW0
GPIO66 = KPCOL0

并由 keypad 驱动统一管理 row/col。


6.2 panel pinctrl 不要覆盖原有配置

如果 panel 节点已有其他 pinctrl 状态,例如:

lcm_rst_low
lcm_rst_high
bias_en_low
bias_en_high

新增 key_rom 时必须追加,而不是替换。

错误风险:

覆盖 panel 原有 pinctrl

LCM 电源 / 复位 / bias 配置丢失

可能导致屏幕不开机、白屏、花屏或上电时序异常

6.3 需要确认 pinctrl select 是否真正执行

DTS 中写了:

pinctrl-names = "key_rom";
pinctrl-0 = <&gpio_key_rom>;

但是否生效,取决于驱动是否调用:

pinctrl_select_state(ctx->pinctrl, ctx->gpio_key_rom);

建议通过 kernel log 确认是否有以下异常:

cannot get panel pinctrl
cannot find pinctrl key_rom

如果没有报错,并且音量减恢复正常,说明 key_rom 状态已正确生效。


7. 验证结果

合入修改后,音量减按键恢复正常。

验证结论:

GPIO68 固定输出低电平生效
GPIO66 KPCOL0 能够检测到按键低电平变化
音量减按键功能恢复

8. 推荐提交说明

dts: configure GPIO68 low to fix volume down key issue

或中文描述:

配置 GPIO68 输出低电平,修复音量减按键异常

更完整版本:

MT8781 音量减按键由 KPROW0 + KPCOL0 构成。
参考项目 workaround,将 GPIO68/KPROW0 配置为普通 GPIO 输出低电平,
GPIO66/KPCOL0 作为 keypad 输入检测。
按下音量减时 KPCOL0 被 GPIO68 拉低,从而恢复按键检测功能。