2012-03-30 06:37:26 -03:00
/*
* Infineon TUA 9001 silicon tuner driver
*
* Copyright ( C ) 2009 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 "tua9001.h"
# include "tua9001_priv.h"
/* write register */
static int tua9001_wr_reg ( struct tua9001_priv * priv , u8 reg , u16 val )
{
int ret ;
u8 buf [ 3 ] = { reg , ( val > > 8 ) & 0xff , ( val > > 0 ) & 0xff } ;
struct i2c_msg msg [ 1 ] = {
{
. addr = priv - > cfg - > i2c_addr ,
. flags = 0 ,
. len = sizeof ( buf ) ,
. buf = buf ,
}
} ;
ret = i2c_transfer ( priv - > i2c , msg , 1 ) ;
if ( ret = = 1 ) {
ret = 0 ;
} else {
2012-09-11 22:27:10 -03:00
dev_warn ( & priv - > i2c - > dev , " %s: i2c wr failed=%d reg=%02x \n " ,
KBUILD_MODNAME , ret , reg ) ;
2012-03-30 06:37:26 -03:00
ret = - EREMOTEIO ;
}
return ret ;
}
static int tua9001_release ( struct dvb_frontend * fe )
{
2012-09-11 22:27:07 -03:00
struct tua9001_priv * priv = fe - > tuner_priv ;
int ret = 0 ;
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: \n " , __func__ ) ;
2012-09-11 22:27:07 -03:00
if ( fe - > callback )
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_CEN , 0 ) ;
2012-03-30 06:37:26 -03:00
kfree ( fe - > tuner_priv ) ;
fe - > tuner_priv = NULL ;
2012-09-11 22:27:07 -03:00
return ret ;
2012-03-30 06:37:26 -03:00
}
static int tua9001_init ( struct dvb_frontend * fe )
{
struct tua9001_priv * priv = fe - > tuner_priv ;
int ret = 0 ;
u8 i ;
struct reg_val data [ ] = {
{ 0x1e , 0x6512 } ,
{ 0x25 , 0xb888 } ,
{ 0x39 , 0x5460 } ,
{ 0x3b , 0x00c0 } ,
{ 0x3a , 0xf000 } ,
{ 0x08 , 0x0000 } ,
{ 0x32 , 0x0030 } ,
{ 0x41 , 0x703a } ,
{ 0x40 , 0x1c78 } ,
{ 0x2c , 0x1c00 } ,
{ 0x36 , 0xc013 } ,
{ 0x37 , 0x6f18 } ,
{ 0x27 , 0x0008 } ,
{ 0x2a , 0x0001 } ,
{ 0x34 , 0x0a40 } ,
} ;
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: \n " , __func__ ) ;
2012-09-11 22:27:07 -03:00
if ( fe - > callback ) {
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 0 ) ;
if ( ret < 0 )
goto err ;
}
2012-03-30 06:37:26 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ; /* open i2c-gate */
for ( i = 0 ; i < ARRAY_SIZE ( data ) ; i + + ) {
ret = tua9001_wr_reg ( priv , data [ i ] . reg , data [ i ] . val ) ;
2012-09-11 22:27:07 -03:00
if ( ret < 0 )
goto err_i2c_gate_ctrl ;
2012-03-30 06:37:26 -03:00
}
2012-09-11 22:27:07 -03:00
err_i2c_gate_ctrl :
2012-03-30 06:37:26 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ; /* close i2c-gate */
2012-09-11 22:27:07 -03:00
err :
if ( ret < 0 )
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: failed=%d \n " , __func__ , ret ) ;
2012-09-11 22:27:07 -03:00
return ret ;
}
static int tua9001_sleep ( struct dvb_frontend * fe )
{
struct tua9001_priv * priv = fe - > tuner_priv ;
int ret = 0 ;
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: \n " , __func__ ) ;
2012-09-11 22:27:07 -03:00
if ( fe - > callback )
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 1 ) ;
2012-03-30 06:37:26 -03:00
if ( ret < 0 )
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: failed=%d \n " , __func__ , ret ) ;
2012-03-30 06:37:26 -03:00
return ret ;
}
static int tua9001_set_params ( struct dvb_frontend * fe )
{
struct tua9001_priv * priv = fe - > tuner_priv ;
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2012-10-27 16:26:56 -03:00
int ret = 0 , i ;
2012-03-30 06:37:26 -03:00
u16 val ;
u32 frequency ;
struct reg_val data [ 2 ] ;
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: delivery_system=%d frequency=%d " \
" bandwidth_hz=%d \n " , __func__ ,
c - > delivery_system , c - > frequency , c - > bandwidth_hz ) ;
2012-03-30 06:37:26 -03:00
switch ( c - > delivery_system ) {
case SYS_DVBT :
switch ( c - > bandwidth_hz ) {
case 8000000 :
val = 0x0000 ;
break ;
case 7000000 :
val = 0x1000 ;
break ;
case 6000000 :
val = 0x2000 ;
break ;
case 5000000 :
val = 0x3000 ;
break ;
default :
ret = - EINVAL ;
goto err ;
}
break ;
default :
ret = - EINVAL ;
goto err ;
}
data [ 0 ] . reg = 0x04 ;
data [ 0 ] . val = val ;
frequency = ( c - > frequency - 150000000 ) ;
frequency / = 100 ;
frequency * = 48 ;
frequency / = 10000 ;
data [ 1 ] . reg = 0x1f ;
data [ 1 ] . val = frequency ;
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ; /* open i2c-gate */
2012-09-11 22:27:07 -03:00
if ( fe - > callback ) {
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 0 ) ;
if ( ret < 0 )
goto err_i2c_gate_ctrl ;
}
2012-03-30 06:37:26 -03:00
for ( i = 0 ; i < ARRAY_SIZE ( data ) ; i + + ) {
ret = tua9001_wr_reg ( priv , data [ i ] . reg , data [ i ] . val ) ;
if ( ret < 0 )
2012-09-11 22:27:07 -03:00
goto err_i2c_gate_ctrl ;
}
if ( fe - > callback ) {
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 1 ) ;
if ( ret < 0 )
goto err_i2c_gate_ctrl ;
2012-03-30 06:37:26 -03:00
}
2012-09-11 22:27:07 -03:00
err_i2c_gate_ctrl :
2012-03-30 06:37:26 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ; /* close i2c-gate */
err :
if ( ret < 0 )
2012-09-11 22:27:10 -03:00
dev_dbg ( & priv - > i2c - > dev , " %s: failed=%d \n " , __func__ , ret ) ;
2012-03-30 06:37:26 -03:00
return ret ;
}
static int tua9001_get_if_frequency ( struct dvb_frontend * fe , u32 * frequency )
{
2012-09-11 22:27:10 -03:00
struct tua9001_priv * priv = fe - > tuner_priv ;
dev_dbg ( & priv - > i2c - > dev , " %s: \n " , __func__ ) ;
2012-03-30 06:37:26 -03:00
* frequency = 0 ; /* Zero-IF */
return 0 ;
}
static const struct dvb_tuner_ops tua9001_tuner_ops = {
. info = {
. name = " Infineon TUA 9001 " ,
. frequency_min = 170000000 ,
. frequency_max = 862000000 ,
. frequency_step = 0 ,
} ,
. release = tua9001_release ,
. init = tua9001_init ,
2012-09-11 22:27:07 -03:00
. sleep = tua9001_sleep ,
2012-03-30 06:37:26 -03:00
. set_params = tua9001_set_params ,
. get_if_frequency = tua9001_get_if_frequency ,
} ;
struct dvb_frontend * tua9001_attach ( struct dvb_frontend * fe ,
struct i2c_adapter * i2c , struct tua9001_config * cfg )
{
struct tua9001_priv * priv = NULL ;
2012-09-11 22:27:07 -03:00
int ret ;
2012-03-30 06:37:26 -03:00
priv = kzalloc ( sizeof ( struct tua9001_priv ) , GFP_KERNEL ) ;
if ( priv = = NULL )
return NULL ;
priv - > cfg = cfg ;
priv - > i2c = i2c ;
2012-09-11 22:27:07 -03:00
if ( fe - > callback ) {
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_CEN , 1 ) ;
if ( ret < 0 )
goto err ;
2012-09-16 22:26:55 -03:00
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 0 ) ;
if ( ret < 0 )
goto err ;
ret = fe - > callback ( priv - > i2c , DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 1 ) ;
if ( ret < 0 )
goto err ;
2012-09-11 22:27:07 -03:00
}
2012-09-11 22:27:10 -03:00
dev_info ( & priv - > i2c - > dev ,
" %s: Infineon TUA 9001 successfully attached \n " ,
KBUILD_MODNAME ) ;
2012-03-30 06:37:26 -03:00
memcpy ( & fe - > ops . tuner_ops , & tua9001_tuner_ops ,
sizeof ( struct dvb_tuner_ops ) ) ;
fe - > tuner_priv = priv ;
return fe ;
2012-09-11 22:27:07 -03:00
err :
2012-09-11 22:27:10 -03:00
dev_dbg ( & i2c - > dev , " %s: failed=%d \n " , __func__ , ret ) ;
2012-09-11 22:27:07 -03:00
kfree ( priv ) ;
return NULL ;
2012-03-30 06:37:26 -03:00
}
EXPORT_SYMBOL ( tua9001_attach ) ;
MODULE_DESCRIPTION ( " Infineon TUA 9001 silicon tuner driver " ) ;
MODULE_AUTHOR ( " Antti Palosaari <crope@iki.fi> " ) ;
MODULE_LICENSE ( " GPL " ) ;