V4L/DVB (4038): New cx88 card #50: NPG Tech RealTV

Added support for a new cx88 card, including it's remote

Signed-off-by: Ricardo Cerqueira <v4l@cerqueira.org>
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 16cd643..04ef1cc 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1148,6 +1148,29 @@
 		}},
 		.blackbird = 1,
 	},
+	[CX88_BOARD_NPGTECH_REALTV] = {
+		.name           = "NPG Tech Real TV",
+		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0	= 0x0788,
+		},{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0	= 0x078b,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+		}},
+		.radio = {
+			 .type  = CX88_RADIO,
+			 .gpio0 = 0x074a,
+		},
+	},
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
 
@@ -1381,6 +1404,10 @@
 		.subvendor = 0x1554,
 		.subdevice = 0x4813,
 		.card      = CX88_BOARD_PIXELVIEW_PLAYTV_P7000,
+	},{
+		.subvendor = 0x14f1,
+		.subdevice = 0x0842,
+		.card      = CX88_BOARD_NPGTECH_REALTV,
 	},
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 78a63b7..4bd86c4 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -70,14 +70,33 @@
 static void cx88_ir_handle_key(struct cx88_IR *ir)
 {
 	struct cx88_core *core = ir->core;
-	u32 gpio, data;
+	u32 gpio, data, auxgpio;
 
 	/* read gpio value */
 	gpio = cx_read(ir->gpio_addr);
+	if (core->board == CX88_BOARD_NPGTECH_REALTV) {
+		/* This board apparently uses a combination of 2 GPIO
+		   to represent the keys. Additionally, the second GPIO
+		   can be used for parity.
+
+		   Example:
+
+		   for key "5"
+			gpio = 0x758, auxgpio = 0xe5 or 0xf5
+		   for key "Power"
+			gpio = 0x758, auxgpio = 0xed or 0xfd
+		 */
+
+		auxgpio = cx_read(MO_GP1_IO);
+		/* Take out the parity part */
+		gpio+=(auxgpio & 0xef);
+	} else
+		auxgpio = gpio;
+
 	if (ir->polling) {
-		if (ir->last_gpio == gpio)
+		if (ir->last_gpio == auxgpio)
 			return;
-		ir->last_gpio = gpio;
+		ir->last_gpio = auxgpio;
 	}
 
 	/* extract data */
@@ -228,6 +247,12 @@
 		ir_type = IR_TYPE_PD;
 		ir->sampling = 0xff00; /* address */
 		break;
+	case CX88_BOARD_NPGTECH_REALTV:
+		ir_codes = ir_codes_npgtech;
+		ir->gpio_addr = MO_GP0_IO;
+		ir->mask_keycode = 0xfa;
+		ir->polling = 50; /* ms */
+		break;
 	}
 
 	if (NULL == ir_codes) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 663def4..5df6e41 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -192,6 +192,7 @@
 #define CX88_BOARD_PCHDTV_HD5500           47
 #define CX88_BOARD_KWORLD_MCE200_DELUXE    48
 #define CX88_BOARD_PIXELVIEW_PLAYTV_P7000  49
+#define CX88_BOARD_NPGTECH_REALTV  50
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,