2019-05-31 01:09:32 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2008-09-08 17:16:40 -03:00
/* DVB USB framework compliant Linux driver for the
2011-02-25 18:41:23 -03:00
* DVBWorld DVB - S 2101 , 2102 , DVB - S2 2104 , DVB - C 3101 ,
2016-03-02 08:06:06 -03:00
* TeVii S421 , S480 , S482 , S600 , S630 , S632 , S650 , S660 , S662 ,
2011-02-25 18:41:23 -03:00
* Prof 1100 , 7500 ,
2015-03-16 14:22:18 -03:00
* Geniatech SU3000 , T220 ,
2016-03-02 08:06:06 -03:00
* TechnoTrend S2 - 4600 ,
* Terratec Cinergy S2 cards
2012-05-08 03:53:17 -03:00
* Copyright ( C ) 2008 - 2012 Igor M . Liplianin ( liplianin @ me . by )
2011-02-25 18:41:23 -03:00
*
2020-03-04 15:54:10 +01:00
* see Documentation / driver - api / media / drivers / dvb - usb . rst for more information
2011-02-25 18:41:23 -03:00
*/
2017-12-28 13:03:51 -05:00
# include <media/dvb-usb-ids.h>
2008-07-20 08:05:50 -03:00
# include "dw2102.h"
2008-09-17 19:19:19 -03:00
# include "si21xx.h"
2008-07-20 08:05:50 -03:00
# include "stv0299.h"
# include "z0194a.h"
2008-10-05 09:11:21 -03:00
# include "stv0288.h"
# include "stb6000.h"
# include "eds1547.h"
2008-09-08 17:16:40 -03:00
# include "cx24116.h"
2009-06-14 20:51:45 -03:00
# include "tda1002x.h"
2009-06-20 09:54:18 -03:00
# include "mt312.h"
# include "zl10039.h"
2012-12-23 19:25:38 -03:00
# include "ts2020.h"
2009-11-27 14:37:35 -03:00
# include "ds3000.h"
# include "stv0900.h"
# include "stv6110.h"
# include "stb6100.h"
# include "stb6100_proc.h"
2012-05-08 03:53:17 -03:00
# include "m88rs2000.h"
2013-11-13 20:53:59 -03:00
# include "tda18271.h"
# include "cxd2820r.h"
2015-03-16 14:22:18 -03:00
# include "m88ds3103.h"
2008-07-20 08:05:50 -03:00
2013-11-02 07:43:40 -03:00
/* Max transfer size done by I2C transfer functions */
# define MAX_XFER_SIZE 64
2013-03-07 09:36:22 -03:00
2008-09-17 19:19:19 -03:00
# define DW210X_READ_MSG 0
# define DW210X_WRITE_MSG 1
2008-07-20 08:05:50 -03:00
# define REG_1F_SYMBOLRATE_BYTE0 0x1f
# define REG_20_SYMBOLRATE_BYTE1 0x20
# define REG_21_SYMBOLRATE_BYTE2 0x21
2008-09-08 17:16:40 -03:00
/* on my own*/
2008-07-20 08:05:50 -03:00
# define DW2102_VOLTAGE_CTRL (0x1800)
2011-02-25 18:41:22 -03:00
# define SU3000_STREAM_CTRL (0x1900)
2008-07-20 08:05:50 -03:00
# define DW2102_RC_QUERY (0x1a00)
2011-02-25 18:41:22 -03:00
# define DW2102_LED_CTRL (0x1b00)
2008-07-20 08:05:50 -03:00
2012-09-28 08:59:32 -03:00
# define DW2101_FIRMWARE "dvb-usb-dw2101.fw"
# define DW2102_FIRMWARE "dvb-usb-dw2102.fw"
# define DW2104_FIRMWARE "dvb-usb-dw2104.fw"
# define DW3101_FIRMWARE "dvb-usb-dw3101.fw"
# define S630_FIRMWARE "dvb-usb-s630.fw"
# define S660_FIRMWARE "dvb-usb-s660.fw"
# define P1100_FIRMWARE "dvb-usb-p1100.fw"
# define P7500_FIRMWARE "dvb-usb-p7500.fw"
2018-05-08 18:10:05 -03:00
# define err_str "did not find the firmware file '%s'. You can use <kernel_dir> / scripts / get_dvb_firmware to get the firmware"
2009-11-27 14:37:35 -03:00
2015-03-16 14:14:04 -03:00
struct dw2102_state {
2011-02-25 18:41:22 -03:00
u8 initialized ;
2015-05-05 13:33:55 -03:00
u8 last_lock ;
2017-02-15 18:29:15 -02:00
u8 data [ MAX_XFER_SIZE + 4 ] ;
2016-02-16 15:53:45 -02:00
struct i2c_client * i2c_client_demod ;
2015-03-16 14:14:05 -03:00
struct i2c_client * i2c_client_tuner ;
2015-05-05 13:33:55 -03:00
/* fe hook functions*/
2015-06-07 14:53:52 -03:00
int ( * old_set_voltage ) ( struct dvb_frontend * f , enum fe_sec_voltage v ) ;
2015-05-05 13:33:55 -03:00
int ( * fe_read_status ) ( struct dvb_frontend * fe ,
2015-06-07 14:53:52 -03:00
enum fe_status * status ) ;
2011-02-25 18:41:23 -03:00
} ;
2008-09-08 17:16:40 -03:00
/* debug */
static int dvb_usb_dw2102_debug ;
module_param_named ( debug , dvb_usb_dw2102_debug , int , 0644 ) ;
2009-06-13 08:10:24 -03:00
MODULE_PARM_DESC ( debug , " set debugging level (1=info 2=xfer 4=rc(or-able)). "
DVB_USB_DEBUG_STATUS ) ;
2009-11-27 14:37:35 -03:00
/* demod probe */
static int demod_probe = 1 ;
module_param_named ( demod , demod_probe , int , 0644 ) ;
[media] dvb-usb: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-18 17:44:15 -02:00
MODULE_PARM_DESC ( demod , " demod to probe (1=cx24116 2=stv0903+stv6110 4=stv0903+stb6100(or-able)). " ) ;
2009-11-27 14:37:35 -03:00
2008-07-20 08:05:50 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2008-09-17 19:19:19 -03:00
static int dw210x_op_rw ( struct usb_device * dev , u8 request , u16 value ,
2008-09-08 17:16:40 -03:00
u16 index , u8 * data , u16 len , int flags )
2008-07-20 08:05:50 -03:00
{
int ret ;
2011-03-21 15:33:44 -03:00
u8 * u8buf ;
2008-09-17 19:19:19 -03:00
unsigned int pipe = ( flags = = DW210X_READ_MSG ) ?
2008-09-08 17:16:40 -03:00
usb_rcvctrlpipe ( dev , 0 ) : usb_sndctrlpipe ( dev , 0 ) ;
2008-09-17 19:19:19 -03:00
u8 request_type = ( flags = = DW210X_READ_MSG ) ? USB_DIR_IN : USB_DIR_OUT ;
2008-07-20 08:05:50 -03:00
2011-03-21 15:33:44 -03:00
u8buf = kmalloc ( len , GFP_KERNEL ) ;
if ( ! u8buf )
return - ENOMEM ;
2008-09-17 19:19:19 -03:00
if ( flags = = DW210X_WRITE_MSG )
2008-07-20 08:05:50 -03:00
memcpy ( u8buf , data , len ) ;
2008-09-08 17:16:40 -03:00
ret = usb_control_msg ( dev , pipe , request , request_type | USB_TYPE_VENDOR ,
value , index , u8buf , len , 2000 ) ;
2008-07-20 08:05:50 -03:00
2008-09-17 19:19:19 -03:00
if ( flags = = DW210X_READ_MSG )
2008-07-20 08:05:50 -03:00
memcpy ( data , u8buf , len ) ;
2011-03-21 15:33:44 -03:00
kfree ( u8buf ) ;
2008-07-20 08:05:50 -03:00
return ret ;
}
/* I2C */
static int dw2102_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] ,
int num )
{
2009-06-14 20:51:45 -03:00
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2012-04-20 03:30:11 -03:00
int i = 0 ;
2008-07-20 08:05:50 -03:00
u8 buf6 [ ] = { 0x2c , 0x05 , 0xc0 , 0 , 0 , 0 , 0 } ;
u16 value ;
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
switch ( num ) {
case 2 :
/* read stv0299 register */
value = msg [ 0 ] . buf [ 0 ] ; /* register */
for ( i = 0 ; i < msg [ 1 ] . len ; i + + ) {
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb5 , value + i , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 2 , DW210X_READ_MSG ) ;
2008-07-20 08:05:50 -03:00
msg [ 1 ] . buf [ i ] = buf6 [ 0 ] ;
}
break ;
case 1 :
switch ( msg [ 0 ] . addr ) {
case 0x68 :
/* write to stv0299 register */
buf6 [ 0 ] = 0x2a ;
buf6 [ 1 ] = msg [ 0 ] . buf [ 0 ] ;
buf6 [ 2 ] = msg [ 0 ] . buf [ 1 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 3 , DW210X_WRITE_MSG ) ;
2008-07-20 08:05:50 -03:00
break ;
case 0x60 :
if ( msg [ 0 ] . flags = = 0 ) {
/* write to tuner pll */
buf6 [ 0 ] = 0x2c ;
buf6 [ 1 ] = 5 ;
buf6 [ 2 ] = 0xc0 ;
buf6 [ 3 ] = msg [ 0 ] . buf [ 0 ] ;
buf6 [ 4 ] = msg [ 0 ] . buf [ 1 ] ;
buf6 [ 5 ] = msg [ 0 ] . buf [ 2 ] ;
buf6 [ 6 ] = msg [ 0 ] . buf [ 3 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 7 , DW210X_WRITE_MSG ) ;
2008-07-20 08:05:50 -03:00
} else {
2008-09-08 17:16:40 -03:00
/* read from tuner */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb5 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 1 , DW210X_READ_MSG ) ;
2008-07-20 08:05:50 -03:00
msg [ 0 ] . buf [ 0 ] = buf6 [ 0 ] ;
}
break ;
case ( DW2102_RC_QUERY ) :
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 2 , DW210X_READ_MSG ) ;
2008-07-20 08:05:50 -03:00
msg [ 0 ] . buf [ 0 ] = buf6 [ 0 ] ;
msg [ 0 ] . buf [ 1 ] = buf6 [ 1 ] ;
break ;
case ( DW2102_VOLTAGE_CTRL ) :
buf6 [ 0 ] = 0x30 ;
buf6 [ 1 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 2 , DW210X_WRITE_MSG ) ;
2008-07-20 08:05:50 -03:00
break ;
}
break ;
}
mutex_unlock ( & d - > i2c_mutex ) ;
return num ;
}
2008-09-17 19:19:19 -03:00
static int dw2102_serit_i2c_transfer ( struct i2c_adapter * adap ,
struct i2c_msg msg [ ] , int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
u8 buf6 [ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
switch ( num ) {
case 2 :
2017-04-01 14:34:49 -03:00
if ( msg [ 0 ] . len ! = 1 ) {
warn ( " i2c rd: len=%d is not 1! \n " ,
msg [ 0 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
if ( 2 + msg [ 1 ] . len > sizeof ( buf6 ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
2008-09-17 19:19:19 -03:00
/* read si2109 register by number */
2009-11-27 14:37:35 -03:00
buf6 [ 0 ] = msg [ 0 ] . addr < < 1 ;
2008-09-17 19:19:19 -03:00
buf6 [ 1 ] = msg [ 0 ] . len ;
buf6 [ 2 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
/* read si2109 register */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc3 , 0xd0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , msg [ 1 ] . len + 2 , DW210X_READ_MSG ) ;
memcpy ( msg [ 1 ] . buf , buf6 + 2 , msg [ 1 ] . len ) ;
break ;
case 1 :
switch ( msg [ 0 ] . addr ) {
case 0x68 :
2017-04-01 14:34:49 -03:00
if ( 2 + msg [ 0 ] . len > sizeof ( buf6 ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ 0 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
2008-09-17 19:19:19 -03:00
/* write to si2109 register */
2009-11-27 14:37:35 -03:00
buf6 [ 0 ] = msg [ 0 ] . addr < < 1 ;
2008-09-17 19:19:19 -03:00
buf6 [ 1 ] = msg [ 0 ] . len ;
memcpy ( buf6 + 2 , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 , buf6 ,
2008-09-17 19:19:19 -03:00
msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
break ;
case ( DW2102_RC_QUERY ) :
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 2 , DW210X_READ_MSG ) ;
msg [ 0 ] . buf [ 0 ] = buf6 [ 0 ] ;
msg [ 0 ] . buf [ 1 ] = buf6 [ 1 ] ;
break ;
case ( DW2102_VOLTAGE_CTRL ) :
buf6 [ 0 ] = 0x30 ;
buf6 [ 1 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
buf6 , 2 , DW210X_WRITE_MSG ) ;
break ;
}
break ;
}
mutex_unlock ( & d - > i2c_mutex ) ;
return num ;
}
2009-06-14 20:51:45 -03:00
2008-10-05 09:11:21 -03:00
static int dw2102_earda_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] , int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2013-11-22 04:56:33 -03:00
int ret ;
2008-10-05 09:11:21 -03:00
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
switch ( num ) {
case 2 : {
/* read */
/* first write first register number */
2013-11-02 07:43:40 -03:00
u8 ibuf [ MAX_XFER_SIZE ] , obuf [ 3 ] ;
2017-04-01 14:34:49 -03:00
if ( 2 + msg [ 0 ] . len ! = sizeof ( obuf ) ) {
warn ( " i2c rd: len=%d is not 1! \n " ,
msg [ 0 ] . len ) ;
ret = - EOPNOTSUPP ;
goto unlock ;
}
2013-11-02 07:43:40 -03:00
if ( 2 + msg [ 1 ] . len > sizeof ( ibuf ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = msg [ 0 ] . addr < < 1 ;
2008-10-05 09:11:21 -03:00
obuf [ 1 ] = msg [ 0 ] . len ;
obuf [ 2 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2008-10-05 09:11:21 -03:00
obuf , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
/* second read registers */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc3 , 0xd1 , 0 ,
2008-10-05 09:11:21 -03:00
ibuf , msg [ 1 ] . len + 2 , DW210X_READ_MSG ) ;
memcpy ( msg [ 1 ] . buf , ibuf + 2 , msg [ 1 ] . len ) ;
break ;
}
case 1 :
switch ( msg [ 0 ] . addr ) {
case 0x68 : {
/* write to register */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ 0 ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = msg [ 0 ] . addr < < 1 ;
2008-10-05 09:11:21 -03:00
obuf [ 1 ] = msg [ 0 ] . len ;
memcpy ( obuf + 2 , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2008-10-05 09:11:21 -03:00
obuf , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
break ;
}
case 0x61 : {
/* write to tuner */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ 0 ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = msg [ 0 ] . addr < < 1 ;
2008-10-05 09:11:21 -03:00
obuf [ 1 ] = msg [ 0 ] . len ;
memcpy ( obuf + 2 , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2008-10-05 09:11:21 -03:00
obuf , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
break ;
}
case ( DW2102_RC_QUERY ) : {
u8 ibuf [ 2 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2008-10-05 09:11:21 -03:00
ibuf , 2 , DW210X_READ_MSG ) ;
memcpy ( msg [ 0 ] . buf , ibuf , 2 ) ;
break ;
}
case ( DW2102_VOLTAGE_CTRL ) : {
u8 obuf [ 2 ] ;
obuf [ 0 ] = 0x30 ;
obuf [ 1 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-10-05 09:11:21 -03:00
obuf , 2 , DW210X_WRITE_MSG ) ;
break ;
}
}
break ;
}
2013-11-22 04:56:33 -03:00
ret = num ;
2008-10-05 09:11:21 -03:00
2013-11-22 04:56:33 -03:00
unlock :
2008-10-05 09:11:21 -03:00
mutex_unlock ( & d - > i2c_mutex ) ;
2013-11-22 04:56:33 -03:00
return ret ;
2008-10-05 09:11:21 -03:00
}
2008-09-17 19:19:19 -03:00
2008-09-08 17:16:40 -03:00
static int dw2104_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] , int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2013-11-22 04:56:33 -03:00
int len , i , j , ret ;
2008-09-08 17:16:40 -03:00
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
2009-11-27 14:37:35 -03:00
for ( j = 0 ; j < num ; j + + ) {
switch ( msg [ j ] . addr ) {
2008-09-08 17:16:40 -03:00
case ( DW2102_RC_QUERY ) : {
u8 ibuf [ 2 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
ibuf , 2 , DW210X_READ_MSG ) ;
2009-11-27 14:37:35 -03:00
memcpy ( msg [ j ] . buf , ibuf , 2 ) ;
2008-09-08 17:16:40 -03:00
break ;
}
case ( DW2102_VOLTAGE_CTRL ) : {
u8 obuf [ 2 ] ;
obuf [ 0 ] = 0x30 ;
2009-11-27 14:37:35 -03:00
obuf [ 1 ] = msg [ j ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb2 , 0 , 0 ,
2008-09-17 19:19:19 -03:00
obuf , 2 , DW210X_WRITE_MSG ) ;
2008-09-08 17:16:40 -03:00
break ;
}
2009-11-27 14:37:35 -03:00
/*case 0x55: cx24116
case 0x6a : stv0903
case 0x68 : ds3000 , stv0903
case 0x60 : ts2020 , stv6110 , stb6100 */
default : {
if ( msg [ j ] . flags = = I2C_M_RD ) {
/* read registers */
2013-11-02 07:43:40 -03:00
u8 ibuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ j ] . len > sizeof ( ibuf ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ j ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc3 ,
2009-11-27 14:37:35 -03:00
( msg [ j ] . addr < < 1 ) + 1 , 0 ,
ibuf , msg [ j ] . len + 2 ,
DW210X_READ_MSG ) ;
memcpy ( msg [ j ] . buf , ibuf + 2 , msg [ j ] . len ) ;
2015-04-29 20:19:20 -03:00
mdelay ( 10 ) ;
2009-11-27 14:37:35 -03:00
} else if ( ( ( msg [ j ] . buf [ 0 ] = = 0xb0 ) & &
( msg [ j ] . addr = = 0x68 ) ) | |
( ( msg [ j ] . buf [ 0 ] = = 0xf7 ) & &
( msg [ j ] . addr = = 0x55 ) ) ) {
/* write firmware */
u8 obuf [ 19 ] ;
obuf [ 0 ] = msg [ j ] . addr < < 1 ;
obuf [ 1 ] = ( msg [ j ] . len > 15 ? 17 : msg [ j ] . len ) ;
obuf [ 2 ] = msg [ j ] . buf [ 0 ] ;
len = msg [ j ] . len - 1 ;
i = 1 ;
do {
memcpy ( obuf + 3 , msg [ j ] . buf + i ,
( len > 16 ? 16 : len ) ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2009-11-27 14:37:35 -03:00
obuf , ( len > 16 ? 16 : len ) + 3 ,
DW210X_WRITE_MSG ) ;
i + = 16 ;
len - = 16 ;
} while ( len > 0 ) ;
} else {
/* write registers */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ j ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ j ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = msg [ j ] . addr < < 1 ;
obuf [ 1 ] = msg [ j ] . len ;
memcpy ( obuf + 2 , msg [ j ] . buf , msg [ j ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2009-11-27 14:37:35 -03:00
obuf , msg [ j ] . len + 2 ,
DW210X_WRITE_MSG ) ;
}
break ;
}
2008-09-08 17:16:40 -03:00
}
}
2013-11-22 04:56:33 -03:00
ret = num ;
2008-09-08 17:16:40 -03:00
2013-11-22 04:56:33 -03:00
unlock :
2008-09-08 17:16:40 -03:00
mutex_unlock ( & d - > i2c_mutex ) ;
2013-11-22 04:56:33 -03:00
return ret ;
2008-09-08 17:16:40 -03:00
}
2009-06-14 20:51:45 -03:00
static int dw3101_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] ,
int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2013-11-22 04:56:33 -03:00
int ret ;
2012-04-20 03:30:11 -03:00
int i ;
2009-06-14 20:51:45 -03:00
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
switch ( num ) {
case 2 : {
/* read */
/* first write first register number */
2013-11-02 07:43:40 -03:00
u8 ibuf [ MAX_XFER_SIZE ] , obuf [ 3 ] ;
2017-04-01 14:34:49 -03:00
if ( 2 + msg [ 0 ] . len ! = sizeof ( obuf ) ) {
warn ( " i2c rd: len=%d is not 1! \n " ,
msg [ 0 ] . len ) ;
ret = - EOPNOTSUPP ;
goto unlock ;
}
2013-11-02 07:43:40 -03:00
if ( 2 + msg [ 1 ] . len > sizeof ( ibuf ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-06-14 20:51:45 -03:00
obuf [ 0 ] = msg [ 0 ] . addr < < 1 ;
obuf [ 1 ] = msg [ 0 ] . len ;
obuf [ 2 ] = msg [ 0 ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2009-06-14 20:51:45 -03:00
obuf , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
/* second read registers */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc3 , 0x19 , 0 ,
2009-06-14 20:51:45 -03:00
ibuf , msg [ 1 ] . len + 2 , DW210X_READ_MSG ) ;
memcpy ( msg [ 1 ] . buf , ibuf + 2 , msg [ 1 ] . len ) ;
break ;
}
case 1 :
switch ( msg [ 0 ] . addr ) {
case 0x60 :
case 0x0c : {
/* write to register */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ 0 ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ 0 ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-06-14 20:51:45 -03:00
obuf [ 0 ] = msg [ 0 ] . addr < < 1 ;
obuf [ 1 ] = msg [ 0 ] . len ;
memcpy ( obuf + 2 , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xc2 , 0 , 0 ,
2009-06-14 20:51:45 -03:00
obuf , msg [ 0 ] . len + 2 , DW210X_WRITE_MSG ) ;
break ;
}
case ( DW2102_RC_QUERY ) : {
u8 ibuf [ 2 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2009-06-14 20:51:45 -03:00
ibuf , 2 , DW210X_READ_MSG ) ;
memcpy ( msg [ 0 ] . buf , ibuf , 2 ) ;
break ;
}
}
break ;
}
for ( i = 0 ; i < num ; i + + ) {
deb_xfer ( " %02x:%02x: %s " , i , msg [ i ] . addr ,
msg [ i ] . flags = = 0 ? " >>> " : " <<< " ) ;
debug_dump ( msg [ i ] . buf , msg [ i ] . len , deb_xfer ) ;
}
2013-11-22 04:56:33 -03:00
ret = num ;
2009-06-14 20:51:45 -03:00
2013-11-22 04:56:33 -03:00
unlock :
2009-06-14 20:51:45 -03:00
mutex_unlock ( & d - > i2c_mutex ) ;
2013-11-22 04:56:33 -03:00
return ret ;
2009-06-14 20:51:45 -03:00
}
2009-11-27 14:37:35 -03:00
static int s6x0_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] ,
2009-06-20 09:54:18 -03:00
int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2009-12-22 18:00:07 -03:00
struct usb_device * udev ;
2013-11-22 04:56:33 -03:00
int len , i , j , ret ;
2009-06-20 09:54:18 -03:00
if ( ! d )
return - ENODEV ;
2009-12-22 18:00:07 -03:00
udev = d - > udev ;
2009-06-20 09:54:18 -03:00
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
2009-11-27 14:37:35 -03:00
for ( j = 0 ; j < num ; j + + ) {
switch ( msg [ j ] . addr ) {
2009-06-20 09:54:18 -03:00
case ( DW2102_RC_QUERY ) : {
2011-02-25 18:41:23 -03:00
u8 ibuf [ 5 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0xb8 , 0 , 0 ,
2011-02-25 18:41:23 -03:00
ibuf , 5 , DW210X_READ_MSG ) ;
memcpy ( msg [ j ] . buf , ibuf + 3 , 2 ) ;
2009-06-20 09:54:18 -03:00
break ;
}
case ( DW2102_VOLTAGE_CTRL ) : {
u8 obuf [ 2 ] ;
2009-12-14 20:24:56 -03:00
obuf [ 0 ] = 1 ;
obuf [ 1 ] = msg [ j ] . buf [ 1 ] ; /* off-on */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x8a , 0 , 0 ,
2009-12-14 20:24:56 -03:00
obuf , 2 , DW210X_WRITE_MSG ) ;
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = 3 ;
2009-12-14 20:24:56 -03:00
obuf [ 1 ] = msg [ j ] . buf [ 0 ] ; /* 13v-18v */
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x8a , 0 , 0 ,
2009-06-20 09:54:18 -03:00
obuf , 2 , DW210X_WRITE_MSG ) ;
break ;
}
2011-02-25 18:41:22 -03:00
case ( DW2102_LED_CTRL ) : {
u8 obuf [ 2 ] ;
obuf [ 0 ] = 5 ;
obuf [ 1 ] = msg [ j ] . buf [ 0 ] ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x8a , 0 , 0 ,
2011-02-25 18:41:22 -03:00
obuf , 2 , DW210X_WRITE_MSG ) ;
break ;
}
2009-11-27 14:37:35 -03:00
/*case 0x55: cx24116
case 0x6a : stv0903
2012-05-08 03:53:17 -03:00
case 0x68 : ds3000 , stv0903 , rs2000
2009-11-27 14:37:35 -03:00
case 0x60 : ts2020 , stv6110 , stb6100
case 0xa0 : eeprom */
default : {
if ( msg [ j ] . flags = = I2C_M_RD ) {
/* read registers */
2013-11-02 07:43:40 -03:00
u8 ibuf [ MAX_XFER_SIZE ] ;
if ( msg [ j ] . len > sizeof ( ibuf ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ j ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x91 , 0 , 0 ,
2009-11-27 14:37:35 -03:00
ibuf , msg [ j ] . len ,
DW210X_READ_MSG ) ;
memcpy ( msg [ j ] . buf , ibuf , msg [ j ] . len ) ;
break ;
} else if ( ( msg [ j ] . buf [ 0 ] = = 0xb0 ) & &
( msg [ j ] . addr = = 0x68 ) ) {
/* write firmware */
u8 obuf [ 19 ] ;
obuf [ 0 ] = ( msg [ j ] . len > 16 ?
18 : msg [ j ] . len + 1 ) ;
obuf [ 1 ] = msg [ j ] . addr < < 1 ;
obuf [ 2 ] = msg [ j ] . buf [ 0 ] ;
len = msg [ j ] . len - 1 ;
i = 1 ;
do {
memcpy ( obuf + 3 , msg [ j ] . buf + i ,
( len > 16 ? 16 : len ) ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x80 , 0 , 0 ,
2009-11-27 14:37:35 -03:00
obuf , ( len > 16 ? 16 : len ) + 3 ,
DW210X_WRITE_MSG ) ;
i + = 16 ;
len - = 16 ;
} while ( len > 0 ) ;
2011-02-27 16:18:38 -03:00
} else if ( j < ( num - 1 ) ) {
2009-12-14 20:24:56 -03:00
/* write register addr before read */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ j ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ j ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-12-14 20:24:56 -03:00
obuf [ 0 ] = msg [ j + 1 ] . len ;
obuf [ 1 ] = ( msg [ j ] . addr < < 1 ) ;
memcpy ( obuf + 2 , msg [ j ] . buf , msg [ j ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev ,
2014-08-20 16:45:27 -03:00
le16_to_cpu ( udev - > descriptor . idProduct ) = =
2011-02-27 16:18:38 -03:00
0x7500 ? 0x92 : 0x90 , 0 , 0 ,
2009-12-14 20:24:56 -03:00
obuf , msg [ j ] . len + 2 ,
DW210X_WRITE_MSG ) ;
break ;
2009-11-27 14:37:35 -03:00
} else {
/* write registers */
2013-11-02 07:43:40 -03:00
u8 obuf [ MAX_XFER_SIZE ] ;
if ( 2 + msg [ j ] . len > sizeof ( obuf ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ j ] . len ) ;
2013-11-22 04:56:33 -03:00
ret = - EOPNOTSUPP ;
goto unlock ;
2013-11-02 07:43:40 -03:00
}
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = msg [ j ] . len + 1 ;
obuf [ 1 ] = ( msg [ j ] . addr < < 1 ) ;
memcpy ( obuf + 2 , msg [ j ] . buf , msg [ j ] . len ) ;
2012-04-20 03:30:11 -03:00
dw210x_op_rw ( d - > udev , 0x80 , 0 , 0 ,
2009-11-27 14:37:35 -03:00
obuf , msg [ j ] . len + 2 ,
DW210X_WRITE_MSG ) ;
break ;
}
break ;
}
2009-06-20 09:54:18 -03:00
}
}
2013-11-22 04:56:33 -03:00
ret = num ;
2009-06-20 09:54:18 -03:00
2013-11-22 04:56:33 -03:00
unlock :
2009-06-20 09:54:18 -03:00
mutex_unlock ( & d - > i2c_mutex ) ;
2013-11-22 04:56:33 -03:00
return ret ;
2009-06-20 09:54:18 -03:00
}
2011-02-25 18:41:22 -03:00
static int su3000_i2c_transfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] ,
int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
2017-02-15 18:29:15 -02:00
struct dw2102_state * state ;
2011-02-25 18:41:22 -03:00
if ( ! d )
return - ENODEV ;
2017-02-15 18:29:15 -02:00
state = d - > priv ;
2011-02-25 18:41:22 -03:00
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
2017-02-15 18:29:15 -02:00
if ( mutex_lock_interruptible ( & d - > data_mutex ) < 0 ) {
mutex_unlock ( & d - > i2c_mutex ) ;
return - EAGAIN ;
}
2011-02-25 18:41:22 -03:00
switch ( num ) {
case 1 :
switch ( msg [ 0 ] . addr ) {
case SU3000_STREAM_CTRL :
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = msg [ 0 ] . buf [ 0 ] + 0x36 ;
state - > data [ 1 ] = 3 ;
state - > data [ 2 ] = 0 ;
if ( dvb_usb_generic_rw ( d , state - > data , 3 ,
state - > data , 0 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " i2c transfer failed. " ) ;
break ;
case DW2102_RC_QUERY :
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x10 ;
if ( dvb_usb_generic_rw ( d , state - > data , 1 ,
state - > data , 2 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " i2c transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
msg [ 0 ] . buf [ 1 ] = state - > data [ 0 ] ;
msg [ 0 ] . buf [ 0 ] = state - > data [ 1 ] ;
2011-02-25 18:41:22 -03:00
break ;
default :
2017-04-01 14:34:49 -03:00
if ( 3 + msg [ 0 ] . len > sizeof ( state - > data ) ) {
warn ( " i2c wr: len=%d is too big! \n " ,
msg [ 0 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
2011-02-25 18:41:22 -03:00
/* always i2c write*/
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x08 ;
state - > data [ 1 ] = msg [ 0 ] . addr ;
state - > data [ 2 ] = msg [ 0 ] . len ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
memcpy ( & state - > data [ 3 ] , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , msg [ 0 ] . len + 3 ,
state - > data , 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " i2c transfer failed. " ) ;
}
break ;
case 2 :
/* always i2c read */
2017-04-01 14:34:49 -03:00
if ( 4 + msg [ 0 ] . len > sizeof ( state - > data ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ 0 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
if ( 1 + msg [ 1 ] . len > sizeof ( state - > data ) ) {
warn ( " i2c rd: len=%d is too big! \n " ,
msg [ 1 ] . len ) ;
num = - EOPNOTSUPP ;
break ;
}
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x09 ;
state - > data [ 1 ] = msg [ 0 ] . len ;
state - > data [ 2 ] = msg [ 1 ] . len ;
state - > data [ 3 ] = msg [ 0 ] . addr ;
memcpy ( & state - > data [ 4 ] , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
if ( dvb_usb_generic_rw ( d , state - > data , msg [ 0 ] . len + 4 ,
state - > data , msg [ 1 ] . len + 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " i2c transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
memcpy ( msg [ 1 ] . buf , & state - > data [ 1 ] , msg [ 1 ] . len ) ;
2011-02-25 18:41:22 -03:00
break ;
default :
warn ( " more than 2 i2c messages at a time is not handled yet. " ) ;
break ;
}
2017-02-15 18:29:15 -02:00
mutex_unlock ( & d - > data_mutex ) ;
2011-02-25 18:41:22 -03:00
mutex_unlock ( & d - > i2c_mutex ) ;
return num ;
}
2008-09-17 19:19:19 -03:00
static u32 dw210x_i2c_func ( struct i2c_adapter * adapter )
2008-07-20 08:05:50 -03:00
{
return I2C_FUNC_I2C ;
}
static struct i2c_algorithm dw2102_i2c_algo = {
. master_xfer = dw2102_i2c_transfer ,
2008-09-17 19:19:19 -03:00
. functionality = dw210x_i2c_func ,
} ;
static struct i2c_algorithm dw2102_serit_i2c_algo = {
. master_xfer = dw2102_serit_i2c_transfer ,
. functionality = dw210x_i2c_func ,
2008-07-20 08:05:50 -03:00
} ;
2008-10-05 09:11:21 -03:00
static struct i2c_algorithm dw2102_earda_i2c_algo = {
. master_xfer = dw2102_earda_i2c_transfer ,
. functionality = dw210x_i2c_func ,
} ;
2008-09-08 17:16:40 -03:00
static struct i2c_algorithm dw2104_i2c_algo = {
. master_xfer = dw2104_i2c_transfer ,
2008-09-17 19:19:19 -03:00
. functionality = dw210x_i2c_func ,
2008-09-08 17:16:40 -03:00
} ;
2009-06-14 20:51:45 -03:00
static struct i2c_algorithm dw3101_i2c_algo = {
. master_xfer = dw3101_i2c_transfer ,
. functionality = dw210x_i2c_func ,
} ;
2009-11-27 14:37:35 -03:00
static struct i2c_algorithm s6x0_i2c_algo = {
. master_xfer = s6x0_i2c_transfer ,
2009-06-20 09:54:18 -03:00
. functionality = dw210x_i2c_func ,
} ;
2011-02-25 18:41:22 -03:00
static struct i2c_algorithm su3000_i2c_algo = {
. master_xfer = su3000_i2c_transfer ,
. functionality = dw210x_i2c_func ,
} ;
2008-09-17 19:19:19 -03:00
static int dw210x_read_mac_address ( struct dvb_usb_device * d , u8 mac [ 6 ] )
2008-09-08 17:16:40 -03:00
{
int i ;
u8 ibuf [ ] = { 0 , 0 } ;
u8 eeprom [ 256 ] , eepromline [ 16 ] ;
for ( i = 0 ; i < 256 ; i + + ) {
2008-09-17 19:19:19 -03:00
if ( dw210x_op_rw ( d - > udev , 0xb6 , 0xa0 , i , ibuf , 2 , DW210X_READ_MSG ) < 0 ) {
2008-09-08 17:16:40 -03:00
err ( " read eeprom failed. " ) ;
return - 1 ;
} else {
eepromline [ i % 16 ] = ibuf [ 0 ] ;
eeprom [ i ] = ibuf [ 0 ] ;
}
if ( ( i % 16 ) = = 15 ) {
deb_xfer ( " %02x: " , i - 15 ) ;
debug_dump ( eepromline , 16 , deb_xfer ) ;
}
}
2009-06-14 20:51:45 -03:00
2008-09-08 17:16:40 -03:00
memcpy ( mac , eeprom + 8 , 6 ) ;
return 0 ;
} ;
2009-11-27 14:37:35 -03:00
static int s6x0_read_mac_address ( struct dvb_usb_device * d , u8 mac [ 6 ] )
2009-06-20 09:54:18 -03:00
{
int i , ret ;
2009-11-27 14:37:35 -03:00
u8 ibuf [ ] = { 0 } , obuf [ ] = { 0 } ;
u8 eeprom [ 256 ] , eepromline [ 16 ] ;
struct i2c_msg msg [ ] = {
{
. addr = 0xa0 > > 1 ,
. flags = 0 ,
. buf = obuf ,
. len = 1 ,
} , {
. addr = 0xa0 > > 1 ,
. flags = I2C_M_RD ,
. buf = ibuf ,
. len = 1 ,
}
} ;
2009-06-20 09:54:18 -03:00
for ( i = 0 ; i < 256 ; i + + ) {
2009-11-27 14:37:35 -03:00
obuf [ 0 ] = i ;
ret = s6x0_i2c_transfer ( & d - > i2c_adap , msg , 2 ) ;
if ( ret ! = 2 ) {
2009-06-20 09:54:18 -03:00
err ( " read eeprom failed. " ) ;
return - 1 ;
} else {
2009-11-27 14:37:35 -03:00
eepromline [ i % 16 ] = ibuf [ 0 ] ;
eeprom [ i ] = ibuf [ 0 ] ;
2009-06-20 09:54:18 -03:00
}
if ( ( i % 16 ) = = 15 ) {
deb_xfer ( " %02x: " , i - 15 ) ;
debug_dump ( eepromline , 16 , deb_xfer ) ;
}
}
memcpy ( mac , eeprom + 16 , 6 ) ;
return 0 ;
} ;
2011-02-25 18:41:22 -03:00
static int su3000_streaming_ctrl ( struct dvb_usb_adapter * adap , int onoff )
{
static u8 command_start [ ] = { 0x00 } ;
static u8 command_stop [ ] = { 0x01 } ;
struct i2c_msg msg = {
. addr = SU3000_STREAM_CTRL ,
. flags = 0 ,
. buf = onoff ? command_start : command_stop ,
. len = 1
} ;
i2c_transfer ( & adap - > dev - > i2c_adap , & msg , 1 ) ;
return 0 ;
}
static int su3000_power_ctrl ( struct dvb_usb_device * d , int i )
{
2015-03-16 14:14:04 -03:00
struct dw2102_state * state = ( struct dw2102_state * ) d - > priv ;
2017-02-15 18:29:15 -02:00
int ret = 0 ;
2011-02-25 18:41:22 -03:00
2016-06-06 10:23:59 -03:00
info ( " %s: %d, initialized %d " , __func__ , i , state - > initialized ) ;
2011-02-25 18:41:22 -03:00
if ( i & & ! state - > initialized ) {
2017-02-15 18:29:15 -02:00
mutex_lock ( & d - > data_mutex ) ;
state - > data [ 0 ] = 0xde ;
state - > data [ 1 ] = 0 ;
2011-02-25 18:41:22 -03:00
state - > initialized = 1 ;
/* reset board */
2017-02-15 18:29:15 -02:00
ret = dvb_usb_generic_rw ( d , state - > data , 2 , NULL , 0 , 0 ) ;
mutex_unlock ( & d - > data_mutex ) ;
2011-02-25 18:41:22 -03:00
}
2017-02-15 18:29:15 -02:00
return ret ;
2011-02-25 18:41:22 -03:00
}
static int su3000_read_mac_address ( struct dvb_usb_device * d , u8 mac [ 6 ] )
{
int i ;
u8 obuf [ ] = { 0x1f , 0xf0 } ;
u8 ibuf [ ] = { 0 } ;
struct i2c_msg msg [ ] = {
{
. addr = 0x51 ,
. flags = 0 ,
. buf = obuf ,
. len = 2 ,
} , {
. addr = 0x51 ,
. flags = I2C_M_RD ,
. buf = ibuf ,
. len = 1 ,
}
} ;
for ( i = 0 ; i < 6 ; i + + ) {
obuf [ 1 ] = 0xf0 + i ;
if ( i2c_transfer ( & d - > i2c_adap , msg , 2 ) ! = 2 )
break ;
else
mac [ i ] = ibuf [ 0 ] ;
}
return 0 ;
}
static int su3000_identify_state ( struct usb_device * udev ,
2020-04-14 12:10:43 +02:00
const struct dvb_usb_device_properties * props ,
const struct dvb_usb_device_description * * desc ,
2011-02-25 18:41:22 -03:00
int * cold )
{
2016-06-06 10:23:59 -03:00
info ( " %s " , __func__ ) ;
2011-02-25 18:41:22 -03:00
* cold = 0 ;
return 0 ;
}
2015-06-07 14:53:52 -03:00
static int dw210x_set_voltage ( struct dvb_frontend * fe ,
enum fe_sec_voltage voltage )
2008-07-20 08:05:50 -03:00
{
2009-12-14 20:24:56 -03:00
static u8 command_13v [ ] = { 0x00 , 0x01 } ;
static u8 command_18v [ ] = { 0x01 , 0x01 } ;
static u8 command_off [ ] = { 0x00 , 0x00 } ;
struct i2c_msg msg = {
. addr = DW2102_VOLTAGE_CTRL ,
. flags = 0 ,
. buf = command_off ,
. len = 2 ,
2008-07-20 08:05:50 -03:00
} ;
struct dvb_usb_adapter * udev_adap =
( struct dvb_usb_adapter * ) ( fe - > dvb - > priv ) ;
if ( voltage = = SEC_VOLTAGE_18 )
2009-12-14 20:24:56 -03:00
msg . buf = command_18v ;
else if ( voltage = = SEC_VOLTAGE_13 )
msg . buf = command_13v ;
i2c_transfer ( & udev_adap - > dev - > i2c_adap , & msg , 1 ) ;
2008-07-20 08:05:50 -03:00
return 0 ;
}
2015-06-07 14:53:52 -03:00
static int s660_set_voltage ( struct dvb_frontend * fe ,
enum fe_sec_voltage voltage )
2011-02-25 18:41:23 -03:00
{
struct dvb_usb_adapter * d =
( struct dvb_usb_adapter * ) ( fe - > dvb - > priv ) ;
2015-03-16 14:14:04 -03:00
struct dw2102_state * st = ( struct dw2102_state * ) d - > dev - > priv ;
2011-02-25 18:41:23 -03:00
dw210x_set_voltage ( fe , voltage ) ;
if ( st - > old_set_voltage )
st - > old_set_voltage ( fe , voltage ) ;
return 0 ;
}
2011-02-25 18:41:22 -03:00
static void dw210x_led_ctrl ( struct dvb_frontend * fe , int offon )
{
static u8 led_off [ ] = { 0 } ;
static u8 led_on [ ] = { 1 } ;
struct i2c_msg msg = {
. addr = DW2102_LED_CTRL ,
. flags = 0 ,
. buf = led_off ,
. len = 1
} ;
struct dvb_usb_adapter * udev_adap =
( struct dvb_usb_adapter * ) ( fe - > dvb - > priv ) ;
if ( offon )
msg . buf = led_on ;
i2c_transfer ( & udev_adap - > dev - > i2c_adap , & msg , 1 ) ;
}
2015-06-07 14:53:52 -03:00
static int tt_s2_4600_read_status ( struct dvb_frontend * fe ,
enum fe_status * status )
2015-05-05 13:33:55 -03:00
{
struct dvb_usb_adapter * d =
( struct dvb_usb_adapter * ) ( fe - > dvb - > priv ) ;
struct dw2102_state * st = ( struct dw2102_state * ) d - > dev - > priv ;
int ret ;
ret = st - > fe_read_status ( fe , status ) ;
/* resync slave fifo when signal change from unlock to lock */
if ( ( * status & FE_HAS_LOCK ) & & ( ! st - > last_lock ) )
su3000_streaming_ctrl ( d , 1 ) ;
st - > last_lock = ( * status & FE_HAS_LOCK ) ? 1 : 0 ;
return ret ;
}
2008-10-17 13:45:55 -03:00
static struct stv0299_config sharp_z0194a_config = {
. demod_address = 0x68 ,
. inittab = sharp_z0194a_inittab ,
. mclk = 88000000UL ,
. invert = 1 ,
. skip_reinit = 0 ,
. lock_output = STV0299_LOCKOUTPUT_1 ,
. volt13_op0_op1 = STV0299_VOLT13_OP1 ,
. min_delay_ms = 100 ,
. set_symbol_rate = sharp_z0194a_set_symbol_rate ,
} ;
2008-09-08 17:16:40 -03:00
static struct cx24116_config dw2104_config = {
. demod_address = 0x55 ,
2008-09-09 13:57:47 -03:00
. mpg_clk_pos_pol = 0x01 ,
2008-09-08 17:16:40 -03:00
} ;
2008-09-17 19:19:19 -03:00
static struct si21xx_config serit_sp1511lhb_config = {
. demod_address = 0x68 ,
. min_delay_ms = 100 ,
} ;
2009-06-14 20:51:45 -03:00
static struct tda10023_config dw3101_tda10023_config = {
. demod_address = 0x0c ,
. invert = 1 ,
} ;
2009-06-20 09:54:18 -03:00
static struct mt312_config zl313_config = {
. demod_address = 0x0e ,
} ;
2009-11-27 14:37:35 -03:00
static struct ds3000_config dw2104_ds3000_config = {
. demod_address = 0x68 ,
} ;
2013-08-28 09:37:37 -03:00
static struct ts2020_config dw2104_ts2020_config = {
2012-12-23 19:25:38 -03:00
. tuner_address = 0x60 ,
2012-12-28 19:40:33 -03:00
. clk_out_div = 1 ,
2013-08-28 09:37:37 -03:00
. frequency_div = 1060000 ,
2012-12-23 19:25:38 -03:00
} ;
2012-12-28 19:40:24 -03:00
static struct ds3000_config s660_ds3000_config = {
. demod_address = 0x68 ,
2012-12-28 19:40:33 -03:00
. ci_mode = 1 ,
2012-12-28 19:40:24 -03:00
. set_lock_led = dw210x_led_ctrl ,
} ;
2013-08-28 09:37:37 -03:00
static struct ts2020_config s660_ts2020_config = {
. tuner_address = 0x60 ,
. clk_out_div = 1 ,
. frequency_div = 1146000 ,
} ;
2009-11-27 14:37:35 -03:00
static struct stv0900_config dw2104a_stv0900_config = {
. demod_address = 0x6a ,
. demod_mode = 0 ,
. xtal = 27000000 ,
. clkmode = 3 , /* 0-CLKI, 2-XTALI, else AUTO */
. diseqc_mode = 2 , /* 2/3 PWM */
. tun1_maddress = 0 , /* 0x60 */
. tun1_adc = 0 , /* 2 Vpp */
. path1_mode = 3 ,
} ;
static struct stb6100_config dw2104a_stb6100_config = {
. tuner_address = 0x60 ,
. refclock = 27000000 ,
} ;
static struct stv0900_config dw2104_stv0900_config = {
. demod_address = 0x68 ,
. 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 dw2104_stv6110_config = {
. i2c_address = 0x60 ,
. mclk = 16000000 ,
. clk_div = 1 ,
} ;
2009-12-14 20:24:56 -03:00
static struct stv0900_config prof_7500_stv0900_config = {
. demod_address = 0x6a ,
. demod_mode = 0 ,
. xtal = 27000000 ,
. clkmode = 3 , /* 0-CLKI, 2-XTALI, else AUTO */
. diseqc_mode = 2 , /* 2/3 PWM */
. tun1_maddress = 0 , /* 0x60 */
. tun1_adc = 0 , /* 2 Vpp */
. path1_mode = 3 ,
. tun1_type = 3 ,
2011-02-25 18:41:22 -03:00
. set_lock_led = dw210x_led_ctrl ,
2009-12-14 20:24:56 -03:00
} ;
2011-02-25 18:41:22 -03:00
static struct ds3000_config su3000_ds3000_config = {
. demod_address = 0x68 ,
. ci_mode = 1 ,
2012-12-28 19:40:33 -03:00
. set_lock_led = dw210x_led_ctrl ,
2012-12-23 19:25:38 -03:00
} ;
2013-11-13 20:53:59 -03:00
static struct cxd2820r_config cxd2820r_config = {
. i2c_address = 0x6c , /* (0xd8 >> 1) */
. ts_mode = 0x38 ,
2014-06-03 14:22:44 -03:00
. ts_clock_inv = 1 ,
2013-11-13 20:53:59 -03:00
} ;
static struct tda18271_config tda18271_config = {
. output_opt = TDA18271_OUTPUT_LT_OFF ,
. gate = TDA18271_GATE_DIGITAL ,
} ;
2012-05-08 03:53:17 -03:00
static u8 m88rs2000_inittab [ ] = {
DEMOD_WRITE , 0x9a , 0x30 ,
DEMOD_WRITE , 0x00 , 0x01 ,
WRITE_DELAY , 0x19 , 0x00 ,
DEMOD_WRITE , 0x00 , 0x00 ,
DEMOD_WRITE , 0x9a , 0xb0 ,
DEMOD_WRITE , 0x81 , 0xc1 ,
DEMOD_WRITE , 0x81 , 0x81 ,
DEMOD_WRITE , 0x86 , 0xc6 ,
DEMOD_WRITE , 0x9a , 0x30 ,
DEMOD_WRITE , 0xf0 , 0x80 ,
DEMOD_WRITE , 0xf1 , 0xbf ,
DEMOD_WRITE , 0xb0 , 0x45 ,
DEMOD_WRITE , 0xb2 , 0x01 ,
DEMOD_WRITE , 0x9a , 0xb0 ,
0xff , 0xaa , 0xff
} ;
static struct m88rs2000_config s421_m88rs2000_config = {
. demod_addr = 0x68 ,
. inittab = m88rs2000_inittab ,
} ;
2008-09-08 17:16:40 -03:00
static int dw2104_frontend_attach ( struct dvb_usb_adapter * d )
{
2009-11-27 14:37:35 -03:00
struct dvb_tuner_ops * tuner_ops = NULL ;
if ( demod_probe & 4 ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0900_attach , & dw2104a_stv0900_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap , 0 ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( stb6100_attach , d - > fe_adap [ 0 ] . fe ,
2009-11-27 14:37:35 -03:00
& dw2104a_stb6100_config ,
& d - > dev - > i2c_adap ) ) {
2011-09-06 09:31:57 -03:00
tuner_ops = & d - > fe_adap [ 0 ] . fe - > ops . tuner_ops ;
2009-11-27 14:37:35 -03:00
tuner_ops - > set_frequency = stb6100_set_freq ;
tuner_ops - > get_frequency = stb6100_get_freq ;
tuner_ops - > set_bandwidth = stb6100_set_bandw ;
tuner_ops - > get_bandwidth = stb6100_get_bandw ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached STV0900+STB6100! " ) ;
2009-11-27 14:37:35 -03:00
return 0 ;
}
}
}
if ( demod_probe & 2 ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0900_attach , & dw2104_stv0900_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap , 0 ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( stv6110_attach , d - > fe_adap [ 0 ] . fe ,
2009-11-27 14:37:35 -03:00
& dw2104_stv6110_config ,
& d - > dev - > i2c_adap ) ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached STV0900+STV6110A! " ) ;
2009-11-27 14:37:35 -03:00
return 0 ;
}
}
}
if ( demod_probe & 1 ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( cx24116_attach , & dw2104_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached cx24116! " ) ;
2009-11-27 14:37:35 -03:00
return 0 ;
}
}
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( ds3000_attach , & dw2104_ds3000_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
2012-12-23 19:25:38 -03:00
dvb_attach ( ts2020_attach , d - > fe_adap [ 0 ] . fe ,
& dw2104_ts2020_config , & d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached DS3000! " ) ;
2008-09-08 17:16:40 -03:00
return 0 ;
}
2009-11-27 14:37:35 -03:00
2008-09-08 17:16:40 -03:00
return - EIO ;
}
2008-09-17 19:19:19 -03:00
static struct dvb_usb_device_properties dw2102_properties ;
2009-06-14 19:41:22 -03:00
static struct dvb_usb_device_properties dw2104_properties ;
2009-11-27 14:37:35 -03:00
static struct dvb_usb_device_properties s6x0_properties ;
2008-09-17 19:19:19 -03:00
2008-07-20 08:05:50 -03:00
static int dw2102_frontend_attach ( struct dvb_usb_adapter * d )
{
2008-09-17 19:19:19 -03:00
if ( dw2102_properties . i2c_algo = = & dw2102_serit_i2c_algo ) {
/*dw2102_properties.adapter->tuner_attach = NULL;*/
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( si21xx_attach , & serit_sp1511lhb_config ,
2008-09-17 19:19:19 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached si21xx! " ) ;
2008-09-17 19:19:19 -03:00
return 0 ;
}
}
2009-11-27 14:37:35 -03:00
2008-10-05 09:11:21 -03:00
if ( dw2102_properties . i2c_algo = = & dw2102_earda_i2c_algo ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0288_attach , & earda_config ,
2008-10-05 09:11:21 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( stb6000_attach , d - > fe_adap [ 0 ] . fe , 0x61 ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached stv0288! " ) ;
2009-11-27 14:37:35 -03:00
return 0 ;
}
2008-10-05 09:11:21 -03:00
}
}
2008-09-17 19:19:19 -03:00
if ( dw2102_properties . i2c_algo = = & dw2102_i2c_algo ) {
/*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0299_attach , & sharp_z0194a_config ,
2008-09-17 19:19:19 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached stv0299! " ) ;
2008-09-17 19:19:19 -03:00
return 0 ;
}
2008-07-20 08:05:50 -03:00
}
return - EIO ;
}
2009-06-14 20:51:45 -03:00
static int dw3101_frontend_attach ( struct dvb_usb_adapter * d )
{
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( tda10023_attach , & dw3101_tda10023_config ,
2009-06-14 20:51:45 -03:00
& d - > dev - > i2c_adap , 0x48 ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
2016-06-06 10:23:59 -03:00
info ( " Attached tda10023! " ) ;
2009-06-14 20:51:45 -03:00
return 0 ;
}
return - EIO ;
}
2011-02-25 18:41:22 -03:00
static int zl100313_frontend_attach ( struct dvb_usb_adapter * d )
2009-06-20 09:54:18 -03:00
{
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( mt312_attach , & zl313_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( zl10039_attach , d - > fe_adap [ 0 ] . fe , 0x60 ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ) {
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2016-06-06 10:23:59 -03:00
info ( " Attached zl100313+zl10039! " ) ;
2009-11-27 14:37:35 -03:00
return 0 ;
}
}
2011-02-25 18:41:22 -03:00
return - EIO ;
}
static int stv0288_frontend_attach ( struct dvb_usb_adapter * d )
{
2011-02-27 16:22:52 -03:00
u8 obuf [ ] = { 7 , 1 } ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0288_attach , & earda_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe = = NULL )
2011-02-27 16:22:52 -03:00
return - EIO ;
2011-09-06 09:31:57 -03:00
if ( NULL = = dvb_attach ( stb6000_attach , d - > fe_adap [ 0 ] . fe , 0x61 , & d - > dev - > i2c_adap ) )
2011-02-27 16:22:52 -03:00
return - EIO ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2011-02-27 16:22:52 -03:00
dw210x_op_rw ( d - > dev - > udev , 0x8a , 0 , 0 , obuf , 2 , DW210X_WRITE_MSG ) ;
2016-06-06 10:23:59 -03:00
info ( " Attached stv0288+stb6000! " ) ;
2011-02-27 16:22:52 -03:00
return 0 ;
2011-02-25 18:41:22 -03:00
}
static int ds3000_frontend_attach ( struct dvb_usb_adapter * d )
{
2015-03-16 14:14:04 -03:00
struct dw2102_state * st = d - > dev - > priv ;
2011-02-25 18:41:23 -03:00
u8 obuf [ ] = { 7 , 1 } ;
2011-02-25 18:41:23 -03:00
2012-12-28 19:40:24 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( ds3000_attach , & s660_ds3000_config ,
2009-11-27 14:37:35 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe = = NULL )
2011-02-25 18:41:23 -03:00
return - EIO ;
2013-08-28 09:37:37 -03:00
dvb_attach ( ts2020_attach , d - > fe_adap [ 0 ] . fe , & s660_ts2020_config ,
2012-12-23 19:25:38 -03:00
& d - > dev - > i2c_adap ) ;
2011-09-06 09:31:57 -03:00
st - > old_set_voltage = d - > fe_adap [ 0 ] . fe - > ops . set_voltage ;
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = s660_set_voltage ;
2011-02-25 18:41:23 -03:00
dw210x_op_rw ( d - > dev - > udev , 0x8a , 0 , 0 , obuf , 2 , DW210X_WRITE_MSG ) ;
2016-06-06 10:23:59 -03:00
info ( " Attached ds3000+ts2020! " ) ;
2011-02-25 18:41:23 -03:00
return 0 ;
2009-06-20 09:54:18 -03:00
}
2009-12-14 20:24:56 -03:00
static int prof_7500_frontend_attach ( struct dvb_usb_adapter * d )
{
2011-02-25 18:41:23 -03:00
u8 obuf [ ] = { 7 , 1 } ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( stv0900_attach , & prof_7500_stv0900_config ,
2009-12-14 20:24:56 -03:00
& d - > dev - > i2c_adap , 0 ) ;
2011-09-06 09:31:57 -03:00
if ( d - > fe_adap [ 0 ] . fe = = NULL )
2009-12-14 20:24:56 -03:00
return - EIO ;
2011-02-25 18:41:23 -03:00
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe - > ops . set_voltage = dw210x_set_voltage ;
2009-12-14 20:24:56 -03:00
2011-02-25 18:41:23 -03:00
dw210x_op_rw ( d - > dev - > udev , 0x8a , 0 , 0 , obuf , 2 , DW210X_WRITE_MSG ) ;
2016-06-06 10:23:59 -03:00
info ( " Attached STV0900+STB6100A! " ) ;
2009-12-14 20:24:56 -03:00
return 0 ;
}
2017-02-15 18:29:15 -02:00
static int su3000_frontend_attach ( struct dvb_usb_adapter * adap )
2011-02-25 18:41:22 -03:00
{
2017-02-15 18:29:15 -02:00
struct dvb_usb_device * d = adap - > dev ;
struct dw2102_state * state = d - > priv ;
mutex_lock ( & d - > data_mutex ) ;
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x80 ;
state - > data [ 2 ] = 0 ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x02 ;
state - > data [ 2 ] = 1 ;
2012-12-28 19:40:33 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2012-12-28 19:40:33 -03:00
err ( " command 0x0e transfer failed. " ) ;
msleep ( 300 ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x83 ;
state - > data [ 2 ] = 0 ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x83 ;
state - > data [ 2 ] = 1 ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x51 ;
2011-02-25 18:41:22 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 1 , state - > data , 1 , 0 ) < 0 )
2011-02-25 18:41:22 -03:00
err ( " command 0x51 transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
mutex_unlock ( & d - > data_mutex ) ;
adap - > fe_adap [ 0 ] . fe = dvb_attach ( ds3000_attach , & su3000_ds3000_config ,
& d - > i2c_adap ) ;
if ( adap - > fe_adap [ 0 ] . fe = = NULL )
2011-02-25 18:41:22 -03:00
return - EIO ;
2017-02-15 18:29:15 -02:00
if ( dvb_attach ( ts2020_attach , adap - > fe_adap [ 0 ] . fe ,
2012-12-28 19:40:33 -03:00
& dw2104_ts2020_config ,
2017-02-15 18:29:15 -02:00
& d - > i2c_adap ) ) {
2016-06-06 10:23:59 -03:00
info ( " Attached DS3000/TS2020! " ) ;
2012-12-28 19:40:33 -03:00
return 0 ;
}
2011-02-25 18:41:22 -03:00
2016-06-06 10:23:59 -03:00
info ( " Failed to attach DS3000/TS2020! " ) ;
2012-12-28 19:40:33 -03:00
return - EIO ;
2011-02-25 18:41:22 -03:00
}
2017-02-15 18:29:15 -02:00
static int t220_frontend_attach ( struct dvb_usb_adapter * adap )
2013-11-13 20:53:59 -03:00
{
2017-02-15 18:29:15 -02:00
struct dvb_usb_device * d = adap - > dev ;
struct dw2102_state * state = d - > priv ;
mutex_lock ( & d - > data_mutex ) ;
2013-11-13 20:53:59 -03:00
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x87 ;
state - > data [ 2 ] = 0x0 ;
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2013-11-13 20:53:59 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x86 ;
state - > data [ 2 ] = 1 ;
2014-06-03 14:22:44 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2014-06-03 14:22:44 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x80 ;
state - > data [ 2 ] = 0 ;
2013-11-13 20:53:59 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2013-11-13 20:53:59 -03:00
err ( " command 0x0e transfer failed. " ) ;
2014-06-03 14:22:44 -03:00
msleep ( 50 ) ;
2013-11-13 20:53:59 -03:00
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x80 ;
state - > data [ 2 ] = 1 ;
2013-11-13 20:53:59 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2013-11-13 20:53:59 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x51 ;
2013-11-13 20:53:59 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 1 , state - > data , 1 , 0 ) < 0 )
2013-11-13 20:53:59 -03:00
err ( " command 0x51 transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
mutex_unlock ( & d - > data_mutex ) ;
adap - > fe_adap [ 0 ] . fe = dvb_attach ( cxd2820r_attach , & cxd2820r_config ,
& d - > i2c_adap , NULL ) ;
if ( adap - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( tda18271_attach , adap - > fe_adap [ 0 ] . fe , 0x60 ,
& d - > i2c_adap , & tda18271_config ) ) {
2016-06-06 10:23:59 -03:00
info ( " Attached TDA18271HD/CXD2820R! " ) ;
2013-11-13 20:53:59 -03:00
return 0 ;
}
}
2016-06-06 10:23:59 -03:00
info ( " Failed to attach TDA18271HD/CXD2820R! " ) ;
2013-11-13 20:53:59 -03:00
return - EIO ;
}
2017-02-15 18:29:15 -02:00
static int m88rs2000_frontend_attach ( struct dvb_usb_adapter * adap )
2012-05-08 03:53:17 -03:00
{
2017-02-15 18:29:15 -02:00
struct dvb_usb_device * d = adap - > dev ;
struct dw2102_state * state = d - > priv ;
mutex_lock ( & d - > data_mutex ) ;
2012-05-08 03:53:17 -03:00
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x51 ;
if ( dvb_usb_generic_rw ( d , state - > data , 1 , state - > data , 1 , 0 ) < 0 )
2012-05-08 03:53:17 -03:00
err ( " command 0x51 transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
mutex_unlock ( & d - > data_mutex ) ;
2012-12-28 19:40:33 -03:00
2017-02-15 18:29:15 -02:00
adap - > fe_adap [ 0 ] . fe = dvb_attach ( m88rs2000_attach ,
& s421_m88rs2000_config ,
& d - > i2c_adap ) ;
if ( adap - > fe_adap [ 0 ] . fe = = NULL )
2012-05-08 03:53:17 -03:00
return - EIO ;
2017-02-15 18:29:15 -02:00
if ( dvb_attach ( ts2020_attach , adap - > fe_adap [ 0 ] . fe ,
2012-12-28 19:40:33 -03:00
& dw2104_ts2020_config ,
2017-02-15 18:29:15 -02:00
& d - > i2c_adap ) ) {
2016-06-06 10:23:59 -03:00
info ( " Attached RS2000/TS2020! " ) ;
2012-12-28 19:40:33 -03:00
return 0 ;
}
2012-05-08 03:53:17 -03:00
2016-06-06 10:23:59 -03:00
info ( " Failed to attach RS2000/TS2020! " ) ;
2012-12-28 19:40:33 -03:00
return - EIO ;
2012-05-08 03:53:17 -03:00
}
2020-02-01 22:48:26 +01:00
static int tt_s2_4600_frontend_attach_probe_demod ( struct dvb_usb_device * d ,
const int probe_addr )
{
struct dw2102_state * state = d - > priv ;
state - > data [ 0 ] = 0x9 ;
state - > data [ 1 ] = 0x1 ;
state - > data [ 2 ] = 0x1 ;
state - > data [ 3 ] = probe_addr ;
state - > data [ 4 ] = 0x0 ;
if ( dvb_usb_generic_rw ( d , state - > data , 5 , state - > data , 2 , 0 ) < 0 ) {
err ( " i2c probe for address 0x%x failed. " , probe_addr ) ;
return 0 ;
}
if ( state - > data [ 0 ] ! = 8 ) /* fail(7) or error, no device at address */
return 0 ;
/* probing successful */
return 1 ;
}
2015-03-16 14:22:18 -03:00
static int tt_s2_4600_frontend_attach ( struct dvb_usb_adapter * adap )
{
struct dvb_usb_device * d = adap - > dev ;
struct dw2102_state * state = d - > priv ;
struct i2c_adapter * i2c_adapter ;
struct i2c_client * client ;
2016-02-16 15:53:45 -02:00
struct i2c_board_info board_info ;
struct m88ds3103_platform_data m88ds3103_pdata = { } ;
2015-03-29 19:28:39 -03:00
struct ts2020_config ts2020_config = { } ;
2020-02-01 22:48:26 +01:00
int demod_addr ;
2015-03-16 14:22:18 -03:00
2017-02-15 18:29:15 -02:00
mutex_lock ( & d - > data_mutex ) ;
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x80 ;
state - > data [ 2 ] = 0x0 ;
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2015-03-16 14:22:18 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x02 ;
state - > data [ 2 ] = 1 ;
2015-03-16 14:22:18 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2015-03-16 14:22:18 -03:00
err ( " command 0x0e transfer failed. " ) ;
msleep ( 300 ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x83 ;
state - > data [ 2 ] = 0 ;
2015-03-16 14:22:18 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2015-03-16 14:22:18 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0xe ;
state - > data [ 1 ] = 0x83 ;
state - > data [ 2 ] = 1 ;
2015-03-16 14:22:18 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 3 , state - > data , 1 , 0 ) < 0 )
2015-03-16 14:22:18 -03:00
err ( " command 0x0e transfer failed. " ) ;
2017-02-15 18:29:15 -02:00
state - > data [ 0 ] = 0x51 ;
2015-03-16 14:22:18 -03:00
2017-02-15 18:29:15 -02:00
if ( dvb_usb_generic_rw ( d , state - > data , 1 , state - > data , 1 , 0 ) < 0 )
2015-03-16 14:22:18 -03:00
err ( " command 0x51 transfer failed. " ) ;
2020-02-01 22:48:26 +01:00
/* probe for demodulator i2c address */
demod_addr = - 1 ;
if ( tt_s2_4600_frontend_attach_probe_demod ( d , 0x68 ) )
demod_addr = 0x68 ;
else if ( tt_s2_4600_frontend_attach_probe_demod ( d , 0x69 ) )
demod_addr = 0x69 ;
else if ( tt_s2_4600_frontend_attach_probe_demod ( d , 0x6a ) )
demod_addr = 0x6a ;
2017-02-15 18:29:15 -02:00
mutex_unlock ( & d - > data_mutex ) ;
2020-02-01 22:48:26 +01:00
if ( demod_addr < 0 ) {
err ( " probing for demodulator failed. Is the external power switched on? " ) ;
return - ENODEV ;
}
2016-02-16 15:53:45 -02:00
/* attach demod */
m88ds3103_pdata . clk = 27000000 ;
m88ds3103_pdata . i2c_wr_max = 33 ;
m88ds3103_pdata . ts_mode = M88DS3103_TS_CI ;
m88ds3103_pdata . ts_clk = 16000 ;
m88ds3103_pdata . ts_clk_pol = 0 ;
m88ds3103_pdata . spec_inv = 0 ;
m88ds3103_pdata . agc = 0x99 ;
m88ds3103_pdata . agc_inv = 0 ;
m88ds3103_pdata . clk_out = M88DS3103_CLOCK_OUT_ENABLED ;
m88ds3103_pdata . envelope_mode = 0 ;
m88ds3103_pdata . lnb_hv_pol = 1 ;
m88ds3103_pdata . lnb_en_pol = 0 ;
memset ( & board_info , 0 , sizeof ( board_info ) ) ;
2020-02-01 22:48:26 +01:00
if ( demod_addr = = 0x6a )
strscpy ( board_info . type , " m88ds3103b " , I2C_NAME_SIZE ) ;
else
strscpy ( board_info . type , " m88ds3103 " , I2C_NAME_SIZE ) ;
board_info . addr = demod_addr ;
2016-02-16 15:53:45 -02:00
board_info . platform_data = & m88ds3103_pdata ;
request_module ( " m88ds3103 " ) ;
2019-12-16 16:51:42 +01:00
client = i2c_new_client_device ( & d - > i2c_adap , & board_info ) ;
if ( ! i2c_client_has_driver ( client ) )
2015-03-16 14:22:18 -03:00
return - ENODEV ;
2016-02-16 15:53:45 -02:00
if ( ! try_module_get ( client - > dev . driver - > owner ) ) {
i2c_unregister_device ( client ) ;
return - ENODEV ;
}
adap - > fe_adap [ 0 ] . fe = m88ds3103_pdata . get_dvb_frontend ( client ) ;
i2c_adapter = m88ds3103_pdata . get_i2c_adapter ( client ) ;
state - > i2c_client_demod = client ;
2015-03-16 14:22:18 -03:00
/* attach tuner */
2015-03-29 19:28:39 -03:00
ts2020_config . fe = adap - > fe_adap [ 0 ] . fe ;
2016-02-16 15:53:45 -02:00
memset ( & board_info , 0 , sizeof ( board_info ) ) ;
2018-09-10 08:19:14 -04:00
strscpy ( board_info . type , " ts2022 " , I2C_NAME_SIZE ) ;
2016-02-16 15:53:45 -02:00
board_info . addr = 0x60 ;
board_info . platform_data = & ts2020_config ;
2015-03-29 19:28:39 -03:00
request_module ( " ts2020 " ) ;
2019-12-16 16:51:42 +01:00
client = i2c_new_client_device ( i2c_adapter , & board_info ) ;
2015-03-16 14:22:18 -03:00
2019-12-16 16:51:42 +01:00
if ( ! i2c_client_has_driver ( client ) ) {
2015-03-16 14:22:18 -03:00
dvb_frontend_detach ( adap - > fe_adap [ 0 ] . fe ) ;
return - ENODEV ;
}
if ( ! try_module_get ( client - > dev . driver - > owner ) ) {
i2c_unregister_device ( client ) ;
dvb_frontend_detach ( adap - > fe_adap [ 0 ] . fe ) ;
return - ENODEV ;
}
/* delegate signal strength measurement to tuner */
adap - > fe_adap [ 0 ] . fe - > ops . read_signal_strength =
adap - > fe_adap [ 0 ] . fe - > ops . tuner_ops . get_rf_strength ;
state - > i2c_client_tuner = client ;
2015-05-05 13:33:55 -03:00
/* hook fe: need to resync the slave fifo when signal locks */
state - > fe_read_status = adap - > fe_adap [ 0 ] . fe - > ops . read_status ;
adap - > fe_adap [ 0 ] . fe - > ops . read_status = tt_s2_4600_read_status ;
state - > last_lock = 0 ;
2015-03-16 14:22:18 -03:00
return 0 ;
}
2008-07-20 08:05:50 -03:00
static int dw2102_tuner_attach ( struct dvb_usb_adapter * adap )
{
2011-09-06 09:31:57 -03:00
dvb_attach ( dvb_pll_attach , adap - > fe_adap [ 0 ] . fe , 0x60 ,
2008-07-20 08:05:50 -03:00
& adap - > dev - > i2c_adap , DVB_PLL_OPERA1 ) ;
return 0 ;
}
2009-06-14 20:51:45 -03:00
static int dw3101_tuner_attach ( struct dvb_usb_adapter * adap )
{
2011-09-06 09:31:57 -03:00
dvb_attach ( dvb_pll_attach , adap - > fe_adap [ 0 ] . fe , 0x60 ,
2009-06-14 20:51:45 -03:00
& adap - > dev - > i2c_adap , DVB_PLL_TUA6034 ) ;
return 0 ;
}
2013-11-15 16:43:33 -03:00
static int dw2102_rc_query ( struct dvb_usb_device * d )
{
u8 key [ 2 ] ;
struct i2c_msg msg = {
. addr = DW2102_RC_QUERY ,
. flags = I2C_M_RD ,
. buf = key ,
. len = 2
} ;
2008-07-20 08:05:50 -03:00
2013-11-15 16:43:33 -03:00
if ( d - > props . i2c_algo - > master_xfer ( & d - > i2c_adap , & msg , 1 ) = = 1 ) {
if ( msg . buf [ 0 ] ! = 0xff ) {
deb_rc ( " %s: rc code: %x, %x \n " ,
__func__ , key [ 0 ] , key [ 1 ] ) ;
2017-08-07 16:20:58 -04:00
rc_keydown ( d - > rc_dev , RC_PROTO_UNKNOWN , key [ 0 ] , 0 ) ;
2013-11-15 16:43:33 -03:00
}
}
2011-02-25 18:41:22 -03:00
2013-11-15 16:43:33 -03:00
return 0 ;
}
2008-07-20 08:05:50 -03:00
2013-11-15 16:43:33 -03:00
static int prof_rc_query ( struct dvb_usb_device * d )
2008-07-20 08:05:50 -03:00
{
u8 key [ 2 ] ;
2009-06-13 08:10:24 -03:00
struct i2c_msg msg = {
. addr = DW2102_RC_QUERY ,
. flags = I2C_M_RD ,
. buf = key ,
. len = 2
2008-07-20 08:05:50 -03:00
} ;
2009-06-13 08:10:24 -03:00
2013-11-15 16:43:33 -03:00
if ( d - > props . i2c_algo - > master_xfer ( & d - > i2c_adap , & msg , 1 ) = = 1 ) {
if ( msg . buf [ 0 ] ! = 0xff ) {
deb_rc ( " %s: rc code: %x, %x \n " ,
__func__ , key [ 0 ] , key [ 1 ] ) ;
2017-08-07 16:20:58 -04:00
rc_keydown ( d - > rc_dev , RC_PROTO_UNKNOWN , key [ 0 ] ^ 0xff ,
0 ) ;
2008-07-20 08:05:50 -03:00
}
2013-11-15 16:43:33 -03:00
}
2009-06-13 08:10:24 -03:00
2013-11-15 16:43:33 -03:00
return 0 ;
}
static int su3000_rc_query ( struct dvb_usb_device * d )
{
u8 key [ 2 ] ;
struct i2c_msg msg = {
. addr = DW2102_RC_QUERY ,
. flags = I2C_M_RD ,
. buf = key ,
. len = 2
} ;
2009-06-13 08:10:24 -03:00
2013-11-15 16:43:33 -03:00
if ( d - > props . i2c_algo - > master_xfer ( & d - > i2c_adap , & msg , 1 ) = = 1 ) {
if ( msg . buf [ 0 ] ! = 0xff ) {
deb_rc ( " %s: rc code: %x, %x \n " ,
__func__ , key [ 0 ] , key [ 1 ] ) ;
2017-08-07 16:20:58 -04:00
rc_keydown ( d - > rc_dev , RC_PROTO_RC5 ,
2014-04-03 20:31:30 -03:00
RC_SCANCODE_RC5 ( key [ 1 ] , key [ 0 ] ) , 0 ) ;
2013-11-15 16:43:33 -03:00
}
2008-07-20 08:05:50 -03:00
}
2009-06-13 08:10:24 -03:00
2008-07-20 08:05:50 -03:00
return 0 ;
}
2011-12-23 19:00:45 -03:00
enum dw2102_table_entry {
CYPRESS_DW2102 ,
CYPRESS_DW2101 ,
CYPRESS_DW2104 ,
TEVII_S650 ,
TERRATEC_CINERGY_S ,
CYPRESS_DW3101 ,
TEVII_S630 ,
PROF_1100 ,
TEVII_S660 ,
PROF_7500 ,
GENIATECH_SU3000 ,
2020-10-06 20:13:09 +02:00
HAUPPAUGE_MAX_S2 ,
2011-12-23 19:00:45 -03:00
TERRATEC_CINERGY_S2 ,
TEVII_S480_1 ,
TEVII_S480_2 ,
X3M_SPC1400HD ,
2012-05-08 03:53:17 -03:00
TEVII_S421 ,
TEVII_S632 ,
2013-02-21 08:11:41 -03:00
TERRATEC_CINERGY_S2_R2 ,
2016-06-13 11:04:50 -03:00
TERRATEC_CINERGY_S2_R3 ,
2016-10-04 08:13:27 -03:00
TERRATEC_CINERGY_S2_R4 ,
2020-05-11 10:29:53 +02:00
TERRATEC_CINERGY_S2_1 ,
TERRATEC_CINERGY_S2_2 ,
2013-03-07 09:36:22 -03:00
GOTVIEW_SAT_HD ,
2013-11-13 20:53:59 -03:00
GENIATECH_T220 ,
2015-03-16 14:22:18 -03:00
TECHNOTREND_S2_4600 ,
2015-03-21 17:42:23 -03:00
TEVII_S482_1 ,
TEVII_S482_2 ,
2016-01-04 17:32:51 -02:00
TERRATEC_CINERGY_S2_BOX ,
2016-03-02 08:06:06 -03:00
TEVII_S662
2011-12-23 19:00:45 -03:00
} ;
2008-07-20 08:05:50 -03:00
static struct usb_device_id dw2102_table [ ] = {
2011-12-23 19:00:45 -03:00
[ CYPRESS_DW2102 ] = { USB_DEVICE ( USB_VID_CYPRESS , USB_PID_DW2102 ) } ,
[ CYPRESS_DW2101 ] = { USB_DEVICE ( USB_VID_CYPRESS , 0x2101 ) } ,
[ CYPRESS_DW2104 ] = { USB_DEVICE ( USB_VID_CYPRESS , USB_PID_DW2104 ) } ,
[ TEVII_S650 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S650 ) } ,
2016-03-03 14:50:17 -03:00
[ TERRATEC_CINERGY_S ] = { USB_DEVICE ( USB_VID_TERRATEC , USB_PID_TERRATEC_CINERGY_S ) } ,
2011-12-23 19:00:45 -03:00
[ CYPRESS_DW3101 ] = { USB_DEVICE ( USB_VID_CYPRESS , USB_PID_DW3101 ) } ,
[ TEVII_S630 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S630 ) } ,
[ PROF_1100 ] = { USB_DEVICE ( 0x3011 , USB_PID_PROF_1100 ) } ,
[ TEVII_S660 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S660 ) } ,
[ PROF_7500 ] = { USB_DEVICE ( 0x3034 , 0x7500 ) } ,
[ GENIATECH_SU3000 ] = { USB_DEVICE ( 0x1f4d , 0x3000 ) } ,
2020-10-06 20:13:09 +02:00
[ HAUPPAUGE_MAX_S2 ] = { USB_DEVICE ( 0x2040 , 0xd900 ) } ,
2016-01-25 12:47:44 -02:00
[ TERRATEC_CINERGY_S2 ] = { USB_DEVICE ( USB_VID_TERRATEC , USB_PID_TERRATEC_CINERGY_S2_R1 ) } ,
2011-12-23 19:00:45 -03:00
[ TEVII_S480_1 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S480_1 ) } ,
[ TEVII_S480_2 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S480_2 ) } ,
[ X3M_SPC1400HD ] = { USB_DEVICE ( 0x1f4d , 0x3100 ) } ,
2012-05-08 03:53:17 -03:00
[ TEVII_S421 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S421 ) } ,
[ TEVII_S632 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S632 ) } ,
2020-05-11 10:29:53 +02:00
[ TERRATEC_CINERGY_S2_R2 ] = { USB_DEVICE ( USB_VID_TERRATEC ,
USB_PID_TERRATEC_CINERGY_S2_R2 ) } ,
[ TERRATEC_CINERGY_S2_R3 ] = { USB_DEVICE ( USB_VID_TERRATEC ,
USB_PID_TERRATEC_CINERGY_S2_R3 ) } ,
[ TERRATEC_CINERGY_S2_R4 ] = { USB_DEVICE ( USB_VID_TERRATEC ,
USB_PID_TERRATEC_CINERGY_S2_R4 ) } ,
[ TERRATEC_CINERGY_S2_1 ] = { USB_DEVICE ( USB_VID_TERRATEC_2 ,
USB_PID_TERRATEC_CINERGY_S2_1 ) } ,
[ TERRATEC_CINERGY_S2_2 ] = { USB_DEVICE ( USB_VID_TERRATEC_2 ,
USB_PID_TERRATEC_CINERGY_S2_2 ) } ,
2013-03-07 09:36:22 -03:00
[ GOTVIEW_SAT_HD ] = { USB_DEVICE ( 0x1FE1 , USB_PID_GOTVIEW_SAT_HD ) } ,
2013-11-13 20:53:59 -03:00
[ GENIATECH_T220 ] = { USB_DEVICE ( 0x1f4d , 0xD220 ) } ,
2015-03-16 14:22:18 -03:00
[ TECHNOTREND_S2_4600 ] = { USB_DEVICE ( USB_VID_TECHNOTREND ,
USB_PID_TECHNOTREND_CONNECT_S2_4600 ) } ,
2015-03-21 17:42:23 -03:00
[ TEVII_S482_1 ] = { USB_DEVICE ( 0x9022 , 0xd483 ) } ,
[ TEVII_S482_2 ] = { USB_DEVICE ( 0x9022 , 0xd484 ) } ,
2016-01-04 17:32:51 -02:00
[ TERRATEC_CINERGY_S2_BOX ] = { USB_DEVICE ( USB_VID_TERRATEC , 0x0105 ) } ,
2016-03-02 08:06:06 -03:00
[ TEVII_S662 ] = { USB_DEVICE ( 0x9022 , USB_PID_TEVII_S662 ) } ,
2008-07-20 08:05:50 -03:00
{ }
} ;
MODULE_DEVICE_TABLE ( usb , dw2102_table ) ;
static int dw2102_load_firmware ( struct usb_device * dev ,
const struct firmware * frmwr )
{
u8 * b , * p ;
int ret = 0 , i ;
u8 reset ;
2008-10-05 09:11:21 -03:00
u8 reset16 [ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
2008-07-20 08:05:50 -03:00
const struct firmware * fw ;
2009-06-20 09:54:18 -03:00
2014-08-20 16:45:27 -03:00
switch ( le16_to_cpu ( dev - > descriptor . idProduct ) ) {
2008-07-20 08:05:50 -03:00
case 0x2101 :
2012-09-28 08:59:32 -03:00
ret = request_firmware ( & fw , DW2101_FIRMWARE , & dev - > dev ) ;
2008-07-20 08:05:50 -03:00
if ( ret ! = 0 ) {
2012-09-28 08:59:32 -03:00
err ( err_str , DW2101_FIRMWARE ) ;
2008-07-20 08:05:50 -03:00
return ret ;
}
break ;
2008-09-08 17:16:40 -03:00
default :
2008-07-20 08:05:50 -03:00
fw = frmwr ;
break ;
}
2008-09-08 17:16:40 -03:00
info ( " start downloading DW210X firmware " ) ;
2008-07-20 08:05:50 -03:00
p = kmalloc ( fw - > size , GFP_KERNEL ) ;
reset = 1 ;
/*stop the CPU*/
2008-09-17 19:19:19 -03:00
dw210x_op_rw ( dev , 0xa0 , 0x7f92 , 0 , & reset , 1 , DW210X_WRITE_MSG ) ;
dw210x_op_rw ( dev , 0xa0 , 0xe600 , 0 , & reset , 1 , DW210X_WRITE_MSG ) ;
2008-07-20 08:05:50 -03:00
if ( p ! = NULL ) {
memcpy ( p , fw - > data , fw - > size ) ;
for ( i = 0 ; i < fw - > size ; i + = 0x40 ) {
b = ( u8 * ) p + i ;
2008-09-17 19:19:19 -03:00
if ( dw210x_op_rw ( dev , 0xa0 , i , 0 , b , 0x40 ,
DW210X_WRITE_MSG ) ! = 0x40 ) {
2008-07-20 08:05:50 -03:00
err ( " error while transferring firmware " ) ;
ret = - EINVAL ;
break ;
}
}
/* restart the CPU */
reset = 0 ;
2008-09-17 19:19:19 -03:00
if ( ret | | dw210x_op_rw ( dev , 0xa0 , 0x7f92 , 0 , & reset , 1 ,
DW210X_WRITE_MSG ) ! = 1 ) {
2008-07-20 08:05:50 -03:00
err ( " could not restart the USB controller CPU. " ) ;
ret = - EINVAL ;
}
2008-09-17 19:19:19 -03:00
if ( ret | | dw210x_op_rw ( dev , 0xa0 , 0xe600 , 0 , & reset , 1 ,
DW210X_WRITE_MSG ) ! = 1 ) {
2008-07-20 08:05:50 -03:00
err ( " could not restart the USB controller CPU. " ) ;
ret = - EINVAL ;
}
/* init registers */
2014-08-20 16:45:27 -03:00
switch ( le16_to_cpu ( dev - > descriptor . idProduct ) ) {
2009-06-14 20:51:45 -03:00
case USB_PID_TEVII_S650 :
2013-11-15 16:43:33 -03:00
dw2104_properties . rc . core . rc_codes = RC_MAP_TEVII_NEC ;
2020-08-23 17:36:59 -05:00
fallthrough ;
2009-06-14 19:41:22 -03:00
case USB_PID_DW2104 :
2008-09-08 17:16:40 -03:00
reset = 1 ;
2008-09-17 19:19:19 -03:00
dw210x_op_rw ( dev , 0xc4 , 0x0000 , 0 , & reset , 1 ,
DW210X_WRITE_MSG ) ;
2020-08-23 17:36:59 -05:00
fallthrough ;
2009-06-14 20:51:45 -03:00
case USB_PID_DW3101 :
2008-09-08 17:16:40 -03:00
reset = 0 ;
2008-09-17 19:19:19 -03:00
dw210x_op_rw ( dev , 0xbf , 0x0040 , 0 , & reset , 0 ,
DW210X_WRITE_MSG ) ;
2008-09-08 17:16:40 -03:00
break ;
2016-03-03 14:50:17 -03:00
case USB_PID_TERRATEC_CINERGY_S :
2008-07-20 08:05:50 -03:00
case USB_PID_DW2102 :
2008-09-17 19:19:19 -03:00
dw210x_op_rw ( dev , 0xbf , 0x0040 , 0 , & reset , 0 ,
DW210X_WRITE_MSG ) ;
dw210x_op_rw ( dev , 0xb9 , 0x0000 , 0 , & reset16 [ 0 ] , 2 ,
DW210X_READ_MSG ) ;
/* check STV0299 frontend */
dw210x_op_rw ( dev , 0xb5 , 0 , 0 , & reset16 [ 0 ] , 2 ,
DW210X_READ_MSG ) ;
2008-12-04 12:49:23 -03:00
if ( ( reset16 [ 0 ] = = 0xa1 ) | | ( reset16 [ 0 ] = = 0x80 ) ) {
2008-09-17 19:19:19 -03:00
dw2102_properties . i2c_algo = & dw2102_i2c_algo ;
2011-09-06 09:31:57 -03:00
dw2102_properties . adapter - > fe [ 0 ] . tuner_attach = & dw2102_tuner_attach ;
2008-10-05 09:11:21 -03:00
break ;
} else {
/* check STV0288 frontend */
reset16 [ 0 ] = 0xd0 ;
reset16 [ 1 ] = 1 ;
reset16 [ 2 ] = 0 ;
dw210x_op_rw ( dev , 0xc2 , 0 , 0 , & reset16 [ 0 ] , 3 ,
DW210X_WRITE_MSG ) ;
dw210x_op_rw ( dev , 0xc3 , 0xd1 , 0 , & reset16 [ 0 ] , 3 ,
DW210X_READ_MSG ) ;
if ( reset16 [ 2 ] = = 0x11 ) {
dw2102_properties . i2c_algo = & dw2102_earda_i2c_algo ;
break ;
}
}
2020-08-23 17:36:59 -05:00
fallthrough ;
2008-07-20 08:05:50 -03:00
case 0x2101 :
2008-09-17 19:19:19 -03:00
dw210x_op_rw ( dev , 0xbc , 0x0030 , 0 , & reset16 [ 0 ] , 2 ,
DW210X_READ_MSG ) ;
dw210x_op_rw ( dev , 0xba , 0x0000 , 0 , & reset16 [ 0 ] , 7 ,
DW210X_READ_MSG ) ;
dw210x_op_rw ( dev , 0xba , 0x0000 , 0 , & reset16 [ 0 ] , 7 ,
DW210X_READ_MSG ) ;
dw210x_op_rw ( dev , 0xb9 , 0x0000 , 0 , & reset16 [ 0 ] , 2 ,
DW210X_READ_MSG ) ;
2008-07-20 08:05:50 -03:00
break ;
}
2009-06-14 20:51:45 -03:00
2008-09-08 17:16:40 -03:00
msleep ( 100 ) ;
2008-07-20 08:05:50 -03:00
kfree ( p ) ;
}
2016-03-07 07:26:55 -03:00
if ( le16_to_cpu ( dev - > descriptor . idProduct ) = = 0x2101 )
release_firmware ( fw ) ;
2008-07-20 08:05:50 -03:00
return ret ;
}
static struct dvb_usb_device_properties dw2102_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2012-09-28 08:59:32 -03:00
. firmware = DW2102_FIRMWARE ,
2008-07-20 08:05:50 -03:00
. no_reconnect = 1 ,
2008-09-17 19:19:19 -03:00
. i2c_algo = & dw2102_serit_i2c_algo ,
2010-07-31 18:04:09 -03:00
2013-11-15 16:43:33 -03:00
. rc . core = {
2010-07-31 18:04:09 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_DM1105_NEC ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_NEC ,
2010-07-31 18:04:09 -03:00
. rc_query = dw2102_rc_query ,
} ,
2008-07-20 08:05:50 -03:00
. generic_bulk_ctrl_endpoint = 0x81 ,
/* parameter for the MPEG2-data transfer */
. num_adapters = 1 ,
. download_firmware = dw2102_load_firmware ,
2008-09-17 19:19:19 -03:00
. read_mac_address = dw210x_read_mac_address ,
2009-06-14 20:51:45 -03:00
. adapter = {
2008-07-20 08:05:50 -03:00
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2008-07-20 08:05:50 -03:00
. frontend_attach = dw2102_frontend_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 09:31:57 -03:00
} } ,
2008-07-20 08:05:50 -03:00
}
} ,
2008-11-05 22:12:56 -03:00
. num_device_descs = 3 ,
2008-07-20 08:05:50 -03:00
. devices = {
{ " DVBWorld DVB-S 2102 USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ CYPRESS_DW2102 ] , NULL } ,
2008-07-20 08:05:50 -03:00
{ NULL } ,
} ,
{ " DVBWorld DVB-S 2101 USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ CYPRESS_DW2101 ] , NULL } ,
2008-07-20 08:05:50 -03:00
{ NULL } ,
2008-11-05 22:12:56 -03:00
} ,
{ " TerraTec Cinergy S USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TERRATEC_CINERGY_S ] , NULL } ,
2008-11-05 22:12:56 -03:00
{ NULL } ,
2008-07-20 08:05:50 -03:00
} ,
}
} ;
2008-09-08 17:16:40 -03:00
static struct dvb_usb_device_properties dw2104_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2012-09-28 08:59:32 -03:00
. firmware = DW2104_FIRMWARE ,
2008-09-08 17:16:40 -03:00
. no_reconnect = 1 ,
. i2c_algo = & dw2104_i2c_algo ,
2013-11-15 16:43:33 -03:00
. rc . core = {
2010-07-31 18:04:09 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_DM1105_NEC ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_NEC ,
2010-07-31 18:04:09 -03:00
. rc_query = dw2102_rc_query ,
} ,
2008-09-08 17:16:40 -03:00
. generic_bulk_ctrl_endpoint = 0x81 ,
/* parameter for the MPEG2-data transfer */
. num_adapters = 1 ,
. download_firmware = dw2102_load_firmware ,
2008-09-17 19:19:19 -03:00
. read_mac_address = dw210x_read_mac_address ,
2008-09-08 17:16:40 -03:00
. adapter = {
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2008-09-08 17:16:40 -03:00
. frontend_attach = dw2104_frontend_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 09:31:57 -03:00
} } ,
2008-09-08 17:16:40 -03:00
}
} ,
. num_device_descs = 2 ,
. devices = {
{ " DVBWorld DW2104 USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ CYPRESS_DW2104 ] , NULL } ,
2008-09-08 17:16:40 -03:00
{ NULL } ,
} ,
{ " TeVii S650 USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TEVII_S650 ] , NULL } ,
2008-09-08 17:16:40 -03:00
{ NULL } ,
} ,
}
} ;
2009-06-14 20:51:45 -03:00
static struct dvb_usb_device_properties dw3101_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2012-09-28 08:59:32 -03:00
. firmware = DW3101_FIRMWARE ,
2009-06-14 20:51:45 -03:00
. no_reconnect = 1 ,
. i2c_algo = & dw3101_i2c_algo ,
2013-11-15 16:43:33 -03:00
. rc . core = {
2010-07-31 18:04:09 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_DM1105_NEC ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_NEC ,
2010-07-31 18:04:09 -03:00
. rc_query = dw2102_rc_query ,
} ,
2009-06-14 20:51:45 -03:00
. generic_bulk_ctrl_endpoint = 0x81 ,
/* parameter for the MPEG2-data transfer */
. num_adapters = 1 ,
. download_firmware = dw2102_load_firmware ,
. read_mac_address = dw210x_read_mac_address ,
. adapter = {
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2009-06-14 20:51:45 -03:00
. frontend_attach = dw3101_frontend_attach ,
. tuner_attach = dw3101_tuner_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 09:31:57 -03:00
} } ,
2009-06-14 20:51:45 -03:00
}
} ,
. num_device_descs = 1 ,
. devices = {
{ " DVBWorld DVB-C 3101 USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ CYPRESS_DW3101 ] , NULL } ,
2009-06-14 20:51:45 -03:00
{ NULL } ,
} ,
}
} ;
2009-11-27 14:37:35 -03:00
static struct dvb_usb_device_properties s6x0_properties = {
2009-06-20 09:54:18 -03:00
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2015-03-16 14:14:04 -03:00
. size_of_priv = sizeof ( struct dw2102_state ) ,
2012-09-28 08:59:32 -03:00
. firmware = S630_FIRMWARE ,
2009-06-20 09:54:18 -03:00
. no_reconnect = 1 ,
2009-11-27 14:37:35 -03:00
. i2c_algo = & s6x0_i2c_algo ,
2013-11-15 16:43:33 -03:00
. rc . core = {
2010-07-31 18:04:09 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_TEVII_NEC ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_NEC ,
2010-07-31 18:04:09 -03:00
. rc_query = dw2102_rc_query ,
} ,
2009-06-20 09:54:18 -03:00
. generic_bulk_ctrl_endpoint = 0x81 ,
. num_adapters = 1 ,
. download_firmware = dw2102_load_firmware ,
2009-11-27 14:37:35 -03:00
. read_mac_address = s6x0_read_mac_address ,
2009-06-20 09:54:18 -03:00
. adapter = {
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2011-02-25 18:41:22 -03:00
. frontend_attach = zl100313_frontend_attach ,
2009-06-20 09:54:18 -03:00
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 09:31:57 -03:00
} } ,
2009-06-20 09:54:18 -03:00
}
} ,
2011-02-25 18:41:22 -03:00
. num_device_descs = 1 ,
2009-06-20 09:54:18 -03:00
. devices = {
{ " TeVii S630 USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TEVII_S630 ] , NULL } ,
2009-06-20 09:54:18 -03:00
{ NULL } ,
} ,
}
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d1100 = {
2011-02-25 18:41:22 -03:00
" Prof 1100 USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ PROF_1100 ] , NULL } ,
2011-02-25 18:41:22 -03:00
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d660 = {
2011-02-25 18:41:22 -03:00
" TeVii S660 USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TEVII_S660 ] , NULL } ,
2011-02-25 18:41:22 -03:00
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d480_1 = {
2011-02-25 18:41:23 -03:00
" TeVii S480.1 USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TEVII_S480_1 ] , NULL } ,
2011-02-25 18:41:23 -03:00
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d480_2 = {
2011-02-25 18:41:23 -03:00
" TeVii S480.2 USB " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TEVII_S480_2 ] , NULL } ,
2011-02-25 18:41:23 -03:00
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d7500 = {
2009-12-14 20:24:56 -03:00
" Prof 7500 USB DVB-S2 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ PROF_7500 ] , NULL } ,
2009-12-14 20:24:56 -03:00
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d421 = {
2012-05-08 03:53:17 -03:00
" TeVii S421 PCI " ,
{ & dw2102_table [ TEVII_S421 ] , NULL } ,
{ NULL } ,
} ;
2017-08-03 06:00:32 -04:00
static const struct dvb_usb_device_description d632 = {
2012-05-08 03:53:17 -03:00
" TeVii S632 USB " ,
{ & dw2102_table [ TEVII_S632 ] , NULL } ,
{ NULL } ,
} ;
2011-02-25 18:41:22 -03:00
static struct dvb_usb_device_properties su3000_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2015-03-16 14:14:04 -03:00
. size_of_priv = sizeof ( struct dw2102_state ) ,
2011-02-25 18:41:22 -03:00
. power_ctrl = su3000_power_ctrl ,
. num_adapters = 1 ,
. identify_state = su3000_identify_state ,
. i2c_algo = & su3000_i2c_algo ,
2013-11-15 16:43:33 -03:00
. rc . core = {
2011-02-25 18:41:22 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_SU3000 ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_RC5 ,
2013-11-15 16:43:33 -03:00
. rc_query = su3000_rc_query ,
2011-02-25 18:41:22 -03:00
} ,
. read_mac_address = su3000_read_mac_address ,
. generic_bulk_ctrl_endpoint = 0x01 ,
. adapter = {
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2011-02-25 18:41:22 -03:00
. streaming_ctrl = su3000_streaming_ctrl ,
. frontend_attach = su3000_frontend_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
}
2011-09-06 09:31:57 -03:00
} } ,
2011-02-25 18:41:22 -03:00
}
} ,
2020-10-06 20:13:09 +02:00
. num_device_descs = 9 ,
2011-02-25 18:41:22 -03:00
. devices = {
{ " SU3000HD DVB-S USB2.0 " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ GENIATECH_SU3000 ] , NULL } ,
2011-02-25 18:41:22 -03:00
{ NULL } ,
} ,
2020-10-06 20:13:09 +02:00
{ " Hauppauge MAX S2 or WinTV NOVA HD USB2.0 " ,
{ & dw2102_table [ HAUPPAUGE_MAX_S2 ] , NULL } ,
{ NULL } ,
} ,
2011-02-25 18:41:22 -03:00
{ " Terratec Cinergy S2 USB HD " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ TERRATEC_CINERGY_S2 ] , NULL } ,
2011-02-25 18:41:22 -03:00
{ NULL } ,
} ,
2011-02-27 16:17:25 -03:00
{ " X3M TV SPC1400HD PCI " ,
2011-12-23 19:00:45 -03:00
{ & dw2102_table [ X3M_SPC1400HD ] , NULL } ,
2011-02-27 16:17:25 -03:00
{ NULL } ,
} ,
2013-02-21 08:11:41 -03:00
{ " Terratec Cinergy S2 USB HD Rev.2 " ,
{ & dw2102_table [ TERRATEC_CINERGY_S2_R2 ] , NULL } ,
{ NULL } ,
} ,
2016-06-13 11:04:50 -03:00
{ " Terratec Cinergy S2 USB HD Rev.3 " ,
{ & dw2102_table [ TERRATEC_CINERGY_S2_R3 ] , NULL } ,
{ NULL } ,
} ,
2020-05-11 10:29:53 +02:00
{ " Terratec Cinergy S2 PCIe Dual Port 1 " ,
{ & dw2102_table [ TERRATEC_CINERGY_S2_1 ] , NULL } ,
{ NULL } ,
} ,
{ " Terratec Cinergy S2 PCIe Dual Port 2 " ,
{ & dw2102_table [ TERRATEC_CINERGY_S2_2 ] , NULL } ,
{ NULL } ,
} ,
2013-03-07 09:36:22 -03:00
{ " GOTVIEW Satellite HD " ,
{ & dw2102_table [ GOTVIEW_SAT_HD ] , NULL } ,
{ NULL } ,
} ,
2011-02-25 18:41:22 -03:00
}
} ;
2013-11-13 20:53:59 -03:00
static struct dvb_usb_device_properties t220_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
2015-03-16 14:14:04 -03:00
. size_of_priv = sizeof ( struct dw2102_state ) ,
2013-11-13 20:53:59 -03:00
. power_ctrl = su3000_power_ctrl ,
. num_adapters = 1 ,
. identify_state = su3000_identify_state ,
. i2c_algo = & su3000_i2c_algo ,
2013-11-15 16:43:33 -03:00
. rc . core = {
2013-11-13 20:53:59 -03:00
. rc_interval = 150 ,
2013-11-15 16:43:33 -03:00
. rc_codes = RC_MAP_SU3000 ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_RC5 ,
2013-11-15 16:43:33 -03:00
. rc_query = su3000_rc_query ,
2013-11-13 20:53:59 -03:00
} ,
. read_mac_address = su3000_read_mac_address ,
. generic_bulk_ctrl_endpoint = 0x01 ,
. adapter = {
{
. num_frontends = 1 ,
. fe = { {
. streaming_ctrl = su3000_streaming_ctrl ,
. frontend_attach = t220_frontend_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
}
} } ,
}
} ,
. num_device_descs = 1 ,
. devices = {
{ " Geniatech T220 DVB-T/T2 USB2.0 " ,
{ & dw2102_table [ GENIATECH_T220 ] , NULL } ,
{ NULL } ,
} ,
}
} ;
2015-03-16 14:22:18 -03:00
static struct dvb_usb_device_properties tt_s2_4600_properties = {
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = DEVICE_SPECIFIC ,
. size_of_priv = sizeof ( struct dw2102_state ) ,
. power_ctrl = su3000_power_ctrl ,
. num_adapters = 1 ,
. identify_state = su3000_identify_state ,
. i2c_algo = & su3000_i2c_algo ,
. rc . core = {
. rc_interval = 250 ,
. rc_codes = RC_MAP_TT_1500 ,
. module_name = " dw2102 " ,
2017-08-07 16:20:58 -04:00
. allowed_protos = RC_PROTO_BIT_RC5 ,
2015-03-16 14:22:18 -03:00
. rc_query = su3000_rc_query ,
} ,
. read_mac_address = su3000_read_mac_address ,
. generic_bulk_ctrl_endpoint = 0x01 ,
. adapter = {
{
. num_frontends = 1 ,
. fe = { {
. streaming_ctrl = su3000_streaming_ctrl ,
. frontend_attach = tt_s2_4600_frontend_attach ,
. stream = {
. type = USB_BULK ,
. count = 8 ,
. endpoint = 0x82 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
}
} } ,
}
} ,
2016-03-02 08:06:06 -03:00
. num_device_descs = 5 ,
2015-03-16 14:22:18 -03:00
. devices = {
{ " TechnoTrend TT-connect S2-4600 " ,
{ & dw2102_table [ TECHNOTREND_S2_4600 ] , NULL } ,
{ NULL } ,
} ,
2015-03-21 17:42:23 -03:00
{ " TeVii S482 (tuner 1) " ,
{ & dw2102_table [ TEVII_S482_1 ] , NULL } ,
{ NULL } ,
} ,
{ " TeVii S482 (tuner 2) " ,
{ & dw2102_table [ TEVII_S482_2 ] , NULL } ,
{ NULL } ,
} ,
2016-01-04 17:32:51 -02:00
{ " Terratec Cinergy S2 USB BOX " ,
{ & dw2102_table [ TERRATEC_CINERGY_S2_BOX ] , NULL } ,
{ NULL } ,
} ,
2016-03-02 08:06:06 -03:00
{ " TeVii S662 " ,
{ & dw2102_table [ TEVII_S662 ] , NULL } ,
{ NULL } ,
} ,
2015-03-16 14:22:18 -03:00
}
} ;
2008-07-20 08:05:50 -03:00
static int dw2102_probe ( struct usb_interface * intf ,
const struct usb_device_id * id )
{
2017-08-10 11:27:44 -04:00
int retval = - ENOMEM ;
2018-07-23 13:04:54 -04:00
struct dvb_usb_device_properties * p1100 ;
struct dvb_usb_device_properties * s660 ;
struct dvb_usb_device_properties * p7500 ;
struct dvb_usb_device_properties * s421 ;
2011-11-17 18:43:40 -03:00
p1100 = kmemdup ( & s6x0_properties ,
sizeof ( struct dvb_usb_device_properties ) , GFP_KERNEL ) ;
2011-02-25 18:41:22 -03:00
if ( ! p1100 )
2017-08-10 11:27:44 -04:00
goto err0 ;
2011-02-25 18:41:22 -03:00
/* copy default structure */
/* fill only different fields */
2012-09-28 08:59:32 -03:00
p1100 - > firmware = P1100_FIRMWARE ;
2011-02-25 18:41:22 -03:00
p1100 - > devices [ 0 ] = d1100 ;
2013-11-15 16:43:33 -03:00
p1100 - > rc . core . rc_query = prof_rc_query ;
p1100 - > rc . core . rc_codes = RC_MAP_TBS_NEC ;
2011-09-06 09:31:57 -03:00
p1100 - > adapter - > fe [ 0 ] . frontend_attach = stv0288_frontend_attach ;
2011-02-25 18:41:22 -03:00
2011-11-17 18:43:40 -03:00
s660 = kmemdup ( & s6x0_properties ,
sizeof ( struct dvb_usb_device_properties ) , GFP_KERNEL ) ;
2017-08-10 11:27:44 -04:00
if ( ! s660 )
goto err1 ;
2012-09-28 08:59:32 -03:00
s660 - > firmware = S660_FIRMWARE ;
2011-02-25 18:41:23 -03:00
s660 - > num_device_descs = 3 ;
2011-02-25 18:41:22 -03:00
s660 - > devices [ 0 ] = d660 ;
2011-02-25 18:41:23 -03:00
s660 - > devices [ 1 ] = d480_1 ;
s660 - > devices [ 2 ] = d480_2 ;
2011-09-06 09:31:57 -03:00
s660 - > adapter - > fe [ 0 ] . frontend_attach = ds3000_frontend_attach ;
2009-12-14 20:24:56 -03:00
2011-11-17 18:43:40 -03:00
p7500 = kmemdup ( & s6x0_properties ,
sizeof ( struct dvb_usb_device_properties ) , GFP_KERNEL ) ;
2017-08-10 11:27:44 -04:00
if ( ! p7500 )
goto err2 ;
2012-09-28 08:59:32 -03:00
p7500 - > firmware = P7500_FIRMWARE ;
2009-12-14 20:24:56 -03:00
p7500 - > devices [ 0 ] = d7500 ;
2013-11-15 16:43:33 -03:00
p7500 - > rc . core . rc_query = prof_rc_query ;
p7500 - > rc . core . rc_codes = RC_MAP_TBS_NEC ;
2011-09-06 09:31:57 -03:00
p7500 - > adapter - > fe [ 0 ] . frontend_attach = prof_7500_frontend_attach ;
2009-12-14 20:24:56 -03:00
2012-05-08 03:53:17 -03:00
s421 = kmemdup ( & su3000_properties ,
sizeof ( struct dvb_usb_device_properties ) , GFP_KERNEL ) ;
2017-08-10 11:27:44 -04:00
if ( ! s421 )
goto err3 ;
2012-05-08 03:53:17 -03:00
s421 - > num_device_descs = 2 ;
s421 - > devices [ 0 ] = d421 ;
s421 - > devices [ 1 ] = d632 ;
s421 - > adapter - > fe [ 0 ] . frontend_attach = m88rs2000_frontend_attach ;
2008-09-08 17:16:40 -03:00
if ( 0 = = dvb_usb_device_init ( intf , & dw2102_properties ,
THIS_MODULE , NULL , adapter_nr ) | |
0 = = dvb_usb_device_init ( intf , & dw2104_properties ,
2009-06-14 20:51:45 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
0 = = dvb_usb_device_init ( intf , & dw3101_properties ,
2009-06-20 09:54:18 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
2009-11-27 14:37:35 -03:00
0 = = dvb_usb_device_init ( intf , & s6x0_properties ,
2009-12-14 20:24:56 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
2011-02-25 18:41:22 -03:00
0 = = dvb_usb_device_init ( intf , p1100 ,
THIS_MODULE , NULL , adapter_nr ) | |
0 = = dvb_usb_device_init ( intf , s660 ,
THIS_MODULE , NULL , adapter_nr ) | |
2009-12-14 20:24:56 -03:00
0 = = dvb_usb_device_init ( intf , p7500 ,
2011-02-25 18:41:22 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
2012-05-08 03:53:17 -03:00
0 = = dvb_usb_device_init ( intf , s421 ,
THIS_MODULE , NULL , adapter_nr ) | |
2011-02-25 18:41:22 -03:00
0 = = dvb_usb_device_init ( intf , & su3000_properties ,
2013-11-13 20:53:59 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
0 = = dvb_usb_device_init ( intf , & t220_properties ,
2015-03-16 14:22:18 -03:00
THIS_MODULE , NULL , adapter_nr ) | |
0 = = dvb_usb_device_init ( intf , & tt_s2_4600_properties ,
2018-07-23 13:04:54 -04:00
THIS_MODULE , NULL , adapter_nr ) ) {
/* clean up copied properties */
kfree ( s421 ) ;
kfree ( p7500 ) ;
kfree ( s660 ) ;
kfree ( p1100 ) ;
2008-09-08 17:16:40 -03:00
return 0 ;
2018-07-23 13:04:54 -04:00
}
2009-11-27 14:37:35 -03:00
2017-08-10 11:27:44 -04:00
retval = - ENODEV ;
kfree ( s421 ) ;
err3 :
kfree ( p7500 ) ;
err2 :
kfree ( s660 ) ;
err1 :
kfree ( p1100 ) ;
err0 :
return retval ;
2008-07-20 08:05:50 -03:00
}
2015-03-16 14:14:05 -03:00
static void dw2102_disconnect ( struct usb_interface * intf )
{
struct dvb_usb_device * d = usb_get_intfdata ( intf ) ;
struct dw2102_state * st = ( struct dw2102_state * ) d - > priv ;
struct i2c_client * client ;
/* remove I2C client for tuner */
client = st - > i2c_client_tuner ;
if ( client ) {
module_put ( client - > dev . driver - > owner ) ;
i2c_unregister_device ( client ) ;
}
2016-02-16 15:53:45 -02:00
/* remove I2C client for demodulator */
client = st - > i2c_client_demod ;
if ( client ) {
module_put ( client - > dev . driver - > owner ) ;
i2c_unregister_device ( client ) ;
}
2015-03-16 14:14:05 -03:00
dvb_usb_device_exit ( intf ) ;
}
2008-07-20 08:05:50 -03:00
static struct usb_driver dw2102_driver = {
. name = " dw2102 " ,
. probe = dw2102_probe ,
2015-03-16 14:14:05 -03:00
. disconnect = dw2102_disconnect ,
2008-07-20 08:05:50 -03:00
. id_table = dw2102_table ,
} ;
2011-11-18 09:46:12 -08:00
module_usb_driver ( dw2102_driver ) ;
2008-07-20 08:05:50 -03:00
MODULE_AUTHOR ( " Igor M. Liplianin (c) liplianin@me.by " ) ;
[media] dvb-usb: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-18 17:44:15 -02:00
MODULE_DESCRIPTION ( " Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101 USB2.0, TeVii S421, S480, S482, S600, S630, S632, S650, TeVii S660, S662, Prof 1100, 7500 USB2.0, Geniatech SU3000, T220, TechnoTrend S2-4600, Terratec Cinergy S2 devices " ) ;
2008-07-20 08:05:50 -03:00
MODULE_VERSION ( " 0.1 " ) ;
MODULE_LICENSE ( " GPL " ) ;
2012-09-28 08:59:32 -03:00
MODULE_FIRMWARE ( DW2101_FIRMWARE ) ;
MODULE_FIRMWARE ( DW2102_FIRMWARE ) ;
MODULE_FIRMWARE ( DW2104_FIRMWARE ) ;
MODULE_FIRMWARE ( DW3101_FIRMWARE ) ;
MODULE_FIRMWARE ( S630_FIRMWARE ) ;
MODULE_FIRMWARE ( S660_FIRMWARE ) ;
MODULE_FIRMWARE ( P1100_FIRMWARE ) ;
MODULE_FIRMWARE ( P7500_FIRMWARE ) ;