2012-03-30 15:21:25 +04:00
/*
* Afatech AF9033 demodulator driver
*
* Copyright ( C ) 2009 Antti Palosaari < crope @ iki . fi >
* Copyright ( C ) 2012 Antti Palosaari < crope @ iki . fi >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include "af9033_priv.h"
2013-11-02 12:11:47 +04:00
/* Max transfer size done by I2C transfer functions */
# define MAX_XFER_SIZE 64
2014-08-31 09:18:34 +04:00
struct af9033_dev {
2014-09-01 03:57:05 +04:00
struct i2c_client * client ;
2012-03-30 15:21:25 +04:00
struct dvb_frontend fe ;
struct af9033_config cfg ;
2014-09-02 10:55:21 +04:00
bool is_af9035 ;
bool is_it9135 ;
2012-03-30 15:21:25 +04:00
u32 bandwidth_hz ;
bool ts_mode_parallel ;
bool ts_mode_serial ;
2012-04-07 17:34:34 +04:00
2014-09-02 10:55:21 +04:00
fe_status_t fe_status ;
2012-04-07 17:34:34 +04:00
u32 ber ;
u32 ucb ;
2014-09-02 15:01:10 +04:00
u64 error_block_count ;
u64 total_block_count ;
2014-09-02 10:55:21 +04:00
struct delayed_work stat_work ;
2012-04-07 17:34:34 +04:00
unsigned long last_stat_check ;
2012-03-30 15:21:25 +04:00
} ;
/* write multiple registers */
2014-08-31 09:18:34 +04:00
static int af9033_wr_regs ( struct af9033_dev * dev , u32 reg , const u8 * val ,
2012-03-30 15:21:25 +04:00
int len )
{
int ret ;
2013-11-02 12:11:47 +04:00
u8 buf [ MAX_XFER_SIZE ] ;
2012-03-30 15:21:25 +04:00
struct i2c_msg msg [ 1 ] = {
{
2014-09-01 03:57:05 +04:00
. addr = dev - > client - > addr ,
2012-03-30 15:21:25 +04:00
. flags = 0 ,
2013-11-02 12:11:47 +04:00
. len = 3 + len ,
2012-03-30 15:21:25 +04:00
. buf = buf ,
}
} ;
2013-11-02 12:11:47 +04:00
if ( 3 + len > sizeof ( buf ) ) {
2014-09-01 03:57:05 +04:00
dev_warn ( & dev - > client - > dev ,
2014-09-01 04:08:09 +04:00
" i2c wr reg=%04x: len=%d is too big! \n " ,
reg , len ) ;
2013-11-02 12:11:47 +04:00
return - EINVAL ;
}
2012-03-30 15:21:25 +04:00
buf [ 0 ] = ( reg > > 16 ) & 0xff ;
buf [ 1 ] = ( reg > > 8 ) & 0xff ;
buf [ 2 ] = ( reg > > 0 ) & 0xff ;
memcpy ( & buf [ 3 ] , val , len ) ;
2014-09-01 03:57:05 +04:00
ret = i2c_transfer ( dev - > client - > adapter , msg , 1 ) ;
2012-03-30 15:21:25 +04:00
if ( ret = = 1 ) {
ret = 0 ;
} else {
2014-09-01 04:08:09 +04:00
dev_warn ( & dev - > client - > dev , " i2c wr failed=%d reg=%06x len=%d \n " ,
ret , reg , len ) ;
2012-03-30 15:21:25 +04:00
ret = - EREMOTEIO ;
}
return ret ;
}
/* read multiple registers */
2014-08-31 09:18:34 +04:00
static int af9033_rd_regs ( struct af9033_dev * dev , u32 reg , u8 * val , int len )
2012-03-30 15:21:25 +04:00
{
int ret ;
u8 buf [ 3 ] = { ( reg > > 16 ) & 0xff , ( reg > > 8 ) & 0xff ,
( reg > > 0 ) & 0xff } ;
struct i2c_msg msg [ 2 ] = {
{
2014-09-01 03:57:05 +04:00
. addr = dev - > client - > addr ,
2012-03-30 15:21:25 +04:00
. flags = 0 ,
. len = sizeof ( buf ) ,
. buf = buf
} , {
2014-09-01 03:57:05 +04:00
. addr = dev - > client - > addr ,
2012-03-30 15:21:25 +04:00
. flags = I2C_M_RD ,
. len = len ,
. buf = val
}
} ;
2014-09-01 03:57:05 +04:00
ret = i2c_transfer ( dev - > client - > adapter , msg , 2 ) ;
2012-03-30 15:21:25 +04:00
if ( ret = = 2 ) {
ret = 0 ;
} else {
2014-09-01 04:08:09 +04:00
dev_warn ( & dev - > client - > dev , " i2c rd failed=%d reg=%06x len=%d \n " ,
ret , reg , len ) ;
2012-03-30 15:21:25 +04:00
ret = - EREMOTEIO ;
}
return ret ;
}
/* write single register */
2014-08-31 09:18:34 +04:00
static int af9033_wr_reg ( struct af9033_dev * dev , u32 reg , u8 val )
2012-03-30 15:21:25 +04:00
{
2014-08-31 09:18:34 +04:00
return af9033_wr_regs ( dev , reg , & val , 1 ) ;
2012-03-30 15:21:25 +04:00
}
/* read single register */
2014-08-31 09:18:34 +04:00
static int af9033_rd_reg ( struct af9033_dev * dev , u32 reg , u8 * val )
2012-03-30 15:21:25 +04:00
{
2014-08-31 09:18:34 +04:00
return af9033_rd_regs ( dev , reg , val , 1 ) ;
2012-03-30 15:21:25 +04:00
}
/* write single register with mask */
2014-08-31 09:18:34 +04:00
static int af9033_wr_reg_mask ( struct af9033_dev * dev , u32 reg , u8 val ,
2012-03-30 15:21:25 +04:00
u8 mask )
{
int ret ;
u8 tmp ;
/* no need for read if whole reg is written */
if ( mask ! = 0xff ) {
2014-08-31 09:18:34 +04:00
ret = af9033_rd_regs ( dev , reg , & tmp , 1 ) ;
2012-03-30 15:21:25 +04:00
if ( ret )
return ret ;
val & = mask ;
tmp & = ~ mask ;
val | = tmp ;
}
2014-08-31 09:18:34 +04:00
return af9033_wr_regs ( dev , reg , & val , 1 ) ;
2012-03-30 15:21:25 +04:00
}
/* read single register with mask */
2014-08-31 09:18:34 +04:00
static int af9033_rd_reg_mask ( struct af9033_dev * dev , u32 reg , u8 * val ,
2012-03-30 15:21:25 +04:00
u8 mask )
{
int ret , i ;
u8 tmp ;
2014-08-31 09:18:34 +04:00
ret = af9033_rd_regs ( dev , reg , & tmp , 1 ) ;
2012-03-30 15:21:25 +04:00
if ( ret )
return ret ;
tmp & = mask ;
/* find position of the first bit */
for ( i = 0 ; i < 8 ; i + + ) {
if ( ( mask > > i ) & 0x01 )
break ;
}
* val = tmp > > i ;
return 0 ;
}
2013-03-08 23:54:09 +04:00
/* write reg val table using reg addr auto increment */
2014-08-31 09:18:34 +04:00
static int af9033_wr_reg_val_tab ( struct af9033_dev * dev ,
2013-03-08 23:54:09 +04:00
const struct reg_val * tab , int tab_len )
{
2013-11-28 00:17:43 +04:00
# define MAX_TAB_LEN 212
2013-03-08 23:54:09 +04:00
int ret , i , j ;
2013-11-28 00:17:43 +04:00
u8 buf [ 1 + MAX_TAB_LEN ] ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " tab_len=%d \n " , tab_len ) ;
2013-11-02 12:11:47 +04:00
if ( tab_len > sizeof ( buf ) ) {
2014-09-01 04:08:09 +04:00
dev_warn ( & dev - > client - > dev , " tab len %d is too big \n " , tab_len ) ;
2013-11-02 12:11:47 +04:00
return - EINVAL ;
}
2013-03-08 23:54:09 +04:00
for ( i = 0 , j = 0 ; i < tab_len ; i + + ) {
buf [ j ] = tab [ i ] . val ;
if ( i = = tab_len - 1 | | tab [ i ] . reg ! = tab [ i + 1 ] . reg - 1 ) {
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , tab [ i ] . reg - j , buf , j + 1 ) ;
2013-03-08 23:54:09 +04:00
if ( ret < 0 )
goto err ;
j = 0 ;
} else {
j + + ;
}
}
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2013-03-08 23:54:09 +04:00
return ret ;
}
2014-08-31 09:18:34 +04:00
static u32 af9033_div ( struct af9033_dev * dev , u32 a , u32 b , u32 x )
2012-03-30 15:21:25 +04:00
{
u32 r = 0 , c = 0 , i ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " a=%d b=%d x=%d \n " , a , b , x ) ;
2012-03-30 15:21:25 +04:00
if ( a > b ) {
c = a / b ;
a = a - c * b ;
}
for ( i = 0 ; i < x ; i + + ) {
if ( a > = b ) {
r + = 1 ;
a - = b ;
}
a < < = 1 ;
r < < = 1 ;
}
r = ( c < < ( u32 ) x ) + r ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " a=%d b=%d x=%d r=%d r=%x \n " , a , b , x , r , r ) ;
2012-03-30 15:21:25 +04:00
return r ;
}
static int af9033_init ( struct dvb_frontend * fe )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
int ret , i , len ;
const struct reg_val * init ;
u8 buf [ 4 ] ;
u32 adc_cw , clock_cw ;
struct reg_val_mask tab [ ] = {
{ 0x80fb24 , 0x00 , 0x08 } ,
{ 0x80004c , 0x00 , 0xff } ,
2014-08-31 09:18:34 +04:00
{ 0x00f641 , dev - > cfg . tuner , 0xff } ,
2012-03-30 15:21:25 +04:00
{ 0x80f5ca , 0x01 , 0x01 } ,
{ 0x80f715 , 0x01 , 0x01 } ,
{ 0x00f41f , 0x04 , 0x04 } ,
{ 0x00f41a , 0x01 , 0x01 } ,
{ 0x80f731 , 0x00 , 0x01 } ,
{ 0x00d91e , 0x00 , 0x01 } ,
{ 0x00d919 , 0x00 , 0x01 } ,
{ 0x80f732 , 0x00 , 0x01 } ,
{ 0x00d91f , 0x00 , 0x01 } ,
{ 0x00d91a , 0x00 , 0x01 } ,
{ 0x80f730 , 0x00 , 0x01 } ,
{ 0x80f778 , 0x00 , 0xff } ,
{ 0x80f73c , 0x01 , 0x01 } ,
{ 0x80f776 , 0x00 , 0x01 } ,
{ 0x00d8fd , 0x01 , 0xff } ,
{ 0x00d830 , 0x01 , 0xff } ,
{ 0x00d831 , 0x00 , 0xff } ,
{ 0x00d832 , 0x00 , 0xff } ,
2014-08-31 09:18:34 +04:00
{ 0x80f985 , dev - > ts_mode_serial , 0x01 } ,
{ 0x80f986 , dev - > ts_mode_parallel , 0x01 } ,
2012-03-30 15:21:25 +04:00
{ 0x00d827 , 0x00 , 0xff } ,
{ 0x00d829 , 0x00 , 0xff } ,
2014-08-31 09:18:34 +04:00
{ 0x800045 , dev - > cfg . adc_multiplier , 0xff } ,
2012-03-30 15:21:25 +04:00
} ;
/* program clock control */
2014-08-31 09:18:34 +04:00
clock_cw = af9033_div ( dev , dev - > cfg . clock , 1000000ul , 19ul ) ;
2012-03-30 15:21:25 +04:00
buf [ 0 ] = ( clock_cw > > 0 ) & 0xff ;
buf [ 1 ] = ( clock_cw > > 8 ) & 0xff ;
buf [ 2 ] = ( clock_cw > > 16 ) & 0xff ;
buf [ 3 ] = ( clock_cw > > 24 ) & 0xff ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " clock=%d clock_cw=%08x \n " ,
dev - > cfg . clock , clock_cw ) ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , 0x800025 , buf , 4 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
/* program ADC control */
for ( i = 0 ; i < ARRAY_SIZE ( clock_adc_lut ) ; i + + ) {
2014-08-31 09:18:34 +04:00
if ( clock_adc_lut [ i ] . clock = = dev - > cfg . clock )
2012-03-30 15:21:25 +04:00
break ;
}
2014-08-31 09:18:34 +04:00
adc_cw = af9033_div ( dev , clock_adc_lut [ i ] . adc , 1000000ul , 19ul ) ;
2012-03-30 15:21:25 +04:00
buf [ 0 ] = ( adc_cw > > 0 ) & 0xff ;
buf [ 1 ] = ( adc_cw > > 8 ) & 0xff ;
buf [ 2 ] = ( adc_cw > > 16 ) & 0xff ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " adc=%d adc_cw=%06x \n " ,
clock_adc_lut [ i ] . adc , adc_cw ) ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , 0x80f1cd , buf , 3 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
/* program register table */
for ( i = 0 ; i < ARRAY_SIZE ( tab ) ; i + + ) {
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , tab [ i ] . reg , tab [ i ] . val ,
2012-03-30 15:21:25 +04:00
tab [ i ] . mask ) ;
if ( ret < 0 )
goto err ;
}
2014-08-09 06:56:49 +04:00
/* clock output */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . dyn0_clk ) {
ret = af9033_wr_reg ( dev , 0x80fba8 , 0x00 ) ;
2014-08-09 08:03:14 +04:00
if ( ret < 0 )
goto err ;
}
2012-03-30 15:21:25 +04:00
/* settings for TS interface */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . ts_mode = = AF9033_TS_MODE_USB ) {
ret = af9033_wr_reg_mask ( dev , 0x80f9a5 , 0x00 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f9b5 , 0x01 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
} else {
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f990 , 0x00 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f9b5 , 0x00 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
}
/* load OFSM settings */
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " load ofsm settings \n " ) ;
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . tuner ) {
2013-02-03 20:39:55 +04:00
case AF9033_TUNER_IT9135_38 :
case AF9033_TUNER_IT9135_51 :
case AF9033_TUNER_IT9135_52 :
2013-03-07 07:03:06 +04:00
len = ARRAY_SIZE ( ofsm_init_it9135_v1 ) ;
init = ofsm_init_it9135_v1 ;
break ;
2013-02-03 20:39:55 +04:00
case AF9033_TUNER_IT9135_60 :
case AF9033_TUNER_IT9135_61 :
case AF9033_TUNER_IT9135_62 :
2013-03-07 07:03:06 +04:00
len = ARRAY_SIZE ( ofsm_init_it9135_v2 ) ;
init = ofsm_init_it9135_v2 ;
2013-02-03 20:39:55 +04:00
break ;
default :
len = ARRAY_SIZE ( ofsm_init ) ;
init = ofsm_init ;
break ;
}
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_val_tab ( dev , init , len ) ;
2013-03-08 23:54:09 +04:00
if ( ret < 0 )
goto err ;
2012-03-30 15:21:25 +04:00
/* load tuner specific settings */
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " load tuner specific settings \n " ) ;
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . tuner ) {
2012-03-30 15:21:25 +04:00
case AF9033_TUNER_TUA9001 :
len = ARRAY_SIZE ( tuner_init_tua9001 ) ;
init = tuner_init_tua9001 ;
break ;
2012-04-02 19:18:36 +04:00
case AF9033_TUNER_FC0011 :
len = ARRAY_SIZE ( tuner_init_fc0011 ) ;
init = tuner_init_fc0011 ;
break ;
2012-04-02 21:18:16 +04:00
case AF9033_TUNER_MXL5007T :
len = ARRAY_SIZE ( tuner_init_mxl5007t ) ;
init = tuner_init_mxl5007t ;
break ;
2012-04-03 00:25:14 +04:00
case AF9033_TUNER_TDA18218 :
len = ARRAY_SIZE ( tuner_init_tda18218 ) ;
init = tuner_init_tda18218 ;
break ;
2012-09-20 21:57:17 +04:00
case AF9033_TUNER_FC2580 :
len = ARRAY_SIZE ( tuner_init_fc2580 ) ;
init = tuner_init_fc2580 ;
break ;
2012-12-03 01:47:00 +04:00
case AF9033_TUNER_FC0012 :
len = ARRAY_SIZE ( tuner_init_fc0012 ) ;
init = tuner_init_fc0012 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_38 :
2013-03-08 04:17:55 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_38 ) ;
init = tuner_init_it9135_38 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_51 :
2013-03-08 04:25:16 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_51 ) ;
init = tuner_init_it9135_51 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_52 :
2013-03-08 04:29:05 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_52 ) ;
init = tuner_init_it9135_52 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_60 :
2013-03-08 04:38:00 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_60 ) ;
init = tuner_init_it9135_60 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_61 :
2013-03-08 04:44:30 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_61 ) ;
init = tuner_init_it9135_61 ;
break ;
2013-01-07 16:48:03 +04:00
case AF9033_TUNER_IT9135_62 :
2013-03-08 04:47:20 +04:00
len = ARRAY_SIZE ( tuner_init_it9135_62 ) ;
init = tuner_init_it9135_62 ;
2013-01-07 16:48:03 +04:00
break ;
2012-03-30 15:21:25 +04:00
default :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " unsupported tuner ID=%d \n " ,
dev - > cfg . tuner ) ;
2012-03-30 15:21:25 +04:00
ret = - ENODEV ;
goto err ;
}
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_val_tab ( dev , init , len ) ;
2013-03-08 23:54:09 +04:00
if ( ret < 0 )
goto err ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . ts_mode = = AF9033_TS_MODE_SERIAL ) {
ret = af9033_wr_reg_mask ( dev , 0x00d91c , 0x01 , 0x01 ) ;
2012-09-23 23:48:47 +04:00
if ( ret < 0 )
goto err ;
2012-12-09 05:51:19 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x00d917 , 0x00 , 0x01 ) ;
2012-09-23 23:48:47 +04:00
if ( ret < 0 )
goto err ;
2012-12-09 05:51:19 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x00d916 , 0x00 , 0x01 ) ;
2012-09-23 23:48:47 +04:00
if ( ret < 0 )
goto err ;
}
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . tuner ) {
2013-03-08 05:18:56 +04:00
case AF9033_TUNER_IT9135_60 :
case AF9033_TUNER_IT9135_61 :
case AF9033_TUNER_IT9135_62 :
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800000 , 0x01 ) ;
2013-03-08 05:18:56 +04:00
if ( ret < 0 )
goto err ;
}
2014-08-31 09:18:34 +04:00
dev - > bandwidth_hz = 0 ; /* force to program all parameters */
2014-09-02 10:55:21 +04:00
/* start statistics polling */
schedule_delayed_work ( & dev - > stat_work , msecs_to_jiffies ( 2000 ) ) ;
2012-03-30 15:21:25 +04:00
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
static int af9033_sleep ( struct dvb_frontend * fe )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
int ret , i ;
u8 tmp ;
2014-09-02 10:55:21 +04:00
/* stop statistics polling */
cancel_delayed_work_sync ( & dev - > stat_work ) ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x80004c , 1 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800000 , 0 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
for ( i = 100 , tmp = 1 ; i & & tmp ; i - - ) {
2014-08-31 09:18:34 +04:00
ret = af9033_rd_reg ( dev , 0x80004c , & tmp ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
usleep_range ( 200 , 10000 ) ;
}
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " loop=%d \n " , i ) ;
2012-03-30 15:21:25 +04:00
if ( i = = 0 ) {
ret = - ETIMEDOUT ;
goto err ;
}
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80fb24 , 0x08 , 0x08 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
/* prevent current leak (?) */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . ts_mode = = AF9033_TS_MODE_SERIAL ) {
2012-03-30 15:21:25 +04:00
/* enable parallel TS */
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x00d917 , 0x00 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x00d916 , 0x01 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
}
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
static int af9033_get_tune_settings ( struct dvb_frontend * fe ,
struct dvb_frontend_tune_settings * fesettings )
{
2013-02-03 20:39:55 +04:00
/* 800 => 2000 because IT9135 v2 is slow to gain lock */
fesettings - > min_delay_ms = 2000 ;
2012-03-30 15:21:25 +04:00
fesettings - > step_size = 0 ;
fesettings - > max_drift = 0 ;
return 0 ;
}
static int af9033_set_frontend ( struct dvb_frontend * fe )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2012-10-03 12:25:40 +04:00
int ret , i , spec_inv , sampling_freq ;
2012-03-30 15:21:25 +04:00
u8 tmp , buf [ 3 ] , bandwidth_reg_val ;
2012-04-02 21:18:16 +04:00
u32 if_frequency , freq_cw , adc_freq ;
2012-03-30 15:21:25 +04:00
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " frequency=%d bandwidth_hz=%d \n " ,
c - > frequency , c - > bandwidth_hz ) ;
2012-03-30 15:21:25 +04:00
/* check bandwidth */
switch ( c - > bandwidth_hz ) {
case 6000000 :
bandwidth_reg_val = 0x00 ;
break ;
case 7000000 :
bandwidth_reg_val = 0x01 ;
break ;
case 8000000 :
bandwidth_reg_val = 0x02 ;
break ;
default :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " invalid bandwidth_hz \n " ) ;
2012-03-30 15:21:25 +04:00
ret = - EINVAL ;
goto err ;
}
/* program tuner */
if ( fe - > ops . tuner_ops . set_params )
fe - > ops . tuner_ops . set_params ( fe ) ;
/* program CFOE coefficients */
2014-08-31 09:18:34 +04:00
if ( c - > bandwidth_hz ! = dev - > bandwidth_hz ) {
2012-03-30 15:21:25 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( coeff_lut ) ; i + + ) {
2014-08-31 09:18:34 +04:00
if ( coeff_lut [ i ] . clock = = dev - > cfg . clock & &
2012-03-30 15:21:25 +04:00
coeff_lut [ i ] . bandwidth_hz = = c - > bandwidth_hz ) {
break ;
}
}
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , 0x800001 ,
2012-03-30 15:21:25 +04:00
coeff_lut [ i ] . val , sizeof ( coeff_lut [ i ] . val ) ) ;
}
/* program frequency control */
2014-08-31 09:18:34 +04:00
if ( c - > bandwidth_hz ! = dev - > bandwidth_hz ) {
spec_inv = dev - > cfg . spec_inv ? - 1 : 1 ;
2012-04-02 21:18:16 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( clock_adc_lut ) ; i + + ) {
2014-08-31 09:18:34 +04:00
if ( clock_adc_lut [ i ] . clock = = dev - > cfg . clock )
2012-04-02 21:18:16 +04:00
break ;
}
adc_freq = clock_adc_lut [ i ] . adc ;
2012-03-30 15:21:25 +04:00
/* get used IF frequency */
if ( fe - > ops . tuner_ops . get_if_frequency )
fe - > ops . tuner_ops . get_if_frequency ( fe , & if_frequency ) ;
else
if_frequency = 0 ;
2012-10-03 12:25:40 +04:00
sampling_freq = if_frequency ;
2012-03-30 15:21:25 +04:00
2012-10-03 12:25:40 +04:00
while ( sampling_freq > ( adc_freq / 2 ) )
sampling_freq - = adc_freq ;
if ( sampling_freq > = 0 )
2012-04-02 21:18:16 +04:00
spec_inv * = - 1 ;
else
2012-10-03 12:25:40 +04:00
sampling_freq * = - 1 ;
2012-04-02 21:18:16 +04:00
2014-08-31 09:18:34 +04:00
freq_cw = af9033_div ( dev , sampling_freq , adc_freq , 23ul ) ;
2012-04-02 21:18:16 +04:00
if ( spec_inv = = - 1 )
2012-10-03 12:25:40 +04:00
freq_cw = 0x800000 - freq_cw ;
2012-04-02 21:18:16 +04:00
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . adc_multiplier = = AF9033_ADC_MULTIPLIER_2X )
2012-04-02 21:18:16 +04:00
freq_cw / = 2 ;
2012-03-30 15:21:25 +04:00
buf [ 0 ] = ( freq_cw > > 0 ) & 0xff ;
buf [ 1 ] = ( freq_cw > > 8 ) & 0xff ;
buf [ 2 ] = ( freq_cw > > 16 ) & 0x7f ;
2013-02-03 20:39:55 +04:00
/* FIXME: there seems to be calculation error here... */
if ( if_frequency = = 0 )
buf [ 2 ] = 0 ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , 0x800029 , buf , 3 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
dev - > bandwidth_hz = c - > bandwidth_hz ;
2012-03-30 15:21:25 +04:00
}
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f904 , bandwidth_reg_val , 0x03 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800040 , 0x00 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800047 , 0x00 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f999 , 0x00 , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
if ( c - > frequency < = 230000000 )
tmp = 0x00 ; /* VHF */
else
tmp = 0x01 ; /* UHF */
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x80004b , tmp ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800000 , 0x00 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
2012-04-05 19:47:19 +04:00
static int af9033_get_frontend ( struct dvb_frontend * fe )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-04-06 04:14:32 +04:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2012-04-05 19:47:19 +04:00
int ret ;
u8 buf [ 8 ] ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " \n " ) ;
2012-04-05 19:47:19 +04:00
/* read all needed registers */
2014-08-31 09:18:34 +04:00
ret = af9033_rd_regs ( dev , 0x80f900 , buf , sizeof ( buf ) ) ;
2012-04-06 04:14:32 +04:00
if ( ret < 0 )
goto err ;
2012-04-05 19:47:19 +04:00
switch ( ( buf [ 0 ] > > 0 ) & 3 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > transmission_mode = TRANSMISSION_MODE_2K ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > transmission_mode = TRANSMISSION_MODE_8K ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 1 ] > > 0 ) & 3 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > guard_interval = GUARD_INTERVAL_1_32 ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > guard_interval = GUARD_INTERVAL_1_16 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > guard_interval = GUARD_INTERVAL_1_8 ;
2012-04-05 19:47:19 +04:00
break ;
case 3 :
2012-04-06 04:14:32 +04:00
c - > guard_interval = GUARD_INTERVAL_1_4 ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 2 ] > > 0 ) & 7 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > hierarchy = HIERARCHY_NONE ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > hierarchy = HIERARCHY_1 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > hierarchy = HIERARCHY_2 ;
2012-04-05 19:47:19 +04:00
break ;
case 3 :
2012-04-06 04:14:32 +04:00
c - > hierarchy = HIERARCHY_4 ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 3 ] > > 0 ) & 3 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > modulation = QPSK ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > modulation = QAM_16 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > modulation = QAM_64 ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 4 ] > > 0 ) & 3 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > bandwidth_hz = 6000000 ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > bandwidth_hz = 7000000 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > bandwidth_hz = 8000000 ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 6 ] > > 0 ) & 7 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_1_2 ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_2_3 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_3_4 ;
2012-04-05 19:47:19 +04:00
break ;
case 3 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_5_6 ;
2012-04-05 19:47:19 +04:00
break ;
case 4 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_7_8 ;
2012-04-05 19:47:19 +04:00
break ;
case 5 :
2012-04-06 04:14:32 +04:00
c - > code_rate_HP = FEC_NONE ;
2012-04-05 19:47:19 +04:00
break ;
}
switch ( ( buf [ 7 ] > > 0 ) & 7 ) {
case 0 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_1_2 ;
2012-04-05 19:47:19 +04:00
break ;
case 1 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_2_3 ;
2012-04-05 19:47:19 +04:00
break ;
case 2 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_3_4 ;
2012-04-05 19:47:19 +04:00
break ;
case 3 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_5_6 ;
2012-04-05 19:47:19 +04:00
break ;
case 4 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_7_8 ;
2012-04-05 19:47:19 +04:00
break ;
case 5 :
2012-04-06 04:14:32 +04:00
c - > code_rate_LP = FEC_NONE ;
2012-04-05 19:47:19 +04:00
break ;
}
2012-04-06 04:14:32 +04:00
return 0 ;
2012-04-05 19:47:19 +04:00
2012-04-06 04:14:32 +04:00
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-04-05 19:47:19 +04:00
return ret ;
}
2012-03-30 15:21:25 +04:00
static int af9033_read_status ( struct dvb_frontend * fe , fe_status_t * status )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
int ret ;
u8 tmp ;
* status = 0 ;
/* radio channel status, 0=no result, 1=has signal, 2=no signal */
2014-08-31 09:18:34 +04:00
ret = af9033_rd_reg ( dev , 0x800047 , & tmp ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
/* has signal */
if ( tmp = = 0x01 )
* status | = FE_HAS_SIGNAL ;
if ( tmp ! = 0x02 ) {
/* TPS lock */
2014-08-31 09:18:34 +04:00
ret = af9033_rd_reg_mask ( dev , 0x80f5a9 , & tmp , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
if ( tmp )
* status | = FE_HAS_SIGNAL | FE_HAS_CARRIER |
FE_HAS_VITERBI ;
/* full lock */
2014-08-31 09:18:34 +04:00
ret = af9033_rd_reg_mask ( dev , 0x80f999 , & tmp , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
if ( tmp )
* status | = FE_HAS_SIGNAL | FE_HAS_CARRIER |
FE_HAS_VITERBI | FE_HAS_SYNC |
FE_HAS_LOCK ;
}
2014-09-02 10:55:21 +04:00
dev - > fe_status = * status ;
2012-03-30 15:21:25 +04:00
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
static int af9033_read_snr ( struct dvb_frontend * fe , u16 * snr )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2014-09-02 12:03:21 +04:00
struct dtv_frontend_properties * c = & dev - > fe . dtv_property_cache ;
2012-04-01 19:50:02 +04:00
2014-09-02 12:03:21 +04:00
/* use DVBv5 CNR */
if ( c - > cnr . stat [ 0 ] . scale = = FE_SCALE_DECIBEL )
* snr = div_s64 ( c - > cnr . stat [ 0 ] . svalue , 100 ) ; /* 1000x => 10x */
else
* snr = 0 ;
2012-03-30 15:21:25 +04:00
return 0 ;
}
static int af9033_read_signal_strength ( struct dvb_frontend * fe , u16 * strength )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
int ret ;
u8 strength2 ;
/* read signal strength of 0-100 scale */
2014-08-31 09:18:34 +04:00
ret = af9033_rd_reg ( dev , 0x800048 , & strength2 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
/* scale value to 0x0000-0xffff */
* strength = strength2 * 0xffff / 100 ;
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
2014-08-31 09:18:34 +04:00
static int af9033_update_ch_stat ( struct af9033_dev * dev )
2012-04-07 17:34:34 +04:00
{
int ret = 0 ;
u32 err_cnt , bit_cnt ;
u16 abort_cnt ;
u8 buf [ 7 ] ;
/* only update data every half second */
2014-08-31 09:18:34 +04:00
if ( time_after ( jiffies , dev - > last_stat_check + msecs_to_jiffies ( 500 ) ) ) {
ret = af9033_rd_regs ( dev , 0x800032 , buf , sizeof ( buf ) ) ;
2012-04-07 17:34:34 +04:00
if ( ret < 0 )
goto err ;
/* in 8 byte packets? */
abort_cnt = ( buf [ 1 ] < < 8 ) + buf [ 0 ] ;
/* in bits */
err_cnt = ( buf [ 4 ] < < 16 ) + ( buf [ 3 ] < < 8 ) + buf [ 2 ] ;
/* in 8 byte packets? always(?) 0x2710 = 10000 */
bit_cnt = ( buf [ 6 ] < < 8 ) + buf [ 5 ] ;
if ( bit_cnt < abort_cnt ) {
abort_cnt = 1000 ;
2014-08-31 09:18:34 +04:00
dev - > ber = 0xffffffff ;
2012-04-07 17:34:34 +04:00
} else {
2014-08-09 21:59:53 +04:00
/*
* 8 byte packets , that have not been rejected already
*/
2012-04-07 17:34:34 +04:00
bit_cnt - = ( u32 ) abort_cnt ;
if ( bit_cnt = = 0 ) {
2014-08-31 09:18:34 +04:00
dev - > ber = 0xffffffff ;
2012-04-07 17:34:34 +04:00
} else {
err_cnt - = ( u32 ) abort_cnt * 8 * 8 ;
bit_cnt * = 8 * 8 ;
2014-08-31 09:18:34 +04:00
dev - > ber = err_cnt * ( 0xffffffff / bit_cnt ) ;
2012-04-07 17:34:34 +04:00
}
}
2014-08-31 09:18:34 +04:00
dev - > ucb + = abort_cnt ;
dev - > last_stat_check = jiffies ;
2012-04-07 17:34:34 +04:00
}
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-09-13 03:23:42 +04:00
2012-04-07 17:34:34 +04:00
return ret ;
}
2012-03-30 15:21:25 +04:00
static int af9033_read_ber ( struct dvb_frontend * fe , u32 * ber )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-04-07 17:34:34 +04:00
int ret ;
2014-08-31 09:18:34 +04:00
ret = af9033_update_ch_stat ( dev ) ;
2012-04-07 17:34:34 +04:00
if ( ret < 0 )
return ret ;
2014-08-31 09:18:34 +04:00
* ber = dev - > ber ;
2012-03-30 15:21:25 +04:00
return 0 ;
}
static int af9033_read_ucblocks ( struct dvb_frontend * fe , u32 * ucblocks )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-04-07 17:34:34 +04:00
int ret ;
2014-08-31 09:18:34 +04:00
ret = af9033_update_ch_stat ( dev ) ;
2012-04-07 17:34:34 +04:00
if ( ret < 0 )
return ret ;
2014-08-31 09:18:34 +04:00
* ucblocks = dev - > ucb ;
2012-03-30 15:21:25 +04:00
return 0 ;
}
static int af9033_i2c_gate_ctrl ( struct dvb_frontend * fe , int enable )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2012-03-30 15:21:25 +04:00
int ret ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " enable=%d \n " , enable ) ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x00fa04 , enable , 0x01 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
goto err ;
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
2014-03-14 21:29:06 +04:00
static int af9033_pid_filter_ctrl ( struct dvb_frontend * fe , int onoff )
2014-02-13 22:40:59 +04:00
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2014-02-13 22:40:59 +04:00
int ret ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " onoff=%d \n " , onoff ) ;
2014-02-13 22:40:59 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg_mask ( dev , 0x80f993 , onoff , 0x01 ) ;
2014-02-13 22:40:59 +04:00
if ( ret < 0 )
goto err ;
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2014-02-13 22:40:59 +04:00
return ret ;
}
2014-08-09 21:59:53 +04:00
static int af9033_pid_filter ( struct dvb_frontend * fe , int index , u16 pid ,
int onoff )
2014-02-13 22:40:59 +04:00
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2014-02-13 22:40:59 +04:00
int ret ;
u8 wbuf [ 2 ] = { ( pid > > 0 ) & 0xff , ( pid > > 8 ) & 0xff } ;
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " index=%d pid=%04x onoff=%d \n " ,
index , pid , onoff ) ;
2014-02-13 22:40:59 +04:00
if ( pid > 0x1fff )
return 0 ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_regs ( dev , 0x80f996 , wbuf , 2 ) ;
2014-02-13 22:40:59 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x80f994 , onoff ) ;
2014-02-13 22:40:59 +04:00
if ( ret < 0 )
goto err ;
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x80f995 , index ) ;
2014-02-13 22:40:59 +04:00
if ( ret < 0 )
goto err ;
return 0 ;
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
2014-02-13 22:40:59 +04:00
return ret ;
}
2014-09-02 10:55:21 +04:00
static void af9033_stat_work ( struct work_struct * work )
{
struct af9033_dev * dev = container_of ( work , struct af9033_dev , stat_work . work ) ;
struct dtv_frontend_properties * c = & dev - > fe . dtv_property_cache ;
2014-09-02 11:24:41 +04:00
int ret , tmp , i , len ;
2014-09-02 15:01:10 +04:00
u8 u8tmp , buf [ 7 ] ;
2014-09-02 10:55:21 +04:00
dev_dbg ( & dev - > client - > dev , " \n " ) ;
2014-09-02 11:24:41 +04:00
/* signal strength */
2014-09-02 10:55:21 +04:00
if ( dev - > fe_status & FE_HAS_SIGNAL ) {
if ( dev - > is_af9035 ) {
ret = af9033_rd_reg ( dev , 0x80004a , & u8tmp ) ;
tmp = - u8tmp * 1000 ;
} else {
ret = af9033_rd_reg ( dev , 0x8000f7 , & u8tmp ) ;
tmp = ( u8tmp - 100 ) * 1000 ;
}
if ( ret )
goto err ;
c - > strength . len = 1 ;
c - > strength . stat [ 0 ] . scale = FE_SCALE_DECIBEL ;
c - > strength . stat [ 0 ] . svalue = tmp ;
} else {
c - > strength . len = 1 ;
c - > strength . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
}
2014-09-02 11:24:41 +04:00
/* CNR */
if ( dev - > fe_status & FE_HAS_VITERBI ) {
u32 snr_val ;
const struct val_snr * snr_lut ;
/* read value */
ret = af9033_rd_regs ( dev , 0x80002c , buf , 3 ) ;
if ( ret )
goto err ;
snr_val = ( buf [ 2 ] < < 16 ) | ( buf [ 1 ] < < 8 ) | ( buf [ 0 ] < < 0 ) ;
/* read current modulation */
ret = af9033_rd_reg ( dev , 0x80f903 , & u8tmp ) ;
if ( ret )
goto err ;
switch ( ( u8tmp > > 0 ) & 3 ) {
case 0 :
len = ARRAY_SIZE ( qpsk_snr_lut ) ;
snr_lut = qpsk_snr_lut ;
break ;
case 1 :
len = ARRAY_SIZE ( qam16_snr_lut ) ;
snr_lut = qam16_snr_lut ;
break ;
case 2 :
len = ARRAY_SIZE ( qam64_snr_lut ) ;
snr_lut = qam64_snr_lut ;
break ;
default :
goto err_schedule_delayed_work ;
}
for ( i = 0 ; i < len ; i + + ) {
tmp = snr_lut [ i ] . snr * 1000 ;
if ( snr_val < snr_lut [ i ] . val )
break ;
}
c - > cnr . len = 1 ;
c - > cnr . stat [ 0 ] . scale = FE_SCALE_DECIBEL ;
c - > cnr . stat [ 0 ] . svalue = tmp ;
} else {
c - > cnr . len = 1 ;
c - > cnr . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
}
2014-09-02 15:01:10 +04:00
/* UCB/PER/BER */
if ( dev - > fe_status & FE_HAS_LOCK ) {
/* outer FEC, 204 byte packets */
u16 abort_packet_count , rsd_packet_count ;
/*
* Packet count used for measurement is 10000
* ( rsd_packet_count ) . Maybe it should be increased ?
*/
ret = af9033_rd_regs ( dev , 0x800032 , buf , 7 ) ;
if ( ret )
goto err ;
abort_packet_count = ( buf [ 1 ] < < 8 ) | ( buf [ 0 ] < < 0 ) ;
rsd_packet_count = ( buf [ 6 ] < < 8 ) | ( buf [ 5 ] < < 0 ) ;
dev - > error_block_count + = abort_packet_count ;
dev - > total_block_count + = rsd_packet_count ;
c - > block_count . len = 1 ;
c - > block_count . stat [ 0 ] . scale = FE_SCALE_COUNTER ;
c - > block_count . stat [ 0 ] . uvalue = dev - > total_block_count ;
c - > block_error . len = 1 ;
c - > block_error . stat [ 0 ] . scale = FE_SCALE_COUNTER ;
c - > block_error . stat [ 0 ] . uvalue = dev - > error_block_count ;
}
2014-09-02 11:24:41 +04:00
err_schedule_delayed_work :
2014-09-02 10:55:21 +04:00
schedule_delayed_work ( & dev - > stat_work , msecs_to_jiffies ( 2000 ) ) ;
return ;
err :
dev_dbg ( & dev - > client - > dev , " failed=%d \n " , ret ) ;
}
2014-09-01 03:57:05 +04:00
static struct dvb_frontend_ops af9033_ops = {
. delsys = { SYS_DVBT } ,
. info = {
. name = " Afatech AF9033 (DVB-T) " ,
. frequency_min = 174000000 ,
. frequency_max = 862000000 ,
. frequency_stepsize = 250000 ,
. frequency_tolerance = 0 ,
. caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK |
FE_CAN_QAM_16 |
FE_CAN_QAM_64 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_RECOVER |
FE_CAN_MUTE_TS
} ,
. init = af9033_init ,
. sleep = af9033_sleep ,
. get_tune_settings = af9033_get_tune_settings ,
. set_frontend = af9033_set_frontend ,
. get_frontend = af9033_get_frontend ,
. read_status = af9033_read_status ,
. read_snr = af9033_read_snr ,
. read_signal_strength = af9033_read_signal_strength ,
. read_ber = af9033_read_ber ,
. read_ucblocks = af9033_read_ucblocks ,
. i2c_gate_ctrl = af9033_i2c_gate_ctrl ,
} ;
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
static int af9033_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
2012-03-30 15:21:25 +04:00
{
2014-09-01 03:57:05 +04:00
struct af9033_config * cfg = client - > dev . platform_data ;
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev ;
2014-09-01 03:57:05 +04:00
int ret ;
2012-03-30 15:21:25 +04:00
u8 buf [ 8 ] ;
2014-08-31 09:03:05 +04:00
u32 reg ;
2012-03-30 15:21:25 +04:00
/* allocate memory for the internal state */
2014-08-31 09:18:34 +04:00
dev = kzalloc ( sizeof ( struct af9033_dev ) , GFP_KERNEL ) ;
2014-09-01 03:57:05 +04:00
if ( dev = = NULL ) {
ret = - ENOMEM ;
dev_err ( & client - > dev , " Could not allocate memory for state \n " ) ;
2012-03-30 15:21:25 +04:00
goto err ;
2014-09-01 03:57:05 +04:00
}
2012-03-30 15:21:25 +04:00
/* setup the state */
2014-09-01 03:57:05 +04:00
dev - > client = client ;
2014-09-02 10:55:21 +04:00
INIT_DELAYED_WORK ( & dev - > stat_work , af9033_stat_work ) ;
2014-09-01 03:57:05 +04:00
memcpy ( & dev - > cfg , cfg , sizeof ( struct af9033_config ) ) ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . clock ! = 12000000 ) {
2014-09-01 03:57:05 +04:00
ret = - ENODEV ;
dev_err ( & dev - > client - > dev ,
2014-09-01 04:08:09 +04:00
" unsupported clock %d Hz, only 12000000 Hz is supported currently \n " ,
dev - > cfg . clock ) ;
2014-09-01 03:57:05 +04:00
goto err_kfree ;
2012-04-01 21:13:36 +04:00
}
2012-03-30 15:21:25 +04:00
/* firmware version */
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . tuner ) {
2014-08-31 09:03:05 +04:00
case AF9033_TUNER_IT9135_38 :
case AF9033_TUNER_IT9135_51 :
case AF9033_TUNER_IT9135_52 :
case AF9033_TUNER_IT9135_60 :
case AF9033_TUNER_IT9135_61 :
case AF9033_TUNER_IT9135_62 :
2014-09-02 10:55:21 +04:00
dev - > is_it9135 = true ;
2014-08-31 09:03:05 +04:00
reg = 0x004bfc ;
break ;
default :
2014-09-02 10:55:21 +04:00
dev - > is_af9035 = true ;
2014-08-31 09:03:05 +04:00
reg = 0x0083e9 ;
break ;
}
2014-08-31 09:18:34 +04:00
ret = af9033_rd_regs ( dev , reg , & buf [ 0 ] , 4 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
2014-09-01 03:57:05 +04:00
goto err_kfree ;
2012-03-30 15:21:25 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_rd_regs ( dev , 0x804191 , & buf [ 4 ] , 4 ) ;
2012-03-30 15:21:25 +04:00
if ( ret < 0 )
2014-09-01 03:57:05 +04:00
goto err_kfree ;
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
dev_info ( & dev - > client - > dev ,
2014-09-01 04:08:09 +04:00
" firmware version: LINK %d.%d.%d.%d - OFDM %d.%d.%d.%d \n " ,
buf [ 0 ] , buf [ 1 ] , buf [ 2 ] , buf [ 3 ] , buf [ 4 ] , buf [ 5 ] , buf [ 6 ] ,
buf [ 7 ] ) ;
2012-03-30 15:21:25 +04:00
2013-03-08 06:13:31 +04:00
/* sleep */
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . tuner ) {
2013-03-08 06:13:31 +04:00
case AF9033_TUNER_IT9135_38 :
case AF9033_TUNER_IT9135_51 :
case AF9033_TUNER_IT9135_52 :
case AF9033_TUNER_IT9135_60 :
case AF9033_TUNER_IT9135_61 :
case AF9033_TUNER_IT9135_62 :
/* IT9135 did not like to sleep at that early */
break ;
default :
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x80004c , 1 ) ;
2013-01-07 16:48:03 +04:00
if ( ret < 0 )
2014-09-01 03:57:05 +04:00
goto err_kfree ;
2013-01-07 16:48:03 +04:00
2014-08-31 09:18:34 +04:00
ret = af9033_wr_reg ( dev , 0x800000 , 0 ) ;
2013-01-07 16:48:03 +04:00
if ( ret < 0 )
2014-09-01 03:57:05 +04:00
goto err_kfree ;
2013-01-07 16:48:03 +04:00
}
2012-09-17 05:26:57 +04:00
2012-03-30 15:21:25 +04:00
/* configure internal TS mode */
2014-08-31 09:18:34 +04:00
switch ( dev - > cfg . ts_mode ) {
2012-03-30 15:21:25 +04:00
case AF9033_TS_MODE_PARALLEL :
2014-08-31 09:18:34 +04:00
dev - > ts_mode_parallel = true ;
2012-03-30 15:21:25 +04:00
break ;
case AF9033_TS_MODE_SERIAL :
2014-08-31 09:18:34 +04:00
dev - > ts_mode_serial = true ;
2012-03-30 15:21:25 +04:00
break ;
case AF9033_TS_MODE_USB :
/* usb mode for AF9035 */
default :
break ;
}
/* create dvb_frontend */
2014-08-31 09:18:34 +04:00
memcpy ( & dev - > fe . ops , & af9033_ops , sizeof ( struct dvb_frontend_ops ) ) ;
dev - > fe . demodulator_priv = dev ;
2014-09-01 03:57:05 +04:00
* cfg - > fe = & dev - > fe ;
if ( cfg - > ops ) {
cfg - > ops - > pid_filter = af9033_pid_filter ;
cfg - > ops - > pid_filter_ctrl = af9033_pid_filter_ctrl ;
2014-03-14 21:29:06 +04:00
}
2014-09-01 03:57:05 +04:00
i2c_set_clientdata ( client , dev ) ;
2014-03-14 21:29:06 +04:00
2014-09-01 03:57:05 +04:00
dev_info ( & dev - > client - > dev , " Afatech AF9033 successfully attached \n " ) ;
return 0 ;
err_kfree :
2014-08-31 09:18:34 +04:00
kfree ( dev ) ;
2014-09-01 03:57:05 +04:00
err :
2014-09-01 04:08:09 +04:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-09-01 03:57:05 +04:00
return ret ;
2012-03-30 15:21:25 +04:00
}
2014-09-01 03:57:05 +04:00
static int af9033_remove ( struct i2c_client * client )
{
struct af9033_dev * dev = i2c_get_clientdata ( client ) ;
2012-03-30 15:21:25 +04:00
2014-09-01 04:08:09 +04:00
dev_dbg ( & dev - > client - > dev , " \n " ) ;
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
dev - > fe . ops . release = NULL ;
dev - > fe . demodulator_priv = NULL ;
kfree ( dev ) ;
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
return 0 ;
}
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
static const struct i2c_device_id af9033_id_table [ ] = {
{ " af9033 " , 0 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , af9033_id_table ) ;
2012-03-30 15:21:25 +04:00
2014-09-01 03:57:05 +04:00
static struct i2c_driver af9033_driver = {
. driver = {
. owner = THIS_MODULE ,
. name = " af9033 " ,
} ,
. probe = af9033_probe ,
. remove = af9033_remove ,
. id_table = af9033_id_table ,
2012-03-30 15:21:25 +04:00
} ;
2014-09-01 03:57:05 +04:00
module_i2c_driver ( af9033_driver ) ;
2012-03-30 15:21:25 +04:00
MODULE_AUTHOR ( " Antti Palosaari <crope@iki.fi> " ) ;
MODULE_DESCRIPTION ( " Afatech AF9033 DVB-T demodulator driver " ) ;
MODULE_LICENSE ( " GPL " ) ;