V4L/DVB (13699): [Mantis, MB86A16] Initial checkin: Mantis, MB86A16

Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
new file mode 100644
index 0000000..4ba16d0
--- /dev/null
+++ b/drivers/media/dvb/mantis/Kconfig
@@ -0,0 +1,13 @@
+config DVB_MANTIS
+	tristate "MANTIS based cards"
+	depends on DVB_CORE && PCI && I2C
+	select DVB_MB86A16
+	select DVB_CU1216
+	select DVB_ZL10353
+	select DVB_STV0299
+	select DVB_PLL
+	help
+	  Support for PCI cards based on the Mantis PCI bridge.
+	  Say Y when you have a Mantis based DVB card and want to use it.
+
+	  If unsure say N.
diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/dvb/mantis/Makefile
new file mode 100644
index 0000000..a980ff2
--- /dev/null
+++ b/drivers/media/dvb/mantis/Makefile
@@ -0,0 +1,7 @@
+mantis-objs = mantis_core.o mantis_dma.o mantis_pci.o mantis_i2c.o	\
+	mantis_dvb.o mantis_vp1033.o mantis_vp1034.o mantis_vp2033.o	\
+	mantis_vp3030.o
+
+obj-$(CONFIG_DVB_MANTIS) += mantis.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
new file mode 100644
index 0000000..ba360f884
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -0,0 +1,135 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_COMMON_H
+#define __MANTIS_COMMON_H
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include <linux/i2c.h>
+#include "mantis_reg.h"
+
+#define MANTIS_ERROR		0
+#define MANTIS_NOTICE		1
+#define MANTIS_INFO		2
+#define MANTIS_DEBUG		3
+
+#define dprintk(x, y, z, format, arg...) do {								\
+	if (z) {											\
+		if	((x > MANTIS_ERROR) && (x > y))							\
+			printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if	((x > MANTIS_NOTICE) && (x > y))						\
+			printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if ((x > MANTIS_INFO) && (x > y))							\
+			printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+		else if ((x > MANTIS_DEBUG) && (x > y))							\
+			printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg);	\
+	} else {											\
+		if (x > y)										\
+			printk(format , ##arg);								\
+	}												\
+} while(0)
+
+#define mwrite(dat, addr)	writel((dat), addr)
+#define mread(addr)		readl(addr)
+
+#define mmwrite(dat, addr)	mwrite((dat), (mantis->mantis_mmio + (addr)))
+#define mmread(addr)		mread(mantis->mantis_mmio + (addr))
+#define mmand(dat, addr)	mmwrite((dat) & mmread(addr), addr)
+#define mmor(dat, addr)		mmwrite((dat) | mmread(addr), addr)
+#define mmaor(dat, addr)	mmwrite((dat) | ((mask) & mmread(addr)), addr)
+
+
+struct mantis_pci {
+	/*	PCI stuff		*/
+	u16			vendor_id;
+	u16			device_id;
+	u8			latency;
+
+	struct			pci_dev *pdev;
+
+	unsigned long		mantis_addr;
+	volatile void __iomem 	*mantis_mmio;
+
+	u8			irq;
+	u8			revision;
+
+	unsigned int		num;
+	u16			ts_size;
+
+	/*	RISC Core		*/
+	u32			finished_block;
+	u32			last_block;
+	u32			line_bytes;
+	u32			line_count;
+	u32			risc_pos;
+	u8			*buf_cpu;
+	dma_addr_t		buf_dma;
+	u32			*risc_cpu;
+	dma_addr_t		risc_dma;
+
+	struct tasklet_struct	tasklet;
+
+	struct i2c_adapter	adapter;
+	int			i2c_rc;
+	wait_queue_head_t	i2c_wq;
+
+	/*	DVB stuff		*/
+	struct dvb_adapter	dvb_adapter;
+	struct dvb_frontend	*fe;
+	struct dvb_demux	demux;
+	struct dmxdev		dmxdev;
+	struct dmx_frontend	fe_hw;
+	struct dmx_frontend	fe_mem;
+	struct dvb_net		dvbnet;
+
+	u8			feeds;
+
+	struct mantis_config	*config;
+
+	u32 			mantis_int_stat;
+	u32 			mantis_int_mask;
+
+	/*	board specific		*/
+	u8			mac_address[8];
+	u32			sub_vendor_id;
+	u32			sub_device_id;
+
+	 /*	A12 A13 A14		*/
+	int			gpio_status;};
+
+extern unsigned int verbose;
+extern unsigned int devs;
+extern unsigned int i2c;
+extern int mantis_dvb_init(struct mantis_pci *mantis);
+extern int mantis_frontend_init(struct mantis_pci *mantis);
+extern int mantis_dvb_exit(struct mantis_pci *mantis);
+extern void mantis_dma_xfer(unsigned long data);
+extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
+
+#endif //__MANTIS_COMMON_H
diff --git a/drivers/media/dvb/mantis/mantis_core.c b/drivers/media/dvb/mantis/mantis_core.c
new file mode 100644
index 0000000..1112277
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_core.c
@@ -0,0 +1,215 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 "mantis_common.h"
+#include "mantis_core.h"
+
+
+static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
+{
+	int err;
+	struct i2c_msg msg[] = {
+		{
+			.addr = 0x50,
+			.flags = 0,
+			.buf = data,
+			.len = 1
+		},{
+			.addr = 0x50,
+			.flags = I2C_M_RD,
+			.buf = data,
+			.len = length
+		},
+	};
+	if ((err = i2c_transfer(&mantis->adapter, msg, 2)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
+			err, data[0], data[1]);
+
+		return err;
+	}
+	msleep_interruptible(2);
+
+	return 0;
+}
+
+static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
+{
+	int err;
+
+	struct i2c_msg msg = {
+		.addr = 0x50,
+		.flags = 0,
+		.buf = data,
+		.len = length
+	};
+
+	if ((err = i2c_transfer(&mantis->adapter, &msg, 1)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
+			err, length, data[0], data[1]);
+
+		return err;
+	}
+
+	return 0;
+}
+
+static int get_subdevice_id(struct mantis_pci *mantis)
+{
+	int err;
+	static u8 sub_device_id[2];
+
+	mantis->sub_device_id = 0;
+	sub_device_id[0] = 0xfc;
+	if ((err = read_eeprom_byte(mantis, &sub_device_id[0], 2)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
+		return err;
+	}
+	mantis->sub_device_id = (sub_device_id[0] << 8) | sub_device_id[1];
+	dprintk(verbose, MANTIS_ERROR, 1, "Sub Device ID=[0x%04x]",
+		mantis->sub_device_id);
+
+	return 0;
+}
+
+static int get_subvendor_id(struct mantis_pci *mantis)
+{
+	int err;
+	static u8 sub_vendor_id[2];
+
+	mantis->sub_vendor_id = 0;
+	sub_vendor_id[0] = 0xfe;
+	if ((err = read_eeprom_byte(mantis, &sub_vendor_id[0], 2)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
+		return err;
+	}
+	mantis->sub_vendor_id = (sub_vendor_id[0] << 8) | sub_vendor_id[1];
+	dprintk(verbose, MANTIS_ERROR, 1, "Sub Vendor ID=[0x%04x]",
+		mantis->sub_vendor_id);
+
+	return 0;
+}
+
+static int get_mac_address(struct mantis_pci *mantis)
+{
+	int err;
+
+	mantis->mac_address[0] = 0x08;
+	if ((err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
+
+		return err;
+	}
+	dprintk(verbose, MANTIS_ERROR, 1,
+		"MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
+		mantis->mac_address[0], mantis->mac_address[1],
+		mantis->mac_address[2],	mantis->mac_address[3],
+		mantis->mac_address[4], mantis->mac_address[5]);
+
+	return 0;
+}
+
+
+int mantis_core_init(struct mantis_pci *mantis)
+{
+	int err = 0;
+
+	if ((err = mantis_i2c_init(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
+		return err;
+	}
+	if ((err = get_mac_address(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
+		return err;
+	}
+	if ((err = get_subvendor_id(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "get Sub vendor ID failed");
+		return err;
+	}
+	if ((err = get_subdevice_id(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "get Sub device ID failed");
+		return err;
+	}
+	if ((err = mantis_dma_init(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
+		return err;
+	}
+	if ((err = mantis_dvb_init(mantis)) < 0) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
+		return err;
+	}
+
+	return 0;
+}
+
+int mantis_core_exit(struct mantis_pci *mantis)
+{
+
+	mantis_dma_stop(mantis);
+	dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");
+	if (mantis_dma_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");
+	if (mantis_dvb_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed");
+	if (mantis_i2c_exit(mantis) < 0)
+		dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed");
+
+	return 0;
+}
+
+void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
+{
+	u32 reg;
+
+	if (value)
+		reg = 0x0000;
+	else
+		reg = 0xffff;
+
+	reg = (value << bitpos);
+
+	mmwrite(mmread(MANTIS_GPIF_ADDR) | reg, MANTIS_GPIF_ADDR);
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+	udelay(100);
+	mmwrite(mmread(MANTIS_GPIF_ADDR) | reg, MANTIS_GPIF_ADDR);
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+}
+
+
+//direction = 0 , no CI passthrough ; 1 , CI passthrough
+void mantis_set_direction(struct mantis_pci *mantis, int direction)
+{
+	u32 reg;
+
+	reg = mmread(0x28);
+	dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup");
+	if (direction == 0x01) { //to CI
+		reg |= 0x04;
+		mmwrite(reg, 0x28);
+		reg &= 0xff - 0x04;
+		mmwrite(reg, 0x28);
+	} else {
+		reg &= 0xff - 0x04;
+		mmwrite(reg, 0x28);
+		reg |= 0x04;
+		mmwrite(reg, 0x28);
+	}
+}
diff --git a/drivers/media/dvb/mantis/mantis_core.h b/drivers/media/dvb/mantis/mantis_core.h
new file mode 100644
index 0000000..31b2a75
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_core.h
@@ -0,0 +1,61 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_CORE_H
+#define __MANTIS_CORE_H
+
+#include "mantis_common.h"
+
+
+#define FE_TYPE_SAT	0
+#define FE_TYPE_CAB	1
+#define FE_TYPE_TER	2
+
+#define FE_TYPE_TS204	0
+#define FE_TYPE_TS188	1
+
+
+struct vendorname {
+	__u8  *sub_vendor_name;
+	__u32 sub_vendor_id;
+};
+
+struct devicetype {
+	__u8  *sub_device_name;
+	__u32 sub_device_id;
+	__u8  device_type;
+	__u32 type_flags;
+};
+
+
+extern int mantis_dma_init(struct mantis_pci *mantis);
+extern int mantis_dma_exit(struct mantis_pci *mantis);
+extern void mantis_dma_start(struct mantis_pci *mantis);
+extern void mantis_dma_stop(struct mantis_pci *mantis);
+extern int mantis_i2c_init(struct mantis_pci *mantis);
+extern int mantis_i2c_exit(struct mantis_pci *mantis);
+extern int mantis_core_init(struct mantis_pci *mantis);
+extern int mantis_core_exit(struct mantis_pci *mantis);
+//extern void mantis_fe_powerup(struct mantis_pci *mantis);
+//extern void mantis_fe_powerdown(struct mantis_pci *mantis);
+//extern void mantis_fe_reset(struct dvb_frontend *fe);
+extern void mantis_set_direction(struct mantis_pci *mantis, int direction);
+
+#endif //__MANTIS_CORE_H
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
new file mode 100644
index 0000000..9e3aa5e
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -0,0 +1,238 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 <asm/page.h>
+#include <linux/vmalloc.h>
+#include "mantis_common.h"
+
+#define RISC_WRITE		(0x01 << 28)
+#define RISC_JUMP		(0x07 << 28)
+#define RISC_IRQ		(0x01 << 24)
+
+#define RISC_STATUS(status)	((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
+#define RISC_FLUSH()		mantis->risc_pos = 0
+#define RISC_INSTR(opcode)	mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)
+
+#define MANTIS_BUF_SIZE		64 * 1024
+#define MANTIS_BLOCK_BYTES	(MANTIS_BUF_SIZE >> 4)
+#define MANTIS_BLOCK_COUNT	(1 << 4)
+#define MANTIS_RISC_SIZE	PAGE_SIZE
+
+int mantis_dma_exit(struct mantis_pci *mantis)
+{
+	if (mantis->buf_cpu) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"DMA=0x%lx cpu=0x%p size=%d",
+			(unsigned long) mantis->buf_dma,
+			 mantis->buf_cpu,
+			 MANTIS_BUF_SIZE);
+
+		pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE,
+				    mantis->buf_cpu, mantis->buf_dma);
+
+		mantis->buf_cpu = NULL;
+	}
+	if (mantis->risc_cpu) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"RISC=0x%lx cpu=0x%p size=%lx",
+			(unsigned long) mantis->risc_dma,
+			mantis->risc_cpu,
+			MANTIS_RISC_SIZE);
+
+		pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE,
+				    mantis->risc_cpu, mantis->risc_dma);
+
+		mantis->risc_cpu = NULL;
+	}
+
+	return 0;
+}
+
+static inline int mantis_alloc_buffers(struct mantis_pci *mantis)
+{
+	if (!mantis->buf_cpu) {
+		mantis->buf_cpu = pci_alloc_consistent(mantis->pdev,
+						       MANTIS_BUF_SIZE,
+						       &mantis->buf_dma);
+		if (!mantis->buf_cpu) {
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"DMA buffer allocation failed");
+
+			goto err;
+		}
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"DMA=0x%lx cpu=0x%p size=%d",
+			(unsigned long) mantis->buf_dma,
+			mantis->buf_cpu, MANTIS_BUF_SIZE);
+	}
+	if (!mantis->risc_cpu) {
+		mantis->risc_cpu = pci_alloc_consistent(mantis->pdev,
+							MANTIS_RISC_SIZE,
+							&mantis->risc_dma);
+
+		if (!mantis->risc_cpu) {
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"RISC program allocation failed");
+
+			mantis_dma_exit(mantis);
+
+			goto err;
+		}
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"RISC=0x%lx cpu=0x%p size=%lx",
+			(unsigned long) mantis->risc_dma,
+			mantis->risc_cpu, MANTIS_RISC_SIZE);
+	}
+
+	return 0;
+err:
+	dprintk(verbose, MANTIS_ERROR, 1, "Out of memory (?) .....");
+	return -ENOMEM;
+}
+
+static inline int mantis_calc_lines(struct mantis_pci *mantis)
+{
+	mantis->line_bytes = MANTIS_BLOCK_BYTES;
+	mantis->line_count = MANTIS_BLOCK_COUNT;
+
+	while (mantis->line_bytes > 4095) {
+		mantis->line_bytes >>= 1;
+		mantis->line_count <<= 1;
+	}
+
+	dprintk(verbose, MANTIS_DEBUG, 1,
+		"Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]",
+		MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count);
+
+	if (mantis->line_count > 255) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Buffer size error");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int mantis_dma_init(struct mantis_pci *mantis)
+{
+	int err = 0;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DMA init");
+	if (mantis_alloc_buffers(mantis) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Error allocating DMA buffer");
+
+		// Stop RISC Engine
+//		mmwrite(mmread(MANTIS_DMA_CTL) & ~MANTIS_RISC_EN, MANTIS_DMA_CTL);
+		mmwrite(0, MANTIS_DMA_CTL);
+
+		goto err;
+	}
+	if ((err = mantis_calc_lines(mantis)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Mantis calc lines failed");
+
+		goto err;
+	}
+
+	return 0;
+err:
+	return err;
+}
+
+
+
+static inline void mantis_risc_program(struct mantis_pci *mantis)
+{
+	u32 buf_pos = 0;
+	u32 line;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis create RISC program");
+	RISC_FLUSH();
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u",
+		mantis->line_count, mantis->line_bytes);
+
+	for (line = 0; line < mantis->line_count; line++) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line);
+		if (!(buf_pos % MANTIS_BLOCK_BYTES)) {
+			RISC_INSTR(RISC_WRITE	|
+				   RISC_IRQ	|
+				   RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) +
+				   (MANTIS_BLOCK_COUNT - 1)) %
+				    MANTIS_BLOCK_COUNT) |
+				    mantis->line_bytes);
+		} else {
+			RISC_INSTR(RISC_WRITE	| mantis->line_bytes);
+		}
+		RISC_INSTR(mantis->buf_dma + buf_pos);
+		buf_pos += mantis->line_bytes;
+	}
+	RISC_INSTR(RISC_JUMP);
+	RISC_INSTR(mantis->risc_dma);
+}
+
+void mantis_dma_start(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis Start DMA engine");
+
+	mantis_risc_program(mantis);
+	mmwrite(cpu_to_le32(mantis->risc_dma), MANTIS_RISC_START);
+	mmwrite(MANTIS_GPIF_RDWRN, MANTIS_GPIF_ADDR);
+
+	mmwrite(0, MANTIS_DMA_CTL);
+	mantis->last_block = mantis->finished_block = 0;
+
+	mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK);
+
+	mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN
+			       | MANTIS_RISC_EN, MANTIS_DMA_CTL);
+
+}
+
+void mantis_dma_stop(struct mantis_pci *mantis)
+{
+	u32 stat = 0, mask = 0;
+
+	stat = mmread(MANTIS_INT_STAT);
+	mask = mmread(MANTIS_INT_MASK);
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
+
+	mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN |
+					    MANTIS_DCAP_EN |
+					    MANTIS_RISC_EN)), MANTIS_DMA_CTL);
+
+	mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT);
+
+	mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI |
+					    MANTIS_INT_RISCEN), MANTIS_INT_MASK);
+}
+
+
+void mantis_dma_xfer(unsigned long data)
+{
+	struct mantis_pci *mantis = (struct mantis_pci *) data;
+
+	while (mantis->last_block != mantis->finished_block) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
+			mantis->last_block, mantis->finished_block);
+
+		(mantis->ts_size ? dvb_dmx_swfilter_204: dvb_dmx_swfilter)
+		(&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);
+		mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT;
+	}
+}
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c
new file mode 100644
index 0000000..5830d4a
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_dvb.c
@@ -0,0 +1,304 @@
+/*
+	Mantis PCI bridge driver
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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/bitops.h>
+#include "mantis_common.h"
+#include "mantis_core.h"
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "mantis_vp1033.h"
+#include "mantis_vp1034.h"
+#include "mantis_vp2033.h"
+#include "mantis_vp3030.h"
+
+/*	Tuner power supply control	*/
+void mantis_fe_powerup(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Power ON");
+	gpio_set_bits(mantis, 0x0c, 1);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 0x0c, 1);
+	msleep_interruptible(100);
+}
+
+void mantis_fe_powerdown(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Power OFF");
+	gpio_set_bits(mantis, 0x0c, 0);
+}
+
+static int mantis_fe_reset(struct dvb_frontend *fe)
+{
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Reset");
+	gpio_set_bits(mantis, 13, 0);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 0);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 1);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 1);
+
+	return 0;
+}
+
+static int mantis_frontend_reset(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Frontend Reset");
+	gpio_set_bits(mantis, 13, 0);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 0);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 1);
+	msleep_interruptible(100);
+	gpio_set_bits(mantis, 13, 1);
+
+	return 0;
+}
+
+static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct mantis_pci *mantis = dvbdmx->priv;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB Start feed");
+	if (!dvbdmx->dmx.frontend) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "no frontend ?");
+		return -EINVAL;
+	}
+	mantis->feeds++;
+	dprintk(verbose, MANTIS_DEBUG, 1,
+		"mantis start feed, feeds=%d",
+		mantis->feeds);
+
+	if (mantis->feeds == 1)	 {
+		dprintk(verbose, MANTIS_DEBUG, 1, "mantis start feed & dma");
+		printk("mantis start feed & dma\n");
+		mantis_dma_start(mantis);
+	}
+
+	return mantis->feeds;
+}
+
+static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
+	struct mantis_pci *mantis = dvbdmx->priv;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
+	if (!dvbdmx->dmx.frontend) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "no frontend ?");
+		return -EINVAL;
+	}
+	mantis->feeds--;
+	if (mantis->feeds == 0) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "mantis stop feed and dma");
+		printk("mantis stop feed and dma\n");
+		mantis_dma_stop(mantis);
+	}
+	return 0;
+}
+
+int __devinit mantis_dvb_init(struct mantis_pci *mantis)
+{
+	int result;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "dvb_register_adapter");
+	if (dvb_register_adapter(&mantis->dvb_adapter,
+				 "Mantis dvb adapter", THIS_MODULE,
+				 &mantis->pdev->dev) < 0) {
+
+		dprintk(verbose, MANTIS_ERROR, 1, "Error registering adapter");
+		return -ENODEV;
+	}
+	mantis->dvb_adapter.priv = mantis;
+	mantis->demux.dmx.capabilities = DMX_TS_FILTERING	|
+					 DMX_SECTION_FILTERING	|
+					 DMX_MEMORY_BASED_FILTERING;
+
+	mantis->demux.priv = mantis;
+	mantis->demux.filternum = 256;
+	mantis->demux.feednum = 256;
+	mantis->demux.start_feed = mantis_dvb_start_feed;
+	mantis->demux.stop_feed = mantis_dvb_stop_feed;
+	mantis->demux.write_to_decoder = NULL;
+	mantis->ts_size = 1; //188
+	dprintk(verbose, MANTIS_DEBUG, 1, "dvb_dmx_init");
+	if ((result = dvb_dmx_init(&mantis->demux)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"dvb_dmx_init failed, ERROR=%d", result);
+
+		goto err0;
+	}
+	mantis->dmxdev.filternum = 256;
+	mantis->dmxdev.demux = &mantis->demux.dmx;
+	mantis->dmxdev.capabilities = 0;
+	dprintk(verbose, MANTIS_DEBUG, 1, "dvb_dmxdev_init");
+	if ((result = dvb_dmxdev_init(&mantis->dmxdev,
+				      &mantis->dvb_adapter)) < 0) {
+
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"dvb_dmxdev_init failed, ERROR=%d", result);
+		goto err1;
+	}
+	mantis->fe_hw.source = DMX_FRONTEND_0;
+	if ((result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx,
+						     &mantis->fe_hw)) < 0) {
+
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"dvb_dmx_init failed, ERROR=%d", result);
+
+		goto err2;
+	}
+	mantis->fe_mem.source = DMX_MEMORY_FE;
+	if ((result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx,
+						     &mantis->fe_mem)) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"dvb_dmx_init failed, ERROR=%d", result);
+
+		goto err3;
+	}
+	if ((result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx,
+							 &mantis->fe_hw)) < 0) {
+
+		dprintk(verbose, MANTIS_ERROR, 1,
+			"dvb_dmx_init failed, ERROR=%d", result);
+
+		goto err4;
+	}
+	dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
+	tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
+	mantis_frontend_init(mantis);
+	return 0;
+
+	/*	Error conditions ..	*/
+err4:
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+err3:
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+err2:
+	dvb_dmxdev_release(&mantis->dmxdev);
+err1:
+	dvb_dmx_release(&mantis->demux);
+err0:
+	dvb_unregister_adapter(&mantis->dvb_adapter);
+
+	return result;
+}
+
+#define MANTIS_VP_1027_DVB_S	0x0013
+#define MANTIS_VP_1033_DVB_S	0x0016
+#define MANTIS_VP_1034_DVB_S	0x0014
+#define MANTIS_VP_1040_DVB_S2
+#define MANTIS_VP_1041_DVB_S2
+#define MANTIS_VP_2033_DVB_C	0x0008
+#define MANTIS_VP_3024_DVB_T	0x0009
+#define MANTIS_VP_3030_DVB_T	0x0024
+
+int __devinit mantis_frontend_init(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Mantis frontend Init");
+	mantis_fe_powerup(mantis);
+	mantis_frontend_reset(mantis);
+	dprintk(verbose, MANTIS_DEBUG, 1, "Device ID=%02x", mantis->sub_device_id);
+	switch (mantis->sub_device_id) {
+	case MANTIS_VP_1033_DVB_S:	// VP-1033
+		dprintk(verbose, MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
+		mantis->fe = stv0299_attach(&lgtdqcs001f_config,
+					    &mantis->adapter);
+
+		if (mantis->fe) {
+			mantis->fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"found STV0299 DVB-S frontend @ 0x%02x",
+				lgtdqcs001f_config.demod_address);
+
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"Mantis DVB-S STV0299 frontend attach success");
+		}
+		break;
+	case MANTIS_VP_1034_DVB_S:	// VP-1034
+		dprintk(verbose, MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
+		mantis->fe = mb86a16_attach(&vp1034_config, &mantis->adapter);
+		if (mantis->fe) {
+			dprintk(verbose, MANTIS_ERROR, 1,
+			"found MB86A16 DVB-S/DSS frontend @0x%02x",
+			vp1034_config.demod_address);
+
+		}
+		break;
+	case MANTIS_VP_2033_DVB_C:	// VP-2033
+		dprintk(verbose, MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
+		mantis->fe = cu1216_attach(&philips_cu1216_config, &mantis->adapter);
+		if (mantis->fe) {
+			mantis->fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set;
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"found Philips CU1216 DVB-C frontend @ 0x%02x",
+				philips_cu1216_config.demod_address);
+
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"Mantis DVB-C Philips CU1216 frontend attach success");
+
+		}
+		break;
+	default:
+		dprintk(verbose, MANTIS_DEBUG, 1, "Unknown frontend:[0x%02x]",
+			mantis->sub_device_id);
+
+		return -ENODEV;
+	}
+	if (mantis->fe == NULL) {
+		dprintk(verbose, MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
+		return -ENODEV;
+	} else {
+		if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
+			dprintk(verbose, MANTIS_ERROR, 1,
+				"ERROR: Frontend registration failed");
+
+			if (mantis->fe->ops.release)
+				mantis->fe->ops.release(mantis->fe);
+
+			mantis->fe = NULL;
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+
+int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
+{
+	tasklet_kill(&mantis->tasklet);
+	dvb_net_release(&mantis->dvbnet);
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
+	mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
+	dvb_dmxdev_release(&mantis->dmxdev);
+	dvb_dmx_release(&mantis->demux);
+
+	if (mantis->fe)
+		dvb_unregister_frontend(mantis->fe);
+	dprintk(verbose, MANTIS_DEBUG, 1, "dvb_unregister_adapter");
+	dvb_unregister_adapter(&mantis->dvb_adapter);
+
+	return 0;
+}
diff --git a/drivers/media/dvb/mantis/mantis_i2c.c b/drivers/media/dvb/mantis/mantis_i2c.c
new file mode 100644
index 0000000..cfecb34
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_i2c.c
@@ -0,0 +1,189 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <linux/ioport.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include "mantis_common.h"
+
+#define I2C_HW_B_MANTIS		0x1c
+
+static int mantis_ack_wait(struct mantis_pci *mantis)
+{
+	int rc = 0;
+
+	if (wait_event_interruptible_timeout(mantis->i2c_wq,
+					     mantis->mantis_int_stat & MANTIS_INT_I2CRACK,
+					     msecs_to_jiffies(50)) == -ERESTARTSYS)
+
+		rc = -EREMOTEIO;
+/*
+	// Wait till we are done
+	while (mantis->mantis_int_stat & MANTIS_INT_I2CRACK){
+		if (mantis->mantis_int_stat & MANTIS_INT_I2CDONE) {
+			mantis->mantis_int_stat &= ~MANTIS_INT_I2CRACK;
+//			dprintk(verbose, MANTIS_DEBUG, 1, "SLAVE RACK 'ed .. Waiting for I2CDONE");
+			break;
+		}
+	}
+
+	if (mantis->mantis_int_stat & MANTIS_INT_I2CDONE) {
+//		dprintk(verbose, MANTIS_DEBUG, 1, "Mantis Int I2CDONE");
+		rc = 1;
+	}
+
+	mantis->mantis_int_stat &= ~MANTIS_INT_I2CDONE;
+*/
+	// ..
+	if (mantis->mantis_int_stat & MANTIS_INT_I2CRACK)
+		msleep_interruptible(10);
+
+	return rc;
+}
+
+static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+	u32 rxd, i;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Address=[0x%02x]", msg->addr);
+	for (i = 0; i < msg->len; i++) {
+		rxd = (msg->addr << 25) | (1 << 24)
+					| MANTIS_I2C_RATE_3
+					| MANTIS_I2C_STOP
+					| MANTIS_I2C_PGMODE;
+
+		if (i == (msg->len - 1))
+			rxd &= ~MANTIS_I2C_STOP;
+
+		mmwrite(rxd, MANTIS_I2CDATA_CTL);
+		if (mantis_ack_wait(mantis) < 0) {
+			dprintk(verbose, MANTIS_DEBUG, 1, "ACK failed<R>");
+			return -EIO;
+		}
+		rxd = mmread(MANTIS_I2CDATA_CTL);
+		msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
+		dprintk(verbose, MANTIS_DEBUG, 1,
+			"Data<R[%d]>=[0x%02x]", i, msg->buf[i]);
+
+		msleep_interruptible(2);
+	}
+
+	return 0;
+}
+
+static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
+{
+	int i;
+	u32 txd = 0;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Address=[0x%02x]", msg->addr);
+	for (i = 0; i < msg->len; i++) {
+		dprintk(verbose, MANTIS_DEBUG, 1, "Data<W[%d]>=[0x%02x]", i, msg->buf[i]);
+		txd = (msg->addr << 25) | (msg->buf[i] << 8)
+					| MANTIS_I2C_RATE_3
+					| MANTIS_I2C_STOP
+					| MANTIS_I2C_PGMODE;
+
+		if (i == (msg->len - 1))
+			txd &= ~MANTIS_I2C_STOP;
+
+		mmwrite(txd, MANTIS_I2CDATA_CTL);
+		if (mantis_ack_wait(mantis) < 0) {
+			dprintk(verbose, MANTIS_DEBUG, 1, "ACK failed<W>");
+			return -1;
+		}
+		udelay(500);
+	}
+
+	return 0;
+}
+
+static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
+{
+	int ret = 0, i;
+	struct mantis_pci *mantis;
+
+	mantis = i2c_get_adapdata(adapter);
+	for (i = 0; i < num; i++) {
+		if (msgs[i].flags & I2C_M_RD)
+			ret = mantis_i2c_read(mantis, &msgs[i]);
+		else
+			ret = mantis_i2c_write(mantis, &msgs[i]);
+
+		if (ret < 0)
+			return ret;
+	}
+
+	return num;
+}
+
+static u32 mantis_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm mantis_algo = {
+	.master_xfer		= mantis_i2c_xfer,
+	.functionality		= mantis_i2c_func,
+};
+
+static struct i2c_adapter mantis_i2c_adapter = {
+	.owner			= THIS_MODULE,
+	.name			= "Mantis I2C",
+	.id			= I2C_HW_B_MANTIS,
+	.class			= I2C_CLASS_TV_DIGITAL,
+	.algo			= &mantis_algo,
+};
+
+int __devinit mantis_i2c_init(struct mantis_pci *mantis)
+{
+	u32 intstat;
+
+	memcpy(&mantis->adapter, &mantis_i2c_adapter, sizeof (mantis_i2c_adapter));
+	i2c_set_adapdata(&mantis->adapter, mantis);
+	mantis->i2c_rc = i2c_add_adapter(&mantis->adapter);
+	if (mantis->i2c_rc < 0)
+		return mantis->i2c_rc;
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "Initializing I2C ..");
+
+	// Clear all interrupts
+	intstat = mmread(MANTIS_INT_STAT);
+	mmwrite(intstat, MANTIS_INT_STAT);
+
+	mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_I2CDONE,
+					  MANTIS_INT_MASK);
+
+	dprintk(verbose, MANTIS_DEBUG, 1, "[0x%08x/%08x]",
+		mmread(MANTIS_INT_STAT), mmread(MANTIS_INT_MASK));
+
+	return 0;
+}
+
+int __devexit mantis_i2c_exit(struct mantis_pci *mantis)
+{
+	dprintk(verbose, MANTIS_DEBUG, 1, "Removing I2C adapter");
+	return i2c_del_adapter(&mantis->adapter);
+}
diff --git a/drivers/media/dvb/mantis/mantis_reg.h b/drivers/media/dvb/mantis/mantis_reg.h
new file mode 100644
index 0000000..1b54e09
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_reg.h
@@ -0,0 +1,109 @@
+/*
+	Mantis PCI bridge driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_REG_H
+#define __MANTIS_REG_H
+
+// Interrupts
+#define MANTIS_INT_STAT			0x00
+#define MANTIS_INT_MASK			0x04
+
+#define MANTIS_INT_RISCSTAT		(0x0f << 28)
+#define MANTIS_INT_RISCEN		(0x01 << 27)
+#define MANTIS_INT_I2CRACK		(0x01 << 26)
+
+//#define MANTIS_INT_GPIF			(0xff << 12)
+
+#define MANTIS_INT_PCMCIA7		(0x01 << 19)
+#define MANTIS_INT_PCMCIA6		(0x01 << 18)
+#define MANTIS_INT_PCMCIA5		(0x01 << 17)
+#define MANTIS_INT_PCMCIA4		(0x01 << 16)
+#define MANTIS_INT_PCMCIA3		(0x01 << 15)
+#define MANTIS_INT_PCMCIA2		(0x01 << 14)
+#define MANTIS_INT_PCMCIA1		(0x01 << 13)
+#define MANTIS_INT_PCMCIA0		(0x01 << 12)
+#define MANTIS_INT_IRQ1			(0x01 << 11)
+#define MANTIS_INT_IRQ0			(0x01 << 10)
+#define MANTIS_INT_OCERR		(0x01 <<  8)
+#define MANTIS_INT_PABORT		(0x01 <<  7)
+#define MANTIS_INT_RIPERR		(0x01 <<  6)
+#define MANTIS_INT_PPERR		(0x01 <<  5)
+#define MANTIS_INT_FTRGT		(0x01 <<  3)
+#define MANTIS_INT_RISCI		(0x01 <<  1)
+#define MANTIS_INT_I2CDONE		(0x01 <<  0)
+
+// DMA
+#define MANTIS_DMA_CTL			0x08
+#define	MANTIS_I2C_RD			(0x01 <<  7)
+#define MANTIS_I2C_WR			(0x01 <<  6)
+#define MANTIS_DCAP_MODE		(0x01 <<  5)
+#define MANTIS_FIFO_TP_4		(0x00 <<  3)
+#define MANTIS_FIFO_TP_8		(0x01 <<  3)
+#define MANTIS_FIFO_TP_16		(0x02 <<  3)
+#define MANTIS_FIFO_EN			(0x01 <<  2)
+#define MANTIS_DCAP_EN			(0x01 <<  1)
+#define MANTIS_RISC_EN			(0x01 <<  0)
+
+#define MANTIS_RISC_START		0x10
+#define MANTIS_RISC_PC			0x14
+
+// I2C
+#define MANTIS_I2CDATA_CTL		0x18
+#define MANTIS_I2C_RATE_1		(0x00 <<  6)
+#define MANTIS_I2C_RATE_2		(0x01 <<  6)
+#define MANTIS_I2C_RATE_3		(0x02 <<  6)
+#define MANTIS_I2C_RATE_4		(0x03 <<  6)
+#define MANTIS_I2C_STOP			(0x01 <<  5)
+#define MANTIS_I2C_PGMODE		(0x01 <<  3)
+
+#define MANTIS_GPIF_IRQCFG		0x98
+#define MANTIS_GPIF_IRQPOL		(0x01 <<  8)
+#define MANTIS_MASK_WRACK		(0x01 <<  7)
+#define MANTIS_MASK_BRRDY		(0x01 <<  6)
+#define MANTIS_MASK_OVFLW		(0x01 <<  5)
+#define MANTIS_MASK_OTHERR		(0x01 <<  4)
+#define MANTIS_MASK_WSTO		(0x01 <<  3)
+#define MANTIS_MASK_EXTIRQ		(0x01 <<  2)
+#define MANTIS_MASK_PLUGIN		(0x01 <<  1)
+#define MANTIS_MASK_PLUGOUT		(0x01 <<  0)
+
+#define MANTIS_GPIF_STATUS		0x9c
+#define MANTIS_SBUF_KILLOP		(0x01 << 15)
+#define MANTIS_SBUF_OPDONE		(0x01 << 14)
+#define MANTIS_SBUF_EMPTY		(0x01 << 13)
+#define MANTIS_GPIF_DETSTAT		(0x01 <<  9)
+#define MANTIS_GPIF_INTSTAT		(0x01 <<  8)
+#define MANTIS_GPIF_WRACK		(0x01 <<  7)
+#define MANTIS_GPIF_BRRDY		(0x01 <<  6)
+#define MANTIS_SBUF_OVFLW		(0x01 <<  5)
+#define MANTIS_GPIF_OTHERR		(0x01 <<  4)
+#define MANTIS_SBUF_WSTO		(0x01 <<  3)
+#define MANTIS_GPIF_EXTIRQ		(0x01 <<  2)
+#define MANTIS_CARD_PLUGIN		(0x01 <<  1)
+#define MANTIS_CARD_PLUGOUT		(0x01 <<  0)
+
+#define MANTIS_GPIF_ADDR		0xb0
+#define MANTIS_GPIF_RDWRN		(0x01 << 31)
+
+#define MANTIS_GPIF_DOUT		0xb4
+#define MANTIS_GPIF_DIN			0xb8
+
+
+#endif //__MANTIS_REG_H
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.c b/drivers/media/dvb/mantis/mantis_vp1033.c
new file mode 100644
index 0000000..720f4fb
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp1033.c
@@ -0,0 +1,151 @@
+/*
+	Mantis VP-1033 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 "mantis_common.h"
+#include "mantis_vp1033.h"
+
+u8 lgtdqcs001f_inittab[] = {
+	0x01, 0x15,
+	0x02, 0x00,
+	0x03, 0x00,
+	0x04, 0x2a,
+	0x05, 0x85,
+	0x06, 0x02,
+	0x07, 0x00,
+	0x08, 0x00,
+	0x0c, 0x01,
+	0x0d, 0x81,
+	0x0e, 0x44,
+	0x0f, 0x94,
+	0x10, 0x3c,
+	0x11, 0x84,
+	0x12, 0xb9,
+	0x13, 0xb5,
+	0x14, 0x4f,
+	0x15, 0xc9,
+	0x16, 0x80,
+	0x17, 0x36,
+	0x18, 0xfb,
+	0x19, 0xcf,
+	0x1a, 0xbc,
+	0x1c, 0x2b,
+	0x1d, 0x27,
+	0x1e, 0x00,
+	0x1f, 0x0b,
+	0x20, 0xa1,
+	0x21, 0x60,
+	0x22, 0x00,
+	0x23, 0x00,
+	0x28, 0x00,
+	0x29, 0x28,
+	0x2a, 0x14,
+	0x2b, 0x0f,
+	0x2c, 0x09,
+	0x2d, 0x05,
+	0x31, 0x1f,
+	0x32, 0x19,
+	0x33, 0xfc,
+	0x34, 0x13,
+	0xff, 0xff,
+};
+
+struct stv0299_config lgtdqcs001f_config = {
+	.demod_address		= 0x68,
+	.inittab		= lgtdqcs001f_inittab,
+	.mclk			= 88000000UL,
+//	.invert = 0,
+	.invert			= 1,
+//	.enhanced_tuning = 0,
+	.skip_reinit		= 0,
+	.lock_output		= STV0229_LOCKOUTPUT_0,
+	.volt13_op0_op1		= STV0299_VOLT13_OP0,
+	.min_delay_ms		= 100,
+	.set_symbol_rate	= lgtdqcs001f_set_symbol_rate,
+//	.pll_set		= lgtdqcs001f_pll_set,
+};
+
+int lgtdqcs001f_tuner_set(struct dvb_frontend *fe,
+			  struct dvb_frontend_parameters *params)
+{
+	u8 buf[4];
+	u32 div;
+
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	struct i2c_msg msg = {
+		.addr = 0x61,
+		.flags = 0,
+		.buf = buf,
+		.len = sizeof (buf)
+	};
+	div = params->frequency / 250;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] =  div & 0xff;
+	buf[2] =  0x83;
+	buf[3] =  0xc0;
+
+	if (params->frequency < 1531000)
+		buf[3] |= 0x04;
+	else
+		buf[3] &= ~0x04;
+	if (i2c_transfer(&mantis->adapter, &msg, 1) < 0) {
+		dprintk(verbose, MANTIS_ERROR, 1, "Write: I2C Transfer failed");
+		return -EIO;
+	}
+	msleep_interruptible(100);
+
+	return 0;
+}
+
+int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
+				u32 srate, u32 ratio)
+{
+	u8 aclk = 0;
+	u8 bclk = 0;
+
+	if (srate < 1500000) {
+		aclk = 0xb7;
+		bclk = 0x47;
+	} else if (srate < 3000000) {
+		aclk = 0xb7;
+		bclk = 0x4b;
+	} else if (srate < 7000000) {
+		aclk = 0xb7;
+		bclk = 0x4f;
+	} else if (srate < 14000000) {
+		aclk = 0xb7;
+		bclk = 0x53;
+	} else if (srate < 30000000) {
+		aclk = 0xb6;
+		bclk = 0x53;
+	} else if (srate < 45000000) {
+		aclk = 0xb4;
+		bclk = 0x51;
+	}
+	stv0299_writereg (fe, 0x13, aclk);
+	stv0299_writereg (fe, 0x14, bclk);
+
+	stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
+	stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
+	stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
+
+	return 0;
+}
diff --git a/drivers/media/dvb/mantis/mantis_vp1033.h b/drivers/media/dvb/mantis/mantis_vp1033.h
new file mode 100644
index 0000000..d50f092
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp1033.h
@@ -0,0 +1,35 @@
+/*
+	Mantis VP-1033 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_VP1033_H
+#define __MANTIS_VP1033_H
+
+#include "stv0299.h"
+#include "dvb_frontend.h"
+
+extern struct stv0299_config lgtdqcs001f_config;
+
+extern int lgtdqcs001f_tuner_set(struct dvb_frontend *fe,
+				 struct dvb_frontend_parameters *params);
+
+extern int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio);
+
+
+#endif // __MANTIS_VP1033_H
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c
new file mode 100644
index 0000000..b85ac29
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp1034.c
@@ -0,0 +1,52 @@
+/*
+	Mantis VP-1034 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 "mantis_common.h"
+#include "mantis_vp1034.h"
+
+struct mb86a16_config vp1034_config = {
+	.demod_address	= 0x08,
+	.set_voltage	= vp1034_set_voltage,
+};
+
+int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13:
+		mmwrite((mmread(MANTIS_GPIF_ADDR)) | voltage, MANTIS_GPIF_ADDR);
+		dprintk(verbose, MANTIS_ERROR, 1, "Polarization=[13V]");
+		break;
+	case SEC_VOLTAGE_18:
+		mmwrite((mmread(MANTIS_GPIF_ADDR)) & voltage, MANTIS_GPIF_ADDR);
+		dprintk(verbose, MANTIS_ERROR, 1, "Polarization=[18V]");
+		break;
+	case SEC_VOLTAGE_OFF:
+		dprintk(verbose, MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
+		break;
+	default:
+		dprintk(verbose, MANTIS_ERROR, 1, "Invalid = (%d)", (u32 ) voltage);
+		return -EINVAL;
+	}
+	mmwrite(0x00, MANTIS_GPIF_DOUT);
+
+	return 0;
+}
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.h b/drivers/media/dvb/mantis/mantis_vp1034.h
new file mode 100644
index 0000000..2324dad
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp1034.h
@@ -0,0 +1,30 @@
+/*
+	Mantis VP-1034 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_VP1034_H
+#define __MANTIS_VP1034_H
+
+#include "mb86a16.h"
+#include "dvb_frontend.h"
+
+extern struct mb86a16_config vp1034_config;
+extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
+
+#endif // __MANTIS_VP1034_H
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.c b/drivers/media/dvb/mantis/mantis_vp2033.c
new file mode 100644
index 0000000..bca9eba
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp2033.c
@@ -0,0 +1,73 @@
+/*
+	Mantis VP-2033 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 "mantis_common.h"
+#include "mantis_vp2033.h"
+
+struct tda10021_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend_ops ops;
+	/* configuration settings */
+	const struct tda10021_config *config;
+	struct dvb_frontend frontend;
+
+	u8 pwm;
+	u8 reg0;
+};
+
+struct cu1216_config philips_cu1216_config = {
+	.demod_address = 0x18 >> 1,
+	.pll_set = philips_cu1216_tuner_set,
+//	.fe_reset = mantis_fe_reset,
+};
+
+int philips_cu1216_tuner_set(struct dvb_frontend *fe,
+			     struct dvb_frontend_parameters *params)
+{
+//	struct tda10021_state *state = fe->demodulator_priv;
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	u8 buf[4];
+
+	struct i2c_msg msg = {
+		.addr = 0xc0 >> 1,
+		.flags = 0,
+		.buf = buf,
+		.len = sizeof (buf)
+	};
+
+#define TUNER_MUL 62500
+
+	u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
+
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = div & 0xff;
+	buf[2] = 0x86;
+	buf[3] = (params->frequency < 150000000 ? 0xA1 :
+		  params->frequency < 445000000 ? 0x92 : 0x34);
+
+//	if (i2c_transfer(state->i2c, &msg, 1) < 0) {
+	if (i2c_transfer(&mantis->adapter, &msg, 1) < 0) {
+		printk("%s tuner not ack!\n", __FUNCTION__);
+		return -EIO;
+	}
+	msleep(100);
+	return 0;
+}
diff --git a/drivers/media/dvb/mantis/mantis_vp2033.h b/drivers/media/dvb/mantis/mantis_vp2033.h
new file mode 100644
index 0000000..29baba180
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp2033.h
@@ -0,0 +1,33 @@
+/*
+	Mantis VP-2033 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_VP2033_H
+#define __MANTIS_VP2033_H
+
+#include "cu1216.h"
+#include "dvb_frontend.h"
+
+extern struct cu1216_config philips_cu1216_config;
+
+extern int philips_cu1216_tuner_set(struct dvb_frontend *fe,
+				    struct dvb_frontend_parameters *params);
+
+
+#endif // __MANTIS_VP2033_H
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.c b/drivers/media/dvb/mantis/mantis_vp3030.c
new file mode 100644
index 0000000..f44f226
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp3030.c
@@ -0,0 +1,53 @@
+/*
+	Mantis VP-3030 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 "mantis_common.h"
+#include "mantis_vp3030.h"
+
+struct zl10353_config mantis_vp3030_config = {
+	.demod_address = 0x0f,
+};
+
+int panasonic_en57h12d5_set_params(struct dvb_frontend *fe,
+				   struct dvb_frontend_parameters *params)
+{
+	u8 buf[4];
+	int rc;
+	struct mantis_pci *mantis = fe->dvb->priv;
+
+	struct i2c_msg tuner_msg = {
+		.addr = 0x60,
+		.flags = 0,
+		.buf = buf,
+		.len = sizeof (buf)
+	};
+
+	if ((params->frequency < 950000) || (params->frequency > 2150000))
+		return -EINVAL;
+	rc = i2c_transfer(&mantis->adapter, &tuner_msg, 1);
+	if (rc != 1) {
+		printk("%s: I2C Transfer returned [%d]\n", __func__, rc);
+		return -EIO;
+	}
+	msleep_interruptible(1);
+	printk("%s: Send params to tuner ok!!!\n", __func__);
+
+	return 0;
+}
diff --git a/drivers/media/dvb/mantis/mantis_vp3030.h b/drivers/media/dvb/mantis/mantis_vp3030.h
new file mode 100644
index 0000000..f8e72cc
--- /dev/null
+++ b/drivers/media/dvb/mantis/mantis_vp3030.h
@@ -0,0 +1,30 @@
+/*
+	Mantis VP-3030 driver
+
+	Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.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 __MANTIS_VP3030_H
+#define __MANTIS_VP3030_H
+
+#include "zl10353.h"
+#include "dvb-pll.h"
+#include "dvb_frontend.h"
+
+extern struct zl10353_config mantis_vp3030_config;
+
+#endif // __MANTIS_VP3030_H