rk3568 音量键工作流程
关键字 rk3568、音量、按键 rk3568中音量键设备节点: /dev/input/event2 /sys/class/input/input2 设备树文件配置,有三处相关配置,且都生成有相关设备节点,但调节音量实际用的是adc-keys: 驱动文件 驱动文件位置: out/kernel/src_tmp/lin
·
关键字
rk3568、音量、按键、volume、key
rk3568中音量键设备节点:
/dev/input/event2
/sys/class/input/input2
设备树文件配置
有三处相关配置,且都生成有相关设备节点,但调节音量实际用的是adc-keys(由于内核要打很多补丁,当前展示out目录下打完补丁后的文件):
驱动文件
驱动文件位置(由于可能打补丁,展示的out目录下路径,如果需要源码路径按文件名搜索即可):
out/kernel/src_tmp/linux-5.10/drivers/input/keyboard/adc-keys.c
初始化:
static int adc_keys_probe(struct platform_device *pdev)
{
// 设置输入设备input的属性等
... ...
error = input_setup_polling(input, adc_keys_poll); // 设置轮询函数
if (error) {
dev_err(dev, "Unable to set up polling: %d\n", error);
return error;
}
if (!device_property_read_u32(dev, "poll-interval", &value)) // 设置轮询间隔 100ms, dtsi文件中有配置“poll-interval = <100>;”
input_set_poll_interval(input, value);
error = input_register_device(input); // 注册输入设备
if (error) {
dev_err(dev, "Unable to register input device: %d\n", error);
return error;
}
return 0;
}
轮询函数
static void adc_keys_poll(struct input_dev *input) // 100ms循环一次
{
struct adc_keys_state *st = input_get_drvdata(input);
int i, value, ret;
u32 diff, closest = 0xffffffff;
int keycode = 0;
ret = iio_read_channel_processed(st->channel, &value);
if (unlikely(ret < 0)) {
/* Forcibly release key if any was pressed */
value = st->keyup_voltage;
} else {
for (i = 0; i < st->num_keys; i++) {
diff = abs(st->map[i].voltage - value);
if (diff < closest) {
closest = diff;
keycode = st->map[i].keycode;
}
}
}
if (abs(st->keyup_voltage - value) < closest)
keycode = 0;
if (st->last_key && st->last_key != keycode)
input_report_key(input, st->last_key, 0); // 检测到按键事件后上报按键事件
if (keycode)
input_report_key(input, keycode, 1);
input_sync(input);
st->last_key = keycode;
}
上报按键事件后,工作流程和电源键类似,由多模接收到按键事件后,传递给订阅此事件的模块,如音频,适配模块等可以订阅此事件,然后调用音量接口调节音量
更多推荐
所有评论(0)