Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80258
  • 博文数量: 15
  • 博客积分: 346
  • 博客等级: 一等列兵
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-14 17:20
文章分类
文章存档

2012年(15)

分类: LINUX

2012-05-19 20:59:02

--key.c

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/errno.h>
  5. #include <linux/sched.h>
  6. #include <linux/init.h>
  7. #include <linux/cdev.h>
  8. #include <linux/device.h>
  9. #include <linux/gpio.h>
  10. #include <linux/mm.h>
  11. #include <linux/irq.h>
  12. #include <linux/interrupt.h>
  13. #include <asm/io.h>
  14. #include <asm/module.h>
  15. #include <asm/uaccess.h>
  16. #include <asm/irq.h>
  17. #include <mach/regs-gpio.h>
  18. #include <mach/hardware.h>

  19. #include "keydev.h"
  20. #define BUTTON_MAJOR 0
  21. #define DEVICE_NAME "button"
  22. #define BUTTON_NR_DEVS 1
  23. static int button_major = BUTTON_MAJOR;

  24. struct button_dev
  25. {
  26.     struct cdev dev;
  27.     wait_queue_head_t button_queue;
  28.     struct fasync_struct *async_queue;
  29. };
  30. struct button_dev *devp;
  31. static struct class *button_class;
  32. static volatile int press_no = -1;

  33. struct button_irq_desc
  34. {
  35.     int irq;
  36.     int pin;
  37.     int flags;
  38.     int no;
  39.     char *name;
  40. };

  41. static struct button_irq_desc button_irq_table [] =
  42. {
  43.     {IRQ_EINT8 , S3C2410_GPG(0) , S3C2410_GPG0_EINT8 , 0, "KEY0"},
  44.     {IRQ_EINT11, S3C2410_GPG(3) , S3C2410_GPG3_EINT11 , 1, "KEY1"},
  45.     {IRQ_EINT13, S3C2410_GPG(5) , S3C2410_GPG5_EINT13 , 2, "KEY2"},
  46.     {IRQ_EINT14, S3C2410_GPG(6) , S3C2410_GPG6_EINT14 , 3, "KEY3"},
  47.     {IRQ_EINT15, S3C2410_GPG(7) , S3C2410_GPG7_EINT15 , 4, "KEY4"},
  48.     {IRQ_EINT19, S3C2410_GPG(11), S3C2410_GPG11_EINT19, 5, "KEY5"},
  49. };

  50. static int s3c2440_key_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
  51. {
  52.     switch (cmd)
  53.     {
  54.         case KEYDEV_POLL:
  55.             break;
  56.         case KEYDEV_IRQ:
  57.             break;
  58.         default:
  59.             return -EINVAL;
  60.     }
  61.     return 0;
  62. }

  63. static int s3c2440_key_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
  64. {
  65.     int err;
  66.     err = copy_to_user(buf, (void *)&press_no, sizeof(int));
  67.     return err ? -EFAULT : 0;
  68. }


  69. static int s3c2440_key_open(struct inode *inode, struct file *filp)
  70. {
  71.     struct button_dev *dev;
  72.     dev = container_of(inode->i_cdev, struct button_dev, dev);
  73.     filp->private_data = dev;
  74.     return 0;
  75. }

  76. static int s3c2440_key_fasync(int fd, struct file *filp, int mode)
  77. {
  78.     struct button_dev *dev = filp->private_data;
  79.     return fasync_helper(fd, filp, mode, &dev->async_queue);
  80. }

  81. static int s3c2440_key_release(struct inode *inode, struct file *filp)
  82. {
  83.     s3c2440_key_fasync(-1, filp, 0);
  84.     return 0;
  85. }

  86. static struct file_operations dev_fops =
  87. {
  88.     .owner = THIS_MODULE,
  89.     .ioctl = s3c2440_key_ioctl,
  90.     .open = s3c2440_key_open,
  91.     .read = s3c2440_key_read,
  92.     .release = s3c2440_key_release,
  93.     .fasync = s3c2440_key_fasync,
  94. };

  95. static irqreturn_t button_irq_handler(int irq, void *dev_id)
  96. {
  97.     int i = *(int *)dev_id;
  98.     if (!s3c2410_gpio_getpin(button_irq_table[i].pin))
  99.     {
  100.         press_no = i;
  101.         if (devp->async_queue)
  102.             kill_fasync(&devp->async_queue, SIGIO, POLL_OUT);
  103.     }
  104.     return IRQ_RETVAL(IRQ_HANDLED);
  105. }

  106. static void s3c2440_key_setup_irq(void)
  107. {
  108.     int i, err;
  109.     for (i = 0; i < sizeof(button_irq_table)/sizeof(button_irq_table[0]); ++i)
  110.     {
  111.         err = request_irq(button_irq_table[i].irq, button_irq_handler, IRQ_TYPE_EDGE_BOTH, button_irq_table[i].name, (void *)&button_irq_table[i].no);    

  112.         if (err)
  113.             printk("apply fail-->%d\n", i);
  114.     }
  115. }

  116. static void s3c2440_key_free_irq(void)
  117. {
  118.     int i;
  119.     for (i = 0; i < sizeof(button_irq_table)/sizeof(button_irq_table[0]); ++i)
  120.     {
  121.         free_irq(button_irq_table[i].irq, &button_irq_table[i].no);
  122.     }
  123. }

  124. static int __init s3c2440_key_init(void)
  125. {
  126.     int result;
  127.     struct device *devxx;
  128.     dev_t devno = MKDEV(button_major, 0);

  129.     if (button_major)
  130.         result = register_chrdev_region(devno, BUTTON_NR_DEVS, DEVICE_NAME);
  131.     else
  132.     {
  133.         result = alloc_chrdev_region(&devno, 0, BUTTON_NR_DEVS, DEVICE_NAME);
  134.         button_major = MAJOR(devno);
  135.         printk("Major-->%d\n", button_major);
  136.     }

  137.     if (result < 0)
  138.         return result;

  139.     devp = kmalloc(sizeof(struct button_dev), GFP_KERNEL);
  140.     if (!devp)
  141.     {
  142.         result = -ENOMEM;
  143.         goto fail_malloc;
  144.     }
  145.     memset(devp, 0, sizeof(struct button_dev));

  146.     cdev_init(&devp->dev, &dev_fops);
  147.     devp->dev.owner = THIS_MODULE;

  148.     cdev_add(&devp->dev, devno, BUTTON_NR_DEVS);

  149.     s3c2440_key_setup_irq();
  150.     init_waitqueue_head(&devp->button_queue);
  151.     
  152.     button_class = class_create(THIS_MODULE, "button_class");
  153.     if (IS_ERR(button_class))
  154.     {
  155.         printk("create class fail!\n");
  156.         goto fail_class;
  157.     }
  158.     devxx = device_create(button_class, NULL, devno, NULL, DEVICE_NAME);
  159.     if (IS_ERR(devxx))
  160.     {
  161.         printk("create device fail!\n");
  162.         goto fail_device;
  163.     }
  164.     return 0;

  165. fail_device:
  166.     class_destroy(button_class);
  167. fail_class:
  168.     cdev_del(&devp->dev);
  169. fail_malloc:
  170.     unregister_chrdev_region(devno, BUTTON_NR_DEVS);
  171.     return result;
  172. }


  173. static void __exit s3c2440_key_exit(void)
  174. {
  175.     s3c2440_key_free_irq();
  176.     cdev_del(&devp->dev);
  177.     device_destroy(button_class, MKDEV(button_major, 0));
  178.     class_destroy(button_class);
  179.     unregister_chrdev_region(MKDEV(button_major, 0), BUTTON_NR_DEVS);
  180. }


  181. MODULE_LICENSE("GPL");
  182. MODULE_AUTHOR("Domod");
  183. module_init(s3c2440_key_init);
  184. module_exit(s3c2440_key_exit);
--keydev.h

点击(此处)折叠或打开

  1. #ifndef __KEYDEV_H__
  2. #define __KEYDEV_H__

  3. #include <linux/ioctl.h>
  4. #define KEYDEV_IOC_MAGIC 'k'

  5. #define KEYDEV_POLL _IO(KEYDEV_IOC_MAGIC, 1)
  6. #define KEYDEV_IRQ _IO(KEYDEV_IOC_MAGIC, 2)

  7. #define KEYDEV_IOC_MAXNR 2

  8. #endif
--app-key.c

点击(此处)折叠或打开

  1. #include "keydev.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <signal.h>
  7. #include <sys/ioctl.h>

  8. int fd;
  9. void input_handler(int num)
  10. {
  11.     int i;
  12.     fd = open("/dev/button", 0);
  13.     read(fd, &i, 4);
  14.     printf("key%d is pressing!\n", i);
  15. }

  16. int main(int argc, char **argv)
  17. {
  18.     int fd, oflags;

  19.     fd = open("/dev/button", 0);
  20.     signal(SIGIO, input_handler);
  21.     fcntl(fd, F_SETOWN, getpid());//设置接收信号的进程为当前进程
  22.     oflags = fcntl(fd, F_GETFL);//读取当前得文件属性
  23.     fcntl(fd, F_SETFL, oflags | FASYNC);


  24.     while(1);
  25. }
--Makefile

点击(此处)折叠或打开

  1. ifneq ($(KERNELRELEASE),)

  2. obj-m := key.o

  3. else

  4. KDIR := /home/domod/arm/kernel/src/linux-2.6.32.2
  5. all:
  6. make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
  7. app:
  8. arm-linux-gcc app-key.c -o key
  9. clean:
  10. rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*


  11. endif

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