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

📄 i2c-keypad.c

📁 Linux下I2C以及I2C下的键盘驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/delay.h>#include <linux/poll.h>#include <asm/uaccess.h>        /* get_user,copy_to_user */#include <linux/string.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/fcntl.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/in.h>//#include <linux/malloc.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/string.h>#include <linux/init.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/errno.h>#include <linux/tqueue.h>#include <linux/wait.h>#include <asm/irq.h>#include <asm/arch/hardware.h>#include <asm/arch/irqs.h>//#include <linux/devfs_fs_kernel.h>#include <linux/miscdevice.h>//#include <asm/arch-mx1ads/hardware.h>#include "i2c-aa.h"#include <linux/i2c.h>#include <linux/i2c-algo-bit.h>#include <linux/i2c-id.h>#include "i2c-keypad.h"struct fasync_struct *keypadv_fasync;#define I2C_DRIVERID_KEYPAD     0x1003/* functions and interface */static int keypad_open(struct inode * inode, 		struct file * filp);static int keypad_release(struct inode * inode, 		struct file * filp);static int keypad_fasync(int fd, 		struct file *filp, 		int mode);static ssize_t keypad_read(struct file * , 		char * , 		size_t , 		loff_t * l);static ssize_t keypad_write(struct file *filp, const char *buf, size_t size, loff_t *l);static int keypad_ioctl(struct inode * inode, struct file *filp, unsigned int cmd , unsigned long arg);static unsigned int keypad_poll(struct file * filp, 		struct poll_table_struct * wait);static void keypad_interrupt(int , 		void *, 		struct pt_regs *);     /* ISR :*/static int i2c_keypad_attach_adapter (struct i2c_adapter * adap);struct file_operations keypad_fops = {	open:           keypad_open,	release:        keypad_release,	read:           keypad_read,	write:		keypad_write,	poll:           keypad_poll,	ioctl:          keypad_ioctl,	fasync:         keypad_fasync,};static struct i2c_driver i2c_keypad_driver = {	name:		"i2c-keypad client driver",	id:		I2C_DRIVERID_KEYPAD,	flags:		I2C_DF_DUMMY | I2C_DF_NOTIFY,	attach_adapter:	i2c_keypad_attach_adapter,	detach_client:	NULL,	command:	NULL/*	inc_use:	NULL,	dec_use:	NULL, */};static struct i2c_client i2c_keypad_client = {	name:		"i2c-keypad client",	id:		1,	flags:		0,	addr:		-1,	adapter:	NULL,	driver:		&i2c_keypad_driver,	data:		NULL};/* local prototype */static int checkDevice(struct inode *pInode);int gMajor = 0;static struct keypad_struct keypadmx1;static int i2c_keypad_initialized = 0;wait_queue_head_t gkeypadWait;//static char interBuf[2];static char key[2];//static char bflag;/****************************************************************************** * Function Name: keypad_open * * Input: 		inode	: * 			filp	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: allocate resource when open the inode * *****************************************************************************/int keypad_open(struct inode * inode, struct file * filp){	unsigned long flags,val;			if(keypadmx1.gKeypadFlag == 1)		return 1;  	save_flags_cli(flags);	keypadmx1.gDataFlag = 0;	keypadmx1.gKeypadFlag = 1;			key[0] = 0;	key[1] = 0;	//bflag = PRESS_NO;		restore_flags(flags);	i2c_keypad_client.adapter->inc_use( i2c_keypad_client.adapter );	val = READREG(KEYPAD_IMR_B); 	val |= 0x00008000;//unmask the interrupt//	val &= 0xFFFF7FFF;//mask the interrupt	WRITEREG(KEYPAD_IMR_B,val); 	MOD_INC_USE_COUNT;	return 0;}/****************************************************************************** * Function Name: keypad_release * * Input: 		inode	: * 			filp	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: release resource when close the inode * *****************************************************************************/int keypad_release(struct inode * inode, struct file * filp){	unsigned long flags,val; 	save_flags_cli(flags);	keypadmx1.gDataFlag = 0;	keypadmx1.gKeypadFlag = 0;		key[0] = 0;	key[1] = 0;	//bflag = PRESS_NO;		restore_flags(flags);	val = READREG(KEYPAD_IMR_B); 	val &= 0xFFFF7FFF;//mask the interrupt	WRITEREG(KEYPAD_IMR_B,val); 	/* call the adapter's decrease usage count function */	i2c_keypad_client.adapter->dec_use( i2c_keypad_client.adapter );	MOD_DEC_USE_COUNT;	return 0;}/*----------------------------------------------------------------------- * static SINT16 i2c_keypad_attach_adapter (struct i2c_adapter * adap) * This function is called when the associated driver is to install to the  * I2C system.  * It shall check whether it can handle the adapter. * * Parameter : * 	adap		point o the adapter structure * Return : * 	Success		0 * 	Failure		-1	 *----------------------------------------------------------------------*/ static int i2c_keypad_attach_adapter (struct i2c_adapter * adap){	/* find out the adapter for the I2C module in the DBMX1*/	if (memcmp(adap->name, "DBMX1 I2C adapter", 17) != 0 )		return -ENODEV;	/* store the adapter to the client driver */	i2c_keypad_client.adapter = adap;	return 0;}/****************************************************************************** * Function Name: keypad_read * * Input: 		filp	: the file  * 			buf	: data buffer * 			count	: number of chars to be readed * 			l	: offset of file * Value Returned:	int	: Return status.If no error, return 0. * * Description: read device driver * *****************************************************************************/ssize_t keypad_read(struct file * filp, char * buf, size_t count, loff_t * l){	char interBuf[2];	int nonBlocking;		unsigned long flags;	int  ret = 0;			nonBlocking = filp->f_flags & O_NONBLOCK;		/*if((count % 3) != 0)		return 0;	*/	if( nonBlocking )	{		if( keypadmx1.gDataFlag == 1)		{			/*if(bflag == PRESS_DOWN)			{	interBuf[0]	= PRESS_DOWN; 	}			else if(bflag == PRESS_UP)			{	interBuf[0]	= PRESS_UP;		}			else			{	interBuf[0]	= PRESS_NO;		}			*/			interBuf[0] = key[0];			interBuf[1] = key[1];			__copy_to_user(buf, interBuf, 2);  			save_flags_cli(flags);			keypadmx1.gDataFlag = 0;			restore_flags(flags);						ret += 2;		}		else			ret = 0;	}    else	{		while(1)		{			if( keypadmx1.gDataFlag == 1)			{				/*if(bflag == PRESS_DOWN)				{	interBuf[0]	= PRESS_DOWN; 	}				else if(bflag == PRESS_UP)				{	interBuf[0]	= PRESS_UP;		}				else				{	interBuf[0]	= PRESS_NO;		}				*/				interBuf[0] = key[0];				interBuf[1] = key[1];				__copy_to_user(buf, interBuf, 2);				  				save_flags_cli(flags);				keypadmx1.gDataFlag = 0;				restore_flags(flags);								ret += 2;				/*if((ret == count) || (ret > count))					break;				*/				break;			}			else			{				interruptible_sleep_on(&gkeypadWait);				if(signal_pending(current))					break;			}		}	}#ifdef TEST		MX1_REG_PTD_DR &= ~0x80000000;	printk("TOUT2 Falls\n");#endif	return ret;}/****************************************************************************** * Function Name: keypad_write * * Input: 		filp	: the file  * 			buf	: data buffer * 			count	: number of chars to be written * 			l	: offset of file * Value Returned:	int	: Return status.If no error, return 0. * * Description: read device driver * *****************************************************************************/static ssize_t keypad_write(struct file *filp, const char *buf, size_t size, loff_t *l){	struct i2c_msg msg;	char wribuf[2];		if(!(size == 2))		return 0;		__copy_from_user(wribuf,buf,size);	msg.addr = i2c_keypad_client.addr;	msg.flags = 0x00;	msg.len = 2;	msg.buf = wribuf;			i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, 0x0F);//change to 400K freq	i2c_transfer( i2c_keypad_client.adapter, &msg, 1 );	i2c_control( &i2c_keypad_client, I2C_IO_CHANGE_FREQ, DEFAULT_FREQ);//change back to 100K freq	return size;}/****************************************************************************** * Function Name: keypad_fasync * * Input: 		fd	: * 			filp	:

⌨️ 快捷键说明

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