📄 cryptdriver.c.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 + -