#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
static unsigned int buttons_major=0;
static struct class *buttons_class =NULL;
static volatile unsigned long *gpecon;
static volatile unsigned long *gpedat;
static volatile unsigned long *gpgcon;
static volatile unsigned long *gpgdat;
static irqreturn_t buttons_handler(int irq, void *dev_id)
{
/*做你想做得事情*/
printk("irq =%d \n",irq);
return IRQ_HANDLED;
}
static int buttons_open(struct inode *inode, struct file *file)
{
/*将KSCAN0设置为输出管脚*/
*gpecon &=~(0x03<<22);
*gpecon |=(0x01<<22);
/*将KSCAN0输出为0*/
*gpedat &=~(0x1<<11);
#if 0
/*将GPG11设置为中断管脚*/
*gpgcon &=~(0x03<<22);
*gpgcon |=(0x02<<22);
#endif
return 0;
}
ssize_t buttons_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
return 0;
}
static ssize_t buttons_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
return 0;
}
static int buttons_close(struct inode *inode, struct file *file)
{
free_irq(IRQ_EINT19,"a");
return 0;
}
/*2. 构建file_operations结构体*/
static struct file_operations led_fops={
.owner =THIS_MODULE,
.open =buttons_open,
.write =buttons_write,
.read =buttons_read,
.release =buttons_close,
};
/*3. 实现入口函数*/
static int __init led_init(void)
{
int ret;
/*1.注册*/
/*1.1 申请主设备号*/
#if 0
/*1.2 静态的申请主设备号*/
ret=register_chrdev(led_major,"led",&led_fops);
#else
/*1.3 动态的申请主设备号*/
buttons_major =register_chrdev(0,"buttons",&led_fops);
#endif
/*2. 构建设备节点*/
buttons_class =class_create(THIS_MODULE,"buttons_class");
class_device_create(buttons_class,NULL,MKDEV(buttons_major,0),NULL,"buttons");
/*注册中断*/
ret=request_irq(IRQ_EINT19,buttons_handler,IRQF_SHARED|IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"k1","a");
/*第一设置相应的管脚为中断管脚*/
/*设置触发方式*/
/*使能中断*/
/*3.将物理地址映射为虚拟地址*/
gpecon =ioremap(0x56000040,4096);
gpedat =gpecon +1;
#if 0
gpgcon=ioremap(0x56000060,8);
gpgdat =gpgcon+1;
#endif
return 0;
}
/*4.实现出口函数*/
static void __exit led_exit(void )
{
unregister_chrdev(buttons_major,"buttons");
class_destroy(buttons_class);
class_device_destroy(buttons_class,MKDEV(buttons_major,0));
iounmap(gpecon);
iounmap(gpgcon);
//free_irq(IRQ_EINT19,"a");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
///
//test
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
int main(int argc, char **argv)
{
int fd;
fd =open("/dev/buttons", O_RDWR);
if(fd<0)
{
printf("cannot open the dev!\n");
return -1;
}
while(1);
return 0;
}