#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> 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; int buttons_open(struct inode *inode, struct file *file) { /* 设置KSCAN0(GPE11)为输出引脚,输出0 */ *gpecon &= ~(0x3 << 22); *gpecon |= (1 << 22); *gpedat &= ~(1<<11); /* 设置EINT0,2,11,19为输入引脚 * GPF0,2,GPG3,GPG11 */ *gpfcon &= ~((0x3<<0) | (0x3<<4)); *gpgcon &= ~((0x3<<6) | (0x3<<22)); return 0; } /* buf[0] => K1(GPG11), 0-按下, 1-松开 * buf[1] => K4(GPG3), 0-按下, 1-松开 * buf[2] => K7(GPF2), 0-按下, 1-松开 * buf[3] => K10(GPF0), 0-按下, 1-松开 */ ssize_t buttons_read(struct file *inode, char __user *buf, size_t size, loff_t *offset) { char ker_buf[4]; unsigned long val; if (size != 4) return -EINVAL; val = *gpgdat; ker_buf[0] = (val & (1<<11)) ? 1 : 0; ker_buf[1] = (val & (1<<3)) ? 1 : 0; val = *gpfdat; ker_buf[2] = (val & (1<<2)) ? 1 : 0; ker_buf[3] = (val & (1<<0)) ? 1 : 0; return copy_to_user(buf, ker_buf, 4); } static const struct file_operations buttons_fops = { .owner = THIS_MODULE, .read = buttons_read, .open = buttons_open /* 设置引脚,申请资源 */ }; int buttons_init(void) { major = register_chrdev(0, "buttons", &buttons_fops); /* sysfs */ cls = class_create(THIS_MODULE, "buttons_class"); class_device_create(cls, NULL, MKDEV(major, 0), NULL, "buttons"); gpecon = ioremap(0x56000040, 4096); gpedat = gpecon + 1; gpfcon = gpecon + 4; gpfdat = gpfcon + 1; gpgcon = gpecon + 8; gpgdat = gpgcon + 1; return 0; } void buttons_exit(void) { unregister_chrdev(major, "buttons"); class_device_destroy(cls, MKDEV(major, 0)); class_destroy(cls); iounmap(gpecon); } module_init(buttons_init); module_exit(buttons_exit); MODULE_LICENSE("GPL"); |