<按键驱动程序>
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int fd;
int count;
int i = 0;
int j = 0;
struct input_event key2;
//在根文件系统用cat /proc/bus/input/devices查看是event几
fd = open("/dev/event1", O_RDWR);
if (fd < 0)
{
perror("open");
return -1;
}
while (1)
{
lseek(fd, 0, SEEK_SET);
count = read(fd, &key2, sizeof(struct input_event));
if(count != sizeof(struct input_event))
{
perror("read");
}
if(EV_KEY == key2.type)
{
printf("
i = %d, type:%d, code:%d, value:%d
", i, key2.type, key2.code, key2.value);
if (key2.value)
{
i++;
printf("***********the k2 down %d times***********
", i);
}
else
{
printf("****************the k2 up*****************
");
}
}
if(EV_SYN == key2.type)
{
printf("syn event
");
if (++j == 2)
{
j = 0;
printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
");
}
}
}
close(fd);
return 0;
}
驱动程序:inputk2_drv.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <linux/timer.h>
static struct input_dev *button_dev;//定义输入设备
struct timer_list my_timer;//定义定时器结构体timer_list
//定义定时器超时处理函数
void timer_func(unsigned long data)
{
int key_value = gpio_get_value(S5PV210_GPH2(0));//上报事件给input核心层input_report_key(button_dev, KEY_A, !key_value);//按下为1//告诉input子系统上报已经完成input_sync(button_dev);//printk("[%d][%s], data=[%lu] ", __LINE__, __FUNCTION__, data);
}
static irqreturn_t button_interrupt(int irq, void *dev_id)
{
//the value of timeout is decided by the n of "jiffies + n"//timeout = n*(1000/HZ) ms(HZ=256 in this project)//the empirical value of timeout ≈ 10~100msmod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20msreturn IRQ_HANDLED;
}
static int __init button_init(void)
{
int ret;ret = gpio_request(S5PV210_GPH2(0), "key2");
if (ret)
{
printk(KERN_ERR "gpio_request Failed to register device
");
goto error1;
}
//为新输入设备分配内存并初始化
button_dev = input_allocate_device();
if (!button_dev)
{
printk(KERN_ERR "can't allocate input mem!
");
goto error2;
}
button_dev->name = "gec_input";
button_dev->id.bustype = 0x1;
button_dev->id.product = 0x2;
button_dev->id.vendor = 0x3;
button_dev->id.version = 0x4;
button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);//set_bit(EV_KEY,button_dev- >evbit[BIT_WORD(EV_KEY)])
button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);//set_bit(KEY_A, button_dev- >keybit[BIT_WORD(KEY_A)])
//注册一个输入设备
ret = input_register_device(button_dev);
if (ret)
{
printk(KERN_ERR "Failed to register device
");
goto error3;
}
//申请中断注册中断处理函数
ret = request_irq(IRQ_EINT(16), button_interrupt,
IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_DISABLED, "button", NULL);
if (ret)
{
printk(KERN_ERR "Can't request irq %d
", IRQ_EINT(16));
goto error4;
}
//定时器
init_timer(&my_timer);//初始化定时器
my_timer.function = timer_func;//注册定时器超时处理函数
return 0;
error4:
free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
input_unregister_device(button_dev);
error3:
input_free_device(button_dev);
error2:
ret = -ENOMEM;
error1:
gpio_free(S5PV210_GPH2(0));
return ret;
}
static void __exit button_exit(void)
{
gpio_free(S5PV210_GPH2(0));
free_irq(IRQ_EINT(16), NULL);
input_unregister_device(button_dev);
del_timer(&my_timer);//删除内核定时器
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE("GPL");
Makefile:
obj-m += inputk2_drv.o
PWD ?= shell pwd
KDIR := /opt/03.kernel_transplant/android-kernel-samsung-dev
all:
make -C $(KDIR) M=$(PWD) modules
cp ./inputk2_drv.ko /mini_rootfs/modules
cp ./inputk2_app /mini_rootfs/modules
rm -rf ./*.o
rm -rf ./*.order
rm -rf ./*.symvers
rm -rf ./*.mod.c
rm -rf ./.*.cmd
rm -rf ./.*.tmp*
rm -rf ./.tmp_versions
<键盘驱动程序>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/interrupt.h>
- #include <linux/platform_device.h>
- #include <linux/input.h>
- #include <linux/slab.h>
- #include <mach/regs-gpio.h>
- #include <linux/gpio.h>
- #include <linux/irq.h>
- #define DHOLE2440_KBD "dhole2440kbd"
- #define DHOLE2440_KBD_IRQ_NUM (6)
- #define KBD_NONE (0xff)
- #define KBD_UP (0)
- #define KBD_DOWN (1)
- typedef struct _dhole2440_key{
- unsigned int gpio;/*对应gpio口*/
- unsigned int irq;/*对应中断*/
- int n_key;/*键值*/
- }dhole2440_key;
- struct dhole2440_kbd{
- dhole2440_key keys[DHOLE2440_KBD_IRQ_NUM];
- struct timer_list key_timer; /*按键去抖定时器*/
- unsigned int key_status; /*按键状态*/
- struct input_dev *input;
- };
- struct dhole2440_kbd *p_dhole2440_kbd;
- struct dhole2440_kbd *get_kbd(void)
- {
- printk("get_kbd p_dhole2440_kbd=%x
", (unsigned int)p_dhole2440_kbd);
- return p_dhole2440_kbd;
- }
- void set_kbd(struct dhole2440_kbd *p_kbd)
- {
- p_dhole2440_kbd = p_kbd;
- printk("set_kbd p_kbd=%x, p_dhole2440_kbd=%x
",
- (unsigned int)p_kbd, (unsigned int)p_dhole2440_kbd);
- }
- static irqreturn_t dhole2440_kbd_handler(int irq, void *p_date)
- {
- unsigned int n_key = 0;
- struct dhole2440_kbd *p_kbd = p_date;
- unsigned int key_state = 0;
- int i;
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- {
- if( irq == p_kbd->keys[i].irq )
- {
- key_state = s3c2410_gpio_getpin(p_kbd->keys[i].gpio);
- n_key = p_kbd->keys[i].n_key;
- break;
- }
- }
- printk("dhole2440_kbd_handler n_key=%d, key_state=%d
", n_key, key_state);
- input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/
- input_sync(p_kbd->input);
- return IRQ_HANDLED;
- }
- static void kbd_free_irqs(void)
- {
- struct dhole2440_kbd *p_kbd = get_kbd();
- int i;
- printk("kbd_free_irqs p_kbd=%x
", (unsigned int)p_kbd);
-
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- free_irq(p_kbd->keys[i].irq, p_kbd);
- }
- static int kbd_req_irqs(void)
- {
- int n_ret;
- int i;
- struct dhole2440_kbd *p_kbd = get_kbd();
- printk("kbd_req_irqs p_kbd=%x
", (unsigned int)p_kbd);
- for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
- {
- n_ret = request_irq(p_kbd->keys[i].irq, dhole2440_kbd_handler, IRQ_TYPE_EDGE_BOTH, DHOLE2440_KBD, p_kbd);
- if(n_ret)
- {
- printk("%d: could not register interrupt
", p_kbd->keys[i].irq);
- goto fail;
- }
- }
- return n_ret;
- fail:
- /*因为上面申请失败的那个没有成功,所以也不要释放*/
- for(i--; i >= 0; i--)
- {
- disable_irq(p_kbd->keys[i].irq);
- free_irq(p_kbd->keys[i].irq, p_kbd);
- }
- return n_ret;
- }
- static void dhole2440_init_kbd_data(struct dhole2440_kbd *p_kbd)
- {
- printk("dhole2440_init_kbd_data p_kbd=%x
", (unsigned int)p_kbd);
- p_kbd->keys[0].gpio = S3C2410_GPG(11);
- p_kbd->keys[1].gpio = S3C2410_GPG(7);
- p_kbd->keys[2].gpio = S3C2410_GPG(6);
- p_kbd->keys[3].gpio = S3C2410_GPG(5);
- p_kbd->keys[4].gpio = S3C2410_GPG(3);
- p_kbd->keys[5].gpio = S3C2410_GPG(0);
- p_kbd->keys[0].irq = IRQ_EINT19;
- p_kbd->keys[1].irq = IRQ_EINT15;
- p_kbd->keys[2].irq = IRQ_EINT14;
- p_kbd->keys[3].irq = IRQ_EINT13;
- p_kbd->keys[4].irq = IRQ_EINT11;
- p_kbd->keys[5].irq = IRQ_EINT8;
- p_kbd->keys[0].n_key = KEY_0;
- p_kbd->keys[1].n_key = KEY_1;
- p_kbd->keys[2].n_key = KEY_2;
- p_kbd->keys[3].n_key = KEY_3;
- p_kbd->keys[4].n_key = KEY_ESC;
- p_kbd->keys[5].n_key = KEY_ENTER;
- }
- static int __devinit dhole2440_keys_probe(struct platform_device *pdev)
- {
- int err = -ENOMEM;
- struct dhole2440_kbd *p_dhole2440_keys = NULL;
- struct input_dev *input_dev = NULL;
- printk("dhole2440_keys_probe entry!
");
- p_dhole2440_keys = kmalloc(sizeof(struct dhole2440_kbd), GFP_KERNEL);
- if( !p_dhole2440_keys )
- {
- printk("dhole2440_keys_probe kmalloc error!
");
- return err;
- }
- printk("dhole2440_keys_probe p_dhole2440_keys=%x
", (unsigned int)p_dhole2440_keys);
- dhole2440_init_kbd_data(p_dhole2440_keys);
- input_dev = input_allocate_device();
- if (!input_dev)
- {
- printk("dhole2440_keys_probe input_allocate_device error!
");
- goto fail;
- }
- p_dhole2440_keys->input = input_dev;
- platform_set_drvdata(pdev, p_dhole2440_keys);
- input_dev->name = pdev->name;
- input_dev->phys = DHOLE2440_KBD"/input0";
- input_dev->id.bustype = BUS_HOST;
- input_dev->dev.parent = &pdev->dev;
- input_dev->id.vendor = 0x0001;
- input_dev->id.product = 0x0001;
- input_dev->id.version = 0x0100;
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(KEY_0, input_dev->keybit);
- __set_bit(KEY_1, input_dev->keybit);
- __set_bit(KEY_2, input_dev->keybit);
- __set_bit(KEY_3, input_dev->keybit);
- __set_bit(KEY_ESC, input_dev->keybit);
- __set_bit(KEY_ENTER, input_dev->keybit);
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
- err = input_register_device(input_dev);
- if( err )
- {
- printk("dhole2440_keys_probe input_register_device error!
");
- goto fail_allocate;
- }
- set_kbd(p_dhole2440_keys);
- err = kbd_req_irqs();
- if( err )
- {
- printk("dhole2440_keys_probe kbd_req_irqs error!
");
- goto fail_register;
- }
- printk("dhole2440_keys_probe sucess!
");
- return 0;
- fail_register:
- input_unregister_device(input_dev);
- goto fail;
- fail_allocate:
- input_free_device(input_dev);
- fail:
- kfree(p_dhole2440_keys);
- return err;
- }
- static int __devexit dhole2440_keys_remove(struct platform_device *pdev)
- {
- struct dhole2440_kbd *p_dhole2440_keys = platform_get_drvdata(pdev);
- printk("dhole2440_keys_remove entry!
");
- kbd_free_irqs();
- input_unregister_device(p_dhole2440_keys->input);
- kfree(p_dhole2440_keys);
- printk("dhole2440_keys_remove sucess!
");
- return 0;
- }
- static void dhole2440_keys_release(struct device *dev)
- {
- dev = dev;
- }
- static struct platform_driver dhole2440_keys_device_driver = {
- .probe = dhole2440_keys_probe,
- .remove = __devexit_p(dhole2440_keys_remove),
- .driver = {
- .name = DHOLE2440_KBD,
- .owner = THIS_MODULE,
- }
- };
- static struct platform_device dhole2440_device_kbd = {
- .name = DHOLE2440_KBD,
- .id = -1,
- .dev = {
- .release = dhole2440_keys_release,
- }
- };
- static int __init dhole2440_keys_init(void)
- {
- int n_ret;
- n_ret = platform_driver_register(&dhole2440_keys_device_driver);
- printk("dhole2440_keys_init 1 n_ret=%d jiffies=%lu,HZ=%d
", n_ret, jiffies, HZ);
- if( n_ret )
- return n_ret;
- n_ret = platform_device_register(&dhole2440_device_kbd);
- printk("dhole2440_keys_init 2 n_ret=%d
", n_ret);
- if( n_ret )
- goto fail;
- return n_ret;
- fail:
- platform_driver_unregister(&dhole2440_keys_device_driver);
- return n_ret;
- }
- static void __exit dhole2440_keys_exit(void)
- {
- printk("dhole2440_keys_exit
");
- platform_device_unregister(&dhole2440_device_kbd);
- platform_driver_unregister(&dhole2440_keys_device_driver);
- }
- module_init(dhole2440_keys_init);
- module_exit(dhole2440_keys_exit);
- MODULE_DESCRIPTION("dhole2440 keyboard input events driver");
- MODULE_AUTHOR("liuzhiping <lyliuzhiping@yeah.net style="word-wrap: break-word;">");
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:dhole2440 keyboard driver");
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">