⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc140_button.c

📁 嵌入式Linux2.6.14下的button源码
💻 C
字号:
/**********************************************************************

 **********************************************************************/
#include <linux/config.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/init.h> 

#include <linux/miscdevice.h> 
#include <linux/sched.h> 
#include <linux/delay.h> 
#include <linux/poll.h> 
#include <linux/spinlock.h> 
#include <linux/delay.h> 
#include <linux/interrupt.h>
#include <linux/wait.h>


#include <asm/irq.h>
#include <asm/hardware.h> 
#include <asm/arch/regs-gpio.h> 
#include <linux/device.h> 
#include <linux/devfs_fs_kernel.h> 
#include <linux/types.h> 
#include <linux/cdev.h> 
#include <linux/errno.h> 
#include <asm/uaccess.h> 
#include <asm/io.h>
#include <asm/arch/regs-mem.h>

#define   	DEVICE_NAME		"io_button" 
#define   	MAX_BUTTON_BUF  16
#define  	 BUF_HEAD    	(buttondev.buf[buttondev.head])     
#define	 	BUF_TAIL   	   	(buttondev.buf[buttondev.tail])     
#define 	INCBUF(x,mod)   ((++(x)) & ((mod)-1))  

#define CPLD_IO_CFG_BASE	(0xE1400000)
#define CPLD_IO_DATA_BASE	(0xE1000000)
#define	ROW					(0)
#define COL					(0x200000)

#define 	REPEAT_DELAY	HZ/10

static int flag = 0;
static unsigned int oldkey=0xffff;
static int  pc140_button_major = 0;



typedef struct {           
    unsigned char buf[MAX_BUTTON_BUF];  
    unsigned int head,tail;           
    wait_queue_head_t wq;         
} BUTTON_DEV;
static BUTTON_DEV buttondev;
struct timer_list button_timer;

static int buttonstatus[64]={0x7f7f,0x7fbf,0x7fdf,0x7fef,0x7ff7,0x7ffb,0x7ffd,0x7ffe,
							 0xbf7f,0xbfbf,0xbfdf,0xbfef,0xbff7,0xbffb,0xbffd,0xbffe,
							 0xdf7f,0xdfbf,0xdfdf,0xdfef,0xdff7,0xdffb,0xdffd,0xdffe,	
							 0xef7f,0xefbf,0xefdf,0xefef,0xeff7,0xeffb,0xeffd,0xeffe,	
							 0xf77f,0xf7bf,0xf7df,0xf7ef,0xf7f7,0xf7fb,0xf7fd,0xf7fe,	
							 0xfb7f,0xfbbf,0xfbdf,0xfbef,0xfbf7,0xfbfb,0xfbfd,0xfbfe,	
							 0xfd7f,0xfdbf,0xfddf,0xfdef,0xfdf7,0xfdfb,0xfdfd,0xfdfe,	
							 0xfe7f,0xfebf,0xfedf,0xfeef,0xfef7,0xfefb,0xfefd,0xfefe,			
};										//row:15--8   col:7--0


static void setdata(unsigned int pin,unsigned char status)
{
	outb(0x00,(CPLD_IO_CFG_BASE + pin));
	outb(status,(CPLD_IO_DATA_BASE + pin));	
}

static unsigned char getdata(unsigned int pin)
{	
	unsigned char status;
	outb(0xff,(CPLD_IO_CFG_BASE + pin));
	status=inb((CPLD_IO_DATA_BASE + pin));
	return status;
}

static void storekey(unsigned int key)
{
	int i;
	for(i=0;i<64;i++)
	{
		if(key==buttonstatus[i]){ 
			BUF_HEAD=i;	
			buttondev.head=INCBUF(buttondev.head,MAX_BUTTON_BUF);
			flag = 1;
			wake_up_interruptible(&(buttondev.wq));
			break;
		}
	}		
}

static unsigned char buttonRead(void)
{
    unsigned char button_ret;
    button_ret=BUF_TAIL;
    buttondev.tail=INCBUF(buttondev.tail,MAX_BUTTON_BUF);
    return button_ret;
}

static void pc140_but_timer_callback(unsigned long data)
{
	unsigned char colstatus,rowstatus;
	unsigned int newkey;
	
	setdata(ROW,0xff);
	setdata(COL,0x00);
	rowstatus = getdata(ROW);
	setdata(ROW,0x00);
	setdata(COL,0xff);
	colstatus = getdata(COL);
	newkey = colstatus|(rowstatus<<8);
printk("key:%d",newkey);
	
	if(((oldkey^newkey)&newkey)!=0){
		storekey(newkey);
	}
	oldkey=newkey;
	mod_timer(&button_timer, jiffies + REPEAT_DELAY);
}

static ssize_t pc140_button_read(struct file *filp, char *buff, size_t count,loff_t *offset)
{	

    static unsigned char button_ret;
 retry:
	if(buttondev.head!=buttondev.tail) 
	{
    button_ret=buttonRead();
    copy_to_user(buff,(char *)&button_ret,sizeof(unsigned char));
    return sizeof(unsigned char);
	 }
    else
	 {
    	if(filp->f_flags & O_NONBLOCK)
        return -EAGAIN;
   	 wait_event_interruptible(buttondev.wq,flag);
   	 flag=0;
   	 if(signal_pending(current))
      		   {
      	  printk("rturn -ERESTARTSYS\n");
      	  return -ERESTARTSYS;
        	  }
    goto retry;
	}

    return sizeof(unsigned char);
}

static irqreturn_t pc140_button_open(struct inode * inode, struct file * filp)
{
   buttondev.head=buttondev.tail=0;
   
 	init_timer(&button_timer); 
 	button_timer.function = pc140_but_timer_callback;
	button_timer.data     = 0;
	
	mod_timer(&button_timer, jiffies + REPEAT_DELAY);	

				
	return 0;
}

static int pc140_button_close(struct inode * inode, struct file * filp)
{
	return 0;
}

static struct file_operations pc140_button_fops = { 
	.owner = THIS_MODULE, 
	.open  = pc140_button_open,
	.release=pc140_button_close,
	.read  = pc140_button_read,
}; 

static int __init pc140_button_init(void)
{
   int ret;
		unsigned int bswcon = inl((unsigned int)S3C2410_BWSCON);
		//printk("S3C2410_BWSCON = 0x%08x\n",bswcon);
		bswcon = (bswcon & 0xFFFCFFFF) | 0x00000000;
		outl(bswcon,(unsigned int)S3C2410_BWSCON);
		bswcon = inl((unsigned int)S3C2410_BWSCON);
		//printk("S3C2410_BWSCON = 0x%08x\n",bswcon);
		outb(0xF0, (0xE0000000 + 0x01E00000 + 1));

   ret = register_chrdev(0,DEVICE_NAME,&pc140_button_fops);
    if(ret < 0) 
  	      {
       printk("button: can't get major number\n");
       return ret;
   	     }
        pc140_button_major = ret;

      #ifdef CONFIG_DEVFS_FS   
    ret = devfs_mk_cdev(MKDEV(pc140_button_major,0),  S_IFCHR | S_IRUGO | S_IWUSR,DEVICE_NAME);
     if(ret)
    	    {
      unregister_chrdev(pc140_button_major,DEVICE_NAME); 
      printk("pc140_button: can't make char device fo devfs\n");
      return ret;
    	    }
      #endif
    init_waitqueue_head(&(buttondev.wq));
    printk(DEVICE_NAME"initialized\n");
setdata(ROW,0);
setdata(COL,0);
		return 0;

}

static void __exit pc140_button_exit(void)
{

        #ifdef CONFIG_DEVFS_FS
                devfs_remove(DEVICE_NAME);
        #endif  
        unregister_chrdev(pc140_button_major,DEVICE_NAME); 
        printk("button driver removed\n"); 
setdata(ROW,0xff);
setdata(COL,0xff);
}

module_init(pc140_button_init);
module_exit(pc140_button_exit);

MODULE_ALIAS(DEVICE_NAME); 
MODULE_DESCRIPTION("pc140 button Driver");
MODULE_AUTHOR("feng");
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -