2005-04-16 15:20:36 -07:00
/*
2005-05-16 21:54:41 -07:00
Frontend / Card driver for TwinHan DST Frontend
Copyright ( C ) 2003 Jamie Honan
Copyright ( C ) 2004 , 2005 Manu Abraham ( manu @ kromtek . com )
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
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 .
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
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 .
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
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 . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
2005-04-16 15:20:36 -07:00
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/string.h>
# include <linux/slab.h>
# include <linux/vmalloc.h>
# include <linux/delay.h>
# include <asm/div64.h>
# include "dvb_frontend.h"
# include "dst_priv.h"
2005-05-16 21:54:41 -07:00
# include "dst_common.h"
static unsigned int verbose = 1 ;
module_param ( verbose , int , 0644 ) ;
MODULE_PARM_DESC ( verbose , " verbose startup messages, default is 1 (yes) " ) ;
static unsigned int dst_addons ;
module_param ( dst_addons , int , 0644 ) ;
2005-05-16 21:54:45 -07:00
MODULE_PARM_DESC ( dst_addons , " CA daughterboard, default is 0 (No addons) " ) ;
2005-04-16 15:20:36 -07:00
2006-06-21 10:27:26 -03:00
static unsigned int dst_algo ;
module_param ( dst_algo , int , 0644 ) ;
MODULE_PARM_DESC ( dst_algo , " tuning algo: default is 0=(SW), 1=(HW) " ) ;
2005-09-09 13:03:00 -07:00
# define HAS_LOCK 1
# define ATTEMPT_TUNE 2
# define HAS_POWER 4
# define DST_ERROR 0
# define DST_NOTICE 1
# define DST_INFO 2
# define DST_DEBUG 3
2006-06-21 10:28:23 -03:00
# define dprintk(x, y, z, format, arg...) do { \
if ( z ) { \
if ( ( x > DST_ERROR ) & & ( x > y ) ) \
printk ( KERN_ERR " dst(%d) %s: " format " \n " , \
state - > bt - > nr , __func__ , # # arg ) ; \
else if ( ( x > DST_NOTICE ) & & ( x > y ) ) \
printk ( KERN_NOTICE " dst(%d) %s: " format " \n " , \
state - > bt - > nr , __func__ , # # arg ) ; \
else if ( ( x > DST_INFO ) & & ( x > y ) ) \
printk ( KERN_INFO " dst(%d) %s: " format " \n " , \
state - > bt - > nr , __func__ , # # arg ) ; \
else if ( ( x > DST_DEBUG ) & & ( x > y ) ) \
printk ( KERN_DEBUG " dst(%d) %s: " format " \n " , \
state - > bt - > nr , __func__ , # # arg ) ; \
} else { \
if ( x > y ) \
printk ( format , # # arg ) ; \
} \
2005-09-09 13:03:00 -07:00
} while ( 0 )
2007-11-05 14:06:31 -03:00
static int dst_command ( struct dst_state * state , u8 * data , u8 len ) ;
2005-09-09 13:03:00 -07:00
static void dst_packsize ( struct dst_state * state , int psize )
2005-04-16 15:20:36 -07:00
{
union dst_gpio_packet bits ;
bits . psize = psize ;
bt878_device_control ( state - > bt , DST_IG_TS , & bits ) ;
}
2007-11-05 14:06:31 -03:00
static int dst_gpio_outb ( struct dst_state * state , u32 mask , u32 enbb ,
u32 outhigh , int delay )
2005-04-16 15:20:36 -07:00
{
union dst_gpio_packet enb ;
union dst_gpio_packet bits ;
int err ;
enb . enb . mask = mask ;
enb . enb . enable = enbb ;
2005-05-16 21:54:41 -07:00
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " mask=[%04x], enbb=[%04x], outhigh=[%04x] " , mask , enbb , outhigh ) ;
2005-04-16 15:20:36 -07:00
if ( ( err = bt878_device_control ( state - > bt , DST_IG_ENABLE , & enb ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " dst_gpio_enb error (err == %i, mask == %02x, enb == %02x) " , err , mask , enbb ) ;
2005-04-16 15:20:36 -07:00
return - EREMOTEIO ;
}
2005-05-16 21:54:43 -07:00
udelay ( 1000 ) ;
2005-04-16 15:20:36 -07:00
/* because complete disabling means no output, no need to do output packet */
if ( enbb = = 0 )
return 0 ;
2005-05-16 21:54:41 -07:00
if ( delay )
msleep ( 10 ) ;
2005-04-16 15:20:36 -07:00
bits . outp . mask = enbb ;
bits . outp . highvals = outhigh ;
if ( ( err = bt878_device_control ( state - > bt , DST_IG_WRITE , & bits ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x) " , err , enbb , outhigh ) ;
2005-04-16 15:20:36 -07:00
return - EREMOTEIO ;
}
2005-09-09 13:03:00 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2007-11-05 14:06:31 -03:00
static int dst_gpio_inb ( struct dst_state * state , u8 * result )
2005-04-16 15:20:36 -07:00
{
union dst_gpio_packet rd_packet ;
int err ;
* result = 0 ;
if ( ( err = bt878_device_control ( state - > bt , DST_IG_READ , & rd_packet ) ) < 0 ) {
2006-06-21 10:28:19 -03:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_inb error (err == %i) " , err ) ;
2005-04-16 15:20:36 -07:00
return - EREMOTEIO ;
}
* result = ( u8 ) rd_packet . rd . value ;
2005-09-09 13:03:00 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
int rdc_reset_state ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Resetting state machine " ) ;
2005-05-16 21:54:41 -07:00
if ( dst_gpio_outb ( state , RDC_8820_INT , RDC_8820_INT , 0 , NO_DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-04-16 15:20:36 -07:00
msleep ( 10 ) ;
2005-05-16 21:54:41 -07:00
if ( dst_gpio_outb ( state , RDC_8820_INT , RDC_8820_INT , RDC_8820_INT , NO_DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
msleep ( 10 ) ;
return - 1 ;
}
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( rdc_reset_state ) ;
2005-04-16 15:20:36 -07:00
2007-11-05 14:06:31 -03:00
static int rdc_8820_reset ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " Resetting DST " ) ;
2005-05-16 21:54:41 -07:00
if ( dst_gpio_outb ( state , RDC_8820_RESET , RDC_8820_RESET , 0 , NO_DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-05-16 21:54:43 -07:00
udelay ( 1000 ) ;
2005-05-16 21:54:41 -07:00
if ( dst_gpio_outb ( state , RDC_8820_RESET , RDC_8820_RESET , RDC_8820_RESET , DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-04-16 15:20:36 -07:00
return 0 ;
}
2007-11-05 14:06:31 -03:00
static int dst_pio_enable ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2005-05-16 21:54:41 -07:00
if ( dst_gpio_outb ( state , ~ 0 , RDC_8820_PIO_0_ENABLE , 0 , NO_DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-05-16 21:54:43 -07:00
udelay ( 1000 ) ;
2005-09-09 13:03:00 -07:00
2005-05-16 21:54:41 -07:00
return 0 ;
}
int dst_pio_disable ( struct dst_state * state )
{
if ( dst_gpio_outb ( state , ~ 0 , RDC_8820_PIO_0_DISABLE , RDC_8820_PIO_0_DISABLE , NO_DELAY ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_outb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-05-16 21:54:43 -07:00
if ( state - > type_flags & DST_TYPE_HAS_FW_1 )
udelay ( 1000 ) ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( dst_pio_disable ) ;
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
int dst_wait_dst_ready ( struct dst_state * state , u8 delay_mode )
2005-04-16 15:20:36 -07:00
{
u8 reply ;
int i ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
for ( i = 0 ; i < 200 ; i + + ) {
2005-05-16 21:54:41 -07:00
if ( dst_gpio_inb ( state , & reply ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " dst_gpio_inb ERROR ! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
if ( ( reply & RDC_8820_PIO_0_ENABLE ) = = 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " dst wait ready after %d " , i ) ;
2005-04-16 15:20:36 -07:00
return 1 ;
}
2005-05-16 21:54:44 -07:00
msleep ( 10 ) ;
2005-05-16 21:54:41 -07:00
}
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_NOTICE , 1 , " dst wait NOT ready after %d " , i ) ;
2005-05-16 21:54:41 -07:00
return 0 ;
}
EXPORT_SYMBOL ( dst_wait_dst_ready ) ;
int dst_error_recovery ( struct dst_state * state )
{
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_NOTICE , 1 , " Trying to return from previous errors. " ) ;
2005-05-16 21:54:41 -07:00
dst_pio_disable ( state ) ;
msleep ( 10 ) ;
dst_pio_enable ( state ) ;
msleep ( 10 ) ;
return 0 ;
}
EXPORT_SYMBOL ( dst_error_recovery ) ;
int dst_error_bailout ( struct dst_state * state )
{
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Trying to bailout from previous error. " ) ;
2005-05-16 21:54:41 -07:00
rdc_8820_reset ( state ) ;
dst_pio_disable ( state ) ;
msleep ( 10 ) ;
return 0 ;
}
EXPORT_SYMBOL ( dst_error_bailout ) ;
2005-09-09 13:03:00 -07:00
int dst_comm_init ( struct dst_state * state )
2005-05-16 21:54:41 -07:00
{
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Initializing DST. " ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_pio_enable ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " PIO Enable Failed " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
if ( ( rdc_reset_state ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " RDC 8820 State RESET Failed. " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:43 -07:00
if ( state - > type_flags & DST_TYPE_HAS_FW_1 )
msleep ( 100 ) ;
else
msleep ( 5 ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( dst_comm_init ) ;
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
int write_dst ( struct dst_state * state , u8 * data , u8 len )
2005-04-16 15:20:36 -07:00
{
struct i2c_msg msg = {
2005-09-09 13:03:00 -07:00
. addr = state - > config - > demod_address ,
. flags = 0 ,
. buf = data ,
. len = len
2005-04-16 15:20:36 -07:00
} ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
int err ;
2005-09-09 13:03:00 -07:00
u8 cnt , i ;
dprintk ( verbose , DST_NOTICE , 0 , " writing [ " ) ;
for ( i = 0 ; i < len ; i + + )
dprintk ( verbose , DST_NOTICE , 0 , " %02x " , data [ i ] ) ;
dprintk ( verbose , DST_NOTICE , 0 , " ] \n " ) ;
2005-05-16 21:54:41 -07:00
for ( cnt = 0 ; cnt < 2 ; cnt + + ) {
2005-04-16 15:20:36 -07:00
if ( ( err = i2c_transfer ( state - > i2c , & msg , 1 ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x) " , err , len , data [ 0 ] ) ;
2005-05-16 21:54:41 -07:00
dst_error_recovery ( state ) ;
2005-04-16 15:20:36 -07:00
continue ;
} else
break ;
}
2005-05-16 21:54:41 -07:00
if ( cnt > = 2 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " RDC 8820 RESET " ) ;
2005-05-16 21:54:41 -07:00
dst_error_bailout ( state ) ;
return - 1 ;
}
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( write_dst ) ;
2005-04-16 15:20:36 -07:00
2005-09-09 13:03:00 -07:00
int read_dst ( struct dst_state * state , u8 * ret , u8 len )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct i2c_msg msg = {
. addr = state - > config - > demod_address ,
. flags = I2C_M_RD ,
. buf = ret ,
. len = len
} ;
2005-04-16 15:20:36 -07:00
int err ;
int cnt ;
2005-05-16 21:54:41 -07:00
for ( cnt = 0 ; cnt < 2 ; cnt + + ) {
2005-04-16 15:20:36 -07:00
if ( ( err = i2c_transfer ( state - > i2c , & msg , 1 ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x) " , err , len , ret [ 0 ] ) ;
2005-05-16 21:54:41 -07:00
dst_error_recovery ( state ) ;
2005-04-16 15:20:36 -07:00
continue ;
} else
break ;
}
2005-05-16 21:54:41 -07:00
if ( cnt > = 2 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " RDC 8820 RESET " ) ;
2005-05-16 21:54:41 -07:00
dst_error_bailout ( state ) ;
return - 1 ;
}
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " reply is 0x%x " , ret [ 0 ] ) ;
for ( err = 1 ; err < len ; err + + )
dprintk ( verbose , DST_DEBUG , 0 , " 0x%x " , ret [ err ] ) ;
if ( err > 1 )
dprintk ( verbose , DST_DEBUG , 0 , " \n " ) ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( read_dst ) ;
2005-04-16 15:20:36 -07:00
2005-07-07 17:57:50 -07:00
static int dst_set_polarization ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2005-07-07 17:57:50 -07:00
switch ( state - > voltage ) {
2005-09-09 13:03:00 -07:00
case SEC_VOLTAGE_13 : /* Vertical */
dprintk ( verbose , DST_INFO , 1 , " Polarization=[Vertical] " ) ;
state - > tx_tuna [ 8 ] & = ~ 0x40 ;
break ;
case SEC_VOLTAGE_18 : /* Horizontal */
dprintk ( verbose , DST_INFO , 1 , " Polarization=[Horizontal] " ) ;
state - > tx_tuna [ 8 ] | = 0x40 ;
break ;
case SEC_VOLTAGE_OFF :
break ;
2005-07-07 17:57:50 -07:00
}
return 0 ;
}
static int dst_set_freq ( struct dst_state * state , u32 freq )
{
2005-04-16 15:20:36 -07:00
state - > frequency = freq ;
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " set Frequency %u " , freq ) ;
2005-04-16 15:20:36 -07:00
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
freq = freq / 1000 ;
if ( freq < 950 | | freq > 2150 )
return - EINVAL ;
2005-07-07 17:57:50 -07:00
state - > tx_tuna [ 2 ] = ( freq > > 8 ) ;
state - > tx_tuna [ 3 ] = ( u8 ) freq ;
state - > tx_tuna [ 4 ] = 0x01 ;
state - > tx_tuna [ 8 ] & = ~ 0x04 ;
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS ) {
if ( freq < 1531 )
state - > tx_tuna [ 8 ] | = 0x04 ;
}
2005-04-16 15:20:36 -07:00
} else if ( state - > dst_type = = DST_TYPE_IS_TERR ) {
freq = freq / 1000 ;
if ( freq < 137000 | | freq > 858000 )
return - EINVAL ;
2005-07-07 17:57:50 -07:00
state - > tx_tuna [ 2 ] = ( freq > > 16 ) & 0xff ;
state - > tx_tuna [ 3 ] = ( freq > > 8 ) & 0xff ;
state - > tx_tuna [ 4 ] = ( u8 ) freq ;
2005-04-16 15:20:36 -07:00
} else if ( state - > dst_type = = DST_TYPE_IS_CABLE ) {
2005-09-09 13:03:02 -07:00
freq = freq / 1000 ;
2005-07-07 17:57:50 -07:00
state - > tx_tuna [ 2 ] = ( freq > > 16 ) & 0xff ;
state - > tx_tuna [ 3 ] = ( freq > > 8 ) & 0xff ;
state - > tx_tuna [ 4 ] = ( u8 ) freq ;
2006-06-21 10:27:15 -03:00
} else if ( state - > dst_type = = DST_TYPE_IS_ATSC ) {
freq = freq / 1000 ;
if ( freq < 51000 | | freq > 858000 )
return - EINVAL ;
state - > tx_tuna [ 2 ] = ( freq > > 16 ) & 0xff ;
state - > tx_tuna [ 3 ] = ( freq > > 8 ) & 0xff ;
state - > tx_tuna [ 4 ] = ( u8 ) freq ;
state - > tx_tuna [ 5 ] = 0x00 ; /* ATSC */
state - > tx_tuna [ 6 ] = 0x00 ;
if ( state - > dst_hw_cap & DST_TYPE_HAS_ANALOG )
state - > tx_tuna [ 7 ] = 0x00 ; /* Digital */
2005-04-16 15:20:36 -07:00
} else
return - EINVAL ;
2005-09-09 13:03:00 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2011-12-26 15:26:49 -03:00
static int dst_set_bandwidth ( struct dst_state * state , u32 bandwidth )
2005-04-16 15:20:36 -07:00
{
state - > bandwidth = bandwidth ;
if ( state - > dst_type ! = DST_TYPE_IS_TERR )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-04-16 15:20:36 -07:00
switch ( bandwidth ) {
2011-12-26 15:26:49 -03:00
case 6000000 :
2005-09-09 13:03:00 -07:00
if ( state - > dst_hw_cap & DST_TYPE_HAS_CA )
state - > tx_tuna [ 7 ] = 0x06 ;
else {
state - > tx_tuna [ 6 ] = 0x06 ;
state - > tx_tuna [ 7 ] = 0x00 ;
}
break ;
2011-12-26 15:26:49 -03:00
case 7000000 :
2005-09-09 13:03:00 -07:00
if ( state - > dst_hw_cap & DST_TYPE_HAS_CA )
state - > tx_tuna [ 7 ] = 0x07 ;
else {
state - > tx_tuna [ 6 ] = 0x07 ;
state - > tx_tuna [ 7 ] = 0x00 ;
}
break ;
2011-12-26 15:26:49 -03:00
case 8000000 :
2005-09-09 13:03:00 -07:00
if ( state - > dst_hw_cap & DST_TYPE_HAS_CA )
state - > tx_tuna [ 7 ] = 0x08 ;
else {
state - > tx_tuna [ 6 ] = 0x08 ;
state - > tx_tuna [ 7 ] = 0x00 ;
}
break ;
default :
return - EINVAL ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-09-09 13:03:00 -07:00
static int dst_set_inversion ( struct dst_state * state , fe_spectral_inversion_t inversion )
2005-04-16 15:20:36 -07:00
{
state - > inversion = inversion ;
switch ( inversion ) {
2005-09-09 13:03:00 -07:00
case INVERSION_OFF : /* Inversion = Normal */
state - > tx_tuna [ 8 ] & = ~ 0x80 ;
break ;
case INVERSION_ON :
state - > tx_tuna [ 8 ] | = 0x80 ;
break ;
default :
return - EINVAL ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-09-09 13:03:00 -07:00
static int dst_set_fec ( struct dst_state * state , fe_code_rate_t fec )
2005-04-16 15:20:36 -07:00
{
state - > fec = fec ;
return 0 ;
}
2005-09-09 13:03:00 -07:00
static fe_code_rate_t dst_get_fec ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
return state - > fec ;
}
2005-09-09 13:03:00 -07:00
static int dst_set_symbolrate ( struct dst_state * state , u32 srate )
2005-04-16 15:20:36 -07:00
{
u32 symcalc ;
u64 sval ;
state - > symbol_rate = srate ;
if ( state - > dst_type = = DST_TYPE_IS_TERR ) {
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " set symrate %u " , srate ) ;
2005-04-16 15:20:36 -07:00
srate / = 1000 ;
2006-06-21 10:41:37 -03:00
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
if ( state - > type_flags & DST_TYPE_HAS_SYMDIV ) {
sval = srate ;
sval < < = 20 ;
do_div ( sval , 88000 ) ;
symcalc = ( u32 ) sval ;
dprintk ( verbose , DST_INFO , 1 , " set symcalc %u " , symcalc ) ;
state - > tx_tuna [ 5 ] = ( u8 ) ( symcalc > > 12 ) ;
state - > tx_tuna [ 6 ] = ( u8 ) ( symcalc > > 4 ) ;
state - > tx_tuna [ 7 ] = ( u8 ) ( symcalc < < 4 ) ;
} else {
state - > tx_tuna [ 5 ] = ( u8 ) ( srate > > 16 ) & 0x7f ;
state - > tx_tuna [ 6 ] = ( u8 ) ( srate > > 8 ) ;
state - > tx_tuna [ 7 ] = ( u8 ) srate ;
}
state - > tx_tuna [ 8 ] & = ~ 0x20 ;
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS ) {
if ( srate > 8000 )
state - > tx_tuna [ 8 ] | = 0x20 ;
}
} else if ( state - > dst_type = = DST_TYPE_IS_CABLE ) {
dprintk ( verbose , DST_DEBUG , 1 , " %s " , state - > fw_name ) ;
if ( ! strncmp ( state - > fw_name , " DCTNEW " , 6 ) ) {
state - > tx_tuna [ 5 ] = ( u8 ) ( srate > > 8 ) ;
state - > tx_tuna [ 6 ] = ( u8 ) srate ;
state - > tx_tuna [ 7 ] = 0x00 ;
} else if ( ! strncmp ( state - > fw_name , " DCT-CI " , 6 ) ) {
state - > tx_tuna [ 5 ] = 0x00 ;
state - > tx_tuna [ 6 ] = ( u8 ) ( srate > > 8 ) ;
state - > tx_tuna [ 7 ] = ( u8 ) srate ;
}
2005-04-16 15:20:36 -07:00
}
return 0 ;
}
2005-07-07 17:57:50 -07:00
static int dst_set_modulation ( struct dst_state * state , fe_modulation_t modulation )
{
if ( state - > dst_type ! = DST_TYPE_IS_CABLE )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-07-07 17:57:50 -07:00
state - > modulation = modulation ;
switch ( modulation ) {
2005-09-09 13:03:00 -07:00
case QAM_16 :
state - > tx_tuna [ 8 ] = 0x10 ;
break ;
case QAM_32 :
state - > tx_tuna [ 8 ] = 0x20 ;
break ;
case QAM_64 :
state - > tx_tuna [ 8 ] = 0x40 ;
break ;
case QAM_128 :
state - > tx_tuna [ 8 ] = 0x80 ;
break ;
case QAM_256 :
2006-06-21 10:41:37 -03:00
if ( ! strncmp ( state - > fw_name , " DCTNEW " , 6 ) )
state - > tx_tuna [ 8 ] = 0xff ;
else if ( ! strncmp ( state - > fw_name , " DCT-CI " , 6 ) )
state - > tx_tuna [ 8 ] = 0x00 ;
2005-09-09 13:03:00 -07:00
break ;
case QPSK :
case QAM_AUTO :
case VSB_8 :
case VSB_16 :
default :
return - EINVAL ;
2005-07-07 17:57:50 -07:00
}
return 0 ;
}
static fe_modulation_t dst_get_modulation ( struct dst_state * state )
{
return state - > modulation ;
}
2005-09-09 13:03:00 -07:00
u8 dst_check_sum ( u8 * buf , u32 len )
2005-04-16 15:20:36 -07:00
{
u32 i ;
u8 val = 0 ;
if ( ! len )
return 0 ;
for ( i = 0 ; i < len ; i + + ) {
val + = buf [ i ] ;
}
return ( ( ~ val ) + 1 ) ;
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( dst_check_sum ) ;
2005-04-16 15:20:36 -07:00
2006-06-21 10:28:19 -03:00
static void dst_type_flags_print ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2006-06-21 10:28:19 -03:00
u32 type_flags = state - > type_flags ;
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " DST type flags : " ) ;
2006-06-21 10:41:41 -03:00
if ( type_flags & DST_TYPE_HAS_TS188 )
dprintk ( verbose , DST_ERROR , 0 , " 0x%x newtuner " , DST_TYPE_HAS_TS188 ) ;
2006-06-21 10:28:05 -03:00
if ( type_flags & DST_TYPE_HAS_NEWTUNE_2 )
dprintk ( verbose , DST_ERROR , 0 , " 0x%x newtuner 2 " , DST_TYPE_HAS_NEWTUNE_2 ) ;
2005-04-16 15:20:36 -07:00
if ( type_flags & DST_TYPE_HAS_TS204 )
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " 0x%x ts204 " , DST_TYPE_HAS_TS204 ) ;
2006-06-21 10:41:45 -03:00
if ( type_flags & DST_TYPE_HAS_VLF )
dprintk ( verbose , DST_ERROR , 0 , " 0x%x VLF " , DST_TYPE_HAS_VLF ) ;
2005-04-16 15:20:36 -07:00
if ( type_flags & DST_TYPE_HAS_SYMDIV )
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " 0x%x symdiv " , DST_TYPE_HAS_SYMDIV ) ;
2005-05-16 21:54:41 -07:00
if ( type_flags & DST_TYPE_HAS_FW_1 )
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " 0x%x firmware version = 1 " , DST_TYPE_HAS_FW_1 ) ;
2005-05-16 21:54:41 -07:00
if ( type_flags & DST_TYPE_HAS_FW_2 )
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " 0x%x firmware version = 2 " , DST_TYPE_HAS_FW_2 ) ;
2005-05-16 21:54:41 -07:00
if ( type_flags & DST_TYPE_HAS_FW_3 )
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 0 , " 0x%x firmware version = 3 " , DST_TYPE_HAS_FW_3 ) ;
dprintk ( verbose , DST_ERROR , 0 , " \n " ) ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
2006-06-21 10:28:19 -03:00
static int dst_type_print ( struct dst_state * state , u8 type )
2005-04-16 15:20:36 -07:00
{
char * otype ;
switch ( type ) {
case DST_TYPE_IS_SAT :
otype = " satellite " ;
break ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
case DST_TYPE_IS_TERR :
otype = " terrestrial " ;
break ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
case DST_TYPE_IS_CABLE :
otype = " cable " ;
break ;
2005-05-16 21:54:41 -07:00
2006-06-21 10:27:05 -03:00
case DST_TYPE_IS_ATSC :
otype = " atsc " ;
break ;
2005-04-16 15:20:36 -07:00
default :
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " invalid dst type %d " , type ) ;
2005-04-16 15:20:36 -07:00
return - EINVAL ;
}
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " DST type: %s " , otype ) ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
2007-11-05 14:06:31 -03:00
static struct tuner_types tuner_list [ ] = {
2006-06-21 10:27:53 -03:00
{
2006-06-21 10:28:09 -03:00
. tuner_type = TUNER_TYPE_L64724 ,
2006-06-21 10:28:01 -03:00
. tuner_name = " L 64724 " ,
2006-06-21 10:28:09 -03:00
. board_name = " UNKNOWN " ,
. fw_name = " UNKNOWN "
2006-06-21 10:27:53 -03:00
} ,
{
2006-06-21 10:28:09 -03:00
. tuner_type = TUNER_TYPE_STV0299 ,
2006-06-21 10:28:01 -03:00
. tuner_name = " STV 0299 " ,
2006-06-21 10:28:09 -03:00
. board_name = " VP1020 " ,
. fw_name = " DST-MOT "
2006-06-21 10:27:53 -03:00
} ,
{
2006-06-21 10:28:09 -03:00
. tuner_type = TUNER_TYPE_STV0299 ,
. tuner_name = " STV 0299 " ,
. board_name = " VP1020 " ,
. fw_name = " DST-03T "
} ,
{
. tuner_type = TUNER_TYPE_MB86A15 ,
2006-06-21 10:28:01 -03:00
. tuner_name = " MB 86A15 " ,
2006-06-21 10:28:09 -03:00
. board_name = " VP1022 " ,
. fw_name = " DST-03T "
2006-06-21 10:27:53 -03:00
} ,
2006-06-21 10:28:01 -03:00
{
2006-06-21 10:28:09 -03:00
. tuner_type = TUNER_TYPE_MB86A15 ,
. tuner_name = " MB 86A15 " ,
. board_name = " VP1025 " ,
. fw_name = " DST-03T "
} ,
{
. tuner_type = TUNER_TYPE_STV0299 ,
. tuner_name = " STV 0299 " ,
. board_name = " VP1030 " ,
. fw_name = " DST-CI "
} ,
{
. tuner_type = TUNER_TYPE_STV0299 ,
. tuner_name = " STV 0299 " ,
. board_name = " VP1030 " ,
. fw_name = " DSTMCI "
} ,
2006-06-21 10:41:37 -03:00
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP2021 " ,
. fw_name = " DCTNEW "
} ,
2006-06-21 10:28:09 -03:00
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP2030 " ,
. fw_name = " DCT-CI "
} ,
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP2031 " ,
. fw_name = " DCT-CI "
} ,
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP2040 " ,
. fw_name = " DCT-CI "
} ,
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP3020 " ,
. fw_name = " DTTFTA "
} ,
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP3021 " ,
. fw_name = " DTTFTA "
} ,
{
. tuner_type = TUNER_TYPE_TDA10046 ,
. tuner_name = " TDA10046 " ,
. board_name = " VP3040 " ,
. fw_name = " DTT-CI "
} ,
{
. tuner_type = TUNER_TYPE_UNKNOWN ,
. tuner_name = " UNKNOWN " ,
. board_name = " VP3051 " ,
. fw_name = " DTTNXT "
} ,
{
. tuner_type = TUNER_TYPE_NXT200x ,
. tuner_name = " NXT200x " ,
. board_name = " VP3220 " ,
. fw_name = " ATSCDI "
} ,
{
. tuner_type = TUNER_TYPE_NXT200x ,
. tuner_name = " NXT200x " ,
. board_name = " VP3250 " ,
. fw_name = " ATSCAD "
} ,
2006-06-21 10:27:53 -03:00
} ;
2005-05-16 21:54:41 -07:00
/*
Known cards list
Satellite
- - - - - - - - - - - - - - - - - - -
2005-05-16 21:54:42 -07:00
200103 A
2005-05-16 21:54:41 -07:00
VP - 1020 DST - MOT LG ( old ) , TS = 188
VP - 1020 DST - 03 T LG ( new ) , TS = 204
VP - 1022 DST - 03 T LG ( new ) , TS = 204
VP - 1025 DST - 03 T LG ( new ) , TS = 204
VP - 1030 DSTMCI , LG ( new ) , TS = 188
VP - 1032 DSTMCI , LG ( new ) , TS = 188
Cable
- - - - - - - - - - - - - - - - - - -
VP - 2030 DCT - CI , Samsung , TS = 204
VP - 2021 DCT - CI , Unknown , TS = 204
VP - 2031 DCT - CI , Philips , TS = 188
VP - 2040 DCT - CI , Philips , TS = 188 , with CA daughter board
VP - 2040 DCT - CI , Philips , TS = 204 , without CA daughter board
Terrestrial
- - - - - - - - - - - - - - - - - - -
VP - 3050 DTTNXT TS = 188
VP - 3040 DTT - CI , Philips , TS = 188
VP - 3040 DTT - CI , Philips , TS = 204
ATSC
- - - - - - - - - - - - - - - - - - -
VP - 3220 ATSCDI , TS = 188
VP - 3250 ATSCAD , TS = 188
*/
2006-02-27 00:07:55 -03:00
static struct dst_types dst_tlist [ ] = {
2005-05-16 21:54:42 -07:00
{
. device_id = " 200103A " ,
. offset = 0 ,
. dst_type = DST_TYPE_IS_SAT ,
2005-07-07 17:57:50 -07:00
. type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:42 -07:00
} , /* obsolete */
2005-05-16 21:54:41 -07:00
{
. device_id = " DST-020 " ,
. offset = 0 ,
. dst_type = DST_TYPE_IS_SAT ,
. type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} , /* obsolete */
{
. device_id = " DST-030 " ,
. offset = 0 ,
. dst_type = DST_TYPE_IS_SAT ,
2006-06-21 10:41:41 -03:00
. type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} , /* obsolete */
{
. device_id = " DST-03T " ,
. offset = 0 ,
. dst_type = DST_TYPE_IS_SAT ,
. type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 ,
. dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
2006-06-21 10:27:49 -03:00
| DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO ,
2006-06-21 10:27:53 -03:00
. tuner_type = TUNER_TYPE_MULTI
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DST-MOT " ,
. offset = 0 ,
. dst_type = DST_TYPE_IS_SAT ,
. type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} , /* obsolete */
{
. device_id = " DST-CI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_SAT ,
2006-06-21 10:27:40 -03:00
. type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1 ,
2006-06-21 10:27:49 -03:00
. dst_feature = DST_TYPE_HAS_CA ,
. tuner_type = 0
2005-05-16 21:54:43 -07:00
} , /* An OEM board */
2005-05-16 21:54:41 -07:00
{
. device_id = " DSTMCI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_SAT ,
2006-06-21 10:41:45 -03:00
. type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF ,
2005-05-16 21:54:41 -07:00
. dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
2006-06-21 10:27:49 -03:00
| DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC ,
. tuner_type = TUNER_TYPE_MULTI
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DSTFCI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_SAT ,
2006-06-21 10:41:41 -03:00
. type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} , /* unknown to vendor */
{
. device_id = " DCT-CI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_CABLE ,
2006-06-21 10:41:45 -03:00
. type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF ,
2006-06-21 10:27:49 -03:00
. dst_feature = DST_TYPE_HAS_CA ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DCTNEW " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_CABLE ,
2006-06-21 10:41:41 -03:00
. type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DTT-CI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_TERR ,
2006-06-21 10:41:45 -03:00
. type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF ,
2006-06-21 10:27:49 -03:00
. dst_feature = DST_TYPE_HAS_CA ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DTTDIG " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_TERR ,
. type_flags = DST_TYPE_HAS_FW_2 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " DTTNXT " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_TERR ,
. type_flags = DST_TYPE_HAS_FW_2 ,
2006-06-21 10:27:49 -03:00
. dst_feature = DST_TYPE_HAS_ANALOG ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " ATSCDI " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_ATSC ,
. type_flags = DST_TYPE_HAS_FW_2 ,
2006-06-21 10:27:49 -03:00
. dst_feature = 0 ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{
. device_id = " ATSCAD " ,
. offset = 1 ,
. dst_type = DST_TYPE_IS_ATSC ,
2006-06-21 10:27:40 -03:00
. type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD ,
2006-06-21 10:27:49 -03:00
. dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG ,
. tuner_type = 0
2005-05-16 21:54:41 -07:00
} ,
{ }
} ;
2005-09-09 13:03:01 -07:00
static int dst_get_mac ( struct dst_state * state )
{
u8 get_mac [ ] = { 0x00 , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
get_mac [ 7 ] = dst_check_sum ( get_mac , 7 ) ;
if ( dst_command ( state , get_mac , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Unsupported Command " ) ;
return - 1 ;
}
memset ( & state - > mac_address , ' \0 ' , 8 ) ;
memcpy ( & state - > mac_address , & state - > rxbuffer , 6 ) ;
2008-10-27 17:47:26 -07:00
dprintk ( verbose , DST_ERROR , 1 , " MAC Address=[%pM] " , state - > mac_address ) ;
2005-09-09 13:03:01 -07:00
return 0 ;
}
static int dst_fw_ver ( struct dst_state * state )
{
u8 get_ver [ ] = { 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
get_ver [ 7 ] = dst_check_sum ( get_ver , 7 ) ;
if ( dst_command ( state , get_ver , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Unsupported Command " ) ;
return - 1 ;
}
memcpy ( & state - > fw_version , & state - > rxbuffer , 8 ) ;
dprintk ( verbose , DST_ERROR , 1 , " Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x " ,
state - > fw_version [ 0 ] > > 4 , state - > fw_version [ 0 ] & 0x0f ,
state - > fw_version [ 1 ] ,
state - > fw_version [ 5 ] , state - > fw_version [ 6 ] ,
state - > fw_version [ 4 ] , state - > fw_version [ 3 ] , state - > fw_version [ 2 ] ) ;
return 0 ;
}
static int dst_card_type ( struct dst_state * state )
{
2006-06-21 10:28:01 -03:00
int j ;
struct tuner_types * p_tuner_list = NULL ;
2005-09-09 13:03:01 -07:00
u8 get_type [ ] = { 0x00 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
get_type [ 7 ] = dst_check_sum ( get_type , 7 ) ;
if ( dst_command ( state , get_type , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Unsupported Command " ) ;
return - 1 ;
}
memset ( & state - > card_info , ' \0 ' , 8 ) ;
2006-06-21 10:27:57 -03:00
memcpy ( & state - > card_info , & state - > rxbuffer , 7 ) ;
2005-09-09 13:03:01 -07:00
dprintk ( verbose , DST_ERROR , 1 , " Device Model=[%s] " , & state - > card_info [ 0 ] ) ;
2006-06-21 10:28:01 -03:00
for ( j = 0 , p_tuner_list = tuner_list ; j < ARRAY_SIZE ( tuner_list ) ; j + + , p_tuner_list + + ) {
if ( ! strcmp ( & state - > card_info [ 0 ] , p_tuner_list - > board_name ) ) {
state - > tuner_type = p_tuner_list - > tuner_type ;
2006-06-21 10:28:19 -03:00
dprintk ( verbose , DST_ERROR , 1 , " DST has [%s] tuner, tuner type=[%d] " ,
2006-06-21 10:28:01 -03:00
p_tuner_list - > tuner_name , p_tuner_list - > tuner_type ) ;
}
}
2005-09-09 13:03:01 -07:00
return 0 ;
}
static int dst_get_vendor ( struct dst_state * state )
{
u8 get_vendor [ ] = { 0x00 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
get_vendor [ 7 ] = dst_check_sum ( get_vendor , 7 ) ;
if ( dst_command ( state , get_vendor , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Unsupported Command " ) ;
return - 1 ;
}
memset ( & state - > vendor , ' \0 ' , 8 ) ;
2006-06-21 10:27:57 -03:00
memcpy ( & state - > vendor , & state - > rxbuffer , 7 ) ;
2005-09-09 13:03:01 -07:00
dprintk ( verbose , DST_ERROR , 1 , " Vendor=[%s] " , & state - > vendor [ 0 ] ) ;
return 0 ;
}
2005-05-16 21:54:41 -07:00
2006-06-21 10:28:27 -03:00
static void debug_dst_buffer ( struct dst_state * state )
{
int i ;
if ( verbose > 2 ) {
printk ( " %s: [ " , __func__ ) ;
for ( i = 0 ; i < 8 ; i + + )
printk ( " %02x " , state - > rxbuffer [ i ] ) ;
printk ( " ] \n " ) ;
}
}
static int dst_check_stv0299 ( struct dst_state * state )
{
u8 check_stv0299 [ ] = { 0x00 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
check_stv0299 [ 7 ] = dst_check_sum ( check_stv0299 , 7 ) ;
if ( dst_command ( state , check_stv0299 , 8 ) < 0 ) {
dprintk ( verbose , DST_ERROR , 1 , " Cmd=[0x04] failed " ) ;
return - 1 ;
}
debug_dst_buffer ( state ) ;
if ( memcmp ( & check_stv0299 , & state - > rxbuffer , 8 ) ) {
dprintk ( verbose , DST_ERROR , 1 , " Found a STV0299 NIM " ) ;
state - > tuner_type = TUNER_TYPE_STV0299 ;
return 0 ;
}
return - 1 ;
}
static int dst_check_mb86a15 ( struct dst_state * state )
{
u8 check_mb86a15 [ ] = { 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
check_mb86a15 [ 7 ] = dst_check_sum ( check_mb86a15 , 7 ) ;
if ( dst_command ( state , check_mb86a15 , 8 ) < 0 ) {
dprintk ( verbose , DST_ERROR , 1 , " Cmd=[0x10], failed " ) ;
return - 1 ;
}
debug_dst_buffer ( state ) ;
if ( memcmp ( & check_mb86a15 , & state - > rxbuffer , 8 ) < 0 ) {
dprintk ( verbose , DST_ERROR , 1 , " Found a MB86A15 NIM " ) ;
state - > tuner_type = TUNER_TYPE_MB86A15 ;
return 0 ;
}
return - 1 ;
}
2005-11-08 21:35:09 -08:00
static int dst_get_tuner_info ( struct dst_state * state )
{
u8 get_tuner_1 [ ] = { 0x00 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
u8 get_tuner_2 [ ] = { 0x00 , 0x0b , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ;
get_tuner_1 [ 7 ] = dst_check_sum ( get_tuner_1 , 7 ) ;
get_tuner_2 [ 7 ] = dst_check_sum ( get_tuner_2 , 7 ) ;
2006-06-21 10:27:40 -03:00
dprintk ( verbose , DST_ERROR , 1 , " DST TYpe = MULTI FE " ) ;
2005-11-08 21:35:09 -08:00
if ( state - > type_flags & DST_TYPE_HAS_MULTI_FE ) {
2006-06-21 10:27:40 -03:00
if ( dst_command ( state , get_tuner_1 , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Cmd=[0x13], Unsupported " ) ;
2006-06-21 10:41:45 -03:00
goto force ;
2005-11-08 21:35:09 -08:00
}
} else {
2006-06-21 10:27:40 -03:00
if ( dst_command ( state , get_tuner_2 , 8 ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Cmd=[0xb], Unsupported " ) ;
2006-06-21 10:41:45 -03:00
goto force ;
2005-11-08 21:35:09 -08:00
}
}
memcpy ( & state - > board_info , & state - > rxbuffer , 8 ) ;
if ( state - > type_flags & DST_TYPE_HAS_MULTI_FE ) {
2006-06-21 10:27:40 -03:00
dprintk ( verbose , DST_ERROR , 1 , " DST type has TS=188 " ) ;
}
if ( state - > board_info [ 0 ] = = 0xbc ) {
2009-07-21 13:47:46 -03:00
if ( state - > dst_type ! = DST_TYPE_IS_ATSC )
2006-06-21 10:41:41 -03:00
state - > type_flags | = DST_TYPE_HAS_TS188 ;
2006-06-21 10:28:12 -03:00
else
2006-06-21 10:28:05 -03:00
state - > type_flags | = DST_TYPE_HAS_NEWTUNE_2 ;
2006-06-21 10:28:12 -03:00
2006-06-21 10:28:16 -03:00
if ( state - > board_info [ 1 ] = = 0x01 ) {
state - > dst_hw_cap | = DST_TYPE_HAS_DBOARD ;
dprintk ( verbose , DST_ERROR , 1 , " DST has Daughterboard " ) ;
}
2005-11-08 21:35:09 -08:00
}
return 0 ;
2006-06-21 10:41:45 -03:00
force :
if ( ! strncmp ( state - > fw_name , " DCT-CI " , 6 ) ) {
state - > type_flags | = DST_TYPE_HAS_TS204 ;
dprintk ( verbose , DST_ERROR , 1 , " Forcing [%s] to TS188 " , state - > fw_name ) ;
}
return - 1 ;
2005-11-08 21:35:09 -08:00
}
2005-05-16 21:54:41 -07:00
static int dst_get_device_id ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
2005-05-16 21:54:41 -07:00
u8 reply ;
2006-06-21 10:27:53 -03:00
int i , j ;
2006-06-21 10:28:27 -03:00
struct dst_types * p_dst_type = NULL ;
struct tuner_types * p_tuner_list = NULL ;
2006-06-21 10:27:53 -03:00
2005-05-16 21:54:41 -07:00
u8 use_dst_type = 0 ;
u32 use_type_flags = 0 ;
2005-04-16 15:20:36 -07:00
2005-05-16 21:54:41 -07:00
static u8 device_type [ 8 ] = { 0x00 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xff } ;
2005-04-16 15:20:36 -07:00
2006-06-21 10:28:27 -03:00
state - > tuner_type = 0 ;
2005-05-16 21:54:41 -07:00
device_type [ 7 ] = dst_check_sum ( device_type , 7 ) ;
if ( write_dst ( state , device_type , FIXED_COMM ) )
return - 1 ; /* Write failed */
if ( ( dst_pio_disable ( state ) ) < 0 )
return - 1 ;
if ( read_dst ( state , & reply , GET_ACK ) )
return - 1 ; /* Read failure */
if ( reply ! = ACK ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Write not Acknowledged! [Reply=0x%02x] " , reply ) ;
2005-05-16 21:54:41 -07:00
return - 1 ; /* Unack'd write */
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
if ( ! dst_wait_dst_ready ( state , DEVICE_INIT ) )
return - 1 ; /* DST not ready yet */
if ( read_dst ( state , state - > rxbuffer , FIXED_COMM ) )
return - 1 ;
dst_pio_disable ( state ) ;
if ( state - > rxbuffer [ 7 ] ! = dst_check_sum ( state - > rxbuffer , 7 ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Checksum failure! " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ; /* Checksum failure */
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
state - > rxbuffer [ 7 ] = ' \0 ' ;
2005-09-09 13:03:00 -07:00
for ( i = 0 , p_dst_type = dst_tlist ; i < ARRAY_SIZE ( dst_tlist ) ; i + + , p_dst_type + + ) {
2005-05-16 21:54:41 -07:00
if ( ! strncmp ( & state - > rxbuffer [ p_dst_type - > offset ] , p_dst_type - > device_id , strlen ( p_dst_type - > device_id ) ) ) {
use_type_flags = p_dst_type - > type_flags ;
use_dst_type = p_dst_type - > dst_type ;
/* Card capabilities */
state - > dst_hw_cap = p_dst_type - > dst_feature ;
2006-06-21 10:28:19 -03:00
dprintk ( verbose , DST_ERROR , 1 , " Recognise [%s] " , p_dst_type - > device_id ) ;
2006-06-21 10:41:37 -03:00
strncpy ( & state - > fw_name [ 0 ] , p_dst_type - > device_id , 6 ) ;
2006-06-21 10:28:27 -03:00
/* Multiple tuners */
if ( p_dst_type - > tuner_type & TUNER_TYPE_MULTI ) {
2006-06-21 10:28:31 -03:00
switch ( use_dst_type ) {
case DST_TYPE_IS_SAT :
/* STV0299 check */
if ( dst_check_stv0299 ( state ) < 0 ) {
dprintk ( verbose , DST_ERROR , 1 , " Unsupported " ) ;
state - > tuner_type = TUNER_TYPE_MB86A15 ;
}
break ;
default :
break ;
}
2006-06-21 10:28:27 -03:00
if ( dst_check_mb86a15 ( state ) < 0 )
dprintk ( verbose , DST_ERROR , 1 , " Unsupported " ) ;
/* Single tuner */
} else {
2006-06-21 10:27:53 -03:00
state - > tuner_type = p_dst_type - > tuner_type ;
2006-06-21 10:28:27 -03:00
}
for ( j = 0 , p_tuner_list = tuner_list ; j < ARRAY_SIZE ( tuner_list ) ; j + + , p_tuner_list + + ) {
if ( ! ( strncmp ( p_dst_type - > device_id , p_tuner_list - > fw_name , 7 ) ) & &
p_tuner_list - > tuner_type = = state - > tuner_type ) {
dprintk ( verbose , DST_ERROR , 1 , " [%s] has a [%s] " ,
p_dst_type - > device_id , p_tuner_list - > tuner_name ) ;
2006-06-21 10:27:53 -03:00
}
}
2005-04-16 15:20:36 -07:00
break ;
}
}
2005-05-16 21:54:41 -07:00
2007-02-14 22:57:42 -02:00
if ( i > = ARRAY_SIZE ( dst_tlist ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " Unable to recognize %s or %s " , & state - > rxbuffer [ 0 ] , & state - > rxbuffer [ 1 ] ) ;
dprintk ( verbose , DST_ERROR , 1 , " please email linux-dvb@linuxtv.org with this type in " ) ;
2005-04-16 15:20:36 -07:00
use_dst_type = DST_TYPE_IS_SAT ;
use_type_flags = DST_TYPE_HAS_SYMDIV ;
}
2006-06-21 10:28:19 -03:00
dst_type_print ( state , use_dst_type ) ;
2005-04-16 15:20:36 -07:00
state - > type_flags = use_type_flags ;
state - > dst_type = use_dst_type ;
2006-06-21 10:28:19 -03:00
dst_type_flags_print ( state ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-05-16 21:54:41 -07:00
static int dst_probe ( struct dst_state * state )
{
2006-02-07 06:49:14 -02:00
mutex_init ( & state - > dst_mutex ) ;
2006-06-21 10:27:20 -03:00
if ( dst_addons & DST_TYPE_HAS_CA ) {
if ( ( rdc_8820_reset ( state ) ) < 0 ) {
dprintk ( verbose , DST_ERROR , 1 , " RDC 8820 RESET Failed. " ) ;
return - 1 ;
}
2005-05-16 21:54:45 -07:00
msleep ( 4000 ) ;
2006-06-21 10:27:20 -03:00
} else {
2005-05-16 21:54:45 -07:00
msleep ( 100 ) ;
2006-06-21 10:27:20 -03:00
}
2005-05-16 21:54:41 -07:00
if ( ( dst_comm_init ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " DST Initialization Failed. " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-05-16 21:54:43 -07:00
msleep ( 100 ) ;
2005-05-16 21:54:41 -07:00
if ( dst_get_device_id ( state ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " unknown device. " ) ;
2005-05-16 21:54:41 -07:00
return - 1 ;
}
2005-09-09 13:03:01 -07:00
if ( dst_get_mac ( state ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " MAC: Unsupported command " ) ;
}
2005-11-08 21:35:09 -08:00
if ( ( state - > type_flags & DST_TYPE_HAS_MULTI_FE ) | | ( state - > type_flags & DST_TYPE_HAS_FW_BUILD ) ) {
if ( dst_get_tuner_info ( state ) < 0 )
dprintk ( verbose , DST_INFO , 1 , " Tuner: Unsupported command " ) ;
}
2005-11-08 21:35:20 -08:00
if ( state - > type_flags & DST_TYPE_HAS_TS204 ) {
dst_packsize ( state , 204 ) ;
}
2005-09-09 13:03:01 -07:00
if ( state - > type_flags & DST_TYPE_HAS_FW_BUILD ) {
if ( dst_fw_ver ( state ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " FW: Unsupported command " ) ;
return 0 ;
}
if ( dst_card_type ( state ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Card: Unsupported command " ) ;
return 0 ;
}
if ( dst_get_vendor ( state ) < 0 ) {
dprintk ( verbose , DST_INFO , 1 , " Vendor: Unsupported command " ) ;
return 0 ;
}
}
2005-05-16 21:54:41 -07:00
return 0 ;
}
2007-11-05 14:06:31 -03:00
static int dst_command ( struct dst_state * state , u8 * data , u8 len )
2005-04-16 15:20:36 -07:00
{
u8 reply ;
2005-11-08 21:35:36 -08:00
2006-02-07 06:49:14 -02:00
mutex_lock ( & state - > dst_mutex ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_comm_init ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_NOTICE , 1 , " DST Communication Initialization Failed. " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
if ( write_dst ( state , data , len ) ) {
2006-08-08 09:10:18 -03:00
dprintk ( verbose , DST_INFO , 1 , " Trying to recover.. " ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_error_recovery ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " Recovery Failed. " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
2005-11-08 21:35:36 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
if ( ( dst_pio_disable ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " PIO Disable Failed. " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:43 -07:00
if ( state - > type_flags & DST_TYPE_HAS_FW_1 )
2008-09-01 17:32:10 -03:00
mdelay ( 3 ) ;
2005-05-16 21:54:41 -07:00
if ( read_dst ( state , & reply , GET_ACK ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " Trying to recover.. " ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_error_recovery ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Recovery Failed. " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
if ( reply ! = ACK ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " write not acknowledged 0x%02x " , reply ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
if ( len > = 2 & & data [ 0 ] = = 0 & & ( data [ 1 ] = = 1 | | data [ 1 ] = = 3 ) )
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:43 -07:00
if ( state - > type_flags & DST_TYPE_HAS_FW_1 )
2008-09-01 17:32:10 -03:00
mdelay ( 3 ) ;
2005-05-16 21:54:43 -07:00
else
udelay ( 2000 ) ;
2005-05-16 21:54:41 -07:00
if ( ! dst_wait_dst_ready ( state , NO_DELAY ) )
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
if ( read_dst ( state , state - > rxbuffer , FIXED_COMM ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " Trying to recover.. " ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_error_recovery ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " Recovery failed. " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
2005-11-08 21:35:36 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
if ( state - > rxbuffer [ 7 ] ! = dst_check_sum ( state - > rxbuffer , 7 ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " checksum failure " ) ;
2005-11-08 21:35:36 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
2006-02-07 06:49:14 -02:00
mutex_unlock ( & state - > dst_mutex ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
2005-11-08 21:35:36 -08:00
error :
2006-02-07 06:49:14 -02:00
mutex_unlock ( & state - > dst_mutex ) ;
2005-11-08 21:35:36 -08:00
return - EIO ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_get_signal ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
int retval ;
u8 get_signal [ ] = { 0x00 , 0x05 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xfb } ;
2008-04-08 23:20:00 -03:00
//dprintk("%s: Getting Signal strength and other parameters\n", __func__);
2005-04-16 15:20:36 -07:00
if ( ( state - > diseq_flags & ATTEMPT_TUNE ) = = 0 ) {
state - > decode_lock = state - > decode_strength = state - > decode_snr = 0 ;
return 0 ;
}
if ( 0 = = ( state - > diseq_flags & HAS_LOCK ) ) {
state - > decode_lock = state - > decode_strength = state - > decode_snr = 0 ;
return 0 ;
}
if ( time_after_eq ( jiffies , state - > cur_jiff + ( HZ / 5 ) ) ) {
retval = dst_command ( state , get_signal , 8 ) ;
if ( retval < 0 )
return retval ;
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
state - > decode_lock = ( ( state - > rxbuffer [ 6 ] & 0x10 ) = = 0 ) ? 1 : 0 ;
state - > decode_strength = state - > rxbuffer [ 5 ] < < 8 ;
state - > decode_snr = state - > rxbuffer [ 2 ] < < 8 | state - > rxbuffer [ 3 ] ;
} else if ( ( state - > dst_type = = DST_TYPE_IS_TERR ) | | ( state - > dst_type = = DST_TYPE_IS_CABLE ) ) {
state - > decode_lock = ( state - > rxbuffer [ 1 ] ) ? 1 : 0 ;
state - > decode_strength = state - > rxbuffer [ 4 ] < < 8 ;
state - > decode_snr = state - > rxbuffer [ 3 ] < < 8 ;
2006-06-21 10:27:15 -03:00
} else if ( state - > dst_type = = DST_TYPE_IS_ATSC ) {
state - > decode_lock = ( state - > rxbuffer [ 6 ] = = 0x00 ) ? 1 : 0 ;
state - > decode_strength = state - > rxbuffer [ 4 ] < < 8 ;
state - > decode_snr = state - > rxbuffer [ 2 ] < < 8 | state - > rxbuffer [ 3 ] ;
2005-04-16 15:20:36 -07:00
}
state - > cur_jiff = jiffies ;
}
return 0 ;
}
2005-09-09 13:03:00 -07:00
static int dst_tone_power_cmd ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
u8 paket [ 8 ] = { 0x00 , 0x09 , 0xff , 0xff , 0x01 , 0x00 , 0x00 , 0x00 } ;
2006-08-08 09:10:18 -03:00
if ( state - > dst_type ! = DST_TYPE_IS_SAT )
return - EOPNOTSUPP ;
2005-05-28 15:51:51 -07:00
paket [ 4 ] = state - > tx_tuna [ 4 ] ;
2005-05-28 15:51:51 -07:00
paket [ 2 ] = state - > tx_tuna [ 2 ] ;
2005-05-28 15:51:48 -07:00
paket [ 3 ] = state - > tx_tuna [ 3 ] ;
2005-05-16 21:54:41 -07:00
paket [ 7 ] = dst_check_sum ( paket , 7 ) ;
2006-08-08 09:10:18 -03:00
return dst_command ( state , paket , 8 ) ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_get_tuna ( struct dst_state * state )
2005-04-16 15:20:36 -07:00
{
int retval ;
2005-05-16 21:54:41 -07:00
2005-04-16 15:20:36 -07:00
if ( ( state - > diseq_flags & ATTEMPT_TUNE ) = = 0 )
return 0 ;
state - > diseq_flags & = ~ ( HAS_LOCK ) ;
2005-05-16 21:54:41 -07:00
if ( ! dst_wait_dst_ready ( state , NO_DELAY ) )
2005-11-08 21:35:38 -08:00
return - EIO ;
2006-06-21 10:41:45 -03:00
if ( ( state - > type_flags & DST_TYPE_HAS_VLF ) & &
2006-06-21 10:41:37 -03:00
! ( state - > dst_type = = DST_TYPE_IS_ATSC ) )
2005-04-16 15:20:36 -07:00
retval = read_dst ( state , state - > rx_tuna , 10 ) ;
2005-09-09 13:03:00 -07:00
else
2005-05-16 21:54:41 -07:00
retval = read_dst ( state , & state - > rx_tuna [ 2 ] , FIXED_COMM ) ;
2005-04-16 15:20:36 -07:00
if ( retval < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " read not successful " ) ;
2005-11-08 21:35:38 -08:00
return retval ;
2005-04-16 15:20:36 -07:00
}
2006-06-21 10:41:45 -03:00
if ( ( state - > type_flags & DST_TYPE_HAS_VLF ) & &
2010-02-07 14:09:16 -03:00
! ( state - > dst_type = = DST_TYPE_IS_ATSC ) ) {
2006-06-21 10:41:37 -03:00
2005-04-16 15:20:36 -07:00
if ( state - > rx_tuna [ 9 ] ! = dst_check_sum ( & state - > rx_tuna [ 0 ] , 9 ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " checksum failure ? " ) ;
2005-11-08 21:35:38 -08:00
return - EIO ;
2005-04-16 15:20:36 -07:00
}
} else {
if ( state - > rx_tuna [ 9 ] ! = dst_check_sum ( & state - > rx_tuna [ 2 ] , 7 ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " checksum failure? " ) ;
2005-11-08 21:35:38 -08:00
return - EIO ;
2005-04-16 15:20:36 -07:00
}
}
if ( state - > rx_tuna [ 2 ] = = 0 & & state - > rx_tuna [ 3 ] = = 0 )
return 0 ;
2005-11-08 21:35:22 -08:00
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
state - > decode_freq = ( ( state - > rx_tuna [ 2 ] & 0x7f ) < < 8 ) + state - > rx_tuna [ 3 ] ;
} else {
state - > decode_freq = ( ( state - > rx_tuna [ 2 ] & 0x7f ) < < 16 ) + ( state - > rx_tuna [ 3 ] < < 8 ) + state - > rx_tuna [ 4 ] ;
}
state - > decode_freq = state - > decode_freq * 1000 ;
2005-04-16 15:20:36 -07:00
state - > decode_lock = 1 ;
state - > diseq_flags | = HAS_LOCK ;
2005-07-07 17:57:50 -07:00
2005-04-16 15:20:36 -07:00
return 1 ;
}
2005-09-09 13:03:00 -07:00
static int dst_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t voltage ) ;
2005-04-16 15:20:36 -07:00
2005-09-09 13:03:00 -07:00
static int dst_write_tuna ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
int retval ;
u8 reply ;
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_INFO , 1 , " type_flags 0x%x " , state - > type_flags ) ;
2005-04-16 15:20:36 -07:00
state - > decode_freq = 0 ;
state - > decode_lock = state - > decode_strength = state - > decode_snr = 0 ;
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
if ( ! ( state - > diseq_flags & HAS_POWER ) )
dst_set_voltage ( fe , SEC_VOLTAGE_13 ) ;
}
state - > diseq_flags & = ~ ( HAS_LOCK | ATTEMPT_TUNE ) ;
2006-02-07 06:49:14 -02:00
mutex_lock ( & state - > dst_mutex ) ;
2005-05-16 21:54:41 -07:00
if ( ( dst_comm_init ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " DST Communication initialization failed. " ) ;
2005-11-08 21:35:38 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
2006-06-21 10:41:37 -03:00
// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
2006-06-21 10:41:45 -03:00
if ( ( state - > type_flags & DST_TYPE_HAS_VLF ) & &
2006-06-21 10:41:37 -03:00
( ! ( state - > dst_type = = DST_TYPE_IS_ATSC ) ) ) {
2005-04-16 15:20:36 -07:00
state - > tx_tuna [ 9 ] = dst_check_sum ( & state - > tx_tuna [ 0 ] , 9 ) ;
retval = write_dst ( state , & state - > tx_tuna [ 0 ] , 10 ) ;
} else {
state - > tx_tuna [ 9 ] = dst_check_sum ( & state - > tx_tuna [ 2 ] , 7 ) ;
2005-05-16 21:54:41 -07:00
retval = write_dst ( state , & state - > tx_tuna [ 2 ] , FIXED_COMM ) ;
2005-04-16 15:20:36 -07:00
}
if ( retval < 0 ) {
2005-05-16 21:54:41 -07:00
dst_pio_disable ( state ) ;
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " write not successful " ) ;
2005-11-08 21:35:38 -08:00
goto werr ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
if ( ( dst_pio_disable ( state ) ) < 0 ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " DST PIO disable failed ! " ) ;
2005-11-08 21:35:38 -08:00
goto error ;
2005-05-16 21:54:41 -07:00
}
if ( ( read_dst ( state , & reply , GET_ACK ) < 0 ) ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " read verify not successful. " ) ;
2005-11-08 21:35:38 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
if ( reply ! = ACK ) {
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_DEBUG , 1 , " write not acknowledged 0x%02x " , reply ) ;
2005-11-08 21:35:38 -08:00
goto error ;
2005-04-16 15:20:36 -07:00
}
state - > diseq_flags | = ATTEMPT_TUNE ;
2005-11-08 21:35:38 -08:00
retval = dst_get_tuna ( state ) ;
werr :
2006-02-07 06:49:14 -02:00
mutex_unlock ( & state - > dst_mutex ) ;
2005-11-08 21:35:38 -08:00
return retval ;
2005-05-16 21:54:41 -07:00
2005-11-08 21:35:38 -08:00
error :
2006-02-07 06:49:14 -02:00
mutex_unlock ( & state - > dst_mutex ) ;
2005-11-08 21:35:38 -08:00
return - EIO ;
2005-04-16 15:20:36 -07:00
}
/*
* line22k0 0x00 , 0x09 , 0x00 , 0xff , 0x01 , 0x00 , 0x00 , 0x00
* line22k1 0x00 , 0x09 , 0x01 , 0xff , 0x01 , 0x00 , 0x00 , 0x00
* line22k2 0x00 , 0x09 , 0x02 , 0xff , 0x01 , 0x00 , 0x00 , 0x00
* tone 0x00 , 0x09 , 0xff , 0x00 , 0x01 , 0x00 , 0x00 , 0x00
* data 0x00 , 0x09 , 0xff , 0x01 , 0x01 , 0x00 , 0x00 , 0x00
* power_off 0x00 , 0x09 , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00
* power_on 0x00 , 0x09 , 0xff , 0xff , 0x01 , 0x00 , 0x00 , 0x00
* Diseqc 1 0x00 , 0x08 , 0x04 , 0xe0 , 0x10 , 0x38 , 0xf0 , 0xec
* Diseqc 2 0x00 , 0x08 , 0x04 , 0xe0 , 0x10 , 0x38 , 0xf4 , 0xe8
* Diseqc 3 0x00 , 0x08 , 0x04 , 0xe0 , 0x10 , 0x38 , 0xf8 , 0xe4
* Diseqc 4 0x00 , 0x08 , 0x04 , 0xe0 , 0x10 , 0x38 , 0xfc , 0xe0
*/
2005-09-09 13:03:00 -07:00
static int dst_set_diseqc ( struct dvb_frontend * fe , struct dvb_diseqc_master_cmd * cmd )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
u8 paket [ 8 ] = { 0x00 , 0x08 , 0x04 , 0xe0 , 0x10 , 0x38 , 0xf0 , 0xec } ;
2005-05-28 15:51:52 -07:00
if ( state - > dst_type ! = DST_TYPE_IS_SAT )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2006-06-21 18:28:13 -03:00
if ( cmd - > msg_len > 0 & & cmd - > msg_len < 5 )
memcpy ( & paket [ 3 ] , cmd - > msg , cmd - > msg_len ) ;
else if ( cmd - > msg_len = = 5 & & state - > dst_hw_cap & DST_TYPE_HAS_DISEQC5 )
memcpy ( & paket [ 2 ] , cmd - > msg , cmd - > msg_len ) ;
else
2005-04-16 15:20:36 -07:00
return - EINVAL ;
paket [ 7 ] = dst_check_sum ( & paket [ 0 ] , 7 ) ;
2006-08-08 09:10:18 -03:00
return dst_command ( state , paket , 8 ) ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t voltage )
2005-04-16 15:20:36 -07:00
{
2006-08-08 09:10:18 -03:00
int need_cmd , retval = 0 ;
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
state - > voltage = voltage ;
2005-05-28 15:51:52 -07:00
if ( state - > dst_type ! = DST_TYPE_IS_SAT )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-04-16 15:20:36 -07:00
need_cmd = 0 ;
2005-05-16 21:54:41 -07:00
2005-09-09 13:03:00 -07:00
switch ( voltage ) {
case SEC_VOLTAGE_13 :
case SEC_VOLTAGE_18 :
if ( ( state - > diseq_flags & HAS_POWER ) = = 0 )
2005-04-16 15:20:36 -07:00
need_cmd = 1 ;
2005-09-09 13:03:00 -07:00
state - > diseq_flags | = HAS_POWER ;
state - > tx_tuna [ 4 ] = 0x01 ;
break ;
case SEC_VOLTAGE_OFF :
need_cmd = 1 ;
state - > diseq_flags & = ~ ( HAS_POWER | HAS_LOCK | ATTEMPT_TUNE ) ;
state - > tx_tuna [ 4 ] = 0x00 ;
break ;
default :
return - EINVAL ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
2005-05-16 21:54:41 -07:00
if ( need_cmd )
2006-08-08 09:10:18 -03:00
retval = dst_tone_power_cmd ( state ) ;
2005-05-16 21:54:41 -07:00
2006-08-08 09:10:18 -03:00
return retval ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_set_tone ( struct dvb_frontend * fe , fe_sec_tone_mode_t tone )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
state - > tone = tone ;
2005-05-28 15:51:52 -07:00
if ( state - > dst_type ! = DST_TYPE_IS_SAT )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-04-16 15:20:36 -07:00
switch ( tone ) {
2005-09-09 13:03:00 -07:00
case SEC_TONE_OFF :
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS )
state - > tx_tuna [ 2 ] = 0x00 ;
else
state - > tx_tuna [ 2 ] = 0xff ;
break ;
2005-05-16 21:54:41 -07:00
2005-09-09 13:03:00 -07:00
case SEC_TONE_ON :
state - > tx_tuna [ 2 ] = 0x02 ;
break ;
default :
return - EINVAL ;
2005-04-16 15:20:36 -07:00
}
2006-08-08 09:10:18 -03:00
return dst_tone_power_cmd ( state ) ;
2005-04-16 15:20:36 -07:00
}
2005-05-28 15:51:48 -07:00
static int dst_send_burst ( struct dvb_frontend * fe , fe_sec_mini_cmd_t minicmd )
{
struct dst_state * state = fe - > demodulator_priv ;
2005-05-28 15:51:52 -07:00
if ( state - > dst_type ! = DST_TYPE_IS_SAT )
2006-08-08 09:10:18 -03:00
return - EOPNOTSUPP ;
2005-05-28 15:51:48 -07:00
state - > minicmd = minicmd ;
switch ( minicmd ) {
2005-09-09 13:03:00 -07:00
case SEC_MINI_A :
state - > tx_tuna [ 3 ] = 0x02 ;
break ;
case SEC_MINI_B :
state - > tx_tuna [ 3 ] = 0xff ;
break ;
2005-05-28 15:51:48 -07:00
}
2006-08-08 09:10:18 -03:00
return dst_tone_power_cmd ( state ) ;
2005-05-28 15:51:48 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_init ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
static u8 sat_tuna_188 [ ] = { 0x09 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x00 , 0x73 , 0x21 , 0x00 , 0x00 } ;
static u8 sat_tuna_204 [ ] = { 0x00 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x55 , 0xbd , 0x50 , 0x00 , 0x00 } ;
static u8 ter_tuna_188 [ ] = { 0x09 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 } ;
static u8 ter_tuna_204 [ ] = { 0x00 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 } ;
2006-06-21 10:41:45 -03:00
static u8 cab_tuna_188 [ ] = { 0x09 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 } ;
static u8 cab_tuna_204 [ ] = { 0x00 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 } ;
2006-06-21 10:28:05 -03:00
static u8 atsc_tuner [ ] = { 0x00 , 0x00 , 0x03 , 0xb6 , 0x01 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 } ;
2005-09-09 13:03:00 -07:00
2005-07-07 17:57:50 -07:00
state - > inversion = INVERSION_OFF ;
2005-04-16 15:20:36 -07:00
state - > voltage = SEC_VOLTAGE_13 ;
state - > tone = SEC_TONE_OFF ;
state - > diseq_flags = 0 ;
state - > k22 = 0x02 ;
2011-12-26 15:26:49 -03:00
state - > bandwidth = 7000000 ;
2005-04-16 15:20:36 -07:00
state - > cur_jiff = jiffies ;
2005-09-09 13:03:00 -07:00
if ( state - > dst_type = = DST_TYPE_IS_SAT )
2006-06-21 10:41:45 -03:00
memcpy ( state - > tx_tuna , ( ( state - > type_flags & DST_TYPE_HAS_VLF ) ? sat_tuna_188 : sat_tuna_204 ) , sizeof ( sat_tuna_204 ) ) ;
2005-09-09 13:03:00 -07:00
else if ( state - > dst_type = = DST_TYPE_IS_TERR )
2006-06-21 10:41:45 -03:00
memcpy ( state - > tx_tuna , ( ( state - > type_flags & DST_TYPE_HAS_VLF ) ? ter_tuna_188 : ter_tuna_204 ) , sizeof ( ter_tuna_204 ) ) ;
2005-09-09 13:03:00 -07:00
else if ( state - > dst_type = = DST_TYPE_IS_CABLE )
2006-06-21 10:41:45 -03:00
memcpy ( state - > tx_tuna , ( ( state - > type_flags & DST_TYPE_HAS_VLF ) ? cab_tuna_188 : cab_tuna_204 ) , sizeof ( cab_tuna_204 ) ) ;
2006-06-21 10:27:46 -03:00
else if ( state - > dst_type = = DST_TYPE_IS_ATSC )
2006-06-21 10:28:05 -03:00
memcpy ( state - > tx_tuna , atsc_tuner , sizeof ( atsc_tuner ) ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2005-09-09 13:03:00 -07:00
static int dst_read_status ( struct dvb_frontend * fe , fe_status_t * status )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
* status = 0 ;
if ( state - > diseq_flags & HAS_LOCK ) {
2005-07-07 17:57:50 -07:00
// dst_get_signal(state); // don't require(?) to ask MCU
2005-04-16 15:20:36 -07:00
if ( state - > decode_lock )
* status | = FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI ;
}
return 0 ;
}
2005-09-09 13:03:00 -07:00
static int dst_read_signal_strength ( struct dvb_frontend * fe , u16 * strength )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
2006-08-08 09:10:18 -03:00
int retval = dst_get_signal ( state ) ;
2005-04-16 15:20:36 -07:00
* strength = state - > decode_strength ;
2006-08-08 09:10:18 -03:00
return retval ;
2005-04-16 15:20:36 -07:00
}
2005-09-09 13:03:00 -07:00
static int dst_read_snr ( struct dvb_frontend * fe , u16 * snr )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
2006-08-08 09:10:18 -03:00
int retval = dst_get_signal ( state ) ;
2005-04-16 15:20:36 -07:00
* snr = state - > decode_snr ;
2006-08-08 09:10:18 -03:00
return retval ;
2005-04-16 15:20:36 -07:00
}
2011-12-26 15:26:49 -03:00
static int dst_set_frontend ( struct dvb_frontend * fe )
2006-06-21 10:27:26 -03:00
{
2011-12-26 15:26:49 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2006-08-08 09:10:18 -03:00
int retval = - EINVAL ;
2006-06-21 10:27:26 -03:00
struct dst_state * state = fe - > demodulator_priv ;
if ( p ! = NULL ) {
2006-08-08 09:10:18 -03:00
retval = dst_set_freq ( state , p - > frequency ) ;
if ( retval ! = 0 )
return retval ;
2006-06-21 10:27:26 -03:00
dprintk ( verbose , DST_DEBUG , 1 , " Set Frequency=[%d] " , p - > frequency ) ;
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS )
dst_set_inversion ( state , p - > inversion ) ;
2011-12-26 15:26:49 -03:00
dst_set_fec ( state , p - > fec_inner ) ;
dst_set_symbolrate ( state , p - > symbol_rate ) ;
2006-06-21 10:27:26 -03:00
dst_set_polarization ( state ) ;
2011-12-26 15:26:49 -03:00
dprintk ( verbose , DST_DEBUG , 1 , " Set Symbolrate=[%d] " , p - > symbol_rate ) ;
2006-06-21 10:27:26 -03:00
} else if ( state - > dst_type = = DST_TYPE_IS_TERR )
2011-12-26 15:26:49 -03:00
dst_set_bandwidth ( state , p - > bandwidth_hz ) ;
2006-06-21 10:27:26 -03:00
else if ( state - > dst_type = = DST_TYPE_IS_CABLE ) {
2011-12-26 15:26:49 -03:00
dst_set_fec ( state , p - > fec_inner ) ;
dst_set_symbolrate ( state , p - > symbol_rate ) ;
dst_set_modulation ( state , p - > modulation ) ;
2006-06-21 10:27:26 -03:00
}
2006-08-08 09:10:18 -03:00
retval = dst_write_tuna ( fe ) ;
2006-06-21 10:27:26 -03:00
}
2006-08-08 09:10:18 -03:00
return retval ;
2006-06-21 10:27:26 -03:00
}
static int dst_tune_frontend ( struct dvb_frontend * fe ,
2011-12-26 17:48:33 -03:00
bool re_tune ,
2006-01-09 15:25:07 -02:00
unsigned int mode_flags ,
2007-07-16 09:27:20 -03:00
unsigned int * delay ,
2006-01-09 15:25:07 -02:00
fe_status_t * status )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2011-12-26 17:48:33 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-04-16 15:20:36 -07:00
2011-12-26 17:48:33 -03:00
if ( re_tune ) {
2006-01-09 15:25:07 -02:00
dst_set_freq ( state , p - > frequency ) ;
dprintk ( verbose , DST_DEBUG , 1 , " Set Frequency=[%d] " , p - > frequency ) ;
2005-05-16 21:54:41 -07:00
2006-01-09 15:25:07 -02:00
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS )
dst_set_inversion ( state , p - > inversion ) ;
2011-12-26 17:48:33 -03:00
dst_set_fec ( state , p - > fec_inner ) ;
dst_set_symbolrate ( state , p - > symbol_rate ) ;
2006-01-09 15:25:07 -02:00
dst_set_polarization ( state ) ;
2011-12-26 17:48:33 -03:00
dprintk ( verbose , DST_DEBUG , 1 , " Set Symbolrate=[%d] " , p - > symbol_rate ) ;
2006-01-09 15:25:07 -02:00
} else if ( state - > dst_type = = DST_TYPE_IS_TERR )
2011-12-26 17:48:33 -03:00
dst_set_bandwidth ( state , p - > bandwidth_hz ) ;
2006-01-09 15:25:07 -02:00
else if ( state - > dst_type = = DST_TYPE_IS_CABLE ) {
2011-12-26 17:48:33 -03:00
dst_set_fec ( state , p - > fec_inner ) ;
dst_set_symbolrate ( state , p - > symbol_rate ) ;
dst_set_modulation ( state , p - > modulation ) ;
2006-01-09 15:25:07 -02:00
}
dst_write_tuna ( fe ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-09 15:25:07 -02:00
if ( ! ( mode_flags & FE_TUNE_MODE_ONESHOT ) )
dst_read_status ( fe , status ) ;
* delay = HZ / 10 ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
2006-06-21 10:27:26 -03:00
static int dst_get_tuning_algo ( struct dvb_frontend * fe )
{
2009-01-27 16:29:44 -03:00
return dst_algo ? DVBFE_ALGO_HW : DVBFE_ALGO_SW ;
2006-06-21 10:27:26 -03:00
}
[media] dvb: don't require a parameter for get_frontend
Just like set_frontend, use the dvb cache properties for get_frontend.
This is more consistent, as both functions are now symetric. Also,
at the places get_frontend is called, it makes sense to update the
cache.
Most of this patch were generated by this small perl script:
while (<>) { $file .= $_; }
if ($file =~ m/\.get_frontend\s*=\s*([\d\w_]+)/) {
my $get = $1;
$file =~ s/($get)(\s*\([^\,\)]+)\,\s*struct\s+dtv_frontend_properties\s*\*\s*([_\d\w]+)\)\s*\{/\1\2)\n{\n\tstruct dtv_frontend_properties *\3 = &fe->dtv_property_cache;/g;
}
print $file;
Of course, the changes at dvb_frontend.[ch] were made by hand,
as well as the changes on a few other places, where get_frontend()
is called internally inside the driver.
On some places, get_frontend() were just a void function. Those
occurrences were removed, as the DVB core handles such cases.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-12-30 11:30:21 -03:00
static int dst_get_frontend ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
[media] dvb: don't require a parameter for get_frontend
Just like set_frontend, use the dvb cache properties for get_frontend.
This is more consistent, as both functions are now symetric. Also,
at the places get_frontend is called, it makes sense to update the
cache.
Most of this patch were generated by this small perl script:
while (<>) { $file .= $_; }
if ($file =~ m/\.get_frontend\s*=\s*([\d\w_]+)/) {
my $get = $1;
$file =~ s/($get)(\s*\([^\,\)]+)\,\s*struct\s+dtv_frontend_properties\s*\*\s*([_\d\w]+)\)\s*\{/\1\2)\n{\n\tstruct dtv_frontend_properties *\3 = &fe->dtv_property_cache;/g;
}
print $file;
Of course, the changes at dvb_frontend.[ch] were made by hand,
as well as the changes on a few other places, where get_frontend()
is called internally inside the driver.
On some places, get_frontend() were just a void function. Those
occurrences were removed, as the DVB core handles such cases.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-12-30 11:30:21 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2005-04-16 15:20:36 -07:00
p - > frequency = state - > decode_freq ;
if ( state - > dst_type = = DST_TYPE_IS_SAT ) {
2005-07-07 17:57:50 -07:00
if ( state - > type_flags & DST_TYPE_HAS_OBS_REGS )
p - > inversion = state - > inversion ;
2011-12-26 15:26:49 -03:00
p - > symbol_rate = state - > symbol_rate ;
p - > fec_inner = dst_get_fec ( state ) ;
2005-04-16 15:20:36 -07:00
} else if ( state - > dst_type = = DST_TYPE_IS_TERR ) {
2011-12-26 15:26:49 -03:00
p - > bandwidth_hz = state - > bandwidth ;
2005-04-16 15:20:36 -07:00
} else if ( state - > dst_type = = DST_TYPE_IS_CABLE ) {
2011-12-26 15:26:49 -03:00
p - > symbol_rate = state - > symbol_rate ;
p - > fec_inner = dst_get_fec ( state ) ;
p - > modulation = dst_get_modulation ( state ) ;
2005-04-16 15:20:36 -07:00
}
return 0 ;
}
2005-09-09 13:03:00 -07:00
static void dst_release ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
2005-09-09 13:03:00 -07:00
struct dst_state * state = fe - > demodulator_priv ;
2006-08-08 15:48:08 -03:00
if ( state - > dst_ca ) {
dvb_unregister_device ( state - > dst_ca ) ;
2008-04-29 21:38:46 -03:00
# ifdef CONFIG_MEDIA_ATTACH
2006-08-08 15:48:08 -03:00
symbol_put ( dst_ca_attach ) ;
# endif
}
2005-04-16 15:20:36 -07:00
kfree ( state ) ;
}
static struct dvb_frontend_ops dst_dvbt_ops ;
static struct dvb_frontend_ops dst_dvbs_ops ;
static struct dvb_frontend_ops dst_dvbc_ops ;
2006-06-21 10:27:05 -03:00
static struct dvb_frontend_ops dst_atsc_ops ;
2005-04-16 15:20:36 -07:00
2005-09-09 13:03:00 -07:00
struct dst_state * dst_attach ( struct dst_state * state , struct dvb_adapter * dvb_adapter )
2005-04-16 15:20:36 -07:00
{
2005-05-16 21:54:41 -07:00
/* check if the ASIC is there */
if ( dst_probe ( state ) < 0 ) {
2005-11-07 01:01:31 -08:00
kfree ( state ) ;
2005-05-16 21:54:41 -07:00
return NULL ;
}
2005-04-16 15:20:36 -07:00
/* determine settings based on type */
2006-05-14 05:01:31 -03:00
/* create dvb_frontend */
2005-04-16 15:20:36 -07:00
switch ( state - > dst_type ) {
case DST_TYPE_IS_TERR :
2006-05-14 05:01:31 -03:00
memcpy ( & state - > frontend . ops , & dst_dvbt_ops , sizeof ( struct dvb_frontend_ops ) ) ;
2005-04-16 15:20:36 -07:00
break ;
case DST_TYPE_IS_CABLE :
2006-05-14 05:01:31 -03:00
memcpy ( & state - > frontend . ops , & dst_dvbc_ops , sizeof ( struct dvb_frontend_ops ) ) ;
2005-04-16 15:20:36 -07:00
break ;
case DST_TYPE_IS_SAT :
2006-05-14 05:01:31 -03:00
memcpy ( & state - > frontend . ops , & dst_dvbs_ops , sizeof ( struct dvb_frontend_ops ) ) ;
2005-04-16 15:20:36 -07:00
break ;
2006-06-21 10:27:05 -03:00
case DST_TYPE_IS_ATSC :
memcpy ( & state - > frontend . ops , & dst_atsc_ops , sizeof ( struct dvb_frontend_ops ) ) ;
break ;
2005-04-16 15:20:36 -07:00
default :
2005-09-09 13:03:00 -07:00
dprintk ( verbose , DST_ERROR , 1 , " unknown DST type. please report to the LinuxTV.org DVB mailinglist. " ) ;
2005-11-07 01:01:31 -08:00
kfree ( state ) ;
2005-05-16 21:54:41 -07:00
return NULL ;
2005-04-16 15:20:36 -07:00
}
state - > frontend . demodulator_priv = state ;
2005-05-16 21:54:41 -07:00
return state ; /* Manu (DST is a card not a frontend) */
2005-04-16 15:20:36 -07:00
}
2005-05-16 21:54:41 -07:00
EXPORT_SYMBOL ( dst_attach ) ;
2005-04-16 15:20:36 -07:00
static struct dvb_frontend_ops dst_dvbt_ops = {
2011-12-26 15:26:49 -03:00
. delsys = { SYS_DVBT } ,
2005-04-16 15:20:36 -07:00
. info = {
. name = " DST DVB-T " ,
. type = FE_OFDM ,
. frequency_min = 137000000 ,
. frequency_max = 858000000 ,
. frequency_stepsize = 166667 ,
2010-07-27 05:48:08 -03:00
. caps = FE_CAN_FEC_AUTO |
FE_CAN_QAM_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO
2005-04-16 15:20:36 -07:00
} ,
. release = dst_release ,
. init = dst_init ,
2006-06-21 10:27:26 -03:00
. tune = dst_tune_frontend ,
2011-12-26 15:26:49 -03:00
. set_frontend = dst_set_frontend ,
. get_frontend = dst_get_frontend ,
2006-06-21 10:27:36 -03:00
. get_frontend_algo = dst_get_tuning_algo ,
2005-04-16 15:20:36 -07:00
. read_status = dst_read_status ,
. read_signal_strength = dst_read_signal_strength ,
. read_snr = dst_read_snr ,
} ;
static struct dvb_frontend_ops dst_dvbs_ops = {
2011-12-26 15:26:49 -03:00
. delsys = { SYS_DVBS } ,
2005-04-16 15:20:36 -07:00
. info = {
. name = " DST DVB-S " ,
. type = FE_QPSK ,
. frequency_min = 950000 ,
. frequency_max = 2150000 ,
. frequency_stepsize = 1000 , /* kHz for QPSK frontends */
. frequency_tolerance = 29500 ,
. symbol_rate_min = 1000000 ,
. symbol_rate_max = 45000000 ,
/* . symbol_rate_tolerance = ???,*/
. caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
} ,
. release = dst_release ,
. init = dst_init ,
2006-06-21 10:27:26 -03:00
. tune = dst_tune_frontend ,
2011-12-26 15:26:49 -03:00
. set_frontend = dst_set_frontend ,
. get_frontend = dst_get_frontend ,
2006-06-21 10:27:36 -03:00
. get_frontend_algo = dst_get_tuning_algo ,
2005-04-16 15:20:36 -07:00
. read_status = dst_read_status ,
. read_signal_strength = dst_read_signal_strength ,
. read_snr = dst_read_snr ,
2005-05-28 15:51:48 -07:00
. diseqc_send_burst = dst_send_burst ,
2005-04-16 15:20:36 -07:00
. diseqc_send_master_cmd = dst_set_diseqc ,
. set_voltage = dst_set_voltage ,
. set_tone = dst_set_tone ,
} ;
static struct dvb_frontend_ops dst_dvbc_ops = {
2011-12-26 15:26:49 -03:00
. delsys = { SYS_DVBC_ANNEX_A } ,
2005-04-16 15:20:36 -07:00
. info = {
. name = " DST DVB-C " ,
. type = FE_QAM ,
. frequency_stepsize = 62500 ,
. frequency_min = 51000000 ,
. frequency_max = 858000000 ,
. symbol_rate_min = 1000000 ,
. symbol_rate_max = 45000000 ,
2010-02-07 14:09:16 -03:00
. caps = FE_CAN_FEC_AUTO |
FE_CAN_QAM_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256
2005-04-16 15:20:36 -07:00
} ,
. release = dst_release ,
. init = dst_init ,
2006-06-21 10:27:26 -03:00
. tune = dst_tune_frontend ,
2011-12-26 15:26:49 -03:00
. set_frontend = dst_set_frontend ,
. get_frontend = dst_get_frontend ,
2006-06-21 10:27:36 -03:00
. get_frontend_algo = dst_get_tuning_algo ,
2005-04-16 15:20:36 -07:00
. read_status = dst_read_status ,
. read_signal_strength = dst_read_signal_strength ,
. read_snr = dst_read_snr ,
} ;
2006-06-21 10:27:05 -03:00
static struct dvb_frontend_ops dst_atsc_ops = {
. info = {
. name = " DST ATSC " ,
. type = FE_ATSC ,
. frequency_stepsize = 62500 ,
. frequency_min = 510000000 ,
. frequency_max = 858000000 ,
. symbol_rate_min = 1000000 ,
. symbol_rate_max = 45000000 ,
. caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
} ,
. release = dst_release ,
. init = dst_init ,
2006-06-21 10:27:26 -03:00
. tune = dst_tune_frontend ,
2011-12-26 15:26:49 -03:00
. set_frontend = dst_set_frontend ,
. get_frontend = dst_get_frontend ,
2006-06-21 10:27:36 -03:00
. get_frontend_algo = dst_get_tuning_algo ,
2006-06-21 10:27:05 -03:00
. read_status = dst_read_status ,
. read_signal_strength = dst_read_signal_strength ,
. read_snr = dst_read_snr ,
} ;
MODULE_DESCRIPTION ( " DST DVB-S/T/C/ATSC Combo Frontend driver " ) ;
2005-05-16 21:54:41 -07:00
MODULE_AUTHOR ( " Jamie Honan, Manu Abraham " ) ;
2005-04-16 15:20:36 -07:00
MODULE_LICENSE ( " GPL " ) ;