驱动学习-------------输入子系统
输入设备分类:根据设备产生的数据类型来分
1, 按键类型---产生的数据是一个键值(整数)
keyboard, button, joystick
2, 绝对坐标类型--产生的数据有最大值和最小值
touchscreen, gsenor
3, 相对坐标类型--产生的数据是相对于上一个数据
mouse
输入子系统的框架
应用层
-----------------------------------------------------
input handler层: drivers/input/evdev.c
1, 与用户进行交互
2, 知道如何将数据给用户,但是不知道数据是什么
注册evdev_handler
匹配成功调用evdev_connect
实现evdev_fops
将当前注册的节点放到input_handler_list里面去,然后遍历input_dev_list进行匹配
evdev里面的handle记录关系,包含handler和dev ,通过找到handler可以找到dev
---------------------------------------------------
input core层: drivers/input/input.c
1, 维护了两个链表,帮助上下两层建立连接
注册设备号创建类 实现fops
调用input函数 subsys_initcall(input_init);
核心层 有两个链表 一个是Handler_list 一个是dev_list(硬件的数据打包到链表)
-------------------------------------
input device层:
1,与硬件交互
2,知道如何从硬件中获取数据,但是不知道如何将数据给用户
默认input handler层和input core内核已经自带,如果没有自带:
make menuconfig
Device Drivers --->
Input device support --->
-*- Generic input layer (needed for keyboard, mouse, ...) //input.c
<*> Event interface // evdev.c
输入子系统编程方法:
针对input device层的编程步骤:
1, 构建input device对象
//构建对象并分配空间
static struct input_dev * key_inputdev; // input_dev描述一个具体的输入设备的对象,描述能够产生什么类型的数据
key_inputdev = input_allocate_device(void);
2, 初始化input device对象
//设置能够产生什么按键数据
key_inputdev->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
//设置产生哪些按键
key_inputdev->keybit[BIT_WORD(KEY_DOWN)]|= BIT_MASK(KEY_DOWN);
key_inputdev->keybit[BIT_WORD(KEY_UP)]|= BIT_MASK(KEY_UP);
3, 注册input device对象
input_register_device(key_inputdev);
4, 初始化硬件,并获取硬件中数据上报
irqno = IRQ_EINT(1);
//参数一:中断处理方法 参数二中断处理函数 参数三 中断触发方式 参数四 中断信息
request_irq(irqno,input_irq_key_svc,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"eint_key",NULL);
中断处理函数 input_irq_key_svc
irqreturn_t input_irq_key_svc(int irqno, void *dev_id)//中断处理方法,传递的数据
{
//获取gpio状态
int value =gpio_get_value(S5PV210_GPH0(1));
if(value) //如果按键抬起
{
//参数一为当前设备 参数二为上报哪个按键 参数三为码值
input_report_key(key_inputdev,KEY_DOWN,0); //input_event(dev, EV_KEY, code, !!value);调用该函数进行上报 ("!!value" 表示无论什么值只能为1或为0)
//每次上报完都需要同步(结束上报)
input_sync(key_inputdev);
}
else //如果按下
{
input_report_key(key_inputdev,KEY_DOWN,1);
input_sync(key_inputdev);
}
return IRQ_HANDLED;
}