打印

Linux下编写zlg7290驱动--键盘驱动编写

[复制链接]
253|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
2.1. 驱动框架搭建




键盘驱动是典型的字符设备驱动,由于zlg7290使用的是I2C总线,所以这里首先搭建一个基于input子系统的驱动框架




static int zlg7290_probe(struct i2c_client *client, const struct i2c_device_id *id)




{




return 0;




}




static int zlg7290_remove(struct i2c_client *client)




{




return 0;




}




static const struct i2c_device_id zlg7290_id[] = {




{ZLG7290_NAME, 0 },




{ }




};




MODULE_DEVICE_TABLE(i2c, zlg7290_id);




static struct i2c_driver zlg7290_driver= {




.probe = zlg7290_probe,




.remove = zlg7290_remove,




.id_table = zlg7290_id,




.driver = {




.name = ZLG7290_NAME,




.owner = THIS_MODULE,




},




};




static int __init zlg7290_init(void)




{




return i2c_add_driver(&zlg7290_driver);




}




static void __exit zlg7290_exit(void)




{




i2c_del_driver(&zlg7290_driver);




}




MODULE_AUTHOR("farsight");




MODULE_DESCRIPTION("zlg7290 driver");




MODULE_LICENSE("GPL");




module_init(zlg7290_init);




module_exit(zlg7290_exit);




2.2. Input驱动框架搭建




键盘一般在内核中被注册为input设备,所以本例也需要将我们的键盘注册为一个input设备,input设备注册相关函数及结构体如下:




struct input_dev;




struct input_dev *input_allocate_device();




int input_register_device(struct input_dev *);




input_dev是linux内核中用来描述一个input设备的结构体,这个结构体用来描述一个input设备。




input_allocate_device内核中用来为input_dev分配空间的函数,这个函数不能被kmalloc等分配内存空间的函数替代,因为这个函数处理分配空间外还做了一些基本的初始化。




input_register_device内核中用来注册input_dev到linux内核中的函数,在调用这个函数前必须完成input_dev的初始化。




如下:




C++ Code




zlg7290->key = input_allocate_device();




if (zlg7290->key == NULL) {




kfree(zlg7290);




return -ENOMEM;




}




key_dev = zlg7290->key;




key_dev->name = "zlg7290";




key_dev->id.bustype = BUS_HOST;




key_dev->id.vendor = 0x0001;




key_dev->id.product = 0x0001;




key_dev->id.version = 0x0001;




key_dev->evbit[0] = BIT_MASK(EV_KEY);




for(i = 1; i <= 64; i++) {




key_dev->keybit[BIT_WORD(key_value<i>)] |= BIT_MASK(key_value<i>);




}




ret = input_register_device(key_dev);




if (ret < 0) {




printk("Failed to register input device\n");




goto err1;




}




这部分代码input_allocate_device()和input_register_device()的使用比较好理解,需要注意的是input_dev初始化这部分内容




在这个input_dev一般需要初始化的主要有如下成员:




key_dev->name = "zlg7290";




key_dev->id.bustype = BUS_HOST;




key_dev->id.vendor = 0x0001;




key_dev->id.product = 0x0001;




key_dev->id.version = 0x0001;




这些成员主要是一些描述类信息。




key_dev->evbit[0] = BIT_MASK(EV_KEY);




for(i = 1; i <= 64; i++) {




key_dev->keybit[BIT_WORD(key_value<i>)] |= BIT_MASK(key_value<i>);




}




key_dev->evbit[0] = BIT_MASK(EV_KEY);




evbit是设备所支持的事件类型,在这里我们使用EV_KEY作为我们的事件类型,有些设备支持多种事件类型。Linux内核时间类型很多,不同设备在注册时使用不同事件类型:




#define EV_SYN 0x00




#define EV_KEY 0x01




#define EV_REL 0x02




#define EV_ABS 0x03




#define EV_MSC 0x04




#define EV_SW 0x05




#define EV_LED 0x11




#define EV_SND 0x12




#define EV_REP 0x14




#define EV_FF 0x15




#define EV_PWR 0x16




key_dev->keybit[BIT_WORD(key_value<i>)] |= BIT_MASK(key_value<i>);




keybit中每一位对应一个按键,初始化所有位都为0,当某一位被置1时,对应按键才能生效。按键需要初始化keybit,如果是其他的input设备则需要初始化其他成员,如下:




unsigned long evbit[BITS_TO_LONGS(EV_CNT)];




unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];




unsigned long relbit[BITS_TO_LONGS(REL_CNT)];




unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];




unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];




unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];




unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];




unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];




unsigned long swbit[BITS_TO_LONGS(SW_CNT)];



使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

432

主题

439

帖子

0

粉丝