V4L/DVB (4638): Basic DVB-T and analog TV support for the HVR1300.

This is the first in a series of patches to add full WinTV-HVR1300
support to Linux. This first patch will enable analog TV support
and DVB-T support. Later patches will add the hardware MPEG encoder
support.

Signed-off-by: Steven Toth <stoth@hauppauge.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 29ba5d5..4a9998f 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1280,6 +1280,29 @@
 		       .gpio3  = 0x02000000,
 	       }},
        },
+	[CX88_BOARD_HAUPPAUGE_HVR1300] = {
+		.name		= "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder",
+		.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,
+			.gpio0	= 0xe780,
+		},{
+			.type	= CX88_VMUX_COMPOSITE1,
+			.vmux	= 1,
+			.gpio0	= 0xe780,
+		},{
+			.type	= CX88_VMUX_SVIDEO,
+			.vmux	= 2,
+			.gpio0	= 0xe780,
+		}},
+		/* fixme: Add radio support */
+		.dvb		= 1,
+	},
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
 
@@ -1542,6 +1565,18 @@
 		.subvendor = 0xc180,
 		.subdevice = 0xc980,
 		.card      = CX88_BOARD_TE_DTV_250_OEM_SWANN,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9600,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9601,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9602,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1300,
 	},
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1597,6 +1632,11 @@
 	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 96009: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX) */
+	case 96019: /* WinTV-HVR1300 (PAL Video, MPEG Video and IR RX/TX) */
+	case 96559: /* WinTV-HVR1300 (PAL Video, MPEG Video no IR) */
+	case 96569: /* WinTV-HVR1300 () */
+	case 96659: /* WinTV-HVR1300 () */
 	case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
 		/* known */
 		break;
@@ -1723,6 +1763,22 @@
 		       core->name, i, cx88_boards[i].name);
 }
 
+void cx88_card_setup_pre_i2c(struct cx88_core *core)
+{
+	switch (core->board) {
+	case CX88_BOARD_HAUPPAUGE_HVR1300:
+		/* Bring the 702 demod up before i2c scanning/attach or devices are hidden */
+		/* We leave here with the 702 on the bus */
+		cx_write(MO_GP0_IO, 0x0000e780);
+		udelay(1000);
+		cx_clear(MO_GP0_IO, 0x00000080);
+		udelay(50);
+		cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
+		udelay(1000);
+		break;
+	}
+}
+
 void cx88_card_setup(struct cx88_core *core)
 {
 	static u8 eeprom[256];
@@ -1752,6 +1808,7 @@
 	case CX88_BOARD_HAUPPAUGE_HVR1100:
 	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
+	case CX88_BOARD_HAUPPAUGE_HVR1300:
 		if (0 == core->i2c_rc)
 			hauppauge_eeprom(core,eeprom);
 		break;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 888ccb6..f379ede 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1133,6 +1133,7 @@
 
 	/* init hardware */
 	cx88_reset(core);
+	cx88_card_setup_pre_i2c(core);
 	cx88_i2c_init(core,pci);
 	cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
 	cx88_card_setup(core);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index a5812e2..c87041d 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -319,6 +319,10 @@
 	.demod_address = 0x63,
 	.output_mode   = CX22702_SERIAL_OUTPUT,
 };
+static struct cx22702_config hauppauge_hvr1300_config = {
+	.demod_address = 0x63,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
+};
 
 static int or51132_set_ts_param(struct dvb_frontend* fe,
 				int is_punctured)
@@ -544,6 +548,16 @@
 				   &dvb_pll_fmd1216me);
 		}
 		break;
+	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_DVICO_FUSIONHDTV_DVB_T_PLUS:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 3049bd5..83ebf7a 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -195,6 +195,7 @@
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_HVR1100:
+	case CX88_BOARD_HAUPPAUGE_HVR1300:
 		ir_codes = ir_codes_hauppauge_new;
 		ir_type = IR_TYPE_RC5;
 		ir->sampling = 1;
@@ -417,6 +418,7 @@
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_HVR1100:
+	case CX88_BOARD_HAUPPAUGE_HVR1300:
 		ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		if ((ircode & 0xfffff000) != 0x3000)
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 1c87c2e..89f12e2 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -200,6 +200,7 @@
 #define CX88_BOARD_HAUPPAUGE_HVR3000       53
 #define CX88_BOARD_NORWOOD_MICRO           54
 #define CX88_BOARD_TE_DTV_250_OEM_SWANN    55
+#define CX88_BOARD_HAUPPAUGE_HVR1300       56
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
@@ -548,6 +549,7 @@
 
 extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci);
 extern void cx88_card_setup(struct cx88_core *core);
+extern void cx88_card_setup_pre_i2c(struct cx88_core *core);
 
 /* ----------------------------------------------------------- */
 /* cx88-tvaudio.c                                              */