這裡簡單寫了個旋鈕驅動,還需繼續完善。
正旋輸出
反旋輸出
#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 //gpio引腳號 #define knod_pin2 55 //gpio引腳號 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");