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 .
*/
# include "af9033_priv.h"
2014-08-31 09:18:34 +04:00
struct af9033_dev {
2014-09-01 03:57:05 +04:00
struct i2c_client * client ;
2016-11-06 07:20:29 +03:00
struct regmap * regmap ;
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
2015-06-07 20:53:52 +03:00
enum fe_status fe_status ;
2014-09-04 06:22:53 +04:00
u64 post_bit_error_prev ; /* for old read_ber we return (curr - prev) */
2014-09-02 15:29:46 +04:00
u64 post_bit_error ;
u64 post_bit_count ;
2014-09-02 15:01:10 +04:00
u64 error_block_count ;
u64 total_block_count ;
2012-03-30 15:21:25 +04:00
} ;
2016-11-06 23:55:36 +03: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 ,
2016-11-06 23:55:36 +03:00
const struct reg_val * tab , int tab_len )
2013-03-08 23:54:09 +04:00
{
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
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 ] ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " tab_len=%d \n " , tab_len ) ;
2013-11-02 12:11:47 +04:00
if ( tab_len > sizeof ( buf ) ) {
2016-11-06 23:55:36 +03:00
dev_warn ( & 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 ) {
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , tab [ i ] . reg - j ,
buf , j + 1 ) ;
if ( ret )
2013-03-08 23:54:09 +04:00
goto err ;
j = 0 ;
} else {
j + + ;
}
}
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2013-03-08 23:54:09 +04:00
return ret ;
}
2012-03-30 15:21:25 +04:00
static int af9033_init ( struct dvb_frontend * fe )
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2014-09-06 18:24:14 +04:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2012-03-30 15:21:25 +04:00
int ret , i , len ;
2016-11-06 20:27:16 +03:00
unsigned int utmp ;
2012-03-30 15:21:25 +04:00
const struct reg_val * init ;
u8 buf [ 4 ] ;
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
} ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
/* Main clk control */
2016-11-06 20:27:16 +03:00
utmp = div_u64 ( ( u64 ) dev - > cfg . clock * 0x80000 , 1000000 ) ;
buf [ 0 ] = ( utmp > > 0 ) & 0xff ;
buf [ 1 ] = ( utmp > > 8 ) & 0xff ;
buf [ 2 ] = ( utmp > > 16 ) & 0xff ;
buf [ 3 ] = ( utmp > > 24 ) & 0xff ;
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , 0x800025 , buf , 4 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " clk=%u clk_cw=%08x \n " , dev - > cfg . clock , utmp ) ;
2016-11-06 20:27:16 +03:00
2016-11-06 23:55:36 +03:00
/* ADC clk control */
2012-03-30 15:21:25 +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-03-30 15:21:25 +04:00
break ;
}
2014-11-04 23:35:07 +03:00
if ( i = = ARRAY_SIZE ( clock_adc_lut ) ) {
2016-11-06 23:55:36 +03:00
dev_err ( & client - > dev , " Couldn't find ADC config for clock %d \n " ,
2014-11-04 23:35:07 +03:00
dev - > cfg . clock ) ;
goto err ;
}
2012-03-30 15:21:25 +04:00
2016-11-06 20:27:16 +03:00
utmp = div_u64 ( ( u64 ) clock_adc_lut [ i ] . adc * 0x80000 , 1000000 ) ;
buf [ 0 ] = ( utmp > > 0 ) & 0xff ;
buf [ 1 ] = ( utmp > > 8 ) & 0xff ;
buf [ 2 ] = ( utmp > > 16 ) & 0xff ;
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , 0x80f1cd , buf , 3 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " adc=%u adc_cw=%06x \n " ,
2016-11-06 20:27:16 +03:00
clock_adc_lut [ i ] . adc , utmp ) ;
2016-11-06 23:55:36 +03:00
/* Config register table */
2012-03-30 15:21:25 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( tab ) ; i + + ) {
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , tab [ i ] . reg , tab [ i ] . mask ,
tab [ i ] . val ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
}
2016-11-06 23:55:36 +03:00
/* Demod clk output */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . dyn0_clk ) {
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80fba8 , 0x00 ) ;
if ( ret )
2014-08-09 08:03:14 +04:00
goto err ;
}
2016-11-06 23:55:36 +03:00
/* TS interface */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . ts_mode = = AF9033_TS_MODE_USB ) {
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f9a5 , 0x01 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f9b5 , 0x01 , 0x01 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
} else {
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f990 , 0x01 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f9b5 , 0x01 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
}
2016-11-06 23:55:36 +03:00
/* Demod core settings */
dev_dbg ( & 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 ) ;
2016-11-06 07:20:29 +03:00
if ( ret )
2013-03-08 23:54:09 +04:00
goto err ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
/* Demod tuner specific settings */
dev_dbg ( & 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 :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ) ;
2016-11-06 07:20:29 +03:00
if ( ret )
2013-03-08 23:54:09 +04:00
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 ) {
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00d91c , 0x01 , 0x01 ) ;
if ( ret )
2012-09-23 23:48:47 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00d917 , 0x01 , 0x00 ) ;
if ( ret )
2012-09-23 23:48:47 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00d916 , 0x01 , 0x00 ) ;
if ( ret )
2012-09-23 23:48:47 +04:00
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 :
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x800000 , 0x01 ) ;
if ( ret )
2013-03-08 05:18:56 +04:00
goto err ;
}
2016-11-06 23:55:36 +03:00
dev - > bandwidth_hz = 0 ; /* Force to program all parameters */
/* Init stats here in order signal app which stats are supported */
2014-09-06 18:24:14 +04:00
c - > strength . len = 1 ;
c - > strength . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
c - > cnr . len = 1 ;
c - > cnr . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
c - > block_count . len = 1 ;
c - > block_count . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
c - > block_error . len = 1 ;
c - > block_error . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
c - > post_bit_count . len = 1 ;
c - > post_bit_count . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
c - > post_bit_error . len = 1 ;
c - > post_bit_error . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
2012-03-30 15:21:25 +04:00
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2016-11-06 07:20:29 +03:00
int ret ;
unsigned int utmp ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80004c , 0x01 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x800000 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_read_poll_timeout ( dev - > regmap , 0x80004c , utmp , utmp = = 0 ,
5000 , 1000000 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80fb24 , 0x08 , 0x08 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
/* Prevent current leak by setting TS interface to parallel mode */
2014-08-31 09:18:34 +04:00
if ( dev - > cfg . ts_mode = = AF9033_TS_MODE_SERIAL ) {
2016-11-06 23:55:36 +03:00
/* Enable parallel TS */
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00d917 , 0x01 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00d916 , 0x01 , 0x01 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
}
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ,
2016-11-06 23:55:36 +03:00
struct dvb_frontend_tune_settings * fesettings )
2012-03-30 15:21:25 +04:00
{
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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2012-03-30 15:21:25 +04:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2016-11-06 20:27:16 +03:00
int ret , i ;
unsigned int utmp , adc_freq ;
2012-03-30 15:21:25 +04:00
u8 tmp , buf [ 3 ] , bandwidth_reg_val ;
2016-11-06 20:27:16 +03:00
u32 if_frequency ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " frequency=%u bandwidth_hz=%u \n " ,
c - > frequency , c - > bandwidth_hz ) ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
/* Check bandwidth */
2012-03-30 15:21:25 +04:00
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 :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " invalid bandwidth_hz \n " ) ;
2012-03-30 15:21:25 +04:00
ret = - EINVAL ;
goto err ;
}
2016-11-06 23:55:36 +03:00
/* Program tuner */
2012-03-30 15:21:25 +04:00
if ( fe - > ops . tuner_ops . set_params )
fe - > ops . tuner_ops . set_params ( fe ) ;
2016-11-06 23:55:36 +03:00
/* 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 & &
2016-11-06 23:55:36 +03:00
coeff_lut [ i ] . bandwidth_hz = = c - > bandwidth_hz ) {
2012-03-30 15:21:25 +04:00
break ;
}
}
2014-11-04 23:35:07 +03:00
if ( i = = ARRAY_SIZE ( coeff_lut ) ) {
2016-11-06 23:55:36 +03:00
dev_err ( & client - > dev ,
" Couldn't find config for clock %u \n " ,
2014-11-04 23:35:07 +03:00
dev - > cfg . clock ) ;
ret = - EINVAL ;
goto err ;
}
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , 0x800001 , coeff_lut [ i ] . val ,
sizeof ( coeff_lut [ i ] . val ) ) ;
if ( ret )
goto err ;
2012-03-30 15:21:25 +04:00
}
2016-11-06 23:55:36 +03:00
/* IF frequency control */
2014-08-31 09:18:34 +04:00
if ( c - > bandwidth_hz ! = dev - > bandwidth_hz ) {
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 ;
}
2014-11-04 23:35:07 +03:00
if ( i = = ARRAY_SIZE ( clock_adc_lut ) ) {
2016-11-06 23:55:36 +03:00
dev_err ( & client - > dev ,
" Couldn't find ADC clock for clock %u \n " ,
2014-11-04 23:35:07 +03:00
dev - > cfg . clock ) ;
ret = - EINVAL ;
goto err ;
}
2012-04-02 21:18:16 +04:00
adc_freq = clock_adc_lut [ i ] . adc ;
2016-11-06 20:27:16 +03:00
if ( dev - > cfg . adc_multiplier = = AF9033_ADC_MULTIPLIER_2X )
adc_freq = 2 * adc_freq ;
2016-11-06 23:55:36 +03:00
/* Get used IF frequency */
2012-03-30 15:21:25 +04:00
if ( fe - > ops . tuner_ops . get_if_frequency )
fe - > ops . tuner_ops . get_if_frequency ( fe , & if_frequency ) ;
else
if_frequency = 0 ;
2016-11-06 20:27:16 +03:00
utmp = DIV_ROUND_CLOSEST_ULL ( ( u64 ) if_frequency * 0x800000 ,
adc_freq ) ;
2012-03-30 15:21:25 +04:00
2016-11-06 20:27:16 +03:00
if ( ! dev - > cfg . spec_inv & & if_frequency )
utmp = 0x800000 - utmp ;
2013-02-03 20:39:55 +04:00
2016-11-06 20:27:16 +03:00
buf [ 0 ] = ( utmp > > 0 ) & 0xff ;
buf [ 1 ] = ( utmp > > 8 ) & 0xff ;
buf [ 2 ] = ( utmp > > 16 ) & 0xff ;
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , 0x800029 , buf , 3 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " if_frequency_cw=%06x \n " , utmp ) ;
2016-11-06 20:27:16 +03:00
2014-08-31 09:18:34 +04:00
dev - > bandwidth_hz = c - > bandwidth_hz ;
2012-03-30 15:21:25 +04:00
}
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f904 , 0x03 ,
bandwidth_reg_val ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x800040 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x800047 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f999 , 0x01 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
if ( c - > frequency < = 230000000 )
tmp = 0x00 ; /* VHF */
else
tmp = 0x01 ; /* UHF */
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80004b , tmp ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
/* Reset FSM */
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x800000 , 0x00 ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
2016-02-04 17:58:30 +03:00
static int af9033_get_frontend ( struct dvb_frontend * fe ,
struct dtv_frontend_properties * c )
2012-04-05 19:47:19 +04:00
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2012-04-05 19:47:19 +04:00
int ret ;
u8 buf [ 8 ] ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-04-05 19:47:19 +04:00
2016-11-06 23:55:36 +03:00
/* Read all needed TPS registers */
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_read ( dev - > regmap , 0x80f900 , buf , 8 ) ;
if ( ret )
2012-04-06 04:14:32 +04:00
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 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-04-05 19:47:19 +04:00
return ret ;
}
2015-06-07 20:53:52 +03:00
static int af9033_read_status ( struct dvb_frontend * fe , enum fe_status * status )
2012-03-30 15:21:25 +04:00
{
2014-08-31 09:18:34 +04:00
struct af9033_dev * dev = fe - > demodulator_priv ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2016-06-30 02:40:21 +03:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2016-12-19 06:42:37 +03:00
int ret , tmp = 0 ;
2016-11-06 07:20:29 +03:00
u8 buf [ 7 ] ;
2016-12-19 06:42:37 +03:00
unsigned int utmp , utmp1 ;
2016-06-30 02:40:21 +03:00
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-03-30 15:21:25 +04:00
* status = 0 ;
2016-11-06 23:55:36 +03:00
/* Radio channel status: 0=no result, 1=has signal, 2=no signal */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x800047 , & utmp ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 23:55:36 +03:00
/* Has signal */
2016-11-06 07:20:29 +03:00
if ( utmp = = 0x01 )
2012-03-30 15:21:25 +04:00
* status | = FE_HAS_SIGNAL ;
2016-11-06 07:20:29 +03:00
if ( utmp ! = 0x02 ) {
2012-03-30 15:21:25 +04:00
/* TPS lock */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f5a9 , & utmp ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
if ( ( utmp > > 0 ) & 0x01 )
2012-03-30 15:21:25 +04:00
* status | = FE_HAS_SIGNAL | FE_HAS_CARRIER |
FE_HAS_VITERBI ;
2016-11-06 23:55:36 +03:00
/* Full lock */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f999 , & utmp ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
if ( ( utmp > > 0 ) & 0x01 )
2012-03-30 15:21:25 +04:00
* 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 ;
2016-11-06 23:55:36 +03:00
/* Signal strength */
2016-06-30 02:40:21 +03:00
if ( dev - > fe_status & FE_HAS_SIGNAL ) {
if ( dev - > is_af9035 ) {
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80004a , & utmp ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-11-06 07:20:29 +03:00
tmp = - utmp * 1000 ;
2016-06-30 02:40:21 +03:00
} else {
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x8000f7 , & utmp ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-11-06 07:20:29 +03:00
tmp = ( utmp - 100 ) * 1000 ;
2016-06-30 02:40:21 +03:00
}
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 ;
}
/* CNR */
if ( dev - > fe_status & FE_HAS_VITERBI ) {
2016-11-06 23:55:36 +03:00
/* Read raw SNR value */
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_read ( dev - > regmap , 0x80002c , buf , 3 ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-12-19 06:42:37 +03:00
utmp1 = buf [ 2 ] < < 16 | buf [ 1 ] < < 8 | buf [ 0 ] < < 0 ;
2016-06-30 02:40:21 +03:00
2016-11-06 23:55:36 +03:00
/* Read superframe number */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f78b , & utmp ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-11-06 07:20:29 +03:00
if ( utmp )
2016-12-19 06:42:37 +03:00
utmp1 / = utmp ;
2016-06-30 02:40:21 +03:00
2016-11-06 23:55:36 +03:00
/* Read current transmission mode */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f900 , & utmp ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-11-06 07:20:29 +03:00
switch ( ( utmp > > 0 ) & 3 ) {
2016-06-30 02:40:21 +03:00
case 0 :
2016-12-19 06:42:37 +03:00
/* 2k */
utmp1 * = 4 ;
2016-06-30 02:40:21 +03:00
break ;
case 1 :
2016-12-19 06:42:37 +03:00
/* 8k */
utmp1 * = 1 ;
2016-06-30 02:40:21 +03:00
break ;
case 2 :
2016-12-19 06:42:37 +03:00
/* 4k */
utmp1 * = 2 ;
2016-06-30 02:40:21 +03:00
break ;
default :
2016-12-19 06:42:37 +03:00
utmp1 * = 0 ;
2016-06-30 02:40:21 +03:00
break ;
}
2016-11-06 23:55:36 +03:00
/* Read current modulation */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f903 , & utmp ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
2016-11-06 07:20:29 +03:00
switch ( ( utmp > > 0 ) & 3 ) {
2016-06-30 02:40:21 +03:00
case 0 :
2016-12-19 06:42:37 +03:00
/*
* QPSK
* CNR [ dB ] 13 * - log10 ( ( 1690000 - value ) / value ) + 2.6
* value [ 653799 , 1689999 ] , 2.6 / 13 = 3355443
*/
utmp1 = clamp ( utmp1 , 653799U , 1689999U ) ;
utmp1 = ( ( u64 ) ( intlog10 ( utmp1 )
- intlog10 ( 1690000 - utmp1 )
+ 3355443 ) * 13 * 1000 ) > > 24 ;
2016-06-30 02:40:21 +03:00
break ;
case 1 :
2016-12-19 06:42:37 +03:00
/*
* QAM - 16
* CNR [ dB ] 6 * log10 ( ( value - 370000 ) / ( 828000 - value ) ) + 15.7
* value [ 371105 , 827999 ] , 15.7 / 6 = 43900382
*/
utmp1 = clamp ( utmp1 , 371105U , 827999U ) ;
utmp1 = ( ( u64 ) ( intlog10 ( utmp1 - 370000 )
- intlog10 ( 828000 - utmp1 )
+ 43900382 ) * 6 * 1000 ) > > 24 ;
2016-06-30 02:40:21 +03:00
break ;
case 2 :
2016-12-19 06:42:37 +03:00
/*
* QAM - 64
* CNR [ dB ] 8 * log10 ( ( value - 193000 ) / ( 425000 - value ) ) + 23.8
* value [ 193246 , 424999 ] , 23.8 / 8 = 49912218
*/
utmp1 = clamp ( utmp1 , 193246U , 424999U ) ;
utmp1 = ( ( u64 ) ( intlog10 ( utmp1 - 193000 )
- intlog10 ( 425000 - utmp1 )
+ 49912218 ) * 8 * 1000 ) > > 24 ;
2016-06-30 02:40:21 +03:00
break ;
default :
2016-12-19 06:42:37 +03:00
utmp1 = 0 ;
2016-06-30 02:40:21 +03:00
break ;
}
2016-12-19 06:42:37 +03:00
dev_dbg ( & client - > dev , " cnr=%u \n " , utmp1 ) ;
2016-06-30 02:40:21 +03:00
c - > cnr . stat [ 0 ] . scale = FE_SCALE_DECIBEL ;
2016-12-19 06:42:37 +03:00
c - > cnr . stat [ 0 ] . svalue = utmp1 ;
2016-06-30 02:40:21 +03:00
} else {
c - > cnr . stat [ 0 ] . scale = FE_SCALE_NOT_AVAILABLE ;
}
/* UCB/PER/BER */
if ( dev - > fe_status & FE_HAS_LOCK ) {
2016-11-06 23:55:36 +03:00
/* Outer FEC, 204 byte packets */
2016-06-30 02:40:21 +03:00
u16 abort_packet_count , rsd_packet_count ;
2016-11-06 23:55:36 +03:00
/* Inner FEC, bits */
2016-06-30 02:40:21 +03:00
u32 rsd_bit_err_count ;
/*
* Packet count used for measurement is 10000
* ( rsd_packet_count ) . Maybe it should be increased ?
*/
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_read ( dev - > regmap , 0x800032 , buf , 7 ) ;
2016-06-30 02:40:21 +03:00
if ( ret )
goto err ;
abort_packet_count = ( buf [ 1 ] < < 8 ) | ( buf [ 0 ] < < 0 ) ;
rsd_bit_err_count = ( buf [ 4 ] < < 16 ) | ( buf [ 3 ] < < 8 ) | buf [ 2 ] ;
rsd_packet_count = ( buf [ 6 ] < < 8 ) | ( buf [ 5 ] < < 0 ) ;
dev - > error_block_count + = abort_packet_count ;
dev - > total_block_count + = rsd_packet_count ;
dev - > post_bit_error + = rsd_bit_err_count ;
dev - > post_bit_count + = rsd_packet_count * 204 * 8 ;
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 ;
c - > post_bit_count . len = 1 ;
c - > post_bit_count . stat [ 0 ] . scale = FE_SCALE_COUNTER ;
c - > post_bit_count . stat [ 0 ] . uvalue = dev - > post_bit_count ;
c - > post_bit_error . len = 1 ;
c - > post_bit_error . stat [ 0 ] . scale = FE_SCALE_COUNTER ;
c - > post_bit_error . stat [ 0 ] . uvalue = dev - > post_bit_error ;
}
2012-03-30 15:21:25 +04:00
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2014-09-02 12:03:21 +04:00
struct dtv_frontend_properties * c = & dev - > fe . dtv_property_cache ;
2014-10-02 06:37:13 +04:00
int ret ;
2016-11-06 07:20:29 +03:00
unsigned int utmp ;
2012-04-01 19:50:02 +04:00
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
/* Use DVBv5 CNR */
2014-10-02 06:37:13 +04:00
if ( c - > cnr . stat [ 0 ] . scale = = FE_SCALE_DECIBEL ) {
2014-11-04 03:53:05 +03:00
/* Return 0.1 dB for AF9030 and 0-0xffff for IT9130. */
if ( dev - > is_af9035 ) {
/* 1000x => 10x (0.1 dB) */
* snr = div_s64 ( c - > cnr . stat [ 0 ] . svalue , 100 ) ;
} else {
/* 1000x => 1x (1 dB) */
* snr = div_s64 ( c - > cnr . stat [ 0 ] . svalue , 1000 ) ;
2014-10-02 06:37:13 +04:00
2016-11-06 23:55:36 +03:00
/* Read current modulation */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x80f903 , & utmp ) ;
2014-11-04 03:53:05 +03:00
if ( ret )
goto err ;
2014-10-02 06:37:13 +04:00
2014-11-04 03:53:05 +03:00
/* scale value to 0x0000-0xffff */
2016-11-06 07:20:29 +03:00
switch ( ( utmp > > 0 ) & 3 ) {
2014-11-04 03:53:05 +03:00
case 0 :
* snr = * snr * 0xffff / 23 ;
break ;
case 1 :
* snr = * snr * 0xffff / 26 ;
break ;
case 2 :
* snr = * snr * 0xffff / 32 ;
break ;
default :
goto err ;
}
2014-10-02 06:37:13 +04:00
}
} else {
2014-09-02 12:03:21 +04:00
* snr = 0 ;
2014-10-02 06:37:13 +04:00
}
2012-03-30 15:21:25 +04:00
return 0 ;
2014-10-02 06:37:13 +04:00
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-10-02 06:37:13 +04:00
return ret ;
2012-03-30 15:21:25 +04:00
}
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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2014-10-01 14:28:54 +04:00
struct dtv_frontend_properties * c = & dev - > fe . dtv_property_cache ;
int ret , tmp , power_real ;
2016-11-06 07:20:29 +03:00
unsigned int utmp ;
u8 gain_offset , buf [ 7 ] ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
2014-10-01 14:28:54 +04:00
if ( dev - > is_af9035 ) {
2016-11-06 23:55:36 +03:00
/* Read signal strength of 0-100 scale */
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x800048 , & utmp ) ;
if ( ret )
2014-11-04 02:24:13 +03:00
goto err ;
2016-11-06 23:55:36 +03:00
/* Scale value to 0x0000-0xffff */
2016-11-06 07:20:29 +03:00
* strength = utmp * 0xffff / 100 ;
2014-10-01 14:28:54 +04:00
} else {
2016-11-06 07:20:29 +03:00
ret = regmap_read ( dev - > regmap , 0x8000f7 , & utmp ) ;
if ( ret )
2014-11-04 03:23:26 +03:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_read ( dev - > regmap , 0x80f900 , buf , 7 ) ;
if ( ret )
2014-11-04 03:23:26 +03:00
goto err ;
2014-10-01 14:28:54 +04:00
if ( c - > frequency < = 300000000 )
gain_offset = 7 ; /* VHF */
else
gain_offset = 4 ; /* UHF */
2016-11-06 07:20:29 +03:00
power_real = ( utmp - 100 - gain_offset ) -
2014-10-01 14:28:54 +04:00
power_reference [ ( ( buf [ 3 ] > > 0 ) & 3 ) ] [ ( ( buf [ 6 ] > > 0 ) & 7 ) ] ;
if ( power_real < - 15 )
tmp = 0 ;
else if ( ( power_real > = - 15 ) & & ( power_real < 0 ) )
tmp = ( 2 * ( power_real + 15 ) ) / 3 ;
else if ( ( power_real > = 0 ) & & ( power_real < 20 ) )
tmp = 4 * power_real + 10 ;
else if ( ( power_real > = 20 ) & & ( power_real < 35 ) )
tmp = ( 2 * ( power_real - 20 ) ) / 3 + 90 ;
else
tmp = 100 ;
2016-11-06 23:55:36 +03:00
/* Scale value to 0x0000-0xffff */
2014-10-01 14:28:54 +04:00
* strength = tmp * 0xffff / 100 ;
}
2012-03-30 15:21:25 +04:00
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 15:21:25 +04:00
return ret ;
}
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
2014-09-04 06:22:53 +04:00
* ber = ( dev - > post_bit_error - dev - > post_bit_error_prev ) ;
dev - > post_bit_error_prev = dev - > post_bit_error ;
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-03-30 15:21:25 +04:00
2014-09-04 06:07:39 +04:00
* ucblocks = dev - > error_block_count ;
2016-11-06 23:55:36 +03:00
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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2012-03-30 15:21:25 +04:00
int ret ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " enable=%d \n " , enable ) ;
2012-03-30 15:21:25 +04:00
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x00fa04 , 0x01 , enable ) ;
if ( ret )
2012-03-30 15:21:25 +04:00
goto err ;
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2014-02-13 22:40:59 +04:00
int ret ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " onoff=%d \n " , onoff ) ;
2014-02-13 22:40:59 +04:00
2016-11-06 07:20:29 +03:00
ret = regmap_update_bits ( dev - > regmap , 0x80f993 , 0x01 , onoff ) ;
if ( ret )
2014-02-13 22:40:59 +04:00
goto err ;
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ,
2016-11-06 23:55:36 +03:00
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 ;
2016-11-06 23:55:36 +03:00
struct i2c_client * client = dev - > client ;
2014-02-13 22:40:59 +04:00
int ret ;
u8 wbuf [ 2 ] = { ( pid > > 0 ) & 0xff , ( pid > > 8 ) & 0xff } ;
2016-11-06 23:55:36 +03:00
dev_dbg ( & 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 ;
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_write ( dev - > regmap , 0x80f996 , wbuf , 2 ) ;
if ( ret )
2014-02-13 22:40:59 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80f994 , onoff ) ;
if ( ret )
2014-02-13 22:40:59 +04:00
goto err ;
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80f995 , index ) ;
if ( ret )
2014-02-13 22:40:59 +04:00
goto err ;
return 0 ;
err :
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-02-13 22:40:59 +04:00
return ret ;
}
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops af9033_ops = {
2016-11-06 23:55:36 +03:00
. delsys = { SYS_DVBT } ,
2014-09-01 03:57:05 +04:00
. 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 ,
2016-11-06 23:55:36 +03:00
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 ;
2016-11-06 07:20:29 +03:00
static const struct regmap_config regmap_config = {
. reg_bits = 24 ,
. val_bits = 8 ,
} ;
2016-11-06 23:55:36 +03:00
/* Allocate memory for the internal state */
dev = kzalloc ( sizeof ( * dev ) , GFP_KERNEL ) ;
if ( ! dev ) {
2014-09-01 03:57:05 +04:00
ret = - ENOMEM ;
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
2016-11-06 23:55:36 +03:00
/* Setup the state */
2014-09-01 03:57:05 +04:00
dev - > client = client ;
2016-11-06 23:55:36 +03:00
memcpy ( & dev - > cfg , cfg , sizeof ( dev - > cfg ) ) ;
switch ( dev - > cfg . ts_mode ) {
case AF9033_TS_MODE_PARALLEL :
dev - > ts_mode_parallel = true ;
break ;
case AF9033_TS_MODE_SERIAL :
dev - > ts_mode_serial = true ;
break ;
case AF9033_TS_MODE_USB :
/* USB mode for AF9035 */
default :
break ;
}
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 ;
2016-11-06 23:55:36 +03:00
dev_err ( & client - > dev ,
" Unsupported clock %u 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
}
2016-11-06 07:20:29 +03:00
/* Create regmap */
dev - > regmap = regmap_init_i2c ( client , & regmap_config ) ;
if ( IS_ERR ( dev - > regmap ) ) {
ret = PTR_ERR ( dev - > regmap ) ;
goto err_kfree ;
}
2016-11-06 23:55:36 +03: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 ;
}
2016-11-06 07:20:29 +03:00
ret = regmap_bulk_read ( dev - > regmap , reg , & buf [ 0 ] , 4 ) ;
if ( ret )
goto err_regmap_exit ;
ret = regmap_bulk_read ( dev - > regmap , 0x804191 , & buf [ 4 ] , 4 ) ;
if ( ret )
goto err_regmap_exit ;
2012-03-30 15:21:25 +04:00
2016-11-06 23:55:36 +03:00
dev_info ( & client - > dev ,
" 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
2016-11-06 23:55:36 +03:00
/* Sleep as chip seems to be partly active by default */
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 :
2016-11-06 07:20:29 +03:00
ret = regmap_write ( dev - > regmap , 0x80004c , 0x01 ) ;
if ( ret )
goto err_regmap_exit ;
ret = regmap_write ( dev - > regmap , 0x800000 , 0x00 ) ;
if ( ret )
goto err_regmap_exit ;
2013-01-07 16:48:03 +04:00
}
2012-09-17 05:26:57 +04:00
2016-11-06 23:55:36 +03:00
/* Create dvb frontend */
memcpy ( & dev - > fe . ops , & af9033_ops , sizeof ( dev - > fe . ops ) ) ;
2014-08-31 09:18:34 +04:00
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
}
2016-11-07 03:14:18 +03:00
cfg - > regmap = dev - > regmap ;
2014-09-01 03:57:05 +04:00
i2c_set_clientdata ( client , dev ) ;
2014-03-14 21:29:06 +04:00
2016-11-06 23:55:36 +03:00
dev_info ( & client - > dev , " Afatech AF9033 successfully attached \n " ) ;
2014-09-01 03:57:05 +04:00
return 0 ;
2016-11-06 07:20:29 +03:00
err_regmap_exit :
regmap_exit ( dev - > regmap ) ;
2014-09-01 03:57:05 +04:00
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
2016-11-06 23:55:36 +03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-03-30 15:21:25 +04:00
2016-11-06 07:20:29 +03:00
regmap_exit ( dev - > regmap ) ;
2014-09-01 03:57:05 +04:00
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 = {
. name = " af9033 " ,
2016-06-30 02:40:22 +03:00
. suppress_bind_attrs = true ,
2014-09-01 03:57:05 +04:00
} ,
. 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 " ) ;