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

📄 i2c_keyboard.c

📁 linux2.6内核下自定义键盘驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	  	   	    printk("0x88 :DAT=0x%02X\r\n",MMIO(I2C3_BASE + I2C_DAT));
	  	   	    AAOUT(1);
	  	   	    udelay(1);
	  	   	    MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	  	   	    udelay(1);
	  	   	    break;
	  	   }
	  	   case 0xA0:{ 
	  	   	    #if 1
	  	   	    AAOUT(1);
	  	   	    udelay(1);
	  	   	    MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	  	   	    udelay(1);
	  	   	    #else
	  	   	    MMIO(I2C3_BASE + I2C_CONTROL)    = 0x00;   //
	            MMIO(I2C3_BASE + I2C_INT_EN)     = 0x00;
	            MMIO(I2C3_BASE + I2C_ADDRESS)    = 0x60;  
	            MMIO(I2C3_BASE + I2C_Powerdown)  = 0x00;  
	            MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	            MMIO(I2C3_BASE + I2C_CONTROL)    = (1<<7)/*ack*/ |  (1<<6)/*enable*/ | (0x00 << 2)/*400KHZ*/; 
	            MMIO(I2C3_BASE + I2C_INT_EN)     = 0x01;
	            #endif
	  	   	    break;
	  	   }
	  	   case 0x60:{
	  	   	    AAOUT(1);
	  	   	    MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	  	   	    break;
	  	   }
         case  0x70:
         case  0x78:
         case  0x90:
         case  0x98:
		     default   :{
		     	    #if 1
		     	    i2c_hardware_error();
		     	    #else
	  	   	    MMIO(I2C3_BASE + I2C_CONTROL)    = 0x00;   //
	            MMIO(I2C3_BASE + I2C_INT_EN)     = 0x00;
	            MMIO(I2C3_BASE + I2C_ADDRESS)    = 0x60;  
	            MMIO(I2C3_BASE + I2C_Powerdown)  = 0x00;  
	            MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01;
	            MMIO(I2C3_BASE + I2C_CONTROL)    = (1<<7)/*ack*/ |  (1<<6)/*enable*/ | (0x00 << 2)/*400KHZ*/; 
	            MMIO(I2C3_BASE + I2C_INT_EN)     = 0x01;
	            #endif
		     }
	  }
    return IRQ_HANDLED;
}

 void init_slave_i2c(){
	  unsigned int uValue;
    MMIO(I2C3_BASE + I2C_CONTROL)   = 0x00;   //
	  MMIO(I2C3_BASE + I2C_INT_EN)    = 0x00;
	  MMIO(I2C3_BASE + I2C_ADDRESS)   = 0x60;  
	  MMIO(I2C3_BASE + I2C_Powerdown) = 0x00;  
	  MMIO(I2C3_BASE + I2C_INT_CLR)   = 0x01;
	  
	  if(request_irq(irq,&infrared_int, SA_INTERRUPT,"i2ckbd", &irq)){
		    printk("request irq %d fail.\n", irq);
        return -EIO;
	  }
	  printk("request irq %d succeeded.\n", irq);
	  disable_irq(irq);
	  enable_irq(irq);
	  MMIO(I2C3_BASE + I2C_CONTROL)   = (1<<7)/*ack*/ |  (1<<6)/*enable*/ | (0x0 << 2)/*100KHZ*/; 
	  MMIO(I2C3_BASE + I2C_INT_EN)     = 0x01 ;
	  
}
static void i2ckbd_timer_fire(unsigned long data)
{
	  unsigned char uBuf[64];
    if(keydown_flag){
    	keydown_flag=0;
    	//input_report_key(i2ckbd.dev, 67, 1);		
    }else{
		   keydown_flag=1;
	  }
	  #if 0
		if(MMIO(I2C3_BASE + I2C_INT_STATUS)!=0x00){
			   u32 uTemp;
			   MMIO(I2C3_BASE + I2C_INT_CLR)    = 0x01; 
			   MMIO(I2C3_BASE + I2C_INT_STATUS) = 0x00;
			   udelay(10);
			   uTemp = MMIO(I2C3_BASE + I2C_STATUS);
			   udelay(100);
			   if(uTemp == 0x80){
			       printk("I2C_I2C_DAT     = 0x%08X\r\n",MMIO(I2C3_BASE + I2C_DAT));
			   }
			   MMIO(I2C3_BASE + I2C_STATUS) = 0x00;
	  }	
		
		//input_report_key(i2ckbd.dev, 67, 0);
    
    input_sync(i2ckbd.dev);
    #endif
	  /*启动定时器*/
	  //mod_timer(&i2ckbd_timer, jiffies+200); 
}

int button_used = 0;
 
static int button_open(struct input_dev *dev)
{
	printk("button_open\n");
	if (button_used++)
		return 0;
 
	/*if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) {
		printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq);
		button_used--;
		return -EBUSY;
	}*/
 
	return 0;
}
 
static void button_close(struct input_dev *dev)
{
	printk("button_close\n");
	if (!--button_used){
		/*free_irq(IRQ_AMIGA_VERTB, button_interrupt);*/
	}
}

static int i2ckbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
        printk("atkbd_event\n");
        return 0;
}



static int i2ckbd_probe(void)
{
	int i;
	
	i2ckbd.dev = input_allocate_device();
	if (!i2ckbd.dev){
		printk(KERN_ERR "%s:%s allocate_device\n", __FUNCTION__, __FILE__);
		return -ENOMEM;
	}


	/* Initialise input stuff */
	init_input_dev(i2ckbd.dev);
	
	i2ckbd.dev->open = button_open;
	i2ckbd.dev->close = button_close;

	sprintf(i2ckbd.phys,"%s/input0","i2ckbd");

	i2ckbd.dev->private = &i2ckbd;
	i2ckbd.dev->event = i2ckbd_event;
	i2ckbd.dev->name = i2ckbd_name;
	i2ckbd.dev->phys = i2ckbd.phys;
	i2ckbd.dev->id.bustype = BUS_I8042;
	i2ckbd.dev->id.vendor = 0x0001;
	i2ckbd.dev->id.product = 1;
	i2ckbd.dev->id.version = I2CKBDVERSION;
	
	i2ckbd.dev->keycode = atkbd_set2_keycode;
	i2ckbd.dev->keycodesize = sizeof(unsigned char);
	i2ckbd.dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
	
	
	set_bit(EV_KEY, i2ckbd.dev->evbit);
	for (i = 0; i < 512; i++)
		if (atkbd_set2_keycode[i] )
			set_bit(atkbd_set2_keycode[i], i2ckbd.dev->keybit);

	/* Get irqs */
	/*if (request_irq(IRQ_ADC, stylus_action, SA_SAMPLE_RANDOM, "i2ckbd_interrupt", i2ckbd.dev)) {
		printk(KERN_ERR "s3c2440_ts.c: Could not allocate ts IRQ_ADC !\n");
		return -EIO;
	}*/

	printk(KERN_INFO "%s successfully loaded\n", i2ckbd_name);

	/* All went ok, so register to the input system */
	input_register_device(i2ckbd.dev);
	
	/*启动定时器*/
	//mod_timer(&i2ckbd_timer, jiffies+HZ);
	return 0;
}
//----------------------------------




static int i2c_driver_infrared_attach(struct i2c_adapter *adapter, int address, int kind){
	
  printk("%s,%s,%s,%d\r\n",__TIME__,__FILE__,__FUNCTION__,__LINE__);
  #if 0
	/* Check if the adapter supports the needed features */
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return 0;
  #endif
  
  
	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
	if (client == 0)
		return -ENOMEM;
	client->addr = address;
	client->adapter = adapter;
	client->driver = &i2c_driver_infrared;
	snprintf(client->name, sizeof(client->name) - 1, "infrared");

	
	//state = kzalloc(sizeof(struct saa7115_state), GFP_KERNEL);
	//i2c_set_clientdata(client, state);
	//if (state == NULL) {
  //		kfree(client);
		//return -ENOMEM;
	//}
	i2c_attach_client(client);

	return 0;
}

static int infrared_probe(struct i2c_adapter *adapter){
	    printk("%s,%s,%s,%d\r\n",__TIME__,__FILE__,__FUNCTION__,__LINE__);
      i2c_probe(adapter, &addr_data, &i2c_driver_infrared_attach);
      return  0;
}

static int infrared_detach(struct i2c_client *client){
	    struct infrared_state *state = i2c_get_clientdata(client);
	    int err;

	    err = i2c_detach_client(client);
	    if (err) {
		      return err;
	    }
	    kfree(state);
	    kfree(client);
	    return 0;
}



static int infrared_command(struct i2c_client *client,unsigned int cmd, void *arg){
	  return 0x00;
}

/* i2c implementation */
static struct i2c_driver i2c_driver_infrared = {
	.driver = {
		.name = "infrared keyboard",
	},
	.id = I2C_DRIVERID_INFRARED,
	.attach_adapter = infrared_probe,
	.detach_client = infrared_detach,
	.command = infrared_command,
};


static int __init i2ckbd_init(void)
{
	int ret;
	printk("Date:%s\r\nTime:%s\r\n",__DATE__,__TIME__);
	init_slave_i2c();
	misc_register(&i2ckbd_driver);
	i2ckbd_probe();
	
	return 0;
}

static void __exit i2ckbd_exit(void){
	  free_irq(irq, &irq);
	  //del_timer(&i2ckbd_timer);
	  input_unregister_device(i2ckbd.dev);
	  misc_deregister(&i2ckbd_driver);
	  //i2c_del_driver(&i2c_driver_infrared);
}

module_init(i2ckbd_init);
module_exit(i2ckbd_exit);

⌨️ 快捷键说明

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