标签:
这里简单写了个旋钮驱动,还需继续完善。
#include<linux/init.h>
#include<linux/module.h>
#include<linux/gpio.h>
#include<linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include<linux/platform_device.h>
#include <linux/workqueue.h>
#define knod_pin1 56
#define knod_pin2 55
struct input_dev *input_dev;
struct work_struct knod1_work;
struct work_struct knod2_work;
int knod_pin1_irq;
int knod_pin2_irq;
static void knod1_report_key(struct work_struct *work)
{
}
static void knod2_report_key(struct work_struct *work)
{
}
static irqreturn_t knod_pin1_interrupt_hander(int irq, void *dev_id)
{
int value;
value = gpio_get_value(knod_pin2);
if (value)
{
input_report_key(input_dev, KEY_VOLUMEUP, 1);
input_sync(input_dev);
printk("knod positive\n");
}
else
{
input_report_key(input_dev, KEY_VOLUMEDOWN, 1);
input_sync(input_dev);
printk("knod inversion\n");
}
return IRQ_HANDLED;
}
static irqreturn_t knod_pin2_interrupt_hander(int irq, void *dev_id)
{
int value;
value = gpio_get_value(knod_pin1);
if (value)
{
input_report_key(input_dev, KEY_VOLUMEUP, 1);
input_sync(input_dev);
printk("knod positive\n");
}
else
{
input_report_key(input_dev, KEY_VOLUMEDOWN, 1);
input_sync(input_dev);
printk("knod inversion\n");
}
return IRQ_HANDLED;
}
void request_knod_irq(void)
{
int result;
knod_pin1_irq = gpio_to_irq(knod_pin1);
knod_pin2_irq = gpio_to_irq(knod_pin2);
result =request_irq(knod_pin1_irq, knod_pin1_interrupt_hander,
IRQ_TYPE_EDGE_FALLING, "knod_pin1", NULL);
if (result < 0)
printk("request irq %d err!\n", knod_pin1);
result =
request_irq(knod_pin2_irq, knod_pin2_interrupt_hander,
IRQ_TYPE_EDGE_RISING, "knod_pin2", NULL);
if (result < 0)
printk("request irq %d err!\n", knod_pin2);
printk("request irq ok!\n");
}
int register_input_device(void)
{
int ret;
input_dev = input_allocate_device();
if (!input_dev)
{
printk("failed to allocate input device err!\n");
return -1;
}
input_dev->name = "knod";
set_bit(EV_KEY, input_dev->evbit);
set_bit(KEY_VOLUMEUP, input_dev->keybit);
set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
ret = input_register_device(input_dev);
if (ret)
{
printk("faild to register input device!\n");
input_free_device(input_dev);
return -1;
}
return 0;
}
static int __devinit knod_probe(struct platform_device *pdev)
{
printk("%s\n", __FUNCTION__);
request_knod_irq();
register_input_device();
INIT_WORK(&knod1_work, knod1_report_key);
INIT_WORK(&knod2_work, knod2_report_key);
return 0;
}
static int __devexit knod_remove(struct platform_device *pdev)
{
free_irq(knod_pin1_irq, NULL);
free_irq(knod_pin2_irq, NULL);
input_unregister_device(input_dev);
input_free_device(input_dev);
return 0;
}
static struct platform_driver knod_driver = {
.driver = { .name = "knod",
.owner =THIS_MODULE,
},
.probe =knod_probe,
.remove = __devexit_p(knod_remove),
};
static struct platform_device knod_device = {
.name = "knod",
};
static int knod_init(void)
{
printk(KERN_ALERT "knod_init!");
platform_device_register(&knod_device);
return platform_driver_register(&knod_driver);
}
static void knod_exit(void)
{
printk(KERN_ALERT "knod_exit!");
platform_driver_unregister(&knod_driver);
platform_device_unregister(&knod_device);
}
module_init(knod_init);
module_exit(knod_exit);
MODULE_LICENSE("Dual BSD/GPL");标签:
原文地址:http://blog.csdn.net/mike8825/article/details/51335552