2019-05-27 09:55:06 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-17 02:20:36 +04:00
/*
* TTUSB DEC Frontend Driver
*
* Copyright ( C ) 2003 - 2004 Alex Woods < linux - dvb @ giblets . org >
*/
2017-12-28 21:03:51 +03:00
# include <media/dvb_frontend.h>
2005-04-17 02:20:36 +04:00
# include "ttusbdecfe.h"
# define LOF_HI 10600000
# define LOF_LO 9750000
struct ttusbdecfe_state {
/* configuration settings */
const struct ttusbdecfe_config * config ;
struct dvb_frontend frontend ;
u8 hi_band ;
u8 voltage ;
} ;
2008-09-06 20:54:06 +04:00
static int ttusbdecfe_dvbs_read_status ( struct dvb_frontend * fe ,
2015-06-07 20:53:52 +03:00
enum fe_status * status )
2008-09-06 20:54:06 +04:00
{
* status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK ;
return 0 ;
}
static int ttusbdecfe_dvbt_read_status ( struct dvb_frontend * fe ,
2015-06-07 20:53:52 +03:00
enum fe_status * status )
2005-04-17 02:20:36 +04:00
{
2006-01-09 20:25:24 +03:00
struct ttusbdecfe_state * state = fe - > demodulator_priv ;
u8 b [ ] = { 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 } ;
u8 result [ 4 ] ;
int len , ret ;
* status = 0 ;
ret = state - > config - > send_command ( fe , 0x73 , sizeof ( b ) , b , & len , result ) ;
if ( ret )
return ret ;
if ( len ! = 4 ) {
2008-04-09 06:20:00 +04:00
printk ( KERN_ERR " %s: unexpected reply \n " , __func__ ) ;
2006-01-09 20:25:24 +03:00
return - EIO ;
}
switch ( result [ 3 ] ) {
case 1 : /* not tuned yet */
case 2 : /* no signal/no lock*/
break ;
case 3 : /* signal found and locked*/
* status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK ;
break ;
case 4 :
* status = FE_TIMEDOUT ;
break ;
default :
pr_info ( " %s: returned unknown value: %d \n " ,
2008-04-09 06:20:00 +04:00
__func__ , result [ 3 ] ) ;
2006-01-09 20:25:24 +03:00
return - EIO ;
}
2005-04-17 02:20:36 +04:00
return 0 ;
}
2011-12-26 23:33:34 +04:00
static int ttusbdecfe_dvbt_set_frontend ( struct dvb_frontend * fe )
2005-04-17 02:20:36 +04:00
{
2011-12-26 23:33:34 +04:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-04-17 02:20:36 +04:00
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
u8 b [ ] = { 0x00 , 0x00 , 0x00 , 0x03 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x01 ,
0x00 , 0x00 , 0x00 , 0xff ,
0x00 , 0x00 , 0x00 , 0xff } ;
2008-05-21 07:31:31 +04:00
__be32 freq = htonl ( p - > frequency / 1000 ) ;
2005-04-17 02:20:36 +04:00
memcpy ( & b [ 4 ] , & freq , sizeof ( u32 ) ) ;
state - > config - > send_command ( fe , 0x71 , sizeof ( b ) , b , NULL , NULL ) ;
return 0 ;
}
2006-01-09 20:25:24 +03:00
static int ttusbdecfe_dvbt_get_tune_settings ( struct dvb_frontend * fe ,
struct dvb_frontend_tune_settings * fesettings )
{
fesettings - > min_delay_ms = 1500 ;
/* Drift compensation makes no sense for DVB-T */
fesettings - > step_size = 0 ;
fesettings - > max_drift = 0 ;
return 0 ;
}
2011-12-26 23:33:34 +04:00
static int ttusbdecfe_dvbs_set_frontend ( struct dvb_frontend * fe )
2005-04-17 02:20:36 +04:00
{
2011-12-26 23:33:34 +04:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-04-17 02:20:36 +04:00
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
u8 b [ ] = { 0x00 , 0x00 , 0x00 , 0x01 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x01 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 } ;
2008-05-21 07:31:31 +04:00
__be32 freq ;
__be32 sym_rate ;
__be32 band ;
__be32 lnb_voltage ;
2005-04-17 02:20:36 +04:00
freq = htonl ( p - > frequency +
( state - > hi_band ? LOF_HI : LOF_LO ) ) ;
memcpy ( & b [ 4 ] , & freq , sizeof ( u32 ) ) ;
2011-12-26 23:33:34 +04:00
sym_rate = htonl ( p - > symbol_rate ) ;
2005-04-17 02:20:36 +04:00
memcpy ( & b [ 12 ] , & sym_rate , sizeof ( u32 ) ) ;
band = htonl ( state - > hi_band ? LOF_HI : LOF_LO ) ;
memcpy ( & b [ 24 ] , & band , sizeof ( u32 ) ) ;
lnb_voltage = htonl ( state - > voltage ) ;
memcpy ( & b [ 28 ] , & lnb_voltage , sizeof ( u32 ) ) ;
state - > config - > send_command ( fe , 0x71 , sizeof ( b ) , b , NULL , NULL ) ;
return 0 ;
}
static int ttusbdecfe_dvbs_diseqc_send_master_cmd ( struct dvb_frontend * fe , struct dvb_diseqc_master_cmd * cmd )
{
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
u8 b [ ] = { 0x00 , 0xff , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 } ;
2014-09-05 16:09:28 +04:00
if ( cmd - > msg_len > sizeof ( b ) - 4 )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
memcpy ( & b [ 4 ] , cmd - > msg , cmd - > msg_len ) ;
state - > config - > send_command ( fe , 0x72 ,
sizeof ( b ) - ( 6 - cmd - > msg_len ) , b ,
NULL , NULL ) ;
return 0 ;
}
2015-06-07 20:53:52 +03:00
static int ttusbdecfe_dvbs_set_tone ( struct dvb_frontend * fe ,
enum fe_sec_tone_mode tone )
2005-04-17 02:20:36 +04:00
{
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
state - > hi_band = ( SEC_TONE_ON = = tone ) ;
return 0 ;
}
2015-06-07 20:53:52 +03:00
static int ttusbdecfe_dvbs_set_voltage ( struct dvb_frontend * fe ,
enum fe_sec_voltage voltage )
2005-04-17 02:20:36 +04:00
{
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
switch ( voltage ) {
case SEC_VOLTAGE_13 :
state - > voltage = 13 ;
break ;
case SEC_VOLTAGE_18 :
state - > voltage = 18 ;
break ;
default :
return - EINVAL ;
}
return 0 ;
}
static void ttusbdecfe_release ( struct dvb_frontend * fe )
{
struct ttusbdecfe_state * state = ( struct ttusbdecfe_state * ) fe - > demodulator_priv ;
kfree ( state ) ;
}
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops ;
2005-04-17 02:20:36 +04:00
struct dvb_frontend * ttusbdecfe_dvbt_attach ( const struct ttusbdecfe_config * config )
{
struct ttusbdecfe_state * state = NULL ;
/* allocate memory for the internal state */
2006-12-13 11:35:56 +03:00
state = kmalloc ( sizeof ( struct ttusbdecfe_state ) , GFP_KERNEL ) ;
2005-07-08 04:57:52 +04:00
if ( state = = NULL )
return NULL ;
2005-04-17 02:20:36 +04:00
/* setup the state */
state - > config = config ;
/* create dvb_frontend */
2006-05-14 12:01:31 +04:00
memcpy ( & state - > frontend . ops , & ttusbdecfe_dvbt_ops , sizeof ( struct dvb_frontend_ops ) ) ;
2005-04-17 02:20:36 +04:00
state - > frontend . demodulator_priv = state ;
return & state - > frontend ;
}
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops ;
2005-04-17 02:20:36 +04:00
struct dvb_frontend * ttusbdecfe_dvbs_attach ( const struct ttusbdecfe_config * config )
{
struct ttusbdecfe_state * state = NULL ;
/* allocate memory for the internal state */
2006-12-13 11:35:56 +03:00
state = kmalloc ( sizeof ( struct ttusbdecfe_state ) , GFP_KERNEL ) ;
2005-07-08 04:57:52 +04:00
if ( state = = NULL )
return NULL ;
2005-04-17 02:20:36 +04:00
/* setup the state */
state - > config = config ;
state - > voltage = 0 ;
state - > hi_band = 0 ;
/* create dvb_frontend */
2006-05-14 12:01:31 +04:00
memcpy ( & state - > frontend . ops , & ttusbdecfe_dvbs_ops , sizeof ( struct dvb_frontend_ops ) ) ;
2005-04-17 02:20:36 +04:00
state - > frontend . demodulator_priv = state ;
return & state - > frontend ;
}
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
2011-12-26 23:33:34 +04:00
. delsys = { SYS_DVBT } ,
2005-04-17 02:20:36 +04:00
. info = {
. name = " TechnoTrend/Hauppauge DEC2000-t Frontend " ,
2018-07-06 01:59:36 +03:00
. frequency_min_hz = 51 * MHz ,
. frequency_max_hz = 858 * MHz ,
. frequency_stepsize_hz = 62500 ,
2005-04-17 02:20:36 +04:00
. caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO ,
} ,
. release = ttusbdecfe_release ,
2011-12-26 23:33:34 +04:00
. set_frontend = ttusbdecfe_dvbt_set_frontend ,
2005-04-17 02:20:36 +04:00
2006-01-09 20:25:24 +03:00
. get_tune_settings = ttusbdecfe_dvbt_get_tune_settings ,
2008-09-06 20:54:06 +04:00
. read_status = ttusbdecfe_dvbt_read_status ,
2005-04-17 02:20:36 +04:00
} ;
2016-08-10 00:32:21 +03:00
static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
2011-12-26 23:33:34 +04:00
. delsys = { SYS_DVBS } ,
2005-04-17 02:20:36 +04:00
. info = {
. name = " TechnoTrend/Hauppauge DEC3000-s Frontend " ,
2018-07-06 01:59:36 +03:00
. frequency_min_hz = 950 * MHz ,
. frequency_max_hz = 2150 * MHz ,
. frequency_stepsize_hz = 125 * kHz ,
2006-01-09 20:25:24 +03:00
. symbol_rate_min = 1000000 , /* guessed */
. symbol_rate_max = 45000000 , /* guessed */
2005-04-17 02:20:36 +04:00
. caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2006-01-09 20:25:24 +03:00
FE_CAN_QPSK
2005-04-17 02:20:36 +04:00
} ,
. release = ttusbdecfe_release ,
2011-12-26 23:33:34 +04:00
. set_frontend = ttusbdecfe_dvbs_set_frontend ,
2005-04-17 02:20:36 +04:00
2008-09-06 20:54:06 +04:00
. read_status = ttusbdecfe_dvbs_read_status ,
2005-04-17 02:20:36 +04:00
. diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd ,
. set_voltage = ttusbdecfe_dvbs_set_voltage ,
. set_tone = ttusbdecfe_dvbs_set_tone ,
} ;
MODULE_DESCRIPTION ( " TTUSB DEC DVB-T/S Demodulator driver " ) ;
MODULE_AUTHOR ( " Alex Woods/Andrew de Quincey " ) ;
MODULE_LICENSE ( " GPL " ) ;
EXPORT_SYMBOL ( ttusbdecfe_dvbt_attach ) ;
EXPORT_SYMBOL ( ttusbdecfe_dvbs_attach ) ;