UDP Technology NCP3200v2

From ZoneMinder Wiki
Revision as of 07:03, 10 October 2014 by Gkmac (talk | contribs) (Add kernel 3.14 patch that allows 16 channel input)
Jump to navigationJump to search
NCP3200v2 capture card - front view

Introduction

The UDP Technology NCP3200v2 is a PCI card with 16 video inputs and 8 Conexant Fusion 878A (also known as BT878) chips.

Manufacturers website: http://www.udptechnology.com/products/PC/NCP3200V2.html

The card has 2 DE-15 (VGA shaped) sockets. Each is fitted with a cable which branches out into 8 yellow BNC connectors which are labelled VIDEO 1(9), VIDEO 2(10) and so on up to VIDEO 8(16).

Linux usage

The card is not properly supported with the bttv driver, but it is possible at present to use 4 of the 16 video inputs without having to patch the kernel.

Alternatively there is an experimental patch for 3.14 kernels which should allow all 16 video inputs to be used.

Using an unpatched kernel for 4 inputs

To use the card with an unpatched kernel, create the file /etc/modprobe.d/bttv.conf with the line below.

options bttv gbuffers=32 card=158,158,158,158,158,158,157,157

This tells the driver that a Geovision GV-800 card is present but unlike the GV-800 the "master" card needs to be the last 2 numbers, as the multiplexers are controlled by the last 2 detected 878A chips.

Using the above, the 4 working inputs will be spread across the /dev/video's as shown in the table below. All these inputs are on the bottom socket furthest from the yellow RCA connector.

Changing the device channel on any of the inputs will have no effect.

Path Socket
/dev/video0 VIDEO 4(12)
/dev/video1
/dev/video2 VIDEO 3(11)
/dev/video3
/dev/video4 VIDEO 2(10)
/dev/video5
/dev/video6 VIDEO 1(9)
/dev/video7

Patching the kernel for 16 video inputs

At present there is a patch that is suitable for 3.14 kernels only. Patches suitable for other kernel versions may be added later.

With this patch, all 8 /dev/video's can be switched to any of the 16 inputs by changing the device channel. Device channels 0 to 7 are on the bottom socket furthest from the yellow RCA connector, channel 0 corresponds to VIDEO 1(9), channel 1 is VIDEO 2(10) and so on. Device channels 8 to 15 are on the top socket next to the yellow RCA connector, channel 8 corresponds to VIDEO 1(9), channel 9 is VIDEO 2(10) and so on.

The card numbers to put into /etc/modprobe.d/bttv.conf will be different across each kernel version.

Patch for 3.14 kernel

options bttv gbuffers=32 card=166,166,166,166,166,166,165,165
diff -uNrp kernel-3.14.orig/drivers/media/pci/bt8xx/bttv-cards.c kernel-3.14.new/drivers/media/pci/bt8xx/bttv-cards.c
--- kernel-3.14.orig/drivers/media/pci/bt8xx/bttv-cards.c	2014-10-09 18:47:03.413696227 +0100
+++ kernel-3.14.new/drivers/media/pci/bt8xx/bttv-cards.c	2014-10-09 18:47:21.471991344 +0100
@@ -80,6 +80,9 @@ static void phytec_muxsel(struct bttv *b
 static void gv800s_muxsel(struct bttv *btv, unsigned int input);
 static void gv800s_init(struct bttv *btv);
 
+static void udp3200_muxsel(struct bttv *btv, unsigned int input);
+static void udp3200_init(struct bttv *btv);
+
 static void td3116_muxsel(struct bttv *btv, unsigned int input);
 
 static int terratec_active_radio_upgrade(struct bttv *btv);
@@ -2855,6 +2858,46 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
+	[BTTV_BOARD_UDP_NCP3200] = {
+		/* UDP Technology NCP3200v2 has 8 Conexant Fusion 878A:
+		 * 	2 video inputs per BT878A = 16 video inputs
+		 * These are the last 2 BT878A chips of the NCP3200v2. These are
+		 * "master" chips and they control the video inputs through 2
+		 * analog multiplexers (MT8816P) via some GPIO pins. The
+		 * slaves should use card type 0xa6 (following this one).
+		 */
+		.name           = "UDP Technology NCP3200v2 (master)",
+		.video_inputs   = 16,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+		.svhs           = NO_SVHS,
+		.gpiomask	= 0xf107f,
+		.no_gpioirq     = 1,
+		.muxsel		= MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+		.pll		= PLL_28,
+		.no_msp34xx	= 1,
+		.no_tda7432	= 1,
+		.muxsel_hook    = udp3200_muxsel,
+	},
+	[BTTV_BOARD_UDP_NCP3200_SL] = {
+		/* UDP Technology NCP3200v2 has 8 Conexant Fusion 878A:
+		 * 	2 video inputs per BT878A = 16 video inputs
+		 * The 6 other BT878A chips are "slave" chips of the NCP3200v2
+		 * and should use this card type.
+		 */
+		.name           = "UDP Technology NCP3200v2 (slave)",
+		.video_inputs   = 16,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+		.svhs           = NO_SVHS,
+		.gpiomask	= 0x00,
+		.no_gpioirq     = 1,
+		.muxsel		= MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+		.pll		= PLL_28,
+		.no_msp34xx	= 1,
+		.no_tda7432	= 1,
+		.muxsel_hook    = udp3200_muxsel,
+	},
 
 };
 
@@ -3407,6 +3450,9 @@ void bttv_init_card2(struct bttv *btv)
 	case BTTV_BOARD_GEOVISION_GV800S:
 		gv800s_init(btv);
 		break;
+	case BTTV_BOARD_UDP_NCP3200:
+		udp3200_init(btv);	
+		break;
 	}
 
 	/* pll configuration */
@@ -4842,6 +4888,73 @@ static void gv800s_init(struct bttv *btv
 	master[btv->c.nr+3] = btv;
 }
 
+/*
+ * UDP Technology NCP3200v2 functions
+ *
+ * adapted from GeoVision GV-800(S), reuses gv800s_write
+ *
+ * Each of the 4 cards (controllers) use this function.
+ * The controller using this function selects the input through the GPIO pins
+ * of the "master" card. A pointer to this card is stored in master[btv->c.nr].
+ *
+ * The parameter 'input' is the requested camera number (0-15) on the controller.
+ * The map array has the address of each input.
+ *
+ * After getting the input address, the function then writes the appropriate
+ * data to the analog switch, and housekeeps the local copy of the switch
+ * information.
+ */
+static void udp3200_muxsel(struct bttv *btv, unsigned int input)
+{
+	struct bttv *mctlr;
+	int xaddr, yaddr;
+	static unsigned int map[16] = { 0, 1, 2, 3, 4, 5, 8, 9,
+					10, 11, 12, 13, 6, 7, 14, 15 };
+	input = input%16;
+	mctlr = master[btv->c.nr];
+	if (mctlr == NULL) {
+		/* do nothing until the "master" is detected */
+		return;
+	}
+	yaddr = (mctlr->c.nr - btv->c.nr) >> 1;
+	xaddr = map[input];
+
+	/* Check if the controller/camera pair has changed, ignore otherwise */
+	if (mctlr->sw_status[yaddr] != xaddr) {
+		/* disable the old switch, enable the new one and save status */
+		gv800s_write(mctlr, mctlr->sw_status[yaddr], yaddr, 0);
+		mctlr->sw_status[yaddr] = xaddr;
+		gv800s_write(mctlr, xaddr, yaddr, 1);
+	}
+}
+
+/* UDP Technology NCP3200v2 "master" chip init */
+static void udp3200_init(struct bttv *btv)
+{
+	int ix;
+
+	gpio_inout(0xf107f, 0xf107f);
+	gpio_write(1<<19); /* reset the analog MUX */
+	gpio_write(0);
+
+	/* Preset camera 0 to the 4 controllers */
+	for (ix = 0; ix < 4; ix++) {
+		btv->sw_status[ix] = ix;
+		gv800s_write(btv, ix, ix, 1);
+	}
+
+	if (btv->c.nr < 6)
+		return;
+	/*
+	 * Store the "master" controller pointer in the master
+	 * array for later use in the muxsel function.
+	 */
+	master[btv->c.nr-6] = btv;
+	master[btv->c.nr-4] = btv;
+	master[btv->c.nr-2] = btv;
+	master[btv->c.nr]   = btv;
+}
+
 /* ----------------------------------------------------------------------- */
 /* motherboard chipset specific stuff                                      */
 
diff -uNrp kernel-3.14.orig/drivers/media/pci/bt8xx/bttv.h kernel-3.14.new/drivers/media/pci/bt8xx/bttv.h
--- kernel-3.14.orig/drivers/media/pci/bt8xx/bttv.h	2014-10-09 18:46:56.564825771 +0100
+++ kernel-3.14.new/drivers/media/pci/bt8xx/bttv.h	2014-10-09 18:47:14.579115295 +0100
@@ -188,6 +188,8 @@
 #define BTTV_BOARD_ADLINK_MPG24            0xa2
 #define BTTV_BOARD_BT848_CAP_14            0xa3
 #define BTTV_BOARD_CYBERVISION_CV06        0xa4
+#define BTTV_BOARD_UDP_NCP3200             0xa5
+#define BTTV_BOARD_UDP_NCP3200_SL          0xa6
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10