http://blog.csdn.net/bingqingsuimeng/article/details/8178122(万能驱动使用input_event读取数据;其他的keyboard,joydev,mouse_dev有自己的input_event,针对性是对intput_event的补充)
驱动目前有8种;万能驱动基本可以满足;其他的是针对性的设备驱动或者是补充万能驱动不支持的设备后期增加的驱动
设备有中断,poll机制去使用自己的方式到指定虚拟地址读取寄存器的数据然后使用input_event发送数据——》evdev->read-》用户
总结:
设备innput_device
{
open(初始化设备,注册中断等)
}
中断会去读取数据->input_event(填充数据)->驱动的event
handler
{
evernt(唤醒read_读取)
connect(连接设备,初始化handle)
operations{
open(用到client,并且调用设备的open初始化设备),
read
}
}
那么我想写一个input_dev
参考amimouse.c的写法(简单)
static int __init amimouse_init(void)
{
int err;
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
return -ENODEV;
amimouse_dev = input_allocate_device();
if (!amimouse_dev)
return -ENOMEM;
amimouse_dev->name = "Amiga mouse";
amimouse_dev->phys = "amimouse/input0";
amimouse_dev->id.bustype = BUS_AMIGA;
amimouse_dev->id.vendor = 0x0001;
amimouse_dev->id.product = 0x0002;
amimouse_dev->id.version = 0x0100;
amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 配置类型包括ev_rel,ev_key
amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 设置ev_rel的标志
amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 设置ev_key的标志
amimouse_dev->open = amimouse_open;
amimouse_dev->close = amimouse_close;
err = input_register_device(amimouse_dev);
if (err) {
input_free_device(amimouse_dev);
return err;
}
return 0;
}
static const struct input_device_id mousedev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_RELBIT,
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
.keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
.relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
}, /* A mouse like device, at least one button,
two relative axes */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_RELBIT,
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
.relbit = { BIT_MASK(REL_WHEEL) },
}, /* A separate scrollwheel */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
}, /* A tablet like device, at least touch detection,
two absolute axes */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
.keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
BIT_MASK(BTN_TOOL_FINGER) },
.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
BIT_MASK(ABS_PRESSURE) |
BIT_MASK(ABS_TOOL_WIDTH) },
}, /* A touchpad */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
.keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
.absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
}, /* Mouse-like device with absolute X and Y but ordinary
clicks, like hp ILO2 High Performance mouse */
{ }, /* Terminating entry */
};
比对函数
static const struct input_device_id *input_match_device(const struct input_device_id *id,
struct input_dev *dev)
{
int i;
for (; id->flags || id->driver_info; id++) {
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
if (id->bustype != dev->id.bustype)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
if (id->vendor != dev->id.vendor)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
if (id->product != dev->id.product)
continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
if (id->version != dev->id.version)
continue;
MATCH_BIT(evbit, EV_MAX);
MATCH_BIT(keybit, KEY_MAX);
MATCH_BIT(relbit, REL_MAX);
MATCH_BIT(absbit, ABS_MAX);
MATCH_BIT(mscbit, MSC_MAX);
MATCH_BIT(ledbit, LED_MAX);
MATCH_BIT(sndbit, SND_MAX);
MATCH_BIT(ffbit, FF_MAX);
MATCH_BIT(swbit, SW_MAX);
return id;
}
return NULL;
}
还记得上一篇中的这个吗:button_dev->evbit[0] = BIT_MASK(EV_KEY); 这就是用来设置输入设备button_dev所支持的事件类型,其中有定义:
#define BIT_MASK(nr)(1UL << ((nr) % BITS_PER_LONG))
#define BITS_PER_LONG 32
input_dev.evdit支持的事件表示方法:
http://blog.csdn.net/tianxiawuzhei/article/details/7607225-----------匹配方法写的很详细
1.17
问题:
input: Unspecified device as /devices/virtual/input/input2
原因:
缺少input->name赋值
阐明:
我们使用Input子系统框架目的就是为了用户可以不需要知道我们的设备,只需要调用input2设备就行了。那么系统需要知道我们这个设备原来名字,然后map到用户可以使用的input2设备。。上面的/devices/virtual/input/其实是在/sys/目录下
增加:
{
/proc是内核和用户之间的直接沟通虚拟文件。。。。。。->/proc/bus/nput(http://blog.csdn.net/xiaocainiaoshangxiao/article/details/38091459)
->handler
->device这两个是input的架构
也就是说这个文件夹下的文件,只要cat 都会输出内核里面的一些信息,proc文件不建议去改变,建议做只读操作,由内核去改变他
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="my_first_ceh"
P: Phys=
S: Sysfs=/devices/virtual/input/input3
U: Uniq=
H: Handlers=kbd event1
B: EV=3
B: KEY=40 90004000
上面是我刚上的驱动信息
1 416 buddyinfo ioports partitions
11 5 bus irq self
2 628 cmdline kallsyms slabinfo
209 672 cpu kmsg softirqs
211 675 cpuinfo kpagecount stat
213 679 crypto kpageflags sys
222 682 devices loadavg sysvipc
228 691 diskstats locks timer_list
244 692 driver meminfo tty
251 693 execdomains misc uptime
298 696 fb modules version
3 697 filesystems mounts vmallocinfo
302 793 fs mtd vmstat
306 794 interrupts net yaffs
4 asound iomem pagetypeinfo zoneinfo
这里面有misc设备
}
{
/sys (这个是对/proc的一个副件补充)(http://www.2cto.com/os/201304/206605.html)
这个文件更多的是讲究怎么分类是对proc的整理
}
{
/dev(在这个目录中包含了所有Linux系统中使用的外部设备。但是这里并不是放的外部设备的驱动程序,这一点和windows,dos操作系统不一样。它实际上是一个访问这些外部设备的端口。)(http://www.xuexila.com/diannao/xitong/linux/339060.html)(mdev用的,用户可以直接打开的设备,所有设备总和)
/dev目录下的节点是怎么创建的?
devf或者udev会自动帮你创建得。
kobject是sysfs文件系统的基础,udev通过监测、检测sysfs来获取新创建的设备的。
}
1.查看Input驱动的方法是/dev/input/event1.....................为什么要看这个呢,因为这个是万能输入驱动evdev驱动。启动后会先匹配;打开设备都是查看/dev下面的文件。/sys还有/proc是底层查看用的
2.如果没有启动qt。就可以open-->/dev/tty1是因为会调用keyboard驱动
exec 0</dev/tty1是吧输入端变成/dev/tty1