--key.c
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/gpio.h>
- #include <linux/mm.h>
- #include <asm/io.h>
- #include <asm/module.h>
- #include <asm/uaccess.h>
- #include <mach/regs-gpio.h>
- #include <mach/hardware.h>
- #include "keydev.h"
- #define KEY_MAJOR 0
- #define DEVICE_NAME "keys"
- #define KEY_NR_DEVS 1
- static int key_major = KEY_MAJOR;
- struct cdev *devp;
- static struct class *key_class;
- static unsigned long key_table[] =
- {
- S3C2410_GPG(0),
- S3C2410_GPG(3),
- S3C2410_GPG(5),
- S3C2410_GPG(6),
- S3C2410_GPG(7),
- S3C2410_GPG(11),
- };
- static unsigned int key_cfg_table[] =
- {
- S3C2410_GPIO_INPUT,
- S3C2410_GPIO_INPUT,
- S3C2410_GPIO_INPUT,
- S3C2410_GPIO_INPUT,
- S3C2410_GPIO_INPUT,
- S3C2410_GPIO_INPUT,
- };
- static int s3c2440_key_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
- {
- switch (cmd)
- {
- case KEYDEV_POLL:
- break;
- case KEYDEV_IRQ:
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- static int s3c2440_key_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
- {
- int i, j, flag = 0;
- static int old = -1, new = -1;
- for (i = 0; i < sizeof(key_table)/sizeof(key_table[0]); ++i)
- {
- if (!s3c2410_gpio_getpin(key_table[i]))
- {
- flag = 1;
- break;
- }
- }
- if (flag)
- {
- new = i;
- for (j = 0; j < 100000; ++j);
- if (!s3c2410_gpio_getpin(key_table[i]) && new != old)
- {
- copy_to_user(buf, &i, 4);
- old = new;
- return 1;
- }
- }
- return 0;
- }
- static int s3c2440_key_open(struct inode *inode, struct file *filp)
- {
- int i;
- for (i = 0; i < sizeof(key_table)/sizeof(key_table[1]); ++i)
- s3c2410_gpio_cfgpin(key_table[i], key_cfg_table[i]);
- return 0;
- }
- static struct file_operations dev_fops =
- {
- .owner = THIS_MODULE,
- .ioctl = s3c2440_key_ioctl,
- .open = s3c2440_key_open,
- .read = s3c2440_key_read,
- };
- static int __init s3c2440_key_init(void)
- {
- int result;
- struct device *devxx;
- dev_t devno = MKDEV(key_major, 0);
- if (key_major)
- result = register_chrdev_region(devno, KEY_NR_DEVS, DEVICE_NAME);
- else
- {
- result = alloc_chrdev_region(&devno, 0, KEY_NR_DEVS, DEVICE_NAME);
- key_major = MAJOR(devno);
- printk("Major-->%d\n", key_major);
- }
- if (result < 0)
- return result;
- devp = kmalloc(sizeof(struct cdev), GFP_KERNEL);
- if (!devp)
- {
- result = -ENOMEM;
- goto fail_malloc;
- }
- memset(devp, 0, sizeof(struct cdev));
- cdev_init(devp, &dev_fops);
- devp->owner = THIS_MODULE;
- cdev_add(devp, devno, KEY_NR_DEVS);
-
- key_class = class_create(THIS_MODULE, "key_class");
- if (IS_ERR(key_class))
- {
- printk("create class fail!\n");
- goto fail_class;
- }
- devxx = device_create(key_class, NULL, devno, NULL, DEVICE_NAME);
- if (IS_ERR(devxx))
- {
- printk("create device fail!\n");
- goto fail_device;
- }
- return 0;
- fail_device:
- class_destroy(key_class);
- fail_class:
- cdev_del(devp);
- fail_malloc:
- unregister_chrdev_region(devno, KEY_NR_DEVS);
- return result;
- }
- static void __exit s3c2440_key_exit(void)
- {
- cdev_del(devp);
- device_destroy(key_class, MKDEV(key_major, 0));
- class_destroy(key_class);
- unregister_chrdev_region(MKDEV(key_major, 0), KEY_NR_DEVS);
- }
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Domod");
- module_init(s3c2440_key_init);
- module_exit(s3c2440_key_exit);
--keydev.h
- #ifndef __KEYDEV_H__
- #define __KEYDEV_H__
- #include <linux/ioctl.h>
- #define KEYDEV_IOC_MAGIC 'k'
- #define KEYDEV_POLL _IO(KEYDEV_IOC_MAGIC, 1)
- #define KEYDEV_IRQ _IO(KEYDEV_IOC_MAGIC, 2)
- #define KEYDEV_IOC_MAXNR 2
- #endif
--app-key.c
- #include "keydev.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- int main(int argc, char **argv)
- {
- int no;
- int fd;
- fd = open("/dev/keys", 0);
- if (fd < 0)
- {
- perror("open device key!");
- exit(1);
- }
- ioctl(fd, KEYDEV_POLL, 0 );
- while (1)
- {
- if (read(fd, &no, 4))
- printf("key%d is pressing!\n", no);
- }
- }
--Makefile
- ifneq ($(KERNELRELEASE),)
- obj-m := key.o
- else
-
- KDIR := /home/domod/arm/kernel/src/linux-2.6.32.2
- all:
- make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
- app:
- arm-linux-gcc app-key.c -o key
- clean:
- rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
- endif
阅读(976) | 评论(0) | 转发(0) |