2005-06-23 22:02:35 -07:00
/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
* receiver
*
2016-01-24 12:56:58 -02:00
* Copyright ( C ) 2005 Patrick Boettcher ( patrick . boettcher @ posteo . de )
2005-06-23 22:02:35 -07:00
*
2005-07-07 17:58:13 -07:00
* partly based on the SDK published by Nebula Electronics
2005-06-23 22:02:35 -07:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation , version 2.
*
* see Documentation / dvb / README . dvb - usb for more information
*/
# include "digitv.h"
# include "mt352.h"
# include "nxt6000.h"
/* debug */
2007-11-05 14:07:06 -03:00
static int dvb_usb_digitv_debug ;
2005-06-23 22:02:35 -07:00
module_param_named ( debug , dvb_usb_digitv_debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " set debugging level (1=rc (or-able)). " DVB_USB_DEBUG_STATUS ) ;
2008-04-09 19:13:13 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2007-11-05 14:07:06 -03:00
# define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
2005-06-23 22:02:35 -07:00
static int digitv_ctrl_msg ( struct dvb_usb_device * d ,
u8 cmd , u8 vv , u8 * wbuf , int wlen , u8 * rbuf , int rlen )
{
2016-10-07 07:55:38 -03:00
struct digitv_state * st = d - > priv ;
2016-10-07 13:52:31 -03:00
int ret , wo ;
wo = ( rbuf = = NULL | | rlen = = 0 ) ; /* write-only */
2005-06-23 22:02:35 -07:00
2017-04-01 14:33:42 -03:00
if ( wlen > 4 | | rlen > 4 )
return - EIO ;
2016-10-07 07:55:38 -03:00
memset ( st - > sndbuf , 0 , 7 ) ;
memset ( st - > rcvbuf , 0 , 7 ) ;
st - > sndbuf [ 0 ] = cmd ;
st - > sndbuf [ 1 ] = vv ;
st - > sndbuf [ 2 ] = wo ? wlen : rlen ;
2005-06-23 22:02:35 -07:00
2006-01-09 15:25:22 -02:00
if ( wo ) {
2016-10-07 07:55:38 -03:00
memcpy ( & st - > sndbuf [ 3 ] , wbuf , wlen ) ;
2016-10-07 13:52:31 -03:00
ret = dvb_usb_generic_write ( d , st - > sndbuf , 7 ) ;
2005-06-23 22:02:35 -07:00
} else {
2016-10-07 13:52:31 -03:00
ret = dvb_usb_generic_rw ( d , st - > sndbuf , 7 , st - > rcvbuf , 7 , 10 ) ;
2016-10-07 07:55:38 -03:00
memcpy ( rbuf , & st - > rcvbuf [ 3 ] , rlen ) ;
2005-06-23 22:02:35 -07:00
}
2016-10-07 13:52:31 -03:00
return ret ;
2005-06-23 22:02:35 -07:00
}
/* I2C */
static int digitv_i2c_xfer ( struct i2c_adapter * adap , struct i2c_msg msg [ ] , int num )
{
struct dvb_usb_device * d = i2c_get_adapdata ( adap ) ;
int i ;
2006-02-07 06:49:14 -02:00
if ( mutex_lock_interruptible ( & d - > i2c_mutex ) < 0 )
2005-06-23 22:02:35 -07:00
return - EAGAIN ;
if ( num > 2 )
warn ( " more than 2 i2c messages at a time is not handled yet. TODO. " ) ;
for ( i = 0 ; i < num ; i + + ) {
/* write/read request */
if ( i + 1 < num & & ( msg [ i + 1 ] . flags & I2C_M_RD ) ) {
if ( digitv_ctrl_msg ( d , USB_READ_COFDM , msg [ i ] . buf [ 0 ] , NULL , 0 ,
msg [ i + 1 ] . buf , msg [ i + 1 ] . len ) < 0 )
break ;
i + + ;
} else
if ( digitv_ctrl_msg ( d , USB_WRITE_COFDM , msg [ i ] . buf [ 0 ] ,
& msg [ i ] . buf [ 1 ] , msg [ i ] . len - 1 , NULL , 0 ) < 0 )
break ;
}
2006-02-07 06:49:14 -02:00
mutex_unlock ( & d - > i2c_mutex ) ;
2005-06-23 22:02:35 -07:00
return i ;
}
static u32 digitv_i2c_func ( struct i2c_adapter * adapter )
{
return I2C_FUNC_I2C ;
}
static struct i2c_algorithm digitv_i2c_algo = {
. master_xfer = digitv_i2c_xfer ,
. functionality = digitv_i2c_func ,
} ;
/* Callbacks for DVB USB */
static int digitv_identify_state ( struct usb_device * udev , struct
2006-09-30 06:53:48 -03:00
dvb_usb_device_properties * props , struct dvb_usb_device_description * * desc ,
2005-06-23 22:02:35 -07:00
int * cold )
{
* cold = udev - > descriptor . iManufacturer = = 0 & & udev - > descriptor . iProduct = = 0 ;
return 0 ;
}
static int digitv_mt352_demod_init ( struct dvb_frontend * fe )
{
2005-07-07 17:58:13 -07:00
static u8 reset_buf [ ] = { 0x89 , 0x38 , 0x8a , 0x2d , 0x50 , 0x80 } ;
static u8 init_buf [ ] = { 0x68 , 0xa0 , 0x8e , 0x40 , 0x53 , 0x50 ,
0x67 , 0x20 , 0x7d , 0x01 , 0x7c , 0x00 , 0x7a , 0x00 ,
0x79 , 0x20 , 0x57 , 0x05 , 0x56 , 0x31 , 0x88 , 0x0f ,
0x75 , 0x32 } ;
int i ;
2005-06-23 22:02:35 -07:00
2005-07-07 17:58:13 -07:00
for ( i = 0 ; i < ARRAY_SIZE ( reset_buf ) ; i + = 2 )
mt352_write ( fe , & reset_buf [ i ] , 2 ) ;
2005-06-23 22:02:35 -07:00
msleep ( 1 ) ;
2005-07-07 17:58:13 -07:00
for ( i = 0 ; i < ARRAY_SIZE ( init_buf ) ; i + = 2 )
mt352_write ( fe , & init_buf [ i ] , 2 ) ;
2005-06-23 22:02:35 -07:00
return 0 ;
}
static struct mt352_config digitv_mt352_config = {
. demod_init = digitv_mt352_demod_init ,
} ;
2011-12-24 12:24:33 -03:00
static int digitv_nxt6000_tuner_set_params ( struct dvb_frontend * fe )
2005-09-09 13:02:48 -07:00
{
2006-09-30 06:53:48 -03:00
struct dvb_usb_adapter * adap = fe - > dvb - > priv ;
2005-09-09 13:02:48 -07:00
u8 b [ 5 ] ;
2007-06-02 16:30:46 -03:00
2011-12-24 12:03:05 -03:00
fe - > ops . tuner_ops . calc_regs ( fe , b , sizeof ( b ) ) ;
2007-02-21 21:47:15 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2006-09-30 06:53:48 -03:00
return digitv_ctrl_msg ( adap - > dev , USB_WRITE_TUNER , 0 , & b [ 1 ] , 4 , NULL , 0 ) ;
2005-09-09 13:02:48 -07:00
}
2005-06-23 22:02:35 -07:00
2005-09-09 13:02:48 -07:00
static struct nxt6000_config digitv_nxt6000_config = {
. clock_inversion = 1 ,
2005-06-23 22:02:35 -07:00
} ;
2006-09-30 06:53:48 -03:00
static int digitv_frontend_attach ( struct dvb_usb_adapter * adap )
2005-06-23 22:02:35 -07:00
{
2007-06-02 16:30:46 -03:00
struct digitv_state * st = adap - > dev - > priv ;
2011-09-17 14:55:47 -03:00
adap - > fe_adap [ 0 ] . fe = dvb_attach ( mt352_attach , & digitv_mt352_config ,
& adap - > dev - > i2c_adap ) ;
if ( ( adap - > fe_adap [ 0 ] . fe ) ! = NULL ) {
2007-06-02 16:30:46 -03:00
st - > is_nxt6000 = 0 ;
2005-06-23 22:02:35 -07:00
return 0 ;
2006-04-18 17:47:12 -03:00
}
2011-09-17 14:55:47 -03:00
adap - > fe_adap [ 0 ] . fe = dvb_attach ( nxt6000_attach ,
& digitv_nxt6000_config ,
& adap - > dev - > i2c_adap ) ;
if ( ( adap - > fe_adap [ 0 ] . fe ) ! = NULL ) {
2007-06-02 16:30:46 -03:00
st - > is_nxt6000 = 1 ;
2006-04-18 17:47:12 -03:00
return 0 ;
}
2005-06-23 22:02:35 -07:00
return - EIO ;
}
2006-09-30 06:53:48 -03:00
static int digitv_tuner_attach ( struct dvb_usb_adapter * adap )
2005-07-07 17:58:13 -07:00
{
2007-06-02 16:30:46 -03:00
struct digitv_state * st = adap - > dev - > priv ;
2011-09-06 09:31:57 -03:00
if ( ! dvb_attach ( dvb_pll_attach , adap - > fe_adap [ 0 ] . fe , 0x60 , NULL , DVB_PLL_TDED4 ) )
2007-06-02 16:30:46 -03:00
return - ENODEV ;
if ( st - > is_nxt6000 )
2011-09-06 09:31:57 -03:00
adap - > fe_adap [ 0 ] . fe - > ops . tuner_ops . set_params = digitv_nxt6000_tuner_set_params ;
2007-06-02 16:30:46 -03:00
2005-07-07 17:58:13 -07:00
return 0 ;
}
[media] rc: Name RC keymap tables as rc_map_table
Remote keytables had different names all over the place. Part of the fault
is due to a bad naming when rc subsystem was created, but there were lots
of old names that were still here.
Use a common standard for everything.
Patch generated by this script:
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_scancode,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_codes_,rc_map_,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_key_map,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_map_table_size,rc_map_size,g <$i >a && mv a $i; done
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2010-11-17 15:46:09 -03:00
static struct rc_map_table rc_map_digitv_table [ ] = {
2009-08-29 15:19:31 -03:00
{ 0x5f55 , KEY_0 } ,
{ 0x6f55 , KEY_1 } ,
{ 0x9f55 , KEY_2 } ,
{ 0xaf55 , KEY_3 } ,
{ 0x5f56 , KEY_4 } ,
{ 0x6f56 , KEY_5 } ,
{ 0x9f56 , KEY_6 } ,
{ 0xaf56 , KEY_7 } ,
{ 0x5f59 , KEY_8 } ,
{ 0x6f59 , KEY_9 } ,
{ 0x9f59 , KEY_TV } ,
{ 0xaf59 , KEY_AUX } ,
{ 0x5f5a , KEY_DVD } ,
{ 0x6f5a , KEY_POWER } ,
2011-01-24 12:18:36 -03:00
{ 0x9f5a , KEY_CAMERA } , /* labelled 'Picture' */
2009-08-29 15:19:31 -03:00
{ 0xaf5a , KEY_AUDIO } ,
{ 0x5f65 , KEY_INFO } ,
{ 0x6f65 , KEY_F13 } , /* 16:9 */
{ 0x9f65 , KEY_F14 } , /* 14:9 */
{ 0xaf65 , KEY_EPG } ,
{ 0x5f66 , KEY_EXIT } ,
{ 0x6f66 , KEY_MENU } ,
{ 0x9f66 , KEY_UP } ,
{ 0xaf66 , KEY_DOWN } ,
{ 0x5f69 , KEY_LEFT } ,
{ 0x6f69 , KEY_RIGHT } ,
{ 0x9f69 , KEY_ENTER } ,
{ 0xaf69 , KEY_CHANNELUP } ,
{ 0x5f6a , KEY_CHANNELDOWN } ,
{ 0x6f6a , KEY_VOLUMEUP } ,
{ 0x9f6a , KEY_VOLUMEDOWN } ,
{ 0xaf6a , KEY_RED } ,
{ 0x5f95 , KEY_GREEN } ,
{ 0x6f95 , KEY_YELLOW } ,
{ 0x9f95 , KEY_BLUE } ,
{ 0xaf95 , KEY_SUBTITLE } ,
{ 0x5f96 , KEY_F15 } , /* AD */
{ 0x6f96 , KEY_TEXT } ,
{ 0x9f96 , KEY_MUTE } ,
{ 0xaf96 , KEY_REWIND } ,
{ 0x5f99 , KEY_STOP } ,
{ 0x6f99 , KEY_PLAY } ,
{ 0x9f99 , KEY_FASTFORWARD } ,
{ 0xaf99 , KEY_F16 } , /* chapter */
{ 0x5f9a , KEY_PAUSE } ,
{ 0x6f9a , KEY_PLAY } ,
{ 0x9f9a , KEY_RECORD } ,
{ 0xaf9a , KEY_F17 } , /* picture in picture */
{ 0x5fa5 , KEY_KPPLUS } , /* zoom in */
{ 0x6fa5 , KEY_KPMINUS } , /* zoom out */
{ 0x9fa5 , KEY_F18 } , /* capture */
{ 0xafa5 , KEY_F19 } , /* web */
{ 0x5fa6 , KEY_EMAIL } ,
{ 0x6fa6 , KEY_PHONE } ,
{ 0x9fa6 , KEY_PC } ,
2005-06-23 22:02:35 -07:00
} ;
2005-12-01 00:51:53 -08:00
static int digitv_rc_query ( struct dvb_usb_device * d , u32 * event , int * state )
2005-06-23 22:02:35 -07:00
{
2006-09-10 12:05:50 -03:00
int i ;
2005-06-23 22:02:35 -07:00
u8 key [ 5 ] ;
2006-09-10 12:05:50 -03:00
u8 b [ 4 ] = { 0 } ;
* event = 0 ;
* state = REMOTE_NO_KEY_PRESSED ;
2005-06-23 22:02:35 -07:00
digitv_ctrl_msg ( d , USB_READ_REMOTE , 0 , NULL , 0 , & key [ 1 ] , 4 ) ;
2006-09-10 12:05:50 -03:00
/* Tell the device we've read the remote. Not sure how necessary
this is , but the Nebula SDK does it . */
digitv_ctrl_msg ( d , USB_WRITE_REMOTE , 0 , b , 4 , NULL , 0 ) ;
/* if something is inside the buffer, simulate key press */
2005-06-23 22:02:35 -07:00
if ( key [ 1 ] ! = 0 )
2006-09-10 12:05:50 -03:00
{
[media] rc: Name RC keymap tables as rc_map_table
Remote keytables had different names all over the place. Part of the fault
is due to a bad naming when rc subsystem was created, but there were lots
of old names that were still here.
Use a common standard for everything.
Patch generated by this script:
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_scancode,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_codes_,rc_map_,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_key_map,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_map_table_size,rc_map_size,g <$i >a && mv a $i; done
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2010-11-17 15:46:09 -03:00
for ( i = 0 ; i < d - > props . rc . legacy . rc_map_size ; i + + ) {
if ( rc5_custom ( & d - > props . rc . legacy . rc_map_table [ i ] ) = = key [ 1 ] & &
rc5_data ( & d - > props . rc . legacy . rc_map_table [ i ] ) = = key [ 2 ] ) {
* event = d - > props . rc . legacy . rc_map_table [ i ] . keycode ;
2006-09-10 12:05:50 -03:00
* state = REMOTE_KEY_PRESSED ;
return 0 ;
}
}
}
2005-06-23 22:02:35 -07:00
if ( key [ 0 ] ! = 0 )
2012-09-26 09:55:14 -03:00
deb_rc ( " key: %*ph \n " , 5 , key ) ;
2005-06-23 22:02:35 -07:00
return 0 ;
}
/* DVB USB Driver stuff */
2006-09-30 06:53:48 -03:00
static struct dvb_usb_device_properties digitv_properties ;
2005-06-23 22:02:35 -07:00
static int digitv_probe ( struct usb_interface * intf ,
const struct usb_device_id * id )
{
2005-09-09 13:02:48 -07:00
struct dvb_usb_device * d ;
2008-04-09 19:13:13 -03:00
int ret = dvb_usb_device_init ( intf , & digitv_properties , THIS_MODULE , & d ,
adapter_nr ) ;
if ( ret = = 0 ) {
2005-09-09 13:02:48 -07:00
u8 b [ 4 ] = { 0 } ;
2006-02-07 06:49:12 -02:00
if ( d ! = NULL ) { /* do that only when the firmware is loaded */
b [ 0 ] = 1 ;
digitv_ctrl_msg ( d , USB_WRITE_REMOTE_TYPE , 0 , b , 4 , NULL , 0 ) ;
2005-09-09 13:02:48 -07:00
2006-02-07 06:49:12 -02:00
b [ 0 ] = 0 ;
digitv_ctrl_msg ( d , USB_WRITE_REMOTE , 0 , b , 4 , NULL , 0 ) ;
}
2005-09-09 13:02:48 -07:00
}
return ret ;
2005-06-23 22:02:35 -07:00
}
static struct usb_device_id digitv_table [ ] = {
{ USB_DEVICE ( USB_VID_ANCHOR , USB_PID_NEBULA_DIGITV ) } ,
{ } /* Terminating entry */
} ;
MODULE_DEVICE_TABLE ( usb , digitv_table ) ;
2006-09-30 06:53:48 -03:00
static struct dvb_usb_device_properties digitv_properties = {
2005-06-23 22:02:35 -07:00
. caps = DVB_USB_IS_AN_I2C_ADAPTER ,
. usb_ctrl = CYPRESS_FX2 ,
2006-02-07 06:49:12 -02:00
. firmware = " dvb-usb-digitv-02.fw " ,
2005-06-23 22:02:35 -07:00
2007-06-02 16:30:46 -03:00
. size_of_priv = sizeof ( struct digitv_state ) ,
2006-09-30 06:53:48 -03:00
. num_adapters = 1 ,
. adapter = {
{
2011-09-06 09:31:57 -03:00
. num_frontends = 1 ,
. fe = { {
2006-10-13 11:34:46 -03:00
. frontend_attach = digitv_frontend_attach ,
. tuner_attach = digitv_tuner_attach ,
2005-06-23 22:02:35 -07:00
2006-10-13 11:34:46 -03:00
/* parameter for the MPEG2-data transfer */
2006-09-30 06:53:48 -03:00
. stream = {
. type = USB_BULK ,
2006-10-13 11:34:46 -03:00
. count = 7 ,
. endpoint = 0x02 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 09:31:57 -03:00
} } ,
2006-09-30 06:53:48 -03:00
}
} ,
. identify_state = digitv_identify_state ,
2010-07-31 18:04:09 -03:00
. rc . legacy = {
. rc_interval = 1000 ,
[media] rc: Name RC keymap tables as rc_map_table
Remote keytables had different names all over the place. Part of the fault
is due to a bad naming when rc subsystem was created, but there were lots
of old names that were still here.
Use a common standard for everything.
Patch generated by this script:
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_scancode,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,ir_codes_,rc_map_,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_key_map,rc_map_table,g <$i >a && mv a $i; done
for i in `find drivers/staging -type f -name *.[ch]` `find include/media -type f -name *.[ch]` `find drivers/media -type f -name *.[ch]`; do sed s,rc_map_table_size,rc_map_size,g <$i >a && mv a $i; done
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2010-11-17 15:46:09 -03:00
. rc_map_table = rc_map_digitv_table ,
. rc_map_size = ARRAY_SIZE ( rc_map_digitv_table ) ,
2010-07-31 18:04:09 -03:00
. rc_query = digitv_rc_query ,
} ,
2006-09-30 06:53:48 -03:00
. i2c_algo = & digitv_i2c_algo ,
. generic_bulk_ctrl_endpoint = 0x01 ,
2005-06-23 22:02:35 -07:00
2005-07-07 17:58:13 -07:00
. num_device_descs = 1 ,
2005-06-23 22:02:35 -07:00
. devices = {
{ " Nebula Electronics uDigiTV DVB-T USB2.0) " ,
{ & digitv_table [ 0 ] , NULL } ,
{ NULL } ,
} ,
2006-02-07 06:49:12 -02:00
{ NULL } ,
2005-06-23 22:02:35 -07:00
}
} ;
static struct usb_driver digitv_driver = {
2005-07-07 17:58:30 -07:00
. name = " dvb_usb_digitv " ,
2005-06-23 22:02:35 -07:00
. probe = digitv_probe ,
. disconnect = dvb_usb_device_exit ,
. id_table = digitv_table ,
} ;
2011-11-18 09:46:12 -08:00
module_usb_driver ( digitv_driver ) ;
2005-06-23 22:02:35 -07:00
2016-01-24 12:56:58 -02:00
MODULE_AUTHOR ( " Patrick Boettcher <patrick.boettcher@posteo.de> " ) ;
2005-06-23 22:02:35 -07:00
MODULE_DESCRIPTION ( " Driver for Nebula Electronics uDigiTV DVB-T USB2.0 " ) ;
MODULE_VERSION ( " 1.0-alpha " ) ;
MODULE_LICENSE ( " GPL " ) ;