2、JZ2440 按键驱动(查询)
驱动代码
1 #include <linux/module.h> 2 #include <linux/kernel.h> 3 #include <linux/fs.h> 4 #include <linux/init.h> 5 #include <linux/delay.h> 6 #include <asm/uaccess.h> 7 #include <asm/irq.h> 8 #include <asm/io.h> 9 #include <asm/arch/regs-gpio.h> 10 #include <asm/hardware.h> 11 12 static struct class *key_dev1_class; 13 static struct class_device *key_dev1_class_dev; 14 15 volatile unsigned long *gpfcon; 16 volatile unsigned long *gpfdat; 17 18 volatile unsigned long *gpgcon; 19 volatile unsigned long *gpgdat; 20 21 static int key_dev1_open(struct inode *inode, struct file *file) 22 { 23 /* 配置GPF0,2为输入引脚 */ 24 *gpfcon &= ~((0x3<<(0*2)) | (0x3<<(2*2))); 25 26 /* 配置GPG3,11为输入引脚 */ 27 *gpgcon &= ~((0x3<<(3*2)) | (0x3<<(11*2))); 28 return 0; 29 } 30 ssize_t key_dev1_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) 31 { 32 /* 返回4个引脚的电平 */ 33 unsigned char key_vals[4]; 34 int regval; 35 36 if (size != sizeof(key_vals)) 37 return -EINVAL; 38 39 /* 读GPF0,2 */ 40 regval = *gpfdat; 41 key_vals[0] = (regval & (1<<0)) ? 1 : 0; 42 key_vals[1] = (regval & (1<<2)) ? 1 : 0; 43 44 45 /* 读GPG3,11 */ 46 regval = *gpgdat; 47 key_vals[2] = (regval & (1<<3)) ? 1 : 0; 48 key_vals[3] = (regval & (1<<11)) ? 1 : 0; 49 50 copy_to_user(buf, key_vals, sizeof(key_vals)); 51 52 return sizeof(key_vals); 53 } 54 55 static struct file_operations key_dev1_fops = 56 { 57 .owner = THIS_MODULE, 58 .open = key_dev1_open, 59 .read = key_dev1_read, 60 }; 61 62 int major; 63 static int __init key_dev1_init(void) 64 { 65 major = register_chrdev(0,"key_dev1",&key_dev1_fops); 66 key_dev1_class = class_create(THIS_MODULE,"key_dev1"); 67 key_dev1_class_dev = class_device_create(key_dev1_class,NULL,MKDEV(major,0),NULL,"key_dev1"); 68 69 gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); 70 gpfdat = gpfcon + 1; 71 72 gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16); 73 gpgdat = gpgcon + 1; 74 return 0; 75 } 76 77 static void __exit key_dev1_exit(void) 78 { 79 unregister_chrdev(major,"key_dev1"); 80 class_device_unregister(key_dev1_class_dev); 81 class_destroy(key_dev1_class); 82 iounmap(gpfcon); 83 iounmap(gpgcon); 84 85 } 86 87 module_init(key_dev1_init); 88 module_exit(key_dev1_exit); 89 MODULE_LICENSE("GPL");
测试代码
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <fcntl.h> 4 #include <stdio.h> 5 6 /* seconddrvtest 7 */ 8 int main(int argc, char **argv) 9 { 10 int fd; 11 unsigned char key_vals[4]; 12 int cnt = 0; 13 14 fd = open("/dev/key_dev1", O_RDWR); 15 if (fd < 0) 16 { 17 printf("can't open!\n"); 18 } 19 20 while (1) 21 { 22 read(fd, key_vals, sizeof(key_vals)); 23 if (!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3]) 24 { 25 printf("%04d key pressed: %d %d %d %d\n", cnt++, key_vals[0], key_vals[1], key_vals[2], key_vals[3]); 26 } 27 } 28 29 return 0; 30 }
Makefile
1 KERN_DIR = /work/system/linux-2.6.22.6 2 3 all: 4 make -C $(KERN_DIR) M=`pwd` modules 5 6 clean: 7 make -C $(KERN_DIR) M=`pwd` modules clean 8 rm -rf modules.order 9 obj-m += key_dev1.o