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

📄 i2c-keypad.c

📁 Linux下I2C以及I2C下的键盘驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
 * 			mode	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: provide fasync functionality for select system call * *****************************************************************************/static int keypad_fasync(int fd, struct file *filp, int mode){	int ret;	/* TODO put this data into file private data */	int minor = checkDevice( filp->f_dentry->d_inode);	if ( minor == - 1)	{		printk("<1>keypad_fasyn:bad device minor\n");		return -ENODEV;	}		printk("keypad driver keypad_fasync\n");	ret = fasync_helper(fd, filp, mode, &keypadv_fasync);	if(ret < 0)		return ret;		return 0;		}/****************************************************************************** * Function Name: keypad_ioctl * * Input: 		inode	: * 			filp	: * 			cmd	: command for ioctl * 			arg	: parameter for command * Value Returned:	int	: Return status.If no error, return 0. * * Description: ioctl for this device driver * * 	 *****************************************************************************/int keypad_ioctl(struct inode * inode, 		struct file *filp,		unsigned int cmd , 		unsigned long arg){	int ret = -EIO;	int minor;			minor = checkDevice( inode );	if ( minor == - 1)	{		printk("keypad_ioctl:bad minor\n");		return -ENODEV;	}		printk("keypad_ioctl:minor=%08x cmd=%d\n",minor,cmd);		return ret;}/****************************************************************************** * Function Name: keypad_poll * * Input: 		filp	: * 			wait	:  * Value Returned:	int	: Return status.If no error, return 0. * * Description: support poll and select * *****************************************************************************/unsigned int keypad_poll(struct file * filp, struct poll_table_struct * wait){	int minor;		minor = checkDevice( filp->f_dentry->d_inode);	if ( minor == - 1)		return -ENODEV;		poll_wait(filp, &gkeypadWait, wait);		return ( keypadmx1.gDataFlag==0) ? 0 : (POLLIN | POLLRDNORM);}/****************************************************************************** * Function Name: keypad_interrupt * * Input: 		irq	: interrupt number * 			dev_id	: device driver name * 			regs	: registers * Value Returned:	void	:  * * Description: interrupt handler for keypad device * *****************************************************************************/static void keypad_interrupt(int irq, void *dev_id, struct pt_regs *regs){	unsigned long val;	char command;	struct i2c_msg msg[2];	char keybuf[2];				#ifdef TEST	printk("TOUT2 Raises\n");	MX1_REG_PTD_DR |= 0x80000000;#endif	val = READREG(KEYPAD_ISR_B);		if(val & 0x00008000) //check if PortB 15 interrupt generated	{		val |= 0x00008000;		WRITEREG(KEYPAD_ISR_B,val); //clear the Interrupt status bit		command = 0x00;				keybuf[0] = 0;		keybuf[1] = 0;				msg[0].addr = i2c_keypad_client.addr;		msg[0].flags = 0x00;		msg[0].len = 1;		msg[0].buf = &command;				msg[1].addr = i2c_keypad_client.addr;		msg[1].flags = I2C_M_RD;		msg[1].len = 2;		msg[1].buf = keybuf;				i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, 0x10);//change to 400K freq		i2c_transfer( i2c_keypad_client.adapter, msg, 2 );		i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, DEFAULT_FREQ);//change back to 100K freq		key[0]=keybuf[0];		key[1]=keybuf[1];					keypadmx1.gDataFlag = 1;		wake_up_interruptible(&gkeypadWait);		if(keypadv_fasync)			kill_fasync(&keypadv_fasync, SIGIO, POLL_IN);				//val |= 0x00008000;		//WRITEREG(KEYPAD_ISR_B,val); //clear the Interrupt status bit	}}/****************************************************************************** * Function Name: checkDevice * * Input: 		inode	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: verify if the inode is a correct inode * *****************************************************************************/static int checkDevice(struct inode *pInode){	int minor;	kdev_t dev = pInode->i_rdev;		if( MAJOR(dev) != gMajor)	{		printk("checkDevice bad major = %d\n",MAJOR(dev) );		return -1;	}	minor = MINOR(dev);		if ( minor < MAX_ID )		return minor;	else	{       		printk("checkDevice bad minor = %d\n",minor );		return -1;	}}/****************************************************************************** * Function Name: initkeypad * * Input: 			: * Value Returned:	int	: init keypad hardware * * Description: verify if the inode is a correct inode * *****************************************************************************/static void __init initkeypad(){	unsigned long val;		if (i2c_keypad_initialized == 0)	{		val = READREG(KEYPAD_GIUS_B);		val |= 0x00008000;		WRITEREG(KEYPAD_GIUS_B,val);    //for GPIO use		val = READREG(KEYPAD_DDIR_B);		val &= 0xFFFF7FFF;		WRITEREG(KEYPAD_DDIR_B,val);	//pin B15 is GPIO input		val = READREG(KEYPAD_ICR1_B); //this register need the SIM_PD input status---positive or negative, edge or level		//val &= 0x3FFFFFFF;			  //set to positive edge sensitive		//val |= 0x40000000;			  //set to negative edge sensitive    		val |= 0xC0000000;			  //set to negative level sensitive		WRITEREG(KEYPAD_ICR1_B,val);/*		val = READREG(KEYPAD_ICONFA1_B);		val &= 0x3FFFFFFF;		val |= 0x40000000;		WRITEREG(KEYPAD_ICONFA1_B,val);    //for GPIO use*/		val = READREG(KEYPAD_PUEN_B); //Port B15 is tri-state when no driven internally or externally		val &= 0xFFFF7FFF;		val |= 0x00008000;//Port B15 is high when no driven internally or externally		WRITEREG(KEYPAD_PUEN_B,val);		i2c_keypad_initialized = 1;	}}/****************************************************************************** * Function Name: init_module * * Input: 		void	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: device driver initialization * *****************************************************************************/static devfs_handle_t devfs_handle;#ifdef MODULEint init_module(void)#elseint __init keypad_init(void)#endif{	unsigned long flags;	int res;	int result = 0;		initkeypad();		/* register our character device */ 	result = devfs_register_chrdev(0, MOD_NAME, &keypad_fops); 	if ( result < 0 ) 	{		printk("i2c-keypad driver: Unable to register driver\n");		return -ENODEV;	}	devfs_handle = devfs_register(NULL, MOD_NAME, DEVFS_FL_DEFAULT,				      result, 0,				      S_IFCHR | S_IRUSR | S_IWUSR,				      &keypad_fops, NULL);   				if( gMajor == 0 )		gMajor = result;	result = request_irq(KEYPAD_GPIO_INT_B, 			keypad_interrupt,			SA_INTERRUPT|SA_SHIRQ,			MOD_NAME,			MOD_NAME);	printk("request_irq() result is %d\n",result);	if (result) {		printk("init_module error from irq %d\n", result);	devfs_unregister_chrdev(gMajor, MOD_NAME);	devfs_unregister(devfs_handle);				return -1;	}	init_waitqueue_head(&gkeypadWait);			i2c_keypad_client.addr = I2C_ADDR_KEYPAD;		if (( res = i2c_add_driver( &i2c_keypad_driver )))	{		return res;	}	if (( res = i2c_attach_client(&i2c_keypad_client )) != 0 )	{			i2c_del_driver(&i2c_keypad_driver);		return res;	} 	save_flags_cli(flags);	keypadmx1.gDataFlag = 0;	keypadmx1.gKeypadFlag = 0;	restore_flags(flags);#ifdef TEST	MX1_REG_PTD_GIUS |= 0x80000000;	MX1_REG_PTD_OCR2 |= 0xc0000000;	MX1_REG_PTD_DR |= 0x80000000;	MX1_REG_PTD_DDIR |= 0x80000000;	printk("TOUT2 as the time trigger\n");	MX1_REG_PTD_DR |= 0x80000000;	MX1_REG_PTD_DR &= ~0x80000000;	#endif	//printk("The major number is %d!\n",gMajor);	printk("The keypad device can now be access from /dev/i2c-keypad\n");	printk("The device still can be access through mknod i2c-keypad c %d 0\n",gMajor);	return 0;}/****************************************************************************** * Function Name: keypad_cleanup * * Input: 		void	: * Value Returned:	void	:  * * Description: clean up and free all of resource for this MODULE * * Modification History: * 	10 DEC,2001, Chen Ning *****************************************************************************/#ifdef MODULEvoid cleanup_module(void)#elsevoid __exit keypad_cleanup(void)#endif{//	int res;	unsigned long val,flags;		 	val = READREG(KEYPAD_IMR_B); 	val &= 0xFFFF7FFF;	WRITEREG(KEYPAD_IMR_B,val); //unmask the interrupt	i2c_detach_client(&i2c_keypad_client);		i2c_del_driver(&i2c_keypad_driver);		i2c_keypad_initialized = 0;		free_irq(KEYPAD_GPIO_INT_B, MOD_NAME);	devfs_unregister_chrdev(gMajor, MOD_NAME);	devfs_unregister(devfs_handle);	  	save_flags_cli(flags);	keypadmx1.gDataFlag = 0;	keypadmx1.gKeypadFlag = 0;	restore_flags(flags);}#ifndef MODULEmodule_init(keypad_init);module_exit(keypad_cleanup);#endif/* end of file */

⌨️ 快捷键说明

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