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

📄 keydriver.c

📁 1) 复制libminigui-str-1.6.2.tar.gz至任意用户目录。 2) 解压此文件 tar zxvf libminigui-str-1.6.2.tar.gz 4) 将zl
💻 C
字号:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include  <linux/capability.h>
#include  <linux/smp_lock.h>
#include  <linux/module.h>
#include <linux/spinlock.h>
#include <linux/poll.h>

#include  <asm/hardware.h>
#include  <asm/io.h>
#include  <linux/irq.h>
#include  <linux/devfs_fs_kernel.h>
#include  <linux/init.h>
#include  "7289.c"
#if LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0)
#include  "linux/smp_lock.h"
#endif

#define KEY_NULL	0
//#define KEY_DOWN	0x80
#define MAX_KBD_BUF	16	/* how many do we want to buffer */

typedef unsigned char KBD_RET;

typedef struct {
	//unsigned int kbdmode;		/*KEYSTATUS_UP KEYSTATUS_DOWN and KEYSTATUS_REPEAT*/
	KBD_RET buf[MAX_KBD_BUF];		/* protect against overrun */
	unsigned int head, tail;		/* head and tail for queued events */
	wait_queue_head_t wq;
	spinlock_t lock;
	unsigned char key;
} KBD_DEV;

static KBD_DEV kbddev;

typedef struct{
	unsigned char key;
	//unsigned char RepeatCnt;
	//unsigned char Funckey;
}Zlg7290Key;
#define  zlg7289_MAJOR  18
#define BUF_HEAD	(kbddev.buf[kbddev.head])
#define BUF_TAIL	(kbddev.buf[kbddev.tail])
#define INCBUF(x,mod) 	((++(x)) & ((mod) - 1))

char   kernel_version[]=UTS_RELEASE;
devfs_handle_t  dev_handle3; 

static KBD_RET kbdRead(void)
{
	KBD_RET  kbd_ret;
	spin_lock_irq(&(kbddev.lock));
	kbd_ret= BUF_TAIL;               //读取按键值
	kbddev.tail = INCBUF(kbddev.tail, MAX_KBD_BUF);
	spin_unlock_irq(&(kbddev.lock));

	return kbd_ret;
}

static inline unsigned char s3c2410_Get_Key(void)
{
	Zlg7290Key key;
	int flags;
	static unsigned char lastkey=0;
	int oldiiccon;

	local_irq_save(flags);
	key.key = ZLG7289_Key();
	local_irq_restore(flags);
	if (key.key == 0xff)             //没有按键
			return 0;
	return key.key;
	
}

static inline void kbdEvent_raw(void)
{
	BUF_HEAD = kbddev.key;                  //将健值写近bufhead
	kbddev.head = INCBUF(kbddev.head, MAX_KBD_BUF);
	wake_up_interruptible(&(kbddev.wq));
}

void Keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
   static int keystatus,oldkey;
   //printk("in interrupt\n");
   spin_lock_irq(&(kbddev.lock));     
   keystatus = GPGDAT&0x04;
   //printk("%x\n",keystatus);
   if(!keystatus)
   {
      if((oldkey=kbddev.key=s3c2410_Get_Key())!=0xff)
      {           //读取健值
	  	 kbdEvent_raw();
      }
   } else {
         kbddev.key = oldkey|0x80;
         kbdEvent_raw();
   }
   spin_unlock_irq(&(kbddev.lock));
   EINTPEND |=(1<<10);
   SRCPND |= (1<<5);
   INTPND |= (1<<5);
}

void zlg_7289init(void)
{
   GPECON = GPECON & ~(0x3f<<22) | (0x15<<22);
   ZLG7289_Init(2000);
   ZLG7289_Reset();
   ZLG7289_Test();

}


static int  read_zlg7289(struct file *file, char *buffer, size_t count,loff_t *f_pos)
{	
	KBD_RET kbd_ret;    

retry: 
	if (kbddev.head != kbddev.tail) {
		kbd_ret = kbdRead();
		copy_to_user(buffer, (char *)&kbd_ret, sizeof(KBD_RET));
		return sizeof(KBD_RET);
	} else {
		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;
		interruptible_sleep_on(&(kbddev.wq));
		if (signal_pending(current))
			return -ERESTARTSYS;
		goto retry;
	}

	return sizeof(KBD_RET);
   
}


static int  write_zlg7289(struct file *file,const char *buf,size_t count,loff_t *f_pos)
{    
	return 0;
	
}

static int open_zlg7289(struct inode *inode,struct file *file)
{   
    kbddev.head = kbddev.tail = 0;
    init_waitqueue_head(&(kbddev.wq));
    MOD_INC_USE_COUNT;
    return 0;
}

static int release_zlg7289(struct inode *inode,struct file *file)
{
    MOD_DEC_USE_COUNT;
    return 0;
}

static int ioctl_zlg7289(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
   return 0;
}

static unsigned int s3c2410_kbd_poll(struct file *filp, struct poll_table_struct *wait)
{
  //printk("poll!\n");
  poll_wait(filp, &(kbddev.wq), wait);
  return (kbddev.head == kbddev.tail) ? 0 : (POLLIN | POLLRDNORM);
   
}

struct file_operations zlg7289_fops={

  	read :      read_zlg7289,
    write:      write_zlg7289,
	ioctl:	    ioctl_zlg7289,
	open :	    open_zlg7289,
    release:    release_zlg7289,

};

 static int __init  zlg72890_init_module(void)
{
   int result,i;
   char ret;
   int flags;
   dev_handle3 = devfs_register( NULL, "zlg7289", DEVFS_FL_DEFAULT, zlg7289_MAJOR, 0, S_IFCHR, &zlg7289_fops, NULL);
   ret = set_external_irq(IRQ_EINT10, EXT_BOTH_EDGES, GPIO_PULLUP_EN);
   result = request_irq(IRQ_EINT10,Keyboard_interrupt,SA_INTERRUPT,"fftkeyboard",NULL);
   if (result < 0) 
   { 
		printk(KERN_INFO "test: can't install interrupt\n"); 
	
   }
   local_irq_save(flags);
   zlg_7289init();
   local_irq_restore(flags);
   printk("congraulation,zlg7289 are successful registed\n");
   kbddev.head = kbddev.tail = 0;
   init_waitqueue_head(&(kbddev.wq));
   return 0;
}

static void __exit fftclr72890_module(void)
{
   //unregister_chrdev(zlg7289_major,"zlg7289");
   devfs_unregister (dev_handle3);
   free_irq(IRQ_EINT10, NULL);
   printk("exit zlg7289\n");

}
MODULE_LICENSE("GPL");

module_init(zlg72890_init_module);
module_exit(fftclr72890_module);



⌨️ 快捷键说明

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