[linux-dvb] Re: [Patch] Adding support for the Hauppage HVR1100
Steve Toth
stoth at hauppauge.com
Wed Nov 30 06:03:14 CET 2005
>>>
>>>
>> Yes. More difficult. I can pollute tuner.ko with cx88 stuff, and have
>> the specific 'gate' flag passed in tuner_setup, or added to cx88_core,
>> but it didn't seem to make any sense when tuner.ko only knows about I2C
>> clients and tuner types (not demods and specific demod behavior, or even
>> DVB related things for that matter).
>>
>
> No, we shouldn't add cx88 specific stuff to tuner.ko, but in
> cx88 where the VIDIOC_S_FREQUENCY ioctl is processed you should be able
> to open the i2c gate before cx88_call_i2c_clients(), no?
>
>
I was trying to avoid any changes outside of cx88_dvb.ko -- It was
probably unavoidable.
A patch is attached for review.
Here's a summary:
1. The cx22702 driver has two exported functions to open/close the
plli2c on demand.
2. cx88_dvb.ko has two new functions which call the demod plli2c
open/close exports driven by board type.
3. cx8800.ko (via the V4L ioctls) calls cx88_dvb-enable/disable when
using cx88_call_i2c_clients, you will see this repeated everywhere
throughout the module. (I tried moving the enable/disable into the
actual cx88_call_i2c_clients function but ended up with circular depmod
references in most of the cx88 modules. I can look into this tomorrow).
Apart from that, we hold a reference to the cx8802_dev struct in
cx88_core else cx88-video has no way to find the original dvb_frontend
structure. cx88_dvb will also become a module dependency of cx8800.
The patch is working here but looks (temporarily) ugly inside cx8800.ko.
More cleanup is required.
Comments/feedback welcome.
Steve
-------------- next part --------------
Index: linux/Documentation/video4linux/CARDLIST.cx88
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/Documentation/video4linux/CARDLIST.cx88,v
retrieving revision 1.16
diff -u -p -r1.16 CARDLIST.cx88
--- linux/Documentation/video4linux/CARDLIST.cx88 22 Nov 2005 19:32:26 -0000 1.16
+++ linux/Documentation/video4linux/CARDLIST.cx88 30 Nov 2005 04:28:29 -0000
@@ -38,3 +38,4 @@
37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202]
38 -> Hauppauge Nova-SE2 DVB-S [0070:9200]
39 -> KWorld DVB-S 100 [17de:08b2]
+ 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402]
Index: linux/drivers/media/dvb/frontends/cx22702.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/frontends/cx22702.c,v
retrieving revision 1.14
diff -u -p -r1.14 cx22702.c
--- linux/drivers/media/dvb/frontends/cx22702.c 26 Nov 2005 23:46:56 -0000 1.14
+++ linux/drivers/media/dvb/frontends/cx22702.c 30 Nov 2005 04:28:29 -0000
@@ -195,6 +195,20 @@ static int cx22702_get_tps (struct cx227
return 0;
}
+int cx22702_enable_plli2c(struct dvb_frontend* fe)
+{
+ struct cx22702_state* state = fe->demodulator_priv;
+ dprintk ("%s\n",__FUNCTION__);
+ return cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+}
+
+int cx22702_disable_plli2c(struct dvb_frontend* fe)
+{
+ struct cx22702_state* state = fe->demodulator_priv;
+ dprintk ("%s\n",__FUNCTION__);
+ return cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
+}
+
/* 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)
{
@@ -202,7 +216,7 @@ static int cx22702_set_tps (struct dvb_f
struct cx22702_state* state = fe->demodulator_priv;
/* set PLL */
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+ cx22702_enable_plli2c(fe);
if (state->config->pll_set) {
state->config->pll_set(fe, p);
} else if (state->config->pll_desc) {
@@ -216,7 +230,7 @@ static int cx22702_set_tps (struct dvb_f
} else {
BUG();
}
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
+ cx22702_disable_plli2c(fe);
/* set inversion */
cx22702_set_inversion (state, p->inversion);
@@ -349,11 +363,10 @@ static int cx22702_init (struct dvb_fron
cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
/* init PLL */
- if (state->config->pll_init) {
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
+ if (state->config->pll_init)
state->config->pll_init(fe);
- cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
- }
+
+ cx22702_disable_plli2c(fe);
return 0;
}
@@ -541,3 +554,5 @@ MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(cx22702_attach);
+EXPORT_SYMBOL(cx22702_enable_plli2c);
+EXPORT_SYMBOL(cx22702_disable_plli2c);
Index: linux/drivers/media/dvb/frontends/cx22702.h
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/frontends/cx22702.h,v
retrieving revision 1.6
diff -u -p -r1.6 cx22702.h
--- linux/drivers/media/dvb/frontends/cx22702.h 26 Nov 2005 23:46:56 -0000 1.6
+++ linux/drivers/media/dvb/frontends/cx22702.h 30 Nov 2005 04:28:29 -0000
@@ -51,4 +51,7 @@ struct cx22702_config
extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
struct i2c_adapter* i2c);
+extern int cx22702_enable_plli2c(struct dvb_frontend* fe);
+extern int cx22702_disable_plli2c(struct dvb_frontend* fe);
+
#endif // CX22702_H
Index: linux/drivers/media/video/cx88/cx88-cards.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/video/cx88/cx88-cards.c,v
retrieving revision 1.108
diff -u -p -r1.108 cx88-cards.c
--- linux/drivers/media/video/cx88/cx88-cards.c 25 Nov 2005 10:24:13 -0000 1.108
+++ linux/drivers/media/video/cx88/cx88-cards.c 30 Nov 2005 04:28:29 -0000
@@ -903,7 +903,6 @@ struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* fixme: add the analog gpio stuff here */
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
@@ -946,6 +945,26 @@ struct cx88_board cx88_boards[] = {
}},
.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,
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -1109,6 +1128,14 @@ struct cx88_subid cx88_subids[] = {
.subvendor = 0x17de,
.subdevice = 0x08b2,
.card = CX88_BOARD_KWORLD_DVBS_100,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x9400,
+ .card = CX88_BOARD_HAUPPAUGE_HVR1100,
+ },{
+ .subvendor = 0x0070,
+ .subdevice = 0x9402,
+ .card = CX88_BOARD_HAUPPAUGE_HVR1100,
},
};
const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1140,9 +1167,6 @@ static void __devinit leadtek_eeprom(str
core->name, core->tuner_type, eeprom_data[0]);
}
-
-/* ----------------------------------------------------------------------- */
-
static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
{
struct tveeprom tv;
@@ -1161,7 +1185,8 @@ static void hauppauge_eeprom(struct cx88
case 90500: /* Nova-T-PCI (oem) */
case 90501: /* Nova-T-PCI (oem/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) */
/* known */
break;
default:
@@ -1279,6 +1304,7 @@ void cx88_card_setup(struct cx88_core *c
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
+ case CX88_BOARD_HAUPPAUGE_HVR1100:
if (0 == core->i2c_rc)
hauppauge_eeprom(core,eeprom);
break;
Index: linux/drivers/media/video/cx88/cx88-dvb.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/video/cx88/cx88-dvb.c,v
retrieving revision 1.74
diff -u -p -r1.74 cx88-dvb.c
--- linux/drivers/media/video/cx88/cx88-dvb.c 22 Nov 2005 19:32:26 -0000 1.74
+++ linux/drivers/media/video/cx88/cx88-dvb.c 30 Nov 2005 04:28:30 -0000
@@ -197,6 +197,14 @@ static struct cx22702_config hauppauge_n
.pll_address = 0x61,
.pll_desc = &dvb_pll_thomson_dtt759x,
};
+static struct cx22702_config hauppauge_hvr1100_config = {
+ .demod_address = 0x63,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+ .output_mode = CX22702_SERIAL_OUTPUT,
+#endif
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_fmd1216me,
+};
#endif
#ifdef HAVE_OR51132
@@ -357,6 +365,32 @@ static struct cx24123_config kworld_dvbs
};
#endif
+/* Called from cx88-video if the I2C gate potentially needs to be opened */
+int cx8802_enable_plli2c(struct cx8802_dev *dev)
+{
+ dprintk(1, "%s\n", __FUNCTION__);
+#ifdef HAVE_CX22702
+ if (dev->core->board == CX88_BOARD_HAUPPAUGE_HVR1100) {
+ if (dev->dvb.frontend)
+ return cx22702_enable_plli2c(dev->dvb.frontend);
+ }
+#endif
+ return 0;
+}
+
+/* Called from cx88-video if the I2C gate potentially needs to be closed */
+int cx8802_disable_plli2c(struct cx8802_dev *dev)
+{
+ dprintk(1, "%s\n", __FUNCTION__);
+#ifdef HAVE_CX22702
+ if (dev->core->board == CX88_BOARD_HAUPPAUGE_HVR1100) {
+ if (dev->dvb.frontend)
+ return cx22702_disable_plli2c(dev->dvb.frontend);
+ }
+#endif
+ return 0;
+}
+
static int dvb_register(struct cx8802_dev *dev)
{
/* init struct videobuf_dvb */
@@ -376,6 +410,10 @@ static int dvb_register(struct cx8802_de
dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
&dev->core->i2c_adap);
break;
+ case CX88_BOARD_HAUPPAUGE_HVR1100:
+ dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
+ &dev->core->i2c_adap);
+ break;
#endif
#ifdef HAVE_MT352
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
@@ -538,6 +576,9 @@ static int __devinit dvb_probe(struct pc
err = dvb_register(dev);
if (0 != err)
goto fail_fini;
+
+ /* Maintain a reference to cx88-video can query the 8802 device. */
+ core->dvbdev = dev;
return 0;
fail_fini:
@@ -553,6 +594,9 @@ static void __devexit dvb_remove(struct
{
struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
+ /* Destroy any 8802 reference. */
+ dev->core->dvbdev = NULL;
+
/* dvb */
videobuf_dvb_unregister(&dev->dvb);
@@ -604,6 +648,9 @@ static void dvb_fini(void)
module_init(dvb_init);
module_exit(dvb_fini);
+EXPORT_SYMBOL(cx8802_enable_plli2c);
+EXPORT_SYMBOL(cx8802_disable_plli2c);
+
/*
* Local variables:
* c-basic-offset: 8
Index: linux/drivers/media/video/cx88/cx88-input.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/video/cx88/cx88-input.c,v
retrieving revision 1.23
diff -u -p -r1.23 cx88-input.c
--- linux/drivers/media/video/cx88/cx88-input.c 18 Nov 2005 01:02:18 -0000 1.23
+++ linux/drivers/media/video/cx88/cx88-input.c 30 Nov 2005 04:28:30 -0000
@@ -385,6 +385,7 @@ int cx88_ir_init(struct cx88_core *core,
case CX88_BOARD_HAUPPAUGE_DVB_T1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+ case CX88_BOARD_HAUPPAUGE_HVR1100:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
Index: linux/drivers/media/video/cx88/cx88-video.c
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/video/cx88/cx88-video.c,v
retrieving revision 1.102
diff -u -p -r1.102 cx88-video.c
--- linux/drivers/media/video/cx88/cx88-video.c 10 Nov 2005 12:40:42 -0000 1.102
+++ linux/drivers/media/video/cx88/cx88-video.c 30 Nov 2005 04:28:30 -0000
@@ -1127,7 +1127,11 @@ static int video_release(struct inode *i
file->private_data = NULL;
kfree(fh);
+ if (dev->core->dvbdev)
+ cx8802_enable_plli2c(dev->core->dvbdev);
cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ if (dev->core->dvbdev)
+ cx8802_disable_plli2c(dev->core->dvbdev);
return 0;
}
@@ -1559,9 +1563,13 @@ int cx88_do_ioctl(struct inode *inode, s
if (i == ARRAY_SIZE(tvnorms))
return -EINVAL;
+ if (core->dvbdev)
+ cx8802_enable_plli2c(core->dvbdev);
down(&core->lock);
cx88_set_tvnorm(core,&tvnorms[i]);
up(&core->lock);
+ if (core->dvbdev)
+ cx8802_disable_plli2c(core->dvbdev);
return 0;
}
@@ -1739,7 +1747,11 @@ int cx88_do_ioctl(struct inode *inode, s
down(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
+ if (core->dvbdev)
+ cx8802_enable_plli2c(core->dvbdev);
cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
+ if (core->dvbdev)
+ cx8802_disable_plli2c(core->dvbdev);
/* When changing channels it is required to reset TVAUDIO */
msleep (10);
@@ -2230,7 +2242,11 @@ static int __devinit cx8800_initdev(stru
/* initial device configuration */
down(&core->lock);
init_controls(core);
+ if (core->dvbdev)
+ cx8802_enable_plli2c(core->dvbdev);
cx88_set_tvnorm(core,tvnorms);
+ if (core->dvbdev)
+ cx8802_disable_plli2c(core->dvbdev);
video_mux(core,0);
up(&core->lock);
Index: linux/drivers/media/video/cx88/cx88.h
===================================================================
RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/video/cx88/cx88.h,v
retrieving revision 1.91
diff -u -p -r1.91 cx88.h
--- linux/drivers/media/video/cx88/cx88.h 22 Nov 2005 19:32:26 -0000 1.91
+++ linux/drivers/media/video/cx88/cx88.h 30 Nov 2005 04:28:30 -0000
@@ -189,6 +189,7 @@ extern struct sram_channel cx88_sram_cha
#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37
#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38
#define CX88_BOARD_KWORLD_DVBS_100 39
+#define CX88_BOARD_HAUPPAUGE_HVR1100 40
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -314,6 +315,9 @@ struct cx88_core {
/* various v4l controls */
u32 freq;
+
+ /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
+ struct cx8802_dev *dvbdev;
};
struct cx8800_dev;
@@ -609,6 +613,9 @@ void cx8802_fini_common(struct cx8802_de
int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
int cx8802_resume_common(struct pci_dev *pci_dev);
+int cx8802_enable_plli2c(struct cx8802_dev *dev);
+int cx8802_disable_plli2c(struct cx8802_dev *dev);
+
/* ----------------------------------------------------------- */
/* cx88-video.c */
extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
More information about the linux-dvb
mailing list