2019-05-23 11:14:50 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-16 15:20:36 -07:00
/*
* budget - ci . c : driver for the SAA7146 based Budget DVB cards
*
* Compiled from various sources by Michael Hunold < michael @ mihu . de >
*
* msp430 IR support contributed by Jack Thomasson < jkt @ Helius . COM >
* partially based on the Siemens DVB driver by Ralph + Marcus Metzler
*
* CI interface support ( c ) 2004 Andrew de Quincey < adq_dvb @ lidskialf . net >
*
2015-12-04 10:38:59 -02:00
* the project ' s page is at https : //linuxtv.org
2005-04-16 15:20:36 -07:00
*/
# include <linux/module.h>
# include <linux/errno.h>
# include <linux/slab.h>
# include <linux/interrupt.h>
# include <linux/spinlock.h>
2010-11-17 13:28:38 -03:00
# include <media/rc-core.h>
2005-04-16 15:20:36 -07:00
2007-01-30 23:25:46 -03:00
# include "budget.h"
2017-12-28 13:03:51 -05:00
# include <media/dvb_ca_en50221.h>
2005-04-16 15:20:36 -07:00
# include "stv0299.h"
2005-09-09 13:03:07 -07:00
# include "stv0297.h"
2005-04-16 15:20:36 -07:00
# include "tda1004x.h"
2008-10-23 18:16:40 -03:00
# include "stb0899_drv.h"
# include "stb0899_reg.h"
2008-01-25 18:20:48 -03:00
# include "stb0899_cfg.h"
2008-10-23 18:16:40 -03:00
# include "stb6100.h"
2008-01-25 18:20:48 -03:00
# include "stb6100_cfg.h"
2006-02-28 09:52:44 -03:00
# include "lnbp21.h"
# include "bsbe1.h"
2006-03-16 11:22:47 -03:00
# include "bsru6.h"
2008-06-15 17:25:46 -03:00
# include "tda1002x.h"
# include "tda827x.h"
2011-03-29 17:37:00 -03:00
# include "bsbe1-d01a.h"
2005-04-16 15:20:36 -07:00
2010-03-12 21:18:14 -03:00
# define MODULE_NAME "budget_ci"
2006-10-27 20:56:51 -03:00
/*
* Regarding DEBIADDR_IR :
* Some CI modules hang if random addresses are read .
* Using address 0x4000 for the IR read means that we
* use the same address as for CI version , which should
* be a safe default .
*/
# define DEBIADDR_IR 0x4000
2005-04-16 15:20:36 -07:00
# define DEBIADDR_CICONTROL 0x0000
# define DEBIADDR_CIVERSION 0x4000
# define DEBIADDR_IO 0x1000
# define DEBIADDR_ATTR 0x3000
# define CICONTROL_RESET 0x01
# define CICONTROL_ENABLETS 0x02
# define CICONTROL_CAMDETECT 0x08
# define DEBICICTL 0x00420000
# define DEBICICAM 0x02420000
# define SLOTSTATUS_NONE 1
# define SLOTSTATUS_PRESENT 2
# define SLOTSTATUS_RESET 4
# define SLOTSTATUS_READY 8
# define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
2006-12-02 21:16:05 -02:00
/* RC5 device wildcard */
# define IR_DEVICE_ANY 255
static int rc5_device = - 1 ;
module_param ( rc5_device , int , 0644 ) ;
MODULE_PARM_DESC ( rc5_device , " only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect) " ) ;
2008-04-22 14:41:48 -03:00
static int ir_debug ;
2006-12-02 21:16:05 -02:00
module_param ( ir_debug , int , 0644 ) ;
MODULE_PARM_DESC ( ir_debug , " enable debugging information for IR decoding " ) ;
2008-09-21 20:50:11 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2006-12-02 21:16:05 -02:00
struct budget_ci_ir {
2010-10-29 16:08:23 -03:00
struct rc_dev * dev ;
2006-12-02 21:16:05 -02:00
struct tasklet_struct msp430_irq_tasklet ;
char name [ 72 ] ; /* 40 + 32 for (struct saa7146_dev).name */
2006-12-02 21:16:05 -02:00
char phys [ 32 ] ;
2006-12-02 21:16:05 -02:00
int rc5_device ;
2007-04-27 12:31:22 -03:00
u32 ir_key ;
bool have_command ;
2011-01-24 12:18:48 -03:00
bool full_rc5 ; /* Outputs a full RC5 code */
2006-12-02 21:16:05 -02:00
} ;
2005-04-16 15:20:36 -07:00
struct budget_ci {
struct budget budget ;
struct tasklet_struct ciintf_irq_tasklet ;
int slot_status ;
2006-04-05 14:09:45 -03:00
int ci_irq ;
2005-04-16 15:20:36 -07:00
struct dvb_ca_en50221 ca ;
2006-12-02 21:16:05 -02:00
struct budget_ci_ir ir ;
2005-07-07 17:57:54 -07:00
u8 tuner_pll_address ; /* used for philips_tdm1316l configs */
2005-04-16 15:20:36 -07:00
} ;
2006-12-02 21:16:05 -02:00
static void msp430_ir_interrupt ( unsigned long data )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) data ;
2010-10-29 16:08:23 -03:00
struct rc_dev * dev = budget_ci - > ir . dev ;
2006-12-02 21:16:05 -02:00
u32 command = ttpci_budget_debiread ( & budget_ci - > budget , DEBINOSWAP , DEBIADDR_IR , 2 , 1 , 0 ) > > 8 ;
2006-12-02 21:16:05 -02:00
/*
* The msp430 chip can generate two different bytes , command and device
*
* type1 : X1CCCCCC , C = command bits ( 0 - 63 )
* type2 : X0TDDDDD , D = device bits ( 0 - 31 ) , T = RC5 toggle bit
*
2007-02-13 09:39:58 -03:00
* Each signal from the remote control can generate one or more command
* bytes and one or more device bytes . For the repeated bytes , the
* highest bit ( X ) is set . The first command byte is always generated
* before the first device byte . Other than that , no specific order
2007-04-27 12:31:22 -03:00
* seems to apply . To make life interesting , bytes can also be lost .
2007-02-13 09:39:58 -03:00
*
* Only when we have a command and device byte , a keypress is
* generated .
2006-12-02 21:16:05 -02:00
*/
2007-02-13 09:39:58 -03:00
if ( ir_debug )
printk ( " budget_ci: received byte 0x%02x \n " , command ) ;
2007-04-27 12:31:22 -03:00
/* Remove repeat bit, we use every command */
command = command & 0x7f ;
2007-02-13 09:39:58 -03:00
2006-12-02 21:16:05 -02:00
/* Is this a RC5 command byte? */
2006-12-02 21:16:05 -02:00
if ( command & 0x40 ) {
2007-04-27 12:31:22 -03:00
budget_ci - > ir . have_command = true ;
budget_ci - > ir . ir_key = command & 0x3f ;
2006-12-02 21:16:05 -02:00
return ;
}
2006-12-02 21:16:05 -02:00
2006-12-02 21:16:05 -02:00
/* It's a RC5 device byte */
2007-04-27 12:31:22 -03:00
if ( ! budget_ci - > ir . have_command )
2007-02-13 09:39:58 -03:00
return ;
2007-04-27 12:31:22 -03:00
budget_ci - > ir . have_command = false ;
2006-12-02 21:16:05 -02:00
2007-04-27 12:31:22 -03:00
if ( budget_ci - > ir . rc5_device ! = IR_DEVICE_ANY & &
budget_ci - > ir . rc5_device ! = ( command & 0x1f ) )
2006-12-02 21:16:05 -02:00
return ;
2006-12-02 21:16:05 -02:00
2011-01-24 12:18:48 -03:00
if ( budget_ci - > ir . full_rc5 ) {
2017-08-07 16:20:58 -04:00
rc_keydown ( dev , RC_PROTO_RC5 ,
2014-04-03 20:31:30 -03:00
RC_SCANCODE_RC5 ( budget_ci - > ir . rc5_device , budget_ci - > ir . ir_key ) ,
! ! ( command & 0x20 ) ) ;
2011-01-24 12:18:48 -03:00
return ;
}
/* FIXME: We should generate complete scancodes for all devices */
2017-08-07 16:20:58 -04:00
rc_keydown ( dev , RC_PROTO_UNKNOWN , budget_ci - > ir . ir_key ,
! ! ( command & 0x20 ) ) ;
2006-12-02 21:16:05 -02:00
}
2005-04-16 15:20:36 -07:00
static int msp430_ir_init ( struct budget_ci * budget_ci )
{
struct saa7146_dev * saa = budget_ci - > budget . dev ;
2010-10-29 16:08:23 -03:00
struct rc_dev * dev ;
2006-12-02 21:16:05 -02:00
int error ;
2009-12-11 11:20:59 -03:00
2016-12-16 06:50:58 -02:00
dev = rc_allocate_device ( RC_DRIVER_SCANCODE ) ;
2010-10-29 16:08:23 -03:00
if ( ! dev ) {
2006-12-02 21:16:05 -02:00
printk ( KERN_ERR " budget_ci: IR interface initialisation failed \n " ) ;
2009-12-11 11:20:59 -03:00
return - ENOMEM ;
2006-12-02 21:16:05 -02:00
}
2005-04-16 15:20:36 -07:00
2006-12-02 21:16:05 -02:00
snprintf ( budget_ci - > ir . name , sizeof ( budget_ci - > ir . name ) ,
" Budget-CI dvb ir receiver %s " , saa - > name ) ;
2006-12-02 21:16:05 -02:00
snprintf ( budget_ci - > ir . phys , sizeof ( budget_ci - > ir . phys ) ,
" pci-%s/ir0 " , pci_name ( saa - > pci ) ) ;
2010-10-29 16:08:23 -03:00
dev - > driver_name = MODULE_NAME ;
2017-07-01 12:13:19 -04:00
dev - > device_name = budget_ci - > ir . name ;
2010-10-29 16:08:23 -03:00
dev - > input_phys = budget_ci - > ir . phys ;
dev - > input_id . bustype = BUS_PCI ;
dev - > input_id . version = 1 ;
2006-12-02 21:16:05 -02:00
if ( saa - > pci - > subsystem_vendor ) {
2010-10-29 16:08:23 -03:00
dev - > input_id . vendor = saa - > pci - > subsystem_vendor ;
dev - > input_id . product = saa - > pci - > subsystem_device ;
2006-12-02 21:16:05 -02:00
} else {
2010-10-29 16:08:23 -03:00
dev - > input_id . vendor = saa - > pci - > vendor ;
dev - > input_id . product = saa - > pci - > device ;
2006-12-02 21:16:05 -02:00
}
2010-10-29 16:08:23 -03:00
dev - > dev . parent = & saa - > pci - > dev ;
2006-12-02 21:16:05 -02:00
2009-12-11 11:20:59 -03:00
if ( rc5_device < 0 )
budget_ci - > ir . rc5_device = IR_DEVICE_ANY ;
else
budget_ci - > ir . rc5_device = rc5_device ;
2006-12-02 21:16:05 -02:00
/* Select keymap and address */
2006-12-02 21:16:05 -02:00
switch ( budget_ci - > budget . dev - > pci - > subsystem_device ) {
case 0x100c :
case 0x100f :
case 0x1011 :
case 0x1012 :
/* The hauppauge keymap is a superset of these remotes */
2011-01-24 12:18:48 -03:00
dev - > map_name = RC_MAP_HAUPPAUGE ;
budget_ci - > ir . full_rc5 = true ;
2006-12-02 21:16:05 -02:00
if ( rc5_device < 0 )
budget_ci - > ir . rc5_device = 0x1f ;
2006-12-02 21:16:05 -02:00
break ;
2007-01-12 14:06:21 -03:00
case 0x1010 :
2007-09-17 22:17:12 -03:00
case 0x1017 :
2010-05-18 04:26:17 -03:00
case 0x1019 :
2008-06-19 23:36:45 -03:00
case 0x101a :
2011-03-29 17:37:00 -03:00
case 0x101b :
2007-01-12 14:06:21 -03:00
/* for the Technotrend 1500 bundled remote */
2010-10-29 16:08:23 -03:00
dev - > map_name = RC_MAP_TT_1500 ;
2007-01-12 14:06:21 -03:00
break ;
2006-12-02 21:16:05 -02:00
default :
/* unknown remote */
2010-10-29 16:08:23 -03:00
dev - > map_name = RC_MAP_BUDGET_CI_OLD ;
2006-12-02 21:16:05 -02:00
break ;
}
2011-12-17 09:03:29 -02:00
if ( ! budget_ci - > ir . full_rc5 )
2014-04-03 20:32:26 -03:00
dev - > scancode_mask = 0xff ;
2006-12-02 21:16:05 -02:00
2010-10-29 16:08:23 -03:00
error = rc_register_device ( dev ) ;
2006-12-02 21:16:05 -02:00
if ( error ) {
printk ( KERN_ERR " budget_ci: could not init driver for IR device (code %d) \n " , error ) ;
2010-10-29 16:08:23 -03:00
rc_free_device ( dev ) ;
2009-12-11 11:20:59 -03:00
return error ;
2006-11-20 10:23:04 -03:00
}
2005-04-16 15:20:36 -07:00
2010-10-29 16:08:23 -03:00
budget_ci - > ir . dev = dev ;
2007-04-27 12:31:22 -03:00
2006-12-02 21:16:05 -02:00
tasklet_init ( & budget_ci - > ir . msp430_irq_tasklet , msp430_ir_interrupt ,
( unsigned long ) budget_ci ) ;
2006-12-03 10:49:47 -03:00
SAA7146_IER_ENABLE ( saa , MASK_06 ) ;
2005-04-16 15:20:36 -07:00
saa7146_setgpio ( saa , 3 , SAA7146_GPIO_IRQHI ) ;
return 0 ;
}
static void msp430_ir_deinit ( struct budget_ci * budget_ci )
{
struct saa7146_dev * saa = budget_ci - > budget . dev ;
2006-12-03 10:49:47 -03:00
SAA7146_IER_DISABLE ( saa , MASK_06 ) ;
2005-04-16 15:20:36 -07:00
saa7146_setgpio ( saa , 3 , SAA7146_GPIO_INPUT ) ;
2006-12-02 21:16:05 -02:00
tasklet_kill ( & budget_ci - > ir . msp430_irq_tasklet ) ;
2005-04-16 15:20:36 -07:00
2010-10-29 16:08:23 -03:00
rc_unregister_device ( budget_ci - > ir . dev ) ;
2005-04-16 15:20:36 -07:00
}
static int ciintf_read_attribute_mem ( struct dvb_ca_en50221 * ca , int slot , int address )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
if ( slot ! = 0 )
return - EINVAL ;
return ttpci_budget_debiread ( & budget_ci - > budget , DEBICICAM ,
DEBIADDR_ATTR | ( address & 0xfff ) , 1 , 1 , 0 ) ;
}
static int ciintf_write_attribute_mem ( struct dvb_ca_en50221 * ca , int slot , int address , u8 value )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
if ( slot ! = 0 )
return - EINVAL ;
return ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICAM ,
DEBIADDR_ATTR | ( address & 0xfff ) , 1 , value , 1 , 0 ) ;
}
static int ciintf_read_cam_control ( struct dvb_ca_en50221 * ca , int slot , u8 address )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
if ( slot ! = 0 )
return - EINVAL ;
return ttpci_budget_debiread ( & budget_ci - > budget , DEBICICAM ,
DEBIADDR_IO | ( address & 3 ) , 1 , 1 , 0 ) ;
}
static int ciintf_write_cam_control ( struct dvb_ca_en50221 * ca , int slot , u8 address , u8 value )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
if ( slot ! = 0 )
return - EINVAL ;
return ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICAM ,
DEBIADDR_IO | ( address & 3 ) , 1 , value , 1 , 0 ) ;
}
static int ciintf_slot_reset ( struct dvb_ca_en50221 * ca , int slot )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
struct saa7146_dev * saa = budget_ci - > budget . dev ;
if ( slot ! = 0 )
return - EINVAL ;
2006-04-05 14:09:45 -03:00
if ( budget_ci - > ci_irq ) {
// trigger on RISING edge during reset so we know when READY is re-asserted
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_IRQHI ) ;
}
2005-04-16 15:20:36 -07:00
budget_ci - > slot_status = SLOTSTATUS_RESET ;
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 0 , 1 , 0 ) ;
msleep ( 1 ) ;
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 ,
CICONTROL_RESET , 1 , 0 ) ;
saa7146_setgpio ( saa , 1 , SAA7146_GPIO_OUTHI ) ;
ttpci_budget_set_video_port ( saa , BUDGET_VIDEO_PORTB ) ;
return 0 ;
}
static int ciintf_slot_shutdown ( struct dvb_ca_en50221 * ca , int slot )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
struct saa7146_dev * saa = budget_ci - > budget . dev ;
if ( slot ! = 0 )
return - EINVAL ;
saa7146_setgpio ( saa , 1 , SAA7146_GPIO_OUTHI ) ;
ttpci_budget_set_video_port ( saa , BUDGET_VIDEO_PORTB ) ;
return 0 ;
}
static int ciintf_slot_ts_enable ( struct dvb_ca_en50221 * ca , int slot )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
struct saa7146_dev * saa = budget_ci - > budget . dev ;
int tmp ;
if ( slot ! = 0 )
return - EINVAL ;
saa7146_setgpio ( saa , 1 , SAA7146_GPIO_OUTLO ) ;
tmp = ttpci_budget_debiread ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 1 , 0 ) ;
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 ,
tmp | CICONTROL_ENABLETS , 1 , 0 ) ;
ttpci_budget_set_video_port ( saa , BUDGET_VIDEO_PORTA ) ;
return 0 ;
}
static void ciintf_interrupt ( unsigned long data )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) data ;
struct saa7146_dev * saa = budget_ci - > budget . dev ;
unsigned int flags ;
// ensure we don't get spurious IRQs during initialisation
if ( ! budget_ci - > budget . ci_present )
return ;
// read the CAM status
flags = ttpci_budget_debiread ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 1 , 0 ) ;
if ( flags & CICONTROL_CAMDETECT ) {
// GPIO should be set to trigger on falling edge if a CAM is present
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_IRQLO ) ;
if ( budget_ci - > slot_status & SLOTSTATUS_NONE ) {
// CAM insertion IRQ
budget_ci - > slot_status = SLOTSTATUS_PRESENT ;
dvb_ca_en50221_camchange_irq ( & budget_ci - > ca , 0 ,
DVB_CA_EN50221_CAMCHANGE_INSERTED ) ;
} else if ( budget_ci - > slot_status & SLOTSTATUS_RESET ) {
// CAM ready (reset completed)
budget_ci - > slot_status = SLOTSTATUS_READY ;
dvb_ca_en50221_camready_irq ( & budget_ci - > ca , 0 ) ;
} else if ( budget_ci - > slot_status & SLOTSTATUS_READY ) {
// FR/DA IRQ
dvb_ca_en50221_frda_irq ( & budget_ci - > ca , 0 ) ;
}
} else {
// trigger on rising edge if a CAM is not present - when a CAM is inserted, we
// only want to get the IRQ when it sets READY. If we trigger on the falling edge,
// the CAM might not actually be ready yet.
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_IRQHI ) ;
// generate a CAM removal IRQ if we haven't already
if ( budget_ci - > slot_status & SLOTSTATUS_OCCUPIED ) {
// CAM removal IRQ
budget_ci - > slot_status = SLOTSTATUS_NONE ;
dvb_ca_en50221_camchange_irq ( & budget_ci - > ca , 0 ,
DVB_CA_EN50221_CAMCHANGE_REMOVED ) ;
}
}
}
2006-04-05 14:09:45 -03:00
static int ciintf_poll_slot_status ( struct dvb_ca_en50221 * ca , int slot , int open )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) ca - > data ;
unsigned int flags ;
// ensure we don't get spurious IRQs during initialisation
if ( ! budget_ci - > budget . ci_present )
return - EINVAL ;
// read the CAM status
flags = ttpci_budget_debiread ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 1 , 0 ) ;
if ( flags & CICONTROL_CAMDETECT ) {
// mark it as present if it wasn't before
if ( budget_ci - > slot_status & SLOTSTATUS_NONE ) {
budget_ci - > slot_status = SLOTSTATUS_PRESENT ;
}
// during a RESET, we check if we can read from IO memory to see when CAM is ready
if ( budget_ci - > slot_status & SLOTSTATUS_RESET ) {
if ( ciintf_read_attribute_mem ( ca , slot , 0 ) = = 0x1d ) {
budget_ci - > slot_status = SLOTSTATUS_READY ;
}
}
} else {
budget_ci - > slot_status = SLOTSTATUS_NONE ;
}
if ( budget_ci - > slot_status ! = SLOTSTATUS_NONE ) {
if ( budget_ci - > slot_status & SLOTSTATUS_READY ) {
return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY ;
}
return DVB_CA_EN50221_POLL_CAM_PRESENT ;
}
return 0 ;
}
2005-04-16 15:20:36 -07:00
static int ciintf_init ( struct budget_ci * budget_ci )
{
struct saa7146_dev * saa = budget_ci - > budget . dev ;
int flags ;
int result ;
2006-04-05 14:09:45 -03:00
int ci_version ;
int ca_flags ;
2005-04-16 15:20:36 -07:00
memset ( & budget_ci - > ca , 0 , sizeof ( struct dvb_ca_en50221 ) ) ;
// enable DEBI pins
2006-12-03 21:08:08 -03:00
saa7146_write ( saa , MC1 , MASK_27 | MASK_11 ) ;
2005-04-16 15:20:36 -07:00
// test if it is there
2006-04-05 14:09:45 -03:00
ci_version = ttpci_budget_debiread ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CIVERSION , 1 , 1 , 0 ) ;
if ( ( ci_version & 0xa0 ) ! = 0xa0 ) {
2005-04-16 15:20:36 -07:00
result = - ENODEV ;
goto error ;
}
2006-04-05 14:09:45 -03:00
2005-04-16 15:20:36 -07:00
// determine whether a CAM is present or not
flags = ttpci_budget_debiread ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 1 , 0 ) ;
budget_ci - > slot_status = SLOTSTATUS_NONE ;
if ( flags & CICONTROL_CAMDETECT )
budget_ci - > slot_status = SLOTSTATUS_PRESENT ;
2006-04-05 14:09:45 -03:00
// version 0xa2 of the CI firmware doesn't generate interrupts
if ( ci_version = = 0xa2 ) {
ca_flags = 0 ;
budget_ci - > ci_irq = 0 ;
} else {
ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
DVB_CA_EN50221_FLAG_IRQ_FR |
DVB_CA_EN50221_FLAG_IRQ_DA ;
budget_ci - > ci_irq = 1 ;
}
2005-04-16 15:20:36 -07:00
// register CI interface
budget_ci - > ca . owner = THIS_MODULE ;
budget_ci - > ca . read_attribute_mem = ciintf_read_attribute_mem ;
budget_ci - > ca . write_attribute_mem = ciintf_write_attribute_mem ;
budget_ci - > ca . read_cam_control = ciintf_read_cam_control ;
budget_ci - > ca . write_cam_control = ciintf_write_cam_control ;
budget_ci - > ca . slot_reset = ciintf_slot_reset ;
budget_ci - > ca . slot_shutdown = ciintf_slot_shutdown ;
budget_ci - > ca . slot_ts_enable = ciintf_slot_ts_enable ;
2006-04-05 14:09:45 -03:00
budget_ci - > ca . poll_slot_status = ciintf_poll_slot_status ;
2005-04-16 15:20:36 -07:00
budget_ci - > ca . data = budget_ci ;
2005-05-16 21:54:39 -07:00
if ( ( result = dvb_ca_en50221_init ( & budget_ci - > budget . dvb_adapter ,
2005-04-16 15:20:36 -07:00
& budget_ci - > ca ,
2006-04-05 14:09:45 -03:00
ca_flags , 1 ) ) ! = 0 ) {
2005-04-16 15:20:36 -07:00
printk ( " budget_ci: CI interface detected, but initialisation failed. \n " ) ;
goto error ;
}
2006-04-05 14:09:45 -03:00
2005-04-16 15:20:36 -07:00
// Setup CI slot IRQ
2006-04-05 14:09:45 -03:00
if ( budget_ci - > ci_irq ) {
tasklet_init ( & budget_ci - > ciintf_irq_tasklet , ciintf_interrupt , ( unsigned long ) budget_ci ) ;
if ( budget_ci - > slot_status ! = SLOTSTATUS_NONE ) {
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_IRQLO ) ;
} else {
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_IRQHI ) ;
}
2006-12-03 10:49:47 -03:00
SAA7146_IER_ENABLE ( saa , MASK_03 ) ;
2005-04-16 15:20:36 -07:00
}
2006-04-05 14:09:45 -03:00
// enable interface
2005-04-16 15:20:36 -07:00
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 ,
CICONTROL_RESET , 1 , 0 ) ;
// success!
printk ( " budget_ci: CI interface initialised \n " ) ;
budget_ci - > budget . ci_present = 1 ;
// forge a fake CI IRQ so the CAM state is setup correctly
2006-04-05 14:09:45 -03:00
if ( budget_ci - > ci_irq ) {
flags = DVB_CA_EN50221_CAMCHANGE_REMOVED ;
if ( budget_ci - > slot_status ! = SLOTSTATUS_NONE )
flags = DVB_CA_EN50221_CAMCHANGE_INSERTED ;
dvb_ca_en50221_camchange_irq ( & budget_ci - > ca , 0 , flags ) ;
}
2005-04-16 15:20:36 -07:00
return 0 ;
error :
2006-12-03 21:08:08 -03:00
saa7146_write ( saa , MC1 , MASK_27 ) ;
2005-04-16 15:20:36 -07:00
return result ;
}
static void ciintf_deinit ( struct budget_ci * budget_ci )
{
struct saa7146_dev * saa = budget_ci - > budget . dev ;
// disable CI interrupts
2006-04-05 14:09:45 -03:00
if ( budget_ci - > ci_irq ) {
2006-12-03 10:49:47 -03:00
SAA7146_IER_DISABLE ( saa , MASK_03 ) ;
2006-04-05 14:09:45 -03:00
saa7146_setgpio ( saa , 0 , SAA7146_GPIO_INPUT ) ;
tasklet_kill ( & budget_ci - > ciintf_irq_tasklet ) ;
}
// reset interface
2005-04-16 15:20:36 -07:00
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 , 0 , 1 , 0 ) ;
msleep ( 1 ) ;
ttpci_budget_debiwrite ( & budget_ci - > budget , DEBICICTL , DEBIADDR_CICONTROL , 1 ,
CICONTROL_RESET , 1 , 0 ) ;
// disable TS data stream to CI interface
saa7146_setgpio ( saa , 1 , SAA7146_GPIO_INPUT ) ;
// release the CA device
dvb_ca_en50221_release ( & budget_ci - > ca ) ;
// disable DEBI pins
2006-12-03 21:08:08 -03:00
saa7146_write ( saa , MC1 , MASK_27 ) ;
2005-04-16 15:20:36 -07:00
}
static void budget_ci_irq ( struct saa7146_dev * dev , u32 * isr )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) dev - > ext_priv ;
dprintk ( 8 , " dev: %p, budget_ci: %p \n " , dev , budget_ci ) ;
if ( * isr & MASK_06 )
2006-12-02 21:16:05 -02:00
tasklet_schedule ( & budget_ci - > ir . msp430_irq_tasklet ) ;
2005-04-16 15:20:36 -07:00
if ( * isr & MASK_10 )
ttpci_budget_irq10_handler ( dev , isr ) ;
2006-04-05 14:09:45 -03:00
if ( ( * isr & MASK_03 ) & & ( budget_ci - > budget . ci_present ) & & ( budget_ci - > ci_irq ) )
2005-04-16 15:20:36 -07:00
tasklet_schedule ( & budget_ci - > ciintf_irq_tasklet ) ;
}
static u8 philips_su1278_tt_inittab [ ] = {
0x01 , 0x0f ,
0x02 , 0x30 ,
0x03 , 0x00 ,
0x04 , 0x5b ,
0x05 , 0x85 ,
0x06 , 0x02 ,
0x07 , 0x00 ,
0x08 , 0x02 ,
0x09 , 0x00 ,
0x0C , 0x01 ,
0x0D , 0x81 ,
0x0E , 0x44 ,
0x0f , 0x14 ,
0x10 , 0x3c ,
0x11 , 0x84 ,
0x12 , 0xda ,
0x13 , 0x97 ,
0x14 , 0x95 ,
0x15 , 0xc9 ,
0x16 , 0x19 ,
0x17 , 0x8c ,
0x18 , 0x59 ,
0x19 , 0xf8 ,
0x1a , 0xfe ,
0x1c , 0x7f ,
0x1d , 0x00 ,
0x1e , 0x00 ,
0x1f , 0x50 ,
0x20 , 0x00 ,
0x21 , 0x00 ,
0x22 , 0x00 ,
0x23 , 0x00 ,
0x28 , 0x00 ,
0x29 , 0x28 ,
0x2a , 0x14 ,
0x2b , 0x0f ,
0x2c , 0x09 ,
0x2d , 0x09 ,
0x31 , 0x1f ,
0x32 , 0x19 ,
0x33 , 0xfc ,
0x34 , 0x93 ,
0xff , 0xff
} ;
static int philips_su1278_tt_set_symbol_rate ( struct dvb_frontend * fe , u32 srate , u32 ratio )
{
stv0299_writereg ( fe , 0x0e , 0x44 ) ;
if ( srate > = 10000000 ) {
stv0299_writereg ( fe , 0x13 , 0x97 ) ;
stv0299_writereg ( fe , 0x14 , 0x95 ) ;
stv0299_writereg ( fe , 0x15 , 0xc9 ) ;
stv0299_writereg ( fe , 0x17 , 0x8c ) ;
stv0299_writereg ( fe , 0x1a , 0xfe ) ;
stv0299_writereg ( fe , 0x1c , 0x7f ) ;
stv0299_writereg ( fe , 0x2d , 0x09 ) ;
} else {
stv0299_writereg ( fe , 0x13 , 0x99 ) ;
stv0299_writereg ( fe , 0x14 , 0x8d ) ;
stv0299_writereg ( fe , 0x15 , 0xce ) ;
stv0299_writereg ( fe , 0x17 , 0x43 ) ;
stv0299_writereg ( fe , 0x1a , 0x1d ) ;
stv0299_writereg ( fe , 0x1c , 0x12 ) ;
stv0299_writereg ( fe , 0x2d , 0x05 ) ;
}
stv0299_writereg ( fe , 0x0e , 0x23 ) ;
stv0299_writereg ( fe , 0x0f , 0x94 ) ;
stv0299_writereg ( fe , 0x10 , 0x39 ) ;
stv0299_writereg ( fe , 0x15 , 0xc9 ) ;
stv0299_writereg ( fe , 0x1f , ( ratio > > 16 ) & 0xff ) ;
stv0299_writereg ( fe , 0x20 , ( ratio > > 8 ) & 0xff ) ;
stv0299_writereg ( fe , 0x21 , ( ratio ) & 0xf0 ) ;
return 0 ;
}
2011-12-24 12:24:33 -03:00
static int philips_su1278_tt_tuner_set_params ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
2011-12-23 08:04:27 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2006-04-18 17:47:11 -03:00
struct budget_ci * budget_ci = ( struct budget_ci * ) fe - > dvb - > priv ;
2005-04-16 15:20:36 -07:00
u32 div ;
u8 buf [ 4 ] ;
struct i2c_msg msg = { . addr = 0x60 , . flags = 0 , . buf = buf , . len = sizeof ( buf ) } ;
2011-12-23 08:04:27 -03:00
if ( ( p - > frequency < 950000 ) | | ( p - > frequency > 2150000 ) )
2005-04-16 15:20:36 -07:00
return - EINVAL ;
2011-12-23 08:04:27 -03:00
div = ( p - > frequency + ( 500 - 1 ) ) / 500 ; /* round correctly */
2005-04-16 15:20:36 -07:00
buf [ 0 ] = ( div > > 8 ) & 0x7f ;
buf [ 1 ] = div & 0xff ;
buf [ 2 ] = 0x80 | ( ( div & 0x18000 ) > > 10 ) | 2 ;
buf [ 3 ] = 0x20 ;
2011-12-23 08:04:27 -03:00
if ( p - > symbol_rate < 4000000 )
2005-04-16 15:20:36 -07:00
buf [ 3 ] | = 1 ;
2011-12-23 08:04:27 -03:00
if ( p - > frequency < 1250000 )
2005-04-16 15:20:36 -07:00
buf [ 3 ] | = 0 ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 1550000 )
2005-04-16 15:20:36 -07:00
buf [ 3 ] | = 0x40 ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 2050000 )
2005-04-16 15:20:36 -07:00
buf [ 3 ] | = 0x80 ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 2150000 )
2005-04-16 15:20:36 -07:00
buf [ 3 ] | = 0xC0 ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2006-04-18 17:47:11 -03:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & msg , 1 ) ! = 1 )
2005-04-16 15:20:36 -07:00
return - EIO ;
return 0 ;
}
2017-02-19 15:04:41 -03:00
static const struct stv0299_config philips_su1278_tt_config = {
2005-04-16 15:20:36 -07:00
. demod_address = 0x68 ,
. inittab = philips_su1278_tt_inittab ,
. mclk = 64000000UL ,
. invert = 0 ,
. skip_reinit = 1 ,
2008-04-20 22:13:37 -03:00
. lock_output = STV0299_LOCKOUTPUT_1 ,
2005-04-16 15:20:36 -07:00
. volt13_op0_op1 = STV0299_VOLT13_OP1 ,
. min_delay_ms = 50 ,
. set_symbol_rate = philips_su1278_tt_set_symbol_rate ,
} ;
2006-04-18 17:47:11 -03:00
static int philips_tdm1316l_tuner_init ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
struct budget_ci * budget_ci = ( struct budget_ci * ) fe - > dvb - > priv ;
static u8 td1316_init [ ] = { 0x0b , 0xf5 , 0x85 , 0xab } ;
static u8 disable_mc44BC374c [ ] = { 0x1d , 0x74 , 0xa0 , 0x68 } ;
2005-07-07 17:57:54 -07:00
struct i2c_msg tuner_msg = { . addr = budget_ci - > tuner_pll_address , . flags = 0 , . buf = td1316_init , . len =
2005-04-16 15:20:36 -07:00
sizeof ( td1316_init ) } ;
// setup PLL configuration
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-04-16 15:20:36 -07:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ! = 1 )
return - EIO ;
msleep ( 1 ) ;
// disable the mc44BC374c (do not check for errors)
tuner_msg . addr = 0x65 ;
tuner_msg . buf = disable_mc44BC374c ;
tuner_msg . len = sizeof ( disable_mc44BC374c ) ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-04-16 15:20:36 -07:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ! = 1 ) {
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-04-16 15:20:36 -07:00
i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ;
}
return 0 ;
}
2011-12-24 12:24:33 -03:00
static int philips_tdm1316l_tuner_set_params ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
2011-12-23 08:04:27 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-04-16 15:20:36 -07:00
struct budget_ci * budget_ci = ( struct budget_ci * ) fe - > dvb - > priv ;
u8 tuner_buf [ 4 ] ;
2005-07-07 17:57:54 -07:00
struct i2c_msg tuner_msg = { . addr = budget_ci - > tuner_pll_address , . flags = 0 , . buf = tuner_buf , . len = sizeof ( tuner_buf ) } ;
2005-04-16 15:20:36 -07:00
int tuner_frequency = 0 ;
u8 band , cp , filter ;
// determine charge pump
2011-12-23 08:04:27 -03:00
tuner_frequency = p - > frequency + 36130000 ;
2005-04-16 15:20:36 -07:00
if ( tuner_frequency < 87000000 )
return - EINVAL ;
else if ( tuner_frequency < 130000000 )
cp = 3 ;
else if ( tuner_frequency < 160000000 )
cp = 5 ;
else if ( tuner_frequency < 200000000 )
cp = 6 ;
else if ( tuner_frequency < 290000000 )
cp = 3 ;
else if ( tuner_frequency < 420000000 )
cp = 5 ;
else if ( tuner_frequency < 480000000 )
cp = 6 ;
else if ( tuner_frequency < 620000000 )
cp = 3 ;
else if ( tuner_frequency < 830000000 )
cp = 5 ;
else if ( tuner_frequency < 895000000 )
cp = 7 ;
else
return - EINVAL ;
// determine band
2011-12-23 08:04:27 -03:00
if ( p - > frequency < 49000000 )
2005-04-16 15:20:36 -07:00
return - EINVAL ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 159000000 )
2005-04-16 15:20:36 -07:00
band = 1 ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 444000000 )
2005-04-16 15:20:36 -07:00
band = 2 ;
2011-12-23 08:04:27 -03:00
else if ( p - > frequency < 861000000 )
2005-04-16 15:20:36 -07:00
band = 4 ;
else
return - EINVAL ;
// setup PLL filter and TDA9889
2011-12-23 08:04:27 -03:00
switch ( p - > bandwidth_hz ) {
case 6000000 :
2006-08-08 09:10:08 -03:00
tda1004x_writereg ( fe , 0x0C , 0x14 ) ;
2005-04-16 15:20:36 -07:00
filter = 0 ;
break ;
2011-12-23 08:04:27 -03:00
case 7000000 :
2006-08-08 09:10:08 -03:00
tda1004x_writereg ( fe , 0x0C , 0x80 ) ;
2005-04-16 15:20:36 -07:00
filter = 0 ;
break ;
2011-12-23 08:04:27 -03:00
case 8000000 :
2006-08-08 09:10:08 -03:00
tda1004x_writereg ( fe , 0x0C , 0x14 ) ;
2005-04-16 15:20:36 -07:00
filter = 1 ;
break ;
default :
return - EINVAL ;
}
// calculate divisor
// ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
2011-12-23 08:04:27 -03:00
tuner_frequency = ( ( ( p - > frequency / 1000 ) * 6 ) + 217280 ) / 1000 ;
2005-04-16 15:20:36 -07:00
// setup tuner buffer
tuner_buf [ 0 ] = tuner_frequency > > 8 ;
tuner_buf [ 1 ] = tuner_frequency & 0xff ;
tuner_buf [ 2 ] = 0xca ;
tuner_buf [ 3 ] = ( cp < < 5 ) | ( filter < < 3 ) | band ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-04-16 15:20:36 -07:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ! = 1 )
return - EIO ;
msleep ( 1 ) ;
return 0 ;
}
static int philips_tdm1316l_request_firmware ( struct dvb_frontend * fe ,
const struct firmware * * fw , char * name )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) fe - > dvb - > priv ;
return request_firmware ( fw , name , & budget_ci - > budget . dev - > pci - > dev ) ;
}
static struct tda1004x_config philips_tdm1316l_config = {
. demod_address = 0x8 ,
. invert = 0 ,
. invert_oclk = 0 ,
2005-07-07 17:57:40 -07:00
. xtal_freq = TDA10046_XTAL_4M ,
. agc_config = TDA10046_AGC_DEFAULT ,
. if_freq = TDA10046_FREQ_3617 ,
2005-04-16 15:20:36 -07:00
. request_firmware = philips_tdm1316l_request_firmware ,
} ;
2007-02-02 19:12:53 -03:00
static struct tda1004x_config philips_tdm1316l_config_invert = {
. demod_address = 0x8 ,
. invert = 1 ,
. invert_oclk = 0 ,
. xtal_freq = TDA10046_XTAL_4M ,
. agc_config = TDA10046_AGC_DEFAULT ,
. if_freq = TDA10046_FREQ_3617 ,
. request_firmware = philips_tdm1316l_request_firmware ,
} ;
2011-12-24 12:24:33 -03:00
static int dvbc_philips_tdm1316l_tuner_set_params ( struct dvb_frontend * fe )
2005-09-09 13:03:07 -07:00
{
2011-12-23 08:04:27 -03:00
struct dtv_frontend_properties * p = & fe - > dtv_property_cache ;
2005-09-09 13:03:07 -07:00
struct budget_ci * budget_ci = ( struct budget_ci * ) fe - > dvb - > priv ;
u8 tuner_buf [ 5 ] ;
struct i2c_msg tuner_msg = { . addr = budget_ci - > tuner_pll_address ,
. flags = 0 ,
. buf = tuner_buf ,
. len = sizeof ( tuner_buf ) } ;
int tuner_frequency = 0 ;
u8 band , cp , filter ;
// determine charge pump
2011-12-23 08:04:27 -03:00
tuner_frequency = p - > frequency + 36125000 ;
2005-09-09 13:03:07 -07:00
if ( tuner_frequency < 87000000 )
return - EINVAL ;
else if ( tuner_frequency < 130000000 ) {
cp = 3 ;
band = 1 ;
} else if ( tuner_frequency < 160000000 ) {
cp = 5 ;
band = 1 ;
} else if ( tuner_frequency < 200000000 ) {
cp = 6 ;
2007-05-03 13:16:12 -03:00
band = 1 ;
2005-09-09 13:03:07 -07:00
} else if ( tuner_frequency < 290000000 ) {
cp = 3 ;
band = 2 ;
} else if ( tuner_frequency < 420000000 ) {
cp = 5 ;
band = 2 ;
} else if ( tuner_frequency < 480000000 ) {
cp = 6 ;
band = 2 ;
} else if ( tuner_frequency < 620000000 ) {
cp = 3 ;
band = 4 ;
} else if ( tuner_frequency < 830000000 ) {
cp = 5 ;
band = 4 ;
} else if ( tuner_frequency < 895000000 ) {
cp = 7 ;
band = 4 ;
} else
return - EINVAL ;
// assume PLL filter should always be 8MHz for the moment.
filter = 1 ;
// calculate divisor
2011-12-23 08:04:27 -03:00
tuner_frequency = ( p - > frequency + 36125000 + ( 62500 / 2 ) ) / 62500 ;
2005-09-09 13:03:07 -07:00
// setup tuner buffer
tuner_buf [ 0 ] = tuner_frequency > > 8 ;
tuner_buf [ 1 ] = tuner_frequency & 0xff ;
tuner_buf [ 2 ] = 0xc8 ;
tuner_buf [ 3 ] = ( cp < < 5 ) | ( filter < < 3 ) | band ;
tuner_buf [ 4 ] = 0x80 ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-09-09 13:03:07 -07:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ! = 1 )
return - EIO ;
msleep ( 50 ) ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2005-09-09 13:03:07 -07:00
if ( i2c_transfer ( & budget_ci - > budget . i2c_adap , & tuner_msg , 1 ) ! = 1 )
return - EIO ;
msleep ( 1 ) ;
return 0 ;
}
static u8 dvbc_philips_tdm1316l_inittab [ ] = {
0x80 , 0x01 ,
0x80 , 0x00 ,
0x81 , 0x01 ,
0x81 , 0x00 ,
0x00 , 0x09 ,
0x01 , 0x69 ,
0x03 , 0x00 ,
0x04 , 0x00 ,
0x07 , 0x00 ,
0x08 , 0x00 ,
0x20 , 0x00 ,
0x21 , 0x40 ,
0x22 , 0x00 ,
0x23 , 0x00 ,
0x24 , 0x40 ,
0x25 , 0x88 ,
0x30 , 0xff ,
0x31 , 0x00 ,
0x32 , 0xff ,
0x33 , 0x00 ,
0x34 , 0x50 ,
0x35 , 0x7f ,
0x36 , 0x00 ,
0x37 , 0x20 ,
0x38 , 0x00 ,
0x40 , 0x1c ,
0x41 , 0xff ,
0x42 , 0x29 ,
0x43 , 0x20 ,
0x44 , 0xff ,
0x45 , 0x00 ,
0x46 , 0x00 ,
0x49 , 0x04 ,
0x4a , 0x00 ,
0x4b , 0x7b ,
0x52 , 0x30 ,
0x55 , 0xae ,
0x56 , 0x47 ,
0x57 , 0xe1 ,
0x58 , 0x3a ,
0x5a , 0x1e ,
0x5b , 0x34 ,
0x60 , 0x00 ,
0x63 , 0x00 ,
0x64 , 0x00 ,
0x65 , 0x00 ,
0x66 , 0x00 ,
0x67 , 0x00 ,
0x68 , 0x00 ,
0x69 , 0x00 ,
0x6a , 0x02 ,
0x6b , 0x00 ,
0x70 , 0xff ,
0x71 , 0x00 ,
0x72 , 0x00 ,
0x73 , 0x00 ,
0x74 , 0x0c ,
0x80 , 0x00 ,
0x81 , 0x00 ,
0x82 , 0x00 ,
0x83 , 0x00 ,
0x84 , 0x04 ,
0x85 , 0x80 ,
0x86 , 0x24 ,
0x87 , 0x78 ,
0x88 , 0x10 ,
0x89 , 0x00 ,
0x90 , 0x01 ,
0x91 , 0x01 ,
0xa0 , 0x04 ,
0xa1 , 0x00 ,
0xa2 , 0x00 ,
0xb0 , 0x91 ,
0xb1 , 0x0b ,
0xc0 , 0x53 ,
0xc1 , 0x70 ,
0xc2 , 0x12 ,
0xd0 , 0x00 ,
0xd1 , 0x00 ,
0xd2 , 0x00 ,
0xd3 , 0x00 ,
0xd4 , 0x00 ,
0xd5 , 0x00 ,
0xde , 0x00 ,
0xdf , 0x00 ,
0x61 , 0x38 ,
0x62 , 0x0a ,
0x53 , 0x13 ,
0x59 , 0x08 ,
0xff , 0xff ,
} ;
static struct stv0297_config dvbc_philips_tdm1316l_config = {
. demod_address = 0x1c ,
. inittab = dvbc_philips_tdm1316l_inittab ,
. invert = 0 ,
2006-04-27 21:45:20 -03:00
. stop_during_read = 1 ,
2005-09-09 13:03:07 -07:00
} ;
2008-06-15 17:25:46 -03:00
static struct tda10023_config tda10023_config = {
. demod_address = 0xc ,
. invert = 0 ,
. xtal = 16000000 ,
. pll_m = 11 ,
. pll_p = 3 ,
. pll_n = 1 ,
. deltaf = 0xa511 ,
} ;
2005-09-09 13:03:07 -07:00
2009-03-25 17:53:02 -03:00
static struct tda827x_config tda827x_config = {
. config = 0 ,
} ;
2008-10-23 18:32:50 -03:00
/* TT S2-3200 DVB-S (STB0899) Inittab */
2008-10-23 18:16:40 -03:00
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1 [ ] = {
{ STB0899_DEV_ID , 0x81 } ,
{ STB0899_DISCNTRL1 , 0x32 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_DISCNTRL2 , 0x80 } ,
{ STB0899_DISRX_ST0 , 0x04 } ,
{ STB0899_DISRX_ST1 , 0x00 } ,
{ STB0899_DISPARITY , 0x00 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_DISSTATUS , 0x20 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_DISF22 , 0x8c } ,
{ STB0899_DISF22RX , 0x9a } ,
2008-10-23 18:45:17 -03:00
{ STB0899_SYSREG , 0x0b } ,
2018-01-04 13:08:56 -05:00
{ STB0899_ACRPRESC , 0x11 } ,
{ STB0899_ACRDIV1 , 0x0a } ,
{ STB0899_ACRDIV2 , 0x05 } ,
{ STB0899_DACR1 , 0x00 } ,
{ STB0899_DACR2 , 0x00 } ,
{ STB0899_OUTCFG , 0x00 } ,
{ STB0899_MODECFG , 0x00 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_IRQSTATUS_3 , 0x30 } ,
{ STB0899_IRQSTATUS_2 , 0x00 } ,
{ STB0899_IRQSTATUS_1 , 0x00 } ,
{ STB0899_IRQSTATUS_0 , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_IRQMSK_3 , 0xf3 } ,
{ STB0899_IRQMSK_2 , 0xfc } ,
{ STB0899_IRQMSK_1 , 0xff } ,
2008-10-23 18:16:40 -03:00
{ STB0899_IRQMSK_0 , 0xff } ,
{ STB0899_IRQCFG , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_I2CCFG , 0x88 } ,
{ STB0899_I2CRPT , 0x48 } , /* 12k Pullup, Repeater=16, Stop=disabled */
2008-10-23 18:16:40 -03:00
{ STB0899_IOPVALUE5 , 0x00 } ,
{ STB0899_IOPVALUE4 , 0x20 } ,
{ STB0899_IOPVALUE3 , 0xc9 } ,
{ STB0899_IOPVALUE2 , 0x90 } ,
{ STB0899_IOPVALUE1 , 0x40 } ,
{ STB0899_IOPVALUE0 , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_GPIO00CFG , 0x82 } ,
{ STB0899_GPIO01CFG , 0x82 } ,
{ STB0899_GPIO02CFG , 0x82 } ,
{ STB0899_GPIO03CFG , 0x82 } ,
{ STB0899_GPIO04CFG , 0x82 } ,
{ STB0899_GPIO05CFG , 0x82 } ,
{ STB0899_GPIO06CFG , 0x82 } ,
{ STB0899_GPIO07CFG , 0x82 } ,
{ STB0899_GPIO08CFG , 0x82 } ,
{ STB0899_GPIO09CFG , 0x82 } ,
{ STB0899_GPIO10CFG , 0x82 } ,
{ STB0899_GPIO11CFG , 0x82 } ,
{ STB0899_GPIO12CFG , 0x82 } ,
{ STB0899_GPIO13CFG , 0x82 } ,
{ STB0899_GPIO14CFG , 0x82 } ,
{ STB0899_GPIO15CFG , 0x82 } ,
{ STB0899_GPIO16CFG , 0x82 } ,
{ STB0899_GPIO17CFG , 0x82 } ,
{ STB0899_GPIO18CFG , 0x82 } ,
{ STB0899_GPIO19CFG , 0x82 } ,
{ STB0899_GPIO20CFG , 0x82 } ,
{ STB0899_SDATCFG , 0xb8 } ,
{ STB0899_SCLTCFG , 0xba } ,
{ STB0899_AGCRFCFG , 0x1c } , /* 0x11 */
{ STB0899_GPIO22 , 0x82 } , /* AGCBB2CFG */
{ STB0899_GPIO21 , 0x91 } , /* AGCBB1CFG */
{ STB0899_DIRCLKCFG , 0x82 } ,
{ STB0899_CLKOUT27CFG , 0x7e } ,
{ STB0899_STDBYCFG , 0x82 } ,
{ STB0899_CS0CFG , 0x82 } ,
{ STB0899_CS1CFG , 0x82 } ,
{ STB0899_DISEQCOCFG , 0x20 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_GPIO32CFG , 0x82 } ,
{ STB0899_GPIO33CFG , 0x82 } ,
{ STB0899_GPIO34CFG , 0x82 } ,
{ STB0899_GPIO35CFG , 0x82 } ,
{ STB0899_GPIO36CFG , 0x82 } ,
{ STB0899_GPIO37CFG , 0x82 } ,
{ STB0899_GPIO38CFG , 0x82 } ,
{ STB0899_GPIO39CFG , 0x82 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_NCOARSE , 0x15 } , /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
{ STB0899_SYNTCTRL , 0x02 } , /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
{ STB0899_FILTCTRL , 0x00 } ,
{ STB0899_SYSCTRL , 0x00 } ,
{ STB0899_STOPCLK1 , 0x20 } ,
{ STB0899_STOPCLK2 , 0x00 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_INTBUFSTATUS , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_INTBUFCTRL , 0x0a } ,
2008-10-23 18:16:40 -03:00
{ 0xffff , 0xff } ,
} ;
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3 [ ] = {
2018-01-04 13:08:56 -05:00
{ STB0899_DEMOD , 0x00 } ,
{ STB0899_RCOMPC , 0xc9 } ,
{ STB0899_AGC1CN , 0x41 } ,
{ STB0899_AGC1REF , 0x10 } ,
2008-11-10 18:56:20 -03:00
{ STB0899_RTC , 0x7a } ,
2018-01-04 13:08:56 -05:00
{ STB0899_TMGCFG , 0x4e } ,
{ STB0899_AGC2REF , 0x34 } ,
{ STB0899_TLSR , 0x84 } ,
{ STB0899_CFD , 0xc7 } ,
2008-11-10 18:56:20 -03:00
{ STB0899_ACLC , 0x87 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_BCLC , 0x94 } ,
{ STB0899_EQON , 0x41 } ,
{ STB0899_LDT , 0xdd } ,
{ STB0899_LDT2 , 0xc9 } ,
{ STB0899_EQUALREF , 0xb4 } ,
{ STB0899_TMGRAMP , 0x10 } ,
{ STB0899_TMGTHD , 0x30 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_IDCCOMP , 0xfb } ,
{ STB0899_QDCCOMP , 0x03 } ,
{ STB0899_POWERI , 0x3b } ,
{ STB0899_POWERQ , 0x3d } ,
{ STB0899_RCOMP , 0x81 } ,
{ STB0899_AGCIQIN , 0x80 } ,
{ STB0899_AGC2I1 , 0x04 } ,
{ STB0899_AGC2I2 , 0xf5 } ,
{ STB0899_TLIR , 0x25 } ,
{ STB0899_RTF , 0x80 } ,
{ STB0899_DSTATUS , 0x00 } ,
{ STB0899_LDI , 0xca } ,
{ STB0899_CFRM , 0xf1 } ,
{ STB0899_CFRL , 0xf3 } ,
{ STB0899_NIRM , 0x2a } ,
{ STB0899_NIRL , 0x05 } ,
{ STB0899_ISYMB , 0x17 } ,
{ STB0899_QSYMB , 0xfa } ,
2018-01-04 13:08:56 -05:00
{ STB0899_SFRH , 0x2f } ,
{ STB0899_SFRM , 0x68 } ,
{ STB0899_SFRL , 0x40 } ,
{ STB0899_SFRUPH , 0x2f } ,
{ STB0899_SFRUPM , 0x68 } ,
{ STB0899_SFRUPL , 0x40 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_EQUAI1 , 0xfd } ,
{ STB0899_EQUAQ1 , 0x04 } ,
{ STB0899_EQUAI2 , 0x0f } ,
{ STB0899_EQUAQ2 , 0xff } ,
{ STB0899_EQUAI3 , 0xdf } ,
{ STB0899_EQUAQ3 , 0xfa } ,
{ STB0899_EQUAI4 , 0x37 } ,
{ STB0899_EQUAQ4 , 0x0d } ,
{ STB0899_EQUAI5 , 0xbd } ,
{ STB0899_EQUAQ5 , 0xf7 } ,
{ STB0899_DSTATUS2 , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_VSTATUS , 0x00 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_VERROR , 0xff } ,
{ STB0899_IQSWAP , 0x2a } ,
{ STB0899_ECNT1M , 0x00 } ,
{ STB0899_ECNT1L , 0x00 } ,
{ STB0899_ECNT2M , 0x00 } ,
{ STB0899_ECNT2L , 0x00 } ,
{ STB0899_ECNT3M , 0x00 } ,
{ STB0899_ECNT3L , 0x00 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_FECAUTO1 , 0x06 } ,
2008-11-10 18:56:20 -03:00
{ STB0899_FECM , 0x01 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_VTH12 , 0xf0 } ,
{ STB0899_VTH23 , 0xa0 } ,
2008-11-10 18:56:20 -03:00
{ STB0899_VTH34 , 0x78 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_VTH56 , 0x4e } ,
{ STB0899_VTH67 , 0x48 } ,
{ STB0899_VTH78 , 0x38 } ,
{ STB0899_PRVIT , 0xff } ,
{ STB0899_VITSYNC , 0x19 } ,
{ STB0899_RSULC , 0xb1 } , /* DVB = 0xb1, DSS = 0xa1 */
{ STB0899_TSULC , 0x42 } ,
{ STB0899_RSLLC , 0x40 } ,
2008-11-10 18:56:20 -03:00
{ STB0899_TSLPL , 0x12 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_TSCFGH , 0x0c } ,
{ STB0899_TSCFGM , 0x00 } ,
{ STB0899_TSCFGL , 0x0c } ,
2009-11-13 18:51:39 -03:00
{ STB0899_TSOUT , 0x4d } , /* 0x0d for CAM */
2018-01-04 13:08:56 -05:00
{ STB0899_RSSYNCDEL , 0x00 } ,
{ STB0899_TSINHDELH , 0x02 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_TSINHDELM , 0x00 } ,
{ STB0899_TSINHDELL , 0x00 } ,
{ STB0899_TSLLSTKM , 0x00 } ,
{ STB0899_TSLLSTKL , 0x00 } ,
{ STB0899_TSULSTKM , 0x00 } ,
{ STB0899_TSULSTKL , 0xab } ,
{ STB0899_PCKLENUL , 0x00 } ,
{ STB0899_PCKLENLL , 0xcc } ,
{ STB0899_RSPCKLEN , 0xcc } ,
{ STB0899_TSSTATUS , 0x80 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_ERRCTRL1 , 0xb6 } ,
{ STB0899_ERRCTRL2 , 0x96 } ,
{ STB0899_ERRCTRL3 , 0x89 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_DMONMSK1 , 0x27 } ,
{ STB0899_DMONMSK0 , 0x03 } ,
2018-01-04 13:08:56 -05:00
{ STB0899_DEMAPVIT , 0x5c } ,
2008-10-23 18:16:40 -03:00
{ STB0899_PLPARM , 0x1f } ,
2018-01-04 13:08:56 -05:00
{ STB0899_PDELCTRL , 0x48 } ,
{ STB0899_PDELCTRL2 , 0x00 } ,
{ STB0899_BBHCTRL1 , 0x00 } ,
{ STB0899_BBHCTRL2 , 0x00 } ,
{ STB0899_HYSTTHRESH , 0x77 } ,
2008-10-23 18:16:40 -03:00
{ STB0899_MATCSTM , 0x00 } ,
{ STB0899_MATCSTL , 0x00 } ,
{ STB0899_UPLCSTM , 0x00 } ,
{ STB0899_UPLCSTL , 0x00 } ,
{ STB0899_DFLCSTM , 0x00 } ,
{ STB0899_DFLCSTL , 0x00 } ,
{ STB0899_SYNCCST , 0x00 } ,
{ STB0899_SYNCDCSTM , 0x00 } ,
{ STB0899_SYNCDCSTL , 0x00 } ,
{ STB0899_ISI_ENTRY , 0x00 } ,
{ STB0899_ISI_BIT_EN , 0x00 } ,
{ STB0899_MATSTRM , 0x00 } ,
{ STB0899_MATSTRL , 0x00 } ,
{ STB0899_UPLSTRM , 0x00 } ,
{ STB0899_UPLSTRL , 0x00 } ,
{ STB0899_DFLSTRM , 0x00 } ,
{ STB0899_DFLSTRL , 0x00 } ,
{ STB0899_SYNCSTR , 0x00 } ,
{ STB0899_SYNCDSTRM , 0x00 } ,
{ STB0899_SYNCDSTRL , 0x00 } ,
{ STB0899_CFGPDELSTATUS1 , 0x10 } ,
{ STB0899_CFGPDELSTATUS2 , 0x00 } ,
{ STB0899_BBFERRORM , 0x00 } ,
{ STB0899_BBFERRORL , 0x00 } ,
{ STB0899_UPKTERRORM , 0x00 } ,
{ STB0899_UPKTERRORL , 0x00 } ,
{ 0xffff , 0xff } ,
} ;
static struct stb0899_config tt3200_config = {
. init_dev = tt3200_stb0899_s1_init_1 ,
2008-01-25 18:20:48 -03:00
. init_s2_demod = stb0899_s2_init_2 ,
2008-10-23 18:32:50 -03:00
. init_s1_demod = tt3200_stb0899_s1_init_3 ,
2008-01-25 18:20:48 -03:00
. init_s2_fec = stb0899_s2_init_4 ,
. init_tst = stb0899_s1_init_5 ,
2008-10-23 18:16:40 -03:00
2008-01-18 14:15:17 -03:00
. postproc = NULL ,
2018-01-04 13:08:56 -05:00
. demod_address = 0x68 ,
2008-10-23 18:16:40 -03:00
. xtal_freq = 27000000 ,
2013-05-08 17:54:57 -03:00
. inversion = IQ_SWAP_ON ,
2008-10-23 18:32:50 -03:00
2008-03-04 19:19:58 -03:00
. lo_clk = 76500000 ,
. hi_clk = 99000000 ,
2008-01-25 18:20:48 -03:00
. esno_ave = STB0899_DVBS2_ESNO_AVE ,
. esno_quant = STB0899_DVBS2_ESNO_QUANT ,
. avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE ,
. avframes_fine = STB0899_DVBS2_AVFRAMES_FINE ,
. miss_threshold = STB0899_DVBS2_MISS_THRESHOLD ,
. uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ ,
. uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK ,
. uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF ,
. sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT ,
. btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS ,
. btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET ,
. crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS ,
. ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER ,
2008-10-23 18:32:50 -03:00
. tuner_get_frequency = stb6100_get_frequency ,
. tuner_set_frequency = stb6100_set_frequency ,
. tuner_set_bandwidth = stb6100_set_bandwidth ,
. tuner_get_bandwidth = stb6100_get_bandwidth ,
2008-01-18 14:15:17 -03:00
. tuner_set_rfsiggain = NULL
2008-10-23 18:16:40 -03:00
} ;
2009-01-05 01:34:20 -03:00
static struct stb6100_config tt3200_stb6100_config = {
2007-10-04 16:52:51 -03:00
. tuner_address = 0x60 ,
. refclock = 27000000 ,
2008-10-23 18:16:40 -03:00
} ;
2005-04-16 15:20:36 -07:00
static void frontend_init ( struct budget_ci * budget_ci )
{
switch ( budget_ci - > budget . dev - > pci - > subsystem_device ) {
case 0x100c : // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
budget_ci - > budget . dvb_frontend =
2006-08-08 09:10:08 -03:00
dvb_attach ( stv0299_attach , & alps_bsru6_config , & budget_ci - > budget . i2c_adap ) ;
2005-04-16 15:20:36 -07:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = alps_bsru6_tuner_set_params ;
2006-04-18 17:47:11 -03:00
budget_ci - > budget . dvb_frontend - > tuner_priv = & budget_ci - > budget . i2c_adap ;
2005-04-16 15:20:36 -07:00
break ;
}
break ;
case 0x100f : // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
budget_ci - > budget . dvb_frontend =
2006-08-08 09:10:08 -03:00
dvb_attach ( stv0299_attach , & philips_su1278_tt_config , & budget_ci - > budget . i2c_adap ) ;
2005-04-16 15:20:36 -07:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = philips_su1278_tt_tuner_set_params ;
2005-04-16 15:20:36 -07:00
break ;
}
break ;
2005-09-09 13:03:07 -07:00
case 0x1010 : // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
budget_ci - > tuner_pll_address = 0x61 ;
budget_ci - > budget . dvb_frontend =
2006-08-08 09:10:08 -03:00
dvb_attach ( stv0297_attach , & dvbc_philips_tdm1316l_config , & budget_ci - > budget . i2c_adap ) ;
2005-09-09 13:03:07 -07:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = dvbc_philips_tdm1316l_tuner_set_params ;
2005-09-09 13:03:07 -07:00
break ;
}
break ;
2005-04-16 15:20:36 -07:00
case 0x1011 : // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
2005-07-07 17:57:54 -07:00
budget_ci - > tuner_pll_address = 0x63 ;
2005-04-16 15:20:36 -07:00
budget_ci - > budget . dvb_frontend =
2006-08-08 09:10:08 -03:00
dvb_attach ( tda10045_attach , & philips_tdm1316l_config , & budget_ci - > budget . i2c_adap ) ;
2005-04-16 15:20:36 -07:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . init = philips_tdm1316l_tuner_init ;
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = philips_tdm1316l_tuner_set_params ;
2005-04-16 15:20:36 -07:00
break ;
}
break ;
2005-07-07 17:57:54 -07:00
2005-09-09 13:03:07 -07:00
case 0x1012 : // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
2005-07-07 17:57:54 -07:00
budget_ci - > tuner_pll_address = 0x60 ;
budget_ci - > budget . dvb_frontend =
2007-02-02 19:12:53 -03:00
dvb_attach ( tda10046_attach , & philips_tdm1316l_config_invert , & budget_ci - > budget . i2c_adap ) ;
2005-07-07 17:57:54 -07:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . init = philips_tdm1316l_tuner_init ;
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = philips_tdm1316l_tuner_set_params ;
2005-07-07 17:57:54 -07:00
break ;
}
break ;
2006-02-28 09:52:44 -03:00
case 0x1017 : // TT S-1500 PCI
2006-08-08 09:10:08 -03:00
budget_ci - > budget . dvb_frontend = dvb_attach ( stv0299_attach , & alps_bsbe1_config , & budget_ci - > budget . i2c_adap ) ;
2006-02-28 09:52:44 -03:00
if ( budget_ci - > budget . dvb_frontend ) {
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . tuner_ops . set_params = alps_bsbe1_tuner_set_params ;
2006-04-18 17:47:11 -03:00
budget_ci - > budget . dvb_frontend - > tuner_priv = & budget_ci - > budget . i2c_adap ;
2006-05-14 05:01:31 -03:00
budget_ci - > budget . dvb_frontend - > ops . dishnetwork_send_legacy_command = NULL ;
2006-08-08 09:10:08 -03:00
if ( dvb_attach ( lnbp21_attach , budget_ci - > budget . dvb_frontend , & budget_ci - > budget . i2c_adap , LNBP21_LLC , 0 ) = = NULL ) {
2008-04-08 23:20:00 -03:00
printk ( " %s: No LNBP21 found! \n " , __func__ ) ;
2006-08-08 09:10:11 -03:00
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
2006-02-28 09:52:44 -03:00
budget_ci - > budget . dvb_frontend = NULL ;
}
}
2008-06-15 17:25:46 -03:00
break ;
2006-02-28 09:52:44 -03:00
2008-06-15 17:25:46 -03:00
case 0x101a : /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
budget_ci - > budget . dvb_frontend = dvb_attach ( tda10023_attach , & tda10023_config , & budget_ci - > budget . i2c_adap , 0x48 ) ;
if ( budget_ci - > budget . dvb_frontend ) {
2009-03-25 17:53:02 -03:00
if ( dvb_attach ( tda827x_attach , budget_ci - > budget . dvb_frontend , 0x61 , & budget_ci - > budget . i2c_adap , & tda827x_config ) = = NULL ) {
2008-06-15 17:25:46 -03:00
printk ( KERN_ERR " %s: No tda827x found! \n " , __func__ ) ;
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
budget_ci - > budget . dvb_frontend = NULL ;
}
}
2006-02-28 09:52:44 -03:00
break ;
2008-10-23 18:16:40 -03:00
2011-03-29 17:37:00 -03:00
case 0x101b : /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
budget_ci - > budget . dvb_frontend = dvb_attach ( stv0288_attach , & stv0288_bsbe1_d01a_config , & budget_ci - > budget . i2c_adap ) ;
if ( budget_ci - > budget . dvb_frontend ) {
if ( dvb_attach ( stb6000_attach , budget_ci - > budget . dvb_frontend , 0x63 , & budget_ci - > budget . i2c_adap ) ) {
if ( ! dvb_attach ( lnbp21_attach , budget_ci - > budget . dvb_frontend , & budget_ci - > budget . i2c_adap , 0 , 0 ) ) {
printk ( KERN_ERR " %s: No LNBP21 found! \n " , __func__ ) ;
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
budget_ci - > budget . dvb_frontend = NULL ;
}
} else {
printk ( KERN_ERR " %s: No STB6000 found! \n " , __func__ ) ;
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
budget_ci - > budget . dvb_frontend = NULL ;
}
}
break ;
2008-10-23 18:16:40 -03:00
case 0x1019 : // TT S2-3200 PCI
2007-10-15 12:08:20 -03:00
/*
* NOTE ! on some STB0899 versions , the internal PLL takes a longer time
* to settle , aka LOCK . On the older revisions of the chip , we don ' t see
* this , as a result on the newer chips the entire clock tree , will not
* be stable after a freshly POWER ' ed up situation .
* In this case , we should RESET the STB0899 ( Active LOW ) and wait for
* PLL stabilization .
*
* On the TT S2 3200 and clones , the STB0899 demodulator ' s RESETB is
* connected to the SAA7146 GPIO , GPIO2 , Pin 142
*/
/* Reset Demodulator */
2007-10-15 13:07:16 -03:00
saa7146_setgpio ( budget_ci - > budget . dev , 2 , SAA7146_GPIO_OUTLO ) ;
2007-10-15 12:08:20 -03:00
/* Wait for everything to die */
msleep ( 50 ) ;
/* Pull it up out of Reset state */
2007-10-15 13:07:16 -03:00
saa7146_setgpio ( budget_ci - > budget . dev , 2 , SAA7146_GPIO_OUTHI ) ;
2007-10-15 12:08:20 -03:00
/* Wait for PLL to stabilize */
msleep ( 250 ) ;
/*
* PLL state should be stable now . Ideally , we should check
* for PLL LOCK status . But well , never mind !
*/
2007-10-08 18:51:54 -03:00
budget_ci - > budget . dvb_frontend = dvb_attach ( stb0899_attach , & tt3200_config , & budget_ci - > budget . i2c_adap ) ;
2008-10-23 18:16:40 -03:00
if ( budget_ci - > budget . dvb_frontend ) {
2007-10-08 18:51:54 -03:00
if ( dvb_attach ( stb6100_attach , budget_ci - > budget . dvb_frontend , & tt3200_stb6100_config , & budget_ci - > budget . i2c_adap ) ) {
if ( ! dvb_attach ( lnbp21_attach , budget_ci - > budget . dvb_frontend , & budget_ci - > budget . i2c_adap , 0 , 0 ) ) {
2009-01-07 14:42:41 -08:00
printk ( " %s: No LNBP21 found! \n " , __func__ ) ;
2007-10-08 18:51:54 -03:00
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
2008-10-23 18:16:40 -03:00
budget_ci - > budget . dvb_frontend = NULL ;
}
} else {
2007-10-08 18:51:54 -03:00
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
budget_ci - > budget . dvb_frontend = NULL ;
2008-10-23 18:16:40 -03:00
}
}
break ;
2005-04-16 15:20:36 -07:00
}
if ( budget_ci - > budget . dvb_frontend = = NULL ) {
2008-09-04 17:24:51 -03:00
printk ( " budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x] \n " ,
2005-04-16 15:20:36 -07:00
budget_ci - > budget . dev - > pci - > vendor ,
budget_ci - > budget . dev - > pci - > device ,
budget_ci - > budget . dev - > pci - > subsystem_vendor ,
budget_ci - > budget . dev - > pci - > subsystem_device ) ;
} else {
if ( dvb_register_frontend
2005-05-16 21:54:39 -07:00
( & budget_ci - > budget . dvb_adapter , budget_ci - > budget . dvb_frontend ) ) {
2005-04-16 15:20:36 -07:00
printk ( " budget-ci: Frontend registration failed! \n " ) ;
2006-08-08 09:10:09 -03:00
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
2005-04-16 15:20:36 -07:00
budget_ci - > budget . dvb_frontend = NULL ;
}
}
}
static int budget_ci_attach ( struct saa7146_dev * dev , struct saa7146_pci_extension_data * info )
{
struct budget_ci * budget_ci ;
int err ;
2006-12-02 21:16:05 -02:00
budget_ci = kzalloc ( sizeof ( struct budget_ci ) , GFP_KERNEL ) ;
2006-12-02 21:16:05 -02:00
if ( ! budget_ci ) {
err = - ENOMEM ;
goto out1 ;
}
2005-04-16 15:20:36 -07:00
dprintk ( 2 , " budget_ci: %p \n " , budget_ci ) ;
dev - > ext_priv = budget_ci ;
2008-09-21 20:50:11 -03:00
err = ttpci_budget_init ( & budget_ci - > budget , dev , info , THIS_MODULE ,
adapter_nr ) ;
2006-12-02 21:16:05 -02:00
if ( err )
goto out2 ;
2005-04-16 15:20:36 -07:00
2006-12-02 21:16:05 -02:00
err = msp430_ir_init ( budget_ci ) ;
if ( err )
goto out3 ;
2005-04-16 15:20:36 -07:00
ciintf_init ( budget_ci ) ;
2005-05-16 21:54:39 -07:00
budget_ci - > budget . dvb_adapter . priv = budget_ci ;
2005-04-16 15:20:36 -07:00
frontend_init ( budget_ci ) ;
2006-07-18 22:55:23 -03:00
ttpci_budget_init_hooks ( & budget_ci - > budget ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
2006-12-02 21:16:05 -02:00
out3 :
ttpci_budget_deinit ( & budget_ci - > budget ) ;
out2 :
kfree ( budget_ci ) ;
out1 :
return err ;
2005-04-16 15:20:36 -07:00
}
static int budget_ci_detach ( struct saa7146_dev * dev )
{
struct budget_ci * budget_ci = ( struct budget_ci * ) dev - > ext_priv ;
struct saa7146_dev * saa = budget_ci - > budget . dev ;
int err ;
if ( budget_ci - > budget . ci_present )
ciintf_deinit ( budget_ci ) ;
2006-12-02 21:16:05 -02:00
msp430_ir_deinit ( budget_ci ) ;
2006-08-08 09:10:08 -03:00
if ( budget_ci - > budget . dvb_frontend ) {
2005-04-16 15:20:36 -07:00
dvb_unregister_frontend ( budget_ci - > budget . dvb_frontend ) ;
2006-08-08 09:10:09 -03:00
dvb_frontend_detach ( budget_ci - > budget . dvb_frontend ) ;
2006-08-08 09:10:08 -03:00
}
2005-04-16 15:20:36 -07:00
err = ttpci_budget_deinit ( & budget_ci - > budget ) ;
// disable frontend and CI interface
saa7146_setgpio ( saa , 2 , SAA7146_GPIO_INPUT ) ;
kfree ( budget_ci ) ;
return err ;
}
static struct saa7146_extension budget_extension ;
2006-02-28 09:52:44 -03:00
MAKE_BUDGET_INFO ( ttbs2 , " TT-Budget/S-1500 PCI " , BUDGET_TT ) ;
2005-04-16 15:20:36 -07:00
MAKE_BUDGET_INFO ( ttbci , " TT-Budget/WinTV-NOVA-CI PCI " , BUDGET_TT_HW_DISEQC ) ;
MAKE_BUDGET_INFO ( ttbt2 , " TT-Budget/WinTV-NOVA-T PCI " , BUDGET_TT ) ;
2005-07-07 17:57:54 -07:00
MAKE_BUDGET_INFO ( ttbtci , " TT-Budget-T-CI PCI " , BUDGET_TT ) ;
2005-09-09 13:03:07 -07:00
MAKE_BUDGET_INFO ( ttbcci , " TT-Budget-C-CI PCI " , BUDGET_TT ) ;
2008-06-15 17:25:46 -03:00
MAKE_BUDGET_INFO ( ttc1501 , " TT-Budget C-1501 PCI " , BUDGET_TT ) ;
2008-10-23 18:16:40 -03:00
MAKE_BUDGET_INFO ( tt3200 , " TT-Budget S2-3200 PCI " , BUDGET_TT ) ;
2011-03-29 17:37:00 -03:00
MAKE_BUDGET_INFO ( ttbs1500b , " TT-Budget S-1500B PCI " , BUDGET_TT ) ;
2005-04-16 15:20:36 -07:00
2017-08-02 13:14:52 -04:00
static const struct pci_device_id pci_tbl [ ] = {
2005-04-16 15:20:36 -07:00
MAKE_EXTENSION_PCI ( ttbci , 0x13c2 , 0x100c ) ,
MAKE_EXTENSION_PCI ( ttbci , 0x13c2 , 0x100f ) ,
2005-09-09 13:03:07 -07:00
MAKE_EXTENSION_PCI ( ttbcci , 0x13c2 , 0x1010 ) ,
2005-04-16 15:20:36 -07:00
MAKE_EXTENSION_PCI ( ttbt2 , 0x13c2 , 0x1011 ) ,
2005-07-07 17:57:54 -07:00
MAKE_EXTENSION_PCI ( ttbtci , 0x13c2 , 0x1012 ) ,
2006-02-28 09:52:44 -03:00
MAKE_EXTENSION_PCI ( ttbs2 , 0x13c2 , 0x1017 ) ,
2008-06-15 17:25:46 -03:00
MAKE_EXTENSION_PCI ( ttc1501 , 0x13c2 , 0x101a ) ,
2008-10-23 18:16:40 -03:00
MAKE_EXTENSION_PCI ( tt3200 , 0x13c2 , 0x1019 ) ,
2011-03-29 17:37:00 -03:00
MAKE_EXTENSION_PCI ( ttbs1500b , 0x13c2 , 0x101b ) ,
2005-04-16 15:20:36 -07:00
{
. vendor = 0 ,
}
} ;
MODULE_DEVICE_TABLE ( pci , pci_tbl ) ;
static struct saa7146_extension budget_extension = {
2006-08-07 13:18:56 -03:00
. name = " budget_ci dvb " ,
2006-11-01 13:09:51 -03:00
. flags = SAA7146_USE_I2C_IRQ ,
2005-04-16 15:20:36 -07:00
. module = THIS_MODULE ,
. pci_tbl = & pci_tbl [ 0 ] ,
. attach = budget_ci_attach ,
. detach = budget_ci_detach ,
. irq_mask = MASK_03 | MASK_06 | MASK_10 ,
. irq_func = budget_ci_irq ,
} ;
static int __init budget_ci_init ( void )
{
return saa7146_register_extension ( & budget_extension ) ;
}
static void __exit budget_ci_exit ( void )
{
saa7146_unregister_extension ( & budget_extension ) ;
}
module_init ( budget_ci_init ) ;
module_exit ( budget_ci_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Michael Hunold, Jack Thomasson, Andrew de Quincey, others " ) ;
[media] ttpci: don't break long lines
Due to the 80-cols restrictions, and latter due to checkpatch
warnings, several strings were broken into multiple lines. This
is not considered a good practice anymore, as it makes harder
to grep for strings at the source code.
As we're right now fixing other drivers due to KERN_CONT, we need
to be able to identify what printk strings don't end with a "\n".
It is a way easier to detect those if we don't break long lines.
So, join those continuation lines.
The patch was generated via the script below, and manually
adjusted if needed.
</script>
use Text::Tabs;
while (<>) {
if ($next ne "") {
$c=$_;
if ($c =~ /^\s+\"(.*)/) {
$c2=$1;
$next =~ s/\"\n$//;
$n = expand($next);
$funpos = index($n, '(');
$pos = index($c2, '",');
if ($funpos && $pos > 0) {
$s1 = substr $c2, 0, $pos + 2;
$s2 = ' ' x ($funpos + 1) . substr $c2, $pos + 2;
$s2 =~ s/^\s+//;
$s2 = ' ' x ($funpos + 1) . $s2 if ($s2 ne "");
print unexpand("$next$s1\n");
print unexpand("$s2\n") if ($s2 ne "");
} else {
print "$next$c2\n";
}
$next="";
next;
} else {
print $next;
}
$next="";
} else {
if (m/\"$/) {
if (!m/\\n\"$/) {
$next=$_;
next;
}
}
}
print $_;
}
</script>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-10-18 17:44:07 -02:00
MODULE_DESCRIPTION ( " driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge " ) ;