2005-04-16 15:20:36 -07:00
/*
*
* device driver for Conexant 2388 x based TV cards
* MPEG Transport Stream ( DVB ) routines
*
2006-01-09 15:25:35 -02:00
* ( c ) 2004 , 2005 Chris Pascoe < c . pascoe @ itee . uq . edu . au >
2005-04-16 15:20:36 -07:00
* ( c ) 2004 Gerd Knorr < kraxel @ bytesex . org > [ SuSE Labs ]
*
* 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 ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/device.h>
# include <linux/fs.h>
# include <linux/kthread.h>
# include <linux/file.h>
# include <linux/suspend.h>
# include "cx88.h"
# include "dvb-pll.h"
2006-01-09 15:32:31 -02:00
# include <media/v4l2-common.h>
2005-07-12 13:58:44 -07:00
2006-08-08 09:10:09 -03:00
# include "mt352.h"
# include "mt352_priv.h"
# ifdef HAVE_VP3054_I2C
# include "cx88-vp3054-i2c.h"
2006-01-09 15:25:02 -02:00
# endif
2006-08-08 09:10:09 -03:00
# include "zl10353.h"
# include "cx22702.h"
# include "or51132.h"
# include "lgdt330x.h"
2006-11-19 19:45:26 -03:00
# include "lgh06xf.h"
2006-08-08 09:10:09 -03:00
# include "nxt200x.h"
# include "cx24123.h"
2006-05-12 20:31:51 -03:00
# include "isl6421.h"
2005-04-16 15:20:36 -07:00
MODULE_DESCRIPTION ( " driver for cx2388x based DVB cards " ) ;
MODULE_AUTHOR ( " Chris Pascoe <c.pascoe@itee.uq.edu.au> " ) ;
MODULE_AUTHOR ( " Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] " ) ;
MODULE_LICENSE ( " GPL " ) ;
static unsigned int debug = 0 ;
module_param ( debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " enable debug messages [dvb] " ) ;
# define dprintk(level,fmt, arg...) if (debug >= level) \
2006-12-02 21:15:51 -02:00
printk ( KERN_DEBUG " %s/2-dvb: " fmt , core - > name , # # arg )
2005-04-16 15:20:36 -07:00
/* ------------------------------------------------------------------ */
static int dvb_buf_setup ( struct videobuf_queue * q ,
unsigned int * count , unsigned int * size )
{
struct cx8802_dev * dev = q - > priv_data ;
dev - > ts_packet_size = 188 * 4 ;
dev - > ts_packet_count = 32 ;
* size = dev - > ts_packet_size * dev - > ts_packet_count ;
* count = 32 ;
return 0 ;
}
static int dvb_buf_prepare ( struct videobuf_queue * q , struct videobuf_buffer * vb ,
enum v4l2_field field )
{
struct cx8802_dev * dev = q - > priv_data ;
2006-03-10 12:29:15 -03:00
return cx8802_buf_prepare ( q , dev , ( struct cx88_buffer * ) vb , field ) ;
2005-04-16 15:20:36 -07:00
}
static void dvb_buf_queue ( struct videobuf_queue * q , struct videobuf_buffer * vb )
{
struct cx8802_dev * dev = q - > priv_data ;
cx8802_buf_queue ( dev , ( struct cx88_buffer * ) vb ) ;
}
static void dvb_buf_release ( struct videobuf_queue * q , struct videobuf_buffer * vb )
{
2006-03-10 12:29:15 -03:00
cx88_free_buffer ( q , ( struct cx88_buffer * ) vb ) ;
2005-04-16 15:20:36 -07:00
}
2005-05-01 08:59:29 -07:00
static struct videobuf_queue_ops dvb_qops = {
2005-04-16 15:20:36 -07:00
. buf_setup = dvb_buf_setup ,
. buf_prepare = dvb_buf_prepare ,
. buf_queue = dvb_buf_queue ,
. buf_release = dvb_buf_release ,
} ;
/* ------------------------------------------------------------------ */
2006-01-09 18:21:31 -02:00
static int dvico_fusionhdtv_demod_init ( struct dvb_frontend * fe )
2005-04-16 15:20:36 -07:00
{
static u8 clock_config [ ] = { CLOCK_CTL , 0x38 , 0x39 } ;
static u8 reset [ ] = { RESET , 0x80 } ;
static u8 adc_ctl_1_cfg [ ] = { ADC_CTL_1 , 0x40 } ;
static u8 agc_cfg [ ] = { AGC_TARGET , 0x24 , 0x20 } ;
static u8 gpp_ctl_cfg [ ] = { GPP_CTL , 0x33 } ;
static u8 capt_range_cfg [ ] = { CAPT_RANGE , 0x32 } ;
mt352_write ( fe , clock_config , sizeof ( clock_config ) ) ;
udelay ( 200 ) ;
mt352_write ( fe , reset , sizeof ( reset ) ) ;
mt352_write ( fe , adc_ctl_1_cfg , sizeof ( adc_ctl_1_cfg ) ) ;
mt352_write ( fe , agc_cfg , sizeof ( agc_cfg ) ) ;
mt352_write ( fe , gpp_ctl_cfg , sizeof ( gpp_ctl_cfg ) ) ;
mt352_write ( fe , capt_range_cfg , sizeof ( capt_range_cfg ) ) ;
return 0 ;
}
2006-01-09 18:21:28 -02:00
static int dvico_dual_demod_init ( struct dvb_frontend * fe )
{
static u8 clock_config [ ] = { CLOCK_CTL , 0x38 , 0x38 } ;
static u8 reset [ ] = { RESET , 0x80 } ;
static u8 adc_ctl_1_cfg [ ] = { ADC_CTL_1 , 0x40 } ;
static u8 agc_cfg [ ] = { AGC_TARGET , 0x28 , 0x20 } ;
static u8 gpp_ctl_cfg [ ] = { GPP_CTL , 0x33 } ;
static u8 capt_range_cfg [ ] = { CAPT_RANGE , 0x32 } ;
mt352_write ( fe , clock_config , sizeof ( clock_config ) ) ;
udelay ( 200 ) ;
mt352_write ( fe , reset , sizeof ( reset ) ) ;
mt352_write ( fe , adc_ctl_1_cfg , sizeof ( adc_ctl_1_cfg ) ) ;
mt352_write ( fe , agc_cfg , sizeof ( agc_cfg ) ) ;
mt352_write ( fe , gpp_ctl_cfg , sizeof ( gpp_ctl_cfg ) ) ;
mt352_write ( fe , capt_range_cfg , sizeof ( capt_range_cfg ) ) ;
return 0 ;
}
2005-04-16 15:20:36 -07:00
static int dntv_live_dvbt_demod_init ( struct dvb_frontend * fe )
{
static u8 clock_config [ ] = { 0x89 , 0x38 , 0x39 } ;
static u8 reset [ ] = { 0x50 , 0x80 } ;
static u8 adc_ctl_1_cfg [ ] = { 0x8E , 0x40 } ;
static u8 agc_cfg [ ] = { 0x67 , 0x10 , 0x23 , 0x00 , 0xFF , 0xFF ,
2005-11-08 21:37:45 -08:00
0x00 , 0xFF , 0x00 , 0x40 , 0x40 } ;
2005-04-16 15:20:36 -07:00
static u8 dntv_extra [ ] = { 0xB5 , 0x7A } ;
static u8 capt_range_cfg [ ] = { 0x75 , 0x32 } ;
mt352_write ( fe , clock_config , sizeof ( clock_config ) ) ;
udelay ( 2000 ) ;
mt352_write ( fe , reset , sizeof ( reset ) ) ;
mt352_write ( fe , adc_ctl_1_cfg , sizeof ( adc_ctl_1_cfg ) ) ;
mt352_write ( fe , agc_cfg , sizeof ( agc_cfg ) ) ;
udelay ( 2000 ) ;
mt352_write ( fe , dntv_extra , sizeof ( dntv_extra ) ) ;
mt352_write ( fe , capt_range_cfg , sizeof ( capt_range_cfg ) ) ;
return 0 ;
}
static struct mt352_config dvico_fusionhdtv = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0f ,
2006-01-09 18:21:31 -02:00
. demod_init = dvico_fusionhdtv_demod_init ,
2005-04-16 15:20:36 -07:00
} ;
static struct mt352_config dntv_live_dvbt_config = {
. demod_address = 0x0f ,
. demod_init = dntv_live_dvbt_demod_init ,
} ;
2006-01-09 15:25:35 -02:00
2006-01-09 18:21:28 -02:00
static struct mt352_config dvico_fusionhdtv_dual = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0f ,
2006-01-09 18:21:28 -02:00
. demod_init = dvico_dual_demod_init ,
} ;
2006-01-09 15:25:35 -02:00
# ifdef HAVE_VP3054_I2C
2006-01-09 18:21:31 -02:00
static int dntv_live_dvbt_pro_demod_init ( struct dvb_frontend * fe )
{
static u8 clock_config [ ] = { 0x89 , 0x38 , 0x38 } ;
static u8 reset [ ] = { 0x50 , 0x80 } ;
static u8 adc_ctl_1_cfg [ ] = { 0x8E , 0x40 } ;
static u8 agc_cfg [ ] = { 0x67 , 0x10 , 0x20 , 0x00 , 0xFF , 0xFF ,
0x00 , 0xFF , 0x00 , 0x40 , 0x40 } ;
static u8 dntv_extra [ ] = { 0xB5 , 0x7A } ;
static u8 capt_range_cfg [ ] = { 0x75 , 0x32 } ;
mt352_write ( fe , clock_config , sizeof ( clock_config ) ) ;
udelay ( 2000 ) ;
mt352_write ( fe , reset , sizeof ( reset ) ) ;
mt352_write ( fe , adc_ctl_1_cfg , sizeof ( adc_ctl_1_cfg ) ) ;
mt352_write ( fe , agc_cfg , sizeof ( agc_cfg ) ) ;
udelay ( 2000 ) ;
mt352_write ( fe , dntv_extra , sizeof ( dntv_extra ) ) ;
mt352_write ( fe , capt_range_cfg , sizeof ( capt_range_cfg ) ) ;
return 0 ;
}
2006-01-09 15:25:35 -02:00
static int philips_fmd1216_pll_init ( struct dvb_frontend * fe )
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
/* this message is to set up ATC and ALC */
static u8 fmd1216_init [ ] = { 0x0b , 0xdc , 0x9c , 0xa0 } ;
struct i2c_msg msg =
{ . addr = dev - > core - > pll_addr , . flags = 0 ,
. buf = fmd1216_init , . len = sizeof ( fmd1216_init ) } ;
int err ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2006-01-09 15:25:35 -02:00
if ( ( err = i2c_transfer ( & dev - > core - > i2c_adap , & msg , 1 ) ) ! = 1 ) {
if ( err < 0 )
return err ;
else
return - EREMOTEIO ;
}
return 0 ;
}
2006-04-18 17:56:10 -03:00
static int dntv_live_dvbt_pro_tuner_set_params ( struct dvb_frontend * fe ,
struct dvb_frontend_parameters * params )
2006-01-09 15:25:35 -02:00
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
2006-04-18 17:56:10 -03:00
u8 buf [ 4 ] ;
2006-01-09 15:25:35 -02:00
struct i2c_msg msg =
{ . addr = dev - > core - > pll_addr , . flags = 0 ,
2006-04-18 17:56:10 -03:00
. buf = buf , . len = 4 } ;
2006-01-09 15:25:35 -02:00
int err ;
/* Switch PLL to DVB mode */
err = philips_fmd1216_pll_init ( fe ) ;
if ( err )
return err ;
/* Tune PLL */
2006-04-18 17:56:10 -03:00
dvb_pll_configure ( dev - > core - > pll_desc , buf ,
2006-01-09 15:25:35 -02:00
params - > frequency ,
params - > u . ofdm . bandwidth ) ;
2006-05-14 05:01:31 -03:00
if ( fe - > ops . i2c_gate_ctrl )
fe - > ops . i2c_gate_ctrl ( fe , 1 ) ;
2006-01-09 15:25:35 -02:00
if ( ( err = i2c_transfer ( & dev - > core - > i2c_adap , & msg , 1 ) ) ! = 1 ) {
2006-04-18 17:56:10 -03:00
2006-01-09 15:25:35 -02:00
printk ( KERN_WARNING " cx88-dvb: %s error "
2006-08-08 15:48:08 -03:00
" (addr %02x <- %02x, err = %i) \n " ,
__FUNCTION__ , dev - > core - > pll_addr , buf [ 0 ] , err ) ;
2006-01-09 15:25:35 -02:00
if ( err < 0 )
return err ;
else
return - EREMOTEIO ;
}
return 0 ;
}
static struct mt352_config dntv_live_dvbt_pro_config = {
. demod_address = 0x0f ,
. no_tuner = 1 ,
2006-01-09 18:21:31 -02:00
. demod_init = dntv_live_dvbt_pro_demod_init ,
2006-01-09 15:25:35 -02:00
} ;
# endif
2005-04-16 15:20:36 -07:00
2006-02-28 08:34:59 -03:00
static struct zl10353_config dvico_fusionhdtv_hybrid = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0f ,
2006-04-18 17:56:10 -03:00
. no_tuner = 1 ,
2006-02-28 08:34:59 -03:00
} ;
static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0f ,
2006-02-28 08:34:59 -03:00
} ;
2005-04-16 15:20:36 -07:00
static struct cx22702_config connexant_refboard_config = {
. demod_address = 0x43 ,
2005-07-15 12:20:26 -07:00
. output_mode = CX22702_SERIAL_OUTPUT ,
2005-04-16 15:20:36 -07:00
} ;
static struct cx22702_config hauppauge_novat_config = {
. demod_address = 0x43 ,
2005-07-15 12:20:26 -07:00
. output_mode = CX22702_SERIAL_OUTPUT ,
2005-04-16 15:20:36 -07:00
} ;
2006-01-09 15:25:12 -02:00
static struct cx22702_config hauppauge_hvr1100_config = {
. demod_address = 0x63 ,
. output_mode = CX22702_SERIAL_OUTPUT ,
} ;
2006-12-02 21:15:51 -02:00
static struct cx22702_config hauppauge_hvr3000_config = {
2006-09-14 15:41:13 -03:00
. demod_address = 0x63 ,
. output_mode = CX22702_SERIAL_OUTPUT ,
} ;
2005-04-16 15:20:36 -07:00
2006-12-02 21:15:51 -02:00
static int cx88_dvb_bus_ctrl ( struct dvb_frontend * fe ,
int acquire )
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
struct cx8802_driver * drv = NULL ;
int ret = 0 ;
drv = cx8802_get_driver ( dev , CX88_MPEG_DVB ) ;
if ( drv ) {
if ( acquire )
ret = drv - > request_acquire ( drv ) ;
else
ret = drv - > request_release ( drv ) ;
}
return ret ;
}
static struct cx22702_config hauppauge_hvr1300_config = {
2006-09-30 00:43:58 -03:00
. demod_address = 0x63 ,
2006-12-02 21:15:51 -02:00
. output_mode = CX22702_SERIAL_OUTPUT ,
2006-09-30 00:43:58 -03:00
} ;
2005-04-16 15:20:36 -07:00
static int or51132_set_ts_param ( struct dvb_frontend * fe ,
int is_punctured )
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
dev - > ts_gen_cntrl = is_punctured ? 0x04 : 0x00 ;
return 0 ;
}
2005-05-01 08:59:29 -07:00
static struct or51132_config pchdtv_hd3000 = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x15 ,
. set_ts_params = or51132_set_ts_param ,
2005-04-16 15:20:36 -07:00
} ;
2005-07-27 11:46:00 -07:00
static int lgdt330x_pll_rf_set ( struct dvb_frontend * fe , int index )
2005-07-27 11:45:55 -07:00
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
struct cx88_core * core = dev - > core ;
dprintk ( 1 , " %s: index = %d \n " , __FUNCTION__ , index ) ;
if ( index = = 0 )
cx_clear ( MO_GP0_IO , 8 ) ;
else
cx_set ( MO_GP0_IO , 8 ) ;
return 0 ;
}
2005-07-27 11:46:00 -07:00
static int lgdt330x_set_ts_param ( struct dvb_frontend * fe , int is_punctured )
2005-07-07 17:58:39 -07:00
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
if ( is_punctured )
dev - > ts_gen_cntrl | = 0x04 ;
else
dev - > ts_gen_cntrl & = ~ 0x04 ;
return 0 ;
}
2005-07-27 11:46:00 -07:00
static struct lgdt330x_config fusionhdtv_3_gold = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0e ,
. demod_chip = LGDT3302 ,
. serial_mpeg = 0x04 , /* TPSERIAL for 3302 in TOP_CONTROL */
. set_ts_params = lgdt330x_set_ts_param ,
2005-07-07 17:58:42 -07:00
} ;
2005-09-09 13:03:41 -07:00
static struct lgdt330x_config fusionhdtv_5_gold = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0e ,
. demod_chip = LGDT3303 ,
. serial_mpeg = 0x40 , /* TPSERIAL for 3303 in TOP_CONTROL */
. set_ts_params = lgdt330x_set_ts_param ,
2005-09-09 13:03:41 -07:00
} ;
2006-04-07 02:21:31 -03:00
static struct lgdt330x_config pchdtv_hd5500 = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x59 ,
. demod_chip = LGDT3303 ,
. serial_mpeg = 0x40 , /* TPSERIAL for 3303 in TOP_CONTROL */
. set_ts_params = lgdt330x_set_ts_param ,
2006-04-07 02:21:31 -03:00
} ;
2005-07-07 17:58:39 -07:00
2005-11-08 21:38:18 -08:00
static int nxt200x_set_ts_param ( struct dvb_frontend * fe ,
int is_punctured )
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
dev - > ts_gen_cntrl = is_punctured ? 0x04 : 0x00 ;
return 0 ;
}
2005-11-08 21:38:40 -08:00
static int nxt200x_set_pll_input ( u8 * buf , int input )
{
if ( input )
buf [ 3 ] | = 0x08 ;
else
buf [ 3 ] & = ~ 0x08 ;
return 0 ;
}
2005-11-08 21:38:18 -08:00
static struct nxt200x_config ati_hdtvwonder = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x0a ,
. set_pll_input = nxt200x_set_pll_input ,
. set_ts_params = nxt200x_set_ts_param ,
2005-11-08 21:38:18 -08:00
} ;
2006-01-09 15:25:02 -02:00
static int cx24123_set_ts_param ( struct dvb_frontend * fe ,
int is_punctured )
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
2006-08-08 15:48:08 -03:00
dev - > ts_gen_cntrl = 0x02 ;
2006-01-09 15:25:02 -02:00
return 0 ;
}
2006-08-08 15:48:08 -03:00
static int kworld_dvbs_100_set_voltage ( struct dvb_frontend * fe ,
fe_sec_voltage_t voltage )
2006-01-09 15:25:02 -02:00
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
struct cx88_core * core = dev - > core ;
2006-05-12 20:31:51 -03:00
if ( voltage = = SEC_VOLTAGE_OFF ) {
2006-08-08 15:48:08 -03:00
cx_write ( MO_GP0_IO , 0x000006fb ) ;
2006-05-12 20:31:51 -03:00
} else {
cx_write ( MO_GP0_IO , 0x000006f9 ) ;
}
if ( core - > prev_set_voltage )
return core - > prev_set_voltage ( fe , voltage ) ;
return 0 ;
2006-01-09 15:25:02 -02:00
}
2006-08-08 15:48:08 -03:00
static int geniatech_dvbs_set_voltage ( struct dvb_frontend * fe ,
fe_sec_voltage_t voltage )
2006-06-29 20:29:33 -03:00
{
struct cx8802_dev * dev = fe - > dvb - > priv ;
struct cx88_core * core = dev - > core ;
if ( voltage = = SEC_VOLTAGE_OFF ) {
dprintk ( 1 , " LNB Voltage OFF \n " ) ;
cx_write ( MO_GP0_IO , 0x0000efff ) ;
}
if ( core - > prev_set_voltage )
return core - > prev_set_voltage ( fe , voltage ) ;
return 0 ;
}
static struct cx24123_config geniatech_dvbs_config = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x55 ,
. set_ts_params = cx24123_set_ts_param ,
2006-06-29 20:29:33 -03:00
} ;
2006-01-09 15:25:02 -02:00
static struct cx24123_config hauppauge_novas_config = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x55 ,
. set_ts_params = cx24123_set_ts_param ,
2006-01-09 15:25:02 -02:00
} ;
static struct cx24123_config kworld_dvbs_100_config = {
2006-08-08 15:48:08 -03:00
. demod_address = 0x15 ,
. set_ts_params = cx24123_set_ts_param ,
2006-09-26 12:30:14 -03:00
. lnb_polarity = 1 ,
2006-01-09 15:25:02 -02:00
} ;
2005-04-16 15:20:36 -07:00
static int dvb_register ( struct cx8802_dev * dev )
{
/* init struct videobuf_dvb */
dev - > dvb . name = dev - > core - > name ;
dev - > ts_gen_cntrl = 0x0c ;
/* init frontend */
switch ( dev - > core - > board ) {
case CX88_BOARD_HAUPPAUGE_DVB_T1 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx22702_attach ,
& hauppauge_novat_config ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
& dev - > core - > i2c_adap ,
& dvb_pll_thomson_dtt759x ) ;
2006-04-18 17:56:10 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
2005-07-07 17:58:40 -07:00
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 :
2005-04-16 15:20:36 -07:00
case CX88_BOARD_CONEXANT_DVB_T1 :
2006-01-09 15:32:45 -02:00
case CX88_BOARD_KWORLD_DVB_T_CX22702 :
2005-11-08 21:37:22 -08:00
case CX88_BOARD_WINFAST_DTV1000 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx22702_attach ,
& connexant_refboard_config ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x60 ,
2006-08-08 15:48:08 -03:00
& dev - > core - > i2c_adap ,
& dvb_pll_thomson_dtt7579 ) ;
2006-04-18 17:56:10 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
2006-05-29 13:51:59 -03:00
case CX88_BOARD_WINFAST_DTV2000H :
2006-01-09 15:25:12 -02:00
case CX88_BOARD_HAUPPAUGE_HVR1100 :
case CX88_BOARD_HAUPPAUGE_HVR1100LP :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx22702_attach ,
& hauppauge_hvr1100_config ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
& dev - > core - > i2c_adap ,
& dvb_pll_fmd1216me ) ;
2006-04-18 17:56:10 -03:00
}
2006-01-09 15:25:12 -02:00
break ;
2006-02-28 08:34:59 -03:00
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( mt352_attach ,
& dvico_fusionhdtv ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x60 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_thomson_dtt7579 ) ;
2006-02-28 08:34:59 -03:00
break ;
2006-04-18 17:56:10 -03:00
}
2006-02-28 08:34:59 -03:00
/* ZL10353 replaces MT352 on later cards */
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( zl10353_attach ,
& dvico_fusionhdtv_plus_v1_1 ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x60 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_thomson_dtt7579 ) ;
2006-04-18 17:56:10 -03:00
}
2006-06-12 14:06:22 -03:00
break ;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL :
/* The tin box says DEE1601, but it seems to be DTT7579
* compatible , with a slightly different MT352 AGC gain . */
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( mt352_attach ,
& dvico_fusionhdtv_dual ,
& dev - > core - > i2c_adap ) ;
2006-06-12 14:06:22 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_thomson_dtt7579 ) ;
2006-06-12 14:06:22 -03:00
break ;
}
/* ZL10353 replaces MT352 on later cards */
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( zl10353_attach ,
& dvico_fusionhdtv_plus_v1_1 ,
& dev - > core - > i2c_adap ) ;
2006-06-12 14:06:22 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_thomson_dtt7579 ) ;
2006-06-12 14:06:22 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
2006-02-28 08:34:59 -03:00
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( mt352_attach ,
& dvico_fusionhdtv ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_lg_z201 ) ;
2006-04-18 17:56:10 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
case CX88_BOARD_KWORLD_DVB_T :
case CX88_BOARD_DNTV_LIVE_DVB_T :
2005-07-07 17:58:36 -07:00
case CX88_BOARD_ADSTECH_DVB_T_PCI :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( mt352_attach ,
& dntv_live_dvbt_config ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_unknown_1 ) ;
2006-04-18 17:56:10 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
2006-01-09 15:25:35 -02:00
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO :
# ifdef HAVE_VP3054_I2C
dev - > core - > pll_addr = 0x61 ;
dev - > core - > pll_desc = & dvb_pll_fmd1216me ;
2006-08-08 09:10:08 -03:00
dev - > dvb . frontend = dvb_attach ( mt352_attach , & dntv_live_dvbt_pro_config ,
2006-01-09 15:25:35 -02:00
& ( ( struct vp3054_i2c_state * ) dev - > card_priv ) - > adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-05-14 05:01:31 -03:00
dev - > dvb . frontend - > ops . tuner_ops . set_params = dntv_live_dvbt_pro_tuner_set_params ;
2006-04-18 17:56:10 -03:00
}
2006-01-09 15:25:35 -02:00
# else
printk ( " %s: built without vp3054 support \n " , dev - > core - > name ) ;
# endif
break ;
2006-02-28 08:34:59 -03:00
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( zl10353_attach ,
& dvico_fusionhdtv_hybrid ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-12-05 01:21:19 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
& dev - > core - > i2c_adap ,
& dvb_pll_thomson_fe6600 ) ;
2006-04-18 17:56:10 -03:00
}
2006-02-28 08:34:59 -03:00
break ;
2005-04-16 15:20:36 -07:00
case CX88_BOARD_PCHDTV_HD3000 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( or51132_attach ,
& pchdtv_hd3000 ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
& dev - > core - > i2c_adap ,
& dvb_pll_thomson_dtt761x ) ;
2006-04-18 17:56:10 -03:00
}
2005-04-16 15:20:36 -07:00
break ;
2005-07-07 17:58:39 -07:00
case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q :
dev - > ts_gen_cntrl = 0x08 ;
{
/* Do a hardware reset of chip before using it. */
struct cx88_core * core = dev - > core ;
cx_clear ( MO_GP0_IO , 1 ) ;
mdelay ( 100 ) ;
2005-07-27 11:45:55 -07:00
cx_set ( MO_GP0_IO , 1 ) ;
2005-07-07 17:58:39 -07:00
mdelay ( 200 ) ;
2005-07-27 11:45:55 -07:00
/* Select RF connector callback */
2005-07-27 11:46:00 -07:00
fusionhdtv_3_gold . pll_rf_set = lgdt330x_pll_rf_set ;
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( lgdt330x_attach ,
& fusionhdtv_3_gold ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-12-05 01:01:39 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
& dev - > core - > i2c_adap ,
& dvb_pll_microtune_4042 ) ;
2006-04-18 17:56:10 -03:00
}
2005-07-07 17:58:39 -07:00
}
break ;
2005-07-07 17:58:42 -07:00
case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T :
dev - > ts_gen_cntrl = 0x08 ;
{
/* Do a hardware reset of chip before using it. */
struct cx88_core * core = dev - > core ;
cx_clear ( MO_GP0_IO , 1 ) ;
mdelay ( 100 ) ;
2005-07-27 11:45:56 -07:00
cx_set ( MO_GP0_IO , 9 ) ;
2005-07-07 17:58:42 -07:00
mdelay ( 200 ) ;
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( lgdt330x_attach ,
& fusionhdtv_3_gold ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-12-05 01:01:39 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
& dev - > core - > i2c_adap ,
& dvb_pll_thomson_dtt761x ) ;
2006-04-18 17:56:10 -03:00
}
2005-07-07 17:58:42 -07:00
}
break ;
2005-09-09 13:03:41 -07:00
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD :
dev - > ts_gen_cntrl = 0x08 ;
{
/* Do a hardware reset of chip before using it. */
struct cx88_core * core = dev - > core ;
cx_clear ( MO_GP0_IO , 1 ) ;
mdelay ( 100 ) ;
cx_set ( MO_GP0_IO , 1 ) ;
mdelay ( 200 ) ;
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( lgdt330x_attach ,
& fusionhdtv_5_gold ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-11-19 19:45:26 -03:00
dvb_attach ( lgh06xf_attach , dev - > dvb . frontend ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
}
2005-09-09 13:03:41 -07:00
}
break ;
2006-04-07 02:21:31 -03:00
case CX88_BOARD_PCHDTV_HD5500 :
dev - > ts_gen_cntrl = 0x08 ;
{
/* Do a hardware reset of chip before using it. */
struct cx88_core * core = dev - > core ;
cx_clear ( MO_GP0_IO , 1 ) ;
mdelay ( 100 ) ;
cx_set ( MO_GP0_IO , 1 ) ;
mdelay ( 200 ) ;
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( lgdt330x_attach ,
& pchdtv_hd5500 ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-11-19 19:45:26 -03:00
dvb_attach ( lgh06xf_attach , dev - > dvb . frontend ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
}
2006-04-07 02:21:31 -03:00
}
break ;
2005-11-08 21:38:18 -08:00
case CX88_BOARD_ATI_HDTVWONDER :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( nxt200x_attach ,
& ati_hdtvwonder ,
& dev - > core - > i2c_adap ) ;
2006-04-18 17:56:10 -03:00
if ( dev - > dvb . frontend ! = NULL ) {
2006-08-08 09:10:08 -03:00
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
2006-08-08 15:48:08 -03:00
NULL , & dvb_pll_tuv1236d ) ;
2006-04-18 17:56:10 -03:00
}
2006-01-09 15:25:02 -02:00
break ;
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 :
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx24123_attach ,
& hauppauge_novas_config ,
& dev - > core - > i2c_adap ) ;
2006-05-12 20:31:51 -03:00
if ( dev - > dvb . frontend ) {
2006-08-08 15:48:08 -03:00
dvb_attach ( isl6421_attach , dev - > dvb . frontend ,
& dev - > core - > i2c_adap , 0x08 , 0x00 , 0x00 ) ;
2006-05-12 20:31:51 -03:00
}
2006-01-09 15:25:02 -02:00
break ;
case CX88_BOARD_KWORLD_DVBS_100 :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx24123_attach ,
& kworld_dvbs_100_config ,
& dev - > core - > i2c_adap ) ;
2006-05-12 20:31:51 -03:00
if ( dev - > dvb . frontend ) {
2006-05-14 05:01:31 -03:00
dev - > core - > prev_set_voltage = dev - > dvb . frontend - > ops . set_voltage ;
dev - > dvb . frontend - > ops . set_voltage = kworld_dvbs_100_set_voltage ;
2006-05-12 20:31:51 -03:00
}
2005-11-08 21:38:18 -08:00
break ;
2006-06-29 20:29:33 -03:00
case CX88_BOARD_GENIATECH_DVBS :
2006-08-08 15:48:08 -03:00
dev - > dvb . frontend = dvb_attach ( cx24123_attach ,
& geniatech_dvbs_config ,
& dev - > core - > i2c_adap ) ;
2006-06-29 20:29:33 -03:00
if ( dev - > dvb . frontend ) {
dev - > core - > prev_set_voltage = dev - > dvb . frontend - > ops . set_voltage ;
dev - > dvb . frontend - > ops . set_voltage = geniatech_dvbs_set_voltage ;
}
break ;
2006-12-02 21:15:51 -02:00
case CX88_BOARD_HAUPPAUGE_HVR1300 :
dev - > dvb . frontend = dvb_attach ( cx22702_attach ,
& hauppauge_hvr1300_config ,
& dev - > core - > i2c_adap ) ;
if ( dev - > dvb . frontend ! = NULL ) {
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
& dev - > core - > i2c_adap ,
& dvb_pll_fmd1216me ) ;
}
break ;
case CX88_BOARD_HAUPPAUGE_HVR3000 :
dev - > dvb . frontend = dvb_attach ( cx22702_attach ,
& hauppauge_hvr3000_config ,
& dev - > core - > i2c_adap ) ;
if ( dev - > dvb . frontend ! = NULL ) {
dvb_attach ( dvb_pll_attach , dev - > dvb . frontend , 0x61 ,
& dev - > core - > i2c_adap ,
& dvb_pll_fmd1216me ) ;
}
break ;
2005-04-16 15:20:36 -07:00
default :
2005-05-01 08:59:19 -07:00
printk ( " %s: The frontend of your DVB/ATSC card isn't supported yet \n " ,
dev - > core - > name ) ;
2005-04-16 15:20:36 -07:00
break ;
}
if ( NULL = = dev - > dvb . frontend ) {
printk ( " %s: frontend initialization failed \n " , dev - > core - > name ) ;
return - 1 ;
}
if ( dev - > core - > pll_desc ) {
2006-05-14 05:01:31 -03:00
dev - > dvb . frontend - > ops . info . frequency_min = dev - > core - > pll_desc - > min ;
dev - > dvb . frontend - > ops . info . frequency_max = dev - > core - > pll_desc - > max ;
2005-04-16 15:20:36 -07:00
}
2006-12-02 21:15:51 -02:00
/* Ensure all frontends negotiate bus access */
dev - > dvb . frontend - > ops . ts_bus_ctrl = cx88_dvb_bus_ctrl ;
2005-04-16 15:20:36 -07:00
2005-09-13 01:25:42 -07:00
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients ( dev - > core , TUNER_SET_STANDBY , NULL ) ;
2005-04-16 15:20:36 -07:00
/* register everything */
2006-04-10 09:27:37 -03:00
return videobuf_dvb_register ( & dev - > dvb , THIS_MODULE , dev , & dev - > pci - > dev ) ;
2005-04-16 15:20:36 -07:00
}
/* ----------------------------------------------------------- */
2006-12-02 21:15:51 -02:00
/* CX8802 MPEG -> mini driver - We have been given the hardware */
static int cx8802_dvb_advise_acquire ( struct cx8802_driver * drv )
2005-04-16 15:20:36 -07:00
{
2006-12-02 21:15:51 -02:00
struct cx88_core * core = drv - > core ;
int err = 0 ;
dprintk ( 1 , " %s \n " , __FUNCTION__ ) ;
switch ( core - > board ) {
case CX88_BOARD_HAUPPAUGE_HVR1300 :
/* We arrive here with either the cx23416 or the cx22702
* on the bus . Take the bus from the cx23416 and enable the
* cx22702 demod
*/
cx_set ( MO_GP0_IO , 0x00000080 ) ; /* cx22702 out of reset and enable */
cx_clear ( MO_GP0_IO , 0x00000004 ) ;
udelay ( 1000 ) ;
break ;
default :
err = - ENODEV ;
}
return err ;
}
/* CX8802 MPEG -> mini driver - We no longer have the hardware */
static int cx8802_dvb_advise_release ( struct cx8802_driver * drv )
{
struct cx88_core * core = drv - > core ;
int err = 0 ;
dprintk ( 1 , " %s \n " , __FUNCTION__ ) ;
switch ( core - > board ) {
case CX88_BOARD_HAUPPAUGE_HVR1300 :
/* Do Nothing, leave the cx22702 on the bus. */
break ;
default :
err = - ENODEV ;
}
return err ;
}
static int cx8802_dvb_probe ( struct cx8802_driver * drv )
{
struct cx88_core * core = drv - > core ;
struct cx8802_dev * dev = drv - > core - > dvbdev ;
2005-04-16 15:20:36 -07:00
int err ;
2006-12-02 21:15:51 -02:00
dprintk ( 1 , " %s \n " , __FUNCTION__ ) ;
dprintk ( 1 , " ->being probed by Card=%d Name=%s, PCI %02x:%02x \n " ,
core - > board ,
core - > name ,
core - > pci_bus ,
core - > pci_slot ) ;
2005-04-16 15:20:36 -07:00
err = - ENODEV ;
2006-09-25 14:09:10 -03:00
if ( ! ( cx88_boards [ core - > board ] . mpeg & CX88_MPEG_DVB ) )
2005-04-16 15:20:36 -07:00
goto fail_core ;
2006-01-09 15:25:35 -02:00
# ifdef HAVE_VP3054_I2C
err = vp3054_i2c_probe ( dev ) ;
if ( 0 ! = err )
2006-12-02 21:15:51 -02:00
goto fail_core ;
2006-01-09 15:25:35 -02:00
# endif
2005-04-16 15:20:36 -07:00
/* dvb stuff */
printk ( " %s/2: cx2388x based dvb card \n " , core - > name ) ;
videobuf_queue_init ( & dev - > dvb . dvbq , & dvb_qops ,
dev - > pci , & dev - > slock ,
V4L2_BUF_TYPE_VIDEO_CAPTURE ,
V4L2_FIELD_TOP ,
sizeof ( struct cx88_buffer ) ,
dev ) ;
err = dvb_register ( dev ) ;
2006-12-02 21:15:51 -02:00
if ( err ! = 0 )
printk ( " %s dvb_register failed err = %d \n " , __FUNCTION__ , err ) ;
2005-04-16 15:20:36 -07:00
fail_core :
return err ;
}
2006-12-02 21:15:51 -02:00
static int cx8802_dvb_remove ( struct cx8802_driver * drv )
2005-04-16 15:20:36 -07:00
{
2006-12-02 21:15:51 -02:00
struct cx8802_dev * dev = drv - > core - > dvbdev ;
2006-01-09 15:25:12 -02:00
2005-04-16 15:20:36 -07:00
/* dvb */
videobuf_dvb_unregister ( & dev - > dvb ) ;
2006-01-09 15:25:35 -02:00
# ifdef HAVE_VP3054_I2C
vp3054_i2c_remove ( dev ) ;
# endif
2006-12-02 21:15:51 -02:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
2006-12-02 21:15:51 -02:00
static struct cx8802_driver cx8802_dvb_driver = {
. type_id = CX88_MPEG_DVB ,
. hw_access = CX8802_DRVCTL_SHARED ,
. probe = cx8802_dvb_probe ,
. remove = cx8802_dvb_remove ,
. advise_acquire = cx8802_dvb_advise_acquire ,
. advise_release = cx8802_dvb_advise_release ,
2005-04-16 15:20:36 -07:00
} ;
static int dvb_init ( void )
{
printk ( KERN_INFO " cx2388x dvb driver version %d.%d.%d loaded \n " ,
( CX88_VERSION_CODE > > 16 ) & 0xff ,
( CX88_VERSION_CODE > > 8 ) & 0xff ,
CX88_VERSION_CODE & 0xff ) ;
# ifdef SNAPSHOT
printk ( KERN_INFO " cx2388x: snapshot date %04d-%02d-%02d \n " ,
SNAPSHOT / 10000 , ( SNAPSHOT / 100 ) % 100 , SNAPSHOT % 100 ) ;
# endif
2006-12-02 21:15:51 -02:00
return cx8802_register_driver ( & cx8802_dvb_driver ) ;
2005-04-16 15:20:36 -07:00
}
static void dvb_fini ( void )
{
2006-12-02 21:15:51 -02:00
cx8802_unregister_driver ( & cx8802_dvb_driver ) ;
2005-04-16 15:20:36 -07:00
}
module_init ( dvb_init ) ;
module_exit ( dvb_fini ) ;
/*
* Local variables :
* c - basic - offset : 8
* compile - command : " make DVB=1 "
* End :
*/