📄 tda8007.c
字号:
**************************************************************************/
static int tda_checkpresence(uchar slot)
{
u8 val;
val = tda_readregister(MSR);
switch(slot)
{
case 1:
if (val & MSR_PR1_MASK) return 1;
break;
case 2:
if (val & MSR_PR2_MASK) return 1;
break;
default:
return ERR_INVALID_SLOT;
break;
}
return 0;
}
/*************************************************************************
功能:select card
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int tda_selectcard(uchar slot)
{
u8 val;
val = tda_readregister(CSR);
switch (slot)
{
case 1:
// Select appropriate smartcard and clear other card selects
tda_writeregister(CSR, (val & ~(CSR_SC3_MASK | CSR_SC2_MASK))|CSR_SC1_MASK);
if(tda_checkpresence(slot) < 0) return NO_CARD_ERR;
break;
case 2:
// Select appropriate smartcard and clear other card selects
tda_writeregister(CSR,(val & ~(CSR_SC3_MASK|CSR_SC1_MASK))|CSR_SC2_MASK);
if(tda_checkpresence(slot) < 0) return NO_CARD_ERR;
break;
case 3:
// Select appropriate smartcard and clear other card selects
tda_writeregister(CSR,(val & ~(CSR_SC2_MASK|CSR_SC1_MASK))|CSR_SC3_MASK);
if(tda_checkpresence(slot) < 0) return NO_CARD_ERR;
break;
default:
return ERR_INVALID_SLOT;
}
// Set global slot identifier value
currentSlot = slot - 1;
printk("card selected: %d\n", currentSlot);
return 0;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int iccard_write( unsigned char *buff, int len ) /* the buffer to fill with data */
{ /* the length of the buffer. */
int i;
int ret;
uchar *txbuf;
uchar tmp;
txbuf = buff;
/*
printk("IC COMMAND = \n");
for(i = 0;i < len; i++)
printk("0x%x ",*(txbuf + i));
printk("\n");
*/
delay_us(50);
for(i = 0;i < len; i++)
{
if (i == (len - 1))
{
tmp = *(txbuf + i);
if((ret = writeLastByte(tmp))< 0)return ret;;
}
else
{
tmp = *(txbuf + i);
if((ret = writeByte(tmp))< 0)return ret;
}
}
return len;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int TDA_iccard_reset( unsigned char * rec_buf,int * rec_len,int cardname)
{
int ret;
char mode = POWERUP_ISO;
if (cardname == SAMCARD)
{
cardname = card_selected;
card_selected = SAMCARD;
ret = tda_selectcard(card_selected);
if(ret < 0)return ret;
ret = tda_powerup(POWERUP_ISO, POWERUP_5V);
if(ret < 0) return ret;
samcard_err = tda_ATRsequence(mode, rec_buf, rec_len);
card_selected = cardname;
if (samcard_err < 0)
{
tda_powerdown();
return samcard_err;
}
}
else if(cardname == USRCARD)
{
cardname = card_selected;
card_selected = USRCARD;
ret = tda_selectcard(card_selected);
if(ret < 0)return ret;
ret = tda_powerup(POWERUP_ISO, POWERUP_5V);
if(ret < 0) return ret;
usrcard_err = tda_ATRsequence(mode, rec_buf, rec_len);
card_selected = cardname;
if (usrcard_err < 0)
{
tda_powerdown();
return usrcard_err;
}
}
else return NO_CARD_ERR;
return 0;
}
/*----------------------------------------------------------------------------*/
/* file_operations functions -------------------------------------------------*/
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static ssize_t TDA_iccard_write (struct file *file,
char *buff, /* the buffer to fill with data */
size_t len, /* the length of the buffer. */
loff_t *offset)
{ /* Our offset in the file */
int retval = 0;
//int ll;
char txbuf[TDA_ICCARD_BUF_SIZE];
if ((len >= sizeof(txbuf))||(len <= 0)) return -EINVAL;
copy_from_user( txbuf, buff, len);
if (card_selected == SAMCARD) {
tda_selectcard(card_selected);
if (samcard_err < 0)
{
printk("iccard.c L1209 samcard_err = %d\n",samcard_err);
return -1;
}
}
else if(card_selected == USRCARD){
tda_selectcard(card_selected);
if(usrcard_err < 0)
{
printk("iccard.c L1209 usrcard_err = %d\n",usrcard_err);
return -1;
}
}
else return NO_SELECTED_CARD_ERR;
//printk("end write command\n");
//delay_cycle(40000);
//delay_us(50);
retval = TDA_iccard_comm(txbuf,len,iccardfifo.buffer,&iccardfifo.len);//2007-10-22 15:47:17//
if(place_err != 0)
printk("place_err = %d\n",place_err);
//printk("%d jiaoyanerr = %d\n partity = %d\n",card_selected,jiaoyanerr,partity);
//for(ll = 0; ll < 10; ll++)
//delay_cycle(20000);
if (card_selected == SAMCARD)
{
samcard_err = retval;
}
else if(card_selected == USRCARD)
{
usrcard_err = retval;
}
else return NO_SELECTED_CARD_ERR;
#ifdef DEBUG_ICCARD
TDA_show_card_err_msg(retval);
#endif
return retval;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static ssize_t TDA_iccard_read (struct file *file,
char *buff, /* the buffer to fill with data */
size_t len, /* the length of the buffer. */
loff_t *offset)
{ /* Our offset in the file */
int retval = 0;
//sti();
if (iccardfifo.len == 0) retval=0;
else
{
retval = iccardfifo.len;
printk("iccardfifo.len = %d\n",iccardfifo.len);
if ( copy_to_user (buff, iccardfifo.buffer, iccardfifo.len) )
retval = -EFAULT;
}
//printk("iccardfifo.len = %d\n",iccardfifo.len);
iccardfifo.len = 0;
return retval;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int TDA_iccard_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, /* the command to the ioctl */
unsigned long arg)
{ /* the parameter to it */
int retval;
int count = 0;
uchar val;
switch (cmd)
{
case TDA_CARD_SELECT:
if ( arg == SAMCARD ) card_selected = SAMCARD;
else if ( arg == USRCARD ) card_selected = USRCARD;
else card_selected = NONECARD;
break;
case TDA_CARD_RESET:
if ( card_selected == USRCARD )
if (usrcard_err == NO_CARD_ERR) return -1;
retval = TDA_iccard_reset( iccardfifo.buffer, &iccardfifo.len, card_selected );
//tda_init();
#ifdef DEBUG_ICCARD
TDA_show_card_err_msg(retval);
#endif
return retval;
break;
case TDA_CARD_STATUS:
if( card_selected == SAMCARD )
{
if ((retval = put_user(samcard_err, (int *)arg)) < 0)
return retval;
}
else if ( card_selected == USRCARD )
{
if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
return retval;
}
else return -EINVAL;
break;
case TDA_CARD_POWER_OFF:
tda_selectcard(card_selected);
tda_powerdown();
break;
case TDA_USR_CARD_ERR:
// printk("usrcard_err = %d\n",usrcard_err);
if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
return retval;
break;
case TDA_SAM_CARD_ERR:
//printk("samcard_err = %d\n",samcard_err);
if ((retval = put_user(samcard_err, (int *)arg)) < 0)
return retval;
break;
case 'a':
count = 0;
tda_selectcard(USRCARD);
tda_powerup(POWERUP_ISO, POWERUP_5V);
printk("Test Time!\n");
tda_writeregister(TOC,0x00);
tda_writeregister(TOR3,0x00);
tda_writeregister(TOR2,0x78);
tda_writeregister(TOR1,0x00);
tda_writeregister(TOC,0x61);
printk("Start count!\n");
do
{
if(++count >= 5000)
{
printk("Time-count dont end\n");
break;
}
val = tda_readregister(USR);
}while (!(val & USR_TOL3_MASK));
printk("Time-count is end\n");
break;
case 'b':
break;
default:
return -EINVAL;
break;
}
return 0;
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int TDA_iccard_open(struct inode *inode, struct file *file)
{
if(iccard_device_open) return -EBUSY;
MOD_INC_USE_COUNT;
/* And my own counter too */
iccard_device_open++;
card_selected = NONECARD;
//init buffer
iccardfifo.len = 0;
#ifdef DEBUG_ICCARD
printk("iccard open ok\n");
#endif
return 0; /* open succeed */
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int TDA_iccard_release(struct inode *inode, struct file *file)
{
tda_selectcard(USRCARD);
tda_powerdown();
tda_selectcard(SAMCARD);
tda_powerdown();
card_selected = NONECARD;
MOD_DEC_USE_COUNT;
/* And my own counter too */
iccard_device_open--;
GPBDAT &= ~(1<<3);//TDA8007 POWER Disable
return 0;
}
//*******************************************************
//*******************************************************
static struct file_operations iccard_fops = {
owner: THIS_MODULE,
read: TDA_iccard_read,
ioctl: TDA_iccard_ioctl,
open: TDA_iccard_open,
release: TDA_iccard_release,
write: TDA_iccard_write,
};
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
int __init TDA_iccard_init(void)
{
int ret = 0;
/* Register the misc device driver */
BWSCON = (BWSCON & ~( BWSCON_WS4 | BWSCON_ST4 | BWSCON_DW4)) |
//(BWSCON_ST4 | BWSCON_WS4 | BWSCON_DW(4, BWSCON_DW_8));
(BWSCON_ST4 | BWSCON_DW(4, BWSCON_DW_8));
BANKCON4 = BANKCON_Tacs0 | BANKCON_Tcos4 | BANKCON_Tacc14 |
BANKCON_Toch1 | BANKCON_Tcah4 | BANKCON_Tacp6 | BANKCON_PMC1;//6 16
printk("BWSCON = %x\nBANKCON4 = %x\n",BWSCON,BANKCON1);
GPBCON &= ~(3<<6);
GPBCON |= (1<<6);
GPBDAT |= (1<<3);//TDA8007 POWER enable
TDA1addr = (void *)EVOC_TDA8007_ADDRESS;
set_external_irq(IRQ_IC, EXT_LOWLEVEL, GPIO_PULLUP_DIS);
ret = request_irq(IRQ_IC, s3c2410_isr_tda, SA_INTERRUPT, "TDA8007", NULL);
if(ret)
{
printk("Request IRQ %d for TDA8007 interface failure.\n",IRQ_IC);
return ret;
}
printk("%d %s interrupts request OK!\n",IRQ_RTC, DEVICE_NAME);
tda_init();
temp_60 = (u8 *)kmalloc(255,GFP_KERNEL);
ret = register_chrdev(0,DEVICE_NAME,&iccard_fops);
if(ret < 0)
printk("%s: Error registering the device\n", __file__);
else
printk("%s: Device register with name: %s and number: %d %d\n",
__file__, DEVICE_NAME, ret, IC_MINOR);
DbIcMajor = ret;
#ifdef CONFIG_DEVFS_FS
devfs_ICraw = devfs_register(NULL,"iccard",
DEVFS_FL_DEFAULT,DbIcMajor,IC_MINOR,
S_IFCHR|S_IRUSR|S_IWUSR,&iccard_fops,NULL);
#endif
printk("%s initialized\n",DEVICE_NAME);
return 0; /* A non zero value means that init_module failed */
}
/*************************************************************************
功能:
参数:
返回值:-1: error
0: OK
**************************************************************************/
void TDA_iccard_cleanup(void)
{
/* IRQ have to be freed after the hardware is instructed not to interrupt
* the processor any more.
*/
printk("iccard cleanup!\n");
kfree(temp_60);
free_irq(IRQ_IC, NULL);
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_ICraw);
#endif
unregister_chrdev(DbIcMajor,DEVICE_NAME);
}
module_init(TDA_iccard_init);
module_exit(TDA_iccard_cleanup);
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -