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

📄 cryptdriver.c.bak

📁 光学指纹头加密芯片IIC的驱动(linux 2.4)
💻 BAK
字号:

#include <linux/fs.h>
#include <linux/iobuf.h>
#include <linux/major.h>   
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/module.h>
//#include <asm/arch/cpu_s3c2410.h>

//#include <linux/cryptdriver.h>
#include "cryptdriver.h"

#define IIC_SDA 		  GPIO_G14//r1   R5
#define IIC_SCL   		GPIO_G13 //r2   R6
#define IIC_RESET	    GPIO_F5//EINT5   

/*
#define IIC_SDA 		 GPIO_C9
#define IIC_SCL   		 GPIO_C8
#define IIC_RESET	 GPIO_C10
*/
static devfs_handle_t devfs_handle;

//
//  Timing control parameter - should be implementation specific.
// delay factors to meet I2C specifications. Should be tuned according to system timings.
#define IIC_SCLK_HFACTOR     	80
#define IIC_SCLK_LFACTOR	230
#define IIC_SDA_FACTOR	       80
#define IIC_SCLK_FACTOR		80
#define IIC_SDA_HFACTOR	40

#define IIC_SCL_CLOCK             10

//#define CRYPT_MAJOR     223 //定义主设备号
static int CRYPT_MAJOR=0;

int     Crypt_open(struct inode*, struct file *);
int     Crypt_release(struct inode*, struct file *);
int      Crypt_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);


static struct file_operations gpio_ctl_fops= { 
	ioctl:          Crypt_ctl_ioctl,
	open:        Crypt_open,
	release:     Crypt_release,
};

int __init gpio_init(void) 
{ 
	int result; 
	result = register_chrdev(0, "cryptdriver", &gpio_ctl_fops); 
	//result = devfs_register(NULL,"i2c_driver",DEVFS_FL_DEFAULT, IOPORT_MAJOR, 0, S_IFCHR |S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP, &gpio_ctl_fops, NULL);
  //result = devfs_register(NULL,"keys4",DEVFS_FL_DEFAULT,KEYS4_MAJOR, 0, S_IFCHR |S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP, &keys4_fops, NULL);
	if (result < 0) { 
		printk("Driver register error!\n"); 
		return result; 

	} 
	CRYPT_MAJOR=result;
	devfs_handle = devfs_register(NULL, "cryptdriver", DEVFS_FL_DEFAULT,CRYPT_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR,&gpio_ctl_fops, NULL);

	return 0; 

} 


int gpio_release(struct inode*inode, struct file *filp)
{ 
       devfs_unregister(devfs_handle);
	unregister_chrdev(CRYPT_MAJOR, "cryptdriver"); 
}

int  Crypt_open(struct inode*inode, struct file *filp)
{
	unsigned char tbuf[4];
	struct crypt_ioctl_data{
	unsigned char Zone,Start,Count;
	unsigned char *PBuffer;
  };
  struct crypt_ioctl_data argm;
	argm.Zone=3;  		// Zone
	argm.Start=0x0f;		//Start
	argm.PBuffer=tbuf;		//PBuffer
	argm.Count=1;		//Count
  
	//unsigned char i;
	//for(i=0;i<4;i++)
	//tbuf[i]=0xff;
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_SDA); 
	write_gpio_bit(GPIO_MODE_OUT | IIC_SDA,1);
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_SCL); 
	write_gpio_bit(GPIO_MODE_OUT | IIC_SCL,1);
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_RESET); 
	write_gpio_bit(GPIO_MODE_OUT | IIC_RESET,1);
	//do{
	CryptResetChip(&tbuf[0]);
	CryptWriteMemory(argm.Zone,argm.Start,argm.PBuffer,argm.Count);
	//}while(tbuf[1]==0xff);
	
	return 0;
}


int  Crypt_release(struct inode*inode, struct file *filp)
{ 
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_SDA); 
	write_gpio_bit(GPIO_MODE_OUT | IIC_SDA,1);
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_SCL); 
	write_gpio_bit(GPIO_MODE_OUT | IIC_SCL,1);
	
	return 0;
}

// Set port direction to input
void IIC_SDA_IN( void )
{
	set_gpio_ctrl(GPIO_MODE_IN | IIC_SDA); 
}

// Set port direction to output
void IIC_SDA_OUT( void )
{
	set_gpio_ctrl(GPIO_MODE_OUT | IIC_SDA); 
}

// Pull down the port
void IIC_CLR( int ports )
{
	switch(ports)
		{
			case IIC_SDA:
   				write_gpio_bit(GPIO_MODE_OUT | IIC_SDA,0);
				break;
			case IIC_SCL:
   				write_gpio_bit(GPIO_MODE_OUT | IIC_SCL,0);
				break;
			case IIC_RESET:
   				write_gpio_bit(GPIO_MODE_OUT | IIC_RESET,0);
				break;
			default:
				break;
		}
}

// Release the port as high-Z. 
void IIC_SET( int ports )
{
	switch(ports)
		{
			case IIC_SDA:
   				write_gpio_bit(GPIO_MODE_OUT | IIC_SDA,1);
				break;
			case IIC_SCL:
				write_gpio_bit(GPIO_MODE_OUT | IIC_SCL,1);
				break;
			 case IIC_RESET:
			 	 write_gpio_bit(GPIO_MODE_OUT | IIC_RESET,1);
				break;
			default:
				break;
		}	
}



// Return status of SDA port at bit 0 ( 0 or 1 )
int   IIC_GET_SDA( void )
{
	 int  nReturn = 0;
	nReturn = read_gpio_bit(IIC_SDA);
	return( nReturn );
}


void IIC_Delay( int nCount )
{
     int i;
     int dummy = 0;

    for(i=0; i<nCount; i++) dummy += i;   
}


//开始启动总线
void IIC_Start( void )
{
	IIC_SDA_OUT();
	IIC_SET( IIC_SDA );
	IIC_SET( IIC_SCL );
    	IIC_Delay( IIC_SCLK_HFACTOR );
    	IIC_CLR( IIC_SDA );
 	IIC_CLR( IIC_SCL );
   	 IIC_Delay( IIC_SCLK_LFACTOR );
}

//结束总线
void IIC_Stop( void )
{
    IIC_SDA_OUT();
    IIC_CLR( IIC_SCL );
    IIC_Delay( IIC_SCLK_LFACTOR );
    IIC_CLR( IIC_SDA );
    IIC_Delay( IIC_SDA_FACTOR );
    IIC_SET( IIC_SCL );
    IIC_SET( IIC_SDA );
    IIC_Delay( IIC_SDA_FACTOR );

}

//发送答应位
void IIC_Ack( void )
{
	IIC_SDA_OUT();
	IIC_CLR( IIC_SDA );
    	IIC_Delay( IIC_SDA_FACTOR );
	IIC_SET( IIC_SCL );
	IIC_Delay(IIC_SCL_CLOCK);
	IIC_CLR( IIC_SCL );
    	IIC_Delay( IIC_SCLK_LFACTOR );
   	IIC_SET( IIC_SDA );
    	IIC_Delay( IIC_SDA_FACTOR );
}

//发送非答应位
void IIC_NoAck( void )
{	
	IIC_SDA_OUT();
   	IIC_SET( IIC_SDA );
    	IIC_Delay( IIC_SDA_FACTOR );
	IIC_SET( IIC_SCL );
	IIC_Delay(IIC_SCL_CLOCK);
	IIC_CLR( IIC_SCL );
    	IIC_Delay( IIC_SCLK_FACTOR );
}

//答应位检查
int  IIC_TestAck(void) 
{
	
	 int  ErrorBit=0;
	 IIC_SDA_IN();
	IIC_SET( IIC_SCL );
	ErrorBit=IIC_GET_SDA();
	IIC_Delay( IIC_SCLK_FACTOR );
	IIC_CLR( IIC_SCL );
    	IIC_Delay( IIC_SCLK_LFACTOR );
	
	return(ErrorBit);
}


//读IIC 一个字节
unsigned char   IIC_Read_Byte(void) 
{
	unsigned char  temp,rbyte=0;
	IIC_SDA_IN();
	for(temp=8;temp!=0;temp--) {
		IIC_SET( IIC_SCL );
		rbyte=rbyte<<1;
		rbyte=rbyte|(IIC_GET_SDA());
		IIC_Delay( IIC_SCLK_FACTOR );
		IIC_CLR( IIC_SCL );
    		IIC_Delay( IIC_SCLK_LFACTOR );
	}
	return(rbyte);
}

//向IIC 写一个字节
  void IIC_Write_Byte( unsigned char   input) 
{		
	 int  temp;
	IIC_SDA_OUT();
	for(temp=0;temp<8;temp++) {
		if( (input&0x0080) == 0x0080 ) {
			IIC_SET( IIC_SDA );
		} 
		else {
			IIC_CLR( IIC_SDA );
		}
		IIC_Delay( IIC_SDA_FACTOR );
		IIC_SET( IIC_SCL );
		IIC_Delay(IIC_SCL_CLOCK);
		IIC_CLR( IIC_SCL );
    		IIC_Delay( IIC_SCLK_LFACTOR );
		input=input<<1;
	}
}

//  Memory block read
int CryptReadMemory( unsigned char nZone, unsigned char nStart, 
		 			 unsigned char *pBuffer, int nCount )
{
    	int i;
   	 unsigned char nCommand;

    	if( nZone > 3 || nStart > 0x3F ) return( 0 );

    	nCommand = ATCOM_READ|( nZone<<2 );

    	IIC_Start();
    	IIC_Write_Byte(nCommand);//write command
    	if(IIC_TestAck())
    	{
    		IIC_Stop();
		return 0;
    	}
	
   	IIC_Write_Byte(nStart);//write addr
    	if(IIC_TestAck())
    	{
    		IIC_Stop();
		return 0;
    	}
  
    	for(i=0; i<nCount-1; i++) {
       	 pBuffer[i] =IIC_Read_Byte();
		IIC_Ack();
  	  }
    	pBuffer[i] = IIC_Read_Byte();
    	IIC_NoAck();
   	IIC_Stop();
    	return( 1 );
}


int CryptWriteMemory( unsigned char nZone, unsigned char nStart, 
		      		  unsigned char *pBuffer, unsigned char nCount )
{
    unsigned char nCommand;
    int i;
    unsigned char nStartLow;
    unsigned char nWriteMax;
    unsigned char nWriteCount = nCount;
    if( nZone > 3 ) return( 0 );

    nCommand = ATCOM_WRITE|( nZone<<2 );

    nStartLow = nStart&0x07;
    nWriteMax = 8 - nStartLow;

    if( nWriteCount > nWriteMax ) {
        nWriteCount = nWriteMax;
    	}	
    IIC_Start();
    IIC_Write_Byte(nCommand);//write command
    if(IIC_TestAck())
    {
    	IIC_Stop();
	return 0;
    	}
	
   IIC_Write_Byte(nStart);//write addr
    if(IIC_TestAck())
    {
    	IIC_Stop();
	return 0;
    	}
	
    for(i=0; i<nWriteCount; i++) { 
        IIC_Write_Byte( pBuffer[i] );//write data 
	if(IIC_TestAck())
    	{
    		IIC_Stop();
		return 0;
    	}
    
    }
    IIC_Stop();
    IIC_Delay( IIC_SCLK_LFACTOR );
    return( nWriteCount );
	
    }

//   Reset
// 
//   Return : 4 bytes ATR
void CryptResetChip( unsigned char *pAtr )
{
    unsigned char inVal;
    unsigned char retVal;
    int i, j;

    IIC_CLR( IIC_SCL );
    IIC_Delay( IIC_SDA_FACTOR );
    IIC_SET( IIC_RESET );
    IIC_Delay( IIC_SDA_FACTOR );
    IIC_SET( IIC_SCL );
    IIC_Delay( IIC_SDA_FACTOR );
    IIC_CLR( IIC_SCL );
    IIC_Delay( IIC_SDA_FACTOR );
    //
    //IIC_Delay( IIC_SDA_FACTOR );
    //IIC_Delay( IIC_SDA_FACTOR );
    IIC_CLR( IIC_RESET );
    IIC_SDA_IN();
    IIC_Delay( IIC_SCLK_FACTOR );

    for(i=0; i<4; i++) {
        retVal = 0x00;
        for(j=0; j<8; j++) {
            	IIC_CLR( IIC_SCL );
           	IIC_Delay( IIC_SDA_FACTOR );
	    	IIC_SET( IIC_SCL );
	 	IIC_Delay( IIC_SDA_HFACTOR );
		    inVal =IIC_GET_SDA();
		    retVal |= (inVal<<j);
		    IIC_Delay( IIC_SDA_HFACTOR );
	    }
		pAtr[i] = retVal;
    }
    IIC_SET( IIC_SCL );
    IIC_Delay( IIC_SDA_HFACTOR );
    IIC_SDA_OUT();
    
}

//
// Verify Password
//

int CryptVerifyPassword( unsigned char bRead, unsigned char nIndex,
		     unsigned char *pPassword )
{
    unsigned char nCommand;
    int i, j;
    unsigned char nAddr;
    unsigned char pTemp[2];
    for(j=0; j<2; j++) {
        IIC_Start();
      
        nCommand = ATCOM_VERIFY_PASSWD;
        if( bRead ) nCommand |= 0x08;
        if( nIndex == 1 ) nCommand |= 0x04;
        IIC_Write_Byte(nCommand);
        if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
		}
        for(i=0; i<3; i++) {
	    IIC_Write_Byte(pPassword[i]);
           if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
    		}	
        }
       IIC_Stop();
	IIC_Delay(IIC_SCLK_LFACTOR);
    }
   
    nAddr = ATCONF_PACW0_ADDR;
    if( bRead ) nAddr |= 4;
    if( nIndex == 1 ) nAddr |= 8;

    if( !CryptReadMemory( 3, nAddr, pTemp, 1 ) ) return( 0 );

    if( pTemp[0] == 0xFF ) return( 1 );
    else return( 0 );
	
}


// Initialize Authentication

int CryptAuthenticateInit( unsigned char *pQ )
{
    int i;
	IIC_Start();
       IIC_Write_Byte(ATCOM_AUTHENT_INIT);
       if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
    		}
	
	for(i=0; i<8; i++) {
	 IIC_Write_Byte(pQ[i]);
        if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
    		}
	}
	IIC_Stop();
	return( 1 );
	
}



// Verify Authentication

int CryptAuthenticateVerify( unsigned char *pCh )
{
	int i;
	IIC_Start();
	IIC_Write_Byte(ATCOM_AUTHENT_VERIFY);
       if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
    		}
	   
	for(i=0; i<8; i++) {
	IIC_Write_Byte( pCh[i]);
       if(IIC_TestAck()){
    		IIC_Stop();
		return 0;
    		}
	}
	IIC_Stop();
	return( 1 );

}


int  Crypt_ctl_ioctl(struct inode*inode,struct file *flip,unsigned int command,unsigned long arg)
{
	int err = 0;
	int ret=1;
	int i;
	struct crypt_ioctl_data *args;
	unsigned char *atrbuf;
	switch (command) {
		case WRITE_BLOCK:// wriete block
			args=(struct crypt_ioctl_data *)arg;
			//printk(" into write_block ......\n");
			ret=CryptWriteMemory(args->Zone,args->Start,args->PBuffer,args->Count);
			//printk("  write_block return %d \n",ret);
			return ret;
		case READ_BLOCK://read block
			args=(struct crypt_ioctl_data *)arg;
			//printk(" into read_block ......\n");
			ret=CryptReadMemory(args->Zone,args->Start,args->PBuffer,args->Count);
			//printk("  read_block return %d \n",ret);
			return ret;
			
		case  RESET_CHIP://reset chip
			atrbuf=(unsigned char *)arg;
			//printk(" into reset_chip ......\n");
			 CryptResetChip(atrbuf);
			 //printk("reset return data is   ");
			 //for(i=0;i<4;i++)
			 //printk("0x%02x   ",atrbuf[i]);
			 //printk("\n");
			return RESET_CHIP;
		case  VERIFY_PWD:// verify password
			args=(struct crypt_ioctl_data *)arg;
			//printk(" into verify_pwd ......\n");
			ret=CryptVerifyPassword(args->Zone,args->Start,args->PBuffer);
      //printk("  verify_pwd return %d \n",ret);
			return ret;
		case  INIT_AUTH://init auth
			args=(struct crypt_ioctl_data *)arg;
			//printk(" into init_auth ......\n");
			ret=CryptAuthenticateInit(args->PBuffer);
			//printk("  init_auth return %d \n",ret);
			return ret;
		case  VERIFY_AUTH://verify auth
			args=(struct crypt_ioctl_data *)arg;
			//printk(" into verify_auth ......\n");
			ret=CryptAuthenticateVerify(args->PBuffer);
			//printk("  verify_auth return %d \n",ret);
			return ret;
			
	}
	
	return err;
}

module_init(gpio_init); //用户加载该驱动时执行insmod gpio_driv.o就会自动调用gpio_init函数,它是驱动
//的入口点,相当于应用程序的main函数。
module_exit(gpio_release); //用户卸载该驱动rmmod gpio_driv时执行


⌨️ 快捷键说明

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