歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

Linux下的旋鈕驅動

這裡簡單寫了個旋鈕驅動,還需繼續完善。

正旋輸出

反旋輸出

#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");

Copyright © Linux教程網 All Rights Reserved