#include <linux/fs.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/ioport.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/irq.h> #include <linux/interrupt.h> #include <asm/mach/irq.h> static int major = 0; static struct class *cls; /* gpecon 0x56000040 */ /* gpfcon 0x56000050 */ /* gpgcon 0x56000060 */ static volatile unsigned long *gpecon; static volatile unsigned long *gpedat; static volatile unsigned long *gpfcon; static volatile unsigned long *gpfdat; static volatile unsigned long *gpgcon; static volatile unsigned long *gpgdat; static irqreturn_t buttons_irq(int irq, void *dev_id) { char *str = (char *)dev_id; printk("irq = %d, dev_id = %s\n", irq, dev_id); return IRQ_HANDLED; } int buttons_open(struct inode *inode, struct file *file) { return 0; } ssize_t buttons_read(struct file *inode, char __user *buf, size_t size, loff_t *offset) { return 0; } static const struct file_operations buttons_fops = { .owner = THIS_MODULE, .read = buttons_read, .open = buttons_open /* 设置引脚,申请资源 */ }; int irq[] = {IRQ_EINT0, IRQ_EINT2, IRQ_EINT11, IRQ_EINT19}; char *id[] = {"K10", "K7", "K4", "K1"}; int buttons_init(void) { int i; major = register_chrdev(0, "buttons", &buttons_fops); /* sysfs ==> 挂接到/sys */ cls = class_create(THIS_MODULE, "buttons_class"); class_device_create(cls, NULL, MKDEV(major, 0), NULL, "buttons"); // mdev会根据/sys下的这些内容创建/dev/buttons gpecon = ioremap(0x56000040, 4096); gpedat = gpecon + 1; gpfcon = gpecon + 4; gpfdat = gpfcon + 1; gpgcon = gpecon + 8; gpgdat = gpgcon + 1; /* 注册中断 */ for (i = 0; i < 4; i++) { request_irq(irq[i], buttons_irq, IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, id[i], id[i]); } /* 设置GPIO为中断引脚 * 设置触发方式 * 使能中断 */ /* 设置KSCAN0(GPE11)为输出引脚,输出0 */ *gpecon &= ~(0x3 << 22); *gpecon |= (1 << 22); *gpedat &= ~(1<<11); return 0; } void buttons_exit(void) { int i; unregister_chrdev(major, "buttons"); class_device_destroy(cls, MKDEV(major, 0)); class_destroy(cls); iounmap(gpecon); for (i = 0; i < 4; i++) { free_irq(irq[i], id[i]); } } module_init(buttons_init); module_exit(buttons_exit); MODULE_LICENSE("GPL"); |