2005-06-24 09:02:35 +04:00
/* DVB USB compliant Linux driver for the
* - TwinhanDTV Alpha / MagicBoxII USB2 .0 DVB - T receiver
* - DigitalNow TinyUSB2 DVB - t receiver
*
* Copyright ( C ) 2004 - 5 Patrick Boettcher ( patrick . boettcher @ desy . de )
*
* Thanks to Twinhan who kindly provided hardware and information .
*
* 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 "vp7045.h"
/* debug */
2007-11-05 20:07:06 +03:00
static int dvb_usb_vp7045_debug ;
2005-06-24 09:02:35 +04:00
module_param_named ( debug , dvb_usb_vp7045_debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " set debugging level (1=info,xfer=2,rc=4 (or-able)). " DVB_USB_DEBUG_STATUS ) ;
2008-04-10 02:13:13 +04:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2007-11-05 20:07:06 +03:00
# define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
# define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
# define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
2005-06-24 09:02:35 +04:00
int vp7045_usb_op ( struct dvb_usb_device * d , u8 cmd , u8 * out , int outlen , u8 * in , int inlen , int msec )
{
int ret = 0 ;
2011-03-21 21:33:42 +03:00
u8 * buf = d - > priv ;
2005-06-24 09:02:35 +04:00
2011-03-21 21:33:42 +03:00
buf [ 0 ] = cmd ;
2005-06-24 09:02:35 +04:00
if ( outlen > 19 )
outlen = 19 ;
if ( inlen > 11 )
inlen = 11 ;
2011-03-21 21:33:42 +03:00
ret = mutex_lock_interruptible ( & d - > usb_mutex ) ;
if ( ret )
return ret ;
2005-06-24 09:02:35 +04:00
if ( out ! = NULL & & outlen > 0 )
2011-03-21 21:33:42 +03:00
memcpy ( & buf [ 1 ] , out , outlen ) ;
2005-06-24 09:02:35 +04:00
deb_xfer ( " out buffer: " ) ;
2011-03-21 21:33:42 +03:00
debug_dump ( buf , outlen + 1 , deb_xfer ) ;
2005-06-24 09:02:35 +04:00
if ( usb_control_msg ( d - > udev ,
usb_sndctrlpipe ( d - > udev , 0 ) ,
TH_COMMAND_OUT , USB_TYPE_VENDOR | USB_DIR_OUT , 0 , 0 ,
2011-03-21 21:33:42 +03:00
buf , 20 , 2000 ) ! = 20 ) {
2005-06-24 09:02:35 +04:00
err ( " USB control message 'out' went wrong. " ) ;
ret = - EIO ;
goto unlock ;
}
msleep ( msec ) ;
if ( usb_control_msg ( d - > udev ,
usb_rcvctrlpipe ( d - > udev , 0 ) ,
TH_COMMAND_IN , USB_TYPE_VENDOR | USB_DIR_IN , 0 , 0 ,
2011-03-21 21:33:42 +03:00
buf , 12 , 2000 ) ! = 12 ) {
2005-06-24 09:02:35 +04:00
err ( " USB control message 'in' went wrong. " ) ;
ret = - EIO ;
goto unlock ;
}
deb_xfer ( " in buffer: " ) ;
2011-03-21 21:33:42 +03:00
debug_dump ( buf , 12 , deb_xfer ) ;
2005-06-24 09:02:35 +04:00
if ( in ! = NULL & & inlen > 0 )
2011-03-21 21:33:42 +03:00
memcpy ( in , & buf [ 1 ] , inlen ) ;
2005-06-24 09:02:35 +04:00
unlock :
2006-02-07 11:49:14 +03:00
mutex_unlock ( & d - > usb_mutex ) ;
2005-06-24 09:02:35 +04:00
return ret ;
}
u8 vp7045_read_reg ( struct dvb_usb_device * d , u8 reg )
{
u8 obuf [ 2 ] = { 0 } , v ;
obuf [ 1 ] = reg ;
vp7045_usb_op ( d , TUNER_REG_READ , obuf , 2 , & v , 1 , 30 ) ;
return v ;
}
static int vp7045_power_ctrl ( struct dvb_usb_device * d , int onoff )
{
u8 v = onoff ;
return vp7045_usb_op ( d , SET_TUNER_POWER , & v , 1 , NULL , 0 , 150 ) ;
}
/* remote control stuff */
/* The keymapping struct. Somehow this should be loaded to the driver, but
* currently it is hardcoded . */
[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 21:46:09 +03:00
static struct rc_map_table rc_map_vp7045_table [ ] = {
2009-08-29 22:19:31 +04:00
{ 0x0016 , KEY_POWER } ,
{ 0x0010 , KEY_MUTE } ,
{ 0x0003 , KEY_1 } ,
{ 0x0001 , KEY_2 } ,
{ 0x0006 , KEY_3 } ,
{ 0x0009 , KEY_4 } ,
{ 0x001d , KEY_5 } ,
{ 0x001f , KEY_6 } ,
{ 0x000d , KEY_7 } ,
{ 0x0019 , KEY_8 } ,
{ 0x001b , KEY_9 } ,
{ 0x0015 , KEY_0 } ,
{ 0x0005 , KEY_CHANNELUP } ,
{ 0x0002 , KEY_CHANNELDOWN } ,
{ 0x001e , KEY_VOLUMEUP } ,
{ 0x000a , KEY_VOLUMEDOWN } ,
{ 0x0011 , KEY_RECORD } ,
{ 0x0017 , KEY_FAVORITES } , /* Heart symbol - Channel list. */
{ 0x0014 , KEY_PLAY } ,
{ 0x001a , KEY_STOP } ,
{ 0x0040 , KEY_REWIND } ,
{ 0x0012 , KEY_FASTFORWARD } ,
{ 0x000e , KEY_PREVIOUS } , /* Recall - Previous channel. */
{ 0x004c , KEY_PAUSE } ,
{ 0x004d , KEY_SCREEN } , /* Full screen mode. */
{ 0x0054 , KEY_AUDIO } , /* MTS - Switch to secondary audio. */
{ 0x000c , KEY_CANCEL } , /* Cancel */
{ 0x001c , KEY_EPG } , /* EPG */
{ 0x0000 , KEY_TAB } , /* Tab */
{ 0x0048 , KEY_INFO } , /* Preview */
{ 0x0004 , KEY_LIST } , /* RecordList */
{ 0x000f , KEY_TEXT } , /* Teletext */
{ 0x0041 , KEY_PREVIOUSSONG } ,
{ 0x0042 , KEY_NEXTSONG } ,
{ 0x004b , KEY_UP } ,
{ 0x0051 , KEY_DOWN } ,
{ 0x004e , KEY_LEFT } ,
{ 0x0052 , KEY_RIGHT } ,
{ 0x004f , KEY_ENTER } ,
{ 0x0013 , KEY_CANCEL } ,
{ 0x004a , KEY_CLEAR } ,
{ 0x0054 , KEY_PRINT } , /* Capture */
{ 0x0043 , KEY_SUBTITLE } , /* Subtitle/CC */
{ 0x0008 , KEY_VIDEO } , /* A/V */
{ 0x0007 , KEY_SLEEP } , /* Hibernate */
{ 0x0045 , KEY_ZOOM } , /* Zoom+ */
{ 0x0018 , KEY_RED } ,
{ 0x0053 , KEY_GREEN } ,
{ 0x005e , KEY_YELLOW } ,
{ 0x005f , KEY_BLUE }
2005-06-24 09:02:35 +04:00
} ;
2005-07-13 00:58:38 +04:00
static int vp7045_rc_query ( struct dvb_usb_device * d , u32 * event , int * state )
2005-06-24 09:02:35 +04:00
{
u8 key ;
int i ;
vp7045_usb_op ( d , RC_VAL_READ , NULL , 0 , & key , 1 , 20 ) ;
deb_rc ( " remote query key: %x %d \n " , key , key ) ;
if ( key = = 0x44 ) {
* state = REMOTE_NO_KEY_PRESSED ;
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 21:46:09 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( rc_map_vp7045_table ) ; i + + )
if ( rc5_data ( & rc_map_vp7045_table [ i ] ) = = key ) {
2005-06-24 09:02:35 +04:00
* state = REMOTE_KEY_PRESSED ;
[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 21:46:09 +03:00
* event = rc_map_vp7045_table [ i ] . keycode ;
2005-06-24 09:02:35 +04:00
break ;
}
return 0 ;
}
static int vp7045_read_eeprom ( struct dvb_usb_device * d , u8 * buf , int len , int offset )
{
int i = 0 ;
u8 v , br [ 2 ] ;
for ( i = 0 ; i < len ; i + + ) {
v = offset + i ;
vp7045_usb_op ( d , GET_EE_VALUE , & v , 1 , br , 2 , 5 ) ;
buf [ i ] = br [ 1 ] ;
}
deb_info ( " VP7045 EEPROM read (offs: %d, len: %d) : " , offset , i ) ;
debug_dump ( buf , i , deb_info ) ;
return 0 ;
}
static int vp7045_read_mac_addr ( struct dvb_usb_device * d , u8 mac [ 6 ] )
{
return vp7045_read_eeprom ( d , mac , 6 , MAC_0_ADDR ) ;
}
2006-09-30 13:53:48 +04:00
static int vp7045_frontend_attach ( struct dvb_usb_adapter * adap )
2005-06-24 09:02:35 +04:00
{
u8 buf [ 255 ] = { 0 } ;
2006-09-30 13:53:48 +04:00
vp7045_usb_op ( adap - > dev , VENDOR_STRING_READ , NULL , 0 , buf , 20 , 0 ) ;
2005-06-24 09:02:35 +04:00
buf [ 10 ] = ' \0 ' ;
deb_info ( " firmware says: %s " , buf ) ;
2006-09-30 13:53:48 +04:00
vp7045_usb_op ( adap - > dev , PRODUCT_STRING_READ , NULL , 0 , buf , 20 , 0 ) ;
2005-06-24 09:02:35 +04:00
buf [ 10 ] = ' \0 ' ;
deb_info ( " %s " , buf ) ;
2006-09-30 13:53:48 +04:00
vp7045_usb_op ( adap - > dev , FW_VERSION_READ , NULL , 0 , buf , 20 , 0 ) ;
2005-06-24 09:02:35 +04:00
buf [ 10 ] = ' \0 ' ;
deb_info ( " v%s \n " , buf ) ;
/* Dump the EEPROM */
/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
2011-09-06 16:31:57 +04:00
adap - > fe_adap [ 0 ] . fe = vp7045_fe_attach ( adap - > dev ) ;
2005-06-24 09:02:35 +04:00
return 0 ;
}
2006-09-30 13:53:48 +04:00
static struct dvb_usb_device_properties vp7045_properties ;
2005-06-24 09:02:35 +04:00
static int vp7045_usb_probe ( struct usb_interface * intf ,
const struct usb_device_id * id )
{
2011-08-10 14:05:20 +04:00
return dvb_usb_device_init ( intf , & vp7045_properties ,
THIS_MODULE , NULL , adapter_nr ) ;
2005-06-24 09:02:35 +04:00
}
static struct usb_device_id vp7045_usb_table [ ] = {
{ USB_DEVICE ( USB_VID_VISIONPLUS , USB_PID_TWINHAN_VP7045_COLD ) } ,
{ USB_DEVICE ( USB_VID_VISIONPLUS , USB_PID_TWINHAN_VP7045_WARM ) } ,
{ USB_DEVICE ( USB_VID_VISIONPLUS , USB_PID_DNTV_TINYUSB2_COLD ) } ,
{ USB_DEVICE ( USB_VID_VISIONPLUS , USB_PID_DNTV_TINYUSB2_WARM ) } ,
{ 0 } ,
} ;
MODULE_DEVICE_TABLE ( usb , vp7045_usb_table ) ;
2006-09-30 13:53:48 +04:00
static struct dvb_usb_device_properties vp7045_properties = {
2005-06-24 09:02:35 +04:00
. usb_ctrl = CYPRESS_FX2 ,
. firmware = " dvb-usb-vp7045-01.fw " ,
2011-08-10 14:05:20 +04:00
. size_of_priv = 20 ,
2005-06-24 09:02:35 +04:00
2006-09-30 13:53:48 +04:00
. num_adapters = 1 ,
. adapter = {
{
2011-09-06 16:31:57 +04:00
. num_frontends = 1 ,
. fe = { {
2006-10-13 18:34:46 +04:00
. frontend_attach = vp7045_frontend_attach ,
/* parameter for the MPEG2-data transfer */
2006-09-30 13:53:48 +04:00
. stream = {
. type = USB_BULK ,
2006-10-13 18:34:46 +04:00
. count = 7 ,
. endpoint = 0x02 ,
. u = {
. bulk = {
. buffersize = 4096 ,
}
}
} ,
2011-09-06 16:31:57 +04:00
} } ,
2006-09-30 13:53:48 +04:00
}
} ,
. power_ctrl = vp7045_power_ctrl ,
. read_mac_address = vp7045_read_mac_addr ,
2010-08-01 01:04:09 +04:00
. rc . legacy = {
. rc_interval = 400 ,
[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 21:46:09 +03:00
. rc_map_table = rc_map_vp7045_table ,
. rc_map_size = ARRAY_SIZE ( rc_map_vp7045_table ) ,
2010-08-01 01:04:09 +04:00
. rc_query = vp7045_rc_query ,
} ,
2005-06-24 09:02:35 +04:00
. num_device_descs = 2 ,
. devices = {
{ . name = " Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II) " ,
. cold_ids = { & vp7045_usb_table [ 0 ] , NULL } ,
. warm_ids = { & vp7045_usb_table [ 1 ] , NULL } ,
} ,
{ . name = " DigitalNow TinyUSB 2 DVB-t Receiver " ,
. cold_ids = { & vp7045_usb_table [ 2 ] , NULL } ,
. warm_ids = { & vp7045_usb_table [ 3 ] , NULL } ,
} ,
2006-02-01 14:02:50 +03:00
{ NULL } ,
2005-06-24 09:02:35 +04:00
}
} ;
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver vp7045_usb_driver = {
2005-07-08 04:58:30 +04:00
. name = " dvb_usb_vp7045 " ,
2005-09-10 00:02:50 +04:00
. probe = vp7045_usb_probe ,
2011-08-10 14:05:20 +04:00
. disconnect = dvb_usb_device_exit ,
2005-09-10 00:02:50 +04:00
. id_table = vp7045_usb_table ,
2005-06-24 09:02:35 +04:00
} ;
2011-11-18 21:46:12 +04:00
module_usb_driver ( vp7045_usb_driver ) ;
2005-06-24 09:02:35 +04:00
MODULE_AUTHOR ( " Patrick Boettcher <patrick.boettcher@desy.de> " ) ;
MODULE_DESCRIPTION ( " Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0 " ) ;
MODULE_VERSION ( " 1.0 " ) ;
MODULE_LICENSE ( " GPL " ) ;