2007-03-11 20:44:05 -03:00
/*
* Driver for the Conexant CX23885 PCIe bridge
*
2008-09-03 17:12:12 -03:00
* Copyright ( c ) 2006 Steven Toth < stoth @ linuxtv . org >
2007-03-11 20:44:05 -03:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; 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 "cx23885.h"
# include <media/v4l2-common.h>
# include "s5h1409.h"
2008-07-09 02:18:49 -03:00
# include "s5h1411.h"
2007-03-11 20:44:05 -03:00
# include "mt2131.h"
2007-12-07 01:40:36 -03:00
# include "tda8290.h"
2007-12-24 04:52:08 -03:00
# include "tda18271.h"
2007-09-08 15:17:13 -03:00
# include "lgdt330x.h"
2007-12-18 01:57:06 -03:00
# include "xc5000.h"
2008-04-19 01:14:19 -03:00
# include "tda10048.h"
2007-12-18 01:09:11 -03:00
# include "tuner-xc2028.h"
2008-04-22 14:46:16 -03:00
# include "tuner-simple.h"
2008-04-22 15:38:26 -03:00
# include "dib7000p.h"
# include "dibx000_common.h"
2008-08-04 21:39:53 -03:00
# include "zl10353.h"
2009-01-17 12:11:20 -03:00
# include "cx24116.h"
2007-03-11 20:44:05 -03:00
2008-01-12 11:36:36 -03:00
static unsigned int debug ;
2007-03-11 20:44:05 -03:00
2008-01-12 11:36:36 -03:00
# define dprintk(level, fmt, arg...)\
do { if ( debug > = level ) \
printk ( KERN_DEBUG " %s/0: " fmt , dev - > name , # # arg ) ; \
} while ( 0 )
2007-03-11 20:44:05 -03:00
/* ------------------------------------------------------------------ */
2007-12-07 01:40:36 -03:00
static unsigned int alt_tuner ;
module_param ( alt_tuner , int , 0644 ) ;
MODULE_PARM_DESC ( alt_tuner , " Enable alternate tuner configuration " ) ;
2008-04-09 19:13:13 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2007-12-07 01:40:36 -03:00
/* ------------------------------------------------------------------ */
2007-03-11 20:44:05 -03:00
static int dvb_buf_setup ( struct videobuf_queue * q ,
unsigned int * count , unsigned int * size )
{
struct cx23885_tsport * port = q - > priv_data ;
port - > ts_packet_size = 188 * 4 ;
port - > ts_packet_count = 32 ;
* size = port - > ts_packet_size * port - > ts_packet_count ;
* count = 32 ;
return 0 ;
}
2007-03-20 23:00:18 -03:00
static int dvb_buf_prepare ( struct videobuf_queue * q ,
struct videobuf_buffer * vb , enum v4l2_field field )
2007-03-11 20:44:05 -03:00
{
struct cx23885_tsport * port = q - > priv_data ;
2008-10-16 20:18:44 -03:00
return cx23885_buf_prepare ( q , port , ( struct cx23885_buffer * ) vb , field ) ;
2007-03-11 20:44:05 -03:00
}
static void dvb_buf_queue ( struct videobuf_queue * q , struct videobuf_buffer * vb )
{
struct cx23885_tsport * port = q - > priv_data ;
2008-10-16 20:18:44 -03:00
cx23885_buf_queue ( port , ( struct cx23885_buffer * ) vb ) ;
2007-03-11 20:44:05 -03:00
}
2007-03-20 23:00:18 -03:00
static void dvb_buf_release ( struct videobuf_queue * q ,
struct videobuf_buffer * vb )
2007-03-11 20:44:05 -03:00
{
2008-10-16 20:18:44 -03:00
cx23885_free_buffer ( q , ( struct cx23885_buffer * ) vb ) ;
2007-03-11 20:44:05 -03:00
}
static struct videobuf_queue_ops dvb_qops = {
. buf_setup = dvb_buf_setup ,
. buf_prepare = dvb_buf_prepare ,
. buf_queue = dvb_buf_queue ,
. buf_release = dvb_buf_release ,
} ;
2007-09-04 21:40:47 -03:00
static struct s5h1409_config hauppauge_generic_config = {
2007-09-08 19:08:17 -03:00
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_ON ,
2007-12-13 10:04:10 -03:00
. qam_if = 44000 ,
2007-09-08 19:08:17 -03:00
. inversion = S5H1409_INVERSION_OFF ,
2008-01-15 21:35:22 -03:00
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
2007-09-08 19:08:17 -03:00
} ;
2008-04-19 01:14:19 -03:00
static struct tda10048_config hauppauge_hvr1200_config = {
. demod_address = 0x10 > > 1 ,
. output_mode = TDA10048_SERIAL_OUTPUT ,
. fwbulkwritelen = TDA10048_BULKWRITE_200 ,
. inversion = TDA10048_INVERSION_ON
} ;
2007-12-07 01:40:36 -03:00
static struct s5h1409_config hauppauge_ezqam_config = {
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_OFF ,
. qam_if = 4000 ,
. inversion = S5H1409_INVERSION_ON ,
2008-01-15 21:35:22 -03:00
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
2007-12-07 01:40:36 -03:00
} ;
2007-09-08 19:08:17 -03:00
static struct s5h1409_config hauppauge_hvr1800lp_config = {
2007-03-11 20:44:05 -03:00
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_OFF ,
2007-12-13 10:04:10 -03:00
. qam_if = 44000 ,
2007-03-20 15:27:53 -03:00
. inversion = S5H1409_INVERSION_OFF ,
2008-01-15 21:35:22 -03:00
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
2007-03-11 20:44:05 -03:00
} ;
2007-12-18 01:09:11 -03:00
static struct s5h1409_config hauppauge_hvr1500_config = {
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_OFF ,
. inversion = S5H1409_INVERSION_OFF ,
2008-01-15 21:35:22 -03:00
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
2007-12-18 01:09:11 -03:00
} ;
2007-09-04 21:40:47 -03:00
static struct mt2131_config hauppauge_generic_tunerconfig = {
2007-08-22 21:01:20 -03:00
0x61
} ;
2007-09-08 15:17:13 -03:00
static struct lgdt330x_config fusionhdtv_5_express = {
. demod_address = 0x0e ,
. demod_chip = LGDT3303 ,
. serial_mpeg = 0x40 ,
} ;
2007-12-18 01:57:06 -03:00
static struct s5h1409_config hauppauge_hvr1500q_config = {
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_ON ,
. qam_if = 44000 ,
. inversion = S5H1409_INVERSION_OFF ,
2008-01-15 21:35:22 -03:00
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
2007-12-18 01:57:06 -03:00
} ;
2008-05-07 01:43:10 -03:00
static struct s5h1409_config dvico_s5h1409_config = {
. demod_address = 0x32 > > 1 ,
. output_mode = S5H1409_SERIAL_OUTPUT ,
. gpio = S5H1409_GPIO_ON ,
. qam_if = 44000 ,
. inversion = S5H1409_INVERSION_OFF ,
. status_mode = S5H1409_DEMODLOCKING ,
. mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
} ;
2008-07-09 02:18:49 -03:00
static struct s5h1411_config dvico_s5h1411_config = {
. output_mode = S5H1411_SERIAL_OUTPUT ,
. gpio = S5H1411_GPIO_ON ,
. qam_if = S5H1411_IF_44000 ,
. vsb_if = S5H1411_IF_44000 ,
. inversion = S5H1411_INVERSION_OFF ,
. status_mode = S5H1411_DEMODLOCKING ,
. mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK ,
} ;
2007-12-18 01:57:06 -03:00
static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
2007-12-20 01:14:43 -03:00
. i2c_address = 0x61 ,
. if_khz = 5380 ,
2007-12-18 01:57:06 -03:00
} ;
2008-05-07 01:43:10 -03:00
static struct xc5000_config dvico_xc5000_tunerconfig = {
. i2c_address = 0x64 ,
. if_khz = 5380 ,
} ;
2007-12-24 04:52:08 -03:00
static struct tda829x_config tda829x_no_probe = {
. probe_tuner = TDA829X_DONT_PROBE ,
} ;
2008-01-02 03:01:54 -03:00
static struct tda18271_std_map hauppauge_tda18271_std_map = {
2008-04-22 14:46:22 -03:00
. atsc_6 = { . if_freq = 5380 , . agc_mode = 3 , . std = 3 ,
. if_lvl = 6 , . rfagc_top = 0x37 } ,
. qam_6 = { . if_freq = 4000 , . agc_mode = 3 , . std = 0 ,
. if_lvl = 6 , . rfagc_top = 0x37 } ,
2008-01-02 03:01:54 -03:00
} ;
static struct tda18271_config hauppauge_tda18271_config = {
. std_map = & hauppauge_tda18271_std_map ,
. gate = TDA18271_GATE_ANALOG ,
} ;
2008-04-19 01:14:19 -03:00
static struct tda18271_config hauppauge_hvr1200_tuner_config = {
. gate = TDA18271_GATE_ANALOG ,
} ;
2008-04-25 19:03:08 -07:00
static struct dibx000_agc_config xc3028_agc_config = {
2008-04-22 15:38:26 -03:00
BAND_VHF | BAND_UHF , /* band_caps */
/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
* P_agc_inv_pwm1 = 0 , P_agc_inv_pwm2 = 0 ,
* P_agc_inh_dc_rv_est = 0 , P_agc_time_est = 3 , P_agc_freeze = 0 ,
* P_agc_nb_est = 2 , P_agc_write = 0
*/
( 0 < < 15 ) | ( 0 < < 14 ) | ( 0 < < 11 ) | ( 0 < < 10 ) | ( 0 < < 9 ) | ( 0 < < 8 ) |
( 3 < < 5 ) | ( 0 < < 4 ) | ( 2 < < 1 ) | ( 0 < < 0 ) , /* setup */
712 , /* inv_gain */
21 , /* time_stabiliz */
0 , /* alpha_level */
118 , /* thlock */
0 , /* wbd_inv */
2867 , /* wbd_ref */
0 , /* wbd_sel */
2 , /* wbd_alpha */
0 , /* agc1_max */
0 , /* agc1_min */
39718 , /* agc2_max */
9930 , /* agc2_min */
0 , /* agc1_pt1 */
0 , /* agc1_pt2 */
0 , /* agc1_pt3 */
0 , /* agc1_slope1 */
0 , /* agc1_slope2 */
0 , /* agc2_pt1 */
128 , /* agc2_pt2 */
29 , /* agc2_slope1 */
29 , /* agc2_slope2 */
17 , /* alpha_mant */
27 , /* alpha_exp */
23 , /* beta_mant */
51 , /* beta_exp */
1 , /* perform_agc_softsplit */
} ;
/* PLL Configuration for COFDM BW_MHz = 8.000000
* With external clock = 30.000000 */
2008-04-25 19:03:08 -07:00
static struct dibx000_bandwidth_config xc3028_bw_config = {
2008-04-22 15:38:26 -03:00
60000 , /* internal */
30000 , /* sampling */
1 , /* pll_cfg: prediv */
8 , /* pll_cfg: ratio */
3 , /* pll_cfg: range */
1 , /* pll_cfg: reset */
0 , /* pll_cfg: bypass */
0 , /* misc: refdiv */
0 , /* misc: bypclk_div */
1 , /* misc: IO_CLK_en_core */
1 , /* misc: ADClkSrc */
0 , /* misc: modulo */
( 3 < < 14 ) | ( 1 < < 12 ) | ( 524 < < 0 ) , /* sad_cfg: refsel, sel, freq_15k */
( 1 < < 25 ) | 5816102 , /* ifreq = 5.200000 MHz */
20452225 , /* timf */
30000000 /* xtal_hz */
} ;
static struct dib7000p_config hauppauge_hvr1400_dib7000_config = {
. output_mpeg2_in_188_bytes = 1 ,
. hostbus_diversity = 1 ,
. tuner_is_baseband = 0 ,
. update_lna = NULL ,
. agc_config_count = 1 ,
. agc = & xc3028_agc_config ,
. bw = & xc3028_bw_config ,
. gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS ,
. gpio_val = DIB7000P_GPIO_DEFAULT_VALUES ,
. gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS ,
. pwm_freq_div = 0 ,
. agc_control = NULL ,
. spur_protect = 0 ,
. output_mode = OUTMODE_MPEG2_SERIAL ,
} ;
2008-08-04 21:39:53 -03:00
static struct zl10353_config dvico_fusionhdtv_xc3028 = {
. demod_address = 0x0f ,
. if2 = 45600 ,
. no_tuner = 1 ,
} ;
2009-01-17 12:11:20 -03:00
static int tbs_set_voltage ( struct dvb_frontend * fe , fe_sec_voltage_t voltage )
{
struct cx23885_tsport * port = fe - > dvb - > priv ;
struct cx23885_dev * dev = port - > dev ;
if ( voltage = = SEC_VOLTAGE_18 )
cx_write ( MC417_RWD , 0x00001e00 ) ; /* GPIO-13 high */
else if ( voltage = = SEC_VOLTAGE_13 )
cx_write ( MC417_RWD , 0x00001a00 ) ; /* GPIO-13 low */
else
cx_write ( MC417_RWD , 0x00001800 ) ; /* GPIO-12 low */
return 0 ;
}
static struct cx24116_config tbs_cx24116_config = {
. demod_address = 0x05 ,
} ;
2009-01-17 12:18:26 -03:00
static struct cx24116_config tevii_cx24116_config = {
. demod_address = 0x55 ,
} ;
2007-03-11 20:44:05 -03:00
static int dvb_register ( struct cx23885_tsport * port )
{
struct cx23885_dev * dev = port - > dev ;
2007-09-09 03:55:34 -03:00
struct cx23885_i2c * i2c_bus = NULL ;
2008-10-11 11:05:50 -03:00
struct videobuf_dvb_frontend * fe0 ;
2008-10-11 11:24:30 -03:00
/* Get the first frontend */
2008-10-11 11:18:53 -03:00
fe0 = videobuf_dvb_get_frontend ( & port - > frontends , 1 ) ;
2008-10-11 11:05:50 -03:00
if ( ! fe0 )
return - EINVAL ;
2007-03-11 20:44:05 -03:00
/* init struct videobuf_dvb */
2008-10-11 11:05:50 -03:00
fe0 - > dvb . name = dev - > name ;
2007-03-11 20:44:05 -03:00
/* init frontend */
switch ( dev - > board ) {
2007-08-22 21:01:20 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1250 :
2007-09-09 03:55:34 -03:00
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( s5h1409_attach ,
2007-09-04 21:40:47 -03:00
& hauppauge_generic_config ,
2007-09-09 03:55:34 -03:00
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
dvb_attach ( mt2131_attach , fe0 - > dvb . frontend ,
2007-09-09 03:55:34 -03:00
& i2c_bus - > i2c_adap ,
2007-09-04 21:40:47 -03:00
& hauppauge_generic_tunerconfig , 0 ) ;
2007-03-11 20:44:05 -03:00
}
break ;
2007-12-07 01:40:36 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1800 :
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:18:53 -03:00
switch ( alt_tuner ) {
2007-12-07 01:40:36 -03:00
case 1 :
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend =
2007-12-07 01:40:36 -03:00
dvb_attach ( s5h1409_attach ,
& hauppauge_ezqam_config ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
dvb_attach ( tda829x_attach , fe0 - > dvb . frontend ,
2007-12-07 01:40:36 -03:00
& dev - > i2c_bus [ 1 ] . i2c_adap , 0x42 ,
2007-12-24 04:52:08 -03:00
& tda829x_no_probe ) ;
2008-10-11 11:05:50 -03:00
dvb_attach ( tda18271_attach , fe0 - > dvb . frontend ,
2007-12-24 04:52:08 -03:00
0x60 , & dev - > i2c_bus [ 1 ] . i2c_adap ,
2008-01-02 03:01:54 -03:00
& hauppauge_tda18271_config ) ;
2007-12-07 01:40:36 -03:00
}
break ;
case 0 :
default :
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend =
2007-12-07 01:40:36 -03:00
dvb_attach ( s5h1409_attach ,
& hauppauge_generic_config ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL )
dvb_attach ( mt2131_attach , fe0 - > dvb . frontend ,
2007-12-07 01:40:36 -03:00
& i2c_bus - > i2c_adap ,
& hauppauge_generic_tunerconfig , 0 ) ;
break ;
}
break ;
2007-09-08 19:08:17 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1800lp :
2007-09-09 03:55:34 -03:00
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( s5h1409_attach ,
2007-09-08 19:08:17 -03:00
& hauppauge_hvr1800lp_config ,
2007-09-09 03:55:34 -03:00
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
dvb_attach ( mt2131_attach , fe0 - > dvb . frontend ,
2007-09-09 03:55:34 -03:00
& i2c_bus - > i2c_adap ,
2007-09-08 19:08:17 -03:00
& hauppauge_generic_tunerconfig , 0 ) ;
}
break ;
2007-09-08 15:17:13 -03:00
case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP :
2007-09-09 03:55:34 -03:00
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( lgdt330x_attach ,
2007-09-08 15:17:13 -03:00
& fusionhdtv_5_express ,
2007-09-09 03:55:34 -03:00
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
dvb_attach ( simple_tuner_attach , fe0 - > dvb . frontend ,
2008-04-22 14:46:16 -03:00
& i2c_bus - > i2c_adap , 0x61 ,
TUNER_LG_TDVS_H06XF ) ;
2007-09-08 15:17:13 -03:00
}
break ;
2007-12-18 01:57:06 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1500Q :
i2c_bus = & dev - > i2c_bus [ 1 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( s5h1409_attach ,
2007-12-18 01:57:06 -03:00
& hauppauge_hvr1500q_config ,
& dev - > i2c_bus [ 0 ] . i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL )
dvb_attach ( xc5000_attach , fe0 - > dvb . frontend ,
2008-09-06 14:56:58 -03:00
& i2c_bus - > i2c_adap ,
& hauppauge_hvr1500q_tunerconfig ) ;
2007-12-18 01:57:06 -03:00
break ;
2007-12-18 01:09:11 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1500 :
i2c_bus = & dev - > i2c_bus [ 1 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( s5h1409_attach ,
2007-12-18 01:09:11 -03:00
& hauppauge_hvr1500_config ,
& dev - > i2c_bus [ 0 ] . i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
2007-12-18 01:09:11 -03:00
struct dvb_frontend * fe ;
struct xc2028_config cfg = {
. i2c_adap = & i2c_bus - > i2c_adap ,
. i2c_addr = 0x61 ,
} ;
static struct xc2028_ctrl ctl = {
2008-09-16 02:15:30 -03:00
. fname = XC2028_DEFAULT_FIRMWARE ,
2007-12-18 01:09:11 -03:00
. max_len = 64 ,
2008-04-21 06:58:48 -03:00
. scode_table = XC3028_FE_OREN538 ,
2007-12-18 01:09:11 -03:00
} ;
fe = dvb_attach ( xc2028_attach ,
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend , & cfg ) ;
2007-12-18 01:09:11 -03:00
if ( fe ! = NULL & & fe - > ops . tuner_ops . set_config ! = NULL )
fe - > ops . tuner_ops . set_config ( fe , & ctl ) ;
}
break ;
2008-04-19 01:14:19 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1200 :
2008-04-19 01:25:52 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1700 :
2008-04-19 01:14:19 -03:00
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( tda10048_attach ,
2008-04-19 01:14:19 -03:00
& hauppauge_hvr1200_config ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
dvb_attach ( tda829x_attach , fe0 - > dvb . frontend ,
2008-04-19 01:14:19 -03:00
& dev - > i2c_bus [ 1 ] . i2c_adap , 0x42 ,
& tda829x_no_probe ) ;
2008-10-11 11:05:50 -03:00
dvb_attach ( tda18271_attach , fe0 - > dvb . frontend ,
2008-04-19 01:14:19 -03:00
0x60 , & dev - > i2c_bus [ 1 ] . i2c_adap ,
& hauppauge_hvr1200_tuner_config ) ;
}
break ;
2008-04-22 15:38:26 -03:00
case CX23885_BOARD_HAUPPAUGE_HVR1400 :
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( dib7000p_attach ,
2008-04-22 15:38:26 -03:00
& i2c_bus - > i2c_adap ,
0x12 , & hauppauge_hvr1400_dib7000_config ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
2008-04-22 15:38:26 -03:00
struct dvb_frontend * fe ;
struct xc2028_config cfg = {
. i2c_adap = & dev - > i2c_bus [ 1 ] . i2c_adap ,
. i2c_addr = 0x64 ,
} ;
static struct xc2028_ctrl ctl = {
2008-09-16 02:15:30 -03:00
. fname = XC3028L_DEFAULT_FIRMWARE ,
2008-04-22 15:38:26 -03:00
. max_len = 64 ,
. demod = 5000 ,
2008-10-16 20:18:44 -03:00
/* This is true for all demods with
v36 firmware ? */
2008-09-28 02:24:44 -03:00
. type = XC2028_D2633 ,
2008-04-22 15:38:26 -03:00
} ;
fe = dvb_attach ( xc2028_attach ,
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend , & cfg ) ;
2008-04-22 15:38:26 -03:00
if ( fe ! = NULL & & fe - > ops . tuner_ops . set_config ! = NULL )
fe - > ops . tuner_ops . set_config ( fe , & ctl ) ;
}
break ;
2008-05-07 01:43:10 -03:00
case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP :
i2c_bus = & dev - > i2c_bus [ port - > nr - 1 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( s5h1409_attach ,
2008-05-07 01:43:10 -03:00
& dvico_s5h1409_config ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend = = NULL )
fe0 - > dvb . frontend = dvb_attach ( s5h1411_attach ,
2008-07-09 02:18:49 -03:00
& dvico_s5h1411_config ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL )
dvb_attach ( xc5000_attach , fe0 - > dvb . frontend ,
2008-09-06 14:56:58 -03:00
& i2c_bus - > i2c_adap ,
& dvico_xc5000_tunerconfig ) ;
2008-05-07 01:43:10 -03:00
break ;
2008-08-04 21:39:53 -03:00
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP : {
i2c_bus = & dev - > i2c_bus [ port - > nr - 1 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( zl10353_attach ,
2008-08-04 21:39:53 -03:00
& dvico_fusionhdtv_xc3028 ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
2008-08-04 21:39:53 -03:00
struct dvb_frontend * fe ;
struct xc2028_config cfg = {
. i2c_adap = & i2c_bus - > i2c_adap ,
. i2c_addr = 0x61 ,
} ;
static struct xc2028_ctrl ctl = {
2008-09-16 02:15:30 -03:00
. fname = XC2028_DEFAULT_FIRMWARE ,
2008-08-04 21:39:53 -03:00
. max_len = 64 ,
. demod = XC3028_FE_ZARLINK456 ,
} ;
2008-10-11 11:05:50 -03:00
fe = dvb_attach ( xc2028_attach , fe0 - > dvb . frontend ,
2008-08-04 21:39:53 -03:00
& cfg ) ;
if ( fe ! = NULL & & fe - > ops . tuner_ops . set_config ! = NULL )
fe - > ops . tuner_ops . set_config ( fe , & ctl ) ;
}
break ;
}
2008-08-12 13:30:03 -03:00
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H :
2008-11-23 14:11:16 -03:00
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F :
2008-08-12 13:30:03 -03:00
i2c_bus = & dev - > i2c_bus [ 0 ] ;
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend = dvb_attach ( zl10353_attach ,
2008-08-12 13:30:03 -03:00
& dvico_fusionhdtv_xc3028 ,
& i2c_bus - > i2c_adap ) ;
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend ! = NULL ) {
2008-08-12 13:30:03 -03:00
struct dvb_frontend * fe ;
struct xc2028_config cfg = {
. i2c_adap = & dev - > i2c_bus [ 1 ] . i2c_adap ,
. i2c_addr = 0x61 ,
} ;
static struct xc2028_ctrl ctl = {
2008-09-16 02:15:30 -03:00
. fname = XC2028_DEFAULT_FIRMWARE ,
2008-08-12 13:30:03 -03:00
. max_len = 64 ,
. demod = XC3028_FE_ZARLINK456 ,
} ;
2008-10-11 11:05:50 -03:00
fe = dvb_attach ( xc2028_attach , fe0 - > dvb . frontend ,
2008-08-12 13:30:03 -03:00
& cfg ) ;
if ( fe ! = NULL & & fe - > ops . tuner_ops . set_config ! = NULL )
fe - > ops . tuner_ops . set_config ( fe , & ctl ) ;
}
2009-01-17 12:11:20 -03:00
break ;
case CX23885_BOARD_TBS_6920 :
i2c_bus = & dev - > i2c_bus [ 0 ] ;
fe0 - > dvb . frontend = dvb_attach ( cx24116_attach ,
& tbs_cx24116_config ,
& i2c_bus - > i2c_adap ) ;
if ( fe0 - > dvb . frontend ! = NULL )
fe0 - > dvb . frontend - > ops . set_voltage = tbs_set_voltage ;
2009-01-17 12:18:26 -03:00
break ;
case CX23885_BOARD_TEVII_S470 :
i2c_bus = & dev - > i2c_bus [ 1 ] ;
fe0 - > dvb . frontend = dvb_attach ( cx24116_attach ,
& tevii_cx24116_config ,
& i2c_bus - > i2c_adap ) ;
if ( fe0 - > dvb . frontend ! = NULL )
fe0 - > dvb . frontend - > ops . set_voltage = tbs_set_voltage ;
2008-08-12 13:30:03 -03:00
break ;
2007-03-11 20:44:05 -03:00
default :
2008-10-16 20:18:44 -03:00
printk ( KERN_INFO " %s: The frontend of your DVB/ATSC card "
" isn't supported yet \n " ,
2007-03-11 20:44:05 -03:00
dev - > name ) ;
break ;
}
2008-10-11 11:05:50 -03:00
if ( NULL = = fe0 - > dvb . frontend ) {
2008-10-16 20:18:44 -03:00
printk ( KERN_ERR " %s: frontend initialization failed \n " ,
dev - > name ) ;
2007-03-11 20:44:05 -03:00
return - 1 ;
}
2008-09-12 13:31:45 -03:00
/* define general-purpose callback pointer */
2008-10-11 11:05:50 -03:00
fe0 - > dvb . frontend - > callback = cx23885_tuner_callback ;
2007-03-11 20:44:05 -03:00
/* Put the analog decoder in standby to keep it quiet */
2007-09-09 03:55:34 -03:00
cx23885_call_i2c_clients ( i2c_bus , TUNER_SET_STANDBY , NULL ) ;
2007-03-11 20:44:05 -03:00
2008-10-11 11:05:50 -03:00
if ( fe0 - > dvb . frontend - > ops . analog_ops . standby )
fe0 - > dvb . frontend - > ops . analog_ops . standby ( fe0 - > dvb . frontend ) ;
2007-12-07 01:40:36 -03:00
2007-03-11 20:44:05 -03:00
/* register everything */
2008-10-11 11:05:50 -03:00
return videobuf_dvb_register_bus ( & port - > frontends , THIS_MODULE , port ,
2008-10-11 11:44:05 -03:00
& dev - > pci - > dev , adapter_nr , 0 ) ;
2008-10-11 11:05:50 -03:00
2007-03-11 20:44:05 -03:00
}
int cx23885_dvb_register ( struct cx23885_tsport * port )
{
2008-10-11 11:05:50 -03:00
struct videobuf_dvb_frontend * fe0 ;
2007-03-11 20:44:05 -03:00
struct cx23885_dev * dev = port - > dev ;
2008-10-11 12:34:39 -03:00
int err , i ;
/* Here we need to allocate the correct number of frontends,
* as reflected in the cards struct . The reality is that currrently
* no cx23885 boards support this - yet . But , if we don ' t modify this
* code then the second frontend would never be allocated ( later )
* and fail with error before the attach in dvb_register ( ) .
* Without these changes we risk an OOPS later . The changes here
* are for safety , and should provide a good foundation for the
* future addition of any multi - frontend cx23885 based boards .
*/
printk ( KERN_INFO " %s() allocating %d frontend(s) \n " , __func__ ,
port - > num_frontends ) ;
2007-03-11 20:44:05 -03:00
2008-10-11 12:34:39 -03:00
for ( i = 1 ; i < = port - > num_frontends ; i + + ) {
2008-10-15 20:26:34 -03:00
if ( videobuf_dvb_alloc_frontend (
2008-10-16 20:18:44 -03:00
& port - > frontends , i ) = = NULL ) {
2008-10-11 12:34:39 -03:00
printk ( KERN_ERR " %s() failed to alloc \n " , __func__ ) ;
return - ENOMEM ;
}
fe0 = videobuf_dvb_get_frontend ( & port - > frontends , i ) ;
if ( ! fe0 )
err = - EINVAL ;
2008-10-11 11:05:50 -03:00
2008-10-11 12:34:39 -03:00
dprintk ( 1 , " %s \n " , __func__ ) ;
2008-10-16 20:18:44 -03:00
dprintk ( 1 , " ->probed by Card=%d Name=%s, PCI %02x:%02x \n " ,
2008-10-11 12:34:39 -03:00
dev - > board ,
dev - > name ,
dev - > pci_bus ,
dev - > pci_slot ) ;
2007-03-11 20:44:05 -03:00
2008-10-11 12:34:39 -03:00
err = - ENODEV ;
2007-03-11 20:44:05 -03:00
2008-10-11 12:34:39 -03:00
/* dvb stuff */
/* We have to init the queue for each frontend on a port. */
2008-10-16 20:18:44 -03:00
printk ( KERN_INFO " %s: cx23885 based dvb card \n " , dev - > name ) ;
videobuf_queue_sg_init ( & fe0 - > dvb . dvbq , & dvb_qops ,
& dev - > pci - > dev , & port - > slock ,
2007-03-20 23:00:18 -03:00
V4L2_BUF_TYPE_VIDEO_CAPTURE , V4L2_FIELD_TOP ,
sizeof ( struct cx23885_buffer ) , port ) ;
2008-10-11 12:34:39 -03:00
}
2007-03-11 20:44:05 -03:00
err = dvb_register ( port ) ;
if ( err ! = 0 )
2008-10-16 20:18:44 -03:00
printk ( KERN_ERR " %s() dvb_register failed err = %d \n " ,
__func__ , err ) ;
2007-03-11 20:44:05 -03:00
return err ;
}
int cx23885_dvb_unregister ( struct cx23885_tsport * port )
{
2008-10-11 11:05:50 -03:00
struct videobuf_dvb_frontend * fe0 ;
2008-10-11 12:34:39 -03:00
/* FIXME: in an error condition where the we have
* an expected number of frontends ( attach problem )
* then this might not clean up correctly , if 1
* is invalid .
* This comment only applies to future boards IF they
* implement MFE support .
*/
2008-10-11 11:18:53 -03:00
fe0 = videobuf_dvb_get_frontend ( & port - > frontends , 1 ) ;
2008-10-16 20:18:44 -03:00
if ( fe0 - > dvb . frontend )
2008-10-11 11:05:50 -03:00
videobuf_dvb_unregister_bus ( & port - > frontends ) ;
2007-03-11 20:44:05 -03:00
return 0 ;
}
2007-03-20 23:00:18 -03:00