2005-05-16 21:54:10 -07:00
/*
* This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII ( b ) / III
*
* flexcop - fe - tuner . c - methods for attaching a frontend and controlling DiSEqC .
*
* see flexcop . c for copyright information .
*/
2008-04-22 14:46:16 -03:00
# include <media/tuner.h>
2005-05-16 21:54:10 -07:00
# include "flexcop.h"
# include "stv0299.h"
# include "mt352.h"
2006-01-23 09:52:39 -02:00
# include "nxt200x.h"
2005-06-23 22:02:41 -07:00
# include "bcm3510.h"
2005-05-16 21:54:10 -07:00
# include "stv0297.h"
# include "mt312.h"
2005-11-08 21:35:32 -08:00
# include "lgdt330x.h"
# include "dvb-pll.h"
2008-04-22 14:46:16 -03:00
# include "tuner-simple.h"
2005-05-16 21:54:10 -07:00
2008-04-13 15:49:22 -03:00
# include "s5h1420.h"
# include "itd1000.h"
2008-03-29 21:28:07 -03:00
# include "cx24123.h"
# include "cx24113.h"
# include "isl6421.h"
2005-05-16 21:54:10 -07:00
/* lnb control */
static int flexcop_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t voltage )
{
struct flexcop_device * fc = fe - > dvb - > priv ;
flexcop_ibi_value v ;
deb_tuner ( " polarity/voltage = %u \n " , voltage ) ;
v = fc - > read_ibi_reg ( fc , misc_204 ) ;
switch ( voltage ) {
case SEC_VOLTAGE_OFF :
v . misc_204 . ACPI1_sig = 1 ;
break ;
case SEC_VOLTAGE_13 :
v . misc_204 . ACPI1_sig = 0 ;
v . misc_204 . LNB_L_H_sig = 0 ;
break ;
case SEC_VOLTAGE_18 :
v . misc_204 . ACPI1_sig = 0 ;
v . misc_204 . LNB_L_H_sig = 1 ;
break ;
default :
err ( " unknown SEC_VOLTAGE value " ) ;
return - EINVAL ;
}
return fc - > write_ibi_reg ( fc , misc_204 , v ) ;
}
static int flexcop_sleep ( struct dvb_frontend * fe )
{
struct flexcop_device * fc = fe - > dvb - > priv ;
/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
if ( fc - > fe_sleep )
return fc - > fe_sleep ( fe ) ;
/* v.misc_204.ACPI3_sig = 1;
fc - > write_ibi_reg ( fc , misc_204 , v ) ; */
return 0 ;
}
static int flexcop_set_tone ( struct dvb_frontend * fe , fe_sec_tone_mode_t tone )
{
/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
struct flexcop_device * fc = fe - > dvb - > priv ;
flexcop_ibi_value v ;
u16 ax ;
v . raw = 0 ;
deb_tuner ( " tone = %u \n " , tone ) ;
switch ( tone ) {
case SEC_TONE_ON :
ax = 0x01ff ;
break ;
case SEC_TONE_OFF :
ax = 0 ;
break ;
default :
err ( " unknown SEC_TONE value " ) ;
return - EINVAL ;
}
v . lnb_switch_freq_200 . LNB_CTLPrescaler_sig = 1 ; /* divide by 2 */
2005-05-16 21:54:19 -07:00
v . lnb_switch_freq_200 . LNB_CTLHighCount_sig = ax ;
v . lnb_switch_freq_200 . LNB_CTLLowCount_sig = ax = = 0 ? 0x1ff : ax ;
2005-05-16 21:54:10 -07:00
return fc - > write_ibi_reg ( fc , lnb_switch_freq_200 , v ) ;
}
static void flexcop_diseqc_send_bit ( struct dvb_frontend * fe , int data )
{
flexcop_set_tone ( fe , SEC_TONE_ON ) ;
udelay ( data ? 500 : 1000 ) ;
flexcop_set_tone ( fe , SEC_TONE_OFF ) ;
udelay ( data ? 1000 : 500 ) ;
}
static void flexcop_diseqc_send_byte ( struct dvb_frontend * fe , int data )
{
int i , par = 1 , d ;
for ( i = 7 ; i > = 0 ; i - - ) {
d = ( data > > i ) & 1 ;
par ^ = d ;
flexcop_diseqc_send_bit ( fe , d ) ;
}
flexcop_diseqc_send_bit ( fe , par ) ;
}
static int flexcop_send_diseqc_msg ( struct dvb_frontend * fe , int len , u8 * msg , unsigned long burst )
{
int i ;
flexcop_set_tone ( fe , SEC_TONE_OFF ) ;
mdelay ( 16 ) ;
for ( i = 0 ; i < len ; i + + )
flexcop_diseqc_send_byte ( fe , msg [ i ] ) ;
mdelay ( 16 ) ;
if ( burst ! = - 1 ) {
if ( burst )
flexcop_diseqc_send_byte ( fe , 0xff ) ;
else {
flexcop_set_tone ( fe , SEC_TONE_ON ) ;
2008-09-01 17:32:10 -03:00
mdelay ( 12 ) ;
udelay ( 500 ) ;
2005-05-16 21:54:10 -07:00
flexcop_set_tone ( fe , SEC_TONE_OFF ) ;
}
msleep ( 20 ) ;
}
return 0 ;
}
static int flexcop_diseqc_send_master_cmd ( struct dvb_frontend * fe , struct dvb_diseqc_master_cmd * cmd )
{
return flexcop_send_diseqc_msg ( fe , cmd - > msg_len , cmd - > msg , 0 ) ;
}
static int flexcop_diseqc_send_burst ( struct dvb_frontend * fe , fe_sec_mini_cmd_t minicmd )
{
return flexcop_send_diseqc_msg ( fe , 0 , NULL , minicmd ) ;
}
/* dvb-s stv0299 */
static int samsung_tbmu24112_set_symbol_rate ( struct dvb_frontend * fe , u32 srate , u32 ratio )
{
u8 aclk = 0 ;
u8 bclk = 0 ;
if ( srate < 1500000 ) { aclk = 0xb7 ; bclk = 0x47 ; }
else if ( srate < 3000000 ) { aclk = 0xb7 ; bclk = 0x4b ; }
else if ( srate < 7000000 ) { aclk = 0xb7 ; bclk = 0x4f ; }
else if ( srate < 14000000 ) { aclk = 0xb7 ; bclk = 0x53 ; }
else if ( srate < 30000000 ) { aclk = 0xb6 ; bclk = 0x53 ; }
else if ( srate < 45000000 ) { aclk = 0xb4 ; bclk = 0x51 ; }
stv0299_writereg ( fe , 0x13 , aclk ) ;
stv0299_writereg ( fe , 0x14 , bclk ) ;
stv0299_writereg ( fe , 0x1f , ( ratio > > 16 ) & 0xff ) ;
stv0299_writereg ( fe , 0x20 , ( ratio > > 8 ) & 0xff ) ;
stv0299_writereg ( fe , 0x21 , ( ratio ) & 0xf0 ) ;
return 0 ;
}
2006-04-18 17:47:12 -03:00
static int samsung_tbmu24112_tuner_set_params ( struct dvb_frontend * fe , struct dvb_frontend_parameters * params )
2005-05-16 21:54:10 -07:00
{
u8 buf [ 4 ] ;
u32 div ;
struct i2c_msg msg = { . addr = 0x61 , . flags = 0 , . buf = buf , . len = sizeof ( buf ) } ;
2006-04-18 17:47:12 -03:00
struct flexcop_device * fc = fe - > dvb - > priv ;
2005-05-16 21:54:10 -07:00
div = params - > frequency / 125 ;
buf [ 0 ] = ( div > > 8 ) & 0x7f ;
buf [ 1 ] = div & 0xff ;
buf [ 2 ] = 0x84 ; /* 0xC4 */
buf [ 3 ] = 0x08 ;
2008-03-29 20:49:57 -03:00
if ( params - > frequency < 1500000 )
buf [ 3 ] | = 0x10 ;
2005-05-16 21:54:10 -07:00
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2008-03-29 20:49:57 -03:00
if ( i2c_transfer ( & fc - > fc_i2c_adap [ 0 ] . i2c_adap , & msg , 1 ) ! = 1 )
2005-05-16 21:54:10 -07:00
return - EIO ;
return 0 ;
}
static u8 samsung_tbmu24112_inittab [ ] = {
0x01 , 0x15 ,
0x02 , 0x30 ,
0x03 , 0x00 ,
0x04 , 0x7D ,
0x05 , 0x35 ,
0x06 , 0x02 ,
0x07 , 0x00 ,
0x08 , 0xC3 ,
0x0C , 0x00 ,
0x0D , 0x81 ,
0x0E , 0x23 ,
0x0F , 0x12 ,
0x10 , 0x7E ,
0x11 , 0x84 ,
0x12 , 0xB9 ,
0x13 , 0x88 ,
0x14 , 0x89 ,
0x15 , 0xC9 ,
0x16 , 0x00 ,
0x17 , 0x5C ,
0x18 , 0x00 ,
0x19 , 0x00 ,
0x1A , 0x00 ,
0x1C , 0x00 ,
0x1D , 0x00 ,
0x1E , 0x00 ,
0x1F , 0x3A ,
0x20 , 0x2E ,
0x21 , 0x80 ,
0x22 , 0xFF ,
0x23 , 0xC1 ,
0x28 , 0x00 ,
0x29 , 0x1E ,
0x2A , 0x14 ,
0x2B , 0x0F ,
0x2C , 0x09 ,
0x2D , 0x05 ,
0x31 , 0x1F ,
0x32 , 0x19 ,
0x33 , 0xFE ,
0x34 , 0x93 ,
0xff , 0xff ,
} ;
static struct stv0299_config samsung_tbmu24112_config = {
. demod_address = 0x68 ,
. inittab = samsung_tbmu24112_inittab ,
. mclk = 88000000UL ,
. invert = 0 ,
. skip_reinit = 0 ,
2008-04-20 22:13:37 -03:00
. lock_output = STV0299_LOCKOUTPUT_LK ,
2005-05-16 21:54:10 -07:00
. volt13_op0_op1 = STV0299_VOLT13_OP1 ,
. min_delay_ms = 100 ,
. set_symbol_rate = samsung_tbmu24112_set_symbol_rate ,
} ;
/* dvb-t mt352 */
static int samsung_tdtc9251dh0_demod_init ( struct dvb_frontend * fe )
{
static u8 mt352_clock_config [ ] = { 0x89 , 0x18 , 0x2d } ;
static u8 mt352_reset [ ] = { 0x50 , 0x80 } ;
static u8 mt352_adc_ctl_1_cfg [ ] = { 0x8E , 0x40 } ;
static u8 mt352_agc_cfg [ ] = { 0x67 , 0x28 , 0xa1 } ;
static u8 mt352_capt_range_cfg [ ] = { 0x75 , 0x32 } ;
mt352_write ( fe , mt352_clock_config , sizeof ( mt352_clock_config ) ) ;
udelay ( 2000 ) ;
mt352_write ( fe , mt352_reset , sizeof ( mt352_reset ) ) ;
mt352_write ( fe , mt352_adc_ctl_1_cfg , sizeof ( mt352_adc_ctl_1_cfg ) ) ;
mt352_write ( fe , mt352_agc_cfg , sizeof ( mt352_agc_cfg ) ) ;
mt352_write ( fe , mt352_capt_range_cfg , sizeof ( mt352_capt_range_cfg ) ) ;
return 0 ;
}
2006-04-18 17:47:12 -03:00
static int samsung_tdtc9251dh0_calc_regs ( struct dvb_frontend * fe , struct dvb_frontend_parameters * params , u8 * pllbuf , int buf_len )
2005-05-16 21:54:10 -07:00
{
u32 div ;
unsigned char bs = 0 ;
2006-04-18 17:47:12 -03:00
if ( buf_len < 5 )
return - EINVAL ;
2005-05-16 21:54:10 -07:00
# define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
div = ( ( ( params - > frequency + 83333 ) * 3 ) / 500000 ) + IF_FREQUENCYx6 ;
if ( params - > frequency > = 48000000 & & params - > frequency < = 154000000 ) bs = 0x09 ;
if ( params - > frequency > = 161000000 & & params - > frequency < = 439000000 ) bs = 0x0a ;
if ( params - > frequency > = 447000000 & & params - > frequency < = 863000000 ) bs = 0x08 ;
2006-04-18 17:47:12 -03:00
pllbuf [ 0 ] = 0x61 ;
2005-05-16 21:54:10 -07:00
pllbuf [ 1 ] = div > > 8 ;
pllbuf [ 2 ] = div & 0xff ;
pllbuf [ 3 ] = 0xcc ;
pllbuf [ 4 ] = bs ;
2006-04-18 17:47:12 -03:00
return 5 ;
2005-05-16 21:54:10 -07:00
}
static struct mt352_config samsung_tdtc9251dh0_config = {
. demod_address = 0x0f ,
2005-06-23 22:02:41 -07:00
. demod_init = samsung_tdtc9251dh0_demod_init ,
2005-05-16 21:54:10 -07:00
} ;
2005-06-23 22:02:41 -07:00
static int flexcop_fe_request_firmware ( struct dvb_frontend * fe , const struct firmware * * fw , char * name )
2005-05-16 21:54:10 -07:00
{
struct flexcop_device * fc = fe - > dvb - > priv ;
return request_firmware ( fw , name , fc - > dev ) ;
}
2005-11-08 21:35:32 -08:00
static struct lgdt330x_config air2pc_atsc_hd5000_config = {
. demod_address = 0x59 ,
. demod_chip = LGDT3303 ,
. serial_mpeg = 0x04 ,
. clock_polarity_flip = 1 ,
} ;
2006-01-23 09:52:39 -02:00
static struct nxt200x_config samsung_tbmv_config = {
2005-06-23 22:02:41 -07:00
. demod_address = 0x0a ,
} ;
static struct bcm3510_config air2pc_atsc_first_gen_config = {
. demod_address = 0x0f ,
. request_firmware = flexcop_fe_request_firmware ,
2005-05-16 21:54:10 -07:00
} ;
2006-04-18 17:47:12 -03:00
static int skystar23_samsung_tbdu18132_tuner_set_params ( struct dvb_frontend * fe , struct dvb_frontend_parameters * params )
2005-05-16 21:54:10 -07:00
{
u8 buf [ 4 ] ;
u32 div ;
struct i2c_msg msg = { . addr = 0x61 , . flags = 0 , . buf = buf , . len = sizeof ( buf ) } ;
struct flexcop_device * fc = fe - > dvb - > priv ;
div = ( params - > frequency + ( 125 / 2 ) ) / 125 ;
buf [ 0 ] = ( div > > 8 ) & 0x7f ;
buf [ 1 ] = ( div > > 0 ) & 0xff ;
buf [ 2 ] = 0x84 | ( ( div > > 10 ) & 0x60 ) ;
buf [ 3 ] = 0x80 ;
if ( params - > frequency < 1550000 )
buf [ 3 ] | = 0x02 ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2008-03-29 20:49:57 -03:00
if ( i2c_transfer ( & fc - > fc_i2c_adap [ 0 ] . i2c_adap , & msg , 1 ) ! = 1 )
2005-05-16 21:54:10 -07:00
return - EIO ;
return 0 ;
}
static struct mt312_config skystar23_samsung_tbdu18132_config = {
. demod_address = 0x0e ,
} ;
2006-05-29 12:31:44 -03:00
static int alps_tdee4_stv0297_tuner_set_params ( struct dvb_frontend * fe ,
struct dvb_frontend_parameters * fep )
2006-04-18 17:47:12 -03:00
{
struct flexcop_device * fc = fe - > dvb - > priv ;
u8 buf [ 4 ] ;
u16 div ;
int ret ;
/* 62.5 kHz * 10 */
# define REF_FREQ 625
# define FREQ_OFFSET 36125
div = ( ( fep - > frequency / 1000 + FREQ_OFFSET ) * 10 ) / REF_FREQ ; // 4 MHz = 4000 KHz
buf [ 0 ] = ( u8 ) ( div > > 8 ) & 0x7f ;
buf [ 1 ] = ( u8 ) div & 0xff ;
/* F(osc) = N * Reference Freq. (62.5 kHz)
* byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
* byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
* byte 4 : 1 * * AGD R3 R2 R1 R0
* byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
* AGD = 1 , R3 R2 R1 R0 = 0 1 0 1 = > byte 4 = 1 * * 10101 = 0x95 */
buf [ 2 ] = 0x95 ;
// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
// 47 - 153 0 * 0 0 0 0 0 1 0x01
// 153 - 430 0 * 0 0 0 0 1 0 0x02
// 430 - 822 0 * 0 0 1 0 0 0 0x08
// 822 - 862 1 * 0 0 1 0 0 0 0x88
if ( fep - > frequency < = 153000000 ) buf [ 3 ] = 0x01 ;
else if ( fep - > frequency < = 430000000 ) buf [ 3 ] = 0x02 ;
else if ( fep - > frequency < = 822000000 ) buf [ 3 ] = 0x08 ;
else buf [ 3 ] = 0x88 ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
2006-12-20 11:10:35 -03:00
fe - > ops . i2c_gate_ctrl ( fe , 0 ) ;
2006-04-18 17:47:12 -03:00
deb_tuner ( " tuner buffer for %d Hz: %x %x %x %x \n " , fep - > frequency , buf [ 0 ] , buf [ 1 ] , buf [ 2 ] , buf [ 3 ] ) ;
2008-03-29 20:49:57 -03:00
ret = fc - > i2c_request ( & fc - > fc_i2c_adap [ 2 ] ,
FC_WRITE , 0x61 , buf [ 0 ] , & buf [ 1 ] , 3 ) ;
2006-04-18 17:47:12 -03:00
deb_tuner ( " tuner write returned: %d \n " , ret ) ;
2008-03-29 20:49:57 -03:00
return ret ;
2006-04-18 17:47:12 -03:00
}
2005-09-09 13:03:07 -07:00
static u8 alps_tdee4_stv0297_inittab [ ] = {
0x80 , 0x01 ,
0x80 , 0x00 ,
0x81 , 0x01 ,
0x81 , 0x00 ,
2006-12-20 11:10:35 -03:00
0x00 , 0x48 ,
0x01 , 0x58 ,
2005-09-09 13:03:07 -07:00
0x03 , 0x00 ,
0x04 , 0x00 ,
0x07 , 0x00 ,
0x08 , 0x00 ,
0x30 , 0xff ,
2006-12-20 11:10:35 -03:00
0x31 , 0x9d ,
2005-09-09 13:03:07 -07:00
0x32 , 0xff ,
0x33 , 0x00 ,
2006-12-20 11:10:35 -03:00
0x34 , 0x29 ,
0x35 , 0x55 ,
0x36 , 0x80 ,
0x37 , 0x6e ,
0x38 , 0x9c ,
0x40 , 0x1a ,
0x41 , 0xfe ,
0x42 , 0x33 ,
2005-09-09 13:03:07 -07:00
0x43 , 0x00 ,
0x44 , 0xff ,
0x45 , 0x00 ,
0x46 , 0x00 ,
0x49 , 0x04 ,
2006-12-20 11:10:35 -03:00
0x4a , 0x51 ,
2005-09-09 13:03:07 -07:00
0x4b , 0xf8 ,
0x52 , 0x30 ,
2006-12-20 11:10:35 -03:00
0x53 , 0x06 ,
0x59 , 0x06 ,
0x5a , 0x5e ,
0x5b , 0x04 ,
0x61 , 0x49 ,
0x62 , 0x0a ,
2005-09-09 13:03:07 -07:00
0x70 , 0xff ,
2006-12-20 11:10:35 -03:00
0x71 , 0x04 ,
2005-09-09 13:03:07 -07:00
0x72 , 0x00 ,
0x73 , 0x00 ,
0x74 , 0x0c ,
2006-12-20 11:10:35 -03:00
0x80 , 0x20 ,
2005-09-09 13:03:07 -07:00
0x81 , 0x00 ,
2006-12-20 11:10:35 -03:00
0x82 , 0x30 ,
2005-09-09 13:03:07 -07:00
0x83 , 0x00 ,
0x84 , 0x04 ,
2006-12-20 11:10:35 -03:00
0x85 , 0x22 ,
0x86 , 0x08 ,
0x87 , 0x1b ,
0x88 , 0x00 ,
2005-09-09 13:03:07 -07:00
0x89 , 0x00 ,
2006-12-20 11:10:35 -03:00
0x90 , 0x00 ,
0x91 , 0x04 ,
0xa0 , 0x86 ,
2005-09-09 13:03:07 -07:00
0xa1 , 0x00 ,
0xa2 , 0x00 ,
0xb0 , 0x91 ,
0xb1 , 0x0b ,
2006-12-20 11:10:35 -03:00
0xc0 , 0x5b ,
0xc1 , 0x10 ,
2005-09-09 13:03:07 -07:00
0xc2 , 0x12 ,
2006-12-20 11:10:35 -03:00
0xd0 , 0x02 ,
2005-09-09 13:03:07 -07:00
0xd1 , 0x00 ,
0xd2 , 0x00 ,
0xd3 , 0x00 ,
2006-12-20 11:10:35 -03:00
0xd4 , 0x02 ,
2005-09-09 13:03:07 -07:00
0xd5 , 0x00 ,
0xde , 0x00 ,
2006-12-20 11:10:35 -03:00
0xdf , 0x01 ,
2005-09-09 13:03:07 -07:00
0xff , 0xff ,
} ;
2005-05-16 21:54:10 -07:00
static struct stv0297_config alps_tdee4_stv0297_config = {
. demod_address = 0x1c ,
2005-09-09 13:03:07 -07:00
. inittab = alps_tdee4_stv0297_inittab ,
2005-05-16 21:54:10 -07:00
// .invert = 1,
// .pll_set = alps_tdee4_stv0297_pll_set,
} ;
2008-03-29 21:28:07 -03:00
2008-04-13 15:49:22 -03:00
/* SkyStar2 rev2.7 (a/u) */
static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
. demod_address = 0x53 ,
. invert = 1 ,
. repeated_start_workaround = 1 ,
2008-09-06 13:31:58 -03:00
. serial_mpeg = 1 ,
2008-04-13 15:49:22 -03:00
} ;
static struct itd1000_config skystar2_rev2_7_itd1000_config = {
. i2c_address = 0x61 ,
} ;
/* SkyStar2 rev2.8 */
2008-03-29 21:28:07 -03:00
static struct cx24123_config skystar2_rev2_8_cx24123_config = {
. demod_address = 0x55 ,
. dont_use_pll = 1 ,
. agc_callback = cx24113_agc_callback ,
} ;
static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
. i2c_addr = 0x54 ,
. xtal_khz = 10111 ,
} ;
2005-05-16 21:54:10 -07:00
/* try to figure out the frontend, each card/box can have on of the following list */
int flexcop_frontend_init ( struct flexcop_device * fc )
{
2006-01-09 15:25:23 -02:00
struct dvb_frontend_ops * ops ;
2008-03-29 20:49:57 -03:00
struct i2c_adapter * i2c = & fc - > fc_i2c_adap [ 0 ] . i2c_adap ;
2008-03-29 21:28:07 -03:00
struct i2c_adapter * i2c_tuner ;
2008-04-13 15:49:22 -03:00
/* enable no_base_addr - no repeated start when reading */
fc - > fc_i2c_adap [ 0 ] . no_base_addr = 1 ;
fc - > fe = dvb_attach ( s5h1420_attach , & skystar2_rev2_7_s5h1420_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
flexcop_ibi_value r108 ;
i2c_tuner = s5h1420_get_tuner_i2c_adapter ( fc - > fe ) ;
ops = & fc - > fe - > ops ;
fc - > fe_sleep = ops - > sleep ;
ops - > sleep = flexcop_sleep ;
fc - > dev_type = FC_SKY_REV27 ;
/* enable no_base_addr - no repeated start when reading */
fc - > fc_i2c_adap [ 2 ] . no_base_addr = 1 ;
if ( dvb_attach ( isl6421_attach , fc - > fe , & fc - > fc_i2c_adap [ 2 ] . i2c_adap , 0x08 , 1 , 1 ) = = NULL )
err ( " ISL6421 could NOT be attached " ) ;
else
info ( " ISL6421 successfully attached " ) ;
/* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */
r108 . raw = 0x00000506 ;
fc - > write_ibi_reg ( fc , tw_sm_c_108 , r108 ) ;
if ( i2c_tuner ) {
if ( dvb_attach ( itd1000_attach , fc - > fe , i2c_tuner , & skystar2_rev2_7_itd1000_config ) = = NULL )
err ( " ITD1000 could NOT be attached " ) ;
else
info ( " ITD1000 successfully attached " ) ;
}
goto fe_found ;
}
fc - > fc_i2c_adap [ 0 ] . no_base_addr = 0 ; /* for the next devices we need it again */
2008-03-29 21:28:07 -03:00
/* try the sky v2.8 (cx24123, isl6421) */
fc - > fe = dvb_attach ( cx24123_attach ,
& skystar2_rev2_8_cx24123_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
i2c_tuner = cx24123_get_tuner_i2c_adapter ( fc - > fe ) ;
if ( i2c_tuner ! = NULL ) {
if ( dvb_attach ( cx24113_attach , fc - > fe ,
& skystar2_rev2_8_cx24113_config ,
i2c_tuner ) = = NULL )
err ( " CX24113 could NOT be attached " ) ;
else
info ( " CX24113 successfully attached " ) ;
}
fc - > dev_type = FC_SKY_REV28 ;
fc - > fc_i2c_adap [ 2 ] . no_base_addr = 1 ;
if ( dvb_attach ( isl6421_attach , fc - > fe ,
& fc - > fc_i2c_adap [ 2 ] . i2c_adap , 0x08 , 0 , 0 ) = = NULL )
err ( " ISL6421 could NOT be attached " ) ;
else
info ( " ISL6421 successfully attached " ) ;
/* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
* IR - receiver ( PIC16F818 ) - but the card has no input for
* that ? ? ? */
goto fe_found ;
}
2006-01-09 15:25:23 -02:00
2005-05-16 21:54:10 -07:00
/* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
2008-03-29 20:49:57 -03:00
fc - > fe = dvb_attach ( stv0299_attach , & samsung_tbmu24112_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
2006-05-14 05:01:31 -03:00
ops = & fc - > fe - > ops ;
2006-01-09 15:25:23 -02:00
2006-04-18 17:47:12 -03:00
ops - > tuner_ops . set_params = samsung_tbmu24112_tuner_set_params ;
2006-01-09 15:25:23 -02:00
ops - > set_voltage = flexcop_set_voltage ;
2005-05-16 21:54:10 -07:00
2008-03-29 20:49:57 -03:00
fc - > fe_sleep = ops - > sleep ;
ops - > sleep = flexcop_sleep ;
2009-03-29 07:46:58 -03:00
fc - > dev_type = FC_SKY_REV26 ;
2008-03-29 20:49:57 -03:00
goto fe_found ;
}
2005-05-16 21:54:10 -07:00
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
2008-03-29 20:49:57 -03:00
fc - > fe = dvb_attach ( mt352_attach , & samsung_tdtc9251dh0_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
2009-03-29 07:46:58 -03:00
fc - > dev_type = FC_AIR_DVBT ;
2006-05-14 05:01:31 -03:00
fc - > fe - > ops . tuner_ops . calc_regs = samsung_tdtc9251dh0_calc_regs ;
2008-03-29 20:49:57 -03:00
goto fe_found ;
}
2005-06-23 22:02:41 -07:00
/* try the air atsc 2nd generation (nxt2002) */
2008-03-29 20:49:57 -03:00
fc - > fe = dvb_attach ( nxt200x_attach , & samsung_tbmv_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
fc - > dev_type = FC_AIR_ATSC2 ;
2007-06-12 16:10:51 -03:00
dvb_attach ( dvb_pll_attach , fc - > fe , 0x61 , NULL , DVB_PLL_SAMSUNG_TBMV ) ;
2008-03-29 20:49:57 -03:00
goto fe_found ;
}
fc - > fe = dvb_attach ( lgdt330x_attach , & air2pc_atsc_hd5000_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
fc - > dev_type = FC_AIR_ATSC3 ;
dvb_attach ( simple_tuner_attach , fc - > fe , i2c , 0x61 ,
TUNER_LG_TDVS_H06XF ) ;
goto fe_found ;
}
2005-06-23 22:02:41 -07:00
/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
2008-03-29 20:49:57 -03:00
fc - > fe = dvb_attach ( bcm3510_attach , & air2pc_atsc_first_gen_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
fc - > dev_type = FC_AIR_ATSC1 ;
goto fe_found ;
}
2005-05-16 21:54:10 -07:00
/* try the cable dvb (stv0297) */
2008-12-01 06:59:37 -03:00
fc - > fc_i2c_adap [ 0 ] . no_base_addr = 1 ;
2008-03-29 20:49:57 -03:00
fc - > fe = dvb_attach ( stv0297_attach , & alps_tdee4_stv0297_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
fc - > dev_type = FC_CABLE ;
2006-05-14 05:01:31 -03:00
fc - > fe - > ops . tuner_ops . set_params = alps_tdee4_stv0297_tuner_set_params ;
2008-03-29 20:49:57 -03:00
goto fe_found ;
}
2008-12-01 06:59:37 -03:00
fc - > fc_i2c_adap [ 0 ] . no_base_addr = 0 ;
2008-03-29 20:49:57 -03:00
2005-05-16 21:54:10 -07:00
/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
2008-04-30 12:21:04 -03:00
fc - > fe = dvb_attach ( mt312_attach ,
2008-03-29 20:49:57 -03:00
& skystar23_samsung_tbdu18132_config , i2c ) ;
if ( fc - > fe ! = NULL ) {
2006-05-14 05:01:31 -03:00
ops = & fc - > fe - > ops ;
2006-01-09 15:25:23 -02:00
2006-04-18 17:47:12 -03:00
ops - > tuner_ops . set_params = skystar23_samsung_tbdu18132_tuner_set_params ;
2006-01-09 15:25:23 -02:00
ops - > diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd ;
ops - > diseqc_send_burst = flexcop_diseqc_send_burst ;
ops - > set_tone = flexcop_set_tone ;
ops - > set_voltage = flexcop_set_voltage ;
2005-05-16 21:54:10 -07:00
2006-01-09 15:25:23 -02:00
fc - > fe_sleep = ops - > sleep ;
ops - > sleep = flexcop_sleep ;
2005-05-16 21:54:10 -07:00
2009-03-29 07:46:58 -03:00
fc - > dev_type = FC_SKY_REV23 ;
2008-03-29 20:49:57 -03:00
goto fe_found ;
2005-05-16 21:54:10 -07:00
}
2008-03-29 20:49:57 -03:00
err ( " no frontend driver found for this B2C2/FlexCop adapter " ) ;
return - ENODEV ;
fe_found :
info ( " found '%s' . " , fc - > fe - > ops . info . name ) ;
if ( dvb_register_frontend ( & fc - > dvb_adapter , fc - > fe ) ) {
err ( " frontend registration failed! " ) ;
ops = & fc - > fe - > ops ;
if ( ops - > release ! = NULL )
ops - > release ( fc - > fe ) ;
fc - > fe = NULL ;
return - EINVAL ;
2005-05-16 21:54:10 -07:00
}
fc - > init_state | = FC_STATE_FE_INIT ;
return 0 ;
}
void flexcop_frontend_exit ( struct flexcop_device * fc )
{
2006-08-08 09:10:08 -03:00
if ( fc - > init_state & FC_STATE_FE_INIT ) {
2005-05-16 21:54:10 -07:00
dvb_unregister_frontend ( fc - > fe ) ;
2006-08-08 09:10:09 -03:00
dvb_frontend_detach ( fc - > fe ) ;
2006-08-08 09:10:08 -03:00
}
2005-05-16 21:54:10 -07:00
fc - > init_state & = ~ FC_STATE_FE_INIT ;
}