2005-05-16 21:54:10 -07:00
/*
* This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII ( b ) / III
*
* flexcop - eeprom . c - eeprom access methods ( currently only MAC address reading is used )
*
* see flexcop . c for copyright information .
*/
# include "flexcop.h"
#if 0
/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
static int eeprom_write ( struct adapter * adapter , u16 addr , u8 * buf , u16 len )
{
return flex_i2c_write ( adapter , 0x20000000 , 0x50 , addr , buf , len ) ;
}
static int eeprom_lrc_write ( struct adapter * adapter , u32 addr , u32 len , u8 * wbuf , u8 * rbuf , int retries )
{
int i ;
for ( i = 0 ; i < retries ; i + + ) {
if ( eeprom_write ( adapter , addr , wbuf , len ) = = len ) {
if ( eeprom_lrc_read ( adapter , addr , len , rbuf , retries ) = = 1 )
return 1 ;
}
}
return 0 ;
}
/* These functions could be used to unlock SkyStar2 cards. */
static int eeprom_writeKey ( struct adapter * adapter , u8 * key , u32 len )
{
u8 rbuf [ 20 ] ;
u8 wbuf [ 20 ] ;
if ( len ! = 16 )
return 0 ;
memcpy ( wbuf , key , len ) ;
wbuf [ 16 ] = 0 ;
wbuf [ 17 ] = 0 ;
wbuf [ 18 ] = 0 ;
wbuf [ 19 ] = calc_lrc ( wbuf , 19 ) ;
return eeprom_lrc_write ( adapter , 0x3e4 , 20 , wbuf , rbuf , 4 ) ;
}
static int eeprom_readKey ( struct adapter * adapter , u8 * key , u32 len )
{
u8 buf [ 20 ] ;
if ( len ! = 16 )
return 0 ;
if ( eeprom_lrc_read ( adapter , 0x3e4 , 20 , buf , 4 ) = = 0 )
return 0 ;
memcpy ( key , buf , len ) ;
return 1 ;
}
static char eeprom_set_mac_addr ( struct adapter * adapter , char type , u8 * mac )
{
u8 tmp [ 8 ] ;
if ( type ! = 0 ) {
tmp [ 0 ] = mac [ 0 ] ;
tmp [ 1 ] = mac [ 1 ] ;
tmp [ 2 ] = mac [ 2 ] ;
tmp [ 3 ] = mac [ 5 ] ;
tmp [ 4 ] = mac [ 6 ] ;
tmp [ 5 ] = mac [ 7 ] ;
} else {
tmp [ 0 ] = mac [ 0 ] ;
tmp [ 1 ] = mac [ 1 ] ;
tmp [ 2 ] = mac [ 2 ] ;
tmp [ 3 ] = mac [ 3 ] ;
tmp [ 4 ] = mac [ 4 ] ;
tmp [ 5 ] = mac [ 5 ] ;
}
tmp [ 6 ] = 0 ;
tmp [ 7 ] = calc_lrc ( tmp , 7 ) ;
if ( eeprom_write ( adapter , 0x3f8 , tmp , 8 ) = = 8 )
return 1 ;
return 0 ;
}
static int flexcop_eeprom_read ( struct flexcop_device * fc , u16 addr , u8 * buf , u16 len )
{
return fc - > i2c_request ( fc , FC_READ , FC_I2C_PORT_EEPROM , 0x50 , addr , buf , len ) ;
}
# endif
static u8 calc_lrc ( u8 * buf , int len )
{
int i ;
u8 sum = 0 ;
for ( i = 0 ; i < len ; i + + )
sum = sum ^ buf [ i ] ;
return sum ;
}
static int flexcop_eeprom_request ( struct flexcop_device * fc , flexcop_access_op_t op , u16 addr , u8 * buf , u16 len , int retries )
{
int i , ret = 0 ;
u8 chipaddr = 0x50 | ( ( addr > > 8 ) & 3 ) ;
for ( i = 0 ; i < retries ; i + + )
if ( ( ret = fc - > i2c_request ( fc , op , FC_I2C_PORT_EEPROM , chipaddr , addr & 0xff , buf , len ) ) = = 0 )
break ;
return ret ;
}
static int flexcop_eeprom_lrc_read ( struct flexcop_device * fc , u16 addr , u8 * buf , u16 len , int retries )
{
int ret = flexcop_eeprom_request ( fc , FC_READ , addr , buf , len , retries ) ;
if ( ret = = 0 )
if ( calc_lrc ( buf , len - 1 ) ! = buf [ len - 1 ] )
ret = - EINVAL ;
return ret ;
}
/* JJ's comment about extended == 1: it is not presently used anywhere but was
* added to the low - level functions for possible support of EUI64
*/
int flexcop_eeprom_check_mac_addr ( struct flexcop_device * fc , int extended )
{
u8 buf [ 8 ] ;
int ret = 0 ;
if ( ( ret = flexcop_eeprom_lrc_read ( fc , 0x3f8 , buf , 8 , 4 ) ) = = 0 ) {
if ( extended ! = 0 ) {
err ( " TODO: extended (EUI64) MAC addresses aren't completely supported yet " ) ;
ret = - EINVAL ;
2005-05-16 21:54:14 -07:00
/* memcpy(fc->dvb_adapter.proposed_mac,buf,3);
2005-05-16 21:54:10 -07:00
mac [ 3 ] = 0xfe ;
mac [ 4 ] = 0xff ;
2005-05-16 21:54:14 -07:00
memcpy ( & fc - > dvb_adapter . proposed_mac [ 3 ] , & buf [ 5 ] , 3 ) ; */
2005-05-16 21:54:10 -07:00
} else
2005-05-16 21:54:14 -07:00
memcpy ( fc - > dvb_adapter . proposed_mac , buf , 6 ) ;
2005-05-16 21:54:10 -07:00
}
return ret ;
}
EXPORT_SYMBOL ( flexcop_eeprom_check_mac_addr ) ;