📄 tda8007.c
字号:
/****************************************Copyright (c)**************************************************
** 北京研祥兴业有限公司
** 研发部
** http://www.FFTChina.com
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: TDA8007.c
**创 建 人: 刘丙毓
**最后修改日期: 2007年9月26日
**-------------- 历史版本信息----------------------------------------------------------------------------
** 创建人: 刘丙毓
** 版 本: v1.0
** 日 期: 2007年9月26日
** 描 述: 原始版本
**
**AD0 ---- BA0 ----- A0
**AD1 ---- BA1 ----- A1
**AD2 ---- BA2 ----- A2
**AD9 ---- BA9 ----- A9
**TDA_INT --- EINT3
**TDA_CS ---- CPLD_67
**TDA_WR ---- CPLD_68
**TDA_RD ---- CPLD_69
**TDA_PWR_EN ---- GPB3
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
/*
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
*/
#include <LINUX kernel.h>
#include <LINUX module.h>
#include <LINUX miscdevice.h>
#include <LINUX fs.h>
#include <LINUX timer.h>
#include <LINUX param.h>
#include <LINUX sched.h>
#include <LINUX mm.h>
#include <LINUX malloc.h>
#include <LINUX init.h>
#include <LINUX TdaDriver.h>
#include <ASM hardware.h arch>
#include <ASM arch irqs.h>
#include <ASM irq.h> /* For IRQ_MACHSPEC */
#include <ASM uaccess.h>
#include <ASM io.h>
#include "TDA8007.h"
/* For IRQ_MACHSPEC */
static const char* __file__ = __FILE__;
#define IC_MINOR 0
#define DEVICE_NAME "s3c2410IC"
#define _INLINE_ inline
#define DEBUG 1
static u8 *TDA1addr;
unsigned int *can0addr;
void clearATRstruct(struct ATR*);
static int tda_ATRsequence(uchar mode, uchar *rec_buf, int * rec_len);
#define TDA_ICCARD_BUF_SIZE 1024
static struct ICCARDFIFO {
unsigned char buffer[TDA_ICCARD_BUF_SIZE];
int len;
}iccardfifo;
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_ICraw;
#endif
static int iccard_device_open = 0;
static int DbIcMajor = 0;
static int card_selected = NONECARD;
static int samcard_err = -1;
static int usrcard_err = -1;
static char place_err ;
//static char reset_err ;
unsigned char *temp_60;
struct ATR lastATR[CARD_SLOTS];
uchar TMode[CARD_SLOTS]; // T=0 or T=1
uint WWT[CARD_SLOTS]; // Work wait time
uint CWT[CARD_SLOTS]; // Character wait time
uchar currentSlot = 0;
#define C1_IC (1<<12) /* icache off/on */
#define C1_DC (1<<2) /* dcache off/on */
static void cp_delay (void)
{
volatile int i;
/* copro seems to need some delay between reading and writing */
for (i = 0; i < 100; i++);
}
static unsigned long read_p15_c1 (void)
{
unsigned long value;
__asm__ __volatile__(
"mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
: "=r" (value)
:
: "memory");
return value;
}
static void write_p15_c1 (unsigned long value)
{
#ifdef MMU_DEBUG
printf ("write %08lx to p15/c1\n", value);
#endif
__asm__ __volatile__(
"mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
:
: "r" (value)
: "memory");
read_p15_c1 ();
}
void dcache_enable (void)
{
ulong reg;
reg = read_p15_c1 ();
cp_delay ();
write_p15_c1 (reg | C1_DC);
}
void dcache_disable (void)
{
ulong reg;
reg = read_p15_c1 ();
cp_delay ();
reg &= ~C1_DC;
write_p15_c1 (reg);
}
int dcache_status (void)
{
return (read_p15_c1 () & C1_DC) != 0;
}
void icache_enable (void)
{
ulong reg;
reg = read_p15_c1 (); /* get control reg. */
cp_delay ();
write_p15_c1 (reg | C1_IC);
}
void icache_disable (void)
{
ulong reg;
reg = read_p15_c1 ();
cp_delay ();
write_p15_c1 (reg & ~C1_IC);
}
int icache_status (void)
{
return (read_p15_c1 () & C1_IC) != 0;
}
/*************************************************************************
功能:delay us
参数:
返回值:-1: error
0: OK
**************************************************************************/
static void delay_us(uint usnum)
{
volatile int i;
for(;usnum > 0;usnum--)
for(i = 0; i < 50; i++);
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static _INLINE_ void tda_writeregister(int address,u8 value)
{
switch (address)
{
case TOC:
case UTR:
// If writing TOC or UTR, check the CRED bit in MSR so that
// we don't overrun the 8007. See MSR.CRED bit description on page
// 18 of 8007 spec.
while (!(readb(TDA1addr + MSR) & MSR_CRED_MASK));
break;
default:
break;
}
writeb(value, TDA1addr + address);//(unsigned long)
//*(volatile unsigned short*)(TDA1addr + address) = value;
//printk("WR : Command = 0x%p Data = 0x%x\n",TDA1addr + address,value);
//delay_us(100);
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static _INLINE_ u8 tda_readregister(int address)
{
u8 toReturn = 0;
switch (address)
{
case URR:
// If reading URR, check the CRED bit in MSR so that
// we don't overrun the 8007. See MSR.CRED bit description on page
// 18 of 8007 spec.
while (!(readb(TDA1addr + MSR) & MSR_CRED_MASK))
{
// If card de-powers exit with zero return value.
//delay_us(100);
if ((readb(TDA1addr + PCR) & 0x01) == 0)// there is possible to become permanent cycle run
{
return 0;
}
}
break;
default:
break;
}
//printk("Command = 0x%p", TDA1addr + address);//(unsigned long)
toReturn = readb( TDA1addr + address);//(unsigned long)
//delay_us(100);
//printk(" Data = 0x%x\n",toReturn);
return toReturn;
}
/*************************************************************************
功能:Dump formatted contents of ATR struct
参数:
返回值:-1: error
0: OK
**************************************************************************/
void s3c2410_isr_tda(int irq,void *dev_id,struct pt_regs *reg)
{
uchar tmp = 0;
tmp = tda_readregister(USR);
if(tmp & USR_TOL1_MASK)printk("Time-Out counter 1 has reched terminal count.\n");
if(tmp & USR_TOL2_MASK)printk("Time-Out counter 2 has reched terminal count.\n");
if(tmp & USR_TOL3_MASK)printk("Time-Out counter 3 has reched terminal count.\n");
tmp = tda_readregister(HSR);
if(tmp & HSR_PTL_MASK)
{
tda_selectcard(USRCARD);
tda_powerdown();
tda_selectcard(SAMCARD);
tda_powerdown();
}
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static void clearATRStruct(struct ATR *myatr)
{
memset(myatr,0xFF,sizeof(struct ATR));
myatr->HistoricalLength = 0;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int tda_init(void)
{
u8 val = 0;
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~(CSR_SC1_MASK | CSR_SC2_MASK | CSR_SC1_MASK));
val = tda_readregister(CSR);
tda_writeregister(CSR,(val | CSR_SC1_MASK) & ~(CSR_SC2_MASK | CSR_SC3_MASK));
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~CSR_nRIU_MASK);
tda_writeregister(CSR,val | CSR_nRIU_MASK);
val = tda_readregister(CSR);
tda_writeregister(CSR,(val | CSR_SC2_MASK) & ~(CSR_SC1_MASK | CSR_SC3_MASK));
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~CSR_nRIU_MASK);
tda_writeregister(CSR,val | CSR_nRIU_MASK);
val = tda_readregister(CSR);
tda_writeregister(CSR,(val | CSR_SC3_MASK) & ~(CSR_SC1_MASK | CSR_SC2_MASK));
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~CSR_nRIU_MASK);
tda_writeregister(CSR,val | CSR_nRIU_MASK);
//tda_readregister(CSR);//debug
// Select smart card slot 1
val = tda_readregister(CSR);
tda_writeregister(CSR,(val | CSR_SC1_MASK) & ~(CSR_SC2_MASK | CSR_SC3_MASK));
// Make sure card is powered down
val = tda_readregister(PCR);
tda_writeregister(PCR,val & ~PCR_START_MASK);
// Select smart card slot 2
val = tda_readregister(CSR);
tda_writeregister(CSR,(val | CSR_SC2_MASK) & ~(CSR_SC1_MASK | CSR_SC2_MASK));
// Make sure card is powered down
val = tda_readregister(PCR);
tda_writeregister(PCR,val & ~PCR_START_MASK);
//tda_readregister(CSR);//debug
// Deselect all cards
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~(CSR_SC1_MASK | CSR_SC2_MASK | CSR_SC3_MASK));
return 0;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int tda_powerup(uchar mode, uchar voltage)
{
uchar val;
// Compile time setting of operating crystal frequency
#if ((CRYSTAL_FREQUENCY_8007 >= 1000000L) && (CRYSTAL_FREQUENCY_8007 <= 5000000L))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -