Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7688062
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2011-09-30 17:44:23

/*

 * Mini-2440按键驱动

 * Lzy 2011-9-30

 */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define DEVICE_NAME   "mybut"

 

static int led_major =   0;

static int led_minor =   0;

struct cdev  *led_device;

 

static unsigned long led_table [] = {

    S3C2410_GPB(5),

    S3C2410_GPB(6),

    S3C2410_GPB(7),

    S3C2410_GPB(8),

};

 

static unsigned int led_cfg_table [] = {

    S3C2410_GPIO_OUTPUT,

    S3C2410_GPIO_OUTPUT,

    S3C2410_GPIO_OUTPUT,

    S3C2410_GPIO_OUTPUT,

};

 

struct button_irq_desc {

    int irq;

    int pin;

    int pin_setting;

    int number;

    char *name;  

};

 

static struct button_irq_desc button_irqs [] = {

    {IRQ_EINT8 , S3C2410_GPG(0) ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},

    {IRQ_EINT11, S3C2410_GPG(3) ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},

    {IRQ_EINT13, S3C2410_GPG(5) ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},

    {IRQ_EINT14, S3C2410_GPG(6) ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},

    {IRQ_EINT15, S3C2410_GPG(7) ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},

    {IRQ_EINT19, S3C2410_GPG(11),  S3C2410_GPG11_EINT19, 5, "KEY5"},

};

 

static irqreturn_t buttons_interrupt(int irq, void *dev_id)

{

    int ret;

   

    switch(irq)

    {

        case IRQ_EINT8:

            ret = s3c2410_gpio_getpin(led_table[0]);

            if(0 == ret)

            {

                s3c2410_gpio_setpin(led_table[0], 1);

            }

            else

            {

                s3c2410_gpio_setpin(led_table[0], 0);

            }

            break;

           

        case IRQ_EINT11:

            ret = s3c2410_gpio_getpin(led_table[1]);

            if(0 == ret)

            {

                s3c2410_gpio_setpin(led_table[1], 1);

            }

            else

            {

                s3c2410_gpio_setpin(led_table[1], 0);

            }

            break;

           

        case IRQ_EINT13:

            ret = s3c2410_gpio_getpin(led_table[2]);

            if(0 == ret)

            {

                s3c2410_gpio_setpin(led_table[2], 1);

            }

            else

            {

                s3c2410_gpio_setpin(led_table[2], 0);

            }

            break;

           

        case IRQ_EINT14:

            ret = s3c2410_gpio_getpin(led_table[3]);

            if(0 == ret)

            {

                s3c2410_gpio_setpin(led_table[3], 1);

            }

            else

            {

                s3c2410_gpio_setpin(led_table[3], 0);

            }

            break;

 

        default:

            break;

 

    }

   

    return IRQ_RETVAL(IRQ_HANDLED);

}

 

static int but_set(void)

{

   int i;

   int err = 0;

  

   for (i = 0; i < 4; i++)

   {

       s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

       s3c2410_gpio_setpin(led_table[i], 0);

   }

  

   for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)

   {

       if (button_irqs[i].irq < 0)

       {

           continue;

       }

       err = request_irq(button_irqs[i].irq, buttons_interrupt, 1,

                         button_irqs[i].name, (void *)&button_irqs[i]);

       if (err)

           break;

   }

 

   if (err)

   {

       i--;

       for (; i >= 0; i--)

       {

           if (button_irqs[i].irq < 0)

           {

            continue;

           }

            disable_irq(button_irqs[i].irq);

           free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

       }

       return -EBUSY;

   }

 

}

 

static int myled_release(struct inode *inode, struct file *filp)

{

    int i;

   

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

    if (button_irqs[i].irq < 0) {

        continue;

    }

    free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

    }

   

    return 0;

}

 

struct file_operations led_fops =

{

    .owner =    THIS_MODULE,

    .release =  myled_release, 

};

 

static int __init but_init(void)

{

    int result = 0;

    dev_t dev = 0;

 

    result = alloc_chrdev_region(&dev, led_minor, 1, DEVICE_NAME);

    led_major = MAJOR(dev);

    if (result < 0) {

       printk(KERN_WARNING "wfet_kb: can't get major %d\n", led_major);

       return result;

    }  

   

    led_device = kmalloc(sizeof(struct cdev), GFP_KERNEL);

    if (!led_device) {

       result = -ENOMEM;

        unregister_chrdev_region(dev, 1);

       return result;

    }

    memset(led_device, 0, sizeof(struct cdev));  

   

    cdev_init(led_device, &led_fops);

    led_device->owner = THIS_MODULE;

    result = cdev_add (led_device, dev, 1);

    if (result) {

       printk(KERN_NOTICE "Error %d adding LED device, major_%d", result, MAJOR(dev));

       kfree(led_device);

        unregister_chrdev_region(dev, 1);

       return result;

    }

 

    but_set();

   

    return 0;

}

 

 

static void but_exit(void)

{

    dev_t devno = MKDEV(led_major, led_minor); 

   

    if (led_device){

        /* Get rid of our char dev entries */  

        cdev_del(led_device); 

 

        kfree(led_device);

        led_device = NULL;

    }

 

    /* cleanup_module is never called if registering failed */

    unregister_chrdev_region(devno, 1);

 

    return;

 

}

module_init(but_init);

module_exit(but_exit);

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Lzy");

 

 源码文件: button.rar   

阅读(3024) | 评论(0) | 转发(4) |
给主人留下些什么吧!~~