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 ,
2012-05-08 03:53:17 -03:00
* TeVii S600 , S630 , S650 , S660 , S480 , S421 , S632
2011-02-25 18:41:23 -03:00
* Prof 1100 , 7500 ,
2015-03-16 14:22:18 -03:00
* Geniatech SU3000 , T220 ,
* TechnoTrend S2 - 4600 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
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation , version 2.
*
* see Documentation / dvb / README . dvb - usb for more information
*/
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"
2015-03-29 19:28:39 -03:00
# include "ts2020.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
2008-07-20 08:05:50 -03:00
# ifndef USB_PID_DW2102
# define USB_PID_DW2102 0x2102
# endif
2008-09-08 17:16:40 -03:00
# ifndef USB_PID_DW2104
# define USB_PID_DW2104 0x2104
# endif
2009-06-14 20:51:45 -03:00
# ifndef USB_PID_DW3101
# define USB_PID_DW3101 0x3101
# endif
2008-11-05 22:12:56 -03:00
# ifndef USB_PID_CINERGY_S
# define USB_PID_CINERGY_S 0x0064
# endif
2009-11-27 14:37:35 -03:00
# ifndef USB_PID_TEVII_S630
# define USB_PID_TEVII_S630 0xd630
# endif
2009-06-14 20:51:45 -03:00
# ifndef USB_PID_TEVII_S650
# define USB_PID_TEVII_S650 0xd650
# endif
2009-11-27 14:37:35 -03:00
# ifndef USB_PID_TEVII_S660
# define USB_PID_TEVII_S660 0xd660
# endif
2011-02-25 18:41:23 -03:00
# ifndef USB_PID_TEVII_S480_1
# define USB_PID_TEVII_S480_1 0xd481
# endif
# ifndef USB_PID_TEVII_S480_2
# define USB_PID_TEVII_S480_2 0xd482
# endif
2009-11-27 14:37:35 -03:00
# ifndef USB_PID_PROF_1100
# define USB_PID_PROF_1100 0xb012
2009-06-20 09:54:18 -03:00
# endif
2012-05-08 03:53:17 -03:00
# ifndef USB_PID_TEVII_S421
# define USB_PID_TEVII_S421 0xd421
# endif
# ifndef USB_PID_TEVII_S632
# define USB_PID_TEVII_S632 0xd632
# endif
2013-03-07 09:36:22 -03:00
# ifndef USB_PID_GOTVIEW_SAT_HD
# define USB_PID_GOTVIEW_SAT_HD 0x5456
# endif
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"
2009-11-27 14:37:35 -03:00
# define err_str "did not find the firmware file. (%s) " \
" Please see linux/Documentation/dvb/ for more details " \
" on firmware-problems. "
2015-03-16 14:14:04 -03:00
struct dw2102_state {
2011-02-25 18:41:22 -03:00
u8 initialized ;
2015-03-16 14:14:05 -03:00
struct i2c_client * i2c_client_tuner ;
2011-02-25 18:41:23 -03:00
int ( * old_set_voltage ) ( struct dvb_frontend * f , fe_sec_voltage_t v ) ;
} ;
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 ) ;
MODULE_PARM_DESC ( demod , " demod to probe (1=cx24116 2=stv0903+stv6110 "
" 4=stv0903+stb6100(or-able)). " ) ;
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 :
/* 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 :
/* 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 ] ;
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 ] ;
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 ) ;
u8 obuf [ 0x40 ] , ibuf [ 0x40 ] ;
if ( ! d )
return - ENODEV ;
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
return - EAGAIN ;
switch ( num ) {
case 1 :
switch ( msg [ 0 ] . addr ) {
case SU3000_STREAM_CTRL :
obuf [ 0 ] = msg [ 0 ] . buf [ 0 ] + 0x36 ;
obuf [ 1 ] = 3 ;
obuf [ 2 ] = 0 ;
if ( dvb_usb_generic_rw ( d , obuf , 3 , ibuf , 0 , 0 ) < 0 )
err ( " i2c transfer failed. " ) ;
break ;
case DW2102_RC_QUERY :
obuf [ 0 ] = 0x10 ;
if ( dvb_usb_generic_rw ( d , obuf , 1 , ibuf , 2 , 0 ) < 0 )
err ( " i2c transfer failed. " ) ;
msg [ 0 ] . buf [ 1 ] = ibuf [ 0 ] ;
msg [ 0 ] . buf [ 0 ] = ibuf [ 1 ] ;
break ;
default :
/* always i2c write*/
obuf [ 0 ] = 0x08 ;
obuf [ 1 ] = msg [ 0 ] . addr ;
obuf [ 2 ] = msg [ 0 ] . len ;
memcpy ( & obuf [ 3 ] , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
if ( dvb_usb_generic_rw ( d , obuf , msg [ 0 ] . len + 3 ,
ibuf , 1 , 0 ) < 0 )
err ( " i2c transfer failed. " ) ;
}
break ;
case 2 :
/* always i2c read */
obuf [ 0 ] = 0x09 ;
obuf [ 1 ] = msg [ 0 ] . len ;
obuf [ 2 ] = msg [ 1 ] . len ;
obuf [ 3 ] = msg [ 0 ] . addr ;
memcpy ( & obuf [ 4 ] , msg [ 0 ] . buf , msg [ 0 ] . len ) ;
if ( dvb_usb_generic_rw ( d , obuf , msg [ 0 ] . len + 4 ,
ibuf , msg [ 1 ] . len + 1 , 0 ) < 0 )
err ( " i2c transfer failed. " ) ;
memcpy ( msg [ 1 ] . buf , & ibuf [ 1 ] , msg [ 1 ] . len ) ;
break ;
default :
warn ( " more than 2 i2c messages at a time is not handled yet. " ) ;
break ;
}
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 ;
2011-02-25 18:41:22 -03:00
u8 obuf [ ] = { 0xde , 0 } ;
info ( " %s: %d, initialized %d \n " , __func__ , i , state - > initialized ) ;
if ( i & & ! state - > initialized ) {
state - > initialized = 1 ;
/* reset board */
dvb_usb_generic_rw ( d , obuf , 2 , NULL , 0 , 0 ) ;
}
return 0 ;
}
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 ] ;
debug_dump ( mac , 6 , printk ) ;
}
return 0 ;
}
static int su3000_identify_state ( struct usb_device * udev ,
struct dvb_usb_device_properties * props ,
struct dvb_usb_device_description * * desc ,
int * cold )
{
info ( " %s \n " , __func__ ) ;
* cold = 0 ;
return 0 ;
}
2008-09-17 19:19:19 -03:00
static int dw210x_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t 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 ;
}
2011-02-25 18:41:23 -03:00
static int s660_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t voltage )
{
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 ) ;
}
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 ,
} ;
2015-03-16 14:22:18 -03:00
static const struct m88ds3103_config tt_s2_4600_m88ds3103_config = {
. i2c_addr = 0x68 ,
. clock = 27000000 ,
. i2c_wr_max = 33 ,
. ts_mode = M88DS3103_TS_CI ,
. ts_clk = 16000 ,
. ts_clk_pol = 0 ,
. spec_inv = 0 ,
. agc_inv = 0 ,
. clock_out = M88DS3103_CLOCK_OUT_ENABLED ,
. envelope_mode = 0 ,
. agc = 0x99 ,
. lnb_hv_pol = 1 ,
. lnb_en_pol = 0 ,
} ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached STV0900+STB6100! \n " ) ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached STV0900+STV6110A! \n " ) ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached cx24116! \n " ) ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached DS3000! \n " ) ;
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 ;
2008-09-17 19:19:19 -03:00
info ( " Attached si21xx! \n " ) ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached stv0288! \n " ) ;
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 ;
2008-09-17 19:19:19 -03:00
info ( " Attached stv0299! \n " ) ;
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 ) {
2009-06-14 20:51:45 -03:00
info ( " Attached tda10023! \n " ) ;
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 ;
2009-11-27 14:37:35 -03:00
info ( " Attached zl100313+zl10039! \n " ) ;
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 ) ;
info ( " Attached stv0288+stb6000! \n " ) ;
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 ) ;
2013-08-28 09:37:37 -03:00
info ( " Attached ds3000+ts2020! \n " ) ;
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 ) ;
2009-12-14 20:24:56 -03:00
info ( " Attached STV0900+STB6100A! \n " ) ;
return 0 ;
}
2011-02-25 18:41:22 -03:00
static int su3000_frontend_attach ( struct dvb_usb_adapter * d )
{
u8 obuf [ 3 ] = { 0xe , 0x80 , 0 } ;
u8 ibuf [ ] = { 0 } ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
2012-12-28 19:40:33 -03:00
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x02 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
msleep ( 300 ) ;
2011-02-25 18:41:22 -03:00
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x83 ;
obuf [ 2 ] = 0 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x83 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0x51 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 1 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x51 transfer failed. " ) ;
2011-09-06 09:31:57 -03:00
d - > fe_adap [ 0 ] . fe = dvb_attach ( ds3000_attach , & su3000_ds3000_config ,
2011-02-25 18:41:22 -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:22 -03:00
return - EIO ;
2012-12-28 19:40:33 -03:00
if ( dvb_attach ( ts2020_attach , d - > fe_adap [ 0 ] . fe ,
& dw2104_ts2020_config ,
& d - > dev - > i2c_adap ) ) {
info ( " Attached DS3000/TS2020! \n " ) ;
return 0 ;
}
2011-02-25 18:41:22 -03:00
2012-12-28 19:40:33 -03:00
info ( " Failed to attach DS3000/TS2020! \n " ) ;
return - EIO ;
2011-02-25 18:41:22 -03:00
}
2013-11-13 20:53:59 -03:00
static int t220_frontend_attach ( struct dvb_usb_adapter * d )
{
2014-06-03 14:22:44 -03:00
u8 obuf [ 3 ] = { 0xe , 0x87 , 0 } ;
2013-11-13 20:53:59 -03:00
u8 ibuf [ ] = { 0 } ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0xe ;
2014-06-03 14:22:44 -03:00
obuf [ 1 ] = 0x86 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x80 ;
2013-11-13 20:53:59 -03:00
obuf [ 2 ] = 0 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
2014-06-03 14:22:44 -03:00
msleep ( 50 ) ;
2013-11-13 20:53:59 -03:00
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x80 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0x51 ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 1 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x51 transfer failed. " ) ;
d - > fe_adap [ 0 ] . fe = dvb_attach ( cxd2820r_attach , & cxd2820r_config ,
& d - > dev - > i2c_adap , NULL ) ;
if ( d - > fe_adap [ 0 ] . fe ! = NULL ) {
if ( dvb_attach ( tda18271_attach , d - > fe_adap [ 0 ] . fe , 0x60 ,
& d - > dev - > i2c_adap , & tda18271_config ) ) {
info ( " Attached TDA18271HD/CXD2820R! \n " ) ;
return 0 ;
}
}
info ( " Failed to attach TDA18271HD/CXD2820R! \n " ) ;
return - EIO ;
}
2012-05-08 03:53:17 -03:00
static int m88rs2000_frontend_attach ( struct dvb_usb_adapter * d )
{
u8 obuf [ ] = { 0x51 } ;
u8 ibuf [ ] = { 0 } ;
if ( dvb_usb_generic_rw ( d - > dev , obuf , 1 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x51 transfer failed. " ) ;
d - > fe_adap [ 0 ] . fe = dvb_attach ( m88rs2000_attach , & s421_m88rs2000_config ,
& d - > dev - > i2c_adap ) ;
2012-12-28 19:40:33 -03:00
2012-05-08 03:53:17 -03:00
if ( d - > fe_adap [ 0 ] . fe = = NULL )
return - EIO ;
2012-12-28 19:40:33 -03:00
if ( dvb_attach ( ts2020_attach , d - > fe_adap [ 0 ] . fe ,
& dw2104_ts2020_config ,
& d - > dev - > i2c_adap ) ) {
info ( " Attached RS2000/TS2020! \n " ) ;
return 0 ;
}
2012-05-08 03:53:17 -03:00
2012-12-28 19:40:33 -03:00
info ( " Failed to attach RS2000/TS2020! \n " ) ;
return - EIO ;
2012-05-08 03:53:17 -03:00
}
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 ;
u8 obuf [ 3 ] = { 0xe , 0x80 , 0 } ;
u8 ibuf [ ] = { 0 } ;
struct i2c_adapter * i2c_adapter ;
struct i2c_client * client ;
struct i2c_board_info info ;
2015-03-29 19:28:39 -03:00
struct ts2020_config ts2020_config = { } ;
2015-03-16 14:22:18 -03:00
if ( dvb_usb_generic_rw ( d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x02 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
msleep ( 300 ) ;
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x83 ;
obuf [ 2 ] = 0 ;
if ( dvb_usb_generic_rw ( d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0xe ;
obuf [ 1 ] = 0x83 ;
obuf [ 2 ] = 1 ;
if ( dvb_usb_generic_rw ( d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x0e transfer failed. " ) ;
obuf [ 0 ] = 0x51 ;
if ( dvb_usb_generic_rw ( d , obuf , 1 , ibuf , 1 , 0 ) < 0 )
err ( " command 0x51 transfer failed. " ) ;
memset ( & info , 0 , sizeof ( struct i2c_board_info ) ) ;
adap - > fe_adap [ 0 ] . fe = dvb_attach ( m88ds3103_attach ,
& tt_s2_4600_m88ds3103_config ,
& d - > i2c_adap ,
& i2c_adapter ) ;
if ( adap - > fe_adap [ 0 ] . fe = = NULL )
return - ENODEV ;
/* attach tuner */
2015-03-29 19:28:39 -03:00
ts2020_config . fe = adap - > fe_adap [ 0 ] . fe ;
strlcpy ( info . type , " ts2022 " , I2C_NAME_SIZE ) ;
2015-03-16 14:22:18 -03:00
info . addr = 0x60 ;
2015-03-29 19:28:39 -03:00
info . platform_data = & ts2020_config ;
request_module ( " ts2020 " ) ;
2015-03-16 14:22:18 -03:00
client = i2c_new_device ( i2c_adapter , & info ) ;
if ( client = = NULL | | client - > dev . driver = = NULL ) {
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 ;
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 ] ) ;
2014-04-03 20:31:30 -03:00
rc_keydown ( d - > rc_dev , RC_TYPE_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 ] ) ;
2014-04-03 20:31:30 -03:00
rc_keydown ( d - > rc_dev , RC_TYPE_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 ] ) ;
2014-04-03 20:31:30 -03:00
rc_keydown ( d - > rc_dev , RC_TYPE_RC5 ,
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 ,
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 ,
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 ,
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 ) } ,
[ TERRATEC_CINERGY_S ] = { USB_DEVICE ( USB_VID_TERRATEC , USB_PID_CINERGY_S ) } ,
[ 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 ) } ,
[ TERRATEC_CINERGY_S2 ] = { USB_DEVICE ( USB_VID_TERRATEC , 0x00a8 ) } ,
[ 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 ) } ,
2013-02-21 08:11:41 -03:00
[ TERRATEC_CINERGY_S2_R2 ] = { USB_DEVICE ( USB_VID_TERRATEC , 0x00b0 ) } ,
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 ) } ,
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 ;
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 ) ;
2009-06-14 20:51:45 -03:00
/* break omitted intentionally */
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 ;
2008-11-05 22:12:56 -03:00
case USB_PID_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 ;
}
}
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 ) ;
}
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 " ,
. allowed_protos = RC_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 " ,
. allowed_protos = RC_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 " ,
. allowed_protos = RC_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 " ,
. allowed_protos = RC_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 } ,
} ,
}
} ;
2014-08-20 16:45:27 -03:00
static struct dvb_usb_device_properties * p1100 ;
2011-02-25 18:41:22 -03:00
static struct dvb_usb_device_description d1100 = {
" 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 } ,
} ;
2014-08-20 16:45:27 -03:00
static struct dvb_usb_device_properties * s660 ;
2011-02-25 18:41:22 -03:00
static struct dvb_usb_device_description d660 = {
" 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 } ,
} ;
2011-02-25 18:41:23 -03:00
static struct dvb_usb_device_description d480_1 = {
" 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 } ,
} ;
static struct dvb_usb_device_description d480_2 = {
" 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 } ,
} ;
2014-08-20 16:45:27 -03:00
static struct dvb_usb_device_properties * p7500 ;
2009-12-14 20:24:56 -03:00
static struct dvb_usb_device_description d7500 = {
" 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 } ,
} ;
2014-08-20 16:45:27 -03:00
static struct dvb_usb_device_properties * s421 ;
2012-05-08 03:53:17 -03:00
static struct dvb_usb_device_description d421 = {
" TeVii S421 PCI " ,
{ & dw2102_table [ TEVII_S421 ] , NULL } ,
{ NULL } ,
} ;
static struct dvb_usb_device_description d632 = {
" 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 " ,
. allowed_protos = RC_BIT_RC5 ,
. 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
}
} ,
2013-03-07 09:36:22 -03:00
. num_device_descs = 5 ,
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 } ,
} ,
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 } ,
} ,
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 " ,
. allowed_protos = RC_BIT_RC5 ,
. 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 " ,
. allowed_protos = RC_BIT_RC5 ,
. 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 ,
}
}
}
} } ,
}
} ,
. num_device_descs = 1 ,
. devices = {
{ " TechnoTrend TT-connect S2-4600 " ,
{ & dw2102_table [ TECHNOTREND_S2_4600 ] , NULL } ,
{ NULL } ,
} ,
}
} ;
2008-07-20 08:05:50 -03:00
static int dw2102_probe ( struct usb_interface * intf ,
const struct usb_device_id * id )
{
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 )
return - ENOMEM ;
/* 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 ) ;
2011-02-25 18:41:22 -03:00
if ( ! s660 ) {
kfree ( p1100 ) ;
return - ENOMEM ;
}
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 ) ;
2011-02-25 18:41:22 -03:00
if ( ! p7500 ) {
kfree ( p1100 ) ;
kfree ( s660 ) ;
2009-12-14 20:24:56 -03:00
return - ENOMEM ;
2011-02-25 18:41:22 -03:00
}
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 ) ;
if ( ! s421 ) {
kfree ( p1100 ) ;
kfree ( s660 ) ;
kfree ( p7500 ) ;
return - ENOMEM ;
}
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 ,
2013-11-13 20:53:59 -03:00
THIS_MODULE , NULL , adapter_nr ) )
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 - ENODEV ;
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 ) ;
}
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 " ) ;
2009-06-14 20:51:45 -03:00
MODULE_DESCRIPTION ( " Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104, "
2012-05-08 03:53:17 -03:00
" DVB-C 3101 USB2.0, "
" TeVii S600, S630, S650, S660, S480, S421, S632 "
" Prof 1100, 7500 USB2.0, "
2015-03-16 14:22:18 -03:00
" Geniatech SU3000, T220, "
" TechnoTrend S2-4600 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 ) ;