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

📄 tda8007.c

📁 TDA8007接口驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************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/arch/hardware.h>
#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))
		  // Set smartcard clock to 1/1 crystal
		 tda_writeregister(CCR,0x00);
	#elif ((CRYSTAL_FREQUENCY_8007 >= 2000000L) && (CRYSTAL_FREQUENCY_8007 <= 10000000L))
		  // Set smartcard clock to 1/2 crystal
		 tda_writeregister(CCR,0x01);
	#elif ((CRYSTAL_FREQUENCY_8007 >= 4000000L) && (CRYSTAL_FREQUENCY_8007 <= 20000000L))
		  // Set smartcard clock to 1/4 crystal
		 tda_writeregister(CCR,0x02);
	#elif ((CRYSTAL_FREQUENCY_8007 >= 8000000L) && (CRYSTAL_FREQUENCY_8007 <= 40000000L))
		  // Set smartcard clock to 1/8 crystal
		 tda_writeregister(CCR,0x03);
	#else
		  // Set smartcard clock to 1/2 internal oscillator (about 1.44MHz)
		  // NOTE: Can only change CCR.2 when shifting to internal oscillator
		 tda_writeregister(CCR,0x01);
		 tda_writeregister(CCR,0x05);
		  // Wait for internal oscillator to engage (check the MSR.CLKSW bit on page 18)
		
		if ( DEBUG > 2 )
		  printk("Waiting for Clock to switch\n");		  
		do
		{
		    val = tda_readregister(MSR);
		}while (!(val & MSR_CLKSW_MASK));
	#endif
		
		printk("Preparing to Apply Power1\n");		
		  // Set the power supply voltage
		val = tda_readregister(PCR);
		  // Clear 1.8V and 3V bits
		tda_writeregister(PCR,val & ~(PCR_3V_5V_MASK|PCR_1V8_MASK));
		switch(voltage)
		{
		   case POWERUP_5V:
		      // Do nothing
		   break;
		   case POWERUP_3V:
		      val = tda_readregister(PCR);
		      // Set 3V bit
		      tda_writeregister(PCR,val | PCR_3V_5V_MASK);
		   break;
		   case POWERUP_1p8V:
		      val = tda_readregister(PCR);
		      // Set 1.8V bit
		      tda_writeregister(PCR,val | PCR_1V8_MASK);
		   break;
		   default:
		      return ERR_POWERUP_VOLTAGE_INVALID;
		   break;
		}
		
		  // Apply reset
		val = tda_readregister(PCR);
		tda_writeregister(PCR,val & ~PCR_RSTIN_MASK);
		
		  printk("Preparing to Apply Power1\n");
		
		val = tda_readregister(HSR);//clear HSR
		  
		do
	  {
		    //Power the card, RST low, C4 and C8 high
		    val = tda_readregister(PCR);
		    tda_writeregister(PCR,val | (PCR_C8_MASK|PCR_C4_MASK|PCR_START_MASK));
		    //tda_writeregister(PCR,val | PCR_START_MASK);
		    
		    val = tda_readregister(HSR);
		    if (val & (HSR_PRTL2_MASK|HSR_PRTL1_MASK|HSR_PRL2_MASK|HSR_PRL1_MASK|HSR_PTL_MASK))
		    {
		    #if DEBUG > 0
		      printk("Power problem detected 0x%2x\n",val);
		    #endif
		      tda_powerdown();
		      return ERR_POWERUP_INTERRUPTED;
		    }
		    val = tda_readregister(PCR);
		}while (!(val & PCR_START_MASK));	
		#if DEBUG > 1
		  printk("Power is on\n");
		#endif
		  // Call common getATR routine
		  return 0;
		  //return tda_ATRsequence(mode);
}
/*************************************************************************
	功能:
	参数:
	Read a byte from the UART or timeout after BWT (T=1), CWT (T=1) or WWT (T=0).
  Not tested		
	返回值:-1: error
			     0: OK		   			
**************************************************************************/
static signed char readByte(uchar *temp)
{
	  u8 val;
	  uint timeout;
	  //printk("tda_readregister(UCR1) = 0x%x\n",tda_readregister(UCR1));
	  if (TMode[currentSlot] == 0)
	    timeout = WWT[currentSlot];  // Use WWT for T=0
	  else
	    timeout = CWT[currentSlot];  // Use CWT for T=1	
	  // Set up timer for 24 bit timer, start immediately	
	  //while(!(tda_readregister(USR) & USR_TBE_RBF_MASK)) 
	  while(!(tda_readregister(MSR) & MSR_TBE_RBF_MASK))
	  {
	    val = tda_readregister(USR);
	    if (val & USR_PE_MASK)
	    {

⌨️ 快捷键说明

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