2008-05-17 23:05:48 -03:00
/*
* DVB USB Linux driver for Anysee E30 DVB - C & DVB - T USB2 .0 receiver
*
* Copyright ( C ) 2007 Antti Palosaari < crope @ iki . fi >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
* TODO :
* - add smart card reader support for Conditional Access ( CA )
*
* Card reader in Anysee is nothing more than ISO 7816 card reader .
* There is no hardware CAM in any Anysee device sold .
* In my understanding it should be implemented by making own module
2008-06-11 11:43:19 -03:00
* for ISO 7816 card reader , like dvb_ca_en50221 is implemented . This
* module registers serial interface that can be used to communicate
2008-05-17 23:05:48 -03:00
* with any ISO 7816 smart card .
*
* Any help according to implement serial smart card reader support
* is highly welcome !
*/
# include "anysee.h"
2012-06-14 04:56:09 -03:00
# include "dvb-pll.h"
2008-05-17 23:05:48 -03:00
# include "tda1002x.h"
# include "mt352.h"
# include "mt352_priv.h"
# include "zl10353.h"
2011-04-10 20:14:50 -03:00
# include "tda18212.h"
2011-04-27 21:11:59 -03:00
# include "cx24116.h"
2011-04-29 13:55:02 -03:00
# include "stv0900.h"
# include "stv6110.h"
2011-04-27 21:11:59 -03:00
# include "isl6423.h"
2011-08-12 18:29:46 -03:00
# include "cxd2820r.h"
2008-05-17 23:05:48 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2008-10-29 21:16:04 -03:00
static DEFINE_MUTEX ( anysee_usb_mutex ) ;
2008-05-17 23:05:48 -03:00
static int anysee_ctrl_msg ( struct dvb_usb_device * d , u8 * sbuf , u8 slen ,
u8 * rbuf , u8 rlen )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2012-01-21 11:19:29 -03:00
int act_len , ret , i ;
2008-05-17 23:05:48 -03:00
u8 buf [ 64 ] ;
memcpy ( & buf [ 0 ] , sbuf , slen ) ;
buf [ 60 ] = state - > seq + + ;
2012-06-14 04:56:09 -03:00
mutex_lock ( & anysee_usb_mutex ) ;
2008-05-17 23:05:48 -03:00
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: >>> %*ph \n " , __func__ , slen , buf ) ;
2011-09-29 20:28:53 -03:00
2008-05-17 23:05:48 -03:00
/* We need receive one message more after dvb_usb_generic_rw due
to weird transaction flow , which is 1 x send + 2 x receive . */
2012-06-20 20:27:42 -03:00
ret = dvb_usbv2_generic_rw ( d , buf , sizeof ( buf ) , buf , sizeof ( buf ) ) ;
2012-01-21 11:19:29 -03:00
if ( ret )
goto error_unlock ;
/* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
* ( EPIPE , Broken pipe ) . Function supports currently msleep ( ) as a
* parameter but I would not like to use it , since according to
* Documentation / timers / timers - howto . txt it should not be used such
* short , under < 20 ms , sleeps . Repeating failed message would be
* better choice as not to add unwanted delays . . .
* Fixing that correctly is one of those or both ;
* 1 ) use repeat if possible
* 2 ) add suitable delay
*/
/* get answer, retry few times if error returned */
for ( i = 0 ; i < 3 ; i + + ) {
2008-05-17 23:05:48 -03:00
/* receive 2nd answer */
ret = usb_bulk_msg ( d - > udev , usb_rcvbulkpipe ( d - > udev ,
2012-06-14 04:56:09 -03:00
d - > props - > generic_bulk_ctrl_endpoint ) , buf , sizeof ( buf ) ,
2008-05-17 23:05:48 -03:00
& act_len , 2000 ) ;
2012-01-21 11:19:29 -03:00
if ( ret ) {
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: recv bulk message " \
" failed=%d \n " , __func__ , ret ) ;
2012-01-21 11:19:29 -03:00
} else {
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: <<< %*ph \n " , __func__ ,
rlen , buf ) ;
2011-09-29 20:28:53 -03:00
if ( buf [ 63 ] ! = 0x4f )
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: cmd failed \n " ,
__func__ ) ;
2012-01-21 11:19:29 -03:00
break ;
2008-05-17 23:05:48 -03:00
}
}
2012-01-21 11:19:29 -03:00
if ( ret ) {
/* all retries failed, it is fatal */
2012-08-14 15:56:20 -03:00
dev_err ( & d - > udev - > dev , " %s: recv bulk message failed=%d \n " ,
KBUILD_MODNAME , ret ) ;
2012-01-21 11:19:29 -03:00
goto error_unlock ;
}
2008-05-17 23:05:48 -03:00
/* read request, copy returned data to return buf */
2012-01-21 11:19:29 -03:00
if ( rbuf & & rlen )
2008-05-17 23:05:48 -03:00
memcpy ( rbuf , buf , rlen ) ;
2012-01-21 11:19:29 -03:00
error_unlock :
2008-05-17 23:05:48 -03:00
mutex_unlock ( & anysee_usb_mutex ) ;
return ret ;
}
static int anysee_read_reg ( struct dvb_usb_device * d , u16 reg , u8 * val )
{
u8 buf [ ] = { CMD_REG_READ , reg > > 8 , reg & 0xff , 0x01 } ;
int ret ;
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , val , 1 ) ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: reg=%04x val=%02x \n " , __func__ , reg , * val ) ;
2008-05-17 23:05:48 -03:00
return ret ;
}
static int anysee_write_reg ( struct dvb_usb_device * d , u16 reg , u8 val )
{
u8 buf [ ] = { CMD_REG_WRITE , reg > > 8 , reg & 0xff , 0x01 , val } ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: reg=%04x val=%02x \n " , __func__ , reg , val ) ;
2008-05-17 23:05:48 -03:00
return anysee_ctrl_msg ( d , buf , sizeof ( buf ) , NULL , 0 ) ;
}
2011-04-10 17:53:52 -03:00
/* write single register with mask */
static int anysee_wr_reg_mask ( struct dvb_usb_device * d , u16 reg , u8 val ,
u8 mask )
{
int ret ;
u8 tmp ;
/* no need for read if whole reg is written */
if ( mask ! = 0xff ) {
ret = anysee_read_reg ( d , reg , & tmp ) ;
if ( ret )
return ret ;
val & = mask ;
tmp & = ~ mask ;
val | = tmp ;
}
return anysee_write_reg ( d , reg , val ) ;
}
2011-09-05 23:33:04 -03:00
/* read single register with mask */
static int anysee_rd_reg_mask ( struct dvb_usb_device * d , u16 reg , u8 * val ,
u8 mask )
{
int ret , i ;
u8 tmp ;
ret = anysee_read_reg ( d , reg , & tmp ) ;
if ( ret )
return ret ;
tmp & = mask ;
/* find position of the first bit */
for ( i = 0 ; i < 8 ; i + + ) {
if ( ( mask > > i ) & 0x01 )
break ;
}
* val = tmp > > i ;
return 0 ;
}
2008-05-17 23:05:48 -03:00
static int anysee_get_hw_info ( struct dvb_usb_device * d , u8 * id )
{
u8 buf [ ] = { CMD_GET_HW_INFO } ;
return anysee_ctrl_msg ( d , buf , sizeof ( buf ) , id , 3 ) ;
}
2012-06-26 00:04:33 -03:00
static int anysee_streaming_ctrl ( struct dvb_frontend * fe , int onoff )
2008-05-17 23:05:48 -03:00
{
u8 buf [ ] = { CMD_STREAMING_CTRL , ( u8 ) onoff , 0x00 } ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & fe_to_d ( fe ) - > udev - > dev , " %s: onoff=%d \n " , __func__ , onoff ) ;
2012-06-26 00:04:33 -03:00
return anysee_ctrl_msg ( fe_to_d ( fe ) , buf , sizeof ( buf ) , NULL , 0 ) ;
2008-05-17 23:05:48 -03:00
}
static int anysee_led_ctrl ( struct dvb_usb_device * d , u8 mode , u8 interval )
{
u8 buf [ ] = { CMD_LED_AND_IR_CTRL , 0x01 , mode , interval } ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: state=%d interval=%d \n " , __func__ ,
mode , interval ) ;
2008-05-17 23:05:48 -03:00
return anysee_ctrl_msg ( d , buf , sizeof ( buf ) , NULL , 0 ) ;
}
static int anysee_ir_ctrl ( struct dvb_usb_device * d , u8 onoff )
{
u8 buf [ ] = { CMD_LED_AND_IR_CTRL , 0x02 , onoff } ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: onoff=%d \n " , __func__ , onoff ) ;
2008-05-17 23:05:48 -03:00
return anysee_ctrl_msg ( d , buf , sizeof ( buf ) , NULL , 0 ) ;
}
/* I2C */
static int anysee_master_xfer ( struct i2c_adapter * adap , struct i2c_msg * msg ,
int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2008-12-29 19:02:24 -03:00
int ret = 0 , inc , i = 0 ;
2011-05-24 06:04:08 -03:00
u8 buf [ 52 ] ; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
2008-05-17 23:05:48 -03:00
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
while ( i < num ) {
if ( num > i + 1 & & ( msg [ i + 1 ] . flags & I2C_M_RD ) ) {
2011-05-24 06:04:08 -03:00
if ( msg [ i ] . len > 2 | | msg [ i + 1 ] . len > 60 ) {
ret = - EOPNOTSUPP ;
break ;
}
2008-05-17 23:05:48 -03:00
buf [ 0 ] = CMD_I2C_READ ;
2011-04-09 20:50:07 -03:00
buf [ 1 ] = ( msg [ i ] . addr < < 1 ) | 0x01 ;
2008-05-17 23:05:48 -03:00
buf [ 2 ] = msg [ i ] . buf [ 0 ] ;
2011-04-12 19:49:25 -03:00
buf [ 3 ] = msg [ i ] . buf [ 1 ] ;
buf [ 4 ] = msg [ i ] . len - 1 ;
2011-04-09 21:00:51 -03:00
buf [ 5 ] = msg [ i + 1 ] . len ;
2011-05-24 06:04:08 -03:00
ret = anysee_ctrl_msg ( d , buf , 6 , msg [ i + 1 ] . buf ,
2008-05-17 23:05:48 -03:00
msg [ i + 1 ] . len ) ;
inc = 2 ;
} else {
2011-05-24 06:04:08 -03:00
if ( msg [ i ] . len > 48 ) {
ret = - EOPNOTSUPP ;
break ;
}
2008-05-17 23:05:48 -03:00
buf [ 0 ] = CMD_I2C_WRITE ;
2011-04-09 20:50:07 -03:00
buf [ 1 ] = ( msg [ i ] . addr < < 1 ) ;
2008-05-17 23:05:48 -03:00
buf [ 2 ] = msg [ i ] . len ;
buf [ 3 ] = 0x01 ;
memcpy ( & buf [ 4 ] , msg [ i ] . buf , msg [ i ] . len ) ;
2011-05-24 06:04:08 -03:00
ret = anysee_ctrl_msg ( d , buf , 4 + msg [ i ] . len , NULL , 0 ) ;
2008-05-17 23:05:48 -03:00
inc = 1 ;
}
if ( ret )
2008-08-11 10:36:43 -03:00
break ;
2008-05-17 23:05:48 -03:00
i + = inc ;
}
mutex_unlock ( & d - > i2c_mutex ) ;
2008-08-11 10:36:43 -03:00
return ret ? ret : i ;
2008-05-17 23:05:48 -03:00
}
static u32 anysee_i2c_func ( struct i2c_adapter * adapter )
{
return I2C_FUNC_I2C ;
}
static struct i2c_algorithm anysee_i2c_algo = {
. master_xfer = anysee_master_xfer ,
. functionality = anysee_i2c_func ,
} ;
static int anysee_mt352_demod_init ( struct dvb_frontend * fe )
{
2009-09-16 19:50:25 -03:00
static u8 clock_config [ ] = { CLOCK_CTL , 0x38 , 0x28 } ;
static u8 reset [ ] = { RESET , 0x80 } ;
static u8 adc_ctl_1_cfg [ ] = { ADC_CTL_1 , 0x40 } ;
static u8 agc_cfg [ ] = { AGC_TARGET , 0x28 , 0x20 } ;
static u8 gpp_ctl_cfg [ ] = { GPP_CTL , 0x33 } ;
2008-05-17 23:05:48 -03:00
static u8 capt_range_cfg [ ] = { CAPT_RANGE , 0x32 } ;
mt352_write ( fe , clock_config , sizeof ( clock_config ) ) ;
udelay ( 200 ) ;
mt352_write ( fe , reset , sizeof ( reset ) ) ;
mt352_write ( fe , adc_ctl_1_cfg , sizeof ( adc_ctl_1_cfg ) ) ;
mt352_write ( fe , agc_cfg , sizeof ( agc_cfg ) ) ;
mt352_write ( fe , gpp_ctl_cfg , sizeof ( gpp_ctl_cfg ) ) ;
mt352_write ( fe , capt_range_cfg , sizeof ( capt_range_cfg ) ) ;
return 0 ;
}
/* Callbacks for DVB USB */
static struct tda10023_config anysee_tda10023_config = {
2011-04-09 20:50:07 -03:00
. demod_address = ( 0x1a > > 1 ) ,
2008-05-17 23:05:48 -03:00
. invert = 0 ,
. xtal = 16000000 ,
. pll_m = 11 ,
. pll_p = 3 ,
. pll_n = 1 ,
2008-06-09 22:58:22 -03:00
. output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C ,
. deltaf = 0xfeeb ,
2008-05-17 23:05:48 -03:00
} ;
static struct mt352_config anysee_mt352_config = {
2011-04-09 20:50:07 -03:00
. demod_address = ( 0x1e > > 1 ) ,
2008-05-17 23:05:48 -03:00
. demod_init = anysee_mt352_demod_init ,
} ;
static struct zl10353_config anysee_zl10353_config = {
2011-04-09 20:50:07 -03:00
. demod_address = ( 0x1e > > 1 ) ,
2008-05-17 23:05:48 -03:00
. parallel_ts = 1 ,
} ;
2011-04-12 17:34:08 -03:00
static struct zl10353_config anysee_zl10353_tda18212_config2 = {
. demod_address = ( 0x1e > > 1 ) ,
. parallel_ts = 1 ,
. disable_i2c_gate_ctrl = 1 ,
. no_tuner = 1 ,
. if2 = 41500 ,
} ;
2011-04-10 20:14:50 -03:00
static struct zl10353_config anysee_zl10353_tda18212_config = {
. demod_address = ( 0x18 > > 1 ) ,
. parallel_ts = 1 ,
. disable_i2c_gate_ctrl = 1 ,
. no_tuner = 1 ,
. if2 = 41500 ,
} ;
static struct tda10023_config anysee_tda10023_tda18212_config = {
. demod_address = ( 0x1a > > 1 ) ,
. xtal = 16000000 ,
. pll_m = 12 ,
. pll_p = 3 ,
. pll_n = 1 ,
2011-09-05 23:33:04 -03:00
. output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B ,
2011-04-10 20:14:50 -03:00
. deltaf = 0xba02 ,
} ;
static struct tda18212_config anysee_tda18212_config = {
. i2c_address = ( 0xc0 > > 1 ) ,
. if_dvbt_6 = 4150 ,
. if_dvbt_7 = 4150 ,
. if_dvbt_8 = 4150 ,
. if_dvbc = 5000 ,
} ;
2011-08-12 18:29:46 -03:00
static struct tda18212_config anysee_tda18212_config2 = {
. i2c_address = 0x60 /* (0xc0 >> 1) */ ,
. if_dvbt_6 = 3550 ,
. if_dvbt_7 = 3700 ,
. if_dvbt_8 = 4150 ,
. if_dvbt2_6 = 3250 ,
. if_dvbt2_7 = 4000 ,
. if_dvbt2_8 = 4000 ,
. if_dvbc = 5000 ,
} ;
2011-04-27 21:11:59 -03:00
static struct cx24116_config anysee_cx24116_config = {
. demod_address = ( 0xaa > > 1 ) ,
. mpg_clk_pos_pol = 0x00 ,
. i2c_wr_max = 48 ,
} ;
2011-04-29 13:55:02 -03:00
static struct stv0900_config anysee_stv0900_config = {
. demod_address = ( 0xd0 > > 1 ) ,
. demod_mode = 0 ,
. xtal = 8000000 ,
. clkmode = 3 ,
. diseqc_mode = 2 ,
. tun1_maddress = 0 ,
. tun1_adc = 1 , /* 1 Vpp */
. path1_mode = 3 ,
} ;
static struct stv6110_config anysee_stv6110_config = {
. i2c_address = ( 0xc0 > > 1 ) ,
. mclk = 16000000 ,
. clk_div = 1 ,
} ;
2011-04-27 21:11:59 -03:00
static struct isl6423_config anysee_isl6423_config = {
. current_max = SEC_CURRENT_800m ,
. curlim = SEC_CURRENT_LIM_OFF ,
. mod_extern = 1 ,
. addr = ( 0x10 > > 1 ) ,
} ;
2011-08-12 18:29:46 -03:00
static struct cxd2820r_config anysee_cxd2820r_config = {
. i2c_address = 0x6d , /* (0xda >> 1) */
. ts_mode = 0x38 ,
} ;
2011-04-10 17:53:52 -03:00
/*
* New USB device strings : Mfr = 1 , Product = 2 , SerialNumber = 0
* Manufacturer : AMT . CO . KR
*
* E30 VID = 04 b4 PID = 861f HW = 2 FW = 2.1 Product = ? ? ? ? ? ? ? ?
* PCB : ?
2011-04-12 20:17:11 -03:00
* parts : DNOS404ZH102A ( MT352 , DTT7579 ( ? ) )
2011-04-10 17:53:52 -03:00
*
2011-05-25 18:30:09 -03:00
* E30 VID = 04 b4 PID = 861f HW = 2 FW = 2.1 " anysee-T(LP) "
* PCB : PCB 507 T ( rev1 .61 )
2011-04-12 20:17:11 -03:00
* parts : DNOS404ZH103A ( ZL10353 , DTT7579 ( ? ) )
2011-05-25 18:30:09 -03:00
* OEA = 0 a OEB = 00 OEC = 00 OED = ff OEE = 00
* IOA = 45 IOB = ff IOC = 00 IOD = ff IOE = 00
2011-04-10 17:53:52 -03:00
*
* E30 Plus VID = 04 b4 PID = 861f HW = 6 FW = 1.0 " anysee "
* PCB : 507 CD ( rev1 .1 )
2011-04-12 20:17:11 -03:00
* parts : DNOS404ZH103A ( ZL10353 , DTT7579 ( ? ) ) , CST56I01
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = 00 OED = ff OEE = fe
* IOA = 4f IOB = ff IOC = 00 IOD = 06 IOE = 01
2011-04-10 17:53:52 -03:00
* IOD [ 0 ] ZL10353 1 = enabled
* IOA [ 7 ] TS 0 = enabled
* tuner is not behind ZL10353 I2C - gate ( no care if gate disabled or not )
*
* E30 C Plus VID = 04 b4 PID = 861f HW = 10 FW = 1.0 " anysee-DC(LP) "
* PCB : 507 DC ( rev0 .2 )
2011-04-12 20:17:11 -03:00
* parts : TDA10023 , DTOS403IH102B TM , CST56I01
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = 00 OED = ff OEE = fe
* IOA = 4f IOB = ff IOC = 00 IOD = 26 IOE = 01
2011-04-10 17:53:52 -03:00
* IOD [ 0 ] TDA10023 1 = enabled
*
2011-04-27 21:11:59 -03:00
* E30 S2 Plus VID = 04 b4 PID = 861f HW = 11 FW = 0.1 " anysee-S2(LP) "
* PCB : 507 SI ( rev2 .1 )
* parts : BS2N10WCC01 ( CX24116 , CX24118 ) , ISL6423 , TDA8024
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = ff OED = ff OEE = fe
* IOA = 4 d IOB = ff IOC = 00 IOD = 26 IOE = 01
2011-04-27 21:11:59 -03:00
* IOD [ 0 ] CX24116 1 = enabled
*
2011-04-10 17:53:52 -03:00
* E30 C Plus VID = 1 c73 PID = 861f HW = 15 FW = 1.2 " anysee-FA(LP) "
* PCB : 507F A ( rev0 .4 )
2011-04-12 20:17:11 -03:00
* parts : TDA10023 , DTOS403IH102B TM , TDA8024
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = ff OED = ff OEE = ff
* IOA = 4 d IOB = ff IOC = 00 IOD = 00 IOE = c0
2011-04-10 17:53:52 -03:00
* IOD [ 5 ] TDA10023 1 = enabled
* IOE [ 0 ] tuner 1 = enabled
*
* E30 Combo Plus VID = 1 c73 PID = 861f HW = 15 FW = 1.2 " anysee-FA(LP) "
* PCB : 507F A ( rev1 .1 )
2011-04-12 20:17:11 -03:00
* parts : ZL10353 , TDA10023 , DTOS403IH102B TM , TDA8024
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = ff OED = ff OEE = ff
* IOA = 4 d IOB = ff IOC = 00 IOD = 00 IOE = c0
2011-04-10 17:53:52 -03:00
* DVB - C :
* IOD [ 5 ] TDA10023 1 = enabled
* IOE [ 0 ] tuner 1 = enabled
* DVB - T :
* IOD [ 0 ] ZL10353 1 = enabled
* IOE [ 0 ] tuner 0 = enabled
* tuner is behind ZL10353 I2C - gate
2011-04-12 20:17:11 -03:00
*
* E7 TC VID = 1 c73 PID = 861f HW = 18 FW = 0.7 AMTCI = 0.5 " anysee-E7TC(LP) "
* PCB : 508 TC ( rev0 .6 )
* parts : ZL10353 , TDA10023 , DNOD44CDH086A ( TDA18212 )
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = 03 OED = f7 OEE = ff
* IOA = 4 d IOB = 00 IOC = cc IOD = 48 IOE = e4
2011-04-12 20:17:11 -03:00
* IOA [ 7 ] TS 1 = enabled
* IOE [ 4 ] TDA18212 1 = enabled
* DVB - C :
* IOD [ 6 ] ZL10353 0 = disabled
* IOD [ 5 ] TDA10023 1 = enabled
* IOE [ 0 ] IF 1 = enabled
* DVB - T :
* IOD [ 5 ] TDA10023 0 = disabled
* IOD [ 6 ] ZL10353 1 = enabled
* IOE [ 0 ] IF 0 = enabled
2011-04-29 13:55:02 -03:00
*
* E7 S2 VID = 1 c73 PID = 861f HW = 19 FW = 0.4 AMTCI = 0.5 " anysee-E7S2(LP) "
* PCB : 508 S2 ( rev0 .7 )
* parts : DNBU10512IST ( STV0903 , STV6110 ) , ISL6423
2011-05-25 18:30:09 -03:00
* OEA = 80 OEB = 00 OEC = 03 OED = f7 OEE = ff
* IOA = 4 d IOB = 00 IOC = c4 IOD = 08 IOE = e4
2011-04-29 13:55:02 -03:00
* IOA [ 7 ] TS 1 = enabled
* IOE [ 5 ] STV0903 1 = enabled
*
2011-08-12 18:29:46 -03:00
* E7 T2C VID = 1 c73 PID = 861f HW = 20 FW = 0.1 AMTCI = 0.5 " anysee-E7T2C(LP) "
* PCB : 508 T2C ( rev0 .3 )
* parts : DNOQ44QCH106A ( CXD2820R , TDA18212 ) , TDA8024
* OEA = 80 OEB = 00 OEC = 03 OED = f7 OEE = ff
* IOA = 4 d IOB = 00 IOC = cc IOD = 48 IOE = e4
* IOA [ 7 ] TS 1 = enabled
* IOE [ 5 ] CXD2820R 1 = enabled
*
2011-05-24 07:57:34 -03:00
* E7 PTC VID = 1 c73 PID = 861f HW = 21 FW = 0.1 AMTCI = ? ? " anysee-E7PTC(LP) "
* PCB : 508 PTC ( rev0 .5 )
* parts : ZL10353 , TDA10023 , DNOD44CDH086A ( TDA18212 )
* OEA = 80 OEB = 00 OEC = 03 OED = f7 OEE = ff
* IOA = 4 d IOB = 00 IOC = cc IOD = 48 IOE = e4
* IOA [ 7 ] TS 1 = enabled
* IOE [ 4 ] TDA18212 1 = enabled
* DVB - C :
* IOD [ 6 ] ZL10353 0 = disabled
* IOD [ 5 ] TDA10023 1 = enabled
* IOE [ 0 ] IF 1 = enabled
* DVB - T :
* IOD [ 5 ] TDA10023 0 = disabled
* IOD [ 6 ] ZL10353 1 = enabled
* IOE [ 0 ] IF 0 = enabled
2011-05-25 18:21:43 -03:00
*
2011-08-12 18:29:46 -03:00
* E7 PS2 VID = 1 c73 PID = 861f HW = 22 FW = 0.1 AMTCI = ? ? " anysee-E7PS2(LP) "
2011-05-25 18:21:43 -03:00
* PCB : 508 PS2 ( rev0 .4 )
* parts : DNBU10512IST ( STV0903 , STV6110 ) , ISL6423
* OEA = 80 OEB = 00 OEC = 03 OED = f7 OEE = ff
* IOA = 4 d IOB = 00 IOC = c4 IOD = 08 IOE = e4
* IOA [ 7 ] TS 1 = enabled
* IOE [ 5 ] STV0903 1 = enabled
2011-04-10 17:53:52 -03:00
*/
2012-06-14 04:56:09 -03:00
static int anysee_read_config ( struct dvb_usb_device * d )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2012-06-14 04:56:09 -03:00
int ret ;
u8 hw_info [ 3 ] ;
/*
* Check which hardware we have .
* We must do this call two times to get reliable values ( hw / fw bug ) .
*/
ret = anysee_get_hw_info ( d , hw_info ) ;
if ( ret )
goto error ;
ret = anysee_get_hw_info ( d , hw_info ) ;
if ( ret )
goto error ;
2012-08-14 15:56:20 -03:00
/*
* Meaning of these info bytes are guessed .
*/
dev_info ( & d - > udev - > dev , " %s: firmware version %d.%d hardware id %d \n " ,
KBUILD_MODNAME , hw_info [ 1 ] , hw_info [ 2 ] , hw_info [ 0 ] ) ;
2012-06-14 04:56:09 -03:00
state - > hw = hw_info [ 0 ] ;
error :
return ret ;
}
2011-09-05 22:10:05 -03:00
/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
static int anysee_i2c_gate_ctrl ( struct dvb_frontend * fe , int enable )
{
/* enable / disable tuner access on IOE[4] */
2012-06-18 19:39:02 -03:00
return anysee_wr_reg_mask ( fe_to_d ( fe ) , REG_IOE , ( enable < < 4 ) , 0x10 ) ;
2011-09-05 22:10:05 -03:00
}
2011-07-25 20:25:21 -03:00
static int anysee_frontend_ctrl ( struct dvb_frontend * fe , int onoff )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = fe_to_priv ( fe ) ;
struct dvb_usb_device * d = fe_to_d ( fe ) ;
2011-07-25 20:25:21 -03:00
int ret ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: fe=%d onoff=%d \n " , __func__ , fe - > id , onoff ) ;
2011-07-25 20:25:21 -03:00
/* no frontend sleep control */
if ( onoff = = 0 )
return 0 ;
switch ( state - > hw ) {
case ANYSEE_HW_507FA : /* 15 */
/* E30 Combo Plus */
/* E30 C Plus */
2012-06-14 04:56:09 -03:00
if ( fe - > id = = 0 ) {
2011-07-25 20:25:21 -03:00
/* disable DVB-T demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 5 ) , 0x20 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-C tuner on IOE[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 1 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
} else {
/* disable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 5 ) , 0x20 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-T demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-T tuner on IOE[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 0 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
}
break ;
case ANYSEE_HW_508TC : /* 18 */
case ANYSEE_HW_508PTC : /* 21 */
/* E7 TC */
/* E7 PTC */
2012-06-14 04:56:09 -03:00
if ( fe - > id = = 0 ) {
2011-07-25 20:25:21 -03:00
/* disable DVB-T demod on IOD[6] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 6 ) , 0x40 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 5 ) , 0x20 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable IF route on IOE[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 1 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
} else {
/* disable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 5 ) , 0x20 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable DVB-T demod on IOD[6] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 6 ) , 0x40 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
/* enable IF route on IOE[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 0 < < 0 ) , 0x01 ) ;
2011-07-25 20:25:21 -03:00
if ( ret )
goto error ;
}
break ;
default :
ret = 0 ;
}
error :
return ret ;
}
2008-05-17 23:05:48 -03:00
static int anysee_frontend_attach ( struct dvb_usb_adapter * adap )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = adap_to_priv ( adap ) ;
struct dvb_usb_device * d = adap_to_d ( adap ) ;
2008-05-17 23:05:48 -03:00
int ret ;
2011-04-10 20:14:50 -03:00
u8 tmp ;
struct i2c_msg msg [ 2 ] = {
{
. addr = anysee_tda18212_config . i2c_address ,
. flags = 0 ,
. len = 1 ,
. buf = " \x00 " ,
} , {
. addr = anysee_tda18212_config . i2c_address ,
. flags = I2C_M_RD ,
. len = 1 ,
. buf = & tmp ,
}
} ;
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
switch ( state - > hw ) {
2011-05-25 18:30:09 -03:00
case ANYSEE_HW_507T : /* 2 */
2011-04-10 17:53:52 -03:00
/* E30 */
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
/* attach demod */
2012-06-18 19:39:02 -03:00
adap - > fe [ 0 ] = dvb_attach ( mt352_attach , & anysee_mt352_config ,
& d - > i2c_adap ) ;
2012-06-14 04:56:09 -03:00
if ( adap - > fe [ 0 ] )
2011-04-10 17:53:52 -03:00
break ;
2008-08-11 10:54:16 -03:00
2011-04-10 17:53:52 -03:00
/* attach demod */
2012-06-18 19:39:02 -03:00
adap - > fe [ 0 ] = dvb_attach ( zl10353_attach , & anysee_zl10353_config ,
& d - > i2c_adap ) ;
2008-08-11 10:54:16 -03:00
2011-04-10 17:53:52 -03:00
break ;
case ANYSEE_HW_507CD : /* 6 */
/* E30 Plus */
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
/* enable DVB-T demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 0 ) , 0x01 ) ;
2011-04-10 17:53:52 -03:00
if ( ret )
goto error ;
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
/* enable transport stream on IOA[7] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 0 < < 7 ) , 0x80 ) ;
2011-04-10 17:53:52 -03:00
if ( ret )
goto error ;
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
/* attach demod */
2012-06-18 19:39:02 -03:00
adap - > fe [ 0 ] = dvb_attach ( zl10353_attach , & anysee_zl10353_config ,
& d - > i2c_adap ) ;
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
break ;
case ANYSEE_HW_507DC : /* 10 */
/* E30 C Plus */
/* enable DVB-C demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 0 ) , 0x01 ) ;
2011-04-10 17:53:52 -03:00
if ( ret )
goto error ;
/* attach demod */
2012-06-14 04:56:09 -03:00
adap - > fe [ 0 ] = dvb_attach ( tda10023_attach ,
2012-06-18 19:39:02 -03:00
& anysee_tda10023_config , & d - > i2c_adap , 0x48 ) ;
2008-05-17 23:05:48 -03:00
2011-04-27 21:11:59 -03:00
break ;
case ANYSEE_HW_507SI : /* 11 */
/* E30 S2 Plus */
/* enable DVB-S/S2 demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 0 ) , 0x01 ) ;
2011-04-27 21:11:59 -03:00
if ( ret )
goto error ;
/* attach demod */
2012-06-18 19:39:02 -03:00
adap - > fe [ 0 ] = dvb_attach ( cx24116_attach , & anysee_cx24116_config ,
& d - > i2c_adap ) ;
2011-04-27 21:11:59 -03:00
2011-04-10 17:53:52 -03:00
break ;
case ANYSEE_HW_507FA : /* 15 */
/* E30 Combo Plus */
/* E30 C Plus */
2011-04-10 20:14:50 -03:00
/* enable tuner on IOE[4] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 1 < < 4 ) , 0x10 ) ;
2011-04-10 20:14:50 -03:00
if ( ret )
goto error ;
/* probe TDA18212 */
tmp = 0 ;
2012-06-18 19:39:02 -03:00
ret = i2c_transfer ( & d - > i2c_adap , msg , 2 ) ;
2011-04-10 20:14:50 -03:00
if ( ret = = 2 & & tmp = = 0xc7 )
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: TDA18212 found \n " ,
__func__ ) ;
2011-04-10 20:14:50 -03:00
else
tmp = 0 ;
/* disable tuner on IOE[4] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 0 < < 4 ) , 0x10 ) ;
2011-04-10 20:14:50 -03:00
if ( ret )
goto error ;
2012-06-14 04:56:09 -03:00
/* disable DVB-T demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 0 ) , 0x01 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 17:53:52 -03:00
2012-06-14 04:56:09 -03:00
/* enable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 5 ) , 0x20 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 17:53:52 -03:00
2012-06-14 04:56:09 -03:00
/* attach demod */
if ( tmp = = 0xc7 ) {
/* TDA18212 config */
adap - > fe [ 0 ] = dvb_attach ( tda10023_attach ,
2011-07-25 20:25:21 -03:00
& anysee_tda10023_tda18212_config ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , 0x48 ) ;
2012-06-14 04:56:09 -03:00
/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
if ( adap - > fe [ 0 ] )
adap - > fe [ 0 ] - > ops . i2c_gate_ctrl =
anysee_i2c_gate_ctrl ;
} else {
/* PLL config */
adap - > fe [ 0 ] = dvb_attach ( tda10023_attach ,
2011-07-25 20:25:21 -03:00
& anysee_tda10023_config ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , 0x48 ) ;
2012-06-14 04:56:09 -03:00
}
2011-04-10 17:53:52 -03:00
2012-06-14 04:56:09 -03:00
/* break out if first frontend attaching fails */
if ( ! adap - > fe [ 0 ] )
break ;
/* disable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 5 ) , 0x20 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
/* enable DVB-T demod on IOD[0] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 0 ) , 0x01 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 17:53:52 -03:00
2012-06-14 04:56:09 -03:00
/* attach demod */
if ( tmp = = 0xc7 ) {
/* TDA18212 config */
adap - > fe [ 1 ] = dvb_attach ( zl10353_attach ,
2011-07-25 20:25:21 -03:00
& anysee_zl10353_tda18212_config2 ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap ) ;
2012-06-14 04:56:09 -03:00
/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
if ( adap - > fe [ 1 ] )
adap - > fe [ 1 ] - > ops . i2c_gate_ctrl =
anysee_i2c_gate_ctrl ;
} else {
/* PLL config */
adap - > fe [ 1 ] = dvb_attach ( zl10353_attach ,
2011-07-25 20:25:21 -03:00
& anysee_zl10353_config ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap ) ;
2011-09-05 22:10:05 -03:00
}
2011-04-10 17:53:52 -03:00
break ;
2011-04-10 20:23:02 -03:00
case ANYSEE_HW_508TC : /* 18 */
2011-05-24 07:57:34 -03:00
case ANYSEE_HW_508PTC : /* 21 */
2011-04-10 20:23:02 -03:00
/* E7 TC */
2011-05-24 07:57:34 -03:00
/* E7 PTC */
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
/* disable DVB-T demod on IOD[6] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 6 ) , 0x40 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
/* enable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 5 ) , 0x20 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
/* attach demod */
adap - > fe [ 0 ] = dvb_attach ( tda10023_attach ,
2011-07-25 20:25:21 -03:00
& anysee_tda10023_tda18212_config ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , 0x48 ) ;
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
if ( adap - > fe [ 0 ] )
adap - > fe [ 0 ] - > ops . i2c_gate_ctrl = anysee_i2c_gate_ctrl ;
/* break out if first frontend attaching fails */
if ( ! adap - > fe [ 0 ] )
break ;
/* disable DVB-C demod on IOD[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 5 ) , 0x20 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
/* enable DVB-T demod on IOD[6] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 6 ) , 0x40 ) ;
2012-06-14 04:56:09 -03:00
if ( ret )
goto error ;
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
/* attach demod */
adap - > fe [ 1 ] = dvb_attach ( zl10353_attach ,
2011-07-25 20:25:21 -03:00
& anysee_zl10353_tda18212_config ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap ) ;
2011-04-12 19:43:30 -03:00
2011-09-05 22:10:05 -03:00
/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
2012-06-14 04:56:09 -03:00
if ( adap - > fe [ 1 ] )
adap - > fe [ 1 ] - > ops . i2c_gate_ctrl = anysee_i2c_gate_ctrl ;
2011-09-05 22:10:05 -03:00
2011-09-05 23:33:04 -03:00
state - > has_ci = true ;
2011-04-29 13:55:02 -03:00
break ;
case ANYSEE_HW_508S2 : /* 19 */
2011-05-25 18:21:43 -03:00
case ANYSEE_HW_508PS2 : /* 22 */
2011-04-29 13:55:02 -03:00
/* E7 S2 */
2011-05-25 18:21:43 -03:00
/* E7 PS2 */
2011-04-29 13:55:02 -03:00
/* enable DVB-S/S2 demod on IOE[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 1 < < 5 ) , 0x20 ) ;
2011-04-29 13:55:02 -03:00
if ( ret )
goto error ;
/* attach demod */
2012-06-14 04:56:09 -03:00
adap - > fe [ 0 ] = dvb_attach ( stv0900_attach ,
2012-06-18 19:39:02 -03:00
& anysee_stv0900_config , & d - > i2c_adap , 0 ) ;
2011-04-29 13:55:02 -03:00
2011-09-05 23:33:04 -03:00
state - > has_ci = true ;
2011-08-12 18:29:46 -03:00
break ;
case ANYSEE_HW_508T2C : /* 20 */
/* E7 T2C */
/* enable DVB-T/T2/C demod on IOE[5] */
2012-06-18 19:39:02 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOE , ( 1 < < 5 ) , 0x20 ) ;
2011-04-29 13:55:02 -03:00
if ( ret )
goto error ;
2012-01-15 14:20:50 -03:00
/* attach demod */
2012-06-14 04:56:09 -03:00
adap - > fe [ 0 ] = dvb_attach ( cxd2820r_attach ,
2012-07-19 21:10:36 -03:00
& anysee_cxd2820r_config , & d - > i2c_adap , NULL ) ;
2011-08-12 18:29:46 -03:00
2011-09-05 23:33:04 -03:00
state - > has_ci = true ;
2011-04-29 13:55:02 -03:00
2011-04-10 20:23:02 -03:00
break ;
2011-04-10 17:53:52 -03:00
}
2008-05-17 23:05:48 -03:00
2012-06-14 04:56:09 -03:00
if ( ! adap - > fe [ 0 ] ) {
2011-04-10 17:53:52 -03:00
/* we have no frontend :-( */
ret = - ENODEV ;
2012-08-14 15:56:20 -03:00
dev_err ( & d - > udev - > dev , " %s: Unsupported Anysee version. " \
" Please report the " \
" <linux-media@vger.kernel.org>. \n " ,
KBUILD_MODNAME ) ;
2011-04-10 17:53:52 -03:00
}
error :
return ret ;
2008-05-17 23:05:48 -03:00
}
static int anysee_tuner_attach ( struct dvb_usb_adapter * adap )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = adap_to_priv ( adap ) ;
struct dvb_usb_device * d = adap_to_d ( adap ) ;
2011-04-10 20:14:50 -03:00
struct dvb_frontend * fe ;
2011-04-12 19:43:30 -03:00
int ret ;
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: \n " , __func__ ) ;
2008-05-17 23:05:48 -03:00
2011-04-10 17:53:52 -03:00
switch ( state - > hw ) {
2011-05-25 18:30:09 -03:00
case ANYSEE_HW_507T : /* 2 */
2011-04-10 17:53:52 -03:00
/* E30 */
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( dvb_pll_attach , adap - > fe [ 0 ] , ( 0xc2 > > 1 ) , NULL ,
DVB_PLL_THOMSON_DTT7579 ) ;
2011-04-12 19:43:30 -03:00
2008-05-17 23:05:48 -03:00
break ;
2011-04-10 17:53:52 -03:00
case ANYSEE_HW_507CD : /* 6 */
/* E30 Plus */
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( dvb_pll_attach , adap - > fe [ 0 ] , ( 0xc2 > > 1 ) ,
& d - > i2c_adap , DVB_PLL_THOMSON_DTT7579 ) ;
2011-04-10 17:53:52 -03:00
break ;
case ANYSEE_HW_507DC : /* 10 */
/* E30 C Plus */
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( dvb_pll_attach , adap - > fe [ 0 ] , ( 0xc0 > > 1 ) ,
& d - > i2c_adap , DVB_PLL_SAMSUNG_DTOS403IH102A ) ;
2011-04-12 19:43:30 -03:00
2011-04-27 21:11:59 -03:00
break ;
case ANYSEE_HW_507SI : /* 11 */
/* E30 S2 Plus */
/* attach LNB controller */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( isl6423_attach , adap - > fe [ 0 ] , & d - > i2c_adap ,
& anysee_isl6423_config ) ;
2011-04-27 21:11:59 -03:00
2011-04-10 17:53:52 -03:00
break ;
case ANYSEE_HW_507FA : /* 15 */
/* E30 Combo Plus */
/* E30 C Plus */
2011-04-10 20:14:50 -03:00
/* Try first attach TDA18212 silicon tuner on IOE[4], if that
* fails attach old simple PLL . */
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( tda18212_attach , adap - > fe [ 0 ] , & d - > i2c_adap ,
& anysee_tda18212_config ) ;
2012-06-14 04:56:09 -03:00
if ( fe & & adap - > fe [ 1 ] ) {
/* attach tuner for 2nd FE */
fe = dvb_attach ( tda18212_attach , adap - > fe [ 1 ] ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , & anysee_tda18212_config ) ;
2012-06-14 04:56:09 -03:00
break ;
} else if ( fe ) {
2011-04-10 20:14:50 -03:00
break ;
2012-06-14 04:56:09 -03:00
}
2011-04-10 20:14:50 -03:00
2011-04-10 17:53:52 -03:00
/* attach tuner */
2012-06-14 04:56:09 -03:00
fe = dvb_attach ( dvb_pll_attach , adap - > fe [ 0 ] , ( 0xc0 > > 1 ) ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , DVB_PLL_SAMSUNG_DTOS403IH102A ) ;
2012-06-14 04:56:09 -03:00
if ( fe & & adap - > fe [ 1 ] ) {
/* attach tuner for 2nd FE */
fe = dvb_attach ( dvb_pll_attach , adap - > fe [ 0 ] ,
2012-06-18 19:39:02 -03:00
( 0xc0 > > 1 ) , & d - > i2c_adap ,
2012-06-14 04:56:09 -03:00
DVB_PLL_SAMSUNG_DTOS403IH102A ) ;
}
2011-04-10 17:53:52 -03:00
2008-05-17 23:05:48 -03:00
break ;
2011-04-10 20:23:02 -03:00
case ANYSEE_HW_508TC : /* 18 */
2011-05-24 07:57:34 -03:00
case ANYSEE_HW_508PTC : /* 21 */
2011-04-10 20:23:02 -03:00
/* E7 TC */
2011-05-24 07:57:34 -03:00
/* E7 PTC */
2011-04-10 20:23:02 -03:00
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( tda18212_attach , adap - > fe [ 0 ] , & d - > i2c_adap ,
& anysee_tda18212_config ) ;
2011-04-10 20:23:02 -03:00
2012-06-14 04:56:09 -03:00
if ( fe ) {
/* attach tuner for 2nd FE */
fe = dvb_attach ( tda18212_attach , adap - > fe [ 1 ] ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , & anysee_tda18212_config ) ;
2012-06-14 04:56:09 -03:00
}
2011-04-29 13:55:02 -03:00
break ;
case ANYSEE_HW_508S2 : /* 19 */
2011-05-25 18:21:43 -03:00
case ANYSEE_HW_508PS2 : /* 22 */
2011-04-29 13:55:02 -03:00
/* E7 S2 */
2011-05-25 18:21:43 -03:00
/* E7 PS2 */
2011-04-29 13:55:02 -03:00
/* attach tuner */
2012-06-14 04:56:09 -03:00
fe = dvb_attach ( stv6110_attach , adap - > fe [ 0 ] ,
2012-06-18 19:39:02 -03:00
& anysee_stv6110_config , & d - > i2c_adap ) ;
2011-04-29 13:55:02 -03:00
if ( fe ) {
/* attach LNB controller */
2012-06-14 04:56:09 -03:00
fe = dvb_attach ( isl6423_attach , adap - > fe [ 0 ] ,
2012-06-18 19:39:02 -03:00
& d - > i2c_adap , & anysee_isl6423_config ) ;
2011-04-29 13:55:02 -03:00
}
2011-04-10 20:23:02 -03:00
break ;
2011-08-12 18:29:46 -03:00
case ANYSEE_HW_508T2C : /* 20 */
/* E7 T2C */
/* attach tuner */
2012-06-18 19:39:02 -03:00
fe = dvb_attach ( tda18212_attach , adap - > fe [ 0 ] , & d - > i2c_adap ,
& anysee_tda18212_config2 ) ;
2011-08-12 18:29:46 -03:00
break ;
2011-04-10 17:53:52 -03:00
default :
2011-04-12 19:43:30 -03:00
fe = NULL ;
2008-05-17 23:05:48 -03:00
}
2011-04-12 19:43:30 -03:00
if ( fe )
ret = 0 ;
else
ret = - ENODEV ;
2011-04-10 17:53:52 -03:00
return ret ;
2008-05-17 23:05:48 -03:00
}
2013-01-04 15:21:26 -03:00
# if IS_ENABLED(CONFIG_RC_CORE)
2010-10-17 18:25:10 -03:00
static int anysee_rc_query ( struct dvb_usb_device * d )
2008-05-17 23:05:48 -03:00
{
u8 buf [ ] = { CMD_GET_IR_CODE } ;
u8 ircode [ 2 ] ;
2010-10-17 18:25:10 -03:00
int ret ;
/* Remote controller is basic NEC using address byte 0x08.
Anysee device RC query returns only two bytes , status and code ,
address byte is dropped . Also it does not return any value for
NEC RCs having address byte other than 0x08 . Due to that , we
cannot use that device as standard NEC receiver .
It could be possible make hack which reads whole code directly
from device memory . . . */
2008-05-17 23:05:48 -03:00
2010-10-17 18:25:10 -03:00
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , ircode , sizeof ( ircode ) ) ;
2008-05-17 23:05:48 -03:00
if ( ret )
return ret ;
2010-10-17 18:25:10 -03:00
if ( ircode [ 0 ] ) {
2012-08-14 15:56:20 -03:00
dev_dbg ( & d - > udev - > dev , " %s: key pressed %02x \n " , __func__ ,
ircode [ 1 ] ) ;
2010-11-17 13:53:11 -03:00
rc_keydown ( d - > rc_dev , 0x08 < < 8 | ircode [ 1 ] , 0 ) ;
2008-05-17 23:05:48 -03:00
}
2010-10-17 18:25:10 -03:00
2008-05-17 23:05:48 -03:00
return 0 ;
}
2012-06-14 04:56:09 -03:00
static int anysee_get_rc_config ( struct dvb_usb_device * d , struct dvb_usb_rc * rc )
{
2012-10-11 19:11:54 -03:00
rc - > allowed_protos = RC_BIT_NEC ;
2012-06-14 04:56:09 -03:00
rc - > query = anysee_rc_query ;
rc - > interval = 250 ; /* windows driver uses 500ms */
return 0 ;
}
2012-12-09 20:12:07 -03:00
# else
# define anysee_get_rc_config NULL
# endif
2012-06-14 04:56:09 -03:00
2011-09-05 23:33:04 -03:00
static int anysee_ci_read_attribute_mem ( struct dvb_ca_en50221 * ci , int slot ,
int addr )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
u8 buf [ ] = { CMD_CI , 0x02 , 0x40 | addr > > 8 , addr & 0xff , 0x00 , 1 } ;
u8 val ;
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , & val , 1 ) ;
if ( ret )
return ret ;
return val ;
}
static int anysee_ci_write_attribute_mem ( struct dvb_ca_en50221 * ci , int slot ,
int addr , u8 val )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
u8 buf [ ] = { CMD_CI , 0x03 , 0x40 | addr > > 8 , addr & 0xff , 0x00 , 1 , val } ;
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , NULL , 0 ) ;
if ( ret )
return ret ;
return 0 ;
}
static int anysee_ci_read_cam_control ( struct dvb_ca_en50221 * ci , int slot ,
u8 addr )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
u8 buf [ ] = { CMD_CI , 0x04 , 0x40 , addr , 0x00 , 1 } ;
u8 val ;
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , & val , 1 ) ;
if ( ret )
return ret ;
return val ;
}
static int anysee_ci_write_cam_control ( struct dvb_ca_en50221 * ci , int slot ,
u8 addr , u8 val )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
u8 buf [ ] = { CMD_CI , 0x05 , 0x40 , addr , 0x00 , 1 , val } ;
ret = anysee_ctrl_msg ( d , buf , sizeof ( buf ) , NULL , 0 ) ;
if ( ret )
return ret ;
return 0 ;
}
static int anysee_ci_slot_reset ( struct dvb_ca_en50221 * ci , int slot )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2011-09-05 23:33:04 -03:00
state - > ci_cam_ready = jiffies + msecs_to_jiffies ( 1000 ) ;
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 0 < < 7 ) , 0x80 ) ;
if ( ret )
return ret ;
msleep ( 300 ) ;
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 1 < < 7 ) , 0x80 ) ;
if ( ret )
return ret ;
return 0 ;
}
static int anysee_ci_slot_shutdown ( struct dvb_ca_en50221 * ci , int slot )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 0 < < 7 ) , 0x80 ) ;
if ( ret )
return ret ;
msleep ( 30 ) ;
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 1 < < 7 ) , 0x80 ) ;
if ( ret )
return ret ;
return 0 ;
}
static int anysee_ci_slot_ts_enable ( struct dvb_ca_en50221 * ci , int slot )
{
struct dvb_usb_device * d = ci - > data ;
int ret ;
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 1 ) , 0x02 ) ;
if ( ret )
return ret ;
return 0 ;
}
static int anysee_ci_poll_slot_status ( struct dvb_ca_en50221 * ci , int slot ,
int open )
{
struct dvb_usb_device * d = ci - > data ;
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2011-09-05 23:33:04 -03:00
int ret ;
2012-10-27 16:28:00 -03:00
u8 tmp = 0 ;
2011-09-05 23:33:04 -03:00
ret = anysee_rd_reg_mask ( d , REG_IOC , & tmp , 0x40 ) ;
if ( ret )
return ret ;
if ( tmp = = 0 ) {
ret = DVB_CA_EN50221_POLL_CAM_PRESENT ;
if ( time_after ( jiffies , state - > ci_cam_ready ) )
ret | = DVB_CA_EN50221_POLL_CAM_READY ;
}
return ret ;
}
static int anysee_ci_init ( struct dvb_usb_device * d )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2011-09-05 23:33:04 -03:00
int ret ;
state - > ci . owner = THIS_MODULE ;
state - > ci . read_attribute_mem = anysee_ci_read_attribute_mem ;
state - > ci . write_attribute_mem = anysee_ci_write_attribute_mem ;
state - > ci . read_cam_control = anysee_ci_read_cam_control ;
state - > ci . write_cam_control = anysee_ci_write_cam_control ;
state - > ci . slot_reset = anysee_ci_slot_reset ;
state - > ci . slot_shutdown = anysee_ci_slot_shutdown ;
state - > ci . slot_ts_enable = anysee_ci_slot_ts_enable ;
state - > ci . poll_slot_status = anysee_ci_poll_slot_status ;
state - > ci . data = d ;
ret = anysee_wr_reg_mask ( d , REG_IOA , ( 1 < < 7 ) , 0x80 ) ;
if ( ret )
return ret ;
2012-01-20 17:39:17 -03:00
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 0 < < 2 ) | ( 0 < < 1 ) | ( 0 < < 0 ) , 0x07 ) ;
if ( ret )
return ret ;
ret = anysee_wr_reg_mask ( d , REG_IOD , ( 1 < < 2 ) | ( 1 < < 1 ) | ( 1 < < 0 ) , 0x07 ) ;
if ( ret )
return ret ;
2011-09-05 23:33:04 -03:00
ret = dvb_ca_en50221_init ( & d - > adapter [ 0 ] . dvb_adap , & state - > ci , 0 , 1 ) ;
if ( ret )
return ret ;
2012-09-22 13:46:24 -03:00
state - > ci_attached = true ;
2011-09-05 23:33:04 -03:00
return 0 ;
}
static void anysee_ci_release ( struct dvb_usb_device * d )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2011-09-05 23:33:04 -03:00
/* detach CI */
2012-09-22 13:46:24 -03:00
if ( state - > ci_attached )
2011-09-05 23:33:04 -03:00
dvb_ca_en50221_release ( & state - > ci ) ;
return ;
}
static int anysee_init ( struct dvb_usb_device * d )
{
2012-06-18 19:39:02 -03:00
struct anysee_state * state = d_to_priv ( d ) ;
2011-09-05 23:33:04 -03:00
int ret ;
2012-06-14 04:56:09 -03:00
/* There is one interface with two alternate settings.
Alternate setting 0 is for bulk transfer .
Alternate setting 1 is for isochronous transfer .
We use bulk transfer ( alternate setting 0 ) . */
ret = usb_set_interface ( d - > udev , 0 , 0 ) ;
if ( ret )
return ret ;
2011-09-05 23:33:04 -03:00
/* LED light */
ret = anysee_led_ctrl ( d , 0x01 , 0x03 ) ;
if ( ret )
return ret ;
/* enable IR */
ret = anysee_ir_ctrl ( d , 1 ) ;
if ( ret )
return ret ;
/* attach CI */
if ( state - > has_ci ) {
ret = anysee_ci_init ( d ) ;
2012-09-22 13:46:24 -03:00
if ( ret )
2011-09-05 23:33:04 -03:00
return ret ;
}
return 0 ;
}
2012-06-20 00:32:53 -03:00
static void anysee_exit ( struct dvb_usb_device * d )
2011-09-05 23:33:04 -03:00
{
2012-06-14 04:56:09 -03:00
return anysee_ci_release ( d ) ;
2011-09-05 23:33:04 -03:00
}
2012-06-14 04:56:09 -03:00
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties anysee_props = {
. driver_name = KBUILD_MODNAME ,
. owner = THIS_MODULE ,
. adapter_nr = adapter_nr ,
. size_of_priv = sizeof ( struct anysee_state ) ,
2008-05-17 23:05:48 -03:00
2012-06-14 04:56:09 -03:00
. generic_bulk_ctrl_endpoint = 0x01 ,
. generic_bulk_ctrl_endpoint_response = 0x81 ,
2008-05-17 23:05:48 -03:00
2012-06-14 04:56:09 -03:00
. i2c_algo = & anysee_i2c_algo ,
. read_config = anysee_read_config ,
. frontend_attach = anysee_frontend_attach ,
. tuner_attach = anysee_tuner_attach ,
. init = anysee_init ,
. get_rc_config = anysee_get_rc_config ,
. frontend_ctrl = anysee_frontend_ctrl ,
. streaming_ctrl = anysee_streaming_ctrl ,
2012-06-20 00:32:53 -03:00
. exit = anysee_exit ,
2008-05-17 23:05:48 -03:00
. num_adapters = 1 ,
. adapter = {
{
2012-06-18 19:39:02 -03:00
. stream = DVB_USB_STREAM_BULK ( 0x82 , 8 , 16 * 512 ) ,
2008-05-17 23:05:48 -03:00
}
}
} ;
2012-06-14 04:56:09 -03:00
static const struct usb_device_id anysee_id_table [ ] = {
{ DVB_USB_DEVICE ( USB_VID_CYPRESS , USB_PID_ANYSEE ,
& anysee_props , " Anysee " , RC_MAP_ANYSEE ) } ,
{ DVB_USB_DEVICE ( USB_VID_AMT , USB_PID_ANYSEE ,
& anysee_props , " Anysee " , RC_MAP_ANYSEE ) } ,
{ }
} ;
MODULE_DEVICE_TABLE ( usb , anysee_id_table ) ;
static struct usb_driver anysee_usb_driver = {
. name = KBUILD_MODNAME ,
. id_table = anysee_id_table ,
. probe = dvb_usbv2_probe ,
. disconnect = dvb_usbv2_disconnect ,
. suspend = dvb_usbv2_suspend ,
. resume = dvb_usbv2_resume ,
2012-08-14 22:21:08 -03:00
. reset_resume = dvb_usbv2_reset_resume ,
2012-06-14 04:56:09 -03:00
. no_dynamic_id = 1 ,
. soft_unbind = 1 ,
2008-05-17 23:05:48 -03:00
} ;
2012-06-14 04:56:09 -03:00
module_usb_driver ( anysee_usb_driver ) ;
2008-05-17 23:05:48 -03:00
MODULE_AUTHOR ( " Antti Palosaari <crope@iki.fi> " ) ;
MODULE_DESCRIPTION ( " Driver Anysee E30 DVB-C & DVB-T USB2.0 " ) ;
MODULE_LICENSE ( " GPL " ) ;