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

📄 i2c-tomega8.c

📁 linux下S3C2410的I2C总线的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	case 2:		/* SEEK_END */		file->f_pos = iccd->memsize + offset;		break;	default:		return -EINVAL;	}	if (file->f_pos < 0)		file->f_pos = 0;	else if (file->f_pos >= iccd->memsize)		file->f_pos = iccd->memsize - 1;	return file->f_pos;}static ssize_t mega8_iccard_read (struct file *file, char *buf, size_t count,                            loff_t *offset){	ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data;	struct i2c_client *client = &mega8_client;	I2C_ICCard buffer;	size_t total_retlen=0;	int ret=0;	int len;		if (*offset + count > iccd->memsize)		count = iccd->memsize- *offset;	while (count) {		if (count > MAX_ICCARD_RWBUFFER) 			len = MAX_ICCARD_RWBUFFER;		else			len = count;		buffer.cmd=CMD_ICC_READ;		iccarddev.iccard_data.address = buffer.iccard_addr = *offset;		iccarddev.iccard_data.cnt = buffer.iccard_cnt = len;		iccarddev.lasterrcode = ICC_FAILED_WAITING;				ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET);		if(ret<0){			iccarddev.lasterrcode=ICC_FAILED_READERR;			break;		}retry: 		if(iccarddev.lasterrcode==ICC_FAILED_WAITING){			interruptible_sleep_on(&(iccarddev.wq));			if (signal_pending(current))				return -ERESTARTSYS;			goto retry;		}		else if(iccarddev.lasterrcode==ICC_FAILED_NULL){	//read successfully			*offset += buffer.iccard_cnt;			copy_to_user(buf, (char *)iccarddev.iccard_data.buffer, buffer.iccard_cnt);			if (copy_to_user(buf, (char *)iccarddev.iccard_data.buffer, buffer.iccard_cnt)) {				return -EFAULT;			}else{				total_retlen += buffer.iccard_cnt;				count -= buffer.iccard_cnt;				buf += buffer.iccard_cnt;			}		}		else{			//read error			break;		}	}		return total_retlen;}static ssize_t mega8_iccard_write(struct file * file, const char * buf, size_t count,                             loff_t *offset){	ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data;	struct i2c_client *client = &mega8_client;	I2C_ICCard buffer;	size_t total_retlen=0;	int ret=0;	int len;		if (*offset + count > iccd->memsize)		count = iccd->memsize- *offset;	while (count) {		if (count > MAX_ICCARD_RWBUFFER) 			len = MAX_ICCARD_RWBUFFER;		else			len = count;		buffer.cmd=CMD_ICC_WRITE;		iccarddev.iccard_data.address = buffer.iccard_addr = *offset;		iccarddev.iccard_data.cnt = buffer.iccard_cnt = len;		iccarddev.lasterrcode = ICC_FAILED_WAITING;		if (copy_from_user(buffer.iccard_buf, buf, len)) {			return -EFAULT;		}		ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET + len);		if(ret<0){			iccarddev.lasterrcode=ICC_FAILED_READERR;			break;		}retry: 		if(iccarddev.lasterrcode==ICC_FAILED_WAITING){			interruptible_sleep_on(&(iccarddev.wq));			if (signal_pending(current))				return -ERESTARTSYS;			goto retry;		}		else if(iccarddev.lasterrcode==ICC_FAILED_NULL){	//write successfully			*offset += buffer.iccard_cnt;			total_retlen += buffer.iccard_cnt;			count -= buffer.iccard_cnt;			buf += buffer.iccard_cnt;		}		else{			//write error			break;		}	}		return total_retlen;}static int mega8_iccard_release (struct inode *inode, struct file *file){	mega8_device_release (DTYPE_ICCARD);	atomic_inc (&atom_cnt);	return 0;}static int iccard_sle4442_read_manufacture_info (unsigned char *buf){	int ret = -1;	int count = 32;	struct i2c_client *client = &mega8_client;//(struct i2c_client *)file->private_data;	I2C_ICCard buffer;	while(count!=0){		buffer.cmd=CMD_ICC_READ;		iccarddev.iccard_data.address=buffer.iccard_addr=0;		iccarddev.iccard_data.cnt=buffer.iccard_cnt=count;		iccarddev.lasterrcode=ICC_FAILED_WAITING;				ret = i2c_master_send(client, (const char*)&buffer, ICCARD_COUNT_OFFSET);		if(ret<0){			iccarddev.lasterrcode=ICC_FAILED_READERR;		}retry: 		if(iccarddev.lasterrcode==ICC_FAILED_WAITING){			interruptible_sleep_on_timeout (&(iccarddev.wq), HZ);			if (signal_pending(current))				return -ERESTARTSYS;			goto retry;		}		else if(iccarddev.lasterrcode==ICC_FAILED_NULL){	//read successfully			memcpy (buf, (char*)iccarddev.iccard_data.buffer, buffer.iccard_cnt);			ret = 0;			break;		}		else{			//read error			ret = -1;			break;		}	}	return ret;}static int do_verification_sle4442 (unsigned char *password ){	int ret = -1;	int count = 3;	struct i2c_client *client = &mega8_client;//(struct i2c_client *)file->private_data;	I2C_ICCard iccard_verifybuffer;	while(count!=0){		iccard_verifybuffer.cmd=CMD_ICC_VERIFY;		iccarddev.iccard_data.cnt=iccard_verifybuffer.iccard_pwdcnt=3;		memcpy (iccard_verifybuffer.iccard_pwdbuf, password, 3);		iccarddev.lasterrcode=ICC_FAILED_WAITING;				ret = i2c_master_send(client, (const char*)&iccard_verifybuffer, ICCARD_COUNT_PWD_OFFSET+iccard_verifybuffer.iccard_pwdcnt);		if(ret<0){			iccarddev.lasterrcode=ICC_FAILED_VERIFYERR;		}retry: 		if(iccarddev.lasterrcode==ICC_FAILED_WAITING){			interruptible_sleep_on_timeout(&(iccarddev.wq), HZ);			DPRINTK ("do verify 4442 retry out\n");			if (signal_pending(current))				return -ERESTARTSYS;			goto retry;		}else if(iccarddev.lasterrcode == ICC_FAILED_NULL){			//verify successfully			DPRINTK ("do verify 4442 success\n");			ret = 0;			break;		}else{			DPRINTK ("do verify 4442 fail\n");			ret = -1;			break;		}	}	return ret;}static int verify_sle4442 (unsigned char *input){	unsigned char manuinfo[32];	unsigned char passwd[3];	/* read manufacture info */#if 0	if (iccard_sle4442_read_manufacture_info (manuinfo))		return -1;#endif	/* generate password according to the manufacture info */	/* FIXME: here, we need generate password but not copy first 3 byte to it */	passwd[0]=input[0];	passwd[1]=input[1];	passwd[2]=input[2];	/* verify it */	if (do_verification_sle4442 (passwd))		return -1;	/* success */	DPRINTK ("verify sle4442 successfully\n");	return 0;}static int select_card_type ( unsigned char cardtype){	I2C_control i2c_ctrl;	int ret;	i2c_ctrl.cmd = CMD_ICC_TYPESEL;	i2c_ctrl.ctrl = (unsigned char)cardtype;	iccarddev.lasterrcode=ICC_FAILED_WAITING;	ret = i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if (ret < 0){		DPRINTK("set ic card type failed!.\n");		return ret;	}	ret = 0;retry: 	if(iccarddev.lasterrcode==ICC_FAILED_WAITING){		interruptible_sleep_on_timeout (&(iccarddev.wq), HZ);		if (signal_pending(current))			return -ERESTARTSYS;		goto retry;	}else if(iccarddev.lasterrcode!=ICC_FAILED_NULL){		//select error		ret = -1;	}	DPRINTK ("select_card_type return :%d\n", ret);	return ret;}static int valid_iccard_dev (unsigned char minor){	int i;	for (i = 0; i < DEVNM_SIZE; i ++){		if (minor == iccarddevinfo[i].minor)			return i;	}	return -1;}static int mega8_iccard_open (struct inode *inode, struct file *file){/*	if (!mega8_kbd_client->adapter)		return -ENODEV;	if (mega8_kbd_client->adapter->inc_use)		mega8_kbd_client->adapter->inc_use (mega8_kbd_client->adapter);*/	unsigned char dev_minor = MINOR(inode->i_rdev);	int cardindex = valid_iccard_dev (dev_minor);	DPRINTK ("minor:%d\n", dev_minor);	if (!inode || cardindex < 0)		return -ENODEV;	if (!atomic_dec_and_test (&atom_cnt)){		DPRINTK ("iccard busy\n");		atomic_inc (&atom_cnt);		return -EBUSY;	}	iccarddev.lasterrcode=ICC_FAILED_NULL;	init_waitqueue_head(&(iccarddev.wq));	DPRINTK( "iccard opened\n");	mega8_device_request (DTYPE_ICCARD);	/*Select Card Type */	if (select_card_type(dev_minor))		goto erropen;#if 0	/* If using sle4442 card, do verification */	if ( dev_minor == ICCARD_TYPE_SLE4442 ){		unsigned char passwd[]={0xab, 0xcd, 0xef};		DPRINTK ("begin verify\n");		if (verify_sle4442(passwd))			goto erropen;	}#endif	file->private_data = iccarddevinfo + cardindex;	return 0;erropen:	mega8_device_release (DTYPE_ICCARD);	atomic_inc (&atom_cnt);	return -ENODEV;}static int mega8_iccard_ioctl (struct inode *inode, struct file *file, 	unsigned int cmd, unsigned long arg){	I2C_control i2c_ctrl;	int ret;	ICCARD_DEV_INFO *iccd= (ICCARD_DEV_INFO*)file->private_data;	switch(cmd){	case ICCARD_IOCTL_LASTERR:		*((unsigned char*)arg)=iccarddev.lasterrcode;		return 0;	case ICCARD_IOCTL_SELCARD:		return select_card_type((unsigned char)arg);	case ICCARD_IOCTL_4442VERIFY:		if (iccd->minor != ICCARD_4442_MINOR)			return -1;		return verify_sle4442((unsigned char*)arg);	}	return 0;}///ENODEV#ifdef CONFIG_DEVFS_FSstatic void reg_dev_files (devfs_handle_t i2c_root){	int i;	for (i = 0; i < DEVNM_SIZE; i ++){		iccard_devfs_handle[i] = devfs_register (i2c_root, iccarddevinfo[i].devname,				DEVFS_FL_DEFAULT, iccardmajor, iccarddevinfo[i].minor,				S_IFCHR | S_IRUSR | S_IWUSR,				&mega8_iccard_fops, NULL);		DPRINTK ("Registered '%s' as minor %d\n", iccarddevinfo[i].devname,				iccarddevinfo[i].minor);	}}#endif#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t mega8_iccard_init (devfs_handle_t i2c_root)#elsestatic int mega8_iccard_init ()#endif{	int ret;//	I2C_control i2c_ctrl;	ret = register_chrdev(0, ICCARD_NAME, &mega8_iccard_fops);	if (ret < 0) {		DPRINTK(ICCARD_NAME" can't be registered\n");#ifdef CONFIG_DEVFS_FS		return NULL;#else		return ret;#endif	}	iccardmajor = ret;#ifdef CONFIG_DEVFS_FS	reg_dev_files (i2c_root);#endif	//set default ic-card is AT24C16/*	i2c_ctrl.cmd=CMD_ICC_TYPESEL;	i2c_ctrl.ctrl=ICCARD_TYPE_AT24C16;	ret=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if(ret<0){		DPRINTK("set ic card type failed!.\n");	}*/	atomic_set (&atom_cnt, 1);#ifdef CONFIG_DEVFS_FS	return iccard_devfs_handle[0];#else	return 0;#endif}static void mega8_iccard_exit (void){	int i;#ifdef	CONFIG_DEVFS_FS	for ( i = 0; i < DEVNM_SIZE; i++){		if (iccard_devfs_handle[i]){			devfs_unregister(iccard_devfs_handle[i]);			iccard_devfs_handle[i] = NULL;		}	}#endif	unregister_chrdev(iccardmajor, ICCARD_NAME);}#endif	//#ifdef CONFIG_I2C_MEGA8_IC_CARD/******************I2C_ICCARD*****************/#define PS2_DEVICE_NULL			0#define PS2_DEVICE_KBD			1#define PS2_DEVICE_MOUSE		2typedef struct{	wait_queue_head_t wq;	spinlock_t lock;	unsigned char data;	int waiting;	int ps2device;	int ndata;}PS2_DEV;#define KBD_BAT		0xaa		/* in */#define KBD_SETLEDS	0xed		/* out */#define KBD_ECHO	0xee		/* in/out */#define KBD_BREAK	0xf0		/* in */#define KBD_TYPRATEDLY	0xf3		/* out */#define KBD_SCANENABLE	0xf4		/* out */#define KBD_DEFDISABLE	0xf5		/* out */#define KBD_DEFAULT	0xf6		/* out */#define KBD_ACK		0xfa		/* in */#define KBD_DIAGFAIL	0xfd		/* in */#define KBD_RESEND	0xfe		/* in/out */#define KBD_RESET	0xff		/* out */#define KBD_READID	0xf2		/* out */#define MOUSE_DATAENABLE		0xf4	//out#ifdef CONFIG_I2C_MEGA8_PS2_0static PS2_DEV ps2dev0;static ps2_handle_event ps2_hdevent0=NULL;#define PS20_SET_WAITING()		ps2dev0.waiting=1#define PS20_CLR_WAITING()		ps2dev0.waiting=0/*********************************************************\	send a data to ps2 device via i2c\*********************************************************/int mega8_PS20_Send(unsigned char data){	int ret;	I2C_control i2c_ctrl;	i2c_ctrl.cmd=CMD_PS2_0;	i2c_ctrl.ctrl=data;	ret=i2c_master_send(&mega8_client, (const char*)&i2c_ctrl, sizeof(i2c_ctrl));	if(ret<0){		DPRINTK("ps2 0 send  failed!.\n");		return -1;	}	return 0;}#define mega8_PS20_FlushData()		ps2dev0.ndata=0;/*********************************************************\	wait ps2 send back data via i2c\*********************************************************/int mega8_PS20_WaitData(unsigned char *data, long timeout){	if(ps2dev0.ndata==1){		*data=ps2dev0.data;		ps2dev0.ndata=0;	//	ps2dev0.waiting=0;		return 0;	}	if(timeout==0){		interruptible_sleep_on(&ps2dev0.wq);		*data=ps2dev0.data;		ps2dev0.ndata=0;		return 0;	}	if(interruptible_sleep_on_timeout(&ps2dev0.wq, timeout)==0){		*data=0;		ps2dev0.ndata=0;		return -1;	}	*data=ps2dev0.data;	ps2dev0.ndata=0;	return 0;}static void mega8_ps2_raw0(unsigned char data){	ps2dev0.ndata=1;	if(ps2dev0.waiting){		ps2dev0.data=data;		wake_up_interruptible(&(ps2dev0.wq));		return;	}#ifdef DEBUG	if(ps2dev0.ps2device==PS2_DEVICE_KBD){		//send data into keyboard		DPRINTK("keyboard receive data=0x%x\n", data);	}	else if(ps2dev0.ps2device==PS2_DEVICE_MOUSE){		DPRINTK("mouse receive data=0x%x\n", data);	}#endif

⌨️ 快捷键说明

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