实现
kernel-5.10/drivers/input/keyboard/adc-keys.c]
过程分析
1.设备树匹配信息解析
io-channels --> 引用使用哪一路ADC
io-channels 属性 为 选择的通道号
io-channel-names 属性 表示 为申请的通道起一个别名。
keyup-threshold-microvolt 属性 表示按键抬起,saradc通道1的电压(单位微伏)。
poll-interval 表示获取ADC值的轮询间隔配置
press-threshold-microvolt 属性 表示按键按下,saradc通道1的电压。
vol-up-key, vol-down-key, menu-key, back-key 在硬件连接上,
linux,code 属性 为 按键上报的键值,键值对应的动作 为 “音量+” 。
label 表示 为按键起一个别名。
2.驱动加载之ADCKEY设备树相关参数获取和初始化
2.1 平台驱动内核内置,平台驱动加载后,当设备树匹配后,加载probe函数
2.2 probe初始化函数与注册input设备流程
(0)实例化获取设备树参数的结构体对象
st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
(1)获取设备树配置参数
1.获取通道
2.获取ADC通道类型
3.获取按键抬起的电压值(即未按下时)
(2)获取按键配置列表
||
1.获取有几个子节点
2.遍历子节点获取每个子节点的参数到map结构体列表,其中每个map
struct adc_keys_button {
u32 voltage;
u32 keycode;
};
获取设备树配置的内容是:
-press-threshold-microvolt
-linux,code
3.驱动加载之input设备注册流程
1.分配一个input device 空间
2.将ADCKEY设备树相关参数获取后的data设置drv驱动平台数据,用于后续poll使用
3.初始化input device对象
4.配置input 轮询
5.配置轮询时间间隔
6.注册Input device对象
4.驱动轮询设置分析
轮询配置主要流程:
||
源码实现
drivers/input/input-poller.c
||
input_setup_polling
依据传参的函数指针和传入的input设备dev结构体,进行初始化delayed_work,注册中断处理函数,中断处理函数会用到 传参函数指针和传入的input设备dev结构体,因为其传参到poller
input_dev_poller_work
轮询调用 函数指针 即adckey驱动中的adc_keys_poll
然后再内部调用了input_dev_poller_queue_work ,开始循环间隔调用,即自己调自己。
注意,此处是在input pdrv注册后才会进行。
5.驱动轮询处理过程与数据上报
如上poll流程,会使得轮询调用如下函数
流程大概就是
1.获取初始化时将ADCKEY设备树相关参数获取后的data设置的drv驱动平台数据
2.获取当前adc值
3.判断是否按下或者抬起,然后进行事件上报
input_report_key(struct input_dev *dev, unsigned int code, int value)
dev:需要上报的 input_dev。
code: 事件码,也就是我们注册的按键值,比如 KEY_L、 KEY_S等等。
value:事件值,比如 1 表示按键按下, 0 表示按键松开。
4.事件同步input_sync()