V4L/DVB (3089): Adding support for the Hauppauge HVR1100 and HVR1100-LP products.
- Add support for the Hauppauge HVR1100 and HVR1100-LP products. - Add i2c_gate_ctrl callback function to dvb_frontend_ops struct. Signed-off-by: Steven Toth <stoth@hauppauge.com> Signed-off-by: Michael Krufky <mkrufky@m1k.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
This commit is contained in:
parent
35dc0fefb1
commit
611900c185
8 changed files with 114 additions and 12 deletions
|
@ -38,3 +38,5 @@
|
||||||
37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
|
37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
|
||||||
38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
|
38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
|
||||||
39 -> KWorld DVB-S 100 [17de:08b2]
|
39 -> KWorld DVB-S 100 [17de:08b2]
|
||||||
|
40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
|
||||||
|
41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802]
|
||||||
|
|
|
@ -85,6 +85,7 @@ struct dvb_frontend_ops {
|
||||||
int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
|
int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
|
||||||
int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg);
|
int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg);
|
||||||
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
|
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
|
||||||
|
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_EVENT 8
|
#define MAX_EVENT 8
|
||||||
|
|
|
@ -195,6 +195,16 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
|
||||||
|
{
|
||||||
|
struct cx22702_state* state = fe->demodulator_priv;
|
||||||
|
dprintk ("%s(%d)\n", __FUNCTION__, enable);
|
||||||
|
if (enable)
|
||||||
|
return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
|
||||||
|
else
|
||||||
|
return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
|
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
|
||||||
static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
|
static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +212,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
|
||||||
struct cx22702_state* state = fe->demodulator_priv;
|
struct cx22702_state* state = fe->demodulator_priv;
|
||||||
|
|
||||||
/* set PLL */
|
/* set PLL */
|
||||||
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
|
cx22702_i2c_gate_ctrl(fe, 1);
|
||||||
if (state->config->pll_set) {
|
if (state->config->pll_set) {
|
||||||
state->config->pll_set(fe, p);
|
state->config->pll_set(fe, p);
|
||||||
} else if (state->config->pll_desc) {
|
} else if (state->config->pll_desc) {
|
||||||
|
@ -216,7 +226,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
|
||||||
} else {
|
} else {
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
|
cx22702_i2c_gate_ctrl(fe, 0);
|
||||||
|
|
||||||
/* set inversion */
|
/* set inversion */
|
||||||
cx22702_set_inversion (state, p->inversion);
|
cx22702_set_inversion (state, p->inversion);
|
||||||
|
@ -349,11 +359,10 @@ static int cx22702_init (struct dvb_frontend* fe)
|
||||||
cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
|
cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
|
||||||
|
|
||||||
/* init PLL */
|
/* init PLL */
|
||||||
if (state->config->pll_init) {
|
if (state->config->pll_init)
|
||||||
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
|
|
||||||
state->config->pll_init(fe);
|
state->config->pll_init(fe);
|
||||||
cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
|
|
||||||
}
|
cx22702_i2c_gate_ctrl(fe, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -531,6 +540,7 @@ static struct dvb_frontend_ops cx22702_ops = {
|
||||||
.read_signal_strength = cx22702_read_signal_strength,
|
.read_signal_strength = cx22702_read_signal_strength,
|
||||||
.read_snr = cx22702_read_snr,
|
.read_snr = cx22702_read_snr,
|
||||||
.read_ucblocks = cx22702_read_ucblocks,
|
.read_ucblocks = cx22702_read_ucblocks,
|
||||||
|
.i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_param(debug, int, 0644);
|
module_param(debug, int, 0644);
|
||||||
|
|
|
@ -903,7 +903,6 @@ struct cx88_board cx88_boards[] = {
|
||||||
.radio_type = UNSET,
|
.radio_type = UNSET,
|
||||||
.tuner_addr = ADDR_UNSET,
|
.tuner_addr = ADDR_UNSET,
|
||||||
.radio_addr = ADDR_UNSET,
|
.radio_addr = ADDR_UNSET,
|
||||||
/* fixme: add the analog gpio stuff here */
|
|
||||||
.input = {{
|
.input = {{
|
||||||
.type = CX88_VMUX_DVB,
|
.type = CX88_VMUX_DVB,
|
||||||
.vmux = 0,
|
.vmux = 0,
|
||||||
|
@ -946,6 +945,43 @@ struct cx88_board cx88_boards[] = {
|
||||||
}},
|
}},
|
||||||
.dvb = 1,
|
.dvb = 1,
|
||||||
},
|
},
|
||||||
|
[CX88_BOARD_HAUPPAUGE_HVR1100] = {
|
||||||
|
.name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
|
||||||
|
.tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
|
||||||
|
.radio_type = UNSET,
|
||||||
|
.tuner_addr = ADDR_UNSET,
|
||||||
|
.radio_addr = ADDR_UNSET,
|
||||||
|
.tda9887_conf = TDA9887_PRESENT,
|
||||||
|
.input = {{
|
||||||
|
.type = CX88_VMUX_TELEVISION,
|
||||||
|
.vmux = 0,
|
||||||
|
},{
|
||||||
|
.type = CX88_VMUX_COMPOSITE1,
|
||||||
|
.vmux = 1,
|
||||||
|
},{
|
||||||
|
.type = CX88_VMUX_SVIDEO,
|
||||||
|
.vmux = 2,
|
||||||
|
}},
|
||||||
|
/* fixme: Add radio support */
|
||||||
|
.dvb = 1,
|
||||||
|
},
|
||||||
|
[CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
|
||||||
|
.name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
|
||||||
|
.tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
|
||||||
|
.radio_type = UNSET,
|
||||||
|
.tuner_addr = ADDR_UNSET,
|
||||||
|
.radio_addr = ADDR_UNSET,
|
||||||
|
.tda9887_conf = TDA9887_PRESENT,
|
||||||
|
.input = {{
|
||||||
|
.type = CX88_VMUX_TELEVISION,
|
||||||
|
.vmux = 0,
|
||||||
|
},{
|
||||||
|
.type = CX88_VMUX_COMPOSITE1,
|
||||||
|
.vmux = 1,
|
||||||
|
}},
|
||||||
|
/* fixme: Add radio support */
|
||||||
|
.dvb = 1,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
|
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
|
||||||
|
|
||||||
|
@ -1109,6 +1145,22 @@ struct cx88_subid cx88_subids[] = {
|
||||||
.subvendor = 0x17de,
|
.subvendor = 0x17de,
|
||||||
.subdevice = 0x08b2,
|
.subdevice = 0x08b2,
|
||||||
.card = CX88_BOARD_KWORLD_DVBS_100,
|
.card = CX88_BOARD_KWORLD_DVBS_100,
|
||||||
|
},{
|
||||||
|
.subvendor = 0x0070,
|
||||||
|
.subdevice = 0x9400,
|
||||||
|
.card = CX88_BOARD_HAUPPAUGE_HVR1100,
|
||||||
|
},{
|
||||||
|
.subvendor = 0x0070,
|
||||||
|
.subdevice = 0x9402,
|
||||||
|
.card = CX88_BOARD_HAUPPAUGE_HVR1100,
|
||||||
|
},{
|
||||||
|
.subvendor = 0x0070,
|
||||||
|
.subdevice = 0x9800,
|
||||||
|
.card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
|
||||||
|
},{
|
||||||
|
.subvendor = 0x0070,
|
||||||
|
.subdevice = 0x9802,
|
||||||
|
.card = CX88_BOARD_HAUPPAUGE_HVR1100LP,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
|
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
|
||||||
|
@ -1140,9 +1192,6 @@ static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
||||||
core->name, core->tuner_type, eeprom_data[0]);
|
core->name, core->tuner_type, eeprom_data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
||||||
{
|
{
|
||||||
struct tveeprom tv;
|
struct tveeprom tv;
|
||||||
|
@ -1161,7 +1210,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
|
||||||
case 90500: /* Nova-T-PCI (oem) */
|
case 90500: /* Nova-T-PCI (oem) */
|
||||||
case 90501: /* Nova-T-PCI (oem/IR) */
|
case 90501: /* Nova-T-PCI (oem/IR) */
|
||||||
case 92000: /* Nova-SE2 (OEM, No Video or IR) */
|
case 92000: /* Nova-SE2 (OEM, No Video or IR) */
|
||||||
|
case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
|
||||||
|
case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
|
||||||
|
case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
|
||||||
/* known */
|
/* known */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1279,6 +1330,8 @@ void cx88_card_setup(struct cx88_core *core)
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
||||||
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
||||||
|
case CX88_BOARD_HAUPPAUGE_HVR1100:
|
||||||
|
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
|
||||||
if (0 == core->i2c_rc)
|
if (0 == core->i2c_rc)
|
||||||
hauppauge_eeprom(core,eeprom);
|
hauppauge_eeprom(core,eeprom);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -191,6 +191,12 @@ static struct cx22702_config hauppauge_novat_config = {
|
||||||
.pll_address = 0x61,
|
.pll_address = 0x61,
|
||||||
.pll_desc = &dvb_pll_thomson_dtt759x,
|
.pll_desc = &dvb_pll_thomson_dtt759x,
|
||||||
};
|
};
|
||||||
|
static struct cx22702_config hauppauge_hvr1100_config = {
|
||||||
|
.demod_address = 0x63,
|
||||||
|
.output_mode = CX22702_SERIAL_OUTPUT,
|
||||||
|
.pll_address = 0x61,
|
||||||
|
.pll_desc = &dvb_pll_fmd1216me,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OR51132
|
#ifdef HAVE_OR51132
|
||||||
|
@ -370,6 +376,11 @@ static int dvb_register(struct cx8802_dev *dev)
|
||||||
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
|
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
|
||||||
&dev->core->i2c_adap);
|
&dev->core->i2c_adap);
|
||||||
break;
|
break;
|
||||||
|
case CX88_BOARD_HAUPPAUGE_HVR1100:
|
||||||
|
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
|
||||||
|
dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
|
||||||
|
&dev->core->i2c_adap);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_MT352
|
#ifdef HAVE_MT352
|
||||||
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
|
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
|
||||||
|
@ -532,6 +543,9 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
|
||||||
err = dvb_register(dev);
|
err = dvb_register(dev);
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
goto fail_fini;
|
goto fail_fini;
|
||||||
|
|
||||||
|
/* Maintain a reference to cx88-video can query the 8802 device. */
|
||||||
|
core->dvbdev = dev;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_fini:
|
fail_fini:
|
||||||
|
@ -547,6 +561,9 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
|
||||||
{
|
{
|
||||||
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
|
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
|
||||||
|
|
||||||
|
/* Destroy any 8802 reference. */
|
||||||
|
dev->core->dvbdev = NULL;
|
||||||
|
|
||||||
/* dvb */
|
/* dvb */
|
||||||
videobuf_dvb_unregister(&dev->dvb);
|
videobuf_dvb_unregister(&dev->dvb);
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,20 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
|
||||||
{
|
{
|
||||||
if (0 != core->i2c_rc)
|
if (0 != core->i2c_rc)
|
||||||
return;
|
return;
|
||||||
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
|
||||||
|
if (core->dvbdev == NULL) {
|
||||||
|
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
|
||||||
|
core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
|
||||||
|
|
||||||
|
i2c_clients_command(&core->i2c_adap, cmd, arg);
|
||||||
|
|
||||||
|
if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
|
||||||
|
core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
|
static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
|
||||||
|
|
|
@ -390,6 +390,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
|
||||||
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
case CX88_BOARD_HAUPPAUGE_DVB_T1:
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
|
||||||
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
|
||||||
|
case CX88_BOARD_HAUPPAUGE_HVR1100:
|
||||||
ir_codes = ir_codes_hauppauge_new;
|
ir_codes = ir_codes_hauppauge_new;
|
||||||
ir_type = IR_TYPE_RC5;
|
ir_type = IR_TYPE_RC5;
|
||||||
ir->sampling = 1;
|
ir->sampling = 1;
|
||||||
|
|
|
@ -182,6 +182,8 @@ extern struct sram_channel cx88_sram_channels[];
|
||||||
#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
|
#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
|
||||||
#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
|
#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
|
||||||
#define CX88_BOARD_KWORLD_DVBS_100 39
|
#define CX88_BOARD_KWORLD_DVBS_100 39
|
||||||
|
#define CX88_BOARD_HAUPPAUGE_HVR1100 40
|
||||||
|
#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41
|
||||||
|
|
||||||
enum cx88_itype {
|
enum cx88_itype {
|
||||||
CX88_VMUX_COMPOSITE1 = 1,
|
CX88_VMUX_COMPOSITE1 = 1,
|
||||||
|
@ -304,6 +306,9 @@ struct cx88_core {
|
||||||
|
|
||||||
/* various v4l controls */
|
/* various v4l controls */
|
||||||
u32 freq;
|
u32 freq;
|
||||||
|
|
||||||
|
/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
|
||||||
|
struct cx8802_dev *dvbdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cx8800_dev;
|
struct cx8800_dev;
|
||||||
|
|
Loading…
Reference in a new issue