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

📄 i2c_keyboard.c

📁 linux2.6内核下自定义键盘驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * ndvd9036 i2c keyboard driver
 *
 * Copyright (c) 2007-2008 zzvcom
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */

/*
 * This driver can handle standard i2c keyboards connected over a one way i2c
 * converter.
 */
 
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <asm/div64.h>
#include <linux/fs.h>
#include <linux/input.h>


#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/delay.h>

#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>

#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/string.h>
#include <linux/rtc.h>		/* get the user-level API */
#include <linux/bcd.h>
#include <linux/list.h>

#include <asm/mach-pnx8550/glb.h>

#include "vcomkeycode.h"

static int irq = 75;
static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
struct i2c_client *client;
I2C_CLIENT_INSMOD_1(infrared);

//struct i2c_client_address_data  addr_data;

#define DRIVER_DESC	"i2c keyboard driver"

MODULE_AUTHOR("huizuokui<huizuokui@zzvcom.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define  I2CKBDVERSION   0x0101

#define  PNX8950_MMIO_BASE 0xBBE00000
#define  I2C3_BASE         0x00069000
#define  I2C_CONTROL       0x00000000
#define  I2C_DAT           0x00000004
#define  I2C_STATUS        0x00000008
#define  I2C_ADDRESS       0x0000000C
#define  I2C_STOP          0x00000010
#define  I2C_PD            0x00000014
#define  I2C_SET_PINS      0x00000018
#define  I2C_OBS_PINS      0x0000001C
                           
#define  I2C_INT_STATUS    0x00000FE0 
#define  I2C_INT_EN        0x00000FE4 
#define  I2C_INT_CLR       0x00000FE8 
#define  I2C_INT_SET       0x00000FEC 
#define  I2C_Powerdown     0x00000FF4 
#define  Module_ID         0x00000FFC 

#define IP0105_AA                       (0x80) /* Bit in the register I2CCON     */
#define IP0105_EN                       (0x40) /* Bit in the register I2CCON     */
#define IP0105_STA                      (0x20) /* Bit in the register I2CCON     */
#define IP0105_STO                      (0x10) /* Bit in the register I2CCON     */
#define IP0105_CR2                      (0x03) /* Bits in the register I2CCON     */
#define IP0105_INTBIT                   (0x01) /* Bit in the register INT_STATUS */




static struct i2c_client *i2c_dev;
static struct i2c_driver i2c_driver_infrared;


static unsigned char atkbd_set2_keycode[512] = {
          0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
          0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
          0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
          0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
          0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
          0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
          0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
         82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
 
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125,
        173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127,
        159,  0,115,  0,164,  0,  0,116,158,  0,150,166,  0,  0,  0,142,
        157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0,
        226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112,
        110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0,
 
          0,  0,  0, 65, 99,
};

struct i2ckbd_struct {
 struct input_dev *dev;
 long xp;
 long yp;
 int count;
 int shift;
 char phys[32];
};

static void i2ckbd_timer_fire(unsigned long data);
static int i2ckbd_probe(void);


int keydown_flag=1;
static char *i2ckbd_name = "i2ckbd mouse & keyboard";
static struct i2ckbd_struct i2ckbd;
static struct timer_list i2ckbd_timer = TIMER_INITIALIZER(i2ckbd_timer_fire, 0, 0);

int i2ckbd_open(struct inode * inode, struct file * file)
{
	return 0;
}


int i2ckbd_close(struct inode * inode, struct file * file)
{
	return 0;
}


 
static struct file_operations i2ckbd_fops = {
	.owner		= THIS_MODULE,
	
	.open		= i2ckbd_open,
	
	.release	= i2ckbd_close
};

static struct miscdevice i2ckbd_driver = {
	MISC_DYNAMIC_MINOR,
	"i2ckbd",
	&i2ckbd_fops,
};


void dump_i2c_reg(void){
	  printk("-------------------------------------------------------------\r\n");
	  printk("i2c device id   = 0x%08X\r\n",MMIO(I2C3_BASE + Module_ID));
	  printk("I2C_CONTROL     = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_CONTROL));
	  printk("I2C_I2C_DAT     = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_DAT));
	  printk("I2C_STATUS      = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_STATUS));
	  printk("I2C_ADDRESS     = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_ADDRESS));
	  printk("I2C_STOP        = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_STOP));
	  printk("I2C_PD          = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_PD));
	  printk("I2C_INT_STATUS  = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_INT_STATUS));
	  printk("I2C_INT_EN      = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_INT_EN));
	  printk("I2C_INT_SET     = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_INT_SET));
	  printk("I2C_Powerdown   = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_Powerdown));
	  printk("-------------------------------------------------------------\r\n");
}

static __inline void AAOUT(int p){
        unsigned int  val ;
        val = MMIO(I2C3_BASE + I2C_CONTROL);
        if (p) { 
        	  val |= 1<<7; 
        } else { 
        	  val &= ~(1<<7); 
        }
        MMIO(I2C3_BASE + I2C_CONTROL) = val;
}
static __inline void STAOUT(int p){
	      unsigned int  val ;
        val = MMIO(I2C3_BASE + I2C_CONTROL);
        if (p) { val |= IP0105_STA; } else { val &= ~IP0105_STA; }
        MMIO(I2C3_BASE + I2C_CONTROL) = val;
}
static __inline void STOOUT(int p){
        MMIO(I2C3_BASE + I2C_STOP) = p;
}
void i2c_hardware_error(void){
	      unsigned int val;
	      
	      val =  MMIO(I2C3_BASE + I2C_CONTROL) ;
	      MMIO(I2C3_BASE + I2C_CONTROL)  =  val & (~IP0105_EN);
	      
        STAOUT(0 ); /* Don't generate START condition */
        STOOUT(1 ); /* Recover from error condition */
        AAOUT(1 );
        MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
        
	      val =  MMIO(I2C3_BASE + I2C_CONTROL) ;
	      MMIO(I2C3_BASE + I2C_CONTROL)  =  val | (IP0105_EN);
}


static irqreturn_t infrared_int(int irq, void *dev_id, struct pt_regs *regs){
	  static unsigned char key_buf[20],key_count ;
	  unsigned int uStatus ,uValue;
	  uStatus = MMIO(I2C3_BASE + I2C_STATUS);
	  udelay(1);
	  //printk("\r\nuStatus=0x%02X     ",uStatus);
	  switch(uStatus){
	  	   case 0x80:{
	  	   	    uValue = MMIO(I2C3_BASE + I2C_DAT);
	  	   	    
	  	   	    if((uValue==0x02)||(uValue==0x00)){                                //收到红外键盘命令认为是数据的开始
	  	   	    	   key_count = 0;
	  	   	    }
	  	   	    #if 1
	  	   	    if((uValue!=0x02)&&((uValue!=0x00))&&((uValue!=0xf7))&&((uValue!=0x01))&&((uValue!=0xF9))){
	  	   	    	  #if 0
	  	   	    	      printk("0x%02X  ",uValue);
	                #else
	                unsigned int i,uTemp;  
	  	   	        key_buf[key_count] = uValue;
	  	   	        key_count += 1;
	  	   	        if(key_count>=2){
	  	   	    	      uTemp = (key_buf[0]<<8) | (key_buf[1]);                     //组合收到的红外编码数据
	  	   	    	      #if 0
	  	   	    	      printk("utemp=0x%04X\r\n",uTemp);
	  	   	    	      #endif
	  	   	    	      for(i=0;i<88;i++){
	  	   	    	      	  if(uTemp == i2ckbd_set_keycode[i][0]) break;            //搜索键盘编码表格
	  	   	    	      }
	  	   	    	      
	  	   	    	      if(i<88) {                                                  //搜索到对应的键盘编码 
	  	   	    	      	  #if 0
	  	   	    	      	  printk("get a key pressed:%d\r\n",i2ckbd_set_keycode[i][1]);
	  	   	    	      	  printk("\r\n");
	  	   	    	      	  #endif
	  	   	    	      	  input_report_key(i2ckbd.dev, i2ckbd_set_keycode[i][1], 1); 
	  	   	    	          input_report_key(i2ckbd.dev, i2ckbd_set_keycode[i][1], 0);	     
	  	   	    	      	  input_sync(i2ckbd.dev);
	  	   	    	      }
	  	   	        	  key_count = 0;
	  	   	        }
	  	   	        #endif
	  	   	    }    
	  	   	    #endif
	  	   	    udelay(1);
   	  	   	  AAOUT(1);
   	  	   	  udelay(1);
	  	   	    MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	  	   	    break;
	  	   }
	  	   case 0x88:{

⌨️ 快捷键说明

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