信息描述部分
#define IMX6UIRQ_CNT 1
#define IMX6UIRQ_NAME "imx6uirq"
#define KEY0VALUE 0X01
#define INVAKEY 0XFF
#define KEY_NUM 1
struct irq_keydesc {
int gpio;
int irqnum;
unsigned char value;
char name[10];
irqreturn_t (*handler)(int, void *);
};
struct imx6uirq_dev{
dev_t devid;
struct cdev cdev;
struct class *class;
struct device *device;
int major;
int minor;
struct device_node *nd;
atomic_t keyvalue;
atomic_t releasekey;
struct timer_list timer;
struct irq_keydesc irqkeydesc;
unsigned char curkeynum;
};
struct imx6uirq_dev imx6uirq;
驱动编写部分
static irqreturn_t key0_handler(int irq, void *dev_id)
{
struct imx6uirq_dev *dev = (struct imx6uirq_dev *)dev_id;
printk("gpio num=%d\n", dev->irqkeydesc.gpio);
dev->curkeynum = 0;
return IRQ_RETVAL(IRQ_HANDLED);
}
static int keyio_init(void)
{
int ret = 0;
imx6uirq.nd = of_find_node_by_path("/key");
if (imx6uirq.nd== NULL){
printk("key node not find!\r\n");
return -EINVAL;
}
imx6uirq.irqkeydesc.gpio = of_get_named_gpio(imx6uirq.nd, "key-gpio", 0);
if(imx6uirq.irqkeydesc.gpio < 0)
{
printk("can not get gpio\r\n");
return -ENAVAIL;
}
ret = gpio_request(imx6uirq.irqkeydesc.gpio, "key0");
if(ret < 0)
{
printk("request gpio failed\r\n");
return -EINVAL;
}
gpio_direction_input(imx6uirq.irqkeydesc.gpio);
imx6uirq.irqkeydesc.irqnum = irq_of_parse_and_map(imx6uirq.nd, 0);
imx6uirq.irqkeydesc.handler = key0_handler;
imx6uirq.irqkeydesc.value = KEY0VALUE;
ret = request_irq(imx6uirq.irqkeydesc.irqnum, imx6uirq.irqkeydesc.handler, \
IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, imx6uirq.irqkeydesc.name, &imx6uirq);
if(ret < 0)
{
printk("irq %d request failed!\r\n", imx6uirq.irqkeydesc.irqnum);
return -EINVAL;
}
return ret;
}
void create_device(void)
{
if (imx6uirq.major) {
imx6uirq.devid = MKDEV(imx6uirq.major, 0);
register_chrdev_region(imx6uirq.devid, IMX6UIRQ_CNT, IMX6UIRQ_NAME);
} else {
alloc_chrdev_region(&imx6uirq.devid, 0, IMX6UIRQ_CNT, IMX6UIRQ_NAME);
imx6uirq.major = MAJOR(imx6uirq.devid);
imx6uirq.minor = MINOR(imx6uirq.devid);
}
cdev_init(&imx6uirq.cdev, &imx6uirq_fops);
cdev_add(&imx6uirq.cdev, imx6uirq.devid, IMX6UIRQ_CNT);
imx6uirq.class = class_create(THIS_MODULE, IMX6UIRQ_NAME);
if (IS_ERR(imx6uirq.class)) {
return PTR_ERR(imx6uirq.class);
}
imx6uirq.device = device_create(imx6uirq.class, NULL, imx6uirq.devid, NULL, IMX6UIRQ_NAME);
if (IS_ERR(imx6uirq.device)) {
return PTR_ERR(imx6uirq.device);
}
}
static int __init imx6ullirq_init(void)
{
int ret = 0;
printk("irq module init\r\n");
create_device();
keyio_init();
return ret;
}
static void __exit imx6ullirq_exit(void)
{
printk("irq module exit\r\n");
free_irq(imx6uirq.irqkeydesc.irqnum, &imx6uirq);
gpio_free(imx6uirq.irqkeydesc.gpio);
cdev_del(&imx6uirq.cdev);
unregister_chrdev_region(imx6uirq.devid, IMX6UIRQ_CNT);
device_destroy(imx6uirq.class, imx6uirq.devid);
class_destroy(imx6uirq.class);
}
module_init(imx6ullirq_init);
module_exit(imx6ullirq_exit);
执行结果如下: