diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index f6ac9ba..458f593 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -25,6 +25,7 @@
 #include <linux/i2c/at24.h>
 #include <linux/i2c/pcf857x.h>
 
+#include <media/fpga_subdev.h>
 #include <media/tvp514x.h>
 
 #include <linux/mtd/mtd.h>
@@ -485,12 +486,14 @@ static int set_vpif_clock(int mux_mode, int hd)
 }
 
 static struct vpif_subdev_info dm646x_vpif_subdev[] = {
+#if 0
 	{
 		.name	= "adv7343",
 		.board_info = {
 			I2C_BOARD_INFO("adv7343", 0x2a),
 		},
 	},
+#endif
 	{
 		.name	= "ths7303",
 		.board_info = {
@@ -595,10 +598,43 @@ static struct tvp514x_platform_data tvp5146_pdata = {
 	.vs_polarity = 1
 };
 
+int dm646x_subdev_s_power(struct fpga_subdev_platform_data *pdata,
+		struct v4l2_subdev *sd, int on)
+{
+	printk(KERN_DEBUG "%s: Power %s\n", __func__, on ? "on" : "off");
+
+	return 0;
+}
+
+int dm646x_subdev_s_stream(struct fpga_subdev_platform_data *pdata,
+		struct v4l2_subdev *sd, int enable)
+{
+	printk(KERN_DEBUG "%s: Stream %s\n", __func__,
+			enable ? "enabled" : "disabled");
+
+	return 0;
+}
+
+static struct fpga_subdev_ops dm646x_subdev_ops = {
+	.s_stream = dm646x_subdev_s_stream,
+	.s_power = dm646x_subdev_s_power,
+};
+
+struct fpga_subdev_platform_data dm646x_subdev_pdata = {
+	.ops = &dm646x_subdev_ops,
+};
+
 #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
 
 static struct vpif_subdev_info vpif_capture_sdev_info[] = {
 	{
+		.name	= "fpga_subdev",
+		.board_info = {
+			.platform_data = &dm646x_subdev_pdata,
+		},
+	},
+#if 0
+	{
 		.name	= TVP5147_CH0,
 		.board_info = {
 			I2C_BOARD_INFO("tvp5146", 0x5d),
@@ -630,6 +666,7 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = {
 			.fid_pol = 0,
 		},
 	},
+#endif
 };
 
 static const struct vpif_input dm6467_ch0_inputs[] = {
@@ -669,6 +706,7 @@ static struct vpif_capture_config dm646x_vpif_capture_cfg = {
 		.inputs = dm6467_ch1_inputs,
 		.input_count = ARRAY_SIZE(dm6467_ch1_inputs),
 	},
+	.card_name = "DM646x EVM",
 };
 
 static void __init evm_init_video(void)
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index f6e4d04..49335b0 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -114,6 +114,14 @@ config VIDEO_IR_I2C
 menu "Encoders/decoders and other helper chips"
 	depends on !VIDEO_HELPER_CHIPS_AUTO
 
+config VIDEO_FPGA_SUBDEV
+	tristate "Subdevice for custom made chips"
+	depends on VIDEO_V4L2
+	---help---
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called fpga-subdev.
+
 comment "Audio decoders"
 
 config VIDEO_TVAUDIO
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 40f98fb..3ce4434 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
 
 # And now the v4l2 drivers:
 
+obj-$(CONFIG_VIDEO_FPGA_SUBDEV) += fpga_subdev.o
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
 obj-$(CONFIG_VIDEO_ZORAN) += zoran/
 obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
index 14b9adb..1305c66 100644
--- a/drivers/media/video/davinci/vpif_capture.c
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -38,6 +38,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/fpga_subdev.h>
 
 #include "vpif_capture.h"
 #include "vpif.h"
@@ -2319,12 +2320,20 @@ static __init int vpif_probe(struct platform_device *pdev)
 
 	for (i = 0; i < subdev_count; i++) {
 		subdevdata = &config->subdev_info[i];
-		vpif_obj.sd[i] =
-			v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
-						  i2c_adap,
-						  subdevdata->name,
-						  &subdevdata->board_info,
-						  NULL);
+		if (subdevdata->board_info.addr) {
+			/* i2c device */
+			vpif_obj.sd[i] =
+				v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+						i2c_adap,
+						NULL,
+						&subdevdata->board_info,
+						NULL);
+		} else {
+			/* custom platform device */
+			vpif_obj.sd[i] =
+				fpga_subdev_init(&vpif_obj.v4l2_dev,
+						subdevdata->board_info.platform_data);
+		}
 
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 14b9adb..1305c66 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/version.h>
 #include <linux/slab.h>
+#include <media/fpga_subdev.h>
 
 #include <asm/irq.h>
 #include <asm/page.h>
@@ -1739,7 +1742,7 @@
 	/* Allocate memory for six channel objects */
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 		vpif_obj.dev[i] =
-		    kmalloc(sizeof(struct channel_obj), GFP_KERNEL);
+		    kzalloc(sizeof(struct channel_obj), GFP_KERNEL);
 		/* If memory allocation fails, return error */
 		if (!vpif_obj.dev[i]) {
 			free_channel_objects_index = i;
@@ -1897,10 +1900,18 @@
 	}
 
 	for (i = 0; i < subdev_count; i++) {
-		vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+		if (subdevdata[i].board_info.addr) {
+			/* i2c device */
+			vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
 						i2c_adap, subdevdata[i].name,
 						&subdevdata[i].board_info,
 						NULL);
+		} else {
+			/* custom platform device */
+			vpif_obj.sd[i] =
+				fpga_subdev_init(&vpif_obj.v4l2_dev,
+						subdevdata[i].board_info.platform_data);
+		}
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
 			goto probe_subdev_out;
diff --git a/drivers/media/video/fpga_subdev.c b/drivers/media/video/fpga_subdev.c
new file mode 100644
index 0000000..b57fe81
--- /dev/null
+++ b/drivers/media/video/fpga_subdev.c
@@ -0,0 +1,97 @@
+/*
+ * This subdevice driver can be used with custom made subdevices (e.g. FPGA's)
+ * that need some or no configuration. The driver calls functions specified in
+ * the board definition file.
+ *
+ * Copyright (C) 2010 Cisco Systems AS
+ * Author: Mats Randgaard <mats.randgaard@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <media/fpga_subdev.h>
+#include <media/v4l2-device.h>
+
+MODULE_DESCRIPTION("FPGA subdevice");
+MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
+MODULE_LICENSE("GPL");
+
+/* Debug functions */
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-2)");
+
+static int fpga_subdev_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct fpga_subdev_platform_data *pdata = v4l2_get_subdevdata(sd);
+
+	if (!pdata || !pdata->ops || !pdata->ops->s_power)
+		return -ENOIOCTLCMD;
+
+	return pdata->ops->s_power(pdata, sd, on);
+}
+
+static int fpga_subdev_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct fpga_subdev_platform_data *pdata = v4l2_get_subdevdata(sd);
+
+	if (!pdata || !pdata->ops || !pdata->ops->s_stream)
+		return -ENOIOCTLCMD;
+
+	return pdata->ops->s_stream(pdata, sd, enable);
+}
+
+static const struct v4l2_subdev_core_ops fpga_subdev_core_ops = {
+	.s_power = fpga_subdev_s_power,
+};
+
+static const struct v4l2_subdev_video_ops fpga_subdev_video_ops = {
+	.s_stream = fpga_subdev_s_stream,
+};
+
+static const struct v4l2_subdev_ops fpga_subdev_ops = {
+	.core = &fpga_subdev_core_ops,
+	.video = &fpga_subdev_video_ops,
+};
+
+
+struct v4l2_subdev *fpga_subdev_init(struct v4l2_device *v4l2_dev,
+		struct fpga_subdev_platform_data *platform_data)
+{
+	struct v4l2_subdev *sd;
+
+	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (!sd) {
+		v4l2_err(v4l2_dev, "unable to allocate memory for subdevice\n");
+		return NULL;
+	}
+
+	v4l2_subdev_init(sd, &fpga_subdev_ops);
+
+	v4l2_set_subdevdata(sd, platform_data);
+
+	snprintf(sd->name, sizeof(sd->name), "%s fpga-subdev", v4l2_dev->name);
+
+	if (v4l2_device_register_subdev(v4l2_dev, sd)) {
+		kfree(sd);
+		v4l2_err(v4l2_dev, "unable to register v4l2 device\n");
+		return NULL;
+	}
+
+	v4l2_info(sd, "%s driver registered\n", sd->name);
+
+	return sd;
+}
diff --git a/include/media/fpga_subdev.h b/include/media/fpga_subdev.h
new file mode 100644
index 0000000..0651c05
--- /dev/null
+++ b/include/media/fpga_subdev.h
@@ -0,0 +1,44 @@
+/*
+ * This subdevice driver can be used with custom made subdevices (e.g. FPGA's)
+ * that need some or no configuration. The driver calls functions specified in
+ * the board definition file.
+ *
+ * Copyright (C) 2010 Cisco Systems AS
+ * Author: Mats Randgaard <mats.randgaard@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _FPGA_SUBDEV_H_
+#define _FPGA_SUBDEV_H_
+
+#include <media/v4l2-subdev.h>
+
+struct fpga_subdev_platform_data;
+
+struct fpga_subdev_ops {
+	int (*s_stream)(struct fpga_subdev_platform_data *pdata,
+			struct v4l2_subdev *sd, int enable);
+	int (*s_power)(struct fpga_subdev_platform_data *pdata,
+			struct v4l2_subdev *sd, int on);
+};
+
+struct fpga_subdev_platform_data {
+	void *priv;
+	struct fpga_subdev_ops *ops;
+};
+
+struct v4l2_subdev *fpga_subdev_init(struct v4l2_device *v4l2_dev,
+		struct fpga_subdev_platform_data *platform_data);
+#endif
