2019-05-20 10:19:02 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2008-09-23 22:43:57 +04:00
/*
Driver for ST STV0288 demodulator
Copyright ( C ) 2006 Georg Acher , BayCom GmbH , acher ( at ) baycom ( dot ) de
for Reel Multimedia
Copyright ( C ) 2008 TurboSight . com , Bob Liu < bob @ turbosight . com >
Copyright ( C ) 2008 Igor M . Liplianin < liplianin @ me . by >
Removed stb6000 specific tuner code and revised some
procedures .
2010-09-26 22:16:20 +04:00
2010 - 09 - 01 Josef Pavlik < josef @ pavlik . it >
Fixed diseqc_msg , diseqc_burst and set_tone problems
2008-09-23 22:43:57 +04:00
*/
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/string.h>
# include <linux/slab.h>
# include <linux/jiffies.h>
# include <asm/div64.h>
2017-12-28 21:03:51 +03:00
# include <media/dvb_frontend.h>
2008-09-23 22:43:57 +04:00
# include "stv0288.h"
struct stv0288_state {
struct i2c_adapter * i2c ;
const struct stv0288_config * config ;
struct dvb_frontend frontend ;
u8 initialised : 1 ;
u32 tuner_frequency ;
u32 symbol_rate ;
2015-06-07 20:53:52 +03:00
enum fe_code_rate fec_inner ;
2008-09-23 22:43:57 +04:00
int errmode ;
} ;
# define STATUS_BER 0
# define STATUS_UCBLOCKS 1
static int debug ;
static int debug_legacy_dish_switch ;
# define dprintk(args...) \
do { \
if ( debug ) \
printk ( KERN_DEBUG " stv0288: " args ) ; \
} while ( 0 )
static int stv0288_writeregI ( struct stv0288_state * state , u8 reg , u8 data )
{
int ret ;
u8 buf [ ] = { reg , data } ;
struct i2c_msg msg = {
. addr = state - > config - > demod_address ,
. flags = 0 ,
. buf = buf ,
. len = 2
} ;
ret = i2c_transfer ( state - > i2c , & msg , 1 ) ;
if ( ret ! = 1 )
[media] dvb-frontends: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-18 22:44:22 +03:00
dprintk ( " %s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i) \n " ,
__func__ , reg , data , ret ) ;
2008-09-23 22:43:57 +04:00
return ( ret ! = 1 ) ? - EREMOTEIO : 0 ;
}
2010-08-25 16:50:20 +04:00
static int stv0288_write ( struct dvb_frontend * fe , const u8 buf [ ] , int len )
2008-09-23 22:43:57 +04:00
{
struct stv0288_state * state = fe - > demodulator_priv ;
if ( len ! = 2 )
return - EINVAL ;
return stv0288_writeregI ( state , buf [ 0 ] , buf [ 1 ] ) ;
}
static u8 stv0288_readreg ( struct stv0288_state * state , u8 reg )
{
int ret ;
u8 b0 [ ] = { reg } ;
u8 b1 [ ] = { 0 } ;
struct i2c_msg msg [ ] = {
{
. addr = state - > config - > demod_address ,
. flags = 0 ,
. buf = b0 ,
. len = 1
} , {
. addr = state - > config - > demod_address ,
. flags = I2C_M_RD ,
. buf = b1 ,
. len = 1
}
} ;
ret = i2c_transfer ( state - > i2c , msg , 2 ) ;
if ( ret ! = 2 )
dprintk ( " %s: readreg error (reg == 0x%02x, ret == %i) \n " ,
__func__ , reg , ret ) ;
return b1 [ 0 ] ;
}
static int stv0288_set_symbolrate ( struct dvb_frontend * fe , u32 srate )
{
struct stv0288_state * state = fe - > demodulator_priv ;
unsigned int temp ;
unsigned char b [ 3 ] ;
if ( ( srate < 1000000 ) | | ( srate > 45000000 ) )
return - EINVAL ;
2011-07-11 01:37:13 +04:00
stv0288_writeregI ( state , 0x22 , 0 ) ;
stv0288_writeregI ( state , 0x23 , 0 ) ;
stv0288_writeregI ( state , 0x2b , 0xff ) ;
stv0288_writeregI ( state , 0x2c , 0xf7 ) ;
2008-09-23 22:43:57 +04:00
temp = ( unsigned int ) srate / 1000 ;
2015-04-29 00:46:13 +03:00
temp = temp * 32768 ;
temp = temp / 25 ;
temp = temp / 125 ;
b [ 0 ] = ( unsigned char ) ( ( temp > > 12 ) & 0xff ) ;
b [ 1 ] = ( unsigned char ) ( ( temp > > 4 ) & 0xff ) ;
b [ 2 ] = ( unsigned char ) ( ( temp < < 4 ) & 0xf0 ) ;
stv0288_writeregI ( state , 0x28 , 0x80 ) ; /* SFRH */
stv0288_writeregI ( state , 0x29 , 0 ) ; /* SFRM */
stv0288_writeregI ( state , 0x2a , 0 ) ; /* SFRL */
stv0288_writeregI ( state , 0x28 , b [ 0 ] ) ;
stv0288_writeregI ( state , 0x29 , b [ 1 ] ) ;
stv0288_writeregI ( state , 0x2a , b [ 2 ] ) ;
dprintk ( " stv0288: stv0288_set_symbolrate \n " ) ;
2008-09-23 22:43:57 +04:00
return 0 ;
}
static int stv0288_send_diseqc_msg ( struct dvb_frontend * fe ,
struct dvb_diseqc_master_cmd * m )
{
struct stv0288_state * state = fe - > demodulator_priv ;
int i ;
dprintk ( " %s \n " , __func__ ) ;
stv0288_writeregI ( state , 0x09 , 0 ) ;
msleep ( 30 ) ;
2010-09-26 22:16:20 +04:00
stv0288_writeregI ( state , 0x05 , 0x12 ) ; /* modulated mode, single shot */
2008-09-23 22:43:57 +04:00
for ( i = 0 ; i < m - > msg_len ; i + + ) {
if ( stv0288_writeregI ( state , 0x06 , m - > msg [ i ] ) )
return - EREMOTEIO ;
}
2010-09-26 22:16:20 +04:00
msleep ( m - > msg_len * 12 ) ;
2008-09-23 22:43:57 +04:00
return 0 ;
}
static int stv0288_send_diseqc_burst ( struct dvb_frontend * fe ,
2015-06-07 20:53:52 +03:00
enum fe_sec_mini_cmd burst )
2008-09-23 22:43:57 +04:00
{
struct stv0288_state * state = fe - > demodulator_priv ;
dprintk ( " %s \n " , __func__ ) ;
2010-09-26 22:16:20 +04:00
if ( stv0288_writeregI ( state , 0x05 , 0x03 ) ) /* burst mode, single shot */
2008-09-23 22:43:57 +04:00
return - EREMOTEIO ;
if ( stv0288_writeregI ( state , 0x06 , burst = = SEC_MINI_A ? 0x00 : 0xff ) )
return - EREMOTEIO ;
2010-09-26 22:16:20 +04:00
msleep ( 15 ) ;
if ( stv0288_writeregI ( state , 0x05 , 0x12 ) )
2008-09-23 22:43:57 +04:00
return - EREMOTEIO ;
return 0 ;
}
2015-06-07 20:53:52 +03:00
static int stv0288_set_tone ( struct dvb_frontend * fe , enum fe_sec_tone_mode tone )
2008-09-23 22:43:57 +04:00
{
struct stv0288_state * state = fe - > demodulator_priv ;
switch ( tone ) {
case SEC_TONE_ON :
2010-09-26 22:16:20 +04:00
if ( stv0288_writeregI ( state , 0x05 , 0x10 ) ) /* cont carrier */
2008-09-23 22:43:57 +04:00
return - EREMOTEIO ;
2010-09-26 22:16:20 +04:00
break ;
2008-09-23 22:43:57 +04:00
case SEC_TONE_OFF :
2010-09-26 22:16:20 +04:00
if ( stv0288_writeregI ( state , 0x05 , 0x12 ) ) /* burst mode off*/
2008-09-23 22:43:57 +04:00
return - EREMOTEIO ;
2010-09-26 22:16:20 +04:00
break ;
2008-09-23 22:43:57 +04:00
default :
return - EINVAL ;
}
2010-09-26 22:16:20 +04:00
return 0 ;
2008-09-23 22:43:57 +04:00
}
static u8 stv0288_inittab [ ] = {
0x01 , 0x15 ,
0x02 , 0x20 ,
0x09 , 0x0 ,
0x0a , 0x4 ,
0x0b , 0x0 ,
0x0c , 0x0 ,
0x0d , 0x0 ,
0x0e , 0xd4 ,
0x0f , 0x30 ,
0x11 , 0x80 ,
0x12 , 0x03 ,
0x13 , 0x48 ,
0x14 , 0x84 ,
0x15 , 0x45 ,
0x16 , 0xb7 ,
0x17 , 0x9c ,
0x18 , 0x0 ,
0x19 , 0xa6 ,
0x1a , 0x88 ,
0x1b , 0x8f ,
0x1c , 0xf0 ,
0x20 , 0x0b ,
0x21 , 0x54 ,
0x22 , 0x0 ,
0x23 , 0x0 ,
0x2b , 0xff ,
0x2c , 0xf7 ,
0x30 , 0x0 ,
0x31 , 0x1e ,
0x32 , 0x14 ,
0x33 , 0x0f ,
0x34 , 0x09 ,
0x35 , 0x0c ,
0x36 , 0x05 ,
0x37 , 0x2f ,
0x38 , 0x16 ,
0x39 , 0xbe ,
0x3a , 0x0 ,
0x3b , 0x13 ,
0x3c , 0x11 ,
0x3d , 0x30 ,
0x40 , 0x63 ,
0x41 , 0x04 ,
2011-04-02 17:51:53 +04:00
0x42 , 0x20 ,
2008-09-23 22:43:57 +04:00
0x43 , 0x00 ,
0x44 , 0x00 ,
0x45 , 0x00 ,
0x46 , 0x00 ,
0x47 , 0x00 ,
0x4a , 0x00 ,
0x50 , 0x10 ,
0x51 , 0x38 ,
0x52 , 0x21 ,
0x58 , 0x54 ,
0x59 , 0x86 ,
0x5a , 0x0 ,
0x5b , 0x9b ,
0x5c , 0x08 ,
0x5d , 0x7f ,
0x5e , 0x0 ,
0x5f , 0xff ,
0x70 , 0x0 ,
0x71 , 0x0 ,
0x72 , 0x0 ,
0x74 , 0x0 ,
0x75 , 0x0 ,
0x76 , 0x0 ,
0x81 , 0x0 ,
0x82 , 0x3f ,
0x83 , 0x3f ,
0x84 , 0x0 ,
0x85 , 0x0 ,
0x88 , 0x0 ,
0x89 , 0x0 ,
0x8a , 0x0 ,
0x8b , 0x0 ,
0x8c , 0x0 ,
0x90 , 0x0 ,
0x91 , 0x0 ,
0x92 , 0x0 ,
0x93 , 0x0 ,
0x94 , 0x1c ,
0x97 , 0x0 ,
0xa0 , 0x48 ,
0xa1 , 0x0 ,
0xb0 , 0xb8 ,
0xb1 , 0x3a ,
0xb2 , 0x10 ,
0xb3 , 0x82 ,
0xb4 , 0x80 ,
0xb5 , 0x82 ,
0xb6 , 0x82 ,
0xb7 , 0x82 ,
0xb8 , 0x20 ,
0xb9 , 0x0 ,
0xf0 , 0x0 ,
0xf1 , 0x0 ,
0xf2 , 0xc0 ,
0x51 , 0x36 ,
0x52 , 0x09 ,
0x53 , 0x94 ,
0x54 , 0x62 ,
0x55 , 0x29 ,
0x56 , 0x64 ,
0x57 , 0x2b ,
0xff , 0xff ,
} ;
2015-06-07 20:53:52 +03:00
static int stv0288_set_voltage ( struct dvb_frontend * fe ,
enum fe_sec_voltage volt )
2008-09-23 22:43:57 +04:00
{
dprintk ( " %s: %s \n " , __func__ ,
volt = = SEC_VOLTAGE_13 ? " SEC_VOLTAGE_13 " :
volt = = SEC_VOLTAGE_18 ? " SEC_VOLTAGE_18 " : " ?? " ) ;
return 0 ;
}
static int stv0288_init ( struct dvb_frontend * fe )
{
struct stv0288_state * state = fe - > demodulator_priv ;
int i ;
2008-10-05 15:52:18 +04:00
u8 reg ;
u8 val ;
2008-09-23 22:43:57 +04:00
dprintk ( " stv0288: init chip \n " ) ;
stv0288_writeregI ( state , 0x41 , 0x04 ) ;
msleep ( 50 ) ;
2008-10-05 15:52:18 +04:00
/* we have default inittab */
if ( state - > config - > inittab = = NULL ) {
for ( i = 0 ; ! ( stv0288_inittab [ i ] = = 0xff & &
2008-09-23 22:43:57 +04:00
stv0288_inittab [ i + 1 ] = = 0xff ) ; i + = 2 )
2008-10-05 15:52:18 +04:00
stv0288_writeregI ( state , stv0288_inittab [ i ] ,
stv0288_inittab [ i + 1 ] ) ;
} else {
for ( i = 0 ; ; i + = 2 ) {
reg = state - > config - > inittab [ i ] ;
val = state - > config - > inittab [ i + 1 ] ;
if ( reg = = 0xff & & val = = 0xff )
break ;
stv0288_writeregI ( state , reg , val ) ;
}
}
2008-09-23 22:43:57 +04:00
return 0 ;
}
2015-06-07 20:53:52 +03:00
static int stv0288_read_status ( struct dvb_frontend * fe , enum fe_status * status )
2008-09-23 22:43:57 +04:00
{
struct stv0288_state * state = fe - > demodulator_priv ;
u8 sync = stv0288_readreg ( state , 0x24 ) ;
if ( sync = = 255 )
sync = 0 ;
dprintk ( " %s : FE_READ_STATUS : VSTATUS: 0x%02x \n " , __func__ , sync ) ;
* status = 0 ;
2011-03-06 19:37:00 +03:00
if ( sync & 0x80 )
* status | = FE_HAS_CARRIER | FE_HAS_SIGNAL ;
if ( sync & 0x10 )
* status | = FE_HAS_VITERBI ;
if ( sync & 0x08 ) {
2008-09-23 22:43:57 +04:00
* status | = FE_HAS_LOCK ;
dprintk ( " stv0288 has locked \n " ) ;
}
return 0 ;
}
static int stv0288_read_ber ( struct dvb_frontend * fe , u32 * ber )
{
struct stv0288_state * state = fe - > demodulator_priv ;
if ( state - > errmode ! = STATUS_BER )
return 0 ;
* ber = ( stv0288_readreg ( state , 0x26 ) < < 8 ) |
stv0288_readreg ( state , 0x27 ) ;
dprintk ( " stv0288_read_ber %d \n " , * ber ) ;
return 0 ;
}
static int stv0288_read_signal_strength ( struct dvb_frontend * fe , u16 * strength )
{
struct stv0288_state * state = fe - > demodulator_priv ;
s32 signal = 0xffff - ( ( stv0288_readreg ( state , 0x10 ) < < 8 ) ) ;
signal = signal * 5 / 4 ;
* strength = ( signal > 0xffff ) ? 0xffff : ( signal < 0 ) ? 0 : signal ;
dprintk ( " stv0288_read_signal_strength %d \n " , * strength ) ;
return 0 ;
}
static int stv0288_sleep ( struct dvb_frontend * fe )
{
struct stv0288_state * state = fe - > demodulator_priv ;
stv0288_writeregI ( state , 0x41 , 0x84 ) ;
state - > initialised = 0 ;
return 0 ;
}
static int stv0288_read_snr ( struct dvb_frontend * fe , u16 * snr )
{
struct stv0288_state * state = fe - > demodulator_priv ;
s32 xsnr = 0xffff - ( ( stv0288_readreg ( state , 0x2d ) < < 8 )
| stv0288_readreg ( state , 0x2e ) ) ;
xsnr = 3 * ( xsnr - 0xa100 ) ;
* snr = ( xsnr > 0xffff ) ? 0xffff : ( xsnr < 0 ) ? 0 : xsnr ;
dprintk ( " stv0288_read_snr %d \n " , * snr ) ;
return 0 ;
}
static int stv0288_read_ucblocks ( struct dvb_frontend * fe , u32 * ucblocks )
{
struct stv0288_state * state = fe - > demodulator_priv ;
if ( state - > errmode ! = STATUS_BER )
return 0 ;
* ucblocks = ( stv0288_readreg ( state , 0x26 ) < < 8 ) |
stv0288_readreg ( state , 0x27 ) ;
dprintk ( " stv0288_read_ber %d \n " , * ucblocks ) ;
return 0 ;
}
2011-12-26 21:25:54 +04:00
static int stv0288_set_frontend ( struct dvb_frontend * fe )
2008-09-23 22:43:57 +04:00
{
struct stv0288_state * state = fe - > demodulator_priv ;
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
char tm ;
unsigned char tda [ 3 ] ;
2011-07-11 01:37:13 +04:00
u8 reg , time_out = 0 ;
2008-09-23 22:43:57 +04:00
dprintk ( " %s : FE_SET_FRONTEND \n " , __func__ ) ;
if ( c - > delivery_system ! = SYS_DVBS ) {
[media] dvb-frontends: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-18 22:44:22 +03:00
dprintk ( " %s: unsupported delivery system selected (%d) \n " ,
__func__ , c - > delivery_system ) ;
return - EOPNOTSUPP ;
2008-09-23 22:43:57 +04:00
}
if ( state - > config - > set_ts_params )
state - > config - > set_ts_params ( fe , 0 ) ;
/* only frequency & symbol_rate are used for tuner*/
if ( fe - > ops . tuner_ops . set_params ) {
2011-12-24 19:24:33 +04:00
fe - > ops . tuner_ops . set_params ( fe ) ;
2008-09-23 22:43:57 +04:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ;
}
udelay ( 10 ) ;
stv0288_set_symbolrate ( fe , c - > symbol_rate ) ;
/* Carrier lock control register */
stv0288_writeregI ( state , 0x15 , 0xc5 ) ;
tda [ 2 ] = 0x0 ; /* CFRL */
2011-07-11 01:37:13 +04:00
for ( tm = - 9 ; tm < 7 ; ) {
2008-09-23 22:43:57 +04:00
/* Viterbi status */
2011-07-11 01:37:13 +04:00
reg = stv0288_readreg ( state , 0x24 ) ;
if ( reg & 0x8 )
break ;
if ( reg & 0x80 ) {
time_out + + ;
if ( time_out > 10 )
break ;
tda [ 2 ] + = 40 ;
if ( tda [ 2 ] < 40 )
tm + + ;
} else {
2008-09-23 22:43:57 +04:00
tm + + ;
2011-07-11 01:37:13 +04:00
tda [ 2 ] = 0 ;
time_out = 0 ;
}
2008-09-23 22:43:57 +04:00
tda [ 1 ] = ( unsigned char ) tm ;
stv0288_writeregI ( state , 0x2b , tda [ 1 ] ) ;
stv0288_writeregI ( state , 0x2c , tda [ 2 ] ) ;
2012-03-03 01:15:41 +04:00
msleep ( 30 ) ;
2008-09-23 22:43:57 +04:00
}
state - > tuner_frequency = c - > frequency ;
state - > fec_inner = FEC_AUTO ;
state - > symbol_rate = c - > symbol_rate ;
return 0 ;
}
static int stv0288_i2c_gate_ctrl ( struct dvb_frontend * fe , int enable )
{
struct stv0288_state * state = fe - > demodulator_priv ;
if ( enable )
stv0288_writeregI ( state , 0x01 , 0xb5 ) ;
else
stv0288_writeregI ( state , 0x01 , 0x35 ) ;
udelay ( 1 ) ;
return 0 ;
}
static void stv0288_release ( struct dvb_frontend * fe )
{
struct stv0288_state * state = fe - > demodulator_priv ;
kfree ( state ) ;
}
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops stv0288_ops = {
2011-12-26 21:25:54 +04:00
. delsys = { SYS_DVBS } ,
2008-09-23 22:43:57 +04:00
. info = {
. name = " ST STV0288 DVB-S " ,
2018-07-06 01:59:36 +03:00
. frequency_min_hz = 950 * MHz ,
. frequency_max_hz = 2150 * MHz ,
. frequency_stepsize_hz = 1 * MHz ,
2008-09-23 22:43:57 +04:00
. symbol_rate_min = 1000000 ,
. symbol_rate_max = 45000000 ,
. symbol_rate_tolerance = 500 , /* ppm */
. 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_QPSK |
FE_CAN_FEC_AUTO
} ,
. release = stv0288_release ,
. init = stv0288_init ,
. sleep = stv0288_sleep ,
. write = stv0288_write ,
. i2c_gate_ctrl = stv0288_i2c_gate_ctrl ,
. read_status = stv0288_read_status ,
. read_ber = stv0288_read_ber ,
. read_signal_strength = stv0288_read_signal_strength ,
. read_snr = stv0288_read_snr ,
. read_ucblocks = stv0288_read_ucblocks ,
. diseqc_send_master_cmd = stv0288_send_diseqc_msg ,
. diseqc_send_burst = stv0288_send_diseqc_burst ,
. set_tone = stv0288_set_tone ,
. set_voltage = stv0288_set_voltage ,
2011-12-26 21:25:54 +04:00
. set_frontend = stv0288_set_frontend ,
2008-09-23 22:43:57 +04:00
} ;
struct dvb_frontend * stv0288_attach ( const struct stv0288_config * config ,
struct i2c_adapter * i2c )
{
struct stv0288_state * state = NULL ;
int id ;
/* allocate memory for the internal state */
2009-08-11 05:51:01 +04:00
state = kzalloc ( sizeof ( struct stv0288_state ) , GFP_KERNEL ) ;
2008-09-23 22:43:57 +04:00
if ( state = = NULL )
goto error ;
/* setup the state */
state - > config = config ;
state - > i2c = i2c ;
state - > initialised = 0 ;
state - > tuner_frequency = 0 ;
state - > symbol_rate = 0 ;
state - > fec_inner = 0 ;
state - > errmode = STATUS_BER ;
stv0288_writeregI ( state , 0x41 , 0x04 ) ;
msleep ( 200 ) ;
id = stv0288_readreg ( state , 0x00 ) ;
dprintk ( " stv0288 id %x \n " , id ) ;
/* register 0x00 contains 0x11 for STV0288 */
if ( id ! = 0x11 )
goto error ;
/* create dvb_frontend */
memcpy ( & state - > frontend . ops , & stv0288_ops ,
sizeof ( struct dvb_frontend_ops ) ) ;
state - > frontend . demodulator_priv = state ;
return & state - > frontend ;
error :
kfree ( state ) ;
return NULL ;
}
EXPORT_SYMBOL ( stv0288_attach ) ;
module_param ( debug_legacy_dish_switch , int , 0444 ) ;
MODULE_PARM_DESC ( debug_legacy_dish_switch ,
" Enable timing analysis for Dish Network legacy switches " ) ;
module_param ( debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " Turn on/off frontend debugging (default:off). " ) ;
MODULE_DESCRIPTION ( " ST STV0288 DVB Demodulator driver " ) ;
MODULE_AUTHOR ( " Georg Acher, Bob Liu, Igor liplianin " ) ;
MODULE_LICENSE ( " GPL " ) ;