2019-05-27 08:55:06 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-03-30 06:37:26 -03:00
/*
2015-04-15 20:26:06 -03:00
* Infineon TUA9001 silicon tuner driver
2012-03-30 06:37:26 -03:00
*
* Copyright ( C ) 2009 Antti Palosaari < crope @ iki . fi >
*/
# include "tua9001_priv.h"
static int tua9001_init ( struct dvb_frontend * fe )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
int ret , i ;
static const struct tua9001_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-03-30 06:37:26 -03:00
} ;
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-09-11 22:27:10 -03:00
2012-09-11 22:27:07 -03:00
if ( fe - > callback ) {
2015-04-15 20:26:06 -03:00
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 0 ) ;
if ( ret )
2012-09-11 22:27:07 -03:00
goto err ;
}
2012-03-30 06:37:26 -03:00
for ( i = 0 ; i < ARRAY_SIZE ( data ) ; i + + ) {
2015-04-15 20:38:43 -03:00
ret = regmap_write ( dev - > regmap , data [ i ] . reg , data [ i ] . val ) ;
2015-04-15 20:26:06 -03:00
if ( ret )
2015-04-15 19:33:13 -03:00
goto err ;
2012-03-30 06:37:26 -03:00
}
2015-04-15 20:26:06 -03:00
return 0 ;
2012-09-11 22:27:07 -03:00
err :
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-09-11 22:27:07 -03:00
return ret ;
}
static int tua9001_sleep ( struct dvb_frontend * fe )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
int ret ;
2012-03-30 06:37:26 -03:00
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-03-30 06:37:26 -03:00
2015-04-15 20:26:06 -03:00
if ( fe - > callback ) {
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 1 ) ;
if ( ret )
goto err ;
}
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 06:37:26 -03:00
return ret ;
}
static int tua9001_set_params ( struct dvb_frontend * fe )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2012-03-30 06:37:26 -03:00
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
2015-04-15 20:26:06 -03:00
int ret , i ;
2012-03-30 06:37:26 -03:00
u16 val ;
2015-04-15 20:26:06 -03:00
struct tua9001_reg_val data [ 2 ] ;
2012-03-30 06:37:26 -03:00
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev ,
" delivery_system=%u frequency=%u bandwidth_hz=%u \n " ,
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 ;
data [ 1 ] . reg = 0x1f ;
2015-04-16 07:36:51 -03:00
data [ 1 ] . val = div_u64 ( ( u64 ) ( c - > frequency - 150000000 ) * 48 , 1000000 ) ;
2012-03-30 06:37:26 -03:00
2012-09-11 22:27:07 -03:00
if ( fe - > callback ) {
2015-04-15 20:26:06 -03:00
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 0 ) ;
if ( ret )
2015-04-15 19:33:13 -03:00
goto err ;
2012-09-11 22:27:07 -03:00
}
2012-03-30 06:37:26 -03:00
for ( i = 0 ; i < ARRAY_SIZE ( data ) ; i + + ) {
2015-04-15 20:38:43 -03:00
ret = regmap_write ( dev - > regmap , data [ i ] . reg , data [ i ] . val ) ;
2015-04-15 20:26:06 -03:00
if ( ret )
2015-04-15 19:33:13 -03:00
goto err ;
2012-09-11 22:27:07 -03:00
}
if ( fe - > callback ) {
2015-04-15 20:26:06 -03:00
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 1 ) ;
if ( ret )
2015-04-15 19:33:13 -03:00
goto err ;
2012-03-30 06:37:26 -03:00
}
2015-04-15 20:26:06 -03:00
return 0 ;
2012-03-30 06:37:26 -03:00
err :
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-03-30 06:37:26 -03:00
return ret ;
}
static int tua9001_get_if_frequency ( struct dvb_frontend * fe , u32 * frequency )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2012-09-11 22:27:10 -03:00
2015-04-15 20:26:06 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-09-11 22:27:10 -03:00
2012-03-30 06:37:26 -03:00
* frequency = 0 ; /* Zero-IF */
return 0 ;
}
static const struct dvb_tuner_ops tua9001_tuner_ops = {
. info = {
2018-07-05 18:59:35 -04:00
. name = " Infineon TUA9001 " ,
. frequency_min_hz = 170 * MHz ,
. frequency_max_hz = 862 * MHz ,
2012-03-30 06:37:26 -03:00
} ,
. 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 ,
} ;
2015-04-15 19:12:34 -03:00
static int tua9001_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev ;
2015-04-15 19:12:34 -03:00
struct tua9001_platform_data * pdata = client - > dev . platform_data ;
struct dvb_frontend * fe = pdata - > dvb_frontend ;
int ret ;
2015-04-15 20:38:43 -03:00
static const struct regmap_config regmap_config = {
. reg_bits = 8 ,
. val_bits = 16 ,
} ;
2015-04-15 19:12:34 -03:00
dev = kzalloc ( sizeof ( * dev ) , GFP_KERNEL ) ;
if ( ! dev ) {
ret = - ENOMEM ;
goto err ;
}
dev - > fe = pdata - > dvb_frontend ;
2015-04-15 20:38:43 -03:00
dev - > client = client ;
dev - > regmap = devm_regmap_init_i2c ( client , & regmap_config ) ;
if ( IS_ERR ( dev - > regmap ) ) {
ret = PTR_ERR ( dev - > regmap ) ;
goto err_kfree ;
}
2015-04-15 19:12:34 -03:00
if ( fe - > callback ) {
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_CEN , 1 ) ;
if ( ret )
goto err_kfree ;
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RXEN , 0 ) ;
if ( ret )
goto err_kfree ;
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_RESETN , 1 ) ;
if ( ret )
goto err_kfree ;
}
fe - > tuner_priv = dev ;
memcpy ( & fe - > ops . tuner_ops , & tua9001_tuner_ops ,
sizeof ( struct dvb_tuner_ops ) ) ;
i2c_set_clientdata ( client , dev ) ;
2015-04-15 20:26:06 -03:00
dev_info ( & client - > dev , " Infineon TUA9001 successfully attached \n " ) ;
2015-04-15 19:12:34 -03:00
return 0 ;
err_kfree :
kfree ( dev ) ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
return ret ;
}
static int tua9001_remove ( struct i2c_client * client )
{
2015-04-15 20:26:06 -03:00
struct tua9001_dev * dev = i2c_get_clientdata ( client ) ;
2015-04-15 19:12:34 -03:00
struct dvb_frontend * fe = dev - > fe ;
int ret ;
dev_dbg ( & client - > dev , " \n " ) ;
if ( fe - > callback ) {
ret = fe - > callback ( client - > adapter ,
DVB_FRONTEND_COMPONENT_TUNER ,
TUA9001_CMD_CEN , 0 ) ;
if ( ret )
2021-10-26 21:40:10 +02:00
dev_err ( & client - > dev , " Tuner disable failed (%pe) \n " , ERR_PTR ( ret ) ) ;
2015-04-15 19:12:34 -03:00
}
kfree ( dev ) ;
return 0 ;
}
static const struct i2c_device_id tua9001_id_table [ ] = {
{ " tua9001 " , 0 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , tua9001_id_table ) ;
static struct i2c_driver tua9001_driver = {
. driver = {
. name = " tua9001 " ,
. suppress_bind_attrs = true ,
} ,
. probe = tua9001_probe ,
. remove = tua9001_remove ,
. id_table = tua9001_id_table ,
} ;
module_i2c_driver ( tua9001_driver ) ;
2015-04-15 20:26:06 -03:00
MODULE_DESCRIPTION ( " Infineon TUA9001 silicon tuner driver " ) ;
2012-03-30 06:37:26 -03:00
MODULE_AUTHOR ( " Antti Palosaari <crope@iki.fi> " ) ;
MODULE_LICENSE ( " GPL " ) ;